mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
ASoC: msm: qdsp6v2: Add a new waitqueue and state for mem map/unmap
All of the commands being sent to the DSP are using cmd_state flag which can be overwritten when several commands are sent at the same time. This results in Memory map/unmap command timing out. The change will separate the memory flag from flags for other commands so that they do not overwrite each other. CRs-fixed: 673781 Change-Id: I61e059f402feb2c4e1e3dbed1825990456e78471 Signed-off-by: Damir Didjusto <damird@codeaurora.org>
This commit is contained in:
parent
ac06b734d8
commit
89f32db377
2 changed files with 27 additions and 26 deletions
|
@ -167,6 +167,7 @@ struct audio_client {
|
|||
/* Relative or absolute TS */
|
||||
atomic_t time_flag;
|
||||
atomic_t nowait_cmd_cnt;
|
||||
atomic_t mem_state;
|
||||
void *priv;
|
||||
uint32_t io_mode;
|
||||
uint64_t time_stamp;
|
||||
|
@ -178,6 +179,7 @@ struct audio_client {
|
|||
struct audio_port_data port[2];
|
||||
wait_queue_head_t cmd_wait;
|
||||
wait_queue_head_t time_wait;
|
||||
wait_queue_head_t mem_wait;
|
||||
int perf_mode;
|
||||
int stream_id;
|
||||
/* audio cache operations fptr*/
|
||||
|
|
|
@ -561,7 +561,7 @@ int send_asm_custom_topology(struct audio_client *ac)
|
|||
q6asm_add_hdr_custom_topology(ac, &asm_top.hdr,
|
||||
APR_PKT_SIZE(APR_HDR_SIZE,
|
||||
sizeof(asm_top)), TRUE);
|
||||
atomic_set(&ac->cmd_state, 1);
|
||||
atomic_set(&ac->mem_state, 1);
|
||||
asm_top.hdr.opcode = ASM_CMD_ADD_TOPOLOGIES;
|
||||
asm_top.payload_addr_lsw = lower_32_bits(cal_block->cal_data.paddr);
|
||||
asm_top.payload_addr_msw = upper_32_bits(cal_block->cal_data.paddr);
|
||||
|
@ -581,8 +581,8 @@ int send_asm_custom_topology(struct audio_client *ac)
|
|||
|
||||
}
|
||||
|
||||
result = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state) <= 0), 5*HZ);
|
||||
result = wait_event_timeout(ac->mem_wait,
|
||||
(atomic_read(&ac->mem_state) <= 0), 5*HZ);
|
||||
if (!result) {
|
||||
|
||||
pr_err("%s: Set topologies failed after timedout payload = 0x%pa\n",
|
||||
|
@ -961,6 +961,7 @@ struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv)
|
|||
|
||||
init_waitqueue_head(&ac->cmd_wait);
|
||||
init_waitqueue_head(&ac->time_wait);
|
||||
init_waitqueue_head(&ac->mem_wait);
|
||||
atomic_set(&ac->time_flag, 1);
|
||||
atomic_set(&ac->reset, 0);
|
||||
INIT_LIST_HEAD(&ac->port[0].mem_map_handle);
|
||||
|
@ -973,6 +974,7 @@ struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv)
|
|||
}
|
||||
atomic_set(&ac->cmd_state, 0);
|
||||
atomic_set(&ac->nowait_cmd_cnt, 0);
|
||||
atomic_set(&ac->mem_state, 0);
|
||||
|
||||
rc = send_asm_custom_topology(ac);
|
||||
if (rc < 0) {
|
||||
|
@ -1280,10 +1282,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
|
|||
atomic_set(&ac->unmap_cb_success, 1);
|
||||
}
|
||||
|
||||
if (atomic_read(&ac->cmd_state)) {
|
||||
atomic_set(&ac->cmd_state, 0);
|
||||
wake_up(&ac->cmd_wait);
|
||||
}
|
||||
if (atomic_cmpxchg(&ac->mem_state, 1, 0))
|
||||
wake_up(&ac->mem_wait);
|
||||
pr_debug("%s:Payload = [0x%x] status[0x%x]\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
break;
|
||||
|
@ -1303,10 +1303,9 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
|
|||
pr_debug("%s:PL#0[0x%x] dir=%x s_id=%x\n",
|
||||
__func__, payload[0], dir, sid);
|
||||
spin_lock_irqsave(&port->dsp_lock, dsp_flags);
|
||||
if (atomic_read(&ac->cmd_state)) {
|
||||
if (atomic_cmpxchg(&ac->mem_state, 1, 0)) {
|
||||
ac->port[dir].tmp_hdl = payload[0];
|
||||
atomic_set(&ac->cmd_state, 0);
|
||||
wake_up(&ac->cmd_wait);
|
||||
wake_up(&ac->mem_wait);
|
||||
}
|
||||
spin_unlock_irqrestore(&port->dsp_lock, dsp_flags);
|
||||
break;
|
||||
|
@ -1315,10 +1314,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
|
|||
pr_debug("%s:PL#0[0x%x]PL#1 [0x%x]\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
spin_lock_irqsave(&port->dsp_lock, dsp_flags);
|
||||
if (atomic_read(&ac->cmd_state)) {
|
||||
atomic_set(&ac->cmd_state, 0);
|
||||
wake_up(&ac->cmd_wait);
|
||||
}
|
||||
if (atomic_cmpxchg(&ac->mem_state, 1, 0))
|
||||
wake_up(&ac->mem_wait);
|
||||
spin_unlock_irqrestore(&port->dsp_lock, dsp_flags);
|
||||
|
||||
break;
|
||||
|
@ -3420,7 +3417,7 @@ int q6asm_memory_map(struct audio_client *ac, phys_addr_t buf_add, int dir,
|
|||
mmap_region_cmd;
|
||||
q6asm_add_mmaphdr(ac, &mmap_regions->hdr, cmd_size,
|
||||
TRUE, ((ac->session << 8) | dir));
|
||||
atomic_set(&ac->cmd_state, 1);
|
||||
atomic_set(&ac->mem_state, 1);
|
||||
mmap_regions->hdr.opcode = ASM_CMD_SHARED_MEM_MAP_REGIONS;
|
||||
mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
|
||||
mmap_regions->num_regions = bufcnt & 0x00ff;
|
||||
|
@ -3447,8 +3444,8 @@ int q6asm_memory_map(struct audio_client *ac, phys_addr_t buf_add, int dir,
|
|||
goto fail_cmd;
|
||||
}
|
||||
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state) == 0 &&
|
||||
rc = wait_event_timeout(ac->mem_wait,
|
||||
(atomic_read(&ac->mem_state) == 0 &&
|
||||
ac->port[dir].tmp_hdl), 5*HZ);
|
||||
if (!rc) {
|
||||
pr_err("timeout. waited for memory_map\n");
|
||||
|
@ -3491,7 +3488,7 @@ int q6asm_memory_unmap(struct audio_client *ac, phys_addr_t buf_add, int dir)
|
|||
q6asm_add_mmaphdr(ac, &mem_unmap.hdr,
|
||||
sizeof(struct avs_cmd_shared_mem_unmap_regions),
|
||||
TRUE, ((ac->session << 8) | dir));
|
||||
atomic_set(&ac->cmd_state, 1);
|
||||
atomic_set(&ac->mem_state, 1);
|
||||
mem_unmap.hdr.opcode = ASM_CMD_SHARED_MEM_UNMAP_REGIONS;
|
||||
mem_unmap.mem_map_handle = 0;
|
||||
list_for_each_safe(ptr, next, &ac->port[dir].mem_map_handle) {
|
||||
|
@ -3519,8 +3516,8 @@ int q6asm_memory_unmap(struct audio_client *ac, phys_addr_t buf_add, int dir)
|
|||
goto fail_cmd;
|
||||
}
|
||||
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state) <= 0), 5 * HZ);
|
||||
rc = wait_event_timeout(ac->mem_wait,
|
||||
(atomic_read(&ac->mem_state) <= 0), 5 * HZ);
|
||||
if (!rc) {
|
||||
pr_err("%s timeout. waited for memory_unmap of handle 0x%x\n",
|
||||
__func__, mem_unmap.mem_map_handle);
|
||||
|
@ -3608,7 +3605,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
|
|||
mmap_region_cmd;
|
||||
q6asm_add_mmaphdr(ac, &mmap_regions->hdr, cmd_size, TRUE,
|
||||
((ac->session << 8) | dir));
|
||||
atomic_set(&ac->cmd_state, 1);
|
||||
atomic_set(&ac->mem_state, 1);
|
||||
pr_debug("mmap_region=0x%p token=0x%x\n",
|
||||
mmap_regions, ((ac->session << 8) | dir));
|
||||
|
||||
|
@ -3640,8 +3637,8 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
|
|||
goto fail_cmd;
|
||||
}
|
||||
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state) <= 0)
|
||||
rc = wait_event_timeout(ac->mem_wait,
|
||||
(atomic_read(&ac->mem_state) <= 0)
|
||||
, 5*HZ);
|
||||
if (!rc) {
|
||||
pr_err("timeout. waited for memory_map\n");
|
||||
|
@ -3696,7 +3693,7 @@ static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir)
|
|||
cmd_size = sizeof(struct avs_cmd_shared_mem_unmap_regions);
|
||||
q6asm_add_mmaphdr(ac, &mem_unmap.hdr, cmd_size,
|
||||
TRUE, ((ac->session << 8) | dir));
|
||||
atomic_set(&ac->cmd_state, 1);
|
||||
atomic_set(&ac->mem_state, 1);
|
||||
port = &ac->port[dir];
|
||||
buf_add = (uint32_t)port->buf->phys;
|
||||
mem_unmap.hdr.opcode = ASM_CMD_SHARED_MEM_UNMAP_REGIONS;
|
||||
|
@ -3726,8 +3723,8 @@ static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir)
|
|||
goto fail_cmd;
|
||||
}
|
||||
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state) <= 0), 5*HZ);
|
||||
rc = wait_event_timeout(ac->mem_wait,
|
||||
(atomic_read(&ac->mem_state) <= 0), 5*HZ);
|
||||
if (!rc) {
|
||||
pr_err("%s timeout. waited for memory_unmap of handle 0x%x\n",
|
||||
__func__, mem_unmap.mem_map_handle);
|
||||
|
@ -5210,6 +5207,7 @@ static int __init q6asm_init(void)
|
|||
common_client.port[1].buf = &common_buf[1];
|
||||
init_waitqueue_head(&common_client.cmd_wait);
|
||||
init_waitqueue_head(&common_client.time_wait);
|
||||
init_waitqueue_head(&common_client.mem_wait);
|
||||
atomic_set(&common_client.time_flag, 1);
|
||||
INIT_LIST_HEAD(&common_client.port[0].mem_map_handle);
|
||||
INIT_LIST_HEAD(&common_client.port[1].mem_map_handle);
|
||||
|
@ -5220,6 +5218,7 @@ static int __init q6asm_init(void)
|
|||
}
|
||||
atomic_set(&common_client.cmd_state, 0);
|
||||
atomic_set(&common_client.nowait_cmd_cnt, 0);
|
||||
atomic_set(&common_client.mem_state, 0);
|
||||
|
||||
if (q6asm_init_cal_data())
|
||||
pr_err("%s: could not init cal data!\n", __func__);
|
||||
|
|
Loading…
Reference in a new issue