]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Sat, 26 Oct 2024 15:33:09 +0000 (11:33 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 26 Oct 2024 15:33:09 +0000 (11:33 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.1/alsa-firewire-lib-avoid-division-by-zero-in-apply_co.patch [new file with mode: 0644]
queue-6.1/alsa-hda-realtek-update-default-depop-procedure.patch [new file with mode: 0644]
queue-6.1/asoc-dt-bindings-davinci-mcasp-fix-interrupt-propert.patch [new file with mode: 0644]
queue-6.1/asoc-dt-bindings-davinci-mcasp-fix-interrupts-proper.patch [new file with mode: 0644]
queue-6.1/cpufreq-cppc-fix-perf_to_khz-khz_to_perf-conversion-.patch [new file with mode: 0644]
queue-6.1/cpufreq-cppc-move-and-rename-cppc_cpufreq_-perf_to_k.patch [new file with mode: 0644]
queue-6.1/powercap-dtpm_devfreq-fix-error-check-against-dev_pm.patch [new file with mode: 0644]
queue-6.1/series

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 (file)
index 0000000..b99e945
--- /dev/null
@@ -0,0 +1,49 @@
+From 2ddcd0586bcd30b14f4a45aee450c468b640fc9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <shum.sdl@nppct.ru>
+
+[ 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 <shum.sdl@nppct.ru>
+Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Link: https://patch.msgid.link/20241018060018.1189537-1-shum.sdl@nppct.ru
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..4477174
--- /dev/null
@@ -0,0 +1,88 @@
+From 3d0f7d362032311c5e680ce13e64d428690967ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Oct 2024 16:13:10 +0800
+Subject: ALSA: hda/realtek: Update default depop procedure
+
+From: Kailang Yang <kailang@realtek.com>
+
+[ 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 <kailang@realtek.com>
+Link: https://lore.kernel.org/17b717a0a0b04a77aea4a8ec820cba13@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..513ac48
--- /dev/null
@@ -0,0 +1,69 @@
+From 919be69756843c96ce5ce5fd7908ba92913bf990 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <miquel.raynal@bootlin.com>
+
+[ 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 <peter.ujfalusi@gmail.com>
+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 <miquel.raynal@bootlin.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://patch.msgid.link/20241003083611.461894-1-miquel.raynal@bootlin.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../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 (file)
index 0000000..88c9b5b
--- /dev/null
@@ -0,0 +1,54 @@
+From 1fcd120b2d3cf6f06a56f7466253870d8cd57c16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 22:47:49 +0200
+Subject: ASoC: dt-bindings: davinci-mcasp: Fix interrupts property
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ 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 <miquel.raynal@bootlin.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://patch.msgid.link/20241001204749.390054-1-miquel.raynal@bootlin.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../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 (file)
index 0000000..b394f77
--- /dev/null
@@ -0,0 +1,74 @@
+From f0817caaecfd06cefeab5692953e36d1c4b1dffa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Oct 2024 10:29:52 +0800
+Subject: cpufreq: CPPC: fix perf_to_khz/khz_to_perf conversion exception
+
+From: liwei <liwei728@huawei.com>
+
+[ 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 <liwei728@huawei.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Link: https://patch.msgid.link/20241024022952.2627694-1-liwei728@huawei.com
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..dbed670
--- /dev/null
@@ -0,0 +1,429 @@
+From e9d68228ca12745a206ef661d534167bea936085 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <vincent.guittot@linaro.org>
+
+[ 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 <vincent.guittot@linaro.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Pierre Gondois <pierre.gondois@arm.com>
+Acked-by: Rafael J. Wysocki <rafael@kernel.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+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 <sashal@kernel.org>
+---
+ 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 <linux/rwsem.h>
+ #include <linux/wait.h>
+ #include <linux/topology.h>
++#include <linux/dmi.h>
++#include <linux/units.h>
++#include <asm/unaligned.h>
+ #include <acpi/cppc_acpi.h>
+@@ -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 <linux/delay.h>
+ #include <linux/cpu.h>
+ #include <linux/cpufreq.h>
+-#include <linux/dmi.h>
+ #include <linux/irq_work.h>
+ #include <linux/kthread.h>
+ #include <linux/time.h>
+@@ -27,12 +26,6 @@
+ #include <acpi/cppc_acpi.h>
+-/* 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 (file)
index 0000000..1c1f566
--- /dev/null
@@ -0,0 +1,45 @@
+From fe576425dc70109c887a46267eb2efa9062289e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <yuancan@huawei.com>
+
+[ 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 <yuancan@huawei.com>
+Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
+Link: https://patch.msgid.link/20241018021205.46460-1-yuancan@huawei.com
+[ rjw: Subject edit ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
index 038c15ba915c45f34fce5bc8fc433a01dd6a7b75..0702e70d7b3d1747db85377ae16520a93c438bf1 100644 (file)
@@ -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