Loading drivers/soc/qcom/qdsp6v2/apr.c +102 −1 Original line number Diff line number Diff line /* Copyright (c) 2010-2014, 2016, 2018 The Linux Foundation. /* Copyright (c) 2010-2014, 2016, 2018-2019 The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify Loading Loading @@ -758,6 +758,107 @@ static void apr_reset_deregister(struct work_struct *work) kfree(apr_reset); } /** * apr_start_rx_rt - Clients call to vote for thread * priority upgrade whenever needed. * * @handle: APR service handle * * Returns 0 on success or error otherwise. */ int apr_start_rx_rt(void *handle) { int rc = 0; struct apr_svc *svc = handle; uint16_t dest_id = 0; uint16_t client_id = 0; if (!svc) { pr_err("%s: Invalid APR handle\n", __func__); return -EINVAL; } mutex_lock(&svc->m_lock); dest_id = svc->dest_id; client_id = svc->client_id; if ((client_id >= APR_CLIENT_MAX) || (dest_id >= APR_DEST_MAX)) { pr_err("%s: %s invalid. client_id = %u, dest_id = %u\n", __func__, client_id >= APR_CLIENT_MAX ? "Client ID" : "Dest ID", client_id, dest_id); rc = -EINVAL; goto exit; } if (!client[dest_id][client_id].handle) { pr_err("%s: Client handle is NULL\n", __func__); rc = -EINVAL; goto exit; } rc = apr_tal_start_rx_rt(client[dest_id][client_id].handle); if (rc) pr_err("%s: failed to set RT thread priority for APR RX. rc = %d\n", __func__, rc); exit: mutex_unlock(&svc->m_lock); return rc; } EXPORT_SYMBOL(apr_start_rx_rt); /** * apr_end_rx_rt - Clients call to unvote for thread * priority upgrade (perviously voted with * apr_start_rx_rt()). * * @handle: APR service handle * * Returns 0 on success or error otherwise. */ int apr_end_rx_rt(void *handle) { int rc = 0; struct apr_svc *svc = handle; uint16_t dest_id = 0; uint16_t client_id = 0; if (!svc) { pr_err("%s: Invalid APR handle\n", __func__); return -EINVAL; } mutex_lock(&svc->m_lock); dest_id = svc->dest_id; client_id = svc->client_id; if ((client_id >= APR_CLIENT_MAX) || (dest_id >= APR_DEST_MAX)) { pr_err("%s: %s invalid. client_id = %u, dest_id = %u\n", __func__, client_id >= APR_CLIENT_MAX ? "Client ID" : "Dest ID", client_id, dest_id); rc = -EINVAL; goto exit; } if (!client[dest_id][client_id].handle) { pr_err("%s: Client handle is NULL\n", __func__); rc = -EINVAL; goto exit; } rc = apr_tal_end_rx_rt(client[dest_id][client_id].handle); if (rc) pr_err("%s: failed to reset RT thread priority for APR RX. rc = %d\n", __func__, rc); exit: mutex_unlock(&svc->m_lock); return rc; } EXPORT_SYMBOL(apr_end_rx_rt); int apr_deregister(void *handle) { struct apr_svc *svc = handle; Loading drivers/soc/qcom/qdsp6v2/apr_tal_glink.c +33 −1 Original line number Diff line number Diff line /* Copyright (c) 2016-2017 The Linux Foundation. /* Copyright (c) 2016-2017, 2019 The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify Loading Loading @@ -358,6 +358,38 @@ unlock: return rc ? NULL : apr_ch; } int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch) { int rc = 0; if (!apr_ch || !apr_ch->handle) { rc = -EINVAL; goto exit; } mutex_lock(&apr_ch->m_lock); rc = glink_start_rx_rt(apr_ch->handle); mutex_unlock(&apr_ch->m_lock); exit: return rc; } int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch) { int rc = 0; if (!apr_ch || !apr_ch->handle) { rc = -EINVAL; goto exit; } mutex_lock(&apr_ch->m_lock); rc = glink_end_rx_rt(apr_ch->handle); mutex_unlock(&apr_ch->m_lock); exit: return rc; } int apr_tal_close(struct apr_svc_ch_dev *apr_ch) { int rc; Loading include/linux/qdsp6v2/apr.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2017, 2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -196,4 +196,6 @@ int apr_set_q6_state(enum apr_subsys_state state); void apr_set_subsys_state(void); const char *apr_get_lpass_subsys_name(void); uint16_t apr_get_reset_domain(uint16_t proc); int apr_start_rx_rt(void *handle); int apr_end_rx_rt(void *handle); #endif include/linux/qdsp6v2/apr_tal.h +9 −1 Original line number Diff line number Diff line /* Copyright (c) 2010-2011, 2016-2017 The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2011, 2016-2017, 2019 The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -78,6 +79,9 @@ int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, #if defined(CONFIG_MSM_QDSP6_APRV2_GLINK) || \ defined(CONFIG_MSM_QDSP6_APRV3_GLINK) int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch); int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch); struct apr_svc_ch_dev { void *handle; spinlock_t w_lock; Loading @@ -90,6 +94,10 @@ struct apr_svc_ch_dev { bool if_remote_intent_ready; }; #else static inline int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch) { return 0; } static inline int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch) { return 0; } struct apr_svc_ch_dev { struct smd_channel *ch; spinlock_t lock; Loading sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c +22 −0 Original line number Diff line number Diff line Loading @@ -686,8 +686,15 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; struct msm_audio *prtd; struct msm_plat_data *pdata; int ret = 0; pdata = (struct msm_plat_data *) dev_get_drvdata(soc_prtd->platform->dev); if (!pdata) { pr_err("%s: platform data not populated\n", __func__); return -EINVAL; } prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL); if (prtd == NULL) { pr_err("Failed to allocate memory for msm_audio\n"); Loading Loading @@ -767,6 +774,10 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) prtd->reset_event = false; runtime->private_data = prtd; msm_adsp_init_mixer_ctl_pp_event_queue(soc_prtd); /* Vote to update the Rx thread priority to RT Thread for playback */ if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && (pdata->perf_mode == LOW_LATENCY_PCM_MODE)) apr_start_rx_rt(prtd->audio_client->apr); return 0; } Loading Loading @@ -874,6 +885,7 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; struct msm_audio *prtd = runtime->private_data; struct msm_plat_data *pdata; uint32_t timeout; int dir = 0; int ret = 0; Loading @@ -883,6 +895,16 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) if (prtd->audio_client) { dir = IN; /* * Unvote to downgrade the Rx thread priority from * RT Thread for Low-Latency use case. */ pdata = (struct msm_plat_data *) dev_get_drvdata(soc_prtd->platform->dev); if (pdata) { if (pdata->perf_mode == LOW_LATENCY_PCM_MODE) apr_end_rx_rt(prtd->audio_client->apr); } /* determine timeout length */ if (runtime->frame_bits == 0 || runtime->rate == 0) { timeout = CMD_EOS_MIN_TIMEOUT_LENGTH; Loading Loading
drivers/soc/qcom/qdsp6v2/apr.c +102 −1 Original line number Diff line number Diff line /* Copyright (c) 2010-2014, 2016, 2018 The Linux Foundation. /* Copyright (c) 2010-2014, 2016, 2018-2019 The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify Loading Loading @@ -758,6 +758,107 @@ static void apr_reset_deregister(struct work_struct *work) kfree(apr_reset); } /** * apr_start_rx_rt - Clients call to vote for thread * priority upgrade whenever needed. * * @handle: APR service handle * * Returns 0 on success or error otherwise. */ int apr_start_rx_rt(void *handle) { int rc = 0; struct apr_svc *svc = handle; uint16_t dest_id = 0; uint16_t client_id = 0; if (!svc) { pr_err("%s: Invalid APR handle\n", __func__); return -EINVAL; } mutex_lock(&svc->m_lock); dest_id = svc->dest_id; client_id = svc->client_id; if ((client_id >= APR_CLIENT_MAX) || (dest_id >= APR_DEST_MAX)) { pr_err("%s: %s invalid. client_id = %u, dest_id = %u\n", __func__, client_id >= APR_CLIENT_MAX ? "Client ID" : "Dest ID", client_id, dest_id); rc = -EINVAL; goto exit; } if (!client[dest_id][client_id].handle) { pr_err("%s: Client handle is NULL\n", __func__); rc = -EINVAL; goto exit; } rc = apr_tal_start_rx_rt(client[dest_id][client_id].handle); if (rc) pr_err("%s: failed to set RT thread priority for APR RX. rc = %d\n", __func__, rc); exit: mutex_unlock(&svc->m_lock); return rc; } EXPORT_SYMBOL(apr_start_rx_rt); /** * apr_end_rx_rt - Clients call to unvote for thread * priority upgrade (perviously voted with * apr_start_rx_rt()). * * @handle: APR service handle * * Returns 0 on success or error otherwise. */ int apr_end_rx_rt(void *handle) { int rc = 0; struct apr_svc *svc = handle; uint16_t dest_id = 0; uint16_t client_id = 0; if (!svc) { pr_err("%s: Invalid APR handle\n", __func__); return -EINVAL; } mutex_lock(&svc->m_lock); dest_id = svc->dest_id; client_id = svc->client_id; if ((client_id >= APR_CLIENT_MAX) || (dest_id >= APR_DEST_MAX)) { pr_err("%s: %s invalid. client_id = %u, dest_id = %u\n", __func__, client_id >= APR_CLIENT_MAX ? "Client ID" : "Dest ID", client_id, dest_id); rc = -EINVAL; goto exit; } if (!client[dest_id][client_id].handle) { pr_err("%s: Client handle is NULL\n", __func__); rc = -EINVAL; goto exit; } rc = apr_tal_end_rx_rt(client[dest_id][client_id].handle); if (rc) pr_err("%s: failed to reset RT thread priority for APR RX. rc = %d\n", __func__, rc); exit: mutex_unlock(&svc->m_lock); return rc; } EXPORT_SYMBOL(apr_end_rx_rt); int apr_deregister(void *handle) { struct apr_svc *svc = handle; Loading
drivers/soc/qcom/qdsp6v2/apr_tal_glink.c +33 −1 Original line number Diff line number Diff line /* Copyright (c) 2016-2017 The Linux Foundation. /* Copyright (c) 2016-2017, 2019 The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify Loading Loading @@ -358,6 +358,38 @@ unlock: return rc ? NULL : apr_ch; } int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch) { int rc = 0; if (!apr_ch || !apr_ch->handle) { rc = -EINVAL; goto exit; } mutex_lock(&apr_ch->m_lock); rc = glink_start_rx_rt(apr_ch->handle); mutex_unlock(&apr_ch->m_lock); exit: return rc; } int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch) { int rc = 0; if (!apr_ch || !apr_ch->handle) { rc = -EINVAL; goto exit; } mutex_lock(&apr_ch->m_lock); rc = glink_end_rx_rt(apr_ch->handle); mutex_unlock(&apr_ch->m_lock); exit: return rc; } int apr_tal_close(struct apr_svc_ch_dev *apr_ch) { int rc; Loading
include/linux/qdsp6v2/apr.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2017, 2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -196,4 +196,6 @@ int apr_set_q6_state(enum apr_subsys_state state); void apr_set_subsys_state(void); const char *apr_get_lpass_subsys_name(void); uint16_t apr_get_reset_domain(uint16_t proc); int apr_start_rx_rt(void *handle); int apr_end_rx_rt(void *handle); #endif
include/linux/qdsp6v2/apr_tal.h +9 −1 Original line number Diff line number Diff line /* Copyright (c) 2010-2011, 2016-2017 The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2011, 2016-2017, 2019 The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -78,6 +79,9 @@ int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, #if defined(CONFIG_MSM_QDSP6_APRV2_GLINK) || \ defined(CONFIG_MSM_QDSP6_APRV3_GLINK) int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch); int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch); struct apr_svc_ch_dev { void *handle; spinlock_t w_lock; Loading @@ -90,6 +94,10 @@ struct apr_svc_ch_dev { bool if_remote_intent_ready; }; #else static inline int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch) { return 0; } static inline int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch) { return 0; } struct apr_svc_ch_dev { struct smd_channel *ch; spinlock_t lock; Loading
sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c +22 −0 Original line number Diff line number Diff line Loading @@ -686,8 +686,15 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; struct msm_audio *prtd; struct msm_plat_data *pdata; int ret = 0; pdata = (struct msm_plat_data *) dev_get_drvdata(soc_prtd->platform->dev); if (!pdata) { pr_err("%s: platform data not populated\n", __func__); return -EINVAL; } prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL); if (prtd == NULL) { pr_err("Failed to allocate memory for msm_audio\n"); Loading Loading @@ -767,6 +774,10 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) prtd->reset_event = false; runtime->private_data = prtd; msm_adsp_init_mixer_ctl_pp_event_queue(soc_prtd); /* Vote to update the Rx thread priority to RT Thread for playback */ if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && (pdata->perf_mode == LOW_LATENCY_PCM_MODE)) apr_start_rx_rt(prtd->audio_client->apr); return 0; } Loading Loading @@ -874,6 +885,7 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; struct msm_audio *prtd = runtime->private_data; struct msm_plat_data *pdata; uint32_t timeout; int dir = 0; int ret = 0; Loading @@ -883,6 +895,16 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) if (prtd->audio_client) { dir = IN; /* * Unvote to downgrade the Rx thread priority from * RT Thread for Low-Latency use case. */ pdata = (struct msm_plat_data *) dev_get_drvdata(soc_prtd->platform->dev); if (pdata) { if (pdata->perf_mode == LOW_LATENCY_PCM_MODE) apr_end_rx_rt(prtd->audio_client->apr); } /* determine timeout length */ if (runtime->frame_bits == 0 || runtime->rate == 0) { timeout = CMD_EOS_MIN_TIMEOUT_LENGTH; Loading