From 5759d8e2892c65d6542ddd40b11367ec2d8cd7ee Mon Sep 17 00:00:00 2001 From: Vijay Kumar Maddula Date: Fri, 2 Aug 2024 01:46:01 +0530 Subject: [PATCH 1/4] asoc: codec: wcd934x: enable auto recovery when port overflows Sometimes audio is mute while capturing from dmics connected to wcd934x codec. Observed slimbus slave port overflows in non working scenario. Enable auto recovery from overflows on the slim slave port. Change-Id: Iad18b80ea13432478fb8a8e1f07bdc354a7106b3 --- asoc/codecs/wcd934x/wcd934x.c | 21 ++++++++++++++++++++- include/asoc/wcd934x_registers.h | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index bd98a054572c..baaa769bb1a9 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -153,6 +153,8 @@ static const struct snd_kcontrol_new name##_mux = \ #define WCD934X_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000) +#define ENABLE_FIFO_OVERRUN_AUTO_RECOVERY_BIT 0x1 + enum { POWER_COLLAPSE, POWER_RESUME, @@ -1561,6 +1563,14 @@ static void tavil_codec_enable_slim_port_intr( val = wcd9xxx_interface_reg_read( tavil_p->wcd9xxx, reg); } + /* Enable auto recovery from slim port overflow on port_num */ + reg = WCD934X_SLIM_PGD_PORT_TX_OR_UR_CFG_0 + port_num; + val = wcd9xxx_interface_reg_read(tavil_p->wcd9xxx, reg); + if(!(val & (1 << ENABLE_FIFO_OVERRUN_AUTO_RECOVERY_BIT))) { + val = val | (1 << ENABLE_FIFO_OVERRUN_AUTO_RECOVERY_BIT); + wcd9xxx_interface_reg_write(tavil_p->wcd9xxx, reg, val); + val = wcd9xxx_interface_reg_read(tavil_p->wcd9xxx, reg); + } } } } @@ -10018,6 +10028,15 @@ static irqreturn_t tavil_slimbus_irq(int irq, void *data) WARN(!cleared, "Couldn't find slimbus %s port %d for closing\n", (tx ? "TX" : "RX"), port_id); + + /* Enable auto recovery from slim port overflow on port_num */ + reg = WCD934X_SLIM_PGD_PORT_TX_OR_UR_CFG_0 + port_id; + val = wcd9xxx_interface_reg_read(tavil->wcd9xxx, reg); + if((val & (1 << ENABLE_FIFO_OVERRUN_AUTO_RECOVERY_BIT))) { + val = val ^ (1 << ENABLE_FIFO_OVERRUN_AUTO_RECOVERY_BIT); + wcd9xxx_interface_reg_write(tavil->wcd9xxx, reg, val); + val = wcd9xxx_interface_reg_read(tavil->wcd9xxx, reg); + } } wcd9xxx_interface_reg_write(tavil->wcd9xxx, WCD934X_SLIM_PGD_PORT_INT_CLR_RX_0 + diff --git a/include/asoc/wcd934x_registers.h b/include/asoc/wcd934x_registers.h index e529f6415650..eb32595e7e0b 100644 --- a/include/asoc/wcd934x_registers.h +++ b/include/asoc/wcd934x_registers.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _WCD934X_REGISTERS_H @@ -1836,5 +1837,6 @@ enum { #define WCD934X_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B) #define WCD934X_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60) #define WCD934X_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70) +#define WCD934X_SLIM_PGD_PORT_TX_OR_UR_CFG_0 (0x1F0) #endif From c90d923bdd966f29940bd9e3bb8bd44716b92fec Mon Sep 17 00:00:00 2001 From: Thrithendra Ungarala Date: Tue, 23 Jul 2024 14:49:45 +0530 Subject: [PATCH 2/4] asoc: Fixed OOB issue in qcs405 Fixed OOB issue is in function msm_meta_mi2s_snd_shutdown Change-Id: I8be7d019eb9b89baaef71fa53dd6c7f2383181c0 Signed-off-by: Thrithendra Ungarala Signed-off-by: basappa --- asoc/qcs405.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 8b012c6c7ccd..0cdc7268a9d7 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -7376,7 +7376,7 @@ static void msm_meta_mi2s_snd_shutdown(struct snd_pcm_substream *substream) pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); - if (index < PRIM_MI2S || index >= MI2S_MAX) { + if (index < PRIM_MI2S || index >= META_MI2S_MAX) { pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); return; } From 448a545731195eae632ed5852f8c07133f8a242c Mon Sep 17 00:00:00 2001 From: Abinath S Date: Fri, 9 Aug 2024 17:53:45 +0530 Subject: [PATCH 3/4] asoc: codec: avoid out of bound write to map array added check for port num and channel iteration are lessthan 8 to avoid out of bound write to 8x8 map array. Change-Id: I4c6fe13a5eb09be623a1c40ce16c5a5e4246e021 Signed-off-by: Abinath S --- asoc/codecs/rouleur/rouleur.c | 5 +++++ asoc/codecs/wcd937x/wcd937x.c | 6 +++++- asoc/codecs/wcd938x/wcd938x.c | 8 +++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index b29ba3b43a62..059ef6b015c3 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -257,6 +258,10 @@ static int rouleur_parse_port_mapping(struct device *dev, for (i = 0; i < map_length; i++) { port_num = dt_array[NUM_SWRS_DT_PARAMS * i]; + if (port_num >= MAX_PORT || ch_iter >= MAX_CH_PER_PORT) { + dev_err(dev, "%s: Invalid port or channel number\n", __func__); + goto err_pdata_fail; + } slave_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 1]; ch_mask = dt_array[NUM_SWRS_DT_PARAMS * i + 2]; ch_rate = dt_array[NUM_SWRS_DT_PARAMS * i + 3]; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 3306130ccd78..184cb7c533ea 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -315,6 +315,10 @@ static int wcd937x_parse_port_mapping(struct device *dev, for (i = 0; i < map_length; i++) { port_num = dt_array[NUM_SWRS_DT_PARAMS * i]; + if (port_num >= MAX_PORT || ch_iter >= MAX_CH_PER_PORT) { + dev_err(dev, "%s: Invalid port or channel number\n", __func__); + goto err_pdata_fail; + } slave_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 1]; ch_mask = dt_array[NUM_SWRS_DT_PARAMS * i + 2]; ch_rate = dt_array[NUM_SWRS_DT_PARAMS * i + 3]; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 3448e41f0727..8497a36b3002 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -395,6 +395,12 @@ static int wcd938x_parse_port_mapping(struct device *dev, for (i = 0; i < map_length; i++) { port_num = dt_array[NUM_SWRS_DT_PARAMS * i]; + + if (port_num >= MAX_PORT || ch_iter >= MAX_CH_PER_PORT) { + dev_err(dev, "%s: Invalid port or channel number\n", __func__); + goto err_pdata_fail; + } + slave_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 1]; ch_mask = dt_array[NUM_SWRS_DT_PARAMS * i + 2]; ch_rate = dt_array[NUM_SWRS_DT_PARAMS * i + 3]; From 921fe7a715ee9aa05754de3c7988430997fb20e8 Mon Sep 17 00:00:00 2001 From: Abinath S Date: Fri, 9 Aug 2024 17:53:45 +0530 Subject: [PATCH 4/4] asoc: codec: avoid out of bound write to map array added check for port num and channel iteration are lessthan 8 to avoid out of bound write to 8x8 map array. Change-Id: I4c6fe13a5eb09be623a1c40ce16c5a5e4246e021 Signed-off-by: Abinath S (cherry picked from commit 448a545731195eae632ed5852f8c07133f8a242c) --- asoc/codecs/rouleur/rouleur.c | 5 +++++ asoc/codecs/wcd937x/wcd937x.c | 6 +++++- asoc/codecs/wcd938x/wcd938x.c | 8 +++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index b29ba3b43a62..059ef6b015c3 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -257,6 +258,10 @@ static int rouleur_parse_port_mapping(struct device *dev, for (i = 0; i < map_length; i++) { port_num = dt_array[NUM_SWRS_DT_PARAMS * i]; + if (port_num >= MAX_PORT || ch_iter >= MAX_CH_PER_PORT) { + dev_err(dev, "%s: Invalid port or channel number\n", __func__); + goto err_pdata_fail; + } slave_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 1]; ch_mask = dt_array[NUM_SWRS_DT_PARAMS * i + 2]; ch_rate = dt_array[NUM_SWRS_DT_PARAMS * i + 3]; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 3306130ccd78..184cb7c533ea 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -315,6 +315,10 @@ static int wcd937x_parse_port_mapping(struct device *dev, for (i = 0; i < map_length; i++) { port_num = dt_array[NUM_SWRS_DT_PARAMS * i]; + if (port_num >= MAX_PORT || ch_iter >= MAX_CH_PER_PORT) { + dev_err(dev, "%s: Invalid port or channel number\n", __func__); + goto err_pdata_fail; + } slave_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 1]; ch_mask = dt_array[NUM_SWRS_DT_PARAMS * i + 2]; ch_rate = dt_array[NUM_SWRS_DT_PARAMS * i + 3]; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 3448e41f0727..8497a36b3002 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -395,6 +395,12 @@ static int wcd938x_parse_port_mapping(struct device *dev, for (i = 0; i < map_length; i++) { port_num = dt_array[NUM_SWRS_DT_PARAMS * i]; + + if (port_num >= MAX_PORT || ch_iter >= MAX_CH_PER_PORT) { + dev_err(dev, "%s: Invalid port or channel number\n", __func__); + goto err_pdata_fail; + } + slave_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 1]; ch_mask = dt_array[NUM_SWRS_DT_PARAMS * i + 2]; ch_rate = dt_array[NUM_SWRS_DT_PARAMS * i + 3];