Merge remote-tracking branch 'mem-ctrl/for-next' into renesas-drivers
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index fb8752b4..aa7447f 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3116,6 +3116,8 @@ * max_sec_lba48: Set or clear transfer size limit to 65535 sectors. + * external: Mark port as external (hotplug-capable). + * [no]lpm: Enable or disable link power management. * [no]setxfer: Indicate if transfer speed mode setting
diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml b/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml index 190a649..bef0052 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
@@ -91,6 +91,14 @@ Firmware must configure interrupt delegation registers based on interrupt delegation list. + riscv,hart-indexes: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 16384 + description: + A list of hart indexes that APLIC should use to address each hart + that is mentioned in the "interrupts-extended" + dependencies: riscv,delegation: [ "riscv,children" ]
diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml index 68709a7..7605a05 100644 --- a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
@@ -42,8 +42,30 @@ description: | list of regulators provided by this controller + properties: + LDO5: + type: object + $ref: regulator.yaml# + description: + Properties for single LDO5 regulator. + + properties: + nxp,sd-vsel-fixed-low: + type: boolean + description: + Let the driver know that SD_VSEL is hardwired to low level and + there is no GPIO to get the actual value from. + + sd-vsel-gpios: + description: + GPIO that can be used to read the current status of the SD_VSEL + signal in order for the driver to know if LDO5CTRL_L or LDO5CTRL_H + is used by the hardware. + + unevaluatedProperties: false + patternProperties: - "^LDO[1-5]$": + "^LDO[1-4]$": type: object $ref: regulator.yaml# description: @@ -78,11 +100,6 @@ additionalProperties: false - sd-vsel-gpios: - description: GPIO that is used to switch LDO5 between being configured by - LDO5CTRL_L or LDO5CTRL_H register. Use this if the SD_VSEL signal is - connected to a host GPIO. - nxp,i2c-lt-enable: type: boolean description:
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml index ebbf0c9..e0f7503 100644 --- a/Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml +++ b/Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml
@@ -22,7 +22,10 @@ properties: compatible: - const: renesas,r9a09g057-sys + items: + - enum: + - renesas,r9a09g047-sys # RZ/G3E + - renesas,r9a09g057-sys # RZ/V2H reg: maxItems: 1
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml index 225c0f0..a8af4fc 100644 --- a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml +++ b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
@@ -552,6 +552,15 @@ - renesas,r9a09g057h41 # RZ/V2H - renesas,r9a09g057h42 # RZ/V2H with Mali-G31 support - renesas,r9a09g057h44 # RZ/V2HP with Mali-G31 + Mali-C55 support + - renesas,r9a09g057h45 # RZ/V2H with cryptographic extension support + - renesas,r9a09g057h46 # RZ/V2H with Mali-G31 + cryptographic extension support + - renesas,r9a09g057h48 # RZ/V2HP with Mali-G31 + Mali-C55 + cryptographic extension support + - const: renesas,r9a09g057 + + - description: Yuridenki-Shokai RZ/V2H Kakip + items: + - const: yuridenki,kakip + - const: renesas,r9a09g057h48 - const: renesas,r9a09g057 additionalProperties: true
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 5079ca6..333491c 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1737,6 +1737,8 @@ description: Shenzhen Yashi Changhua Intelligent Technology Co., Ltd. "^ysoft,.*": description: Y Soft Corporation a.s. + "^yuridenki,.*": + description: Yuridenki-Shokai Co. Ltd. "^zarlink,.*": description: Zarlink Semiconductor "^zealz,.*":
diff --git a/Documentation/devicetree/bindings/xilinx.txt b/Documentation/devicetree/bindings/xilinx.txt index 28199b3..0ee9de9 100644 --- a/Documentation/devicetree/bindings/xilinx.txt +++ b/Documentation/devicetree/bindings/xilinx.txt
@@ -102,15 +102,6 @@ Default is <d#1024 d#480>. - rotate-display (empty) : rotate display 180 degrees. - ii) Xilinx SystemACE - - The Xilinx SystemACE device is used to program FPGAs from an FPGA - bitstream stored on a CF card. It can also be used as a generic CF - interface device. - - Optional properties: - - 8-bit (empty) : Set this property for SystemACE in 8 bit mode - iii) Xilinx EMAC and Xilinx TEMAC Xilinx Ethernet devices. In addition to general xilinx properties @@ -118,13 +109,6 @@ property, and may include other common network device properties like local-mac-address. - iv) Xilinx Uartlite - - Xilinx uartlite devices are simple fixed speed serial ports. - - Required properties: - - current-speed : Baud rate of uartlite - v) Xilinx hwicap Xilinx hwicap devices provide access to the configuration logic @@ -141,16 +125,6 @@ - compatible : should contain "xlnx,xps-hwicap-1.00.a" or "xlnx,opb-hwicap-1.00.b". - vi) Xilinx Uart 16550 - - Xilinx UART 16550 devices are very similar to the NS16550 but with - different register spacing and an offset from the base address. - - Required properties: - - clock-frequency : Frequency of the clock input - - reg-offset : A value of 3 is required - - reg-shift : A value of 2 is required - vii) Xilinx USB Host controller The Xilinx USB host controller is EHCI compatible but with a different
diff --git a/MAINTAINERS b/MAINTAINERS index 896a307..9280c6a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS
@@ -3005,7 +3005,9 @@ F: arch/arm/include/debug/renesas-scif.S F: arch/arm/mach-shmobile/ F: arch/arm64/boot/dts/renesas/ +F: arch/arm64/configs/renesas_defconfig F: arch/riscv/boot/dts/renesas/ +F: arch/riscv/configs/rzfive_defconfig F: drivers/nvmem/rcar-efuse.c F: drivers/pmdomain/renesas/ F: drivers/soc/renesas/ @@ -3428,6 +3430,7 @@ F: drivers/virt/coco/pkvm-guest/ F: tools/testing/selftests/arm64/ X: arch/arm64/boot/dts/ +X: arch/arm64/configs/renesas_defconfig ARROW SPEEDCHIPS XRS7000 SERIES ETHERNET SWITCH DRIVER M: George McCollister <george.mccollister@gmail.com> @@ -20287,6 +20290,7 @@ P: Documentation/arch/riscv/patch-acceptance.rst T: git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git F: arch/riscv/ +X: arch/riscv/configs/rzfive_defconfig N: riscv K: riscv @@ -26250,3 +26254,5 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git F: * F: */ +X: arch/arm64/configs/renesas_defconfig +X: arch/riscv/configs/rzfive_defconfig
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index fd28f31..8c30ed1 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig
@@ -14,6 +14,7 @@ CONFIG_NR_CPUS=8 CONFIG_HIGHMEM=y CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index c38367a..3cd34a4 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -8,19 +8,15 @@ */ #include <linux/clocksource.h> -#include <linux/device.h> -#include <linux/dma-map-ops.h> #include <linux/io.h> #include <linux/kernel.h> #include <linux/memblock.h> #include <linux/of.h> #include <linux/of_clk.h> -#include <linux/of_fdt.h> #include <linux/psci.h> #include <asm/mach/arch.h> #include <asm/secure_cntvoff.h> #include "common.h" -#include "rcar-gen2.h" static const struct of_device_id cpg_matches[] __initconst = { { .compatible = "renesas,r8a7742-cpg-mssr", .data = "extal" }, @@ -122,76 +118,6 @@ static void __init rcar_gen2_timer_init(void) timer_probe(); } -struct memory_reserve_config { - u64 reserved; - u64 base, size; -}; - -static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname, - int depth, void *data) -{ - const char *type = of_get_flat_dt_prop(node, "device_type", NULL); - const __be32 *reg, *endp; - int l; - struct memory_reserve_config *mrc = data; - u64 lpae_start = 1ULL << 32; - - /* We are scanning "memory" nodes only */ - if (type == NULL || strcmp(type, "memory")) - return 0; - - reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l); - if (reg == NULL) - reg = of_get_flat_dt_prop(node, "reg", &l); - if (reg == NULL) - return 0; - - endp = reg + (l / sizeof(__be32)); - while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { - u64 base, size; - - base = dt_mem_next_cell(dt_root_addr_cells, ®); - size = dt_mem_next_cell(dt_root_size_cells, ®); - - if (base >= lpae_start) - continue; - - if ((base + size) >= lpae_start) - size = lpae_start - base; - - if (size < mrc->reserved) - continue; - - if (base < mrc->base) - continue; - - /* keep the area at top near the 32-bit legacy limit */ - mrc->base = base + size - mrc->reserved; - mrc->size = mrc->reserved; - } - - return 0; -} - -static void __init rcar_gen2_reserve(void) -{ - struct memory_reserve_config mrc; - - /* reserve 256 MiB at the top of the physical legacy 32-bit space */ - memset(&mrc, 0, sizeof(mrc)); - mrc.reserved = SZ_256M; - - of_scan_flat_dt(rcar_gen2_scan_mem, &mrc); -#ifdef CONFIG_DMA_CMA - if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) { - static struct cma *rcar_gen2_dma_contiguous; - - dma_contiguous_reserve_area(mrc.size, mrc.base, 0, - &rcar_gen2_dma_contiguous, true); - } -#endif -} - static const char * const rcar_gen2_boards_compat_dt[] __initconst = { "renesas,r8a7790", "renesas,r8a7791", @@ -204,7 +130,6 @@ static const char * const rcar_gen2_boards_compat_dt[] __initconst = { DT_MACHINE_START(RCAR_GEN2_DT, "Generic R-Car Gen2 (Flattened Device Tree)") .init_late = shmobile_init_late, .init_time = rcar_gen2_timer_init, - .reserve = rcar_gen2_reserve, .dt_compat = rcar_gen2_boards_compat_dt, MACHINE_END @@ -220,6 +145,5 @@ static const char * const rz_g1_boards_compat_dt[] __initconst = { DT_MACHINE_START(RZ_G1_DT, "Generic RZ/G1 (Flattened Device Tree)") .init_late = shmobile_init_late, .init_time = rcar_gen2_timer_init, - .reserve = rcar_gen2_reserve, .dt_compat = rz_g1_boards_compat_dt, MACHINE_END
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi index 59813ef..33031e9 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
@@ -232,7 +232,6 @@ pmic@25 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pmic>; interrupts-extended = <&gpio1 3 IRQ_TYPE_EDGE_RISING>; - sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; regulators { reg_vdd_soc: BUCK1 { @@ -555,7 +554,6 @@ MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c3 pinctrl_pmic: pmicirqgrp { fsl,pins = < MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x41 - MX8MP_IOMUXC_GPIO1_IO04__GPIO1_IO04 0x41 >; }; @@ -623,6 +621,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d0 MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0 MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0 MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0 >; }; @@ -634,6 +633,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4 MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4 MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4 MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0 >; }; @@ -645,6 +645,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d6 MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6 MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6 MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0 >; };
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile index 928635f..c81d0f7 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -143,12 +143,16 @@ dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-smarc-cru-csi-ov5645.dtb dtb-$(CONFIG_ARCH_R9A08G045) += r9a08g045s33-smarc.dtb +dtb-$(CONFIG_ARCH_R9A08G045) += r9a08g045s33-smarc-pmod1-type-3a.dtbo +r9a08g045s33-smarc-pmod1-type-3a-dtbs := r9a08g045s33-smarc.dtb r9a08g045s33-smarc-pmod1-type-3a.dtbo +dtb-$(CONFIG_ARCH_R9A08G045) += r9a08g045s33-smarc-pmod1-type-3a.dtb dtb-$(CONFIG_ARCH_R9A09G011) += r9a09g011-v2mevk2.dtb dtb-$(CONFIG_ARCH_R9A09G047) += r9a09g047e57-smarc.dtb dtb-$(CONFIG_ARCH_R9A09G057) += r9a09g057h44-rzv2h-evk.dtb +dtb-$(CONFIG_ARCH_R9A09G057) += r9a09g057h48-kakip.dtb dtb-$(CONFIG_ARCH_RCAR_GEN3) += draak-ebisu-panel-aa104xd12.dtbo dtb-$(CONFIG_ARCH_RCAR_GEN3) += salvator-panel-aa104xd12.dtbo
diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso index 9450d8a..0c00566 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso +++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso
@@ -70,7 +70,7 @@ gpio@27 { gpio-controller; #gpio-cells = <2>; - vin0_adv7612_en { + vin0-adv7612-en-hog { gpio-hog; gpios = <3 GPIO_ACTIVE_LOW>; output-high;
diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi index fe6d978..905285b 100644 --- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
@@ -2338,6 +2338,42 @@ fcpvd1: fcp@fea11000 { iommus = <&ipmmu_vi1 7>; }; + fcpvx0: fcp@fedb0000 { + compatible = "renesas,fcpv"; + reg = <0 0xfedb0000 0 0x200>; + clocks = <&cpg CPG_MOD 1100>; + power-domains = <&sysc R8A779A0_PD_A3ISP01>; + resets = <&cpg 1100>; + iommus = <&ipmmu_vi1 24>; + }; + + fcpvx1: fcp@fedb8000 { + compatible = "renesas,fcpv"; + reg = <0 0xfedb8000 0 0x200>; + clocks = <&cpg CPG_MOD 1101>; + power-domains = <&sysc R8A779A0_PD_A3ISP01>; + resets = <&cpg 1101>; + iommus = <&ipmmu_vi1 25>; + }; + + fcpvx2: fcp@fedc0000 { + compatible = "renesas,fcpv"; + reg = <0 0xfedc0000 0 0x200>; + clocks = <&cpg CPG_MOD 1102>; + power-domains = <&sysc R8A779A0_PD_A3ISP23>; + resets = <&cpg 1102>; + iommus = <&ipmmu_vi1 26>; + }; + + fcpvx3: fcp@fedc8000 { + compatible = "renesas,fcpv"; + reg = <0 0xfedc8000 0 0x200>; + clocks = <&cpg CPG_MOD 1103>; + power-domains = <&sysc R8A779A0_PD_A3ISP23>; + resets = <&cpg 1103>; + iommus = <&ipmmu_vi1 27>; + }; + vspd0: vsp@fea20000 { compatible = "renesas,vsp2"; reg = <0 0xfea20000 0 0x5000>; @@ -2360,6 +2396,50 @@ vspd1: vsp@fea28000 { renesas,fcp = <&fcpvd1>; }; + vspx0: vsp@fedd0000 { + compatible = "renesas,vsp2"; + reg = <0 0xfedd0000 0 0x8000>; + interrupts = <GIC_SPI 600 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1028>; + power-domains = <&sysc R8A779A0_PD_A3ISP01>; + resets = <&cpg 1028>; + + renesas,fcp = <&fcpvx0>; + }; + + vspx1: vsp@fedd8000 { + compatible = "renesas,vsp2"; + reg = <0 0xfedd8000 0 0x8000>; + interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1029>; + power-domains = <&sysc R8A779A0_PD_A3ISP01>; + resets = <&cpg 1029>; + + renesas,fcp = <&fcpvx1>; + }; + + vspx2: vsp@fede0000 { + compatible = "renesas,vsp2"; + reg = <0 0xfede0000 0 0x8000>; + interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1030>; + power-domains = <&sysc R8A779A0_PD_A3ISP23>; + resets = <&cpg 1030>; + + renesas,fcp = <&fcpvx2>; + }; + + vspx3: vsp@fede8000 { + compatible = "renesas,vsp2"; + reg = <0 0xfede8000 0 0x8000>; + interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1031>; + power-domains = <&sysc R8A779A0_PD_A3ISP23>; + resets = <&cpg 1031>; + + renesas,fcp = <&fcpvx3>; + }; + csi40: csi2@feaa0000 { compatible = "renesas,r8a779a0-csi2"; reg = <0 0xfeaa0000 0 0x10000>;
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0-spider-ethernet.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0-spider-ethernet.dtsi index 5d38669..ad2b039 100644 --- a/arch/arm64/boot/dts/renesas/r8a779f0-spider-ethernet.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779f0-spider-ethernet.dtsi
@@ -5,6 +5,14 @@ * Copyright (C) 2021 Renesas Electronics Corp. */ +/ { + aliases { + ethernet0 = &rswitch_port0; + ethernet1 = &rswitch_port1; + ethernet2 = &rswitch_port2; + }; +}; + ð_serdes { status = "okay"; }; @@ -42,61 +50,61 @@ &rswitch { pinctrl-0 = <&tsn0_pins>, <&tsn1_pins>, <&tsn2_pins>; pinctrl-names = "default"; status = "okay"; +}; - ethernet-ports { +&rswitch_port0 { + reg = <0>; + phy-handle = <&u101>; + phy-mode = "sgmii"; + phys = <ð_serdes 0>; + status = "okay"; + + mdio { #address-cells = <1>; #size-cells = <0>; - port@0 { - reg = <0>; - phy-handle = <&u101>; - phy-mode = "sgmii"; - phys = <ð_serdes 0>; - - mdio { - #address-cells = <1>; - #size-cells = <0>; - - u101: ethernet-phy@1 { - reg = <1>; - compatible = "ethernet-phy-ieee802.3-c45"; - interrupts-extended = <&gpio3 10 IRQ_TYPE_LEVEL_LOW>; - }; - }; - }; - port@1 { + u101: ethernet-phy@1 { reg = <1>; - phy-handle = <&u201>; - phy-mode = "sgmii"; - phys = <ð_serdes 1>; - - mdio { - #address-cells = <1>; - #size-cells = <0>; - - u201: ethernet-phy@2 { - reg = <2>; - compatible = "ethernet-phy-ieee802.3-c45"; - interrupts-extended = <&gpio3 11 IRQ_TYPE_LEVEL_LOW>; - }; - }; + compatible = "ethernet-phy-ieee802.3-c45"; + interrupts-extended = <&gpio3 10 IRQ_TYPE_LEVEL_LOW>; }; - port@2 { + }; +}; + +&rswitch_port1 { + reg = <1>; + phy-handle = <&u201>; + phy-mode = "sgmii"; + phys = <ð_serdes 1>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + u201: ethernet-phy@2 { reg = <2>; - phy-handle = <&u301>; - phy-mode = "sgmii"; - phys = <ð_serdes 2>; + compatible = "ethernet-phy-ieee802.3-c45"; + interrupts-extended = <&gpio3 11 IRQ_TYPE_LEVEL_LOW>; + }; + }; +}; - mdio { - #address-cells = <1>; - #size-cells = <0>; +&rswitch_port2 { + reg = <2>; + phy-handle = <&u301>; + phy-mode = "sgmii"; + phys = <ð_serdes 2>; + status = "okay"; - u301: ethernet-phy@3 { - reg = <3>; - compatible = "ethernet-phy-ieee802.3-c45"; - interrupts-extended = <&gpio3 9 IRQ_TYPE_LEVEL_LOW>; - }; - }; + mdio { + #address-cells = <1>; + #size-cells = <0>; + + u301: ethernet-phy@3 { + reg = <3>; + compatible = "ethernet-phy-ieee802.3-c45"; + interrupts-extended = <&gpio3 9 IRQ_TYPE_LEVEL_LOW>; }; }; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi index 054498e..fdc466b 100644 --- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
@@ -974,17 +974,20 @@ ethernet-ports { #address-cells = <1>; #size-cells = <0>; - port@0 { + rswitch_port0: port@0 { reg = <0>; phys = <ð_serdes 0>; + status = "disabled"; }; - port@1 { + rswitch_port1: port@1 { reg = <1>; phys = <ð_serdes 1>; + status = "disabled"; }; - port@2 { + rswitch_port2: port@2 { reg = <2>; phys = <ð_serdes 2>; + status = "disabled"; }; }; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts b/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts index 5d71d52..df652e7 100644 --- a/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts +++ b/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts
@@ -22,7 +22,8 @@ aliases { i2c5 = &i2c5; serial0 = &hscif0; serial1 = &hscif1; - ethernet0 = &rswitch; + ethernet0 = &rswitch_port0; + ethernet1 = &rswitch_port1; }; chosen { @@ -179,49 +180,42 @@ &rswitch { pinctrl-0 = <&tsn0_pins>, <&tsn1_pins>; pinctrl-names = "default"; status = "okay"; +}; - ethernet-ports { +&rswitch_port0 { + reg = <0>; + phy-handle = <&ic99>; + phy-mode = "sgmii"; + phys = <ð_serdes 0>; + status = "okay"; + + mdio { #address-cells = <1>; #size-cells = <0>; - port@0 { - reg = <0>; - phy-handle = <&ic99>; - phy-mode = "sgmii"; - phys = <ð_serdes 0>; - - mdio { - #address-cells = <1>; - #size-cells = <0>; - - ic99: ethernet-phy@1 { - reg = <1>; - compatible = "ethernet-phy-ieee802.3-c45"; - interrupts-extended = <&gpio3 10 IRQ_TYPE_LEVEL_LOW>; - }; - }; - }; - - port@1 { + ic99: ethernet-phy@1 { reg = <1>; - phy-handle = <&ic102>; - phy-mode = "sgmii"; - phys = <ð_serdes 1>; - - mdio { - #address-cells = <1>; - #size-cells = <0>; - - ic102: ethernet-phy@2 { - reg = <2>; - compatible = "ethernet-phy-ieee802.3-c45"; - interrupts-extended = <&gpio3 11 IRQ_TYPE_LEVEL_LOW>; - }; - }; + compatible = "ethernet-phy-ieee802.3-c45"; + interrupts-extended = <&gpio3 10 IRQ_TYPE_LEVEL_LOW>; }; + }; +}; - port@2 { - status = "disabled"; +&rswitch_port1 { + reg = <1>; + phy-handle = <&ic102>; + phy-mode = "sgmii"; + phys = <ð_serdes 1>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ic102: ethernet-phy@2 { + reg = <2>; + compatible = "ethernet-phy-ieee802.3-c45"; + interrupts-extended = <&gpio3 11 IRQ_TYPE_LEVEL_LOW>; }; }; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi index 104f740..550e7da 100644 --- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
@@ -2171,6 +2171,24 @@ fcpvd1: fcp@fea11000 { iommus = <&ipmmu_vi1 7>; }; + fcpvx0: fcp@fedb0000 { + compatible = "renesas,fcpv"; + reg = <0 0xfedb0000 0 0x200>; + clocks = <&cpg CPG_MOD 1100>; + power-domains = <&sysc R8A779G0_PD_A3ISP0>; + resets = <&cpg 1100>; + iommus = <&ipmmu_vi1 24>; + }; + + fcpvx1: fcp@fedb8000 { + compatible = "renesas,fcpv"; + reg = <0 0xfedb8000 0 0x200>; + clocks = <&cpg CPG_MOD 1101>; + power-domains = <&sysc R8A779G0_PD_A3ISP1>; + resets = <&cpg 1101>; + iommus = <&ipmmu_vi1 25>; + }; + vspd0: vsp@fea20000 { compatible = "renesas,vsp2"; reg = <0 0xfea20000 0 0x7000>; @@ -2193,6 +2211,28 @@ vspd1: vsp@fea28000 { renesas,fcp = <&fcpvd1>; }; + vspx0: vsp@fedd0000 { + compatible = "renesas,vsp2"; + reg = <0 0xfedd0000 0 0x8000>; + interrupts = <GIC_SPI 556 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1028>; + power-domains = <&sysc R8A779G0_PD_A3ISP0>; + resets = <&cpg 1028>; + + renesas,fcp = <&fcpvx0>; + }; + + vspx1: vsp@fedd8000 { + compatible = "renesas,vsp2"; + reg = <0 0xfedd8000 0 0x8000>; + interrupts = <GIC_SPI 557 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1029>; + power-domains = <&sysc R8A779G0_PD_A3ISP1>; + resets = <&cpg 1029>; + + renesas,fcp = <&fcpvx1>; + }; + du: display@feb00000 { compatible = "renesas,du-r8a779g0"; reg = <0 0xfeb00000 0 0x40000>; @@ -2453,46 +2493,6 @@ port@1 { }; }; - fcpvx0: fcp@fedb0000 { - compatible = "renesas,fcpv"; - reg = <0 0xfedb0000 0 0x200>; - clocks = <&cpg CPG_MOD 1100>; - power-domains = <&sysc R8A779G0_PD_A3ISP0>; - resets = <&cpg 1100>; - iommus = <&ipmmu_vi1 24>; - }; - - fcpvx1: fcp@fedb8000 { - compatible = "renesas,fcpv"; - reg = <0 0xfedb8000 0 0x200>; - clocks = <&cpg CPG_MOD 1101>; - power-domains = <&sysc R8A779G0_PD_A3ISP1>; - resets = <&cpg 1101>; - iommus = <&ipmmu_vi1 25>; - }; - - vspx0: vsp@fedd0000 { - compatible = "renesas,vsp2"; - reg = <0 0xfedd0000 0 0x8000>; - interrupts = <GIC_SPI 556 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 1028>; - power-domains = <&sysc R8A779G0_PD_A3ISP0>; - resets = <&cpg 1028>; - - renesas,fcp = <&fcpvx0>; - }; - - vspx1: vsp@fedd8000 { - compatible = "renesas,vsp2"; - reg = <0 0xfedd8000 0 0x8000>; - interrupts = <GIC_SPI 557 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 1029>; - power-domains = <&sysc R8A779G0_PD_A3ISP1>; - resets = <&cpg 1029>; - - renesas,fcp = <&fcpvx1>; - }; - prr: chipid@fff00044 { compatible = "renesas,prr"; reg = <0 0xfff00044 0 4>;
diff --git a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts index 18fd52f..99bbb8a 100644 --- a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts +++ b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
@@ -46,6 +46,8 @@ aliases { serial0 = &hscif0; serial1 = &hscif2; ethernet0 = &avb0; + ethernet1 = &avb1; + ethernet2 = &avb2; }; can_transceiver0: can-phy0 { @@ -200,17 +202,64 @@ &audio_clkin { &avb0 { pinctrl-0 = <&avb0_pins>; pinctrl-names = "default"; - phy-handle = <&phy0>; + phy-handle = <&avb0_phy>; tx-internal-delay-ps = <2000>; status = "okay"; - phy0: ethernet-phy@0 { - compatible = "ethernet-phy-id0022.1622", - "ethernet-phy-ieee802.3-c22"; - rxc-skew-ps = <1500>; - reg = <0>; - interrupts-extended = <&gpio7 5 IRQ_TYPE_LEVEL_LOW>; - reset-gpios = <&gpio7 10 GPIO_ACTIVE_LOW>; + mdio { + #address-cells = <1>; + #size-cells = <0>; + + avb0_phy: ethernet-phy@0 { + compatible = "ethernet-phy-id0022.1622", + "ethernet-phy-ieee802.3-c22"; + rxc-skew-ps = <1500>; + reg = <0>; + interrupts-extended = <&gpio7 5 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpio7 10 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&avb1 { + pinctrl-0 = <&avb1_pins>; + pinctrl-names = "default"; + phy-handle = <&avb1_phy>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + reset-gpios = <&gpio6 1 GPIO_ACTIVE_LOW>; + reset-post-delay-us = <4000>; + + avb1_phy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0>; + interrupts-extended = <&gpio6 3 IRQ_TYPE_LEVEL_LOW>; + }; + }; +}; + +&avb2 { + pinctrl-0 = <&avb2_pins>; + pinctrl-names = "default"; + phy-handle = <&avb2_phy>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + reset-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>; + reset-post-delay-us = <4000>; + + avb2_phy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0>; + interrupts-extended = <&gpio5 4 IRQ_TYPE_LEVEL_LOW>; + }; }; }; @@ -233,25 +282,6 @@ channel1 { }; }; -&dsi0 { - status = "okay"; - - ports { - port@1 { - reg = <1>; - - dsi0_out: endpoint { - remote-endpoint = <&sn65dsi86_in0>; - data-lanes = <1 2 3 4>; - }; - }; - }; -}; - -&du { - status = "okay"; -}; - &csi40 { status = "okay"; @@ -292,6 +322,25 @@ csi41_in: endpoint { }; }; +&dsi0 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + + dsi0_out: endpoint { + remote-endpoint = <&sn65dsi86_in0>; + data-lanes = <1 2 3 4>; + }; + }; + }; +}; + +&du { + status = "okay"; +}; + &extal_clk { clock-frequency = <16666666>; }; @@ -558,6 +607,56 @@ pins_mii { }; }; + avb1_pins: avb1 { + mux { + groups = "avb1_link", "avb1_mdio", "avb1_rgmii", + "avb1_txcrefclk"; + function = "avb1"; + }; + + link { + groups = "avb1_link"; + bias-disable; + }; + + mdio { + groups = "avb1_mdio"; + drive-strength = <24>; + bias-disable; + }; + + rgmii { + groups = "avb1_rgmii"; + drive-strength = <24>; + bias-disable; + }; + }; + + avb2_pins: avb2 { + mux { + groups = "avb2_link", "avb2_mdio", "avb2_rgmii", + "avb2_txcrefclk"; + function = "avb2"; + }; + + link { + groups = "avb2_link"; + bias-disable; + }; + + mdio { + groups = "avb2_mdio"; + drive-strength = <24>; + bias-disable; + }; + + rgmii { + groups = "avb2_rgmii"; + drive-strength = <24>; + bias-disable; + }; + }; + can_clk_pins: can-clk { groups = "can_clk"; function = "can_clk";
diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi index d0c01c0..196b433 100644 --- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -793,8 +793,6 @@ avb0: ethernet@e6800000 { rx-internal-delay-ps = <0>; tx-internal-delay-ps = <0>; iommus = <&ipmmu_hc 0>; - #address-cells = <1>; - #size-cells = <0>; status = "disabled"; }; @@ -842,8 +840,6 @@ avb1: ethernet@e6810000 { rx-internal-delay-ps = <0>; tx-internal-delay-ps = <0>; iommus = <&ipmmu_hc 1>; - #address-cells = <1>; - #size-cells = <0>; status = "disabled"; }; @@ -891,8 +887,6 @@ avb2: ethernet@e6820000 { rx-internal-delay-ps = <0>; tx-internal-delay-ps = <0>; iommus = <&ipmmu_hc 2>; - #address-cells = <1>; - #size-cells = <0>; status = "disabled"; }; @@ -1908,6 +1902,15 @@ fcpvd0: fcp@fea10000 { resets = <&cpg 508>; }; + fcpvx0: fcp@fedb0000 { + compatible = "renesas,fcpv"; + reg = <0 0xfedb0000 0 0x200>; + clocks = <&cpg CPG_MOD 1100>; + power-domains = <&sysc R8A779H0_PD_A3ISP0>; + resets = <&cpg 1100>; + iommus = <&ipmmu_vi1 24>; + }; + vspd0: vsp@fea20000 { compatible = "renesas,vsp2"; reg = <0 0xfea20000 0 0x8000>; @@ -1918,6 +1921,17 @@ vspd0: vsp@fea20000 { renesas,fcp = <&fcpvd0>; }; + vspx0: vsp@fedd0000 { + compatible = "renesas,vsp2"; + reg = <0 0xfedd0000 0 0x8000>; + interrupts = <GIC_SPI 556 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 1028>; + power-domains = <&sysc R8A779H0_PD_A3ISP0>; + resets = <&cpg 1028>; + + renesas,fcp = <&fcpvx0>; + }; + du: display@feb00000 { compatible = "renesas,du-r8a779h0"; reg = <0 0xfeb00000 0 0x40000>;
diff --git a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi index a9b98db..d1e228b 100644 --- a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
@@ -443,7 +443,6 @@ sysc: system-controller@11020000 { <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "lpm_int", "ca55stbydone_int", "cm33stbyr_int", "ca55_deny"; - status = "disabled"; }; pinctrl: pinctrl@11030000 {
diff --git a/arch/arm64/boot/dts/renesas/r9a08g045s33-smarc-pmod1-type-3a.dtso b/arch/arm64/boot/dts/renesas/r9a08g045s33-smarc-pmod1-type-3a.dtso new file mode 100644 index 0000000..4a81e3a --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a08g045s33-smarc-pmod1-type-3a.dtso
@@ -0,0 +1,48 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source for the RZ/G3S SMARC Carrier II EVK PMOD parts + * + * Copyright (C) 2024 Renesas Electronics Corp. + * + * + * [Connection] + * + * SMARC Carrier II EVK + * +--------------------------------------------+ + * |PMOD1_3A (PMOD1 PIN HEADER) | + * | SCIF1_CTS# (pin1) (pin7) PMOD1_GPIO10 | + * | SCIF1_TXD (pin2) (pin8) PMOD1_GPIO11 | + * | SCIF1_RXD (pin3) (pin9) PMOD1_GPIO12 | + * | SCIF1_RTS# (pin4) (pin10) PMOD1_GPIO13 | + * | GND (pin5) (pin11) GND | + * | PWR_PMOD1 (pin6) (pin12) GND | + * +--------------------------------------------+ + * + * The following switches should be set as follows for SCIF1: + * - SW_CONFIG2: ON + * - SW_OPT_MUX4: ON + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/pinctrl/rzg2l-pinctrl.h> +#include "rzg3s-smarc-switches.h" + +&pinctrl { + scif1_pins: scif1-pins { + pinmux = <RZG2L_PORT_PINMUX(14, 0, 1)>, /* TXD */ + <RZG2L_PORT_PINMUX(14, 1, 1)>, /* RXD */ + <RZG2L_PORT_PINMUX(16, 0, 1)>, /* CTS# */ + <RZG2L_PORT_PINMUX(16, 1, 1)>; /* RTS# */ + }; +}; + +#if SW_CONFIG3 == SW_ON && SW_OPT_MUX4 == SW_ON +&scif1 { + pinctrl-names = "default"; + pinctrl-0 = <&scif1_pins>; + uart-has-rtscts; + status = "okay"; +}; +#endif
diff --git a/arch/arm64/boot/dts/renesas/r9a09g047.dtsi b/arch/arm64/boot/dts/renesas/r9a09g047.dtsi index 200e9ea..c93aa16 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g047.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g047.dtsi
@@ -154,6 +154,13 @@ cpg: clock-controller@10420000 { #power-domain-cells = <0>; }; + sys: system-controller@10430000 { + compatible = "renesas,r9a09g047-sys"; + reg = <0 0x10430000 0 0x10000>; + clocks = <&cpg CPG_CORE R9A09G047_SYS_0_PCLK>; + resets = <&cpg 0x30>; + }; + scif0: serial@11c01400 { compatible = "renesas,scif-r9a09g047", "renesas,scif-r9a09g057"; reg = <0 0x11c01400 0 0x400>; @@ -175,6 +182,36 @@ scif0: serial@11c01400 { status = "disabled"; }; + wdt1: watchdog@14400000 { + compatible = "renesas,r9a09g047-wdt", "renesas,r9a09g057-wdt"; + reg = <0 0x14400000 0 0x400>; + clocks = <&cpg CPG_MOD 0x4d>, <&cpg CPG_MOD 0x4e>; + clock-names = "pclk", "oscclk"; + resets = <&cpg 0x76>; + power-domains = <&cpg>; + status = "disabled"; + }; + + wdt2: watchdog@13000000 { + compatible = "renesas,r9a09g047-wdt", "renesas,r9a09g057-wdt"; + reg = <0 0x13000000 0 0x400>; + clocks = <&cpg CPG_MOD 0x4f>, <&cpg CPG_MOD 0x50>; + clock-names = "pclk", "oscclk"; + resets = <&cpg 0x77>; + power-domains = <&cpg>; + status = "disabled"; + }; + + wdt3: watchdog@13000400 { + compatible = "renesas,r9a09g047-wdt", "renesas,r9a09g057-wdt"; + reg = <0 0x13000400 0 0x400>; + clocks = <&cpg CPG_MOD 0x51>, <&cpg CPG_MOD 0x52>; + clock-names = "pclk", "oscclk"; + resets = <&cpg 0x78>; + power-domains = <&cpg>; + status = "disabled"; + }; + i2c0: i2c@14400400 { compatible = "renesas,riic-r9a09g047", "renesas,riic-r9a09g057"; reg = <0 0x14400400 0 0x400>;
diff --git a/arch/arm64/boot/dts/renesas/r9a09g057.dtsi b/arch/arm64/boot/dts/renesas/r9a09g057.dtsi index 1c550b2..f7a2f8c 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g057.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g057.dtsi
@@ -249,7 +249,6 @@ sys: system-controller@10430000 { reg = <0 0x10430000 0 0x10000>; clocks = <&cpg CPG_CORE R9A09G057_SYS_0_PCLK>; resets = <&cpg 0x30>; - status = "disabled"; }; ostm0: timer@11800000 {
diff --git a/arch/arm64/boot/dts/renesas/r9a09g057h48-kakip.dts b/arch/arm64/boot/dts/renesas/r9a09g057h48-kakip.dts new file mode 100644 index 0000000..d2586d2 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a09g057h48-kakip.dts
@@ -0,0 +1,136 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source for Yuridenki-Shokai the Kakip board + * + * Copyright (C) 2024 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> + */ + +/dts-v1/; + +#include <dt-bindings/pinctrl/renesas,r9a09g057-pinctrl.h> +#include <dt-bindings/gpio/gpio.h> +#include "r9a09g057.dtsi" + +/ { + model = "Yuridenki-Shokai Kakip Board based on r9a09g057h48"; + compatible = "yuridenki,kakip", "renesas,r9a09g057h48", "renesas,r9a09g057"; + + aliases { + serial0 = &scif; + mmc0 = &sdhi0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@48000000 { + device_type = "memory"; + /* first 128MB is reserved for secure area. */ + reg = <0x0 0x48000000 0x1 0xF8000000>; + }; + + reg_3p3v: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + vqmmc_sdhi0: regulator-vccq-sdhi0 { + compatible = "regulator-gpio"; + regulator-name = "SDHI0 VccQ"; + gpios = <&pinctrl RZV2H_GPIO(A, 0) GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + gpios-states = <0>; + states = <3300000 0>, <1800000 1>; + }; +}; + +&ostm0 { + status = "okay"; +}; + +&ostm1 { + status = "okay"; +}; + +&ostm2 { + status = "okay"; +}; + +&ostm3 { + status = "okay"; +}; + +&ostm4 { + status = "okay"; +}; + +&ostm5 { + status = "okay"; +}; + +&ostm6 { + status = "okay"; +}; + +&ostm7 { + status = "okay"; +}; + +&pinctrl { + scif_pins: scif { + pins = "SCIF_RXD", "SCIF_TXD"; + }; + + sd0-pwr-en-hog { + gpio-hog; + gpios = <RZV2H_GPIO(A, 1) GPIO_ACTIVE_HIGH>; + output-high; + line-name = "sd0_pwr_en"; + }; + + sdhi0_pins: sd0 { + sd0-clk { + pins = "SD0CLK"; + renesas,output-impedance = <3>; + slew-rate = <0>; + }; + + sd0-data { + pins = "SD0DAT0", "SD0DAT1", "SD0DAT2", "SD0DAT3", "SD0CMD"; + input-enable; + renesas,output-impedance = <3>; + slew-rate = <0>; + }; + + sd0-mux { + pinmux = <RZV2H_PORT_PINMUX(A, 5, 15)>; /* SD0_CD */ + }; + }; +}; + +&qextal_clk { + clock-frequency = <24000000>; +}; + +&scif { + pinctrl-0 = <&scif_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&sdhi0 { + pinctrl-0 = <&sdhi0_pins>; + pinctrl-names = "default"; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <&vqmmc_sdhi0>; + bus-width = <4>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi index 6b583ae..f4ba050 100644 --- a/arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi
@@ -26,3 +26,7 @@ &qextal_clk { &rtxin_clk { clock-frequency = <32768>; }; + +&wdt1 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi index ef12c1c..39845fa 100644 --- a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
@@ -9,25 +9,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/rzg2l-pinctrl.h> -/* - * On-board switches' states: - * @SW_OFF: switch's state is OFF - * @SW_ON: switch's state is ON - */ -#define SW_OFF 0 -#define SW_ON 1 - -/* - * SW_CONFIG[x] switches' states: - * @SW_CONFIG2: - * SW_OFF - SD0 is connected to eMMC - * SW_ON - SD0 is connected to uSD0 card - * @SW_CONFIG3: - * SW_OFF - SD2 is connected to SoC - * SW_ON - SCIF1, SSI0, IRQ0, IRQ1 connected to SoC - */ -#define SW_CONFIG2 SW_OFF -#define SW_CONFIG3 SW_ON +#include "rzg3s-smarc-switches.h" / { compatible = "renesas,rzg3s-smarcm", "renesas,r9a08g045s33", "renesas,r9a08g045";
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc-switches.h b/arch/arm64/boot/dts/renesas/rzg3s-smarc-switches.h new file mode 100644 index 0000000..bbf908a --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc-switches.h
@@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * On-board switches for the Renesas RZ/G3S SMARC Module and RZ SMARC Carrier II + * boards. + * + * Copyright (C) 2024 Renesas Electronics Corp. + */ + +#ifndef __RZG3S_SMARC_SWITCHES_H__ +#define __RZG3S_SMARC_SWITCHES_H__ + +/* + * On-board switches' states: + * @SW_OFF: switch's state is OFF + * @SW_ON: switch's state is ON + */ +#define SW_OFF 0 +#define SW_ON 1 + +/* + * SW_CONFIG[x] switches' states: + * @SW_CONFIG2: + * SW_OFF - SD0 is connected to eMMC + * SW_ON - SD0 is connected to uSD0 card + * @SW_CONFIG3: + * SW_OFF - SD2 is connected to SoC + * SW_ON - SCIF1, SSI0, IRQ0, IRQ1 connected to SoC + */ +#define SW_CONFIG2 SW_OFF +#define SW_CONFIG3 SW_ON + +/* + * SW_OPT_MUX[x] switches' states: + * @SW_OPT_MUX4: + * SW_OFF - The SMARC SER0 signals are routed to M.2 Key E UART + * SW_ON - The SMARC SER0 signals are routed to PMOD1 + */ +#define SW_OPT_MUX4 SW_ON + +#endif /* __RZG3S_SMARC_SWITCHES_H__ */
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi index 81b4ffd..5e044a4 100644 --- a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
@@ -12,6 +12,8 @@ / { aliases { i2c0 = &i2c0; + serial0 = &scif1; + serial1 = &scif3; serial3 = &scif0; mmc1 = &sdhi1; }; @@ -162,6 +164,11 @@ scif0_pins: scif0 { <RZG2L_PORT_PINMUX(6, 4, 1)>; /* TXD */ }; + scif3_pins: scif3 { + pinmux = <RZG2L_PORT_PINMUX(17, 2, 7)>, /* RXD */ + <RZG2L_PORT_PINMUX(17, 3, 7)>; /* TXD */ + }; + sdhi1_pins: sd1 { data { pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3"; @@ -208,6 +215,12 @@ &scif0 { status = "okay"; }; +&scif3 { + pinctrl-names = "default"; + pinctrl-0 = <&scif3_pins>; + status = "okay"; +}; + &sdhi1 { pinctrl-0 = <&sdhi1_pins>; pinctrl-1 = <&sdhi1_pins_uhs>;
diff --git a/arch/arm64/configs/renesas_defconfig b/arch/arm64/configs/renesas_defconfig new file mode 100644 index 0000000..81d063c --- /dev/null +++ b/arch/arm64/configs/renesas_defconfig
@@ -0,0 +1,458 @@ +CONFIG_LOCALVERSION="-arm64-renesas" +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_PREEMPT=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_USER_NS=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_PROFILING=y +CONFIG_KEXEC=y +CONFIG_ARCH_RENESAS=y +# CONFIG_AMPERE_ERRATUM_AC03_CPU_38 is not set +# CONFIG_ARM64_ERRATUM_1508412 is not set +# CONFIG_ARM64_ERRATUM_2051678 is not set +# CONFIG_ARM64_ERRATUM_2077057 is not set +# CONFIG_ARM64_ERRATUM_2658417 is not set +# CONFIG_ARM64_ERRATUM_2054223 is not set +# CONFIG_ARM64_ERRATUM_2067961 is not set +# CONFIG_ARM64_ERRATUM_2645198 is not set +# CONFIG_ARM64_ERRATUM_2966298 is not set +# CONFIG_ARM64_ERRATUM_3117295 is not set +# CONFIG_ARM64_ERRATUM_3194386 is not set +# CONFIG_CAVIUM_ERRATUM_22375 is not set +# CONFIG_CAVIUM_ERRATUM_23154 is not set +# CONFIG_CAVIUM_ERRATUM_27456 is not set +# CONFIG_CAVIUM_ERRATUM_30115 is not set +# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set +# CONFIG_FUJITSU_ERRATUM_010001 is not set +# CONFIG_HISILICON_ERRATUM_161600802 is not set +# CONFIG_HISILICON_ERRATUM_162100801 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set +# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set +# CONFIG_ROCKCHIP_ERRATUM_3588001 is not set +# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set +CONFIG_ARM64_VA_BITS_48=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_CLUSTER=y +CONFIG_NR_CPUS=8 +CONFIG_XEN=y +CONFIG_COMPAT=y +# CONFIG_ARM64_PTR_AUTH is not set +# CONFIG_ARM64_AMU_EXTN is not set +# CONFIG_ARM64_TLB_RANGE is not set +# CONFIG_ARM64_BTI is not set +# CONFIG_ARM64_E0PD is not set +# CONFIG_ARM64_MTE is not set +# CONFIG_ARM64_EPAN is not set +# CONFIG_ARM64_POE is not set +# CONFIG_ARM64_HAFT is not set +# CONFIG_ARM64_GCS is not set +CONFIG_HIBERNATION=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +CONFIG_CPU_IDLE=y +CONFIG_ARM_PSCI_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPUFREQ_DT=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y +CONFIG_JUMP_LABEL=y +CONFIG_BLK_DEV_INTEGRITY=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_SLAB_FREELIST_HARDENED=y +# CONFIG_COMPAT_BRK is not set +CONFIG_KSM=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y +CONFIG_CMA=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +CONFIG_CAN=y +CONFIG_BT=y +CONFIG_BT_LEDS=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_LL=y +CONFIG_CFG80211=y +CONFIG_MAC80211=y +CONFIG_MAC80211_LEDS=y +CONFIG_PCI=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=y +CONFIG_PCI_IOV=y +CONFIG_HOTPLUG_PCI=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCIE_RCAR_HOST=y +CONFIG_PCIE_RCAR_EP=y +CONFIG_PCIE_RCAR_GEN4_HOST=y +CONFIG_PCIE_RCAR_GEN4_EP=y +CONFIG_PCI_ENDPOINT=y +CONFIG_PCI_ENDPOINT_CONFIGFS=y +CONFIG_PCI_EPF_TEST=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_DMIID is not set +CONFIG_MTD=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_BE_BYTE_SWAP=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_HYPERBUS=y +CONFIG_RPCIF_HYPERBUS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_VIRTIO_BLK=y +CONFIG_SRAM=y +CONFIG_PCI_ENDPOINT_TEST=y +CONFIG_EEPROM_AT24=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_SAS_LIBSAS=y +CONFIG_SCSI_SAS_ATA=y +CONFIG_ATA=y +# CONFIG_SATA_PMP is not set +CONFIG_SATA_RCAR=y +CONFIG_NETDEVICES=y +CONFIG_TUN=y +CONFIG_VIRTIO_NET=y +CONFIG_SH_ETH=y +CONFIG_RAVB=y +CONFIG_RENESAS_ETHER_SWITCH=y +CONFIG_RTSN=y +CONFIG_MARVELL_10G_PHY=y +CONFIG_MARVELL_88Q2XXX_PHY=y +CONFIG_MICREL_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_CAN_RCAR=y +CONFIG_CAN_RCAR_CANFD=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y +CONFIG_WLCORE=y +CONFIG_WLCORE_SDIO=y +CONFIG_INPUT_MATRIXKMAP=y +CONFIG_INPUT_EVDEV=y +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=y +# CONFIG_MOUSE_PS2 is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_DA9063_ONKEY=y +# CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +# CONFIG_SERIAL_8250_EXAR is not set +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_8250_EM=y +# CONFIG_SERIAL_8250_PERICOM is not set +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_DEV_BUS=y +CONFIG_VIRTIO_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_RIIC=y +CONFIG_I2C_RZV2M=y +CONFIG_I2C_SH_MOBILE=y +CONFIG_I2C_RCAR=y +CONFIG_SPI=y +CONFIG_SPI_RPCIF=y +CONFIG_SPI_RSPI=y +CONFIG_SPI_RZV2M_CSI=y +CONFIG_SPI_SH_MSIOF=y +CONFIG_SPI_SPIDEV=y +CONFIG_PINCTRL_DA9062=y +CONFIG_PINCTRL_SINGLE=y +CONFIG_GPIO_RCAR=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_BD9571MWV=y +CONFIG_SENSORS_ISL28022=y +CONFIG_THERMAL=y +CONFIG_CPU_THERMAL=y +CONFIG_THERMAL_EMULATION=y +CONFIG_RCAR_THERMAL=y +CONFIG_RCAR_GEN3_THERMAL=y +CONFIG_RZG2L_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_RENESAS_WDT=y +CONFIG_RENESAS_RZG2LWDT=y +CONFIG_RENESAS_RZV2HWDT=y +CONFIG_MFD_BD9571MWV=y +CONFIG_MFD_DA9062=y +CONFIG_RZ_MTU3=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_BD9571MWV=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RAA215300=y +CONFIG_MEDIA_SUPPORT=y +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_SDR_SUPPORT=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SDR_PLATFORM_DRIVERS=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_RCAR_CSI2=y +CONFIG_VIDEO_RCAR_ISP=y +CONFIG_VIDEO_RCAR_VIN=y +CONFIG_VIDEO_RZG2L_CSI2=y +CONFIG_VIDEO_RZG2L_CRU=y +CONFIG_VIDEO_RENESAS_FCP=y +CONFIG_VIDEO_RENESAS_FDP1=y +CONFIG_VIDEO_RENESAS_VSP1=y +CONFIG_VIDEO_RCAR_DRIF=y +CONFIG_VIDEO_IMX219=y +CONFIG_VIDEO_OV5645=y +CONFIG_VIDEO_ADV7180=y +CONFIG_VIDEO_ADV748X=y +CONFIG_VIDEO_ADV7604=y +CONFIG_VIDEO_ADV7604_CEC=y +# CONFIG_MEDIA_TUNER_E4000 is not set +# CONFIG_MEDIA_TUNER_FC0011 is not set +# CONFIG_MEDIA_TUNER_FC0012 is not set +# CONFIG_MEDIA_TUNER_FC0013 is not set +# CONFIG_MEDIA_TUNER_FC2580 is not set +# CONFIG_MEDIA_TUNER_IT913X is not set +# CONFIG_MEDIA_TUNER_M88RS6000T is not set +# CONFIG_MEDIA_TUNER_MAX2165 is not set +# CONFIG_MEDIA_TUNER_MC44S803 is not set +# CONFIG_MEDIA_TUNER_MSI001 is not set +# CONFIG_MEDIA_TUNER_MT2060 is not set +# CONFIG_MEDIA_TUNER_MT2063 is not set +# CONFIG_MEDIA_TUNER_MT20XX is not set +# CONFIG_MEDIA_TUNER_MT2131 is not set +# CONFIG_MEDIA_TUNER_MT2266 is not set +# CONFIG_MEDIA_TUNER_MXL301RF is not set +# CONFIG_MEDIA_TUNER_MXL5005S is not set +# CONFIG_MEDIA_TUNER_MXL5007T is not set +# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set +# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set +# CONFIG_MEDIA_TUNER_QT1010 is not set +# CONFIG_MEDIA_TUNER_R820T is not set +# CONFIG_MEDIA_TUNER_SI2157 is not set +# CONFIG_MEDIA_TUNER_SIMPLE is not set +# CONFIG_MEDIA_TUNER_TDA18212 is not set +# CONFIG_MEDIA_TUNER_TDA18218 is not set +# CONFIG_MEDIA_TUNER_TDA18250 is not set +# CONFIG_MEDIA_TUNER_TDA18271 is not set +# CONFIG_MEDIA_TUNER_TDA827X is not set +# CONFIG_MEDIA_TUNER_TDA8290 is not set +# CONFIG_MEDIA_TUNER_TDA9887 is not set +# CONFIG_MEDIA_TUNER_TEA5761 is not set +# CONFIG_MEDIA_TUNER_TEA5767 is not set +# CONFIG_MEDIA_TUNER_TUA9001 is not set +# CONFIG_MEDIA_TUNER_XC2028 is not set +# CONFIG_MEDIA_TUNER_XC4000 is not set +# CONFIG_MEDIA_TUNER_XC5000 is not set +CONFIG_DRM=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_I2C_NXP_TDA998X=y +CONFIG_DRM_RCAR_DU=y +CONFIG_DRM_RCAR_DW_HDMI=y +CONFIG_DRM_RZG2L_DU=y +CONFIG_DRM_RZG2L_MIPI_DSI=y +CONFIG_DRM_PANEL_LVDS=y +CONFIG_DRM_DISPLAY_CONNECTOR=y +CONFIG_DRM_SIMPLE_BRIDGE=y +CONFIG_DRM_THINE_THC63LVD1024=y +CONFIG_DRM_TI_SN65DSI86=y +CONFIG_DRM_I2C_ADV7511=y +CONFIG_DRM_I2C_ADV7511_AUDIO=y +CONFIG_DRM_DW_HDMI_AHB_AUDIO=y +CONFIG_DRM_DW_HDMI_I2S_AUDIO=y +CONFIG_DRM_DW_HDMI_CEC=y +CONFIG_DRM_PANFROST=y +CONFIG_FB_DEVICE=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_RCAR=y +CONFIG_SND_SOC_RZ=y +CONFIG_SND_SOC_AK4613=y +CONFIG_SND_SOC_AK4619=y +CONFIG_SND_SOC_DA7213=y +CONFIG_SND_SOC_PCM3168A_I2C=y +CONFIG_SND_SOC_SIMPLE_MUX=y +CONFIG_SND_SOC_WM8978=y +CONFIG_SND_SIMPLE_CARD=y +CONFIG_SND_AUDIO_GRAPH_CARD=y +CONFIG_SND_AUDIO_GRAPH_CARD2=y +CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USB_XHCI_RZV2M=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_RENESAS_USBHS_HCD=y +CONFIG_USB_RENESAS_USBHS=y +CONFIG_USB_STORAGE=y +CONFIG_USB_HSIC_USB3503=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_RENESAS_USBHS_UDC=y +CONFIG_USB_RZV2M_USB3DRD=y +CONFIG_USB_RENESAS_USB3=y +CONFIG_USB_SNP_UDC_PLAT=y +CONFIG_USB_BDC_UDC=y +CONFIG_TYPEC=y +CONFIG_TYPEC_HD3SS3220=y +CONFIG_MMC=y +CONFIG_MMC_SDHI=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_RENESAS=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_ISL1208=y +CONFIG_RTC_DRV_RX8581=y +CONFIG_RTC_DRV_DA9063=y +CONFIG_DMADEVICES=y +CONFIG_DW_EDMA=y +CONFIG_RCAR_DMAC=y +CONFIG_RENESAS_USB_DMAC=y +CONFIG_RZ_DMAC=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_MMIO=y +# CONFIG_XEN_PCIDEV_STUB is not set +CONFIG_STAGING=y +CONFIG_STAGING_MEDIA=y +CONFIG_VIDEO_MAX96712=y +CONFIG_COMMON_CLK_CS2000_CP=y +CONFIG_COMMON_CLK_PWM=y +CONFIG_COMMON_CLK_VC3=y +CONFIG_COMMON_CLK_VC5=y +CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y +CONFIG_CLK_RENESAS_VBATTB=y +CONFIG_HWSPINLOCK=y +# CONFIG_FSL_ERRATUM_A008585 is not set +# CONFIG_HISILICON_ERRATUM_161010101 is not set +# CONFIG_ARM64_ERRATUM_858921 is not set +CONFIG_RENESAS_OSTM=y +CONFIG_MAILBOX=y +CONFIG_ARCH_R8A77995=y +CONFIG_ARCH_R8A77990=y +CONFIG_ARCH_R8A77951=y +CONFIG_ARCH_R8A77965=y +CONFIG_ARCH_R8A77960=y +CONFIG_ARCH_R8A77961=y +CONFIG_ARCH_R8A779F0=y +CONFIG_ARCH_R8A77980=y +CONFIG_ARCH_R8A77970=y +CONFIG_ARCH_R8A779A0=y +CONFIG_ARCH_R8A779G0=y +CONFIG_ARCH_R8A779H0=y +CONFIG_ARCH_R8A774C0=y +CONFIG_ARCH_R8A774E1=y +CONFIG_ARCH_R8A774A1=y +CONFIG_ARCH_R8A774B1=y +CONFIG_ARCH_R9A07G043=y +CONFIG_ARCH_R9A07G044=y +CONFIG_ARCH_R9A07G054=y +CONFIG_ARCH_R9A08G045=y +CONFIG_ARCH_R9A09G011=y +CONFIG_ARCH_R9A09G047=y +CONFIG_ARCH_R9A09G057=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_MEMORY=y +CONFIG_RENESAS_RPCIF=y +CONFIG_IIO=y +CONFIG_MAX9611=y +CONFIG_RZG2L_ADC=y +CONFIG_PWM=y +CONFIG_PWM_RCAR=y +CONFIG_PWM_RENESAS_TPU=y +CONFIG_PWM_RZ_MTU3=y +CONFIG_RESET_RZG2L_USBPHY_CTRL=y +CONFIG_PHY_CAN_TRANSCEIVER=y +CONFIG_PHY_R8A779F0_ETHERNET_SERDES=y +CONFIG_PHY_RCAR_GEN3_PCIE=y +CONFIG_PHY_RCAR_GEN3_USB2=y +CONFIG_PHY_RCAR_GEN3_USB3=y +CONFIG_NVMEM_RCAR_EFUSE=y +CONFIG_TEE=y +CONFIG_OPTEE=y +CONFIG_COUNTER=y +CONFIG_RZ_MTU3_CNT=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_FANOTIFY=y +CONFIG_QUOTA=y +CONFIG_AUTOFS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_HUGETLBFS=y +CONFIG_SQUASHFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_DEV_CCREE=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=128 +CONFIG_CMA_ALIGNMENT=9 +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_FTRACE is not set
diff --git a/arch/riscv/configs/rzfive_defconfig b/arch/riscv/configs/rzfive_defconfig new file mode 100644 index 0000000..fe44f9c --- /dev/null +++ b/arch/riscv/configs/rzfive_defconfig
@@ -0,0 +1,217 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_SYSCALL=y +CONFIG_PREEMPT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_CGROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EXPERT=y +# CONFIG_SYSFS_SYSCALL is not set +CONFIG_PROFILING=y +CONFIG_ARCH_RENESAS=y +CONFIG_ERRATA_SIFIVE=y +CONFIG_NONPORTABLE=y +# CONFIG_RISCV_ISA_SUPM is not set +# CONFIG_RISCV_ISA_ZICBOM is not set +# CONFIG_EFI is not set +CONFIG_PM_AUTOSLEEP=y +CONFIG_CPU_IDLE=y +CONFIG_RISCV_SBI_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPUFREQ_DT=y +CONFIG_JUMP_LABEL=y +CONFIG_SLAB_FREELIST_HARDENED=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NETFILTER=y +CONFIG_NET_SCHED=y +CONFIG_NETLINK_DIAG=y +CONFIG_CGROUP_NET_PRIO=y +CONFIG_CAN=y +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_PAGE_POOL_STATS=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_MTD=y +# CONFIG_MTD_OF_PARTS is not set +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_VIRTIO_BLK=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +CONFIG_SCSI_VIRTIO=y +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_MD=y +CONFIG_NETDEVICES=y +CONFIG_VIRTIO_NET=y +CONFIG_RAVB=y +CONFIG_MICREL_PHY=y +CONFIG_MICROSEMI_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_CAN_RCAR_CANFD=y +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_MOUSE_PS2 is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_DA9063_ONKEY=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_SERIAL_EARLYCON_RISCV_SBI=y +CONFIG_SERIAL_SH_SCI=y +CONFIG_HVC_RISCV_SBI=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_HW_RANDOM_VIRTIO=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_RIIC=y +CONFIG_SPI=y +CONFIG_SPI_RPCIF=y +CONFIG_SPI_RSPI=y +# CONFIG_PTP_1588_CLOCK is not set +CONFIG_PINCTRL_DA9062=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y +CONFIG_POWER_SUPPLY=y +CONFIG_THERMAL=y +CONFIG_THERMAL_DEBUGFS=y +CONFIG_CPU_THERMAL=y +CONFIG_DA9062_THERMAL=y +CONFIG_RZG2L_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_DA9062_WATCHDOG=y +CONFIG_RENESAS_RZG2LWDT=y +CONFIG_MFD_DA9062=y +CONFIG_RZ_MTU3=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_SOUND=y +CONFIG_SND=y +# CONFIG_SND_PCM_TIMER is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_PROC_FS is not set +# CONFIG_SND_CTL_FAST_LOOKUP is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_RZ=y +CONFIG_SND_SOC_WM8978=y +CONFIG_SND_SIMPLE_CARD=y +CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_RENESAS_USBHS=y +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=y +CONFIG_USB_GADGET=y +CONFIG_USB_RENESAS_USBHS_UDC=y +CONFIG_MMC=y +CONFIG_MMC_SDHI=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DA9063=y +CONFIG_DMADEVICES=y +CONFIG_RZ_DMAC=y +CONFIG_SYNC_FILE=y +CONFIG_COMMON_CLK_VC3=y +CONFIG_RENESAS_OSTM=y +CONFIG_MAILBOX=y +# CONFIG_RISCV_IOMMU is not set +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_CTRL=y +CONFIG_RPMSG_VIRTIO=y +CONFIG_ARCH_R9A07G043=y +CONFIG_EXTCON=y +CONFIG_MEMORY=y +CONFIG_RENESAS_RPCIF=y +CONFIG_IIO=y +CONFIG_RZG2L_ADC=y +CONFIG_RESET_RZG2L_USBPHY_CTRL=y +CONFIG_RESET_SIMPLE=y +CONFIG_PHY_RCAR_GEN3_USB2=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_AUTOFS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4_2_READ_PLUS is not set +CONFIG_9P_FS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_SECURITY=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_DEV_VIRTIO=y +CONFIG_PRINTK_TIME=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_PAGEALLOC=y +CONFIG_SCHED_STACK_END_CHECK=y +CONFIG_DEBUG_VM=y +CONFIG_DEBUG_VM_PGFLAGS=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_SOFTLOCKUP_DETECTOR=y +CONFIG_WQ_WATCHDOG=y +CONFIG_WQ_CPU_INTENSIVE_REPORT=y +# CONFIG_SCHED_DEBUG is not set +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_RWSEMS=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_DEBUG_LIST=y +CONFIG_DEBUG_PLIST=y +CONFIG_DEBUG_SG=y +CONFIG_RCU_EQS_DEBUG=y +# CONFIG_FTRACE is not set +CONFIG_MEMTEST=y
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 63ec2f21..9c4a21e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c
@@ -88,6 +88,7 @@ struct ata_force_param { unsigned int xfer_mask; unsigned int quirk_on; unsigned int quirk_off; + unsigned int pflags_on; u16 lflags_on; u16 lflags_off; }; @@ -332,6 +333,35 @@ void ata_force_cbl(struct ata_port *ap) } /** + * ata_force_pflags - force port flags according to libata.force + * @ap: ATA port of interest + * + * Force port flags according to libata.force and whine about it. + * + * LOCKING: + * EH context. + */ +static void ata_force_pflags(struct ata_port *ap) +{ + int i; + + for (i = ata_force_tbl_size - 1; i >= 0; i--) { + const struct ata_force_ent *fe = &ata_force_tbl[i]; + + if (fe->port != -1 && fe->port != ap->print_id) + continue; + + /* let pflags stack */ + if (fe->param.pflags_on) { + ap->pflags |= fe->param.pflags_on; + ata_port_notice(ap, + "FORCE: port flag 0x%x forced -> 0x%x\n", + fe->param.pflags_on, ap->pflags); + } + } +} + +/** * ata_force_link_limits - force link limits according to libata.force * @link: ATA link of interest * @@ -486,6 +516,7 @@ static void ata_force_quirks(struct ata_device *dev) } } #else +static inline void ata_force_pflags(struct ata_port *ap) { } static inline void ata_force_link_limits(struct ata_link *link) { } static inline void ata_force_xfermask(struct ata_device *dev) { } static inline void ata_force_quirks(struct ata_device *dev) { } @@ -5456,6 +5487,8 @@ struct ata_port *ata_port_alloc(struct ata_host *host) #endif ata_sff_port_init(ap); + ata_force_pflags(ap); + return ap; } EXPORT_SYMBOL_GPL(ata_port_alloc); @@ -6268,6 +6301,9 @@ EXPORT_SYMBOL_GPL(ata_platform_remove_one); { "no" #name, .lflags_on = (flags) }, \ { #name, .lflags_off = (flags) } +#define force_pflag_on(name, flags) \ + { #name, .pflags_on = (flags) } + #define force_quirk_on(name, flag) \ { #name, .quirk_on = (flag) } @@ -6327,6 +6363,8 @@ static const struct ata_force_param force_tbl[] __initconst = { force_lflag_on(rstonce, ATA_LFLAG_RST_ONCE), force_lflag_onoff(dbdelay, ATA_LFLAG_NO_DEBOUNCE_DELAY), + force_pflag_on(external, ATA_PFLAG_EXTERNAL), + force_quirk_onoff(ncq, ATA_QUIRK_NONCQ), force_quirk_onoff(ncqtrim, ATA_QUIRK_NO_NCQ_TRIM), force_quirk_onoff(ncqati, ATA_QUIRK_NO_NCQ_ON_ATI),
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index bdb4504..6f31240 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h
@@ -73,12 +73,12 @@ struct regmap { void *bus_context; const char *name; - bool async; spinlock_t async_lock; wait_queue_head_t async_waitq; struct list_head async_list; struct list_head async_free; int async_ret; + bool async; #ifdef CONFIG_DEBUG_FS bool debugfs_disable; @@ -117,8 +117,6 @@ struct regmap { void *val_buf, size_t val_size); int (*write)(void *context, const void *data, size_t count); - bool defer_caching; - unsigned long read_flag_mask; unsigned long write_flag_mask; @@ -127,6 +125,8 @@ struct regmap { int reg_stride; int reg_stride_order; + bool defer_caching; + /* If set, will always write field to HW. */ bool force_write_field; @@ -161,6 +161,9 @@ struct regmap { struct reg_sequence *patch; int patch_regs; + /* if set, the regmap core can sleep */ + bool can_sleep; + /* if set, converts bulk read to single read */ bool use_single_read; /* if set, converts bulk write to single write */ @@ -176,9 +179,6 @@ struct regmap { void *selector_work_buf; /* Scratch buffer used for selector */ struct hwspinlock *hwlock; - - /* if set, the regmap core can sleep */ - bool can_sleep; }; struct regcache_ops {
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 33b3bc9..282f816 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c
@@ -1127,8 +1127,8 @@ static void vdc_queue_drain(struct vdc_port *port) spin_lock_irq(&port->vio.lock); port->drain = 0; - blk_mq_unquiesce_queue(q, memflags); - blk_mq_unfreeze_queue(q); + blk_mq_unquiesce_queue(q); + blk_mq_unfreeze_queue(q, memflags); } static void vdc_ldc_reset_timer_work(struct work_struct *work)
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c index 491b529..ca347297 100644 --- a/drivers/gpio/gpio-brcmstb.c +++ b/drivers/gpio/gpio-brcmstb.c
@@ -9,6 +9,7 @@ #include <linux/irqchip/chained_irq.h> #include <linux/interrupt.h> #include <linux/platform_device.h> +#include <linux/string_choices.h> enum gio_reg_index { GIO_REG_ODEN = 0, @@ -224,7 +225,7 @@ static int brcmstb_gpio_priv_set_wake(struct brcmstb_gpio_priv *priv, ret = disable_irq_wake(priv->parent_wake_irq); if (ret) dev_err(&priv->pdev->dev, "failed to %s wake-up interrupt\n", - enable ? "enable" : "disable"); + str_enable_disable(enable)); return ret; }
diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 25db014..56effd0 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c
@@ -15,6 +15,7 @@ #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/seq_file.h> +#include <linux/string_choices.h> #include <linux/types.h> #define CRYSTALCOVE_GPIO_NUM 16 @@ -317,7 +318,7 @@ static void crystalcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip offset = gpio % 8; seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s %s\n", gpio, ctlo & CTLO_DIR_OUT ? "out" : "in ", - ctli & 0x1 ? "hi" : "lo", + str_hi_lo(ctli & 0x1), ctli & CTLI_INTCNT_NE ? "fall" : " ", ctli & CTLI_INTCNT_PE ? "rise" : " ", ctlo,
diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 169f33c4..30a0522 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c
@@ -30,6 +30,7 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spinlock.h> +#include <linux/string_choices.h> #define GRGPIO_MAX_NGPIO 32 @@ -438,7 +439,7 @@ static int grgpio_probe(struct platform_device *ofdev) } dev_info(dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n", - priv->regs, gc->base, gc->ngpio, priv->domain ? "on" : "off"); + priv->regs, gc->base, gc->ngpio, str_on_off(priv->domain)); return 0; }
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 5ffb332..363bad2 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c
@@ -49,6 +49,7 @@ #include <linux/pwm.h> #include <linux/regmap.h> #include <linux/slab.h> +#include <linux/string_choices.h> /* * GPIO unit register offsets. @@ -907,14 +908,14 @@ static void mvebu_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) if (is_out) { seq_printf(s, " out %s %s\n", - out & msk ? "hi" : "lo", + str_hi_lo(out & msk), blink & msk ? "(blink )" : ""); continue; } seq_printf(s, " in %s (act %s) - IRQ", - (data_in ^ in_pol) & msk ? "hi" : "lo", - in_pol & msk ? "lo" : "hi"); + str_hi_lo((data_in ^ in_pol) & msk), + str_lo_hi(in_pol & msk)); if (!((edg_msk | lvl_msk) & msk)) { seq_puts(s, " disabled\n"); continue;
diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index 836f1cc..fa19a44 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c
@@ -30,6 +30,7 @@ #include <linux/reset.h> #include <linux/seq_file.h> #include <linux/slab.h> +#include <linux/string_choices.h> #include <linux/types.h> #include <linux/gpio/gpio-nomadik.h> @@ -430,7 +431,7 @@ void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev, seq_printf(s, " gpio-%-3d (%-20.20s) out %s %s", gpio, label ?: "(none)", - data_out ? "hi" : "lo", + str_hi_lo(data_out), (mode < 0) ? "unknown" : modes[mode]); } else { int irq = chip->to_irq(chip, offset);
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 75a3633..2e22e1e 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c
@@ -15,6 +15,7 @@ #include <linux/platform_device.h> #include <linux/seq_file.h> #include <linux/slab.h> +#include <linux/string_choices.h> /* * These registers are modified under the irq bus lock and cached to avoid @@ -273,8 +274,7 @@ static void stmpe_dbg_show_one(struct seq_file *s, if (dir) { seq_printf(s, " gpio-%-3d (%-20.20s) out %s", - gpio, label ?: "(none)", - val ? "hi" : "lo"); + gpio, label ?: "(none)", str_hi_lo(val)); } else { u8 edge_det_reg; u8 rise_reg; @@ -343,7 +343,7 @@ static void stmpe_dbg_show_one(struct seq_file *s, seq_printf(s, " gpio-%-3d (%-20.20s) in %s %13s %13s %25s %25s", gpio, label ?: "(none)", - val ? "hi" : "lo", + str_hi_lo(val), edge_det_values[edge_det], irqen ? "IRQ-enabled" : "IRQ-disabled", rise_values[rise],
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index 94ca9d0..1ec24f6 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c
@@ -15,6 +15,7 @@ #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/seq_file.h> +#include <linux/string_choices.h> /* * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks: @@ -393,7 +394,7 @@ static void wcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s\n", gpio, ctlo & CTLO_DIR_OUT ? "out" : "in ", - ctli & 0x1 ? "hi" : "lo", + str_hi_lo(ctli & 0x1), ctli & CTLI_INTCNT_NE ? "fall" : " ", ctli & CTLI_INTCNT_PE ? "rise" : " ", ctlo,
diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c index f7d5120..61bb83a 100644 --- a/drivers/gpio/gpio-wm831x.c +++ b/drivers/gpio/gpio-wm831x.c
@@ -16,6 +16,7 @@ #include <linux/mfd/core.h> #include <linux/platform_device.h> #include <linux/seq_file.h> +#include <linux/string_choices.h> #include <linux/mfd/wm831x/core.h> #include <linux/mfd/wm831x/pdata.h> @@ -234,7 +235,7 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) seq_printf(s, " %s %s %s %s%s\n" " %s%s (0x%4x)\n", reg & WM831X_GPN_DIR ? "in" : "out", - wm831x_gpio_get(chip, i) ? "high" : "low", + str_high_low(wm831x_gpio_get(chip, i)), pull, powerdomain, reg & WM831X_GPN_POL ? "" : " inverted",
diff --git a/drivers/gpio/gpio-xra1403.c b/drivers/gpio/gpio-xra1403.c index dc2710c..842cf87 100644 --- a/drivers/gpio/gpio-xra1403.c +++ b/drivers/gpio/gpio-xra1403.c
@@ -13,6 +13,7 @@ #include <linux/mutex.h> #include <linux/seq_file.h> #include <linux/spi/spi.h> +#include <linux/string_choices.h> #include <linux/regmap.h> /* XRA1403 registers */ @@ -140,7 +141,7 @@ static void xra1403_dbg_show(struct seq_file *s, struct gpio_chip *chip) seq_printf(s, " gpio-%-3d (%-12s) %s %s\n", chip->base + i, label, (gcr & BIT(i)) ? "in" : "out", - (gsr & BIT(i)) ? "hi" : "lo"); + str_hi_lo(gsr & BIT(i))); } } #else
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 679ed76..be33515 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c
@@ -26,6 +26,7 @@ #include <linux/slab.h> #include <linux/srcu.h> #include <linux/string.h> +#include <linux/string_choices.h> #include <linux/gpio.h> #include <linux/gpio/driver.h> @@ -5007,7 +5008,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev) seq_printf(s, " gpio-%-3u (%-20.20s|%-20.20s) %s %s %s%s\n", gpio, desc->name ?: "", gpiod_get_label(desc), is_out ? "out" : "in ", - value >= 0 ? (value ? "hi" : "lo") : "? ", + value >= 0 ? str_hi_lo(value) : "? ", is_irq ? "IRQ " : "", active_low ? "ACTIVE LOW" : ""); } else if (desc->name) {
diff --git a/drivers/gpu/drm/display/drm_dp_cec.c b/drivers/gpu/drm/display/drm_dp_cec.c index 007ceb2..56a4965e 100644 --- a/drivers/gpu/drm/display/drm_dp_cec.c +++ b/drivers/gpu/drm/display/drm_dp_cec.c
@@ -311,16 +311,6 @@ void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address) if (!aux->transfer) return; -#ifndef CONFIG_MEDIA_CEC_RC - /* - * CEC_CAP_RC is part of CEC_CAP_DEFAULTS, but it is stripped by - * cec_allocate_adapter() if CONFIG_MEDIA_CEC_RC is undefined. - * - * Do this here as well to ensure the tests against cec_caps are - * correct. - */ - cec_caps &= ~CEC_CAP_RC; -#endif cancel_delayed_work_sync(&aux->cec.unregister_work); mutex_lock(&aux->cec.lock); @@ -337,7 +327,9 @@ void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address) num_las = CEC_MAX_LOG_ADDRS; if (aux->cec.adap) { - if (aux->cec.adap->capabilities == cec_caps && + /* Check if the adapter properties have changed */ + if ((aux->cec.adap->capabilities & CEC_CAP_MONITOR_ALL) == + (cec_caps & CEC_CAP_MONITOR_ALL) && aux->cec.adap->available_log_addrs == num_las) { /* Unchanged, so just set the phys addr */ cec_s_phys_addr(aux->cec.adap, source_physical_address, false);
diff --git a/drivers/irqchip/irq-riscv-aplic-direct.c b/drivers/irqchip/irq-riscv-aplic-direct.c index 7cd6b64..205ad61 100644 --- a/drivers/irqchip/irq-riscv-aplic-direct.c +++ b/drivers/irqchip/irq-riscv-aplic-direct.c
@@ -31,7 +31,7 @@ struct aplic_direct { }; struct aplic_idc { - unsigned int hart_index; + u32 hart_index; void __iomem *regs; struct aplic_direct *direct; }; @@ -219,6 +219,20 @@ static int aplic_direct_parse_parent_hwirq(struct device *dev, u32 index, return 0; } +static int aplic_direct_get_hart_index(struct device *dev, u32 logical_index, + u32 *hart_index) +{ + const char *prop_hart_index = "riscv,hart-indexes"; + struct device_node *np = to_of_node(dev->fwnode); + + if (!np || !of_property_present(np, prop_hart_index)) { + *hart_index = logical_index; + return 0; + } + + return of_property_read_u32_index(np, prop_hart_index, logical_index, hart_index); +} + int aplic_direct_setup(struct device *dev, void __iomem *regs) { int i, j, rc, cpu, current_cpu, setup_count = 0; @@ -265,8 +279,12 @@ int aplic_direct_setup(struct device *dev, void __iomem *regs) cpumask_set_cpu(cpu, &direct->lmask); idc = per_cpu_ptr(&aplic_idcs, cpu); - idc->hart_index = i; - idc->regs = priv->regs + APLIC_IDC_BASE + i * APLIC_IDC_SIZE; + rc = aplic_direct_get_hart_index(dev, i, &idc->hart_index); + if (rc) { + dev_warn(dev, "hart index not found for IDC%d\n", i); + continue; + } + idc->regs = priv->regs + APLIC_IDC_BASE + idc->hart_index * APLIC_IDC_SIZE; idc->direct = direct; aplic_idc_set_delivery(idc, true);
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index 1224721..5fd4558 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c
@@ -159,18 +159,6 @@ int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on) } EXPORT_SYMBOL(mmc_gpio_set_cd_wake); -/* Register an alternate interrupt service routine for - * the card-detect GPIO. - */ -void mmc_gpio_set_cd_isr(struct mmc_host *host, irq_handler_t isr) -{ - struct mmc_gpio *ctx = host->slot.handler_priv; - - WARN_ON(ctx->cd_gpio_isr); - ctx->cd_gpio_isr = isr; -} -EXPORT_SYMBOL(mmc_gpio_set_cd_isr); - /** * mmc_gpiod_request_cd - request a gpio descriptor for card-detection * @host: mmc host
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 4b6e913..345ea91 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c
@@ -273,6 +273,7 @@ #define MSDC_PAD_TUNE_CMD2_SEL BIT(21) /* RW */ #define PAD_DS_TUNE_DLY_SEL BIT(0) /* RW */ +#define PAD_DS_TUNE_DLY2_SEL BIT(1) /* RW */ #define PAD_DS_TUNE_DLY1 GENMASK(6, 2) /* RW */ #define PAD_DS_TUNE_DLY2 GENMASK(11, 7) /* RW */ #define PAD_DS_TUNE_DLY3 GENMASK(16, 12) /* RW */ @@ -318,6 +319,7 @@ /* EMMC50_PAD_DS_TUNE mask */ #define PAD_DS_DLY_SEL BIT(16) /* RW */ +#define PAD_DS_DLY2_SEL BIT(15) /* RW */ #define PAD_DS_DLY1 GENMASK(14, 10) /* RW */ #define PAD_DS_DLY3 GENMASK(4, 0) /* RW */ @@ -2504,13 +2506,23 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode) static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) { struct msdc_host *host = mmc_priv(mmc); + host->hs400_mode = true; - if (host->top_base) - writel(host->hs400_ds_delay, - host->top_base + EMMC50_PAD_DS_TUNE); - else - writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE); + if (host->top_base) { + if (host->hs400_ds_dly3) + sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE, + PAD_DS_DLY3, host->hs400_ds_dly3); + if (host->hs400_ds_delay) + writel(host->hs400_ds_delay, + host->top_base + EMMC50_PAD_DS_TUNE); + } else { + if (host->hs400_ds_dly3) + sdr_set_field(host->base + PAD_DS_TUNE, + PAD_DS_TUNE_DLY3, host->hs400_ds_dly3); + if (host->hs400_ds_delay) + writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE); + } /* hs400 mode must set it to 0 */ sdr_clr_bits(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS); /* to improve read performance, set outstanding to 2 */ @@ -2530,14 +2542,11 @@ static int msdc_execute_hs400_tuning(struct mmc_host *mmc, struct mmc_card *card if (host->top_base) { sdr_set_bits(host->top_base + EMMC50_PAD_DS_TUNE, PAD_DS_DLY_SEL); - if (host->hs400_ds_dly3) - sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE, - PAD_DS_DLY3, host->hs400_ds_dly3); + sdr_clr_bits(host->top_base + EMMC50_PAD_DS_TUNE, + PAD_DS_DLY2_SEL); } else { sdr_set_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY_SEL); - if (host->hs400_ds_dly3) - sdr_set_field(host->base + PAD_DS_TUNE, - PAD_DS_TUNE_DLY3, host->hs400_ds_dly3); + sdr_clr_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY2_SEL); } host->hs400_tuning = true;
diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c index b73f673..f75c318 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c
@@ -155,7 +155,6 @@ struct sdhci_am654_data { u32 tuning_loop; #define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0) -#define SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA BIT(1) }; struct window { @@ -357,29 +356,6 @@ static void sdhci_j721e_4bit_set_clock(struct sdhci_host *host, sdhci_set_clock(host, clock); } -static int sdhci_am654_start_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct sdhci_host *host = mmc_priv(mmc); - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host); - int ret; - - if ((sdhci_am654->quirks & SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA) && - ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) { - if (!IS_ERR(mmc->supply.vqmmc)) { - ret = mmc_regulator_set_vqmmc(mmc, ios); - if (ret < 0) { - pr_err("%s: Switching to 1.8V signalling voltage failed,\n", - mmc_hostname(mmc)); - return -EIO; - } - } - return 0; - } - - return sdhci_start_signal_voltage_switch(mmc, ios); -} - static u8 sdhci_am654_write_power_on(struct sdhci_host *host, u8 val, int reg) { writeb(val, host->ioaddr + reg); @@ -868,11 +844,6 @@ static int sdhci_am654_get_of_property(struct platform_device *pdev, if (device_property_read_bool(dev, "ti,fails-without-test-cd")) sdhci_am654->quirks |= SDHCI_AM654_QUIRK_FORCE_CDTEST; - /* Suppress v1p8 ena for eMMC and SD with vqmmc supply */ - if (!!of_parse_phandle(dev->of_node, "vmmc-supply", 0) == - !!of_parse_phandle(dev->of_node, "vqmmc-supply", 0)) - sdhci_am654->quirks |= SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA; - sdhci_get_of_property(pdev); return 0; @@ -969,7 +940,6 @@ static int sdhci_am654_probe(struct platform_device *pdev) goto err_pltfm_free; } - host->mmc_host_ops.start_signal_voltage_switch = sdhci_am654_start_signal_voltage_switch; host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning; pm_runtime_get_noresume(dev);
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 4004677..818d4e4 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c
@@ -1700,7 +1700,13 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count) status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, NULL, 0, &result); - if (status < 0) + + /* + * It's either a kernel error or the host observed a connection + * lost. In either case it's not possible communicate with the + * controller and thus enter the error code path. + */ + if (status < 0 || status == NVME_SC_HOST_PATH_ERROR) return status; /*
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 094be16..f4f1866 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c
@@ -781,11 +781,19 @@ nvme_fc_abort_lsops(struct nvme_fc_rport *rport) static void nvme_fc_ctrl_connectivity_loss(struct nvme_fc_ctrl *ctrl) { + enum nvme_ctrl_state state; + unsigned long flags; + dev_info(ctrl->ctrl.device, "NVME-FC{%d}: controller connectivity lost. Awaiting " "Reconnect", ctrl->cnum); - switch (nvme_ctrl_state(&ctrl->ctrl)) { + spin_lock_irqsave(&ctrl->lock, flags); + set_bit(ASSOC_FAILED, &ctrl->flags); + state = nvme_ctrl_state(&ctrl->ctrl); + spin_unlock_irqrestore(&ctrl->lock, flags); + + switch (state) { case NVME_CTRL_NEW: case NVME_CTRL_LIVE: /* @@ -2079,7 +2087,8 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) nvme_fc_complete_rq(rq); check_error: - if (terminate_assoc && ctrl->ctrl.state != NVME_CTRL_RESETTING) + if (terminate_assoc && + nvme_ctrl_state(&ctrl->ctrl) != NVME_CTRL_RESETTING) queue_work(nvme_reset_wq, &ctrl->ioerr_work); } @@ -2533,6 +2542,8 @@ __nvme_fc_abort_outstanding_ios(struct nvme_fc_ctrl *ctrl, bool start_queues) static void nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) { + enum nvme_ctrl_state state = nvme_ctrl_state(&ctrl->ctrl); + /* * if an error (io timeout, etc) while (re)connecting, the remote * port requested terminating of the association (disconnect_ls) @@ -2540,9 +2551,8 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) * the controller. Abort any ios on the association and let the * create_association error path resolve things. */ - if (ctrl->ctrl.state == NVME_CTRL_CONNECTING) { + if (state == NVME_CTRL_CONNECTING) { __nvme_fc_abort_outstanding_ios(ctrl, true); - set_bit(ASSOC_FAILED, &ctrl->flags); dev_warn(ctrl->ctrl.device, "NVME-FC{%d}: transport error during (re)connect\n", ctrl->cnum); @@ -2550,7 +2560,7 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) } /* Otherwise, only proceed if in LIVE state - e.g. on first error */ - if (ctrl->ctrl.state != NVME_CTRL_LIVE) + if (state != NVME_CTRL_LIVE) return; dev_warn(ctrl->ctrl.device, @@ -3167,12 +3177,18 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl) else ret = nvme_fc_recreate_io_queues(ctrl); } - if (!ret && test_bit(ASSOC_FAILED, &ctrl->flags)) - ret = -EIO; if (ret) goto out_term_aen_ops; - changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE); + spin_lock_irqsave(&ctrl->lock, flags); + if (!test_bit(ASSOC_FAILED, &ctrl->flags)) + changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE); + else + ret = -EIO; + spin_unlock_irqrestore(&ctrl->lock, flags); + + if (ret) + goto out_term_aen_ops; ctrl->ctrl.nr_reconnects = 0; @@ -3578,8 +3594,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, list_add_tail(&ctrl->ctrl_list, &rport->ctrl_list); spin_unlock_irqrestore(&rport->lock, flags); - if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING) || - !nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { + if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { dev_err(ctrl->ctrl.device, "NVME-FC{%d}: failed to init ctrl state\n", ctrl->cnum); goto fail_ctrl;
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 278bed4..9197a5b 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c
@@ -2153,14 +2153,6 @@ static int nvme_alloc_host_mem_multi(struct nvme_dev *dev, u64 preferred, return 0; out_free_bufs: - while (--i >= 0) { - size_t size = le32_to_cpu(descs[i].size) * NVME_CTRL_PAGE_SIZE; - - dma_free_attrs(dev->dev, size, bufs[i], - le64_to_cpu(descs[i].addr), - DMA_ATTR_NO_KERNEL_MAPPING | DMA_ATTR_NO_WARN); - } - kfree(bufs); out_free_descs: dma_free_coherent(dev->dev, descs_size, descs, descs_dma); @@ -3147,7 +3139,9 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) * because of high power consumption (> 2 Watt) in s2idle * sleep. Only some boards with Intel CPU are affected. */ - if (dmi_match(DMI_BOARD_NAME, "GMxPXxx") || + if (dmi_match(DMI_BOARD_NAME, "DN50Z-140HC-YD") || + dmi_match(DMI_BOARD_NAME, "GMxPXxx") || + dmi_match(DMI_BOARD_NAME, "GXxMRXx") || dmi_match(DMI_BOARD_NAME, "PH4PG31") || dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1") || dmi_match(DMI_BOARD_NAME, "PH6PG01_PH6PG71"))
diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c index b68a9e5..3a41b9a 100644 --- a/drivers/nvme/host/sysfs.c +++ b/drivers/nvme/host/sysfs.c
@@ -792,7 +792,7 @@ static umode_t nvme_tls_attrs_are_visible(struct kobject *kobj, return a->mode; } -const struct attribute_group nvme_tls_attrs_group = { +static const struct attribute_group nvme_tls_attrs_group = { .attrs = nvme_tls_attrs, .is_visible = nvme_tls_attrs_are_visible, };
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index e670dc1..acc138b 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c
@@ -1068,6 +1068,7 @@ static void nvme_execute_identify_ns_nvm(struct nvmet_req *req) goto out; } status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id)); + kfree(id); out: nvmet_req_complete(req, status); }
diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c index a7ff05b..eb406c9 100644 --- a/drivers/nvme/target/fabrics-cmd.c +++ b/drivers/nvme/target/fabrics-cmd.c
@@ -287,7 +287,7 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req) args.subsysnqn = d->subsysnqn; args.hostnqn = d->hostnqn; args.hostid = &d->hostid; - args.kato = c->kato; + args.kato = le32_to_cpu(c->kato); ctrl = nvmet_alloc_ctrl(&args); if (!ctrl)
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c index c1f574f..83be065 100644 --- a/drivers/nvme/target/io-cmd-bdev.c +++ b/drivers/nvme/target/io-cmd-bdev.c
@@ -272,7 +272,7 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req) iter_flags = SG_MITER_FROM_SG; } - if (req->cmd->rw.control & NVME_RW_LR) + if (req->cmd->rw.control & cpu_to_le16(NVME_RW_LR)) opf |= REQ_FAILFAST_DEV; if (is_pci_p2pdma_page(sg_page(req->sg)))
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index b540216..4be8d22 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h
@@ -589,7 +589,7 @@ struct nvmet_alloc_ctrl_args { const struct nvmet_fabrics_ops *ops; struct device *p2p_client; u32 kato; - u32 result; + __le32 result; u16 error_loc; u16 status; };
diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 0d6c202..d73004b 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c
@@ -42,7 +42,7 @@ #define CY8C95X0_PORTSEL 0x18 /* Port settings, write PORTSEL first */ #define CY8C95X0_INTMASK 0x19 -#define CY8C95X0_PWMSEL 0x1A +#define CY8C95X0_SELPWM 0x1A #define CY8C95X0_INVERT 0x1B #define CY8C95X0_DIRECTION 0x1C /* Drive mode register change state on writing '1' */ @@ -328,14 +328,14 @@ static int cypress_get_pin_mask(struct cy8c95x0_pinctrl *chip, unsigned int pin) static bool cy8c95x0_readable_register(struct device *dev, unsigned int reg) { /* - * Only 12 registers are present per port (see Table 6 in the - * datasheet). + * Only 12 registers are present per port (see Table 6 in the datasheet). */ - if (reg >= CY8C95X0_VIRTUAL && (reg % MUXED_STRIDE) < 12) - return true; + if (reg >= CY8C95X0_VIRTUAL && (reg % MUXED_STRIDE) >= 12) + return false; switch (reg) { case 0x24 ... 0x27: + case 0x31 ... 0x3f: return false; default: return true; @@ -344,8 +344,11 @@ static bool cy8c95x0_readable_register(struct device *dev, unsigned int reg) static bool cy8c95x0_writeable_register(struct device *dev, unsigned int reg) { - if (reg >= CY8C95X0_VIRTUAL) - return true; + /* + * Only 12 registers are present per port (see Table 6 in the datasheet). + */ + if (reg >= CY8C95X0_VIRTUAL && (reg % MUXED_STRIDE) >= 12) + return false; switch (reg) { case CY8C95X0_INPUT_(0) ... CY8C95X0_INPUT_(7): @@ -353,6 +356,7 @@ static bool cy8c95x0_writeable_register(struct device *dev, unsigned int reg) case CY8C95X0_DEVID: return false; case 0x24 ... 0x27: + case 0x31 ... 0x3f: return false; default: return true; @@ -365,8 +369,8 @@ static bool cy8c95x0_volatile_register(struct device *dev, unsigned int reg) case CY8C95X0_INPUT_(0) ... CY8C95X0_INPUT_(7): case CY8C95X0_INTSTATUS_(0) ... CY8C95X0_INTSTATUS_(7): case CY8C95X0_INTMASK: + case CY8C95X0_SELPWM: case CY8C95X0_INVERT: - case CY8C95X0_PWMSEL: case CY8C95X0_DIRECTION: case CY8C95X0_DRV_PU: case CY8C95X0_DRV_PD: @@ -395,7 +399,7 @@ static bool cy8c95x0_muxed_register(unsigned int reg) { switch (reg) { case CY8C95X0_INTMASK: - case CY8C95X0_PWMSEL: + case CY8C95X0_SELPWM: case CY8C95X0_INVERT: case CY8C95X0_DIRECTION: case CY8C95X0_DRV_PU: @@ -466,7 +470,11 @@ static const struct regmap_config cy8c9520_i2c_regmap = { .max_register = 0, /* Updated at runtime */ .num_reg_defaults_raw = 0, /* Updated at runtime */ .use_single_read = true, /* Workaround for regcache bug */ +#if IS_ENABLED(CONFIG_DEBUG_PINCTRL) + .disable_locking = false, +#else .disable_locking = true, +#endif }; static inline int cy8c95x0_regmap_update_bits_base(struct cy8c95x0_pinctrl *chip, @@ -789,7 +797,7 @@ static int cy8c95x0_gpio_get_pincfg(struct cy8c95x0_pinctrl *chip, reg = CY8C95X0_DIRECTION; break; case PIN_CONFIG_MODE_PWM: - reg = CY8C95X0_PWMSEL; + reg = CY8C95X0_SELPWM; break; case PIN_CONFIG_OUTPUT: reg = CY8C95X0_OUTPUT; @@ -868,7 +876,7 @@ static int cy8c95x0_gpio_set_pincfg(struct cy8c95x0_pinctrl *chip, reg = CY8C95X0_DRV_PP_FAST; break; case PIN_CONFIG_MODE_PWM: - reg = CY8C95X0_PWMSEL; + reg = CY8C95X0_SELPWM; break; case PIN_CONFIG_OUTPUT_ENABLE: return cy8c95x0_pinmux_direction(chip, off, !arg); @@ -1153,7 +1161,7 @@ static void cy8c95x0_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file * bitmap_zero(mask, MAX_LINE); __set_bit(pin, mask); - if (cy8c95x0_read_regs_mask(chip, CY8C95X0_PWMSEL, pwm, mask)) { + if (cy8c95x0_read_regs_mask(chip, CY8C95X0_SELPWM, pwm, mask)) { seq_puts(s, "not available"); return; } @@ -1198,7 +1206,7 @@ static int cy8c95x0_set_mode(struct cy8c95x0_pinctrl *chip, unsigned int off, bo u8 port = cypress_get_port(chip, off); u8 bit = cypress_get_pin_mask(chip, off); - return cy8c95x0_regmap_write_bits(chip, CY8C95X0_PWMSEL, port, bit, mode ? bit : 0); + return cy8c95x0_regmap_write_bits(chip, CY8C95X0_SELPWM, port, bit, mode ? bit : 0); } static int cy8c95x0_pinmux_mode(struct cy8c95x0_pinctrl *chip, @@ -1347,7 +1355,7 @@ static int cy8c95x0_irq_setup(struct cy8c95x0_pinctrl *chip, int irq) ret = devm_request_threaded_irq(chip->dev, irq, NULL, cy8c95x0_irq_handler, - IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_HIGH, + IRQF_ONESHOT | IRQF_SHARED, dev_name(chip->dev), chip); if (ret) { dev_err(chip->dev, "failed to request irq %d\n", irq); @@ -1438,15 +1446,15 @@ static int cy8c95x0_probe(struct i2c_client *client) switch (chip->tpin) { case 20: strscpy(chip->name, cy8c95x0_id[0].name); - regmap_range_conf.range_max = CY8C95X0_VIRTUAL + 3 * MUXED_STRIDE; + regmap_range_conf.range_max = CY8C95X0_VIRTUAL + 3 * MUXED_STRIDE - 1; break; case 40: strscpy(chip->name, cy8c95x0_id[1].name); - regmap_range_conf.range_max = CY8C95X0_VIRTUAL + 6 * MUXED_STRIDE; + regmap_range_conf.range_max = CY8C95X0_VIRTUAL + 6 * MUXED_STRIDE - 1; break; case 60: strscpy(chip->name, cy8c95x0_id[2].name); - regmap_range_conf.range_max = CY8C95X0_VIRTUAL + 8 * MUXED_STRIDE; + regmap_range_conf.range_max = CY8C95X0_VIRTUAL + 8 * MUXED_STRIDE - 1; break; default: return -ENODEV;
diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c index 52c32dc..4112a00 100644 --- a/drivers/powercap/powercap_sys.c +++ b/drivers/powercap/powercap_sys.c
@@ -627,8 +627,7 @@ struct powercap_control_type *powercap_register_control_type( dev_set_name(&control_type->dev, "%s", name); result = device_register(&control_type->dev); if (result) { - if (control_type->allocated) - kfree(control_type); + put_device(&control_type->dev); return ERR_PTR(result); } idr_init(&control_type->idr);
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c index 3b99feb..5accab0 100644 --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c
@@ -17,6 +17,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/pwm.h> #include <linux/time.h> #define DEFAULT_SYMBOL_NAMESPACE "PWM_LPSS"
diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h index b5267ab..6079218 100644 --- a/drivers/pwm/pwm-lpss.h +++ b/drivers/pwm/pwm-lpss.h
@@ -10,7 +10,6 @@ #ifndef __PWM_LPSS_H #define __PWM_LPSS_H -#include <linux/pwm.h> #include <linux/types.h> #include <linux/platform_data/x86/pwm-lpss.h>
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index 40f7dba..0274f41 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c
@@ -14,8 +14,9 @@ #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> +#include <linux/regulator/of_regulator.h> -#define AD5398_CURRENT_EN_MASK 0x8000 +#define AD5398_SW_POWER_DOWN BIT(16) struct ad5398_chip_info { struct i2c_client *client; @@ -113,7 +114,7 @@ static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int /* prepare register data */ selector = (selector << chip->current_offset) & chip->current_mask; - data = (unsigned short)selector | (data & AD5398_CURRENT_EN_MASK); + data = (unsigned short)selector | (data & AD5398_SW_POWER_DOWN); /* write the new current value back as well as enable bit */ ret = ad5398_write_reg(client, data); @@ -132,10 +133,10 @@ static int ad5398_is_enabled(struct regulator_dev *rdev) if (ret < 0) return ret; - if (data & AD5398_CURRENT_EN_MASK) - return 1; - else + if (data & AD5398_SW_POWER_DOWN) return 0; + else + return 1; } static int ad5398_enable(struct regulator_dev *rdev) @@ -149,10 +150,10 @@ static int ad5398_enable(struct regulator_dev *rdev) if (ret < 0) return ret; - if (data & AD5398_CURRENT_EN_MASK) + if (!(data & AD5398_SW_POWER_DOWN)) return 0; - data |= AD5398_CURRENT_EN_MASK; + data &= ~AD5398_SW_POWER_DOWN; ret = ad5398_write_reg(client, data); @@ -170,10 +171,10 @@ static int ad5398_disable(struct regulator_dev *rdev) if (ret < 0) return ret; - if (!(data & AD5398_CURRENT_EN_MASK)) + if (data & AD5398_SW_POWER_DOWN) return 0; - data &= ~AD5398_CURRENT_EN_MASK; + data |= AD5398_SW_POWER_DOWN; ret = ad5398_write_reg(client, data); @@ -221,15 +222,20 @@ static int ad5398_probe(struct i2c_client *client) const struct ad5398_current_data_format *df = (struct ad5398_current_data_format *)id->driver_data; - if (!init_data) - return -EINVAL; - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; config.dev = &client->dev; + if (client->dev.of_node) + init_data = of_get_regulator_init_data(&client->dev, + client->dev.of_node, + &ad5398_reg); + if (!init_data) + return -EINVAL; + config.init_data = init_data; + config.of_node = client->dev.of_node; config.driver_data = chip; chip->client = client;
diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c index faa6b79..4519e72 100644 --- a/drivers/regulator/pca9450-regulator.c +++ b/drivers/regulator/pca9450-regulator.c
@@ -98,6 +98,58 @@ static const struct regulator_ops pca9450_ldo_regulator_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, }; +static unsigned int pca9450_ldo5_get_reg_voltage_sel(struct regulator_dev *rdev) +{ + struct pca9450 *pca9450 = rdev_get_drvdata(rdev); + + if (pca9450->sd_vsel_gpio && !gpiod_get_value(pca9450->sd_vsel_gpio)) + return PCA9450_REG_LDO5CTRL_L; + + return rdev->desc->vsel_reg; +} + +static int pca9450_ldo5_get_voltage_sel_regmap(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, pca9450_ldo5_get_reg_voltage_sel(rdev), &val); + if (ret != 0) + return ret; + + val &= rdev->desc->vsel_mask; + val >>= ffs(rdev->desc->vsel_mask) - 1; + + return val; +} + +static int pca9450_ldo5_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned int sel) +{ + int ret; + + sel <<= ffs(rdev->desc->vsel_mask) - 1; + + ret = regmap_update_bits(rdev->regmap, pca9450_ldo5_get_reg_voltage_sel(rdev), + rdev->desc->vsel_mask, sel); + if (ret) + return ret; + + if (rdev->desc->apply_bit) + ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg, + rdev->desc->apply_bit, + rdev->desc->apply_bit); + return ret; +} + +static const struct regulator_ops pca9450_ldo5_regulator_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = pca9450_ldo5_set_voltage_sel_regmap, + .get_voltage_sel = pca9450_ldo5_get_voltage_sel_regmap, +}; + /* * BUCK1/2/3 * 0.60 to 2.1875V (12.5mV step) @@ -453,14 +505,14 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = { .of_match = of_match_ptr("LDO5"), .regulators_node = of_match_ptr("regulators"), .id = PCA9450_LDO5, - .ops = &pca9450_ldo_regulator_ops, + .ops = &pca9450_ldo5_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = PCA9450_LDO5_VOLTAGE_NUM, .linear_ranges = pca9450_ldo5_volts, .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts), .vsel_reg = PCA9450_REG_LDO5CTRL_H, .vsel_mask = LDO5HOUT_MASK, - .enable_reg = PCA9450_REG_LDO5CTRL_H, + .enable_reg = PCA9450_REG_LDO5CTRL_L, .enable_mask = LDO5H_EN_MASK, .owner = THIS_MODULE, }, @@ -667,14 +719,14 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = { .of_match = of_match_ptr("LDO5"), .regulators_node = of_match_ptr("regulators"), .id = PCA9450_LDO5, - .ops = &pca9450_ldo_regulator_ops, + .ops = &pca9450_ldo5_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = PCA9450_LDO5_VOLTAGE_NUM, .linear_ranges = pca9450_ldo5_volts, .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts), .vsel_reg = PCA9450_REG_LDO5CTRL_H, .vsel_mask = LDO5HOUT_MASK, - .enable_reg = PCA9450_REG_LDO5CTRL_H, + .enable_reg = PCA9450_REG_LDO5CTRL_L, .enable_mask = LDO5H_EN_MASK, .owner = THIS_MODULE, }, @@ -857,14 +909,14 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = { .of_match = of_match_ptr("LDO5"), .regulators_node = of_match_ptr("regulators"), .id = PCA9450_LDO5, - .ops = &pca9450_ldo_regulator_ops, + .ops = &pca9450_ldo5_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = PCA9450_LDO5_VOLTAGE_NUM, .linear_ranges = pca9450_ldo5_volts, .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts), .vsel_reg = PCA9450_REG_LDO5CTRL_H, .vsel_mask = LDO5HOUT_MASK, - .enable_reg = PCA9450_REG_LDO5CTRL_H, + .enable_reg = PCA9450_REG_LDO5CTRL_L, .enable_mask = LDO5H_EN_MASK, .owner = THIS_MODULE, }, @@ -915,6 +967,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) of_device_get_match_data(&i2c->dev); const struct pca9450_regulator_desc *regulator_desc; struct regulator_config config = { }; + struct regulator_dev *ldo5; struct pca9450 *pca9450; unsigned int device_id, i; unsigned int reset_ctrl; @@ -980,11 +1033,15 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) config.regmap = pca9450->regmap; config.dev = pca9450->dev; + config.driver_data = pca9450; rdev = devm_regulator_register(pca9450->dev, desc, &config); if (IS_ERR(rdev)) return dev_err_probe(pca9450->dev, PTR_ERR(rdev), "Failed to register regulator(%s)\n", desc->name); + + if (!strcmp(desc->name, "ldo5")) + ldo5 = rdev; } if (pca9450->irq) { @@ -1032,15 +1089,28 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) } /* - * The driver uses the LDO5CTRL_H register to control the LDO5 regulator. - * This is only valid if the SD_VSEL input of the PMIC is high. Let's - * check if the pin is available as GPIO and set it to high. + * For LDO5 we need to be able to check the status of the SD_VSEL input in + * order to know which control register is used. Most boards connect SD_VSEL + * to the VSELECT signal, so we can use the GPIO that is internally routed + * to this signal (if SION bit is set in IOMUX). */ - pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH); + pca9450->sd_vsel_gpio = gpiod_get_optional(&ldo5->dev, "sd-vsel", GPIOD_IN); + if (IS_ERR(pca9450->sd_vsel_gpio)) { + dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n"); + return ret; + } - if (IS_ERR(pca9450->sd_vsel_gpio)) - return dev_err_probe(&i2c->dev, PTR_ERR(pca9450->sd_vsel_gpio), - "Failed to get SD_VSEL GPIO\n"); + /* + * For LDO5 we need to be able to check the status of the SD_VSEL input in + * order to know which control register is used. Most boards connect SD_VSEL + * to the VSELECT signal, so we can use the GPIO that is internally routed + * to this signal (if SION bit is set in IOMUX). + */ + pca9450->sd_vsel_gpio = gpiod_get_optional(&ldo5->dev, "sd-vsel", GPIOD_IN); + if (IS_ERR(pca9450->sd_vsel_gpio)) { + dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n"); + return ret; + } dev_info(&i2c->dev, "%s probed.\n", type == PCA9450_TYPE_PCA9450A ? "pca9450a" :
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index 6d2e135..49648cf 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig
@@ -334,6 +334,7 @@ config ARCH_R9A08G045 bool "ARM64 Platform support for RZ/G3S" select ARCH_RZG2L + select SYSC_R9A08G045 help This enables support for the Renesas RZ/G3S SoC variants. @@ -347,12 +348,14 @@ config ARCH_R9A09G047 bool "ARM64 Platform support for RZ/G3E" + select SYS_R9A09G047 help This enables support for the Renesas RZ/G3E SoC variants. config ARCH_R9A09G057 bool "ARM64 Platform support for RZ/V2H(P)" select RENESAS_RZV2H_ICU + select SYS_R9A09G057 help This enables support for the Renesas RZ/V2H(P) SoC variants. @@ -383,4 +386,19 @@ config RST_RCAR bool "Reset Controller support for R-Car" if COMPILE_TEST +config SYSC_RZ + bool "System controller for RZ SoCs" if COMPILE_TEST + +config SYSC_R9A08G045 + bool "Renesas RZ/G3S System controller support" if COMPILE_TEST + select SYSC_RZ + +config SYS_R9A09G047 + bool "Renesas RZ/G3E System controller support" if COMPILE_TEST + select SYSC_RZ + +config SYS_R9A09G057 + bool "Renesas RZ/V2H System controller support" if COMPILE_TEST + select SYSC_RZ + endif # SOC_RENESAS
diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile index 734f8f8..81d4c57 100644 --- a/drivers/soc/renesas/Makefile +++ b/drivers/soc/renesas/Makefile
@@ -6,7 +6,11 @@ ifdef CONFIG_SMP obj-$(CONFIG_ARCH_R9A06G032) += r9a06g032-smp.o endif +obj-$(CONFIG_SYSC_R9A08G045) += r9a08g045-sysc.o +obj-$(CONFIG_SYS_R9A09G047) += r9a09g047-sys.o +obj-$(CONFIG_SYS_R9A09G057) += r9a09g057-sys.o # Family obj-$(CONFIG_PWC_RZV2M) += pwc-rzv2m.o obj-$(CONFIG_RST_RCAR) += rcar-rst.o +obj-$(CONFIG_SYSC_RZ) += rz-sysc.o
diff --git a/drivers/soc/renesas/r9a08g045-sysc.c b/drivers/soc/renesas/r9a08g045-sysc.c new file mode 100644 index 0000000..f4db143 --- /dev/null +++ b/drivers/soc/renesas/r9a08g045-sysc.c
@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RZ/G3S System controller driver + * + * Copyright (C) 2024 Renesas Electronics Corp. + */ + +#include <linux/bits.h> +#include <linux/init.h> + +#include "rz-sysc.h" + +static const struct rz_sysc_soc_id_init_data rzg3s_sysc_soc_id_init_data __initconst = { + .family = "RZ/G3S", + .id = 0x85e0447, + .devid_offset = 0xa04, + .revision_mask = GENMASK(31, 28), + .specific_id_mask = GENMASK(27, 0), +}; + +const struct rz_sysc_init_data rzg3s_sysc_init_data __initconst = { + .soc_id_init_data = &rzg3s_sysc_soc_id_init_data, +};
diff --git a/drivers/soc/renesas/r9a09g047-sys.c b/drivers/soc/renesas/r9a09g047-sys.c new file mode 100644 index 0000000..cd2eb77 --- /dev/null +++ b/drivers/soc/renesas/r9a09g047-sys.c
@@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RZ/G3E System controller (SYS) driver + * + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/device.h> +#include <linux/init.h> +#include <linux/io.h> + +#include "rz-sysc.h" + +/* Register Offsets */ +#define SYS_LSI_MODE 0x300 +/* + * BOOTPLLCA[1:0] + * [0,0] => 1.1GHZ + * [0,1] => 1.5GHZ + * [1,0] => 1.6GHZ + * [1,1] => 1.7GHZ + */ +#define SYS_LSI_MODE_STAT_BOOTPLLCA55 GENMASK(12, 11) +#define SYS_LSI_MODE_CA55_1_7GHZ 0x3 + +#define SYS_LSI_PRR 0x308 +#define SYS_LSI_PRR_CA55_DIS BIT(8) +#define SYS_LSI_PRR_NPU_DIS BIT(1) + +static void rzg3e_sys_print_id(struct device *dev, + void __iomem *sysc_base, + struct soc_device_attribute *soc_dev_attr) +{ + bool is_quad_core, npu_enabled; + u32 prr_val, mode_val; + + prr_val = readl(sysc_base + SYS_LSI_PRR); + mode_val = readl(sysc_base + SYS_LSI_MODE); + + /* Check CPU and NPU configuration */ + is_quad_core = !(prr_val & SYS_LSI_PRR_CA55_DIS); + npu_enabled = !(prr_val & SYS_LSI_PRR_NPU_DIS); + + dev_info(dev, "Detected Renesas %s Core %s %s Rev %s%s\n", + is_quad_core ? "Quad" : "Dual", soc_dev_attr->family, + soc_dev_attr->soc_id, soc_dev_attr->revision, + npu_enabled ? " with Ethos-U55" : ""); + + /* Check CA55 PLL configuration */ + if (FIELD_GET(SYS_LSI_MODE_STAT_BOOTPLLCA55, mode_val) != SYS_LSI_MODE_CA55_1_7GHZ) + dev_warn(dev, "CA55 PLL is not set to 1.7GHz\n"); +} + +static const struct rz_sysc_soc_id_init_data rzg3e_sys_soc_id_init_data __initconst = { + .family = "RZ/G3E", + .id = 0x8679447, + .devid_offset = 0x304, + .revision_mask = GENMASK(31, 28), + .specific_id_mask = GENMASK(27, 0), + .print_id = rzg3e_sys_print_id, +}; + +const struct rz_sysc_init_data rzg3e_sys_init_data = { + .soc_id_init_data = &rzg3e_sys_soc_id_init_data, +};
diff --git a/drivers/soc/renesas/r9a09g057-sys.c b/drivers/soc/renesas/r9a09g057-sys.c new file mode 100644 index 0000000..4c21cc2 --- /dev/null +++ b/drivers/soc/renesas/r9a09g057-sys.c
@@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RZ/V2H System controller (SYS) driver + * + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/device.h> +#include <linux/init.h> +#include <linux/io.h> + +#include "rz-sysc.h" + +/* Register Offsets */ +#define SYS_LSI_MODE 0x300 +/* + * BOOTPLLCA[1:0] + * [0,0] => 1.1GHZ + * [0,1] => 1.5GHZ + * [1,0] => 1.6GHZ + * [1,1] => 1.7GHZ + */ +#define SYS_LSI_MODE_STAT_BOOTPLLCA55 GENMASK(12, 11) +#define SYS_LSI_MODE_CA55_1_7GHZ 0x3 + +#define SYS_LSI_PRR 0x308 +#define SYS_LSI_PRR_GPU_DIS BIT(0) +#define SYS_LSI_PRR_ISP_DIS BIT(4) + +static void rzv2h_sys_print_id(struct device *dev, + void __iomem *sysc_base, + struct soc_device_attribute *soc_dev_attr) +{ + bool gpu_enabled, isp_enabled; + u32 prr_val, mode_val; + + prr_val = readl(sysc_base + SYS_LSI_PRR); + mode_val = readl(sysc_base + SYS_LSI_MODE); + + /* Check GPU and ISP configuration */ + gpu_enabled = !(prr_val & SYS_LSI_PRR_GPU_DIS); + isp_enabled = !(prr_val & SYS_LSI_PRR_ISP_DIS); + + dev_info(dev, "Detected Renesas %s %s Rev %s%s%s\n", + soc_dev_attr->family, soc_dev_attr->soc_id, soc_dev_attr->revision, + gpu_enabled ? " with GE3D (Mali-G31)" : "", + isp_enabled ? " with ISP (Mali-C55)" : ""); + + /* Check CA55 PLL configuration */ + if (FIELD_GET(SYS_LSI_MODE_STAT_BOOTPLLCA55, mode_val) != SYS_LSI_MODE_CA55_1_7GHZ) + dev_warn(dev, "CA55 PLL is not set to 1.7GHz\n"); +} + +static const struct rz_sysc_soc_id_init_data rzv2h_sys_soc_id_init_data __initconst = { + .family = "RZ/V2H", + .id = 0x847a447, + .devid_offset = 0x304, + .revision_mask = GENMASK(31, 28), + .specific_id_mask = GENMASK(27, 0), + .print_id = rzv2h_sys_print_id, +}; + +const struct rz_sysc_init_data rzv2h_sys_init_data = { + .soc_id_init_data = &rzv2h_sys_soc_id_init_data, +};
diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c index 172d59e6..df2b3841 100644 --- a/drivers/soc/renesas/renesas-soc.c +++ b/drivers/soc/renesas/renesas-soc.c
@@ -71,14 +71,6 @@ static const struct renesas_family fam_rzg2ul __initconst __maybe_unused = { .name = "RZ/G2UL", }; -static const struct renesas_family fam_rzg3s __initconst __maybe_unused = { - .name = "RZ/G3S", -}; - -static const struct renesas_family fam_rzv2h __initconst __maybe_unused = { - .name = "RZ/V2H", -}; - static const struct renesas_family fam_rzv2l __initconst __maybe_unused = { .name = "RZ/V2L", }; @@ -176,16 +168,6 @@ static const struct renesas_soc soc_rz_g2ul __initconst __maybe_unused = { .id = 0x8450447, }; -static const struct renesas_soc soc_rz_g3s __initconst __maybe_unused = { - .family = &fam_rzg3s, - .id = 0x85e0447, -}; - -static const struct renesas_soc soc_rz_v2h __initconst __maybe_unused = { - .family = &fam_rzv2h, - .id = 0x847a447, -}; - static const struct renesas_soc soc_rz_v2l __initconst __maybe_unused = { .family = &fam_rzv2l, .id = 0x8447447, @@ -289,7 +271,6 @@ static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = { .id = 0x37, }; - static const struct of_device_id renesas_socs[] __initconst __maybe_unused = { #ifdef CONFIG_ARCH_R7S72100 { .compatible = "renesas,r7s72100", .data = &soc_rz_a1h }, @@ -410,15 +391,9 @@ static const struct of_device_id renesas_socs[] __initconst __maybe_unused = { #ifdef CONFIG_ARCH_R9A07G054 { .compatible = "renesas,r9a07g054", .data = &soc_rz_v2l }, #endif -#ifdef CONFIG_ARCH_R9A08G045 - { .compatible = "renesas,r9a08g045", .data = &soc_rz_g3s }, -#endif #ifdef CONFIG_ARCH_R9A09G011 { .compatible = "renesas,r9a09g011", .data = &soc_rz_v2m }, #endif -#ifdef CONFIG_ARCH_R9A09G057 - { .compatible = "renesas,r9a09g057", .data = &soc_rz_v2h }, -#endif #ifdef CONFIG_ARCH_SH73A0 { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 }, #endif @@ -444,11 +419,6 @@ static const struct renesas_id id_rzg2l __initconst = { .mask = 0xfffffff, }; -static const struct renesas_id id_rzv2h __initconst = { - .offset = 0x304, - .mask = 0xfffffff, -}; - static const struct renesas_id id_rzv2m __initconst = { .offset = 0x104, .mask = 0xff, @@ -466,7 +436,6 @@ static const struct of_device_id renesas_ids[] __initconst = { { .compatible = "renesas,r9a07g054-sysc", .data = &id_rzg2l }, { .compatible = "renesas,r9a08g045-sysc", .data = &id_rzg2l }, { .compatible = "renesas,r9a09g011-sys", .data = &id_rzv2m }, - { .compatible = "renesas,r9a09g057-sys", .data = &id_rzv2h }, { .compatible = "renesas,prr", .data = &id_prr }, { /* sentinel */ } }; @@ -531,7 +500,7 @@ static int __init renesas_soc_init(void) eslo = product & 0xf; soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u", eshi, eslo); - } else if (id == &id_rzg2l || id == &id_rzv2h) { + } else if (id == &id_rzg2l) { eshi = ((product >> 28) & 0x0f); soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%u", eshi);
diff --git a/drivers/soc/renesas/rz-sysc.c b/drivers/soc/renesas/rz-sysc.c new file mode 100644 index 0000000..1c98da3 --- /dev/null +++ b/drivers/soc/renesas/rz-sysc.c
@@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RZ System controller driver + * + * Copyright (C) 2024 Renesas Electronics Corp. + */ + +#include <linux/io.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/sys_soc.h> + +#include "rz-sysc.h" + +#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) + +/** + * struct rz_sysc - RZ SYSC private data structure + * @base: SYSC base address + * @dev: SYSC device pointer + */ +struct rz_sysc { + void __iomem *base; + struct device *dev; +}; + +static int rz_sysc_soc_init(struct rz_sysc *sysc, const struct of_device_id *match) +{ + const struct rz_sysc_init_data *sysc_data = match->data; + const struct rz_sysc_soc_id_init_data *soc_data = sysc_data->soc_id_init_data; + struct soc_device_attribute *soc_dev_attr; + const char *soc_id_start, *soc_id_end; + u32 val, revision, specific_id; + struct soc_device *soc_dev; + char soc_id[32] = {0}; + size_t size; + + soc_id_start = strchr(match->compatible, ',') + 1; + soc_id_end = strchr(match->compatible, '-'); + size = soc_id_end - soc_id_start + 1; + if (size > 32) + size = sizeof(soc_id); + strscpy(soc_id, soc_id_start, size); + + soc_dev_attr = devm_kzalloc(sysc->dev, sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return -ENOMEM; + + soc_dev_attr->family = devm_kstrdup(sysc->dev, soc_data->family, GFP_KERNEL); + if (!soc_dev_attr->family) + return -ENOMEM; + + soc_dev_attr->soc_id = devm_kstrdup(sysc->dev, soc_id, GFP_KERNEL); + if (!soc_dev_attr->soc_id) + return -ENOMEM; + + val = readl(sysc->base + soc_data->devid_offset); + revision = field_get(soc_data->revision_mask, val); + specific_id = field_get(soc_data->specific_id_mask, val); + soc_dev_attr->revision = devm_kasprintf(sysc->dev, GFP_KERNEL, "%u", revision); + if (!soc_dev_attr->revision) + return -ENOMEM; + + if (soc_data->id && specific_id != soc_data->id) { + dev_warn(sysc->dev, "SoC mismatch (product = 0x%x)\n", specific_id); + return -ENODEV; + } + + /* Try to call SoC-specific device identification */ + if (soc_data->print_id) { + soc_data->print_id(sysc->dev, sysc->base, soc_dev_attr); + } else { + dev_info(sysc->dev, "Detected Renesas %s %s Rev %s\n", + soc_dev_attr->family, soc_dev_attr->soc_id, soc_dev_attr->revision); + } + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) + return PTR_ERR(soc_dev); + + return 0; +} + +static const struct of_device_id rz_sysc_match[] = { +#ifdef CONFIG_SYSC_R9A08G045 + { .compatible = "renesas,r9a08g045-sysc", .data = &rzg3s_sysc_init_data }, +#endif +#ifdef CONFIG_SYS_R9A09G047 + { .compatible = "renesas,r9a09g047-sys", .data = &rzg3e_sys_init_data }, +#endif +#ifdef CONFIG_SYS_R9A09G057 + { .compatible = "renesas,r9a09g057-sys", .data = &rzv2h_sys_init_data }, +#endif + { } +}; +MODULE_DEVICE_TABLE(of, rz_sysc_match); + +static int rz_sysc_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + struct device *dev = &pdev->dev; + struct rz_sysc *sysc; + + match = of_match_node(rz_sysc_match, dev->of_node); + if (!match) + return -ENODEV; + + sysc = devm_kzalloc(dev, sizeof(*sysc), GFP_KERNEL); + if (!sysc) + return -ENOMEM; + + sysc->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(sysc->base)) + return PTR_ERR(sysc->base); + + sysc->dev = dev; + return rz_sysc_soc_init(sysc, match); +} + +static struct platform_driver rz_sysc_driver = { + .driver = { + .name = "renesas-rz-sysc", + .of_match_table = rz_sysc_match + }, + .probe = rz_sysc_probe +}; + +static int __init rz_sysc_init(void) +{ + return platform_driver_register(&rz_sysc_driver); +} +subsys_initcall(rz_sysc_init); + +MODULE_DESCRIPTION("Renesas RZ System Controller Driver"); +MODULE_AUTHOR("Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>"); +MODULE_LICENSE("GPL");
diff --git a/drivers/soc/renesas/rz-sysc.h b/drivers/soc/renesas/rz-sysc.h new file mode 100644 index 0000000..aa83948 --- /dev/null +++ b/drivers/soc/renesas/rz-sysc.h
@@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Renesas RZ System Controller + * + * Copyright (C) 2024 Renesas Electronics Corp. + */ + +#ifndef __SOC_RENESAS_RZ_SYSC_H__ +#define __SOC_RENESAS_RZ_SYSC_H__ + +#include <linux/device.h> +#include <linux/sys_soc.h> +#include <linux/types.h> + +/** + * struct rz_syc_soc_id_init_data - RZ SYSC SoC identification initialization data + * @family: RZ SoC family + * @id: RZ SoC expected ID + * @devid_offset: SYSC SoC ID register offset + * @revision_mask: SYSC SoC ID revision mask + * @specific_id_mask: SYSC SoC ID specific ID mask + * @print_id: print SoC-specific extended device identification + */ +struct rz_sysc_soc_id_init_data { + const char * const family; + u32 id; + u32 devid_offset; + u32 revision_mask; + u32 specific_id_mask; + void (*print_id)(struct device *dev, void __iomem *sysc_base, + struct soc_device_attribute *soc_dev_attr); +}; + +/** + * struct rz_sysc_init_data - RZ SYSC initialization data + * @soc_id_init_data: RZ SYSC SoC ID initialization data + */ +struct rz_sysc_init_data { + const struct rz_sysc_soc_id_init_data *soc_id_init_data; +}; + +extern const struct rz_sysc_init_data rzg3e_sys_init_data; +extern const struct rz_sysc_init_data rzg3s_sysc_init_data; +extern const struct rz_sysc_init_data rzv2h_sys_init_data; + +#endif /* __SOC_RENESAS_RZ_SYSC_H__ */
diff --git a/drivers/spi/spi-realtek-rtl-snand.c b/drivers/spi/spi-realtek-rtl-snand.c index cd04840..741cf2a 100644 --- a/drivers/spi/spi-realtek-rtl-snand.c +++ b/drivers/spi/spi-realtek-rtl-snand.c
@@ -364,7 +364,6 @@ static int rtl_snand_probe(struct platform_device *pdev) .reg_bits = 32, .val_bits = 32, .reg_stride = 4, - .cache_type = REGCACHE_NONE, }; int irq, ret;
diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c index d800d79..1b0c8ea 100644 --- a/drivers/spi/spi-zynqmp-gqspi.c +++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -82,7 +82,6 @@ #define GQSPI_GENFIFO_RX 0x00020000 #define GQSPI_GENFIFO_STRIPE 0x00040000 #define GQSPI_GENFIFO_POLL 0x00080000 -#define GQSPI_GENFIFO_EXP_START 0x00000100 #define GQSPI_FIFO_CTRL_RST_RX_FIFO_MASK 0x00000004 #define GQSPI_FIFO_CTRL_RST_TX_FIFO_MASK 0x00000002 #define GQSPI_FIFO_CTRL_RST_GEN_FIFO_MASK 0x00000001 @@ -580,6 +579,8 @@ static int zynqmp_qspi_config_op(struct zynqmp_qspi *xqspi, zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg); zynqmp_qspi_set_tapdelay(xqspi, baud_rate_val); } + + dev_dbg(xqspi->dev, "config speed %u\n", req_speed_hz); return 0; } @@ -670,69 +671,77 @@ static void zynqmp_qspi_readrxfifo(struct zynqmp_qspi *xqspi, u32 size) static void zynqmp_qspi_fillgenfifo(struct zynqmp_qspi *xqspi, u8 nbits, u32 genfifoentry) { - u32 transfer_len = 0; + u32 transfer_len, tempcount, exponent; + u8 imm_data; - if (xqspi->txbuf) { - genfifoentry &= ~GQSPI_GENFIFO_RX; - genfifoentry |= GQSPI_GENFIFO_DATA_XFER; - genfifoentry |= GQSPI_GENFIFO_TX; - transfer_len = xqspi->bytes_to_transfer; - } else if (xqspi->rxbuf) { - genfifoentry &= ~GQSPI_GENFIFO_TX; - genfifoentry |= GQSPI_GENFIFO_DATA_XFER; + genfifoentry |= GQSPI_GENFIFO_DATA_XFER; + if (xqspi->rxbuf) { genfifoentry |= GQSPI_GENFIFO_RX; if (xqspi->mode == GQSPI_MODE_DMA) transfer_len = xqspi->dma_rx_bytes; else transfer_len = xqspi->bytes_to_receive; } else { - /* Sending dummy circles here */ - genfifoentry &= ~(GQSPI_GENFIFO_TX | GQSPI_GENFIFO_RX); - genfifoentry |= GQSPI_GENFIFO_DATA_XFER; transfer_len = xqspi->bytes_to_transfer; } + + if (xqspi->txbuf) + genfifoentry |= GQSPI_GENFIFO_TX; + genfifoentry |= zynqmp_qspi_selectspimode(xqspi, nbits); xqspi->genfifoentry = genfifoentry; + dev_dbg(xqspi->dev, "genfifo %05x transfer_len %u\n", + genfifoentry, transfer_len); - if ((transfer_len) < GQSPI_GENFIFO_IMM_DATA_MASK) { - genfifoentry &= ~GQSPI_GENFIFO_IMM_DATA_MASK; - genfifoentry |= transfer_len; - zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, genfifoentry); - } else { - int tempcount = transfer_len; - u32 exponent = 8; /* 2^8 = 256 */ - u8 imm_data = tempcount & 0xFF; - - tempcount &= ~(tempcount & 0xFF); - /* Immediate entry */ - if (tempcount != 0) { - /* Exponent entries */ - genfifoentry |= GQSPI_GENFIFO_EXP; - while (tempcount != 0) { - if (tempcount & GQSPI_GENFIFO_EXP_START) { - genfifoentry &= - ~GQSPI_GENFIFO_IMM_DATA_MASK; - genfifoentry |= exponent; - zynqmp_gqspi_write(xqspi, - GQSPI_GEN_FIFO_OFST, - genfifoentry); - } - tempcount = tempcount >> 1; - exponent++; - } - } - if (imm_data != 0) { - genfifoentry &= ~GQSPI_GENFIFO_EXP; - genfifoentry &= ~GQSPI_GENFIFO_IMM_DATA_MASK; - genfifoentry |= (u8)(imm_data & 0xFF); + /* Exponent entries */ + imm_data = transfer_len; + tempcount = transfer_len >> 8; + exponent = 8; + genfifoentry |= GQSPI_GENFIFO_EXP; + while (tempcount) { + if (tempcount & 1) zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, - genfifoentry); - } + genfifoentry | exponent); + tempcount >>= 1; + exponent++; } - if (xqspi->mode == GQSPI_MODE_IO && xqspi->rxbuf) { - /* Dummy generic FIFO entry */ - zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, 0x0); - } + + /* Immediate entry */ + genfifoentry &= ~GQSPI_GENFIFO_EXP; + if (imm_data) + zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, + genfifoentry | imm_data); + + /* Dummy generic FIFO entry */ + if (xqspi->mode == GQSPI_MODE_IO && xqspi->rxbuf) + zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, 0); +} + +/** + * zynqmp_qspi_disable_dma() - Disable DMA mode + * @xqspi: GQSPI instance + */ +static void zynqmp_qspi_disable_dma(struct zynqmp_qspi *xqspi) +{ + u32 config_reg = zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST); + + config_reg &= ~GQSPI_CFG_MODE_EN_MASK; + zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg); + xqspi->mode = GQSPI_MODE_IO; +} + +/** + * zynqmp_qspi_enable_dma() - Enable DMA mode + * @xqspi: GQSPI instance + */ +static void zynqmp_qspi_enable_dma(struct zynqmp_qspi *xqspi) +{ + u32 config_reg = zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST); + + config_reg &= ~GQSPI_CFG_MODE_EN_MASK; + config_reg |= GQSPI_CFG_MODE_EN_DMA_MASK; + zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg); + xqspi->mode = GQSPI_MODE_DMA; } /** @@ -744,7 +753,7 @@ static void zynqmp_qspi_fillgenfifo(struct zynqmp_qspi *xqspi, u8 nbits, */ static void zynqmp_process_dma_irq(struct zynqmp_qspi *xqspi) { - u32 config_reg, genfifoentry; + u32 genfifoentry; dma_unmap_single(xqspi->dev, xqspi->dma_addr, xqspi->dma_rx_bytes, DMA_FROM_DEVICE); @@ -758,9 +767,7 @@ static void zynqmp_process_dma_irq(struct zynqmp_qspi *xqspi) if (xqspi->bytes_to_receive > 0) { /* Switch to IO mode,for remaining bytes to receive */ - config_reg = zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST); - config_reg &= ~GQSPI_CFG_MODE_EN_MASK; - zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg); + zynqmp_qspi_disable_dma(xqspi); /* Initiate the transfer of remaining bytes */ genfifoentry = xqspi->genfifoentry; @@ -799,7 +806,6 @@ static void zynqmp_process_dma_irq(struct zynqmp_qspi *xqspi) static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id) { struct zynqmp_qspi *xqspi = (struct zynqmp_qspi *)dev_id; - irqreturn_t ret = IRQ_NONE; u32 status, mask, dma_status = 0; status = zynqmp_gqspi_read(xqspi, GQSPI_ISR_OFST); @@ -814,27 +820,24 @@ static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id) dma_status); } - if (mask & GQSPI_ISR_TXNOT_FULL_MASK) { - zynqmp_qspi_filltxfifo(xqspi, GQSPI_TX_FIFO_FILL); - ret = IRQ_HANDLED; - } + if (!mask && !dma_status) + return IRQ_NONE; - if (dma_status & GQSPI_QSPIDMA_DST_I_STS_DONE_MASK) { + if (mask & GQSPI_ISR_TXNOT_FULL_MASK) + zynqmp_qspi_filltxfifo(xqspi, GQSPI_TX_FIFO_FILL); + + if (dma_status & GQSPI_QSPIDMA_DST_I_STS_DONE_MASK) zynqmp_process_dma_irq(xqspi); - ret = IRQ_HANDLED; - } else if (!(mask & GQSPI_IER_RXEMPTY_MASK) && - (mask & GQSPI_IER_GENFIFOEMPTY_MASK)) { + else if (!(mask & GQSPI_IER_RXEMPTY_MASK) && + (mask & GQSPI_IER_GENFIFOEMPTY_MASK)) zynqmp_qspi_readrxfifo(xqspi, GQSPI_RX_FIFO_FILL); - ret = IRQ_HANDLED; - } if (xqspi->bytes_to_receive == 0 && xqspi->bytes_to_transfer == 0 && ((status & GQSPI_IRQ_MASK) == GQSPI_IRQ_MASK)) { zynqmp_gqspi_write(xqspi, GQSPI_IDR_OFST, GQSPI_ISR_IDR_MASK); complete(&xqspi->data_completion); - ret = IRQ_HANDLED; } - return ret; + return IRQ_HANDLED; } /** @@ -845,17 +848,14 @@ static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id) */ static int zynqmp_qspi_setuprxdma(struct zynqmp_qspi *xqspi) { - u32 rx_bytes, rx_rem, config_reg; + u32 rx_bytes, rx_rem; dma_addr_t addr; u64 dma_align = (u64)(uintptr_t)xqspi->rxbuf; if (xqspi->bytes_to_receive < 8 || ((dma_align & GQSPI_DMA_UNALIGN) != 0x0)) { /* Setting to IO mode */ - config_reg = zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST); - config_reg &= ~GQSPI_CFG_MODE_EN_MASK; - zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg); - xqspi->mode = GQSPI_MODE_IO; + zynqmp_qspi_disable_dma(xqspi); xqspi->dma_rx_bytes = 0; return 0; } @@ -878,14 +878,7 @@ static int zynqmp_qspi_setuprxdma(struct zynqmp_qspi *xqspi) zynqmp_gqspi_write(xqspi, GQSPI_QSPIDMA_DST_ADDR_MSB_OFST, ((u32)addr) & 0xfff); - /* Enabling the DMA mode */ - config_reg = zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST); - config_reg &= ~GQSPI_CFG_MODE_EN_MASK; - config_reg |= GQSPI_CFG_MODE_EN_DMA_MASK; - zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, config_reg); - - /* Switch to DMA mode */ - xqspi->mode = GQSPI_MODE_DMA; + zynqmp_qspi_enable_dma(xqspi); /* Write the number of bytes to transfer */ zynqmp_gqspi_write(xqspi, GQSPI_QSPIDMA_DST_SIZE_OFST, rx_bytes); @@ -905,18 +898,10 @@ static int zynqmp_qspi_setuprxdma(struct zynqmp_qspi *xqspi) static void zynqmp_qspi_write_op(struct zynqmp_qspi *xqspi, u8 tx_nbits, u32 genfifoentry) { - u32 config_reg; - zynqmp_qspi_fillgenfifo(xqspi, tx_nbits, genfifoentry); zynqmp_qspi_filltxfifo(xqspi, GQSPI_TXD_DEPTH); - if (xqspi->mode == GQSPI_MODE_DMA) { - config_reg = zynqmp_gqspi_read(xqspi, - GQSPI_CONFIG_OFST); - config_reg &= ~GQSPI_CFG_MODE_EN_MASK; - zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, - config_reg); - xqspi->mode = GQSPI_MODE_IO; - } + if (xqspi->mode == GQSPI_MODE_DMA) + zynqmp_qspi_disable_dma(xqspi); } /** @@ -1059,8 +1044,8 @@ static unsigned long zynqmp_qspi_timeout(struct zynqmp_qspi *xqspi, u8 bits, static int zynqmp_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) { - struct zynqmp_qspi *xqspi = spi_controller_get_devdata - (mem->spi->controller); + struct zynqmp_qspi *xqspi = + spi_controller_get_devdata(mem->spi->controller); unsigned long timeout; int err = 0, i; u32 genfifoentry = 0;
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h index 274a276..1ed7b0d 100644 --- a/include/linux/mmc/slot-gpio.h +++ b/include/linux/mmc/slot-gpio.h
@@ -22,7 +22,6 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id, unsigned int idx, unsigned int debounce); int mmc_gpiod_set_cd_config(struct mmc_host *host, unsigned long config); -void mmc_gpio_set_cd_isr(struct mmc_host *host, irq_handler_t isr); int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on); void mmc_gpiod_request_cd_irq(struct mmc_host *host); bool mmc_can_gpio_cd(struct mmc_host *host);
diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c index 5d0928f..f7d328f 100644 --- a/io_uring/io-wq.c +++ b/io_uring/io-wq.c
@@ -30,7 +30,6 @@ enum { IO_WORKER_F_UP = 0, /* up and active */ IO_WORKER_F_RUNNING = 1, /* account as running */ IO_WORKER_F_FREE = 2, /* worker on free list */ - IO_WORKER_F_BOUND = 3, /* is doing bounded work */ }; enum { @@ -46,12 +45,12 @@ enum { */ struct io_worker { refcount_t ref; - int create_index; unsigned long flags; struct hlist_nulls_node nulls_node; struct list_head all_list; struct task_struct *task; struct io_wq *wq; + struct io_wq_acct *acct; struct io_wq_work *cur_work; raw_spinlock_t lock; @@ -77,10 +76,27 @@ struct io_worker { #define IO_WQ_NR_HASH_BUCKETS (1u << IO_WQ_HASH_ORDER) struct io_wq_acct { + /** + * Protects access to the worker lists. + */ + raw_spinlock_t workers_lock; + unsigned nr_workers; unsigned max_workers; - int index; atomic_t nr_running; + + /** + * The list of free workers. Protected by #workers_lock + * (write) and RCU (read). + */ + struct hlist_nulls_head free_list; + + /** + * The list of all workers. Protected by #workers_lock + * (write) and RCU (read). + */ + struct list_head all_list; + raw_spinlock_t lock; struct io_wq_work_list work_list; unsigned long flags; @@ -112,12 +128,6 @@ struct io_wq { struct io_wq_acct acct[IO_WQ_ACCT_NR]; - /* lock protects access to elements below */ - raw_spinlock_t lock; - - struct hlist_nulls_head free_list; - struct list_head all_list; - struct wait_queue_entry wait; struct io_wq_work *hash_tail[IO_WQ_NR_HASH_BUCKETS]; @@ -135,7 +145,7 @@ struct io_cb_cancel_data { bool cancel_all; }; -static bool create_io_worker(struct io_wq *wq, int index); +static bool create_io_worker(struct io_wq *wq, struct io_wq_acct *acct); static void io_wq_dec_running(struct io_worker *worker); static bool io_acct_cancel_pending_work(struct io_wq *wq, struct io_wq_acct *acct, @@ -160,14 +170,14 @@ static inline struct io_wq_acct *io_get_acct(struct io_wq *wq, bool bound) } static inline struct io_wq_acct *io_work_get_acct(struct io_wq *wq, - struct io_wq_work *work) + unsigned int work_flags) { - return io_get_acct(wq, !(atomic_read(&work->flags) & IO_WQ_WORK_UNBOUND)); + return io_get_acct(wq, !(work_flags & IO_WQ_WORK_UNBOUND)); } static inline struct io_wq_acct *io_wq_get_acct(struct io_worker *worker) { - return io_get_acct(worker->wq, test_bit(IO_WORKER_F_BOUND, &worker->flags)); + return worker->acct; } static void io_worker_ref_put(struct io_wq *wq) @@ -192,9 +202,9 @@ static void io_worker_cancel_cb(struct io_worker *worker) struct io_wq *wq = worker->wq; atomic_dec(&acct->nr_running); - raw_spin_lock(&wq->lock); + raw_spin_lock(&acct->workers_lock); acct->nr_workers--; - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); io_worker_ref_put(wq); clear_bit_unlock(0, &worker->create_state); io_worker_release(worker); @@ -213,6 +223,7 @@ static bool io_task_worker_match(struct callback_head *cb, void *data) static void io_worker_exit(struct io_worker *worker) { struct io_wq *wq = worker->wq; + struct io_wq_acct *acct = io_wq_get_acct(worker); while (1) { struct callback_head *cb = task_work_cancel_match(wq->task, @@ -226,11 +237,11 @@ static void io_worker_exit(struct io_worker *worker) io_worker_release(worker); wait_for_completion(&worker->ref_done); - raw_spin_lock(&wq->lock); + raw_spin_lock(&acct->workers_lock); if (test_bit(IO_WORKER_F_FREE, &worker->flags)) hlist_nulls_del_rcu(&worker->nulls_node); list_del_rcu(&worker->all_list); - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); io_wq_dec_running(worker); /* * this worker is a goner, clear ->worker_private to avoid any @@ -269,8 +280,7 @@ static inline bool io_acct_run_queue(struct io_wq_acct *acct) * Check head of free list for an available worker. If one isn't available, * caller must create one. */ -static bool io_wq_activate_free_worker(struct io_wq *wq, - struct io_wq_acct *acct) +static bool io_acct_activate_free_worker(struct io_wq_acct *acct) __must_hold(RCU) { struct hlist_nulls_node *n; @@ -281,13 +291,9 @@ static bool io_wq_activate_free_worker(struct io_wq *wq, * activate. If a given worker is on the free_list but in the process * of exiting, keep trying. */ - hlist_nulls_for_each_entry_rcu(worker, n, &wq->free_list, nulls_node) { + hlist_nulls_for_each_entry_rcu(worker, n, &acct->free_list, nulls_node) { if (!io_worker_get(worker)) continue; - if (io_wq_get_acct(worker) != acct) { - io_worker_release(worker); - continue; - } /* * If the worker is already running, it's either already * starting work or finishing work. In either case, if it does @@ -314,16 +320,16 @@ static bool io_wq_create_worker(struct io_wq *wq, struct io_wq_acct *acct) if (unlikely(!acct->max_workers)) pr_warn_once("io-wq is not configured for unbound workers"); - raw_spin_lock(&wq->lock); + raw_spin_lock(&acct->workers_lock); if (acct->nr_workers >= acct->max_workers) { - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); return true; } acct->nr_workers++; - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); atomic_inc(&acct->nr_running); atomic_inc(&wq->worker_refs); - return create_io_worker(wq, acct->index); + return create_io_worker(wq, acct); } static void io_wq_inc_running(struct io_worker *worker) @@ -343,16 +349,16 @@ static void create_worker_cb(struct callback_head *cb) worker = container_of(cb, struct io_worker, create_work); wq = worker->wq; - acct = &wq->acct[worker->create_index]; - raw_spin_lock(&wq->lock); + acct = worker->acct; + raw_spin_lock(&acct->workers_lock); if (acct->nr_workers < acct->max_workers) { acct->nr_workers++; do_create = true; } - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); if (do_create) { - create_io_worker(wq, worker->create_index); + create_io_worker(wq, acct); } else { atomic_dec(&acct->nr_running); io_worker_ref_put(wq); @@ -384,7 +390,6 @@ static bool io_queue_worker_create(struct io_worker *worker, atomic_inc(&wq->worker_refs); init_task_work(&worker->create_work, func); - worker->create_index = acct->index; if (!task_work_add(wq->task, &worker->create_work, TWA_SIGNAL)) { /* * EXIT may have been set after checking it above, check after @@ -430,31 +435,36 @@ static void io_wq_dec_running(struct io_worker *worker) * Worker will start processing some work. Move it to the busy list, if * it's currently on the freelist */ -static void __io_worker_busy(struct io_wq *wq, struct io_worker *worker) +static void __io_worker_busy(struct io_wq_acct *acct, struct io_worker *worker) { if (test_bit(IO_WORKER_F_FREE, &worker->flags)) { clear_bit(IO_WORKER_F_FREE, &worker->flags); - raw_spin_lock(&wq->lock); + raw_spin_lock(&acct->workers_lock); hlist_nulls_del_init_rcu(&worker->nulls_node); - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); } } /* * No work, worker going to sleep. Move to freelist. */ -static void __io_worker_idle(struct io_wq *wq, struct io_worker *worker) - __must_hold(wq->lock) +static void __io_worker_idle(struct io_wq_acct *acct, struct io_worker *worker) + __must_hold(acct->workers_lock) { if (!test_bit(IO_WORKER_F_FREE, &worker->flags)) { set_bit(IO_WORKER_F_FREE, &worker->flags); - hlist_nulls_add_head_rcu(&worker->nulls_node, &wq->free_list); + hlist_nulls_add_head_rcu(&worker->nulls_node, &acct->free_list); } } +static inline unsigned int __io_get_work_hash(unsigned int work_flags) +{ + return work_flags >> IO_WQ_HASH_SHIFT; +} + static inline unsigned int io_get_work_hash(struct io_wq_work *work) { - return atomic_read(&work->flags) >> IO_WQ_HASH_SHIFT; + return __io_get_work_hash(atomic_read(&work->flags)); } static bool io_wait_on_hash(struct io_wq *wq, unsigned int hash) @@ -475,26 +485,27 @@ static bool io_wait_on_hash(struct io_wq *wq, unsigned int hash) } static struct io_wq_work *io_get_next_work(struct io_wq_acct *acct, - struct io_worker *worker) + struct io_wq *wq) __must_hold(acct->lock) { struct io_wq_work_node *node, *prev; struct io_wq_work *work, *tail; unsigned int stall_hash = -1U; - struct io_wq *wq = worker->wq; wq_list_for_each(node, prev, &acct->work_list) { + unsigned int work_flags; unsigned int hash; work = container_of(node, struct io_wq_work, list); /* not hashed, can run anytime */ - if (!io_wq_is_hashed(work)) { + work_flags = atomic_read(&work->flags); + if (!__io_wq_is_hashed(work_flags)) { wq_list_del(&acct->work_list, node, prev); return work; } - hash = io_get_work_hash(work); + hash = __io_get_work_hash(work_flags); /* all items with this hash lie in [work, tail] */ tail = wq->hash_tail[hash]; @@ -564,7 +575,7 @@ static void io_worker_handle_work(struct io_wq_acct *acct, * can't make progress, any work completion or insertion will * clear the stalled flag. */ - work = io_get_next_work(acct, worker); + work = io_get_next_work(acct, wq); if (work) { /* * Make sure cancelation can find this, even before @@ -583,7 +594,7 @@ static void io_worker_handle_work(struct io_wq_acct *acct, if (!work) break; - __io_worker_busy(wq, worker); + __io_worker_busy(acct, worker); io_assign_current_work(worker, work); __set_current_state(TASK_RUNNING); @@ -591,12 +602,15 @@ static void io_worker_handle_work(struct io_wq_acct *acct, /* handle a whole dependent link */ do { struct io_wq_work *next_hashed, *linked; - unsigned int hash = io_get_work_hash(work); + unsigned int work_flags = atomic_read(&work->flags); + unsigned int hash = __io_wq_is_hashed(work_flags) + ? __io_get_work_hash(work_flags) + : -1U; next_hashed = wq_next_work(work); if (do_kill && - (atomic_read(&work->flags) & IO_WQ_WORK_UNBOUND)) + (work_flags & IO_WQ_WORK_UNBOUND)) atomic_or(IO_WQ_WORK_CANCEL, &work->flags); wq->do_work(work); io_assign_current_work(worker, NULL); @@ -654,20 +668,20 @@ static int io_wq_worker(void *data) while (io_acct_run_queue(acct)) io_worker_handle_work(acct, worker); - raw_spin_lock(&wq->lock); + raw_spin_lock(&acct->workers_lock); /* * Last sleep timed out. Exit if we're not the last worker, * or if someone modified our affinity. */ if (last_timeout && (exit_mask || acct->nr_workers > 1)) { acct->nr_workers--; - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); __set_current_state(TASK_RUNNING); break; } last_timeout = false; - __io_worker_idle(wq, worker); - raw_spin_unlock(&wq->lock); + __io_worker_idle(acct, worker); + raw_spin_unlock(&acct->workers_lock); if (io_run_task_work()) continue; ret = schedule_timeout(WORKER_IDLE_TIMEOUT); @@ -728,18 +742,18 @@ void io_wq_worker_sleeping(struct task_struct *tsk) io_wq_dec_running(worker); } -static void io_init_new_worker(struct io_wq *wq, struct io_worker *worker, +static void io_init_new_worker(struct io_wq *wq, struct io_wq_acct *acct, struct io_worker *worker, struct task_struct *tsk) { tsk->worker_private = worker; worker->task = tsk; set_cpus_allowed_ptr(tsk, wq->cpu_mask); - raw_spin_lock(&wq->lock); - hlist_nulls_add_head_rcu(&worker->nulls_node, &wq->free_list); - list_add_tail_rcu(&worker->all_list, &wq->all_list); + raw_spin_lock(&acct->workers_lock); + hlist_nulls_add_head_rcu(&worker->nulls_node, &acct->free_list); + list_add_tail_rcu(&worker->all_list, &acct->all_list); set_bit(IO_WORKER_F_FREE, &worker->flags); - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); wake_up_new_task(tsk); } @@ -775,20 +789,20 @@ static void create_worker_cont(struct callback_head *cb) struct io_worker *worker; struct task_struct *tsk; struct io_wq *wq; + struct io_wq_acct *acct; worker = container_of(cb, struct io_worker, create_work); clear_bit_unlock(0, &worker->create_state); wq = worker->wq; + acct = io_wq_get_acct(worker); tsk = create_io_thread(io_wq_worker, worker, NUMA_NO_NODE); if (!IS_ERR(tsk)) { - io_init_new_worker(wq, worker, tsk); + io_init_new_worker(wq, acct, worker, tsk); io_worker_release(worker); return; } else if (!io_should_retry_thread(worker, PTR_ERR(tsk))) { - struct io_wq_acct *acct = io_wq_get_acct(worker); - atomic_dec(&acct->nr_running); - raw_spin_lock(&wq->lock); + raw_spin_lock(&acct->workers_lock); acct->nr_workers--; if (!acct->nr_workers) { struct io_cb_cancel_data match = { @@ -796,11 +810,11 @@ static void create_worker_cont(struct callback_head *cb) .cancel_all = true, }; - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); while (io_acct_cancel_pending_work(wq, acct, &match)) ; } else { - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); } io_worker_ref_put(wq); kfree(worker); @@ -821,9 +835,8 @@ static void io_workqueue_create(struct work_struct *work) kfree(worker); } -static bool create_io_worker(struct io_wq *wq, int index) +static bool create_io_worker(struct io_wq *wq, struct io_wq_acct *acct) { - struct io_wq_acct *acct = &wq->acct[index]; struct io_worker *worker; struct task_struct *tsk; @@ -833,24 +846,22 @@ static bool create_io_worker(struct io_wq *wq, int index) if (!worker) { fail: atomic_dec(&acct->nr_running); - raw_spin_lock(&wq->lock); + raw_spin_lock(&acct->workers_lock); acct->nr_workers--; - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); io_worker_ref_put(wq); return false; } refcount_set(&worker->ref, 1); worker->wq = wq; + worker->acct = acct; raw_spin_lock_init(&worker->lock); init_completion(&worker->ref_done); - if (index == IO_WQ_ACCT_BOUND) - set_bit(IO_WORKER_F_BOUND, &worker->flags); - tsk = create_io_thread(io_wq_worker, worker, NUMA_NO_NODE); if (!IS_ERR(tsk)) { - io_init_new_worker(wq, worker, tsk); + io_init_new_worker(wq, acct, worker, tsk); } else if (!io_should_retry_thread(worker, PTR_ERR(tsk))) { kfree(worker); goto fail; @@ -866,14 +877,14 @@ static bool create_io_worker(struct io_wq *wq, int index) * Iterate the passed in list and call the specific function for each * worker that isn't exiting */ -static bool io_wq_for_each_worker(struct io_wq *wq, - bool (*func)(struct io_worker *, void *), - void *data) +static bool io_acct_for_each_worker(struct io_wq_acct *acct, + bool (*func)(struct io_worker *, void *), + void *data) { struct io_worker *worker; bool ret = false; - list_for_each_entry_rcu(worker, &wq->all_list, all_list) { + list_for_each_entry_rcu(worker, &acct->all_list, all_list) { if (io_worker_get(worker)) { /* no task if node is/was offline */ if (worker->task) @@ -887,6 +898,18 @@ static bool io_wq_for_each_worker(struct io_wq *wq, return ret; } +static bool io_wq_for_each_worker(struct io_wq *wq, + bool (*func)(struct io_worker *, void *), + void *data) +{ + for (int i = 0; i < IO_WQ_ACCT_NR; i++) { + if (!io_acct_for_each_worker(&wq->acct[i], func, data)) + return false; + } + + return true; +} + static bool io_wq_worker_wake(struct io_worker *worker, void *data) { __set_notify_signal(worker->task); @@ -903,19 +926,19 @@ static void io_run_cancel(struct io_wq_work *work, struct io_wq *wq) } while (work); } -static void io_wq_insert_work(struct io_wq *wq, struct io_wq_work *work) +static void io_wq_insert_work(struct io_wq *wq, struct io_wq_acct *acct, + struct io_wq_work *work, unsigned int work_flags) { - struct io_wq_acct *acct = io_work_get_acct(wq, work); unsigned int hash; struct io_wq_work *tail; - if (!io_wq_is_hashed(work)) { + if (!__io_wq_is_hashed(work_flags)) { append: wq_list_add_tail(&work->list, &acct->work_list); return; } - hash = io_get_work_hash(work); + hash = __io_get_work_hash(work_flags); tail = wq->hash_tail[hash]; wq->hash_tail[hash] = work; if (!tail) @@ -931,8 +954,8 @@ static bool io_wq_work_match_item(struct io_wq_work *work, void *data) void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work) { - struct io_wq_acct *acct = io_work_get_acct(wq, work); unsigned int work_flags = atomic_read(&work->flags); + struct io_wq_acct *acct = io_work_get_acct(wq, work_flags); struct io_cb_cancel_data match = { .fn = io_wq_work_match_item, .data = work, @@ -951,12 +974,12 @@ void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work) } raw_spin_lock(&acct->lock); - io_wq_insert_work(wq, work); + io_wq_insert_work(wq, acct, work, work_flags); clear_bit(IO_ACCT_STALLED_BIT, &acct->flags); raw_spin_unlock(&acct->lock); rcu_read_lock(); - do_create = !io_wq_activate_free_worker(wq, acct); + do_create = !io_acct_activate_free_worker(acct); rcu_read_unlock(); if (do_create && ((work_flags & IO_WQ_WORK_CONCURRENT) || @@ -967,12 +990,12 @@ void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work) if (likely(did_create)) return; - raw_spin_lock(&wq->lock); + raw_spin_lock(&acct->workers_lock); if (acct->nr_workers) { - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); return; } - raw_spin_unlock(&wq->lock); + raw_spin_unlock(&acct->workers_lock); /* fatal condition, failed to create the first worker */ io_acct_cancel_pending_work(wq, acct, &match); @@ -1021,10 +1044,10 @@ static bool io_wq_worker_cancel(struct io_worker *worker, void *data) } static inline void io_wq_remove_pending(struct io_wq *wq, + struct io_wq_acct *acct, struct io_wq_work *work, struct io_wq_work_node *prev) { - struct io_wq_acct *acct = io_work_get_acct(wq, work); unsigned int hash = io_get_work_hash(work); struct io_wq_work *prev_work = NULL; @@ -1051,7 +1074,7 @@ static bool io_acct_cancel_pending_work(struct io_wq *wq, work = container_of(node, struct io_wq_work, list); if (!match->fn(work, match->data)) continue; - io_wq_remove_pending(wq, work, prev); + io_wq_remove_pending(wq, acct, work, prev); raw_spin_unlock(&acct->lock); io_run_cancel(work, wq); match->nr_pending++; @@ -1079,11 +1102,22 @@ static void io_wq_cancel_pending_work(struct io_wq *wq, } } +static void io_acct_cancel_running_work(struct io_wq_acct *acct, + struct io_cb_cancel_data *match) +{ + raw_spin_lock(&acct->workers_lock); + io_acct_for_each_worker(acct, io_wq_worker_cancel, match); + raw_spin_unlock(&acct->workers_lock); +} + static void io_wq_cancel_running_work(struct io_wq *wq, struct io_cb_cancel_data *match) { rcu_read_lock(); - io_wq_for_each_worker(wq, io_wq_worker_cancel, match); + + for (int i = 0; i < IO_WQ_ACCT_NR; i++) + io_acct_cancel_running_work(&wq->acct[i], match); + rcu_read_unlock(); } @@ -1106,16 +1140,14 @@ enum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel, * as an indication that we attempt to signal cancellation. The * completion will run normally in this case. * - * Do both of these while holding the wq->lock, to ensure that + * Do both of these while holding the acct->workers_lock, to ensure that * we'll find a work item regardless of state. */ io_wq_cancel_pending_work(wq, &match); if (match.nr_pending && !match.cancel_all) return IO_WQ_CANCEL_OK; - raw_spin_lock(&wq->lock); io_wq_cancel_running_work(wq, &match); - raw_spin_unlock(&wq->lock); if (match.nr_running && !match.cancel_all) return IO_WQ_CANCEL_RUNNING; @@ -1139,7 +1171,7 @@ static int io_wq_hash_wake(struct wait_queue_entry *wait, unsigned mode, struct io_wq_acct *acct = &wq->acct[i]; if (test_and_clear_bit(IO_ACCT_STALLED_BIT, &acct->flags)) - io_wq_activate_free_worker(wq, acct); + io_acct_activate_free_worker(acct); } rcu_read_unlock(); return 1; @@ -1177,16 +1209,16 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) for (i = 0; i < IO_WQ_ACCT_NR; i++) { struct io_wq_acct *acct = &wq->acct[i]; - acct->index = i; atomic_set(&acct->nr_running, 0); + + raw_spin_lock_init(&acct->workers_lock); + INIT_HLIST_NULLS_HEAD(&acct->free_list, 0); + INIT_LIST_HEAD(&acct->all_list); + INIT_WQ_LIST(&acct->work_list); raw_spin_lock_init(&acct->lock); } - raw_spin_lock_init(&wq->lock); - INIT_HLIST_NULLS_HEAD(&wq->free_list, 0); - INIT_LIST_HEAD(&wq->all_list); - wq->task = get_task_struct(data->task); atomic_set(&wq->worker_refs, 1); init_completion(&wq->worker_done); @@ -1372,14 +1404,14 @@ int io_wq_max_workers(struct io_wq *wq, int *new_count) rcu_read_lock(); - raw_spin_lock(&wq->lock); for (i = 0; i < IO_WQ_ACCT_NR; i++) { acct = &wq->acct[i]; + raw_spin_lock(&acct->workers_lock); prev[i] = max_t(int, acct->max_workers, prev[i]); if (new_count[i]) acct->max_workers = new_count[i]; + raw_spin_unlock(&acct->workers_lock); } - raw_spin_unlock(&wq->lock); rcu_read_unlock(); for (i = 0; i < IO_WQ_ACCT_NR; i++)
diff --git a/io_uring/io-wq.h b/io_uring/io-wq.h index b3b004a..d4fb294 100644 --- a/io_uring/io-wq.h +++ b/io_uring/io-wq.h
@@ -54,9 +54,14 @@ int io_wq_cpu_affinity(struct io_uring_task *tctx, cpumask_var_t mask); int io_wq_max_workers(struct io_wq *wq, int *new_count); bool io_wq_worker_stopped(void); +static inline bool __io_wq_is_hashed(unsigned int work_flags) +{ + return work_flags & IO_WQ_WORK_HASHED; +} + static inline bool io_wq_is_hashed(struct io_wq_work *work) { - return atomic_read(&work->flags) & IO_WQ_WORK_HASHED; + return __io_wq_is_hashed(atomic_read(&work->flags)); } typedef bool (work_cancel_fn)(struct io_wq_work *, void *);
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index ceacf62..2f311ae 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c
@@ -282,6 +282,16 @@ static int io_alloc_hash_table(struct io_hash_table *table, unsigned bits) return 0; } +static void io_free_alloc_caches(struct io_ring_ctx *ctx) +{ + io_alloc_cache_free(&ctx->apoll_cache, kfree); + io_alloc_cache_free(&ctx->netmsg_cache, io_netmsg_cache_free); + io_alloc_cache_free(&ctx->rw_cache, io_rw_cache_free); + io_alloc_cache_free(&ctx->uring_cache, kfree); + io_alloc_cache_free(&ctx->msg_cache, kfree); + io_futex_cache_free(ctx); +} + static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) { struct io_ring_ctx *ctx; @@ -360,12 +370,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) free_ref: percpu_ref_exit(&ctx->refs); err: - io_alloc_cache_free(&ctx->apoll_cache, kfree); - io_alloc_cache_free(&ctx->netmsg_cache, io_netmsg_cache_free); - io_alloc_cache_free(&ctx->rw_cache, io_rw_cache_free); - io_alloc_cache_free(&ctx->uring_cache, kfree); - io_alloc_cache_free(&ctx->msg_cache, kfree); - io_futex_cache_free(ctx); + io_free_alloc_caches(ctx); kvfree(ctx->cancel_table.hbs); xa_destroy(&ctx->io_bl_xa); kfree(ctx); @@ -393,28 +398,30 @@ static bool req_need_defer(struct io_kiocb *req, u32 seq) static void io_clean_op(struct io_kiocb *req) { - if (req->flags & REQ_F_BUFFER_SELECTED) { + const io_req_flags_t req_flags = req->flags; + + if (req_flags & REQ_F_BUFFER_SELECTED) { spin_lock(&req->ctx->completion_lock); io_kbuf_drop(req); spin_unlock(&req->ctx->completion_lock); } - if (req->flags & REQ_F_NEED_CLEANUP) { + if (req_flags & REQ_F_NEED_CLEANUP) { const struct io_cold_def *def = &io_cold_defs[req->opcode]; if (def->cleanup) def->cleanup(req); } - if ((req->flags & REQ_F_POLLED) && req->apoll) { + if ((req_flags & REQ_F_POLLED) && req->apoll) { kfree(req->apoll->double_poll); kfree(req->apoll); req->apoll = NULL; } - if (req->flags & REQ_F_INFLIGHT) + if (req_flags & REQ_F_INFLIGHT) atomic_dec(&req->tctx->inflight_tracked); - if (req->flags & REQ_F_CREDS) + if (req_flags & REQ_F_CREDS) put_cred(req->creds); - if (req->flags & REQ_F_ASYNC_DATA) { + if (req_flags & REQ_F_ASYNC_DATA) { kfree(req->async_data); req->async_data = NULL; } @@ -455,31 +462,37 @@ static noinline void __io_arm_ltimeout(struct io_kiocb *req) io_queue_linked_timeout(__io_prep_linked_timeout(req)); } +static inline void _io_arm_ltimeout(struct io_kiocb *req, unsigned int req_flags) +{ + if (unlikely(req_flags & REQ_F_ARM_LTIMEOUT)) + __io_arm_ltimeout(req); +} + static inline void io_arm_ltimeout(struct io_kiocb *req) { - if (unlikely(req->flags & REQ_F_ARM_LTIMEOUT)) - __io_arm_ltimeout(req); + _io_arm_ltimeout(req, req->flags); } static void io_prep_async_work(struct io_kiocb *req) { + io_req_flags_t req_flags = req->flags; const struct io_issue_def *def = &io_issue_defs[req->opcode]; struct io_ring_ctx *ctx = req->ctx; - if (!(req->flags & REQ_F_CREDS)) { - req->flags |= REQ_F_CREDS; + if (!(req_flags & REQ_F_CREDS)) { + req_flags = req->flags |= REQ_F_CREDS; req->creds = get_current_cred(); } req->work.list.next = NULL; atomic_set(&req->work.flags, 0); - if (req->flags & REQ_F_FORCE_ASYNC) + if (req_flags & REQ_F_FORCE_ASYNC) atomic_or(IO_WQ_WORK_CONCURRENT, &req->work.flags); - if (req->file && !(req->flags & REQ_F_FIXED_FILE)) - req->flags |= io_file_get_flags(req->file); + if (req->file && !(req_flags & REQ_F_FIXED_FILE)) + req_flags = req->flags |= io_file_get_flags(req->file); - if (req->file && (req->flags & REQ_F_ISREG)) { + if (req->file && (req_flags & REQ_F_ISREG)) { bool should_hash = def->hash_reg_file; /* don't serialize this request if the fs doesn't need it */ @@ -1705,13 +1718,14 @@ static __cold void io_drain_req(struct io_kiocb *req) spin_unlock(&ctx->completion_lock); } -static bool io_assign_file(struct io_kiocb *req, const struct io_issue_def *def, +static bool io_assign_file(struct io_kiocb *req, unsigned int req_flags, + const struct io_issue_def *def, unsigned int issue_flags) { if (req->file || !def->needs_file) return true; - if (req->flags & REQ_F_FIXED_FILE) + if (req_flags & REQ_F_FIXED_FILE) req->file = io_file_get_fixed(req, req->cqe.fd, issue_flags); else req->file = io_file_get_normal(req, req->cqe.fd); @@ -1721,14 +1735,15 @@ static bool io_assign_file(struct io_kiocb *req, const struct io_issue_def *def, static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags) { + const io_req_flags_t req_flags = req->flags; const struct io_issue_def *def = &io_issue_defs[req->opcode]; const struct cred *creds = NULL; int ret; - if (unlikely(!io_assign_file(req, def, issue_flags))) + if (unlikely(!io_assign_file(req, req_flags, def, issue_flags))) return -EBADF; - if (unlikely((req->flags & REQ_F_CREDS) && req->creds != current_cred())) + if (unlikely((req_flags & REQ_F_CREDS) && req->creds != current_cred())) creds = override_creds(req->creds); if (!def->audit_skip) @@ -1785,18 +1800,19 @@ struct io_wq_work *io_wq_free_work(struct io_wq_work *work) void io_wq_submit_work(struct io_wq_work *work) { struct io_kiocb *req = container_of(work, struct io_kiocb, work); + const io_req_flags_t req_flags = req->flags; const struct io_issue_def *def = &io_issue_defs[req->opcode]; unsigned int issue_flags = IO_URING_F_UNLOCKED | IO_URING_F_IOWQ; bool needs_poll = false; int ret = 0, err = -ECANCELED; /* one will be dropped by ->io_wq_free_work() after returning to io-wq */ - if (!(req->flags & REQ_F_REFCOUNT)) + if (!(req_flags & REQ_F_REFCOUNT)) __io_req_set_refcount(req, 2); else req_ref_get(req); - io_arm_ltimeout(req); + _io_arm_ltimeout(req, req_flags); /* either cancelled or io-wq is dying, so don't touch tctx->iowq */ if (atomic_read(&work->flags) & IO_WQ_WORK_CANCEL) { @@ -1804,7 +1820,7 @@ void io_wq_submit_work(struct io_wq_work *work) io_req_task_queue_fail(req, err); return; } - if (!io_assign_file(req, def, issue_flags)) { + if (!io_assign_file(req, req_flags, def, issue_flags)) { err = -EBADF; atomic_or(IO_WQ_WORK_CANCEL, &work->flags); goto fail; @@ -1818,7 +1834,7 @@ void io_wq_submit_work(struct io_wq_work *work) * Don't allow any multishot execution from io-wq. It's more restrictive * than necessary and also cleaner. */ - if (req->flags & REQ_F_APOLL_MULTISHOT) { + if (req_flags & REQ_F_APOLL_MULTISHOT) { err = -EBADFD; if (!io_file_can_poll(req)) goto fail; @@ -1833,7 +1849,7 @@ void io_wq_submit_work(struct io_wq_work *work) } } - if (req->flags & REQ_F_FORCE_ASYNC) { + if (req_flags & REQ_F_FORCE_ASYNC) { bool opcode_poll = def->pollin || def->pollout; if (opcode_poll && io_file_can_poll(req)) { @@ -1851,7 +1867,7 @@ void io_wq_submit_work(struct io_wq_work *work) * If REQ_F_NOWAIT is set, then don't wait or retry with * poll. -EAGAIN is final for that case. */ - if (req->flags & REQ_F_NOWAIT) + if (req_flags & REQ_F_NOWAIT) break; /* @@ -2702,12 +2718,7 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx) io_sqe_files_unregister(ctx); io_cqring_overflow_kill(ctx); io_eventfd_unregister(ctx); - io_alloc_cache_free(&ctx->apoll_cache, kfree); - io_alloc_cache_free(&ctx->netmsg_cache, io_netmsg_cache_free); - io_alloc_cache_free(&ctx->rw_cache, io_rw_cache_free); - io_alloc_cache_free(&ctx->uring_cache, kfree); - io_alloc_cache_free(&ctx->msg_cache, kfree); - io_futex_cache_free(ctx); + io_free_alloc_caches(ctx); io_destroy_buffers(ctx); io_free_region(ctx, &ctx->param_region); mutex_unlock(&ctx->uring_lock); @@ -3535,6 +3546,44 @@ static struct file *io_uring_get_file(struct io_ring_ctx *ctx) O_RDWR | O_CLOEXEC, NULL); } +static int io_uring_sanitise_params(struct io_uring_params *p) +{ + unsigned flags = p->flags; + + /* There is no way to mmap rings without a real fd */ + if ((flags & IORING_SETUP_REGISTERED_FD_ONLY) && + !(flags & IORING_SETUP_NO_MMAP)) + return -EINVAL; + + if (flags & IORING_SETUP_SQPOLL) { + /* IPI related flags don't make sense with SQPOLL */ + if (flags & (IORING_SETUP_COOP_TASKRUN | + IORING_SETUP_TASKRUN_FLAG | + IORING_SETUP_DEFER_TASKRUN)) + return -EINVAL; + } + + if (flags & IORING_SETUP_TASKRUN_FLAG) { + if (!(flags & (IORING_SETUP_COOP_TASKRUN | + IORING_SETUP_DEFER_TASKRUN))) + return -EINVAL; + } + + /* HYBRID_IOPOLL only valid with IOPOLL */ + if ((flags & IORING_SETUP_HYBRID_IOPOLL) && !(flags & IORING_SETUP_IOPOLL)) + return -EINVAL; + + /* + * For DEFER_TASKRUN we require the completion task to be the same as + * the submission task. This implies that there is only one submitter. + */ + if ((flags & IORING_SETUP_DEFER_TASKRUN) && + !(flags & IORING_SETUP_SINGLE_ISSUER)) + return -EINVAL; + + return 0; +} + int io_uring_fill_params(unsigned entries, struct io_uring_params *p) { if (!entries) @@ -3545,10 +3594,6 @@ int io_uring_fill_params(unsigned entries, struct io_uring_params *p) entries = IORING_MAX_ENTRIES; } - if ((p->flags & IORING_SETUP_REGISTERED_FD_ONLY) - && !(p->flags & IORING_SETUP_NO_MMAP)) - return -EINVAL; - /* * Use twice as many entries for the CQ ring. It's possible for the * application to drive a higher depth than the size of the SQ ring, @@ -3610,6 +3655,10 @@ static __cold int io_uring_create(unsigned entries, struct io_uring_params *p, struct file *file; int ret; + ret = io_uring_sanitise_params(p); + if (ret) + return ret; + ret = io_uring_fill_params(entries, p); if (unlikely(ret)) return ret; @@ -3657,37 +3706,10 @@ static __cold int io_uring_create(unsigned entries, struct io_uring_params *p, * For SQPOLL, we just need a wakeup, always. For !SQPOLL, if * COOP_TASKRUN is set, then IPIs are never needed by the app. */ - ret = -EINVAL; - if (ctx->flags & IORING_SETUP_SQPOLL) { - /* IPI related flags don't make sense with SQPOLL */ - if (ctx->flags & (IORING_SETUP_COOP_TASKRUN | - IORING_SETUP_TASKRUN_FLAG | - IORING_SETUP_DEFER_TASKRUN)) - goto err; + if (ctx->flags & (IORING_SETUP_SQPOLL|IORING_SETUP_COOP_TASKRUN)) ctx->notify_method = TWA_SIGNAL_NO_IPI; - } else if (ctx->flags & IORING_SETUP_COOP_TASKRUN) { - ctx->notify_method = TWA_SIGNAL_NO_IPI; - } else { - if (ctx->flags & IORING_SETUP_TASKRUN_FLAG && - !(ctx->flags & IORING_SETUP_DEFER_TASKRUN)) - goto err; + else ctx->notify_method = TWA_SIGNAL; - } - - /* HYBRID_IOPOLL only valid with IOPOLL */ - if ((ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_HYBRID_IOPOLL)) == - IORING_SETUP_HYBRID_IOPOLL) - goto err; - - /* - * For DEFER_TASKRUN we require the completion task to be the same as the - * submission task. This implies that there is only one submitter, so enforce - * that. - */ - if (ctx->flags & IORING_SETUP_DEFER_TASKRUN && - !(ctx->flags & IORING_SETUP_SINGLE_ISSUER)) { - goto err; - } /* * This is just grabbed for accounting purposes. When a process exits, @@ -3920,6 +3942,7 @@ static int __init io_uring_init(void) SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT); iou_wq = alloc_workqueue("iou_exit", WQ_UNBOUND, 64); + BUG_ON(!iou_wq); #ifdef CONFIG_SYSCTL register_sysctl_init("kernel", kernel_io_uring_disabled_table);
diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 1075598..fa41366 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c
@@ -183,6 +183,8 @@ static int micfil_set_quality(struct fsl_micfil *micfil) case QUALITY_VLOW2: qsel = MICFIL_QSEL_VLOW2_QUALITY; break; + default: + return -EINVAL; } return regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,