From: Sasha Levin Date: Sat, 26 Oct 2024 15:33:09 +0000 (-0400) Subject: Fixes for 6.6 X-Git-Tag: v5.15.170~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0fec993bb58642b4e7d51411ec7f5910e266b062;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.6 Signed-off-by: Sasha Levin --- diff --git a/queue-6.6/alsa-firewire-lib-avoid-division-by-zero-in-apply_co.patch b/queue-6.6/alsa-firewire-lib-avoid-division-by-zero-in-apply_co.patch new file mode 100644 index 00000000000..c3faf2b5757 --- /dev/null +++ b/queue-6.6/alsa-firewire-lib-avoid-division-by-zero-in-apply_co.patch @@ -0,0 +1,49 @@ +From dcba2d1e4c667ebd00504bbcb049b12f07aef914 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Oct 2024 09:00:18 +0300 +Subject: ALSA: firewire-lib: Avoid division by zero in + apply_constraint_to_size() + +From: Andrey Shumilin + +[ Upstream commit 72cafe63b35d06b5cfbaf807e90ae657907858da ] + +The step variable is initialized to zero. It is changed in the loop, +but if it's not changed it will remain zero. Add a variable check +before the division. + +The observed behavior was introduced by commit 826b5de90c0b +("ALSA: firewire-lib: fix insufficient PCM rule for period/buffer size"), +and it is difficult to show that any of the interval parameters will +satisfy the snd_interval_test() condition with data from the +amdtp_rate_table[] table. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 826b5de90c0b ("ALSA: firewire-lib: fix insufficient PCM rule for period/buffer size") +Signed-off-by: Andrey Shumilin +Reviewed-by: Takashi Sakamoto +Link: https://patch.msgid.link/20241018060018.1189537-1-shum.sdl@nppct.ru +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/firewire/amdtp-stream.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c +index 5f0f8d9c08d1e..8c6254ff143eb 100644 +--- a/sound/firewire/amdtp-stream.c ++++ b/sound/firewire/amdtp-stream.c +@@ -172,6 +172,9 @@ static int apply_constraint_to_size(struct snd_pcm_hw_params *params, + step = max(step, amdtp_syt_intervals[i]); + } + ++ if (step == 0) ++ return -EINVAL; ++ + t.min = roundup(s->min, step); + t.max = rounddown(s->max, step); + t.integer = 1; +-- +2.43.0 + diff --git a/queue-6.6/alsa-hda-realtek-update-default-depop-procedure.patch b/queue-6.6/alsa-hda-realtek-update-default-depop-procedure.patch new file mode 100644 index 00000000000..4fcd01f3943 --- /dev/null +++ b/queue-6.6/alsa-hda-realtek-update-default-depop-procedure.patch @@ -0,0 +1,88 @@ +From 2b04cf0fcc2521f54b81867585066a4429957b3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Oct 2024 16:13:10 +0800 +Subject: ALSA: hda/realtek: Update default depop procedure + +From: Kailang Yang + +[ Upstream commit e3ea2757c312e51bbf62ebc434a6f7df1e3a201f ] + +Old procedure has a chance to meet Headphone no output. + +Fixes: c2d6af53a43f ("ALSA: hda/realtek - Add default procedure for suspend and resume state") +Signed-off-by: Kailang Yang +Link: https://lore.kernel.org/17b717a0a0b04a77aea4a8ec820cba13@realtek.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 38 ++++++++++++++++------------------- + 1 file changed, 17 insertions(+), 21 deletions(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 07e1547fff2e5..4dc5c7a18d6e7 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -3857,20 +3857,18 @@ static void alc_default_init(struct hda_codec *codec) + + hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); + +- if (hp_pin_sense) ++ if (hp_pin_sense) { + msleep(2); + +- snd_hda_codec_write(codec, hp_pin, 0, +- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); +- +- if (hp_pin_sense) +- msleep(85); ++ snd_hda_codec_write(codec, hp_pin, 0, ++ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + +- snd_hda_codec_write(codec, hp_pin, 0, +- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); ++ msleep(75); + +- if (hp_pin_sense) +- msleep(100); ++ snd_hda_codec_write(codec, hp_pin, 0, ++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); ++ msleep(75); ++ } + } + + static void alc_default_shutup(struct hda_codec *codec) +@@ -3886,22 +3884,20 @@ static void alc_default_shutup(struct hda_codec *codec) + + hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); + +- if (hp_pin_sense) ++ if (hp_pin_sense) { + msleep(2); + +- snd_hda_codec_write(codec, hp_pin, 0, +- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); +- +- if (hp_pin_sense) +- msleep(85); +- +- if (!spec->no_shutup_pins) + snd_hda_codec_write(codec, hp_pin, 0, +- AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); ++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + +- if (hp_pin_sense) +- msleep(100); ++ msleep(75); + ++ if (!spec->no_shutup_pins) ++ snd_hda_codec_write(codec, hp_pin, 0, ++ AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); ++ ++ msleep(75); ++ } + alc_auto_setup_eapd(codec, false); + alc_shutup_pins(codec); + } +-- +2.43.0 + diff --git a/queue-6.6/asoc-dt-bindings-davinci-mcasp-fix-interrupt-propert.patch b/queue-6.6/asoc-dt-bindings-davinci-mcasp-fix-interrupt-propert.patch new file mode 100644 index 00000000000..4f19de56789 --- /dev/null +++ b/queue-6.6/asoc-dt-bindings-davinci-mcasp-fix-interrupt-propert.patch @@ -0,0 +1,69 @@ +From 6fa397b8c1f2d05846e5917a3359572c689abd84 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Oct 2024 10:36:11 +0200 +Subject: ASoC: dt-bindings: davinci-mcasp: Fix interrupt properties +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Miquel Raynal + +[ Upstream commit 8380dbf1b9ef66e3ce6c1d660fd7259637c2a929 ] + +Combinations of "tx" alone, "rx" alone and "tx", "rx" together are +supposedly valid (see link below), which is not the case today as "rx" +alone is not accepted by the current binding. + +Let's rework the two interrupt properties to expose all correct +possibilities. + +Cc: Péter Ujfalusi +Link: https://lore.kernel.org/linux-sound/20241003102552.2c11840e@xps-13/T/#m277fce1d49c50d94e071f7890aed472fa2c64052 +Fixes: 8be90641a0bb ("ASoC: dt-bindings: davinci-mcasp: convert McASP bindings to yaml schema") +Signed-off-by: Miquel Raynal +Acked-by: Krzysztof Kozlowski +Link: https://patch.msgid.link/20241003083611.461894-1-miquel.raynal@bootlin.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + .../bindings/sound/davinci-mcasp-audio.yaml | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml +index ab3206ffa4af8..beef193aaaeba 100644 +--- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml ++++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml +@@ -102,21 +102,21 @@ properties: + default: 2 + + interrupts: +- oneOf: +- - minItems: 1 +- items: +- - description: TX interrupt +- - description: RX interrupt +- - items: +- - description: common/combined interrupt ++ minItems: 1 ++ maxItems: 2 + + interrupt-names: + oneOf: +- - minItems: 1 ++ - description: TX interrupt ++ const: tx ++ - description: RX interrupt ++ const: rx ++ - description: TX and RX interrupts + items: + - const: tx + - const: rx +- - const: common ++ - description: Common/combined interrupt ++ const: common + + fck_parent: + $ref: /schemas/types.yaml#/definitions/string +-- +2.43.0 + diff --git a/queue-6.6/asoc-dt-bindings-davinci-mcasp-fix-interrupts-proper.patch b/queue-6.6/asoc-dt-bindings-davinci-mcasp-fix-interrupts-proper.patch new file mode 100644 index 00000000000..07bfd905ad3 --- /dev/null +++ b/queue-6.6/asoc-dt-bindings-davinci-mcasp-fix-interrupts-proper.patch @@ -0,0 +1,54 @@ +From 4ad7f23c45db0c6671a44c451a23f3c3f301a75d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Oct 2024 22:47:49 +0200 +Subject: ASoC: dt-bindings: davinci-mcasp: Fix interrupts property + +From: Miquel Raynal + +[ Upstream commit 17d8adc4cd5181c13c1041b197b76efc09eaf8a8 ] + +My understanding of the interrupts property is that it can either be: +1/ - TX +2/ - TX + - RX +3/ - Common/combined. + +There are very little chances that either: + - TX + - Common/combined +or even + - TX + - RX + - Common/combined +could be a thing. + +Looking at the interrupt-names definition (which uses oneOf instead of +anyOf), it makes indeed little sense to use anyOf in the interrupts +definition. I believe this is just a mistake, hence let's fix it. + +Fixes: 8be90641a0bb ("ASoC: dt-bindings: davinci-mcasp: convert McASP bindings to yaml schema") +Signed-off-by: Miquel Raynal +Reviewed-by: Krzysztof Kozlowski +Link: https://patch.msgid.link/20241001204749.390054-1-miquel.raynal@bootlin.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + .../devicetree/bindings/sound/davinci-mcasp-audio.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml +index 7735e08d35ba1..ab3206ffa4af8 100644 +--- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml ++++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml +@@ -102,7 +102,7 @@ properties: + default: 2 + + interrupts: +- anyOf: ++ oneOf: + - minItems: 1 + items: + - description: TX interrupt +-- +2.43.0 + diff --git a/queue-6.6/asoc-fsl_micfil-add-a-flag-to-distinguish-with-diffe.patch b/queue-6.6/asoc-fsl_micfil-add-a-flag-to-distinguish-with-diffe.patch new file mode 100644 index 00000000000..e6836fa669d --- /dev/null +++ b/queue-6.6/asoc-fsl_micfil-add-a-flag-to-distinguish-with-diffe.patch @@ -0,0 +1,132 @@ +From 44ed66524a15e0d8e19dc69366c322ff1e7ca930 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Oct 2024 16:15:07 +0900 +Subject: ASoC: fsl_micfil: Add a flag to distinguish with different volume + control types + +From: Chancel Liu + +[ Upstream commit da95e891dd5d5de6c5ebc010bd028a2e028de093 ] + +On i.MX8MM the register of volume control has positive and negative +values. It is different from other platforms like i.MX8MP and i.MX93 +which only have positive values. Add a volume_sx flag to use SX_TLV +volume control for this kind of platform. Use common TLV volume control +for other platforms. + +Fixes: cdfa92eb90f5 ("ASoC: fsl_micfil: Correct the number of steps on SX controls") +Signed-off-by: Chancel Liu +Reviewed-by: Daniel Baluta +Link: https://patch.msgid.link/20241017071507.2577786-1-chancel.liu@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_micfil.c | 43 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 42 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c +index 0d37edb70261c..9407179af5d57 100644 +--- a/sound/soc/fsl/fsl_micfil.c ++++ b/sound/soc/fsl/fsl_micfil.c +@@ -67,6 +67,7 @@ struct fsl_micfil_soc_data { + bool imx; + bool use_edma; + bool use_verid; ++ bool volume_sx; + u64 formats; + }; + +@@ -76,6 +77,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mm = { + .fifo_depth = 8, + .dataline = 0xf, + .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .volume_sx = true, + }; + + static struct fsl_micfil_soc_data fsl_micfil_imx8mp = { +@@ -84,6 +86,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mp = { + .fifo_depth = 32, + .dataline = 0xf, + .formats = SNDRV_PCM_FMTBIT_S32_LE, ++ .volume_sx = false, + }; + + static struct fsl_micfil_soc_data fsl_micfil_imx93 = { +@@ -94,6 +97,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx93 = { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .use_edma = true, + .use_verid = true, ++ .volume_sx = false, + }; + + static const struct of_device_id fsl_micfil_dt_ids[] = { +@@ -317,7 +321,26 @@ static int hwvad_detected(struct snd_kcontrol *kcontrol, + return 0; + } + +-static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = { ++static const struct snd_kcontrol_new fsl_micfil_volume_controls[] = { ++ SOC_SINGLE_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL, ++ MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0, gain_tlv), ++ SOC_SINGLE_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL, ++ MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0, gain_tlv), ++ SOC_SINGLE_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL, ++ MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0, gain_tlv), ++ SOC_SINGLE_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL, ++ MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0, gain_tlv), ++ SOC_SINGLE_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL, ++ MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0, gain_tlv), ++ SOC_SINGLE_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL, ++ MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0, gain_tlv), ++ SOC_SINGLE_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL, ++ MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0, gain_tlv), ++ SOC_SINGLE_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL, ++ MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0, gain_tlv), ++}; ++ ++static const struct snd_kcontrol_new fsl_micfil_volume_sx_controls[] = { + SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(0), 0x8, 0xF, gain_tlv), + SOC_SINGLE_SX_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL, +@@ -334,6 +357,9 @@ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = { + MICFIL_OUTGAIN_CHX_SHIFT(6), 0x8, 0xF, gain_tlv), + SOC_SINGLE_SX_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(7), 0x8, 0xF, gain_tlv), ++}; ++ ++static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = { + SOC_ENUM_EXT("MICFIL Quality Select", + fsl_micfil_quality_enum, + micfil_quality_get, micfil_quality_set), +@@ -801,6 +827,20 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai) + return 0; + } + ++static int fsl_micfil_component_probe(struct snd_soc_component *component) ++{ ++ struct fsl_micfil *micfil = snd_soc_component_get_drvdata(component); ++ ++ if (micfil->soc->volume_sx) ++ snd_soc_add_component_controls(component, fsl_micfil_volume_sx_controls, ++ ARRAY_SIZE(fsl_micfil_volume_sx_controls)); ++ else ++ snd_soc_add_component_controls(component, fsl_micfil_volume_controls, ++ ARRAY_SIZE(fsl_micfil_volume_controls)); ++ ++ return 0; ++} ++ + static const struct snd_soc_dai_ops fsl_micfil_dai_ops = { + .probe = fsl_micfil_dai_probe, + .startup = fsl_micfil_startup, +@@ -821,6 +861,7 @@ static struct snd_soc_dai_driver fsl_micfil_dai = { + + static const struct snd_soc_component_driver fsl_micfil_component = { + .name = "fsl-micfil-dai", ++ .probe = fsl_micfil_component_probe, + .controls = fsl_micfil_snd_controls, + .num_controls = ARRAY_SIZE(fsl_micfil_snd_controls), + .legacy_dai_naming = 1, +-- +2.43.0 + diff --git a/queue-6.6/asoc-loongson-fix-component-check-failed-on-fdt-syst.patch b/queue-6.6/asoc-loongson-fix-component-check-failed-on-fdt-syst.patch new file mode 100644 index 00000000000..7905783b2e9 --- /dev/null +++ b/queue-6.6/asoc-loongson-fix-component-check-failed-on-fdt-syst.patch @@ -0,0 +1,36 @@ +From 2a509d369bb4afb1d1587fa4a676584fc69eb3cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Oct 2024 15:52:27 +0800 +Subject: ASoC: loongson: Fix component check failed on FDT systems + +From: Binbin Zhou + +[ Upstream commit a6134e7b4d4a14e0942f113a6df1d518baa2a0a4 ] + +Add missing snd_soc_dai_link.platforms assignment to avoid +soc_dai_link_sanity_check() failure. + +Fixes: d24028606e76 ("ASoC: loongson: Add Loongson ASoC Sound Card Support") +Signed-off-by: Binbin Zhou +Link: https://patch.msgid.link/6645888f2f9e8a1d8d799109f867d0f97fd78c58.1728459624.git.zhoubinbin@loongson.cn +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/loongson/loongson_card.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/loongson/loongson_card.c b/sound/soc/loongson/loongson_card.c +index 8cc54aedd0024..010e959d4c69a 100644 +--- a/sound/soc/loongson/loongson_card.c ++++ b/sound/soc/loongson/loongson_card.c +@@ -137,6 +137,7 @@ static int loongson_card_parse_of(struct loongson_card_data *data) + dev_err(dev, "getting cpu dlc error (%d)\n", ret); + goto err; + } ++ loongson_dai_links[i].platforms->of_node = loongson_dai_links[i].cpus->of_node; + + ret = snd_soc_of_get_dlc(codec, NULL, loongson_dai_links[i].codecs, 0); + if (ret < 0) { +-- +2.43.0 + diff --git a/queue-6.6/asoc-max98388-fix-missing-increment-of-variable-slot.patch b/queue-6.6/asoc-max98388-fix-missing-increment-of-variable-slot.patch new file mode 100644 index 00000000000..a6befde8741 --- /dev/null +++ b/queue-6.6/asoc-max98388-fix-missing-increment-of-variable-slot.patch @@ -0,0 +1,40 @@ +From 1338e70550e2313e6e0668b399592d098ce04f04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Oct 2024 19:20:32 +0100 +Subject: ASoC: max98388: Fix missing increment of variable slot_found + +From: Colin Ian King + +[ Upstream commit ca2803fadfd239abf155ef4a563b22a9507ee4b2 ] + +The variable slot_found is being initialized to zero and inside +a for-loop is being checked if it's reached MAX_NUM_CH, however, +this is currently impossible since slot_found is never changed. +In a previous loop a similar coding pattern is used and slot_found +is being incremented. It appears the increment of slot_found is +missing from the loop, so fix the code by adding in the increment. + +Fixes: 6a8e1d46f062 ("ASoC: max98388: add amplifier driver") +Signed-off-by: Colin Ian King +Link: https://patch.msgid.link/20241010182032.776280-1-colin.i.king@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/max98388.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/codecs/max98388.c b/sound/soc/codecs/max98388.c +index cde5e85946cb8..87386404129d9 100644 +--- a/sound/soc/codecs/max98388.c ++++ b/sound/soc/codecs/max98388.c +@@ -764,6 +764,7 @@ static int max98388_dai_tdm_slot(struct snd_soc_dai *dai, + addr = MAX98388_R2044_PCM_TX_CTRL1 + (cnt / 8); + bits = cnt % 8; + regmap_update_bits(max98388->regmap, addr, bits, bits); ++ slot_found++; + if (slot_found >= MAX_NUM_CH) + break; + } +-- +2.43.0 + diff --git a/queue-6.6/asoc-rsnd-fix-probe-failure-on-hihope-boards-due-to-.patch b/queue-6.6/asoc-rsnd-fix-probe-failure-on-hihope-boards-due-to-.patch new file mode 100644 index 00000000000..2dfdd807cd6 --- /dev/null +++ b/queue-6.6/asoc-rsnd-fix-probe-failure-on-hihope-boards-due-to-.patch @@ -0,0 +1,75 @@ +From 054648195f535e104b7813d93e9ba886e2b67ce5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Oct 2024 15:14:32 +0100 +Subject: ASoC: rsnd: Fix probe failure on HiHope boards due to endpoint + parsing + +From: Lad Prabhakar + +[ Upstream commit 9b064d200aa8fee9d1d7ced05d8a617e45966715 ] + +On the HiHope boards, we have a single port with a single endpoint defined +as below: +.... + rsnd_port: port { + rsnd_endpoint: endpoint { + remote-endpoint = <&dw_hdmi0_snd_in>; + + dai-format = "i2s"; + bitclock-master = <&rsnd_endpoint>; + frame-master = <&rsnd_endpoint>; + + playback = <&ssi2>; + }; + }; +.... + +With commit 547b02f74e4a ("ASoC: rsnd: enable multi Component support for +Audio Graph Card/Card2"), support for multiple ports was added. This caused +probe failures on HiHope boards, as the endpoint could not be retrieved due +to incorrect device node pointers being used. + +This patch fixes the issue by updating the `rsnd_dai_of_node()` and +`rsnd_dai_probe()` functions to use the correct device node pointers based +on the port names ('port' or 'ports'). It ensures that the endpoint is +properly parsed for both single and multi-port configurations, restoring +compatibility with HiHope boards. + +Fixes: 547b02f74e4a ("ASoC: rsnd: enable multi Component support for Audio Graph Card/Card2") +Signed-off-by: Lad Prabhakar +Acked-by: Kuninori Morimoto +Link: https://patch.msgid.link/20241010141432.716868-1-prabhakar.mahadev-lad.rj@bp.renesas.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sh/rcar/core.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index 1bd7114c472a8..98c7be340a536 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -1297,7 +1297,9 @@ static int rsnd_dai_of_node(struct rsnd_priv *priv, int *is_graph) + if (!of_node_name_eq(ports, "ports") && + !of_node_name_eq(ports, "port")) + continue; +- priv->component_dais[i] = of_graph_get_endpoint_count(ports); ++ priv->component_dais[i] = ++ of_graph_get_endpoint_count(of_node_name_eq(ports, "ports") ? ++ ports : np); + nr += priv->component_dais[i]; + i++; + if (i >= RSND_MAX_COMPONENT) { +@@ -1510,7 +1512,8 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) + if (!of_node_name_eq(ports, "ports") && + !of_node_name_eq(ports, "port")) + continue; +- for_each_endpoint_of_node(ports, dai_np) { ++ for_each_endpoint_of_node(of_node_name_eq(ports, "ports") ? ++ ports : np, dai_np) { + __rsnd_dai_probe(priv, dai_np, dai_np, 0, dai_i); + if (rsnd_is_gen3(priv) || rsnd_is_gen4(priv)) { + rdai = rsnd_rdai_get(priv, dai_i); +-- +2.43.0 + diff --git a/queue-6.6/cpufreq-cppc-fix-perf_to_khz-khz_to_perf-conversion-.patch b/queue-6.6/cpufreq-cppc-fix-perf_to_khz-khz_to_perf-conversion-.patch new file mode 100644 index 00000000000..9d25d9a1e87 --- /dev/null +++ b/queue-6.6/cpufreq-cppc-fix-perf_to_khz-khz_to_perf-conversion-.patch @@ -0,0 +1,74 @@ +From 00be6912c2518e3109f2e8a2928c9a42921e03df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Oct 2024 10:29:52 +0800 +Subject: cpufreq: CPPC: fix perf_to_khz/khz_to_perf conversion exception + +From: liwei + +[ Upstream commit d93df29bdab133b85e94b3c328e7fe26a0ebd56c ] + +When the nominal_freq recorded by the kernel is equal to the lowest_freq, +and the frequency adjustment operation is triggered externally, there is +a logic error in cppc_perf_to_khz()/cppc_khz_to_perf(), resulting in perf +and khz conversion errors. + +Fix this by adding a branch processing logic when nominal_freq is equal +to lowest_freq. + +Fixes: ec1c7ad47664 ("cpufreq: CPPC: Fix performance/frequency conversion") +Signed-off-by: liwei +Acked-by: Viresh Kumar +Link: https://patch.msgid.link/20241024022952.2627694-1-liwei728@huawei.com +[ rjw: Subject and changelog edits ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/cppc_acpi.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c +index 2297404fe4714..5df417626fd10 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -1912,9 +1912,15 @@ unsigned int cppc_perf_to_khz(struct cppc_perf_caps *caps, unsigned int perf) + u64 mul, div; + + if (caps->lowest_freq && caps->nominal_freq) { +- mul = caps->nominal_freq - caps->lowest_freq; ++ /* Avoid special case when nominal_freq is equal to lowest_freq */ ++ if (caps->lowest_freq == caps->nominal_freq) { ++ mul = caps->nominal_freq; ++ div = caps->nominal_perf; ++ } else { ++ mul = caps->nominal_freq - caps->lowest_freq; ++ div = caps->nominal_perf - caps->lowest_perf; ++ } + mul *= KHZ_PER_MHZ; +- div = caps->nominal_perf - caps->lowest_perf; + offset = caps->nominal_freq * KHZ_PER_MHZ - + div64_u64(caps->nominal_perf * mul, div); + } else { +@@ -1935,11 +1941,17 @@ unsigned int cppc_khz_to_perf(struct cppc_perf_caps *caps, unsigned int freq) + { + s64 retval, offset = 0; + static u64 max_khz; +- u64 mul, div; ++ u64 mul, div; + + if (caps->lowest_freq && caps->nominal_freq) { +- mul = caps->nominal_perf - caps->lowest_perf; +- div = caps->nominal_freq - caps->lowest_freq; ++ /* Avoid special case when nominal_freq is equal to lowest_freq */ ++ if (caps->lowest_freq == caps->nominal_freq) { ++ mul = caps->nominal_perf; ++ div = caps->nominal_freq; ++ } else { ++ mul = caps->nominal_perf - caps->lowest_perf; ++ div = caps->nominal_freq - caps->lowest_freq; ++ } + /* + * We don't need to convert to kHz for computing offset and can + * directly use nominal_freq and lowest_freq as the div64_u64 +-- +2.43.0 + diff --git a/queue-6.6/cpufreq-cppc-move-and-rename-cppc_cpufreq_-perf_to_k.patch b/queue-6.6/cpufreq-cppc-move-and-rename-cppc_cpufreq_-perf_to_k.patch new file mode 100644 index 00000000000..071ed86e131 --- /dev/null +++ b/queue-6.6/cpufreq-cppc-move-and-rename-cppc_cpufreq_-perf_to_k.patch @@ -0,0 +1,429 @@ +From e48dcac354cee4c5d84c7ca3618396d362bd265c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Dec 2023 11:48:53 +0100 +Subject: cpufreq/cppc: Move and rename + cppc_cpufreq_{perf_to_khz|khz_to_perf}() + +From: Vincent Guittot + +[ Upstream commit 50b813b147e9eb6546a1fc49d4e703e6d23691f2 ] + +Move and rename cppc_cpufreq_perf_to_khz() and cppc_cpufreq_khz_to_perf() to +use them outside cppc_cpufreq in topology_init_cpu_capacity_cppc(). + +Modify the interface to use struct cppc_perf_caps *caps instead of +struct cppc_cpudata *cpu_data as we only use the fields of cppc_perf_caps. + +cppc_cpufreq was converting the lowest and nominal freq from MHz to kHz +before using them. We move this conversion inside cppc_perf_to_khz and +cppc_khz_to_perf to make them generic and usable outside cppc_cpufreq. + +No functional change + +Signed-off-by: Vincent Guittot +Signed-off-by: Ingo Molnar +Tested-by: Pierre Gondois +Acked-by: Rafael J. Wysocki +Acked-by: Viresh Kumar +Link: https://lore.kernel.org/r/20231211104855.558096-6-vincent.guittot@linaro.org +Stable-dep-of: d93df29bdab1 ("cpufreq: CPPC: fix perf_to_khz/khz_to_perf conversion exception") +Signed-off-by: Sasha Levin +--- + drivers/acpi/cppc_acpi.c | 104 ++++++++++++++++++++++++ + drivers/cpufreq/cppc_cpufreq.c | 139 ++++----------------------------- + include/acpi/cppc_acpi.h | 2 + + 3 files changed, 123 insertions(+), 122 deletions(-) + +diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c +index 7aced0b9bad7c..2297404fe4714 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -39,6 +39,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #include + +@@ -1858,3 +1861,104 @@ unsigned int cppc_get_transition_latency(int cpu_num) + return latency_ns; + } + EXPORT_SYMBOL_GPL(cppc_get_transition_latency); ++ ++/* Minimum struct length needed for the DMI processor entry we want */ ++#define DMI_ENTRY_PROCESSOR_MIN_LENGTH 48 ++ ++/* Offset in the DMI processor structure for the max frequency */ ++#define DMI_PROCESSOR_MAX_SPEED 0x14 ++ ++/* Callback function used to retrieve the max frequency from DMI */ ++static void cppc_find_dmi_mhz(const struct dmi_header *dm, void *private) ++{ ++ const u8 *dmi_data = (const u8 *)dm; ++ u16 *mhz = (u16 *)private; ++ ++ if (dm->type == DMI_ENTRY_PROCESSOR && ++ dm->length >= DMI_ENTRY_PROCESSOR_MIN_LENGTH) { ++ u16 val = (u16)get_unaligned((const u16 *) ++ (dmi_data + DMI_PROCESSOR_MAX_SPEED)); ++ *mhz = val > *mhz ? val : *mhz; ++ } ++} ++ ++/* Look up the max frequency in DMI */ ++static u64 cppc_get_dmi_max_khz(void) ++{ ++ u16 mhz = 0; ++ ++ dmi_walk(cppc_find_dmi_mhz, &mhz); ++ ++ /* ++ * Real stupid fallback value, just in case there is no ++ * actual value set. ++ */ ++ mhz = mhz ? mhz : 1; ++ ++ return KHZ_PER_MHZ * mhz; ++} ++ ++/* ++ * If CPPC lowest_freq and nominal_freq registers are exposed then we can ++ * use them to convert perf to freq and vice versa. The conversion is ++ * extrapolated as an affine function passing by the 2 points: ++ * - (Low perf, Low freq) ++ * - (Nominal perf, Nominal freq) ++ */ ++unsigned int cppc_perf_to_khz(struct cppc_perf_caps *caps, unsigned int perf) ++{ ++ s64 retval, offset = 0; ++ static u64 max_khz; ++ u64 mul, div; ++ ++ if (caps->lowest_freq && caps->nominal_freq) { ++ mul = caps->nominal_freq - caps->lowest_freq; ++ mul *= KHZ_PER_MHZ; ++ div = caps->nominal_perf - caps->lowest_perf; ++ offset = caps->nominal_freq * KHZ_PER_MHZ - ++ div64_u64(caps->nominal_perf * mul, div); ++ } else { ++ if (!max_khz) ++ max_khz = cppc_get_dmi_max_khz(); ++ mul = max_khz; ++ div = caps->highest_perf; ++ } ++ ++ retval = offset + div64_u64(perf * mul, div); ++ if (retval >= 0) ++ return retval; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cppc_perf_to_khz); ++ ++unsigned int cppc_khz_to_perf(struct cppc_perf_caps *caps, unsigned int freq) ++{ ++ s64 retval, offset = 0; ++ static u64 max_khz; ++ u64 mul, div; ++ ++ if (caps->lowest_freq && caps->nominal_freq) { ++ mul = caps->nominal_perf - caps->lowest_perf; ++ div = caps->nominal_freq - caps->lowest_freq; ++ /* ++ * We don't need to convert to kHz for computing offset and can ++ * directly use nominal_freq and lowest_freq as the div64_u64 ++ * will remove the frequency unit. ++ */ ++ offset = caps->nominal_perf - ++ div64_u64(caps->nominal_freq * mul, div); ++ /* But we need it for computing the perf level. */ ++ div *= KHZ_PER_MHZ; ++ } else { ++ if (!max_khz) ++ max_khz = cppc_get_dmi_max_khz(); ++ mul = caps->highest_perf; ++ div = max_khz; ++ } ++ ++ retval = offset + div64_u64(freq * mul, div); ++ if (retval >= 0) ++ return retval; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cppc_khz_to_perf); +diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c +index 1ba3943be8a3d..15f1d41920a33 100644 +--- a/drivers/cpufreq/cppc_cpufreq.c ++++ b/drivers/cpufreq/cppc_cpufreq.c +@@ -16,7 +16,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -27,12 +26,6 @@ + + #include + +-/* Minimum struct length needed for the DMI processor entry we want */ +-#define DMI_ENTRY_PROCESSOR_MIN_LENGTH 48 +- +-/* Offset in the DMI processor structure for the max frequency */ +-#define DMI_PROCESSOR_MAX_SPEED 0x14 +- + /* + * This list contains information parsed from per CPU ACPI _CPC and _PSD + * structures: e.g. the highest and lowest supported performance, capabilities, +@@ -291,97 +284,9 @@ static inline void cppc_freq_invariance_exit(void) + } + #endif /* CONFIG_ACPI_CPPC_CPUFREQ_FIE */ + +-/* Callback function used to retrieve the max frequency from DMI */ +-static void cppc_find_dmi_mhz(const struct dmi_header *dm, void *private) +-{ +- const u8 *dmi_data = (const u8 *)dm; +- u16 *mhz = (u16 *)private; +- +- if (dm->type == DMI_ENTRY_PROCESSOR && +- dm->length >= DMI_ENTRY_PROCESSOR_MIN_LENGTH) { +- u16 val = (u16)get_unaligned((const u16 *) +- (dmi_data + DMI_PROCESSOR_MAX_SPEED)); +- *mhz = val > *mhz ? val : *mhz; +- } +-} +- +-/* Look up the max frequency in DMI */ +-static u64 cppc_get_dmi_max_khz(void) +-{ +- u16 mhz = 0; +- +- dmi_walk(cppc_find_dmi_mhz, &mhz); +- +- /* +- * Real stupid fallback value, just in case there is no +- * actual value set. +- */ +- mhz = mhz ? mhz : 1; +- +- return (1000 * mhz); +-} +- +-/* +- * If CPPC lowest_freq and nominal_freq registers are exposed then we can +- * use them to convert perf to freq and vice versa. The conversion is +- * extrapolated as an affine function passing by the 2 points: +- * - (Low perf, Low freq) +- * - (Nominal perf, Nominal perf) +- */ +-static unsigned int cppc_cpufreq_perf_to_khz(struct cppc_cpudata *cpu_data, +- unsigned int perf) +-{ +- struct cppc_perf_caps *caps = &cpu_data->perf_caps; +- s64 retval, offset = 0; +- static u64 max_khz; +- u64 mul, div; +- +- if (caps->lowest_freq && caps->nominal_freq) { +- mul = caps->nominal_freq - caps->lowest_freq; +- div = caps->nominal_perf - caps->lowest_perf; +- offset = caps->nominal_freq - div64_u64(caps->nominal_perf * mul, div); +- } else { +- if (!max_khz) +- max_khz = cppc_get_dmi_max_khz(); +- mul = max_khz; +- div = caps->highest_perf; +- } +- +- retval = offset + div64_u64(perf * mul, div); +- if (retval >= 0) +- return retval; +- return 0; +-} +- +-static unsigned int cppc_cpufreq_khz_to_perf(struct cppc_cpudata *cpu_data, +- unsigned int freq) +-{ +- struct cppc_perf_caps *caps = &cpu_data->perf_caps; +- s64 retval, offset = 0; +- static u64 max_khz; +- u64 mul, div; +- +- if (caps->lowest_freq && caps->nominal_freq) { +- mul = caps->nominal_perf - caps->lowest_perf; +- div = caps->nominal_freq - caps->lowest_freq; +- offset = caps->nominal_perf - div64_u64(caps->nominal_freq * mul, div); +- } else { +- if (!max_khz) +- max_khz = cppc_get_dmi_max_khz(); +- mul = caps->highest_perf; +- div = max_khz; +- } +- +- retval = offset + div64_u64(freq * mul, div); +- if (retval >= 0) +- return retval; +- return 0; +-} +- + static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +- + { + struct cppc_cpudata *cpu_data = policy->driver_data; + unsigned int cpu = policy->cpu; +@@ -389,7 +294,7 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, + u32 desired_perf; + int ret = 0; + +- desired_perf = cppc_cpufreq_khz_to_perf(cpu_data, target_freq); ++ desired_perf = cppc_khz_to_perf(&cpu_data->perf_caps, target_freq); + /* Return if it is exactly the same perf */ + if (desired_perf == cpu_data->perf_ctrls.desired_perf) + return ret; +@@ -417,7 +322,7 @@ static unsigned int cppc_cpufreq_fast_switch(struct cpufreq_policy *policy, + u32 desired_perf; + int ret; + +- desired_perf = cppc_cpufreq_khz_to_perf(cpu_data, target_freq); ++ desired_perf = cppc_khz_to_perf(&cpu_data->perf_caps, target_freq); + cpu_data->perf_ctrls.desired_perf = desired_perf; + ret = cppc_set_perf(cpu, &cpu_data->perf_ctrls); + +@@ -530,7 +435,7 @@ static int cppc_get_cpu_power(struct device *cpu_dev, + min_step = min_cap / CPPC_EM_CAP_STEP; + max_step = max_cap / CPPC_EM_CAP_STEP; + +- perf_prev = cppc_cpufreq_khz_to_perf(cpu_data, *KHz); ++ perf_prev = cppc_khz_to_perf(perf_caps, *KHz); + step = perf_prev / perf_step; + + if (step > max_step) +@@ -550,8 +455,8 @@ static int cppc_get_cpu_power(struct device *cpu_dev, + perf = step * perf_step; + } + +- *KHz = cppc_cpufreq_perf_to_khz(cpu_data, perf); +- perf_check = cppc_cpufreq_khz_to_perf(cpu_data, *KHz); ++ *KHz = cppc_perf_to_khz(perf_caps, perf); ++ perf_check = cppc_khz_to_perf(perf_caps, *KHz); + step_check = perf_check / perf_step; + + /* +@@ -561,8 +466,8 @@ static int cppc_get_cpu_power(struct device *cpu_dev, + */ + while ((*KHz == prev_freq) || (step_check != step)) { + perf++; +- *KHz = cppc_cpufreq_perf_to_khz(cpu_data, perf); +- perf_check = cppc_cpufreq_khz_to_perf(cpu_data, *KHz); ++ *KHz = cppc_perf_to_khz(perf_caps, perf); ++ perf_check = cppc_khz_to_perf(perf_caps, *KHz); + step_check = perf_check / perf_step; + } + +@@ -591,7 +496,7 @@ static int cppc_get_cpu_cost(struct device *cpu_dev, unsigned long KHz, + perf_caps = &cpu_data->perf_caps; + max_cap = arch_scale_cpu_capacity(cpu_dev->id); + +- perf_prev = cppc_cpufreq_khz_to_perf(cpu_data, KHz); ++ perf_prev = cppc_khz_to_perf(perf_caps, KHz); + perf_step = CPPC_EM_CAP_STEP * perf_caps->highest_perf / max_cap; + step = perf_prev / perf_step; + +@@ -679,10 +584,6 @@ static struct cppc_cpudata *cppc_cpufreq_get_cpu_data(unsigned int cpu) + goto free_mask; + } + +- /* Convert the lowest and nominal freq from MHz to KHz */ +- cpu_data->perf_caps.lowest_freq *= 1000; +- cpu_data->perf_caps.nominal_freq *= 1000; +- + list_add(&cpu_data->node, &cpu_data_list); + + return cpu_data; +@@ -724,20 +625,16 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) + * Set min to lowest nonlinear perf to avoid any efficiency penalty (see + * Section 8.4.7.1.1.5 of ACPI 6.1 spec) + */ +- policy->min = cppc_cpufreq_perf_to_khz(cpu_data, +- caps->lowest_nonlinear_perf); +- policy->max = cppc_cpufreq_perf_to_khz(cpu_data, +- caps->nominal_perf); ++ policy->min = cppc_perf_to_khz(caps, caps->lowest_nonlinear_perf); ++ policy->max = cppc_perf_to_khz(caps, caps->nominal_perf); + + /* + * Set cpuinfo.min_freq to Lowest to make the full range of performance + * available if userspace wants to use any perf between lowest & lowest + * nonlinear perf + */ +- policy->cpuinfo.min_freq = cppc_cpufreq_perf_to_khz(cpu_data, +- caps->lowest_perf); +- policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu_data, +- caps->nominal_perf); ++ policy->cpuinfo.min_freq = cppc_perf_to_khz(caps, caps->lowest_perf); ++ policy->cpuinfo.max_freq = cppc_perf_to_khz(caps, caps->nominal_perf); + + policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu); + policy->shared_type = cpu_data->shared_type; +@@ -773,7 +670,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) + boost_supported = true; + + /* Set policy->cur to max now. The governors will adjust later. */ +- policy->cur = cppc_cpufreq_perf_to_khz(cpu_data, caps->highest_perf); ++ policy->cur = cppc_perf_to_khz(caps, caps->highest_perf); + cpu_data->perf_ctrls.desired_perf = caps->highest_perf; + + ret = cppc_set_perf(cpu, &cpu_data->perf_ctrls); +@@ -868,7 +765,7 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) + delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0, + &fb_ctrs_t1); + +- return cppc_cpufreq_perf_to_khz(cpu_data, delivered_perf); ++ return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf); + } + + static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state) +@@ -883,11 +780,9 @@ static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state) + } + + if (state) +- policy->max = cppc_cpufreq_perf_to_khz(cpu_data, +- caps->highest_perf); ++ policy->max = cppc_perf_to_khz(caps, caps->highest_perf); + else +- policy->max = cppc_cpufreq_perf_to_khz(cpu_data, +- caps->nominal_perf); ++ policy->max = cppc_perf_to_khz(caps, caps->nominal_perf); + policy->cpuinfo.max_freq = policy->max; + + ret = freq_qos_update_request(policy->max_freq_req, policy->max); +@@ -947,7 +842,7 @@ static unsigned int hisi_cppc_cpufreq_get_rate(unsigned int cpu) + if (ret < 0) + return -EIO; + +- return cppc_cpufreq_perf_to_khz(cpu_data, desired_perf); ++ return cppc_perf_to_khz(&cpu_data->perf_caps, desired_perf); + } + + static void cppc_check_hisi_workaround(void) +diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h +index ec425d2834f86..e1720d9306669 100644 +--- a/include/acpi/cppc_acpi.h ++++ b/include/acpi/cppc_acpi.h +@@ -147,6 +147,8 @@ extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); + extern int cppc_set_enable(int cpu, bool enable); + extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps); + extern bool cppc_perf_ctrs_in_pcc(void); ++extern unsigned int cppc_perf_to_khz(struct cppc_perf_caps *caps, unsigned int perf); ++extern unsigned int cppc_khz_to_perf(struct cppc_perf_caps *caps, unsigned int freq); + extern bool acpi_cpc_valid(void); + extern bool cppc_allow_fast_switch(void); + extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data); +-- +2.43.0 + diff --git a/queue-6.6/nfsd-cancel-nfsd_shrinker_work-using-sync-mode-in-nf.patch b/queue-6.6/nfsd-cancel-nfsd_shrinker_work-using-sync-mode-in-nf.patch new file mode 100644 index 00000000000..1644681fb78 --- /dev/null +++ b/queue-6.6/nfsd-cancel-nfsd_shrinker_work-using-sync-mode-in-nf.patch @@ -0,0 +1,103 @@ +From 3761b78767a679093a0aa9d17580aa9e46793708 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Oct 2024 16:25:40 +0800 +Subject: nfsd: cancel nfsd_shrinker_work using sync mode in + nfs4_state_shutdown_net + +From: Yang Erkun + +[ Upstream commit d5ff2fb2e7167e9483846e34148e60c0c016a1f6 ] + +In the normal case, when we excute `echo 0 > /proc/fs/nfsd/threads`, the +function `nfs4_state_destroy_net` in `nfs4_state_shutdown_net` will +release all resources related to the hashed `nfs4_client`. If the +`nfsd_client_shrinker` is running concurrently, the `expire_client` +function will first unhash this client and then destroy it. This can +lead to the following warning. Additionally, numerous use-after-free +errors may occur as well. + +nfsd_client_shrinker echo 0 > /proc/fs/nfsd/threads + +expire_client nfsd_shutdown_net + unhash_client ... + nfs4_state_shutdown_net + /* won't wait shrinker exit */ + /* cancel_work(&nn->nfsd_shrinker_work) + * nfsd_file for this /* won't destroy unhashed client1 */ + * client1 still alive nfs4_state_destroy_net + */ + + nfsd_file_cache_shutdown + /* trigger warning */ + kmem_cache_destroy(nfsd_file_slab) + kmem_cache_destroy(nfsd_file_mark_slab) + /* release nfsd_file and mark */ + __destroy_client + +==================================================================== +BUG nfsd_file (Not tainted): Objects remaining in nfsd_file on +__kmem_cache_shutdown() +-------------------------------------------------------------------- +CPU: 4 UID: 0 PID: 764 Comm: sh Not tainted 6.12.0-rc3+ #1 + + dump_stack_lvl+0x53/0x70 + slab_err+0xb0/0xf0 + __kmem_cache_shutdown+0x15c/0x310 + kmem_cache_destroy+0x66/0x160 + nfsd_file_cache_shutdown+0xac/0x210 [nfsd] + nfsd_destroy_serv+0x251/0x2a0 [nfsd] + nfsd_svc+0x125/0x1e0 [nfsd] + write_threads+0x16a/0x2a0 [nfsd] + nfsctl_transaction_write+0x74/0xa0 [nfsd] + vfs_write+0x1a5/0x6d0 + ksys_write+0xc1/0x160 + do_syscall_64+0x5f/0x170 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +==================================================================== +BUG nfsd_file_mark (Tainted: G B W ): Objects remaining +nfsd_file_mark on __kmem_cache_shutdown() +-------------------------------------------------------------------- + + dump_stack_lvl+0x53/0x70 + slab_err+0xb0/0xf0 + __kmem_cache_shutdown+0x15c/0x310 + kmem_cache_destroy+0x66/0x160 + nfsd_file_cache_shutdown+0xc8/0x210 [nfsd] + nfsd_destroy_serv+0x251/0x2a0 [nfsd] + nfsd_svc+0x125/0x1e0 [nfsd] + write_threads+0x16a/0x2a0 [nfsd] + nfsctl_transaction_write+0x74/0xa0 [nfsd] + vfs_write+0x1a5/0x6d0 + ksys_write+0xc1/0x160 + do_syscall_64+0x5f/0x170 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +To resolve this issue, cancel `nfsd_shrinker_work` using synchronous +mode in nfs4_state_shutdown_net. + +Fixes: 7c24fa225081 ("NFSD: replace delayed_work with work_struct for nfsd_client_shrinker") +Signed-off-by: Yang Erkun +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfs4state.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index f16bbbfcf672c..975dd74a7a4db 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -8254,7 +8254,7 @@ nfs4_state_shutdown_net(struct net *net) + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + + unregister_shrinker(&nn->nfsd_client_shrinker); +- cancel_work(&nn->nfsd_shrinker_work); ++ cancel_work_sync(&nn->nfsd_shrinker_work); + cancel_delayed_work_sync(&nn->laundromat_work); + locks_end_grace(&nn->nfsd4_manager); + +-- +2.43.0 + diff --git a/queue-6.6/powercap-dtpm_devfreq-fix-error-check-against-dev_pm.patch b/queue-6.6/powercap-dtpm_devfreq-fix-error-check-against-dev_pm.patch new file mode 100644 index 00000000000..32df7acbfaf --- /dev/null +++ b/queue-6.6/powercap-dtpm_devfreq-fix-error-check-against-dev_pm.patch @@ -0,0 +1,45 @@ +From ceaac7662473a7ea8dba9314a3bf76403c825867 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Oct 2024 10:12:05 +0800 +Subject: powercap: dtpm_devfreq: Fix error check against + dev_pm_qos_add_request() + +From: Yuan Can + +[ Upstream commit 5209d1b654f1db80509040cc694c7814a1b547e3 ] + +The caller of the function dev_pm_qos_add_request() checks again a non +zero value but dev_pm_qos_add_request() can return '1' if the request +already exists. Therefore, the setup function fails while the QoS +request actually did not failed. + +Fix that by changing the check against a negative value like all the +other callers of the function. + +Fixes: e44655617317 ("powercap/drivers/dtpm: Add dtpm devfreq with energy model support") +Signed-off-by: Yuan Can +Reviewed-by: Lukasz Luba +Link: https://patch.msgid.link/20241018021205.46460-1-yuancan@huawei.com +[ rjw: Subject edit ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/dtpm_devfreq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/powercap/dtpm_devfreq.c b/drivers/powercap/dtpm_devfreq.c +index 612c3b59dd5be..0ca53db7a90eb 100644 +--- a/drivers/powercap/dtpm_devfreq.c ++++ b/drivers/powercap/dtpm_devfreq.c +@@ -166,7 +166,7 @@ static int __dtpm_devfreq_setup(struct devfreq *devfreq, struct dtpm *parent) + ret = dev_pm_qos_add_request(dev, &dtpm_devfreq->qos_req, + DEV_PM_QOS_MAX_FREQUENCY, + PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE); +- if (ret) { ++ if (ret < 0) { + pr_err("Failed to add QoS request: %d\n", ret); + goto out_dtpm_unregister; + } +-- +2.43.0 + diff --git a/queue-6.6/series b/queue-6.6/series index aaffe41c896..ffe134c010d 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -161,3 +161,16 @@ bpf-perf-fix-perf_event_detach_bpf_prog-error-handli.patch net-dsa-mv88e6xxx-group-cycle-counter-coefficients.patch net-dsa-mv88e6xxx-read-cycle-counter-period-from-har.patch net-dsa-mv88e6xxx-support-4000ps-cycle-counter-perio.patch +asoc-dt-bindings-davinci-mcasp-fix-interrupts-proper.patch +asoc-dt-bindings-davinci-mcasp-fix-interrupt-propert.patch +asoc-loongson-fix-component-check-failed-on-fdt-syst.patch +asoc-max98388-fix-missing-increment-of-variable-slot.patch +asoc-rsnd-fix-probe-failure-on-hihope-boards-due-to-.patch +asoc-fsl_micfil-add-a-flag-to-distinguish-with-diffe.patch +alsa-firewire-lib-avoid-division-by-zero-in-apply_co.patch +powercap-dtpm_devfreq-fix-error-check-against-dev_pm.patch +nfsd-cancel-nfsd_shrinker_work-using-sync-mode-in-nf.patch +alsa-hda-realtek-update-default-depop-procedure.patch +smb-client-handle-kstrdup-failures-for-passwords.patch +cpufreq-cppc-move-and-rename-cppc_cpufreq_-perf_to_k.patch +cpufreq-cppc-fix-perf_to_khz-khz_to_perf-conversion-.patch diff --git a/queue-6.6/smb-client-handle-kstrdup-failures-for-passwords.patch b/queue-6.6/smb-client-handle-kstrdup-failures-for-passwords.patch new file mode 100644 index 00000000000..c9ea1ae1fca --- /dev/null +++ b/queue-6.6/smb-client-handle-kstrdup-failures-for-passwords.patch @@ -0,0 +1,50 @@ +From 835c4de5592711d15399e2117afdbf0eef1ba906 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Oct 2024 15:21:26 -0300 +Subject: smb: client: Handle kstrdup failures for passwords + +From: Henrique Carvalho + +[ Upstream commit 9a5dd61151399ad5a5d69aad28ab164734c1e3bc ] + +In smb3_reconfigure(), after duplicating ctx->password and +ctx->password2 with kstrdup(), we need to check for allocation +failures. + +If ses->password allocation fails, return -ENOMEM. +If ses->password2 allocation fails, free ses->password, set it +to NULL, and return -ENOMEM. + +Fixes: c1eb537bf456 ("cifs: allow changing password during remount") +Reviewed-by: David Howells +Signed-off-by: Henrique Carvalho +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/fs_context.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c +index 3bbac925d0766..8d7484400fe8e 100644 +--- a/fs/smb/client/fs_context.c ++++ b/fs/smb/client/fs_context.c +@@ -918,8 +918,15 @@ static int smb3_reconfigure(struct fs_context *fc) + else { + kfree_sensitive(ses->password); + ses->password = kstrdup(ctx->password, GFP_KERNEL); ++ if (!ses->password) ++ return -ENOMEM; + kfree_sensitive(ses->password2); + ses->password2 = kstrdup(ctx->password2, GFP_KERNEL); ++ if (!ses->password2) { ++ kfree_sensitive(ses->password); ++ ses->password = NULL; ++ return -ENOMEM; ++ } + } + STEAL_STRING(cifs_sb, ctx, domainname); + STEAL_STRING(cifs_sb, ctx, nodename); +-- +2.43.0 +