diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2014-04-28 17:05:17 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-04-28 17:05:16 -0700 |
| commit | 940e3eee0098da57ac748ce325f0989c29a663cd (patch) | |
| tree | d4e999abc01b2f155c411497974c9670c686a120 | |
| parent | da83135574239d4fab3712610c01b594317d6db0 (diff) | |
| parent | 88db73d0645c64aa1aff54fe98cb56a3bd14d784 (diff) | |
Merge "ASoC: msm: qdsp6v2: Do not free memory that has not been unmapped from DSP"
| -rw-r--r-- | include/sound/q6asm-v2.h | 1 | ||||
| -rw-r--r-- | sound/soc/msm/qdsp6v2/q6asm.c | 49 |
2 files changed, 45 insertions, 5 deletions
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h index 7bb2f2423d5..67298e2cb57 100644 --- a/include/sound/q6asm-v2.h +++ b/include/sound/q6asm-v2.h @@ -181,6 +181,7 @@ struct audio_client { int stream_id; /* audio cache operations fptr*/ int (*fptr_cache_ops)(struct audio_buffer *abuff, int cache_op); + atomic_t unmap_cb_success; }; void q6asm_audio_client_free(struct audio_client *ac); diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index d49dcc76ced..a28107d483a 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -672,8 +672,11 @@ int q6asm_audio_client_buf_free(unsigned int dir, while (cnt >= 0) { if (port->buf[cnt].data) { - msm_audio_ion_free(port->buf[cnt].client, - port->buf[cnt].handle); + if (!rc) + msm_audio_ion_free( + port->buf[cnt].client, + port->buf[cnt].handle); + port->buf[cnt].client = NULL; port->buf[cnt].handle = NULL; port->buf[cnt].data = NULL; @@ -719,7 +722,9 @@ int q6asm_audio_client_buf_free_contiguous(unsigned int dir, (void *)&port->buf[0].phys, (void *)port->buf[0].client, (void *)port->buf[0].handle); - msm_audio_ion_free(port->buf[0].client, port->buf[0].handle); + if (!rc) + msm_audio_ion_free(port->buf[0].client, + port->buf[0].handle); port->buf[0].client = NULL; port->buf[0].handle = NULL; } @@ -1167,6 +1172,13 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) if (payload[1] != 0) { pr_err("%s: cmd = 0x%x returned error = 0x%x sid:%d\n", __func__, payload[0], payload[1], sid); + if (payload[0] == + ASM_CMD_SHARED_MEM_UNMAP_REGIONS) + atomic_set(&ac->unmap_cb_success, 0); + } else { + if (payload[0] == + ASM_CMD_SHARED_MEM_UNMAP_REGIONS) + atomic_set(&ac->unmap_cb_success, 1); } if (atomic_read(&ac->cmd_state)) { @@ -3189,6 +3201,7 @@ int q6asm_memory_unmap(struct audio_client *ac, phys_addr_t buf_add, int dir) TRUE, ((ac->session << 8) | dir)); atomic_set(&ac->cmd_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) { buf_node = list_entry(ptr, struct asm_buffer_node, list); @@ -3200,6 +3213,12 @@ int q6asm_memory_unmap(struct audio_client *ac, phys_addr_t buf_add, int dir) } pr_debug("%s: mem_unmap-mem_map_handle: 0x%x", __func__, mem_unmap.mem_map_handle); + + if (mem_unmap.mem_map_handle == 0) { + pr_err("%s Do not send null mem handle to DSP\n", __func__); + rc = 0; + goto fail_cmd; + } rc = apr_send_pkt(ac->mmap_apr, (uint32_t *) &mem_unmap); if (rc < 0) { pr_err("mem_unmap op[0x%x]rc[%d]\n", @@ -3211,7 +3230,13 @@ int q6asm_memory_unmap(struct audio_client *ac, phys_addr_t buf_add, int dir) rc = wait_event_timeout(ac->cmd_wait, (atomic_read(&ac->cmd_state) == 0), 5 * HZ); if (!rc) { - pr_err("timeout. waited for memory_unmap\n"); + pr_err("%s timeout. waited for memory_unmap of handle 0x%x\n", + __func__, mem_unmap.mem_map_handle); + rc = -ETIMEDOUT; + goto fail_cmd; + } else if (atomic_read(&ac->unmap_cb_success) == 0) { + pr_err("%s Error in mem unmap callback of handle 0x%x\n", + __func__, mem_unmap.mem_map_handle); rc = -EINVAL; goto fail_cmd; } @@ -3370,6 +3395,7 @@ static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir) port = &ac->port[dir]; buf_add = (uint32_t)port->buf->phys; 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) { buf_node = list_entry(ptr, struct asm_buffer_node, list); @@ -3382,6 +3408,12 @@ static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir) pr_debug("%s: mem_unmap-mem_map_handle: 0x%x", __func__, mem_unmap.mem_map_handle); + + if (mem_unmap.mem_map_handle == 0) { + pr_err("%s Do not send null mem handle to DSP\n", __func__); + rc = 0; + goto fail_cmd; + } rc = apr_send_pkt(ac->mmap_apr, (uint32_t *) &mem_unmap); if (rc < 0) { pr_err("mmap_regions op[0x%x]rc[%d]\n", @@ -3392,7 +3424,14 @@ static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir) rc = wait_event_timeout(ac->cmd_wait, (atomic_read(&ac->cmd_state) == 0), 5*HZ); if (!rc) { - pr_err("timeout. waited for memory_unmap\n"); + pr_err("%s timeout. waited for memory_unmap of handle 0x%x\n", + __func__, mem_unmap.mem_map_handle); + rc = -ETIMEDOUT; + goto fail_cmd; + } else if (atomic_read(&ac->unmap_cb_success) == 0) { + pr_err("%s Error in mem unmap callback of handle 0x%x\n", + __func__, mem_unmap.mem_map_handle); + rc = -EINVAL; goto fail_cmd; } rc = 0; |
