]> Git Repo - linux.git/commitdiff
Merge tag 'driver-core-6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Tue, 28 Jan 2025 20:25:12 +0000 (12:25 -0800)
committerLinus Torvalds <[email protected]>
Tue, 28 Jan 2025 20:25:12 +0000 (12:25 -0800)
Pull driver core and debugfs updates from Greg KH:
 "Here is the big set of driver core and debugfs updates for 6.14-rc1.

  Included in here is a bunch of driver core, PCI, OF, and platform rust
  bindings (all acked by the different subsystem maintainers), hence the
  merge conflict with the rust tree, and some driver core api updates to
  mark things as const, which will also require some fixups due to new
  stuff coming in through other trees in this merge window.

  There are also a bunch of debugfs updates from Al, and there is at
  least one user that does have a regression with these, but Al is
  working on tracking down the fix for it. In my use (and everyone
  else's linux-next use), it does not seem like a big issue at the
  moment.

  Here's a short list of the things in here:

   - driver core rust bindings for PCI, platform, OF, and some i/o
     functions.

     We are almost at the "write a real driver in rust" stage now,
     depending on what you want to do.

   - misc device rust bindings and a sample driver to show how to use
     them

   - debugfs cleanups in the fs as well as the users of the fs api for
     places where drivers got it wrong or were unnecessarily doing
     things in complex ways.

   - driver core const work, making more of the api take const * for
     different parameters to make the rust bindings easier overall.

   - other small fixes and updates

  All of these have been in linux-next with all of the aforementioned
  merge conflicts, and the one debugfs issue, which looks to be resolved
  "soon""

* tag 'driver-core-6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (95 commits)
  rust: device: Use as_char_ptr() to avoid explicit cast
  rust: device: Replace CString with CStr in property_present()
  devcoredump: Constify 'struct bin_attribute'
  devcoredump: Define 'struct bin_attribute' through macro
  rust: device: Add property_present()
  saner replacement for debugfs_rename()
  orangefs-debugfs: don't mess with ->d_name
  octeontx2: don't mess with ->d_parent or ->d_parent->d_name
  arm_scmi: don't mess with ->d_parent->d_name
  slub: don't mess with ->d_name
  sof-client-ipc-flood-test: don't mess with ->d_name
  qat: don't mess with ->d_name
  xhci: don't mess with ->d_iname
  mtu3: don't mess wiht ->d_iname
  greybus/camera - stop messing with ->d_iname
  mediatek: stop messing with ->d_iname
  netdevsim: don't embed file_operations into your structs
  b43legacy: make use of debugfs_get_aux()
  b43: stop embedding struct file_operations into their objects
  carl9170: stop embedding file_operations into their objects
  ...

29 files changed:
1  2 
Documentation/userspace-api/ioctl/ioctl-number.rst
MAINTAINERS
arch/powerpc/platforms/powernv/opal.c
drivers/block/sunvdc.c
drivers/gpu/drm/mediatek/mtk_drm_drv.c
drivers/hwmon/hwmon.c
drivers/i2c/i2c-core-base.c
drivers/leds/leds-turris-omnia.c
drivers/media/pci/mgb4/mgb4_core.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/of/unittest-data/tests-platform.dtsi
drivers/pwm/core.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/scsi_transport_iscsi.c
drivers/tty/serial/serial_core.c
drivers/usb/mtu3/mtu3_debugfs.c
drivers/usb/typec/class.c
include/linux/device/bus.h
include/scsi/scsi_transport_iscsi.h
kernel/bpf/btf.c
kernel/module/sysfs.c
mm/slub.c
net/mac80211/debugfs_netdev.c
net/wireless/core.c
rust/kernel/device.rs
rust/kernel/lib.rs
rust/kernel/miscdevice.rs
rust/kernel/sync.rs
rust/kernel/types.rs

index bf5aff018c2f402742384aae4abef08ee9801dba,dc4bc0cab69f6b040824f375c2ee798c5de92389..6d1465315df328c49cf2141c24d13bdaa809c2f7
@@@ -283,7 -283,6 +283,7 @@@ Code  Seq#    Include Fil
  'p'   80-9F  linux/ppdev.h                                           user-space parport
                                                                       <mailto:[email protected]>
  'p'   A1-A5  linux/pps.h                                             LinuxPPS
 +'p'   B1-B3  linux/pps_gen.h                                         LinuxPPS
                                                                       <mailto:[email protected]>
  'q'   00-1F  linux/serio.h
  'q'   80-FF  linux/telephony.h                                       Internet PhoneJACK, Internet LineJACK
                                                                       <mailto:[email protected]>
  'z'   10-4F  drivers/s390/crypto/zcrypt_api.h                        conflict!
  '|'   00-7F  linux/media.h
+ '|'   80-9F  samples/                                                Any sample and example drivers
  0x80  00-1F  linux/fb.h
  0x81  00-1F  linux/vduse.h
  0x89  00-06  arch/x86/include/asm/sockios.h
diff --combined MAINTAINERS
index d49306cc17e3403dbc06e2c7927d6cfce514481b,e19a49e87861973d22089ae662079f06ec96c1ea..936e80f2c9ce201bf7e4a5abe4d240a937ed5e78
@@@ -185,14 -185,6 +185,14 @@@ W:       http://www.adaptec.com
  F:    Documentation/scsi/aacraid.rst
  F:    drivers/scsi/aacraid/
  
 +AAEON UPBOARD FPGA MFD DRIVER
 +M:    Thomas Richard <[email protected]>
 +S:    Maintained
 +F:    drivers/leds/leds-upboard.c
 +F:    drivers/mfd/upboard-fpga.c
 +F:    drivers/pinctrl/pinctrl-upboard.c
 +F:    include/linux/mfd/upboard-fpga.h
 +
  AB8500 BATTERY AND CHARGER DRIVERS
  M:    Linus Walleij <[email protected]>
  F:    Documentation/devicetree/bindings/power/supply/*ab8500*
@@@ -824,7 -816,7 +824,7 @@@ F: drivers/media/platform/sunxi/sun4i-c
  
  ALLWINNER A31 CSI DRIVER
  M:    Yong Deng <[email protected]>
 -M:    Paul Kocialkowski <paul[email protected]>
 +M:    Paul Kocialkowski <paul[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git git://linuxtv.org/media.git
@@@ -832,7 -824,7 +832,7 @@@ F: Documentation/devicetree/bindings/me
  F:    drivers/media/platform/sunxi/sun6i-csi/
  
  ALLWINNER A31 ISP DRIVER
 -M:    Paul Kocialkowski <paul[email protected]>
 +M:    Paul Kocialkowski <paul[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git git://linuxtv.org/media.git
@@@ -841,7 -833,7 +841,7 @@@ F: drivers/staging/media/sunxi/sun6i-is
  F:    drivers/staging/media/sunxi/sun6i-isp/uapi/sun6i-isp-config.h
  
  ALLWINNER A31 MIPI CSI-2 BRIDGE DRIVER
 -M:    Paul Kocialkowski <paul[email protected]>
 +M:    Paul Kocialkowski <paul[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git git://linuxtv.org/media.git
@@@ -884,7 -876,7 +884,7 @@@ F: drivers/thermal/sun8i_thermal.
  
  ALLWINNER VPU DRIVER
  M:    Maxime Ripard <[email protected]>
 -M:    Paul Kocialkowski <paul[email protected]>
 +M:    Paul Kocialkowski <paul[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/staging/media/sunxi/cedrus/
@@@ -959,7 -951,7 +959,7 @@@ M: Arthur Kiyanovski <[email protected]
  R:    David Arinzon <[email protected]>
  R:    Saeed Bishara <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/networking/device_drivers/ethernet/amazon/ena.rst
  F:    drivers/net/ethernet/amazon/
  
  S:    Supported
  F:    drivers/i2c/busses/i2c-amd-asf-plat.c
  
 +AMD NODE DRIVER
 +M:    Mario Limonciello <[email protected]>
 +M:    Yazen Ghannam <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +F:    arch/x86/include/asm/amd_node.h
 +F:    arch/x86/kernel/amd_node.c
 +
  AMD PDS CORE DRIVER
  M:    Shannon Nelson <[email protected]>
  M:    Brett Creeley <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/networking/device_drivers/ethernet/amd/pds_core.rst
  F:    drivers/net/ethernet/amd/pds_core/
  F:    include/linux/pds/
  AMD PMC DRIVER
  M:    Shyam Sundar S K <[email protected]>
  L:    [email protected]
 -S:    Maintained
 +S:    Supported
  F:    drivers/platform/x86/amd/pmc/
  
  AMD PMF DRIVER
  S:    Supported
  F:    drivers/spi/spi-amd.c
  
 +AMD XDNA DRIVER
 +M:    Min Ma <[email protected]>
 +M:    Lizhi Hou <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +T:    git https://gitlab.freedesktop.org/drm/misc/kernel.git
 +F:    Documentation/accel/amdxdna/
 +F:    drivers/accel/amdxdna/
 +F:    include/trace/events/amdxdna.h
 +F:    include/uapi/drm/amdxdna_accel.h
 +
  AMD XGBE DRIVER
  M:    "Shyam Sundar S K" <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi
  F:    drivers/net/ethernet/amd/xgbe/
  
@@@ -1252,7 -1225,7 +1252,7 @@@ S:      Maintaine
  F:    Documentation/devicetree/bindings/rtc/amlogic,a4-rtc.yaml
  F:    drivers/rtc/rtc-amlogic-a4.c
  
 -AMPHENOL CHIPCAP 2 HUMIDITY-TEMPERATURE IIO DRIVER
 +AMPHENOL CHIPCAP 2 DRIVER
  M:    Javier Carrasco <[email protected]>
  L:    [email protected]
  S:    Maintained
@@@ -1318,7 -1291,7 +1318,7 @@@ W:      https://ez.analog.com/linux-software
  F:    Documentation/devicetree/bindings/iio/adc/adi,ad4695.yaml
  F:    Documentation/iio/ad4695.rst
  F:    drivers/iio/adc/ad4695.c
 -F:    include/dt-bindings/iio/adi,ad4695.h
 +F:    include/dt-bindings/iio/adc/adi,ad4695.h
  
  ANALOG DEVICES INC AD7091R DRIVER
  M:    Marcelo Schmitt <[email protected]>
@@@ -1729,14 -1702,14 +1729,14 @@@ F:   drivers/edac/xgene_edac.
  APPLIED MICRO (APM) X-GENE SOC ETHERNET (V2) DRIVER
  M:    Iyappan Subramanian <[email protected]>
  M:    Keyur Chudgar <[email protected]>
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/apm/xgene-v2/
  
  APPLIED MICRO (APM) X-GENE SOC ETHERNET DRIVER
  M:    Iyappan Subramanian <[email protected]>
  M:    Keyur Chudgar <[email protected]>
  M:    Quan Nguyen <[email protected]>
 -S:    Supported
 +S:    Maintained
  F:    Documentation/devicetree/bindings/net/apm-xgene-enet.txt
  F:    Documentation/devicetree/bindings/net/apm-xgene-mdio.txt
  F:    drivers/net/ethernet/apm/xgene/
@@@ -1774,7 -1747,7 +1774,7 @@@ F:      drivers/hwmon/aquacomputer_d5next.
  AQUANTIA ETHERNET DRIVER (atlantic)
  M:    Igor Russkikh <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    https://www.marvell.com/
  Q:    https://patchwork.kernel.org/project/netdevbpf/list/
  F:    Documentation/networking/device_drivers/ethernet/aquantia/atlantic.rst
@@@ -1783,7 -1756,7 +1783,7 @@@ F:      drivers/net/ethernet/aquantia/atlant
  AQUANTIA ETHERNET DRIVER PTP SUBSYSTEM
  M:    Egor Pomozov <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    http://www.aquantia.com
  F:    drivers/net/ethernet/aquantia/atlantic/aq_ptp*
  
@@@ -1945,7 -1918,6 +1945,7 @@@ ARM PMU PROFILING AND DEBUGGIN
  M:    Will Deacon <[email protected]>
  M:    Mark Rutland <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
 +L:    [email protected]
  S:    Maintained
  F:    Documentation/devicetree/bindings/arm/pmu.yaml
  F:    Documentation/devicetree/bindings/perf/
@@@ -2309,15 -2281,6 +2309,15 @@@ F:    arch/arm64/boot/dts/bitmain
  F:    drivers/clk/clk-bm1880.c
  F:    drivers/pinctrl/pinctrl-bm1880.c
  
 +ARM/BLAIZE ARCHITECTURE
 +M:    James Cowgill <[email protected]>
 +M:    Matt Redfearn <[email protected]>
 +M:    Neil Jones <[email protected]>
 +M:    Nikolaos Pasaloukos <[email protected]>
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/arm/blaize.yaml
 +F:    arch/arm64/boot/dts/blaize/
 +
  ARM/CALXEDA HIGHBANK ARCHITECTURE
  M:    Andre Przywara <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -2328,7 -2291,7 +2328,7 @@@ F:      arch/arm/mach-highbank
  ARM/CAVIUM THUNDER NETWORK DRIVER
  M:    Sunil Goutham <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/cavium/thunder/
  
  ARM/CIRRUS LOGIC BK3 MACHINE SUPPORT
@@@ -2864,19 -2827,12 +2864,19 @@@ ARM/NXP S32G ARCHITECTUR
  R:    Chester Lin <[email protected]>
  R:    Matthias Brugger <[email protected]>
  R:    Ghennadi Procopciuc <[email protected]>
 -L:    NXP S32 Linux Team <[email protected]>
 +R:    NXP S32 Linux Team <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm64/boot/dts/freescale/s32g*.dts*
  F:    drivers/pinctrl/nxp/
  
 +ARM/NXP S32G/S32R DWMAC ETHERNET DRIVER
 +M:    Jan Petrous <[email protected]>
 +L:    NXP S32 Linux Team <[email protected]>
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
 +F:    drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
 +
  ARM/Orion SoC/Technologic Systems TS-78xx platform support
  M:    Alexander Clouter <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -3064,7 -3020,6 +3064,7 @@@ F:      drivers/*/*s3c24
  F:    drivers/*/*s3c64xx*
  F:    drivers/*/*s5pv210*
  F:    drivers/clocksource/samsung_pwm_timer.c
 +F:    drivers/mailbox/exynos-mailbox.c
  F:    drivers/memory/samsung/
  F:    drivers/pwm/pwm-samsung.c
  F:    drivers/soc/samsung/
@@@ -3704,7 -3659,7 +3704,7 @@@ F:      include/uapi/linux/sonet.
  ATMEL MACB ETHERNET DRIVER
  M:    Nicolas Ferre <[email protected]>
  M:    Claudiu Beznea <[email protected]>
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/cadence/
  
  ATMEL MAXTOUCH DRIVER
@@@ -3912,9 -3867,9 +3912,9 @@@ S:      Maintaine
  F:    drivers/platform/x86/barco-p50-gpio.c
  
  BATMAN ADVANCED
 -M:    Marek Lindner <marek[email protected]>
 +M:    Marek Lindner <marek[email protected]>
  M:    Simon Wunderlich <[email protected]>
 -M:    Antonio Quartulli <a@unstable.cc>
 +M:    Antonio Quartulli <a[email protected]>
  M:    Sven Eckelmann <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
@@@ -4432,7 -4387,7 +4432,7 @@@ F:      drivers/net/ethernet/broadcom/asp2
  BROADCOM B44 10/100 ETHERNET DRIVER
  M:    Michael Chan <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/broadcom/b44.*
  
  BROADCOM B53/SF2 ETHERNET SWITCH DRIVER
@@@ -4616,7 -4571,7 +4616,7 @@@ BROADCOM BNX2 GIGABIT ETHERNET DRIVE
  M:    Rasesh Mody <[email protected]>
  M:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/broadcom/bnx2.*
  F:    drivers/net/ethernet/broadcom/bnx2_*
  
@@@ -4640,14 -4595,13 +4640,14 @@@ BROADCOM BNX2X 10 GIGABIT ETHERNET DRIV
  M:    Sudarsana Kalluru <[email protected]>
  M:    Manish Chopra <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/broadcom/bnx2x/
  
  BROADCOM BNXT_EN 50 GIGABIT ETHERNET DRIVER
  M:    Michael Chan <[email protected]>
 +M:    Pavan Chebbi <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/firmware/broadcom/tee_bnxt_fw.c
  F:    drivers/net/ethernet/broadcom/bnxt/
  F:    include/linux/firmware/broadcom/tee_bnxt_fw.h
@@@ -4743,7 -4697,7 +4743,7 @@@ M:      Doug Berger <[email protected]
  M:    Florian Fainelli <[email protected]>
  R:    Broadcom internal kernel review list <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/devicetree/bindings/net/brcm,bcmgenet.yaml
  F:    Documentation/devicetree/bindings/net/brcm,unimac-mdio.yaml
  F:    drivers/net/ethernet/broadcom/genet/
@@@ -4810,7 -4764,6 +4810,7 @@@ F:      drivers/scsi/mpi3mr
  
  BROADCOM NETXTREME-E ROCE DRIVER
  M:    Selvin Xavier <[email protected]>
 +M:    Kalesh AP <[email protected]>
  L:    [email protected]
  S:    Supported
  W:    http://www.broadcom.com
@@@ -4896,7 -4849,7 +4896,7 @@@ BROADCOM SYSTEMPORT ETHERNET DRIVE
  M:    Florian Fainelli <[email protected]>
  R:    Broadcom internal kernel review list <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/devicetree/bindings/net/brcm,systemport.yaml
  F:    drivers/net/ethernet/broadcom/bcmsysport.*
  F:    drivers/net/ethernet/broadcom/unimac.h
@@@ -4905,7 -4858,7 +4905,7 @@@ BROADCOM TG3 GIGABIT ETHERNET DRIVE
  M:    Pavan Chebbi <[email protected]>
  M:    Michael Chan <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/broadcom/tg3.*
  
  BROADCOM VK DRIVER
@@@ -4927,7 -4880,7 +4927,7 @@@ M:      Rasesh Mody <[email protected]
  M:    Sudarsana Kalluru <[email protected]>
  M:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/brocade/bna/
  
  BSG (block layer generic sg v4 driver)
@@@ -5054,7 -5007,7 +5054,7 @@@ F:      drivers/media/platform/cadence/cdns-
  CADENCE NAND DRIVER
  L:    [email protected]
  S:    Orphan
 -F:    Documentation/devicetree/bindings/mtd/cadence-nand-controller.txt
 +F:    Documentation/devicetree/bindings/mtd/cdns,hp-nfc.yaml
  F:    drivers/mtd/nand/raw/cadence-nand-controller.c
  
  CADENCE USB3 DRD IP DRIVER
@@@ -5153,7 -5106,6 +5153,7 @@@ F:      include/uapi/linux/can/gw.
  F:    include/uapi/linux/can/isotp.h
  F:    include/uapi/linux/can/raw.h
  F:    net/can/
 +F:    net/sched/em_canid.c
  
  CAN-J1939 NETWORK LAYER
  M:    Robin van der Gracht <[email protected]>
@@@ -5193,7 -5145,6 +5193,7 @@@ M:      Serge Hallyn <[email protected]
  L:    [email protected]
  S:    Supported
  F:    include/linux/capability.h
 +F:    include/trace/events/capability.h
  F:    include/uapi/linux/capability.h
  F:    kernel/capability.c
  F:    security/commoncap.c
@@@ -5366,6 -5317,7 +5366,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  F:    drivers/char/
  F:    drivers/misc/
  F:    include/linux/miscdevice.h
+ F:    samples/rust/rust_misc_device.rs
  X:    drivers/char/agp/
  X:    drivers/char/hw_random/
  X:    drivers/char/ipmi/
@@@ -5481,12 -5433,9 +5482,12 @@@ F:    include/linux/platform_data/cros_usb
  
  CHROMEOS EC USB TYPE-C DRIVER
  M:    Prashant Malani <[email protected]>
 +M:    Benson Leung <[email protected]>
 +M:    Abhishek Pandit-Subedi <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/platform/chrome/cros_ec_typec.*
 +F:    drivers/platform/chrome/cros_typec_altmode.*
  F:    drivers/platform/chrome/cros_typec_switch.c
  F:    drivers/platform/chrome/cros_typec_vdm.*
  
  S:    Maintained
  F:    drivers/watchdog/cros_ec_wdt.c
  
 +CHROMEOS UCSI DRIVER
 +M:    Abhishek Pandit-Subedi <[email protected]>
 +M:    Łukasz Bartosik <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    drivers/usb/typec/ucsi/cros_ec_ucsi.c
 +
  CHRONTEL CH7322 CEC DRIVER
  M:    Joe Tessler <[email protected]>
  L:    [email protected]
@@@ -5524,7 -5466,6 +5525,7 @@@ L:      [email protected]
  L:    [email protected]
  S:    Maintained
  F:    Documentation/devicetree/bindings/sound/cirrus,cs*
 +F:    Documentation/sound/codecs/cs*
  F:    drivers/mfd/cs42l43*
  F:    drivers/pinctrl/cirrus/pinctrl-cs42l43*
  F:    drivers/spi/spi-cs42l43*
@@@ -5557,8 -5498,8 +5558,8 @@@ L:      [email protected]
  S:    Supported
  W:    https://github.com/CirrusLogic/linux-drivers/wiki
  T:    git https://github.com/CirrusLogic/linux-drivers.git
 -F:    drivers/firmware/cirrus/*
 -F:    include/linux/firmware/cirrus/*
 +F:    drivers/firmware/cirrus/
 +F:    include/linux/firmware/cirrus/
  
  CIRRUS LOGIC EP93XX ETHERNET DRIVER
  M:    Hartley Sweeten <[email protected]>
@@@ -5628,7 -5569,7 +5629,7 @@@ F:      drivers/scsi/snic
  CISCO VIC ETHERNET NIC DRIVER
  M:    Christian Benvenuti <[email protected]>
  M:    Satish Kharat <[email protected]>
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/cisco/enic/
  
  CISCO VIC LOW LATENCY NIC DRIVER
@@@ -6114,30 -6055,12 +6115,30 @@@ S:   Maintaine
  F:    Documentation/filesystems/cramfs.rst
  F:    fs/cramfs/
  
 +CRC LIBRARY
 +M:    Eric Biggers <[email protected]>
 +R:    Ard Biesheuvel <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +T:    git https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git crc-next
 +F:    Documentation/staging/crc*
 +F:    arch/*/lib/crc*
 +F:    include/linux/crc*
 +F:    lib/crc*
 +
  CREATIVE SB0540
  M:    Bastien Nocera <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/hid/hid-creative-sb0540.c
  
 +INTEL CRPS COMMON REDUNDANT PSU DRIVER
 +M:    Ninad Palsule <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    Documentation/hwmon/crps.rst
 +F:    drivers/hwmon/pmbus/crps.c
 +
  CRYPTO API
  M:    Herbert Xu <[email protected]>
  M:    "David S. Miller" <[email protected]>
@@@ -6244,7 -6167,7 +6245,7 @@@ F:      drivers/media/dvb-frontends/cxd2820r
  CXGB3 ETHERNET DRIVER (CXGB3)
  M:    Potnuri Bharat Teja <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    http://www.chelsio.com
  F:    drivers/net/ethernet/chelsio/cxgb3/
  
@@@ -6265,14 -6188,14 +6266,14 @@@ F:   drivers/crypto/chelsi
  CXGB4 ETHERNET DRIVER (CXGB4)
  M:    Potnuri Bharat Teja <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    http://www.chelsio.com
  F:    drivers/net/ethernet/chelsio/cxgb4/
  
  CXGB4 INLINE CRYPTO DRIVER
  M:    Ayush Sawal <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    http://www.chelsio.com
  F:    drivers/net/ethernet/chelsio/inline_crypto/
  
@@@ -6294,7 -6217,7 +6295,7 @@@ F:      include/uapi/rdma/cxgb4-abi.
  CXGB4VF ETHERNET DRIVER (CXGB4VF)
  M:    Potnuri Bharat Teja <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    http://www.chelsio.com
  F:    drivers/net/ethernet/chelsio/cxgb4vf/
  
@@@ -6302,8 -6225,8 +6303,8 @@@ CXL (IBM Coherent Accelerator Processo
  M:    Frederic Barrat <[email protected]>
  M:    Andrew Donnellan <[email protected]>
  L:    [email protected]
 -S:    Supported
 -F:    Documentation/ABI/testing/sysfs-class-cxl
 +S:    Obsolete
 +F:    Documentation/ABI/obsolete/sysfs-class-cxl
  F:    Documentation/arch/powerpc/cxl.rst
  F:    arch/powerpc/platforms/powernv/pci-cxl.c
  F:    drivers/misc/cxl/
@@@ -6404,7 -6327,6 +6405,7 @@@ F:      Documentation/mm/damon
  F:    include/linux/damon.h
  F:    include/trace/events/damon.h
  F:    mm/damon/
 +F:    samples/damon/
  F:    tools/testing/selftests/damon/
  
  DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER
  S:    Maintained
  F:    drivers/rtc/rtc-sd2405al.c
  
 -DH ELECTRONICS IMX6 DHCOM/DHCOR BOARD SUPPORT
 +DH ELECTRONICS DHSOM SOM AND BOARD SUPPORT
  M:    Christoph Niedermaier <[email protected]>
 -L:    [email protected]
 -S:    Maintained
 -F:    arch/arm/boot/dts/nxp/imx/imx6*-dhcom-*
 -F:    arch/arm/boot/dts/nxp/imx/imx6*-dhcor-*
 -
 -DH ELECTRONICS STM32MP1 DHCOM/DHCOR BOARD SUPPORT
  M:    Marek Vasut <[email protected]>
  L:    [email protected]
  S:    Maintained
 -F:    arch/arm/boot/dts/st/stm32mp1*-dhcom-*
 -F:    arch/arm/boot/dts/st/stm32mp1*-dhcor-*
 +N:    dhcom
 +N:    dhcor
 +N:    dhsom
  
  DIALOG SEMICONDUCTOR DRIVERS
  M:    Support Opensource <[email protected]>
@@@ -7091,6 -7018,7 +7092,7 @@@ F:      include/linux/component.
  DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
  M:    Greg Kroah-Hartman <[email protected]>
  R:    "Rafael J. Wysocki" <[email protected]>
+ R:    Danilo Krummrich <[email protected]>
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
  F:    Documentation/core-api/kobject.rst
@@@ -7101,8 -7029,14 +7103,14 @@@ F:    include/linux/debugfs.
  F:    include/linux/fwnode.h
  F:    include/linux/kobj*
  F:    include/linux/property.h
+ F:    include/linux/sysfs.h
  F:    lib/kobj*
  F:    rust/kernel/device.rs
+ F:    rust/kernel/device_id.rs
+ F:    rust/kernel/devres.rs
+ F:    rust/kernel/driver.rs
+ F:    rust/kernel/platform.rs
+ F:    samples/rust/rust_driver_platform.rs
  
  DRIVERS FOR OMAP ADAPTIVE VOLTAGE SCALING (AVS)
  M:    Nishanth Menon <[email protected]>
@@@ -7140,8 -7074,7 +7148,8 @@@ T:      git https://gitlab.freedesktop.org/d
  F:    drivers/gpu/drm/sun4i/sun8i*
  
  DRM DRIVER FOR ARM PL111 CLCD
 -S:    Orphan
 +M:    Linus Walleij <[email protected]>
 +S:    Maintained
  T:    git https://gitlab.freedesktop.org/drm/misc/kernel.git
  F:    drivers/gpu/drm/pl111/
  
@@@ -7307,7 -7240,7 +7315,7 @@@ F:      Documentation/devicetree/bindings/di
  F:    drivers/gpu/drm/panel/panel-lg-sw43408.c
  
  DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER
 -M:    Paul Kocialkowski <paul[email protected]>
 +M:    Paul Kocialkowski <paul[email protected]>
  S:    Supported
  T:    git https://gitlab.freedesktop.org/drm/misc/kernel.git
  F:    drivers/gpu/drm/logicvc/
@@@ -7456,7 -7389,7 +7464,7 @@@ L:      [email protected]
  S:    Obsolete
  W:    https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/
  T:    git https://gitlab.freedesktop.org/drm/misc/kernel.git
 -F:    drivers/gpu/drm/tiny/cirrus.c
 +F:    drivers/gpu/drm/tiny/cirrus-qemu.c
  
  DRM DRIVER FOR QXL VIRTUAL GPU
  M:    Dave Airlie <[email protected]>
@@@ -7867,7 -7800,6 +7875,7 @@@ F:      drivers/gpu/drm/rockchip
  
  DRM DRIVERS FOR STI
  M:    Alain Volmat <[email protected]>
 +M:    Raphael Gallais-Pou <[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git https://gitlab.freedesktop.org/drm/misc/kernel.git
@@@ -8468,7 -8400,7 +8476,7 @@@ M:      Ajit Khaparde <ajit.khaparde@broadco
  M:    Sriharsha Basavapatna <[email protected]>
  M:    Somnath Kotur <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    http://www.emulex.com
  F:    drivers/net/ethernet/emulex/benet/
  
@@@ -8623,8 -8555,8 +8631,8 @@@ F:      rust/kernel/net/phy.r
  F:    rust/kernel/net/phy/reg.rs
  
  EXEC & BINFMT API, ELF
 +M:    Kees Cook <[email protected]>
  R:    Eric Biederman <[email protected]>
 -R:    Kees Cook <[email protected]>
  L:    [email protected]
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/execve
@@@ -8636,7 -8568,6 +8644,7 @@@ F:      fs/tests/binfmt_*_kunit.
  F:    fs/tests/exec_kunit.c
  F:    include/linux/binfmts.h
  F:    include/linux/elf.h
 +F:    include/uapi/linux/auxvec.h
  F:    include/uapi/linux/binfmts.h
  F:    include/uapi/linux/elf.h
  F:    tools/testing/selftests/exec/
@@@ -8710,7 -8641,6 +8718,7 @@@ L:      [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git
  F:    Documentation/devicetree/bindings/extcon/
 +F:    Documentation/driver-api/extcon.rst
  F:    Documentation/firmware-guide/acpi/extcon-intel-int3496.rst
  F:    drivers/extcon/
  F:    include/linux/extcon.h
  S:    Maintained
  F:    drivers/input/joystick/fsia6b.c
  
 -FOCUSRITE SCARLETT2 MIXER DRIVER (Scarlett Gen 2+ and Clarett)
 +FOCUSRITE CONTROL PROTOCOL/SCARLETT2 MIXER DRIVERS (Scarlett Gen 2+, Clarett, and Vocaster)
  M:    Geoffrey D. Bennett <[email protected]>
  L:    [email protected]
  S:    Maintained
 -W:    https://github.com/geoffreybennett/scarlett-gen2
 -B:    https://github.com/geoffreybennett/scarlett-gen2/issues
 -T:    git https://github.com/geoffreybennett/scarlett-gen2.git
 +W:    https://github.com/geoffreybennett/linux-fcp
 +B:    https://github.com/geoffreybennett/linux-fcp/issues
 +T:    git https://github.com/geoffreybennett/linux-fcp.git
 +F:    include/uapi/sound/fcp.h
  F:    include/uapi/sound/scarlett2.h
 +F:    sound/usb/fcp.c
  F:    sound/usb/mixer_scarlett2.c
  
  FORCEDETH GIGABIT ETHERNET DRIVER
@@@ -9511,7 -9439,7 +9519,7 @@@ F:      samples/ftrac
  FUNGIBLE ETHERNET DRIVERS
  M:    Dimitris Michailidis <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/fungible/
  
  FUSE: FILESYSTEM IN USERSPACE
@@@ -9816,7 -9744,7 +9824,7 @@@ M:      Jeroen de Borst <[email protected]
  M:    Praveen Kaligineedi <[email protected]>
  R:    Shailend Chand <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/networking/device_drivers/ethernet/google/gve.rst
  F:    drivers/net/ethernet/google
  
@@@ -9831,12 -9759,9 +9839,12 @@@ F:    drivers/firmware/google
  
  GOOGLE TENSOR SoC SUPPORT
  M:    Peter Griffin <[email protected]>
 +R:    André Draszik <[email protected]>
 +R:    Tudor Ambarus <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  L:    [email protected]
  S:    Maintained
 +C:    irc://irc.oftc.net/pixel6-kernel-dev
  F:    Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
  F:    arch/arm64/boot/dts/exynos/google/
  F:    drivers/clk/samsung/clk-gs101.c
@@@ -10111,8 -10036,7 +10119,8 @@@ F:   include/trace/events/handshake.
  F:    net/handshake/
  
  HANTRO VPU CODEC DRIVER
 -M:    Ezequiel Garcia <[email protected]>
 +M:    Nicolas Dufresne <[email protected]>
 +M:    Benjamin Gaignard <[email protected]>
  M:    Philipp Zabel <[email protected]>
  L:    [email protected]
  L:    [email protected]
@@@ -10360,6 -10284,7 +10368,6 @@@ F:   drivers/input/touchscreen/himax_hx83
  
  HIPPI
  M:    Jes Sorensen <[email protected]>
 -L:    [email protected]
  S:    Maintained
  F:    drivers/net/hippi/
  F:    include/linux/hippidevice.h
@@@ -10752,8 -10677,10 +10760,8 @@@ F:  Documentation/devicetree/bindings/bu
  F:    Documentation/networking/device_drivers/ethernet/microsoft/netvsc.rst
  F:    Documentation/virt/hyperv
  F:    arch/arm64/hyperv
 -F:    arch/arm64/include/asm/hyperv-tlfs.h
  F:    arch/arm64/include/asm/mshyperv.h
  F:    arch/x86/hyperv
 -F:    arch/x86/include/asm/hyperv-tlfs.h
  F:    arch/x86/include/asm/mshyperv.h
  F:    arch/x86/include/asm/trace/hyperv.h
  F:    arch/x86/kernel/cpu/mshyperv.c
@@@ -10769,13 -10696,9 +10777,13 @@@ F: drivers/pci/controller/pci-hyperv.
  F:    drivers/scsi/storvsc_drv.c
  F:    drivers/uio/uio_hv_generic.c
  F:    drivers/video/fbdev/hyperv_fb.c
 -F:    include/asm-generic/hyperv-tlfs.h
  F:    include/asm-generic/mshyperv.h
  F:    include/clocksource/hyperv_timer.h
 +F:    include/hyperv/hvgdk.h
 +F:    include/hyperv/hvgdk_ext.h
 +F:    include/hyperv/hvgdk_mini.h
 +F:    include/hyperv/hvhdk.h
 +F:    include/hyperv/hvhdk_mini.h
  F:    include/linux/hyperv.h
  F:    include/net/mana
  F:    include/uapi/linux/hyperv.h
@@@ -11043,7 -10966,7 +11051,7 @@@ M:   Rick Lindsley <[email protected]
  R:    Nick Child <[email protected]>
  R:    Thomas Falcon <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/ibm/ibmvnic.*
  
  IBM Power VFIO Support
@@@ -11054,7 -10977,7 +11062,7 @@@ F:   drivers/vfio/vfio_iommu_spapr_tce.
  IBM Power Virtual Ethernet Device Driver
  M:    Nick Child <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/ibm/ibmveth.*
  
  IBM Power Virtual FC Device Drivers
@@@ -11523,8 -11446,9 +11531,8 @@@ F:   drivers/mfd/intel_pmc_bxt.
  F:    include/linux/mfd/intel_pmc_bxt.h
  
  INTEL C600 SERIES SAS CONTROLLER DRIVER
 -M:    Artur Paszkiewicz <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Orphan
  T:    git git://git.code.sf.net/p/intel-sas/isci
  F:    drivers/scsi/isci/
  
@@@ -11586,7 -11510,7 +11594,7 @@@ INTEL ETHERNET DRIVER
  M:    Tony Nguyen <[email protected]>
  M:    Przemek Kitszel <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
 -S:    Supported
 +S:    Maintained
  W:    https://www.intel.com/content/www/us/en/support.html
  Q:    https://patchwork.ozlabs.org/project/intel-wired-lan/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue.git
@@@ -11955,12 -11879,6 +11963,12 @@@ S: Maintaine
  F:    arch/x86/include/asm/intel_telemetry.h
  F:    drivers/platform/x86/intel/telemetry/
  
 +INTEL TOUCH HOST CONTROLLER (THC) DRIVER
 +M:    Even Xu <[email protected]>
 +M:    Xinpeng Sun <[email protected]>
 +S:    Maintained
 +F:    drivers/hid/intel-thc-hid/
 +
  INTEL TPMI DRIVER
  M:    Srinivas Pandruvada <[email protected]>
  L:    [email protected]
@@@ -12161,7 -12079,7 +12169,7 @@@ F:   include/uapi/linux/io_uring.
  F:    io_uring/
  
  IPMI SUBSYSTEM
 -M:    Corey Minyard <[email protected]>
 +M:    Corey Minyard <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
  W:    http://openipmi.sourceforge.net/
@@@ -12473,13 -12391,6 +12481,13 @@@ F: Documentation/kbuild/kconfig
  F:    scripts/Kconfig.include
  F:    scripts/kconfig/
  
 +KCORE
 +M:    Omar Sandoval <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    fs/proc/kcore.c
 +F:    include/linux/kcore.h
 +
  KCOV
  R:    Dmitry Vyukov <[email protected]>
  R:    Andrey Konovalov <[email protected]>
@@@ -12698,8 -12609,8 +12706,8 @@@ F:   arch/arm64/include/asm/kvm
  F:    arch/arm64/include/uapi/asm/kvm*
  F:    arch/arm64/kvm/
  F:    include/kvm/arm_*
 -F:    tools/testing/selftests/kvm/*/aarch64/
 -F:    tools/testing/selftests/kvm/aarch64/
 +F:    tools/testing/selftests/kvm/*/arm64/
 +F:    tools/testing/selftests/kvm/arm64/
  
  KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
  M:    Tianrui Zhao <[email protected]>
@@@ -12770,8 -12681,8 +12778,8 @@@ F:   arch/s390/kvm
  F:    arch/s390/mm/gmap.c
  F:    drivers/s390/char/uvdevice.c
  F:    tools/testing/selftests/drivers/s390x/uvdevice/
 -F:    tools/testing/selftests/kvm/*/s390x/
 -F:    tools/testing/selftests/kvm/s390x/
 +F:    tools/testing/selftests/kvm/*/s390/
 +F:    tools/testing/selftests/kvm/s390/
  
  KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86)
  M:    Sean Christopherson <[email protected]>
@@@ -12788,8 -12699,8 +12796,8 @@@ F:   arch/x86/include/uapi/asm/svm.
  F:    arch/x86/include/uapi/asm/vmx.h
  F:    arch/x86/kvm/
  F:    arch/x86/kvm/*/
 -F:    tools/testing/selftests/kvm/*/x86_64/
 -F:    tools/testing/selftests/kvm/x86_64/
 +F:    tools/testing/selftests/kvm/*/x86/
 +F:    tools/testing/selftests/kvm/x86/
  
  KERNFS
  M:    Greg Kroah-Hartman <[email protected]>
  S:    Maintained
  W:    http://kgdb.wiki.kernel.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb.git
 -F:    Documentation/dev-tools/kgdb.rst
 +F:    Documentation/process/debugging/kgdb.rst
  F:    drivers/misc/kgdbts.c
  F:    drivers/tty/serial/kgdboc.c
  F:    include/linux/kdb.h
@@@ -13207,7 -13118,7 +13215,7 @@@ LIBETH COMMON ETHERNET LIBRAR
  M:    Alexander Lobakin <[email protected]>
  L:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
 -S:    Supported
 +S:    Maintained
  T:    git https://github.com/alobakin/linux.git
  F:    drivers/net/ethernet/intel/libeth/
  F:    include/net/libeth/
@@@ -13217,7 -13128,7 +13225,7 @@@ LIBIE COMMON INTEL ETHERNET LIBRAR
  M:    Alexander Lobakin <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  T:    git https://github.com/alobakin/linux.git
  F:    drivers/net/ethernet/intel/libie/
  F:    include/linux/net/intel/libie/
  L:    [email protected]
  L:    [email protected]
  S:    Supported
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git rcu/dev
  F:    Documentation/atomic_bitops.txt
  F:    Documentation/atomic_t.txt
  F:    Documentation/core-api/refcount-vs-atomic.rst
@@@ -13518,8 -13429,8 +13526,8 @@@ LOCKING PRIMITIVE
  M:    Peter Zijlstra <[email protected]>
  M:    Ingo Molnar <[email protected]>
  M:    Will Deacon <[email protected]>
 +M:    Boqun Feng <[email protected]> (LOCKDEP & RUST)
  R:    Waiman Long <[email protected]>
 -R:    Boqun Feng <[email protected]> (LOCKDEP)
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/core
@@@ -13533,11 -13444,6 +13541,11 @@@ F: include/linux/seqlock.
  F:    include/linux/spinlock*.h
  F:    kernel/locking/
  F:    lib/locking*.[ch]
 +F:    rust/helpers/mutex.c
 +F:    rust/helpers/spinlock.c
 +F:    rust/kernel/sync/lock.rs
 +F:    rust/kernel/sync/lock/
 +F:    rust/kernel/sync/locked_by.rs
  X:    kernel/locking/locktorture.c
  
  LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks)
@@@ -13642,12 -13548,6 +13650,12 @@@ S: Maintaine
  F:    Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml
  F:    drivers/thermal/loongson2_thermal.c
  
 +LOONGSON EDAC DRIVER
 +M:    Zhao Qunqin <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    drivers/edac/loongson_edac.c
 +
  LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
  M:    Sathya Prakash <[email protected]>
  M:    Sreekanth Reddy <[email protected]>
@@@ -14031,7 -13931,7 +14039,7 @@@ MARVELL OCTEON ENDPOINT DRIVE
  M:    Veerasenareddy Burru <[email protected]>
  M:    Sathesh Edara <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/marvell/octeon_ep
  
  MARVELL OCTEON ENDPOINT VF DRIVER
@@@ -14040,7 -13940,7 +14048,7 @@@ M:   Sathesh Edara <[email protected]
  M:    Shinas Rasheed <[email protected]>
  M:    Satananda Burla <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/marvell/octeon_ep_vf
  
  MARVELL OCTEONTX2 PHYSICAL FUNCTION DRIVER
@@@ -14048,9 -13948,8 +14056,9 @@@ M:   Sunil Goutham <[email protected]
  M:    Geetha sowjanya <[email protected]>
  M:    Subbaraya Sundeep <[email protected]>
  M:    hariprasad <[email protected]>
 +M:    Bharat Bhushan <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/marvell/octeontx2/nic/
  F:    include/linux/soc/marvell/octeontx2/
  
@@@ -14062,7 -13961,7 +14070,7 @@@ M:   Jerin Jacob <[email protected]
  M:    hariprasad <[email protected]>
  M:    Subbaraya Sundeep <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/networking/device_drivers/ethernet/marvell/octeontx2.rst
  F:    drivers/net/ethernet/marvell/octeontx2/af/
  
@@@ -14602,14 -14501,6 +14610,14 @@@ W: https://linuxtv.or
  T:    git git://linuxtv.org/media.git
  F:    drivers/media/dvb-frontends/stv6111*
  
 +MEDIA DRIVERS FOR STM32 - CSI
 +M:    Alain Volmat <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +T:    git git://linuxtv.org/media_tree.git
 +F:    Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
 +F:    drivers/media/platform/st/stm32/stm32-csi.c
 +
  MEDIA DRIVERS FOR STM32 - DCMI / DCMIPP
  M:    Hugues Fruchet <[email protected]>
  M:    Alain Volmat <[email protected]>
@@@ -14958,7 -14849,7 +14966,7 @@@ F:   drivers/i2c/busses/i2c-mlxbf.
  MELLANOX ETHERNET DRIVER (mlx4_en)
  M:    Tariq Toukan <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    https://www.nvidia.com/networking/
  Q:    https://patchwork.kernel.org/project/netdevbpf/list/
  F:    drivers/net/ethernet/mellanox/mlx4/en_*
@@@ -14967,7 -14858,7 +14975,7 @@@ MELLANOX ETHERNET DRIVER (mlx5e
  M:    Saeed Mahameed <[email protected]>
  M:    Tariq Toukan <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    https://www.nvidia.com/networking/
  Q:    https://patchwork.kernel.org/project/netdevbpf/list/
  F:    drivers/net/ethernet/mellanox/mlx5/core/en_*
  MELLANOX ETHERNET INNOVA DRIVERS
  R:    Boris Pismenny <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    https://www.nvidia.com/networking/
  Q:    https://patchwork.kernel.org/project/netdevbpf/list/
  F:    drivers/net/ethernet/mellanox/mlx5/core/en_accel/*
@@@ -15014,7 -14905,7 +15022,7 @@@ MELLANOX MLX4 core VPI drive
  M:    Tariq Toukan <[email protected]>
  L:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    https://www.nvidia.com/networking/
  Q:    https://patchwork.kernel.org/project/netdevbpf/list/
  F:    drivers/net/ethernet/mellanox/mlx4/
@@@ -15036,7 -14927,7 +15044,7 @@@ M:   Leon Romanovsky <[email protected]
  M:    Tariq Toukan <[email protected]>
  L:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  W:    https://www.nvidia.com/networking/
  Q:    https://patchwork.kernel.org/project/netdevbpf/list/
  F:    Documentation/networking/device_drivers/ethernet/mellanox/
  S:    Maintained
  W:    http://www.linux-mm.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
 +F:    mm/mlock.c
  F:    mm/mmap.c
 +F:    mm/mprotect.c
 +F:    mm/mremap.c
 +F:    mm/mseal.c
 +F:    mm/vma.c
 +F:    mm/vma.h
 +F:    mm/vma_internal.h
 +F:    tools/testing/vma/
  
  MEMORY TECHNOLOGY DEVICES (MTD)
  M:    Miquel Raynal <[email protected]>
@@@ -15278,7 -15161,7 +15286,7 @@@ META ETHERNET DRIVER
  M:    Alexander Duyck <[email protected]>
  M:    Jakub Kicinski <[email protected]>
  R:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/networking/device_drivers/ethernet/meta/
  F:    drivers/net/ethernet/meta/
  
@@@ -16286,8 -16169,7 +16294,8 @@@ M:   Breno Leitao <[email protected]
  S:    Maintained
  F:    Documentation/networking/netconsole.rst
  F:    drivers/net/netconsole.c
 -F:    tools/testing/selftests/drivers/net/netcons_basic.sh
 +F:    tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
 +F:    tools/testing/selftests/drivers/net/netcons\*
  
  NETDEVSIM
  M:    Jakub Kicinski <[email protected]>
@@@ -16304,7 -16186,7 +16312,7 @@@ F:   net/sched/sch_netem.
  NETERION 10GbE DRIVERS (s2io)
  M:    Jon Mason <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/networking/device_drivers/ethernet/neterion/s2io.rst
  F:    drivers/net/ethernet/neterion/
  
@@@ -16403,7 -16285,7 +16411,7 @@@ F:   include/linux/inetdevice.
  F:    include/linux/netdev*
  F:    include/linux/platform_data/wiznet.h
  F:    include/uapi/linux/cn_proc.h
 -F:    include/uapi/linux/ethtool_netlink.h
 +F:    include/uapi/linux/ethtool_netlink*
  F:    include/uapi/linux/if_*
  F:    include/uapi/linux/net_shaper.h
  F:    include/uapi/linux/netdev*
@@@ -16629,7 -16511,7 +16637,7 @@@ M:   Manish Chopra <[email protected]
  M:    Rahul Verma <[email protected]>
  M:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/qlogic/netxen/
  
  NET_FAILOVER MODULE
@@@ -16725,8 -16607,8 +16733,8 @@@ F:   arch/nios2
  
  NITRO ENCLAVES (NE)
  M:    Alexandru Ciobotaru <[email protected]>
 +R:    The AWS Nitro Enclaves Team <[email protected]>
  L:    [email protected]
 -L:    The AWS Nitro Enclaves Team <[email protected]>
  S:    Supported
  W:    https://aws.amazon.com/ec2/nitro/nitro-enclaves/
  F:    Documentation/virt/ne_overview.rst
@@@ -16737,8 -16619,8 +16745,8 @@@ F:   samples/nitro_enclaves
  
  NITRO SECURE MODULE (NSM)
  M:    Alexander Graf <[email protected]>
 +R:    The AWS Nitro Enclaves Team <[email protected]>
  L:    [email protected]
 -L:    The AWS Nitro Enclaves Team <[email protected]>
  S:    Supported
  W:    https://aws.amazon.com/ec2/nitro/nitro-enclaves/
  F:    drivers/misc/nsm.c
@@@ -16834,15 -16716,6 +16842,15 @@@ T: git https://github.com/Paragon-Softw
  F:    Documentation/filesystems/ntfs3.rst
  F:    fs/ntfs3/
  
 +NTSYNC SYNCHRONIZATION PRIMITIVE DRIVER
 +M:    Elizabeth Figura <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +F:    Documentation/userspace-api/ntsync.rst
 +F:    drivers/misc/ntsync.c
 +F:    include/uapi/linux/ntsync.h
 +F:    tools/testing/selftests/drivers/ntsync/
 +
  NUBUS SUBSYSTEM
  M:    Finn Thain <[email protected]>
  L:    [email protected]
@@@ -16924,7 -16797,6 +16932,7 @@@ T:   git git://git.kernel.org/pub/scm/lin
  F:    Documentation/ABI/stable/sysfs-bus-nvmem
  F:    Documentation/devicetree/bindings/nvmem/
  F:    drivers/nvmem/
 +F:    include/dt-bindings/nvmem/
  F:    include/linux/nvmem-consumer.h
  F:    include/linux/nvmem-provider.h
  
@@@ -17632,6 -17504,7 +17640,7 @@@ T:   git git://git.kernel.org/pub/scm/lin
  F:    Documentation/ABI/testing/sysfs-firmware-ofw
  F:    drivers/of/
  F:    include/linux/of*.h
+ F:    rust/kernel/of.rs
  F:    scripts/dtc/
  F:    tools/testing/selftests/dt/
  K:    of_overlay_notifier_
@@@ -17771,7 -17644,6 +17780,7 @@@ F:   Documentation/core-api/packing.rs
  F:    include/linux/packing.h
  F:    lib/packing.c
  F:    lib/packing_test.c
 +F:    scripts/gen_packed_field_checks.c
  
  PADATA PARALLEL EXECUTION MECHANISM
  M:    Steffen Klassert <[email protected]>
@@@ -18038,7 -17910,7 +18047,7 @@@ M:   Karthikeyan Mitran <m.karthikeyan@mo
  M:    Hou Zhiqiang <[email protected]>
  L:    [email protected]
  S:    Supported
 -F:    Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
 +F:    Documentation/devicetree/bindings/pci/mbvl,gpex40-pcie.yaml
  F:    drivers/pci/controller/mobiveil/pcie-mobiveil*
  
  PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
@@@ -18062,6 -17934,7 +18071,6 @@@ M:   Hou Zhiqiang <[email protected]
  L:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
 -F:    Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
  F:    drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
  
  PCI DRIVER FOR PLDA PCIE IP
@@@ -18139,7 -18012,7 +18148,7 @@@ F:   Documentation/PCI/endpoint/
  F:    Documentation/misc-devices/pci-endpoint-test.rst
  F:    drivers/misc/pci_endpoint_test.c
  F:    drivers/pci/endpoint/
 -F:    tools/pci/
 +F:    tools/testing/selftests/pci_endpoint/
  
  PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC
  M:    Mahesh J Salgaonkar <[email protected]>
@@@ -18232,6 -18105,8 +18241,8 @@@ F:   include/asm-generic/pci
  F:    include/linux/of_pci.h
  F:    include/linux/pci*
  F:    include/uapi/linux/pci*
+ F:    rust/kernel/pci.rs
+ F:    samples/rust/rust_driver_pci.rs
  
  PCIE BANDWIDTH CONTROLLER
  M:    Ilpo Järvinen <[email protected]>
@@@ -18415,7 -18290,7 +18426,7 @@@ PENSANDO ETHERNET DRIVER
  M:    Shannon Nelson <[email protected]>
  M:    Brett Creeley <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/networking/device_drivers/ethernet/pensando/ionic.rst
  F:    drivers/net/ethernet/pensando/
  
@@@ -18560,8 -18435,8 +18571,8 @@@ M:   Fabio Estevam <[email protected]
  M:    Shawn Guo <[email protected]>
  M:    Jacky Bai <[email protected]>
  R:    Pengutronix Kernel Team <[email protected]>
 +R:    NXP S32 Linux Team <[email protected]>
  L:    [email protected]
 -L:    NXP S32 Linux Team <[email protected]>
  S:    Maintained
  F:    Documentation/devicetree/bindings/pinctrl/fsl,*
  F:    Documentation/devicetree/bindings/pinctrl/nxp,s32*
@@@ -18845,13 -18720,11 +18856,13 @@@ L:        [email protected] (subscriber
  S:    Maintained
  W:    http://wiki.enneenne.com/index.php/LinuxPPS_support
  F:    Documentation/ABI/testing/sysfs-pps
 +F:    Documentation/ABI/testing/sysfs-pps-gen
  F:    Documentation/devicetree/bindings/pps/pps-gpio.yaml
  F:    Documentation/driver-api/pps.rst
  F:    drivers/pps/
  F:    include/linux/pps*.h
  F:    include/uapi/linux/pps.h
 +F:    include/uapi/linux/pps_gen.h
  
  PRESSURE STALL INFORMATION (PSI)
  M:    Johannes Weiner <[email protected]>
@@@ -19184,7 -19057,7 +19195,7 @@@ F:   drivers/scsi/qedi
  QLOGIC QL4xxx ETHERNET DRIVER
  M:    Manish Chopra <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/qlogic/qed/
  F:    drivers/net/ethernet/qlogic/qede/
  F:    include/linux/qed/
@@@ -19212,7 -19085,7 +19223,7 @@@ F:   drivers/scsi/qla2xxx
  QLOGIC QLA3XXX NETWORK DRIVER
  M:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/qlogic/qla3xxx.*
  
  QLOGIC QLA4XXX iSCSI DRIVER
@@@ -19228,7 -19101,7 +19239,7 @@@ M:   Shahed Shaikh <[email protected]
  M:    Manish Chopra <[email protected]>
  M:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/qlogic/qlcnic/
  
  QM1D1B0004 MEDIA DRIVER
  S:    Odd Fixes
  F:    drivers/media/tuners/qm1d1c0042*
  
 +QNAP MCU DRIVER
 +M:    Heiko Stuebner <[email protected]>
 +S:    Maintained
 +F:    drivers/hwmon/qnap-mcu-hwmon.c
 +F:    drivers/input/misc/qnap-mcu-input.c
 +F:    drivers/leds/leds-qnap-mcu.c
 +F:    drivers/mfd/qnap-mcu.c
 +F:    include/linux/mfd/qnap-mcu.h
 +
  QNX4 FILESYSTEM
  M:    Anders Larsen <[email protected]>
  S:    Maintained
@@@ -19707,7 -19571,7 +19718,7 @@@ F:   drivers/ras/amd/fmpm.
  
  RASPBERRY PI PISP BACK END
  M:    Jacopo Mondi <[email protected]>
 -L:    Raspberry Pi Kernel Maintenance <[email protected]>
 +R:    Raspberry Pi Kernel Maintenance <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
@@@ -19747,7 -19611,7 +19758,7 @@@ R:   Mathieu Desnoyers <mathieu.desnoyers
  R:    Lai Jiangshan <[email protected]>
  L:    [email protected]
  S:    Supported
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git rcu/dev
  F:    tools/testing/selftests/rcutorture
  
  RDACM20 Camera Sensor
@@@ -19826,10 -19690,11 +19837,11 @@@ R:        Zqiang <[email protected]
  L:    [email protected]
  S:    Supported
  W:    http://www.rdrop.com/users/paulmck/RCU/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git rcu/dev
  F:    Documentation/RCU/
  F:    include/linux/rcu*
  F:    kernel/rcu/
+ F:    rust/kernel/sync/rcu.rs
  X:    Documentation/RCU/torture.rst
  X:    include/linux/srcu*.h
  X:    kernel/rcu/srcu*.c
@@@ -19978,7 -19843,7 +19990,7 @@@ M:   Paul Barker <[email protected]
  M:    Niklas Söderlund <[email protected]>
  L:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/devicetree/bindings/net/renesas,etheravb.yaml
  F:    drivers/net/ethernet/renesas/Kconfig
  F:    drivers/net/ethernet/renesas/Makefile
@@@ -19998,7 -19863,7 +20010,7 @@@ RENESAS ETHERNET TSN DRIVE
  M:    Niklas Söderlund <[email protected]>
  L:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/devicetree/bindings/net/renesas,ethertsn.yaml
  F:    drivers/net/ethernet/renesas/rtsn.*
  
@@@ -20148,7 -20013,7 +20160,7 @@@ RENESAS SUPERH ETHERNET DRIVE
  M:    Niklas Söderlund <[email protected]>
  L:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/devicetree/bindings/net/renesas,ether.yaml
  F:    drivers/net/ethernet/renesas/Kconfig
  F:    drivers/net/ethernet/renesas/Makefile
@@@ -20216,7 -20081,7 +20228,7 @@@ F:   net/rfkill
  RHASHTABLE
  M:    Thomas Graf <[email protected]>
  M:    Herbert Xu <[email protected]>
 -L:    netdev@vger.kernel.org
 +L:    linux-crypto@vger.kernel.org
  S:    Maintained
  F:    include/linux/rhashtable-types.h
  F:    include/linux/rhashtable.h
@@@ -20323,15 -20188,6 +20335,15 @@@ F: drivers/perf/riscv_pmu.
  F:    drivers/perf/riscv_pmu_legacy.c
  F:    drivers/perf/riscv_pmu_sbi.c
  
 +RISC-V SPACEMIT SoC Support
 +M:    Yixun Lan <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +T:    git https://github.com/spacemit-com/linux
 +F:    arch/riscv/boot/dts/spacemit/
 +N:    spacemit
 +K:    spacemit
 +
  RISC-V THEAD SoC SUPPORT
  M:    Drew Fustini <[email protected]>
  M:    Guo Ren <[email protected]>
  S:    Odd Fixes
  F:    drivers/tty/serial/rp2.*
  
 +ROHM BD79703 DAC
 +M:    Matti Vaittinen <[email protected]>
 +S:    Supported
 +F:    drivers/iio/dac/rohm-bd79703.c
 +
  ROHM BD99954 CHARGER IC
  M:    Matti Vaittinen <[email protected]>
  S:    Supported
@@@ -20475,6 -20326,7 +20487,6 @@@ ROHM BU270xx LIGHT SENSOR DRIVER
  M:    Matti Vaittinen <[email protected]>
  L:    [email protected]
  S:    Supported
 -F:    drivers/iio/light/rohm-bu27008.c
  F:    drivers/iio/light/rohm-bu27034.c
  
  ROHM MULTIFUNCTION BD9571MWV-M PMIC DEVICE DRIVERS
@@@ -20816,7 -20668,8 +20828,7 @@@ F:   arch/s390/include/uapi/asm/zcrypt.
  F:    drivers/s390/crypto/
  
  S390 ZFCP DRIVER
 -M:    Steffen Maier <[email protected]>
 -M:    Benjamin Block <[email protected]>
 +M:    Nihar Panda <[email protected]>
  L:    [email protected]
  S:    Supported
  F:    drivers/s390/scsi/zfcp_*
@@@ -20871,15 -20724,6 +20883,15 @@@ F: arch/arm64/boot/dts/exynos/exynos850
  F:    drivers/clk/samsung/clk-exynos850.c
  F:    include/dt-bindings/clock/exynos850.h
  
 +SAMSUNG EXYNOS MAILBOX DRIVER
 +M:    Tudor Ambarus <[email protected]>
 +L:    [email protected]
 +L:    [email protected]
 +S:    Supported
 +F:    Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
 +F:    drivers/mailbox/exynos-mailbox.c
 +F:    include/linux/mailbox/exynos-message.h
 +
  SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
  M:    Krzysztof Kozlowski <[email protected]>
  L:    [email protected]
@@@ -21012,7 -20856,7 +21024,7 @@@ F:   include/linux/platform_data/spi-s3c6
  SAMSUNG SXGBE DRIVERS
  M:    Byungho An <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/samsung/sxgbe/
  
  SAMSUNG THERMAL DRIVER
@@@ -21406,7 -21250,6 +21418,7 @@@ M:   Srinivas Kandagatla <srinivas.kandag
  L:    [email protected]
  S:    Maintained
  F:    Documentation/devicetree/bindings/slimbus/
 +F:    Documentation/driver-api/slimbus.rst
  F:    drivers/slimbus/
  F:    include/linux/slimbus.h
  
@@@ -21415,7 -21258,7 +21427,7 @@@ M:   Edward Cree <[email protected]
  M:    Martin Habets <[email protected]>
  L:    [email protected]
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    Documentation/networking/devlink/sfc.rst
  F:    drivers/net/ethernet/sfc/
  
@@@ -21746,7 -21589,7 +21758,7 @@@ R:   Mathieu Desnoyers <mathieu.desnoyers
  L:    [email protected]
  S:    Supported
  W:    http://www.rdrop.com/users/paulmck/RCU/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git rcu/dev
  F:    include/linux/srcu*.h
  F:    kernel/rcu/srcu*.c
  
@@@ -22157,7 -22000,6 +22169,7 @@@ W:   https://github.com/thesofproject/lin
  F:    sound/soc/sof/
  
  SOUND - GENERIC SOUND CARD (Simple-Audio-Card, Audio-Graph-Card)
 +M:    Mark Brown <[email protected]>
  M:    Kuninori Morimoto <[email protected]>
  S:    Supported
  L:    [email protected]
@@@ -22337,14 -22179,6 +22349,14 @@@ T: git git://linuxtv.org/media.gi
  F:    Documentation/devicetree/bindings/media/i2c/st,st-mipid02.yaml
  F:    drivers/media/i2c/st-mipid02.c
  
 +ST STC3117 FUEL GAUGE DRIVER
 +M:    Hardevsinh Palaniya <[email protected]>
 +M:    Bhavin Sharma <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/power/supply/st,stc3117.yaml
 +F:    drivers/power/supply/stc3117_fuel_gauge.c
 +
  ST STM32 FIREWALL
  M:    Gatien Chevallier <[email protected]>
  S:    Maintained
@@@ -22620,7 -22454,7 +22632,7 @@@ F:   arch/*/kernel/static_call.
  F:    include/linux/jump_label*.h
  F:    include/linux/static_call*.h
  F:    kernel/jump_label.c
 -F:    kernel/static_call.c
 +F:    kernel/static_call*.c
  
  STI AUDIO (ASoC) DRIVERS
  M:    Arnaud Pouliquen <[email protected]>
@@@ -22905,7 -22739,7 +22917,7 @@@ F:   include/linux/platform_data/dma-dw.
  SYNOPSYS DESIGNWARE ENTERPRISE ETHERNET DRIVER
  M:    Jose Abreu <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/synopsys/
  
  SYNOPSYS DESIGNWARE ETHERNET XPCS DRIVER
@@@ -23305,7 -23139,7 +23317,7 @@@ F:   drivers/phy/tegra/xusb
  TEHUTI ETHERNET DRIVER
  M:    Andy Gospodarek <[email protected]>
  L:    [email protected]
 -S:    Supported
 +S:    Maintained
  F:    drivers/net/ethernet/tehuti/tehuti.*
  
  TEHUTI TN40XX ETHERNET DRIVER
@@@ -23391,8 -23225,6 +23403,8 @@@ M:   Jerome Brunet <[email protected]
  L:    [email protected]
  S:    Maintained
  F:    Documentation/devicetree/bindings/hwmon/pmbus/ti,tps25990.yaml
 +F:    Documentation/hwmon/tps25990.rst
 +F:    drivers/hwmon/pmbus/tps25990.c
  
  TEXAS INSTRUMENTS TPS23861 PoE PSE DRIVER
  M:    Robert Marko <[email protected]>
@@@ -23410,13 -23242,6 +23422,13 @@@ S: Supporte
  F:    Documentation/devicetree/bindings/iio/dac/ti,dac7612.yaml
  F:    drivers/iio/dac/ti-dac7612.c
  
 +TEXAS INSTRUMENTS' LB8864 LED BACKLIGHT DRIVER
 +M:    Alexander Sverdlin <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/leds/backlight/ti,lp8864.yaml
 +F:    drivers/leds/leds-lp8864.c
 +
  TEXAS INSTRUMENTS' SYSTEM CONTROL INTERFACE (TISCI) PROTOCOL DRIVER
  M:    Nishanth Menon <[email protected]>
  M:    Tero Kristo <[email protected]>
@@@ -23724,7 -23549,6 +23736,7 @@@ T:   git git://git.kernel.org/pub/scm/lin
  F:    Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
  F:    drivers/pmdomain/ti/omap_prm.c
  F:    drivers/soc/ti/*
 +F:    include/linux/pruss_driver.h
  
  TI LM49xxx FAMILY ASoC CODEC DRIVERS
  M:    M R Swami Reddy <[email protected]>
@@@ -23889,7 -23713,7 +23901,7 @@@ M:   "Paul E. McKenney" <[email protected]
  M:    Josh Triplett <[email protected]>
  L:    [email protected]
  S:    Supported
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git rcu/dev
  F:    Documentation/RCU/torture.rst
  F:    kernel/locking/locktorture.c
  F:    kernel/rcu/rcuscale.c
  S:    Maintained
  W:    http://www.ideasonboard.org/uvc/
  T:    git git://linuxtv.org/media.git
 +F:    Documentation/userspace-api/media/drivers/uvcvideo.rst
 +F:    Documentation/userspace-api/media/v4l/metafmt-uvc.rst
 +F:    drivers/media/common/uvc.c
  F:    drivers/media/usb/uvc/
 +F:    include/linux/usb/uvc.h
  F:    include/uapi/linux/uvcvideo.h
  
  USB WEBCAM GADGET
@@@ -25208,6 -25028,21 +25220,6 @@@ F:  include/uapi/linux/vsockmon.
  F:    net/vmw_vsock/
  F:    tools/testing/vsock/
  
 -VMA
 -M:    Andrew Morton <[email protected]>
 -M:    Liam R. Howlett <[email protected]>
 -M:    Lorenzo Stoakes <[email protected]>
 -R:    Vlastimil Babka <[email protected]>
 -R:    Jann Horn <[email protected]>
 -L:    [email protected]
 -S:    Maintained
 -W:    https://www.linux-mm.org
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
 -F:    mm/vma.c
 -F:    mm/vma.h
 -F:    mm/vma_internal.h
 -F:    tools/testing/vma/
 -
  VMALLOC
  M:    Andrew Morton <[email protected]>
  R:    Uladzislau Rezki <[email protected]>
index 09bd93464b4f72b901baf7911319f38b7874b265,013637e2b2a8e6a4ec6b93a520f8d5d9d3245467..9ec265fcaff4e2713f3fbb823bbfefd211fd3afd
@@@ -180,7 -180,10 +180,7 @@@ int __init early_init_dt_scan_recoverab
        /*
         * Allocate a buffer to hold the MC recoverable ranges.
         */
 -      mc_recoverable_range = memblock_alloc(size, __alignof__(u64));
 -      if (!mc_recoverable_range)
 -              panic("%s: Failed to allocate %u bytes align=0x%lx\n",
 -                    __func__, size, __alignof__(u64));
 +      mc_recoverable_range = memblock_alloc_or_panic(size, __alignof__(u64));
  
        for (i = 0; i < mc_recoverable_range_len; i++) {
                mc_recoverable_range[i].start_addr =
@@@ -815,7 -818,7 +815,7 @@@ static int opal_add_one_export(struct k
        sysfs_bin_attr_init(attr);
        attr->attr.name = name;
        attr->attr.mode = 0400;
-       attr->read = sysfs_bin_attr_simple_read;
+       attr->read_new = sysfs_bin_attr_simple_read;
        attr->private = __va(vals[0]);
        attr->size = vals[1];
  
diff --combined drivers/block/sunvdc.c
index 88dcae6ec575172ed1d4b019f9851c1320f62d4d,386643ceed59921203828844aa070833c44c67fb..e4d1e7284daeece51e30ea7a71d16387ffc290de
@@@ -829,7 -829,7 +829,7 @@@ static int probe_disk(struct vdc_port *
        }
  
        err = blk_mq_alloc_sq_tag_set(&port->tag_set, &vdc_mq_ops,
 -                      VDC_TX_RING_SIZE, BLK_MQ_F_SHOULD_MERGE);
 +                      VDC_TX_RING_SIZE, 0);
        if (err)
                return err;
  
@@@ -918,12 -918,12 +918,12 @@@ struct vdc_check_port_data 
        char    *type;
  };
  
- static int vdc_device_probed(struct device *dev, void *arg)
+ static int vdc_device_probed(struct device *dev, const void *arg)
  {
        struct vio_dev *vdev = to_vio_dev(dev);
-       struct vdc_check_port_data *port_data;
+       const struct vdc_check_port_data *port_data;
  
-       port_data = (struct vdc_check_port_data *)arg;
+       port_data = (const struct vdc_check_port_data *)arg;
  
        if ((vdev->dev_no == port_data->dev_no) &&
            (!(strcmp((char *)&vdev->type, port_data->type))) &&
index cd25e5afe55a7a304f8256d06be466cf86b6baf6,fe617c49449db2dab9bc88a5290898df7ac7dcb5..f22ad2882697cc5459192ce969b8b8ebd11f6901
@@@ -12,9 -12,9 +12,9 @@@
  #include <linux/pm_runtime.h>
  #include <linux/dma-mapping.h>
  
 +#include <drm/clients/drm_client_setup.h>
  #include <drm/drm_atomic.h>
  #include <drm/drm_atomic_helper.h>
 -#include <drm/drm_client_setup.h>
  #include <drm/drm_drv.h>
  #include <drm/drm_fbdev_dma.h>
  #include <drm/drm_fourcc.h>
@@@ -33,6 -33,7 +33,6 @@@
  
  #define DRIVER_NAME "mediatek"
  #define DRIVER_DESC "Mediatek SoC DRM"
 -#define DRIVER_DATE "20150513"
  #define DRIVER_MAJOR 1
  #define DRIVER_MINOR 0
  
@@@ -358,7 -359,7 +358,7 @@@ static const struct of_device_id mtk_dr
  };
  MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
  
- static int mtk_drm_match(struct device *dev, void *data)
+ static int mtk_drm_match(struct device *dev, const void *data)
  {
        if (!strncmp(dev_name(dev), "mediatek-drm", sizeof("mediatek-drm") - 1))
                return true;
@@@ -617,6 -618,7 +617,6 @@@ static const struct drm_driver mtk_drm_
  
        .name = DRIVER_NAME,
        .desc = DRIVER_DESC,
 -      .date = DRIVER_DATE,
        .major = DRIVER_MAJOR,
        .minor = DRIVER_MINOR,
  };
diff --combined drivers/hwmon/hwmon.c
index b7c0b1e3c23b82c515b142452a11de9ad0fa2cc0,6552ee5186896e9290658a26d8f230849aacafa6..9703d60e9bbf00292b7ef5a0d78b5cb2ad326568
@@@ -158,6 -158,11 +158,6 @@@ static umode_t hwmon_is_visible(const s
  
  /* Thermal zone handling */
  
 -/*
 - * The complex conditional is necessary to avoid a cyclic dependency
 - * between hwmon and thermal_sys modules.
 - */
 -#ifdef CONFIG_THERMAL_OF
  static int hwmon_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
  {
        struct hwmon_thermal_data *tdata = thermal_zone_device_priv(tz);
@@@ -263,9 -268,6 +263,9 @@@ static int hwmon_thermal_register_senso
        void *drvdata = dev_get_drvdata(dev);
        int i;
  
 +      if (!IS_ENABLED(CONFIG_THERMAL_OF))
 +              return 0;
 +
        for (i = 1; info[i]; i++) {
                int j;
  
@@@ -294,9 -296,6 +294,9 @@@ static void hwmon_thermal_notify(struc
        struct hwmon_device *hwdev = to_hwmon_device(dev);
        struct hwmon_thermal_data *tzdata;
  
 +      if (!IS_ENABLED(CONFIG_THERMAL_OF))
 +              return;
 +
        list_for_each_entry(tzdata, &hwdev->tzdata, node) {
                if (tzdata->index == index) {
                        thermal_zone_device_update(tzdata->tzd,
        }
  }
  
 -#else
 -static int hwmon_thermal_register_sensors(struct device *dev)
 -{
 -      return 0;
 -}
 -
 -static void hwmon_thermal_notify(struct device *dev, int index) { }
 -
 -#endif /* IS_REACHABLE(CONFIG_THERMAL) && ... */
 -
  static int hwmon_attr_base(enum hwmon_sensor_types type)
  {
        if (type == hwmon_in || type == hwmon_intrusion)
  
  static DEFINE_MUTEX(hwmon_pec_mutex);
  
- static int hwmon_match_device(struct device *dev, void *data)
+ static int hwmon_match_device(struct device *dev, const void *data)
  {
        return dev->class == &hwmon_class;
  }
@@@ -1170,12 -1179,6 +1170,12 @@@ devm_hwmon_device_register_with_info(st
        if (!dev)
                return ERR_PTR(-EINVAL);
  
 +      if (!name) {
 +              name = devm_hwmon_sanitize_name(dev, dev_name(dev));
 +              if (IS_ERR(name))
 +                      return ERR_CAST(name);
 +      }
 +
        ptr = devres_alloc(devm_hwmon_release, sizeof(*ptr), GFP_KERNEL);
        if (!ptr)
                return ERR_PTR(-ENOMEM);
index c24ccefb015ee2310dd41f4e5c967ff373b8e665,7c810893bfa332721d242f6c4a83f6217f22a6fc..e2c2a2ef1c12c36fa9f94bb219c5df85af273841
@@@ -1015,8 -1015,6 +1015,8 @@@ i2c_new_client_device(struct i2c_adapte
        if (status)
                goto out_remove_swnode;
  
 +      client->debugfs = debugfs_create_dir(dev_name(&client->dev), adap->debugfs);
 +
        dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",
                client->name, dev_name(&client->dev));
  
@@@ -1060,8 -1058,6 +1060,8 @@@ void i2c_unregister_device(struct i2c_c
  
        if (ACPI_COMPANION(&client->dev))
                acpi_device_clear_enumerated(ACPI_COMPANION(&client->dev));
 +
 +      debugfs_remove_recursive(client->debugfs);
        device_remove_software_node(&client->dev);
        device_unregister(&client->dev);
  }
@@@ -1297,12 -1293,14 +1297,12 @@@ new_device_store(struct device *dev, st
                info.flags |= I2C_CLIENT_SLAVE;
        }
  
 +      info.flags |= I2C_CLIENT_USER;
 +
        client = i2c_new_client_device(adap, &info);
        if (IS_ERR(client))
                return PTR_ERR(client);
  
 -      /* Keep track of the added device */
 -      mutex_lock(&adap->userspace_clients_lock);
 -      list_add_tail(&client->detected, &adap->userspace_clients);
 -      mutex_unlock(&adap->userspace_clients_lock);
        dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
                 info.type, info.addr);
  
  }
  static DEVICE_ATTR_WO(new_device);
  
- static int __i2c_find_user_addr(struct device *dev, void *addrp)
++static int __i2c_find_user_addr(struct device *dev, const void *addrp)
 +{
 +      struct i2c_client *client = i2c_verify_client(dev);
 +      unsigned short addr = *(unsigned short *)addrp;
 +
 +      return client && client->flags & I2C_CLIENT_USER &&
 +             i2c_encode_flags_to_addr(client) == addr;
 +}
 +
  /*
   * And of course let the users delete the devices they instantiated, if
   * they got it wrong. This interface can only be used to delete devices
@@@ -1333,7 -1322,7 +1333,7 @@@ delete_device_store(struct device *dev
                    const char *buf, size_t count)
  {
        struct i2c_adapter *adap = to_i2c_adapter(dev);
 -      struct i2c_client *client, *next;
 +      struct device *child_dev;
        unsigned short addr;
        char end;
        int res;
                return -EINVAL;
        }
  
 +      mutex_lock(&core_lock);
        /* Make sure the device was added through sysfs */
 -      res = -ENOENT;
 -      mutex_lock_nested(&adap->userspace_clients_lock,
 -                        i2c_adapter_depth(adap));
 -      list_for_each_entry_safe(client, next, &adap->userspace_clients,
 -                               detected) {
 -              if (i2c_encode_flags_to_addr(client) == addr) {
 -                      dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
 -                               "delete_device", client->name, client->addr);
 -
 -                      list_del(&client->detected);
 -                      i2c_unregister_device(client);
 -                      res = count;
 -                      break;
 -              }
 +      child_dev = device_find_child(&adap->dev, &addr, __i2c_find_user_addr);
 +      if (child_dev) {
 +              i2c_unregister_device(i2c_verify_client(child_dev));
 +              put_device(child_dev);
 +      } else {
 +              dev_err(dev, "Can't find userspace-created device at %#x\n", addr);
 +              count = -ENOENT;
        }
 -      mutex_unlock(&adap->userspace_clients_lock);
 +      mutex_unlock(&core_lock);
  
 -      if (res < 0)
 -              dev_err(dev, "%s: Can't find device in list\n",
 -                      "delete_device");
 -      return res;
 +      return count;
  }
  static DEVICE_ATTR_IGNORE_LOCKDEP(delete_device, S_IWUSR, NULL,
                                  delete_device_store);
@@@ -1532,6 -1530,8 +1532,6 @@@ static int i2c_register_adapter(struct 
        adap->locked_flags = 0;
        rt_mutex_init(&adap->bus_lock);
        rt_mutex_init(&adap->mux_lock);
 -      mutex_init(&adap->userspace_clients_lock);
 -      INIT_LIST_HEAD(&adap->userspace_clients);
  
        /* Set default timeout to 1 second if not already set */
        if (adap->timeout == 0)
        res = device_add(&adap->dev);
        if (res) {
                pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
 +              put_device(&adap->dev);
                goto out_list;
        }
  
@@@ -1697,6 -1696,23 +1697,6 @@@ int i2c_add_numbered_adapter(struct i2c
  }
  EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
  
 -static void i2c_do_del_adapter(struct i2c_driver *driver,
 -                            struct i2c_adapter *adapter)
 -{
 -      struct i2c_client *client, *_n;
 -
 -      /* Remove the devices we created ourselves as the result of hardware
 -       * probing (using a driver's detect method) */
 -      list_for_each_entry_safe(client, _n, &driver->clients, detected) {
 -              if (client->adapter == adapter) {
 -                      dev_dbg(&adapter->dev, "Removing %s at 0x%x\n",
 -                              client->name, client->addr);
 -                      list_del(&client->detected);
 -                      i2c_unregister_device(client);
 -              }
 -      }
 -}
 -
  static int __unregister_client(struct device *dev, void *dummy)
  {
        struct i2c_client *client = i2c_verify_client(dev);
@@@ -1712,6 -1728,12 +1712,6 @@@ static int __unregister_dummy(struct de
        return 0;
  }
  
 -static int __process_removed_adapter(struct device_driver *d, void *data)
 -{
 -      i2c_do_del_adapter(to_i2c_driver(d), data);
 -      return 0;
 -}
 -
  /**
   * i2c_del_adapter - unregister I2C adapter
   * @adap: the adapter being unregistered
  void i2c_del_adapter(struct i2c_adapter *adap)
  {
        struct i2c_adapter *found;
 -      struct i2c_client *client, *next;
  
        /* First make sure that this adapter was ever added */
        mutex_lock(&core_lock);
        }
  
        i2c_acpi_remove_space_handler(adap);
 -      /* Tell drivers about this removal */
 -      mutex_lock(&core_lock);
 -      bus_for_each_drv(&i2c_bus_type, NULL, adap,
 -                             __process_removed_adapter);
 -      mutex_unlock(&core_lock);
 -
 -      /* Remove devices instantiated from sysfs */
 -      mutex_lock_nested(&adap->userspace_clients_lock,
 -                        i2c_adapter_depth(adap));
 -      list_for_each_entry_safe(client, next, &adap->userspace_clients,
 -                               detected) {
 -              dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name,
 -                      client->addr);
 -              list_del(&client->detected);
 -              i2c_unregister_device(client);
 -      }
 -      mutex_unlock(&adap->userspace_clients_lock);
  
        /* Detach any active clients. This can't fail, thus we do not
         * check the returned value. This is a two-pass process, because
         * we can't remove the dummy devices during the first pass: they
         * could have been instantiated by real devices wishing to clean
         * them up properly, so we give them a chance to do that first. */
 +      mutex_lock(&core_lock);
        device_for_each_child(&adap->dev, NULL, __unregister_client);
        device_for_each_child(&adap->dev, NULL, __unregister_dummy);
 +      mutex_unlock(&core_lock);
  
        /* device name is gone after device_unregister */
        dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
@@@ -1963,6 -2001,7 +1963,6 @@@ int i2c_register_driver(struct module *
        /* add the driver to the list of i2c drivers in the driver core */
        driver->driver.owner = owner;
        driver->driver.bus = &i2c_bus_type;
 -      INIT_LIST_HEAD(&driver->clients);
  
        /* When registration returns, the driver core
         * will have called probe() for all matching-but-unbound devices.
  }
  EXPORT_SYMBOL(i2c_register_driver);
  
 -static int __process_removed_driver(struct device *dev, void *data)
 +static int __i2c_unregister_detected_client(struct device *dev, void *argp)
  {
 -      if (dev->type == &i2c_adapter_type)
 -              i2c_do_del_adapter(data, to_i2c_adapter(dev));
 +      struct i2c_client *client = i2c_verify_client(dev);
 +
 +      if (client && client->flags & I2C_CLIENT_AUTO)
 +              i2c_unregister_device(client);
 +
        return 0;
  }
  
   */
  void i2c_del_driver(struct i2c_driver *driver)
  {
 -      i2c_for_each_dev(driver, __process_removed_driver);
 +      mutex_lock(&core_lock);
 +      /* Satisfy __must_check, function can't fail */
 +      if (driver_for_each_device(&driver->driver, NULL, NULL,
 +                                 __i2c_unregister_detected_client)) {
 +      }
 +      mutex_unlock(&core_lock);
  
        driver_unregister(&driver->driver);
        pr_debug("driver [%s] unregistered\n", driver->driver.name);
@@@ -2429,7 -2460,6 +2429,7 @@@ static int i2c_detect_address(struct i2
        /* Finally call the custom detection function */
        memset(&info, 0, sizeof(struct i2c_board_info));
        info.addr = addr;
 +      info.flags = I2C_CLIENT_AUTO;
        err = driver->detect(temp_client, &info);
        if (err) {
                /* -ENODEV is returned if the detection fails. We catch it
                dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",
                        info.type, info.addr);
                client = i2c_new_client_device(adapter, &info);
 -              if (!IS_ERR(client))
 -                      list_add_tail(&client->detected, &driver->clients);
 -              else
 +              if (IS_ERR(client))
                        dev_err(&adapter->dev, "Failed creating %s at 0x%02x\n",
                                info.type, info.addr);
        }
  static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
  {
        const unsigned short *address_list;
 -      struct i2c_client *temp_client;
 +      struct i2c_client temp_client;
        int i, err = 0;
  
        address_list = driver->address_list;
                return 0;
  
        /* Set up a temporary client to help detect callback */
 -      temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
 -      if (!temp_client)
 -              return -ENOMEM;
 -      temp_client->adapter = adapter;
 +      memset(&temp_client, 0, sizeof(temp_client));
 +      temp_client.adapter = adapter;
  
        for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
                dev_dbg(&adapter->dev,
                        "found normal entry for adapter %d, addr 0x%02x\n",
                        i2c_adapter_id(adapter), address_list[i]);
 -              temp_client->addr = address_list[i];
 -              err = i2c_detect_address(temp_client, driver);
 +              temp_client.addr = address_list[i];
 +              err = i2c_detect_address(&temp_client, driver);
                if (unlikely(err))
                        break;
        }
  
 -      kfree(temp_client);
        return err;
  }
  
index 7d3b24c8ecae548640f6722f848dd7f2d9d43b8a,2de825ac08b3d7470f06ba4102b19897a8e68aa5..4fe1a9c0bc1ba3158ab4e3d077c6c65782eddb31
@@@ -2,7 -2,7 +2,7 @@@
  /*
   * CZ.NIC's Turris Omnia LEDs driver
   *
 - * 2020, 2023 by Marek Behún <[email protected]>
 + * 2020, 2023, 2024 by Marek Behún <[email protected]>
   */
  
  #include <linux/i2c.h>
  #include <linux/module.h>
  #include <linux/mutex.h>
  #include <linux/of.h>
 +#include <linux/turris-omnia-mcu-interface.h>
  
  #define OMNIA_BOARD_LEDS      12
  #define OMNIA_LED_NUM_CHANNELS        3
  
 -/* MCU controller commands at I2C address 0x2a */
 -#define OMNIA_MCU_I2C_ADDR            0x2a
 -
 -#define CMD_GET_STATUS_WORD           0x01
 -#define STS_FEATURES_SUPPORTED                BIT(2)
 -
 -#define CMD_GET_FEATURES              0x10
 -#define FEAT_LED_GAMMA_CORRECTION     BIT(5)
 -
 -/* LED controller commands at I2C address 0x2b */
 -#define CMD_LED_MODE                  0x03
 -#define CMD_LED_MODE_LED(l)           ((l) & 0x0f)
 -#define CMD_LED_MODE_USER             0x10
 -
 -#define CMD_LED_STATE                 0x04
 -#define CMD_LED_STATE_LED(l)          ((l) & 0x0f)
 -#define CMD_LED_STATE_ON              0x10
 -
 -#define CMD_LED_COLOR                 0x05
 -#define CMD_LED_SET_BRIGHTNESS                0x07
 -#define CMD_LED_GET_BRIGHTNESS                0x08
 -
 -#define CMD_SET_GAMMA_CORRECTION      0x30
 -#define CMD_GET_GAMMA_CORRECTION      0x31
 -
 +/* MCU controller I2C address 0x2a, needed for detecting MCU features */
 +#define OMNIA_MCU_I2C_ADDR    0x2a
 +
 +/**
 + * struct omnia_led - per-LED part of driver private data structure
 + * @mc_cdev:          multi-color LED class device
 + * @subled_info:      per-channel information
 + * @cached_channels:  cached values of per-channel brightness that was sent to the MCU
 + * @on:                       whether the LED was set on
 + * @hwtrig:           whether the LED blinking was offloaded to the MCU
 + * @reg:              LED identifier to the MCU
 + */
  struct omnia_led {
        struct led_classdev_mc mc_cdev;
        struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS];
  
  #define to_omnia_led(l)               container_of(l, struct omnia_led, mc_cdev)
  
 +/**
 + * struct omnia_leds - driver private data structure
 + * @client:                   I2C client device
 + * @lock:                     mutex to protect cached state
 + * @has_gamma_correction:     whether the MCU firmware supports gamma correction
 + * @brightness_knode:         kernel node of the "brightness" device sysfs attribute (this is the
 + *                            driver specific global brightness, not the LED classdev brightness)
 + * @leds:                     flexible array of per-LED data
 + */
  struct omnia_leds {
        struct i2c_client *client;
        struct mutex lock;
        bool has_gamma_correction;
 +      struct kernfs_node *brightness_knode;
        struct omnia_led leds[];
  };
  
 -static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val)
 -{
 -      u8 buf[2] = { cmd, val };
 -      int ret;
 -
 -      ret = i2c_master_send(client, buf, sizeof(buf));
 -
 -      return ret < 0 ? ret : 0;
 -}
 -
 -static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd,
 -                            void *reply, size_t len)
 -{
 -      struct i2c_msg msgs[2];
 -      int ret;
 -
 -      msgs[0].addr = addr;
 -      msgs[0].flags = 0;
 -      msgs[0].len = 1;
 -      msgs[0].buf = &cmd;
 -      msgs[1].addr = addr;
 -      msgs[1].flags = I2C_M_RD;
 -      msgs[1].len = len;
 -      msgs[1].buf = reply;
 -
 -      ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
 -      if (likely(ret == ARRAY_SIZE(msgs)))
 -              return 0;
 -      else if (ret < 0)
 -              return ret;
 -      else
 -              return -EIO;
 -}
 -
 -static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
 +static int omnia_cmd_set_color(const struct i2c_client *client, u8 led, u8 r, u8 g, u8 b)
  {
 -      u8 reply;
 -      int err;
 +      u8 buf[5] = { OMNIA_CMD_LED_COLOR, led, r, g, b };
  
 -      err = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
 -      if (err)
 -              return err;
 -
 -      return reply;
 +      return omnia_cmd_write(client, buf, sizeof(buf));
  }
  
  static int omnia_led_send_color_cmd(const struct i2c_client *client,
                                    struct omnia_led *led)
  {
 -      char cmd[5];
        int ret;
  
 -      cmd[0] = CMD_LED_COLOR;
 -      cmd[1] = led->reg;
 -      cmd[2] = led->subled_info[0].brightness;
 -      cmd[3] = led->subled_info[1].brightness;
 -      cmd[4] = led->subled_info[2].brightness;
 -
        /* Send the color change command */
 -      ret = i2c_master_send(client, cmd, 5);
 +      ret = omnia_cmd_set_color(client, led->reg, led->subled_info[0].brightness,
 +                                led->subled_info[1].brightness, led->subled_info[2].brightness);
        if (ret < 0)
                return ret;
  
@@@ -123,12 -170,12 +123,12 @@@ static int omnia_led_brightness_set_blo
         * is not being blinked by HW.
         */
        if (!err && !led->hwtrig && !brightness != !led->on) {
 -              u8 state = CMD_LED_STATE_LED(led->reg);
 +              u8 state = OMNIA_CMD_LED_STATE_LED(led->reg);
  
                if (brightness)
 -                      state |= CMD_LED_STATE_ON;
 +                      state |= OMNIA_CMD_LED_STATE_ON;
  
 -              err = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state);
 +              err = omnia_cmd_write_u8(leds->client, OMNIA_CMD_LED_STATE, state);
                if (!err)
                        led->on = !!brightness;
        }
@@@ -163,8 -210,8 +163,8 @@@ static int omnia_hwtrig_activate(struc
  
        if (!err) {
                /* Put the LED into MCU controlled mode */
 -              err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE,
 -                                       CMD_LED_MODE_LED(led->reg));
 +              err = omnia_cmd_write_u8(leds->client, OMNIA_CMD_LED_MODE,
 +                                       OMNIA_CMD_LED_MODE_LED(led->reg));
                if (!err)
                        led->hwtrig = true;
        }
@@@ -185,8 -232,9 +185,8 @@@ static void omnia_hwtrig_deactivate(str
        led->hwtrig = false;
  
        /* Put the LED into software mode */
 -      err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE,
 -                               CMD_LED_MODE_LED(led->reg) |
 -                               CMD_LED_MODE_USER);
 +      err = omnia_cmd_write_u8(leds->client, OMNIA_CMD_LED_MODE,
 +                               OMNIA_CMD_LED_MODE_LED(led->reg) | OMNIA_CMD_LED_MODE_USER);
  
        mutex_unlock(&leds->lock);
  
@@@ -252,26 -300,38 +252,26 @@@ static int omnia_led_register(struct i2
         */
        cdev->default_trigger = omnia_hw_trigger.name;
  
 -      /* put the LED into software mode */
 -      ret = omnia_cmd_write_u8(client, CMD_LED_MODE,
 -                               CMD_LED_MODE_LED(led->reg) |
 -                               CMD_LED_MODE_USER);
 -      if (ret) {
 -              dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np,
 -                      ret);
 -              return ret;
 -      }
 +      /* Put the LED into software mode */
 +      ret = omnia_cmd_write_u8(client, OMNIA_CMD_LED_MODE, OMNIA_CMD_LED_MODE_LED(led->reg) |
 +                                                           OMNIA_CMD_LED_MODE_USER);
 +      if (ret)
 +              return dev_err_probe(dev, ret, "Cannot set LED %pOF to software mode\n", np);
  
 -      /* disable the LED */
 -      ret = omnia_cmd_write_u8(client, CMD_LED_STATE,
 -                               CMD_LED_STATE_LED(led->reg));
 -      if (ret) {
 -              dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret);
 -              return ret;
 -      }
 +      /* Disable the LED */
 +      ret = omnia_cmd_write_u8(client, OMNIA_CMD_LED_STATE, OMNIA_CMD_LED_STATE_LED(led->reg));
 +      if (ret)
 +              return dev_err_probe(dev, ret, "Cannot set LED %pOF brightness\n", np);
  
        /* Set initial color and cache it */
        ret = omnia_led_send_color_cmd(client, led);
 -      if (ret < 0) {
 -              dev_err(dev, "Cannot set LED %pOF initial color: %i\n", np,
 -                      ret);
 -              return ret;
 -      }
 +      if (ret < 0)
 +              return dev_err_probe(dev, ret, "Cannot set LED %pOF initial color\n", np);
  
        ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev,
                                                        &init_data);
 -      if (ret < 0) {
 -              dev_err(dev, "Cannot register LED %pOF: %i\n", np, ret);
 -              return ret;
 -      }
 +      if (ret < 0)
 +              return dev_err_probe(dev, ret, "Cannot register LED %pOF\n", np);
  
        return 1;
  }
@@@ -291,14 -351,14 +291,14 @@@ static ssize_t brightness_show(struct d
                               char *buf)
  {
        struct i2c_client *client = to_i2c_client(dev);
 -      int ret;
 -
 -      ret = omnia_cmd_read_u8(client, CMD_LED_GET_BRIGHTNESS);
 +      u8 reply;
 +      int err;
  
 -      if (ret < 0)
 -              return ret;
 +      err = omnia_cmd_read_u8(client, OMNIA_CMD_GET_BRIGHTNESS, &reply);
 +      if (err < 0)
 +              return err;
  
 -      return sysfs_emit(buf, "%d\n", ret);
 +      return sysfs_emit(buf, "%d\n", reply);
  }
  
  static ssize_t brightness_store(struct device *dev, struct device_attribute *a,
        if (brightness > 100)
                return -EINVAL;
  
 -      err = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness);
 +      err = omnia_cmd_write_u8(client, OMNIA_CMD_SET_BRIGHTNESS, brightness);
  
        return err ?: count;
  }
@@@ -325,16 -385,17 +325,16 @@@ static ssize_t gamma_correction_show(st
  {
        struct i2c_client *client = to_i2c_client(dev);
        struct omnia_leds *leds = i2c_get_clientdata(client);
 -      int ret;
 +      u8 reply = 0;
 +      int err;
  
        if (leds->has_gamma_correction) {
 -              ret = omnia_cmd_read_u8(client, CMD_GET_GAMMA_CORRECTION);
 -              if (ret < 0)
 -                      return ret;
 -      } else {
 -              ret = 0;
 +              err = omnia_cmd_read_u8(client, OMNIA_CMD_GET_GAMMA_CORRECTION, &reply);
 +              if (err < 0)
 +                      return err;
        }
  
 -      return sysfs_emit(buf, "%d\n", !!ret);
 +      return sysfs_emit(buf, "%d\n", !!reply);
  }
  
  static ssize_t gamma_correction_store(struct device *dev,
        if (kstrtobool(buf, &val) < 0)
                return -EINVAL;
  
 -      err = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val);
 +      err = omnia_cmd_write_u8(client, OMNIA_CMD_SET_GAMMA_CORRECTION, val);
  
        return err ?: count;
  }
@@@ -365,104 -426,26 +365,104 @@@ static struct attribute *omnia_led_cont
  };
  ATTRIBUTE_GROUPS(omnia_led_controller);
  
 -static int omnia_mcu_get_features(const struct i2c_client *client)
 +static irqreturn_t omnia_brightness_changed_threaded_fn(int irq, void *data)
 +{
 +      struct omnia_leds *leds = data;
 +
 +      if (unlikely(!leds->brightness_knode)) {
 +              /*
 +               * Note that sysfs_get_dirent() may sleep. This is okay, because we are in threaded
 +               * context.
 +               */
 +              leds->brightness_knode = sysfs_get_dirent(leds->client->dev.kobj.sd, "brightness");
 +              if (!leds->brightness_knode)
 +                      return IRQ_NONE;
 +      }
 +
 +      sysfs_notify_dirent(leds->brightness_knode);
 +
 +      return IRQ_HANDLED;
 +}
 +
 +static void omnia_brightness_knode_put(void *data)
 +{
 +      struct omnia_leds *leds = data;
 +
 +      if (leds->brightness_knode)
 +              sysfs_put(leds->brightness_knode);
 +}
 +
 +static int omnia_request_brightness_irq(struct omnia_leds *leds)
 +{
 +      struct device *dev = &leds->client->dev;
 +      int ret;
 +
 +      if (!leds->client->irq) {
 +              dev_info(dev,
 +                       "Brightness change interrupt supported by MCU firmware but not described in device-tree\n");
 +
 +              return 0;
 +      }
 +
 +      /*
 +       * Registering the brightness_knode destructor before requesting the IRQ ensures that on
 +       * removal the brightness_knode sysfs node is put only after the IRQ is freed.
 +       * This is needed because the interrupt handler uses the knode.
 +       */
 +      ret = devm_add_action(dev, omnia_brightness_knode_put, leds);
 +      if (ret < 0)
 +              return ret;
 +
 +      return devm_request_threaded_irq(dev, leds->client->irq, NULL,
 +                                       omnia_brightness_changed_threaded_fn, IRQF_ONESHOT,
 +                                       "leds-turris-omnia", leds);
 +}
 +
 +static int omnia_mcu_get_features(const struct i2c_client *mcu_client)
  {
        u16 reply;
        int err;
  
 -      err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
 -                               CMD_GET_STATUS_WORD, &reply, sizeof(reply));
 +      err = omnia_cmd_read_u16(mcu_client, OMNIA_CMD_GET_STATUS_WORD, &reply);
        if (err)
                return err;
  
 -      /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */
 -      if (!(le16_to_cpu(reply) & STS_FEATURES_SUPPORTED))
 +      /* Check whether MCU firmware supports the OMNIA_CMD_GET_FEAUTRES command */
 +      if (!(reply & OMNIA_STS_FEATURES_SUPPORTED))
                return 0;
  
 -      err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
 -                               CMD_GET_FEATURES, &reply, sizeof(reply));
 +      err = omnia_cmd_read_u16(mcu_client, OMNIA_CMD_GET_FEATURES, &reply);
        if (err)
                return err;
  
 -      return le16_to_cpu(reply);
 +      return reply;
 +}
 +
- static int omnia_match_mcu_client(struct device *dev, void *data)
++static int omnia_match_mcu_client(struct device *dev, const void *data)
 +{
 +      struct i2c_client *client;
 +
 +      client = i2c_verify_client(dev);
 +      if (!client)
 +              return 0;
 +
 +      return client->addr == OMNIA_MCU_I2C_ADDR;
 +}
 +
 +static int omnia_find_mcu_and_get_features(struct device *dev)
 +{
 +      struct device *mcu_dev;
 +      int ret;
 +
 +      mcu_dev = device_find_child(dev->parent, NULL, omnia_match_mcu_client);
 +      if (!mcu_dev)
 +              return -ENODEV;
 +
 +      ret = omnia_mcu_get_features(i2c_verify_client(mcu_dev));
 +
 +      put_device(mcu_dev);
 +
 +      return ret;
  }
  
  static int omnia_leds_probe(struct i2c_client *client)
        int ret, count;
  
        count = of_get_available_child_count(np);
 -      if (!count) {
 -              dev_err(dev, "LEDs are not defined in device tree!\n");
 -              return -ENODEV;
 -      } else if (count > OMNIA_BOARD_LEDS) {
 -              dev_err(dev, "Too many LEDs defined in device tree!\n");
 -              return -EINVAL;
 -      }
 +      if (count == 0)
 +              return dev_err_probe(dev, -ENODEV, "LEDs are not defined in device tree!\n");
 +      if (count > OMNIA_BOARD_LEDS)
 +              return dev_err_probe(dev, -EINVAL, "Too many LEDs defined in device tree!\n");
  
        leds = devm_kzalloc(dev, struct_size(leds, leds, count), GFP_KERNEL);
        if (!leds)
        leds->client = client;
        i2c_set_clientdata(client, leds);
  
 -      ret = omnia_mcu_get_features(client);
 -      if (ret < 0) {
 -              dev_err(dev, "Cannot determine MCU supported features: %d\n",
 -                      ret);
 -              return ret;
 -      }
 +      ret = omnia_find_mcu_and_get_features(dev);
 +      if (ret < 0)
 +              return dev_err_probe(dev, ret, "Cannot determine MCU supported features\n");
  
 -      leds->has_gamma_correction = ret & FEAT_LED_GAMMA_CORRECTION;
 -      if (!leds->has_gamma_correction) {
 -              dev_info(dev,
 -                       "Your board's MCU firmware does not support the LED gamma correction feature.\n");
 -              dev_info(dev,
 -                       "Consider upgrading MCU firmware with the omnia-mcutool utility.\n");
 +      leds->has_gamma_correction = ret & OMNIA_FEAT_LED_GAMMA_CORRECTION;
 +
 +      if (ret & OMNIA_FEAT_BRIGHTNESS_INT) {
 +              ret = omnia_request_brightness_irq(leds);
 +              if (ret < 0)
 +                      return dev_err_probe(dev, ret, "Cannot request brightness IRQ\n");
        }
  
        mutex_init(&leds->lock);
  
        ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
 -      if (ret < 0) {
 -              dev_err(dev, "Cannot register private LED trigger: %d\n", ret);
 -              return ret;
 -      }
 +      if (ret < 0)
 +              return dev_err_probe(dev, ret, "Cannot register private LED trigger\n");
  
        led = &leds->leds[0];
        for_each_available_child_of_node_scoped(np, child) {
  
  static void omnia_leds_remove(struct i2c_client *client)
  {
 -      u8 buf[5];
 -
 -      /* put all LEDs into default (HW triggered) mode */
 -      omnia_cmd_write_u8(client, CMD_LED_MODE,
 -                         CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
 -
 -      /* set all LEDs color to [255, 255, 255] */
 -      buf[0] = CMD_LED_COLOR;
 -      buf[1] = OMNIA_BOARD_LEDS;
 -      buf[2] = 255;
 -      buf[3] = 255;
 -      buf[4] = 255;
 +      /* Put all LEDs into default (HW triggered) mode */
 +      omnia_cmd_write_u8(client, OMNIA_CMD_LED_MODE, OMNIA_CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
  
 -      i2c_master_send(client, buf, 5);
 +      /* Set all LEDs color to [255, 255, 255] */
 +      omnia_cmd_set_color(client, OMNIA_BOARD_LEDS, 255, 255, 255);
  }
  
  static const struct of_device_id of_omnia_leds_match[] = {
index 8ceaed5c14531177691dbc4248cb0c4b92402b7f,697d50bedfe285d74c702efde61e510df87c1229..f90ffc4dad523a6e33db3cd5fa3daa329e45568e
@@@ -40,9 -40,7 +40,9 @@@
  #include "mgb4_trigger.h"
  #include "mgb4_core.h"
  
 -#define MGB4_USER_IRQS 16
 +#define MGB4_USER_IRQS  16
 +#define MGB4_MGB4_BAR_ID 0
 +#define MGB4_XDMA_BAR_ID 1
  
  #define DIGITEQ_VID 0x1ed8
  #define T100_DID    0x0101
@@@ -125,7 -123,7 +125,7 @@@ static const struct hwmon_chip_info tem
  };
  #endif
  
- static int match_i2c_adap(struct device *dev, void *data)
+ static int match_i2c_adap(struct device *dev, const void *data)
  {
        return i2c_verify_adapter(dev) ? 1 : 0;
  }
@@@ -141,7 -139,7 +141,7 @@@ static struct i2c_adapter *get_i2c_adap
        return dev ? to_i2c_adapter(dev) : NULL;
  }
  
- static int match_spi_adap(struct device *dev, void *data)
+ static int match_spi_adap(struct device *dev, const void *data)
  {
        return to_spi_device(dev) ? 1 : 0;
  }
index edbf8994455d3730154369954fc934690b8ccfbe,82e2908016bdd0db589f1bdeff55ddb5c7ab6861..5212dc439b1d900bb8a03fd7f4f3f5d8192bc536
@@@ -77,6 -77,7 +77,6 @@@ module_param(phyaddr, int, 0444)
  MODULE_PARM_DESC(phyaddr, "Physical device address");
  
  #define STMMAC_TX_THRESH(x)   ((x)->dma_conf.dma_tx_size / 4)
 -#define STMMAC_RX_THRESH(x)   ((x)->dma_conf.dma_rx_size / 4)
  
  /* Limit to make sure XDP TX and slow path can coexist */
  #define STMMAC_XSK_TX_BUDGET_MAX      256
@@@ -106,13 -107,15 +106,13 @@@ static int buf_sz = DEFAULT_BUFSIZE
  module_param(buf_sz, int, 0644);
  MODULE_PARM_DESC(buf_sz, "DMA buffer size");
  
 -#define       STMMAC_RX_COPYBREAK     256
 -
  static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
                                      NETIF_MSG_LINK | NETIF_MSG_IFUP |
                                      NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
  
  #define STMMAC_DEFAULT_LPI_TIMER      1000
 -static int eee_timer = STMMAC_DEFAULT_LPI_TIMER;
 -module_param(eee_timer, int, 0644);
 +static unsigned int eee_timer = STMMAC_DEFAULT_LPI_TIMER;
 +module_param(eee_timer, uint, 0644);
  MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec");
  #define STMMAC_LPI_T(x) (jiffies + usecs_to_jiffies(x))
  
@@@ -194,6 -197,8 +194,6 @@@ static void stmmac_verify_args(void
                flow_ctrl = FLOW_OFF;
        if (unlikely((pause < 0) || (pause > 0xffff)))
                pause = PAUSE_TIME;
 -      if (eee_timer < 0)
 -              eee_timer = STMMAC_DEFAULT_LPI_TIMER;
  }
  
  static void __stmmac_disable_all_queues(struct stmmac_priv *priv)
@@@ -296,7 -301,7 +296,7 @@@ static void stmmac_global_err(struct st
   */
  static void stmmac_clk_csr_set(struct stmmac_priv *priv)
  {
 -      u32 clk_rate;
 +      unsigned long clk_rate;
  
        clk_rate = clk_get_rate(priv->plat->stmmac_clk);
  
                        priv->clk_csr = STMMAC_CSR_150_250M;
                else if ((clk_rate >= CSR_F_250M) && (clk_rate <= CSR_F_300M))
                        priv->clk_csr = STMMAC_CSR_250_300M;
 +              else if ((clk_rate >= CSR_F_300M) && (clk_rate < CSR_F_500M))
 +                      priv->clk_csr = STMMAC_CSR_300_500M;
 +              else if ((clk_rate >= CSR_F_500M) && (clk_rate < CSR_F_800M))
 +                      priv->clk_csr = STMMAC_CSR_500_800M;
        }
  
        if (priv->plat->flags & STMMAC_FLAG_HAS_SUN8I) {
@@@ -390,17 -391,23 +390,17 @@@ static inline u32 stmmac_rx_dirty(struc
        return dirty;
  }
  
 -static void stmmac_lpi_entry_timer_config(struct stmmac_priv *priv, bool en)
 +static void stmmac_disable_hw_lpi_timer(struct stmmac_priv *priv)
  {
 -      int tx_lpi_timer;
 +      stmmac_set_eee_lpi_timer(priv, priv->hw, 0);
 +}
  
 -      /* Clear/set the SW EEE timer flag based on LPI ET enablement */
 -      priv->eee_sw_timer_en = en ? 0 : 1;
 -      tx_lpi_timer  = en ? priv->tx_lpi_timer : 0;
 -      stmmac_set_eee_lpi_timer(priv, priv->hw, tx_lpi_timer);
 +static void stmmac_enable_hw_lpi_timer(struct stmmac_priv *priv)
 +{
 +      stmmac_set_eee_lpi_timer(priv, priv->hw, priv->tx_lpi_timer);
  }
  
 -/**
 - * stmmac_enable_eee_mode - check and enter in LPI mode
 - * @priv: driver private structure
 - * Description: this function is to verify and enter in LPI mode in case of
 - * EEE.
 - */
 -static int stmmac_enable_eee_mode(struct stmmac_priv *priv)
 +static bool stmmac_eee_tx_busy(struct stmmac_priv *priv)
  {
        u32 tx_cnt = priv->plat->tx_queues_to_use;
        u32 queue;
                struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
  
                if (tx_q->dirty_tx != tx_q->cur_tx)
 -                      return -EBUSY; /* still unfinished work */
 +                      return true; /* still unfinished work */
 +      }
 +
 +      return false;
 +}
 +
 +static void stmmac_restart_sw_lpi_timer(struct stmmac_priv *priv)
 +{
 +      mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
 +}
 +
 +/**
 + * stmmac_try_to_start_sw_lpi - check and enter in LPI mode
 + * @priv: driver private structure
 + * Description: this function is to verify and enter in LPI mode in case of
 + * EEE.
 + */
 +static void stmmac_try_to_start_sw_lpi(struct stmmac_priv *priv)
 +{
 +      if (stmmac_eee_tx_busy(priv)) {
 +              stmmac_restart_sw_lpi_timer(priv);
 +              return;
        }
  
        /* Check and enter in LPI mode */
        if (!priv->tx_path_in_lpi_mode)
                stmmac_set_eee_mode(priv, priv->hw,
                        priv->plat->flags & STMMAC_FLAG_EN_TX_LPI_CLOCKGATING);
 -      return 0;
  }
  
  /**
 - * stmmac_disable_eee_mode - disable and exit from LPI mode
 + * stmmac_stop_sw_lpi - stop transmitting LPI
   * @priv: driver private structure
 - * Description: this function is to exit and disable EEE in case of
 - * LPI state is true. This is called by the xmit.
 + * Description: When using software-controlled LPI, stop transmitting LPI state.
   */
 -void stmmac_disable_eee_mode(struct stmmac_priv *priv)
 +static void stmmac_stop_sw_lpi(struct stmmac_priv *priv)
  {
 -      if (!priv->eee_sw_timer_en) {
 -              stmmac_lpi_entry_timer_config(priv, 0);
 -              return;
 -      }
 -
        stmmac_reset_eee_mode(priv, priv->hw);
        del_timer_sync(&priv->eee_ctrl_timer);
        priv->tx_path_in_lpi_mode = false;
@@@ -463,27 -456,25 +463,27 @@@ static void stmmac_eee_ctrl_timer(struc
  {
        struct stmmac_priv *priv = from_timer(priv, t, eee_ctrl_timer);
  
 -      if (stmmac_enable_eee_mode(priv))
 -              mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
 +      stmmac_try_to_start_sw_lpi(priv);
  }
  
  /**
   * stmmac_eee_init - init EEE
   * @priv: driver private structure
 + * @active: indicates whether EEE should be enabled.
   * Description:
   *  if the GMAC supports the EEE (from the HW cap reg) and the phy device
   *  can also manage EEE, this function enable the LPI state and start related
   *  timer.
   */
 -bool stmmac_eee_init(struct stmmac_priv *priv)
 +static void stmmac_eee_init(struct stmmac_priv *priv, bool active)
  {
 -      int eee_tw_timer = priv->eee_tw_timer;
 +      priv->eee_active = active;
  
        /* Check if MAC core supports the EEE feature. */
 -      if (!priv->dma_cap.eee)
 -              return false;
 +      if (!priv->dma_cap.eee) {
 +              priv->eee_enabled = false;
 +              return;
 +      }
  
        mutex_lock(&priv->lock);
  
        if (!priv->eee_active) {
                if (priv->eee_enabled) {
                        netdev_dbg(priv->dev, "disable EEE\n");
 -                      stmmac_lpi_entry_timer_config(priv, 0);
 +                      priv->eee_sw_timer_en = false;
 +                      stmmac_disable_hw_lpi_timer(priv);
                        del_timer_sync(&priv->eee_ctrl_timer);
 -                      stmmac_set_eee_timer(priv, priv->hw, 0, eee_tw_timer);
 +                      stmmac_set_eee_timer(priv, priv->hw, 0,
 +                                           STMMAC_DEFAULT_TWT_LS);
                        if (priv->hw->xpcs)
                                xpcs_config_eee(priv->hw->xpcs,
                                                priv->plat->mult_fact_100ns,
                                                false);
                }
 +              priv->eee_enabled = false;
                mutex_unlock(&priv->lock);
 -              return false;
 +              return;
        }
  
        if (priv->eee_active && !priv->eee_enabled) {
 -              timer_setup(&priv->eee_ctrl_timer, stmmac_eee_ctrl_timer, 0);
                stmmac_set_eee_timer(priv, priv->hw, STMMAC_DEFAULT_LIT_LS,
 -                                   eee_tw_timer);
 +                                   STMMAC_DEFAULT_TWT_LS);
                if (priv->hw->xpcs)
                        xpcs_config_eee(priv->hw->xpcs,
                                        priv->plat->mult_fact_100ns,
        }
  
        if (priv->plat->has_gmac4 && priv->tx_lpi_timer <= STMMAC_ET_MAX) {
 +              /* Use hardware LPI mode */
                del_timer_sync(&priv->eee_ctrl_timer);
                priv->tx_path_in_lpi_mode = false;
 -              stmmac_lpi_entry_timer_config(priv, 1);
 +              priv->eee_sw_timer_en = false;
 +              stmmac_enable_hw_lpi_timer(priv);
        } else {
 -              stmmac_lpi_entry_timer_config(priv, 0);
 -              mod_timer(&priv->eee_ctrl_timer,
 -                        STMMAC_LPI_T(priv->tx_lpi_timer));
 +              /* Use software LPI mode */
 +              priv->eee_sw_timer_en = true;
 +              stmmac_disable_hw_lpi_timer(priv);
 +              stmmac_restart_sw_lpi_timer(priv);
        }
  
 +      priv->eee_enabled = true;
 +
        mutex_unlock(&priv->lock);
        netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n");
 -      return true;
  }
  
  /* stmmac_get_tx_hwtstamp - get HW TX timestamps
@@@ -988,8 -973,10 +988,8 @@@ static void stmmac_mac_link_down(struc
        struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
  
        stmmac_mac_set(priv, priv->ioaddr, false);
 -      priv->eee_active = false;
 -      priv->tx_lpi_enabled = false;
 -      priv->eee_enabled = stmmac_eee_init(priv);
 -      stmmac_set_eee_pls(priv, priv->hw, false);
 +      if (priv->dma_cap.eee)
 +              stmmac_set_eee_pls(priv, priv->hw, false);
  
        if (stmmac_fpe_supported(priv))
                stmmac_fpe_link_state_handle(priv, false);
@@@ -1096,8 -1083,14 +1096,8 @@@ static void stmmac_mac_link_up(struct p
                writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
  
        stmmac_mac_set(priv, priv->ioaddr, true);
 -      if (phy && priv->dma_cap.eee) {
 -              priv->eee_active =
 -                      phy_init_eee(phy, !(priv->plat->flags &
 -                              STMMAC_FLAG_RX_CLK_RUNS_IN_LPI)) >= 0;
 -              priv->eee_enabled = stmmac_eee_init(priv);
 -              priv->tx_lpi_enabled = priv->eee_enabled;
 +      if (priv->dma_cap.eee)
                stmmac_set_eee_pls(priv, priv->hw, true);
 -      }
  
        if (stmmac_fpe_supported(priv))
                stmmac_fpe_link_state_handle(priv, true);
                stmmac_hwtstamp_correct_latency(priv, priv);
  }
  
 +static void stmmac_mac_disable_tx_lpi(struct phylink_config *config)
 +{
 +      struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
 +
 +      stmmac_eee_init(priv, false);
 +}
 +
 +static int stmmac_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
 +                                  bool tx_clk_stop)
 +{
 +      struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
 +
 +      priv->tx_lpi_timer = timer;
 +      stmmac_eee_init(priv, true);
 +
 +      return 0;
 +}
 +
  static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
        .mac_get_caps = stmmac_mac_get_caps,
        .mac_select_pcs = stmmac_mac_select_pcs,
        .mac_config = stmmac_mac_config,
        .mac_link_down = stmmac_mac_link_down,
        .mac_link_up = stmmac_mac_link_up,
 +      .mac_disable_tx_lpi = stmmac_mac_disable_tx_lpi,
 +      .mac_enable_tx_lpi = stmmac_mac_enable_tx_lpi,
  };
  
  /**
@@@ -1204,27 -1177,15 +1204,27 @@@ static int stmmac_init_phy(struct net_d
                        return -ENODEV;
                }
  
 -              if (priv->dma_cap.eee)
 -                      phy_support_eee(phydev);
 -
                ret = phylink_connect_phy(priv->phylink, phydev);
        } else {
                fwnode_handle_put(phy_fwnode);
                ret = phylink_fwnode_phy_connect(priv->phylink, fwnode, 0);
        }
  
 +      if (ret == 0) {
 +              struct ethtool_keee eee;
 +
 +              /* Configure phylib's copy of the LPI timer. Normally,
 +               * phylink_config.lpi_timer_default would do this, but there is
 +               * a chance that userspace could change the eee_timer setting
 +               * via sysfs before the first open. Thus, preserve existing
 +               * behaviour.
 +               */
 +              if (!phylink_ethtool_get_eee(priv->phylink, &eee)) {
 +                      eee.tx_lpi_timer = priv->tx_lpi_timer;
 +                      phylink_ethtool_set_eee(priv->phylink, &eee);
 +              }
 +      }
 +
        if (!priv->plat->pmt) {
                struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
  
@@@ -1241,7 -1202,6 +1241,7 @@@ static int stmmac_phy_setup(struct stmm
        struct stmmac_mdio_bus_data *mdio_bus_data;
        int mode = priv->plat->phy_interface;
        struct fwnode_handle *fwnode;
 +      struct phylink_pcs *pcs;
        struct phylink *phylink;
  
        priv->phylink_config.dev = &priv->dev->dev;
        /* Stmmac always requires an RX clock for hardware initialization */
        priv->phylink_config.mac_requires_rxc = true;
  
 +      if (!(priv->plat->flags & STMMAC_FLAG_RX_CLK_RUNS_IN_LPI))
 +              priv->phylink_config.eee_rx_clk_stop_enable = true;
 +
        mdio_bus_data = priv->plat->mdio_bus_data;
        if (mdio_bus_data)
                priv->phylink_config.default_an_inband =
  
        /* If we have an xpcs, it defines which PHY interfaces are supported. */
        if (priv->hw->xpcs)
 -              xpcs_get_interfaces(priv->hw->xpcs,
 -                                  priv->phylink_config.supported_interfaces);
 +              pcs = xpcs_to_phylink_pcs(priv->hw->xpcs);
 +      else
 +              pcs = priv->hw->phylink_pcs;
 +
 +      if (pcs)
 +              phy_interface_or(priv->phylink_config.supported_interfaces,
 +                               priv->phylink_config.supported_interfaces,
 +                               pcs->supported_interfaces);
 +
 +      if (priv->dma_cap.eee) {
 +              /* Assume all supported interfaces also support LPI */
 +              memcpy(priv->phylink_config.lpi_interfaces,
 +                     priv->phylink_config.supported_interfaces,
 +                     sizeof(priv->phylink_config.lpi_interfaces));
 +
 +              /* All full duplex speeds above 100Mbps are supported */
 +              priv->phylink_config.lpi_capabilities = ~(MAC_1000FD - 1) |
 +                                                      MAC_100FD;
 +              priv->phylink_config.lpi_timer_default = eee_timer * 1000;
 +              priv->phylink_config.eee_enabled_default = true;
 +      }
  
        fwnode = priv->plat->port_node;
        if (!fwnode)
@@@ -1369,14 -1307,6 +1369,14 @@@ static void stmmac_display_rings(struc
        stmmac_display_tx_rings(priv, dma_conf);
  }
  
 +static unsigned int stmmac_rx_offset(struct stmmac_priv *priv)
 +{
 +      if (stmmac_xdp_is_enabled(priv))
 +              return XDP_PACKET_HEADROOM;
 +
 +      return NET_SKB_PAD;
 +}
 +
  static int stmmac_set_bfsize(int mtu, int bufsize)
  {
        int ret = bufsize;
@@@ -2073,26 -2003,22 +2073,26 @@@ static int __alloc_dma_rx_desc_resource
        struct stmmac_channel *ch = &priv->channel[queue];
        bool xdp_prog = stmmac_xdp_is_enabled(priv);
        struct page_pool_params pp_params = { 0 };
 -      unsigned int num_pages;
 +      unsigned int dma_buf_sz_pad, num_pages;
        unsigned int napi_id;
        int ret;
  
 +      dma_buf_sz_pad = stmmac_rx_offset(priv) + dma_conf->dma_buf_sz +
 +                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 +      num_pages = DIV_ROUND_UP(dma_buf_sz_pad, PAGE_SIZE);
 +
        rx_q->queue_index = queue;
        rx_q->priv_data = priv;
 +      rx_q->napi_skb_frag_size = num_pages * PAGE_SIZE;
  
        pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
        pp_params.pool_size = dma_conf->dma_rx_size;
 -      num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE);
 -      pp_params.order = ilog2(num_pages);
 +      pp_params.order = order_base_2(num_pages);
        pp_params.nid = dev_to_node(priv->device);
        pp_params.dev = priv->device;
        pp_params.dma_dir = xdp_prog ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
        pp_params.offset = stmmac_rx_offset(priv);
 -      pp_params.max_len = STMMAC_MAX_RX_BUF_SIZE(num_pages);
 +      pp_params.max_len = dma_conf->dma_buf_sz;
  
        rx_q->page_pool = page_pool_create(&pp_params);
        if (IS_ERR(rx_q->page_pool)) {
@@@ -2831,8 -2757,11 +2831,8 @@@ static int stmmac_tx_clean(struct stmma
                        xmits = budget;
        }
  
 -      if (priv->eee_enabled && !priv->tx_path_in_lpi_mode &&
 -          priv->eee_sw_timer_en) {
 -              if (stmmac_enable_eee_mode(priv))
 -                      mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
 -      }
 +      if (priv->eee_sw_timer_en && !priv->tx_path_in_lpi_mode)
 +              stmmac_restart_sw_lpi_timer(priv);
  
        /* We still have pending packets, let's call for a new scheduling */
        if (tx_q->dirty_tx != tx_q->cur_tx)
@@@ -3507,6 -3436,12 +3507,6 @@@ static int stmmac_hw_setup(struct net_d
        else if (ptp_register)
                stmmac_ptp_register(priv);
  
 -      priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS;
 -
 -      /* Convert the timer from msec to usec */
 -      if (!priv->tx_lpi_timer)
 -              priv->tx_lpi_timer = eee_timer * 1000;
 -
        if (priv->use_riwt) {
                u32 queue;
  
@@@ -3973,10 -3908,6 +3973,10 @@@ static int __stmmac_open(struct net_dev
        u32 chan;
        int ret;
  
 +      /* Initialise the tx lpi timer, converting from msec to usec */
 +      if (!priv->tx_lpi_timer)
 +              priv->tx_lpi_timer = eee_timer * 1000;
 +
        ret = pm_runtime_resume_and_get(priv->device);
        if (ret < 0)
                return ret;
                }
        }
  
 -      priv->rx_copybreak = STMMAC_RX_COPYBREAK;
 -
        buf_sz = dma_conf->dma_buf_sz;
        for (int i = 0; i < MTL_MAX_TX_QUEUES; i++)
                if (priv->dma_conf.tx_queue[i].tbs & STMMAC_TBS_EN)
@@@ -4091,6 -4024,11 +4091,6 @@@ static int stmmac_release(struct net_de
        /* Free the IRQ lines */
        stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0);
  
 -      if (priv->eee_enabled) {
 -              priv->tx_path_in_lpi_mode = false;
 -              del_timer_sync(&priv->eee_ctrl_timer);
 -      }
 -
        /* Stop TX/RX DMA and clear the descriptors */
        stmmac_stop_all_dma(priv);
  
@@@ -4179,7 -4117,11 +4179,7 @@@ static void stmmac_tso_allocator(struc
                        desc = &tx_q->dma_tx[tx_q->cur_tx];
  
                curr_addr = des + (total_len - tmp_len);
 -              if (priv->dma_cap.addr64 <= 32)
 -                      desc->des0 = cpu_to_le32(curr_addr);
 -              else
 -                      stmmac_set_desc_addr(priv, desc, curr_addr);
 -
 +              stmmac_set_desc_addr(priv, desc, curr_addr);
                buff_size = tmp_len >= TSO_MAX_BUFF_SIZE ?
                            TSO_MAX_BUFF_SIZE : tmp_len;
  
@@@ -4225,27 -4167,17 +4225,27 @@@ static void stmmac_flush_tx_descriptors
   *  First Descriptor
   *   --------
   *   | DES0 |---> buffer1 = L2/L3/L4 header
 - *   | DES1 |---> TCP Payload (can continue on next descr...)
 - *   | DES2 |---> buffer 1 and 2 len
 + *   | DES1 |---> can be used as buffer2 for TCP Payload if the DMA AXI address
 + *   |      |     width is 32-bit, but we never use it.
 + *   |      |     Also can be used as the most-significant 8-bits or 16-bits of
 + *   |      |     buffer1 address pointer if the DMA AXI address width is 40-bit
 + *   |      |     or 48-bit, and we always use it.
 + *   | DES2 |---> buffer1 len
   *   | DES3 |---> must set TSE, TCP hdr len-> [22:19]. TCP payload len [17:0]
   *   --------
 + *   --------
 + *   | DES0 |---> buffer1 = TCP Payload (can continue on next descr...)
 + *   | DES1 |---> same as the First Descriptor
 + *   | DES2 |---> buffer1 len
 + *   | DES3 |
 + *   --------
   *    |
   *     ...
   *    |
   *   --------
 - *   | DES0 | --| Split TCP Payload on Buffers 1 and 2
 - *   | DES1 | --|
 - *   | DES2 | --> buffer 1 and 2 len
 + *   | DES0 |---> buffer1 = Split TCP Payload
 + *   | DES1 |---> same as the First Descriptor
 + *   | DES2 |---> buffer1 len
   *   | DES3 |
   *   --------
   *
@@@ -4255,14 -4187,15 +4255,14 @@@ static netdev_tx_t stmmac_tso_xmit(stru
  {
        struct dma_desc *desc, *first, *mss_desc = NULL;
        struct stmmac_priv *priv = netdev_priv(dev);
 -      int tmp_pay_len = 0, first_tx, nfrags;
        unsigned int first_entry, tx_packets;
        struct stmmac_txq_stats *txq_stats;
        struct stmmac_tx_queue *tx_q;
        u32 pay_len, mss, queue;
 -      dma_addr_t tso_des, des;
 +      int i, first_tx, nfrags;
        u8 proto_hdr_len, hdr;
 +      dma_addr_t des;
        bool set_ic;
 -      int i;
  
        /* Always insert VLAN tag to SKB payload for TSO frames.
         *
        if (dma_mapping_error(priv->device, des))
                goto dma_map_err;
  
 -      if (priv->dma_cap.addr64 <= 32) {
 -              first->des0 = cpu_to_le32(des);
 -
 -              /* Fill start of payload in buff2 of first descriptor */
 -              if (pay_len)
 -                      first->des1 = cpu_to_le32(des + proto_hdr_len);
 -
 -              /* If needed take extra descriptors to fill the remaining payload */
 -              tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
 -              tso_des = des;
 -      } else {
 -              stmmac_set_desc_addr(priv, first, des);
 -              tmp_pay_len = pay_len;
 -              tso_des = des + proto_hdr_len;
 -              pay_len = 0;
 -      }
 -
 -      stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), queue);
 +      stmmac_set_desc_addr(priv, first, des);
 +      stmmac_tso_allocator(priv, des + proto_hdr_len, pay_len,
 +                           (nfrags == 0), queue);
  
        /* In case two or more DMA transmit descriptors are allocated for this
         * non-paged SKB data, the DMA buffer address should be saved to
        }
  
        /* Complete the first descriptor before granting the DMA */
 -      stmmac_prepare_tso_tx_desc(priv, first, 1,
 -                      proto_hdr_len,
 -                      pay_len,
 -                      1, tx_q->tx_skbuff_dma[first_entry].last_segment,
 -                      hdr / 4, (skb->len - proto_hdr_len));
 +      stmmac_prepare_tso_tx_desc(priv, first, 1, proto_hdr_len, 0, 1,
 +                                 tx_q->tx_skbuff_dma[first_entry].last_segment,
 +                                 hdr / 4, (skb->len - proto_hdr_len));
  
        /* If context desc is used to change MSS */
        if (mss_desc) {
@@@ -4542,7 -4492,7 +4542,7 @@@ static netdev_tx_t stmmac_xmit(struct s
        first_tx = tx_q->cur_tx;
  
        if (priv->tx_path_in_lpi_mode && priv->eee_sw_timer_en)
 -              stmmac_disable_eee_mode(priv);
 +              stmmac_stop_sw_lpi(priv);
  
        /* Manage oversized TCP frames for GMAC4 device */
        if (skb_is_gso(skb) && priv->tso) {
@@@ -5523,7 -5473,7 +5523,7 @@@ read_again
                if (priv->extend_desc)
                        stmmac_rx_extended_status(priv, &priv->xstats, rx_q->dma_erx + entry);
                if (unlikely(status == discard_frame)) {
 -                      page_pool_recycle_direct(rx_q->page_pool, buf->page);
 +                      page_pool_put_page(rx_q->page_pool, buf->page, 0, true);
                        buf->page = NULL;
                        error = 1;
                        if (!priv->hwts_rx_en)
  
                /* Buffer is good. Go on. */
  
 -              prefetch(page_address(buf->page) + buf->page_offset);
 -              if (buf->sec_page)
 -                      prefetch(page_address(buf->sec_page));
 -
                buf1_len = stmmac_rx_buf1_len(priv, p, status, len);
                len += buf1_len;
                buf2_len = stmmac_rx_buf2_len(priv, p, status, len);
  
                        dma_sync_single_for_cpu(priv->device, buf->addr,
                                                buf1_len, dma_dir);
 +                      net_prefetch(page_address(buf->page) +
 +                                   buf->page_offset);
  
                        xdp_init_buff(&ctx.xdp, buf_sz, &rx_q->xdp_rxq);
                        xdp_prepare_buff(&ctx.xdp, page_address(buf->page),
                }
  
                if (!skb) {
 +                      unsigned int head_pad_len;
 +
                        /* XDP program may expand or reduce tail */
                        buf1_len = ctx.xdp.data_end - ctx.xdp.data;
  
 -                      skb = napi_alloc_skb(&ch->rx_napi, buf1_len);
 +                      skb = napi_build_skb(page_address(buf->page),
 +                                           rx_q->napi_skb_frag_size);
                        if (!skb) {
 +                              page_pool_recycle_direct(rx_q->page_pool,
 +                                                       buf->page);
                                rx_dropped++;
                                count++;
                                goto drain_data;
                        }
  
                        /* XDP program may adjust header */
 -                      skb_copy_to_linear_data(skb, ctx.xdp.data, buf1_len);
 +                      head_pad_len = ctx.xdp.data - ctx.xdp.data_hard_start;
 +                      skb_reserve(skb, head_pad_len);
                        skb_put(skb, buf1_len);
 -
 -                      /* Data payload copied into SKB, page ready for recycle */
 -                      page_pool_recycle_direct(rx_q->page_pool, buf->page);
 +                      skb_mark_for_recycle(skb);
                        buf->page = NULL;
                } else if (buf1_len) {
                        dma_sync_single_for_cpu(priv->device, buf->addr,
                        skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
                                        buf->page, buf->page_offset, buf1_len,
                                        priv->dma_conf.dma_buf_sz);
 -
 -                      /* Data payload appended into SKB */
 -                      skb_mark_for_recycle(skb);
                        buf->page = NULL;
                }
  
                        skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
                                        buf->sec_page, 0, buf2_len,
                                        priv->dma_conf.dma_buf_sz);
 -
 -                      /* Data payload appended into SKB */
 -                      skb_mark_for_recycle(skb);
                        buf->sec_page = NULL;
                }
  
@@@ -6535,11 -6489,7 +6535,7 @@@ static int stmmac_device_event(struct n
  
        switch (event) {
        case NETDEV_CHANGENAME:
-               if (priv->dbgfs_dir)
-                       priv->dbgfs_dir = debugfs_rename(stmmac_fs_dir,
-                                                        priv->dbgfs_dir,
-                                                        stmmac_fs_dir,
-                                                        dev->name);
+               debugfs_change_name(priv->dbgfs_dir, "%s", dev->name);
                break;
        }
  done:
@@@ -7453,8 -7403,6 +7449,8 @@@ int stmmac_dvr_probe(struct device *dev
  
        INIT_WORK(&priv->service_task, stmmac_service_task);
  
 +      timer_setup(&priv->eee_ctrl_timer, stmmac_eee_ctrl_timer, 0);
 +
        /* Override with kernel parameters if supplied XXX CRS XXX
         * this needs to have multiple instances
         */
@@@ -7762,7 -7710,7 +7758,7 @@@ int stmmac_suspend(struct device *dev
        for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
                hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer);
  
 -      if (priv->eee_enabled) {
 +      if (priv->eee_sw_timer_en) {
                priv->tx_path_in_lpi_mode = false;
                del_timer_sync(&priv->eee_ctrl_timer);
        }
index cd310b26b50c811dbfe3526cf8994d18f9926aa8,2caaf1c10ee6f86dedfdc250bdebb655fe1ffe46..4171f43cf01cc7ded1a7ac2ad71afee1030248ef
                                        reg = <0x100>;
                                };
                        };
+                       test-device@2 {
+                               compatible = "test,rust-device";
+                               reg = <0x2>;
+                       };
                };
 +
 +              platform-tests-2 {
 +                      // No #address-cells or #size-cells
 +                      node {
 +                              #address-cells = <1>;
 +                              #size-cells = <1>;
 +
 +                              test-device@100 {
 +                                      compatible = "test-sub-device";
 +                                      reg = <0x100 1>;
 +                              };
 +                      };
 +              };
        };
  };
diff --combined drivers/pwm/core.c
index 99d0bc693315238f19cfef2dcf9fb4e61748e490,14144d0fa38e0c4e0bc34b9c929e127f1b2e96b6..ccd54c089bab8b975f1fa480b9956f0df9ce7c14
@@@ -242,9 -242,6 +242,9 @@@ int pwm_round_waveform_might_sleep(stru
  
        BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
  
 +      if (!pwmchip_supports_waveform(chip))
 +              return -EOPNOTSUPP;
 +
        if (!pwm_wf_valid(wf))
                return -EINVAL;
  
@@@ -297,9 -294,6 +297,9 @@@ int pwm_get_waveform_might_sleep(struc
  
        BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
  
 +      if (!pwmchip_supports_waveform(chip) || !ops->read_waveform)
 +              return -EOPNOTSUPP;
 +
        guard(pwmchip)(chip);
  
        if (!chip->operational)
@@@ -326,9 -320,6 +326,9 @@@ static int __pwm_set_waveform(struct pw
  
        BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
  
 +      if (!pwmchip_supports_waveform(chip))
 +              return -EOPNOTSUPP;
 +
        if (!pwm_wf_valid(wf))
                return -EINVAL;
  
@@@ -601,7 -592,7 +601,7 @@@ static int __pwm_apply(struct pwm_devic
            state->usage_power == pwm->state.usage_power)
                return 0;
  
 -      if (ops->write_waveform) {
 +      if (pwmchip_supports_waveform(chip)) {
                struct pwm_waveform wf;
                char wfhw[WFHWSIZE];
  
@@@ -755,7 -746,7 +755,7 @@@ int pwm_get_state_hw(struct pwm_device 
        if (!chip->operational)
                return -ENODEV;
  
 -      if (ops->read_waveform) {
 +      if (pwmchip_supports_waveform(chip) && ops->read_waveform) {
                char wfhw[WFHWSIZE];
                struct pwm_waveform wf;
  
@@@ -1285,7 -1276,7 +1285,7 @@@ static int pwm_export_child(struct devi
        return 0;
  }
  
- static int pwm_unexport_match(struct device *pwm_dev, void *data)
+ static int pwm_unexport_match(struct device *pwm_dev, const void *data)
  {
        return pwm_from_dev(pwm_dev) == data;
  }
index 062ec5f247584eab1df040da3ea44d6889f70db4,133f36457b283a53b4dca29adf081f385a371368..6b0e6b4cd8af859199acc218ecf482b4e69b64b4
@@@ -160,7 -160,7 +160,7 @@@ static int qla4xxx_eh_abort(struct scsi
  static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd);
  static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd);
  static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd);
 -static int qla4xxx_slave_alloc(struct scsi_device *device);
 +static int qla4xxx_sdev_init(struct scsi_device *device);
  static umode_t qla4_attr_is_visible(int param_type, int param);
  static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type);
  
@@@ -234,7 -234,7 +234,7 @@@ static struct scsi_host_template qla4xx
        .eh_host_reset_handler  = qla4xxx_eh_host_reset,
        .eh_timed_out           = qla4xxx_eh_cmd_timed_out,
  
 -      .slave_alloc            = qla4xxx_slave_alloc,
 +      .sdev_init              = qla4xxx_sdev_init,
        .change_queue_depth     = scsi_change_queue_depth,
  
        .this_id                = -1,
@@@ -7189,7 -7189,8 +7189,8 @@@ exit_new_nt_list
   *    1: if flashnode entry is non-persistent
   *    0: if flashnode entry is persistent
   **/
- static int qla4xxx_sysfs_ddb_is_non_persistent(struct device *dev, void *data)
+ static int qla4xxx_sysfs_ddb_is_non_persistent(struct device *dev,
+                                              const void *data)
  {
        struct iscsi_bus_flash_session *fnode_sess;
  
@@@ -9052,7 -9053,7 +9053,7 @@@ static void qla4xxx_config_dma_addressi
        }
  }
  
 -static int qla4xxx_slave_alloc(struct scsi_device *sdev)
 +static int qla4xxx_sdev_init(struct scsi_device *sdev)
  {
        struct iscsi_cls_session *cls_sess;
        struct iscsi_session *sess;
@@@ -9846,7 -9847,7 +9847,7 @@@ static const struct pci_error_handlers 
        .resume = qla4xxx_pci_resume,
  };
  
 -static struct pci_device_id qla4xxx_pci_tbl[] = {
 +static const struct pci_device_id qla4xxx_pci_tbl[] = {
        {
                .vendor         = PCI_VENDOR_ID_QLOGIC,
                .device         = PCI_DEVICE_ID_QLOGIC_ISP4010,
index fec8ffb8d6535450de0fe4208fb8ec1a470b4f27,0d474de2d960a865c52c9e7253f173d70ddd8f16..9c347c64c315f8ff2e955e598321918da0b7826a
@@@ -1324,7 -1324,7 +1324,7 @@@ EXPORT_SYMBOL_GPL(iscsi_create_flashnod
   *  1 on success
   *  0 on failure
   */
- static int iscsi_is_flashnode_conn_dev(struct device *dev, void *data)
+ static int iscsi_is_flashnode_conn_dev(struct device *dev, const void *data)
  {
        return dev->bus == &iscsi_flashnode_bus;
  }
@@@ -1335,7 -1335,7 +1335,7 @@@ static int iscsi_destroy_flashnode_conn
        return 0;
  }
  
- static int flashnode_match_index(struct device *dev, void *data)
+ static int flashnode_match_index(struct device *dev, const void *data)
  {
        struct iscsi_bus_flash_session *fnode_sess = NULL;
        int ret = 0;
                goto exit_match_index;
  
        fnode_sess = iscsi_dev_to_flash_session(dev);
-       ret = (fnode_sess->target_id == *((int *)data)) ? 1 : 0;
+       ret = (fnode_sess->target_id == *((const int *)data)) ? 1 : 0;
  
  exit_match_index:
        return ret;
@@@ -1389,8 -1389,8 +1389,8 @@@ iscsi_get_flashnode_by_index(struct Scs
   *  %NULL on failure
   */
  struct device *
- iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
-                         int (*fn)(struct device *dev, void *data))
+ iscsi_find_flashnode_sess(struct Scsi_Host *shost, const void *data,
+                         device_match_t fn)
  {
        return device_find_child(&shost->shost_gendev, data, fn);
  }
@@@ -2122,6 -2122,33 +2122,6 @@@ destroy_wq
  }
  EXPORT_SYMBOL_GPL(iscsi_add_session);
  
 -/**
 - * iscsi_create_session - create iscsi class session
 - * @shost: scsi host
 - * @transport: iscsi transport
 - * @dd_size: private driver data size
 - * @target_id: which target
 - *
 - * This can be called from a LLD or iscsi_transport.
 - */
 -struct iscsi_cls_session *
 -iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
 -                   int dd_size, unsigned int target_id)
 -{
 -      struct iscsi_cls_session *session;
 -
 -      session = iscsi_alloc_session(shost, transport, dd_size);
 -      if (!session)
 -              return NULL;
 -
 -      if (iscsi_add_session(session, target_id)) {
 -              iscsi_free_session(session);
 -              return NULL;
 -      }
 -      return session;
 -}
 -EXPORT_SYMBOL_GPL(iscsi_create_session);
 -
  static void iscsi_conn_release(struct device *dev)
  {
        struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev);
@@@ -4077,7 -4104,7 +4077,7 @@@ iscsi_if_rx(struct sk_buff *skb
                }
                do {
                        /*
 -                       * special case for GET_STATS:
 +                       * special case for GET_STATS, GET_CHAP and GET_HOST_STATS:
                         * on success - sending reply and stats from
                         * inside of if_recv_msg(),
                         * on error - fall through.
                                break;
                        if (ev->type == ISCSI_UEVENT_GET_CHAP && !err)
                                break;
 +                      if (ev->type == ISCSI_UEVENT_GET_HOST_STATS && !err)
 +                              break;
                        err = iscsi_if_send_reply(portid, nlh->nlmsg_type,
                                                  ev, sizeof(*ev));
                        if (err == -EAGAIN && --retries < 0) {
index c472594c3a9f4215294c5b93546488f545f89004,8e0aa2c76d4037047a16f6c631eccaa066d8f230..92f7e752f86208b7d6b88358c3d28e150978dff9
@@@ -790,6 -790,7 +790,6 @@@ static int uart_get_info(struct tty_por
  {
        struct uart_state *state = container_of(port, struct uart_state, port);
        struct uart_port *uport;
 -      int ret = -ENODEV;
  
        /* Initialize structure in case we error out later to prevent any stack info leakage. */
        *retinfo = (struct serial_struct){};
         * Ensure the state we copy is consistent and no hardware changes
         * occur as we go
         */
 -      mutex_lock(&port->mutex);
 +      guard(mutex)(&port->mutex);
        uport = uart_port_check(state);
        if (!uport)
 -              goto out;
 +              return -ENODEV;
  
        retinfo->type       = uport->type;
        retinfo->line       = uport->line;
        retinfo->iomem_reg_shift = uport->regshift;
        retinfo->iomem_base      = (void *)(unsigned long)uport->mapbase;
  
 -      ret = 0;
 -out:
 -      mutex_unlock(&port->mutex);
 -      return ret;
 +      return 0;
  }
  
  static int uart_get_info_user(struct tty_struct *tty,
        return uart_get_info(port, ss) < 0 ? -EIO : 0;
  }
  
 +static int uart_change_port(struct uart_port *uport,
 +                          const struct serial_struct *new_info,
 +                          unsigned long new_port)
 +{
 +      unsigned long old_iobase, old_mapbase;
 +      unsigned int old_type, old_iotype, old_hub6, old_shift;
 +      int retval;
 +
 +      old_iobase = uport->iobase;
 +      old_mapbase = uport->mapbase;
 +      old_type = uport->type;
 +      old_hub6 = uport->hub6;
 +      old_iotype = uport->iotype;
 +      old_shift = uport->regshift;
 +
 +      if (old_type != PORT_UNKNOWN && uport->ops->release_port)
 +              uport->ops->release_port(uport);
 +
 +      uport->iobase = new_port;
 +      uport->type = new_info->type;
 +      uport->hub6 = new_info->hub6;
 +      uport->iotype = new_info->io_type;
 +      uport->regshift = new_info->iomem_reg_shift;
 +      uport->mapbase = (unsigned long)new_info->iomem_base;
 +
 +      if (uport->type == PORT_UNKNOWN || !uport->ops->request_port)
 +              return 0;
 +
 +      retval = uport->ops->request_port(uport);
 +      if (retval == 0)
 +              return 0; /* succeeded => done */
 +
 +      /*
 +       * If we fail to request resources for the new port, try to restore the
 +       * old settings.
 +       */
 +      uport->iobase = old_iobase;
 +      uport->type = old_type;
 +      uport->hub6 = old_hub6;
 +      uport->iotype = old_iotype;
 +      uport->regshift = old_shift;
 +      uport->mapbase = old_mapbase;
 +
 +      if (old_type == PORT_UNKNOWN)
 +              return retval;
 +
 +      retval = uport->ops->request_port(uport);
 +      /* If we failed to restore the old settings, we fail like this. */
 +      if (retval)
 +              uport->type = PORT_UNKNOWN;
 +
 +      /* We failed anyway. */
 +      return -EBUSY;
 +}
 +
  static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
                         struct uart_state *state,
                         struct serial_struct *new_info)
        unsigned int change_irq, change_port, closing_wait;
        unsigned int old_custom_divisor, close_delay;
        upf_t old_flags, new_flags;
 -      int retval = 0;
 +      int retval;
  
        if (!uport)
                return -EIO;
        if (!(uport->flags & UPF_FIXED_PORT)) {
                unsigned int uartclk = new_info->baud_base * 16;
                /* check needs to be done here before other settings made */
 -              if (uartclk == 0) {
 -                      retval = -EINVAL;
 -                      goto exit;
 -              }
 +              if (uartclk == 0)
 +                      return -EINVAL;
        }
        if (!capable(CAP_SYS_ADMIN)) {
 -              retval = -EPERM;
                if (change_irq || change_port ||
                    (new_info->baud_base != uport->uartclk / 16) ||
                    (close_delay != port->close_delay) ||
                    (new_info->xmit_fifo_size &&
                     new_info->xmit_fifo_size != uport->fifosize) ||
                    (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0))
 -                      goto exit;
 +                      return -EPERM;
                uport->flags = ((uport->flags & ~UPF_USR_MASK) |
                               (new_flags & UPF_USR_MASK));
                uport->custom_divisor = new_info->custom_divisor;
        if (change_irq || change_port) {
                retval = security_locked_down(LOCKDOWN_TIOCSSERIAL);
                if (retval)
 -                      goto exit;
 +                      return retval;
        }
  
 -      /*
 -       * Ask the low level driver to verify the settings.
 -       */
 -      if (uport->ops->verify_port)
 +       /* Ask the low level driver to verify the settings. */
 +      if (uport->ops->verify_port) {
                retval = uport->ops->verify_port(uport, new_info);
 +              if (retval)
 +                      return retval;
 +      }
  
        if ((new_info->irq >= irq_get_nr_irqs()) || (new_info->irq < 0) ||
            (new_info->baud_base < 9600))
 -              retval = -EINVAL;
 -
 -      if (retval)
 -              goto exit;
 +              return -EINVAL;
  
        if (change_port || change_irq) {
 -              retval = -EBUSY;
 -
 -              /*
 -               * Make sure that we are the sole user of this port.
 -               */
 +               /* Make sure that we are the sole user of this port. */
                if (tty_port_users(port) > 1)
 -                      goto exit;
 +                      return -EBUSY;
  
                /*
                 * We need to shutdown the serial port at the old
        }
  
        if (change_port) {
 -              unsigned long old_iobase, old_mapbase;
 -              unsigned int old_type, old_iotype, old_hub6, old_shift;
 -
 -              old_iobase = uport->iobase;
 -              old_mapbase = uport->mapbase;
 -              old_type = uport->type;
 -              old_hub6 = uport->hub6;
 -              old_iotype = uport->iotype;
 -              old_shift = uport->regshift;
 -
 -              /*
 -               * Free and release old regions
 -               */
 -              if (old_type != PORT_UNKNOWN && uport->ops->release_port)
 -                      uport->ops->release_port(uport);
 -
 -              uport->iobase = new_port;
 -              uport->type = new_info->type;
 -              uport->hub6 = new_info->hub6;
 -              uport->iotype = new_info->io_type;
 -              uport->regshift = new_info->iomem_reg_shift;
 -              uport->mapbase = (unsigned long)new_info->iomem_base;
 -
 -              /*
 -               * Claim and map the new regions
 -               */
 -              if (uport->type != PORT_UNKNOWN && uport->ops->request_port) {
 -                      retval = uport->ops->request_port(uport);
 -              } else {
 -                      /* Always success - Jean II */
 -                      retval = 0;
 -              }
 -
 -              /*
 -               * If we fail to request resources for the
 -               * new port, try to restore the old settings.
 -               */
 -              if (retval) {
 -                      uport->iobase = old_iobase;
 -                      uport->type = old_type;
 -                      uport->hub6 = old_hub6;
 -                      uport->iotype = old_iotype;
 -                      uport->regshift = old_shift;
 -                      uport->mapbase = old_mapbase;
 -
 -                      if (old_type != PORT_UNKNOWN) {
 -                              retval = uport->ops->request_port(uport);
 -                              /*
 -                               * If we failed to restore the old settings,
 -                               * we fail like this.
 -                               */
 -                              if (retval)
 -                                      uport->type = PORT_UNKNOWN;
 -
 -                              /*
 -                               * We failed anyway.
 -                               */
 -                              retval = -EBUSY;
 -                      }
 -
 -                      /* Added to return the correct error -Ram Gupta */
 -                      goto exit;
 -              }
 +              retval = uart_change_port(uport, new_info, new_port);
 +              if (retval)
 +                      return retval;
        }
  
        if (change_irq)
                uport->fifosize = new_info->xmit_fifo_size;
  
   check_and_exit:
 -      retval = 0;
        if (uport->type == PORT_UNKNOWN)
 -              goto exit;
 +              return 0;
 +
        if (tty_port_initialized(port)) {
                if (((old_flags ^ uport->flags) & UPF_SPD_MASK) ||
                    old_custom_divisor != uport->custom_divisor) {
                        }
                        uart_change_line_settings(tty, state, NULL);
                }
 -      } else {
 -              retval = uart_startup(tty, state, true);
 -              if (retval == 0)
 -                      tty_port_set_initialized(port, true);
 -              if (retval > 0)
 -                      retval = 0;
 +
 +              return 0;
        }
 - exit:
 -      return retval;
 +
 +      retval = uart_startup(tty, state, true);
 +      if (retval < 0)
 +              return retval;
 +      if (retval == 0)
 +              tty_port_set_initialized(port, true);
 +
 +      return 0;
  }
  
  static int uart_set_info_user(struct tty_struct *tty, struct serial_struct *ss)
@@@ -2349,9 -2365,9 +2349,9 @@@ struct uart_match 
        struct uart_driver *driver;
  };
  
- static int serial_match_port(struct device *dev, void *data)
+ static int serial_match_port(struct device *dev, const void *data)
  {
-       struct uart_match *match = data;
+       const struct uart_match *match = data;
        struct tty_driver *tty_drv = match->driver->tty_driver;
        dev_t devt = MKDEV(tty_drv->major, tty_drv->minor_start) +
                match->port->line;
@@@ -3045,25 -3061,26 +3045,25 @@@ static ssize_t console_store(struct dev
        if (ret)
                return ret;
  
 -      mutex_lock(&port->mutex);
 +      guard(mutex)(&port->mutex);
        uport = uart_port_check(state);
 -      if (uport) {
 -              oldconsole = uart_console_registered(uport);
 -              if (oldconsole && !newconsole) {
 -                      ret = unregister_console(uport->cons);
 -              } else if (!oldconsole && newconsole) {
 -                      if (uart_console(uport)) {
 -                              uport->console_reinit = 1;
 -                              register_console(uport->cons);
 -                      } else {
 -                              ret = -ENOENT;
 -                      }
 -              }
 -      } else {
 -              ret = -ENXIO;
 +      if (!uport)
 +              return -ENXIO;
 +
 +      oldconsole = uart_console_registered(uport);
 +      if (oldconsole && !newconsole) {
 +              ret = unregister_console(uport->cons);
 +              if (ret < 0)
 +                      return ret;
 +      } else if (!oldconsole && newconsole) {
 +              if (!uart_console(uport))
 +                      return -ENOENT;
 +
 +              uport->console_reinit = 1;
 +              register_console(uport->cons);
        }
 -      mutex_unlock(&port->mutex);
  
 -      return ret < 0 ? ret : count;
 +      return count;
  }
  
  static DEVICE_ATTR_RO(uartclk);
@@@ -3119,6 -3136,7 +3119,6 @@@ static int serial_core_add_one_port(str
  {
        struct uart_state *state;
        struct tty_port *port;
 -      int ret = 0;
        struct device *tty_dev;
        int num_groups;
  
        state = drv->state + uport->line;
        port = &state->port;
  
 -      mutex_lock(&port->mutex);
 -      if (state->uart_port) {
 -              ret = -EINVAL;
 -              goto out;
 -      }
 +      guard(mutex)(&port->mutex);
 +      if (state->uart_port)
 +              return -EINVAL;
  
        /* Link the port to the driver state table and vice versa */
        atomic_set(&state->refcount, 1);
        uport->minor = drv->tty_driver->minor_start + uport->line;
        uport->name = kasprintf(GFP_KERNEL, "%s%d", drv->dev_name,
                                drv->tty_driver->name_base + uport->line);
 -      if (!uport->name) {
 -              ret = -ENOMEM;
 -              goto out;
 -      }
 +      if (!uport->name)
 +              return -ENOMEM;
  
        if (uport->cons && uport->dev)
                of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
  
        uport->tty_groups = kcalloc(num_groups, sizeof(*uport->tty_groups),
                                    GFP_KERNEL);
 -      if (!uport->tty_groups) {
 -              ret = -ENOMEM;
 -              goto out;
 -      }
 +      if (!uport->tty_groups)
 +              return -ENOMEM;
 +
        uport->tty_groups[0] = &tty_dev_attr_group;
        if (uport->attr_group)
                uport->tty_groups[1] = uport->attr_group;
                       uport->line);
        }
  
 - out:
 -      mutex_unlock(&port->mutex);
 -
 -      return ret;
 +      return 0;
  }
  
  /**
@@@ -3358,7 -3384,7 +3358,7 @@@ int serial_core_register_port(struct ua
        struct serial_ctrl_device *ctrl_dev, *new_ctrl_dev = NULL;
        int ret;
  
 -      mutex_lock(&port_mutex);
 +      guard(mutex)(&port_mutex);
  
        /*
         * Prevent serial_port_runtime_resume() from trying to use the port
        ctrl_dev = serial_core_ctrl_find(drv, port->dev, port->ctrl_id);
        if (!ctrl_dev) {
                new_ctrl_dev = serial_core_ctrl_device_add(port);
 -              if (IS_ERR(new_ctrl_dev)) {
 -                      ret = PTR_ERR(new_ctrl_dev);
 -                      goto err_unlock;
 -              }
 +              if (IS_ERR(new_ctrl_dev))
 +                      return PTR_ERR(new_ctrl_dev);
                ctrl_dev = new_ctrl_dev;
        }
  
        if (ret)
                goto err_unregister_port_dev;
  
 -      mutex_unlock(&port_mutex);
 -
        return 0;
  
  err_unregister_port_dev:
  err_unregister_ctrl_dev:
        serial_base_ctrl_device_remove(new_ctrl_dev);
  
 -err_unlock:
 -      mutex_unlock(&port_mutex);
 -
        return ret;
  }
  
index 9bd74c505872dd05bf1237f96d1dde878f76b59b,deeac2c8f58974c27edff65eb2975c01ba1501ac..c003049bafbfb532c6d8d8b9364b3e242afb0e17
@@@ -7,7 -7,6 +7,7 @@@
   * Author: Chunfeng Yun <[email protected]>
   */
  
 +#include <linux/string_choices.h>
  #include <linux/uaccess.h>
  
  #include "mtu3.h"
@@@ -257,16 -256,7 +257,7 @@@ static const struct mtu3_file_map mtu3_
  
  static int mtu3_ep_open(struct inode *inode, struct file *file)
  {
-       const char *file_name = file_dentry(file)->d_iname;
-       const struct mtu3_file_map *f_map;
-       int i;
-       for (i = 0; i < ARRAY_SIZE(mtu3_ep_files); i++) {
-               f_map = &mtu3_ep_files[i];
-               if (strcmp(f_map->name, file_name) == 0)
-                       break;
-       }
+       const struct mtu3_file_map *f_map = debugfs_get_aux(file);
  
        return single_open(file, f_map->show, inode->i_private);
  }
@@@ -289,17 -279,8 +280,8 @@@ static const struct debugfs_reg32 mtu3_
  
  static int mtu3_probe_show(struct seq_file *sf, void *unused)
  {
-       const char *file_name = file_dentry(sf->file)->d_iname;
        struct mtu3 *mtu = sf->private;
-       const struct debugfs_reg32 *regs;
-       int i;
-       for (i = 0; i < ARRAY_SIZE(mtu3_prb_regs); i++) {
-               regs = &mtu3_prb_regs[i];
-               if (strcmp(regs->name, file_name) == 0)
-                       break;
-       }
+       const struct debugfs_reg32 *regs = debugfs_get_aux(sf->file);
  
        seq_printf(sf, "0x%04x - 0x%08x\n", (u32)regs->offset,
                   mtu3_readl(mtu->ippc_base, (u32)regs->offset));
@@@ -315,13 -296,11 +297,11 @@@ static int mtu3_probe_open(struct inod
  static ssize_t mtu3_probe_write(struct file *file, const char __user *ubuf,
                                size_t count, loff_t *ppos)
  {
-       const char *file_name = file_dentry(file)->d_iname;
        struct seq_file *sf = file->private_data;
        struct mtu3 *mtu = sf->private;
-       const struct debugfs_reg32 *regs;
+       const struct debugfs_reg32 *regs = debugfs_get_aux(file);
        char buf[32];
        u32 val;
-       int i;
  
        if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
                return -EFAULT;
        if (kstrtou32(buf, 0, &val))
                return -EINVAL;
  
-       for (i = 0; i < ARRAY_SIZE(mtu3_prb_regs); i++) {
-               regs = &mtu3_prb_regs[i];
-               if (strcmp(regs->name, file_name) == 0)
-                       break;
-       }
        mtu3_writel(mtu->ippc_base, (u32)regs->offset, val);
  
        return count;
@@@ -359,8 -332,8 +333,8 @@@ static void mtu3_debugfs_create_prb_fil
  
        for (i = 0; i < ARRAY_SIZE(mtu3_prb_regs); i++) {
                regs = &mtu3_prb_regs[i];
-               debugfs_create_file(regs->name, 0644, dir_prb,
-                                   mtu, &mtu3_probe_fops);
+               debugfs_create_file_aux(regs->name, 0644, dir_prb,
+                                   mtu, regs, &mtu3_probe_fops);
        }
  
        mtu3_debugfs_regset(mtu, mtu->ippc_base, mtu3_prb_regs,
@@@ -380,8 -353,8 +354,8 @@@ static void mtu3_debugfs_create_ep_dir(
        for (i = 0; i < ARRAY_SIZE(mtu3_ep_files); i++) {
                files = &mtu3_ep_files[i];
  
-               debugfs_create_file(files->name, 0444, dir_ep,
-                                   mep, &mtu3_ep_fops);
+               debugfs_create_file_aux(files->name, 0444, dir_ep,
+                                   mep, files, &mtu3_ep_fops);
        }
  }
  
@@@ -480,7 -453,7 +454,7 @@@ static int ssusb_vbus_show(struct seq_f
        struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
  
        seq_printf(sf, "vbus state: %s\n(echo on/off)\n",
 -                 regulator_is_enabled(otg_sx->vbus) ? "on" : "off");
 +                 str_on_off(regulator_is_enabled(otg_sx->vbus)));
  
        return 0;
  }
index a137e105cc553355ef8981847ef957aa4cc00208,3a4e0bd0131774afd0d746d2f0a306190219feec..9c76c3d0c6cff9c9b94ef35fb0cb4be0e395aad6
@@@ -10,7 -10,6 +10,7 @@@
  #include <linux/mutex.h>
  #include <linux/property.h>
  #include <linux/slab.h>
 +#include <linux/string_choices.h>
  #include <linux/usb/pd_vdo.h>
  #include <linux/usb/typec_mux.h>
  #include <linux/usb/typec_retimer.h>
@@@ -230,21 -229,21 +230,21 @@@ static const char * const usb_modes[] 
  /* ------------------------------------------------------------------------- */
  /* Alternate Modes */
  
- static int altmode_match(struct device *dev, void *data)
+ static int altmode_match(struct device *dev, const void *data)
  {
        struct typec_altmode *adev = to_typec_altmode(dev);
-       struct typec_device_id *id = data;
+       const struct typec_device_id *id = data;
  
        if (!is_typec_altmode(dev))
                return 0;
  
 -      return ((adev->svid == id->svid) && (adev->mode == id->mode));
 +      return (adev->svid == id->svid);
  }
  
  static void typec_altmode_set_partner(struct altmode *altmode)
  {
        struct typec_altmode *adev = &altmode->adev;
 -      struct typec_device_id id = { adev->svid, adev->mode, };
 +      struct typec_device_id id = { adev->svid };
        struct typec_port *port = typec_altmode2port(adev);
        struct altmode *partner;
        struct device *dev;
@@@ -362,7 -361,7 +362,7 @@@ active_show(struct device *dev, struct 
  {
        struct typec_altmode *alt = to_typec_altmode(dev);
  
 -      return sprintf(buf, "%s\n", alt->active ? "yes" : "no");
 +      return sprintf(buf, "%s\n", str_yes_no(alt->active));
  }
  
  static ssize_t active_store(struct device *dev, struct device_attribute *attr,
@@@ -459,8 -458,7 +459,8 @@@ static umode_t typec_altmode_attr_is_vi
        struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj));
  
        if (attr == &dev_attr_active.attr)
 -              if (!adev->ops || !adev->ops->activate)
 +              if (!is_typec_port(adev->dev.parent) &&
 +                  (!adev->ops || !adev->ops->activate))
                        return 0444;
  
        return attr->mode;
@@@ -565,7 -563,7 +565,7 @@@ typec_register_altmode(struct device *p
  
        if (is_port) {
                alt->attrs[3] = &dev_attr_supported_roles.attr;
 -              alt->adev.active = true; /* Enabled by default */
 +              alt->adev.active = !desc->inactive; /* Enabled by default */
        }
  
        sprintf(alt->group_name, "mode%d", desc->mode);
@@@ -708,7 -706,7 +708,7 @@@ static ssize_t supports_usb_power_deliv
  {
        struct typec_partner *p = to_typec_partner(dev);
  
 -      return sprintf(buf, "%s\n", p->usb_pd ? "yes" : "no");
 +      return sprintf(buf, "%s\n", str_yes_no(p->usb_pd));
  }
  static DEVICE_ATTR_RO(supports_usb_power_delivery);
  
@@@ -1284,11 -1282,6 +1284,6 @@@ const struct device_type typec_cable_de
        .release = typec_cable_release,
  };
  
- static int cable_match(struct device *dev, void *data)
- {
-       return is_typec_cable(dev);
- }
  /**
   * typec_cable_get - Get a reference to the USB Type-C cable
   * @port: The USB Type-C Port the cable is connected to
@@@ -1300,7 -1293,8 +1295,8 @@@ struct typec_cable *typec_cable_get(str
  {
        struct device *dev;
  
-       dev = device_find_child(&port->dev, NULL, cable_match);
+       dev = device_find_child(&port->dev, &typec_cable_dev_type,
+                               device_match_type);
        if (!dev)
                return NULL;
  
@@@ -1860,7 -1854,7 +1856,7 @@@ static ssize_t vconn_source_show(struc
        struct typec_port *port = to_typec_port(dev);
  
        return sprintf(buf, "%s\n",
 -                     port->vconn_role == TYPEC_SOURCE ? "yes" : "no");
 +                     str_yes_no(port->vconn_role == TYPEC_SOURCE));
  }
  static DEVICE_ATTR_RW(vconn_source);
  
@@@ -2030,16 -2024,12 +2026,12 @@@ const struct device_type typec_port_dev
  /* --------------------------------------- */
  /* Driver callbacks to report role updates */
  
- static int partner_match(struct device *dev, void *data)
- {
-       return is_typec_partner(dev);
- }
  static struct typec_partner *typec_get_partner(struct typec_port *port)
  {
        struct device *dev;
  
-       dev = device_find_child(&port->dev, NULL, partner_match);
+       dev = device_find_child(&port->dev, &typec_partner_dev_type,
+                               device_match_type);
        if (!dev)
                return NULL;
  
@@@ -2172,7 -2162,9 +2164,9 @@@ void typec_set_pwr_opmode(struct typec_
        sysfs_notify(&port->dev.kobj, NULL, "power_operation_mode");
        kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
  
-       partner_dev = device_find_child(&port->dev, NULL, partner_match);
+       partner_dev = device_find_child(&port->dev,
+                                       &typec_partner_dev_type,
+                                       device_match_type);
        if (partner_dev) {
                struct typec_partner *partner = to_typec_partner(partner_dev);
  
@@@ -2336,7 -2328,9 +2330,9 @@@ int typec_get_negotiated_svdm_version(s
        enum usb_pd_svdm_ver svdm_version;
        struct device *partner_dev;
  
-       partner_dev = device_find_child(&port->dev, NULL, partner_match);
+       partner_dev = device_find_child(&port->dev,
+                                       &typec_partner_dev_type,
+                                       device_match_type);
        if (!partner_dev)
                return -ENODEV;
  
@@@ -2363,7 -2357,8 +2359,8 @@@ int typec_get_cable_svdm_version(struc
        enum usb_pd_svdm_ver svdm_version;
        struct device *cable_dev;
  
-       cable_dev = device_find_child(&port->dev, NULL, cable_match);
+       cable_dev = device_find_child(&port->dev, &typec_cable_dev_type,
+                                     device_match_type);
        if (!cable_dev)
                return -ENODEV;
  
index b18658bce2c3819fc1cbeb38fb98391d56ec3317,3d3517da41a141aeadc8f219a44fd360cfd931ff..f5a56efd2bd6a78bd58e2fd2996cacc624d4b14f
@@@ -48,7 -48,6 +48,7 @@@ struct fwnode_handle
   *            will never get called until they do.
   * @remove:   Called when a device removed from this bus.
   * @shutdown: Called at shut-down time to quiesce the device.
 + * @irq_get_affinity: Get IRQ affinity mask for the device on this bus.
   *
   * @online:   Called to put the device back online (after offlining it).
   * @offline:  Called to put the device offline for hot-removal. May fail.
@@@ -88,8 -87,6 +88,8 @@@ struct bus_type 
        void (*sync_state)(struct device *dev);
        void (*remove)(struct device *dev);
        void (*shutdown)(struct device *dev);
 +      const struct cpumask *(*irq_get_affinity)(struct device *dev,
 +                      unsigned int irq_vec);
  
        int (*online)(struct device *dev);
        int (*offline)(struct device *dev);
@@@ -134,6 -131,7 +134,7 @@@ typedef int (*device_match_t)(struct de
  
  /* Generic device matching functions that all busses can use to match with */
  int device_match_name(struct device *dev, const void *name);
+ int device_match_type(struct device *dev, const void *type);
  int device_match_of_node(struct device *dev, const void *np);
  int device_match_fwnode(struct device *dev, const void *fwnode);
  int device_match_devt(struct device *dev, const void *pdevt);
@@@ -141,9 -139,12 +142,12 @@@ int device_match_acpi_dev(struct devic
  int device_match_acpi_handle(struct device *dev, const void *handle);
  int device_match_any(struct device *dev, const void *unused);
  
+ /* Device iterating function type for various driver core for_each APIs */
+ typedef int (*device_iter_t)(struct device *dev, void *data);
  /* iterator helpers for buses */
- int bus_for_each_dev(const struct bus_type *bus, struct device *start, void *data,
-                    int (*fn)(struct device *dev, void *data));
+ int bus_for_each_dev(const struct bus_type *bus, struct device *start,
+                    void *data, device_iter_t fn);
  struct device *bus_find_device(const struct bus_type *bus, struct device *start,
                               const void *data, device_match_t match);
  /**
index 5474494a1e99d958f5d6d5805a8641c9b7361a9b,4d3baf324900f4b2b1ff3a5724b7ca7d122dc468..76de2b662f4fbb350c76b410a4d309a058b0088e
@@@ -447,6 -447,10 +447,6 @@@ extern int iscsi_add_session(struct isc
                             unsigned int target_id);
  extern int iscsi_session_event(struct iscsi_cls_session *session,
                               enum iscsi_uevent_e event);
 -extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
 -                                              struct iscsi_transport *t,
 -                                              int dd_size,
 -                                              unsigned int target_id);
  extern void iscsi_force_destroy_session(struct iscsi_cls_session *session);
  extern void iscsi_remove_session(struct iscsi_cls_session *session);
  extern void iscsi_free_session(struct iscsi_cls_session *session);
@@@ -493,8 -497,8 +493,8 @@@ extern void iscsi_destroy_all_flashnode
  extern int iscsi_flashnode_bus_match(struct device *dev,
                                     const struct device_driver *drv);
  extern struct device *
- iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
-                         int (*fn)(struct device *dev, void *data));
+ iscsi_find_flashnode_sess(struct Scsi_Host *shost, const void *data,
+                         device_match_t fn);
  extern struct device *
  iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess);
  
diff --combined kernel/bpf/btf.c
index 8396ce1d0fba3014fe5af3419502cfde74782466,76de36d2552002d1e25c826d701340d9cde07ba1..9de6acddd479b4f5e32a5e6ba43cf369de4cee29
@@@ -498,6 -498,11 +498,6 @@@ bool btf_type_is_void(const struct btf_
        return t == &btf_void;
  }
  
 -static bool btf_type_is_fwd(const struct btf_type *t)
 -{
 -      return BTF_INFO_KIND(t->info) == BTF_KIND_FWD;
 -}
 -
  static bool btf_type_is_datasec(const struct btf_type *t)
  {
        return BTF_INFO_KIND(t->info) == BTF_KIND_DATASEC;
@@@ -7882,9 -7887,14 +7882,9 @@@ struct btf *btf_get_by_fd(int fd
        struct btf *btf;
        CLASS(fd, f)(fd);
  
 -      if (fd_empty(f))
 -              return ERR_PTR(-EBADF);
 -
 -      if (fd_file(f)->f_op != &btf_fops)
 -              return ERR_PTR(-EINVAL);
 -
 -      btf = fd_file(f)->private_data;
 -      refcount_inc(&btf->refcnt);
 +      btf = __btf_get_by_fd(f);
 +      if (!IS_ERR(btf))
 +              refcount_inc(&btf->refcnt);
  
        return btf;
  }
@@@ -8001,17 -8011,6 +8001,6 @@@ struct btf_module 
  static LIST_HEAD(btf_modules);
  static DEFINE_MUTEX(btf_module_mutex);
  
- static ssize_t
- btf_module_read(struct file *file, struct kobject *kobj,
-               struct bin_attribute *bin_attr,
-               char *buf, loff_t off, size_t len)
- {
-       const struct btf *btf = bin_attr->private;
-       memcpy(buf, btf->data + off, len);
-       return len;
- }
  static void purge_cand_cache(struct btf *btf);
  
  static int btf_module_notify(struct notifier_block *nb, unsigned long op,
                        attr->attr.name = btf->name;
                        attr->attr.mode = 0444;
                        attr->size = btf->data_size;
-                       attr->private = btf;
-                       attr->read = btf_module_read;
+                       attr->private = btf->data;
+                       attr->read_new = sysfs_bin_attr_simple_read;
  
                        err = sysfs_create_bin_file(btf_kobj, attr);
                        if (err) {
diff --combined kernel/module/sysfs.c
index f99616499e2e054c9c6f62ecc51d4b2c06a5b7eb,254017b58b645d4afcf6876d29bcc2e2113a8dc4..b401ff4b02d2904d3b5fca93e10e188ddcbaf787
   * J. Corbet <[email protected]>
   */
  #ifdef CONFIG_KALLSYMS
 -struct module_sect_attr {
 -      struct bin_attribute battr;
 -      unsigned long address;
 -};
 -
  struct module_sect_attrs {
        struct attribute_group grp;
 -      unsigned int nsections;
 -      struct module_sect_attr attrs[];
 +      struct bin_attribute attrs[];
  };
  
  #define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4))
  static ssize_t module_sect_read(struct file *file, struct kobject *kobj,
 -                              struct bin_attribute *battr,
 +                              const struct bin_attribute *battr,
                                char *buf, loff_t pos, size_t count)
  {
 -      struct module_sect_attr *sattr =
 -              container_of(battr, struct module_sect_attr, battr);
        char bounce[MODULE_SECT_READ_SIZE + 1];
        size_t wrote;
  
@@@ -45,7 -53,7 +45,7 @@@
         */
        wrote = scnprintf(bounce, sizeof(bounce), "0x%px\n",
                          kallsyms_show_value(file->f_cred)
 -                              ? (void *)sattr->address : NULL);
 +                              ? battr->private : NULL);
        count = min(count, wrote);
        memcpy(buf, bounce, count);
  
  
  static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
  {
 -      unsigned int section;
 +      const struct bin_attribute *const *bin_attr;
  
 -      for (section = 0; section < sect_attrs->nsections; section++)
 -              kfree(sect_attrs->attrs[section].battr.attr.name);
 +      for (bin_attr = sect_attrs->grp.bin_attrs_new; *bin_attr; bin_attr++)
 +              kfree((*bin_attr)->attr.name);
 +      kfree(sect_attrs->grp.bin_attrs_new);
        kfree(sect_attrs);
  }
  
  static int add_sect_attrs(struct module *mod, const struct load_info *info)
  {
 -      unsigned int nloaded = 0, i, size[2];
        struct module_sect_attrs *sect_attrs;
 -      struct module_sect_attr *sattr;
 -      struct bin_attribute **gattr;
 +      const struct bin_attribute **gattr;
 +      struct bin_attribute *sattr;
 +      unsigned int nloaded = 0, i;
        int ret;
  
        /* Count loaded sections and allocate structures */
        for (i = 0; i < info->hdr->e_shnum; i++)
                if (!sect_empty(&info->sechdrs[i]))
                        nloaded++;
 -      size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
 -                      sizeof(sect_attrs->grp.bin_attrs[0]));
 -      size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
 -      sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
 +      sect_attrs = kzalloc(struct_size(sect_attrs, attrs, nloaded), GFP_KERNEL);
        if (!sect_attrs)
                return -ENOMEM;
  
 +      gattr = kcalloc(nloaded + 1, sizeof(*gattr), GFP_KERNEL);
 +      if (!gattr) {
 +              kfree(sect_attrs);
 +              return -ENOMEM;
 +      }
 +
        /* Setup section attributes. */
        sect_attrs->grp.name = "sections";
 -      sect_attrs->grp.bin_attrs = (void *)sect_attrs + size[0];
 +      sect_attrs->grp.bin_attrs_new = gattr;
  
 -      sect_attrs->nsections = 0;
        sattr = &sect_attrs->attrs[0];
 -      gattr = &sect_attrs->grp.bin_attrs[0];
        for (i = 0; i < info->hdr->e_shnum; i++) {
                Elf_Shdr *sec = &info->sechdrs[i];
  
                if (sect_empty(sec))
                        continue;
 -              sysfs_bin_attr_init(&sattr->battr);
 -              sattr->address = sec->sh_addr;
 -              sattr->battr.attr.name =
 +              sysfs_bin_attr_init(sattr);
 +              sattr->attr.name =
                        kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
 -              if (!sattr->battr.attr.name) {
 +              if (!sattr->attr.name) {
                        ret = -ENOMEM;
                        goto out;
                }
 -              sect_attrs->nsections++;
 -              sattr->battr.read = module_sect_read;
 -              sattr->battr.size = MODULE_SECT_READ_SIZE;
 -              sattr->battr.attr.mode = 0400;
 -              *(gattr++) = &(sattr++)->battr;
 +              sattr->read_new = module_sect_read;
 +              sattr->private = (void *)sec->sh_addr;
 +              sattr->size = MODULE_SECT_READ_SIZE;
 +              sattr->attr.mode = 0400;
 +              *(gattr++) = sattr++;
        }
 -      *gattr = NULL;
  
        ret = sysfs_create_group(&mod->mkobj.kobj, &sect_attrs->grp);
        if (ret)
@@@ -138,13 -146,20 +138,13 @@@ static void remove_sect_attrs(struct mo
   */
  
  struct module_notes_attrs {
 -      struct kobject *dir;
 -      unsigned int notes;
 -      struct bin_attribute attrs[] __counted_by(notes);
 +      struct attribute_group grp;
 +      struct bin_attribute attrs[];
  };
  
 -static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
 -                           unsigned int i)
 +static void free_notes_attrs(struct module_notes_attrs *notes_attrs)
  {
 -      if (notes_attrs->dir) {
 -              while (i-- > 0)
 -                      sysfs_remove_bin_file(notes_attrs->dir,
 -                                            &notes_attrs->attrs[i]);
 -              kobject_put(notes_attrs->dir);
 -      }
 +      kfree(notes_attrs->grp.bin_attrs_new);
        kfree(notes_attrs);
  }
  
@@@ -152,7 -167,6 +152,7 @@@ static int add_notes_attrs(struct modul
  {
        unsigned int notes, loaded, i;
        struct module_notes_attrs *notes_attrs;
 +      const struct bin_attribute **gattr;
        struct bin_attribute *nattr;
        int ret;
  
        if (!notes_attrs)
                return -ENOMEM;
  
 -      notes_attrs->notes = notes;
 +      gattr = kcalloc(notes + 1, sizeof(*gattr), GFP_KERNEL);
 +      if (!gattr) {
 +              kfree(notes_attrs);
 +              return -ENOMEM;
 +      }
 +
 +      notes_attrs->grp.name = "notes";
 +      notes_attrs->grp.bin_attrs_new = gattr;
 +
        nattr = &notes_attrs->attrs[0];
        for (loaded = i = 0; i < info->hdr->e_shnum; ++i) {
                if (sect_empty(&info->sechdrs[i]))
                        continue;
                if (info->sechdrs[i].sh_type == SHT_NOTE) {
                        sysfs_bin_attr_init(nattr);
 -                      nattr->attr.name = mod->sect_attrs->attrs[loaded].battr.attr.name;
 +                      nattr->attr.name = mod->sect_attrs->attrs[loaded].attr.name;
                        nattr->attr.mode = 0444;
                        nattr->size = info->sechdrs[i].sh_size;
                        nattr->private = (void *)info->sechdrs[i].sh_addr;
-                       nattr->read = sysfs_bin_attr_simple_read;
+                       nattr->read_new = sysfs_bin_attr_simple_read;
 -                      ++nattr;
 +                      *(gattr++) = nattr++;
                }
                ++loaded;
        }
  
 -      notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj);
 -      if (!notes_attrs->dir) {
 -              ret = -ENOMEM;
 +      ret = sysfs_create_group(&mod->mkobj.kobj, &notes_attrs->grp);
 +      if (ret)
                goto out;
 -      }
 -
 -      for (i = 0; i < notes; ++i) {
 -              ret = sysfs_create_bin_file(notes_attrs->dir, &notes_attrs->attrs[i]);
 -              if (ret)
 -                      goto out;
 -      }
  
        mod->notes_attrs = notes_attrs;
        return 0;
  
  out:
 -      free_notes_attrs(notes_attrs, i);
 +      free_notes_attrs(notes_attrs);
        return ret;
  }
  
  static void remove_notes_attrs(struct module *mod)
  {
 -      if (mod->notes_attrs)
 -              free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes);
 +      if (mod->notes_attrs) {
 +              sysfs_remove_group(&mod->mkobj.kobj,
 +                                 &mod->notes_attrs->grp);
 +              /*
 +               * We are positive that no one is using any notes attrs
 +               * at this point.  Deallocate immediately.
 +               */
 +              free_notes_attrs(mod->notes_attrs);
 +              mod->notes_attrs = NULL;
 +      }
  }
  
  #else /* !CONFIG_KALLSYMS */
@@@ -269,7 -275,7 +269,7 @@@ static int add_usage_links(struct modul
  
  static void module_remove_modinfo_attrs(struct module *mod, int end)
  {
 -      struct module_attribute *attr;
 +      const struct module_attribute *attr;
        int i;
  
        for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) {
  
  static int module_add_modinfo_attrs(struct module *mod)
  {
 -      struct module_attribute *attr;
 +      const struct module_attribute *attr;
        struct module_attribute *temp_attr;
        int error = 0;
        int i;
diff --combined mm/slub.c
index 996691c137eba12e71584eb03a8993cfbd4fc0b3,4f006b04755281c66e890cafcf3ac58a686a3120..1f50129dcfb3cd1fc76ac9398fa7718cedb42385
+++ b/mm/slub.c
@@@ -2311,7 -2311,7 +2311,7 @@@ bool slab_free_hook(struct kmem_cache *
                         * We have to do this manually because the rcu_head is
                         * not located inside the object.
                         */
 -                      kasan_record_aux_stack_noalloc(x);
 +                      kasan_record_aux_stack(x);
  
                        delayed_free->object = x;
                        call_rcu(&delayed_free->head, slab_free_after_rcu_debug);
@@@ -2420,15 -2420,17 +2420,15 @@@ static inline struct slab *alloc_slab_p
        unsigned int order = oo_order(oo);
  
        if (node == NUMA_NO_NODE)
 -              folio = (struct folio *)alloc_pages(flags, order);
 +              folio = (struct folio *)alloc_frozen_pages(flags, order);
        else
 -              folio = (struct folio *)__alloc_pages_node(node, flags, order);
 +              folio = (struct folio *)__alloc_frozen_pages(flags, order, node, NULL);
  
        if (!folio)
                return NULL;
  
        slab = folio_slab(folio);
        __folio_set_slab(folio);
 -      /* Make the flag visible before any changes to folio->mapping */
 -      smp_wmb();
        if (folio_is_pfmemalloc(folio))
                slab_set_pfmemalloc(slab);
  
@@@ -2649,10 -2651,12 +2649,10 @@@ static void __free_slab(struct kmem_cac
  
        __slab_clear_pfmemalloc(slab);
        folio->mapping = NULL;
 -      /* Make the mapping reset visible before clearing the flag */
 -      smp_wmb();
        __folio_clear_slab(folio);
        mm_account_reclaimed_pages(pages);
        unaccount_slab(slab, order, s);
 -      __free_pages(&folio->page, order);
 +      free_frozen_pages(&folio->page, order);
  }
  
  static void rcu_free_slab(struct rcu_head *h)
@@@ -7509,10 -7513,7 +7509,7 @@@ static int slab_debug_trace_open(struc
                return -ENOMEM;
        }
  
-       if (strcmp(filep->f_path.dentry->d_name.name, "alloc_traces") == 0)
-               alloc = TRACK_ALLOC;
-       else
-               alloc = TRACK_FREE;
+       alloc = debugfs_get_aux_num(filep);
  
        if (!alloc_loc_track(t, PAGE_SIZE / sizeof(struct location), GFP_KERNEL)) {
                bitmap_free(obj_map);
@@@ -7568,11 -7569,11 +7565,11 @@@ static void debugfs_slab_add(struct kme
  
        slab_cache_dir = debugfs_create_dir(s->name, slab_debugfs_root);
  
-       debugfs_create_file("alloc_traces", 0400,
-               slab_cache_dir, s, &slab_debugfs_fops);
+       debugfs_create_file_aux_num("alloc_traces", 0400, slab_cache_dir, s,
+                                       TRACK_ALLOC, &slab_debugfs_fops);
  
-       debugfs_create_file("free_traces", 0400,
-               slab_cache_dir, s, &slab_debugfs_fops);
+       debugfs_create_file_aux_num("free_traces", 0400, slab_cache_dir, s,
+                                       TRACK_FREE, &slab_debugfs_fops);
  }
  
  void debugfs_slab_release(struct kmem_cache *s)
index e7687a7b16835ab851af4ed7fc255d17ebc25e32,9fa38c489edcce963cc8b98b13a21cbf42033432..54c479910d054be014affaea27197003d6cf01c0
@@@ -727,7 -727,7 +727,7 @@@ static ssize_t ieee80211_if_parse_activ
  {
        u16 active_links;
  
 -      if (kstrtou16(buf, 0, &active_links))
 +      if (kstrtou16(buf, 0, &active_links) || !active_links)
                return -EINVAL;
  
        return ieee80211_set_active_links(&sdata->vif, active_links) ?: buflen;
@@@ -1025,16 -1025,7 +1025,7 @@@ void ieee80211_debugfs_remove_netdev(st
  
  void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
  {
-       struct dentry *dir;
-       char buf[10 + IFNAMSIZ];
-       dir = sdata->vif.debugfs_dir;
-       if (IS_ERR_OR_NULL(dir))
-               return;
-       sprintf(buf, "netdev:%s", sdata->name);
-       debugfs_rename(dir->d_parent, dir, dir->d_parent, buf);
+       debugfs_change_name(sdata->vif.debugfs_dir, "netdev:%s", sdata->name);
  }
  
  void ieee80211_debugfs_recreate_netdev(struct ieee80211_sub_if_data *sdata,
diff --combined net/wireless/core.c
index 70857018f020aefd478e1cb0142f57c6828c501a,9130cb872ed3469f79bdd9c8d4c7da41bf42c15c..12b780de8779ce656a2ce78ae9d3886ab2924fbd
@@@ -143,10 -143,7 +143,7 @@@ int cfg80211_dev_rename(struct cfg80211
        if (result)
                return result;
  
-       if (!IS_ERR_OR_NULL(rdev->wiphy.debugfsdir))
-               debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
-                              rdev->wiphy.debugfsdir,
-                              rdev->wiphy.debugfsdir->d_parent, newname);
+       debugfs_change_name(rdev->wiphy.debugfsdir, "%s", newname);
  
        nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
  
@@@ -191,8 -188,7 +188,8 @@@ int cfg80211_switch_netns(struct cfg802
                return err;
        }
  
 -      wiphy_lock(&rdev->wiphy);
 +      guard(wiphy)(&rdev->wiphy);
 +
        list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
                if (!wdev->netdev)
                        continue;
                        continue;
                nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
        }
 -      wiphy_unlock(&rdev->wiphy);
  
        return 0;
  }
@@@ -221,9 -218,9 +218,9 @@@ static void cfg80211_rfkill_poll(struc
  {
        struct cfg80211_registered_device *rdev = data;
  
 -      wiphy_lock(&rdev->wiphy);
 +      guard(wiphy)(&rdev->wiphy);
 +
        rdev_rfkill_poll(rdev);
 -      wiphy_unlock(&rdev->wiphy);
  }
  
  void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
@@@ -283,7 -280,7 +280,7 @@@ void cfg80211_shutdown_all_interfaces(s
  
                /* otherwise, check iftype */
  
 -              wiphy_lock(wiphy);
 +              guard(wiphy)(wiphy);
  
                switch (wdev->iftype) {
                case NL80211_IFTYPE_P2P_DEVICE:
                default:
                        break;
                }
 -
 -              wiphy_unlock(wiphy);
        }
  }
  EXPORT_SYMBOL_GPL(cfg80211_shutdown_all_interfaces);
@@@ -329,9 -328,9 +326,9 @@@ static void cfg80211_event_work(struct 
        rdev = container_of(work, struct cfg80211_registered_device,
                            event_work);
  
 -      wiphy_lock(&rdev->wiphy);
 +      guard(wiphy)(&rdev->wiphy);
 +
        cfg80211_process_rdev_events(rdev);
 -      wiphy_unlock(&rdev->wiphy);
  }
  
  void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
                        if (wdev->netdev)
                                dev_close(wdev->netdev);
  
 -                      wiphy_lock(&rdev->wiphy);
 +                      guard(wiphy)(&rdev->wiphy);
 +
                        cfg80211_leave(rdev, wdev);
                        cfg80211_remove_virtual_intf(rdev, wdev);
 -                      wiphy_unlock(&rdev->wiphy);
                }
        }
  }
@@@ -421,9 -420,9 +418,9 @@@ static void cfg80211_wiphy_work(struct 
  
        trace_wiphy_work_worker_start(&rdev->wiphy);
  
 -      wiphy_lock(&rdev->wiphy);
 +      guard(wiphy)(&rdev->wiphy);
        if (rdev->suspended)
 -              goto out;
 +              return;
  
        spin_lock_irq(&rdev->wiphy_work_lock);
        wk = list_first_entry_or_null(&rdev->wiphy_work_list,
        } else {
                spin_unlock_irq(&rdev->wiphy_work_lock);
        }
 -out:
 -      wiphy_unlock(&rdev->wiphy);
  }
  
  /* exported functions */
@@@ -1522,9 -1523,9 +1519,9 @@@ static int cfg80211_netdev_notifier_cal
                break;
        case NETDEV_REGISTER:
                if (!wdev->registered) {
 -                      wiphy_lock(&rdev->wiphy);
 +                      guard(wiphy)(&rdev->wiphy);
 +
                        cfg80211_register_wdev(rdev, wdev);
 -                      wiphy_unlock(&rdev->wiphy);
                }
                break;
        case NETDEV_UNREGISTER:
                 * so check wdev->registered.
                 */
                if (wdev->registered && !wdev->registering) {
 -                      wiphy_lock(&rdev->wiphy);
 +                      guard(wiphy)(&rdev->wiphy);
 +
                        _cfg80211_unregister_wdev(wdev, false);
 -                      wiphy_unlock(&rdev->wiphy);
                }
                break;
        case NETDEV_GOING_DOWN:
 -              wiphy_lock(&rdev->wiphy);
 -              cfg80211_leave(rdev, wdev);
 -              cfg80211_remove_links(wdev);
 -              wiphy_unlock(&rdev->wiphy);
 +              scoped_guard(wiphy, &rdev->wiphy) {
 +                      cfg80211_leave(rdev, wdev);
 +                      cfg80211_remove_links(wdev);
 +              }
                /* since we just did cfg80211_leave() nothing to do there */
                cancel_work_sync(&wdev->disconnect_wk);
                cancel_work_sync(&wdev->pmsr_free_wk);
diff --combined rust/kernel/device.rs
index d5e6a19ff6b7ba3b5be2ce512525c4573f94fb88,e7a2024b88d5547fea7f3c6f1d23de5896505b31..db2d9658ba47d9c492bc813ce3eb2ff29703ca31
@@@ -6,6 -6,7 +6,7 @@@
  
  use crate::{
      bindings,
+     str::CStr,
      types::{ARef, Opaque},
  };
  use core::{fmt, ptr};
@@@ -173,13 -174,19 +174,19 @@@ impl Device 
          #[cfg(CONFIG_PRINTK)]
          unsafe {
              bindings::_dev_printk(
 -                klevel as *const _ as *const core::ffi::c_char,
 +                klevel as *const _ as *const crate::ffi::c_char,
                  self.as_raw(),
                  c_str!("%pA").as_char_ptr(),
 -                &msg as *const _ as *const core::ffi::c_void,
 +                &msg as *const _ as *const crate::ffi::c_void,
              )
          };
      }
+     /// Checks if property is present or not.
+     pub fn property_present(&self, name: &CStr) -> bool {
+         // SAFETY: By the invariant of `CStr`, `name` is null-terminated.
+         unsafe { bindings::device_property_present(self.as_raw().cast_const(), name.as_char_ptr()) }
+     }
  }
  
  // SAFETY: Instances of `Device` are always reference-counted.
diff --combined rust/kernel/lib.rs
index 545d1170ee6358e185b48ce10493fc61c646155c,b11fa08de3c0f41d2e6ae18d91c41149287aa024..496ed32b0911a9fdbce5d26738b9cf7ef910b269
  
  #![no_std]
  #![feature(arbitrary_self_types)]
 -#![feature(coerce_unsized)]
 -#![feature(dispatch_from_dyn)]
 +#![cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, feature(derive_coerce_pointee))]
 +#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(coerce_unsized))]
 +#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(dispatch_from_dyn))]
 +#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(unsize))]
  #![feature(inline_const)]
  #![feature(lint_reasons)]
 -#![feature(unsize)]
+ // Stable in Rust 1.83
+ #![feature(const_maybe_uninit_as_mut_ptr)]
+ #![feature(const_mut_refs)]
+ #![feature(const_ptr_write)]
+ #![feature(const_refs_to_cell)]
  
  // Ensure conditional compilation based on the kernel configuration works;
  // otherwise we may silently break things like initcall handling.
@@@ -33,15 -37,18 +38,19 @@@ pub use ffi
  pub mod alloc;
  #[cfg(CONFIG_BLOCK)]
  pub mod block;
 -mod build_assert;
 +#[doc(hidden)]
 +pub mod build_assert;
  pub mod cred;
  pub mod device;
+ pub mod device_id;
+ pub mod devres;
+ pub mod driver;
  pub mod error;
  #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)]
  pub mod firmware;
  pub mod fs;
  pub mod init;
+ pub mod io;
  pub mod ioctl;
  pub mod jump_label;
  #[cfg(CONFIG_KUNIT)]
@@@ -50,11 -57,16 +59,16 @@@ pub mod list
  pub mod miscdevice;
  #[cfg(CONFIG_NET)]
  pub mod net;
+ pub mod of;
  pub mod page;
+ #[cfg(CONFIG_PCI)]
+ pub mod pci;
  pub mod pid_namespace;
+ pub mod platform;
  pub mod prelude;
  pub mod print;
  pub mod rbtree;
+ pub mod revocable;
  pub mod security;
  pub mod seq_file;
  pub mod sizes;
@@@ -76,6 -88,9 +90,6 @@@ pub use bindings
  pub use macros;
  pub use uapi;
  
 -#[doc(hidden)]
 -pub use build_error::build_error;
 -
  /// Prefix to appear before log messages printed from within the `kernel` crate.
  const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
  
@@@ -115,6 -130,12 +129,12 @@@ impl<T: Module> InPlaceModule for T 
      }
  }
  
+ /// Metadata attached to a [`Module`] or [`InPlaceModule`].
+ pub trait ModuleMetadata {
+     /// The name of the module as specified in the `module!` macro.
+     const NAME: &'static crate::str::CStr;
+ }
  /// Equivalent to `THIS_MODULE` in the C API.
  ///
  /// C header: [`include/linux/init.h`](srctree/include/linux/init.h)
index b3a6cc50b240e9373a7d4e9959fabb42235a794f,dfb363630c70b7187cae91f692d38bcf42d56a0a..e14433b2ab9d8fa391474b2ad7e3ed55c64b4d91
  
  use crate::{
      bindings,
+     device::Device,
      error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR},
 +    ffi::{c_int, c_long, c_uint, c_ulong},
+     fs::File,
      prelude::*,
+     seq_file::SeqFile,
      str::CStr,
      types::{ForeignOwnable, Opaque},
  };
 -use core::{
 -    ffi::{c_int, c_long, c_uint, c_ulong},
 -    marker::PhantomData,
 -    mem::MaybeUninit,
 -    pin::Pin,
 -};
 +use core::{marker::PhantomData, mem::MaybeUninit, pin::Pin};
  
  /// Options for creating a misc device.
  #[derive(Copy, Clone)]
@@@ -80,6 -87,16 +83,16 @@@ impl<T: MiscDevice> MiscDeviceRegistrat
      pub fn as_raw(&self) -> *mut bindings::miscdevice {
          self.inner.get()
      }
+     /// Access the `this_device` field.
+     pub fn device(&self) -> &Device {
+         // SAFETY: This can only be called after a successful register(), which always
+         // initialises `this_device` with a valid device. Furthermore, the signature of this
+         // function tells the borrow-checker that the `&Device` reference must not outlive the
+         // `&MiscDeviceRegistration<T>` used to obtain it, so the last use of the reference must be
+         // before the underlying `struct miscdevice` is destroyed.
+         unsafe { Device::as_ref((*self.as_raw()).this_device) }
+     }
  }
  
  #[pinned_drop]
@@@ -92,17 -109,17 +105,17 @@@ impl<T> PinnedDrop for MiscDeviceRegist
  
  /// Trait implemented by the private data of an open misc device.
  #[vtable]
- pub trait MiscDevice {
+ pub trait MiscDevice: Sized {
      /// What kind of pointer should `Self` be wrapped in.
      type Ptr: ForeignOwnable + Send + Sync;
  
      /// Called when the misc device is opened.
      ///
      /// The returned pointer will be stored as the private data for the file.
-     fn open() -> Result<Self::Ptr>;
+     fn open(_file: &File, _misc: &MiscDeviceRegistration<Self>) -> Result<Self::Ptr>;
  
      /// Called when the misc device is released.
-     fn release(device: Self::Ptr) {
+     fn release(device: Self::Ptr, _file: &File) {
          drop(device);
      }
  
      /// [`kernel::ioctl`]: mod@crate::ioctl
      fn ioctl(
          _device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>,
+         _file: &File,
          _cmd: u32,
          _arg: usize,
      ) -> Result<isize> {
 -        kernel::build_error!(VTABLE_DEFAULT_ERROR)
 +        build_error!(VTABLE_DEFAULT_ERROR)
      }
  
      /// Handler for ioctls.
      #[cfg(CONFIG_COMPAT)]
      fn compat_ioctl(
          _device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>,
+         _file: &File,
          _cmd: u32,
          _arg: usize,
      ) -> Result<isize> {
 -        kernel::build_error!(VTABLE_DEFAULT_ERROR)
 +        build_error!(VTABLE_DEFAULT_ERROR)
      }
 -        kernel::build_error!(VTABLE_DEFAULT_ERROR)
+     /// Show info for this fd.
+     fn show_fdinfo(
+         _device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>,
+         _m: &SeqFile,
+         _file: &File,
+     ) {
++        build_error!(VTABLE_DEFAULT_ERROR)
+     }
  }
  
  const fn create_vtable<T: MiscDevice>() -> &'static bindings::file_operations {
              } else {
                  None
              },
+             show_fdinfo: maybe_fn(T::HAS_SHOW_FDINFO, fops_show_fdinfo::<T>),
              // SAFETY: All zeros is a valid value for `bindings::file_operations`.
              ..unsafe { MaybeUninit::zeroed().assume_init() }
          };
  /// The file must be associated with a `MiscDeviceRegistration<T>`.
  unsafe extern "C" fn fops_open<T: MiscDevice>(
      inode: *mut bindings::inode,
-     file: *mut bindings::file,
+     raw_file: *mut bindings::file,
  ) -> c_int {
      // SAFETY: The pointers are valid and for a file being opened.
-     let ret = unsafe { bindings::generic_file_open(inode, file) };
+     let ret = unsafe { bindings::generic_file_open(inode, raw_file) };
      if ret != 0 {
          return ret;
      }
  
-     let ptr = match T::open() {
+     // SAFETY: The open call of a file can access the private data.
+     let misc_ptr = unsafe { (*raw_file).private_data };
+     // SAFETY: This is a miscdevice, so `misc_open()` set the private data to a pointer to the
+     // associated `struct miscdevice` before calling into this method. Furthermore, `misc_open()`
+     // ensures that the miscdevice can't be unregistered and freed during this call to `fops_open`.
+     let misc = unsafe { &*misc_ptr.cast::<MiscDeviceRegistration<T>>() };
+     // SAFETY:
+     // * This underlying file is valid for (much longer than) the duration of `T::open`.
+     // * There is no active fdget_pos region on the file on this thread.
+     let file = unsafe { File::from_raw_file(raw_file) };
+     let ptr = match T::open(file, misc) {
          Ok(ptr) => ptr,
          Err(err) => return err.to_errno(),
      };
  
-     // SAFETY: The open call of a file owns the private data.
-     unsafe { (*file).private_data = ptr.into_foreign() };
+     // This overwrites the private data with the value specified by the user, changing the type of
+     // this file's private data. All future accesses to the private data is performed by other
+     // fops_* methods in this file, which all correctly cast the private data to the new type.
+     //
+     // SAFETY: The open call of a file can access the private data.
 -    unsafe { (*raw_file).private_data = ptr.into_foreign().cast_mut() };
++    unsafe { (*raw_file).private_data = ptr.into_foreign() };
  
      0
  }
@@@ -207,7 -253,10 +249,10 @@@ unsafe extern "C" fn fops_release<T: Mi
      // SAFETY: The release call of a file owns the private data.
      let ptr = unsafe { <T::Ptr as ForeignOwnable>::from_foreign(private) };
  
-     T::release(ptr);
+     // SAFETY:
+     // * The file is valid for the duration of this call.
+     // * There is no active fdget_pos region on the file on this thread.
+     T::release(ptr, unsafe { File::from_raw_file(file) });
  
      0
  }
@@@ -225,7 -274,12 +270,12 @@@ unsafe extern "C" fn fops_ioctl<T: Misc
      // SAFETY: Ioctl calls can borrow the private data of the file.
      let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) };
  
-     match T::ioctl(device, cmd, arg) {
+     // SAFETY:
+     // * The file is valid for the duration of this call.
+     // * There is no active fdget_pos region on the file on this thread.
+     let file = unsafe { File::from_raw_file(file) };
 -    match T::ioctl(device, file, cmd, arg as usize) {
++    match T::ioctl(device, file, cmd, arg) {
          Ok(ret) => ret as c_long,
          Err(err) => err.to_errno() as c_long,
      }
@@@ -245,8 -299,36 +295,36 @@@ unsafe extern "C" fn fops_compat_ioctl<
      // SAFETY: Ioctl calls can borrow the private data of the file.
      let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) };
  
-     match T::compat_ioctl(device, cmd, arg) {
+     // SAFETY:
+     // * The file is valid for the duration of this call.
+     // * There is no active fdget_pos region on the file on this thread.
+     let file = unsafe { File::from_raw_file(file) };
 -    match T::compat_ioctl(device, file, cmd, arg as usize) {
++    match T::compat_ioctl(device, file, cmd, arg) {
          Ok(ret) => ret as c_long,
          Err(err) => err.to_errno() as c_long,
      }
  }
+ /// # Safety
+ ///
+ /// - `file` must be a valid file that is associated with a `MiscDeviceRegistration<T>`.
+ /// - `seq_file` must be a valid `struct seq_file` that we can write to.
+ unsafe extern "C" fn fops_show_fdinfo<T: MiscDevice>(
+     seq_file: *mut bindings::seq_file,
+     file: *mut bindings::file,
+ ) {
+     // SAFETY: The release call of a file owns the private data.
+     let private = unsafe { (*file).private_data };
+     // SAFETY: Ioctl calls can borrow the private data of the file.
+     let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) };
+     // SAFETY:
+     // * The file is valid for the duration of this call.
+     // * There is no active fdget_pos region on the file on this thread.
+     let file = unsafe { File::from_raw_file(file) };
+     // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
+     // this method is called.
+     let m = unsafe { SeqFile::from_raw(seq_file) };
+     T::show_fdinfo(device, m, file);
+ }
diff --combined rust/kernel/sync.rs
index dffdaad972cebf460cc1d400480b910c401ea219,0654008198b2bec4a3b7a0b6010544ec7e282997..3498fb344dc9338184c04a05183b1d0e14d4543b
@@@ -12,12 -12,13 +12,13 @@@ mod condvar
  pub mod lock;
  mod locked_by;
  pub mod poll;
+ pub mod rcu;
  
  pub use arc::{Arc, ArcBorrow, UniqueArc};
  pub use condvar::{new_condvar, CondVar, CondVarTimeoutResult};
  pub use lock::global::{global_lock, GlobalGuard, GlobalLock, GlobalLockBackend, GlobalLockedBy};
 -pub use lock::mutex::{new_mutex, Mutex};
 -pub use lock::spinlock::{new_spinlock, SpinLock};
 +pub use lock::mutex::{new_mutex, Mutex, MutexGuard};
 +pub use lock::spinlock::{new_spinlock, SpinLock, SpinLockGuard};
  pub use locked_by::LockedBy;
  
  /// Represents a lockdep class. It's a wrapper around C's `lock_class_key`.
diff --combined rust/kernel/types.rs
index 0dfaf45a755c7ce702027918e5fd3e97c407fda4,3aea6af9a0bca70ee42b4bad2fe31a99750cbf11..2bbaab83b9d65da667a07e85b3c89c7fa881b53c
@@@ -19,34 -19,35 +19,34 @@@ use core::
  /// This trait is meant to be used in cases when Rust objects are stored in C objects and
  /// eventually "freed" back to Rust.
  pub trait ForeignOwnable: Sized {
 -    /// Type of values borrowed between calls to [`ForeignOwnable::into_foreign`] and
 -    /// [`ForeignOwnable::from_foreign`].
 +    /// Type used to immutably borrow a value that is currently foreign-owned.
      type Borrowed<'a>;
  
 +    /// Type used to mutably borrow a value that is currently foreign-owned.
 +    type BorrowedMut<'a>;
 +
      /// Converts a Rust-owned object to a foreign-owned one.
      ///
      /// The foreign representation is a pointer to void. There are no guarantees for this pointer.
      /// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in
 -    /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`],
 -    /// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior.
 -    fn into_foreign(self) -> *const crate::ffi::c_void;
 -
 -    /// Borrows a foreign-owned object.
 -    ///
 -    /// # Safety
 +    /// any way except for [`from_foreign`], [`try_from_foreign`], [`borrow`], or [`borrow_mut`] can
 +    /// result in undefined behavior.
      ///
 -    /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
 -    /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
 -    unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Self::Borrowed<'a>;
 +    /// [`from_foreign`]: Self::from_foreign
 +    /// [`try_from_foreign`]: Self::try_from_foreign
 +    /// [`borrow`]: Self::borrow
 +    /// [`borrow_mut`]: Self::borrow_mut
 +    fn into_foreign(self) -> *mut crate::ffi::c_void;
  
      /// Converts a foreign-owned object back to a Rust-owned one.
      ///
      /// # Safety
      ///
 -    /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
 -    /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
 -    /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for
 -    /// this object must have been dropped.
 -    unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self;
 +    /// The provided pointer must have been returned by a previous call to [`into_foreign`], and it
 +    /// must not be passed to `from_foreign` more than once.
 +    ///
 +    /// [`into_foreign`]: Self::into_foreign
 +    unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self;
  
      /// Tries to convert a foreign-owned object back to a Rust-owned one.
      ///
      ///
      /// # Safety
      ///
 -    /// `ptr` must either be null or satisfy the safety requirements for
 -    /// [`ForeignOwnable::from_foreign`].
 -    unsafe fn try_from_foreign(ptr: *const crate::ffi::c_void) -> Option<Self> {
 +    /// `ptr` must either be null or satisfy the safety requirements for [`from_foreign`].
 +    ///
 +    /// [`from_foreign`]: Self::from_foreign
 +    unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> {
          if ptr.is_null() {
              None
          } else {
              unsafe { Some(Self::from_foreign(ptr)) }
          }
      }
 +
 +    /// Borrows a foreign-owned object immutably.
 +    ///
 +    /// This method provides a way to access a foreign-owned value from Rust immutably. It provides
 +    /// you with exactly the same abilities as an `&Self` when the value is Rust-owned.
 +    ///
 +    /// # Safety
 +    ///
 +    /// The provided pointer must have been returned by a previous call to [`into_foreign`], and if
 +    /// the pointer is ever passed to [`from_foreign`], then that call must happen after the end of
 +    /// the lifetime 'a.
 +    ///
 +    /// [`into_foreign`]: Self::into_foreign
 +    /// [`from_foreign`]: Self::from_foreign
 +    unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>;
 +
 +    /// Borrows a foreign-owned object mutably.
 +    ///
 +    /// This method provides a way to access a foreign-owned value from Rust mutably. It provides
 +    /// you with exactly the same abilities as an `&mut Self` when the value is Rust-owned, except
 +    /// that the address of the object must not be changed.
 +    ///
 +    /// Note that for types like [`Arc`], an `&mut Arc<T>` only gives you immutable access to the
 +    /// inner value, so this method also only provides immutable access in that case.
 +    ///
 +    /// In the case of `Box<T>`, this method gives you the ability to modify the inner `T`, but it
 +    /// does not let you change the box itself. That is, you cannot change which allocation the box
 +    /// points at.
 +    ///
 +    /// # Safety
 +    ///
 +    /// The provided pointer must have been returned by a previous call to [`into_foreign`], and if
 +    /// the pointer is ever passed to [`from_foreign`], then that call must happen after the end of
 +    /// the lifetime 'a.
 +    ///
 +    /// The lifetime 'a must not overlap with the lifetime of any other call to [`borrow`] or
 +    /// `borrow_mut` on the same object.
 +    ///
 +    /// [`into_foreign`]: Self::into_foreign
 +    /// [`from_foreign`]: Self::from_foreign
 +    /// [`borrow`]: Self::borrow
 +    /// [`Arc`]: crate::sync::Arc
 +    unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a>;
  }
  
  impl ForeignOwnable for () {
      type Borrowed<'a> = ();
 +    type BorrowedMut<'a> = ();
  
 -    fn into_foreign(self) -> *const crate::ffi::c_void {
 +    fn into_foreign(self) -> *mut crate::ffi::c_void {
          core::ptr::NonNull::dangling().as_ptr()
      }
  
 -    unsafe fn borrow<'a>(_: *const crate::ffi::c_void) -> Self::Borrowed<'a> {}
 +    unsafe fn from_foreign(_: *mut crate::ffi::c_void) -> Self {}
  
 -    unsafe fn from_foreign(_: *const crate::ffi::c_void) -> Self {}
 +    unsafe fn borrow<'a>(_: *mut crate::ffi::c_void) -> Self::Borrowed<'a> {}
 +    unsafe fn borrow_mut<'a>(_: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a> {}
  }
  
  /// Runs a cleanup function/closure when dropped.
@@@ -326,6 -281,17 +326,17 @@@ impl<T> Opaque<T> 
          }
      }
  
+     /// Create an opaque pin-initializer from the given pin-initializer.
+     pub fn pin_init(slot: impl PinInit<T>) -> impl PinInit<Self> {
+         Self::ffi_init(|ptr: *mut T| {
+             // SAFETY:
+             //   - `ptr` is a valid pointer to uninitialized memory,
+             //   - `slot` is not accessed on error; the call is infallible,
+             //   - `slot` is pinned in memory.
+             let _ = unsafe { init::PinInit::<T>::__pinned_init(slot, ptr) };
+         })
+     }
      /// Creates a pin-initializer from the given initializer closure.
      ///
      /// The returned initializer calls the given closure with the pointer to the inner `T` of this
@@@ -479,7 -445,7 +490,7 @@@ impl<T: AlwaysRefCounted> ARef<T> 
      /// }
      ///
      /// let mut data = Empty {};
 -    /// let ptr = NonNull::<Empty>::new(&mut data as *mut _).unwrap();
 +    /// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
      /// # // SAFETY: TODO.
      /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
      /// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
This page took 0.387805 seconds and 4 git commands to generate.