diff options
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1133_linux-5.15.134.patch | 13841 |
2 files changed, 13845 insertions, 0 deletions
diff --git a/0000_README b/0000_README index cff36e07..f55c19af 100644 --- a/0000_README +++ b/0000_README @@ -575,6 +575,10 @@ Patch: 1132_linux-5.15.133.patch From: https://www.kernel.org Desc: Linux 5.15.133 +Patch: 1133_linux-5.15.134.patch +From: https://www.kernel.org +Desc: Linux 5.15.134 + 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/1133_linux-5.15.134.patch b/1133_linux-5.15.134.patch new file mode 100644 index 00000000..1e943a3f --- /dev/null +++ b/1133_linux-5.15.134.patch @@ -0,0 +1,13841 @@ +diff --git a/Makefile b/Makefile +index b6e42a131235d..9800b8d6046a8 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 15 +-SUBLEVEL = 133 ++SUBLEVEL = 134 + EXTRAVERSION = + NAME = Trick or Treat + +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index f6ec85d58dd12..f53695ecbb782 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for AM33XX SoC + * + * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/bus/ti-sysc.h> +diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi +index de33c4f89f33d..cb316135bc7c9 100644 +--- a/arch/arm/boot/dts/am3517.dtsi ++++ b/arch/arm/boot/dts/am3517.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for am3517 SoC + * + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include "omap3.dtsi" +diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi +index 61a1d88f9df68..8613355bbd5ec 100644 +--- a/arch/arm/boot/dts/am4372.dtsi ++++ b/arch/arm/boot/dts/am4372.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for AM4372 SoC + * + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/bus/ti-sysc.h> +diff --git a/arch/arm/boot/dts/artpec6-devboard.dts b/arch/arm/boot/dts/artpec6-devboard.dts +index d20d95359b284..042a9cc920c67 100644 +--- a/arch/arm/boot/dts/artpec6-devboard.dts ++++ b/arch/arm/boot/dts/artpec6-devboard.dts +@@ -1,10 +1,5 @@ +-/* +- * Axis ARTPEC-6 development board. +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only ++// Axis ARTPEC-6 development board. + + /dts-v1/; + #include "artpec6.dtsi" +diff --git a/arch/arm/boot/dts/dm814x.dtsi b/arch/arm/boot/dts/dm814x.dtsi +index 7702e048e110f..379abf90c765d 100644 +--- a/arch/arm/boot/dts/dm814x.dtsi ++++ b/arch/arm/boot/dts/dm814x.dtsi +@@ -1,8 +1,4 @@ +-/* +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only + + #include <dt-bindings/bus/ti-sysc.h> + #include <dt-bindings/clock/dm814.h> +diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi +index a9e7274806f46..ce62f1fa1faff 100644 +--- a/arch/arm/boot/dts/dm816x.dtsi ++++ b/arch/arm/boot/dts/dm816x.dtsi +@@ -1,8 +1,4 @@ +-/* +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only + + #include <dt-bindings/bus/ti-sysc.h> + #include <dt-bindings/clock/dm816.h> +diff --git a/arch/arm/boot/dts/dra62x.dtsi b/arch/arm/boot/dts/dra62x.dtsi +index cc4878aaa8ea8..cfefa670515cc 100644 +--- a/arch/arm/boot/dts/dra62x.dtsi ++++ b/arch/arm/boot/dts/dra62x.dtsi +@@ -1,8 +1,4 @@ +-/* +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only + + #include "dm814x.dtsi" + +diff --git a/arch/arm/boot/dts/dra7-dspeve-thermal.dtsi b/arch/arm/boot/dts/dra7-dspeve-thermal.dtsi +index e75569383dd80..747ff0db90c7d 100644 +--- a/arch/arm/boot/dts/dra7-dspeve-thermal.dtsi ++++ b/arch/arm/boot/dts/dra7-dspeve-thermal.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for DRA7x SoC DSPEVE thermal + * + * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/thermal/thermal.h> +diff --git a/arch/arm/boot/dts/dra7-iva-thermal.dtsi b/arch/arm/boot/dts/dra7-iva-thermal.dtsi +index a7077321613f0..0a31313065df4 100644 +--- a/arch/arm/boot/dts/dra7-iva-thermal.dtsi ++++ b/arch/arm/boot/dts/dra7-iva-thermal.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for DRA7x SoC IVA thermal + * + * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/thermal/thermal.h> +diff --git a/arch/arm/boot/dts/imx6q-gk802.dts b/arch/arm/boot/dts/imx6q-gk802.dts +index ccc2487d47ca9..2fda68f9d3f64 100644 +--- a/arch/arm/boot/dts/imx6q-gk802.dts ++++ b/arch/arm/boot/dts/imx6q-gk802.dts +@@ -1,10 +1,5 @@ +-/* +- * Copyright (C) 2013 Philipp Zabel +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only ++// Copyright (C) 2013 Philipp Zabel + + /dts-v1/; + #include <dt-bindings/gpio/gpio.h> +diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi +index a4423ff0df392..67c68c61ae029 100644 +--- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi ++++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi +@@ -614,12 +614,12 @@ + /* Configure pwm clock source for timers 8 & 9 */ + &timer8 { + assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>; +- assigned-clock-parents = <&sys_clkin_ck>; ++ assigned-clock-parents = <&sys_32k_ck>; + }; + + &timer9 { + assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>; +- assigned-clock-parents = <&sys_clkin_ck>; ++ assigned-clock-parents = <&sys_32k_ck>; + }; + + /* +diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi +index ded7e8fec9eba..9cf52650f0731 100644 +--- a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi ++++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi +@@ -8,9 +8,9 @@ + + / { + vddvario: regulator-vddvario { +- compatible = "regulator-fixed"; +- regulator-name = "vddvario"; +- regulator-always-on; ++ compatible = "regulator-fixed"; ++ regulator-name = "vddvario"; ++ regulator-always-on; + }; + + vdd33a: regulator-vdd33a { +diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi +index e7534fe9c53cf..bc8961f3690f0 100644 +--- a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi ++++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi +@@ -12,9 +12,9 @@ + + / { + vddvario: regulator-vddvario { +- compatible = "regulator-fixed"; +- regulator-name = "vddvario"; +- regulator-always-on; ++ compatible = "regulator-fixed"; ++ regulator-name = "vddvario"; ++ regulator-always-on; + }; + + vdd33a: regulator-vdd33a { +diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi +index 5750ca1233cc2..afabb36a8ac13 100644 +--- a/arch/arm/boot/dts/omap2.dtsi ++++ b/arch/arm/boot/dts/omap2.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP2 SoC + * + * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/bus/ti-sysc.h> +diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi +index bb529a2a295db..821da51cb8704 100644 +--- a/arch/arm/boot/dts/omap2420.dtsi ++++ b/arch/arm/boot/dts/omap2420.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP2420 SoC + * + * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include "omap2.dtsi" +diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi +index 23115ba61bc06..b9a9e6e45266f 100644 +--- a/arch/arm/boot/dts/omap2430.dtsi ++++ b/arch/arm/boot/dts/omap2430.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP243x SoC + * + * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include "omap2.dtsi" +diff --git a/arch/arm/boot/dts/omap3-cm-t3517.dts b/arch/arm/boot/dts/omap3-cm-t3517.dts +index 3b8349094baa6..f25c0a84a190c 100644 +--- a/arch/arm/boot/dts/omap3-cm-t3517.dts ++++ b/arch/arm/boot/dts/omap3-cm-t3517.dts +@@ -11,12 +11,12 @@ + model = "CompuLab CM-T3517"; + compatible = "compulab,omap3-cm-t3517", "ti,am3517", "ti,omap3"; + +- vmmc: regulator-vmmc { +- compatible = "regulator-fixed"; +- regulator-name = "vmmc"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- }; ++ vmmc: regulator-vmmc { ++ compatible = "regulator-fixed"; ++ regulator-name = "vmmc"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; + + wl12xx_vmmc2: wl12xx_vmmc2 { + compatible = "regulator-fixed"; +diff --git a/arch/arm/boot/dts/omap3-cpu-thermal.dtsi b/arch/arm/boot/dts/omap3-cpu-thermal.dtsi +index 1ed8378593745..4d2684e4ae06e 100644 +--- a/arch/arm/boot/dts/omap3-cpu-thermal.dtsi ++++ b/arch/arm/boot/dts/omap3-cpu-thermal.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP3 SoC CPU thermal + * + * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/thermal/thermal.h> +@@ -15,8 +12,7 @@ cpu_thermal: cpu_thermal { + polling-delay = <1000>; /* milliseconds */ + coefficients = <0 20000>; + +- /* sensor ID */ +- thermal-sensors = <&bandgap 0>; ++ thermal-sensors = <&bandgap>; + + cpu_trips: trips { + cpu_alert0: cpu_alert { +diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi +index bb5e00b36d8dc..465e0c0ebe568 100644 +--- a/arch/arm/boot/dts/omap3-gta04.dtsi ++++ b/arch/arm/boot/dts/omap3-gta04.dtsi +@@ -332,7 +332,7 @@ + OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */ + OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */ + >; +- }; ++ }; + + gps_pins: pinmux_gps_pins { + pinctrl-single,pins = < +@@ -866,8 +866,8 @@ + }; + + &hdqw1w { +- pinctrl-names = "default"; +- pinctrl-0 = <&hdq_pins>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdq_pins>; + }; + + /* image signal processor within OMAP3 SoC */ +diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts +index 9c6a927245904..b898e2f6f41dc 100644 +--- a/arch/arm/boot/dts/omap3-ldp.dts ++++ b/arch/arm/boot/dts/omap3-ldp.dts +@@ -301,5 +301,5 @@ + + &vaux1 { + /* Needed for ads7846 */ +- regulator-name = "vcc"; ++ regulator-name = "vcc"; + }; +diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts +index d40c3d2c4914e..fdd929bc65d79 100644 +--- a/arch/arm/boot/dts/omap3-n900.dts ++++ b/arch/arm/boot/dts/omap3-n900.dts +@@ -236,27 +236,27 @@ + pinctrl-single,pins = < + + /* address lines */ +- OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0) /* gpmc_a1.gpmc_a1 */ +- OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0) /* gpmc_a2.gpmc_a2 */ +- OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0) /* gpmc_a3.gpmc_a3 */ ++ OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0) /* gpmc_a1.gpmc_a1 */ ++ OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0) /* gpmc_a2.gpmc_a2 */ ++ OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0) /* gpmc_a3.gpmc_a3 */ + + /* data lines, gpmc_d0..d7 not muxable according to TRM */ +- OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0) /* gpmc_d8.gpmc_d8 */ +- OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0) /* gpmc_d9.gpmc_d9 */ +- OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0) /* gpmc_d10.gpmc_d10 */ +- OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0) /* gpmc_d11.gpmc_d11 */ +- OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0) /* gpmc_d12.gpmc_d12 */ +- OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0) /* gpmc_d13.gpmc_d13 */ +- OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0) /* gpmc_d14.gpmc_d14 */ +- OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0) /* gpmc_d15.gpmc_d15 */ ++ OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0) /* gpmc_d8.gpmc_d8 */ ++ OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0) /* gpmc_d9.gpmc_d9 */ ++ OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0) /* gpmc_d10.gpmc_d10 */ ++ OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0) /* gpmc_d11.gpmc_d11 */ ++ OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0) /* gpmc_d12.gpmc_d12 */ ++ OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0) /* gpmc_d13.gpmc_d13 */ ++ OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0) /* gpmc_d14.gpmc_d14 */ ++ OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0) /* gpmc_d15.gpmc_d15 */ + + /* + * gpmc_ncs0, gpmc_nadv_ale, gpmc_noe, gpmc_nwe, gpmc_wait0 not muxable + * according to TRM. OneNAND seems to require PIN_INPUT on clock. + */ +- OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0) /* gpmc_ncs1.gpmc_ncs1 */ +- OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0) /* gpmc_clk.gpmc_clk */ +- >; ++ OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0) /* gpmc_ncs1.gpmc_ncs1 */ ++ OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0) /* gpmc_clk.gpmc_clk */ ++ >; + }; + + i2c1_pins: pinmux_i2c1_pins { +@@ -738,12 +738,12 @@ + + si4713: si4713@63 { + compatible = "silabs,si4713"; +- reg = <0x63>; ++ reg = <0x63>; + +- interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */ +- reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */ +- vio-supply = <&vio>; +- vdd-supply = <&vaux1>; ++ interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */ ++ reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */ ++ vio-supply = <&vio>; ++ vdd-supply = <&vaux1>; + }; + + bq24150a: bq24150a@6b { +diff --git a/arch/arm/boot/dts/omap3-zoom3.dts b/arch/arm/boot/dts/omap3-zoom3.dts +index 0482676d18306..ce58b1f208e81 100644 +--- a/arch/arm/boot/dts/omap3-zoom3.dts ++++ b/arch/arm/boot/dts/omap3-zoom3.dts +@@ -23,9 +23,9 @@ + }; + + vddvario: regulator-vddvario { +- compatible = "regulator-fixed"; +- regulator-name = "vddvario"; +- regulator-always-on; ++ compatible = "regulator-fixed"; ++ regulator-name = "vddvario"; ++ regulator-always-on; + }; + + vdd33a: regulator-vdd33a { +@@ -84,28 +84,28 @@ + + uart1_pins: pinmux_uart1_pins { + pinctrl-single,pins = < +- OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0) /* uart1_cts.uart1_cts */ +- OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0) /* uart1_rts.uart1_rts */ +- OMAP3_CORE1_IOPAD(0x2182, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */ +- OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_tx */ ++ OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0) /* uart1_cts.uart1_cts */ ++ OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0) /* uart1_rts.uart1_rts */ ++ OMAP3_CORE1_IOPAD(0x2182, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */ ++ OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_tx */ + >; + }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < +- OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */ +- OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ +- OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */ +- OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */ ++ OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */ ++ OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ ++ OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */ ++ OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */ + >; + }; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < +- OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLDOWN | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */ +- OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */ +- OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ +- OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */ ++ OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLDOWN | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */ ++ OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */ ++ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ ++ OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */ + >; + }; + +@@ -205,22 +205,22 @@ + }; + + &uart1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart1_pins>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; + }; + + &uart2 { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart2_pins>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; + }; + + &uart3 { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart3_pins>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins>; + }; + + &uart4 { +- status = "disabled"; ++ status = "disabled"; + }; + + &usb_otg_hs { +diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi +index 64b7e6fddd1bc..825075ff0e342 100644 +--- a/arch/arm/boot/dts/omap3.dtsi ++++ b/arch/arm/boot/dts/omap3.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP3 SoC + * + * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/bus/ti-sysc.h> +diff --git a/arch/arm/boot/dts/omap34xx.dtsi b/arch/arm/boot/dts/omap34xx.dtsi +index 8b8451399784f..2eb73ae7ef3e7 100644 +--- a/arch/arm/boot/dts/omap34xx.dtsi ++++ b/arch/arm/boot/dts/omap34xx.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP34xx/OMAP35xx SoC + * + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/bus/ti-sysc.h> +diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi +index 22b33098b1a2d..32ac7924a1303 100644 +--- a/arch/arm/boot/dts/omap36xx.dtsi ++++ b/arch/arm/boot/dts/omap36xx.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP3 SoC + * + * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/bus/ti-sysc.h> +diff --git a/arch/arm/boot/dts/omap4-cpu-thermal.dtsi b/arch/arm/boot/dts/omap4-cpu-thermal.dtsi +index 03d054b2bf9af..d484ec1e4fd86 100644 +--- a/arch/arm/boot/dts/omap4-cpu-thermal.dtsi ++++ b/arch/arm/boot/dts/omap4-cpu-thermal.dtsi +@@ -1,12 +1,9 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP4/5 SoC CPU thermal + * + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/ + * Contact: Eduardo Valentin <eduardo.valentin@ti.com> +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/thermal/thermal.h> +@@ -15,21 +12,24 @@ cpu_thermal: cpu_thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + +- /* sensor ID */ +- thermal-sensors = <&bandgap 0>; ++ /* ++ * See 44xx files for single sensor addressing, omap5 and dra7 need ++ * also sensor ID for addressing. ++ */ ++ thermal-sensors = <&bandgap 0>; + + cpu_trips: trips { +- cpu_alert0: cpu_alert { +- temperature = <100000>; /* millicelsius */ +- hysteresis = <2000>; /* millicelsius */ +- type = "passive"; +- }; +- cpu_crit: cpu_crit { +- temperature = <125000>; /* millicelsius */ +- hysteresis = <2000>; /* millicelsius */ +- type = "critical"; +- }; +- }; ++ cpu_alert0: cpu_alert { ++ temperature = <100000>; /* millicelsius */ ++ hysteresis = <2000>; /* millicelsius */ ++ type = "passive"; ++ }; ++ cpu_crit: cpu_crit { ++ temperature = <125000>; /* millicelsius */ ++ hysteresis = <2000>; /* millicelsius */ ++ type = "critical"; ++ }; ++ }; + + cpu_cooling_maps: cooling-maps { + map0 { +diff --git a/arch/arm/boot/dts/omap443x.dtsi b/arch/arm/boot/dts/omap443x.dtsi +index 8466161197aef..2104170fe2cd7 100644 +--- a/arch/arm/boot/dts/omap443x.dtsi ++++ b/arch/arm/boot/dts/omap443x.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP443x SoC + * + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include "omap4.dtsi" +@@ -72,6 +69,7 @@ + }; + + &cpu_thermal { ++ thermal-sensors = <&bandgap>; + coefficients = <0 20000>; + }; + +diff --git a/arch/arm/boot/dts/omap4460.dtsi b/arch/arm/boot/dts/omap4460.dtsi +index 3d6db1db94e04..a6764750d4476 100644 +--- a/arch/arm/boot/dts/omap4460.dtsi ++++ b/arch/arm/boot/dts/omap4460.dtsi +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP4460 SoC + * + * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + #include "omap4.dtsi" + +@@ -82,6 +79,7 @@ + }; + + &cpu_thermal { ++ thermal-sensors = <&bandgap>; + coefficients = <348 (-9301)>; + }; + +diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts +index e62ea8b6d53fd..af288d63a26a4 100644 +--- a/arch/arm/boot/dts/omap5-cm-t54.dts ++++ b/arch/arm/boot/dts/omap5-cm-t54.dts +@@ -84,36 +84,36 @@ + }; + + lcd0: display { +- compatible = "startek,startek-kd050c", "panel-dpi"; +- label = "lcd"; +- +- pinctrl-names = "default"; +- pinctrl-0 = <&lcd_pins>; +- +- enable-gpios = <&gpio8 3 GPIO_ACTIVE_HIGH>; +- +- panel-timing { +- clock-frequency = <33000000>; +- hactive = <800>; +- vactive = <480>; +- hfront-porch = <40>; +- hback-porch = <40>; +- hsync-len = <43>; +- vback-porch = <29>; +- vfront-porch = <13>; +- vsync-len = <3>; +- hsync-active = <0>; +- vsync-active = <0>; +- de-active = <1>; +- pixelclk-active = <1>; +- }; +- +- port { +- lcd_in: endpoint { +- remote-endpoint = <&dpi_lcd_out>; +- }; +- }; +- }; ++ compatible = "startek,startek-kd050c", "panel-dpi"; ++ label = "lcd"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&lcd_pins>; ++ ++ enable-gpios = <&gpio8 3 GPIO_ACTIVE_HIGH>; ++ ++ panel-timing { ++ clock-frequency = <33000000>; ++ hactive = <800>; ++ vactive = <480>; ++ hfront-porch = <40>; ++ hback-porch = <40>; ++ hsync-len = <43>; ++ vback-porch = <29>; ++ vfront-porch = <13>; ++ vsync-len = <3>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ de-active = <1>; ++ pixelclk-active = <1>; ++ }; ++ ++ port { ++ lcd_in: endpoint { ++ remote-endpoint = <&dpi_lcd_out>; ++ }; ++ }; ++ }; + + hdmi0: connector0 { + compatible = "hdmi-connector"; +@@ -644,8 +644,8 @@ + }; + + &usb3 { +- extcon = <&extcon_usb3>; +- vbus-supply = <&smps10_out1_reg>; ++ extcon = <&extcon_usb3>; ++ vbus-supply = <&smps10_out1_reg>; + }; + + &cpu0 { +diff --git a/arch/arm/boot/dts/omap5-core-thermal.dtsi b/arch/arm/boot/dts/omap5-core-thermal.dtsi +index 02e76338bfbc0..e0d8e39a0014b 100644 +--- a/arch/arm/boot/dts/omap5-core-thermal.dtsi ++++ b/arch/arm/boot/dts/omap5-core-thermal.dtsi +@@ -1,12 +1,9 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP543x SoC CORE thermal + * + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/ + * Contact: Eduardo Valentin <eduardo.valentin@ti.com> +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/thermal/thermal.h> +diff --git a/arch/arm/boot/dts/omap5-gpu-thermal.dtsi b/arch/arm/boot/dts/omap5-gpu-thermal.dtsi +index bf8fa9372e575..1b4b7d9136c84 100644 +--- a/arch/arm/boot/dts/omap5-gpu-thermal.dtsi ++++ b/arch/arm/boot/dts/omap5-gpu-thermal.dtsi +@@ -1,12 +1,9 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree Source for OMAP543x SoC GPU thermal + * + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/ + * Contact: Eduardo Valentin <eduardo.valentin@ti.com> +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #include <dt-bindings/thermal/thermal.h> +diff --git a/arch/arm/boot/dts/orion5x-lacie-d2-network.dts b/arch/arm/boot/dts/orion5x-lacie-d2-network.dts +index 422958d13d42f..03471d30bfd95 100644 +--- a/arch/arm/boot/dts/orion5x-lacie-d2-network.dts ++++ b/arch/arm/boot/dts/orion5x-lacie-d2-network.dts +@@ -1,10 +1,7 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + /dts-v1/; +diff --git a/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts b/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts +index 0043e0040153c..f17e25ac98ddb 100644 +--- a/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts ++++ b/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts +@@ -1,10 +1,5 @@ +-/* +- * Copyright (C) 2012 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only ++// Copyright (C) 2012 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + + /* + * TODO: add Orion USB device port init when kernel.org support is added. +diff --git a/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts b/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts +index 0ca6208a267de..d57859998350d 100644 +--- a/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts ++++ b/arch/arm/boot/dts/orion5x-maxtor-shared-storage-2.dts +@@ -1,10 +1,7 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * Copyright (C) Sylver Bruneau <sylver.bruneau@googlemail.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + /dts-v1/; +diff --git a/arch/arm/boot/dts/orion5x-mv88f5181.dtsi b/arch/arm/boot/dts/orion5x-mv88f5181.dtsi +index f667012b26ca1..819f9efb7058d 100644 +--- a/arch/arm/boot/dts/orion5x-mv88f5181.dtsi ++++ b/arch/arm/boot/dts/orion5x-mv88f5181.dtsi +@@ -1,10 +1,5 @@ +-/* +- * Copyright (C) 2016 Jamie Lentin <jm@lentin.co.uk> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only ++// Copyright (C) 2016 Jamie Lentin <jm@lentin.co.uk> + + #include "orion5x.dtsi" + +diff --git a/arch/arm/boot/dts/orion5x-mv88f5182.dtsi b/arch/arm/boot/dts/orion5x-mv88f5182.dtsi +index d1ed71c602096..86b87fb26dc9a 100644 +--- a/arch/arm/boot/dts/orion5x-mv88f5182.dtsi ++++ b/arch/arm/boot/dts/orion5x-mv88f5182.dtsi +@@ -1,10 +1,5 @@ +-/* +- * Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only ++// Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + + #include "orion5x.dtsi" + +diff --git a/arch/arm/boot/dts/orion5x-netgear-wnr854t.dts b/arch/arm/boot/dts/orion5x-netgear-wnr854t.dts +index ea081afa469d9..4f4888ec91380 100644 +--- a/arch/arm/boot/dts/orion5x-netgear-wnr854t.dts ++++ b/arch/arm/boot/dts/orion5x-netgear-wnr854t.dts +@@ -1,10 +1,5 @@ +-/* +- * Copyright (C) 2016 Jamie Lentin <jm@lentin.co.uk> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only ++// Copyright (C) 2016 Jamie Lentin <jm@lentin.co.uk> + + /dts-v1/; + +diff --git a/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts b/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts +index 487324f7c54e7..fd78aa02a3c5b 100644 +--- a/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts ++++ b/arch/arm/boot/dts/orion5x-rd88f5182-nas.dts +@@ -1,10 +1,5 @@ +-/* +- * Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only ++// Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + + /dts-v1/; + +diff --git a/arch/arm/boot/dts/orion5x.dtsi b/arch/arm/boot/dts/orion5x.dtsi +index 61e631b3fd8bb..2d41f5c166ee7 100644 +--- a/arch/arm/boot/dts/orion5x.dtsi ++++ b/arch/arm/boot/dts/orion5x.dtsi +@@ -1,10 +1,5 @@ +-/* +- * Copyright (C) 2012 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only ++// Copyright (C) 2012 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + + #define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16)) + +diff --git a/arch/arm/include/asm/hardware/cache-aurora-l2.h b/arch/arm/include/asm/hardware/cache-aurora-l2.h +index 39769ffa00512..9694808ee97ce 100644 +--- a/arch/arm/include/asm/hardware/cache-aurora-l2.h ++++ b/arch/arm/include/asm/hardware/cache-aurora-l2.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * AURORA shared L2 cache controller support + * +@@ -5,10 +6,6 @@ + * + * Yehuda Yitschak <yehuday@marvell.com> + * Gregory CLEMENT <gregory.clement@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __ASM_ARM_HARDWARE_AURORA_L2_H +diff --git a/arch/arm/include/asm/hardware/cache-feroceon-l2.h b/arch/arm/include/asm/hardware/cache-feroceon-l2.h +index 12e1588dc4f13..eb2e7b7f70a87 100644 +--- a/arch/arm/include/asm/hardware/cache-feroceon-l2.h ++++ b/arch/arm/include/asm/hardware/cache-feroceon-l2.h +@@ -1,13 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * arch/arm/include/asm/hardware/cache-feroceon-l2.h + * + * Copyright (C) 2008 Marvell Semiconductor +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + extern void __init feroceon_l2_init(int l2_wt_override); + extern int __init feroceon_of_init(void); +- +diff --git a/arch/arm/include/asm/hardware/cache-tauros2.h b/arch/arm/include/asm/hardware/cache-tauros2.h +index 295e2e40151b1..4e493facaa317 100644 +--- a/arch/arm/include/asm/hardware/cache-tauros2.h ++++ b/arch/arm/include/asm/hardware/cache-tauros2.h +@@ -1,11 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * arch/arm/include/asm/hardware/cache-tauros2.h + * + * Copyright (C) 2008 Marvell Semiconductor +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define CACHE_TAUROS2_PREFETCH_ON (1 << 0) +diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c +index 823c9cc98f18b..d820161445fa9 100644 +--- a/arch/arm/mach-davinci/board-da830-evm.c ++++ b/arch/arm/mach-davinci/board-da830-evm.c +@@ -1,13 +1,11 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * TI DA830/OMAP L137 EVM board + * + * Author: Mark A. Greer <mgreer@mvista.com> + * Derived from: arch/arm/mach-davinci/board-dm644x-evm.c + * +- * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007, 2009 (c) MontaVista Software, Inc. + */ + #include <linux/kernel.h> + #include <linux/init.h> +diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c +index 7f7f6bae21c2d..1601a74261a67 100644 +--- a/arch/arm/mach-davinci/board-da850-evm.c ++++ b/arch/arm/mach-davinci/board-da850-evm.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * TI DA850/OMAP-L138 EVM board + * +@@ -6,10 +7,7 @@ + * Derived from: arch/arm/mach-davinci/board-da830-evm.c + * Original Copyrights follow: + * +- * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007, 2009 (c) MontaVista Software, Inc. + */ + #include <linux/console.h> + #include <linux/delay.h> +diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c +index 3c5a9e3c128ab..debc912b133fa 100644 +--- a/arch/arm/mach-davinci/board-dm355-evm.c ++++ b/arch/arm/mach-davinci/board-dm355-evm.c +@@ -1,12 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * TI DaVinci EVM board support + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * +- * 2007 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007 (c) MontaVista Software, Inc. + */ + #include <linux/kernel.h> + #include <linux/init.h> +diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c +index e475b2113e70f..7c8307d590a40 100644 +--- a/arch/arm/mach-davinci/board-dm355-leopard.c ++++ b/arch/arm/mach-davinci/board-dm355-leopard.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * DM355 leopard board support + * + * Based on board-dm355-evm.c +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/kernel.h> + #include <linux/init.h> +diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c +index cce3a621eb20b..92a92c4cef722 100644 +--- a/arch/arm/mach-davinci/board-dm644x-evm.c ++++ b/arch/arm/mach-davinci/board-dm644x-evm.c +@@ -1,12 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * TI DaVinci EVM board support + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * +- * 2007 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007 (c) MontaVista Software, Inc. + */ + #include <linux/kernel.h> + #include <linux/init.h> +diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c +index ee91d81ebbfdf..c62815535b863 100644 +--- a/arch/arm/mach-davinci/board-dm646x-evm.c ++++ b/arch/arm/mach-davinci/board-dm646x-evm.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * TI DaVinci DM646X EVM board + * +@@ -5,11 +6,6 @@ + * Copyright (C) 2006 Texas Instruments. + * + * (C) 2007-2008, MontaVista Software, Inc. +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. +- * + */ + + /************************************************************************** +@@ -873,4 +869,3 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM") + .init_late = davinci_init_late, + .dma_zone_size = SZ_128M, + MACHINE_END +- +diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c +index 2127969beb965..a36365edfe20f 100644 +--- a/arch/arm/mach-davinci/board-mityomapl138.c ++++ b/arch/arm/mach-davinci/board-mityomapl138.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Critical Link MityOMAP-L138 SoM + * + * Copyright (C) 2010 Critical Link LLC - https://www.criticallink.com +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of +- * any kind, whether express or implied. + */ + + #define pr_fmt(fmt) "MityOMAPL138: " fmt +diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c +index b4843f68bb575..ae0bce8655b44 100644 +--- a/arch/arm/mach-davinci/board-neuros-osd2.c ++++ b/arch/arm/mach-davinci/board-neuros-osd2.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Neuros Technologies OSD2 board support + * +@@ -18,10 +19,6 @@ + * + * For more information please refer to + * http://wiki.neurostechnology.com/index.php/OSD_2.0_HD +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/platform_device.h> + #include <linux/gpio.h> +diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c +index 88df8011a4e6b..f3e85d16f56a8 100644 +--- a/arch/arm/mach-davinci/board-omapl138-hawk.c ++++ b/arch/arm/mach-davinci/board-omapl138-hawk.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Hawkboard.org based on TI's OMAP-L138 Platform + * + * Initial code: Syed Mohammed Khasim + * + * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of +- * any kind, whether express or implied. + */ + #include <linux/kernel.h> + #include <linux/init.h> +diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c +index ae61d19f9b3af..5c2760723fcfb 100644 +--- a/arch/arm/mach-davinci/common.c ++++ b/arch/arm/mach-davinci/common.c +@@ -1,12 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Code commons to all DaVinci SoCs. + * + * Author: Mark A. Greer <mgreer@mvista.com> + * +- * 2009 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2009 (c) MontaVista Software, Inc. + */ + #include <linux/module.h> + #include <linux/io.h> +diff --git a/arch/arm/mach-davinci/cpuidle.h b/arch/arm/mach-davinci/cpuidle.h +index 0d9193aefab51..976d43073597e 100644 +--- a/arch/arm/mach-davinci/cpuidle.h ++++ b/arch/arm/mach-davinci/cpuidle.h +@@ -1,11 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * TI DaVinci cpuidle platform support + * + * 2009 (C) Texas Instruments, Inc. https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + #ifndef _MACH_DAVINCI_CPUIDLE_H + #define _MACH_DAVINCI_CPUIDLE_H +diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c +index 018ab4b549f1d..cd07415dc5350 100644 +--- a/arch/arm/mach-davinci/da830.c ++++ b/arch/arm/mach-davinci/da830.c +@@ -1,12 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * TI DA830/OMAP L137 chip specific setup + * + * Author: Mark A. Greer <mgreer@mvista.com> + * +- * 2009 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2009 (c) MontaVista Software, Inc. + */ + #include <linux/clk-provider.h> + #include <linux/clk/davinci.h> +diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c +index 68156e7239a68..aedf020b62ed1 100644 +--- a/arch/arm/mach-davinci/da850.c ++++ b/arch/arm/mach-davinci/da850.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * TI DA850/OMAP-L138 chip specific setup + * +@@ -6,10 +7,7 @@ + * Derived from: arch/arm/mach-davinci/da830.c + * Original Copyrights follow: + * +- * 2009 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2009 (c) MontaVista Software, Inc. + */ + + #include <linux/clk-provider.h> +diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c +index 5de72d2fa8f09..a49151bf37c46 100644 +--- a/arch/arm/mach-davinci/dm355.c ++++ b/arch/arm/mach-davinci/dm355.c +@@ -1,12 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * TI DaVinci DM355 chip specific setup + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * +- * 2007 (c) Deep Root Systems, LLC. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007 (c) Deep Root Systems, LLC. + */ + + #include <linux/clk-provider.h> +diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c +index 24988939ae462..f9b82a6a16300 100644 +--- a/arch/arm/mach-davinci/dm644x.c ++++ b/arch/arm/mach-davinci/dm644x.c +@@ -1,12 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * TI DaVinci DM644x chip specific setup + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * +- * 2007 (c) Deep Root Systems, LLC. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007 (c) Deep Root Systems, LLC. + */ + + #include <linux/clk-provider.h> +diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c +index 4ffd028ed9978..d85d8e9e13715 100644 +--- a/arch/arm/mach-davinci/dm646x.c ++++ b/arch/arm/mach-davinci/dm646x.c +@@ -1,12 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * TI DaVinci DM646x chip specific setup + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * +- * 2007 (c) Deep Root Systems, LLC. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007 (c) Deep Root Systems, LLC. + */ + + #include <linux/clk-provider.h> +diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h +index 139b83de011d3..772b51e0ac5eb 100644 +--- a/arch/arm/mach-davinci/include/mach/common.h ++++ b/arch/arm/mach-davinci/include/mach/common.h +@@ -1,12 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Header for code common to all DaVinci machines. + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * +- * 2007 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007 (c) MontaVista Software, Inc. + */ + + #ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H +diff --git a/arch/arm/mach-davinci/include/mach/cputype.h b/arch/arm/mach-davinci/include/mach/cputype.h +index 1fc84e21664d2..81de85757a938 100644 +--- a/arch/arm/mach-davinci/include/mach/cputype.h ++++ b/arch/arm/mach-davinci/include/mach/cputype.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * DaVinci CPU type detection + * +@@ -8,10 +9,7 @@ + * compiled in to the kernel, the macros return 0 so that + * resulting code can be optimized out. + * +- * 2009 (c) Deep Root Systems, LLC. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2009 (c) Deep Root Systems, LLC. + */ + #ifndef _ASM_ARCH_CPU_H + #define _ASM_ARCH_CPU_H +diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h +index 1618b30661a9b..f138f6d33d4aa 100644 +--- a/arch/arm/mach-davinci/include/mach/da8xx.h ++++ b/arch/arm/mach-davinci/include/mach/da8xx.h +@@ -1,12 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Chip specific defines for DA8XX/OMAP L1XX SoC + * + * Author: Mark A. Greer <mgreer@mvista.com> + * +- * 2007, 2009-2010 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007, 2009-2010 (c) MontaVista Software, Inc. + */ + #ifndef __ASM_ARCH_DAVINCI_DA8XX_H + #define __ASM_ARCH_DAVINCI_DA8XX_H +diff --git a/arch/arm/mach-davinci/include/mach/hardware.h b/arch/arm/mach-davinci/include/mach/hardware.h +index 16bb42291d39d..7848b6a240b48 100644 +--- a/arch/arm/mach-davinci/include/mach/hardware.h ++++ b/arch/arm/mach-davinci/include/mach/hardware.h +@@ -1,12 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Hardware definitions common to all DaVinci family processors + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * +- * 2007 (c) Deep Root Systems, LLC. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007 (c) Deep Root Systems, LLC. + */ + #ifndef __ASM_ARCH_HARDWARE_H + #define __ASM_ARCH_HARDWARE_H +diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h +index d4b4aa87964f0..85fda53ffd205 100644 +--- a/arch/arm/mach-davinci/include/mach/serial.h ++++ b/arch/arm/mach-davinci/include/mach/serial.h +@@ -1,12 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * DaVinci serial device definitions + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * +- * 2007 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007 (c) MontaVista Software, Inc. + */ + #ifndef __ASM_ARCH_SERIAL_H + #define __ASM_ARCH_SERIAL_H +diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c +index 6a2ff0a654a5b..0d8ac2f936617 100644 +--- a/arch/arm/mach-davinci/mux.c ++++ b/arch/arm/mach-davinci/mux.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Utility to set the DAVINCI MUX register from a table in mux.h + * +@@ -8,10 +9,7 @@ + * + * Written by Tony Lindgren + * +- * 2007 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007 (c) MontaVista Software, Inc. + * + * Copyright (C) 2008 Texas Instruments. + */ +diff --git a/arch/arm/mach-davinci/mux.h b/arch/arm/mach-davinci/mux.h +index 5aad1e7dd2103..558b9c1b32c06 100644 +--- a/arch/arm/mach-davinci/mux.h ++++ b/arch/arm/mach-davinci/mux.h +@@ -1,12 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Pin-multiplex helper macros for TI DaVinci family devices + * + * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com> + * +- * 2007 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2007 (c) MontaVista Software, Inc. + * + * Copyright (C) 2008 Texas Instruments. + */ +diff --git a/arch/arm/mach-davinci/pm_domain.c b/arch/arm/mach-davinci/pm_domain.c +index e251fd593bfd1..6b21d5bd999c6 100644 +--- a/arch/arm/mach-davinci/pm_domain.c ++++ b/arch/arm/mach-davinci/pm_domain.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Runtime PM support code for DaVinci + * + * Author: Kevin Hilman + * + * Copyright (C) 2012 Texas Instruments, Inc. +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/init.h> + #include <linux/pm_runtime.h> +diff --git a/arch/arm/mach-dove/bridge-regs.h b/arch/arm/mach-dove/bridge-regs.h +index ace0b0bfbf114..6fbc152d0950d 100644 +--- a/arch/arm/mach-dove/bridge-regs.h ++++ b/arch/arm/mach-dove/bridge-regs.h +@@ -1,10 +1,5 @@ +-/* +- * Mbus-L to Mbus Bridge Registers +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* Mbus-L to Mbus Bridge Registers */ + + #ifndef __ASM_ARCH_BRIDGE_REGS_H + #define __ASM_ARCH_BRIDGE_REGS_H +diff --git a/arch/arm/mach-dove/cm-a510.c b/arch/arm/mach-dove/cm-a510.c +index 9f25c993d8637..beb532537c225 100644 +--- a/arch/arm/mach-dove/cm-a510.c ++++ b/arch/arm/mach-dove/cm-a510.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-dove/cm-a510.c + * +@@ -5,10 +6,6 @@ + * Konstantin Sinyuk <kostyas@compulab.co.il> + * + * Based on Marvell DB-MV88AP510-BP Development Board Setup +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c +index dbe970e378953..cd4ae7e4768dd 100644 +--- a/arch/arm/mach-dove/common.c ++++ b/arch/arm/mach-dove/common.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-dove/common.c + * + * Core functions for Marvell Dove 88AP510 System On Chip +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/clk-provider.h> +diff --git a/arch/arm/mach-dove/common.h b/arch/arm/mach-dove/common.h +index 1d725224d1461..57ebc413d68c2 100644 +--- a/arch/arm/mach-dove/common.h ++++ b/arch/arm/mach-dove/common.h +@@ -1,11 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * arch/arm/mach-dove/common.h + * + * Core functions for Marvell Dove 88AP510 System On Chip +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __ARCH_DOVE_COMMON_H +diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c +index 418ab21b9d9b2..d5bf540405772 100644 +--- a/arch/arm/mach-dove/dove-db-setup.c ++++ b/arch/arm/mach-dove/dove-db-setup.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-dove/dove-db-setup.c + * + * Marvell DB-MV88AP510-BP Development Board Setup +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-dove/dove.h b/arch/arm/mach-dove/dove.h +index 320ed1696abdc..e5054e3b0b782 100644 +--- a/arch/arm/mach-dove/dove.h ++++ b/arch/arm/mach-dove/dove.h +@@ -1,10 +1,5 @@ +-/* +- * Generic definitions for Marvell Dove 88AP510 SoC +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* Generic definitions for Marvell Dove 88AP510 SoC */ + + #ifndef __ASM_ARCH_DOVE_H + #define __ASM_ARCH_DOVE_H +diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c +index 31ccbcee26274..0c851a11183d2 100644 +--- a/arch/arm/mach-dove/irq.c ++++ b/arch/arm/mach-dove/irq.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-dove/irq.c + * + * Dove IRQ handling. +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/init.h> + #include <linux/irq.h> +diff --git a/arch/arm/mach-dove/irqs.h b/arch/arm/mach-dove/irqs.h +index a0742179faffe..5467098c70428 100644 +--- a/arch/arm/mach-dove/irqs.h ++++ b/arch/arm/mach-dove/irqs.h +@@ -1,10 +1,5 @@ +-/* +- * IRQ definitions for Marvell Dove 88AP510 SoC +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* IRQ definitions for Marvell Dove 88AP510 SoC */ + + #ifndef __ASM_ARCH_IRQS_H + #define __ASM_ARCH_IRQS_H +diff --git a/arch/arm/mach-dove/mpp.c b/arch/arm/mach-dove/mpp.c +index 6acd8488bb05f..93cb137da5f86 100644 +--- a/arch/arm/mach-dove/mpp.c ++++ b/arch/arm/mach-dove/mpp.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-dove/mpp.c + * + * MPP functions for Marvell Dove SoCs +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c +index ee91ac6b5ebf1..cff5c77aa7a6c 100644 +--- a/arch/arm/mach-dove/pcie.c ++++ b/arch/arm/mach-dove/pcie.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-dove/pcie.c + * + * PCIe functions for Marvell Dove 88AP510 SoC +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-dove/pm.h b/arch/arm/mach-dove/pm.h +index 01267746d7072..a4c3aba1e2d0d 100644 +--- a/arch/arm/mach-dove/pm.h ++++ b/arch/arm/mach-dove/pm.h +@@ -1,8 +1,4 @@ +-/* +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++/* SPDX-License-Identifier: GPL-2.0-only */ + + #ifndef __ASM_ARCH_PM_H + #define __ASM_ARCH_PM_H +diff --git a/arch/arm/mach-lpc18xx/board-dt.c b/arch/arm/mach-lpc18xx/board-dt.c +index fdcee78d1bc4c..4729eb83401ae 100644 +--- a/arch/arm/mach-lpc18xx/board-dt.c ++++ b/arch/arm/mach-lpc18xx/board-dt.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree board file for NXP LPC18xx/43xx + * + * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <asm/mach/arch.h> +diff --git a/arch/arm/mach-lpc32xx/pm.c b/arch/arm/mach-lpc32xx/pm.c +index b27fa1b9f56c1..2572bd89a5e8d 100644 +--- a/arch/arm/mach-lpc32xx/pm.c ++++ b/arch/arm/mach-lpc32xx/pm.c +@@ -1,13 +1,11 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-lpc32xx/pm.c + * + * Original authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com> + * Modified by Kevin Wells <kevin.wells@nxp.com> + * +- * 2005 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2005 (c) MontaVista Software, Inc. + */ + + /* +diff --git a/arch/arm/mach-lpc32xx/suspend.S b/arch/arm/mach-lpc32xx/suspend.S +index 3f0a8282ef6fd..a95c5e0e40384 100644 +--- a/arch/arm/mach-lpc32xx/suspend.S ++++ b/arch/arm/mach-lpc32xx/suspend.S +@@ -1,13 +1,11 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * arch/arm/mach-lpc32xx/suspend.S + * + * Original authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com> + * Modified by Kevin Wells <kevin.wells@nxp.com> + * +- * 2005 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2005 (c) MontaVista Software, Inc. + */ + #include <linux/linkage.h> + #include <asm/assembler.h> +diff --git a/arch/arm/mach-mv78xx0/bridge-regs.h b/arch/arm/mach-mv78xx0/bridge-regs.h +index 2f54e1753d45e..d57ac967c4b39 100644 +--- a/arch/arm/mach-mv78xx0/bridge-regs.h ++++ b/arch/arm/mach-mv78xx0/bridge-regs.h +@@ -1,8 +1,4 @@ +-/* +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++/* SPDX-License-Identifier: GPL-2.0-only */ + + #ifndef __ASM_ARCH_BRIDGE_REGS_H + #define __ASM_ARCH_BRIDGE_REGS_H +diff --git a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c +index e112f2e7cc9a9..9aa765d4cdc8a 100644 +--- a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c ++++ b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-mv78xx0/buffalo-wxl-setup.c + * + * Buffalo WXL (Terastation Duo) Setup routines + * + * sebastien requiem <sebastien@requiem.fr> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c +index dd762d1b083fd..461a68945c26e 100644 +--- a/arch/arm/mach-mv78xx0/common.c ++++ b/arch/arm/mach-mv78xx0/common.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-mv78xx0/common.c + * + * Core functions for Marvell MV78xx0 SoCs +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-mv78xx0/common.h b/arch/arm/mach-mv78xx0/common.h +index 6889af26077da..d8c6c2400e278 100644 +--- a/arch/arm/mach-mv78xx0/common.h ++++ b/arch/arm/mach-mv78xx0/common.h +@@ -1,11 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * arch/arm/mach-mv78xx0/common.h + * + * Core functions for Marvell MV78xx0 SoCs +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __ARCH_MV78XX0_COMMON_H +diff --git a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c +index cf16e08d4cf5b..da633a33a0c12 100644 +--- a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c ++++ b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-mv78xx0/db78x00-bp-setup.c + * + * Marvell DB-78x00-BP Development Board Setup +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c +index 788569e960e15..da7a219e2ef55 100644 +--- a/arch/arm/mach-mv78xx0/irq.c ++++ b/arch/arm/mach-mv78xx0/irq.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-mv78xx0/irq.c + * + * MV78xx0 IRQ handling. +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/gpio.h> + #include <linux/kernel.h> +diff --git a/arch/arm/mach-mv78xx0/irqs.h b/arch/arm/mach-mv78xx0/irqs.h +index 67e0fe730a13f..12b357d383d88 100644 +--- a/arch/arm/mach-mv78xx0/irqs.h ++++ b/arch/arm/mach-mv78xx0/irqs.h +@@ -1,10 +1,5 @@ +-/* +- * IRQ definitions for Marvell MV78xx0 SoCs +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* IRQ definitions for Marvell MV78xx0 SoCs */ + + #ifndef __ASM_ARCH_IRQS_H + #define __ASM_ARCH_IRQS_H +diff --git a/arch/arm/mach-mv78xx0/mpp.c b/arch/arm/mach-mv78xx0/mpp.c +index 72843c02e95ac..aff0e612cbba5 100644 +--- a/arch/arm/mach-mv78xx0/mpp.c ++++ b/arch/arm/mach-mv78xx0/mpp.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-mv78x00/mpp.c + * + * MPP functions for Marvell MV78x00 SoCs +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/gpio.h> + #include <linux/kernel.h> +diff --git a/arch/arm/mach-mv78xx0/mpp.h b/arch/arm/mach-mv78xx0/mpp.h +index 3752302ae2ee3..47db52f45546e 100644 +--- a/arch/arm/mach-mv78xx0/mpp.h ++++ b/arch/arm/mach-mv78xx0/mpp.h +@@ -1,12 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * linux/arch/arm/mach-mv78xx0/mpp.h -- Multi Purpose Pins + * +- * + * sebastien requiem <sebastien@requiem.fr> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __MV78X00_MPP_H +diff --git a/arch/arm/mach-mv78xx0/mv78xx0.h b/arch/arm/mach-mv78xx0/mv78xx0.h +index c1a9a1d1b2957..3f19bef7d7ace 100644 +--- a/arch/arm/mach-mv78xx0/mv78xx0.h ++++ b/arch/arm/mach-mv78xx0/mv78xx0.h +@@ -1,10 +1,7 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Generic definitions for Marvell MV78xx0 SoC flavors: + * MV781x0 and MV782x0. +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __ASM_ARCH_MV78XX0_H +diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c +index 636d84b404664..c07f1641179bd 100644 +--- a/arch/arm/mach-mv78xx0/pcie.c ++++ b/arch/arm/mach-mv78xx0/pcie.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-mv78xx0/pcie.c + * + * PCIe functions for Marvell MV78xx0 SoCs +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c +index 308ab71ec8221..80ca8b1a81de2 100644 +--- a/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c ++++ b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-mv78x00/rd78x00-masa-setup.c + * + * Marvell RD-78x00-mASA Development Board Setup +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h +index 09413b6784099..c96ecdafe31f1 100644 +--- a/arch/arm/mach-mvebu/armada-370-xp.h ++++ b/arch/arm/mach-mvebu/armada-370-xp.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Generic definitions for Marvell Armada_370_XP SoCs + * +@@ -6,10 +7,6 @@ + * Lior Amsalem <alior@marvell.com> + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __MACH_ARMADA_370_XP_H +diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c +index d2df5ef9382b4..fd5d0c8ff6958 100644 +--- a/arch/arm/mach-mvebu/board-v7.c ++++ b/arch/arm/mach-mvebu/board-v7.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Device Tree support for Armada 370 and XP platforms. + * +@@ -6,10 +7,6 @@ + * Lior Amsalem <alior@marvell.com> + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c +index 49e3c8d20c2fa..883dab1b54f3d 100644 +--- a/arch/arm/mach-mvebu/coherency.c ++++ b/arch/arm/mach-mvebu/coherency.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Coherency fabric (Aurora) support for Armada 370, 375, 38x and XP + * platforms. +@@ -8,10 +9,6 @@ + * Gregory Clement <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + * The Armada 370, 375, 38x and XP SOCs have a coherency fabric which is + * responsible for ensuring hardware coherency between all CPUs and between + * CPUs and I/O masters. This file initializes the coherency fabric and +diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h +index 6067f14263f79..cae866ab48673 100644 +--- a/arch/arm/mach-mvebu/coherency.h ++++ b/arch/arm/mach-mvebu/coherency.h +@@ -1,14 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * arch/arm/mach-mvebu/include/mach/coherency.h + * +- * + * Coherency fabric (Aurora) support for Armada 370 and XP platforms. + * + * Copyright (C) 2012 Marvell +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __MACH_370_XP_COHERENCY_H +diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S +index a3a64bf972507..eb81656e32d47 100644 +--- a/arch/arm/mach-mvebu/coherency_ll.S ++++ b/arch/arm/mach-mvebu/coherency_ll.S +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Coherency fabric: low level functions + * +@@ -5,10 +6,6 @@ + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + * This file implements the assembly function to add a CPU to the + * coherency fabric. This function is called by each of the secondary + * CPUs during their early boot in an SMP kernel, this why this +diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h +index 6b775492cfadc..fbfa3c4f30df7 100644 +--- a/arch/arm/mach-mvebu/common.h ++++ b/arch/arm/mach-mvebu/common.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Core functions for Marvell System On Chip + * +@@ -6,10 +7,6 @@ + * Lior Amsalem <alior@marvell.com> + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __ARCH_MVEBU_COMMON_H +diff --git a/arch/arm/mach-mvebu/cpu-reset.c b/arch/arm/mach-mvebu/cpu-reset.c +index f33a31c6aff8b..66b6c0c6ce1de 100644 +--- a/arch/arm/mach-mvebu/cpu-reset.c ++++ b/arch/arm/mach-mvebu/cpu-reset.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (C) 2014 Marvell + * + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define pr_fmt(fmt) "mvebu-cpureset: " fmt +diff --git a/arch/arm/mach-mvebu/dove.c b/arch/arm/mach-mvebu/dove.c +index d076c5771adc2..c938ba725d3e9 100644 +--- a/arch/arm/mach-mvebu/dove.c ++++ b/arch/arm/mach-mvebu/dove.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-mvebu/dove.c + * + * Marvell Dove 88AP510 System On Chip FDT Board +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/init.h> +diff --git a/arch/arm/mach-mvebu/headsmp-a9.S b/arch/arm/mach-mvebu/headsmp-a9.S +index b093a196e8017..df723cf85caec 100644 +--- a/arch/arm/mach-mvebu/headsmp-a9.S ++++ b/arch/arm/mach-mvebu/headsmp-a9.S +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * SMP support: Entry point for secondary CPUs of Marvell EBU + * Cortex-A9 based SOCs (Armada 375 and Armada 38x). +@@ -6,10 +7,6 @@ + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/linkage.h> +diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S +index 2c4032e368bad..f05c59dad32ac 100644 +--- a/arch/arm/mach-mvebu/headsmp.S ++++ b/arch/arm/mach-mvebu/headsmp.S +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * SMP support: Entry point for secondary CPUs + * +@@ -7,10 +8,6 @@ + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + * This file implements the assembly entry point for secondary CPUs in + * an SMP kernel. The only thing we need to do is to add the CPU to + * the coherency fabric by writing to 2 registers. Currently the base +diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c +index 06b1706595f4c..8ff34753e7609 100644 +--- a/arch/arm/mach-mvebu/kirkwood.c ++++ b/arch/arm/mach-mvebu/kirkwood.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net> + * + * arch/arm/mach-mvebu/kirkwood.c + * + * Flattened Device Tree board initialization +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/clk.h> +diff --git a/arch/arm/mach-mvebu/kirkwood.h b/arch/arm/mach-mvebu/kirkwood.h +index 89f3d1f516435..15135994ce2f2 100644 +--- a/arch/arm/mach-mvebu/kirkwood.h ++++ b/arch/arm/mach-mvebu/kirkwood.h +@@ -1,12 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * arch/arm/mach-mvebu/kirkwood.h + * + * Generic definitions for Marvell Kirkwood SoC flavors: + * 88F6180, 88F6192 and 88F6281. +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define KIRKWOOD_REGS_PHYS_BASE 0xf1000000 +diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.c b/arch/arm/mach-mvebu/mvebu-soc-id.c +index a99434bcee849..f436c7b8c7aee 100644 +--- a/arch/arm/mach-mvebu/mvebu-soc-id.c ++++ b/arch/arm/mach-mvebu/mvebu-soc-id.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * ID and revision information for mvebu SoCs + * +@@ -5,10 +6,6 @@ + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + * All the mvebu SoCs have information related to their variant and + * revision that can be read from the PCI control register. This is + * done before the PCI initialization to avoid any conflict. Once the +diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.h b/arch/arm/mach-mvebu/mvebu-soc-id.h +index e124a0b82a3e7..225649b2288a2 100644 +--- a/arch/arm/mach-mvebu/mvebu-soc-id.h ++++ b/arch/arm/mach-mvebu/mvebu-soc-id.h +@@ -1,11 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Marvell EBU SoC ID and revision definitions. + * + * Copyright (C) 2014 Marvell Semiconductor +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __LINUX_MVEBU_SOC_ID_H +diff --git a/arch/arm/mach-mvebu/platsmp-a9.c b/arch/arm/mach-mvebu/platsmp-a9.c +index d715dec1c197d..785ee2af5baab 100644 +--- a/arch/arm/mach-mvebu/platsmp-a9.c ++++ b/arch/arm/mach-mvebu/platsmp-a9.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Symmetric Multi Processing (SMP) support for Marvell EBU Cortex-A9 + * based SOCs (Armada 375/38x). +@@ -6,10 +7,6 @@ + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/init.h> +diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c +index c130497dc6cc4..18384ea6862cf 100644 +--- a/arch/arm/mach-mvebu/platsmp.c ++++ b/arch/arm/mach-mvebu/platsmp.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Symmetric Multi Processing (SMP) support for Armada XP + * +@@ -8,10 +9,6 @@ + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + * The Armada XP SoC has 4 ARMv7 PJ4B CPUs running in full HW coherency + * This file implements the routines for preparing the SMP infrastructure + * and waking up the secondary CPUs +diff --git a/arch/arm/mach-mvebu/pm-board.c b/arch/arm/mach-mvebu/pm-board.c +index 0705525116996..7fa1806acd659 100644 +--- a/arch/arm/mach-mvebu/pm-board.c ++++ b/arch/arm/mach-mvebu/pm-board.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Board-level suspend/resume support. + * + * Copyright (C) 2014-2015 Marvell + * + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/delay.h> +diff --git a/arch/arm/mach-mvebu/pm.c b/arch/arm/mach-mvebu/pm.c +index c487be61d6d8c..b149d9b775050 100644 +--- a/arch/arm/mach-mvebu/pm.c ++++ b/arch/arm/mach-mvebu/pm.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Suspend/resume support. Currently supporting Armada XP only. + * + * Copyright (C) 2014 Marvell + * + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/cpu_pm.h> +diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c +index 73d5d72dfc3e5..af27a7156675a 100644 +--- a/arch/arm/mach-mvebu/pmsu.c ++++ b/arch/arm/mach-mvebu/pmsu.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Power Management Service Unit(PMSU) support for Armada 370/XP platforms. + * +@@ -7,10 +8,6 @@ + * Gregory Clement <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + * The Armada 370 and Armada XP SOCs have a power management service + * unit which is responsible for powering down and waking up CPUs and + * other SOC units +diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h +index ea79269c27023..1e847388e8dde 100644 +--- a/arch/arm/mach-mvebu/pmsu.h ++++ b/arch/arm/mach-mvebu/pmsu.h +@@ -1,11 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Power Management Service Unit (PMSU) support for Armada 370/XP platforms. + * + * Copyright (C) 2012 Marvell +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __MACH_MVEBU_PMSU_H +diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S +index 7aae9a25cfeb7..f7d21385fd88c 100644 +--- a/arch/arm/mach-mvebu/pmsu_ll.S ++++ b/arch/arm/mach-mvebu/pmsu_ll.S +@@ -1,12 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Copyright (C) 2014 Marvell + * + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * Gregory Clement <gregory.clement@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/linkage.h> +diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c +index 04d9ebe6a90a0..48224b6ed6dc7 100644 +--- a/arch/arm/mach-mvebu/system-controller.c ++++ b/arch/arm/mach-mvebu/system-controller.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * System controller support for Armada 370, 375 and XP platforms. + * +@@ -7,10 +8,6 @@ + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + * The Armada 370, 375 and Armada XP SoCs have a range of + * miscellaneous registers, that do not belong to a particular device, + * but rather provide system-level features. This basic +diff --git a/arch/arm/mach-omap1/include/mach/mtd-xip.h b/arch/arm/mach-omap1/include/mach/mtd-xip.h +index d09b2bc4920fe..b163b8a65605b 100644 +--- a/arch/arm/mach-omap1/include/mach/mtd-xip.h ++++ b/arch/arm/mach-omap1/include/mach/mtd-xip.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * MTD primitives for XIP support. Architecture specific functions. + * +@@ -5,10 +6,7 @@ + * + * Author: Vladimir Barinov <vbarinov@embeddedalley.com> + * +- * (c) 2005 MontaVista Software, Inc. This file is licensed under the +- * terms of the GNU General Public License version 2. This program is +- * licensed "as is" without any warranty of any kind, whether express or +- * implied. ++ * (c) 2005 MontaVista Software, Inc. + */ + + #ifndef __ARCH_OMAP_MTD_XIP_H__ +diff --git a/arch/arm/mach-omap1/pm_bus.c b/arch/arm/mach-omap1/pm_bus.c +index 667c1637ff919..c04619ac06312 100644 +--- a/arch/arm/mach-omap1/pm_bus.c ++++ b/arch/arm/mach-omap1/pm_bus.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Runtime PM support code for OMAP1 + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * + * Copyright (C) 2010 Texas Instruments, Inc. +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/init.h> + #include <linux/kernel.h> +@@ -43,4 +40,3 @@ static int __init omap1_pm_runtime_init(void) + return 0; + } + core_initcall(omap1_pm_runtime_init); +- +diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h +index 899da0ae98000..31860ffd28abc 100644 +--- a/arch/arm/mach-omap2/prcm43xx.h ++++ b/arch/arm/mach-omap2/prcm43xx.h +@@ -1,11 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * AM43x PRCM defines + * + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/ +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. + */ + + #ifndef __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H +diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c +index 86f1ac4c24125..ea02d40405c4a 100644 +--- a/arch/arm/mach-omap2/vc.c ++++ b/arch/arm/mach-omap2/vc.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * OMAP Voltage Controller (VC) interface + * + * Copyright (C) 2011 Texas Instruments, Inc. +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/kernel.h> + #include <linux/delay.h> +@@ -895,4 +892,3 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm) + else if (cpu_is_omap44xx()) + omap4_vc_init_channel(voltdm); + } +- +diff --git a/arch/arm/mach-orion5x/board-d2net.c b/arch/arm/mach-orion5x/board-d2net.c +index a89376a5cd929..0297e302d7bc8 100644 +--- a/arch/arm/mach-orion5x/board-d2net.c ++++ b/arch/arm/mach-orion5x/board-d2net.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/board-d2net.c + * + * LaCie d2Network and Big Disk Network NAS setup + * + * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/board-dt.c b/arch/arm/mach-orion5x/board-dt.c +index 3f651df3a71cf..be47492c6640d 100644 +--- a/arch/arm/mach-orion5x/board-dt.c ++++ b/arch/arm/mach-orion5x/board-dt.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright 2012 (C), Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * + * arch/arm/mach-orion5x/board-dt.c + * + * Flattened Device Tree board initialization +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/board-rd88f5182.c b/arch/arm/mach-orion5x/board-rd88f5182.c +index b7b0f52f4c0a0..596601367989a 100644 +--- a/arch/arm/mach-orion5x/board-rd88f5182.c ++++ b/arch/arm/mach-orion5x/board-rd88f5182.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/rd88f5182-setup.c + * + * Marvell Orion-NAS Reference Design Setup + * + * Maintainer: Ronen Shitrit <rshitrit@marvell.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/gpio.h> + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/bridge-regs.h b/arch/arm/mach-orion5x/bridge-regs.h +index 305598eaaee15..fe85bc5b131fc 100644 +--- a/arch/arm/mach-orion5x/bridge-regs.h ++++ b/arch/arm/mach-orion5x/bridge-regs.h +@@ -1,10 +1,5 @@ +-/* +- * Orion CPU Bridge Registers +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* Orion CPU Bridge Registers */ + + #ifndef __ASM_ARCH_BRIDGE_REGS_H + #define __ASM_ARCH_BRIDGE_REGS_H +diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c +index 7bcb41137bbf6..2e711b7252c64 100644 +--- a/arch/arm/mach-orion5x/common.c ++++ b/arch/arm/mach-orion5x/common.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/common.c + * + * Core functions for Marvell Orion 5x SoCs + * + * Maintainer: Tzachi Perelstein <tzachi@marvell.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c +index 39eae10ac8def..fe1a4cef1ba2d 100644 +--- a/arch/arm/mach-orion5x/db88f5281-setup.c ++++ b/arch/arm/mach-orion5x/db88f5281-setup.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/db88f5281-setup.c + * + * Marvell Orion-2 Development Board Setup + * + * Maintainer: Tzachi Perelstein <tzachi@marvell.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/gpio.h> + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c +index ac4af2283bef9..5b076eefe2b4a 100644 +--- a/arch/arm/mach-orion5x/irq.c ++++ b/arch/arm/mach-orion5x/irq.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/irq.c + * + * Core IRQ functions for Marvell Orion System On Chip + * + * Maintainer: Tzachi Perelstein <tzachi@marvell.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/gpio.h> + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/irqs.h b/arch/arm/mach-orion5x/irqs.h +index 506c8e0b30c42..a70c47cfa6bcb 100644 +--- a/arch/arm/mach-orion5x/irqs.h ++++ b/arch/arm/mach-orion5x/irqs.h +@@ -1,11 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * IRQ definitions for Orion SoC + * + * Maintainer: Tzachi Perelstein <tzachi@marvell.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __ASM_ARCH_IRQS_H +diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c +index 83d43cff4bd77..acba066180801 100644 +--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c ++++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/kurobox_pro-setup.c + * + * Maintainer: Ronen Shitrit <rshitrit@marvell.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/gpio.h> + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/ls_hgl-setup.c b/arch/arm/mach-orion5x/ls_hgl-setup.c +index 47ba6e0502f59..af07f617465f7 100644 +--- a/arch/arm/mach-orion5x/ls_hgl-setup.c ++++ b/arch/arm/mach-orion5x/ls_hgl-setup.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/ls_hgl-setup.c + * + * Maintainer: Zhu Qingsen <zhuqs@cn.fujitsu.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c +index 19ef185944158..b9855dce6ba0a 100644 +--- a/arch/arm/mach-orion5x/mpp.c ++++ b/arch/arm/mach-orion5x/mpp.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/mpp.c + * + * MPP functions for Marvell Orion 5x SoCs +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c +index bf6be4cfd2384..695cc683cd833 100644 +--- a/arch/arm/mach-orion5x/net2big-setup.c ++++ b/arch/arm/mach-orion5x/net2big-setup.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/net2big-setup.c + * + * LaCie 2Big Network NAS setup + * + * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +@@ -432,4 +429,3 @@ MACHINE_START(NET2BIG, "LaCie 2Big Network") + .fixup = tag_fixup_mem32, + .restart = orion5x_restart, + MACHINE_END +- +diff --git a/arch/arm/mach-orion5x/orion5x.h b/arch/arm/mach-orion5x/orion5x.h +index 2b66120fba86c..26f1ccb8cb281 100644 +--- a/arch/arm/mach-orion5x/orion5x.h ++++ b/arch/arm/mach-orion5x/orion5x.h +@@ -1,12 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Generic definitions of Orion SoC flavors: + * Orion-1, Orion-VoIP, Orion-NAS, Orion-2, and Orion-1-90. + * + * Maintainer: Tzachi Perelstein <tzachi@marvell.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __ASM_ARCH_ORION5X_H +diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c +index 76951bfbacf57..fa62add8cf8a6 100644 +--- a/arch/arm/mach-orion5x/pci.c ++++ b/arch/arm/mach-orion5x/pci.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/pci.c + * + * PCI and PCIe functions for Marvell Orion System On Chip + * + * Maintainer: Tzachi Perelstein <tzachi@marvell.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c +index c65ab7db36ad9..432fc8357d9e1 100644 +--- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c ++++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c + * + * Marvell Orion-VoIP FXO Reference Design Setup +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/gpio.h> + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c +index 76b8138d9d79b..d4b1a9c3cd362 100644 +--- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c ++++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/rd88f5181l-ge-setup.c + * + * Marvell Orion-VoIP GE Reference Design Setup +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/gpio.h> + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c +index fe3e67c81fb82..6ffcfc6445e24 100644 +--- a/arch/arm/mach-orion5x/rd88f5182-setup.c ++++ b/arch/arm/mach-orion5x/rd88f5182-setup.c +@@ -1,13 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/rd88f5182-setup.c + * + * Marvell Orion-NAS Reference Design Setup + * + * Maintainer: Ronen Shitrit <rshitrit@marvell.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/gpio.h> + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c +index 5f388a1ed1e4c..93f74fd6b4dac 100644 +--- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c ++++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/rd88f6183-ap-ge-setup.c + * + * Marvell Orion-1-90 AP GE Reference Design Setup +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/gpio.h> + #include <linux/kernel.h> +diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c +index a39764faf2a01..af810e7ccd796 100644 +--- a/arch/arm/mach-orion5x/ts78xx-setup.c ++++ b/arch/arm/mach-orion5x/ts78xx-setup.c +@@ -1,11 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-orion5x/ts78xx-setup.c + * + * Maintainer: Alexander Clouter <alex@digriz.org.uk> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c +index 83589a28a4911..e5f327054dd33 100644 +--- a/arch/arm/mach-orion5x/wnr854t-setup.c ++++ b/arch/arm/mach-orion5x/wnr854t-setup.c +@@ -1,10 +1,5 @@ +-/* +- * arch/arm/mach-orion5x/wnr854t-setup.c +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only ++// arch/arm/mach-orion5x/wnr854t-setup.c + #include <linux/gpio.h> + #include <linux/kernel.h> + #include <linux/init.h> +diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c +index cea08d4a25974..e6a2da6662df5 100644 +--- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c ++++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c +@@ -1,10 +1,5 @@ +-/* +- * arch/arm/mach-orion5x/wrt350n-v2-setup.c +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- */ ++// SPDX-License-Identifier: GPL-2.0-only ++// arch/arm/mach-orion5x/wrt350n-v2-setup.c + #include <linux/gpio.h> + #include <linux/kernel.h> + #include <linux/init.h> +diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c +index f37c44b6139d7..b9e235cb5a073 100644 +--- a/arch/arm/mach-pxa/eseries.c ++++ b/arch/arm/mach-pxa/eseries.c +@@ -1,13 +1,8 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Hardware definitions for the Toshiba eseries PDAs + * + * Copyright (c) 2003 Ian Molton <spyro@f2s.com> +- * +- * This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. +- * + */ + + #include <linux/clkdev.h> +diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S +index eab1645bb4adb..60d0d14d4a0fe 100644 +--- a/arch/arm/mach-pxa/standby.S ++++ b/arch/arm/mach-pxa/standby.S +@@ -1,12 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * PXA27x standby mode + * + * Author: David Burrage + * +- * 2005 (c) MontaVista Software, Inc. This file is licensed under +- * the terms of the GNU General Public License version 2. This program +- * is licensed "as is" without any warranty of any kind, whether express +- * or implied. ++ * 2005 (c) MontaVista Software, Inc. + */ + + #include <linux/linkage.h> +diff --git a/arch/arm/mach-spear/generic.h b/arch/arm/mach-spear/generic.h +index 8ec2b92dca192..43b7996ab7545 100644 +--- a/arch/arm/mach-spear/generic.h ++++ b/arch/arm/mach-spear/generic.h +@@ -1,13 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * spear machine family generic header file + * + * Copyright (C) 2009-2012 ST Microelectronics + * Rajeev Kumar <rajeev-dlh.kumar@st.com> + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __MACH_GENERIC_H +diff --git a/arch/arm/mach-spear/include/mach/misc_regs.h b/arch/arm/mach-spear/include/mach/misc_regs.h +index cfaf7c665b588..12a789bd896e0 100644 +--- a/arch/arm/mach-spear/include/mach/misc_regs.h ++++ b/arch/arm/mach-spear/include/mach/misc_regs.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * arch/arm/mach-spear3xx/include/mach/misc_regs.h + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __MACH_MISC_REGS_H +diff --git a/arch/arm/mach-spear/include/mach/spear.h b/arch/arm/mach-spear/include/mach/spear.h +index 5ed841ccf8a38..432efd407c763 100644 +--- a/arch/arm/mach-spear/include/mach/spear.h ++++ b/arch/arm/mach-spear/include/mach/spear.h +@@ -1,13 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * SPEAr3xx/6xx Machine family specific definition + * + * Copyright (C) 2009,2012 ST Microelectronics + * Rajeev Kumar<rajeev-dlh.kumar@st.com> + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __MACH_SPEAR_H +diff --git a/arch/arm/mach-spear/pl080.c b/arch/arm/mach-spear/pl080.c +index b4529f3e0ee97..35c929de46755 100644 +--- a/arch/arm/mach-spear/pl080.c ++++ b/arch/arm/mach-spear/pl080.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/plat-spear/pl080.c + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2012 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/amba/pl08x.h> +diff --git a/arch/arm/mach-spear/pl080.h b/arch/arm/mach-spear/pl080.h +index 608dec6725aea..3732d940dbfb6 100644 +--- a/arch/arm/mach-spear/pl080.h ++++ b/arch/arm/mach-spear/pl080.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * arch/arm/plat-spear/include/plat/pl080.h + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2012 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #ifndef __PLAT_PL080_H +diff --git a/arch/arm/mach-spear/restart.c b/arch/arm/mach-spear/restart.c +index b4342155a7833..01f529675629f 100644 +--- a/arch/arm/mach-spear/restart.c ++++ b/arch/arm/mach-spear/restart.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/plat-spear/restart.c + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + #include <linux/io.h> + #include <linux/amba/sp810.h> +diff --git a/arch/arm/mach-spear/spear1310.c b/arch/arm/mach-spear/spear1310.c +index a7d4f136836fa..020b27e65aea0 100644 +--- a/arch/arm/mach-spear/spear1310.c ++++ b/arch/arm/mach-spear/spear1310.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-spear13xx/spear1310.c + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2012 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define pr_fmt(fmt) "SPEAr1310: " fmt +diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c +index a212af90c0bc6..a391f154eff9b 100644 +--- a/arch/arm/mach-spear/spear1340.c ++++ b/arch/arm/mach-spear/spear1340.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-spear13xx/spear1340.c + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2012 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define pr_fmt(fmt) "SPEAr1340: " fmt +diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c +index 74d1ca2a529a7..64087046dfff7 100644 +--- a/arch/arm/mach-spear/spear13xx.c ++++ b/arch/arm/mach-spear/spear13xx.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-spear13xx/spear13xx.c + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2012 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define pr_fmt(fmt) "SPEAr13xx: " fmt +diff --git a/arch/arm/mach-spear/spear300.c b/arch/arm/mach-spear/spear300.c +index 325b89579be10..490df8aaad90c 100644 +--- a/arch/arm/mach-spear/spear300.c ++++ b/arch/arm/mach-spear/spear300.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-spear3xx/spear300.c + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2009-2012 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define pr_fmt(fmt) "SPEAr300: " fmt +diff --git a/arch/arm/mach-spear/spear310.c b/arch/arm/mach-spear/spear310.c +index 59e173dc85cf3..5ca325fc1b825 100644 +--- a/arch/arm/mach-spear/spear310.c ++++ b/arch/arm/mach-spear/spear310.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-spear3xx/spear310.c + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2009-2012 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define pr_fmt(fmt) "SPEAr310: " fmt +diff --git a/arch/arm/mach-spear/spear320.c b/arch/arm/mach-spear/spear320.c +index 926d5a243238a..991de88dfe4d3 100644 +--- a/arch/arm/mach-spear/spear320.c ++++ b/arch/arm/mach-spear/spear320.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-spear3xx/spear320.c + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2009-2012 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define pr_fmt(fmt) "SPEAr320: " fmt +diff --git a/arch/arm/mach-spear/spear3xx.c b/arch/arm/mach-spear/spear3xx.c +index f83321d5e3538..cdaa41900a399 100644 +--- a/arch/arm/mach-spear/spear3xx.c ++++ b/arch/arm/mach-spear/spear3xx.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-spear3xx/spear3xx.c + * +@@ -5,10 +6,6 @@ + * + * Copyright (C) 2009-2012 ST Microelectronics + * Viresh Kumar <vireshk@kernel.org> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #define pr_fmt(fmt) "SPEAr3xx: " fmt +diff --git a/arch/arm/mach-spear/spear6xx.c b/arch/arm/mach-spear/spear6xx.c +index c5fc110134ba6..11eb64a369807 100644 +--- a/arch/arm/mach-spear/spear6xx.c ++++ b/arch/arm/mach-spear/spear6xx.c +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mach-spear6xx/spear6xx.c + * +@@ -7,10 +8,6 @@ + * Rajeev Kumar<rajeev-dlh.kumar@st.com> + * + * Copyright 2012 Stefan Roese <sr@denx.de> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/amba/pl08x.h> +diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c +index d1fdb6066f7bb..6baf952fa902f 100644 +--- a/arch/arm/mach-spear/time.c ++++ b/arch/arm/mach-spear/time.c +@@ -1,12 +1,9 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/plat-spear/time.c + * + * Copyright (C) 2010 ST Microelectronics + * Shiraz Hashim<shiraz.linux.kernel@gmail.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. + */ + + #include <linux/clk.h> +diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c +index 5c1b7a7b9af63..25dbd84a1aafa 100644 +--- a/arch/arm/mm/cache-feroceon-l2.c ++++ b/arch/arm/mm/cache-feroceon-l2.c +@@ -1,12 +1,9 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mm/cache-feroceon-l2.c - Feroceon L2 cache controller support + * + * Copyright (C) 2008 Marvell Semiconductor + * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + * References: + * - Unified Layer 2 Cache for Feroceon CPU Cores, + * Document ID MV-S104858-00, Rev. A, October 23 2007. +diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c +index 88255bea65e41..b1e1aba602f7f 100644 +--- a/arch/arm/mm/cache-tauros2.c ++++ b/arch/arm/mm/cache-tauros2.c +@@ -1,12 +1,9 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * arch/arm/mm/cache-tauros2.c - Tauros2 L2 cache controller support + * + * Copyright (C) 2008 Marvell Semiconductor + * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + * References: + * - PJ1 CPU Core Datasheet, + * Document ID MV-S104837-01, Rev 0.7, January 24 2008. +diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c +index 50de86eb8784c..3183df60ad337 100644 +--- a/arch/mips/alchemy/devboards/db1000.c ++++ b/arch/mips/alchemy/devboards/db1000.c +@@ -164,6 +164,7 @@ static struct platform_device db1x00_audio_dev = { + + /******************************************************************************/ + ++#ifdef CONFIG_MMC_AU1X + static irqreturn_t db1100_mmc_cd(int irq, void *ptr) + { + mmc_detect_change(ptr, msecs_to_jiffies(500)); +@@ -369,6 +370,7 @@ static struct platform_device db1100_mmc1_dev = { + .num_resources = ARRAY_SIZE(au1100_mmc1_res), + .resource = au1100_mmc1_res, + }; ++#endif /* CONFIG_MMC_AU1X */ + + /******************************************************************************/ + +@@ -432,8 +434,10 @@ static struct platform_device *db1x00_devs[] = { + + static struct platform_device *db1100_devs[] = { + &au1100_lcd_device, ++#ifdef CONFIG_MMC_AU1X + &db1100_mmc0_dev, + &db1100_mmc1_dev, ++#endif + }; + + int __init db1000_dev_setup(void) +diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c +index 76080c71a2a7b..f521874ebb07b 100644 +--- a/arch/mips/alchemy/devboards/db1200.c ++++ b/arch/mips/alchemy/devboards/db1200.c +@@ -326,6 +326,7 @@ static struct platform_device db1200_ide_dev = { + + /**********************************************************************/ + ++#ifdef CONFIG_MMC_AU1X + /* SD carddetects: they're supposed to be edge-triggered, but ack + * doesn't seem to work (CPLD Rev 2). Instead, the screaming one + * is disabled and its counterpart enabled. The 200ms timeout is +@@ -584,6 +585,7 @@ static struct platform_device pb1200_mmc1_dev = { + .num_resources = ARRAY_SIZE(au1200_mmc1_res), + .resource = au1200_mmc1_res, + }; ++#endif /* CONFIG_MMC_AU1X */ + + /**********************************************************************/ + +@@ -751,7 +753,9 @@ static struct platform_device db1200_audiodma_dev = { + static struct platform_device *db1200_devs[] __initdata = { + NULL, /* PSC0, selected by S6.8 */ + &db1200_ide_dev, ++#ifdef CONFIG_MMC_AU1X + &db1200_mmc0_dev, ++#endif + &au1200_lcd_dev, + &db1200_eth_dev, + &db1200_nand_dev, +@@ -762,7 +766,9 @@ static struct platform_device *db1200_devs[] __initdata = { + }; + + static struct platform_device *pb1200_devs[] __initdata = { ++#ifdef CONFIG_MMC_AU1X + &pb1200_mmc1_dev, ++#endif + }; + + /* Some peripheral base addresses differ on the PB1200 */ +diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c +index ca71e5ed51abd..c965d00074818 100644 +--- a/arch/mips/alchemy/devboards/db1300.c ++++ b/arch/mips/alchemy/devboards/db1300.c +@@ -450,6 +450,7 @@ static struct platform_device db1300_ide_dev = { + + /**********************************************************************/ + ++#ifdef CONFIG_MMC_AU1X + static irqreturn_t db1300_mmc_cd(int irq, void *ptr) + { + disable_irq_nosync(irq); +@@ -632,6 +633,7 @@ static struct platform_device db1300_sd0_dev = { + .resource = au1300_sd0_res, + .num_resources = ARRAY_SIZE(au1300_sd0_res), + }; ++#endif /* CONFIG_MMC_AU1X */ + + /**********************************************************************/ + +@@ -776,8 +778,10 @@ static struct platform_device *db1300_dev[] __initdata = { + &db1300_5waysw_dev, + &db1300_nand_dev, + &db1300_ide_dev, ++#ifdef CONFIG_MMC_AU1X + &db1300_sd0_dev, + &db1300_sd1_dev, ++#endif + &db1300_lcd_dev, + &db1300_ac97_dev, + &db1300_i2s_dev, +diff --git a/arch/parisc/include/asm/ropes.h b/arch/parisc/include/asm/ropes.h +index 8e51c775c80a6..62399c7ea94a1 100644 +--- a/arch/parisc/include/asm/ropes.h ++++ b/arch/parisc/include/asm/ropes.h +@@ -86,6 +86,9 @@ struct sba_device { + struct ioc ioc[MAX_IOC]; + }; + ++/* list of SBA's in system, see drivers/parisc/sba_iommu.c */ ++extern struct sba_device *sba_list; ++ + #define ASTRO_RUNWAY_PORT 0x582 + #define IKE_MERCED_PORT 0x803 + #define REO_MERCED_PORT 0x804 +diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c +index e7ee0c0c91d35..8f12b9f318ae6 100644 +--- a/arch/parisc/kernel/drivers.c ++++ b/arch/parisc/kernel/drivers.c +@@ -924,9 +924,9 @@ static __init void qemu_header(void) + pr_info("#define PARISC_MODEL \"%s\"\n\n", + boot_cpu_data.pdc.sys_model_name); + ++ #define p ((unsigned long *)&boot_cpu_data.pdc.model) + pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, " + "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n", +- #define p ((unsigned long *)&boot_cpu_data.pdc.model) + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); + #undef p + +diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c +index e6cc38ef69458..5d9044e65a1a6 100644 +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -386,7 +386,7 @@ union irq_stack_union { + volatile unsigned int lock[1]; + }; + +-DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { ++static DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { + .slock = { 1,1,1,1 }, + }; + #endif +diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c +index 91a3be14808b1..affb03f56a7e1 100644 +--- a/arch/powerpc/kernel/hw_breakpoint.c ++++ b/arch/powerpc/kernel/hw_breakpoint.c +@@ -478,11 +478,13 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs) + struct arch_hw_breakpoint *info; + int i; + ++ preempt_disable(); ++ + for (i = 0; i < nr_wp_slots(); i++) { + if (unlikely(tsk->thread.last_hit_ubp[i])) + goto reset; + } +- return; ++ goto out; + + reset: + regs_set_return_msr(regs, regs->msr & ~MSR_SE); +@@ -491,6 +493,9 @@ reset: + __set_breakpoint(i, info); + tsk->thread.last_hit_ubp[i] = NULL; + } ++ ++out: ++ preempt_enable(); + } + + static bool is_larx_stcx_instr(int type) +@@ -605,6 +610,11 @@ static void handle_p10dd1_spurious_exception(struct arch_hw_breakpoint **info, + } + } + ++/* ++ * Handle a DABR or DAWR exception. ++ * ++ * Called in atomic context. ++ */ + int hw_breakpoint_handler(struct die_args *args) + { + bool err = false; +@@ -731,6 +741,8 @@ NOKPROBE_SYMBOL(hw_breakpoint_handler); + + /* + * Handle single-step exceptions following a DABR hit. ++ * ++ * Called in atomic context. + */ + static int single_step_dabr_instruction(struct die_args *args) + { +@@ -788,6 +800,8 @@ NOKPROBE_SYMBOL(single_step_dabr_instruction); + + /* + * Handle debug exception notifications. ++ * ++ * Called in atomic context. + */ + int hw_breakpoint_exceptions_notify( + struct notifier_block *unused, unsigned long val, void *data) +diff --git a/arch/powerpc/kernel/hw_breakpoint_constraints.c b/arch/powerpc/kernel/hw_breakpoint_constraints.c +index 675d1f66ab728..a541e3b755479 100644 +--- a/arch/powerpc/kernel/hw_breakpoint_constraints.c ++++ b/arch/powerpc/kernel/hw_breakpoint_constraints.c +@@ -140,8 +140,13 @@ void wp_get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr, + int *type, int *size, unsigned long *ea) + { + struct instruction_op op; ++ int err; + +- if (__get_user_instr(*instr, (void __user *)regs->nip)) ++ pagefault_disable(); ++ err = __get_user_instr(*instr, (void __user *)regs->nip); ++ pagefault_enable(); ++ ++ if (err) + return; + + analyse_instr(&op, regs, *instr); +diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c +index 1816f560a4652..284ccc90fb11c 100644 +--- a/arch/powerpc/perf/hv-24x7.c ++++ b/arch/powerpc/perf/hv-24x7.c +@@ -1431,7 +1431,7 @@ static int h_24x7_event_init(struct perf_event *event) + } + + domain = event_get_domain(event); +- if (domain >= HV_PERF_DOMAIN_MAX) { ++ if (domain == 0 || domain >= HV_PERF_DOMAIN_MAX) { + pr_devel("invalid domain %d\n", domain); + return -EINVAL; + } +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c +index 0d2c5fe841414..6322a08edbba5 100644 +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -2414,7 +2414,7 @@ static void __init srso_select_mitigation(void) + + switch (srso_cmd) { + case SRSO_CMD_OFF: +- return; ++ goto pred_cmd; + + case SRSO_CMD_MICROCODE: + if (has_microcode) { +@@ -2692,7 +2692,7 @@ static ssize_t srso_show_state(char *buf) + + return sysfs_emit(buf, "%s%s\n", + srso_strings[srso_mitigation], +- (cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode")); ++ boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode"); + } + + static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr, +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index 3151c08bb54a5..01c4f8f45b837 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -1172,7 +1172,7 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { + VULNBL_AMD(0x15, RETBLEED), + VULNBL_AMD(0x16, RETBLEED), + VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO), +- VULNBL_HYGON(0x18, RETBLEED | SMT_RSB), ++ VULNBL_HYGON(0x18, RETBLEED | SMT_RSB | SRSO), + VULNBL_AMD(0x19, SRSO), + {} + }; +diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile +index a65b7a9ebff28..d8b0fadf429a9 100644 +--- a/arch/xtensa/boot/Makefile ++++ b/arch/xtensa/boot/Makefile +@@ -9,8 +9,7 @@ + + + # KBUILD_CFLAGS used when building rest of boot (takes effect recursively) +-KBUILD_CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include +-HOSTFLAGS += -Iarch/$(ARCH)/boot/include ++KBUILD_CFLAGS += -fno-builtin + + subdir-y := lib + targets += vmlinux.bin vmlinux.bin.gz +diff --git a/arch/xtensa/boot/lib/zmem.c b/arch/xtensa/boot/lib/zmem.c +index e3ecd743c5153..b89189355122a 100644 +--- a/arch/xtensa/boot/lib/zmem.c ++++ b/arch/xtensa/boot/lib/zmem.c +@@ -4,13 +4,14 @@ + /* bits taken from ppc */ + + extern void *avail_ram, *end_avail; ++void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); + +-void exit (void) ++static void exit(void) + { + for (;;); + } + +-void *zalloc(unsigned size) ++static void *zalloc(unsigned int size) + { + void *p = avail_ram; + +diff --git a/arch/xtensa/include/asm/core.h b/arch/xtensa/include/asm/core.h +index a4e40166ff4bb..0fa3649649e98 100644 +--- a/arch/xtensa/include/asm/core.h ++++ b/arch/xtensa/include/asm/core.h +@@ -6,6 +6,10 @@ + + #include <variant/core.h> + ++#ifndef XCHAL_HAVE_DIV32 ++#define XCHAL_HAVE_DIV32 0 ++#endif ++ + #ifndef XCHAL_HAVE_EXCLUSIVE + #define XCHAL_HAVE_EXCLUSIVE 0 + #endif +diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c +index 1270de83435eb..e8491ac0d5b93 100644 +--- a/arch/xtensa/platforms/iss/network.c ++++ b/arch/xtensa/platforms/iss/network.c +@@ -204,7 +204,7 @@ static int tuntap_write(struct iss_net_private *lp, struct sk_buff **skb) + return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len); + } + +-unsigned short tuntap_protocol(struct sk_buff *skb) ++static unsigned short tuntap_protocol(struct sk_buff *skb) + { + return eth_type_trans(skb, skb->dev); + } +@@ -477,7 +477,7 @@ static int iss_net_change_mtu(struct net_device *dev, int new_mtu) + return -EINVAL; + } + +-void iss_net_user_timer_expire(struct timer_list *unused) ++static void iss_net_user_timer_expire(struct timer_list *unused) + { + } + +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index acc028414ee94..3147b2e6cd8c9 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -50,7 +50,8 @@ enum board_ids { + /* board IDs by feature in alphabetical order */ + board_ahci, + board_ahci_ign_iferr, +- board_ahci_mobile, ++ board_ahci_low_power, ++ board_ahci_no_debounce_delay, + board_ahci_nomsi, + board_ahci_noncq, + board_ahci_nosntf, +@@ -135,13 +136,20 @@ static const struct ata_port_info ahci_port_info[] = { + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, +- [board_ahci_mobile] = { ++ [board_ahci_low_power] = { + AHCI_HFLAGS (AHCI_HFLAG_IS_MOBILE), + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, ++ [board_ahci_no_debounce_delay] = { ++ .flags = AHCI_FLAG_COMMON, ++ .link_flags = ATA_LFLAG_NO_DEBOUNCE_DELAY, ++ .pio_mask = ATA_PIO4, ++ .udma_mask = ATA_UDMA6, ++ .port_ops = &ahci_ops, ++ }, + [board_ahci_nomsi] = { + AHCI_HFLAGS (AHCI_HFLAG_NO_MSI), + .flags = AHCI_FLAG_COMMON, +@@ -268,13 +276,13 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */ + { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */ + { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */ +- { PCI_VDEVICE(INTEL, 0x2929), board_ahci_mobile }, /* ICH9M */ +- { PCI_VDEVICE(INTEL, 0x292a), board_ahci_mobile }, /* ICH9M */ +- { PCI_VDEVICE(INTEL, 0x292b), board_ahci_mobile }, /* ICH9M */ +- { PCI_VDEVICE(INTEL, 0x292c), board_ahci_mobile }, /* ICH9M */ +- { PCI_VDEVICE(INTEL, 0x292f), board_ahci_mobile }, /* ICH9M */ ++ { PCI_VDEVICE(INTEL, 0x2929), board_ahci_low_power }, /* ICH9M */ ++ { PCI_VDEVICE(INTEL, 0x292a), board_ahci_low_power }, /* ICH9M */ ++ { PCI_VDEVICE(INTEL, 0x292b), board_ahci_low_power }, /* ICH9M */ ++ { PCI_VDEVICE(INTEL, 0x292c), board_ahci_low_power }, /* ICH9M */ ++ { PCI_VDEVICE(INTEL, 0x292f), board_ahci_low_power }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */ +- { PCI_VDEVICE(INTEL, 0x294e), board_ahci_mobile }, /* ICH9M */ ++ { PCI_VDEVICE(INTEL, 0x294e), board_ahci_low_power }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */ + { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */ + { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */ +@@ -284,9 +292,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */ + { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */ + { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */ +- { PCI_VDEVICE(INTEL, 0x3b29), board_ahci_mobile }, /* PCH M AHCI */ ++ { PCI_VDEVICE(INTEL, 0x3b29), board_ahci_low_power }, /* PCH M AHCI */ + { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ +- { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_mobile }, /* PCH M RAID */ ++ { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_low_power }, /* PCH M RAID */ + { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ + { PCI_VDEVICE(INTEL, 0x19b0), board_ahci_pcs7 }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19b1), board_ahci_pcs7 }, /* DNV AHCI */ +@@ -309,9 +317,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(INTEL, 0x19cE), board_ahci_pcs7 }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19cF), board_ahci_pcs7 }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ +- { PCI_VDEVICE(INTEL, 0x1c03), board_ahci_mobile }, /* CPT M AHCI */ ++ { PCI_VDEVICE(INTEL, 0x1c03), board_ahci_low_power }, /* CPT M AHCI */ + { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ +- { PCI_VDEVICE(INTEL, 0x1c05), board_ahci_mobile }, /* CPT M RAID */ ++ { PCI_VDEVICE(INTEL, 0x1c05), board_ahci_low_power }, /* CPT M RAID */ + { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */ + { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */ + { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */ +@@ -320,29 +328,29 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */ + { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ + { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */ +- { PCI_VDEVICE(INTEL, 0x1e03), board_ahci_mobile }, /* Panther M AHCI */ ++ { PCI_VDEVICE(INTEL, 0x1e03), board_ahci_low_power }, /* Panther M AHCI */ + { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */ + { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */ + { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */ +- { PCI_VDEVICE(INTEL, 0x1e07), board_ahci_mobile }, /* Panther M RAID */ ++ { PCI_VDEVICE(INTEL, 0x1e07), board_ahci_low_power }, /* Panther M RAID */ + { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */ + { PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */ +- { PCI_VDEVICE(INTEL, 0x8c03), board_ahci_mobile }, /* Lynx M AHCI */ ++ { PCI_VDEVICE(INTEL, 0x8c03), board_ahci_low_power }, /* Lynx M AHCI */ + { PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */ +- { PCI_VDEVICE(INTEL, 0x8c05), board_ahci_mobile }, /* Lynx M RAID */ ++ { PCI_VDEVICE(INTEL, 0x8c05), board_ahci_low_power }, /* Lynx M RAID */ + { PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */ +- { PCI_VDEVICE(INTEL, 0x8c07), board_ahci_mobile }, /* Lynx M RAID */ ++ { PCI_VDEVICE(INTEL, 0x8c07), board_ahci_low_power }, /* Lynx M RAID */ + { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */ +- { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_mobile }, /* Lynx M RAID */ +- { PCI_VDEVICE(INTEL, 0x9c02), board_ahci_mobile }, /* Lynx LP AHCI */ +- { PCI_VDEVICE(INTEL, 0x9c03), board_ahci_mobile }, /* Lynx LP AHCI */ +- { PCI_VDEVICE(INTEL, 0x9c04), board_ahci_mobile }, /* Lynx LP RAID */ +- { PCI_VDEVICE(INTEL, 0x9c05), board_ahci_mobile }, /* Lynx LP RAID */ +- { PCI_VDEVICE(INTEL, 0x9c06), board_ahci_mobile }, /* Lynx LP RAID */ +- { PCI_VDEVICE(INTEL, 0x9c07), board_ahci_mobile }, /* Lynx LP RAID */ +- { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_mobile }, /* Lynx LP RAID */ +- { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_mobile }, /* Lynx LP RAID */ +- { PCI_VDEVICE(INTEL, 0x9dd3), board_ahci_mobile }, /* Cannon Lake PCH-LP AHCI */ ++ { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_low_power }, /* Lynx M RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c02), board_ahci_low_power }, /* Lynx LP AHCI */ ++ { PCI_VDEVICE(INTEL, 0x9c03), board_ahci_low_power }, /* Lynx LP AHCI */ ++ { PCI_VDEVICE(INTEL, 0x9c04), board_ahci_low_power }, /* Lynx LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c05), board_ahci_low_power }, /* Lynx LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c06), board_ahci_low_power }, /* Lynx LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c07), board_ahci_low_power }, /* Lynx LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_low_power }, /* Lynx LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_low_power }, /* Lynx LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9dd3), board_ahci_low_power }, /* Cannon Lake PCH-LP AHCI */ + { PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */ + { PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */ + { PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */ +@@ -374,26 +382,26 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */ + { PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */ + { PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */ +- { PCI_VDEVICE(INTEL, 0x9c83), board_ahci_mobile }, /* Wildcat LP AHCI */ +- { PCI_VDEVICE(INTEL, 0x9c85), board_ahci_mobile }, /* Wildcat LP RAID */ +- { PCI_VDEVICE(INTEL, 0x9c87), board_ahci_mobile }, /* Wildcat LP RAID */ +- { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_mobile }, /* Wildcat LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c83), board_ahci_low_power }, /* Wildcat LP AHCI */ ++ { PCI_VDEVICE(INTEL, 0x9c85), board_ahci_low_power }, /* Wildcat LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c87), board_ahci_low_power }, /* Wildcat LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_low_power }, /* Wildcat LP RAID */ + { PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */ +- { PCI_VDEVICE(INTEL, 0x8c83), board_ahci_mobile }, /* 9 Series M AHCI */ ++ { PCI_VDEVICE(INTEL, 0x8c83), board_ahci_low_power }, /* 9 Series M AHCI */ + { PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */ +- { PCI_VDEVICE(INTEL, 0x8c85), board_ahci_mobile }, /* 9 Series M RAID */ ++ { PCI_VDEVICE(INTEL, 0x8c85), board_ahci_low_power }, /* 9 Series M RAID */ + { PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */ +- { PCI_VDEVICE(INTEL, 0x8c87), board_ahci_mobile }, /* 9 Series M RAID */ ++ { PCI_VDEVICE(INTEL, 0x8c87), board_ahci_low_power }, /* 9 Series M RAID */ + { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ +- { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_mobile }, /* 9 Series M RAID */ +- { PCI_VDEVICE(INTEL, 0x9d03), board_ahci_mobile }, /* Sunrise LP AHCI */ +- { PCI_VDEVICE(INTEL, 0x9d05), board_ahci_mobile }, /* Sunrise LP RAID */ +- { PCI_VDEVICE(INTEL, 0x9d07), board_ahci_mobile }, /* Sunrise LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_low_power }, /* 9 Series M RAID */ ++ { PCI_VDEVICE(INTEL, 0x9d03), board_ahci_low_power }, /* Sunrise LP AHCI */ ++ { PCI_VDEVICE(INTEL, 0x9d05), board_ahci_low_power }, /* Sunrise LP RAID */ ++ { PCI_VDEVICE(INTEL, 0x9d07), board_ahci_low_power }, /* Sunrise LP RAID */ + { PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */ +- { PCI_VDEVICE(INTEL, 0xa103), board_ahci_mobile }, /* Sunrise M AHCI */ ++ { PCI_VDEVICE(INTEL, 0xa103), board_ahci_low_power }, /* Sunrise M AHCI */ + { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ + { PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */ +- { PCI_VDEVICE(INTEL, 0xa107), board_ahci_mobile }, /* Sunrise M RAID */ ++ { PCI_VDEVICE(INTEL, 0xa107), board_ahci_low_power }, /* Sunrise M RAID */ + { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ + { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/ +@@ -410,13 +418,15 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */ + { PCI_VDEVICE(INTEL, 0x06d7), board_ahci }, /* Comet Lake-H RAID */ + { PCI_VDEVICE(INTEL, 0xa386), board_ahci }, /* Comet Lake PCH-V RAID */ +- { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */ +- { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */ +- { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */ +- { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */ +- { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_mobile }, /* Ice Lake LP AHCI */ +- { PCI_VDEVICE(INTEL, 0x02d3), board_ahci_mobile }, /* Comet Lake PCH-U AHCI */ +- { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_mobile }, /* Comet Lake PCH RAID */ ++ { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_low_power }, /* Bay Trail AHCI */ ++ { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_low_power }, /* Bay Trail AHCI */ ++ { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_low_power }, /* Cherry Tr. AHCI */ ++ { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_low_power }, /* ApolloLake AHCI */ ++ { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_low_power }, /* Ice Lake LP AHCI */ ++ { PCI_VDEVICE(INTEL, 0x02d3), board_ahci_low_power }, /* Comet Lake PCH-U AHCI */ ++ { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */ ++ /* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */ ++ { PCI_VDEVICE(INTEL, 0x4b63), board_ahci_low_power }, /* Elkhart Lake AHCI */ + + /* JMicron 360/1/3/5/6, match class to avoid IDE function */ + { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, +@@ -442,8 +452,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { + board_ahci_al }, + /* AMD */ + { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */ ++ { PCI_VDEVICE(AMD, 0x7801), board_ahci_no_debounce_delay }, /* AMD Hudson-2 (AHCI mode) */ + { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */ +- { PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */ ++ { PCI_VDEVICE(AMD, 0x7901), board_ahci_low_power }, /* AMD Green Sardine */ + /* AMD is using RAID class only for ahci controllers */ + { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci }, +@@ -707,7 +718,7 @@ static void ahci_pci_init_controller(struct ata_host *host) + + /* clear port IRQ */ + tmp = readl(port_mmio + PORT_IRQ_STAT); +- VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); ++ dev_dbg(&pdev->dev, "PORT_IRQ_STAT 0x%x\n", tmp); + if (tmp) + writel(tmp, port_mmio + PORT_IRQ_STAT); + } +@@ -1499,7 +1510,6 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance) + u32 irq_stat, irq_masked; + unsigned int handled = 1; + +- VPRINTK("ENTER\n"); + hpriv = host->private_data; + mmio = hpriv->mmio; + irq_stat = readl(mmio + HOST_IRQ_STAT); +@@ -1516,7 +1526,6 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance) + irq_stat = readl(mmio + HOST_IRQ_STAT); + spin_unlock(&host->lock); + } while (irq_stat); +- VPRINTK("EXIT\n"); + + return IRQ_RETVAL(handled); + } +diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c +index 6e9c5ade4c2ea..649815c196ed0 100644 +--- a/drivers/ata/ahci_brcm.c ++++ b/drivers/ata/ahci_brcm.c +@@ -333,7 +333,7 @@ static struct ata_port_operations ahci_brcm_platform_ops = { + + static const struct ata_port_info ahci_brcm_port_info = { + .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, +- .link_flags = ATA_LFLAG_NO_DB_DELAY, ++ .link_flags = ATA_LFLAG_NO_DEBOUNCE_DELAY, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_brcm_platform_ops, +diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c +index 292099410cf68..c1f61d255bc31 100644 +--- a/drivers/ata/ahci_xgene.c ++++ b/drivers/ata/ahci_xgene.c +@@ -588,8 +588,6 @@ static irqreturn_t xgene_ahci_irq_intr(int irq, void *dev_instance) + void __iomem *mmio; + u32 irq_stat, irq_masked; + +- VPRINTK("ENTER\n"); +- + hpriv = host->private_data; + mmio = hpriv->mmio; + +@@ -612,8 +610,6 @@ static irqreturn_t xgene_ahci_irq_intr(int irq, void *dev_instance) + + spin_unlock(&host->lock); + +- VPRINTK("EXIT\n"); +- + return IRQ_RETVAL(rc); + } + +diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c +index 192115a45dd78..e22d45fb8ebdc 100644 +--- a/drivers/ata/libahci.c ++++ b/drivers/ata/libahci.c +@@ -1200,6 +1200,26 @@ static ssize_t ahci_activity_show(struct ata_device *dev, char *buf) + return sprintf(buf, "%d\n", emp->blink_policy); + } + ++static void ahci_port_clear_pending_irq(struct ata_port *ap) ++{ ++ struct ahci_host_priv *hpriv = ap->host->private_data; ++ void __iomem *port_mmio = ahci_port_base(ap); ++ u32 tmp; ++ ++ /* clear SError */ ++ tmp = readl(port_mmio + PORT_SCR_ERR); ++ dev_dbg(ap->host->dev, "PORT_SCR_ERR 0x%x\n", tmp); ++ writel(tmp, port_mmio + PORT_SCR_ERR); ++ ++ /* clear port IRQ */ ++ tmp = readl(port_mmio + PORT_IRQ_STAT); ++ dev_dbg(ap->host->dev, "PORT_IRQ_STAT 0x%x\n", tmp); ++ if (tmp) ++ writel(tmp, port_mmio + PORT_IRQ_STAT); ++ ++ writel(1 << ap->port_no, hpriv->mmio + HOST_IRQ_STAT); ++} ++ + static void ahci_port_init(struct device *dev, struct ata_port *ap, + int port_no, void __iomem *mmio, + void __iomem *port_mmio) +@@ -1214,18 +1234,7 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap, + if (rc) + dev_warn(dev, "%s (%d)\n", emsg, rc); + +- /* clear SError */ +- tmp = readl(port_mmio + PORT_SCR_ERR); +- VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); +- writel(tmp, port_mmio + PORT_SCR_ERR); +- +- /* clear port IRQ */ +- tmp = readl(port_mmio + PORT_IRQ_STAT); +- VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); +- if (tmp) +- writel(tmp, port_mmio + PORT_IRQ_STAT); +- +- writel(1 << port_no, mmio + HOST_IRQ_STAT); ++ ahci_port_clear_pending_irq(ap); + + /* mark esata ports */ + tmp = readl(port_mmio + PORT_CMD); +@@ -1252,10 +1261,10 @@ void ahci_init_controller(struct ata_host *host) + } + + tmp = readl(mmio + HOST_CTL); +- VPRINTK("HOST_CTL 0x%x\n", tmp); ++ dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp); + writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); + tmp = readl(mmio + HOST_CTL); +- VPRINTK("HOST_CTL 0x%x\n", tmp); ++ dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp); + } + EXPORT_SYMBOL_GPL(ahci_init_controller); + +@@ -1555,6 +1564,8 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class, + tf.status = ATA_BUSY; + ata_tf_to_fis(&tf, 0, 0, d2h_fis); + ++ ahci_port_clear_pending_irq(ap); ++ + rc = sata_link_hardreset(link, timing, deadline, online, + ahci_check_ready); + +@@ -1906,8 +1917,6 @@ static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance) + void __iomem *port_mmio = ahci_port_base(ap); + u32 status; + +- VPRINTK("ENTER\n"); +- + status = readl(port_mmio + PORT_IRQ_STAT); + writel(status, port_mmio + PORT_IRQ_STAT); + +@@ -1915,8 +1924,6 @@ static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance) + ahci_handle_port_interrupt(ap, port_mmio, status); + spin_unlock(ap->lock); + +- VPRINTK("EXIT\n"); +- + return IRQ_HANDLED; + } + +@@ -1933,9 +1940,7 @@ u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked) + ap = host->ports[i]; + if (ap) { + ahci_port_intr(ap); +- VPRINTK("port %u\n", i); + } else { +- VPRINTK("port %u (no irq)\n", i); + if (ata_ratelimit()) + dev_warn(host->dev, + "interrupt on disabled port %u\n", i); +@@ -1956,8 +1961,6 @@ static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance) + void __iomem *mmio; + u32 irq_stat, irq_masked; + +- VPRINTK("ENTER\n"); +- + hpriv = host->private_data; + mmio = hpriv->mmio; + +@@ -1985,8 +1988,6 @@ static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance) + + spin_unlock(&host->lock); + +- VPRINTK("EXIT\n"); +- + return IRQ_RETVAL(rc); + } + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 025260b80a94c..96786d6fcf37b 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -4999,17 +4999,19 @@ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, + struct ata_link *link; + unsigned long flags; + +- /* Previous resume operation might still be in +- * progress. Wait for PM_PENDING to clear. ++ spin_lock_irqsave(ap->lock, flags); ++ ++ /* ++ * A previous PM operation might still be in progress. Wait for ++ * ATA_PFLAG_PM_PENDING to clear. + */ + if (ap->pflags & ATA_PFLAG_PM_PENDING) { ++ spin_unlock_irqrestore(ap->lock, flags); + ata_port_wait_eh(ap); +- WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); ++ spin_lock_irqsave(ap->lock, flags); + } + +- /* request PM ops to EH */ +- spin_lock_irqsave(ap->lock, flags); +- ++ /* Request PM operation to EH */ + ap->pm_mesg = mesg; + ap->pflags |= ATA_PFLAG_PM_PENDING; + ata_for_each_link(link, ap, HOST_FIRST) { +@@ -5021,10 +5023,8 @@ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, + + spin_unlock_irqrestore(ap->lock, flags); + +- if (!async) { ++ if (!async) + ata_port_wait_eh(ap); +- WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); +- } + } + + /* +@@ -5192,7 +5192,7 @@ EXPORT_SYMBOL_GPL(ata_host_resume); + #endif + + const struct device_type ata_port_type = { +- .name = "ata_port", ++ .name = ATA_PORT_TYPE_NAME, + #ifdef CONFIG_PM + .pm = &ata_port_pm_ops, + #endif +@@ -5940,11 +5940,30 @@ static void ata_port_detach(struct ata_port *ap) + if (!ap->ops->error_handler) + goto skip_eh; + +- /* tell EH we're leaving & flush EH */ ++ /* Wait for any ongoing EH */ ++ ata_port_wait_eh(ap); ++ ++ mutex_lock(&ap->scsi_scan_mutex); + spin_lock_irqsave(ap->lock, flags); ++ ++ /* Remove scsi devices */ ++ ata_for_each_link(link, ap, HOST_FIRST) { ++ ata_for_each_dev(dev, link, ALL) { ++ if (dev->sdev) { ++ spin_unlock_irqrestore(ap->lock, flags); ++ scsi_remove_device(dev->sdev); ++ spin_lock_irqsave(ap->lock, flags); ++ dev->sdev = NULL; ++ } ++ } ++ } ++ ++ /* Tell EH to disable all devices */ + ap->pflags |= ATA_PFLAG_UNLOADING; + ata_port_schedule_eh(ap); ++ + spin_unlock_irqrestore(ap->lock, flags); ++ mutex_unlock(&ap->scsi_scan_mutex); + + /* wait till EH commits suicide */ + ata_port_wait_eh(ap); +diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c +index 8350abc172908..8444832008703 100644 +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2703,18 +2703,11 @@ int ata_eh_reset(struct ata_link *link, int classify, + postreset(slave, classes); + } + +- /* +- * Some controllers can't be frozen very well and may set spurious +- * error conditions during reset. Clear accumulated error +- * information and re-thaw the port if frozen. As reset is the +- * final recovery action and we cross check link onlineness against +- * device classification later, no hotplug event is lost by this. +- */ ++ /* clear cached SError */ + spin_lock_irqsave(link->ap->lock, flags); +- memset(&link->eh_info, 0, sizeof(link->eh_info)); ++ link->eh_info.serror = 0; + if (slave) +- memset(&slave->eh_info, 0, sizeof(link->eh_info)); +- ap->pflags &= ~ATA_PFLAG_EH_PENDING; ++ slave->eh_info.serror = 0; + spin_unlock_irqrestore(link->ap->lock, flags); + + if (ap->pflags & ATA_PFLAG_FROZEN) +diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c +index cb9395a3ad8e8..04bdd53abf20b 100644 +--- a/drivers/ata/libata-sata.c ++++ b/drivers/ata/libata-sata.c +@@ -317,7 +317,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, + * immediately after resuming. Delay 200ms before + * debouncing. + */ +- if (!(link->flags & ATA_LFLAG_NO_DB_DELAY)) ++ if (!(link->flags & ATA_LFLAG_NO_DEBOUNCE_DELAY)) + ata_msleep(link->ap, 200); + + /* is SControl restored correctly? */ +diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c +index fd9c768f31efe..9d0596dabfb9f 100644 +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -4214,7 +4214,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) + break; + + case MAINTENANCE_IN: +- if (scsicmd[1] == MI_REPORT_SUPPORTED_OPERATION_CODES) ++ if ((scsicmd[1] & 0x1f) == MI_REPORT_SUPPORTED_OPERATION_CODES) + ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in); + else + ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); +diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c +index 60f22e1a4943f..e180f63a035e2 100644 +--- a/drivers/ata/libata-transport.c ++++ b/drivers/ata/libata-transport.c +@@ -266,6 +266,10 @@ void ata_tport_delete(struct ata_port *ap) + put_device(dev); + } + ++static const struct device_type ata_port_sas_type = { ++ .name = ATA_PORT_TYPE_NAME, ++}; ++ + /** ata_tport_add - initialize a transport ATA port structure + * + * @parent: parent device +@@ -283,7 +287,10 @@ int ata_tport_add(struct device *parent, + struct device *dev = &ap->tdev; + + device_initialize(dev); +- dev->type = &ata_port_type; ++ if (ap->flags & ATA_FLAG_SAS_HOST) ++ dev->type = &ata_port_sas_type; ++ else ++ dev->type = &ata_port_type; + + dev->parent = parent; + ata_host_get(ap->host); +diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h +index 68cdd81d747c5..bf71bd9e66cd8 100644 +--- a/drivers/ata/libata.h ++++ b/drivers/ata/libata.h +@@ -30,6 +30,8 @@ enum { + ATA_DNXFER_QUIET = (1 << 31), + }; + ++#define ATA_PORT_TYPE_NAME "ata_port" ++ + extern atomic_t ata_print_id; + extern int atapi_passthru16; + extern int libata_fua; +diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c +index 74ab6cf031ce0..0a159989c899a 100644 +--- a/drivers/bus/ti-sysc.c ++++ b/drivers/bus/ti-sysc.c +@@ -38,6 +38,7 @@ enum sysc_soc { + SOC_2420, + SOC_2430, + SOC_3430, ++ SOC_AM35, + SOC_3630, + SOC_4430, + SOC_4460, +@@ -1117,6 +1118,11 @@ static int sysc_enable_module(struct device *dev) + if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE | + SYSC_QUIRK_SWSUP_SIDLE_ACT)) { + best_mode = SYSC_IDLE_NO; ++ ++ /* Clear WAKEUP */ ++ if (regbits->enwkup_shift >= 0 && ++ ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) ++ reg &= ~BIT(regbits->enwkup_shift); + } else { + best_mode = fls(ddata->cfg.sidlemodes) - 1; + if (best_mode > SYSC_IDLE_MASK) { +@@ -1237,6 +1243,13 @@ set_sidle: + } + } + ++ if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE_ACT) { ++ /* Set WAKEUP */ ++ if (regbits->enwkup_shift >= 0 && ++ ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) ++ reg |= BIT(regbits->enwkup_shift); ++ } ++ + reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); + reg |= best_mode << regbits->sidle_shift; + if (regbits->autoidle_shift >= 0 && +@@ -1496,16 +1509,16 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { + SYSC_QUIRK("sham", 0, 0x100, 0x110, 0x114, 0x40000c03, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, +- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), ++ SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, +- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), ++ SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), + /* Uarts on omap4 and later */ + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, +- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), ++ SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, +- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), ++ SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff, +- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), ++ SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), + + /* Quirks that need to be set based on the module address */ + SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, +@@ -1829,7 +1842,7 @@ static void sysc_pre_reset_quirk_dss(struct sysc *ddata) + dev_warn(ddata->dev, "%s: timed out %08x !+ %08x\n", + __func__, val, irq_mask); + +- if (sysc_soc->soc == SOC_3430) { ++ if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) { + /* Clear DSS_SDI_CONTROL */ + sysc_write(ddata, 0x44, 0); + +@@ -2096,8 +2109,7 @@ static int sysc_reset(struct sysc *ddata) + } + + if (ddata->cfg.srst_udelay) +- usleep_range(ddata->cfg.srst_udelay, +- ddata->cfg.srst_udelay * 2); ++ fsleep(ddata->cfg.srst_udelay); + + if (ddata->post_reset_quirk) + ddata->post_reset_quirk(ddata); +@@ -2973,6 +2985,7 @@ static void ti_sysc_idle(struct work_struct *work) + static const struct soc_device_attribute sysc_soc_match[] = { + SOC_FLAG("OMAP242*", SOC_2420), + SOC_FLAG("OMAP243*", SOC_2430), ++ SOC_FLAG("AM35*", SOC_AM35), + SOC_FLAG("OMAP3[45]*", SOC_3430), + SOC_FLAG("OMAP3[67]*", SOC_3630), + SOC_FLAG("OMAP443*", SOC_4430), +@@ -3179,7 +3192,7 @@ static int sysc_check_active_timer(struct sysc *ddata) + * can be dropped if we stop supporting old beagleboard revisions + * A to B4 at some point. + */ +- if (sysc_soc->soc == SOC_3430) ++ if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) + error = -ENXIO; + else + error = -EBUSY; +diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c +index 514f9f287a781..c6f181702b9a7 100644 +--- a/drivers/char/agp/parisc-agp.c ++++ b/drivers/char/agp/parisc-agp.c +@@ -394,8 +394,6 @@ find_quicksilver(struct device *dev, void *data) + static int __init + parisc_agp_init(void) + { +- extern struct sba_device *sba_list; +- + int err = -1; + struct parisc_device *sba = NULL, *lba = NULL; + struct lba_device *lbadev = NULL; +diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c +index 6ecf18f71c329..f6721f1d40885 100644 +--- a/drivers/clk/tegra/clk-bpmp.c ++++ b/drivers/clk/tegra/clk-bpmp.c +@@ -159,7 +159,7 @@ static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw, + + err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); + if (err < 0) +- return err; ++ return 0; + + return response.rate; + } +diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c +index a6c06d7476c32..1f410809d3ee4 100644 +--- a/drivers/firmware/imx/imx-dsp.c ++++ b/drivers/firmware/imx/imx-dsp.c +@@ -115,6 +115,7 @@ static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc) + dsp_chan->idx = i % 2; + dsp_chan->ch = mbox_request_channel_byname(cl, chan_name); + if (IS_ERR(dsp_chan->ch)) { ++ kfree(dsp_chan->name); + ret = PTR_ERR(dsp_chan->ch); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to request mbox chan %s ret %d\n", +diff --git a/drivers/gpio/gpio-pmic-eic-sprd.c b/drivers/gpio/gpio-pmic-eic-sprd.c +index 9382851905662..e969ce9131ddf 100644 +--- a/drivers/gpio/gpio-pmic-eic-sprd.c ++++ b/drivers/gpio/gpio-pmic-eic-sprd.c +@@ -338,6 +338,7 @@ static int sprd_pmic_eic_probe(struct platform_device *pdev) + pmic_eic->chip.set_config = sprd_pmic_eic_set_config; + pmic_eic->chip.set = sprd_pmic_eic_set; + pmic_eic->chip.get = sprd_pmic_eic_get; ++ pmic_eic->chip.can_sleep = true; + + pmic_eic->intc.name = dev_name(&pdev->dev); + pmic_eic->intc.irq_mask = sprd_pmic_eic_irq_mask; +diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c +index de6afa3f97168..05357473d2a11 100644 +--- a/drivers/gpio/gpio-tb10x.c ++++ b/drivers/gpio/gpio-tb10x.c +@@ -195,7 +195,7 @@ static int tb10x_gpio_probe(struct platform_device *pdev) + handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, + IRQ_GC_INIT_MASK_CACHE); + if (ret) +- return ret; ++ goto err_remove_domain; + + gc = tb10x_gpio->domain->gc->gc[0]; + gc->reg_base = tb10x_gpio->base; +@@ -209,6 +209,10 @@ static int tb10x_gpio_probe(struct platform_device *pdev) + } + + return 0; ++ ++err_remove_domain: ++ irq_domain_remove(tb10x_gpio->domain); ++ return ret; + } + + static int tb10x_gpio_remove(struct platform_device *pdev) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +index e8485b1f02ed6..70d49b998ee9e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +@@ -926,12 +926,17 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) + struct atom_context *atom_context; + + atom_context = adev->mode_info.atom_context; +- memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name)); +- memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn)); +- vbios_info.version = atom_context->version; +- memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str, +- sizeof(atom_context->vbios_ver_str)); +- memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date)); ++ if (atom_context) { ++ memcpy(vbios_info.name, atom_context->name, ++ sizeof(atom_context->name)); ++ memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, ++ sizeof(atom_context->vbios_pn)); ++ vbios_info.version = atom_context->version; ++ memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str, ++ sizeof(atom_context->vbios_ver_str)); ++ memcpy(vbios_info.date, atom_context->date, ++ sizeof(atom_context->date)); ++ } + + return copy_to_user(out, &vbios_info, + min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0; +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index 52142d272c868..87825818d43ec 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -980,7 +980,9 @@ void dce110_edp_backlight_control( + return; + } + +- if (link->panel_cntl) { ++ if (link->panel_cntl && !(link->dpcd_sink_ext_caps.bits.oled || ++ link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || ++ link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) { + bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl); + + if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) { +diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c +index b3cb910b30852..f96c0a89854b8 100644 +--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c ++++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c +@@ -272,7 +272,9 @@ static int sn65dsi83_attach(struct drm_bridge *bridge, + + dsi->lanes = ctx->dsi_lanes; + dsi->format = MIPI_DSI_FMT_RGB888; +- dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; ++ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | ++ MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | ++ MIPI_DSI_MODE_VIDEO_NO_HSA | MIPI_DSI_MODE_NO_EOT_PACKET; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { +diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c +index a7692584487cc..b075c9bc3a500 100644 +--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c ++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c +@@ -326,6 +326,8 @@ static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge, + return; + + cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid); ++ ++ kfree(edid); + } else + cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier); + } +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index 74d343d1a36b8..656e2acf3cd9a 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -1861,6 +1861,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) + "SMBus I801 adapter at %04lx", priv->smba); + err = i2c_add_adapter(&priv->adapter); + if (err) { ++ platform_device_unregister(priv->tco_pdev); + i801_acpi_remove(priv); + return err; + } +diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c +index c1b6797372409..73c808ef1bfe5 100644 +--- a/drivers/i2c/busses/i2c-npcm7xx.c ++++ b/drivers/i2c/busses/i2c-npcm7xx.c +@@ -675,6 +675,7 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, + { + struct i2c_msg *msgs; + int msgs_num; ++ bool do_complete = false; + + msgs = bus->msgs; + msgs_num = bus->msgs_num; +@@ -701,23 +702,17 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, + msgs[1].flags & I2C_M_RD) + msgs[1].len = info; + } +- if (completion_done(&bus->cmd_complete) == false) +- complete(&bus->cmd_complete); +- break; +- ++ do_complete = true; ++ break; + case I2C_NACK_IND: + /* MASTER transmit got a NACK before tx all bytes */ + bus->cmd_err = -ENXIO; +- if (bus->master_or_slave == I2C_MASTER) +- complete(&bus->cmd_complete); +- ++ do_complete = true; + break; + case I2C_BUS_ERR_IND: + /* Bus error */ + bus->cmd_err = -EAGAIN; +- if (bus->master_or_slave == I2C_MASTER) +- complete(&bus->cmd_complete); +- ++ do_complete = true; + break; + case I2C_WAKE_UP_IND: + /* I2C wake up */ +@@ -731,6 +726,8 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, + if (bus->slave) + bus->master_or_slave = I2C_SLAVE; + #endif ++ if (do_complete) ++ complete(&bus->cmd_complete); + } + + static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus) +diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c +index f7a7405d4350a..8e8688e8de0fb 100644 +--- a/drivers/i2c/muxes/i2c-demux-pinctrl.c ++++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c +@@ -243,6 +243,10 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) + + props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL); + props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL); ++ if (!props[i].name || !props[i].value) { ++ err = -ENOMEM; ++ goto err_rollback; ++ } + props[i].length = 3; + + of_changeset_init(&priv->chan[i].chgset); +diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c +index bac415a52b780..8bad785dce36f 100644 +--- a/drivers/i2c/muxes/i2c-mux-gpio.c ++++ b/drivers/i2c/muxes/i2c-mux-gpio.c +@@ -49,45 +49,6 @@ static int i2c_mux_gpio_deselect(struct i2c_mux_core *muxc, u32 chan) + return 0; + } + +-#ifdef CONFIG_ACPI +- +-static int i2c_mux_gpio_get_acpi_adr(struct device *dev, +- struct fwnode_handle *fwdev, +- unsigned int *adr) +- +-{ +- unsigned long long adr64; +- acpi_status status; +- +- status = acpi_evaluate_integer(ACPI_HANDLE_FWNODE(fwdev), +- METHOD_NAME__ADR, +- NULL, &adr64); +- +- if (!ACPI_SUCCESS(status)) { +- dev_err(dev, "Cannot get address\n"); +- return -EINVAL; +- } +- +- *adr = adr64; +- if (*adr != adr64) { +- dev_err(dev, "Address out of range\n"); +- return -ERANGE; +- } +- +- return 0; +-} +- +-#else +- +-static int i2c_mux_gpio_get_acpi_adr(struct device *dev, +- struct fwnode_handle *fwdev, +- unsigned int *adr) +-{ +- return -EINVAL; +-} +- +-#endif +- + static int i2c_mux_gpio_probe_fw(struct gpiomux *mux, + struct platform_device *pdev) + { +@@ -141,9 +102,11 @@ static int i2c_mux_gpio_probe_fw(struct gpiomux *mux, + fwnode_property_read_u32(child, "reg", values + i); + + } else if (is_acpi_node(child)) { +- rc = i2c_mux_gpio_get_acpi_adr(dev, child, values + i); +- if (rc) +- return rc; ++ rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i); ++ if (rc) { ++ fwnode_handle_put(child); ++ return dev_err_probe(dev, rc, "Cannot get address\n"); ++ } + } + + i++; +diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h +new file mode 100644 +index 0000000000000..a0d8528685fe3 +--- /dev/null ++++ b/drivers/input/serio/i8042-acpipnpio.h +@@ -0,0 +1,1657 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++#ifndef _I8042_ACPIPNPIO_H ++#define _I8042_ACPIPNPIO_H ++ ++ ++#ifdef CONFIG_X86 ++#include <asm/x86_init.h> ++#endif ++ ++/* ++ * Names. ++ */ ++ ++#define I8042_KBD_PHYS_DESC "isa0060/serio0" ++#define I8042_AUX_PHYS_DESC "isa0060/serio1" ++#define I8042_MUX_PHYS_DESC "isa0060/serio%d" ++ ++/* ++ * IRQs. ++ */ ++ ++#if defined(__ia64__) ++# define I8042_MAP_IRQ(x) isa_irq_to_vector((x)) ++#else ++# define I8042_MAP_IRQ(x) (x) ++#endif ++ ++#define I8042_KBD_IRQ i8042_kbd_irq ++#define I8042_AUX_IRQ i8042_aux_irq ++ ++static int i8042_kbd_irq; ++static int i8042_aux_irq; ++ ++/* ++ * Register numbers. ++ */ ++ ++#define I8042_COMMAND_REG i8042_command_reg ++#define I8042_STATUS_REG i8042_command_reg ++#define I8042_DATA_REG i8042_data_reg ++ ++static int i8042_command_reg = 0x64; ++static int i8042_data_reg = 0x60; ++ ++ ++static inline int i8042_read_data(void) ++{ ++ return inb(I8042_DATA_REG); ++} ++ ++static inline int i8042_read_status(void) ++{ ++ return inb(I8042_STATUS_REG); ++} ++ ++static inline void i8042_write_data(int val) ++{ ++ outb(val, I8042_DATA_REG); ++} ++ ++static inline void i8042_write_command(int val) ++{ ++ outb(val, I8042_COMMAND_REG); ++} ++ ++#ifdef CONFIG_X86 ++ ++#include <linux/dmi.h> ++ ++#define SERIO_QUIRK_NOKBD BIT(0) ++#define SERIO_QUIRK_NOAUX BIT(1) ++#define SERIO_QUIRK_NOMUX BIT(2) ++#define SERIO_QUIRK_FORCEMUX BIT(3) ++#define SERIO_QUIRK_UNLOCK BIT(4) ++#define SERIO_QUIRK_PROBE_DEFER BIT(5) ++#define SERIO_QUIRK_RESET_ALWAYS BIT(6) ++#define SERIO_QUIRK_RESET_NEVER BIT(7) ++#define SERIO_QUIRK_DIECT BIT(8) ++#define SERIO_QUIRK_DUMBKBD BIT(9) ++#define SERIO_QUIRK_NOLOOP BIT(10) ++#define SERIO_QUIRK_NOTIMEOUT BIT(11) ++#define SERIO_QUIRK_KBDRESET BIT(12) ++#define SERIO_QUIRK_DRITEK BIT(13) ++#define SERIO_QUIRK_NOPNP BIT(14) ++ ++/* Quirk table for different mainboards. Options similar or identical to i8042 ++ * module parameters. ++ * ORDERING IS IMPORTANT! The first match will be apllied and the rest ignored. ++ * This allows entries to overwrite vendor wide quirks on a per device basis. ++ * Where this is irrelevant, entries are sorted case sensitive by DMI_SYS_VENDOR ++ * and/or DMI_BOARD_VENDOR to make it easier to avoid dublicate entries. ++ */ ++static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Asus X450LCP */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER) ++ }, ++ { ++ /* ASUS ZenBook UX425UA/QA */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) ++ }, ++ { ++ /* ASUS ZenBook UM325UA/QA */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) ++ }, ++ /* ++ * On some Asus laptops, just running self tests cause problems. ++ */ ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_NEVER) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /* Convertible Notebook */ ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_NEVER) ++ }, ++ { ++ /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), ++ DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"), ++ DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* ASUS G1S */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), ++ DMI_MATCH(DMI_BOARD_NAME, "G1S"), ++ DMI_MATCH(DMI_BOARD_VERSION, "1.0"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Acer Aspire 5710 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Acer Aspire 7738 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Acer Aspire 5536 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* ++ * Acer Aspire 5738z ++ * Touchpad stops working in mux mode when dis- + re-enabled ++ * with the touchpad enable/disable toggle hotkey ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Acer Aspire One 150 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A114-31"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A314-31"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-31"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-332"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-432"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate Spin B118-RN"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ /* ++ * Some Wistron based laptops need us to explicitly enable the 'Dritek ++ * keyboard extension' to make their extra keys start generating scancodes. ++ * Originally, this was just confined to older laptops, but a few Acer laptops ++ * have turned up in 2007 that also need this again. ++ */ ++ { ++ /* Acer Aspire 5100 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_DRITEK) ++ }, ++ { ++ /* Acer Aspire 5610 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_DRITEK) ++ }, ++ { ++ /* Acer Aspire 5630 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_DRITEK) ++ }, ++ { ++ /* Acer Aspire 5650 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_DRITEK) ++ }, ++ { ++ /* Acer Aspire 5680 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_DRITEK) ++ }, ++ { ++ /* Acer Aspire 5720 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_DRITEK) ++ }, ++ { ++ /* Acer Aspire 9110 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_DRITEK) ++ }, ++ { ++ /* Acer TravelMate 660 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_DRITEK) ++ }, ++ { ++ /* Acer TravelMate 2490 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_DRITEK) ++ }, ++ { ++ /* Acer TravelMate 4280 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_DRITEK) ++ }, ++ { ++ /* Amoi M636/A737 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Compal HEL80I */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "8500"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Advent 4211 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ /* Dell Embedded Box PC 3000 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Dell XPS M1530 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Dell Vostro 1510 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Dell Vostro V13 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) ++ }, ++ { ++ /* Dell Vostro 1320 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ /* Dell Vostro 1520 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ /* Dell Vostro 1720 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ /* Entroware Proteus */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Entroware"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Proteus"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "EL07R4"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ /* ++ * Some Fujitsu notebooks are having trouble with touchpads if ++ * active multiplexing mode is activated. Luckily they don't have ++ * external PS/2 ports so we can safely disable it. ++ * ... apparently some Toshibas don't like MUX mode either and ++ * die horrible death on reboot. ++ */ ++ { ++ /* Fujitsu Lifebook P7010/P7010D */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu Lifebook P5020D */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu Lifebook S2000 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu Lifebook S6230 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu Lifebook T725 laptop */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) ++ }, ++ { ++ /* Fujitsu Lifebook U745 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu T70H */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu A544 laptop */ ++ /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) ++ }, ++ { ++ /* Fujitsu AH544 laptop */ ++ /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) ++ }, ++ { ++ /* Fujitsu U574 laptop */ ++ /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) ++ }, ++ { ++ /* Fujitsu UH554 laptop */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) ++ }, ++ { ++ /* Fujitsu Lifebook P7010 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu-Siemens Lifebook T3010 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu-Siemens Lifebook E4010 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu-Siemens Amilo Pro 2010 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu-Siemens Amilo Pro 2030 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Fujitsu Lifebook A574/H */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "FMVA0501PZ"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Gigabyte M912 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "M912"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "01"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Gigabyte Spring Peak - defines wrong chassis type */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Gigabyte T1005 - defines wrong chassis type ("Other") */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "T1005"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ /* ++ * Some laptops need keyboard reset before probing for the trackpad to get ++ * it detected, initialised & finally work. ++ */ ++ { ++ /* Gigabyte P35 v2 - Elantech touchpad */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_KBDRESET) ++ }, ++ { ++ /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X3"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_KBDRESET) ++ }, ++ { ++ /* Gigabyte P34 - Elantech touchpad */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "P34"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_KBDRESET) ++ }, ++ { ++ /* Gigabyte P57 - Elantech touchpad */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "P57"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_KBDRESET) ++ }, ++ { ++ /* Gericom Bellagio */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Gigabyte M1022M netbook */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."), ++ DMI_MATCH(DMI_BOARD_NAME, "M1022E"), ++ DMI_MATCH(DMI_BOARD_VERSION, "1.02"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* ++ * HP Pavilion DV4017EA - ++ * errors on MUX ports are reported without raising AUXDATA ++ * causing "spurious NAK" messages. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* ++ * HP Pavilion ZT1000 - ++ * like DV4017EA does not raise AUXERR for errors on MUX ports. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* ++ * HP Pavilion DV4270ca - ++ * like DV4017EA does not raise AUXERR for errors on MUX ports. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Newer HP Pavilion dv4 models */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) ++ }, ++ { ++ /* IBM 2656 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "IBM"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "2656"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Avatar AVIU-145A6 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Intel"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Intel MBO Desktop D845PESV */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), ++ DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* ++ * Intel NUC D54250WYK - does not have i8042 controller but ++ * declares PS/2 devices in DSDT. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), ++ DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* Lenovo 3000 n100 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Lenovo XiaoXin Air 12 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "80UN"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Lenovo LaVie Z */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Lenovo Ideapad U455 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "20046"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ /* Lenovo ThinkPad L460 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ /* Lenovo ThinkPad Twist S230u */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ /* LG Electronics X110 */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), ++ DMI_MATCH(DMI_BOARD_NAME, "X110"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ /* Medion Akoya Mini E1210 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ /* Medion Akoya E1222 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ { ++ /* MSI Wind U-100 */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), ++ DMI_MATCH(DMI_BOARD_NAME, "U-100"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* ++ * No data is coming from the touchscreen unless KBC ++ * is in legacy mode. ++ */ ++ /* Panasonic CF-29 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Medion Akoya E7225 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Medion"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Microsoft Virtual Machine */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Medion MAM 2070 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* TUXEDO BU1406 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* OQO Model 01 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "OQO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "00"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C15B"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Acer Aspire 5 A515 */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "PK"), ++ DMI_MATCH(DMI_BOARD_NAME, "Grumpy_PK"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* ULI EV4873 - AUX LOOP does not work properly */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ULI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* ++ * Arima-Rioworks HDAMB - ++ * AUX LOOP command does not raise AUX IRQ ++ */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"), ++ DMI_MATCH(DMI_BOARD_NAME, "HDAMB"), ++ DMI_MATCH(DMI_BOARD_VERSION, "Rev E"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ { ++ /* Sharp Actius MM20 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* ++ * Sony Vaio FZ-240E - ++ * reset and GET ID commands issued via KBD port are ++ * sometimes being delivered to AUX3. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* ++ * Most (all?) VAIOs do not have external PS/2 ports nor ++ * they implement active multiplexing properly, and ++ * MUX discovery usually messes up keyboard/touchpad. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), ++ DMI_MATCH(DMI_BOARD_NAME, "VAIO"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* Sony Vaio FS-115b */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ /* ++ * Sony Vaio VGN-CS series require MUX or the touch sensor ++ * buttons will disturb touchpad operation ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_FORCEMUX) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX) ++ }, ++ /* ++ * A lot of modern Clevo barebones have touchpad and/or keyboard issues ++ * after suspend fixable with nomux + reset + noloop + nopnp. Luckily, ++ * none of them have an external PS/2 port so this can safely be set for ++ * all of them. These two are based on a Clevo design, but have the ++ * board_name changed. ++ */ ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"), ++ DMI_MATCH(DMI_BOARD_NAME, "AURA1501"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"), ++ DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* Mivvy M310 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "N10"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) ++ }, ++ /* ++ * Some laptops need keyboard reset before probing for the trackpad to get ++ * it detected, initialised & finally work. ++ */ ++ { ++ /* Schenker XMG C504 - Elantech touchpad */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "XMG"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C504"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_KBDRESET) ++ }, ++ { ++ /* Blue FB5601 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "blue"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "M606"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) ++ }, ++ /* ++ * A lot of modern Clevo barebones have touchpad and/or keyboard issues ++ * after suspend fixable with nomux + reset + noloop + nopnp. Luckily, ++ * none of them have an external PS/2 port so this can safely be set for ++ * all of them. ++ * Clevo barebones come with board_vendor and/or system_vendor set to ++ * either the very generic string "Notebook" and/or a different value ++ * for each individual reseller. The only somewhat universal way to ++ * identify them is by board_name. ++ */ ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "LAPQC71A"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "LAPQC71B"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "N140CU"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "N141CU"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ /* ++ * At least one modern Clevo barebone has the touchpad connected both ++ * via PS/2 and i2c interface. This causes a race condition between the ++ * psmouse and i2c-hid driver. Since the full capability of the touchpad ++ * is available via the i2c interface and the device has no external ++ * PS/2 port, it is safe to just ignore all ps2 mouses here to avoid ++ * this issue. The known affected device is the ++ * TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU which comes with one of ++ * the two different dmi strings below. NS50MU is not a typo! ++ */ ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "NS50MU"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX | ++ SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | ++ SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "NS50_70MU"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX | ++ SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | ++ SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* ++ * This is only a partial board_name and might be followed by ++ * another letter or number. DMI_MATCH however does do partial ++ * matching. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_NAME, "P65xH"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */ ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* ++ * This is only a partial board_name and might be followed by ++ * another letter or number. DMI_MATCH however does do partial ++ * matching. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_NAME, "P65_P67H"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* ++ * This is only a partial board_name and might be followed by ++ * another letter or number. DMI_MATCH however does do partial ++ * matching. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_NAME, "P65_67RP"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* ++ * This is only a partial board_name and might be followed by ++ * another letter or number. DMI_MATCH however does do partial ++ * matching. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_NAME, "P65_67RS"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ /* ++ * This is only a partial board_name and might be followed by ++ * another letter or number. DMI_MATCH however does do partial ++ * matching. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_NAME, "P67xRP"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "PB50_70DFx,DDx"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "PCX0DX"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ /* See comment on TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU above */ ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "PD5x_7xPNP_PNR_PNN_PNT"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOAUX) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "X170SM"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "X170KM-G"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | ++ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) ++ }, ++ { } ++}; ++ ++#ifdef CONFIG_PNP ++static const struct dmi_system_id i8042_dmi_laptop_table[] __initconst = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ ++ }, ++ }, ++ { } ++}; ++#endif ++ ++#endif /* CONFIG_X86 */ ++ ++#ifdef CONFIG_PNP ++#include <linux/pnp.h> ++ ++static bool i8042_pnp_kbd_registered; ++static unsigned int i8042_pnp_kbd_devices; ++static bool i8042_pnp_aux_registered; ++static unsigned int i8042_pnp_aux_devices; ++ ++static int i8042_pnp_command_reg; ++static int i8042_pnp_data_reg; ++static int i8042_pnp_kbd_irq; ++static int i8042_pnp_aux_irq; ++ ++static char i8042_pnp_kbd_name[32]; ++static char i8042_pnp_aux_name[32]; ++ ++static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size) ++{ ++ strlcpy(dst, "PNP:", dst_size); ++ ++ while (id) { ++ strlcat(dst, " ", dst_size); ++ strlcat(dst, id->id, dst_size); ++ id = id->next; ++ } ++} ++ ++static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did) ++{ ++ if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) ++ i8042_pnp_data_reg = pnp_port_start(dev,0); ++ ++ if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1) ++ i8042_pnp_command_reg = pnp_port_start(dev, 1); ++ ++ if (pnp_irq_valid(dev,0)) ++ i8042_pnp_kbd_irq = pnp_irq(dev, 0); ++ ++ strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); ++ if (strlen(pnp_dev_name(dev))) { ++ strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); ++ strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); ++ } ++ i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id, ++ sizeof(i8042_kbd_firmware_id)); ++ i8042_kbd_fwnode = dev_fwnode(&dev->dev); ++ ++ /* Keyboard ports are always supposed to be wakeup-enabled */ ++ device_set_wakeup_enable(&dev->dev, true); ++ ++ i8042_pnp_kbd_devices++; ++ return 0; ++} ++ ++static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did) ++{ ++ if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) ++ i8042_pnp_data_reg = pnp_port_start(dev,0); ++ ++ if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1) ++ i8042_pnp_command_reg = pnp_port_start(dev, 1); ++ ++ if (pnp_irq_valid(dev, 0)) ++ i8042_pnp_aux_irq = pnp_irq(dev, 0); ++ ++ strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); ++ if (strlen(pnp_dev_name(dev))) { ++ strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); ++ strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); ++ } ++ i8042_pnp_id_to_string(dev->id, i8042_aux_firmware_id, ++ sizeof(i8042_aux_firmware_id)); ++ ++ i8042_pnp_aux_devices++; ++ return 0; ++} ++ ++static const struct pnp_device_id pnp_kbd_devids[] = { ++ { .id = "PNP0300", .driver_data = 0 }, ++ { .id = "PNP0301", .driver_data = 0 }, ++ { .id = "PNP0302", .driver_data = 0 }, ++ { .id = "PNP0303", .driver_data = 0 }, ++ { .id = "PNP0304", .driver_data = 0 }, ++ { .id = "PNP0305", .driver_data = 0 }, ++ { .id = "PNP0306", .driver_data = 0 }, ++ { .id = "PNP0309", .driver_data = 0 }, ++ { .id = "PNP030a", .driver_data = 0 }, ++ { .id = "PNP030b", .driver_data = 0 }, ++ { .id = "PNP0320", .driver_data = 0 }, ++ { .id = "PNP0343", .driver_data = 0 }, ++ { .id = "PNP0344", .driver_data = 0 }, ++ { .id = "PNP0345", .driver_data = 0 }, ++ { .id = "CPQA0D7", .driver_data = 0 }, ++ { .id = "", }, ++}; ++MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids); ++ ++static struct pnp_driver i8042_pnp_kbd_driver = { ++ .name = "i8042 kbd", ++ .id_table = pnp_kbd_devids, ++ .probe = i8042_pnp_kbd_probe, ++ .driver = { ++ .probe_type = PROBE_FORCE_SYNCHRONOUS, ++ .suppress_bind_attrs = true, ++ }, ++}; ++ ++static const struct pnp_device_id pnp_aux_devids[] = { ++ { .id = "AUI0200", .driver_data = 0 }, ++ { .id = "FJC6000", .driver_data = 0 }, ++ { .id = "FJC6001", .driver_data = 0 }, ++ { .id = "PNP0f03", .driver_data = 0 }, ++ { .id = "PNP0f0b", .driver_data = 0 }, ++ { .id = "PNP0f0e", .driver_data = 0 }, ++ { .id = "PNP0f12", .driver_data = 0 }, ++ { .id = "PNP0f13", .driver_data = 0 }, ++ { .id = "PNP0f19", .driver_data = 0 }, ++ { .id = "PNP0f1c", .driver_data = 0 }, ++ { .id = "SYN0801", .driver_data = 0 }, ++ { .id = "", }, ++}; ++MODULE_DEVICE_TABLE(pnp, pnp_aux_devids); ++ ++static struct pnp_driver i8042_pnp_aux_driver = { ++ .name = "i8042 aux", ++ .id_table = pnp_aux_devids, ++ .probe = i8042_pnp_aux_probe, ++ .driver = { ++ .probe_type = PROBE_FORCE_SYNCHRONOUS, ++ .suppress_bind_attrs = true, ++ }, ++}; ++ ++static void i8042_pnp_exit(void) ++{ ++ if (i8042_pnp_kbd_registered) { ++ i8042_pnp_kbd_registered = false; ++ pnp_unregister_driver(&i8042_pnp_kbd_driver); ++ } ++ ++ if (i8042_pnp_aux_registered) { ++ i8042_pnp_aux_registered = false; ++ pnp_unregister_driver(&i8042_pnp_aux_driver); ++ } ++} ++ ++static int __init i8042_pnp_init(void) ++{ ++ char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; ++ bool pnp_data_busted = false; ++ int err; ++ ++ if (i8042_nopnp) { ++ pr_info("PNP detection disabled\n"); ++ return 0; ++ } ++ ++ err = pnp_register_driver(&i8042_pnp_kbd_driver); ++ if (!err) ++ i8042_pnp_kbd_registered = true; ++ ++ err = pnp_register_driver(&i8042_pnp_aux_driver); ++ if (!err) ++ i8042_pnp_aux_registered = true; ++ ++ if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) { ++ i8042_pnp_exit(); ++#if defined(__ia64__) ++ return -ENODEV; ++#else ++ pr_info("PNP: No PS/2 controller found.\n"); ++ if (x86_platform.legacy.i8042 != ++ X86_LEGACY_I8042_EXPECTED_PRESENT) ++ return -ENODEV; ++ pr_info("Probing ports directly.\n"); ++ return 0; ++#endif ++ } ++ ++ if (i8042_pnp_kbd_devices) ++ snprintf(kbd_irq_str, sizeof(kbd_irq_str), ++ "%d", i8042_pnp_kbd_irq); ++ if (i8042_pnp_aux_devices) ++ snprintf(aux_irq_str, sizeof(aux_irq_str), ++ "%d", i8042_pnp_aux_irq); ++ ++ pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", ++ i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", ++ i8042_pnp_aux_name, ++ i8042_pnp_data_reg, i8042_pnp_command_reg, ++ kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", ++ aux_irq_str); ++ ++#if defined(__ia64__) ++ if (!i8042_pnp_kbd_devices) ++ i8042_nokbd = true; ++ if (!i8042_pnp_aux_devices) ++ i8042_noaux = true; ++#endif ++ ++ if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && ++ i8042_pnp_data_reg != i8042_data_reg) || ++ !i8042_pnp_data_reg) { ++ pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n", ++ i8042_pnp_data_reg, i8042_data_reg); ++ i8042_pnp_data_reg = i8042_data_reg; ++ pnp_data_busted = true; ++ } ++ ++ if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && ++ i8042_pnp_command_reg != i8042_command_reg) || ++ !i8042_pnp_command_reg) { ++ pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n", ++ i8042_pnp_command_reg, i8042_command_reg); ++ i8042_pnp_command_reg = i8042_command_reg; ++ pnp_data_busted = true; ++ } ++ ++ if (!i8042_nokbd && !i8042_pnp_kbd_irq) { ++ pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n", ++ i8042_kbd_irq); ++ i8042_pnp_kbd_irq = i8042_kbd_irq; ++ pnp_data_busted = true; ++ } ++ ++ if (!i8042_noaux && !i8042_pnp_aux_irq) { ++ if (!pnp_data_busted && i8042_pnp_kbd_irq) { ++ pr_warn("PNP: PS/2 appears to have AUX port disabled, " ++ "if this is incorrect please boot with i8042.nopnp\n"); ++ i8042_noaux = true; ++ } else { ++ pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n", ++ i8042_aux_irq); ++ i8042_pnp_aux_irq = i8042_aux_irq; ++ } ++ } ++ ++ i8042_data_reg = i8042_pnp_data_reg; ++ i8042_command_reg = i8042_pnp_command_reg; ++ i8042_kbd_irq = i8042_pnp_kbd_irq; ++ i8042_aux_irq = i8042_pnp_aux_irq; ++ ++#ifdef CONFIG_X86 ++ i8042_bypass_aux_irq_test = !pnp_data_busted && ++ dmi_check_system(i8042_dmi_laptop_table); ++#endif ++ ++ return 0; ++} ++ ++#else /* !CONFIG_PNP */ ++static inline int i8042_pnp_init(void) { return 0; } ++static inline void i8042_pnp_exit(void) { } ++#endif /* CONFIG_PNP */ ++ ++ ++#ifdef CONFIG_X86 ++static void __init i8042_check_quirks(void) ++{ ++ const struct dmi_system_id *device_quirk_info; ++ uintptr_t quirks; ++ ++ device_quirk_info = dmi_first_match(i8042_dmi_quirk_table); ++ if (!device_quirk_info) ++ return; ++ ++ quirks = (uintptr_t)device_quirk_info->driver_data; ++ ++ if (quirks & SERIO_QUIRK_NOKBD) ++ i8042_nokbd = true; ++ if (quirks & SERIO_QUIRK_NOAUX) ++ i8042_noaux = true; ++ if (quirks & SERIO_QUIRK_NOMUX) ++ i8042_nomux = true; ++ if (quirks & SERIO_QUIRK_FORCEMUX) ++ i8042_nomux = false; ++ if (quirks & SERIO_QUIRK_UNLOCK) ++ i8042_unlock = true; ++ if (quirks & SERIO_QUIRK_PROBE_DEFER) ++ i8042_probe_defer = true; ++ /* Honor module parameter when value is not default */ ++ if (i8042_reset == I8042_RESET_DEFAULT) { ++ if (quirks & SERIO_QUIRK_RESET_ALWAYS) ++ i8042_reset = I8042_RESET_ALWAYS; ++ if (quirks & SERIO_QUIRK_RESET_NEVER) ++ i8042_reset = I8042_RESET_NEVER; ++ } ++ if (quirks & SERIO_QUIRK_DIECT) ++ i8042_direct = true; ++ if (quirks & SERIO_QUIRK_DUMBKBD) ++ i8042_dumbkbd = true; ++ if (quirks & SERIO_QUIRK_NOLOOP) ++ i8042_noloop = true; ++ if (quirks & SERIO_QUIRK_NOTIMEOUT) ++ i8042_notimeout = true; ++ if (quirks & SERIO_QUIRK_KBDRESET) ++ i8042_kbdreset = true; ++ if (quirks & SERIO_QUIRK_DRITEK) ++ i8042_dritek = true; ++#ifdef CONFIG_PNP ++ if (quirks & SERIO_QUIRK_NOPNP) ++ i8042_nopnp = true; ++#endif ++} ++#else ++static inline void i8042_check_quirks(void) {} ++#endif ++ ++static int __init i8042_platform_init(void) ++{ ++ int retval; ++ ++#ifdef CONFIG_X86 ++ u8 a20_on = 0xdf; ++ /* Just return if platform does not have i8042 controller */ ++ if (x86_platform.legacy.i8042 == X86_LEGACY_I8042_PLATFORM_ABSENT) ++ return -ENODEV; ++#endif ++ ++/* ++ * On ix86 platforms touching the i8042 data register region can do really ++ * bad things. Because of this the region is always reserved on ix86 boxes. ++ * ++ * if (!request_region(I8042_DATA_REG, 16, "i8042")) ++ * return -EBUSY; ++ */ ++ ++ i8042_kbd_irq = I8042_MAP_IRQ(1); ++ i8042_aux_irq = I8042_MAP_IRQ(12); ++ ++#if defined(__ia64__) ++ i8042_reset = I8042_RESET_ALWAYS; ++#endif ++ ++ i8042_check_quirks(); ++ ++ retval = i8042_pnp_init(); ++ if (retval) ++ return retval; ++ ++#ifdef CONFIG_X86 ++ /* ++ * A20 was already enabled during early kernel init. But some buggy ++ * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to ++ * resume from S3. So we do it here and hope that nothing breaks. ++ */ ++ i8042_command(&a20_on, 0x10d1); ++ i8042_command(NULL, 0x00ff); /* Null command for SMM firmware */ ++#endif /* CONFIG_X86 */ ++ ++ return retval; ++} ++ ++static inline void i8042_platform_exit(void) ++{ ++ i8042_pnp_exit(); ++} ++ ++#endif /* _I8042_ACPIPNPIO_H */ +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +deleted file mode 100644 +index 339e765bcf5ae..0000000000000 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ /dev/null +@@ -1,1650 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-only */ +-#ifndef _I8042_X86IA64IO_H +-#define _I8042_X86IA64IO_H +- +- +-#ifdef CONFIG_X86 +-#include <asm/x86_init.h> +-#endif +- +-/* +- * Names. +- */ +- +-#define I8042_KBD_PHYS_DESC "isa0060/serio0" +-#define I8042_AUX_PHYS_DESC "isa0060/serio1" +-#define I8042_MUX_PHYS_DESC "isa0060/serio%d" +- +-/* +- * IRQs. +- */ +- +-#if defined(__ia64__) +-# define I8042_MAP_IRQ(x) isa_irq_to_vector((x)) +-#else +-# define I8042_MAP_IRQ(x) (x) +-#endif +- +-#define I8042_KBD_IRQ i8042_kbd_irq +-#define I8042_AUX_IRQ i8042_aux_irq +- +-static int i8042_kbd_irq; +-static int i8042_aux_irq; +- +-/* +- * Register numbers. +- */ +- +-#define I8042_COMMAND_REG i8042_command_reg +-#define I8042_STATUS_REG i8042_command_reg +-#define I8042_DATA_REG i8042_data_reg +- +-static int i8042_command_reg = 0x64; +-static int i8042_data_reg = 0x60; +- +- +-static inline int i8042_read_data(void) +-{ +- return inb(I8042_DATA_REG); +-} +- +-static inline int i8042_read_status(void) +-{ +- return inb(I8042_STATUS_REG); +-} +- +-static inline void i8042_write_data(int val) +-{ +- outb(val, I8042_DATA_REG); +-} +- +-static inline void i8042_write_command(int val) +-{ +- outb(val, I8042_COMMAND_REG); +-} +- +-#ifdef CONFIG_X86 +- +-#include <linux/dmi.h> +- +-#define SERIO_QUIRK_NOKBD BIT(0) +-#define SERIO_QUIRK_NOAUX BIT(1) +-#define SERIO_QUIRK_NOMUX BIT(2) +-#define SERIO_QUIRK_FORCEMUX BIT(3) +-#define SERIO_QUIRK_UNLOCK BIT(4) +-#define SERIO_QUIRK_PROBE_DEFER BIT(5) +-#define SERIO_QUIRK_RESET_ALWAYS BIT(6) +-#define SERIO_QUIRK_RESET_NEVER BIT(7) +-#define SERIO_QUIRK_DIECT BIT(8) +-#define SERIO_QUIRK_DUMBKBD BIT(9) +-#define SERIO_QUIRK_NOLOOP BIT(10) +-#define SERIO_QUIRK_NOTIMEOUT BIT(11) +-#define SERIO_QUIRK_KBDRESET BIT(12) +-#define SERIO_QUIRK_DRITEK BIT(13) +-#define SERIO_QUIRK_NOPNP BIT(14) +- +-/* Quirk table for different mainboards. Options similar or identical to i8042 +- * module parameters. +- * ORDERING IS IMPORTANT! The first match will be apllied and the rest ignored. +- * This allows entries to overwrite vendor wide quirks on a per device basis. +- * Where this is irrelevant, entries are sorted case sensitive by DMI_SYS_VENDOR +- * and/or DMI_BOARD_VENDOR to make it easier to avoid dublicate entries. +- */ +-static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Asus X450LCP */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER) +- }, +- { +- /* ASUS ZenBook UX425UA/QA */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) +- }, +- { +- /* ASUS ZenBook UM325UA/QA */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) +- }, +- /* +- * On some Asus laptops, just running self tests cause problems. +- */ +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_NEVER) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /* Convertible Notebook */ +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_NEVER) +- }, +- { +- /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */ +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), +- DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"), +- DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* ASUS G1S */ +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), +- DMI_MATCH(DMI_BOARD_NAME, "G1S"), +- DMI_MATCH(DMI_BOARD_VERSION, "1.0"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Acer Aspire 5710 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Acer Aspire 7738 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Acer Aspire 5536 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* +- * Acer Aspire 5738z +- * Touchpad stops working in mux mode when dis- + re-enabled +- * with the touchpad enable/disable toggle hotkey +- */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Acer Aspire One 150 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A114-31"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A314-31"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-31"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-332"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-432"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate Spin B118-RN"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- /* +- * Some Wistron based laptops need us to explicitly enable the 'Dritek +- * keyboard extension' to make their extra keys start generating scancodes. +- * Originally, this was just confined to older laptops, but a few Acer laptops +- * have turned up in 2007 that also need this again. +- */ +- { +- /* Acer Aspire 5100 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_DRITEK) +- }, +- { +- /* Acer Aspire 5610 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_DRITEK) +- }, +- { +- /* Acer Aspire 5630 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_DRITEK) +- }, +- { +- /* Acer Aspire 5650 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_DRITEK) +- }, +- { +- /* Acer Aspire 5680 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_DRITEK) +- }, +- { +- /* Acer Aspire 5720 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_DRITEK) +- }, +- { +- /* Acer Aspire 9110 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_DRITEK) +- }, +- { +- /* Acer TravelMate 660 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_DRITEK) +- }, +- { +- /* Acer TravelMate 2490 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_DRITEK) +- }, +- { +- /* Acer TravelMate 4280 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +- DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_DRITEK) +- }, +- { +- /* Amoi M636/A737 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"), +- DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Compal HEL80I */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), +- DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), +- DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "8500"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), +- DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Advent 4211 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- /* Dell Embedded Box PC 3000 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +- DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Dell XPS M1530 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +- DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Dell Vostro 1510 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +- DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Dell Vostro V13 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +- DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) +- }, +- { +- /* Dell Vostro 1320 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +- DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- /* Dell Vostro 1520 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +- DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- /* Dell Vostro 1720 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +- DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- /* Entroware Proteus */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Entroware"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Proteus"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "EL07R4"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS) +- }, +- /* +- * Some Fujitsu notebooks are having trouble with touchpads if +- * active multiplexing mode is activated. Luckily they don't have +- * external PS/2 ports so we can safely disable it. +- * ... apparently some Toshibas don't like MUX mode either and +- * die horrible death on reboot. +- */ +- { +- /* Fujitsu Lifebook P7010/P7010D */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu Lifebook P5020D */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu Lifebook S2000 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu Lifebook S6230 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu Lifebook T725 laptop */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) +- }, +- { +- /* Fujitsu Lifebook U745 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu T70H */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu A544 laptop */ +- /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) +- }, +- { +- /* Fujitsu AH544 laptop */ +- /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) +- }, +- { +- /* Fujitsu U574 laptop */ +- /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) +- }, +- { +- /* Fujitsu UH554 laptop */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) +- }, +- { +- /* Fujitsu Lifebook P7010 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), +- DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu-Siemens Lifebook T3010 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu-Siemens Lifebook E4010 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu-Siemens Amilo Pro 2010 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), +- DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu-Siemens Amilo Pro 2030 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), +- DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Fujitsu Lifebook A574/H */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "FMVA0501PZ"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Gigabyte M912 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +- DMI_MATCH(DMI_PRODUCT_NAME, "M912"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "01"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Gigabyte Spring Peak - defines wrong chassis type */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Gigabyte T1005 - defines wrong chassis type ("Other") */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +- DMI_MATCH(DMI_PRODUCT_NAME, "T1005"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +- DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- /* +- * Some laptops need keyboard reset before probing for the trackpad to get +- * it detected, initialised & finally work. +- */ +- { +- /* Gigabyte P35 v2 - Elantech touchpad */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +- DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_KBDRESET) +- }, +- { +- /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +- DMI_MATCH(DMI_PRODUCT_NAME, "X3"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_KBDRESET) +- }, +- { +- /* Gigabyte P34 - Elantech touchpad */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +- DMI_MATCH(DMI_PRODUCT_NAME, "P34"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_KBDRESET) +- }, +- { +- /* Gigabyte P57 - Elantech touchpad */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +- DMI_MATCH(DMI_PRODUCT_NAME, "P57"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_KBDRESET) +- }, +- { +- /* Gericom Bellagio */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), +- DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Gigabyte M1022M netbook */ +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."), +- DMI_MATCH(DMI_BOARD_NAME, "M1022E"), +- DMI_MATCH(DMI_BOARD_VERSION, "1.02"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), +- DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* +- * HP Pavilion DV4017EA - +- * errors on MUX ports are reported without raising AUXDATA +- * causing "spurious NAK" messages. +- */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* +- * HP Pavilion ZT1000 - +- * like DV4017EA does not raise AUXERR for errors on MUX ports. +- */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), +- DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* +- * HP Pavilion DV4270ca - +- * like DV4017EA does not raise AUXERR for errors on MUX ports. +- */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Newer HP Pavilion dv4 models */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), +- DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) +- }, +- { +- /* IBM 2656 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "IBM"), +- DMI_MATCH(DMI_PRODUCT_NAME, "2656"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Avatar AVIU-145A6 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Intel"), +- DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Intel MBO Desktop D845PESV */ +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), +- DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOPNP) +- }, +- { +- /* +- * Intel NUC D54250WYK - does not have i8042 controller but +- * declares PS/2 devices in DSDT. +- */ +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), +- DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOPNP) +- }, +- { +- /* Lenovo 3000 n100 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Lenovo XiaoXin Air 12 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_NAME, "80UN"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Lenovo LaVie Z */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Lenovo Ideapad U455 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_NAME, "20046"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- /* Lenovo ThinkPad L460 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- /* Lenovo ThinkPad Twist S230u */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- /* LG Electronics X110 */ +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), +- DMI_MATCH(DMI_BOARD_NAME, "X110"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- /* Medion Akoya Mini E1210 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), +- DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- /* Medion Akoya E1222 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), +- DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- { +- /* MSI Wind U-100 */ +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), +- DMI_MATCH(DMI_BOARD_NAME, "U-100"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOPNP) +- }, +- { +- /* +- * No data is coming from the touchscreen unless KBC +- * is in legacy mode. +- */ +- /* Panasonic CF-29 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), +- DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Medion Akoya E7225 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Medion"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Microsoft Virtual Machine */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Medion MAM 2070 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), +- DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* TUXEDO BU1406 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), +- DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* OQO Model 01 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "OQO"), +- DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "00"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"), +- DMI_MATCH(DMI_PRODUCT_NAME, "C15B"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Acer Aspire 5 A515 */ +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "PK"), +- DMI_MATCH(DMI_BOARD_NAME, "Grumpy_PK"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOPNP) +- }, +- { +- /* ULI EV4873 - AUX LOOP does not work properly */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ULI"), +- DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* +- * Arima-Rioworks HDAMB - +- * AUX LOOP command does not raise AUX IRQ +- */ +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"), +- DMI_MATCH(DMI_BOARD_NAME, "HDAMB"), +- DMI_MATCH(DMI_BOARD_VERSION, "Rev E"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- { +- /* Sharp Actius MM20 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), +- DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* +- * Sony Vaio FZ-240E - +- * reset and GET ID commands issued via KBD port are +- * sometimes being delivered to AUX3. +- */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), +- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* +- * Most (all?) VAIOs do not have external PS/2 ports nor +- * they implement active multiplexing properly, and +- * MUX discovery usually messes up keyboard/touchpad. +- */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), +- DMI_MATCH(DMI_BOARD_NAME, "VAIO"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* Sony Vaio FS-115b */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), +- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- /* +- * Sony Vaio VGN-CS series require MUX or the touch sensor +- * buttons will disturb touchpad operation +- */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), +- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_FORCEMUX) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), +- DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), +- DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX) +- }, +- /* +- * A lot of modern Clevo barebones have touchpad and/or keyboard issues +- * after suspend fixable with nomux + reset + noloop + nopnp. Luckily, +- * none of them have an external PS/2 port so this can safely be set for +- * all of them. These two are based on a Clevo design, but have the +- * board_name changed. +- */ +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"), +- DMI_MATCH(DMI_BOARD_NAME, "AURA1501"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"), +- DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- /* Mivvy M310 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), +- DMI_MATCH(DMI_PRODUCT_NAME, "N10"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) +- }, +- /* +- * Some laptops need keyboard reset before probing for the trackpad to get +- * it detected, initialised & finally work. +- */ +- { +- /* Schenker XMG C504 - Elantech touchpad */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "XMG"), +- DMI_MATCH(DMI_PRODUCT_NAME, "C504"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_KBDRESET) +- }, +- { +- /* Blue FB5601 */ +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "blue"), +- DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "M606"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOLOOP) +- }, +- /* +- * A lot of modern Clevo barebones have touchpad and/or keyboard issues +- * after suspend fixable with nomux + reset + noloop + nopnp. Luckily, +- * none of them have an external PS/2 port so this can safely be set for +- * all of them. +- * Clevo barebones come with board_vendor and/or system_vendor set to +- * either the very generic string "Notebook" and/or a different value +- * for each individual reseller. The only somewhat universal way to +- * identify them is by board_name. +- */ +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "LAPQC71A"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "LAPQC71B"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "N140CU"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "N141CU"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- /* +- * At least one modern Clevo barebone has the touchpad connected both +- * via PS/2 and i2c interface. This causes a race condition between the +- * psmouse and i2c-hid driver. Since the full capability of the touchpad +- * is available via the i2c interface and the device has no external +- * PS/2 port, it is safe to just ignore all ps2 mouses here to avoid +- * this issue. The known affected device is the +- * TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU which comes with one of +- * the two different dmi strings below. NS50MU is not a typo! +- */ +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "NS50MU"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX | +- SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | +- SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "NS50_70MU"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX | +- SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | +- SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- /* +- * This is only a partial board_name and might be followed by +- * another letter or number. DMI_MATCH however does do partial +- * matching. +- */ +- .matches = { +- DMI_MATCH(DMI_PRODUCT_NAME, "P65xH"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */ +- .matches = { +- DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- /* +- * This is only a partial board_name and might be followed by +- * another letter or number. DMI_MATCH however does do partial +- * matching. +- */ +- .matches = { +- DMI_MATCH(DMI_PRODUCT_NAME, "P65_P67H"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- /* +- * This is only a partial board_name and might be followed by +- * another letter or number. DMI_MATCH however does do partial +- * matching. +- */ +- .matches = { +- DMI_MATCH(DMI_PRODUCT_NAME, "P65_67RP"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- /* +- * This is only a partial board_name and might be followed by +- * another letter or number. DMI_MATCH however does do partial +- * matching. +- */ +- .matches = { +- DMI_MATCH(DMI_PRODUCT_NAME, "P65_67RS"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- /* +- * This is only a partial board_name and might be followed by +- * another letter or number. DMI_MATCH however does do partial +- * matching. +- */ +- .matches = { +- DMI_MATCH(DMI_PRODUCT_NAME, "P67xRP"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "PB50_70DFx,DDx"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "PCX0DX"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "X170SM"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { +- .matches = { +- DMI_MATCH(DMI_BOARD_NAME, "X170KM-G"), +- }, +- .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | +- SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) +- }, +- { } +-}; +- +-#ifdef CONFIG_PNP +-static const struct dmi_system_id i8042_dmi_laptop_table[] __initconst = { +- { +- .matches = { +- DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ +- }, +- }, +- { +- .matches = { +- DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ +- }, +- }, +- { +- .matches = { +- DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ +- }, +- }, +- { +- .matches = { +- DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ +- }, +- }, +- { } +-}; +-#endif +- +-#endif /* CONFIG_X86 */ +- +-#ifdef CONFIG_PNP +-#include <linux/pnp.h> +- +-static bool i8042_pnp_kbd_registered; +-static unsigned int i8042_pnp_kbd_devices; +-static bool i8042_pnp_aux_registered; +-static unsigned int i8042_pnp_aux_devices; +- +-static int i8042_pnp_command_reg; +-static int i8042_pnp_data_reg; +-static int i8042_pnp_kbd_irq; +-static int i8042_pnp_aux_irq; +- +-static char i8042_pnp_kbd_name[32]; +-static char i8042_pnp_aux_name[32]; +- +-static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size) +-{ +- strlcpy(dst, "PNP:", dst_size); +- +- while (id) { +- strlcat(dst, " ", dst_size); +- strlcat(dst, id->id, dst_size); +- id = id->next; +- } +-} +- +-static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did) +-{ +- if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) +- i8042_pnp_data_reg = pnp_port_start(dev,0); +- +- if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1) +- i8042_pnp_command_reg = pnp_port_start(dev, 1); +- +- if (pnp_irq_valid(dev,0)) +- i8042_pnp_kbd_irq = pnp_irq(dev, 0); +- +- strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); +- if (strlen(pnp_dev_name(dev))) { +- strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); +- strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); +- } +- i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id, +- sizeof(i8042_kbd_firmware_id)); +- i8042_kbd_fwnode = dev_fwnode(&dev->dev); +- +- /* Keyboard ports are always supposed to be wakeup-enabled */ +- device_set_wakeup_enable(&dev->dev, true); +- +- i8042_pnp_kbd_devices++; +- return 0; +-} +- +-static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did) +-{ +- if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) +- i8042_pnp_data_reg = pnp_port_start(dev,0); +- +- if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1) +- i8042_pnp_command_reg = pnp_port_start(dev, 1); +- +- if (pnp_irq_valid(dev, 0)) +- i8042_pnp_aux_irq = pnp_irq(dev, 0); +- +- strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); +- if (strlen(pnp_dev_name(dev))) { +- strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); +- strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); +- } +- i8042_pnp_id_to_string(dev->id, i8042_aux_firmware_id, +- sizeof(i8042_aux_firmware_id)); +- +- i8042_pnp_aux_devices++; +- return 0; +-} +- +-static const struct pnp_device_id pnp_kbd_devids[] = { +- { .id = "PNP0300", .driver_data = 0 }, +- { .id = "PNP0301", .driver_data = 0 }, +- { .id = "PNP0302", .driver_data = 0 }, +- { .id = "PNP0303", .driver_data = 0 }, +- { .id = "PNP0304", .driver_data = 0 }, +- { .id = "PNP0305", .driver_data = 0 }, +- { .id = "PNP0306", .driver_data = 0 }, +- { .id = "PNP0309", .driver_data = 0 }, +- { .id = "PNP030a", .driver_data = 0 }, +- { .id = "PNP030b", .driver_data = 0 }, +- { .id = "PNP0320", .driver_data = 0 }, +- { .id = "PNP0343", .driver_data = 0 }, +- { .id = "PNP0344", .driver_data = 0 }, +- { .id = "PNP0345", .driver_data = 0 }, +- { .id = "CPQA0D7", .driver_data = 0 }, +- { .id = "", }, +-}; +-MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids); +- +-static struct pnp_driver i8042_pnp_kbd_driver = { +- .name = "i8042 kbd", +- .id_table = pnp_kbd_devids, +- .probe = i8042_pnp_kbd_probe, +- .driver = { +- .probe_type = PROBE_FORCE_SYNCHRONOUS, +- .suppress_bind_attrs = true, +- }, +-}; +- +-static const struct pnp_device_id pnp_aux_devids[] = { +- { .id = "AUI0200", .driver_data = 0 }, +- { .id = "FJC6000", .driver_data = 0 }, +- { .id = "FJC6001", .driver_data = 0 }, +- { .id = "PNP0f03", .driver_data = 0 }, +- { .id = "PNP0f0b", .driver_data = 0 }, +- { .id = "PNP0f0e", .driver_data = 0 }, +- { .id = "PNP0f12", .driver_data = 0 }, +- { .id = "PNP0f13", .driver_data = 0 }, +- { .id = "PNP0f19", .driver_data = 0 }, +- { .id = "PNP0f1c", .driver_data = 0 }, +- { .id = "SYN0801", .driver_data = 0 }, +- { .id = "", }, +-}; +-MODULE_DEVICE_TABLE(pnp, pnp_aux_devids); +- +-static struct pnp_driver i8042_pnp_aux_driver = { +- .name = "i8042 aux", +- .id_table = pnp_aux_devids, +- .probe = i8042_pnp_aux_probe, +- .driver = { +- .probe_type = PROBE_FORCE_SYNCHRONOUS, +- .suppress_bind_attrs = true, +- }, +-}; +- +-static void i8042_pnp_exit(void) +-{ +- if (i8042_pnp_kbd_registered) { +- i8042_pnp_kbd_registered = false; +- pnp_unregister_driver(&i8042_pnp_kbd_driver); +- } +- +- if (i8042_pnp_aux_registered) { +- i8042_pnp_aux_registered = false; +- pnp_unregister_driver(&i8042_pnp_aux_driver); +- } +-} +- +-static int __init i8042_pnp_init(void) +-{ +- char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; +- bool pnp_data_busted = false; +- int err; +- +- if (i8042_nopnp) { +- pr_info("PNP detection disabled\n"); +- return 0; +- } +- +- err = pnp_register_driver(&i8042_pnp_kbd_driver); +- if (!err) +- i8042_pnp_kbd_registered = true; +- +- err = pnp_register_driver(&i8042_pnp_aux_driver); +- if (!err) +- i8042_pnp_aux_registered = true; +- +- if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) { +- i8042_pnp_exit(); +-#if defined(__ia64__) +- return -ENODEV; +-#else +- pr_info("PNP: No PS/2 controller found.\n"); +- if (x86_platform.legacy.i8042 != +- X86_LEGACY_I8042_EXPECTED_PRESENT) +- return -ENODEV; +- pr_info("Probing ports directly.\n"); +- return 0; +-#endif +- } +- +- if (i8042_pnp_kbd_devices) +- snprintf(kbd_irq_str, sizeof(kbd_irq_str), +- "%d", i8042_pnp_kbd_irq); +- if (i8042_pnp_aux_devices) +- snprintf(aux_irq_str, sizeof(aux_irq_str), +- "%d", i8042_pnp_aux_irq); +- +- pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", +- i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", +- i8042_pnp_aux_name, +- i8042_pnp_data_reg, i8042_pnp_command_reg, +- kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", +- aux_irq_str); +- +-#if defined(__ia64__) +- if (!i8042_pnp_kbd_devices) +- i8042_nokbd = true; +- if (!i8042_pnp_aux_devices) +- i8042_noaux = true; +-#endif +- +- if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && +- i8042_pnp_data_reg != i8042_data_reg) || +- !i8042_pnp_data_reg) { +- pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n", +- i8042_pnp_data_reg, i8042_data_reg); +- i8042_pnp_data_reg = i8042_data_reg; +- pnp_data_busted = true; +- } +- +- if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && +- i8042_pnp_command_reg != i8042_command_reg) || +- !i8042_pnp_command_reg) { +- pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n", +- i8042_pnp_command_reg, i8042_command_reg); +- i8042_pnp_command_reg = i8042_command_reg; +- pnp_data_busted = true; +- } +- +- if (!i8042_nokbd && !i8042_pnp_kbd_irq) { +- pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n", +- i8042_kbd_irq); +- i8042_pnp_kbd_irq = i8042_kbd_irq; +- pnp_data_busted = true; +- } +- +- if (!i8042_noaux && !i8042_pnp_aux_irq) { +- if (!pnp_data_busted && i8042_pnp_kbd_irq) { +- pr_warn("PNP: PS/2 appears to have AUX port disabled, " +- "if this is incorrect please boot with i8042.nopnp\n"); +- i8042_noaux = true; +- } else { +- pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n", +- i8042_aux_irq); +- i8042_pnp_aux_irq = i8042_aux_irq; +- } +- } +- +- i8042_data_reg = i8042_pnp_data_reg; +- i8042_command_reg = i8042_pnp_command_reg; +- i8042_kbd_irq = i8042_pnp_kbd_irq; +- i8042_aux_irq = i8042_pnp_aux_irq; +- +-#ifdef CONFIG_X86 +- i8042_bypass_aux_irq_test = !pnp_data_busted && +- dmi_check_system(i8042_dmi_laptop_table); +-#endif +- +- return 0; +-} +- +-#else /* !CONFIG_PNP */ +-static inline int i8042_pnp_init(void) { return 0; } +-static inline void i8042_pnp_exit(void) { } +-#endif /* CONFIG_PNP */ +- +- +-#ifdef CONFIG_X86 +-static void __init i8042_check_quirks(void) +-{ +- const struct dmi_system_id *device_quirk_info; +- uintptr_t quirks; +- +- device_quirk_info = dmi_first_match(i8042_dmi_quirk_table); +- if (!device_quirk_info) +- return; +- +- quirks = (uintptr_t)device_quirk_info->driver_data; +- +- if (quirks & SERIO_QUIRK_NOKBD) +- i8042_nokbd = true; +- if (quirks & SERIO_QUIRK_NOAUX) +- i8042_noaux = true; +- if (quirks & SERIO_QUIRK_NOMUX) +- i8042_nomux = true; +- if (quirks & SERIO_QUIRK_FORCEMUX) +- i8042_nomux = false; +- if (quirks & SERIO_QUIRK_UNLOCK) +- i8042_unlock = true; +- if (quirks & SERIO_QUIRK_PROBE_DEFER) +- i8042_probe_defer = true; +- /* Honor module parameter when value is not default */ +- if (i8042_reset == I8042_RESET_DEFAULT) { +- if (quirks & SERIO_QUIRK_RESET_ALWAYS) +- i8042_reset = I8042_RESET_ALWAYS; +- if (quirks & SERIO_QUIRK_RESET_NEVER) +- i8042_reset = I8042_RESET_NEVER; +- } +- if (quirks & SERIO_QUIRK_DIECT) +- i8042_direct = true; +- if (quirks & SERIO_QUIRK_DUMBKBD) +- i8042_dumbkbd = true; +- if (quirks & SERIO_QUIRK_NOLOOP) +- i8042_noloop = true; +- if (quirks & SERIO_QUIRK_NOTIMEOUT) +- i8042_notimeout = true; +- if (quirks & SERIO_QUIRK_KBDRESET) +- i8042_kbdreset = true; +- if (quirks & SERIO_QUIRK_DRITEK) +- i8042_dritek = true; +-#ifdef CONFIG_PNP +- if (quirks & SERIO_QUIRK_NOPNP) +- i8042_nopnp = true; +-#endif +-} +-#else +-static inline void i8042_check_quirks(void) {} +-#endif +- +-static int __init i8042_platform_init(void) +-{ +- int retval; +- +-#ifdef CONFIG_X86 +- u8 a20_on = 0xdf; +- /* Just return if platform does not have i8042 controller */ +- if (x86_platform.legacy.i8042 == X86_LEGACY_I8042_PLATFORM_ABSENT) +- return -ENODEV; +-#endif +- +-/* +- * On ix86 platforms touching the i8042 data register region can do really +- * bad things. Because of this the region is always reserved on ix86 boxes. +- * +- * if (!request_region(I8042_DATA_REG, 16, "i8042")) +- * return -EBUSY; +- */ +- +- i8042_kbd_irq = I8042_MAP_IRQ(1); +- i8042_aux_irq = I8042_MAP_IRQ(12); +- +-#if defined(__ia64__) +- i8042_reset = I8042_RESET_ALWAYS; +-#endif +- +- i8042_check_quirks(); +- +- retval = i8042_pnp_init(); +- if (retval) +- return retval; +- +-#ifdef CONFIG_X86 +- /* +- * A20 was already enabled during early kernel init. But some buggy +- * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to +- * resume from S3. So we do it here and hope that nothing breaks. +- */ +- i8042_command(&a20_on, 0x10d1); +- i8042_command(NULL, 0x00ff); /* Null command for SMM firmware */ +-#endif /* CONFIG_X86 */ +- +- return retval; +-} +- +-static inline void i8042_platform_exit(void) +-{ +- i8042_pnp_exit(); +-} +- +-#endif /* _I8042_X86IA64IO_H */ +diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h +index 55381783dc82d..bf2592fa9a783 100644 +--- a/drivers/input/serio/i8042.h ++++ b/drivers/input/serio/i8042.h +@@ -20,7 +20,7 @@ + #elif defined(CONFIG_SPARC) + #include "i8042-sparcio.h" + #elif defined(CONFIG_X86) || defined(CONFIG_IA64) +-#include "i8042-x86ia64io.h" ++#include "i8042-acpipnpio.h" + #else + #include "i8042-io.h" + #endif +diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c +index ab654b33f5d24..b7c41bd7409cd 100644 +--- a/drivers/interconnect/core.c ++++ b/drivers/interconnect/core.c +@@ -13,6 +13,7 @@ + #include <linux/interconnect.h> + #include <linux/interconnect-provider.h> + #include <linux/list.h> ++#include <linux/sched/mm.h> + #include <linux/module.h> + #include <linux/mutex.h> + #include <linux/slab.h> +diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c +index e2e80eb2840ca..01748742c6842 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c +@@ -186,6 +186,15 @@ static void arm_smmu_free_shared_cd(struct arm_smmu_ctx_desc *cd) + } + } + ++/* ++ * Cloned from the MAX_TLBI_OPS in arch/arm64/include/asm/tlbflush.h, this ++ * is used as a threshold to replace per-page TLBI commands to issue in the ++ * command queue with an address-space TLBI command, when SMMU w/o a range ++ * invalidation feature handles too many per-page TLBI commands, which will ++ * otherwise result in a soft lockup. ++ */ ++#define CMDQ_MAX_TLBI_OPS (1 << (PAGE_SHIFT - 3)) ++ + static void arm_smmu_mm_invalidate_range(struct mmu_notifier *mn, + struct mm_struct *mm, + unsigned long start, unsigned long end) +@@ -200,10 +209,22 @@ static void arm_smmu_mm_invalidate_range(struct mmu_notifier *mn, + * range. So do a simple translation here by calculating size correctly. + */ + size = end - start; ++ if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_RANGE_INV)) { ++ if (size >= CMDQ_MAX_TLBI_OPS * PAGE_SIZE) ++ size = 0; ++ } ++ ++ if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) { ++ if (!size) ++ arm_smmu_tlb_inv_asid(smmu_domain->smmu, ++ smmu_mn->cd->asid); ++ else ++ arm_smmu_tlb_inv_range_asid(start, size, ++ smmu_mn->cd->asid, ++ PAGE_SIZE, false, ++ smmu_domain); ++ } + +- if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) +- arm_smmu_tlb_inv_range_asid(start, size, smmu_mn->cd->asid, +- PAGE_SIZE, false, smmu_domain); + arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, start, size); + } + +diff --git a/drivers/media/common/videobuf2/frame_vector.c b/drivers/media/common/videobuf2/frame_vector.c +index 144027035892a..07ebe4424df3a 100644 +--- a/drivers/media/common/videobuf2/frame_vector.c ++++ b/drivers/media/common/videobuf2/frame_vector.c +@@ -30,6 +30,10 @@ + * different type underlying the specified range of virtual addresses. + * When the function isn't able to map a single page, it returns error. + * ++ * Note that get_vaddr_frames() cannot follow VM_IO mappings. It used ++ * to be able to do that, but that could (racily) return non-refcounted ++ * pfns. ++ * + * This function takes care of grabbing mmap_lock as necessary. + */ + int get_vaddr_frames(unsigned long start, unsigned int nr_frames, +@@ -55,8 +59,6 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, + if (likely(ret > 0)) + return ret; + +- /* This used to (racily) return non-refcounted pfns. Let people know */ +- WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping"); + vec->nr_frames = 0; + return ret ? ret : -EFAULT; + } +diff --git a/drivers/misc/cardreader/rts5227.c b/drivers/misc/cardreader/rts5227.c +index 0f106d7006251..e4def5fa69027 100644 +--- a/drivers/misc/cardreader/rts5227.c ++++ b/drivers/misc/cardreader/rts5227.c +@@ -81,63 +81,20 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr) + + static void rts5227_init_from_cfg(struct rtsx_pcr *pcr) + { +- struct pci_dev *pdev = pcr->pci; +- int l1ss; +- u32 lval; + struct rtsx_cr_option *option = &pcr->option; + +- l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); +- if (!l1ss) +- return; +- +- pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); +- + if (CHK_PCI_PID(pcr, 0x522A)) { +- if (0 == (lval & 0x0F)) +- rtsx_pci_enable_oobs_polling(pcr); +- else ++ if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN ++ | PM_L1_1_EN | PM_L1_2_EN)) + rtsx_pci_disable_oobs_polling(pcr); ++ else ++ rtsx_pci_enable_oobs_polling(pcr); + } + +- if (lval & PCI_L1SS_CTL1_ASPM_L1_1) +- rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); +- else +- rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); +- +- if (lval & PCI_L1SS_CTL1_ASPM_L1_2) +- rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); +- else +- rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); +- +- if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) +- rtsx_set_dev_flag(pcr, PM_L1_1_EN); +- else +- rtsx_clear_dev_flag(pcr, PM_L1_1_EN); +- +- if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) +- rtsx_set_dev_flag(pcr, PM_L1_2_EN); +- else +- rtsx_clear_dev_flag(pcr, PM_L1_2_EN); +- + if (option->ltr_en) { +- u16 val; +- +- pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val); +- if (val & PCI_EXP_DEVCTL2_LTR_EN) { +- option->ltr_enabled = true; +- option->ltr_active = true; ++ if (option->ltr_enabled) + rtsx_set_ltr_latency(pcr, option->ltr_active_latency); +- } else { +- option->ltr_enabled = false; +- } + } +- +- if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN +- | PM_L1_1_EN | PM_L1_2_EN)) +- option->force_clkreq_0 = false; +- else +- option->force_clkreq_0 = true; +- + } + + static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) +@@ -171,7 +128,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) + else + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x30, 0x00); + +- if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) ++ if (option->force_clkreq_0) + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, + FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); + else +diff --git a/drivers/misc/cardreader/rts5228.c b/drivers/misc/cardreader/rts5228.c +index 282a03520cf52..d80216c69d4f2 100644 +--- a/drivers/misc/cardreader/rts5228.c ++++ b/drivers/misc/cardreader/rts5228.c +@@ -378,59 +378,25 @@ static void rts5228_process_ocp(struct rtsx_pcr *pcr) + + static void rts5228_init_from_cfg(struct rtsx_pcr *pcr) + { +- struct pci_dev *pdev = pcr->pci; +- int l1ss; +- u32 lval; + struct rtsx_cr_option *option = &pcr->option; + +- l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); +- if (!l1ss) +- return; +- +- pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); +- +- if (0 == (lval & 0x0F)) +- rtsx_pci_enable_oobs_polling(pcr); +- else ++ if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN ++ | PM_L1_1_EN | PM_L1_2_EN)) + rtsx_pci_disable_oobs_polling(pcr); +- +- if (lval & PCI_L1SS_CTL1_ASPM_L1_1) +- rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); +- else +- rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); +- +- if (lval & PCI_L1SS_CTL1_ASPM_L1_2) +- rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); +- else +- rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); +- +- if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) +- rtsx_set_dev_flag(pcr, PM_L1_1_EN); + else +- rtsx_clear_dev_flag(pcr, PM_L1_1_EN); +- +- if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) +- rtsx_set_dev_flag(pcr, PM_L1_2_EN); +- else +- rtsx_clear_dev_flag(pcr, PM_L1_2_EN); ++ rtsx_pci_enable_oobs_polling(pcr); + + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); +- if (option->ltr_en) { +- u16 val; + +- pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val); +- if (val & PCI_EXP_DEVCTL2_LTR_EN) { +- option->ltr_enabled = true; +- option->ltr_active = true; ++ if (option->ltr_en) { ++ if (option->ltr_enabled) + rtsx_set_ltr_latency(pcr, option->ltr_active_latency); +- } else { +- option->ltr_enabled = false; +- } + } + } + + static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) + { ++ struct rtsx_cr_option *option = &pcr->option; + + rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1, + CD_RESUME_EN_MASK, CD_RESUME_EN_MASK); +@@ -461,6 +427,17 @@ static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) + else + rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); + ++ /* ++ * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced ++ * to drive low, and we forcibly request clock. ++ */ ++ if (option->force_clkreq_0) ++ rtsx_pci_write_register(pcr, PETXCFG, ++ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); ++ else ++ rtsx_pci_write_register(pcr, PETXCFG, ++ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); ++ + rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); + rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); + rtsx_pci_write_register(pcr, RTS5228_REG_PME_FORCE_CTL, +diff --git a/drivers/misc/cardreader/rts5249.c b/drivers/misc/cardreader/rts5249.c +index 6b5e4bdf209df..e34613f404997 100644 +--- a/drivers/misc/cardreader/rts5249.c ++++ b/drivers/misc/cardreader/rts5249.c +@@ -85,64 +85,22 @@ static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr) + + static void rts5249_init_from_cfg(struct rtsx_pcr *pcr) + { +- struct pci_dev *pdev = pcr->pci; +- int l1ss; + struct rtsx_cr_option *option = &(pcr->option); +- u32 lval; +- +- l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); +- if (!l1ss) +- return; +- +- pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); + + if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) { +- if (0 == (lval & 0x0F)) +- rtsx_pci_enable_oobs_polling(pcr); +- else ++ if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN ++ | PM_L1_1_EN | PM_L1_2_EN)) + rtsx_pci_disable_oobs_polling(pcr); ++ else ++ rtsx_pci_enable_oobs_polling(pcr); + } + +- +- if (lval & PCI_L1SS_CTL1_ASPM_L1_1) +- rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); +- +- if (lval & PCI_L1SS_CTL1_ASPM_L1_2) +- rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); +- +- if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) +- rtsx_set_dev_flag(pcr, PM_L1_1_EN); +- +- if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) +- rtsx_set_dev_flag(pcr, PM_L1_2_EN); +- + if (option->ltr_en) { +- u16 val; +- +- pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); +- if (val & PCI_EXP_DEVCTL2_LTR_EN) { +- option->ltr_enabled = true; +- option->ltr_active = true; ++ if (option->ltr_enabled) + rtsx_set_ltr_latency(pcr, option->ltr_active_latency); +- } else { +- option->ltr_enabled = false; +- } + } + } + +-static int rts5249_init_from_hw(struct rtsx_pcr *pcr) +-{ +- struct rtsx_cr_option *option = &(pcr->option); +- +- if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN +- | PM_L1_1_EN | PM_L1_2_EN)) +- option->force_clkreq_0 = false; +- else +- option->force_clkreq_0 = true; +- +- return 0; +-} +- + static void rts52xa_save_content_from_efuse(struct rtsx_pcr *pcr) + { + u8 cnt, sv; +@@ -254,7 +212,6 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) + struct rtsx_cr_option *option = &(pcr->option); + + rts5249_init_from_cfg(pcr); +- rts5249_init_from_hw(pcr); + + rtsx_pci_init_cmd(pcr); + +@@ -302,11 +259,12 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) + } + } + ++ + /* + * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced + * to drive low, and we forcibly request clock. + */ +- if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) ++ if (option->force_clkreq_0) + rtsx_pci_write_register(pcr, PETXCFG, + FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); + else +diff --git a/drivers/misc/cardreader/rts5260.c b/drivers/misc/cardreader/rts5260.c +index 79b18f6f73a8a..d2d3a6ccb8f7d 100644 +--- a/drivers/misc/cardreader/rts5260.c ++++ b/drivers/misc/cardreader/rts5260.c +@@ -480,47 +480,19 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr) + + static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) + { +- struct pci_dev *pdev = pcr->pci; +- int l1ss; + struct rtsx_cr_option *option = &pcr->option; +- u32 lval; +- +- l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); +- if (!l1ss) +- return; +- +- pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); +- +- if (lval & PCI_L1SS_CTL1_ASPM_L1_1) +- rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); +- +- if (lval & PCI_L1SS_CTL1_ASPM_L1_2) +- rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); +- +- if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) +- rtsx_set_dev_flag(pcr, PM_L1_1_EN); +- +- if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) +- rtsx_set_dev_flag(pcr, PM_L1_2_EN); + + rts5260_pwr_saving_setting(pcr); + + if (option->ltr_en) { +- u16 val; +- +- pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); +- if (val & PCI_EXP_DEVCTL2_LTR_EN) { +- option->ltr_enabled = true; +- option->ltr_active = true; ++ if (option->ltr_enabled) + rtsx_set_ltr_latency(pcr, option->ltr_active_latency); +- } else { +- option->ltr_enabled = false; +- } + } + } + + static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) + { ++ struct rtsx_cr_option *option = &pcr->option; + + /* Set mcu_cnt to 7 to ensure data can be sampled properly */ + rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); +@@ -539,6 +511,17 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) + + rts5260_init_hw(pcr); + ++ /* ++ * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced ++ * to drive low, and we forcibly request clock. ++ */ ++ if (option->force_clkreq_0) ++ rtsx_pci_write_register(pcr, PETXCFG, ++ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); ++ else ++ rtsx_pci_write_register(pcr, PETXCFG, ++ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); ++ + rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); + + return 0; +diff --git a/drivers/misc/cardreader/rts5261.c b/drivers/misc/cardreader/rts5261.c +index 2a97eeb0e5097..179b80099558f 100644 +--- a/drivers/misc/cardreader/rts5261.c ++++ b/drivers/misc/cardreader/rts5261.c +@@ -424,54 +424,17 @@ static int rts5261_init_from_hw(struct rtsx_pcr *pcr) + + static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) + { +- struct pci_dev *pdev = pcr->pci; +- int l1ss; +- u32 lval; + struct rtsx_cr_option *option = &pcr->option; + +- l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); +- if (!l1ss) +- return; +- +- pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); +- +- if (lval & PCI_L1SS_CTL1_ASPM_L1_1) +- rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); +- else +- rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); +- +- if (lval & PCI_L1SS_CTL1_ASPM_L1_2) +- rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); +- else +- rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); +- +- if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) +- rtsx_set_dev_flag(pcr, PM_L1_1_EN); +- else +- rtsx_clear_dev_flag(pcr, PM_L1_1_EN); +- +- if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) +- rtsx_set_dev_flag(pcr, PM_L1_2_EN); +- else +- rtsx_clear_dev_flag(pcr, PM_L1_2_EN); +- +- rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); + if (option->ltr_en) { +- u16 val; +- +- pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); +- if (val & PCI_EXP_DEVCTL2_LTR_EN) { +- option->ltr_enabled = true; +- option->ltr_active = true; ++ if (option->ltr_enabled) + rtsx_set_ltr_latency(pcr, option->ltr_active_latency); +- } else { +- option->ltr_enabled = false; +- } + } + } + + static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) + { ++ struct rtsx_cr_option *option = &pcr->option; + u32 val; + + rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1, +@@ -517,6 +480,17 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) + else + rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); + ++ /* ++ * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced ++ * to drive low, and we forcibly request clock. ++ */ ++ if (option->force_clkreq_0) ++ rtsx_pci_write_register(pcr, PETXCFG, ++ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); ++ else ++ rtsx_pci_write_register(pcr, PETXCFG, ++ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); ++ + rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); + rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); + rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL, +diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c +index c0bf747305e22..b2099bb54ac12 100644 +--- a/drivers/misc/cardreader/rtsx_pcr.c ++++ b/drivers/misc/cardreader/rtsx_pcr.c +@@ -1400,11 +1400,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) + return err; + } + +- if (pcr->aspm_mode == ASPM_MODE_REG) { ++ if (pcr->aspm_mode == ASPM_MODE_REG) + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); +- rtsx_pci_write_register(pcr, PETXCFG, +- FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); +- } + + /* No CD interrupt if probing driver with card inserted. + * So we need to initialize pcr->card_exist here. +@@ -1419,7 +1416,9 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) + + static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) + { +- int err; ++ struct rtsx_cr_option *option = &(pcr->option); ++ int err, l1ss; ++ u32 lval; + u16 cfg_val; + u8 val; + +@@ -1504,6 +1503,48 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) + pcr->aspm_enabled = true; + } + ++ l1ss = pci_find_ext_capability(pcr->pci, PCI_EXT_CAP_ID_L1SS); ++ if (l1ss) { ++ pci_read_config_dword(pcr->pci, l1ss + PCI_L1SS_CTL1, &lval); ++ ++ if (lval & PCI_L1SS_CTL1_ASPM_L1_1) ++ rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); ++ else ++ rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); ++ ++ if (lval & PCI_L1SS_CTL1_ASPM_L1_2) ++ rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); ++ else ++ rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); ++ ++ if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) ++ rtsx_set_dev_flag(pcr, PM_L1_1_EN); ++ else ++ rtsx_clear_dev_flag(pcr, PM_L1_1_EN); ++ ++ if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) ++ rtsx_set_dev_flag(pcr, PM_L1_2_EN); ++ else ++ rtsx_clear_dev_flag(pcr, PM_L1_2_EN); ++ ++ pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &cfg_val); ++ if (cfg_val & PCI_EXP_DEVCTL2_LTR_EN) { ++ option->ltr_enabled = true; ++ option->ltr_active = true; ++ } else { ++ option->ltr_enabled = false; ++ } ++ ++ if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN ++ | PM_L1_1_EN | PM_L1_2_EN)) ++ option->force_clkreq_0 = false; ++ else ++ option->force_clkreq_0 = true; ++ } else { ++ option->ltr_enabled = false; ++ option->force_clkreq_0 = true; ++ } ++ + if (pcr->ops->fetch_vendor_settings) + pcr->ops->fetch_vendor_settings(pcr); + +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c +index f3673be4fc087..3eba01de95259 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -1788,6 +1788,9 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, + return work_done; + + error: ++ if (xdp_flags & ENA_XDP_REDIRECT) ++ xdp_do_flush(); ++ + adapter = netdev_priv(rx_ring->netdev); + + if (rc == -ENOSPC) { +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 931bb40ac05b5..4cb22e4060520 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -2520,6 +2520,7 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget) + struct rx_cmp_ext *rxcmp1; + u32 cp_cons, tmp_raw_cons; + u32 raw_cons = cpr->cp_raw_cons; ++ bool flush_xdp = false; + u32 rx_pkts = 0; + u8 event = 0; + +@@ -2554,6 +2555,8 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget) + rx_pkts++; + else if (rc == -EBUSY) /* partial completion */ + break; ++ if (event & BNXT_REDIRECT_EVENT) ++ flush_xdp = true; + } else if (unlikely(TX_CMP_TYPE(txcmp) == + CMPL_BASE_TYPE_HWRM_DONE)) { + bnxt_hwrm_handler(bp, txcmp); +@@ -2573,6 +2576,8 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget) + + if (event & BNXT_AGG_EVENT) + bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod); ++ if (flush_xdp) ++ xdp_do_flush(); + + if (!bnxt_has_work(bp, cpr) && rx_pkts < budget) { + napi_complete_done(napi, rx_pkts); +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index 3693ff55197dd..fde1ff3580458 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -3156,6 +3156,15 @@ static void hns3_set_default_feature(struct net_device *netdev) + NETIF_F_HW_TC); + + netdev->hw_enc_features |= netdev->vlan_features | NETIF_F_TSO_MANGLEID; ++ ++ /* The device_version V3 hardware can't offload the checksum for IP in ++ * GRE packets, but can do it for NvGRE. So default to disable the ++ * checksum and GSO offload for GRE. ++ */ ++ if (ae_dev->dev_version > HNAE3_DEVICE_VERSION_V2) { ++ netdev->features &= ~NETIF_F_GSO_GRE; ++ netdev->features &= ~NETIF_F_GSO_GRE_CSUM; ++ } + } + + static int hns3_alloc_buffer(struct hns3_enet_ring *ring, +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index a415760505ab4..ca59e1cd992e5 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -3391,9 +3391,14 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) + static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type, + u32 regclr) + { ++#define HCLGE_IMP_RESET_DELAY 5 ++ + switch (event_type) { + case HCLGE_VECTOR0_EVENT_PTP: + case HCLGE_VECTOR0_EVENT_RST: ++ if (regclr == BIT(HCLGE_VECTOR0_IMPRESET_INT_B)) ++ mdelay(HCLGE_IMP_RESET_DELAY); ++ + hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr); + break; + case HCLGE_VECTOR0_EVENT_MBX: +@@ -7546,6 +7551,12 @@ static int hclge_del_cls_flower(struct hnae3_handle *handle, + ret = hclge_fd_tcam_config(hdev, HCLGE_FD_STAGE_1, true, rule->location, + NULL, false); + if (ret) { ++ /* if tcam config fail, set rule state to TO_DEL, ++ * so the rule will be deleted when periodic ++ * task being scheduled. ++ */ ++ hclge_update_fd_list(hdev, HCLGE_FD_TO_DEL, rule->location, NULL); ++ set_bit(HCLGE_STATE_FD_TBL_CHANGED, &hdev->state); + spin_unlock_bh(&hdev->fd_rule_lock); + return ret; + } +@@ -8967,7 +8978,7 @@ static void hclge_update_overflow_flags(struct hclge_vport *vport, + if (mac_type == HCLGE_MAC_ADDR_UC) { + if (is_all_added) + vport->overflow_promisc_flags &= ~HNAE3_OVERFLOW_UPE; +- else ++ else if (hclge_is_umv_space_full(vport, true)) + vport->overflow_promisc_flags |= HNAE3_OVERFLOW_UPE; + } else { + if (is_all_added) +diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h +index a42ca847c8f86..b76e6f94edb05 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e.h ++++ b/drivers/net/ethernet/intel/i40e/i40e.h +@@ -566,6 +566,7 @@ struct i40e_pf { + #define I40E_FLAG_DISABLE_FW_LLDP BIT(24) + #define I40E_FLAG_RS_FEC BIT(25) + #define I40E_FLAG_BASE_R_FEC BIT(26) ++#define I40E_FLAG_VF_VLAN_PRUNING BIT(27) + /* TOTAL_PORT_SHUTDOWN + * Allows to physically disable the link on the NIC's port. + * If enabled, (after link down request from the OS) +diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +index d124cb947ffa5..d0b9ee756b306 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +@@ -451,6 +451,8 @@ static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = { + I40E_PRIV_FLAG("disable-fw-lldp", I40E_FLAG_DISABLE_FW_LLDP, 0), + I40E_PRIV_FLAG("rs-fec", I40E_FLAG_RS_FEC, 0), + I40E_PRIV_FLAG("base-r-fec", I40E_FLAG_BASE_R_FEC, 0), ++ I40E_PRIV_FLAG("vf-vlan-pruning", ++ I40E_FLAG_VF_VLAN_PRUNING, 0), + }; + + #define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gstrings_priv_flags) +@@ -5293,6 +5295,13 @@ flags_complete: + return -EOPNOTSUPP; + } + ++ if ((changed_flags & I40E_FLAG_VF_VLAN_PRUNING) && ++ pf->num_alloc_vfs) { ++ dev_warn(&pf->pdev->dev, ++ "Changing vf-vlan-pruning flag while VF(s) are active is not supported\n"); ++ return -EOPNOTSUPP; ++ } ++ + if ((changed_flags & new_flags & + I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) && + (new_flags & I40E_FLAG_MFP_ENABLED)) +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index d3f3874220a31..539bb69548f23 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -1426,6 +1426,114 @@ static int i40e_correct_mac_vlan_filters(struct i40e_vsi *vsi, + return 0; + } + ++/** ++ * i40e_get_vf_new_vlan - Get new vlan id on a vf ++ * @vsi: the vsi to configure ++ * @new_mac: new mac filter to be added ++ * @f: existing mac filter, replaced with new_mac->f if new_mac is not NULL ++ * @vlan_filters: the number of active VLAN filters ++ * @trusted: flag if the VF is trusted ++ * ++ * Get new VLAN id based on current VLAN filters, trust, PVID ++ * and vf-vlan-prune-disable flag. ++ * ++ * Returns the value of the new vlan filter or ++ * the old value if no new filter is needed. ++ */ ++static s16 i40e_get_vf_new_vlan(struct i40e_vsi *vsi, ++ struct i40e_new_mac_filter *new_mac, ++ struct i40e_mac_filter *f, ++ int vlan_filters, ++ bool trusted) ++{ ++ s16 pvid = le16_to_cpu(vsi->info.pvid); ++ struct i40e_pf *pf = vsi->back; ++ bool is_any; ++ ++ if (new_mac) ++ f = new_mac->f; ++ ++ if (pvid && f->vlan != pvid) ++ return pvid; ++ ++ is_any = (trusted || ++ !(pf->flags & I40E_FLAG_VF_VLAN_PRUNING)); ++ ++ if ((vlan_filters && f->vlan == I40E_VLAN_ANY) || ++ (!is_any && !vlan_filters && f->vlan == I40E_VLAN_ANY) || ++ (is_any && !vlan_filters && f->vlan == 0)) { ++ if (is_any) ++ return I40E_VLAN_ANY; ++ else ++ return 0; ++ } ++ ++ return f->vlan; ++} ++ ++/** ++ * i40e_correct_vf_mac_vlan_filters - Correct non-VLAN VF filters if necessary ++ * @vsi: the vsi to configure ++ * @tmp_add_list: list of filters ready to be added ++ * @tmp_del_list: list of filters ready to be deleted ++ * @vlan_filters: the number of active VLAN filters ++ * @trusted: flag if the VF is trusted ++ * ++ * Correct VF VLAN filters based on current VLAN filters, trust, PVID ++ * and vf-vlan-prune-disable flag. ++ * ++ * In case of memory allocation failure return -ENOMEM. Otherwise, return 0. ++ * ++ * This function is only expected to be called from within ++ * i40e_sync_vsi_filters. ++ * ++ * NOTE: This function expects to be called while under the ++ * mac_filter_hash_lock ++ */ ++static int i40e_correct_vf_mac_vlan_filters(struct i40e_vsi *vsi, ++ struct hlist_head *tmp_add_list, ++ struct hlist_head *tmp_del_list, ++ int vlan_filters, ++ bool trusted) ++{ ++ struct i40e_mac_filter *f, *add_head; ++ struct i40e_new_mac_filter *new_mac; ++ struct hlist_node *h; ++ int bkt, new_vlan; ++ ++ hlist_for_each_entry(new_mac, tmp_add_list, hlist) { ++ new_mac->f->vlan = i40e_get_vf_new_vlan(vsi, new_mac, NULL, ++ vlan_filters, trusted); ++ } ++ ++ hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) { ++ new_vlan = i40e_get_vf_new_vlan(vsi, NULL, f, vlan_filters, ++ trusted); ++ if (new_vlan != f->vlan) { ++ add_head = i40e_add_filter(vsi, f->macaddr, new_vlan); ++ if (!add_head) ++ return -ENOMEM; ++ /* Create a temporary i40e_new_mac_filter */ ++ new_mac = kzalloc(sizeof(*new_mac), GFP_ATOMIC); ++ if (!new_mac) ++ return -ENOMEM; ++ new_mac->f = add_head; ++ new_mac->state = add_head->state; ++ ++ /* Add the new filter to the tmp list */ ++ hlist_add_head(&new_mac->hlist, tmp_add_list); ++ ++ /* Put the original filter into the delete list */ ++ f->state = I40E_FILTER_REMOVE; ++ hash_del(&f->hlist); ++ hlist_add_head(&f->hlist, tmp_del_list); ++ } ++ } ++ ++ vsi->has_vlan_filter = !!vlan_filters; ++ return 0; ++} ++ + /** + * i40e_rm_default_mac_filter - Remove the default MAC filter set by NVM + * @vsi: the PF Main VSI - inappropriate for any other VSI +@@ -2483,10 +2591,14 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) + vlan_filters++; + } + +- retval = i40e_correct_mac_vlan_filters(vsi, +- &tmp_add_list, +- &tmp_del_list, +- vlan_filters); ++ if (vsi->type != I40E_VSI_SRIOV) ++ retval = i40e_correct_mac_vlan_filters ++ (vsi, &tmp_add_list, &tmp_del_list, ++ vlan_filters); ++ else if (pf->vf) ++ retval = i40e_correct_vf_mac_vlan_filters ++ (vsi, &tmp_add_list, &tmp_del_list, ++ vlan_filters, pf->vf[vsi->vf_id].trusted); + + hlist_for_each_entry(new, &tmp_add_list, hlist) + netdev_hw_addr_refcnt(new->f, vsi->netdev, 1); +@@ -2656,7 +2768,8 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) + } + + /* if the VF is not trusted do not do promisc */ +- if ((vsi->type == I40E_VSI_SRIOV) && !pf->vf[vsi->vf_id].trusted) { ++ if (vsi->type == I40E_VSI_SRIOV && pf->vf && ++ !pf->vf[vsi->vf_id].trusted) { + clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state); + goto out; + } +@@ -2915,8 +3028,21 @@ int i40e_add_vlan_all_mac(struct i40e_vsi *vsi, s16 vid) + int bkt; + + hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) { +- if (f->state == I40E_FILTER_REMOVE) ++ /* If we're asked to add a filter that has been marked for ++ * removal, it is safe to simply restore it to active state. ++ * __i40e_del_filter will have simply deleted any filters which ++ * were previously marked NEW or FAILED, so if it is currently ++ * marked REMOVE it must have previously been ACTIVE. Since we ++ * haven't yet run the sync filters task, just restore this ++ * filter to the ACTIVE state so that the sync task leaves it ++ * in place. ++ */ ++ if (f->state == I40E_FILTER_REMOVE && f->vlan == vid) { ++ f->state = I40E_FILTER_ACTIVE; ++ continue; ++ } else if (f->state == I40E_FILTER_REMOVE) { + continue; ++ } + add_f = i40e_add_filter(vsi, f->macaddr, vid); + if (!add_f) { + dev_info(&vsi->back->pdev->dev, +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 46758bbcb04f4..7950b18cb7a41 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -4372,9 +4372,8 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, + /* duplicate request, so just return success */ + goto error_pvid; + +- i40e_vc_reset_vf(vf, true); +- /* During reset the VF got a new VSI, so refresh a pointer. */ +- vsi = pf->vsi[vf->lan_vsi_idx]; ++ i40e_vlan_stripping_enable(vsi); ++ + /* Locked once because multiple functions below iterate list */ + spin_lock_bh(&vsi->mac_filter_hash_lock); + +@@ -4387,7 +4386,7 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, + * MAC addresses deleted. + */ + if ((!(vlan_id || qos) || +- vlanprio != le16_to_cpu(vsi->info.pvid)) && ++ vlanprio != le16_to_cpu(vsi->info.pvid)) && + vsi->info.pvid) { + ret = i40e_add_vlan_all_mac(vsi, I40E_VLAN_ANY); + if (ret) { +@@ -4460,6 +4459,10 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, + */ + vf->port_vlan_id = le16_to_cpu(vsi->info.pvid); + ++ i40e_vc_reset_vf(vf, true); ++ /* During reset the VF got a new VSI, so refresh a pointer. */ ++ vsi = pf->vsi[vf->lan_vsi_idx]; ++ + ret = i40e_config_vf_promiscuous_mode(vf, vsi->id, allmulti, alluni); + if (ret) { + dev_err(&pf->pdev->dev, "Unable to config vf promiscuous mode\n"); +@@ -4750,6 +4753,11 @@ int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting) + goto out; + + vf->trusted = setting; ++ ++ /* request PF to sync mac/vlan filters for the VF */ ++ set_bit(__I40E_MACVLAN_SYNC_PENDING, pf->state); ++ pf->vsi[vf->lan_vsi_idx]->flags |= I40E_VSI_FLAG_FILTER_CHANGED; ++ + i40e_vc_reset_vf(vf, true); + dev_info(&pf->pdev->dev, "VF %u is now %strusted\n", + vf_id, setting ? "" : "un"); +diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c +index a87f4f1ae6845..41b8ff0d4df5e 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_main.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c +@@ -1142,7 +1142,8 @@ void iavf_down(struct iavf_adapter *adapter) + iavf_clear_fdir_filters(adapter); + iavf_clear_adv_rss_conf(adapter); + +- if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) { ++ if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) && ++ !(test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))) { + /* cancel any current operation */ + adapter->current_op = VIRTCHNL_OP_UNKNOWN; + /* Schedule operations to close down the HW. Don't wait +diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c +index 859ddc07fbbfe..17cb4c13d0020 100644 +--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c ++++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c +@@ -861,6 +861,18 @@ static void igc_ethtool_get_stats(struct net_device *netdev, + spin_unlock(&adapter->stats64_lock); + } + ++static int igc_ethtool_get_previous_rx_coalesce(struct igc_adapter *adapter) ++{ ++ return (adapter->rx_itr_setting <= 3) ? ++ adapter->rx_itr_setting : adapter->rx_itr_setting >> 2; ++} ++ ++static int igc_ethtool_get_previous_tx_coalesce(struct igc_adapter *adapter) ++{ ++ return (adapter->tx_itr_setting <= 3) ? ++ adapter->tx_itr_setting : adapter->tx_itr_setting >> 2; ++} ++ + static int igc_ethtool_get_coalesce(struct net_device *netdev, + struct ethtool_coalesce *ec, + struct kernel_ethtool_coalesce *kernel_coal, +@@ -868,17 +880,8 @@ static int igc_ethtool_get_coalesce(struct net_device *netdev, + { + struct igc_adapter *adapter = netdev_priv(netdev); + +- if (adapter->rx_itr_setting <= 3) +- ec->rx_coalesce_usecs = adapter->rx_itr_setting; +- else +- ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2; +- +- if (!(adapter->flags & IGC_FLAG_QUEUE_PAIRS)) { +- if (adapter->tx_itr_setting <= 3) +- ec->tx_coalesce_usecs = adapter->tx_itr_setting; +- else +- ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2; +- } ++ ec->rx_coalesce_usecs = igc_ethtool_get_previous_rx_coalesce(adapter); ++ ec->tx_coalesce_usecs = igc_ethtool_get_previous_tx_coalesce(adapter); + + return 0; + } +@@ -903,8 +906,12 @@ static int igc_ethtool_set_coalesce(struct net_device *netdev, + ec->tx_coalesce_usecs == 2) + return -EINVAL; + +- if ((adapter->flags & IGC_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs) ++ if ((adapter->flags & IGC_FLAG_QUEUE_PAIRS) && ++ ec->tx_coalesce_usecs != igc_ethtool_get_previous_tx_coalesce(adapter)) { ++ NL_SET_ERR_MSG_MOD(extack, ++ "Queue Pair mode enabled, both Rx and Tx coalescing controlled by rx-usecs"); + return -EINVAL; ++ } + + /* If ITR is disabled, disable DMAC */ + if (ec->rx_coalesce_usecs == 0) { +diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c +index a8c24a1c12b43..6185566fbb98c 100644 +--- a/drivers/net/ethernet/intel/igc/igc_main.c ++++ b/drivers/net/ethernet/intel/igc/igc_main.c +@@ -6271,7 +6271,7 @@ static int igc_xdp_xmit(struct net_device *dev, int num_frames, + struct igc_ring *ring; + int i, drops; + +- if (unlikely(test_bit(__IGC_DOWN, &adapter->state))) ++ if (unlikely(!netif_carrier_ok(dev))) + return -ENETDOWN; + + if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h +index 922bb6c9e01d5..676c58dc19817 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h ++++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h +@@ -174,6 +174,7 @@ typedef void (*ionic_desc_cb)(struct ionic_queue *q, + struct ionic_desc_info *desc_info, + struct ionic_cq_info *cq_info, void *cb_arg); + ++#define IONIC_MAX_BUF_LEN ((u16)-1) + #define IONIC_PAGE_SIZE PAGE_SIZE + #define IONIC_PAGE_SPLIT_SZ (PAGE_SIZE / 2) + #define IONIC_PAGE_GFP_MASK (GFP_ATOMIC | __GFP_NOWARN |\ +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +index 376f97b4008bb..6604f5862f892 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +@@ -151,7 +151,8 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue *q, + return NULL; + } + +- frag_len = min_t(u16, len, IONIC_PAGE_SIZE - buf_info->page_offset); ++ frag_len = min_t(u16, len, min_t(u32, IONIC_MAX_BUF_LEN, ++ IONIC_PAGE_SIZE - buf_info->page_offset)); + len -= frag_len; + + dma_sync_single_for_cpu(dev, +@@ -388,7 +389,8 @@ void ionic_rx_fill(struct ionic_queue *q) + + /* fill main descriptor - buf[0] */ + desc->addr = cpu_to_le64(buf_info->dma_addr + buf_info->page_offset); +- frag_len = min_t(u16, len, IONIC_PAGE_SIZE - buf_info->page_offset); ++ frag_len = min_t(u16, len, min_t(u32, IONIC_MAX_BUF_LEN, ++ IONIC_PAGE_SIZE - buf_info->page_offset)); + desc->len = cpu_to_le16(frag_len); + remain_len -= frag_len; + buf_info++; +@@ -407,7 +409,9 @@ void ionic_rx_fill(struct ionic_queue *q) + } + + sg_elem->addr = cpu_to_le64(buf_info->dma_addr + buf_info->page_offset); +- frag_len = min_t(u16, remain_len, IONIC_PAGE_SIZE - buf_info->page_offset); ++ frag_len = min_t(u16, remain_len, min_t(u32, IONIC_MAX_BUF_LEN, ++ IONIC_PAGE_SIZE - ++ buf_info->page_offset)); + sg_elem->len = cpu_to_le16(frag_len); + remain_len -= frag_len; + buf_info++; +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index f99df92d211e2..44275094906c0 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -2122,7 +2122,12 @@ static const struct ethtool_ops team_ethtool_ops = { + static void team_setup_by_port(struct net_device *dev, + struct net_device *port_dev) + { +- dev->header_ops = port_dev->header_ops; ++ struct team *team = netdev_priv(dev); ++ ++ if (port_dev->type == ARPHRD_ETHER) ++ dev->header_ops = team->header_ops_cache; ++ else ++ dev->header_ops = port_dev->header_ops; + dev->type = port_dev->type; + dev->hard_header_len = port_dev->hard_header_len; + dev->needed_headroom = port_dev->needed_headroom; +@@ -2169,8 +2174,11 @@ static int team_dev_type_check_change(struct net_device *dev, + + static void team_setup(struct net_device *dev) + { ++ struct team *team = netdev_priv(dev); ++ + ether_setup(dev); + dev->max_mtu = ETH_MAX_MTU; ++ team->header_ops_cache = dev->header_ops; + + dev->netdev_ops = &team_netdev_ops; + dev->ethtool_ops = &team_ethtool_ops; +diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c +index 3395dcb0b262b..470852f7a64d1 100644 +--- a/drivers/net/thunderbolt.c ++++ b/drivers/net/thunderbolt.c +@@ -993,12 +993,11 @@ static bool tbnet_xmit_csum_and_map(struct tbnet *net, struct sk_buff *skb, + *tucso = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, 0, + ip_hdr(skb)->protocol, 0); +- } else if (skb_is_gso_v6(skb)) { ++ } else if (skb_is_gso(skb) && skb_is_gso_v6(skb)) { + tucso = dest + ((void *)&(tcp_hdr(skb)->check) - data); + *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, 0, + IPPROTO_TCP, 0); +- return false; + } else if (protocol == htons(ETH_P_IPV6)) { + tucso = dest + skb_checksum_start_offset(skb) + skb->csum_offset; + *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index bb3813e8474f4..65172a654a198 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -384,14 +384,6 @@ static int nvme_pci_npages_sgl(void) + NVME_CTRL_PAGE_SIZE); + } + +-static size_t nvme_pci_iod_alloc_size(void) +-{ +- size_t npages = max(nvme_pci_npages_prp(), nvme_pci_npages_sgl()); +- +- return sizeof(__le64 *) * npages + +- sizeof(struct scatterlist) * NVME_MAX_SEGS; +-} +- + static int nvme_admin_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, + unsigned int hctx_idx) + { +@@ -2662,6 +2654,22 @@ static void nvme_release_prp_pools(struct nvme_dev *dev) + dma_pool_destroy(dev->prp_small_pool); + } + ++static int nvme_pci_alloc_iod_mempool(struct nvme_dev *dev) ++{ ++ size_t npages = max(nvme_pci_npages_prp(), nvme_pci_npages_sgl()); ++ size_t alloc_size = sizeof(__le64 *) * npages + ++ sizeof(struct scatterlist) * NVME_MAX_SEGS; ++ ++ WARN_ON_ONCE(alloc_size > PAGE_SIZE); ++ dev->iod_mempool = mempool_create_node(1, ++ mempool_kmalloc, mempool_kfree, ++ (void *)alloc_size, GFP_KERNEL, ++ dev_to_node(dev->dev)); ++ if (!dev->iod_mempool) ++ return -ENOMEM; ++ return 0; ++} ++ + static void nvme_free_tagset(struct nvme_dev *dev) + { + if (dev->tagset.tags) +@@ -2669,6 +2677,7 @@ static void nvme_free_tagset(struct nvme_dev *dev) + dev->ctrl.tagset = NULL; + } + ++/* pairs with nvme_pci_alloc_dev */ + static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl) + { + struct nvme_dev *dev = to_nvme_dev(ctrl); +@@ -2958,20 +2967,20 @@ static void nvme_async_probe(void *data, async_cookie_t cookie) + nvme_put_ctrl(&dev->ctrl); + } + +-static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) ++static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev, ++ const struct pci_device_id *id) + { +- int node, result = -ENOMEM; +- struct nvme_dev *dev; + unsigned long quirks = id->driver_data; +- size_t alloc_size; +- +- node = dev_to_node(&pdev->dev); +- if (node == NUMA_NO_NODE) +- set_dev_node(&pdev->dev, first_memory_node); ++ int node = dev_to_node(&pdev->dev); ++ struct nvme_dev *dev; ++ int ret = -ENOMEM; + + dev = kzalloc_node(sizeof(*dev), GFP_KERNEL, node); + if (!dev) +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); ++ INIT_WORK(&dev->ctrl.reset_work, nvme_reset_work); ++ INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work); ++ mutex_init(&dev->shutdown_lock); + + dev->nr_write_queues = write_queues; + dev->nr_poll_queues = poll_queues; +@@ -2979,25 +2988,11 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) + dev->queues = kcalloc_node(dev->nr_allocated_queues, + sizeof(struct nvme_queue), GFP_KERNEL, node); + if (!dev->queues) +- goto free; ++ goto out_free_dev; + + dev->dev = get_device(&pdev->dev); +- pci_set_drvdata(pdev, dev); +- +- result = nvme_dev_map(dev); +- if (result) +- goto put_pci; +- +- INIT_WORK(&dev->ctrl.reset_work, nvme_reset_work); +- INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work); +- mutex_init(&dev->shutdown_lock); +- +- result = nvme_setup_prp_pools(dev); +- if (result) +- goto unmap; + + quirks |= check_vendor_combination_bug(pdev); +- + if (!noacpi && acpi_storage_d3(&pdev->dev)) { + /* + * Some systems use a bios work around to ask for D3 on +@@ -3007,46 +3002,54 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) + "platform quirk: setting simple suspend\n"); + quirks |= NVME_QUIRK_SIMPLE_SUSPEND; + } ++ ret = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops, ++ quirks); ++ if (ret) ++ goto out_put_device; ++ return dev; + +- /* +- * Double check that our mempool alloc size will cover the biggest +- * command we support. +- */ +- alloc_size = nvme_pci_iod_alloc_size(); +- WARN_ON_ONCE(alloc_size > PAGE_SIZE); ++out_put_device: ++ put_device(dev->dev); ++ kfree(dev->queues); ++out_free_dev: ++ kfree(dev); ++ return ERR_PTR(ret); ++} + +- dev->iod_mempool = mempool_create_node(1, mempool_kmalloc, +- mempool_kfree, +- (void *) alloc_size, +- GFP_KERNEL, node); +- if (!dev->iod_mempool) { +- result = -ENOMEM; +- goto release_pools; +- } ++static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) ++{ ++ struct nvme_dev *dev; ++ int result = -ENOMEM; ++ ++ dev = nvme_pci_alloc_dev(pdev, id); ++ if (IS_ERR(dev)) ++ return PTR_ERR(dev); ++ ++ result = nvme_dev_map(dev); ++ if (result) ++ goto out_uninit_ctrl; ++ ++ result = nvme_setup_prp_pools(dev); ++ if (result) ++ goto out_dev_unmap; + +- result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops, +- quirks); ++ result = nvme_pci_alloc_iod_mempool(dev); + if (result) +- goto release_mempool; ++ goto out_release_prp_pools; + + dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev)); ++ pci_set_drvdata(pdev, dev); + + nvme_reset_ctrl(&dev->ctrl); + async_schedule(nvme_async_probe, dev); +- + return 0; + +- release_mempool: +- mempool_destroy(dev->iod_mempool); +- release_pools: ++out_release_prp_pools: + nvme_release_prp_pools(dev); +- unmap: ++out_dev_unmap: + nvme_dev_unmap(dev); +- put_pci: +- put_device(dev->dev); +- free: +- kfree(dev->queues); +- kfree(dev); ++out_uninit_ctrl: ++ nvme_uninit_ctrl(&dev->ctrl); + return result; + } + +diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c +index 93ea922618c3d..56562ae99f683 100644 +--- a/drivers/parisc/iosapic.c ++++ b/drivers/parisc/iosapic.c +@@ -202,9 +202,9 @@ static inline void iosapic_write(void __iomem *iosapic, unsigned int reg, u32 va + + static DEFINE_SPINLOCK(iosapic_lock); + +-static inline void iosapic_eoi(void __iomem *addr, unsigned int data) ++static inline void iosapic_eoi(__le32 __iomem *addr, __le32 data) + { +- __raw_writel(data, addr); ++ __raw_writel((__force u32)data, addr); + } + + /* +diff --git a/drivers/parisc/iosapic_private.h b/drivers/parisc/iosapic_private.h +index 73ecc657ad954..bd8ff40162b4b 100644 +--- a/drivers/parisc/iosapic_private.h ++++ b/drivers/parisc/iosapic_private.h +@@ -118,8 +118,8 @@ struct iosapic_irt { + struct vector_info { + struct iosapic_info *iosapic; /* I/O SAPIC this vector is on */ + struct irt_entry *irte; /* IRT entry */ +- u32 __iomem *eoi_addr; /* precalculate EOI reg address */ +- u32 eoi_data; /* IA64: ? PA: swapped txn_data */ ++ __le32 __iomem *eoi_addr; /* precalculate EOI reg address */ ++ __le32 eoi_data; /* IA64: ? PA: swapped txn_data */ + int txn_irq; /* virtual IRQ number for processor */ + ulong txn_addr; /* IA64: id_eid PA: partial HPA */ + u32 txn_data; /* CPU interrupt bit */ +diff --git a/drivers/platform/mellanox/Kconfig b/drivers/platform/mellanox/Kconfig +index edd17e1a1f88f..a57ae5cbc00a8 100644 +--- a/drivers/platform/mellanox/Kconfig ++++ b/drivers/platform/mellanox/Kconfig +@@ -48,6 +48,7 @@ config MLXBF_BOOTCTL + tristate "Mellanox BlueField Firmware Boot Control driver" + depends on ARM64 + depends on ACPI ++ depends on NET + help + The Mellanox BlueField firmware implements functionality to + request swapping the primary and alternate eMMC boot partition, +diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c +index e7a3e34028178..189c5460edd81 100644 +--- a/drivers/platform/x86/intel_scu_ipc.c ++++ b/drivers/platform/x86/intel_scu_ipc.c +@@ -19,6 +19,7 @@ + #include <linux/init.h> + #include <linux/interrupt.h> + #include <linux/io.h> ++#include <linux/iopoll.h> + #include <linux/module.h> + #include <linux/slab.h> + +@@ -232,19 +233,15 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset) + /* Wait till scu status is busy */ + static inline int busy_loop(struct intel_scu_ipc_dev *scu) + { +- unsigned long end = jiffies + IPC_TIMEOUT; +- +- do { +- u32 status; +- +- status = ipc_read_status(scu); +- if (!(status & IPC_STATUS_BUSY)) +- return (status & IPC_STATUS_ERR) ? -EIO : 0; ++ u8 status; ++ int err; + +- usleep_range(50, 100); +- } while (time_before(jiffies, end)); ++ err = readx_poll_timeout(ipc_read_status, scu, status, !(status & IPC_STATUS_BUSY), ++ 100, jiffies_to_usecs(IPC_TIMEOUT)); ++ if (err) ++ return err; + +- return -ETIMEDOUT; ++ return (status & IPC_STATUS_ERR) ? -EIO : 0; + } + + /* Wait till ipc ioc interrupt is received or timeout in 10 HZ */ +@@ -252,10 +249,12 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu) + { + int status; + +- if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT)) +- return -ETIMEDOUT; ++ wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT); + + status = ipc_read_status(scu); ++ if (status & IPC_STATUS_BUSY) ++ return -ETIMEDOUT; ++ + if (status & IPC_STATUS_ERR) + return -EIO; + +@@ -267,6 +266,24 @@ static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu) + return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu); + } + ++static struct intel_scu_ipc_dev *intel_scu_ipc_get(struct intel_scu_ipc_dev *scu) ++{ ++ u8 status; ++ ++ if (!scu) ++ scu = ipcdev; ++ if (!scu) ++ return ERR_PTR(-ENODEV); ++ ++ status = ipc_read_status(scu); ++ if (status & IPC_STATUS_BUSY) { ++ dev_dbg(&scu->dev, "device is busy\n"); ++ return ERR_PTR(-EBUSY); ++ } ++ ++ return scu; ++} ++ + /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ + static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, + u32 count, u32 op, u32 id) +@@ -280,11 +297,10 @@ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, + memset(cbuf, 0, sizeof(cbuf)); + + mutex_lock(&ipclock); +- if (!scu) +- scu = ipcdev; +- if (!scu) { ++ scu = intel_scu_ipc_get(scu); ++ if (IS_ERR(scu)) { + mutex_unlock(&ipclock); +- return -ENODEV; ++ return PTR_ERR(scu); + } + + for (nc = 0; nc < count; nc++, offset += 2) { +@@ -439,13 +455,12 @@ int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd, + int err; + + mutex_lock(&ipclock); +- if (!scu) +- scu = ipcdev; +- if (!scu) { ++ scu = intel_scu_ipc_get(scu); ++ if (IS_ERR(scu)) { + mutex_unlock(&ipclock); +- return -ENODEV; ++ return PTR_ERR(scu); + } +- scu = ipcdev; ++ + cmdval = sub << 12 | cmd; + ipc_command(scu, cmdval); + err = intel_scu_ipc_check_status(scu); +@@ -485,11 +500,10 @@ int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd, + return -EINVAL; + + mutex_lock(&ipclock); +- if (!scu) +- scu = ipcdev; +- if (!scu) { ++ scu = intel_scu_ipc_get(scu); ++ if (IS_ERR(scu)) { + mutex_unlock(&ipclock); +- return -ENODEV; ++ return PTR_ERR(scu); + } + + memcpy(inbuf, in, inlen); +diff --git a/drivers/power/supply/ucs1002_power.c b/drivers/power/supply/ucs1002_power.c +index ef673ec3db568..332cb50d9fb4f 100644 +--- a/drivers/power/supply/ucs1002_power.c ++++ b/drivers/power/supply/ucs1002_power.c +@@ -384,7 +384,8 @@ static int ucs1002_get_property(struct power_supply *psy, + case POWER_SUPPLY_PROP_USB_TYPE: + return ucs1002_get_usb_type(info, val); + case POWER_SUPPLY_PROP_HEALTH: +- return val->intval = info->health; ++ val->intval = info->health; ++ return 0; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = info->present; + return 0; +diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c +index 32fc450bf84b4..352705e023c83 100644 +--- a/drivers/scsi/pm8001/pm8001_hwi.c ++++ b/drivers/scsi/pm8001/pm8001_hwi.c +@@ -4402,7 +4402,7 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) + payload.sas_identify.dev_type = SAS_END_DEVICE; + payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; + memcpy(payload.sas_identify.sas_addr, +- pm8001_ha->sas_addr, SAS_ADDR_SIZE); ++ &pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE); + payload.sas_identify.phy_id = phy_id; + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, + sizeof(payload), 0); +diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c +index 04746df26c6c9..d37b1bdb29b49 100644 +--- a/drivers/scsi/pm8001/pm80xx_hwi.c ++++ b/drivers/scsi/pm8001/pm80xx_hwi.c +@@ -3793,10 +3793,12 @@ static int mpi_set_controller_config_resp(struct pm8001_hba_info *pm8001_ha, + (struct set_ctrl_cfg_resp *)(piomb + 4); + u32 status = le32_to_cpu(pPayload->status); + u32 err_qlfr_pgcd = le32_to_cpu(pPayload->err_qlfr_pgcd); ++ u32 tag = le32_to_cpu(pPayload->tag); + + pm8001_dbg(pm8001_ha, MSG, + "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n", + status, err_qlfr_pgcd); ++ pm8001_tag_free(pm8001_ha, tag); + + return 0; + } +@@ -4814,7 +4816,7 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) + payload.sas_identify.dev_type = SAS_END_DEVICE; + payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; + memcpy(payload.sas_identify.sas_addr, +- &pm8001_ha->sas_addr, SAS_ADDR_SIZE); ++ &pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE); + payload.sas_identify.phy_id = phy_id; + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, + sizeof(payload), 0); +diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c +index bb5761ed3f511..a1a1f4e466609 100644 +--- a/drivers/scsi/qedf/qedf_io.c ++++ b/drivers/scsi/qedf/qedf_io.c +@@ -1913,6 +1913,7 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) + goto drop_rdata_kref; + } + ++ spin_lock_irqsave(&fcport->rport_lock, flags); + if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || + test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || + test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { +@@ -1920,17 +1921,20 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) + "io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n", + io_req->xid, io_req->sc_cmd); + rc = 1; ++ spin_unlock_irqrestore(&fcport->rport_lock, flags); + goto drop_rdata_kref; + } + ++ /* Set the command type to abort */ ++ io_req->cmd_type = QEDF_ABTS; ++ spin_unlock_irqrestore(&fcport->rport_lock, flags); ++ + kref_get(&io_req->refcount); + + xid = io_req->xid; + qedf->control_requests++; + qedf->packet_aborts++; + +- /* Set the command type to abort */ +- io_req->cmd_type = QEDF_ABTS; + io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; + + set_bit(QEDF_CMD_IN_ABORT, &io_req->flags); +@@ -2219,7 +2223,9 @@ process_els: + refcount, fcport, fcport->rdata->ids.port_id); + + /* Cleanup cmds re-use the same TID as the original I/O */ ++ spin_lock_irqsave(&fcport->rport_lock, flags); + io_req->cmd_type = QEDF_CLEANUP; ++ spin_unlock_irqrestore(&fcport->rport_lock, flags); + io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; + + init_completion(&io_req->cleanup_done); +diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c +index 61959dd2237fc..18380a932ab61 100644 +--- a/drivers/scsi/qedf/qedf_main.c ++++ b/drivers/scsi/qedf/qedf_main.c +@@ -2807,6 +2807,8 @@ void qedf_process_cqe(struct qedf_ctx *qedf, struct fcoe_cqe *cqe) + struct qedf_ioreq *io_req; + struct qedf_rport *fcport; + u32 comp_type; ++ u8 io_comp_type; ++ unsigned long flags; + + comp_type = (cqe->cqe_data >> FCOE_CQE_CQE_TYPE_SHIFT) & + FCOE_CQE_CQE_TYPE_MASK; +@@ -2840,11 +2842,14 @@ void qedf_process_cqe(struct qedf_ctx *qedf, struct fcoe_cqe *cqe) + return; + } + ++ spin_lock_irqsave(&fcport->rport_lock, flags); ++ io_comp_type = io_req->cmd_type; ++ spin_unlock_irqrestore(&fcport->rport_lock, flags); + + switch (comp_type) { + case FCOE_GOOD_COMPLETION_CQE_TYPE: + atomic_inc(&fcport->free_sqes); +- switch (io_req->cmd_type) { ++ switch (io_comp_type) { + case QEDF_SCSI_CMD: + qedf_scsi_completion(qedf, cqe, io_req); + break; +diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h +index d70c2f4ba718e..3c876967e8b16 100644 +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -3461,6 +3461,7 @@ struct qla_msix_entry { + int have_irq; + int in_use; + uint32_t vector; ++ uint32_t vector_base0; + uint16_t entry; + char name[30]; + void *handle; +@@ -3790,6 +3791,7 @@ struct qla_qpair { + uint64_t retry_term_jiff; + struct qla_tgt_counters tgt_counters; + uint16_t cpuid; ++ bool cpu_mapped; + struct qla_fw_resources fwres ____cacheline_aligned; + u32 cmd_cnt; + u32 cmd_completion_cnt; +@@ -4119,6 +4121,7 @@ struct qla_hw_data { + struct req_que **req_q_map; + struct rsp_que **rsp_q_map; + struct qla_qpair **queue_pair_map; ++ struct qla_qpair **qp_cpu_map; + unsigned long req_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)]; + unsigned long rsp_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)]; + unsigned long qpair_qid_map[(QLA_MAX_QUEUES / 8) +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index 1a2ceef92bf07..b59d5b560a278 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -9779,8 +9779,9 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, + qpair->req = ha->req_q_map[req_id]; + qpair->rsp->req = qpair->req; + qpair->rsp->qpair = qpair; +- /* init qpair to this cpu. Will adjust at run time. */ +- qla_cpu_update(qpair, raw_smp_processor_id()); ++ ++ if (!qpair->cpu_mapped) ++ qla_cpu_update(qpair, raw_smp_processor_id()); + + if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { + if (ha->fw_attributes & BIT_4) +diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h +index a7b5d11146827..a4a56ab0ba747 100644 +--- a/drivers/scsi/qla2xxx/qla_inline.h ++++ b/drivers/scsi/qla2xxx/qla_inline.h +@@ -573,3 +573,61 @@ fcport_is_bigger(fc_port_t *fcport) + { + return !fcport_is_smaller(fcport); + } ++ ++static inline struct qla_qpair * ++qla_mapq_nvme_select_qpair(struct qla_hw_data *ha, struct qla_qpair *qpair) ++{ ++ int cpuid = raw_smp_processor_id(); ++ ++ if (qpair->cpuid != cpuid && ++ ha->qp_cpu_map[cpuid]) { ++ qpair = ha->qp_cpu_map[cpuid]; ++ } ++ return qpair; ++} ++ ++static inline void ++qla_mapq_init_qp_cpu_map(struct qla_hw_data *ha, ++ struct qla_msix_entry *msix, ++ struct qla_qpair *qpair) ++{ ++ const struct cpumask *mask; ++ unsigned int cpu; ++ ++ if (!ha->qp_cpu_map) ++ return; ++ mask = pci_irq_get_affinity(ha->pdev, msix->vector_base0); ++ if (!mask) ++ return; ++ qpair->cpuid = cpumask_first(mask); ++ for_each_cpu(cpu, mask) { ++ ha->qp_cpu_map[cpu] = qpair; ++ } ++ msix->cpuid = qpair->cpuid; ++ qpair->cpu_mapped = true; ++} ++ ++static inline void ++qla_mapq_free_qp_cpu_map(struct qla_hw_data *ha) ++{ ++ if (ha->qp_cpu_map) { ++ kfree(ha->qp_cpu_map); ++ ha->qp_cpu_map = NULL; ++ } ++} ++ ++static inline int qla_mapq_alloc_qp_cpu_map(struct qla_hw_data *ha) ++{ ++ scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); ++ ++ if (!ha->qp_cpu_map) { ++ ha->qp_cpu_map = kcalloc(NR_CPUS, sizeof(struct qla_qpair *), ++ GFP_KERNEL); ++ if (!ha->qp_cpu_map) { ++ ql_log(ql_log_fatal, vha, 0x0180, ++ "Unable to allocate memory for qp_cpu_map ptrs.\n"); ++ return -1; ++ } ++ } ++ return 0; ++} +diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c +index 80c2dcf567b0c..51e906fa8694e 100644 +--- a/drivers/scsi/qla2xxx/qla_isr.c ++++ b/drivers/scsi/qla2xxx/qla_isr.c +@@ -3780,9 +3780,11 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, + if (!ha->flags.fw_started) + return; + +- if (rsp->qpair->cpuid != smp_processor_id() || !rsp->qpair->rcv_intr) { ++ if (rsp->qpair->cpuid != raw_smp_processor_id() || !rsp->qpair->rcv_intr) { + rsp->qpair->rcv_intr = 1; +- qla_cpu_update(rsp->qpair, smp_processor_id()); ++ ++ if (!rsp->qpair->cpu_mapped) ++ qla_cpu_update(rsp->qpair, raw_smp_processor_id()); + } + + #define __update_rsp_in(_update, _is_shadow_hba, _rsp, _rsp_in) \ +@@ -4277,7 +4279,7 @@ qla2xxx_msix_rsp_q(int irq, void *dev_id) + } + ha = qpair->hw; + +- queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); ++ queue_work(ha->wq, &qpair->q_work); + + return IRQ_HANDLED; + } +@@ -4303,7 +4305,7 @@ qla2xxx_msix_rsp_q_hs(int irq, void *dev_id) + wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); + spin_unlock_irqrestore(&ha->hardware_lock, flags); + +- queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); ++ queue_work(ha->wq, &qpair->q_work); + + return IRQ_HANDLED; + } +@@ -4396,6 +4398,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) + for (i = 0; i < ha->msix_count; i++) { + qentry = &ha->msix_entries[i]; + qentry->vector = pci_irq_vector(ha->pdev, i); ++ qentry->vector_base0 = i; + qentry->entry = i; + qentry->have_irq = 0; + qentry->in_use = 0; +@@ -4623,5 +4626,6 @@ int qla25xx_request_irq(struct qla_hw_data *ha, struct qla_qpair *qpair, + } + msix->have_irq = 1; + msix->handle = qpair; ++ qla_mapq_init_qp_cpu_map(ha, msix, qpair); + return ret; + } +diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c +index f535f478e37c8..088e84042efc7 100644 +--- a/drivers/scsi/qla2xxx/qla_nvme.c ++++ b/drivers/scsi/qla2xxx/qla_nvme.c +@@ -598,6 +598,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, + fc_port_t *fcport; + struct srb_iocb *nvme; + struct scsi_qla_host *vha; ++ struct qla_hw_data *ha; + int rval; + srb_t *sp; + struct qla_qpair *qpair = hw_queue_handle; +@@ -618,6 +619,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, + return -ENODEV; + + vha = fcport->vha; ++ ha = vha->hw; + + if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) + return -EBUSY; +@@ -632,6 +634,8 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, + if (fcport->nvme_flag & NVME_FLAG_RESETTING) + return -EBUSY; + ++ qpair = qla_mapq_nvme_select_qpair(ha, qpair); ++ + /* Alloc SRB structure */ + sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC); + if (!sp) +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index a40af9b832ab4..1b175e5c0cfcc 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -467,6 +467,11 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, + "Unable to allocate memory for queue pair ptrs.\n"); + goto fail_qpair_map; + } ++ if (qla_mapq_alloc_qp_cpu_map(ha) != 0) { ++ kfree(ha->queue_pair_map); ++ ha->queue_pair_map = NULL; ++ goto fail_qpair_map; ++ } + } + + /* +@@ -541,6 +546,7 @@ static void qla2x00_free_queues(struct qla_hw_data *ha) + ha->base_qpair = NULL; + } + ++ qla_mapq_free_qp_cpu_map(ha); + spin_lock_irqsave(&ha->hardware_lock, flags); + for (cnt = 0; cnt < ha->max_req_queues; cnt++) { + if (!test_bit(cnt, ha->req_qid_map)) +diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c +index 2ce041fdec755..ef46dce73978a 100644 +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -4459,8 +4459,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, + queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, &cmd->work); + } else if (ha->msix_count) { + if (cmd->atio.u.isp24.fcp_cmnd.rddata) +- queue_work_on(smp_processor_id(), qla_tgt_wq, +- &cmd->work); ++ queue_work(qla_tgt_wq, &cmd->work); + else + queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, + &cmd->work); +diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c +index 03de1bcf1461d..b3852be971e46 100644 +--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c ++++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c +@@ -310,7 +310,7 @@ static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd) + cmd->trc_flags |= TRC_CMD_DONE; + + INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free); +- queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); ++ queue_work(tcm_qla2xxx_free_wq, &cmd->work); + } + + /* +@@ -557,7 +557,7 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) + cmd->trc_flags |= TRC_DATA_IN; + cmd->cmd_in_wq = 1; + INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work); +- queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); ++ queue_work(tcm_qla2xxx_free_wq, &cmd->work); + } + + static int tcm_qla2xxx_chk_dif_tags(uint32_t tag) +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index d00d263705e15..f48036f09eab5 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -2309,7 +2309,6 @@ __ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd, + bool completion) + { + lockdep_assert_held(&hba->uic_cmd_mutex); +- lockdep_assert_held(hba->host->host_lock); + + if (!ufshcd_ready_for_uic_cmd(hba)) { + dev_err(hba->dev, +@@ -2336,15 +2335,12 @@ __ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd, + int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) + { + int ret; +- unsigned long flags; + + ufshcd_hold(hba, false); + mutex_lock(&hba->uic_cmd_mutex); + ufshcd_add_delay_before_dme_cmd(hba); + +- spin_lock_irqsave(hba->host->host_lock, flags); + ret = __ufshcd_send_uic_cmd(hba, uic_cmd, true); +- spin_unlock_irqrestore(hba->host->host_lock, flags); + if (!ret) + ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd); + +@@ -3967,8 +3963,8 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) + wmb(); + reenable_intr = true; + } +- ret = __ufshcd_send_uic_cmd(hba, cmd, false); + spin_unlock_irqrestore(hba->host->host_lock, flags); ++ ret = __ufshcd_send_uic_cmd(hba, cmd, false); + if (ret) { + dev_err(hba->dev, + "pwr ctrl cmd 0x%x with mode 0x%x uic error %d\n", +diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c +index 32ed9dc88e455..08197b03955dd 100644 +--- a/drivers/soc/imx/soc-imx8m.c ++++ b/drivers/soc/imx/soc-imx8m.c +@@ -100,6 +100,7 @@ static void __init imx8mm_soc_uid(void) + { + void __iomem *ocotp_base; + struct device_node *np; ++ struct clk *clk; + u32 offset = of_machine_is_compatible("fsl,imx8mp") ? + IMX8MP_OCOTP_UID_OFFSET : 0; + +@@ -109,11 +110,20 @@ static void __init imx8mm_soc_uid(void) + + ocotp_base = of_iomap(np, 0); + WARN_ON(!ocotp_base); ++ clk = of_clk_get_by_name(np, NULL); ++ if (IS_ERR(clk)) { ++ WARN_ON(IS_ERR(clk)); ++ return; ++ } ++ ++ clk_prepare_enable(clk); + + soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset); + soc_uid <<= 32; + soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset); + ++ clk_disable_unprepare(clk); ++ clk_put(clk); + iounmap(ocotp_base); + of_node_put(np); + } +diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c +index 2b0301fc971c6..23e4c30e6a60a 100644 +--- a/drivers/spi/spi-nxp-fspi.c ++++ b/drivers/spi/spi-nxp-fspi.c +@@ -1029,6 +1029,13 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f) + fspi_writel(f, FSPI_AHBCR_PREF_EN | FSPI_AHBCR_RDADDROPT, + base + FSPI_AHBCR); + ++ /* Reset the FLSHxCR1 registers. */ ++ reg = FSPI_FLSHXCR1_TCSH(0x3) | FSPI_FLSHXCR1_TCSS(0x3); ++ fspi_writel(f, reg, base + FSPI_FLSHA1CR1); ++ fspi_writel(f, reg, base + FSPI_FLSHA2CR1); ++ fspi_writel(f, reg, base + FSPI_FLSHB1CR1); ++ fspi_writel(f, reg, base + FSPI_FLSHB2CR1); ++ + /* AHB Read - Set lut sequence ID for all CS. */ + fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2); + fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2); +diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c +index 3c6f201b5dd85..191baa6e45c08 100644 +--- a/drivers/spi/spi-stm32.c ++++ b/drivers/spi/spi-stm32.c +@@ -268,6 +268,7 @@ struct stm32_spi_cfg { + * @fifo_size: size of the embedded fifo in bytes + * @cur_midi: master inter-data idleness in ns + * @cur_speed: speed configured in Hz ++ * @cur_half_period: time of a half bit in us + * @cur_bpw: number of bits in a single SPI data frame + * @cur_fthlv: fifo threshold level (data frames in a single data packet) + * @cur_comm: SPI communication mode +@@ -294,6 +295,7 @@ struct stm32_spi { + + unsigned int cur_midi; + unsigned int cur_speed; ++ unsigned int cur_half_period; + unsigned int cur_bpw; + unsigned int cur_fthlv; + unsigned int cur_comm; +@@ -454,6 +456,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz, + + spi->cur_speed = spi->clk_rate / (1 << mbrdiv); + ++ spi->cur_half_period = DIV_ROUND_CLOSEST(USEC_PER_SEC, 2 * spi->cur_speed); ++ + return mbrdiv - 1; + } + +@@ -695,6 +699,10 @@ static void stm32h7_spi_disable(struct stm32_spi *spi) + return; + } + ++ /* Add a delay to make sure that transmission is ended. */ ++ if (spi->cur_half_period) ++ udelay(spi->cur_half_period); ++ + if (spi->cur_usedma && spi->dma_tx) + dmaengine_terminate_all(spi->dma_tx); + if (spi->cur_usedma && spi->dma_rx) +diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c +index 23ad052528dbe..d79853ba7792a 100644 +--- a/drivers/spi/spi-sun6i.c ++++ b/drivers/spi/spi-sun6i.c +@@ -95,6 +95,7 @@ struct sun6i_spi { + struct reset_control *rstc; + + struct completion done; ++ struct completion dma_rx_done; + + const u8 *tx_buf; + u8 *rx_buf; +@@ -189,6 +190,13 @@ static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) + return SUN6I_MAX_XFER_SIZE - 1; + } + ++static void sun6i_spi_dma_rx_cb(void *param) ++{ ++ struct sun6i_spi *sspi = param; ++ ++ complete(&sspi->dma_rx_done); ++} ++ + static int sun6i_spi_prepare_dma(struct sun6i_spi *sspi, + struct spi_transfer *tfr) + { +@@ -200,7 +208,7 @@ static int sun6i_spi_prepare_dma(struct sun6i_spi *sspi, + struct dma_slave_config rxconf = { + .direction = DMA_DEV_TO_MEM, + .src_addr = sspi->dma_addr_rx, +- .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, ++ .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, + .src_maxburst = 8, + }; + +@@ -213,6 +221,8 @@ static int sun6i_spi_prepare_dma(struct sun6i_spi *sspi, + DMA_PREP_INTERRUPT); + if (!rxdesc) + return -EINVAL; ++ rxdesc->callback_param = sspi; ++ rxdesc->callback = sun6i_spi_dma_rx_cb; + } + + txdesc = NULL; +@@ -268,6 +278,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, + return -EINVAL; + + reinit_completion(&sspi->done); ++ reinit_completion(&sspi->dma_rx_done); + sspi->tx_buf = tfr->tx_buf; + sspi->rx_buf = tfr->rx_buf; + sspi->len = tfr->len; +@@ -426,6 +437,22 @@ static int sun6i_spi_transfer_one(struct spi_master *master, + start = jiffies; + timeout = wait_for_completion_timeout(&sspi->done, + msecs_to_jiffies(tx_time)); ++ ++ if (!use_dma) { ++ sun6i_spi_drain_fifo(sspi); ++ } else { ++ if (timeout && rx_len) { ++ /* ++ * Even though RX on the peripheral side has finished ++ * RX DMA might still be in flight ++ */ ++ timeout = wait_for_completion_timeout(&sspi->dma_rx_done, ++ timeout); ++ if (!timeout) ++ dev_warn(&master->dev, "RX DMA timeout\n"); ++ } ++ } ++ + end = jiffies; + if (!timeout) { + dev_warn(&master->dev, +@@ -453,7 +480,6 @@ static irqreturn_t sun6i_spi_handler(int irq, void *dev_id) + /* Transfer complete */ + if (status & SUN6I_INT_CTL_TC) { + sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TC); +- sun6i_spi_drain_fifo(sspi); + complete(&sspi->done); + return IRQ_HANDLED; + } +@@ -611,6 +637,7 @@ static int sun6i_spi_probe(struct platform_device *pdev) + } + + init_completion(&sspi->done); ++ init_completion(&sspi->dma_rx_done); + + sspi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(sspi->rstc)) { +diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c +index 67889c0144142..c16ed6e9e49dd 100644 +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -2412,10 +2412,8 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) + gsm->has_devices = false; + } + for (i = NUM_DLCI - 1; i >= 0; i--) +- if (gsm->dlci[i]) { ++ if (gsm->dlci[i]) + gsm_dlci_release(gsm->dlci[i]); +- gsm->dlci[i] = NULL; +- } + mutex_unlock(&gsm->mutex); + /* Now wipe the queues */ + tty_ldisc_flush(gsm->tty); +diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c +index 74e477016f255..45a8f76f562e7 100644 +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -1930,7 +1930,10 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) + skip_rx = true; + + if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { +- if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) ++ struct irq_data *d; ++ ++ d = irq_get_irq_data(port->irq); ++ if (d && irqd_is_wakeup_set(d)) + pm_wakeup_event(tport->tty->dev, 0); + if (!up->dma || handle_rx_dma(up, iir)) + status = serial8250_rx_chars(up, status); +diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig +index 26531aa194282..662524574cc33 100644 +--- a/drivers/video/fbdev/Kconfig ++++ b/drivers/video/fbdev/Kconfig +@@ -2017,7 +2017,7 @@ config FB_COBALT + + config FB_SH7760 + bool "SH7760/SH7763/SH7720/SH7721 LCDC support" +- depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ ++ depends on FB=y && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ + || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA +diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c +index ced2fc0deb8c4..a8052a3faaabb 100644 +--- a/drivers/watchdog/iTCO_wdt.c ++++ b/drivers/watchdog/iTCO_wdt.c +@@ -424,6 +424,20 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev) + return time_left; + } + ++/* Returns true if the watchdog was running */ ++static bool iTCO_wdt_set_running(struct iTCO_wdt_private *p) ++{ ++ u16 val; ++ ++ /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled */ ++ val = inw(TCO1_CNT(p)); ++ if (!(val & BIT(11))) { ++ set_bit(WDOG_HW_RUNNING, &p->wddev.status); ++ return true; ++ } ++ return false; ++} ++ + /* + * Kernel Interfaces + */ +@@ -512,9 +526,6 @@ static int iTCO_wdt_probe(struct platform_device *pdev) + return -ENODEV; /* Cannot reset NO_REBOOT bit */ + } + +- /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ +- p->update_no_reboot_bit(p->no_reboot_priv, true); +- + if (turn_SMI_watchdog_clear_off >= p->iTCO_version) { + /* + * Bit 13: TCO_EN -> 0 +@@ -566,8 +577,13 @@ static int iTCO_wdt_probe(struct platform_device *pdev) + watchdog_set_drvdata(&p->wddev, p); + platform_set_drvdata(pdev, p); + +- /* Make sure the watchdog is not running */ +- iTCO_wdt_stop(&p->wddev); ++ if (!iTCO_wdt_set_running(p)) { ++ /* ++ * If the watchdog was not running set NO_REBOOT now to ++ * prevent later reboots. ++ */ ++ p->update_no_reboot_bit(p->no_reboot_priv, true); ++ } + + /* Check that the heartbeat value is within it's range; + if not reset to the default */ +diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c +index c316931fc99c5..f51f6e4d1a322 100644 +--- a/fs/binfmt_elf_fdpic.c ++++ b/fs/binfmt_elf_fdpic.c +@@ -345,10 +345,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) + /* there's now no turning back... the old userspace image is dead, + * defunct, deceased, etc. + */ ++ SET_PERSONALITY(exec_params.hdr); + if (elf_check_fdpic(&exec_params.hdr)) +- set_personality(PER_LINUX_FDPIC); +- else +- set_personality(PER_LINUX); ++ current->personality |= PER_LINUX_FDPIC; + if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) + current->personality |= READ_IMPLIES_EXEC; + +diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c +index e6872d65c0e25..fd951aeaeac5a 100644 +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -1401,9 +1401,10 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, + ret = __btrfs_add_delayed_insertion_item(delayed_node, delayed_item); + if (unlikely(ret)) { + btrfs_err(trans->fs_info, +- "err add delayed dir index item(name: %.*s) into the insertion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)", +- name_len, name, delayed_node->root->root_key.objectid, +- delayed_node->inode_id, ret); ++"error adding delayed dir index item, name: %.*s, index: %llu, root: %llu, dir: %llu, dir->index_cnt: %llu, delayed_node->index_cnt: %llu, error: %d", ++ name_len, name, index, btrfs_root_id(delayed_node->root), ++ delayed_node->inode_id, dir->index_cnt, ++ delayed_node->index_cnt, ret); + BUG(); + } + mutex_unlock(&delayed_node->mutex); +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index f9f6dfbc86bcd..346fc46d019bf 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -6722,8 +6722,14 @@ void read_extent_buffer(const struct extent_buffer *eb, void *dstv, + char *dst = (char *)dstv; + unsigned long i = get_eb_page_index(start); + +- if (check_eb_range(eb, start, len)) ++ if (check_eb_range(eb, start, len)) { ++ /* ++ * Invalid range hit, reset the memory, so callers won't get ++ * some random garbage for their uninitialzed memory. ++ */ ++ memset(dstv, 0, len); + return; ++ } + + offset = get_eb_offset_in_page(eb, start); + +diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c +index ea23b83fc96be..2fd0ee0e6e931 100644 +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -2364,7 +2364,7 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) + * calculated f_bavail. + */ + if (!mixed && block_rsv->space_info->full && +- total_free_meta - thresh < block_rsv->size) ++ (total_free_meta < thresh || total_free_meta - thresh < block_rsv->size)) + buf->f_bavail = 0; + + buf->f_type = BTRFS_SUPER_MAGIC; +diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c +index 82848412ad852..30a9a89c141bb 100644 +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -2531,7 +2531,7 @@ int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start, + } + + cifsFileInfo_put(cfile); +- return -ENOTSUPP; ++ return -EOPNOTSUPP; + } + + int cifs_truncate_page(struct address_space *mapping, loff_t from) +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index 560c4ababfe1a..d8ce079ba9091 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -266,7 +266,7 @@ smb2_adjust_credits(struct TCP_Server_Info *server, + cifs_server_dbg(VFS, "request has less credits (%d) than required (%d)", + credits->value, new_val); + +- return -ENOTSUPP; ++ return -EOPNOTSUPP; + } + + spin_lock(&server->req_lock); +@@ -1308,7 +1308,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, + /* Use a fudge factor of 256 bytes in case we collide + * with a different set_EAs command. + */ +- if(CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - ++ if (CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - + MAX_SMB2_CLOSE_RESPONSE_SIZE - 256 < + used_len + ea_name_len + ea_value_len + 1) { + rc = -ENOSPC; +@@ -4822,7 +4822,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, + + if (shdr->Command != SMB2_READ) { + cifs_server_dbg(VFS, "only big read responses are supported\n"); +- return -ENOTSUPP; ++ return -EOPNOTSUPP; + } + + if (server->ops->is_session_expired && +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 976cb4b3ff660..e1a5ec7362ad6 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1656,7 +1656,7 @@ struct ext4_sb_info { + struct task_struct *s_mmp_tsk; + + /* record the last minlen when FITRIM is called. */ +- atomic_t s_last_trim_minblks; ++ unsigned long s_last_trim_minblks; + + /* Reference to checksum algorithm driver via cryptoapi */ + struct crypto_shash *s_chksum_driver; +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 7e7153c673c0d..e5b81d8be2324 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -16,6 +16,7 @@ + #include <linux/slab.h> + #include <linux/nospec.h> + #include <linux/backing-dev.h> ++#include <linux/freezer.h> + #include <trace/events/ext4.h> + + /* +@@ -6433,6 +6434,21 @@ __acquires(bitlock) + return ret; + } + ++static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb, ++ ext4_group_t grp) ++{ ++ if (grp < ext4_get_groups_count(sb)) ++ return EXT4_CLUSTERS_PER_GROUP(sb) - 1; ++ return (ext4_blocks_count(EXT4_SB(sb)->s_es) - ++ ext4_group_first_block_no(sb, grp) - 1) >> ++ EXT4_CLUSTER_BITS(sb); ++} ++ ++static bool ext4_trim_interrupted(void) ++{ ++ return fatal_signal_pending(current) || freezing(current); ++} ++ + static int ext4_try_to_trim_range(struct super_block *sb, + struct ext4_buddy *e4b, ext4_grpblk_t start, + ext4_grpblk_t max, ext4_grpblk_t minblocks) +@@ -6440,12 +6456,13 @@ __acquires(ext4_group_lock_ptr(sb, e4b->bd_group)) + __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) + { + ext4_grpblk_t next, count, free_count; ++ bool set_trimmed = false; + void *bitmap; +- int ret = 0; + + bitmap = e4b->bd_bitmap; +- start = (e4b->bd_info->bb_first_free > start) ? +- e4b->bd_info->bb_first_free : start; ++ if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group)) ++ set_trimmed = true; ++ start = max(e4b->bd_info->bb_first_free, start); + count = 0; + free_count = 0; + +@@ -6456,19 +6473,17 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) + next = mb_find_next_bit(bitmap, max + 1, start); + + if ((next - start) >= minblocks) { +- ret = ext4_trim_extent(sb, start, next - start, e4b); ++ int ret = ext4_trim_extent(sb, start, next - start, e4b); ++ + if (ret && ret != -EOPNOTSUPP) +- break; +- ret = 0; ++ return count; + count += next - start; + } + free_count += next - start; + start = next + 1; + +- if (fatal_signal_pending(current)) { +- count = -ERESTARTSYS; +- break; +- } ++ if (ext4_trim_interrupted()) ++ return count; + + if (need_resched()) { + ext4_unlock_group(sb, e4b->bd_group); +@@ -6480,6 +6495,9 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) + break; + } + ++ if (set_trimmed) ++ EXT4_MB_GRP_SET_TRIMMED(e4b->bd_info); ++ + return count; + } + +@@ -6490,7 +6508,6 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) + * @start: first group block to examine + * @max: last group block to examine + * @minblocks: minimum extent block count +- * @set_trimmed: set the trimmed flag if at least one block is trimmed + * + * ext4_trim_all_free walks through group's block bitmap searching for free + * extents. When the free extent is found, mark it as used in group buddy +@@ -6500,7 +6517,7 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) + static ext4_grpblk_t + ext4_trim_all_free(struct super_block *sb, ext4_group_t group, + ext4_grpblk_t start, ext4_grpblk_t max, +- ext4_grpblk_t minblocks, bool set_trimmed) ++ ext4_grpblk_t minblocks) + { + struct ext4_buddy e4b; + int ret; +@@ -6517,13 +6534,10 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, + ext4_lock_group(sb, group); + + if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) || +- minblocks < atomic_read(&EXT4_SB(sb)->s_last_trim_minblks)) { ++ minblocks < EXT4_SB(sb)->s_last_trim_minblks) + ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks); +- if (ret >= 0 && set_trimmed) +- EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info); +- } else { ++ else + ret = 0; +- } + + ext4_unlock_group(sb, group); + ext4_mb_unload_buddy(&e4b); +@@ -6556,7 +6570,6 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) + ext4_fsblk_t first_data_blk = + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); + ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es); +- bool whole_group, eof = false; + int ret = 0; + + start = range->start >> sb->s_blocksize_bits; +@@ -6575,10 +6588,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) + if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) + goto out; + } +- if (end >= max_blks - 1) { ++ if (end >= max_blks - 1) + end = max_blks - 1; +- eof = true; +- } + if (end <= first_data_blk) + goto out; + if (start < first_data_blk) +@@ -6592,9 +6603,10 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) + + /* end now represents the last cluster to discard in this group */ + end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; +- whole_group = true; + + for (group = first_group; group <= last_group; group++) { ++ if (ext4_trim_interrupted()) ++ break; + grp = ext4_get_group_info(sb, group); + if (!grp) + continue; +@@ -6611,13 +6623,11 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) + * change it for the last group, note that last_cluster is + * already computed earlier by ext4_get_group_no_and_offset() + */ +- if (group == last_group) { ++ if (group == last_group) + end = last_cluster; +- whole_group = eof ? true : end == EXT4_CLUSTERS_PER_GROUP(sb) - 1; +- } + if (grp->bb_free >= minlen) { + cnt = ext4_trim_all_free(sb, group, first_cluster, +- end, minlen, whole_group); ++ end, minlen); + if (cnt < 0) { + ret = cnt; + break; +@@ -6633,7 +6643,7 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) + } + + if (!ret) +- atomic_set(&EXT4_SB(sb)->s_last_trim_minblks, minlen); ++ EXT4_SB(sb)->s_last_trim_minblks = minlen; + + out: + range->len = EXT4_C2B(EXT4_SB(sb), trimmed) << sb->s_blocksize_bits; +@@ -6662,8 +6672,7 @@ ext4_mballoc_query_range( + + ext4_lock_group(sb, group); + +- start = (e4b.bd_info->bb_first_free > start) ? +- e4b.bd_info->bb_first_free : start; ++ start = max(e4b.bd_info->bb_first_free, start); + if (end >= EXT4_CLUSTERS_PER_GROUP(sb)) + end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; + +diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c +index 018af6ec97b40..bbe2a5cc49f68 100644 +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -525,7 +525,9 @@ static void nfs_direct_add_page_head(struct list_head *list, + kref_get(&head->wb_kref); + } + +-static void nfs_direct_join_group(struct list_head *list, struct inode *inode) ++static void nfs_direct_join_group(struct list_head *list, ++ struct nfs_commit_info *cinfo, ++ struct inode *inode) + { + struct nfs_page *req, *subreq; + +@@ -547,7 +549,7 @@ static void nfs_direct_join_group(struct list_head *list, struct inode *inode) + nfs_release_request(subreq); + } + } while ((subreq = subreq->wb_this_page) != req); +- nfs_join_page_group(req, inode); ++ nfs_join_page_group(req, cinfo, inode); + } + } + +@@ -573,7 +575,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) + nfs_init_cinfo_from_dreq(&cinfo, dreq); + nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); + +- nfs_direct_join_group(&reqs, dreq->inode); ++ nfs_direct_join_group(&reqs, &cinfo, dreq->inode); + + dreq->count = 0; + dreq->max_count = 0; +@@ -784,16 +786,21 @@ static void nfs_write_sync_pgio_error(struct list_head *head, int error) + static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr) + { + struct nfs_direct_req *dreq = hdr->dreq; ++ struct nfs_page *req; ++ struct nfs_commit_info cinfo; + ++ nfs_init_cinfo_from_dreq(&cinfo, dreq); + spin_lock(&dreq->lock); +- if (dreq->error == 0) { ++ if (dreq->error == 0) + dreq->flags = NFS_ODIRECT_RESCHED_WRITES; +- /* fake unstable write to let common nfs resend pages */ +- hdr->verf.committed = NFS_UNSTABLE; +- hdr->good_bytes = hdr->args.offset + hdr->args.count - +- hdr->io_start; +- } ++ set_bit(NFS_IOHDR_REDO, &hdr->flags); + spin_unlock(&dreq->lock); ++ while (!list_empty(&hdr->pages)) { ++ req = nfs_list_entry(hdr->pages.next); ++ nfs_list_remove_request(req); ++ nfs_unlock_request(req); ++ nfs_mark_request_commit(req, NULL, &cinfo, 0); ++ } + } + + static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { +diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c +index ceef75b4d2494..4269df0f0ffa5 100644 +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -1238,6 +1238,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg, + case -EPFNOSUPPORT: + case -EPROTONOSUPPORT: + case -EOPNOTSUPP: ++ case -EINVAL: + case -ECONNREFUSED: + case -ECONNRESET: + case -EHOSTDOWN: +diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c +index 1bf7a72ebda6e..cba8b4c1fb4a3 100644 +--- a/fs/nfs/nfs4client.c ++++ b/fs/nfs/nfs4client.c +@@ -231,6 +231,8 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) + __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); + __set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags); + ++ if (test_bit(NFS_CS_DS, &cl_init->init_flags)) ++ __set_bit(NFS_CS_DS, &clp->cl_flags); + /* + * Set up the connection to the server before we add add to the + * global list. +@@ -414,6 +416,8 @@ static void nfs4_add_trunk(struct nfs_client *clp, struct nfs_client *old) + .net = old->cl_net, + .servername = old->cl_hostname, + }; ++ int max_connect = test_bit(NFS_CS_PNFS, &clp->cl_flags) ? ++ clp->cl_max_connect : old->cl_max_connect; + + if (clp->cl_proto != old->cl_proto) + return; +@@ -427,7 +431,7 @@ static void nfs4_add_trunk(struct nfs_client *clp, struct nfs_client *old) + xprt_args.addrlen = clp_salen; + + rpc_clnt_add_xprt(old->cl_rpcclient, &xprt_args, +- rpc_clnt_test_and_add_xprt, NULL); ++ rpc_clnt_test_and_add_xprt, &max_connect); + } + + /** +@@ -993,6 +997,9 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, + if (mds_srv->flags & NFS_MOUNT_NORESVPORT) + __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); + ++ __set_bit(NFS_CS_DS, &cl_init.init_flags); ++ __set_bit(NFS_CS_PNFS, &cl_init.init_flags); ++ cl_init.max_connect = NFS_MAX_TRANSPORTS; + /* + * Set an authflavor equual to the MDS value. Use the MDS nfs_client + * cl_ipaddr so as to use the same EXCHANGE_ID co_ownerid as the MDS +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index a21e25cbd4515..32204c0b3d098 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -8715,6 +8715,8 @@ nfs4_run_exchange_id(struct nfs_client *clp, const struct cred *cred, + #ifdef CONFIG_NFS_V4_1_MIGRATION + calldata->args.flags |= EXCHGID4_FLAG_SUPP_MOVED_MIGR; + #endif ++ if (test_bit(NFS_CS_DS, &clp->cl_flags)) ++ calldata->args.flags |= EXCHGID4_FLAG_USE_PNFS_DS; + msg.rpc_argp = &calldata->args; + msg.rpc_resp = &calldata->res; + task_setup_data.callback_data = calldata; +@@ -8792,6 +8794,8 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre + /* Save the EXCHANGE_ID verifier session trunk tests */ + memcpy(clp->cl_confirm.data, argp->verifier.data, + sizeof(clp->cl_confirm.data)); ++ if (resp->flags & EXCHGID4_FLAG_USE_PNFS_DS) ++ set_bit(NFS_CS_DS, &clp->cl_flags); + out: + trace_nfs4_exchange_id(clp, status); + rpc_put_task(task); +diff --git a/fs/nfs/write.c b/fs/nfs/write.c +index be70874bc3292..4231d51fc1add 100644 +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -58,7 +58,8 @@ static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops; + static const struct nfs_commit_completion_ops nfs_commit_completion_ops; + static const struct nfs_rw_ops nfs_rw_write_ops; + static void nfs_inode_remove_request(struct nfs_page *req); +-static void nfs_clear_request_commit(struct nfs_page *req); ++static void nfs_clear_request_commit(struct nfs_commit_info *cinfo, ++ struct nfs_page *req); + static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo, + struct inode *inode); + static struct nfs_page * +@@ -500,8 +501,8 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list, + * the (former) group. All subrequests are removed from any write or commit + * lists, unlinked from the group and destroyed. + */ +-void +-nfs_join_page_group(struct nfs_page *head, struct inode *inode) ++void nfs_join_page_group(struct nfs_page *head, struct nfs_commit_info *cinfo, ++ struct inode *inode) + { + struct nfs_page *subreq; + struct nfs_page *destroy_list = NULL; +@@ -531,7 +532,7 @@ nfs_join_page_group(struct nfs_page *head, struct inode *inode) + * Commit list removal accounting is done after locks are dropped */ + subreq = head; + do { +- nfs_clear_request_commit(subreq); ++ nfs_clear_request_commit(cinfo, subreq); + subreq = subreq->wb_this_page; + } while (subreq != head); + +@@ -565,8 +566,10 @@ nfs_lock_and_join_requests(struct page *page) + { + struct inode *inode = page_file_mapping(page)->host; + struct nfs_page *head; ++ struct nfs_commit_info cinfo; + int ret; + ++ nfs_init_cinfo_from_inode(&cinfo, inode); + /* + * A reference is taken only on the head request which acts as a + * reference to the whole page group - the group will not be destroyed +@@ -583,7 +586,7 @@ nfs_lock_and_join_requests(struct page *page) + return ERR_PTR(ret); + } + +- nfs_join_page_group(head, inode); ++ nfs_join_page_group(head, &cinfo, inode); + + return head; + } +@@ -945,18 +948,16 @@ nfs_clear_page_commit(struct page *page) + } + + /* Called holding the request lock on @req */ +-static void +-nfs_clear_request_commit(struct nfs_page *req) ++static void nfs_clear_request_commit(struct nfs_commit_info *cinfo, ++ struct nfs_page *req) + { + if (test_bit(PG_CLEAN, &req->wb_flags)) { + struct nfs_open_context *ctx = nfs_req_openctx(req); + struct inode *inode = d_inode(ctx->dentry); +- struct nfs_commit_info cinfo; + +- nfs_init_cinfo_from_inode(&cinfo, inode); + mutex_lock(&NFS_I(inode)->commit_mutex); +- if (!pnfs_clear_request_commit(req, &cinfo)) { +- nfs_request_remove_commit_list(req, &cinfo); ++ if (!pnfs_clear_request_commit(req, cinfo)) { ++ nfs_request_remove_commit_list(req, cinfo); + } + mutex_unlock(&NFS_I(inode)->commit_mutex); + nfs_clear_page_commit(req->wb_page); +diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c +index aadea660c66c9..b0077f5f71124 100644 +--- a/fs/nilfs2/gcinode.c ++++ b/fs/nilfs2/gcinode.c +@@ -73,10 +73,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, + struct the_nilfs *nilfs = inode->i_sb->s_fs_info; + + err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn); +- if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */ +- brelse(bh); ++ if (unlikely(err)) /* -EIO, -ENOMEM, -ENOENT */ + goto failed; +- } + } + + lock_buffer(bh); +@@ -102,6 +100,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, + failed: + unlock_page(bh->b_page); + put_page(bh->b_page); ++ if (unlikely(err)) ++ brelse(bh); + return err; + } + +diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c +index a6d21fc0033c6..97f387d30e743 100644 +--- a/fs/proc/task_nommu.c ++++ b/fs/proc/task_nommu.c +@@ -208,11 +208,16 @@ static void *m_start(struct seq_file *m, loff_t *pos) + return ERR_PTR(-ESRCH); + + mm = priv->mm; +- if (!mm || !mmget_not_zero(mm)) ++ if (!mm || !mmget_not_zero(mm)) { ++ put_task_struct(priv->task); ++ priv->task = NULL; + return NULL; ++ } + + if (mmap_read_lock_killable(mm)) { + mmput(mm); ++ put_task_struct(priv->task); ++ priv->task = NULL; + return ERR_PTR(-EINTR); + } + +@@ -221,23 +226,21 @@ static void *m_start(struct seq_file *m, loff_t *pos) + if (n-- == 0) + return p; + +- mmap_read_unlock(mm); +- mmput(mm); + return NULL; + } + +-static void m_stop(struct seq_file *m, void *_vml) ++static void m_stop(struct seq_file *m, void *v) + { + struct proc_maps_private *priv = m->private; ++ struct mm_struct *mm = priv->mm; + +- if (!IS_ERR_OR_NULL(_vml)) { +- mmap_read_unlock(priv->mm); +- mmput(priv->mm); +- } +- if (priv->task) { +- put_task_struct(priv->task); +- priv->task = NULL; +- } ++ if (!priv->task) ++ return; ++ ++ mmap_read_unlock(mm); ++ mmput(mm); ++ put_task_struct(priv->task); ++ priv->task = NULL; + } + + static void *m_next(struct seq_file *m, void *_p, loff_t *pos) +diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c +index bf1f3607d0b60..08df23edea720 100644 +--- a/fs/xfs/scrub/common.c ++++ b/fs/xfs/scrub/common.c +@@ -864,28 +864,3 @@ xchk_ilock_inverted( + return -EDEADLOCK; + } + +-/* Pause background reaping of resources. */ +-void +-xchk_stop_reaping( +- struct xfs_scrub *sc) +-{ +- sc->flags |= XCHK_REAPING_DISABLED; +- xfs_blockgc_stop(sc->mp); +- xfs_inodegc_stop(sc->mp); +-} +- +-/* Restart background reaping of resources. */ +-void +-xchk_start_reaping( +- struct xfs_scrub *sc) +-{ +- /* +- * Readonly filesystems do not perform inactivation or speculative +- * preallocation, so there's no need to restart the workers. +- */ +- if (!xfs_is_readonly(sc->mp)) { +- xfs_inodegc_start(sc->mp); +- xfs_blockgc_start(sc->mp); +- } +- sc->flags &= ~XCHK_REAPING_DISABLED; +-} +diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h +index 454145db10e71..2ca80102e704a 100644 +--- a/fs/xfs/scrub/common.h ++++ b/fs/xfs/scrub/common.h +@@ -148,7 +148,5 @@ static inline bool xchk_skip_xref(struct xfs_scrub_metadata *sm) + + int xchk_metadata_inode_forks(struct xfs_scrub *sc); + int xchk_ilock_inverted(struct xfs_inode *ip, uint lock_mode); +-void xchk_stop_reaping(struct xfs_scrub *sc); +-void xchk_start_reaping(struct xfs_scrub *sc); + + #endif /* __XFS_SCRUB_COMMON_H__ */ +diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c +index 48a6cbdf95d08..037541339d80a 100644 +--- a/fs/xfs/scrub/fscounters.c ++++ b/fs/xfs/scrub/fscounters.c +@@ -128,13 +128,6 @@ xchk_setup_fscounters( + if (error) + return error; + +- /* +- * Pause background reclaim while we're scrubbing to reduce the +- * likelihood of background perturbations to the counters throwing off +- * our calculations. +- */ +- xchk_stop_reaping(sc); +- + return xchk_trans_alloc(sc, 0); + } + +@@ -353,6 +346,12 @@ xchk_fscounters( + if (fdblocks > mp->m_sb.sb_dblocks) + xchk_set_corrupt(sc); + ++ /* ++ * XXX: We can't quiesce percpu counter updates, so exit early. ++ * This can be re-enabled when we gain exclusive freeze functionality. ++ */ ++ return 0; ++ + /* + * If ifree exceeds icount by more than the minimum variance then + * something's probably wrong with the counters. +diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c +index 51e4c61916d20..e4d2a41983f73 100644 +--- a/fs/xfs/scrub/scrub.c ++++ b/fs/xfs/scrub/scrub.c +@@ -171,8 +171,6 @@ xchk_teardown( + } + if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR) + mnt_drop_write_file(sc->file); +- if (sc->flags & XCHK_REAPING_DISABLED) +- xchk_start_reaping(sc); + if (sc->flags & XCHK_HAS_QUOTAOFFLOCK) { + mutex_unlock(&sc->mp->m_quotainfo->qi_quotaofflock); + sc->flags &= ~XCHK_HAS_QUOTAOFFLOCK; +diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h +index 80e5026bba44a..e8d9fe9de26ed 100644 +--- a/fs/xfs/scrub/scrub.h ++++ b/fs/xfs/scrub/scrub.h +@@ -89,7 +89,6 @@ struct xfs_scrub { + /* XCHK state flags grow up from zero, XREP state flags grown down from 2^31 */ + #define XCHK_TRY_HARDER (1 << 0) /* can't get resources, try again */ + #define XCHK_HAS_QUOTAOFFLOCK (1 << 1) /* we hold the quotaoff lock */ +-#define XCHK_REAPING_DISABLED (1 << 2) /* background block reaping paused */ + #define XREP_ALREADY_FIXED (1 << 31) /* checking our repair work */ + + /* Metadata scrubbers */ +diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c +index 5e44d7bbd8fca..eab98d76dbe1f 100644 +--- a/fs/xfs/xfs_icache.c ++++ b/fs/xfs/xfs_icache.c +@@ -448,18 +448,23 @@ xfs_iget_check_free_state( + } + + /* Make all pending inactivation work start immediately. */ +-static void ++static bool + xfs_inodegc_queue_all( + struct xfs_mount *mp) + { + struct xfs_inodegc *gc; + int cpu; ++ bool ret = false; + + for_each_online_cpu(cpu) { + gc = per_cpu_ptr(mp->m_inodegc, cpu); +- if (!llist_empty(&gc->list)) +- queue_work_on(cpu, mp->m_inodegc_wq, &gc->work); ++ if (!llist_empty(&gc->list)) { ++ mod_delayed_work_on(cpu, mp->m_inodegc_wq, &gc->work, 0); ++ ret = true; ++ } + } ++ ++ return ret; + } + + /* +@@ -1851,11 +1856,13 @@ void + xfs_inodegc_worker( + struct work_struct *work) + { +- struct xfs_inodegc *gc = container_of(work, struct xfs_inodegc, +- work); ++ struct xfs_inodegc *gc = container_of(to_delayed_work(work), ++ struct xfs_inodegc, work); + struct llist_node *node = llist_del_all(&gc->list); + struct xfs_inode *ip, *n; + ++ ASSERT(gc->cpu == smp_processor_id()); ++ + WRITE_ONCE(gc->items, 0); + + if (!node) +@@ -1872,42 +1879,69 @@ xfs_inodegc_worker( + } + + /* +- * Force all currently queued inode inactivation work to run immediately and +- * wait for the work to finish. ++ * Expedite all pending inodegc work to run immediately. This does not wait for ++ * completion of the work. + */ + void +-xfs_inodegc_flush( ++xfs_inodegc_push( + struct xfs_mount *mp) + { + if (!xfs_is_inodegc_enabled(mp)) + return; ++ trace_xfs_inodegc_push(mp, __return_address); ++ xfs_inodegc_queue_all(mp); ++} + ++/* ++ * Force all currently queued inode inactivation work to run immediately and ++ * wait for the work to finish. ++ */ ++void ++xfs_inodegc_flush( ++ struct xfs_mount *mp) ++{ ++ xfs_inodegc_push(mp); + trace_xfs_inodegc_flush(mp, __return_address); +- +- xfs_inodegc_queue_all(mp); + flush_workqueue(mp->m_inodegc_wq); + } + + /* + * Flush all the pending work and then disable the inode inactivation background +- * workers and wait for them to stop. ++ * workers and wait for them to stop. Caller must hold sb->s_umount to ++ * coordinate changes in the inodegc_enabled state. + */ + void + xfs_inodegc_stop( + struct xfs_mount *mp) + { ++ bool rerun; ++ + if (!xfs_clear_inodegc_enabled(mp)) + return; + ++ /* ++ * Drain all pending inodegc work, including inodes that could be ++ * queued by racing xfs_inodegc_queue or xfs_inodegc_shrinker_scan ++ * threads that sample the inodegc state just prior to us clearing it. ++ * The inodegc flag state prevents new threads from queuing more ++ * inodes, so we queue pending work items and flush the workqueue until ++ * all inodegc lists are empty. IOWs, we cannot use drain_workqueue ++ * here because it does not allow other unserialized mechanisms to ++ * reschedule inodegc work while this draining is in progress. ++ */ + xfs_inodegc_queue_all(mp); +- drain_workqueue(mp->m_inodegc_wq); ++ do { ++ flush_workqueue(mp->m_inodegc_wq); ++ rerun = xfs_inodegc_queue_all(mp); ++ } while (rerun); + + trace_xfs_inodegc_stop(mp, __return_address); + } + + /* + * Enable the inode inactivation background workers and schedule deferred inode +- * inactivation work if there is any. ++ * inactivation work if there is any. Caller must hold sb->s_umount to ++ * coordinate changes in the inodegc_enabled state. + */ + void + xfs_inodegc_start( +@@ -2021,6 +2055,7 @@ xfs_inodegc_queue( + struct xfs_inodegc *gc; + int items; + unsigned int shrinker_hits; ++ unsigned long queue_delay = 1; + + trace_xfs_inode_set_need_inactive(ip); + spin_lock(&ip->i_flags_lock); +@@ -2032,19 +2067,27 @@ xfs_inodegc_queue( + items = READ_ONCE(gc->items); + WRITE_ONCE(gc->items, items + 1); + shrinker_hits = READ_ONCE(gc->shrinker_hits); +- put_cpu_ptr(gc); + +- if (!xfs_is_inodegc_enabled(mp)) ++ /* ++ * We queue the work while holding the current CPU so that the work ++ * is scheduled to run on this CPU. ++ */ ++ if (!xfs_is_inodegc_enabled(mp)) { ++ put_cpu_ptr(gc); + return; +- +- if (xfs_inodegc_want_queue_work(ip, items)) { +- trace_xfs_inodegc_queue(mp, __return_address); +- queue_work(mp->m_inodegc_wq, &gc->work); + } + ++ if (xfs_inodegc_want_queue_work(ip, items)) ++ queue_delay = 0; ++ ++ trace_xfs_inodegc_queue(mp, __return_address); ++ mod_delayed_work_on(current_cpu(), mp->m_inodegc_wq, &gc->work, ++ queue_delay); ++ put_cpu_ptr(gc); ++ + if (xfs_inodegc_want_flush_work(ip, items, shrinker_hits)) { + trace_xfs_inodegc_throttle(mp, __return_address); +- flush_work(&gc->work); ++ flush_delayed_work(&gc->work); + } + } + +@@ -2061,7 +2104,7 @@ xfs_inodegc_cpu_dead( + unsigned int count = 0; + + dead_gc = per_cpu_ptr(mp->m_inodegc, dead_cpu); +- cancel_work_sync(&dead_gc->work); ++ cancel_delayed_work_sync(&dead_gc->work); + + if (llist_empty(&dead_gc->list)) + return; +@@ -2080,12 +2123,13 @@ xfs_inodegc_cpu_dead( + llist_add_batch(first, last, &gc->list); + count += READ_ONCE(gc->items); + WRITE_ONCE(gc->items, count); +- put_cpu_ptr(gc); + + if (xfs_is_inodegc_enabled(mp)) { + trace_xfs_inodegc_queue(mp, __return_address); +- queue_work(mp->m_inodegc_wq, &gc->work); ++ mod_delayed_work_on(current_cpu(), mp->m_inodegc_wq, &gc->work, ++ 0); + } ++ put_cpu_ptr(gc); + } + + /* +@@ -2180,7 +2224,7 @@ xfs_inodegc_shrinker_scan( + unsigned int h = READ_ONCE(gc->shrinker_hits); + + WRITE_ONCE(gc->shrinker_hits, h + 1); +- queue_work_on(cpu, mp->m_inodegc_wq, &gc->work); ++ mod_delayed_work_on(cpu, mp->m_inodegc_wq, &gc->work, 0); + no_items = false; + } + } +diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h +index 2e4cfddf8b8ed..6cd180721659b 100644 +--- a/fs/xfs/xfs_icache.h ++++ b/fs/xfs/xfs_icache.h +@@ -76,6 +76,7 @@ void xfs_blockgc_stop(struct xfs_mount *mp); + void xfs_blockgc_start(struct xfs_mount *mp); + + void xfs_inodegc_worker(struct work_struct *work); ++void xfs_inodegc_push(struct xfs_mount *mp); + void xfs_inodegc_flush(struct xfs_mount *mp); + void xfs_inodegc_stop(struct xfs_mount *mp); + void xfs_inodegc_start(struct xfs_mount *mp); +diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h +index 86564295fce6d..29f35169bf9cf 100644 +--- a/fs/xfs/xfs_mount.h ++++ b/fs/xfs/xfs_mount.h +@@ -61,11 +61,14 @@ struct xfs_error_cfg { + */ + struct xfs_inodegc { + struct llist_head list; +- struct work_struct work; ++ struct delayed_work work; + + /* approximate count of inodes in the list */ + unsigned int items; + unsigned int shrinker_hits; ++#if defined(DEBUG) || defined(XFS_WARN) ++ unsigned int cpu; ++#endif + }; + + /* +diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c +index 47fe60e1a8873..322a111dfbc0f 100644 +--- a/fs/xfs/xfs_qm_syscalls.c ++++ b/fs/xfs/xfs_qm_syscalls.c +@@ -481,9 +481,12 @@ xfs_qm_scall_getquota( + struct xfs_dquot *dqp; + int error; + +- /* Flush inodegc work at the start of a quota reporting scan. */ ++ /* ++ * Expedite pending inodegc work at the start of a quota reporting ++ * scan but don't block waiting for it to complete. ++ */ + if (id == 0) +- xfs_inodegc_flush(mp); ++ xfs_inodegc_push(mp); + + /* + * Try to get the dquot. We don't want it allocated on disk, so don't +@@ -525,7 +528,7 @@ xfs_qm_scall_getquota_next( + + /* Flush inodegc work at the start of a quota reporting scan. */ + if (*id == 0) +- xfs_inodegc_flush(mp); ++ xfs_inodegc_push(mp); + + error = xfs_qm_dqget_next(mp, *id, type, &dqp); + if (error) +diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c +index df1d6be61bfa3..569960e4ea3a6 100644 +--- a/fs/xfs/xfs_super.c ++++ b/fs/xfs/xfs_super.c +@@ -795,8 +795,11 @@ xfs_fs_statfs( + xfs_extlen_t lsize; + int64_t ffree; + +- /* Wait for whatever inactivations are in progress. */ +- xfs_inodegc_flush(mp); ++ /* ++ * Expedite background inodegc but don't wait. We do not want to block ++ * here waiting hours for a billion extent file to be truncated. ++ */ ++ xfs_inodegc_push(mp); + + statp->f_type = XFS_SUPER_MAGIC; + statp->f_namelen = MAXNAMELEN - 1; +@@ -1059,9 +1062,12 @@ xfs_inodegc_init_percpu( + + for_each_possible_cpu(cpu) { + gc = per_cpu_ptr(mp->m_inodegc, cpu); ++#if defined(DEBUG) || defined(XFS_WARN) ++ gc->cpu = cpu; ++#endif + init_llist_head(&gc->list); + gc->items = 0; +- INIT_WORK(&gc->work, xfs_inodegc_worker); ++ INIT_DELAYED_WORK(&gc->work, xfs_inodegc_worker); + } + return 0; + } +diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h +index 1033a95fbf8e6..ebd17ddba0243 100644 +--- a/fs/xfs/xfs_trace.h ++++ b/fs/xfs/xfs_trace.h +@@ -240,6 +240,7 @@ DEFINE_EVENT(xfs_fs_class, name, \ + TP_PROTO(struct xfs_mount *mp, void *caller_ip), \ + TP_ARGS(mp, caller_ip)) + DEFINE_FS_EVENT(xfs_inodegc_flush); ++DEFINE_FS_EVENT(xfs_inodegc_push); + DEFINE_FS_EVENT(xfs_inodegc_start); + DEFINE_FS_EVENT(xfs_inodegc_stop); + DEFINE_FS_EVENT(xfs_inodegc_queue); +diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h +index 47d9abfbdb556..1deb9a0fe74ef 100644 +--- a/include/linux/btf_ids.h ++++ b/include/linux/btf_ids.h +@@ -38,7 +38,7 @@ asm( \ + ____BTF_ID(symbol) + + #define __ID(prefix) \ +- __PASTE(prefix, __COUNTER__) ++ __PASTE(__PASTE(prefix, __COUNTER__), __LINE__) + + /* + * The BTF_ID defines unique symbol for each ID pointing +diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h +index 45cdb12243e3f..0d97d1cf660f7 100644 +--- a/include/linux/cgroup.h ++++ b/include/linux/cgroup.h +@@ -451,6 +451,7 @@ extern struct mutex cgroup_mutex; + extern spinlock_t css_set_lock; + #define task_css_set_check(task, __c) \ + rcu_dereference_check((task)->cgroups, \ ++ rcu_read_lock_sched_held() || \ + lockdep_is_held(&cgroup_mutex) || \ + lockdep_is_held(&css_set_lock) || \ + ((task)->flags & PF_EXITING) || (__c)) +@@ -792,11 +793,9 @@ static inline void cgroup_account_cputime(struct task_struct *task, + + cpuacct_charge(task, delta_exec); + +- rcu_read_lock(); + cgrp = task_dfl_cgroup(task); + if (cgroup_parent(cgrp)) + __cgroup_account_cputime(cgrp, delta_exec); +- rcu_read_unlock(); + } + + static inline void cgroup_account_cputime_field(struct task_struct *task, +diff --git a/include/linux/if_team.h b/include/linux/if_team.h +index 5dd1657947b75..762c77d13e7dd 100644 +--- a/include/linux/if_team.h ++++ b/include/linux/if_team.h +@@ -189,6 +189,8 @@ struct team { + struct net_device *dev; /* associated netdevice */ + struct team_pcpu_stats __percpu *pcpu_stats; + ++ const struct header_ops *header_ops_cache; ++ + struct mutex lock; /* used for overall locking, e.g. port lists write */ + + /* +diff --git a/include/linux/libata.h b/include/linux/libata.h +index fa568d35bcbfa..3069064dc269c 100644 +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -191,7 +191,7 @@ enum { + ATA_LFLAG_NO_LPM = (1 << 8), /* disable LPM on this link */ + ATA_LFLAG_RST_ONCE = (1 << 9), /* limit recovery to one reset */ + ATA_LFLAG_CHANGED = (1 << 10), /* LPM state changed on this link */ +- ATA_LFLAG_NO_DB_DELAY = (1 << 11), /* no debounce delay on link resume */ ++ ATA_LFLAG_NO_DEBOUNCE_DELAY = (1 << 11), /* no debounce delay on link resume */ + + /* struct ata_port flags */ + ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ +@@ -301,7 +301,7 @@ enum { + * advised to wait only for the following duration before + * doing SRST. + */ +- ATA_TMOUT_PMP_SRST_WAIT = 5000, ++ ATA_TMOUT_PMP_SRST_WAIT = 10000, + + /* When the LPM policy is set to ATA_LPM_MAX_POWER, there might + * be a spurious PHY event, so ignore the first PHY event that +diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h +index da9ef0ab9b4b6..5e065f16d061d 100644 +--- a/include/linux/nfs_fs_sb.h ++++ b/include/linux/nfs_fs_sb.h +@@ -48,6 +48,7 @@ struct nfs_client { + #define NFS_CS_NOPING 6 /* - don't ping on connect */ + #define NFS_CS_DS 7 /* - Server is a DS */ + #define NFS_CS_REUSEPORT 8 /* - reuse src port on reconnect */ ++#define NFS_CS_PNFS 9 /* - Server used for pnfs */ + struct sockaddr_storage cl_addr; /* server identifier */ + size_t cl_addrlen; + char * cl_hostname; /* hostname of server */ +diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h +index f0373a6cb5fb6..40aa09a21f75d 100644 +--- a/include/linux/nfs_page.h ++++ b/include/linux/nfs_page.h +@@ -145,7 +145,9 @@ extern void nfs_unlock_request(struct nfs_page *req); + extern void nfs_unlock_and_release_request(struct nfs_page *); + extern struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req); + extern int nfs_page_group_lock_subrequests(struct nfs_page *head); +-extern void nfs_join_page_group(struct nfs_page *head, struct inode *inode); ++extern void nfs_join_page_group(struct nfs_page *head, ++ struct nfs_commit_info *cinfo, ++ struct inode *inode); + extern int nfs_page_group_lock(struct nfs_page *); + extern void nfs_page_group_unlock(struct nfs_page *); + extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int); +diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h +index 37ded6b8fee61..2c5d0102315d2 100644 +--- a/include/linux/seqlock.h ++++ b/include/linux/seqlock.h +@@ -516,8 +516,8 @@ do { \ + + static inline void do_write_seqcount_begin_nested(seqcount_t *s, int subclass) + { +- do_raw_write_seqcount_begin(s); + seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_); ++ do_raw_write_seqcount_begin(s); + } + + /** +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index 1458b3eae8ada..a0b47f2b896e1 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -477,6 +477,7 @@ struct nft_set_elem_expr { + * + * @list: table set list node + * @bindings: list of set bindings ++ * @refs: internal refcounting for async set destruction + * @table: table this set belongs to + * @net: netnamespace this set belongs to + * @name: name of the set +@@ -498,6 +499,7 @@ struct nft_set_elem_expr { + * @expr: stateful expression + * @ops: set ops + * @flags: set flags ++ * @dead: set will be freed, never cleared + * @genmask: generation mask + * @klen: key length + * @dlen: data length +@@ -506,6 +508,7 @@ struct nft_set_elem_expr { + struct nft_set { + struct list_head list; + struct list_head bindings; ++ refcount_t refs; + struct nft_table *table; + possible_net_t net; + char *name; +@@ -527,7 +530,8 @@ struct nft_set { + struct list_head pending_update; + /* runtime data below here */ + const struct nft_set_ops *ops ____cacheline_aligned; +- u16 flags:14, ++ u16 flags:13, ++ dead:1, + genmask:2; + u8 klen; + u8 dlen; +@@ -548,6 +552,11 @@ static inline void *nft_set_priv(const struct nft_set *set) + return (void *)set->data; + } + ++static inline bool nft_set_gc_is_pending(const struct nft_set *s) ++{ ++ return refcount_read(&s->refs) != 1; ++} ++ + static inline struct nft_set *nft_set_container_of(const void *priv) + { + return (void *)priv - offsetof(struct nft_set, data); +@@ -561,7 +570,6 @@ struct nft_set *nft_set_lookup_global(const struct net *net, + + struct nft_set_ext *nft_set_catchall_lookup(const struct net *net, + const struct nft_set *set); +-void *nft_set_catchall_gc(const struct nft_set *set); + + static inline unsigned long nft_set_gc_interval(const struct nft_set *set) + { +@@ -776,62 +784,6 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem, + void nf_tables_set_elem_destroy(const struct nft_ctx *ctx, + const struct nft_set *set, void *elem); + +-/** +- * struct nft_set_gc_batch_head - nf_tables set garbage collection batch +- * +- * @rcu: rcu head +- * @set: set the elements belong to +- * @cnt: count of elements +- */ +-struct nft_set_gc_batch_head { +- struct rcu_head rcu; +- const struct nft_set *set; +- unsigned int cnt; +-}; +- +-#define NFT_SET_GC_BATCH_SIZE ((PAGE_SIZE - \ +- sizeof(struct nft_set_gc_batch_head)) / \ +- sizeof(void *)) +- +-/** +- * struct nft_set_gc_batch - nf_tables set garbage collection batch +- * +- * @head: GC batch head +- * @elems: garbage collection elements +- */ +-struct nft_set_gc_batch { +- struct nft_set_gc_batch_head head; +- void *elems[NFT_SET_GC_BATCH_SIZE]; +-}; +- +-struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set, +- gfp_t gfp); +-void nft_set_gc_batch_release(struct rcu_head *rcu); +- +-static inline void nft_set_gc_batch_complete(struct nft_set_gc_batch *gcb) +-{ +- if (gcb != NULL) +- call_rcu(&gcb->head.rcu, nft_set_gc_batch_release); +-} +- +-static inline struct nft_set_gc_batch * +-nft_set_gc_batch_check(const struct nft_set *set, struct nft_set_gc_batch *gcb, +- gfp_t gfp) +-{ +- if (gcb != NULL) { +- if (gcb->head.cnt + 1 < ARRAY_SIZE(gcb->elems)) +- return gcb; +- nft_set_gc_batch_complete(gcb); +- } +- return nft_set_gc_batch_alloc(set, gfp); +-} +- +-static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb, +- void *elem) +-{ +- gcb->elems[gcb->head.cnt++] = elem; +-} +- + struct nft_expr_ops; + /** + * struct nft_expr_type - nf_tables expression type +@@ -1490,39 +1442,30 @@ static inline void nft_set_elem_change_active(const struct net *net, + + #endif /* IS_ENABLED(CONFIG_NF_TABLES) */ + +-/* +- * We use a free bit in the genmask field to indicate the element +- * is busy, meaning it is currently being processed either by +- * the netlink API or GC. +- * +- * Even though the genmask is only a single byte wide, this works +- * because the extension structure if fully constant once initialized, +- * so there are no non-atomic write accesses unless it is already +- * marked busy. +- */ +-#define NFT_SET_ELEM_BUSY_MASK (1 << 2) ++#define NFT_SET_ELEM_DEAD_MASK (1 << 2) + + #if defined(__LITTLE_ENDIAN_BITFIELD) +-#define NFT_SET_ELEM_BUSY_BIT 2 ++#define NFT_SET_ELEM_DEAD_BIT 2 + #elif defined(__BIG_ENDIAN_BITFIELD) +-#define NFT_SET_ELEM_BUSY_BIT (BITS_PER_LONG - BITS_PER_BYTE + 2) ++#define NFT_SET_ELEM_DEAD_BIT (BITS_PER_LONG - BITS_PER_BYTE + 2) + #else + #error + #endif + +-static inline int nft_set_elem_mark_busy(struct nft_set_ext *ext) ++static inline void nft_set_elem_dead(struct nft_set_ext *ext) + { + unsigned long *word = (unsigned long *)ext; + + BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0); +- return test_and_set_bit(NFT_SET_ELEM_BUSY_BIT, word); ++ set_bit(NFT_SET_ELEM_DEAD_BIT, word); + } + +-static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext) ++static inline int nft_set_elem_is_dead(const struct nft_set_ext *ext) + { + unsigned long *word = (unsigned long *)ext; + +- clear_bit(NFT_SET_ELEM_BUSY_BIT, word); ++ BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0); ++ return test_bit(NFT_SET_ELEM_DEAD_BIT, word); + } + + /** +@@ -1656,6 +1599,39 @@ struct nft_trans_flowtable { + #define nft_trans_flowtable_flags(trans) \ + (((struct nft_trans_flowtable *)trans->data)->flags) + ++#define NFT_TRANS_GC_BATCHCOUNT 256 ++ ++struct nft_trans_gc { ++ struct list_head list; ++ struct net *net; ++ struct nft_set *set; ++ u32 seq; ++ u16 count; ++ void *priv[NFT_TRANS_GC_BATCHCOUNT]; ++ struct rcu_head rcu; ++}; ++ ++struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set, ++ unsigned int gc_seq, gfp_t gfp); ++void nft_trans_gc_destroy(struct nft_trans_gc *trans); ++ ++struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc, ++ unsigned int gc_seq, gfp_t gfp); ++void nft_trans_gc_queue_async_done(struct nft_trans_gc *gc); ++ ++struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp); ++void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans); ++ ++void nft_trans_gc_elem_add(struct nft_trans_gc *gc, void *priv); ++ ++struct nft_trans_gc *nft_trans_gc_catchall_async(struct nft_trans_gc *gc, ++ unsigned int gc_seq); ++struct nft_trans_gc *nft_trans_gc_catchall_sync(struct nft_trans_gc *gc); ++ ++void nft_setelem_data_deactivate(const struct net *net, ++ const struct nft_set *set, ++ struct nft_set_elem *elem); ++ + int __init nft_chain_filter_init(void); + void nft_chain_filter_fini(void); + +@@ -1683,6 +1659,7 @@ struct nftables_pernet { + u64 table_handle; + unsigned int base_seq; + u8 validate_state; ++ unsigned int gc_seq; + }; + + extern unsigned int nf_tables_net_id; +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index a887e582f0e78..9fb06a511250f 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -1762,7 +1762,9 @@ union bpf_attr { + * performed again, if the helper is used in combination with + * direct packet access. + * Return +- * 0 on success, or a negative error in case of failure. ++ * 0 on success, or a negative error in case of failure. Positive ++ * error indicates a potential drop or congestion in the target ++ * device. The particular positive error codes are not defined. + * + * u64 bpf_get_current_pid_tgid(void) + * Return +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 1519125b98147..d00bedfdadbbe 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -4038,7 +4038,7 @@ static int io_linkat_prep(struct io_kiocb *req, + + if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) + return -EINVAL; +- if (sqe->ioprio || sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in) ++ if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in) + return -EINVAL; + if (unlikely(req->flags & REQ_F_FIXED_FILE)) + return -EBADF; +diff --git a/kernel/bpf/queue_stack_maps.c b/kernel/bpf/queue_stack_maps.c +index f9c734aaa9902..ef95b796a0fa3 100644 +--- a/kernel/bpf/queue_stack_maps.c ++++ b/kernel/bpf/queue_stack_maps.c +@@ -103,7 +103,12 @@ static int __queue_map_get(struct bpf_map *map, void *value, bool delete) + int err = 0; + void *ptr; + +- raw_spin_lock_irqsave(&qs->lock, flags); ++ if (in_nmi()) { ++ if (!raw_spin_trylock_irqsave(&qs->lock, flags)) ++ return -EBUSY; ++ } else { ++ raw_spin_lock_irqsave(&qs->lock, flags); ++ } + + if (queue_stack_map_is_empty(qs)) { + memset(value, 0, qs->map.value_size); +@@ -133,7 +138,12 @@ static int __stack_map_get(struct bpf_map *map, void *value, bool delete) + void *ptr; + u32 index; + +- raw_spin_lock_irqsave(&qs->lock, flags); ++ if (in_nmi()) { ++ if (!raw_spin_trylock_irqsave(&qs->lock, flags)) ++ return -EBUSY; ++ } else { ++ raw_spin_lock_irqsave(&qs->lock, flags); ++ } + + if (queue_stack_map_is_empty(qs)) { + memset(value, 0, qs->map.value_size); +@@ -198,7 +208,12 @@ static int queue_stack_map_push_elem(struct bpf_map *map, void *value, + if (flags & BPF_NOEXIST || flags > BPF_EXIST) + return -EINVAL; + +- raw_spin_lock_irqsave(&qs->lock, irq_flags); ++ if (in_nmi()) { ++ if (!raw_spin_trylock_irqsave(&qs->lock, irq_flags)) ++ return -EBUSY; ++ } else { ++ raw_spin_lock_irqsave(&qs->lock, irq_flags); ++ } + + if (queue_stack_map_is_full(qs)) { + if (!replace) { +diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c +index 2caafd13f8aac..1f9a8cee42241 100644 +--- a/kernel/dma/debug.c ++++ b/kernel/dma/debug.c +@@ -605,15 +605,19 @@ static struct dma_debug_entry *__dma_entry_alloc(void) + return entry; + } + +-static void __dma_entry_alloc_check_leak(void) ++/* ++ * This should be called outside of free_entries_lock scope to avoid potential ++ * deadlocks with serial consoles that use DMA. ++ */ ++static void __dma_entry_alloc_check_leak(u32 nr_entries) + { +- u32 tmp = nr_total_entries % nr_prealloc_entries; ++ u32 tmp = nr_entries % nr_prealloc_entries; + + /* Shout each time we tick over some multiple of the initial pool */ + if (tmp < DMA_DEBUG_DYNAMIC_ENTRIES) { + pr_info("dma_debug_entry pool grown to %u (%u00%%)\n", +- nr_total_entries, +- (nr_total_entries / nr_prealloc_entries)); ++ nr_entries, ++ (nr_entries / nr_prealloc_entries)); + } + } + +@@ -624,8 +628,10 @@ static void __dma_entry_alloc_check_leak(void) + */ + static struct dma_debug_entry *dma_entry_alloc(void) + { ++ bool alloc_check_leak = false; + struct dma_debug_entry *entry; + unsigned long flags; ++ u32 nr_entries; + + spin_lock_irqsave(&free_entries_lock, flags); + if (num_free_entries == 0) { +@@ -635,13 +641,17 @@ static struct dma_debug_entry *dma_entry_alloc(void) + pr_err("debugging out of memory - disabling\n"); + return NULL; + } +- __dma_entry_alloc_check_leak(); ++ alloc_check_leak = true; ++ nr_entries = nr_total_entries; + } + + entry = __dma_entry_alloc(); + + spin_unlock_irqrestore(&free_entries_lock, flags); + ++ if (alloc_check_leak) ++ __dma_entry_alloc_check_leak(nr_entries); ++ + #ifdef CONFIG_STACKTRACE + entry->stack_len = stack_trace_save(entry->stack_entries, + ARRAY_SIZE(entry->stack_entries), +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 2324b7055260a..02c91528127af 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -8725,7 +8725,7 @@ void __init init_idle(struct task_struct *idle, int cpu) + * PF_KTHREAD should already be set at this point; regardless, make it + * look like a proper per-CPU kthread. + */ +- idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY; ++ idle->flags |= PF_KTHREAD | PF_NO_SETAFFINITY; + kthread_set_per_cpu(idle, cpu); + + #ifdef CONFIG_SMP +diff --git a/kernel/sched/cpuacct.c b/kernel/sched/cpuacct.c +index cacc2076ad214..f0af0fecde9d9 100644 +--- a/kernel/sched/cpuacct.c ++++ b/kernel/sched/cpuacct.c +@@ -331,12 +331,10 @@ void cpuacct_charge(struct task_struct *tsk, u64 cputime) + unsigned int cpu = task_cpu(tsk); + struct cpuacct *ca; + +- rcu_read_lock(); ++ lockdep_assert_rq_held(cpu_rq(cpu)); + + for (ca = task_ca(tsk); ca; ca = parent_ca(ca)) + *per_cpu_ptr(ca->cpuusage, cpu) += cputime; +- +- rcu_read_unlock(); + } + + /* +diff --git a/kernel/sched/cpupri.c b/kernel/sched/cpupri.c +index d583f2aa744e5..b41655e00f611 100644 +--- a/kernel/sched/cpupri.c ++++ b/kernel/sched/cpupri.c +@@ -102,6 +102,7 @@ static inline int __cpupri_find(struct cpupri *cp, struct task_struct *p, + + if (lowest_mask) { + cpumask_and(lowest_mask, &p->cpus_mask, vec->mask); ++ cpumask_and(lowest_mask, lowest_mask, cpu_active_mask); + + /* + * We have to ensure that we have at least one bit +diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c +index 499a3e286cd05..6b8d2169d9ea4 100644 +--- a/kernel/sched/idle.c ++++ b/kernel/sched/idle.c +@@ -397,6 +397,7 @@ EXPORT_SYMBOL_GPL(play_idle_precise); + + void cpu_startup_entry(enum cpuhp_state state) + { ++ current->flags |= PF_IDLE; + arch_cpu_idle_prepare(); + cpuhp_online_idle(state); + while (1) +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index db7cefd196cec..2e5f3de7bfb09 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -1106,6 +1106,9 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu, + if (full) { + poll_wait(filp, &work->full_waiters, poll_table); + work->full_waiters_pending = true; ++ if (!cpu_buffer->shortest_full || ++ cpu_buffer->shortest_full > full) ++ cpu_buffer->shortest_full = full; + } else { + poll_wait(filp, &work->waiters, poll_table); + work->waiters_pending = true; +@@ -2176,6 +2179,8 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size, + err = -ENOMEM; + goto out_err; + } ++ ++ cond_resched(); + } + + cpus_read_lock(); +@@ -2350,6 +2355,11 @@ rb_iter_head_event(struct ring_buffer_iter *iter) + */ + commit = rb_page_commit(iter_head_page); + smp_rmb(); ++ ++ /* An event needs to be at least 8 bytes in size */ ++ if (iter->head > commit - 8) ++ goto reset; ++ + event = __rb_page_index(iter_head_page, iter->head); + length = rb_event_length(event); + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 6adacfc880d6c..7453840c77be2 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -4887,6 +4887,39 @@ int tracing_open_generic_tr(struct inode *inode, struct file *filp) + return 0; + } + ++/* ++ * The private pointer of the inode is the trace_event_file. ++ * Update the tr ref count associated to it. ++ */ ++int tracing_open_file_tr(struct inode *inode, struct file *filp) ++{ ++ struct trace_event_file *file = inode->i_private; ++ int ret; ++ ++ ret = tracing_check_open_get_tr(file->tr); ++ if (ret) ++ return ret; ++ ++ filp->private_data = inode->i_private; ++ ++ return 0; ++} ++ ++int tracing_release_file_tr(struct inode *inode, struct file *filp) ++{ ++ struct trace_event_file *file = inode->i_private; ++ ++ trace_array_put(file->tr); ++ ++ return 0; ++} ++ ++static int tracing_mark_open(struct inode *inode, struct file *filp) ++{ ++ stream_open(inode, filp); ++ return tracing_open_generic_tr(inode, filp); ++} ++ + static int tracing_release(struct inode *inode, struct file *file) + { + struct trace_array *tr = inode->i_private; +@@ -7225,9 +7258,6 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, + if (tt) + event_triggers_post_call(tr->trace_marker_file, tt); + +- if (written > 0) +- *fpos += written; +- + return written; + } + +@@ -7286,9 +7316,6 @@ tracing_mark_raw_write(struct file *filp, const char __user *ubuf, + + __buffer_unlock_commit(buffer, event); + +- if (written > 0) +- *fpos += written; +- + return written; + } + +@@ -7699,16 +7726,14 @@ static const struct file_operations tracing_free_buffer_fops = { + }; + + static const struct file_operations tracing_mark_fops = { +- .open = tracing_open_generic_tr, ++ .open = tracing_mark_open, + .write = tracing_mark_write, +- .llseek = generic_file_llseek, + .release = tracing_release_generic_tr, + }; + + static const struct file_operations tracing_mark_raw_fops = { +- .open = tracing_open_generic_tr, ++ .open = tracing_mark_open, + .write = tracing_mark_raw_write, +- .llseek = generic_file_llseek, + .release = tracing_release_generic_tr, + }; + +diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h +index 90ab921884b10..a4a90bd3373be 100644 +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -591,6 +591,8 @@ void tracing_reset_all_online_cpus(void); + void tracing_reset_all_online_cpus_unlocked(void); + int tracing_open_generic(struct inode *inode, struct file *filp); + int tracing_open_generic_tr(struct inode *inode, struct file *filp); ++int tracing_open_file_tr(struct inode *inode, struct file *filp); ++int tracing_release_file_tr(struct inode *inode, struct file *filp); + bool tracing_is_disabled(void); + bool tracer_tracing_is_on(struct trace_array *tr); + void tracer_tracing_on(struct trace_array *tr); +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index 2a2a599997671..c626d02776a54 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -2078,9 +2078,10 @@ static const struct file_operations ftrace_set_event_notrace_pid_fops = { + }; + + static const struct file_operations ftrace_enable_fops = { +- .open = tracing_open_generic, ++ .open = tracing_open_file_tr, + .read = event_enable_read, + .write = event_enable_write, ++ .release = tracing_release_file_tr, + .llseek = default_llseek, + }; + +@@ -2097,9 +2098,10 @@ static const struct file_operations ftrace_event_id_fops = { + }; + + static const struct file_operations ftrace_event_filter_fops = { +- .open = tracing_open_generic, ++ .open = tracing_open_file_tr, + .read = event_filter_read, + .write = event_filter_write, ++ .release = tracing_release_file_tr, + .llseek = default_llseek, + }; + +diff --git a/kernel/trace/trace_events_inject.c b/kernel/trace/trace_events_inject.c +index c188045c5f976..b1fce64e126c0 100644 +--- a/kernel/trace/trace_events_inject.c ++++ b/kernel/trace/trace_events_inject.c +@@ -321,7 +321,8 @@ event_inject_read(struct file *file, char __user *buf, size_t size, + } + + const struct file_operations event_inject_fops = { +- .open = tracing_open_generic, ++ .open = tracing_open_file_tr, + .read = event_inject_read, + .write = event_inject_write, ++ .release = tracing_release_file_tr, + }; +diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c +index 3d69ad5463a9f..011bd3c59da19 100644 +--- a/net/bridge/br_forward.c ++++ b/net/bridge/br_forward.c +@@ -124,7 +124,7 @@ static int deliver_clone(const struct net_bridge_port *prev, + + skb = skb_clone(skb, GFP_ATOMIC); + if (!skb) { +- dev->stats.tx_dropped++; ++ DEV_STATS_INC(dev, tx_dropped); + return -ENOMEM; + } + +@@ -263,7 +263,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb, + + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) { +- dev->stats.tx_dropped++; ++ DEV_STATS_INC(dev, tx_dropped); + return; + } + +diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c +index 6743c8a0fe8e1..54bfcdf692732 100644 +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -146,12 +146,12 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb + if ((mdst && mdst->host_joined) || + br_multicast_is_router(brmctx, skb)) { + local_rcv = true; +- br->dev->stats.multicast++; ++ DEV_STATS_INC(br->dev, multicast); + } + mcast_hit = true; + } else { + local_rcv = true; +- br->dev->stats.multicast++; ++ DEV_STATS_INC(br->dev, multicast); + } + break; + case BR_PKT_UNICAST: +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index 2596a54c2fe71..a1efbd0f2ad32 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -1278,7 +1278,7 @@ proto_again: + break; + } + +- nhoff += ntohs(hdr->message_length); ++ nhoff += sizeof(struct ptp_header); + fdret = FLOW_DISSECT_RET_OUT_GOOD; + break; + } +diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c +index 1490ba960365e..b44e46dc8e040 100644 +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -250,13 +250,8 @@ static int dccp_v4_err(struct sk_buff *skb, u32 info) + int err; + struct net *net = dev_net(skb->dev); + +- /* For the first __dccp_basic_hdr_len() check, we only need dh->dccph_x, +- * which is in byte 7 of the dccp header. +- * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us. +- * +- * Later on, we want to access the sequence number fields, which are +- * beyond 8 bytes, so we have to pskb_may_pull() ourselves. +- */ ++ if (!pskb_may_pull(skb, offset + sizeof(*dh))) ++ return -EINVAL; + dh = (struct dccp_hdr *)(skb->data + offset); + if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) + return -EINVAL; +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index c9f11f86266c0..0ddf64845a06c 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -83,13 +83,8 @@ static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + __u64 seq; + struct net *net = dev_net(skb->dev); + +- /* For the first __dccp_basic_hdr_len() check, we only need dh->dccph_x, +- * which is in byte 7 of the dccp header. +- * Our caller (icmpv6_notify()) already pulled 8 bytes for us. +- * +- * Later on, we want to access the sequence number fields, which are +- * beyond 8 bytes, so we have to pskb_may_pull() ourselves. +- */ ++ if (!pskb_may_pull(skb, offset + sizeof(*dh))) ++ return -EINVAL; + dh = (struct dccp_hdr *)(skb->data + offset); + if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) + return -EINVAL; +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index bc6240d327a8f..968cc4aa6e96c 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1220,6 +1220,7 @@ EXPORT_INDIRECT_CALLABLE(ipv4_dst_check); + + static void ipv4_send_dest_unreach(struct sk_buff *skb) + { ++ struct net_device *dev; + struct ip_options opt; + int res; + +@@ -1237,7 +1238,8 @@ static void ipv4_send_dest_unreach(struct sk_buff *skb) + opt.optlen = ip_hdr(skb)->ihl * 4 - sizeof(struct iphdr); + + rcu_read_lock(); +- res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL); ++ dev = skb->dev ? skb->dev : skb_rtable(skb)->dst.dev; ++ res = __ip_options_compile(dev_net(dev), &opt, skb, NULL); + rcu_read_unlock(); + + if (res) +diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c +index 62fb1031763d1..f8854bff286cb 100644 +--- a/net/ncsi/ncsi-aen.c ++++ b/net/ncsi/ncsi-aen.c +@@ -89,6 +89,11 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp, + if ((had_link == has_link) || chained) + return 0; + ++ if (had_link) ++ netif_carrier_off(ndp->ndev.dev); ++ else ++ netif_carrier_on(ndp->ndev.dev); ++ + if (!ndp->multi_package && !nc->package->multi_channel) { + if (had_link) { + ndp->flags |= NCSI_DEV_RESHUFFLE; +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index c911fc09f363c..33869db42bb6b 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -682,6 +682,14 @@ __ip_set_put(struct ip_set *set) + /* set->ref can be swapped out by ip_set_swap, netlink events (like dump) need + * a separate reference counter + */ ++static void ++__ip_set_get_netlink(struct ip_set *set) ++{ ++ write_lock_bh(&ip_set_ref_lock); ++ set->ref_netlink++; ++ write_unlock_bh(&ip_set_ref_lock); ++} ++ + static void + __ip_set_put_netlink(struct ip_set *set) + { +@@ -1695,11 +1703,11 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb, + + do { + if (retried) { +- __ip_set_get(set); ++ __ip_set_get_netlink(set); + nfnl_unlock(NFNL_SUBSYS_IPSET); + cond_resched(); + nfnl_lock(NFNL_SUBSYS_IPSET); +- __ip_set_put(set); ++ __ip_set_put_netlink(set); + } + + ip_set_lock(set); +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index d84da11aaee5c..8a4cd1c16e0e4 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -31,7 +31,9 @@ static LIST_HEAD(nf_tables_expressions); + static LIST_HEAD(nf_tables_objects); + static LIST_HEAD(nf_tables_flowtables); + static LIST_HEAD(nf_tables_destroy_list); ++static LIST_HEAD(nf_tables_gc_list); + static DEFINE_SPINLOCK(nf_tables_destroy_list_lock); ++static DEFINE_SPINLOCK(nf_tables_gc_list_lock); + + enum { + NFT_VALIDATE_SKIP = 0, +@@ -122,6 +124,9 @@ static void nft_validate_state_update(struct net *net, u8 new_validate_state) + static void nf_tables_trans_destroy_work(struct work_struct *w); + static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work); + ++static void nft_trans_gc_work(struct work_struct *work); ++static DECLARE_WORK(trans_gc_work, nft_trans_gc_work); ++ + static void nft_ctx_init(struct nft_ctx *ctx, + struct net *net, + const struct sk_buff *skb, +@@ -583,10 +588,6 @@ static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type, + return __nft_trans_set_add(ctx, msg_type, set, NULL); + } + +-static void nft_setelem_data_deactivate(const struct net *net, +- const struct nft_set *set, +- struct nft_set_elem *elem); +- + static int nft_mapelem_deactivate(const struct nft_ctx *ctx, + struct nft_set *set, + const struct nft_set_iter *iter, +@@ -1158,6 +1159,10 @@ static int nf_tables_updtable(struct nft_ctx *ctx) + flags & NFT_TABLE_F_OWNER)) + return -EOPNOTSUPP; + ++ /* No dormant off/on/off/on games in single transaction */ ++ if (ctx->table->flags & __NFT_TABLE_F_UPDATE) ++ return -EINVAL; ++ + trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE, + sizeof(struct nft_trans_table)); + if (trans == NULL) +@@ -1343,7 +1348,7 @@ static int nft_flush_table(struct nft_ctx *ctx) + if (!nft_is_active_next(ctx->net, chain)) + continue; + +- if (nft_chain_is_bound(chain)) ++ if (nft_chain_binding(chain)) + continue; + + ctx->chain = chain; +@@ -1357,8 +1362,7 @@ static int nft_flush_table(struct nft_ctx *ctx) + if (!nft_is_active_next(ctx->net, set)) + continue; + +- if (nft_set_is_anonymous(set) && +- !list_empty(&set->bindings)) ++ if (nft_set_is_anonymous(set)) + continue; + + err = nft_delset(ctx, set); +@@ -1388,7 +1392,7 @@ static int nft_flush_table(struct nft_ctx *ctx) + if (!nft_is_active_next(ctx->net, chain)) + continue; + +- if (nft_chain_is_bound(chain)) ++ if (nft_chain_binding(chain)) + continue; + + ctx->chain = chain; +@@ -2693,6 +2697,9 @@ static int nf_tables_delchain(struct sk_buff *skb, const struct nfnl_info *info, + return PTR_ERR(chain); + } + ++ if (nft_chain_binding(chain)) ++ return -EOPNOTSUPP; ++ + if (info->nlh->nlmsg_flags & NLM_F_NONREC && + chain->use > 0) + return -EBUSY; +@@ -3670,6 +3677,11 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, + } + + if (info->nlh->nlmsg_flags & NLM_F_REPLACE) { ++ if (nft_chain_binding(chain)) { ++ err = -EOPNOTSUPP; ++ goto err_destroy_flow_rule; ++ } ++ + err = nft_delrule(&ctx, old_rule); + if (err < 0) + goto err_destroy_flow_rule; +@@ -3773,7 +3785,7 @@ static int nf_tables_delrule(struct sk_buff *skb, const struct nfnl_info *info, + NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]); + return PTR_ERR(chain); + } +- if (nft_chain_is_bound(chain)) ++ if (nft_chain_binding(chain)) + return -EOPNOTSUPP; + } + +@@ -3803,7 +3815,7 @@ static int nf_tables_delrule(struct sk_buff *skb, const struct nfnl_info *info, + list_for_each_entry(chain, &table->chains, list) { + if (!nft_is_active_next(net, chain)) + continue; +- if (nft_chain_is_bound(chain)) ++ if (nft_chain_binding(chain)) + continue; + + ctx.chain = chain; +@@ -4757,6 +4769,7 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, + + INIT_LIST_HEAD(&set->bindings); + INIT_LIST_HEAD(&set->catchall_list); ++ refcount_set(&set->refs, 1); + set->table = table; + write_pnet(&set->net, net); + set->ops = ops; +@@ -4824,6 +4837,14 @@ static void nft_set_catchall_destroy(const struct nft_ctx *ctx, + } + } + ++static void nft_set_put(struct nft_set *set) ++{ ++ if (refcount_dec_and_test(&set->refs)) { ++ kfree(set->name); ++ kvfree(set); ++ } ++} ++ + static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set) + { + int i; +@@ -4836,8 +4857,7 @@ static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set) + + set->ops->destroy(ctx, set); + nft_set_catchall_destroy(ctx, set); +- kfree(set->name); +- kvfree(set); ++ nft_set_put(set); + } + + static int nf_tables_delset(struct sk_buff *skb, const struct nfnl_info *info, +@@ -5289,8 +5309,12 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx, + const struct nft_set_iter *iter, + struct nft_set_elem *elem) + { ++ const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); + struct nft_set_dump_args *args; + ++ if (nft_set_elem_expired(ext)) ++ return 0; ++ + args = container_of(iter, struct nft_set_dump_args, iter); + return nf_tables_fill_setelem(args->skb, set, elem); + } +@@ -5902,7 +5926,8 @@ struct nft_set_ext *nft_set_catchall_lookup(const struct net *net, + list_for_each_entry_rcu(catchall, &set->catchall_list, list) { + ext = nft_set_elem_ext(set, catchall->elem); + if (nft_set_elem_active(ext, genmask) && +- !nft_set_elem_expired(ext)) ++ !nft_set_elem_expired(ext) && ++ !nft_set_elem_is_dead(ext)) + return ext; + } + +@@ -5910,29 +5935,6 @@ struct nft_set_ext *nft_set_catchall_lookup(const struct net *net, + } + EXPORT_SYMBOL_GPL(nft_set_catchall_lookup); + +-void *nft_set_catchall_gc(const struct nft_set *set) +-{ +- struct nft_set_elem_catchall *catchall, *next; +- struct nft_set_ext *ext; +- void *elem = NULL; +- +- list_for_each_entry_safe(catchall, next, &set->catchall_list, list) { +- ext = nft_set_elem_ext(set, catchall->elem); +- +- if (!nft_set_elem_expired(ext) || +- nft_set_elem_mark_busy(ext)) +- continue; +- +- elem = catchall->elem; +- list_del_rcu(&catchall->list); +- kfree_rcu(catchall, rcu); +- break; +- } +- +- return elem; +-} +-EXPORT_SYMBOL_GPL(nft_set_catchall_gc); +- + static int nft_setelem_catchall_insert(const struct net *net, + struct nft_set *set, + const struct nft_set_elem *elem, +@@ -5994,7 +5996,6 @@ static void nft_setelem_activate(struct net *net, struct nft_set *set, + + if (nft_setelem_is_catchall(set, elem)) { + nft_set_elem_change_active(net, set, ext); +- nft_set_elem_clear_busy(ext); + } else { + set->ops->activate(net, set, elem); + } +@@ -6009,8 +6010,7 @@ static int nft_setelem_catchall_deactivate(const struct net *net, + + list_for_each_entry(catchall, &set->catchall_list, list) { + ext = nft_set_elem_ext(set, catchall->elem); +- if (!nft_is_active(net, ext) || +- nft_set_elem_mark_busy(ext)) ++ if (!nft_is_active(net, ext)) + continue; + + kfree(elem->priv); +@@ -6399,7 +6399,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, + goto err_elem_expr; + } + +- ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK; ++ ext->genmask = nft_genmask_cur(ctx->net); + + err = nft_setelem_insert(ctx->net, set, &elem, &ext2, flags); + if (err) { +@@ -6547,9 +6547,9 @@ static void nft_setelem_data_activate(const struct net *net, + nft_use_inc_restore(&(*nft_set_ext_obj(ext))->use); + } + +-static void nft_setelem_data_deactivate(const struct net *net, +- const struct nft_set *set, +- struct nft_set_elem *elem) ++void nft_setelem_data_deactivate(const struct net *net, ++ const struct nft_set *set, ++ struct nft_set_elem *elem) + { + const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); + +@@ -6711,8 +6711,7 @@ static int nft_set_catchall_flush(const struct nft_ctx *ctx, + + list_for_each_entry_rcu(catchall, &set->catchall_list, list) { + ext = nft_set_elem_ext(set, catchall->elem); +- if (!nft_set_elem_active(ext, genmask) || +- nft_set_elem_mark_busy(ext)) ++ if (!nft_set_elem_active(ext, genmask)) + continue; + + elem.priv = catchall->elem; +@@ -6764,8 +6763,10 @@ static int nf_tables_delsetelem(struct sk_buff *skb, + if (IS_ERR(set)) + return PTR_ERR(set); + +- if (!list_empty(&set->bindings) && +- (set->flags & (NFT_SET_CONSTANT | NFT_SET_ANONYMOUS))) ++ if (nft_set_is_anonymous(set)) ++ return -EOPNOTSUPP; ++ ++ if (!list_empty(&set->bindings) && (set->flags & NFT_SET_CONSTANT)) + return -EBUSY; + + nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); +@@ -6781,29 +6782,6 @@ static int nf_tables_delsetelem(struct sk_buff *skb, + return err; + } + +-void nft_set_gc_batch_release(struct rcu_head *rcu) +-{ +- struct nft_set_gc_batch *gcb; +- unsigned int i; +- +- gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu); +- for (i = 0; i < gcb->head.cnt; i++) +- nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true); +- kfree(gcb); +-} +- +-struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set, +- gfp_t gfp) +-{ +- struct nft_set_gc_batch *gcb; +- +- gcb = kzalloc(sizeof(*gcb), gfp); +- if (gcb == NULL) +- return gcb; +- gcb->head.set = set; +- return gcb; +-} +- + /* + * Stateful objects + */ +@@ -8883,6 +8861,234 @@ void nft_chain_del(struct nft_chain *chain) + list_del_rcu(&chain->list); + } + ++static void nft_trans_gc_setelem_remove(struct nft_ctx *ctx, ++ struct nft_trans_gc *trans) ++{ ++ void **priv = trans->priv; ++ unsigned int i; ++ ++ for (i = 0; i < trans->count; i++) { ++ struct nft_set_elem elem = { ++ .priv = priv[i], ++ }; ++ ++ nft_setelem_data_deactivate(ctx->net, trans->set, &elem); ++ nft_setelem_remove(ctx->net, trans->set, &elem); ++ } ++} ++ ++void nft_trans_gc_destroy(struct nft_trans_gc *trans) ++{ ++ nft_set_put(trans->set); ++ put_net(trans->net); ++ kfree(trans); ++} ++ ++static void nft_trans_gc_trans_free(struct rcu_head *rcu) ++{ ++ struct nft_set_elem elem = {}; ++ struct nft_trans_gc *trans; ++ struct nft_ctx ctx = {}; ++ unsigned int i; ++ ++ trans = container_of(rcu, struct nft_trans_gc, rcu); ++ ctx.net = read_pnet(&trans->set->net); ++ ++ for (i = 0; i < trans->count; i++) { ++ elem.priv = trans->priv[i]; ++ if (!nft_setelem_is_catchall(trans->set, &elem)) ++ atomic_dec(&trans->set->nelems); ++ ++ nf_tables_set_elem_destroy(&ctx, trans->set, elem.priv); ++ } ++ ++ nft_trans_gc_destroy(trans); ++} ++ ++static bool nft_trans_gc_work_done(struct nft_trans_gc *trans) ++{ ++ struct nftables_pernet *nft_net; ++ struct nft_ctx ctx = {}; ++ ++ nft_net = nft_pernet(trans->net); ++ ++ mutex_lock(&nft_net->commit_mutex); ++ ++ /* Check for race with transaction, otherwise this batch refers to ++ * stale objects that might not be there anymore. Skip transaction if ++ * set has been destroyed from control plane transaction in case gc ++ * worker loses race. ++ */ ++ if (READ_ONCE(nft_net->gc_seq) != trans->seq || trans->set->dead) { ++ mutex_unlock(&nft_net->commit_mutex); ++ return false; ++ } ++ ++ ctx.net = trans->net; ++ ctx.table = trans->set->table; ++ ++ nft_trans_gc_setelem_remove(&ctx, trans); ++ mutex_unlock(&nft_net->commit_mutex); ++ ++ return true; ++} ++ ++static void nft_trans_gc_work(struct work_struct *work) ++{ ++ struct nft_trans_gc *trans, *next; ++ LIST_HEAD(trans_gc_list); ++ ++ spin_lock(&nf_tables_gc_list_lock); ++ list_splice_init(&nf_tables_gc_list, &trans_gc_list); ++ spin_unlock(&nf_tables_gc_list_lock); ++ ++ list_for_each_entry_safe(trans, next, &trans_gc_list, list) { ++ list_del(&trans->list); ++ if (!nft_trans_gc_work_done(trans)) { ++ nft_trans_gc_destroy(trans); ++ continue; ++ } ++ call_rcu(&trans->rcu, nft_trans_gc_trans_free); ++ } ++} ++ ++struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set, ++ unsigned int gc_seq, gfp_t gfp) ++{ ++ struct net *net = read_pnet(&set->net); ++ struct nft_trans_gc *trans; ++ ++ trans = kzalloc(sizeof(*trans), gfp); ++ if (!trans) ++ return NULL; ++ ++ trans->net = maybe_get_net(net); ++ if (!trans->net) { ++ kfree(trans); ++ return NULL; ++ } ++ ++ refcount_inc(&set->refs); ++ trans->set = set; ++ trans->seq = gc_seq; ++ ++ return trans; ++} ++ ++void nft_trans_gc_elem_add(struct nft_trans_gc *trans, void *priv) ++{ ++ trans->priv[trans->count++] = priv; ++} ++ ++static void nft_trans_gc_queue_work(struct nft_trans_gc *trans) ++{ ++ spin_lock(&nf_tables_gc_list_lock); ++ list_add_tail(&trans->list, &nf_tables_gc_list); ++ spin_unlock(&nf_tables_gc_list_lock); ++ ++ schedule_work(&trans_gc_work); ++} ++ ++static int nft_trans_gc_space(struct nft_trans_gc *trans) ++{ ++ return NFT_TRANS_GC_BATCHCOUNT - trans->count; ++} ++ ++struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc, ++ unsigned int gc_seq, gfp_t gfp) ++{ ++ struct nft_set *set; ++ ++ if (nft_trans_gc_space(gc)) ++ return gc; ++ ++ set = gc->set; ++ nft_trans_gc_queue_work(gc); ++ ++ return nft_trans_gc_alloc(set, gc_seq, gfp); ++} ++ ++void nft_trans_gc_queue_async_done(struct nft_trans_gc *trans) ++{ ++ if (trans->count == 0) { ++ nft_trans_gc_destroy(trans); ++ return; ++ } ++ ++ nft_trans_gc_queue_work(trans); ++} ++ ++struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp) ++{ ++ struct nft_set *set; ++ ++ if (WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net))) ++ return NULL; ++ ++ if (nft_trans_gc_space(gc)) ++ return gc; ++ ++ set = gc->set; ++ call_rcu(&gc->rcu, nft_trans_gc_trans_free); ++ ++ return nft_trans_gc_alloc(set, 0, gfp); ++} ++ ++void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans) ++{ ++ WARN_ON_ONCE(!lockdep_commit_lock_is_held(trans->net)); ++ ++ if (trans->count == 0) { ++ nft_trans_gc_destroy(trans); ++ return; ++ } ++ ++ call_rcu(&trans->rcu, nft_trans_gc_trans_free); ++} ++ ++static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc, ++ unsigned int gc_seq, ++ bool sync) ++{ ++ struct nft_set_elem_catchall *catchall; ++ const struct nft_set *set = gc->set; ++ struct nft_set_ext *ext; ++ ++ list_for_each_entry_rcu(catchall, &set->catchall_list, list) { ++ ext = nft_set_elem_ext(set, catchall->elem); ++ ++ if (!nft_set_elem_expired(ext)) ++ continue; ++ if (nft_set_elem_is_dead(ext)) ++ goto dead_elem; ++ ++ nft_set_elem_dead(ext); ++dead_elem: ++ if (sync) ++ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); ++ else ++ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); ++ ++ if (!gc) ++ return NULL; ++ ++ nft_trans_gc_elem_add(gc, catchall->elem); ++ } ++ ++ return gc; ++} ++ ++struct nft_trans_gc *nft_trans_gc_catchall_async(struct nft_trans_gc *gc, ++ unsigned int gc_seq) ++{ ++ return nft_trans_gc_catchall(gc, gc_seq, false); ++} ++ ++struct nft_trans_gc *nft_trans_gc_catchall_sync(struct nft_trans_gc *gc) ++{ ++ return nft_trans_gc_catchall(gc, 0, true); ++} ++ + static void nf_tables_module_autoload_cleanup(struct net *net) + { + struct nftables_pernet *nft_net = nft_pernet(net); +@@ -9041,15 +9247,31 @@ static void nft_set_commit_update(struct list_head *set_update_list) + } + } + ++static unsigned int nft_gc_seq_begin(struct nftables_pernet *nft_net) ++{ ++ unsigned int gc_seq; ++ ++ /* Bump gc counter, it becomes odd, this is the busy mark. */ ++ gc_seq = READ_ONCE(nft_net->gc_seq); ++ WRITE_ONCE(nft_net->gc_seq, ++gc_seq); ++ ++ return gc_seq; ++} ++ ++static void nft_gc_seq_end(struct nftables_pernet *nft_net, unsigned int gc_seq) ++{ ++ WRITE_ONCE(nft_net->gc_seq, ++gc_seq); ++} ++ + static int nf_tables_commit(struct net *net, struct sk_buff *skb) + { + struct nftables_pernet *nft_net = nft_pernet(net); + struct nft_trans *trans, *next; ++ unsigned int base_seq, gc_seq; + LIST_HEAD(set_update_list); + struct nft_trans_elem *te; + struct nft_chain *chain; + struct nft_table *table; +- unsigned int base_seq; + LIST_HEAD(adl); + int err; + +@@ -9126,6 +9348,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + + WRITE_ONCE(nft_net->base_seq, base_seq); + ++ gc_seq = nft_gc_seq_begin(nft_net); ++ + /* step 3. Start new generation, rules_gen_X now in use. */ + net->nft.gencursor = nft_gencursor_next(net); + +@@ -9214,6 +9438,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + nft_trans_destroy(trans); + break; + case NFT_MSG_DELSET: ++ nft_trans_set(trans)->dead = 1; + list_del_rcu(&nft_trans_set(trans)->list); + nf_tables_set_notify(&trans->ctx, nft_trans_set(trans), + NFT_MSG_DELSET, GFP_KERNEL); +@@ -9313,6 +9538,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + nft_commit_notify(net, NETLINK_CB(skb).portid); + nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN); + nf_tables_commit_audit_log(&adl, nft_net->base_seq); ++ ++ nft_gc_seq_end(nft_net, gc_seq); + nf_tables_commit_release(net); + + return 0; +@@ -9571,7 +9798,12 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb, + enum nfnl_abort_action action) + { + struct nftables_pernet *nft_net = nft_pernet(net); +- int ret = __nf_tables_abort(net, action); ++ unsigned int gc_seq; ++ int ret; ++ ++ gc_seq = nft_gc_seq_begin(nft_net); ++ ret = __nf_tables_abort(net, action); ++ nft_gc_seq_end(nft_net, gc_seq); + + mutex_unlock(&nft_net->commit_mutex); + +@@ -10234,7 +10466,7 @@ static void __nft_release_table(struct net *net, struct nft_table *table) + ctx.family = table->family; + ctx.table = table; + list_for_each_entry(chain, &table->chains, list) { +- if (nft_chain_is_bound(chain)) ++ if (nft_chain_binding(chain)) + continue; + + ctx.chain = chain; +@@ -10295,6 +10527,7 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event, + struct net *net = n->net; + unsigned int deleted; + bool restart = false; ++ unsigned int gc_seq; + + if (event != NETLINK_URELEASE || n->protocol != NETLINK_NETFILTER) + return NOTIFY_DONE; +@@ -10302,6 +10535,9 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event, + nft_net = nft_pernet(net); + deleted = 0; + mutex_lock(&nft_net->commit_mutex); ++ ++ gc_seq = nft_gc_seq_begin(nft_net); ++ + if (!list_empty(&nf_tables_destroy_list)) + nf_tables_trans_destroy_flush_work(); + again: +@@ -10324,6 +10560,8 @@ again: + if (restart) + goto again; + } ++ nft_gc_seq_end(nft_net, gc_seq); ++ + mutex_unlock(&nft_net->commit_mutex); + + return NOTIFY_DONE; +@@ -10345,6 +10583,7 @@ static int __net_init nf_tables_init_net(struct net *net) + mutex_init(&nft_net->commit_mutex); + nft_net->base_seq = 1; + nft_net->validate_state = NFT_VALIDATE_SKIP; ++ nft_net->gc_seq = 0; + + return 0; + } +@@ -10361,22 +10600,36 @@ static void __net_exit nf_tables_pre_exit_net(struct net *net) + static void __net_exit nf_tables_exit_net(struct net *net) + { + struct nftables_pernet *nft_net = nft_pernet(net); ++ unsigned int gc_seq; + + mutex_lock(&nft_net->commit_mutex); ++ ++ gc_seq = nft_gc_seq_begin(nft_net); ++ + if (!list_empty(&nft_net->commit_list) || + !list_empty(&nft_net->module_list)) + __nf_tables_abort(net, NFNL_ABORT_NONE); ++ + __nft_release_tables(net); ++ ++ nft_gc_seq_end(nft_net, gc_seq); ++ + mutex_unlock(&nft_net->commit_mutex); + WARN_ON_ONCE(!list_empty(&nft_net->tables)); + WARN_ON_ONCE(!list_empty(&nft_net->module_list)); + WARN_ON_ONCE(!list_empty(&nft_net->notify_list)); + } + ++static void nf_tables_exit_batch(struct list_head *net_exit_list) ++{ ++ flush_work(&trans_gc_work); ++} ++ + static struct pernet_operations nf_tables_net_ops = { + .init = nf_tables_init_net, + .pre_exit = nf_tables_pre_exit_net, + .exit = nf_tables_exit_net, ++ .exit_batch = nf_tables_exit_batch, + .id = &nf_tables_net_id, + .size = sizeof(struct nftables_pernet), + }; +@@ -10448,6 +10701,7 @@ static void __exit nf_tables_module_exit(void) + nft_chain_filter_fini(); + nft_chain_route_fini(); + unregister_pernet_subsys(&nf_tables_net_ops); ++ cancel_work_sync(&trans_gc_work); + cancel_work_sync(&trans_destroy_work); + rcu_barrier(); + rhltable_destroy(&nft_objname_ht); +diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c +index 3609680831a14..daee46cf62abb 100644 +--- a/net/netfilter/nft_exthdr.c ++++ b/net/netfilter/nft_exthdr.c +@@ -245,7 +245,12 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr, + if (!tcph) + goto err; + ++ if (skb_ensure_writable(pkt->skb, nft_thoff(pkt) + tcphdr_len)) ++ goto err; ++ ++ tcph = (struct tcphdr *)(pkt->skb->data + nft_thoff(pkt)); + opt = (u8 *)tcph; ++ + for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) { + union { + __be16 v16; +@@ -260,15 +265,6 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr, + if (i + optl > tcphdr_len || priv->len + priv->offset > optl) + goto err; + +- if (skb_ensure_writable(pkt->skb, +- nft_thoff(pkt) + i + priv->len)) +- goto err; +- +- tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, +- &tcphdr_len); +- if (!tcph) +- goto err; +- + offset = i + priv->offset; + + switch (priv->len) { +@@ -315,6 +311,63 @@ err: + regs->verdict.code = NFT_BREAK; + } + ++static void nft_exthdr_tcp_strip_eval(const struct nft_expr *expr, ++ struct nft_regs *regs, ++ const struct nft_pktinfo *pkt) ++{ ++ u8 buff[sizeof(struct tcphdr) + MAX_TCP_OPTION_SPACE]; ++ struct nft_exthdr *priv = nft_expr_priv(expr); ++ unsigned int i, tcphdr_len, optl; ++ struct tcphdr *tcph; ++ u8 *opt; ++ ++ tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len); ++ if (!tcph) ++ goto err; ++ ++ if (skb_ensure_writable(pkt->skb, nft_thoff(pkt) + tcphdr_len)) ++ goto drop; ++ ++ tcph = (struct tcphdr *)(pkt->skb->data + nft_thoff(pkt)); ++ opt = (u8 *)tcph; ++ ++ for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) { ++ unsigned int j; ++ ++ optl = optlen(opt, i); ++ if (priv->type != opt[i]) ++ continue; ++ ++ if (i + optl > tcphdr_len) ++ goto drop; ++ ++ for (j = 0; j < optl; ++j) { ++ u16 n = TCPOPT_NOP; ++ u16 o = opt[i+j]; ++ ++ if ((i + j) % 2 == 0) { ++ o <<= 8; ++ n <<= 8; ++ } ++ inet_proto_csum_replace2(&tcph->check, pkt->skb, htons(o), ++ htons(n), false); ++ } ++ memset(opt + i, TCPOPT_NOP, optl); ++ return; ++ } ++ ++ /* option not found, continue. This allows to do multiple ++ * option removals per rule. ++ */ ++ return; ++err: ++ regs->verdict.code = NFT_BREAK; ++ return; ++drop: ++ /* can't remove, no choice but to drop */ ++ regs->verdict.code = NF_DROP; ++} ++ + static void nft_exthdr_sctp_eval(const struct nft_expr *expr, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +@@ -463,6 +516,28 @@ static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx, + priv->len); + } + ++static int nft_exthdr_tcp_strip_init(const struct nft_ctx *ctx, ++ const struct nft_expr *expr, ++ const struct nlattr * const tb[]) ++{ ++ struct nft_exthdr *priv = nft_expr_priv(expr); ++ ++ if (tb[NFTA_EXTHDR_SREG] || ++ tb[NFTA_EXTHDR_DREG] || ++ tb[NFTA_EXTHDR_FLAGS] || ++ tb[NFTA_EXTHDR_OFFSET] || ++ tb[NFTA_EXTHDR_LEN]) ++ return -EINVAL; ++ ++ if (!tb[NFTA_EXTHDR_TYPE]) ++ return -EINVAL; ++ ++ priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); ++ priv->op = NFT_EXTHDR_OP_TCPOPT; ++ ++ return 0; ++} ++ + static int nft_exthdr_ipv4_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]) +@@ -523,6 +598,13 @@ static int nft_exthdr_dump_set(struct sk_buff *skb, const struct nft_expr *expr) + return nft_exthdr_dump_common(skb, priv); + } + ++static int nft_exthdr_dump_strip(struct sk_buff *skb, const struct nft_expr *expr) ++{ ++ const struct nft_exthdr *priv = nft_expr_priv(expr); ++ ++ return nft_exthdr_dump_common(skb, priv); ++} ++ + static const struct nft_expr_ops nft_exthdr_ipv6_ops = { + .type = &nft_exthdr_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_exthdr)), +@@ -555,6 +637,14 @@ static const struct nft_expr_ops nft_exthdr_tcp_set_ops = { + .dump = nft_exthdr_dump_set, + }; + ++static const struct nft_expr_ops nft_exthdr_tcp_strip_ops = { ++ .type = &nft_exthdr_type, ++ .size = NFT_EXPR_SIZE(sizeof(struct nft_exthdr)), ++ .eval = nft_exthdr_tcp_strip_eval, ++ .init = nft_exthdr_tcp_strip_init, ++ .dump = nft_exthdr_dump_strip, ++}; ++ + static const struct nft_expr_ops nft_exthdr_sctp_ops = { + .type = &nft_exthdr_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_exthdr)), +@@ -582,7 +672,7 @@ nft_exthdr_select_ops(const struct nft_ctx *ctx, + return &nft_exthdr_tcp_set_ops; + if (tb[NFTA_EXTHDR_DREG]) + return &nft_exthdr_tcp_ops; +- break; ++ return &nft_exthdr_tcp_strip_ops; + case NFT_EXTHDR_OP_IPV6: + if (tb[NFTA_EXTHDR_DREG]) + return &nft_exthdr_ipv6_ops; +diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c +index 0b73cb0e752f7..2013de934cef0 100644 +--- a/net/netfilter/nft_set_hash.c ++++ b/net/netfilter/nft_set_hash.c +@@ -59,6 +59,8 @@ static inline int nft_rhash_cmp(struct rhashtable_compare_arg *arg, + + if (memcmp(nft_set_ext_key(&he->ext), x->key, x->set->klen)) + return 1; ++ if (nft_set_elem_is_dead(&he->ext)) ++ return 1; + if (nft_set_elem_expired(&he->ext)) + return 1; + if (!nft_set_elem_active(&he->ext, x->genmask)) +@@ -188,7 +190,6 @@ static void nft_rhash_activate(const struct net *net, const struct nft_set *set, + struct nft_rhash_elem *he = elem->priv; + + nft_set_elem_change_active(net, set, &he->ext); +- nft_set_elem_clear_busy(&he->ext); + } + + static bool nft_rhash_flush(const struct net *net, +@@ -196,12 +197,9 @@ static bool nft_rhash_flush(const struct net *net, + { + struct nft_rhash_elem *he = priv; + +- if (!nft_set_elem_mark_busy(&he->ext) || +- !nft_is_active(net, &he->ext)) { +- nft_set_elem_change_active(net, set, &he->ext); +- return true; +- } +- return false; ++ nft_set_elem_change_active(net, set, &he->ext); ++ ++ return true; + } + + static void *nft_rhash_deactivate(const struct net *net, +@@ -218,9 +216,8 @@ static void *nft_rhash_deactivate(const struct net *net, + + rcu_read_lock(); + he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params); +- if (he != NULL && +- !nft_rhash_flush(net, set, he)) +- he = NULL; ++ if (he) ++ nft_set_elem_change_active(net, set, &he->ext); + + rcu_read_unlock(); + +@@ -252,7 +249,9 @@ static bool nft_rhash_delete(const struct nft_set *set, + if (he == NULL) + return false; + +- return rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params) == 0; ++ nft_set_elem_dead(&he->ext); ++ ++ return true; + } + + static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set, +@@ -278,8 +277,6 @@ static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set, + + if (iter->count < iter->skip) + goto cont; +- if (nft_set_elem_expired(&he->ext)) +- goto cont; + if (!nft_set_elem_active(&he->ext, iter->genmask)) + goto cont; + +@@ -314,25 +311,48 @@ static bool nft_rhash_expr_needs_gc_run(const struct nft_set *set, + + static void nft_rhash_gc(struct work_struct *work) + { ++ struct nftables_pernet *nft_net; + struct nft_set *set; + struct nft_rhash_elem *he; + struct nft_rhash *priv; +- struct nft_set_gc_batch *gcb = NULL; + struct rhashtable_iter hti; ++ struct nft_trans_gc *gc; ++ struct net *net; ++ u32 gc_seq; + + priv = container_of(work, struct nft_rhash, gc_work.work); + set = nft_set_container_of(priv); ++ net = read_pnet(&set->net); ++ nft_net = nft_pernet(net); ++ gc_seq = READ_ONCE(nft_net->gc_seq); ++ ++ if (nft_set_gc_is_pending(set)) ++ goto done; ++ ++ gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL); ++ if (!gc) ++ goto done; + + rhashtable_walk_enter(&priv->ht, &hti); + rhashtable_walk_start(&hti); + + while ((he = rhashtable_walk_next(&hti))) { + if (IS_ERR(he)) { +- if (PTR_ERR(he) != -EAGAIN) +- break; +- continue; ++ nft_trans_gc_destroy(gc); ++ gc = NULL; ++ goto try_later; ++ } ++ ++ /* Ruleset has been updated, try later. */ ++ if (READ_ONCE(nft_net->gc_seq) != gc_seq) { ++ nft_trans_gc_destroy(gc); ++ gc = NULL; ++ goto try_later; + } + ++ if (nft_set_elem_is_dead(&he->ext)) ++ goto dead_elem; ++ + if (nft_set_ext_exists(&he->ext, NFT_SET_EXT_EXPRESSIONS) && + nft_rhash_expr_needs_gc_run(set, &he->ext)) + goto needs_gc_run; +@@ -340,26 +360,26 @@ static void nft_rhash_gc(struct work_struct *work) + if (!nft_set_elem_expired(&he->ext)) + continue; + needs_gc_run: +- if (nft_set_elem_mark_busy(&he->ext)) +- continue; ++ nft_set_elem_dead(&he->ext); ++dead_elem: ++ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); ++ if (!gc) ++ goto try_later; + +- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC); +- if (gcb == NULL) +- break; +- rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params); +- atomic_dec(&set->nelems); +- nft_set_gc_batch_add(gcb, he); ++ nft_trans_gc_elem_add(gc, he); + } ++ ++ gc = nft_trans_gc_catchall_async(gc, gc_seq); ++ ++try_later: ++ /* catchall list iteration requires rcu read side lock. */ + rhashtable_walk_stop(&hti); + rhashtable_walk_exit(&hti); + +- he = nft_set_catchall_gc(set); +- if (he) { +- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC); +- if (gcb) +- nft_set_gc_batch_add(gcb, he); +- } +- nft_set_gc_batch_complete(gcb); ++ if (gc) ++ nft_trans_gc_queue_async_done(gc); ++ ++done: + queue_delayed_work(system_power_efficient_wq, &priv->gc_work, + nft_set_gc_interval(set)); + } +@@ -394,7 +414,7 @@ static int nft_rhash_init(const struct nft_set *set, + return err; + + INIT_DEFERRABLE_WORK(&priv->gc_work, nft_rhash_gc); +- if (set->flags & NFT_SET_TIMEOUT) ++ if (set->flags & (NFT_SET_TIMEOUT | NFT_SET_EVAL)) + nft_rhash_gc_init(set); + + return 0; +@@ -422,7 +442,6 @@ static void nft_rhash_destroy(const struct nft_ctx *ctx, + }; + + cancel_delayed_work_sync(&priv->gc_work); +- rcu_barrier(); + rhashtable_free_and_destroy(&priv->ht, nft_rhash_elem_destroy, + (void *)&rhash_ctx); + } +diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c +index 8c16681884b7e..deea6196d9925 100644 +--- a/net/netfilter/nft_set_pipapo.c ++++ b/net/netfilter/nft_set_pipapo.c +@@ -566,8 +566,9 @@ next_match: + goto out; + + if (last) { +- if (nft_set_elem_expired(&f->mt[b].e->ext) || +- (genmask && ++ if (nft_set_elem_expired(&f->mt[b].e->ext)) ++ goto next_match; ++ if ((genmask && + !nft_set_elem_active(&f->mt[b].e->ext, genmask))) + goto next_match; + +@@ -602,7 +603,7 @@ static void *nft_pipapo_get(const struct net *net, const struct nft_set *set, + const struct nft_set_elem *elem, unsigned int flags) + { + return pipapo_get(net, set, (const u8 *)elem->key.val.data, +- nft_genmask_cur(net)); ++ nft_genmask_cur(net)); + } + + /** +@@ -1536,16 +1537,34 @@ static void pipapo_drop(struct nft_pipapo_match *m, + } + } + ++static void nft_pipapo_gc_deactivate(struct net *net, struct nft_set *set, ++ struct nft_pipapo_elem *e) ++ ++{ ++ struct nft_set_elem elem = { ++ .priv = e, ++ }; ++ ++ nft_setelem_data_deactivate(net, set, &elem); ++} ++ + /** + * pipapo_gc() - Drop expired entries from set, destroy start and end elements +- * @set: nftables API set representation ++ * @_set: nftables API set representation + * @m: Matching data + */ +-static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m) ++static void pipapo_gc(const struct nft_set *_set, struct nft_pipapo_match *m) + { ++ struct nft_set *set = (struct nft_set *) _set; + struct nft_pipapo *priv = nft_set_priv(set); ++ struct net *net = read_pnet(&set->net); + int rules_f0, first_rule = 0; + struct nft_pipapo_elem *e; ++ struct nft_trans_gc *gc; ++ ++ gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL); ++ if (!gc) ++ return; + + while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) { + union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS]; +@@ -1569,13 +1588,20 @@ static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m) + f--; + i--; + e = f->mt[rulemap[i].to].e; +- if (nft_set_elem_expired(&e->ext) && +- !nft_set_elem_mark_busy(&e->ext)) { ++ ++ /* synchronous gc never fails, there is no need to set on ++ * NFT_SET_ELEM_DEAD_BIT. ++ */ ++ if (nft_set_elem_expired(&e->ext)) { + priv->dirty = true; +- pipapo_drop(m, rulemap); + +- rcu_barrier(); +- nft_set_elem_destroy(set, e, true); ++ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); ++ if (!gc) ++ return; ++ ++ nft_pipapo_gc_deactivate(net, set, e); ++ pipapo_drop(m, rulemap); ++ nft_trans_gc_elem_add(gc, e); + + /* And check again current first rule, which is now the + * first we haven't checked. +@@ -1585,11 +1611,11 @@ static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m) + } + } + +- e = nft_set_catchall_gc(set); +- if (e) +- nft_set_elem_destroy(set, e, true); +- +- priv->last_gc = jiffies; ++ gc = nft_trans_gc_catchall_sync(gc); ++ if (gc) { ++ nft_trans_gc_queue_sync_done(gc); ++ priv->last_gc = jiffies; ++ } + } + + /** +@@ -1718,14 +1744,9 @@ static void nft_pipapo_activate(const struct net *net, + const struct nft_set *set, + const struct nft_set_elem *elem) + { +- struct nft_pipapo_elem *e; +- +- e = pipapo_get(net, set, (const u8 *)elem->key.val.data, 0); +- if (IS_ERR(e)) +- return; ++ struct nft_pipapo_elem *e = elem->priv; + + nft_set_elem_change_active(net, set, &e->ext); +- nft_set_elem_clear_busy(&e->ext); + } + + /** +@@ -1937,10 +1958,6 @@ static void nft_pipapo_remove(const struct net *net, const struct nft_set *set, + + data = (const u8 *)nft_set_ext_key(&e->ext); + +- e = pipapo_get(net, set, data, 0); +- if (IS_ERR(e)) +- return; +- + while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) { + union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS]; + const u8 *match_start, *match_end; +@@ -2024,8 +2041,6 @@ static void nft_pipapo_walk(const struct nft_ctx *ctx, struct nft_set *set, + goto cont; + + e = f->mt[r].e; +- if (nft_set_elem_expired(&e->ext)) +- goto cont; + + elem.priv = e; + +diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c +index 8d73fffd2d09d..487572dcd6144 100644 +--- a/net/netfilter/nft_set_rbtree.c ++++ b/net/netfilter/nft_set_rbtree.c +@@ -46,6 +46,12 @@ static int nft_rbtree_cmp(const struct nft_set *set, + set->klen); + } + ++static bool nft_rbtree_elem_expired(const struct nft_rbtree_elem *rbe) ++{ ++ return nft_set_elem_expired(&rbe->ext) || ++ nft_set_elem_is_dead(&rbe->ext); ++} ++ + static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set, + const u32 *key, const struct nft_set_ext **ext, + unsigned int seq) +@@ -80,7 +86,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set + continue; + } + +- if (nft_set_elem_expired(&rbe->ext)) ++ if (nft_rbtree_elem_expired(rbe)) + return false; + + if (nft_rbtree_interval_end(rbe)) { +@@ -98,7 +104,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set + + if (set->flags & NFT_SET_INTERVAL && interval != NULL && + nft_set_elem_active(&interval->ext, genmask) && +- !nft_set_elem_expired(&interval->ext) && ++ !nft_rbtree_elem_expired(interval) && + nft_rbtree_interval_start(interval)) { + *ext = &interval->ext; + return true; +@@ -215,6 +221,18 @@ static void *nft_rbtree_get(const struct net *net, const struct nft_set *set, + return rbe; + } + ++static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set, ++ struct nft_rbtree *priv, ++ struct nft_rbtree_elem *rbe) ++{ ++ struct nft_set_elem elem = { ++ .priv = rbe, ++ }; ++ ++ nft_setelem_data_deactivate(net, set, &elem); ++ rb_erase(&rbe->node, &priv->root); ++} ++ + static int nft_rbtree_gc_elem(const struct nft_set *__set, + struct nft_rbtree *priv, + struct nft_rbtree_elem *rbe, +@@ -222,11 +240,12 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, + { + struct nft_set *set = (struct nft_set *)__set; + struct rb_node *prev = rb_prev(&rbe->node); ++ struct net *net = read_pnet(&set->net); + struct nft_rbtree_elem *rbe_prev; +- struct nft_set_gc_batch *gcb; ++ struct nft_trans_gc *gc; + +- gcb = nft_set_gc_batch_check(set, NULL, GFP_ATOMIC); +- if (!gcb) ++ gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC); ++ if (!gc) + return -ENOMEM; + + /* search for end interval coming before this element. +@@ -244,17 +263,28 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, + + if (prev) { + rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); ++ nft_rbtree_gc_remove(net, set, priv, rbe_prev); ++ ++ /* There is always room in this trans gc for this element, ++ * memory allocation never actually happens, hence, the warning ++ * splat in such case. No need to set NFT_SET_ELEM_DEAD_BIT, ++ * this is synchronous gc which never fails. ++ */ ++ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); ++ if (WARN_ON_ONCE(!gc)) ++ return -ENOMEM; + +- rb_erase(&rbe_prev->node, &priv->root); +- atomic_dec(&set->nelems); +- nft_set_gc_batch_add(gcb, rbe_prev); ++ nft_trans_gc_elem_add(gc, rbe_prev); + } + +- rb_erase(&rbe->node, &priv->root); +- atomic_dec(&set->nelems); ++ nft_rbtree_gc_remove(net, set, priv, rbe); ++ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); ++ if (WARN_ON_ONCE(!gc)) ++ return -ENOMEM; ++ ++ nft_trans_gc_elem_add(gc, rbe); + +- nft_set_gc_batch_add(gcb, rbe); +- nft_set_gc_batch_complete(gcb); ++ nft_trans_gc_queue_sync_done(gc); + + return 0; + } +@@ -282,6 +312,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, + struct nft_rbtree_elem *rbe, *rbe_le = NULL, *rbe_ge = NULL; + struct rb_node *node, *next, *parent, **p, *first = NULL; + struct nft_rbtree *priv = nft_set_priv(set); ++ u8 cur_genmask = nft_genmask_cur(net); + u8 genmask = nft_genmask_next(net); + int d, err; + +@@ -327,8 +358,11 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, + if (!nft_set_elem_active(&rbe->ext, genmask)) + continue; + +- /* perform garbage collection to avoid bogus overlap reports. */ +- if (nft_set_elem_expired(&rbe->ext)) { ++ /* perform garbage collection to avoid bogus overlap reports ++ * but skip new elements in this transaction. ++ */ ++ if (nft_set_elem_expired(&rbe->ext) && ++ nft_set_elem_active(&rbe->ext, cur_genmask)) { + err = nft_rbtree_gc_elem(set, priv, rbe, genmask); + if (err < 0) + return err; +@@ -482,7 +516,6 @@ static void nft_rbtree_activate(const struct net *net, + struct nft_rbtree_elem *rbe = elem->priv; + + nft_set_elem_change_active(net, set, &rbe->ext); +- nft_set_elem_clear_busy(&rbe->ext); + } + + static bool nft_rbtree_flush(const struct net *net, +@@ -490,12 +523,9 @@ static bool nft_rbtree_flush(const struct net *net, + { + struct nft_rbtree_elem *rbe = priv; + +- if (!nft_set_elem_mark_busy(&rbe->ext) || +- !nft_is_active(net, &rbe->ext)) { +- nft_set_elem_change_active(net, set, &rbe->ext); +- return true; +- } +- return false; ++ nft_set_elem_change_active(net, set, &rbe->ext); ++ ++ return true; + } + + static void *nft_rbtree_deactivate(const struct net *net, +@@ -552,8 +582,6 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx, + + if (iter->count < iter->skip) + goto cont; +- if (nft_set_elem_expired(&rbe->ext)) +- goto cont; + if (!nft_set_elem_active(&rbe->ext, iter->genmask)) + goto cont; + +@@ -572,26 +600,42 @@ cont: + + static void nft_rbtree_gc(struct work_struct *work) + { +- struct nft_rbtree_elem *rbe, *rbe_end = NULL, *rbe_prev = NULL; +- struct nft_set_gc_batch *gcb = NULL; ++ struct nft_rbtree_elem *rbe, *rbe_end = NULL; ++ struct nftables_pernet *nft_net; + struct nft_rbtree *priv; ++ struct nft_trans_gc *gc; + struct rb_node *node; + struct nft_set *set; ++ unsigned int gc_seq; + struct net *net; +- u8 genmask; + + priv = container_of(work, struct nft_rbtree, gc_work.work); + set = nft_set_container_of(priv); + net = read_pnet(&set->net); +- genmask = nft_genmask_cur(net); ++ nft_net = nft_pernet(net); ++ gc_seq = READ_ONCE(nft_net->gc_seq); + +- write_lock_bh(&priv->lock); +- write_seqcount_begin(&priv->count); ++ if (nft_set_gc_is_pending(set)) ++ goto done; ++ ++ gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL); ++ if (!gc) ++ goto done; ++ ++ read_lock_bh(&priv->lock); + for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) { ++ ++ /* Ruleset has been updated, try later. */ ++ if (READ_ONCE(nft_net->gc_seq) != gc_seq) { ++ nft_trans_gc_destroy(gc); ++ gc = NULL; ++ goto try_later; ++ } ++ + rbe = rb_entry(node, struct nft_rbtree_elem, node); + +- if (!nft_set_elem_active(&rbe->ext, genmask)) +- continue; ++ if (nft_set_elem_is_dead(&rbe->ext)) ++ goto dead_elem; + + /* elements are reversed in the rbtree for historical reasons, + * from highest to lowest value, that is why end element is +@@ -604,46 +648,35 @@ static void nft_rbtree_gc(struct work_struct *work) + if (!nft_set_elem_expired(&rbe->ext)) + continue; + +- if (nft_set_elem_mark_busy(&rbe->ext)) { +- rbe_end = NULL; ++ nft_set_elem_dead(&rbe->ext); ++ ++ if (!rbe_end) + continue; +- } + +- if (rbe_prev) { +- rb_erase(&rbe_prev->node, &priv->root); +- rbe_prev = NULL; +- } +- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC); +- if (!gcb) +- break; ++ nft_set_elem_dead(&rbe_end->ext); + +- atomic_dec(&set->nelems); +- nft_set_gc_batch_add(gcb, rbe); +- rbe_prev = rbe; ++ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); ++ if (!gc) ++ goto try_later; + +- if (rbe_end) { +- atomic_dec(&set->nelems); +- nft_set_gc_batch_add(gcb, rbe_end); +- rb_erase(&rbe_end->node, &priv->root); +- rbe_end = NULL; +- } +- node = rb_next(node); +- if (!node) +- break; +- } +- if (rbe_prev) +- rb_erase(&rbe_prev->node, &priv->root); +- write_seqcount_end(&priv->count); +- write_unlock_bh(&priv->lock); ++ nft_trans_gc_elem_add(gc, rbe_end); ++ rbe_end = NULL; ++dead_elem: ++ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); ++ if (!gc) ++ goto try_later; + +- rbe = nft_set_catchall_gc(set); +- if (rbe) { +- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC); +- if (gcb) +- nft_set_gc_batch_add(gcb, rbe); ++ nft_trans_gc_elem_add(gc, rbe); + } +- nft_set_gc_batch_complete(gcb); + ++ gc = nft_trans_gc_catchall_async(gc, gc_seq); ++ ++try_later: ++ read_unlock_bh(&priv->lock); ++ ++ if (gc) ++ nft_trans_gc_queue_async_done(gc); ++done: + queue_delayed_work(system_power_efficient_wq, &priv->gc_work, + nft_set_gc_interval(set)); + } +diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c +index a9e4ff948a7d6..f71f073fd27ac 100644 +--- a/net/rds/rdma_transport.c ++++ b/net/rds/rdma_transport.c +@@ -86,11 +86,13 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id, + break; + + case RDMA_CM_EVENT_ADDR_RESOLVED: +- rdma_set_service_type(cm_id, conn->c_tos); +- rdma_set_min_rnr_timer(cm_id, IB_RNR_TIMER_000_32); +- /* XXX do we need to clean up if this fails? */ +- ret = rdma_resolve_route(cm_id, +- RDS_RDMA_RESOLVE_TIMEOUT_MS); ++ if (conn) { ++ rdma_set_service_type(cm_id, conn->c_tos); ++ rdma_set_min_rnr_timer(cm_id, IB_RNR_TIMER_000_32); ++ /* XXX do we need to clean up if this fails? */ ++ ret = rdma_resolve_route(cm_id, ++ RDS_RDMA_RESOLVE_TIMEOUT_MS); ++ } + break; + + case RDMA_CM_EVENT_ROUTE_RESOLVED: +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index b9c54c03c30a6..7756c62e0c3ed 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -2392,8 +2392,7 @@ call_status(struct rpc_task *task) + goto out_exit; + } + task->tk_action = call_encode; +- if (status != -ECONNRESET && status != -ECONNABORTED) +- rpc_check_timeout(task); ++ rpc_check_timeout(task); + return; + out_exit: + rpc_call_rpcerror(task, status); +@@ -2668,6 +2667,7 @@ out_msg_denied: + case rpc_autherr_rejectedverf: + case rpcsec_gsserr_credproblem: + case rpcsec_gsserr_ctxproblem: ++ rpcauth_invalcred(task); + if (!task->tk_cred_retry) + break; + task->tk_cred_retry--; +@@ -2821,19 +2821,22 @@ static const struct rpc_call_ops rpc_cb_add_xprt_call_ops = { + * @clnt: pointer to struct rpc_clnt + * @xps: pointer to struct rpc_xprt_switch, + * @xprt: pointer struct rpc_xprt +- * @dummy: unused ++ * @in_max_connect: pointer to the max_connect value for the passed in xprt transport + */ + int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, + struct rpc_xprt_switch *xps, struct rpc_xprt *xprt, +- void *dummy) ++ void *in_max_connect) + { + struct rpc_cb_add_xprt_calldata *data; + struct rpc_task *task; ++ int max_connect = clnt->cl_max_connect; + +- if (xps->xps_nunique_destaddr_xprts + 1 > clnt->cl_max_connect) { ++ if (in_max_connect) ++ max_connect = *(int *)in_max_connect; ++ if (xps->xps_nunique_destaddr_xprts + 1 > max_connect) { + rcu_read_lock(); + pr_warn("SUNRPC: reached max allowed number (%d) did not add " +- "transport to server: %s\n", clnt->cl_max_connect, ++ "transport to server: %s\n", max_connect, + rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR)); + rcu_read_unlock(); + return -EINVAL; +diff --git a/security/smack/smack.h b/security/smack/smack.h +index 99c3422596ab9..a71b7a1ca24c2 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -120,6 +120,7 @@ struct inode_smack { + struct task_smack { + struct smack_known *smk_task; /* label for access control */ + struct smack_known *smk_forked; /* label when forked */ ++ struct smack_known *smk_transmuted;/* label when transmuted */ + struct list_head smk_rules; /* per task access rules */ + struct mutex smk_rules_lock; /* lock for the rules */ + struct list_head smk_relabel; /* transit allowed labels */ +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 3f3f56f6be4da..39f564f47fea5 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -955,8 +955,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + const struct qstr *qstr, const char **name, + void **value, size_t *len) + { ++ struct task_smack *tsp = smack_cred(current_cred()); + struct inode_smack *issp = smack_inode(inode); +- struct smack_known *skp = smk_of_current(); ++ struct smack_known *skp = smk_of_task(tsp); + struct smack_known *isp = smk_of_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); + int may; +@@ -965,20 +966,34 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + *name = XATTR_SMACK_SUFFIX; + + if (value && len) { +- rcu_read_lock(); +- may = smk_access_entry(skp->smk_known, dsp->smk_known, +- &skp->smk_rules); +- rcu_read_unlock(); ++ /* ++ * If equal, transmuting already occurred in ++ * smack_dentry_create_files_as(). No need to check again. ++ */ ++ if (tsp->smk_task != tsp->smk_transmuted) { ++ rcu_read_lock(); ++ may = smk_access_entry(skp->smk_known, dsp->smk_known, ++ &skp->smk_rules); ++ rcu_read_unlock(); ++ } + + /* +- * If the access rule allows transmutation and +- * the directory requests transmutation then +- * by all means transmute. ++ * In addition to having smk_task equal to smk_transmuted, ++ * if the access rule allows transmutation and the directory ++ * requests transmutation then by all means transmute. + * Mark the inode as changed. + */ +- if (may > 0 && ((may & MAY_TRANSMUTE) != 0) && +- smk_inode_transmutable(dir)) { +- isp = dsp; ++ if ((tsp->smk_task == tsp->smk_transmuted) || ++ (may > 0 && ((may & MAY_TRANSMUTE) != 0) && ++ smk_inode_transmutable(dir))) { ++ /* ++ * The caller of smack_dentry_create_files_as() ++ * should have overridden the current cred, so the ++ * inode label was already set correctly in ++ * smack_inode_alloc_security(). ++ */ ++ if (tsp->smk_task != tsp->smk_transmuted) ++ isp = dsp; + issp->smk_flags |= SMK_INODE_CHANGED; + } + +@@ -1414,10 +1429,19 @@ static int smack_inode_getsecurity(struct user_namespace *mnt_userns, + struct super_block *sbp; + struct inode *ip = (struct inode *)inode; + struct smack_known *isp; ++ struct inode_smack *ispp; ++ size_t label_len; ++ char *label = NULL; + +- if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) ++ if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { + isp = smk_of_inode(inode); +- else { ++ } else if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) { ++ ispp = smack_inode(inode); ++ if (ispp->smk_flags & SMK_INODE_TRANSMUTE) ++ label = TRANS_TRUE; ++ else ++ label = ""; ++ } else { + /* + * The rest of the Smack xattrs are only on sockets. + */ +@@ -1439,13 +1463,18 @@ static int smack_inode_getsecurity(struct user_namespace *mnt_userns, + return -EOPNOTSUPP; + } + ++ if (!label) ++ label = isp->smk_known; ++ ++ label_len = strlen(label); ++ + if (alloc) { +- *buffer = kstrdup(isp->smk_known, GFP_KERNEL); ++ *buffer = kstrdup(label, GFP_KERNEL); + if (*buffer == NULL) + return -ENOMEM; + } + +- return strlen(isp->smk_known); ++ return label_len; + } + + +@@ -4634,7 +4663,7 @@ static int smack_inode_copy_up(struct dentry *dentry, struct cred **new) + /* + * Get label from overlay inode and set it in create_sid + */ +- isp = smack_inode(d_inode(dentry->d_parent)); ++ isp = smack_inode(d_inode(dentry)); + skp = isp->smk_inode; + tsp->smk_task = skp; + *new = new_creds; +@@ -4685,8 +4714,10 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, + * providing access is transmuting use the containing + * directory label instead of the process label. + */ +- if (may > 0 && (may & MAY_TRANSMUTE)) ++ if (may > 0 && (may & MAY_TRANSMUTE)) { + ntsp->smk_task = isp->smk_inode; ++ ntsp->smk_transmuted = ntsp->smk_task; ++ } + } + return 0; + } +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 1379ac07df350..1e9092d7e9e8f 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2203,6 +2203,7 @@ static const struct snd_pci_quirk power_save_denylist[] = { + SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0), + /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */ + SND_PCI_QUIRK(0x17aa, 0x2227, "Lenovo X1 Carbon 3rd Gen", 0), ++ SND_PCI_QUIRK(0x17aa, 0x316e, "Lenovo ThinkCentre M70q", 0), + /* https://bugzilla.redhat.com/show_bug.cgi?id=1689623 */ + SND_PCI_QUIRK(0x17aa, 0x367b, "Lenovo IdeaCentre B550", 0), + /* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */ +diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c +index d991e457060c7..0363255c39ea9 100644 +--- a/sound/soc/fsl/imx-audmix.c ++++ b/sound/soc/fsl/imx-audmix.c +@@ -320,7 +320,7 @@ static int imx_audmix_probe(struct platform_device *pdev) + if (IS_ERR(priv->cpu_mclk)) { + ret = PTR_ERR(priv->cpu_mclk); + dev_err(&cpu_pdev->dev, "failed to get DAI mclk1: %d\n", ret); +- return -EINVAL; ++ return ret; + } + + priv->audmix_pdev = audmix_pdev; +diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c +index 35049043e5322..933bac7ea1864 100644 +--- a/sound/soc/fsl/imx-pcm-rpmsg.c ++++ b/sound/soc/fsl/imx-pcm-rpmsg.c +@@ -19,6 +19,7 @@ + static struct snd_pcm_hardware imx_rpmsg_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | ++ SNDRV_PCM_INFO_BATCH | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP | +diff --git a/sound/soc/fsl/imx-rpmsg.c b/sound/soc/fsl/imx-rpmsg.c +index f96fe4ff8425b..d208b05051fd5 100644 +--- a/sound/soc/fsl/imx-rpmsg.c ++++ b/sound/soc/fsl/imx-rpmsg.c +@@ -66,6 +66,14 @@ static int imx_rpmsg_probe(struct platform_device *pdev) + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS; + ++ /* ++ * i.MX rpmsg sound cards work on codec slave mode. MCLK will be ++ * disabled by CPU DAI driver in hw_free(). Some codec requires MCLK ++ * present at power up/down sequence. So need to set ignore_pmdown_time ++ * to power down codec immediately before MCLK is turned off. ++ */ ++ data->dai.ignore_pmdown_time = 1; ++ + /* Optional codec node */ + ret = of_parse_phandle_with_fixed_args(np, "audio-codec", 0, 0, &args); + if (ret) { +diff --git a/sound/soc/meson/axg-spdifin.c b/sound/soc/meson/axg-spdifin.c +index d0d09f945b489..7aaded1fc376b 100644 +--- a/sound/soc/meson/axg-spdifin.c ++++ b/sound/soc/meson/axg-spdifin.c +@@ -112,34 +112,6 @@ static int axg_spdifin_prepare(struct snd_pcm_substream *substream, + return 0; + } + +-static int axg_spdifin_startup(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai) +-{ +- struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); +- int ret; +- +- ret = clk_prepare_enable(priv->refclk); +- if (ret) { +- dev_err(dai->dev, +- "failed to enable spdifin reference clock\n"); +- return ret; +- } +- +- regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, +- SPDIFIN_CTRL0_EN); +- +- return 0; +-} +- +-static void axg_spdifin_shutdown(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai) +-{ +- struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); +- +- regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0); +- clk_disable_unprepare(priv->refclk); +-} +- + static void axg_spdifin_write_mode_param(struct regmap *map, int mode, + unsigned int val, + unsigned int num_per_reg, +@@ -251,25 +223,38 @@ static int axg_spdifin_dai_probe(struct snd_soc_dai *dai) + ret = axg_spdifin_sample_mode_config(dai, priv); + if (ret) { + dev_err(dai->dev, "mode configuration failed\n"); +- clk_disable_unprepare(priv->pclk); +- return ret; ++ goto pclk_err; + } + ++ ret = clk_prepare_enable(priv->refclk); ++ if (ret) { ++ dev_err(dai->dev, ++ "failed to enable spdifin reference clock\n"); ++ goto pclk_err; ++ } ++ ++ regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, ++ SPDIFIN_CTRL0_EN); ++ + return 0; ++ ++pclk_err: ++ clk_disable_unprepare(priv->pclk); ++ return ret; + } + + static int axg_spdifin_dai_remove(struct snd_soc_dai *dai) + { + struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); + ++ regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0); ++ clk_disable_unprepare(priv->refclk); + clk_disable_unprepare(priv->pclk); + return 0; + } + + static const struct snd_soc_dai_ops axg_spdifin_ops = { + .prepare = axg_spdifin_prepare, +- .startup = axg_spdifin_startup, +- .shutdown = axg_spdifin_shutdown, + }; + + static int axg_spdifin_iec958_info(struct snd_kcontrol *kcontrol, +diff --git a/tools/include/linux/btf_ids.h b/tools/include/linux/btf_ids.h +index 57890b357f851..eca91e7a4d394 100644 +--- a/tools/include/linux/btf_ids.h ++++ b/tools/include/linux/btf_ids.h +@@ -38,7 +38,7 @@ asm( \ + ____BTF_ID(symbol) + + #define __ID(prefix) \ +- __PASTE(prefix, __COUNTER__) ++ __PASTE(__PASTE(prefix, __COUNTER__), __LINE__) + + /* + * The BTF_ID defines unique symbol for each ID pointing +diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h +index 8330e3ca8fbfb..1e3e3f16eabcb 100644 +--- a/tools/include/uapi/linux/bpf.h ++++ b/tools/include/uapi/linux/bpf.h +@@ -1762,7 +1762,9 @@ union bpf_attr { + * performed again, if the helper is used in combination with + * direct packet access. + * Return +- * 0 on success, or a negative error in case of failure. ++ * 0 on success, or a negative error in case of failure. Positive ++ * error indicates a potential drop or congestion in the target ++ * device. The particular positive error codes are not defined. + * + * u64 bpf_get_current_pid_tgid(void) + * Return +diff --git a/tools/perf/util/Build b/tools/perf/util/Build +index f2914d5bed6e8..7d085927da413 100644 +--- a/tools/perf/util/Build ++++ b/tools/perf/util/Build +@@ -263,6 +263,12 @@ ifeq ($(BISON_GE_35),1) + else + bison_flags += -w + endif ++ ++BISON_LT_381 := $(shell expr $(shell $(BISON) --version | grep bison | sed -e 's/.\+ \([0-9]\+\).\([0-9]\+\).\([0-9]\+\)/\1\2\3/g') \< 381) ++ifeq ($(BISON_LT_381),1) ++ bison_flags += -DYYNOMEM=YYABORT ++endif ++ + CFLAGS_parse-events-bison.o += $(bison_flags) + CFLAGS_pmu-bison.o += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags) + CFLAGS_expr-bison.o += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags) +diff --git a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc +index 0eb47fbb3f44d..42422e4251078 100644 +--- a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc ++++ b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc +@@ -39,7 +39,7 @@ instance_read() { + + instance_set() { + while :; do +- echo 1 > foo/events/sched/sched_switch ++ echo 1 > foo/events/sched/sched_switch/enable + done 2> /dev/null + } + +diff --git a/tools/testing/selftests/kselftest_deps.sh b/tools/testing/selftests/kselftest_deps.sh +index 00e60d6eb16bc..7e51f4a373d35 100755 +--- a/tools/testing/selftests/kselftest_deps.sh ++++ b/tools/testing/selftests/kselftest_deps.sh +@@ -46,11 +46,11 @@ fi + print_targets=0 + + while getopts "p" arg; do +- case $arg in +- p) ++ case $arg in ++ p) + print_targets=1 + shift;; +- esac ++ esac + done + + if [ $# -eq 0 ] +@@ -92,6 +92,10 @@ pass_cnt=0 + # Get all TARGETS from selftests Makefile + targets=$(egrep "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2) + ++# Initially, in LDLIBS related lines, the dep checker needs ++# to ignore lines containing the following strings: ++filter="\$(VAR_LDLIBS)\|pkg-config\|PKG_CONFIG\|IOURING_EXTRA_LIBS" ++ + # Single test case + if [ $# -eq 2 ] + then +@@ -100,6 +104,8 @@ then + l1_test $test + l2_test $test + l3_test $test ++ l4_test $test ++ l5_test $test + + print_results $1 $2 + exit $? +@@ -113,7 +119,7 @@ fi + # Append space at the end of the list to append more tests. + + l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \ +- grep -v "VAR_LDLIBS" | awk -F: '{print $1}') ++ grep -v "$filter" | awk -F: '{print $1}' | uniq) + + # Level 2: LDLIBS set dynamically. + # +@@ -126,7 +132,7 @@ l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \ + # Append space at the end of the list to append more tests. + + l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \ +- grep -v "VAR_LDLIBS" | awk -F: '{print $1}') ++ grep -v "$filter" | awk -F: '{print $1}' | uniq) + + # Level 3 + # memfd and others use pkg-config to find mount and fuse libs +@@ -138,11 +144,32 @@ l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \ + # VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) + + l3_tests=$(grep -r --include=Makefile "^VAR_LDLIBS" | \ +- grep -v "pkg-config" | awk -F: '{print $1}') ++ grep -v "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq) + +-#echo $l1_tests +-#echo $l2_1_tests +-#echo $l3_tests ++# Level 4 ++# some tests may fall back to default using `|| echo -l<libname>` ++# if pkg-config doesn't find the libs, instead of using VAR_LDLIBS ++# as per level 3 checks. ++# e.g: ++# netfilter/Makefile ++# LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) ++l4_tests=$(grep -r --include=Makefile "^LDLIBS" | \ ++ grep "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq) ++ ++# Level 5 ++# some tests may use IOURING_EXTRA_LIBS to add extra libs to LDLIBS, ++# which in turn may be defined in a sub-Makefile ++# e.g.: ++# mm/Makefile ++# $(OUTPUT)/gup_longterm: LDLIBS += $(IOURING_EXTRA_LIBS) ++l5_tests=$(grep -r --include=Makefile "LDLIBS +=.*\$(IOURING_EXTRA_LIBS)" | \ ++ awk -F: '{print $1}' | uniq) ++ ++#echo l1_tests $l1_tests ++#echo l2_tests $l2_tests ++#echo l3_tests $l3_tests ++#echo l4_tests $l4_tests ++#echo l5_tests $l5_tests + + all_tests + print_results $1 $2 +@@ -164,24 +191,32 @@ all_tests() + for test in $l3_tests; do + l3_test $test + done ++ ++ for test in $l4_tests; do ++ l4_test $test ++ done ++ ++ for test in $l5_tests; do ++ l5_test $test ++ done + } + + # Use same parsing used for l1_tests and pick libraries this time. + l1_test() + { + test_libs=$(grep --include=Makefile "^LDLIBS" $test | \ +- grep -v "VAR_LDLIBS" | \ ++ grep -v "$filter" | \ + sed -e 's/\:/ /' | \ + sed -e 's/+/ /' | cut -d "=" -f 2) + + check_libs $test $test_libs + } + +-# Use same parsing used for l2__tests and pick libraries this time. ++# Use same parsing used for l2_tests and pick libraries this time. + l2_test() + { + test_libs=$(grep --include=Makefile ": LDLIBS" $test | \ +- grep -v "VAR_LDLIBS" | \ ++ grep -v "$filter" | \ + sed -e 's/\:/ /' | sed -e 's/+/ /' | \ + cut -d "=" -f 2) + +@@ -197,6 +232,24 @@ l3_test() + check_libs $test $test_libs + } + ++l4_test() ++{ ++ test_libs=$(grep --include=Makefile "^VAR_LDLIBS\|^LDLIBS" $test | \ ++ grep "\(pkg-config\|PKG_CONFIG\).*|| echo " | \ ++ sed -e 's/.*|| echo //' | sed -e 's/)$//') ++ ++ check_libs $test $test_libs ++} ++ ++l5_test() ++{ ++ tests=$(find $(dirname "$test") -type f -name "*.mk") ++ test_libs=$(grep "^IOURING_EXTRA_LIBS +\?=" $tests | \ ++ cut -d "=" -f 2) ++ ++ check_libs $test $test_libs ++} ++ + check_libs() + { + +diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c +index 97fceb9be9ed3..3bdb093731358 100644 +--- a/tools/testing/selftests/net/tls.c ++++ b/tools/testing/selftests/net/tls.c +@@ -441,11 +441,11 @@ TEST_F(tls, sendmsg_large) + + msg.msg_iov = &vec; + msg.msg_iovlen = 1; +- EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len); ++ EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len); + } + + while (recvs++ < sends) { +- EXPECT_NE(recv(self->fd, mem, send_len, 0), -1); ++ EXPECT_NE(recv(self->cfd, mem, send_len, 0), -1); + } + + free(mem); +@@ -474,9 +474,9 @@ TEST_F(tls, sendmsg_multiple) + msg.msg_iov = vec; + msg.msg_iovlen = iov_len; + +- EXPECT_EQ(sendmsg(self->cfd, &msg, 0), total_len); ++ EXPECT_EQ(sendmsg(self->fd, &msg, 0), total_len); + buf = malloc(total_len); +- EXPECT_NE(recv(self->fd, buf, total_len, 0), -1); ++ EXPECT_NE(recv(self->cfd, buf, total_len, 0), -1); + for (i = 0; i < iov_len; i++) { + EXPECT_EQ(memcmp(test_strs[i], buf + len_cmp, + strlen(test_strs[i])), |