1
0
mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2026-01-11 09:00:12 +00:00

Compare commits

...

50 Commits

Author SHA1 Message Date
Linus Torvalds
f8f9c1f4d0 Linux 6.19-rc3 2025-12-28 13:24:26 -08:00
Linus Torvalds
c875a6c324 USB fixes for 6.19-rc3
Here are some small USB fixes, and bunch of reverts for 6.19-rc3.
 Included in here are:
   - reverts of some typec ucsi driver changes that had a lot of
     regression reports after -rc1.  Let's just revert it all for now and
     it will come back in a way that is better tested.
   - other typec bugfixes
   - usb-storage quirk fixups
   - dwc3 driver fix
   - other minor USB fixes for reported problems.
 
 All of these have passed 0-day testing and individual testing.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaVElGw8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ylMeQCgzsZZNX7AtfUXlHkFENzlKFyAYZEAn0Nl01xd
 BBKmE3GqGMWsVIJ2T0AI
 =cjZ8
 -----END PGP SIGNATURE-----

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

Pull USB fixes from Greg KH:
 "Here are some small USB fixes, and bunch of reverts for 6.19-rc3.
  Included in here are:

   - reverts of some typec ucsi driver changes that had a lot of
     regression reports after -rc1. Let's just revert it all for now and
     it will come back in a way that is better tested.

   - other typec bugfixes

   - usb-storage quirk fixups

   - dwc3 driver fix

   - other minor USB fixes for reported problems.

  All of these have passed 0-day testing and individual testing"

* tag 'usb-6.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (22 commits)
  Revert "usb: typec: ucsi: Update UCSI structure to have message in and message out fields"
  Revert "usb: typec: ucsi: Add support for message out data structure"
  Revert "usb: typec: ucsi: Enable debugfs for message_out data structure"
  Revert "usb: typec: ucsi: Add support for SET_PDOS command"
  Revert "usb: typec: ucsi: Fix null pointer dereference in ucsi_sync_control_common"
  Revert "usb: typec: ucsi: Get connector status after enable notifications"
  usb: ohci-nxp: clean up probe error labels
  usb: gadget: lpc32xx_udc: clean up probe error labels
  usb: ohci-nxp: fix device leak on probe failure
  usb: phy: isp1301: fix non-OF device reference imbalance
  usb: gadget: lpc32xx_udc: fix clock imbalance in error path
  usb: typec: ucsi: Get connector status after enable notifications
  usb: usb-storage: Maintain minimal modifications to the bcdDevice range.
  usb: dwc3: of-simple: fix clock resource leak in dwc3_of_simple_probe
  usb: typec: ucsi: Fix null pointer dereference in ucsi_sync_control_common
  USB: lpc32xx_udc: Fix error handling in probe
  usb: typec: altmodes/displayport: Drop the device reference in dp_altmode_probe()
  usb: phy: fsl-usb: Fix use-after-free in delayed work during device removal
  usb: renesas_usbhs: Fix a resource leak in usbhs_pipe_malloc()
  usb: typec: ucsi: huawei-gaokin: add DRM dependency
  ...
2025-12-28 10:21:47 -08:00
Linus Torvalds
15225b910c Serial driver fixes for 6.19-rc3
Here are some small serial driver fixes for some reported issues.
 Included in here are:
   - serial sysfs fwnode fix that was much reported
   - sh-sci driver fix
   - serial device init bugfix
   - 8250 bugfix
   - xilinx_uartps bugfix
 
 All of these have passed 0-day testing and individual testing
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaVEl7A8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+yn1AgCfYUqy05A3BNhwOfhzoJ2ToKn/aZkAn0iYT/06
 vLBTQBtVhoMff9CneVvu
 =eNi3
 -----END PGP SIGNATURE-----

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

Pull serial driver fixes from Greg KH:
 "Here are some small serial driver fixes for some reported issues.
  Included in here are:

   - serial sysfs fwnode fix that was much reported

   - sh-sci driver fix

   - serial device init bugfix

   - 8250 bugfix

   - xilinx_uartps bugfix

  All of these have passed 0-day testing and individual testing"

* tag 'tty-6.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  serial: xilinx_uartps: fix rs485 delay_rts_after_send
  serial: sh-sci: Check that the DMA cookie is valid
  serial: core: Fix serial device initialization
  serial: 8250: longson: Fix NULL vs IS_ERR() bug in probe
  serial: core: Restore sysfs fwnode information
2025-12-28 10:14:49 -08:00
Linus Torvalds
1c55bc8710 firewire fixes for 6.19-rc3
A fix for PCI driver for Texas Instruments PCILyx series. The driver had
 a bug where it allocated a DMA-coherent buffer of 16 KB but released it
 using PAGE_SIZE. This disproportion was reported in 2020, but the fix was
 never merged. It is finally resolved.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQE66IEYNDXNBPeGKSsLtaWM8LwEwUCaVEkHAAKCRCsLtaWM8Lw
 E47xAQCakWPjeQ1S64vK9lmNAcUjWRw/YhacDLVv3euEBjSzuwEAwvK3pPv95IlA
 fO6V8UVJN+Lg5dwusM+fdleZqvR4mQ4=
 =UZIn
 -----END PGP SIGNATURE-----

Merge tag 'firewire-fixes-6.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394

Pull firewire fix from Takashi Sakamoto:
 "A fix for PCI driver for Texas Instruments PCILyx series.

  The driver had a bug where it allocated a DMA-coherent buffer of 16 KB
  but released it using PAGE_SIZE. This disproportion was reported in
  2020, but the fix was never merged. It is finally resolved"

* tag 'firewire-fixes-6.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394:
  firewire: nosy: Fix dma_free_coherent() size
2025-12-28 10:11:18 -08:00
Linus Torvalds
03de3e44a7 RISC-V updates for v6.19-rc3
- Add probing and userspace reporting support for the standard RISC-V
   ISA extensions Zilsd and Zclsd, which implement load/store dual
   instructions on RV32
 
 - Abstract the register saving code in setup_sigcontext() so it can be
   used for stateful RISC-V ISA extensions beyond the vector extension
 
 - Add the SBI extension ID and some initial data structure definitions
   for the RISC-V standard SBI debug trigger extension
 
 - Clean up some code slightly: change some page table functions to
   avoid atomic operations oinn !SMP and to avoid unnecessary casts to
   atomic_long_t; and use the existing RISCV_FULL_BARRIER macro in
   place of some open-coded "fence rw,rw" instructions
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEElRDoIDdEz9/svf2Kx4+xDQu9KksFAmlQ5hUACgkQx4+xDQu9
 KkuzjQ/+LV27EOKp3ofhkN6yD+u/MZJv2L8d/L+iuZ6mC7ynerVqY7jHj1bUtSWG
 lGJPLLtB3rWITsN0tTkQZDE+LySABACvGsHsH0jDOPu25EUu8fmKL+4UOBpJ4EmH
 GrldJCgJjZiV9/NdFqUSwpsZKfuNC3IT5hQvEfFmBGexMb4O0ch2LTrqNTxsS5eu
 x1a5DJPbls8olyTYYMoIIbQMU35bHdQWSGEUBvKpisziD11E5c9P9zZcN/X7TnFZ
 9wxDCeCmdtiayJzWECRO5HFErxw16IWOBsW7JwanOLlJuE2vi/hEW3bwAAQMaYSh
 FvN6ID9d6fE9cuStNfqILuWeF8cogVkowMzEX9ud6hFp8AKE/mAlF4Rd26qIAbwE
 Migv/MjSuMKSYfPIcJ+fkrMoPgMeMCoGW34NtSV7MjSujBYozjjnN/Yc5iSu5rdN
 16b08rtusMvQI0Eowt21RO7iXRauK1+6Xcag5WZytD+sdMZkPxOepDK/mZijiida
 w8FYENlHEjhlF7A9Uiy8igVCjXJg63r3ctcnzB2wskUb+gfJF9IXdpv0O7ZO6IoJ
 6Q4OI3oNhHSWic7noXYu+dSbTT4DjlPpUBnI79X7bPo+6Ck3X9fr8YPpHzKnmHN9
 aVixfWk8zShNutROkt+3vQYzgNACcNtMT9Uz5Ce2FI3urqALp1M=
 =Pgyz
 -----END PGP SIGNATURE-----

Merge tag 'riscv-for-linus-6.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull RISC-V updates from Paul Walmsley:
 "Nothing exotic here; these are the cleanup and new ISA extension
  probing patches (not including CFI):

   - Add probing and userspace reporting support for the standard RISC-V
     ISA extensions Zilsd and Zclsd, which implement load/store dual
     instructions on RV32

   - Abstract the register saving code in setup_sigcontext() so it can
     be used for stateful RISC-V ISA extensions beyond the vector
     extension

   - Add the SBI extension ID and some initial data structure
     definitions for the RISC-V standard SBI debug trigger extension

   - Clean up some code slightly: change some page table functions to
     avoid atomic operations oinn !SMP and to avoid unnecessary casts to
     atomic_long_t; and use the existing RISCV_FULL_BARRIER macro in
     place of some open-coded 'fence rw,rw' instructions"

* tag 'riscv-for-linus-6.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  riscv: Add SBI debug trigger extension and function ids
  riscv/atomic.h: use RISCV_FULL_BARRIER in _arch_atomic* function.
  riscv: hwprobe: export Zilsd and Zclsd ISA extensions
  riscv: add ISA extension parsing for Zilsd and Zclsd
  dt-bindings: riscv: add Zilsd and Zclsd extension descriptions
  riscv: mm: use xchg() on non-atomic_long_t variables, not atomic_long_xchg()
  riscv: mm: ptep_get_and_clear(): avoid atomic ops when !CONFIG_SMP
  riscv: mm: pmdp_huge_get_and_clear(): avoid atomic ops when !CONFIG_SMP
  riscv: signal: abstract header saving for setup_sigcontext
2025-12-28 09:44:26 -08:00
Linus Torvalds
cd80afff48 powerpc fixes for 6.19 #2
- Fix for kexec warning due to SMT disable or partial SMT enabled
  - Handle font bitmap pointer with reloc_offset to fix boot crash
  - Fix to enable cpuidle state for Power11
  - Couple of misc fixes
 
 Thanks to: Aboorva Devarajan, Aditya Bodkhe, Cedar Maxwell, Christian Zigotzky, Christophe Leroy, Christophe Leroy (CS GROUP), Finn Thain, Gopi Krishna Menon, Guenter Roeck, Jan Stancek, Joe Lawrence, Josh Poimboeuf, Justin M. Forbes, Madadi Vineeth Reddy, Naveen N Rao (AMD), Nysal Jan K.A., Sachin P Bappalige, Samir M, Sourabh Jain, Srikar Dronamraju, Stan Johnson
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEqX2DNAOgU8sBX3pRpnEsdPSHZJQFAmlQnssACgkQpnEsdPSH
 ZJTVyg//f3NGQ3WJPWm0bx162qM8H1sExsdji6ra7ViDx/0fx93RjU23bmvn/zc1
 Dirfk224xyYHTXIz9Crd6cESao6RgECqucolnjDyZFg0ip2Ew8yIkL386h50NVhL
 IuMeWrAwj7QE5mJ5hvqq1019MAq2sk6WvIOJACqzbogVH8k4E119LnzrvNk6phOX
 aQr9RvpIrfA5TmReG8PT5owkFPr8yiqV4Gz7p4JOKgruvkAj5zJk2FLEOh7yU9/Q
 Wcqrp3m3F2Gl3QCdj8F5gQGDUU3sxapgRrjOQZTTJckfDJcYDz9W9XteBVXicVMr
 Uc2Lzgps5fnjORQYXQi/q6Z1XeHTCsO9CAM81l9zGmeg/J53CUI4SMumQn+kEdSN
 lLpNecU6YDrae1QdT97o18tpWPQSueAapv/Uxnn2goY8Q80IZyhY6iy8ITdbEK0x
 CqAyqFNWfpNJIt2PLCUVzfcVJ7iPCQBTBVCTKJSUmlxOScadj+UKDACGKZIN/jtR
 CNBcoM4Ciz4Po1KLFhbfHqp0ixuxHRPfaS+1UyIfKHEYwoNvpCHlXtBf9qQYW92h
 07/4ou6uzTmfuvyAQ8iY67/cMWDFocz3ephViOzmiCiEg445xx6w94CGiWp0QFCP
 D6wYlDh48IxH8iia4r7r/IB0r1Bw7gygUM/zeu5weMnvxmcUwII=
 =mQlX
 -----END PGP SIGNATURE-----

Merge tag 'powerpc-6.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc fixes from Madhavan Srinivasan:

 - Fix for kexec warning due to SMT disable or partial SMT enabled

 - Handle font bitmap pointer with reloc_offset to fix boot crash

 - Fix to enable cpuidle state for Power11

 - Couple of misc fixes

Thanks to Aboorva Devarajan, Aditya Bodkhe, Cedar Maxwell, Christian
Zigotzky, Christophe Leroy, Christophe Leroy (CS GROUP), Finn Thain,
Gopi Krishna Menon, Guenter Roeck, Jan Stancek, Joe Lawrence, Josh
Poimboeuf, Justin M. Forbes, Madadi Vineeth Reddy, Naveen N Rao (AMD),
Nysal Jan K.A., Sachin P Bappalige, Samir M, Sourabh Jain, Srikar
Dronamraju, and Stan Johnson

* tag 'powerpc-6.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/32: Restore disabling of interrupts at interrupt/syscall exit
  powerpc/powernv: Enable cpuidle state detection for POWER11
  powerpc: Add reloc_offset() to font bitmap pointer used for bootx_printf()
  powerpc/tools: drop `-o pipefail` in gcc check scripts
  selftests/powerpc/pmu/: Add check_extended_reg_test to .gitignore
  powerpc/kexec: Enable SMT before waking offline CPUs
2025-12-28 09:40:09 -08:00
Thomas Fourier
c48c0fd0e1 firewire: nosy: Fix dma_free_coherent() size
It looks like the buffer allocated and mapped in add_card() is done
with size RCV_BUFFER_SIZE which is 16 KB and 4KB.

Fixes: 286468210d83 ("firewire: new driver: nosy - IEEE 1394 traffic sniffer")
Co-developed-by: Thomas Fourier <fourier.thomas@gmail.com>
Signed-off-by: Thomas Fourier <fourier.thomas@gmail.com>
Co-developed-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Link: https://lore.kernel.org/r/20251216165420.38355-2-fourier.thomas@gmail.com
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
2025-12-26 22:04:03 +09:00
Greg Kroah-Hartman
22201800f1 Merge patch series "usb: typec: ucsi: revert broken buffer management"
Johan Hovold <johan@kernel.org> says:

The new buffer management code has not been tested or reviewed properly
and breaks boot of machines like the Lenovo ThinkPad X13s.

Fixing this will require designing a proper interface for managing these
transactions, something which most likely involves reverting most of the
offending commit anyway.

Revert the broken code to fix the regression and let Intel come up with
a properly tested implementation for a later kernel.

Link: https://lore.kernel.org/r/20251222152204.2846-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 15:59:03 +01:00
Johan Hovold
e7a9f66001 Revert "usb: typec: ucsi: Update UCSI structure to have message in and message out fields"
This reverts commit 3e082978c33151d576694deac8abde021ea669a8.

The new buffer management code has not been tested or reviewed properly
and breaks boot of machines like the Lenovo ThinkPad X13s:

    Unable to handle kernel NULL pointer dereference at virtual address
    0000000000000000

    CPU: 0 UID: 0 PID: 813 Comm: kworker/0:3 Not tainted 6.19.0-rc2 #26 PREEMPT
    Hardware name: LENOVO 21BYZ9SRUS/21BYZ9SRUS, BIOS N3HET87W (1.59 ) 12/05/2023
    Workqueue: events ucsi_handle_connector_change [typec_ucsi]

    Call trace:
     ucsi_sync_control_common+0xe4/0x1ec [typec_ucsi] (P)
     ucsi_run_command+0xcc/0x194 [typec_ucsi]
     ucsi_send_command_common+0x84/0x2a0 [typec_ucsi]
     ucsi_get_connector_status+0x48/0x78 [typec_ucsi]
     ucsi_handle_connector_change+0x5c/0x4f4 [typec_ucsi]
     process_one_work+0x208/0x60c
     worker_thread+0x244/0x388

The new code completely ignores concurrency so that the message length
can be updated while a transaction is ongoing. In the above case, the
length ends up being modified by another thread while processing an ack
so that the NULL cci pointer is dereferenced.

Fixing this will require designing a proper interface for managing these
transactions, something which most likely involves reverting most of the
offending commit anyway.

Revert the broken code to fix the regression and let Intel come up with
a properly tested implementation for a later kernel.

Fixes: 3e082978c331 ("usb: typec: ucsi: Update UCSI structure to have message in and message out fields")
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20251222152204.2846-5-johan@kernel.org
2025-12-23 15:59:01 +01:00
Johan Hovold
2e46b4e024 Revert "usb: typec: ucsi: Add support for message out data structure"
This reverts commit db0028637cc832add6d87564fcc2ebb12781b046.

The new buffer management code that this feature relies on is broken so
revert for now.

As for the in buffer, nothing prevents the out message size and buffer
from being modified while the message is being processed due to lack of
serialisation.

Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20251222152204.2846-4-johan@kernel.org
2025-12-23 15:59:01 +01:00
Johan Hovold
174e7d0f47 Revert "usb: typec: ucsi: Enable debugfs for message_out data structure"
This reverts commit 775fae520e6ae62c393a8daf42dc534f09692f3f.

The new buffer management code that this relies on is broken so revert
for now.

It also looks like the error handling needs some more thought as the
message out size is not reset on errors.

Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20251222152204.2846-3-johan@kernel.org
2025-12-23 15:59:01 +01:00
Johan Hovold
784b756dde Revert "usb: typec: ucsi: Add support for SET_PDOS command"
This reverts commit 1b474ee01fbb73b1365adbf9b3067f7375e471ee.

The new buffer management code that this feature relies on is broken so
revert for now.

The interface for writing data and support for UCSI_SET_PDOS looks like
it could use some more thought as well.

Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20251222152204.2846-2-johan@kernel.org
2025-12-23 15:59:01 +01:00
Greg Kroah-Hartman
df3e316930 Revert "usb: typec: ucsi: Fix null pointer dereference in ucsi_sync_control_common"
This reverts commit 14ad4c10d5bdd413ff9a914260e89b5f54b7a2c7.

The originally offending commit will be reverted instead of this fix up
at this point in time, so revert this fix.

Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Mario Limonciello (AMD) <superm1@kernel.org>
Cc: stable <stable@kernel.org>
Cc: Johan Hovold <johan@kernel.org>
Fixes: 14ad4c10d5bd ("usb: typec: ucsi: Fix null pointer dereference in ucsi_sync_control_common")
Link: https://lore.kernel.org/r/20251222152204.2846-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 15:57:16 +01:00
Greg Kroah-Hartman
0dc580d4a6 Revert "usb: typec: ucsi: Get connector status after enable notifications"
This reverts commit 5106dbab44fba8ec6dede3f4e75d17f5aa777ec8.

There are reported issues in this file, so revert the commit for now so
that the original offending changes can be reverted and working systems
can be restored.  This can come back at a later time if it is rebased
yet-again (sorry.)

Cc: stable <stable@kernel.org>
Cc: Johan Hovold <johan@kernel.org>
Link: https://lore.kernel.org/r/20251222152204.2846-1-johan@kernel.org
Fixes: 5106dbab44fb ("usb: typec: ucsi: Get connector status after enable notifications")
Cc: Kenneth R. Crudup <kenny@panix.com>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Hsin-Te Yuan <yuanhsinte@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 15:56:04 +01:00
Johan Hovold
8ff242c041 usb: ohci-nxp: clean up probe error labels
Error labels should be named after what they do rather than after from
where they are jumped to.

Rename the probe error labels for consistency and to improve
readability.

Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>
Link: https://patch.msgid.link/20251218153519.19453-6-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 15:48:46 +01:00
Johan Hovold
ad6fb7367e usb: gadget: lpc32xx_udc: clean up probe error labels
Error labels should be named after what they do rather than after from
where they are jumped to.

Rename the probe error labels for consistency and to improve
readability.

Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>
Link: https://patch.msgid.link/20251218153519.19453-5-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 15:48:46 +01:00
Johan Hovold
b4c61e542f usb: ohci-nxp: fix device leak on probe failure
Make sure to drop the reference taken when looking up the PHY I2C device
during probe on probe failure (e.g. probe deferral) and on driver
unbind.

Fixes: 73108aa90cbf ("USB: ohci-nxp: Use isp1301 driver")
Cc: stable@vger.kernel.org	# 3.5
Reported-by: Ma Ke <make24@iscas.ac.cn>
Link: https://lore.kernel.org/lkml/20251117013428.21840-1-make24@iscas.ac.cn/
Signed-off-by: Johan Hovold <johan@kernel.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>
Link: https://patch.msgid.link/20251218153519.19453-4-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 15:48:46 +01:00
Johan Hovold
b4b64fda4d usb: phy: isp1301: fix non-OF device reference imbalance
A recent change fixing a device reference leak in a UDC driver
introduced a potential use-after-free in the non-OF case as the
isp1301_get_client() helper only increases the reference count for the
returned I2C device in the OF case.

Increment the reference count also for non-OF so that the caller can
decrement it unconditionally.

Note that this is inherently racy just as using the returned I2C device
is since nothing is preventing the PHY driver from being unbound while
in use.

Fixes: c84117912bdd ("USB: lpc32xx_udc: Fix error handling in probe")
Cc: stable@vger.kernel.org
Cc: Ma Ke <make24@iscas.ac.cn>
Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>
Link: https://patch.msgid.link/20251218153519.19453-3-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 15:48:46 +01:00
Johan Hovold
782be79e45 usb: gadget: lpc32xx_udc: fix clock imbalance in error path
A recent change fixing a device reference leak introduced a clock
imbalance by reusing an error path so that the clock may be disabled
before having been enabled.

Note that the clock framework allows for passing in NULL clocks so there
is no risk for a NULL pointer dereference.

Also drop the bogus I2C client NULL check added by the offending commit
as the pointer has already been verified to be non-NULL.

Fixes: c84117912bdd ("USB: lpc32xx_udc: Fix error handling in probe")
Cc: stable@vger.kernel.org
Cc: Ma Ke <make24@iscas.ac.cn>
Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>
Link: https://patch.msgid.link/20251218153519.19453-2-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 15:48:46 +01:00
Hsin-Te Yuan
5106dbab44 usb: typec: ucsi: Get connector status after enable notifications
Originally, the notification for connector change will be enabled after
the first read of the connector status. Therefore, if the event happens
during this window, it will be missing and make the status unsynced.

Get the connector status only after enabling the notification for
connector change to ensure the status is synced.

Fixes: c1b0bc2dabfa ("usb: typec: Add support for UCSI interface")
Cc: stable <stable@kernel.org>
Tested-by: Kenneth R. Crudup <kenny@panix.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Hsin-Te Yuan <yuanhsinte@chromium.org>
Link: https://patch.msgid.link/20251218-ucsi-v7-1-aea83e83fb12@chromium.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 15:41:44 +01:00
Chen Changcheng
0831269b5f usb: usb-storage: Maintain minimal modifications to the bcdDevice range.
We cannot determine which models require the NO_ATA_1X and
IGNORE_RESIDUE quirks aside from the EL-R12 optical drive device.

Fixes: 955a48a5353f ("usb: usb-storage: No additional quirks need to be added to the EL-R12 optical drive.")
Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
Link: https://patch.msgid.link/20251218012318.15978-1-chenchangcheng@kylinos.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 15:41:31 +01:00
j.turek
267ee93c41 serial: xilinx_uartps: fix rs485 delay_rts_after_send
RTS line control with delay should be triggered when there is no more
bytes in kfifo and hardware buffer is empty. Without this patch RTS
control is scheduled right after feeding hardware buffer and this is too
early.

RTS line may change state before hardware buffer is empty.

With this patch delayed RTS state change is triggered when function
cdns_uart_handle_tx is called from cdns_uart_isr on
CDNS_UART_IXR_TXEMPTY exactly when hardware completed transmission

Fixes: fccc9d9233f9 ("tty: serial: uartps: Add rs485 support to uartps driver")
Cc: stable <stable@kernel.org>
Link: https://patch.msgid.link/20251221103221.1971125-1-jakub.turek@elsta.tech
Signed-off-by: Jakub Turek  <jakub.turek@elsta.tech>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 11:55:16 +01:00
Claudiu Beznea
c3ca8a0aac serial: sh-sci: Check that the DMA cookie is valid
The driver updates struct sci_port::tx_cookie to zero right before the TX
work is scheduled, or to -EINVAL when DMA is disabled.
dma_async_is_complete(), called through dma_cookie_status() (and possibly
through dmaengine_tx_status()), considers cookies valid only if they have
values greater than or equal to 1.

Passing zero or -EINVAL to dmaengine_tx_status() before any TX DMA
transfer has started leads to an incorrect TX status being reported, as the
cookie is invalid for the DMA subsystem. This may cause long wait times
when the serial device is opened for configuration before any TX activity
has occurred.

Check that the TX cookie is valid before passing it to
dmaengine_tx_status().

Fixes: 7cc0e0a43a91 ("serial: sh-sci: Check if TX data was written to device in .tx_empty()")
Cc: stable <stable@kernel.org>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Link: https://patch.msgid.link/20251217135759.402015-1-claudiu.beznea.uj@bp.renesas.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 11:54:00 +01:00
Alexander Stein
f54151148b serial: core: Fix serial device initialization
During restoring sysfs fwnode information the information of_node_reused
was dropped. This was previously set by device_set_of_node_from_dev().
Add it back manually

Fixes: 24ec03cc5512 ("serial: core: Restore sysfs fwnode information")
Cc: stable <stable@kernel.org>
Suggested-by: Cosmin Tanislav <demonsingur@gmail.com>
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Tested-by: Michael Walle <mwalle@kernel.org>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Cosmin Tanislav <demonsingur@gmail.com>
Link: https://patch.msgid.link/20251219152813.1893982-1-alexander.stein@ew.tq-group.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-23 11:53:37 +01:00
Christophe Leroy (CS GROUP)
608328ba5b powerpc/32: Restore disabling of interrupts at interrupt/syscall exit
Commit 2997876c4a1a ("powerpc/32: Restore clearing of MSR[RI] at
interrupt/syscall exit") delayed clearing of MSR[RI], but missed that
both MSR[RI] and MSR[EE] are cleared at the same time, so the commit
also delayed the disabling of interrupts, leading to unexpected
behaviour.

To fix that, mostly revert the blamed commit and restore the clearing
of MSR[RI] in interrupt_exit_kernel_prepare() instead. For 8xx it
implies adding a synchronising instruction after the mtspr in order to
make sure no instruction counter interrupt (used for perf events) will
fire just after clearing MSR[RI].

Reported-by: Christian Zigotzky <chzigotzky@xenosoft.de>
Closes: https://lore.kernel.org/all/4d0bd05d-6158-1323-3509-744d3fbe8fc7@xenosoft.de/
Reported-by: Guenter Roeck <linux@roeck-us.net>
Closes: https://lore.kernel.org/all/6b05eb1c-fdef-44e0-91a7-8286825e68f1@roeck-us.net/
Fixes: 2997876c4a1a ("powerpc/32: Restore clearing of MSR[RI] at interrupt/syscall exit")
Signed-off-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/585ea521b2be99d293b539bbfae148366cfb3687.1766146895.git.chleroy@kernel.org
2025-12-22 18:25:07 +05:30
Aboorva Devarajan
fbe409d138 powerpc/powernv: Enable cpuidle state detection for POWER11
Extend cpuidle state detection to POWER11 by updating the PVR check.
This ensures POWER11 correctly recognizes supported stop states,
similar to POWER9 and POWER10.

Without Patch: (Power11 - PowerNV systems)

CPUidle driver: powernv_idle
CPUidle governor: menu
analyzing CPU 927:

Number of idle states: 1
Available idle states: snooze
snooze:
Flags/Description: snooze
Latency: 0
Usage: 251631
Duration: 207497715900

--
With Patch: (Power11 - PowerNV systems)

CPUidle driver: powernv_idle
CPUidle governor: menu
analyzing CPU 959:

Number of idle states: 4
Available idle states: snooze stop0_lite stop0 stop3
snooze:
Flags/Description: snooze
Latency: 0
Usage: 2
Duration: 33
stop0_lite:
Flags/Description: stop0_lite
Latency: 1
Usage: 1
Duration: 52
stop0:
Flags/Description: stop0
Latency: 10
Usage: 13
Duration: 1920
stop3:
Flags/Description: stop3
Latency: 45
Usage: 381
Duration: 21638478

Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
Tested-by: Madadi Vineeth Reddy <vineethr@linux.ibm.com>
Reviewed-by: Madadi Vineeth Reddy <vineethr@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20250908085123.216780-1-aboorvad@linux.ibm.com
2025-12-22 18:08:56 +05:30
Finn Thain
b94b735675 powerpc: Add reloc_offset() to font bitmap pointer used for bootx_printf()
Since Linux v6.7, booting using BootX on an Old World PowerMac produces
an early crash. Stan Johnson writes, "the symptoms are that the screen
goes blank and the backlight stays on, and the system freezes (Linux
doesn't boot)."

Further testing revealed that the failure can be avoided by disabling
CONFIG_BOOTX_TEXT. Bisection revealed that the regression was caused by
a change to the font bitmap pointer that's used when btext_init() begins
painting characters on the display, early in the boot process.

Christophe Leroy explains, "before kernel text is relocated to its final
location ... data is addressed with an offset which is added to the
Global Offset Table (GOT) entries at the start of bootx_init()
by function reloc_got2(). But the pointers that are located inside a
structure are not referenced in the GOT and are therefore not updated by
reloc_got2(). It is therefore needed to apply the offset manually by using
PTRRELOC() macro."

Cc: stable@vger.kernel.org
Link: https://lists.debian.org/debian-powerpc/2025/10/msg00111.html
Link: https://lore.kernel.org/linuxppc-dev/d81ddca8-c5ee-d583-d579-02b19ed95301@yahoo.com/
Reported-by: Cedar Maxwell <cedarmaxwell@mac.com>
Closes: https://lists.debian.org/debian-powerpc/2025/09/msg00031.html
Bisected-by: Stan Johnson <userm57@yahoo.com>
Tested-by: Stan Johnson <userm57@yahoo.com>
Fixes: 0ebc7feae79a ("powerpc: Use shared font data")
Suggested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Finn Thain <fthain@linux-m68k.org>
Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/22b3b247425a052b079ab84da926706b3702c2c7.1762731022.git.fthain@linux-m68k.org
2025-12-22 17:59:07 +05:30
Jan Stancek
f1164534ad powerpc/tools: drop -o pipefail in gcc check scripts
Fixes: 0f71dcfb4aef ("powerpc/ftrace: Add support for -fpatchable-function-entry")
Fixes: b71c9ffb1405 ("powerpc: Add arch/powerpc/tools directory")
Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: Jan Stancek <jstancek@redhat.com>
Fixes: 8c50b72a3b4f ("powerpc/ftrace: Add Kconfig & Make glue for mprofile-kernel")
Fixes: abba759796f9 ("powerpc/kbuild: move -mprofile-kernel check to Kconfig")
Tested-by: Justin M. Forbes <jforbes@fedoraproject.org>
Reviewed-by: Naveen N Rao (AMD) <naveen@kernel.org>
Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/cc6cdd116c3ad9d990df21f13c6d8e8a83815bbd.1758641374.git.jstancek@redhat.com
2025-12-22 17:56:34 +05:30
Gopi Krishna Menon
42f53b3900 selftests/powerpc/pmu/: Add check_extended_reg_test to .gitignore
Add the check_extended_reg_test binary to .gitignore to avoid accidentally
staging the build artifact.

Signed-off-by: Gopi Krishna Menon <krishnagopi487@gmail.com>
Tested-by: Aditya Bodkhe <adityab1@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20250922004439.2395-1-krishnagopi487@gmail.com
2025-12-22 17:55:07 +05:30
Nysal Jan K.A.
c2296a1e42 powerpc/kexec: Enable SMT before waking offline CPUs
If SMT is disabled or a partial SMT state is enabled, when a new kernel
image is loaded for kexec, on reboot the following warning is observed:

kexec: Waking offline cpu 228.
WARNING: CPU: 0 PID: 9062 at arch/powerpc/kexec/core_64.c:223 kexec_prepare_cpus+0x1b0/0x1bc
[snip]
 NIP kexec_prepare_cpus+0x1b0/0x1bc
 LR  kexec_prepare_cpus+0x1a0/0x1bc
 Call Trace:
  kexec_prepare_cpus+0x1a0/0x1bc (unreliable)
  default_machine_kexec+0x160/0x19c
  machine_kexec+0x80/0x88
  kernel_kexec+0xd0/0x118
  __do_sys_reboot+0x210/0x2c4
  system_call_exception+0x124/0x320
  system_call_vectored_common+0x15c/0x2ec

This occurs as add_cpu() fails due to cpu_bootable() returning false for
CPUs that fail the cpu_smt_thread_allowed() check or non primary
threads if SMT is disabled.

Fix the issue by enabling SMT and resetting the number of SMT threads to
the number of threads per core, before attempting to wake up all present
CPUs.

Fixes: 38253464bc82 ("cpu/SMT: Create topology_smt_thread_allowed()")
Reported-by: Sachin P Bappalige <sachinpb@linux.ibm.com>
Cc: stable@vger.kernel.org # v6.6+
Reviewed-by: Srikar Dronamraju <srikar@linux.ibm.com>
Signed-off-by: Nysal Jan K.A. <nysal@linux.ibm.com>
Tested-by: Samir M <samir@linux.ibm.com>
Reviewed-by: Sourabh Jain <sourabhjain@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20251028105516.26258-1-nysal@linux.ibm.com
2025-12-22 17:53:37 +05:30
Himanshu Chauhan
5efaf92da4 riscv: Add SBI debug trigger extension and function ids
Debug trigger extension is an SBI extension to support native debugging
in S-mode and VS-mode. This patch adds the extension and the function
IDs defined by the extension.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Link: https://patch.msgid.link/20250710125231.653967-2-hchauhan@ventanamicro.com
[pjw@kernel.org: updated to apply]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2025-12-19 00:22:30 -07:00
Zongmin Zhou
f02dd25472 riscv/atomic.h: use RISCV_FULL_BARRIER in _arch_atomic* function.
Replace the same code with the pre-defined macro
RISCV_FULL_BARRIER to simplify the code.

Signed-off-by: Zongmin Zhou <zhouzongmin@kylinos.cn>
Link: https://patch.msgid.link/20251120095831.64211-1-min_halo@163.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2025-12-19 00:22:30 -07:00
Pincheng Wang
6118ebed3b riscv: hwprobe: export Zilsd and Zclsd ISA extensions
Export Zilsd and Zclsd ISA extensions through hwprobe.

Signed-off-by: Pincheng Wang <pincheng.plct@isrc.iscas.ac.cn>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Link: https://patch.msgid.link/20250826162939.1494021-4-pincheng.plct@isrc.iscas.ac.cn
[pjw@kernel.org: fixed whitespace; updated to apply]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2025-12-19 00:22:30 -07:00
Pincheng Wang
3f0cbfb8a1 riscv: add ISA extension parsing for Zilsd and Zclsd
Add parsing for Zilsd and Zclsd ISA extensions which were ratified in
commit f88abf1 ("Integrating load/store pair for RV32 with the
main manual") of the riscv-isa-manual.

Signed-off-by: Pincheng Wang <pincheng.plct@isrc.iscas.ac.cn>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Link: https://patch.msgid.link/20250826162939.1494021-3-pincheng.plct@isrc.iscas.ac.cn
[pjw@kernel.org: cleaned up checkpatch issues, whitespace; updated to apply]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2025-12-19 00:18:34 -07:00
Pincheng Wang
4115155baf dt-bindings: riscv: add Zilsd and Zclsd extension descriptions
Add descriptions for the Zilsd (Load/Store pair instructions) and
Zclsd (Compressed Load/Store pair instructions) ISA extensions
which were ratified in commit f88abf1 ("Integrating load/store
pair for RV32 with the main manual") of the riscv-isa-manual.

Signed-off-by: Pincheng Wang <pincheng.plct@isrc.iscas.ac.cn>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://patch.msgid.link/20250826162939.1494021-2-pincheng.plct@isrc.iscas.ac.cn
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2025-12-19 00:18:34 -07:00
Paul Walmsley
e0e51a0de0 riscv: mm: use xchg() on non-atomic_long_t variables, not atomic_long_xchg()
Let's not call atomic_long_xchg() on something that's not an
atomic_long_t, and just use xchg() instead.  Continues the cleanup
from commit 546e42c8c6d94 ("riscv: Use an atomic xchg in
pudp_huge_get_and_clear()"),

Cc: Alexandre Ghiti <alex@ghiti.fr>
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2025-12-19 00:18:33 -07:00
Paul Walmsley
425cc087fb riscv: mm: ptep_get_and_clear(): avoid atomic ops when !CONFIG_SMP
When !CONFIG_SMP, there's no need for atomic operations in
ptep_get_and_clear(), so, similar to x86, let's not use atomics in
this case.

Cc: Alexandre Ghiti <alex@ghiti.fr>
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2025-12-19 00:18:33 -07:00
Paul Walmsley
1e6084d5c4 riscv: mm: pmdp_huge_get_and_clear(): avoid atomic ops when !CONFIG_SMP
When !CONFIG_SMP, there's no need for atomic operations in
pmdp_huge_get_and_clear(), so, similar to what x86 does, let's not use
atomics in this case.  See also commit 546e42c8c6d94 ("riscv: Use an
atomic xchg in pudp_huge_get_and_clear()").

Cc: Alexandre Ghiti <alex@ghiti.fr>
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2025-12-19 00:18:33 -07:00
Andy Chiu
818d78ba1b riscv: signal: abstract header saving for setup_sigcontext
The function save_v_state() served two purposes. First, it saved
extension context into the signal stack. Then, it constructed the
extension header if there was no fault. The second part is independent
of the extension itself. As a result, we can pull that part out, so
future extensions may reuse it. This patch adds arch_ext_list and makes
setup_sigcontext() go through all possible extensions' save() callback.
The callback returns a positive value indicating the size of the
successfully saved extension. Then the kernel proceeds to construct the
header for that extension. The kernel skips an extension if it does
not exist, or if the saving fails for some reasons. The error code is
propagated out on the later case.

This patch does not introduce any functional changes.

Signed-off-by: Andy Chiu <andybnac@gmail.com>
Link: https://patch.msgid.link/20251112-v5_user_cfi_series-v23-16-b55691eacf4f@rivosinc.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2025-12-19 00:18:33 -07:00
Dan Carpenter
5edb7338d6 serial: 8250: longson: Fix NULL vs IS_ERR() bug in probe
The devm_platform_get_and_ioremap_resource() function never returns
NULL, it returns error pointers.  Fix the error checking to match.

Fixes: 25e95d763176 ("serial: 8250: Add Loongson uart driver support")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Link: https://patch.msgid.link/aSsIa3KdAlXh5uQC@stanley.mountain
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 15:11:00 +01:00
Andy Shevchenko
24ec03cc55 serial: core: Restore sysfs fwnode information
The change that restores sysfs fwnode information does it only for OF cases.
Update the fix to cover all possible types of fwnodes.

Fixes: d36f0e9a0002 ("serial: core: restore of_node information in sysfs")
Cc: stable <stable@kernel.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20251127163650.2942075-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 15:10:46 +01:00
Miaoqian Lin
3b4961313d usb: dwc3: of-simple: fix clock resource leak in dwc3_of_simple_probe
When clk_bulk_prepare_enable() fails, the error path jumps to
err_resetc_assert, skipping clk_bulk_put_all() and leaking the
clock references acquired by clk_bulk_get_all().

Add err_clk_put_all label to properly release clock resources
in all error paths.

Found via static analysis and code review.

Fixes: c0c61471ef86 ("usb: dwc3: of-simple: Convert to bulk clk API")
Cc: stable <stable@kernel.org>
Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://patch.msgid.link/20251211064937.2360510-1-linmq006@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 14:54:38 +01:00
Mario Limonciello (AMD)
14ad4c10d5 usb: typec: ucsi: Fix null pointer dereference in ucsi_sync_control_common
Add missing null check for cci parameter before dereferencing it in
ucsi_sync_control_common(). The function can be called with cci=NULL
from ucsi_acknowledge(), which leads to a null pointer dereference
when accessing *cci in the condition check.

The crash occurs because the code checks if cci is not null before
calling ucsi->ops->read_cci(ucsi, cci), but then immediately
dereferences cci without a null check in the following condition:
(*cci & UCSI_CCI_COMMAND_COMPLETE).

KASAN trace:
  KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
  RIP: 0010:ucsi_sync_control_common+0x2ae/0x4e0 [typec_ucsi]

Cc: stable <stable@kernel.org>
Fixes: 667ecac55861 ("usb: typec: ucsi: return CCI and message from sync_control callback")
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
Link: https://patch.msgid.link/20251216122210.5457-1-superm1@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 14:54:23 +01:00
Ma Ke
c84117912b USB: lpc32xx_udc: Fix error handling in probe
lpc32xx_udc_probe() acquires an i2c_client reference through
isp1301_get_client() but fails to release it in both error handling
paths and the normal removal path. This could result in a reference
count leak for the I2C device, preventing proper cleanup and potentially
leading to resource exhaustion. Add put_device() to release the
reference in the probe failure path and in the remove function.

Calling path: isp1301_get_client() -> of_find_i2c_device_by_node() ->
i2c_find_device_by_fwnode(). As comments of i2c_find_device_by_fwnode()
says, 'The user must call put_device(&client->dev) once done with the
i2c client.'

Found by code review.

Cc: stable <stable@kernel.org>
Fixes: 24a28e428351 ("USB: gadget driver for LPC32xx")
Signed-off-by: Ma Ke <make24@iscas.ac.cn>
Link: https://patch.msgid.link/20251215020931.15324-1-make24@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 14:53:36 +01:00
Haoxiang Li
128bb7fab3 usb: typec: altmodes/displayport: Drop the device reference in dp_altmode_probe()
In error paths, call typec_altmode_put_plug() to drop the device reference
obtained by typec_altmode_get_plug().

Fixes: 71ba4fe56656 ("usb: typec: altmodes/displayport: add SOP' support")
Cc: stable <stable@kernel.org>
Signed-off-by: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20251206070445.190770-1-lihaoxiang@isrc.iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 14:53:16 +01:00
Duoming Zhou
41ca62e3e2 usb: phy: fsl-usb: Fix use-after-free in delayed work during device removal
The delayed work item otg_event is initialized in fsl_otg_conf() and
scheduled under two conditions:
1. When a host controller binds to the OTG controller.
2. When the USB ID pin state changes (cable insertion/removal).

A race condition occurs when the device is removed via fsl_otg_remove():
the fsl_otg instance may be freed while the delayed work is still pending
or executing. This leads to use-after-free when the work function
fsl_otg_event() accesses the already freed memory.

The problematic scenario:

(detach thread)            | (delayed work)
fsl_otg_remove()           |
  kfree(fsl_otg_dev) //FREE| fsl_otg_event()
                           |   og = container_of(...) //USE
                           |   og-> //USE

Fix this by calling disable_delayed_work_sync() in fsl_otg_remove()
before deallocating the fsl_otg structure. This ensures the delayed work
is properly canceled and completes execution prior to memory deallocation.

This bug was identified through static analysis.

Fixes: 0807c500a1a6 ("USB: add Freescale USB OTG Transceiver driver")
Cc: stable <stable@kernel.org>
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Link: https://patch.msgid.link/20251205034831.12846-1-duoming@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 14:52:12 +01:00
Haoxiang Li
36cc7e09df usb: renesas_usbhs: Fix a resource leak in usbhs_pipe_malloc()
usbhsp_get_pipe() set pipe's flags to IS_USED. In error paths,
usbhsp_put_pipe() is required to clear pipe's flags to prevent
pipe exhaustion.

Fixes: f1407d5c6624 ("usb: renesas_usbhs: Add Renesas USBHS common code")
Cc: stable <stable@kernel.org>
Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
Link: https://patch.msgid.link/20251204132129.109234-1-haoxiang_li2024@163.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 14:51:54 +01:00
Arnd Bergmann
d14cd998e6 usb: typec: ucsi: huawei-gaokin: add DRM dependency
Selecting DRM_AUX_HPD_BRIDGE is not possible from a built-in driver when
CONFIG_DRM=m:

WARNING: unmet direct dependencies detected for DRM_AUX_HPD_BRIDGE
  Depends on [m]: HAS_IOMEM [=y] && DRM [=m] && DRM_BRIDGE [=y] && OF [=y]
  Selected by [y]:
  - UCSI_HUAWEI_GAOKUN [=y] && USB_SUPPORT [=y] && TYPEC [=y] && TYPEC_UCSI [=y] && EC_HUAWEI_GAOKUN [=y] && DRM_BRIDGE [=y] && OF [=y]

Add the same dependency we have in similar drivers to work around this.

Fixes: 00327d7f2c8c ("usb: typec: ucsi: add Huawei Matebook E Go ucsi driver")
Cc: stable <stable@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20251204101111.1035975-1-arnd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 14:51:30 +01:00
Udipto Goswami
e1003aa7ec usb: dwc3: keep susphy enabled during exit to avoid controller faults
On some platforms, switching USB roles from host to device can trigger
controller faults due to premature PHY power-down. This occurs when the
PHY is disabled too early during teardown, causing synchronization
issues between the PHY and controller.

Keep susphy enabled during dwc3_host_exit() and dwc3_gadget_exit()
ensures the PHY remains in a low-power state capable of handling
required commands during role switch.

Cc: stable <stable@kernel.org>
Fixes: 6d735722063a ("usb: dwc3: core: Prevent phy suspend during init")
Suggested-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Signed-off-by: Udipto Goswami <udipto.goswami@oss.qualcomm.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://patch.msgid.link/20251126054221.120638-1-udipto.goswami@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 14:49:18 +01:00
Łukasz Bartosik
74098cc06e xhci: dbgtty: fix device unregister: fixup
This fixup replaces tty_vhangup() call with call to
tty_port_tty_vhangup(). Both calls hangup tty device
synchronously however tty_port_tty_vhangup() increases
reference count during the hangup operation using
scoped_guard(tty_port_tty).

Cc: stable <stable@kernel.org>
Fixes: 1f73b8b56cf3 ("xhci: dbgtty: fix device unregister")
Signed-off-by: Łukasz Bartosik <ukaszb@chromium.org>
Link: https://patch.msgid.link/20251127111644.3161386-1-ukaszb@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-17 14:48:42 +01:00
47 changed files with 352 additions and 278 deletions

View File

@ -281,6 +281,14 @@ The following keys are defined:
* :c:macro:`RISCV_HWPROBE_EXT_ZICBOP`: The Zicbop extension is supported, as
ratified in commit 3dd606f ("Create cmobase-v1.0.pdf") of riscv-CMOs.
* :c:macro:`RISCV_HWPROBE_EXT_ZILSD`: The Zilsd extension is supported as
defined in the RISC-V ISA manual starting from commit f88abf1 ("Integrating
load/store pair for RV32 with the main manual") of the riscv-isa-manual.
* :c:macro:`RISCV_HWPROBE_EXT_ZCLSD`: The Zclsd extension is supported as
defined in the RISC-V ISA manual starting from commit f88abf1 ("Integrating
load/store pair for RV32 with the main manual") of the riscv-isa-manual.
* :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: Deprecated. Returns similar values to
:c:macro:`RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF`, but the key was
mistakenly classified as a bitmask rather than a value.

View File

@ -377,6 +377,20 @@ properties:
guarantee on LR/SC sequences, as ratified in commit b1d806605f87
("Updated to ratified state.") of the riscv profiles specification.
- const: zilsd
description:
The standard Zilsd extension which provides support for aligned
register-pair load and store operations in 32-bit instruction
encodings, as ratified in commit f88abf1 ("Integrating
load/store pair for RV32 with the main manual") of riscv-isa-manual.
- const: zclsd
description:
The Zclsd extension implements the compressed (16-bit) version of the
Load/Store Pair for RV32. As with Zilsd, this extension was ratified
in commit f88abf1 ("Integrating load/store pair for RV32 with the
main manual") of riscv-isa-manual.
- const: zk
description:
The standard Zk Standard Scalar cryptography extension as ratified
@ -882,6 +896,16 @@ properties:
anyOf:
- const: v
- const: zve32x
# Zclsd depends on Zilsd and Zca
- if:
contains:
anyOf:
- const: zclsd
then:
contains:
allOf:
- const: zilsd
- const: zca
allOf:
# Zcf extension does not exist on rv64
@ -899,6 +923,18 @@ allOf:
not:
contains:
const: zcf
# Zilsd extension does not exist on rv64
- if:
properties:
riscv,isa-base:
contains:
const: rv64i
then:
properties:
riscv,isa-extensions:
not:
contains:
const: zilsd
additionalProperties: true
...

View File

@ -2,7 +2,7 @@
VERSION = 6
PATCHLEVEL = 19
SUBLEVEL = 0
EXTRAVERSION = -rc2
EXTRAVERSION = -rc3
NAME = Baby Opossum Posse
# *DOCUMENTATION*

View File

@ -90,7 +90,7 @@ static inline void __hard_EE_RI_disable(void)
if (IS_ENABLED(CONFIG_BOOKE))
wrtee(0);
else if (IS_ENABLED(CONFIG_PPC_8xx))
wrtspr(SPRN_NRI);
wrtspr_sync(SPRN_NRI);
else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
__mtmsrd(0, 1);
else

View File

@ -1400,6 +1400,7 @@ static inline void mtmsr_isync(unsigned long val)
: "r" ((unsigned long)(v)) \
: "memory")
#define wrtspr(rn) asm volatile("mtspr " __stringify(rn) ",2" : : : "memory")
#define wrtspr_sync(rn) asm volatile("mtspr " __stringify(rn) ",2; sync" : : : "memory")
static inline void wrtee(unsigned long val)
{

View File

@ -20,6 +20,7 @@
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/udbg.h>
#include <asm/setup.h>
#define NO_SCROLL
@ -463,7 +464,7 @@ static noinline void draw_byte(unsigned char c, long locX, long locY)
{
unsigned char *base = calc_base(locX << 3, locY << 4);
unsigned int font_index = c * 16;
const unsigned char *font = font_sun_8x16.data + font_index;
const unsigned char *font = PTRRELOC(font_sun_8x16.data) + font_index;
int rb = dispDeviceRowBytes;
rmci_maybe_on();

View File

@ -101,17 +101,6 @@ SYM_FUNC_END(__kuep_unlock)
.endm
#endif
.macro clr_ri trash
#ifndef CONFIG_BOOKE
#ifdef CONFIG_PPC_8xx
mtspr SPRN_NRI, \trash
#else
li \trash, MSR_KERNEL & ~MSR_RI
mtmsr \trash
#endif
#endif
.endm
.globl transfer_to_syscall
transfer_to_syscall:
stw r3, ORIG_GPR3(r1)
@ -160,7 +149,6 @@ ret_from_syscall:
cmpwi r3,0
REST_GPR(3, r1)
syscall_exit_finish:
clr_ri r4
mtspr SPRN_SRR0,r7
mtspr SPRN_SRR1,r8
@ -237,7 +225,6 @@ fast_exception_return:
/* Clear the exception marker on the stack to avoid confusing stacktrace */
li r10, 0
stw r10, 8(r11)
clr_ri r10
mtspr SPRN_SRR1,r9
mtspr SPRN_SRR0,r12
REST_GPR(9, r11)
@ -270,7 +257,6 @@ interrupt_return:
.Lfast_user_interrupt_return:
lwz r11,_NIP(r1)
lwz r12,_MSR(r1)
clr_ri r4
mtspr SPRN_SRR0,r11
mtspr SPRN_SRR1,r12
@ -313,7 +299,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
cmpwi cr1,r3,0
lwz r11,_NIP(r1)
lwz r12,_MSR(r1)
clr_ri r4
mtspr SPRN_SRR0,r11
mtspr SPRN_SRR1,r12

View File

@ -38,7 +38,7 @@ static inline bool exit_must_hard_disable(void)
#else
static inline bool exit_must_hard_disable(void)
{
return false;
return true;
}
#endif
@ -443,6 +443,9 @@ again:
if (unlikely(stack_store))
__hard_EE_RI_disable();
#else
} else {
__hard_EE_RI_disable();
#endif /* CONFIG_PPC64 */
}

View File

@ -202,6 +202,23 @@ static void kexec_prepare_cpus_wait(int wait_state)
mb();
}
/*
* The add_cpu() call in wake_offline_cpus() can fail as cpu_bootable()
* returns false for CPUs that fail the cpu_smt_thread_allowed() check
* or non primary threads if SMT is disabled. Re-enable SMT and set the
* number of SMT threads to threads per core.
*/
static void kexec_smt_reenable(void)
{
#if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT)
lock_device_hotplug();
cpu_smt_num_threads = threads_per_core;
cpu_smt_control = CPU_SMT_ENABLED;
unlock_device_hotplug();
#endif
}
/*
* We need to make sure each present CPU is online. The next kernel will scan
* the device tree and assume primary threads are online and query secondary
@ -216,6 +233,8 @@ static void wake_offline_cpus(void)
{
int cpu = 0;
kexec_smt_reenable();
for_each_present_cpu(cpu) {
if (!cpu_online(cpu)) {
printk(KERN_INFO "kexec: Waking offline cpu %d.\n",

View File

@ -1171,8 +1171,9 @@ static void __init pnv_arch300_idle_init(void)
u64 max_residency_ns = 0;
int i;
/* stop is not really architected, we only have p9,p10 drivers */
if (!pvr_version_is(PVR_POWER10) && !pvr_version_is(PVR_POWER9))
/* stop is not really architected, we only have p9,p10 and p11 drivers */
if (!pvr_version_is(PVR_POWER9) && !pvr_version_is(PVR_POWER10) &&
!pvr_version_is(PVR_POWER11))
return;
/*
@ -1189,8 +1190,8 @@ static void __init pnv_arch300_idle_init(void)
struct pnv_idle_states_t *state = &pnv_idle_states[i];
u64 psscr_rl = state->psscr_val & PSSCR_RL_MASK;
/* No deep loss driver implemented for POWER10 yet */
if (pvr_version_is(PVR_POWER10) &&
/* No deep loss driver implemented for POWER10 and POWER11 yet */
if ((pvr_version_is(PVR_POWER10) || pvr_version_is(PVR_POWER11)) &&
state->flags & (OPAL_PM_TIMEBASE_STOP|OPAL_PM_LOSE_FULL_CONTEXT))
continue;

View File

@ -2,7 +2,6 @@
# SPDX-License-Identifier: GPL-2.0
set -e
set -o pipefail
# To debug, uncomment the following line
# set -x

View File

@ -2,7 +2,6 @@
# SPDX-License-Identifier: GPL-2.0
set -e
set -o pipefail
# To debug, uncomment the following line
# set -x

View File

@ -203,7 +203,7 @@ ATOMIC_OPS(xor, xor, i)
" add %[rc], %[p], %[a]\n" \
" sc." sfx ".rl %[rc], %[rc], %[c]\n" \
" bnez %[rc], 0b\n" \
" fence rw, rw\n" \
RISCV_FULL_BARRIER \
"1:\n" \
: [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
: [a]"r" (_a), [u]"r" (_u) \
@ -242,7 +242,7 @@ static __always_inline s64 arch_atomic64_fetch_add_unless(atomic64_t *v, s64 a,
" addi %[rc], %[p], 1\n" \
" sc." sfx ".rl %[rc], %[rc], %[c]\n" \
" bnez %[rc], 0b\n" \
" fence rw, rw\n" \
RISCV_FULL_BARRIER \
"1:\n" \
: [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
: \
@ -268,7 +268,7 @@ static __always_inline bool arch_atomic_inc_unless_negative(atomic_t *v)
" addi %[rc], %[p], -1\n" \
" sc." sfx ".rl %[rc], %[rc], %[c]\n" \
" bnez %[rc], 0b\n" \
" fence rw, rw\n" \
RISCV_FULL_BARRIER \
"1:\n" \
: [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
: \
@ -294,7 +294,7 @@ static __always_inline bool arch_atomic_dec_unless_positive(atomic_t *v)
" bltz %[rc], 1f\n" \
" sc." sfx ".rl %[rc], %[rc], %[c]\n" \
" bnez %[rc], 0b\n" \
" fence rw, rw\n" \
RISCV_FULL_BARRIER \
"1:\n" \
: [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \
: \

View File

@ -108,6 +108,8 @@
#define RISCV_ISA_EXT_ZICBOP 99
#define RISCV_ISA_EXT_SVRSW60T59B 100
#define RISCV_ISA_EXT_ZALASR 101
#define RISCV_ISA_EXT_ZILSD 102
#define RISCV_ISA_EXT_ZCLSD 103
#define RISCV_ISA_EXT_XLINUXENVCFG 127

View File

@ -660,7 +660,13 @@ extern int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long a
static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
unsigned long address, pte_t *ptep)
{
pte_t pte = __pte(atomic_long_xchg((atomic_long_t *)ptep, 0));
#ifdef CONFIG_SMP
pte_t pte = __pte(xchg(&ptep->pte, 0));
#else
pte_t pte = *ptep;
set_pte(ptep, __pte(0));
#endif
page_table_check_pte_clear(mm, pte);
@ -997,7 +1003,13 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
unsigned long address, pmd_t *pmdp)
{
pmd_t pmd = __pmd(atomic_long_xchg((atomic_long_t *)pmdp, 0));
#ifdef CONFIG_SMP
pmd_t pmd = __pmd(xchg(&pmdp->pmd, 0));
#else
pmd_t pmd = *pmdp;
pmd_clear(pmdp);
#endif
page_table_check_pmd_clear(mm, pmd);

View File

@ -37,6 +37,7 @@ enum sbi_ext_id {
SBI_EXT_NACL = 0x4E41434C,
SBI_EXT_FWFT = 0x46574654,
SBI_EXT_MPXY = 0x4D505859,
SBI_EXT_DBTR = 0x44425452,
/* Experimentals extensions must lie within this range */
SBI_EXT_EXPERIMENTAL_START = 0x08000000,
@ -505,6 +506,34 @@ enum sbi_mpxy_rpmi_attribute_id {
#define SBI_MPXY_CHAN_CAP_SEND_WITHOUT_RESP BIT(4)
#define SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS BIT(5)
/* SBI debug triggers function IDs */
enum sbi_ext_dbtr_fid {
SBI_EXT_DBTR_NUM_TRIGGERS = 0,
SBI_EXT_DBTR_SETUP_SHMEM,
SBI_EXT_DBTR_TRIG_READ,
SBI_EXT_DBTR_TRIG_INSTALL,
SBI_EXT_DBTR_TRIG_UPDATE,
SBI_EXT_DBTR_TRIG_UNINSTALL,
SBI_EXT_DBTR_TRIG_ENABLE,
SBI_EXT_DBTR_TRIG_DISABLE,
};
struct sbi_dbtr_data_msg {
unsigned long tstate;
unsigned long tdata1;
unsigned long tdata2;
unsigned long tdata3;
};
struct sbi_dbtr_id_msg {
unsigned long idx;
};
union sbi_dbtr_shmem_entry {
struct sbi_dbtr_data_msg data;
struct sbi_dbtr_id_msg id;
};
/* SBI spec version fields */
#define SBI_SPEC_VERSION_DEFAULT 0x1
#define SBI_SPEC_VERSION_MAJOR_SHIFT 24

View File

@ -424,6 +424,9 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
#define riscv_v_thread_free(tsk) do {} while (0)
#define riscv_v_setup_ctx_cache() do {} while (0)
#define riscv_v_thread_alloc(tsk) do {} while (0)
#define get_cpu_vector_context() do {} while (0)
#define put_cpu_vector_context() do {} while (0)
#define riscv_v_vstate_set_restore(task, regs) do {} while (0)
#endif /* CONFIG_RISCV_ISA_V */

View File

@ -84,6 +84,9 @@ struct riscv_hwprobe {
#define RISCV_HWPROBE_EXT_ZABHA (1ULL << 58)
#define RISCV_HWPROBE_EXT_ZALASR (1ULL << 59)
#define RISCV_HWPROBE_EXT_ZICBOP (1ULL << 60)
#define RISCV_HWPROBE_EXT_ZILSD (1ULL << 61)
#define RISCV_HWPROBE_EXT_ZCLSD (1ULL << 62)
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)

View File

@ -242,6 +242,28 @@ static int riscv_ext_zcf_validate(const struct riscv_isa_ext_data *data,
return -EPROBE_DEFER;
}
static int riscv_ext_zilsd_validate(const struct riscv_isa_ext_data *data,
const unsigned long *isa_bitmap)
{
if (IS_ENABLED(CONFIG_64BIT))
return -EINVAL;
return 0;
}
static int riscv_ext_zclsd_validate(const struct riscv_isa_ext_data *data,
const unsigned long *isa_bitmap)
{
if (IS_ENABLED(CONFIG_64BIT))
return -EINVAL;
if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZILSD) &&
__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZCA))
return 0;
return -EPROBE_DEFER;
}
static int riscv_vector_f_validate(const struct riscv_isa_ext_data *data,
const unsigned long *isa_bitmap)
{
@ -484,6 +506,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA_VALIDATE(zcd, RISCV_ISA_EXT_ZCD, riscv_ext_zcd_validate),
__RISCV_ISA_EXT_DATA_VALIDATE(zcf, RISCV_ISA_EXT_ZCF, riscv_ext_zcf_validate),
__RISCV_ISA_EXT_DATA_VALIDATE(zcmop, RISCV_ISA_EXT_ZCMOP, riscv_ext_zca_depends),
__RISCV_ISA_EXT_DATA_VALIDATE(zclsd, RISCV_ISA_EXT_ZCLSD, riscv_ext_zclsd_validate),
__RISCV_ISA_EXT_DATA_VALIDATE(zilsd, RISCV_ISA_EXT_ZILSD, riscv_ext_zilsd_validate),
__RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA),
__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
__RISCV_ISA_EXT_DATA(zbc, RISCV_ISA_EXT_ZBC),

View File

@ -68,18 +68,19 @@ static long save_fp_state(struct pt_regs *regs,
#define restore_fp_state(task, regs) (0)
#endif
#ifdef CONFIG_RISCV_ISA_V
static long save_v_state(struct pt_regs *regs, void __user **sc_vec)
static long save_v_state(struct pt_regs *regs, void __user *sc_vec)
{
struct __riscv_ctx_hdr __user *hdr;
struct __sc_riscv_v_state __user *state;
void __user *datap;
long err;
hdr = *sc_vec;
/* Place state to the user's signal context space after the hdr */
state = (struct __sc_riscv_v_state __user *)(hdr + 1);
if (!IS_ENABLED(CONFIG_RISCV_ISA_V) ||
!((has_vector() || has_xtheadvector()) &&
riscv_v_vstate_query(regs)))
return 0;
/* Place state to the user's signal context space */
state = (struct __sc_riscv_v_state __user *)sc_vec;
/* Point datap right after the end of __sc_riscv_v_state */
datap = state + 1;
@ -97,15 +98,11 @@ static long save_v_state(struct pt_regs *regs, void __user **sc_vec)
err |= __put_user((__force void *)datap, &state->v_state.datap);
/* Copy the whole vector content to user space datap. */
err |= __copy_to_user(datap, current->thread.vstate.datap, riscv_v_vsize);
/* Copy magic to the user space after saving all vector conetext */
err |= __put_user(RISCV_V_MAGIC, &hdr->magic);
err |= __put_user(riscv_v_sc_size, &hdr->size);
if (unlikely(err))
return err;
return -EFAULT;
/* Only progress the sv_vec if everything has done successfully */
*sc_vec += riscv_v_sc_size;
return 0;
/* Only return the size if everything has done successfully */
return riscv_v_sc_size;
}
/*
@ -142,10 +139,20 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
*/
return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
}
#else
#define save_v_state(task, regs) (0)
#define __restore_v_state(task, regs) (0)
#endif
struct arch_ext_priv {
__u32 magic;
long (*save)(struct pt_regs *regs, void __user *sc_vec);
};
struct arch_ext_priv arch_ext_list[] = {
{
.magic = RISCV_V_MAGIC,
.save = &save_v_state,
},
};
const size_t nr_arch_exts = ARRAY_SIZE(arch_ext_list);
static long restore_sigcontext(struct pt_regs *regs,
struct sigcontext __user *sc)
@ -270,7 +277,8 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
{
struct sigcontext __user *sc = &frame->uc.uc_mcontext;
struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
long err;
struct arch_ext_priv *arch_ext;
long err, i, ext_size;
/* sc_regs is structured the same as the start of pt_regs */
err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs));
@ -278,8 +286,20 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
if (has_fpu())
err |= save_fp_state(regs, &sc->sc_fpregs);
/* Save the vector state. */
if ((has_vector() || has_xtheadvector()) && riscv_v_vstate_query(regs))
err |= save_v_state(regs, (void __user **)&sc_ext_ptr);
for (i = 0; i < nr_arch_exts; i++) {
arch_ext = &arch_ext_list[i];
if (!arch_ext->save)
continue;
ext_size = arch_ext->save(regs, sc_ext_ptr + 1);
if (ext_size <= 0) {
err |= ext_size;
} else {
err |= __put_user(arch_ext->magic, &sc_ext_ptr->magic);
err |= __put_user(ext_size, &sc_ext_ptr->size);
sc_ext_ptr = (void *)sc_ext_ptr + ext_size;
}
}
/* Write zero to fp-reserved space and check it on restore_sigcontext */
err |= __put_user(0, &sc->sc_extdesc.reserved);
/* And put END __riscv_ctx_hdr at the end. */

View File

@ -121,6 +121,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
EXT_KEY(ZBS);
EXT_KEY(ZCA);
EXT_KEY(ZCB);
EXT_KEY(ZCLSD);
EXT_KEY(ZCMOP);
EXT_KEY(ZICBOM);
EXT_KEY(ZICBOP);
@ -130,6 +131,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
EXT_KEY(ZIHINTNTL);
EXT_KEY(ZIHINTPAUSE);
EXT_KEY(ZIHPM);
EXT_KEY(ZILSD);
EXT_KEY(ZIMOP);
EXT_KEY(ZKND);
EXT_KEY(ZKNE);

View File

@ -36,6 +36,8 @@
static char driver_name[] = KBUILD_MODNAME;
#define RCV_BUFFER_SIZE (16 * 1024)
/* this is the physical layout of a PCL, its size is 128 bytes */
struct pcl {
__le32 next;
@ -517,16 +519,14 @@ remove_card(struct pci_dev *dev)
lynx->rcv_start_pcl, lynx->rcv_start_pcl_bus);
dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl),
lynx->rcv_pcl, lynx->rcv_pcl_bus);
dma_free_coherent(&lynx->pci_device->dev, PAGE_SIZE, lynx->rcv_buffer,
lynx->rcv_buffer_bus);
dma_free_coherent(&lynx->pci_device->dev, RCV_BUFFER_SIZE,
lynx->rcv_buffer, lynx->rcv_buffer_bus);
iounmap(lynx->registers);
pci_disable_device(dev);
lynx_put(lynx);
}
#define RCV_BUFFER_SIZE (16 * 1024)
static int
add_card(struct pci_dev *dev, const struct pci_device_id *unused)
{
@ -680,7 +680,7 @@ fail_deallocate_buffers:
dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl),
lynx->rcv_pcl, lynx->rcv_pcl_bus);
if (lynx->rcv_buffer)
dma_free_coherent(&lynx->pci_device->dev, PAGE_SIZE,
dma_free_coherent(&lynx->pci_device->dev, RCV_BUFFER_SIZE,
lynx->rcv_buffer, lynx->rcv_buffer_bus);
iounmap(lynx->registers);

View File

@ -128,8 +128,8 @@ static int loongson_uart_probe(struct platform_device *pdev)
port->private_data = priv;
port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &priv->res);
if (!port->membase)
return -ENOMEM;
if (IS_ERR(port->membase))
return PTR_ERR(port->membase);
port->mapbase = priv->res->start;
port->mapsize = resource_size(priv->res);

View File

@ -13,7 +13,7 @@
#include <linux/device.h>
#include <linux/idr.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/serial_core.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@ -60,6 +60,7 @@ void serial_base_driver_unregister(struct device_driver *driver)
driver_unregister(driver);
}
/* On failure the caller must put device @dev with put_device() */
static int serial_base_device_init(struct uart_port *port,
struct device *dev,
struct device *parent_dev,
@ -73,7 +74,9 @@ static int serial_base_device_init(struct uart_port *port,
dev->parent = parent_dev;
dev->bus = &serial_base_bus_type;
dev->release = release;
device_set_of_node_from_dev(dev, parent_dev);
dev->of_node_reused = true;
device_set_node(dev, fwnode_handle_get(dev_fwnode(parent_dev)));
if (!serial_base_initialized) {
dev_dbg(port->dev, "uart_add_one_port() called before arch_initcall()?\n");
@ -94,7 +97,7 @@ static void serial_base_ctrl_release(struct device *dev)
{
struct serial_ctrl_device *ctrl_dev = to_serial_base_ctrl_device(dev);
of_node_put(dev->of_node);
fwnode_handle_put(dev_fwnode(dev));
kfree(ctrl_dev);
}
@ -142,7 +145,7 @@ static void serial_base_port_release(struct device *dev)
{
struct serial_port_device *port_dev = to_serial_base_port_device(dev);
of_node_put(dev->of_node);
fwnode_handle_put(dev_fwnode(dev));
kfree(port_dev);
}

View File

@ -1914,7 +1914,7 @@ static void sci_dma_check_tx_occurred(struct sci_port *s)
struct dma_tx_state state;
enum dma_status status;
if (!s->chan_tx)
if (!s->chan_tx || s->cookie_tx <= 0)
return;
status = dmaengine_tx_status(s->chan_tx, s->cookie_tx, &state);

View File

@ -428,10 +428,17 @@ static void cdns_uart_handle_tx(void *dev_id)
struct tty_port *tport = &port->state->port;
unsigned int numbytes;
unsigned char ch;
ktime_t rts_delay;
if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
/* Disable the TX Empty interrupt */
writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IDR);
/* Set RTS line after delay */
if (cdns_uart->port->rs485.flags & SER_RS485_ENABLED) {
cdns_uart->tx_timer.function = &cdns_rs485_rx_callback;
rts_delay = ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart));
hrtimer_start(&cdns_uart->tx_timer, rts_delay, HRTIMER_MODE_REL);
}
return;
}
@ -448,13 +455,6 @@ static void cdns_uart_handle_tx(void *dev_id)
/* Enable the TX Empty interrupt */
writel(CDNS_UART_IXR_TXEMPTY, cdns_uart->port->membase + CDNS_UART_IER);
if (cdns_uart->port->rs485.flags & SER_RS485_ENABLED &&
(kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port))) {
hrtimer_update_function(&cdns_uart->tx_timer, cdns_rs485_rx_callback);
hrtimer_start(&cdns_uart->tx_timer,
ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart)), HRTIMER_MODE_REL);
}
}
/**

View File

@ -70,11 +70,11 @@ static int dwc3_of_simple_probe(struct platform_device *pdev)
simple->num_clocks = ret;
ret = clk_bulk_prepare_enable(simple->num_clocks, simple->clks);
if (ret)
goto err_resetc_assert;
goto err_clk_put_all;
ret = of_platform_populate(np, NULL, NULL, dev);
if (ret)
goto err_clk_put;
goto err_clk_disable;
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
@ -82,8 +82,9 @@ static int dwc3_of_simple_probe(struct platform_device *pdev)
return 0;
err_clk_put:
err_clk_disable:
clk_bulk_disable_unprepare(simple->num_clocks, simple->clks);
err_clk_put_all:
clk_bulk_put_all(simple->num_clocks, simple->clks);
err_resetc_assert:

View File

@ -4826,7 +4826,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
if (!dwc->gadget)
return;
dwc3_enable_susphy(dwc, false);
dwc3_enable_susphy(dwc, true);
usb_del_gadget(dwc->gadget);
dwc3_gadget_free_endpoints(dwc);
usb_put_gadget(dwc->gadget);

View File

@ -227,7 +227,7 @@ void dwc3_host_exit(struct dwc3 *dwc)
if (dwc->sys_wakeup)
device_init_wakeup(&dwc->xhci->dev, false);
dwc3_enable_susphy(dwc, false);
dwc3_enable_susphy(dwc, true);
platform_device_unregister(dwc->xhci);
dwc->xhci = NULL;
}

View File

@ -3020,7 +3020,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
pdev->dev.dma_mask = &lpc32xx_usbd_dmamask;
retval = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (retval)
return retval;
goto err_put_client;
udc->board = &lpc32xx_usbddata;
@ -3038,28 +3038,32 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
/* Get IRQs */
for (i = 0; i < 4; i++) {
udc->udp_irq[i] = platform_get_irq(pdev, i);
if (udc->udp_irq[i] < 0)
return udc->udp_irq[i];
if (udc->udp_irq[i] < 0) {
retval = udc->udp_irq[i];
goto err_put_client;
}
}
udc->udp_baseaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(udc->udp_baseaddr)) {
dev_err(udc->dev, "IO map failure\n");
return PTR_ERR(udc->udp_baseaddr);
retval = PTR_ERR(udc->udp_baseaddr);
goto err_put_client;
}
/* Get USB device clock */
udc->usb_slv_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(udc->usb_slv_clk)) {
dev_err(udc->dev, "failed to acquire USB device clock\n");
return PTR_ERR(udc->usb_slv_clk);
retval = PTR_ERR(udc->usb_slv_clk);
goto err_put_client;
}
/* Enable USB device clock */
retval = clk_prepare_enable(udc->usb_slv_clk);
if (retval < 0) {
dev_err(udc->dev, "failed to start USB device clock\n");
return retval;
goto err_put_client;
}
/* Setup deferred workqueue data */
@ -3080,7 +3084,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
if (!udc->udca_v_base) {
dev_err(udc->dev, "error getting UDCA region\n");
retval = -ENOMEM;
goto i2c_fail;
goto err_disable_clk;
}
udc->udca_p_base = dma_handle;
dev_dbg(udc->dev, "DMA buffer(0x%x bytes), P:0x%08x, V:0x%p\n",
@ -3093,7 +3097,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
if (!udc->dd_cache) {
dev_err(udc->dev, "error getting DD DMA region\n");
retval = -ENOMEM;
goto dma_alloc_fail;
goto err_free_dma;
}
/* Clear USB peripheral and initialize gadget endpoints */
@ -3107,14 +3111,14 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
if (retval < 0) {
dev_err(udc->dev, "LP request irq %d failed\n",
udc->udp_irq[IRQ_USB_LP]);
goto irq_req_fail;
goto err_destroy_pool;
}
retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_HP],
lpc32xx_usb_hp_irq, 0, "udc_hp", udc);
if (retval < 0) {
dev_err(udc->dev, "HP request irq %d failed\n",
udc->udp_irq[IRQ_USB_HP]);
goto irq_req_fail;
goto err_destroy_pool;
}
retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_DEVDMA],
@ -3122,7 +3126,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
if (retval < 0) {
dev_err(udc->dev, "DEV request irq %d failed\n",
udc->udp_irq[IRQ_USB_DEVDMA]);
goto irq_req_fail;
goto err_destroy_pool;
}
/* The transceiver interrupt is used for VBUS detection and will
@ -3133,7 +3137,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
if (retval < 0) {
dev_err(udc->dev, "VBUS request irq %d failed\n",
udc->udp_irq[IRQ_USB_ATX]);
goto irq_req_fail;
goto err_destroy_pool;
}
/* Initialize wait queue */
@ -3142,7 +3146,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
retval = usb_add_gadget_udc(dev, &udc->gadget);
if (retval < 0)
goto add_gadget_fail;
goto err_destroy_pool;
dev_set_drvdata(dev, udc);
device_init_wakeup(dev, 1);
@ -3154,14 +3158,16 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
dev_info(udc->dev, "%s version %s\n", driver_name, DRIVER_VERSION);
return 0;
add_gadget_fail:
irq_req_fail:
err_destroy_pool:
dma_pool_destroy(udc->dd_cache);
dma_alloc_fail:
err_free_dma:
dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE,
udc->udca_v_base, udc->udca_p_base);
i2c_fail:
err_disable_clk:
clk_disable_unprepare(udc->usb_slv_clk);
err_put_client:
put_device(&udc->isp1301_i2c_client->dev);
dev_err(udc->dev, "%s probe failed, %d\n", driver_name, retval);
return retval;
@ -3190,6 +3196,8 @@ static void lpc32xx_udc_remove(struct platform_device *pdev)
udc->udca_v_base, udc->udca_p_base);
clk_disable_unprepare(udc->usb_slv_clk);
put_device(&udc->isp1301_i2c_client->dev);
}
#ifdef CONFIG_PM

View File

@ -169,13 +169,13 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (ret)
goto fail_disable;
goto err_put_client;
dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name);
if (usb_disabled()) {
dev_err(&pdev->dev, "USB is disabled\n");
ret = -ENODEV;
goto fail_disable;
goto err_put_client;
}
/* Enable USB host clock */
@ -183,7 +183,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
if (IS_ERR(usb_host_clk)) {
dev_err(&pdev->dev, "failed to acquire and start USB OHCI clock\n");
ret = PTR_ERR(usb_host_clk);
goto fail_disable;
goto err_put_client;
}
isp1301_configure();
@ -192,13 +192,13 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
if (!hcd) {
dev_err(&pdev->dev, "Failed to allocate HC buffer\n");
ret = -ENOMEM;
goto fail_disable;
goto err_put_client;
}
hcd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(hcd->regs)) {
ret = PTR_ERR(hcd->regs);
goto fail_resource;
goto err_put_hcd;
}
hcd->rsrc_start = res->start;
hcd->rsrc_len = resource_size(res);
@ -206,7 +206,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = -ENXIO;
goto fail_resource;
goto err_put_hcd;
}
ohci_nxp_start_hc();
@ -220,9 +220,10 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
}
ohci_nxp_stop_hc();
fail_resource:
err_put_hcd:
usb_put_hcd(hcd);
fail_disable:
err_put_client:
put_device(&isp1301_i2c_client->dev);
isp1301_i2c_client = NULL;
return ret;
}
@ -234,6 +235,7 @@ static void ohci_hcd_nxp_remove(struct platform_device *pdev)
usb_remove_hcd(hcd);
ohci_nxp_stop_hc();
usb_put_hcd(hcd);
put_device(&isp1301_i2c_client->dev);
isp1301_i2c_client = NULL;
}

View File

@ -554,7 +554,7 @@ static void xhci_dbc_tty_unregister_device(struct xhci_dbc *dbc)
* Hang up the TTY. This wakes up any blocked
* writers and causes subsequent writes to fail.
*/
tty_vhangup(port->port.tty);
tty_port_tty_vhangup(&port->port);
tty_unregister_device(dbc_tty_driver, port->minor);
xhci_dbc_tty_exit_port(port);

View File

@ -988,6 +988,7 @@ static void fsl_otg_remove(struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);
disable_delayed_work_sync(&fsl_otg_dev->otg_event);
usb_remove_phy(&fsl_otg_dev->phy);
free_irq(fsl_otg_dev->irq, fsl_otg_dev);

View File

@ -149,7 +149,12 @@ struct i2c_client *isp1301_get_client(struct device_node *node)
return client;
/* non-DT: only one ISP1301 chip supported */
return isp1301_i2c_client;
if (isp1301_i2c_client) {
get_device(&isp1301_i2c_client->dev);
return isp1301_i2c_client;
}
return NULL;
}
EXPORT_SYMBOL_GPL(isp1301_get_client);

View File

@ -713,11 +713,13 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
/* make sure pipe is not busy */
ret = usbhsp_pipe_barrier(pipe);
if (ret < 0) {
usbhsp_put_pipe(pipe);
dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe));
return NULL;
}
if (usbhsp_setup_pipecfg(pipe, is_host, dir_in, &pipecfg)) {
usbhsp_put_pipe(pipe);
dev_err(dev, "can't setup pipe\n");
return NULL;
}

View File

@ -98,7 +98,7 @@ UNUSUAL_DEV(0x125f, 0xa94a, 0x0160, 0x0160,
US_FL_NO_ATA_1X),
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
UNUSUAL_DEV(0x13fd, 0x3940, 0x0309, 0x0309,
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x0309,
"Initio Corporation",
"INIC-3069",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,

View File

@ -766,12 +766,16 @@ int dp_altmode_probe(struct typec_altmode *alt)
if (!(DP_CAP_PIN_ASSIGN_DFP_D(port->vdo) &
DP_CAP_PIN_ASSIGN_UFP_D(alt->vdo)) &&
!(DP_CAP_PIN_ASSIGN_UFP_D(port->vdo) &
DP_CAP_PIN_ASSIGN_DFP_D(alt->vdo)))
DP_CAP_PIN_ASSIGN_DFP_D(alt->vdo))) {
typec_altmode_put_plug(plug);
return -ENODEV;
}
dp = devm_kzalloc(&alt->dev, sizeof(*dp), GFP_KERNEL);
if (!dp)
if (!dp) {
typec_altmode_put_plug(plug);
return -ENOMEM;
}
INIT_WORK(&dp->work, dp_altmode_work);
mutex_init(&dp->lock);

View File

@ -96,6 +96,7 @@ config UCSI_LENOVO_YOGA_C630
config UCSI_HUAWEI_GAOKUN
tristate "UCSI Interface Driver for Huawei Matebook E Go"
depends on EC_HUAWEI_GAOKUN
depends on DRM || !DRM
select DRM_AUX_HPD_BRIDGE if DRM_BRIDGE && OF
help
This driver enables UCSI support on the Huawei Matebook E Go tablet,

View File

@ -105,12 +105,13 @@ static int cros_ucsi_async_control(struct ucsi *ucsi, u64 cmd)
return 0;
}
static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci)
static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci,
void *data, size_t size)
{
struct cros_ucsi_data *udata = ucsi_get_drvdata(ucsi);
int ret;
ret = ucsi_sync_control_common(ucsi, cmd, cci);
ret = ucsi_sync_control_common(ucsi, cmd, cci, data, size);
switch (ret) {
case -EBUSY:
/* EC may return -EBUSY if CCI.busy is set.

View File

@ -37,9 +37,7 @@ static int ucsi_cmd(void *data, u64 val)
case UCSI_SET_USB:
case UCSI_SET_POWER_LEVEL:
case UCSI_READ_POWER_LEVEL:
case UCSI_SET_PDOS:
ucsi->message_in_size = 0;
ret = ucsi_send_command(ucsi, val);
ret = ucsi_send_command(ucsi, val, NULL, 0);
break;
case UCSI_GET_CAPABILITY:
case UCSI_GET_CONNECTOR_CAPABILITY:
@ -54,9 +52,9 @@ static int ucsi_cmd(void *data, u64 val)
case UCSI_GET_ATTENTION_VDO:
case UCSI_GET_CAM_CS:
case UCSI_GET_LPM_PPM_INFO:
ucsi->message_in_size = sizeof(ucsi->debugfs->response);
ret = ucsi_send_command(ucsi, val);
memcpy(&ucsi->debugfs->response, ucsi->message_in, sizeof(ucsi->debugfs->response));
ret = ucsi_send_command(ucsi, val,
&ucsi->debugfs->response,
sizeof(ucsi->debugfs->response));
break;
default:
ret = -EOPNOTSUPP;
@ -111,30 +109,6 @@ static int ucsi_vbus_volt_show(struct seq_file *m, void *v)
}
DEFINE_SHOW_ATTRIBUTE(ucsi_vbus_volt);
static ssize_t ucsi_message_out_write(struct file *file,
const char __user *data, size_t count, loff_t *ppos)
{
struct ucsi *ucsi = file->private_data;
int ret;
char *buf __free(kfree) = memdup_user_nul(data, count);
if (IS_ERR(buf))
return PTR_ERR(buf);
ucsi->message_out_size = min(count / 2, UCSI_MAX_MESSAGE_OUT_LENGTH);
ret = hex2bin(ucsi->message_out, buf, ucsi->message_out_size);
if (ret)
return ret;
return count;
}
static const struct file_operations ucsi_message_out_fops = {
.open = simple_open,
.write = ucsi_message_out_write,
.llseek = generic_file_llseek,
};
void ucsi_debugfs_register(struct ucsi *ucsi)
{
ucsi->debugfs = kzalloc(sizeof(*ucsi->debugfs), GFP_KERNEL);
@ -147,8 +121,6 @@ void ucsi_debugfs_register(struct ucsi *ucsi)
debugfs_create_file("peak_current", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_peak_curr_fops);
debugfs_create_file("avg_current", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_avg_curr_fops);
debugfs_create_file("vbus_voltage", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_vbus_volt_fops);
debugfs_create_file("message_out", 0200, ucsi->debugfs->dentry, ucsi,
&ucsi_message_out_fops);
}
void ucsi_debugfs_unregister(struct ucsi *ucsi)

View File

@ -67,14 +67,11 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo)
}
command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(dp->con->num);
ucsi->message_in_size = sizeof(cur);
ret = ucsi_send_command(ucsi, command);
ret = ucsi_send_command(ucsi, command, &cur, sizeof(cur));
if (ret < 0) {
if (ucsi->version > 0x0100)
goto err_unlock;
cur = 0xff;
} else {
memcpy(&cur, ucsi->message_in, ucsi->message_in_size);
}
if (cur != 0xff) {
@ -129,8 +126,7 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
}
command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 0, dp->offset, 0);
dp->con->ucsi->message_in_size = 0;
ret = ucsi_send_command(dp->con->ucsi, command);
ret = ucsi_send_command(dp->con->ucsi, command, NULL, 0);
if (ret < 0)
goto out_unlock;
@ -197,8 +193,7 @@ static int ucsi_displayport_configure(struct ucsi_dp *dp)
command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 1, dp->offset, pins);
dp->con->ucsi->message_in_size = 0;
return ucsi_send_command(dp->con->ucsi, command);
return ucsi_send_command(dp->con->ucsi, command, NULL, 0);
}
static int ucsi_displayport_vdm(struct typec_altmode *alt,

View File

@ -55,7 +55,8 @@ void ucsi_notify_common(struct ucsi *ucsi, u32 cci)
}
EXPORT_SYMBOL_GPL(ucsi_notify_common);
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci)
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
void *data, size_t size)
{
bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI;
int ret;
@ -67,20 +68,6 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci)
reinit_completion(&ucsi->complete);
if (ucsi->message_out_size > 0) {
if (!ucsi->ops->write_message_out) {
ucsi->message_out_size = 0;
ret = -EOPNOTSUPP;
goto out_clear_bit;
}
ret = ucsi->ops->write_message_out(ucsi, ucsi->message_out,
ucsi->message_out_size);
ucsi->message_out_size = 0;
if (ret)
goto out_clear_bit;
}
ret = ucsi->ops->async_control(ucsi, command);
if (ret)
goto out_clear_bit;
@ -97,10 +84,9 @@ out_clear_bit:
if (!ret && cci)
ret = ucsi->ops->read_cci(ucsi, cci);
if (!ret && ucsi->message_in_size > 0 &&
if (!ret && data &&
(*cci & UCSI_CCI_COMMAND_COMPLETE))
ret = ucsi->ops->read_message_in(ucsi, ucsi->message_in,
ucsi->message_in_size);
ret = ucsi->ops->read_message_in(ucsi, data, size);
return ret;
}
@ -117,25 +103,23 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack)
ctrl |= UCSI_ACK_CONNECTOR_CHANGE;
}
ucsi->message_in_size = 0;
return ucsi->ops->sync_control(ucsi, ctrl, NULL);
return ucsi->ops->sync_control(ucsi, ctrl, NULL, NULL, 0);
}
static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, bool conn_ack)
static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
void *data, size_t size, bool conn_ack)
{
int ret, err;
*cci = 0;
if (ucsi->message_in_size > UCSI_MAX_DATA_LENGTH(ucsi))
if (size > UCSI_MAX_DATA_LENGTH(ucsi))
return -EINVAL;
ret = ucsi->ops->sync_control(ucsi, command, cci);
ret = ucsi->ops->sync_control(ucsi, command, cci, data, size);
if (*cci & UCSI_CCI_BUSY) {
ucsi->message_in_size = 0;
return ucsi_run_command(ucsi, UCSI_CANCEL, cci, false) ?: -EBUSY;
}
if (*cci & UCSI_CCI_BUSY)
return ucsi_run_command(ucsi, UCSI_CANCEL, cci, NULL, 0, false) ?: -EBUSY;
if (ret)
return ret;
@ -167,13 +151,10 @@ static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)
int ret;
command = UCSI_GET_ERROR_STATUS | UCSI_CONNECTOR_NUMBER(connector_num);
ucsi->message_in_size = sizeof(error);
ret = ucsi_run_command(ucsi, command, &cci, false);
ret = ucsi_run_command(ucsi, command, &cci, &error, sizeof(error), false);
if (ret < 0)
return ret;
memcpy(&error, ucsi->message_in, sizeof(error));
switch (error) {
case UCSI_ERROR_INCOMPATIBLE_PARTNER:
return -EOPNOTSUPP;
@ -219,7 +200,8 @@ static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)
return -EIO;
}
static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd, bool conn_ack)
static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd,
void *data, size_t size, bool conn_ack)
{
u8 connector_num;
u32 cci;
@ -247,7 +229,7 @@ static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd, bool conn_ack)
mutex_lock(&ucsi->ppm_lock);
ret = ucsi_run_command(ucsi, cmd, &cci, conn_ack);
ret = ucsi_run_command(ucsi, cmd, &cci, data, size, conn_ack);
if (cci & UCSI_CCI_ERROR)
ret = ucsi_read_error(ucsi, connector_num);
@ -256,9 +238,10 @@ static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd, bool conn_ack)
return ret;
}
int ucsi_send_command(struct ucsi *ucsi, u64 command)
int ucsi_send_command(struct ucsi *ucsi, u64 command,
void *data, size_t size)
{
return ucsi_send_command_common(ucsi, command, false);
return ucsi_send_command_common(ucsi, command, data, size, false);
}
EXPORT_SYMBOL_GPL(ucsi_send_command);
@ -336,8 +319,7 @@ void ucsi_altmode_update_active(struct ucsi_connector *con)
int i;
command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(con->num);
con->ucsi->message_in_size = sizeof(cur);
ret = ucsi_send_command(con->ucsi, command);
ret = ucsi_send_command(con->ucsi, command, &cur, sizeof(cur));
if (ret < 0) {
if (con->ucsi->version > 0x0100) {
dev_err(con->ucsi->dev,
@ -345,8 +327,6 @@ void ucsi_altmode_update_active(struct ucsi_connector *con)
return;
}
cur = 0xff;
} else {
memcpy(&cur, con->ucsi->message_in, sizeof(cur));
}
if (cur < UCSI_MAX_ALTMODES)
@ -530,8 +510,7 @@ ucsi_register_altmodes_nvidia(struct ucsi_connector *con, u8 recipient)
command |= UCSI_GET_ALTMODE_RECIPIENT(recipient);
command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num);
command |= UCSI_GET_ALTMODE_OFFSET(i);
ucsi->message_in_size = sizeof(alt);
len = ucsi_send_command(con->ucsi, command);
len = ucsi_send_command(con->ucsi, command, &alt, sizeof(alt));
/*
* We are collecting all altmodes first and then registering.
* Some type-C device will return zero length data beyond last
@ -540,8 +519,6 @@ ucsi_register_altmodes_nvidia(struct ucsi_connector *con, u8 recipient)
if (len < 0)
return len;
memcpy(&alt, ucsi->message_in, sizeof(alt));
/* We got all altmodes, now break out and register them */
if (!len || !alt.svid)
break;
@ -609,15 +586,12 @@ static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient)
command |= UCSI_GET_ALTMODE_RECIPIENT(recipient);
command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num);
command |= UCSI_GET_ALTMODE_OFFSET(i);
con->ucsi->message_in_size = sizeof(alt);
len = ucsi_send_command(con->ucsi, command);
len = ucsi_send_command(con->ucsi, command, alt, sizeof(alt));
if (len == -EBUSY)
continue;
if (len <= 0)
return len;
memcpy(&alt, con->ucsi->message_in, sizeof(alt));
/*
* This code is requesting one alt mode at a time, but some PPMs
* may still return two. If that happens both alt modes need be
@ -685,9 +659,7 @@ static int ucsi_get_connector_status(struct ucsi_connector *con, bool conn_ack)
UCSI_MAX_DATA_LENGTH(con->ucsi));
int ret;
con->ucsi->message_in_size = size;
ret = ucsi_send_command_common(con->ucsi, command, conn_ack);
memcpy(&con->status, con->ucsi->message_in, size);
ret = ucsi_send_command_common(con->ucsi, command, &con->status, size, conn_ack);
return ret < 0 ? ret : 0;
}
@ -710,9 +682,8 @@ static int ucsi_read_pdos(struct ucsi_connector *con,
command |= UCSI_GET_PDOS_PDO_OFFSET(offset);
command |= UCSI_GET_PDOS_NUM_PDOS(num_pdos - 1);
command |= is_source(role) ? UCSI_GET_PDOS_SRC_PDOS : 0;
ucsi->message_in_size = num_pdos * sizeof(u32);
ret = ucsi_send_command(ucsi, command);
memcpy(pdos + offset, ucsi->message_in, num_pdos * sizeof(u32));
ret = ucsi_send_command(ucsi, command, pdos + offset,
num_pdos * sizeof(u32));
if (ret < 0 && ret != -ETIMEDOUT)
dev_err(ucsi->dev, "UCSI_GET_PDOS failed (%d)\n", ret);
@ -799,9 +770,7 @@ static int ucsi_get_pd_message(struct ucsi_connector *con, u8 recipient,
command |= UCSI_GET_PD_MESSAGE_BYTES(len);
command |= UCSI_GET_PD_MESSAGE_TYPE(type);
con->ucsi->message_in_size = len;
ret = ucsi_send_command(con->ucsi, command);
memcpy(data + offset, con->ucsi->message_in, len);
ret = ucsi_send_command(con->ucsi, command, data + offset, len);
if (ret < 0)
return ret;
}
@ -966,9 +935,7 @@ static int ucsi_register_cable(struct ucsi_connector *con)
int ret;
command = UCSI_GET_CABLE_PROPERTY | UCSI_CONNECTOR_NUMBER(con->num);
con->ucsi->message_in_size = sizeof(cable_prop);
ret = ucsi_send_command(con->ucsi, command);
memcpy(&cable_prop, con->ucsi->message_in, sizeof(cable_prop));
ret = ucsi_send_command(con->ucsi, command, &cable_prop, sizeof(cable_prop));
if (ret < 0) {
dev_err(con->ucsi->dev, "GET_CABLE_PROPERTY failed (%d)\n", ret);
return ret;
@ -1029,9 +996,7 @@ static int ucsi_check_connector_capability(struct ucsi_connector *con)
return 0;
command = UCSI_GET_CONNECTOR_CAPABILITY | UCSI_CONNECTOR_NUMBER(con->num);
con->ucsi->message_in_size = sizeof(con->cap);
ret = ucsi_send_command(con->ucsi, command);
memcpy(&con->cap, con->ucsi->message_in, sizeof(con->cap));
ret = ucsi_send_command(con->ucsi, command, &con->cap, sizeof(con->cap));
if (ret < 0) {
dev_err(con->ucsi->dev, "GET_CONNECTOR_CAPABILITY failed (%d)\n", ret);
return ret;
@ -1415,8 +1380,7 @@ static int ucsi_reset_connector(struct ucsi_connector *con, bool hard)
else if (con->ucsi->version >= UCSI_VERSION_2_0)
command |= hard ? 0 : UCSI_CONNECTOR_RESET_DATA_VER_2_0;
con->ucsi->message_in_size = 0;
return ucsi_send_command(con->ucsi, command);
return ucsi_send_command(con->ucsi, command, NULL, 0);
}
static int ucsi_reset_ppm(struct ucsi *ucsi)
@ -1497,8 +1461,7 @@ static int ucsi_role_cmd(struct ucsi_connector *con, u64 command)
{
int ret;
con->ucsi->message_in_size = 0;
ret = ucsi_send_command(con->ucsi, command);
ret = ucsi_send_command(con->ucsi, command, NULL, 0);
if (ret == -ETIMEDOUT) {
u64 c;
@ -1506,8 +1469,7 @@ static int ucsi_role_cmd(struct ucsi_connector *con, u64 command)
ucsi_reset_ppm(con->ucsi);
c = UCSI_SET_NOTIFICATION_ENABLE | con->ucsi->ntfy;
con->ucsi->message_in_size = 0;
ucsi_send_command(con->ucsi, c);
ucsi_send_command(con->ucsi, c, NULL, 0);
ucsi_reset_connector(con, true);
}
@ -1660,13 +1622,10 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
/* Get connector capability */
command = UCSI_GET_CONNECTOR_CAPABILITY;
command |= UCSI_CONNECTOR_NUMBER(con->num);
ucsi->message_in_size = sizeof(con->cap);
ret = ucsi_send_command(ucsi, command);
ret = ucsi_send_command(ucsi, command, &con->cap, sizeof(con->cap));
if (ret < 0)
goto out_unlock;
memcpy(&con->cap, ucsi->message_in, sizeof(con->cap));
if (UCSI_CONCAP(con, OPMODE_DRP))
cap->data = TYPEC_PORT_DRD;
else if (UCSI_CONCAP(con, OPMODE_DFP))
@ -1863,20 +1822,17 @@ static int ucsi_init(struct ucsi *ucsi)
/* Enable basic notifications */
ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
command = UCSI_SET_NOTIFICATION_ENABLE | ntfy;
ucsi->message_in_size = 0;
ret = ucsi_send_command(ucsi, command);
ret = ucsi_send_command(ucsi, command, NULL, 0);
if (ret < 0)
goto err_reset;
/* Get PPM capabilities */
command = UCSI_GET_CAPABILITY;
ucsi->message_in_size = BITS_TO_BYTES(UCSI_GET_CAPABILITY_SIZE);
ret = ucsi_send_command(ucsi, command);
ret = ucsi_send_command(ucsi, command, &ucsi->cap,
BITS_TO_BYTES(UCSI_GET_CAPABILITY_SIZE));
if (ret < 0)
goto err_reset;
memcpy(&ucsi->cap, ucsi->message_in, BITS_TO_BYTES(UCSI_GET_CAPABILITY_SIZE));
if (!ucsi->cap.num_connectors) {
ret = -ENODEV;
goto err_reset;
@ -1906,8 +1862,7 @@ static int ucsi_init(struct ucsi *ucsi)
/* Enable all supported notifications */
ntfy = ucsi_get_supported_notifications(ucsi);
command = UCSI_SET_NOTIFICATION_ENABLE | ntfy;
ucsi->message_in_size = 0;
ret = ucsi_send_command(ucsi, command);
ret = ucsi_send_command(ucsi, command, NULL, 0);
if (ret < 0)
goto err_unregister;
@ -1958,8 +1913,7 @@ static void ucsi_resume_work(struct work_struct *work)
/* Restore UCSI notification enable mask after system resume */
command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
ucsi->message_in_size = 0;
ret = ucsi_send_command(ucsi, command);
ret = ucsi_send_command(ucsi, command, NULL, 0);
if (ret < 0) {
dev_err(ucsi->dev, "failed to re-enable notifications (%d)\n", ret);
return;

View File

@ -29,10 +29,6 @@ struct dentry;
#define UCSI_MESSAGE_OUT 32
#define UCSIv2_MESSAGE_OUT 272
/* Define maximum lengths for message buffers */
#define UCSI_MAX_MESSAGE_IN_LENGTH 256
#define UCSI_MAX_MESSAGE_OUT_LENGTH 256
/* UCSI versions */
#define UCSI_VERSION_1_0 0x0100
#define UCSI_VERSION_1_1 0x0110
@ -69,7 +65,6 @@ struct dentry;
* @read_cci: Read CCI register
* @poll_cci: Read CCI register while polling with notifications disabled
* @read_message_in: Read message data from UCSI
* @write_message_out: Write message data to UCSI
* @sync_control: Blocking control operation
* @async_control: Non-blocking control operation
* @update_altmodes: Squashes duplicate DP altmodes
@ -85,8 +80,8 @@ struct ucsi_operations {
int (*read_cci)(struct ucsi *ucsi, u32 *cci);
int (*poll_cci)(struct ucsi *ucsi, u32 *cci);
int (*read_message_in)(struct ucsi *ucsi, void *val, size_t val_len);
int (*write_message_out)(struct ucsi *ucsi, void *data, size_t data_len);
int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci);
int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci,
void *data, size_t size);
int (*async_control)(struct ucsi *ucsi, u64 command);
bool (*update_altmodes)(struct ucsi *ucsi, u8 recipient,
struct ucsi_altmode *orig,
@ -137,7 +132,6 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
#define UCSI_GET_PD_MESSAGE 0x15
#define UCSI_GET_CAM_CS 0x18
#define UCSI_SET_SINK_PATH 0x1c
#define UCSI_SET_PDOS 0x1d
#define UCSI_READ_POWER_LEVEL 0x1e
#define UCSI_SET_USB 0x21
#define UCSI_GET_LPM_PPM_INFO 0x22
@ -499,12 +493,6 @@ struct ucsi {
unsigned long quirks;
#define UCSI_NO_PARTNER_PDOS BIT(0) /* Don't read partner's PDOs */
#define UCSI_DELAY_DEVICE_PDOS BIT(1) /* Reading PDOs fails until the parter is in PD mode */
/* Fixed-size buffers for incoming and outgoing messages */
u8 message_in[UCSI_MAX_MESSAGE_IN_LENGTH];
size_t message_in_size;
u8 message_out[UCSI_MAX_MESSAGE_OUT_LENGTH];
size_t message_out_size;
};
#define UCSI_MAX_DATA_LENGTH(u) (((u)->version < UCSI_VERSION_2_0) ? 0x10 : 0xff)
@ -567,13 +555,15 @@ struct ucsi_connector {
struct usb_pd_identity cable_identity;
};
int ucsi_send_command(struct ucsi *ucsi, u64 command);
int ucsi_send_command(struct ucsi *ucsi, u64 command,
void *retval, size_t size);
void ucsi_altmode_update_active(struct ucsi_connector *con);
int ucsi_resume(struct ucsi *ucsi);
void ucsi_notify_common(struct ucsi *ucsi, u32 cci);
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci);
int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
void *data, size_t size);
#if IS_ENABLED(CONFIG_POWER_SUPPLY)
int ucsi_register_port_psy(struct ucsi_connector *con);

View File

@ -86,21 +86,6 @@ static int ucsi_acpi_read_message_in(struct ucsi *ucsi, void *val, size_t val_le
return 0;
}
static int ucsi_acpi_write_message_out(struct ucsi *ucsi, void *data, size_t data_len)
{
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
if (!data || !data_len)
return -EINVAL;
if (ucsi->version <= UCSI_VERSION_1_2)
memcpy(ua->base + UCSI_MESSAGE_OUT, data, data_len);
else
memcpy(ua->base + UCSIv2_MESSAGE_OUT, data, data_len);
return 0;
}
static int ucsi_acpi_async_control(struct ucsi *ucsi, u64 command)
{
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
@ -116,19 +101,19 @@ static const struct ucsi_operations ucsi_acpi_ops = {
.read_cci = ucsi_acpi_read_cci,
.poll_cci = ucsi_acpi_poll_cci,
.read_message_in = ucsi_acpi_read_message_in,
.write_message_out = ucsi_acpi_write_message_out,
.sync_control = ucsi_sync_control_common,
.async_control = ucsi_acpi_async_control
};
static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci)
static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
void *val, size_t len)
{
u16 bogus_change = UCSI_CONSTAT_POWER_LEVEL_CHANGE |
UCSI_CONSTAT_PDOS_CHANGE;
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
int ret;
ret = ucsi_sync_control_common(ucsi, command, cci);
ret = ucsi_sync_control_common(ucsi, command, cci, val, len);
if (ret < 0)
return ret;
@ -140,8 +125,8 @@ static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci)
if (UCSI_COMMAND(ua->cmd) == UCSI_GET_CONNECTOR_STATUS &&
ua->check_bogus_event) {
/* Clear the bogus change */
if (*(u16 *)ucsi->message_in == bogus_change)
*(u16 *)ucsi->message_in = 0;
if (*(u16 *)val == bogus_change)
*(u16 *)val = 0;
ua->check_bogus_event = false;
}

View File

@ -606,7 +606,8 @@ static int ucsi_ccg_async_control(struct ucsi *ucsi, u64 command)
return ccg_write(uc, reg, (u8 *)&command, sizeof(command));
}
static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci)
static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
void *data, size_t size)
{
struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
struct ucsi_connector *con;
@ -628,16 +629,16 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci)
ucsi_ccg_update_set_new_cam_cmd(uc, con, &command);
}
ret = ucsi_sync_control_common(ucsi, command, cci);
ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
switch (UCSI_COMMAND(command)) {
case UCSI_GET_CURRENT_CAM:
if (uc->has_multiple_dp)
ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)ucsi->message_in);
ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)data);
break;
case UCSI_GET_ALTERNATE_MODES:
if (UCSI_ALTMODE_RECIPIENT(command) == UCSI_RECIPIENT_SOP) {
struct ucsi_altmode *alt = (struct ucsi_altmode *)ucsi->message_in;
struct ucsi_altmode *alt = data;
if (alt[0].svid == USB_TYPEC_NVIDIA_VLINK_SID)
ucsi_ccg_nvidia_altmode(uc, alt, command);
@ -645,7 +646,7 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci)
break;
case UCSI_GET_CAPABILITY:
if (uc->fw_build == CCG_FW_BUILD_NVIDIA_TEGRA) {
struct ucsi_capability *cap = (struct ucsi_capability *)ucsi->message_in;
struct ucsi_capability *cap = data;
cap->features &= ~UCSI_CAP_ALT_MODE_DETAILS;
}

View File

@ -88,7 +88,8 @@ static int yoga_c630_ucsi_async_control(struct ucsi *ucsi, u64 command)
static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi,
u64 command,
u32 *cci)
u32 *cci,
void *data, size_t size)
{
int ret;
@ -106,8 +107,8 @@ static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi,
};
dev_dbg(ucsi->dev, "faking DP altmode for con1\n");
memset(ucsi->message_in, 0, ucsi->message_in_size);
memcpy(ucsi->message_in, &alt, min(sizeof(alt), ucsi->message_in_size));
memset(data, 0, size);
memcpy(data, &alt, min(sizeof(alt), size));
*cci = UCSI_CCI_COMMAND_COMPLETE | UCSI_SET_CCI_LENGTH(sizeof(alt));
return 0;
}
@ -120,18 +121,18 @@ static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi,
if (UCSI_COMMAND(command) == UCSI_GET_ALTERNATE_MODES &&
UCSI_GET_ALTMODE_GET_CONNECTOR_NUMBER(command) == 2) {
dev_dbg(ucsi->dev, "ignoring altmodes for con2\n");
memset(ucsi->message_in, 0, ucsi->message_in_size);
memset(data, 0, size);
*cci = UCSI_CCI_COMMAND_COMPLETE;
return 0;
}
ret = ucsi_sync_control_common(ucsi, command, cci);
ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
if (ret < 0)
return ret;
/* UCSI_GET_CURRENT_CAM is off-by-one on all ports */
if (UCSI_COMMAND(command) == UCSI_GET_CURRENT_CAM && ucsi->message_in_size > 0)
ucsi->message_in[0]--;
if (UCSI_COMMAND(command) == UCSI_GET_CURRENT_CAM && data)
((u8 *)data)[0]--;
return ret;
}

View File

@ -1,5 +1,6 @@
bhrb_filter_map_test
bhrb_no_crash_wo_pmu_test
check_extended_reg_test
intr_regs_no_crash_wo_pmu_test
mmcr0_cc56run_test
mmcr0_exceptionbits_test