summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Wei <lucaswei@google.com>2021-06-22 18:16:46 +0800
committerLucas Wei <lucaswei@google.com>2021-06-22 18:16:46 +0800
commit45edbf733479053bb97caf86cbf982df96173351 (patch)
tree06a1db673415392eb52dc0d3a44ad57b033b493f
parent525c625395885f30a4f6424cde533a11b4cc5990 (diff)
parent7c6cfed3e7ea8bb6371872aa8700d8d1f01456f4 (diff)
downloadmsm-extra-android-msm-barbet-4.19-android12-v2-beta-2.tar.gz
Bug: 187909050 Signed-off-by: Lucas Wei <lucaswei@google.com> Change-Id: I5355253bce3b7c945ea75f94f24d22ec601dacf5
-rw-r--r--asoc/codecs/bolero/bolero-cdc.c2
-rw-r--r--asoc/codecs/bolero/rx-macro.c27
-rw-r--r--asoc/codecs/bolero/tx-macro.c17
-rw-r--r--asoc/codecs/bolero/va-macro.c17
-rw-r--r--asoc/codecs/bolero/wsa-macro.c15
-rw-r--r--asoc/msm-pcm-routing-v2.c15
-rw-r--r--dsp/q6adm.c120
-rw-r--r--dsp/q6afe.c7
-rw-r--r--dsp/rtac.c4
-rw-r--r--include/dsp/q6adm-v2.h4
-rw-r--r--soc/swr-mstr-ctrl.c50
11 files changed, 149 insertions, 129 deletions
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index 53c70fab..e80a8239 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -1379,7 +1379,6 @@ static int bolero_probe(struct platform_device *pdev)
mutex_init(&priv->vote_lock);
INIT_WORK(&priv->bolero_add_child_devices_work,
bolero_add_child_devices);
- schedule_work(&priv->bolero_add_child_devices_work);
/* Register LPASS core hw vote */
lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote");
@@ -1403,6 +1402,7 @@ static int bolero_probe(struct platform_device *pdev)
}
priv->lpass_audio_hw_vote = lpass_audio_hw_vote;
+ schedule_work(&priv->bolero_add_child_devices_work);
return 0;
}
diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c
index 07dd8ada..9934a865 100644
--- a/asoc/codecs/bolero/rx-macro.c
+++ b/asoc/codecs/bolero/rx-macro.c
@@ -350,6 +350,7 @@ struct rx_macro_bcl_pmic_params {
u8 ppid;
};
+static int rx_macro_core_vote(void *handle, bool enable);
static int rx_macro_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai);
@@ -1230,10 +1231,12 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv,
if (rx_priv->rx_mclk_users == 0) {
if (rx_priv->is_native_on)
rx_priv->clk_id = RX_CORE_CLK;
+ rx_macro_core_vote(rx_priv, true);
ret = bolero_clk_rsc_request_clock(rx_priv->dev,
rx_priv->default_clk_id,
rx_priv->clk_id,
true);
+ rx_macro_core_vote(rx_priv, false);
if (ret < 0) {
dev_err(rx_priv->dev,
"%s: rx request clock enable failed\n",
@@ -1283,10 +1286,12 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv,
0x01, 0x00);
bolero_clk_rsc_fs_gen_request(rx_priv->dev,
false);
+ rx_macro_core_vote(rx_priv, true);
bolero_clk_rsc_request_clock(rx_priv->dev,
rx_priv->default_clk_id,
rx_priv->clk_id,
false);
+ rx_macro_core_vote(rx_priv, false);
rx_priv->clk_id = rx_priv->default_clk_id;
}
}
@@ -1396,18 +1401,21 @@ static int rx_macro_event_handler(struct snd_soc_component *component,
}
break;
case BOLERO_MACRO_EVT_PRE_SSR_UP:
+ rx_macro_core_vote(rx_priv, true);
/* enable&disable RX_CORE_CLK to reset GFMUX reg */
ret = bolero_clk_rsc_request_clock(rx_priv->dev,
rx_priv->default_clk_id,
RX_CORE_CLK, true);
- if (ret < 0)
+ if (ret < 0) {
dev_err_ratelimited(rx_priv->dev,
"%s, failed to enable clk, ret:%d\n",
__func__, ret);
- else
+ } else {
bolero_clk_rsc_request_clock(rx_priv->dev,
rx_priv->default_clk_id,
RX_CORE_CLK, false);
+ }
+ rx_macro_core_vote(rx_priv, false);
break;
case BOLERO_MACRO_EVT_SSR_UP:
trace_printk("%s, enter SSR up\n", __func__);
@@ -3672,22 +3680,25 @@ static const struct snd_soc_dapm_route rx_audio_map[] = {
static int rx_macro_core_vote(void *handle, bool enable)
{
+ int rc = 0;
struct rx_macro_priv *rx_priv = (struct rx_macro_priv *) handle;
if (rx_priv == NULL) {
pr_err("%s: rx priv data is NULL\n", __func__);
return -EINVAL;
}
+
if (enable) {
pm_runtime_get_sync(rx_priv->dev);
+ if (bolero_check_core_votes(rx_priv->dev))
+ rc = 0;
+ else
+ rc = -ENOTSYNC;
+ } else {
pm_runtime_put_autosuspend(rx_priv->dev);
pm_runtime_mark_last_busy(rx_priv->dev);
}
-
- if (bolero_check_core_votes(rx_priv->dev))
- return 0;
- else
- return -EINVAL;
+ return rc;
}
static int rx_swrm_clock(void *handle, bool enable)
@@ -4165,12 +4176,12 @@ static int rx_macro_probe(struct platform_device *pdev)
"%s: register macro failed\n", __func__);
goto err_reg_macro;
}
- schedule_work(&rx_priv->rx_macro_add_child_devices_work);
pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_suspend_ignore_children(&pdev->dev, true);
pm_runtime_enable(&pdev->dev);
+ schedule_work(&rx_priv->rx_macro_add_child_devices_work);
return 0;
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index 713357e9..2c95a62d 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -2678,22 +2678,25 @@ static int tx_macro_clk_switch(struct snd_soc_component *component, int clk_src)
static int tx_macro_core_vote(void *handle, bool enable)
{
+ int rc = 0;
struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
if (tx_priv == NULL) {
pr_err("%s: tx priv data is NULL\n", __func__);
return -EINVAL;
}
+
if (enable) {
pm_runtime_get_sync(tx_priv->dev);
+ if (bolero_check_core_votes(tx_priv->dev))
+ rc = 0;
+ else
+ rc = -ENOTSYNC;
+ } else {
pm_runtime_put_autosuspend(tx_priv->dev);
pm_runtime_mark_last_busy(tx_priv->dev);
}
-
- if (bolero_check_core_votes(tx_priv->dev))
- return 0;
- else
- return -EINVAL;
+ return rc;
}
static int tx_macro_swrm_clock(void *handle, bool enable)
@@ -3280,13 +3283,13 @@ static int tx_macro_probe(struct platform_device *pdev)
"%s: register macro failed\n", __func__);
goto err_reg_macro;
}
- if (is_used_tx_swr_gpio)
- schedule_work(&tx_priv->tx_macro_add_child_devices_work);
pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_suspend_ignore_children(&pdev->dev, true);
pm_runtime_enable(&pdev->dev);
+ if (is_used_tx_swr_gpio)
+ schedule_work(&tx_priv->tx_macro_add_child_devices_work);
return 0;
err_reg_macro:
diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c
index 79515882..1133d573 100644
--- a/asoc/codecs/bolero/va-macro.c
+++ b/asoc/codecs/bolero/va-macro.c
@@ -671,22 +671,25 @@ done:
static int va_macro_core_vote(void *handle, bool enable)
{
+ int rc = 0;
struct va_macro_priv *va_priv = (struct va_macro_priv *) handle;
if (va_priv == NULL) {
pr_err("%s: va priv data is NULL\n", __func__);
return -EINVAL;
}
+
if (enable) {
pm_runtime_get_sync(va_priv->dev);
+ if (bolero_check_core_votes(va_priv->dev))
+ rc = 0;
+ else
+ rc = -ENOTSYNC;
+ } else {
pm_runtime_put_autosuspend(va_priv->dev);
pm_runtime_mark_last_busy(va_priv->dev);
}
-
- if (bolero_check_core_votes(va_priv->dev))
- return 0;
- else
- return -EINVAL;
+ return rc;
}
static int va_macro_swrm_clock(void *handle, bool enable)
@@ -3142,13 +3145,13 @@ static int va_macro_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
goto reg_macro_fail;
}
- if (is_used_va_swr_gpio)
- schedule_work(&va_priv->va_macro_add_child_devices_work);
pm_runtime_set_autosuspend_delay(&pdev->dev, VA_AUTO_SUSPEND_DELAY);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_suspend_ignore_children(&pdev->dev, true);
pm_runtime_enable(&pdev->dev);
+ if (is_used_va_swr_gpio)
+ schedule_work(&va_priv->va_macro_add_child_devices_work);
return ret;
reg_macro_fail:
diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c
index 5ace96db..4e06d12b 100644
--- a/asoc/codecs/bolero/wsa-macro.c
+++ b/asoc/codecs/bolero/wsa-macro.c
@@ -2828,22 +2828,25 @@ static void wsa_macro_init_reg(struct snd_soc_component *component)
static int wsa_macro_core_vote(void *handle, bool enable)
{
+ int rc = 0;
struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
if (wsa_priv == NULL) {
pr_err("%s: wsa priv data is NULL\n", __func__);
return -EINVAL;
}
+
if (enable) {
pm_runtime_get_sync(wsa_priv->dev);
+ if (bolero_check_core_votes(wsa_priv->dev))
+ rc = 0;
+ else
+ rc = -ENOTSYNC;
+ } else {
pm_runtime_put_autosuspend(wsa_priv->dev);
pm_runtime_mark_last_busy(wsa_priv->dev);
}
-
- if (bolero_check_core_votes(wsa_priv->dev))
- return 0;
- else
- return -EINVAL;
+ return rc;
}
static int wsa_swrm_clock(void *handle, bool enable)
@@ -3237,12 +3240,12 @@ static int wsa_macro_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
goto reg_macro_fail;
}
- schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_suspend_ignore_children(&pdev->dev, true);
pm_runtime_enable(&pdev->dev);
+ schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
return ret;
reg_macro_fail:
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index 05650130..a704b570 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -1731,6 +1731,11 @@ static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode,
for (i = 0; i < ADM_MAX_CHANNELS && channel_input[fe_id][i] > 0;
++i) {
be_id = channel_input[fe_id][i] - 1;
+ if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) {
+ pr_err("%s: Received out of bounds be_id %d\n",
+ __func__, be_id);
+ return -EINVAL;
+ }
channel_mixer[fe_id].input_channels[i] =
msm_bedais[be_id].channel;
@@ -3526,10 +3531,10 @@ static int msm_pcm_get_out_chs(struct snd_kcontrol *kcontrol,
static int msm_pcm_put_out_chs(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- u16 fe_id = 0;
-
+ u16 fe_id = 0, out_ch = 0;
fe_id = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->shift;
+ out_ch = ucontrol->value.integer.value[0];
if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
pr_err("%s: invalid FE %d\n", __func__, fe_id);
return -EINVAL;
@@ -3538,6 +3543,12 @@ static int msm_pcm_put_out_chs(struct snd_kcontrol *kcontrol,
pr_debug("%s: fe_id is %d, output channels = %d\n", __func__,
fe_id,
(unsigned int)(ucontrol->value.integer.value[0]));
+ if (out_ch < 0 ||
+ out_ch > ADM_MAX_CHANNELS) {
+ pr_err("%s: invalid output channel %d\n", __func__,
+ out_ch);
+ return -EINVAL;
+ }
channel_mixer[fe_id].output_channel =
(unsigned int)(ucontrol->value.integer.value[0]);
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index 708cc0fd..e63547d8 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -874,10 +874,11 @@ EXPORT_SYMBOL(adm_set_custom_chmix_cfg);
* adm_apr_send_pkt : returns 0 on success, negative otherwise.
*/
int adm_apr_send_pkt(void *data, wait_queue_head_t *wait,
- int port_idx, int copp_idx)
+ int port_idx, int copp_idx, int opcode)
{
int ret = 0;
atomic_t *copp_stat = NULL;
+ int32_t time_out = msecs_to_jiffies(TIMEOUT_MS);
wait = &this_adm.copp.wait[port_idx][copp_idx];
if (!wait)
@@ -889,18 +890,30 @@ int adm_apr_send_pkt(void *data, wait_queue_head_t *wait,
copp_stat = &this_adm.copp.stat[port_idx][copp_idx];
atomic_set(copp_stat, -1);
- if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]) == 0) {
- pr_err("%s: port[0x%x] coppid[0x%x] is not active, ERROR\n",
- __func__, port_idx, copp_idx);
- mutex_unlock(&this_adm.adm_apr_lock);
- return -EINVAL;
+ if (opcode != ADM_CMD_DEVICE_OPEN_V8 &&
+ opcode != ADM_CMD_DEVICE_OPEN_V6 &&
+ opcode != ADM_CMD_DEVICE_OPEN_V5 &&
+ opcode != ADM_CMD_DEVICE_CLOSE_V5) {
+ if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx])
+ == 0) {
+ pr_err("%s: port[0x%x] copp[0x%x] inactive\n",
+ __func__, port_idx, copp_idx);
+ mutex_unlock(&this_adm.adm_apr_lock);
+ return -EINVAL;
+ }
+ }
+
+ if (opcode == ADM_CMD_DEVICE_OPEN_V8 ||
+ opcode == ADM_CMD_DEVICE_OPEN_V6 ||
+ opcode == ADM_CMD_DEVICE_OPEN_V5) {
+ time_out = msecs_to_jiffies(2 * TIMEOUT_MS);
}
ret = apr_send_pkt(this_adm.apr, data);
if (ret > 0) {
ret = wait_event_timeout(*wait,
atomic_read(copp_stat) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
+ time_out);
if (atomic_read(copp_stat) > 0) {
pr_err("%s: DSP returned error[%s]\n", __func__,
adsp_err_get_err_str(atomic_read(copp_stat)));
@@ -992,7 +1005,7 @@ int adm_set_pp_params(int port_id, int copp_idx,
}
ret = adm_apr_send_pkt((uint32_t *) adm_set_params,
&this_adm.copp.wait[port_idx][copp_idx],
- port_idx, copp_idx);
+ port_idx, copp_idx, adm_set_params->apr_hdr.opcode);
done:
kfree(adm_set_params);
return ret;
@@ -1045,7 +1058,6 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id,
int returned_param_size_in_bytes = 0;
int port_idx = 0;
int idx = 0;
- atomic_t *copp_stat = NULL;
int ret = 0;
if (param_hdr == NULL) {
@@ -1093,33 +1105,9 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id,
else
adm_get_params.apr_hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5;
- copp_stat = &this_adm.copp.stat[port_idx][copp_idx];
- atomic_set(copp_stat, -1);
-
- ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_params);
- if (ret < 0) {
- pr_err("%s: Get params APR send failed port = 0x%x ret %d\n",
- __func__, port_id, ret);
- ret = -EINVAL;
- goto done;
- }
- ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(copp_stat) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: Get params timed out port = 0x%x\n", __func__,
- port_id);
- ret = -ETIMEDOUT;
- goto done;
- }
- if (atomic_read(copp_stat) > 0) {
- pr_err("%s: DSP returned error[%s]\n", __func__,
- adsp_err_get_err_str(atomic_read(copp_stat)));
- ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat));
- goto done;
- }
-
- ret = 0;
+ ret = adm_apr_send_pkt((uint32_t *) &adm_get_params,
+ &this_adm.copp.wait[port_idx][copp_idx],
+ port_idx, copp_idx, adm_get_params.apr_hdr.opcode);
/* Copy data to caller if sent in band */
if (!returned_param_data) {
@@ -1147,7 +1135,6 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id,
memcpy(returned_param_data, &adm_get_parameters[idx + 1],
returned_param_size_in_bytes);
-done:
return ret;
}
EXPORT_SYMBOL(adm_get_pp_params);
@@ -3328,8 +3315,9 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
ep2_payload_size);
}
- ret = apr_send_pkt(this_adm.apr,
- (uint32_t *)adm_params);
+ ret = adm_apr_send_pkt((uint32_t *) adm_params,
+ &this_adm.copp.wait[port_idx][copp_idx],
+ port_idx, copp_idx, open_v8.hdr.opcode);
if (ret < 0) {
pr_err("%s: port_id: 0x%x for[0x%x] failed %d for open_v8\n",
__func__, tmp_port, port_id, ret);
@@ -3415,11 +3403,13 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
if (ret)
return ret;
- ret = apr_send_pkt(this_adm.apr,
- (uint32_t *)&open_v6);
+ ret = adm_apr_send_pkt((uint32_t *) &open_v6,
+ &this_adm.copp.wait[port_idx][copp_idx],
+ port_idx, copp_idx, open_v6.hdr.opcode);
} else {
- ret = apr_send_pkt(this_adm.apr,
- (uint32_t *)&open);
+ ret = adm_apr_send_pkt((uint32_t *) &open,
+ &this_adm.copp.wait[port_idx][copp_idx],
+ port_idx, copp_idx, open.hdr.opcode);
}
if (ret < 0) {
pr_err("%s: port_id: 0x%x for[0x%x] failed %d\n",
@@ -3427,26 +3417,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
return -EINVAL;
}
}
-
- /* Wait for the callback with copp id */
- ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(2 * TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: ADM open timedout for port_id: 0x%x for [0x%x]\n",
- __func__, tmp_port, port_id);
- return -EINVAL;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- return adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- }
}
atomic_inc(&this_adm.copp.cnt[port_idx][copp_idx]);
@@ -3951,31 +3921,13 @@ int adm_close(int port_id, int perf_mode, int copp_idx)
clear_bit(ADM_STATUS_CALIBRATION_REQUIRED,
(void *)&this_adm.copp.adm_status[port_idx][copp_idx]);
-
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)&close);
+ ret = adm_apr_send_pkt((uint32_t *) &close,
+ &this_adm.copp.wait[port_idx][copp_idx],
+ port_idx, copp_idx, close.opcode);
if (ret < 0) {
pr_err("%s: ADM close failed %d\n", __func__, ret);
return -EINVAL;
}
-
- ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: ADM cmd Route timedout for port 0x%x\n",
- __func__, port_id);
- return -EINVAL;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- return adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- }
}
if (perf_mode != ULTRA_LOW_LATENCY_PCM_MODE) {
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 4aaa0194..e7cba919 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -10598,6 +10598,7 @@ static int afe_get_cal_sp_th_vi_param(int32_t cal_type, size_t data_size,
if (cal_data == NULL ||
data_size > sizeof(*cal_data) ||
+ data_size < sizeof(cal_data->cal_hdr) ||
this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL)
return 0;
@@ -10626,7 +10627,8 @@ static int afe_get_cal_spv4_ex_vi_ftm_param(int32_t cal_type, size_t data_size,
pr_debug("%s: cal_type = %d\n", __func__, cal_type);
if (this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL] == NULL ||
cal_data == NULL ||
- data_size != sizeof(*cal_data))
+ data_size > sizeof(*cal_data) ||
+ data_size < sizeof(cal_data->cal_hdr))
goto done;
mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock);
@@ -10693,7 +10695,8 @@ static int afe_get_cal_sp_ex_vi_ftm_param(int32_t cal_type, size_t data_size,
pr_debug("%s: cal_type = %d\n", __func__, cal_type);
if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL ||
cal_data == NULL ||
- data_size != sizeof(*cal_data))
+ data_size > sizeof(*cal_data) ||
+ data_size < sizeof(cal_data->cal_hdr))
goto done;
mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock);
diff --git a/dsp/rtac.c b/dsp/rtac.c
index ed298e9c..4ae16f06 100644
--- a/dsp/rtac.c
+++ b/dsp/rtac.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/fs.h>
@@ -882,7 +882,7 @@ int send_adm_apr(void *buf, u32 opcode)
mutex_unlock(&rtac_adm_apr_mutex);
result = adm_apr_send_pkt((uint32_t *)rtac_adm_buffer,
- NULL, port_idx, copp_idx);
+ NULL, port_idx, copp_idx, adm_params.opcode);
mutex_lock(&rtac_adm_apr_mutex);
if (opcode == ADM_CMD_GET_PP_PARAMS_V5) {
diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h
index 20b2450b..84fc1e01 100644
--- a/include/dsp/q6adm-v2.h
+++ b/include/dsp/q6adm-v2.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
*/
#ifndef __Q6_ADM_V2_H__
#define __Q6_ADM_V2_H__
@@ -230,5 +230,5 @@ void msm_dts_srs_release_lock(void);
void adm_set_native_mode(int mode);
int adm_set_ffecns_freeze_event(bool ffecns_freeze_event);
int adm_apr_send_pkt(void *data, wait_queue_head_t *wait,
- int port_idx, int copp_idx);
+ int port_idx, int copp_idx, int opcode);
#endif /* __Q6_ADM_V2_H__ */
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index 80fa3947..a3662010 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -457,7 +457,7 @@ static int swrm_get_ssp_period(struct swr_mstr_ctrl *swrm,
return ((swrm->bus_clk * 2) / ((row * col) * frame_sync));
}
-static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm)
+static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm, bool enable)
{
int ret = 0;
@@ -470,7 +470,7 @@ static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm)
goto exit;
}
if (swrm->core_vote) {
- ret = swrm->core_vote(swrm->handle, true);
+ ret = swrm->core_vote(swrm->handle, enable);
if (ret)
dev_err_ratelimited(swrm->dev,
"%s: core vote request failed\n", __func__);
@@ -501,8 +501,10 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable)
dev_err_ratelimited(swrm->dev,
"%s: core vote request failed\n",
__func__);
+ swrm->core_vote(swrm->handle, false);
goto exit;
}
+ ret = swrm->core_vote(swrm->handle, false);
}
}
swrm->clk_ref_count++;
@@ -538,6 +540,7 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm,
{
u32 temp = (u32)(*value);
int ret = 0;
+ int vote_ret = 0;
mutex_lock(&swrm->devlock);
if (!swrm->dev_up)
@@ -551,13 +554,20 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm,
__func__);
goto err;
}
- } else if (swrm_core_vote_request(swrm)) {
- goto err;
+ } else {
+ vote_ret = swrm_core_vote_request(swrm, true);
+ if (vote_ret == -ENOTSYNC)
+ goto err_vote;
+ else if (vote_ret)
+ goto err;
}
iowrite32(temp, swrm->swrm_dig_base + reg);
if (is_swr_clk_needed(swrm))
swrm_clk_request(swrm, FALSE);
+err_vote:
+ if (!is_swr_clk_needed(swrm))
+ swrm_core_vote_request(swrm, false);
err:
mutex_unlock(&swrm->devlock);
return ret;
@@ -568,6 +578,7 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm,
{
u32 temp = 0;
int ret = 0;
+ int vote_ret = 0;
mutex_lock(&swrm->devlock);
if (!swrm->dev_up)
@@ -580,14 +591,21 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm,
__func__);
goto err;
}
- } else if (swrm_core_vote_request(swrm)) {
- goto err;
+ } else {
+ vote_ret = swrm_core_vote_request(swrm, true);
+ if (vote_ret == -ENOTSYNC)
+ goto err_vote;
+ else if (vote_ret)
+ goto err;
}
temp = ioread32(swrm->swrm_dig_base + reg);
*value = temp;
if (is_swr_clk_needed(swrm))
swrm_clk_request(swrm, FALSE);
+err_vote:
+ if (!is_swr_clk_needed(swrm))
+ swrm_core_vote_request(swrm, false);
err:
mutex_unlock(&swrm->devlock);
return ret;
@@ -2576,6 +2594,7 @@ static int swrm_probe(struct platform_device *pdev)
int ret = 0;
struct clk *lpass_core_hw_vote = NULL;
struct clk *lpass_core_audio = NULL;
+ u32 swrm_hw_ver = 0;
/* Allocate soundwire master driver structure */
swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl),
@@ -2602,6 +2621,14 @@ static int swrm_probe(struct platform_device *pdev)
ret = -EINVAL;
goto err_pdata_fail;
}
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,swr-master-version",
+ &swrm->version);
+ if (ret) {
+ dev_dbg(&pdev->dev, "%s: swrm version not defined, use default\n",
+ __func__);
+ swrm->version = SWRM_VERSION_1_6;
+ }
ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr_master_id",
&swrm->master_id);
if (ret) {
@@ -2849,7 +2876,11 @@ static int swrm_probe(struct platform_device *pdev)
swr_master_add_boarddevices(&swrm->master);
mutex_lock(&swrm->mlock);
swrm_clk_request(swrm, true);
- swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION);
+ swrm_hw_ver = swr_master_read(swrm, SWRM_COMP_HW_VERSION);
+ if (swrm->version != swrm_hw_ver)
+ dev_info(&pdev->dev,
+ "%s: version specified in dtsi: 0x%x not match with HW read version 0x%x\n",
+ __func__, swrm->version, swrm_hw_ver);
ret = swrm_master_init(swrm);
if (ret < 0) {
dev_err(&pdev->dev,
@@ -3127,6 +3158,7 @@ static int swrm_runtime_suspend(struct device *dev)
struct swr_master *mstr = &swrm->master;
struct swr_device *swr_dev;
int current_state = 0;
+ struct irq_data *irq_data = NULL;
trace_printk("%s: pm_runtime: suspend state: %d\n",
__func__, swrm->state);
@@ -3235,7 +3267,9 @@ static int swrm_runtime_suspend(struct device *dev)
if (swrm->clk_stop_mode0_supp) {
if (swrm->wake_irq > 0) {
- enable_irq(swrm->wake_irq);
+ irq_data = irq_get_irq_data(swrm->wake_irq);
+ if (irq_data && irqd_irq_disabled(irq_data))
+ enable_irq(swrm->wake_irq);
} else if (swrm->ipc_wakeup) {
msm_aud_evt_blocking_notifier_call_chain(
SWR_WAKE_IRQ_REGISTER, (void *)swrm);