ASoC: msm: qdspv2: add an API to destroy ion client
Currently ion fd is used to extract ion handle to free ion client. ION FD is not valid if user-space application is crashed so ion handle is returned to the client during msm_audio_ion_phys_assign() API which is used to destroy ion client in msm_audio_ion_phys_free() API. Change-Id: Idcc4ca838741aac26662a679117af9d9c935e630 Signed-off-by: Vidyakumar Athota <vathota@codeaurora.org>
This commit is contained in:
parent
a49bb61510
commit
e4faef1e35
6 changed files with 174 additions and 72 deletions
|
@ -210,11 +210,11 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int msm_audio_ion_phys_assign(const char *name, int fd, ion_phys_addr_t *paddr,
|
||||
size_t *pa_len, u8 assign_type)
|
||||
int msm_audio_ion_phys_free(struct ion_client *client,
|
||||
struct ion_handle *handle,
|
||||
ion_phys_addr_t *paddr,
|
||||
size_t *pa_len, u8 assign_type)
|
||||
{
|
||||
struct ion_client *client;
|
||||
struct ion_handle *handle;
|
||||
int ret;
|
||||
|
||||
if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
|
||||
|
@ -222,40 +222,76 @@ int msm_audio_ion_phys_assign(const char *name, int fd, ion_phys_addr_t *paddr,
|
|||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
if (!name || !paddr || !pa_len) {
|
||||
if (!client || !handle || !paddr || !pa_len) {
|
||||
pr_err("%s: Invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
client = msm_audio_ion_client_create(name);
|
||||
if (IS_ERR_OR_NULL((void *)(client))) {
|
||||
pr_err("%s: ION create client failed\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
handle = ion_import_dma_buf(client, fd);
|
||||
if (IS_ERR_OR_NULL((void *) (handle))) {
|
||||
pr_err("%s: ion import dma buffer failed\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto err_destroy_client;
|
||||
}
|
||||
|
||||
ret = ion_phys(client, handle, paddr, pa_len);
|
||||
if (ret) {
|
||||
pr_err("%s: could not get physical address for handle, ret = %d\n",
|
||||
__func__, ret);
|
||||
goto err_ion_handle;
|
||||
}
|
||||
pr_debug("%s: ION Physical address is %x\n", __func__, (u32)*paddr);
|
||||
|
||||
ret = msm_audio_hyp_assign(paddr, pa_len, assign_type);
|
||||
|
||||
err_ion_handle:
|
||||
ion_free(client, handle);
|
||||
ion_client_destroy(client);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int msm_audio_ion_phys_assign(const char *name, struct ion_client **client,
|
||||
struct ion_handle **handle, int fd,
|
||||
ion_phys_addr_t *paddr,
|
||||
size_t *pa_len, u8 assign_type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
|
||||
pr_debug("%s:probe is not done, deferred\n", __func__);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
if (!name || !client || !handle || !paddr || !pa_len) {
|
||||
pr_err("%s: Invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*client = msm_audio_ion_client_create(name);
|
||||
if (IS_ERR_OR_NULL((void *)(*client))) {
|
||||
pr_err("%s: ION create client failed\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*handle = ion_import_dma_buf(*client, fd);
|
||||
if (IS_ERR_OR_NULL((void *) (*handle))) {
|
||||
pr_err("%s: ion import dma buffer failed\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto err_destroy_client;
|
||||
}
|
||||
|
||||
ret = ion_phys(*client, *handle, paddr, pa_len);
|
||||
if (ret) {
|
||||
pr_err("%s: could not get physical address for handle, ret = %d\n",
|
||||
__func__, ret);
|
||||
goto err_ion_handle;
|
||||
}
|
||||
|
||||
ret = msm_audio_hyp_assign(paddr, pa_len, assign_type);
|
||||
|
||||
return ret;
|
||||
|
||||
err_ion_handle:
|
||||
ion_free(*client, *handle);
|
||||
|
||||
err_destroy_client:
|
||||
ion_client_destroy(client);
|
||||
ion_client_destroy(*client);
|
||||
*client = NULL;
|
||||
*handle = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,12 @@ int msm_audio_ion_free_legacy(struct ion_client *client,
|
|||
struct ion_handle *handle);
|
||||
u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa);
|
||||
|
||||
int msm_audio_ion_phys_assign(const char *name, int fd, ion_phys_addr_t *paddr,
|
||||
size_t *pa_len, u8 assign_type);
|
||||
int msm_audio_ion_phys_assign(const char *name, struct ion_client **client,
|
||||
struct ion_handle **handle,
|
||||
int fd, ion_phys_addr_t *paddr,
|
||||
size_t *pa_len, u8 assign_type);
|
||||
int msm_audio_ion_phys_free(struct ion_client *client,
|
||||
struct ion_handle *handle,
|
||||
ion_phys_addr_t *paddr,
|
||||
size_t *pa_len, u8 assign_type);
|
||||
#endif /* _LINUX_MSM_AUDIO_ION_H */
|
||||
|
|
|
@ -639,7 +639,8 @@ int q6asm_send_audio_effects_params(struct audio_client *ac, char *params,
|
|||
int q6asm_send_stream_cmd(struct audio_client *ac,
|
||||
struct msm_adsp_event_data *data);
|
||||
|
||||
int q6asm_audio_map_shm_fd(struct audio_client *ac, int fd);
|
||||
int q6asm_audio_map_shm_fd(struct audio_client *ac, struct ion_client **client,
|
||||
struct ion_handle **handle, int fd);
|
||||
|
||||
int q6asm_send_rtic_event_ack(struct audio_client *ac,
|
||||
void *param, uint32_t params_length);
|
||||
|
|
|
@ -159,6 +159,10 @@ struct msm_compr_audio {
|
|||
uint32_t start_delay_msw;
|
||||
|
||||
int32_t shm_ion_fd;
|
||||
struct ion_client *lib_ion_client;
|
||||
struct ion_client *shm_ion_client;
|
||||
struct ion_handle *lib_ion_handle;
|
||||
struct ion_handle *shm_ion_handle;
|
||||
|
||||
uint64_t marker_timestamp;
|
||||
|
||||
|
@ -1510,20 +1514,16 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int msm_compr_map_unmap_fd(int fd, bool add_pages)
|
||||
static int msm_compr_map_ion_fd(struct msm_compr_audio *prtd, int fd)
|
||||
{
|
||||
ion_phys_addr_t paddr;
|
||||
size_t pa_len = 0;
|
||||
int ret = 0;
|
||||
u8 assign_type;
|
||||
|
||||
if (add_pages)
|
||||
assign_type = HLOS_TO_ADSP;
|
||||
else
|
||||
assign_type = ADSP_TO_HLOS;
|
||||
|
||||
ret = msm_audio_ion_phys_assign("audio_lib_mem_client", fd,
|
||||
&paddr, &pa_len, assign_type);
|
||||
ret = msm_audio_ion_phys_assign("audio_lib_mem_client",
|
||||
&prtd->lib_ion_client,
|
||||
&prtd->lib_ion_handle,
|
||||
fd, &paddr, &pa_len, HLOS_TO_ADSP);
|
||||
if (ret) {
|
||||
pr_err("%s: audio lib ION phys failed, rc = %d\n",
|
||||
__func__, ret);
|
||||
|
@ -1531,19 +1531,48 @@ static int msm_compr_map_unmap_fd(int fd, bool add_pages)
|
|||
}
|
||||
|
||||
ret = q6core_add_remove_pool_pages(paddr, pa_len,
|
||||
ADSP_MEMORY_MAP_HLOS_PHYSPOOL, add_pages);
|
||||
ADSP_MEMORY_MAP_HLOS_PHYSPOOL, true);
|
||||
if (ret) {
|
||||
pr_err("%s: add remove pages failed, rc = %d\n", __func__, ret);
|
||||
/* Assign back to HLOS if add pages cmd failed */
|
||||
if (add_pages)
|
||||
msm_audio_ion_phys_assign("audio_lib_mem_client", fd,
|
||||
&paddr, &pa_len, ADSP_TO_HLOS);
|
||||
msm_audio_ion_phys_free(prtd->lib_ion_client,
|
||||
prtd->lib_ion_handle,
|
||||
&paddr, &pa_len, ADSP_TO_HLOS);
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_compr_unmap_ion_fd(struct msm_compr_audio *prtd)
|
||||
{
|
||||
ion_phys_addr_t paddr;
|
||||
size_t pa_len = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!prtd->lib_ion_client || !prtd->lib_ion_handle) {
|
||||
pr_err("%s: ion_client or ion_handle is NULL", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = msm_audio_ion_phys_free(prtd->lib_ion_client,
|
||||
prtd->lib_ion_handle,
|
||||
&paddr, &pa_len, ADSP_TO_HLOS);
|
||||
if (ret) {
|
||||
pr_err("%s: audio lib ION phys failed, rc = %d\n",
|
||||
__func__, ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = q6core_add_remove_pool_pages(paddr, pa_len,
|
||||
ADSP_MEMORY_MAP_HLOS_PHYSPOOL, false);
|
||||
if (ret)
|
||||
pr_err("%s: add remove pages failed, rc = %d\n", __func__, ret);
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_compr_playback_open(struct snd_compr_stream *cstream)
|
||||
{
|
||||
struct snd_compr_runtime *runtime = cstream->runtime;
|
||||
|
@ -1628,8 +1657,8 @@ static int msm_compr_playback_open(struct snd_compr_stream *cstream)
|
|||
prtd->session_id = prtd->audio_client->session;
|
||||
msm_adsp_init_mixer_ctl_pp_event_queue(rtd);
|
||||
if (pdata->ion_fd[rtd->dai_link->be_id] > 0) {
|
||||
ret = msm_compr_map_unmap_fd(
|
||||
pdata->ion_fd[rtd->dai_link->be_id], true);
|
||||
ret = msm_compr_map_ion_fd(prtd,
|
||||
pdata->ion_fd[rtd->dai_link->be_id]);
|
||||
if (ret < 0)
|
||||
goto map_err;
|
||||
}
|
||||
|
@ -1800,12 +1829,11 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream)
|
|||
|
||||
q6asm_audio_client_buf_free_contiguous(dir, ac);
|
||||
if (prtd->shm_ion_fd > 0)
|
||||
msm_audio_ion_phys_assign("audio_shm_mem_client",
|
||||
prtd->shm_ion_fd,
|
||||
&paddr, &pa_len, ADSP_TO_HLOS);
|
||||
msm_audio_ion_phys_free(prtd->shm_ion_client,
|
||||
prtd->shm_ion_handle,
|
||||
&paddr, &pa_len, ADSP_TO_HLOS);
|
||||
if (pdata->ion_fd[soc_prtd->dai_link->be_id] > 0) {
|
||||
msm_compr_map_unmap_fd(pdata->ion_fd[soc_prtd->dai_link->be_id],
|
||||
false);
|
||||
msm_compr_unmap_ion_fd(prtd);
|
||||
pdata->ion_fd[soc_prtd->dai_link->be_id] = 0;
|
||||
}
|
||||
|
||||
|
@ -3755,7 +3783,9 @@ static int msm_compr_shm_ion_fd_map_put(struct snd_kcontrol *kcontrol,
|
|||
|
||||
memcpy(&prtd->shm_ion_fd, ucontrol->value.bytes.data,
|
||||
sizeof(prtd->shm_ion_fd));
|
||||
ret = q6asm_audio_map_shm_fd(prtd->audio_client, prtd->shm_ion_fd);
|
||||
ret = q6asm_audio_map_shm_fd(prtd->audio_client,
|
||||
&prtd->shm_ion_client,
|
||||
&prtd->shm_ion_handle, prtd->shm_ion_fd);
|
||||
if (ret < 0)
|
||||
pr_err("%s: failed to map shm mem\n", __func__);
|
||||
done:
|
||||
|
|
|
@ -82,6 +82,10 @@ struct msm_transcode_loopback {
|
|||
int session_id;
|
||||
struct audio_client *audio_client;
|
||||
int32_t shm_ion_fd;
|
||||
struct ion_client *lib_ion_client;
|
||||
struct ion_client *shm_ion_client;
|
||||
struct ion_handle *lib_ion_handle;
|
||||
struct ion_handle *shm_ion_handle;
|
||||
};
|
||||
|
||||
/* Transcode loopback global info struct */
|
||||
|
@ -182,20 +186,17 @@ static void populate_codec_list(struct msm_transcode_loopback *trans,
|
|||
}
|
||||
}
|
||||
|
||||
static int msm_transcode_map_unmap_fd(int fd, bool add_pages)
|
||||
static int msm_transcode_map_ion_fd(struct msm_transcode_loopback *trans,
|
||||
int fd)
|
||||
{
|
||||
ion_phys_addr_t paddr;
|
||||
size_t pa_len = 0;
|
||||
int ret = 0;
|
||||
u8 assign_type;
|
||||
|
||||
if (add_pages)
|
||||
assign_type = HLOS_TO_ADSP;
|
||||
else
|
||||
assign_type = ADSP_TO_HLOS;
|
||||
|
||||
ret = msm_audio_ion_phys_assign("audio_lib_mem_client", fd,
|
||||
&paddr, &pa_len, assign_type);
|
||||
ret = msm_audio_ion_phys_assign("audio_lib_mem_client",
|
||||
&trans->lib_ion_client,
|
||||
&trans->lib_ion_handle, fd,
|
||||
&paddr, &pa_len, HLOS_TO_ADSP);
|
||||
if (ret) {
|
||||
pr_err("%s: audio lib ION phys failed, rc = %d\n", __func__,
|
||||
ret);
|
||||
|
@ -203,19 +204,47 @@ static int msm_transcode_map_unmap_fd(int fd, bool add_pages)
|
|||
}
|
||||
|
||||
ret = q6core_add_remove_pool_pages(paddr, pa_len,
|
||||
ADSP_MEMORY_MAP_HLOS_PHYSPOOL, add_pages);
|
||||
ADSP_MEMORY_MAP_HLOS_PHYSPOOL, true);
|
||||
if (ret) {
|
||||
pr_err("%s: add remove pages failed, rc = %d\n", __func__, ret);
|
||||
pr_err("%s: add pages failed, rc = %d\n", __func__, ret);
|
||||
/* Assign back to HLOS if add pages cmd failed */
|
||||
if (add_pages)
|
||||
msm_audio_ion_phys_assign("audio_lib_mem_client", fd,
|
||||
&paddr, &pa_len, ADSP_TO_HLOS);
|
||||
msm_audio_ion_phys_free(trans->lib_ion_client,
|
||||
trans->lib_ion_handle,
|
||||
&paddr, &pa_len, ADSP_TO_HLOS);
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_transcode_unmap_ion_fd(struct msm_transcode_loopback *trans)
|
||||
{
|
||||
ion_phys_addr_t paddr;
|
||||
size_t pa_len = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!trans->lib_ion_client || !trans->lib_ion_handle) {
|
||||
pr_err("%s: ion_client or ion_handle is NULL", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = msm_audio_ion_phys_free(trans->lib_ion_client,
|
||||
trans->lib_ion_handle,
|
||||
&paddr, &pa_len, ADSP_TO_HLOS);
|
||||
if (ret) {
|
||||
pr_err("%s: audio lib ION phys failed, rc = %d\n", __func__,
|
||||
ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = q6core_add_remove_pool_pages(paddr, pa_len,
|
||||
ADSP_MEMORY_MAP_HLOS_PHYSPOOL, false);
|
||||
if (ret)
|
||||
pr_err("%s: remove pages failed, rc = %d\n", __func__, ret);
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_transcode_loopback_open(struct snd_compr_stream *cstream)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -262,9 +291,8 @@ static int msm_transcode_loopback_open(struct snd_compr_stream *cstream)
|
|||
}
|
||||
msm_adsp_init_mixer_ctl_pp_event_queue(rtd);
|
||||
if (pdata->ion_fd[rtd->dai_link->be_id] > 0) {
|
||||
ret = msm_transcode_map_unmap_fd(
|
||||
pdata->ion_fd[rtd->dai_link->be_id],
|
||||
true);
|
||||
ret = msm_transcode_map_ion_fd(trans,
|
||||
pdata->ion_fd[rtd->dai_link->be_id]);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
}
|
||||
|
@ -335,16 +363,13 @@ static int msm_transcode_loopback_free(struct snd_compr_stream *cstream)
|
|||
memset(&trans->sink, 0, sizeof(struct loopback_stream));
|
||||
msm_adsp_clean_mixer_ctl_pp_event_queue(rtd);
|
||||
if (trans->shm_ion_fd > 0) {
|
||||
msm_audio_ion_phys_assign("audio_shm_mem_client",
|
||||
trans->shm_ion_fd,
|
||||
&paddr, &pa_len,
|
||||
ADSP_TO_HLOS);
|
||||
msm_audio_ion_phys_free(trans->shm_ion_client,
|
||||
trans->shm_ion_handle,
|
||||
&paddr, &pa_len, ADSP_TO_HLOS);
|
||||
trans->shm_ion_fd = 0;
|
||||
}
|
||||
if (pdata->ion_fd[rtd->dai_link->be_id] > 0) {
|
||||
msm_transcode_map_unmap_fd(
|
||||
pdata->ion_fd[rtd->dai_link->be_id],
|
||||
false);
|
||||
msm_transcode_unmap_ion_fd(trans);
|
||||
pdata->ion_fd[rtd->dai_link->be_id] = 0;
|
||||
}
|
||||
} else if (cstream->direction == SND_COMPRESS_CAPTURE) {
|
||||
|
@ -658,7 +683,9 @@ static int msm_transcode_shm_ion_fd_map_put(struct snd_kcontrol *kcontrol,
|
|||
|
||||
memcpy(&prtd->shm_ion_fd, ucontrol->value.bytes.data,
|
||||
sizeof(prtd->shm_ion_fd));
|
||||
ret = q6asm_audio_map_shm_fd(prtd->audio_client, prtd->shm_ion_fd);
|
||||
ret = q6asm_audio_map_shm_fd(prtd->audio_client,
|
||||
&prtd->shm_ion_client,
|
||||
&prtd->shm_ion_handle, prtd->shm_ion_fd);
|
||||
if (ret < 0)
|
||||
pr_err("%s: failed to map shm mem\n", __func__);
|
||||
done:
|
||||
|
|
|
@ -7118,7 +7118,8 @@ fail_cmd:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int q6asm_audio_map_shm_fd(struct audio_client *ac, int fd)
|
||||
int q6asm_audio_map_shm_fd(struct audio_client *ac, struct ion_client **client,
|
||||
struct ion_handle **handle, int fd)
|
||||
{
|
||||
ion_phys_addr_t paddr;
|
||||
size_t pa_len = 0;
|
||||
|
@ -7137,7 +7138,8 @@ int q6asm_audio_map_shm_fd(struct audio_client *ac, int fd)
|
|||
goto fail_cmd;
|
||||
}
|
||||
|
||||
ret = msm_audio_ion_phys_assign("audio_shm_mem_client", fd,
|
||||
ret = msm_audio_ion_phys_assign("audio_shm_mem_client", client,
|
||||
handle, fd,
|
||||
&paddr, &pa_len, HLOS_TO_ADSP);
|
||||
if (ret) {
|
||||
pr_err("%s: shm ION phys failed, rc = %d\n", __func__, ret);
|
||||
|
|
Loading…
Add table
Reference in a new issue