]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.6
authorSasha Levin <sashal@kernel.org>
Mon, 22 Apr 2024 22:34:54 +0000 (18:34 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 22 Apr 2024 22:34:54 +0000 (18:34 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
29 files changed:
queue-6.6/alsa-scarlett2-add-correct-product-series-name-to-me.patch [new file with mode: 0644]
queue-6.6/alsa-scarlett2-add-focusrite-clarett-2pre-and-4pre-s.patch [new file with mode: 0644]
queue-6.6/alsa-scarlett2-add-focusrite-clarett-2pre-and-4pre-u.patch [new file with mode: 0644]
queue-6.6/alsa-scarlett2-add-support-for-clarett-8pre-usb.patch [new file with mode: 0644]
queue-6.6/alsa-scarlett2-default-mixer-driver-to-enabled.patch [new file with mode: 0644]
queue-6.6/alsa-scarlett2-move-usb-ids-out-from-device_info-str.patch [new file with mode: 0644]
queue-6.6/alsa-scarlett2-rename-scarlett_gen2-to-scarlett2.patch [new file with mode: 0644]
queue-6.6/asoc-ti-convert-pandora-asoc-to-gpio-descriptors.patch [new file with mode: 0644]
queue-6.6/clk-get-runtime-pm-before-walking-tree-during-disabl.patch [new file with mode: 0644]
queue-6.6/clk-get-runtime-pm-before-walking-tree-for-clk_summa.patch [new file with mode: 0644]
queue-6.6/clk-initialize-struct-clk_core-kref-earlier.patch [new file with mode: 0644]
queue-6.6/clk-mediatek-do-a-runtime-pm-get-on-controllers-duri.patch [new file with mode: 0644]
queue-6.6/clk-remove-prepare_lock-hold-assertion-in-__clk_rele.patch [new file with mode: 0644]
queue-6.6/clk-show-active-consumers-of-clocks-in-debugfs.patch [new file with mode: 0644]
queue-6.6/drm-panel-orientation-quirks-add-quirk-for-lenovo-le.patch [new file with mode: 0644]
queue-6.6/interconnect-don-t-access-req_list-while-it-s-being-.patch [new file with mode: 0644]
queue-6.6/pci-add-pci_header_type_mfd-definition.patch [new file with mode: 0644]
queue-6.6/pci-dpc-use-field_get.patch [new file with mode: 0644]
queue-6.6/pci-simplify-pcie_capability_clear_and_set_word-to-..patch [new file with mode: 0644]
queue-6.6/pci-use-pci_header_type_-instead-of-literals.patch [new file with mode: 0644]
queue-6.6/platform-x86-amd-pmc-extend-framework-13-quirk-to-mo.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/usb-new-quirk-to-reduce-the-set_address-request-time.patch [new file with mode: 0644]
queue-6.6/usb-pci-quirks-group-amd-specific-quirk-code-togethe.patch [new file with mode: 0644]
queue-6.6/usb-pci-quirks-handle-has_ioport-dependency-for-amd-.patch [new file with mode: 0644]
queue-6.6/usb-pci-quirks-handle-has_ioport-dependency-for-uhci.patch [new file with mode: 0644]
queue-6.6/usb-xhci-add-timeout-argument-in-address_device-usb-.patch [new file with mode: 0644]
queue-6.6/x86-bugs-fix-bhi-retpoline-check.patch [new file with mode: 0644]
queue-6.6/x86-cpufeatures-fix-dependencies-for-gfni-vaes-and-v.patch [new file with mode: 0644]

diff --git a/queue-6.6/alsa-scarlett2-add-correct-product-series-name-to-me.patch b/queue-6.6/alsa-scarlett2-add-correct-product-series-name-to-me.patch
new file mode 100644 (file)
index 0000000..4b93b30
--- /dev/null
@@ -0,0 +1,220 @@
+From 1a70dc15594ae20f6c1c5695204457bee4565b90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 03:03:03 +0930
+Subject: ALSA: scarlett2: Add correct product series name to messages
+
+From: Geoffrey D. Bennett <g@b4.vu>
+
+[ Upstream commit 6e743781d62e28f5fa095e5f31f878819622c143 ]
+
+This driver was originally developed for the Focusrite Scarlett Gen 2
+series, but now also supports the Scarlett Gen 3 series, the
+Clarett 8Pre USB, and the Clarett+ 8Pre. The messages output by the
+driver on initialisation and error include the identifying text
+"Scarlett Gen 2/3", but this is no longer accurate, and writing
+"Scarlett Gen 2/3/Clarett USB/Clarett+" would be unwieldy.
+
+Add series_name field to the scarlett2_device_entry struct so that
+concise and accurate messages can be output.
+
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Link: https://lore.kernel.org/r/3774b9d35bf1fbdd6fdad9f3f4f97e9b82ac76bf.1694705811.git.g@b4.vu
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: b61a3acada00 ("ALSA: scarlett2: Add Focusrite Clarett+ 2Pre and 4Pre support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer_scarlett_gen2.c | 81 ++++++++++++++++++++++-----------
+ 1 file changed, 54 insertions(+), 27 deletions(-)
+
+diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
+index c53ce9b81a7bb..83df5621c98f5 100644
+--- a/sound/usb/mixer_scarlett_gen2.c
++++ b/sound/usb/mixer_scarlett_gen2.c
+@@ -391,6 +391,7 @@ struct scarlett2_data {
+       struct mutex data_mutex; /* lock access to this data */
+       struct delayed_work work;
+       const struct scarlett2_device_info *info;
++      const char *series_name;
+       __u8 bInterfaceNumber;
+       __u8 bEndpointAddress;
+       __u16 wMaxPacketSize;
+@@ -887,25 +888,26 @@ static const struct scarlett2_device_info clarett_8pre_info = {
+ struct scarlett2_device_entry {
+       const u32 usb_id; /* USB device identifier */
+       const struct scarlett2_device_info *info;
++      const char *series_name;
+ };
+ static const struct scarlett2_device_entry scarlett2_devices[] = {
+       /* Supported Gen 2 devices */
+-      { USB_ID(0x1235, 0x8203), &s6i6_gen2_info },
+-      { USB_ID(0x1235, 0x8204), &s18i8_gen2_info },
+-      { USB_ID(0x1235, 0x8201), &s18i20_gen2_info },
++      { USB_ID(0x1235, 0x8203), &s6i6_gen2_info, "Scarlett Gen 2" },
++      { USB_ID(0x1235, 0x8204), &s18i8_gen2_info, "Scarlett Gen 2" },
++      { USB_ID(0x1235, 0x8201), &s18i20_gen2_info, "Scarlett Gen 2" },
+       /* Supported Gen 3 devices */
+-      { USB_ID(0x1235, 0x8211), &solo_gen3_info },
+-      { USB_ID(0x1235, 0x8210), &s2i2_gen3_info },
+-      { USB_ID(0x1235, 0x8212), &s4i4_gen3_info },
+-      { USB_ID(0x1235, 0x8213), &s8i6_gen3_info },
+-      { USB_ID(0x1235, 0x8214), &s18i8_gen3_info },
+-      { USB_ID(0x1235, 0x8215), &s18i20_gen3_info },
++      { USB_ID(0x1235, 0x8211), &solo_gen3_info, "Scarlett Gen 3" },
++      { USB_ID(0x1235, 0x8210), &s2i2_gen3_info, "Scarlett Gen 3" },
++      { USB_ID(0x1235, 0x8212), &s4i4_gen3_info, "Scarlett Gen 3" },
++      { USB_ID(0x1235, 0x8213), &s8i6_gen3_info, "Scarlett Gen 3" },
++      { USB_ID(0x1235, 0x8214), &s18i8_gen3_info, "Scarlett Gen 3" },
++      { USB_ID(0x1235, 0x8215), &s18i20_gen3_info, "Scarlett Gen 3" },
+       /* Supported Clarett USB/Clarett+ devices */
+-      { USB_ID(0x1235, 0x8208), &clarett_8pre_info },
+-      { USB_ID(0x1235, 0x820c), &clarett_8pre_info },
++      { USB_ID(0x1235, 0x8208), &clarett_8pre_info, "Clarett USB" },
++      { USB_ID(0x1235, 0x820c), &clarett_8pre_info, "Clarett+" },
+       /* End of list */
+       { 0, NULL },
+@@ -1205,8 +1207,8 @@ static int scarlett2_usb(
+       if (err != req_buf_size) {
+               usb_audio_err(
+                       mixer->chip,
+-                      "Scarlett Gen 2/3 USB request result cmd %x was %d\n",
+-                      cmd, err);
++                      "%s USB request result cmd %x was %d\n",
++                      private->series_name, cmd, err);
+               err = -EINVAL;
+               goto unlock;
+       }
+@@ -1222,9 +1224,8 @@ static int scarlett2_usb(
+       if (err != resp_buf_size) {
+               usb_audio_err(
+                       mixer->chip,
+-                      "Scarlett Gen 2/3 USB response result cmd %x was %d "
+-                      "expected %zu\n",
+-                      cmd, err, resp_buf_size);
++                      "%s USB response result cmd %x was %d expected %zu\n",
++                      private->series_name, cmd, err, resp_buf_size);
+               err = -EINVAL;
+               goto unlock;
+       }
+@@ -1240,9 +1241,10 @@ static int scarlett2_usb(
+           resp->pad) {
+               usb_audio_err(
+                       mixer->chip,
+-                      "Scarlett Gen 2/3 USB invalid response; "
++                      "%s USB invalid response; "
+                          "cmd tx/rx %d/%d seq %d/%d size %d/%d "
+                          "error %d pad %d\n",
++                      private->series_name,
+                       le32_to_cpu(req->cmd), le32_to_cpu(resp->cmd),
+                       le16_to_cpu(req->seq), le16_to_cpu(resp->seq),
+                       resp_size, le16_to_cpu(resp->size),
+@@ -3798,7 +3800,7 @@ static int scarlett2_find_fc_interface(struct usb_device *dev,
+ /* Initialise private data */
+ static int scarlett2_init_private(struct usb_mixer_interface *mixer,
+-                                const struct scarlett2_device_info *info)
++                                const struct scarlett2_device_entry *entry)
+ {
+       struct scarlett2_data *private =
+               kzalloc(sizeof(struct scarlett2_data), GFP_KERNEL);
+@@ -3814,7 +3816,8 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer,
+       mixer->private_free = scarlett2_private_free;
+       mixer->private_suspend = scarlett2_private_suspend;
+-      private->info = info;
++      private->info = entry->info;
++      private->series_name = entry->series_name;
+       scarlett2_count_mux_io(private);
+       private->scarlett2_seq = 0;
+       private->mixer = mixer;
+@@ -4135,19 +4138,28 @@ static int scarlett2_init_notify(struct usb_mixer_interface *mixer)
+       return usb_submit_urb(mixer->urb, GFP_KERNEL);
+ }
+-static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer)
++static const struct scarlett2_device_entry *get_scarlett2_device_entry(
++      struct usb_mixer_interface *mixer)
+ {
+       const struct scarlett2_device_entry *entry = scarlett2_devices;
+-      int err;
+       /* Find entry in scarlett2_devices */
+       while (entry->usb_id && entry->usb_id != mixer->chip->usb_id)
+               entry++;
+       if (!entry->usb_id)
+-              return -EINVAL;
++              return NULL;
++
++      return entry;
++}
++
++static int snd_scarlett_gen2_controls_create(
++      struct usb_mixer_interface *mixer,
++      const struct scarlett2_device_entry *entry)
++{
++      int err;
+       /* Initialise private data */
+-      err = scarlett2_init_private(mixer, entry->info);
++      err = scarlett2_init_private(mixer, entry);
+       if (err < 0)
+               return err;
+@@ -4231,17 +4243,30 @@ static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer)
+ int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer)
+ {
+       struct snd_usb_audio *chip = mixer->chip;
++      const struct scarlett2_device_entry *entry;
+       int err;
+       /* only use UAC_VERSION_2 */
+       if (!mixer->protocol)
+               return 0;
++      /* find entry in scarlett2_devices */
++      entry = get_scarlett2_device_entry(mixer);
++      if (!entry) {
++              usb_audio_err(mixer->chip,
++                            "%s: missing device entry for %04x:%04x\n",
++                            __func__,
++                            USB_ID_VENDOR(chip->usb_id),
++                            USB_ID_PRODUCT(chip->usb_id));
++              return 0;
++      }
++
+       if (chip->setup & SCARLETT2_DISABLE) {
+               usb_audio_info(chip,
+-                      "Focusrite Scarlett Gen 2/3 Mixer Driver disabled "
++                      "Focusrite %s Mixer Driver disabled "
+                       "by modprobe options (snd_usb_audio "
+                       "vid=0x%04x pid=0x%04x device_setup=%d)\n",
++                      entry->series_name,
+                       USB_ID_VENDOR(chip->usb_id),
+                       USB_ID_PRODUCT(chip->usb_id),
+                       SCARLETT2_DISABLE);
+@@ -4249,14 +4274,16 @@ int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer)
+       }
+       usb_audio_info(chip,
+-              "Focusrite Scarlett Gen 2/3 Mixer Driver enabled (pid=0x%04x); "
++              "Focusrite %s Mixer Driver enabled (pid=0x%04x); "
+               "report any issues to g@b4.vu",
++              entry->series_name,
+               USB_ID_PRODUCT(chip->usb_id));
+-      err = snd_scarlett_gen2_controls_create(mixer);
++      err = snd_scarlett_gen2_controls_create(mixer, entry);
+       if (err < 0)
+               usb_audio_err(mixer->chip,
+-                            "Error initialising Scarlett Mixer Driver: %d",
++                            "Error initialising %s Mixer Driver: %d",
++                            entry->series_name,
+                             err);
+       return err;
+-- 
+2.43.0
+
diff --git a/queue-6.6/alsa-scarlett2-add-focusrite-clarett-2pre-and-4pre-s.patch b/queue-6.6/alsa-scarlett2-add-focusrite-clarett-2pre-and-4pre-s.patch
new file mode 100644 (file)
index 0000000..97ef81c
--- /dev/null
@@ -0,0 +1,171 @@
+From af4a3a3cfe96790e7ada75a3a256d2298502b55f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 01:11:30 +0930
+Subject: ALSA: scarlett2: Add Focusrite Clarett+ 2Pre and 4Pre support
+
+From: Geoffrey D. Bennett <g@b4.vu>
+
+[ Upstream commit b61a3acada0031e7a4922d1340b4296ab95c260b ]
+
+The Focusrite Clarett+ series uses the same protocol as the Scarlett
+Gen 2 and Gen 3 series. This patch adds support for the Clarett+ 2Pre
+and Clarett+ 4Pre similarly to the existing 8Pre support by adding
+appropriate entries to the scarlett2 driver.
+
+The Clarett 2Pre USB and 4Pre USB presumably use the same protocol as
+well, so support for them can easily be added if someone can test.
+
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Link: https://lore.kernel.org/r/ZRL7qjC3tYQllT3H@m.b4.vu
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer_quirks.c        |  2 +
+ sound/usb/mixer_scarlett_gen2.c | 97 ++++++++++++++++++++++++++++++++-
+ 2 files changed, 98 insertions(+), 1 deletion(-)
+
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index b122d7aedb443..3721d59a56809 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -3448,6 +3448,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
+       case USB_ID(0x1235, 0x8214): /* Focusrite Scarlett 18i8 3rd Gen */
+       case USB_ID(0x1235, 0x8215): /* Focusrite Scarlett 18i20 3rd Gen */
+       case USB_ID(0x1235, 0x8208): /* Focusrite Clarett 8Pre USB */
++      case USB_ID(0x1235, 0x820a): /* Focusrite Clarett+ 2Pre */
++      case USB_ID(0x1235, 0x820b): /* Focusrite Clarett+ 4Pre */
+       case USB_ID(0x1235, 0x820c): /* Focusrite Clarett+ 8Pre */
+               err = snd_scarlett_gen2_init(mixer);
+               break;
+diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
+index 83df5621c98f5..653dc7d8fb47c 100644
+--- a/sound/usb/mixer_scarlett_gen2.c
++++ b/sound/usb/mixer_scarlett_gen2.c
+@@ -6,7 +6,7 @@
+  *   - 6i6/18i8/18i20 Gen 2
+  *   - Solo/2i2/4i4/8i6/18i8/18i20 Gen 3
+  *   - Clarett 8Pre USB
+- *   - Clarett+ 8Pre
++ *   - Clarett+ 2Pre/4Pre/8Pre
+  *
+  *   Copyright (c) 2018-2023 by Geoffrey D. Bennett <g at b4.vu>
+  *   Copyright (c) 2020-2021 by Vladimir Sadovnikov <sadko4u@gmail.com>
+@@ -60,6 +60,10 @@
+  * Support for Clarett 8Pre USB added in Sep 2023 (thanks to Philippe
+  * Perrot for confirmation).
+  *
++ * Support for Clarett+ 4Pre and 2Pre added in Sep 2023 (thanks to
++ * Gregory Rozzo for donating a 4Pre, and David Sherwood and Patrice
++ * Peterson for usbmon output).
++ *
+  * This ALSA mixer gives access to (model-dependent):
+  *  - input, output, mixer-matrix muxes
+  *  - mixer-matrix gain stages
+@@ -832,6 +836,95 @@ static const struct scarlett2_device_info s18i20_gen3_info = {
+       } },
+ };
++static const struct scarlett2_device_info clarett_2pre_info = {
++      .config_set = SCARLETT2_CONFIG_SET_CLARETT,
++      .line_out_hw_vol = 1,
++      .level_input_count = 2,
++      .air_input_count = 2,
++
++      .line_out_descrs = {
++              "Monitor L",
++              "Monitor R",
++              "Headphones L",
++              "Headphones R",
++      },
++
++      .port_count = {
++              [SCARLETT2_PORT_TYPE_NONE]     = {  1,  0 },
++              [SCARLETT2_PORT_TYPE_ANALOGUE] = {  2,  4 },
++              [SCARLETT2_PORT_TYPE_SPDIF]    = {  2,  0 },
++              [SCARLETT2_PORT_TYPE_ADAT]     = {  8,  0 },
++              [SCARLETT2_PORT_TYPE_MIX]      = { 10, 18 },
++              [SCARLETT2_PORT_TYPE_PCM]      = {  4, 12 },
++      },
++
++      .mux_assignment = { {
++              { SCARLETT2_PORT_TYPE_PCM,      0, 12 },
++              { SCARLETT2_PORT_TYPE_ANALOGUE, 0,  4 },
++              { SCARLETT2_PORT_TYPE_MIX,      0, 18 },
++              { SCARLETT2_PORT_TYPE_NONE,     0,  8 },
++              { 0,                            0,  0 },
++      }, {
++              { SCARLETT2_PORT_TYPE_PCM,      0,  8 },
++              { SCARLETT2_PORT_TYPE_ANALOGUE, 0,  4 },
++              { SCARLETT2_PORT_TYPE_MIX,      0, 18 },
++              { SCARLETT2_PORT_TYPE_NONE,     0,  8 },
++              { 0,                            0,  0 },
++      }, {
++              { SCARLETT2_PORT_TYPE_PCM,      0,  2 },
++              { SCARLETT2_PORT_TYPE_ANALOGUE, 0,  4 },
++              { SCARLETT2_PORT_TYPE_NONE,     0, 26 },
++              { 0,                            0,  0 },
++      } },
++};
++
++static const struct scarlett2_device_info clarett_4pre_info = {
++      .config_set = SCARLETT2_CONFIG_SET_CLARETT,
++      .line_out_hw_vol = 1,
++      .level_input_count = 2,
++      .air_input_count = 4,
++
++      .line_out_descrs = {
++              "Monitor L",
++              "Monitor R",
++              "Headphones 1 L",
++              "Headphones 1 R",
++              "Headphones 2 L",
++              "Headphones 2 R",
++      },
++
++      .port_count = {
++              [SCARLETT2_PORT_TYPE_NONE]     = {  1,  0 },
++              [SCARLETT2_PORT_TYPE_ANALOGUE] = {  8,  6 },
++              [SCARLETT2_PORT_TYPE_SPDIF]    = {  2,  2 },
++              [SCARLETT2_PORT_TYPE_ADAT]     = {  8,  0 },
++              [SCARLETT2_PORT_TYPE_MIX]      = { 10, 18 },
++              [SCARLETT2_PORT_TYPE_PCM]      = {  8, 18 },
++      },
++
++      .mux_assignment = { {
++              { SCARLETT2_PORT_TYPE_PCM,      0, 18 },
++              { SCARLETT2_PORT_TYPE_ANALOGUE, 0,  6 },
++              { SCARLETT2_PORT_TYPE_SPDIF,    0,  2 },
++              { SCARLETT2_PORT_TYPE_MIX,      0, 18 },
++              { SCARLETT2_PORT_TYPE_NONE,     0,  8 },
++              { 0,                            0,  0 },
++      }, {
++              { SCARLETT2_PORT_TYPE_PCM,      0, 14 },
++              { SCARLETT2_PORT_TYPE_ANALOGUE, 0,  6 },
++              { SCARLETT2_PORT_TYPE_SPDIF,    0,  2 },
++              { SCARLETT2_PORT_TYPE_MIX,      0, 18 },
++              { SCARLETT2_PORT_TYPE_NONE,     0,  8 },
++              { 0,                            0,  0 },
++      }, {
++              { SCARLETT2_PORT_TYPE_PCM,      0, 12 },
++              { SCARLETT2_PORT_TYPE_ANALOGUE, 0,  6 },
++              { SCARLETT2_PORT_TYPE_SPDIF,    0,  2 },
++              { SCARLETT2_PORT_TYPE_NONE,     0, 24 },
++              { 0,                            0,  0 },
++      } },
++};
++
+ static const struct scarlett2_device_info clarett_8pre_info = {
+       .config_set = SCARLETT2_CONFIG_SET_CLARETT,
+       .line_out_hw_vol = 1,
+@@ -907,6 +1000,8 @@ static const struct scarlett2_device_entry scarlett2_devices[] = {
+       /* Supported Clarett USB/Clarett+ devices */
+       { USB_ID(0x1235, 0x8208), &clarett_8pre_info, "Clarett USB" },
++      { USB_ID(0x1235, 0x820a), &clarett_2pre_info, "Clarett+" },
++      { USB_ID(0x1235, 0x820b), &clarett_4pre_info, "Clarett+" },
+       { USB_ID(0x1235, 0x820c), &clarett_8pre_info, "Clarett+" },
+       /* End of list */
+-- 
+2.43.0
+
diff --git a/queue-6.6/alsa-scarlett2-add-focusrite-clarett-2pre-and-4pre-u.patch b/queue-6.6/alsa-scarlett2-add-focusrite-clarett-2pre-and-4pre-u.patch
new file mode 100644 (file)
index 0000000..50c3c6d
--- /dev/null
@@ -0,0 +1,78 @@
+From 93b953c99a41fb5e9660f50227a2c9def7619ad7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Oct 2023 22:03:04 +1030
+Subject: ALSA: scarlett2: Add Focusrite Clarett 2Pre and 4Pre USB support
+
+From: Geoffrey D. Bennett <g@b4.vu>
+
+[ Upstream commit 2b17b489e47a956c8e93c8f1bcabb0343c851d90 ]
+
+It has been confirmed that all devices in the Focusrite Clarett USB
+series work the same as the devices in the Clarett+ series. Add the
+missing PIDs to enable support for the Clarett 2Pre and 4Pre USB.
+
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Link: https://lore.kernel.org/r/ZSFB8EVTG1PK1eq/@m.b4.vu
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer_quirks.c        | 2 ++
+ sound/usb/mixer_scarlett_gen2.c | 8 ++++++--
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index 3721d59a56809..a331732fed890 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -3447,6 +3447,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
+       case USB_ID(0x1235, 0x8213): /* Focusrite Scarlett 8i6 3rd Gen */
+       case USB_ID(0x1235, 0x8214): /* Focusrite Scarlett 18i8 3rd Gen */
+       case USB_ID(0x1235, 0x8215): /* Focusrite Scarlett 18i20 3rd Gen */
++      case USB_ID(0x1235, 0x8206): /* Focusrite Clarett 2Pre USB */
++      case USB_ID(0x1235, 0x8207): /* Focusrite Clarett 4Pre USB */
+       case USB_ID(0x1235, 0x8208): /* Focusrite Clarett 8Pre USB */
+       case USB_ID(0x1235, 0x820a): /* Focusrite Clarett+ 2Pre */
+       case USB_ID(0x1235, 0x820b): /* Focusrite Clarett+ 4Pre */
+diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
+index 653dc7d8fb47c..e5e70abf5286b 100644
+--- a/sound/usb/mixer_scarlett_gen2.c
++++ b/sound/usb/mixer_scarlett_gen2.c
+@@ -5,7 +5,7 @@
+  *   Supported models:
+  *   - 6i6/18i8/18i20 Gen 2
+  *   - Solo/2i2/4i4/8i6/18i8/18i20 Gen 3
+- *   - Clarett 8Pre USB
++ *   - Clarett 2Pre/4Pre/8Pre USB
+  *   - Clarett+ 2Pre/4Pre/8Pre
+  *
+  *   Copyright (c) 2018-2023 by Geoffrey D. Bennett <g at b4.vu>
+@@ -64,6 +64,8 @@
+  * Gregory Rozzo for donating a 4Pre, and David Sherwood and Patrice
+  * Peterson for usbmon output).
+  *
++ * Support for Clarett 2Pre and 4Pre USB added in Oct 2023.
++ *
+  * This ALSA mixer gives access to (model-dependent):
+  *  - input, output, mixer-matrix muxes
+  *  - mixer-matrix gain stages
+@@ -999,6 +1001,8 @@ static const struct scarlett2_device_entry scarlett2_devices[] = {
+       { USB_ID(0x1235, 0x8215), &s18i20_gen3_info, "Scarlett Gen 3" },
+       /* Supported Clarett USB/Clarett+ devices */
++      { USB_ID(0x1235, 0x8206), &clarett_2pre_info, "Clarett USB" },
++      { USB_ID(0x1235, 0x8207), &clarett_4pre_info, "Clarett USB" },
+       { USB_ID(0x1235, 0x8208), &clarett_8pre_info, "Clarett USB" },
+       { USB_ID(0x1235, 0x820a), &clarett_2pre_info, "Clarett+" },
+       { USB_ID(0x1235, 0x820b), &clarett_4pre_info, "Clarett+" },
+@@ -1197,7 +1201,7 @@ static const struct scarlett2_config
+       [SCARLETT2_CONFIG_TALKBACK_MAP] = {
+               .offset = 0xb0, .size = 16, .activate = 10 },
+-/* Clarett+ 8Pre */
++/* Clarett USB and Clarett+ devices: 2Pre, 4Pre, 8Pre */
+ }, {
+       [SCARLETT2_CONFIG_DIM_MUTE] = {
+               .offset = 0x31, .size = 8, .activate = 2 },
+-- 
+2.43.0
+
diff --git a/queue-6.6/alsa-scarlett2-add-support-for-clarett-8pre-usb.patch b/queue-6.6/alsa-scarlett2-add-support-for-clarett-8pre-usb.patch
new file mode 100644 (file)
index 0000000..827b9af
--- /dev/null
@@ -0,0 +1,78 @@
+From bc37874cb1330dfe64ab2dc79d81b303cb0d7203 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 03:02:37 +0930
+Subject: ALSA: scarlett2: Add support for Clarett 8Pre USB
+
+From: Geoffrey D. Bennett <g@b4.vu>
+
+[ Upstream commit b9a98cdd3ac7b80d8ea0f6acd81c88ad3d8bcb4a ]
+
+The Clarett 8Pre USB works the same as the Clarett+ 8Pre, only the USB
+ID is different.
+
+Tested-by: Philippe Perrot <philippe@perrot-net.fr>
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Link: https://lore.kernel.org/r/e59f47b29e2037f031b56bde10474c6e96e31ba5.1694705811.git.g@b4.vu
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer_quirks.c        |  1 +
+ sound/usb/mixer_scarlett_gen2.c | 11 ++++++++---
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index 1f32e3ae3aa31..b122d7aedb443 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -3447,6 +3447,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
+       case USB_ID(0x1235, 0x8213): /* Focusrite Scarlett 8i6 3rd Gen */
+       case USB_ID(0x1235, 0x8214): /* Focusrite Scarlett 18i8 3rd Gen */
+       case USB_ID(0x1235, 0x8215): /* Focusrite Scarlett 18i20 3rd Gen */
++      case USB_ID(0x1235, 0x8208): /* Focusrite Clarett 8Pre USB */
+       case USB_ID(0x1235, 0x820c): /* Focusrite Clarett+ 8Pre */
+               err = snd_scarlett_gen2_init(mixer);
+               break;
+diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
+index cfb7345ee7a8c..bf3d916d5a13c 100644
+--- a/sound/usb/mixer_scarlett_gen2.c
++++ b/sound/usb/mixer_scarlett_gen2.c
+@@ -1,13 +1,14 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+- *   Focusrite Scarlett Gen 2/3 and Clarett+ Driver for ALSA
++ *   Focusrite Scarlett Gen 2/3 and Clarett USB/Clarett+ Driver for ALSA
+  *
+  *   Supported models:
+  *   - 6i6/18i8/18i20 Gen 2
+  *   - Solo/2i2/4i4/8i6/18i8/18i20 Gen 3
++ *   - Clarett 8Pre USB
+  *   - Clarett+ 8Pre
+  *
+- *   Copyright (c) 2018-2022 by Geoffrey D. Bennett <g at b4.vu>
++ *   Copyright (c) 2018-2023 by Geoffrey D. Bennett <g at b4.vu>
+  *   Copyright (c) 2020-2021 by Vladimir Sadovnikov <sadko4u@gmail.com>
+  *   Copyright (c) 2022 by Christian Colglazier <christian@cacolglazier.com>
+  *
+@@ -56,6 +57,9 @@
+  * Support for Clarett+ 8Pre added in Aug 2022 by Christian
+  * Colglazier.
+  *
++ * Support for Clarett 8Pre USB added in Sep 2023 (thanks to Philippe
++ * Perrot for confirmation).
++ *
+  * This ALSA mixer gives access to (model-dependent):
+  *  - input, output, mixer-matrix muxes
+  *  - mixer-matrix gain stages
+@@ -899,7 +903,8 @@ static const struct scarlett2_device_entry scarlett2_devices[] = {
+       { USB_ID(0x1235, 0x8214), &s18i8_gen3_info },
+       { USB_ID(0x1235, 0x8215), &s18i20_gen3_info },
+-      /* Supported Clarett+ devices */
++      /* Supported Clarett USB/Clarett+ devices */
++      { USB_ID(0x1235, 0x8208), &clarett_8pre_info },
+       { USB_ID(0x1235, 0x820c), &clarett_8pre_info },
+       /* End of list */
+-- 
+2.43.0
+
diff --git a/queue-6.6/alsa-scarlett2-default-mixer-driver-to-enabled.patch b/queue-6.6/alsa-scarlett2-default-mixer-driver-to-enabled.patch
new file mode 100644 (file)
index 0000000..27147d2
--- /dev/null
@@ -0,0 +1,82 @@
+From d7da5fd48f26e16cf88bbb8f2e9bca23d0d8ade1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 03:01:57 +0930
+Subject: ALSA: scarlett2: Default mixer driver to enabled
+
+From: Geoffrey D. Bennett <g@b4.vu>
+
+[ Upstream commit bc83058f598757a908b30f8f536338cb1478ab5b ]
+
+Early versions of this mixer driver did not work on all hardware, so
+out of caution the driver was disabled by default and had to be
+explicitly enabled with device_setup=1.
+
+Since commit 764fa6e686e0 ("ALSA: usb-audio: scarlett2: Fix device
+hang with ehci-pci") no more problems of this nature have been
+reported. Therefore, enable the driver by default but provide a new
+device_setup option to disable the driver in case that is needed.
+
+- device_setup value of 0 now means "enable" rather than "disable".
+- device_setup value of 1 is now ignored.
+- device_setup value of 4 now means "disable".
+
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Link: https://lore.kernel.org/r/89600a35b40307f2766578ad1ca2f21801286b58.1694705811.git.g@b4.vu
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: b61a3acada00 ("ALSA: scarlett2: Add Focusrite Clarett+ 2Pre and 4Pre support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer_scarlett_gen2.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
+index bf3d916d5a13c..c53ce9b81a7bb 100644
+--- a/sound/usb/mixer_scarlett_gen2.c
++++ b/sound/usb/mixer_scarlett_gen2.c
+@@ -145,12 +145,12 @@
+ #include "mixer_scarlett_gen2.h"
+-/* device_setup value to enable */
+-#define SCARLETT2_ENABLE 0x01
+-
+ /* device_setup value to allow turning MSD mode back on */
+ #define SCARLETT2_MSD_ENABLE 0x02
++/* device_setup value to disable this mixer driver */
++#define SCARLETT2_DISABLE 0x04
++
+ /* some gui mixers can't handle negative ctl values */
+ #define SCARLETT2_VOLUME_BIAS 127
+@@ -4237,19 +4237,20 @@ int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer)
+       if (!mixer->protocol)
+               return 0;
+-      if (!(chip->setup & SCARLETT2_ENABLE)) {
++      if (chip->setup & SCARLETT2_DISABLE) {
+               usb_audio_info(chip,
+-                      "Focusrite Scarlett Gen 2/3 Mixer Driver disabled; "
+-                      "use options snd_usb_audio vid=0x%04x pid=0x%04x "
+-                      "device_setup=1 to enable and report any issues "
+-                      "to g@b4.vu",
++                      "Focusrite Scarlett Gen 2/3 Mixer Driver disabled "
++                      "by modprobe options (snd_usb_audio "
++                      "vid=0x%04x pid=0x%04x device_setup=%d)\n",
+                       USB_ID_VENDOR(chip->usb_id),
+-                      USB_ID_PRODUCT(chip->usb_id));
++                      USB_ID_PRODUCT(chip->usb_id),
++                      SCARLETT2_DISABLE);
+               return 0;
+       }
+       usb_audio_info(chip,
+-              "Focusrite Scarlett Gen 2/3 Mixer Driver enabled pid=0x%04x",
++              "Focusrite Scarlett Gen 2/3 Mixer Driver enabled (pid=0x%04x); "
++              "report any issues to g@b4.vu",
+               USB_ID_PRODUCT(chip->usb_id));
+       err = snd_scarlett_gen2_controls_create(mixer);
+-- 
+2.43.0
+
diff --git a/queue-6.6/alsa-scarlett2-move-usb-ids-out-from-device_info-str.patch b/queue-6.6/alsa-scarlett2-move-usb-ids-out-from-device_info-str.patch
new file mode 100644 (file)
index 0000000..bae86f6
--- /dev/null
@@ -0,0 +1,196 @@
+From 81d93f4f95db569abab7e9be131cad9419facf17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 03:02:16 +0930
+Subject: ALSA: scarlett2: Move USB IDs out from device_info struct
+
+From: Geoffrey D. Bennett <g@b4.vu>
+
+[ Upstream commit d98cc489029dba4d99714c2e8ec4f5ba249f6851 ]
+
+By moving the USB IDs from the device_info struct into
+scarlett2_devices[], that will allow for devices with different
+USB IDs to share the same device_info.
+
+Tested-by: Philippe Perrot <philippe@perrot-net.fr>
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Link: https://lore.kernel.org/r/8263368e8d49e6fcebc709817bd82ab79b404468.1694705811.git.g@b4.vu
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: b9a98cdd3ac7 ("ALSA: scarlett2: Add support for Clarett 8Pre USB")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer_scarlett_gen2.c | 63 ++++++++++++---------------------
+ 1 file changed, 23 insertions(+), 40 deletions(-)
+
+diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
+index c04cff7225411..cfb7345ee7a8c 100644
+--- a/sound/usb/mixer_scarlett_gen2.c
++++ b/sound/usb/mixer_scarlett_gen2.c
+@@ -317,8 +317,6 @@ struct scarlett2_mux_entry {
+ };
+ struct scarlett2_device_info {
+-      u32 usb_id; /* USB device identifier */
+-
+       /* Gen 3 devices have an internal MSD mode switch that needs
+        * to be disabled in order to access the full functionality of
+        * the device.
+@@ -440,8 +438,6 @@ struct scarlett2_data {
+ /*** Model-specific data ***/
+ static const struct scarlett2_device_info s6i6_gen2_info = {
+-      .usb_id = USB_ID(0x1235, 0x8203),
+-
+       .config_set = SCARLETT2_CONFIG_SET_GEN_2,
+       .level_input_count = 2,
+       .pad_input_count = 2,
+@@ -486,8 +482,6 @@ static const struct scarlett2_device_info s6i6_gen2_info = {
+ };
+ static const struct scarlett2_device_info s18i8_gen2_info = {
+-      .usb_id = USB_ID(0x1235, 0x8204),
+-
+       .config_set = SCARLETT2_CONFIG_SET_GEN_2,
+       .level_input_count = 2,
+       .pad_input_count = 4,
+@@ -535,8 +529,6 @@ static const struct scarlett2_device_info s18i8_gen2_info = {
+ };
+ static const struct scarlett2_device_info s18i20_gen2_info = {
+-      .usb_id = USB_ID(0x1235, 0x8201),
+-
+       .config_set = SCARLETT2_CONFIG_SET_GEN_2,
+       .line_out_hw_vol = 1,
+@@ -589,8 +581,6 @@ static const struct scarlett2_device_info s18i20_gen2_info = {
+ };
+ static const struct scarlett2_device_info solo_gen3_info = {
+-      .usb_id = USB_ID(0x1235, 0x8211),
+-
+       .has_msd_mode = 1,
+       .config_set = SCARLETT2_CONFIG_SET_NO_MIXER,
+       .level_input_count = 1,
+@@ -602,8 +592,6 @@ static const struct scarlett2_device_info solo_gen3_info = {
+ };
+ static const struct scarlett2_device_info s2i2_gen3_info = {
+-      .usb_id = USB_ID(0x1235, 0x8210),
+-
+       .has_msd_mode = 1,
+       .config_set = SCARLETT2_CONFIG_SET_NO_MIXER,
+       .level_input_count = 2,
+@@ -614,8 +602,6 @@ static const struct scarlett2_device_info s2i2_gen3_info = {
+ };
+ static const struct scarlett2_device_info s4i4_gen3_info = {
+-      .usb_id = USB_ID(0x1235, 0x8212),
+-
+       .has_msd_mode = 1,
+       .config_set = SCARLETT2_CONFIG_SET_GEN_3,
+       .level_input_count = 2,
+@@ -660,8 +646,6 @@ static const struct scarlett2_device_info s4i4_gen3_info = {
+ };
+ static const struct scarlett2_device_info s8i6_gen3_info = {
+-      .usb_id = USB_ID(0x1235, 0x8213),
+-
+       .has_msd_mode = 1,
+       .config_set = SCARLETT2_CONFIG_SET_GEN_3,
+       .level_input_count = 2,
+@@ -713,8 +697,6 @@ static const struct scarlett2_device_info s8i6_gen3_info = {
+ };
+ static const struct scarlett2_device_info s18i8_gen3_info = {
+-      .usb_id = USB_ID(0x1235, 0x8214),
+-
+       .has_msd_mode = 1,
+       .config_set = SCARLETT2_CONFIG_SET_GEN_3,
+       .line_out_hw_vol = 1,
+@@ -783,8 +765,6 @@ static const struct scarlett2_device_info s18i8_gen3_info = {
+ };
+ static const struct scarlett2_device_info s18i20_gen3_info = {
+-      .usb_id = USB_ID(0x1235, 0x8215),
+-
+       .has_msd_mode = 1,
+       .config_set = SCARLETT2_CONFIG_SET_GEN_3,
+       .line_out_hw_vol = 1,
+@@ -848,8 +828,6 @@ static const struct scarlett2_device_info s18i20_gen3_info = {
+ };
+ static const struct scarlett2_device_info clarett_8pre_info = {
+-      .usb_id = USB_ID(0x1235, 0x820c),
+-
+       .config_set = SCARLETT2_CONFIG_SET_CLARETT,
+       .line_out_hw_vol = 1,
+       .level_input_count = 2,
+@@ -902,25 +880,30 @@ static const struct scarlett2_device_info clarett_8pre_info = {
+       } },
+ };
+-static const struct scarlett2_device_info *scarlett2_devices[] = {
++struct scarlett2_device_entry {
++      const u32 usb_id; /* USB device identifier */
++      const struct scarlett2_device_info *info;
++};
++
++static const struct scarlett2_device_entry scarlett2_devices[] = {
+       /* Supported Gen 2 devices */
+-      &s6i6_gen2_info,
+-      &s18i8_gen2_info,
+-      &s18i20_gen2_info,
++      { USB_ID(0x1235, 0x8203), &s6i6_gen2_info },
++      { USB_ID(0x1235, 0x8204), &s18i8_gen2_info },
++      { USB_ID(0x1235, 0x8201), &s18i20_gen2_info },
+       /* Supported Gen 3 devices */
+-      &solo_gen3_info,
+-      &s2i2_gen3_info,
+-      &s4i4_gen3_info,
+-      &s8i6_gen3_info,
+-      &s18i8_gen3_info,
+-      &s18i20_gen3_info,
++      { USB_ID(0x1235, 0x8211), &solo_gen3_info },
++      { USB_ID(0x1235, 0x8210), &s2i2_gen3_info },
++      { USB_ID(0x1235, 0x8212), &s4i4_gen3_info },
++      { USB_ID(0x1235, 0x8213), &s8i6_gen3_info },
++      { USB_ID(0x1235, 0x8214), &s18i8_gen3_info },
++      { USB_ID(0x1235, 0x8215), &s18i20_gen3_info },
+       /* Supported Clarett+ devices */
+-      &clarett_8pre_info,
++      { USB_ID(0x1235, 0x820c), &clarett_8pre_info },
+       /* End of list */
+-      NULL
++      { 0, NULL },
+ };
+ /* get the starting port index number for a given port type/direction */
+@@ -4149,17 +4132,17 @@ static int scarlett2_init_notify(struct usb_mixer_interface *mixer)
+ static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer)
+ {
+-      const struct scarlett2_device_info **info = scarlett2_devices;
++      const struct scarlett2_device_entry *entry = scarlett2_devices;
+       int err;
+-      /* Find device in scarlett2_devices */
+-      while (*info && (*info)->usb_id != mixer->chip->usb_id)
+-              info++;
+-      if (!*info)
++      /* Find entry in scarlett2_devices */
++      while (entry->usb_id && entry->usb_id != mixer->chip->usb_id)
++              entry++;
++      if (!entry->usb_id)
+               return -EINVAL;
+       /* Initialise private data */
+-      err = scarlett2_init_private(mixer, *info);
++      err = scarlett2_init_private(mixer, entry->info);
+       if (err < 0)
+               return err;
+-- 
+2.43.0
+
diff --git a/queue-6.6/alsa-scarlett2-rename-scarlett_gen2-to-scarlett2.patch b/queue-6.6/alsa-scarlett2-rename-scarlett_gen2-to-scarlett2.patch
new file mode 100644 (file)
index 0000000..493bea6
--- /dev/null
@@ -0,0 +1,163 @@
+From 9061ae27fb9689cb6debe89d82ec501d18aededa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Oct 2023 04:31:28 +1030
+Subject: ALSA: scarlett2: Rename scarlett_gen2 to scarlett2
+
+From: Geoffrey D. Bennett <g@b4.vu>
+
+[ Upstream commit efc3d7d20361cc59325a9f0525e079333b4459c0 ]
+
+This driver was originally developed for the Focusrite Scarlett Gen 2
+series. Since then Focusrite have used a similar protocol for their
+Gen 3, Gen 4, Clarett USB, Clarett+, and Vocaster series.
+
+Let's call this common protocol the "Scarlett 2 Protocol" and rename
+the driver to scarlett2 to not imply that it is restricted to Gen 2
+series devices.
+
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Link: https://lore.kernel.org/r/e1ad7f69a1e20cdb39094164504389160c1a0a0b.1698342632.git.g@b4.vu
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ MAINTAINERS                                          |  2 +-
+ sound/usb/Makefile                                   |  2 +-
+ sound/usb/mixer_quirks.c                             |  4 ++--
+ .../usb/{mixer_scarlett_gen2.c => mixer_scarlett2.c} | 12 +++++++-----
+ sound/usb/mixer_scarlett2.h                          |  7 +++++++
+ sound/usb/mixer_scarlett_gen2.h                      |  7 -------
+ 6 files changed, 18 insertions(+), 16 deletions(-)
+ rename sound/usb/{mixer_scarlett_gen2.c => mixer_scarlett2.c} (99%)
+ create mode 100644 sound/usb/mixer_scarlett2.h
+ delete mode 100644 sound/usb/mixer_scarlett_gen2.h
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 40312bb550f06..72a2880afab7a 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -8142,7 +8142,7 @@ M:       Geoffrey D. Bennett <g@b4.vu>
+ L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
+ S:    Maintained
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
+-F:    sound/usb/mixer_scarlett_gen2.c
++F:    sound/usb/mixer_scarlett2.c
+ FORCEDETH GIGABIT ETHERNET DRIVER
+ M:    Rain River <rain.1986.08.12@gmail.com>
+diff --git a/sound/usb/Makefile b/sound/usb/Makefile
+index db5ff76d0e61f..8c657c2753c84 100644
+--- a/sound/usb/Makefile
++++ b/sound/usb/Makefile
+@@ -12,7 +12,7 @@ snd-usb-audio-objs :=        card.o \
+                       mixer.o \
+                       mixer_quirks.o \
+                       mixer_scarlett.o \
+-                      mixer_scarlett_gen2.o \
++                      mixer_scarlett2.o \
+                       mixer_us16x08.o \
+                       mixer_s1810c.o \
+                       pcm.o \
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index a331732fed890..c8d48566e1759 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -33,7 +33,7 @@
+ #include "mixer.h"
+ #include "mixer_quirks.h"
+ #include "mixer_scarlett.h"
+-#include "mixer_scarlett_gen2.h"
++#include "mixer_scarlett2.h"
+ #include "mixer_us16x08.h"
+ #include "mixer_s1810c.h"
+ #include "helper.h"
+@@ -3453,7 +3453,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
+       case USB_ID(0x1235, 0x820a): /* Focusrite Clarett+ 2Pre */
+       case USB_ID(0x1235, 0x820b): /* Focusrite Clarett+ 4Pre */
+       case USB_ID(0x1235, 0x820c): /* Focusrite Clarett+ 8Pre */
+-              err = snd_scarlett_gen2_init(mixer);
++              err = snd_scarlett2_init(mixer);
+               break;
+       case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */
+diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett2.c
+similarity index 99%
+rename from sound/usb/mixer_scarlett_gen2.c
+rename to sound/usb/mixer_scarlett2.c
+index e5e70abf5286b..90480b9b9b089 100644
+--- a/sound/usb/mixer_scarlett_gen2.c
++++ b/sound/usb/mixer_scarlett2.c
+@@ -1,6 +1,8 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+- *   Focusrite Scarlett Gen 2/3 and Clarett USB/Clarett+ Driver for ALSA
++ *   Focusrite Scarlett 2 Protocol Driver for ALSA
++ *   (including Scarlett 2nd Gen, 3rd Gen, Clarett USB, and Clarett+
++ *   series products)
+  *
+  *   Supported models:
+  *   - 6i6/18i8/18i20 Gen 2
+@@ -149,7 +151,7 @@
+ #include "mixer.h"
+ #include "helper.h"
+-#include "mixer_scarlett_gen2.h"
++#include "mixer_scarlett2.h"
+ /* device_setup value to allow turning MSD mode back on */
+ #define SCARLETT2_MSD_ENABLE 0x02
+@@ -4251,7 +4253,7 @@ static const struct scarlett2_device_entry *get_scarlett2_device_entry(
+       return entry;
+ }
+-static int snd_scarlett_gen2_controls_create(
++static int snd_scarlett2_controls_create(
+       struct usb_mixer_interface *mixer,
+       const struct scarlett2_device_entry *entry)
+ {
+@@ -4339,7 +4341,7 @@ static int snd_scarlett_gen2_controls_create(
+       return 0;
+ }
+-int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer)
++int snd_scarlett2_init(struct usb_mixer_interface *mixer)
+ {
+       struct snd_usb_audio *chip = mixer->chip;
+       const struct scarlett2_device_entry *entry;
+@@ -4378,7 +4380,7 @@ int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer)
+               entry->series_name,
+               USB_ID_PRODUCT(chip->usb_id));
+-      err = snd_scarlett_gen2_controls_create(mixer, entry);
++      err = snd_scarlett2_controls_create(mixer, entry);
+       if (err < 0)
+               usb_audio_err(mixer->chip,
+                             "Error initialising %s Mixer Driver: %d",
+diff --git a/sound/usb/mixer_scarlett2.h b/sound/usb/mixer_scarlett2.h
+new file mode 100644
+index 0000000000000..d209362cf41a6
+--- /dev/null
++++ b/sound/usb/mixer_scarlett2.h
+@@ -0,0 +1,7 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef __USB_MIXER_SCARLETT2_H
++#define __USB_MIXER_SCARLETT2_H
++
++int snd_scarlett2_init(struct usb_mixer_interface *mixer);
++
++#endif /* __USB_MIXER_SCARLETT2_H */
+diff --git a/sound/usb/mixer_scarlett_gen2.h b/sound/usb/mixer_scarlett_gen2.h
+deleted file mode 100644
+index 668c6b0cb50a6..0000000000000
+--- a/sound/usb/mixer_scarlett_gen2.h
++++ /dev/null
+@@ -1,7 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0 */
+-#ifndef __USB_MIXER_SCARLETT_GEN2_H
+-#define __USB_MIXER_SCARLETT_GEN2_H
+-
+-int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer);
+-
+-#endif /* __USB_MIXER_SCARLETT_GEN2_H */
+-- 
+2.43.0
+
diff --git a/queue-6.6/asoc-ti-convert-pandora-asoc-to-gpio-descriptors.patch b/queue-6.6/asoc-ti-convert-pandora-asoc-to-gpio-descriptors.patch
new file mode 100644 (file)
index 0000000..98a0b32
--- /dev/null
@@ -0,0 +1,185 @@
+From 2d9170f123541e6e41c59b7745442b172d5e6072 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Sep 2023 15:25:32 +0200
+Subject: ASoC: ti: Convert Pandora ASoC to GPIO descriptors
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 319e6ac143b9e9048e527ab9dd2aabb8fdf3d60f ]
+
+The Pandora uses GPIO descriptors pretty much exclusively, but not
+for ASoC, so let's fix it. Register the pins in a descriptor table
+in the machine since the ASoC device is not using device tree.
+
+Use static locals for the GPIO descriptors because I'm not able
+to experient with better state storage on any real hardware. Others
+using the Pandora can come afterwards and improve this.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Acked-by: Jarkko Nikula <jarkko.nikula@bitmer.com>
+Link: https://lore.kernel.org/r/20230926-descriptors-asoc-ti-v1-4-60cf4f8adbc5@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/pdata-quirks.c | 10 +++++
+ sound/soc/ti/omap3pandora.c        | 63 +++++++++++-------------------
+ 2 files changed, 33 insertions(+), 40 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
+index c1c0121f478d6..b947bacf23a37 100644
+--- a/arch/arm/mach-omap2/pdata-quirks.c
++++ b/arch/arm/mach-omap2/pdata-quirks.c
+@@ -275,9 +275,19 @@ static struct platform_device pandora_backlight = {
+       .id     = -1,
+ };
++static struct gpiod_lookup_table pandora_soc_audio_gpios = {
++      .dev_id = "soc-audio",
++      .table = {
++              GPIO_LOOKUP("gpio-112-127", 6, "dac", GPIO_ACTIVE_HIGH),
++              GPIO_LOOKUP("gpio-0-15", 14, "amp", GPIO_ACTIVE_HIGH),
++              { }
++      },
++};
++
+ static void __init omap3_pandora_legacy_init(void)
+ {
+       platform_device_register(&pandora_backlight);
++      gpiod_add_lookup_table(&pandora_soc_audio_gpios);
+ }
+ #endif /* CONFIG_ARCH_OMAP3 */
+diff --git a/sound/soc/ti/omap3pandora.c b/sound/soc/ti/omap3pandora.c
+index a287e9747c2a1..fa92ed97dfe3b 100644
+--- a/sound/soc/ti/omap3pandora.c
++++ b/sound/soc/ti/omap3pandora.c
+@@ -7,7 +7,7 @@
+ #include <linux/clk.h>
+ #include <linux/platform_device.h>
+-#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/delay.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/module.h>
+@@ -21,12 +21,11 @@
+ #include "omap-mcbsp.h"
+-#define OMAP3_PANDORA_DAC_POWER_GPIO  118
+-#define OMAP3_PANDORA_AMP_POWER_GPIO  14
+-
+ #define PREFIX "ASoC omap3pandora: "
+ static struct regulator *omap3pandora_dac_reg;
++static struct gpio_desc *dac_power_gpio;
++static struct gpio_desc *amp_power_gpio;
+ static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+@@ -78,9 +77,9 @@ static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
+                       return ret;
+               }
+               mdelay(1);
+-              gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
++              gpiod_set_value(dac_power_gpio, 1);
+       } else {
+-              gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
++              gpiod_set_value(dac_power_gpio, 0);
+               mdelay(1);
+               regulator_disable(omap3pandora_dac_reg);
+       }
+@@ -92,9 +91,9 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *k, int event)
+ {
+       if (SND_SOC_DAPM_EVENT_ON(event))
+-              gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
++              gpiod_set_value(amp_power_gpio, 1);
+       else
+-              gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
++              gpiod_set_value(amp_power_gpio, 0);
+       return 0;
+ }
+@@ -229,35 +228,10 @@ static int __init omap3pandora_soc_init(void)
+       pr_info("OMAP3 Pandora SoC init\n");
+-      ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power");
+-      if (ret) {
+-              pr_err(PREFIX "Failed to get DAC power GPIO\n");
+-              return ret;
+-      }
+-
+-      ret = gpio_direction_output(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
+-      if (ret) {
+-              pr_err(PREFIX "Failed to set DAC power GPIO direction\n");
+-              goto fail0;
+-      }
+-
+-      ret = gpio_request(OMAP3_PANDORA_AMP_POWER_GPIO, "amp_power");
+-      if (ret) {
+-              pr_err(PREFIX "Failed to get amp power GPIO\n");
+-              goto fail0;
+-      }
+-
+-      ret = gpio_direction_output(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
+-      if (ret) {
+-              pr_err(PREFIX "Failed to set amp power GPIO direction\n");
+-              goto fail1;
+-      }
+-
+       omap3pandora_snd_device = platform_device_alloc("soc-audio", -1);
+       if (omap3pandora_snd_device == NULL) {
+               pr_err(PREFIX "Platform device allocation failed\n");
+-              ret = -ENOMEM;
+-              goto fail1;
++              return -ENOMEM;
+       }
+       platform_set_drvdata(omap3pandora_snd_device, &snd_soc_card_omap3pandora);
+@@ -268,6 +242,20 @@ static int __init omap3pandora_soc_init(void)
+               goto fail2;
+       }
++      dac_power_gpio = devm_gpiod_get(&omap3pandora_snd_device->dev,
++                                      "dac", GPIOD_OUT_LOW);
++      if (IS_ERR(dac_power_gpio)) {
++              ret = PTR_ERR(dac_power_gpio);
++              goto fail3;
++      }
++
++      amp_power_gpio = devm_gpiod_get(&omap3pandora_snd_device->dev,
++                                      "amp", GPIOD_OUT_LOW);
++      if (IS_ERR(amp_power_gpio)) {
++              ret = PTR_ERR(amp_power_gpio);
++              goto fail3;
++      }
++
+       omap3pandora_dac_reg = regulator_get(&omap3pandora_snd_device->dev, "vcc");
+       if (IS_ERR(omap3pandora_dac_reg)) {
+               pr_err(PREFIX "Failed to get DAC regulator from %s: %ld\n",
+@@ -283,10 +271,7 @@ static int __init omap3pandora_soc_init(void)
+       platform_device_del(omap3pandora_snd_device);
+ fail2:
+       platform_device_put(omap3pandora_snd_device);
+-fail1:
+-      gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
+-fail0:
+-      gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
++
+       return ret;
+ }
+ module_init(omap3pandora_soc_init);
+@@ -295,8 +280,6 @@ static void __exit omap3pandora_soc_exit(void)
+ {
+       regulator_put(omap3pandora_dac_reg);
+       platform_device_unregister(omap3pandora_snd_device);
+-      gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
+-      gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
+ }
+ module_exit(omap3pandora_soc_exit);
+-- 
+2.43.0
+
diff --git a/queue-6.6/clk-get-runtime-pm-before-walking-tree-during-disabl.patch b/queue-6.6/clk-get-runtime-pm-before-walking-tree-during-disabl.patch
new file mode 100644 (file)
index 0000000..16b9caf
--- /dev/null
@@ -0,0 +1,344 @@
+From 3412ba3e03e0c72638d059ea48241fa764ca46e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 11:41:58 -0700
+Subject: clk: Get runtime PM before walking tree during disable_unused
+
+From: Stephen Boyd <sboyd@kernel.org>
+
+[ Upstream commit e581cf5d216289ef292d1a4036d53ce90e122469 ]
+
+Doug reported [1] the following hung task:
+
+ INFO: task swapper/0:1 blocked for more than 122 seconds.
+       Not tainted 5.15.149-21875-gf795ebc40eb8 #1
+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+ task:swapper/0       state:D stack:    0 pid:    1 ppid:     0 flags:0x00000008
+ Call trace:
+  __switch_to+0xf4/0x1f4
+  __schedule+0x418/0xb80
+  schedule+0x5c/0x10c
+  rpm_resume+0xe0/0x52c
+  rpm_resume+0x178/0x52c
+  __pm_runtime_resume+0x58/0x98
+  clk_pm_runtime_get+0x30/0xb0
+  clk_disable_unused_subtree+0x58/0x208
+  clk_disable_unused_subtree+0x38/0x208
+  clk_disable_unused_subtree+0x38/0x208
+  clk_disable_unused_subtree+0x38/0x208
+  clk_disable_unused_subtree+0x38/0x208
+  clk_disable_unused+0x4c/0xe4
+  do_one_initcall+0xcc/0x2d8
+  do_initcall_level+0xa4/0x148
+  do_initcalls+0x5c/0x9c
+  do_basic_setup+0x24/0x30
+  kernel_init_freeable+0xec/0x164
+  kernel_init+0x28/0x120
+  ret_from_fork+0x10/0x20
+ INFO: task kworker/u16:0:9 blocked for more than 122 seconds.
+       Not tainted 5.15.149-21875-gf795ebc40eb8 #1
+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+ task:kworker/u16:0   state:D stack:    0 pid:    9 ppid:     2 flags:0x00000008
+ Workqueue: events_unbound deferred_probe_work_func
+ Call trace:
+  __switch_to+0xf4/0x1f4
+  __schedule+0x418/0xb80
+  schedule+0x5c/0x10c
+  schedule_preempt_disabled+0x2c/0x48
+  __mutex_lock+0x238/0x488
+  __mutex_lock_slowpath+0x1c/0x28
+  mutex_lock+0x50/0x74
+  clk_prepare_lock+0x7c/0x9c
+  clk_core_prepare_lock+0x20/0x44
+  clk_prepare+0x24/0x30
+  clk_bulk_prepare+0x40/0xb0
+  mdss_runtime_resume+0x54/0x1c8
+  pm_generic_runtime_resume+0x30/0x44
+  __genpd_runtime_resume+0x68/0x7c
+  genpd_runtime_resume+0x108/0x1f4
+  __rpm_callback+0x84/0x144
+  rpm_callback+0x30/0x88
+  rpm_resume+0x1f4/0x52c
+  rpm_resume+0x178/0x52c
+  __pm_runtime_resume+0x58/0x98
+  __device_attach+0xe0/0x170
+  device_initial_probe+0x1c/0x28
+  bus_probe_device+0x3c/0x9c
+  device_add+0x644/0x814
+  mipi_dsi_device_register_full+0xe4/0x170
+  devm_mipi_dsi_device_register_full+0x28/0x70
+  ti_sn_bridge_probe+0x1dc/0x2c0
+  auxiliary_bus_probe+0x4c/0x94
+  really_probe+0xcc/0x2c8
+  __driver_probe_device+0xa8/0x130
+  driver_probe_device+0x48/0x110
+  __device_attach_driver+0xa4/0xcc
+  bus_for_each_drv+0x8c/0xd8
+  __device_attach+0xf8/0x170
+  device_initial_probe+0x1c/0x28
+  bus_probe_device+0x3c/0x9c
+  deferred_probe_work_func+0x9c/0xd8
+  process_one_work+0x148/0x518
+  worker_thread+0x138/0x350
+  kthread+0x138/0x1e0
+  ret_from_fork+0x10/0x20
+
+The first thread is walking the clk tree and calling
+clk_pm_runtime_get() to power on devices required to read the clk
+hardware via struct clk_ops::is_enabled(). This thread holds the clk
+prepare_lock, and is trying to runtime PM resume a device, when it finds
+that the device is in the process of resuming so the thread schedule()s
+away waiting for the device to finish resuming before continuing. The
+second thread is runtime PM resuming the same device, but the runtime
+resume callback is calling clk_prepare(), trying to grab the
+prepare_lock waiting on the first thread.
+
+This is a classic ABBA deadlock. To properly fix the deadlock, we must
+never runtime PM resume or suspend a device with the clk prepare_lock
+held. Actually doing that is near impossible today because the global
+prepare_lock would have to be dropped in the middle of the tree, the
+device runtime PM resumed/suspended, and then the prepare_lock grabbed
+again to ensure consistency of the clk tree topology. If anything
+changes with the clk tree in the meantime, we've lost and will need to
+start the operation all over again.
+
+Luckily, most of the time we're simply incrementing or decrementing the
+runtime PM count on an active device, so we don't have the chance to
+schedule away with the prepare_lock held. Let's fix this immediate
+problem that can be triggered more easily by simply booting on Qualcomm
+sc7180.
+
+Introduce a list of clk_core structures that have been registered, or
+are in the process of being registered, that require runtime PM to
+operate. Iterate this list and call clk_pm_runtime_get() on each of them
+without holding the prepare_lock during clk_disable_unused(). This way
+we can be certain that the runtime PM state of the devices will be
+active and resumed so we can't schedule away while walking the clk tree
+with the prepare_lock held. Similarly, call clk_pm_runtime_put() without
+the prepare_lock held to properly drop the runtime PM reference. We
+remove the calls to clk_pm_runtime_{get,put}() in this path because
+they're superfluous now that we know the devices are runtime resumed.
+
+Reported-by: Douglas Anderson <dianders@chromium.org>
+Closes: https://lore.kernel.org/all/20220922084322.RFC.2.I375b6b9e0a0a5348962f004beb3dafee6a12dfbb@changeid/ [1]
+Closes: https://issuetracker.google.com/328070191
+Cc: Marek Szyprowski <m.szyprowski@samsung.com>
+Cc: Ulf Hansson <ulf.hansson@linaro.org>
+Cc: Krzysztof Kozlowski <krzk@kernel.org>
+Fixes: 9a34b45397e5 ("clk: Add support for runtime PM")
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Link: https://lore.kernel.org/r/20240325184204.745706-5-sboyd@kernel.org
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 117 +++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 105 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 56b8f540e8abe..7c87a8084df76 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -37,6 +37,10 @@ static HLIST_HEAD(clk_root_list);
+ static HLIST_HEAD(clk_orphan_list);
+ static LIST_HEAD(clk_notifier_list);
++/* List of registered clks that use runtime PM */
++static HLIST_HEAD(clk_rpm_list);
++static DEFINE_MUTEX(clk_rpm_list_lock);
++
+ static const struct hlist_head *all_lists[] = {
+       &clk_root_list,
+       &clk_orphan_list,
+@@ -59,6 +63,7 @@ struct clk_core {
+       struct clk_hw           *hw;
+       struct module           *owner;
+       struct device           *dev;
++      struct hlist_node       rpm_node;
+       struct device_node      *of_node;
+       struct clk_core         *parent;
+       struct clk_parent_map   *parents;
+@@ -122,6 +127,89 @@ static void clk_pm_runtime_put(struct clk_core *core)
+       pm_runtime_put_sync(core->dev);
+ }
++/**
++ * clk_pm_runtime_get_all() - Runtime "get" all clk provider devices
++ *
++ * Call clk_pm_runtime_get() on all runtime PM enabled clks in the clk tree so
++ * that disabling unused clks avoids a deadlock where a device is runtime PM
++ * resuming/suspending and the runtime PM callback is trying to grab the
++ * prepare_lock for something like clk_prepare_enable() while
++ * clk_disable_unused_subtree() holds the prepare_lock and is trying to runtime
++ * PM resume/suspend the device as well.
++ *
++ * Context: Acquires the 'clk_rpm_list_lock' and returns with the lock held on
++ * success. Otherwise the lock is released on failure.
++ *
++ * Return: 0 on success, negative errno otherwise.
++ */
++static int clk_pm_runtime_get_all(void)
++{
++      int ret;
++      struct clk_core *core, *failed;
++
++      /*
++       * Grab the list lock to prevent any new clks from being registered
++       * or unregistered until clk_pm_runtime_put_all().
++       */
++      mutex_lock(&clk_rpm_list_lock);
++
++      /*
++       * Runtime PM "get" all the devices that are needed for the clks
++       * currently registered. Do this without holding the prepare_lock, to
++       * avoid the deadlock.
++       */
++      hlist_for_each_entry(core, &clk_rpm_list, rpm_node) {
++              ret = clk_pm_runtime_get(core);
++              if (ret) {
++                      failed = core;
++                      pr_err("clk: Failed to runtime PM get '%s' for clk '%s'\n",
++                             dev_name(failed->dev), failed->name);
++                      goto err;
++              }
++      }
++
++      return 0;
++
++err:
++      hlist_for_each_entry(core, &clk_rpm_list, rpm_node) {
++              if (core == failed)
++                      break;
++
++              clk_pm_runtime_put(core);
++      }
++      mutex_unlock(&clk_rpm_list_lock);
++
++      return ret;
++}
++
++/**
++ * clk_pm_runtime_put_all() - Runtime "put" all clk provider devices
++ *
++ * Put the runtime PM references taken in clk_pm_runtime_get_all() and release
++ * the 'clk_rpm_list_lock'.
++ */
++static void clk_pm_runtime_put_all(void)
++{
++      struct clk_core *core;
++
++      hlist_for_each_entry(core, &clk_rpm_list, rpm_node)
++              clk_pm_runtime_put(core);
++      mutex_unlock(&clk_rpm_list_lock);
++}
++
++static void clk_pm_runtime_init(struct clk_core *core)
++{
++      struct device *dev = core->dev;
++
++      if (dev && pm_runtime_enabled(dev)) {
++              core->rpm_enabled = true;
++
++              mutex_lock(&clk_rpm_list_lock);
++              hlist_add_head(&core->rpm_node, &clk_rpm_list);
++              mutex_unlock(&clk_rpm_list_lock);
++      }
++}
++
+ /***           locking             ***/
+ static void clk_prepare_lock(void)
+ {
+@@ -1362,9 +1450,6 @@ static void __init clk_unprepare_unused_subtree(struct clk_core *core)
+       if (core->flags & CLK_IGNORE_UNUSED)
+               return;
+-      if (clk_pm_runtime_get(core))
+-              return;
+-
+       if (clk_core_is_prepared(core)) {
+               trace_clk_unprepare(core);
+               if (core->ops->unprepare_unused)
+@@ -1373,8 +1458,6 @@ static void __init clk_unprepare_unused_subtree(struct clk_core *core)
+                       core->ops->unprepare(core->hw);
+               trace_clk_unprepare_complete(core);
+       }
+-
+-      clk_pm_runtime_put(core);
+ }
+ static void __init clk_disable_unused_subtree(struct clk_core *core)
+@@ -1390,9 +1473,6 @@ static void __init clk_disable_unused_subtree(struct clk_core *core)
+       if (core->flags & CLK_OPS_PARENT_ENABLE)
+               clk_core_prepare_enable(core->parent);
+-      if (clk_pm_runtime_get(core))
+-              goto unprepare_out;
+-
+       flags = clk_enable_lock();
+       if (core->enable_count)
+@@ -1417,8 +1497,6 @@ static void __init clk_disable_unused_subtree(struct clk_core *core)
+ unlock_out:
+       clk_enable_unlock(flags);
+-      clk_pm_runtime_put(core);
+-unprepare_out:
+       if (core->flags & CLK_OPS_PARENT_ENABLE)
+               clk_core_disable_unprepare(core->parent);
+ }
+@@ -1434,6 +1512,7 @@ __setup("clk_ignore_unused", clk_ignore_unused_setup);
+ static int __init clk_disable_unused(void)
+ {
+       struct clk_core *core;
++      int ret;
+       if (clk_ignore_unused) {
+               pr_warn("clk: Not disabling unused clocks\n");
+@@ -1442,6 +1521,13 @@ static int __init clk_disable_unused(void)
+       pr_info("clk: Disabling unused clocks\n");
++      ret = clk_pm_runtime_get_all();
++      if (ret)
++              return ret;
++      /*
++       * Grab the prepare lock to keep the clk topology stable while iterating
++       * over clks.
++       */
+       clk_prepare_lock();
+       hlist_for_each_entry(core, &clk_root_list, child_node)
+@@ -1458,6 +1544,8 @@ static int __init clk_disable_unused(void)
+       clk_prepare_unlock();
++      clk_pm_runtime_put_all();
++
+       return 0;
+ }
+ late_initcall_sync(clk_disable_unused);
+@@ -4152,6 +4240,12 @@ static void __clk_release(struct kref *ref)
+ {
+       struct clk_core *core = container_of(ref, struct clk_core, ref);
++      if (core->rpm_enabled) {
++              mutex_lock(&clk_rpm_list_lock);
++              hlist_del(&core->rpm_node);
++              mutex_unlock(&clk_rpm_list_lock);
++      }
++
+       clk_core_free_parent_map(core);
+       kfree_const(core->name);
+       kfree(core);
+@@ -4191,9 +4285,8 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
+       }
+       core->ops = init->ops;
+-      if (dev && pm_runtime_enabled(dev))
+-              core->rpm_enabled = true;
+       core->dev = dev;
++      clk_pm_runtime_init(core);
+       core->of_node = np;
+       if (dev && dev->driver)
+               core->owner = dev->driver->owner;
+-- 
+2.43.0
+
diff --git a/queue-6.6/clk-get-runtime-pm-before-walking-tree-for-clk_summa.patch b/queue-6.6/clk-get-runtime-pm-before-walking-tree-for-clk_summa.patch
new file mode 100644 (file)
index 0000000..681ff73
--- /dev/null
@@ -0,0 +1,95 @@
+From 3d18d8c18eea27073229ed3c512791713a7aac50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 11:41:59 -0700
+Subject: clk: Get runtime PM before walking tree for clk_summary
+
+From: Stephen Boyd <sboyd@kernel.org>
+
+[ Upstream commit 9d1e795f754db1ac3344528b7af0b17b8146f321 ]
+
+Similar to the previous commit, we should make sure that all devices are
+runtime resumed before printing the clk_summary through debugfs. Failure
+to do so would result in a deadlock if the thread is resuming a device
+to print clk state and that device is also runtime resuming in another
+thread, e.g the screen is turning on and the display driver is starting
+up. We remove the calls to clk_pm_runtime_{get,put}() in this path
+because they're superfluous now that we know the devices are runtime
+resumed. This also squashes a bug where the return value of
+clk_pm_runtime_get() wasn't checked, leading to an RPM count underflow
+on error paths.
+
+Fixes: 1bb294a7981c ("clk: Enable/Disable runtime PM for clk_summary")
+Cc: Taniya Das <quic_tdas@quicinc.com>
+Cc: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Link: https://lore.kernel.org/r/20240325184204.745706-6-sboyd@kernel.org
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 011e7632541fa..4a67c0d4823cf 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -3321,9 +3321,7 @@ static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
+ {
+       struct clk_core *child;
+-      clk_pm_runtime_get(c);
+       clk_summary_show_one(s, c, level);
+-      clk_pm_runtime_put(c);
+       hlist_for_each_entry(child, &c->children, child_node)
+               clk_summary_show_subtree(s, child, level + 1);
+@@ -3333,11 +3331,15 @@ static int clk_summary_show(struct seq_file *s, void *data)
+ {
+       struct clk_core *c;
+       struct hlist_head **lists = s->private;
++      int ret;
+       seq_puts(s, "                                 enable  prepare  protect                                duty  hardware                            connection\n");
+       seq_puts(s, "   clock                          count    count    count        rate   accuracy phase  cycle    enable   consumer                         id\n");
+       seq_puts(s, "---------------------------------------------------------------------------------------------------------------------------------------------\n");
++      ret = clk_pm_runtime_get_all();
++      if (ret)
++              return ret;
+       clk_prepare_lock();
+@@ -3346,6 +3348,7 @@ static int clk_summary_show(struct seq_file *s, void *data)
+                       clk_summary_show_subtree(s, c, 0);
+       clk_prepare_unlock();
++      clk_pm_runtime_put_all();
+       return 0;
+ }
+@@ -3393,8 +3396,14 @@ static int clk_dump_show(struct seq_file *s, void *data)
+       struct clk_core *c;
+       bool first_node = true;
+       struct hlist_head **lists = s->private;
++      int ret;
++
++      ret = clk_pm_runtime_get_all();
++      if (ret)
++              return ret;
+       seq_putc(s, '{');
++
+       clk_prepare_lock();
+       for (; *lists; lists++) {
+@@ -3407,6 +3416,7 @@ static int clk_dump_show(struct seq_file *s, void *data)
+       }
+       clk_prepare_unlock();
++      clk_pm_runtime_put_all();
+       seq_puts(s, "}\n");
+       return 0;
+-- 
+2.43.0
+
diff --git a/queue-6.6/clk-initialize-struct-clk_core-kref-earlier.patch b/queue-6.6/clk-initialize-struct-clk_core-kref-earlier.patch
new file mode 100644 (file)
index 0000000..6aeebff
--- /dev/null
@@ -0,0 +1,98 @@
+From add4ef5fecd25e1ead273e1d6b4db31581c090fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 11:41:57 -0700
+Subject: clk: Initialize struct clk_core kref earlier
+
+From: Stephen Boyd <sboyd@kernel.org>
+
+[ Upstream commit 9d05ae531c2cff20d5d527f04e28d28e04379929 ]
+
+Initialize this kref once we allocate memory for the struct clk_core so
+that we can reuse the release function to free any memory associated
+with the structure. This mostly consolidates code, but also clarifies
+that the kref lifetime exists once the container structure (struct
+clk_core) is allocated instead of leaving it in a half-baked state for
+most of __clk_core_init().
+
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Link: https://lore.kernel.org/r/20240325184204.745706-4-sboyd@kernel.org
+Stable-dep-of: e581cf5d2162 ("clk: Get runtime PM before walking tree during disable_unused")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 28 +++++++++++++---------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index ac5be561ccdc9..56b8f540e8abe 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -3919,8 +3919,6 @@ static int __clk_core_init(struct clk_core *core)
+       }
+       clk_core_reparent_orphans_nolock();
+-
+-      kref_init(&core->ref);
+ out:
+       clk_pm_runtime_put(core);
+ unlock:
+@@ -4149,6 +4147,16 @@ static void clk_core_free_parent_map(struct clk_core *core)
+       kfree(core->parents);
+ }
++/* Free memory allocated for a struct clk_core */
++static void __clk_release(struct kref *ref)
++{
++      struct clk_core *core = container_of(ref, struct clk_core, ref);
++
++      clk_core_free_parent_map(core);
++      kfree_const(core->name);
++      kfree(core);
++}
++
+ static struct clk *
+ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
+ {
+@@ -4169,6 +4177,8 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
+               goto fail_out;
+       }
++      kref_init(&core->ref);
++
+       core->name = kstrdup_const(init->name, GFP_KERNEL);
+       if (!core->name) {
+               ret = -ENOMEM;
+@@ -4223,12 +4233,10 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
+       hw->clk = NULL;
+ fail_create_clk:
+-      clk_core_free_parent_map(core);
+ fail_parents:
+ fail_ops:
+-      kfree_const(core->name);
+ fail_name:
+-      kfree(core);
++      kref_put(&core->ref, __clk_release);
+ fail_out:
+       return ERR_PTR(ret);
+ }
+@@ -4308,16 +4316,6 @@ int of_clk_hw_register(struct device_node *node, struct clk_hw *hw)
+ }
+ EXPORT_SYMBOL_GPL(of_clk_hw_register);
+-/* Free memory allocated for a clock. */
+-static void __clk_release(struct kref *ref)
+-{
+-      struct clk_core *core = container_of(ref, struct clk_core, ref);
+-
+-      clk_core_free_parent_map(core);
+-      kfree_const(core->name);
+-      kfree(core);
+-}
+-
+ /*
+  * Empty clk_ops for unregistered clocks. These are used temporarily
+  * after clk_unregister() was called on a clock and until last clock
+-- 
+2.43.0
+
diff --git a/queue-6.6/clk-mediatek-do-a-runtime-pm-get-on-controllers-duri.patch b/queue-6.6/clk-mediatek-do-a-runtime-pm-get-on-controllers-duri.patch
new file mode 100644 (file)
index 0000000..705f3d3
--- /dev/null
@@ -0,0 +1,95 @@
+From 48e47292742c39b19ee238d3b09443d27a88123d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 19:51:55 +0800
+Subject: clk: mediatek: Do a runtime PM get on controllers during probe
+
+From: Pin-yen Lin <treapking@chromium.org>
+
+[ Upstream commit 2f7b1d8b5505efb0057cd1ab85fca206063ea4c3 ]
+
+mt8183-mfgcfg has a mutual dependency with genpd during the probing
+stage, which leads to a deadlock in the following call stack:
+
+CPU0:  genpd_lock --> clk_prepare_lock
+genpd_power_off_work_fn()
+ genpd_lock()
+ generic_pm_domain::power_off()
+    clk_unprepare()
+      clk_prepare_lock()
+
+CPU1: clk_prepare_lock --> genpd_lock
+clk_register()
+  __clk_core_init()
+    clk_prepare_lock()
+    clk_pm_runtime_get()
+      genpd_lock()
+
+Do a runtime PM get at the probe function to make sure clk_register()
+won't acquire the genpd lock. Instead of only modifying mt8183-mfgcfg,
+do this on all mediatek clock controller probings because we don't
+believe this would cause any regression.
+
+Verified on MT8183 and MT8192 Chromebooks.
+
+Fixes: acddfc2c261b ("clk: mediatek: Add MT8183 clock support")
+Signed-off-by: Pin-yen Lin <treapking@chromium.org>
+
+Link: https://lore.kernel.org/r/20240312115249.3341654-1-treapking@chromium.org
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mtk.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
+index 2e55368dc4d82..bd37ab4d1a9bb 100644
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -13,6 +13,7 @@
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
+ #include <linux/slab.h>
+ #include "clk-mtk.h"
+@@ -494,6 +495,16 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
+                       return IS_ERR(base) ? PTR_ERR(base) : -ENOMEM;
+       }
++
++      devm_pm_runtime_enable(&pdev->dev);
++      /*
++       * Do a pm_runtime_resume_and_get() to workaround a possible
++       * deadlock between clk_register() and the genpd framework.
++       */
++      r = pm_runtime_resume_and_get(&pdev->dev);
++      if (r)
++              return r;
++
+       /* Calculate how many clk_hw_onecell_data entries to allocate */
+       num_clks = mcd->num_clks + mcd->num_composite_clks;
+       num_clks += mcd->num_fixed_clks + mcd->num_factor_clks;
+@@ -574,6 +585,8 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
+                       goto unregister_clks;
+       }
++      pm_runtime_put(&pdev->dev);
++
+       return r;
+ unregister_clks:
+@@ -604,6 +617,8 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
+ free_base:
+       if (mcd->shared_io && base)
+               iounmap(base);
++
++      pm_runtime_put(&pdev->dev);
+       return r;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/clk-remove-prepare_lock-hold-assertion-in-__clk_rele.patch b/queue-6.6/clk-remove-prepare_lock-hold-assertion-in-__clk_rele.patch
new file mode 100644 (file)
index 0000000..df227ad
--- /dev/null
@@ -0,0 +1,44 @@
+From 2deb3754e80187eadbd2e3a2604264173d94d784 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 11:41:55 -0700
+Subject: clk: Remove prepare_lock hold assertion in __clk_release()
+
+From: Stephen Boyd <sboyd@kernel.org>
+
+[ Upstream commit 8358a76cfb47c9a5af627a0c4e7168aa14fa25f6 ]
+
+Removing this assertion lets us move the kref_put() call outside the
+prepare_lock section. We don't need to hold the prepare_lock here to
+free memory and destroy the clk_core structure. We've already unlinked
+the clk from the clk tree and by the time the release function runs
+nothing holds a reference to the clk_core anymore so anything with the
+pointer can't access the memory that's being freed anyway. Way back in
+commit 496eadf821c2 ("clk: Use lockdep asserts to find missing hold of
+prepare_lock") we didn't need to have this assertion either.
+
+Fixes: 496eadf821c2 ("clk: Use lockdep asserts to find missing hold of prepare_lock")
+Cc: Krzysztof Kozlowski <krzk@kernel.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Link: https://lore.kernel.org/r/20240325184204.745706-2-sboyd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 50228cb0c5590..ac5be561ccdc9 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -4313,8 +4313,6 @@ static void __clk_release(struct kref *ref)
+ {
+       struct clk_core *core = container_of(ref, struct clk_core, ref);
+-      lockdep_assert_held(&prepare_lock);
+-
+       clk_core_free_parent_map(core);
+       kfree_const(core->name);
+       kfree(core);
+-- 
+2.43.0
+
diff --git a/queue-6.6/clk-show-active-consumers-of-clocks-in-debugfs.patch b/queue-6.6/clk-show-active-consumers-of-clocks-in-debugfs.patch
new file mode 100644 (file)
index 0000000..5808f32
--- /dev/null
@@ -0,0 +1,109 @@
+From f7deca7e1681741a0c477e4408cbda438dc7715d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Nov 2022 22:53:19 +0530
+Subject: clk: Show active consumers of clocks in debugfs
+
+From: Vishal Badole <badolevishal1116@gmail.com>
+
+[ Upstream commit dcce5cc7826e9c6b3a2443e5e6b7f8d02a103c35 ]
+
+This feature lists the clock consumer's name and respective connection
+id. Using this feature user can easily check that which user has
+acquired and enabled a particular clock.
+
+Usage:
+>> cat /sys/kernel/debug/clk/clk_summary
+                      enable  prepare  protect
+                                                                          duty  hardware                            Connection
+   clock               count    count    count    rate   accuracy phase  cycle    enable   consumer                         Id
+------------------------------------------------------------------------------------------------------------------------------
+ clk_mcasp0_fixed         0        0        0    24576000          0      0  50000     Y   deviceless                     of_clk_get_from_provider
+                                                                                           deviceless                     no_connection_id
+    clk_mcasp0            0        0        0    24576000          0      0  50000     N      simple-audio-card,cpu           no_connection_id
+                                                                                              deviceless                      no_connection_id
+
+Co-developed-by: Chinmoy Ghosh <chinmoyghosh2001@gmail.com>
+Signed-off-by: Chinmoy Ghosh <chinmoyghosh2001@gmail.com>
+Co-developed-by: Mintu Patel <mintupatel89@gmail.com>
+Signed-off-by: Mintu Patel <mintupatel89@gmail.com>
+Co-developed-by: Vimal Kumar <vimal.kumar32@gmail.com>
+Signed-off-by: Vimal Kumar <vimal.kumar32@gmail.com>
+Signed-off-by: Vishal Badole <badolevishal1116@gmail.com>
+Link: https://lore.kernel.org/r/1669569799-8526-1-git-send-email-badolevishal1116@gmail.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 9d1e795f754d ("clk: Get runtime PM before walking tree for clk_summary")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 34 ++++++++++++++++++++++++----------
+ 1 file changed, 24 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 7c87a8084df76..011e7632541fa 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -3279,28 +3279,41 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
+                                int level)
+ {
+       int phase;
++      struct clk *clk_user;
++      int multi_node = 0;
+-      seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu ",
++      seq_printf(s, "%*s%-*s %-7d %-8d %-8d %-11lu %-10lu ",
+                  level * 3 + 1, "",
+-                 30 - level * 3, c->name,
++                 35 - level * 3, c->name,
+                  c->enable_count, c->prepare_count, c->protect_count,
+                  clk_core_get_rate_recalc(c),
+                  clk_core_get_accuracy_recalc(c));
+       phase = clk_core_get_phase(c);
+       if (phase >= 0)
+-              seq_printf(s, "%5d", phase);
++              seq_printf(s, "%-5d", phase);
+       else
+               seq_puts(s, "-----");
+-      seq_printf(s, " %6d", clk_core_get_scaled_duty_cycle(c, 100000));
++      seq_printf(s, " %-6d", clk_core_get_scaled_duty_cycle(c, 100000));
+       if (c->ops->is_enabled)
+-              seq_printf(s, " %9c\n", clk_core_is_enabled(c) ? 'Y' : 'N');
++              seq_printf(s, " %5c ", clk_core_is_enabled(c) ? 'Y' : 'N');
+       else if (!c->ops->enable)
+-              seq_printf(s, " %9c\n", 'Y');
++              seq_printf(s, " %5c ", 'Y');
+       else
+-              seq_printf(s, " %9c\n", '?');
++              seq_printf(s, " %5c ", '?');
++
++      hlist_for_each_entry(clk_user, &c->clks, clks_node) {
++              seq_printf(s, "%*s%-*s  %-25s\n",
++                         level * 3 + 2 + 105 * multi_node, "",
++                         30,
++                         clk_user->dev_id ? clk_user->dev_id : "deviceless",
++                         clk_user->con_id ? clk_user->con_id : "no_connection_id");
++
++              multi_node = 1;
++      }
++
+ }
+ static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
+@@ -3321,9 +3334,10 @@ static int clk_summary_show(struct seq_file *s, void *data)
+       struct clk_core *c;
+       struct hlist_head **lists = s->private;
+-      seq_puts(s, "                                 enable  prepare  protect                                duty  hardware\n");
+-      seq_puts(s, "   clock                          count    count    count        rate   accuracy phase  cycle    enable\n");
+-      seq_puts(s, "-------------------------------------------------------------------------------------------------------\n");
++      seq_puts(s, "                                 enable  prepare  protect                                duty  hardware                            connection\n");
++      seq_puts(s, "   clock                          count    count    count        rate   accuracy phase  cycle    enable   consumer                         id\n");
++      seq_puts(s, "---------------------------------------------------------------------------------------------------------------------------------------------\n");
++
+       clk_prepare_lock();
+-- 
+2.43.0
+
diff --git a/queue-6.6/drm-panel-orientation-quirks-add-quirk-for-lenovo-le.patch b/queue-6.6/drm-panel-orientation-quirks-add-quirk-for-lenovo-le.patch
new file mode 100644 (file)
index 0000000..854b239
--- /dev/null
@@ -0,0 +1,43 @@
+From 985e3b77f8754a181adba14ba97ecda7839f468e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Nov 2023 23:38:59 +0000
+Subject: drm: panel-orientation-quirks: Add quirk for Lenovo Legion Go
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Brenton Simpson <appsforartists@google.com>
+
+[ Upstream commit 430143b0d3611f4a9c8434319e5e504244749e79 ]
+
+The Legion Go has a 2560x1600 portrait screen, with the native "up" facing
+the right controller (90° CW from the rest of the device).
+
+Signed-off-by: Brenton Simpson <appsforartists@google.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20231114233859.274189-1-appsforartists@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index 3fe5e6439c401..aa93129c3397e 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -348,6 +348,12 @@ static const struct dmi_system_id orientation_data[] = {
+                 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"),
+               },
+               .driver_data = (void *)&lcd1200x1920_rightside_up,
++      }, {    /* Lenovo Legion Go 8APU1 */
++              .matches = {
++                DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++                DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Legion Go 8APU1"),
++              },
++              .driver_data = (void *)&lcd1600x2560_leftside_up,
+       }, {    /* Lenovo Yoga Book X90F / X90L */
+               .matches = {
+                 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+-- 
+2.43.0
+
diff --git a/queue-6.6/interconnect-don-t-access-req_list-while-it-s-being-.patch b/queue-6.6/interconnect-don-t-access-req_list-while-it-s-being-.patch
new file mode 100644 (file)
index 0000000..0333abe
--- /dev/null
@@ -0,0 +1,106 @@
+From a94dd5aee55f39a2f6df40f401fc583c5a7e27ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 14:56:52 -0800
+Subject: interconnect: Don't access req_list while it's being manipulated
+
+From: Mike Tipton <quic_mdtipton@quicinc.com>
+
+[ Upstream commit de1bf25b6d771abdb52d43546cf57ad775fb68a1 ]
+
+The icc_lock mutex was split into separate icc_lock and icc_bw_lock
+mutexes in [1] to avoid lockdep splats. However, this didn't adequately
+protect access to icc_node::req_list.
+
+The icc_set_bw() function will eventually iterate over req_list while
+only holding icc_bw_lock, but req_list can be modified while only
+holding icc_lock. This causes races between icc_set_bw(), of_icc_get(),
+and icc_put().
+
+Example A:
+
+  CPU0                               CPU1
+  ----                               ----
+  icc_set_bw(path_a)
+    mutex_lock(&icc_bw_lock);
+                                     icc_put(path_b)
+                                       mutex_lock(&icc_lock);
+    aggregate_requests()
+      hlist_for_each_entry(r, ...
+                                       hlist_del(...
+        <r = invalid pointer>
+
+Example B:
+
+  CPU0                               CPU1
+  ----                               ----
+  icc_set_bw(path_a)
+    mutex_lock(&icc_bw_lock);
+                                     path_b = of_icc_get()
+                                       of_icc_get_by_index()
+                                         mutex_lock(&icc_lock);
+                                         path_find()
+                                           path_init()
+    aggregate_requests()
+      hlist_for_each_entry(r, ...
+                                             hlist_add_head(...
+        <r = invalid pointer>
+
+Fix this by ensuring icc_bw_lock is always held before manipulating
+icc_node::req_list. The additional places icc_bw_lock is held don't
+perform any memory allocations, so we should still be safe from the
+original lockdep splats that motivated the separate locks.
+
+[1] commit af42269c3523 ("interconnect: Fix locking for runpm vs reclaim")
+
+Signed-off-by: Mike Tipton <quic_mdtipton@quicinc.com>
+Fixes: af42269c3523 ("interconnect: Fix locking for runpm vs reclaim")
+Reviewed-by: Rob Clark <robdclark@chromium.org>
+Link: https://lore.kernel.org/r/20240305225652.22872-1-quic_mdtipton@quicinc.com
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/interconnect/core.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
+index 50bac2d79d9b5..68edb07d4443e 100644
+--- a/drivers/interconnect/core.c
++++ b/drivers/interconnect/core.c
+@@ -176,6 +176,8 @@ static struct icc_path *path_init(struct device *dev, struct icc_node *dst,
+       path->num_nodes = num_nodes;
++      mutex_lock(&icc_bw_lock);
++
+       for (i = num_nodes - 1; i >= 0; i--) {
+               node->provider->users++;
+               hlist_add_head(&path->reqs[i].req_node, &node->req_list);
+@@ -186,6 +188,8 @@ static struct icc_path *path_init(struct device *dev, struct icc_node *dst,
+               node = node->reverse;
+       }
++      mutex_unlock(&icc_bw_lock);
++
+       return path;
+ }
+@@ -792,12 +796,16 @@ void icc_put(struct icc_path *path)
+               pr_err("%s: error (%d)\n", __func__, ret);
+       mutex_lock(&icc_lock);
++      mutex_lock(&icc_bw_lock);
++
+       for (i = 0; i < path->num_nodes; i++) {
+               node = path->reqs[i].node;
+               hlist_del(&path->reqs[i].req_node);
+               if (!WARN_ON(!node->provider->users))
+                       node->provider->users--;
+       }
++
++      mutex_unlock(&icc_bw_lock);
+       mutex_unlock(&icc_lock);
+       kfree_const(path->name);
+-- 
+2.43.0
+
diff --git a/queue-6.6/pci-add-pci_header_type_mfd-definition.patch b/queue-6.6/pci-add-pci_header_type_mfd-definition.patch
new file mode 100644 (file)
index 0000000..57218d0
--- /dev/null
@@ -0,0 +1,38 @@
+From 364b460e7117f64ad97ab29ba0a81ed0aa71aad2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Oct 2023 15:52:59 +0300
+Subject: PCI: Add PCI_HEADER_TYPE_MFD definition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit bdca03a271f2de2c24ea56756fd9bbcff35173fb ]
+
+Add PCI_HEADER_TYPE_MFD so we can replace literals in the code.
+
+Link: https://lore.kernel.org/r/20231003125300.5541-3-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Stable-dep-of: 83c088148c8e ("PCI: Use PCI_HEADER_TYPE_* instead of literals")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/pci_regs.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
+index e5f558d964939..06df65f11c396 100644
+--- a/include/uapi/linux/pci_regs.h
++++ b/include/uapi/linux/pci_regs.h
+@@ -80,6 +80,7 @@
+ #define  PCI_HEADER_TYPE_NORMAL               0
+ #define  PCI_HEADER_TYPE_BRIDGE               1
+ #define  PCI_HEADER_TYPE_CARDBUS      2
++#define  PCI_HEADER_TYPE_MFD          0x80    /* Multi-Function Device (possible) */
+ #define PCI_BIST              0x0f    /* 8 bits */
+ #define  PCI_BIST_CODE_MASK   0x0f    /* Return result */
+-- 
+2.43.0
+
diff --git a/queue-6.6/pci-dpc-use-field_get.patch b/queue-6.6/pci-dpc-use-field_get.patch
new file mode 100644 (file)
index 0000000..1a1a210
--- /dev/null
@@ -0,0 +1,83 @@
+From c681bf711459e12cc5f0a38c2024452ef5dfee57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Oct 2023 14:32:51 +0300
+Subject: PCI/DPC: Use FIELD_GET()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bjorn Helgaas <bhelgaas@google.com>
+
+[ Upstream commit 9a9eec4765737b9b2a8d6ae03de6480a5f12dd5c ]
+
+Use FIELD_GET() to remove dependencies on the field position, i.e., the
+shift value. No functional change intended.
+
+Link: https://lore.kernel.org/r/20231018113254.17616-5-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/dpc.c        | 5 +++--
+ drivers/pci/quirks.c          | 2 +-
+ include/uapi/linux/pci_regs.h | 1 +
+ 3 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
+index b4818007788f9..a5cec2a4e057d 100644
+--- a/drivers/pci/pcie/dpc.c
++++ b/drivers/pci/pcie/dpc.c
+@@ -9,6 +9,7 @@
+ #define dev_fmt(fmt) "DPC: " fmt
+ #include <linux/aer.h>
++#include <linux/bitfield.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+ #include <linux/init.h>
+@@ -202,7 +203,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
+       /* Get First Error Pointer */
+       pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &dpc_status);
+-      first_error = (dpc_status & 0x1f00) >> 8;
++      first_error = FIELD_GET(PCI_EXP_DPC_RP_PIO_FEP, dpc_status);
+       for (i = 0; i < ARRAY_SIZE(rp_pio_error_string); i++) {
+               if ((status & ~mask) & (1 << i))
+@@ -338,7 +339,7 @@ void pci_dpc_init(struct pci_dev *pdev)
+       /* Quirks may set dpc_rp_log_size if device or firmware is buggy */
+       if (!pdev->dpc_rp_log_size) {
+               pdev->dpc_rp_log_size =
+-                      (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
++                              FIELD_GET(PCI_EXP_DPC_RP_PIO_LOG_SIZE, cap);
+               if (pdev->dpc_rp_log_size < 4 || pdev->dpc_rp_log_size > 9) {
+                       pci_err(pdev, "RP PIO log size %u is invalid\n",
+                               pdev->dpc_rp_log_size);
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 675f77ac1968d..e1c652b1c53a4 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -6198,7 +6198,7 @@ static void dpc_log_size(struct pci_dev *dev)
+       if (!(val & PCI_EXP_DPC_CAP_RP_EXT))
+               return;
+-      if (!((val & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8)) {
++      if (FIELD_GET(PCI_EXP_DPC_RP_PIO_LOG_SIZE, val) == 0) {
+               pci_info(dev, "Overriding RP PIO Log Size to 4\n");
+               dev->dpc_rp_log_size = 4;
+       }
+diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
+index 06df65f11c396..6c31c805ac4bd 100644
+--- a/include/uapi/linux/pci_regs.h
++++ b/include/uapi/linux/pci_regs.h
+@@ -1046,6 +1046,7 @@
+ #define  PCI_EXP_DPC_STATUS_INTERRUPT     0x0008 /* Interrupt Status */
+ #define  PCI_EXP_DPC_RP_BUSY              0x0010 /* Root Port Busy */
+ #define  PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */
++#define  PCI_EXP_DPC_RP_PIO_FEP                   0x1f00 /* RP PIO First Err Ptr */
+ #define PCI_EXP_DPC_SOURCE_ID          0x0A   /* DPC Source Identifier */
+-- 
+2.43.0
+
diff --git a/queue-6.6/pci-simplify-pcie_capability_clear_and_set_word-to-..patch b/queue-6.6/pci-simplify-pcie_capability_clear_and_set_word-to-..patch
new file mode 100644 (file)
index 0000000..4036e9b
--- /dev/null
@@ -0,0 +1,66 @@
+From b79500383c8b70476a81c5898ce40f191503b128 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Oct 2023 15:19:23 +0300
+Subject: PCI: Simplify pcie_capability_clear_and_set_word() to
+ ..._clear_word()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 0fce6e5c87faec2c8bf28d2abc8cb595f4e244b6 ]
+
+When using pcie_capability_clear_and_set_word() but not actually *setting*
+anything, use pcie_capability_clear_word() instead.
+
+Link: https://lore.kernel.org/r/20231026121924.2164-1-ilpo.jarvinen@linux.intel.com
+Link: https://lore.kernel.org/r/20231026121924.2164-2-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+[bhelgaas: squash]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/aspm.c | 8 ++++----
+ drivers/pci/quirks.c    | 6 +++---
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
+index 7e3b342215e5b..19a673aa08eb2 100644
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -689,10 +689,10 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
+        * in pcie_config_aspm_link().
+        */
+       if (enable_req & (ASPM_STATE_L1_1 | ASPM_STATE_L1_2)) {
+-              pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL,
+-                                                 PCI_EXP_LNKCTL_ASPM_L1, 0);
+-              pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL,
+-                                                 PCI_EXP_LNKCTL_ASPM_L1, 0);
++              pcie_capability_clear_word(child, PCI_EXP_LNKCTL,
++                                         PCI_EXP_LNKCTL_ASPM_L1);
++              pcie_capability_clear_word(parent, PCI_EXP_LNKCTL,
++                                         PCI_EXP_LNKCTL_ASPM_L1);
+       }
+       val = 0;
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index e1c652b1c53a4..fa770601c655a 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -4571,9 +4571,9 @@ static void quirk_disable_root_port_attributes(struct pci_dev *pdev)
+       pci_info(root_port, "Disabling No Snoop/Relaxed Ordering Attributes to avoid PCIe Completion erratum in %s\n",
+                dev_name(&pdev->dev));
+-      pcie_capability_clear_and_set_word(root_port, PCI_EXP_DEVCTL,
+-                                         PCI_EXP_DEVCTL_RELAX_EN |
+-                                         PCI_EXP_DEVCTL_NOSNOOP_EN, 0);
++      pcie_capability_clear_word(root_port, PCI_EXP_DEVCTL,
++                                 PCI_EXP_DEVCTL_RELAX_EN |
++                                 PCI_EXP_DEVCTL_NOSNOOP_EN);
+ }
+ /*
+-- 
+2.43.0
+
diff --git a/queue-6.6/pci-use-pci_header_type_-instead-of-literals.patch b/queue-6.6/pci-use-pci_header_type_-instead-of-literals.patch
new file mode 100644 (file)
index 0000000..57d2522
--- /dev/null
@@ -0,0 +1,323 @@
+From 47a6faa3158d5013c24f05c59c3d3b84f273d9dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Oct 2023 15:53:00 +0300
+Subject: PCI: Use PCI_HEADER_TYPE_* instead of literals
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 83c088148c8e5c439eec6c7651692f797547e1a8 ]
+
+Replace literals under drivers/pci/ with PCI_HEADER_TYPE_MASK,
+PCI_HEADER_TYPE_NORMAL, and PCI_HEADER_TYPE_MFD.
+
+Also replace !! boolean conversions with FIELD_GET().
+
+Link: https://lore.kernel.org/r/20231003125300.5541-4-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> # for Renesas R-Car
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-layerscape.c   |  2 +-
+ .../controller/mobiveil/pcie-mobiveil-host.c  |  2 +-
+ drivers/pci/controller/pcie-iproc.c           |  2 +-
+ drivers/pci/controller/pcie-rcar-ep.c         |  2 +-
+ drivers/pci/controller/pcie-rcar-host.c       |  2 +-
+ drivers/pci/controller/vmd.c                  |  2 +-
+ drivers/pci/hotplug/cpqphp_ctrl.c             |  6 ++---
+ drivers/pci/hotplug/cpqphp_pci.c              | 22 +++++++++----------
+ drivers/pci/hotplug/ibmphp.h                  |  5 +++--
+ drivers/pci/hotplug/ibmphp_pci.c              |  2 +-
+ drivers/pci/pci.c                             |  2 +-
+ drivers/pci/quirks.c                          |  6 ++---
+ 12 files changed, 28 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
+index b931d597656f6..37956e09c65bd 100644
+--- a/drivers/pci/controller/dwc/pci-layerscape.c
++++ b/drivers/pci/controller/dwc/pci-layerscape.c
+@@ -58,7 +58,7 @@ static bool ls_pcie_is_bridge(struct ls_pcie *pcie)
+       u32 header_type;
+       header_type = ioread8(pci->dbi_base + PCI_HEADER_TYPE);
+-      header_type &= 0x7f;
++      header_type &= PCI_HEADER_TYPE_MASK;
+       return header_type == PCI_HEADER_TYPE_BRIDGE;
+ }
+diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+index 45b97a4b14dbd..32951f7d6d6d6 100644
+--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
++++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+@@ -539,7 +539,7 @@ static bool mobiveil_pcie_is_bridge(struct mobiveil_pcie *pcie)
+       u32 header_type;
+       header_type = mobiveil_csr_readb(pcie, PCI_HEADER_TYPE);
+-      header_type &= 0x7f;
++      header_type &= PCI_HEADER_TYPE_MASK;
+       return header_type == PCI_HEADER_TYPE_BRIDGE;
+ }
+diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
+index bd1c98b688516..97f739a2c9f8f 100644
+--- a/drivers/pci/controller/pcie-iproc.c
++++ b/drivers/pci/controller/pcie-iproc.c
+@@ -783,7 +783,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie)
+       /* make sure we are not in EP mode */
+       iproc_pci_raw_config_read32(pcie, 0, PCI_HEADER_TYPE, 1, &hdr_type);
+-      if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) {
++      if ((hdr_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE) {
+               dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type);
+               return -EFAULT;
+       }
+diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c
+index f9682df1da619..7034c0ff23d0d 100644
+--- a/drivers/pci/controller/pcie-rcar-ep.c
++++ b/drivers/pci/controller/pcie-rcar-ep.c
+@@ -43,7 +43,7 @@ static void rcar_pcie_ep_hw_init(struct rcar_pcie *pcie)
+       rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
+       rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
+                  PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ENDPOINT << 4);
+-      rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
++      rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), PCI_HEADER_TYPE_MASK,
+                  PCI_HEADER_TYPE_NORMAL);
+       /* Write out the physical slot number = 0 */
+diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
+index 88975e40ee2fb..bf7cc0b6a6957 100644
+--- a/drivers/pci/controller/pcie-rcar-host.c
++++ b/drivers/pci/controller/pcie-rcar-host.c
+@@ -460,7 +460,7 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
+       rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
+       rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
+               PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
+-      rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
++      rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), PCI_HEADER_TYPE_MASK,
+               PCI_HEADER_TYPE_BRIDGE);
+       /* Enable data link layer active state reporting */
+diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
+index 6ac0afae0ca18..2af46e6587aff 100644
+--- a/drivers/pci/controller/vmd.c
++++ b/drivers/pci/controller/vmd.c
+@@ -527,7 +527,7 @@ static void vmd_domain_reset(struct vmd_dev *vmd)
+                       hdr_type = readb(base + PCI_HEADER_TYPE);
+-                      functions = (hdr_type & 0x80) ? 8 : 1;
++                      functions = (hdr_type & PCI_HEADER_TYPE_MFD) ? 8 : 1;
+                       for (fn = 0; fn < functions; fn++) {
+                               base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus,
+                                               PCI_DEVFN(dev, fn), 0);
+diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
+index e429ecddc8feb..c01968ef0bd7b 100644
+--- a/drivers/pci/hotplug/cpqphp_ctrl.c
++++ b/drivers/pci/hotplug/cpqphp_ctrl.c
+@@ -2059,7 +2059,7 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
+                               return rc;
+                       /* If it's a bridge, check the VGA Enable bit */
+-                      if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
++                      if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
+                               rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
+                               if (rc)
+                                       return rc;
+@@ -2342,7 +2342,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
+       if (rc)
+               return rc;
+-      if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
++      if ((temp_byte & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
+               /* set Primary bus */
+               dbg("set Primary bus = %d\n", func->bus);
+               rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
+@@ -2739,7 +2739,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
+                                        *   PCI_BRIDGE_CTL_SERR |
+                                        *   PCI_BRIDGE_CTL_NO_ISA */
+               rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
+-      } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
++      } else if ((temp_byte & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
+               /* Standard device */
+               rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
+diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
+index 3b248426a9f42..e9f1fb333a718 100644
+--- a/drivers/pci/hotplug/cpqphp_pci.c
++++ b/drivers/pci/hotplug/cpqphp_pci.c
+@@ -363,7 +363,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
+                       return rc;
+               /* If multi-function device, set max_functions to 8 */
+-              if (header_type & 0x80)
++              if (header_type & PCI_HEADER_TYPE_MFD)
+                       max_functions = 8;
+               else
+                       max_functions = 1;
+@@ -372,7 +372,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
+               do {
+                       DevError = 0;
+-                      if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
++                      if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
+                               /* Recurse the subordinate bus
+                                * get the subordinate bus number
+                                */
+@@ -487,13 +487,13 @@ int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot)
+       pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
+       pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
+-      if (header_type & 0x80) /* Multi-function device */
++      if (header_type & PCI_HEADER_TYPE_MFD)
+               max_functions = 8;
+       else
+               max_functions = 1;
+       while (function < max_functions) {
+-              if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
++              if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
+                       /*  Recurse the subordinate bus */
+                       pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
+@@ -571,7 +571,7 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func)
+               /* Check for Bridge */
+               pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+-              if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
++              if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
+                       pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
+                       sub_bus = (int) secondary_bus;
+@@ -625,7 +625,7 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func)
+                       }       /* End of base register loop */
+-              } else if ((header_type & 0x7F) == 0x00) {
++              } else if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
+                       /* Figure out IO and memory base lengths */
+                       for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
+                               temp_register = 0xFFFFFFFF;
+@@ -723,7 +723,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func)
+               /* Check for Bridge */
+               pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+-              if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
++              if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
+                       /* Clear Bridge Control Register */
+                       command = 0x00;
+                       pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
+@@ -858,7 +858,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func)
+                               }
+                       }       /* End of base register loop */
+               /* Standard header */
+-              } else if ((header_type & 0x7F) == 0x00) {
++              } else if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
+                       /* Figure out IO and memory base lengths */
+                       for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
+                               pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
+@@ -975,7 +975,7 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func)
+               pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+               /* If this is a bridge device, restore subordinate devices */
+-              if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
++              if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
+                       pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
+                       sub_bus = (int) secondary_bus;
+@@ -1067,7 +1067,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
+               /* Check for Bridge */
+               pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+-              if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
++              if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
+                       /* In order to continue checking, we must program the
+                        * bus registers in the bridge to respond to accesses
+                        * for its subordinate bus(es)
+@@ -1090,7 +1090,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
+               }
+               /* Check to see if it is a standard config header */
+-              else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
++              else if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
+                       /* Check subsystem vendor and ID */
+                       pci_bus_read_config_dword(pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
+diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
+index 41eafe511210f..c248a09be7b5d 100644
+--- a/drivers/pci/hotplug/ibmphp.h
++++ b/drivers/pci/hotplug/ibmphp.h
+@@ -17,6 +17,7 @@
+  */
+ #include <linux/pci_hotplug.h>
++#include <linux/pci_regs.h>
+ extern int ibmphp_debug;
+@@ -286,8 +287,8 @@ int ibmphp_register_pci(void);
+ /* pci specific defines */
+ #define PCI_VENDOR_ID_NOTVALID                0xFFFF
+-#define PCI_HEADER_TYPE_MULTIDEVICE   0x80
+-#define PCI_HEADER_TYPE_MULTIBRIDGE   0x81
++#define PCI_HEADER_TYPE_MULTIDEVICE   (PCI_HEADER_TYPE_MFD|PCI_HEADER_TYPE_NORMAL)
++#define PCI_HEADER_TYPE_MULTIBRIDGE   (PCI_HEADER_TYPE_MFD|PCI_HEADER_TYPE_BRIDGE)
+ #define LATENCY               0x64
+ #define CACHE         64
+diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
+index 50038e5f9ca40..eeb412cbd9fe3 100644
+--- a/drivers/pci/hotplug/ibmphp_pci.c
++++ b/drivers/pci/hotplug/ibmphp_pci.c
+@@ -1087,7 +1087,7 @@ static struct res_needed *scan_behind_bridge(struct pci_func *func, u8 busno)
+                               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
+                               debug("hdr_type behind the bridge is %x\n", hdr_type);
+-                              if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
++                              if ((hdr_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
+                                       err("embedded bridges not supported for hot-plugging.\n");
+                                       amount->not_correct = 1;
+                                       return amount;
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 06fc6f532d6c4..dae9d9e2826f0 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -534,7 +534,7 @@ u8 pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
+       pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+-      pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & 0x7f);
++      pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & PCI_HEADER_TYPE_MASK);
+       if (pos)
+               pos = __pci_find_next_cap(bus, devfn, pos, cap);
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index b3976dcb71f10..675f77ac1968d 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -1849,8 +1849,8 @@ static void quirk_jmicron_ata(struct pci_dev *pdev)
+       /* Update pdev accordingly */
+       pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr);
+-      pdev->hdr_type = hdr & 0x7f;
+-      pdev->multifunction = !!(hdr & 0x80);
++      pdev->hdr_type = hdr & PCI_HEADER_TYPE_MASK;
++      pdev->multifunction = FIELD_GET(PCI_HEADER_TYPE_MFD, hdr);
+       pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class);
+       pdev->class = class >> 8;
+@@ -5710,7 +5710,7 @@ static void quirk_nvidia_hda(struct pci_dev *gpu)
+       /* The GPU becomes a multi-function device when the HDA is enabled */
+       pci_read_config_byte(gpu, PCI_HEADER_TYPE, &hdr_type);
+-      gpu->multifunction = !!(hdr_type & 0x80);
++      gpu->multifunction = FIELD_GET(PCI_HEADER_TYPE_MFD, hdr_type);
+ }
+ DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+                              PCI_BASE_CLASS_DISPLAY, 16, quirk_nvidia_hda);
+-- 
+2.43.0
+
diff --git a/queue-6.6/platform-x86-amd-pmc-extend-framework-13-quirk-to-mo.patch b/queue-6.6/platform-x86-amd-pmc-extend-framework-13-quirk-to-mo.patch
new file mode 100644 (file)
index 0000000..d417636
--- /dev/null
@@ -0,0 +1,51 @@
+From b37ae317311ca84849536995e9eb6239c7341dcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Apr 2024 09:10:46 -0500
+Subject: platform/x86/amd/pmc: Extend Framework 13 quirk to more BIOSes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit f609e7b1b49e4d15cf107d2069673ee63860c398 ]
+
+BIOS 03.05 still hasn't fixed the spurious IRQ1 issue.  As it's still
+being worked on there is still a possibility that it won't need to
+apply to future BIOS releases.
+
+Add a quirk for BIOS 03.05 as well.
+
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20240410141046.433-1-mario.limonciello@amd.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/amd/pmc/pmc-quirks.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c
+index b456370166b6b..b4f49720c87f6 100644
+--- a/drivers/platform/x86/amd/pmc/pmc-quirks.c
++++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c
+@@ -208,6 +208,15 @@ static const struct dmi_system_id fwbug_list[] = {
+                       DMI_MATCH(DMI_BIOS_VERSION, "03.03"),
+               }
+       },
++      {
++              .ident = "Framework Laptop 13 (Phoenix)",
++              .driver_data = &quirk_spurious_8042,
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "Laptop 13 (AMD Ryzen 7040Series)"),
++                      DMI_MATCH(DMI_BIOS_VERSION, "03.05"),
++              }
++      },
+       {}
+ };
+-- 
+2.43.0
+
index 14801d820dee0f014059737e5a40733dfdf02fbe..6f572a6e997ffff3fa143f60f7cac04282aea312 100644 (file)
@@ -66,3 +66,31 @@ s390-cio-fix-race-condition-during-online-processing.patch
 drm-nv04-fix-out-of-bounds-access.patch
 drm-panel-visionox-rm69299-don-t-unregister-dsi-devi.patch
 drm-radeon-make-fstrict-flex-arrays-3-happy.patch
+alsa-scarlett2-move-usb-ids-out-from-device_info-str.patch
+alsa-scarlett2-add-support-for-clarett-8pre-usb.patch
+asoc-ti-convert-pandora-asoc-to-gpio-descriptors.patch
+usb-pci-quirks-group-amd-specific-quirk-code-togethe.patch
+usb-pci-quirks-handle-has_ioport-dependency-for-amd-.patch
+usb-pci-quirks-handle-has_ioport-dependency-for-uhci.patch
+pci-add-pci_header_type_mfd-definition.patch
+pci-use-pci_header_type_-instead-of-literals.patch
+alsa-scarlett2-default-mixer-driver-to-enabled.patch
+alsa-scarlett2-add-correct-product-series-name-to-me.patch
+alsa-scarlett2-add-focusrite-clarett-2pre-and-4pre-s.patch
+alsa-scarlett2-add-focusrite-clarett-2pre-and-4pre-u.patch
+pci-dpc-use-field_get.patch
+pci-simplify-pcie_capability_clear_and_set_word-to-..patch
+alsa-scarlett2-rename-scarlett_gen2-to-scarlett2.patch
+drm-panel-orientation-quirks-add-quirk-for-lenovo-le.patch
+usb-xhci-add-timeout-argument-in-address_device-usb-.patch
+usb-new-quirk-to-reduce-the-set_address-request-time.patch
+platform-x86-amd-pmc-extend-framework-13-quirk-to-mo.patch
+interconnect-don-t-access-req_list-while-it-s-being-.patch
+clk-remove-prepare_lock-hold-assertion-in-__clk_rele.patch
+clk-initialize-struct-clk_core-kref-earlier.patch
+clk-get-runtime-pm-before-walking-tree-during-disabl.patch
+clk-show-active-consumers-of-clocks-in-debugfs.patch
+clk-get-runtime-pm-before-walking-tree-for-clk_summa.patch
+clk-mediatek-do-a-runtime-pm-get-on-controllers-duri.patch
+x86-bugs-fix-bhi-retpoline-check.patch
+x86-cpufeatures-fix-dependencies-for-gfni-vaes-and-v.patch
diff --git a/queue-6.6/usb-new-quirk-to-reduce-the-set_address-request-time.patch b/queue-6.6/usb-new-quirk-to-reduce-the-set_address-request-time.patch
new file mode 100644 (file)
index 0000000..5517c39
--- /dev/null
@@ -0,0 +1,167 @@
+From 62e8bd54dc1548022c2db1bc175fa5c649f10751 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Oct 2023 17:20:29 +0200
+Subject: usb: new quirk to reduce the SET_ADDRESS request timeout
+
+From: Hardik Gajjar <hgajjar@de.adit-jv.com>
+
+[ Upstream commit 5a1ccf0c72cf917ff3ccc131d1bb8d19338ffe52 ]
+
+This patch introduces a new USB quirk,
+USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT, which modifies the timeout value
+for the SET_ADDRESS request. The standard timeout for USB request/command
+is 5000 ms, as recommended in the USB 3.2 specification (section 9.2.6.1).
+
+However, certain scenarios, such as connecting devices through an APTIV
+hub, can lead to timeout errors when the device enumerates as full speed
+initially and later switches to high speed during chirp negotiation.
+
+In such cases, USB analyzer logs reveal that the bus suspends for
+5 seconds due to incorrect chirp parsing and resumes only after two
+consecutive timeout errors trigger a hub driver reset.
+
+Packet(54) Dir(?) Full Speed J(997.100 us) Idle(  2.850 us)
+_______| Time Stamp(28 . 105 910 682)
+_______|_____________________________________________________________Ch0
+Packet(55) Dir(?) Full Speed J(997.118 us) Idle(  2.850 us)
+_______| Time Stamp(28 . 106 910 632)
+_______|_____________________________________________________________Ch0
+Packet(56) Dir(?) Full Speed J(399.650 us) Idle(222.582 us)
+_______| Time Stamp(28 . 107 910 600)
+_______|_____________________________________________________________Ch0
+Packet(57) Dir Chirp J( 23.955 ms) Idle(115.169 ms)
+_______| Time Stamp(28 . 108 532 832)
+_______|_____________________________________________________________Ch0
+Packet(58) Dir(?) Full Speed J (Suspend)( 5.347 sec) Idle(  5.366 us)
+_______| Time Stamp(28 . 247 657 600)
+_______|_____________________________________________________________Ch0
+
+This 5-second delay in device enumeration is undesirable, particularly
+in automotive applications where quick enumeration is crucial
+(ideally within 3 seconds).
+
+The newly introduced quirks provide the flexibility to align with a
+3-second time limit, as required in specific contexts like automotive
+applications.
+
+By reducing the SET_ADDRESS request timeout to 500 ms, the
+system can respond more swiftly to errors, initiate rapid recovery, and
+ensure efficient device enumeration. This change is vital for scenarios
+where rapid smartphone enumeration and screen projection are essential.
+
+To use the quirk, please write "vendor_id:product_id:p" to
+/sys/bus/usb/drivers/hub/module/parameter/quirks
+
+For example,
+echo "0x2c48:0x0132:p" > /sys/bus/usb/drivers/hub/module/parameters/quirks"
+
+Signed-off-by: Hardik Gajjar <hgajjar@de.adit-jv.com>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20231027152029.104363-2-hgajjar@de.adit-jv.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/kernel-parameters.txt |  3 +++
+ drivers/usb/core/hub.c                          | 15 +++++++++++++--
+ drivers/usb/core/quirks.c                       |  7 +++++++
+ include/linux/usb/quirks.h                      |  3 +++
+ 4 files changed, 26 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index 4cd15aee16c20..66dfc348043d6 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -6853,6 +6853,9 @@
+                                       pause after every control message);
+                               o = USB_QUIRK_HUB_SLOW_RESET (Hub needs extra
+                                       delay after resetting its port);
++                              p = USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT
++                                      (Reduce timeout of the SET_ADDRESS
++                                      request from 5000 ms to 500 ms);
+                       Example: quirks=0781:5580:bk,0a5c:5834:gij
+       usbhid.mousepoll=
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 73ab30e0da774..7417972202b8b 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -60,6 +60,12 @@
+ #define USB_PING_RESPONSE_TIME                400     /* ns */
+ #define USB_REDUCE_FRAME_INTR_BINTERVAL       9
++/*
++ * The SET_ADDRESS request timeout will be 500 ms when
++ * USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT quirk flag is set.
++ */
++#define USB_SHORT_SET_ADDRESS_REQ_TIMEOUT     500  /* ms */
++
+ /* Protect struct usb_device->state and ->children members
+  * Note: Both are also protected by ->dev.sem, except that ->state can
+  * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
+@@ -4663,7 +4669,12 @@ EXPORT_SYMBOL_GPL(usb_ep0_reinit);
+ static int hub_set_address(struct usb_device *udev, int devnum)
+ {
+       int retval;
++      unsigned int timeout_ms = USB_CTRL_SET_TIMEOUT;
+       struct usb_hcd *hcd = bus_to_hcd(udev->bus);
++      struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
++
++      if (hub->hdev->quirks & USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT)
++              timeout_ms = USB_SHORT_SET_ADDRESS_REQ_TIMEOUT;
+       /*
+        * The host controller will choose the device address,
+@@ -4676,11 +4687,11 @@ static int hub_set_address(struct usb_device *udev, int devnum)
+       if (udev->state != USB_STATE_DEFAULT)
+               return -EINVAL;
+       if (hcd->driver->address_device)
+-              retval = hcd->driver->address_device(hcd, udev, USB_CTRL_SET_TIMEOUT);
++              retval = hcd->driver->address_device(hcd, udev, timeout_ms);
+       else
+               retval = usb_control_msg(udev, usb_sndaddr0pipe(),
+                               USB_REQ_SET_ADDRESS, 0, devnum, 0,
+-                              NULL, 0, USB_CTRL_SET_TIMEOUT);
++                              NULL, 0, timeout_ms);
+       if (retval == 0) {
+               update_devnum(udev, devnum);
+               /* Device now using proper address. */
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index 15e9bd180a1d2..b4783574b8e66 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -138,6 +138,9 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp)
+                       case 'o':
+                               flags |= USB_QUIRK_HUB_SLOW_RESET;
+                               break;
++                      case 'p':
++                              flags |= USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT;
++                              break;
+                       /* Ignore unrecognized flag characters */
+                       }
+               }
+@@ -527,6 +530,10 @@ static const struct usb_device_id usb_quirk_list[] = {
+       { USB_DEVICE(0x2386, 0x350e), .driver_info = USB_QUIRK_NO_LPM },
++      /* APTIV AUTOMOTIVE HUB */
++      { USB_DEVICE(0x2c48, 0x0132), .driver_info =
++                      USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT },
++
+       /* DJI CineSSD */
+       { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
+diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
+index eeb7c2157c72f..59409c1fc3dee 100644
+--- a/include/linux/usb/quirks.h
++++ b/include/linux/usb/quirks.h
+@@ -72,4 +72,7 @@
+ /* device has endpoints that should be ignored */
+ #define USB_QUIRK_ENDPOINT_IGNORE             BIT(15)
++/* short SET_ADDRESS request timeout */
++#define USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT       BIT(16)
++
+ #endif /* __LINUX_USB_QUIRKS_H */
+-- 
+2.43.0
+
diff --git a/queue-6.6/usb-pci-quirks-group-amd-specific-quirk-code-togethe.patch b/queue-6.6/usb-pci-quirks-group-amd-specific-quirk-code-togethe.patch
new file mode 100644 (file)
index 0000000..9a98345
--- /dev/null
@@ -0,0 +1,225 @@
+From 952f4e84ead9ecf5b11d30bdc72d08c391ef630f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Sep 2023 14:56:51 +0200
+Subject: usb: pci-quirks: group AMD specific quirk code together
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit 7ca9f9ba8aa7380dee5dd8346b57bbaf198b075a ]
+
+A follow on patch will introduce CONFIG_USB_PCI_AMD governing the AMD
+quirk and adding its compile time dependency on HAS_IOPORT. In order to
+minimize the number of #ifdefs in C files and make that patch easier
+to read first group the code together. This is pure code movement
+no functional change is intended.
+
+Co-developed-by: Arnd Bergmann <arnd@kernel.org>
+Signed-off-by: Arnd Bergmann <arnd@kernel.org>
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230911125653.1393895-2-schnelle@linux.ibm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/pci-quirks.c | 119 +++++++++++++++++-----------------
+ drivers/usb/host/pci-quirks.h |  14 ++--
+ 2 files changed, 68 insertions(+), 65 deletions(-)
+
+diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
+index 2665832f9addf..5e06fad82a228 100644
+--- a/drivers/usb/host/pci-quirks.c
++++ b/drivers/usb/host/pci-quirks.c
+@@ -60,6 +60,22 @@
+ #define EHCI_USBLEGCTLSTS     4               /* legacy control/status */
+ #define EHCI_USBLEGCTLSTS_SOOE        (1 << 13)       /* SMI on ownership change */
++/* ASMEDIA quirk use */
++#define ASMT_DATA_WRITE0_REG  0xF8
++#define ASMT_DATA_WRITE1_REG  0xFC
++#define ASMT_CONTROL_REG      0xE0
++#define ASMT_CONTROL_WRITE_BIT        0x02
++#define ASMT_WRITEREG_CMD     0x10423
++#define ASMT_FLOWCTL_ADDR     0xFA30
++#define ASMT_FLOWCTL_DATA     0xBA
++#define ASMT_PSEUDO_DATA      0
++
++/* Intel quirk use */
++#define USB_INTEL_XUSB2PR      0xD0
++#define USB_INTEL_USB2PRM      0xD4
++#define USB_INTEL_USB3_PSSEN   0xD8
++#define USB_INTEL_USB3PRM      0xDC
++
+ /* AMD quirk use */
+ #define       AB_REG_BAR_LOW          0xe0
+ #define       AB_REG_BAR_HIGH         0xe1
+@@ -93,21 +109,6 @@
+ #define       NB_PIF0_PWRDOWN_0       0x01100012
+ #define       NB_PIF0_PWRDOWN_1       0x01100013
+-#define USB_INTEL_XUSB2PR      0xD0
+-#define USB_INTEL_USB2PRM      0xD4
+-#define USB_INTEL_USB3_PSSEN   0xD8
+-#define USB_INTEL_USB3PRM      0xDC
+-
+-/* ASMEDIA quirk use */
+-#define ASMT_DATA_WRITE0_REG  0xF8
+-#define ASMT_DATA_WRITE1_REG  0xFC
+-#define ASMT_CONTROL_REG      0xE0
+-#define ASMT_CONTROL_WRITE_BIT        0x02
+-#define ASMT_WRITEREG_CMD     0x10423
+-#define ASMT_FLOWCTL_ADDR     0xFA30
+-#define ASMT_FLOWCTL_DATA     0xBA
+-#define ASMT_PSEUDO_DATA      0
+-
+ /*
+  * amd_chipset_gen values represent AMD different chipset generations
+  */
+@@ -458,50 +459,6 @@ void usb_amd_quirk_pll_disable(void)
+ }
+ EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable);
+-static int usb_asmedia_wait_write(struct pci_dev *pdev)
+-{
+-      unsigned long retry_count;
+-      unsigned char value;
+-
+-      for (retry_count = 1000; retry_count > 0; --retry_count) {
+-
+-              pci_read_config_byte(pdev, ASMT_CONTROL_REG, &value);
+-
+-              if (value == 0xff) {
+-                      dev_err(&pdev->dev, "%s: check_ready ERROR", __func__);
+-                      return -EIO;
+-              }
+-
+-              if ((value & ASMT_CONTROL_WRITE_BIT) == 0)
+-                      return 0;
+-
+-              udelay(50);
+-      }
+-
+-      dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__);
+-      return -ETIMEDOUT;
+-}
+-
+-void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev)
+-{
+-      if (usb_asmedia_wait_write(pdev) != 0)
+-              return;
+-
+-      /* send command and address to device */
+-      pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_WRITEREG_CMD);
+-      pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_FLOWCTL_ADDR);
+-      pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
+-
+-      if (usb_asmedia_wait_write(pdev) != 0)
+-              return;
+-
+-      /* send data to device */
+-      pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_FLOWCTL_DATA);
+-      pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_PSEUDO_DATA);
+-      pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
+-}
+-EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol);
+-
+ void usb_amd_quirk_pll_enable(void)
+ {
+       usb_amd_quirk_pll(0);
+@@ -631,6 +588,50 @@ bool usb_amd_pt_check_port(struct device *device, int port)
+ }
+ EXPORT_SYMBOL_GPL(usb_amd_pt_check_port);
++static int usb_asmedia_wait_write(struct pci_dev *pdev)
++{
++      unsigned long retry_count;
++      unsigned char value;
++
++      for (retry_count = 1000; retry_count > 0; --retry_count) {
++
++              pci_read_config_byte(pdev, ASMT_CONTROL_REG, &value);
++
++              if (value == 0xff) {
++                      dev_err(&pdev->dev, "%s: check_ready ERROR", __func__);
++                      return -EIO;
++              }
++
++              if ((value & ASMT_CONTROL_WRITE_BIT) == 0)
++                      return 0;
++
++              udelay(50);
++      }
++
++      dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__);
++      return -ETIMEDOUT;
++}
++
++void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev)
++{
++      if (usb_asmedia_wait_write(pdev) != 0)
++              return;
++
++      /* send command and address to device */
++      pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_WRITEREG_CMD);
++      pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_FLOWCTL_ADDR);
++      pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
++
++      if (usb_asmedia_wait_write(pdev) != 0)
++              return;
++
++      /* send data to device */
++      pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_FLOWCTL_DATA);
++      pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_PSEUDO_DATA);
++      pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
++}
++EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol);
++
+ /*
+  * Make sure the controller is completely inactive, unable to
+  * generate interrupts or do DMA.
+diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h
+index e729de21fad7a..cde2263a9d2e4 100644
+--- a/drivers/usb/host/pci-quirks.h
++++ b/drivers/usb/host/pci-quirks.h
+@@ -3,8 +3,6 @@
+ #define __LINUX_USB_PCI_QUIRKS_H
+ #ifdef CONFIG_USB_PCI
+-void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
+-int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
+ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev);
+ bool usb_amd_hang_symptom_quirk(void);
+ bool usb_amd_prefetch_quirk(void);
+@@ -12,23 +10,27 @@ void usb_amd_dev_put(void);
+ bool usb_amd_quirk_pll_check(void);
+ void usb_amd_quirk_pll_disable(void);
+ void usb_amd_quirk_pll_enable(void);
++void sb800_prefetch(struct device *dev, int on);
++bool usb_amd_pt_check_port(struct device *device, int port);
++
++void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
++int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
+ void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev);
+ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
+ void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
+-void sb800_prefetch(struct device *dev, int on);
+-bool usb_amd_pt_check_port(struct device *device, int port);
+ #else
+ struct pci_dev;
+ static inline void usb_amd_quirk_pll_disable(void) {}
+ static inline void usb_amd_quirk_pll_enable(void) {}
+-static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
+ static inline void usb_amd_dev_put(void) {}
+-static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
+ static inline void sb800_prefetch(struct device *dev, int on) {}
+ static inline bool usb_amd_pt_check_port(struct device *device, int port)
+ {
+       return false;
+ }
++
++static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
++static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
+ #endif  /* CONFIG_USB_PCI */
+ #endif  /*  __LINUX_USB_PCI_QUIRKS_H  */
+-- 
+2.43.0
+
diff --git a/queue-6.6/usb-pci-quirks-handle-has_ioport-dependency-for-amd-.patch b/queue-6.6/usb-pci-quirks-handle-has_ioport-dependency-for-amd-.patch
new file mode 100644 (file)
index 0000000..18a7e1a
--- /dev/null
@@ -0,0 +1,174 @@
+From 0f70138cda5d225e8d81ea1d734d20e6b11e7478 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Sep 2023 14:56:52 +0200
+Subject: usb: pci-quirks: handle HAS_IOPORT dependency for AMD quirk
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit 52e24f8c0a102ac76649c6b71224fadcc82bd5da ]
+
+In a future patch HAS_IOPORT=n will result in inb()/outb() and friends
+not being declared. In the pci-quirks case the I/O port acceses are
+used in the quirks for several AMD south bridges, Add a config option
+for the AMD quirks to depend on HAS_IOPORT and #ifdef the quirk code.
+
+Co-developed-by: Arnd Bergmann <arnd@kernel.org>
+Signed-off-by: Arnd Bergmann <arnd@kernel.org>
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230911125653.1393895-3-schnelle@linux.ibm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/Kconfig           | 10 ++++++++++
+ drivers/usb/core/hcd-pci.c    |  3 +--
+ drivers/usb/host/pci-quirks.c |  2 ++
+ drivers/usb/host/pci-quirks.h | 30 ++++++++++++++++++++++--------
+ include/linux/usb/hcd.h       | 17 +++++++++++++++++
+ 5 files changed, 52 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
+index 7f33bcc315f27..abf8c6cdea9ea 100644
+--- a/drivers/usb/Kconfig
++++ b/drivers/usb/Kconfig
+@@ -91,6 +91,16 @@ config USB_PCI
+         If you have such a device you may say N here and PCI related code
+         will not be built in the USB driver.
++config USB_PCI_AMD
++      bool "AMD PCI USB host support"
++      depends on USB_PCI && HAS_IOPORT
++      default X86 || MACH_LOONGSON64 || PPC_PASEMI
++      help
++        Enable workarounds for USB implementation quirks in SB600/SB700/SB800
++        and later south bridge implementations. These are common on x86 PCs
++        with AMD CPUs but rarely used elsewhere, with the exception of a few
++        powerpc and mips desktop machines.
++
+ if USB
+ source "drivers/usb/core/Kconfig"
+diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
+index 990280688b254..ee3156f495338 100644
+--- a/drivers/usb/core/hcd-pci.c
++++ b/drivers/usb/core/hcd-pci.c
+@@ -206,8 +206,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct hc_driver *driver)
+               goto free_irq_vectors;
+       }
+-      hcd->amd_resume_bug = (usb_hcd_amd_remote_wakeup_quirk(dev) &&
+-                      driver->flags & (HCD_USB11 | HCD_USB3)) ? 1 : 0;
++      hcd->amd_resume_bug = usb_hcd_amd_resume_bug(dev, driver);
+       if (driver->flags & HCD_MEMORY) {
+               /* EHCI, OHCI */
+diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
+index 5e06fad82a228..10813096d00c6 100644
+--- a/drivers/usb/host/pci-quirks.c
++++ b/drivers/usb/host/pci-quirks.c
+@@ -76,6 +76,7 @@
+ #define USB_INTEL_USB3_PSSEN   0xD8
+ #define USB_INTEL_USB3PRM      0xDC
++#ifdef CONFIG_USB_PCI_AMD
+ /* AMD quirk use */
+ #define       AB_REG_BAR_LOW          0xe0
+ #define       AB_REG_BAR_HIGH         0xe1
+@@ -587,6 +588,7 @@ bool usb_amd_pt_check_port(struct device *device, int port)
+       return !(value & BIT(port_shift));
+ }
+ EXPORT_SYMBOL_GPL(usb_amd_pt_check_port);
++#endif /* CONFIG_USB_PCI_AMD */
+ static int usb_asmedia_wait_write(struct pci_dev *pdev)
+ {
+diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h
+index cde2263a9d2e4..a5230b0b9e913 100644
+--- a/drivers/usb/host/pci-quirks.h
++++ b/drivers/usb/host/pci-quirks.h
+@@ -2,7 +2,7 @@
+ #ifndef __LINUX_USB_PCI_QUIRKS_H
+ #define __LINUX_USB_PCI_QUIRKS_H
+-#ifdef CONFIG_USB_PCI
++#ifdef CONFIG_USB_PCI_AMD
+ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev);
+ bool usb_amd_hang_symptom_quirk(void);
+ bool usb_amd_prefetch_quirk(void);
+@@ -12,23 +12,37 @@ void usb_amd_quirk_pll_disable(void);
+ void usb_amd_quirk_pll_enable(void);
+ void sb800_prefetch(struct device *dev, int on);
+ bool usb_amd_pt_check_port(struct device *device, int port);
+-
+-void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
+-int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
+-void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev);
+-void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
+-void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
+ #else
+-struct pci_dev;
++static inline bool usb_amd_hang_symptom_quirk(void)
++{
++      return false;
++};
++static inline bool usb_amd_prefetch_quirk(void)
++{
++      return false;
++}
+ static inline void usb_amd_quirk_pll_disable(void) {}
+ static inline void usb_amd_quirk_pll_enable(void) {}
+ static inline void usb_amd_dev_put(void) {}
++static inline bool usb_amd_quirk_pll_check(void)
++{
++      return false;
++}
+ static inline void sb800_prefetch(struct device *dev, int on) {}
+ static inline bool usb_amd_pt_check_port(struct device *device, int port)
+ {
+       return false;
+ }
++#endif /* CONFIG_USB_PCI_AMD */
++#ifdef CONFIG_USB_PCI
++void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
++int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
++void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev);
++void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
++void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
++#else
++struct pci_dev;
+ static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
+ static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
+ #endif  /* CONFIG_USB_PCI */
+diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
+index 61d4f0b793dcd..00724b4f6e122 100644
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -484,8 +484,25 @@ extern int usb_hcd_pci_probe(struct pci_dev *dev,
+ extern void usb_hcd_pci_remove(struct pci_dev *dev);
+ extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
++#ifdef CONFIG_USB_PCI_AMD
+ extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev);
++static inline bool usb_hcd_amd_resume_bug(struct pci_dev *dev,
++                                        const struct hc_driver *driver)
++{
++      if (!usb_hcd_amd_remote_wakeup_quirk(dev))
++              return false;
++      if (driver->flags & (HCD_USB11 | HCD_USB3))
++              return true;
++      return false;
++}
++#else /* CONFIG_USB_PCI_AMD */
++static inline bool usb_hcd_amd_resume_bug(struct pci_dev *dev,
++                                        const struct hc_driver *driver)
++{
++      return false;
++}
++#endif
+ extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
+ #endif /* CONFIG_USB_PCI */
+-- 
+2.43.0
+
diff --git a/queue-6.6/usb-pci-quirks-handle-has_ioport-dependency-for-uhci.patch b/queue-6.6/usb-pci-quirks-handle-has_ioport-dependency-for-uhci.patch
new file mode 100644 (file)
index 0000000..93d134e
--- /dev/null
@@ -0,0 +1,78 @@
+From 62308e4a79ca6840e7c164e05a067e5a9f87d504 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Sep 2023 14:56:53 +0200
+Subject: usb: pci-quirks: handle HAS_IOPORT dependency for UHCI handoff
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit 358ad297e379ff548247e3e24c6619559942bfdd ]
+
+In a future patch HAS_IOPORT=n will result in inb()/outb() and friends
+not being declared. With the AMD quirk handled USB PCI quirks still use
+inw() in uhci_check_and_reset_hc() and thus indirectly in
+quirk_usb_handoff_uhci(). Handle this by conditionally compiling
+uhci_check_and_reset_hc() and stubbing out quirk_usb_handoff_uhci() when
+HAS_IOPORT is not available.
+
+Co-developed-by: Arnd Bergmann <arnd@kernel.org>
+Signed-off-by: Arnd Bergmann <arnd@kernel.org>
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230911125653.1393895-4-schnelle@linux.ibm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/pci-quirks.c | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
+index 10813096d00c6..1f9c1b1435d86 100644
+--- a/drivers/usb/host/pci-quirks.c
++++ b/drivers/usb/host/pci-quirks.c
+@@ -634,6 +634,16 @@ void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev)
+ }
+ EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol);
++static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
++{
++      u16 cmd;
++
++      return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
++}
++
++#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
++
++#if defined(CONFIG_HAS_IOPORT) && IS_ENABLED(CONFIG_USB_UHCI_HCD)
+ /*
+  * Make sure the controller is completely inactive, unable to
+  * generate interrupts or do DMA.
+@@ -715,14 +725,7 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
+ }
+ EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
+-static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
+-{
+-      u16 cmd;
+-      return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
+-}
+-
+ #define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
+-#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
+ static void quirk_usb_handoff_uhci(struct pci_dev *pdev)
+ {
+@@ -742,6 +745,12 @@ static void quirk_usb_handoff_uhci(struct pci_dev *pdev)
+               uhci_check_and_reset_hc(pdev, base);
+ }
++#else /* defined(CONFIG_HAS_IOPORT && IS_ENABLED(CONFIG_USB_UHCI_HCD) */
++
++static void quirk_usb_handoff_uhci(struct pci_dev *pdev) {}
++
++#endif /* defined(CONFIG_HAS_IOPORT && IS_ENABLED(CONFIG_USB_UHCI_HCD) */
++
+ static int mmio_resource_enabled(struct pci_dev *pdev, int idx)
+ {
+       return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
+-- 
+2.43.0
+
diff --git a/queue-6.6/usb-xhci-add-timeout-argument-in-address_device-usb-.patch b/queue-6.6/usb-xhci-add-timeout-argument-in-address_device-usb-.patch
new file mode 100644 (file)
index 0000000..15ae2ff
--- /dev/null
@@ -0,0 +1,206 @@
+From 747b080e78dddb4c56c6991d74381a2f5a98a484 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Oct 2023 17:20:28 +0200
+Subject: usb: xhci: Add timeout argument in address_device USB HCD callback
+
+From: Hardik Gajjar <hgajjar@de.adit-jv.com>
+
+[ Upstream commit a769154c7cac037914ba375ae88aae55b2c853e0 ]
+
+- The HCD address_device callback now accepts a user-defined timeout value
+  in milliseconds, providing better control over command execution times.
+- The default timeout value for the address_device command has been set
+  to 5000 ms, aligning with the USB 3.2 specification. However, this
+  timeout can be adjusted as needed.
+- The xhci_setup_device function has been updated to accept the timeout
+  value, allowing it to specify the maximum wait time for the command
+  operation to complete.
+- The hub driver has also been updated to accommodate the newly added
+  timeout parameter during the SET_ADDRESS request.
+
+Signed-off-by: Hardik Gajjar <hgajjar@de.adit-jv.com>
+Reviewed-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20231027152029.104363-1-hgajjar@de.adit-jv.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 5a1ccf0c72cf ("usb: new quirk to reduce the SET_ADDRESS request timeout")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/core/hub.c       |  2 +-
+ drivers/usb/host/xhci-mem.c  |  2 ++
+ drivers/usb/host/xhci-ring.c | 11 ++++++-----
+ drivers/usb/host/xhci.c      | 23 ++++++++++++++++-------
+ drivers/usb/host/xhci.h      |  9 +++++++--
+ include/linux/usb/hcd.h      |  5 +++--
+ 6 files changed, 35 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 9a3da5d7fe1bc..73ab30e0da774 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -4676,7 +4676,7 @@ static int hub_set_address(struct usb_device *udev, int devnum)
+       if (udev->state != USB_STATE_DEFAULT)
+               return -EINVAL;
+       if (hcd->driver->address_device)
+-              retval = hcd->driver->address_device(hcd, udev);
++              retval = hcd->driver->address_device(hcd, udev, USB_CTRL_SET_TIMEOUT);
+       else
+               retval = usb_control_msg(udev, usb_sndaddr0pipe(),
+                               USB_REQ_SET_ADDRESS, 0, devnum, 0,
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 0a37f0d511cf5..b1e3fa54c6397 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1729,6 +1729,8 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,
+       }
+       command->status = 0;
++      /* set default timeout to 5000 ms */
++      command->timeout_ms = XHCI_CMD_DEFAULT_TIMEOUT;
+       INIT_LIST_HEAD(&command->cmd_list);
+       return command;
+ }
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 3ec1a2617ed7e..c959d9144baa5 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -372,9 +372,10 @@ void xhci_ring_cmd_db(struct xhci_hcd *xhci)
+       readl(&xhci->dba->doorbell[0]);
+ }
+-static bool xhci_mod_cmd_timer(struct xhci_hcd *xhci, unsigned long delay)
++static bool xhci_mod_cmd_timer(struct xhci_hcd *xhci)
+ {
+-      return mod_delayed_work(system_wq, &xhci->cmd_timer, delay);
++      return mod_delayed_work(system_wq, &xhci->cmd_timer,
++                      msecs_to_jiffies(xhci->current_cmd->timeout_ms));
+ }
+ static struct xhci_command *xhci_next_queued_cmd(struct xhci_hcd *xhci)
+@@ -418,7 +419,7 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
+       if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) &&
+           !(xhci->xhc_state & XHCI_STATE_DYING)) {
+               xhci->current_cmd = cur_cmd;
+-              xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
++              xhci_mod_cmd_timer(xhci);
+               xhci_ring_cmd_db(xhci);
+       }
+ }
+@@ -1792,7 +1793,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
+       if (!list_is_singular(&xhci->cmd_list)) {
+               xhci->current_cmd = list_first_entry(&cmd->cmd_list,
+                                               struct xhci_command, cmd_list);
+-              xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
++              xhci_mod_cmd_timer(xhci);
+       } else if (xhci->current_cmd == cmd) {
+               xhci->current_cmd = NULL;
+       }
+@@ -4359,7 +4360,7 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd,
+       /* if there are no other commands queued we start the timeout timer */
+       if (list_empty(&xhci->cmd_list)) {
+               xhci->current_cmd = cmd;
+-              xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
++              xhci_mod_cmd_timer(xhci);
+       }
+       list_add_tail(&cmd->cmd_list, &xhci->cmd_list);
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index c4c733d724bd8..573b5784d1c3d 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4007,12 +4007,18 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
+       return 0;
+ }
+-/*
+- * Issue an Address Device command and optionally send a corresponding
+- * SetAddress request to the device.
++/**
++ * xhci_setup_device - issues an Address Device command to assign a unique
++ *                    USB bus address.
++ * @hcd: USB host controller data structure.
++ * @udev: USB dev structure representing the connected device.
++ * @setup: Enum specifying setup mode: address only or with context.
++ * @timeout_ms: Max wait time (ms) for the command operation to complete.
++ *
++ * Return: 0 if successful; otherwise, negative error code.
+  */
+ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
+-                           enum xhci_setup_dev setup)
++                           enum xhci_setup_dev setup, unsigned int timeout_ms)
+ {
+       const char *act = setup == SETUP_CONTEXT_ONLY ? "context" : "address";
+       unsigned long flags;
+@@ -4069,6 +4075,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
+       }
+       command->in_ctx = virt_dev->in_ctx;
++      command->timeout_ms = timeout_ms;
+       slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+       ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx);
+@@ -4195,14 +4202,16 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
+       return ret;
+ }
+-static int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
++static int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev,
++                             unsigned int timeout_ms)
+ {
+-      return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ADDRESS);
++      return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ADDRESS, timeout_ms);
+ }
+ static int xhci_enable_device(struct usb_hcd *hcd, struct usb_device *udev)
+ {
+-      return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ONLY);
++      return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ONLY,
++                               XHCI_CMD_DEFAULT_TIMEOUT);
+ }
+ /*
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 31088602c0708..be480d6ac8586 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -818,6 +818,8 @@ struct xhci_command {
+       struct completion               *completion;
+       union xhci_trb                  *command_trb;
+       struct list_head                cmd_list;
++      /* xHCI command response timeout in milliseconds */
++      unsigned int                    timeout_ms;
+ };
+ /* drop context bitmasks */
+@@ -1577,8 +1579,11 @@ struct xhci_td {
+       unsigned int            num_trbs;
+ };
+-/* xHCI command default timeout value */
+-#define XHCI_CMD_DEFAULT_TIMEOUT      (5 * HZ)
++/*
++ * xHCI command default timeout value in milliseconds.
++ * USB 3.2 spec, section 9.2.6.1
++ */
++#define XHCI_CMD_DEFAULT_TIMEOUT      5000
+ /* command descriptor */
+ struct xhci_cd {
+diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
+index 00724b4f6e122..cd77fc6095a15 100644
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -372,8 +372,9 @@ struct hc_driver {
+                * or bandwidth constraints.
+                */
+       void    (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
+-              /* Returns the hardware-chosen device address */
+-      int     (*address_device)(struct usb_hcd *, struct usb_device *udev);
++              /* Set the hardware-chosen device address */
++      int     (*address_device)(struct usb_hcd *, struct usb_device *udev,
++                                unsigned int timeout_ms);
+               /* prepares the hardware to send commands to the device */
+       int     (*enable_device)(struct usb_hcd *, struct usb_device *udev);
+               /* Notifies the HCD after a hub descriptor is fetched.
+-- 
+2.43.0
+
diff --git a/queue-6.6/x86-bugs-fix-bhi-retpoline-check.patch b/queue-6.6/x86-bugs-fix-bhi-retpoline-check.patch
new file mode 100644 (file)
index 0000000..3673209
--- /dev/null
@@ -0,0 +1,63 @@
+From 6913394ca254cc05bbe3f6c08fbe8be5902d6366 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Apr 2024 11:10:33 -0700
+Subject: x86/bugs: Fix BHI retpoline check
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 69129794d94c544810e68b2b4eaa7e44063f9bf2 ]
+
+Confusingly, X86_FEATURE_RETPOLINE doesn't mean retpolines are enabled,
+as it also includes the original "AMD retpoline" which isn't a retpoline
+at all.
+
+Also replace cpu_feature_enabled() with boot_cpu_has() because this is
+before alternatives are patched and cpu_feature_enabled()'s fallback
+path is slower than plain old boot_cpu_has().
+
+Fixes: ec9404e40e8f ("x86/bhi: Add BHI mitigation knob")
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/ad3807424a3953f0323c011a643405619f2a4927.1712944776.git.jpoimboe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/bugs.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 5ff69b1d39b20..c2dc9b7426acb 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -1651,7 +1651,8 @@ static void __init bhi_select_mitigation(void)
+               return;
+       /* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */
+-      if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) {
++      if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
++          !boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) {
+               spec_ctrl_disable_kernel_rrsba();
+               if (rrsba_disabled)
+                       return;
+@@ -2803,11 +2804,13 @@ static const char *spectre_bhi_state(void)
+ {
+       if (!boot_cpu_has_bug(X86_BUG_BHI))
+               return "; BHI: Not affected";
+-      else if  (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW))
++      else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW))
+               return "; BHI: BHI_DIS_S";
+-      else if  (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP))
++      else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP))
+               return "; BHI: SW loop, KVM: SW loop";
+-      else if (boot_cpu_has(X86_FEATURE_RETPOLINE) && rrsba_disabled)
++      else if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
++               !boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE) &&
++               rrsba_disabled)
+               return "; BHI: Retpoline";
+       else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT))
+               return "; BHI: Vulnerable, KVM: SW loop";
+-- 
+2.43.0
+
diff --git a/queue-6.6/x86-cpufeatures-fix-dependencies-for-gfni-vaes-and-v.patch b/queue-6.6/x86-cpufeatures-fix-dependencies-for-gfni-vaes-and-v.patch
new file mode 100644 (file)
index 0000000..6c64f40
--- /dev/null
@@ -0,0 +1,59 @@
+From b868532f95c97854462e0bd2b3681f65c184d17d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Apr 2024 23:04:34 -0700
+Subject: x86/cpufeatures: Fix dependencies for GFNI, VAES, and VPCLMULQDQ
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 9543f6e26634537997b6e909c20911b7bf4876de ]
+
+Fix cpuid_deps[] to list the correct dependencies for GFNI, VAES, and
+VPCLMULQDQ.  These features don't depend on AVX512, and there exist CPUs
+that support these features but not AVX512.  GFNI actually doesn't even
+depend on AVX.
+
+This prevents GFNI from being unnecessarily disabled if AVX is disabled
+to mitigate the GDS vulnerability.
+
+This also prevents all three features from being unnecessarily disabled
+if AVX512VL (or its dependency AVX512F) were to be disabled, but it
+looks like there isn't any case where this happens anyway.
+
+Fixes: c128dbfa0f87 ("x86/cpufeatures: Enable new SSE/AVX/AVX512 CPU features")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
+Link: https://lore.kernel.org/r/20240417060434.47101-1-ebiggers@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/cpuid-deps.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c
+index e462c1d3800a6..6fb6d8a57ceca 100644
+--- a/arch/x86/kernel/cpu/cpuid-deps.c
++++ b/arch/x86/kernel/cpu/cpuid-deps.c
+@@ -44,7 +44,10 @@ static const struct cpuid_dep cpuid_deps[] = {
+       { X86_FEATURE_F16C,                     X86_FEATURE_XMM2,     },
+       { X86_FEATURE_AES,                      X86_FEATURE_XMM2      },
+       { X86_FEATURE_SHA_NI,                   X86_FEATURE_XMM2      },
++      { X86_FEATURE_GFNI,                     X86_FEATURE_XMM2      },
+       { X86_FEATURE_FMA,                      X86_FEATURE_AVX       },
++      { X86_FEATURE_VAES,                     X86_FEATURE_AVX       },
++      { X86_FEATURE_VPCLMULQDQ,               X86_FEATURE_AVX       },
+       { X86_FEATURE_AVX2,                     X86_FEATURE_AVX,      },
+       { X86_FEATURE_AVX512F,                  X86_FEATURE_AVX,      },
+       { X86_FEATURE_AVX512IFMA,               X86_FEATURE_AVX512F   },
+@@ -56,9 +59,6 @@ static const struct cpuid_dep cpuid_deps[] = {
+       { X86_FEATURE_AVX512VL,                 X86_FEATURE_AVX512F   },
+       { X86_FEATURE_AVX512VBMI,               X86_FEATURE_AVX512F   },
+       { X86_FEATURE_AVX512_VBMI2,             X86_FEATURE_AVX512VL  },
+-      { X86_FEATURE_GFNI,                     X86_FEATURE_AVX512VL  },
+-      { X86_FEATURE_VAES,                     X86_FEATURE_AVX512VL  },
+-      { X86_FEATURE_VPCLMULQDQ,               X86_FEATURE_AVX512VL  },
+       { X86_FEATURE_AVX512_VNNI,              X86_FEATURE_AVX512VL  },
+       { X86_FEATURE_AVX512_BITALG,            X86_FEATURE_AVX512VL  },
+       { X86_FEATURE_AVX512_4VNNIW,            X86_FEATURE_AVX512F   },
+-- 
+2.43.0
+