]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.16-stable patches master
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 Aug 2025 16:02:04 +0000 (18:02 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 Aug 2025 16:02:04 +0000 (18:02 +0200)
added patches:
cdx-fix-off-by-one-error-in-cdx_rpmsg_probe.patch
comedi-fix-use-of-uninitialized-memory-in-do_insn_ioctl-and-do_insnlist_ioctl.patch
comedi-make-insn_rw_emulate_bits-do-insn-n-samples.patch
comedi-pcl726-prevent-invalid-irq-number.patch
ftrace-also-allocate-and-copy-hash-for-reading-of-filter-files.patch
iio-adc-ad7124-fix-channel-lookup-in-syscalib-functions.patch
iio-adc-ad7173-prevent-scan-if-too-many-setups-requested.patch
iio-adc-bd79124-add-gpiolib-dependency.patch
iio-adc-rzg2l-cleanup-suspend-resume-path.patch
iio-adc-rzg2l_adc-set-driver-data-before-enabling-runtime-pm.patch
iio-light-as73211-ensure-buffer-holes-are-zeroed.patch
iio-pressure-bmp280-use-is_err-in-bmp280_common_probe.patch
iio-proximity-isl29501-fix-buffered-read-on-big-endian-systems.patch
iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch
kcov-usb-don-t-disable-interrupts-in-kcov_remote_start_usb_softirq.patch
most-core-drop-device-reference-after-usage-in-get_channel.patch
usb-core-hcd-fix-accessing-unmapped-memory-in-single_step_set_feature-test.patch
usb-dwc3-ignore-late-xfernotready-event-to-prevent-halt-timeout.patch
usb-dwc3-pci-add-support-for-the-intel-wildcat-lake.patch
usb-dwc3-remove-warn_on-for-device-endpoint-command-timeouts.patch
usb-quirks-add-delay_init-quick-for-another-sandisk-3.2gen1-flash-drive.patch
usb-renesas-xhci-fix-external-rom-access-timeouts.patch
usb-storage-add-unusual-devs-entry-for-novatek-ntk96550-based-camera.patch
usb-storage-ignore-driver-cd-mode-for-realtek-multi-mode-wi-fi-dongles.patch
usb-storage-realtek_cr-use-correct-byte-order-for-bcs-residue.patch
usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch
usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch
usb-xhci-fix-host-not-responding-after-suspend-and-resume.patch
usb-xhci-fix-slot_id-resource-race-conflict.patch

30 files changed:
queue-6.16/cdx-fix-off-by-one-error-in-cdx_rpmsg_probe.patch [new file with mode: 0644]
queue-6.16/comedi-fix-use-of-uninitialized-memory-in-do_insn_ioctl-and-do_insnlist_ioctl.patch [new file with mode: 0644]
queue-6.16/comedi-make-insn_rw_emulate_bits-do-insn-n-samples.patch [new file with mode: 0644]
queue-6.16/comedi-pcl726-prevent-invalid-irq-number.patch [new file with mode: 0644]
queue-6.16/ftrace-also-allocate-and-copy-hash-for-reading-of-filter-files.patch [new file with mode: 0644]
queue-6.16/iio-adc-ad7124-fix-channel-lookup-in-syscalib-functions.patch [new file with mode: 0644]
queue-6.16/iio-adc-ad7173-prevent-scan-if-too-many-setups-requested.patch [new file with mode: 0644]
queue-6.16/iio-adc-bd79124-add-gpiolib-dependency.patch [new file with mode: 0644]
queue-6.16/iio-adc-rzg2l-cleanup-suspend-resume-path.patch [new file with mode: 0644]
queue-6.16/iio-adc-rzg2l_adc-set-driver-data-before-enabling-runtime-pm.patch [new file with mode: 0644]
queue-6.16/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch [new file with mode: 0644]
queue-6.16/iio-pressure-bmp280-use-is_err-in-bmp280_common_probe.patch [new file with mode: 0644]
queue-6.16/iio-proximity-isl29501-fix-buffered-read-on-big-endian-systems.patch [new file with mode: 0644]
queue-6.16/iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch [new file with mode: 0644]
queue-6.16/kcov-usb-don-t-disable-interrupts-in-kcov_remote_start_usb_softirq.patch [new file with mode: 0644]
queue-6.16/most-core-drop-device-reference-after-usage-in-get_channel.patch [new file with mode: 0644]
queue-6.16/series
queue-6.16/usb-core-hcd-fix-accessing-unmapped-memory-in-single_step_set_feature-test.patch [new file with mode: 0644]
queue-6.16/usb-dwc3-ignore-late-xfernotready-event-to-prevent-halt-timeout.patch [new file with mode: 0644]
queue-6.16/usb-dwc3-pci-add-support-for-the-intel-wildcat-lake.patch [new file with mode: 0644]
queue-6.16/usb-dwc3-remove-warn_on-for-device-endpoint-command-timeouts.patch [new file with mode: 0644]
queue-6.16/usb-quirks-add-delay_init-quick-for-another-sandisk-3.2gen1-flash-drive.patch [new file with mode: 0644]
queue-6.16/usb-renesas-xhci-fix-external-rom-access-timeouts.patch [new file with mode: 0644]
queue-6.16/usb-storage-add-unusual-devs-entry-for-novatek-ntk96550-based-camera.patch [new file with mode: 0644]
queue-6.16/usb-storage-ignore-driver-cd-mode-for-realtek-multi-mode-wi-fi-dongles.patch [new file with mode: 0644]
queue-6.16/usb-storage-realtek_cr-use-correct-byte-order-for-bcs-residue.patch [new file with mode: 0644]
queue-6.16/usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch [new file with mode: 0644]
queue-6.16/usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch [new file with mode: 0644]
queue-6.16/usb-xhci-fix-host-not-responding-after-suspend-and-resume.patch [new file with mode: 0644]
queue-6.16/usb-xhci-fix-slot_id-resource-race-conflict.patch [new file with mode: 0644]

diff --git a/queue-6.16/cdx-fix-off-by-one-error-in-cdx_rpmsg_probe.patch b/queue-6.16/cdx-fix-off-by-one-error-in-cdx_rpmsg_probe.patch
new file mode 100644 (file)
index 0000000..08e76e0
--- /dev/null
@@ -0,0 +1,38 @@
+From 300a0cfe9f375b2843bcb331bcfa7503475ef5dd Mon Sep 17 00:00:00 2001
+From: Thorsten Blum <thorsten.blum@linux.dev>
+Date: Wed, 6 Aug 2025 11:05:09 +0200
+Subject: cdx: Fix off-by-one error in cdx_rpmsg_probe()
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+commit 300a0cfe9f375b2843bcb331bcfa7503475ef5dd upstream.
+
+In cdx_rpmsg_probe(), strscpy() is incorrectly called with the length of
+the source string (excluding the NUL terminator) rather than the size of
+the destination buffer. This results in one character less being copied
+from 'cdx_rpmsg_id_table[0].name' to 'chinfo.name'.
+
+Use the destination buffer size instead to ensure the name is copied
+correctly.
+
+Cc: stable <stable@kernel.org>
+Fixes: 2a226927d9b8 ("cdx: add rpmsg communication channel for CDX")
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Link: https://lore.kernel.org/r/20250806090512.121260-2-thorsten.blum@linux.dev
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cdx/controller/cdx_rpmsg.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/cdx/controller/cdx_rpmsg.c
++++ b/drivers/cdx/controller/cdx_rpmsg.c
+@@ -129,8 +129,7 @@ static int cdx_rpmsg_probe(struct rpmsg_
+       chinfo.src = RPMSG_ADDR_ANY;
+       chinfo.dst = rpdev->dst;
+-      strscpy(chinfo.name, cdx_rpmsg_id_table[0].name,
+-              strlen(cdx_rpmsg_id_table[0].name));
++      strscpy(chinfo.name, cdx_rpmsg_id_table[0].name, sizeof(chinfo.name));
+       cdx_mcdi->ept = rpmsg_create_ept(rpdev, cdx_rpmsg_cb, NULL, chinfo);
+       if (!cdx_mcdi->ept) {
diff --git a/queue-6.16/comedi-fix-use-of-uninitialized-memory-in-do_insn_ioctl-and-do_insnlist_ioctl.patch b/queue-6.16/comedi-fix-use-of-uninitialized-memory-in-do_insn_ioctl-and-do_insnlist_ioctl.patch
new file mode 100644 (file)
index 0000000..57fb30c
--- /dev/null
@@ -0,0 +1,72 @@
+From 3cd212e895ca2d58963fdc6422502b10dd3966bb Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Fri, 25 Jul 2025 13:53:24 +0100
+Subject: comedi: Fix use of uninitialized memory in do_insn_ioctl() and do_insnlist_ioctl()
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit 3cd212e895ca2d58963fdc6422502b10dd3966bb upstream.
+
+syzbot reports a KMSAN kernel-infoleak in `do_insn_ioctl()`.  A kernel
+buffer is allocated to hold `insn->n` samples (each of which is an
+`unsigned int`).  For some instruction types, `insn->n` samples are
+copied back to user-space, unless an error code is being returned.  The
+problem is that not all the instruction handlers that need to return
+data to userspace fill in the whole `insn->n` samples, so that there is
+an information leak.  There is a similar syzbot report for
+`do_insnlist_ioctl()`, although it does not have a reproducer for it at
+the time of writing.
+
+One culprit is `insn_rw_emulate_bits()` which is used as the handler for
+`INSN_READ` or `INSN_WRITE` instructions for subdevices that do not have
+a specific handler for that instruction, but do have an `INSN_BITS`
+handler.  For `INSN_READ` it only fills in at most 1 sample, so if
+`insn->n` is greater than 1, the remaining `insn->n - 1` samples copied
+to userspace will be uninitialized kernel data.
+
+Another culprit is `vm80xx_ai_insn_read()` in the "vm80xx" driver.  It
+never returns an error, even if it fails to fill the buffer.
+
+Fix it in `do_insn_ioctl()` and `do_insnlist_ioctl()` by making sure
+that uninitialized parts of the allocated buffer are zeroed before
+handling each instruction.
+
+Thanks to Arnaud Lecomte for their fix to `do_insn_ioctl()`.  That fix
+replaced the call to `kmalloc_array()` with `kcalloc()`, but it is not
+always necessary to clear the whole buffer.
+
+Fixes: ed9eccbe8970 ("Staging: add comedi core")
+Reported-by: syzbot+a5e45f768aab5892da5d@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=a5e45f768aab5892da5d
+Reported-by: syzbot+fb4362a104d45ab09cf9@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=fb4362a104d45ab09cf9
+Cc: stable <stable@kernel.org> # 5.13+
+Cc: Arnaud Lecomte <contact@arnaud-lcm.com>
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Link: https://lore.kernel.org/r/20250725125324.80276-1-abbotti@mev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/comedi/comedi_fops.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/comedi/comedi_fops.c
++++ b/drivers/comedi/comedi_fops.c
+@@ -1587,6 +1587,9 @@ static int do_insnlist_ioctl(struct come
+                               memset(&data[n], 0, (MIN_SAMPLES - n) *
+                                                   sizeof(unsigned int));
+                       }
++              } else {
++                      memset(data, 0, max_t(unsigned int, n, MIN_SAMPLES) *
++                                      sizeof(unsigned int));
+               }
+               ret = parse_insn(dev, insns + i, data, file);
+               if (ret < 0)
+@@ -1670,6 +1673,8 @@ static int do_insn_ioctl(struct comedi_d
+                       memset(&data[insn->n], 0,
+                              (MIN_SAMPLES - insn->n) * sizeof(unsigned int));
+               }
++      } else {
++              memset(data, 0, n_data * sizeof(unsigned int));
+       }
+       ret = parse_insn(dev, insn, data, file);
+       if (ret < 0)
diff --git a/queue-6.16/comedi-make-insn_rw_emulate_bits-do-insn-n-samples.patch b/queue-6.16/comedi-make-insn_rw_emulate_bits-do-insn-n-samples.patch
new file mode 100644 (file)
index 0000000..d3a37bb
--- /dev/null
@@ -0,0 +1,82 @@
+From 7afba9221f70d4cbce0f417c558879cba0eb5e66 Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Fri, 25 Jul 2025 15:10:34 +0100
+Subject: comedi: Make insn_rw_emulate_bits() do insn->n samples
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit 7afba9221f70d4cbce0f417c558879cba0eb5e66 upstream.
+
+The `insn_rw_emulate_bits()` function is used as a default handler for
+`INSN_READ` instructions for subdevices that have a handler for
+`INSN_BITS` but not for `INSN_READ`.  Similarly, it is used as a default
+handler for `INSN_WRITE` instructions for subdevices that have a handler
+for `INSN_BITS` but not for `INSN_WRITE`. It works by emulating the
+`INSN_READ` or `INSN_WRITE` instruction handling with a constructed
+`INSN_BITS` instruction.  However, `INSN_READ` and `INSN_WRITE`
+instructions are supposed to be able read or write multiple samples,
+indicated by the `insn->n` value, but `insn_rw_emulate_bits()` currently
+only handles a single sample.  For `INSN_READ`, the comedi core will
+copy `insn->n` samples back to user-space.  (That triggered KASAN
+kernel-infoleak errors when `insn->n` was greater than 1, but that is
+being fixed more generally elsewhere in the comedi core.)
+
+Make `insn_rw_emulate_bits()` either handle `insn->n` samples, or return
+an error, to conform to the general expectation for `INSN_READ` and
+`INSN_WRITE` handlers.
+
+Fixes: ed9eccbe8970 ("Staging: add comedi core")
+Cc: stable <stable@kernel.org> # 5.13+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Link: https://lore.kernel.org/r/20250725141034.87297-1-abbotti@mev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/comedi/drivers.c |   25 +++++++++++++------------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+--- a/drivers/comedi/drivers.c
++++ b/drivers/comedi/drivers.c
+@@ -620,11 +620,9 @@ static int insn_rw_emulate_bits(struct c
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int base_chan = (chan < 32) ? 0 : chan;
+       unsigned int _data[2];
++      unsigned int i;
+       int ret;
+-      if (insn->n == 0)
+-              return 0;
+-
+       memset(_data, 0, sizeof(_data));
+       memset(&_insn, 0, sizeof(_insn));
+       _insn.insn = INSN_BITS;
+@@ -635,18 +633,21 @@ static int insn_rw_emulate_bits(struct c
+       if (insn->insn == INSN_WRITE) {
+               if (!(s->subdev_flags & SDF_WRITABLE))
+                       return -EINVAL;
+-              _data[0] = 1U << (chan - base_chan);                 /* mask */
+-              _data[1] = data[0] ? (1U << (chan - base_chan)) : 0; /* bits */
++              _data[0] = 1U << (chan - base_chan);            /* mask */
+       }
++      for (i = 0; i < insn->n; i++) {
++              if (insn->insn == INSN_WRITE)
++                      _data[1] = data[i] ? _data[0] : 0;      /* bits */
++
++              ret = s->insn_bits(dev, s, &_insn, _data);
++              if (ret < 0)
++                      return ret;
+-      ret = s->insn_bits(dev, s, &_insn, _data);
+-      if (ret < 0)
+-              return ret;
+-
+-      if (insn->insn == INSN_READ)
+-              data[0] = (_data[1] >> (chan - base_chan)) & 1;
++              if (insn->insn == INSN_READ)
++                      data[i] = (_data[1] >> (chan - base_chan)) & 1;
++      }
+-      return 1;
++      return insn->n;
+ }
+ static int __comedi_device_postconfig_async(struct comedi_device *dev,
diff --git a/queue-6.16/comedi-pcl726-prevent-invalid-irq-number.patch b/queue-6.16/comedi-pcl726-prevent-invalid-irq-number.patch
new file mode 100644 (file)
index 0000000..f307ab6
--- /dev/null
@@ -0,0 +1,50 @@
+From 96cb948408b3adb69df7e451ba7da9d21f814d00 Mon Sep 17 00:00:00 2001
+From: Edward Adam Davis <eadavis@qq.com>
+Date: Mon, 7 Jul 2025 20:39:58 +0800
+Subject: comedi: pcl726: Prevent invalid irq number
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+commit 96cb948408b3adb69df7e451ba7da9d21f814d00 upstream.
+
+The reproducer passed in an irq number(0x80008000) that was too large,
+which triggered the oob.
+
+Added an interrupt number check to prevent users from passing in an irq
+number that was too large.
+
+If `it->options[1]` is 31, then `1 << it->options[1]` is still invalid
+because it shifts a 1-bit into the sign bit (which is UB in C).
+Possible solutions include reducing the upper bound on the
+`it->options[1]` value to 30 or lower, or using `1U << it->options[1]`.
+
+The old code would just not attempt to request the IRQ if the
+`options[1]` value were invalid.  And it would still configure the
+device without interrupts even if the call to `request_irq` returned an
+error.  So it would be better to combine this test with the test below.
+
+Fixes: fff46207245c ("staging: comedi: pcl726: enable the interrupt support code")
+Cc: stable <stable@kernel.org> # 5.13+
+Reported-by: syzbot+5cd373521edd68bebcb3@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=5cd373521edd68bebcb3
+Tested-by: syzbot+5cd373521edd68bebcb3@syzkaller.appspotmail.com
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
+Link: https://lore.kernel.org/r/tencent_3C66983CC1369E962436264A50759176BF09@qq.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/comedi/drivers/pcl726.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/comedi/drivers/pcl726.c
++++ b/drivers/comedi/drivers/pcl726.c
+@@ -328,7 +328,8 @@ static int pcl726_attach(struct comedi_d
+        * Hook up the external trigger source interrupt only if the
+        * user config option is valid and the board supports interrupts.
+        */
+-      if (it->options[1] && (board->irq_mask & (1 << it->options[1]))) {
++      if (it->options[1] > 0 && it->options[1] < 16 &&
++          (board->irq_mask & (1U << it->options[1]))) {
+               ret = request_irq(it->options[1], pcl726_interrupt, 0,
+                                 dev->board_name, dev);
+               if (ret == 0) {
diff --git a/queue-6.16/ftrace-also-allocate-and-copy-hash-for-reading-of-filter-files.patch b/queue-6.16/ftrace-also-allocate-and-copy-hash-for-reading-of-filter-files.patch
new file mode 100644 (file)
index 0000000..fcfc940
--- /dev/null
@@ -0,0 +1,75 @@
+From bfb336cf97df7b37b2b2edec0f69773e06d11955 Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Fri, 22 Aug 2025 18:36:06 -0400
+Subject: ftrace: Also allocate and copy hash for reading of filter files
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+commit bfb336cf97df7b37b2b2edec0f69773e06d11955 upstream.
+
+Currently the reader of set_ftrace_filter and set_ftrace_notrace just adds
+the pointer to the global tracer hash to its iterator. Unlike the writer
+that allocates a copy of the hash, the reader keeps the pointer to the
+filter hashes. This is problematic because this pointer is static across
+function calls that release the locks that can update the global tracer
+hashes. This can cause UAF and similar bugs.
+
+Allocate and copy the hash for reading the filter files like it is done
+for the writers. This not only fixes UAF bugs, but also makes the code a
+bit simpler as it doesn't have to differentiate when to free the
+iterator's hash between writers and readers.
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/20250822183606.12962cc3@batman.local.home
+Fixes: c20489dad156 ("ftrace: Assign iter->hash to filter or notrace hashes on seq read")
+Closes: https://lore.kernel.org/all/20250813023044.2121943-1-wutengda@huaweicloud.com/
+Closes: https://lore.kernel.org/all/20250822192437.GA458494@ax162/
+Reported-by: Tengda Wu <wutengda@huaweicloud.com>
+Tested-by: Tengda Wu <wutengda@huaweicloud.com>
+Tested-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/ftrace.c |   19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -4665,13 +4665,17 @@ ftrace_regex_open(struct ftrace_ops *ops
+               } else {
+                       iter->hash = alloc_and_copy_ftrace_hash(size_bits, hash);
+               }
++      } else {
++              if (hash)
++                      iter->hash = alloc_and_copy_ftrace_hash(hash->size_bits, hash);
++              else
++                      iter->hash = EMPTY_HASH;
++      }
+-              if (!iter->hash) {
+-                      trace_parser_put(&iter->parser);
+-                      goto out_unlock;
+-              }
+-      } else
+-              iter->hash = hash;
++      if (!iter->hash) {
++              trace_parser_put(&iter->parser);
++              goto out_unlock;
++      }
+       ret = 0;
+@@ -6547,9 +6551,6 @@ int ftrace_regex_release(struct inode *i
+               ftrace_hash_move_and_update_ops(iter->ops, orig_hash,
+                                                     iter->hash, filter_hash);
+               mutex_unlock(&ftrace_lock);
+-      } else {
+-              /* For read only, the hash is the ops hash */
+-              iter->hash = NULL;
+       }
+       mutex_unlock(&iter->ops->func_hash->regex_lock);
diff --git a/queue-6.16/iio-adc-ad7124-fix-channel-lookup-in-syscalib-functions.patch b/queue-6.16/iio-adc-ad7124-fix-channel-lookup-in-syscalib-functions.patch
new file mode 100644 (file)
index 0000000..05f4e07
--- /dev/null
@@ -0,0 +1,83 @@
+From 197e299aae42ffa19028eaea92b2f30dd9fb8445 Mon Sep 17 00:00:00 2001
+From: David Lechner <dlechner@baylibre.com>
+Date: Sat, 26 Jul 2025 11:28:48 -0500
+Subject: iio: adc: ad7124: fix channel lookup in syscalib functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: David Lechner <dlechner@baylibre.com>
+
+commit 197e299aae42ffa19028eaea92b2f30dd9fb8445 upstream.
+
+Fix possible incorrect channel lookup in the syscalib functions by using
+the correct channel address instead of the channel number.
+
+In the ad7124 driver, the channel field of struct iio_chan_spec is the
+input pin number of the positive input of the channel. This can be, but
+is not always the same as the index in the channels array. The correct
+index in the channels array is stored in the address field (and also
+scan_index). We use the address field to perform the correct lookup.
+
+Fixes: 47036a03a303 ("iio: adc: ad7124: Implement internal calibration at probe time")
+Signed-off-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250726-iio-adc-ad7124-fix-channel-lookup-in-syscalib-v1-1-b9d14bb684af@baylibre.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/ad7124.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/iio/adc/ad7124.c
++++ b/drivers/iio/adc/ad7124.c
+@@ -855,7 +855,7 @@ enum {
+ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan_spec *chan)
+ {
+       struct device *dev = &st->sd.spi->dev;
+-      struct ad7124_channel *ch = &st->channels[chan->channel];
++      struct ad7124_channel *ch = &st->channels[chan->address];
+       int ret;
+       if (ch->syscalib_mode == AD7124_SYSCALIB_ZERO_SCALE) {
+@@ -871,8 +871,8 @@ static int ad7124_syscalib_locked(struct
+               if (ret < 0)
+                       return ret;
+-              dev_dbg(dev, "offset for channel %d after zero-scale calibration: 0x%x\n",
+-                      chan->channel, ch->cfg.calibration_offset);
++              dev_dbg(dev, "offset for channel %lu after zero-scale calibration: 0x%x\n",
++                      chan->address, ch->cfg.calibration_offset);
+       } else {
+               ch->cfg.calibration_gain = st->gain_default;
+@@ -886,8 +886,8 @@ static int ad7124_syscalib_locked(struct
+               if (ret < 0)
+                       return ret;
+-              dev_dbg(dev, "gain for channel %d after full-scale calibration: 0x%x\n",
+-                      chan->channel, ch->cfg.calibration_gain);
++              dev_dbg(dev, "gain for channel %lu after full-scale calibration: 0x%x\n",
++                      chan->address, ch->cfg.calibration_gain);
+       }
+       return 0;
+@@ -930,7 +930,7 @@ static int ad7124_set_syscalib_mode(stru
+ {
+       struct ad7124_state *st = iio_priv(indio_dev);
+-      st->channels[chan->channel].syscalib_mode = mode;
++      st->channels[chan->address].syscalib_mode = mode;
+       return 0;
+ }
+@@ -940,7 +940,7 @@ static int ad7124_get_syscalib_mode(stru
+ {
+       struct ad7124_state *st = iio_priv(indio_dev);
+-      return st->channels[chan->channel].syscalib_mode;
++      return st->channels[chan->address].syscalib_mode;
+ }
+ static const struct iio_enum ad7124_syscalib_mode_enum = {
diff --git a/queue-6.16/iio-adc-ad7173-prevent-scan-if-too-many-setups-requested.patch b/queue-6.16/iio-adc-ad7173-prevent-scan-if-too-many-setups-requested.patch
new file mode 100644 (file)
index 0000000..1ece8b8
--- /dev/null
@@ -0,0 +1,170 @@
+From 1cfb22c277c7274f54babaa5b416dfbc00181e16 Mon Sep 17 00:00:00 2001
+From: David Lechner <dlechner@baylibre.com>
+Date: Tue, 22 Jul 2025 14:20:07 -0500
+Subject: iio: adc: ad7173: prevent scan if too many setups requested
+
+From: David Lechner <dlechner@baylibre.com>
+
+commit 1cfb22c277c7274f54babaa5b416dfbc00181e16 upstream.
+
+Add a check to ad7173_update_scan_mode() to ensure that we didn't exceed
+the maximum number of unique channel configurations.
+
+In the AD7173 family of chips, there are some chips that have 16
+CHANNELx registers but only 8 setups (combination of CONFIGx, FILTERx,
+GAINx and OFFSETx registers). Since commit 92c247216918 ("iio: adc:
+ad7173: fix num_slots"), it is possible to have more than 8 channels
+enabled in a scan at the same time, so it is possible to get a bad
+configuration when more than 8 channels are using unique configurations.
+This happens because the algorithm to allocate the setup slots only
+takes into account which slot has been least recently used and doesn't
+know about the maximum number of slots available.
+
+Since the algorithm to allocate the setup slots is quite complex, it is
+simpler to check after the fact if the current state is valid or not.
+So this patch adds a check in ad7173_update_scan_mode() after setting up
+all of the configurations to make sure that the actual setup still
+matches the requested setup for each enabled channel. If not, we prevent
+the scan from being enabled and return an error.
+
+The setup comparison in ad7173_setup_equal() is refactored to a separate
+function since we need to call it in two places now.
+
+Fixes: 92c247216918 ("iio: adc: ad7173: fix num_slots")
+Signed-off-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250722-iio-adc-ad7173-fix-setup-use-limits-v2-1-8e96bdb72a9c@baylibre.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/ad7173.c |   87 ++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 75 insertions(+), 12 deletions(-)
+
+--- a/drivers/iio/adc/ad7173.c
++++ b/drivers/iio/adc/ad7173.c
+@@ -200,7 +200,7 @@ struct ad7173_channel_config {
+       /*
+        * Following fields are used to compare equality. If you
+        * make adaptations in it, you most likely also have to adapt
+-       * ad7173_find_live_config(), too.
++       * ad7173_is_setup_equal(), too.
+        */
+       struct_group(config_props,
+               bool bipolar;
+@@ -562,12 +562,19 @@ static void ad7173_reset_usage_cnts(stru
+       st->config_usage_counter = 0;
+ }
+-static struct ad7173_channel_config *
+-ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg)
++/**
++ * ad7173_is_setup_equal - Compare two channel setups
++ * @cfg1: First channel configuration
++ * @cfg2: Second channel configuration
++ *
++ * Compares all configuration options that affect the registers connected to
++ * SETUP_SEL, namely CONFIGx, FILTERx, GAINx and OFFSETx.
++ *
++ * Returns: true if the setups are identical, false otherwise
++ */
++static bool ad7173_is_setup_equal(const struct ad7173_channel_config *cfg1,
++                                const struct ad7173_channel_config *cfg2)
+ {
+-      struct ad7173_channel_config *cfg_aux;
+-      int i;
+-
+       /*
+        * This is just to make sure that the comparison is adapted after
+        * struct ad7173_channel_config was changed.
+@@ -580,14 +587,22 @@ ad7173_find_live_config(struct ad7173_st
+                                    u8 ref_sel;
+                            }));
++      return cfg1->bipolar == cfg2->bipolar &&
++             cfg1->input_buf == cfg2->input_buf &&
++             cfg1->odr == cfg2->odr &&
++             cfg1->ref_sel == cfg2->ref_sel;
++}
++
++static struct ad7173_channel_config *
++ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg)
++{
++      struct ad7173_channel_config *cfg_aux;
++      int i;
++
+       for (i = 0; i < st->num_channels; i++) {
+               cfg_aux = &st->channels[i].cfg;
+-              if (cfg_aux->live &&
+-                  cfg->bipolar == cfg_aux->bipolar &&
+-                  cfg->input_buf == cfg_aux->input_buf &&
+-                  cfg->odr == cfg_aux->odr &&
+-                  cfg->ref_sel == cfg_aux->ref_sel)
++              if (cfg_aux->live && ad7173_is_setup_equal(cfg, cfg_aux))
+                       return cfg_aux;
+       }
+       return NULL;
+@@ -1229,7 +1244,7 @@ static int ad7173_update_scan_mode(struc
+                                  const unsigned long *scan_mask)
+ {
+       struct ad7173_state *st = iio_priv(indio_dev);
+-      int i, ret;
++      int i, j, k, ret;
+       for (i = 0; i < indio_dev->num_channels; i++) {
+               if (test_bit(i, scan_mask))
+@@ -1240,6 +1255,54 @@ static int ad7173_update_scan_mode(struc
+                       return ret;
+       }
++      /*
++       * On some chips, there are more channels that setups, so if there were
++       * more unique setups requested than the number of available slots,
++       * ad7173_set_channel() will have written over some of the slots. We
++       * can detect this by making sure each assigned cfg_slot matches the
++       * requested configuration. If it doesn't, we know that the slot was
++       * overwritten by a different channel.
++       */
++      for_each_set_bit(i, scan_mask, indio_dev->num_channels) {
++              const struct ad7173_channel_config *cfg1, *cfg2;
++
++              cfg1 = &st->channels[i].cfg;
++
++              for_each_set_bit(j, scan_mask, indio_dev->num_channels) {
++                      cfg2 = &st->channels[j].cfg;
++
++                      /*
++                       * Only compare configs that are assigned to the same
++                       * SETUP_SEL slot and don't compare channel to itself.
++                       */
++                      if (i == j || cfg1->cfg_slot != cfg2->cfg_slot)
++                              continue;
++
++                      /*
++                       * If we find two different configs trying to use the
++                       * same SETUP_SEL slot, then we know that the that we
++                       * have too many unique configurations requested for
++                       * the available slots and at least one was overwritten.
++                       */
++                      if (!ad7173_is_setup_equal(cfg1, cfg2)) {
++                              /*
++                               * At this point, there isn't a way to tell
++                               * which setups are actually programmed in the
++                               * ADC anymore, so we could read them back to
++                               * see, but it is simpler to just turn off all
++                               * of the live flags so that everything gets
++                               * reprogramed on the next attempt read a sample.
++                               */
++                              for (k = 0; k < st->num_channels; k++)
++                                      st->channels[k].cfg.live = false;
++
++                              dev_err(&st->sd.spi->dev,
++                                      "Too many unique channel configurations requested for scan\n");
++                              return -EINVAL;
++                      }
++              }
++      }
++
+       return 0;
+ }
diff --git a/queue-6.16/iio-adc-bd79124-add-gpiolib-dependency.patch b/queue-6.16/iio-adc-bd79124-add-gpiolib-dependency.patch
new file mode 100644 (file)
index 0000000..8b08365
--- /dev/null
@@ -0,0 +1,47 @@
+From 8a6ededaad2d2dcaac8e545bffee1073dca9db95 Mon Sep 17 00:00:00 2001
+From: Matti Vaittinen <mazziesaccount@gmail.com>
+Date: Wed, 13 Aug 2025 12:16:06 +0300
+Subject: iio: adc: bd79124: Add GPIOLIB dependency
+
+From: Matti Vaittinen <mazziesaccount@gmail.com>
+
+commit 8a6ededaad2d2dcaac8e545bffee1073dca9db95 upstream.
+
+The bd79124 has ADC inputs which can be muxed to be GPIOs. The driver
+supports this by registering a GPIO-chip for channels which aren't used
+as ADC.
+
+The Kconfig entry does not handle the dependency to GPIOLIB, which
+causes errors:
+
+ERROR: modpost: "devm_gpiochip_add_data_with_key" [drivers/iio/adc/rohm-bd79124.ko] undefined!
+ERROR: modpost: "gpiochip_get_data" [drivers/iio/adc/rohm-bd79124.ko] undefined!
+
+at linking phase if GPIOLIB is not configured to be used.
+
+Fix this by adding dependency to the GPIOLIB.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202508131533.5sSkq80B-lkp@intel.com/
+Fixes: 3f57a3b9ab74 ("iio: adc: Support ROHM BD79124 ADC")
+Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://patch.msgid.link/6837249bddf358924e67566293944506206d2d62.1755076369.git.mazziesaccount@gmail.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/Kconfig |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/Kconfig
++++ b/drivers/iio/adc/Kconfig
+@@ -1257,7 +1257,7 @@ config RN5T618_ADC
+ config ROHM_BD79124
+       tristate "Rohm BD79124 ADC driver"
+-      depends on I2C
++      depends on I2C && GPIOLIB
+       select REGMAP_I2C
+       select IIO_ADC_HELPER
+       help
diff --git a/queue-6.16/iio-adc-rzg2l-cleanup-suspend-resume-path.patch b/queue-6.16/iio-adc-rzg2l-cleanup-suspend-resume-path.patch
new file mode 100644 (file)
index 0000000..b9a6a88
--- /dev/null
@@ -0,0 +1,100 @@
+From a3c6eabe3bbd6b0e7124d68b2d3bc32fed17362e Mon Sep 17 00:00:00 2001
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Date: Sun, 10 Aug 2025 15:33:27 +0300
+Subject: iio: adc: rzg2l: Cleanup suspend/resume path
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+commit a3c6eabe3bbd6b0e7124d68b2d3bc32fed17362e upstream.
+
+There is no need to manually track the runtime PM status in the driver.
+The pm_runtime_force_suspend() and pm_runtime_force_resume() functions
+already call pm_runtime_status_suspended() to check the runtime PM state.
+
+Additionally, avoid calling pm_runtime_put_autosuspend() during the
+suspend/resume path, as this would decrease the usage counter of a
+potential user that had the ADC open before the suspend/resume cycle.
+
+Fixes: 563cf94f9329 ("iio: adc: rzg2l_adc: Add suspend/resume support")
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://patch.msgid.link/20250810123328.800104-2-claudiu.beznea.uj@bp.renesas.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/rzg2l_adc.c | 29 ++++++++---------------------
+ 1 file changed, 8 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/iio/adc/rzg2l_adc.c b/drivers/iio/adc/rzg2l_adc.c
+index 9674d48074c9..0cb5a67fd497 100644
+--- a/drivers/iio/adc/rzg2l_adc.c
++++ b/drivers/iio/adc/rzg2l_adc.c
+@@ -89,7 +89,6 @@ struct rzg2l_adc {
+       struct completion completion;
+       struct mutex lock;
+       u16 last_val[RZG2L_ADC_MAX_CHANNELS];
+-      bool was_rpm_active;
+ };
+ /**
+@@ -541,14 +540,9 @@ static int rzg2l_adc_suspend(struct device *dev)
+       };
+       int ret;
+-      if (pm_runtime_suspended(dev)) {
+-              adc->was_rpm_active = false;
+-      } else {
+-              ret = pm_runtime_force_suspend(dev);
+-              if (ret)
+-                      return ret;
+-              adc->was_rpm_active = true;
+-      }
++      ret = pm_runtime_force_suspend(dev);
++      if (ret)
++              return ret;
+       ret = reset_control_bulk_assert(ARRAY_SIZE(resets), resets);
+       if (ret)
+@@ -557,9 +551,7 @@ static int rzg2l_adc_suspend(struct device *dev)
+       return 0;
+ rpm_restore:
+-      if (adc->was_rpm_active)
+-              pm_runtime_force_resume(dev);
+-
++      pm_runtime_force_resume(dev);
+       return ret;
+ }
+@@ -577,11 +569,9 @@ static int rzg2l_adc_resume(struct device *dev)
+       if (ret)
+               return ret;
+-      if (adc->was_rpm_active) {
+-              ret = pm_runtime_force_resume(dev);
+-              if (ret)
+-                      goto resets_restore;
+-      }
++      ret = pm_runtime_force_resume(dev);
++      if (ret)
++              goto resets_restore;
+       ret = rzg2l_adc_hw_init(dev, adc);
+       if (ret)
+@@ -590,10 +580,7 @@ static int rzg2l_adc_resume(struct device *dev)
+       return 0;
+ rpm_restore:
+-      if (adc->was_rpm_active) {
+-              pm_runtime_mark_last_busy(dev);
+-              pm_runtime_put_autosuspend(dev);
+-      }
++      pm_runtime_force_suspend(dev);
+ resets_restore:
+       reset_control_bulk_assert(ARRAY_SIZE(resets), resets);
+       return ret;
+-- 
+2.50.1
+
diff --git a/queue-6.16/iio-adc-rzg2l_adc-set-driver-data-before-enabling-runtime-pm.patch b/queue-6.16/iio-adc-rzg2l_adc-set-driver-data-before-enabling-runtime-pm.patch
new file mode 100644 (file)
index 0000000..953a974
--- /dev/null
@@ -0,0 +1,47 @@
+From c69e13965f26b8058f538ea8bdbd2d7718cf1fbe Mon Sep 17 00:00:00 2001
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Date: Sun, 10 Aug 2025 15:33:28 +0300
+Subject: iio: adc: rzg2l_adc: Set driver data before enabling runtime PM
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+commit c69e13965f26b8058f538ea8bdbd2d7718cf1fbe upstream.
+
+When stress-testing the system by repeatedly unbinding and binding the ADC
+device in a loop, and the ADC is a supplier for another device (e.g., a
+thermal hardware block that reads temperature through the ADC), it may
+happen that the ADC device is runtime-resumed immediately after runtime PM
+is enabled, triggered by its consumer. At this point, since drvdata is not
+yet set and the driver's runtime PM callbacks rely on it, a crash can
+occur. To avoid this, set drvdata just after it was allocated.
+
+Fixes: 89ee8174e8c8 ("iio: adc: rzg2l_adc: Simplify the runtime PM code")
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://patch.msgid.link/20250810123328.800104-3-claudiu.beznea.uj@bp.renesas.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/rzg2l_adc.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/adc/rzg2l_adc.c
++++ b/drivers/iio/adc/rzg2l_adc.c
+@@ -428,6 +428,8 @@ static int rzg2l_adc_probe(struct platfo
+       if (!indio_dev)
+               return -ENOMEM;
++      platform_set_drvdata(pdev, indio_dev);
++
+       adc = iio_priv(indio_dev);
+       adc->hw_params = device_get_match_data(dev);
+@@ -460,8 +462,6 @@ static int rzg2l_adc_probe(struct platfo
+       if (ret)
+               return ret;
+-      platform_set_drvdata(pdev, indio_dev);
+-
+       ret = rzg2l_adc_hw_init(dev, adc);
+       if (ret)
+               return dev_err_probe(&pdev->dev, ret,
diff --git a/queue-6.16/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch b/queue-6.16/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch
new file mode 100644 (file)
index 0000000..f155f91
--- /dev/null
@@ -0,0 +1,34 @@
+From 433b99e922943efdfd62b9a8e3ad1604838181f2 Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sat, 2 Aug 2025 17:44:21 +0100
+Subject: iio: light: as73211: Ensure buffer holes are zeroed
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 433b99e922943efdfd62b9a8e3ad1604838181f2 upstream.
+
+Given that the buffer is copied to a kfifo that ultimately user space
+can read, ensure we zero it.
+
+Fixes: 403e5586b52e ("iio: light: as73211: New driver")
+Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Link: https://patch.msgid.link/20250802164436.515988-2-jic23@kernel.org
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/light/as73211.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/light/as73211.c
++++ b/drivers/iio/light/as73211.c
+@@ -639,7 +639,7 @@ static irqreturn_t as73211_trigger_handl
+       struct {
+               __le16 chan[4];
+               aligned_s64 ts;
+-      } scan;
++      } scan = { };
+       int data_result, ret;
+       mutex_lock(&data->mutex);
diff --git a/queue-6.16/iio-pressure-bmp280-use-is_err-in-bmp280_common_probe.patch b/queue-6.16/iio-pressure-bmp280-use-is_err-in-bmp280_common_probe.patch
new file mode 100644 (file)
index 0000000..3741f57
--- /dev/null
@@ -0,0 +1,43 @@
+From 43c0f6456f801181a80b73d95def0e0fd134e1cc Mon Sep 17 00:00:00 2001
+From: Salah Triki <salah.triki@gmail.com>
+Date: Mon, 18 Aug 2025 10:27:30 +0100
+Subject: iio: pressure: bmp280: Use IS_ERR() in bmp280_common_probe()
+
+From: Salah Triki <salah.triki@gmail.com>
+
+commit 43c0f6456f801181a80b73d95def0e0fd134e1cc upstream.
+
+`devm_gpiod_get_optional()` may return non-NULL error pointer on failure.
+Check its return value using `IS_ERR()` and propagate the error if
+necessary.
+
+Fixes: df6e71256c84 ("iio: pressure: bmp280: Explicitly mark GPIO optional")
+Signed-off-by: Salah Triki <salah.triki@gmail.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250818092740.545379-2-salah.triki@gmail.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/pressure/bmp280-core.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/iio/pressure/bmp280-core.c
++++ b/drivers/iio/pressure/bmp280-core.c
+@@ -3216,11 +3216,12 @@ int bmp280_common_probe(struct device *d
+       /* Bring chip out of reset if there is an assigned GPIO line */
+       gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
++      if (IS_ERR(gpiod))
++              return dev_err_probe(dev, PTR_ERR(gpiod), "failed to get reset GPIO\n");
++
+       /* Deassert the signal */
+-      if (gpiod) {
+-              dev_info(dev, "release reset\n");
+-              gpiod_set_value(gpiod, 0);
+-      }
++      dev_info(dev, "release reset\n");
++      gpiod_set_value(gpiod, 0);
+       data->regmap = regmap;
diff --git a/queue-6.16/iio-proximity-isl29501-fix-buffered-read-on-big-endian-systems.patch b/queue-6.16/iio-proximity-isl29501-fix-buffered-read-on-big-endian-systems.patch
new file mode 100644 (file)
index 0000000..7a68584
--- /dev/null
@@ -0,0 +1,52 @@
+From de18e978d0cda23e4c102e18092b63a5b0b3a800 Mon Sep 17 00:00:00 2001
+From: David Lechner <dlechner@baylibre.com>
+Date: Tue, 22 Jul 2025 15:54:21 -0500
+Subject: iio: proximity: isl29501: fix buffered read on big-endian systems
+
+From: David Lechner <dlechner@baylibre.com>
+
+commit de18e978d0cda23e4c102e18092b63a5b0b3a800 upstream.
+
+Fix passing a u32 value as a u16 buffer scan item. This works on little-
+endian systems, but not on big-endian systems.
+
+A new local variable is introduced for getting the register value and
+the array is changed to a struct to make the data layout more explicit
+rather than just changing the type and having to recalculate the proper
+length needed for the timestamp.
+
+Fixes: 1c28799257bc ("iio: light: isl29501: Add support for the ISL29501 ToF sensor.")
+Signed-off-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250722-iio-use-more-iio_declare_buffer_with_ts-7-v2-1-d3ebeb001ed3@baylibre.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/proximity/isl29501.c |   14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/iio/proximity/isl29501.c
++++ b/drivers/iio/proximity/isl29501.c
+@@ -938,12 +938,18 @@ static irqreturn_t isl29501_trigger_hand
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct isl29501_private *isl29501 = iio_priv(indio_dev);
+       const unsigned long *active_mask = indio_dev->active_scan_mask;
+-      u32 buffer[4] __aligned(8) = {}; /* 1x16-bit + naturally aligned ts */
++      u32 value;
++      struct {
++              u16 data;
++              aligned_s64 ts;
++      } scan = { };
+-      if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask))
+-              isl29501_register_read(isl29501, REG_DISTANCE, buffer);
++      if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) {
++              isl29501_register_read(isl29501, REG_DISTANCE, &value);
++              scan.data = value;
++      }
+-      iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
++      iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);
+       iio_trigger_notify_done(indio_dev->trig);
+       return IRQ_HANDLED;
diff --git a/queue-6.16/iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch b/queue-6.16/iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch
new file mode 100644 (file)
index 0000000..06accd3
--- /dev/null
@@ -0,0 +1,93 @@
+From ae5bc07ec9f73a41734270ef3f800c5c8a7e0ad3 Mon Sep 17 00:00:00 2001
+From: David Lechner <dlechner@baylibre.com>
+Date: Mon, 21 Jul 2025 18:04:04 -0500
+Subject: iio: temperature: maxim_thermocouple: use DMA-safe buffer for spi_read()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: David Lechner <dlechner@baylibre.com>
+
+commit ae5bc07ec9f73a41734270ef3f800c5c8a7e0ad3 upstream.
+
+Replace using stack-allocated buffers with a DMA-safe buffer for use
+with spi_read(). This allows the driver to be safely used with
+DMA-enabled SPI controllers.
+
+The buffer array is also converted to a struct with a union to make the
+usage of the memory in the buffer more clear and ensure proper alignment.
+
+Fixes: 1f25ca11d84a ("iio: temperature: add support for Maxim thermocouple chips")
+Signed-off-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250721-iio-use-more-iio_declare_buffer_with_ts-3-v2-1-0c68d41ccf6c@baylibre.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/temperature/maxim_thermocouple.c |   26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+--- a/drivers/iio/temperature/maxim_thermocouple.c
++++ b/drivers/iio/temperature/maxim_thermocouple.c
+@@ -11,6 +11,7 @@
+ #include <linux/module.h>
+ #include <linux/err.h>
+ #include <linux/spi/spi.h>
++#include <linux/types.h>
+ #include <linux/iio/iio.h>
+ #include <linux/iio/sysfs.h>
+ #include <linux/iio/trigger.h>
+@@ -121,8 +122,15 @@ struct maxim_thermocouple_data {
+       struct spi_device *spi;
+       const struct maxim_thermocouple_chip *chip;
+       char tc_type;
+-
+-      u8 buffer[16] __aligned(IIO_DMA_MINALIGN);
++      /* Buffer for reading up to 2 hardware channels. */
++      struct {
++              union {
++                      __be16 raw16;
++                      __be32 raw32;
++                      __be16 raw[2];
++              };
++              aligned_s64 timestamp;
++      } buffer __aligned(IIO_DMA_MINALIGN);
+ };
+ static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
+@@ -130,18 +138,16 @@ static int maxim_thermocouple_read(struc
+ {
+       unsigned int storage_bytes = data->chip->read_size;
+       unsigned int shift = chan->scan_type.shift + (chan->address * 8);
+-      __be16 buf16;
+-      __be32 buf32;
+       int ret;
+       switch (storage_bytes) {
+       case 2:
+-              ret = spi_read(data->spi, (void *)&buf16, storage_bytes);
+-              *val = be16_to_cpu(buf16);
++              ret = spi_read(data->spi, &data->buffer.raw16, storage_bytes);
++              *val = be16_to_cpu(data->buffer.raw16);
+               break;
+       case 4:
+-              ret = spi_read(data->spi, (void *)&buf32, storage_bytes);
+-              *val = be32_to_cpu(buf32);
++              ret = spi_read(data->spi, &data->buffer.raw32, storage_bytes);
++              *val = be32_to_cpu(data->buffer.raw32);
+               break;
+       default:
+               ret = -EINVAL;
+@@ -166,9 +172,9 @@ static irqreturn_t maxim_thermocouple_tr
+       struct maxim_thermocouple_data *data = iio_priv(indio_dev);
+       int ret;
+-      ret = spi_read(data->spi, data->buffer, data->chip->read_size);
++      ret = spi_read(data->spi, data->buffer.raw, data->chip->read_size);
+       if (!ret) {
+-              iio_push_to_buffers_with_ts(indio_dev, data->buffer,
++              iio_push_to_buffers_with_ts(indio_dev, &data->buffer,
+                                           sizeof(data->buffer),
+                                           iio_get_time_ns(indio_dev));
+       }
diff --git a/queue-6.16/kcov-usb-don-t-disable-interrupts-in-kcov_remote_start_usb_softirq.patch b/queue-6.16/kcov-usb-don-t-disable-interrupts-in-kcov_remote_start_usb_softirq.patch
new file mode 100644 (file)
index 0000000..5da74db
--- /dev/null
@@ -0,0 +1,143 @@
+From 9528d32873b38281ae105f2f5799e79ae9d086c2 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Mon, 11 Aug 2025 10:27:45 +0200
+Subject: kcov, usb: Don't disable interrupts in kcov_remote_start_usb_softirq()
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+commit 9528d32873b38281ae105f2f5799e79ae9d086c2 upstream.
+
+kcov_remote_start_usb_softirq() the begin of urb's completion callback.
+HCDs marked HCD_BH will invoke this function from the softirq and
+in_serving_softirq() will detect this properly.
+Root-HUB (RH) requests will not be delayed to softirq but complete
+immediately in IRQ context.
+This will confuse kcov because in_serving_softirq() will report true if
+the softirq is served after the hardirq and if the softirq got
+interrupted by the hardirq in which currently runs.
+
+This was addressed by simply disabling interrupts in
+kcov_remote_start_usb_softirq() which avoided the interruption by the RH
+while a regular completion callback was invoked.
+This not only changes the behaviour while kconv is enabled but also
+breaks PREEMPT_RT because now sleeping locks can no longer be acquired.
+
+Revert the previous fix. Address the issue by invoking
+kcov_remote_start_usb() only if the context is just "serving softirqs"
+which is identified by checking in_serving_softirq() and in_hardirq()
+must be false.
+
+Fixes: f85d39dd7ed89 ("kcov, usb: disable interrupts in kcov_remote_start_usb_softirq")
+Cc: stable <stable@kernel.org>
+Reported-by: Yunseong Kim <ysk@kzalloc.com>
+Closes: https://lore.kernel.org/all/20250725201400.1078395-2-ysk@kzalloc.com/
+Tested-by: Yunseong Kim <ysk@kzalloc.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://lore.kernel.org/r/20250811082745.ycJqBXMs@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hcd.c |   12 +++++-------
+ include/linux/kcov.h   |   47 +++++++++--------------------------------------
+ 2 files changed, 14 insertions(+), 45 deletions(-)
+
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -1623,7 +1623,6 @@ static void __usb_hcd_giveback_urb(struc
+       struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus);
+       struct usb_anchor *anchor = urb->anchor;
+       int status = urb->unlinked;
+-      unsigned long flags;
+       urb->hcpriv = NULL;
+       if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
+@@ -1641,14 +1640,13 @@ static void __usb_hcd_giveback_urb(struc
+       /* pass ownership to the completion handler */
+       urb->status = status;
+       /*
+-       * Only collect coverage in the softirq context and disable interrupts
+-       * to avoid scenarios with nested remote coverage collection sections
+-       * that KCOV does not support.
+-       * See the comment next to kcov_remote_start_usb_softirq() for details.
++       * This function can be called in task context inside another remote
++       * coverage collection section, but kcov doesn't support that kind of
++       * recursion yet. Only collect coverage in softirq context for now.
+        */
+-      flags = kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum);
++      kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum);
+       urb->complete(urb);
+-      kcov_remote_stop_softirq(flags);
++      kcov_remote_stop_softirq();
+       usb_anchor_resume_wakeups(anchor);
+       atomic_dec(&urb->use_count);
+--- a/include/linux/kcov.h
++++ b/include/linux/kcov.h
+@@ -57,47 +57,21 @@ static inline void kcov_remote_start_usb
+ /*
+  * The softirq flavor of kcov_remote_*() functions is introduced as a temporary
+- * workaround for KCOV's lack of nested remote coverage sections support.
+- *
+- * Adding support is tracked in https://bugzilla.kernel.org/show_bug.cgi?id=210337.
+- *
+- * kcov_remote_start_usb_softirq():
+- *
+- * 1. Only collects coverage when called in the softirq context. This allows
+- *    avoiding nested remote coverage collection sections in the task context.
+- *    For example, USB/IP calls usb_hcd_giveback_urb() in the task context
+- *    within an existing remote coverage collection section. Thus, KCOV should
+- *    not attempt to start collecting coverage within the coverage collection
+- *    section in __usb_hcd_giveback_urb() in this case.
+- *
+- * 2. Disables interrupts for the duration of the coverage collection section.
+- *    This allows avoiding nested remote coverage collection sections in the
+- *    softirq context (a softirq might occur during the execution of a work in
+- *    the BH workqueue, which runs with in_serving_softirq() > 0).
+- *    For example, usb_giveback_urb_bh() runs in the BH workqueue with
+- *    interrupts enabled, so __usb_hcd_giveback_urb() might be interrupted in
+- *    the middle of its remote coverage collection section, and the interrupt
+- *    handler might invoke __usb_hcd_giveback_urb() again.
++ * work around for kcov's lack of nested remote coverage sections support in
++ * task context. Adding support for nested sections is tracked in:
++ * https://bugzilla.kernel.org/show_bug.cgi?id=210337
+  */
+-static inline unsigned long kcov_remote_start_usb_softirq(u64 id)
++static inline void kcov_remote_start_usb_softirq(u64 id)
+ {
+-      unsigned long flags = 0;
+-
+-      if (in_serving_softirq()) {
+-              local_irq_save(flags);
++      if (in_serving_softirq() && !in_hardirq())
+               kcov_remote_start_usb(id);
+-      }
+-
+-      return flags;
+ }
+-static inline void kcov_remote_stop_softirq(unsigned long flags)
++static inline void kcov_remote_stop_softirq(void)
+ {
+-      if (in_serving_softirq()) {
++      if (in_serving_softirq() && !in_hardirq())
+               kcov_remote_stop();
+-              local_irq_restore(flags);
+-      }
+ }
+ #ifdef CONFIG_64BIT
+@@ -131,11 +105,8 @@ static inline u64 kcov_common_handle(voi
+ }
+ static inline void kcov_remote_start_common(u64 id) {}
+ static inline void kcov_remote_start_usb(u64 id) {}
+-static inline unsigned long kcov_remote_start_usb_softirq(u64 id)
+-{
+-      return 0;
+-}
+-static inline void kcov_remote_stop_softirq(unsigned long flags) {}
++static inline void kcov_remote_start_usb_softirq(u64 id) {}
++static inline void kcov_remote_stop_softirq(void) {}
+ #endif /* CONFIG_KCOV */
+ #endif /* _LINUX_KCOV_H */
diff --git a/queue-6.16/most-core-drop-device-reference-after-usage-in-get_channel.patch b/queue-6.16/most-core-drop-device-reference-after-usage-in-get_channel.patch
new file mode 100644 (file)
index 0000000..b22824f
--- /dev/null
@@ -0,0 +1,34 @@
+From b47b493d6387ae437098112936f32be27f73516c Mon Sep 17 00:00:00 2001
+From: Miaoqian Lin <linmq006@gmail.com>
+Date: Mon, 4 Aug 2025 12:29:55 +0400
+Subject: most: core: Drop device reference after usage in get_channel()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+commit b47b493d6387ae437098112936f32be27f73516c upstream.
+
+In get_channel(), the reference obtained by bus_find_device_by_name()
+was dropped via put_device() before accessing the device's driver data
+Move put_device() after usage to avoid potential issues.
+
+Fixes: 2485055394be ("staging: most: core: drop device reference")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20250804082955.3621026-1-linmq006@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/most/core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/most/core.c
++++ b/drivers/most/core.c
+@@ -538,8 +538,8 @@ static struct most_channel *get_channel(
+       dev = bus_find_device_by_name(&mostbus, NULL, mdev);
+       if (!dev)
+               return NULL;
+-      put_device(dev);
+       iface = dev_get_drvdata(dev);
++      put_device(dev);
+       list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) {
+               if (!strcmp(dev_name(&c->dev), mdev_ch))
+                       return c;
index 132ada9f7c92487c645aa48ecf29601a1b9f4025..186722dfe8a1d14564b864eb9e209b9aed608f9f 100644 (file)
@@ -297,3 +297,32 @@ drm-dp-change-aux-dpcd-probe-address-from-dpcd_rev-to-lane0_1_status.patch
 fpga-zynq_fpga-fix-the-wrong-usage-of-dma_map_sgtable.patch
 iio-adc-ad7380-fix-missing-max_conversion_rate_hz-on-adaq4381-4.patch
 iio-accel-sca3300-fix-uninitialized-iio-scan-data.patch
+ftrace-also-allocate-and-copy-hash-for-reading-of-filter-files.patch
+iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch
+iio-adc-ad7124-fix-channel-lookup-in-syscalib-functions.patch
+iio-light-as73211-ensure-buffer-holes-are-zeroed.patch
+iio-pressure-bmp280-use-is_err-in-bmp280_common_probe.patch
+iio-adc-rzg2l_adc-set-driver-data-before-enabling-runtime-pm.patch
+iio-adc-bd79124-add-gpiolib-dependency.patch
+iio-adc-ad7173-prevent-scan-if-too-many-setups-requested.patch
+iio-proximity-isl29501-fix-buffered-read-on-big-endian-systems.patch
+iio-adc-rzg2l-cleanup-suspend-resume-path.patch
+most-core-drop-device-reference-after-usage-in-get_channel.patch
+kcov-usb-don-t-disable-interrupts-in-kcov_remote_start_usb_softirq.patch
+cdx-fix-off-by-one-error-in-cdx_rpmsg_probe.patch
+usb-quirks-add-delay_init-quick-for-another-sandisk-3.2gen1-flash-drive.patch
+comedi-make-insn_rw_emulate_bits-do-insn-n-samples.patch
+comedi-pcl726-prevent-invalid-irq-number.patch
+comedi-fix-use-of-uninitialized-memory-in-do_insn_ioctl-and-do_insnlist_ioctl.patch
+usb-core-hcd-fix-accessing-unmapped-memory-in-single_step_set_feature-test.patch
+usb-renesas-xhci-fix-external-rom-access-timeouts.patch
+usb-storage-add-unusual-devs-entry-for-novatek-ntk96550-based-camera.patch
+usb-storage-realtek_cr-use-correct-byte-order-for-bcs-residue.patch
+usb-storage-ignore-driver-cd-mode-for-realtek-multi-mode-wi-fi-dongles.patch
+usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch
+usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch
+usb-xhci-fix-slot_id-resource-race-conflict.patch
+usb-xhci-fix-host-not-responding-after-suspend-and-resume.patch
+usb-dwc3-ignore-late-xfernotready-event-to-prevent-halt-timeout.patch
+usb-dwc3-remove-warn_on-for-device-endpoint-command-timeouts.patch
+usb-dwc3-pci-add-support-for-the-intel-wildcat-lake.patch
diff --git a/queue-6.16/usb-core-hcd-fix-accessing-unmapped-memory-in-single_step_set_feature-test.patch b/queue-6.16/usb-core-hcd-fix-accessing-unmapped-memory-in-single_step_set_feature-test.patch
new file mode 100644 (file)
index 0000000..61ef7e1
--- /dev/null
@@ -0,0 +1,58 @@
+From 8fe06185e11ae753414aa6117f0e798aa77567ff Mon Sep 17 00:00:00 2001
+From: Xu Yang <xu.yang_2@nxp.com>
+Date: Wed, 6 Aug 2025 16:39:55 +0800
+Subject: usb: core: hcd: fix accessing unmapped memory in SINGLE_STEP_SET_FEATURE test
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+commit 8fe06185e11ae753414aa6117f0e798aa77567ff upstream.
+
+The USB core will unmap urb->transfer_dma after SETUP stage completes.
+Then the USB controller will access unmapped memory when it received
+device descriptor. If iommu is equipped, the entire test can't be
+completed due to the memory accessing is blocked.
+
+Fix it by calling map_urb_for_dma() again for IN stage. To reduce
+redundant map for urb->transfer_buffer, this will also set
+URB_NO_TRANSFER_DMA_MAP flag before first map_urb_for_dma() to skip
+dma map for urb->transfer_buffer and clear URB_NO_TRANSFER_DMA_MAP
+flag before second map_urb_for_dma().
+
+Fixes: 216e0e563d81 ("usb: core: hcd: use map_urb_for_dma for single step set feature urb")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Jun Li <jun.li@nxp.com>
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20250806083955.3325299-1-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hcd.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -2151,7 +2151,7 @@ static struct urb *request_single_step_s
+       urb->complete = usb_ehset_completion;
+       urb->status = -EINPROGRESS;
+       urb->actual_length = 0;
+-      urb->transfer_flags = URB_DIR_IN;
++      urb->transfer_flags = URB_DIR_IN | URB_NO_TRANSFER_DMA_MAP;
+       usb_get_urb(urb);
+       atomic_inc(&urb->use_count);
+       atomic_inc(&urb->dev->urbnum);
+@@ -2215,9 +2215,15 @@ int ehset_single_step_set_feature(struct
+       /* Complete remaining DATA and STATUS stages using the same URB */
+       urb->status = -EINPROGRESS;
++      urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP;
+       usb_get_urb(urb);
+       atomic_inc(&urb->use_count);
+       atomic_inc(&urb->dev->urbnum);
++      if (map_urb_for_dma(hcd, urb, GFP_KERNEL)) {
++              usb_put_urb(urb);
++              goto out1;
++      }
++
+       retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 0);
+       if (!retval && !wait_for_completion_timeout(&done,
+                                               msecs_to_jiffies(2000))) {
diff --git a/queue-6.16/usb-dwc3-ignore-late-xfernotready-event-to-prevent-halt-timeout.patch b/queue-6.16/usb-dwc3-ignore-late-xfernotready-event-to-prevent-halt-timeout.patch
new file mode 100644 (file)
index 0000000..45ae10a
--- /dev/null
@@ -0,0 +1,46 @@
+From 58577118cc7cec9eb7c1836bf88f865ff2c5e3a3 Mon Sep 17 00:00:00 2001
+From: Kuen-Han Tsai <khtsai@google.com>
+Date: Thu, 7 Aug 2025 17:06:55 +0800
+Subject: usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
+
+From: Kuen-Han Tsai <khtsai@google.com>
+
+commit 58577118cc7cec9eb7c1836bf88f865ff2c5e3a3 upstream.
+
+During a device-initiated disconnect, the End Transfer command resets
+the event filter, allowing a new xferNotReady event to be generated
+before the controller is fully halted. Processing this late event
+incorrectly triggers a Start Transfer, which prevents the controller
+from halting and results in a DSTS.DEVCTLHLT bit polling timeout.
+
+Ignore the late xferNotReady event if the controller is already in a
+disconnected state.
+
+Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20250807090700.2397190-1-khtsai@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -3779,6 +3779,15 @@ static void dwc3_gadget_endpoint_transfe
+ static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep,
+               const struct dwc3_event_depevt *event)
+ {
++      /*
++       * During a device-initiated disconnect, a late xferNotReady event can
++       * be generated after the End Transfer command resets the event filter,
++       * but before the controller is halted. Ignore it to prevent a new
++       * transfer from starting.
++       */
++      if (!dep->dwc->connected)
++              return;
++
+       dwc3_gadget_endpoint_frame_from_event(dep, event);
+       /*
diff --git a/queue-6.16/usb-dwc3-pci-add-support-for-the-intel-wildcat-lake.patch b/queue-6.16/usb-dwc3-pci-add-support-for-the-intel-wildcat-lake.patch
new file mode 100644 (file)
index 0000000..4a95cde
--- /dev/null
@@ -0,0 +1,38 @@
+From 86f390ba59cd8d5755bafe2b163c3e6b89d6bbd9 Mon Sep 17 00:00:00 2001
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Date: Tue, 12 Aug 2025 16:11:00 +0300
+Subject: usb: dwc3: pci: add support for the Intel Wildcat Lake
+
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+
+commit 86f390ba59cd8d5755bafe2b163c3e6b89d6bbd9 upstream.
+
+This patch adds the necessary PCI ID for Intel Wildcat Lake
+devices.
+
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Cc: stable <stable@kernel.org>
+Link: https://lore.kernel.org/r/20250812131101.2930199-1-heikki.krogerus@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-pci.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -41,6 +41,7 @@
+ #define PCI_DEVICE_ID_INTEL_TGPLP             0xa0ee
+ #define PCI_DEVICE_ID_INTEL_TGPH              0x43ee
+ #define PCI_DEVICE_ID_INTEL_JSP                       0x4dee
++#define PCI_DEVICE_ID_INTEL_WCL                       0x4d7e
+ #define PCI_DEVICE_ID_INTEL_ADL                       0x460e
+ #define PCI_DEVICE_ID_INTEL_ADL_PCH           0x51ee
+ #define PCI_DEVICE_ID_INTEL_ADLN              0x465e
+@@ -431,6 +432,7 @@ static const struct pci_device_id dwc3_p
+       { PCI_DEVICE_DATA(INTEL, TGPLP, &dwc3_pci_intel_swnode) },
+       { PCI_DEVICE_DATA(INTEL, TGPH, &dwc3_pci_intel_swnode) },
+       { PCI_DEVICE_DATA(INTEL, JSP, &dwc3_pci_intel_swnode) },
++      { PCI_DEVICE_DATA(INTEL, WCL, &dwc3_pci_intel_swnode) },
+       { PCI_DEVICE_DATA(INTEL, ADL, &dwc3_pci_intel_swnode) },
+       { PCI_DEVICE_DATA(INTEL, ADL_PCH, &dwc3_pci_intel_swnode) },
+       { PCI_DEVICE_DATA(INTEL, ADLN, &dwc3_pci_intel_swnode) },
diff --git a/queue-6.16/usb-dwc3-remove-warn_on-for-device-endpoint-command-timeouts.patch b/queue-6.16/usb-dwc3-remove-warn_on-for-device-endpoint-command-timeouts.patch
new file mode 100644 (file)
index 0000000..2d99bb2
--- /dev/null
@@ -0,0 +1,133 @@
+From 45eae113dccaf8e502090ecf5b3d9e9b805add6f Mon Sep 17 00:00:00 2001
+From: Selvarasu Ganesan <selvarasu.g@samsung.com>
+Date: Fri, 8 Aug 2025 18:23:05 +0530
+Subject: usb: dwc3: Remove WARN_ON for device endpoint command timeouts
+
+From: Selvarasu Ganesan <selvarasu.g@samsung.com>
+
+commit 45eae113dccaf8e502090ecf5b3d9e9b805add6f upstream.
+
+This commit addresses a rarely observed endpoint command timeout
+which causes kernel panic due to warn when 'panic_on_warn' is enabled
+and unnecessary call trace prints when 'panic_on_warn' is disabled.
+It is seen during fast software-controlled connect/disconnect testcases.
+The following is one such endpoint command timeout that we observed:
+
+1. Connect
+   =======
+->dwc3_thread_interrupt
+ ->dwc3_ep0_interrupt
+  ->configfs_composite_setup
+   ->composite_setup
+    ->usb_ep_queue
+     ->dwc3_gadget_ep0_queue
+      ->__dwc3_gadget_ep0_queue
+       ->__dwc3_ep0_do_control_data
+        ->dwc3_send_gadget_ep_cmd
+
+2. Disconnect
+   ==========
+->dwc3_thread_interrupt
+ ->dwc3_gadget_disconnect_interrupt
+  ->dwc3_ep0_reset_state
+   ->dwc3_ep0_end_control_data
+    ->dwc3_send_gadget_ep_cmd
+
+In the issue scenario, in Exynos platforms, we observed that control
+transfers for the previous connect have not yet been completed and end
+transfer command sent as a part of the disconnect sequence and
+processing of USB_ENDPOINT_HALT feature request from the host timeout.
+This maybe an expected scenario since the controller is processing EP
+commands sent as a part of the previous connect. It maybe better to
+remove WARN_ON in all places where device endpoint commands are sent to
+avoid unnecessary kernel panic due to warn.
+
+Cc: stable <stable@kernel.org>
+Co-developed-by: Akash M <akash.m5@samsung.com>
+Signed-off-by: Akash M <akash.m5@samsung.com>
+Signed-off-by: Selvarasu Ganesan <selvarasu.g@samsung.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://lore.kernel.org/r/20250808125315.1607-1-selvarasu.g@samsung.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/ep0.c    |   20 ++++++++++++++++----
+ drivers/usb/dwc3/gadget.c |   10 ++++++++--
+ 2 files changed, 24 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/dwc3/ep0.c
++++ b/drivers/usb/dwc3/ep0.c
+@@ -288,7 +288,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwc
+       dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 8,
+                       DWC3_TRBCTL_CONTROL_SETUP, false);
+       ret = dwc3_ep0_start_trans(dep);
+-      WARN_ON(ret < 0);
++      if (ret < 0)
++              dev_err(dwc->dev, "ep0 out start transfer failed: %d\n", ret);
++
+       for (i = 2; i < DWC3_ENDPOINTS_NUM; i++) {
+               struct dwc3_ep *dwc3_ep;
+@@ -1061,7 +1063,9 @@ static void __dwc3_ep0_do_control_data(s
+               ret = dwc3_ep0_start_trans(dep);
+       }
+-      WARN_ON(ret < 0);
++      if (ret < 0)
++              dev_err(dwc->dev,
++                      "ep0 data phase start transfer failed: %d\n", ret);
+ }
+ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
+@@ -1078,7 +1082,12 @@ static int dwc3_ep0_start_control_status
+ static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
+ {
+-      WARN_ON(dwc3_ep0_start_control_status(dep));
++      int     ret;
++
++      ret = dwc3_ep0_start_control_status(dep);
++      if (ret)
++              dev_err(dwc->dev,
++                      "ep0 status phase start transfer failed: %d\n", ret);
+ }
+ static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
+@@ -1121,7 +1130,10 @@ void dwc3_ep0_end_control_data(struct dw
+       cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
+       memset(&params, 0, sizeof(params));
+       ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
+-      WARN_ON_ONCE(ret);
++      if (ret)
++              dev_err_ratelimited(dwc->dev,
++                      "ep0 data phase end transfer failed: %d\n", ret);
++
+       dep->resource_index = 0;
+ }
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1774,7 +1774,11 @@ static int __dwc3_stop_active_transfer(s
+               dep->flags |= DWC3_EP_DELAY_STOP;
+               return 0;
+       }
+-      WARN_ON_ONCE(ret);
++
++      if (ret)
++              dev_err_ratelimited(dep->dwc->dev,
++                              "end transfer failed: %d\n", ret);
++
+       dep->resource_index = 0;
+       if (!interrupt)
+@@ -4050,7 +4054,9 @@ static void dwc3_clear_stall_all_ep(stru
+               dep->flags &= ~DWC3_EP_STALL;
+               ret = dwc3_send_clear_stall_ep_cmd(dep);
+-              WARN_ON_ONCE(ret);
++              if (ret)
++                      dev_err_ratelimited(dwc->dev,
++                              "failed to clear STALL on %s\n", dep->name);
+       }
+ }
diff --git a/queue-6.16/usb-quirks-add-delay_init-quick-for-another-sandisk-3.2gen1-flash-drive.patch b/queue-6.16/usb-quirks-add-delay_init-quick-for-another-sandisk-3.2gen1-flash-drive.patch
new file mode 100644 (file)
index 0000000..854028d
--- /dev/null
@@ -0,0 +1,31 @@
+From e664036cf36480414936cd91f4cfa2179a3d8367 Mon Sep 17 00:00:00 2001
+From: Miao Li <limiao@kylinos.cn>
+Date: Fri, 1 Aug 2025 16:27:28 +0800
+Subject: usb: quirks: Add DELAY_INIT quick for another SanDisk 3.2Gen1 Flash Drive
+
+From: Miao Li <limiao@kylinos.cn>
+
+commit e664036cf36480414936cd91f4cfa2179a3d8367 upstream.
+
+Another SanDisk 3.2Gen1 Flash Drive also need DELAY_INIT quick,
+or it will randomly work incorrectly on Huawei hisi platforms
+when doing reboot test.
+
+Signed-off-by: Miao Li <limiao@kylinos.cn>
+Cc: stable <stable@kernel.org>
+Link: https://lore.kernel.org/r/20250801082728.469406-1-limiao870622@163.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/quirks.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -371,6 +371,7 @@ static const struct usb_device_id usb_qu
+       { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
+       /* SanDisk Corp. SanDisk 3.2Gen1 */
++      { USB_DEVICE(0x0781, 0x5596), .driver_info = USB_QUIRK_DELAY_INIT },
+       { USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },
+       /* SanDisk Extreme 55AE */
diff --git a/queue-6.16/usb-renesas-xhci-fix-external-rom-access-timeouts.patch b/queue-6.16/usb-renesas-xhci-fix-external-rom-access-timeouts.patch
new file mode 100644 (file)
index 0000000..d8f6c1a
--- /dev/null
@@ -0,0 +1,72 @@
+From f9420f4757752f056144896024d5ea89e5a611f1 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marek.vasut+renesas@mailbox.org>
+Date: Sun, 3 Aug 2025 00:55:20 +0200
+Subject: usb: renesas-xhci: Fix External ROM access timeouts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Vasut <marek.vasut+renesas@mailbox.org>
+
+commit f9420f4757752f056144896024d5ea89e5a611f1 upstream.
+
+Increase the External ROM access timeouts to prevent failures during
+programming of External SPI EEPROM chips. The current timeouts are
+too short for some SPI EEPROMs used with uPD720201 controllers.
+
+The current timeout for Chip Erase in renesas_rom_erase() is 100 ms ,
+the current timeout for Sector Erase issued by the controller before
+Page Program in renesas_fw_download_image() is also 100 ms. Neither
+timeout is sufficient for e.g. the Macronix MX25L5121E or MX25V5126F.
+
+MX25L5121E reference manual [1] page 35 section "ERASE AND PROGRAMMING
+PERFORMANCE" and page 23 section "Table 8. AC CHARACTERISTICS (Temperature
+= 0°C to 70°C for Commercial grade, VCC = 2.7V ~ 3.6V)" row "tCE" indicate
+that the maximum time required for Chip Erase opcode to complete is 2 s,
+and for Sector Erase it is 300 ms .
+
+MX25V5126F reference manual [2] page 47 section "13. ERASE AND PROGRAMMING
+PERFORMANCE (2.3V - 3.6V)" and page 42 section "Table 8. AC CHARACTERISTICS
+(Temperature = -40°C to 85°C for Industrial grade, VCC = 2.3V - 3.6V)" row
+"tCE" indicate that the maximum time required for Chip Erase opcode to
+complete is 3.2 s, and for Sector Erase it is 400 ms .
+
+Update the timeouts such, that Chip Erase timeout is set to 5 seconds,
+and Sector Erase timeout is set to 500 ms. Such lengthy timeouts ought
+to be sufficient for majority of SPI EEPROM chips.
+
+[1] https://www.macronix.com/Lists/Datasheet/Attachments/8634/MX25L5121E,%203V,%20512Kb,%20v1.3.pdf
+[2] https://www.macronix.com/Lists/Datasheet/Attachments/8750/MX25V5126F,%202.5V,%20512Kb,%20v1.1.pdf
+
+Fixes: 2478be82de44 ("usb: renesas-xhci: Add ROM loader for uPD720201")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
+Link: https://lore.kernel.org/r/20250802225526.25431-1-marek.vasut+renesas@mailbox.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-pci-renesas.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/xhci-pci-renesas.c
++++ b/drivers/usb/host/xhci-pci-renesas.c
+@@ -47,8 +47,9 @@
+ #define RENESAS_ROM_ERASE_MAGIC                               0x5A65726F
+ #define RENESAS_ROM_WRITE_MAGIC                               0x53524F4D
+-#define RENESAS_RETRY 10000
+-#define RENESAS_DELAY 10
++#define RENESAS_RETRY                 50000   /* 50000 * RENESAS_DELAY ~= 500ms */
++#define RENESAS_CHIP_ERASE_RETRY      500000  /* 500000 * RENESAS_DELAY ~= 5s */
++#define RENESAS_DELAY                 10
+ #define RENESAS_FW_NAME       "renesas_usb_fw.mem"
+@@ -407,7 +408,7 @@ static void renesas_rom_erase(struct pci
+       /* sleep a bit while ROM is erased */
+       msleep(20);
+-      for (i = 0; i < RENESAS_RETRY; i++) {
++      for (i = 0; i < RENESAS_CHIP_ERASE_RETRY; i++) {
+               retval = pci_read_config_byte(pdev, RENESAS_ROM_STATUS,
+                                             &status);
+               status &= RENESAS_ROM_STATUS_ERASE;
diff --git a/queue-6.16/usb-storage-add-unusual-devs-entry-for-novatek-ntk96550-based-camera.patch b/queue-6.16/usb-storage-add-unusual-devs-entry-for-novatek-ntk96550-based-camera.patch
new file mode 100644 (file)
index 0000000..24e43b2
--- /dev/null
@@ -0,0 +1,54 @@
+From 6ca8af3c8fb584f3424a827f554ff74f898c27cd Mon Sep 17 00:00:00 2001
+From: Mael GUERIN <mael.guerin@murena.io>
+Date: Wed, 6 Aug 2025 18:44:03 +0200
+Subject: USB: storage: Add unusual-devs entry for Novatek NTK96550-based camera
+
+From: Mael GUERIN <mael.guerin@murena.io>
+
+commit 6ca8af3c8fb584f3424a827f554ff74f898c27cd upstream.
+
+Add the US_FL_BULK_IGNORE_TAG quirk for Novatek NTK96550-based camera
+to fix USB resets after sending SCSI vendor commands due to CBW and
+CSW tags difference, leading to undesired slowness while communicating
+with the device.
+
+Please find below the copy of /sys/kernel/debug/usb/devices with my
+device plugged in (listed as TechSys USB mass storage here, the
+underlying chipset being the Novatek NTK96550-based camera):
+
+T:  Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  3 Spd=480  MxCh= 0
+D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
+P:  Vendor=0603 ProdID=8611 Rev= 0.01
+S:  Manufacturer=TechSys
+S:  Product=USB Mass Storage
+S:  SerialNumber=966110000000100
+C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
+E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+Signed-off-by: Mael GUERIN <mael.guerin@murena.io>
+Cc: stable <stable@kernel.org>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20250806164406.43450-1-mael.guerin@murena.io
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/storage/unusual_devs.h |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -934,6 +934,13 @@ UNUSUAL_DEV(  0x05e3, 0x0723, 0x9451, 0x
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_SANE_SENSE ),
++/* Added by Maël GUERIN <mael.guerin@murena.io> */
++UNUSUAL_DEV(  0x0603, 0x8611, 0x0000, 0xffff,
++              "Novatek",
++              "NTK96550-based camera",
++              USB_SC_SCSI, USB_PR_BULK, NULL,
++              US_FL_BULK_IGNORE_TAG ),
++
+ /*
+  * Reported by Hanno Boeck <hanno@gmx.de>
+  * Taken from the Lycoris Kernel
diff --git a/queue-6.16/usb-storage-ignore-driver-cd-mode-for-realtek-multi-mode-wi-fi-dongles.patch b/queue-6.16/usb-storage-ignore-driver-cd-mode-for-realtek-multi-mode-wi-fi-dongles.patch
new file mode 100644 (file)
index 0000000..44e6015
--- /dev/null
@@ -0,0 +1,79 @@
+From a3dc32c635bae0ae569f489e00de0e8f015bfc25 Mon Sep 17 00:00:00 2001
+From: Zenm Chen <zenmchen@gmail.com>
+Date: Thu, 14 Aug 2025 00:24:15 +0800
+Subject: USB: storage: Ignore driver CD mode for Realtek multi-mode Wi-Fi dongles
+
+From: Zenm Chen <zenmchen@gmail.com>
+
+commit a3dc32c635bae0ae569f489e00de0e8f015bfc25 upstream.
+
+Many Realtek USB Wi-Fi dongles released in recent years have two modes:
+one is driver CD mode which has Windows driver onboard, another one is
+Wi-Fi mode. Add the US_FL_IGNORE_DEVICE quirk for these multi-mode devices.
+Otherwise, usb_modeswitch may fail to switch them to Wi-Fi mode.
+
+Currently there are only two USB IDs known to be used by these multi-mode
+Wi-Fi dongles: 0bda:1a2b and 0bda:a192.
+
+Information about Mercury MW310UH in /sys/kernel/debug/usb/devices.
+T:  Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 12 Spd=480  MxCh= 0
+D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
+P:  Vendor=0bda ProdID=a192 Rev= 2.00
+S:  Manufacturer=Realtek
+S:  Product=DISK
+C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none)
+E:  Ad=8a(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+Information about D-Link AX9U rev. A1 in /sys/kernel/debug/usb/devices.
+T:  Bus=03 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 55 Spd=480  MxCh= 0
+D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
+P:  Vendor=0bda ProdID=1a2b Rev= 0.00
+S:  Manufacturer=Realtek
+S:  Product=DISK
+C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none)
+E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+Cc: stable <stable@kernel.org>
+Signed-off-by: Zenm Chen <zenmchen@gmail.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20250813162415.2630-1-zenmchen@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/storage/unusual_devs.h |   22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1501,6 +1501,28 @@ UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_WP_DETECT ),
++/*
++ * Reported by Zenm Chen <zenmchen@gmail.com>
++ * Ignore driver CD mode, otherwise usb_modeswitch may fail to switch
++ * the device into Wi-Fi mode.
++ */
++UNUSUAL_DEV( 0x0bda, 0x1a2b, 0x0000, 0xffff,
++              "Realtek",
++              "DISK",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++              US_FL_IGNORE_DEVICE ),
++
++/*
++ * Reported by Zenm Chen <zenmchen@gmail.com>
++ * Ignore driver CD mode, otherwise usb_modeswitch may fail to switch
++ * the device into Wi-Fi mode.
++ */
++UNUSUAL_DEV( 0x0bda, 0xa192, 0x0000, 0xffff,
++              "Realtek",
++              "DISK",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++              US_FL_IGNORE_DEVICE ),
++
+ UNUSUAL_DEV(  0x0d49, 0x7310, 0x0000, 0x9999,
+               "Maxtor",
+               "USB to SATA",
diff --git a/queue-6.16/usb-storage-realtek_cr-use-correct-byte-order-for-bcs-residue.patch b/queue-6.16/usb-storage-realtek_cr-use-correct-byte-order-for-bcs-residue.patch
new file mode 100644 (file)
index 0000000..61442e8
--- /dev/null
@@ -0,0 +1,35 @@
+From 98da66a70ad2396e5a508c4245367797ebc052ce Mon Sep 17 00:00:00 2001
+From: Thorsten Blum <thorsten.blum@linux.dev>
+Date: Wed, 13 Aug 2025 16:52:49 +0200
+Subject: usb: storage: realtek_cr: Use correct byte order for bcs->Residue
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+commit 98da66a70ad2396e5a508c4245367797ebc052ce upstream.
+
+Since 'bcs->Residue' has the data type '__le32', convert it to the
+correct byte order of the CPU using this driver when assigning it to
+the local variable 'residue'.
+
+Cc: stable <stable@kernel.org>
+Fixes: 50a6cb932d5c ("USB: usb_storage: add ums-realtek driver")
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Link: https://lore.kernel.org/r/20250813145247.184717-3-thorsten.blum@linux.dev
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/storage/realtek_cr.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/storage/realtek_cr.c
++++ b/drivers/usb/storage/realtek_cr.c
+@@ -252,7 +252,7 @@ static int rts51x_bulk_transport(struct
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+-      residue = bcs->Residue;
++      residue = le32_to_cpu(bcs->Residue);
+       if (bcs->Tag != us->tag)
+               return USB_STOR_TRANSPORT_ERROR;
diff --git a/queue-6.16/usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch b/queue-6.16/usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch
new file mode 100644 (file)
index 0000000..5a26349
--- /dev/null
@@ -0,0 +1,53 @@
+From cabb6c5f4d9e7f49bdf8c0a13c74bd93ee35f45a Mon Sep 17 00:00:00 2001
+From: Amit Sunil Dhamne <amitsd@google.com>
+Date: Fri, 15 Aug 2025 11:31:51 -0700
+Subject: usb: typec: maxim_contaminant: disable low power mode when reading comparator values
+
+From: Amit Sunil Dhamne <amitsd@google.com>
+
+commit cabb6c5f4d9e7f49bdf8c0a13c74bd93ee35f45a upstream.
+
+Low power mode is enabled when reading CC resistance as part of
+`max_contaminant_read_resistance_kohm()` and left in that state.
+However, it's supposed to work with 1uA current source. To read CC
+comparator values current source is changed to 80uA. This causes a storm
+of CC interrupts as it (falsely) detects a potential contaminant. To
+prevent this, disable low power mode current sourcing before reading
+comparator values.
+
+Fixes: 02b332a06397 ("usb: typec: maxim_contaminant: Implement check_contaminant callback")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
+Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
+Link: https://lore.kernel.org/stable/20250814-fix-upstream-contaminant-v1-1-801ce8089031%40google.com
+Link: https://lore.kernel.org/r/20250815-fix-upstream-contaminant-v2-1-6c8d6c3adafb@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/maxim_contaminant.c |    5 +++++
+ drivers/usb/typec/tcpm/tcpci_maxim.h       |    1 +
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/usb/typec/tcpm/maxim_contaminant.c
++++ b/drivers/usb/typec/tcpm/maxim_contaminant.c
+@@ -188,6 +188,11 @@ static int max_contaminant_read_comparat
+       if (ret < 0)
+               return ret;
++      /* Disable low power mode */
++      ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL,
++                               FIELD_PREP(CCLPMODESEL,
++                                          LOW_POWER_MODE_DISABLE));
++
+       /* Sleep to allow comparators settle */
+       usleep_range(5000, 6000);
+       ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL, TCPC_TCPC_CTRL_ORIENTATION, PLUG_ORNT_CC1);
+--- a/drivers/usb/typec/tcpm/tcpci_maxim.h
++++ b/drivers/usb/typec/tcpm/tcpci_maxim.h
+@@ -21,6 +21,7 @@
+ #define CCOVPDIS                                BIT(6)
+ #define SBURPCTRL                               BIT(5)
+ #define CCLPMODESEL                             GENMASK(4, 3)
++#define LOW_POWER_MODE_DISABLE                  0
+ #define ULTRA_LOW_POWER_MODE                    1
+ #define CCRPCTRL                                GENMASK(2, 0)
+ #define UA_1_SRC                                1
diff --git a/queue-6.16/usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch b/queue-6.16/usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch
new file mode 100644 (file)
index 0000000..15bf09d
--- /dev/null
@@ -0,0 +1,117 @@
+From a381c6d6f646226924809d0ad01a9465786da463 Mon Sep 17 00:00:00 2001
+From: Amit Sunil Dhamne <amitsd@google.com>
+Date: Fri, 15 Aug 2025 11:31:52 -0700
+Subject: usb: typec: maxim_contaminant: re-enable cc toggle if cc is open and port is clean
+
+From: Amit Sunil Dhamne <amitsd@google.com>
+
+commit a381c6d6f646226924809d0ad01a9465786da463 upstream.
+
+Presently in `max_contaminant_is_contaminant()` if there's no
+contaminant detected previously, CC is open & stopped toggling and no
+contaminant is currently present, TCPC.RC would be programmed to do DRP
+toggling. However, it didn't actively look for a connection. This would
+lead to Type-C not detect *any* new connections. Hence, in the above
+situation, re-enable toggling & program TCPC to look for a new
+connection.
+
+Also, return early if TCPC was looking for connection as this indicates
+TCPC has neither detected a potential connection nor a change in
+contaminant state.
+
+In addition, once dry detection is complete (port is dry), restart
+toggling.
+
+Fixes: 02b332a06397e ("usb: typec: maxim_contaminant: Implement check_contaminant callback")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
+Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
+Link: https://lore.kernel.org/r/20250815-fix-upstream-contaminant-v2-2-6c8d6c3adafb@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/maxim_contaminant.c |   53 +++++++++++++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+
+--- a/drivers/usb/typec/tcpm/maxim_contaminant.c
++++ b/drivers/usb/typec/tcpm/maxim_contaminant.c
+@@ -329,6 +329,39 @@ static int max_contaminant_enable_dry_de
+       return 0;
+ }
++static int max_contaminant_enable_toggling(struct max_tcpci_chip *chip)
++{
++      struct regmap *regmap = chip->data.regmap;
++      int ret;
++
++      /* Disable dry detection if enabled. */
++      ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL,
++                               FIELD_PREP(CCLPMODESEL,
++                                          LOW_POWER_MODE_DISABLE));
++      if (ret)
++              return ret;
++
++      ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL1, CCCONNDRY, 0);
++      if (ret)
++              return ret;
++
++      ret = max_tcpci_write8(chip, TCPC_ROLE_CTRL, TCPC_ROLE_CTRL_DRP |
++                             FIELD_PREP(TCPC_ROLE_CTRL_CC1,
++                                        TCPC_ROLE_CTRL_CC_RD) |
++                             FIELD_PREP(TCPC_ROLE_CTRL_CC2,
++                                        TCPC_ROLE_CTRL_CC_RD));
++      if (ret)
++              return ret;
++
++      ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL,
++                               TCPC_TCPC_CTRL_EN_LK4CONN_ALRT,
++                               TCPC_TCPC_CTRL_EN_LK4CONN_ALRT);
++      if (ret)
++              return ret;
++
++      return max_tcpci_write8(chip, TCPC_COMMAND, TCPC_CMD_LOOK4CONNECTION);
++}
++
+ bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect_while_debounce,
+                                   bool *cc_handled)
+ {
+@@ -345,6 +378,12 @@ bool max_contaminant_is_contaminant(stru
+       if (ret < 0)
+               return false;
++      if (cc_status & TCPC_CC_STATUS_TOGGLING) {
++              if (chip->contaminant_state == DETECTED)
++                      return true;
++              return false;
++      }
++
+       if (chip->contaminant_state == NOT_DETECTED || chip->contaminant_state == SINK) {
+               if (!disconnect_while_debounce)
+                       msleep(100);
+@@ -377,6 +416,12 @@ bool max_contaminant_is_contaminant(stru
+                               max_contaminant_enable_dry_detection(chip);
+                               return true;
+                       }
++
++                      ret = max_contaminant_enable_toggling(chip);
++                      if (ret)
++                              dev_err(chip->dev,
++                                      "Failed to enable toggling, ret=%d",
++                                      ret);
+               }
+       } else if (chip->contaminant_state == DETECTED) {
+               if (!(cc_status & TCPC_CC_STATUS_TOGGLING)) {
+@@ -384,6 +429,14 @@ bool max_contaminant_is_contaminant(stru
+                       if (chip->contaminant_state == DETECTED) {
+                               max_contaminant_enable_dry_detection(chip);
+                               return true;
++                      } else {
++                              ret = max_contaminant_enable_toggling(chip);
++                              if (ret) {
++                                      dev_err(chip->dev,
++                                              "Failed to enable toggling, ret=%d",
++                                              ret);
++                                      return true;
++                              }
+                       }
+               }
+       }
diff --git a/queue-6.16/usb-xhci-fix-host-not-responding-after-suspend-and-resume.patch b/queue-6.16/usb-xhci-fix-host-not-responding-after-suspend-and-resume.patch
new file mode 100644 (file)
index 0000000..2c3368c
--- /dev/null
@@ -0,0 +1,57 @@
+From ff9a09b3e09c7b794b56f2f5858f5ce42ba46cb3 Mon Sep 17 00:00:00 2001
+From: Niklas Neronin <niklas.neronin@linux.intel.com>
+Date: Tue, 19 Aug 2025 15:58:44 +0300
+Subject: usb: xhci: fix host not responding after suspend and resume
+
+From: Niklas Neronin <niklas.neronin@linux.intel.com>
+
+commit ff9a09b3e09c7b794b56f2f5858f5ce42ba46cb3 upstream.
+
+Partially revert commit e1db856bd288 ("usb: xhci: remove '0' write to
+write-1-to-clear register") because the patch cleared the Interrupt Pending
+bit during interrupt enabling and disabling. The Interrupt Pending bit
+should only be cleared when the driver has handled the interrupt.
+
+Ideally, all interrupts should be handled before disabling the interrupt;
+consequently, no interrupt should be pending when enabling the interrupt.
+For this reason, keep the debug message informing if an interrupt is still
+pending when an interrupt is disabled.
+
+Because the Interrupt Pending bit is write-1-to-clear, writing '0' to it
+ensures that the state does not change.
+
+Link: https://lore.kernel.org/linux-usb/20250818231103.672ec7ed@foxbook
+Fixes: e1db856bd288 ("usb: xhci: remove '0' write to write-1-to-clear register")
+Closes: https://bbs.archlinux.org/viewtopic.php?id=307641
+cc: stable@vger.kernel.org # 6.16+
+Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20250819125844.2042452-3-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 0e03691f03bf..742c23826e17 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -309,6 +309,7 @@ int xhci_enable_interrupter(struct xhci_interrupter *ir)
+               return -EINVAL;
+       iman = readl(&ir->ir_set->iman);
++      iman &= ~IMAN_IP;
+       iman |= IMAN_IE;
+       writel(iman, &ir->ir_set->iman);
+@@ -325,6 +326,7 @@ int xhci_disable_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
+               return -EINVAL;
+       iman = readl(&ir->ir_set->iman);
++      iman &= ~IMAN_IP;
+       iman &= ~IMAN_IE;
+       writel(iman, &ir->ir_set->iman);
+-- 
+2.50.1
+
diff --git a/queue-6.16/usb-xhci-fix-slot_id-resource-race-conflict.patch b/queue-6.16/usb-xhci-fix-slot_id-resource-race-conflict.patch
new file mode 100644 (file)
index 0000000..1a879a5
--- /dev/null
@@ -0,0 +1,221 @@
+From 2eb03376151bb8585caa23ed2673583107bb5193 Mon Sep 17 00:00:00 2001
+From: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
+Date: Tue, 19 Aug 2025 15:58:43 +0300
+Subject: usb: xhci: Fix slot_id resource race conflict
+
+From: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
+
+commit 2eb03376151bb8585caa23ed2673583107bb5193 upstream.
+
+xHC controller may immediately reuse a slot_id after it's disabled,
+giving it to a new enumerating device before the xhci driver freed
+all resources related to the disabled device.
+
+In such a scenario, device-A with slot_id equal to 1 is disconnecting
+while device-B is enumerating, device-B will fail to enumerate in the
+follow sequence.
+
+1.[device-A] send disable slot command
+2.[device-B] send enable slot command
+3.[device-A] disable slot command completed and wakeup waiting thread
+4.[device-B] enable slot command completed with slot_id equal to 1 and
+            wakeup waiting thread
+5.[device-B] driver checks that slot_id is still in use (by device-A) in
+            xhci_alloc_virt_device, and fail to enumerate due to this
+            conflict
+6.[device-A] xhci->devs[slot_id] set to NULL in xhci_free_virt_device
+
+To fix driver's slot_id resources conflict, clear xhci->devs[slot_id] and
+xhci->dcbba->dev_context_ptrs[slot_id] pointers in the interrupt context
+when disable slot command completes successfully. Simultaneously, adjust
+function xhci_free_virt_device to accurately handle device release.
+
+[minor smatch warning and commit message fix -Mathias]
+
+Cc: stable@vger.kernel.org
+Fixes: 7faac1953ed1 ("xhci: avoid race between disable slot command and host runtime suspend")
+Signed-off-by: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20250819125844.2042452-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-hub.c  |    3 +--
+ drivers/usb/host/xhci-mem.c  |   22 +++++++++++-----------
+ drivers/usb/host/xhci-ring.c |    9 +++++++--
+ drivers/usb/host/xhci.c      |   21 ++++++++++++++-------
+ drivers/usb/host/xhci.h      |    3 ++-
+ 5 files changed, 35 insertions(+), 23 deletions(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -704,8 +704,7 @@ static int xhci_enter_test_mode(struct x
+               if (!xhci->devs[i])
+                       continue;
+-              retval = xhci_disable_slot(xhci, i);
+-              xhci_free_virt_device(xhci, i);
++              retval = xhci_disable_and_free_slot(xhci, i);
+               if (retval)
+                       xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n",
+                                i, retval);
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -865,21 +865,20 @@ free_tts:
+  * will be manipulated by the configure endpoint, allocate device, or update
+  * hub functions while this function is removing the TT entries from the list.
+  */
+-void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
++void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev,
++              int slot_id)
+ {
+-      struct xhci_virt_device *dev;
+       int i;
+       int old_active_eps = 0;
+       /* Slot ID 0 is reserved */
+-      if (slot_id == 0 || !xhci->devs[slot_id])
++      if (slot_id == 0 || !dev)
+               return;
+-      dev = xhci->devs[slot_id];
+-
+-      xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
+-      if (!dev)
+-              return;
++      /* If device ctx array still points to _this_ device, clear it */
++      if (dev->out_ctx &&
++          xhci->dcbaa->dev_context_ptrs[slot_id] == cpu_to_le64(dev->out_ctx->dma))
++              xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
+       trace_xhci_free_virt_device(dev);
+@@ -920,8 +919,9 @@ void xhci_free_virt_device(struct xhci_h
+               dev->udev->slot_id = 0;
+       if (dev->rhub_port && dev->rhub_port->slot_id == slot_id)
+               dev->rhub_port->slot_id = 0;
+-      kfree(xhci->devs[slot_id]);
+-      xhci->devs[slot_id] = NULL;
++      if (xhci->devs[slot_id] == dev)
++              xhci->devs[slot_id] = NULL;
++      kfree(dev);
+ }
+ /*
+@@ -962,7 +962,7 @@ static void xhci_free_virt_devices_depth
+ out:
+       /* we are now at a leaf device */
+       xhci_debugfs_remove_slot(xhci, slot_id);
+-      xhci_free_virt_device(xhci, slot_id);
++      xhci_free_virt_device(xhci, vdev, slot_id);
+ }
+ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1592,7 +1592,8 @@ static void xhci_handle_cmd_enable_slot(
+               command->slot_id = 0;
+ }
+-static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)
++static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id,
++                                      u32 cmd_comp_code)
+ {
+       struct xhci_virt_device *virt_dev;
+       struct xhci_slot_ctx *slot_ctx;
+@@ -1607,6 +1608,10 @@ static void xhci_handle_cmd_disable_slot
+       if (xhci->quirks & XHCI_EP_LIMIT_QUIRK)
+               /* Delete default control endpoint resources */
+               xhci_free_device_endpoint_resources(xhci, virt_dev, true);
++      if (cmd_comp_code == COMP_SUCCESS) {
++              xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
++              xhci->devs[slot_id] = NULL;
++      }
+ }
+ static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id)
+@@ -1856,7 +1861,7 @@ static void handle_cmd_completion(struct
+               xhci_handle_cmd_enable_slot(slot_id, cmd, cmd_comp_code);
+               break;
+       case TRB_DISABLE_SLOT:
+-              xhci_handle_cmd_disable_slot(xhci, slot_id);
++              xhci_handle_cmd_disable_slot(xhci, slot_id, cmd_comp_code);
+               break;
+       case TRB_CONFIG_EP:
+               if (!cmd->completion)
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -3932,8 +3932,7 @@ static int xhci_discover_or_reset_device
+                * Obtaining a new device slot to inform the xHCI host that
+                * the USB device has been reset.
+                */
+-              ret = xhci_disable_slot(xhci, udev->slot_id);
+-              xhci_free_virt_device(xhci, udev->slot_id);
++              ret = xhci_disable_and_free_slot(xhci, udev->slot_id);
+               if (!ret) {
+                       ret = xhci_alloc_dev(hcd, udev);
+                       if (ret == 1)
+@@ -4090,7 +4089,7 @@ static void xhci_free_dev(struct usb_hcd
+       xhci_disable_slot(xhci, udev->slot_id);
+       spin_lock_irqsave(&xhci->lock, flags);
+-      xhci_free_virt_device(xhci, udev->slot_id);
++      xhci_free_virt_device(xhci, virt_dev, udev->slot_id);
+       spin_unlock_irqrestore(&xhci->lock, flags);
+ }
+@@ -4139,6 +4138,16 @@ int xhci_disable_slot(struct xhci_hcd *x
+       return 0;
+ }
++int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id)
++{
++      struct xhci_virt_device *vdev = xhci->devs[slot_id];
++      int ret;
++
++      ret = xhci_disable_slot(xhci, slot_id);
++      xhci_free_virt_device(xhci, vdev, slot_id);
++      return ret;
++}
++
+ /*
+  * Checks if we have enough host controller resources for the default control
+  * endpoint.
+@@ -4245,8 +4254,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd,
+       return 1;
+ disable_slot:
+-      xhci_disable_slot(xhci, udev->slot_id);
+-      xhci_free_virt_device(xhci, udev->slot_id);
++      xhci_disable_and_free_slot(xhci, udev->slot_id);
+       return 0;
+ }
+@@ -4382,8 +4390,7 @@ static int xhci_setup_device(struct usb_
+               dev_warn(&udev->dev, "Device not responding to setup %s.\n", act);
+               mutex_unlock(&xhci->mutex);
+-              ret = xhci_disable_slot(xhci, udev->slot_id);
+-              xhci_free_virt_device(xhci, udev->slot_id);
++              ret = xhci_disable_and_free_slot(xhci, udev->slot_id);
+               if (!ret) {
+                       if (xhci_alloc_dev(hcd, udev) == 1)
+                               xhci_setup_addressable_virt_dev(xhci, udev);
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1791,7 +1791,7 @@ void xhci_dbg_trace(struct xhci_hcd *xhc
+ /* xHCI memory management */
+ void xhci_mem_cleanup(struct xhci_hcd *xhci);
+ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags);
+-void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id);
++void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, int slot_id);
+ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags);
+ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev);
+ void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
+@@ -1888,6 +1888,7 @@ void xhci_reset_bandwidth(struct usb_hcd
+ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
+                          struct usb_tt *tt, gfp_t mem_flags);
+ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
++int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id);
+ int xhci_ext_cap_init(struct xhci_hcd *xhci);
+ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);