From b688fb30fc20ecb1662ec4abcf0c2f8a5ee13c7d Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 26 Oct 2024 11:33:09 -0400 Subject: [PATCH] Fixes for 6.1 Signed-off-by: Sasha Levin --- ...b-avoid-division-by-zero-in-apply_co.patch | 49 ++ ...altek-update-default-depop-procedure.patch | 88 ++++ ...-davinci-mcasp-fix-interrupt-propert.patch | 69 +++ ...-davinci-mcasp-fix-interrupts-proper.patch | 54 +++ ...-perf_to_khz-khz_to_perf-conversion-.patch | 74 +++ ...e-and-rename-cppc_cpufreq_-perf_to_k.patch | 429 ++++++++++++++++++ ...vfreq-fix-error-check-against-dev_pm.patch | 45 ++ queue-6.1/series | 7 + 8 files changed, 815 insertions(+) create mode 100644 queue-6.1/alsa-firewire-lib-avoid-division-by-zero-in-apply_co.patch create mode 100644 queue-6.1/alsa-hda-realtek-update-default-depop-procedure.patch create mode 100644 queue-6.1/asoc-dt-bindings-davinci-mcasp-fix-interrupt-propert.patch create mode 100644 queue-6.1/asoc-dt-bindings-davinci-mcasp-fix-interrupts-proper.patch create mode 100644 queue-6.1/cpufreq-cppc-fix-perf_to_khz-khz_to_perf-conversion-.patch create mode 100644 queue-6.1/cpufreq-cppc-move-and-rename-cppc_cpufreq_-perf_to_k.patch create mode 100644 queue-6.1/powercap-dtpm_devfreq-fix-error-check-against-dev_pm.patch diff --git a/queue-6.1/alsa-firewire-lib-avoid-division-by-zero-in-apply_co.patch b/queue-6.1/alsa-firewire-lib-avoid-division-by-zero-in-apply_co.patch new file mode 100644 index 00000000000..b99e945b1ce --- /dev/null +++ b/queue-6.1/alsa-firewire-lib-avoid-division-by-zero-in-apply_co.patch @@ -0,0 +1,49 @@ +From 2ddcd0586bcd30b14f4a45aee450c468b640fc9f 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 842fe127c5378..b5b3b4d177aaf 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.1/alsa-hda-realtek-update-default-depop-procedure.patch b/queue-6.1/alsa-hda-realtek-update-default-depop-procedure.patch new file mode 100644 index 00000000000..44771746b77 --- /dev/null +++ b/queue-6.1/alsa-hda-realtek-update-default-depop-procedure.patch @@ -0,0 +1,88 @@ +From 3d0f7d362032311c5e680ce13e64d428690967ce 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 8c8a3f6499c22..e8c4c4c3474da 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -3854,20 +3854,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) +@@ -3883,22 +3881,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.1/asoc-dt-bindings-davinci-mcasp-fix-interrupt-propert.patch b/queue-6.1/asoc-dt-bindings-davinci-mcasp-fix-interrupt-propert.patch new file mode 100644 index 00000000000..513ac48be10 --- /dev/null +++ b/queue-6.1/asoc-dt-bindings-davinci-mcasp-fix-interrupt-propert.patch @@ -0,0 +1,69 @@ +From 919be69756843c96ce5ce5fd7908ba92913bf990 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 b181f7481a951..fe02773a490a9 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.1/asoc-dt-bindings-davinci-mcasp-fix-interrupts-proper.patch b/queue-6.1/asoc-dt-bindings-davinci-mcasp-fix-interrupts-proper.patch new file mode 100644 index 00000000000..88c9b5be999 --- /dev/null +++ b/queue-6.1/asoc-dt-bindings-davinci-mcasp-fix-interrupts-proper.patch @@ -0,0 +1,54 @@ +From 1fcd120b2d3cf6f06a56f7466253870d8cd57c16 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 f46c66bc6b2d8..b181f7481a951 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.1/cpufreq-cppc-fix-perf_to_khz-khz_to_perf-conversion-.patch b/queue-6.1/cpufreq-cppc-fix-perf_to_khz-khz_to_perf-conversion-.patch new file mode 100644 index 00000000000..b394f77f86f --- /dev/null +++ b/queue-6.1/cpufreq-cppc-fix-perf_to_khz-khz_to_perf-conversion-.patch @@ -0,0 +1,74 @@ +From f0817caaecfd06cefeab5692953e36d1c4b1dffa 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 8d4b72488eb5e..3d9326172af49 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -1718,9 +1718,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 { +@@ -1741,11 +1747,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.1/cpufreq-cppc-move-and-rename-cppc_cpufreq_-perf_to_k.patch b/queue-6.1/cpufreq-cppc-move-and-rename-cppc_cpufreq_-perf_to_k.patch new file mode 100644 index 00000000000..dbed670ec60 --- /dev/null +++ b/queue-6.1/cpufreq-cppc-move-and-rename-cppc_cpufreq_-perf_to_k.patch @@ -0,0 +1,429 @@ +From e9d68228ca12745a206ef661d534167bea936085 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 12296d85a7196..8d4b72488eb5e 100644 +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -39,6 +39,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #include + +@@ -1664,3 +1667,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 8791a88c7741c..0050242d382e7 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, +@@ -288,97 +281,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; +@@ -386,7 +291,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; +@@ -414,7 +319,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); + +@@ -527,7 +432,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) +@@ -547,8 +452,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; + + /* +@@ -558,8 +463,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; + } + +@@ -588,7 +493,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; + +@@ -676,10 +581,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; +@@ -721,20 +622,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; +@@ -770,7 +667,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); +@@ -865,7 +762,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) +@@ -880,11 +777,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); +@@ -944,7 +839,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 b097bd57b2e47..2d1ec0e6ee018 100644 +--- a/include/acpi/cppc_acpi.h ++++ b/include/acpi/cppc_acpi.h +@@ -143,6 +143,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.1/powercap-dtpm_devfreq-fix-error-check-against-dev_pm.patch b/queue-6.1/powercap-dtpm_devfreq-fix-error-check-against-dev_pm.patch new file mode 100644 index 00000000000..1c1f56626f2 --- /dev/null +++ b/queue-6.1/powercap-dtpm_devfreq-fix-error-check-against-dev_pm.patch @@ -0,0 +1,45 @@ +From fe576425dc70109c887a46267eb2efa9062289e2 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.1/series b/queue-6.1/series index 038c15ba915..0702e70d7b3 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -105,3 +105,10 @@ posix-clock-posix-clock-fix-unbalanced-locking-in-pc.patch bluetooth-sco-fix-uaf-on-sco_sock_timeout.patch bluetooth-iso-fix-uaf-on-iso_sock_timeout.patch bpf-perf-fix-perf_event_detach_bpf_prog-error-handli.patch +asoc-dt-bindings-davinci-mcasp-fix-interrupts-proper.patch +asoc-dt-bindings-davinci-mcasp-fix-interrupt-propert.patch +alsa-firewire-lib-avoid-division-by-zero-in-apply_co.patch +powercap-dtpm_devfreq-fix-error-check-against-dev_pm.patch +alsa-hda-realtek-update-default-depop-procedure.patch +cpufreq-cppc-move-and-rename-cppc_cpufreq_-perf_to_k.patch +cpufreq-cppc-fix-perf_to_khz-khz_to_perf-conversion-.patch -- 2.47.2