Loading sound/soc/msm/qdsp6v2/q6asm.c +52 −35 Original line number Diff line number Diff line /* * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * Author: Brian Swetland <swetland@google.com> * * This software is licensed under the terms of the GNU General Public Loading Loading @@ -577,11 +577,12 @@ static bool q6asm_is_valid_audio_client(struct audio_client *ac) static void q6asm_session_free(struct audio_client *ac) { int session_id; unsigned long flags; pr_debug("%s: sessionid[%d]\n", __func__, ac->session); session_id = ac->session; rtac_remove_popp_from_adm_devices(ac->session); spin_lock_bh(&(session[session_id].session_lock)); spin_lock_irqsave(&(session[session_id].session_lock), flags); session[ac->session].ac = NULL; ac->session = 0; ac->perf_mode = LEGACY_PCM_MODE; Loading @@ -590,7 +591,8 @@ static void q6asm_session_free(struct audio_client *ac) ac->priv = NULL; kfree(ac); ac = NULL; spin_unlock_bh(&(session[session_id].session_lock)); spin_unlock_irqrestore(&(session[session_id].session_lock), flags); return; } Loading Loading @@ -1534,6 +1536,7 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) uint32_t i = IN; uint32_t *payload; unsigned long dsp_flags; unsigned long flags; struct asm_buffer_node *buf_node = NULL; struct list_head *ptr, *next; union asm_token_struct asm_token; Loading Loading @@ -1588,7 +1591,7 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) session_id = asm_token._token.session_id; if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) spin_lock(&(session[session_id].session_lock)); spin_lock_irqsave(&(session[session_id].session_lock), flags); ac = q6asm_get_audio_client(session_id); dir = q6asm_get_flag_from_token(&asm_token, ASM_DIRECTION_OFFSET); Loading @@ -1598,7 +1601,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) __func__, session_id); if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading Loading @@ -1651,7 +1655,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) } if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading Loading @@ -1687,7 +1692,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) ac->cb(data->opcode, data->token, data->payload, ac->priv); if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading Loading @@ -1756,6 +1762,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) uint8_t buf_index; struct msm_adsp_event_data *pp_event_package = NULL; uint32_t payload_size = 0; unsigned long flags; int session_id; if (ac == NULL) { Loading @@ -1774,11 +1781,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) return -EINVAL; } spin_lock(&(session[session_id].session_lock)); spin_lock_irqsave(&(session[session_id].session_lock), flags); if (!q6asm_is_valid_audio_client(ac)) { pr_err("%s: audio client pointer is invalid, ac = %pK\n", __func__, ac); spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; } Loading @@ -1791,9 +1800,6 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } if (data->opcode == RESET_EVENTS) { spin_unlock(&(session[session_id].session_lock)); mutex_lock(&ac->cmd_lock); spin_lock(&(session[session_id].session_lock)); atomic_set(&ac->reset, 1); if (ac->apr == NULL) { ac->apr = ac->apr2; Loading @@ -1814,8 +1820,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) wake_up(&ac->time_wait); wake_up(&ac->cmd_wait); wake_up(&ac->mem_wait); spin_unlock(&(session[session_id].session_lock)); mutex_unlock(&ac->cmd_lock); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading @@ -1829,7 +1835,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW)) { if (payload == NULL) { pr_err("%s: payload is null\n", __func__); spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; } dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", Loading @@ -1855,7 +1862,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) ret = q6asm_is_valid_session(data, priv); if (ret != 0) { pr_err("%s: session invalid %d\n", __func__, ret); spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return ret; } case ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2: Loading Loading @@ -1895,8 +1903,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) payload[1]); wake_up(&ac->cmd_wait); } spin_unlock( &(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } if ((is_adsp_reg_event(payload[0]) >= 0) || Loading Loading @@ -1927,8 +1936,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) atomic_set(&ac->mem_state, payload[1]); wake_up(&ac->mem_wait); } spin_unlock( &(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } if (atomic_read(&ac->mem_state) && wakeup_flag) { Loading Loading @@ -1977,7 +1987,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) break; } spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading @@ -1991,8 +2002,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", __func__); spin_unlock( &(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; } spin_lock_irqsave(&port->dsp_lock, dsp_flags); Loading @@ -2007,8 +2019,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, payload[0], payload[1]); spin_unlock_irqrestore(&port->dsp_lock, dsp_flags); spin_unlock( &(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; } port->buf[buf_index].used = 1; Loading Loading @@ -2079,8 +2092,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (ac->io_mode & SYNC_IO_MODE) { if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", __func__); spin_unlock( &(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; } spin_lock_irqsave(&port->dsp_lock, dsp_flags); Loading Loading @@ -2155,10 +2169,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", __func__, payload[0], payload[1]); i = is_adsp_raise_event(data->opcode); if (i < 0) { spin_unlock(&(session[session_id].session_lock)); if (i < 0) return 0; } /* repack payload for asm_stream_pp_event * package is composed of event type + size + actual payload Loading @@ -2167,10 +2179,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pp_event_package = kzalloc(payload_size + sizeof(struct msm_adsp_event_data), GFP_ATOMIC); if (!pp_event_package) { spin_unlock(&(session[session_id].session_lock)); if (!pp_event_package) return -ENOMEM; } pp_event_package->event_type = i; pp_event_package->payload_len = payload_size; Loading @@ -2179,7 +2189,6 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) ac->cb(data->opcode, data->token, (void *)pp_event_package, ac->priv); kfree(pp_event_package); spin_unlock(&(session[session_id].session_lock)); return 0; case ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2: pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", Loading @@ -2205,7 +2214,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (ac->cb) ac->cb(data->opcode, data->token, data->payload, ac->priv); spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading Loading @@ -2381,11 +2391,16 @@ int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac) static void __q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, uint32_t pkt_size, uint32_t cmd_flg, uint32_t stream_id) { unsigned long flags; dev_vdbg(ac->dev, "%s: pkt_size=%d cmd_flg=%d session=%d stream_id=%d\n", __func__, pkt_size, cmd_flg, ac->session, stream_id); mutex_lock(&ac->cmd_lock); spin_lock_irqsave(&(session[ac->session].session_lock), flags); if (ac->apr == NULL) { pr_err("%s: AC APR handle NULL", __func__); spin_unlock_irqrestore( &(session[ac->session].session_lock), flags); mutex_unlock(&ac->cmd_lock); return; } Loading @@ -2408,6 +2423,8 @@ static void __q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, WAIT_CMD); hdr->pkt_size = pkt_size; spin_unlock_irqrestore( &(session[ac->session].session_lock), flags); mutex_unlock(&ac->cmd_lock); return; } Loading Loading
sound/soc/msm/qdsp6v2/q6asm.c +52 −35 Original line number Diff line number Diff line /* * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * Author: Brian Swetland <swetland@google.com> * * This software is licensed under the terms of the GNU General Public Loading Loading @@ -577,11 +577,12 @@ static bool q6asm_is_valid_audio_client(struct audio_client *ac) static void q6asm_session_free(struct audio_client *ac) { int session_id; unsigned long flags; pr_debug("%s: sessionid[%d]\n", __func__, ac->session); session_id = ac->session; rtac_remove_popp_from_adm_devices(ac->session); spin_lock_bh(&(session[session_id].session_lock)); spin_lock_irqsave(&(session[session_id].session_lock), flags); session[ac->session].ac = NULL; ac->session = 0; ac->perf_mode = LEGACY_PCM_MODE; Loading @@ -590,7 +591,8 @@ static void q6asm_session_free(struct audio_client *ac) ac->priv = NULL; kfree(ac); ac = NULL; spin_unlock_bh(&(session[session_id].session_lock)); spin_unlock_irqrestore(&(session[session_id].session_lock), flags); return; } Loading Loading @@ -1534,6 +1536,7 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) uint32_t i = IN; uint32_t *payload; unsigned long dsp_flags; unsigned long flags; struct asm_buffer_node *buf_node = NULL; struct list_head *ptr, *next; union asm_token_struct asm_token; Loading Loading @@ -1588,7 +1591,7 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) session_id = asm_token._token.session_id; if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) spin_lock(&(session[session_id].session_lock)); spin_lock_irqsave(&(session[session_id].session_lock), flags); ac = q6asm_get_audio_client(session_id); dir = q6asm_get_flag_from_token(&asm_token, ASM_DIRECTION_OFFSET); Loading @@ -1598,7 +1601,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) __func__, session_id); if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading Loading @@ -1651,7 +1655,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) } if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading Loading @@ -1687,7 +1692,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) ac->cb(data->opcode, data->token, data->payload, ac->priv); if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading Loading @@ -1756,6 +1762,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) uint8_t buf_index; struct msm_adsp_event_data *pp_event_package = NULL; uint32_t payload_size = 0; unsigned long flags; int session_id; if (ac == NULL) { Loading @@ -1774,11 +1781,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) return -EINVAL; } spin_lock(&(session[session_id].session_lock)); spin_lock_irqsave(&(session[session_id].session_lock), flags); if (!q6asm_is_valid_audio_client(ac)) { pr_err("%s: audio client pointer is invalid, ac = %pK\n", __func__, ac); spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; } Loading @@ -1791,9 +1800,6 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } if (data->opcode == RESET_EVENTS) { spin_unlock(&(session[session_id].session_lock)); mutex_lock(&ac->cmd_lock); spin_lock(&(session[session_id].session_lock)); atomic_set(&ac->reset, 1); if (ac->apr == NULL) { ac->apr = ac->apr2; Loading @@ -1814,8 +1820,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) wake_up(&ac->time_wait); wake_up(&ac->cmd_wait); wake_up(&ac->mem_wait); spin_unlock(&(session[session_id].session_lock)); mutex_unlock(&ac->cmd_lock); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading @@ -1829,7 +1835,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW)) { if (payload == NULL) { pr_err("%s: payload is null\n", __func__); spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; } dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", Loading @@ -1855,7 +1862,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) ret = q6asm_is_valid_session(data, priv); if (ret != 0) { pr_err("%s: session invalid %d\n", __func__, ret); spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return ret; } case ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2: Loading Loading @@ -1895,8 +1903,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) payload[1]); wake_up(&ac->cmd_wait); } spin_unlock( &(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } if ((is_adsp_reg_event(payload[0]) >= 0) || Loading Loading @@ -1927,8 +1936,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) atomic_set(&ac->mem_state, payload[1]); wake_up(&ac->mem_wait); } spin_unlock( &(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } if (atomic_read(&ac->mem_state) && wakeup_flag) { Loading Loading @@ -1977,7 +1987,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) break; } spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading @@ -1991,8 +2002,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", __func__); spin_unlock( &(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; } spin_lock_irqsave(&port->dsp_lock, dsp_flags); Loading @@ -2007,8 +2019,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, payload[0], payload[1]); spin_unlock_irqrestore(&port->dsp_lock, dsp_flags); spin_unlock( &(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; } port->buf[buf_index].used = 1; Loading Loading @@ -2079,8 +2092,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (ac->io_mode & SYNC_IO_MODE) { if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", __func__); spin_unlock( &(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; } spin_lock_irqsave(&port->dsp_lock, dsp_flags); Loading Loading @@ -2155,10 +2169,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", __func__, payload[0], payload[1]); i = is_adsp_raise_event(data->opcode); if (i < 0) { spin_unlock(&(session[session_id].session_lock)); if (i < 0) return 0; } /* repack payload for asm_stream_pp_event * package is composed of event type + size + actual payload Loading @@ -2167,10 +2179,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pp_event_package = kzalloc(payload_size + sizeof(struct msm_adsp_event_data), GFP_ATOMIC); if (!pp_event_package) { spin_unlock(&(session[session_id].session_lock)); if (!pp_event_package) return -ENOMEM; } pp_event_package->event_type = i; pp_event_package->payload_len = payload_size; Loading @@ -2179,7 +2189,6 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) ac->cb(data->opcode, data->token, (void *)pp_event_package, ac->priv); kfree(pp_event_package); spin_unlock(&(session[session_id].session_lock)); return 0; case ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2: pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", Loading @@ -2205,7 +2214,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (ac->cb) ac->cb(data->opcode, data->token, data->payload, ac->priv); spin_unlock(&(session[session_id].session_lock)); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; } Loading Loading @@ -2381,11 +2391,16 @@ int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac) static void __q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, uint32_t pkt_size, uint32_t cmd_flg, uint32_t stream_id) { unsigned long flags; dev_vdbg(ac->dev, "%s: pkt_size=%d cmd_flg=%d session=%d stream_id=%d\n", __func__, pkt_size, cmd_flg, ac->session, stream_id); mutex_lock(&ac->cmd_lock); spin_lock_irqsave(&(session[ac->session].session_lock), flags); if (ac->apr == NULL) { pr_err("%s: AC APR handle NULL", __func__); spin_unlock_irqrestore( &(session[ac->session].session_lock), flags); mutex_unlock(&ac->cmd_lock); return; } Loading @@ -2408,6 +2423,8 @@ static void __q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, WAIT_CMD); hdr->pkt_size = pkt_size; spin_unlock_irqrestore( &(session[ac->session].session_lock), flags); mutex_unlock(&ac->cmd_lock); return; } Loading