From: Greg Kroah-Hartman Date: Sat, 23 Aug 2025 16:02:04 +0000 (+0200) Subject: 6.16-stable patches X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;ds=sidebyside;p=thirdparty%2Fkernel%2Fstable-queue.git 6.16-stable patches 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 --- 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 index 0000000000..08e76e019c --- /dev/null +++ b/queue-6.16/cdx-fix-off-by-one-error-in-cdx_rpmsg_probe.patch @@ -0,0 +1,38 @@ +From 300a0cfe9f375b2843bcb331bcfa7503475ef5dd Mon Sep 17 00:00:00 2001 +From: Thorsten Blum +Date: Wed, 6 Aug 2025 11:05:09 +0200 +Subject: cdx: Fix off-by-one error in cdx_rpmsg_probe() + +From: Thorsten Blum + +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 +Fixes: 2a226927d9b8 ("cdx: add rpmsg communication channel for CDX") +Signed-off-by: Thorsten Blum +Link: https://lore.kernel.org/r/20250806090512.121260-2-thorsten.blum@linux.dev +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..57fb30c363 --- /dev/null +++ b/queue-6.16/comedi-fix-use-of-uninitialized-memory-in-do_insn_ioctl-and-do_insnlist_ioctl.patch @@ -0,0 +1,72 @@ +From 3cd212e895ca2d58963fdc6422502b10dd3966bb Mon Sep 17 00:00:00 2001 +From: Ian Abbott +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 + +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 # 5.13+ +Cc: Arnaud Lecomte +Signed-off-by: Ian Abbott +Link: https://lore.kernel.org/r/20250725125324.80276-1-abbotti@mev.co.uk +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..d3a37bb1a9 --- /dev/null +++ b/queue-6.16/comedi-make-insn_rw_emulate_bits-do-insn-n-samples.patch @@ -0,0 +1,82 @@ +From 7afba9221f70d4cbce0f417c558879cba0eb5e66 Mon Sep 17 00:00:00 2001 +From: Ian Abbott +Date: Fri, 25 Jul 2025 15:10:34 +0100 +Subject: comedi: Make insn_rw_emulate_bits() do insn->n samples + +From: Ian Abbott + +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 # 5.13+ +Signed-off-by: Ian Abbott +Link: https://lore.kernel.org/r/20250725141034.87297-1-abbotti@mev.co.uk +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..f307ab6d9e --- /dev/null +++ b/queue-6.16/comedi-pcl726-prevent-invalid-irq-number.patch @@ -0,0 +1,50 @@ +From 96cb948408b3adb69df7e451ba7da9d21f814d00 Mon Sep 17 00:00:00 2001 +From: Edward Adam Davis +Date: Mon, 7 Jul 2025 20:39:58 +0800 +Subject: comedi: pcl726: Prevent invalid irq number + +From: Edward Adam Davis + +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 # 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 +Reviewed-by: Ian Abbott +Link: https://lore.kernel.org/r/tencent_3C66983CC1369E962436264A50759176BF09@qq.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..fcfc940c0f --- /dev/null +++ b/queue-6.16/ftrace-also-allocate-and-copy-hash-for-reading-of-filter-files.patch @@ -0,0 +1,75 @@ +From bfb336cf97df7b37b2b2edec0f69773e06d11955 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Fri, 22 Aug 2025 18:36:06 -0400 +Subject: ftrace: Also allocate and copy hash for reading of filter files + +From: Steven Rostedt + +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 +Cc: Mathieu Desnoyers +Cc: Nathan Chancellor +Cc: Linus Torvalds +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 +Tested-by: Tengda Wu +Tested-by: Nathan Chancellor +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..05f4e0708a --- /dev/null +++ b/queue-6.16/iio-adc-ad7124-fix-channel-lookup-in-syscalib-functions.patch @@ -0,0 +1,83 @@ +From 197e299aae42ffa19028eaea92b2f30dd9fb8445 Mon Sep 17 00:00:00 2001 +From: David Lechner +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 + +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 +Reviewed-by: Nuno Sá +Link: https://patch.msgid.link/20250726-iio-adc-ad7124-fix-channel-lookup-in-syscalib-v1-1-b9d14bb684af@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..1ece8b82da --- /dev/null +++ b/queue-6.16/iio-adc-ad7173-prevent-scan-if-too-many-setups-requested.patch @@ -0,0 +1,170 @@ +From 1cfb22c277c7274f54babaa5b416dfbc00181e16 Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Tue, 22 Jul 2025 14:20:07 -0500 +Subject: iio: adc: ad7173: prevent scan if too many setups requested + +From: David Lechner + +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 +Link: https://patch.msgid.link/20250722-iio-adc-ad7173-fix-setup-use-limits-v2-1-8e96bdb72a9c@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..8b08365907 --- /dev/null +++ b/queue-6.16/iio-adc-bd79124-add-gpiolib-dependency.patch @@ -0,0 +1,47 @@ +From 8a6ededaad2d2dcaac8e545bffee1073dca9db95 Mon Sep 17 00:00:00 2001 +From: Matti Vaittinen +Date: Wed, 13 Aug 2025 12:16:06 +0300 +Subject: iio: adc: bd79124: Add GPIOLIB dependency + +From: Matti Vaittinen + +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 +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 +Reviewed-by: Bartosz Golaszewski +Link: https://patch.msgid.link/6837249bddf358924e67566293944506206d2d62.1755076369.git.mazziesaccount@gmail.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..b9a6a88a5b --- /dev/null +++ b/queue-6.16/iio-adc-rzg2l-cleanup-suspend-resume-path.patch @@ -0,0 +1,100 @@ +From a3c6eabe3bbd6b0e7124d68b2d3bc32fed17362e Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea +Date: Sun, 10 Aug 2025 15:33:27 +0300 +Subject: iio: adc: rzg2l: Cleanup suspend/resume path + +From: Claudiu Beznea + +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 +Reviewed-by: Lad Prabhakar +Signed-off-by: Claudiu Beznea +Link: https://patch.msgid.link/20250810123328.800104-2-claudiu.beznea.uj@bp.renesas.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..953a9745a0 --- /dev/null +++ b/queue-6.16/iio-adc-rzg2l_adc-set-driver-data-before-enabling-runtime-pm.patch @@ -0,0 +1,47 @@ +From c69e13965f26b8058f538ea8bdbd2d7718cf1fbe Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea +Date: Sun, 10 Aug 2025 15:33:28 +0300 +Subject: iio: adc: rzg2l_adc: Set driver data before enabling runtime PM + +From: Claudiu Beznea + +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 +Link: https://patch.msgid.link/20250810123328.800104-3-claudiu.beznea.uj@bp.renesas.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..f155f916d3 --- /dev/null +++ b/queue-6.16/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch @@ -0,0 +1,34 @@ +From 433b99e922943efdfd62b9a8e3ad1604838181f2 Mon Sep 17 00:00:00 2001 +From: Jonathan Cameron +Date: Sat, 2 Aug 2025 17:44:21 +0100 +Subject: iio: light: as73211: Ensure buffer holes are zeroed + +From: Jonathan Cameron + +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 +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20250802164436.515988-2-jic23@kernel.org +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..3741f57631 --- /dev/null +++ b/queue-6.16/iio-pressure-bmp280-use-is_err-in-bmp280_common_probe.patch @@ -0,0 +1,43 @@ +From 43c0f6456f801181a80b73d95def0e0fd134e1cc Mon Sep 17 00:00:00 2001 +From: Salah Triki +Date: Mon, 18 Aug 2025 10:27:30 +0100 +Subject: iio: pressure: bmp280: Use IS_ERR() in bmp280_common_probe() + +From: Salah Triki + +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 +Reviewed-by: David Lechner +Link: https://patch.msgid.link/20250818092740.545379-2-salah.triki@gmail.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..7a68584f3d --- /dev/null +++ b/queue-6.16/iio-proximity-isl29501-fix-buffered-read-on-big-endian-systems.patch @@ -0,0 +1,52 @@ +From de18e978d0cda23e4c102e18092b63a5b0b3a800 Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Tue, 22 Jul 2025 15:54:21 -0500 +Subject: iio: proximity: isl29501: fix buffered read on big-endian systems + +From: David Lechner + +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 +Link: https://patch.msgid.link/20250722-iio-use-more-iio_declare_buffer_with_ts-7-v2-1-d3ebeb001ed3@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..06accd3465 --- /dev/null +++ b/queue-6.16/iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch @@ -0,0 +1,93 @@ +From ae5bc07ec9f73a41734270ef3f800c5c8a7e0ad3 Mon Sep 17 00:00:00 2001 +From: David Lechner +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 + +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 +Reviewed-by: Nuno Sá +Link: https://patch.msgid.link/20250721-iio-use-more-iio_declare_buffer_with_ts-3-v2-1-0c68d41ccf6c@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + #include + #include + #include +@@ -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 index 0000000000..5da74db9b5 --- /dev/null +++ b/queue-6.16/kcov-usb-don-t-disable-interrupts-in-kcov_remote_start_usb_softirq.patch @@ -0,0 +1,143 @@ +From 9528d32873b38281ae105f2f5799e79ae9d086c2 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +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 + +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 +Reported-by: Yunseong Kim +Closes: https://lore.kernel.org/all/20250725201400.1078395-2-ysk@kzalloc.com/ +Tested-by: Yunseong Kim +Signed-off-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/r/20250811082745.ycJqBXMs@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..b22824fea4 --- /dev/null +++ b/queue-6.16/most-core-drop-device-reference-after-usage-in-get_channel.patch @@ -0,0 +1,34 @@ +From b47b493d6387ae437098112936f32be27f73516c Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Mon, 4 Aug 2025 12:29:55 +0400 +Subject: most: core: Drop device reference after usage in get_channel() + +From: Miaoqian Lin + +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 +Signed-off-by: Miaoqian Lin +Link: https://lore.kernel.org/r/20250804082955.3621026-1-linmq006@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-6.16/series b/queue-6.16/series index 132ada9f7c..186722dfe8 100644 --- a/queue-6.16/series +++ b/queue-6.16/series @@ -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 index 0000000000..61ef7e1ac9 --- /dev/null +++ b/queue-6.16/usb-core-hcd-fix-accessing-unmapped-memory-in-single_step_set_feature-test.patch @@ -0,0 +1,58 @@ +From 8fe06185e11ae753414aa6117f0e798aa77567ff Mon Sep 17 00:00:00 2001 +From: Xu Yang +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 + +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 +Reviewed-by: Jun Li +Signed-off-by: Xu Yang +Acked-by: Alan Stern +Link: https://lore.kernel.org/r/20250806083955.3325299-1-xu.yang_2@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..45ae10a139 --- /dev/null +++ b/queue-6.16/usb-dwc3-ignore-late-xfernotready-event-to-prevent-halt-timeout.patch @@ -0,0 +1,46 @@ +From 58577118cc7cec9eb7c1836bf88f865ff2c5e3a3 Mon Sep 17 00:00:00 2001 +From: Kuen-Han Tsai +Date: Thu, 7 Aug 2025 17:06:55 +0800 +Subject: usb: dwc3: Ignore late xferNotReady event to prevent halt timeout + +From: Kuen-Han Tsai + +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 +Signed-off-by: Kuen-Han Tsai +Acked-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20250807090700.2397190-1-khtsai@google.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..4a95cde51b --- /dev/null +++ b/queue-6.16/usb-dwc3-pci-add-support-for-the-intel-wildcat-lake.patch @@ -0,0 +1,38 @@ +From 86f390ba59cd8d5755bafe2b163c3e6b89d6bbd9 Mon Sep 17 00:00:00 2001 +From: Heikki Krogerus +Date: Tue, 12 Aug 2025 16:11:00 +0300 +Subject: usb: dwc3: pci: add support for the Intel Wildcat Lake + +From: Heikki Krogerus + +commit 86f390ba59cd8d5755bafe2b163c3e6b89d6bbd9 upstream. + +This patch adds the necessary PCI ID for Intel Wildcat Lake +devices. + +Signed-off-by: Heikki Krogerus +Cc: stable +Link: https://lore.kernel.org/r/20250812131101.2930199-1-heikki.krogerus@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..2d99bb2eb9 --- /dev/null +++ b/queue-6.16/usb-dwc3-remove-warn_on-for-device-endpoint-command-timeouts.patch @@ -0,0 +1,133 @@ +From 45eae113dccaf8e502090ecf5b3d9e9b805add6f Mon Sep 17 00:00:00 2001 +From: Selvarasu Ganesan +Date: Fri, 8 Aug 2025 18:23:05 +0530 +Subject: usb: dwc3: Remove WARN_ON for device endpoint command timeouts + +From: Selvarasu Ganesan + +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 +Co-developed-by: Akash M +Signed-off-by: Akash M +Signed-off-by: Selvarasu Ganesan +Acked-by: Thinh Nguyen +Reviewed-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/r/20250808125315.1607-1-selvarasu.g@samsung.com +Signed-off-by: Greg Kroah-Hartman +--- + 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(¶ms, 0, sizeof(params)); + ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); +- 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 index 0000000000..854028db6a --- /dev/null +++ b/queue-6.16/usb-quirks-add-delay_init-quick-for-another-sandisk-3.2gen1-flash-drive.patch @@ -0,0 +1,31 @@ +From e664036cf36480414936cd91f4cfa2179a3d8367 Mon Sep 17 00:00:00 2001 +From: Miao Li +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 + +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 +Cc: stable +Link: https://lore.kernel.org/r/20250801082728.469406-1-limiao870622@163.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..d8f6c1ad86 --- /dev/null +++ b/queue-6.16/usb-renesas-xhci-fix-external-rom-access-timeouts.patch @@ -0,0 +1,72 @@ +From f9420f4757752f056144896024d5ea89e5a611f1 Mon Sep 17 00:00:00 2001 +From: Marek Vasut +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 + +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 +Signed-off-by: Marek Vasut +Link: https://lore.kernel.org/r/20250802225526.25431-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..24e43b2cf0 --- /dev/null +++ b/queue-6.16/usb-storage-add-unusual-devs-entry-for-novatek-ntk96550-based-camera.patch @@ -0,0 +1,54 @@ +From 6ca8af3c8fb584f3424a827f554ff74f898c27cd Mon Sep 17 00:00:00 2001 +From: Mael GUERIN +Date: Wed, 6 Aug 2025 18:44:03 +0200 +Subject: USB: storage: Add unusual-devs entry for Novatek NTK96550-based camera + +From: Mael GUERIN + +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 +Cc: stable +Acked-by: Alan Stern +Link: https://lore.kernel.org/r/20250806164406.43450-1-mael.guerin@murena.io +Signed-off-by: Greg Kroah-Hartman +--- + 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 */ ++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 + * 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 index 0000000000..44e6015c02 --- /dev/null +++ b/queue-6.16/usb-storage-ignore-driver-cd-mode-for-realtek-multi-mode-wi-fi-dongles.patch @@ -0,0 +1,79 @@ +From a3dc32c635bae0ae569f489e00de0e8f015bfc25 Mon Sep 17 00:00:00 2001 +From: Zenm Chen +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 + +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 +Signed-off-by: Zenm Chen +Acked-by: Alan Stern +Link: https://lore.kernel.org/r/20250813162415.2630-1-zenmchen@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++ * 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 ++ * 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 index 0000000000..61442e8032 --- /dev/null +++ b/queue-6.16/usb-storage-realtek_cr-use-correct-byte-order-for-bcs-residue.patch @@ -0,0 +1,35 @@ +From 98da66a70ad2396e5a508c4245367797ebc052ce Mon Sep 17 00:00:00 2001 +From: Thorsten Blum +Date: Wed, 13 Aug 2025 16:52:49 +0200 +Subject: usb: storage: realtek_cr: Use correct byte order for bcs->Residue + +From: Thorsten Blum + +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 +Fixes: 50a6cb932d5c ("USB: usb_storage: add ums-realtek driver") +Suggested-by: Alan Stern +Acked-by: Alan Stern +Signed-off-by: Thorsten Blum +Link: https://lore.kernel.org/r/20250813145247.184717-3-thorsten.blum@linux.dev +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..5a2634922a --- /dev/null +++ b/queue-6.16/usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch @@ -0,0 +1,53 @@ +From cabb6c5f4d9e7f49bdf8c0a13c74bd93ee35f45a Mon Sep 17 00:00:00 2001 +From: Amit Sunil Dhamne +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 + +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 +Signed-off-by: Amit Sunil Dhamne +Reviewed-by: Badhri Jagan Sridharan +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 +--- + 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 index 0000000000..15bf09db7a --- /dev/null +++ b/queue-6.16/usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch @@ -0,0 +1,117 @@ +From a381c6d6f646226924809d0ad01a9465786da463 Mon Sep 17 00:00:00 2001 +From: Amit Sunil Dhamne +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 + +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 +Signed-off-by: Amit Sunil Dhamne +Reviewed-by: Badhri Jagan Sridharan +Link: https://lore.kernel.org/r/20250815-fix-upstream-contaminant-v2-2-6c8d6c3adafb@google.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..2c3368ccea --- /dev/null +++ b/queue-6.16/usb-xhci-fix-host-not-responding-after-suspend-and-resume.patch @@ -0,0 +1,57 @@ +From ff9a09b3e09c7b794b56f2f5858f5ce42ba46cb3 Mon Sep 17 00:00:00 2001 +From: Niklas Neronin +Date: Tue, 19 Aug 2025 15:58:44 +0300 +Subject: usb: xhci: fix host not responding after suspend and resume + +From: Niklas Neronin + +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 +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250819125844.2042452-3-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..1a879a502a --- /dev/null +++ b/queue-6.16/usb-xhci-fix-slot_id-resource-race-conflict.patch @@ -0,0 +1,221 @@ +From 2eb03376151bb8585caa23ed2673583107bb5193 Mon Sep 17 00:00:00 2001 +From: Weitao Wang +Date: Tue, 19 Aug 2025 15:58:43 +0300 +Subject: usb: xhci: Fix slot_id resource race conflict + +From: Weitao Wang + +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 +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250819125844.2042452-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + 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);