2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

Compare commits

...

39 Commits

Author SHA1 Message Date
Linus Torvalds
8d245acc1e Char/Misc/IIO fixes for 6.17-rc3
Here are a small number of char/misc/iio and other driver fixes for
 6.17-rc3.  Included in here are:
   - IIO driver bugfixes for reported issues
   - bunch of comedi driver fixes
   - most core bugfix
   - fpga driver bugfix
   - cdx driver bugfix
 
 All of these have been in linux-next this week with no reported issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaKnPRw8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ymvOACffARDm9ydwRppM7KpQ0CDEOP8Gd8An2zt1S3z
 W5KoFRCkMEOZj93miep3
 =Lp/R
 -----END PGP SIGNATURE-----

Merge tag 'char-misc-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc/iio fixes from Greg KH:
 "Here are a small number of char/misc/iio and other driver fixes for
  6.17-rc3.  Included in here are:

   - IIO driver bugfixes for reported issues

   - bunch of comedi driver fixes

   - most core bugfix

   - fpga driver bugfix

   - cdx driver bugfix

  All of these have been in linux-next this week with no reported
  issues"

* tag 'char-misc-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  most: core: Drop device reference after usage in get_channel()
  comedi: Make insn_rw_emulate_bits() do insn->n samples
  comedi: Fix use of uninitialized memory in do_insn_ioctl() and do_insnlist_ioctl()
  comedi: pcl726: Prevent invalid irq number
  cdx: Fix off-by-one error in cdx_rpmsg_probe()
  fpga: zynq_fpga: Fix the wrong usage of dma_map_sgtable()
  iio: pressure: bmp280: Use IS_ERR() in bmp280_common_probe()
  iio: light: as73211: Ensure buffer holes are zeroed
  iio: adc: rzg2l_adc: Set driver data before enabling runtime PM
  iio: adc: rzg2l: Cleanup suspend/resume path
  iio: adc: ad7380: fix missing max_conversion_rate_hz on adaq4381-4
  iio: adc: bd79124: Add GPIOLIB dependency
  iio: imu: inv_icm42600: change invalid data error to -EBUSY
  iio: adc: ad7124: fix channel lookup in syscalib functions
  iio: temperature: maxim_thermocouple: use DMA-safe buffer for spi_read()
  iio: adc: ad7173: prevent scan if too many setups requested
  iio: proximity: isl29501: fix buffered read on big-endian systems
  iio: accel: sca3300: fix uninitialized iio scan data
2025-08-23 11:27:31 -04:00
Linus Torvalds
8004d08330 USB fixes for 6.17-rc3
Here are some small USB driver fixes for 6.17-rc3 to resolve a bunch of
 reported issues.  Included in here are:
   - typec driver fixes
   - dwc3 new device id
   - dwc3 driver fixes
   - new usb-storage driver quirks
   - xhci driver fixes
   - other tiny USB driver fixes to resolve bugs
 
 All of these have been in linux-next this week with no reported issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaKnTpQ8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+yk+7gCfV8UA7wAViZTaXWmqsa3GzeuSMKIAoKdcM0+j
 hV48oay+3njPXzlsTp0d
 =lRRr
 -----END PGP SIGNATURE-----

Merge tag 'usb-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are some small USB driver fixes for 6.17-rc3 to resolve a bunch
  of reported issues. Included in here are:

   - typec driver fixes

   - dwc3 new device id

   - dwc3 driver fixes

   - new usb-storage driver quirks

   - xhci driver fixes

   - other tiny USB driver fixes to resolve bugs

  All of these have been in linux-next this week with no reported issues"

* tag 'usb-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: xhci: fix host not responding after suspend and resume
  usb: xhci: Fix slot_id resource race conflict
  usb: typec: fusb302: Revert incorrect threaded irq fix
  USB: core: Update kerneldoc for usb_hcd_giveback_urb()
  usb: typec: maxim_contaminant: re-enable cc toggle if cc is open and port is clean
  usb: typec: maxim_contaminant: disable low power mode when reading comparator values
  usb: dwc3: Remove WARN_ON for device endpoint command timeouts
  USB: storage: Ignore driver CD mode for Realtek multi-mode Wi-Fi dongles
  usb: storage: realtek_cr: Use correct byte order for bcs->Residue
  usb: chipidea: imx: improve usbmisc_imx7d_pullup()
  kcov, usb: Don't disable interrupts in kcov_remote_start_usb_softirq()
  usb: dwc3: pci: add support for the Intel Wildcat Lake
  usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
  USB: storage: Add unusual-devs entry for Novatek NTK96550-based camera
  usb: core: hcd: fix accessing unmapped memory in SINGLE_STEP_SET_FEATURE test
  usb: renesas-xhci: Fix External ROM access timeouts
  usb: gadget: tegra-xudc: fix PM use count underflow
  usb: quirks: Add DELAY_INIT quick for another SanDisk 3.2Gen1 Flash Drive
2025-08-23 11:21:56 -04:00
Greg Kroah-Hartman
fe85261d7d IIO: 1st set of fixes for 6.17
Usual mixed bunch of ancient issues and relatively new ones.
 
 adi,ad7124
 - Fix channel lookup to use chan->address for indexing array.
 adi,ad7173
 - Stop accidentally enabling more configs than supported at one time.
 adi,ad7380
 - Fill in missing max_conversion_rate_hz for adaq4381-4
 ams,as73211
 - Fix uninitialized holes in scan data exposed to userspace.
 bosch,bmp280
 - Check for error when requesting optional GPIO rather than simply assuming
   success or a NULL return when no GPIO provided.
 invensense,icm42600
 - Change error code returned to -EBUSY on a temperature read with neither
   accelerometer nor gyroscope in use.  Reduces chance of misinterpretation
   by userspace.
 kionix,sca3300
 - Fix uninitialized holes in scan data exposed to userspace.
 maxim,thermocouple
 - Use a DMA-safe buffer for spi_read().
 renesas,isl29501
 - Fix ordering issue for big endian systems
 renesas,rsg2l
 - Fix an underflow issue around suspend/resume.
 - Make sure driver data is in place before enabling runtime PM that uses
   it.
 rohm,bd79124
 - Add missing GPIOLIB dependency.  May rework in future to allow this to be
   optional in future but for now this is the least invasive build fix.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmijdaURHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0FojnyRAAuTOb8IqpzLHS7BJb6ubONmOrzwY290HA
 BzwbB5/RfgDaW1rUMMy6n2QZ21V/mMdojLnBpIM1avpkYoWHkTdxyNN56eHI+xX3
 D2C5AjbnGdAxalWtUpbzh9G/99FyWxMv1SXaXRW28hzE/uzc/wSN2Tfozzi2pRxc
 PvPGFd2q6NvTaoS7fEs5IpyNhCMWy2HLp/5kML7n8MihRXxMRTzZ2ar49/L9Ps60
 eY6KdpCXkK+l1zBINTLPryXoIhn1/VyG02A7alwCP3gXuaFdqp3bAKcXhghFzERn
 mkKIbDvZ2HKn5VarAYqXLZrhO94Ve8kHYGQ3yImDtWvuh1+zPF0mSpHjGyPcgnDO
 F35yPbB+njPMAtYNwm5O+dseTHnNffWPOzUheozPKAdLc3e5hYdzEGeqXNHk3HCS
 vvzRyE4Pum1gY7l76kPAqZK67KNiHhNqEFugKaQXiZ+XP2bzvEMO2HSelAvfnzUx
 kvWzx0XGmNKB+jyys/uthn0A66PqqGMPMShPIcSDEDjnajrK7EfIPiMc0rfkoFVi
 3MFMefAnJEOthDc/m2GQqhHqGUEwCok2BlBqnBni1dcvgBW7TqOjOmIqFmSRjINF
 K9W79uYgeOMIM51h5MoiG15lWm0eUvj0XokRSlq9LXlZhWIkjruNW8GOE88tk6bw
 IOwjOUen/20=
 =QGkA
 -----END PGP SIGNATURE-----

Merge tag 'iio-fixes-for-6.17a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-linus

Jonathan writes:

IIO: 1st set of fixes for 6.17

Usual mixed bunch of ancient issues and relatively new ones.

adi,ad7124
- Fix channel lookup to use chan->address for indexing array.
adi,ad7173
- Stop accidentally enabling more configs than supported at one time.
adi,ad7380
- Fill in missing max_conversion_rate_hz for adaq4381-4
ams,as73211
- Fix uninitialized holes in scan data exposed to userspace.
bosch,bmp280
- Check for error when requesting optional GPIO rather than simply assuming
  success or a NULL return when no GPIO provided.
invensense,icm42600
- Change error code returned to -EBUSY on a temperature read with neither
  accelerometer nor gyroscope in use.  Reduces chance of misinterpretation
  by userspace.
kionix,sca3300
- Fix uninitialized holes in scan data exposed to userspace.
maxim,thermocouple
- Use a DMA-safe buffer for spi_read().
renesas,isl29501
- Fix ordering issue for big endian systems
renesas,rsg2l
- Fix an underflow issue around suspend/resume.
- Make sure driver data is in place before enabling runtime PM that uses
  it.
rohm,bd79124
- Add missing GPIOLIB dependency.  May rework in future to allow this to be
  optional in future but for now this is the least invasive build fix.

* tag 'iio-fixes-for-6.17a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio:
  iio: pressure: bmp280: Use IS_ERR() in bmp280_common_probe()
  iio: light: as73211: Ensure buffer holes are zeroed
  iio: adc: rzg2l_adc: Set driver data before enabling runtime PM
  iio: adc: rzg2l: Cleanup suspend/resume path
  iio: adc: ad7380: fix missing max_conversion_rate_hz on adaq4381-4
  iio: adc: bd79124: Add GPIOLIB dependency
  iio: imu: inv_icm42600: change invalid data error to -EBUSY
  iio: adc: ad7124: fix channel lookup in syscalib functions
  iio: temperature: maxim_thermocouple: use DMA-safe buffer for spi_read()
  iio: adc: ad7173: prevent scan if too many setups requested
  iio: proximity: isl29501: fix buffered read on big-endian systems
  iio: accel: sca3300: fix uninitialized iio scan data
2025-08-20 11:05:00 +02:00
Niklas Neronin
ff9a09b3e0 usb: xhci: fix host not responding after suspend and resume
Partially revert commit e1db856bd2 ("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: e1db856bd2 ("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>
2025-08-19 16:12:13 +02:00
Weitao Wang
2eb0337615 usb: xhci: Fix slot_id resource race conflict
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: 7faac1953e ("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>
2025-08-19 16:12:13 +02:00
Miaoqian Lin
b47b493d63 most: core: Drop device reference after usage in get_channel()
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: 2485055394 ("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>
2025-08-19 12:57:34 +02:00
Ian Abbott
7afba9221f comedi: Make insn_rw_emulate_bits() do insn->n samples
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: ed9eccbe89 ("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>
2025-08-19 12:57:01 +02:00
Ian Abbott
3cd212e895 comedi: Fix use of uninitialized memory in do_insn_ioctl() and do_insnlist_ioctl()
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: ed9eccbe89 ("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>
2025-08-19 12:56:47 +02:00
Edward Adam Davis
96cb948408 comedi: pcl726: Prevent invalid irq number
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: fff4620724 ("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>
2025-08-19 12:56:16 +02:00
Thorsten Blum
300a0cfe9f cdx: Fix off-by-one error in cdx_rpmsg_probe()
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: 2a226927d9 ("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>
2025-08-19 12:55:16 +02:00
Xu Yilun
1ca61060de fpga: zynq_fpga: Fix the wrong usage of dma_map_sgtable()
dma_map_sgtable() returns only 0 or the error code. Read sgt->nents to
get the number of mapped segments.

Fixes: 37e0070322 ("zynq_fpga: use sgtable-based scatterlist wrappers")
Reported-by: Pavel Pisa <pisa@fel.cvut.cz>
Closes: https://lore.kernel.org/linux-fpga/202508041548.22955.pisa@fel.cvut.cz/
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
Tested-by: Pavel Pisa <pisa@fel.cvut.cz>
Link: https://lore.kernel.org/r/20250806070605.1920909-2-yilun.xu@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-19 12:54:45 +02:00
Sebastian Reichel
309b6341d5 usb: typec: fusb302: Revert incorrect threaded irq fix
The fusb302 irq handler has been carefully optimized by Hans de Goede in
commit 207338ec5a ("usb: typec: fusb302: Improve suspend/resume
handling"). A recent 'fix' undid most of that work to avoid a virtio-gpio
driver bug.

This reverts the incorrect fix, since it is of very low quality. It
reverts the quirks from Hans change (and thus reintroduces the problems
fixed by Hans) while keeping the overhead from the original change.

The proper fix to support using fusb302 with an interrupt line provided
by virtio-gpio must be implemented in the virtio driver instead, which
should support disabling the IRQ from the fusb302 interrupt routine.

Cc: Hans de Goede <hansg@kernel.org>
Cc: Yongbo Zhang <giraffesnn123@gmail.com>
Fixes: 1c2d81bded ("usb: typec: fusb302: fix scheduling while atomic when using virtio-gpio")
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://lore.kernel.org/r/20250818-fusb302-unthreaded-irq-v1-1-3a9a11a9f56f@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-19 12:29:33 +02:00
Alan Stern
70fb252a84 USB: core: Update kerneldoc for usb_hcd_giveback_urb()
The kerneldoc added for usb_hcd_giveback_urb() by commit 41631d3616
("usb: core: Replace in_interrupt() in comments") is unclear and
incorrect.  Update the text for greater clarity and to say that URBs
for a root hub will always use a BH context for their completion.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/41eaae05-116a-4568-940c-eeb94ab6baa0@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-19 12:29:04 +02:00
Salah Triki
43c0f6456f iio: pressure: bmp280: Use IS_ERR() in bmp280_common_probe()
`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: df6e71256c ("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>
2025-08-18 19:22:18 +01:00
Amit Sunil Dhamne
a381c6d6f6 usb: typec: maxim_contaminant: re-enable cc toggle if cc is open and port is clean
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: 02b332a063 ("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>
2025-08-17 12:14:55 +02:00
Amit Sunil Dhamne
cabb6c5f4d usb: typec: maxim_contaminant: disable low power mode when reading comparator values
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: 02b332a063 ("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>
Rule: add
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>
2025-08-17 12:14:50 +02:00
Selvarasu Ganesan
45eae113dc usb: dwc3: Remove WARN_ON for device endpoint command timeouts
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>
2025-08-17 12:14:11 +02:00
Zenm Chen
a3dc32c635 USB: storage: Ignore driver CD mode for Realtek multi-mode Wi-Fi dongles
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>
2025-08-17 12:13:36 +02:00
Jonathan Cameron
433b99e922 iio: light: as73211: Ensure buffer holes are zeroed
Given that the buffer is copied to a kfifo that ultimately user space
can read, ensure we zero it.

Fixes: 403e5586b5 ("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>
2025-08-16 14:58:35 +01:00
Claudiu Beznea
c69e13965f iio: adc: rzg2l_adc: Set driver data before enabling runtime PM
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: 89ee8174e8 ("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>
2025-08-16 14:52:43 +01:00
Claudiu Beznea
a3c6eabe3b iio: adc: rzg2l: Cleanup suspend/resume path
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: 563cf94f93 ("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>
2025-08-16 14:52:20 +01:00
David Lechner
b04e455189 iio: adc: ad7380: fix missing max_conversion_rate_hz on adaq4381-4
Add max_conversion_rate_hz to the chip info for "adaq4381-4". Without
this, the driver fails to probe because it tries to set the initial
sample rate to 0 Hz, which is not valid.

Fixes: bbeaec81a0 ("iio: ad7380: add support for SPI offload")
Signed-off-by: David Lechner <dlechner@baylibre.com>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Link: https://patch.msgid.link/20250811-iio-adc-ad7380-fix-missing-max_conversion_rate_hs-on-ad4381-4-v1-1-ffb728d7a71c@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
2025-08-16 14:32:35 +01:00
Matti Vaittinen
8a6ededaad iio: adc: bd79124: Add GPIOLIB dependency
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: 3f57a3b9ab ("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>
2025-08-16 13:25:35 +01:00
Thorsten Blum
98da66a70a usb: storage: realtek_cr: Use correct byte order for bcs->Residue
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: 50a6cb932d ("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>
2025-08-13 17:19:28 +02:00
Xu Yang
421255afa2 usb: chipidea: imx: improve usbmisc_imx7d_pullup()
When add workaround for ERR051725, the usbmisc will put PHY to
Non-driving mode (OPMODE = 01) after stopping the device controller
and put PHY back to Normal mode (OPMODE = 00) after starting the device
controller.

However, this will bring issue for host controller. Because the PHY may
stay in Non-driving mode after switching the role from device to host.
Then the port will not work if USB device is attached. To fix this issue,
improving the workaround by putting PHY to Non-driving mode for a certain
period and back to Normal mode finally. To make host detect a disconnect
signal, the period should be at least 125us (a micro-frame time) for
high-speed link.

And only working as high-speed mode will need workaround for ERR051725.
So this will also filter the pullup event for high-speed.

Fixes: 11992b4100 ("usb: chipidea: imx: implement workaround for ERR051725")
Reviewed-by: Jun Li <jun.li@nxp.com>
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Acked-by: Peter Chen <peter.chen@kernel.org>
Link: https://lore.kernel.org/r/20250811100833.862876-1-xu.yang_2@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-13 17:19:10 +02:00
Sebastian Andrzej Siewior
9528d32873 kcov, usb: Don't disable interrupts in kcov_remote_start_usb_softirq()
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: f85d39dd7e ("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>
2025-08-13 17:18:43 +02:00
Heikki Krogerus
86f390ba59 usb: dwc3: pci: add support for the Intel Wildcat Lake
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>
2025-08-13 17:17:40 +02:00
Kuen-Han Tsai
58577118cc usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
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: 72246da40f ("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>
2025-08-13 17:17:13 +02:00
Mael GUERIN
6ca8af3c8f USB: storage: Add unusual-devs entry for Novatek NTK96550-based camera
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>
2025-08-13 17:16:46 +02:00
Xu Yang
8fe06185e1 usb: core: hcd: fix accessing unmapped memory in SINGLE_STEP_SET_FEATURE test
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: 216e0e563d ("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>
2025-08-13 17:16:22 +02:00
Marek Vasut
f9420f4757 usb: renesas-xhci: Fix External ROM access timeouts
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: 2478be82de ("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>
2025-08-13 17:15:59 +02:00
Russell King (Oracle)
202ad1aaca usb: gadget: tegra-xudc: fix PM use count underflow
Upon resume from system suspend, the PM runtime core issues the
following warning:

tegra-xudc 3550000.usb: Runtime PM usage count underflow!

This is because tegra_xudc_resume() unconditionally calls
schedule_work(&xudc->usb_role_sw_work) whether or not anything has
changed, which causes tegra_xudc_device_mode_off() to be called
even when we're already in that mode.

Keep track of the current state of "device_mode", and only schedule
this work if it has changed from the hardware state on resume.

Signed-off-by: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Link: https://lore.kernel.org/r/E1uhtkH-007KDZ-JT@rmk-PC.armlinux.org.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-13 17:15:45 +02:00
Miao Li
e664036cf3 usb: quirks: Add DELAY_INIT quick for another SanDisk 3.2Gen1 Flash Drive
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>
2025-08-13 17:15:19 +02:00
Jean-Baptiste Maneyrol
dfdc31e7cc iio: imu: inv_icm42600: change invalid data error to -EBUSY
Temperature sensor returns the temperature of the mechanical parts
of the chip. If both accel and gyro are off, the temperature sensor is
also automatically turned off and returns invalid data.

In this case, returning -EBUSY error code is better then -EINVAL and
indicates userspace that it needs to retry reading temperature in
another context.

Fixes: bc3eb0207f ("iio: imu: inv_icm42600: add temperature sensor support")
Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
Cc: stable@vger.kernel.org
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Reviewed-by: Sean Nyekjaer <sean@geanix.com>
Link: https://patch.msgid.link/20250808-inv-icm42600-change-temperature-error-code-v1-1-986fbf63b77d@tdk.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
2025-08-11 21:35:01 +01:00
David Lechner
197e299aae iio: adc: ad7124: fix channel lookup in syscalib functions
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: 47036a03a3 ("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>
2025-08-11 21:35:01 +01:00
David Lechner
ae5bc07ec9 iio: temperature: maxim_thermocouple: use DMA-safe buffer for spi_read()
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: 1f25ca11d8 ("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>
2025-08-11 21:35:01 +01:00
David Lechner
1cfb22c277 iio: adc: ad7173: prevent scan if too many setups requested
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 92c2472169 ("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: 92c2472169 ("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>
2025-08-11 21:35:01 +01:00
David Lechner
de18e978d0 iio: proximity: isl29501: fix buffered read on big-endian systems
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: 1c28799257 ("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>
2025-08-11 21:35:01 +01:00
David Lechner
4e5b705cc6 iio: accel: sca3300: fix uninitialized iio scan data
Fix potential leak of uninitialized stack data to userspace by ensuring
that the `channels` array is zeroed before use.

Fixes: edeb67fbbf ("iio: accel: sca3300: use IIO_DECLARE_BUFFER_WITH_TS")
Signed-off-by: David Lechner <dlechner@baylibre.com>
Link: https://patch.msgid.link/20250723-iio-accel-sca3300-fix-uninitialized-iio-scan-data-v1-1-12dbfb3307b7@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
2025-08-11 21:35:01 +01:00
37 changed files with 383 additions and 182 deletions

View File

@ -129,8 +129,7 @@ static int cdx_rpmsg_probe(struct rpmsg_device *rpdev)
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) {

View File

@ -1587,6 +1587,9 @@ static int do_insnlist_ioctl(struct comedi_device *dev,
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_device *dev,
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)

View File

@ -620,11 +620,9 @@ static int insn_rw_emulate_bits(struct comedi_device *dev,
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 comedi_device *dev,
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;
if (insn->insn == INSN_READ)
data[i] = (_data[1] >> (chan - base_chan)) & 1;
}
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;
return 1;
return insn->n;
}
static int __comedi_device_postconfig_async(struct comedi_device *dev,

View File

@ -328,7 +328,8 @@ static int pcl726_attach(struct comedi_device *dev,
* 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) {

View File

@ -405,12 +405,12 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, struct sg_table *sgt)
}
}
priv->dma_nelms =
dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0);
if (priv->dma_nelms == 0) {
err = dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0);
if (err) {
dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n");
return -ENOMEM;
return err;
}
priv->dma_nelms = sgt->nents;
/* enable clock */
err = clk_enable(priv->clk);

View File

@ -477,7 +477,7 @@ static irqreturn_t sca3300_trigger_handler(int irq, void *p)
struct iio_dev *indio_dev = pf->indio_dev;
struct sca3300_data *data = iio_priv(indio_dev);
int bit, ret, val, i = 0;
IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX);
IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX) = { };
iio_for_each_active_channel(indio_dev, bit) {
ret = sca3300_read_reg(data, indio_dev->channels[bit].address, &val);

View File

@ -1300,7 +1300,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

View File

@ -849,7 +849,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) {
@ -865,8 +865,8 @@ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan
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;
@ -880,8 +880,8 @@ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan
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;
@ -924,7 +924,7 @@ static int ad7124_set_syscalib_mode(struct iio_dev *indio_dev,
{
struct ad7124_state *st = iio_priv(indio_dev);
st->channels[chan->channel].syscalib_mode = mode;
st->channels[chan->address].syscalib_mode = mode;
return 0;
}
@ -934,7 +934,7 @@ static int ad7124_get_syscalib_mode(struct iio_dev *indio_dev,
{
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 = {

View File

@ -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;
@ -561,12 +561,19 @@ static void ad7173_reset_usage_cnts(struct ad7173_state *st)
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.
@ -579,14 +586,22 @@ ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *c
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;
@ -1228,7 +1243,7 @@ static int ad7173_update_scan_mode(struct iio_dev *indio_dev,
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))
@ -1239,6 +1254,54 @@ static int ad7173_update_scan_mode(struct iio_dev *indio_dev,
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;
}

View File

@ -873,6 +873,7 @@ static const struct ad7380_chip_info adaq4381_4_chip_info = {
.has_hardware_gain = true,
.available_scan_masks = ad7380_4_channel_scan_masks,
.timing_specs = &ad7380_4_timing,
.max_conversion_rate_hz = 4 * MEGA,
};
static const struct spi_offload_config ad7380_offload_config = {

View File

@ -89,7 +89,6 @@ struct rzg2l_adc {
struct completion completion;
struct mutex lock;
u16 last_val[RZG2L_ADC_MAX_CHANNELS];
bool was_rpm_active;
};
/**
@ -428,6 +427,8 @@ static int rzg2l_adc_probe(struct platform_device *pdev)
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 +461,6 @@ static int rzg2l_adc_probe(struct platform_device *pdev)
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,
@ -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;

View File

@ -32,8 +32,12 @@ static int inv_icm42600_temp_read(struct inv_icm42600_state *st, s16 *temp)
goto exit;
*temp = (s16)be16_to_cpup(raw);
/*
* Temperature data is invalid if both accel and gyro are off.
* Return -EBUSY in this case.
*/
if (*temp == INV_ICM42600_DATA_INVALID)
ret = -EINVAL;
ret = -EBUSY;
exit:
mutex_unlock(&st->lock);

View File

@ -639,7 +639,7 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p)
struct {
__le16 chan[4];
aligned_s64 ts;
} scan;
} scan = { };
int data_result, ret;
mutex_lock(&data->mutex);

View File

@ -3213,11 +3213,12 @@ int bmp280_common_probe(struct device *dev,
/* 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;

View File

@ -938,12 +938,18 @@ static irqreturn_t isl29501_trigger_handler(int irq, void *p)
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;

View File

@ -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(struct maxim_thermocouple_data *data,
{
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_trigger_handler(int irq, void *private)
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));
}

View File

@ -538,8 +538,8 @@ static struct most_channel *get_channel(char *mdev, char *mdev_ch)
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;

View File

@ -338,7 +338,8 @@ static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
schedule_work(&ci->usb_phy->chg_work);
break;
case CI_HDRC_CONTROLLER_PULLUP_EVENT:
if (ci->role == CI_ROLE_GADGET)
if (ci->role == CI_ROLE_GADGET &&
ci->gadget.speed == USB_SPEED_HIGH)
imx_usbmisc_pullup(data->usbmisc_data,
ci->gadget.connected);
break;

View File

@ -1068,15 +1068,24 @@ static void usbmisc_imx7d_pullup(struct imx_usbmisc_data *data, bool on)
unsigned long flags;
u32 val;
if (on)
return;
spin_lock_irqsave(&usbmisc->lock, flags);
val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
if (!on) {
val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
val |= MX7D_USBNC_USB_CTRL2_OPMODE(1);
val |= MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN;
} else {
val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN;
}
val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
val |= MX7D_USBNC_USB_CTRL2_OPMODE(1);
val |= MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN;
writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
spin_unlock_irqrestore(&usbmisc->lock, flags);
/* Last for at least 1 micro-frame to let host see disconnect signal */
usleep_range(125, 150);
spin_lock_irqsave(&usbmisc->lock, flags);
val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
val |= MX7D_USBNC_USB_CTRL2_OPMODE(0);
val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN;
writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
spin_unlock_irqrestore(&usbmisc->lock, flags);
}

View File

@ -1636,7 +1636,6 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
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) &&
@ -1654,14 +1653,13 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
/* 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);
@ -1719,10 +1717,10 @@ static void usb_giveback_urb_bh(struct work_struct *work)
* @urb: urb being returned to the USB device driver.
* @status: completion status code for the URB.
*
* Context: atomic. The completion callback is invoked in caller's context.
* For HCDs with HCD_BH flag set, the completion callback is invoked in BH
* context (except for URBs submitted to the root hub which always complete in
* caller's context).
* Context: atomic. The completion callback is invoked either in a work queue
* (BH) context or in the caller's context, depending on whether the HCD_BH
* flag is set in the @hcd structure, except that URBs submitted to the
* root hub always complete in BH context.
*
* This hands the URB from HCD to its USB device driver, using its
* completion function. The HCD has freed all per-urb resources
@ -2166,7 +2164,7 @@ static struct urb *request_single_step_set_feature_urb(
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);
@ -2230,9 +2228,15 @@ int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
/* 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))) {

View File

@ -371,6 +371,7 @@ static const struct usb_device_id usb_quirk_list[] = {
{ 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 */

View File

@ -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_pci_id_table[] = {
{ 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) },

View File

@ -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(struct dwc3 *dwc,
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(struct dwc3_ep *dep)
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 dwc3 *dwc, struct dwc3_ep *dep)
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;
}

View File

@ -1772,7 +1772,11 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
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)
@ -3777,6 +3781,15 @@ static void dwc3_gadget_endpoint_transfer_complete(struct dwc3_ep *dep,
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);
/*
@ -4039,7 +4052,9 @@ static void dwc3_clear_stall_all_ep(struct dwc3 *dwc)
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);
}
}

View File

@ -502,6 +502,7 @@ struct tegra_xudc {
struct clk_bulk_data *clks;
bool device_mode;
bool current_device_mode;
struct work_struct usb_role_sw_work;
struct phy **usb3_phy;
@ -715,6 +716,8 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
phy_set_mode_ext(xudc->curr_utmi_phy, PHY_MODE_USB_OTG,
USB_ROLE_DEVICE);
xudc->current_device_mode = true;
}
static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
@ -725,6 +728,8 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
dev_dbg(xudc->dev, "device mode off\n");
xudc->current_device_mode = false;
connected = !!(xudc_readl(xudc, PORTSC) & PORTSC_CCS);
reinit_completion(&xudc->disconnect_complete);
@ -4044,10 +4049,10 @@ static int __maybe_unused tegra_xudc_resume(struct device *dev)
spin_lock_irqsave(&xudc->lock, flags);
xudc->suspended = false;
if (xudc->device_mode != xudc->current_device_mode)
schedule_work(&xudc->usb_role_sw_work);
spin_unlock_irqrestore(&xudc->lock, flags);
schedule_work(&xudc->usb_role_sw_work);
pm_runtime_enable(dev);
return 0;

View File

@ -704,8 +704,7 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci,
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);

View File

@ -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_hcd *xhci, int slot_id)
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_first(struct xhci_hcd *xhci, int slot_i
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,

View File

@ -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_dev *pdev)
/* 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;

View File

@ -1592,7 +1592,8 @@ static void xhci_handle_cmd_enable_slot(int slot_id, struct xhci_command *comman
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(struct xhci_hcd *xhci, int slot_id)
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_hcd *xhci,
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)

View File

@ -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);
@ -3932,8 +3934,7 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd,
* 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 +4091,7 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
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 +4140,16 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
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 +4256,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
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 +4392,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
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);

View File

@ -1791,7 +1791,7 @@ void xhci_dbg_trace(struct xhci_hcd *xhci, void (*trace)(struct va_format *),
/* 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 *hcd, struct usb_device *udev);
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);

View File

@ -252,7 +252,7 @@ static int rts51x_bulk_transport(struct us_data *us, u8 lun,
return USB_STOR_TRANSPORT_ERROR;
}
residue = bcs->Residue;
residue = le32_to_cpu(bcs->Residue);
if (bcs->Tag != us->tag)
return USB_STOR_TRANSPORT_ERROR;

View File

@ -934,6 +934,13 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451,
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
@ -1494,6 +1501,28 @@ UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9999,
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",

View File

@ -1485,6 +1485,9 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id)
struct fusb302_chip *chip = dev_id;
unsigned long flags;
/* Disable our level triggered IRQ until our irq_work has cleared it */
disable_irq_nosync(chip->gpio_int_n_irq);
spin_lock_irqsave(&chip->irq_lock, flags);
if (chip->irq_suspended)
chip->irq_while_suspended = true;
@ -1627,6 +1630,7 @@ static void fusb302_irq_work(struct work_struct *work)
}
done:
mutex_unlock(&chip->lock);
enable_irq(chip->gpio_int_n_irq);
}
static int init_gpio(struct fusb302_chip *chip)
@ -1751,10 +1755,9 @@ static int fusb302_probe(struct i2c_client *client)
goto destroy_workqueue;
}
ret = devm_request_threaded_irq(dev, chip->gpio_int_n_irq,
NULL, fusb302_irq_intn,
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
"fsc_interrupt_int_n", chip);
ret = request_irq(chip->gpio_int_n_irq, fusb302_irq_intn,
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
"fsc_interrupt_int_n", chip);
if (ret < 0) {
dev_err(dev, "cannot request IRQ for GPIO Int_N, ret=%d", ret);
goto tcpm_unregister_port;
@ -1779,6 +1782,7 @@ static void fusb302_remove(struct i2c_client *client)
struct fusb302_chip *chip = i2c_get_clientdata(client);
disable_irq_wake(chip->gpio_int_n_irq);
free_irq(chip->gpio_int_n_irq, chip);
cancel_work_sync(&chip->irq_work);
cancel_delayed_work_sync(&chip->bc_lvl_handler);
tcpm_unregister_port(chip->tcpm_port);

View File

@ -188,6 +188,11 @@ static int max_contaminant_read_comparators(struct max_tcpci_chip *chip, u8 *ven
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);
@ -324,6 +329,39 @@ static int max_contaminant_enable_dry_detection(struct max_tcpci_chip *chip)
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)
{
@ -340,6 +378,12 @@ bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect
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);
@ -372,6 +416,12 @@ bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect
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)) {
@ -379,6 +429,14 @@ bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect
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;
}
}
}
}

View File

@ -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

View File

@ -57,47 +57,21 @@ static inline void kcov_remote_start_usb(u64 id)
/*
* 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(void)
}
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 */