ASoC: msm: Release ocmem in cases of map/unmap failure
Release ocmem when ocmem_map or ocmem_unmap returned
failure due to mapping misaligned ocmem chunks.
Change-Id: Idbde98ed5e1943a10572d4105e3dff8286cab4be
Signed-off-by: Phani Kumar Uppalapati <phaniu@codeaurora.org>
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.c b/sound/soc/msm/qdsp6v2/audio_ocmem.c
index 08d7277..bedaba0 100644
--- a/sound/soc/msm/qdsp6v2/audio_ocmem.c
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.c
@@ -243,7 +243,7 @@
struct ocmem_buf *buf = NULL;
struct avcs_cmd_rsp_get_low_power_segments_info_t *lp_segptr;
- pr_debug("%s\n", __func__);
+ pr_debug("%s, %p\n", __func__, &audio_ocmem_lcl);
atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_DEFAULT);
if (audio_ocmem_lcl.lp_memseg_ptr == NULL) {
/* Retrieve low power segments */
@@ -329,6 +329,7 @@
if (ret) {
pr_err("%s: ocmem_map failed\n", __func__);
atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_FAIL);
+ goto fail_cmd1;
}
wait_event_interruptible(audio_ocmem_lcl.audio_wait,
@@ -372,7 +373,7 @@
pr_err("%s: ocmem_unmap failed, state[%d]\n",
__func__,
atomic_read(&audio_ocmem_lcl.audio_state));
- goto fail_cmd;
+ goto fail_cmd1;
}
wait_event_interruptible(audio_ocmem_lcl.audio_wait,
@@ -384,7 +385,7 @@
pr_err("%s: ocmem_shrink failed, state[%d]\n",
__func__,
atomic_read(&audio_ocmem_lcl.audio_state));
- goto fail_cmd;
+ goto fail_cmd1;
}
atomic_set(&audio_ocmem_lcl.audio_cond, 1);
clear_bit_pos(audio_ocmem_lcl.audio_state,
@@ -405,7 +406,7 @@
pr_err("%s: ocmem_map failed, state[%d]\n",
__func__,
atomic_read(&audio_ocmem_lcl.audio_state));
- goto fail_cmd;
+ goto fail_cmd1;
}
wait_event_interruptible(audio_ocmem_lcl.audio_wait,
(atomic_read(&audio_ocmem_lcl.audio_state) &
@@ -428,7 +429,7 @@
pr_err("%s: ocmem_unmap failed, state[0x%x]\n",
__func__,
atomic_read(&audio_ocmem_lcl.audio_state));
- goto fail_cmd;
+ goto fail_cmd1;
}
wait_event_interruptible(
audio_ocmem_lcl.audio_wait,
@@ -446,14 +447,16 @@
pr_err("%s: ocmem_shrink failed, state[0x%x]\n",
__func__,
atomic_read(&audio_ocmem_lcl.audio_state));
- goto fail_cmd;
+ goto fail_cmd1;
}
clear_bit_pos(audio_ocmem_lcl.audio_state,
OCMEM_STATE_SHRINK);
}
- pr_debug("%s: calling ocmem free\n", __func__);
+ pr_debug("%s: calling ocmem free, state:0x%x\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
ret = ocmem_free(OCMEM_LP_AUDIO, audio_ocmem_lcl.buf);
if (ret == -EAGAIN) {
pr_debug("%s: received EAGAIN\n", __func__);
@@ -466,7 +469,7 @@
pr_err("%s: ocmem_shrink failed, state[0x%x]\n",
__func__,
atomic_read(&audio_ocmem_lcl.audio_state));
- goto fail_cmd;
+ goto fail_cmd1;
}
pr_debug("calling free after EAGAIN");
ret = ocmem_free(OCMEM_LP_AUDIO,
@@ -474,19 +477,19 @@
if (ret) {
pr_err("%s: ocmem_free failed\n",
__func__);
- goto fail_cmd;
+ goto fail_cmd2;
}
} else {
pr_debug("%s: shrink callback already processed\n",
__func__);
- goto fail_cmd;
+ goto fail_cmd1;
}
} else if (ret) {
pr_err("%s: ocmem_free failed, state[0x%x], ret:%d\n",
__func__,
atomic_read(&audio_ocmem_lcl.audio_state),
ret);
- goto fail_cmd;
+ goto fail_cmd2;
}
pr_debug("%s: ocmem_free success\n", __func__);
/* Fall through */
@@ -508,6 +511,14 @@
mutex_unlock(&audio_ocmem_lcl.state_process_lock);
}
ret = 0;
+ goto fail_cmd;
+
+fail_cmd1:
+ ret = ocmem_free(OCMEM_LP_AUDIO, audio_ocmem_lcl.buf);
+ if (ret)
+ pr_err("%s: ocmem_free failed\n", __func__);
+fail_cmd2:
+ mutex_unlock(&audio_ocmem_lcl.state_process_lock);
fail_cmd:
pr_debug("%s: exit\n", __func__);
audio_ocmem_lcl.audio_ocmem_running = false;
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index 42cbcd1..5fec0c1 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -29,7 +29,7 @@
struct apr_svc *core_handle_q;
wait_queue_head_t bus_bw_req_wait;
u32 bus_bw_resp_received;
- struct avcs_cmd_rsp_get_low_power_segments_info_t *lp_ocm_payload;
+ struct avcs_cmd_rsp_get_low_power_segments_info_t lp_ocm_payload;
};
static struct q6core_str q6core_lcl;
@@ -74,19 +74,19 @@
pr_info("%s: cmd = AVCS_CMDRSP_GET_LOW_POWER_SEGMENTS_INFO num_segments = 0x%x\n",
__func__, payload1[0]);
nseg = payload1[0];
- q6core_lcl.lp_ocm_payload->num_segments = nseg;
- q6core_lcl.lp_ocm_payload->bandwidth = payload1[1];
+ q6core_lcl.lp_ocm_payload.num_segments = nseg;
+ q6core_lcl.lp_ocm_payload.bandwidth = payload1[1];
for (i = 0, j = 2; i < nseg; i++) {
- q6core_lcl.lp_ocm_payload->mem_segment[i].type =
+ q6core_lcl.lp_ocm_payload.mem_segment[i].type =
(payload1[j] & 0xffff);
- q6core_lcl.lp_ocm_payload->mem_segment[i].category =
+ q6core_lcl.lp_ocm_payload.mem_segment[i].category =
((payload1[j++] >> 16) & 0xffff);
- q6core_lcl.lp_ocm_payload->mem_segment[i].size =
+ q6core_lcl.lp_ocm_payload.mem_segment[i].size =
payload1[j++];
- q6core_lcl.lp_ocm_payload->
+ q6core_lcl.lp_ocm_payload.
mem_segment[i].start_address_lsw =
payload1[j++];
- q6core_lcl.lp_ocm_payload->
+ q6core_lcl.lp_ocm_payload.
mem_segment[i].start_address_msw =
payload1[j++];
}
@@ -152,7 +152,6 @@
struct avcs_cmd_rsp_get_low_power_segments_info_t **lp_memseg)
{
struct avcs_cmd_get_low_power_segments_info lp_ocm_cmd;
- u8 *cptr = NULL;
int ret = 0;
pr_debug("%s: ", __func__);
@@ -163,16 +162,6 @@
return -ENODEV;
}
- cptr = kzalloc(
- sizeof(struct avcs_cmd_rsp_get_low_power_segments_info_t),
- GFP_KERNEL);
- if (!cptr) {
- pr_err("%s: Failed to allocate memory for low power segment struct\n",
- __func__);
- return -ENOMEM;
- }
- q6core_lcl.lp_ocm_payload =
- (struct avcs_cmd_rsp_get_low_power_segments_info_t *) cptr;
lp_ocm_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
@@ -201,7 +190,7 @@
goto fail_cmd;
}
- *lp_memseg = q6core_lcl.lp_ocm_payload;
+ *lp_memseg = &q6core_lcl.lp_ocm_payload;
return 0;
fail_cmd:
@@ -215,14 +204,6 @@
q6core_lcl.bus_bw_resp_received = 0;
q6core_lcl.core_handle_q = NULL;
- q6core_lcl.lp_ocm_payload = kzalloc(
- sizeof(struct avcs_cmd_rsp_get_low_power_segments_info_t), GFP_KERNEL);
-
- if (!q6core_lcl.lp_ocm_payload) {
- pr_err("%s: Failed to allocate memory for low power segment struct\n",
- __func__);
- return -ENOMEM;
- }
return 0;
}
@@ -230,7 +211,7 @@
static void __exit core_exit(void)
{
- kfree(q6core_lcl.lp_ocm_payload);
+
}
module_exit(core_exit);
MODULE_DESCRIPTION("ADSP core driver");