diff --git a/techpack/audio/asoc/msm-pcm-host-voice-v2.c b/techpack/audio/asoc/msm-pcm-host-voice-v2.c index 3319e3dceb67..ad5ab90bee1a 100644 --- a/techpack/audio/asoc/msm-pcm-host-voice-v2.c +++ b/techpack/audio/asoc/msm-pcm-host-voice-v2.c @@ -663,6 +663,13 @@ static void hpcm_copy_playback_data_from_queue(struct dai_data *dai_data, struct hpcm_buf_node, list); list_del(&buf_node->list); *len = buf_node->frame.len; + + if (*len > HPCM_MAX_VOC_PKT_SIZE) { + pr_err("%s: Playback data len %d overflow\n", + __func__, *len); + return; + } + memcpy((u8 *)dai_data->vocpcm_ion_buffer.kvaddr, &buf_node->frame.voc_pkt[0], buf_node->frame.len); @@ -690,8 +697,8 @@ static void hpcm_copy_capture_data_to_queue(struct dai_data *dai_data, if (dai_data->substream == NULL) return; - if (len >= HPCM_MAX_VOC_PKT_SIZE) { - pr_err("%s: Copy capture data len %d is > HPCM_MAX_VOC_PKT_SIZE\n", + if (len > HPCM_MAX_VOC_PKT_SIZE) { + pr_err("%s: Copy capture data len %d overflow\n", __func__, len); return; } diff --git a/techpack/audio/asoc/msm-pcm-q6-v2.c b/techpack/audio/asoc/msm-pcm-q6-v2.c index b26ae17520c7..bb19c4b7d386 100644 --- a/techpack/audio/asoc/msm-pcm-q6-v2.c +++ b/techpack/audio/asoc/msm-pcm-q6-v2.c @@ -1336,7 +1336,7 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, goto fail; } - if (size == 0 || size < prtd->pcm_count) { + if ((size == 0 || size < prtd->pcm_count) && ((offset + size) < prtd->pcm_count)) { memset(bufptr + offset + size, 0, prtd->pcm_count - size); if (fbytes > prtd->pcm_count) size = xfer = prtd->pcm_count; diff --git a/techpack/audio/asoc/msm-pcm-routing-v2.c b/techpack/audio/asoc/msm-pcm-routing-v2.c index 1f9655710892..af333527757d 100644 --- a/techpack/audio/asoc/msm-pcm-routing-v2.c +++ b/techpack/audio/asoc/msm-pcm-routing-v2.c @@ -36106,6 +36106,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia5 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, @@ -36122,7 +36123,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia6 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, @@ -36131,6 +36131,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, {"MultiMedia6 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"MultiMedia6 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, +#endif + {"MultiMedia6 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -36236,6 +36238,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia10 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia16 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia16 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, {"MultiMedia16 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, @@ -36252,6 +36255,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia16 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia16 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia16 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, +#endif {"MultiMedia16 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, @@ -36286,6 +36290,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia18 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia18 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, {"MultiMedia18 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia18 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, @@ -36294,6 +36299,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia18 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, {"MultiMedia18 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"MultiMedia18 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, +#endif {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, @@ -36305,6 +36311,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia19 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, {"MultiMedia19 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia19 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, @@ -36313,6 +36320,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, {"MultiMedia19 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"MultiMedia19 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, +#endif {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -36323,6 +36331,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia28 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia28 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, {"MultiMedia28 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia28 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, @@ -36331,6 +36340,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia28 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, {"MultiMedia28 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"MultiMedia28 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, +#endif {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -36341,6 +36351,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia29 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, +#ifndef CONFIG_TDM_DISABLE {"MultiMedia29 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, {"MultiMedia29 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia29 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, @@ -36349,6 +36360,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia29 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, {"MultiMedia29 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"MultiMedia29 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, +#endif {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, diff --git a/techpack/audio/dsp/q6afe.c b/techpack/audio/dsp/q6afe.c index d1acb5c9fe0e..ed856382ece3 100644 --- a/techpack/audio/dsp/q6afe.c +++ b/techpack/audio/dsp/q6afe.c @@ -1327,6 +1327,9 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) sizeof(struct afe_port_mod_evt_rsp_hdr)); uint32_t *dc_presence_flag = num_channels + 1; + if (*num_channels < 1 || *num_channels > 4) + return -EINVAL; + for (i = 0; i < *num_channels; i++) { if (dc_presence_flag[i] == 1) dc_detected = true; @@ -8730,6 +8733,14 @@ static int afe_sidetone_iir(u16 tx_port_id) pr_debug("%s: adding 2 to size:%d\n", __func__, size); size = size + 2; } + + if (size > MAX_SIDETONE_IIR_DATA_SIZE) { + pr_err("%s: iir_config size is out of bounds:%d\n", __func__, size); + mutex_unlock(&this_afe.cal_data[cal_index]->lock); + ret = -EINVAL; + goto done; + } + memcpy(&filter_data.iir_config, &st_iir_cal_info->iir_config, size); mutex_unlock(&this_afe.cal_data[cal_index]->lock); diff --git a/techpack/audio/dsp/q6asm.c b/techpack/audio/dsp/q6asm.c index ed84f225f017..ea4db1956da2 100644 --- a/techpack/audio/dsp/q6asm.c +++ b/techpack/audio/dsp/q6asm.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -2434,6 +2435,15 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) config_debug_fs_read_cb(); + if (data->payload_size != (READDONE_IDX_SEQ_ID + 1) * sizeof(uint32_t)) { + pr_err("%s: payload size of %d is less than expected %d.\n", + __func__, data->payload_size, + ((READDONE_IDX_SEQ_ID + 1) * sizeof(uint32_t))); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); + return -EINVAL; + } dev_vdbg(ac->dev, "%s: ReadDone: status=%d buff_add=0x%x act_size=%d offset=%d\n", __func__, payload[READDONE_IDX_STATUS], payload[READDONE_IDX_BUFADD_LSW], diff --git a/techpack/audio/soc/swr-mstr-ctrl.c b/techpack/audio/soc/swr-mstr-ctrl.c index 752d5c2b2940..098f2fe1c36c 100644 --- a/techpack/audio/soc/swr-mstr-ctrl.c +++ b/techpack/audio/soc/swr-mstr-ctrl.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1738,6 +1738,8 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n", __func__); pm_runtime_mark_last_busy(swrm->dev); + if (!enable) + pm_runtime_set_autosuspend_delay(swrm->dev, 80); pm_runtime_put_autosuspend(swrm->dev); } exit: @@ -2848,6 +2850,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->clklock); mutex_init(&swrm->devlock); mutex_init(&swrm->pm_lock); + mutex_init(&swrm->runtime_lock); swrm->wlock_holders = 0; swrm->pm_state = SWRM_PM_SLEEPABLE; init_waitqueue_head(&swrm->pm_wq); @@ -3020,6 +3023,7 @@ err_irq_fail: mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->pm_lock); pm_qos_remove_request(&swrm->pm_qos_req); + mutex_destroy(&swrm->runtime_lock); err_pdata_fail: err_memory_fail: @@ -3059,6 +3063,7 @@ static int swrm_remove(struct platform_device *pdev) mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->pm_lock); pm_qos_remove_request(&swrm->pm_qos_req); + mutex_destroy(&swrm->runtime_lock); devm_kfree(&pdev->dev, swrm); return 0; } @@ -3090,6 +3095,7 @@ static int swrm_runtime_resume(struct device *dev) dev_dbg(dev, "%s: pm_runtime: resume, state:%d\n", __func__, swrm->state); + mutex_lock(&swrm->runtime_lock); mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { @@ -3101,6 +3107,7 @@ static int swrm_runtime_resume(struct device *dev) if (swrm->req_clk_switch) swrm->req_clk_switch = false; mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); return 0; } if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { @@ -3118,6 +3125,7 @@ static int swrm_runtime_resume(struct device *dev) pr_err("%s: irq data is NULL\n", __func__); mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); return IRQ_NONE; } mutex_lock(&swrm->irq_lock); @@ -3157,7 +3165,9 @@ static int swrm_runtime_resume(struct device *dev) } swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); - swr_master_write(swrm, SWRM_MCP_BUS_CTRL, 0x01); + if (swrm->version > SWRM_VERSION_1_5) + swr_master_write(swrm, SWRM_MCP_BUS_CTRL, 0x01); + swrm_master_init(swrm); /* wait for hw enumeration to complete */ usleep_range(100, 105); @@ -3209,6 +3219,7 @@ exit: if (swrm->req_clk_switch) swrm->req_clk_switch = false; mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); return ret; } @@ -3230,6 +3241,7 @@ static int swrm_runtime_suspend(struct device *dev) swrm->state = SWR_MSTR_SSR; return 0; } + mutex_lock(&swrm->runtime_lock); mutex_lock(&swrm->reslock); mutex_lock(&swrm->force_down_lock); current_state = swrm->state; @@ -3327,6 +3339,10 @@ exit: if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); + dev_dbg(dev, "%s: pm_runtime: suspend done state: %d\n", + __func__, swrm->state); + pm_runtime_set_autosuspend_delay(dev, auto_suspend_timer); return ret; } #endif /* CONFIG_PM */ diff --git a/techpack/audio/soc/swr-mstr-ctrl.h b/techpack/audio/soc/swr-mstr-ctrl.h index 8cb613aaf125..1793d8bdfa09 100644 --- a/techpack/audio/soc/swr-mstr-ctrl.h +++ b/techpack/audio/soc/swr-mstr-ctrl.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _SWR_WCD_CTRL_H @@ -134,6 +135,7 @@ struct swr_mstr_ctrl { struct mutex reslock; struct mutex pm_lock; struct mutex irq_lock; + struct mutex runtime_lock; u32 swrm_base_reg; char __iomem *swrm_dig_base; char __iomem *swrm_hctl_reg;