From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id DB61D15800D for ; Sat, 31 Dec 2022 15:29:34 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 00AC4E0845; Sat, 31 Dec 2022 15:29:34 +0000 (UTC) Received: from smtp.gentoo.org (dev.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 7B070E0845 for ; Sat, 31 Dec 2022 15:29:33 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 7A3BB340DDF for ; Sat, 31 Dec 2022 15:29:31 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id EC2366F2 for ; Sat, 31 Dec 2022 15:29:29 +0000 (UTC) From: "Mike Pagano" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Pagano" Message-ID: <1672500556.47bebee42dd8af1585608157960c0bcf25816035.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:6.0 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1015_linux-6.0.16.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: 47bebee42dd8af1585608157960c0bcf25816035 X-VCS-Branch: 6.0 Date: Sat, 31 Dec 2022 15:29:29 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: f64b5147-4c1b-4ca2-b44b-cb01f616a288 X-Archives-Hash: 6a1c3391edef3573b0531179d39468b5 commit: 47bebee42dd8af1585608157960c0bcf25816035 Author: Mike Pagano gentoo org> AuthorDate: Sat Dec 31 15:29:16 2022 +0000 Commit: Mike Pagano gentoo org> CommitDate: Sat Dec 31 15:29:16 2022 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=47bebee4 Linux patch 6.0.16 Signed-off-by: Mike Pagano gentoo.org> 0000_README | 4 + 1015_linux-6.0.16.patch | 45617 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45621 insertions(+) diff --git a/0000_README b/0000_README index 302d8339..44fc4c7e 100644 --- a/0000_README +++ b/0000_README @@ -103,6 +103,10 @@ Patch: 1014_linux-6.0.15.patch From: http://www.kernel.org Desc: Linux 6.0.15 +Patch: 1015_linux-6.0.16.patch +From: http://www.kernel.org +Desc: Linux 6.0.16 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1015_linux-6.0.16.patch b/1015_linux-6.0.16.patch new file mode 100644 index 00000000..e72ee462 --- /dev/null +++ b/1015_linux-6.0.16.patch @@ -0,0 +1,45617 @@ +diff --git a/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor b/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor +index d76cd3946434d..e9ef69aef20b1 100644 +--- a/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor ++++ b/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor +@@ -5,6 +5,9 @@ Contact: linux-mtd@lists.infradead.org + Description: (RO) The JEDEC ID of the SPI NOR flash as reported by the + flash device. + ++ The attribute is not present if the flash doesn't support ++ the "Read JEDEC ID" command (9Fh). This is the case for ++ non-JEDEC compliant flashes. + + What: /sys/bus/spi/devices/.../spi-nor/manufacturer + Date: April 2021 +diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst +index ee6572b1edada..66d1b23ca64fe 100644 +--- a/Documentation/admin-guide/sysctl/kernel.rst ++++ b/Documentation/admin-guide/sysctl/kernel.rst +@@ -1298,6 +1298,29 @@ watchdog work to be queued by the watchdog timer function, otherwise the NMI + watchdog — if enabled — can detect a hard lockup condition. + + ++split_lock_mitigate (x86 only) ++============================== ++ ++On x86, each "split lock" imposes a system-wide performance penalty. On larger ++systems, large numbers of split locks from unprivileged users can result in ++denials of service to well-behaved and potentially more important users. ++ ++The kernel mitigates these bad users by detecting split locks and imposing ++penalties: forcing them to wait and only allowing one core to execute split ++locks at a time. ++ ++These mitigations can make those bad applications unbearably slow. Setting ++split_lock_mitigate=0 may restore some application performance, but will also ++increase system exposure to denial of service attacks from split lock users. ++ ++= =================================================================== ++0 Disable the mitigation mode - just warns the split lock on kernel log ++ and exposes the system to denials of service from the split lockers. ++1 Enable the mitigation mode (this is the default) - penalizes the split ++ lockers with intentional performance degradation. ++= =================================================================== ++ ++ + stack_erasing + ============= + +diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml +index bad9135489de5..1d20cdcc69ff8 100644 +--- a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml ++++ b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml +@@ -22,6 +22,8 @@ properties: + + clock-names: true + ++ reg: true ++ + compatible: + enum: + - qcom,sc7280-lpassaoncc +@@ -38,8 +40,8 @@ properties: + '#power-domain-cells': + const: 1 + +- reg: +- maxItems: 1 ++ '#reset-cells': ++ const: 1 + + required: + - compatible +@@ -69,6 +71,11 @@ allOf: + items: + - const: bi_tcxo + - const: lpass_aon_cc_main_rcg_clk_src ++ ++ reg: ++ items: ++ - description: lpass core cc register ++ - description: lpass audio csr register + - if: + properties: + compatible: +@@ -90,6 +97,8 @@ allOf: + - const: bi_tcxo_ao + - const: iface + ++ reg: ++ maxItems: 1 + - if: + properties: + compatible: +@@ -108,6 +117,8 @@ allOf: + items: + - const: bi_tcxo + ++ reg: ++ maxItems: 1 + examples: + - | + #include +@@ -116,13 +127,15 @@ examples: + #include + lpass_audiocc: clock-controller@3300000 { + compatible = "qcom,sc7280-lpassaudiocc"; +- reg = <0x3300000 0x30000>; ++ reg = <0x3300000 0x30000>, ++ <0x32a9000 0x1000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&lpass_aon LPASS_AON_CC_MAIN_RCG_CLK_SRC>; + clock-names = "bi_tcxo", "lpass_aon_cc_main_rcg_clk_src"; + power-domains = <&lpass_aon LPASS_AON_CC_LPASS_AUDIO_HM_GDSC>; + #clock-cells = <1>; + #power-domain-cells = <1>; ++ #reset-cells = <1>; + }; + + - | +diff --git a/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml b/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml +index 02e605fac408d..9ddba7f2e7aa6 100644 +--- a/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml ++++ b/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml +@@ -473,9 +473,6 @@ patternProperties: + Specifies whether the event is to be interpreted as a key (1) + or a switch (5). + +- required: +- - linux,code +- + additionalProperties: false + + dependencies: +@@ -501,7 +498,7 @@ patternProperties: + + azoteq,slider-size: + $ref: /schemas/types.yaml#/definitions/uint32 +- minimum: 0 ++ minimum: 1 + maximum: 65535 + description: + Specifies the slider's one-dimensional resolution, equal to the +@@ -575,9 +572,9 @@ patternProperties: + linux,code: true + + azoteq,gesture-max-ms: +- multipleOf: 4 ++ multipleOf: 16 + minimum: 0 +- maximum: 1020 ++ maximum: 4080 + description: + Specifies the length of time (in ms) within which a tap, swipe + or flick gesture must be completed in order to be acknowledged +@@ -585,9 +582,9 @@ patternProperties: + gesture applies to all remaining swipe or flick gestures. + + azoteq,gesture-min-ms: +- multipleOf: 4 ++ multipleOf: 16 + minimum: 0 +- maximum: 124 ++ maximum: 496 + description: + Specifies the length of time (in ms) for which a tap gesture must + be held in order to be acknowledged by the device. +@@ -620,9 +617,6 @@ patternProperties: + GPIO, they must all be of the same type (proximity, touch or + slider gesture). + +- required: +- - linux,code +- + additionalProperties: false + + required: +@@ -693,6 +687,7 @@ allOf: + properties: + azoteq,slider-size: + multipleOf: 16 ++ minimum: 16 + maximum: 4080 + + azoteq,top-speed: +@@ -935,14 +930,14 @@ examples: + + event-tap { + linux,code = ; +- azoteq,gesture-max-ms = <600>; +- azoteq,gesture-min-ms = <24>; ++ azoteq,gesture-max-ms = <400>; ++ azoteq,gesture-min-ms = <32>; + }; + + event-flick-pos { + linux,code = ; +- azoteq,gesture-max-ms = <600>; +- azoteq,gesture-dist = <816>; ++ azoteq,gesture-max-ms = <800>; ++ azoteq,gesture-dist = <800>; + }; + + event-flick-neg { +diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +index 65cbc6dee545e..2a5bafe0660a0 100644 +--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml ++++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +@@ -92,6 +92,10 @@ properties: + type: object + $ref: /schemas/regulator/regulator.yaml# + ++ pwm: ++ type: object ++ $ref: /schemas/leds/leds-qcom-lpg.yaml# ++ + patternProperties: + "^adc@[0-9a-f]+$": + type: object +@@ -117,10 +121,6 @@ patternProperties: + type: object + $ref: /schemas/power/reset/qcom,pon.yaml# + +- "pwm@[0-9a-f]+$": +- type: object +- $ref: /schemas/leds/leds-qcom-lpg.yaml# +- + "^rtc@[0-9a-f]+$": + type: object + $ref: /schemas/rtc/qcom-pm8xxx-rtc.yaml# +diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml +index 376e739bcad40..49b4f7a32e71e 100644 +--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml +@@ -14,9 +14,6 @@ description: |+ + This PCIe host controller is based on the Synopsys DesignWare PCIe IP + and thus inherits all the common properties defined in snps,dw-pcie.yaml. + +-allOf: +- - $ref: /schemas/pci/snps,dw-pcie.yaml# +- + properties: + compatible: + enum: +@@ -61,7 +58,7 @@ properties: + - const: pcie + - const: pcie_bus + - const: pcie_phy +- - const: pcie_inbound_axi for imx6sx-pcie, pcie_aux for imx8mq-pcie ++ - enum: [ pcie_inbound_axi, pcie_aux ] + + num-lanes: + const: 1 +@@ -175,6 +172,47 @@ required: + - clocks + - clock-names + ++allOf: ++ - $ref: /schemas/pci/snps,dw-pcie.yaml# ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: fsl,imx6sx-pcie ++ then: ++ properties: ++ clock-names: ++ items: ++ - {} ++ - {} ++ - {} ++ - const: pcie_inbound_axi ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: fsl,imx8mq-pcie ++ then: ++ properties: ++ clock-names: ++ items: ++ - {} ++ - {} ++ - {} ++ - const: pcie_aux ++ - if: ++ properties: ++ compatible: ++ not: ++ contains: ++ enum: ++ - fsl,imx6sx-pcie ++ - fsl,imx8mq-pcie ++ then: ++ properties: ++ clock-names: ++ maxItems: 3 ++ + unevaluatedProperties: false + + examples: +diff --git a/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml b/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml +index 30b6396d83c83..aea0e2bcdd778 100644 +--- a/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml +@@ -36,7 +36,7 @@ properties: + - const: mpu + + interrupts: +- maxItems: 1 ++ maxItems: 2 + + clocks: + items: +@@ -94,8 +94,9 @@ examples: + #interrupt-cells = <1>; + ranges = <0x81000000 0 0x40000000 0 0x40000000 0 0x00010000>, + <0x82000000 0 0x50000000 0 0x50000000 0 0x20000000>; +- interrupts = ; +- interrupt-names = "intr"; ++ interrupts = , ++ ; ++ interrupt-names = "msi", "intr"; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = + <0 0 0 1 &gic GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH +diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml +index 4eadea55df10f..41abfa94877fb 100644 +--- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml ++++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml +@@ -87,6 +87,8 @@ patternProperties: + "wifi_led" "led" 1, 2 + "i2c" "i2c" 3, 4 + "uart1_0" "uart" 7, 8, 9, 10 ++ "uart1_rx_tx" "uart" 42, 43 ++ "uart1_cts_rts" "uart" 44, 45 + "pcie_clk" "pcie" 9 + "pcie_wake" "pcie" 10 + "spi1_0" "spi" 11, 12, 13, 14 +@@ -98,9 +100,11 @@ patternProperties: + "emmc_45" "emmc" 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32 + "spi1_1" "spi" 23, 24, 25, 26 +- "uart1_2" "uart" 29, 30, 31, 32 ++ "uart1_2_rx_tx" "uart" 29, 30 ++ "uart1_2_cts_rts" "uart" 31, 32 + "uart1_1" "uart" 23, 24, 25, 26 +- "uart2_0" "uart" 29, 30, 31, 32 ++ "uart2_0_rx_tx" "uart" 29, 30 ++ "uart2_0_cts_rts" "uart" 31, 32 + "spi0" "spi" 33, 34, 35, 36 + "spi0_wp_hold" "spi" 37, 38 + "uart1_3_rx_tx" "uart" 35, 36 +@@ -153,7 +157,7 @@ patternProperties: + then: + properties: + groups: +- enum: [emmc, emmc_rst] ++ enum: [emmc_45, emmc_51] + - if: + properties: + function: +@@ -217,8 +221,12 @@ patternProperties: + then: + properties: + groups: +- enum: [uart1_0, uart1_1, uart1_2, uart1_3_rx_tx, +- uart1_3_cts_rts, uart2_0, uart2_1, uart0, uart1, uart2] ++ items: ++ enum: [uart1_0, uart1_rx_tx, uart1_cts_rts, uart1_1, ++ uart1_2_rx_tx, uart1_2_cts_rts, uart1_3_rx_tx, ++ uart1_3_cts_rts, uart2_0_rx_tx, uart2_0_cts_rts, ++ uart2_1, uart0, uart1, uart2] ++ maxItems: 2 + - if: + properties: + function: +@@ -348,6 +356,27 @@ examples: + interrupt-parent = <&gic>; + #interrupt-cells = <2>; + ++ pcie_pins: pcie-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie_clk", "pcie_wake", "pcie_pereset"; ++ }; ++ }; ++ ++ pwm_pins: pwm-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm0", "pwm1_0"; ++ }; ++ }; ++ ++ spi0_pins: spi0-pins { ++ mux { ++ function = "spi"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ }; ++ + uart1_pins: uart1-pins { + mux { + function = "uart"; +@@ -355,6 +384,13 @@ examples: + }; + }; + ++ uart1_3_pins: uart1-3-pins { ++ mux { ++ function = "uart"; ++ groups = "uart1_3_rx_tx", "uart1_3_cts_rts"; ++ }; ++ }; ++ + uart2_pins: uart2-pins { + mux { + function = "uart"; +diff --git a/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml b/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml +index a7fae1772a81b..cd8e9a8907f84 100644 +--- a/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml ++++ b/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml +@@ -30,7 +30,9 @@ properties: + maxItems: 1 + + "#pwm-cells": +- const: 2 ++ enum: [2, 3] ++ description: ++ The only flag supported by the controller is PWM_POLARITY_INVERTED. + + microchip,sync-update-mask: + description: | +diff --git a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt +index 5d6ea66a863fe..1f75feec3dec6 100644 +--- a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt ++++ b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt +@@ -109,7 +109,7 @@ audio-codec@1{ + reg = <1 0>; + interrupts = <&msmgpio 54 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "intr2" +- reset-gpios = <&msmgpio 64 0>; ++ reset-gpios = <&msmgpio 64 GPIO_ACTIVE_LOW>; + slim-ifc-dev = <&wc9335_ifd>; + clock-names = "mclk", "native"; + clocks = <&rpmcc RPM_SMD_DIV_CLK1>, +diff --git a/Documentation/devicetree/bindings/sound/rt5682.txt b/Documentation/devicetree/bindings/sound/rt5682.txt +index c5f2b8febceec..6b87db68337c2 100644 +--- a/Documentation/devicetree/bindings/sound/rt5682.txt ++++ b/Documentation/devicetree/bindings/sound/rt5682.txt +@@ -46,7 +46,7 @@ Optional properties: + + - realtek,dmic-clk-driving-high : Set the high driving of the DMIC clock out. + +-- #sound-dai-cells: Should be set to '<0>'. ++- #sound-dai-cells: Should be set to '<1>'. + + Pins on the device (for linking into audio routes) for RT5682: + +diff --git a/Documentation/driver-api/spi.rst b/Documentation/driver-api/spi.rst +index f64cb666498aa..f28887045049d 100644 +--- a/Documentation/driver-api/spi.rst ++++ b/Documentation/driver-api/spi.rst +@@ -25,8 +25,8 @@ hardware, which may be as simple as a set of GPIO pins or as complex as + a pair of FIFOs connected to dual DMA engines on the other side of the + SPI shift register (maximizing throughput). Such drivers bridge between + whatever bus they sit on (often the platform bus) and SPI, and expose +-the SPI side of their device as a :c:type:`struct spi_master +-`. SPI devices are children of that master, ++the SPI side of their device as a :c:type:`struct spi_controller ++`. SPI devices are children of that master, + represented as a :c:type:`struct spi_device ` and + manufactured from :c:type:`struct spi_board_info + ` descriptors which are usually provided by +diff --git a/Documentation/fault-injection/fault-injection.rst b/Documentation/fault-injection/fault-injection.rst +index 17779a2772e51..5f6454b9dbd4d 100644 +--- a/Documentation/fault-injection/fault-injection.rst ++++ b/Documentation/fault-injection/fault-injection.rst +@@ -83,9 +83,7 @@ configuration of fault-injection capabilities. + - /sys/kernel/debug/fail*/times: + + specifies how many times failures may happen at most. A value of -1 +- means "no limit". Note, though, that this file only accepts unsigned +- values. So, if you want to specify -1, you better use 'printf' instead +- of 'echo', e.g.: $ printf %#x -1 > times ++ means "no limit". + + - /sys/kernel/debug/fail*/space: + +@@ -284,7 +282,7 @@ Application Examples + echo Y > /sys/kernel/debug/$FAILTYPE/task-filter + echo 10 > /sys/kernel/debug/$FAILTYPE/probability + echo 100 > /sys/kernel/debug/$FAILTYPE/interval +- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times ++ echo -1 > /sys/kernel/debug/$FAILTYPE/times + echo 0 > /sys/kernel/debug/$FAILTYPE/space + echo 2 > /sys/kernel/debug/$FAILTYPE/verbose + echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait +@@ -338,7 +336,7 @@ Application Examples + echo N > /sys/kernel/debug/$FAILTYPE/task-filter + echo 10 > /sys/kernel/debug/$FAILTYPE/probability + echo 100 > /sys/kernel/debug/$FAILTYPE/interval +- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times ++ echo -1 > /sys/kernel/debug/$FAILTYPE/times + echo 0 > /sys/kernel/debug/$FAILTYPE/space + echo 2 > /sys/kernel/debug/$FAILTYPE/verbose + echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait +@@ -369,7 +367,7 @@ Application Examples + echo N > /sys/kernel/debug/$FAILTYPE/task-filter + echo 100 > /sys/kernel/debug/$FAILTYPE/probability + echo 0 > /sys/kernel/debug/$FAILTYPE/interval +- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times ++ echo -1 > /sys/kernel/debug/$FAILTYPE/times + echo 0 > /sys/kernel/debug/$FAILTYPE/space + echo 1 > /sys/kernel/debug/$FAILTYPE/verbose + +diff --git a/Makefile b/Makefile +index 0c7ae314ad3d5..ff8d88b113919 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 0 +-SUBLEVEL = 15 ++SUBLEVEL = 16 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +diff --git a/arch/Kconfig b/arch/Kconfig +index 8b311e400ec14..732a4680e733e 100644 +--- a/arch/Kconfig ++++ b/arch/Kconfig +@@ -629,7 +629,7 @@ config ARCH_SUPPORTS_SHADOW_CALL_STACK + config SHADOW_CALL_STACK + bool "Shadow Call Stack" + depends on ARCH_SUPPORTS_SHADOW_CALL_STACK +- depends on DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER ++ depends on DYNAMIC_FTRACE_WITH_ARGS || DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER + help + This option enables the compiler's Shadow Call Stack, which + uses a shadow stack to protect function return addresses from +diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h +index fdc485d7787a6..084c27cb0c707 100644 +--- a/arch/alpha/include/asm/thread_info.h ++++ b/arch/alpha/include/asm/thread_info.h +@@ -75,7 +75,7 @@ register struct thread_info *__current_thread_info __asm__("$8"); + + /* Work to do on interrupt/exception return. */ + #define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ +- _TIF_NOTIFY_RESUME) ++ _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL) + + /* Work to do on any return to userspace. */ + #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \ +diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S +index e227f3a29a43c..c41a5a9c3b9f2 100644 +--- a/arch/alpha/kernel/entry.S ++++ b/arch/alpha/kernel/entry.S +@@ -469,8 +469,10 @@ entSys: + #ifdef CONFIG_AUDITSYSCALL + lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + and $3, $6, $3 +-#endif + bne $3, strace ++#else ++ blbs $3, strace /* check for SYSCALL_TRACE in disguise */ ++#endif + beq $4, 1f + ldq $27, 0($5) + 1: jsr $26, ($27), sys_ni_syscall +diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi +index 46e6d3ed8f35a..c042c416a94a3 100644 +--- a/arch/arm/boot/dts/armada-370.dtsi ++++ b/arch/arm/boot/dts/armada-370.dtsi +@@ -74,7 +74,7 @@ + + pcie2: pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x80000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi +index 7f2f24a29e6c1..352a2f7ba3114 100644 +--- a/arch/arm/boot/dts/armada-375.dtsi ++++ b/arch/arm/boot/dts/armada-375.dtsi +@@ -582,7 +582,7 @@ + + pcie1: pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi +index cff1269f3fbfd..7146cc8f082af 100644 +--- a/arch/arm/boot/dts/armada-380.dtsi ++++ b/arch/arm/boot/dts/armada-380.dtsi +@@ -79,7 +79,7 @@ + /* x1 port */ + pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x40000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -98,7 +98,7 @@ + /* x1 port */ + pcie@3,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001800 0 0x44000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts +index a41902e3815cd..0b64d7505dca0 100644 +--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts ++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts +@@ -23,6 +23,12 @@ + stdout-path = &uart0; + }; + ++ aliases { ++ ethernet0 = ð0; ++ ethernet1 = ð1; ++ ethernet2 = ð2; ++ }; ++ + memory { + device_type = "memory"; + reg = <0x00000000 0x40000000>; /* 1024 MB */ +@@ -455,7 +461,17 @@ + }; + }; + +- /* port 6 is connected to eth0 */ ++ ports@6 { ++ reg = <6>; ++ label = "cpu"; ++ ethernet = <ð0>; ++ phy-mode = "rgmii-id"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; + }; + }; + }; +diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi +index 83392b92dae28..be8d607c59b21 100644 +--- a/arch/arm/boot/dts/armada-385.dtsi ++++ b/arch/arm/boot/dts/armada-385.dtsi +@@ -93,7 +93,7 @@ + /* x1 port */ + pcie2: pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x40000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -121,7 +121,7 @@ + /* x1 port */ + pcie3: pcie@3,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001800 0 0x44000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -152,7 +152,7 @@ + */ + pcie4: pcie@4,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; ++ assigned-addresses = <0x82002000 0 0x48000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi +index e0b7c20998312..9525e7b7f4360 100644 +--- a/arch/arm/boot/dts/armada-39x.dtsi ++++ b/arch/arm/boot/dts/armada-39x.dtsi +@@ -453,7 +453,7 @@ + /* x1 port */ + pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x40000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -472,7 +472,7 @@ + /* x1 port */ + pcie@3,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001800 0 0x44000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -494,7 +494,7 @@ + */ + pcie@4,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; ++ assigned-addresses = <0x82002000 0 0x48000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +index 8558bf6bb54c6..d55fe162fc7f0 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +@@ -97,7 +97,7 @@ + + pcie2: pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -115,7 +115,7 @@ + + pcie3: pcie@3,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; ++ assigned-addresses = <0x82001800 0 0x48000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -133,7 +133,7 @@ + + pcie4: pcie@4,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>; ++ assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -151,7 +151,7 @@ + + pcie5: pcie@5,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; ++ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; + reg = <0x2800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +index 2d85fe8ac3272..fdcc818199401 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +@@ -112,7 +112,7 @@ + + pcie2: pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -130,7 +130,7 @@ + + pcie3: pcie@3,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; ++ assigned-addresses = <0x82001800 0 0x48000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -148,7 +148,7 @@ + + pcie4: pcie@4,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>; ++ assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -166,7 +166,7 @@ + + pcie5: pcie@5,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; ++ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; + reg = <0x2800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -184,7 +184,7 @@ + + pcie6: pcie@6,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x84000 0 0x2000>; ++ assigned-addresses = <0x82003000 0 0x84000 0 0x2000>; + reg = <0x3000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -202,7 +202,7 @@ + + pcie7: pcie@7,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x88000 0 0x2000>; ++ assigned-addresses = <0x82003800 0 0x88000 0 0x2000>; + reg = <0x3800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -220,7 +220,7 @@ + + pcie8: pcie@8,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>; ++ assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>; + reg = <0x4000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -238,7 +238,7 @@ + + pcie9: pcie@9,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x42000 0 0x2000>; ++ assigned-addresses = <0x82004800 0 0x42000 0 0x2000>; + reg = <0x4800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts +index a6a2bc3b855c2..fcc890e3ad735 100644 +--- a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts ++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts +@@ -162,16 +162,9 @@ + #size-cells = <1>; + ranges; + +- /* LPC FW cycle bridge region requires natural alignment */ +- flash_memory: region@b8000000 { +- no-map; +- reg = <0xb8000000 0x04000000>; /* 64M */ +- }; +- +- /* 48MB region from the end of flash to start of vga memory */ +- ramoops@bc000000 { ++ ramoops@b3e00000 { + compatible = "ramoops"; +- reg = <0xbc000000 0x200000>; /* 16 * (4 * 0x8000) */ ++ reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */ + record-size = <0x8000>; + console-size = <0x8000>; + ftrace-size = <0x8000>; +@@ -179,6 +172,12 @@ + max-reason = <3>; /* KMSG_DUMP_EMERG */ + }; + ++ /* LPC FW cycle bridge region requires natural alignment */ ++ flash_memory: region@b4000000 { ++ no-map; ++ reg = <0xb4000000 0x04000000>; /* 64M */ ++ }; ++ + /* VGA region is dictated by hardware strapping */ + vga_memory: region@bf000000 { + no-map; +diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +index bf59a9962379d..4879da4cdbd25 100644 +--- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts ++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +@@ -95,14 +95,9 @@ + #size-cells = <1>; + ranges; + +- flash_memory: region@b8000000 { +- no-map; +- reg = <0xb8000000 0x04000000>; /* 64M */ +- }; +- +- ramoops@bc000000 { ++ ramoops@b3e00000 { + compatible = "ramoops"; +- reg = <0xbc000000 0x200000>; /* 16 * (4 * 0x8000) */ ++ reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */ + record-size = <0x8000>; + console-size = <0x8000>; + ftrace-size = <0x8000>; +@@ -110,6 +105,13 @@ + max-reason = <3>; /* KMSG_DUMP_EMERG */ + }; + ++ /* LPC FW cycle bridge region requires natural alignment */ ++ flash_memory: region@b4000000 { ++ no-map; ++ reg = <0xb4000000 0x04000000>; /* 64M */ ++ }; ++ ++ /* VGA region is dictated by hardware strapping */ + vga_memory: region@bf000000 { + no-map; + compatible = "shared-dma-pool"; +diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi +index 89e0bdaf3a85f..726d353eda686 100644 +--- a/arch/arm/boot/dts/dove.dtsi ++++ b/arch/arm/boot/dts/dove.dtsi +@@ -129,7 +129,7 @@ + pcie1: pcie@2 { + device_type = "pci"; + status = "disabled"; +- assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x80000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + clocks = <&gate_clk 5>; + marvell,pcie-port = <1>; +diff --git a/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts b/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts +index d10669fcd527d..9e9eba8bad5e4 100644 +--- a/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts ++++ b/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts +@@ -366,7 +366,7 @@ + spi-max-frequency = <20000000>; + spi-rx-bus-width = <2>; + label = "bmc"; +- partitions@80000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts b/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts +index 491606c4f044d..2a394cc15284c 100644 +--- a/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts ++++ b/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts +@@ -142,7 +142,7 @@ + reg = <0>; + spi-rx-bus-width = <2>; + +- partitions@80000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts b/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts +index a0c2d76526258..f7b38bee039bc 100644 +--- a/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts ++++ b/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts +@@ -388,7 +388,7 @@ + spi-max-frequency = <5000000>; + spi-rx-bus-width = <2>; + label = "bmc"; +- partitions@80000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +@@ -422,7 +422,7 @@ + reg = <1>; + spi-max-frequency = <5000000>; + spi-rx-bus-width = <2>; +- partitions@88000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +@@ -447,7 +447,7 @@ + reg = <0>; + spi-max-frequency = <5000000>; + spi-rx-bus-width = <2>; +- partitions@A0000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts +index 3dad32834e5ea..f53d45fa1de87 100644 +--- a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts ++++ b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts +@@ -74,7 +74,7 @@ + spi-rx-bus-width = <2>; + reg = <0>; + spi-max-frequency = <5000000>; +- partitions@80000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +@@ -135,7 +135,7 @@ + spi-rx-bus-width = <2>; + reg = <0>; + spi-max-frequency = <5000000>; +- partitions@A0000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts +index 132e702281fc5..87359ab05db3e 100644 +--- a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts ++++ b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts +@@ -107,7 +107,7 @@ + reg = <0>; + spi-rx-bus-width = <2>; + +- partitions@80000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +@@ -146,7 +146,7 @@ + reg = <1>; + npcm,fiu-rx-bus-width = <2>; + +- partitions@88000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +@@ -173,7 +173,7 @@ + reg = <0>; + spi-rx-bus-width = <2>; + +- partitions@A0000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi +index ada4c828bf2f4..095849423de1d 100644 +--- a/arch/arm/boot/dts/qcom-apq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi +@@ -1580,7 +1580,7 @@ + }; + + etb@1a01000 { +- compatible = "coresight-etb10", "arm,primecell"; ++ compatible = "arm,coresight-etb10", "arm,primecell"; + reg = <0x1a01000 0x1000>; + + clocks = <&rpmcc RPM_QDSS_CLK>; +diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi +index fd41243a0b2c0..9d5a04a46b14e 100644 +--- a/arch/arm/boot/dts/spear600.dtsi ++++ b/arch/arm/boot/dts/spear600.dtsi +@@ -47,7 +47,7 @@ + compatible = "arm,pl110", "arm,primecell"; + reg = <0xfc200000 0x1000>; + interrupt-parent = <&vic1>; +- interrupts = <12>; ++ interrupts = <13>; + status = "disabled"; + }; + +diff --git a/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts b/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts +index 2e3c9fbb4eb36..275167f26fd9d 100644 +--- a/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts ++++ b/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts +@@ -13,7 +13,6 @@ + /dts-v1/; + + #include "stm32mp157.dtsi" +-#include "stm32mp15xc.dtsi" + #include "stm32mp15xx-dhcor-som.dtsi" + #include "stm32mp15xx-dhcor-avenger96.dtsi" + +diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +index 90933077d66de..b6957cbdeff5f 100644 +--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi ++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +@@ -100,7 +100,7 @@ + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + +- gpios = <&gpioz 3 GPIO_ACTIVE_HIGH>; ++ gpio = <&gpioz 3 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c +index 41b2e8abc9e69..708816caf859c 100644 +--- a/arch/arm/mach-mmp/time.c ++++ b/arch/arm/mach-mmp/time.c +@@ -43,18 +43,21 @@ + static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE; + + /* +- * FIXME: the timer needs some delay to stablize the counter capture ++ * Read the timer through the CVWR register. Delay is required after requesting ++ * a read. The CR register cannot be directly read due to metastability issues ++ * documented in the PXA168 software manual. + */ + static inline uint32_t timer_read(void) + { +- int delay = 100; ++ uint32_t val; ++ int delay = 3; + + __raw_writel(1, mmp_timer_base + TMR_CVWR(1)); + + while (delay--) +- cpu_relax(); ++ val = __raw_readl(mmp_timer_base + TMR_CVWR(1)); + +- return __raw_readl(mmp_timer_base + TMR_CVWR(1)); ++ return val; + } + + static u64 notrace mmp_read_sched_clock(void) +diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi +index 51a63b29d4045..a4d195e9eb8c8 100644 +--- a/arch/arm64/boot/dts/apple/t8103.dtsi ++++ b/arch/arm64/boot/dts/apple/t8103.dtsi +@@ -412,7 +412,7 @@ + resets = <&ps_ans2>; + }; + +- pcie0_dart_0: dart@681008000 { ++ pcie0_dart_0: iommu@681008000 { + compatible = "apple,t8103-dart"; + reg = <0x6 0x81008000 0x0 0x4000>; + #iommu-cells = <1>; +@@ -421,7 +421,7 @@ + power-domains = <&ps_apcie_gp>; + }; + +- pcie0_dart_1: dart@682008000 { ++ pcie0_dart_1: iommu@682008000 { + compatible = "apple,t8103-dart"; + reg = <0x6 0x82008000 0x0 0x4000>; + #iommu-cells = <1>; +@@ -430,7 +430,7 @@ + power-domains = <&ps_apcie_gp>; + }; + +- pcie0_dart_2: dart@683008000 { ++ pcie0_dart_2: iommu@683008000 { + compatible = "apple,t8103-dart"; + reg = <0x6 0x83008000 0x0 0x4000>; + #iommu-cells = <1>; +diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +index ada164d423f3d..200f97e1c4c9c 100644 +--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +@@ -125,9 +125,12 @@ + /delete-property/ mrvl,i2c-fast-mode; + status = "okay"; + ++ /* MCP7940MT-I/MNY RTC */ + rtc@6f { + compatible = "microchip,mcp7940x"; + reg = <0x6f>; ++ interrupt-parent = <&gpiosb>; ++ interrupts = <5 0>; /* GPIO2_5 */ + }; + }; + +diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts +index 9b1af9c801308..d31a194124c91 100644 +--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts ++++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts +@@ -26,14 +26,14 @@ + stdout-path = "serial0:921600n8"; + }; + +- cpus_fixed_vproc0: fixedregulator@0 { ++ cpus_fixed_vproc0: regulator-vproc-buck0 { + compatible = "regulator-fixed"; + regulator-name = "vproc_buck0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + +- cpus_fixed_vproc1: fixedregulator@1 { ++ cpus_fixed_vproc1: regulator-vproc-buck1 { + compatible = "regulator-fixed"; + regulator-name = "vproc_buck1"; + regulator-min-microvolt = <1000000>; +@@ -50,7 +50,7 @@ + id-gpio = <&pio 14 GPIO_ACTIVE_HIGH>; + }; + +- usb_p0_vbus: regulator@2 { ++ usb_p0_vbus: regulator-usb-p0-vbus { + compatible = "regulator-fixed"; + regulator-name = "p0_vbus"; + regulator-min-microvolt = <5000000>; +@@ -59,7 +59,7 @@ + enable-active-high; + }; + +- usb_p1_vbus: regulator@3 { ++ usb_p1_vbus: regulator-usb-p1-vbus { + compatible = "regulator-fixed"; + regulator-name = "p1_vbus"; + regulator-min-microvolt = <5000000>; +@@ -68,7 +68,7 @@ + enable-active-high; + }; + +- usb_p2_vbus: regulator@4 { ++ usb_p2_vbus: regulator-usb-p2-vbus { + compatible = "regulator-fixed"; + regulator-name = "p2_vbus"; + regulator-min-microvolt = <5000000>; +@@ -77,7 +77,7 @@ + enable-active-high; + }; + +- usb_p3_vbus: regulator@5 { ++ usb_p3_vbus: regulator-usb-p3-vbus { + compatible = "regulator-fixed"; + regulator-name = "p3_vbus"; + regulator-min-microvolt = <5000000>; +diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +index 4797537cb3683..2ebefd144d6f5 100644 +--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +@@ -160,70 +160,70 @@ + #clock-cells = <0>; + }; + +- clk26m: oscillator@0 { ++ clk26m: oscillator-26m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + clock-output-names = "clk26m"; + }; + +- clk32k: oscillator@1 { ++ clk32k: oscillator-32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "clk32k"; + }; + +- clkfpc: oscillator@2 { ++ clkfpc: oscillator-50m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + clock-output-names = "clkfpc"; + }; + +- clkaud_ext_i_0: oscillator@3 { ++ clkaud_ext_i_0: oscillator-aud0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <6500000>; + clock-output-names = "clkaud_ext_i_0"; + }; + +- clkaud_ext_i_1: oscillator@4 { ++ clkaud_ext_i_1: oscillator-aud1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <196608000>; + clock-output-names = "clkaud_ext_i_1"; + }; + +- clkaud_ext_i_2: oscillator@5 { ++ clkaud_ext_i_2: oscillator-aud2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <180633600>; + clock-output-names = "clkaud_ext_i_2"; + }; + +- clki2si0_mck_i: oscillator@6 { ++ clki2si0_mck_i: oscillator-i2s0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <30000000>; + clock-output-names = "clki2si0_mck_i"; + }; + +- clki2si1_mck_i: oscillator@7 { ++ clki2si1_mck_i: oscillator-i2s1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <30000000>; + clock-output-names = "clki2si1_mck_i"; + }; + +- clki2si2_mck_i: oscillator@8 { ++ clki2si2_mck_i: oscillator-i2s2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <30000000>; + clock-output-names = "clki2si2_mck_i"; + }; + +- clktdmin_mclk_i: oscillator@9 { ++ clktdmin_mclk_i: oscillator-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <30000000>; +@@ -266,7 +266,7 @@ + reg = <0 0x10005000 0 0x1000>; + }; + +- pio: pinctrl@10005000 { ++ pio: pinctrl@1000b000 { + compatible = "mediatek,mt2712-pinctrl"; + reg = <0 0x1000b000 0 0x1000>; + mediatek,pctl-regmap = <&syscfg_pctl_a>; +diff --git a/arch/arm64/boot/dts/mediatek/mt6779.dtsi b/arch/arm64/boot/dts/mediatek/mt6779.dtsi +index 9bdf5145966c5..dde9ce137b4f1 100644 +--- a/arch/arm64/boot/dts/mediatek/mt6779.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt6779.dtsi +@@ -88,14 +88,14 @@ + interrupts = ; + }; + +- clk26m: oscillator@0 { ++ clk26m: oscillator-26m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + clock-output-names = "clk26m"; + }; + +- clk32k: oscillator@1 { ++ clk32k: oscillator-32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; +@@ -117,7 +117,7 @@ + compatible = "simple-bus"; + ranges; + +- gic: interrupt-controller@0c000000 { ++ gic: interrupt-controller@c000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <4>; + interrupt-parent = <&gic>; +@@ -138,7 +138,7 @@ + + }; + +- sysirq: intpol-controller@0c53a650 { ++ sysirq: intpol-controller@c53a650 { + compatible = "mediatek,mt6779-sysirq", + "mediatek,mt6577-sysirq"; + interrupt-controller; +diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi +index 15616231022a2..c3677d77e0a45 100644 +--- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi +@@ -95,7 +95,7 @@ + }; + }; + +- clk26m: oscillator@0 { ++ clk26m: oscillator-26m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; +diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +index e3a407d03551f..25b297bbb1b02 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +@@ -13,7 +13,7 @@ + #address-cells = <2>; + #size-cells = <2>; + +- clk40m: oscillator@0 { ++ clk40m: oscillator-40m { + compatible = "fixed-clock"; + clock-frequency = <40000000>; + #clock-cells = <0>; +@@ -162,7 +162,7 @@ + #clock-cells = <1>; + }; + +- trng: trng@1020f000 { ++ trng: rng@1020f000 { + compatible = "mediatek,mt7986-rng", + "mediatek,mt7623-rng"; + reg = <0 0x1020f000 0 0x100>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +index 9d32871973a29..85fb61324be8d 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +@@ -1670,7 +1670,7 @@ + ; + interrupt-names = "job", "mmu", "gpu"; + +- clocks = <&topckgen CLK_TOP_MFGPLL_CK>; ++ clocks = <&mfgcfg CLK_MFG_BG3D>; + + power-domains = + <&spm MT8183_POWER_DOMAIN_MFG_CORE0>, +diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +index 066c14989708a..e694ddb74f7d5 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +@@ -27,7 +27,7 @@ + reg = <0x000>; + enable-method = "psci"; + clock-frequency = <1701000000>; +- capacity-dmips-mhz = <578>; ++ capacity-dmips-mhz = <308>; + cpu-idle-states = <&cpu_off_l &cluster_off_l>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; +@@ -39,7 +39,7 @@ + reg = <0x100>; + enable-method = "psci"; + clock-frequency = <1701000000>; +- capacity-dmips-mhz = <578>; ++ capacity-dmips-mhz = <308>; + cpu-idle-states = <&cpu_off_l &cluster_off_l>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; +@@ -51,7 +51,7 @@ + reg = <0x200>; + enable-method = "psci"; + clock-frequency = <1701000000>; +- capacity-dmips-mhz = <578>; ++ capacity-dmips-mhz = <308>; + cpu-idle-states = <&cpu_off_l &cluster_off_l>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; +@@ -63,7 +63,7 @@ + reg = <0x300>; + enable-method = "psci"; + clock-frequency = <1701000000>; +- capacity-dmips-mhz = <578>; ++ capacity-dmips-mhz = <308>; + cpu-idle-states = <&cpu_off_l &cluster_off_l>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; +diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +index 8ee1529683a34..ec8dfb3d1c6d6 100644 +--- a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi ++++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +@@ -17,7 +17,7 @@ + }; + + firmware { +- optee: optee@4fd00000 { ++ optee: optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; +@@ -209,7 +209,7 @@ + }; + }; + +- i2c0_pins_a: i2c0@0 { ++ i2c0_pins_a: i2c0 { + pins1 { + pinmux = , + ; +@@ -217,7 +217,7 @@ + }; + }; + +- i2c2_pins_a: i2c2@0 { ++ i2c2_pins_a: i2c2 { + pins1 { + pinmux = , + ; +diff --git a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts +index 567b331065560..92f264891d84b 100644 +--- a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts ++++ b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts +@@ -368,7 +368,7 @@ + + bus-width = <4>; + +- cd-gpios = <&tlmm 38 0x1>; ++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vreg_l21a_2p95>; + vqmmc-supply = <&vreg_l13a_2p95>; +diff --git a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts +index 1ba2eca33c7b6..6a716c83e5f1d 100644 +--- a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts ++++ b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts +@@ -37,6 +37,8 @@ + + &blsp1_spi1 { + cs-select = <0>; ++ pinctrl-0 = <&spi_0_pins>; ++ pinctrl-names = "default"; + status = "okay"; + + flash@0 { +diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi +index 48bc2e09128d9..863a60b636416 100644 +--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi +@@ -1331,7 +1331,7 @@ + }; + + mpss: remoteproc@4080000 { +- compatible = "qcom,msm8916-mss-pil", "qcom,q6v5-pil"; ++ compatible = "qcom,msm8916-mss-pil"; + reg = <0x04080000 0x100>, + <0x04020000 0x040>; + +diff --git a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi +index f430d797196f5..ff60b7004d260 100644 +--- a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi +@@ -471,7 +471,7 @@ + &sdhc2 { + status = "okay"; + +- cd-gpios = <&tlmm 100 0>; ++ cd-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>; + vmmc-supply = <&pm8994_l21>; + vqmmc-supply = <&pm8994_l13>; + }; +diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi +index 8bc6c070e3066..86ef0091cafff 100644 +--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + + / { +@@ -502,7 +503,7 @@ + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + +- cd-gpios = <&tlmm 100 0>; ++ cd-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>; + bus-width = <4>; + status = "disabled"; + }; +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index 742eac4ce9b35..5cf04c350a62c 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -143,82 +144,92 @@ + /* Nominal fmax for now */ + opp-307200000 { + opp-hz = /bits/ 64 <307200000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-422400000 { + opp-hz = /bits/ 64 <422400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-556800000 { + opp-hz = /bits/ 64 <556800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-652800000 { + opp-hz = /bits/ 64 <652800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-729600000 { + opp-hz = /bits/ 64 <729600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-844800000 { + opp-hz = /bits/ 64 <844800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-960000000 { + opp-hz = /bits/ 64 <960000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1036800000 { + opp-hz = /bits/ 64 <1036800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1113600000 { + opp-hz = /bits/ 64 <1113600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1190400000 { + opp-hz = /bits/ 64 <1190400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1228800000 { + opp-hz = /bits/ 64 <1228800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1324800000 { + opp-hz = /bits/ 64 <1324800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x5>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1363200000 { ++ opp-hz = /bits/ 64 <1363200000>; ++ opp-supported-hw = <0x2>; + clock-latency-ns = <200000>; + }; + opp-1401600000 { + opp-hz = /bits/ 64 <1401600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x5>; + clock-latency-ns = <200000>; + }; + opp-1478400000 { + opp-hz = /bits/ 64 <1478400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1497600000 { ++ opp-hz = /bits/ 64 <1497600000>; ++ opp-supported-hw = <0x04>; + clock-latency-ns = <200000>; + }; + opp-1593600000 { + opp-hz = /bits/ 64 <1593600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + }; +@@ -231,127 +242,137 @@ + /* Nominal fmax for now */ + opp-307200000 { + opp-hz = /bits/ 64 <307200000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-403200000 { + opp-hz = /bits/ 64 <403200000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-556800000 { + opp-hz = /bits/ 64 <556800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-652800000 { + opp-hz = /bits/ 64 <652800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-729600000 { + opp-hz = /bits/ 64 <729600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-806400000 { + opp-hz = /bits/ 64 <806400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-883200000 { + opp-hz = /bits/ 64 <883200000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-940800000 { + opp-hz = /bits/ 64 <940800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1036800000 { + opp-hz = /bits/ 64 <1036800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1113600000 { + opp-hz = /bits/ 64 <1113600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1190400000 { + opp-hz = /bits/ 64 <1190400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1248000000 { + opp-hz = /bits/ 64 <1248000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1324800000 { + opp-hz = /bits/ 64 <1324800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1401600000 { + opp-hz = /bits/ 64 <1401600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1478400000 { + opp-hz = /bits/ 64 <1478400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1555200000 { + opp-hz = /bits/ 64 <1555200000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1632000000 { + opp-hz = /bits/ 64 <1632000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1708800000 { + opp-hz = /bits/ 64 <1708800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1785600000 { + opp-hz = /bits/ 64 <1785600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1804800000 { ++ opp-hz = /bits/ 64 <1804800000>; ++ opp-supported-hw = <0x6>; + clock-latency-ns = <200000>; + }; + opp-1824000000 { + opp-hz = /bits/ 64 <1824000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1900800000 { ++ opp-hz = /bits/ 64 <1900800000>; ++ opp-supported-hw = <0x4>; + clock-latency-ns = <200000>; + }; + opp-1920000000 { + opp-hz = /bits/ 64 <1920000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + opp-1996800000 { + opp-hz = /bits/ 64 <1996800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + opp-2073600000 { + opp-hz = /bits/ 64 <2073600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + opp-2150400000 { + opp-hz = /bits/ 64 <2150400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + }; +@@ -1208,17 +1229,17 @@ + compatible = "operating-points-v2"; + + /* +- * 624Mhz and 560Mhz are only available on speed +- * bin (1 << 0). All the rest are available on +- * all bins of the hardware ++ * 624Mhz is only available on speed bins 0 and 3. ++ * 560Mhz is only available on speed bins 0, 2 and 3. ++ * All the rest are available on all bins of the hardware. + */ + opp-624000000 { + opp-hz = /bits/ 64 <624000000>; +- opp-supported-hw = <0x01>; ++ opp-supported-hw = <0x09>; + }; + opp-560000000 { + opp-hz = /bits/ 64 <560000000>; +- opp-supported-hw = <0x01>; ++ opp-supported-hw = <0x0d>; + }; + opp-510000000 { + opp-hz = /bits/ 64 <510000000>; +@@ -3337,7 +3358,7 @@ + interrupt-names = "intr1", "intr2"; + interrupt-controller; + #interrupt-cells = <1>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_LOW>; + + slim-ifc-dev = <&tasha_ifd>; + +diff --git a/arch/arm64/boot/dts/qcom/msm8996pro.dtsi b/arch/arm64/boot/dts/qcom/msm8996pro.dtsi +new file mode 100644 +index 0000000000000..63e1b4ec7a360 +--- /dev/null ++++ b/arch/arm64/boot/dts/qcom/msm8996pro.dtsi +@@ -0,0 +1,266 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++/* ++ * Copyright (c) 2022, Linaro Limited ++ */ ++ ++#include "msm8996.dtsi" ++ ++/ { ++ /delete-node/ opp-table-cluster0; ++ /delete-node/ opp-table-cluster1; ++ ++ /* ++ * On MSM8996 Pro the cpufreq driver shifts speed bins into the high ++ * nibble of supported hw, so speed bin 0 becomes 0x10, speed bin 1 ++ * becomes 0x20, speed 2 becomes 0x40. ++ */ ++ ++ cluster0_opp: opp-table-cluster0 { ++ compatible = "operating-points-v2-kryo-cpu"; ++ nvmem-cells = <&speedbin_efuse>; ++ opp-shared; ++ ++ opp-307200000 { ++ opp-hz = /bits/ 64 <307200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-384000000 { ++ opp-hz = /bits/ 64 <384000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-460800000 { ++ opp-hz = /bits/ 64 <460800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-537600000 { ++ opp-hz = /bits/ 64 <537600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-614400000 { ++ opp-hz = /bits/ 64 <614400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-691200000 { ++ opp-hz = /bits/ 64 <691200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-768000000 { ++ opp-hz = /bits/ 64 <768000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-844800000 { ++ opp-hz = /bits/ 64 <844800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-902400000 { ++ opp-hz = /bits/ 64 <902400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-979200000 { ++ opp-hz = /bits/ 64 <979200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1056000000 { ++ opp-hz = /bits/ 64 <1056000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1132800000 { ++ opp-hz = /bits/ 64 <1132800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1209600000 { ++ opp-hz = /bits/ 64 <1209600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1286400000 { ++ opp-hz = /bits/ 64 <1286400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1363200000 { ++ opp-hz = /bits/ 64 <1363200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1440000000 { ++ opp-hz = /bits/ 64 <1440000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1516800000 { ++ opp-hz = /bits/ 64 <1516800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1593600000 { ++ opp-hz = /bits/ 64 <1593600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1996800000 { ++ opp-hz = /bits/ 64 <1996800000>; ++ opp-supported-hw = <0x20>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-2188800000 { ++ opp-hz = /bits/ 64 <2188800000>; ++ opp-supported-hw = <0x10>; ++ clock-latency-ns = <200000>; ++ }; ++ }; ++ ++ cluster1_opp: opp-table-cluster1 { ++ compatible = "operating-points-v2-kryo-cpu"; ++ nvmem-cells = <&speedbin_efuse>; ++ opp-shared; ++ ++ opp-307200000 { ++ opp-hz = /bits/ 64 <307200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-384000000 { ++ opp-hz = /bits/ 64 <384000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-460800000 { ++ opp-hz = /bits/ 64 <460800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-537600000 { ++ opp-hz = /bits/ 64 <537600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-614400000 { ++ opp-hz = /bits/ 64 <614400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-691200000 { ++ opp-hz = /bits/ 64 <691200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-748800000 { ++ opp-hz = /bits/ 64 <748800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-825600000 { ++ opp-hz = /bits/ 64 <825600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-902400000 { ++ opp-hz = /bits/ 64 <902400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-979200000 { ++ opp-hz = /bits/ 64 <979200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1056000000 { ++ opp-hz = /bits/ 64 <1056000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1132800000 { ++ opp-hz = /bits/ 64 <1132800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1209600000 { ++ opp-hz = /bits/ 64 <1209600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1286400000 { ++ opp-hz = /bits/ 64 <1286400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1363200000 { ++ opp-hz = /bits/ 64 <1363200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1440000000 { ++ opp-hz = /bits/ 64 <1440000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1516800000 { ++ opp-hz = /bits/ 64 <1516800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1593600000 { ++ opp-hz = /bits/ 64 <1593600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1670400000 { ++ opp-hz = /bits/ 64 <1670400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1747200000 { ++ opp-hz = /bits/ 64 <1747200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1824000000 { ++ opp-hz = /bits/ 64 <1824000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1900800000 { ++ opp-hz = /bits/ 64 <1900800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1977600000 { ++ opp-hz = /bits/ 64 <1977600000>; ++ opp-supported-hw = <0x30>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-2054400000 { ++ opp-hz = /bits/ 64 <2054400000>; ++ opp-supported-hw = <0x30>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-2150400000 { ++ opp-hz = /bits/ 64 <2150400000>; ++ opp-supported-hw = <0x30>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-2246400000 { ++ opp-hz = /bits/ 64 <2246400000>; ++ opp-supported-hw = <0x10>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-2342400000 { ++ opp-hz = /bits/ 64 <2342400000>; ++ opp-supported-hw = <0x10>; ++ clock-latency-ns = <200000>; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/qcom/pm6350.dtsi b/arch/arm64/boot/dts/qcom/pm6350.dtsi +index ecf9b99191828..68245d78d2b93 100644 +--- a/arch/arm64/boot/dts/qcom/pm6350.dtsi ++++ b/arch/arm64/boot/dts/qcom/pm6350.dtsi +@@ -3,6 +3,7 @@ + * Copyright (c) 2021, Luca Weiss + */ + ++#include + #include + + &spmi_bus { +diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi +index d0eefbb516634..d8c9ece20cd9a 100644 +--- a/arch/arm64/boot/dts/qcom/pm660.dtsi ++++ b/arch/arm64/boot/dts/qcom/pm660.dtsi +@@ -163,7 +163,7 @@ + qcom,pre-scaling = <1 3>; + }; + +- vcoin: vcoin@83 { ++ vcoin: vcoin@85 { + reg = ; + qcom,decimation = <1024>; + qcom,pre-scaling = <1 3>; +diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi +index 1bd6c7dcd9e91..bfab67f4a7c9c 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi +@@ -194,6 +194,12 @@ ap_ts_pen_1v8: &i2c4 { + pins = "gpio49", "gpio50", "gpio51", "gpio52"; + function = "mi2s_1"; + }; ++ ++ pinconf { ++ pins = "gpio49", "gpio50", "gpio51", "gpio52"; ++ drive-strength = <2>; ++ bias-pull-down; ++ }; + }; + + &ts_reset_l { +diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi +index 1bc9091cad2a8..12f01815230bc 100644 +--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi +@@ -773,7 +773,7 @@ + pins = "gpio17", "gpio18", "gpio19"; + function = "gpio"; + drive-strength = <2>; +- bias-no-pull; ++ bias-disable; + }; + }; + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +index b5eb8f7eca1d5..b5f11fbcc3004 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +@@ -1436,7 +1436,7 @@ ap_ts_i2c: &i2c14 { + config { + pins = "gpio126"; + function = "gpio"; +- bias-no-pull; ++ bias-disable; + drive-strength = <2>; + output-low; + }; +@@ -1446,7 +1446,7 @@ ap_ts_i2c: &i2c14 { + config { + pins = "gpio126"; + function = "gpio"; +- bias-no-pull; ++ bias-disable; + drive-strength = <2>; + output-high; + }; +diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +index c6e2c571b4527..b2eddcd875069 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +@@ -1081,7 +1081,7 @@ + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; +@@ -1255,7 +1255,7 @@ + reg = <0x60>; + + // CAM3_RST_N +- enable-gpios = <&tlmm 21 0>; ++ enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&cam3_default>; + gpios = <&tlmm 16 0>, +diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts +index 82c27f90d300d..0f470cf1ed1c1 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts +@@ -546,7 +546,7 @@ + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; +diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts +index dba7c2693ff50..1cc477c309451 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts +@@ -126,7 +126,7 @@ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + +- gpio = <&tlmm 23 0>; ++ gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-boot-on; + enable-active-high; +@@ -628,7 +628,7 @@ + }; + + wcd_intr_default: wcd-intr-default { +- pins = "goui54"; ++ pins = "gpio54"; + function = "gpio"; + input-enable; + bias-pull-down; +@@ -712,7 +712,7 @@ + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; +diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +index a7af1bed43129..be59a8ba9c1fe 100644 +--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts ++++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +@@ -772,7 +772,7 @@ + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; +diff --git a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts +index b0315eeb13205..f954fe5cb61ab 100644 +--- a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts ++++ b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts +@@ -704,7 +704,7 @@ + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; +diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi +index 8c582a9e4ada4..0127224086823 100644 +--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi +@@ -458,7 +458,7 @@ + sdhc_1: mmc@4744000 { + compatible = "qcom,sm6125-sdhci", "qcom,sdhci-msm-v5"; + reg = <0x04744000 0x1000>, <0x04745000 0x1000>; +- reg-names = "hc", "core"; ++ reg-names = "hc", "cqhci"; + + interrupts = , + ; +diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi +index d06aefdf3d9ed..76608c1d7f0c4 100644 +--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi +@@ -482,6 +482,7 @@ + interrupts = , + ; + interrupt-names = "hc_irq", "pwr_irq"; ++ iommus = <&apps_smmu 0x60 0x0>; + + clocks = <&gcc GCC_SDCC1_AHB_CLK>, + <&gcc GCC_SDCC1_APPS_CLK>, +@@ -928,6 +929,7 @@ + interrupts = , + ; + interrupt-names = "hc_irq", "pwr_irq"; ++ iommus = <&apps_smmu 0x560 0x0>; + + clocks = <&gcc GCC_SDCC2_AHB_CLK>, + <&gcc GCC_SDCC2_APPS_CLK>, +@@ -1005,15 +1007,11 @@ + dp_phy: dp-phy@88ea200 { + reg = <0 0x088ea200 0 0x200>, + <0 0x088ea400 0 0x200>, +- <0 0x088eac00 0 0x400>, ++ <0 0x088eaa00 0 0x200>, + <0 0x088ea600 0 0x200>, +- <0 0x088ea800 0 0x200>, +- <0 0x088eaa00 0 0x100>; ++ <0 0x088ea800 0 0x200>; + #phy-cells = <0>; + #clock-cells = <1>; +- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; +- clock-names = "pipe0"; +- clock-output-names = "usb3_phy_pipe_clk_src"; + }; + }; + +diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi +index 916f12b799b79..3df80dde92496 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi +@@ -2038,11 +2038,11 @@ + status = "disabled"; + + ufs_mem_phy_lanes: phy@1d87400 { +- reg = <0 0x01d87400 0 0x108>, +- <0 0x01d87600 0 0x1e0>, +- <0 0x01d87c00 0 0x1dc>, +- <0 0x01d87800 0 0x108>, +- <0 0x01d87a00 0 0x1e0>; ++ reg = <0 0x01d87400 0 0x16c>, ++ <0 0x01d87600 0 0x200>, ++ <0 0x01d87c00 0 0x200>, ++ <0 0x01d87800 0 0x16c>, ++ <0 0x01d87a00 0 0x200>; + #phy-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts +index 7ab3627cc347d..a05fe468e0b41 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts ++++ b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts +@@ -635,7 +635,7 @@ + wcd938x: codec { + compatible = "qcom,wcd9380-codec"; + #sound-dai-cells = <1>; +- reset-gpios = <&tlmm 32 0>; ++ reset-gpios = <&tlmm 32 GPIO_ACTIVE_LOW>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-rxtx-supply = <&vreg_s4a_1p8>; + vdd-io-supply = <&vreg_s4a_1p8>; +diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi +index 5428aab3058dd..e4769dcfaad7b 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi +@@ -619,7 +619,7 @@ + pins = "gpio39"; + function = "gpio"; + drive-strength = <2>; +- bias-disabled; ++ bias-disable; + input-enable; + }; + +diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi +index 052b4dbc1ee44..652fb0231da0e 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi +@@ -2172,11 +2172,11 @@ + status = "disabled"; + + ufs_mem_phy_lanes: phy@1d87400 { +- reg = <0 0x01d87400 0 0x108>, +- <0 0x01d87600 0 0x1e0>, +- <0 0x01d87c00 0 0x1dc>, +- <0 0x01d87800 0 0x108>, +- <0 0x01d87a00 0 0x1e0>; ++ reg = <0 0x01d87400 0 0x16c>, ++ <0 0x01d87600 0 0x200>, ++ <0 0x01d87c00 0 0x200>, ++ <0 0x01d87800 0 0x16c>, ++ <0 0x01d87a00 0 0x200>; + #phy-cells = <0>; + }; + }; +@@ -2447,7 +2447,7 @@ + pins = "gpio7"; + function = "dmic1_data"; + drive-strength = <2>; +- pull-down; ++ bias-pull-down; + input-enable; + }; + }; +@@ -2884,15 +2884,11 @@ + dp_phy: dp-phy@88ea200 { + reg = <0 0x088ea200 0 0x200>, + <0 0x088ea400 0 0x200>, +- <0 0x088eac00 0 0x400>, ++ <0 0x088eaa00 0 0x200>, + <0 0x088ea600 0 0x200>, +- <0 0x088ea800 0 0x200>, +- <0 0x088eaa00 0 0x100>; ++ <0 0x088ea800 0 0x200>; + #phy-cells = <0>; + #clock-cells = <1>; +- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; +- clock-names = "pipe0"; +- clock-output-names = "usb3_phy_pipe_clk_src"; + }; + }; + +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index d9b08dfc2980d..eace5b2ee3812 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -2142,11 +2142,11 @@ + status = "disabled"; + + ufs_mem_phy_lanes: phy@1d87400 { +- reg = <0 0x01d87400 0 0x108>, +- <0 0x01d87600 0 0x1e0>, +- <0 0x01d87c00 0 0x1dc>, +- <0 0x01d87800 0 0x108>, +- <0 0x01d87a00 0 0x1e0>; ++ reg = <0 0x01d87400 0 0x188>, ++ <0 0x01d87600 0 0x200>, ++ <0 0x01d87c00 0 0x200>, ++ <0 0x01d87800 0 0x188>, ++ <0 0x01d87a00 0 0x200>; + #phy-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi +index 8a6c0f3e7bb70..ed3e1eff4f58f 100644 +--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi +@@ -3131,11 +3131,11 @@ + status = "disabled"; + + ufs_mem_phy_lanes: phy@1d87400 { +- reg = <0 0x01d87400 0 0x108>, +- <0 0x01d87600 0 0x1e0>, +- <0 0x01d87c00 0 0x1dc>, +- <0 0x01d87800 0 0x108>, +- <0 0x01d87a00 0 0x1e0>; ++ reg = <0 0x01d87400 0 0x188>, ++ <0 0x01d87600 0 0x200>, ++ <0 0x01d87c00 0 0x200>, ++ <0 0x01d87800 0 0x188>, ++ <0 0x01d87a00 0 0x200>; + #phy-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +index 384817ffa4deb..d4f3ebfe841ab 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +@@ -442,7 +442,7 @@ + reg = <0 0xe6540000 0 0x60>; + interrupts = ; + clocks = <&cpg CPG_MOD 514>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x31>, <&dmac0 0x30>, +@@ -459,7 +459,7 @@ + reg = <0 0xe6550000 0 0x60>; + interrupts = ; + clocks = <&cpg CPG_MOD 515>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x33>, <&dmac0 0x32>, +@@ -476,7 +476,7 @@ + reg = <0 0xe6560000 0 0x60>; + interrupts = ; + clocks = <&cpg CPG_MOD 516>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x35>, <&dmac0 0x34>, +@@ -493,7 +493,7 @@ + reg = <0 0xe66a0000 0 0x60>; + interrupts = ; + clocks = <&cpg CPG_MOD 517>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x37>, <&dmac0 0x36>, +@@ -522,7 +522,7 @@ + reg = <0 0xe6e60000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 702>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x51>, <&dmac0 0x50>, +@@ -539,7 +539,7 @@ + reg = <0 0xe6e68000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x53>, <&dmac0 0x52>, +@@ -556,7 +556,7 @@ + reg = <0 0xe6c50000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 704>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x57>, <&dmac0 0x56>, +@@ -573,7 +573,7 @@ + reg = <0 0xe6c40000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 705>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x59>, <&dmac0 0x58>, +diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi +index 1c15726cff8bf..4bd3cb107b38b 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi +@@ -87,7 +87,7 @@ + reg = <0 0xe6540000 0 96>; + interrupts = ; + clocks = <&cpg CPG_MOD 514>, +- <&cpg CPG_CORE R8A779G0_CLK_S0D3_PER>, ++ <&cpg CPG_CORE R8A779G0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; +diff --git a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi +index d4cc5459fbb76..4ce0f39446492 100644 +--- a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi ++++ b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi +@@ -48,7 +48,7 @@ + #size-cells = <2>; + ranges; + +- gic: interrupt-controller@82000000 { ++ gic: interrupt-controller@82010000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <0>; +diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi +index d0abb9aa0e9ed..e3852c9463528 100644 +--- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi ++++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi +@@ -55,14 +55,14 @@ + samsung,pins = "gpf5-0"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + ufs_refclk_out: ufs-refclk-out-pins { + samsung,pins = "gpf5-1"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + }; + +@@ -239,105 +239,105 @@ + samsung,pins = "gpb6-1"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + pwm1_out: pwm1-out-pins { + samsung,pins = "gpb6-5"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c0_bus: hs-i2c0-bus-pins { + samsung,pins = "gpb0-0", "gpb0-1"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c1_bus: hs-i2c1-bus-pins { + samsung,pins = "gpb0-2", "gpb0-3"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c2_bus: hs-i2c2-bus-pins { + samsung,pins = "gpb0-4", "gpb0-5"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c3_bus: hs-i2c3-bus-pins { + samsung,pins = "gpb0-6", "gpb0-7"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c4_bus: hs-i2c4-bus-pins { + samsung,pins = "gpb1-0", "gpb1-1"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c5_bus: hs-i2c5-bus-pins { + samsung,pins = "gpb1-2", "gpb1-3"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c6_bus: hs-i2c6-bus-pins { + samsung,pins = "gpb1-4", "gpb1-5"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c7_bus: hs-i2c7-bus-pins { + samsung,pins = "gpb1-6", "gpb1-7"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + uart0_data: uart0-data-pins { + samsung,pins = "gpb7-0", "gpb7-1"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + uart1_data: uart1-data-pins { + samsung,pins = "gpb7-4", "gpb7-5"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + spi0_bus: spi0-bus-pins { + samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + spi1_bus: spi1-bus-pins { + samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + spi2_bus: spi2-bus-pins { + samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + }; + +diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.h b/arch/arm64/boot/dts/tesla/fsd-pinctrl.h +index 6ffbda3624930..c397d02208a08 100644 +--- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.h ++++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.h +@@ -16,9 +16,9 @@ + #define FSD_PIN_PULL_UP 3 + + #define FSD_PIN_DRV_LV1 0 +-#define FSD_PIN_DRV_LV2 2 +-#define FSD_PIN_DRV_LV3 1 +-#define FSD_PIN_DRV_LV4 3 ++#define FSD_PIN_DRV_LV2 1 ++#define FSD_PIN_DRV_LV4 2 ++#define FSD_PIN_DRV_LV6 3 + + #define FSD_PIN_FUNC_INPUT 0 + #define FSD_PIN_FUNC_OUTPUT 1 +diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +index 8919fede3cd76..ef960386c62cb 100644 +--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +@@ -120,7 +120,6 @@ + dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, + <&main_udmap 0x4001>; + dma-names = "tx", "rx1", "rx2"; +- dma-coherent; + + rng: rng@4e10000 { + compatible = "inside-secure,safexcel-eip76"; +diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +index 43b6cf5791eee..75789c0f82bd3 100644 +--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +@@ -337,7 +337,6 @@ + dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, + <&main_udmap 0x4001>; + dma-names = "tx", "rx1", "rx2"; +- dma-coherent; + + rng: rng@4e10000 { + compatible = "inside-secure,safexcel-eip76"; +diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi +index 34e7d577ae13b..c89f28235812a 100644 +--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi +@@ -60,7 +60,7 @@ + #interrupt-cells = <1>; + ti,sci = <&sms>; + ti,sci-dev-id = <148>; +- ti,interrupt-ranges = <8 360 56>; ++ ti,interrupt-ranges = <8 392 56>; + }; + + main_pmx0: pinctrl@11c000 { +diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi +index 4d1bfabd1313a..f0644851602cd 100644 +--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi +@@ -65,7 +65,7 @@ + #interrupt-cells = <1>; + ti,sci = <&sms>; + ti,sci-dev-id = <125>; +- ti,interrupt-ranges = <16 928 16>; ++ ti,interrupt-ranges = <16 960 16>; + }; + + mcu_conf: syscon@40f00000 { +diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h +index 86eb0bfe3b380..d9144b6e078c8 100644 +--- a/arch/arm64/include/asm/processor.h ++++ b/arch/arm64/include/asm/processor.h +@@ -308,13 +308,13 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, + } + #endif + +-static inline bool is_ttbr0_addr(unsigned long addr) ++static __always_inline bool is_ttbr0_addr(unsigned long addr) + { + /* entry assembly clears tags for TTBR0 addrs */ + return addr < TASK_SIZE; + } + +-static inline bool is_ttbr1_addr(unsigned long addr) ++static __always_inline bool is_ttbr1_addr(unsigned long addr) + { + /* TTBR1 addresses may have a tag if KASAN_SW_TAGS is in use */ + return arch_kasan_reset_tag(addr) >= PAGE_OFFSET; +diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c +index c33f1fad27450..89628bd370d91 100644 +--- a/arch/arm64/mm/fault.c ++++ b/arch/arm64/mm/fault.c +@@ -353,6 +353,11 @@ static bool is_el1_mte_sync_tag_check_fault(unsigned long esr) + return false; + } + ++static bool is_translation_fault(unsigned long esr) ++{ ++ return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT; ++} ++ + static void __do_kernel_fault(unsigned long addr, unsigned long esr, + struct pt_regs *regs) + { +@@ -385,7 +390,8 @@ static void __do_kernel_fault(unsigned long addr, unsigned long esr, + } else if (addr < PAGE_SIZE) { + msg = "NULL pointer dereference"; + } else { +- if (kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs)) ++ if (is_translation_fault(esr) && ++ kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs)) + return; + + msg = "paging request"; +diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c +index 6e6756e8fa0a9..86a6e25908664 100644 +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -361,6 +361,8 @@ static struct clk clk_periph = { + */ + int clk_enable(struct clk *clk) + { ++ if (!clk) ++ return 0; + mutex_lock(&clocks_mutex); + clk_enable_unlocked(clk); + mutex_unlock(&clocks_mutex); +diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +index d09d0769f5496..0fd9ac76eb742 100644 +--- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c ++++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +@@ -211,7 +211,7 @@ union cvmx_helper_link_info __cvmx_helper_board_link_get(int ipd_port) + { + union cvmx_helper_link_info result; + +- WARN(!octeon_is_simulation(), ++ WARN_ONCE(!octeon_is_simulation(), + "Using deprecated link status - please update your DT"); + + /* Unless we fix it later, all links are defaulted to down */ +diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c +index 6f49fd9be1f3c..9abfc4bf9bd83 100644 +--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c ++++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c +@@ -1096,7 +1096,7 @@ union cvmx_helper_link_info cvmx_helper_link_get(int ipd_port) + if (index == 0) + result = __cvmx_helper_rgmii_link_get(ipd_port); + else { +- WARN(1, "Using deprecated link status - please update your DT"); ++ WARN_ONCE(1, "Using deprecated link status - please update your DT"); + result.s.full_duplex = 1; + result.s.link_up = 1; + result.s.speed = 1000; +diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h +index 6bbf082dd149e..79d5bb0e06d63 100644 +--- a/arch/mips/include/asm/mach-ralink/mt7621.h ++++ b/arch/mips/include/asm/mach-ralink/mt7621.h +@@ -7,10 +7,12 @@ + #ifndef _MT7621_REGS_H_ + #define _MT7621_REGS_H_ + ++#define IOMEM(x) ((void __iomem *)(KSEG1ADDR(x))) ++ + #define MT7621_PALMBUS_BASE 0x1C000000 + #define MT7621_PALMBUS_SIZE 0x03FFFFFF + +-#define MT7621_SYSC_BASE 0x1E000000 ++#define MT7621_SYSC_BASE IOMEM(0x1E000000) + + #define SYSC_REG_CHIP_NAME0 0x00 + #define SYSC_REG_CHIP_NAME1 0x04 +diff --git a/arch/mips/kernel/vpe-cmp.c b/arch/mips/kernel/vpe-cmp.c +index e673603e11e5d..92140edb3ce3e 100644 +--- a/arch/mips/kernel/vpe-cmp.c ++++ b/arch/mips/kernel/vpe-cmp.c +@@ -75,7 +75,6 @@ ATTRIBUTE_GROUPS(vpe); + + static void vpe_device_release(struct device *cd) + { +- kfree(cd); + } + + static struct class vpe_class = { +@@ -157,6 +156,7 @@ out_dev: + device_del(&vpe_device); + + out_class: ++ put_device(&vpe_device); + class_unregister(&vpe_class); + + out_chrdev: +@@ -169,7 +169,7 @@ void __exit vpe_module_exit(void) + { + struct vpe *v, *n; + +- device_del(&vpe_device); ++ device_unregister(&vpe_device); + class_unregister(&vpe_class); + unregister_chrdev(major, VPE_MODULE_NAME); + +diff --git a/arch/mips/kernel/vpe-mt.c b/arch/mips/kernel/vpe-mt.c +index bad6b0891b2b5..84a82b551ec35 100644 +--- a/arch/mips/kernel/vpe-mt.c ++++ b/arch/mips/kernel/vpe-mt.c +@@ -313,7 +313,6 @@ ATTRIBUTE_GROUPS(vpe); + + static void vpe_device_release(struct device *cd) + { +- kfree(cd); + } + + static struct class vpe_class = { +@@ -497,6 +496,7 @@ out_dev: + device_del(&vpe_device); + + out_class: ++ put_device(&vpe_device); + class_unregister(&vpe_class); + + out_chrdev: +@@ -509,7 +509,7 @@ void __exit vpe_module_exit(void) + { + struct vpe *v, *n; + +- device_del(&vpe_device); ++ device_unregister(&vpe_device); + class_unregister(&vpe_class); + unregister_chrdev(major, VPE_MODULE_NAME); + +diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c +index fb0565bc34fda..bbf5811afbf2c 100644 +--- a/arch/mips/ralink/mt7621.c ++++ b/arch/mips/ralink/mt7621.c +@@ -25,6 +25,7 @@ + #define MT7621_MEM_TEST_PATTERN 0xaa5555aa + + static u32 detect_magic __initdata; ++static struct ralink_soc_info *soc_info_ptr; + + int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) + { +@@ -97,41 +98,83 @@ void __init ralink_of_remap(void) + panic("Failed to remap core resources"); + } + +-static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev) ++static unsigned int __init mt7621_get_soc_name0(void) ++{ ++ return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME0); ++} ++ ++static unsigned int __init mt7621_get_soc_name1(void) ++{ ++ return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME1); ++} ++ ++static bool __init mt7621_soc_valid(void) ++{ ++ if (mt7621_get_soc_name0() == MT7621_CHIP_NAME0 && ++ mt7621_get_soc_name1() == MT7621_CHIP_NAME1) ++ return true; ++ else ++ return false; ++} ++ ++static const char __init *mt7621_get_soc_id(void) ++{ ++ if (mt7621_soc_valid()) ++ return "MT7621"; ++ else ++ return "invalid"; ++} ++ ++static unsigned int __init mt7621_get_soc_rev(void) ++{ ++ return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_REV); ++} ++ ++static unsigned int __init mt7621_get_soc_ver(void) ++{ ++ return (mt7621_get_soc_rev() >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK; ++} ++ ++static unsigned int __init mt7621_get_soc_eco(void) ++{ ++ return (mt7621_get_soc_rev() & CHIP_REV_ECO_MASK); ++} ++ ++static const char __init *mt7621_get_soc_revision(void) ++{ ++ if (mt7621_get_soc_rev() == 1 && mt7621_get_soc_eco() == 1) ++ return "E2"; ++ else ++ return "E1"; ++} ++ ++static int __init mt7621_soc_dev_init(void) + { + struct soc_device *soc_dev; + struct soc_device_attribute *soc_dev_attr; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) +- return; ++ return -ENOMEM; + + soc_dev_attr->soc_id = "mt7621"; + soc_dev_attr->family = "Ralink"; ++ soc_dev_attr->revision = mt7621_get_soc_revision(); + +- if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 && +- (rev & CHIP_REV_ECO_MASK) == 1) +- soc_dev_attr->revision = "E2"; +- else +- soc_dev_attr->revision = "E1"; +- +- soc_dev_attr->data = soc_info; ++ soc_dev_attr->data = soc_info_ptr; + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr); +- return; ++ return PTR_ERR(soc_dev); + } ++ ++ return 0; + } ++device_initcall(mt7621_soc_dev_init); + + void __init prom_soc_init(struct ralink_soc_info *soc_info) + { +- void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE); +- unsigned char *name = NULL; +- u32 n0; +- u32 n1; +- u32 rev; +- + /* Early detection of CMP support */ + mips_cm_probe(); + mips_cpc_probe(); +@@ -154,27 +197,23 @@ void __init prom_soc_init(struct ralink_soc_info *soc_info) + __sync(); + } + +- n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); +- n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); +- +- if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) { +- name = "MT7621"; ++ if (mt7621_soc_valid()) + soc_info->compatible = "mediatek,mt7621-soc"; +- } else { +- panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1); +- } ++ else ++ panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", ++ mt7621_get_soc_name0(), ++ mt7621_get_soc_name1()); + ralink_soc = MT762X_SOC_MT7621AT; +- rev = __raw_readl(sysc + SYSC_REG_CHIP_REV); + + snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, + "MediaTek %s ver:%u eco:%u", +- name, +- (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK, +- (rev & CHIP_REV_ECO_MASK)); ++ mt7621_get_soc_id(), ++ mt7621_get_soc_ver(), ++ mt7621_get_soc_eco()); + + soc_info->mem_detect = mt7621_memory_detect; + +- soc_dev_init(soc_info, rev); ++ soc_info_ptr = soc_info; + + if (!register_cps_smp_ops()) + return; +diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c +index ea8072acf8d94..01c132bc33d54 100644 +--- a/arch/mips/ralink/of.c ++++ b/arch/mips/ralink/of.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #include "common.h" + +@@ -81,7 +82,8 @@ static int __init plat_of_setup(void) + __dt_register_buses(soc_info.compatible, "palmbus"); + + /* make sure that the reset controller is setup early */ +- ralink_rst_init(); ++ if (ralink_soc != MT762X_SOC_MT7621AT) ++ ralink_rst_init(); + + return 0; + } +diff --git a/arch/powerpc/boot/dts/turris1x.dts b/arch/powerpc/boot/dts/turris1x.dts +index 045af668e9284..e9cda34a140e0 100644 +--- a/arch/powerpc/boot/dts/turris1x.dts ++++ b/arch/powerpc/boot/dts/turris1x.dts +@@ -69,6 +69,20 @@ + interrupt-parent = <&gpio>; + interrupts = <12 IRQ_TYPE_LEVEL_LOW>, /* GPIO12 - ALERT pin */ + <13 IRQ_TYPE_LEVEL_LOW>; /* GPIO13 - CRIT pin */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* Local temperature sensor (SA56004ED internal) */ ++ channel@0 { ++ reg = <0>; ++ label = "board"; ++ }; ++ ++ /* Remote temperature sensor (D+/D- connected to P2020 CPU Temperature Diode) */ ++ channel@1 { ++ reg = <1>; ++ label = "cpu"; ++ }; + }; + + /* DDR3 SPD/EEPROM */ +diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h +index 8abae463f6c12..95fd7f9485d55 100644 +--- a/arch/powerpc/include/asm/hvcall.h ++++ b/arch/powerpc/include/asm/hvcall.h +@@ -79,7 +79,7 @@ + #define H_NOT_ENOUGH_RESOURCES -44 + #define H_R_STATE -45 + #define H_RESCINDED -46 +-#define H_P1 -54 ++#define H_ABORTED -54 + #define H_P2 -55 + #define H_P3 -56 + #define H_P4 -57 +@@ -100,7 +100,6 @@ + #define H_COP_HW -74 + #define H_STATE -75 + #define H_IN_USE -77 +-#define H_ABORTED -78 + #define H_UNSUPPORTED_FLAG_START -256 + #define H_UNSUPPORTED_FLAG_END -511 + #define H_MULTI_THREADS_ACTIVE -9005 +diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c +index 082f6d0308a47..8718289c051dd 100644 +--- a/arch/powerpc/perf/callchain.c ++++ b/arch/powerpc/perf/callchain.c +@@ -61,6 +61,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re + next_sp = fp[0]; + + if (next_sp == sp + STACK_INT_FRAME_SIZE && ++ validate_sp(sp, current, STACK_INT_FRAME_SIZE) && + fp[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) { + /* + * This looks like an interrupt frame for an +diff --git a/arch/powerpc/perf/hv-gpci-requests.h b/arch/powerpc/perf/hv-gpci-requests.h +index 8965b4463d433..5e86371a20c78 100644 +--- a/arch/powerpc/perf/hv-gpci-requests.h ++++ b/arch/powerpc/perf/hv-gpci-requests.h +@@ -79,6 +79,7 @@ REQUEST(__field(0, 8, partition_id) + ) + #include I(REQUEST_END) + ++#ifdef ENABLE_EVENTS_COUNTERINFO_V6 + /* + * Not available for counter_info_version >= 0x8, use + * run_instruction_cycles_by_partition(0x100) instead. +@@ -92,6 +93,7 @@ REQUEST(__field(0, 8, partition_id) + __count(0x10, 8, cycles) + ) + #include I(REQUEST_END) ++#endif + + #define REQUEST_NAME system_performance_capabilities + #define REQUEST_NUM 0x40 +@@ -103,6 +105,7 @@ REQUEST(__field(0, 1, perf_collect_privileged) + ) + #include I(REQUEST_END) + ++#ifdef ENABLE_EVENTS_COUNTERINFO_V6 + #define REQUEST_NAME processor_bus_utilization_abc_links + #define REQUEST_NUM 0x50 + #define REQUEST_IDX_KIND "hw_chip_id=?" +@@ -194,6 +197,7 @@ REQUEST(__field(0, 4, phys_processor_idx) + __count(0x28, 8, instructions_completed) + ) + #include I(REQUEST_END) ++#endif + + /* Processor_core_power_mode (0x95) skipped, no counters */ + /* Affinity_domain_information_by_virtual_processor (0xA0) skipped, +diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c +index 5eb60ed5b5e8a..7ff8ff3509f5f 100644 +--- a/arch/powerpc/perf/hv-gpci.c ++++ b/arch/powerpc/perf/hv-gpci.c +@@ -70,9 +70,9 @@ static const struct attribute_group format_group = { + .attrs = format_attrs, + }; + +-static const struct attribute_group event_group = { ++static struct attribute_group event_group = { + .name = "events", +- .attrs = hv_gpci_event_attrs, ++ /* .attrs is set in init */ + }; + + #define HV_CAPS_ATTR(_name, _format) \ +@@ -330,6 +330,7 @@ static int hv_gpci_init(void) + int r; + unsigned long hret; + struct hv_perf_caps caps; ++ struct hv_gpci_request_buffer *arg; + + hv_gpci_assert_offsets_correct(); + +@@ -353,6 +354,36 @@ static int hv_gpci_init(void) + /* sampling not supported */ + h_gpci_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; + ++ arg = (void *)get_cpu_var(hv_gpci_reqb); ++ memset(arg, 0, HGPCI_REQ_BUFFER_SIZE); ++ ++ /* ++ * hcall H_GET_PERF_COUNTER_INFO populates the output ++ * counter_info_version value based on the system hypervisor. ++ * Pass the counter request 0x10 corresponds to request type ++ * 'Dispatch_timebase_by_processor', to get the supported ++ * counter_info_version. ++ */ ++ arg->params.counter_request = cpu_to_be32(0x10); ++ ++ r = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, ++ virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE); ++ if (r) { ++ pr_devel("hcall failed, can't get supported counter_info_version: 0x%x\n", r); ++ arg->params.counter_info_version_out = 0x8; ++ } ++ ++ /* ++ * Use counter_info_version_out value to assign ++ * required hv-gpci event list. ++ */ ++ if (arg->params.counter_info_version_out >= 0x8) ++ event_group.attrs = hv_gpci_event_attrs; ++ else ++ event_group.attrs = hv_gpci_event_attrs_v6; ++ ++ put_cpu_var(hv_gpci_reqb); ++ + r = perf_pmu_register(&h_gpci_pmu, h_gpci_pmu.name, -1); + if (r) + return r; +diff --git a/arch/powerpc/perf/hv-gpci.h b/arch/powerpc/perf/hv-gpci.h +index 4d108262bed79..c72020912dea5 100644 +--- a/arch/powerpc/perf/hv-gpci.h ++++ b/arch/powerpc/perf/hv-gpci.h +@@ -26,6 +26,7 @@ enum { + #define REQUEST_FILE "../hv-gpci-requests.h" + #define NAME_LOWER hv_gpci + #define NAME_UPPER HV_GPCI ++#define ENABLE_EVENTS_COUNTERINFO_V6 + #include "req-gen/perf.h" + #undef REQUEST_FILE + #undef NAME_LOWER +diff --git a/arch/powerpc/perf/req-gen/perf.h b/arch/powerpc/perf/req-gen/perf.h +index fa9bc804e67af..6b2a59fefffa7 100644 +--- a/arch/powerpc/perf/req-gen/perf.h ++++ b/arch/powerpc/perf/req-gen/perf.h +@@ -139,6 +139,26 @@ PMU_EVENT_ATTR_STRING( \ + #define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ + r_fields + ++/* Generate event list for platforms with counter_info_version 0x6 or below */ ++static __maybe_unused struct attribute *hv_gpci_event_attrs_v6[] = { ++#include REQUEST_FILE ++ NULL ++}; ++ ++/* ++ * Based on getPerfCountInfo v1.018 documentation, some of the hv-gpci ++ * events were deprecated for platform firmware that supports ++ * counter_info_version 0x8 or above. ++ * Those deprecated events are still part of platform firmware that ++ * support counter_info_version 0x6 and below. As per the getPerfCountInfo ++ * v1.018 documentation there is no counter_info_version 0x7. ++ * Undefining macro ENABLE_EVENTS_COUNTERINFO_V6, to disable the addition of ++ * deprecated events in "hv_gpci_event_attrs" attribute group, for platforms ++ * that supports counter_info_version 0x8 or above. ++ */ ++#undef ENABLE_EVENTS_COUNTERINFO_V6 ++ ++/* Generate event list for platforms with counter_info_version 0x8 or above*/ + static __maybe_unused struct attribute *hv_gpci_event_attrs[] = { + #include REQUEST_FILE + NULL +diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +index 48038aaedbd36..2875c206ac0f8 100644 +--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c ++++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +@@ -531,6 +531,7 @@ static int mpc52xx_lpbfifo_probe(struct platform_device *op) + err_bcom_rx_irq: + bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task); + err_bcom_rx: ++ free_irq(lpbfifo.irq, &lpbfifo); + err_irq: + iounmap(lpbfifo.regs); + lpbfifo.regs = NULL; +diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c +index bb8caa5071f8c..dddb5c6f81209 100644 +--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c ++++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c +@@ -107,7 +107,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, + + goto next; + unreg: +- platform_device_del(pdev); ++ platform_device_put(pdev); + err: + pr_err("%pOF: registration failed\n", np); + next: +diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c +index 8e40ccac0f44e..e5a58a9b2fe9f 100644 +--- a/arch/powerpc/platforms/pseries/eeh_pseries.c ++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c +@@ -848,16 +848,7 @@ static int __init eeh_pseries_init(void) + } + + /* Initialize error log size */ +- eeh_error_buf_size = rtas_token("rtas-error-log-max"); +- if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) { +- pr_info("%s: unknown EEH error log size\n", +- __func__); +- eeh_error_buf_size = 1024; +- } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) { +- pr_info("%s: EEH error log size %d exceeds the maximal %d\n", +- __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX); +- eeh_error_buf_size = RTAS_ERROR_LOG_MAX; +- } ++ eeh_error_buf_size = rtas_get_error_log_max(); + + /* Set EEH probe mode */ + eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG); +diff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c +index f4b5b5a64db3d..63a1e1fe01851 100644 +--- a/arch/powerpc/platforms/pseries/plpks.c ++++ b/arch/powerpc/platforms/pseries/plpks.c +@@ -75,7 +75,7 @@ static int pseries_status_to_err(int rc) + case H_FUNCTION: + err = -ENXIO; + break; +- case H_P1: ++ case H_PARAMETER: + case H_P2: + case H_P3: + case H_P4: +@@ -111,7 +111,7 @@ static int pseries_status_to_err(int rc) + err = -EEXIST; + break; + case H_ABORTED: +- err = -EINTR; ++ err = -EIO; + break; + default: + err = -EINVAL; +@@ -366,22 +366,24 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var) + { + unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; + struct plpks_auth *auth; +- struct label *label; ++ struct label *label = NULL; + u8 *output; + int rc; + + if (var->namelen > MAX_NAME_SIZE) + return -EINVAL; + +- auth = construct_auth(PKS_OS_OWNER); ++ auth = construct_auth(consumer); + if (IS_ERR(auth)) + return PTR_ERR(auth); + +- label = construct_label(var->component, var->os, var->name, +- var->namelen); +- if (IS_ERR(label)) { +- rc = PTR_ERR(label); +- goto out_free_auth; ++ if (consumer == PKS_OS_OWNER) { ++ label = construct_label(var->component, var->os, var->name, ++ var->namelen); ++ if (IS_ERR(label)) { ++ rc = PTR_ERR(label); ++ goto out_free_auth; ++ } + } + + output = kzalloc(maxobjsize, GFP_KERNEL); +@@ -390,9 +392,15 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var) + goto out_free_label; + } + +- rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth), +- virt_to_phys(label), label->size, virt_to_phys(output), +- maxobjsize); ++ if (consumer == PKS_OS_OWNER) ++ rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth), ++ virt_to_phys(label), label->size, virt_to_phys(output), ++ maxobjsize); ++ else ++ rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth), ++ virt_to_phys(var->name), var->namelen, virt_to_phys(output), ++ maxobjsize); ++ + + if (rc != H_SUCCESS) { + pr_err("Failed to read variable %s for component %s with error %d\n", +diff --git a/arch/powerpc/platforms/pseries/plpks.h b/arch/powerpc/platforms/pseries/plpks.h +index c6a291367bb13..275ccd86bfb5e 100644 +--- a/arch/powerpc/platforms/pseries/plpks.h ++++ b/arch/powerpc/platforms/pseries/plpks.h +@@ -17,7 +17,7 @@ + #define WORLDREADABLE 0x08000000 + #define SIGNEDUPDATE 0x01000000 + +-#define PLPKS_VAR_LINUX 0x01 ++#define PLPKS_VAR_LINUX 0x02 + #define PLPKS_VAR_COMMON 0x04 + + struct plpks_var { +diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c +index e2c8f93b535ba..e454192643910 100644 +--- a/arch/powerpc/sysdev/xive/spapr.c ++++ b/arch/powerpc/sysdev/xive/spapr.c +@@ -439,6 +439,7 @@ static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) + + data->trig_mmio = ioremap(data->trig_page, 1u << data->esb_shift); + if (!data->trig_mmio) { ++ iounmap(data->eoi_mmio); + pr_err("Failed to map trigger page for irq 0x%x\n", hw_irq); + return -ENOMEM; + } +diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c +index 26ef3388c24c4..df91dfc7ff727 100644 +--- a/arch/powerpc/xmon/xmon.c ++++ b/arch/powerpc/xmon/xmon.c +@@ -1525,9 +1525,9 @@ bpt_cmds(void) + cmd = inchar(); + + switch (cmd) { +- static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n"; +- int mode; +- case 'd': /* bd - hardware data breakpoint */ ++ case 'd': { /* bd - hardware data breakpoint */ ++ static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n"; ++ int mode; + if (xmon_is_ro) { + printf(xmon_ro_msg); + break; +@@ -1560,6 +1560,7 @@ bpt_cmds(void) + + force_enable_xmon(); + break; ++ } + + case 'i': /* bi - hardware instr breakpoint */ + if (xmon_is_ro) { +diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h +index a5c2ca1d1cd8b..ec19d6afc8965 100644 +--- a/arch/riscv/include/asm/hugetlb.h ++++ b/arch/riscv/include/asm/hugetlb.h +@@ -5,4 +5,10 @@ + #include + #include + ++static inline void arch_clear_hugepage_flags(struct page *page) ++{ ++ clear_bit(PG_dcache_clean, &page->flags); ++} ++#define arch_clear_hugepage_flags arch_clear_hugepage_flags ++ + #endif /* _ASM_RISCV_HUGETLB_H */ +diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h +index 92080a2279372..42497d487a174 100644 +--- a/arch/riscv/include/asm/io.h ++++ b/arch/riscv/include/asm/io.h +@@ -135,4 +135,9 @@ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw()) + + #include + ++#ifdef CONFIG_MMU ++#define arch_memremap_wb(addr, size) \ ++ ((__force void *)ioremap_prot((addr), (size), _PAGE_KERNEL)) ++#endif ++ + #endif /* _ASM_RISCV_IO_H */ +diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h +index dc42375c23571..42a042c0e13ed 100644 +--- a/arch/riscv/include/asm/pgtable-64.h ++++ b/arch/riscv/include/asm/pgtable-64.h +@@ -25,7 +25,11 @@ extern bool pgtable_l5_enabled; + #define PGDIR_MASK (~(PGDIR_SIZE - 1)) + + /* p4d is folded into pgd in case of 4-level page table */ +-#define P4D_SHIFT 39 ++#define P4D_SHIFT_L3 30 ++#define P4D_SHIFT_L4 39 ++#define P4D_SHIFT_L5 39 ++#define P4D_SHIFT (pgtable_l5_enabled ? P4D_SHIFT_L5 : \ ++ (pgtable_l4_enabled ? P4D_SHIFT_L4 : P4D_SHIFT_L3)) + #define P4D_SIZE (_AC(1, UL) << P4D_SHIFT) + #define P4D_MASK (~(P4D_SIZE - 1)) + +diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S +index 186abd146eaff..3221a9e5f3724 100644 +--- a/arch/riscv/kernel/entry.S ++++ b/arch/riscv/kernel/entry.S +@@ -263,12 +263,11 @@ ret_from_exception: + #endif + bnez s0, resume_kernel + +-resume_userspace: + /* Interrupts must be disabled here so flags are checked atomically */ + REG_L s0, TASK_TI_FLAGS(tp) /* current_thread_info->flags */ + andi s1, s0, _TIF_WORK_MASK +- bnez s1, work_pending +- ++ bnez s1, resume_userspace_slow ++resume_userspace: + #ifdef CONFIG_CONTEXT_TRACKING_USER + call user_enter_callable + #endif +@@ -368,19 +367,12 @@ resume_kernel: + j restore_all + #endif + +-work_pending: ++resume_userspace_slow: + /* Enter slow path for supplementary processing */ +- la ra, ret_from_exception +- andi s1, s0, _TIF_NEED_RESCHED +- bnez s1, work_resched +-work_notifysig: +- /* Handle pending signals and notify-resume requests */ +- csrs CSR_STATUS, SR_IE /* Enable interrupts for do_notify_resume() */ + move a0, sp /* pt_regs */ + move a1, s0 /* current_thread_info->flags */ +- tail do_notify_resume +-work_resched: +- tail schedule ++ call do_work_pending ++ j resume_userspace + + /* Slow paths for ptrace. */ + handle_syscall_trace_enter: +diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c +index 5c591123c4409..bfb2afa4135f8 100644 +--- a/arch/riscv/kernel/signal.c ++++ b/arch/riscv/kernel/signal.c +@@ -313,19 +313,27 @@ static void do_signal(struct pt_regs *regs) + } + + /* +- * notification of userspace execution resumption +- * - triggered by the _TIF_WORK_MASK flags ++ * Handle any pending work on the resume-to-userspace path, as indicated by ++ * _TIF_WORK_MASK. Entered from assembly with IRQs off. + */ +-asmlinkage __visible void do_notify_resume(struct pt_regs *regs, +- unsigned long thread_info_flags) ++asmlinkage __visible void do_work_pending(struct pt_regs *regs, ++ unsigned long thread_info_flags) + { +- if (thread_info_flags & _TIF_UPROBE) +- uprobe_notify_resume(regs); +- +- /* Handle pending signal delivery */ +- if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) +- do_signal(regs); +- +- if (thread_info_flags & _TIF_NOTIFY_RESUME) +- resume_user_mode_work(regs); ++ do { ++ if (thread_info_flags & _TIF_NEED_RESCHED) { ++ schedule(); ++ } else { ++ local_irq_enable(); ++ if (thread_info_flags & _TIF_UPROBE) ++ uprobe_notify_resume(regs); ++ /* Handle pending signal delivery */ ++ if (thread_info_flags & (_TIF_SIGPENDING | ++ _TIF_NOTIFY_SIGNAL)) ++ do_signal(regs); ++ if (thread_info_flags & _TIF_NOTIFY_RESUME) ++ resume_user_mode_work(regs); ++ } ++ local_irq_disable(); ++ thread_info_flags = read_thread_flags(); ++ } while (thread_info_flags & _TIF_WORK_MASK); + } +diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c +index 6e8822446069e..026b458331582 100644 +--- a/arch/riscv/kernel/traps.c ++++ b/arch/riscv/kernel/traps.c +@@ -211,7 +211,7 @@ static DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], + * shadow stack, handled_ kernel_ stack_ overflow(in kernel/entry.S) is used + * to get per-cpu overflow stack(get_overflow_stack). + */ +-long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)]; ++long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)] __aligned(16); + asmlinkage unsigned long get_overflow_stack(void) + { + return (unsigned long)this_cpu_ptr(overflow_stack) + +diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c +index f692c0716aa7a..aa7ae63270449 100644 +--- a/arch/riscv/kvm/vcpu.c ++++ b/arch/riscv/kvm/vcpu.c +@@ -286,12 +286,15 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu, + if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id))) + return -EFAULT; + +- /* This ONE REG interface is only defined for single letter extensions */ +- if (fls(reg_val) >= RISCV_ISA_EXT_BASE) +- return -EINVAL; +- + switch (reg_num) { + case KVM_REG_RISCV_CONFIG_REG(isa): ++ /* ++ * This ONE REG interface is only defined for ++ * single letter extensions. ++ */ ++ if (fls(reg_val) >= RISCV_ISA_EXT_BASE) ++ return -EINVAL; ++ + if (!vcpu->arch.ran_atleast_once) { + /* Ignore the enable/disable request for certain extensions */ + for (i = 0; i < RISCV_ISA_EXT_BASE; i++) { +diff --git a/arch/riscv/mm/physaddr.c b/arch/riscv/mm/physaddr.c +index 19cf25a74ee29..9b18bda74154e 100644 +--- a/arch/riscv/mm/physaddr.c ++++ b/arch/riscv/mm/physaddr.c +@@ -22,7 +22,7 @@ EXPORT_SYMBOL(__virt_to_phys); + phys_addr_t __phys_addr_symbol(unsigned long x) + { + unsigned long kernel_start = kernel_map.virt_addr; +- unsigned long kernel_end = (unsigned long)_end; ++ unsigned long kernel_end = kernel_start + kernel_map.size; + + /* + * Boundary checking aginst the kernel image mapping. +diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c +index 00df3a8f92acd..f2417ac54edd6 100644 +--- a/arch/riscv/net/bpf_jit_comp64.c ++++ b/arch/riscv/net/bpf_jit_comp64.c +@@ -136,6 +136,25 @@ static bool in_auipc_jalr_range(s64 val) + val < ((1L << 31) - (1L << 11)); + } + ++/* Emit fixed-length instructions for address */ ++static int emit_addr(u8 rd, u64 addr, bool extra_pass, struct rv_jit_context *ctx) ++{ ++ u64 ip = (u64)(ctx->insns + ctx->ninsns); ++ s64 off = addr - ip; ++ s64 upper = (off + (1 << 11)) >> 12; ++ s64 lower = off & 0xfff; ++ ++ if (extra_pass && !in_auipc_jalr_range(off)) { ++ pr_err("bpf-jit: target offset 0x%llx is out of range\n", off); ++ return -ERANGE; ++ } ++ ++ emit(rv_auipc(rd, upper), ctx); ++ emit(rv_addi(rd, rd, lower), ctx); ++ return 0; ++} ++ ++/* Emit variable-length instructions for 32-bit and 64-bit imm */ + static void emit_imm(u8 rd, s64 val, struct rv_jit_context *ctx) + { + /* Note that the immediate from the add is sign-extended, +@@ -1050,7 +1069,15 @@ out_be: + u64 imm64; + + imm64 = (u64)insn1.imm << 32 | (u32)imm; +- emit_imm(rd, imm64, ctx); ++ if (bpf_pseudo_func(insn)) { ++ /* fixed-length insns for extra jit pass */ ++ ret = emit_addr(rd, imm64, extra_pass, ctx); ++ if (ret) ++ return ret; ++ } else { ++ emit_imm(rd, imm64, ctx); ++ } ++ + return 1; + } + +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index 4728d3f5d5c40..3fec0e9d92410 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -450,8 +450,8 @@ config X86_X2APIC + + Some Intel systems circa 2022 and later are locked into x2APIC mode + and can not fall back to the legacy APIC modes if SGX or TDX are +- enabled in the BIOS. They will be unable to boot without enabling +- this option. ++ enabled in the BIOS. They will boot with very reduced functionality ++ without enabling this option. + + If you don't know what to do here, say N. + +diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c +index 1ef4f7861e2ec..1f4869227efb9 100644 +--- a/arch/x86/events/intel/uncore_snb.c ++++ b/arch/x86/events/intel/uncore_snb.c +@@ -1338,6 +1338,7 @@ static void __uncore_imc_init_box(struct intel_uncore_box *box, + /* MCHBAR is disabled */ + if (!(mch_bar & BIT(0))) { + pr_warn("perf uncore: MCHBAR is disabled. Failed to map IMC free-running counters.\n"); ++ pci_dev_put(pdev); + return; + } + mch_bar &= ~BIT(0); +@@ -1352,6 +1353,8 @@ static void __uncore_imc_init_box(struct intel_uncore_box *box, + box->io_addr = ioremap(addr, type->mmio_map_size); + if (!box->io_addr) + pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name); ++ ++ pci_dev_put(pdev); + } + + static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box) +diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c +index ed869443efb21..fcd95e93f479a 100644 +--- a/arch/x86/events/intel/uncore_snbep.c ++++ b/arch/x86/events/intel/uncore_snbep.c +@@ -2891,6 +2891,7 @@ static bool hswep_has_limit_sbox(unsigned int device) + return false; + + pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4); ++ pci_dev_put(dev); + if (!hswep_get_chop(capid4)) + return true; + +@@ -4492,6 +4493,8 @@ static int sad_cfg_iio_topology(struct intel_uncore_type *type, u8 *sad_pmon_map + type->topology = NULL; + } + ++ pci_dev_put(dev); ++ + return ret; + } + +@@ -4857,6 +4860,8 @@ static int snr_uncore_mmio_map(struct intel_uncore_box *box, + + addr += box_ctl; + ++ pci_dev_put(pdev); ++ + box->io_addr = ioremap(addr, type->mmio_map_size); + if (!box->io_addr) { + pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name); +diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c +index a0165df3c4d8c..d03561b2fffe6 100644 +--- a/arch/x86/hyperv/hv_init.c ++++ b/arch/x86/hyperv/hv_init.c +@@ -536,8 +536,6 @@ void hyperv_cleanup(void) + { + union hv_x64_msr_hypercall_contents hypercall_msr; + +- unregister_syscore_ops(&hv_syscore_ops); +- + /* Reset our OS id */ + wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); + hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, 0); +diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h +index 3415321c8240c..3216da7074bad 100644 +--- a/arch/x86/include/asm/apic.h ++++ b/arch/x86/include/asm/apic.h +@@ -249,7 +249,6 @@ static inline u64 native_x2apic_icr_read(void) + extern int x2apic_mode; + extern int x2apic_phys; + extern void __init x2apic_set_max_apicid(u32 apicid); +-extern void __init check_x2apic(void); + extern void x2apic_setup(void); + static inline int x2apic_enabled(void) + { +@@ -258,13 +257,13 @@ static inline int x2apic_enabled(void) + + #define x2apic_supported() (boot_cpu_has(X86_FEATURE_X2APIC)) + #else /* !CONFIG_X86_X2APIC */ +-static inline void check_x2apic(void) { } + static inline void x2apic_setup(void) { } + static inline int x2apic_enabled(void) { return 0; } + + #define x2apic_mode (0) + #define x2apic_supported() (0) + #endif /* !CONFIG_X86_X2APIC */ ++extern void __init check_x2apic(void); + + struct irq_data; + +diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h +index fd6f6e5b755a7..a336feef0af14 100644 +--- a/arch/x86/include/asm/realmode.h ++++ b/arch/x86/include/asm/realmode.h +@@ -91,6 +91,7 @@ static inline void set_real_mode_mem(phys_addr_t mem) + + void reserve_real_mode(void); + void load_trampoline_pgtable(void); ++void init_real_mode(void); + + #endif /* __ASSEMBLY__ */ + +diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h +index e9170457697e4..c1c8c581759d6 100644 +--- a/arch/x86/include/asm/x86_init.h ++++ b/arch/x86/include/asm/x86_init.h +@@ -285,6 +285,8 @@ struct x86_hyper_runtime { + * possible in x86_early_init_platform_quirks() by + * only using the current x86_hardware_subarch + * semantics. ++ * @realmode_reserve: reserve memory for realmode trampoline ++ * @realmode_init: initialize realmode trampoline + * @hyper: x86 hypervisor specific runtime callbacks + */ + struct x86_platform_ops { +@@ -301,6 +303,8 @@ struct x86_platform_ops { + void (*apic_post_init)(void); + struct x86_legacy_features legacy; + void (*set_legacy_features)(void); ++ void (*realmode_reserve)(void); ++ void (*realmode_init)(void); + struct x86_hyper_runtime hyper; + struct x86_guest guest; + }; +diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c +index c6876d3ea4b17..20d9a604da7c4 100644 +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -1931,16 +1931,19 @@ void __init check_x2apic(void) + } + } + #else /* CONFIG_X86_X2APIC */ +-static int __init validate_x2apic(void) ++void __init check_x2apic(void) + { + if (!apic_is_x2apic_enabled()) +- return 0; ++ return; + /* +- * Checkme: Can we simply turn off x2apic here instead of panic? ++ * Checkme: Can we simply turn off x2APIC here instead of disabling the APIC? + */ +- panic("BIOS has enabled x2apic but kernel doesn't support x2apic, please disable x2apic in BIOS.\n"); ++ pr_err("Kernel does not support x2APIC, please recompile with CONFIG_X86_X2APIC.\n"); ++ pr_err("Disabling APIC, expect reduced performance and functionality.\n"); ++ ++ disable_apic = 1; ++ setup_clear_cpu_cap(X86_FEATURE_APIC); + } +-early_initcall(validate_x2apic); + + static inline void try_to_enable_x2apic(int remap_mode) { } + static inline void __x2apic_enable(void) { } +diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c +index 2d7ea5480ec33..4278996504833 100644 +--- a/arch/x86/kernel/cpu/intel.c ++++ b/arch/x86/kernel/cpu/intel.c +@@ -1034,8 +1034,32 @@ static const struct { + + static struct ratelimit_state bld_ratelimit; + ++static unsigned int sysctl_sld_mitigate = 1; + static DEFINE_SEMAPHORE(buslock_sem); + ++#ifdef CONFIG_PROC_SYSCTL ++static struct ctl_table sld_sysctls[] = { ++ { ++ .procname = "split_lock_mitigate", ++ .data = &sysctl_sld_mitigate, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0644, ++ .proc_handler = proc_douintvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE, ++ }, ++ {} ++}; ++ ++static int __init sld_mitigate_sysctl_init(void) ++{ ++ register_sysctl_init("kernel", sld_sysctls); ++ return 0; ++} ++ ++late_initcall(sld_mitigate_sysctl_init); ++#endif ++ + static inline bool match_option(const char *arg, int arglen, const char *opt) + { + int len = strlen(opt), ratelimit; +@@ -1146,12 +1170,20 @@ static void split_lock_init(void) + split_lock_verify_msr(sld_state != sld_off); + } + +-static void __split_lock_reenable(struct work_struct *work) ++static void __split_lock_reenable_unlock(struct work_struct *work) + { + sld_update_msr(true); + up(&buslock_sem); + } + ++static DECLARE_DELAYED_WORK(sl_reenable_unlock, __split_lock_reenable_unlock); ++ ++static void __split_lock_reenable(struct work_struct *work) ++{ ++ sld_update_msr(true); ++} ++static DECLARE_DELAYED_WORK(sl_reenable, __split_lock_reenable); ++ + /* + * If a CPU goes offline with pending delayed work to re-enable split lock + * detection then the delayed work will be executed on some other CPU. That +@@ -1169,10 +1201,9 @@ static int splitlock_cpu_offline(unsigned int cpu) + return 0; + } + +-static DECLARE_DELAYED_WORK(split_lock_reenable, __split_lock_reenable); +- + static void split_lock_warn(unsigned long ip) + { ++ struct delayed_work *work; + int cpu; + + if (!current->reported_split_lock) +@@ -1180,14 +1211,26 @@ static void split_lock_warn(unsigned long ip) + current->comm, current->pid, ip); + current->reported_split_lock = 1; + +- /* misery factor #1, sleep 10ms before trying to execute split lock */ +- if (msleep_interruptible(10) > 0) +- return; +- /* Misery factor #2, only allow one buslocked disabled core at a time */ +- if (down_interruptible(&buslock_sem) == -EINTR) +- return; ++ if (sysctl_sld_mitigate) { ++ /* ++ * misery factor #1: ++ * sleep 10ms before trying to execute split lock. ++ */ ++ if (msleep_interruptible(10) > 0) ++ return; ++ /* ++ * Misery factor #2: ++ * only allow one buslocked disabled core at a time. ++ */ ++ if (down_interruptible(&buslock_sem) == -EINTR) ++ return; ++ work = &sl_reenable_unlock; ++ } else { ++ work = &sl_reenable; ++ } ++ + cpu = get_cpu(); +- schedule_delayed_work_on(cpu, &split_lock_reenable, 2); ++ schedule_delayed_work_on(cpu, work, 2); + + /* Disable split lock detection on this CPU to make progress */ + sld_update_msr(false); +diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c +index 8bdeae2fc3091..6942a3d8b578c 100644 +--- a/arch/x86/kernel/cpu/sgx/encl.c ++++ b/arch/x86/kernel/cpu/sgx/encl.c +@@ -677,11 +677,15 @@ const struct vm_operations_struct sgx_vm_ops = { + void sgx_encl_release(struct kref *ref) + { + struct sgx_encl *encl = container_of(ref, struct sgx_encl, refcount); ++ unsigned long max_page_index = PFN_DOWN(encl->base + encl->size - 1); + struct sgx_va_page *va_page; + struct sgx_encl_page *entry; +- unsigned long index; ++ unsigned long count = 0; ++ ++ XA_STATE(xas, &encl->page_array, PFN_DOWN(encl->base)); + +- xa_for_each(&encl->page_array, index, entry) { ++ xas_lock(&xas); ++ xas_for_each(&xas, entry, max_page_index) { + if (entry->epc_page) { + /* + * The page and its radix tree entry cannot be freed +@@ -696,9 +700,20 @@ void sgx_encl_release(struct kref *ref) + } + + kfree(entry); +- /* Invoke scheduler to prevent soft lockups. */ +- cond_resched(); ++ /* ++ * Invoke scheduler on every XA_CHECK_SCHED iteration ++ * to prevent soft lockups. ++ */ ++ if (!(++count % XA_CHECK_SCHED)) { ++ xas_pause(&xas); ++ xas_unlock(&xas); ++ ++ cond_resched(); ++ ++ xas_lock(&xas); ++ } + } ++ xas_unlock(&xas); + + xa_destroy(&encl->page_array); + +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index 216fee7144eef..892609cde4a20 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1175,7 +1175,7 @@ void __init setup_arch(char **cmdline_p) + * Moreover, on machines with SandyBridge graphics or in setups that use + * crashkernel the entire 1M is reserved anyway. + */ +- reserve_real_mode(); ++ x86_platform.realmode_reserve(); + + init_mem_mapping(); + +diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c +index b63cf8f7745ee..6c07f6daaa227 100644 +--- a/arch/x86/kernel/uprobes.c ++++ b/arch/x86/kernel/uprobes.c +@@ -722,8 +722,9 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn) + switch (opc1) { + case 0xeb: /* jmp 8 */ + case 0xe9: /* jmp 32 */ +- case 0x90: /* prefix* + nop; same as jmp with .offs = 0 */ + break; ++ case 0x90: /* prefix* + nop; same as jmp with .offs = 0 */ ++ goto setup; + + case 0xe8: /* call relative */ + branch_clear_offset(auprobe, insn); +@@ -753,6 +754,7 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn) + return -ENOTSUPP; + } + ++setup: + auprobe->branch.opc1 = opc1; + auprobe->branch.ilen = insn->length; + auprobe->branch.offs = insn->immediate.value; +diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c +index e84ee5cdbd8c6..3a164fb0d4c3e 100644 +--- a/arch/x86/kernel/x86_init.c ++++ b/arch/x86/kernel/x86_init.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + void x86_init_noop(void) { } + void __init x86_init_uint_noop(unsigned int unused) { } +@@ -145,6 +146,8 @@ struct x86_platform_ops x86_platform __ro_after_init = { + .get_nmi_reason = default_get_nmi_reason, + .save_sched_clock_state = tsc_save_sched_clock_state, + .restore_sched_clock_state = tsc_restore_sched_clock_state, ++ .realmode_reserve = reserve_real_mode, ++ .realmode_init = init_real_mode, + .hyper.pin_vcpu = x86_op_int_noop, + + .guest = { +diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c +index 41d7669a97ad1..af565816d2ba6 100644 +--- a/arch/x86/realmode/init.c ++++ b/arch/x86/realmode/init.c +@@ -200,14 +200,18 @@ static void __init set_real_mode_permissions(void) + set_memory_x((unsigned long) text_start, text_size >> PAGE_SHIFT); + } + +-static int __init init_real_mode(void) ++void __init init_real_mode(void) + { + if (!real_mode_header) + panic("Real mode trampoline was not allocated"); + + setup_real_mode(); + set_real_mode_permissions(); ++} + ++static int __init do_init_real_mode(void) ++{ ++ x86_platform.realmode_init(); + return 0; + } +-early_initcall(init_real_mode); ++early_initcall(do_init_real_mode); +diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c +index 9b1a58dda935b..807ab4fbe2c42 100644 +--- a/arch/x86/xen/enlighten_pv.c ++++ b/arch/x86/xen/enlighten_pv.c +@@ -1224,6 +1224,8 @@ asmlinkage __visible void __init xen_start_kernel(struct start_info *si) + xen_vcpu_info_reset(0); + + x86_platform.get_nmi_reason = xen_get_nmi_reason; ++ x86_platform.realmode_reserve = x86_init_noop; ++ x86_platform.realmode_init = x86_init_noop; + + x86_init.resources.memory_setup = xen_memory_setup; + x86_init.irqs.intr_mode_select = x86_init_noop; +diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c +index c3e1f9a7d43aa..4b0d6fff88de5 100644 +--- a/arch/x86/xen/smp.c ++++ b/arch/x86/xen/smp.c +@@ -32,30 +32,30 @@ static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) + + void xen_smp_intr_free(unsigned int cpu) + { ++ kfree(per_cpu(xen_resched_irq, cpu).name); ++ per_cpu(xen_resched_irq, cpu).name = NULL; + if (per_cpu(xen_resched_irq, cpu).irq >= 0) { + unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu).irq, NULL); + per_cpu(xen_resched_irq, cpu).irq = -1; +- kfree(per_cpu(xen_resched_irq, cpu).name); +- per_cpu(xen_resched_irq, cpu).name = NULL; + } ++ kfree(per_cpu(xen_callfunc_irq, cpu).name); ++ per_cpu(xen_callfunc_irq, cpu).name = NULL; + if (per_cpu(xen_callfunc_irq, cpu).irq >= 0) { + unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu).irq, NULL); + per_cpu(xen_callfunc_irq, cpu).irq = -1; +- kfree(per_cpu(xen_callfunc_irq, cpu).name); +- per_cpu(xen_callfunc_irq, cpu).name = NULL; + } ++ kfree(per_cpu(xen_debug_irq, cpu).name); ++ per_cpu(xen_debug_irq, cpu).name = NULL; + if (per_cpu(xen_debug_irq, cpu).irq >= 0) { + unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu).irq, NULL); + per_cpu(xen_debug_irq, cpu).irq = -1; +- kfree(per_cpu(xen_debug_irq, cpu).name); +- per_cpu(xen_debug_irq, cpu).name = NULL; + } ++ kfree(per_cpu(xen_callfuncsingle_irq, cpu).name); ++ per_cpu(xen_callfuncsingle_irq, cpu).name = NULL; + if (per_cpu(xen_callfuncsingle_irq, cpu).irq >= 0) { + unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu).irq, + NULL); + per_cpu(xen_callfuncsingle_irq, cpu).irq = -1; +- kfree(per_cpu(xen_callfuncsingle_irq, cpu).name); +- per_cpu(xen_callfuncsingle_irq, cpu).name = NULL; + } + } + +@@ -65,6 +65,7 @@ int xen_smp_intr_init(unsigned int cpu) + char *resched_name, *callfunc_name, *debug_name; + + resched_name = kasprintf(GFP_KERNEL, "resched%d", cpu); ++ per_cpu(xen_resched_irq, cpu).name = resched_name; + rc = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR, + cpu, + xen_reschedule_interrupt, +@@ -74,9 +75,9 @@ int xen_smp_intr_init(unsigned int cpu) + if (rc < 0) + goto fail; + per_cpu(xen_resched_irq, cpu).irq = rc; +- per_cpu(xen_resched_irq, cpu).name = resched_name; + + callfunc_name = kasprintf(GFP_KERNEL, "callfunc%d", cpu); ++ per_cpu(xen_callfunc_irq, cpu).name = callfunc_name; + rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR, + cpu, + xen_call_function_interrupt, +@@ -86,10 +87,10 @@ int xen_smp_intr_init(unsigned int cpu) + if (rc < 0) + goto fail; + per_cpu(xen_callfunc_irq, cpu).irq = rc; +- per_cpu(xen_callfunc_irq, cpu).name = callfunc_name; + + if (!xen_fifo_events) { + debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu); ++ per_cpu(xen_debug_irq, cpu).name = debug_name; + rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu, + xen_debug_interrupt, + IRQF_PERCPU | IRQF_NOBALANCING, +@@ -97,10 +98,10 @@ int xen_smp_intr_init(unsigned int cpu) + if (rc < 0) + goto fail; + per_cpu(xen_debug_irq, cpu).irq = rc; +- per_cpu(xen_debug_irq, cpu).name = debug_name; + } + + callfunc_name = kasprintf(GFP_KERNEL, "callfuncsingle%d", cpu); ++ per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name; + rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR, + cpu, + xen_call_function_single_interrupt, +@@ -110,7 +111,6 @@ int xen_smp_intr_init(unsigned int cpu) + if (rc < 0) + goto fail; + per_cpu(xen_callfuncsingle_irq, cpu).irq = rc; +- per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name; + + return 0; + +diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c +index ba7af2eca755b..cd80f8422e173 100644 +--- a/arch/x86/xen/smp_pv.c ++++ b/arch/x86/xen/smp_pv.c +@@ -97,18 +97,18 @@ asmlinkage __visible void cpu_bringup_and_idle(void) + + void xen_smp_intr_free_pv(unsigned int cpu) + { ++ kfree(per_cpu(xen_irq_work, cpu).name); ++ per_cpu(xen_irq_work, cpu).name = NULL; + if (per_cpu(xen_irq_work, cpu).irq >= 0) { + unbind_from_irqhandler(per_cpu(xen_irq_work, cpu).irq, NULL); + per_cpu(xen_irq_work, cpu).irq = -1; +- kfree(per_cpu(xen_irq_work, cpu).name); +- per_cpu(xen_irq_work, cpu).name = NULL; + } + ++ kfree(per_cpu(xen_pmu_irq, cpu).name); ++ per_cpu(xen_pmu_irq, cpu).name = NULL; + if (per_cpu(xen_pmu_irq, cpu).irq >= 0) { + unbind_from_irqhandler(per_cpu(xen_pmu_irq, cpu).irq, NULL); + per_cpu(xen_pmu_irq, cpu).irq = -1; +- kfree(per_cpu(xen_pmu_irq, cpu).name); +- per_cpu(xen_pmu_irq, cpu).name = NULL; + } + } + +@@ -118,6 +118,7 @@ int xen_smp_intr_init_pv(unsigned int cpu) + char *callfunc_name, *pmu_name; + + callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu); ++ per_cpu(xen_irq_work, cpu).name = callfunc_name; + rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, + cpu, + xen_irq_work_interrupt, +@@ -127,10 +128,10 @@ int xen_smp_intr_init_pv(unsigned int cpu) + if (rc < 0) + goto fail; + per_cpu(xen_irq_work, cpu).irq = rc; +- per_cpu(xen_irq_work, cpu).name = callfunc_name; + + if (is_xen_pmu) { + pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu); ++ per_cpu(xen_pmu_irq, cpu).name = pmu_name; + rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu, + xen_pmu_irq_handler, + IRQF_PERCPU|IRQF_NOBALANCING, +@@ -138,7 +139,6 @@ int xen_smp_intr_init_pv(unsigned int cpu) + if (rc < 0) + goto fail; + per_cpu(xen_pmu_irq, cpu).irq = rc; +- per_cpu(xen_pmu_irq, cpu).name = pmu_name; + } + + return 0; +diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c +index 043c73dfd2c98..5c6fc16e4b925 100644 +--- a/arch/x86/xen/spinlock.c ++++ b/arch/x86/xen/spinlock.c +@@ -75,6 +75,7 @@ void xen_init_lock_cpu(int cpu) + cpu, per_cpu(lock_kicker_irq, cpu)); + + name = kasprintf(GFP_KERNEL, "spinlock%d", cpu); ++ per_cpu(irq_name, cpu) = name; + irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR, + cpu, + dummy_handler, +@@ -85,7 +86,6 @@ void xen_init_lock_cpu(int cpu) + if (irq >= 0) { + disable_irq(irq); /* make sure it's never delivered */ + per_cpu(lock_kicker_irq, cpu) = irq; +- per_cpu(irq_name, cpu) = name; + } + + printk("cpu %d spinlock event irq %d\n", cpu, irq); +@@ -98,6 +98,8 @@ void xen_uninit_lock_cpu(int cpu) + if (!xen_pvspin) + return; + ++ kfree(per_cpu(irq_name, cpu)); ++ per_cpu(irq_name, cpu) = NULL; + /* + * When booting the kernel with 'mitigations=auto,nosmt', the secondary + * CPUs are not activated, and lock_kicker_irq is not initialized. +@@ -108,8 +110,6 @@ void xen_uninit_lock_cpu(int cpu) + + unbind_from_irqhandler(irq, NULL); + per_cpu(lock_kicker_irq, cpu) = -1; +- kfree(per_cpu(irq_name, cpu)); +- per_cpu(irq_name, cpu) = NULL; + } + + PV_CALLEE_SAVE_REGS_THUNK(xen_vcpu_stolen); +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index c740b41fe0a49..528ca21044a57 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -386,6 +386,12 @@ static void bfq_put_stable_ref(struct bfq_queue *bfqq); + + void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, bool is_sync) + { ++ struct bfq_queue *old_bfqq = bic->bfqq[is_sync]; ++ ++ /* Clear bic pointer if bfqq is detached from this bic */ ++ if (old_bfqq && old_bfqq->bic == bic) ++ old_bfqq->bic = NULL; ++ + /* + * If bfqq != NULL, then a non-stable queue merge between + * bic->bfqq and bfqq is happening here. This causes troubles +@@ -5379,7 +5385,6 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync) + unsigned long flags; + + spin_lock_irqsave(&bfqd->lock, flags); +- bfqq->bic = NULL; + bfq_exit_bfqq(bfqd, bfqq); + bic_set_bfqq(bic, NULL, is_sync); + spin_unlock_irqrestore(&bfqd->lock, flags); +@@ -6786,6 +6791,12 @@ static struct bfq_queue *bfq_init_rq(struct request *rq) + bfqq = bfq_get_bfqq_handle_split(bfqd, bic, bio, + true, is_sync, + NULL); ++ if (unlikely(bfqq == &bfqd->oom_bfqq)) ++ bfqq_already_existing = true; ++ } else ++ bfqq_already_existing = true; ++ ++ if (!bfqq_already_existing) { + bfqq->waker_bfqq = old_bfqq->waker_bfqq; + bfqq->tentative_waker_bfqq = NULL; + +@@ -6799,8 +6810,7 @@ static struct bfq_queue *bfq_init_rq(struct request *rq) + if (bfqq->waker_bfqq) + hlist_add_head(&bfqq->woken_list_node, + &bfqq->waker_bfqq->woken_list); +- } else +- bfqq_already_existing = true; ++ } + } + } + +diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c +index 93997d297d427..4515288fbe351 100644 +--- a/block/blk-mq-sysfs.c ++++ b/block/blk-mq-sysfs.c +@@ -185,7 +185,7 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx) + { + struct request_queue *q = hctx->queue; + struct blk_mq_ctx *ctx; +- int i, ret; ++ int i, j, ret; + + if (!hctx->nr_ctx) + return 0; +@@ -197,9 +197,16 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx) + hctx_for_each_ctx(hctx, ctx, i) { + ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu); + if (ret) +- break; ++ goto out; + } + ++ return 0; ++out: ++ hctx_for_each_ctx(hctx, ctx, j) { ++ if (j < i) ++ kobject_del(&ctx->kobj); ++ } ++ kobject_del(&hctx->kobj); + return ret; + } + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 3f1f5e3e0951d..1a30f65802749 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -1442,7 +1442,13 @@ static void blk_mq_rq_timed_out(struct request *req) + blk_add_timer(req); + } + +-static bool blk_mq_req_expired(struct request *rq, unsigned long *next) ++struct blk_expired_data { ++ bool has_timedout_rq; ++ unsigned long next; ++ unsigned long timeout_start; ++}; ++ ++static bool blk_mq_req_expired(struct request *rq, struct blk_expired_data *expired) + { + unsigned long deadline; + +@@ -1452,13 +1458,13 @@ static bool blk_mq_req_expired(struct request *rq, unsigned long *next) + return false; + + deadline = READ_ONCE(rq->deadline); +- if (time_after_eq(jiffies, deadline)) ++ if (time_after_eq(expired->timeout_start, deadline)) + return true; + +- if (*next == 0) +- *next = deadline; +- else if (time_after(*next, deadline)) +- *next = deadline; ++ if (expired->next == 0) ++ expired->next = deadline; ++ else if (time_after(expired->next, deadline)) ++ expired->next = deadline; + return false; + } + +@@ -1472,7 +1478,7 @@ void blk_mq_put_rq_ref(struct request *rq) + + static bool blk_mq_check_expired(struct request *rq, void *priv) + { +- unsigned long *next = priv; ++ struct blk_expired_data *expired = priv; + + /* + * blk_mq_queue_tag_busy_iter() has locked the request, so it cannot +@@ -1481,7 +1487,18 @@ static bool blk_mq_check_expired(struct request *rq, void *priv) + * it was completed and reallocated as a new request after returning + * from blk_mq_check_expired(). + */ +- if (blk_mq_req_expired(rq, next)) ++ if (blk_mq_req_expired(rq, expired)) { ++ expired->has_timedout_rq = true; ++ return false; ++ } ++ return true; ++} ++ ++static bool blk_mq_handle_expired(struct request *rq, void *priv) ++{ ++ struct blk_expired_data *expired = priv; ++ ++ if (blk_mq_req_expired(rq, expired)) + blk_mq_rq_timed_out(rq); + return true; + } +@@ -1490,7 +1507,9 @@ static void blk_mq_timeout_work(struct work_struct *work) + { + struct request_queue *q = + container_of(work, struct request_queue, timeout_work); +- unsigned long next = 0; ++ struct blk_expired_data expired = { ++ .timeout_start = jiffies, ++ }; + struct blk_mq_hw_ctx *hctx; + unsigned long i; + +@@ -1510,10 +1529,23 @@ static void blk_mq_timeout_work(struct work_struct *work) + if (!percpu_ref_tryget(&q->q_usage_counter)) + return; + +- blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &next); ++ /* check if there is any timed-out request */ ++ blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &expired); ++ if (expired.has_timedout_rq) { ++ /* ++ * Before walking tags, we must ensure any submit started ++ * before the current time has finished. Since the submit ++ * uses srcu or rcu, wait for a synchronization point to ++ * ensure all running submits have finished ++ */ ++ blk_mq_wait_quiesce_done(q); ++ ++ expired.next = 0; ++ blk_mq_queue_tag_busy_iter(q, blk_mq_handle_expired, &expired); ++ } + +- if (next != 0) { +- mod_timer(&q->timeout, next); ++ if (expired.next != 0) { ++ mod_timer(&q->timeout, expired.next); + } else { + /* + * Request timeouts are handled as a forward rolling timer. If +diff --git a/block/genhd.c b/block/genhd.c +index 044ff97381e33..28654723bc2b2 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -522,6 +522,7 @@ out_unregister_queue: + rq_qos_exit(disk->queue); + out_put_slave_dir: + kobject_put(disk->slave_dir); ++ disk->slave_dir = NULL; + out_put_holder_dir: + kobject_put(disk->part0->bd_holder_dir); + out_del_integrity: +@@ -618,6 +619,7 @@ void del_gendisk(struct gendisk *disk) + + kobject_put(disk->part0->bd_holder_dir); + kobject_put(disk->slave_dir); ++ disk->slave_dir = NULL; + + part_stat_set_all(disk->part0, 0); + disk->part0->bd_stamp = 0; +diff --git a/crypto/cryptd.c b/crypto/cryptd.c +index 668095eca0faf..ca3a40fc7da91 100644 +--- a/crypto/cryptd.c ++++ b/crypto/cryptd.c +@@ -68,11 +68,12 @@ struct aead_instance_ctx { + + struct cryptd_skcipher_ctx { + refcount_t refcnt; +- struct crypto_sync_skcipher *child; ++ struct crypto_skcipher *child; + }; + + struct cryptd_skcipher_request_ctx { + crypto_completion_t complete; ++ struct skcipher_request req; + }; + + struct cryptd_hash_ctx { +@@ -227,13 +228,13 @@ static int cryptd_skcipher_setkey(struct crypto_skcipher *parent, + const u8 *key, unsigned int keylen) + { + struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(parent); +- struct crypto_sync_skcipher *child = ctx->child; ++ struct crypto_skcipher *child = ctx->child; + +- crypto_sync_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); +- crypto_sync_skcipher_set_flags(child, +- crypto_skcipher_get_flags(parent) & +- CRYPTO_TFM_REQ_MASK); +- return crypto_sync_skcipher_setkey(child, key, keylen); ++ crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); ++ crypto_skcipher_set_flags(child, ++ crypto_skcipher_get_flags(parent) & ++ CRYPTO_TFM_REQ_MASK); ++ return crypto_skcipher_setkey(child, key, keylen); + } + + static void cryptd_skcipher_complete(struct skcipher_request *req, int err) +@@ -258,13 +259,13 @@ static void cryptd_skcipher_encrypt(struct crypto_async_request *base, + struct cryptd_skcipher_request_ctx *rctx = skcipher_request_ctx(req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- struct crypto_sync_skcipher *child = ctx->child; +- SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, child); ++ struct skcipher_request *subreq = &rctx->req; ++ struct crypto_skcipher *child = ctx->child; + + if (unlikely(err == -EINPROGRESS)) + goto out; + +- skcipher_request_set_sync_tfm(subreq, child); ++ skcipher_request_set_tfm(subreq, child); + skcipher_request_set_callback(subreq, CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); + skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, +@@ -286,13 +287,13 @@ static void cryptd_skcipher_decrypt(struct crypto_async_request *base, + struct cryptd_skcipher_request_ctx *rctx = skcipher_request_ctx(req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- struct crypto_sync_skcipher *child = ctx->child; +- SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, child); ++ struct skcipher_request *subreq = &rctx->req; ++ struct crypto_skcipher *child = ctx->child; + + if (unlikely(err == -EINPROGRESS)) + goto out; + +- skcipher_request_set_sync_tfm(subreq, child); ++ skcipher_request_set_tfm(subreq, child); + skcipher_request_set_callback(subreq, CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); + skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, +@@ -343,9 +344,10 @@ static int cryptd_skcipher_init_tfm(struct crypto_skcipher *tfm) + if (IS_ERR(cipher)) + return PTR_ERR(cipher); + +- ctx->child = (struct crypto_sync_skcipher *)cipher; ++ ctx->child = cipher; + crypto_skcipher_set_reqsize( +- tfm, sizeof(struct cryptd_skcipher_request_ctx)); ++ tfm, sizeof(struct cryptd_skcipher_request_ctx) + ++ crypto_skcipher_reqsize(cipher)); + return 0; + } + +@@ -353,7 +355,7 @@ static void cryptd_skcipher_exit_tfm(struct crypto_skcipher *tfm) + { + struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); + +- crypto_free_sync_skcipher(ctx->child); ++ crypto_free_skcipher(ctx->child); + } + + static void cryptd_skcipher_free(struct skcipher_instance *inst) +@@ -931,7 +933,7 @@ struct crypto_skcipher *cryptd_skcipher_child(struct cryptd_skcipher *tfm) + { + struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(&tfm->base); + +- return &ctx->child->base; ++ return ctx->child; + } + EXPORT_SYMBOL_GPL(cryptd_skcipher_child); + +diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c +index 59eb8ec366643..bc57b182f3047 100644 +--- a/crypto/tcrypt.c ++++ b/crypto/tcrypt.c +@@ -1101,15 +1101,6 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs, + goto out_free_tfm; + } + +- +- for (i = 0; i < num_mb; ++i) +- if (testmgr_alloc_buf(data[i].xbuf)) { +- while (i--) +- testmgr_free_buf(data[i].xbuf); +- goto out_free_tfm; +- } +- +- + for (i = 0; i < num_mb; ++i) { + data[i].req = skcipher_request_alloc(tfm, GFP_KERNEL); + if (!data[i].req) { +@@ -1494,387 +1485,387 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) + } + + for (i = 1; i < 200; i++) +- ret += do_test(NULL, 0, 0, i, num_mb); ++ ret = min(ret, do_test(NULL, 0, 0, i, num_mb)); + break; + + case 1: +- ret += tcrypt_test("md5"); ++ ret = min(ret, tcrypt_test("md5")); + break; + + case 2: +- ret += tcrypt_test("sha1"); ++ ret = min(ret, tcrypt_test("sha1")); + break; + + case 3: +- ret += tcrypt_test("ecb(des)"); +- ret += tcrypt_test("cbc(des)"); +- ret += tcrypt_test("ctr(des)"); ++ ret = min(ret, tcrypt_test("ecb(des)")); ++ ret = min(ret, tcrypt_test("cbc(des)")); ++ ret = min(ret, tcrypt_test("ctr(des)")); + break; + + case 4: +- ret += tcrypt_test("ecb(des3_ede)"); +- ret += tcrypt_test("cbc(des3_ede)"); +- ret += tcrypt_test("ctr(des3_ede)"); ++ ret = min(ret, tcrypt_test("ecb(des3_ede)")); ++ ret = min(ret, tcrypt_test("cbc(des3_ede)")); ++ ret = min(ret, tcrypt_test("ctr(des3_ede)")); + break; + + case 5: +- ret += tcrypt_test("md4"); ++ ret = min(ret, tcrypt_test("md4")); + break; + + case 6: +- ret += tcrypt_test("sha256"); ++ ret = min(ret, tcrypt_test("sha256")); + break; + + case 7: +- ret += tcrypt_test("ecb(blowfish)"); +- ret += tcrypt_test("cbc(blowfish)"); +- ret += tcrypt_test("ctr(blowfish)"); ++ ret = min(ret, tcrypt_test("ecb(blowfish)")); ++ ret = min(ret, tcrypt_test("cbc(blowfish)")); ++ ret = min(ret, tcrypt_test("ctr(blowfish)")); + break; + + case 8: +- ret += tcrypt_test("ecb(twofish)"); +- ret += tcrypt_test("cbc(twofish)"); +- ret += tcrypt_test("ctr(twofish)"); +- ret += tcrypt_test("lrw(twofish)"); +- ret += tcrypt_test("xts(twofish)"); ++ ret = min(ret, tcrypt_test("ecb(twofish)")); ++ ret = min(ret, tcrypt_test("cbc(twofish)")); ++ ret = min(ret, tcrypt_test("ctr(twofish)")); ++ ret = min(ret, tcrypt_test("lrw(twofish)")); ++ ret = min(ret, tcrypt_test("xts(twofish)")); + break; + + case 9: +- ret += tcrypt_test("ecb(serpent)"); +- ret += tcrypt_test("cbc(serpent)"); +- ret += tcrypt_test("ctr(serpent)"); +- ret += tcrypt_test("lrw(serpent)"); +- ret += tcrypt_test("xts(serpent)"); ++ ret = min(ret, tcrypt_test("ecb(serpent)")); ++ ret = min(ret, tcrypt_test("cbc(serpent)")); ++ ret = min(ret, tcrypt_test("ctr(serpent)")); ++ ret = min(ret, tcrypt_test("lrw(serpent)")); ++ ret = min(ret, tcrypt_test("xts(serpent)")); + break; + + case 10: +- ret += tcrypt_test("ecb(aes)"); +- ret += tcrypt_test("cbc(aes)"); +- ret += tcrypt_test("lrw(aes)"); +- ret += tcrypt_test("xts(aes)"); +- ret += tcrypt_test("ctr(aes)"); +- ret += tcrypt_test("rfc3686(ctr(aes))"); +- ret += tcrypt_test("ofb(aes)"); +- ret += tcrypt_test("cfb(aes)"); +- ret += tcrypt_test("xctr(aes)"); ++ ret = min(ret, tcrypt_test("ecb(aes)")); ++ ret = min(ret, tcrypt_test("cbc(aes)")); ++ ret = min(ret, tcrypt_test("lrw(aes)")); ++ ret = min(ret, tcrypt_test("xts(aes)")); ++ ret = min(ret, tcrypt_test("ctr(aes)")); ++ ret = min(ret, tcrypt_test("rfc3686(ctr(aes))")); ++ ret = min(ret, tcrypt_test("ofb(aes)")); ++ ret = min(ret, tcrypt_test("cfb(aes)")); ++ ret = min(ret, tcrypt_test("xctr(aes)")); + break; + + case 11: +- ret += tcrypt_test("sha384"); ++ ret = min(ret, tcrypt_test("sha384")); + break; + + case 12: +- ret += tcrypt_test("sha512"); ++ ret = min(ret, tcrypt_test("sha512")); + break; + + case 13: +- ret += tcrypt_test("deflate"); ++ ret = min(ret, tcrypt_test("deflate")); + break; + + case 14: +- ret += tcrypt_test("ecb(cast5)"); +- ret += tcrypt_test("cbc(cast5)"); +- ret += tcrypt_test("ctr(cast5)"); ++ ret = min(ret, tcrypt_test("ecb(cast5)")); ++ ret = min(ret, tcrypt_test("cbc(cast5)")); ++ ret = min(ret, tcrypt_test("ctr(cast5)")); + break; + + case 15: +- ret += tcrypt_test("ecb(cast6)"); +- ret += tcrypt_test("cbc(cast6)"); +- ret += tcrypt_test("ctr(cast6)"); +- ret += tcrypt_test("lrw(cast6)"); +- ret += tcrypt_test("xts(cast6)"); ++ ret = min(ret, tcrypt_test("ecb(cast6)")); ++ ret = min(ret, tcrypt_test("cbc(cast6)")); ++ ret = min(ret, tcrypt_test("ctr(cast6)")); ++ ret = min(ret, tcrypt_test("lrw(cast6)")); ++ ret = min(ret, tcrypt_test("xts(cast6)")); + break; + + case 16: +- ret += tcrypt_test("ecb(arc4)"); ++ ret = min(ret, tcrypt_test("ecb(arc4)")); + break; + + case 17: +- ret += tcrypt_test("michael_mic"); ++ ret = min(ret, tcrypt_test("michael_mic")); + break; + + case 18: +- ret += tcrypt_test("crc32c"); ++ ret = min(ret, tcrypt_test("crc32c")); + break; + + case 19: +- ret += tcrypt_test("ecb(tea)"); ++ ret = min(ret, tcrypt_test("ecb(tea)")); + break; + + case 20: +- ret += tcrypt_test("ecb(xtea)"); ++ ret = min(ret, tcrypt_test("ecb(xtea)")); + break; + + case 21: +- ret += tcrypt_test("ecb(khazad)"); ++ ret = min(ret, tcrypt_test("ecb(khazad)")); + break; + + case 22: +- ret += tcrypt_test("wp512"); ++ ret = min(ret, tcrypt_test("wp512")); + break; + + case 23: +- ret += tcrypt_test("wp384"); ++ ret = min(ret, tcrypt_test("wp384")); + break; + + case 24: +- ret += tcrypt_test("wp256"); ++ ret = min(ret, tcrypt_test("wp256")); + break; + + case 26: +- ret += tcrypt_test("ecb(anubis)"); +- ret += tcrypt_test("cbc(anubis)"); ++ ret = min(ret, tcrypt_test("ecb(anubis)")); ++ ret = min(ret, tcrypt_test("cbc(anubis)")); + break; + + case 30: +- ret += tcrypt_test("ecb(xeta)"); ++ ret = min(ret, tcrypt_test("ecb(xeta)")); + break; + + case 31: +- ret += tcrypt_test("pcbc(fcrypt)"); ++ ret = min(ret, tcrypt_test("pcbc(fcrypt)")); + break; + + case 32: +- ret += tcrypt_test("ecb(camellia)"); +- ret += tcrypt_test("cbc(camellia)"); +- ret += tcrypt_test("ctr(camellia)"); +- ret += tcrypt_test("lrw(camellia)"); +- ret += tcrypt_test("xts(camellia)"); ++ ret = min(ret, tcrypt_test("ecb(camellia)")); ++ ret = min(ret, tcrypt_test("cbc(camellia)")); ++ ret = min(ret, tcrypt_test("ctr(camellia)")); ++ ret = min(ret, tcrypt_test("lrw(camellia)")); ++ ret = min(ret, tcrypt_test("xts(camellia)")); + break; + + case 33: +- ret += tcrypt_test("sha224"); ++ ret = min(ret, tcrypt_test("sha224")); + break; + + case 35: +- ret += tcrypt_test("gcm(aes)"); ++ ret = min(ret, tcrypt_test("gcm(aes)")); + break; + + case 36: +- ret += tcrypt_test("lzo"); ++ ret = min(ret, tcrypt_test("lzo")); + break; + + case 37: +- ret += tcrypt_test("ccm(aes)"); ++ ret = min(ret, tcrypt_test("ccm(aes)")); + break; + + case 38: +- ret += tcrypt_test("cts(cbc(aes))"); ++ ret = min(ret, tcrypt_test("cts(cbc(aes))")); + break; + + case 39: +- ret += tcrypt_test("xxhash64"); ++ ret = min(ret, tcrypt_test("xxhash64")); + break; + + case 40: +- ret += tcrypt_test("rmd160"); ++ ret = min(ret, tcrypt_test("rmd160")); + break; + + case 42: +- ret += tcrypt_test("blake2b-512"); ++ ret = min(ret, tcrypt_test("blake2b-512")); + break; + + case 43: +- ret += tcrypt_test("ecb(seed)"); ++ ret = min(ret, tcrypt_test("ecb(seed)")); + break; + + case 45: +- ret += tcrypt_test("rfc4309(ccm(aes))"); ++ ret = min(ret, tcrypt_test("rfc4309(ccm(aes))")); + break; + + case 46: +- ret += tcrypt_test("ghash"); ++ ret = min(ret, tcrypt_test("ghash")); + break; + + case 47: +- ret += tcrypt_test("crct10dif"); ++ ret = min(ret, tcrypt_test("crct10dif")); + break; + + case 48: +- ret += tcrypt_test("sha3-224"); ++ ret = min(ret, tcrypt_test("sha3-224")); + break; + + case 49: +- ret += tcrypt_test("sha3-256"); ++ ret = min(ret, tcrypt_test("sha3-256")); + break; + + case 50: +- ret += tcrypt_test("sha3-384"); ++ ret = min(ret, tcrypt_test("sha3-384")); + break; + + case 51: +- ret += tcrypt_test("sha3-512"); ++ ret = min(ret, tcrypt_test("sha3-512")); + break; + + case 52: +- ret += tcrypt_test("sm3"); ++ ret = min(ret, tcrypt_test("sm3")); + break; + + case 53: +- ret += tcrypt_test("streebog256"); ++ ret = min(ret, tcrypt_test("streebog256")); + break; + + case 54: +- ret += tcrypt_test("streebog512"); ++ ret = min(ret, tcrypt_test("streebog512")); + break; + + case 55: +- ret += tcrypt_test("gcm(sm4)"); ++ ret = min(ret, tcrypt_test("gcm(sm4)")); + break; + + case 56: +- ret += tcrypt_test("ccm(sm4)"); ++ ret = min(ret, tcrypt_test("ccm(sm4)")); + break; + + case 57: +- ret += tcrypt_test("polyval"); ++ ret = min(ret, tcrypt_test("polyval")); + break; + + case 58: +- ret += tcrypt_test("gcm(aria)"); ++ ret = min(ret, tcrypt_test("gcm(aria)")); + break; + + case 100: +- ret += tcrypt_test("hmac(md5)"); ++ ret = min(ret, tcrypt_test("hmac(md5)")); + break; + + case 101: +- ret += tcrypt_test("hmac(sha1)"); ++ ret = min(ret, tcrypt_test("hmac(sha1)")); + break; + + case 102: +- ret += tcrypt_test("hmac(sha256)"); ++ ret = min(ret, tcrypt_test("hmac(sha256)")); + break; + + case 103: +- ret += tcrypt_test("hmac(sha384)"); ++ ret = min(ret, tcrypt_test("hmac(sha384)")); + break; + + case 104: +- ret += tcrypt_test("hmac(sha512)"); ++ ret = min(ret, tcrypt_test("hmac(sha512)")); + break; + + case 105: +- ret += tcrypt_test("hmac(sha224)"); ++ ret = min(ret, tcrypt_test("hmac(sha224)")); + break; + + case 106: +- ret += tcrypt_test("xcbc(aes)"); ++ ret = min(ret, tcrypt_test("xcbc(aes)")); + break; + + case 108: +- ret += tcrypt_test("hmac(rmd160)"); ++ ret = min(ret, tcrypt_test("hmac(rmd160)")); + break; + + case 109: +- ret += tcrypt_test("vmac64(aes)"); ++ ret = min(ret, tcrypt_test("vmac64(aes)")); + break; + + case 111: +- ret += tcrypt_test("hmac(sha3-224)"); ++ ret = min(ret, tcrypt_test("hmac(sha3-224)")); + break; + + case 112: +- ret += tcrypt_test("hmac(sha3-256)"); ++ ret = min(ret, tcrypt_test("hmac(sha3-256)")); + break; + + case 113: +- ret += tcrypt_test("hmac(sha3-384)"); ++ ret = min(ret, tcrypt_test("hmac(sha3-384)")); + break; + + case 114: +- ret += tcrypt_test("hmac(sha3-512)"); ++ ret = min(ret, tcrypt_test("hmac(sha3-512)")); + break; + + case 115: +- ret += tcrypt_test("hmac(streebog256)"); ++ ret = min(ret, tcrypt_test("hmac(streebog256)")); + break; + + case 116: +- ret += tcrypt_test("hmac(streebog512)"); ++ ret = min(ret, tcrypt_test("hmac(streebog512)")); + break; + + case 150: +- ret += tcrypt_test("ansi_cprng"); ++ ret = min(ret, tcrypt_test("ansi_cprng")); + break; + + case 151: +- ret += tcrypt_test("rfc4106(gcm(aes))"); ++ ret = min(ret, tcrypt_test("rfc4106(gcm(aes))")); + break; + + case 152: +- ret += tcrypt_test("rfc4543(gcm(aes))"); ++ ret = min(ret, tcrypt_test("rfc4543(gcm(aes))")); + break; + + case 153: +- ret += tcrypt_test("cmac(aes)"); ++ ret = min(ret, tcrypt_test("cmac(aes)")); + break; + + case 154: +- ret += tcrypt_test("cmac(des3_ede)"); ++ ret = min(ret, tcrypt_test("cmac(des3_ede)")); + break; + + case 155: +- ret += tcrypt_test("authenc(hmac(sha1),cbc(aes))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(aes))")); + break; + + case 156: +- ret += tcrypt_test("authenc(hmac(md5),ecb(cipher_null))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(md5),ecb(cipher_null))")); + break; + + case 157: +- ret += tcrypt_test("authenc(hmac(sha1),ecb(cipher_null))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),ecb(cipher_null))")); + break; + + case 158: +- ret += tcrypt_test("cbcmac(sm4)"); ++ ret = min(ret, tcrypt_test("cbcmac(sm4)")); + break; + + case 159: +- ret += tcrypt_test("cmac(sm4)"); ++ ret = min(ret, tcrypt_test("cmac(sm4)")); + break; + + case 181: +- ret += tcrypt_test("authenc(hmac(sha1),cbc(des))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(des))")); + break; + case 182: +- ret += tcrypt_test("authenc(hmac(sha1),cbc(des3_ede))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(des3_ede))")); + break; + case 183: +- ret += tcrypt_test("authenc(hmac(sha224),cbc(des))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha224),cbc(des))")); + break; + case 184: +- ret += tcrypt_test("authenc(hmac(sha224),cbc(des3_ede))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha224),cbc(des3_ede))")); + break; + case 185: +- ret += tcrypt_test("authenc(hmac(sha256),cbc(des))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha256),cbc(des))")); + break; + case 186: +- ret += tcrypt_test("authenc(hmac(sha256),cbc(des3_ede))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha256),cbc(des3_ede))")); + break; + case 187: +- ret += tcrypt_test("authenc(hmac(sha384),cbc(des))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha384),cbc(des))")); + break; + case 188: +- ret += tcrypt_test("authenc(hmac(sha384),cbc(des3_ede))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha384),cbc(des3_ede))")); + break; + case 189: +- ret += tcrypt_test("authenc(hmac(sha512),cbc(des))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha512),cbc(des))")); + break; + case 190: +- ret += tcrypt_test("authenc(hmac(sha512),cbc(des3_ede))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha512),cbc(des3_ede))")); + break; + case 191: +- ret += tcrypt_test("ecb(sm4)"); +- ret += tcrypt_test("cbc(sm4)"); +- ret += tcrypt_test("cfb(sm4)"); +- ret += tcrypt_test("ctr(sm4)"); ++ ret = min(ret, tcrypt_test("ecb(sm4)")); ++ ret = min(ret, tcrypt_test("cbc(sm4)")); ++ ret = min(ret, tcrypt_test("cfb(sm4)")); ++ ret = min(ret, tcrypt_test("ctr(sm4)")); + break; + case 192: +- ret += tcrypt_test("ecb(aria)"); +- ret += tcrypt_test("cbc(aria)"); +- ret += tcrypt_test("cfb(aria)"); +- ret += tcrypt_test("ctr(aria)"); ++ ret = min(ret, tcrypt_test("ecb(aria)")); ++ ret = min(ret, tcrypt_test("cbc(aria)")); ++ ret = min(ret, tcrypt_test("cfb(aria)")); ++ ret = min(ret, tcrypt_test("ctr(aria)")); + break; + case 200: + test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, +diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c +index ae2e768830bfc..9332bc688713c 100644 +--- a/drivers/acpi/acpica/dsmethod.c ++++ b/drivers/acpi/acpica/dsmethod.c +@@ -517,7 +517,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, + info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); + if (!info) { + status = AE_NO_MEMORY; +- goto cleanup; ++ goto pop_walk_state; + } + + info->parameters = &this_walk_state->operands[0]; +@@ -529,7 +529,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, + + ACPI_FREE(info); + if (ACPI_FAILURE(status)) { +- goto cleanup; ++ goto pop_walk_state; + } + + next_walk_state->method_nesting_depth = +@@ -575,6 +575,12 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, + + return_ACPI_STATUS(status); + ++pop_walk_state: ++ ++ /* On error, pop the walk state to be deleted from thread */ ++ ++ acpi_ds_pop_walk_state(thread); ++ + cleanup: + + /* On error, we must terminate the method properly */ +diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c +index 400b9e15a709c..63c17f420fb86 100644 +--- a/drivers/acpi/acpica/utcopy.c ++++ b/drivers/acpi/acpica/utcopy.c +@@ -916,13 +916,6 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, + status = acpi_ut_walk_package_tree(source_obj, dest_obj, + acpi_ut_copy_ielement_to_ielement, + walk_state); +- if (ACPI_FAILURE(status)) { +- +- /* On failure, delete the destination package object */ +- +- acpi_ut_remove_reference(dest_obj); +- } +- + return_ACPI_STATUS(status); + } + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index c95e535035a04..fdc760e1e09ef 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -1879,6 +1879,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"), + }, + }, ++ { ++ /* ++ * HP Pavilion Gaming Laptop 15-cx0041ur ++ */ ++ .callback = ec_honor_dsdt_gpe, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "HP"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP 15-cx0041ur"), ++ }, ++ }, + { + /* + * Samsung hardware +diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c +index dabe45eba055d..0d9a17fdd83eb 100644 +--- a/drivers/acpi/irq.c ++++ b/drivers/acpi/irq.c +@@ -94,6 +94,7 @@ EXPORT_SYMBOL_GPL(acpi_unregister_gsi); + /** + * acpi_get_irq_source_fwhandle() - Retrieve fwhandle from IRQ resource source. + * @source: acpi_resource_source to use for the lookup. ++ * @gsi: GSI IRQ number + * + * Description: + * Retrieve the fwhandle of the device referenced by the given IRQ resource +@@ -295,8 +296,8 @@ EXPORT_SYMBOL_GPL(acpi_irq_get); + /** + * acpi_set_irq_model - Setup the GSI irqdomain information + * @model: the value assigned to acpi_irq_model +- * @fwnode: the irq_domain identifier for mapping and looking up +- * GSI interrupts ++ * @fn: a dispatcher function that will return the domain fwnode ++ * for a given GSI + */ + void __init acpi_set_irq_model(enum acpi_irq_model_id model, + struct fwnode_handle *(*fn)(u32)) +diff --git a/drivers/acpi/pfr_telemetry.c b/drivers/acpi/pfr_telemetry.c +index 9abf350bd7a5a..27fb6cdad75f9 100644 +--- a/drivers/acpi/pfr_telemetry.c ++++ b/drivers/acpi/pfr_telemetry.c +@@ -144,7 +144,7 @@ static int get_pfrt_log_data_info(struct pfrt_log_data_info *data_info, + ret = 0; + + free_acpi_buffer: +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +@@ -180,7 +180,7 @@ static int set_pfrt_log_level(int level, struct pfrt_log_device *pfrt_log_dev) + ret = -EBUSY; + } + +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +@@ -218,7 +218,7 @@ static int get_pfrt_log_level(struct pfrt_log_device *pfrt_log_dev) + ret = obj->integer.value; + + free_acpi_buffer: +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +diff --git a/drivers/acpi/pfr_update.c b/drivers/acpi/pfr_update.c +index 6bb0b778b5da5..9d2bdc13253a5 100644 +--- a/drivers/acpi/pfr_update.c ++++ b/drivers/acpi/pfr_update.c +@@ -178,7 +178,7 @@ static int query_capability(struct pfru_update_cap_info *cap_hdr, + ret = 0; + + free_acpi_buffer: +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +@@ -224,7 +224,7 @@ static int query_buffer(struct pfru_com_buf_info *info, + ret = 0; + + free_acpi_buffer: +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +@@ -385,7 +385,7 @@ static int start_update(int action, struct pfru_device *pfru_dev) + ret = 0; + + free_acpi_buffer: +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index 9f40917c49efb..4d1dd255c1228 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -1134,6 +1134,9 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr) + status = acpi_get_parent(handle, &pr_ahandle); + while (ACPI_SUCCESS(status)) { + d = acpi_fetch_acpi_dev(pr_ahandle); ++ if (!d) ++ break; ++ + handle = pr_ahandle; + + if (strcmp(acpi_device_hid(d), ACPI_PROCESSOR_CONTAINER_HID)) +diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c +index 950a93922ca8f..ae60e4aae0eec 100644 +--- a/drivers/acpi/x86/utils.c ++++ b/drivers/acpi/x86/utils.c +@@ -308,7 +308,7 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { + ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), + }, + { +- /* Lenovo Yoga Tablet 1050F/L */ ++ /* Lenovo Yoga Tablet 2 1050F/L */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."), + DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"), +@@ -319,6 +319,27 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { + .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | + ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), + }, ++ { ++ /* Lenovo Yoga Tab 3 Pro X90F */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), ++ }, ++ .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | ++ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), ++ }, ++ { ++ /* Medion Lifetab S10346 */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), ++ DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), ++ /* Way too generic, also match on BIOS data */ ++ DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"), ++ }, ++ .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | ++ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), ++ }, + { + /* Nextbook Ares 8 */ + .matches = { +@@ -348,6 +369,7 @@ static const struct acpi_device_id i2c_acpi_known_good_ids[] = { + { "10EC5640", 0 }, /* RealTek ALC5640 audio codec */ + { "INT33F4", 0 }, /* X-Powers AXP288 PMIC */ + { "INT33FD", 0 }, /* Intel Crystal Cove PMIC */ ++ { "INT34D3", 0 }, /* Intel Whiskey Cove PMIC */ + { "NPCE69A", 0 }, /* Asus Transformer keyboard dock */ + {} + }; +diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c +index 13b9d0fdd42c8..8e292e2abb046 100644 +--- a/drivers/ata/libata-sata.c ++++ b/drivers/ata/libata-sata.c +@@ -1392,7 +1392,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev, + tf->hob_lbah = buf[10]; + tf->nsect = buf[12]; + tf->hob_nsect = buf[13]; +- if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id)) ++ if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id) && ++ (tf->status & ATA_SENSE)) + tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16]; + + return 0; +@@ -1456,8 +1457,12 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) + memcpy(&qc->result_tf, &tf, sizeof(tf)); + qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; + qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; +- if (dev->class == ATA_DEV_ZAC && +- ((qc->result_tf.status & ATA_SENSE) || qc->result_tf.auxiliary)) { ++ ++ /* ++ * If the device supports NCQ autosense, ata_eh_read_log_10h() will have ++ * stored the sense data in qc->result_tf.auxiliary. ++ */ ++ if (qc->result_tf.auxiliary) { + char sense_key, asc, ascq; + + sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; +diff --git a/drivers/base/class.c b/drivers/base/class.c +index 8feb85e186e3b..e394e3e473b5d 100644 +--- a/drivers/base/class.c ++++ b/drivers/base/class.c +@@ -192,6 +192,11 @@ int __class_register(struct class *cls, struct lock_class_key *key) + } + error = class_add_groups(class_get(cls), cls->class_groups); + class_put(cls); ++ if (error) { ++ kobject_del(&cp->subsys.kobj); ++ kfree_const(cp->subsys.kobj.name); ++ kfree(cp); ++ } + return error; + } + EXPORT_SYMBOL_GPL(__class_register); +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index 997be3ac20a79..d36fb07190bf5 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -484,7 +484,17 @@ static int rpm_idle(struct device *dev, int rpmflags) + + dev->power.idle_notification = true; + +- retval = __rpm_callback(callback, dev); ++ if (dev->power.irq_safe) ++ spin_unlock(&dev->power.lock); ++ else ++ spin_unlock_irq(&dev->power.lock); ++ ++ retval = callback(dev); ++ ++ if (dev->power.irq_safe) ++ spin_lock(&dev->power.lock); ++ else ++ spin_lock_irq(&dev->power.lock); + + dev->power.idle_notification = false; + wake_up_all(&dev->power.wait_queue); +diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c +index 4ef9488d05cde..3de89795f5843 100644 +--- a/drivers/base/regmap/regmap-irq.c ++++ b/drivers/base/regmap/regmap-irq.c +@@ -722,6 +722,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, + int i; + int ret = -ENOMEM; + int num_type_reg; ++ int num_regs; + u32 reg; + + if (chip->num_regs <= 0) +@@ -796,14 +797,20 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, + goto err_alloc; + } + +- num_type_reg = chip->type_in_mask ? chip->num_regs : chip->num_type_reg; +- if (num_type_reg) { +- d->type_buf_def = kcalloc(num_type_reg, ++ /* ++ * Use num_config_regs if defined, otherwise fall back to num_type_reg ++ * to maintain backward compatibility. ++ */ ++ num_type_reg = chip->num_config_regs ? chip->num_config_regs ++ : chip->num_type_reg; ++ num_regs = chip->type_in_mask ? chip->num_regs : num_type_reg; ++ if (num_regs) { ++ d->type_buf_def = kcalloc(num_regs, + sizeof(*d->type_buf_def), GFP_KERNEL); + if (!d->type_buf_def) + goto err_alloc; + +- d->type_buf = kcalloc(num_type_reg, sizeof(*d->type_buf), ++ d->type_buf = kcalloc(num_regs, sizeof(*d->type_buf), + GFP_KERNEL); + if (!d->type_buf) + goto err_alloc; +diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c +index 8532b839a3435..6772402326842 100644 +--- a/drivers/block/drbd/drbd_main.c ++++ b/drivers/block/drbd/drbd_main.c +@@ -2217,7 +2217,8 @@ void drbd_destroy_device(struct kref *kref) + kref_put(&peer_device->connection->kref, drbd_destroy_connection); + kfree(peer_device); + } +- memset(device, 0xfd, sizeof(*device)); ++ if (device->submit.wq) ++ destroy_workqueue(device->submit.wq); + kfree(device); + kref_put(&resource->kref, drbd_destroy_resource); + } +@@ -2309,7 +2310,6 @@ void drbd_destroy_resource(struct kref *kref) + idr_destroy(&resource->devices); + free_cpumask_var(resource->cpu_mask); + kfree(resource->name); +- memset(resource, 0xf2, sizeof(*resource)); + kfree(resource); + } + +@@ -2650,7 +2650,6 @@ void drbd_destroy_connection(struct kref *kref) + drbd_free_socket(&connection->data); + kfree(connection->int_dig_in); + kfree(connection->int_dig_vv); +- memset(connection, 0xfc, sizeof(*connection)); + kfree(connection); + kref_put(&resource->kref, drbd_destroy_resource); + } +@@ -2774,7 +2773,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig + + err = add_disk(disk); + if (err) +- goto out_idr_remove_from_resource; ++ goto out_destroy_workqueue; + + /* inherit the connection state */ + device->state.conn = first_connection(resource)->cstate; +@@ -2788,6 +2787,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig + drbd_debugfs_device_add(device); + return NO_ERROR; + ++out_destroy_workqueue: ++ destroy_workqueue(device->submit.wq); + out_idr_remove_from_resource: + for_each_connection_safe(connection, n, resource) { + peer_device = idr_remove(&connection->peer_devices, vnr); +diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c +index 013d355a2033b..921c303a7b5c4 100644 +--- a/drivers/block/drbd/drbd_nl.c ++++ b/drivers/block/drbd/drbd_nl.c +@@ -1210,6 +1210,7 @@ static void decide_on_discard_support(struct drbd_device *device, + struct drbd_connection *connection = + first_peer_device(device)->connection; + struct request_queue *q = device->rq_queue; ++ unsigned int max_discard_sectors; + + if (bdev && !bdev_max_discard_sectors(bdev->backing_bdev)) + goto not_supported; +@@ -1230,15 +1231,14 @@ static void decide_on_discard_support(struct drbd_device *device, + * topology on all peers. + */ + blk_queue_discard_granularity(q, 512); +- q->limits.max_discard_sectors = drbd_max_discard_sectors(connection); +- q->limits.max_write_zeroes_sectors = +- drbd_max_discard_sectors(connection); ++ max_discard_sectors = drbd_max_discard_sectors(connection); ++ blk_queue_max_discard_sectors(q, max_discard_sectors); ++ blk_queue_max_write_zeroes_sectors(q, max_discard_sectors); + return; + + not_supported: + blk_queue_discard_granularity(q, 0); +- q->limits.max_discard_sectors = 0; +- q->limits.max_write_zeroes_sectors = 0; ++ blk_queue_max_discard_sectors(q, 0); + } + + static void fixup_write_zeroes(struct drbd_device *device, struct request_queue *q) +diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c +index ccad3d7b3ddd9..487840e3564df 100644 +--- a/drivers/block/floppy.c ++++ b/drivers/block/floppy.c +@@ -4593,8 +4593,10 @@ static int __init do_floppy_init(void) + goto out_put_disk; + + err = floppy_alloc_disk(drive, 0); +- if (err) ++ if (err) { ++ blk_mq_free_tag_set(&tag_sets[drive]); + goto out_put_disk; ++ } + + timer_setup(&motor_off_timer[drive], motor_off_callback, 0); + } +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index ad92192c7d617..d12d3d171ec4c 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -1773,7 +1773,16 @@ static const struct block_device_operations lo_fops = { + /* + * And now the modules code and kernel interface. + */ +-static int max_loop; ++ ++/* ++ * If max_loop is specified, create that many devices upfront. ++ * This also becomes a hard limit. If max_loop is not specified, ++ * create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module ++ * init time. Loop devices can be requested on-demand with the ++ * /dev/loop-control interface, or be instantiated by accessing ++ * a 'dead' device node. ++ */ ++static int max_loop = CONFIG_BLK_DEV_LOOP_MIN_COUNT; + module_param(max_loop, int, 0444); + MODULE_PARM_DESC(max_loop, "Maximum number of loop devices"); + module_param(max_part, int, 0444); +@@ -2181,7 +2190,7 @@ MODULE_ALIAS("devname:loop-control"); + + static int __init loop_init(void) + { +- int i, nr; ++ int i; + int err; + + part_shift = 0; +@@ -2209,19 +2218,6 @@ static int __init loop_init(void) + goto err_out; + } + +- /* +- * If max_loop is specified, create that many devices upfront. +- * This also becomes a hard limit. If max_loop is not specified, +- * create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module +- * init time. Loop devices can be requested on-demand with the +- * /dev/loop-control interface, or be instantiated by accessing +- * a 'dead' device node. +- */ +- if (max_loop) +- nr = max_loop; +- else +- nr = CONFIG_BLK_DEV_LOOP_MIN_COUNT; +- + err = misc_register(&loop_misc); + if (err < 0) + goto err_out; +@@ -2233,7 +2229,7 @@ static int __init loop_init(void) + } + + /* pre-create number of devices given by config or max_loop */ +- for (i = 0; i < nr; i++) ++ for (i = 0; i < max_loop; i++) + loop_add(i); + + printk(KERN_INFO "loop: module loaded\n"); +diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c +index d44a966675179..0c2542cee294b 100644 +--- a/drivers/bluetooth/btintel.c ++++ b/drivers/bluetooth/btintel.c +@@ -2522,7 +2522,7 @@ static int btintel_setup_combined(struct hci_dev *hdev) + */ + err = btintel_read_version(hdev, &ver); + if (err) +- return err; ++ break; + + /* Apply the device specific HCI quirks + * +@@ -2563,7 +2563,8 @@ static int btintel_setup_combined(struct hci_dev *hdev) + default: + bt_dev_err(hdev, "Unsupported Intel hw variant (%u)", + INTEL_HW_VARIANT(ver_tlv.cnvi_bt)); +- return -EINVAL; ++ err = -EINVAL; ++ break; + } + + exit_error: +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 882b5893f9108..a132e7aba6054 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -788,13 +788,13 @@ static inline void btusb_free_frags(struct btusb_data *data) + + spin_lock_irqsave(&data->rxlock, flags); + +- kfree_skb(data->evt_skb); ++ dev_kfree_skb_irq(data->evt_skb); + data->evt_skb = NULL; + +- kfree_skb(data->acl_skb); ++ dev_kfree_skb_irq(data->acl_skb); + data->acl_skb = NULL; + +- kfree_skb(data->sco_skb); ++ dev_kfree_skb_irq(data->sco_skb); + data->sco_skb = NULL; + + spin_unlock_irqrestore(&data->rxlock, flags); +diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c +index d7e0b75db8a60..2b6c0e1922cb3 100644 +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -53,11 +53,13 @@ + * struct bcm_device_data - device specific data + * @no_early_set_baudrate: Disallow set baudrate before driver setup() + * @drive_rts_on_open: drive RTS signal on ->open() when platform requires it ++ * @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable + * @max_autobaud_speed: max baudrate supported by device in autobaud mode + */ + struct bcm_device_data { + bool no_early_set_baudrate; + bool drive_rts_on_open; ++ bool no_uart_clock_set; + u32 max_autobaud_speed; + }; + +@@ -100,6 +102,7 @@ struct bcm_device_data { + * @is_suspended: whether flow control is currently disabled + * @no_early_set_baudrate: don't set_baudrate before setup() + * @drive_rts_on_open: drive RTS signal on ->open() when platform requires it ++ * @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable + * @pcm_int_params: keep the initial PCM configuration + * @use_autobaud_mode: start Bluetooth device in autobaud mode + * @max_autobaud_speed: max baudrate supported by device in autobaud mode +@@ -140,6 +143,7 @@ struct bcm_device { + #endif + bool no_early_set_baudrate; + bool drive_rts_on_open; ++ bool no_uart_clock_set; + bool use_autobaud_mode; + u8 pcm_int_params[5]; + u32 max_autobaud_speed; +@@ -172,10 +176,11 @@ static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed) + static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed) + { + struct hci_dev *hdev = hu->hdev; ++ struct bcm_data *bcm = hu->priv; + struct sk_buff *skb; + struct bcm_update_uart_baud_rate param; + +- if (speed > 3000000) { ++ if (speed > 3000000 && !bcm->dev->no_uart_clock_set) { + struct bcm_write_uart_clock_setting clock; + + clock.type = BCM_UART_CLOCK_48MHZ; +@@ -1529,6 +1534,7 @@ static int bcm_serdev_probe(struct serdev_device *serdev) + bcmdev->max_autobaud_speed = data->max_autobaud_speed; + bcmdev->no_early_set_baudrate = data->no_early_set_baudrate; + bcmdev->drive_rts_on_open = data->drive_rts_on_open; ++ bcmdev->no_uart_clock_set = data->no_uart_clock_set; + } + + return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto); +@@ -1550,6 +1556,10 @@ static struct bcm_device_data bcm43438_device_data = { + .drive_rts_on_open = true, + }; + ++static struct bcm_device_data cyw4373a0_device_data = { ++ .no_uart_clock_set = true, ++}; ++ + static struct bcm_device_data cyw55572_device_data = { + .max_autobaud_speed = 921600, + }; +@@ -1566,6 +1576,7 @@ static const struct of_device_id bcm_bluetooth_of_match[] = { + { .compatible = "brcm,bcm4349-bt", .data = &bcm43438_device_data }, + { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data }, + { .compatible = "brcm,bcm4335a0" }, ++ { .compatible = "cypress,cyw4373a0-bt", .data = &cyw4373a0_device_data }, + { .compatible = "infineon,cyw55572-bt", .data = &cyw55572_device_data }, + { }, + }; +diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c +index cf4a560958173..8055f63603f45 100644 +--- a/drivers/bluetooth/hci_bcsp.c ++++ b/drivers/bluetooth/hci_bcsp.c +@@ -378,7 +378,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) + i++; + + __skb_unlink(skb, &bcsp->unack); +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + } + + if (skb_queue_empty(&bcsp->unack)) +diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c +index c5a0409ef84fd..6455bc4fb5bb3 100644 +--- a/drivers/bluetooth/hci_h5.c ++++ b/drivers/bluetooth/hci_h5.c +@@ -313,7 +313,7 @@ static void h5_pkt_cull(struct h5 *h5) + break; + + __skb_unlink(skb, &h5->unack); +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + } + + if (skb_queue_empty(&h5->unack)) +diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c +index 4eb420a9ed04e..5abc01a2acf72 100644 +--- a/drivers/bluetooth/hci_ll.c ++++ b/drivers/bluetooth/hci_ll.c +@@ -345,7 +345,7 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb) + default: + BT_ERR("illegal hcill state: %ld (losing packet)", + ll->hcill_state); +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + break; + } + +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c +index 8df11016fd51b..bae9b2a408d95 100644 +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -912,7 +912,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb) + default: + BT_ERR("Illegal tx state: %d (losing packet)", + qca->tx_ibs_state); +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + break; + } + +diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c +index c22d4184bb612..0555e3838bce1 100644 +--- a/drivers/char/hw_random/amd-rng.c ++++ b/drivers/char/hw_random/amd-rng.c +@@ -143,15 +143,19 @@ static int __init amd_rng_mod_init(void) + found: + err = pci_read_config_dword(pdev, 0x58, &pmbase); + if (err) +- return err; ++ goto put_dev; + + pmbase &= 0x0000FF00; +- if (pmbase == 0) +- return -EIO; ++ if (pmbase == 0) { ++ err = -EIO; ++ goto put_dev; ++ } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); +- if (!priv) +- return -ENOMEM; ++ if (!priv) { ++ err = -ENOMEM; ++ goto put_dev; ++ } + + if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) { + dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n", +@@ -185,6 +189,8 @@ err_iomap: + release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE); + out: + kfree(priv); ++put_dev: ++ pci_dev_put(pdev); + return err; + } + +@@ -200,6 +206,8 @@ static void __exit amd_rng_mod_exit(void) + + release_region(priv->pmbase + PMBASE_OFFSET, PMBASE_SIZE); + ++ pci_dev_put(priv->pcidev); ++ + kfree(priv); + } + +diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c +index 138ce434f86b2..12fbe80918319 100644 +--- a/drivers/char/hw_random/geode-rng.c ++++ b/drivers/char/hw_random/geode-rng.c +@@ -51,6 +51,10 @@ static const struct pci_device_id pci_tbl[] = { + }; + MODULE_DEVICE_TABLE(pci, pci_tbl); + ++struct amd_geode_priv { ++ struct pci_dev *pcidev; ++ void __iomem *membase; ++}; + + static int geode_rng_data_read(struct hwrng *rng, u32 *data) + { +@@ -90,6 +94,7 @@ static int __init geode_rng_init(void) + const struct pci_device_id *ent; + void __iomem *mem; + unsigned long rng_base; ++ struct amd_geode_priv *priv; + + for_each_pci_dev(pdev) { + ent = pci_match_id(pci_tbl, pdev); +@@ -97,17 +102,26 @@ static int __init geode_rng_init(void) + goto found; + } + /* Device not found. */ +- goto out; ++ return err; + + found: ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) { ++ err = -ENOMEM; ++ goto put_dev; ++ } ++ + rng_base = pci_resource_start(pdev, 0); + if (rng_base == 0) +- goto out; ++ goto free_priv; + err = -ENOMEM; + mem = ioremap(rng_base, 0x58); + if (!mem) +- goto out; +- geode_rng.priv = (unsigned long)mem; ++ goto free_priv; ++ ++ geode_rng.priv = (unsigned long)priv; ++ priv->membase = mem; ++ priv->pcidev = pdev; + + pr_info("AMD Geode RNG detected\n"); + err = hwrng_register(&geode_rng); +@@ -116,20 +130,26 @@ found: + err); + goto err_unmap; + } +-out: + return err; + + err_unmap: + iounmap(mem); +- goto out; ++free_priv: ++ kfree(priv); ++put_dev: ++ pci_dev_put(pdev); ++ return err; + } + + static void __exit geode_rng_exit(void) + { +- void __iomem *mem = (void __iomem *)geode_rng.priv; ++ struct amd_geode_priv *priv; + ++ priv = (struct amd_geode_priv *)geode_rng.priv; + hwrng_unregister(&geode_rng); +- iounmap(mem); ++ iounmap(priv->membase); ++ pci_dev_put(priv->pcidev); ++ kfree(priv); + } + + module_init(geode_rng_init); +diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c +index 703433493c852..c9e32d100b7eb 100644 +--- a/drivers/char/ipmi/ipmi_msghandler.c ++++ b/drivers/char/ipmi/ipmi_msghandler.c +@@ -3710,12 +3710,16 @@ static void deliver_smi_err_response(struct ipmi_smi *intf, + struct ipmi_smi_msg *msg, + unsigned char err) + { ++ int rv; + msg->rsp[0] = msg->data[0] | 4; + msg->rsp[1] = msg->data[1]; + msg->rsp[2] = err; + msg->rsp_size = 3; +- /* It's an error, so it will never requeue, no need to check return. */ +- handle_one_recv_msg(intf, msg); ++ ++ /* This will never requeue, but it may ask us to free the message. */ ++ rv = handle_one_recv_msg(intf, msg); ++ if (rv == 0) ++ ipmi_free_smi_msg(msg); + } + + static void cleanup_smi_msgs(struct ipmi_smi *intf) +diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c +index cdc88cde1e9aa..417e5a3ccfaeb 100644 +--- a/drivers/char/ipmi/kcs_bmc_aspeed.c ++++ b/drivers/char/ipmi/kcs_bmc_aspeed.c +@@ -399,13 +399,31 @@ static void aspeed_kcs_check_obe(struct timer_list *timer) + static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 state) + { + struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc); ++ int rc; ++ u8 str; + + /* We don't have an OBE IRQ, emulate it */ + if (mask & KCS_BMC_EVENT_TYPE_OBE) { +- if (KCS_BMC_EVENT_TYPE_OBE & state) +- mod_timer(&priv->obe.timer, jiffies + OBE_POLL_PERIOD); +- else ++ if (KCS_BMC_EVENT_TYPE_OBE & state) { ++ /* ++ * Given we don't have an OBE IRQ, delay by polling briefly to see if we can ++ * observe such an event before returning to the caller. This is not ++ * incorrect because OBF may have already become clear before enabling the ++ * IRQ if we had one, under which circumstance no event will be propagated ++ * anyway. ++ * ++ * The onus is on the client to perform a race-free check that it hasn't ++ * missed the event. ++ */ ++ rc = read_poll_timeout_atomic(aspeed_kcs_inb, str, ++ !(str & KCS_BMC_STR_OBF), 1, 100, false, ++ &priv->kcs_bmc, priv->kcs_bmc.ioreg.str); ++ /* Time for the slow path? */ ++ if (rc == -ETIMEDOUT) ++ mod_timer(&priv->obe.timer, jiffies + OBE_POLL_PERIOD); ++ } else { + del_timer(&priv->obe.timer); ++ } + } + + if (mask & KCS_BMC_EVENT_TYPE_IBF) { +diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c +index 18606651d1aa4..65f8f179a27f0 100644 +--- a/drivers/char/tpm/tpm_crb.c ++++ b/drivers/char/tpm/tpm_crb.c +@@ -252,7 +252,7 @@ static int __crb_relinquish_locality(struct device *dev, + iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl); + if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value, + TPM2_TIMEOUT_C)) { +- dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n"); ++ dev_warn(dev, "TPM_LOC_STATE_x.Relinquish timed out\n"); + return -ETIME; + } + +diff --git a/drivers/char/tpm/tpm_ftpm_tee.c b/drivers/char/tpm/tpm_ftpm_tee.c +index 5c233423c56fa..deff23bb54bf1 100644 +--- a/drivers/char/tpm/tpm_ftpm_tee.c ++++ b/drivers/char/tpm/tpm_ftpm_tee.c +@@ -397,7 +397,13 @@ static int __init ftpm_mod_init(void) + if (rc) + return rc; + +- return driver_register(&ftpm_tee_driver.driver); ++ rc = driver_register(&ftpm_tee_driver.driver); ++ if (rc) { ++ platform_driver_unregister(&ftpm_tee_plat_driver); ++ return rc; ++ } ++ ++ return 0; + } + + static void __exit ftpm_mod_exit(void) +diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c +index 757623bacfd50..3f98e587b3e84 100644 +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -682,15 +682,19 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status) + { + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); + +- switch (priv->manufacturer_id) { +- case TPM_VID_WINBOND: +- return ((status == TPM_STS_VALID) || +- (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY))); +- case TPM_VID_STM: +- return (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)); +- default: +- return (status == TPM_STS_COMMAND_READY); ++ if (!test_bit(TPM_TIS_DEFAULT_CANCELLATION, &priv->flags)) { ++ switch (priv->manufacturer_id) { ++ case TPM_VID_WINBOND: ++ return ((status == TPM_STS_VALID) || ++ (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY))); ++ case TPM_VID_STM: ++ return (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)); ++ default: ++ break; ++ } + } ++ ++ return status == TPM_STS_COMMAND_READY; + } + + static irqreturn_t tis_int_handler(int dummy, void *dev_id) +diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h +index 66a5a13cd1df2..b68479e0de10f 100644 +--- a/drivers/char/tpm/tpm_tis_core.h ++++ b/drivers/char/tpm/tpm_tis_core.h +@@ -86,6 +86,7 @@ enum tis_defaults { + enum tpm_tis_flags { + TPM_TIS_ITPM_WORKAROUND = BIT(0), + TPM_TIS_INVALID_STATUS = BIT(1), ++ TPM_TIS_DEFAULT_CANCELLATION = BIT(2), + }; + + struct tpm_tis_data { +diff --git a/drivers/char/tpm/tpm_tis_i2c.c b/drivers/char/tpm/tpm_tis_i2c.c +index ba0911b1d1ff3..e728a61659f86 100644 +--- a/drivers/char/tpm/tpm_tis_i2c.c ++++ b/drivers/char/tpm/tpm_tis_i2c.c +@@ -49,7 +49,7 @@ + + /* Masks with bits that must be read zero */ + #define TPM_ACCESS_READ_ZERO 0x48 +-#define TPM_INT_ENABLE_ZERO 0x7FFFFF6 ++#define TPM_INT_ENABLE_ZERO 0x7FFFFF60 + #define TPM_STS_READ_ZERO 0x23 + #define TPM_INTF_CAPABILITY_ZERO 0x0FFFF000 + #define TPM_I2C_INTERFACE_CAPABILITY_ZERO 0x80000000 +@@ -329,6 +329,7 @@ static int tpm_tis_i2c_probe(struct i2c_client *dev, + if (!phy->io_buf) + return -ENOMEM; + ++ set_bit(TPM_TIS_DEFAULT_CANCELLATION, &phy->priv.flags); + phy->i2c_client = dev; + + /* must precede all communication with the tpm */ +diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c +index d37c45b676abe..2afea905f7f3c 100644 +--- a/drivers/clk/imx/clk-imx8mn.c ++++ b/drivers/clk/imx/clk-imx8mn.c +@@ -27,10 +27,10 @@ static u32 share_count_nand; + static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; + static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; + static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; +-static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; ++static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", }; + static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", }; + static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; +-static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; ++static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", }; + static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; + static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", }; + +@@ -40,24 +40,24 @@ static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl + + static const char * const imx8mn_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", }; + +-static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "vpu_pll_out", +- "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; ++static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "m7_alt_pll_out", ++ "sys_pll1_800m", "audio_pll1_out", "video_pll_out", "sys_pll3_out", }; + + static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", +- "video_pll1_out", "audio_pll2_out", }; ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_gpu_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", +- "video_pll1_out", "audio_pll2_out", }; ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", + "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out", +- "video_pll1_out", "sys_pll1_100m",}; ++ "video_pll_out", "sys_pll1_100m",}; + + static const char * const imx8mn_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", + "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", +- "video_pll1_out", "sys_pll3_out", }; ++ "video_pll_out", "sys_pll3_out", }; + + static const char * const imx8mn_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", + "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", +@@ -77,23 +77,23 @@ static const char * const imx8mn_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", " + + static const char * const imx8mn_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", +- "video_pll1_out", "audio_pll2_out", }; ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", +- "video_pll1_out", "audio_pll2_out", }; ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out", +- "video_pll1_out", "audio_pll2_out", }; ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", + "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out", +- "audio_pll1_out", "video_pll1_out", }; ++ "audio_pll1_out", "video_pll_out", }; + + static const char * const imx8mn_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out", +- "audio_pll1_out", "video_pll1_out", }; ++ "audio_pll1_out", "video_pll_out", }; + + static const char * const imx8mn_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", + "sys_pll2_500m", "sys_pll2_1000m", "sys_pll3_out", +@@ -103,49 +103,49 @@ static const char * const imx8mn_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", + "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_250m", "audio_pll2_out", }; + +-static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", ++static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out", + "audio_pll1_out", "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll3_out", "clk_ext4", }; + + static const char * const imx8mn_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", +- "clk_ext3", "clk_ext4", }; ++ "video_pll_out", "sys_pll1_133m", "dummy", ++ "clk_ext2", "clk_ext3", }; + + static const char * const imx8mn_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext2", "clk_ext3", }; + + static const char * const imx8mn_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext2", "clk_ext3", }; + + static const char * const imx8mn_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", + "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out", +- "video_pll1_out", "clk_ext4", }; ++ "video_pll_out", "clk_ext4", }; + + static const char * const imx8mn_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", + "clk_ext1", "clk_ext2", "clk_ext3", +- "clk_ext4", "video_pll1_out", }; ++ "clk_ext4", "video_pll_out", }; + + static const char * const imx8mn_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", +- "sys_pll2_200m", "sys_pll2_500m", "video_pll1_out", +- "audio_pll2_out", }; ++ "sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out", ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", + "sys_pll1_400m", "audio_pll2_out", "sys_pll3_out", +- "sys_pll2_250m", "video_pll1_out", }; ++ "sys_pll2_250m", "video_pll_out", }; + + static const char * const imx8mn_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m", + "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", +@@ -160,19 +160,19 @@ static const char * const imx8mn_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "s + "audio_pll2_out", "sys_pll1_100m", }; + + static const char * const imx8mn_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", +- "sys_pll3_out", "audio_pll1_out", "video_pll1_out", ++ "sys_pll3_out", "audio_pll1_out", "video_pll_out", + "audio_pll2_out", "sys_pll1_133m", }; + + static const char * const imx8mn_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", +- "sys_pll3_out", "audio_pll1_out", "video_pll1_out", ++ "sys_pll3_out", "audio_pll1_out", "video_pll_out", + "audio_pll2_out", "sys_pll1_133m", }; + + static const char * const imx8mn_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", +- "sys_pll3_out", "audio_pll1_out", "video_pll1_out", ++ "sys_pll3_out", "audio_pll1_out", "video_pll_out", + "audio_pll2_out", "sys_pll1_133m", }; + + static const char * const imx8mn_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", +- "sys_pll3_out", "audio_pll1_out", "video_pll1_out", ++ "sys_pll3_out", "audio_pll1_out", "video_pll_out", + "audio_pll2_out", "sys_pll1_133m", }; + + static const char * const imx8mn_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", +@@ -213,63 +213,63 @@ static const char * const imx8mn_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "s + + static const char * const imx8mn_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext1", +- "sys_pll1_80m", "video_pll1_out", }; ++ "sys_pll1_80m", "video_pll_out", }; + + static const char * const imx8mn_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext1", +- "sys_pll1_80m", "video_pll1_out", }; ++ "sys_pll1_80m", "video_pll_out", }; + + static const char * const imx8mn_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext2", +- "sys_pll1_80m", "video_pll1_out", }; ++ "sys_pll1_80m", "video_pll_out", }; + + static const char * const imx8mn_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext2", +- "sys_pll1_80m", "video_pll1_out", }; ++ "sys_pll1_80m", "video_pll_out", }; + + static const char * const imx8mn_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", +- "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out", ++ "m7_alt_pll_out", "sys_pll2_125m", "sys_pll3_out", + "sys_pll1_80m", "sys_pll2_166m", }; + +-static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out", ++static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "m7_alt_pll_out", + "sys_pll3_out", "sys_pll2_200m", "sys_pll1_266m", + "sys_pll2_500m", "sys_pll1_100m", }; + + static const char * const imx8mn_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", + "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", + "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", +@@ -277,15 +277,15 @@ static const char * const imx8mn_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "s + + static const char * const imx8mn_camera_pixel_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", + "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", + "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", +@@ -306,9 +306,9 @@ static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "du + "dummy", "sys_pll1_80m", }; + static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", + "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", +- "video_pll1_out", "osc_32k", }; ++ "video_pll_out", "osc_32k", }; + +-static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out", ++static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out", + "dummy", "dummy", "gpu_pll_out", "dummy", + "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3", + "dummy", "dummy", "osc_24m", "dummy", "osc_32k"}; +@@ -349,19 +349,19 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) + + hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +- hws[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); ++ hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +- hws[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); ++ hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + + hws[IMX8MN_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); + hws[IMX8MN_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll); +- hws[IMX8MN_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll); ++ hws[IMX8MN_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", base + 0x28, &imx_1443x_pll); + hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll); + hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); +- hws[IMX8MN_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); ++ hws[IMX8MN_M7_ALT_PLL] = imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel", base + 0x74, &imx_1416x_pll); + hws[IMX8MN_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); + hws[IMX8MN_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000); + hws[IMX8MN_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000); +@@ -370,20 +370,20 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) + /* PLL bypass out */ + hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT); +- hws[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT); ++ hws[IMX8MN_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); +- hws[IMX8MN_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT); ++ hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1, m7_alt_pll_bypass_sels, ARRAY_SIZE(m7_alt_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT); + + /* PLL out gate */ + hws[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13); + hws[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13); +- hws[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13); ++ hws[IMX8MN_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", base + 0x28, 13); + hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13); + hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11); +- hws[IMX8MN_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11); ++ hws[IMX8MN_M7_ALT_PLL_OUT] = imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass", base + 0x74, 11); + hws[IMX8MN_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11); + hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); + +diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c +index 652ae58c2735f..5d68d975b4eb1 100644 +--- a/drivers/clk/imx/clk-imx8mp.c ++++ b/drivers/clk/imx/clk-imx8mp.c +@@ -17,6 +17,7 @@ + + static u32 share_count_nand; + static u32 share_count_media; ++static u32 share_count_usb; + + static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; + static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; +@@ -673,7 +674,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) + hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0); + hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0); + hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0); +- hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0); ++ hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate2_shared2("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0, &share_count_usb); ++ hws[IMX8MP_CLK_USB_SUSP] = imx_clk_hw_gate2_shared2("usb_suspend_clk", "osc_32k", ccm_base + 0x44d0, 0, &share_count_usb); + hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0); + hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0); + hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0); +diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c +index dcc41d178238e..2e99c3443d3c3 100644 +--- a/drivers/clk/imx/clk-imx93.c ++++ b/drivers/clk/imx/clk-imx93.c +@@ -162,7 +162,7 @@ static const struct imx93_clk_ccgr { + { IMX93_CLK_MU_B_GATE, "mu_b", "bus_aon_root", 0x8500, }, + { IMX93_CLK_EDMA1_GATE, "edma1", "m33_root", 0x8540, }, + { IMX93_CLK_EDMA2_GATE, "edma2", "wakeup_axi_root", 0x8580, }, +- { IMX93_CLK_FLEXSPI1_GATE, "flexspi", "flexspi_root", 0x8640, }, ++ { IMX93_CLK_FLEXSPI1_GATE, "flexspi1", "flexspi1_root", 0x8640, }, + { IMX93_CLK_GPIO1_GATE, "gpio1", "m33_root", 0x8880, }, + { IMX93_CLK_GPIO2_GATE, "gpio2", "bus_wakeup_root", 0x88c0, }, + { IMX93_CLK_GPIO3_GATE, "gpio3", "bus_wakeup_root", 0x8900, }, +@@ -229,7 +229,7 @@ static const struct imx93_clk_ccgr { + { IMX93_CLK_AUD_XCVR_GATE, "aud_xcvr", "audio_xcvr_root", 0x9b80, }, + { IMX93_CLK_SPDIF_GATE, "spdif", "spdif_root", 0x9c00, }, + { IMX93_CLK_HSIO_32K_GATE, "hsio_32k", "osc_32k", 0x9dc0, }, +- { IMX93_CLK_ENET1_GATE, "enet1", "enet_root", 0x9e00, }, ++ { IMX93_CLK_ENET1_GATE, "enet1", "wakeup_axi_root", 0x9e00, }, + { IMX93_CLK_ENET_QOS_GATE, "enet_qos", "wakeup_axi_root", 0x9e40, }, + { IMX93_CLK_SYS_CNT_GATE, "sys_cnt", "osc_24m", 0x9e80, }, + { IMX93_CLK_TSTMR1_GATE, "tstmr1", "bus_aon_root", 0x9ec0, }, +@@ -247,7 +247,7 @@ static int imx93_clocks_probe(struct platform_device *pdev) + struct device_node *np = dev->of_node; + const struct imx93_clk_root *root; + const struct imx93_clk_ccgr *ccgr; +- void __iomem *base = NULL; ++ void __iomem *base, *anatop_base; + int i, ret; + + clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, +@@ -274,20 +274,22 @@ static int imx93_clocks_probe(struct platform_device *pdev) + "sys_pll_pfd2", 1, 2); + + np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop"); +- base = of_iomap(np, 0); ++ anatop_base = of_iomap(np, 0); + of_node_put(np); +- if (WARN_ON(!base)) ++ if (WARN_ON(!anatop_base)) + return -ENOMEM; + +- clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", base + 0x1200, ++ clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", anatop_base + 0x1200, + &imx_fracn_gppll); +- clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", base + 0x1400, ++ clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", anatop_base + 0x1400, + &imx_fracn_gppll); + + np = dev->of_node; + base = devm_platform_ioremap_resource(pdev, 0); +- if (WARN_ON(IS_ERR(base))) ++ if (WARN_ON(IS_ERR(base))) { ++ iounmap(anatop_base); + return PTR_ERR(base); ++ } + + for (i = 0; i < ARRAY_SIZE(root_array); i++) { + root = &root_array[i]; +@@ -317,6 +319,7 @@ static int imx93_clocks_probe(struct platform_device *pdev) + + unregister_hws: + imx_unregister_hw_clocks(clks, IMX93_CLK_END); ++ iounmap(anatop_base); + + return ret; + } +diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c +index 9539d35588ee9..26108e9f7e67a 100644 +--- a/drivers/clk/imx/clk-imxrt1050.c ++++ b/drivers/clk/imx/clk-imxrt1050.c +@@ -140,7 +140,7 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) + hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2); + hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4); + hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24); +- hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10); ++ hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x70, 28); + hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6); + hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7); + imx_check_clk_hws(hws, IMXRT1050_CLK_END); +diff --git a/drivers/clk/mediatek/clk-mt7986-infracfg.c b/drivers/clk/mediatek/clk-mt7986-infracfg.c +index d90727a53283c..49666047bf0ed 100644 +--- a/drivers/clk/mediatek/clk-mt7986-infracfg.c ++++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c +@@ -153,7 +153,7 @@ static const struct mtk_gate infra_clks[] = { + 18), + GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "infra_sysaxi_d2", + 19), +- GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "csw_f26m_sel", 20), ++ GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "infra_adc_frc", 20), + GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m_sel", 21), + GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x_sel", 23), + /* INFRA2 */ +diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c +index 45da736bd5f4c..293a9dfa7151a 100644 +--- a/drivers/clk/qcom/clk-krait.c ++++ b/drivers/clk/qcom/clk-krait.c +@@ -114,6 +114,8 @@ static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate, + + if (d->lpl) + mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift; ++ else ++ mask <<= d->shift; + + spin_lock_irqsave(&krait_clock_reg_lock, flags); + val = krait_get_l2_indirect_reg(d->offset); +diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c +index 0c3c2e26ede90..ea6f54ed846ec 100644 +--- a/drivers/clk/qcom/dispcc-sm6350.c ++++ b/drivers/clk/qcom/dispcc-sm6350.c +@@ -306,7 +306,7 @@ static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { + .name = "disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), +- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, ++ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE, + .ops = &clk_pixel_ops, + }, + }; +@@ -385,7 +385,7 @@ static struct clk_branch disp_cc_mdss_byte0_clk = { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, ++ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE, + .ops = &clk_branch2_ops, + }, + }, +diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c +index 718de17a1e600..6447f3e81b555 100644 +--- a/drivers/clk/qcom/gcc-ipq806x.c ++++ b/drivers/clk/qcom/gcc-ipq806x.c +@@ -79,7 +79,9 @@ static struct clk_regmap pll4_vote = { + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "pll4_vote", +- .parent_names = (const char *[]){ "pll4" }, ++ .parent_data = &(const struct clk_parent_data){ ++ .fw_name = "pll4", .name = "pll4", ++ }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c +index 9755ef4888c19..a0ba37656b07b 100644 +--- a/drivers/clk/qcom/gcc-sm8250.c ++++ b/drivers/clk/qcom/gcc-sm8250.c +@@ -3267,7 +3267,7 @@ static struct gdsc usb30_prim_gdsc = { + .pd = { + .name = "usb30_prim_gdsc", + }, +- .pwrsts = PWRSTS_OFF_ON, ++ .pwrsts = PWRSTS_RET_ON, + }; + + static struct gdsc usb30_sec_gdsc = { +@@ -3275,7 +3275,7 @@ static struct gdsc usb30_sec_gdsc = { + .pd = { + .name = "usb30_sec_gdsc", + }, +- .pwrsts = PWRSTS_OFF_ON, ++ .pwrsts = PWRSTS_RET_ON, + }; + + static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = { +diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c +index 6ab6e5a34c724..b2646b7e13c9f 100644 +--- a/drivers/clk/qcom/lpassaudiocc-sc7280.c ++++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c +@@ -12,6 +12,7 @@ + #include + #include + ++#include + #include + + #include "clk-alpha-pll.h" +@@ -22,6 +23,7 @@ + #include "clk-regmap-mux.h" + #include "common.h" + #include "gdsc.h" ++#include "reset.h" + + enum { + P_BI_TCXO, +@@ -38,6 +40,32 @@ static const struct pll_vco zonda_vco[] = { + { 595200000UL, 3600000000UL, 0 }, + }; + ++static struct clk_branch lpass_q6ss_ahbm_clk = { ++ .halt_reg = 0x901c, ++ .halt_check = BRANCH_HALT, ++ .clkr = { ++ .enable_reg = 0x901c, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "lpass_q6ss_ahbm_clk", ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch lpass_q6ss_ahbs_clk = { ++ .halt_reg = 0x9020, ++ .halt_check = BRANCH_HALT_VOTED, ++ .clkr = { ++ .enable_reg = 0x9020, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "lpass_q6ss_ahbs_clk", ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ + /* 1128.96MHz configuration */ + static const struct alpha_pll_config lpass_audio_cc_pll_config = { + .l = 0x3a, +@@ -221,7 +249,7 @@ static struct clk_rcg2 lpass_aon_cc_main_rcg_clk_src = { + .parent_data = lpass_aon_cc_parent_data_0, + .num_parents = ARRAY_SIZE(lpass_aon_cc_parent_data_0), + .flags = CLK_OPS_PARENT_ENABLE, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -614,6 +642,11 @@ static struct gdsc lpass_aon_cc_lpass_audio_hm_gdsc = { + .flags = RETAIN_FF_ENABLE, + }; + ++static struct clk_regmap *lpass_cc_sc7280_clocks[] = { ++ [LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr, ++ [LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr, ++}; ++ + static struct clk_regmap *lpass_aon_cc_sc7280_clocks[] = { + [LPASS_AON_CC_AUDIO_HM_H_CLK] = &lpass_aon_cc_audio_hm_h_clk.clkr, + [LPASS_AON_CC_VA_MEM0_CLK] = &lpass_aon_cc_va_mem0_clk.clkr, +@@ -659,45 +692,47 @@ static struct regmap_config lpass_audio_cc_sc7280_regmap_config = { + .fast_io = true, + }; + ++static const struct qcom_cc_desc lpass_cc_sc7280_desc = { ++ .config = &lpass_audio_cc_sc7280_regmap_config, ++ .clks = lpass_cc_sc7280_clocks, ++ .num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks), ++}; ++ + static const struct qcom_cc_desc lpass_audio_cc_sc7280_desc = { + .config = &lpass_audio_cc_sc7280_regmap_config, + .clks = lpass_audio_cc_sc7280_clocks, + .num_clks = ARRAY_SIZE(lpass_audio_cc_sc7280_clocks), + }; + ++static const struct qcom_reset_map lpass_audio_cc_sc7280_resets[] = { ++ [LPASS_AUDIO_SWR_RX_CGCR] = { 0xa0, 1 }, ++ [LPASS_AUDIO_SWR_TX_CGCR] = { 0xa8, 1 }, ++ [LPASS_AUDIO_SWR_WSA_CGCR] = { 0xb0, 1 }, ++}; ++ ++static const struct qcom_cc_desc lpass_audio_cc_reset_sc7280_desc = { ++ .config = &lpass_audio_cc_sc7280_regmap_config, ++ .resets = lpass_audio_cc_sc7280_resets, ++ .num_resets = ARRAY_SIZE(lpass_audio_cc_sc7280_resets), ++}; ++ + static const struct of_device_id lpass_audio_cc_sc7280_match_table[] = { + { .compatible = "qcom,sc7280-lpassaudiocc" }, + { } + }; + MODULE_DEVICE_TABLE(of, lpass_audio_cc_sc7280_match_table); + +-static void lpassaudio_pm_runtime_disable(void *data) +-{ +- pm_runtime_disable(data); +-} +- +-static void lpassaudio_pm_clk_destroy(void *data) +-{ +- pm_clk_destroy(data); +-} +- +-static int lpassaudio_create_pm_clks(struct platform_device *pdev) ++static int lpass_audio_setup_runtime_pm(struct platform_device *pdev) + { + int ret; + + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, 50); +- pm_runtime_enable(&pdev->dev); +- +- ret = devm_add_action_or_reset(&pdev->dev, lpassaudio_pm_runtime_disable, &pdev->dev); +- if (ret) +- return ret; +- +- ret = pm_clk_create(&pdev->dev); ++ ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + +- ret = devm_add_action_or_reset(&pdev->dev, lpassaudio_pm_clk_destroy, &pdev->dev); ++ ret = devm_pm_clk_create(&pdev->dev); + if (ret) + return ret; + +@@ -705,7 +740,7 @@ static int lpassaudio_create_pm_clks(struct platform_device *pdev) + if (ret < 0) + dev_err(&pdev->dev, "failed to acquire iface clock\n"); + +- return ret; ++ return pm_runtime_resume_and_get(&pdev->dev); + } + + static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) +@@ -714,7 +749,7 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) + struct regmap *regmap; + int ret; + +- ret = lpassaudio_create_pm_clks(pdev); ++ ret = lpass_audio_setup_runtime_pm(pdev); + if (ret) + return ret; + +@@ -724,8 +759,8 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) + + regmap = qcom_cc_map(pdev, desc); + if (IS_ERR(regmap)) { +- pm_runtime_disable(&pdev->dev); +- return PTR_ERR(regmap); ++ ret = PTR_ERR(regmap); ++ goto exit; + } + + clk_zonda_pll_configure(&lpass_audio_cc_pll, regmap, &lpass_audio_cc_pll_config); +@@ -734,16 +769,21 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) + regmap_write(regmap, 0x4, 0x3b); + regmap_write(regmap, 0x8, 0xff05); + +- ret = qcom_cc_really_probe(pdev, &lpass_audio_cc_sc7280_desc, regmap); ++ ret = qcom_cc_probe_by_index(pdev, 0, &lpass_audio_cc_sc7280_desc); + if (ret) { + dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC clocks\n"); +- pm_runtime_disable(&pdev->dev); +- return ret; ++ goto exit; ++ } ++ ++ ret = qcom_cc_probe_by_index(pdev, 1, &lpass_audio_cc_reset_sc7280_desc); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC Resets\n"); ++ goto exit; + } + + pm_runtime_mark_last_busy(&pdev->dev); ++exit: + pm_runtime_put_autosuspend(&pdev->dev); +- pm_runtime_put_sync(&pdev->dev); + + return ret; + } +@@ -781,27 +821,38 @@ static int lpass_aon_cc_sc7280_probe(struct platform_device *pdev) + struct regmap *regmap; + int ret; + +- ret = lpassaudio_create_pm_clks(pdev); ++ ret = lpass_audio_setup_runtime_pm(pdev); + if (ret) + return ret; + ++ if (of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) { ++ lpass_audio_cc_sc7280_regmap_config.name = "cc"; ++ desc = &lpass_cc_sc7280_desc; ++ ret = qcom_cc_probe(pdev, desc); ++ goto exit; ++ } ++ + lpass_audio_cc_sc7280_regmap_config.name = "lpasscc_aon"; + lpass_audio_cc_sc7280_regmap_config.max_register = 0xa0008; + desc = &lpass_aon_cc_sc7280_desc; + + regmap = qcom_cc_map(pdev, desc); +- if (IS_ERR(regmap)) +- return PTR_ERR(regmap); ++ if (IS_ERR(regmap)) { ++ ret = PTR_ERR(regmap); ++ goto exit; ++ } + + clk_lucid_pll_configure(&lpass_aon_cc_pll, regmap, &lpass_aon_cc_pll_config); + + ret = qcom_cc_really_probe(pdev, &lpass_aon_cc_sc7280_desc, regmap); +- if (ret) ++ if (ret) { + dev_err(&pdev->dev, "Failed to register LPASS AON CC clocks\n"); ++ goto exit; ++ } + + pm_runtime_mark_last_busy(&pdev->dev); ++exit: + pm_runtime_put_autosuspend(&pdev->dev); +- pm_runtime_put_sync(&pdev->dev); + + return ret; + } +diff --git a/drivers/clk/qcom/lpasscc-sc7280.c b/drivers/clk/qcom/lpasscc-sc7280.c +index b39ee1c9647bc..5c1e17bd0d763 100644 +--- a/drivers/clk/qcom/lpasscc-sc7280.c ++++ b/drivers/clk/qcom/lpasscc-sc7280.c +@@ -17,32 +17,6 @@ + #include "clk-branch.h" + #include "common.h" + +-static struct clk_branch lpass_q6ss_ahbm_clk = { +- .halt_reg = 0x1c, +- .halt_check = BRANCH_HALT, +- .clkr = { +- .enable_reg = 0x1c, +- .enable_mask = BIT(0), +- .hw.init = &(struct clk_init_data){ +- .name = "lpass_q6ss_ahbm_clk", +- .ops = &clk_branch2_ops, +- }, +- }, +-}; +- +-static struct clk_branch lpass_q6ss_ahbs_clk = { +- .halt_reg = 0x20, +- .halt_check = BRANCH_HALT_VOTED, +- .clkr = { +- .enable_reg = 0x20, +- .enable_mask = BIT(0), +- .hw.init = &(struct clk_init_data){ +- .name = "lpass_q6ss_ahbs_clk", +- .ops = &clk_branch2_ops, +- }, +- }, +-}; +- + static struct clk_branch lpass_top_cc_lpi_q6_axim_hs_clk = { + .halt_reg = 0x0, + .halt_check = BRANCH_HALT, +@@ -105,17 +79,6 @@ static struct regmap_config lpass_regmap_config = { + .fast_io = true, + }; + +-static struct clk_regmap *lpass_cc_sc7280_clocks[] = { +- [LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr, +- [LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr, +-}; +- +-static const struct qcom_cc_desc lpass_cc_sc7280_desc = { +- .config = &lpass_regmap_config, +- .clks = lpass_cc_sc7280_clocks, +- .num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks), +-}; +- + static struct clk_regmap *lpass_cc_top_sc7280_clocks[] = { + [LPASS_TOP_CC_LPI_Q6_AXIM_HS_CLK] = + &lpass_top_cc_lpi_q6_axim_hs_clk.clkr, +@@ -169,13 +132,6 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev) + if (ret) + goto destroy_pm_clk; + +- lpass_regmap_config.name = "cc"; +- desc = &lpass_cc_sc7280_desc; +- +- ret = qcom_cc_probe_by_index(pdev, 2, desc); +- if (ret) +- goto destroy_pm_clk; +- + return 0; + + destroy_pm_clk: +diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c +index ac09b7b840aba..a5731994cbed1 100644 +--- a/drivers/clk/qcom/lpasscorecc-sc7180.c ++++ b/drivers/clk/qcom/lpasscorecc-sc7180.c +@@ -356,7 +356,7 @@ static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = { + .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs), + }; + +-static int lpass_create_pm_clks(struct platform_device *pdev) ++static int lpass_setup_runtime_pm(struct platform_device *pdev) + { + int ret; + +@@ -375,7 +375,7 @@ static int lpass_create_pm_clks(struct platform_device *pdev) + if (ret < 0) + dev_err(&pdev->dev, "failed to acquire iface clock\n"); + +- return ret; ++ return pm_runtime_resume_and_get(&pdev->dev); + } + + static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) +@@ -384,7 +384,7 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) + struct regmap *regmap; + int ret; + +- ret = lpass_create_pm_clks(pdev); ++ ret = lpass_setup_runtime_pm(pdev); + if (ret) + return ret; + +@@ -392,12 +392,14 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) + desc = &lpass_audio_hm_sc7180_desc; + ret = qcom_cc_probe_by_index(pdev, 1, desc); + if (ret) +- return ret; ++ goto exit; + + lpass_core_cc_sc7180_regmap_config.name = "lpass_core_cc"; + regmap = qcom_cc_map(pdev, &lpass_core_cc_sc7180_desc); +- if (IS_ERR(regmap)) +- return PTR_ERR(regmap); ++ if (IS_ERR(regmap)) { ++ ret = PTR_ERR(regmap); ++ goto exit; ++ } + + /* + * Keep the CLK always-ON +@@ -415,6 +417,7 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) + ret = qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap); + + pm_runtime_mark_last_busy(&pdev->dev); ++exit: + pm_runtime_put_autosuspend(&pdev->dev); + + return ret; +@@ -425,14 +428,19 @@ static int lpass_hm_core_probe(struct platform_device *pdev) + const struct qcom_cc_desc *desc; + int ret; + +- ret = lpass_create_pm_clks(pdev); ++ ret = lpass_setup_runtime_pm(pdev); + if (ret) + return ret; + + lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core"; + desc = &lpass_core_hm_sc7180_desc; + +- return qcom_cc_probe_by_index(pdev, 0, desc); ++ ret = qcom_cc_probe_by_index(pdev, 0, desc); ++ ++ pm_runtime_mark_last_busy(&pdev->dev); ++ pm_runtime_put_autosuspend(&pdev->dev); ++ ++ return ret; + } + + static const struct of_device_id lpass_hm_sc7180_match_table[] = { +diff --git a/drivers/clk/qcom/lpasscorecc-sc7280.c b/drivers/clk/qcom/lpasscorecc-sc7280.c +index 1f1f1bd1b68ef..6ad19b06b1ce3 100644 +--- a/drivers/clk/qcom/lpasscorecc-sc7280.c ++++ b/drivers/clk/qcom/lpasscorecc-sc7280.c +@@ -190,6 +190,19 @@ static struct clk_rcg2 lpass_core_cc_ext_if1_clk_src = { + }, + }; + ++static struct clk_rcg2 lpass_core_cc_ext_mclk0_clk_src = { ++ .cmd_rcgr = 0x20000, ++ .mnd_width = 8, ++ .hid_width = 5, ++ .parent_map = lpass_core_cc_parent_map_0, ++ .freq_tbl = ftbl_lpass_core_cc_ext_if0_clk_src, ++ .clkr.hw.init = &(const struct clk_init_data){ ++ .name = "lpass_core_cc_ext_mclk0_clk_src", ++ .parent_data = lpass_core_cc_parent_data_0, ++ .num_parents = ARRAY_SIZE(lpass_core_cc_parent_data_0), ++ .ops = &clk_rcg2_ops, ++ }, ++}; + + static struct clk_branch lpass_core_cc_core_clk = { + .halt_reg = 0x1f000, +@@ -283,6 +296,24 @@ static struct clk_branch lpass_core_cc_lpm_mem0_core_clk = { + }, + }; + ++static struct clk_branch lpass_core_cc_ext_mclk0_clk = { ++ .halt_reg = 0x20014, ++ .halt_check = BRANCH_HALT, ++ .clkr = { ++ .enable_reg = 0x20014, ++ .enable_mask = BIT(0), ++ .hw.init = &(const struct clk_init_data){ ++ .name = "lpass_core_cc_ext_mclk0_clk", ++ .parent_hws = (const struct clk_hw*[]){ ++ &lpass_core_cc_ext_mclk0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ + static struct clk_branch lpass_core_cc_sysnoc_mport_core_clk = { + .halt_reg = 0x23000, + .halt_check = BRANCH_HALT_VOTED, +@@ -326,6 +357,8 @@ static struct clk_regmap *lpass_core_cc_sc7280_clocks[] = { + [LPASS_CORE_CC_LPM_CORE_CLK] = &lpass_core_cc_lpm_core_clk.clkr, + [LPASS_CORE_CC_LPM_MEM0_CORE_CLK] = &lpass_core_cc_lpm_mem0_core_clk.clkr, + [LPASS_CORE_CC_SYSNOC_MPORT_CORE_CLK] = &lpass_core_cc_sysnoc_mport_core_clk.clkr, ++ [LPASS_CORE_CC_EXT_MCLK0_CLK] = &lpass_core_cc_ext_mclk0_clk.clkr, ++ [LPASS_CORE_CC_EXT_MCLK0_CLK_SRC] = &lpass_core_cc_ext_mclk0_clk_src.clkr, + }; + + static struct regmap_config lpass_core_cc_sc7280_regmap_config = { +diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c +index d74d46833012f..e02542ca24a06 100644 +--- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c ++++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c +@@ -116,7 +116,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { + DEF_FIXED("cp", R8A779A0_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cl16mck", R8A779A0_CLK_CL16MCK, CLK_PLL1_DIV2, 64, 1), + +- DEF_GEN4_SDH("sdh0", R8A779A0_CLK_SD0H, CLK_SDSRC, 0x870), ++ DEF_GEN4_SDH("sd0h", R8A779A0_CLK_SD0H, CLK_SDSRC, 0x870), + DEF_GEN4_SD("sd0", R8A779A0_CLK_SD0, R8A779A0_CLK_SD0H, 0x870), + + DEF_BASE("rpc", R8A779A0_CLK_RPC, CLK_TYPE_GEN4_RPC, CLK_RPCSRC), +diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c +index cd80b6084eceb..ab104a25a6019 100644 +--- a/drivers/clk/renesas/r8a779f0-cpg-mssr.c ++++ b/drivers/clk/renesas/r8a779f0-cpg-mssr.c +@@ -108,7 +108,13 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = { + DEF_FIXED("cbfusa", R8A779F0_CLK_CBFUSA, CLK_EXTAL, 2, 1), + DEF_FIXED("cpex", R8A779F0_CLK_CPEX, CLK_EXTAL, 2, 1), + +- DEF_GEN4_SD("sd0", R8A779F0_CLK_SD0, CLK_SDSRC, 0x870), ++ DEF_FIXED("sasyncrt", R8A779F0_CLK_SASYNCRT, CLK_PLL5_DIV4, 48, 1), ++ DEF_FIXED("sasyncperd1", R8A779F0_CLK_SASYNCPERD1, CLK_PLL5_DIV4, 3, 1), ++ DEF_FIXED("sasyncperd2", R8A779F0_CLK_SASYNCPERD2, R8A779F0_CLK_SASYNCPERD1, 2, 1), ++ DEF_FIXED("sasyncperd4", R8A779F0_CLK_SASYNCPERD4, R8A779F0_CLK_SASYNCPERD1, 4, 1), ++ ++ DEF_GEN4_SDH("sd0h", R8A779F0_CLK_SD0H, CLK_SDSRC, 0x870), ++ DEF_GEN4_SD("sd0", R8A779F0_CLK_SD0, R8A779F0_CLK_SD0H, 0x870), + + DEF_BASE("rpc", R8A779F0_CLK_RPC, CLK_TYPE_GEN4_RPC, CLK_RPCSRC), + DEF_BASE("rpcd2", R8A779F0_CLK_RPCD2, CLK_TYPE_GEN4_RPCD2, R8A779F0_CLK_RPC), +@@ -120,10 +126,10 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = { + }; + + static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = { +- DEF_MOD("hscif0", 514, R8A779F0_CLK_S0D3), +- DEF_MOD("hscif1", 515, R8A779F0_CLK_S0D3), +- DEF_MOD("hscif2", 516, R8A779F0_CLK_S0D3), +- DEF_MOD("hscif3", 517, R8A779F0_CLK_S0D3), ++ DEF_MOD("hscif0", 514, R8A779F0_CLK_SASYNCPERD1), ++ DEF_MOD("hscif1", 515, R8A779F0_CLK_SASYNCPERD1), ++ DEF_MOD("hscif2", 516, R8A779F0_CLK_SASYNCPERD1), ++ DEF_MOD("hscif3", 517, R8A779F0_CLK_SASYNCPERD1), + DEF_MOD("i2c0", 518, R8A779F0_CLK_S0D6_PER), + DEF_MOD("i2c1", 519, R8A779F0_CLK_S0D6_PER), + DEF_MOD("i2c2", 520, R8A779F0_CLK_S0D6_PER), +@@ -132,13 +138,18 @@ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = { + DEF_MOD("i2c5", 523, R8A779F0_CLK_S0D6_PER), + DEF_MOD("pcie0", 624, R8A779F0_CLK_S0D2), + DEF_MOD("pcie1", 625, R8A779F0_CLK_S0D2), +- DEF_MOD("scif0", 702, R8A779F0_CLK_S0D12_PER), +- DEF_MOD("scif1", 703, R8A779F0_CLK_S0D12_PER), +- DEF_MOD("scif3", 704, R8A779F0_CLK_S0D12_PER), +- DEF_MOD("scif4", 705, R8A779F0_CLK_S0D12_PER), ++ DEF_MOD("scif0", 702, R8A779F0_CLK_SASYNCPERD4), ++ DEF_MOD("scif1", 703, R8A779F0_CLK_SASYNCPERD4), ++ DEF_MOD("scif3", 704, R8A779F0_CLK_SASYNCPERD4), ++ DEF_MOD("scif4", 705, R8A779F0_CLK_SASYNCPERD4), + DEF_MOD("sdhi0", 706, R8A779F0_CLK_SD0), + DEF_MOD("sys-dmac0", 709, R8A779F0_CLK_S0D3_PER), + DEF_MOD("sys-dmac1", 710, R8A779F0_CLK_S0D3_PER), ++ DEF_MOD("tmu0", 713, R8A779F0_CLK_SASYNCRT), ++ DEF_MOD("tmu1", 714, R8A779F0_CLK_SASYNCPERD2), ++ DEF_MOD("tmu2", 715, R8A779F0_CLK_SASYNCPERD2), ++ DEF_MOD("tmu3", 716, R8A779F0_CLK_SASYNCPERD2), ++ DEF_MOD("tmu4", 717, R8A779F0_CLK_SASYNCPERD2), + DEF_MOD("wdt", 907, R8A779F0_CLK_R), + DEF_MOD("pfc0", 915, R8A779F0_CLK_CL16M), + DEF_MOD("tsc", 919, R8A779F0_CLK_CL16M), +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index 1488c9d6e6394..983faa5707b9c 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -412,7 +412,7 @@ static int r9a06g032_attach_dev(struct generic_pm_domain *pd, + int error; + int index; + +- while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, ++ while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i++, + &clkspec)) { + if (clkspec.np != pd->dev.of_node) + continue; +@@ -425,7 +425,6 @@ static int r9a06g032_attach_dev(struct generic_pm_domain *pd, + if (error) + return error; + } +- i++; + } + + return 0; +diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c +index f7827b3b7fc1c..6e5e502be44a6 100644 +--- a/drivers/clk/rockchip/clk-pll.c ++++ b/drivers/clk/rockchip/clk-pll.c +@@ -981,6 +981,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, + return mux_clk; + + err_pll: ++ kfree(pll->rate_table); + clk_unregister(mux_clk); + mux_clk = pll_clk; + err_mux: +diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c +index fe383471c5f0a..0ff28938943f0 100644 +--- a/drivers/clk/samsung/clk-pll.c ++++ b/drivers/clk/samsung/clk-pll.c +@@ -1583,6 +1583,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, + if (ret) { + pr_err("%s: failed to register pll clock %s : %d\n", + __func__, pll_clk->name, ret); ++ kfree(pll->rate_table); + kfree(pll); + return; + } +diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c +index 53d6e3ec4309f..c94b59b80dd43 100644 +--- a/drivers/clk/socfpga/clk-gate.c ++++ b/drivers/clk/socfpga/clk-gate.c +@@ -188,8 +188,10 @@ void __init socfpga_gate_init(struct device_node *node) + return; + + ops = kmemdup(&gateclk_ops, sizeof(gateclk_ops), GFP_KERNEL); +- if (WARN_ON(!ops)) ++ if (WARN_ON(!ops)) { ++ kfree(socfpga_clk); + return; ++ } + + rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2); + if (rc) +@@ -243,6 +245,7 @@ void __init socfpga_gate_init(struct device_node *node) + + err = clk_hw_register(NULL, hw_clk); + if (err) { ++ kfree(ops); + kfree(socfpga_clk); + return; + } +diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c +index d820292a381d0..40df1db102a77 100644 +--- a/drivers/clk/st/clkgen-fsyn.c ++++ b/drivers/clk/st/clkgen-fsyn.c +@@ -1020,9 +1020,10 @@ static void __init st_of_quadfs_setup(struct device_node *np, + + clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, datac->data, + reg, lock); +- if (IS_ERR(clk)) ++ if (IS_ERR(clk)) { ++ kfree(lock); + goto err_exit; +- else ++ } else + pr_debug("%s: parent %s rate %u\n", + __clk_get_name(clk), + __clk_get_name(clk_get_parent(clk)), +diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c +index a484cb945d67b..1f3234f226674 100644 +--- a/drivers/clk/visconti/pll.c ++++ b/drivers/clk/visconti/pll.c +@@ -277,6 +277,7 @@ static struct clk_hw *visconti_register_pll(struct visconti_pll_provider *ctx, + ret = clk_hw_register(NULL, &pll->hw); + if (ret) { + pr_err("failed to register pll clock %s : %d\n", name, ret); ++ kfree(pll->rate_table); + kfree(pll); + pll_hw_clk = ERR_PTR(ret); + } +diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c +index 64dcb082d4cf6..7b952aa52c0b9 100644 +--- a/drivers/clocksource/sh_cmt.c ++++ b/drivers/clocksource/sh_cmt.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -116,6 +117,7 @@ struct sh_cmt_device { + void __iomem *mapbase; + struct clk *clk; + unsigned long rate; ++ unsigned int reg_delay; + + raw_spinlock_t lock; /* Protect the shared start/stop register */ + +@@ -247,10 +249,17 @@ static inline u32 sh_cmt_read_cmstr(struct sh_cmt_channel *ch) + + static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch, u32 value) + { +- if (ch->iostart) +- ch->cmt->info->write_control(ch->iostart, 0, value); +- else +- ch->cmt->info->write_control(ch->cmt->mapbase, 0, value); ++ u32 old_value = sh_cmt_read_cmstr(ch); ++ ++ if (value != old_value) { ++ if (ch->iostart) { ++ ch->cmt->info->write_control(ch->iostart, 0, value); ++ udelay(ch->cmt->reg_delay); ++ } else { ++ ch->cmt->info->write_control(ch->cmt->mapbase, 0, value); ++ udelay(ch->cmt->reg_delay); ++ } ++ } + } + + static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch) +@@ -260,7 +269,12 @@ static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch) + + static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch, u32 value) + { +- ch->cmt->info->write_control(ch->ioctrl, CMCSR, value); ++ u32 old_value = sh_cmt_read_cmcsr(ch); ++ ++ if (value != old_value) { ++ ch->cmt->info->write_control(ch->ioctrl, CMCSR, value); ++ udelay(ch->cmt->reg_delay); ++ } + } + + static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch) +@@ -268,14 +282,33 @@ static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch) + return ch->cmt->info->read_count(ch->ioctrl, CMCNT); + } + +-static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value) ++static inline int sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value) + { ++ /* Tests showed that we need to wait 3 clocks here */ ++ unsigned int cmcnt_delay = DIV_ROUND_UP(3 * ch->cmt->reg_delay, 2); ++ u32 reg; ++ ++ if (ch->cmt->info->model > SH_CMT_16BIT) { ++ int ret = read_poll_timeout_atomic(sh_cmt_read_cmcsr, reg, ++ !(reg & SH_CMT32_CMCSR_WRFLG), ++ 1, cmcnt_delay, false, ch); ++ if (ret < 0) ++ return ret; ++ } ++ + ch->cmt->info->write_count(ch->ioctrl, CMCNT, value); ++ udelay(cmcnt_delay); ++ return 0; + } + + static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch, u32 value) + { +- ch->cmt->info->write_count(ch->ioctrl, CMCOR, value); ++ u32 old_value = ch->cmt->info->read_count(ch->ioctrl, CMCOR); ++ ++ if (value != old_value) { ++ ch->cmt->info->write_count(ch->ioctrl, CMCOR, value); ++ udelay(ch->cmt->reg_delay); ++ } + } + + static u32 sh_cmt_get_counter(struct sh_cmt_channel *ch, u32 *has_wrapped) +@@ -319,7 +352,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start) + + static int sh_cmt_enable(struct sh_cmt_channel *ch) + { +- int k, ret; ++ int ret; + + dev_pm_syscore_device(&ch->cmt->pdev->dev, true); + +@@ -347,26 +380,9 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch) + } + + sh_cmt_write_cmcor(ch, 0xffffffff); +- sh_cmt_write_cmcnt(ch, 0); +- +- /* +- * According to the sh73a0 user's manual, as CMCNT can be operated +- * only by the RCLK (Pseudo 32 kHz), there's one restriction on +- * modifying CMCNT register; two RCLK cycles are necessary before +- * this register is either read or any modification of the value +- * it holds is reflected in the LSI's actual operation. +- * +- * While at it, we're supposed to clear out the CMCNT as of this +- * moment, so make sure it's processed properly here. This will +- * take RCLKx2 at maximum. +- */ +- for (k = 0; k < 100; k++) { +- if (!sh_cmt_read_cmcnt(ch)) +- break; +- udelay(1); +- } ++ ret = sh_cmt_write_cmcnt(ch, 0); + +- if (sh_cmt_read_cmcnt(ch)) { ++ if (ret || sh_cmt_read_cmcnt(ch)) { + dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n", + ch->index); + ret = -ETIMEDOUT; +@@ -995,8 +1011,8 @@ MODULE_DEVICE_TABLE(of, sh_cmt_of_table); + + static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) + { +- unsigned int mask; +- unsigned int i; ++ unsigned int mask, i; ++ unsigned long rate; + int ret; + + cmt->pdev = pdev; +@@ -1032,10 +1048,16 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) + if (ret < 0) + goto err_clk_unprepare; + +- if (cmt->info->width == 16) +- cmt->rate = clk_get_rate(cmt->clk) / 512; +- else +- cmt->rate = clk_get_rate(cmt->clk) / 8; ++ rate = clk_get_rate(cmt->clk); ++ if (!rate) { ++ ret = -EINVAL; ++ goto err_clk_disable; ++ } ++ ++ /* We shall wait 2 input clks after register writes */ ++ if (cmt->info->model >= SH_CMT_48BIT) ++ cmt->reg_delay = DIV_ROUND_UP(2UL * USEC_PER_SEC, rate); ++ cmt->rate = rate / (cmt->info->width == 16 ? 512 : 8); + + /* Map the memory resource(s). */ + ret = sh_cmt_map_memory(cmt); +diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c +index 2737407ff0698..632523c1232f6 100644 +--- a/drivers/clocksource/timer-ti-dm-systimer.c ++++ b/drivers/clocksource/timer-ti-dm-systimer.c +@@ -345,8 +345,10 @@ static int __init dmtimer_systimer_init_clock(struct dmtimer_systimer *t, + return error; + + r = clk_get_rate(clock); +- if (!r) ++ if (!r) { ++ clk_disable_unprepare(clock); + return -ENODEV; ++ } + + if (is_ick) + t->ick = clock; +diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c +index 469f7c91564b6..78c2c038d3ae4 100644 +--- a/drivers/clocksource/timer-ti-dm.c ++++ b/drivers/clocksource/timer-ti-dm.c +@@ -1081,7 +1081,7 @@ static struct platform_driver omap_dm_timer_driver = { + .remove = omap_dm_timer_remove, + .driver = { + .name = "omap_timer", +- .of_match_table = of_match_ptr(omap_timer_match), ++ .of_match_table = omap_timer_match, + .pm = &omap_dm_timer_pm_ops, + }, + }; +diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c +index 68031d93ce895..aee3b1a8aaa77 100644 +--- a/drivers/counter/stm32-lptimer-cnt.c ++++ b/drivers/counter/stm32-lptimer-cnt.c +@@ -69,7 +69,7 @@ static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv, + + /* ensure CMP & ARR registers are properly written */ + ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, +- (val & STM32_LPTIM_CMPOK_ARROK), ++ (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK, + 100, 1000); + if (ret) + return ret; +diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c +index 6448e03bcf488..59b19b9975e8c 100644 +--- a/drivers/cpufreq/amd_freq_sensitivity.c ++++ b/drivers/cpufreq/amd_freq_sensitivity.c +@@ -125,6 +125,8 @@ static int __init amd_freq_sensitivity_init(void) + if (!pcidev) { + if (!boot_cpu_has(X86_FEATURE_PROC_FEEDBACK)) + return -ENODEV; ++ } else { ++ pci_dev_put(pcidev); + } + + if (rdmsrl_safe(MSR_AMD64_FREQ_SENSITIVITY_ACTUAL, &val)) +diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c +index bb32659820ceb..823b069203e1b 100644 +--- a/drivers/cpufreq/qcom-cpufreq-hw.c ++++ b/drivers/cpufreq/qcom-cpufreq-hw.c +@@ -122,7 +122,35 @@ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy, + return 0; + } + ++static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data) ++{ ++ unsigned int lval; ++ ++ if (data->soc_data->reg_current_vote) ++ lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff; ++ else ++ lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff; ++ ++ return lval * xo_rate; ++} ++ ++/* Get the current frequency of the CPU (after throttling) */ + static unsigned int qcom_cpufreq_hw_get(unsigned int cpu) ++{ ++ struct qcom_cpufreq_data *data; ++ struct cpufreq_policy *policy; ++ ++ policy = cpufreq_cpu_get_raw(cpu); ++ if (!policy) ++ return 0; ++ ++ data = policy->driver_data; ++ ++ return qcom_lmh_get_throttle_freq(data) / HZ_PER_KHZ; ++} ++ ++/* Get the frequency requested by the cpufreq core for the CPU */ ++static unsigned int qcom_cpufreq_get_freq(unsigned int cpu) + { + struct qcom_cpufreq_data *data; + const struct qcom_cpufreq_soc_data *soc_data; +@@ -190,6 +218,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev, + } + } else if (ret != -ENODEV) { + dev_err(cpu_dev, "Invalid opp table in device tree\n"); ++ kfree(table); + return ret; + } else { + policy->fast_switch_possible = true; +@@ -283,18 +312,6 @@ static void qcom_get_related_cpus(int index, struct cpumask *m) + } + } + +-static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data) +-{ +- unsigned int lval; +- +- if (data->soc_data->reg_current_vote) +- lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff; +- else +- lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff; +- +- return lval * xo_rate; +-} +- + static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) + { + struct cpufreq_policy *policy = data->policy; +@@ -336,7 +353,7 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) + * If h/w throttled frequency is higher than what cpufreq has requested + * for, then stop polling and switch back to interrupt mechanism. + */ +- if (throttled_freq >= qcom_cpufreq_hw_get(cpu)) ++ if (throttled_freq >= qcom_cpufreq_get_freq(cpu)) + enable_irq(data->throttle_irq); + else + mod_delayed_work(system_highpri_wq, &data->throttle_work, +diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c +index 252f2a9686a62..448bc796b0b40 100644 +--- a/drivers/cpuidle/dt_idle_states.c ++++ b/drivers/cpuidle/dt_idle_states.c +@@ -223,6 +223,6 @@ int dt_init_idle_driver(struct cpuidle_driver *drv, + * also be 0 on platforms with missing DT idle states or legacy DT + * configuration predating the DT idle states bindings. + */ +- return i; ++ return state_idx - start_idx; + } + EXPORT_SYMBOL_GPL(dt_init_idle_driver); +diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig +index 3e6aa319920b7..79d9e14b70c87 100644 +--- a/drivers/crypto/Kconfig ++++ b/drivers/crypto/Kconfig +@@ -669,7 +669,12 @@ config CRYPTO_DEV_IMGTEC_HASH + config CRYPTO_DEV_ROCKCHIP + tristate "Rockchip's Cryptographic Engine driver" + depends on OF && ARCH_ROCKCHIP ++ depends on PM ++ select CRYPTO_ECB ++ select CRYPTO_CBC ++ select CRYPTO_DES + select CRYPTO_AES ++ select CRYPTO_ENGINE + select CRYPTO_LIB_DES + select CRYPTO_MD5 + select CRYPTO_SHA1 +diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c +index 910d6751644cf..902f6be057ec6 100644 +--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c ++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c +@@ -124,7 +124,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq) + unsigned int ivsize = crypto_skcipher_ivsize(tfm); + struct sun8i_ss_flow *sf = &ss->flows[rctx->flow]; + int i = 0; +- u32 a; ++ dma_addr_t a; + int err; + + rctx->ivlen = ivsize; +diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c +index 6e7ae896717cd..937187027ad57 100644 +--- a/drivers/crypto/amlogic/amlogic-gxl-core.c ++++ b/drivers/crypto/amlogic/amlogic-gxl-core.c +@@ -237,7 +237,6 @@ static int meson_crypto_probe(struct platform_device *pdev) + return err; + } + +- mc->irqs = devm_kcalloc(mc->dev, MAXFLOW, sizeof(int), GFP_KERNEL); + for (i = 0; i < MAXFLOW; i++) { + mc->irqs[i] = platform_get_irq(pdev, i); + if (mc->irqs[i] < 0) +diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h +index dc0f142324a3c..8c0746a1d6d43 100644 +--- a/drivers/crypto/amlogic/amlogic-gxl.h ++++ b/drivers/crypto/amlogic/amlogic-gxl.h +@@ -95,7 +95,7 @@ struct meson_dev { + struct device *dev; + struct meson_flow *chanlist; + atomic_t flow; +- int *irqs; ++ int irqs[MAXFLOW]; + #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG + struct dentry *dbgfs_dir; + #endif +diff --git a/drivers/crypto/cavium/nitrox/nitrox_mbx.c b/drivers/crypto/cavium/nitrox/nitrox_mbx.c +index 9e7308e39b304..d4e06999af9b7 100644 +--- a/drivers/crypto/cavium/nitrox/nitrox_mbx.c ++++ b/drivers/crypto/cavium/nitrox/nitrox_mbx.c +@@ -195,6 +195,7 @@ int nitrox_mbox_init(struct nitrox_device *ndev) + ndev->iov.pf2vf_wq = alloc_workqueue("nitrox_pf2vf", 0, 0); + if (!ndev->iov.pf2vf_wq) { + kfree(ndev->iov.vfdev); ++ ndev->iov.vfdev = NULL; + return -ENOMEM; + } + /* enable pf2vf mailbox interrupts */ +diff --git a/drivers/crypto/ccree/cc_debugfs.c b/drivers/crypto/ccree/cc_debugfs.c +index 7083767602fcf..8f008f024f8f1 100644 +--- a/drivers/crypto/ccree/cc_debugfs.c ++++ b/drivers/crypto/ccree/cc_debugfs.c +@@ -55,7 +55,7 @@ void __init cc_debugfs_global_init(void) + cc_debugfs_dir = debugfs_create_dir("ccree", NULL); + } + +-void __exit cc_debugfs_global_fini(void) ++void cc_debugfs_global_fini(void) + { + debugfs_remove(cc_debugfs_dir); + } +diff --git a/drivers/crypto/ccree/cc_driver.c b/drivers/crypto/ccree/cc_driver.c +index cadead18b59e8..d489c6f808925 100644 +--- a/drivers/crypto/ccree/cc_driver.c ++++ b/drivers/crypto/ccree/cc_driver.c +@@ -651,9 +651,17 @@ static struct platform_driver ccree_driver = { + + static int __init ccree_init(void) + { ++ int rc; ++ + cc_debugfs_global_init(); + +- return platform_driver_register(&ccree_driver); ++ rc = platform_driver_register(&ccree_driver); ++ if (rc) { ++ cc_debugfs_global_fini(); ++ return rc; ++ } ++ ++ return 0; + } + module_init(ccree_init); + +diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c +index 9d529df0eab9b..7a50ca664ada1 100644 +--- a/drivers/crypto/hisilicon/hpre/hpre_main.c ++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c +@@ -457,7 +457,7 @@ static void hpre_open_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + /* Enable prefetch */ +@@ -478,7 +478,7 @@ static void hpre_close_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + val = readl_relaxed(qm->io_base + HPRE_PREFETCH_CFG); +@@ -1287,18 +1287,12 @@ err_with_qm_init: + static void hpre_remove(struct pci_dev *pdev) + { + struct hisi_qm *qm = pci_get_drvdata(pdev); +- int ret; + + hisi_qm_pm_uninit(qm); + hisi_qm_wait_task_finish(qm, &hpre_devices); + hisi_qm_alg_unregister(qm, &hpre_devices); +- if (qm->fun_type == QM_HW_PF && qm->vfs_num) { +- ret = hisi_qm_sriov_disable(pdev, true); +- if (ret) { +- pci_err(pdev, "Disable SRIOV fail!\n"); +- return; +- } +- } ++ if (qm->fun_type == QM_HW_PF && qm->vfs_num) ++ hisi_qm_sriov_disable(pdev, true); + + hpre_debugfs_exit(qm); + hisi_qm_stop(qm, QM_NORMAL); +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 9fa2efe601537..959f4846aa233 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -86,9 +86,7 @@ + #define QM_DB_CMD_SHIFT_V1 16 + #define QM_DB_INDEX_SHIFT_V1 32 + #define QM_DB_PRIORITY_SHIFT_V1 48 +-#define QM_QUE_ISO_CFG_V 0x0030 + #define QM_PAGE_SIZE 0x0034 +-#define QM_QUE_ISO_EN 0x100154 + #define QM_CAPBILITY 0x100158 + #define QM_QP_NUN_MASK GENMASK(10, 0) + #define QM_QP_DB_INTERVAL 0x10000 +@@ -205,6 +203,8 @@ + #define MAX_WAIT_COUNTS 1000 + #define QM_CACHE_WB_START 0x204 + #define QM_CACHE_WB_DONE 0x208 ++#define QM_FUNC_CAPS_REG 0x3100 ++#define QM_CAPBILITY_VERSION GENMASK(7, 0) + + #define PCI_BAR_2 2 + #define PCI_BAR_4 4 +@@ -252,7 +252,6 @@ + #define QM_QOS_MIN_CIR_B 100 + #define QM_QOS_MAX_CIR_U 6 + #define QM_QOS_MAX_CIR_S 11 +-#define QM_QOS_VAL_MAX_LEN 32 + #define QM_DFX_BASE 0x0100000 + #define QM_DFX_STATE1 0x0104000 + #define QM_DFX_STATE2 0x01040C8 +@@ -329,6 +328,22 @@ enum qm_mb_cmd { + QM_VF_GET_QOS, + }; + ++static const struct hisi_qm_cap_info qm_cap_info_comm[] = { ++ {QM_SUPPORT_DB_ISOLATION, 0x30, 0, BIT(0), 0x0, 0x0, 0x0}, ++ {QM_SUPPORT_FUNC_QOS, 0x3100, 0, BIT(8), 0x0, 0x0, 0x1}, ++ {QM_SUPPORT_STOP_QP, 0x3100, 0, BIT(9), 0x0, 0x0, 0x1}, ++ {QM_SUPPORT_MB_COMMAND, 0x3100, 0, BIT(11), 0x0, 0x0, 0x1}, ++ {QM_SUPPORT_SVA_PREFETCH, 0x3100, 0, BIT(14), 0x0, 0x0, 0x1}, ++}; ++ ++static const struct hisi_qm_cap_info qm_cap_info_pf[] = { ++ {QM_SUPPORT_RPM, 0x3100, 0, BIT(13), 0x0, 0x0, 0x1}, ++}; ++ ++static const struct hisi_qm_cap_info qm_cap_info_vf[] = { ++ {QM_SUPPORT_RPM, 0x3100, 0, BIT(12), 0x0, 0x0, 0x0}, ++}; ++ + struct qm_cqe { + __le32 rsvd0; + __le16 cmd_id; +@@ -426,10 +441,7 @@ struct hisi_qm_hw_ops { + void (*hw_error_init)(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe); + void (*hw_error_uninit)(struct hisi_qm *qm); + enum acc_err_result (*hw_error_handle)(struct hisi_qm *qm); +- int (*stop_qp)(struct hisi_qp *qp); + int (*set_msi)(struct hisi_qm *qm, bool set); +- int (*ping_all_vfs)(struct hisi_qm *qm, u64 cmd); +- int (*ping_pf)(struct hisi_qm *qm, u64 cmd); + }; + + struct qm_dfx_item { +@@ -828,6 +840,36 @@ static int qm_dev_mem_reset(struct hisi_qm *qm) + POLL_TIMEOUT); + } + ++/** ++ * hisi_qm_get_hw_info() - Get device information. ++ * @qm: The qm which want to get information. ++ * @info_table: Array for storing device information. ++ * @index: Index in info_table. ++ * @is_read: Whether read from reg, 0: not support read from reg. ++ * ++ * This function returns device information the caller needs. ++ */ ++u32 hisi_qm_get_hw_info(struct hisi_qm *qm, ++ const struct hisi_qm_cap_info *info_table, ++ u32 index, bool is_read) ++{ ++ u32 val; ++ ++ switch (qm->ver) { ++ case QM_HW_V1: ++ return info_table[index].v1_val; ++ case QM_HW_V2: ++ return info_table[index].v2_val; ++ default: ++ if (!is_read) ++ return info_table[index].v3_val; ++ ++ val = readl(qm->io_base + info_table[index].offset); ++ return (val >> info_table[index].shift) & info_table[index].mask; ++ } ++} ++EXPORT_SYMBOL_GPL(hisi_qm_get_hw_info); ++ + static u32 qm_get_irq_num_v1(struct hisi_qm *qm) + { + return QM_IRQ_NUM_V1; +@@ -854,7 +896,7 @@ static int qm_pm_get_sync(struct hisi_qm *qm) + struct device *dev = &qm->pdev->dev; + int ret; + +- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps)) + return 0; + + ret = pm_runtime_resume_and_get(dev); +@@ -870,7 +912,7 @@ static void qm_pm_put_sync(struct hisi_qm *qm) + { + struct device *dev = &qm->pdev->dev; + +- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps)) + return; + + pm_runtime_mark_last_busy(dev); +@@ -1151,7 +1193,7 @@ static void qm_init_prefetch(struct hisi_qm *qm) + struct device *dev = &qm->pdev->dev; + u32 page_type = 0x0; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + switch (PAGE_SIZE) { +@@ -1270,7 +1312,7 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base, + } + break; + case SHAPER_VFT: +- if (qm->ver >= QM_HW_V3) { ++ if (factor) { + tmp = factor->cir_b | + (factor->cir_u << QM_SHAPER_FACTOR_CIR_U_SHIFT) | + (factor->cir_s << QM_SHAPER_FACTOR_CIR_S_SHIFT) | +@@ -1288,10 +1330,13 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base, + static int qm_set_vft_common(struct hisi_qm *qm, enum vft_type type, + u32 fun_num, u32 base, u32 number) + { +- struct qm_shaper_factor *factor = &qm->factor[fun_num]; ++ struct qm_shaper_factor *factor = NULL; + unsigned int val; + int ret; + ++ if (type == SHAPER_VFT && test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) ++ factor = &qm->factor[fun_num]; ++ + ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val, + val & BIT(0), POLL_PERIOD, + POLL_TIMEOUT); +@@ -1349,7 +1394,7 @@ static int qm_set_sqc_cqc_vft(struct hisi_qm *qm, u32 fun_num, u32 base, + } + + /* init default shaper qos val */ +- if (qm->ver >= QM_HW_V3) { ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) { + ret = qm_shaper_init_vft(qm, fun_num); + if (ret) + goto back_sqc_cqc; +@@ -2495,7 +2540,7 @@ static int qm_wait_vf_prepare_finish(struct hisi_qm *qm) + u64 val; + u32 i; + +- if (!qm->vfs_num || qm->ver < QM_HW_V3) ++ if (!qm->vfs_num || !test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) + return 0; + + while (true) { +@@ -2780,10 +2825,7 @@ static const struct hisi_qm_hw_ops qm_hw_ops_v3 = { + .hw_error_init = qm_hw_error_init_v3, + .hw_error_uninit = qm_hw_error_uninit_v3, + .hw_error_handle = qm_hw_error_handle_v2, +- .stop_qp = qm_stop_qp, + .set_msi = qm_set_msi_v3, +- .ping_all_vfs = qm_ping_all_vfs, +- .ping_pf = qm_ping_pf, + }; + + static void *qm_get_avail_sqe(struct hisi_qp *qp) +@@ -3080,8 +3122,8 @@ static int qm_drain_qp(struct hisi_qp *qp) + return 0; + + /* Kunpeng930 supports drain qp by device */ +- if (qm->ops->stop_qp) { +- ret = qm->ops->stop_qp(qp); ++ if (test_bit(QM_SUPPORT_STOP_QP, &qm->caps)) { ++ ret = qm_stop_qp(qp); + if (ret) + dev_err(dev, "Failed to stop qp(%u)!\n", qp->qp_id); + return ret; +@@ -3312,7 +3354,7 @@ static int hisi_qm_uacce_mmap(struct uacce_queue *q, + if (qm->ver == QM_HW_V1) { + if (sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR) + return -EINVAL; +- } else if (qm->ver == QM_HW_V2 || !qm->use_db_isolation) { ++ } else if (!test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) { + if (sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR + + QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE)) + return -EINVAL; +@@ -3466,7 +3508,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm) + + if (qm->ver == QM_HW_V1) + mmio_page_nr = QM_DOORBELL_PAGE_NR; +- else if (qm->ver == QM_HW_V2 || !qm->use_db_isolation) ++ else if (!test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) + mmio_page_nr = QM_DOORBELL_PAGE_NR + + QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE; + else +@@ -3628,7 +3670,7 @@ static void hisi_qm_pre_init(struct hisi_qm *qm) + init_rwsem(&qm->qps_lock); + qm->qp_in_used = 0; + qm->misc_ctl = false; +- if (qm->fun_type == QM_HW_PF && qm->ver > QM_HW_V2) { ++ if (test_bit(QM_SUPPORT_RPM, &qm->caps)) { + if (!acpi_device_power_manageable(ACPI_COMPANION(&pdev->dev))) + dev_info(&pdev->dev, "_PS0 and _PR0 are not defined"); + } +@@ -3638,7 +3680,7 @@ static void qm_cmd_uninit(struct hisi_qm *qm) + { + u32 val; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) + return; + + val = readl(qm->io_base + QM_IFC_INT_MASK); +@@ -3650,7 +3692,7 @@ static void qm_cmd_init(struct hisi_qm *qm) + { + u32 val; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) + return; + + /* Clear communication interrupt source */ +@@ -3666,7 +3708,7 @@ static void qm_put_pci_res(struct hisi_qm *qm) + { + struct pci_dev *pdev = qm->pdev; + +- if (qm->use_db_isolation) ++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) + iounmap(qm->db_io_base); + + iounmap(qm->io_base); +@@ -3716,7 +3758,9 @@ static void hisi_qm_memory_uninit(struct hisi_qm *qm) + } + + idr_destroy(&qm->qp_idr); +- kfree(qm->factor); ++ ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) ++ kfree(qm->factor); + } + + /** +@@ -4499,12 +4543,10 @@ static int qm_vf_read_qos(struct hisi_qm *qm) + qm->mb_qos = 0; + + /* vf ping pf to get function qos */ +- if (qm->ops->ping_pf) { +- ret = qm->ops->ping_pf(qm, QM_VF_GET_QOS); +- if (ret) { +- pci_err(qm->pdev, "failed to send cmd to PF to get qos!\n"); +- return ret; +- } ++ ret = qm_ping_pf(qm, QM_VF_GET_QOS); ++ if (ret) { ++ pci_err(qm->pdev, "failed to send cmd to PF to get qos!\n"); ++ return ret; + } + + while (true) { +@@ -4583,7 +4625,7 @@ static ssize_t qm_get_qos_value(struct hisi_qm *qm, const char *buf, + unsigned int *fun_index) + { + char tbuf_bdf[QM_DBG_READ_LEN] = {0}; +- char val_buf[QM_QOS_VAL_MAX_LEN] = {0}; ++ char val_buf[QM_DBG_READ_LEN] = {0}; + u32 tmp1, device, function; + int ret, bus; + +@@ -4676,14 +4718,14 @@ static const struct file_operations qm_algqos_fops = { + * hisi_qm_set_algqos_init() - Initialize function qos debugfs files. + * @qm: The qm for which we want to add debugfs files. + * +- * Create function qos debugfs files. ++ * Create function qos debugfs files, VF ping PF to get function qos. + */ + static void hisi_qm_set_algqos_init(struct hisi_qm *qm) + { + if (qm->fun_type == QM_HW_PF) + debugfs_create_file("alg_qos", 0644, qm->debug.debug_root, + qm, &qm_algqos_fops); +- else ++ else if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) + debugfs_create_file("alg_qos", 0444, qm->debug.debug_root, + qm, &qm_algqos_fops); + } +@@ -4731,7 +4773,7 @@ void hisi_qm_debug_init(struct hisi_qm *qm) + &qm_atomic64_ops); + } + +- if (qm->ver >= QM_HW_V3) ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) + hisi_qm_set_algqos_init(qm); + } + EXPORT_SYMBOL_GPL(hisi_qm_debug_init); +@@ -4848,7 +4890,9 @@ int hisi_qm_sriov_disable(struct pci_dev *pdev, bool is_frozen) + + pci_disable_sriov(pdev); + /* clear vf function shaper configure array */ +- memset(qm->factor + 1, 0, sizeof(struct qm_shaper_factor) * total_vfs); ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) ++ memset(qm->factor + 1, 0, sizeof(struct qm_shaper_factor) * total_vfs); ++ + ret = qm_clear_vft_config(qm); + if (ret) + return ret; +@@ -5072,8 +5116,8 @@ static int qm_try_stop_vfs(struct hisi_qm *qm, u64 cmd, + return 0; + + /* Kunpeng930 supports to notify VFs to stop before PF reset */ +- if (qm->ops->ping_all_vfs) { +- ret = qm->ops->ping_all_vfs(qm, cmd); ++ if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) { ++ ret = qm_ping_all_vfs(qm, cmd); + if (ret) + pci_err(pdev, "failed to send cmd to all VFs before PF reset!\n"); + } else { +@@ -5264,8 +5308,8 @@ static int qm_try_start_vfs(struct hisi_qm *qm, enum qm_mb_cmd cmd) + } + + /* Kunpeng930 supports to notify VFs to start after PF reset. */ +- if (qm->ops->ping_all_vfs) { +- ret = qm->ops->ping_all_vfs(qm, cmd); ++ if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) { ++ ret = qm_ping_all_vfs(qm, cmd); + if (ret) + pci_warn(pdev, "failed to send cmd to all VFs after PF reset!\n"); + } else { +@@ -5713,7 +5757,7 @@ err_prepare: + hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET); + out: + pci_save_state(pdev); +- ret = qm->ops->ping_pf(qm, cmd); ++ ret = qm_ping_pf(qm, cmd); + if (ret) + dev_warn(&pdev->dev, "PF responds timeout in reset prepare!\n"); + } +@@ -5731,7 +5775,8 @@ static void qm_pf_reset_vf_done(struct hisi_qm *qm) + cmd = QM_VF_START_FAIL; + } + +- ret = qm->ops->ping_pf(qm, cmd); ++ qm_cmd_init(qm); ++ ret = qm_ping_pf(qm, cmd); + if (ret) + dev_warn(&pdev->dev, "PF responds timeout in reset done!\n"); + +@@ -5792,7 +5837,6 @@ static void qm_pf_reset_vf_process(struct hisi_qm *qm, + goto err_get_status; + + qm_pf_reset_vf_done(qm); +- qm_cmd_init(qm); + + dev_info(dev, "device reset done.\n"); + +@@ -5936,7 +5980,7 @@ static int qm_get_qp_num(struct hisi_qm *qm) + qm->ctrl_qp_num = readl(qm->io_base + QM_CAPBILITY) & + QM_QP_NUN_MASK; + +- if (qm->use_db_isolation) ++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) + qm->max_qp_num = (readl(qm->io_base + QM_CAPBILITY) >> + QM_QP_MAX_NUM_SHIFT) & QM_QP_NUN_MASK; + else +@@ -5952,6 +5996,39 @@ static int qm_get_qp_num(struct hisi_qm *qm) + return 0; + } + ++static void qm_get_hw_caps(struct hisi_qm *qm) ++{ ++ const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ? ++ qm_cap_info_pf : qm_cap_info_vf; ++ u32 size = qm->fun_type == QM_HW_PF ? ARRAY_SIZE(qm_cap_info_pf) : ++ ARRAY_SIZE(qm_cap_info_vf); ++ u32 val, i; ++ ++ /* Doorbell isolate register is a independent register. */ ++ val = hisi_qm_get_hw_info(qm, qm_cap_info_comm, QM_SUPPORT_DB_ISOLATION, true); ++ if (val) ++ set_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps); ++ ++ if (qm->ver >= QM_HW_V3) { ++ val = readl(qm->io_base + QM_FUNC_CAPS_REG); ++ qm->cap_ver = val & QM_CAPBILITY_VERSION; ++ } ++ ++ /* Get PF/VF common capbility */ ++ for (i = 1; i < ARRAY_SIZE(qm_cap_info_comm); i++) { ++ val = hisi_qm_get_hw_info(qm, qm_cap_info_comm, i, qm->cap_ver); ++ if (val) ++ set_bit(qm_cap_info_comm[i].type, &qm->caps); ++ } ++ ++ /* Get PF/VF different capbility */ ++ for (i = 0; i < size; i++) { ++ val = hisi_qm_get_hw_info(qm, cap_info, i, qm->cap_ver); ++ if (val) ++ set_bit(cap_info[i].type, &qm->caps); ++ } ++} ++ + static int qm_get_pci_res(struct hisi_qm *qm) + { + struct pci_dev *pdev = qm->pdev; +@@ -5971,16 +6048,8 @@ static int qm_get_pci_res(struct hisi_qm *qm) + goto err_request_mem_regions; + } + +- if (qm->ver > QM_HW_V2) { +- if (qm->fun_type == QM_HW_PF) +- qm->use_db_isolation = readl(qm->io_base + +- QM_QUE_ISO_EN) & BIT(0); +- else +- qm->use_db_isolation = readl(qm->io_base + +- QM_QUE_ISO_CFG_V) & BIT(0); +- } +- +- if (qm->use_db_isolation) { ++ qm_get_hw_caps(qm); ++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) { + qm->db_interval = QM_QP_DB_INTERVAL; + qm->db_phys_base = pci_resource_start(pdev, PCI_BAR_4); + qm->db_io_base = ioremap(qm->db_phys_base, +@@ -6004,7 +6073,7 @@ static int qm_get_pci_res(struct hisi_qm *qm) + return 0; + + err_db_ioremap: +- if (qm->use_db_isolation) ++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) + iounmap(qm->db_io_base); + err_ioremap: + iounmap(qm->io_base); +@@ -6121,12 +6190,15 @@ static int hisi_qm_memory_init(struct hisi_qm *qm) + int ret, total_func, i; + size_t off = 0; + +- total_func = pci_sriov_get_totalvfs(qm->pdev) + 1; +- qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL); +- if (!qm->factor) +- return -ENOMEM; +- for (i = 0; i < total_func; i++) +- qm->factor[i].func_qos = QM_QOS_MAX_VAL; ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) { ++ total_func = pci_sriov_get_totalvfs(qm->pdev) + 1; ++ qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL); ++ if (!qm->factor) ++ return -ENOMEM; ++ ++ for (i = 0; i < total_func; i++) ++ qm->factor[i].func_qos = QM_QOS_MAX_VAL; ++ } + + #define QM_INIT_BUF(qm, type, num) do { \ + (qm)->type = ((qm)->qdma.va + (off)); \ +@@ -6143,8 +6215,8 @@ static int hisi_qm_memory_init(struct hisi_qm *qm) + GFP_ATOMIC); + dev_dbg(dev, "allocate qm dma buf size=%zx)\n", qm->qdma.size); + if (!qm->qdma.va) { +- ret = -ENOMEM; +- goto err_alloc_qdma; ++ ret = -ENOMEM; ++ goto err_destroy_idr; + } + + QM_INIT_BUF(qm, eqe, QM_EQ_DEPTH); +@@ -6160,8 +6232,10 @@ static int hisi_qm_memory_init(struct hisi_qm *qm) + + err_alloc_qp_array: + dma_free_coherent(dev, qm->qdma.size, qm->qdma.va, qm->qdma.dma); +-err_alloc_qdma: +- kfree(qm->factor); ++err_destroy_idr: ++ idr_destroy(&qm->qp_idr); ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) ++ kfree(qm->factor); + + return ret; + } +@@ -6304,7 +6378,7 @@ void hisi_qm_pm_init(struct hisi_qm *qm) + { + struct device *dev = &qm->pdev->dev; + +- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps)) + return; + + pm_runtime_set_autosuspend_delay(dev, QM_AUTOSUSPEND_DELAY); +@@ -6323,7 +6397,7 @@ void hisi_qm_pm_uninit(struct hisi_qm *qm) + { + struct device *dev = &qm->pdev->dev; + +- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps)) + return; + + pm_runtime_get_noresume(dev); +diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c +index 2c0be91c0b094..1ec3b06345fd4 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_main.c ++++ b/drivers/crypto/hisilicon/sec2/sec_main.c +@@ -415,7 +415,7 @@ static void sec_open_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + /* Enable prefetch */ +@@ -435,7 +435,7 @@ static void sec_close_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + val = readl_relaxed(qm->io_base + SEC_PREFETCH_CFG); +diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c +index c3303d99acac7..65ed2ae8e1319 100644 +--- a/drivers/crypto/hisilicon/zip/zip_main.c ++++ b/drivers/crypto/hisilicon/zip/zip_main.c +@@ -348,7 +348,7 @@ static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + /* Enable prefetch */ +@@ -368,7 +368,7 @@ static void hisi_zip_close_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + val = readl_relaxed(qm->io_base + HZIP_PREFETCH_CFG); +diff --git a/drivers/crypto/img-hash.c b/drivers/crypto/img-hash.c +index d8e82d69745d8..9629e98bd68b7 100644 +--- a/drivers/crypto/img-hash.c ++++ b/drivers/crypto/img-hash.c +@@ -358,12 +358,16 @@ static int img_hash_dma_init(struct img_hash_dev *hdev) + static void img_hash_dma_task(unsigned long d) + { + struct img_hash_dev *hdev = (struct img_hash_dev *)d; +- struct img_hash_request_ctx *ctx = ahash_request_ctx(hdev->req); ++ struct img_hash_request_ctx *ctx; + u8 *addr; + size_t nbytes, bleft, wsend, len, tbc; + struct scatterlist tsg; + +- if (!hdev->req || !ctx->sg) ++ if (!hdev->req) ++ return; ++ ++ ctx = ahash_request_ctx(hdev->req); ++ if (!ctx->sg) + return; + + addr = sg_virt(ctx->sg); +diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c +index 655a7f5a406a1..cbeda59c6b191 100644 +--- a/drivers/crypto/omap-sham.c ++++ b/drivers/crypto/omap-sham.c +@@ -2114,7 +2114,7 @@ static int omap_sham_probe(struct platform_device *pdev) + + pm_runtime_enable(dev); + +- err = pm_runtime_get_sync(dev); ++ err = pm_runtime_resume_and_get(dev); + if (err < 0) { + dev_err(dev, "failed to get sync: %d\n", err); + goto err_pm; +diff --git a/drivers/crypto/qat/qat_4xxx/adf_drv.c b/drivers/crypto/qat/qat_4xxx/adf_drv.c +index 2f212561acc47..670a58b25cb16 100644 +--- a/drivers/crypto/qat/qat_4xxx/adf_drv.c ++++ b/drivers/crypto/qat/qat_4xxx/adf_drv.c +@@ -261,6 +261,7 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev); + if (!hw_data->accel_capabilities_mask) { + dev_err(&pdev->dev, "Failed to get capabilities mask.\n"); ++ ret = -EINVAL; + goto out_err; + } + +diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c +index 35d73061d1569..14a0aef18ab13 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -65,186 +65,24 @@ static void rk_crypto_disable_clk(struct rk_crypto_info *dev) + clk_disable_unprepare(dev->sclk); + } + +-static int check_alignment(struct scatterlist *sg_src, +- struct scatterlist *sg_dst, +- int align_mask) +-{ +- int in, out, align; +- +- in = IS_ALIGNED((uint32_t)sg_src->offset, 4) && +- IS_ALIGNED((uint32_t)sg_src->length, align_mask); +- if (!sg_dst) +- return in; +- out = IS_ALIGNED((uint32_t)sg_dst->offset, 4) && +- IS_ALIGNED((uint32_t)sg_dst->length, align_mask); +- align = in && out; +- +- return (align && (sg_src->length == sg_dst->length)); +-} +- +-static int rk_load_data(struct rk_crypto_info *dev, +- struct scatterlist *sg_src, +- struct scatterlist *sg_dst) +-{ +- unsigned int count; +- +- dev->aligned = dev->aligned ? +- check_alignment(sg_src, sg_dst, dev->align_size) : +- dev->aligned; +- if (dev->aligned) { +- count = min(dev->left_bytes, sg_src->length); +- dev->left_bytes -= count; +- +- if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) { +- dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n", +- __func__, __LINE__); +- return -EINVAL; +- } +- dev->addr_in = sg_dma_address(sg_src); +- +- if (sg_dst) { +- if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) { +- dev_err(dev->dev, +- "[%s:%d] dma_map_sg(dst) error\n", +- __func__, __LINE__); +- dma_unmap_sg(dev->dev, sg_src, 1, +- DMA_TO_DEVICE); +- return -EINVAL; +- } +- dev->addr_out = sg_dma_address(sg_dst); +- } +- } else { +- count = (dev->left_bytes > PAGE_SIZE) ? +- PAGE_SIZE : dev->left_bytes; +- +- if (!sg_pcopy_to_buffer(dev->first, dev->src_nents, +- dev->addr_vir, count, +- dev->total - dev->left_bytes)) { +- dev_err(dev->dev, "[%s:%d] pcopy err\n", +- __func__, __LINE__); +- return -EINVAL; +- } +- dev->left_bytes -= count; +- sg_init_one(&dev->sg_tmp, dev->addr_vir, count); +- if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1, DMA_TO_DEVICE)) { +- dev_err(dev->dev, "[%s:%d] dma_map_sg(sg_tmp) error\n", +- __func__, __LINE__); +- return -ENOMEM; +- } +- dev->addr_in = sg_dma_address(&dev->sg_tmp); +- +- if (sg_dst) { +- if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1, +- DMA_FROM_DEVICE)) { +- dev_err(dev->dev, +- "[%s:%d] dma_map_sg(sg_tmp) error\n", +- __func__, __LINE__); +- dma_unmap_sg(dev->dev, &dev->sg_tmp, 1, +- DMA_TO_DEVICE); +- return -ENOMEM; +- } +- dev->addr_out = sg_dma_address(&dev->sg_tmp); +- } +- } +- dev->count = count; +- return 0; +-} +- +-static void rk_unload_data(struct rk_crypto_info *dev) +-{ +- struct scatterlist *sg_in, *sg_out; +- +- sg_in = dev->aligned ? dev->sg_src : &dev->sg_tmp; +- dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE); +- +- if (dev->sg_dst) { +- sg_out = dev->aligned ? dev->sg_dst : &dev->sg_tmp; +- dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE); +- } +-} +- + static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) + { + struct rk_crypto_info *dev = platform_get_drvdata(dev_id); + u32 interrupt_status; + +- spin_lock(&dev->lock); + interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS); + CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status); + ++ dev->status = 1; + if (interrupt_status & 0x0a) { + dev_warn(dev->dev, "DMA Error\n"); +- dev->err = -EFAULT; ++ dev->status = 0; + } +- tasklet_schedule(&dev->done_task); ++ complete(&dev->complete); + +- spin_unlock(&dev->lock); + return IRQ_HANDLED; + } + +-static int rk_crypto_enqueue(struct rk_crypto_info *dev, +- struct crypto_async_request *async_req) +-{ +- unsigned long flags; +- int ret; +- +- spin_lock_irqsave(&dev->lock, flags); +- ret = crypto_enqueue_request(&dev->queue, async_req); +- if (dev->busy) { +- spin_unlock_irqrestore(&dev->lock, flags); +- return ret; +- } +- dev->busy = true; +- spin_unlock_irqrestore(&dev->lock, flags); +- tasklet_schedule(&dev->queue_task); +- +- return ret; +-} +- +-static void rk_crypto_queue_task_cb(unsigned long data) +-{ +- struct rk_crypto_info *dev = (struct rk_crypto_info *)data; +- struct crypto_async_request *async_req, *backlog; +- unsigned long flags; +- int err = 0; +- +- dev->err = 0; +- spin_lock_irqsave(&dev->lock, flags); +- backlog = crypto_get_backlog(&dev->queue); +- async_req = crypto_dequeue_request(&dev->queue); +- +- if (!async_req) { +- dev->busy = false; +- spin_unlock_irqrestore(&dev->lock, flags); +- return; +- } +- spin_unlock_irqrestore(&dev->lock, flags); +- +- if (backlog) { +- backlog->complete(backlog, -EINPROGRESS); +- backlog = NULL; +- } +- +- dev->async_req = async_req; +- err = dev->start(dev); +- if (err) +- dev->complete(dev->async_req, err); +-} +- +-static void rk_crypto_done_task_cb(unsigned long data) +-{ +- struct rk_crypto_info *dev = (struct rk_crypto_info *)data; +- +- if (dev->err) { +- dev->complete(dev->async_req, dev->err); +- return; +- } +- +- dev->err = dev->update(dev); +- if (dev->err) +- dev->complete(dev->async_req, dev->err); +-} +- + static struct rk_crypto_tmp *rk_cipher_algs[] = { + &rk_ecb_aes_alg, + &rk_cbc_aes_alg, +@@ -337,8 +175,6 @@ static int rk_crypto_probe(struct platform_device *pdev) + if (err) + goto err_crypto; + +- spin_lock_init(&crypto_info->lock); +- + crypto_info->reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(crypto_info->reg)) { + err = PTR_ERR(crypto_info->reg); +@@ -389,18 +225,11 @@ static int rk_crypto_probe(struct platform_device *pdev) + crypto_info->dev = &pdev->dev; + platform_set_drvdata(pdev, crypto_info); + +- tasklet_init(&crypto_info->queue_task, +- rk_crypto_queue_task_cb, (unsigned long)crypto_info); +- tasklet_init(&crypto_info->done_task, +- rk_crypto_done_task_cb, (unsigned long)crypto_info); +- crypto_init_queue(&crypto_info->queue, 50); ++ crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true); ++ crypto_engine_start(crypto_info->engine); ++ init_completion(&crypto_info->complete); + +- crypto_info->enable_clk = rk_crypto_enable_clk; +- crypto_info->disable_clk = rk_crypto_disable_clk; +- crypto_info->load_data = rk_load_data; +- crypto_info->unload_data = rk_unload_data; +- crypto_info->enqueue = rk_crypto_enqueue; +- crypto_info->busy = false; ++ rk_crypto_enable_clk(crypto_info); + + err = rk_crypto_register(crypto_info); + if (err) { +@@ -412,9 +241,9 @@ static int rk_crypto_probe(struct platform_device *pdev) + return 0; + + err_register_alg: +- tasklet_kill(&crypto_info->queue_task); +- tasklet_kill(&crypto_info->done_task); ++ crypto_engine_exit(crypto_info->engine); + err_crypto: ++ dev_err(dev, "Crypto Accelerator not successfully registered\n"); + return err; + } + +@@ -423,8 +252,8 @@ static int rk_crypto_remove(struct platform_device *pdev) + struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev); + + rk_crypto_unregister(); +- tasklet_kill(&crypto_tmp->done_task); +- tasklet_kill(&crypto_tmp->queue_task); ++ rk_crypto_disable_clk(crypto_tmp); ++ crypto_engine_exit(crypto_tmp->engine); + return 0; + } + +diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h +index 97278c2574ff9..045e811b4af84 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -5,9 +5,11 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include + #include + #include + +@@ -193,45 +195,15 @@ struct rk_crypto_info { + struct reset_control *rst; + void __iomem *reg; + int irq; +- struct crypto_queue queue; +- struct tasklet_struct queue_task; +- struct tasklet_struct done_task; +- struct crypto_async_request *async_req; +- int err; +- /* device lock */ +- spinlock_t lock; +- +- /* the public variable */ +- struct scatterlist *sg_src; +- struct scatterlist *sg_dst; +- struct scatterlist sg_tmp; +- struct scatterlist *first; +- unsigned int left_bytes; +- void *addr_vir; +- int aligned; +- int align_size; +- size_t src_nents; +- size_t dst_nents; +- unsigned int total; +- unsigned int count; +- dma_addr_t addr_in; +- dma_addr_t addr_out; +- bool busy; +- int (*start)(struct rk_crypto_info *dev); +- int (*update)(struct rk_crypto_info *dev); +- void (*complete)(struct crypto_async_request *base, int err); +- int (*enable_clk)(struct rk_crypto_info *dev); +- void (*disable_clk)(struct rk_crypto_info *dev); +- int (*load_data)(struct rk_crypto_info *dev, +- struct scatterlist *sg_src, +- struct scatterlist *sg_dst); +- void (*unload_data)(struct rk_crypto_info *dev); +- int (*enqueue)(struct rk_crypto_info *dev, +- struct crypto_async_request *async_req); ++ ++ struct crypto_engine *engine; ++ struct completion complete; ++ int status; + }; + + /* the private variable of hash */ + struct rk_ahash_ctx { ++ struct crypto_engine_ctx enginectx; + struct rk_crypto_info *dev; + /* for fallback */ + struct crypto_ahash *fallback_tfm; +@@ -241,14 +213,23 @@ struct rk_ahash_ctx { + struct rk_ahash_rctx { + struct ahash_request fallback_req; + u32 mode; ++ int nrsg; + }; + + /* the private variable of cipher */ + struct rk_cipher_ctx { ++ struct crypto_engine_ctx enginectx; + struct rk_crypto_info *dev; + unsigned int keylen; +- u32 mode; ++ u8 key[AES_MAX_KEY_SIZE]; + u8 iv[AES_BLOCK_SIZE]; ++ struct crypto_skcipher *fallback_tfm; ++}; ++ ++struct rk_cipher_rctx { ++ u8 backup_iv[AES_BLOCK_SIZE]; ++ u32 mode; ++ struct skcipher_request fallback_req; // keep at the end + }; + + enum alg_type { +diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +index ed03058497bc2..edd40e16a3f0a 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -9,6 +9,7 @@ + * Some ideas are from marvell/cesa.c and s5p-sss.c driver. + */ + #include ++#include + #include "rk3288_crypto.h" + + /* +@@ -16,6 +17,40 @@ + * so we put the fixed hash out when met zero message. + */ + ++static bool rk_ahash_need_fallback(struct ahash_request *req) ++{ ++ struct scatterlist *sg; ++ ++ sg = req->src; ++ while (sg) { ++ if (!IS_ALIGNED(sg->offset, sizeof(u32))) { ++ return true; ++ } ++ if (sg->length % 4) { ++ return true; ++ } ++ sg = sg_next(sg); ++ } ++ return false; ++} ++ ++static int rk_ahash_digest_fb(struct ahash_request *areq) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm); ++ ++ ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); ++ rctx->fallback_req.base.flags = areq->base.flags & ++ CRYPTO_TFM_REQ_MAY_SLEEP; ++ ++ rctx->fallback_req.nbytes = areq->nbytes; ++ rctx->fallback_req.src = areq->src; ++ rctx->fallback_req.result = areq->result; ++ ++ return crypto_ahash_digest(&rctx->fallback_req); ++} ++ + static int zero_message_process(struct ahash_request *req) + { + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); +@@ -38,16 +73,12 @@ static int zero_message_process(struct ahash_request *req) + return 0; + } + +-static void rk_ahash_crypto_complete(struct crypto_async_request *base, int err) +-{ +- if (base->complete) +- base->complete(base, err); +-} +- +-static void rk_ahash_reg_init(struct rk_crypto_info *dev) ++static void rk_ahash_reg_init(struct ahash_request *req) + { +- struct ahash_request *req = ahash_request_cast(dev->async_req); + struct rk_ahash_rctx *rctx = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ struct rk_crypto_info *dev = tctx->dev; + int reg_status; + + reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) | +@@ -74,7 +105,7 @@ static void rk_ahash_reg_init(struct rk_crypto_info *dev) + RK_CRYPTO_BYTESWAP_BRFIFO | + RK_CRYPTO_BYTESWAP_BTFIFO); + +- CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, dev->total); ++ CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, req->nbytes); + } + + static int rk_ahash_init(struct ahash_request *req) +@@ -167,48 +198,64 @@ static int rk_ahash_digest(struct ahash_request *req) + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm); + struct rk_crypto_info *dev = tctx->dev; + ++ if (rk_ahash_need_fallback(req)) ++ return rk_ahash_digest_fb(req); ++ + if (!req->nbytes) + return zero_message_process(req); +- else +- return dev->enqueue(dev, &req->base); ++ ++ return crypto_transfer_hash_request_to_engine(dev->engine, req); + } + +-static void crypto_ahash_dma_start(struct rk_crypto_info *dev) ++static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg) + { +- CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, dev->addr_in); +- CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, (dev->count + 3) / 4); ++ CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, sg_dma_address(sg)); ++ CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, sg_dma_len(sg) / 4); + CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_HASH_START | + (RK_CRYPTO_HASH_START << 16)); + } + +-static int rk_ahash_set_data_start(struct rk_crypto_info *dev) ++static int rk_hash_prepare(struct crypto_engine *engine, void *breq) ++{ ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ int ret; ++ ++ ret = dma_map_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); ++ if (ret <= 0) ++ return -EINVAL; ++ ++ rctx->nrsg = ret; ++ ++ return 0; ++} ++ ++static int rk_hash_unprepare(struct crypto_engine *engine, void *breq) + { +- int err; ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); + +- err = dev->load_data(dev, dev->sg_src, NULL); +- if (!err) +- crypto_ahash_dma_start(dev); +- return err; ++ dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE); ++ return 0; + } + +-static int rk_ahash_start(struct rk_crypto_info *dev) ++static int rk_hash_run(struct crypto_engine *engine, void *breq) + { +- struct ahash_request *req = ahash_request_cast(dev->async_req); +- struct crypto_ahash *tfm; +- struct rk_ahash_rctx *rctx; +- +- dev->total = req->nbytes; +- dev->left_bytes = req->nbytes; +- dev->aligned = 0; +- dev->align_size = 4; +- dev->sg_dst = NULL; +- dev->sg_src = req->src; +- dev->first = req->src; +- dev->src_nents = sg_nents(req->src); +- rctx = ahash_request_ctx(req); ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ struct scatterlist *sg = areq->src; ++ int err = 0; ++ int i; ++ u32 v; ++ + rctx->mode = 0; + +- tfm = crypto_ahash_reqtfm(req); + switch (crypto_ahash_digestsize(tfm)) { + case SHA1_DIGEST_SIZE: + rctx->mode = RK_CRYPTO_HASH_SHA1; +@@ -220,32 +267,26 @@ static int rk_ahash_start(struct rk_crypto_info *dev) + rctx->mode = RK_CRYPTO_HASH_MD5; + break; + default: +- return -EINVAL; ++ err = -EINVAL; ++ goto theend; + } + +- rk_ahash_reg_init(dev); +- return rk_ahash_set_data_start(dev); +-} +- +-static int rk_ahash_crypto_rx(struct rk_crypto_info *dev) +-{ +- int err = 0; +- struct ahash_request *req = ahash_request_cast(dev->async_req); +- struct crypto_ahash *tfm; +- +- dev->unload_data(dev); +- if (dev->left_bytes) { +- if (dev->aligned) { +- if (sg_is_last(dev->sg_src)) { +- dev_warn(dev->dev, "[%s:%d], Lack of data\n", +- __func__, __LINE__); +- err = -ENOMEM; +- goto out_rx; +- } +- dev->sg_src = sg_next(dev->sg_src); ++ rk_ahash_reg_init(areq); ++ ++ while (sg) { ++ reinit_completion(&tctx->dev->complete); ++ tctx->dev->status = 0; ++ crypto_ahash_dma_start(tctx->dev, sg); ++ wait_for_completion_interruptible_timeout(&tctx->dev->complete, ++ msecs_to_jiffies(2000)); ++ if (!tctx->dev->status) { ++ dev_err(tctx->dev->dev, "DMA timeout\n"); ++ err = -EFAULT; ++ goto theend; + } +- err = rk_ahash_set_data_start(dev); +- } else { ++ sg = sg_next(sg); ++ } ++ + /* + * it will take some time to process date after last dma + * transmission. +@@ -256,18 +297,20 @@ static int rk_ahash_crypto_rx(struct rk_crypto_info *dev) + * efficiency, and make it response quickly when dma + * complete. + */ +- while (!CRYPTO_READ(dev, RK_CRYPTO_HASH_STS)) +- udelay(10); +- +- tfm = crypto_ahash_reqtfm(req); +- memcpy_fromio(req->result, dev->reg + RK_CRYPTO_HASH_DOUT_0, +- crypto_ahash_digestsize(tfm)); +- dev->complete(dev->async_req, 0); +- tasklet_schedule(&dev->queue_task); ++ while (!CRYPTO_READ(tctx->dev, RK_CRYPTO_HASH_STS)) ++ udelay(10); ++ ++ for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) { ++ v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4); ++ put_unaligned_le32(v, areq->result + i * 4); + } + +-out_rx: +- return err; ++theend: ++ local_bh_disable(); ++ crypto_finalize_hash_request(engine, breq, err); ++ local_bh_enable(); ++ ++ return 0; + } + + static int rk_cra_hash_init(struct crypto_tfm *tfm) +@@ -281,14 +324,6 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm) + algt = container_of(alg, struct rk_crypto_tmp, alg.hash); + + tctx->dev = algt->dev; +- tctx->dev->addr_vir = (void *)__get_free_page(GFP_KERNEL); +- if (!tctx->dev->addr_vir) { +- dev_err(tctx->dev->dev, "failed to kmalloc for addr_vir\n"); +- return -ENOMEM; +- } +- tctx->dev->start = rk_ahash_start; +- tctx->dev->update = rk_ahash_crypto_rx; +- tctx->dev->complete = rk_ahash_crypto_complete; + + /* for fallback */ + tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0, +@@ -297,19 +332,23 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm) + dev_err(tctx->dev->dev, "Could not load fallback driver.\n"); + return PTR_ERR(tctx->fallback_tfm); + } ++ + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct rk_ahash_rctx) + + crypto_ahash_reqsize(tctx->fallback_tfm)); + +- return tctx->dev->enable_clk(tctx->dev); ++ tctx->enginectx.op.do_one_request = rk_hash_run; ++ tctx->enginectx.op.prepare_request = rk_hash_prepare; ++ tctx->enginectx.op.unprepare_request = rk_hash_unprepare; ++ ++ return 0; + } + + static void rk_cra_hash_exit(struct crypto_tfm *tfm) + { + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); + +- free_page((unsigned long)tctx->dev->addr_vir); +- return tctx->dev->disable_clk(tctx->dev); ++ crypto_free_ahash(tctx->fallback_tfm); + } + + struct rk_crypto_tmp rk_ahash_sha1 = { +diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +index 5bbf0d2722e11..67a7e05d5ae31 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -9,23 +9,77 @@ + * Some ideas are from marvell-cesa.c and s5p-sss.c driver. + */ + #include ++#include + #include "rk3288_crypto.h" + + #define RK_CRYPTO_DEC BIT(0) + +-static void rk_crypto_complete(struct crypto_async_request *base, int err) ++static int rk_cipher_need_fallback(struct skcipher_request *req) + { +- if (base->complete) +- base->complete(base, err); ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ unsigned int bs = crypto_skcipher_blocksize(tfm); ++ struct scatterlist *sgs, *sgd; ++ unsigned int stodo, dtodo, len; ++ ++ if (!req->cryptlen) ++ return true; ++ ++ len = req->cryptlen; ++ sgs = req->src; ++ sgd = req->dst; ++ while (sgs && sgd) { ++ if (!IS_ALIGNED(sgs->offset, sizeof(u32))) { ++ return true; ++ } ++ if (!IS_ALIGNED(sgd->offset, sizeof(u32))) { ++ return true; ++ } ++ stodo = min(len, sgs->length); ++ if (stodo % bs) { ++ return true; ++ } ++ dtodo = min(len, sgd->length); ++ if (dtodo % bs) { ++ return true; ++ } ++ if (stodo != dtodo) { ++ return true; ++ } ++ len -= stodo; ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); ++ } ++ return false; ++} ++ ++static int rk_cipher_fallback(struct skcipher_request *areq) ++{ ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); ++ struct rk_cipher_ctx *op = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq); ++ int err; ++ ++ skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm); ++ skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags, ++ areq->base.complete, areq->base.data); ++ skcipher_request_set_crypt(&rctx->fallback_req, areq->src, areq->dst, ++ areq->cryptlen, areq->iv); ++ if (rctx->mode & RK_CRYPTO_DEC) ++ err = crypto_skcipher_decrypt(&rctx->fallback_req); ++ else ++ err = crypto_skcipher_encrypt(&rctx->fallback_req); ++ return err; + } + + static int rk_handle_req(struct rk_crypto_info *dev, + struct skcipher_request *req) + { +- if (!IS_ALIGNED(req->cryptlen, dev->align_size)) +- return -EINVAL; +- else +- return dev->enqueue(dev, &req->base); ++ struct crypto_engine *engine = dev->engine; ++ ++ if (rk_cipher_need_fallback(req)) ++ return rk_cipher_fallback(req); ++ ++ return crypto_transfer_skcipher_request_to_engine(engine, req); + } + + static int rk_aes_setkey(struct crypto_skcipher *cipher, +@@ -38,8 +92,9 @@ static int rk_aes_setkey(struct crypto_skcipher *cipher, + keylen != AES_KEYSIZE_256) + return -EINVAL; + ctx->keylen = keylen; +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen); +- return 0; ++ memcpy(ctx->key, key, keylen); ++ ++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + + static int rk_des_setkey(struct crypto_skcipher *cipher, +@@ -53,8 +108,9 @@ static int rk_des_setkey(struct crypto_skcipher *cipher, + return err; + + ctx->keylen = keylen; +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); +- return 0; ++ memcpy(ctx->key, key, keylen); ++ ++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + + static int rk_tdes_setkey(struct crypto_skcipher *cipher, +@@ -68,17 +124,19 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher, + return err; + + ctx->keylen = keylen; +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); +- return 0; ++ memcpy(ctx->key, key, keylen); ++ ++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + + static int rk_aes_ecb_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_ECB_MODE; ++ rctx->mode = RK_CRYPTO_AES_ECB_MODE; + return rk_handle_req(dev, req); + } + +@@ -86,9 +144,10 @@ static int rk_aes_ecb_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -96,9 +155,10 @@ static int rk_aes_cbc_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_CBC_MODE; ++ rctx->mode = RK_CRYPTO_AES_CBC_MODE; + return rk_handle_req(dev, req); + } + +@@ -106,9 +166,10 @@ static int rk_aes_cbc_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -116,9 +177,10 @@ static int rk_des_ecb_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = 0; ++ rctx->mode = 0; + return rk_handle_req(dev, req); + } + +@@ -126,9 +188,10 @@ static int rk_des_ecb_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -136,9 +199,10 @@ static int rk_des_cbc_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC; ++ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC; + return rk_handle_req(dev, req); + } + +@@ -146,9 +210,10 @@ static int rk_des_cbc_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -156,9 +221,10 @@ static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT; ++ rctx->mode = RK_CRYPTO_TDES_SELECT; + return rk_handle_req(dev, req); + } + +@@ -166,9 +232,10 @@ static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -176,9 +243,10 @@ static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC; ++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC; + return rk_handle_req(dev, req); + } + +@@ -186,43 +254,42 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC | ++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC | + RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +-static void rk_ablk_hw_init(struct rk_crypto_info *dev) ++static void rk_ablk_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req) + { +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); + struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); +- u32 ivsize, block, conf_reg = 0; ++ u32 block, conf_reg = 0; + + block = crypto_tfm_alg_blocksize(tfm); +- ivsize = crypto_skcipher_ivsize(cipher); + + if (block == DES_BLOCK_SIZE) { +- ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE | ++ rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE | + RK_CRYPTO_TDES_BYTESWAP_KEY | + RK_CRYPTO_TDES_BYTESWAP_IV; +- CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode); +- memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize); ++ CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode); ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen); + conf_reg = RK_CRYPTO_DESSEL; + } else { +- ctx->mode |= RK_CRYPTO_AES_FIFO_MODE | ++ rctx->mode |= RK_CRYPTO_AES_FIFO_MODE | + RK_CRYPTO_AES_KEY_CHANGE | + RK_CRYPTO_AES_BYTESWAP_KEY | + RK_CRYPTO_AES_BYTESWAP_IV; + if (ctx->keylen == AES_KEYSIZE_192) +- ctx->mode |= RK_CRYPTO_AES_192BIT_key; ++ rctx->mode |= RK_CRYPTO_AES_192BIT_key; + else if (ctx->keylen == AES_KEYSIZE_256) +- ctx->mode |= RK_CRYPTO_AES_256BIT_key; +- CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode); +- memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize); ++ rctx->mode |= RK_CRYPTO_AES_256BIT_key; ++ CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode); ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen); + } + conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | + RK_CRYPTO_BYTESWAP_BRFIFO; +@@ -231,146 +298,138 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev) + RK_CRYPTO_BCDMA_ERR_ENA | RK_CRYPTO_BCDMA_DONE_ENA); + } + +-static void crypto_dma_start(struct rk_crypto_info *dev) ++static void crypto_dma_start(struct rk_crypto_info *dev, ++ struct scatterlist *sgs, ++ struct scatterlist *sgd, unsigned int todo) + { +- CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, dev->addr_in); +- CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, dev->count / 4); +- CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, dev->addr_out); ++ CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, sg_dma_address(sgs)); ++ CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, todo); ++ CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, sg_dma_address(sgd)); + CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_BLOCK_START | + _SBF(RK_CRYPTO_BLOCK_START, 16)); + } + +-static int rk_set_data_start(struct rk_crypto_info *dev) ++static int rk_cipher_run(struct crypto_engine *engine, void *async_req) + { +- int err; +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base); ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- u32 ivsize = crypto_skcipher_ivsize(tfm); +- u8 *src_last_blk = page_address(sg_page(dev->sg_src)) + +- dev->sg_src->offset + dev->sg_src->length - ivsize; +- +- /* Store the iv that need to be updated in chain mode. +- * And update the IV buffer to contain the next IV for decryption mode. +- */ +- if (ctx->mode & RK_CRYPTO_DEC) { +- memcpy(ctx->iv, src_last_blk, ivsize); +- sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv, +- ivsize, dev->total - ivsize); +- } +- +- err = dev->load_data(dev, dev->sg_src, dev->sg_dst); +- if (!err) +- crypto_dma_start(dev); +- return err; +-} +- +-static int rk_ablk_start(struct rk_crypto_info *dev) +-{ +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- unsigned long flags; ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq); ++ struct scatterlist *sgs, *sgd; + int err = 0; ++ int ivsize = crypto_skcipher_ivsize(tfm); ++ int offset; ++ u8 iv[AES_BLOCK_SIZE]; ++ u8 biv[AES_BLOCK_SIZE]; ++ u8 *ivtouse = areq->iv; ++ unsigned int len = areq->cryptlen; ++ unsigned int todo; ++ ++ ivsize = crypto_skcipher_ivsize(tfm); ++ if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) { ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ offset = areq->cryptlen - ivsize; ++ scatterwalk_map_and_copy(rctx->backup_iv, areq->src, ++ offset, ivsize, 0); ++ } ++ } + +- dev->left_bytes = req->cryptlen; +- dev->total = req->cryptlen; +- dev->sg_src = req->src; +- dev->first = req->src; +- dev->src_nents = sg_nents(req->src); +- dev->sg_dst = req->dst; +- dev->dst_nents = sg_nents(req->dst); +- dev->aligned = 1; +- +- spin_lock_irqsave(&dev->lock, flags); +- rk_ablk_hw_init(dev); +- err = rk_set_data_start(dev); +- spin_unlock_irqrestore(&dev->lock, flags); +- return err; +-} ++ sgs = areq->src; ++ sgd = areq->dst; + +-static void rk_iv_copyback(struct rk_crypto_info *dev) +-{ +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- u32 ivsize = crypto_skcipher_ivsize(tfm); +- +- /* Update the IV buffer to contain the next IV for encryption mode. */ +- if (!(ctx->mode & RK_CRYPTO_DEC)) { +- if (dev->aligned) { +- memcpy(req->iv, sg_virt(dev->sg_dst) + +- dev->sg_dst->length - ivsize, ivsize); ++ while (sgs && sgd && len) { ++ if (!sgs->length) { ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); ++ continue; ++ } ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ /* we backup last block of source to be used as IV at next step */ ++ offset = sgs->length - ivsize; ++ scatterwalk_map_and_copy(biv, sgs, offset, ivsize, 0); ++ } ++ if (sgs == sgd) { ++ err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ if (err <= 0) { ++ err = -EINVAL; ++ goto theend_iv; ++ } ++ } else { ++ err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); ++ if (err <= 0) { ++ err = -EINVAL; ++ goto theend_iv; ++ } ++ err = dma_map_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); ++ if (err <= 0) { ++ err = -EINVAL; ++ goto theend_sgs; ++ } ++ } ++ err = 0; ++ rk_ablk_hw_init(ctx->dev, areq); ++ if (ivsize) { ++ if (ivsize == DES_BLOCK_SIZE) ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize); ++ else ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize); ++ } ++ reinit_completion(&ctx->dev->complete); ++ ctx->dev->status = 0; ++ ++ todo = min(sg_dma_len(sgs), len); ++ len -= todo; ++ crypto_dma_start(ctx->dev, sgs, sgd, todo / 4); ++ wait_for_completion_interruptible_timeout(&ctx->dev->complete, ++ msecs_to_jiffies(2000)); ++ if (!ctx->dev->status) { ++ dev_err(ctx->dev->dev, "DMA timeout\n"); ++ err = -EFAULT; ++ goto theend; ++ } ++ if (sgs == sgd) { ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ } else { ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); ++ dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); ++ } ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ memcpy(iv, biv, ivsize); ++ ivtouse = iv; + } else { +- memcpy(req->iv, dev->addr_vir + +- dev->count - ivsize, ivsize); ++ offset = sgd->length - ivsize; ++ scatterwalk_map_and_copy(iv, sgd, offset, ivsize, 0); ++ ivtouse = iv; + } ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); + } +-} +- +-static void rk_update_iv(struct rk_crypto_info *dev) +-{ +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- u32 ivsize = crypto_skcipher_ivsize(tfm); +- u8 *new_iv = NULL; + +- if (ctx->mode & RK_CRYPTO_DEC) { +- new_iv = ctx->iv; +- } else { +- new_iv = page_address(sg_page(dev->sg_dst)) + +- dev->sg_dst->offset + dev->sg_dst->length - ivsize; ++ if (areq->iv && ivsize > 0) { ++ offset = areq->cryptlen - ivsize; ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ memcpy(areq->iv, rctx->backup_iv, ivsize); ++ memzero_explicit(rctx->backup_iv, ivsize); ++ } else { ++ scatterwalk_map_and_copy(areq->iv, areq->dst, offset, ++ ivsize, 0); ++ } + } + +- if (ivsize == DES_BLOCK_SIZE) +- memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize); +- else if (ivsize == AES_BLOCK_SIZE) +- memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize); +-} ++theend: ++ local_bh_disable(); ++ crypto_finalize_skcipher_request(engine, areq, err); ++ local_bh_enable(); ++ return 0; + +-/* return: +- * true some err was occurred +- * fault no err, continue +- */ +-static int rk_ablk_rx(struct rk_crypto_info *dev) +-{ +- int err = 0; +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- +- dev->unload_data(dev); +- if (!dev->aligned) { +- if (!sg_pcopy_from_buffer(req->dst, dev->dst_nents, +- dev->addr_vir, dev->count, +- dev->total - dev->left_bytes - +- dev->count)) { +- err = -EINVAL; +- goto out_rx; +- } +- } +- if (dev->left_bytes) { +- rk_update_iv(dev); +- if (dev->aligned) { +- if (sg_is_last(dev->sg_src)) { +- dev_err(dev->dev, "[%s:%d] Lack of data\n", +- __func__, __LINE__); +- err = -ENOMEM; +- goto out_rx; +- } +- dev->sg_src = sg_next(dev->sg_src); +- dev->sg_dst = sg_next(dev->sg_dst); +- } +- err = rk_set_data_start(dev); ++theend_sgs: ++ if (sgs == sgd) { ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); + } else { +- rk_iv_copyback(dev); +- /* here show the calculation is over without any err */ +- dev->complete(dev->async_req, 0); +- tasklet_schedule(&dev->queue_task); ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); ++ dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); + } +-out_rx: ++theend_iv: + return err; + } + +@@ -378,26 +437,34 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) + { + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ const char *name = crypto_tfm_alg_name(&tfm->base); + struct rk_crypto_tmp *algt; + + algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + + ctx->dev = algt->dev; +- ctx->dev->align_size = crypto_tfm_alg_alignmask(crypto_skcipher_tfm(tfm)) + 1; +- ctx->dev->start = rk_ablk_start; +- ctx->dev->update = rk_ablk_rx; +- ctx->dev->complete = rk_crypto_complete; +- ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL); + +- return ctx->dev->addr_vir ? ctx->dev->enable_clk(ctx->dev) : -ENOMEM; ++ ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK); ++ if (IS_ERR(ctx->fallback_tfm)) { ++ dev_err(ctx->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n", ++ name, PTR_ERR(ctx->fallback_tfm)); ++ return PTR_ERR(ctx->fallback_tfm); ++ } ++ ++ tfm->reqsize = sizeof(struct rk_cipher_rctx) + ++ crypto_skcipher_reqsize(ctx->fallback_tfm); ++ ++ ctx->enginectx.op.do_one_request = rk_cipher_run; ++ ++ return 0; + } + + static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) + { + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + +- free_page((unsigned long)ctx->dev->addr_vir); +- ctx->dev->disable_clk(ctx->dev); ++ memzero_explicit(ctx->key, ctx->keylen); ++ crypto_free_skcipher(ctx->fallback_tfm); + } + + struct rk_crypto_tmp rk_ecb_aes_alg = { +@@ -406,7 +473,7 @@ struct rk_crypto_tmp rk_ecb_aes_alg = { + .base.cra_name = "ecb(aes)", + .base.cra_driver_name = "ecb-aes-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x0f, +@@ -428,7 +495,7 @@ struct rk_crypto_tmp rk_cbc_aes_alg = { + .base.cra_name = "cbc(aes)", + .base.cra_driver_name = "cbc-aes-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x0f, +@@ -451,7 +518,7 @@ struct rk_crypto_tmp rk_ecb_des_alg = { + .base.cra_name = "ecb(des)", + .base.cra_driver_name = "ecb-des-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +@@ -473,7 +540,7 @@ struct rk_crypto_tmp rk_cbc_des_alg = { + .base.cra_name = "cbc(des)", + .base.cra_driver_name = "cbc-des-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +@@ -496,7 +563,7 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = { + .base.cra_name = "ecb(des3_ede)", + .base.cra_driver_name = "ecb-des3-ede-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +@@ -518,7 +585,7 @@ struct rk_crypto_tmp rk_cbc_des3_ede_alg = { + .base.cra_name = "cbc(des3_ede)", + .base.cra_driver_name = "cbc-des3-ede-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c +index 0e5a5662d5a40..0a051d6568800 100644 +--- a/drivers/dio/dio.c ++++ b/drivers/dio/dio.c +@@ -109,6 +109,12 @@ static char dio_no_name[] = { 0 }; + + #endif /* CONFIG_DIO_CONSTANTS */ + ++static void dio_dev_release(struct device *dev) ++{ ++ struct dio_dev *ddev = container_of(dev, typeof(struct dio_dev), dev); ++ kfree(ddev); ++} ++ + int __init dio_find(int deviceid) + { + /* Called to find a DIO device before the full bus scan has run. +@@ -225,6 +231,7 @@ static int __init dio_init(void) + dev->bus = &dio_bus; + dev->dev.parent = &dio_bus.dev; + dev->dev.bus = &dio_bus_type; ++ dev->dev.release = dio_dev_release; + dev->scode = scode; + dev->resource.start = pa; + dev->resource.end = pa + DIO_SIZE(scode, va); +@@ -252,6 +259,7 @@ static int __init dio_init(void) + if (error) { + pr_err("DIO: Error registering device %s\n", + dev->name); ++ put_device(&dev->dev); + continue; + } + error = dio_create_sysfs_dev_files(dev); +diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c +index 6780761a16403..e3334762be853 100644 +--- a/drivers/dma/apple-admac.c ++++ b/drivers/dma/apple-admac.c +@@ -20,6 +20,12 @@ + #define NCHANNELS_MAX 64 + #define IRQ_NOUTPUTS 4 + ++/* ++ * For allocation purposes we split the cache ++ * memory into blocks of fixed size (given in bytes). ++ */ ++#define SRAM_BLOCK 2048 ++ + #define RING_WRITE_SLOT GENMASK(1, 0) + #define RING_READ_SLOT GENMASK(5, 4) + #define RING_FULL BIT(9) +@@ -35,6 +41,9 @@ + #define REG_TX_STOP 0x0004 + #define REG_RX_START 0x0008 + #define REG_RX_STOP 0x000c ++#define REG_IMPRINT 0x0090 ++#define REG_TX_SRAM_SIZE 0x0094 ++#define REG_RX_SRAM_SIZE 0x0098 + + #define REG_CHAN_CTL(ch) (0x8000 + (ch) * 0x200) + #define REG_CHAN_CTL_RST_RINGS BIT(0) +@@ -52,7 +61,9 @@ + #define BUS_WIDTH_FRAME_2_WORDS 0x10 + #define BUS_WIDTH_FRAME_4_WORDS 0x20 + +-#define CHAN_BUFSIZE 0x8000 ++#define REG_CHAN_SRAM_CARVEOUT(ch) (0x8050 + (ch) * 0x200) ++#define CHAN_SRAM_CARVEOUT_SIZE GENMASK(31, 16) ++#define CHAN_SRAM_CARVEOUT_BASE GENMASK(15, 0) + + #define REG_CHAN_FIFOCTL(ch) (0x8054 + (ch) * 0x200) + #define CHAN_FIFOCTL_LIMIT GENMASK(31, 16) +@@ -75,6 +86,8 @@ struct admac_chan { + struct dma_chan chan; + struct tasklet_struct tasklet; + ++ u32 carveout; ++ + spinlock_t lock; + struct admac_tx *current_tx; + int nperiod_acks; +@@ -91,11 +104,24 @@ struct admac_chan { + struct list_head to_free; + }; + ++struct admac_sram { ++ u32 size; ++ /* ++ * SRAM_CARVEOUT has 16-bit fields, so the SRAM cannot be larger than ++ * 64K and a 32-bit bitfield over 2K blocks covers it. ++ */ ++ u32 allocated; ++}; ++ + struct admac_data { + struct dma_device dma; + struct device *dev; + __iomem void *base; + ++ struct mutex cache_alloc_lock; ++ struct admac_sram txcache, rxcache; ++ ++ int irq; + int irq_index; + int nchannels; + struct admac_chan channels[]; +@@ -115,6 +141,60 @@ struct admac_tx { + struct list_head node; + }; + ++static int admac_alloc_sram_carveout(struct admac_data *ad, ++ enum dma_transfer_direction dir, ++ u32 *out) ++{ ++ struct admac_sram *sram; ++ int i, ret = 0, nblocks; ++ ++ if (dir == DMA_MEM_TO_DEV) ++ sram = &ad->txcache; ++ else ++ sram = &ad->rxcache; ++ ++ mutex_lock(&ad->cache_alloc_lock); ++ ++ nblocks = sram->size / SRAM_BLOCK; ++ for (i = 0; i < nblocks; i++) ++ if (!(sram->allocated & BIT(i))) ++ break; ++ ++ if (i < nblocks) { ++ *out = FIELD_PREP(CHAN_SRAM_CARVEOUT_BASE, i * SRAM_BLOCK) | ++ FIELD_PREP(CHAN_SRAM_CARVEOUT_SIZE, SRAM_BLOCK); ++ sram->allocated |= BIT(i); ++ } else { ++ ret = -EBUSY; ++ } ++ ++ mutex_unlock(&ad->cache_alloc_lock); ++ ++ return ret; ++} ++ ++static void admac_free_sram_carveout(struct admac_data *ad, ++ enum dma_transfer_direction dir, ++ u32 carveout) ++{ ++ struct admac_sram *sram; ++ u32 base = FIELD_GET(CHAN_SRAM_CARVEOUT_BASE, carveout); ++ int i; ++ ++ if (dir == DMA_MEM_TO_DEV) ++ sram = &ad->txcache; ++ else ++ sram = &ad->rxcache; ++ ++ if (WARN_ON(base >= sram->size)) ++ return; ++ ++ mutex_lock(&ad->cache_alloc_lock); ++ i = base / SRAM_BLOCK; ++ sram->allocated &= ~BIT(i); ++ mutex_unlock(&ad->cache_alloc_lock); ++} ++ + static void admac_modify(struct admac_data *ad, int reg, u32 mask, u32 val) + { + void __iomem *addr = ad->base + reg; +@@ -463,15 +543,28 @@ static void admac_synchronize(struct dma_chan *chan) + static int admac_alloc_chan_resources(struct dma_chan *chan) + { + struct admac_chan *adchan = to_admac_chan(chan); ++ struct admac_data *ad = adchan->host; ++ int ret; + + dma_cookie_init(&adchan->chan); ++ ret = admac_alloc_sram_carveout(ad, admac_chan_direction(adchan->no), ++ &adchan->carveout); ++ if (ret < 0) ++ return ret; ++ ++ writel_relaxed(adchan->carveout, ++ ad->base + REG_CHAN_SRAM_CARVEOUT(adchan->no)); + return 0; + } + + static void admac_free_chan_resources(struct dma_chan *chan) + { ++ struct admac_chan *adchan = to_admac_chan(chan); ++ + admac_terminate_all(chan); + admac_synchronize(chan); ++ admac_free_sram_carveout(adchan->host, admac_chan_direction(adchan->no), ++ adchan->carveout); + } + + static struct dma_chan *admac_dma_of_xlate(struct of_phandle_args *dma_spec, +@@ -709,6 +802,7 @@ static int admac_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, ad); + ad->dev = &pdev->dev; + ad->nchannels = nchannels; ++ mutex_init(&ad->cache_alloc_lock); + + /* + * The controller has 4 IRQ outputs. Try them all until +@@ -724,12 +818,7 @@ static int admac_probe(struct platform_device *pdev) + + if (irq < 0) + return dev_err_probe(&pdev->dev, irq, "no usable interrupt\n"); +- +- err = devm_request_irq(&pdev->dev, irq, admac_interrupt, +- 0, dev_name(&pdev->dev), ad); +- if (err) +- return dev_err_probe(&pdev->dev, err, +- "unable to register interrupt\n"); ++ ad->irq = irq; + + ad->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ad->base)) +@@ -774,17 +863,36 @@ static int admac_probe(struct platform_device *pdev) + tasklet_setup(&adchan->tasklet, admac_chan_tasklet); + } + +- err = dma_async_device_register(&ad->dma); ++ err = request_irq(irq, admac_interrupt, 0, dev_name(&pdev->dev), ad); + if (err) +- return dev_err_probe(&pdev->dev, err, "failed to register DMA device\n"); ++ return dev_err_probe(&pdev->dev, err, ++ "unable to register interrupt\n"); ++ ++ err = dma_async_device_register(&ad->dma); ++ if (err) { ++ dev_err_probe(&pdev->dev, err, "failed to register DMA device\n"); ++ goto free_irq; ++ } + + err = of_dma_controller_register(pdev->dev.of_node, admac_dma_of_xlate, ad); + if (err) { + dma_async_device_unregister(&ad->dma); +- return dev_err_probe(&pdev->dev, err, "failed to register with OF\n"); ++ dev_err_probe(&pdev->dev, err, "failed to register with OF\n"); ++ goto free_irq; + } + ++ ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE); ++ ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE); ++ ++ dev_info(&pdev->dev, "Audio DMA Controller\n"); ++ dev_info(&pdev->dev, "imprint %x TX cache %u RX cache %u\n", ++ readl_relaxed(ad->base + REG_IMPRINT), ad->txcache.size, ad->rxcache.size); ++ + return 0; ++ ++free_irq: ++ free_irq(ad->irq, ad); ++ return err; + } + + static int admac_remove(struct platform_device *pdev) +@@ -793,6 +901,7 @@ static int admac_remove(struct platform_device *pdev) + + of_dma_controller_free(pdev->dev.of_node); + dma_async_device_unregister(&ad->dma); ++ free_irq(ad->irq, ad); + + return 0; + } +diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c +index 6cf50ee0b77c5..e0af60833d28c 100644 +--- a/drivers/edac/i10nm_base.c ++++ b/drivers/edac/i10nm_base.c +@@ -198,11 +198,10 @@ static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus, + if (unlikely(pci_enable_device(pdev) < 0)) { + edac_dbg(2, "Failed to enable device %02x:%02x.%x\n", + bus, dev, fun); ++ pci_dev_put(pdev); + return NULL; + } + +- pci_dev_get(pdev); +- + return pdev; + } + +diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig +index dca7cecb37e34..290186e44e6bd 100644 +--- a/drivers/extcon/Kconfig ++++ b/drivers/extcon/Kconfig +@@ -183,7 +183,7 @@ config EXTCON_USBC_CROS_EC + + config EXTCON_USBC_TUSB320 + tristate "TI TUSB320 USB-C extcon support" +- depends on I2C ++ depends on I2C && TYPEC + select REGMAP_I2C + help + Say Y here to enable support for USB Type C cable detection extcon +diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c +index 6ba3d89b106d0..7223c4b9dc707 100644 +--- a/drivers/extcon/extcon-usbc-tusb320.c ++++ b/drivers/extcon/extcon-usbc-tusb320.c +@@ -6,6 +6,7 @@ + * Author: Michael Auchter + */ + ++#include + #include + #include + #include +@@ -13,6 +14,24 @@ + #include + #include + #include ++#include ++ ++#define TUSB320_REG8 0x8 ++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE GENMASK(7, 6) ++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE_USB 0x0 ++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE_15A 0x1 ++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE_30A 0x2 ++#define TUSB320_REG8_CURRENT_MODE_DETECT GENMASK(5, 4) ++#define TUSB320_REG8_CURRENT_MODE_DETECT_DEF 0x0 ++#define TUSB320_REG8_CURRENT_MODE_DETECT_MED 0x1 ++#define TUSB320_REG8_CURRENT_MODE_DETECT_ACC 0x2 ++#define TUSB320_REG8_CURRENT_MODE_DETECT_HI 0x3 ++#define TUSB320_REG8_ACCESSORY_CONNECTED GENMASK(3, 2) ++#define TUSB320_REG8_ACCESSORY_CONNECTED_NONE 0x0 ++#define TUSB320_REG8_ACCESSORY_CONNECTED_AUDIO 0x4 ++#define TUSB320_REG8_ACCESSORY_CONNECTED_ACC 0x5 ++#define TUSB320_REG8_ACCESSORY_CONNECTED_DEBUG 0x6 ++#define TUSB320_REG8_ACTIVE_CABLE_DETECTION BIT(0) + + #define TUSB320_REG9 0x9 + #define TUSB320_REG9_ATTACHED_STATE_SHIFT 6 +@@ -55,6 +74,10 @@ struct tusb320_priv { + struct extcon_dev *edev; + struct tusb320_ops *ops; + enum tusb320_attached_state state; ++ struct typec_port *port; ++ struct typec_capability cap; ++ enum typec_port_type port_type; ++ enum typec_pwr_opmode pwr_opmode; + }; + + static const char * const tusb_attached_states[] = { +@@ -184,19 +207,47 @@ static struct tusb320_ops tusb320l_ops = { + .get_revision = tusb320l_get_revision, + }; + +-static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) ++static int tusb320_set_adv_pwr_mode(struct tusb320_priv *priv) + { +- struct tusb320_priv *priv = dev_id; +- int state, polarity; +- unsigned reg; ++ u8 mode; ++ ++ if (priv->pwr_opmode == TYPEC_PWR_MODE_USB) ++ mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_USB; ++ else if (priv->pwr_opmode == TYPEC_PWR_MODE_1_5A) ++ mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_15A; ++ else if (priv->pwr_opmode == TYPEC_PWR_MODE_3_0A) ++ mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_30A; ++ else /* No other mode is supported. */ ++ return -EINVAL; + +- if (regmap_read(priv->regmap, TUSB320_REG9, ®)) { +- dev_err(priv->dev, "error during i2c read!\n"); +- return IRQ_NONE; +- } ++ return regmap_write_bits(priv->regmap, TUSB320_REG8, ++ TUSB320_REG8_CURRENT_MODE_ADVERTISE, ++ FIELD_PREP(TUSB320_REG8_CURRENT_MODE_ADVERTISE, ++ mode)); ++} + +- if (!(reg & TUSB320_REG9_INTERRUPT_STATUS)) +- return IRQ_NONE; ++static int tusb320_port_type_set(struct typec_port *port, ++ enum typec_port_type type) ++{ ++ struct tusb320_priv *priv = typec_get_drvdata(port); ++ ++ if (type == TYPEC_PORT_SRC) ++ return priv->ops->set_mode(priv, TUSB320_MODE_DFP); ++ else if (type == TYPEC_PORT_SNK) ++ return priv->ops->set_mode(priv, TUSB320_MODE_UFP); ++ else if (type == TYPEC_PORT_DRP) ++ return priv->ops->set_mode(priv, TUSB320_MODE_DRP); ++ else ++ return priv->ops->set_mode(priv, TUSB320_MODE_PORT); ++} ++ ++static const struct typec_operations tusb320_typec_ops = { ++ .port_type_set = tusb320_port_type_set, ++}; ++ ++static void tusb320_extcon_irq_handler(struct tusb320_priv *priv, u8 reg) ++{ ++ int state, polarity; + + state = (reg >> TUSB320_REG9_ATTACHED_STATE_SHIFT) & + TUSB320_REG9_ATTACHED_STATE_MASK; +@@ -219,19 +270,166 @@ static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) + extcon_sync(priv->edev, EXTCON_USB_HOST); + + priv->state = state; ++} ++ ++static void tusb320_typec_irq_handler(struct tusb320_priv *priv, u8 reg9) ++{ ++ struct typec_port *port = priv->port; ++ struct device *dev = priv->dev; ++ u8 mode, role, state; ++ int ret, reg8; ++ bool ori; ++ ++ ori = reg9 & TUSB320_REG9_CABLE_DIRECTION; ++ typec_set_orientation(port, ori ? TYPEC_ORIENTATION_REVERSE : ++ TYPEC_ORIENTATION_NORMAL); ++ ++ state = (reg9 >> TUSB320_REG9_ATTACHED_STATE_SHIFT) & ++ TUSB320_REG9_ATTACHED_STATE_MASK; ++ if (state == TUSB320_ATTACHED_STATE_DFP) ++ role = TYPEC_SOURCE; ++ else ++ role = TYPEC_SINK; ++ ++ typec_set_vconn_role(port, role); ++ typec_set_pwr_role(port, role); ++ typec_set_data_role(port, role == TYPEC_SOURCE ? ++ TYPEC_HOST : TYPEC_DEVICE); ++ ++ ret = regmap_read(priv->regmap, TUSB320_REG8, ®8); ++ if (ret) { ++ dev_err(dev, "error during reg8 i2c read, ret=%d!\n", ret); ++ return; ++ } ++ ++ mode = FIELD_GET(TUSB320_REG8_CURRENT_MODE_DETECT, reg8); ++ if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_DEF) ++ typec_set_pwr_opmode(port, TYPEC_PWR_MODE_USB); ++ else if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_MED) ++ typec_set_pwr_opmode(port, TYPEC_PWR_MODE_1_5A); ++ else if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_HI) ++ typec_set_pwr_opmode(port, TYPEC_PWR_MODE_3_0A); ++ else /* Charge through accessory */ ++ typec_set_pwr_opmode(port, TYPEC_PWR_MODE_USB); ++} ++ ++static irqreturn_t tusb320_state_update_handler(struct tusb320_priv *priv, ++ bool force_update) ++{ ++ unsigned int reg; ++ ++ if (regmap_read(priv->regmap, TUSB320_REG9, ®)) { ++ dev_err(priv->dev, "error during i2c read!\n"); ++ return IRQ_NONE; ++ } ++ ++ if (!force_update && !(reg & TUSB320_REG9_INTERRUPT_STATUS)) ++ return IRQ_NONE; ++ ++ tusb320_extcon_irq_handler(priv, reg); ++ ++ /* ++ * Type-C support is optional. Only call the Type-C handler if a ++ * port had been registered previously. ++ */ ++ if (priv->port) ++ tusb320_typec_irq_handler(priv, reg); + + regmap_write(priv->regmap, TUSB320_REG9, reg); + + return IRQ_HANDLED; + } + ++static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) ++{ ++ struct tusb320_priv *priv = dev_id; ++ ++ return tusb320_state_update_handler(priv, false); ++} ++ + static const struct regmap_config tusb320_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + }; + +-static int tusb320_extcon_probe(struct i2c_client *client, +- const struct i2c_device_id *id) ++static int tusb320_extcon_probe(struct tusb320_priv *priv) ++{ ++ int ret; ++ ++ priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable); ++ if (IS_ERR(priv->edev)) { ++ dev_err(priv->dev, "failed to allocate extcon device\n"); ++ return PTR_ERR(priv->edev); ++ } ++ ++ ret = devm_extcon_dev_register(priv->dev, priv->edev); ++ if (ret < 0) { ++ dev_err(priv->dev, "failed to register extcon device\n"); ++ return ret; ++ } ++ ++ extcon_set_property_capability(priv->edev, EXTCON_USB, ++ EXTCON_PROP_USB_TYPEC_POLARITY); ++ extcon_set_property_capability(priv->edev, EXTCON_USB_HOST, ++ EXTCON_PROP_USB_TYPEC_POLARITY); ++ ++ return 0; ++} ++ ++static int tusb320_typec_probe(struct i2c_client *client, ++ struct tusb320_priv *priv) ++{ ++ struct fwnode_handle *connector; ++ const char *cap_str; ++ int ret; ++ ++ /* The Type-C connector is optional, for backward compatibility. */ ++ connector = device_get_named_child_node(&client->dev, "connector"); ++ if (!connector) ++ return 0; ++ ++ /* Type-C connector found. */ ++ ret = typec_get_fw_cap(&priv->cap, connector); ++ if (ret) ++ return ret; ++ ++ priv->port_type = priv->cap.type; ++ ++ /* This goes into register 0x8 field CURRENT_MODE_ADVERTISE */ ++ ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str); ++ if (ret) ++ return ret; ++ ++ ret = typec_find_pwr_opmode(cap_str); ++ if (ret < 0) ++ return ret; ++ if (ret == TYPEC_PWR_MODE_PD) ++ return -EINVAL; ++ ++ priv->pwr_opmode = ret; ++ ++ /* Initialize the hardware with the devicetree settings. */ ++ ret = tusb320_set_adv_pwr_mode(priv); ++ if (ret) ++ return ret; ++ ++ priv->cap.revision = USB_TYPEC_REV_1_1; ++ priv->cap.accessory[0] = TYPEC_ACCESSORY_AUDIO; ++ priv->cap.accessory[1] = TYPEC_ACCESSORY_DEBUG; ++ priv->cap.orientation_aware = true; ++ priv->cap.driver_data = priv; ++ priv->cap.ops = &tusb320_typec_ops; ++ priv->cap.fwnode = connector; ++ ++ priv->port = typec_register_port(&client->dev, &priv->cap); ++ if (IS_ERR(priv->port)) ++ return PTR_ERR(priv->port); ++ ++ return 0; ++} ++ ++static int tusb320_probe(struct i2c_client *client, ++ const struct i2c_device_id *id) + { + struct tusb320_priv *priv; + const void *match_data; +@@ -257,12 +455,6 @@ static int tusb320_extcon_probe(struct i2c_client *client, + + priv->ops = (struct tusb320_ops*)match_data; + +- priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable); +- if (IS_ERR(priv->edev)) { +- dev_err(priv->dev, "failed to allocate extcon device\n"); +- return PTR_ERR(priv->edev); +- } +- + if (priv->ops->get_revision) { + ret = priv->ops->get_revision(priv, &revision); + if (ret) +@@ -272,19 +464,16 @@ static int tusb320_extcon_probe(struct i2c_client *client, + dev_info(priv->dev, "chip revision %d\n", revision); + } + +- ret = devm_extcon_dev_register(priv->dev, priv->edev); +- if (ret < 0) { +- dev_err(priv->dev, "failed to register extcon device\n"); ++ ret = tusb320_extcon_probe(priv); ++ if (ret) + return ret; +- } + +- extcon_set_property_capability(priv->edev, EXTCON_USB, +- EXTCON_PROP_USB_TYPEC_POLARITY); +- extcon_set_property_capability(priv->edev, EXTCON_USB_HOST, +- EXTCON_PROP_USB_TYPEC_POLARITY); ++ ret = tusb320_typec_probe(client, priv); ++ if (ret) ++ return ret; + + /* update initial state */ +- tusb320_irq_handler(client->irq, priv); ++ tusb320_state_update_handler(priv, true); + + /* Reset chip to its default state */ + ret = tusb320_reset(priv); +@@ -295,7 +484,7 @@ static int tusb320_extcon_probe(struct i2c_client *client, + * State and polarity might change after a reset, so update + * them again and make sure the interrupt status bit is cleared. + */ +- tusb320_irq_handler(client->irq, priv); ++ tusb320_state_update_handler(priv, true); + + ret = devm_request_threaded_irq(priv->dev, client->irq, NULL, + tusb320_irq_handler, +@@ -313,7 +502,7 @@ static const struct of_device_id tusb320_extcon_dt_match[] = { + MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match); + + static struct i2c_driver tusb320_extcon_driver = { +- .probe = tusb320_extcon_probe, ++ .probe = tusb320_probe, + .driver = { + .name = "extcon-tusb320", + .of_match_table = tusb320_extcon_dt_match, +diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c +index 4b8978b254f9a..dba315f675bc7 100644 +--- a/drivers/firmware/raspberrypi.c ++++ b/drivers/firmware/raspberrypi.c +@@ -272,6 +272,7 @@ static int rpi_firmware_probe(struct platform_device *pdev) + int ret = PTR_ERR(fw->chan); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get mbox channel: %d\n", ret); ++ kfree(fw); + return ret; + } + +diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c +index ebc32bbd9b833..6281e7153b475 100644 +--- a/drivers/firmware/ti_sci.c ++++ b/drivers/firmware/ti_sci.c +@@ -429,15 +429,14 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info, + * during noirq phase, so we must manually poll the completion. + */ + ret = read_poll_timeout_atomic(try_wait_for_completion, done_state, +- true, 1, ++ done_state, 1, + info->desc->max_rx_timeout_ms * 1000, + false, &xfer->done); + } + +- if (ret == -ETIMEDOUT || !done_state) { ++ if (ret == -ETIMEDOUT) + dev_err(dev, "Mbox timedout in resp(caller: %pS)\n", + (void *)_RET_IP_); +- } + + /* + * NOTE: we might prefer not to need the mailbox ticker to manage the +diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c +index 92f185575e941..12e068dc60bc2 100644 +--- a/drivers/gpio/gpiolib-cdev.c ++++ b/drivers/gpio/gpiolib-cdev.c +@@ -55,6 +55,50 @@ static_assert(IS_ALIGNED(sizeof(struct gpio_v2_line_values), 8)); + * interface to gpiolib GPIOs via ioctl()s. + */ + ++typedef __poll_t (*poll_fn)(struct file *, struct poll_table_struct *); ++typedef long (*ioctl_fn)(struct file *, unsigned int, unsigned long); ++typedef ssize_t (*read_fn)(struct file *, char __user *, ++ size_t count, loff_t *); ++ ++static __poll_t call_poll_locked(struct file *file, ++ struct poll_table_struct *wait, ++ struct gpio_device *gdev, poll_fn func) ++{ ++ __poll_t ret; ++ ++ down_read(&gdev->sem); ++ ret = func(file, wait); ++ up_read(&gdev->sem); ++ ++ return ret; ++} ++ ++static long call_ioctl_locked(struct file *file, unsigned int cmd, ++ unsigned long arg, struct gpio_device *gdev, ++ ioctl_fn func) ++{ ++ long ret; ++ ++ down_read(&gdev->sem); ++ ret = func(file, cmd, arg); ++ up_read(&gdev->sem); ++ ++ return ret; ++} ++ ++static ssize_t call_read_locked(struct file *file, char __user *buf, ++ size_t count, loff_t *f_ps, ++ struct gpio_device *gdev, read_fn func) ++{ ++ ssize_t ret; ++ ++ down_read(&gdev->sem); ++ ret = func(file, buf, count, f_ps); ++ up_read(&gdev->sem); ++ ++ return ret; ++} ++ + /* + * GPIO line handle management + */ +@@ -191,8 +235,8 @@ static long linehandle_set_config(struct linehandle_state *lh, + return 0; + } + +-static long linehandle_ioctl(struct file *file, unsigned int cmd, +- unsigned long arg) ++static long linehandle_ioctl_unlocked(struct file *file, unsigned int cmd, ++ unsigned long arg) + { + struct linehandle_state *lh = file->private_data; + void __user *ip = (void __user *)arg; +@@ -201,6 +245,9 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd, + unsigned int i; + int ret; + ++ if (!lh->gdev->chip) ++ return -ENODEV; ++ + switch (cmd) { + case GPIOHANDLE_GET_LINE_VALUES_IOCTL: + /* NOTE: It's okay to read values of output lines */ +@@ -247,6 +294,15 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd, + } + } + ++static long linehandle_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct linehandle_state *lh = file->private_data; ++ ++ return call_ioctl_locked(file, cmd, arg, lh->gdev, ++ linehandle_ioctl_unlocked); ++} ++ + #ifdef CONFIG_COMPAT + static long linehandle_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +@@ -1378,12 +1434,15 @@ static long linereq_set_config(struct linereq *lr, void __user *ip) + return ret; + } + +-static long linereq_ioctl(struct file *file, unsigned int cmd, +- unsigned long arg) ++static long linereq_ioctl_unlocked(struct file *file, unsigned int cmd, ++ unsigned long arg) + { + struct linereq *lr = file->private_data; + void __user *ip = (void __user *)arg; + ++ if (!lr->gdev->chip) ++ return -ENODEV; ++ + switch (cmd) { + case GPIO_V2_LINE_GET_VALUES_IOCTL: + return linereq_get_values(lr, ip); +@@ -1396,6 +1455,15 @@ static long linereq_ioctl(struct file *file, unsigned int cmd, + } + } + ++static long linereq_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct linereq *lr = file->private_data; ++ ++ return call_ioctl_locked(file, cmd, arg, lr->gdev, ++ linereq_ioctl_unlocked); ++} ++ + #ifdef CONFIG_COMPAT + static long linereq_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +@@ -1404,12 +1472,15 @@ static long linereq_ioctl_compat(struct file *file, unsigned int cmd, + } + #endif + +-static __poll_t linereq_poll(struct file *file, +- struct poll_table_struct *wait) ++static __poll_t linereq_poll_unlocked(struct file *file, ++ struct poll_table_struct *wait) + { + struct linereq *lr = file->private_data; + __poll_t events = 0; + ++ if (!lr->gdev->chip) ++ return EPOLLHUP | EPOLLERR; ++ + poll_wait(file, &lr->wait, wait); + + if (!kfifo_is_empty_spinlocked_noirqsave(&lr->events, +@@ -1419,16 +1490,25 @@ static __poll_t linereq_poll(struct file *file, + return events; + } + +-static ssize_t linereq_read(struct file *file, +- char __user *buf, +- size_t count, +- loff_t *f_ps) ++static __poll_t linereq_poll(struct file *file, ++ struct poll_table_struct *wait) ++{ ++ struct linereq *lr = file->private_data; ++ ++ return call_poll_locked(file, wait, lr->gdev, linereq_poll_unlocked); ++} ++ ++static ssize_t linereq_read_unlocked(struct file *file, char __user *buf, ++ size_t count, loff_t *f_ps) + { + struct linereq *lr = file->private_data; + struct gpio_v2_line_event le; + ssize_t bytes_read = 0; + int ret; + ++ if (!lr->gdev->chip) ++ return -ENODEV; ++ + if (count < sizeof(le)) + return -EINVAL; + +@@ -1473,6 +1553,15 @@ static ssize_t linereq_read(struct file *file, + return bytes_read; + } + ++static ssize_t linereq_read(struct file *file, char __user *buf, ++ size_t count, loff_t *f_ps) ++{ ++ struct linereq *lr = file->private_data; ++ ++ return call_read_locked(file, buf, count, f_ps, lr->gdev, ++ linereq_read_unlocked); ++} ++ + static void linereq_free(struct linereq *lr) + { + unsigned int i; +@@ -1692,12 +1781,15 @@ struct lineevent_state { + (GPIOEVENT_REQUEST_RISING_EDGE | \ + GPIOEVENT_REQUEST_FALLING_EDGE) + +-static __poll_t lineevent_poll(struct file *file, +- struct poll_table_struct *wait) ++static __poll_t lineevent_poll_unlocked(struct file *file, ++ struct poll_table_struct *wait) + { + struct lineevent_state *le = file->private_data; + __poll_t events = 0; + ++ if (!le->gdev->chip) ++ return EPOLLHUP | EPOLLERR; ++ + poll_wait(file, &le->wait, wait); + + if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock)) +@@ -1706,15 +1798,21 @@ static __poll_t lineevent_poll(struct file *file, + return events; + } + ++static __poll_t lineevent_poll(struct file *file, ++ struct poll_table_struct *wait) ++{ ++ struct lineevent_state *le = file->private_data; ++ ++ return call_poll_locked(file, wait, le->gdev, lineevent_poll_unlocked); ++} ++ + struct compat_gpioeevent_data { + compat_u64 timestamp; + u32 id; + }; + +-static ssize_t lineevent_read(struct file *file, +- char __user *buf, +- size_t count, +- loff_t *f_ps) ++static ssize_t lineevent_read_unlocked(struct file *file, char __user *buf, ++ size_t count, loff_t *f_ps) + { + struct lineevent_state *le = file->private_data; + struct gpioevent_data ge; +@@ -1722,6 +1820,9 @@ static ssize_t lineevent_read(struct file *file, + ssize_t ge_size; + int ret; + ++ if (!le->gdev->chip) ++ return -ENODEV; ++ + /* + * When compatible system call is being used the struct gpioevent_data, + * in case of at least ia32, has different size due to the alignment +@@ -1779,6 +1880,15 @@ static ssize_t lineevent_read(struct file *file, + return bytes_read; + } + ++static ssize_t lineevent_read(struct file *file, char __user *buf, ++ size_t count, loff_t *f_ps) ++{ ++ struct lineevent_state *le = file->private_data; ++ ++ return call_read_locked(file, buf, count, f_ps, le->gdev, ++ lineevent_read_unlocked); ++} ++ + static void lineevent_free(struct lineevent_state *le) + { + if (le->irq) +@@ -1796,13 +1906,16 @@ static int lineevent_release(struct inode *inode, struct file *file) + return 0; + } + +-static long lineevent_ioctl(struct file *file, unsigned int cmd, +- unsigned long arg) ++static long lineevent_ioctl_unlocked(struct file *file, unsigned int cmd, ++ unsigned long arg) + { + struct lineevent_state *le = file->private_data; + void __user *ip = (void __user *)arg; + struct gpiohandle_data ghd; + ++ if (!le->gdev->chip) ++ return -ENODEV; ++ + /* + * We can get the value for an event line but not set it, + * because it is input by definition. +@@ -1825,6 +1938,15 @@ static long lineevent_ioctl(struct file *file, unsigned int cmd, + return -EINVAL; + } + ++static long lineevent_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct lineevent_state *le = file->private_data; ++ ++ return call_ioctl_locked(file, cmd, arg, le->gdev, ++ lineevent_ioctl_unlocked); ++} ++ + #ifdef CONFIG_COMPAT + static long lineevent_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +@@ -2383,12 +2505,15 @@ static int lineinfo_changed_notify(struct notifier_block *nb, + return NOTIFY_OK; + } + +-static __poll_t lineinfo_watch_poll(struct file *file, +- struct poll_table_struct *pollt) ++static __poll_t lineinfo_watch_poll_unlocked(struct file *file, ++ struct poll_table_struct *pollt) + { + struct gpio_chardev_data *cdev = file->private_data; + __poll_t events = 0; + ++ if (!cdev->gdev->chip) ++ return EPOLLHUP | EPOLLERR; ++ + poll_wait(file, &cdev->wait, pollt); + + if (!kfifo_is_empty_spinlocked_noirqsave(&cdev->events, +@@ -2398,8 +2523,17 @@ static __poll_t lineinfo_watch_poll(struct file *file, + return events; + } + +-static ssize_t lineinfo_watch_read(struct file *file, char __user *buf, +- size_t count, loff_t *off) ++static __poll_t lineinfo_watch_poll(struct file *file, ++ struct poll_table_struct *pollt) ++{ ++ struct gpio_chardev_data *cdev = file->private_data; ++ ++ return call_poll_locked(file, pollt, cdev->gdev, ++ lineinfo_watch_poll_unlocked); ++} ++ ++static ssize_t lineinfo_watch_read_unlocked(struct file *file, char __user *buf, ++ size_t count, loff_t *off) + { + struct gpio_chardev_data *cdev = file->private_data; + struct gpio_v2_line_info_changed event; +@@ -2407,6 +2541,9 @@ static ssize_t lineinfo_watch_read(struct file *file, char __user *buf, + int ret; + size_t event_size; + ++ if (!cdev->gdev->chip) ++ return -ENODEV; ++ + #ifndef CONFIG_GPIO_CDEV_V1 + event_size = sizeof(struct gpio_v2_line_info_changed); + if (count < event_size) +@@ -2474,6 +2611,15 @@ static ssize_t lineinfo_watch_read(struct file *file, char __user *buf, + return bytes_read; + } + ++static ssize_t lineinfo_watch_read(struct file *file, char __user *buf, ++ size_t count, loff_t *off) ++{ ++ struct gpio_chardev_data *cdev = file->private_data; ++ ++ return call_read_locked(file, buf, count, off, cdev->gdev, ++ lineinfo_watch_read_unlocked); ++} ++ + /** + * gpio_chrdev_open() - open the chardev for ioctl operations + * @inode: inode for this chardev +@@ -2487,13 +2633,17 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file) + struct gpio_chardev_data *cdev; + int ret = -ENOMEM; + ++ down_read(&gdev->sem); ++ + /* Fail on open if the backing gpiochip is gone */ +- if (!gdev->chip) +- return -ENODEV; ++ if (!gdev->chip) { ++ ret = -ENODEV; ++ goto out_unlock; ++ } + + cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + if (!cdev) +- return -ENOMEM; ++ goto out_unlock; + + cdev->watched_lines = bitmap_zalloc(gdev->chip->ngpio, GFP_KERNEL); + if (!cdev->watched_lines) +@@ -2516,6 +2666,8 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file) + if (ret) + goto out_unregister_notifier; + ++ up_read(&gdev->sem); ++ + return ret; + + out_unregister_notifier: +@@ -2525,6 +2677,8 @@ out_free_bitmap: + bitmap_free(cdev->watched_lines); + out_free_cdev: + kfree(cdev); ++out_unlock: ++ up_read(&gdev->sem); + return ret; + } + +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index eb7d00608c7fb..2adca7c2dd5c8 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -735,6 +735,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, + spin_unlock_irqrestore(&gpio_lock, flags); + + BLOCKING_INIT_NOTIFIER_HEAD(&gdev->notifier); ++ init_rwsem(&gdev->sem); + + #ifdef CONFIG_PINCTRL + INIT_LIST_HEAD(&gdev->pin_ranges); +@@ -875,6 +876,8 @@ void gpiochip_remove(struct gpio_chip *gc) + unsigned long flags; + unsigned int i; + ++ down_write(&gdev->sem); ++ + /* FIXME: should the legacy sysfs handling be moved to gpio_device? */ + gpiochip_sysfs_unregister(gdev); + gpiochip_free_hogs(gc); +@@ -909,6 +912,7 @@ void gpiochip_remove(struct gpio_chip *gc) + * gone. + */ + gcdev_unregister(gdev); ++ up_write(&gdev->sem); + put_device(&gdev->dev); + } + EXPORT_SYMBOL_GPL(gpiochip_remove); +diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h +index d900ecdbac46d..9ad68a0adf4a8 100644 +--- a/drivers/gpio/gpiolib.h ++++ b/drivers/gpio/gpiolib.h +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #define GPIOCHIP_NAME "gpiochip" + +@@ -39,6 +40,9 @@ + * @list: links gpio_device:s together for traversal + * @notifier: used to notify subscribers about lines being requested, released + * or reconfigured ++ * @sem: protects the structure from a NULL-pointer dereference of @chip by ++ * user-space operations when the device gets unregistered during ++ * a hot-unplug event + * @pin_ranges: range of pins served by the GPIO driver + * + * This state container holds most of the runtime variable data +@@ -60,6 +64,7 @@ struct gpio_device { + void *data; + struct list_head list; + struct blocking_notifier_head notifier; ++ struct rw_semaphore sem; + + #ifdef CONFIG_PINCTRL + /* +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +index 5e184952ec988..6659630303a38 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +@@ -2253,7 +2253,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev, + + ret = drm_vma_node_allow(&obj->vma_node, drm_priv); + if (ret) { +- kfree(mem); ++ kfree(*mem); + return ret; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +index e363f56c72af1..30c28a69e847d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +@@ -317,6 +317,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) + + if (!found) + return false; ++ pci_dev_put(pdev); + + adev->bios = kmalloc(size, GFP_KERNEL); + if (!adev->bios) { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index e0c960cc1d2e1..f04e698e631c5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -5004,6 +5004,8 @@ static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev) + pm_runtime_enable(&(p->dev)); + pm_runtime_resume(&(p->dev)); + } ++ ++ pci_dev_put(p); + } + + static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev) +@@ -5042,6 +5044,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev) + + if (expires < ktime_get_mono_fast_ns()) { + dev_warn(adev->dev, "failed to suspend display audio\n"); ++ pci_dev_put(p); + /* TODO: abort the succeeding gpu reset? */ + return -ETIMEDOUT; + } +@@ -5049,6 +5052,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev) + + pm_runtime_disable(&(p->dev)); + ++ pci_dev_put(p); + return 0; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +index 617d072275ebe..77210fd64a2bc 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +@@ -75,6 +75,8 @@ struct amdgpu_vf_error_buffer { + uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE]; + }; + ++enum idh_request; ++ + /** + * struct amdgpu_virt_ops - amdgpu device virt operations + */ +@@ -84,7 +86,8 @@ struct amdgpu_virt_ops { + int (*req_init_data)(struct amdgpu_device *adev); + int (*reset_gpu)(struct amdgpu_device *adev); + int (*wait_reset)(struct amdgpu_device *adev); +- void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); ++ void (*trans_msg)(struct amdgpu_device *adev, enum idh_request req, ++ u32 data1, u32 data2, u32 data3); + }; + + /* +diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c +index b3fba8dea63ca..6853b93ac82e7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/nv.c ++++ b/drivers/gpu/drm/amd/amdgpu/nv.c +@@ -82,10 +82,10 @@ static const struct amdgpu_video_codecs nv_video_codecs_encode = + /* Navi1x */ + static const struct amdgpu_video_codec_info nv_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, +@@ -100,10 +100,10 @@ static const struct amdgpu_video_codecs nv_video_codecs_decode = + /* Sienna Cichlid */ + static const struct amdgpu_video_codec_info sc_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, +@@ -125,10 +125,10 @@ static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] = + + static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, +@@ -149,7 +149,7 @@ static struct amdgpu_video_codecs sriov_sc_video_codecs_decode = + + /* Beige Goby*/ + static const struct amdgpu_video_codec_info bg_video_codecs_decode_array[] = { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, + }; +@@ -166,7 +166,7 @@ static const struct amdgpu_video_codecs bg_video_codecs_encode = { + + /* Yellow Carp*/ + static const struct amdgpu_video_codec_info yc_video_codecs_decode_array[] = { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, +diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c +index e3b2b6b4f1a66..7cd17dda32ceb 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc15.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c +@@ -103,10 +103,10 @@ static const struct amdgpu_video_codecs vega_video_codecs_encode = + /* Vega */ + static const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + }; +@@ -120,10 +120,10 @@ static const struct amdgpu_video_codecs vega_video_codecs_decode = + /* Raven */ + static const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)}, +@@ -138,10 +138,10 @@ static const struct amdgpu_video_codecs rv_video_codecs_decode = + /* Renoir, Arcturus */ + static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, +diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c +index 9c3463b481396..6d21c975b73d1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc21.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc21.c +@@ -61,7 +61,7 @@ static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_encode = + + static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +index a0154a5f71832..e2d3027c39936 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +@@ -41,39 +41,6 @@ + #include "dm_helpers.h" + #include "ddc_service_types.h" + +-struct monitor_patch_info { +- unsigned int manufacturer_id; +- unsigned int product_id; +- void (*patch_func)(struct dc_edid_caps *edid_caps, unsigned int param); +- unsigned int patch_param; +-}; +-static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param); +- +-static const struct monitor_patch_info monitor_patch_table[] = { +-{0x6D1E, 0x5BBF, set_max_dsc_bpp_limit, 15}, +-{0x6D1E, 0x5B9A, set_max_dsc_bpp_limit, 15}, +-}; +- +-static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param) +-{ +- if (edid_caps) +- edid_caps->panel_patch.max_dsc_target_bpp_limit = param; +-} +- +-static int amdgpu_dm_patch_edid_caps(struct dc_edid_caps *edid_caps) +-{ +- int i, ret = 0; +- +- for (i = 0; i < ARRAY_SIZE(monitor_patch_table); i++) +- if ((edid_caps->manufacturer_id == monitor_patch_table[i].manufacturer_id) +- && (edid_caps->product_id == monitor_patch_table[i].product_id)) { +- monitor_patch_table[i].patch_func(edid_caps, monitor_patch_table[i].patch_param); +- ret++; +- } +- +- return ret; +-} +- + /* dm_helpers_parse_edid_caps + * + * Parse edid caps +@@ -148,8 +115,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps( + kfree(sads); + kfree(sadb); + +- amdgpu_dm_patch_edid_caps(edid_caps); +- + return result; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index de3a1f3fd4f1a..c98cd7c5b9f7a 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -487,6 +487,7 @@ static enum bp_result get_gpio_i2c_info( + uint32_t count = 0; + unsigned int table_index = 0; + bool find_valid = false; ++ struct atom_gpio_pin_assignment *pin; + + if (!info) + return BP_RESULT_BADINPUT; +@@ -514,20 +515,17 @@ static enum bp_result get_gpio_i2c_info( + - sizeof(struct atom_common_table_header)) + / sizeof(struct atom_gpio_pin_assignment); + ++ pin = (struct atom_gpio_pin_assignment *) header->gpio_pin; ++ + for (table_index = 0; table_index < count; table_index++) { +- if (((record->i2c_id & I2C_HW_CAP) == ( +- header->gpio_pin[table_index].gpio_id & +- I2C_HW_CAP)) && +- ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == +- (header->gpio_pin[table_index].gpio_id & +- I2C_HW_ENGINE_ID_MASK)) && +- ((record->i2c_id & I2C_HW_LANE_MUX) == +- (header->gpio_pin[table_index].gpio_id & +- I2C_HW_LANE_MUX))) { ++ if (((record->i2c_id & I2C_HW_CAP) == (pin->gpio_id & I2C_HW_CAP)) && ++ ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == (pin->gpio_id & I2C_HW_ENGINE_ID_MASK)) && ++ ((record->i2c_id & I2C_HW_LANE_MUX) == (pin->gpio_id & I2C_HW_LANE_MUX))) { + /* still valid */ + find_valid = true; + break; + } ++ pin = (struct atom_gpio_pin_assignment *)((uint8_t *)pin + sizeof(struct atom_gpio_pin_assignment)); + } + + /* If we don't find the entry that we are looking for then +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +index e7f1d5f8166f9..59a29c32f66a8 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +@@ -436,7 +436,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base, + } + + if (!new_clocks->dtbclk_en) { +- new_clocks->ref_dtbclk_khz = 0; ++ new_clocks->ref_dtbclk_khz = clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz * 1000; + } + + /* clock limits are received with MHz precision, divide by 1000 to prevent setting clocks at every call */ +diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c +index fc6aa098bda06..8db9f75144662 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c +@@ -1128,6 +1128,7 @@ struct resource_pool *dce60_create_resource_pool( + if (dce60_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +@@ -1325,6 +1326,7 @@ struct resource_pool *dce61_create_resource_pool( + if (dce61_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +@@ -1518,6 +1520,7 @@ struct resource_pool *dce64_create_resource_pool( + if (dce64_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +index b28025960050c..5825e6f412bd7 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +@@ -1137,6 +1137,7 @@ struct resource_pool *dce80_create_resource_pool( + if (dce80_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +@@ -1336,6 +1337,7 @@ struct resource_pool *dce81_create_resource_pool( + if (dce81_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index bc9b92838ea9f..d7757e7900ba7 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -867,6 +867,32 @@ static void false_optc_underflow_wa( + tg->funcs->clear_optc_underflow(tg); + } + ++static int calculate_vready_offset_for_group(struct pipe_ctx *pipe) ++{ ++ struct pipe_ctx *other_pipe; ++ int vready_offset = pipe->pipe_dlg_param.vready_offset; ++ ++ /* Always use the largest vready_offset of all connected pipes */ ++ for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ ++ return vready_offset; ++} ++ + enum dc_status dcn10_enable_stream_timing( + struct pipe_ctx *pipe_ctx, + struct dc_state *context, +@@ -902,7 +928,7 @@ enum dc_status dcn10_enable_stream_timing( + pipe_ctx->stream_res.tg->funcs->program_timing( + pipe_ctx->stream_res.tg, + &stream->timing, +- pipe_ctx->pipe_dlg_param.vready_offset, ++ calculate_vready_offset_for_group(pipe_ctx), + pipe_ctx->pipe_dlg_param.vstartup_start, + pipe_ctx->pipe_dlg_param.vupdate_offset, + pipe_ctx->pipe_dlg_param.vupdate_width, +@@ -2869,7 +2895,7 @@ void dcn10_program_pipe( + + pipe_ctx->stream_res.tg->funcs->program_global_sync( + pipe_ctx->stream_res.tg, +- pipe_ctx->pipe_dlg_param.vready_offset, ++ calculate_vready_offset_for_group(pipe_ctx), + pipe_ctx->pipe_dlg_param.vstartup_start, + pipe_ctx->pipe_dlg_param.vupdate_offset, + pipe_ctx->pipe_dlg_param.vupdate_width); +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +index 0f30df523fdf5..cd799ce6e48b8 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +@@ -1608,6 +1608,31 @@ static void dcn20_update_dchubp_dpp( + hubp->funcs->phantom_hubp_post_enable(hubp); + } + ++static int calculate_vready_offset_for_group(struct pipe_ctx *pipe) ++{ ++ struct pipe_ctx *other_pipe; ++ int vready_offset = pipe->pipe_dlg_param.vready_offset; ++ ++ /* Always use the largest vready_offset of all connected pipes */ ++ for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ ++ return vready_offset; ++} + + static void dcn20_program_pipe( + struct dc *dc, +@@ -1626,16 +1651,14 @@ static void dcn20_program_pipe( + && !pipe_ctx->prev_odm_pipe) { + pipe_ctx->stream_res.tg->funcs->program_global_sync( + pipe_ctx->stream_res.tg, +- pipe_ctx->pipe_dlg_param.vready_offset, ++ calculate_vready_offset_for_group(pipe_ctx), + pipe_ctx->pipe_dlg_param.vstartup_start, + pipe_ctx->pipe_dlg_param.vupdate_offset, + pipe_ctx->pipe_dlg_param.vupdate_width); + + if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) { +- pipe_ctx->stream_res.tg->funcs->wait_for_state( +- pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK); +- pipe_ctx->stream_res.tg->funcs->wait_for_state( +- pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE); ++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK); ++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE); + } + + pipe_ctx->stream_res.tg->funcs->set_vtg_params( +@@ -2040,7 +2063,7 @@ bool dcn20_update_bandwidth( + + pipe_ctx->stream_res.tg->funcs->program_global_sync( + pipe_ctx->stream_res.tg, +- pipe_ctx->pipe_dlg_param.vready_offset, ++ calculate_vready_offset_for_group(pipe_ctx), + pipe_ctx->pipe_dlg_param.vstartup_start, + pipe_ctx->pipe_dlg_param.vupdate_offset, + pipe_ctx->pipe_dlg_param.vupdate_width); +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c +index 6dd8dadd68a5d..6f160f65c8fa9 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c +@@ -225,11 +225,7 @@ void dccg32_set_dtbclk_dto( + } else { + REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLK_DTO_ENABLE[params->otg_inst], 0, +- PIPE_DTO_SRC_SEL[params->otg_inst], 1); +- if (params->is_hdmi) +- REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], +- PIPE_DTO_SRC_SEL[params->otg_inst], 0); +- ++ PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1); + REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0); + REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0); + } +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +index 07c56e231b045..d05df4f7139fd 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +@@ -485,9 +485,11 @@ void dcn32_set_phantom_stream_timing(struct dc *dc, + unsigned int i, pipe_idx; + struct pipe_ctx *pipe; + uint32_t phantom_vactive, phantom_bp, pstate_width_fw_delay_lines; ++ unsigned int num_dpp; + unsigned int vlevel = context->bw_ctx.dml.vba.VoltageLevel; + unsigned int dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; + unsigned int socclk = context->bw_ctx.dml.vba.SOCCLKPerState[vlevel]; ++ struct vba_vars_st *vba = &context->bw_ctx.dml.vba; + + dc_assert_fp_enabled(); + +@@ -523,6 +525,11 @@ void dcn32_set_phantom_stream_timing(struct dc *dc, + phantom_vactive = get_subviewport_lines_needed_in_mall(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx) + + pstate_width_fw_delay_lines + dc->caps.subvp_swath_height_margin_lines; + ++ // W/A for DCC corruption with certain high resolution timings. ++ // Determing if pipesplit is used. If so, add meta_row_height to the phantom vactive. ++ num_dpp = vba->NoOfDPP[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]]; ++ phantom_vactive += num_dpp > 1 ? vba->meta_row_height[vba->pipe_plane[pipe_idx]] : 0; ++ + // For backporch of phantom pipe, use vstartup of the main pipe + phantom_bp = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); + +diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h +index 7e3231c2191ca..ffe19883b2ee9 100644 +--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h ++++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h +@@ -354,7 +354,8 @@ struct amd_pm_funcs { + int (*get_power_profile_mode)(void *handle, char *buf); + int (*set_power_profile_mode)(void *handle, long *input, uint32_t size); + int (*set_fine_grain_clk_vol)(void *handle, uint32_t type, long *input, uint32_t size); +- int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size); ++ int (*odn_edit_dpm_table)(void *handle, enum PP_OD_DPM_TABLE_COMMAND type, ++ long *input, uint32_t size); + int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state); + int (*smu_i2c_bus_access)(void *handle, bool acquire); + int (*gfx_state_change_set)(void *handle, uint32_t state); +diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +index 1eb4e613b27a5..6562978de84a0 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +@@ -838,7 +838,8 @@ static int pp_set_fine_grain_clk_vol(void *handle, uint32_t type, long *input, u + return hwmgr->hwmgr_func->set_fine_grain_clk_vol(hwmgr, type, input, size); + } + +-static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint32_t size) ++static int pp_odn_edit_dpm_table(void *handle, enum PP_OD_DPM_TABLE_COMMAND type, ++ long *input, uint32_t size) + { + struct pp_hwmgr *hwmgr = handle; + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +index 67d7da0b6fed5..1d829402cd2e2 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +@@ -75,8 +75,10 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr) + for (i = 0; i < table_entries; i++) { + result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state); + if (result) { ++ kfree(hwmgr->current_ps); + kfree(hwmgr->request_ps); + kfree(hwmgr->ps); ++ hwmgr->current_ps = NULL; + hwmgr->request_ps = NULL; + hwmgr->ps = NULL; + return -EINVAL; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +index 97b3ad3690467..b30684c84e20e 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +@@ -2961,7 +2961,8 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, + data->od8_settings.od8_settings_array; + OverDriveTable_t *od_table = + &(data->smc_state_table.overdrive_table); +- int32_t input_index, input_clk, input_vol, i; ++ int32_t input_clk, input_vol, i; ++ uint32_t input_index; + int od8_id; + int ret; + +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +index 70b560737687e..ad5f6a15a1d7d 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +@@ -1588,6 +1588,10 @@ bool smu_v11_0_baco_is_support(struct smu_context *smu) + if (amdgpu_sriov_vf(smu->adev) || !smu_baco->platform_support) + return false; + ++ /* return true if ASIC is in BACO state already */ ++ if (smu_v11_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER) ++ return true; ++ + /* Arcturus does not support this bit mask */ + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) && + !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT)) +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +index d74debc584f89..39deb06a86ba3 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +@@ -1436,7 +1436,7 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu, + + static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf) + { +- DpmActivityMonitorCoeffIntExternal_t activity_monitor_external[PP_SMC_POWER_PROFILE_COUNT]; ++ DpmActivityMonitorCoeffIntExternal_t *activity_monitor_external; + uint32_t i, j, size = 0; + int16_t workload_type = 0; + int result = 0; +@@ -1444,6 +1444,12 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf + if (!buf) + return -EINVAL; + ++ activity_monitor_external = kcalloc(PP_SMC_POWER_PROFILE_COUNT, ++ sizeof(*activity_monitor_external), ++ GFP_KERNEL); ++ if (!activity_monitor_external) ++ return -ENOMEM; ++ + size += sysfs_emit_at(buf, size, " "); + for (i = 0; i <= PP_SMC_POWER_PROFILE_WINDOW3D; i++) + size += sysfs_emit_at(buf, size, "%-14s%s", amdgpu_pp_profile_name[i], +@@ -1456,15 +1462,17 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf + workload_type = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_WORKLOAD, + i); +- if (workload_type < 0) +- return -EINVAL; ++ if (workload_type < 0) { ++ result = -EINVAL; ++ goto out; ++ } + + result = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type, + (void *)(&activity_monitor_external[i]), false); + if (result) { + dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); +- return result; ++ goto out; + } + } + +@@ -1492,7 +1500,10 @@ do { \ + PRINT_DPM_MONITOR(Fclk_BoosterFreq); + #undef PRINT_DPM_MONITOR + +- return size; ++ result = size; ++out: ++ kfree(activity_monitor_external); ++ return result; + } + + static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size) +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h +index 94de73cbeb2dd..17445800248dd 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h ++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h +@@ -402,7 +402,8 @@ static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) + + void adv7533_dsi_power_on(struct adv7511 *adv); + void adv7533_dsi_power_off(struct adv7511 *adv); +-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode); ++enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, ++ const struct drm_display_mode *mode); + int adv7533_patch_registers(struct adv7511 *adv); + int adv7533_patch_cec_registers(struct adv7511 *adv); + int adv7533_attach_dsi(struct adv7511 *adv); +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +index 6031bdd923420..0f0950c111960 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c ++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +@@ -697,7 +697,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) + } + + static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511, +- struct drm_display_mode *mode) ++ const struct drm_display_mode *mode) + { + if (mode->clock > 165000) + return MODE_CLOCK_HIGH; +@@ -791,9 +791,6 @@ static void adv7511_mode_set(struct adv7511 *adv7511, + regmap_update_bits(adv7511->regmap, 0x17, + 0x60, (vsync_polarity << 6) | (hsync_polarity << 5)); + +- if (adv7511->type == ADV7533 || adv7511->type == ADV7535) +- adv7533_mode_set(adv7511, adj_mode); +- + drm_mode_copy(&adv7511->curr_mode, adj_mode); + + /* +@@ -913,6 +910,18 @@ static void adv7511_bridge_mode_set(struct drm_bridge *bridge, + adv7511_mode_set(adv, mode, adj_mode); + } + ++static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge, ++ const struct drm_display_info *info, ++ const struct drm_display_mode *mode) ++{ ++ struct adv7511 *adv = bridge_to_adv7511(bridge); ++ ++ if (adv->type == ADV7533 || adv->type == ADV7535) ++ return adv7533_mode_valid(adv, mode); ++ else ++ return adv7511_mode_valid(adv, mode); ++} ++ + static int adv7511_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) + { +@@ -960,6 +969,7 @@ static const struct drm_bridge_funcs adv7511_bridge_funcs = { + .enable = adv7511_bridge_enable, + .disable = adv7511_bridge_disable, + .mode_set = adv7511_bridge_mode_set, ++ .mode_valid = adv7511_bridge_mode_valid, + .attach = adv7511_bridge_attach, + .detect = adv7511_bridge_detect, + .get_edid = adv7511_bridge_get_edid, +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c +index ef6270806d1d3..258c79d4dab0a 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c ++++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c +@@ -100,26 +100,27 @@ void adv7533_dsi_power_off(struct adv7511 *adv) + regmap_write(adv->regmap_cec, 0x27, 0x0b); + } + +-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode) ++enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, ++ const struct drm_display_mode *mode) + { ++ int lanes; + struct mipi_dsi_device *dsi = adv->dsi; +- int lanes, ret; +- +- if (adv->num_dsi_lanes != 4) +- return; + + if (mode->clock > 80000) + lanes = 4; + else + lanes = 3; + +- if (lanes != dsi->lanes) { +- mipi_dsi_detach(dsi); +- dsi->lanes = lanes; +- ret = mipi_dsi_attach(dsi); +- if (ret) +- dev_err(&dsi->dev, "failed to change host lanes\n"); +- } ++ /* ++ * TODO: add support for dynamic switching of lanes ++ * by using the bridge pre_enable() op . Till then filter ++ * out the modes which shall need different number of lanes ++ * than what was configured in the device tree. ++ */ ++ if (lanes != dsi->lanes) ++ return MODE_BAD; ++ ++ return MODE_OK; + } + + int adv7533_patch_registers(struct adv7511 *adv) +diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c +index a09d1a39ab0ae..711f403afe7ce 100644 +--- a/drivers/gpu/drm/bridge/ite-it6505.c ++++ b/drivers/gpu/drm/bridge/ite-it6505.c +@@ -2854,10 +2854,7 @@ static int it6505_bridge_attach(struct drm_bridge *bridge, + } + + /* Register aux channel */ +- it6505->aux.name = "DP-AUX"; +- it6505->aux.dev = dev; + it6505->aux.drm_dev = bridge->dev; +- it6505->aux.transfer = it6505_aux_transfer; + + ret = drm_dp_aux_register(&it6505->aux); + +@@ -3310,6 +3307,11 @@ static int it6505_i2c_probe(struct i2c_client *client, + DRM_DEV_DEBUG_DRIVER(dev, "it6505 device name: %s", dev_name(dev)); + debugfs_init(it6505); + ++ it6505->aux.name = "DP-AUX"; ++ it6505->aux.dev = dev; ++ it6505->aux.transfer = it6505_aux_transfer; ++ drm_dp_aux_init(&it6505->aux); ++ + it6505->bridge.funcs = &it6505_bridge_funcs; + it6505->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; + it6505->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | +diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index 8bf41aa240687..6526d6ade04bf 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -899,7 +899,6 @@ int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state, + bool can_disable_primary_planes) + { + struct drm_device *dev = crtc_state->crtc->dev; +- struct drm_atomic_state *state = crtc_state->state; + + if (!crtc_state->enable) + return 0; +@@ -910,14 +909,7 @@ int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state, + struct drm_plane *plane; + + drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) { +- struct drm_plane_state *plane_state; +- +- if (plane->type != DRM_PLANE_TYPE_PRIMARY) +- continue; +- plane_state = drm_atomic_get_plane_state(state, plane); +- if (IS_ERR(plane_state)) +- return PTR_ERR(plane_state); +- if (plane_state->fb && plane_state->crtc) { ++ if (plane->type == DRM_PLANE_TYPE_PRIMARY) { + has_primary_plane = true; + break; + } +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index eaa819381281b..fefcfac999d99 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -87,6 +87,8 @@ static int oui(u8 first, u8 second, u8 third) + #define EDID_QUIRK_FORCE_10BPC (1 << 11) + /* Non desktop display (i.e. HMD) */ + #define EDID_QUIRK_NON_DESKTOP (1 << 12) ++/* Cap the DSC target bitrate to 15bpp */ ++#define EDID_QUIRK_CAP_DSC_15BPP (1 << 13) + + #define MICROSOFT_IEEE_OUI 0xca125c + +@@ -147,6 +149,12 @@ static const struct edid_quirk { + EDID_QUIRK('F', 'C', 'M', 13600, EDID_QUIRK_PREFER_LARGE_75 | + EDID_QUIRK_DETAILED_IN_CM), + ++ /* LG 27GP950 */ ++ EDID_QUIRK('G', 'S', 'M', 0x5bbf, EDID_QUIRK_CAP_DSC_15BPP), ++ ++ /* LG 27GN950 */ ++ EDID_QUIRK('G', 'S', 'M', 0x5b9a, EDID_QUIRK_CAP_DSC_15BPP), ++ + /* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */ + EDID_QUIRK('L', 'G', 'D', 764, EDID_QUIRK_FORCE_10BPC), + +@@ -6116,6 +6124,7 @@ static void drm_reset_display_info(struct drm_connector *connector) + + info->mso_stream_count = 0; + info->mso_pixel_overlap = 0; ++ info->max_dsc_bpp = 0; + } + + static u32 update_display_info(struct drm_connector *connector, +@@ -6202,6 +6211,9 @@ out: + info->non_desktop = true; + } + ++ if (quirks & EDID_QUIRK_CAP_DSC_15BPP) ++ info->max_dsc_bpp = 15; ++ + return quirks; + } + +diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c +index 07741b678798b..6768b7d18b6fb 100644 +--- a/drivers/gpu/drm/drm_fourcc.c ++++ b/drivers/gpu/drm/drm_fourcc.c +@@ -263,12 +263,12 @@ const struct drm_format_info *__drm_format_info(u32 format) + .vsub = 2, .is_yuv = true }, + { .format = DRM_FORMAT_Q410, .depth = 0, + .num_planes = 3, .char_per_block = { 2, 2, 2 }, +- .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0, +- .vsub = 0, .is_yuv = true }, ++ .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, ++ .vsub = 1, .is_yuv = true }, + { .format = DRM_FORMAT_Q401, .depth = 0, + .num_planes = 3, .char_per_block = { 2, 2, 2 }, +- .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0, +- .vsub = 0, .is_yuv = true }, ++ .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, ++ .vsub = 1, .is_yuv = true }, + { .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2, + .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 }, + .hsub = 2, .vsub = 2, .is_yuv = true}, +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +index 37018bc55810d..f667e7906d1f4 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +@@ -416,6 +416,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) + if (gpu->identity.model == chipModel_GC700) + gpu->identity.features &= ~chipFeatures_FAST_CLEAR; + ++ /* These models/revisions don't have the 2D pipe bit */ ++ if ((gpu->identity.model == chipModel_GC500 && ++ gpu->identity.revision <= 2) || ++ gpu->identity.model == chipModel_GC300) ++ gpu->identity.features |= chipFeatures_PIPE_2D; ++ + if ((gpu->identity.model == chipModel_GC500 && + gpu->identity.revision < 2) || + (gpu->identity.model == chipModel_GC300 && +@@ -449,8 +455,9 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) + gpu_read(gpu, VIVS_HI_CHIP_MINOR_FEATURE_5); + } + +- /* GC600 idle register reports zero bits where modules aren't present */ +- if (gpu->identity.model == chipModel_GC600) ++ /* GC600/300 idle register reports zero bits where modules aren't present */ ++ if (gpu->identity.model == chipModel_GC600 || ++ gpu->identity.model == chipModel_GC300) + gpu->idle_mask = VIVS_HI_IDLE_STATE_TX | + VIVS_HI_IDLE_STATE_RA | + VIVS_HI_IDLE_STATE_SE | +diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c +index 4d4a715b429d1..2c2b92324a2e9 100644 +--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c ++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c +@@ -60,8 +60,9 @@ static int fsl_dcu_drm_connector_get_modes(struct drm_connector *connector) + return drm_panel_get_modes(fsl_connector->panel, connector); + } + +-static int fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector, +- struct drm_display_mode *mode) ++static enum drm_mode_status ++fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) + { + if (mode->hdisplay & 0xf) + return MODE_ERROR; +diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c +index 459571e2cc575..2bfcfbfa52a4f 100644 +--- a/drivers/gpu/drm/i915/display/intel_bios.c ++++ b/drivers/gpu/drm/i915/display/intel_bios.c +@@ -414,7 +414,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915, + ptrs->lvds_entries++; + + if (size != 0 || ptrs->lvds_entries != 3) { +- kfree(ptrs); ++ kfree(ptrs_block); + return NULL; + } + +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index 21ba510716b6c..d852cfd1d6eba 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -3641,61 +3641,6 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, + } + } + +-static void +-intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp, +- const struct intel_crtc_state *crtc_state) +-{ +- struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); +- struct drm_device *dev = dig_port->base.base.dev; +- struct drm_i915_private *dev_priv = to_i915(dev); +- struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); +- enum pipe pipe = crtc->pipe; +- u32 trans_ddi_func_ctl_value, trans_conf_value, dp_tp_ctl_value; +- +- trans_ddi_func_ctl_value = intel_de_read(dev_priv, +- TRANS_DDI_FUNC_CTL(pipe)); +- trans_conf_value = intel_de_read(dev_priv, PIPECONF(pipe)); +- dp_tp_ctl_value = intel_de_read(dev_priv, TGL_DP_TP_CTL(pipe)); +- +- trans_ddi_func_ctl_value &= ~(TRANS_DDI_FUNC_ENABLE | +- TGL_TRANS_DDI_PORT_MASK); +- trans_conf_value &= ~PIPECONF_ENABLE; +- dp_tp_ctl_value &= ~DP_TP_CTL_ENABLE; +- +- intel_de_write(dev_priv, PIPECONF(pipe), trans_conf_value); +- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe), +- trans_ddi_func_ctl_value); +- intel_de_write(dev_priv, TGL_DP_TP_CTL(pipe), dp_tp_ctl_value); +-} +- +-static void +-intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, +- const struct intel_crtc_state *crtc_state) +-{ +- struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); +- struct drm_device *dev = dig_port->base.base.dev; +- struct drm_i915_private *dev_priv = to_i915(dev); +- enum port port = dig_port->base.port; +- struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); +- enum pipe pipe = crtc->pipe; +- u32 trans_ddi_func_ctl_value, trans_conf_value, dp_tp_ctl_value; +- +- trans_ddi_func_ctl_value = intel_de_read(dev_priv, +- TRANS_DDI_FUNC_CTL(pipe)); +- trans_conf_value = intel_de_read(dev_priv, PIPECONF(pipe)); +- dp_tp_ctl_value = intel_de_read(dev_priv, TGL_DP_TP_CTL(pipe)); +- +- trans_ddi_func_ctl_value |= TRANS_DDI_FUNC_ENABLE | +- TGL_TRANS_DDI_SELECT_PORT(port); +- trans_conf_value |= PIPECONF_ENABLE; +- dp_tp_ctl_value |= DP_TP_CTL_ENABLE; +- +- intel_de_write(dev_priv, PIPECONF(pipe), trans_conf_value); +- intel_de_write(dev_priv, TGL_DP_TP_CTL(pipe), dp_tp_ctl_value); +- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe), +- trans_ddi_func_ctl_value); +-} +- + static void intel_dp_process_phy_request(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) + { +@@ -3714,14 +3659,10 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp, + intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, + link_status); + +- intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state); +- + intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX); + + intel_dp_phy_pattern_update(intel_dp, crtc_state); + +- intel_dp_autotest_phy_ddi_enable(intel_dp, crtc_state); +- + drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET, + intel_dp->train_set, crtc_state->lane_count); + +diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h +index 04e435bce79bd..cbc8b857d5f7a 100644 +--- a/drivers/gpu/drm/i915/gt/intel_engine.h ++++ b/drivers/gpu/drm/i915/gt/intel_engine.h +@@ -348,4 +348,10 @@ intel_engine_get_hung_context(struct intel_engine_cs *engine) + return engine->hung_ce; + } + ++u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value); ++u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 value); ++u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value); ++u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value); ++u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 value); ++ + #endif /* _INTEL_RINGBUFFER_H_ */ +diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c +index 37fa813af7661..3dd0af057e6b1 100644 +--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c ++++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c +@@ -486,6 +486,17 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, + engine->logical_mask = BIT(logical_instance); + __sprint_engine_name(engine); + ++ if ((engine->class == COMPUTE_CLASS && !RCS_MASK(engine->gt) && ++ __ffs(CCS_MASK(engine->gt)) == engine->instance) || ++ engine->class == RENDER_CLASS) ++ engine->flags |= I915_ENGINE_FIRST_RENDER_COMPUTE; ++ ++ /* features common between engines sharing EUs */ ++ if (engine->class == RENDER_CLASS || engine->class == COMPUTE_CLASS) { ++ engine->flags |= I915_ENGINE_HAS_RCS_REG_STATE; ++ engine->flags |= I915_ENGINE_HAS_EU_PRIORITY; ++ } ++ + engine->props.heartbeat_interval_ms = + CONFIG_DRM_I915_HEARTBEAT_INTERVAL; + engine->props.max_busywait_duration_ns = +@@ -498,19 +509,28 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, + CONFIG_DRM_I915_TIMESLICE_DURATION; + + /* Override to uninterruptible for OpenCL workloads. */ +- if (GRAPHICS_VER(i915) == 12 && engine->class == RENDER_CLASS) ++ if (GRAPHICS_VER(i915) == 12 && (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE)) + engine->props.preempt_timeout_ms = 0; + +- if ((engine->class == COMPUTE_CLASS && !RCS_MASK(engine->gt) && +- __ffs(CCS_MASK(engine->gt)) == engine->instance) || +- engine->class == RENDER_CLASS) +- engine->flags |= I915_ENGINE_FIRST_RENDER_COMPUTE; +- +- /* features common between engines sharing EUs */ +- if (engine->class == RENDER_CLASS || engine->class == COMPUTE_CLASS) { +- engine->flags |= I915_ENGINE_HAS_RCS_REG_STATE; +- engine->flags |= I915_ENGINE_HAS_EU_PRIORITY; +- } ++ /* Cap properties according to any system limits */ ++#define CLAMP_PROP(field) \ ++ do { \ ++ u64 clamp = intel_clamp_##field(engine, engine->props.field); \ ++ if (clamp != engine->props.field) { \ ++ drm_notice(&engine->i915->drm, \ ++ "Warning, clamping %s to %lld to prevent overflow\n", \ ++ #field, clamp); \ ++ engine->props.field = clamp; \ ++ } \ ++ } while (0) ++ ++ CLAMP_PROP(heartbeat_interval_ms); ++ CLAMP_PROP(max_busywait_duration_ns); ++ CLAMP_PROP(preempt_timeout_ms); ++ CLAMP_PROP(stop_timeout_ms); ++ CLAMP_PROP(timeslice_duration_ms); ++ ++#undef CLAMP_PROP + + engine->defaults = engine->props; /* never to change again */ + +@@ -534,6 +554,55 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, + return 0; + } + ++u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value) ++{ ++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)); ++ ++ return value; ++} ++ ++u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 value) ++{ ++ value = min(value, jiffies_to_nsecs(2)); ++ ++ return value; ++} ++ ++u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value) ++{ ++ /* ++ * NB: The GuC API only supports 32bit values. However, the limit is further ++ * reduced due to internal calculations which would otherwise overflow. ++ */ ++ if (intel_guc_submission_is_wanted(&engine->gt->uc.guc)) ++ value = min_t(u64, value, guc_policy_max_preempt_timeout_ms()); ++ ++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)); ++ ++ return value; ++} ++ ++u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value) ++{ ++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)); ++ ++ return value; ++} ++ ++u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 value) ++{ ++ /* ++ * NB: The GuC API only supports 32bit values. However, the limit is further ++ * reduced due to internal calculations which would otherwise overflow. ++ */ ++ if (intel_guc_submission_is_wanted(&engine->gt->uc.guc)) ++ value = min_t(u64, value, guc_policy_max_exec_quantum_ms()); ++ ++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)); ++ ++ return value; ++} ++ + static void __setup_engine_capabilities(struct intel_engine_cs *engine) + { + struct drm_i915_private *i915 = engine->i915; +diff --git a/drivers/gpu/drm/i915/gt/sysfs_engines.c b/drivers/gpu/drm/i915/gt/sysfs_engines.c +index 9670310562029..f2d9858d827c2 100644 +--- a/drivers/gpu/drm/i915/gt/sysfs_engines.c ++++ b/drivers/gpu/drm/i915/gt/sysfs_engines.c +@@ -144,7 +144,7 @@ max_spin_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + struct intel_engine_cs *engine = kobj_to_engine(kobj); +- unsigned long long duration; ++ unsigned long long duration, clamped; + int err; + + /* +@@ -168,7 +168,8 @@ max_spin_store(struct kobject *kobj, struct kobj_attribute *attr, + if (err) + return err; + +- if (duration > jiffies_to_nsecs(2)) ++ clamped = intel_clamp_max_busywait_duration_ns(engine, duration); ++ if (duration != clamped) + return -EINVAL; + + WRITE_ONCE(engine->props.max_busywait_duration_ns, duration); +@@ -203,7 +204,7 @@ timeslice_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + struct intel_engine_cs *engine = kobj_to_engine(kobj); +- unsigned long long duration; ++ unsigned long long duration, clamped; + int err; + + /* +@@ -218,7 +219,8 @@ timeslice_store(struct kobject *kobj, struct kobj_attribute *attr, + if (err) + return err; + +- if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)) ++ clamped = intel_clamp_timeslice_duration_ms(engine, duration); ++ if (duration != clamped) + return -EINVAL; + + WRITE_ONCE(engine->props.timeslice_duration_ms, duration); +@@ -256,7 +258,7 @@ stop_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + struct intel_engine_cs *engine = kobj_to_engine(kobj); +- unsigned long long duration; ++ unsigned long long duration, clamped; + int err; + + /* +@@ -272,7 +274,8 @@ stop_store(struct kobject *kobj, struct kobj_attribute *attr, + if (err) + return err; + +- if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)) ++ clamped = intel_clamp_stop_timeout_ms(engine, duration); ++ if (duration != clamped) + return -EINVAL; + + WRITE_ONCE(engine->props.stop_timeout_ms, duration); +@@ -306,7 +309,7 @@ preempt_timeout_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + struct intel_engine_cs *engine = kobj_to_engine(kobj); +- unsigned long long timeout; ++ unsigned long long timeout, clamped; + int err; + + /* +@@ -322,7 +325,8 @@ preempt_timeout_store(struct kobject *kobj, struct kobj_attribute *attr, + if (err) + return err; + +- if (timeout > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)) ++ clamped = intel_clamp_preempt_timeout_ms(engine, timeout); ++ if (timeout != clamped) + return -EINVAL; + + WRITE_ONCE(engine->props.preempt_timeout_ms, timeout); +@@ -362,7 +366,7 @@ heartbeat_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + struct intel_engine_cs *engine = kobj_to_engine(kobj); +- unsigned long long delay; ++ unsigned long long delay, clamped; + int err; + + /* +@@ -379,7 +383,8 @@ heartbeat_store(struct kobject *kobj, struct kobj_attribute *attr, + if (err) + return err; + +- if (delay >= jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)) ++ clamped = intel_clamp_heartbeat_interval_ms(engine, delay); ++ if (delay != clamped) + return -EINVAL; + + err = intel_engine_set_heartbeat(engine, delay); +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c +index 2706a8c650900..7fbcfeda91951 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c +@@ -224,53 +224,22 @@ static u32 guc_ctl_feature_flags(struct intel_guc *guc) + + static u32 guc_ctl_log_params_flags(struct intel_guc *guc) + { +- u32 offset = intel_guc_ggtt_offset(guc, guc->log.vma) >> PAGE_SHIFT; +- u32 flags; +- +- #if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0) +- #define LOG_UNIT SZ_1M +- #define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS +- #else +- #define LOG_UNIT SZ_4K +- #define LOG_FLAG 0 +- #endif +- +- #if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0) +- #define CAPTURE_UNIT SZ_1M +- #define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS +- #else +- #define CAPTURE_UNIT SZ_4K +- #define CAPTURE_FLAG 0 +- #endif +- +- BUILD_BUG_ON(!CRASH_BUFFER_SIZE); +- BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT)); +- BUILD_BUG_ON(!DEBUG_BUFFER_SIZE); +- BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT)); +- BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE); +- BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT)); +- +- BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) > +- (GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT)); +- BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) > +- (GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT)); +- BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) > +- (GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT)); ++ struct intel_guc_log *log = &guc->log; ++ u32 offset, flags; ++ ++ GEM_BUG_ON(!log->sizes_initialised); ++ ++ offset = intel_guc_ggtt_offset(guc, log->vma) >> PAGE_SHIFT; + + flags = GUC_LOG_VALID | + GUC_LOG_NOTIFY_ON_HALF_FULL | +- CAPTURE_FLAG | +- LOG_FLAG | +- ((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) | +- ((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) | +- ((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << GUC_LOG_CAPTURE_SHIFT) | ++ log->sizes[GUC_LOG_SECTIONS_DEBUG].flag | ++ log->sizes[GUC_LOG_SECTIONS_CAPTURE].flag | ++ (log->sizes[GUC_LOG_SECTIONS_CRASH].count << GUC_LOG_CRASH_SHIFT) | ++ (log->sizes[GUC_LOG_SECTIONS_DEBUG].count << GUC_LOG_DEBUG_SHIFT) | ++ (log->sizes[GUC_LOG_SECTIONS_CAPTURE].count << GUC_LOG_CAPTURE_SHIFT) | + (offset << GUC_LOG_BUF_ADDR_SHIFT); + +- #undef LOG_UNIT +- #undef LOG_FLAG +- #undef CAPTURE_UNIT +- #undef CAPTURE_FLAG +- + return flags; + } + +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +index 75257bd20ff01..4c51888fd78b4 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +@@ -165,7 +165,7 @@ static const struct __guc_mmio_reg_descr empty_regs_list[] = { + } + + /* List of lists */ +-static struct __guc_mmio_reg_descr_group default_lists[] = { ++static const struct __guc_mmio_reg_descr_group default_lists[] = { + MAKE_REGLIST(default_global_regs, PF, GLOBAL, 0), + MAKE_REGLIST(default_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS), + MAKE_REGLIST(xe_lpd_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_RENDER_CLASS), +@@ -419,6 +419,44 @@ guc_capture_get_device_reglist(struct intel_guc *guc) + return default_lists; + } + ++static const char * ++__stringify_type(u32 type) ++{ ++ switch (type) { ++ case GUC_CAPTURE_LIST_TYPE_GLOBAL: ++ return "Global"; ++ case GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS: ++ return "Class"; ++ case GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE: ++ return "Instance"; ++ default: ++ break; ++ } ++ ++ return "unknown"; ++} ++ ++static const char * ++__stringify_engclass(u32 class) ++{ ++ switch (class) { ++ case GUC_RENDER_CLASS: ++ return "Render"; ++ case GUC_VIDEO_CLASS: ++ return "Video"; ++ case GUC_VIDEOENHANCE_CLASS: ++ return "VideoEnhance"; ++ case GUC_BLITTER_CLASS: ++ return "Blitter"; ++ case GUC_COMPUTE_CLASS: ++ return "Compute"; ++ default: ++ break; ++ } ++ ++ return "unknown"; ++} ++ + static int + guc_capture_list_init(struct intel_guc *guc, u32 owner, u32 type, u32 classid, + struct guc_mmio_reg *ptr, u16 num_entries) +@@ -482,32 +520,55 @@ guc_cap_list_num_regs(struct intel_guc_state_capture *gc, u32 owner, u32 type, u + return num_regs; + } + +-int +-intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, +- size_t *size) ++static int ++guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, ++ size_t *size, bool is_purpose_est) + { + struct intel_guc_state_capture *gc = guc->capture; ++ struct drm_i915_private *i915 = guc_to_gt(guc)->i915; + struct __guc_capture_ads_cache *cache = &gc->ads_cache[owner][type][classid]; + int num_regs; + +- if (!gc->reglists) ++ if (!gc->reglists) { ++ drm_warn(&i915->drm, "GuC-capture: No reglist on this device\n"); + return -ENODEV; ++ } + + if (cache->is_valid) { + *size = cache->size; + return cache->status; + } + ++ if (!is_purpose_est && owner == GUC_CAPTURE_LIST_INDEX_PF && ++ !guc_capture_get_one_list(gc->reglists, owner, type, classid)) { ++ if (type == GUC_CAPTURE_LIST_TYPE_GLOBAL) ++ drm_warn(&i915->drm, "Missing GuC-Err-Cap reglist Global!\n"); ++ else ++ drm_warn(&i915->drm, "Missing GuC-Err-Cap reglist %s(%u):%s(%u)!\n", ++ __stringify_type(type), type, ++ __stringify_engclass(classid), classid); ++ return -ENODATA; ++ } ++ + num_regs = guc_cap_list_num_regs(gc, owner, type, classid); ++ /* intentional empty lists can exist depending on hw config */ + if (!num_regs) + return -ENODATA; + +- *size = PAGE_ALIGN((sizeof(struct guc_debug_capture_list)) + +- (num_regs * sizeof(struct guc_mmio_reg))); ++ if (size) ++ *size = PAGE_ALIGN((sizeof(struct guc_debug_capture_list)) + ++ (num_regs * sizeof(struct guc_mmio_reg))); + + return 0; + } + ++int ++intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, ++ size_t *size) ++{ ++ return guc_capture_getlistsize(guc, owner, type, classid, size, false); ++} ++ + static void guc_capture_create_prealloc_nodes(struct intel_guc *guc); + + int +@@ -600,15 +661,13 @@ intel_guc_capture_getnullheader(struct intel_guc *guc, + return 0; + } + +-#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3 +- +-int +-intel_guc_capture_output_min_size_est(struct intel_guc *guc) ++static int ++guc_capture_output_min_size_est(struct intel_guc *guc) + { + struct intel_gt *gt = guc_to_gt(guc); + struct intel_engine_cs *engine; + enum intel_engine_id id; +- int worst_min_size = 0, num_regs = 0; ++ int worst_min_size = 0; + size_t tmp = 0; + + if (!guc->capture) +@@ -623,33 +682,58 @@ intel_guc_capture_output_min_size_est(struct intel_guc *guc) + * For each engine instance, there would be 1 x guc_state_capture_group_t output + * followed by 3 x guc_state_capture_t lists. The latter is how the register + * dumps are split across different register types (where the '3' are global vs class +- * vs instance). Finally, let's multiply the whole thing by 3x (just so we are +- * not limited to just 1 round of data in a worst case full register dump log) +- * +- * NOTE: intel_guc_log that allocates the log buffer would round this size up to +- * a power of two. ++ * vs instance). + */ +- + for_each_engine(engine, gt, id) { + worst_min_size += sizeof(struct guc_state_capture_group_header_t) + + (3 * sizeof(struct guc_state_capture_header_t)); + +- if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_GLOBAL, 0, &tmp)) +- num_regs += tmp; ++ if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_GLOBAL, 0, &tmp, true)) ++ worst_min_size += tmp; + +- if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS, +- engine->class, &tmp)) { +- num_regs += tmp; ++ if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS, ++ engine->class, &tmp, true)) { ++ worst_min_size += tmp; + } +- if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE, +- engine->class, &tmp)) { +- num_regs += tmp; ++ if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE, ++ engine->class, &tmp, true)) { ++ worst_min_size += tmp; + } + } + +- worst_min_size += (num_regs * sizeof(struct guc_mmio_reg)); ++ return worst_min_size; ++} ++ ++/* ++ * Add on a 3x multiplier to allow for multiple back-to-back captures occurring ++ * before the i915 can read the data out and process it ++ */ ++#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3 + +- return (worst_min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER); ++static void check_guc_capture_size(struct intel_guc *guc) ++{ ++ struct drm_i915_private *i915 = guc_to_gt(guc)->i915; ++ int min_size = guc_capture_output_min_size_est(guc); ++ int spare_size = min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER; ++ u32 buffer_size = intel_guc_log_section_size_capture(&guc->log); ++ ++ /* ++ * NOTE: min_size is much smaller than the capture region allocation (DG2: <80K vs 1MB) ++ * Additionally, its based on space needed to fit all engines getting reset at once ++ * within the same G2H handler task slot. This is very unlikely. However, if GuC really ++ * does run out of space for whatever reason, we will see an separate warning message ++ * when processing the G2H event capture-notification, search for: ++ * INTEL_GUC_STATE_CAPTURE_EVENT_STATUS_NOSPACE. ++ */ ++ if (min_size < 0) ++ drm_warn(&i915->drm, "Failed to calculate GuC error state capture buffer minimum size: %d!\n", ++ min_size); ++ else if (min_size > buffer_size) ++ drm_warn(&i915->drm, "GuC error state capture buffer maybe small: %d < %d\n", ++ buffer_size, min_size); ++ else if (spare_size > buffer_size) ++ drm_dbg(&i915->drm, "GuC error state capture buffer lacks spare size: %d < %d (min = %d)\n", ++ buffer_size, spare_size, min_size); + } + + /* +@@ -1278,7 +1362,8 @@ static void __guc_capture_process_output(struct intel_guc *guc) + + log_buf_state = guc->log.buf_addr + + (sizeof(struct guc_log_buffer_state) * GUC_CAPTURE_LOG_BUFFER); +- src_data = guc->log.buf_addr + intel_guc_get_log_buffer_offset(GUC_CAPTURE_LOG_BUFFER); ++ src_data = guc->log.buf_addr + ++ intel_guc_get_log_buffer_offset(&guc->log, GUC_CAPTURE_LOG_BUFFER); + + /* + * Make a copy of the state structure, inside GuC log buffer +@@ -1286,7 +1371,7 @@ static void __guc_capture_process_output(struct intel_guc *guc) + * from it multiple times. + */ + memcpy(&log_buf_state_local, log_buf_state, sizeof(struct guc_log_buffer_state)); +- buffer_size = intel_guc_get_log_buffer_size(GUC_CAPTURE_LOG_BUFFER); ++ buffer_size = intel_guc_get_log_buffer_size(&guc->log, GUC_CAPTURE_LOG_BUFFER); + read_offset = log_buf_state_local.read_ptr; + write_offset = log_buf_state_local.sampled_write_ptr; + full_count = log_buf_state_local.buffer_full_cnt; +@@ -1580,5 +1665,7 @@ int intel_guc_capture_init(struct intel_guc *guc) + INIT_LIST_HEAD(&guc->capture->outlist); + INIT_LIST_HEAD(&guc->capture->cachelist); + ++ check_guc_capture_size(guc); ++ + return 0; + } +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h +index d3d7bd0b6db64..fbd3713c7832d 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h +@@ -21,7 +21,6 @@ int intel_guc_capture_print_engine_node(struct drm_i915_error_state_buf *m, + void intel_guc_capture_get_matching_node(struct intel_gt *gt, struct intel_engine_coredump *ee, + struct intel_context *ce); + void intel_guc_capture_process(struct intel_guc *guc); +-int intel_guc_capture_output_min_size_est(struct intel_guc *guc); + int intel_guc_capture_getlist(struct intel_guc *guc, u32 owner, u32 type, u32 classid, + void **outptr); + int intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h +index 323b055e5db97..502e7cb5a3025 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h +@@ -305,6 +305,27 @@ struct guc_update_context_policy { + + #define GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US 500000 + ++/* ++ * GuC converts the timeout to clock ticks internally. Different platforms have ++ * different GuC clocks. Thus, the maximum value before overflow is platform ++ * dependent. Current worst case scenario is about 110s. So, the spec says to ++ * limit to 100s to be safe. ++ */ ++#define GUC_POLICY_MAX_EXEC_QUANTUM_US (100 * 1000 * 1000UL) ++#define GUC_POLICY_MAX_PREEMPT_TIMEOUT_US (100 * 1000 * 1000UL) ++ ++static inline u32 guc_policy_max_exec_quantum_ms(void) ++{ ++ BUILD_BUG_ON(GUC_POLICY_MAX_EXEC_QUANTUM_US >= UINT_MAX); ++ return GUC_POLICY_MAX_EXEC_QUANTUM_US / 1000; ++} ++ ++static inline u32 guc_policy_max_preempt_timeout_ms(void) ++{ ++ BUILD_BUG_ON(GUC_POLICY_MAX_PREEMPT_TIMEOUT_US >= UINT_MAX); ++ return GUC_POLICY_MAX_PREEMPT_TIMEOUT_US / 1000; ++} ++ + struct guc_policies { + u32 submission_queue_depth[GUC_MAX_ENGINE_CLASSES]; + /* In micro seconds. How much time to allow before DPC processing is +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +index 25b2d7ce6640d..8d755d285247e 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +@@ -13,8 +13,187 @@ + #include "intel_guc_capture.h" + #include "intel_guc_log.h" + ++#if defined(CONFIG_DRM_I915_DEBUG_GUC) ++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_2M ++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_16M ++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M ++#elif defined(CONFIG_DRM_I915_DEBUG_GEM) ++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_1M ++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_2M ++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M ++#else ++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_8K ++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_64K ++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M ++#endif ++ + static void guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log); + ++struct guc_log_section { ++ u32 max; ++ u32 flag; ++ u32 default_val; ++ const char *name; ++}; ++ ++static s32 scale_log_param(struct intel_guc_log *log, const struct guc_log_section *section, ++ s32 param) ++{ ++ /* -1 means default */ ++ if (param < 0) ++ return section->default_val; ++ ++ /* Check for 32-bit overflow */ ++ if (param >= SZ_4K) { ++ drm_err(&guc_to_gt(log_to_guc(log))->i915->drm, "Size too large for GuC %s log: %dMB!", ++ section->name, param); ++ return section->default_val; ++ } ++ ++ /* Param units are 1MB */ ++ return param * SZ_1M; ++} ++ ++static void _guc_log_init_sizes(struct intel_guc_log *log) ++{ ++ struct intel_guc *guc = log_to_guc(log); ++ struct drm_i915_private *i915 = guc_to_gt(guc)->i915; ++ static const struct guc_log_section sections[GUC_LOG_SECTIONS_LIMIT] = { ++ { ++ GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT, ++ GUC_LOG_LOG_ALLOC_UNITS, ++ GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE, ++ "crash dump" ++ }, ++ { ++ GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT, ++ GUC_LOG_LOG_ALLOC_UNITS, ++ GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE, ++ "debug", ++ }, ++ { ++ GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT, ++ GUC_LOG_CAPTURE_ALLOC_UNITS, ++ GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE, ++ "capture", ++ } ++ }; ++ s32 params[GUC_LOG_SECTIONS_LIMIT] = { ++ i915->params.guc_log_size_crash, ++ i915->params.guc_log_size_debug, ++ i915->params.guc_log_size_capture, ++ }; ++ int i; ++ ++ for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++) ++ log->sizes[i].bytes = scale_log_param(log, sections + i, params[i]); ++ ++ /* If debug size > 1MB then bump default crash size to keep the same units */ ++ if (log->sizes[GUC_LOG_SECTIONS_DEBUG].bytes >= SZ_1M && ++ (i915->params.guc_log_size_crash == -1) && ++ GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE < SZ_1M) ++ log->sizes[GUC_LOG_SECTIONS_CRASH].bytes = SZ_1M; ++ ++ /* Prepare the GuC API structure fields: */ ++ for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++) { ++ /* Convert to correct units */ ++ if ((log->sizes[i].bytes % SZ_1M) == 0) { ++ log->sizes[i].units = SZ_1M; ++ log->sizes[i].flag = sections[i].flag; ++ } else { ++ log->sizes[i].units = SZ_4K; ++ log->sizes[i].flag = 0; ++ } ++ ++ if (!IS_ALIGNED(log->sizes[i].bytes, log->sizes[i].units)) ++ drm_err(&i915->drm, "Mis-aligned GuC log %s size: 0x%X vs 0x%X!", ++ sections[i].name, log->sizes[i].bytes, log->sizes[i].units); ++ log->sizes[i].count = log->sizes[i].bytes / log->sizes[i].units; ++ ++ if (!log->sizes[i].count) { ++ drm_err(&i915->drm, "Zero GuC log %s size!", sections[i].name); ++ } else { ++ /* Size is +1 unit */ ++ log->sizes[i].count--; ++ } ++ ++ /* Clip to field size */ ++ if (log->sizes[i].count > sections[i].max) { ++ drm_err(&i915->drm, "GuC log %s size too large: %d vs %d!", ++ sections[i].name, log->sizes[i].count + 1, sections[i].max + 1); ++ log->sizes[i].count = sections[i].max; ++ } ++ } ++ ++ if (log->sizes[GUC_LOG_SECTIONS_CRASH].units != log->sizes[GUC_LOG_SECTIONS_DEBUG].units) { ++ drm_err(&i915->drm, "Unit mis-match for GuC log crash and debug sections: %d vs %d!", ++ log->sizes[GUC_LOG_SECTIONS_CRASH].units, ++ log->sizes[GUC_LOG_SECTIONS_DEBUG].units); ++ log->sizes[GUC_LOG_SECTIONS_CRASH].units = log->sizes[GUC_LOG_SECTIONS_DEBUG].units; ++ log->sizes[GUC_LOG_SECTIONS_CRASH].count = 0; ++ } ++ ++ log->sizes_initialised = true; ++} ++ ++static void guc_log_init_sizes(struct intel_guc_log *log) ++{ ++ if (log->sizes_initialised) ++ return; ++ ++ _guc_log_init_sizes(log); ++} ++ ++static u32 intel_guc_log_section_size_crash(struct intel_guc_log *log) ++{ ++ guc_log_init_sizes(log); ++ ++ return log->sizes[GUC_LOG_SECTIONS_CRASH].bytes; ++} ++ ++static u32 intel_guc_log_section_size_debug(struct intel_guc_log *log) ++{ ++ guc_log_init_sizes(log); ++ ++ return log->sizes[GUC_LOG_SECTIONS_DEBUG].bytes; ++} ++ ++u32 intel_guc_log_section_size_capture(struct intel_guc_log *log) ++{ ++ guc_log_init_sizes(log); ++ ++ return log->sizes[GUC_LOG_SECTIONS_CAPTURE].bytes; ++} ++ ++static u32 intel_guc_log_size(struct intel_guc_log *log) ++{ ++ /* ++ * GuC Log buffer Layout: ++ * ++ * NB: Ordering must follow "enum guc_log_buffer_type". ++ * ++ * +===============================+ 00B ++ * | Debug state header | ++ * +-------------------------------+ 32B ++ * | Crash dump state header | ++ * +-------------------------------+ 64B ++ * | Capture state header | ++ * +-------------------------------+ 96B ++ * | | ++ * +===============================+ PAGE_SIZE (4KB) ++ * | Debug logs | ++ * +===============================+ + DEBUG_SIZE ++ * | Crash Dump logs | ++ * +===============================+ + CRASH_SIZE ++ * | Capture logs | ++ * +===============================+ + CAPTURE_SIZE ++ */ ++ return PAGE_SIZE + ++ intel_guc_log_section_size_crash(log) + ++ intel_guc_log_section_size_debug(log) + ++ intel_guc_log_section_size_capture(log); ++} ++ + /** + * DOC: GuC firmware log + * +@@ -139,7 +318,8 @@ static void guc_move_to_next_buf(struct intel_guc_log *log) + smp_wmb(); + + /* All data has been written, so now move the offset of sub buffer. */ +- relay_reserve(log->relay.channel, log->vma->obj->base.size - CAPTURE_BUFFER_SIZE); ++ relay_reserve(log->relay.channel, log->vma->obj->base.size - ++ intel_guc_log_section_size_capture(log)); + + /* Switch to the next sub buffer */ + relay_flush(log->relay.channel); +@@ -184,15 +364,16 @@ bool intel_guc_check_log_buf_overflow(struct intel_guc_log *log, + return overflow; + } + +-unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type) ++unsigned int intel_guc_get_log_buffer_size(struct intel_guc_log *log, ++ enum guc_log_buffer_type type) + { + switch (type) { + case GUC_DEBUG_LOG_BUFFER: +- return DEBUG_BUFFER_SIZE; ++ return intel_guc_log_section_size_debug(log); + case GUC_CRASH_DUMP_LOG_BUFFER: +- return CRASH_BUFFER_SIZE; ++ return intel_guc_log_section_size_crash(log); + case GUC_CAPTURE_LOG_BUFFER: +- return CAPTURE_BUFFER_SIZE; ++ return intel_guc_log_section_size_capture(log); + default: + MISSING_CASE(type); + } +@@ -200,7 +381,8 @@ unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type) + return 0; + } + +-size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type) ++size_t intel_guc_get_log_buffer_offset(struct intel_guc_log *log, ++ enum guc_log_buffer_type type) + { + enum guc_log_buffer_type i; + size_t offset = PAGE_SIZE;/* for the log_buffer_states */ +@@ -208,7 +390,7 @@ size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type) + for (i = GUC_DEBUG_LOG_BUFFER; i < GUC_MAX_LOG_BUFFER; ++i) { + if (i == type) + break; +- offset += intel_guc_get_log_buffer_size(i); ++ offset += intel_guc_get_log_buffer_size(log, i); + } + + return offset; +@@ -259,7 +441,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log) + */ + memcpy(&log_buf_state_local, log_buf_state, + sizeof(struct guc_log_buffer_state)); +- buffer_size = intel_guc_get_log_buffer_size(type); ++ buffer_size = intel_guc_get_log_buffer_size(log, type); + read_offset = log_buf_state_local.read_ptr; + write_offset = log_buf_state_local.sampled_write_ptr; + full_cnt = log_buf_state_local.buffer_full_cnt; +@@ -374,7 +556,7 @@ static int guc_log_relay_create(struct intel_guc_log *log) + * Keep the size of sub buffers same as shared log buffer + * but GuC log-events excludes the error-state-capture logs + */ +- subbuf_size = log->vma->size - CAPTURE_BUFFER_SIZE; ++ subbuf_size = log->vma->size - intel_guc_log_section_size_capture(log); + + /* + * Store up to 8 snapshots, which is large enough to buffer sufficient +@@ -461,32 +643,7 @@ int intel_guc_log_create(struct intel_guc_log *log) + + GEM_BUG_ON(log->vma); + +- /* +- * GuC Log buffer Layout +- * (this ordering must follow "enum guc_log_buffer_type" definition) +- * +- * +===============================+ 00B +- * | Debug state header | +- * +-------------------------------+ 32B +- * | Crash dump state header | +- * +-------------------------------+ 64B +- * | Capture state header | +- * +-------------------------------+ 96B +- * | | +- * +===============================+ PAGE_SIZE (4KB) +- * | Debug logs | +- * +===============================+ + DEBUG_SIZE +- * | Crash Dump logs | +- * +===============================+ + CRASH_SIZE +- * | Capture logs | +- * +===============================+ + CAPTURE_SIZE +- */ +- if (intel_guc_capture_output_min_size_est(guc) > CAPTURE_BUFFER_SIZE) +- DRM_WARN("GuC log buffer for state_capture maybe too small. %d < %d\n", +- CAPTURE_BUFFER_SIZE, intel_guc_capture_output_min_size_est(guc)); +- +- guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE + +- CAPTURE_BUFFER_SIZE; ++ guc_log_size = intel_guc_log_size(log); + + vma = intel_guc_allocate_vma(guc, guc_log_size); + if (IS_ERR(vma)) { +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h +index 18007e639be99..02127703be809 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h +@@ -15,20 +15,6 @@ + + struct intel_guc; + +-#if defined(CONFIG_DRM_I915_DEBUG_GUC) +-#define CRASH_BUFFER_SIZE SZ_2M +-#define DEBUG_BUFFER_SIZE SZ_16M +-#define CAPTURE_BUFFER_SIZE SZ_4M +-#elif defined(CONFIG_DRM_I915_DEBUG_GEM) +-#define CRASH_BUFFER_SIZE SZ_1M +-#define DEBUG_BUFFER_SIZE SZ_2M +-#define CAPTURE_BUFFER_SIZE SZ_1M +-#else +-#define CRASH_BUFFER_SIZE SZ_8K +-#define DEBUG_BUFFER_SIZE SZ_64K +-#define CAPTURE_BUFFER_SIZE SZ_16K +-#endif +- + /* + * While we're using plain log level in i915, GuC controls are much more... + * "elaborate"? We have a couple of bits for verbosity, separate bit for actual +@@ -46,10 +32,30 @@ struct intel_guc; + #define GUC_VERBOSITY_TO_LOG_LEVEL(x) ((x) + 2) + #define GUC_LOG_LEVEL_MAX GUC_VERBOSITY_TO_LOG_LEVEL(GUC_LOG_VERBOSITY_MAX) + ++enum { ++ GUC_LOG_SECTIONS_CRASH, ++ GUC_LOG_SECTIONS_DEBUG, ++ GUC_LOG_SECTIONS_CAPTURE, ++ GUC_LOG_SECTIONS_LIMIT ++}; ++ + struct intel_guc_log { + u32 level; ++ ++ /* Allocation settings */ ++ struct { ++ s32 bytes; /* Size in bytes */ ++ s32 units; /* GuC API units - 1MB or 4KB */ ++ s32 count; /* Number of API units */ ++ u32 flag; /* GuC API units flag */ ++ } sizes[GUC_LOG_SECTIONS_LIMIT]; ++ bool sizes_initialised; ++ ++ /* Combined buffer allocation */ + struct i915_vma *vma; + void *buf_addr; ++ ++ /* RelayFS support */ + struct { + bool buf_in_use; + bool started; +@@ -58,6 +64,7 @@ struct intel_guc_log { + struct mutex lock; + u32 full_count; + } relay; ++ + /* logging related stats */ + struct { + u32 sampled_overflow; +@@ -69,8 +76,9 @@ struct intel_guc_log { + void intel_guc_log_init_early(struct intel_guc_log *log); + bool intel_guc_check_log_buf_overflow(struct intel_guc_log *log, enum guc_log_buffer_type type, + unsigned int full_cnt); +-unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type); +-size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type); ++unsigned int intel_guc_get_log_buffer_size(struct intel_guc_log *log, ++ enum guc_log_buffer_type type); ++size_t intel_guc_get_log_buffer_offset(struct intel_guc_log *log, enum guc_log_buffer_type type); + int intel_guc_log_create(struct intel_guc_log *log); + void intel_guc_log_destroy(struct intel_guc_log *log); + +@@ -92,4 +100,6 @@ void intel_guc_log_info(struct intel_guc_log *log, struct drm_printer *p); + int intel_guc_log_dump(struct intel_guc_log *log, struct drm_printer *p, + bool dump_load_err); + ++u32 intel_guc_log_section_size_capture(struct intel_guc_log *log); ++ + #endif +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +index fe179146d51b9..cd0c5043863b6 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +@@ -2430,6 +2430,10 @@ static int guc_context_policy_init_v70(struct intel_context *ce, bool loop) + int ret; + + /* NB: For both of these, zero means disabled. */ ++ GEM_BUG_ON(overflows_type(engine->props.timeslice_duration_ms * 1000, ++ execution_quantum)); ++ GEM_BUG_ON(overflows_type(engine->props.preempt_timeout_ms * 1000, ++ preemption_timeout)); + execution_quantum = engine->props.timeslice_duration_ms * 1000; + preemption_timeout = engine->props.preempt_timeout_ms * 1000; + +@@ -2486,6 +2490,10 @@ static void guc_context_policy_init_v69(struct intel_engine_cs *engine, + desc->policy_flags |= CONTEXT_POLICY_FLAG_PREEMPT_TO_IDLE_V69; + + /* NB: For both of these, zero means disabled. */ ++ GEM_BUG_ON(overflows_type(engine->props.timeslice_duration_ms * 1000, ++ desc->execution_quantum)); ++ GEM_BUG_ON(overflows_type(engine->props.preempt_timeout_ms * 1000, ++ desc->preemption_timeout)); + desc->execution_quantum = engine->props.timeslice_duration_ms * 1000; + desc->preemption_timeout = engine->props.preempt_timeout_ms * 1000; + } +diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c +index 6fc475a5db615..06ca5b8221118 100644 +--- a/drivers/gpu/drm/i915/i915_params.c ++++ b/drivers/gpu/drm/i915/i915_params.c +@@ -171,6 +171,18 @@ i915_param_named(guc_log_level, int, 0400, + "GuC firmware logging level. Requires GuC to be loaded. " + "(-1=auto [default], 0=disable, 1..4=enable with verbosity min..max)"); + ++i915_param_named(guc_log_size_crash, int, 0400, ++ "GuC firmware logging buffer size for crash dumps (in MB)" ++ "(-1=auto [default], NB: max = 4, other restrictions apply)"); ++ ++i915_param_named(guc_log_size_debug, int, 0400, ++ "GuC firmware logging buffer size for debug logs (in MB)" ++ "(-1=auto [default], NB: max = 16, other restrictions apply)"); ++ ++i915_param_named(guc_log_size_capture, int, 0400, ++ "GuC error capture register dump buffer size (in MB)" ++ "(-1=auto [default], NB: max = 4, other restrictions apply)"); ++ + i915_param_named_unsafe(guc_firmware_path, charp, 0400, + "GuC firmware path to use instead of the default one"); + +diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h +index 2733cb6cfe094..f684d1ab87078 100644 +--- a/drivers/gpu/drm/i915/i915_params.h ++++ b/drivers/gpu/drm/i915/i915_params.h +@@ -61,6 +61,9 @@ struct drm_printer; + param(int, invert_brightness, 0, 0600) \ + param(int, enable_guc, -1, 0400) \ + param(int, guc_log_level, -1, 0400) \ ++ param(int, guc_log_size_crash, -1, 0400) \ ++ param(int, guc_log_size_debug, -1, 0400) \ ++ param(int, guc_log_size_capture, -1, 0400) \ + param(char *, guc_firmware_path, NULL, 0400) \ + param(char *, huc_firmware_path, NULL, 0400) \ + param(char *, dmc_firmware_path, NULL, 0400) \ +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 630a4e301ef6c..b11b5a2c06639 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -462,9 +462,6 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi) + if (--dpi->refcount != 0) + return; + +- if (dpi->pinctrl && dpi->pins_gpio) +- pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio); +- + mtk_dpi_disable(dpi); + clk_disable_unprepare(dpi->pixel_clk); + clk_disable_unprepare(dpi->engine_clk); +@@ -489,9 +486,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi) + goto err_pixel; + } + +- if (dpi->pinctrl && dpi->pins_dpi) +- pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi); +- + return 0; + + err_pixel: +@@ -722,12 +716,18 @@ static void mtk_dpi_bridge_disable(struct drm_bridge *bridge) + struct mtk_dpi *dpi = bridge_to_dpi(bridge); + + mtk_dpi_power_off(dpi); ++ ++ if (dpi->pinctrl && dpi->pins_gpio) ++ pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio); + } + + static void mtk_dpi_bridge_enable(struct drm_bridge *bridge) + { + struct mtk_dpi *dpi = bridge_to_dpi(bridge); + ++ if (dpi->pinctrl && dpi->pins_dpi) ++ pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi); ++ + mtk_dpi_power_on(dpi); + mtk_dpi_set_display_mode(dpi, &dpi->mode); + mtk_dpi_enable(dpi); +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c +index 3196189429bcf..7613b0fa2be6e 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c +@@ -1203,9 +1203,10 @@ static enum drm_connector_status mtk_hdmi_detect(struct mtk_hdmi *hdmi) + return mtk_hdmi_update_plugged_status(hdmi); + } + +-static int mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge, +- const struct drm_display_info *info, +- const struct drm_display_mode *mode) ++static enum drm_mode_status ++mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge, ++ const struct drm_display_info *info, ++ const struct drm_display_mode *mode) + { + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); + struct drm_bridge *next_bridge; +diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c +index 5675bc2a92cf8..3f73b211fa8e3 100644 +--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c ++++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c +@@ -116,9 +116,10 @@ static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge, + return i; + } + +-static int meson_encoder_cvbs_mode_valid(struct drm_bridge *bridge, +- const struct drm_display_info *display_info, +- const struct drm_display_mode *mode) ++static enum drm_mode_status ++meson_encoder_cvbs_mode_valid(struct drm_bridge *bridge, ++ const struct drm_display_info *display_info, ++ const struct drm_display_mode *mode) + { + if (meson_cvbs_get_mode(mode)) + return MODE_OK; +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +index 4d501100b9e45..5804c35ae74b3 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +@@ -1869,7 +1869,7 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) + + if (val == UINT_MAX) { + DRM_DEV_ERROR(dev, +- "missing support for speed-bin: %u. Some OPPs may not be supported by hardware", ++ "missing support for speed-bin: %u. Some OPPs may not be supported by hardware\n", + fuse); + return UINT_MAX; + } +@@ -1879,7 +1879,7 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) + + static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) + { +- u32 supp_hw = UINT_MAX; ++ u32 supp_hw; + u32 speedbin; + int ret; + +@@ -1891,15 +1891,13 @@ static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) + if (ret == -ENOENT) { + return 0; + } else if (ret) { +- DRM_DEV_ERROR(dev, +- "failed to read speed-bin (%d). Some OPPs may not be supported by hardware", +- ret); +- goto done; ++ dev_err_probe(dev, ret, ++ "failed to read speed-bin. Some OPPs may not be supported by hardware\n"); ++ return ret; + } + + supp_hw = fuse_to_supp_hw(dev, rev, speedbin); + +-done: + ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +index 52a626117f70f..7f5dba96b2ffa 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +@@ -162,7 +162,7 @@ enum dpu_enc_rc_states { + * @vsync_event_work: worker to handle vsync event for autorefresh + * @topology: topology of the display + * @idle_timeout: idle timeout duration in milliseconds +- * @dsc: msm_display_dsc_config pointer, for DSC-enabled encoders ++ * @dsc: drm_dsc_config pointer, for DSC-enabled encoders + */ + struct dpu_encoder_virt { + struct drm_encoder base; +@@ -208,7 +208,7 @@ struct dpu_encoder_virt { + bool wide_bus_en; + + /* DSC configuration */ +- struct msm_display_dsc_config *dsc; ++ struct drm_dsc_config *dsc; + }; + + #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base) +@@ -1791,12 +1791,12 @@ static void dpu_encoder_vsync_event_work_handler(struct kthread_work *work) + } + + static u32 +-dpu_encoder_dsc_initial_line_calc(struct msm_display_dsc_config *dsc, ++dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc, + u32 enc_ip_width) + { + int ssm_delay, total_pixels, soft_slice_per_enc; + +- soft_slice_per_enc = enc_ip_width / dsc->drm->slice_width; ++ soft_slice_per_enc = enc_ip_width / dsc->slice_width; + + /* + * minimum number of initial line pixels is a sum of: +@@ -1808,16 +1808,16 @@ dpu_encoder_dsc_initial_line_calc(struct msm_display_dsc_config *dsc, + * 5. 6 additional pixels as the output of the rate buffer is + * 48 bits wide + */ +- ssm_delay = ((dsc->drm->bits_per_component < 10) ? 84 : 92); +- total_pixels = ssm_delay * 3 + dsc->drm->initial_xmit_delay + 47; ++ ssm_delay = ((dsc->bits_per_component < 10) ? 84 : 92); ++ total_pixels = ssm_delay * 3 + dsc->initial_xmit_delay + 47; + if (soft_slice_per_enc > 1) + total_pixels += (ssm_delay * 3); +- return DIV_ROUND_UP(total_pixels, dsc->drm->slice_width); ++ return DIV_ROUND_UP(total_pixels, dsc->slice_width); + } + + static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, + struct dpu_hw_pingpong *hw_pp, +- struct msm_display_dsc_config *dsc, ++ struct drm_dsc_config *dsc, + u32 common_mode, + u32 initial_lines) + { +@@ -1835,7 +1835,7 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, + } + + static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, +- struct msm_display_dsc_config *dsc) ++ struct drm_dsc_config *dsc) + { + /* coding only for 2LM, 2enc, 1 dsc config */ + struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; +@@ -1858,14 +1858,15 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, + } + } + +- pic_width = dsc->drm->pic_width; ++ dsc_common_mode = 0; ++ pic_width = dsc->pic_width; + + dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL; + if (enc_master->intf_mode == INTF_MODE_VIDEO) + dsc_common_mode |= DSC_MODE_VIDEO; + +- this_frame_slices = pic_width / dsc->drm->slice_width; +- intf_ip_w = this_frame_slices * dsc->drm->slice_width; ++ this_frame_slices = pic_width / dsc->slice_width; ++ intf_ip_w = this_frame_slices * dsc->slice_width; + + /* + * dsc merge case: when using 2 encoders for the same stream, +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +index d4d1ecd416e39..9e7236ef34e6d 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +@@ -36,7 +36,7 @@ struct msm_display_info { + uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY]; + bool is_cmd_mode; + bool is_te_using_watchdog_timer; +- struct msm_display_dsc_config *dsc; ++ struct drm_dsc_config *dsc; + }; + + /** +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +index 411689ae63825..3662df698dae5 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +@@ -37,12 +37,12 @@ static void dpu_hw_dsc_disable(struct dpu_hw_dsc *dsc) + } + + static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, +- struct msm_display_dsc_config *dsc, ++ struct drm_dsc_config *dsc, + u32 mode, + u32 initial_lines) + { + struct dpu_hw_blk_reg_map *c = &hw_dsc->hw; +- u32 data, lsb, bpp; ++ u32 data; + u32 slice_last_group_size; + u32 det_thresh_flatness; + bool is_cmd_mode = !(mode & DSC_MODE_VIDEO); +@@ -52,89 +52,82 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, + if (is_cmd_mode) + initial_lines += 1; + +- slice_last_group_size = 3 - (dsc->drm->slice_width % 3); ++ slice_last_group_size = 3 - (dsc->slice_width % 3); + data = (initial_lines << 20); + data |= ((slice_last_group_size - 1) << 18); + /* bpp is 6.4 format, 4 LSBs bits are for fractional part */ +- data |= dsc->drm->bits_per_pixel << 12; +- lsb = dsc->drm->bits_per_pixel % 4; +- bpp = dsc->drm->bits_per_pixel / 4; +- bpp *= 4; +- bpp <<= 4; +- bpp |= lsb; +- +- data |= bpp << 8; +- data |= (dsc->drm->block_pred_enable << 7); +- data |= (dsc->drm->line_buf_depth << 3); +- data |= (dsc->drm->simple_422 << 2); +- data |= (dsc->drm->convert_rgb << 1); +- data |= dsc->drm->bits_per_component; ++ data |= (dsc->bits_per_pixel << 8); ++ data |= (dsc->block_pred_enable << 7); ++ data |= (dsc->line_buf_depth << 3); ++ data |= (dsc->simple_422 << 2); ++ data |= (dsc->convert_rgb << 1); ++ data |= dsc->bits_per_component; + + DPU_REG_WRITE(c, DSC_ENC, data); + +- data = dsc->drm->pic_width << 16; +- data |= dsc->drm->pic_height; ++ data = dsc->pic_width << 16; ++ data |= dsc->pic_height; + DPU_REG_WRITE(c, DSC_PICTURE, data); + +- data = dsc->drm->slice_width << 16; +- data |= dsc->drm->slice_height; ++ data = dsc->slice_width << 16; ++ data |= dsc->slice_height; + DPU_REG_WRITE(c, DSC_SLICE, data); + +- data = dsc->drm->slice_chunk_size << 16; ++ data = dsc->slice_chunk_size << 16; + DPU_REG_WRITE(c, DSC_CHUNK_SIZE, data); + +- data = dsc->drm->initial_dec_delay << 16; +- data |= dsc->drm->initial_xmit_delay; ++ data = dsc->initial_dec_delay << 16; ++ data |= dsc->initial_xmit_delay; + DPU_REG_WRITE(c, DSC_DELAY, data); + +- data = dsc->drm->initial_scale_value; ++ data = dsc->initial_scale_value; + DPU_REG_WRITE(c, DSC_SCALE_INITIAL, data); + +- data = dsc->drm->scale_decrement_interval; ++ data = dsc->scale_decrement_interval; + DPU_REG_WRITE(c, DSC_SCALE_DEC_INTERVAL, data); + +- data = dsc->drm->scale_increment_interval; ++ data = dsc->scale_increment_interval; + DPU_REG_WRITE(c, DSC_SCALE_INC_INTERVAL, data); + +- data = dsc->drm->first_line_bpg_offset; ++ data = dsc->first_line_bpg_offset; + DPU_REG_WRITE(c, DSC_FIRST_LINE_BPG_OFFSET, data); + +- data = dsc->drm->nfl_bpg_offset << 16; +- data |= dsc->drm->slice_bpg_offset; ++ data = dsc->nfl_bpg_offset << 16; ++ data |= dsc->slice_bpg_offset; + DPU_REG_WRITE(c, DSC_BPG_OFFSET, data); + +- data = dsc->drm->initial_offset << 16; +- data |= dsc->drm->final_offset; ++ data = dsc->initial_offset << 16; ++ data |= dsc->final_offset; + DPU_REG_WRITE(c, DSC_DSC_OFFSET, data); + +- det_thresh_flatness = 7 + 2 * (dsc->drm->bits_per_component - 8); ++ det_thresh_flatness = 7 + 2 * (dsc->bits_per_component - 8); + data = det_thresh_flatness << 10; +- data |= dsc->drm->flatness_max_qp << 5; +- data |= dsc->drm->flatness_min_qp; ++ data |= dsc->flatness_max_qp << 5; ++ data |= dsc->flatness_min_qp; + DPU_REG_WRITE(c, DSC_FLATNESS, data); + +- data = dsc->drm->rc_model_size; ++ data = dsc->rc_model_size; + DPU_REG_WRITE(c, DSC_RC_MODEL_SIZE, data); + +- data = dsc->drm->rc_tgt_offset_low << 18; +- data |= dsc->drm->rc_tgt_offset_high << 14; +- data |= dsc->drm->rc_quant_incr_limit1 << 9; +- data |= dsc->drm->rc_quant_incr_limit0 << 4; +- data |= dsc->drm->rc_edge_factor; ++ data = dsc->rc_tgt_offset_low << 18; ++ data |= dsc->rc_tgt_offset_high << 14; ++ data |= dsc->rc_quant_incr_limit1 << 9; ++ data |= dsc->rc_quant_incr_limit0 << 4; ++ data |= dsc->rc_edge_factor; + DPU_REG_WRITE(c, DSC_RC, data); + } + + static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc, +- struct msm_display_dsc_config *dsc) ++ struct drm_dsc_config *dsc) + { +- struct drm_dsc_rc_range_parameters *rc = dsc->drm->rc_range_params; ++ struct drm_dsc_rc_range_parameters *rc = dsc->rc_range_params; + struct dpu_hw_blk_reg_map *c = &hw_dsc->hw; + u32 off; + int i; + + off = DSC_RC_BUF_THRESH; + for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++) { +- DPU_REG_WRITE(c, off, dsc->drm->rc_buf_thresh[i]); ++ DPU_REG_WRITE(c, off, dsc->rc_buf_thresh[i]); + off += 4; + } + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +index 45e4118f1fa27..c0b77fe1a6968 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +@@ -31,7 +31,7 @@ struct dpu_hw_dsc_ops { + * @initial_lines: amount of initial lines to be used + */ + void (*dsc_config)(struct dpu_hw_dsc *hw_dsc, +- struct msm_display_dsc_config *dsc, ++ struct drm_dsc_config *dsc, + u32 mode, + u32 initial_lines); + +@@ -41,7 +41,7 @@ struct dpu_hw_dsc_ops { + * @dsc: panel dsc parameters + */ + void (*dsc_config_thresh)(struct dpu_hw_dsc *hw_dsc, +- struct msm_display_dsc_config *dsc); ++ struct drm_dsc_config *dsc); + }; + + struct dpu_hw_dsc { +diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +index b0d21838a1343..29ae5c9613f36 100644 +--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c ++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +@@ -203,7 +203,7 @@ static int mdp5_set_split_display(struct msm_kms *kms, + slave_encoder); + } + +-static void mdp5_destroy(struct platform_device *pdev); ++static void mdp5_destroy(struct mdp5_kms *mdp5_kms); + + static void mdp5_kms_destroy(struct msm_kms *kms) + { +@@ -223,7 +223,7 @@ static void mdp5_kms_destroy(struct msm_kms *kms) + } + + mdp_kms_destroy(&mdp5_kms->base); +- mdp5_destroy(mdp5_kms->pdev); ++ mdp5_destroy(mdp5_kms); + } + + #ifdef CONFIG_DEBUG_FS +@@ -559,6 +559,8 @@ static int mdp5_kms_init(struct drm_device *dev) + int irq, i, ret; + + ret = mdp5_init(to_platform_device(dev->dev), dev); ++ if (ret) ++ return ret; + + /* priv->kms would have been populated by the MDP5 driver */ + kms = priv->kms; +@@ -632,9 +634,8 @@ fail: + return ret; + } + +-static void mdp5_destroy(struct platform_device *pdev) ++static void mdp5_destroy(struct mdp5_kms *mdp5_kms) + { +- struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev); + int i; + + if (mdp5_kms->ctlm) +@@ -648,7 +649,7 @@ static void mdp5_destroy(struct platform_device *pdev) + kfree(mdp5_kms->intfs[i]); + + if (mdp5_kms->rpm_enabled) +- pm_runtime_disable(&pdev->dev); ++ pm_runtime_disable(&mdp5_kms->pdev->dev); + + drm_atomic_private_obj_fini(&mdp5_kms->glob_state); + drm_modeset_lock_fini(&mdp5_kms->glob_state_lock); +@@ -797,8 +798,6 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) + goto fail; + } + +- platform_set_drvdata(pdev, mdp5_kms); +- + spin_lock_init(&mdp5_kms->resource_lock); + + mdp5_kms->dev = dev; +@@ -839,6 +838,9 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) + */ + clk_set_rate(mdp5_kms->core_clk, 200000000); + ++ /* set uninit-ed kms */ ++ priv->kms = &mdp5_kms->base.base; ++ + pm_runtime_enable(&pdev->dev); + mdp5_kms->rpm_enabled = true; + +@@ -890,13 +892,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) + if (ret) + goto fail; + +- /* set uninit-ed kms */ +- priv->kms = &mdp5_kms->base.base; +- + return 0; + fail: + if (mdp5_kms) +- mdp5_destroy(pdev); ++ mdp5_destroy(mdp5_kms); + return ret; + } + +@@ -953,7 +952,8 @@ static int mdp5_dev_remove(struct platform_device *pdev) + static __maybe_unused int mdp5_runtime_suspend(struct device *dev) + { + struct platform_device *pdev = to_platform_device(dev); +- struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev); ++ struct msm_drm_private *priv = platform_get_drvdata(pdev); ++ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); + + DBG(""); + +@@ -963,7 +963,8 @@ static __maybe_unused int mdp5_runtime_suspend(struct device *dev) + static __maybe_unused int mdp5_runtime_resume(struct device *dev) + { + struct platform_device *pdev = to_platform_device(dev); +- struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev); ++ struct msm_drm_private *priv = platform_get_drvdata(pdev); ++ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); + + DBG(""); + +diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c +index a49f6dbbe8883..c9d9b384ddd03 100644 +--- a/drivers/gpu/drm/msm/dp/dp_display.c ++++ b/drivers/gpu/drm/msm/dp/dp_display.c +@@ -857,7 +857,7 @@ static int dp_display_set_mode(struct msm_dp *dp_display, + + dp = container_of(dp_display, struct dp_display_private, dp_display); + +- dp->panel->dp_mode.drm_mode = mode->drm_mode; ++ drm_mode_copy(&dp->panel->dp_mode.drm_mode, &mode->drm_mode); + dp->panel->dp_mode.bpp = mode->bpp; + dp->panel->dp_mode.capabilities = mode->capabilities; + dp_panel_init_panel_info(dp->panel); +diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c +index 3db85b5c0febd..31e452ede71f0 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi.c ++++ b/drivers/gpu/drm/msm/dsi/dsi.c +@@ -21,7 +21,7 @@ bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi) + return !(host_flags & MIPI_DSI_MODE_VIDEO); + } + +-struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi) ++struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi) + { + return msm_dsi_host_get_dsc_config(msm_dsi->host); + } +diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h +index 580a1e6358bfc..df46cdda1b433 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi.h ++++ b/drivers/gpu/drm/msm/dsi/dsi.h +@@ -154,7 +154,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi); + int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi); + void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct mipi_dsi_host *host); + void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host); +-struct msm_display_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host); ++struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host); + + /* dsi phy */ + struct msm_dsi_phy; +diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c +index a34078497af12..cf7d5b69aac58 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_host.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c +@@ -21,6 +21,7 @@ + + #include