Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 5 Jun 2022 16:25:12 +0000 (09:25 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 5 Jun 2022 16:25:12 +0000 (09:25 -0700)
Pull more SCSI updates from James Bottomley:
 "Mostly small bug fixes plus other trivial updates.

  The major change of note is moving ufs out of scsi and a minor update
  to lpfc vmid handling"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (24 commits)
  scsi: qla2xxx: Remove unused 'ql_dm_tgt_ex_pct' parameter
  scsi: qla2xxx: Remove setting of 'req' and 'rsp' parameters
  scsi: mpi3mr: Fix kernel-doc
  scsi: lpfc: Add support for ATTO Fibre Channel devices
  scsi: core: Return BLK_STS_TRANSPORT for ALUA transitioning
  scsi: sd_zbc: Prevent zone information memory leak
  scsi: sd: Fix potential NULL pointer dereference
  scsi: mpi3mr: Rework mrioc->bsg_device model to fix warnings
  scsi: myrb: Fix up null pointer access on myrb_cleanup()
  scsi: core: Unexport scsi_bus_type
  scsi: sd: Don't call blk_cleanup_disk() in sd_probe()
  scsi: ufs: ufshcd: Delete unnecessary NULL check
  scsi: isci: Fix typo in comment
  scsi: pmcraid: Fix typo in comment
  scsi: smartpqi: Fix typo in comment
  scsi: qedf: Fix typo in comment
  scsi: esas2r: Fix typo in comment
  scsi: storvsc: Fix typo in comment
  scsi: ufs: Split the drivers/scsi/ufs directory
  scsi: qla1280: Remove redundant variable
  ...

1  2 
MAINTAINERS
drivers/Kconfig
drivers/Makefile
drivers/nvme/host/fc.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/sd.c
drivers/scsi/storvsc_drv.c
drivers/ufs/core/ufshpb.c

diff --combined MAINTAINERS
index 20bdf22601c3f3c94720222e9c1fd363de512de9,483a57da1f165380f7ccf33cb82fb1224038741f..b54288db77aa8dd957b30968698c5b42fcb570d8
@@@ -201,7 -201,6 +201,7 @@@ F: include/net/ieee80211_radiotap.
  F:    include/net/iw_handler.h
  F:    include/net/wext.h
  F:    include/uapi/linux/nl80211.h
 +F:    include/uapi/linux/wireless.h
  F:    net/wireless/
  
  8169 10/100/1000 GIGABIT ETHERNET DRIVER
@@@ -382,7 -381,7 +382,7 @@@ F: include/acpi
  F:    tools/power/acpi/
  
  ACPI FOR ARM64 (ACPI/arm64)
 -M:    Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 +M:    Lorenzo Pieralisi <lpieralisi@kernel.org>
  M:    Hanjun Guo <guohanjun@huawei.com>
  M:    Sudeep Holla <sudeep.holla@arm.com>
  L:    linux-acpi@vger.kernel.org
@@@ -820,7 -819,7 +820,7 @@@ S: Maintaine
  F:    drivers/mailbox/mailbox-altera.c
  
  ALTERA MSGDMA IP CORE DRIVER
 -M:    Olivier Dautricourt <olivier.dautricourt@orolia.com>
 +M:    Olivier Dautricourt <olivierdautricourt@gmail.com>
  R:    Stefan Roese <sr@denx.de>
  L:    dmaengine@vger.kernel.org
  S:    Odd Fixes
@@@ -1044,6 -1043,7 +1044,6 @@@ F:      arch/arm64/boot/dts/amd/amd-seattle-
  F:    drivers/net/ethernet/amd/xgbe/
  
  AMD SENSOR FUSION HUB DRIVER
 -M:    Nehal Shah <nehal-bakulchandra.shah@amd.com>
  M:    Basavaraj Natikar <basavaraj.natikar@amd.com>
  L:    linux-input@vger.kernel.org
  S:    Maintained
@@@ -1090,14 -1090,6 +1090,14 @@@ W:    https://ez.analog.com/linux-software
  F:    Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml
  F:    drivers/iio/adc/ad7292.c
  
 +ANALOG DEVICES INC AD3552R DRIVER
 +M:    Nuno Sá <nuno.sa@analog.com>
 +L:    linux-iio@vger.kernel.org
 +S:    Supported
 +W:    https://ez.analog.com/linux-software-drivers
 +F:    Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
 +F:    drivers/iio/dac/ad3552r.c
 +
  ANALOG DEVICES INC AD7293 DRIVER
  M:    Antoniu Miclaus <antoniu.miclaus@analog.com>
  L:    linux-iio@vger.kernel.org
@@@ -1383,6 -1375,14 +1383,6 @@@ L:     linux-input@vger.kernel.or
  S:    Odd fixes
  F:    drivers/input/mouse/bcm5974.c
  
 -APPLE DART IOMMU DRIVER
 -M:    Sven Peter <sven@svenpeter.dev>
 -R:    Alyssa Rosenzweig <alyssa@rosenzweig.io>
 -L:    iommu@lists.linux-foundation.org
 -S:    Maintained
 -F:    Documentation/devicetree/bindings/iommu/apple,dart.yaml
 -F:    drivers/iommu/apple-dart.c
 -
  APPLE PCIE CONTROLLER DRIVER
  M:    Alyssa Rosenzweig <alyssa@rosenzweig.io>
  M:    Marc Zyngier <maz@kernel.org>
@@@ -1446,7 -1446,6 +1446,7 @@@ F:      drivers/media/i2c/aptina-pll.
  
  AQUACOMPUTER D5 NEXT PUMP SENSOR DRIVER
  M:    Aleksa Savic <savicaleksa83@gmail.com>
 +M:    Jack Doan <me@jackdoan.com>
  L:    linux-hwmon@vger.kernel.org
  S:    Maintained
  F:    Documentation/hwmon/aquacomputer_d5next.rst
@@@ -1526,7 -1525,10 +1526,7 @@@ F:     Documentation/devicetree/bindings/mt
  F:    arch/arm/boot/dts/arm-realview-*
  F:    arch/arm/boot/dts/integrator*
  F:    arch/arm/boot/dts/versatile*
 -F:    arch/arm/mach-integrator/
 -F:    arch/arm/mach-realview/
  F:    arch/arm/mach-versatile/
 -F:    arch/arm/plat-versatile/
  F:    drivers/bus/arm-integrator-lm.c
  F:    drivers/clk/versatile/
  F:    drivers/i2c/busses/i2c-versatile.c
@@@ -1834,11 -1836,7 +1834,11 @@@ F:    Documentation/devicetree/bindings/ar
  F:    Documentation/devicetree/bindings/clock/apple,nco.yaml
  F:    Documentation/devicetree/bindings/i2c/apple,i2c.yaml
  F:    Documentation/devicetree/bindings/interrupt-controller/apple,*
 +F:    Documentation/devicetree/bindings/iommu/apple,dart.yaml
 +F:    Documentation/devicetree/bindings/iommu/apple,sart.yaml
  F:    Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml
 +F:    Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml
 +F:    Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
  F:    Documentation/devicetree/bindings/pci/apple,pcie.yaml
  F:    Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
  F:    Documentation/devicetree/bindings/power/apple*
@@@ -1847,18 -1845,14 +1847,18 @@@ F:   arch/arm64/boot/dts/apple
  F:    drivers/clk/clk-apple-nco.c
  F:    drivers/i2c/busses/i2c-pasemi-core.c
  F:    drivers/i2c/busses/i2c-pasemi-platform.c
 +F:    drivers/iommu/apple-dart.c
  F:    drivers/irqchip/irq-apple-aic.c
  F:    drivers/mailbox/apple-mailbox.c
 +F:    drivers/nvme/host/apple.c
 +F:    drivers/nvmem/apple-efuses.c
  F:    drivers/pinctrl/pinctrl-apple-gpio.c
  F:    drivers/soc/apple/*
  F:    drivers/watchdog/apple_wdt.c
  F:    include/dt-bindings/interrupt-controller/apple-aic.h
  F:    include/dt-bindings/pinctrl/apple.h
  F:    include/linux/apple-mailbox.h
 +F:    include/linux/soc/apple/*
  
  ARM/ARTPEC MACHINE SUPPORT
  M:    Jesper Nilsson <jesper.nilsson@axis.com>
@@@ -2135,18 -2129,6 +2135,18 @@@ T:    git git://git.kernel.org/pub/scm/lin
  F:    arch/arm/mach-sa1100/include/mach/jornada720.h
  F:    arch/arm/mach-sa1100/jornada720.c
  
 +ARM/HPE GXP ARCHITECTURE
 +M:    Jean-Marie Verdun <verdun@hpe.com>
 +M:    Nick Hawkins <nick.hawkins@hpe.com>
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/arm/hpe,gxp.yaml
 +F:    Documentation/devicetree/bindings/timer/hpe,gxp-timer.yaml
 +F:    arch/arm/boot/dts/hpe-bmc*
 +F:    arch/arm/boot/dts/hpe-gxp*
 +F:    arch/arm/mach-hpe/
 +F:    drivers/clocksource/timer-gxp.c
 +F:    drivers/watchdog/gxp-wdt.c
 +
  ARM/IGEP MACHINE SUPPORT
  M:    Enric Balletbo i Serra <eballetbo@gmail.com>
  M:    Javier Martinez Canillas <javier@dowhile0.org>
@@@ -2565,7 -2547,7 +2565,7 @@@ F:      drivers/pci/controller/dwc/pcie-qcom
  F:    drivers/phy/qualcomm/
  F:    drivers/power/*/msm*
  F:    drivers/reset/reset-qcom-*
- F:    drivers/scsi/ufs/ufs-qcom*
+ F:    drivers/ufs/host/ufs-qcom*
  F:    drivers/spi/spi-geni-qcom.c
  F:    drivers/spi/spi-qcom-qspi.c
  F:    drivers/spi/spi-qup.c
@@@ -2589,7 -2571,7 +2589,7 @@@ F:      Documentation/devicetree/bindings/ar
  F:    Documentation/devicetree/bindings/gpio/gpio-rda.yaml
  F:    Documentation/devicetree/bindings/interrupt-controller/rda,8810pl-intc.txt
  F:    Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml
 -F:    Documentation/devicetree/bindings/timer/rda,8810pl-timer.txt
 +F:    Documentation/devicetree/bindings/timer/rda,8810pl-timer.yaml
  F:    arch/arm/boot/dts/rda8810pl-*
  F:    drivers/clocksource/timer-rda.c
  F:    drivers/gpio/gpio-rda.c
@@@ -2654,14 -2636,13 +2654,14 @@@ F:   sound/soc/rockchip
  N:    rockchip
  
  ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  R:    Alim Akhtar <alim.akhtar@samsung.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-samsung-soc@vger.kernel.org
  S:    Maintained
  C:    irc://irc.libera.chat/linux-exynos
  Q:    https://patchwork.kernel.org/project/linux-samsung-soc/list/
 +B:    mailto:linux-samsung-soc@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git
  F:    Documentation/arm/samsung/
  F:    Documentation/devicetree/bindings/arm/samsung/
@@@ -2962,7 -2943,7 +2962,7 @@@ N:      uniphie
  ARM/VERSATILE EXPRESS PLATFORM
  M:    Liviu Dudau <liviu.dudau@arm.com>
  M:    Sudeep Holla <sudeep.holla@arm.com>
 -M:    Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 +M:    Lorenzo Pieralisi <lpieralisi@kernel.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    */*/*/vexpress*
@@@ -3118,16 -3099,6 +3118,16 @@@ S:    Maintaine
  F:    Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml
  F:    drivers/mmc/host/sdhci-of-aspeed*
  
 +ASPEED SMC SPI DRIVER
 +M:    Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>
 +M:    Cédric Le Goater <clg@kaod.org>
 +L:    linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
 +L:    openbmc@lists.ozlabs.org (moderated for non-subscribers)
 +L:    linux-spi@vger.kernel.org
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml
 +F:    drivers/spi/spi-aspeed-smc.c
 +
  ASPEED VIDEO ENGINE DRIVER
  M:    Eddie James <eajames@linux.ibm.com>
  L:    linux-media@vger.kernel.org
@@@ -3533,14 -3504,10 +3533,14 @@@ R:   Andy Shevchenko <andriy.shevchenko@l
  R:    Rasmus Villemoes <linux@rasmusvillemoes.dk>
  S:    Maintained
  F:    include/linux/bitmap.h
 +F:    include/linux/cpumask.h
  F:    include/linux/find.h
 +F:    include/linux/nodemask.h
  F:    lib/bitmap.c
 +F:    lib/cpumask.c
  F:    lib/find_bit.c
  F:    lib/find_bit_benchmark.c
 +F:    lib/nodemask.c
  F:    lib/test_bitmap.c
  F:    tools/include/linux/bitmap.h
  F:    tools/include/linux/find.h
@@@ -3602,9 -3569,8 +3602,9 @@@ M:      Andy Gospodarek <andy@greyhouse.net
  L:    netdev@vger.kernel.org
  S:    Supported
  W:    http://sourceforge.net/projects/bonding/
 +F:    Documentation/networking/bonding.rst
  F:    drivers/net/bonding/
 -F:    include/net/bonding.h
 +F:    include/net/bond*
  F:    include/uapi/linux/if_bonding.h
  
  BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER
@@@ -3774,23 -3740,9 +3774,23 @@@ F:    drivers/net/dsa/bcm_sf2
  F:    include/linux/dsa/brcm.h
  F:    include/linux/platform_data/b53.h
  
 +BROADCOM BCMBCA ARM ARCHITECTURE
 +M:    William Zhang <william.zhang@broadcom.com>
 +M:    Anand Gore <anand.gore@broadcom.com>
 +M:    Kursad Oney <kursad.oney@broadcom.com>
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +S:    Maintained
 +T:    git git://github.com/broadcom/stblinux.git
 +F:    Documentation/devicetree/bindings/arm/bcm/brcm,bcmbca.yaml
 +F:    arch/arm/boot/dts/bcm47622.dtsi
 +F:    arch/arm/boot/dts/bcm947622.dts
 +N:    bcmbca
 +N:    bcm[9]?47622
 +
  BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
  M:    Nicolas Saenz Julienne <nsaenz@kernel.org>
 -L:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
@@@ -3800,13 -3752,12 +3800,13 @@@ F:   drivers/pci/controller/pcie-brcmstb.
  F:    drivers/staging/vc04_services
  N:    bcm2711
  N:    bcm283*
 +N:    raspberrypi
  
  BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE
  M:    Florian Fainelli <f.fainelli@gmail.com>
  M:    Ray Jui <rjui@broadcom.com>
  M:    Scott Branden <sbranden@broadcom.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  S:    Maintained
  T:    git git://github.com/broadcom/mach-bcm
  F:    arch/arm/mach-bcm/
@@@ -3826,7 -3777,7 +3826,7 @@@ F:      arch/mips/include/asm/mach-bcm47xx/
  
  BROADCOM BCM4908 ETHERNET DRIVER
  M:    Rafał Miłecki <rafal@milecki.pl>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    netdev@vger.kernel.org
  S:    Maintained
  F:    Documentation/devicetree/bindings/net/brcm,bcm4908-enet.yaml
@@@ -3835,7 -3786,7 +3835,7 @@@ F:      drivers/net/ethernet/broadcom/unimac
  
  BROADCOM BCM4908 PINMUX DRIVER
  M:    Rafał Miłecki <rafal@milecki.pl>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-gpio@vger.kernel.org
  S:    Maintained
  F:    Documentation/devicetree/bindings/pinctrl/brcm,bcm4908-pinctrl.yaml
@@@ -3845,7 -3796,7 +3845,7 @@@ BROADCOM BCM5301X ARM ARCHITECTUR
  M:    Florian Fainelli <f.fainelli@gmail.com>
  M:    Hauke Mehrtens <hauke@hauke-m.de>
  M:    Rafał Miłecki <zajec5@gmail.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/boot/dts/bcm470*
@@@ -3856,7 -3807,7 +3856,7 @@@ F:      arch/arm/mach-bcm/bcm_5301x.
  BROADCOM BCM53573 ARM ARCHITECTURE
  M:    Florian Fainelli <f.fainelli@gmail.com>
  M:    Rafał Miłecki <rafal@milecki.pl>
 -L:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/boot/dts/bcm47189*
@@@ -3864,7 -3815,7 +3864,7 @@@ F:      arch/arm/boot/dts/bcm53573
  
  BROADCOM BCM63XX ARM ARCHITECTURE
  M:    Florian Fainelli <f.fainelli@gmail.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  T:    git git://github.com/broadcom/stblinux.git
@@@ -3878,7 -3829,7 +3878,7 @@@ F:      drivers/usb/gadget/udc/bcm63xx_udc.
  
  BROADCOM BCM7XXX ARM ARCHITECTURE
  M:    Florian Fainelli <f.fainelli@gmail.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  T:    git git://github.com/broadcom/stblinux.git
@@@ -3896,21 -3847,21 +3896,21 @@@ N:   bcm712
  BROADCOM BDC DRIVER
  M:    Al Cooper <alcooperx@gmail.com>
  L:    linux-usb@vger.kernel.org
 -L:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  S:    Maintained
  F:    Documentation/devicetree/bindings/usb/brcm,bdc.yaml
  F:    drivers/usb/gadget/udc/bdc/
  
  BROADCOM BMIPS CPUFREQ DRIVER
  M:    Markus Mayer <mmayer@broadcom.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-pm@vger.kernel.org
  S:    Maintained
  F:    drivers/cpufreq/bmips-cpufreq.c
  
  BROADCOM BMIPS MIPS ARCHITECTURE
  M:    Florian Fainelli <f.fainelli@gmail.com>
 -L:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-mips@vger.kernel.org
  S:    Maintained
  T:    git git://github.com/broadcom/stblinux.git
@@@ -3961,9 -3912,7 +3961,9 @@@ BROADCOM BNXT_EN 50 GIGABIT ETHERNET DR
  M:    Michael Chan <michael.chan@broadcom.com>
  L:    netdev@vger.kernel.org
  S:    Supported
 +F:    drivers/firmware/broadcom/tee_bnxt_fw.c
  F:    drivers/net/ethernet/broadcom/bnxt/
 +F:    include/linux/firmware/broadcom/tee_bnxt_fw.h
  
  BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
  M:    Arend van Spriel <aspriel@gmail.com>
@@@ -3978,53 -3927,53 +3978,53 @@@ F:   drivers/net/wireless/broadcom/brcm80
  BROADCOM BRCMSTB GPIO DRIVER
  M:    Doug Berger <opendmb@gmail.com>
  M:    Florian Fainelli <f.fainelli@gmail.com>
 -L:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  S:    Supported
  F:    Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
  F:    drivers/gpio/gpio-brcmstb.c
  
  BROADCOM BRCMSTB I2C DRIVER
  M:    Kamal Dasu <kdasu.kdev@gmail.com>
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-i2c@vger.kernel.org
 -L:    bcm-kernel-feedback-list@broadcom.com
  S:    Supported
  F:    Documentation/devicetree/bindings/i2c/brcm,brcmstb-i2c.yaml
  F:    drivers/i2c/busses/i2c-brcmstb.c
  
  BROADCOM BRCMSTB UART DRIVER
  M:    Al Cooper <alcooperx@gmail.com>
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-serial@vger.kernel.org
 -L:    bcm-kernel-feedback-list@broadcom.com
  S:    Maintained
  F:    Documentation/devicetree/bindings/serial/brcm,bcm7271-uart.yaml
  F:    drivers/tty/serial/8250/8250_bcm7271.c
  
  BROADCOM BRCMSTB USB EHCI DRIVER
  M:    Al Cooper <alcooperx@gmail.com>
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-usb@vger.kernel.org
 -L:    bcm-kernel-feedback-list@broadcom.com
  S:    Maintained
  F:    Documentation/devicetree/bindings/usb/brcm,bcm7445-ehci.yaml
  F:    drivers/usb/host/ehci-brcm.*
  
  BROADCOM BRCMSTB USB PIN MAP DRIVER
  M:    Al Cooper <alcooperx@gmail.com>
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-usb@vger.kernel.org
 -L:    bcm-kernel-feedback-list@broadcom.com
  S:    Maintained
  F:    Documentation/devicetree/bindings/usb/brcm,usb-pinmap.yaml
  F:    drivers/usb/misc/brcmstb-usb-pinmap.c
  
  BROADCOM BRCMSTB USB2 and USB3 PHY DRIVER
  M:    Al Cooper <alcooperx@gmail.com>
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-kernel@vger.kernel.org
 -L:    bcm-kernel-feedback-list@broadcom.com
  S:    Maintained
  F:    drivers/phy/broadcom/phy-brcm-usb*
  
  BROADCOM ETHERNET PHY DRIVERS
  M:    Florian Fainelli <f.fainelli@gmail.com>
 -L:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    netdev@vger.kernel.org
  S:    Supported
  F:    Documentation/devicetree/bindings/net/broadcom-bcm87xx.txt
@@@ -4035,7 -3984,7 +4035,7 @@@ F:      include/linux/brcmphy.
  BROADCOM GENET ETHERNET DRIVER
  M:    Doug Berger <opendmb@gmail.com>
  M:    Florian Fainelli <f.fainelli@gmail.com>
 -L:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    netdev@vger.kernel.org
  S:    Supported
  F:    Documentation/devicetree/bindings/net/brcm,bcmgenet.yaml
@@@ -4049,7 -3998,7 +4049,7 @@@ F:      include/linux/platform_data/mdio-bcm
  BROADCOM IPROC ARM ARCHITECTURE
  M:    Ray Jui <rjui@broadcom.com>
  M:    Scott Branden <sbranden@broadcom.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  T:    git git://github.com/broadcom/stblinux.git
@@@ -4077,7 -4026,7 +4077,7 @@@ N:      stingra
  
  BROADCOM IPROC GBIT ETHERNET DRIVER
  M:    Rafał Miłecki <rafal@milecki.pl>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    netdev@vger.kernel.org
  S:    Maintained
  F:    Documentation/devicetree/bindings/net/brcm,amac.yaml
@@@ -4086,7 -4035,7 +4086,7 @@@ F:      drivers/net/ethernet/broadcom/unimac
  
  BROADCOM KONA GPIO DRIVER
  M:    Ray Jui <rjui@broadcom.com>
 -L:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  S:    Supported
  F:    Documentation/devicetree/bindings/gpio/brcm,kona-gpio.txt
  F:    drivers/gpio/gpio-bcm-kona.c
@@@ -4119,7 -4068,7 +4119,7 @@@ F:      drivers/firmware/broadcom/
  BROADCOM PMB (POWER MANAGEMENT BUS) DRIVER
  M:    Rafał Miłecki <rafal@milecki.pl>
  M:    Florian Fainelli <f.fainelli@gmail.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-pm@vger.kernel.org
  S:    Maintained
  T:    git git://github.com/broadcom/stblinux.git
@@@ -4135,7 -4084,7 +4135,7 @@@ F:      include/linux/bcma
  
  BROADCOM SPI DRIVER
  M:    Kamal Dasu <kdasu.kdev@gmail.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  S:    Maintained
  F:    Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.yaml
  F:    drivers/spi/spi-bcm-qspi.*
@@@ -4144,7 -4093,7 +4144,7 @@@ F:      drivers/spi/spi-iproc-qspi.
  
  BROADCOM STB AVS CPUFREQ DRIVER
  M:    Markus Mayer <mmayer@broadcom.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-pm@vger.kernel.org
  S:    Maintained
  F:    Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt
@@@ -4152,7 -4101,7 +4152,7 @@@ F:      drivers/cpufreq/brcmstb
  
  BROADCOM STB AVS TMON DRIVER
  M:    Markus Mayer <mmayer@broadcom.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-pm@vger.kernel.org
  S:    Maintained
  F:    Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml
@@@ -4160,7 -4109,7 +4160,7 @@@ F:      drivers/thermal/broadcom/brcmstb
  
  BROADCOM STB DPFE DRIVER
  M:    Markus Mayer <mmayer@broadcom.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
@@@ -4169,8 -4118,8 +4169,8 @@@ F:      drivers/memory/brcmstb_dpfe.
  BROADCOM STB NAND FLASH DRIVER
  M:    Brian Norris <computersforpeace@gmail.com>
  M:    Kamal Dasu <kdasu.kdev@gmail.com>
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-mtd@lists.infradead.org
 -L:    bcm-kernel-feedback-list@broadcom.com
  S:    Maintained
  F:    drivers/mtd/nand/raw/brcmnand/
  F:    include/linux/platform_data/brcmnand.h
@@@ -4179,7 -4128,7 +4179,7 @@@ BROADCOM STB PCIE DRIVE
  M:    Jim Quinlan <jim2101024@gmail.com>
  M:    Nicolas Saenz Julienne <nsaenz@kernel.org>
  M:    Florian Fainelli <f.fainelli@gmail.com>
 -M:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-pci@vger.kernel.org
  S:    Maintained
  F:    Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
@@@ -4187,7 -4136,7 +4187,7 @@@ F:      drivers/pci/controller/pcie-brcmstb.
  
  BROADCOM SYSTEMPORT ETHERNET DRIVER
  M:    Florian Fainelli <f.fainelli@gmail.com>
 -L:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    netdev@vger.kernel.org
  S:    Supported
  F:    drivers/net/ethernet/broadcom/bcmsysport.*
@@@ -4204,7 -4153,7 +4204,7 @@@ F:      drivers/net/ethernet/broadcom/tg3.
  
  BROADCOM VK DRIVER
  M:    Scott Branden <scott.branden@broadcom.com>
 -L:    bcm-kernel-feedback-list@broadcom.com
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  S:    Supported
  F:    drivers/misc/bcm-vk/
  F:    include/uapi/linux/misc/bcm_vk.h
@@@ -4422,6 -4371,7 +4422,6 @@@ F:      drivers/net/can
  F:    drivers/phy/phy-can-transceiver.c
  F:    include/linux/can/bittiming.h
  F:    include/linux/can/dev.h
 -F:    include/linux/can/led.h
  F:    include/linux/can/length.h
  F:    include/linux/can/platform/
  F:    include/linux/can/rx-offload.h
@@@ -4592,8 -4542,8 +4592,8 @@@ F:      drivers/power/supply/cw2015_battery.
  
  CEPH COMMON CODE (LIBCEPH)
  M:    Ilya Dryomov <idryomov@gmail.com>
 -M:    Jeff Layton <jlayton@kernel.org>
  M:    Xiubo Li <xiubli@redhat.com>
 +R:    Jeff Layton <jlayton@kernel.org>
  L:    ceph-devel@vger.kernel.org
  S:    Supported
  W:    http://ceph.com/
@@@ -4603,9 -4553,9 +4603,9 @@@ F:      include/linux/crush
  F:    net/ceph/
  
  CEPH DISTRIBUTED FILE SYSTEM CLIENT (CEPH)
 -M:    Jeff Layton <jlayton@kernel.org>
  M:    Xiubo Li <xiubli@redhat.com>
  M:    Ilya Dryomov <idryomov@gmail.com>
 +R:    Jeff Layton <jlayton@kernel.org>
  L:    ceph-devel@vger.kernel.org
  S:    Supported
  W:    http://ceph.com/
@@@ -4620,9 -4570,7 +4620,9 @@@ L:      keyrings@vger.kernel.or
  S:    Maintained
  F:    Documentation/admin-guide/module-signing.rst
  F:    certs/
 +F:    scripts/check-blacklist-hashes.awk
  F:    scripts/sign-file.c
 +F:    tools/certs/
  
  CFAG12864B LCD DRIVER
  M:    Miguel Ojeda <ojeda@kernel.org>
@@@ -4667,7 -4615,6 +4667,7 @@@ F:      Documentation/dev-tools/checkpatch.r
  
  CHINESE DOCUMENTATION
  M:    Alex Shi <alexs@kernel.org>
 +M:    Yanteng Si <siyanteng@loongson.cn>
  S:    Maintained
  F:    Documentation/translations/zh_CN/
  
@@@ -4741,12 -4688,10 +4741,12 @@@ CIRRUS LOGIC AUDIO CODEC DRIVER
  M:    James Schulman <james.schulman@cirrus.com>
  M:    David Rhodes <david.rhodes@cirrus.com>
  M:    Lucas Tanure <tanureal@opensource.cirrus.com>
 +M:    Richard Fitzgerald <rf@opensource.cirrus.com>
  L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
  L:    patches@opensource.cirrus.com
  S:    Maintained
  F:    Documentation/devicetree/bindings/sound/cirrus,cs*
 +F:    include/dt-bindings/sound/cs*
  F:    sound/pci/hda/cs*
  F:    sound/soc/codecs/cs*
  
@@@ -4846,7 -4791,6 +4846,7 @@@ F:      .clang-forma
  CLANG/LLVM BUILD SUPPORT
  M:    Nathan Chancellor <nathan@kernel.org>
  M:    Nick Desaulniers <ndesaulniers@google.com>
 +R:    Tom Rix <trix@redhat.com>
  L:    llvm@lists.linux.dev
  S:    Supported
  W:    https://clangbuiltlinux.github.io/
@@@ -5047,7 -4991,6 +5047,7 @@@ F:      Documentation/admin-guide/cgroup-v1
  F:    Documentation/admin-guide/cgroup-v2.rst
  F:    include/linux/cgroup*
  F:    kernel/cgroup/
 +F:    tools/testing/selftests/cgroup/
  
  CONTROL GROUP - BLOCK IO CONTROLLER (BLKIO)
  M:    Tejun Heo <tj@kernel.org>
@@@ -5076,15 -5019,11 +5076,15 @@@ M:   Johannes Weiner <hannes@cmpxchg.org
  M:    Michal Hocko <mhocko@kernel.org>
  M:    Roman Gushchin <roman.gushchin@linux.dev>
  M:    Shakeel Butt <shakeelb@google.com>
 +R:    Muchun Song <songmuchun@bytedance.com>
  L:    cgroups@vger.kernel.org
  L:    linux-mm@kvack.org
  S:    Maintained
  F:    mm/memcontrol.c
  F:    mm/swap_cgroup.c
 +F:    tools/testing/selftests/cgroup/memcg_protection.m
 +F:    tools/testing/selftests/cgroup/test_kmem.c
 +F:    tools/testing/selftests/cgroup/test_memcontrol.c
  
  CORETEMP HARDWARE MONITORING DRIVER
  M:    Fenghua Yu <fenghua.yu@intel.com>
@@@ -5106,6 -5045,12 +5106,6 @@@ S:     Maintaine
  F:    Documentation/hwmon/corsair-psu.rst
  F:    drivers/hwmon/corsair-psu.c
  
 -COSA/SRP SYNC SERIAL DRIVER
 -M:    Jan "Yenya" Kasprzak <kas@fi.muni.cz>
 -S:    Maintained
 -W:    http://www.fi.muni.cz/~kas/cosa/
 -F:    drivers/net/wan/cosa*
 -
  COUNTER SUBSYSTEM
  M:    William Breathitt Gray <vilhelm.gray@gmail.com>
  L:    linux-iio@vger.kernel.org
@@@ -5182,7 -5127,7 +5182,7 @@@ F:      arch/x86/kernel/cpuid.
  F:    arch/x86/kernel/msr.c
  
  CPUIDLE DRIVER - ARM BIG LITTLE
 -M:    Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 +M:    Lorenzo Pieralisi <lpieralisi@kernel.org>
  M:    Daniel Lezcano <daniel.lezcano@linaro.org>
  L:    linux-pm@vger.kernel.org
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -5202,7 -5147,7 +5202,7 @@@ F:      drivers/cpuidle/cpuidle-exynos.
  F:    include/linux/platform_data/cpuidle-exynos.h
  
  CPUIDLE DRIVER - ARM PSCI
 -M:    Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 +M:    Lorenzo Pieralisi <lpieralisi@kernel.org>
  M:    Sudeep Holla <sudeep.holla@arm.com>
  L:    linux-pm@vger.kernel.org
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -5287,14 -5232,6 +5287,14 @@@ T:    git git://linuxtv.org/media_tree.gi
  F:    Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml
  F:    drivers/media/platform/sunxi/sun6i-csi/
  
 +CTU CAN FD DRIVER
 +M:    Pavel Pisa <pisa@cmp.felk.cvut.cz>
 +M:    Ondrej Ille <ondrej.ille@gmail.com>
 +L:    linux-can@vger.kernel.org
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/net/can/ctu,ctucanfd.yaml
 +F:    drivers/net/can/ctucanfd/
 +
  CW1200 WLAN driver
  M:    Solomon Peachy <pizza@shaftnet.org>
  S:    Maintained
@@@ -5497,7 -5434,6 +5497,7 @@@ F:      net/ax25/sysctl_net_ax25.
  
  DATA ACCESS MONITOR
  M:    SeongJae Park <sj@kernel.org>
 +L:    damon@lists.linux.dev
  L:    linux-mm@kvack.org
  S:    Maintained
  F:    Documentation/ABI/testing/sysfs-kernel-mm-damon
@@@ -5779,7 -5715,7 +5779,7 @@@ W:      http://lanana.org/docs/device-list/i
  
  DEVICE RESOURCE MANAGEMENT HELPERS
  M:    Hans de Goede <hdegoede@redhat.com>
 -R:    Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
 +R:    Matti Vaittinen <mazziesaccount@gmail.com>
  S:    Maintained
  F:    include/linux/devm-helpers.h
  
@@@ -5976,7 -5912,7 +5976,7 @@@ R:      Benjamin Gaignard <benjamin.gaignard
  R:    Liam Mark <lmark@codeaurora.org>
  R:    Laura Abbott <labbott@redhat.com>
  R:    Brian Starkey <Brian.Starkey@arm.com>
 -R:    John Stultz <john.stultz@linaro.org>
 +R:    John Stultz <jstultz@google.com>
  L:    linux-media@vger.kernel.org
  L:    dri-devel@lists.freedesktop.org
  L:    linaro-mm-sig@lists.linaro.org (moderated for non-subscribers)
@@@ -6051,12 -5987,6 +6051,12 @@@ L:    linux-doc@vger.kernel.or
  S:    Maintained
  F:    Documentation/translations/it_IT
  
 +DOCUMENTATION/JAPANESE
 +R:    Akira Yokosawa <akiyks@gmail.com>
 +L:    linux-doc@vger.kernel.org
 +S:    Maintained
 +F:    Documentation/translations/ja_JP
 +
  DONGWOON DW9714 LENS VOICE COIL DRIVER
  M:    Sakari Ailus <sakari.ailus@linux.intel.com>
  L:    linux-media@vger.kernel.org
@@@ -6323,9 -6253,8 +6323,9 @@@ F:      drivers/gpu/drm/tiny/panel-mipi-dbi.
  
  DRM DRIVER FOR MSM ADRENO GPU
  M:    Rob Clark <robdclark@gmail.com>
 -M:    Sean Paul <sean@poorly.run>
 -R:    Abhinav Kumar <quic_abhinavk@quicinc.com>
 +M:    Abhinav Kumar <quic_abhinavk@quicinc.com>
 +M:    Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 +R:    Sean Paul <sean@poorly.run>
  L:    linux-arm-msm@vger.kernel.org
  L:    dri-devel@lists.freedesktop.org
  L:    freedreno@lists.freedesktop.org
@@@ -6378,11 -6307,6 +6378,11 @@@ S:    Maintaine
  F:    Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.yaml
  F:    drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
  
 +DRM DRIVER FOR PARADE PS8640 BRIDGE CHIP
 +R:    Douglas Anderson <dianders@chromium.org>
 +F:    Documentation/devicetree/bindings/display/bridge/ps8640.yaml
 +F:    drivers/gpu/drm/bridge/parade-ps8640.c
 +
  DRM DRIVER FOR PERVASIVE DISPLAYS REPAPER PANELS
  M:    Noralf Trønnes <noralf@tronnes.org>
  S:    Maintained
@@@ -6496,11 -6420,6 +6496,11 @@@ DRM DRIVER FOR TDFX VIDEO CARD
  S:    Orphan / Obsolete
  F:    drivers/gpu/drm/tdfx/
  
 +DRM DRIVER FOR TI SN65DSI86 BRIDGE CHIP
 +R:    Douglas Anderson <dianders@chromium.org>
 +F:    Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml
 +F:    drivers/gpu/drm/bridge/ti-sn65dsi86.c
 +
  DRM DRIVER FOR TPO TPG110 PANELS
  M:    Linus Walleij <linus.walleij@linaro.org>
  S:    Maintained
@@@ -6620,7 -6539,6 +6620,7 @@@ R:      Jonas Karlman <jonas@kwiboo.se
  R:    Jernej Skrabec <jernej.skrabec@gmail.com>
  S:    Maintained
  T:    git git://anongit.freedesktop.org/drm/drm-misc
 +F:    Documentation/devicetree/bindings/display/bridge/
  F:    drivers/gpu/drm/bridge/
  
  DRM DRIVERS FOR EXYNOS
@@@ -6664,7 -6582,7 +6664,7 @@@ F:      drivers/gpu/drm/gma500
  DRM DRIVERS FOR HISILICON
  M:    Xinliang Liu <xinliang.liu@linaro.org>
  M:    Tian Tao  <tiantao6@hisilicon.com>
 -R:    John Stultz <john.stultz@linaro.org>
 +R:    John Stultz <jstultz@google.com>
  R:    Xinwei Kong <kong.kongxinwei@hisilicon.com>
  R:    Chen Feng <puck.chen@hisilicon.com>
  L:    dri-devel@lists.freedesktop.org
@@@ -7460,6 -7378,7 +7460,6 @@@ L:      linux-mm@kvack.or
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/execve
  F:    arch/alpha/kernel/binfmt_loader.c
 -F:    arch/x86/ia32/ia32_aout.c
  F:    fs/*binfmt_*.c
  F:    fs/exec.c
  F:    include/linux/binfmts.h
@@@ -7537,7 -7456,6 +7537,7 @@@ S:      Maintaine
  F:    Documentation/admin-guide/bootconfig.rst
  F:    fs/proc/bootconfig.c
  F:    include/linux/bootconfig.h
 +F:    lib/bootconfig-data.S
  F:    lib/bootconfig.c
  F:    tools/bootconfig/*
  F:    tools/bootconfig/scripts/*
@@@ -7576,7 -7494,7 +7576,7 @@@ F:      Documentation/hwmon/f71805f.rs
  F:    drivers/hwmon/f71805f.c
  
  FADDR2LINE
 -M:    Josh Poimboeuf <jpoimboe@redhat.com>
 +M:    Josh Poimboeuf <jpoimboe@kernel.org>
  S:    Maintained
  F:    scripts/faddr2line
  
@@@ -7731,7 -7649,6 +7731,7 @@@ F:      include/linux/arm_ffa.
  
  FIRMWARE LOADER (request_firmware)
  M:    Luis Chamberlain <mcgrof@kernel.org>
 +M:    Russ Weight <russell.h.weight@intel.com>
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  F:    Documentation/firmware_class/
@@@ -7800,7 -7717,7 +7800,7 @@@ R:      Tom Rix <trix@redhat.com
  L:    linux-fpga@vger.kernel.org
  S:    Maintained
  Q:    http://patchwork.kernel.org/project/linux-fpga/list/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga.git
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/fpga/linux-fpga.git
  F:    Documentation/devicetree/bindings/fpga/
  F:    Documentation/driver-api/fpga/
  F:    Documentation/fpga/
@@@ -8190,7 -8107,7 +8190,7 @@@ M:      Ingo Molnar <mingo@redhat.com
  R:    Peter Zijlstra <peterz@infradead.org>
  R:    Darren Hart <dvhart@infradead.org>
  R:    Davidlohr Bueso <dave@stgolabs.net>
 -R:    André Almeida <andrealmeid@collabora.com>
 +R:    André Almeida <andrealmeid@igalia.com>
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/core
@@@ -8426,7 -8343,7 +8426,7 @@@ M:      Mika Westerberg <mika.westerberg@lin
  M:    Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  L:    linux-gpio@vger.kernel.org
  L:    linux-acpi@vger.kernel.org
 -S:    Maintained
 +S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git
  F:    Documentation/firmware-guide/acpi/gpio-properties.rst
  F:    drivers/gpio/gpiolib-acpi.c
@@@ -8463,7 -8380,7 +8463,7 @@@ M:      Linus Walleij <linus.walleij@linaro.
  M:    Bartosz Golaszewski <brgl@bgdev.pl>
  L:    linux-gpio@vger.kernel.org
  S:    Maintained
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
  F:    Documentation/ABI/obsolete/sysfs-gpio
  F:    Documentation/ABI/testing/gpio-cdev
  F:    Documentation/admin-guide/gpio/
@@@ -8634,6 -8551,17 +8634,6 @@@ L:     linux-efi@vger.kernel.or
  S:    Maintained
  F:    block/partitions/efi.*
  
 -H8/300 ARCHITECTURE
 -M:    Yoshinori Sato <ysato@users.sourceforge.jp>
 -L:    uclinux-h8-devel@lists.sourceforge.jp (moderated for non-subscribers)
 -S:    Maintained
 -W:    http://uclinux-h8.sourceforge.jp
 -T:    git git://git.sourceforge.jp/gitroot/uclinux-h8/linux.git
 -F:    arch/h8300/
 -F:    drivers/clk/h8300/
 -F:    drivers/clocksource/h8300_*.c
 -F:    drivers/irqchip/irq-renesas-h8*.c
 -
  HABANALABS PCI DRIVER
  M:    Oded Gabbay <ogabbay@kernel.org>
  S:    Supported
@@@ -8747,6 -8675,7 +8747,6 @@@ F:      include/linux/cciss*.
  F:    include/uapi/linux/cciss*.h
  
  HFI1 DRIVER
 -M:    Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
  M:    Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
  L:    linux-rdma@vger.kernel.org
  S:    Supported
@@@ -8819,14 -8748,6 +8819,14 @@@ F:    drivers/hid/hid-sensor-
  F:    drivers/iio/*/hid-*
  F:    include/linux/hid-sensor-*
  
 +HID WACOM DRIVER
 +M:    Ping Cheng <ping.cheng@wacom.com>
 +M:    Jason Gerecke  <jason.gerecke@wacom.com>
 +L:    linux-input@vger.kernel.org
 +S:    Maintained
 +F:    drivers/hid/wacom.h
 +F:    drivers/hid/wacom_*
 +
  HIGH-RESOLUTION TIMERS, CLOCKEVENTS
  M:    Thomas Gleixner <tglx@linutronix.de>
  L:    linux-kernel@vger.kernel.org
@@@ -8842,6 -8763,7 +8842,6 @@@ F:      kernel/time/timer_*.
  HIGH-SPEED SCC DRIVER FOR AX.25
  L:    linux-hams@vger.kernel.org
  S:    Orphan
 -F:    drivers/net/hamradio/dmascc.c
  F:    drivers/net/hamradio/scc.c
  
  HIGHPOINT ROCKETRAID 3xxx RAID DRIVER
@@@ -8922,7 -8844,7 +8922,7 @@@ F:      Documentation/devicetree/bindings/ne
  F:    drivers/net/ethernet/hisilicon/
  
  HIKEY960 ONBOARD USB GPIO HUB DRIVER
 -M:    John Stultz <john.stultz@linaro.org>
 +M:    John Stultz <jstultz@google.com>
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  F:    drivers/misc/hisi_hikey_usb.c
@@@ -9077,16 -8999,8 +9077,16 @@@ L:    linux-input@vger.kernel.or
  S:    Maintained
  F:    drivers/input/touchscreen/htcpen.c
  
 +HTE SUBSYSTEM
 +M:    Dipen Patel <dipenp@nvidia.com>
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/timestamp/
 +F:    Documentation/hte/
 +F:    drivers/hte/
 +F:    include/linux/hte.h
 +
  HTS221 TEMPERATURE-HUMIDITY IIO DRIVER
 -M:    Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
 +M:    Lorenzo Bianconi <lorenzo@kernel.org>
  L:    linux-iio@vger.kernel.org
  S:    Maintained
  W:    http://www.st.com/
@@@ -9099,20 -9013,16 +9099,20 @@@ S:   Orpha
  F:    Documentation/networking/device_drivers/ethernet/huawei/hinic.rst
  F:    drivers/net/ethernet/huawei/hinic/
  
 -HUGETLB FILESYSTEM
 +HUGETLB SUBSYSTEM
  M:    Mike Kravetz <mike.kravetz@oracle.com>
 +M:    Muchun Song <songmuchun@bytedance.com>
  L:    linux-mm@kvack.org
  S:    Maintained
  F:    Documentation/ABI/testing/sysfs-kernel-mm-hugepages
  F:    Documentation/admin-guide/mm/hugetlbpage.rst
  F:    Documentation/vm/hugetlbfs_reserv.rst
 +F:    Documentation/vm/vmemmap_dedup.rst
  F:    fs/hugetlbfs/
  F:    include/linux/hugetlb.h
  F:    mm/hugetlb.c
 +F:    mm/hugetlb_vmemmap.c
 +F:    mm/hugetlb_vmemmap.h
  
  HVA ST MEDIA DRIVER
  M:    Jean-Christophe Trotin <jean-christophe.trotin@foss.st.com>
@@@ -9354,13 -9264,13 +9354,13 @@@ F:   drivers/i2c/i2c-stub.
  I3C DRIVER FOR CADENCE I3C MASTER IP
  M:    Przemysław Gaj <pgaj@cadence.com>
  S:    Maintained
 -F:    Documentation/devicetree/bindings/i3c/cdns,i3c-master.txt
 +F:    Documentation/devicetree/bindings/i3c/cdns,i3c-master.yaml
  F:    drivers/i3c/master/i3c-master-cdns.c
  
  I3C DRIVER FOR SYNOPSYS DESIGNWARE
  M:    Vitor Soares <vitor.soares@synopsys.com>
  S:    Maintained
 -F:    Documentation/devicetree/bindings/i3c/snps,dw-i3c-master.txt
 +F:    Documentation/devicetree/bindings/i3c/snps,dw-i3c-master.yaml
  F:    drivers/i3c/master/dw*
  
  I3C SUBSYSTEM
@@@ -9426,12 -9336,14 +9426,12 @@@ F:   drivers/pci/hotplug/rpaphp
  
  IBM Power SRIOV Virtual NIC Device Driver
  M:    Dany Madden <drt@linux.ibm.com>
 -M:    Sukadev Bhattiprolu <sukadev@linux.ibm.com>
  R:    Thomas Falcon <tlfalcon@linux.ibm.com>
  L:    netdev@vger.kernel.org
  S:    Supported
  F:    drivers/net/ethernet/ibm/ibmvnic.*
  
  IBM Power Virtual Accelerator Switchboard
 -M:    Sukadev Bhattiprolu <sukadev@linux.ibm.com>
  L:    linuxppc-dev@lists.ozlabs.org
  S:    Supported
  F:    arch/powerpc/include/asm/vas.h
@@@ -9686,7 -9598,6 +9686,7 @@@ F:      drivers/iio/pressure/dps310.
  
  INFINIBAND SUBSYSTEM
  M:    Jason Gunthorpe <jgg@nvidia.com>
 +M:    Leon Romanovsky <leonro@nvidia.com>
  L:    linux-rdma@vger.kernel.org
  S:    Supported
  W:    https://github.com/linux-rdma/rdma-core
@@@ -9899,7 -9810,7 +9899,7 @@@ F:      drivers/video/fbdev/intelfb
  INTEL GPIO DRIVERS
  M:    Andy Shevchenko <andy@kernel.org>
  L:    linux-gpio@vger.kernel.org
 -S:    Maintained
 +S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git
  F:    drivers/gpio/gpio-ich.c
  F:    drivers/gpio/gpio-merrifield.c
@@@ -9948,14 -9859,6 +9948,14 @@@ B:    https://bugzilla.kernel.or
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git
  F:    drivers/idle/intel_idle.c
  
 +INTEL IN FIELD SCAN (IFS) DEVICE
 +M:    Jithu Joseph <jithu.joseph@intel.com>
 +R:    Ashok Raj <ashok.raj@intel.com>
 +R:    Tony Luck <tony.luck@intel.com>
 +S:    Maintained
 +F:    drivers/platform/x86/intel/ifs
 +F:    include/trace/events/intel_ifs.h
 +
  INTEL INTEGRATED SENSOR HUB DRIVER
  M:    Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
  M:    Jiri Kosina <jikos@kernel.org>
@@@ -10081,7 -9984,6 +10081,7 @@@ S:    Supporte
  F:    Documentation/driver-api/mei/*
  F:    drivers/misc/mei/
  F:    drivers/watchdog/mei_wdt.c
 +F:    include/linux/mei_aux.h
  F:    include/linux/mei_cl_bus.h
  F:    include/uapi/linux/mei.h
  F:    samples/mei/*
@@@ -10120,7 -10022,7 +10120,7 @@@ F:   drivers/platform/x86/intel/pmc
  
  INTEL PMIC GPIO DRIVERS
  M:    Andy Shevchenko <andy@kernel.org>
 -S:    Maintained
 +S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git
  F:    drivers/gpio/gpio-*cove.c
  
@@@ -10226,7 -10128,7 +10226,7 @@@ S:   Supporte
  F:    drivers/net/wireless/intel/iwlegacy/
  
  INTEL WIRELESS WIFI LINK (iwlwifi)
 -M:    Luca Coelho <luciano.coelho@intel.com>
 +M:    Gregory Greenman <gregory.greenman@intel.com>
  L:    linux-wireless@vger.kernel.org
  S:    Supported
  W:    https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi
@@@ -10335,6 -10237,8 +10335,6 @@@ F:   drivers/net/ethernet/sgi/ioc3-eth.
  IOMAP FILESYSTEM LIBRARY
  M:    Christoph Hellwig <hch@infradead.org>
  M:    Darrick J. Wong <djwong@kernel.org>
 -M:    linux-xfs@vger.kernel.org
 -M:    linux-fsdevel@vger.kernel.org
  L:    linux-xfs@vger.kernel.org
  L:    linux-fsdevel@vger.kernel.org
  S:    Supported
@@@ -10643,7 -10547,6 +10643,7 @@@ M:   Andrey Ryabinin <ryabinin.a.a@gmail.
  R:    Alexander Potapenko <glider@google.com>
  R:    Andrey Konovalov <andreyknvl@gmail.com>
  R:    Dmitry Vyukov <dvyukov@google.com>
 +R:    Vincenzo Frascino <vincenzo.frascino@arm.com>
  L:    kasan-dev@googlegroups.com
  S:    Maintained
  F:    Documentation/dev-tools/kasan.rst
@@@ -10862,8 -10765,6 +10862,8 @@@ T:   git git://github.com/kvm-riscv/linux
  F:    arch/riscv/include/asm/kvm*
  F:    arch/riscv/include/uapi/asm/kvm*
  F:    arch/riscv/kvm/
 +F:    tools/testing/selftests/kvm/*/riscv/
 +F:    tools/testing/selftests/kvm/riscv/
  
  KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
  M:    Christian Borntraeger <borntraeger@linux.ibm.com>
@@@ -10878,12 -10779,9 +10878,12 @@@ F: Documentation/virt/kvm/s390
  F:    arch/s390/include/asm/gmap.h
  F:    arch/s390/include/asm/kvm*
  F:    arch/s390/include/uapi/asm/kvm*
 +F:    arch/s390/include/uapi/asm/uvdevice.h
  F:    arch/s390/kernel/uv.c
  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/
  
@@@ -10956,15 -10854,6 +10956,15 @@@ S: Supporte
  F:    include/keys/trusted_tee.h
  F:    security/keys/trusted-keys/trusted_tee.c
  
 +KEYS-TRUSTED-CAAM
 +M:    Ahmad Fatoum <a.fatoum@pengutronix.de>
 +R:    Pengutronix Kernel Team <kernel@pengutronix.de>
 +L:    linux-integrity@vger.kernel.org
 +L:    keyrings@vger.kernel.org
 +S:    Maintained
 +F:    include/keys/trusted_caam.h
 +F:    security/keys/trusted-keys/trusted_caam.c
 +
  KEYS/KEYRINGS
  M:    David Howells <dhowells@redhat.com>
  M:    Jarkko Sakkinen <jarkko@kernel.org>
@@@ -11019,7 -10908,6 +11019,7 @@@ F:   drivers/tty/serial/kgdboc.
  F:    include/linux/kdb.h
  F:    include/linux/kgdb.h
  F:    kernel/debug/
 +F:    kernel/module/kdb.c
  
  KHADAS MCU MFD DRIVER
  M:    Neil Armstrong <narmstrong@baylibre.com>
@@@ -11321,7 -11209,7 +11321,7 @@@ F:   scripts/spdxcheck.p
  
  LINEAR RANGES HELPERS
  M:    Mark Brown <broonie@kernel.org>
 -R:    Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
 +R:    Matti Vaittinen <mazziesaccount@gmail.com>
  F:    lib/linear_ranges.c
  F:    lib/test_linear_ranges.c
  F:    include/linux/linear_range.h
@@@ -11458,7 -11346,7 +11458,7 @@@ F:   drivers/mmc/host/litex_mmc.
  N:    litex
  
  LIVE PATCHING
 -M:    Josh Poimboeuf <jpoimboe@redhat.com>
 +M:    Josh Poimboeuf <jpoimboe@kernel.org>
  M:    Jiri Kosina <jikos@kernel.org>
  M:    Miroslav Benes <mbenes@suse.cz>
  M:    Petr Mladek <pmladek@suse.com>
@@@ -11469,9 -11357,10 +11469,9 @@@ T:  git git://git.kernel.org/pub/scm/lin
  F:    Documentation/ABI/testing/sysfs-kernel-livepatch
  F:    Documentation/livepatch/
  F:    arch/powerpc/include/asm/livepatch.h
 -F:    arch/s390/include/asm/livepatch.h
 -F:    arch/x86/include/asm/livepatch.h
  F:    include/linux/livepatch.h
  F:    kernel/livepatch/
 +F:    kernel/module/livepatch.c
  F:    lib/livepatch/
  F:    samples/livepatch/
  F:    tools/testing/selftests/livepatch/
@@@ -11577,16 -11466,6 +11577,16 @@@ S: Maintaine
  F:    Documentation/devicetree/bindings/display/bridge/lontium,lt8912b.yaml
  F:    drivers/gpu/drm/bridge/lontium-lt8912b.c
  
 +LOONGARCH
 +M:    Huacai Chen <chenhuacai@kernel.org>
 +R:    WANG Xuerui <kernel@xen0n.name>
 +S:    Maintained
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git
 +F:    arch/loongarch/
 +F:    drivers/*/*loongarch*
 +F:    Documentation/loongarch/
 +F:    Documentation/translations/zh_CN/loongarch/
 +
  LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
  M:    Sathya Prakash <sathya.prakash@broadcom.com>
  M:    Sreekanth Reddy <sreekanth.reddy@broadcom.com>
@@@ -11947,16 -11826,9 +11947,16 @@@ MARVELL XENON MMC/SD/SDIO HOST CONTROLL
  M:    Hu Ziji <huziji@marvell.com>
  L:    linux-mmc@vger.kernel.org
  S:    Supported
 -F:    Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt
 +F:    Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml
  F:    drivers/mmc/host/sdhci-xenon*
  
 +MARVELL OCTEON ENDPOINT DRIVER
 +M:    Veerasenareddy Burru <vburru@marvell.com>
 +M:    Abhijit Ayarekar <aayarekar@marvell.com>
 +L:    netdev@vger.kernel.org
 +S:    Supported
 +F:    drivers/net/ethernet/marvell/octeon_ep
 +
  MATROX FRAMEBUFFER DRIVER
  L:    linux-fbdev@vger.kernel.org
  S:    Orphan
@@@ -12034,7 -11906,7 +12034,7 @@@ F:   drivers/iio/proximity/mb1232.
  
  MAXIM MAX17040 FAMILY FUEL GAUGE DRIVERS
  R:    Iskren Chernev <iskren.chernev@gmail.com>
 -R:    Krzysztof Kozlowski <krzk@kernel.org>
 +R:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  R:    Marek Szyprowski <m.szyprowski@samsung.com>
  R:    Matheus Castello <matheus@castello.eng.br>
  L:    linux-pm@vger.kernel.org
@@@ -12044,7 -11916,7 +12044,7 @@@ F:   drivers/power/supply/max17040_batter
  
  MAXIM MAX17042 FAMILY FUEL GAUGE DRIVERS
  R:    Hans de Goede <hdegoede@redhat.com>
 -R:    Krzysztof Kozlowski <krzk@kernel.org>
 +R:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  R:    Marek Szyprowski <m.szyprowski@samsung.com>
  R:    Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
  R:    Purism Kernel Team <kernel@puri.sm>
@@@ -12096,11 -11968,10 +12096,11 @@@ F:        Documentation/devicetree/bindings/po
  F:    drivers/power/supply/max77976_charger.c
  
  MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  M:    Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
  L:    linux-pm@vger.kernel.org
  S:    Supported
 +B:    mailto:linux-samsung-soc@vger.kernel.org
  F:    Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
  F:    Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
  F:    drivers/power/supply/max14577_charger.c
@@@ -12108,11 -11979,10 +12108,11 @@@ F:        drivers/power/supply/max77693_charge
  
  MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS
  M:    Chanwoo Choi <cw00.choi@samsung.com>
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  M:    Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
  L:    linux-kernel@vger.kernel.org
  S:    Supported
 +B:    mailto:linux-samsung-soc@vger.kernel.org
  F:    Documentation/devicetree/bindings/*/maxim,max14577.yaml
  F:    Documentation/devicetree/bindings/*/maxim,max77686.yaml
  F:    Documentation/devicetree/bindings/*/maxim,max77693.yaml
@@@ -12282,7 -12152,7 +12282,7 @@@ T:   git git://linuxtv.org/media_tree.gi
  F:    Documentation/admin-guide/media/imx7.rst
  F:    Documentation/devicetree/bindings/media/nxp,imx-mipi-csi2.yaml
  F:    Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml
 -F:    drivers/media/platform/imx/imx-mipi-csis.c
 +F:    drivers/media/platform/nxp/imx-mipi-csis.c
  F:    drivers/staging/media/imx/imx7-media-csi.c
  
  MEDIA DRIVERS FOR HELENE
@@@ -12337,7 -12207,7 +12337,7 @@@ L:   linux-media@vger.kernel.or
  L:    linux-tegra@vger.kernel.org
  S:    Maintained
  T:    git git://linuxtv.org/media_tree.git
 -F:    Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
 +F:    Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
  F:    drivers/media/platform/nvidia/tegra-vde/
  
  MEDIA DRIVERS FOR RENESAS - CEU
@@@ -12487,7 -12357,7 +12487,7 @@@ MEDIATEK I2C CONTROLLER DRIVE
  M:    Qii Wang <qii.wang@mediatek.com>
  L:    linux-i2c@vger.kernel.org
  S:    Maintained
 -F:    Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
 +F:    Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml
  F:    drivers/i2c/busses/i2c-mt65xx.c
  
  MEDIATEK IOMMU DRIVER
@@@ -12500,9 -12370,10 +12500,9 @@@ F:  drivers/iommu/mtk_iommu
  F:    include/dt-bindings/memory/mt*-port.h
  
  MEDIATEK JPEG DRIVER
 -M:    Rick Chang <rick.chang@mediatek.com>
  M:    Bin Liu <bin.liu@mediatek.com>
  S:    Supported
 -F:    Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
 +F:    Documentation/devicetree/bindings/media/mediatek-jpeg-*.yaml
  F:    drivers/media/platform/mediatek/jpeg/
  
  MEDIATEK MDP DRIVER
@@@ -12518,7 -12389,7 +12518,7 @@@ MEDIATEK MEDIA DRIVE
  M:    Tiffany Lin <tiffany.lin@mediatek.com>
  M:    Andrew-CT Chen <andrew-ct.chen@mediatek.com>
  S:    Supported
 -F:    Documentation/devicetree/bindings/media/mediatek-vcodec.txt
 +F:    Documentation/devicetree/bindings/media/mediatek,vcodec*.yaml
  F:    Documentation/devicetree/bindings/media/mediatek-vpu.txt
  F:    drivers/media/platform/mediatek/vcodec/
  F:    drivers/media/platform/mediatek/vpu/
@@@ -12531,7 -12402,7 +12531,7 @@@ F:   drivers/mmc/host/mtk-sd.
  
  MEDIATEK MT76 WIRELESS LAN DRIVER
  M:    Felix Fietkau <nbd@nbd.name>
 -M:    Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
 +M:    Lorenzo Bianconi <lorenzo@kernel.org>
  M:    Ryder Lee <ryder.lee@mediatek.com>
  R:    Shayne Chen <shayne.chen@mediatek.com>
  R:    Sean Wang <sean.wang@mediatek.com>
@@@ -12605,17 -12476,6 +12605,17 @@@ S: Maintaine
  F:    drivers/net/dsa/mt7530.*
  F:    net/dsa/tag_mtk.c
  
 +MEDIATEK T7XX 5G WWAN MODEM DRIVER
 +M:    Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
 +M:    Intel Corporation <linuxwwan@intel.com>
 +R:    Chiranjeevi Rapolu <chiranjeevi.rapolu@linux.intel.com>
 +R:    Liu Haijun <haijun.liu@mediatek.com>
 +R:    M Chetan Kumar <m.chetan.kumar@linux.intel.com>
 +R:    Ricardo Martinez <ricardo.martinez@linux.intel.com>
 +L:    netdev@vger.kernel.org
 +S:    Supported
 +F:    drivers/net/wwan/t7xx/
 +
  MEDIATEK USB3 DRD IP DRIVER
  M:    Chunfeng Yun <chunfeng.yun@mediatek.com>
  L:    linux-usb@vger.kernel.org
@@@ -12813,10 -12673,9 +12813,10 @@@ F: mm/memblock.
  F:    tools/testing/memblock/
  
  MEMORY CONTROLLER DRIVERS
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
 +B:    mailto:krzysztof.kozlowski@linaro.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git
  F:    Documentation/devicetree/bindings/memory-controllers/
  F:    drivers/memory/
@@@ -12935,7 -12794,7 +12935,7 @@@ F:   arch/arm64/boot/dts/marvell/armada-3
  
  MHI BUS
  M:    Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 -R:    Hemant Kumar <hemantk@codeaurora.org>
 +R:    Hemant Kumar <quic_hemantk@quicinc.com>
  L:    mhi@lists.linux.dev
  L:    linux-arm-msm@vger.kernel.org
  S:    Maintained
@@@ -13045,13 -12904,6 +13045,13 @@@ F: drivers/net/dsa/microchip/
  F:    include/linux/platform_data/microchip-ksz.h
  F:    net/dsa/tag_ksz.c
  
 +MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER
 +M:    Arun Ramadoss <arun.ramadoss@microchip.com>
 +R:    UNGLinuxDriver@microchip.com
 +L:    netdev@vger.kernel.org
 +S:    Maintained
 +F:    drivers/net/phy/microchip_t1.c
 +
  MICROCHIP LAN743X ETHERNET DRIVER
  M:    Bryan Whitehead <bryan.whitehead@microchip.com>
  M:    UNGLinuxDriver@microchip.com
@@@ -13105,7 -12957,7 +13105,7 @@@ M:   Claudiu Beznea <claudiu.beznea@micro
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-pwm@vger.kernel.org
  S:    Supported
 -F:    Documentation/devicetree/bindings/pwm/atmel-pwm.txt
 +F:    Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml
  F:    drivers/pwm/pwm-atmel.c
  
  MICROCHIP SAMA5D2-COMPATIBLE ADC DRIVER
@@@ -13413,7 -13265,7 +13413,7 @@@ L:   linux-kernel@vger.kernel.or
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git modules-next
  F:    include/linux/module.h
 -F:    kernel/module.c
 +F:    kernel/module/
  
  MONOLITHIC POWER SYSTEM PMIC DRIVER
  M:    Saravanan Sekar <sravanhome@gmail.com>
@@@ -13444,7 -13296,7 +13444,7 @@@ F:   drivers/net/phy/motorcomm.
  MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD
  M:    Jiri Slaby <jirislaby@kernel.org>
  S:    Maintained
 -F:    Documentation/driver-api/serial/moxa-smartio.rst
 +F:    Documentation/driver-api/tty/moxa-smartio.rst
  F:    drivers/tty/mxser.*
  
  MR800 AVERMEDIA USB FM RADIO DRIVER
@@@ -13677,21 -13529,12 +13677,21 @@@ M:        Samuel Mendoza-Jonas <sam@mendozajon
  S:    Maintained
  F:    net/ncsi/
  
 -NCT6775 HARDWARE MONITOR DRIVER
 +NCT6775 HARDWARE MONITOR DRIVER - CORE & PLATFORM DRIVER
  M:    Guenter Roeck <linux@roeck-us.net>
  L:    linux-hwmon@vger.kernel.org
  S:    Maintained
  F:    Documentation/hwmon/nct6775.rst
 -F:    drivers/hwmon/nct6775.c
 +F:    drivers/hwmon/nct6775-core.c
 +F:    drivers/hwmon/nct6775-platform.c
 +F:    drivers/hwmon/nct6775.h
 +
 +NCT6775 HARDWARE MONITOR DRIVER - I2C DRIVER
 +M:    Zev Weiss <zev@bewilderbeest.net>
 +L:    linux-hwmon@vger.kernel.org
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/hwmon/nuvoton,nct6775.yaml
 +F:    drivers/hwmon/nct6775-i2c.c
  
  NETDEVSIM
  M:    Jakub Kicinski <kuba@kernel.org>
@@@ -13781,7 -13624,6 +13781,7 @@@ F:   net/core/drop_monitor.
  
  NETWORKING DRIVERS
  M:    "David S. Miller" <davem@davemloft.net>
 +M:    Eric Dumazet <edumazet@google.com>
  M:    Jakub Kicinski <kuba@kernel.org>
  M:    Paolo Abeni <pabeni@redhat.com>
  L:    netdev@vger.kernel.org
@@@ -13829,7 -13671,6 +13829,7 @@@ F:   tools/testing/selftests/drivers/net/
  
  NETWORKING [GENERAL]
  M:    "David S. Miller" <davem@davemloft.net>
 +M:    Eric Dumazet <edumazet@google.com>
  M:    Jakub Kicinski <kuba@kernel.org>
  M:    Paolo Abeni <pabeni@redhat.com>
  L:    netdev@vger.kernel.org
@@@ -13924,7 -13765,6 +13924,7 @@@ F:   include/net/mptcp.
  F:    include/trace/events/mptcp.h
  F:    include/uapi/linux/mptcp.h
  F:    net/mptcp/
 +F:    tools/testing/selftests/bpf/*/*mptcp*.c
  F:    tools/testing/selftests/net/mptcp/
  
  NETWORKING [TCP]
@@@ -13977,11 -13817,10 +13977,11 @@@ F:        include/uapi/linux/nexthop.
  F:    net/ipv4/nexthop.c
  
  NFC SUBSYSTEM
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  L:    linux-nfc@lists.01.org (subscribers-only)
  L:    netdev@vger.kernel.org
  S:    Maintained
 +B:    mailto:linux-nfc@lists.01.org
  F:    Documentation/devicetree/bindings/net/nfc/
  F:    drivers/nfc/
  F:    include/linux/platform_data/nfcmrvl.h
@@@ -14295,7 -14134,7 +14295,7 @@@ F:   Documentation/devicetree/bindings/re
  F:    drivers/regulator/pf8x00-regulator.c
  
  NXP PTN5150A CC LOGIC AND EXTCON DRIVER
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  F:    Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml
@@@ -14352,7 -14191,7 +14352,7 @@@ R:   NXP Linux Team <linux-imx@nxp.com
  L:    linux-media@vger.kernel.org
  S:    Maintained
  F:    Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
 -F:    drivers/media/platform/imx-jpeg
 +F:    drivers/media/platform/nxp/imx-jpeg
  
  NZXT-KRAKEN2 HARDWARE MONITORING DRIVER
  M:    Jonas Malaco <jonas@protocubo.io>
@@@ -14377,7 -14216,7 +14377,7 @@@ F:   lib/objagg.
  F:    lib/test_objagg.c
  
  OBJTOOL
 -M:    Josh Poimboeuf <jpoimboe@redhat.com>
 +M:    Josh Poimboeuf <jpoimboe@kernel.org>
  M:    Peter Zijlstra <peterz@infradead.org>
  S:    Supported
  F:    tools/objtool/
@@@ -14525,6 -14364,7 +14525,6 @@@ F:   arch/arm/*omap*/*pm
  F:    drivers/cpufreq/omap-cpufreq.c
  
  OMAP POWERDOMAIN SOC ADAPTATION LAYER SUPPORT
 -M:    Rajendra Nayak <rnayak@codeaurora.org>
  M:    Paul Walmsley <paul@pwsan.com>
  L:    linux-omap@vger.kernel.org
  S:    Maintained
@@@ -14550,7 -14390,6 +14550,7 @@@ F:   arch/arm/boot/dts/am335x-nano.dt
  
  OMAP1 SUPPORT
  M:    Aaro Koskinen <aaro.koskinen@iki.fi>
 +M:    Janusz Krzysztofik <jmkrzyszt@gmail.com>
  M:    Tony Lindgren <tony@atomide.com>
  L:    linux-omap@vger.kernel.org
  S:    Maintained
@@@ -14818,6 -14657,7 +14818,6 @@@ F:   drivers/rtc/rtc-optee.
  
  OPA-VNIC DRIVER
  M:    Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
 -M:    Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
  L:    linux-rdma@vger.kernel.org
  S:    Supported
  F:    drivers/infiniband/ulp/opa_vnic
@@@ -14848,7 -14688,7 +14848,7 @@@ F:   scripts/dtc
  
  OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
  M:    Rob Herring <robh+dt@kernel.org>
 -M:    Krzysztof Kozlowski <krzk+dt@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
  L:    devicetree@vger.kernel.org
  S:    Maintained
  C:    irc://irc.libera.chat/devicetree
@@@ -14986,19 -14826,6 +14986,19 @@@ F: Documentation/core-api/padata.rs
  F:    include/linux/padata.h
  F:    kernel/padata.c
  
 +PAGE CACHE
 +M:    Matthew Wilcox (Oracle) <willy@infradead.org>
 +L:    linux-fsdevel@vger.kernel.org
 +S:    Supported
 +T:    git git://git.infradead.org/users/willy/pagecache.git
 +F:    Documentation/filesystems/locking.rst
 +F:    Documentation/filesystems/vfs.rst
 +F:    include/linux/pagemap.h
 +F:    mm/filemap.c
 +F:    mm/page-writeback.c
 +F:    mm/readahead.c
 +F:    mm/truncate.c
 +
  PAGE POOL
  M:    Jesper Dangaard Brouer <hawk@kernel.org>
  M:    Ilias Apalodimas <ilias.apalodimas@linaro.org>
@@@ -15327,7 -15154,7 +15327,7 @@@ F:   drivers/pci/controller/pci-v3-semi.
  
  PCI ENDPOINT SUBSYSTEM
  M:    Kishon Vijay Abraham I <kishon@ti.com>
 -M:    Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 +M:    Lorenzo Pieralisi <lpieralisi@kernel.org>
  R:    Krzysztof Wilczyński <kw@linux.com>
  L:    linux-pci@vger.kernel.org
  S:    Supported
@@@ -15390,7 -15217,7 +15390,7 @@@ F:   Documentation/devicetree/bindings/pc
  F:    drivers/pci/controller/pci-xgene-msi.c
  
  PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS
 -M:    Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 +M:    Lorenzo Pieralisi <lpieralisi@kernel.org>
  R:    Rob Herring <robh@kernel.org>
  R:    Krzysztof Wilczyński <kw@linux.com>
  L:    linux-pci@vger.kernel.org
@@@ -15531,7 -15358,7 +15531,7 @@@ PCIE DRIVER FOR SOCIONEXT UNIPHIE
  M:    Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
  L:    linux-pci@vger.kernel.org
  S:    Maintained
 -F:    Documentation/devicetree/bindings/pci/uniphier-pcie*
 +F:    Documentation/devicetree/bindings/pci/socionext,uniphier-pcie*
  F:    drivers/pci/controller/dwc/pcie-uniphier*
  
  PCIE DRIVER FOR ST SPEAR13XX
@@@ -15641,8 -15468,7 +15641,8 @@@ F:   tools/perf
  PERFORMANCE EVENTS TOOLING ARM64
  R:    John Garry <john.garry@huawei.com>
  R:    Will Deacon <will@kernel.org>
 -R:    Mathieu Poirier <mathieu.poirier@linaro.org>
 +R:    James Clark <james.clark@arm.com>
 +R:    Mike Leach <mike.leach@linaro.org>
  R:    Leo Yan <leo.yan@linaro.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Supported
@@@ -15774,7 -15600,7 +15774,7 @@@ F:   drivers/pinctrl/renesas
  
  PIN CONTROLLER - SAMSUNG
  M:    Tomasz Figa <tomasz.figa@gmail.com>
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  M:    Sylwester Nawrocki <s.nawrocki@samsung.com>
  R:    Alim Akhtar <alim.akhtar@samsung.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -15782,7 -15608,6 +15782,7 @@@ L:   linux-samsung-soc@vger.kernel.or
  S:    Maintained
  C:    irc://irc.libera.chat/linux-exynos
  Q:    https://patchwork.kernel.org/project/linux-samsung-soc/list/
 +B:    mailto:linux-samsung-soc@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
  F:    Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml
  F:    drivers/pinctrl/samsung/
@@@ -15943,7 -15768,7 +15943,7 @@@ F:   include/linux/dtpm.
  
  POWER STATE COORDINATION INTERFACE (PSCI)
  M:    Mark Rutland <mark.rutland@arm.com>
 -M:    Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 +M:    Lorenzo Pieralisi <lpieralisi@kernel.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    drivers/firmware/psci/
@@@ -16031,9 -15856,7 +16031,9 @@@ F:   kernel/printk
  PRINTK INDEXING
  R:    Chris Down <chris@chrisdown.name>
  S:    Maintained
 +F:    Documentation/core-api/printk-index.rst
  F:    kernel/printk/index.c
 +K:    printk_index
  
  PROC FILESYSTEM
  L:    linux-kernel@vger.kernel.org
@@@ -16137,6 -15960,7 +16137,6 @@@ F:   include/asm-generic/syscall.
  F:    include/linux/ptrace.h
  F:    include/linux/regset.h
  F:    include/uapi/linux/ptrace.h
 -F:    include/uapi/linux/ptrace.h
  F:    kernel/ptrace.c
  
  PULSE8-CEC DRIVER
@@@ -16147,12 -15971,6 +16147,12 @@@ T: git git://linuxtv.org/media_tree.gi
  F:    Documentation/admin-guide/media/pulse8-cec.rst
  F:    drivers/media/cec/usb/pulse8/
  
 +PURELIFI PLFXLC DRIVER
 +M:    Srinivasan Raju <srini.raju@purelifi.com>
 +L:    linux-wireless@vger.kernel.org
 +S:    Supported
 +F:    drivers/net/wireless/purelifi/plfxlc/
 +
  PVRUSB2 VIDEO4LINUX DRIVER
  M:    Mike Isely <isely@pobox.com>
  L:    pvrusb2@isely.net       (subscribers-only)
@@@ -16281,6 -16099,7 +16281,6 @@@ F:   include/uapi/linux/qemu_fw_cfg.
  
  QIB DRIVER
  M:    Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
 -M:    Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
  L:    linux-rdma@vger.kernel.org
  S:    Supported
  F:    drivers/infiniband/hw/qib/
@@@ -16620,7 -16439,6 +16620,7 @@@ S:   Supporte
  T:    git https://gitlab.freedesktop.org/agd5f/linux.git
  B:    https://gitlab.freedesktop.org/drm/amd/-/issues
  C:    irc://irc.oftc.net/radeon
 +F:    Documentation/gpu/amdgpu/
  F:    drivers/gpu/drm/amd/
  F:    drivers/gpu/drm/radeon/
  F:    include/uapi/drm/amdgpu_drm.h
@@@ -16685,13 -16503,6 +16685,13 @@@ L: linux-mips@vger.kernel.or
  S:    Maintained
  F:    arch/mips/boot/dts/ralink/mt7621*
  
 +RALINK PINCTRL DRIVER
 +M:    Arınç ÜNAL <arinc.unal@arinc9.com>
 +M:    Sergio Paracuellos <sergio.paracuellos@gmail.com>
 +L:    linux-mips@vger.kernel.org
 +S:    Maintained
 +F:    drivers/pinctrl/ralink/
 +
  RALINK RT2X00 WIRELESS LAN DRIVER
  M:    Stanislaw Gruszka <stf_xl@wp.pl>
  M:    Helmut Schaa <helmut.schaa@googlemail.com>
@@@ -16806,6 -16617,7 +16806,6 @@@ F:   drivers/net/ethernet/rdc/r6040.
  
  RDMAVT - RDMA verbs software
  M:    Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
 -M:    Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
  L:    linux-rdma@vger.kernel.org
  S:    Supported
  F:    drivers/infiniband/sw/rdmavt
@@@ -17038,14 -16850,6 +17038,14 @@@ S: Supporte
  F:    Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml
  F:    drivers/iio/adc/rzg2l_adc.c
  
 +RENESAS RZ/N1 RTC CONTROLLER DRIVER
 +M:    Miquel Raynal <miquel.raynal@bootlin.com>
 +L:    linux-rtc@vger.kernel.org
 +L:    linux-renesas-soc@vger.kernel.org
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
 +F:    drivers/rtc/rtc-rzn1.c
 +
  RENESAS R-CAR GEN3 & RZ/N1 NAND CONTROLLER DRIVER
  M:    Miquel Raynal <miquel.raynal@bootlin.com>
  L:    linux-mtd@lists.infradead.org
@@@ -17208,7 -17012,8 +17208,7 @@@ S:   Odd Fixe
  F:    drivers/tty/serial/rp2.*
  
  ROHM BD99954 CHARGER IC
 -R:    Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
 -L:    linux-power@fi.rohmeurope.com
 +R:    Matti Vaittinen <mazziesaccount@gmail.com>
  S:    Supported
  F:    drivers/power/supply/bd99954-charger.c
  F:    drivers/power/supply/bd99954-charger.h
@@@ -17231,7 -17036,8 +17231,7 @@@ F:   drivers/regulator/bd9571mwv-regulato
  F:    include/linux/mfd/bd9571mwv.h
  
  ROHM POWER MANAGEMENT IC DEVICE DRIVERS
 -R:    Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
 -L:    linux-power@fi.rohmeurope.com
 +R:    Matti Vaittinen <mazziesaccount@gmail.com>
  S:    Supported
  F:    drivers/clk/clk-bd718x7.c
  F:    drivers/gpio/gpio-bd71815.c
@@@ -17473,7 -17279,7 +17473,7 @@@ W:   http://www.ibm.com/developerworks/li
  F:    drivers/s390/scsi/zfcp_*
  
  S3C ADC BATTERY DRIVER
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  L:    linux-samsung-soc@vger.kernel.org
  S:    Odd Fixes
  F:    drivers/power/supply/s3c_adc_battery.c
@@@ -17518,16 -17324,15 +17518,16 @@@ F:        Documentation/admin-guide/LSM/SafeSe
  F:    security/safesetid/
  
  SAMSUNG AUDIO (ASoC) DRIVERS
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  M:    Sylwester Nawrocki <s.nawrocki@samsung.com>
  L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
  S:    Supported
 +B:    mailto:linux-samsung-soc@vger.kernel.org
  F:    Documentation/devicetree/bindings/sound/samsung*
  F:    sound/soc/samsung/
  
  SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  L:    linux-crypto@vger.kernel.org
  L:    linux-samsung-soc@vger.kernel.org
  S:    Maintained
@@@ -17562,12 -17367,11 +17562,12 @@@ S:        Maintaine
  F:    drivers/platform/x86/samsung-laptop.c
  
  SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  M:    Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
  L:    linux-kernel@vger.kernel.org
  L:    linux-samsung-soc@vger.kernel.org
  S:    Supported
 +B:    mailto:linux-samsung-soc@vger.kernel.org
  F:    Documentation/devicetree/bindings/clock/samsung,s2mps11.yaml
  F:    Documentation/devicetree/bindings/mfd/samsung,s2m*.yaml
  F:    Documentation/devicetree/bindings/mfd/samsung,s5m*.yaml
@@@ -17589,7 -17393,7 +17589,7 @@@ F:   drivers/media/platform/samsung/s3c-c
  F:    include/media/drv-intf/s3c_camif.h
  
  SAMSUNG S3FWRN5 NFC DRIVER
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  M:    Krzysztof Opasiak <k.opasiak@samsung.com>
  L:    linux-nfc@lists.01.org (subscribers-only)
  S:    Maintained
@@@ -17611,7 -17415,7 +17611,7 @@@ S:   Supporte
  F:    drivers/media/i2c/s5k5baf.c
  
  SAMSUNG S5P Security SubSystem (SSS) DRIVER
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  M:    Vladimir Zapolskiy <vz@mleia.com>
  L:    linux-crypto@vger.kernel.org
  L:    linux-samsung-soc@vger.kernel.org
@@@ -17646,7 -17450,7 +17646,7 @@@ F:   include/linux/clk/samsung.
  F:    include/linux/platform_data/clk-s3c2410.h
  
  SAMSUNG SPI DRIVERS
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  M:    Andi Shyti <andi@etezian.org>
  L:    linux-spi@vger.kernel.org
  L:    linux-samsung-soc@vger.kernel.org
@@@ -17664,7 -17468,7 +17664,7 @@@ F:   drivers/net/ethernet/samsung/sxgbe
  
  SAMSUNG THERMAL DRIVER
  M:    Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
 -M:    Krzysztof Kozlowski <krzk@kernel.org>
 +M:    Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  L:    linux-pm@vger.kernel.org
  L:    linux-samsung-soc@vger.kernel.org
  S:    Maintained
@@@ -17705,7 -17509,6 +17705,7 @@@ R:   Steven Rostedt <rostedt@goodmis.org
  R:    Ben Segall <bsegall@google.com> (CONFIG_CFS_BANDWIDTH)
  R:    Mel Gorman <mgorman@suse.de> (CONFIG_NUMA_BALANCING)
  R:    Daniel Bristot de Oliveira <bristot@redhat.com> (SCHED_DEADLINE)
 +R:    Valentin Schneider <vschneid@redhat.com> (TOPOLOGY)
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched/core
@@@ -17755,6 -17558,7 +17755,7 @@@ T:   git git://git.kernel.org/pub/scm/lin
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
  F:    Documentation/devicetree/bindings/scsi/
  F:    drivers/scsi/
+ F:    drivers/ufs/
  F:    include/scsi/
  
  SCSI TAPE DRIVER
@@@ -17849,8 -17653,8 +17850,8 @@@ K:   \bTIF_SECCOMP\
  
  SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) Broadcom BRCMSTB DRIVER
  M:    Al Cooper <alcooperx@gmail.com>
 +R:    Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
  L:    linux-mmc@vger.kernel.org
 -L:    bcm-kernel-feedback-list@broadcom.com
  S:    Maintained
  F:    drivers/mmc/host/sdhci-brcmstb*
  
@@@ -18180,8 -17984,8 +18181,8 @@@ F:   drivers/platform/x86/touchscreen_dmi
  SILICON LABS WIRELESS DRIVERS (for WFxxx series)
  M:    Jérôme Pouiller <jerome.pouiller@silabs.com>
  S:    Supported
 -F:    Documentation/devicetree/bindings/staging/net/wireless/silabs,wfx.yaml
 -F:    drivers/staging/wfx/
 +F:    Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml
 +F:    drivers/net/wireless/silabs/wfx/
  
  SILICON MOTION SM712 FRAME BUFFER DRIVER
  M:    Sudip Mukherjee <sudipm.mukherjee@gmail.com>
@@@ -18294,7 -18098,6 +18295,7 @@@ M:   Joonsoo Kim <iamjoonsoo.kim@lge.com
  M:    Andrew Morton <akpm@linux-foundation.org>
  M:    Vlastimil Babka <vbabka@suse.cz>
  R:    Roman Gushchin <roman.gushchin@linux.dev>
 +R:    Hyeonggon Yoo <42.hyeyoo@gmail.com>
  L:    linux-mm@kvack.org
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git
@@@ -18330,7 -18133,7 +18331,7 @@@ F:   drivers/net/ethernet/smsc/smc91x.
  
  SECURE MONITOR CALL(SMC) CALLING CONVENTION (SMCCC)
  M:    Mark Rutland <mark.rutland@arm.com>
 -M:    Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 +M:    Lorenzo Pieralisi <lpieralisi@kernel.org>
  M:    Sudeep Holla <sudeep.holla@arm.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
@@@ -18827,7 -18630,7 +18828,7 @@@ S:   Maintaine
  F:    arch/alpha/kernel/srm_env.c
  
  ST LSM6DSx IMU IIO DRIVER
 -M:    Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
 +M:    Lorenzo Bianconi <lorenzo@kernel.org>
  L:    linux-iio@vger.kernel.org
  S:    Maintained
  W:    http://www.st.com/
@@@ -18984,7 -18787,7 +18985,7 @@@ F:   include/dt-bindings/reset/starfive-j
  
  STATIC BRANCH/CALL
  M:    Peter Zijlstra <peterz@infradead.org>
 -M:    Josh Poimboeuf <jpoimboe@redhat.com>
 +M:    Josh Poimboeuf <jpoimboe@kernel.org>
  M:    Jason Baron <jbaron@akamai.com>
  R:    Steven Rostedt <rostedt@goodmis.org>
  R:    Ard Biesheuvel <ardb@kernel.org>
@@@ -19068,26 -18871,12 +19069,26 @@@ L:        netdev@vger.kernel.or
  S:    Maintained
  F:    drivers/net/ethernet/dlink/sundance.c
  
 +SUNPLUS ETHERNET DRIVER
 +M:    Wells Lu <wellslutw@gmail.com>
 +L:    netdev@vger.kernel.org
 +S:    Maintained
 +W:    https://sunplus.atlassian.net/wiki/spaces/doc/overview
 +F:    Documentation/devicetree/bindings/net/sunplus,sp7021-emac.yaml
 +F:    drivers/net/ethernet/sunplus/
 +
  SUNPLUS OCOTP DRIVER
  M:    Vincent Shih <vincent.sunplus@gmail.com>
  S:    Maintained
  F:    Documentation/devicetree/bindings/nvmem/sunplus,sp7021-ocotp.yaml
  F:    drivers/nvmem/sunplus-ocotp.c
  
 +SUNPLUS PWM DRIVER
 +M:    Hammer Hsieh <hammerh0314@gmail.com>
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/pwm/sunplus,sp7021-pwm.yaml
 +F:    drivers/pwm/pwm-sunplus.c
 +
  SUNPLUS RTC DRIVER
  M:    Vincent Shih <vincent.sunplus@gmail.com>
  L:    linux-rtc@vger.kernel.org
@@@ -19108,13 -18897,6 +19109,13 @@@ S: Maintaine
  F:    Documentation/devicetree/bindings/serial/sunplus,sp7021-uart.yaml
  F:    drivers/tty/serial/sunplus-uart.c
  
 +SUNPLUS WATCHDOG DRIVER
 +M:    Xiantao Hu <xt.hu@cqplus1.com>
 +L:    linux-watchdog@vger.kernel.org
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/watchdog/sunplus,sp7021-wdt.yaml
 +F:    drivers/watchdog/sunplus_wdt.c
 +
  SUPERH
  M:    Yoshinori Sato <ysato@users.sourceforge.jp>
  M:    Rich Felker <dalias@libc.org>
@@@ -19260,7 -19042,6 +19261,7 @@@ SYNOPSYS DESIGNWARE DMAC DRIVE
  M:    Viresh Kumar <vireshk@kernel.org>
  R:    Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  S:    Maintained
 +F:    Documentation/devicetree/bindings/dma/renesas,rzn1-dmamux.yaml
  F:    Documentation/devicetree/bindings/dma/snps,dma-spear1340.yaml
  F:    drivers/dma/dw/
  F:    include/dt-bindings/dma/dw-dmac.h
@@@ -19755,7 -19536,6 +19756,7 @@@ F:   drivers/thermal
  F:    include/linux/cpu_cooling.h
  F:    include/linux/thermal.h
  F:    include/uapi/linux/thermal.h
 +F:    tools/lib/thermal/
  F:    tools/thermal/
  
  THERMAL DRIVER FOR AMLOGIC SOCS
@@@ -20008,7 -19788,7 +20009,7 @@@ F:   drivers/net/wireless/ti
  F:    include/linux/wl12xx.h
  
  TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
 -M:    John Stultz <john.stultz@linaro.org>
 +M:    John Stultz <jstultz@google.com>
  M:    Thomas Gleixner <tglx@linutronix.de>
  R:    Stephen Boyd <sboyd@kernel.org>
  L:    linux-kernel@vger.kernel.org
@@@ -20055,7 -19835,6 +20056,7 @@@ F:   drivers/media/usb/tm6000
  TMIO/SDHI MMC DRIVER
  M:    Wolfram Sang <wsa+renesas@sang-engineering.com>
  L:    linux-mmc@vger.kernel.org
 +L:    linux-renesas-soc@vger.kernel.org
  S:    Supported
  F:    drivers/mmc/host/renesas_sdhi*
  F:    drivers/mmc/host/tmio_mmc*
@@@ -20065,7 -19844,6 +20066,7 @@@ TMP401 HARDWARE MONITOR DRIVE
  M:    Guenter Roeck <linux@roeck-us.net>
  L:    linux-hwmon@vger.kernel.org
  S:    Maintained
 +F:    Documentation/devicetree/bindings/hwmon/ti,tmp401.yaml
  F:    Documentation/hwmon/tmp401.rst
  F:    drivers/hwmon/tmp401.c
  
@@@ -20179,8 -19957,8 +20180,8 @@@ M:   Ingo Molnar <mingo@redhat.com
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
  F:    Documentation/trace/ftrace.rst
 -F:    arch/*/*/*/ftrace.h
 -F:    arch/*/kernel/ftrace.c
 +F:    arch/*/*/*/*ftrace*
 +F:    arch/*/*/*ftrace*
  F:    fs/tracefs/
  F:    include/*/ftrace.h
  F:    include/linux/trace*.h
@@@ -20411,27 -20189,36 +20412,28 @@@ F:        drivers/cdrom/cdrom.
  F:    include/linux/cdrom.h
  F:    include/uapi/linux/cdrom.h
  
 -UNISYS S-PAR DRIVERS
 -M:    David Kershner <david.kershner@unisys.com>
 -L:    sparmaintainer@unisys.com (Unisys internal)
 -S:    Supported
 -F:    drivers/staging/unisys/
 -F:    drivers/visorbus/
 -F:    include/linux/visorbus.h
 -
  UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER
  R:    Alim Akhtar <alim.akhtar@samsung.com>
  R:    Avri Altman <avri.altman@wdc.com>
+ R:    Bart Van Assche <bvanassche@acm.org>
  L:    linux-scsi@vger.kernel.org
  S:    Supported
  F:    Documentation/devicetree/bindings/ufs/
  F:    Documentation/scsi/ufs.rst
- F:    drivers/scsi/ufs/
+ F:    drivers/ufs/core/
  
  UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER DWC HOOKS
  M:    Pedro Sousa <pedrom.sousa@synopsys.com>
  L:    linux-scsi@vger.kernel.org
  S:    Supported
- F:    drivers/scsi/ufs/*dwc*
+ F:    drivers/ufs/host/*dwc*
  
  UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER MEDIATEK HOOKS
  M:    Stanley Chu <stanley.chu@mediatek.com>
  L:    linux-scsi@vger.kernel.org
  L:    linux-mediatek@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
- F:    drivers/scsi/ufs/ufs-mediatek*
+ F:    drivers/ufs/host/ufs-mediatek*
  
  UNSORTED BLOCK IMAGES (UBI)
  M:    Richard Weinberger <richard@nod.at>
@@@ -20741,6 -20528,7 +20743,6 @@@ F:   drivers/usb/host/uhci
  
  USB VIDEO CLASS
  M:    Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 -L:    linux-uvc-devel@lists.sourceforge.net (subscribers-only)
  L:    linux-media@vger.kernel.org
  S:    Maintained
  W:    http://www.ideasonboard.org/uvc/
@@@ -21079,7 -20867,6 +21081,7 @@@ F:   include/uapi/linux/virtio_crypto.
  VIRTIO DRIVERS FOR S390
  M:    Cornelia Huck <cohuck@redhat.com>
  M:    Halil Pasic <pasic@linux.ibm.com>
 +M:    Eric Farman <farman@linux.ibm.com>
  L:    linux-s390@vger.kernel.org
  L:    virtualization@lists.linux-foundation.org
  L:    kvm@vger.kernel.org
@@@ -21230,7 -21017,7 +21232,7 @@@ L:   linux-kernel@vger.kernel.or
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
  F:    Documentation/driver-api/vme.rst
 -F:    drivers/staging/vme/
 +F:    drivers/staging/vme_user/
  F:    drivers/vme/
  F:    include/linux/vme*
  
@@@ -21334,7 -21121,7 +21336,7 @@@ F:   include/linux/regulator
  K:    regulator_get_optional
  
  VOLTAGE AND CURRENT REGULATOR IRQ HELPERS
 -R:    Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
 +R:    Matti Vaittinen <mazziesaccount@gmail.com>
  F:    drivers/regulator/irq_helpers.c
  
  VRF
@@@ -21447,8 -21234,10 +21449,8 @@@ S:  Maintaine
  F:    drivers/hid/hid-wiimote*
  
  WILOCITY WIL6210 WIRELESS DRIVER
 -M:    Maya Erez <merez@codeaurora.org>
  L:    linux-wireless@vger.kernel.org
 -L:    wil6210@qti.qualcomm.com
 -S:    Supported
 +S:    Orphan
  W:    https://wireless.wiki.kernel.org/en/users/Drivers/wil6210
  F:    drivers/net/wireless/ath/wil6210/
  
@@@ -21652,15 -21441,6 +21654,15 @@@ F: arch/x86/include/asm/uv
  F:    arch/x86/kernel/apic/x2apic_uv_x.c
  F:    arch/x86/platform/uv/
  
 +X86 STACK UNWINDING
 +M:    Josh Poimboeuf <jpoimboe@kernel.org>
 +M:    Peter Zijlstra <peterz@infradead.org>
 +S:    Supported
 +F:    arch/x86/include/asm/unwind*.h
 +F:    arch/x86/kernel/dumpstack.c
 +F:    arch/x86/kernel/stacktrace.c
 +F:    arch/x86/kernel/unwind_*.c
 +
  X86 VDSO
  M:    Andy Lutomirski <luto@kernel.org>
  L:    linux-kernel@vger.kernel.org
@@@ -21719,7 -21499,6 +21721,7 @@@ K:   (?:\b|_)xdp(?:\b|_
  XDP SOCKETS (AF_XDP)
  M:    Björn Töpel <bjorn@kernel.org>
  M:    Magnus Karlsson <magnus.karlsson@intel.com>
 +M:    Maciej Fijalkowski <maciej.fijalkowski@intel.com>
  R:    Jonathan Lemon <jonathan.lemon@gmail.com>
  L:    netdev@vger.kernel.org
  L:    bpf@vger.kernel.org
@@@ -21756,29 -21535,23 +21758,29 @@@ F:        arch/arm64/include/asm/xen
  F:    arch/arm64/xen/
  
  XEN HYPERVISOR INTERFACE
 -M:    Boris Ostrovsky <boris.ostrovsky@oracle.com>
  M:    Juergen Gross <jgross@suse.com>
 -R:    Stefano Stabellini <sstabellini@kernel.org>
 +M:    Stefano Stabellini <sstabellini@kernel.org>
 +R:    Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
  L:    xen-devel@lists.xenproject.org (moderated for non-subscribers)
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git
  F:    Documentation/ABI/stable/sysfs-hypervisor-xen
  F:    Documentation/ABI/testing/sysfs-hypervisor-xen
 -F:    arch/x86/include/asm/pvclock-abi.h
 -F:    arch/x86/include/asm/xen/
 -F:    arch/x86/platform/pvh/
 -F:    arch/x86/xen/
  F:    drivers/*/xen-*front.c
  F:    drivers/xen/
  F:    include/uapi/xen/
  F:    include/xen/
  
 +XEN HYPERVISOR X86
 +M:    Juergen Gross <jgross@suse.com>
 +R:    Boris Ostrovsky <boris.ostrovsky@oracle.com>
 +L:    xen-devel@lists.xenproject.org (moderated for non-subscribers)
 +S:    Supported
 +F:    arch/x86/include/asm/pvclock-abi.h
 +F:    arch/x86/include/asm/xen/
 +F:    arch/x86/platform/pvh/
 +F:    arch/x86/xen/
 +
  XEN NETWORK BACKEND DRIVER
  M:    Wei Liu <wei.liu@kernel.org>
  M:    Paul Durrant <paul@xen.org>
@@@ -21830,6 -21603,7 +21832,6 @@@ F:   drivers/xen/*swiotlb
  XFS FILESYSTEM
  C:    irc://irc.oftc.net/xfs
  M:    Darrick J. Wong <djwong@kernel.org>
 -M:    linux-xfs@vger.kernel.org
  L:    linux-xfs@vger.kernel.org
  S:    Supported
  W:    http://xfs.org/
@@@ -21859,7 -21633,7 +21861,7 @@@ M:   Appana Durga Kedareswara rao <appana
  R:    Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
  L:    linux-can@vger.kernel.org
  S:    Maintained
 -F:    Documentation/devicetree/bindings/net/can/xilinx_can.txt
 +F:    Documentation/devicetree/bindings/net/can/xilinx,can.yaml
  F:    drivers/net/can/xilinx_can.c
  
  XILINX GPIO DRIVER
@@@ -21883,12 -21657,6 +21885,12 @@@ F: drivers/misc/Makefil
  F:    drivers/misc/xilinx_sdfec.c
  F:    include/uapi/misc/xilinx_sdfec.h
  
 +XILINX PWM DRIVER
 +M:    Sean Anderson <sean.anderson@seco.com>
 +S:    Maintained
 +F:    drivers/pwm/pwm-xilinx.c
 +F:    include/clocksource/timer-xilinx.h
 +
  XILINX UARTLITE SERIAL DRIVER
  M:    Peter Korsgaard <jacmet@sunsite.dk>
  L:    linux-serial@vger.kernel.org
diff --combined drivers/Kconfig
index 38af943294cafa3fd4398fe6fdf35bdff63407f7,a7ec388e18485d32f675854ccefbbe5f75dcc14c..b6a172d32a7d378bc398ddeed819a0b8688a9abc
@@@ -107,6 -107,8 +107,8 @@@ source "drivers/usb/Kconfig
  
  source "drivers/mmc/Kconfig"
  
+ source "drivers/ufs/Kconfig"
  source "drivers/memstick/Kconfig"
  
  source "drivers/leds/Kconfig"
@@@ -225,6 -227,8 +227,6 @@@ source "drivers/mux/Kconfig
  
  source "drivers/opp/Kconfig"
  
 -source "drivers/visorbus/Kconfig"
 -
  source "drivers/siox/Kconfig"
  
  source "drivers/slimbus/Kconfig"
@@@ -237,6 -241,4 +239,6 @@@ source "drivers/most/Kconfig
  
  source "drivers/peci/Kconfig"
  
 +source "drivers/hte/Kconfig"
 +
  endmenu
diff --combined drivers/Makefile
index 091627d6099100665dc12a4750aac50d2ac6a0cc,8b4b90202e58a5badf819977a23bd3f4a6a18bbe..9a30842b22c5411bf00245761f472da9c13370b7
@@@ -72,9 -72,9 +72,9 @@@ obj-$(CONFIG_PARPORT)         += parport
  obj-y                         += base/ block/ misc/ mfd/ nfc/
  obj-$(CONFIG_LIBNVDIMM)               += nvdimm/
  obj-$(CONFIG_DAX)             += dax/
 -obj-$(CONFIG_CXL_BUS)         += cxl/
  obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/
  obj-$(CONFIG_NUBUS)           += nubus/
 +obj-y                         += cxl/
  obj-y                         += macintosh/
  obj-y                         += scsi/
  obj-y                         += nvme/
@@@ -128,6 -128,7 +128,7 @@@ obj-$(CONFIG_PM_OPP)               += opp
  obj-$(CONFIG_CPU_FREQ)                += cpufreq/
  obj-$(CONFIG_CPU_IDLE)                += cpuidle/
  obj-y                         += mmc/
+ obj-y                         += ufs/
  obj-$(CONFIG_MEMSTICK)                += memstick/
  obj-$(CONFIG_NEW_LEDS)                += leds/
  obj-$(CONFIG_INFINIBAND)      += infiniband/
@@@ -181,10 -182,10 +182,10 @@@ obj-$(CONFIG_FPGA)              += fpga
  obj-$(CONFIG_FSI)             += fsi/
  obj-$(CONFIG_TEE)             += tee/
  obj-$(CONFIG_MULTIPLEXER)     += mux/
 -obj-$(CONFIG_UNISYS_VISORBUS) += visorbus/
  obj-$(CONFIG_SIOX)            += siox/
  obj-$(CONFIG_GNSS)            += gnss/
  obj-$(CONFIG_INTERCONNECT)    += interconnect/
  obj-$(CONFIG_COUNTER)         += counter/
  obj-$(CONFIG_MOST)            += most/
  obj-$(CONFIG_PECI)            += peci/
 +obj-$(CONFIG_HTE)             += hte/
diff --combined drivers/nvme/host/fc.c
index 7ae72c7a211b975ecba3009cb337211dbacbee5d,05f9da251758f27e98c4f83bf4dbe348d15e6d0e..3c778bb0c2944725ad321c5b5a33df33d516eabf
@@@ -1899,6 -1899,24 +1899,24 @@@ nvme_fc_ctrl_ioerr_work(struct work_str
        nvme_fc_error_recovery(ctrl, "transport detected io error");
  }
  
+ /*
+  * nvme_fc_io_getuuid - Routine called to get the appid field
+  * associated with request by the lldd
+  * @req:IO request from nvme fc to driver
+  * Returns: UUID if there is an appid associated with VM or
+  * NULL if the user/libvirt has not set the appid to VM
+  */
+ char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req)
+ {
+       struct nvme_fc_fcp_op *op = fcp_req_to_fcp_op(req);
+       struct request *rq = op->rq;
+       if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq->bio)
+               return NULL;
+       return blkcg_get_fc_appid(rq->bio);
+ }
+ EXPORT_SYMBOL_GPL(nvme_fc_io_getuuid);
  static void
  nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)
  {
@@@ -3831,9 -3849,6 +3849,9 @@@ process_local_list
        return count;
  }
  
 +static DEVICE_ATTR(nvme_discovery, 0200, NULL, nvme_fc_nvme_discovery_store);
 +
 +#ifdef CONFIG_BLK_CGROUP_FC_APPID
  /* Parse the cgroup id from a buf and return the length of cgrpid */
  static int fc_parse_cgrpid(const char *buf, u64 *id)
  {
  }
  
  /*
 - * fc_update_appid: Parse and update the appid in the blkcg associated with
 - * cgroupid.
 - * @buf: buf contains both cgrpid and appid info
 - * @count: size of the buffer
 + * Parse and update the appid in the blkcg associated with the cgroupid.
   */
 -static int fc_update_appid(const char *buf, size_t count)
 +static ssize_t fc_appid_store(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t count)
  {
        u64 cgrp_id;
        int appid_len = 0;
                return ret;
        return count;
  }
 -
 -static ssize_t fc_appid_store(struct device *dev,
 -              struct device_attribute *attr, const char *buf, size_t count)
 -{
 -      int ret  = 0;
 -
 -      ret = fc_update_appid(buf, count);
 -      if (ret < 0)
 -              return -EINVAL;
 -      return count;
 -}
 -static DEVICE_ATTR(nvme_discovery, 0200, NULL, nvme_fc_nvme_discovery_store);
  static DEVICE_ATTR(appid_store, 0200, NULL, fc_appid_store);
 +#endif /* CONFIG_BLK_CGROUP_FC_APPID */
  
  static struct attribute *nvme_fc_attrs[] = {
        &dev_attr_nvme_discovery.attr,
 +#ifdef CONFIG_BLK_CGROUP_FC_APPID
        &dev_attr_appid_store.attr,
 +#endif
        NULL
  };
  
index 3b8afa9d305690267b6ae20615340794d95aa91e,f5f4409e24cd6cc3347b7ade668696f0131a4634..d439682032489f630675390674bb1224dc7ede28
@@@ -87,14 -87,6 +87,6 @@@ static voi
  lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_io_buf *psb);
  static int
  lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc);
- static void
- lpfc_put_vmid_in_hashtable(struct lpfc_vport *vport, u32 hash,
-                          struct lpfc_vmid *vmp);
- static void lpfc_vmid_update_entry(struct lpfc_vport *vport, struct scsi_cmnd
-                                  *cmd, struct lpfc_vmid *vmp,
-                                  union lpfc_vmid_io_tag *tag);
- static void lpfc_vmid_assign_cs_ctl(struct lpfc_vport *vport,
-                                   struct lpfc_vmid *vmid);
  
  /**
   * lpfc_sli4_set_rsp_sgl_last - Set the last bit in the response sge.
@@@ -5270,254 -5262,6 +5262,6 @@@ void lpfc_poll_timeout(struct timer_lis
        }
  }
  
- /*
-  * lpfc_get_vmid_from_hashtable - search the UUID in the hash table
-  * @vport: The virtual port for which this call is being executed.
-  * @hash: calculated hash value
-  * @buf: uuid associated with the VE
-  * Return the VMID entry associated with the UUID
-  * Make sure to acquire the appropriate lock before invoking this routine.
-  */
- struct lpfc_vmid *lpfc_get_vmid_from_hashtable(struct lpfc_vport *vport,
-                                             u32 hash, u8 *buf)
- {
-       struct lpfc_vmid *vmp;
-       hash_for_each_possible(vport->hash_table, vmp, hnode, hash) {
-               if (memcmp(&vmp->host_vmid[0], buf, 16) == 0)
-                       return vmp;
-       }
-       return NULL;
- }
- /*
-  * lpfc_put_vmid_in_hashtable - put the VMID in the hash table
-  * @vport: The virtual port for which this call is being executed.
-  * @hash - calculated hash value
-  * @vmp: Pointer to a VMID entry representing a VM sending I/O
-  *
-  * This routine will insert the newly acquired VMID entity in the hash table.
-  * Make sure to acquire the appropriate lock before invoking this routine.
-  */
- static void
- lpfc_put_vmid_in_hashtable(struct lpfc_vport *vport, u32 hash,
-                          struct lpfc_vmid *vmp)
- {
-       hash_add(vport->hash_table, &vmp->hnode, hash);
- }
- /*
-  * lpfc_vmid_hash_fn - create a hash value of the UUID
-  * @vmid: uuid associated with the VE
-  * @len: length of the VMID string
-  * Returns the calculated hash value
-  */
- int lpfc_vmid_hash_fn(const char *vmid, int len)
- {
-       int c;
-       int hash = 0;
-       if (len == 0)
-               return 0;
-       while (len--) {
-               c = *vmid++;
-               if (c >= 'A' && c <= 'Z')
-                       c += 'a' - 'A';
-               hash = (hash + (c << LPFC_VMID_HASH_SHIFT) +
-                       (c >> LPFC_VMID_HASH_SHIFT)) * 19;
-       }
-       return hash & LPFC_VMID_HASH_MASK;
- }
- /*
-  * lpfc_vmid_update_entry - update the vmid entry in the hash table
-  * @vport: The virtual port for which this call is being executed.
-  * @cmd: address of scsi cmd descriptor
-  * @vmp: Pointer to a VMID entry representing a VM sending I/O
-  * @tag: VMID tag
-  */
- static void lpfc_vmid_update_entry(struct lpfc_vport *vport, struct scsi_cmnd
-                                  *cmd, struct lpfc_vmid *vmp,
-                                  union lpfc_vmid_io_tag *tag)
- {
-       u64 *lta;
-       if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
-               tag->cs_ctl_vmid = vmp->un.cs_ctl_vmid;
-       else if (vport->phba->cfg_vmid_app_header)
-               tag->app_id = vmp->un.app_id;
-       if (cmd->sc_data_direction == DMA_TO_DEVICE)
-               vmp->io_wr_cnt++;
-       else
-               vmp->io_rd_cnt++;
-       /* update the last access timestamp in the table */
-       lta = per_cpu_ptr(vmp->last_io_time, raw_smp_processor_id());
-       *lta = jiffies;
- }
- static void lpfc_vmid_assign_cs_ctl(struct lpfc_vport *vport,
-                                   struct lpfc_vmid *vmid)
- {
-       u32 hash;
-       struct lpfc_vmid *pvmid;
-       if (vport->port_type == LPFC_PHYSICAL_PORT) {
-               vmid->un.cs_ctl_vmid = lpfc_vmid_get_cs_ctl(vport);
-       } else {
-               hash = lpfc_vmid_hash_fn(vmid->host_vmid, vmid->vmid_len);
-               pvmid =
-                   lpfc_get_vmid_from_hashtable(vport->phba->pport, hash,
-                                               vmid->host_vmid);
-               if (pvmid)
-                       vmid->un.cs_ctl_vmid = pvmid->un.cs_ctl_vmid;
-               else
-                       vmid->un.cs_ctl_vmid = lpfc_vmid_get_cs_ctl(vport);
-       }
- }
- /*
-  * lpfc_vmid_get_appid - get the VMID associated with the UUID
-  * @vport: The virtual port for which this call is being executed.
-  * @uuid: UUID associated with the VE
-  * @cmd: address of scsi_cmd descriptor
-  * @tag: VMID tag
-  * Returns status of the function
-  */
- static int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid, struct
-                              scsi_cmnd * cmd, union lpfc_vmid_io_tag *tag)
- {
-       struct lpfc_vmid *vmp = NULL;
-       int hash, len, rc = -EPERM, i;
-       /* check if QFPA is complete */
-       if (lpfc_vmid_is_type_priority_tag(vport) &&
-           !(vport->vmid_flag & LPFC_VMID_QFPA_CMPL) &&
-           (vport->vmid_flag & LPFC_VMID_ISSUE_QFPA)) {
-               vport->work_port_events |= WORKER_CHECK_VMID_ISSUE_QFPA;
-               return -EAGAIN;
-       }
-       /* search if the UUID has already been mapped to the VMID */
-       len = strlen(uuid);
-       hash = lpfc_vmid_hash_fn(uuid, len);
-       /* search for the VMID in the table */
-       read_lock(&vport->vmid_lock);
-       vmp = lpfc_get_vmid_from_hashtable(vport, hash, uuid);
-       /* if found, check if its already registered  */
-       if (vmp  && vmp->flag & LPFC_VMID_REGISTERED) {
-               read_unlock(&vport->vmid_lock);
-               lpfc_vmid_update_entry(vport, cmd, vmp, tag);
-               rc = 0;
-       } else if (vmp && (vmp->flag & LPFC_VMID_REQ_REGISTER ||
-                          vmp->flag & LPFC_VMID_DE_REGISTER)) {
-               /* else if register or dereg request has already been sent */
-               /* Hence VMID tag will not be added for this I/O */
-               read_unlock(&vport->vmid_lock);
-               rc = -EBUSY;
-       } else {
-               /* The VMID was not found in the hashtable. At this point, */
-               /* drop the read lock first before proceeding further */
-               read_unlock(&vport->vmid_lock);
-               /* start the process to obtain one as per the */
-               /* type of the VMID indicated */
-               write_lock(&vport->vmid_lock);
-               vmp = lpfc_get_vmid_from_hashtable(vport, hash, uuid);
-               /* while the read lock was released, in case the entry was */
-               /* added by other context or is in process of being added */
-               if (vmp && vmp->flag & LPFC_VMID_REGISTERED) {
-                       lpfc_vmid_update_entry(vport, cmd, vmp, tag);
-                       write_unlock(&vport->vmid_lock);
-                       return 0;
-               } else if (vmp && vmp->flag & LPFC_VMID_REQ_REGISTER) {
-                       write_unlock(&vport->vmid_lock);
-                       return -EBUSY;
-               }
-               /* else search and allocate a free slot in the hash table */
-               if (vport->cur_vmid_cnt < vport->max_vmid) {
-                       for (i = 0; i < vport->max_vmid; i++) {
-                               vmp = vport->vmid + i;
-                               if (vmp->flag == LPFC_VMID_SLOT_FREE)
-                                       break;
-                       }
-                       if (i == vport->max_vmid)
-                               vmp = NULL;
-               } else {
-                       vmp = NULL;
-               }
-               if (!vmp) {
-                       write_unlock(&vport->vmid_lock);
-                       return -ENOMEM;
-               }
-               /* Add the vmid and register */
-               lpfc_put_vmid_in_hashtable(vport, hash, vmp);
-               vmp->vmid_len = len;
-               memcpy(vmp->host_vmid, uuid, vmp->vmid_len);
-               vmp->io_rd_cnt = 0;
-               vmp->io_wr_cnt = 0;
-               vmp->flag = LPFC_VMID_SLOT_USED;
-               vmp->delete_inactive =
-                       vport->vmid_inactivity_timeout ? 1 : 0;
-               /* if type priority tag, get next available VMID */
-               if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
-                       lpfc_vmid_assign_cs_ctl(vport, vmp);
-               /* allocate the per cpu variable for holding */
-               /* the last access time stamp only if VMID is enabled */
-               if (!vmp->last_io_time)
-                       vmp->last_io_time = __alloc_percpu(sizeof(u64),
-                                                          __alignof__(struct
-                                                          lpfc_vmid));
-               if (!vmp->last_io_time) {
-                       hash_del(&vmp->hnode);
-                       vmp->flag = LPFC_VMID_SLOT_FREE;
-                       write_unlock(&vport->vmid_lock);
-                       return -EIO;
-               }
-               write_unlock(&vport->vmid_lock);
-               /* complete transaction with switch */
-               if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
-                       rc = lpfc_vmid_uvem(vport, vmp, true);
-               else if (vport->phba->cfg_vmid_app_header)
-                       rc = lpfc_vmid_cmd(vport, SLI_CTAS_RAPP_IDENT, vmp);
-               if (!rc) {
-                       write_lock(&vport->vmid_lock);
-                       vport->cur_vmid_cnt++;
-                       vmp->flag |= LPFC_VMID_REQ_REGISTER;
-                       write_unlock(&vport->vmid_lock);
-               } else {
-                       write_lock(&vport->vmid_lock);
-                       hash_del(&vmp->hnode);
-                       vmp->flag = LPFC_VMID_SLOT_FREE;
-                       free_percpu(vmp->last_io_time);
-                       write_unlock(&vport->vmid_lock);
-                       return -EIO;
-               }
-               /* finally, enable the idle timer once */
-               if (!(vport->phba->pport->vmid_flag & LPFC_VMID_TIMER_ENBLD)) {
-                       mod_timer(&vport->phba->inactive_vmid_poll,
-                                 jiffies +
-                                 msecs_to_jiffies(1000 * LPFC_VMID_TIMER));
-                       vport->phba->pport->vmid_flag |= LPFC_VMID_TIMER_ENBLD;
-               }
-       }
-       return rc;
- }
  /*
   * lpfc_is_command_vm_io - get the UUID from blk cgroup
   * @cmd: Pointer to scsi_cmnd data structure
@@@ -5527,9 -5271,7 +5271,9 @@@ static char *lpfc_is_command_vm_io(stru
  {
        struct bio *bio = scsi_cmd_to_rq(cmd)->bio;
  
 -      return bio ? blkcg_get_fc_appid(bio) : NULL;
 +      if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !bio)
 +              return NULL;
 +      return blkcg_get_fc_appid(bio);
  }
  
  /**
@@@ -5704,9 -5446,10 +5448,10 @@@ lpfc_queuecommand(struct Scsi_Host *sho
                uuid = lpfc_is_command_vm_io(cmnd);
  
                if (uuid) {
-                       err = lpfc_vmid_get_appid(vport, uuid, cmnd,
-                               (union lpfc_vmid_io_tag *)
-                                       &cur_iocbq->vmid_tag);
+                       err = lpfc_vmid_get_appid(vport, uuid,
+                                       cmnd->sc_data_direction,
+                                       (union lpfc_vmid_io_tag *)
+                                               &cur_iocbq->vmid_tag);
                        if (!err)
                                cur_iocbq->cmd_flag |= LPFC_IO_VMID;
                }
index a02235a6a8e9361b55359024b9986001019980fb,92420766ebec97ba06e368ef5e36e7420b768438..cb97f625970d0cac62ed63dce2f68e5af794a6bd
@@@ -48,13 -48,6 +48,6 @@@ MODULE_PARM_DESC(qlini_mode
        "when ready "
        "\"enabled\" (default) - initiator mode will always stay enabled.");
  
- static int ql_dm_tgt_ex_pct = 0;
- module_param(ql_dm_tgt_ex_pct, int, S_IRUGO|S_IWUSR);
- MODULE_PARM_DESC(ql_dm_tgt_ex_pct,
-       "For Dual Mode (qlini_mode=dual), this parameter determines "
-       "the percentage of exchanges/cmds FW will allocate resources "
-       "for Target mode.");
  int ql2xuctrlirq = 1;
  module_param(ql2xuctrlirq, int, 0644);
  MODULE_PARM_DESC(ql2xuctrlirq,
@@@ -3826,9 -3819,6 +3819,9 @@@ int qlt_abort_cmd(struct qla_tgt_cmd *c
  
        spin_lock_irqsave(&cmd->cmd_lock, flags);
        if (cmd->aborted) {
 +              if (cmd->sg_mapped)
 +                      qlt_unmap_sg(vha, cmd);
 +
                spin_unlock_irqrestore(&cmd->cmd_lock, flags);
                /*
                 * It's normal to see 2 calls in this path:
diff --combined drivers/scsi/sd.c
index 749316462075e9834c7209f19b55baec799f2141,03e1379a44e82b144cd3be37caf8ad76c4b59aad..895b56c8f25e3c137afffc41b8a3eb60fe58ac5c
@@@ -797,6 -797,7 +797,6 @@@ static void sd_config_discard(struct sc
        case SD_LBP_FULL:
        case SD_LBP_DISABLE:
                blk_queue_max_discard_sectors(q, 0);
 -              blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
                return;
  
        case SD_LBP_UNMAP:
        }
  
        blk_queue_max_discard_sectors(q, max_blocks * (logical_block_size >> 9));
 -      blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
  }
  
  static blk_status_t sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
@@@ -3521,7 -3523,7 +3521,7 @@@ static int sd_probe(struct device *dev
        error = device_add_disk(dev, gd, NULL);
        if (error) {
                put_device(&sdkp->disk_dev);
-               blk_cleanup_disk(gd);
+               put_disk(gd);
                goto out;
        }
  
   out_put:
        put_disk(gd);
   out_free:
-       sd_zbc_release_disk(sdkp);
        kfree(sdkp);
   out:
        scsi_autopm_put_device(sdp);
@@@ -3579,7 -3580,7 +3578,7 @@@ static void scsi_disk_release(struct de
        struct scsi_disk *sdkp = to_scsi_disk(dev);
  
        ida_free(&sd_index_ida, sdkp->index);
-       sd_zbc_release_disk(sdkp);
+       sd_zbc_free_zone_info(sdkp);
        put_device(&sdkp->device->sdev_gendev);
        free_opal_dev(sdkp->opal_dev);
  
index 08ed059a738b92065f7fd0f91608e043267c72a6,4fe4f679628404c7094f02b413bcbb7e8351bb20..ca3530982e52c8f7f219dd51877bc76bc771cc2a
@@@ -54,6 -54,7 +54,6 @@@
  
  #define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_)  ((((MAJOR_) & 0xff) << 8) | \
                                                (((MINOR_) & 0xff)))
 -
  #define VMSTOR_PROTO_VERSION_WIN6     VMSTOR_PROTO_VERSION(2, 0)
  #define VMSTOR_PROTO_VERSION_WIN7     VMSTOR_PROTO_VERSION(4, 2)
  #define VMSTOR_PROTO_VERSION_WIN8     VMSTOR_PROTO_VERSION(5, 1)
@@@ -135,10 -136,20 +135,10 @@@ struct hv_fc_wwn_packet 
   */
  #define STORVSC_MAX_CMD_LEN                   0x10
  
 -#define POST_WIN7_STORVSC_SENSE_BUFFER_SIZE   0x14
 -#define PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE    0x12
 -
 +/* Sense buffer size is the same for all versions since Windows 8 */
  #define STORVSC_SENSE_BUFFER_SIZE             0x14
  #define STORVSC_MAX_BUF_LEN_WITH_PADDING      0x14
  
 -/*
 - * Sense buffer size changed in win8; have a run-time
 - * variable to track the size we should use.  This value will
 - * likely change during protocol negotiation but it is valid
 - * to start by assuming pre-Win8.
 - */
 -static int sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
 -
  /*
   * The storage protocol version is determined during the
   * initial exchange with the host.  It will indicate which
@@@ -166,6 -177,18 +166,6 @@@ do {                                                              
                dev_warn(&(dev)->device, fmt, ##__VA_ARGS__);   \
  } while (0)
  
 -struct vmscsi_win8_extension {
 -      /*
 -       * The following were added in Windows 8
 -       */
 -      u16 reserve;
 -      u8  queue_tag;
 -      u8  queue_action;
 -      u32 srb_flags;
 -      u32 time_out_value;
 -      u32 queue_sort_ey;
 -} __packed;
 -
  struct vmscsi_request {
        u16 length;
        u8 srb_status;
        /*
         * The following was added in win8.
         */
 -      struct vmscsi_win8_extension win8_extension;
 +      u16 reserve;
 +      u8  queue_tag;
 +      u8  queue_action;
 +      u32 srb_flags;
 +      u32 time_out_value;
 +      u32 queue_sort_ey;
  
  } __attribute((packed));
  
  /*
 - * The list of storage protocols in order of preference.
 + * The list of windows version in order of preference.
   */
 -struct vmstor_protocol {
 -      int protocol_version;
 -      int sense_buffer_size;
 -      int vmscsi_size_delta;
 -};
 -
  
 -static const struct vmstor_protocol vmstor_protocols[] = {
 -      {
 +static const int protocol_version[] = {
                VMSTOR_PROTO_VERSION_WIN10,
 -              POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
 -              0
 -      },
 -      {
                VMSTOR_PROTO_VERSION_WIN8_1,
 -              POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
 -              0
 -      },
 -      {
                VMSTOR_PROTO_VERSION_WIN8,
 -              POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
 -              0
 -      },
 -      {
 -              VMSTOR_PROTO_VERSION_WIN7,
 -              PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE,
 -              sizeof(struct vmscsi_win8_extension),
 -      },
 -      {
 -              VMSTOR_PROTO_VERSION_WIN6,
 -              PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE,
 -              sizeof(struct vmscsi_win8_extension),
 -      }
  };
  
  
@@@ -363,7 -409,9 +363,7 @@@ static void storvsc_on_channel_callback
  #define STORVSC_IDE_MAX_CHANNELS                      1
  
  /*
 - * Upper bound on the size of a storvsc packet. vmscsi_size_delta is not
 - * included in the calculation because it is set after STORVSC_MAX_PKT_SIZE
 - * is used in storvsc_connect_to_vsp
 + * Upper bound on the size of a storvsc packet.
   */
  #define STORVSC_MAX_PKT_SIZE (sizeof(struct vmpacket_descriptor) +\
                              sizeof(struct vstor_packet))
@@@ -404,6 -452,17 +404,6 @@@ struct storvsc_device 
        unsigned char path_id;
        unsigned char target_id;
  
 -      /*
 -       * The size of the vmscsi_request has changed in win8. The
 -       * additional size is because of new elements added to the
 -       * structure. These elements are valid only when we are talking
 -       * to a win8 host.
 -       * Track the correction to size we need to apply. This value
 -       * will likely change during protocol negotiation but it is
 -       * valid to start by assuming pre-Win8.
 -       */
 -      int vmscsi_size_delta;
 -
        /*
         * Max I/O, the device can support.
         */
@@@ -479,7 -538,7 +479,7 @@@ static void storvsc_host_scan(struct wo
        host = host_device->host;
        /*
         * Before scanning the host, first check to see if any of the
-        * currrently known devices have been hot removed. We issue a
+        * currently known devices have been hot removed. We issue a
         * "unit ready" command against all currently known devices.
         * This I/O will result in an error for devices that have been
         * removed. As part of handling the I/O error, we remove the device.
@@@ -736,7 -795,8 +736,7 @@@ static void  handle_multichannel_storag
        vstor_packet->sub_channel_count = num_sc;
  
        ret = vmbus_sendpacket(device->channel, vstor_packet,
 -                             (sizeof(struct vstor_packet) -
 -                             stor_device->vmscsi_size_delta),
 +                             sizeof(struct vstor_packet),
                               VMBUS_RQST_INIT,
                               VM_PKT_DATA_INBAND,
                               VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@@ -804,7 -864,8 +804,7 @@@ static int storvsc_execute_vstor_op(str
        vstor_packet->flags = REQUEST_COMPLETION_FLAG;
  
        ret = vmbus_sendpacket(device->channel, vstor_packet,
 -                             (sizeof(struct vstor_packet) -
 -                             stor_device->vmscsi_size_delta),
 +                             sizeof(struct vstor_packet),
                               VMBUS_RQST_INIT,
                               VM_PKT_DATA_INBAND,
                               VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@@ -854,13 -915,14 +854,13 @@@ static int storvsc_channel_init(struct 
         * Query host supported protocol version.
         */
  
 -      for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
 +      for (i = 0; i < ARRAY_SIZE(protocol_version); i++) {
                /* reuse the packet for version range supported */
                memset(vstor_packet, 0, sizeof(struct vstor_packet));
                vstor_packet->operation =
                        VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
  
 -              vstor_packet->version.major_minor =
 -                      vmstor_protocols[i].protocol_version;
 +              vstor_packet->version.major_minor = protocol_version[i];
  
                /*
                 * The revision number is only used in Windows; set it to 0.
                        return -EINVAL;
  
                if (vstor_packet->status == 0) {
 -                      vmstor_proto_version =
 -                              vmstor_protocols[i].protocol_version;
 -
 -                      sense_buffer_size =
 -                              vmstor_protocols[i].sense_buffer_size;
 -
 -                      stor_device->vmscsi_size_delta =
 -                              vmstor_protocols[i].vmscsi_size_delta;
 +                      vmstor_proto_version = protocol_version[i];
  
                        break;
                }
        }
  
 -      if (vstor_packet->status != 0)
 +      if (vstor_packet->status != 0) {
 +              dev_err(&device->device, "Obsolete Hyper-V version\n");
                return -EINVAL;
 +      }
  
  
        memset(vstor_packet, 0, sizeof(struct vstor_packet));
        cpumask_set_cpu(device->channel->target_cpu,
                        &stor_device->alloced_cpus);
  
 -      if (vmstor_proto_version >= VMSTOR_PROTO_VERSION_WIN8) {
 -              if (vstor_packet->storage_channel_properties.flags &
 -                  STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
 -                      process_sub_channels = true;
 -      }
 +      if (vstor_packet->storage_channel_properties.flags &
 +          STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
 +              process_sub_channels = true;
 +
        stor_device->max_transfer_bytes =
                vstor_packet->storage_channel_properties.max_transfer_bytes;
  
@@@ -1129,7 -1197,7 +1129,7 @@@ static void storvsc_on_io_completion(st
         * Copy over the sense_info_length, but limit to the known max
         * size if Hyper-V returns a bad value.
         */
 -      stor_pkt->vm_srb.sense_info_length = min_t(u8, sense_buffer_size,
 +      stor_pkt->vm_srb.sense_info_length = min_t(u8, STORVSC_SENSE_BUFFER_SIZE,
                vstor_packet->vm_srb.sense_info_length);
  
        if (vstor_packet->vm_srb.scsi_status != 0 ||
@@@ -1221,8 -1289,8 +1221,8 @@@ static void storvsc_on_channel_callback
                struct storvsc_cmd_request *request = NULL;
                u32 pktlen = hv_pkt_datalen(desc);
                u64 rqst_id = desc->trans_id;
 -              u32 minlen = rqst_id ? sizeof(struct vstor_packet) -
 -                      stor_device->vmscsi_size_delta : sizeof(enum vstor_packet_operation);
 +              u32 minlen = rqst_id ? sizeof(struct vstor_packet) :
 +                      sizeof(enum vstor_packet_operation);
  
                if (pktlen < minlen) {
                        dev_err(&device->device,
                }
  
                memcpy(&request->vstor_packet, packet,
 -                     (sizeof(struct vstor_packet) - stor_device->vmscsi_size_delta));
 +                     sizeof(struct vstor_packet));
                complete(&request->wait_event);
        }
  }
@@@ -1489,10 -1557,11 +1489,10 @@@ static int storvsc_do_io(struct hv_devi
  found_channel:
        vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
  
 -      vstor_packet->vm_srb.length = (sizeof(struct vmscsi_request) -
 -                                      stor_device->vmscsi_size_delta);
 +      vstor_packet->vm_srb.length = sizeof(struct vmscsi_request);
  
  
 -      vstor_packet->vm_srb.sense_info_length = sense_buffer_size;
 +      vstor_packet->vm_srb.sense_info_length = STORVSC_SENSE_BUFFER_SIZE;
  
  
        vstor_packet->vm_srb.data_transfer_length =
                ret = vmbus_sendpacket_mpb_desc(outgoing_channel,
                                request->payload, request->payload_sz,
                                vstor_packet,
 -                              (sizeof(struct vstor_packet) -
 -                              stor_device->vmscsi_size_delta),
 +                              sizeof(struct vstor_packet),
                                (unsigned long)request);
        } else {
                ret = vmbus_sendpacket(outgoing_channel, vstor_packet,
 -                             (sizeof(struct vstor_packet) -
 -                              stor_device->vmscsi_size_delta),
 +                             sizeof(struct vstor_packet),
                               (unsigned long)request,
                               VM_PKT_DATA_INBAND,
                               VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@@ -1613,7 -1684,8 +1613,7 @@@ static int storvsc_host_reset_handler(s
        vstor_packet->vm_srb.path_id = stor_device->path_id;
  
        ret = vmbus_sendpacket(device->channel, vstor_packet,
 -                             (sizeof(struct vstor_packet) -
 -                              stor_device->vmscsi_size_delta),
 +                             sizeof(struct vstor_packet),
                               VMBUS_RQST_RESET,
                               VM_PKT_DATA_INBAND,
                               VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@@ -1706,31 -1778,31 +1706,31 @@@ static int storvsc_queuecommand(struct 
  
        memset(&cmd_request->vstor_packet, 0, sizeof(struct vstor_packet));
        vm_srb = &cmd_request->vstor_packet.vm_srb;
 -      vm_srb->win8_extension.time_out_value = 60;
 +      vm_srb->time_out_value = 60;
  
 -      vm_srb->win8_extension.srb_flags |=
 +      vm_srb->srb_flags |=
                SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
  
        if (scmnd->device->tagged_supported) {
 -              vm_srb->win8_extension.srb_flags |=
 +              vm_srb->srb_flags |=
                (SRB_FLAGS_QUEUE_ACTION_ENABLE | SRB_FLAGS_NO_QUEUE_FREEZE);
 -              vm_srb->win8_extension.queue_tag = SP_UNTAGGED;
 -              vm_srb->win8_extension.queue_action = SRB_SIMPLE_TAG_REQUEST;
 +              vm_srb->queue_tag = SP_UNTAGGED;
 +              vm_srb->queue_action = SRB_SIMPLE_TAG_REQUEST;
        }
  
        /* Build the SRB */
        switch (scmnd->sc_data_direction) {
        case DMA_TO_DEVICE:
                vm_srb->data_in = WRITE_TYPE;
 -              vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_OUT;
 +              vm_srb->srb_flags |= SRB_FLAGS_DATA_OUT;
                break;
        case DMA_FROM_DEVICE:
                vm_srb->data_in = READ_TYPE;
 -              vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_IN;
 +              vm_srb->srb_flags |= SRB_FLAGS_DATA_IN;
                break;
        case DMA_NONE:
                vm_srb->data_in = UNKNOWN_TYPE;
 -              vm_srb->win8_extension.srb_flags |= SRB_FLAGS_NO_DATA_TRANSFER;
 +              vm_srb->srb_flags |= SRB_FLAGS_NO_DATA_TRANSFER;
                break;
        default:
                /*
@@@ -1894,16 -1966,34 +1894,16 @@@ static int storvsc_probe(struct hv_devi
        bool is_fc = ((dev_id->driver_data == SFC_GUID) ? true : false);
        int target = 0;
        struct storvsc_device *stor_device;
 -      int max_luns_per_target;
 -      int max_targets;
 -      int max_channels;
        int max_sub_channels = 0;
  
        /*
 -       * Based on the windows host we are running on,
 -       * set state to properly communicate with the host.
 +       * We support sub-channels for storage on SCSI and FC controllers.
 +       * The number of sub-channels offerred is based on the number of
 +       * VCPUs in the guest.
         */
 -
 -      if (vmbus_proto_version < VERSION_WIN8) {
 -              max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
 -              max_targets = STORVSC_IDE_MAX_TARGETS;
 -              max_channels = STORVSC_IDE_MAX_CHANNELS;
 -      } else {
 -              max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
 -              max_targets = STORVSC_MAX_TARGETS;
 -              max_channels = STORVSC_MAX_CHANNELS;
 -              /*
 -               * On Windows8 and above, we support sub-channels for storage
 -               * on SCSI and FC controllers.
 -               * The number of sub-channels offerred is based on the number of
 -               * VCPUs in the guest.
 -               */
 -              if (!dev_is_ide)
 -                      max_sub_channels =
 -                              (num_cpus - 1) / storvsc_vcpus_per_sub_channel;
 -      }
 +      if (!dev_is_ide)
 +              max_sub_channels =
 +                      (num_cpus - 1) / storvsc_vcpus_per_sub_channel;
  
        scsi_driver.can_queue = max_outstanding_req_per_channel *
                                (max_sub_channels + 1) *
        init_waitqueue_head(&stor_device->waiting_to_drain);
        stor_device->device = device;
        stor_device->host = host;
 -      stor_device->vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
        spin_lock_init(&stor_device->lock);
        hv_set_drvdata(device, stor_device);
        dma_set_min_align_mask(&device->device, HV_HYP_PAGE_SIZE - 1);
                break;
  
        case SCSI_GUID:
 -              host->max_lun = max_luns_per_target;
 -              host->max_id = max_targets;
 -              host->max_channel = max_channels - 1;
 +              host->max_lun = STORVSC_MAX_LUNS_PER_TARGET;
 +              host->max_id = STORVSC_MAX_TARGETS;
 +              host->max_channel = STORVSC_MAX_CHANNELS - 1;
                break;
  
        default:
@@@ -2144,6 -2235,10 +2144,6 @@@ static int __init storvsc_drv_init(void
         * than the ring buffer size since that page is reserved for
         * the ring buffer indices) by the max request size (which is
         * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64)
 -       *
 -       * The computation underestimates max_outstanding_req_per_channel
 -       * for Win7 and older hosts because it does not take into account
 -       * the vmscsi_size_delta correction to the max request size.
         */
        max_outstanding_req_per_channel =
                ((storvsc_ringbuffer_size - PAGE_SIZE) /
index 0000000000000000000000000000000000000000,aee0ec4cee70eac41d8769b806fbddce0714e1ff..de2bb8401bc4e4fa0b06bc4a124bff27e3522032
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,2670 +1,2667 @@@
 -      blk_execute_rq_nowait(req, true, ufshpb_umap_req_compl_fn);
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+  * Universal Flash Storage Host Performance Booster
+  *
+  * Copyright (C) 2017-2021 Samsung Electronics Co., Ltd.
+  *
+  * Authors:
+  *    Yongmyung Lee <ymhungry.lee@samsung.com>
+  *    Jinyoung Choi <j-young.choi@samsung.com>
+  */
+ #include <asm/unaligned.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
+ #include <linux/module.h>
+ #include <scsi/scsi_cmnd.h>
+ #include "ufshcd-priv.h"
+ #include "ufshpb.h"
+ #include "../../scsi/sd.h"
+ #define ACTIVATION_THRESHOLD 8 /* 8 IOs */
+ #define READ_TO_MS 1000
+ #define READ_TO_EXPIRIES 100
+ #define POLLING_INTERVAL_MS 200
+ #define THROTTLE_MAP_REQ_DEFAULT 1
+ /* memory management */
+ static struct kmem_cache *ufshpb_mctx_cache;
+ static mempool_t *ufshpb_mctx_pool;
+ static mempool_t *ufshpb_page_pool;
+ /* A cache size of 2MB can cache ppn in the 1GB range. */
+ static unsigned int ufshpb_host_map_kbytes = 2048;
+ static int tot_active_srgn_pages;
+ static struct workqueue_struct *ufshpb_wq;
+ static void ufshpb_update_active_info(struct ufshpb_lu *hpb, int rgn_idx,
+                                     int srgn_idx);
+ bool ufshpb_is_allowed(struct ufs_hba *hba)
+ {
+       return !(hba->ufshpb_dev.hpb_disabled);
+ }
+ /* HPB version 1.0 is called as legacy version. */
+ bool ufshpb_is_legacy(struct ufs_hba *hba)
+ {
+       return hba->ufshpb_dev.is_legacy;
+ }
+ static struct ufshpb_lu *ufshpb_get_hpb_data(struct scsi_device *sdev)
+ {
+       return sdev->hostdata;
+ }
+ static int ufshpb_get_state(struct ufshpb_lu *hpb)
+ {
+       return atomic_read(&hpb->hpb_state);
+ }
+ static void ufshpb_set_state(struct ufshpb_lu *hpb, int state)
+ {
+       atomic_set(&hpb->hpb_state, state);
+ }
+ static int ufshpb_is_valid_srgn(struct ufshpb_region *rgn,
+                               struct ufshpb_subregion *srgn)
+ {
+       return rgn->rgn_state != HPB_RGN_INACTIVE &&
+               srgn->srgn_state == HPB_SRGN_VALID;
+ }
+ static bool ufshpb_is_read_cmd(struct scsi_cmnd *cmd)
+ {
+       return req_op(scsi_cmd_to_rq(cmd)) == REQ_OP_READ;
+ }
+ static bool ufshpb_is_write_or_discard(struct scsi_cmnd *cmd)
+ {
+       return op_is_write(req_op(scsi_cmd_to_rq(cmd))) ||
+              op_is_discard(req_op(scsi_cmd_to_rq(cmd)));
+ }
+ static bool ufshpb_is_supported_chunk(struct ufshpb_lu *hpb, int transfer_len)
+ {
+       return transfer_len <= hpb->pre_req_max_tr_len;
+ }
+ static bool ufshpb_is_general_lun(int lun)
+ {
+       return lun < UFS_UPIU_MAX_UNIT_NUM_ID;
+ }
+ static bool ufshpb_is_pinned_region(struct ufshpb_lu *hpb, int rgn_idx)
+ {
+       return hpb->lu_pinned_end != PINNED_NOT_SET &&
+              rgn_idx >= hpb->lu_pinned_start && rgn_idx <= hpb->lu_pinned_end;
+ }
+ static void ufshpb_kick_map_work(struct ufshpb_lu *hpb)
+ {
+       bool ret = false;
+       unsigned long flags;
+       if (ufshpb_get_state(hpb) != HPB_PRESENT)
+               return;
+       spin_lock_irqsave(&hpb->rsp_list_lock, flags);
+       if (!list_empty(&hpb->lh_inact_rgn) || !list_empty(&hpb->lh_act_srgn))
+               ret = true;
+       spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
+       if (ret)
+               queue_work(ufshpb_wq, &hpb->map_work);
+ }
+ static bool ufshpb_is_hpb_rsp_valid(struct ufs_hba *hba,
+                                   struct ufshcd_lrb *lrbp,
+                                   struct utp_hpb_rsp *rsp_field)
+ {
+       /* Check HPB_UPDATE_ALERT */
+       if (!(lrbp->ucd_rsp_ptr->header.dword_2 &
+             UPIU_HEADER_DWORD(0, 2, 0, 0)))
+               return false;
+       if (be16_to_cpu(rsp_field->sense_data_len) != DEV_SENSE_SEG_LEN ||
+           rsp_field->desc_type != DEV_DES_TYPE ||
+           rsp_field->additional_len != DEV_ADDITIONAL_LEN ||
+           rsp_field->active_rgn_cnt > MAX_ACTIVE_NUM ||
+           rsp_field->inactive_rgn_cnt > MAX_INACTIVE_NUM ||
+           rsp_field->hpb_op == HPB_RSP_NONE ||
+           (rsp_field->hpb_op == HPB_RSP_REQ_REGION_UPDATE &&
+            !rsp_field->active_rgn_cnt && !rsp_field->inactive_rgn_cnt))
+               return false;
+       if (!ufshpb_is_general_lun(rsp_field->lun)) {
+               dev_warn(hba->dev, "ufshpb: lun(%d) not supported\n",
+                        lrbp->lun);
+               return false;
+       }
+       return true;
+ }
+ static void ufshpb_iterate_rgn(struct ufshpb_lu *hpb, int rgn_idx, int srgn_idx,
+                              int srgn_offset, int cnt, bool set_dirty)
+ {
+       struct ufshpb_region *rgn;
+       struct ufshpb_subregion *srgn, *prev_srgn = NULL;
+       int set_bit_len;
+       int bitmap_len;
+       unsigned long flags;
+ next_srgn:
+       rgn = hpb->rgn_tbl + rgn_idx;
+       srgn = rgn->srgn_tbl + srgn_idx;
+       if (likely(!srgn->is_last))
+               bitmap_len = hpb->entries_per_srgn;
+       else
+               bitmap_len = hpb->last_srgn_entries;
+       if ((srgn_offset + cnt) > bitmap_len)
+               set_bit_len = bitmap_len - srgn_offset;
+       else
+               set_bit_len = cnt;
+       spin_lock_irqsave(&hpb->rgn_state_lock, flags);
+       if (rgn->rgn_state != HPB_RGN_INACTIVE) {
+               if (set_dirty) {
+                       if (srgn->srgn_state == HPB_SRGN_VALID)
+                               bitmap_set(srgn->mctx->ppn_dirty, srgn_offset,
+                                          set_bit_len);
+               } else if (hpb->is_hcm) {
+                        /* rewind the read timer for lru regions */
+                       rgn->read_timeout = ktime_add_ms(ktime_get(),
+                                       rgn->hpb->params.read_timeout_ms);
+                       rgn->read_timeout_expiries =
+                               rgn->hpb->params.read_timeout_expiries;
+               }
+       }
+       spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+       if (hpb->is_hcm && prev_srgn != srgn) {
+               bool activate = false;
+               spin_lock(&rgn->rgn_lock);
+               if (set_dirty) {
+                       rgn->reads -= srgn->reads;
+                       srgn->reads = 0;
+                       set_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags);
+               } else {
+                       srgn->reads++;
+                       rgn->reads++;
+                       if (srgn->reads == hpb->params.activation_thld)
+                               activate = true;
+               }
+               spin_unlock(&rgn->rgn_lock);
+               if (activate ||
+                   test_and_clear_bit(RGN_FLAG_UPDATE, &rgn->rgn_flags)) {
+                       spin_lock_irqsave(&hpb->rsp_list_lock, flags);
+                       ufshpb_update_active_info(hpb, rgn_idx, srgn_idx);
+                       spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
+                       dev_dbg(&hpb->sdev_ufs_lu->sdev_dev,
+                               "activate region %d-%d\n", rgn_idx, srgn_idx);
+               }
+               prev_srgn = srgn;
+       }
+       srgn_offset = 0;
+       if (++srgn_idx == hpb->srgns_per_rgn) {
+               srgn_idx = 0;
+               rgn_idx++;
+       }
+       cnt -= set_bit_len;
+       if (cnt > 0)
+               goto next_srgn;
+ }
+ static bool ufshpb_test_ppn_dirty(struct ufshpb_lu *hpb, int rgn_idx,
+                                 int srgn_idx, int srgn_offset, int cnt)
+ {
+       struct ufshpb_region *rgn;
+       struct ufshpb_subregion *srgn;
+       int bitmap_len;
+       int bit_len;
+ next_srgn:
+       rgn = hpb->rgn_tbl + rgn_idx;
+       srgn = rgn->srgn_tbl + srgn_idx;
+       if (likely(!srgn->is_last))
+               bitmap_len = hpb->entries_per_srgn;
+       else
+               bitmap_len = hpb->last_srgn_entries;
+       if (!ufshpb_is_valid_srgn(rgn, srgn))
+               return true;
+       /*
+        * If the region state is active, mctx must be allocated.
+        * In this case, check whether the region is evicted or
+        * mctx allocation fail.
+        */
+       if (unlikely(!srgn->mctx)) {
+               dev_err(&hpb->sdev_ufs_lu->sdev_dev,
+                       "no mctx in region %d subregion %d.\n",
+                       srgn->rgn_idx, srgn->srgn_idx);
+               return true;
+       }
+       if ((srgn_offset + cnt) > bitmap_len)
+               bit_len = bitmap_len - srgn_offset;
+       else
+               bit_len = cnt;
+       if (find_next_bit(srgn->mctx->ppn_dirty, bit_len + srgn_offset,
+                         srgn_offset) < bit_len + srgn_offset)
+               return true;
+       srgn_offset = 0;
+       if (++srgn_idx == hpb->srgns_per_rgn) {
+               srgn_idx = 0;
+               rgn_idx++;
+       }
+       cnt -= bit_len;
+       if (cnt > 0)
+               goto next_srgn;
+       return false;
+ }
+ static inline bool is_rgn_dirty(struct ufshpb_region *rgn)
+ {
+       return test_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags);
+ }
+ static int ufshpb_fill_ppn_from_page(struct ufshpb_lu *hpb,
+                                    struct ufshpb_map_ctx *mctx, int pos,
+                                    int len, __be64 *ppn_buf)
+ {
+       struct page *page;
+       int index, offset;
+       int copied;
+       index = pos / (PAGE_SIZE / HPB_ENTRY_SIZE);
+       offset = pos % (PAGE_SIZE / HPB_ENTRY_SIZE);
+       if ((offset + len) <= (PAGE_SIZE / HPB_ENTRY_SIZE))
+               copied = len;
+       else
+               copied = (PAGE_SIZE / HPB_ENTRY_SIZE) - offset;
+       page = mctx->m_page[index];
+       if (unlikely(!page)) {
+               dev_err(&hpb->sdev_ufs_lu->sdev_dev,
+                       "error. cannot find page in mctx\n");
+               return -ENOMEM;
+       }
+       memcpy(ppn_buf, page_address(page) + (offset * HPB_ENTRY_SIZE),
+              copied * HPB_ENTRY_SIZE);
+       return copied;
+ }
+ static void
+ ufshpb_get_pos_from_lpn(struct ufshpb_lu *hpb, unsigned long lpn, int *rgn_idx,
+                       int *srgn_idx, int *offset)
+ {
+       int rgn_offset;
+       *rgn_idx = lpn >> hpb->entries_per_rgn_shift;
+       rgn_offset = lpn & hpb->entries_per_rgn_mask;
+       *srgn_idx = rgn_offset >> hpb->entries_per_srgn_shift;
+       *offset = rgn_offset & hpb->entries_per_srgn_mask;
+ }
+ static void
+ ufshpb_set_hpb_read_to_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp,
+                           __be64 ppn, u8 transfer_len)
+ {
+       unsigned char *cdb = lrbp->cmd->cmnd;
+       __be64 ppn_tmp = ppn;
+       cdb[0] = UFSHPB_READ;
+       if (hba->dev_quirks & UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ)
+               ppn_tmp = (__force __be64)swab64((__force u64)ppn);
+       /* ppn value is stored as big-endian in the host memory */
+       memcpy(&cdb[6], &ppn_tmp, sizeof(__be64));
+       cdb[14] = transfer_len;
+       cdb[15] = 0;
+       lrbp->cmd->cmd_len = UFS_CDB_SIZE;
+ }
+ /*
+  * This function will set up HPB read command using host-side L2P map data.
+  */
+ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+ {
+       struct ufshpb_lu *hpb;
+       struct ufshpb_region *rgn;
+       struct ufshpb_subregion *srgn;
+       struct scsi_cmnd *cmd = lrbp->cmd;
+       u32 lpn;
+       __be64 ppn;
+       unsigned long flags;
+       int transfer_len, rgn_idx, srgn_idx, srgn_offset;
+       int err = 0;
+       hpb = ufshpb_get_hpb_data(cmd->device);
+       if (!hpb)
+               return -ENODEV;
+       if (ufshpb_get_state(hpb) == HPB_INIT)
+               return -ENODEV;
+       if (ufshpb_get_state(hpb) != HPB_PRESENT) {
+               dev_notice(&hpb->sdev_ufs_lu->sdev_dev,
+                          "%s: ufshpb state is not PRESENT", __func__);
+               return -ENODEV;
+       }
+       if (blk_rq_is_passthrough(scsi_cmd_to_rq(cmd)) ||
+           (!ufshpb_is_write_or_discard(cmd) &&
+            !ufshpb_is_read_cmd(cmd)))
+               return 0;
+       transfer_len = sectors_to_logical(cmd->device,
+                                         blk_rq_sectors(scsi_cmd_to_rq(cmd)));
+       if (unlikely(!transfer_len))
+               return 0;
+       lpn = sectors_to_logical(cmd->device, blk_rq_pos(scsi_cmd_to_rq(cmd)));
+       ufshpb_get_pos_from_lpn(hpb, lpn, &rgn_idx, &srgn_idx, &srgn_offset);
+       rgn = hpb->rgn_tbl + rgn_idx;
+       srgn = rgn->srgn_tbl + srgn_idx;
+       /* If command type is WRITE or DISCARD, set bitmap as drity */
+       if (ufshpb_is_write_or_discard(cmd)) {
+               ufshpb_iterate_rgn(hpb, rgn_idx, srgn_idx, srgn_offset,
+                                  transfer_len, true);
+               return 0;
+       }
+       if (!ufshpb_is_supported_chunk(hpb, transfer_len))
+               return 0;
+       if (hpb->is_hcm) {
+               /*
+                * in host control mode, reads are the main source for
+                * activation trials.
+                */
+               ufshpb_iterate_rgn(hpb, rgn_idx, srgn_idx, srgn_offset,
+                                  transfer_len, false);
+               /* keep those counters normalized */
+               if (rgn->reads > hpb->entries_per_srgn)
+                       schedule_work(&hpb->ufshpb_normalization_work);
+       }
+       spin_lock_irqsave(&hpb->rgn_state_lock, flags);
+       if (ufshpb_test_ppn_dirty(hpb, rgn_idx, srgn_idx, srgn_offset,
+                                  transfer_len)) {
+               hpb->stats.miss_cnt++;
+               spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+               return 0;
+       }
+       err = ufshpb_fill_ppn_from_page(hpb, srgn->mctx, srgn_offset, 1, &ppn);
+       spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+       if (unlikely(err < 0)) {
+               /*
+                * In this case, the region state is active,
+                * but the ppn table is not allocated.
+                * Make sure that ppn table must be allocated on
+                * active state.
+                */
+               dev_err(hba->dev, "get ppn failed. err %d\n", err);
+               return err;
+       }
+       ufshpb_set_hpb_read_to_upiu(hba, lrbp, ppn, transfer_len);
+       hpb->stats.hit_cnt++;
+       return 0;
+ }
+ static struct ufshpb_req *ufshpb_get_req(struct ufshpb_lu *hpb,
+                                        int rgn_idx, enum req_opf dir,
+                                        bool atomic)
+ {
+       struct ufshpb_req *rq;
+       struct request *req;
+       int retries = HPB_MAP_REQ_RETRIES;
+       rq = kmem_cache_alloc(hpb->map_req_cache, GFP_KERNEL);
+       if (!rq)
+               return NULL;
+ retry:
+       req = blk_mq_alloc_request(hpb->sdev_ufs_lu->request_queue, dir,
+                             BLK_MQ_REQ_NOWAIT);
+       if (!atomic && (PTR_ERR(req) == -EWOULDBLOCK) && (--retries > 0)) {
+               usleep_range(3000, 3100);
+               goto retry;
+       }
+       if (IS_ERR(req))
+               goto free_rq;
+       rq->hpb = hpb;
+       rq->req = req;
+       rq->rb.rgn_idx = rgn_idx;
+       return rq;
+ free_rq:
+       kmem_cache_free(hpb->map_req_cache, rq);
+       return NULL;
+ }
+ static void ufshpb_put_req(struct ufshpb_lu *hpb, struct ufshpb_req *rq)
+ {
+       blk_mq_free_request(rq->req);
+       kmem_cache_free(hpb->map_req_cache, rq);
+ }
+ static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb,
+                                            struct ufshpb_subregion *srgn)
+ {
+       struct ufshpb_req *map_req;
+       struct bio *bio;
+       unsigned long flags;
+       if (hpb->is_hcm &&
+           hpb->num_inflight_map_req >= hpb->params.inflight_map_req) {
+               dev_info(&hpb->sdev_ufs_lu->sdev_dev,
+                        "map_req throttle. inflight %d throttle %d",
+                        hpb->num_inflight_map_req,
+                        hpb->params.inflight_map_req);
+               return NULL;
+       }
+       map_req = ufshpb_get_req(hpb, srgn->rgn_idx, REQ_OP_DRV_IN, false);
+       if (!map_req)
+               return NULL;
+       bio = bio_alloc(NULL, hpb->pages_per_srgn, 0, GFP_KERNEL);
+       if (!bio) {
+               ufshpb_put_req(hpb, map_req);
+               return NULL;
+       }
+       map_req->bio = bio;
+       map_req->rb.srgn_idx = srgn->srgn_idx;
+       map_req->rb.mctx = srgn->mctx;
+       spin_lock_irqsave(&hpb->param_lock, flags);
+       hpb->num_inflight_map_req++;
+       spin_unlock_irqrestore(&hpb->param_lock, flags);
+       return map_req;
+ }
+ static void ufshpb_put_map_req(struct ufshpb_lu *hpb,
+                              struct ufshpb_req *map_req)
+ {
+       unsigned long flags;
+       bio_put(map_req->bio);
+       ufshpb_put_req(hpb, map_req);
+       spin_lock_irqsave(&hpb->param_lock, flags);
+       hpb->num_inflight_map_req--;
+       spin_unlock_irqrestore(&hpb->param_lock, flags);
+ }
+ static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu *hpb,
+                                    struct ufshpb_subregion *srgn)
+ {
+       struct ufshpb_region *rgn;
+       u32 num_entries = hpb->entries_per_srgn;
+       if (!srgn->mctx) {
+               dev_err(&hpb->sdev_ufs_lu->sdev_dev,
+                       "no mctx in region %d subregion %d.\n",
+                       srgn->rgn_idx, srgn->srgn_idx);
+               return -1;
+       }
+       if (unlikely(srgn->is_last))
+               num_entries = hpb->last_srgn_entries;
+       bitmap_zero(srgn->mctx->ppn_dirty, num_entries);
+       rgn = hpb->rgn_tbl + srgn->rgn_idx;
+       clear_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags);
+       return 0;
+ }
+ static void ufshpb_update_active_info(struct ufshpb_lu *hpb, int rgn_idx,
+                                     int srgn_idx)
+ {
+       struct ufshpb_region *rgn;
+       struct ufshpb_subregion *srgn;
+       rgn = hpb->rgn_tbl + rgn_idx;
+       srgn = rgn->srgn_tbl + srgn_idx;
+       list_del_init(&rgn->list_inact_rgn);
+       if (list_empty(&srgn->list_act_srgn))
+               list_add_tail(&srgn->list_act_srgn, &hpb->lh_act_srgn);
+       hpb->stats.rcmd_active_cnt++;
+ }
+ static void ufshpb_update_inactive_info(struct ufshpb_lu *hpb, int rgn_idx)
+ {
+       struct ufshpb_region *rgn;
+       struct ufshpb_subregion *srgn;
+       int srgn_idx;
+       rgn = hpb->rgn_tbl + rgn_idx;
+       for_each_sub_region(rgn, srgn_idx, srgn)
+               list_del_init(&srgn->list_act_srgn);
+       if (list_empty(&rgn->list_inact_rgn))
+               list_add_tail(&rgn->list_inact_rgn, &hpb->lh_inact_rgn);
+       hpb->stats.rcmd_inactive_cnt++;
+ }
+ static void ufshpb_activate_subregion(struct ufshpb_lu *hpb,
+                                     struct ufshpb_subregion *srgn)
+ {
+       struct ufshpb_region *rgn;
+       /*
+        * If there is no mctx in subregion
+        * after I/O progress for HPB_READ_BUFFER, the region to which the
+        * subregion belongs was evicted.
+        * Make sure the region must not evict in I/O progress
+        */
+       if (!srgn->mctx) {
+               dev_err(&hpb->sdev_ufs_lu->sdev_dev,
+                       "no mctx in region %d subregion %d.\n",
+                       srgn->rgn_idx, srgn->srgn_idx);
+               srgn->srgn_state = HPB_SRGN_INVALID;
+               return;
+       }
+       rgn = hpb->rgn_tbl + srgn->rgn_idx;
+       if (unlikely(rgn->rgn_state == HPB_RGN_INACTIVE)) {
+               dev_err(&hpb->sdev_ufs_lu->sdev_dev,
+                       "region %d subregion %d evicted\n",
+                       srgn->rgn_idx, srgn->srgn_idx);
+               srgn->srgn_state = HPB_SRGN_INVALID;
+               return;
+       }
+       srgn->srgn_state = HPB_SRGN_VALID;
+ }
+ static void ufshpb_umap_req_compl_fn(struct request *req, blk_status_t error)
+ {
+       struct ufshpb_req *umap_req = (struct ufshpb_req *)req->end_io_data;
+       ufshpb_put_req(umap_req->hpb, umap_req);
+ }
+ static void ufshpb_map_req_compl_fn(struct request *req, blk_status_t error)
+ {
+       struct ufshpb_req *map_req = (struct ufshpb_req *) req->end_io_data;
+       struct ufshpb_lu *hpb = map_req->hpb;
+       struct ufshpb_subregion *srgn;
+       unsigned long flags;
+       srgn = hpb->rgn_tbl[map_req->rb.rgn_idx].srgn_tbl +
+               map_req->rb.srgn_idx;
+       ufshpb_clear_dirty_bitmap(hpb, srgn);
+       spin_lock_irqsave(&hpb->rgn_state_lock, flags);
+       ufshpb_activate_subregion(hpb, srgn);
+       spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+       ufshpb_put_map_req(map_req->hpb, map_req);
+ }
+ static void ufshpb_set_unmap_cmd(unsigned char *cdb, struct ufshpb_region *rgn)
+ {
+       cdb[0] = UFSHPB_WRITE_BUFFER;
+       cdb[1] = rgn ? UFSHPB_WRITE_BUFFER_INACT_SINGLE_ID :
+                         UFSHPB_WRITE_BUFFER_INACT_ALL_ID;
+       if (rgn)
+               put_unaligned_be16(rgn->rgn_idx, &cdb[2]);
+       cdb[9] = 0x00;
+ }
+ static void ufshpb_set_read_buf_cmd(unsigned char *cdb, int rgn_idx,
+                                   int srgn_idx, int srgn_mem_size)
+ {
+       cdb[0] = UFSHPB_READ_BUFFER;
+       cdb[1] = UFSHPB_READ_BUFFER_ID;
+       put_unaligned_be16(rgn_idx, &cdb[2]);
+       put_unaligned_be16(srgn_idx, &cdb[4]);
+       put_unaligned_be24(srgn_mem_size, &cdb[6]);
+       cdb[9] = 0x00;
+ }
+ static void ufshpb_execute_umap_req(struct ufshpb_lu *hpb,
+                                  struct ufshpb_req *umap_req,
+                                  struct ufshpb_region *rgn)
+ {
+       struct request *req = umap_req->req;
+       struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
+       req->timeout = 0;
+       req->end_io_data = umap_req;
++      req->end_io = ufshpb_umap_req_compl_fn;
+       ufshpb_set_unmap_cmd(scmd->cmnd, rgn);
+       scmd->cmd_len = HPB_WRITE_BUFFER_CMD_LENGTH;
 -      blk_execute_rq_nowait(req, true, ufshpb_map_req_compl_fn);
++      blk_execute_rq_nowait(req, true);
+       hpb->stats.umap_req_cnt++;
+ }
+ static int ufshpb_execute_map_req(struct ufshpb_lu *hpb,
+                                 struct ufshpb_req *map_req, bool last)
+ {
+       struct request_queue *q;
+       struct request *req;
+       struct scsi_cmnd *scmd;
+       int mem_size = hpb->srgn_mem_size;
+       int ret = 0;
+       int i;
+       q = hpb->sdev_ufs_lu->request_queue;
+       for (i = 0; i < hpb->pages_per_srgn; i++) {
+               ret = bio_add_pc_page(q, map_req->bio, map_req->rb.mctx->m_page[i],
+                                     PAGE_SIZE, 0);
+               if (ret != PAGE_SIZE) {
+                       dev_err(&hpb->sdev_ufs_lu->sdev_dev,
+                                  "bio_add_pc_page fail %d - %d\n",
+                                  map_req->rb.rgn_idx, map_req->rb.srgn_idx);
+                       return ret;
+               }
+       }
+       req = map_req->req;
+       blk_rq_append_bio(req, map_req->bio);
+       req->end_io_data = map_req;
++      req->end_io = ufshpb_map_req_compl_fn;
+       if (unlikely(last))
+               mem_size = hpb->last_srgn_entries * HPB_ENTRY_SIZE;
+       scmd = blk_mq_rq_to_pdu(req);
+       ufshpb_set_read_buf_cmd(scmd->cmnd, map_req->rb.rgn_idx,
+                               map_req->rb.srgn_idx, mem_size);
+       scmd->cmd_len = HPB_READ_BUFFER_CMD_LENGTH;
 -      data_seg_len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2)
 -              & MASK_RSP_UPIU_DATA_SEG_LEN;
 -
 -      /* To flush remained rsp_list, we queue the map_work task */
 -      if (!data_seg_len) {
 -              if (!ufshpb_is_general_lun(hpb->lun))
 -                      return;
 -
 -              ufshpb_kick_map_work(hpb);
 -              return;
 -      }
 -
++      blk_execute_rq_nowait(req, true);
+       hpb->stats.map_req_cnt++;
+       return 0;
+ }
+ static struct ufshpb_map_ctx *ufshpb_get_map_ctx(struct ufshpb_lu *hpb,
+                                                bool last)
+ {
+       struct ufshpb_map_ctx *mctx;
+       u32 num_entries = hpb->entries_per_srgn;
+       int i, j;
+       mctx = mempool_alloc(ufshpb_mctx_pool, GFP_KERNEL);
+       if (!mctx)
+               return NULL;
+       mctx->m_page = kmem_cache_alloc(hpb->m_page_cache, GFP_KERNEL);
+       if (!mctx->m_page)
+               goto release_mctx;
+       if (unlikely(last))
+               num_entries = hpb->last_srgn_entries;
+       mctx->ppn_dirty = bitmap_zalloc(num_entries, GFP_KERNEL);
+       if (!mctx->ppn_dirty)
+               goto release_m_page;
+       for (i = 0; i < hpb->pages_per_srgn; i++) {
+               mctx->m_page[i] = mempool_alloc(ufshpb_page_pool, GFP_KERNEL);
+               if (!mctx->m_page[i]) {
+                       for (j = 0; j < i; j++)
+                               mempool_free(mctx->m_page[j], ufshpb_page_pool);
+                       goto release_ppn_dirty;
+               }
+               clear_page(page_address(mctx->m_page[i]));
+       }
+       return mctx;
+ release_ppn_dirty:
+       bitmap_free(mctx->ppn_dirty);
+ release_m_page:
+       kmem_cache_free(hpb->m_page_cache, mctx->m_page);
+ release_mctx:
+       mempool_free(mctx, ufshpb_mctx_pool);
+       return NULL;
+ }
+ static void ufshpb_put_map_ctx(struct ufshpb_lu *hpb,
+                              struct ufshpb_map_ctx *mctx)
+ {
+       int i;
+       for (i = 0; i < hpb->pages_per_srgn; i++)
+               mempool_free(mctx->m_page[i], ufshpb_page_pool);
+       bitmap_free(mctx->ppn_dirty);
+       kmem_cache_free(hpb->m_page_cache, mctx->m_page);
+       mempool_free(mctx, ufshpb_mctx_pool);
+ }
+ static int ufshpb_check_srgns_issue_state(struct ufshpb_lu *hpb,
+                                         struct ufshpb_region *rgn)
+ {
+       struct ufshpb_subregion *srgn;
+       int srgn_idx;
+       for_each_sub_region(rgn, srgn_idx, srgn)
+               if (srgn->srgn_state == HPB_SRGN_ISSUED)
+                       return -EPERM;
+       return 0;
+ }
+ static void ufshpb_read_to_handler(struct work_struct *work)
+ {
+       struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu,
+                                            ufshpb_read_to_work.work);
+       struct victim_select_info *lru_info = &hpb->lru_info;
+       struct ufshpb_region *rgn, *next_rgn;
+       unsigned long flags;
+       unsigned int poll;
+       LIST_HEAD(expired_list);
+       if (test_and_set_bit(TIMEOUT_WORK_RUNNING, &hpb->work_data_bits))
+               return;
+       spin_lock_irqsave(&hpb->rgn_state_lock, flags);
+       list_for_each_entry_safe(rgn, next_rgn, &lru_info->lh_lru_rgn,
+                                list_lru_rgn) {
+               bool timedout = ktime_after(ktime_get(), rgn->read_timeout);
+               if (timedout) {
+                       rgn->read_timeout_expiries--;
+                       if (is_rgn_dirty(rgn) ||
+                           rgn->read_timeout_expiries == 0)
+                               list_add(&rgn->list_expired_rgn, &expired_list);
+                       else
+                               rgn->read_timeout = ktime_add_ms(ktime_get(),
+                                               hpb->params.read_timeout_ms);
+               }
+       }
+       spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+       list_for_each_entry_safe(rgn, next_rgn, &expired_list,
+                                list_expired_rgn) {
+               list_del_init(&rgn->list_expired_rgn);
+               spin_lock_irqsave(&hpb->rsp_list_lock, flags);
+               ufshpb_update_inactive_info(hpb, rgn->rgn_idx);
+               spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
+       }
+       ufshpb_kick_map_work(hpb);
+       clear_bit(TIMEOUT_WORK_RUNNING, &hpb->work_data_bits);
+       poll = hpb->params.timeout_polling_interval_ms;
+       schedule_delayed_work(&hpb->ufshpb_read_to_work,
+                             msecs_to_jiffies(poll));
+ }
+ static void ufshpb_add_lru_info(struct victim_select_info *lru_info,
+                               struct ufshpb_region *rgn)
+ {
+       rgn->rgn_state = HPB_RGN_ACTIVE;
+       list_add_tail(&rgn->list_lru_rgn, &lru_info->lh_lru_rgn);
+       atomic_inc(&lru_info->active_cnt);
+       if (rgn->hpb->is_hcm) {
+               rgn->read_timeout =
+                       ktime_add_ms(ktime_get(),
+                                    rgn->hpb->params.read_timeout_ms);
+               rgn->read_timeout_expiries =
+                       rgn->hpb->params.read_timeout_expiries;
+       }
+ }
+ static void ufshpb_hit_lru_info(struct victim_select_info *lru_info,
+                               struct ufshpb_region *rgn)
+ {
+       list_move_tail(&rgn->list_lru_rgn, &lru_info->lh_lru_rgn);
+ }
+ static struct ufshpb_region *ufshpb_victim_lru_info(struct ufshpb_lu *hpb)
+ {
+       struct victim_select_info *lru_info = &hpb->lru_info;
+       struct ufshpb_region *rgn, *victim_rgn = NULL;
+       list_for_each_entry(rgn, &lru_info->lh_lru_rgn, list_lru_rgn) {
+               if (ufshpb_check_srgns_issue_state(hpb, rgn))
+                       continue;
+               /*
+                * in host control mode, verify that the exiting region
+                * has fewer reads
+                */
+               if (hpb->is_hcm &&
+                   rgn->reads > hpb->params.eviction_thld_exit)
+                       continue;
+               victim_rgn = rgn;
+               break;
+       }
+       if (!victim_rgn)
+               dev_err(&hpb->sdev_ufs_lu->sdev_dev,
+                       "%s: no region allocated\n",
+                       __func__);
+       return victim_rgn;
+ }
+ static void ufshpb_cleanup_lru_info(struct victim_select_info *lru_info,
+                                   struct ufshpb_region *rgn)
+ {
+       list_del_init(&rgn->list_lru_rgn);
+       rgn->rgn_state = HPB_RGN_INACTIVE;
+       atomic_dec(&lru_info->active_cnt);
+ }
+ static void ufshpb_purge_active_subregion(struct ufshpb_lu *hpb,
+                                         struct ufshpb_subregion *srgn)
+ {
+       if (srgn->srgn_state != HPB_SRGN_UNUSED) {
+               ufshpb_put_map_ctx(hpb, srgn->mctx);
+               srgn->srgn_state = HPB_SRGN_UNUSED;
+               srgn->mctx = NULL;
+       }
+ }
+ static int ufshpb_issue_umap_req(struct ufshpb_lu *hpb,
+                                struct ufshpb_region *rgn,
+                                bool atomic)
+ {
+       struct ufshpb_req *umap_req;
+       int rgn_idx = rgn ? rgn->rgn_idx : 0;
+       umap_req = ufshpb_get_req(hpb, rgn_idx, REQ_OP_DRV_OUT, atomic);
+       if (!umap_req)
+               return -ENOMEM;
+       ufshpb_execute_umap_req(hpb, umap_req, rgn);
+       return 0;
+ }
+ static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,
+                                       struct ufshpb_region *rgn)
+ {
+       return ufshpb_issue_umap_req(hpb, rgn, true);
+ }
+ static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
+                                struct ufshpb_region *rgn)
+ {
+       struct victim_select_info *lru_info;
+       struct ufshpb_subregion *srgn;
+       int srgn_idx;
+       lru_info = &hpb->lru_info;
+       dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n", rgn->rgn_idx);
+       ufshpb_cleanup_lru_info(lru_info, rgn);
+       for_each_sub_region(rgn, srgn_idx, srgn)
+               ufshpb_purge_active_subregion(hpb, srgn);
+ }
+ static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn)
+ {
+       unsigned long flags;
+       int ret = 0;
+       spin_lock_irqsave(&hpb->rgn_state_lock, flags);
+       if (rgn->rgn_state == HPB_RGN_PINNED) {
+               dev_warn(&hpb->sdev_ufs_lu->sdev_dev,
+                        "pinned region cannot drop-out. region %d\n",
+                        rgn->rgn_idx);
+               goto out;
+       }
+       if (!list_empty(&rgn->list_lru_rgn)) {
+               if (ufshpb_check_srgns_issue_state(hpb, rgn)) {
+                       ret = -EBUSY;
+                       goto out;
+               }
+               if (hpb->is_hcm) {
+                       spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+                       ret = ufshpb_issue_umap_single_req(hpb, rgn);
+                       spin_lock_irqsave(&hpb->rgn_state_lock, flags);
+                       if (ret)
+                               goto out;
+               }
+               __ufshpb_evict_region(hpb, rgn);
+       }
+ out:
+       spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+       return ret;
+ }
+ static int ufshpb_issue_map_req(struct ufshpb_lu *hpb,
+                               struct ufshpb_region *rgn,
+                               struct ufshpb_subregion *srgn)
+ {
+       struct ufshpb_req *map_req;
+       unsigned long flags;
+       int ret;
+       int err = -EAGAIN;
+       bool alloc_required = false;
+       enum HPB_SRGN_STATE state = HPB_SRGN_INVALID;
+       spin_lock_irqsave(&hpb->rgn_state_lock, flags);
+       if (ufshpb_get_state(hpb) != HPB_PRESENT) {
+               dev_notice(&hpb->sdev_ufs_lu->sdev_dev,
+                          "%s: ufshpb state is not PRESENT\n", __func__);
+               goto unlock_out;
+       }
+       if ((rgn->rgn_state == HPB_RGN_INACTIVE) &&
+           (srgn->srgn_state == HPB_SRGN_INVALID)) {
+               err = 0;
+               goto unlock_out;
+       }
+       if (srgn->srgn_state == HPB_SRGN_UNUSED)
+               alloc_required = true;
+       /*
+        * If the subregion is already ISSUED state,
+        * a specific event (e.g., GC or wear-leveling, etc.) occurs in
+        * the device and HPB response for map loading is received.
+        * In this case, after finishing the HPB_READ_BUFFER,
+        * the next HPB_READ_BUFFER is performed again to obtain the latest
+        * map data.
+        */
+       if (srgn->srgn_state == HPB_SRGN_ISSUED)
+               goto unlock_out;
+       srgn->srgn_state = HPB_SRGN_ISSUED;
+       spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+       if (alloc_required) {
+               srgn->mctx = ufshpb_get_map_ctx(hpb, srgn->is_last);
+               if (!srgn->mctx) {
+                       dev_err(&hpb->sdev_ufs_lu->sdev_dev,
+                           "get map_ctx failed. region %d - %d\n",
+                           rgn->rgn_idx, srgn->srgn_idx);
+                       state = HPB_SRGN_UNUSED;
+                       goto change_srgn_state;
+               }
+       }
+       map_req = ufshpb_get_map_req(hpb, srgn);
+       if (!map_req)
+               goto change_srgn_state;
+       ret = ufshpb_execute_map_req(hpb, map_req, srgn->is_last);
+       if (ret) {
+               dev_err(&hpb->sdev_ufs_lu->sdev_dev,
+                          "%s: issue map_req failed: %d, region %d - %d\n",
+                          __func__, ret, srgn->rgn_idx, srgn->srgn_idx);
+               goto free_map_req;
+       }
+       return 0;
+ free_map_req:
+       ufshpb_put_map_req(hpb, map_req);
+ change_srgn_state:
+       spin_lock_irqsave(&hpb->rgn_state_lock, flags);
+       srgn->srgn_state = state;
+ unlock_out:
+       spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+       return err;
+ }
+ static int ufshpb_add_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn)
+ {
+       struct ufshpb_region *victim_rgn = NULL;
+       struct victim_select_info *lru_info = &hpb->lru_info;
+       unsigned long flags;
+       int ret = 0;
+       spin_lock_irqsave(&hpb->rgn_state_lock, flags);
+       /*
+        * If region belongs to lru_list, just move the region
+        * to the front of lru list because the state of the region
+        * is already active-state.
+        */
+       if (!list_empty(&rgn->list_lru_rgn)) {
+               ufshpb_hit_lru_info(lru_info, rgn);
+               goto out;
+       }
+       if (rgn->rgn_state == HPB_RGN_INACTIVE) {
+               if (atomic_read(&lru_info->active_cnt) ==
+                   lru_info->max_lru_active_cnt) {
+                       /*
+                        * If the maximum number of active regions
+                        * is exceeded, evict the least recently used region.
+                        * This case may occur when the device responds
+                        * to the eviction information late.
+                        * It is okay to evict the least recently used region,
+                        * because the device could detect this region
+                        * by not issuing HPB_READ
+                        *
+                        * in host control mode, verify that the entering
+                        * region has enough reads
+                        */
+                       if (hpb->is_hcm &&
+                           rgn->reads < hpb->params.eviction_thld_enter) {
+                               ret = -EACCES;
+                               goto out;
+                       }
+                       victim_rgn = ufshpb_victim_lru_info(hpb);
+                       if (!victim_rgn) {
+                               dev_warn(&hpb->sdev_ufs_lu->sdev_dev,
+                                   "cannot get victim region %s\n",
+                                   hpb->is_hcm ? "" : "error");
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       dev_dbg(&hpb->sdev_ufs_lu->sdev_dev,
+                               "LRU full (%d), choose victim %d\n",
+                               atomic_read(&lru_info->active_cnt),
+                               victim_rgn->rgn_idx);
+                       if (hpb->is_hcm) {
+                               spin_unlock_irqrestore(&hpb->rgn_state_lock,
+                                                      flags);
+                               ret = ufshpb_issue_umap_single_req(hpb,
+                                                               victim_rgn);
+                               spin_lock_irqsave(&hpb->rgn_state_lock,
+                                                 flags);
+                               if (ret)
+                                       goto out;
+                       }
+                       __ufshpb_evict_region(hpb, victim_rgn);
+               }
+               /*
+                * When a region is added to lru_info list_head,
+                * it is guaranteed that the subregion has been
+                * assigned all mctx. If failed, try to receive mctx again
+                * without being added to lru_info list_head
+                */
+               ufshpb_add_lru_info(lru_info, rgn);
+       }
+ out:
+       spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+       return ret;
+ }
+ /**
+  *ufshpb_submit_region_inactive() - submit a region to be inactivated later
+  *@hpb: per-LU HPB instance
+  *@region_index: the index associated with the region that will be inactivated later
+  */
+ static void ufshpb_submit_region_inactive(struct ufshpb_lu *hpb, int region_index)
+ {
+       int subregion_index;
+       struct ufshpb_region *rgn;
+       struct ufshpb_subregion *srgn;
+       /*
+        * Remove this region from active region list and add it to inactive list
+        */
+       spin_lock(&hpb->rsp_list_lock);
+       ufshpb_update_inactive_info(hpb, region_index);
+       spin_unlock(&hpb->rsp_list_lock);
+       rgn = hpb->rgn_tbl + region_index;
+       /*
+        * Set subregion state to be HPB_SRGN_INVALID, there will no HPB read on this subregion
+        */
+       spin_lock(&hpb->rgn_state_lock);
+       if (rgn->rgn_state != HPB_RGN_INACTIVE) {
+               for (subregion_index = 0; subregion_index < rgn->srgn_cnt; subregion_index++) {
+                       srgn = rgn->srgn_tbl + subregion_index;
+                       if (srgn->srgn_state == HPB_SRGN_VALID)
+                               srgn->srgn_state = HPB_SRGN_INVALID;
+               }
+       }
+       spin_unlock(&hpb->rgn_state_lock);
+ }
+ static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb,
+                                        struct utp_hpb_rsp *rsp_field)
+ {
+       struct ufshpb_region *rgn;
+       struct ufshpb_subregion *srgn;
+       int i, rgn_i, srgn_i;
+       BUILD_BUG_ON(sizeof(struct ufshpb_active_field) != HPB_ACT_FIELD_SIZE);
+       /*
+        * If the active region and the inactive region are the same,
+        * we will inactivate this region.
+        * The device could check this (region inactivated) and
+        * will response the proper active region information
+        */
+       for (i = 0; i < rsp_field->active_rgn_cnt; i++) {
+               rgn_i =
+                       be16_to_cpu(rsp_field->hpb_active_field[i].active_rgn);
+               srgn_i =
+                       be16_to_cpu(rsp_field->hpb_active_field[i].active_srgn);
+               rgn = hpb->rgn_tbl + rgn_i;
+               if (hpb->is_hcm &&
+                   (rgn->rgn_state != HPB_RGN_ACTIVE || is_rgn_dirty(rgn))) {
+                       /*
+                        * in host control mode, subregion activation
+                        * recommendations are only allowed to active regions.
+                        * Also, ignore recommendations for dirty regions - the
+                        * host will make decisions concerning those by himself
+                        */
+                       continue;
+               }
+               dev_dbg(&hpb->sdev_ufs_lu->sdev_dev,
+                       "activate(%d) region %d - %d\n", i, rgn_i, srgn_i);
+               spin_lock(&hpb->rsp_list_lock);
+               ufshpb_update_active_info(hpb, rgn_i, srgn_i);
+               spin_unlock(&hpb->rsp_list_lock);
+               srgn = rgn->srgn_tbl + srgn_i;
+               /* blocking HPB_READ */
+               spin_lock(&hpb->rgn_state_lock);
+               if (srgn->srgn_state == HPB_SRGN_VALID)
+                       srgn->srgn_state = HPB_SRGN_INVALID;
+               spin_unlock(&hpb->rgn_state_lock);
+       }
+       if (hpb->is_hcm) {
+               /*
+                * in host control mode the device is not allowed to inactivate
+                * regions
+                */
+               goto out;
+       }
+       for (i = 0; i < rsp_field->inactive_rgn_cnt; i++) {
+               rgn_i = be16_to_cpu(rsp_field->hpb_inactive_field[i]);
+               dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "inactivate(%d) region %d\n", i, rgn_i);
+               ufshpb_submit_region_inactive(hpb, rgn_i);
+       }
+ out:
+       dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "Noti: #ACT %u #INACT %u\n",
+               rsp_field->active_rgn_cnt, rsp_field->inactive_rgn_cnt);
+       if (ufshpb_get_state(hpb) == HPB_PRESENT)
+               queue_work(ufshpb_wq, &hpb->map_work);
+ }
+ /*
+  * Set the flags of all active regions to RGN_FLAG_UPDATE to let host side reload L2P entries later
+  */
+ static void ufshpb_set_regions_update(struct ufshpb_lu *hpb)
+ {
+       struct victim_select_info *lru_info = &hpb->lru_info;
+       struct ufshpb_region *rgn;
+       unsigned long flags;
+       spin_lock_irqsave(&hpb->rgn_state_lock, flags);
+       list_for_each_entry(rgn, &lru_info->lh_lru_rgn, list_lru_rgn)
+               set_bit(RGN_FLAG_UPDATE, &rgn->rgn_flags);
+       spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+ }
+ static void ufshpb_dev_reset_handler(struct ufs_hba *hba)
+ {
+       struct scsi_device *sdev;
+       struct ufshpb_lu *hpb;
+       __shost_for_each_device(sdev, hba->host) {
+               hpb = ufshpb_get_hpb_data(sdev);
+               if (!hpb)
+                       continue;
+               if (hpb->is_hcm) {
+                       /*
+                        * For the HPB host control mode, in case device powered up and lost HPB
+                        * information, we will set the region flag to be RGN_FLAG_UPDATE, it will
+                        * let host reload its L2P entries(reactivate region in the UFS device).
+                        */
+                       ufshpb_set_regions_update(hpb);
+               } else {
+                       /*
+                        * For the HPB device control mode, if host side receives 02h:HPB Operation
+                        * in UPIU response, which means device recommends the host side should
+                        * inactivate all active regions. Here we add all active regions to inactive
+                        * list, they will be inactivated later in ufshpb_map_work_handler().
+                        */
+                       struct victim_select_info *lru_info = &hpb->lru_info;
+                       struct ufshpb_region *rgn;
+                       list_for_each_entry(rgn, &lru_info->lh_lru_rgn, list_lru_rgn)
+                               ufshpb_submit_region_inactive(hpb, rgn->rgn_idx);
+                       if (ufshpb_get_state(hpb) == HPB_PRESENT)
+                               queue_work(ufshpb_wq, &hpb->map_work);
+               }
+       }
+ }
+ /*
+  * This function will parse recommended active subregion information in sense
+  * data field of response UPIU with SAM_STAT_GOOD state.
+  */
+ void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+ {
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(lrbp->cmd->device);
+       struct utp_hpb_rsp *rsp_field = &lrbp->ucd_rsp_ptr->hr;
+       int data_seg_len;
++      data_seg_len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2)
++              & MASK_RSP_UPIU_DATA_SEG_LEN;
++
++      /* If data segment length is zero, rsp_field is not valid */
++      if (!data_seg_len)
++              return;
++
+       if (unlikely(lrbp->lun != rsp_field->lun)) {
+               struct scsi_device *sdev;
+               bool found = false;
+               __shost_for_each_device(sdev, hba->host) {
+                       hpb = ufshpb_get_hpb_data(sdev);
+                       if (!hpb)
+                               continue;
+                       if (rsp_field->lun == hpb->lun) {
+                               found = true;
+                               break;
+                       }
+               }
+               if (!found)
+                       return;
+       }
+       if (!hpb)
+               return;
+       if (ufshpb_get_state(hpb) == HPB_INIT)
+               return;
+       if ((ufshpb_get_state(hpb) != HPB_PRESENT) &&
+           (ufshpb_get_state(hpb) != HPB_SUSPEND)) {
+               dev_notice(&hpb->sdev_ufs_lu->sdev_dev,
+                          "%s: ufshpb state is not PRESENT/SUSPEND\n",
+                          __func__);
+               return;
+       }
+       BUILD_BUG_ON(sizeof(struct utp_hpb_rsp) != UTP_HPB_RSP_SIZE);
+       if (!ufshpb_is_hpb_rsp_valid(hba, lrbp, rsp_field))
+               return;
+       hpb->stats.rcmd_noti_cnt++;
+       switch (rsp_field->hpb_op) {
+       case HPB_RSP_REQ_REGION_UPDATE:
+               if (data_seg_len != DEV_DATA_SEG_LEN)
+                       dev_warn(&hpb->sdev_ufs_lu->sdev_dev,
+                                "%s: data seg length is not same.\n",
+                                __func__);
+               ufshpb_rsp_req_region_update(hpb, rsp_field);
+               break;
+       case HPB_RSP_DEV_RESET:
+               dev_warn(&hpb->sdev_ufs_lu->sdev_dev,
+                        "UFS device lost HPB information during PM.\n");
+               ufshpb_dev_reset_handler(hba);
+               break;
+       default:
+               dev_notice(&hpb->sdev_ufs_lu->sdev_dev,
+                          "hpb_op is not available: %d\n",
+                          rsp_field->hpb_op);
+               break;
+       }
+ }
+ static void ufshpb_add_active_list(struct ufshpb_lu *hpb,
+                                  struct ufshpb_region *rgn,
+                                  struct ufshpb_subregion *srgn)
+ {
+       if (!list_empty(&rgn->list_inact_rgn))
+               return;
+       if (!list_empty(&srgn->list_act_srgn)) {
+               list_move(&srgn->list_act_srgn, &hpb->lh_act_srgn);
+               return;
+       }
+       list_add(&srgn->list_act_srgn, &hpb->lh_act_srgn);
+ }
+ static void ufshpb_add_pending_evict_list(struct ufshpb_lu *hpb,
+                                         struct ufshpb_region *rgn,
+                                         struct list_head *pending_list)
+ {
+       struct ufshpb_subregion *srgn;
+       int srgn_idx;
+       if (!list_empty(&rgn->list_inact_rgn))
+               return;
+       for_each_sub_region(rgn, srgn_idx, srgn)
+               if (!list_empty(&srgn->list_act_srgn))
+                       return;
+       list_add_tail(&rgn->list_inact_rgn, pending_list);
+ }
+ static void ufshpb_run_active_subregion_list(struct ufshpb_lu *hpb)
+ {
+       struct ufshpb_region *rgn;
+       struct ufshpb_subregion *srgn;
+       unsigned long flags;
+       int ret = 0;
+       spin_lock_irqsave(&hpb->rsp_list_lock, flags);
+       while ((srgn = list_first_entry_or_null(&hpb->lh_act_srgn,
+                                               struct ufshpb_subregion,
+                                               list_act_srgn))) {
+               if (ufshpb_get_state(hpb) == HPB_SUSPEND)
+                       break;
+               list_del_init(&srgn->list_act_srgn);
+               spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
+               rgn = hpb->rgn_tbl + srgn->rgn_idx;
+               ret = ufshpb_add_region(hpb, rgn);
+               if (ret)
+                       goto active_failed;
+               ret = ufshpb_issue_map_req(hpb, rgn, srgn);
+               if (ret) {
+                       dev_err(&hpb->sdev_ufs_lu->sdev_dev,
+                           "issue map_req failed. ret %d, region %d - %d\n",
+                           ret, rgn->rgn_idx, srgn->srgn_idx);
+                       goto active_failed;
+               }
+               spin_lock_irqsave(&hpb->rsp_list_lock, flags);
+       }
+       spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
+       return;
+ active_failed:
+       dev_err(&hpb->sdev_ufs_lu->sdev_dev, "failed to activate region %d - %d, will retry\n",
+                  rgn->rgn_idx, srgn->srgn_idx);
+       spin_lock_irqsave(&hpb->rsp_list_lock, flags);
+       ufshpb_add_active_list(hpb, rgn, srgn);
+       spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
+ }
+ static void ufshpb_run_inactive_region_list(struct ufshpb_lu *hpb)
+ {
+       struct ufshpb_region *rgn;
+       unsigned long flags;
+       int ret;
+       LIST_HEAD(pending_list);
+       spin_lock_irqsave(&hpb->rsp_list_lock, flags);
+       while ((rgn = list_first_entry_or_null(&hpb->lh_inact_rgn,
+                                              struct ufshpb_region,
+                                              list_inact_rgn))) {
+               if (ufshpb_get_state(hpb) == HPB_SUSPEND)
+                       break;
+               list_del_init(&rgn->list_inact_rgn);
+               spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
+               ret = ufshpb_evict_region(hpb, rgn);
+               if (ret) {
+                       spin_lock_irqsave(&hpb->rsp_list_lock, flags);
+                       ufshpb_add_pending_evict_list(hpb, rgn, &pending_list);
+                       spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
+               }
+               spin_lock_irqsave(&hpb->rsp_list_lock, flags);
+       }
+       list_splice(&pending_list, &hpb->lh_inact_rgn);
+       spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
+ }
+ static void ufshpb_normalization_work_handler(struct work_struct *work)
+ {
+       struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu,
+                                            ufshpb_normalization_work);
+       int rgn_idx;
+       u8 factor = hpb->params.normalization_factor;
+       for (rgn_idx = 0; rgn_idx < hpb->rgns_per_lu; rgn_idx++) {
+               struct ufshpb_region *rgn = hpb->rgn_tbl + rgn_idx;
+               int srgn_idx;
+               spin_lock(&rgn->rgn_lock);
+               rgn->reads = 0;
+               for (srgn_idx = 0; srgn_idx < hpb->srgns_per_rgn; srgn_idx++) {
+                       struct ufshpb_subregion *srgn = rgn->srgn_tbl + srgn_idx;
+                       srgn->reads >>= factor;
+                       rgn->reads += srgn->reads;
+               }
+               spin_unlock(&rgn->rgn_lock);
+               if (rgn->rgn_state != HPB_RGN_ACTIVE || rgn->reads)
+                       continue;
+               /* if region is active but has no reads - inactivate it */
+               spin_lock(&hpb->rsp_list_lock);
+               ufshpb_update_inactive_info(hpb, rgn->rgn_idx);
+               spin_unlock(&hpb->rsp_list_lock);
+       }
+ }
+ static void ufshpb_map_work_handler(struct work_struct *work)
+ {
+       struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu, map_work);
+       if (ufshpb_get_state(hpb) != HPB_PRESENT) {
+               dev_notice(&hpb->sdev_ufs_lu->sdev_dev,
+                          "%s: ufshpb state is not PRESENT\n", __func__);
+               return;
+       }
+       ufshpb_run_inactive_region_list(hpb);
+       ufshpb_run_active_subregion_list(hpb);
+ }
+ /*
+  * this function doesn't need to hold lock due to be called in init.
+  * (rgn_state_lock, rsp_list_lock, etc..)
+  */
+ static int ufshpb_init_pinned_active_region(struct ufs_hba *hba,
+                                           struct ufshpb_lu *hpb,
+                                           struct ufshpb_region *rgn)
+ {
+       struct ufshpb_subregion *srgn;
+       int srgn_idx, i;
+       int err = 0;
+       for_each_sub_region(rgn, srgn_idx, srgn) {
+               srgn->mctx = ufshpb_get_map_ctx(hpb, srgn->is_last);
+               srgn->srgn_state = HPB_SRGN_INVALID;
+               if (!srgn->mctx) {
+                       err = -ENOMEM;
+                       dev_err(hba->dev,
+                               "alloc mctx for pinned region failed\n");
+                       goto release;
+               }
+               list_add_tail(&srgn->list_act_srgn, &hpb->lh_act_srgn);
+       }
+       rgn->rgn_state = HPB_RGN_PINNED;
+       return 0;
+ release:
+       for (i = 0; i < srgn_idx; i++) {
+               srgn = rgn->srgn_tbl + i;
+               ufshpb_put_map_ctx(hpb, srgn->mctx);
+       }
+       return err;
+ }
+ static void ufshpb_init_subregion_tbl(struct ufshpb_lu *hpb,
+                                     struct ufshpb_region *rgn, bool last)
+ {
+       int srgn_idx;
+       struct ufshpb_subregion *srgn;
+       for_each_sub_region(rgn, srgn_idx, srgn) {
+               INIT_LIST_HEAD(&srgn->list_act_srgn);
+               srgn->rgn_idx = rgn->rgn_idx;
+               srgn->srgn_idx = srgn_idx;
+               srgn->srgn_state = HPB_SRGN_UNUSED;
+       }
+       if (unlikely(last && hpb->last_srgn_entries))
+               srgn->is_last = true;
+ }
+ static int ufshpb_alloc_subregion_tbl(struct ufshpb_lu *hpb,
+                                     struct ufshpb_region *rgn, int srgn_cnt)
+ {
+       rgn->srgn_tbl = kvcalloc(srgn_cnt, sizeof(struct ufshpb_subregion),
+                                GFP_KERNEL);
+       if (!rgn->srgn_tbl)
+               return -ENOMEM;
+       rgn->srgn_cnt = srgn_cnt;
+       return 0;
+ }
+ static void ufshpb_lu_parameter_init(struct ufs_hba *hba,
+                                    struct ufshpb_lu *hpb,
+                                    struct ufshpb_dev_info *hpb_dev_info,
+                                    struct ufshpb_lu_info *hpb_lu_info)
+ {
+       u32 entries_per_rgn;
+       u64 rgn_mem_size, tmp;
+       if (ufshpb_is_legacy(hba))
+               hpb->pre_req_max_tr_len = HPB_LEGACY_CHUNK_HIGH;
+       else
+               hpb->pre_req_max_tr_len = hpb_dev_info->max_hpb_single_cmd;
+       hpb->lu_pinned_start = hpb_lu_info->pinned_start;
+       hpb->lu_pinned_end = hpb_lu_info->num_pinned ?
+               (hpb_lu_info->pinned_start + hpb_lu_info->num_pinned - 1)
+               : PINNED_NOT_SET;
+       hpb->lru_info.max_lru_active_cnt =
+               hpb_lu_info->max_active_rgns - hpb_lu_info->num_pinned;
+       rgn_mem_size = (1ULL << hpb_dev_info->rgn_size) * HPB_RGN_SIZE_UNIT
+                       * HPB_ENTRY_SIZE;
+       do_div(rgn_mem_size, HPB_ENTRY_BLOCK_SIZE);
+       hpb->srgn_mem_size = (1ULL << hpb_dev_info->srgn_size)
+               * HPB_RGN_SIZE_UNIT / HPB_ENTRY_BLOCK_SIZE * HPB_ENTRY_SIZE;
+       tmp = rgn_mem_size;
+       do_div(tmp, HPB_ENTRY_SIZE);
+       entries_per_rgn = (u32)tmp;
+       hpb->entries_per_rgn_shift = ilog2(entries_per_rgn);
+       hpb->entries_per_rgn_mask = entries_per_rgn - 1;
+       hpb->entries_per_srgn = hpb->srgn_mem_size / HPB_ENTRY_SIZE;
+       hpb->entries_per_srgn_shift = ilog2(hpb->entries_per_srgn);
+       hpb->entries_per_srgn_mask = hpb->entries_per_srgn - 1;
+       tmp = rgn_mem_size;
+       do_div(tmp, hpb->srgn_mem_size);
+       hpb->srgns_per_rgn = (int)tmp;
+       hpb->rgns_per_lu = DIV_ROUND_UP(hpb_lu_info->num_blocks,
+                               entries_per_rgn);
+       hpb->srgns_per_lu = DIV_ROUND_UP(hpb_lu_info->num_blocks,
+                               (hpb->srgn_mem_size / HPB_ENTRY_SIZE));
+       hpb->last_srgn_entries = hpb_lu_info->num_blocks
+                                % (hpb->srgn_mem_size / HPB_ENTRY_SIZE);
+       hpb->pages_per_srgn = DIV_ROUND_UP(hpb->srgn_mem_size, PAGE_SIZE);
+       if (hpb_dev_info->control_mode == HPB_HOST_CONTROL)
+               hpb->is_hcm = true;
+ }
+ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb)
+ {
+       struct ufshpb_region *rgn_table, *rgn;
+       int rgn_idx, i;
+       int ret = 0;
+       rgn_table = kvcalloc(hpb->rgns_per_lu, sizeof(struct ufshpb_region),
+                           GFP_KERNEL);
+       if (!rgn_table)
+               return -ENOMEM;
+       for (rgn_idx = 0; rgn_idx < hpb->rgns_per_lu; rgn_idx++) {
+               int srgn_cnt = hpb->srgns_per_rgn;
+               bool last_srgn = false;
+               rgn = rgn_table + rgn_idx;
+               rgn->rgn_idx = rgn_idx;
+               spin_lock_init(&rgn->rgn_lock);
+               INIT_LIST_HEAD(&rgn->list_inact_rgn);
+               INIT_LIST_HEAD(&rgn->list_lru_rgn);
+               INIT_LIST_HEAD(&rgn->list_expired_rgn);
+               if (rgn_idx == hpb->rgns_per_lu - 1) {
+                       srgn_cnt = ((hpb->srgns_per_lu - 1) %
+                                   hpb->srgns_per_rgn) + 1;
+                       last_srgn = true;
+               }
+               ret = ufshpb_alloc_subregion_tbl(hpb, rgn, srgn_cnt);
+               if (ret)
+                       goto release_srgn_table;
+               ufshpb_init_subregion_tbl(hpb, rgn, last_srgn);
+               if (ufshpb_is_pinned_region(hpb, rgn_idx)) {
+                       ret = ufshpb_init_pinned_active_region(hba, hpb, rgn);
+                       if (ret)
+                               goto release_srgn_table;
+               } else {
+                       rgn->rgn_state = HPB_RGN_INACTIVE;
+               }
+               rgn->rgn_flags = 0;
+               rgn->hpb = hpb;
+       }
+       hpb->rgn_tbl = rgn_table;
+       return 0;
+ release_srgn_table:
+       for (i = 0; i <= rgn_idx; i++)
+               kvfree(rgn_table[i].srgn_tbl);
+       kvfree(rgn_table);
+       return ret;
+ }
+ static void ufshpb_destroy_subregion_tbl(struct ufshpb_lu *hpb,
+                                        struct ufshpb_region *rgn)
+ {
+       int srgn_idx;
+       struct ufshpb_subregion *srgn;
+       for_each_sub_region(rgn, srgn_idx, srgn)
+               if (srgn->srgn_state != HPB_SRGN_UNUSED) {
+                       srgn->srgn_state = HPB_SRGN_UNUSED;
+                       ufshpb_put_map_ctx(hpb, srgn->mctx);
+               }
+ }
+ static void ufshpb_destroy_region_tbl(struct ufshpb_lu *hpb)
+ {
+       int rgn_idx;
+       for (rgn_idx = 0; rgn_idx < hpb->rgns_per_lu; rgn_idx++) {
+               struct ufshpb_region *rgn;
+               rgn = hpb->rgn_tbl + rgn_idx;
+               if (rgn->rgn_state != HPB_RGN_INACTIVE) {
+                       rgn->rgn_state = HPB_RGN_INACTIVE;
+                       ufshpb_destroy_subregion_tbl(hpb, rgn);
+               }
+               kvfree(rgn->srgn_tbl);
+       }
+       kvfree(hpb->rgn_tbl);
+ }
+ /* SYSFS functions */
+ #define ufshpb_sysfs_attr_show_func(__name)                           \
+ static ssize_t __name##_show(struct device *dev,                      \
+       struct device_attribute *attr, char *buf)                       \
+ {                                                                     \
+       struct scsi_device *sdev = to_scsi_device(dev);                 \
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);              \
+                                                                       \
+       if (!hpb)                                                       \
+               return -ENODEV;                                         \
+                                                                       \
+       return sysfs_emit(buf, "%llu\n", hpb->stats.__name);            \
+ }                                                                     \
+ \
+ static DEVICE_ATTR_RO(__name)
+ ufshpb_sysfs_attr_show_func(hit_cnt);
+ ufshpb_sysfs_attr_show_func(miss_cnt);
+ ufshpb_sysfs_attr_show_func(rcmd_noti_cnt);
+ ufshpb_sysfs_attr_show_func(rcmd_active_cnt);
+ ufshpb_sysfs_attr_show_func(rcmd_inactive_cnt);
+ ufshpb_sysfs_attr_show_func(map_req_cnt);
+ ufshpb_sysfs_attr_show_func(umap_req_cnt);
+ static struct attribute *hpb_dev_stat_attrs[] = {
+       &dev_attr_hit_cnt.attr,
+       &dev_attr_miss_cnt.attr,
+       &dev_attr_rcmd_noti_cnt.attr,
+       &dev_attr_rcmd_active_cnt.attr,
+       &dev_attr_rcmd_inactive_cnt.attr,
+       &dev_attr_map_req_cnt.attr,
+       &dev_attr_umap_req_cnt.attr,
+       NULL,
+ };
+ struct attribute_group ufs_sysfs_hpb_stat_group = {
+       .name = "hpb_stats",
+       .attrs = hpb_dev_stat_attrs,
+ };
+ /* SYSFS functions */
+ #define ufshpb_sysfs_param_show_func(__name)                          \
+ static ssize_t __name##_show(struct device *dev,                      \
+       struct device_attribute *attr, char *buf)                       \
+ {                                                                     \
+       struct scsi_device *sdev = to_scsi_device(dev);                 \
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);              \
+                                                                       \
+       if (!hpb)                                                       \
+               return -ENODEV;                                         \
+                                                                       \
+       return sysfs_emit(buf, "%d\n", hpb->params.__name);             \
+ }
+ ufshpb_sysfs_param_show_func(requeue_timeout_ms);
+ static ssize_t
+ requeue_timeout_ms_store(struct device *dev, struct device_attribute *attr,
+                        const char *buf, size_t count)
+ {
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);
+       int val;
+       if (!hpb)
+               return -ENODEV;
+       if (kstrtouint(buf, 0, &val))
+               return -EINVAL;
+       if (val < 0)
+               return -EINVAL;
+       hpb->params.requeue_timeout_ms = val;
+       return count;
+ }
+ static DEVICE_ATTR_RW(requeue_timeout_ms);
+ ufshpb_sysfs_param_show_func(activation_thld);
+ static ssize_t
+ activation_thld_store(struct device *dev, struct device_attribute *attr,
+                     const char *buf, size_t count)
+ {
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);
+       int val;
+       if (!hpb)
+               return -ENODEV;
+       if (!hpb->is_hcm)
+               return -EOPNOTSUPP;
+       if (kstrtouint(buf, 0, &val))
+               return -EINVAL;
+       if (val <= 0)
+               return -EINVAL;
+       hpb->params.activation_thld = val;
+       return count;
+ }
+ static DEVICE_ATTR_RW(activation_thld);
+ ufshpb_sysfs_param_show_func(normalization_factor);
+ static ssize_t
+ normalization_factor_store(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
+ {
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);
+       int val;
+       if (!hpb)
+               return -ENODEV;
+       if (!hpb->is_hcm)
+               return -EOPNOTSUPP;
+       if (kstrtouint(buf, 0, &val))
+               return -EINVAL;
+       if (val <= 0 || val > ilog2(hpb->entries_per_srgn))
+               return -EINVAL;
+       hpb->params.normalization_factor = val;
+       return count;
+ }
+ static DEVICE_ATTR_RW(normalization_factor);
+ ufshpb_sysfs_param_show_func(eviction_thld_enter);
+ static ssize_t
+ eviction_thld_enter_store(struct device *dev, struct device_attribute *attr,
+                         const char *buf, size_t count)
+ {
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);
+       int val;
+       if (!hpb)
+               return -ENODEV;
+       if (!hpb->is_hcm)
+               return -EOPNOTSUPP;
+       if (kstrtouint(buf, 0, &val))
+               return -EINVAL;
+       if (val <= hpb->params.eviction_thld_exit)
+               return -EINVAL;
+       hpb->params.eviction_thld_enter = val;
+       return count;
+ }
+ static DEVICE_ATTR_RW(eviction_thld_enter);
+ ufshpb_sysfs_param_show_func(eviction_thld_exit);
+ static ssize_t
+ eviction_thld_exit_store(struct device *dev, struct device_attribute *attr,
+                        const char *buf, size_t count)
+ {
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);
+       int val;
+       if (!hpb)
+               return -ENODEV;
+       if (!hpb->is_hcm)
+               return -EOPNOTSUPP;
+       if (kstrtouint(buf, 0, &val))
+               return -EINVAL;
+       if (val <= hpb->params.activation_thld)
+               return -EINVAL;
+       hpb->params.eviction_thld_exit = val;
+       return count;
+ }
+ static DEVICE_ATTR_RW(eviction_thld_exit);
+ ufshpb_sysfs_param_show_func(read_timeout_ms);
+ static ssize_t
+ read_timeout_ms_store(struct device *dev, struct device_attribute *attr,
+                     const char *buf, size_t count)
+ {
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);
+       int val;
+       if (!hpb)
+               return -ENODEV;
+       if (!hpb->is_hcm)
+               return -EOPNOTSUPP;
+       if (kstrtouint(buf, 0, &val))
+               return -EINVAL;
+       /* read_timeout >> timeout_polling_interval */
+       if (val < hpb->params.timeout_polling_interval_ms * 2)
+               return -EINVAL;
+       hpb->params.read_timeout_ms = val;
+       return count;
+ }
+ static DEVICE_ATTR_RW(read_timeout_ms);
+ ufshpb_sysfs_param_show_func(read_timeout_expiries);
+ static ssize_t
+ read_timeout_expiries_store(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t count)
+ {
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);
+       int val;
+       if (!hpb)
+               return -ENODEV;
+       if (!hpb->is_hcm)
+               return -EOPNOTSUPP;
+       if (kstrtouint(buf, 0, &val))
+               return -EINVAL;
+       if (val <= 0)
+               return -EINVAL;
+       hpb->params.read_timeout_expiries = val;
+       return count;
+ }
+ static DEVICE_ATTR_RW(read_timeout_expiries);
+ ufshpb_sysfs_param_show_func(timeout_polling_interval_ms);
+ static ssize_t
+ timeout_polling_interval_ms_store(struct device *dev,
+                                 struct device_attribute *attr,
+                                 const char *buf, size_t count)
+ {
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);
+       int val;
+       if (!hpb)
+               return -ENODEV;
+       if (!hpb->is_hcm)
+               return -EOPNOTSUPP;
+       if (kstrtouint(buf, 0, &val))
+               return -EINVAL;
+       /* timeout_polling_interval << read_timeout */
+       if (val <= 0 || val > hpb->params.read_timeout_ms / 2)
+               return -EINVAL;
+       hpb->params.timeout_polling_interval_ms = val;
+       return count;
+ }
+ static DEVICE_ATTR_RW(timeout_polling_interval_ms);
+ ufshpb_sysfs_param_show_func(inflight_map_req);
+ static ssize_t inflight_map_req_store(struct device *dev,
+                                     struct device_attribute *attr,
+                                     const char *buf, size_t count)
+ {
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);
+       int val;
+       if (!hpb)
+               return -ENODEV;
+       if (!hpb->is_hcm)
+               return -EOPNOTSUPP;
+       if (kstrtouint(buf, 0, &val))
+               return -EINVAL;
+       if (val <= 0 || val > hpb->sdev_ufs_lu->queue_depth - 1)
+               return -EINVAL;
+       hpb->params.inflight_map_req = val;
+       return count;
+ }
+ static DEVICE_ATTR_RW(inflight_map_req);
+ static void ufshpb_hcm_param_init(struct ufshpb_lu *hpb)
+ {
+       hpb->params.activation_thld = ACTIVATION_THRESHOLD;
+       hpb->params.normalization_factor = 1;
+       hpb->params.eviction_thld_enter = (ACTIVATION_THRESHOLD << 5);
+       hpb->params.eviction_thld_exit = (ACTIVATION_THRESHOLD << 4);
+       hpb->params.read_timeout_ms = READ_TO_MS;
+       hpb->params.read_timeout_expiries = READ_TO_EXPIRIES;
+       hpb->params.timeout_polling_interval_ms = POLLING_INTERVAL_MS;
+       hpb->params.inflight_map_req = THROTTLE_MAP_REQ_DEFAULT;
+ }
+ static struct attribute *hpb_dev_param_attrs[] = {
+       &dev_attr_requeue_timeout_ms.attr,
+       &dev_attr_activation_thld.attr,
+       &dev_attr_normalization_factor.attr,
+       &dev_attr_eviction_thld_enter.attr,
+       &dev_attr_eviction_thld_exit.attr,
+       &dev_attr_read_timeout_ms.attr,
+       &dev_attr_read_timeout_expiries.attr,
+       &dev_attr_timeout_polling_interval_ms.attr,
+       &dev_attr_inflight_map_req.attr,
+       NULL,
+ };
+ struct attribute_group ufs_sysfs_hpb_param_group = {
+       .name = "hpb_params",
+       .attrs = hpb_dev_param_attrs,
+ };
+ static int ufshpb_pre_req_mempool_init(struct ufshpb_lu *hpb)
+ {
+       struct ufshpb_req *pre_req = NULL, *t;
+       int qd = hpb->sdev_ufs_lu->queue_depth / 2;
+       int i;
+       INIT_LIST_HEAD(&hpb->lh_pre_req_free);
+       hpb->pre_req = kcalloc(qd, sizeof(struct ufshpb_req), GFP_KERNEL);
+       hpb->throttle_pre_req = qd;
+       hpb->num_inflight_pre_req = 0;
+       if (!hpb->pre_req)
+               goto release_mem;
+       for (i = 0; i < qd; i++) {
+               pre_req = hpb->pre_req + i;
+               INIT_LIST_HEAD(&pre_req->list_req);
+               pre_req->req = NULL;
+               pre_req->bio = bio_alloc(NULL, 1, 0, GFP_KERNEL);
+               if (!pre_req->bio)
+                       goto release_mem;
+               pre_req->wb.m_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+               if (!pre_req->wb.m_page) {
+                       bio_put(pre_req->bio);
+                       goto release_mem;
+               }
+               list_add_tail(&pre_req->list_req, &hpb->lh_pre_req_free);
+       }
+       return 0;
+ release_mem:
+       list_for_each_entry_safe(pre_req, t, &hpb->lh_pre_req_free, list_req) {
+               list_del_init(&pre_req->list_req);
+               bio_put(pre_req->bio);
+               __free_page(pre_req->wb.m_page);
+       }
+       kfree(hpb->pre_req);
+       return -ENOMEM;
+ }
+ static void ufshpb_pre_req_mempool_destroy(struct ufshpb_lu *hpb)
+ {
+       struct ufshpb_req *pre_req = NULL;
+       int i;
+       for (i = 0; i < hpb->throttle_pre_req; i++) {
+               pre_req = hpb->pre_req + i;
+               bio_put(hpb->pre_req[i].bio);
+               if (!pre_req->wb.m_page)
+                       __free_page(hpb->pre_req[i].wb.m_page);
+               list_del_init(&pre_req->list_req);
+       }
+       kfree(hpb->pre_req);
+ }
+ static void ufshpb_stat_init(struct ufshpb_lu *hpb)
+ {
+       hpb->stats.hit_cnt = 0;
+       hpb->stats.miss_cnt = 0;
+       hpb->stats.rcmd_noti_cnt = 0;
+       hpb->stats.rcmd_active_cnt = 0;
+       hpb->stats.rcmd_inactive_cnt = 0;
+       hpb->stats.map_req_cnt = 0;
+       hpb->stats.umap_req_cnt = 0;
+ }
+ static void ufshpb_param_init(struct ufshpb_lu *hpb)
+ {
+       hpb->params.requeue_timeout_ms = HPB_REQUEUE_TIME_MS;
+       if (hpb->is_hcm)
+               ufshpb_hcm_param_init(hpb);
+ }
+ static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb)
+ {
+       int ret;
+       spin_lock_init(&hpb->rgn_state_lock);
+       spin_lock_init(&hpb->rsp_list_lock);
+       spin_lock_init(&hpb->param_lock);
+       INIT_LIST_HEAD(&hpb->lru_info.lh_lru_rgn);
+       INIT_LIST_HEAD(&hpb->lh_act_srgn);
+       INIT_LIST_HEAD(&hpb->lh_inact_rgn);
+       INIT_LIST_HEAD(&hpb->list_hpb_lu);
+       INIT_WORK(&hpb->map_work, ufshpb_map_work_handler);
+       if (hpb->is_hcm) {
+               INIT_WORK(&hpb->ufshpb_normalization_work,
+                         ufshpb_normalization_work_handler);
+               INIT_DELAYED_WORK(&hpb->ufshpb_read_to_work,
+                                 ufshpb_read_to_handler);
+       }
+       hpb->map_req_cache = kmem_cache_create("ufshpb_req_cache",
+                         sizeof(struct ufshpb_req), 0, 0, NULL);
+       if (!hpb->map_req_cache) {
+               dev_err(hba->dev, "ufshpb(%d) ufshpb_req_cache create fail",
+                       hpb->lun);
+               return -ENOMEM;
+       }
+       hpb->m_page_cache = kmem_cache_create("ufshpb_m_page_cache",
+                         sizeof(struct page *) * hpb->pages_per_srgn,
+                         0, 0, NULL);
+       if (!hpb->m_page_cache) {
+               dev_err(hba->dev, "ufshpb(%d) ufshpb_m_page_cache create fail",
+                       hpb->lun);
+               ret = -ENOMEM;
+               goto release_req_cache;
+       }
+       ret = ufshpb_pre_req_mempool_init(hpb);
+       if (ret) {
+               dev_err(hba->dev, "ufshpb(%d) pre_req_mempool init fail",
+                       hpb->lun);
+               goto release_m_page_cache;
+       }
+       ret = ufshpb_alloc_region_tbl(hba, hpb);
+       if (ret)
+               goto release_pre_req_mempool;
+       ufshpb_stat_init(hpb);
+       ufshpb_param_init(hpb);
+       if (hpb->is_hcm) {
+               unsigned int poll;
+               poll = hpb->params.timeout_polling_interval_ms;
+               schedule_delayed_work(&hpb->ufshpb_read_to_work,
+                                     msecs_to_jiffies(poll));
+       }
+       return 0;
+ release_pre_req_mempool:
+       ufshpb_pre_req_mempool_destroy(hpb);
+ release_m_page_cache:
+       kmem_cache_destroy(hpb->m_page_cache);
+ release_req_cache:
+       kmem_cache_destroy(hpb->map_req_cache);
+       return ret;
+ }
+ static struct ufshpb_lu *
+ ufshpb_alloc_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev,
+                   struct ufshpb_dev_info *hpb_dev_info,
+                   struct ufshpb_lu_info *hpb_lu_info)
+ {
+       struct ufshpb_lu *hpb;
+       int ret;
+       hpb = kzalloc(sizeof(struct ufshpb_lu), GFP_KERNEL);
+       if (!hpb)
+               return NULL;
+       hpb->lun = sdev->lun;
+       hpb->sdev_ufs_lu = sdev;
+       ufshpb_lu_parameter_init(hba, hpb, hpb_dev_info, hpb_lu_info);
+       ret = ufshpb_lu_hpb_init(hba, hpb);
+       if (ret) {
+               dev_err(hba->dev, "hpb lu init failed. ret %d", ret);
+               goto release_hpb;
+       }
+       sdev->hostdata = hpb;
+       return hpb;
+ release_hpb:
+       kfree(hpb);
+       return NULL;
+ }
+ static void ufshpb_discard_rsp_lists(struct ufshpb_lu *hpb)
+ {
+       struct ufshpb_region *rgn, *next_rgn;
+       struct ufshpb_subregion *srgn, *next_srgn;
+       unsigned long flags;
+       /*
+        * If the device reset occurred, the remaining HPB region information
+        * may be stale. Therefore, by discarding the lists of HPB response
+        * that remained after reset, we prevent unnecessary work.
+        */
+       spin_lock_irqsave(&hpb->rsp_list_lock, flags);
+       list_for_each_entry_safe(rgn, next_rgn, &hpb->lh_inact_rgn,
+                                list_inact_rgn)
+               list_del_init(&rgn->list_inact_rgn);
+       list_for_each_entry_safe(srgn, next_srgn, &hpb->lh_act_srgn,
+                                list_act_srgn)
+               list_del_init(&srgn->list_act_srgn);
+       spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
+ }
+ static void ufshpb_cancel_jobs(struct ufshpb_lu *hpb)
+ {
+       if (hpb->is_hcm) {
+               cancel_delayed_work_sync(&hpb->ufshpb_read_to_work);
+               cancel_work_sync(&hpb->ufshpb_normalization_work);
+       }
+       cancel_work_sync(&hpb->map_work);
+ }
+ static bool ufshpb_check_hpb_reset_query(struct ufs_hba *hba)
+ {
+       int err = 0;
+       bool flag_res = true;
+       int try;
+       /* wait for the device to complete HPB reset query */
+       for (try = 0; try < HPB_RESET_REQ_RETRIES; try++) {
+               dev_dbg(hba->dev,
+                       "%s start flag reset polling %d times\n",
+                       __func__, try);
+               /* Poll fHpbReset flag to be cleared */
+               err = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG,
+                               QUERY_FLAG_IDN_HPB_RESET, 0, &flag_res);
+               if (err) {
+                       dev_err(hba->dev,
+                               "%s reading fHpbReset flag failed with error %d\n",
+                               __func__, err);
+                       return flag_res;
+               }
+               if (!flag_res)
+                       goto out;
+               usleep_range(1000, 1100);
+       }
+       if (flag_res) {
+               dev_err(hba->dev,
+                       "%s fHpbReset was not cleared by the device\n",
+                       __func__);
+       }
+ out:
+       return flag_res;
+ }
+ /**
+  * ufshpb_toggle_state - switch HPB state of all LUs
+  * @hba: per-adapter instance
+  * @src: expected current HPB state
+  * @dest: target HPB state to switch to
+  */
+ void ufshpb_toggle_state(struct ufs_hba *hba, enum UFSHPB_STATE src, enum UFSHPB_STATE dest)
+ {
+       struct ufshpb_lu *hpb;
+       struct scsi_device *sdev;
+       shost_for_each_device(sdev, hba->host) {
+               hpb = ufshpb_get_hpb_data(sdev);
+               if (!hpb || ufshpb_get_state(hpb) != src)
+                       continue;
+               ufshpb_set_state(hpb, dest);
+               if (dest == HPB_RESET) {
+                       ufshpb_cancel_jobs(hpb);
+                       ufshpb_discard_rsp_lists(hpb);
+               }
+       }
+ }
+ void ufshpb_suspend(struct ufs_hba *hba)
+ {
+       struct ufshpb_lu *hpb;
+       struct scsi_device *sdev;
+       shost_for_each_device(sdev, hba->host) {
+               hpb = ufshpb_get_hpb_data(sdev);
+               if (!hpb || ufshpb_get_state(hpb) != HPB_PRESENT)
+                       continue;
+               ufshpb_set_state(hpb, HPB_SUSPEND);
+               ufshpb_cancel_jobs(hpb);
+       }
+ }
+ void ufshpb_resume(struct ufs_hba *hba)
+ {
+       struct ufshpb_lu *hpb;
+       struct scsi_device *sdev;
+       shost_for_each_device(sdev, hba->host) {
+               hpb = ufshpb_get_hpb_data(sdev);
+               if (!hpb || ufshpb_get_state(hpb) != HPB_SUSPEND)
+                       continue;
+               ufshpb_set_state(hpb, HPB_PRESENT);
+               ufshpb_kick_map_work(hpb);
+               if (hpb->is_hcm) {
+                       unsigned int poll = hpb->params.timeout_polling_interval_ms;
+                       schedule_delayed_work(&hpb->ufshpb_read_to_work, msecs_to_jiffies(poll));
+               }
+       }
+ }
+ static int ufshpb_get_lu_info(struct ufs_hba *hba, int lun,
+                             struct ufshpb_lu_info *hpb_lu_info)
+ {
+       u16 max_active_rgns;
+       u8 lu_enable;
+       int size;
+       int ret;
+       char desc_buf[QUERY_DESC_MAX_SIZE];
+       ufshcd_map_desc_id_to_length(hba, QUERY_DESC_IDN_UNIT, &size);
+       ufshcd_rpm_get_sync(hba);
+       ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC,
+                                           QUERY_DESC_IDN_UNIT, lun, 0,
+                                           desc_buf, &size);
+       ufshcd_rpm_put_sync(hba);
+       if (ret) {
+               dev_err(hba->dev,
+                       "%s: idn: %d lun: %d  query request failed",
+                       __func__, QUERY_DESC_IDN_UNIT, lun);
+               return ret;
+       }
+       lu_enable = desc_buf[UNIT_DESC_PARAM_LU_ENABLE];
+       if (lu_enable != LU_ENABLED_HPB_FUNC)
+               return -ENODEV;
+       max_active_rgns = get_unaligned_be16(
+                       desc_buf + UNIT_DESC_PARAM_HPB_LU_MAX_ACTIVE_RGNS);
+       if (!max_active_rgns) {
+               dev_err(hba->dev,
+                       "lun %d wrong number of max active regions\n", lun);
+               return -ENODEV;
+       }
+       hpb_lu_info->num_blocks = get_unaligned_be64(
+                       desc_buf + UNIT_DESC_PARAM_LOGICAL_BLK_COUNT);
+       hpb_lu_info->pinned_start = get_unaligned_be16(
+                       desc_buf + UNIT_DESC_PARAM_HPB_PIN_RGN_START_OFF);
+       hpb_lu_info->num_pinned = get_unaligned_be16(
+                       desc_buf + UNIT_DESC_PARAM_HPB_NUM_PIN_RGNS);
+       hpb_lu_info->max_active_rgns = max_active_rgns;
+       return 0;
+ }
+ void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev)
+ {
+       struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev);
+       if (!hpb)
+               return;
+       ufshpb_set_state(hpb, HPB_FAILED);
+       sdev = hpb->sdev_ufs_lu;
+       sdev->hostdata = NULL;
+       ufshpb_cancel_jobs(hpb);
+       ufshpb_pre_req_mempool_destroy(hpb);
+       ufshpb_destroy_region_tbl(hpb);
+       kmem_cache_destroy(hpb->map_req_cache);
+       kmem_cache_destroy(hpb->m_page_cache);
+       list_del_init(&hpb->list_hpb_lu);
+       kfree(hpb);
+ }
+ static void ufshpb_hpb_lu_prepared(struct ufs_hba *hba)
+ {
+       int pool_size;
+       struct ufshpb_lu *hpb;
+       struct scsi_device *sdev;
+       bool init_success;
+       if (tot_active_srgn_pages == 0) {
+               ufshpb_remove(hba);
+               return;
+       }
+       init_success = !ufshpb_check_hpb_reset_query(hba);
+       pool_size = PAGE_ALIGN(ufshpb_host_map_kbytes * 1024) / PAGE_SIZE;
+       if (pool_size > tot_active_srgn_pages) {
+               mempool_resize(ufshpb_mctx_pool, tot_active_srgn_pages);
+               mempool_resize(ufshpb_page_pool, tot_active_srgn_pages);
+       }
+       shost_for_each_device(sdev, hba->host) {
+               hpb = ufshpb_get_hpb_data(sdev);
+               if (!hpb)
+                       continue;
+               if (init_success) {
+                       ufshpb_set_state(hpb, HPB_PRESENT);
+                       if ((hpb->lu_pinned_end - hpb->lu_pinned_start) > 0)
+                               queue_work(ufshpb_wq, &hpb->map_work);
+               } else {
+                       dev_err(hba->dev, "destroy HPB lu %d\n", hpb->lun);
+                       ufshpb_destroy_lu(hba, sdev);
+               }
+       }
+       if (!init_success)
+               ufshpb_remove(hba);
+ }
+ void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev)
+ {
+       struct ufshpb_lu *hpb;
+       int ret;
+       struct ufshpb_lu_info hpb_lu_info = { 0 };
+       int lun = sdev->lun;
+       if (lun >= hba->dev_info.max_lu_supported)
+               goto out;
+       ret = ufshpb_get_lu_info(hba, lun, &hpb_lu_info);
+       if (ret)
+               goto out;
+       hpb = ufshpb_alloc_hpb_lu(hba, sdev, &hba->ufshpb_dev,
+                                 &hpb_lu_info);
+       if (!hpb)
+               goto out;
+       tot_active_srgn_pages += hpb_lu_info.max_active_rgns *
+                       hpb->srgns_per_rgn * hpb->pages_per_srgn;
+ out:
+       /* All LUs are initialized */
+       if (atomic_dec_and_test(&hba->ufshpb_dev.slave_conf_cnt))
+               ufshpb_hpb_lu_prepared(hba);
+ }
+ static int ufshpb_init_mem_wq(struct ufs_hba *hba)
+ {
+       int ret;
+       unsigned int pool_size;
+       ufshpb_mctx_cache = kmem_cache_create("ufshpb_mctx_cache",
+                                       sizeof(struct ufshpb_map_ctx),
+                                       0, 0, NULL);
+       if (!ufshpb_mctx_cache) {
+               dev_err(hba->dev, "ufshpb: cannot init mctx cache\n");
+               return -ENOMEM;
+       }
+       pool_size = PAGE_ALIGN(ufshpb_host_map_kbytes * 1024) / PAGE_SIZE;
+       dev_info(hba->dev, "%s:%d ufshpb_host_map_kbytes %u pool_size %u\n",
+              __func__, __LINE__, ufshpb_host_map_kbytes, pool_size);
+       ufshpb_mctx_pool = mempool_create_slab_pool(pool_size,
+                                                   ufshpb_mctx_cache);
+       if (!ufshpb_mctx_pool) {
+               dev_err(hba->dev, "ufshpb: cannot init mctx pool\n");
+               ret = -ENOMEM;
+               goto release_mctx_cache;
+       }
+       ufshpb_page_pool = mempool_create_page_pool(pool_size, 0);
+       if (!ufshpb_page_pool) {
+               dev_err(hba->dev, "ufshpb: cannot init page pool\n");
+               ret = -ENOMEM;
+               goto release_mctx_pool;
+       }
+       ufshpb_wq = alloc_workqueue("ufshpb-wq",
+                                       WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
+       if (!ufshpb_wq) {
+               dev_err(hba->dev, "ufshpb: alloc workqueue failed\n");
+               ret = -ENOMEM;
+               goto release_page_pool;
+       }
+       return 0;
+ release_page_pool:
+       mempool_destroy(ufshpb_page_pool);
+ release_mctx_pool:
+       mempool_destroy(ufshpb_mctx_pool);
+ release_mctx_cache:
+       kmem_cache_destroy(ufshpb_mctx_cache);
+       return ret;
+ }
+ void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf)
+ {
+       struct ufshpb_dev_info *hpb_info = &hba->ufshpb_dev;
+       int max_active_rgns = 0;
+       int hpb_num_lu;
+       hpb_num_lu = geo_buf[GEOMETRY_DESC_PARAM_HPB_NUMBER_LU];
+       if (hpb_num_lu == 0) {
+               dev_err(hba->dev, "No HPB LU supported\n");
+               hpb_info->hpb_disabled = true;
+               return;
+       }
+       hpb_info->rgn_size = geo_buf[GEOMETRY_DESC_PARAM_HPB_REGION_SIZE];
+       hpb_info->srgn_size = geo_buf[GEOMETRY_DESC_PARAM_HPB_SUBREGION_SIZE];
+       max_active_rgns = get_unaligned_be16(geo_buf +
+                         GEOMETRY_DESC_PARAM_HPB_MAX_ACTIVE_REGS);
+       if (hpb_info->rgn_size == 0 || hpb_info->srgn_size == 0 ||
+           max_active_rgns == 0) {
+               dev_err(hba->dev, "No HPB supported device\n");
+               hpb_info->hpb_disabled = true;
+               return;
+       }
+ }
+ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf)
+ {
+       struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev;
+       int version, ret;
+       int max_single_cmd;
+       hpb_dev_info->control_mode = desc_buf[DEVICE_DESC_PARAM_HPB_CONTROL];
+       version = get_unaligned_be16(desc_buf + DEVICE_DESC_PARAM_HPB_VER);
+       if ((version != HPB_SUPPORT_VERSION) &&
+           (version != HPB_SUPPORT_LEGACY_VERSION)) {
+               dev_err(hba->dev, "%s: HPB %x version is not supported.\n",
+                       __func__, version);
+               hpb_dev_info->hpb_disabled = true;
+               return;
+       }
+       if (version == HPB_SUPPORT_LEGACY_VERSION)
+               hpb_dev_info->is_legacy = true;
+       /*
+        * Get the number of user logical unit to check whether all
+        * scsi_device finish initialization
+        */
+       hpb_dev_info->num_lu = desc_buf[DEVICE_DESC_PARAM_NUM_LU];
+       if (hpb_dev_info->is_legacy)
+               return;
+       ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
+               QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_single_cmd);
+       if (ret)
+               hpb_dev_info->max_hpb_single_cmd = HPB_LEGACY_CHUNK_HIGH;
+       else
+               hpb_dev_info->max_hpb_single_cmd = min(max_single_cmd + 1, HPB_MULTI_CHUNK_HIGH);
+ }
+ void ufshpb_init(struct ufs_hba *hba)
+ {
+       struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev;
+       int try;
+       int ret;
+       if (!ufshpb_is_allowed(hba) || !hba->dev_info.hpb_enabled)
+               return;
+       if (ufshpb_init_mem_wq(hba)) {
+               hpb_dev_info->hpb_disabled = true;
+               return;
+       }
+       atomic_set(&hpb_dev_info->slave_conf_cnt, hpb_dev_info->num_lu);
+       tot_active_srgn_pages = 0;
+       /* issue HPB reset query */
+       for (try = 0; try < HPB_RESET_REQ_RETRIES; try++) {
+               ret = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_SET_FLAG,
+                                       QUERY_FLAG_IDN_HPB_RESET, 0, NULL);
+               if (!ret)
+                       break;
+       }
+ }
+ void ufshpb_remove(struct ufs_hba *hba)
+ {
+       mempool_destroy(ufshpb_page_pool);
+       mempool_destroy(ufshpb_mctx_pool);
+       kmem_cache_destroy(ufshpb_mctx_cache);
+       destroy_workqueue(ufshpb_wq);
+ }
+ module_param(ufshpb_host_map_kbytes, uint, 0644);
+ MODULE_PARM_DESC(ufshpb_host_map_kbytes,
+       "ufshpb host mapping memory kilo-bytes for ufshpb memory-pool");