diff options
909 files changed, 21358 insertions, 7618 deletions
diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt index bfd5b558477d..5c01e65951fa 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.txt +++ b/Documentation/devicetree/bindings/arm/amlogic.txt @@ -29,26 +29,34 @@ Boards with the Amlogic Meson GXM S912 SoC shall have the following properties: Required root node property: compatible: "amlogic,s912", "amlogic,meson-gxm"; -Board compatible values: +Board compatible values (alphabetically, grouped by SoC): + - "geniatech,atv1200" (Meson6) + - "minix,neo-x8" (Meson8) - - "tronfy,mxq" (Meson8b) + - "hardkernel,odroid-c1" (Meson8b) + - "tronfy,mxq" (Meson8b) + + - "amlogic,p200" (Meson gxbb) + - "amlogic,p201" (Meson gxbb) + - "friendlyarm,nanopi-k2" (Meson gxbb) + - "hardkernel,odroid-c2" (Meson gxbb) + - "nexbox,a95x" (Meson gxbb or Meson gxl s905x) - "tronsmart,vega-s95-pro", "tronsmart,vega-s95" (Meson gxbb) - "tronsmart,vega-s95-meta", "tronsmart,vega-s95" (Meson gxbb) - "tronsmart,vega-s95-telos", "tronsmart,vega-s95" (Meson gxbb) - - "hardkernel,odroid-c2" (Meson gxbb) - - "amlogic,p200" (Meson gxbb) - - "amlogic,p201" (Meson gxbb) - "wetek,hub" (Meson gxbb) - "wetek,play2" (Meson gxbb) + - "amlogic,p212" (Meson gxl s905x) + - "hwacom,amazetv" (Meson gxl s905x) - "khadas,vim" (Meson gxl s905x) - "amlogic,p230" (Meson gxl s905d) - "amlogic,p231" (Meson gxl s905d) - - "hwacom,amazetv" (Meson gxl s905x) + - "amlogic,q200" (Meson gxm s912) - "amlogic,q201" (Meson gxm s912) - - "nexbox,a95x" (Meson gxbb or Meson gxl s905x) + - "kingnovel,r-box-pro" (Meson gxm S912) - "nexbox,a1" (Meson gxm s912) diff --git a/Documentation/devicetree/bindings/arm/keystone/keystone.txt b/Documentation/devicetree/bindings/arm/keystone/keystone.txt index 48f6703a28c8..f310bad04483 100644 --- a/Documentation/devicetree/bindings/arm/keystone/keystone.txt +++ b/Documentation/devicetree/bindings/arm/keystone/keystone.txt @@ -37,3 +37,6 @@ Boards: - K2G EVM compatible = "ti,k2g-evm", "ti,k2g", "ti-keystone" + +- K2G Industrial Communication Engine EVM + compatible = "ti,k2g-ice", "ti,k2g", "ti-keystone" diff --git a/Documentation/devicetree/bindings/arm/realtek.txt b/Documentation/devicetree/bindings/arm/realtek.txt new file mode 100644 index 000000000000..13d755787b4f --- /dev/null +++ b/Documentation/devicetree/bindings/arm/realtek.txt @@ -0,0 +1,20 @@ +Realtek platforms device tree bindings +-------------------------------------- + + +RTD1295 SoC +=========== + +Required root node properties: + + - compatible : must contain "realtek,rtd1295" + + +Root node property compatible must contain, depending on board: + + - Zidoo X9S: "zidoo,x9s" + + +Example: + + compatible = "zidoo,x9s", "realtek,rtd1295"; diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index c965d99e86c2..11c0ac4a2d56 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -42,6 +42,10 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "firefly,firefly-rk3288-reload", "rockchip,rk3288"; +- Firefly Firefly-RK3399 board: + Required root node properties: + - compatible = "firefly,firefly-rk3399", "rockchip,rk3399"; + - ChipSPARK PopMetal-RK3288 board: Required root node properties: - compatible = "chipspark,popmetal-rk3288", "rockchip,rk3288"; @@ -138,9 +142,9 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "rockchip,px5-evb", "rockchip,px5", "rockchip,rk3368"; -- Rockchip RK1108 Evaluation board +- Rockchip RV1108 Evaluation board Required root node properties: - - compatible = "rockchip,rk1108-evb", "rockchip,rk1108"; + - compatible = "rockchip,rv1108-evb", "rockchip,rv1108"; - Rockchip RK3368 evb: Required root node properties: diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt index 170fe0562c63..4b60ce21f4f3 100644 --- a/Documentation/devicetree/bindings/arm/shmobile.txt +++ b/Documentation/devicetree/bindings/arm/shmobile.txt @@ -55,6 +55,8 @@ Boards: compatible = "renesas,bockw", "renesas,r8a7778" - Genmai (RTK772100BC00000BR) compatible = "renesas,genmai", "renesas,r7s72100" + - GR-Peach (X28A-M01-E/F) + compatible = "renesas,gr-peach", "renesas,r7s72100" - Gose (RTP0RC7793SEB00010S) compatible = "renesas,gose", "renesas,r8a7793" - H3ULCB (R-Car Starter Kit Premier, RTP0RC7795SKB00010S) diff --git a/Documentation/devicetree/bindings/clock/sun8i-de2.txt b/Documentation/devicetree/bindings/clock/sun8i-de2.txt new file mode 100644 index 000000000000..631d27cd89d6 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/sun8i-de2.txt @@ -0,0 +1,31 @@ +Allwinner Display Engine 2.0 Clock Control Binding +-------------------------------------------------- + +Required properties : +- compatible: must contain one of the following compatibles: + - "allwinner,sun8i-a83t-de2-clk" + - "allwinner,sun8i-v3s-de2-clk" + - "allwinner,sun50i-h5-de2-clk" + +- reg: Must contain the registers base address and length +- clocks: phandle to the clocks feeding the display engine subsystem. + Three are needed: + - "mod": the display engine module clock + - "bus": the bus clock for the whole display engine subsystem +- clock-names: Must contain the clock names described just above +- resets: phandle to the reset control for the display engine subsystem. +- #clock-cells : must contain 1 +- #reset-cells : must contain 1 + +Example: +de2_clocks: clock@1000000 { + compatible = "allwinner,sun8i-a83t-de2-clk"; + reg = <0x01000000 0x100000>; + clocks = <&ccu CLK_BUS_DE>, + <&ccu CLK_DE>; + clock-names = "bus", + "mod"; + resets = <&ccu RST_BUS_DE>; + #clock-cells = <1>; + #reset-cells = <1>; +}; diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt index e9c5a1d9834a..095a5807d874 100644 --- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt +++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt @@ -6,6 +6,8 @@ Required properties : - "allwinner,sun6i-a31-ccu" - "allwinner,sun8i-a23-ccu" - "allwinner,sun8i-a33-ccu" + - "allwinner,sun8i-a83t-ccu" + - "allwinner,sun8i-a83t-r-ccu" - "allwinner,sun8i-h3-ccu" - "allwinner,sun8i-h3-r-ccu" - "allwinner,sun8i-v3s-ccu" @@ -18,11 +20,12 @@ Required properties : - clocks: phandle to the oscillators feeding the CCU. Two are needed: - "hosc": the high frequency oscillator (usually at 24MHz) - "losc": the low frequency oscillator (usually at 32kHz) + On the A83T, this is the internal 16MHz oscillator divided by 512 - clock-names: Must contain the clock names described just above - #clock-cells : must contain 1 - #reset-cells : must contain 1 -For the PRCM CCUs on H3/A64, one more clock is needed: +For the PRCM CCUs on A83T/H3/A64, one more clock is needed: - "iosc": the SoC's internal frequency oscillator Example for generic CCU: diff --git a/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt index ba0e15ad5bd9..0c38e4b8fc51 100644 --- a/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt +++ b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt @@ -63,64 +63,64 @@ cpu0_opp_table: opp-table { * because they can not be enabled simultaneously on a * single SoC. */ - opp50@300000000 { + opp50-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <950000 931000 969000>; opp-supported-hw = <0x06 0x0010>; opp-suspend; }; - opp100@275000000 { + opp100-275000000 { opp-hz = /bits/ 64 <275000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x01 0x00FF>; opp-suspend; }; - opp100@300000000 { + opp100-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x06 0x0020>; opp-suspend; }; - opp100@500000000 { + opp100-500000000 { opp-hz = /bits/ 64 <500000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x01 0xFFFF>; }; - opp100@600000000 { + opp100-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x06 0x0040>; }; - opp120@600000000 { + opp120-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1200000 1176000 1224000>; opp-supported-hw = <0x01 0xFFFF>; }; - opp120@720000000 { + opp120-720000000 { opp-hz = /bits/ 64 <720000000>; opp-microvolt = <1200000 1176000 1224000>; opp-supported-hw = <0x06 0x0080>; }; - oppturbo@720000000 { + oppturbo-720000000 { opp-hz = /bits/ 64 <720000000>; opp-microvolt = <1260000 1234800 1285200>; opp-supported-hw = <0x01 0xFFFF>; }; - oppturbo@800000000 { + oppturbo-800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = <1260000 1234800 1285200>; opp-supported-hw = <0x06 0x0100>; }; - oppnitro@1000000000 { + oppnitro-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <1325000 1298500 1351500>; opp-supported-hw = <0x04 0x0200>; diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt new file mode 100644 index 000000000000..d3b6e1a4713a --- /dev/null +++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt @@ -0,0 +1,86 @@ +ARM Mali Midgard GPU +==================== + +Required properties: + +- compatible : + * Must contain one of the following: + + "arm,mali-t604" + + "arm,mali-t624" + + "arm,mali-t628" + + "arm,mali-t720" + + "arm,mali-t760" + + "arm,mali-t820" + + "arm,mali-t830" + + "arm,mali-t860" + + "arm,mali-t880" + * which must be preceded by one of the following vendor specifics: + + "amlogic,meson-gxm-mali" + + "rockchip,rk3288-mali" + +- reg : Physical base address of the device and length of the register area. + +- interrupts : Contains the three IRQ lines required by Mali Midgard devices. + +- interrupt-names : Contains the names of IRQ resources in the order they were + provided in the interrupts property. Must contain: "job", "mmu", "gpu". + + +Optional properties: + +- clocks : Phandle to clock for the Mali Midgard device. + +- mali-supply : Phandle to regulator for the Mali device. Refer to + Documentation/devicetree/bindings/regulator/regulator.txt for details. + +- operating-points-v2 : Refer to Documentation/devicetree/bindings/power/opp.txt + for details. + + +Example for a Mali-T760: + +gpu@ffa30000 { + compatible = "rockchip,rk3288-mali", "arm,mali-t760", "arm,mali-midgard"; + reg = <0xffa30000 0x10000>; + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "job", "mmu", "gpu"; + clocks = <&cru ACLK_GPU>; + mali-supply = <&vdd_gpu>; + operating-points-v2 = <&gpu_opp_table>; + power-domains = <&power RK3288_PD_GPU>; +}; + +gpu_opp_table: opp_table0 { + compatible = "operating-points-v2"; + + opp@533000000 { + opp-hz = /bits/ 64 <533000000>; + opp-microvolt = <1250000>; + }; + opp@450000000 { + opp-hz = /bits/ 64 <450000000>; + opp-microvolt = <1150000>; + }; + opp@400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <1125000>; + }; + opp@350000000 { + opp-hz = /bits/ 64 <350000000>; + opp-microvolt = <1075000>; + }; + opp@266000000 { + opp-hz = /bits/ 64 <266000000>; + opp-microvolt = <1025000>; + }; + opp@160000000 { + opp-hz = /bits/ 64 <160000000>; + opp-microvolt = <925000>; + }; + opp@100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <912500>; + }; +}; diff --git a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt index dedfb02c744a..a2cf5e1c87d8 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt @@ -7,6 +7,20 @@ This file documents differences between the core properties described by mmc.txt and the properties used by the sdhci-esdhc driver. Required properties: + - compatible : should be "fsl,esdhc", or "fsl,<chip>-esdhc". + Possible compatibles for PowerPC: + "fsl,mpc8536-esdhc" + "fsl,mpc8378-esdhc" + "fsl,p2020-esdhc" + "fsl,p4080-esdhc" + "fsl,t1040-esdhc" + "fsl,t4240-esdhc" + Possible compatibles for ARM: + "fsl,ls1012a-esdhc" + "fsl,ls1088a-esdhc" + "fsl,ls1043a-esdhc" + "fsl,ls1046a-esdhc" + "fsl,ls2080a-esdhc" - interrupt-parent : interrupt source phandle. - clock-frequency : specifies eSDHC base clock frequency. diff --git a/Documentation/devicetree/bindings/net/dsa/marvell.txt b/Documentation/devicetree/bindings/net/dsa/marvell.txt index 7ef9dbb08957..1d4d0f49c9d0 100644 --- a/Documentation/devicetree/bindings/net/dsa/marvell.txt +++ b/Documentation/devicetree/bindings/net/dsa/marvell.txt @@ -26,6 +26,10 @@ Optional properties: - interrupt-controller : Indicates the switch is itself an interrupt controller. This is used for the PHY interrupts. #interrupt-cells = <2> : Controller uses two cells, number and flag +- eeprom-length : Set to the length of an EEPROM connected to the + switch. Must be set if the switch can not detect + the presence and/or size of a connected EEPROM, + otherwise optional. - mdio : Container of PHY and devices on the switches MDIO bus. - mdio? : Container of PHYs and devices on the external MDIO diff --git a/Documentation/devicetree/bindings/pci/faraday,ftpci100.txt b/Documentation/devicetree/bindings/pci/faraday,ftpci100.txt index 35d4a979bb7b..89a84f8aa621 100644 --- a/Documentation/devicetree/bindings/pci/faraday,ftpci100.txt +++ b/Documentation/devicetree/bindings/pci/faraday,ftpci100.txt @@ -30,6 +30,13 @@ Mandatory properties: 128MB, 256MB, 512MB, 1GB or 2GB in size. The memory should be marked as pre-fetchable. +Optional properties: +- clocks: when present, this should contain the peripheral clock (PCLK) and the + PCI clock (PCICLK). If these are not present, they are assumed to be + hard-wired enabled and always on. The PCI clock will be 33 or 66 MHz. +- clock-names: when present, this should contain "PCLK" for the peripheral + clock and "PCICLK" for the PCI-side clock. + Mandatory subnodes: - For "faraday,ftpci100" a node representing the interrupt-controller inside the host bridge is mandatory. It has the following mandatory properties: diff --git a/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt new file mode 100644 index 000000000000..fe80dda9bf73 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt @@ -0,0 +1,130 @@ +MediaTek Gen2 PCIe controller which is available on MT7623 series SoCs + +PCIe subsys supports single root complex (RC) with 3 Root Ports. Each root +ports supports a Gen2 1-lane Link and has PIPE interface to PHY. + +Required properties: +- compatible: Should contain "mediatek,mt7623-pcie". +- device_type: Must be "pci" +- reg: Base addresses and lengths of the PCIe controller. +- #address-cells: Address representation for root ports (must be 3) +- #size-cells: Size representation for root ports (must be 2) +- #interrupt-cells: Size representation for interrupts (must be 1) +- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties + Please refer to the standard PCI bus binding document for a more detailed + explanation. +- clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names: Must include the following entries: + - free_ck :for reference clock of PCIe subsys + - sys_ck0 :for clock of Port0 + - sys_ck1 :for clock of Port1 + - sys_ck2 :for clock of Port2 +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the following entries: + - pcie-rst0 :port0 reset + - pcie-rst1 :port1 reset + - pcie-rst2 :port2 reset +- phys: List of PHY specifiers (used by generic PHY framework). +- phy-names : Must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the + number of PHYs as specified in *phys* property. +- power-domains: A phandle and power domain specifier pair to the power domain + which is responsible for collapsing and restoring power to the peripheral. +- bus-range: Range of bus numbers associated with this controller. +- ranges: Ranges for the PCI memory and I/O regions. + +In addition, the device tree node must have sub-nodes describing each +PCIe port interface, having the following mandatory properties: + +Required properties: +- device_type: Must be "pci" +- reg: Only the first four bytes are used to refer to the correct bus number + and device number. +- #address-cells: Must be 3 +- #size-cells: Must be 2 +- #interrupt-cells: Must be 1 +- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties + Please refer to the standard PCI bus binding document for a more detailed + explanation. +- ranges: Sub-ranges distributed from the PCIe controller node. An empty + property is sufficient. +- num-lanes: Number of lanes to use for this port. + +Examples: + + hifsys: syscon@1a000000 { + compatible = "mediatek,mt7623-hifsys", + "mediatek,mt2701-hifsys", + "syscon"; + reg = <0 0x1a000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pcie: pcie-controller@1a140000 { + compatible = "mediatek,mt7623-pcie"; + device_type = "pci"; + reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */ + <0 0x1a142000 0 0x1000>, /* Port0 registers */ + <0 0x1a143000 0 0x1000>, /* Port1 registers */ + <0 0x1a144000 0 0x1000>; /* Port2 registers */ + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xf800 0 0 0>; + interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, + <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, + <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_ETHIF_SEL>, + <&hifsys CLK_HIFSYS_PCIE0>, + <&hifsys CLK_HIFSYS_PCIE1>, + <&hifsys CLK_HIFSYS_PCIE2>; + clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; + resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, + <&hifsys MT2701_HIFSYS_PCIE1_RST>, + <&hifsys MT2701_HIFSYS_PCIE2_RST>; + reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; + phys = <&pcie0_phy>, <&pcie1_phy>, <&pcie2_phy>; + phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; + bus-range = <0x00 0xff>; + ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* I/O space */ + 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* memory space */ + + pcie@0,0 { + device_type = "pci"; + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; + ranges; + num-lanes = <1>; + }; + + pcie@1,0 { + device_type = "pci"; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; + ranges; + num-lanes = <1>; + }; + + pcie@2,0 { + device_type = "pci"; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; + ranges; + num-lanes = <1>; + }; + }; diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt index e15f9b19901f..9d418b71774f 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt @@ -8,6 +8,7 @@ - "qcom,pcie-apq8064" for apq8064 - "qcom,pcie-apq8084" for apq8084 - "qcom,pcie-msm8996" for msm8996 or apq8096 + - "qcom,pcie-ipq4019" for ipq4019 - reg: Usage: required @@ -87,7 +88,7 @@ - "core" Clocks the pcie hw block - "phy" Clocks the pcie PHY block - clock-names: - Usage: required for apq8084 + Usage: required for apq8084/ipq4019 Value type: <stringlist> Definition: Should contain the following entries - "aux" Auxiliary (AUX) clock @@ -126,6 +127,23 @@ Definition: Should contain the following entries - "core" Core reset +- reset-names: + Usage: required for ipq/apq8064 + Value type: <stringlist> + Definition: Should contain the following entries + - "axi_m" AXI master reset + - "axi_s" AXI slave reset + - "pipe" PIPE reset + - "axi_m_vmid" VMID reset + - "axi_s_xpu" XPU reset + - "parf" PARF reset + - "phy" PHY reset + - "axi_m_sticky" AXI sticky reset + - "pipe_sticky" PIPE sticky reset + - "pwr" PWR reset + - "ahb" AHB reset + - "phy_ahb" PHY AHB reset + - power-domains: Usage: required for apq8084 and msm8996/apq8096 Value type: <prop-encoded-array> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt index 71a3c134af1b..f01d154090da 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt @@ -247,7 +247,6 @@ bias-bus-hold - latch weakly bias-pull-up - pull up the pin bias-pull-down - pull down the pin bias-pull-pin-default - use pin-default pull state -bi-directional - pin supports simultaneous input/output operations drive-push-pull - drive actively high and low drive-open-drain - drive with open drain drive-open-source - drive with open source @@ -260,7 +259,6 @@ input-debounce - debounce mode with debound time X power-source - select between different power supplies low-power-enable - enable low power mode low-power-disable - disable low power mode -output-enable - enable output on pin regardless of output value output-low - set the pin to output mode with low level output-high - set the pin to output mode with high level slew-rate - set the slew rate diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index c03d20140366..b10fe16cdaa1 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -165,6 +165,7 @@ keithkoep Keith & Koep GmbH keymile Keymile GmbH khadas Khadas kinetic Kinetic Technologies +kingnovel Kingnovel Technology Co., Ltd. kosagi Sutajio Ko-Usagi PTE Ltd. kyo Kyocera Corporation lacie LaCie @@ -356,6 +357,7 @@ xlnx Xilinx xunlong Shenzhen Xunlong Software CO.,Limited zarlink Zarlink Semiconductor zeitec ZEITEC Semiconductor Co., LTD. +zidoo Shenzhen Zidoo Technology Co., Ltd. zii Zodiac Inflight Innovations zte ZTE Corp. zyxel ZyXEL Communications Corp. diff --git a/Documentation/networking/dpaa.txt b/Documentation/networking/dpaa.txt new file mode 100644 index 000000000000..76e016d4d344 --- /dev/null +++ b/Documentation/networking/dpaa.txt @@ -0,0 +1,194 @@ +The QorIQ DPAA Ethernet Driver +============================== + +Authors: +Madalin Bucur <madalin.bucur@nxp.com> +Camelia Groza <camelia.groza@nxp.com> + +Contents +======== + + - DPAA Ethernet Overview + - DPAA Ethernet Supported SoCs + - Configuring DPAA Ethernet in your kernel + - DPAA Ethernet Frame Processing + - DPAA Ethernet Features + - Debugging + +DPAA Ethernet Overview +====================== + +DPAA stands for Data Path Acceleration Architecture and it is a +set of networking acceleration IPs that are available on several +generations of SoCs, both on PowerPC and ARM64. + +The Freescale DPAA architecture consists of a series of hardware blocks +that support Ethernet connectivity. The Ethernet driver depends upon the +following drivers in the Linux kernel: + + - Peripheral Access Memory Unit (PAMU) (* needed only for PPC platforms) + drivers/iommu/fsl_* + - Frame Manager (FMan) + drivers/net/ethernet/freescale/fman + - Queue Manager (QMan), Buffer Manager (BMan) + drivers/soc/fsl/qbman + +A simplified view of the dpaa_eth interfaces mapped to FMan MACs: + + dpaa_eth /eth0\ ... /ethN\ + driver | | | | + ------------- ---- ----------- ---- ------------- + -Ports / Tx Rx \ ... / Tx Rx \ + FMan | | | | + -MACs | MAC0 | | MACN | + / dtsec0 \ ... / dtsecN \ (or tgec) + / \ / \(or memac) + --------- -------------- --- -------------- --------- + FMan, FMan Port, FMan SP, FMan MURAM drivers + --------------------------------------------------------- + FMan HW blocks: MURAM, MACs, Ports, SP + --------------------------------------------------------- + +The dpaa_eth relation to the QMan, BMan and FMan: + ________________________________ + dpaa_eth / eth0 \ + driver / \ + --------- -^- -^- -^- --- --------- + QMan driver / \ / \ / \ \ / | BMan | + |Rx | |Rx | |Tx | |Tx | | driver | + --------- |Dfl| |Err| |Cnf| |FQs| | | + QMan HW |FQ | |FQ | |FQs| | | | | + / \ / \ / \ \ / | | + --------- --- --- --- -v- --------- + | FMan QMI | | + | FMan HW FMan BMI | BMan HW | + ----------------------- -------- + +where the acronyms used above (and in the code) are: +DPAA = Data Path Acceleration Architecture +FMan = DPAA Frame Manager +QMan = DPAA Queue Manager +BMan = DPAA Buffers Manager +QMI = QMan interface in FMan +BMI = BMan interface in FMan +FMan SP = FMan Storage Profiles +MURAM = Multi-user RAM in FMan +FQ = QMan Frame Queue +Rx Dfl FQ = default reception FQ +Rx Err FQ = Rx error frames FQ +Tx Cnf FQ = Tx confirmation FQs +Tx FQs = transmission frame queues +dtsec = datapath three speed Ethernet controller (10/100/1000 Mbps) +tgec = ten gigabit Ethernet controller (10 Gbps) +memac = multirate Ethernet MAC (10/100/1000/10000) + +DPAA Ethernet Supported SoCs +============================ + +The DPAA drivers enable the Ethernet controllers present on the following SoCs: + +# PPC +P1023 +P2041 +P3041 +P4080 +P5020 +P5040 +T1023 +T1024 +T1040 +T1042 +T2080 +T4240 +B4860 + +# ARM +LS1043A +LS1046A + +Configuring DPAA Ethernet in your kernel +======================================== + +To enable the DPAA Ethernet driver, the following Kconfig options are required: + +# common for arch/arm64 and arch/powerpc platforms +CONFIG_FSL_DPAA=y +CONFIG_FSL_FMAN=y +CONFIG_FSL_DPAA_ETH=y +CONFIG_FSL_XGMAC_MDIO=y + +# for arch/powerpc only +CONFIG_FSL_PAMU=y + +# common options needed for the PHYs used on the RDBs +CONFIG_VITESSE_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_AQUANTIA_PHY=y + +DPAA Ethernet Frame Processing +============================== + +On Rx, buffers for the incoming frames are retrieved from one of the three +existing buffers pools. The driver initializes and seeds these, each with +buffers of different sizes: 1KB, 2KB and 4KB. + +On Tx, all transmitted frames are returned to the driver through Tx +confirmation frame queues. The driver is then responsible for freeing the +buffers. In order to do this properly, a backpointer is added to the buffer +before transmission that points to the skb. When the buffer returns to the +driver on a confirmation FQ, the skb can be correctly consumed. + +DPAA Ethernet Features +====================== + +Currently the DPAA Ethernet driver enables the basic features required for +a Linux Ethernet driver. The support for advanced features will be added +gradually. + +The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx +checksum offload feature is enabled by default and cannot be controlled through +ethtool. + +The driver has support for multiple prioritized Tx traffic classes. Priorities +range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with +strict priority levels. Each traffic class contains NR_CPU TX queues. By +default, only one traffic class is enabled and the lowest priority Tx queues +are used. Higher priority traffic classes can be enabled with the mqprio +qdisc. For example, all four traffic classes are enabled on an interface with +the following command. Furthermore, skb priority levels are mapped to traffic +classes as follows: + + * priorities 0 to 3 - traffic class 0 (low priority) + * priorities 4 to 7 - traffic class 1 (medium-low priority) + * priorities 8 to 11 - traffic class 2 (medium-high priority) + * priorities 12 to 15 - traffic class 3 (high priority) + +tc qdisc add dev <int> root handle 1: \ + mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1 + +Debugging +========= + +The following statistics are exported for each interface through ethtool: + + - interrupt count per CPU + - Rx packets count per CPU + - Tx packets count per CPU + - Tx confirmed packets count per CPU + - Tx S/G frames count per CPU + - Tx error count per CPU + - Rx error count per CPU + - Rx error count per type + - congestion related statistics: + - congestion status + - time spent in congestion + - number of time the device entered congestion + - dropped packets count per cause + +The driver also exports the following information in sysfs: + + - the FQ IDs for each FQ type + /sys/devices/platform/dpaa-ethernet.0/net/<int>/fqids + + - the IDs of the buffer pools in use + /sys/devices/platform/dpaa-ethernet.0/net/<int>/bpids diff --git a/MAINTAINERS b/MAINTAINERS index 34b0324d53c5..31631bc18861 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1489,13 +1489,15 @@ M: Gregory Clement <gregory.clement@free-electrons.com> M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained -F: arch/arm/mach-mvebu/ -F: drivers/rtc/rtc-armada38x.c F: arch/arm/boot/dts/armada* F: arch/arm/boot/dts/kirkwood* +F: arch/arm/configs/mvebu_*_defconfig +F: arch/arm/mach-mvebu/ F: arch/arm64/boot/dts/marvell/armada* F: drivers/cpufreq/mvebu-cpufreq.c -F: arch/arm/configs/mvebu_*_defconfig +F: drivers/irqchip/irq-armada-370-xp.c +F: drivers/irqchip/irq-mvebu-* +F: drivers/rtc/rtc-armada38x.c ARM/Marvell Berlin SoC support M: Jisheng Zhang <jszhang@marvell.com> @@ -1677,6 +1679,13 @@ M: Lennert Buytenhek <kernel@wantstofly.org> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained +ARM/REALTEK ARCHITECTURE +M: Andreas Färber <afaerber@suse.de> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm64/boot/dts/realtek/ +F: Documentation/devicetree/bindings/arm/realtek.txt + ARM/RENESAS ARM64 ARCHITECTURE M: Simon Horman <horms@verge.net.au> M: Magnus Damm <magnus.damm@gmail.com> @@ -1721,7 +1730,6 @@ N: rockchip ARM/SAMSUNG EXYNOS ARM ARCHITECTURES M: Kukjin Kim <kgene@kernel.org> M: Krzysztof Kozlowski <krzk@kernel.org> -R: Javier Martinez Canillas <javier@osg.samsung.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/ @@ -1843,8 +1851,8 @@ F: drivers/i2c/busses/i2c-st.c F: drivers/media/rc/st_rc.c F: drivers/media/platform/sti/c8sectpfe/ F: drivers/mmc/host/sdhci-st.c -F: drivers/phy/phy-miphy28lp.c -F: drivers/phy/phy-stih407-usb.c +F: drivers/phy/st/phy-miphy28lp.c +F: drivers/phy/st/phy-stih407-usb.c F: drivers/pinctrl/pinctrl-st.c F: drivers/remoteproc/st_remoteproc.c F: drivers/remoteproc/st_slim_rproc.c @@ -2685,7 +2693,6 @@ N: kona F: arch/arm/mach-bcm/ BROADCOM BCM2835 ARM ARCHITECTURE -M: Lee Jones <lee@kernel.org> M: Eric Anholt <eric@anholt.net> M: Stefan Wahren <stefan.wahren@i2se.com> L: linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers) @@ -5622,7 +5629,7 @@ F: scripts/get_maintainer.pl GENWQE (IBM Generic Workqueue Card) M: Frank Haverkamp <haver@linux.vnet.ibm.com> -M: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com> +M: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com> S: Supported F: drivers/misc/genwqe/ @@ -8509,7 +8516,7 @@ S: Odd Fixes F: drivers/media/radio/radio-miropcm20* MELLANOX MLX4 core VPI driver -M: Yishai Hadas <yishaih@mellanox.com> +M: Tariq Toukan <tariqt@mellanox.com> L: netdev@vger.kernel.org L: linux-rdma@vger.kernel.org W: http://www.mellanox.com @@ -8517,7 +8524,6 @@ Q: http://patchwork.ozlabs.org/project/netdev/list/ S: Supported F: drivers/net/ethernet/mellanox/mlx4/ F: include/linux/mlx4/ -F: include/uapi/rdma/mlx4-abi.h MELLANOX MLX4 IB driver M: Yishai Hadas <yishaih@mellanox.com> @@ -8527,6 +8533,7 @@ Q: http://patchwork.kernel.org/project/linux-rdma/list/ S: Supported F: drivers/infiniband/hw/mlx4/ F: include/linux/mlx4/ +F: include/uapi/rdma/mlx4-abi.h MELLANOX MLX5 core VPI driver M: Saeed Mahameed <saeedm@mellanox.com> @@ -8539,7 +8546,6 @@ Q: http://patchwork.ozlabs.org/project/netdev/list/ S: Supported F: drivers/net/ethernet/mellanox/mlx5/core/ F: include/linux/mlx5/ -F: include/uapi/rdma/mlx5-abi.h MELLANOX MLX5 IB driver M: Matan Barak <matanb@mellanox.com> @@ -8550,6 +8556,7 @@ Q: http://patchwork.kernel.org/project/linux-rdma/list/ S: Supported F: drivers/infiniband/hw/mlx5/ F: include/linux/mlx5/ +F: include/uapi/rdma/mlx5-abi.h MELEXIS MLX90614 DRIVER M: Crt Mori <cmo@melexis.com> @@ -10837,7 +10844,7 @@ RENESAS USB2 PHY DRIVER M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> L: linux-renesas-soc@vger.kernel.org S: Maintained -F: drivers/phy/phy-rcar-gen3-usb2.c +F: drivers/phy/renesas/phy-rcar-gen3-usb2.c RESET CONTROLLER FRAMEWORK M: Philipp Zabel <p.zabel@pengutronix.de> @@ -11239,12 +11246,12 @@ L: linux-kernel@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/phy/samsung-phy.txt F: Documentation/phy/samsung-usb2.txt -F: drivers/phy/phy-exynos4210-usb2.c -F: drivers/phy/phy-exynos4x12-usb2.c -F: drivers/phy/phy-exynos5250-usb2.c -F: drivers/phy/phy-s5pv210-usb2.c -F: drivers/phy/phy-samsung-usb2.c -F: drivers/phy/phy-samsung-usb2.h +F: drivers/phy/samsung/phy-exynos4210-usb2.c +F: drivers/phy/samsung/phy-exynos4x12-usb2.c +F: drivers/phy/samsung/phy-exynos5250-usb2.c +F: drivers/phy/samsung/phy-s5pv210-usb2.c +F: drivers/phy/samsung/phy-samsung-usb2.c +F: drivers/phy/samsung/phy-samsung-usb2.h SERIAL DRIVERS M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index a867575a758b..3329d0dd171b 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -1092,8 +1092,8 @@ noinline void __init arc_ioc_setup(void) if (read_aux_reg(ARC_REG_SLC_BCR)) slc_entire_op(OP_FLUSH_N_INV); - /* IOC Aperture start: TDB: handle non default CONFIG_LINUX_LINK_BASE */ - write_aux_reg(ARC_REG_IO_COH_AP0_BASE, 0x80000); + /* IOC Aperture start */ + write_aux_reg(ARC_REG_IO_COH_AP0_BASE, CONFIG_LINUX_LINK_BASE >> 12); /* * IOC Aperture size: diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 426d2716f55d..b3677d1d07fc 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -776,6 +776,30 @@ choice their output to the standard serial port on the RealView PB1176 platform. + config DEBUG_RV1108_UART0 + bool "Kernel low-level debugging messages via Rockchip RV1108 UART0" + depends on ARCH_ROCKCHIP + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Rockchip RV1108 based platforms. + + config DEBUG_RV1108_UART1 + bool "Kernel low-level debugging messages via Rockchip RV1108 UART1" + depends on ARCH_ROCKCHIP + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Rockchip RV1108 based platforms. + + config DEBUG_RV1108_UART2 + bool "Kernel low-level debugging messages via Rockchip RV1108 UART2" + depends on ARCH_ROCKCHIP + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Rockchip RV1108 based platforms. + config DEBUG_RK29_UART0 bool "Kernel low-level debugging messages via Rockchip RK29 UART0" depends on ARCH_ROCKCHIP @@ -1465,6 +1489,9 @@ config DEBUG_UART_PHYS default 0x10126000 if DEBUG_RK3X_UART1 default 0x101f1000 if DEBUG_VERSATILE default 0x101fb000 if DEBUG_NOMADIK_UART + default 0x10210000 if DEBUG_RV1108_UART2 + default 0x10220000 if DEBUG_RV1108_UART1 + default 0x10230000 if DEBUG_RV1108_UART0 default 0x11002000 if DEBUG_MT8127_UART0 default 0x11006000 if DEBUG_MT6589_UART0 default 0x11009000 if DEBUG_MT8135_UART3 @@ -1563,6 +1590,9 @@ config DEBUG_UART_PHYS config DEBUG_UART_VIRT hex "Virtual base address of debug UART" + default 0xc881f000 if DEBUG_RV1108_UART2 + default 0xc8821000 if DEBUG_RV1108_UART1 + default 0xc8912000 if DEBUG_RV1108_UART0 default 0xe0000a00 if DEBUG_NETX_UART default 0xe0010fe0 if ARCH_RPC default 0xf0000be0 if ARCH_EBSA110 diff --git a/arch/arm/arm-soc-for-next-contents.txt b/arch/arm/arm-soc-for-next-contents.txt new file mode 100644 index 000000000000..239a650bd52f --- /dev/null +++ b/arch/arm/arm-soc-for-next-contents.txt @@ -0,0 +1,36 @@ +fixes + patch + ARM: omap2+: make omap4_get_cpu1_ns_pa_addr declaration usable + <no branch> (1c0803652d82b9a62980886e019c9f70576028a5) + https://github.com/mbgg/linux-mediatek tags/v4.11-next-fixes + <no branch> (7b4ccb3c466f62bbf2f4dd5d6a143d945a6f3051) + https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-fixes-for-v4.12 + <no branch> (6a680783aaadd168557eec695374929ac066536f) + git://git.infradead.org/linux-mvebu tags/mvebu-dt64-4.12-3 + <no branch> (d2718d1365f7fce624fd7ed163f60532f92ed016) + git://git.infradead.org/linux-mvebu tags/mvebu-arm64-4.12-1 + tee/initial-merge + Merge branch 'tee/initial-merge' into fixes + patch + tee: add ARM_SMCCC dependency + <no branch> (2ea659a9ef488125eb46da6eb571de5eae5c43f6) + Merge tag 'v4.12-rc1' into fixes + contains next/tee + patch + devicetree: Move include prefixes from arch to separate directory + <no branch> (b155f05dc578299557447a6fd6545ebc72c1d19b) + http://github.com/Broadcom/stblinux tags/arm-soc/for-4.12/devicetree-fixes + <no branch> (31d848aa1d85530770f0bdf1b61a042335d340ad) + http://github.com/Broadcom/stblinux tags/arm-soc/for-4.12/drivers-fixes + patch + ARM: configs: add a gemini defconfig + arm64: defconfig: sync with savedefconfig + arm64: defconfig: enable options needed for QCom DB410c board + <no branch> (e23c7f7d57831fdae444be9d507e67716ab601d4) + git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-fixes-4.12 + <no branch> (bca5238816939436d72ae6bab124c4b0641a3a99) + git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.12/fixes-v2-signed + patch + ARM: remove duplicate 'const' annotations' + firmware: ti_sci: fix strncat length check + ARM: dts: keystone-k2l: fix broken Ethernet due to disabled OSR diff --git a/arch/arm/boot/compressed/efi-header.S b/arch/arm/boot/compressed/efi-header.S index 9d5dc4fda3c1..3f7d1b74c5e0 100644 --- a/arch/arm/boot/compressed/efi-header.S +++ b/arch/arm/boot/compressed/efi-header.S @@ -17,14 +17,12 @@ @ there. .inst 'M' | ('Z' << 8) | (0x1310 << 16) @ tstne r0, #0x4d000 #else - mov r0, r0 + W(mov) r0, r0 #endif .endm .macro __EFI_HEADER #ifdef CONFIG_EFI_STUB - b __efi_start - .set start_offset, __efi_start - start .org start + 0x3c @ diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 7c711ba61417..8a756870c238 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -130,19 +130,22 @@ start: .rept 7 __nop .endr - ARM( mov r0, r0 ) - ARM( b 1f ) - THUMB( badr r12, 1f ) - THUMB( bx r12 ) +#ifndef CONFIG_THUMB2_KERNEL + mov r0, r0 +#else + AR_CLASS( sub pc, pc, #3 ) @ A/R: switch to Thumb2 mode + M_CLASS( nop.w ) @ M: already in Thumb2 mode + .thumb +#endif + W(b) 1f .word _magic_sig @ Magic numbers to help the loader .word _magic_start @ absolute load/run zImage address .word _magic_end @ zImage end address .word 0x04030201 @ endianness flag - THUMB( .thumb ) -1: __EFI_HEADER - + __EFI_HEADER +1: ARM_BE8( setend be ) @ go BE8 if compiled for BE8 AR_CLASS( mrs r9, cpsr ) #ifdef CONFIG_ARM_VIRT_EXT diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 9c5e1d944d1c..3bd29feb8298 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -72,6 +72,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ bcm2835-rpi-b-plus.dtb \ bcm2835-rpi-a-plus.dtb \ bcm2836-rpi-2-b.dtb \ + bcm2837-rpi-3-b.dtb \ bcm2835-rpi-zero.dtb dtb-$(CONFIG_ARCH_BCM_5301X) += \ bcm4708-asus-rt-ac56u.dtb \ @@ -204,7 +205,8 @@ dtb-$(CONFIG_ARCH_KEYSTONE) += \ keystone-k2hk-evm.dtb \ keystone-k2l-evm.dtb \ keystone-k2e-evm.dtb \ - keystone-k2g-evm.dtb + keystone-k2g-evm.dtb \ + keystone-k2g-ice.dtb dtb-$(CONFIG_MACH_KIRKWOOD) += \ kirkwood-b3.dtb \ kirkwood-blackarmor-nas220.dtb \ @@ -363,6 +365,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6dl-gw551x.dtb \ imx6dl-gw552x.dtb \ imx6dl-gw553x.dtb \ + imx6dl-gw560x.dtb \ imx6dl-gw5903.dtb \ imx6dl-gw5904.dtb \ imx6dl-hummingboard.dtb \ @@ -408,6 +411,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6q-gw551x.dtb \ imx6q-gw552x.dtb \ imx6q-gw553x.dtb \ + imx6q-gw560x.dtb \ imx6q-gw5903.dtb \ imx6q-gw5904.dtb \ imx6q-h100.dtb \ @@ -476,6 +480,7 @@ dtb-$(CONFIG_SOC_IMX7D) += \ imx7d-cl-som-imx7.dtb \ imx7d-colibri-eval-v3.dtb \ imx7d-nitrogen7.dtb \ + imx7d-pico.dtb \ imx7d-sbc-imx7.dtb \ imx7d-sdb.dtb \ imx7d-sdb-sht11.dtb \ @@ -701,6 +706,7 @@ dtb-$(CONFIG_ARCH_REALVIEW) += \ dtb-$(CONFIG_ARCH_RENESAS) += \ emev2-kzm9d.dtb \ r7s72100-genmai.dtb \ + r7s72100-gr-peach.dtb \ r7s72100-rskrza1.dtb \ r8a73a4-ape6evm.dtb \ r8a7740-armadillo800eva.dtb \ @@ -718,7 +724,7 @@ dtb-$(CONFIG_ARCH_RENESAS) += \ r8a7794-silk.dtb \ sh73a0-kzm9g.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += \ - rk1108-evb.dtb \ + rv1108-evb.dtb \ rk3036-evb.dtb \ rk3036-kylin.dtb \ rk3066a-bqcurie2.dtb \ @@ -905,7 +911,8 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-h3-orangepi-plus.dtb \ sun8i-h3-orangepi-plus2e.dtb \ sun8i-r16-parrot.dtb \ - sun8i-v3s-licheepi-zero.dtb + sun8i-v3s-licheepi-zero.dtb \ + sun8i-v3s-licheepi-zero-dock.dtb dtb-$(CONFIG_MACH_SUN9I) += \ sun9i-a80-optimus.dtb \ sun9i-a80-cubieboard4.dtb @@ -999,6 +1006,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \ armada-385-db-ap.dtb \ armada-385-linksys-caiman.dtb \ armada-385-linksys-cobra.dtb \ + armada-385-linksys-rango.dtb \ armada-385-linksys-shelby.dtb \ armada-385-synology-ds116.dtb \ armada-385-turris-omnia.dtb \ diff --git a/arch/arm/boot/dts/am335x-baltos.dtsi b/arch/arm/boot/dts/am335x-baltos.dtsi index d42b98f15e8b..ec6052c521ef 100644 --- a/arch/arm/boot/dts/am335x-baltos.dtsi +++ b/arch/arm/boot/dts/am335x-baltos.dtsi @@ -255,7 +255,7 @@ }; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; pagesize = <8>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/am335x-base0033.dts b/arch/arm/boot/dts/am335x-base0033.dts index c2bee452dab8..29782be07605 100644 --- a/arch/arm/boot/dts/am335x-base0033.dts +++ b/arch/arm/boot/dts/am335x-base0033.dts @@ -89,7 +89,7 @@ &i2c0 { eeprom: eeprom@50 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x50>; }; }; diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index bf6b26abe35b..1d154444dfef 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -232,7 +232,7 @@ }; baseboard_eeprom: baseboard_eeprom@50 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x50>; #address-cells = <1>; @@ -251,7 +251,7 @@ clock-frequency = <100000>; cape_eeprom0: cape_eeprom0@54 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x54>; #address-cells = <1>; #size-cells = <1>; @@ -261,7 +261,7 @@ }; cape_eeprom1: cape_eeprom1@55 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x55>; #address-cells = <1>; #size-cells = <1>; @@ -271,7 +271,7 @@ }; cape_eeprom2: cape_eeprom2@56 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x56>; #address-cells = <1>; #size-cells = <1>; @@ -281,7 +281,7 @@ }; cape_eeprom3: cape_eeprom3@57 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x57>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/am335x-boneblack-wireless.dts b/arch/arm/boot/dts/am335x-boneblack-wireless.dts index 105bd10655f7..83f49f616b19 100644 --- a/arch/arm/boot/dts/am335x-boneblack-wireless.dts +++ b/arch/arm/boot/dts/am335x-boneblack-wireless.dts @@ -97,6 +97,11 @@ pinctrl-names = "default"; pinctrl-0 = <&uart3_pins &bt_pins>; status = "okay"; + + bluetooth { + compatible = "ti,wl1835-st"; + enable-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; + }; }; &gpio3 { diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts index 935ed17d22e4..d154d3133c16 100644 --- a/arch/arm/boot/dts/am335x-boneblack.dts +++ b/arch/arm/boot/dts/am335x-boneblack.dts @@ -22,7 +22,7 @@ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed * to support 1GHz OPP so enable it for PG 2.0 on this board. */ - oppnitro@1000000000 { + oppnitro-1000000000 { opp-supported-hw = <0x06 0x0100>; }; }; diff --git a/arch/arm/boot/dts/am335x-nano.dts b/arch/arm/boot/dts/am335x-nano.dts index 807494bc722b..946d7069f417 100644 --- a/arch/arm/boot/dts/am335x-nano.dts +++ b/arch/arm/boot/dts/am335x-nano.dts @@ -224,7 +224,7 @@ }; eeprom@53 { - compatible = "microchip,24c02"; + compatible = "microchip,24c02", "atmel,24c02"; reg = <0x53>; pagesize = <8>; }; diff --git a/arch/arm/boot/dts/am335x-pepper.dts b/arch/arm/boot/dts/am335x-pepper.dts index 30e2f8770aaf..03c7d77023c6 100644 --- a/arch/arm/boot/dts/am335x-pepper.dts +++ b/arch/arm/boot/dts/am335x-pepper.dts @@ -67,7 +67,7 @@ }; eeprom: eeprom@50 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/am335x-phycore-som.dtsi b/arch/arm/boot/dts/am335x-phycore-som.dtsi index 14533ff6d0ad..428a25e952b0 100644 --- a/arch/arm/boot/dts/am335x-phycore-som.dtsi +++ b/arch/arm/boot/dts/am335x-phycore-som.dtsi @@ -138,7 +138,7 @@ }; i2c_rtc: rtc@68 { - compatible = "rv4162"; + compatible = "microcrystal,rv4162"; reg = <0x68>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/am335x-shc.dts b/arch/arm/boot/dts/am335x-shc.dts index bf8727a19ece..4f6a286ea293 100644 --- a/arch/arm/boot/dts/am335x-shc.dts +++ b/arch/arm/boot/dts/am335x-shc.dts @@ -188,7 +188,7 @@ }; at24@50 { - compatible = "at24,24c32"; + compatible = "atmel,24c32"; pagesize = <32>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/am335x-sl50.dts b/arch/arm/boot/dts/am335x-sl50.dts index c5d2589c55fc..1bcc60424ecd 100644 --- a/arch/arm/boot/dts/am335x-sl50.dts +++ b/arch/arm/boot/dts/am335x-sl50.dts @@ -220,7 +220,7 @@ mmc1_pins: pinmux_mmc1_pins { pinctrl-single,pins = < - AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */ + AM33XX_IOPAD(0x96c, PIN_INPUT | MUX_MODE7) /* uart0_rtsn.gpio1_9 */ >; }; @@ -280,10 +280,6 @@ AM33XX_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE7) /* nKbdReset - gpmc_ad13.gpio1_13 */ AM33XX_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE7) /* nDispReset - gpmc_ad14.gpio1_14 */ AM33XX_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE7) /* USB1_enPower - gpmc_a1.gpio1_17 */ - /* AVR Programming - SPI Bus (bit bang) - Screen and Keyboard */ - AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE7) /* Kbd/Disp/BattMOSI spi0_d0.gpio0_3 */ - AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE7) /* Kbd/Disp/BattMISO spi0_d1.gpio0_4 */ - AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE7) /* Kbd/Disp/BattSCLK spi0_clk.gpio0_2 */ /* PDI Bus - Battery system */ AM33XX_IOPAD(0x840, PIN_INPUT_PULLUP | MUX_MODE7) /* nBattReset gpmc_a0.gpio1_16 */ AM33XX_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE7) /* BattPDIData gpmc_ad15.gpio1_15 */ @@ -309,7 +305,7 @@ }; eeprom: eeprom@50 { - compatible = "at,24c256"; + compatible = "atmel,24c256"; reg = <0x50>; }; @@ -384,7 +380,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; bus-width = <4>; - cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + cd-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; vmmc-supply = <&vmmcsd_fixed>; }; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 9e242943dcec..bdacb3dd689c 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -64,64 +64,64 @@ * because the can not be enabled simultaneously on a * single SoC. */ - opp50@300000000 { + opp50-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <950000 931000 969000>; opp-supported-hw = <0x06 0x0010>; opp-suspend; }; - opp100@275000000 { + opp100-275000000 { opp-hz = /bits/ 64 <275000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x01 0x00FF>; opp-suspend; }; - opp100@300000000 { + opp100-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x06 0x0020>; opp-suspend; }; - opp100@500000000 { + opp100-500000000 { opp-hz = /bits/ 64 <500000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x01 0xFFFF>; }; - opp100@600000000 { + opp100-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0x06 0x0040>; }; - opp120@600000000 { + opp120-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1200000 1176000 1224000>; opp-supported-hw = <0x01 0xFFFF>; }; - opp120@720000000 { + opp120-720000000 { opp-hz = /bits/ 64 <720000000>; opp-microvolt = <1200000 1176000 1224000>; opp-supported-hw = <0x06 0x0080>; }; - oppturbo@720000000 { + oppturbo-720000000 { opp-hz = /bits/ 64 <720000000>; opp-microvolt = <1260000 1234800 1285200>; opp-supported-hw = <0x01 0xFFFF>; }; - oppturbo@800000000 { + oppturbo-800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = <1260000 1234800 1285200>; opp-supported-hw = <0x06 0x0100>; }; - oppnitro@1000000000 { + oppnitro-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <1325000 1298500 1351500>; opp-supported-hw = <0x04 0x0200>; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 176e09e9a45e..e5b061469bf8 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -59,32 +59,32 @@ compatible = "operating-points-v2-ti-cpu"; syscon = <&scm_conf>; - opp50@300000000 { + opp50-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <950000 931000 969000>; opp-supported-hw = <0xFF 0x01>; opp-suspend; }; - opp100@600000000 { + opp100-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1100000 1078000 1122000>; opp-supported-hw = <0xFF 0x04>; }; - opp120@720000000 { + opp120-720000000 { opp-hz = /bits/ 64 <720000000>; opp-microvolt = <1200000 1176000 1224000>; opp-supported-hw = <0xFF 0x08>; }; - oppturbo@800000000 { + oppturbo-800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = <1260000 1234800 1285200>; opp-supported-hw = <0xFF 0x10>; }; - oppnitro@1000000000 { + oppnitro-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <1325000 1298500 1351500>; opp-supported-hw = <0xFF 0x20>; diff --git a/arch/arm/boot/dts/am437x-idk-evm.dts b/arch/arm/boot/dts/am437x-idk-evm.dts index c1f7f9336e64..5e364473067f 100644 --- a/arch/arm/boot/dts/am437x-idk-evm.dts +++ b/arch/arm/boot/dts/am437x-idk-evm.dts @@ -339,7 +339,7 @@ clock-frequency = <400000>; at24@50 { - compatible = "at24,24c256"; + compatible = "atmel,24c256"; pagesize = <64>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts index 4dc54bee2f36..a62e1583da04 100644 --- a/arch/arm/boot/dts/am437x-sk-evm.dts +++ b/arch/arm/boot/dts/am437x-sk-evm.dts @@ -511,7 +511,7 @@ }; at24@50 { - compatible = "at24,24c256"; + compatible = "atmel,24c256"; pagesize = <64>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index 9acd4ccdec4e..f6648ab10d29 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -477,7 +477,7 @@ }; at24@50 { - compatible = "at24,24c256"; + compatible = "atmel,24c256"; pagesize = <64>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/am43xx-clocks.dtsi b/arch/arm/boot/dts/am43xx-clocks.dtsi index d1d73b725f47..430be5829f8f 100644 --- a/arch/arm/boot/dts/am43xx-clocks.dtsi +++ b/arch/arm/boot/dts/am43xx-clocks.dtsi @@ -833,4 +833,40 @@ ti,bit-shift = <23>; reg = <0x4100>; }; + + clkout2_src_mux_ck: clkout2_src_mux_ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&clk_rc32k_ck>, <&sysclk_div>, <&dpll_ddr_m2_ck>, + <&dpll_per_m2_ck>, <&dpll_disp_m2_ck>, + <&dpll_mpu_m2_ck>, <&dpll_extdev_ck>; + reg = <0x4108>; + }; + + clkout2_pre_div_ck: clkout2_pre_div_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&clkout2_src_mux_ck>; + ti,bit-shift = <4>; + ti,max-div = <8>; + reg = <0x4108>; + }; + + clkout2_post_div_ck: clkout2_post_div_ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&clkout2_pre_div_ck>; + ti,bit-shift = <8>; + ti,max-div = <32>; + ti,index-power-of-two; + reg = <0x4108>; + }; + + clkout2_ck: clkout2_ck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&clkout2_post_div_ck>; + ti,bit-shift = <16>; + reg = <0x4108>; + }; }; diff --git a/arch/arm/boot/dts/am571x-idk.dts b/arch/arm/boot/dts/am571x-idk.dts index ad68d1eb3bc3..7b207835b2d1 100644 --- a/arch/arm/boot/dts/am571x-idk.dts +++ b/arch/arm/boot/dts/am571x-idk.dts @@ -79,3 +79,20 @@ id-gpio = <&gpio5 7 GPIO_ACTIVE_HIGH>; vbus-gpio = <&gpio7 22 GPIO_ACTIVE_HIGH>; }; + +&mailbox5 { + status = "okay"; + mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { + status = "okay"; + }; + mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { + status = "okay"; + }; +}; + +&mailbox6 { + status = "okay"; + mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { + status = "okay"; + }; +}; diff --git a/arch/arm/boot/dts/am572x-idk.dts b/arch/arm/boot/dts/am572x-idk.dts index 8350b4b34b08..9da6d83ca185 100644 --- a/arch/arm/boot/dts/am572x-idk.dts +++ b/arch/arm/boot/dts/am572x-idk.dts @@ -91,3 +91,23 @@ &pcie1 { gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; }; + +&mailbox5 { + status = "okay"; + mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { + status = "okay"; + }; + mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { + status = "okay"; + }; +}; + +&mailbox6 { + status = "okay"; + mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { + status = "okay"; + }; + mbox_dsp2_ipc3x: mbox_dsp2_ipc3x { + status = "okay"; + }; +}; diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi index 585d792a8fdd..fdfe5b16b806 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi +++ b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi @@ -388,7 +388,7 @@ }; eeprom: eeprom@50 { - compatible = "at,24c32"; + compatible = "atmel,24c32"; reg = <0x50>; }; }; diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index cc011c8bc36b..5e815ccf72e1 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -137,29 +137,38 @@ }; gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>, <90>; + clocks = <&coreclk 0>; }; gpio2: gpio@18180 { - compatible = "marvell,orion-gpio"; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; reg = <0x18180 0x40>; ngpios = <2>; gpio-controller; diff --git a/arch/arm/boot/dts/armada-385-linksys-caiman.dts b/arch/arm/boot/dts/armada-385-linksys-caiman.dts index f3cee918d285..ee669ae61011 100644 --- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts +++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts @@ -44,71 +44,128 @@ model = "Linksys WRT1200AC"; compatible = "linksys,caiman", "linksys,armada385", "marvell,armada385", "marvell,armada380"; +}; + +&expander0 { + wan_amber@0 { + label = "caiman:amber:wan"; + reg = <0x0>; + }; + + wan_white@1 { + label = "caiman:white:wan"; + reg = <0x1>; + }; + + wlan_2g@2 { + label = "caiman:white:wlan_2g"; + reg = <0x2>; + }; + + wlan_5g@3 { + label = "caiman:white:wlan_5g"; + reg = <0x3>; + }; + + usb2@5 { + label = "caiman:white:usb2"; + reg = <0x5>; + }; + + usb3_1@6 { + label = "caiman:white:usb3_1"; + reg = <0x6>; + }; + + usb3_2@7 { + label = "caiman:white:usb3_2"; + reg = <0x7>; + }; + + wps_white@8 { + label = "caiman:white:wps"; + reg = <0x8>; + }; + + wps_amber@9 { + label = "caiman:amber:wps"; + reg = <0x9>; + }; +}; + +&gpio_leds { + power { + label = "caiman:white:power"; + }; + + sata { + label = "caiman:white:sata"; + }; +}; + +&nand { + /* 128MiB */ + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x200000>; /* 2MiB */ + read-only; + }; + + partition@100000 { + label = "u_env"; + reg = <0x200000 0x40000>; /* 256KiB */ + }; + + partition@140000 { + label = "s_env"; + reg = <0x240000 0x40000>; /* 256KiB */ + }; + + partition@900000 { + label = "devinfo"; + reg = <0x900000 0x100000>; /* 1MiB */ + read-only; + }; + + /* kernel1 overlaps with rootfs1 by design */ + partition@a00000 { + label = "kernel1"; + reg = <0xa00000 0x2800000>; /* 40MiB */ + }; + + partition@1000000 { + label = "rootfs1"; + reg = <0x1000000 0x2200000>; /* 34MiB */ + }; + + /* kernel2 overlaps with rootfs2 by design */ + partition@3200000 { + label = "kernel2"; + reg = <0x3200000 0x2800000>; /* 40MiB */ + }; + + partition@3800000 { + label = "rootfs2"; + reg = <0x3800000 0x2200000>; /* 34MiB */ + }; + + /* + * 38MiB, last MiB is for the BBT, not writable + */ + partition@5a00000 { + label = "syscfg"; + reg = <0x5a00000 0x2600000>; + }; - soc { - internal-regs{ - i2c@11000 { - - pca9635@68 { - #address-cells = <1>; - #size-cells = <0>; - - wan_amber@0 { - label = "caiman:amber:wan"; - reg = <0x0>; - }; - - wan_white@1 { - label = "caiman:white:wan"; - reg = <0x1>; - }; - - wlan_2g@2 { - label = "caiman:white:wlan_2g"; - reg = <0x2>; - }; - - wlan_5g@3 { - label = "caiman:white:wlan_5g"; - reg = <0x3>; - }; - - usb2@5 { - label = "caiman:white:usb2"; - reg = <0x5>; - }; - - usb3_1@6 { - label = "caiman:white:usb3_1"; - reg = <0x6>; - }; - - usb3_2@7 { - label = "caiman:white:usb3_2"; - reg = <0x7>; - }; - - wps_white@8 { - label = "caiman:white:wps"; - reg = <0x8>; - }; - - wps_amber@9 { - label = "caiman:amber:wps"; - reg = <0x9>; - }; - }; - }; - }; - }; - - gpio-leds { - power { - label = "caiman:white:power"; - }; - - sata { - label = "caiman:white:sata"; - }; + /* + * Unused area between "s_env" and "devinfo". + * Moved here because otherwise the renumbered + * partitions would break the bootloader + * supplied bootargs + */ + partition@180000 { + label = "unused_area"; + reg = <0x280000 0x680000>; /* 6.5MiB */ }; }; diff --git a/arch/arm/boot/dts/armada-385-linksys-cobra.dts b/arch/arm/boot/dts/armada-385-linksys-cobra.dts index 111071860559..5169ca89c55a 100644 --- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts +++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts @@ -44,71 +44,128 @@ model = "Linksys WRT1900ACv2"; compatible = "linksys,cobra", "linksys,armada385", "marvell,armada385", "marvell,armada380"; +}; + +&expander0 { + wan_amber@0 { + label = "cobra:amber:wan"; + reg = <0x0>; + }; + + wan_white@1 { + label = "cobra:white:wan"; + reg = <0x1>; + }; + + wlan_2g@2 { + label = "cobra:white:wlan_2g"; + reg = <0x2>; + }; + + wlan_5g@3 { + label = "cobra:white:wlan_5g"; + reg = <0x3>; + }; + + usb2@5 { + label = "cobra:white:usb2"; + reg = <0x5>; + }; + + usb3_1@6 { + label = "cobra:white:usb3_1"; + reg = <0x6>; + }; + + usb3_2@7 { + label = "cobra:white:usb3_2"; + reg = <0x7>; + }; + + wps_white@8 { + label = "cobra:white:wps"; + reg = <0x8>; + }; + + wps_amber@9 { + label = "cobra:amber:wps"; + reg = <0x9>; + }; +}; + +&gpio_leds { + power { + label = "cobra:white:power"; + }; + + sata { + label = "cobra:white:sata"; + }; +}; + +&nand { + /* 128MiB */ + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x200000>; /* 2MiB */ + read-only; + }; + + partition@100000 { + label = "u_env"; + reg = <0x200000 0x40000>; /* 256KiB */ + }; + + partition@140000 { + label = "s_env"; + reg = <0x240000 0x40000>; /* 256KiB */ + }; + + partition@900000 { + label = "devinfo"; + reg = <0x900000 0x100000>; /* 1MiB */ + read-only; + }; + + /* kernel1 overlaps with rootfs1 by design */ + partition@a00000 { + label = "kernel1"; + reg = <0xa00000 0x2800000>; /* 40MiB */ + }; + + partition@1000000 { + label = "rootfs1"; + reg = <0x1000000 0x2200000>; /* 34MiB */ + }; + + /* kernel2 overlaps with rootfs2 by design */ + partition@3200000 { + label = "kernel2"; + reg = <0x3200000 0x2800000>; /* 40MiB */ + }; + + partition@3800000 { + label = "rootfs2"; + reg = <0x3800000 0x2200000>; /* 34MiB */ + }; + + /* + * 38MiB, last MiB is for the BBT, not writable + */ + partition@5a00000 { + label = "syscfg"; + reg = <0x5a00000 0x2600000>; + }; - soc { - internal-regs{ - i2c@11000 { - - pca9635@68 { - #address-cells = <1>; - #size-cells = <0>; - - wan_amber@0 { - label = "cobra:amber:wan"; - reg = <0x0>; - }; - - wan_white@1 { - label = "cobra:white:wan"; - reg = <0x1>; - }; - - wlan_2g@2 { - label = "cobra:white:wlan_2g"; - reg = <0x2>; - }; - - wlan_5g@3 { - label = "cobra:white:wlan_5g"; - reg = <0x3>; - }; - - usb2@5 { - label = "cobra:white:usb2"; - reg = <0x5>; - }; - - usb3_1@6 { - label = "cobra:white:usb3_1"; - reg = <0x6>; - }; - - usb3_2@7 { - label = "cobra:white:usb3_2"; - reg = <0x7>; - }; - - wps_white@8 { - label = "cobra:white:wps"; - reg = <0x8>; - }; - - wps_amber@9 { - label = "cobra:amber:wps"; - reg = <0x9>; - }; - }; - }; - }; - }; - - gpio-leds { - power { - label = "cobra:white:power"; - }; - - sata { - label = "cobra:white:sata"; - }; + /* + * Unused area between "s_env" and "devinfo". + * Moved here because otherwise the renumbered + * partitions would break the bootloader + * supplied bootargs + */ + partition@180000 { + label = "unused_area"; + reg = <0x280000 0x680000>; /* 6.5MiB */ }; }; diff --git a/arch/arm/boot/dts/armada-385-linksys-rango.dts b/arch/arm/boot/dts/armada-385-linksys-rango.dts new file mode 100644 index 000000000000..da8a0f3d432b --- /dev/null +++ b/arch/arm/boot/dts/armada-385-linksys-rango.dts @@ -0,0 +1,203 @@ +/* + * Device Tree file for the Linksys WRT3200ACM (Rango) + * + * Copyright (C) 2016 Imre Kaloz <kaloz@openwrt.org> + * + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without + * any warranty of any kind, whether express or implied. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include "armada-385-linksys.dtsi" + +/ { + model = "Linksys WRT3200ACM"; + compatible = "linksys,rango", "linksys,armada385", "marvell,armada385", + "marvell,armada380"; +}; + +&expander0 { + wan_amber@0 { + label = "rango:amber:wan"; + reg = <0x0>; + }; + + wan_white@1 { + label = "rango:white:wan"; + reg = <0x1>; + }; + + usb2@5 { + label = "rango:white:usb2"; + reg = <0x5>; + }; + + usb3_1@6 { + label = "rango:white:usb3_1"; + reg = <0x6>; + }; + + usb3_2@7 { + label = "rango:white:usb3_2"; + reg = <0x7>; + }; + + wps_white@8 { + label = "rango:white:wps"; + reg = <0x8>; + }; + + wps_amber@9 { + label = "rango:amber:wps"; + reg = <0x9>; + }; +}; + +&gpio_leds { + power { + gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; + label = "rango:white:power"; + }; + + sata { + gpios = <&gpio0 21 GPIO_ACTIVE_LOW>; + label = "rango:white:sata"; + }; + + wlan_2g { + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; + label = "rango:white:wlan_2g"; + }; + + wlan_5g { + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + label = "rango:white:wlan_5g"; + }; +}; + +&gpio_leds_pins { + marvell,pins = "mpp21", "mpp45", "mpp46", "mpp56"; +}; + +&nand { + /* AMD/Spansion S34ML02G2 256MiB, OEM Layout */ + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x200000>; /* 2MiB */ + read-only; + }; + + partition@200000 { + label = "u_env"; + reg = <0x200000 0x20000>; /* 128KiB */ + }; + + partition@220000 { + label = "s_env"; + reg = <0x220000 0x40000>; /* 256KiB */ + }; + + partition@7e0000 { + label = "devinfo"; + reg = <0x7e0000 0x40000>; /* 256KiB */ + read-only; + }; + + partition@820000 { + label = "sysdiag"; + reg = <0x820000 0x1e0000>; /* 1920KiB */ + read-only; + }; + + /* kernel1 overlaps with rootfs1 by design */ + partition@a00000 { + label = "kernel1"; + reg = <0xa00000 0x5000000>; /* 80MiB */ + }; + + partition@1000000 { + label = "rootfs1"; + reg = <0x1000000 0x4a00000>; /* 74MiB */ + }; + + /* kernel2 overlaps with rootfs2 by design */ + partition@5a00000 { + label = "kernel2"; + reg = <0x5a00000 0x5000000>; /* 80MiB */ + }; + + partition@6000000 { + label = "rootfs2"; + reg = <0x6000000 0x4a00000>; /* 74MiB */ + }; + + /* + * 86MiB, last MiB is for the BBT, not writable + */ + partition@aa00000 { + label = "syscfg"; + reg = <0xaa00000 0x5600000>; + }; + + /* + * Unused area between "s_env" and "devinfo". + * Moved here because otherwise the renumbered + * partitions would break the bootloader + * supplied bootargs + */ + partition@180000 { + label = "unused_area"; + reg = <0x260000 0x5c0000>; /* 5.75MiB */ + }; +}; + +&sdhci { + pinctrl-names = "default"; + pinctrl-0 = <&sdhci_pins>; + no-1-8-v; + non-removable; + wp-inverted; + bus-width = <8>; + status = "okay"; +}; + +&usb3_1_vbus { + gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>; +}; + +&usb3_1_vbus_pins { + marvell,pins = "mpp44"; +}; diff --git a/arch/arm/boot/dts/armada-385-linksys-shelby.dts b/arch/arm/boot/dts/armada-385-linksys-shelby.dts index c7a8ddd7f9a5..94aa35bc0bff 100644 --- a/arch/arm/boot/dts/armada-385-linksys-shelby.dts +++ b/arch/arm/boot/dts/armada-385-linksys-shelby.dts @@ -44,71 +44,128 @@ model = "Linksys WRT1900ACS"; compatible = "linksys,shelby", "linksys,armada385", "marvell,armada385", "marvell,armada380"; +}; + +&expander0 { + wan_amber@0 { + label = "shelby:amber:wan"; + reg = <0x0>; + }; + + wan_white@1 { + label = "shelby:white:wan"; + reg = <0x1>; + }; + + wlan_2g@2 { + label = "shelby:white:wlan_2g"; + reg = <0x2>; + }; + + wlan_5g@3 { + label = "shelby:white:wlan_5g"; + reg = <0x3>; + }; + + usb2@5 { + label = "shelby:white:usb2"; + reg = <0x5>; + }; + + usb3_1@6 { + label = "shelby:white:usb3_1"; + reg = <0x6>; + }; + + usb3_2@7 { + label = "shelby:white:usb3_2"; + reg = <0x7>; + }; + + wps_white@8 { + label = "shelby:white:wps"; + reg = <0x8>; + }; + + wps_amber@9 { + label = "shelby:amber:wps"; + reg = <0x9>; + }; +}; + +&gpio_leds { + power { + label = "shelby:white:power"; + }; + + sata { + label = "shelby:white:sata"; + }; +}; + +&nand { + /* 128MiB */ + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x200000>; /* 2MiB */ + read-only; + }; + + partition@100000 { + label = "u_env"; + reg = <0x200000 0x40000>; /* 256KiB */ + }; + + partition@140000 { + label = "s_env"; + reg = <0x240000 0x40000>; /* 256KiB */ + }; + + partition@900000 { + label = "devinfo"; + reg = <0x900000 0x100000>; /* 1MiB */ + read-only; + }; + + /* kernel1 overlaps with rootfs1 by design */ + partition@a00000 { + label = "kernel1"; + reg = <0xa00000 0x2800000>; /* 40MiB */ + }; + + partition@1000000 { + label = "rootfs1"; + reg = <0x1000000 0x2200000>; /* 34MiB */ + }; + + /* kernel2 overlaps with rootfs2 by design */ + partition@3200000 { + label = "kernel2"; + reg = <0x3200000 0x2800000>; /* 40MiB */ + }; + + partition@3800000 { + label = "rootfs2"; + reg = <0x3800000 0x2200000>; /* 34MiB */ + }; + + /* + * 38MiB, last MiB is for the BBT, not writable + */ + partition@5a00000 { + label = "syscfg"; + reg = <0x5a00000 0x2600000>; + }; - soc { - internal-regs{ - i2c@11000 { - - pca9635@68 { - #address-cells = <1>; - #size-cells = <0>; - - wan_amber@0 { - label = "shelby:amber:wan"; - reg = <0x0>; - }; - - wan_white@1 { - label = "shelby:white:wan"; - reg = <0x1>; - }; - - wlan_2g@2 { - label = "shelby:white:wlan_2g"; - reg = <0x2>; - }; - - wlan_5g@3 { - label = "shelby:white:wlan_5g"; - reg = <0x3>; - }; - - usb2@5 { - label = "shelby:white:usb2"; - reg = <0x5>; - }; - - usb3_1@6 { - label = "shelby:white:usb3_1"; - reg = <0x6>; - }; - - usb3_2@7 { - label = "shelby:white:usb3_2"; - reg = <0x7>; - }; - - wps_white@8 { - label = "shelby:white:wps"; - reg = <0x8>; - }; - - wps_amber@9 { - label = "shelby:amber:wps"; - reg = <0x9>; - }; - }; - }; - }; - }; - - gpio-leds { - power { - label = "shelby:white:power"; - }; - - sata { - label = "shelby:white:sata"; - }; + /* + * Unused area between "s_env" and "devinfo". + * Moved here because otherwise the renumbered + * partitions would break the bootloader + * supplied bootargs + */ + partition@180000 { + label = "unused_area"; + reg = <0x280000 0x680000>; /* 6.5MiB */ }; }; diff --git a/arch/arm/boot/dts/armada-385-linksys.dtsi b/arch/arm/boot/dts/armada-385-linksys.dtsi index 2306c45685b1..e1f355ffc8f7 100644 --- a/arch/arm/boot/dts/armada-385-linksys.dtsi +++ b/arch/arm/boot/dts/armada-385-linksys.dtsi @@ -52,7 +52,7 @@ memory { device_type = "memory"; - reg = <0x00000000 0x20000000>; /* 512 MB */ + reg = <0x00000000 0x20000000>; /* 512 MiB */ }; soc { @@ -61,255 +61,45 @@ MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000 MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; - - internal-regs { - i2c@11000 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; - status = "okay"; - - tmp421@4c { - compatible = "ti,tmp421"; - reg = <0x4c>; - }; - - pca9635@68 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nxp,pca9635"; - reg = <0x68>; - }; - }; - - /* J10: VCC, NC, RX, NC, TX, GND */ - serial@12000 { - status = "okay"; - }; - - ethernet@70000 { - status = "okay"; - phy-mode = "rgmii-id"; - buffer-manager = <&bm>; - bm,pool-long = <2>; - bm,pool-short = <3>; - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - - ethernet@34000 { - status = "okay"; - phy-mode = "sgmii"; - buffer-manager = <&bm>; - bm,pool-long = <0>; - bm,pool-short = <1>; - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - - mdio@72004 { - status = "okay"; - - switch@0 { - compatible = "marvell,mv88e6085"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - label = "lan4"; - }; - - port@1 { - reg = <1>; - label = "lan3"; - }; - - port@2 { - reg = <2>; - label = "lan2"; - }; - - port@3 { - reg = <3>; - label = "lan1"; - }; - - port@4 { - reg = <4>; - label = "wan"; - }; - - port@5 { - reg = <5>; - label = "cpu"; - ethernet = <ð2>; - - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - }; - }; - }; - - sata@a8000 { - status = "okay"; - }; - - bm@c8000 { - status = "okay"; - }; - - /* USB part of the eSATA/USB 2.0 port */ - usb@58000 { - status = "okay"; - }; - - usb3@f8000 { - status = "okay"; - usb-phy = <&usb3_phy>; - }; - - flash@d0000 { - status = "okay"; - num-cs = <1>; - marvell,nand-keep-config; - marvell,nand-enable-arbiter; - nand-on-flash-bbt; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x200000>; /* 2MB */ - read-only; - }; - - partition@100000 { - label = "u_env"; - reg = <0x200000 0x40000>; /* 256KB */ - }; - - partition@140000 { - label = "s_env"; - reg = <0x240000 0x40000>; /* 256KB */ - }; - - partition@900000 { - label = "devinfo"; - reg = <0x900000 0x100000>; /* 1MB */ - read-only; - }; - - /* kernel1 overlaps with rootfs1 by design */ - partition@a00000 { - label = "kernel1"; - reg = <0xa00000 0x2800000>; /* 40MB */ - }; - - partition@1000000 { - label = "rootfs1"; - reg = <0x1000000 0x2200000>; /* 34MB */ - }; - - /* kernel2 overlaps with rootfs2 by design */ - partition@3200000 { - label = "kernel2"; - reg = <0x3200000 0x2800000>; /* 40MB */ - }; - - partition@3800000 { - label = "rootfs2"; - reg = <0x3800000 0x2200000>; /* 34MB */ - }; - - /* - * 38MB, last MB is for the BBT, not writable - */ - partition@5a00000 { - label = "syscfg"; - reg = <0x5a00000 0x2600000>; - }; - - /* - * Unused area between "s_env" and "devinfo". - * Moved here because otherwise the renumbered - * partitions would break the bootloader - * supplied bootargs - */ - partition@180000 { - label = "unused_area"; - reg = <0x280000 0x680000>; /* 6.5MB */ - }; - }; - }; - - bm-bppi { - status = "okay"; - }; - - pcie-controller { - status = "okay"; - - pcie@1,0 { - /* Marvell 88W8864, 5GHz-only */ - status = "okay"; - }; - - pcie@2,0 { - /* Marvell 88W8864, 2GHz-only */ - status = "okay"; - }; - }; }; - usb3_phy: usb3_phy { + usb3_1_phy: usb3_1-phy { compatible = "usb-nop-xceiv"; - vcc-supply = <®_xhci0_vbus>; + vcc-supply = <&usb3_1_vbus>; }; - reg_xhci0_vbus: xhci0-vbus { + usb3_1_vbus: usb3_1-vbus { compatible = "regulator-fixed"; pinctrl-names = "default"; - pinctrl-0 = <&xhci0_vbus_pins>; - regulator-name = "xhci0-vbus"; + pinctrl-0 = <&usb3_1_vbus_pins>; + regulator-name = "usb3_1-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; enable-active-high; gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>; }; - gpio_keys { + gpio_keys: gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&keys_pin>; + pinctrl-0 = <&gpio_keys_pins>; pinctrl-names = "default"; - button@1 { + wps { label = "WPS"; linux,code = <KEY_WPS_BUTTON>; gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; }; - button@2 { + reset { label = "Factory Reset Button"; linux,code = <KEY_RESTART>; gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; }; }; - gpio-leds { + gpio_leds: gpio-leds { compatible = "gpio-leds"; - pinctrl-0 = <&power_led_pin &sata_led_pin>; + pinctrl-0 = <&gpio_leds_pins>; pinctrl-names = "default"; power { @@ -323,21 +113,83 @@ linux,default-trigger = "disk-activity"; }; }; +}; - dsa@0 { - status = "disabled"; +&ahci0 { + status = "okay"; +}; + +&bm { + status = "okay"; +}; - compatible = "marvell,dsa"; - #address-cells = <2>; +&bm_bppi { + status = "okay"; +}; + +ð0 { + status = "okay"; + phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + bm,pool-short = <1>; + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +ð2 { + status = "okay"; + phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <2>; + bm,pool-short = <3>; + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + status = "okay"; + + tmp421@4c { + compatible = "ti,tmp421"; + reg = <0x4c>; + }; + + expander0: pca9635@68 { + #address-cells = <1>; #size-cells = <0>; + compatible = "nxp,pca9635"; + reg = <0x68>; + }; +}; + +&nand { + /* 128MiB or 256MiB */ + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; +}; - dsa,ethernet = <ð2>; - dsa,mii-bus = <&mdio>; +&mdio { + status = "okay"; - switch@0 { + switch@0 { + compatible = "marvell,mv88e6085"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + ports { #address-cells = <1>; #size-cells = <0>; - reg = <0x0 0>; /* MDIO address 0, switch 0 in tree */ port@0 { reg = <0>; @@ -367,28 +219,45 @@ port@5 { reg = <5>; label = "cpu"; + ethernet = <ð2>; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; }; }; }; +&pciec { + status = "okay"; +}; + +&pcie1 { + /* Marvell 88W8864, 5GHz-only */ + status = "okay"; +}; + +&pcie2 { + /* Marvell 88W8864, 2GHz-only */ + status = "okay"; +}; + &pinctrl { - keys_pin: keys-pin { + gpio_keys_pins: gpio-keys-pins { + /* mpp24: wps, mpp29: reset */ marvell,pins = "mpp24", "mpp29"; marvell,function = "gpio"; }; - power_led_pin: power-led-pin { - marvell,pins = "mpp55"; - marvell,function = "gpio"; - }; - - sata_led_pin: sata-led-pin { - marvell,pins = "mpp54"; + gpio_leds_pins: gpio-leds-pins { + /* mpp54: sata, mpp55: power */ + marvell,pins = "mpp54", "mpp55"; marvell,function = "gpio"; }; - xhci0_vbus_pins: xhci0-vbus-pins { + usb3_1_vbus_pins: usb3_1-vbus-pins { marvell,pins = "mpp50"; marvell,function = "gpio"; }; @@ -397,3 +266,18 @@ &spi0 { status = "disabled"; }; + +&uart0 { + /* J10: VCC, NC, RX, NC, TX, GND */ + status = "okay"; +}; + +&usb0 { + /* USB part of the eSATA/USB 2.0 port */ + status = "okay"; +}; + +&usb3_1 { + status = "okay"; + usb-phy = <&usb3_1_phy>; +}; diff --git a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi index 84cc232a29e9..be22ec5236ac 100644 --- a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi +++ b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi @@ -311,6 +311,10 @@ reg = <0x20a00 0x2d0>, <0x21070 0x58>; }; +&rtc { + status = "disabled"; +}; + &timer { compatible = "marvell,armada-xp-timer"; clocks = <&coreclk 2>, <&refclk>; diff --git a/arch/arm/boot/dts/armada-xp-98dx4251.dtsi b/arch/arm/boot/dts/armada-xp-98dx4251.dtsi index 51de91b31a9d..bc9f824020eb 100644 --- a/arch/arm/boot/dts/armada-xp-98dx4251.dtsi +++ b/arch/arm/boot/dts/armada-xp-98dx4251.dtsi @@ -87,4 +87,5 @@ &pp0 { compatible = "marvell,prestera-98dx4251"; + interrupts = <33>, <34>, <35>, <36>; }; diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts index 9efcf59c9b44..6d705f518254 100644 --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts @@ -308,13 +308,11 @@ }; }; - gpio_fan { + pwm_fan { /* SUNON HA4010V4-0000-C99 */ - compatible = "gpio-fan"; - gpios = <&gpio0 24 0>; - gpio-fan,speed-map = <0 0 - 4500 1>; + compatible = "pwm-fan"; + pwms = <&gpio0 24 4000>; }; dsa { diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi index 07c5090ecd29..f77168c9add4 100644 --- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi @@ -202,25 +202,33 @@ internal-regs { gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <17>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>; + clocks = <&coreclk 0>; }; }; }; diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi index 64e936ae7b22..0ecfaf49d239 100644 --- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi @@ -285,29 +285,38 @@ internal-regs { gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>, <90>; + clocks = <&coreclk 0>; }; gpio2: gpio@18180 { - compatible = "marvell,orion-gpio"; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; reg = <0x18180 0x40>; ngpios = <3>; gpio-controller; diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi index d1383dde43eb..670ece4c6fa7 100644 --- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi @@ -323,29 +323,38 @@ internal-regs { gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>, <90>; + clocks = <&coreclk 0>; }; gpio2: gpio@18180 { - compatible = "marvell,orion-gpio"; + compatible = "marvell,armada-370-xp-gpio", + "marvell,orion-gpio"; reg = <0x18180 0x40>; ngpios = <3>; gpio-controller; diff --git a/arch/arm/boot/dts/at91-linea.dtsi b/arch/arm/boot/dts/at91-linea.dtsi index 0721c8472509..9bf9aaeff3e8 100644 --- a/arch/arm/boot/dts/at91-linea.dtsi +++ b/arch/arm/boot/dts/at91-linea.dtsi @@ -31,7 +31,7 @@ status = "okay"; eeprom@51 { - compatible = "st,24c64"; + compatible = "st,24c64", "atmel,24c64"; reg = <0x51>; pagesize = <32>; }; diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts index 0bef9e0b89c6..37de94fc9b5a 100644 --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts @@ -258,6 +258,12 @@ status = "okay"; }; + can0: can@f8054000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can0_default>; + status = "okay"; + }; + uart3: serial@fc008000 { atmel,use-dma-rx; atmel,use-dma-tx; @@ -322,6 +328,18 @@ bias-disable; }; + pinctrl_can0_default: can0_default { + pinmux = <PIN_PC10__CANTX0>, + <PIN_PC11__CANRX0>; + bias-disable; + }; + + pinctrl_can1_default: can1_default { + pinmux = <PIN_PC26__CANTX1>, + <PIN_PC27__CANRX1>; + bias-disable; + }; + pinctrl_charger_chglev: charger_chglev { pinmux = <PIN_PA12__GPIO>; bias-disable; @@ -469,6 +487,12 @@ }; }; + + can1: can@fc050000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can1_default>; + status = "okay"; + }; }; }; diff --git a/arch/arm/boot/dts/at91-tse850-3.dts b/arch/arm/boot/dts/at91-tse850-3.dts index 498fba3e52b5..a5c0dd630253 100644 --- a/arch/arm/boot/dts/at91-tse850-3.dts +++ b/arch/arm/boot/dts/at91-tse850-3.dts @@ -239,7 +239,7 @@ }; eeprom@50 { - compatible = "nxp,24c02"; + compatible = "nxp,24c02", "atmel,24c02"; reg = <0x50>; pagesize = <16>; }; diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi index 9677dd5cf6b6..3c8fa26e87b7 100644 --- a/arch/arm/boot/dts/axp209.dtsi +++ b/arch/arm/boot/dts/axp209.dtsi @@ -64,6 +64,11 @@ #gpio-cells = <2>; }; + battery_power_supply: battery-power-supply { + compatible = "x-powers,axp209-battery-power-supply"; + status = "disabled"; + }; + regulators { /* Default work frequency for buck regulators */ x-powers,dcdc-freq = <1500>; diff --git a/arch/arm/boot/dts/axp22x.dtsi b/arch/arm/boot/dts/axp22x.dtsi index 67331c5f1714..87fb08e812ec 100644 --- a/arch/arm/boot/dts/axp22x.dtsi +++ b/arch/arm/boot/dts/axp22x.dtsi @@ -57,6 +57,11 @@ status = "disabled"; }; + battery_power_supply: battery-power-supply { + compatible = "x-powers,axp221-battery-power-supply"; + status = "disabled"; + }; + regulators { /* Default work frequency for buck regulators */ x-powers,dcdc-freq = <3000>; diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index a7b5ce133784..e55b362b9d6e 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -65,13 +65,13 @@ &sdhci { pinctrl-names = "default"; pinctrl-0 = <&emmc_gpio48>; - status = "okay"; bus-width = <4>; }; &sdhost { pinctrl-names = "default"; pinctrl-0 = <&sdhost_gpio48>; + status = "okay"; bus-width = <4>; }; diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi index 0890d97e674d..659b6e9513b1 100644 --- a/arch/arm/boot/dts/bcm2835.dtsi +++ b/arch/arm/boot/dts/bcm2835.dtsi @@ -24,6 +24,10 @@ }; }; +&cpu_thermal { + coefficients = <(-538) 407000>; +}; + /* enable thermal sensor with the correct compatible property set */ &thermal { compatible = "brcm,bcm2835-thermal"; diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi index 519a44f5d25a..da3deeb42592 100644 --- a/arch/arm/boot/dts/bcm2836.dtsi +++ b/arch/arm/boot/dts/bcm2836.dtsi @@ -77,6 +77,10 @@ interrupts = <8>; }; +&cpu_thermal { + coefficients = <(-538) 407000>; +}; + /* enable thermal sensor with the correct compatible property set */ &thermal { compatible = "brcm,bcm2836-thermal"; diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts new file mode 100644 index 000000000000..c72a27d908b6 --- /dev/null +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts @@ -0,0 +1 @@ +#include "arm64/broadcom/bcm2837-rpi-3-b.dts" diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index 561f27d8d922..cc721a4e02db 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi @@ -3,6 +3,11 @@ #include <dt-bindings/clock/bcm2835-aux.h> #include <dt-bindings/gpio/gpio.h> +/* firmware-provided startup stubs live here, where the secondary CPUs are + * spinning. + */ +/memreserve/ 0x00000000 0x00001000; + /* This include file covers the common peripherals and configuration between * bcm2835 and bcm2836 implementations, leaving the CPU configuration to * bcm2835.dtsi and bcm2836.dtsi. @@ -19,6 +24,26 @@ bootargs = "earlyprintk console=ttyAMA0"; }; + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <80000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + }; + }; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; @@ -430,6 +455,7 @@ compatible = "brcm,bcm2835-thermal"; reg = <0x7e212000 0x8>; clocks = <&clocks BCM2835_CLOCK_TSENS>; + #thermal-sensor-cells = <0>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index 31a9e061ddd0..f47fc4daf062 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -529,7 +529,8 @@ }; &usb1 { - dr_mode = "peripheral"; + dr_mode = "otg"; + extcon = <&extcon_usb1>; }; &usb2 { diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index e7144662af45..0f0f6f58bd18 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -99,14 +99,14 @@ compatible = "operating-points-v2-ti-cpu"; syscon = <&scm_wkup>; - opp_nom@1000000000 { + opp_nom-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <1060000 850000 1150000>; opp-supported-hw = <0xFF 0x01>; opp-suspend; }; - opp_od@1176000000 { + opp_od-1176000000 { opp-hz = /bits/ 64 <1176000000>; opp-microvolt = <1160000 885000 1160000>; opp-supported-hw = <0xFF 0x02>; diff --git a/arch/arm/boot/dts/dra72-evm-common.dtsi b/arch/arm/boot/dts/dra72-evm-common.dtsi index ad24544adf0f..85780549bc26 100644 --- a/arch/arm/boot/dts/dra72-evm-common.dtsi +++ b/arch/arm/boot/dts/dra72-evm-common.dtsi @@ -392,7 +392,8 @@ }; &usb1 { - dr_mode = "peripheral"; + dr_mode = "otg"; + extcon = <&extcon_usb1>; }; &usb2 { diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi index 0124faf175c8..42ea246e71cb 100644 --- a/arch/arm/boot/dts/emev2.dtsi +++ b/arch/arm/boot/dts/emev2.dtsi @@ -197,7 +197,7 @@ clock-names = "sclk"; }; - pfc: pfc@e0140200 { + pfc: pin-controller@e0140200 { compatible = "renesas,pfc-emev2"; reg = <0xe0140200 0x100>; }; diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 6098dacd09f1..6a432460eb77 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -14,7 +14,6 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/input/input.h> #include "exynos5250.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Insignal Arndale evaluation board based on EXYNOS5250"; diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts index a97a785ccc6b..6632f657394e 100644 --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -13,7 +13,6 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include "exynos5250.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { model = "SAMSUNG SMDK5250 board based on EXYNOS5250"; diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts index 4d7bdb735ed3..95c3bcace9dc 100644 --- a/arch/arm/boot/dts/exynos5250-spring.dts +++ b/arch/arm/boot/dts/exynos5250-spring.dts @@ -14,7 +14,6 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/input/input.h> #include "exynos5250.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Google Spring"; diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts index 9cc83c51c925..ee1bb9b8b366 100644 --- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -16,7 +16,6 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/input/input.h> #include <dt-bindings/clock/samsung,s2mps11.h> -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Insignal Arndale Octa evaluation board based on EXYNOS5420"; diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 1f964ec35c5e..2cd65699a29c 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -16,7 +16,6 @@ #include <dt-bindings/regulator/maxim,max77802.h> #include "exynos5420.dtsi" #include "exynos5420-cpus.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Google Peach Pit Rev 6+"; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index aaccd0da41e5..08c8ab173e87 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -13,7 +13,6 @@ #include "exynos5420.dtsi" #include "exynos5420-cpus.dtsi" #include <dt-bindings/gpio/gpio.h> -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Samsung SMDK5420 board based on EXYNOS5420"; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi index 05b9afdd6757..657535e2e3cc 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi @@ -18,7 +18,6 @@ #include <dt-bindings/sound/samsung-i2s.h> #include "exynos5800.dtsi" #include "exynos5422-cpus.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { memory@40000000 { diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index f9ff7f07ae0c..ecf1c916e8fc 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -16,7 +16,6 @@ #include <dt-bindings/regulator/maxim,max77802.h> #include "exynos5800.dtsi" #include "exynos5420-cpus.dtsi" -#include "exynos-mfc-reserved-memory.dtsi" / { model = "Google Peach Pi Rev 10+"; diff --git a/arch/arm/boot/dts/imx6dl-gw560x.dts b/arch/arm/boot/dts/imx6dl-gw560x.dts new file mode 100644 index 000000000000..21bdfaf8df53 --- /dev/null +++ b/arch/arm/boot/dts/imx6dl-gw560x.dts @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "imx6dl.dtsi" +#include "imx6qdl-gw560x.dtsi" + +/ { + model = "Gateworks Ventana i.MX6 DualLite/Solo GW560X"; + compatible = "gw,imx6dl-gw560x", "gw,ventana", "fsl,imx6dl"; +}; diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts index 8e84713f42c0..687ab911c13f 100644 --- a/arch/arm/boot/dts/imx6q-gw5400-a.dts +++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts @@ -19,7 +19,6 @@ /* these are used by bootloader for disabling nodes */ aliases { - ethernet1 = ð1; i2c0 = &i2c1; i2c1 = &i2c2; i2c2 = &i2c3; @@ -347,10 +346,6 @@ &pcie { reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>; status = "okay"; - - eth1: sky2@8 { /* MAC/PHY on bus 8 */ - compatible = "marvell,sky2"; - }; }; &ssi1 { diff --git a/arch/arm/boot/dts/imx6q-gw560x.dts b/arch/arm/boot/dts/imx6q-gw560x.dts new file mode 100644 index 000000000000..735f2bbf1439 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-gw560x.dts @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "imx6q.dtsi" +#include "imx6qdl-gw560x.dtsi" + +/ { + model = "Gateworks Ventana i.MX6 Dual/Quad GW560X"; + compatible = "gw,imx6q-gw560x", "gw,ventana", "fsl,imx6q"; +}; + +&sata { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index e9a5d0b8c7b0..dd33849335b2 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -125,7 +125,7 @@ clocks = <&clks IMX6QDL_CLK_OPENVG_AXI>, <&clks IMX6QDL_CLK_GPU2D_CORE>; clock-names = "bus", "core"; - power-domains = <&gpc 1>; + power-domains = <&pd_pu>; }; ipu2: ipu@02800000 { diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi index e8078758f26c..ad84eddb6836 100644 --- a/arch/arm/boot/dts/imx6qdl-colibri.dtsi +++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi @@ -254,6 +254,7 @@ clocks = <&clks IMX6QDL_CLK_CKO>; VDDA-supply = <®_2p5v>; VDDIO-supply = <®_3p3v>; + lrclk-strength = <3>; }; /* STMPE811 touch screen controller */ diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi index a208e7e0dc6e..5bc6ed1a5b35 100644 --- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi @@ -14,7 +14,6 @@ / { /* these are used by bootloader for disabling nodes */ aliases { - ethernet1 = ð1; led0 = &led0; led1 = &led1; led2 = &led2; @@ -342,10 +341,6 @@ pinctrl-0 = <&pinctrl_pcie>; reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>; status = "okay"; - - eth1: sky2@8 { /* MAC/PHY on bus 8 */ - compatible = "marvell,sky2"; - }; }; &pwm2 { diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi index 968fda94d14b..66fcf838e964 100644 --- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi @@ -14,7 +14,6 @@ / { /* these are used by bootloader for disabling nodes */ aliases { - ethernet1 = ð1; led0 = &led0; led1 = &led1; led2 = &led2; @@ -379,10 +378,6 @@ pinctrl-0 = <&pinctrl_pcie>; reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>; status = "okay"; - - eth1: sky2@8 { /* MAC/PHY on bus 8 */ - compatible = "marvell,sky2"; - }; }; &pwm1 { diff --git a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi new file mode 100644 index 000000000000..d894dde6e85d --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi @@ -0,0 +1,749 @@ +/* + * Copyright 2017 Gateworks Corporation + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> + +/ { + /* these are used by bootloader for disabling nodes */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + ssi0 = &ssi1; + usb0 = &usbh1; + usb1 = &usbotg; + }; + + chosen { + stdout-path = &uart2; + }; + + backlight-display { + compatible = "pwm-backlight"; + pwms = <&pwm4 0 5000000>; + brightness-levels = < + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100 + >; + default-brightness-level = <100>; + }; + + backlight-keypad { + compatible = "gpio-backlight"; + gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>; + default-on; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + led0: user1 { + label = "user1"; + gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + + led1: user2 { + label = "user2"; + gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ + default-state = "off"; + }; + + led2: user3 { + label = "user3"; + gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ + default-state = "off"; + }; + }; + + memory@10000000 { + reg = <0x10000000 0x40000000>; + }; + + pps { + compatible = "pps-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pps>; + gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>; + }; + + reg_2p5v: regulator-2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_5p0v: regulator-5p0v { + compatible = "regulator-fixed"; + regulator-name = "5P0V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_12p0v: regulator-12p0v { + compatible = "regulator-fixed"; + regulator-name = "12P0V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_1p4v: regulator-vddsoc { + compatible = "regulator-fixed"; + regulator-name = "vdd_soc"; + regulator-min-microvolt = <1400000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + }; + + reg_usb_h1_vbus: regulator-usb-h1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usb_otg_vbus: regulator-usb-otg-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + sound { + compatible = "fsl,imx6q-ventana-sgtl5000", + "fsl,imx-audio-sgtl5000"; + model = "sgtl5000-audio"; + ssi-controller = <&ssi1>; + audio-codec = <&sgtl5000>; + audio-routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + mux-int-port = <1>; + mux-ext-port = <4>; + }; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; +}; + +&ecspi3 { + cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi3>; + status = "okay"; +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan>; + status = "okay"; +}; + +&clks { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, + <&clks IMX6QDL_CLK_PLL3_USB_OTG>; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii-id"; + phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c3>; + status = "okay"; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + eeprom1: eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; + + eeprom2: eeprom@51 { + compatible = "atmel,24c02"; + reg = <0x51>; + pagesize = <16>; + }; + + eeprom3: eeprom@52 { + compatible = "atmel,24c02"; + reg = <0x52>; + pagesize = <16>; + }; + + eeprom4: eeprom@53 { + compatible = "atmel,24c02"; + reg = <0x53>; + pagesize = <16>; + }; + + pca9555: gpio@23 { + compatible = "nxp,pca9555"; + reg = <0x23>; + gpio-controller; + #gpio-cells = <2>; + }; + + ds1672: rtc@68 { + compatible = "dallas,ds1672"; + reg = <0x68>; + }; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks IMX6QDL_CLK_CKO>; + VDDA-supply = <®_1p8v>; + VDDIO-supply = <®_3p3v>; + }; + + tca8418: keypad@34 { + compatible = "ti,tca8418"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_keypad>; + reg = <0x34>; + interrupt-parent = <&gpio5>; + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; + linux,keymap = < MATRIX_KEY(0x00, 0x01, BTN_0) + MATRIX_KEY(0x00, 0x00, BTN_1) + MATRIX_KEY(0x01, 0x01, BTN_2) + MATRIX_KEY(0x01, 0x00, BTN_3) + MATRIX_KEY(0x02, 0x00, BTN_4) + MATRIX_KEY(0x00, 0x03, BTN_5) + MATRIX_KEY(0x00, 0x02, BTN_6) + MATRIX_KEY(0x01, 0x03, BTN_7) + MATRIX_KEY(0x01, 0x02, BTN_8) + MATRIX_KEY(0x02, 0x02, BTN_9) + >; + keypad,num-rows = <4>; + keypad,num-columns = <4>; + }; + + ltc3676: pmic@3c { + compatible = "lltc,ltc3676"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + reg = <0x3c>; + interrupt-parent = <&gpio1>; + interrupts = <8 IRQ_TYPE_EDGE_FALLING>; + + regulators { + /* VDD_DDR (1+R1/R2 = 2.105) */ + reg_vdd_ddr: sw2 { + regulator-name = "vddddr"; + regulator-min-microvolt = <868310>; + regulator-max-microvolt = <1684000>; + lltc,fb-voltage-divider = <221000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_ARM (1+R1/R2 = 1.931) */ + reg_vdd_arm: sw3 { + regulator-name = "vddarm"; + regulator-min-microvolt = <796551>; + regulator-max-microvolt = <1544827>; + lltc,fb-voltage-divider = <243000 261000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + linux,phandle = <®_vdd_arm>; + }; + + /* VDD_1P8 (1+R1/R2 = 2.505): GPS/VideoIn/ENET-PHY */ + reg_1p8v: sw4 { + regulator-name = "vdd1p8"; + regulator-min-microvolt = <1033310>; + regulator-max-microvolt = <2004000>; + lltc,fb-voltage-divider = <301000 200000>; + regulator-ramp-delay = <7000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_1P0 (1+R1/R2 = 1.39): PCIe/ENET-PHY */ + reg_1p0v: ldo2 { + regulator-name = "vdd1p0"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1050000>; + lltc,fb-voltage-divider = <78700 200000>; + regulator-boot-on; + regulator-always-on; + }; + + /* VDD_AUD_1P8: Audio codec */ + reg_aud_1p8v: ldo3 { + regulator-name = "vdd1p8a"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + }; + + /* VDD_HIGH (1+R1/R2 = 4.17) */ + reg_3p0v: ldo4 { + regulator-name = "vdd3p0"; + regulator-min-microvolt = <3023250>; + regulator-max-microvolt = <3023250>; + lltc,fb-voltage-divider = <634000 200000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + egalax_ts: touchscreen@4 { + compatible = "eeti,egalax_ts"; + reg = <0x04>; + interrupt-parent = <&gpio5>; + interrupts = <12 IRQ_TYPE_EDGE_FALLING>; + wakeup-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; + }; +}; + +&ldb { + fsl,dual-channel; + status = "okay"; + + lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; + status = "okay"; + + display-timings { + native-mode = <&timing0>; + timing0: hsd100pxn1 { + clock-frequency = <65000000>; + hactive = <1024>; + vactive = <768>; + hback-porch = <220>; + hfront-porch = <40>; + vback-porch = <21>; + vfront-porch = <7>; + hsync-len = <60>; + vsync-len = <10>; + }; + }; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpio = <&gpio4 31 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */ + status = "disabled"; +}; + +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */ + status = "disabled"; +}; + +&pwm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm4>; + status = "okay"; +}; + +&ssi1 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + uart-has-rtscts; + rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_h1_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1>; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + bus-width = <8>; + vmmc-supply = <®_3p3v>; + non-removable; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + cd-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>; + vmmc-supply = <®_3p3v>; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; +}; + +&iomuxc { + pinctrl_audmux: audmuxgrp { + fsl,pins = < + /* AUD4 */ + MX6QDL_PAD_DISP0_DAT20__AUD4_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x110b0 + MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x130b0 + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 /* AUD4_MCK */ + /* AUD6 */ + MX6QDL_PAD_DI0_PIN2__AUD6_TXD 0x130b0 + MX6QDL_PAD_DI0_PIN3__AUD6_TXFS 0x130b0 + MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x130b0 + MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x130b0 + >; + }; + + pinctrl_ecspi3: escpi3grp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1 + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1 + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1 + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x100b1 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b030 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b030 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b030 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b030 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x4001b0b0 /* PHY_RST# */ + >; + }; + + pinctrl_flexcan: flexcangrp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b1 + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b0b1 + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x4001b0b0 /* CAN_STBY */ + >; + }; + + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0 + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x1b0b0 + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x4001b0b0 /* DIOI2C_DIS# */ + MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12 0x0001b0b0 /* LVDS_TOUCH_IRQ# */ + MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13 0x0001b0b0 /* LVDS_BACKEN */ + >; + }; + + pinctrl_keypad: keypadgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11 0x0001b0b0 /* KEYPAD_IRQ# */ + MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x0001b0b0 /* KEYPAD_LED_EN */ + >; + }; + + pinctrl_pcie: pciegrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT10__GPIO4_IO31 0x1b0b0 /* PCI_RST# */ + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x4001b0b0 /* PCIESKT_WDIS# */ + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x0001b0b0 /* PMIC_IRQ# */ + >; + }; + + pinctrl_pps: ppsgrp { + fsl,pins = < + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x1b0b1 + >; + }; + + pinctrl_pwm2: pwm2grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm3: pwm3grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm4: pwm4grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1 + MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x4001b0b1 /* TEN */ + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart5: uart5grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbh1: usbh1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x4001b0b0 /* USBHUB_RST# */ + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /* PWR_EN */ + MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x1b0b0 /* OC */ + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170f9 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100f9 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170f9 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170f9 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170f9 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x170f9 + MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x170f9 + MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x170f9 + MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x170f9 + MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x170f9 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x17059 /* CD */ + MX6QDL_PAD_NANDF_CS1__SD3_VSELECT 0x17059 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp100mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9 + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x170b9 /* CD */ + MX6QDL_PAD_NANDF_CS1__SD3_VSELECT 0x170b9 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp200mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9 + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x170f9 /* CD */ + MX6QDL_PAD_NANDF_CS1__SD3_VSELECT 0x170f9 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT8__WDOG1_B 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi index bad3c9f9eeac..b63134e3b51a 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi @@ -408,7 +408,7 @@ }; rtc: rtc@68 { - compatible = "st,rv4162"; + compatible = "microcrystal,rv4162"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rv4162>; reg = <0x68>; diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi index 559da17297ef..aeaa5a6e4fcf 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi @@ -326,7 +326,7 @@ }; rtc@68 { - compatible = "st,rv4162"; + compatible = "microcrystal,rv4162"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rv4162>; reg = <0x68>; diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi index 82dc5744ae19..850ceadbc2cf 100644 --- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi +++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi @@ -88,6 +88,7 @@ clocks = <&clks IMX6QDL_CLK_CKO>; VDDA-supply = <®_2p5v>; VDDIO-supply = <®_3p3v>; + lrclk-strength = <3>; }; }; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index e426faa9c243..f325411f66aa 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -156,7 +156,7 @@ <&clks IMX6QDL_CLK_GPU3D_CORE>, <&clks IMX6QDL_CLK_GPU3D_SHADER>; clock-names = "bus", "core", "shader"; - power-domains = <&gpc 1>; + power-domains = <&pd_pu>; }; gpu_2d: gpu@00134000 { @@ -166,7 +166,7 @@ clocks = <&clks IMX6QDL_CLK_GPU2D_AXI>, <&clks IMX6QDL_CLK_GPU2D_CORE>; clock-names = "bus", "core"; - power-domains = <&gpc 1>; + power-domains = <&pd_pu>; }; timer@00a00600 { @@ -434,7 +434,7 @@ clocks = <&clks IMX6QDL_CLK_VPU_AXI>, <&clks IMX6QDL_CLK_MMDC_CH0_AXI>; clock-names = "per", "ahb"; - power-domains = <&gpc 1>; + power-domains = <&pd_pu>; resets = <&src 1>; iram = <&ocram>; }; @@ -644,6 +644,7 @@ anatop-min-bit-val = <4>; anatop-min-voltage = <800000>; anatop-max-voltage = <1375000>; + anatop-enable-bit = <0>; }; regulator-3p0 { @@ -658,6 +659,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2625000>; anatop-max-voltage = <3400000>; + anatop-enable-bit = <0>; }; regulator-2p5 { @@ -672,6 +674,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2100000>; anatop-max-voltage = <2875000>; + anatop-enable-bit = <0>; }; reg_arm: regulator-vddcore { @@ -797,14 +800,29 @@ interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>, <0 90 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&intc>; - pu-supply = <®_pu>; - clocks = <&clks IMX6QDL_CLK_GPU3D_CORE>, - <&clks IMX6QDL_CLK_GPU3D_SHADER>, - <&clks IMX6QDL_CLK_GPU2D_CORE>, - <&clks IMX6QDL_CLK_GPU2D_AXI>, - <&clks IMX6QDL_CLK_OPENVG_AXI>, - <&clks IMX6QDL_CLK_VPU_AXI>; - #power-domain-cells = <1>; + clocks = <&clks IMX6QDL_CLK_IPG>; + clock-names = "ipg"; + + pgc { + #address-cells = <1>; + #size-cells = <0>; + + power-domain@0 { + reg = <0>; + #power-domain-cells = <0>; + }; + pd_pu: power-domain@1 { + reg = <1>; + #power-domain-cells = <0>; + power-supply = <®_pu>; + clocks = <&clks IMX6QDL_CLK_GPU3D_CORE>, + <&clks IMX6QDL_CLK_GPU3D_SHADER>, + <&clks IMX6QDL_CLK_GPU2D_CORE>, + <&clks IMX6QDL_CLK_GPU2D_AXI>, + <&clks IMX6QDL_CLK_OPENVG_AXI>, + <&clks IMX6QDL_CLK_VPU_AXI>; + }; + }; }; gpr: iomuxc-gpr@020e0000 { diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi index 59453f2ac4ba..299d863690c5 100644 --- a/arch/arm/boot/dts/imx6qp.dtsi +++ b/arch/arm/boot/dts/imx6qp.dtsi @@ -120,6 +120,10 @@ <0 119 IRQ_TYPE_LEVEL_HIGH>; }; +&gpc { + compatible = "fsl,imx6qp-gpc", "fsl,imx6q-gpc"; +}; + &ipu1 { compatible = "fsl,imx6qp-ipu", "fsl,imx6q-ipu"; fsl,prg = <&prg1>; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index cc9572ea2860..3243af4a9984 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -530,6 +530,7 @@ anatop-min-bit-val = <4>; anatop-min-voltage = <800000>; anatop-max-voltage = <1375000>; + anatop-enable-bit = <0>; }; regulator-3p0 { @@ -544,6 +545,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2625000>; anatop-max-voltage = <3400000>; + anatop-enable-bit = <0>; }; regulator-2p5 { @@ -558,6 +560,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2100000>; anatop-max-voltage = <2850000>; + anatop-enable-bit = <0>; }; reg_arm: regulator-vddcore { diff --git a/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts b/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts index 802da45aa551..ac1989e5d5ad 100644 --- a/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts +++ b/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts @@ -374,7 +374,7 @@ cap-sdio-irq; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&gpio7>; diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts index d71da30c9cff..c0139d7e497a 100644 --- a/arch/arm/boot/dts/imx6sx-sdb.dts +++ b/arch/arm/boot/dts/imx6sx-sdb.dts @@ -128,3 +128,11 @@ reg = <1>; }; }; + +®_arm { + vin-supply = <&sw1a_reg>; +}; + +®_soc { + vin-supply = <&sw1a_reg>; +}; diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index 3f1416be4c36..f16b9df9d0c6 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -587,6 +587,7 @@ anatop-min-bit-val = <4>; anatop-min-voltage = <800000>; anatop-max-voltage = <1375000>; + anatop-enable-bit = <0>; }; regulator-3p0 { @@ -601,6 +602,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2625000>; anatop-max-voltage = <3400000>; + anatop-enable-bit = <0>; }; regulator-2p5 { @@ -615,6 +617,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2100000>; anatop-max-voltage = <2875000>; + anatop-enable-bit = <0>; }; reg_arm: regulator-vddcore { diff --git a/arch/arm/boot/dts/imx6ul-opos6ul.dtsi b/arch/arm/boot/dts/imx6ul-opos6ul.dtsi index 51095df33a90..aec5ccce0321 100644 --- a/arch/arm/boot/dts/imx6ul-opos6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul-opos6ul.dtsi @@ -120,7 +120,7 @@ #address-cells = <1>; #size-cells = <0>; - brcmf: bcrmf@1 { + brcmf: wifi@1 { compatible = "brcm,bcm4329-fmac"; reg = <1>; interrupt-parent = <&gpio2>; diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index b9d7d2d09402..6da2b77edd46 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -542,6 +542,7 @@ anatop-min-bit-val = <0>; anatop-min-voltage = <2625000>; anatop-max-voltage = <3400000>; + anatop-enable-bit = <0>; }; reg_arm: regulator-vddcore { diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi index 2d87489f9105..d7753f79937a 100644 --- a/arch/arm/boot/dts/imx7-colibri.dtsi +++ b/arch/arm/boot/dts/imx7-colibri.dtsi @@ -43,7 +43,7 @@ / { bl: backlight { compatible = "pwm-backlight"; - pwms = <&pwm1 0 5000000>; + pwms = <&pwm1 0 5000000 0>; }; reg_module_3v3: regulator-module-3v3 { diff --git a/arch/arm/boot/dts/imx7d-nitrogen7.dts b/arch/arm/boot/dts/imx7d-nitrogen7.dts index 5d98e2b5d54b..dd40e49f6c42 100644 --- a/arch/arm/boot/dts/imx7d-nitrogen7.dts +++ b/arch/arm/boot/dts/imx7d-nitrogen7.dts @@ -67,7 +67,7 @@ backlight-j20 { compatible = "pwm-backlight"; - pwms = <&pwm1 0 5000000>; + pwms = <&pwm1 0 5000000 0>; brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <6>; status = "okay"; @@ -279,7 +279,7 @@ status = "okay"; rtc@68 { - compatible = "rv4162"; + compatible = "microcrystal,rv4162"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2_rv4162>; reg = <0x68>; diff --git a/arch/arm/boot/dts/imx7d-pico.dts b/arch/arm/boot/dts/imx7d-pico.dts new file mode 100644 index 000000000000..ebda3dffc270 --- /dev/null +++ b/arch/arm/boot/dts/imx7d-pico.dts @@ -0,0 +1,387 @@ +/* + * Copyright 2017 NXP + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx7d.dtsi" + +/ { + model = "Technexion Pico i.MX7D Board"; + compatible = "technexion,imx7d-pico", "fsl,imx7d"; + + memory { + reg = <0x80000000 0x80000000>; + }; + + reg_2p5v: regulator-2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_usb_otg1_vbus: regulator-usb-otg1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio4 5 GPIO_ACTIVE_LOW>; + }; + + reg_usb_otg2_vbus: regulator-usb-otg2-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg2_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_vref_1v8: regulator-vref-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vref-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx7-sgtl5000"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,cpu { + sound-dai = <&sai1>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&codec>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + }; + }; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet1>; + assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>, + <&clks IMX7D_ENET1_TIME_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>; + assigned-clock-rates = <0>, <100000000>; + phy-mode = "rgmii"; + phy-handle = <ðphy0>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + status = "okay"; + }; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + codec: sgtl5000@0a { + #sound-dai-cells = <0>; + reg = <0x0a>; + compatible = "fsl,sgtl5000"; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_vref_1v8>; + }; +}; + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; + status = "okay"; + + pmic: pfuze3000@08 { + compatible = "fsl,pfuze3000"; + reg = <0x08>; + + regulators { + sw1a_reg: sw1a { + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + /* use sw1c_reg to align with pfuze100/pfuze200 */ + sw1c_reg: sw1b { + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1475000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1850000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3a_reg: sw3 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1650000>; + regulator-boot-on; + regulator-always-on; + }; + + swbst_reg: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-boot-on; + regulator-always-on; + }; + + vgen1_reg: vldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen2_reg: vldo2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + }; + + vgen3_reg: vccsd { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen4_reg: v33 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen5_reg: vldo3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen6_reg: vldo4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; +}; + +&sai1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai1>; + assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>, + <&clks IMX7D_SAI1_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>; + assigned-clock-rates = <0>, <24576000>; + status = "okay"; +}; + +&uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; + assigned-clocks = <&clks IMX7D_UART5_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>; + status = "okay"; +}; + +&usbotg1 { + vbus-supply = <®_usb_otg1_vbus>; + status = "okay"; +}; + +&usbotg2 { + vbus-supply = <®_usb_otg2_vbus>; + dr_mode = "host"; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>; + assigned-clock-rates = <400000000>; + bus-width = <8>; + fsl,tuning-step = <2>; + non-removable; + status = "okay"; +}; + +&iomuxc { + pinctrl_enet1: enet1grp { + fsl,pins = < + MX7D_PAD_SD2_CD_B__ENET1_MDIO 0x3 + MX7D_PAD_SD2_WP__ENET1_MDC 0x3 + MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x1 + MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x1 + MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x1 + MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 0x1 + MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 0x1 + MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x1 + MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC 0x1 + MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x1 + MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x1 + MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 0x1 + MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 0x1 + MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x1 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX7D_PAD_UART1_TX_DATA__I2C1_SDA 0x4000007f + MX7D_PAD_UART1_RX_DATA__I2C1_SCL 0x4000007f + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX7D_PAD_SAI1_RX_BCLK__I2C4_SDA 0x4000007f + MX7D_PAD_SAI1_RX_SYNC__I2C4_SCL 0x4000007f + >; + }; + + pinctrl_sai1: sai1grp { + fsl,pins = < + MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK 0x1f + MX7D_PAD_ENET1_CRS__SAI1_TX_SYNC 0x1f + MX7D_PAD_ENET1_COL__SAI1_TX_DATA0 0x30 + MX7D_PAD_ENET1_TX_CLK__SAI1_RX_DATA0 0x1f + >; + }; + + pinctrl_uart5: uart5grp { + fsl,pins = < + MX7D_PAD_I2C4_SDA__UART5_DCE_TX 0x79 + MX7D_PAD_I2C4_SCL__UART5_DCE_RX 0x79 + >; + }; + + pinctrl_usbotg1_pwr: usbotg_pwr { + fsl,pins = < + MX7D_PAD_UART3_TX_DATA__GPIO4_IO5 0x14 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX7D_PAD_SD3_CMD__SD3_CMD 0x59 + MX7D_PAD_SD3_CLK__SD3_CLK 0x19 + MX7D_PAD_SD3_DATA0__SD3_DATA0 0x59 + MX7D_PAD_SD3_DATA1__SD3_DATA1 0x59 + MX7D_PAD_SD3_DATA2__SD3_DATA2 0x59 + MX7D_PAD_SD3_DATA3__SD3_DATA3 0x59 + MX7D_PAD_SD3_DATA4__SD3_DATA4 0x59 + MX7D_PAD_SD3_DATA5__SD3_DATA5 0x59 + MX7D_PAD_SD3_DATA6__SD3_DATA6 0x59 + MX7D_PAD_SD3_DATA7__SD3_DATA7 0x59 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp_100mhz { + fsl,pins = < + MX7D_PAD_SD3_CMD__SD3_CMD 0x5a + MX7D_PAD_SD3_CLK__SD3_CLK 0x1a + MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5a + MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5a + MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5a + MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5a + MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5a + MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5a + MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5a + MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5a + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp_200mhz { + fsl,pins = < + MX7D_PAD_SD3_CMD__SD3_CMD 0x5b + MX7D_PAD_SD3_CLK__SD3_CLK 0x1b + MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5b + MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5b + MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5b + MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5b + MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5b + MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5b + MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5b + MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5b + >; + }; +}; diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index 5be01a1bf840..77c400f0017a 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts @@ -52,6 +52,27 @@ reg = <0x80000000 0x80000000>; }; + spi4 { + compatible = "spi-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi4>; + gpio-sck = <&gpio1 13 GPIO_ACTIVE_HIGH>; + gpio-mosi = <&gpio1 9 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; + num-chipselects = <1>; + #address-cells = <1>; + #size-cells = <0>; + + extended_io: gpio-expander@0 { + compatible = "fairchild,74hc595"; + gpio-controller; + #gpio-cells = <2>; + reg = <0>; + registers-number = <1>; + spi-max-frequency = <100000>; + }; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -328,6 +349,11 @@ }; }; +&pcie { + reset-gpio = <&extended_io 1 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + &pwm1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pwm1>; @@ -642,5 +668,13 @@ fsl,pins = < MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT 0x110b0 >; + + pinctrl_spi4: spi4grp { + fsl,pins = < + MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x59 + MX7D_PAD_GPIO1_IO12__GPIO1_IO12 0x59 + MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x59 + >; + }; }; }; diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi index f6dee41a05d9..f46814a7ea44 100644 --- a/arch/arm/boot/dts/imx7d.dtsi +++ b/arch/arm/boot/dts/imx7d.dtsi @@ -42,6 +42,7 @@ */ #include "imx7s.dtsi" +#include <dt-bindings/reset/imx7-reset.h> / { cpus { @@ -127,6 +128,42 @@ fsl,num-rx-queues=<3>; status = "disabled"; }; + + pcie: pcie@0x33800000 { + compatible = "fsl,imx7d-pcie", "snps,dw-pcie"; + reg = <0x33800000 0x4000>, + <0x4ff00000 0x80000>; + reg-names = "dbi", "config"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x81000000 0 0 0x4ff80000 0 0x00010000 /* downstream I/O */ + 0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */ + num-lanes = <1>; + interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "msi"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>, + <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>, + <&clks IMX7D_PCIE_PHY_ROOT_CLK>; + clock-names = "pcie", "pcie_bus", "pcie_phy"; + assigned-clocks = <&clks IMX7D_PCIE_CTRL_ROOT_SRC>, + <&clks IMX7D_PCIE_PHY_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>, + <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>; + + fsl,max-link-speed = <2>; + power-domains = <&pgc_pcie_phy>; + resets = <&src IMX7_RESET_PCIEPHY>, + <&src IMX7_RESET_PCIE_CTRL_APPS_EN>; + reset-names = "pciephy", "apps"; + status = "disabled"; + }; }; &ca_funnel_ports { diff --git a/arch/arm/boot/dts/imx7s-warp.dts b/arch/arm/boot/dts/imx7s-warp.dts index d5237fd0fa65..8dfed85471e1 100644 --- a/arch/arm/boot/dts/imx7s-warp.dts +++ b/arch/arm/boot/dts/imx7s-warp.dts @@ -295,6 +295,7 @@ assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>; assigned-clock-rates = <400000000>; bus-width = <8>; + no-1-8-v; fsl,tuning-step = <2>; non-removable; status = "okay"; diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index c4f12fd2e044..4cf6c458b583 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -42,6 +42,7 @@ */ #include <dt-bindings/clock/imx7d-clock.h> +#include <dt-bindings/power/imx7-power.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/interrupt-controller/arm-gic.h> @@ -119,7 +120,7 @@ #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; - interrupt-parent = <&intc>; + interrupt-parent = <&gpc>; ranges; funnel@30041000 { @@ -301,6 +302,7 @@ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; #interrupt-cells = <3>; interrupt-controller; + interrupt-parent = <&intc>; reg = <0x31001000 0x1000>, <0x31002000 0x2000>, <0x31004000 0x2000>, @@ -309,6 +311,7 @@ timer { compatible = "arm,armv7-timer"; + interrupt-parent = <&intc>; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, @@ -488,7 +491,8 @@ }; gpr: iomuxc-gpr@30340000 { - compatible = "fsl,imx7d-iomuxc-gpr", "syscon"; + compatible = "fsl,imx7d-iomuxc-gpr", + "fsl,imx6q-iomuxc-gpr", "syscon"; reg = <0x30340000 0x10000>; }; @@ -516,6 +520,7 @@ anatop-min-bit-val = <8>; anatop-min-voltage = <800000>; anatop-max-voltage = <1200000>; + anatop-enable-bit = <0>; }; }; @@ -563,6 +568,27 @@ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; #reset-cells = <1>; }; + + gpc: gpc@303a0000 { + compatible = "fsl,imx7d-gpc"; + reg = <0x303a0000 0x10000>; + interrupt-controller; + interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + #interrupt-cells = <3>; + interrupt-parent = <&intc>; + #power-domain-cells = <1>; + + pgc { + #address-cells = <1>; + #size-cells = <0>; + + pgc_pcie_phy: pgc-power-domain@IMX7_POWER_DOMAIN_PCIE_PHY { + #power-domain-cells = <0>; + reg = <IMX7_POWER_DOMAIN_PCIE_PHY>; + power-supply = <®_1p0d>; + }; + }; + }; }; aips2: aips-bus@30400000 { @@ -609,7 +635,7 @@ clocks = <&clks IMX7D_PWM1_ROOT_CLK>, <&clks IMX7D_PWM1_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -620,7 +646,7 @@ clocks = <&clks IMX7D_PWM2_ROOT_CLK>, <&clks IMX7D_PWM2_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -631,7 +657,7 @@ clocks = <&clks IMX7D_PWM3_ROOT_CLK>, <&clks IMX7D_PWM3_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -642,7 +668,7 @@ clocks = <&clks IMX7D_PWM4_ROOT_CLK>, <&clks IMX7D_PWM4_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -934,8 +960,8 @@ compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc"; reg = <0x30b40000 0x10000>; interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>, <&clks IMX7D_USDHC1_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; @@ -946,8 +972,8 @@ compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc"; reg = <0x30b50000 0x10000>; interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>, <&clks IMX7D_USDHC2_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; @@ -958,8 +984,8 @@ compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc"; reg = <0x30b60000 0x10000>; interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>, <&clks IMX7D_USDHC3_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; diff --git a/arch/arm/boot/dts/keystone-k2g-evm.dts b/arch/arm/boot/dts/keystone-k2g-evm.dts index 692fcbb1434a..61883cb969d2 100644 --- a/arch/arm/boot/dts/keystone-k2g-evm.dts +++ b/arch/arm/boot/dts/keystone-k2g-evm.dts @@ -20,7 +20,7 @@ compatible = "ti,k2g-evm", "ti,k2g", "ti,keystone"; model = "Texas Instruments K2G General Purpose EVM"; - memory { + memory@800000000 { device_type = "memory"; reg = <0x00000008 0x00000000 0x00000000 0x80000000>; }; diff --git a/arch/arm/boot/dts/keystone-k2g-ice.dts b/arch/arm/boot/dts/keystone-k2g-ice.dts new file mode 100644 index 000000000000..d820d37b5148 --- /dev/null +++ b/arch/arm/boot/dts/keystone-k2g-ice.dts @@ -0,0 +1,35 @@ +/* + * Device Tree Source for K2G Industrial Communication Engine EVM + * + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0 + */ +/dts-v1/; + +#include "keystone-k2g.dtsi" + +/ { + compatible = "ti,k2g-ice", "ti,k2g", "ti,keystone"; + model = "Texas Instruments K2G Industrial Communication EVM"; + + memory@800000000 { + device_type = "memory"; + reg = <0x00000008 0x00000000 0x00000000 0x20000000>; + }; +}; + +&k2g_pinctrl { + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + K2G_CORE_IOPAD(0x11cc) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + K2G_CORE_IOPAD(0x11d0) (BUFFER_CLASS_B | PIN_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi index f59567fe7d91..a789f75a1ed5 100644 --- a/arch/arm/boot/dts/keystone-k2g.dtsi +++ b/arch/arm/boot/dts/keystone-k2g.dtsi @@ -15,7 +15,6 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/pinctrl/keystone.h> -#include "skeleton.dtsi" / { compatible = "ti,k2g","ti,keystone"; @@ -24,6 +23,8 @@ #size-cells = <2>; interrupt-parent = <&gic>; + chosen { }; + aliases { serial0 = &uart0; }; diff --git a/arch/arm/boot/dts/keystone-k2l-netcp.dtsi b/arch/arm/boot/dts/keystone-k2l-netcp.dtsi index b6f26824e83a..66f615a74118 100644 --- a/arch/arm/boot/dts/keystone-k2l-netcp.dtsi +++ b/arch/arm/boot/dts/keystone-k2l-netcp.dtsi @@ -137,8 +137,8 @@ netcp: netcp@26000000 { /* NetCP address range */ ranges = <0 0x26000000 0x1000000>; - clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>, <&clkosr>; - clock-names = "pa_clk", "ethss_clk", "cpts", "osr_clk"; + clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>; + clock-names = "pa_clk", "ethss_clk", "cpts"; dma-coherent; ti,navigator-dmas = <&dma_gbe 0>, diff --git a/arch/arm/boot/dts/keystone-k2l.dtsi b/arch/arm/boot/dts/keystone-k2l.dtsi index b58e7ebc0919..148650406cf7 100644 --- a/arch/arm/boot/dts/keystone-k2l.dtsi +++ b/arch/arm/boot/dts/keystone-k2l.dtsi @@ -232,6 +232,14 @@ }; }; + osr: sram@70000000 { + compatible = "mmio-sram"; + reg = <0x70000000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&clkosr>; + }; + dspgpio0: keystone_dsp_gpio@02620240 { compatible = "ti,keystone-dsp-gpio"; gpio-controller; diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi index efe53998c961..6d89736c7b44 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi @@ -7,6 +7,10 @@ #include <dt-bindings/input/input.h> / { + chosen { + stdout-path = &uart1; + }; + cpus { cpu@0 { cpu0-supply = <&vcc>; diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi index 8c77c87660cd..8d9c36970dfd 100644 --- a/arch/arm/boot/dts/meson.dtsi +++ b/arch/arm/boot/dts/meson.dtsi @@ -65,100 +65,108 @@ #interrupt-cells = <3>; }; - timer@c1109940 { - compatible = "amlogic,meson6-timer"; - reg = <0xc1109940 0x18>; - interrupts = <0 10 1>; - }; - soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; - wdt: watchdog@c1109900 { - compatible = "amlogic,meson6-wdt"; - reg = <0xc1109900 0x8>; - interrupts = <0 0 1>; - }; - - uart_AO: serial@c81004c0 { - compatible = "amlogic,meson-uart"; - reg = <0xc81004c0 0x18>; - interrupts = <0 90 1>; - clocks = <&clk81>; - status = "disabled"; - }; - - uart_A: serial@c11084c0 { - compatible = "amlogic,meson-uart"; - reg = <0xc11084c0 0x18>; - interrupts = <0 26 1>; - clocks = <&clk81>; - status = "disabled"; - }; - - uart_B: serial@c11084dc { - compatible = "amlogic,meson-uart"; - reg = <0xc11084dc 0x18>; - interrupts = <0 75 1>; - clocks = <&clk81>; - status = "disabled"; - }; - - uart_C: serial@c1108700 { - compatible = "amlogic,meson-uart"; - reg = <0xc1108700 0x18>; - interrupts = <0 93 1>; - clocks = <&clk81>; - status = "disabled"; - }; - - i2c_AO: i2c@c8100500 { - compatible = "amlogic,meson6-i2c"; - reg = <0xc8100500 0x20>; - interrupts = <0 92 1>; - clocks = <&clk81>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - i2c_A: i2c@c1108500 { - compatible = "amlogic,meson6-i2c"; - reg = <0xc1108500 0x20>; - interrupts = <0 21 1>; - clocks = <&clk81>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - i2c_B: i2c@c11087c0 { - compatible = "amlogic,meson6-i2c"; - reg = <0xc11087c0 0x20>; - interrupts = <0 128 1>; - clocks = <&clk81>; + cbus: cbus@c1100000 { + compatible = "simple-bus"; + reg = <0xc1100000 0x200000>; #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; + #size-cells = <1>; + ranges = <0x0 0xc1100000 0x200000>; + + uart_A: serial@84c0 { + compatible = "amlogic,meson-uart"; + reg = <0x84c0 0x18>; + interrupts = <0 26 1>; + status = "disabled"; + }; + + uart_B: serial@84dc { + compatible = "amlogic,meson-uart"; + reg = <0x84dc 0x18>; + interrupts = <0 75 1>; + status = "disabled"; + }; + + i2c_A: i2c@8500 { + compatible = "amlogic,meson6-i2c"; + reg = <0x8500 0x20>; + interrupts = <0 21 1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + uart_C: serial@8700 { + compatible = "amlogic,meson-uart"; + reg = <0x8700 0x18>; + interrupts = <0 93 1>; + status = "disabled"; + }; + + i2c_B: i2c@87c0 { + compatible = "amlogic,meson6-i2c"; + reg = <0x87c0 0x20>; + interrupts = <0 128 1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spifc: spi@8c80 { + compatible = "amlogic,meson6-spifc"; + reg = <0x8c80 0x80>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + wdt: watchdog@9900 { + compatible = "amlogic,meson6-wdt"; + reg = <0x9900 0x8>; + interrupts = <0 0 1>; + }; + + timer@9940 { + compatible = "amlogic,meson6-timer"; + reg = <0x9940 0x18>; + interrupts = <0 10 1>; + }; }; - ir_receiver: ir-receiver@c8100480 { - compatible= "amlogic,meson6-ir"; - reg = <0xc8100480 0x20>; - interrupts = <0 15 1>; - status = "disabled"; - }; - - spifc: spi@c1108c80 { - compatible = "amlogic,meson6-spifc"; - reg = <0xc1108c80 0x80>; + aobus: aobus@c8100000 { + compatible = "simple-bus"; + reg = <0xc8100000 0x100000>; #address-cells = <1>; - #size-cells = <0>; - clocks = <&clk81>; - status = "disabled"; + #size-cells = <1>; + ranges = <0x0 0xc8100000 0x100000>; + + ir_receiver: ir-receiver@480 { + compatible= "amlogic,meson6-ir"; + reg = <0x480 0x20>; + interrupts = <0 15 1>; + status = "disabled"; + }; + + uart_AO: serial@4c0 { + compatible = "amlogic,meson-uart"; + reg = <0x4c0 0x18>; + interrupts = <0 90 1>; + status = "disabled"; + }; + + i2c_AO: i2c@500 { + compatible = "amlogic,meson6-i2c"; + reg = <0x500 0x20>; + interrupts = <0 92 1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; ethmac: ethernet@c9410000 { @@ -167,8 +175,6 @@ 0xc1108108 0x4>; interrupts = <0 8 1>; interrupt-names = "macirq"; - clocks = <&clk81>; - clock-names = "stmmaceth"; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/meson6.dtsi b/arch/arm/boot/dts/meson6.dtsi index 8b33be15af94..b0fc91ffd6a1 100644 --- a/arch/arm/boot/dts/meson6.dtsi +++ b/arch/arm/boot/dts/meson6.dtsi @@ -51,8 +51,6 @@ model = "Amlogic Meson6 SoC"; compatible = "amlogic,meson6"; - interrupt-parent = <&gic>; - cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi index ebc763eab195..6993077331c7 100644 --- a/arch/arm/boot/dts/meson8.dtsi +++ b/arch/arm/boot/dts/meson8.dtsi @@ -50,8 +50,6 @@ model = "Amlogic Meson8 SoC"; compatible = "amlogic,meson8"; - interrupt-parent = <&gic>; - cpus { #address-cells = <1>; #size-cells = <0>; @@ -91,18 +89,55 @@ clock-frequency = <141666666>; }; - pinctrl_cbus: pinctrl@c1109880 { +}; /* end of / */ + +&aobus { + pinctrl_aobus: pinctrl@84 { + compatible = "amlogic,meson8-aobus-pinctrl"; + reg = <0x84 0xc>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio_ao: ao-bank@14 { + reg = <0x14 0x4>, + <0x2c 0x4>, + <0x24 0x8>; + reg-names = "mux", "pull", "gpio"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_aobus 0 120 16>; + }; + + uart_ao_a_pins: uart_ao_a { + mux { + groups = "uart_tx_ao_a", "uart_rx_ao_a"; + function = "uart_ao"; + }; + }; + + i2c_ao_pins: i2c_mst_ao { + mux { + groups = "i2c_mst_sck_ao", "i2c_mst_sda_ao"; + function = "i2c_mst_ao"; + }; + }; + }; +}; + +&cbus { + pinctrl_cbus: pinctrl@9880 { compatible = "amlogic,meson8-cbus-pinctrl"; - reg = <0xc1109880 0x10>; + reg = <0x9880 0x10>; #address-cells = <1>; #size-cells = <1>; ranges; - gpio: banks@c11080b0 { - reg = <0xc11080b0 0x28>, - <0xc11080e8 0x18>, - <0xc1108120 0x18>, - <0xc1108030 0x30>; + gpio: banks@80b0 { + reg = <0x80b0 0x28>, + <0x80e8 0x18>, + <0x8120 0x18>, + <0x8030 0x30>; reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; #gpio-cells = <2>; @@ -134,36 +169,47 @@ }; }; }; - - pinctrl_aobus: pinctrl@c8100084 { - compatible = "amlogic,meson8-aobus-pinctrl"; - reg = <0xc8100084 0xc>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - gpio_ao: ao-bank@c1108030 { - reg = <0xc8100014 0x4>, - <0xc810002c 0x4>, - <0xc8100024 0x8>; - reg-names = "mux", "pull", "gpio"; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_aobus 0 120 16>; - }; - - uart_ao_a_pins: uart_ao_a { - mux { - groups = "uart_tx_ao_a", "uart_rx_ao_a"; - function = "uart_ao"; - }; - }; - - i2c_ao_pins: i2c_mst_ao { - mux { - groups = "i2c_mst_sck_ao", "i2c_mst_sda_ao"; - function = "i2c_mst_ao"; - }; - }; - }; -}; /* end of / */ +}; + +ðmac { + clocks = <&clk81>; + clock-names = "stmmaceth"; +}; + +&i2c_AO { + clocks = <&clk81>; +}; + +&i2c_A { + clocks = <&clk81>; +}; + +&i2c_B { + clocks = <&clk81>; +}; + +&L2 { + arm,data-latency = <3 3 3>; + arm,tag-latency = <2 2 2>; + arm,filter-ranges = <0x100000 0xc0000000>; +}; + +&spifc { + clocks = <&clk81>; +}; + +&uart_AO { + clocks = <&clk81>; +}; + +&uart_A { + clocks = <&clk81>; +}; + +&uart_B { + clocks = <&clk81>; +}; + +&uart_C { + clocks = <&clk81>; +}; diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi index 828aa49c678c..d9f116a418b2 100644 --- a/arch/arm/boot/dts/meson8b.dtsi +++ b/arch/arm/boot/dts/meson8b.dtsi @@ -47,11 +47,9 @@ #include <dt-bindings/clock/meson8b-clkc.h> #include <dt-bindings/gpio/meson8b-gpio.h> #include <dt-bindings/reset/amlogic,meson8b-reset.h> -#include "skeleton.dtsi" +#include "meson.dtsi" / { - interrupt-parent = <&gic>; - cpus { #address-cells = <1>; #size-cells = <0>; @@ -84,147 +82,113 @@ reg = <0x203>; }; }; +}; /* end of / */ - soc { - compatible = "simple-bus"; +&aobus { + pinctrl_aobus: pinctrl@84 { + compatible = "amlogic,meson8b-aobus-pinctrl"; + reg = <0x84 0xc>; #address-cells = <1>; #size-cells = <1>; ranges; - L2: l2-cache-controller@c4200000 { - compatible = "arm,pl310-cache"; - reg = <0xc4200000 0x1000>; - cache-unified; - cache-level = <2>; - }; - - gic: interrupt-controller@c4301000 { - compatible = "arm,cortex-a9-gic"; - reg = <0xc4301000 0x1000>, - <0xc4300100 0x0100>; - interrupt-controller; - #interrupt-cells = <3>; + gpio_ao: ao-bank@14 { + reg = <0x14 0x4>, + <0x2c 0x4>, + <0x24 0x8>; + reg-names = "mux", "pull", "gpio"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_aobus 0 130 16>; }; - reset: reset-controller@c1104404 { - compatible = "amlogic,meson8b-reset"; - reg = <0xc1104404 0x20>; - #reset-cells = <1>; + uart_ao_a_pins: uart_ao_a { + mux { + groups = "uart_tx_ao_a", "uart_rx_ao_a"; + function = "uart_ao"; + }; }; + }; +}; - wdt: watchdog@c1109900 { - compatible = "amlogic,meson8b-wdt"; - reg = <0xc1109900 0x8>; - interrupts = <0 0 1>; - }; +&cbus { + clkc: clock-controller@4000 { + #clock-cells = <1>; + compatible = "amlogic,meson8b-clkc"; + reg = <0x8000 0x4>, <0x4000 0x460>; + }; - timer@c1109940 { - compatible = "amlogic,meson6-timer"; - reg = <0xc1109940 0x18>; - interrupts = <0 10 1>; - }; + reset: reset-controller@4404 { + compatible = "amlogic,meson8b-reset"; + reg = <0x4404 0x20>; + #reset-cells = <1>; + }; - uart_AO: serial@c81004c0 { - compatible = "amlogic,meson-uart"; - reg = <0xc81004c0 0x18>; - interrupts = <0 90 1>; - clocks = <&clkc CLKID_CLK81>; - status = "disabled"; - }; + pwm_ab: pwm@8550 { + compatible = "amlogic,meson8b-pwm"; + reg = <0x8550 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; - uart_A: serial@c11084c0 { - compatible = "amlogic,meson-uart"; - reg = <0xc11084c0 0x18>; - interrupts = <0 26 1>; - clocks = <&clkc CLKID_CLK81>; - status = "disabled"; - }; + pwm_cd: pwm@8650 { + compatible = "amlogic,meson8b-pwm"; + reg = <0x8650 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; - uart_B: serial@c11084dc { - compatible = "amlogic,meson-uart"; - reg = <0xc11084dc 0x18>; - interrupts = <0 75 1>; - clocks = <&clkc CLKID_CLK81>; - status = "disabled"; - }; + pwm_ef: pwm@86c0 { + compatible = "amlogic,meson8b-pwm"; + reg = <0x86c0 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; - uart_C: serial@c1108700 { - compatible = "amlogic,meson-uart"; - reg = <0xc1108700 0x18>; - interrupts = <0 93 1>; - clocks = <&clkc CLKID_CLK81>; - status = "disabled"; - }; + wdt: watchdog@9900 { + compatible = "amlogic,meson8b-wdt"; + reg = <0x9900 0x8>; + interrupts = <0 0 1>; + }; - clkc: clock-controller@c1104000 { - #clock-cells = <1>; - compatible = "amlogic,meson8b-clkc"; - reg = <0xc1108000 0x4>, <0xc1104000 0x460>; - }; + pinctrl_cbus: pinctrl@9880 { + compatible = "amlogic,meson8b-cbus-pinctrl"; + reg = <0x9880 0x10>; + #address-cells = <1>; + #size-cells = <1>; + ranges; - pwm_ab: pwm@8550 { - compatible = "amlogic,meson8b-pwm"; - reg = <0xc1108550 0x10>; - #pwm-cells = <3>; - status = "disabled"; + gpio: banks@80b0 { + reg = <0x80b0 0x28>, + <0x80e8 0x18>, + <0x8120 0x18>, + <0x8030 0x38>; + reg-names = "mux", "pull", "pull-enable", "gpio"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_cbus 0 0 130>; }; + }; +}; - pwm_cd: pwm@8650 { - compatible = "amlogic,meson8b-pwm"; - reg = <0xc1108650 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; +&L2 { + arm,data-latency = <3 3 3>; + arm,tag-latency = <2 2 2>; + arm,filter-ranges = <0x100000 0xc0000000>; +}; - pwm_ef: pwm@86c0 { - compatible = "amlogic,meson8b-pwm"; - reg = <0xc11086c0 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; +&uart_AO { + clocks = <&clkc CLKID_CLK81>; +}; - pinctrl_cbus: pinctrl@c1109880 { - compatible = "amlogic,meson8b-cbus-pinctrl"; - reg = <0xc1109880 0x10>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - gpio: banks@c11080b0 { - reg = <0xc11080b0 0x28>, - <0xc11080e8 0x18>, - <0xc1108120 0x18>, - <0xc1108030 0x38>; - reg-names = "mux", "pull", "pull-enable", "gpio"; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_cbus 0 0 130>; - }; - }; +&uart_A { + clocks = <&clkc CLKID_CLK81>; +}; - pinctrl_aobus: pinctrl@c8100084 { - compatible = "amlogic,meson8b-aobus-pinctrl"; - reg = <0xc8100084 0xc>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - gpio_ao: ao-bank@c1108030 { - reg = <0xc8100014 0x4>, - <0xc810002c 0x4>, - <0xc8100024 0x8>; - reg-names = "mux", "pull", "gpio"; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_aobus 0 130 16>; - }; +&uart_B { + clocks = <&clkc CLKID_CLK81>; +}; - uart_ao_a_pins: uart_ao_a { - mux { - groups = "uart_tx_ao_a", "uart_rx_ao_a"; - function = "uart_ao"; - }; - }; - }; - }; -}; /* end of / */ +&uart_C { + clocks = <&clkc CLKID_CLK81>; +}; diff --git a/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/arch/arm/boot/dts/omap3-cm-t3x.dtsi index 57b9a028a49a..fccd5383243c 100644 --- a/arch/arm/boot/dts/omap3-cm-t3x.dtsi +++ b/arch/arm/boot/dts/omap3-cm-t3x.dtsi @@ -188,7 +188,7 @@ clock-frequency = <400000>; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; pagesize = <16>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi index f330c69cc683..82aa9c4a0f1c 100644 --- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi +++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi @@ -201,7 +201,8 @@ }; &gpmc { - ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */ + ranges = <0 0 0x30000000 0x1000000 /* CS0: 16MB for NAND */ + 6 0 0x2c000000 0x1000000>; /* CS6: 16MB for DM9000 */ nand@0,0 { compatible = "ti,omap2-nand"; @@ -256,12 +257,8 @@ reg = <0x680000 0xf980000>; }; }; -}; - -&gpmc { - ranges = <6 0 0x2c000000 0x1000000>; /* CS6: 16MB for DM9000 */ - ethernet@0,0 { + ethernet@6,0 { compatible = "davicom,dm9000"; reg = <6 0x000 2 6 0x400 2>; /* CS6, offset 0 and 0x400, IO size 2 */ diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts index 4f9a76544602..c963b31ec3b3 100644 --- a/arch/arm/boot/dts/omap3-evm-37xx.dts +++ b/arch/arm/boot/dts/omap3-evm-37xx.dts @@ -34,7 +34,15 @@ >; }; +&hsusb2_phy { + pinctrl-names = "default"; + pinctrl-0 = <&ehci_phy_pins>; +}; + &omap3_pmx_core { + pinctrl-names = "default"; + pinctrl-0 = <&on_board_gpio_61 &hsusb2_pins>; + dss_dpi_pins1: pinmux_dss_dpi_pins2 { pinctrl-single,pins = < OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */ @@ -98,6 +106,37 @@ >; }; + /* Devices are routed with gpmc_nbe1.gpio_61 to on-board devices */ + on_board_gpio_61: pinmux_ehci_port_select_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x20c8, PIN_OUTPUT | MUX_MODE4) + >; + }; + + /* Used by OHCI and EHCI. OHCI won't work without external phy */ + hsusb2_pins: pinmux_hsusb2_pins { + pinctrl-single,pins = < + + /* mcspi1_cs3.hsusb2_data2 */ + OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* mcspi2_clk.hsusb2_data7 */ + OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* mcspi2_simo.hsusb2_data4 */ + OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* mcspi2_somi.hsusb2_data5 */ + OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* mcspi2_cs0.hsusb2_data6 */ + OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* mcspi2_cs1.hsusb2_data3 */ + OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) + >; + }; + wl12xx_gpio: pinmux_wl12xx_gpio { pinctrl-single,pins = < OMAP3_CORE1_IOPAD(0x2180, PIN_OUTPUT | MUX_MODE4) /* uart1_cts.gpio_150 */ @@ -112,6 +151,46 @@ }; }; +&omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb2_2_pins>; + + ehci_phy_pins: pinmux_ehci_phy_pins { + pinctrl-single,pins = < + + /* EHCI PHY reset GPIO etk_d7.gpio_21 */ + OMAP3630_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4) + + /* EHCI VBUS etk_d8.gpio_22 */ + OMAP3630_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) + >; + }; + + /* Used by OHCI and EHCI. OHCI won't work without external phy */ + hsusb2_2_pins: pinmux_hsusb2_2_pins { + pinctrl-single,pins = < + + /* etk_d10.hsusb2_clk */ + OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) + + /* etk_d11.hsusb2_stp */ + OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) + + /* etk_d12.hsusb2_dir */ + OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* etk_d13.hsusb2_nxt */ + OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* etk_d14.hsusb2_data0 */ + OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) + + /* etk_d15.hsusb2_data1 */ + OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) + >; + }; +}; + &omap3_pmx_wkup { dss_dpi_pins2: pinmux_dss_dpi_pins1 { pinctrl-single,pins = < @@ -153,6 +232,29 @@ pinctrl-0 = <&uart3_pins>; }; +/* + * GPIO_61 (nUSB2_EN_1V8) must be low to enable on-board EHCI USB2 interface + * for bus switch SN74CB3Q3384A, level-shifter SN74AVC16T245DGGR, and 1.8V. + */ +&gpio2 { + en_usb2_port { + gpio-hog; + gpios = <29 GPIO_ACTIVE_HIGH>; /* gpio_61 */ + output-low; + line-name = "enable usb2 port"; + }; +}; + +/* T2_GPIO_2 low to route GPIO_61 to on-board devices */ +&twl_gpio { + en_on_board_gpio_61 { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "en_hsusb2_clk"; + }; +}; + &gpmc { ranges = <0 0 0x30000000 0x1000000>, /* CS0: 16MB for NAND */ <5 0 0x2c000000 0x01000000>; diff --git a/arch/arm/boot/dts/omap3-evm-common.dtsi b/arch/arm/boot/dts/omap3-evm-common.dtsi index 090475083c2f..2b1d6977a535 100644 --- a/arch/arm/boot/dts/omap3-evm-common.dtsi +++ b/arch/arm/boot/dts/omap3-evm-common.dtsi @@ -12,6 +12,24 @@ }; }; + /* HS USB Port 2 Power */ + hsusb2_power: hsusb2_power_reg { + compatible = "regulator-fixed"; + regulator-name = "hsusb2_vbus"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>; /* gpio_22 */ + startup-delay-us = <70000>; + enable-active-high; + }; + + /* HS USB Host PHY on PORT 2 */ + hsusb2_phy: hsusb2_phy { + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; /* gpio_21 */ + vcc-supply = <&hsusb2_power>; + }; + leds { compatible = "gpio-leds"; ledb { @@ -76,7 +94,6 @@ &lcd_3v3 { gpio = <&gpio5 25 GPIO_ACTIVE_LOW>; /* gpio153 */ - enable-active-low; }; &lcd0 { @@ -143,6 +160,14 @@ >; }; +&usbhshost { + port2-mode = "ehci-phy"; +}; + +&usbhsehci { + phys = <0 &hsusb2_phy>; +}; + &usb_otg_hs { interface-type = <0>; usb-phy = <&usb2_phy>; @@ -159,3 +184,10 @@ reg = <5 0 0xff>; }; }; + +&vaux2 { + regulator-name = "usb_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; +}; diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi index 9ec737069369..4504908c23fe 100644 --- a/arch/arm/boot/dts/omap3-gta04.dtsi +++ b/arch/arm/boot/dts/omap3-gta04.dtsi @@ -419,7 +419,7 @@ /* RFID EEPROM */ m24lr64@50 { - compatible = "at,24c64"; + compatible = "atmel,24c64"; reg = <0x50>; }; }; diff --git a/arch/arm/boot/dts/omap3-sb-t35.dtsi b/arch/arm/boot/dts/omap3-sb-t35.dtsi index 73643fabde5d..4476fb685a1b 100644 --- a/arch/arm/boot/dts/omap3-sb-t35.dtsi +++ b/arch/arm/boot/dts/omap3-sb-t35.dtsi @@ -50,7 +50,6 @@ pinctrl-names = "default"; pinctrl-0 = <&sb_t35_audio_amp>; gpio = <&gpio2 29 GPIO_ACTIVE_LOW>; /* gpio_61 */ - enable-active-low; regulator-always-on; }; }; @@ -90,7 +89,7 @@ clock-frequency = <400000>; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; pagesize = <16>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/omap3-tao3530.dtsi b/arch/arm/boot/dts/omap3-tao3530.dtsi index dc80886b5329..06ac0f80bcf0 100644 --- a/arch/arm/boot/dts/omap3-tao3530.dtsi +++ b/arch/arm/boot/dts/omap3-tao3530.dtsi @@ -63,7 +63,6 @@ regulator-min-microvolt = <3150000>; regulator-max-microvolt = <3150000>; gpio = <&gpio5 29 GPIO_ACTIVE_LOW>; /* gpio_157 */ - enable-active-low; startup-delay-us = <10000>; }; }; diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts index 89eb607f4a9e..13f8d8640208 100644 --- a/arch/arm/boot/dts/omap4-droid4-xt894.dts +++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts @@ -453,6 +453,15 @@ OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE7) >; }; + + uart4_pins: pinmux_uart4_pins { + pinctrl-single,pins = < + OMAP4_IOPAD(0x15c, PIN_INPUT | MUX_MODE0) /* uart4_rx */ + OMAP4_IOPAD(0x15e, PIN_OUTPUT | MUX_MODE0) /* uart4_tx */ + OMAP4_IOPAD(0x110, PIN_INPUT_PULLUP | MUX_MODE5) /* uart4_cts */ + OMAP4_IOPAD(0x112, PIN_OUTPUT_PULLUP | MUX_MODE5) /* uart4_rts */ + >; + }; }; &omap4_pmx_wkup { @@ -469,6 +478,17 @@ &omap4_pmx_core 0x17c>; }; +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins>; + + bluetooth { + compatible = "ti,wl1285-st"; + enable-gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>; /* gpio 174 */ + max-speed = <3686400>; + }; +}; + &usbhsehci { phys = <&hsusb1_phy>; }; diff --git a/arch/arm/boot/dts/omap4-duovero.dtsi b/arch/arm/boot/dts/omap4-duovero.dtsi index ec0bd9779e1a..6e6810c258eb 100644 --- a/arch/arm/boot/dts/omap4-duovero.dtsi +++ b/arch/arm/boot/dts/omap4-duovero.dtsi @@ -12,6 +12,10 @@ model = "Gumstix Duovero"; compatible = "gumstix,omap4-duovero", "ti,omap4430", "ti,omap4"; + chosen { + stdout-path = &uart3; + }; + memory@80000000 { device_type = "memory"; reg = <0x80000000 0x40000000>; /* 1 GB */ diff --git a/arch/arm/boot/dts/omap4-var-som-om44.dtsi b/arch/arm/boot/dts/omap4-var-som-om44.dtsi index 758b6eb7ae43..6500bfc8d130 100644 --- a/arch/arm/boot/dts/omap4-var-som-om44.dtsi +++ b/arch/arm/boot/dts/omap4-var-som-om44.dtsi @@ -241,7 +241,7 @@ }; eeprom@50 { - compatible = "microchip,24c32"; + compatible = "microchip,24c32", "atmel,24c32"; reg = <0x50>; }; }; diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts index b153f604932a..78397f66d0b2 100644 --- a/arch/arm/boot/dts/omap5-cm-t54.dts +++ b/arch/arm/boot/dts/omap5-cm-t54.dts @@ -404,7 +404,7 @@ clock-frequency = <400000>; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; pagesize = <16>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/omap5-sbc-t54.dts b/arch/arm/boot/dts/omap5-sbc-t54.dts index 337bbbc01a35..7b8810d13257 100644 --- a/arch/arm/boot/dts/omap5-sbc-t54.dts +++ b/arch/arm/boot/dts/omap5-sbc-t54.dts @@ -44,7 +44,7 @@ clock-frequency = <400000>; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c02"; pagesize = <16>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts index 0d42c46f13e7..ec2c8baef62a 100644 --- a/arch/arm/boot/dts/omap5-uevm.dts +++ b/arch/arm/boot/dts/omap5-uevm.dts @@ -137,6 +137,13 @@ }; }; +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + + cd-gpios = <&gpio5 24 GPIO_ACTIVE_LOW>; /* gpio5_152 */ +}; + &omap5_pmx_core { evm_keys_pins: pinmux_evm_keys_gpio_pins { pinctrl-single,pins = < @@ -150,6 +157,12 @@ OMAP5_IOPAD(0x1c8, PIN_INPUT | MUX_MODE0) /* i2c5_sda */ >; }; + + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + OMAP5_IOPAD(0x1d4, PIN_INPUT_PULLUP | MUX_MODE6) /* gpio5_152 */ + >; + }; }; &tpd12s015 { diff --git a/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval.dts b/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval.dts index 8f5de029bca9..f245064f320e 100644 --- a/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval.dts +++ b/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval.dts @@ -320,43 +320,37 @@ }; /* OTG */ - phy@12500000 { - status = "okay"; - dr_mode = "peripheral"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l4>; - }; - - phy@12520000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - phy@12530000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - gadget@12500000 { - status = "okay"; - }; - - /* OTG */ usb@12500000 { status = "okay"; + dr_mode = "peripheral"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + }; }; usb@12520000 { status = "okay"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; usb@12530000 { status = "okay"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; amba { diff --git a/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts b/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts index e39440a86739..3483a66e44c1 100644 --- a/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts +++ b/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts @@ -321,21 +321,15 @@ }; /* OTG */ - phy@12500000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l4>; - dr_mode = "otg"; - }; - - gadget@12500000 { - status = "okay"; - }; - - /* OTG */ usb@12500000 { status = "okay"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + }; }; amba { diff --git a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts index 35f1d46edded..5b151e425530 100644 --- a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts +++ b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts @@ -150,42 +150,37 @@ }; /* OTG */ - usb1_phy: phy@12500000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l4>; - }; - - usb3_phy: phy@12520000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - usb4_phy: phy@12530000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - gadget1: gadget@12500000 { - status = "ok"; - }; - - /* OTG */ - usb1: usb@12500000 { + usb@12500000 { status = "ok"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + }; }; - usb3: usb@12520000 { + usb@12520000 { status = "okay"; + dr_mode = "host"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; - usb4: usb@12530000 { + usb@12530000 { status = "okay"; + dr_mode = "host"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; /* on board fixed 3.3v supply */ diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts index 881ce707311a..053b5bdd7808 100644 --- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts +++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts @@ -244,42 +244,37 @@ }; /* OTG */ - usb1_phy: phy@12500000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l4>; - }; - - usb3_phy: phy@12520000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - usb4_phy: phy@12530000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l23>; - }; - - gadget1: gadget@12500000 { - status = "okay"; - }; - - /* OTG */ - usb1: usb@12500000 { + usb@12500000 { status = "okay"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + }; }; - usb3: usb@12520000 { + usb@12520000 { status = "okay"; + dr_mode = "host"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; - usb4: usb@12530000 { + usb@12530000 { status = "okay"; + dr_mode = "host"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l23>; + }; + }; }; pci@1b500000 { diff --git a/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts b/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts index a34ba3555454..88a9aff41e2f 100644 --- a/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts +++ b/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts @@ -349,15 +349,15 @@ }; }; - phy@12500000 { - status = "okay"; - vddcx-supply = <&pm8921_s3>; - v3p3-supply = <&pm8921_l3>; - v1p8-supply = <&pm8921_l4>; - }; - - gadget@12500000 { + usb@12500000 { status = "okay"; + dr_mode = "otg"; + ulpi { + phy { + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + }; }; gsbi@1a200000 { diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index 14a6f5ed02de..f3db185a6809 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -197,7 +197,7 @@ clock-frequency = <27000000>; }; - sleep_clk { + sleep_clk: sleep_clk { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <32768>; @@ -884,81 +884,97 @@ }; }; - usb1_phy: phy@12500000 { - compatible = "qcom,usb-otg-ci"; - reg = <0x12500000 0x400>; - interrupts = <GIC_SPI 100 IRQ_TYPE_NONE>; - status = "disabled"; - - clocks = <&gcc USB_HS1_XCVR_CLK>, - <&gcc USB_HS1_H_CLK>; - clock-names = "core", "iface"; - - resets = <&gcc USB_HS1_RESET>; - reset-names = "link"; - }; - - usb3_phy: phy@12520000 { - compatible = "qcom,usb-otg-ci"; - reg = <0x12520000 0x400>; - interrupts = <GIC_SPI 188 IRQ_TYPE_NONE>; - status = "disabled"; - dr_mode = "host"; - - clocks = <&gcc USB_HS3_XCVR_CLK>, - <&gcc USB_HS3_H_CLK>; - clock-names = "core", "iface"; - - resets = <&gcc USB_HS3_RESET>; - reset-names = "link"; - }; - - usb4_phy: phy@12530000 { - compatible = "qcom,usb-otg-ci"; - reg = <0x12530000 0x400>; - interrupts = <GIC_SPI 215 IRQ_TYPE_NONE>; - status = "disabled"; - dr_mode = "host"; - - clocks = <&gcc USB_HS4_XCVR_CLK>, - <&gcc USB_HS4_H_CLK>; - clock-names = "core", "iface"; - - resets = <&gcc USB_HS4_RESET>; - reset-names = "link"; - }; - - gadget1: gadget@12500000 { - compatible = "qcom,ci-hdrc"; - reg = <0x12500000 0x400>; - status = "disabled"; - dr_mode = "peripheral"; - interrupts = <GIC_SPI 100 IRQ_TYPE_NONE>; - usb-phy = <&usb1_phy>; - }; - usb1: usb@12500000 { - compatible = "qcom,ehci-host"; - reg = <0x12500000 0x400>; - interrupts = <GIC_SPI 100 IRQ_TYPE_NONE>; - status = "disabled"; - usb-phy = <&usb1_phy>; + compatible = "qcom,ci-hdrc"; + reg = <0x12500000 0x200>, + <0x12500200 0x200>; + interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc USB_HS1_XCVR_CLK>, <&gcc USB_HS1_H_CLK>; + clock-names = "core", "iface"; + assigned-clocks = <&gcc USB_HS1_XCVR_CLK>; + assigned-clock-rates = <60000000>; + resets = <&gcc USB_HS1_RESET>; + reset-names = "core"; + phy_type = "ulpi"; + ahb-burst-config = <0>; + phys = <&usb_hs1_phy>; + phy-names = "usb-phy"; + status = "disabled"; + #reset-cells = <1>; + + ulpi { + usb_hs1_phy: phy { + compatible = "qcom,usb-hs-phy-apq8064", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&sleep_clk>, <&cxo_board>; + clock-names = "sleep", "ref"; + resets = <&usb1 0>; + reset-names = "por"; + }; + }; }; usb3: usb@12520000 { - compatible = "qcom,ehci-host"; - reg = <0x12520000 0x400>; - interrupts = <GIC_SPI 188 IRQ_TYPE_NONE>; - status = "disabled"; - usb-phy = <&usb3_phy>; + compatible = "qcom,ci-hdrc"; + reg = <0x12520000 0x200>, + <0x12520200 0x200>; + interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc USB_HS3_XCVR_CLK>, <&gcc USB_HS3_H_CLK>; + clock-names = "core", "iface"; + assigned-clocks = <&gcc USB_HS3_XCVR_CLK>; + assigned-clock-rates = <60000000>; + resets = <&gcc USB_HS3_RESET>; + reset-names = "core"; + phy_type = "ulpi"; + ahb-burst-config = <0>; + phys = <&usb_hs3_phy>; + phy-names = "usb-phy"; + status = "disabled"; + #reset-cells = <1>; + + ulpi { + usb_hs3_phy: phy { + compatible = "qcom,usb-hs-phy-apq8064", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&sleep_clk>, <&cxo_board>; + clock-names = "sleep", "ref"; + resets = <&usb3 0>; + reset-names = "por"; + }; + }; }; usb4: usb@12530000 { - compatible = "qcom,ehci-host"; - reg = <0x12530000 0x400>; - interrupts = <GIC_SPI 215 IRQ_TYPE_NONE>; - status = "disabled"; - usb-phy = <&usb4_phy>; + compatible = "qcom,ci-hdrc"; + reg = <0x12530000 0x200>, + <0x12530200 0x200>; + interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc USB_HS4_XCVR_CLK>, <&gcc USB_HS4_H_CLK>; + clock-names = "core", "iface"; + assigned-clocks = <&gcc USB_HS4_XCVR_CLK>; + assigned-clock-rates = <60000000>; + resets = <&gcc USB_HS4_RESET>; + reset-names = "core"; + phy_type = "ulpi"; + ahb-burst-config = <0>; + phys = <&usb_hs4_phy>; + phy-names = "usb-phy"; + status = "disabled"; + #reset-cells = <1>; + + ulpi { + usb_hs4_phy: phy { + compatible = "qcom,usb-hs-phy-apq8064", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&sleep_clk>, <&cxo_board>; + clock-names = "sleep", "ref"; + resets = <&usb4 0>; + reset-names = "por"; + }; + }; }; sata_phy0: phy@1b400000 { diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts index ad51df27dfb7..32f3b81f609c 100644 --- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts +++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts @@ -44,6 +44,26 @@ vqmmc-supply = <&pm8941_l13>; }; + usb@f9a55000 { + status = "ok"; + phys = <&usb_hs2_phy>; + phy-select = <&tcsr 0xb000 1>; + extcon = <&smbb>, <&usb_id>; + vbus-supply = <&chg_otg>; + hnp-disable; + srp-disable; + adp-disable; + ulpi { + phy@b { + status = "ok"; + v3p3-supply = <&pm8941_l24>; + v1p8-supply = <&pm8941_l6>; + extcon = <&smbb>; + qcom,init-seq = /bits/ 8 <0x1 0x63>; + }; + }; + }; + pinctrl@fd510000 { i2c11_pins: i2c11 { diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts index e7c1577d56f4..50966378f9e4 100644 --- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts +++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts @@ -92,7 +92,6 @@ vdd_l9_l10_l17_l22-supply = <&vreg_boost>; vdd_l13_l20_l23_l24-supply = <&vreg_boost>; vdd_l21-supply = <&vreg_boost>; - vin_5vs-supply = <&pm8941_5v>; s1 { regulator-min-microvolt = <1300000>; diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 307bf6a647b3..c5ee68a3f7f5 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -3,6 +3,7 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/clock/qcom,gcc-msm8974.h> #include <dt-bindings/clock/qcom,rpmcc.h> +#include <dt-bindings/reset/qcom,gcc-msm8974.h> #include <dt-bindings/gpio/gpio.h> #include "skeleton.dtsi" @@ -551,6 +552,11 @@ reg = <0xfc400000 0x4000>; }; + tcsr: syscon@fd4a0000 { + compatible = "syscon"; + reg = <0xfd4a0000 0x10000>; + }; + tcsr_mutex_block: syscon@fd484000 { compatible = "syscon"; reg = <0xfd484000 0x2000>; @@ -620,6 +626,50 @@ status = "disabled"; }; + otg: usb@f9a55000 { + compatible = "qcom,ci-hdrc"; + reg = <0xf9a55000 0x200>, + <0xf9a55200 0x200>; + interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_USB_HS_AHB_CLK>, + <&gcc GCC_USB_HS_SYSTEM_CLK>; + clock-names = "iface", "core"; + assigned-clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>; + assigned-clock-rates = <75000000>; + resets = <&gcc GCC_USB_HS_BCR>; + reset-names = "core"; + phy_type = "ulpi"; + dr_mode = "otg"; + ahb-burst-config = <0>; + phy-names = "usb-phy"; + status = "disabled"; + #reset-cells = <1>; + + ulpi { + usb_hs1_phy: phy@a { + compatible = "qcom,usb-hs-phy-msm8974", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; + clock-names = "ref", "sleep"; + resets = <&gcc GCC_USB2A_PHY_BCR>, <&otg 0>; + reset-names = "phy", "por"; + status = "disabled"; + }; + + usb_hs2_phy: phy@b { + compatible = "qcom,usb-hs-phy-msm8974", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&xo_board>, <&gcc GCC_USB2B_PHY_SLEEP_CLK>; + clock-names = "ref", "sleep"; + resets = <&gcc GCC_USB2B_PHY_BCR>, <&otg 1>; + reset-names = "phy", "por"; + status = "disabled"; + }; + }; + }; + rng@f9bff000 { compatible = "qcom,prng"; reg = <0xf9bff000 0x200>; @@ -1021,7 +1071,6 @@ pm8941_s1: s1 {}; pm8941_s2: s2 {}; pm8941_s3: s3 {}; - pm8941_5v: s4 {}; pm8941_l1: l1 {}; pm8941_l2: l2 {}; @@ -1051,9 +1100,6 @@ pm8941_lvs1: lvs1 {}; pm8941_lvs2: lvs2 {}; pm8941_lvs3: lvs3 {}; - - pm8941_5vs1: 5vs1 {}; - pm8941_5vs2: 5vs2 {}; }; }; }; diff --git a/arch/arm/boot/dts/qcom-pm8941.dtsi b/arch/arm/boot/dts/qcom-pm8941.dtsi index f8eb5e31c920..3fc9f34f45bb 100644 --- a/arch/arm/boot/dts/qcom-pm8941.dtsi +++ b/arch/arm/boot/dts/qcom-pm8941.dtsi @@ -26,7 +26,14 @@ bias-pull-up; }; - charger@1000 { + usb_id: misc@900 { + compatible = "qcom,pm8941-misc"; + reg = <0x900>; + interrupts = <0x0 0x9 0 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "usb_id"; + }; + + smbb: charger@1000 { compatible = "qcom,pm8941-charger"; reg = <0x1000>; interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>, @@ -45,6 +52,10 @@ "chg-gone", "usb-valid", "dc-valid"; + + usb-otg-in-supply = <&pm8941_5vs1>; + + chg_otg: otg-vbus { }; }; pm8941_gpios: gpios@c000 { @@ -171,5 +182,28 @@ status = "disabled"; }; + + regulators { + compatible = "qcom,pm8941-regulators"; + interrupts = <0x1 0x83 0x2 0>, <0x1 0x84 0x2 0>; + interrupt-names = "ocp-5vs1", "ocp-5vs2"; + vin_5vs-supply = <&pm8941_5v>; + + pm8941_5v: s4 { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-enable-ramp-delay = <500>; + }; + + pm8941_5vs1: 5vs1 { + regulator-enable-ramp-delay = <1000>; + regulator-pull-down; + regulator-over-current-protection; + qcom,ocp-max-retries = <10>; + qcom,ocp-retry-delay = <30>; + qcom,vs-soft-start-strength = <0>; + regulator-initial-mode = <1>; + }; + }; }; }; diff --git a/arch/arm/boot/dts/r7s72100-gr-peach.dts b/arch/arm/boot/dts/r7s72100-gr-peach.dts new file mode 100644 index 000000000000..a1b2aef984f6 --- /dev/null +++ b/arch/arm/boot/dts/r7s72100-gr-peach.dts @@ -0,0 +1,66 @@ +/* + * Device Tree Source for the GR-Peach board + * + * Copyright (C) 2017 Jacopo Mondi <jacopo+renesas@jmondi.org> + * Copyright (C) 2016 Renesas Electronics + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +#include "r7s72100.dtsi" + +/ { + model = "GR-Peach"; + compatible = "renesas,gr-peach", "renesas,r7s72100"; + + aliases { + serial0 = &scif2; + }; + + chosen { + bootargs = "ignore_loglevel rw root=/dev/mtdblock0"; + stdout-path = "serial0:115200n8"; + }; + + memory@20000000 { + device_type = "memory"; + reg = <0x20000000 0x00a00000>; + + }; + + lbsc { + #address-cells = <1>; + #size-cells = <1>; + }; + + flash@18000000 { + compatible = "mtd-rom"; + probe-type = "map_rom"; + reg = <0x18000000 0x00800000>; + bank-width = <4>; + device-width = <1>; + + #address-cells = <1>; + #size-cells = <1>; + + rootfs@600000 { + label = "rootfs"; + reg = <0x00600000 0x00200000>; + }; + }; +}; + +&extal_clk { + clock-frequency = <13333000>; +}; + +&usb_x1_clk { + clock-frequency = <48000000>; +}; + +&scif2 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi index 0423996e4dcc..5cf53e9943af 100644 --- a/arch/arm/boot/dts/r7s72100.dtsi +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -144,9 +144,9 @@ #clock-cells = <1>; compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0xfcfe0430 4>; - clocks = <&b_clk>; - clock-indices = <R7S72100_CLK_ETHER>; - clock-output-names = "ether"; + clocks = <&b_clk>, <&p1_clk>, <&p1_clk>; + clock-indices = <R7S72100_CLK_ETHER R7S72100_CLK_USB0 R7S72100_CLK_USB1>; + clock-output-names = "ether", "usb0", "usb1"; }; mstp8_clks: mstp8_clks@fcfe0434 { diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index 1f5c9f6dddba..310222634570 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -219,7 +219,7 @@ power-domains = <&pd_c4>; }; - pfc: pfc@e6050000 { + pfc: pin-controller@e6050000 { compatible = "renesas,pfc-r8a73a4"; reg = <0 0xe6050000 0 0x9000>; gpio-controller; diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index 34159a8349de..d37d22682a63 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -299,7 +299,7 @@ status = "disabled"; }; - pfc: pfc@e6050000 { + pfc: pin-controller@e6050000 { compatible = "renesas,pfc-r8a7740"; reg = <0xe6050000 0x8000>, <0xe605800c 0x20>; diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index 1e93c94a9eac..8f3156c0e575 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -142,7 +142,7 @@ interrupt-controller; }; - pfc: pfc@fffc0000 { + pfc: pin-controller@fffc0000 { compatible = "renesas,pfc-r8a7778"; reg = <0xfffc0000 0x118>; }; diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index ae2d9a9c65af..8ee0b2ca5d39 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -286,7 +286,7 @@ status = "disabled"; }; - pfc: pfc@fffc0000 { + pfc: pin-controller@fffc0000 { compatible = "renesas,pfc-r8a7779"; reg = <0xfffc0000 0x23c>; }; diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 99269aaca6fc..416956a42c93 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -614,7 +614,7 @@ max-frequency = <97500000>; }; - pfc: pfc@e6060000 { + pfc: pin-controller@e6060000 { compatible = "renesas,pfc-r8a7790"; reg = <0 0xe6060000 0 0x250>; }; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 4d0c2ce59900..b730c889a404 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -562,7 +562,7 @@ status = "disabled"; }; - pfc: pfc@e6060000 { + pfc: pin-controller@e6060000 { compatible = "renesas,pfc-r8a7791"; reg = <0 0xe6060000 0 0x250>; }; @@ -776,6 +776,15 @@ status = "disabled"; }; + adc: adc@e6e54000 { + compatible = "renesas,r8a7791-gyroadc", "renesas,rcar-gyroadc"; + reg = <0 0xe6e54000 0 64>; + clocks = <&mstp9_clks R8A7791_CLK_GYROADC>; + clock-names = "fck"; + power-domains = <&sysc R8A7791_PD_ALWAYS_ON>; + status = "disabled"; + }; + scif2: serial@e6e58000 { compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", "renesas,scif"; @@ -1425,13 +1434,15 @@ mstp9_clks: mstp9_clks@e6150994 { compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>; - clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, + clocks = <&p_clk>, + <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&p_clk>, <&p_clk>, <&cpg_clocks R8A7791_CLK_QSPI>, <&hp_clk>, <&cp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>; #clock-cells = <1>; clock-indices = < + R8A7791_CLK_GYROADC R8A7791_CLK_GPIO7 R8A7791_CLK_GPIO6 R8A7791_CLK_GPIO5 R8A7791_CLK_GPIO4 R8A7791_CLK_GPIO3 R8A7791_CLK_GPIO2 R8A7791_CLK_GPIO1 R8A7791_CLK_GPIO0 R8A7791_CLK_RCAN1 R8A7791_CLK_RCAN0 R8A7791_CLK_QSPI_MOD R8A7791_CLK_I2C5 @@ -1439,6 +1450,7 @@ R8A7791_CLK_I2C1 R8A7791_CLK_I2C0 >; clock-output-names = + "gyroadc", "gpio7", "gpio6", "gpio5", "gpio4", "gpio3", "gpio2", "gpio1", "gpio0", "rcan1", "rcan0", "qspi_mod", "i2c5", "i2c6", "i2c4", "i2c3", "i2c2", "i2c1", "i2c0"; diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index 806c93f6ae8b..30f083528468 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -253,12 +253,23 @@ }; }; + hdmi-in { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&adv7612_in>; + }; + }; + }; + hdmi-out { compatible = "hdmi-connector"; type = "a"; port { - hdmi_con: endpoint { + hdmi_con_out: endpoint { remote-endpoint = <&adv7511_out>; }; }; @@ -348,16 +359,37 @@ sdhi0_pins: sd0 { groups = "sdhi0_data4", "sdhi0_ctrl"; function = "sdhi0"; + power-source = <3300>; + }; + + sdhi0_pins_uhs: sd0_uhs { + groups = "sdhi0_data4", "sdhi0_ctrl"; + function = "sdhi0"; + power-source = <1800>; }; sdhi1_pins: sd1 { groups = "sdhi1_data4", "sdhi1_ctrl"; function = "sdhi1"; + power-source = <3300>; + }; + + sdhi1_pins_uhs: sd1_uhs { + groups = "sdhi1_data4", "sdhi1_ctrl"; + function = "sdhi1"; + power-source = <1800>; }; sdhi2_pins: sd2 { groups = "sdhi2_data4", "sdhi2_ctrl"; function = "sdhi2"; + power-source = <3300>; + }; + + sdhi2_pins_uhs: sd2_uhs { + groups = "sdhi2_data4", "sdhi2_ctrl"; + function = "sdhi2"; + power-source = <1800>; }; qspi_pins: qspi { @@ -374,6 +406,11 @@ groups = "audio_clk_a"; function = "audio_clk"; }; + + vin0_pins: vin0 { + groups = "vin0_data24", "vin0_sync", "vin0_clkenb", "vin0_clk"; + function = "vin0"; + }; }; ðer { @@ -416,33 +453,40 @@ &sdhi0 { pinctrl-0 = <&sdhi0_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdhi0_pins_uhs>; + pinctrl-names = "default", "state_uhs"; vmmc-supply = <&vcc_sdhi0>; vqmmc-supply = <&vccq_sdhi0>; cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>; + sd-uhs-sdr50; + sd-uhs-sdr104; status = "okay"; }; &sdhi1 { pinctrl-0 = <&sdhi1_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdhi1_pins_uhs>; + pinctrl-names = "default", "state_uhs"; vmmc-supply = <&vcc_sdhi1>; vqmmc-supply = <&vccq_sdhi1>; cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio6 15 GPIO_ACTIVE_HIGH>; + sd-uhs-sdr50; status = "okay"; }; &sdhi2 { pinctrl-0 = <&sdhi2_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdhi2_pins_uhs>; + pinctrl-names = "default", "state_uhs"; vmmc-supply = <&vcc_sdhi2>; vqmmc-supply = <&vccq_sdhi2>; cd-gpios = <&gpio6 22 GPIO_ACTIVE_LOW>; + sd-uhs-sdr50; status = "okay"; }; @@ -524,7 +568,34 @@ port@1 { reg = <1>; adv7511_out: endpoint { - remote-endpoint = <&hdmi_con>; + remote-endpoint = <&hdmi_con_out>; + }; + }; + }; + }; + + hdmi-in@4c { + compatible = "adi,adv7612"; + reg = <0x4c>; + interrupt-parent = <&gpio4>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + default-input = <0>; + + port { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7612_in: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; + }; + + port@2 { + reg = <2>; + adv7612_out: endpoint { + remote-endpoint = <&vin0ep2>; }; }; }; @@ -578,3 +649,24 @@ &ssi1 { shared-pin; }; + +/* HDMI video input */ +&vin0 { + status = "okay"; + pinctrl-0 = <&vin0_pins>; + pinctrl-names = "default"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + vin0ep2: endpoint { + remote-endpoint = <&adv7612_out>; + bus-width = <24>; + hsync-active = <0>; + vsync-active = <0>; + pclk-sample = <1>; + data-active = <1>; + }; + }; +}; diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 4de6041d61f9..13b980f27bbc 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -529,7 +529,7 @@ status = "disabled"; }; - pfc: pfc@e6060000 { + pfc: pin-controller@e6060000 { compatible = "renesas,pfc-r8a7793"; reg = <0 0xe6060000 0 0x250>; }; @@ -542,6 +542,7 @@ dmas = <&dmac0 0xcd>, <&dmac0 0xce>, <&dmac1 0xcd>, <&dmac1 0xce>; dma-names = "tx", "rx", "tx", "rx"; + max-frequency = <195000000>; power-domains = <&sysc R8A7793_PD_ALWAYS_ON>; status = "disabled"; }; @@ -554,6 +555,7 @@ dmas = <&dmac0 0xc1>, <&dmac0 0xc2>, <&dmac1 0xc1>, <&dmac1 0xc2>; dma-names = "tx", "rx", "tx", "rx"; + max-frequency = <97500000>; power-domains = <&sysc R8A7793_PD_ALWAYS_ON>; status = "disabled"; }; @@ -566,6 +568,7 @@ dmas = <&dmac0 0xd3>, <&dmac0 0xd4>, <&dmac1 0xd3>, <&dmac1 0xd4>; dma-names = "tx", "rx", "tx", "rx"; + max-frequency = <97500000>; power-domains = <&sysc R8A7793_PD_ALWAYS_ON>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/r8a77xx-aa104xd12-panel.dtsi b/arch/arm/boot/dts/r8a77xx-aa104xd12-panel.dtsi index 65cb50f0c29f..238d14bb0ebe 100644 --- a/arch/arm/boot/dts/r8a77xx-aa104xd12-panel.dtsi +++ b/arch/arm/boot/dts/r8a77xx-aa104xd12-panel.dtsi @@ -10,10 +10,11 @@ / { panel { - compatible = "mitsubishi,aa104xd12", "panel-dpi"; + compatible = "mitsubishi,aa104xd12", "panel-lvds"; width-mm = <210>; height-mm = <158>; + data-mapping = "jeida-18"; panel-timing { /* 1024x768 @65Hz */ diff --git a/arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi b/arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi index a07ebf8f6938..04aafd479775 100644 --- a/arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi +++ b/arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi @@ -10,10 +10,11 @@ / { panel { - compatible = "mitsubishi,aa121td01", "panel-dpi"; + compatible = "mitsubishi,aa121td01", "panel-lvds"; width-mm = <261>; height-mm = <163>; + data-mapping = "jeida-18"; panel-timing { /* 1280x800 @60Hz */ diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi index 48a0c1cf4301..df574135797a 100644 --- a/arch/arm/boot/dts/rk322x.dtsi +++ b/arch/arm/boot/dts/rk322x.dtsi @@ -66,10 +66,7 @@ compatible = "arm,cortex-a7"; reg = <0xf00>; resets = <&cru SRST_CORE0>; - operating-points = < - /* KHz uV */ - 816000 1000000 - >; + operating-points-v2 = <&cpu0_opp_table>; #cooling-cells = <2>; /* min followed by max */ clock-latency = <40000>; clocks = <&cru ARMCLK>; @@ -80,6 +77,7 @@ compatible = "arm,cortex-a7"; reg = <0xf01>; resets = <&cru SRST_CORE1>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu2: cpu@f02 { @@ -87,6 +85,7 @@ compatible = "arm,cortex-a7"; reg = <0xf02>; resets = <&cru SRST_CORE2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu3: cpu@f03 { @@ -94,6 +93,35 @@ compatible = "arm,cortex-a7"; reg = <0xf03>; resets = <&cru SRST_CORE3>; + operating-points-v2 = <&cpu0_opp_table>; + }; + }; + + cpu0_opp_table: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <950000>; + clock-latency-ns = <40000>; + opp-suspend; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <975000>; + }; + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <1000000>; + }; + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <1175000>; + }; + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1275000>; }; }; @@ -280,6 +308,14 @@ status = "disabled"; }; + wdt: watchdog@110a0000 { + compatible = "snps,dw-wdt"; + reg = <0x110a0000 0x100>; + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_CPU>; + status = "disabled"; + }; + pwm0: pwm@110b0000 { compatible = "rockchip,rk3288-pwm"; reg = <0x110b0000 0x10>; @@ -338,8 +374,18 @@ rockchip,grf = <&grf>; #clock-cells = <1>; #reset-cells = <1>; - assigned-clocks = <&cru PLL_GPLL>; - assigned-clock-rates = <594000000>; + assigned-clocks = + <&cru PLL_GPLL>, <&cru ARMCLK>, + <&cru PLL_CPLL>, <&cru ACLK_PERI>, + <&cru HCLK_PERI>, <&cru PCLK_PERI>, + <&cru ACLK_CPU>, <&cru HCLK_CPU>, + <&cru PCLK_CPU>; + assigned-clock-rates = + <594000000>, <816000000>, + <500000000>, <150000000>, + <150000000>, <75000000>, + <150000000>, <150000000>, + <75000000>; }; thermal-zones { @@ -388,6 +434,8 @@ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; clock-names = "tsadc", "apb_pclk"; + assigned-clocks = <&cru SCLK_TSADC>; + assigned-clock-rates = <32768>; resets = <&cru SRST_TSADC>; reset-names = "tsadc-apb"; pinctrl-names = "init", "default", "sleep"; @@ -621,9 +669,9 @@ <0 12 RK_FUNC_1 &pcfg_pull_none>, <0 13 RK_FUNC_1 &pcfg_pull_none>, <0 14 RK_FUNC_1 &pcfg_pull_none>, - <1 2 RK_FUNC_1 &pcfg_pull_none>, - <1 4 RK_FUNC_1 &pcfg_pull_none>, - <1 5 RK_FUNC_1 &pcfg_pull_none>; + <1 2 RK_FUNC_2 &pcfg_pull_none>, + <1 4 RK_FUNC_2 &pcfg_pull_none>, + <1 5 RK_FUNC_2 &pcfg_pull_none>; }; }; @@ -693,10 +741,15 @@ uart2 { uart2_xfer: uart2-xfer { - rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_none>, + rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_up>, <1 19 RK_FUNC_2 &pcfg_pull_none>; }; + uart21_xfer: uart21-xfer { + rockchip,pins = <1 10 RK_FUNC_2 &pcfg_pull_up>, + <1 9 RK_FUNC_2 &pcfg_pull_none>; + }; + uart2_cts: uart2-cts { rockchip,pins = <0 25 RK_FUNC_1 &pcfg_pull_none>; }; diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi index 10793ac18599..864747342e3e 100644 --- a/arch/arm/boot/dts/rk3288-firefly.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly.dtsi @@ -219,6 +219,11 @@ status = "ok"; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &hdmi { ddc-i2c-bus = <&i2c5>; status = "okay"; diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi index f0778a46bca9..749a9b86e6e2 100644 --- a/arch/arm/boot/dts/rk3288-rock2-som.dtsi +++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi @@ -113,6 +113,11 @@ tx_delay = <0x30>; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &i2c0 { status = "okay"; diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts index a23a94811be8..8ed25e9f60bc 100644 --- a/arch/arm/boot/dts/rk3288-rock2-square.dts +++ b/arch/arm/boot/dts/rk3288-rock2-square.dts @@ -125,10 +125,6 @@ gpio = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&host_vbus_drv>; - /* Always on as the rockchip usb phy doesn't have a vbus-supply - * property - */ - regulator-always-on; regulator-name = "vcc_host"; }; @@ -279,6 +275,10 @@ status = "okay"; }; +&usbphy1 { + vbus-supply = <&vcc_usb_host>; +}; + &usb_host0_ehci { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi index 5d1eb0a25827..d709fa1847f9 100644 --- a/arch/arm/boot/dts/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi @@ -161,6 +161,11 @@ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &hdmi { ddc-i2c-bus = <&i2c5>; status = "okay"; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index ad5d6022e95f..2484f11761ea 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -43,6 +43,7 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/pinctrl/rockchip.h> #include <dt-bindings/clock/rk3288-cru.h> +#include <dt-bindings/power/rk3288-power.h> #include <dt-bindings/thermal/thermal.h> #include <dt-bindings/power/rk3288-power.h> #include <dt-bindings/soc/rockchip,boot-mode.h> @@ -1125,6 +1126,48 @@ }; }; + gpu: mali@ffa30000 { + compatible = "rockchip,rk3288-mali", "arm,mali-t760", "arm,mali-midgard"; + reg = <0xffa30000 0x10000>; + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "job", "mmu", "gpu"; + clocks = <&cru ACLK_GPU>; + operating-points-v2 = <&gpu_opp_table>; + power-domains = <&power RK3288_PD_GPU>; + status = "disabled"; + }; + + gpu_opp_table: gpu-opp-table { + compatible = "operating-points-v2"; + + opp@100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <950000>; + }; + opp@200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <950000>; + }; + opp@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <1000000>; + }; + opp@400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <1100000>; + }; + opp@500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <1200000>; + }; + opp@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <1250000>; + }; + }; + qos_gpu_r: qos@ffaa0000 { compatible = "syscon"; reg = <0xffaa0000 0x20>; diff --git a/arch/arm/boot/dts/rk1108-evb.dts b/arch/arm/boot/dts/rv1108-evb.dts index 3956cff4ca79..58cf4ac079c3 100644 --- a/arch/arm/boot/dts/rk1108-evb.dts +++ b/arch/arm/boot/dts/rv1108-evb.dts @@ -40,11 +40,11 @@ /dts-v1/; -#include "rk1108.dtsi" +#include "rv1108.dtsi" / { - model = "Rockchip RK1108 Evaluation board"; - compatible = "rockchip,rk1108-evb", "rockchip,rk1108"; + model = "Rockchip RV1108 Evaluation board"; + compatible = "rockchip,rv1108-evb", "rockchip,rv1108"; memory@60000000 { device_type = "memory"; diff --git a/arch/arm/boot/dts/rk1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi index 1297924db6ad..437098b556eb 100644 --- a/arch/arm/boot/dts/rk1108.dtsi +++ b/arch/arm/boot/dts/rv1108.dtsi @@ -47,7 +47,7 @@ #address-cells = <1>; #size-cells = <1>; - compatible = "rockchip,rk1108"; + compatible = "rockchip,rv1108"; interrupt-parent = <&gic>; @@ -113,7 +113,7 @@ }; uart2: serial@10210000 { - compatible = "rockchip,rk1108-uart", "snps,dw-apb-uart"; + compatible = "rockchip,rv1108-uart", "snps,dw-apb-uart"; reg = <0x10210000 0x100>; interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; @@ -127,7 +127,7 @@ }; uart1: serial@10220000 { - compatible = "rockchip,rk1108-uart", "snps,dw-apb-uart"; + compatible = "rockchip,rv1108-uart", "snps,dw-apb-uart"; reg = <0x10220000 0x100>; interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; @@ -141,7 +141,7 @@ }; uart0: serial@10230000 { - compatible = "rockchip,rk1108-uart", "snps,dw-apb-uart"; + compatible = "rockchip,rv1108-uart", "snps,dw-apb-uart"; reg = <0x10230000 0x100>; interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; @@ -155,17 +155,17 @@ }; grf: syscon@10300000 { - compatible = "rockchip,rk1108-grf", "syscon"; + compatible = "rockchip,rv1108-grf", "syscon"; reg = <0x10300000 0x1000>; }; pmugrf: syscon@20060000 { - compatible = "rockchip,rk1108-pmugrf", "syscon"; + compatible = "rockchip,rv1108-pmugrf", "syscon"; reg = <0x20060000 0x1000>; }; cru: clock-controller@20200000 { - compatible = "rockchip,rk1108-cru"; + compatible = "rockchip,rv1108-cru"; reg = <0x20200000 0x1000>; rockchip,grf = <&grf>; #clock-cells = <1>; @@ -173,7 +173,7 @@ }; emmc: dwmmc@30110000 { - compatible = "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc"; + compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; clock-freq-min-max = <400000 150000000>; clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; @@ -185,7 +185,7 @@ }; sdio: dwmmc@30120000 { - compatible = "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc"; + compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; clock-freq-min-max = <400000 150000000>; clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; @@ -197,7 +197,7 @@ }; sdmmc: dwmmc@30130000 { - compatible = "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc"; + compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; clock-freq-min-max = <400000 100000000>; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi index 8067c71c3a38..ce95dcb8bdf9 100644 --- a/arch/arm/boot/dts/sama5d2.dtsi +++ b/arch/arm/boot/dts/sama5d2.dtsi @@ -762,6 +762,18 @@ atmel,clk-output-range = <0 83000000>; }; + can0_clk: can0_clk { + #clock-cells = <0>; + reg = <56>; + atmel,clk-output-range = <0 83000000>; + }; + + can1_clk: can1_clk { + #clock-cells = <0>; + reg = <57>; + atmel,clk-output-range = <0 83000000>; + }; + classd_clk: classd_clk { #clock-cells = <0>; reg = <59>; @@ -890,6 +902,18 @@ #clock-cells = <0>; reg = <55>; }; + + can0_gclk: can0_gclk { + #clock-cells = <0>; + reg = <56>; + atmel,clk-output-range = <0 80000000>; + }; + + can1_gclk: can1_gclk { + #clock-cells = <0>; + reg = <57>; + atmel,clk-output-range = <0 80000000>; + }; }; }; @@ -1144,6 +1168,22 @@ clocks = <&clk32k>; }; + can0: can@f8054000 { + compatible = "bosch,m_can"; + reg = <0xf8054000 0x4000>, <0x210000 0x4000>; + reg-names = "m_can", "message_ram"; + interrupts = <56 IRQ_TYPE_LEVEL_HIGH 7>, + <64 IRQ_TYPE_LEVEL_HIGH 7>; + interrupt-names = "int0", "int1"; + clocks = <&can0_clk>, <&can0_gclk>; + clock-names = "hclk", "cclk"; + assigned-clocks = <&can0_gclk>; + assigned-clock-parents = <&utmi>; + assigned-clock-rates = <40000000>; + bosch,mram-cfg = <0x0 0 0 64 0 0 32 32>; + status = "disabled"; + }; + spi1: spi@fc000000 { compatible = "atmel,at91rm9200-spi"; reg = <0xfc000000 0x100>; @@ -1305,6 +1345,22 @@ status = "okay"; }; + can1: can@fc050000 { + compatible = "bosch,m_can"; + reg = <0xfc050000 0x4000>, <0x210000 0x4000>; + reg-names = "m_can", "message_ram"; + interrupts = <57 IRQ_TYPE_LEVEL_HIGH 7>, + <65 IRQ_TYPE_LEVEL_HIGH 7>; + interrupt-names = "int0", "int1"; + clocks = <&can1_clk>, <&can1_gclk>; + clock-names = "hclk", "cclk"; + assigned-clocks = <&can1_gclk>; + assigned-clock-parents = <&utmi>; + assigned-clock-rates = <40000000>; + bosch,mram-cfg = <0x1100 0 0 64 0 0 32 32>; + status = "disabled"; + }; + sfrbu: sfr@fc05c000 { compatible = "atmel,sama5d2-sfrbu", "syscon"; reg = <0xfc05c000 0x20>; diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index 6b01ab354e88..4ea5c5a16c57 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -444,7 +444,7 @@ status = "disabled"; }; - pfc: pfc@e6050000 { + pfc: pin-controller@e6050000 { compatible = "renesas,pfc-sh73a0"; reg = <0xe6050000 0x8000>, <0xe605801c 0x1c>; diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts index f2a01fe2bebc..f80d37ddc4c6 100644 --- a/arch/arm/boot/dts/sun4i-a10-a1000.dts +++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts @@ -171,7 +171,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts b/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts index 942d739a4384..6b02de592a02 100644 --- a/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts +++ b/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts @@ -109,7 +109,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts index 17f8c5ec011c..a7d61994b8fd 100644 --- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts @@ -128,7 +128,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts index d844938e2aa7..404ce7694899 100644 --- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts +++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts @@ -142,7 +142,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -182,6 +182,10 @@ #include "axp209.dtsi" +&ac_power_supply { + status = "okay"; +}; + ®_dcdc2 { regulator-always-on; regulator-min-microvolt = <1000000>; diff --git a/arch/arm/boot/dts/sun4i-a10-dserve-dsrv9703c.dts b/arch/arm/boot/dts/sun4i-a10-dserve-dsrv9703c.dts index aad3bec1cb39..e0777ae808c7 100644 --- a/arch/arm/boot/dts/sun4i-a10-dserve-dsrv9703c.dts +++ b/arch/arm/boot/dts/sun4i-a10-dserve-dsrv9703c.dts @@ -163,7 +163,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts b/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts index 9616cdecce93..d8bfd7b74916 100644 --- a/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts +++ b/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts @@ -146,7 +146,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH01 */ diff --git a/arch/arm/boot/dts/sun4i-a10-hackberry.dts b/arch/arm/boot/dts/sun4i-a10-hackberry.dts index a1a7282199d5..856cfc9128e6 100644 --- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts +++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts @@ -107,7 +107,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts b/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts index 85dcf81ab64e..6506595268b2 100644 --- a/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts +++ b/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts @@ -79,7 +79,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -120,10 +120,6 @@ status = "okay"; }; -&usb2_vbus_pin_a { - pins = "PH6"; -}; - &usb_otg { dr_mode = "otg"; status = "okay"; diff --git a/arch/arm/boot/dts/sun4i-a10-inet1.dts b/arch/arm/boot/dts/sun4i-a10-inet1.dts index b8923b92cb36..d51d8c302daf 100644 --- a/arch/arm/boot/dts/sun4i-a10-inet1.dts +++ b/arch/arm/boot/dts/sun4i-a10-inet1.dts @@ -161,7 +161,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts index a1a2bbb3f9d3..a8e479fe43ca 100644 --- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts +++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts @@ -147,7 +147,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts index 4a27eb9102cd..2acb89a87d41 100644 --- a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts +++ b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts @@ -305,7 +305,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts b/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts index 4e798f014c99..92e3e030ced3 100644 --- a/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts +++ b/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts @@ -100,7 +100,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts b/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts index 308dc1513041..92b2d4af3d21 100644 --- a/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts +++ b/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts @@ -140,7 +140,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-marsboard.dts b/arch/arm/boot/dts/sun4i-a10-marsboard.dts index 98a5f7258dca..0f927da28ee1 100644 --- a/arch/arm/boot/dts/sun4i-a10-marsboard.dts +++ b/arch/arm/boot/dts/sun4i-a10-marsboard.dts @@ -141,7 +141,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts index 484c57493bd2..a5ed9e4e22c6 100644 --- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts +++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts @@ -97,7 +97,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-mk802.dts b/arch/arm/boot/dts/sun4i-a10-mk802.dts index 2b75745cd246..81db6824a2c7 100644 --- a/arch/arm/boot/dts/sun4i-a10-mk802.dts +++ b/arch/arm/boot/dts/sun4i-a10-mk802.dts @@ -72,7 +72,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-mk802ii.dts b/arch/arm/boot/dts/sun4i-a10-mk802ii.dts index c861fa7e356c..e74a881fd9a7 100644 --- a/arch/arm/boot/dts/sun4i-a10-mk802ii.dts +++ b/arch/arm/boot/dts/sun4i-a10-mk802ii.dts @@ -83,7 +83,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts index 3a2522a9419d..462412ee903c 100644 --- a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts +++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts @@ -145,7 +145,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-pcduino.dts b/arch/arm/boot/dts/sun4i-a10-pcduino.dts index 83596fd2ccfc..84f55e76df0c 100644 --- a/arch/arm/boot/dts/sun4i-a10-pcduino.dts +++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts @@ -147,7 +147,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts b/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts index a68c7cc53b94..c0f8c88b5a7d 100644 --- a/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts +++ b/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts @@ -149,7 +149,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index b63668ece151..41c2579143fd 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -1030,12 +1030,6 @@ bias-pull-up; }; - mmc0_cd_pin_reference_design: mmc0_cd_pin@0 { - pins = "PH1"; - function = "gpio_in"; - bias-pull-up; - }; - ps20_pins_a: ps20@0 { pins = "PI20", "PI21"; function = "ps2"; diff --git a/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts b/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts index c6f742a7e69f..d2dee8d434bf 100644 --- a/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts +++ b/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts @@ -136,14 +136,6 @@ status = "okay"; }; -&usb0_vbus_pin_a { - pins = "PG13"; -}; - -&usb1_vbus_pin_a { - pins = "PB10"; -}; - &usb_otg { dr_mode = "host"; status = "okay"; diff --git a/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts b/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts index a27c3fa58736..16f839df4227 100644 --- a/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts +++ b/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts @@ -168,10 +168,6 @@ status = "okay"; }; -&usb1_vbus_pin_a { - pins = "PG13"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>; diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts index 894f874a5beb..da95118af4dc 100644 --- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts +++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts @@ -63,6 +63,17 @@ stdout-path = "serial0:115200n8"; }; + connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + leds { compatible = "gpio-leds"; pinctrl-names = "default"; @@ -76,6 +87,10 @@ }; }; +&be0 { + status = "okay"; +}; + &ehci0 { status = "okay"; }; @@ -91,6 +106,16 @@ status = "okay"; }; +&hdmi { + status = "okay"; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + &i2c0 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins_a>; @@ -248,6 +273,10 @@ status = "okay"; }; +&tcon0 { + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; @@ -271,10 +300,6 @@ status = "okay"; }; -&usb0_vbus_pin_a { - pins = "PG11"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>; diff --git a/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts b/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts index ea3e5655a61b..5482be174e12 100644 --- a/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts +++ b/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts @@ -216,10 +216,6 @@ status = "okay"; }; -&usb1_vbus_pin_a { - pins = "PG12"; -}; - &usbphy { usb1_vbus-supply = <®_usb1_vbus>; status = "okay"; diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 1e38ff80366c..18f25c5e75ae 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -71,7 +71,46 @@ }; }; + display-engine { + compatible = "allwinner,sun5i-a10s-display-engine"; + allwinner,pipelines = <&fe0>; + }; + soc@01c00000 { + hdmi: hdmi@01c16000 { + compatible = "allwinner,sun5i-a10s-hdmi"; + reg = <0x01c16000 0x1000>; + interrupts = <58>; + clocks = <&ccu CLK_AHB_HDMI>, <&ccu CLK_HDMI>, + <&ccu 9>, + <&ccu 16>; + clock-names = "ahb", "mod", "pll-0", "pll-1"; + dmas = <&dma SUN4I_DMA_NORMAL 16>, + <&dma SUN4I_DMA_NORMAL 16>, + <&dma SUN4I_DMA_DEDICATED 24>; + dma-names = "ddc-tx", "ddc-rx", "audio-tx"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in: port@0 { + reg = <0>; + + hdmi_in_tcon0: endpoint { + remote-endpoint = <&tcon0_out_hdmi>; + }; + }; + + hdmi_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; + }; + pwm: pwm@01c20e00 { compatible = "allwinner,sun5i-a10s-pwm"; reg = <0x01c20e00 0xc>; @@ -128,3 +167,11 @@ &sram_a { }; + +&tcon0_out { + tcon0_out_hdmi: endpoint@2 { + reg = <2>; + remote-endpoint = <&hdmi_in_tcon0>; + allwinner,tcon-channel = <1>; + }; +}; diff --git a/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts b/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts index 34411d27aadf..3dbb0d7c2f8c 100644 --- a/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts +++ b/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts @@ -207,10 +207,6 @@ status = "okay"; }; -&usb0_vbus_pin_a { - pins = "PG12"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; diff --git a/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts b/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts index 2489c16f7efa..584fa579ded2 100644 --- a/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts +++ b/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts @@ -186,7 +186,6 @@ }; ®_usb0_vbus { - pinctrl-0 = <&usb0_vbus_pin_a>; gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ status = "okay"; }; @@ -202,10 +201,6 @@ status = "okay"; }; -&usb0_vbus_pin_a { - pins = "PG12"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts index 95f591bb8ced..38072c7e10e2 100644 --- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts +++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts @@ -269,10 +269,6 @@ status = "okay"; }; -&usb0_vbus_pin_a { - pins = "PG12"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts index d0785602663b..879a4b0f3bd5 100644 --- a/arch/arm/boot/dts/sun5i-r8-chip.dts +++ b/arch/arm/boot/dts/sun5i-r8-chip.dts @@ -132,6 +132,10 @@ status = "okay"; }; +&battery_power_supply { + status = "okay"; +}; + &i2c1 { pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins_a>; diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi index 5175f9cc9bed..0e29f1d98a9e 100644 --- a/arch/arm/boot/dts/sun5i.dtsi +++ b/arch/arm/boot/dts/sun5i.dtsi @@ -272,6 +272,7 @@ tcon0_out_tve0: endpoint@1 { reg = <1>; remote-endpoint = <&tve0_in_tcon0>; + allwinner,tcon-channel = <1>; }; }; }; diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts index d4f74f476f25..9ecb5f0b3f83 100644 --- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts +++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts @@ -253,6 +253,10 @@ #include "axp22x.dtsi" +&ac_power_supply { + status = "okay"; +}; + ®_aldo1 { regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; @@ -319,7 +323,6 @@ &tcon0 { pinctrl-names = "default"; pinctrl-0 = <&lcd0_rgb888_pins>; - status = "okay"; }; &tcon0_out { @@ -344,11 +347,6 @@ status = "okay"; }; -&usb1_vbus_pin_a { - /* different pin from sunxi-common-regulators */ - pins = "PH24"; -}; - &usbphy { usb0_id_det-gpio = <&pio 0 15 GPIO_ACTIVE_HIGH>; /* PA15 */ usb0_vbus_det-gpio = <&pio 0 16 GPIO_ACTIVE_HIGH>; /* PA16 */ diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index 9c999d3788f6..d0cede5aaeb5 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -232,7 +232,7 @@ de: display-engine { compatible = "allwinner,sun6i-a31-display-engine"; - allwinner,pipelines = <&fe0>; + allwinner,pipelines = <&fe0>, <&fe1>; status = "disabled"; }; @@ -264,7 +264,6 @@ "tcon-ch0", "tcon-ch1"; clock-output-names = "tcon0-pixel-clock"; - status = "disabled"; ports { #address-cells = <1>; @@ -289,6 +288,43 @@ }; }; + tcon1: lcd-controller@01c0d000 { + compatible = "allwinner,sun6i-a31-tcon"; + reg = <0x01c0d000 0x1000>; + interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + resets = <&ccu RST_AHB1_LCD1>; + reset-names = "lcd"; + clocks = <&ccu CLK_AHB1_LCD1>, + <&ccu CLK_LCD1_CH0>, + <&ccu CLK_LCD1_CH1>; + clock-names = "ahb", + "tcon-ch0", + "tcon-ch1"; + clock-output-names = "tcon1-pixel-clock"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + tcon1_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + tcon1_in_drc1: endpoint@0 { + reg = <0>; + remote-endpoint = <&drc1_out_tcon1>; + }; + }; + + tcon1_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; + }; + mmc0: mmc@01c0f000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c0f000 0x1000>; @@ -896,6 +932,130 @@ reg = <0>; remote-endpoint = <&be0_in_fe0>; }; + + fe0_out_be1: endpoint@1 { + reg = <1>; + remote-endpoint = <&be1_in_fe0>; + }; + }; + }; + }; + + fe1: display-frontend@01e20000 { + compatible = "allwinner,sun6i-a31-display-frontend"; + reg = <0x01e20000 0x20000>; + interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_AHB1_FE1>, <&ccu CLK_FE1>, + <&ccu CLK_DRAM_FE1>; + clock-names = "ahb", "mod", + "ram"; + resets = <&ccu RST_AHB1_FE1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + fe1_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + fe1_out_be0: endpoint@0 { + reg = <0>; + remote-endpoint = <&be0_in_fe1>; + }; + + fe1_out_be1: endpoint@1 { + reg = <1>; + remote-endpoint = <&be1_in_fe1>; + }; + }; + }; + }; + + be1: display-backend@01e40000 { + compatible = "allwinner,sun6i-a31-display-backend"; + reg = <0x01e40000 0x10000>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_AHB1_BE1>, <&ccu CLK_BE1>, + <&ccu CLK_DRAM_BE1>; + clock-names = "ahb", "mod", + "ram"; + resets = <&ccu RST_AHB1_BE1>; + + assigned-clocks = <&ccu CLK_BE1>; + assigned-clock-rates = <300000000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + be1_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + be1_in_fe0: endpoint@0 { + reg = <0>; + remote-endpoint = <&fe0_out_be1>; + }; + + be1_in_fe1: endpoint@1 { + reg = <1>; + remote-endpoint = <&fe1_out_be1>; + }; + }; + + be1_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + be1_out_drc1: endpoint@0 { + reg = <0>; + remote-endpoint = <&drc1_in_be1>; + }; + }; + }; + }; + + drc1: drc@01e50000 { + compatible = "allwinner,sun6i-a31-drc"; + reg = <0x01e50000 0x10000>; + interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_AHB1_DRC1>, <&ccu CLK_IEP_DRC1>, + <&ccu CLK_DRAM_DRC1>; + clock-names = "ahb", "mod", + "ram"; + resets = <&ccu RST_AHB1_DRC1>; + + assigned-clocks = <&ccu CLK_IEP_DRC1>; + assigned-clock-rates = <300000000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + drc1_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + drc1_in_be1: endpoint@0 { + reg = <0>; + remote-endpoint = <&be1_out_drc1>; + }; + }; + + drc1_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + drc1_out_tcon1: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon1_in_drc1>; + }; }; }; }; @@ -926,6 +1086,11 @@ reg = <0>; remote-endpoint = <&fe0_out_be0>; }; + + be0_in_fe1: endpoint@1 { + reg = <1>; + remote-endpoint = <&fe1_out_be0>; + }; }; be0_out: port@1 { diff --git a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts index bdfdce8ca6ba..51e6f1d21c32 100644 --- a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts +++ b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts @@ -138,7 +138,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&r_pio>; diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts index 08e776ae095a..eb55e74232c9 100644 --- a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts +++ b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts @@ -144,6 +144,10 @@ #include "axp209.dtsi" +&ac_power_supply { + status = "okay"; +}; + &ir0 { pinctrl-names = "default"; pinctrl-0 = <&ir0_rx_pins_a>; @@ -172,7 +176,7 @@ wakeup-source; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts index ed2f35adf542..88a1c2363c6c 100644 --- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts +++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts @@ -177,6 +177,57 @@ }; &pio { + gpio-line-names = + /* PA */ + "ERXD3", "ERXD2", "ERXD1", "ERXD0", "ETXD3", + "ETXD2", "ETXD1", "ETXD0", + "ERXCK", "ERXERR", "ERXDV", "EMDC", "EMDIO", + "ETXEN", "ETXCK", "ECRS", + "ECOL", "ETXERR", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PB */ + "PMU-SCK", "PMU-SDA", "", "", "", "", "", "", + "", "USB0-DRV", "", "", "", "", "", "", + "", "", "", "", "SCL", "SDA", "", "", + "", "", "", "", "", "", "", "", + /* PC */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PD */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PE */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PF */ + "SD0-D1", "SD0-D0", "SD0-CLK", "SD0-CMD", "SD0-D3", + "SD0-D2", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PG */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* PH */ + "TXD0", "RXD0", "IO-1", "PH3", "USB0-IDDET", "PH5", "", "", + "", "", "SD0-DET", "", "", "", "", "", + "", "", "", "", "IO-4", "IO-5", "", "EMAC-PWR-EN", + "LED1", "", "", "", "", "", "", "", + /* PI */ + "", "", "", "IO-GCLK", "", "", "", "", + "", "", "SPI-CE0", "SPI-CLK", "SPI-MOSI", + "SPI-MISO", "SPI-CE1", "", + "IO-6", "IO-3", "IO-2", "IO-0", "", "", "", "", + "", "", "", "", "", "", "", ""; + usb0_id_detect_pin: usb0_id_detect_pin@0 { pins = "PH4"; function = "gpio_in"; diff --git a/arch/arm/boot/dts/sun7i-a20-bananapro.dts b/arch/arm/boot/dts/sun7i-a20-bananapro.dts index 83516bc81225..e7af1b7c33d5 100644 --- a/arch/arm/boot/dts/sun7i-a20-bananapro.dts +++ b/arch/arm/boot/dts/sun7i-a20-bananapro.dts @@ -172,7 +172,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts index a2eab7aa80e0..2a50207618cb 100644 --- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts +++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts @@ -137,7 +137,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -174,13 +174,12 @@ status = "okay"; }; -&usb_otg { - dr_mode = "otg"; +#include "axp209.dtsi" + +&ac_power_supply { status = "okay"; }; -#include "axp209.dtsi" - ®_dcdc2 { regulator-always-on; regulator-min-microvolt = <1000000>; @@ -220,6 +219,11 @@ status = "okay"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>; diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts index 102903e83bd2..bb510187602c 100644 --- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts +++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts @@ -178,7 +178,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -195,7 +195,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; @@ -336,6 +336,7 @@ pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; usb0_id_det-gpios = <&pio 7 19 GPIO_ACTIVE_HIGH>; /* PH19 */ usb0_vbus_det-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */ + usb0_vbus_power-supply = <&usb_power_supply>; usb0_vbus-supply = <®_usb0_vbus>; usb1_vbus-supply = <®_usb1_vbus>; usb2_vbus-supply = <®_usb2_vbus>; diff --git a/arch/arm/boot/dts/sun7i-a20-hummingbird.dts b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts index 99c00b9a1546..6e6264cd69f8 100644 --- a/arch/arm/boot/dts/sun7i-a20-hummingbird.dts +++ b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts @@ -160,7 +160,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v0>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts b/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts index 4da49717da21..55809973a568 100644 --- a/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts +++ b/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts @@ -157,7 +157,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -173,7 +173,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; diff --git a/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts b/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts index 28d3abbdc2d4..794e7617f545 100644 --- a/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts +++ b/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts @@ -104,7 +104,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 8 5 GPIO_ACTIVE_HIGH>; /* PI5 */ diff --git a/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts b/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts index d52222c82cb8..8a8a6dbcd414 100644 --- a/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts +++ b/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts @@ -121,7 +121,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts b/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts index 96bb0bc198ba..004b6ddac813 100644 --- a/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts +++ b/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts @@ -85,10 +85,6 @@ }; }; -&ahci_pwr_pin_a { - pins = "PB3"; -}; - &ahci { target-supply = <®_ahci_5v>; status = "okay"; @@ -319,10 +315,6 @@ status = "okay"; }; -&usb2_vbus_pin_a { - pins = "PH12"; -}; - &usbphy { pinctrl-names = "default"; pinctrl-0 = <&usb0_id_detect_pin>; diff --git a/arch/arm/boot/dts/sun7i-a20-m3.dts b/arch/arm/boot/dts/sun7i-a20-m3.dts index 86f69813683e..43c94787ef07 100644 --- a/arch/arm/boot/dts/sun7i-a20-m3.dts +++ b/arch/arm/boot/dts/sun7i-a20-m3.dts @@ -117,7 +117,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-mk808c.dts b/arch/arm/boot/dts/sun7i-a20-mk808c.dts index c4ee30709f3a..f7413094183c 100644 --- a/arch/arm/boot/dts/sun7i-a20-mk808c.dts +++ b/arch/arm/boot/dts/sun7i-a20-mk808c.dts @@ -109,7 +109,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v0>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts index 1af5b46862cb..64c8ef9a2756 100644 --- a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts +++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts @@ -187,7 +187,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts index dcd0f7a0dffa..2ce1a9f13a17 100644 --- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts +++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts @@ -130,7 +130,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts index e7d45425758c..097bd755764c 100644 --- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts +++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts @@ -131,7 +131,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts index def0ad8395bb..0b7403e4d687 100644 --- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts +++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts @@ -198,7 +198,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts index f47a5c46bc20..39bc73db72e5 100644 --- a/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts +++ b/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts @@ -130,7 +130,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts index 7c96b53b76bf..777152a3df0f 100644 --- a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts +++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts @@ -106,10 +106,6 @@ status = "okay"; }; -&ahci_pwr_pin_a { - pins = "PH2"; -}; - &codec { status = "okay"; }; @@ -160,7 +156,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts b/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts index e19f17177755..f8d0aafb9f88 100644 --- a/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts +++ b/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts @@ -151,7 +151,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ diff --git a/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts b/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts index c3078d4f1093..7f8405a0dd0f 100644 --- a/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts +++ b/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts @@ -120,7 +120,7 @@ &mmc0 { pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + pinctrl-0 = <&mmc0_pins_a>; vmmc-supply = <®_vcc3v3>; bus-width = <4>; cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ @@ -137,7 +137,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 93aa55970bd7..c03b59aaec82 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -1190,12 +1190,6 @@ bias-pull-up; }; - mmc0_cd_pin_reference_design: mmc0_cd_pin@0 { - pins = "PH1"; - function = "gpio_in"; - bias-pull-up; - }; - mmc2_pins_a: mmc2@0 { pins = "PC6", "PC7", "PC8", "PC9", "PC10", "PC11"; diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts index 9b620cc1d5f1..433cf2a2a9a2 100644 --- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts +++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts @@ -88,13 +88,13 @@ }; &cpu0_opp_table { - opp@1104000000 { + opp-1104000000 { opp-hz = /bits/ 64 <1104000000>; opp-microvolt = <1320000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@1200000000 { + opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; opp-microvolt = <1320000>; clock-latency-ns = <244144>; /* 8 32k periods */ @@ -196,6 +196,10 @@ status = "okay"; }; +&battery_power_supply { + status = "okay"; +}; + ®_aldo1 { regulator-always-on; regulator-min-microvolt = <3000000>; diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi index 013978259372..22660919bd08 100644 --- a/arch/arm/boot/dts/sun8i-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a33.dtsi @@ -50,73 +50,73 @@ compatible = "operating-points-v2"; opp-shared; - opp@120000000 { + opp-120000000 { opp-hz = /bits/ 64 <120000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@240000000 { + opp-240000000 { opp-hz = /bits/ 64 <240000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@312000000 { + opp-312000000 { opp-hz = /bits/ 64 <312000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@408000000 { + opp-408000000 { opp-hz = /bits/ 64 <408000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@480000000 { + opp-480000000 { opp-hz = /bits/ 64 <480000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@504000000 { + opp-504000000 { opp-hz = /bits/ 64 <504000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@600000000 { + opp-600000000 { opp-hz = /bits/ 64 <600000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@648000000 { + opp-648000000 { opp-hz = /bits/ 64 <648000000>; opp-microvolt = <1040000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@720000000 { + opp-720000000 { opp-hz = /bits/ 64 <720000000>; opp-microvolt = <1100000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@816000000 { + opp-816000000 { opp-hz = /bits/ 64 <816000000>; opp-microvolt = <1100000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@912000000 { + opp-912000000 { opp-hz = /bits/ 64 <912000000>; opp-microvolt = <1200000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - opp@1008000000 { + opp-1008000000 { opp-hz = /bits/ 64 <1008000000>; opp-microvolt = <1200000>; clock-latency-ns = <244144>; /* 8 32k periods */ @@ -164,15 +164,15 @@ mali_opp_table: gpu-opp-table { compatible = "operating-points-v2"; - opp@144000000 { + opp-144000000 { opp-hz = /bits/ 64 <144000000>; }; - opp@240000000 { + opp-240000000 { opp-hz = /bits/ 64 <240000000>; }; - opp@384000000 { + opp-384000000 { opp-hz = /bits/ 64 <384000000>; }; }; diff --git a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts index 342e1d33fa1c..aecdeeb368ed 100644 --- a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts +++ b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts @@ -59,6 +59,6 @@ &uart0 { pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_b>; + pinctrl-0 = <&uart0_pb_pins>; status = "okay"; }; diff --git a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts index 88b1e0970b8d..cff33454fc24 100644 --- a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts +++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts @@ -45,6 +45,8 @@ /dts-v1/; #include "sun8i-a83t.dtsi" +#include <dt-bindings/gpio/gpio.h> + / { model = "Cubietech Cubietruck Plus"; compatible = "cubietech,cubietruck-plus", "allwinner,sun8i-a83t"; @@ -56,10 +58,56 @@ chosen { stdout-path = "serial0:115200n8"; }; + + leds { + compatible = "gpio-leds"; + + blue { + label = "cubietruck-plus:blue:usr"; + gpios = <&pio 3 25 GPIO_ACTIVE_HIGH>; /* PD25 */ + }; + + orange { + label = "cubietruck-plus:orange:usr"; + gpios = <&pio 3 26 GPIO_ACTIVE_HIGH>; /* PD26 */ + }; + + white { + label = "cubietruck-plus:white:usr"; + gpios = <&pio 3 27 GPIO_ACTIVE_HIGH>; /* PD27 */ + }; + + green { + label = "cubietruck-plus:green:usr"; + gpios = <&pio 4 4 GPIO_ACTIVE_HIGH>; /* PE4 */ + }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "On-board SPDIF"; + + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; + + simple-audio-card,codec { + sound-dai = <&spdif_out>; + }; + }; + + spdif_out: spdif-out { + #sound-dai-cells = <0>; + compatible = "linux,spdif-dit"; + }; +}; + +&spdif { + status = "okay"; }; &uart0 { pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_b>; + pinctrl-0 = <&uart0_pb_pins>; status = "okay"; }; diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index 0ec143773ee9..1dc4cfe81534 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -40,15 +40,20 @@ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "skeleton.dtsi" - #include <dt-bindings/interrupt-controller/arm-gic.h> / { interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + aliases { + }; + + chosen { + }; cpus { #address-cells = <1>; @@ -121,6 +126,7 @@ #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <24000000>; + clock-accuracy = <50000>; clock-output-names = "osc24M"; }; @@ -146,25 +152,49 @@ }; }; + memory { + reg = <0x40000000 0x80000000>; + device_type = "memory"; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; - pio: pinctrl@01c20800 { + dma: dma-controller@1c02000 { + compatible = "allwinner,sun8i-a83t-dma"; + reg = <0x01c02000 0x1000>; + interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu 21>; + resets = <&ccu 7>; + #dma-cells = <1>; + }; + + ccu: clock@1c20000 { + compatible = "allwinner,sun8i-a83t-ccu"; + reg = <0x01c20000 0x400>; + clocks = <&osc24M>, <&osc16Md512>; + clock-names = "hosc", "losc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pio: pinctrl@1c20800 { compatible = "allwinner,sun8i-a83t-pinctrl"; interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; reg = <0x01c20800 0x400>; - clocks = <&osc24M>; + clocks = <&ccu 45>, <&osc24M>, <&osc16Md512>; + clock-names = "apb", "hosc", "losc"; gpio-controller; interrupt-controller; #interrupt-cells = <3>; #gpio-cells = <3>; - mmc0_pins_a: mmc0@0 { + mmc0_pins: mmc0-pins { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; function = "mmc0"; @@ -172,18 +202,23 @@ bias-pull-up; }; - uart0_pins_a: uart0@0 { - pins = "PF2", "PF4"; - function = "uart0"; + spdif_tx_pin: spdif-tx-pin { + pins = "PE18"; + function = "spdif"; }; - uart0_pins_b: uart0@1 { + uart0_pb_pins: uart0-pb-pins { pins = "PB9", "PB10"; function = "uart0"; }; + + uart0_pf_pins: uart0-pf-pins { + pins = "PF2", "PF4"; + function = "uart0"; + }; }; - timer@01c20c00 { + timer@1c20c00 { compatible = "allwinner,sun4i-a10-timer"; reg = <0x01c20c00 0xa0>; interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>, @@ -191,24 +226,41 @@ clocks = <&osc24M>; }; - watchdog@01c20ca0 { + watchdog@1c20ca0 { compatible = "allwinner,sun6i-a31-wdt"; reg = <0x01c20ca0 0x20>; interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; clocks = <&osc24M>; }; + spdif: spdif@1c21000 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun8i-a83t-spdif", + "allwinner,sun8i-h3-spdif"; + reg = <0x01c21000 0x400>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu 44>, <&ccu 76>; + resets = <&ccu 32>; + clock-names = "apb", "spdif"; + dmas = <&dma 2>; + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx_pin>; + status = "disabled"; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <4>; - clocks = <&osc24M>; + clocks = <&ccu 53>; + resets = <&ccu 40>; status = "disabled"; }; - gic: interrupt-controller@01c81000 { + gic: interrupt-controller@1c81000 { compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; reg = <0x01c81000 0x1000>, <0x01c82000 0x2000>, diff --git a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts index 9e8b082c134f..0b8b969f7c64 100644 --- a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts +++ b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts @@ -143,6 +143,19 @@ status = "okay"; }; +&spi0 { + /* Disable SPI NOR by default: it optional on Orange Pi Zero boards */ + status = "disabled"; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mxicy,mx25l1606e", "winbond,w25q128"; + reg = <0>; + spi-max-frequency = <40000000>; + }; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; diff --git a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts index 52acbe111cad..883072b611fa 100644 --- a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts +++ b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts @@ -92,6 +92,10 @@ }; }; +&ehci0 { + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -126,7 +130,7 @@ non-removable; status = "okay"; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&pio>; @@ -145,6 +149,10 @@ status = "okay"; }; +&ohci0 { + status = "okay"; +}; + &ohci1 { status = "okay"; }; @@ -170,6 +178,11 @@ }; }; +®_usb0_vbus { + gpio = <&pio 3 11 GPIO_ACTIVE_HIGH>; /* PD11 */ + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; @@ -182,7 +195,14 @@ status = "okay"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { - /* USB VBUS is on as long as VCC-IO is on */ + usb0_id_det-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ + usb0_vbus-supply = <®_usb0_vbus>; + /* USB host VBUS is on as long as VCC-IO is on */ status = "okay"; }; diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts index 5b6d14555b7c..8ff71b1bb45b 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts @@ -104,6 +104,15 @@ }; }; +&codec { + allwinner,pa-gpios = <&pio 0 16 GPIO_ACTIVE_HIGH>; /* PA16 */ + allwinner,audio-routing = + "Speaker", "LINEOUT", + "MIC1", "Mic", + "Mic", "MBIAS"; + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -195,10 +204,6 @@ status = "disabled"; }; -&usb1_vbus_pin_a { - pins = "PG13"; -}; - &usbphy { usb1_vbus-supply = <®_usb1_vbus>; status = "okay"; diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts index f148111c326d..1a044b17d6c6 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts @@ -97,6 +97,10 @@ status = "okay"; }; +&ehci0 { + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -125,6 +129,10 @@ status = "okay"; }; +&ohci0 { + status = "okay"; +}; + &ohci1 { status = "okay"; }; @@ -156,6 +164,11 @@ }; }; +®_usb0_vbus { + gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */ + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; @@ -180,7 +193,14 @@ status = "disabled"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { - /* USB VBUS is always on */ + usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ + usb0_vbus-supply = <®_usb0_vbus>; + /* VBUS on USB host ports are always on */ status = "okay"; }; diff --git a/arch/arm/boot/dts/sun8i-v3s-licheepi-zero-dock.dts b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero-dock.dts new file mode 100644 index 000000000000..d1311098ea45 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero-dock.dts @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "sun8i-v3s-licheepi-zero.dts" + +#include <dt-bindings/input/input.h> + +/ { + model = "Lichee Pi Zero with Dock"; + compatible = "licheepi,licheepi-zero-dock", "licheepi,licheepi-zero", + "allwinner,sun8i-v3s"; + + leds { + /* The LEDs use PG0~2 pins, which conflict with MMC1 */ + status = "disbaled"; + }; +}; + +&mmc1 { + broken-cd; + bus-width = <4>; + vmmc-supply = <®_vcc3v3>; + status = "okay"; +}; + +&lradc { + vref-supply = <®_vcc3v0>; + status = "okay"; + + button@200 { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + channel = <0>; + voltage = <200000>; + }; + + button@400 { + label = "Volume Down"; + linux,code = <KEY_VOLUMEDOWN>; + channel = <0>; + voltage = <400000>; + }; + + button@600 { + label = "Select"; + linux,code = <KEY_SELECT>; + channel = <0>; + voltage = <600000>; + }; + + button@800 { + label = "Start"; + linux,code = <KEY_OK>; + channel = <0>; + voltage = <800000>; + }; +}; diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi index 71075969e5e6..a49ebef53c91 100644 --- a/arch/arm/boot/dts/sun8i-v3s.dtsi +++ b/arch/arm/boot/dts/sun8i-v3s.dtsi @@ -41,6 +41,8 @@ */ #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/sun8i-v3s-ccu.h> +#include <dt-bindings/reset/sun8i-v3s-ccu.h> / { #address-cells = <1>; @@ -55,7 +57,7 @@ compatible = "arm,cortex-a7"; device_type = "cpu"; reg = <0>; - clocks = <&ccu 14>; + clocks = <&ccu CLK_CPU>; }; }; @@ -96,15 +98,15 @@ mmc0: mmc@01c0f000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c0f000 0x1000>; - clocks = <&ccu 22>, - <&ccu 45>, - <&ccu 47>, - <&ccu 46>; + clocks = <&ccu CLK_BUS_MMC0>, + <&ccu CLK_MMC0>, + <&ccu CLK_MMC0_OUTPUT>, + <&ccu CLK_MMC0_SAMPLE>; clock-names = "ahb", "mmc", "output", "sample"; - resets = <&ccu 7>; + resets = <&ccu RST_BUS_MMC0>; reset-names = "ahb"; interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; @@ -115,17 +117,19 @@ mmc1: mmc@01c10000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c10000 0x1000>; - clocks = <&ccu 23>, - <&ccu 48>, - <&ccu 50>, - <&ccu 49>; + clocks = <&ccu CLK_BUS_MMC1>, + <&ccu CLK_MMC1>, + <&ccu CLK_MMC1_OUTPUT>, + <&ccu CLK_MMC1_SAMPLE>; clock-names = "ahb", "mmc", "output", "sample"; - resets = <&ccu 8>; + resets = <&ccu RST_BUS_MMC1>; reset-names = "ahb"; interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -134,15 +138,15 @@ mmc2: mmc@01c11000 { compatible = "allwinner,sun7i-a20-mmc"; reg = <0x01c11000 0x1000>; - clocks = <&ccu 24>, - <&ccu 51>, - <&ccu 53>, - <&ccu 52>; + clocks = <&ccu CLK_BUS_MMC2>, + <&ccu CLK_MMC2>, + <&ccu CLK_MMC2_OUTPUT>, + <&ccu CLK_MMC2_SAMPLE>; clock-names = "ahb", "mmc", "output", "sample"; - resets = <&ccu 9>; + resets = <&ccu RST_BUS_MMC2>; reset-names = "ahb"; interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; @@ -153,8 +157,8 @@ usb_otg: usb@01c19000 { compatible = "allwinner,sun8i-h3-musb"; reg = <0x01c19000 0x0400>; - clocks = <&ccu 29>; - resets = <&ccu 17>; + clocks = <&ccu CLK_BUS_OTG>; + resets = <&ccu RST_BUS_OTG>; interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "mc"; phys = <&usbphy 0>; @@ -169,9 +173,9 @@ <0x01c1a800 0x4>; reg-names = "phy_ctrl", "pmu0"; - clocks = <&ccu 56>; + clocks = <&ccu CLK_USB_PHY0>; clock-names = "usb0_phy"; - resets = <&ccu 0>; + resets = <&ccu RST_USB_PHY0>; reset-names = "usb0_reset"; status = "disabled"; #phy-cells = <1>; @@ -198,7 +202,7 @@ reg = <0x01c20800 0x400>; interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&ccu 37>, <&osc24M>, <&osc32k>; + clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>; clock-names = "apb", "hosc", "losc"; gpio-controller; #gpio-cells = <3>; @@ -222,6 +226,19 @@ drive-strength = <30>; bias-pull-up; }; + + mmc1_pins: mmc1 { + pins = "PG0", "PG1", "PG2", "PG3", + "PG4", "PG5"; + function = "mmc1"; + drive-strength = <30>; + bias-pull-up; + }; + + spi0_pins: spi0 { + pins = "PC0", "PC1", "PC2", "PC3"; + function = "spi0"; + }; }; timer@01c20c00 { @@ -238,14 +255,21 @@ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; }; + lradc: lradc@1c22800 { + compatible = "allwinner,sun4i-a10-lradc-keys"; + reg = <0x01c22800 0x400>; + interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <4>; - clocks = <&ccu 40>; - resets = <&ccu 49>; + clocks = <&ccu CLK_BUS_UART0>; + resets = <&ccu RST_BUS_UART0>; status = "disabled"; }; @@ -255,8 +279,8 @@ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <4>; - clocks = <&ccu 41>; - resets = <&ccu 50>; + clocks = <&ccu CLK_BUS_UART1>; + resets = <&ccu RST_BUS_UART1>; status = "disabled"; }; @@ -266,8 +290,8 @@ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <4>; - clocks = <&ccu 42>; - resets = <&ccu 51>; + clocks = <&ccu CLK_BUS_UART2>; + resets = <&ccu RST_BUS_UART2>; status = "disabled"; }; @@ -275,8 +299,8 @@ compatible = "allwinner,sun6i-a31-i2c"; reg = <0x01c2ac00 0x400>; interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&ccu 38>; - resets = <&ccu 46>; + clocks = <&ccu CLK_BUS_I2C0>; + resets = <&ccu RST_BUS_I2C0>; pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins>; status = "disabled"; @@ -288,8 +312,22 @@ compatible = "allwinner,sun6i-a31-i2c"; reg = <0x01c2b000 0x400>; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&ccu 39>; - resets = <&ccu 47>; + clocks = <&ccu CLK_BUS_I2C1>; + resets = <&ccu RST_BUS_I2C1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi0: spi@1c68000 { + compatible = "allwinner,sun8i-h3-spi"; + reg = <0x01c68000 0x1000>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; + clock-names = "ahb", "mod"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + resets = <&ccu RST_BUS_SPI0>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/sunxi-common-regulators.dtsi b/arch/arm/boot/dts/sunxi-common-regulators.dtsi index ce5c53e4452f..d8e5826fb3de 100644 --- a/arch/arm/boot/dts/sunxi-common-regulators.dtsi +++ b/arch/arm/boot/dts/sunxi-common-regulators.dtsi @@ -44,33 +44,9 @@ #include <dt-bindings/gpio/gpio.h> -&pio { - ahci_pwr_pin_a: ahci_pwr_pin@0 { - pins = "PB8"; - function = "gpio_out"; - }; - - usb0_vbus_pin_a: usb0_vbus_pin@0 { - pins = "PB9"; - function = "gpio_out"; - }; - - usb1_vbus_pin_a: usb1_vbus_pin@0 { - pins = "PH6"; - function = "gpio_out"; - }; - - usb2_vbus_pin_a: usb2_vbus_pin@0 { - pins = "PH3"; - function = "gpio_out"; - }; -}; - / { reg_ahci_5v: ahci-5v { compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&ahci_pwr_pin_a>; regulator-name = "ahci-5v"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; @@ -82,8 +58,6 @@ reg_usb0_vbus: usb0-vbus { compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&usb0_vbus_pin_a>; regulator-name = "usb0-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; @@ -94,8 +68,6 @@ reg_usb1_vbus: usb1-vbus { compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&usb1_vbus_pin_a>; regulator-name = "usb1-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; @@ -107,8 +79,6 @@ reg_usb2_vbus: usb2-vbus { compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&usb2_vbus_pin_a>; regulator-name = "usb2-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi index 1aeeacb3a884..d0067fec99de 100644 --- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi +++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi @@ -558,7 +558,7 @@ }; r_ccu: clock@1f01400 { - compatible = "allwinner,sun50i-a64-r-ccu"; + compatible = "allwinner,sun8i-h3-r-ccu"; reg = <0x01f01400 0x100>; clocks = <&osc24M>, <&osc32k>, <&iosc>; clock-names = "hosc", "losc", "iosc"; diff --git a/arch/arm/common/mcpm_entry.c b/arch/arm/common/mcpm_entry.c index cf062472e07b..2b913f17d50f 100644 --- a/arch/arm/common/mcpm_entry.c +++ b/arch/arm/common/mcpm_entry.c @@ -235,7 +235,7 @@ int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster) return ret; } -typedef void (*phys_reset_t)(unsigned long); +typedef typeof(cpu_reset) phys_reset_t; void mcpm_cpu_power_down(void) { @@ -300,7 +300,7 @@ void mcpm_cpu_power_down(void) * on the CPU. */ phys_reset = (phys_reset_t)(unsigned long)__pa_symbol(cpu_reset); - phys_reset(__pa_symbol(mcpm_entry_point)); + phys_reset(__pa_symbol(mcpm_entry_point), false); /* should never get here */ BUG(); @@ -389,7 +389,7 @@ static int __init nocache_trampoline(unsigned long _arg) __mcpm_cpu_down(cpu, cluster); phys_reset = (phys_reset_t)(unsigned long)__pa_symbol(cpu_reset); - phys_reset(__pa_symbol(mcpm_entry_point)); + phys_reset(__pa_symbol(mcpm_entry_point), false); BUG(); } diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 6dc661c4a2c1..960d55445e05 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -265,6 +265,12 @@ CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_USER=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_DEV_EXYNOS_RNG=y CONFIG_CRYPTO_DEV_S5P=y CONFIG_ARM_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM_NEON=m diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index bb6fa568b620..bf1e7e316918 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -55,6 +55,9 @@ CONFIG_CMDLINE="noinitrd console=ttymxc0,115200" CONFIG_KEXEC=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_ARM_IMX6Q_CPUFREQ=y CONFIG_CPU_IDLE=y CONFIG_VFP=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 2685e03600b1..705d908e004a 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -935,7 +935,13 @@ CONFIG_CPUFREQ_DT=y CONFIG_KEYSTONE_IRQ=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_ST=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_USER_API_AEAD=m CONFIG_CRYPTO_DEV_MARVELL_CESA=m +CONFIG_CRYPTO_DEV_EXYNOS_RNG=m CONFIG_CRYPTO_DEV_S5P=m CONFIG_CRYPTO_DEV_SUN4I_SS=m CONFIG_CRYPTO_DEV_ROCKCHIP=m diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig index f1a0e2503cbe..69553704f2dc 100644 --- a/arch/arm/configs/mvebu_v7_defconfig +++ b/arch/arm/configs/mvebu_v7_defconfig @@ -135,6 +135,8 @@ CONFIG_DMADEVICES=y CONFIG_MV_XOR=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_MEMORY=y +CONFIG_PWM=y +CONFIG_SENSORS_PWM_FAN=y CONFIG_EXT4_FS=y CONFIG_ISO9660_FS=y CONFIG_JOLIET=y diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 6e0f751be229..aef2b54a691c 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -8,6 +8,7 @@ CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y # CONFIG_UTS_NS is not set # CONFIG_IPC_NS is not set # CONFIG_PID_NS is not set @@ -75,6 +76,7 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_MXS_LRADC=y CONFIG_TOUCHSCREEN_TSC2007=m # CONFIG_SERIO is not set CONFIG_DEVPTS_MULTIPLE_INSTANCES=y @@ -95,6 +97,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_STMP3XXX_RTC_WATCHDOG=y +CONFIG_MFD_MXS_LRADC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_FB=y @@ -136,10 +139,9 @@ CONFIG_RTC_DRV_DS1307=m CONFIG_RTC_DRV_STMP=y CONFIG_DMADEVICES=y CONFIG_MXS_DMA=y -CONFIG_STAGING=y -CONFIG_MXS_LRADC=y CONFIG_IIO=y CONFIG_IIO_SYSFS_TRIGGER=y +CONFIG_MXS_LRADC_ADC=y CONFIG_PWM=y CONFIG_PWM_MXS=y CONFIG_NVMEM=y diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig index 777c9e986425..e04494b830ab 100644 --- a/arch/arm/configs/sama5_defconfig +++ b/arch/arm/configs/sama5_defconfig @@ -3,6 +3,8 @@ CONFIG_SYSVIPC=y CONFIG_FHANDLE=y CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y CONFIG_BLK_DEV_INITRD=y @@ -52,6 +54,7 @@ CONFIG_IP_PNP_RARP=y CONFIG_IPV6_SIT_6RD=y CONFIG_CAN=y CONFIG_CAN_AT91=y +CONFIG_CAN_M_CAN=y CONFIG_CFG80211=y CONFIG_MAC80211=y CONFIG_MAC80211_LEDS=y diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h index 302240c19a5a..a0d726a47c8a 100644 --- a/arch/arm/include/asm/pgtable-nommu.h +++ b/arch/arm/include/asm/pgtable-nommu.h @@ -66,6 +66,7 @@ typedef pte_t *pte_addr_t; #define pgprot_noncached(prot) (prot) #define pgprot_writecombine(prot) (prot) #define pgprot_dmacoherent(prot) (prot) +#define pgprot_device(prot) (prot) /* diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 939e8b58c59d..151cece4a293 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -123,10 +123,10 @@ void __show_regs(struct pt_regs *regs) print_symbol("PC is at %s\n", instruction_pointer(regs)); print_symbol("LR is at %s\n", regs->ARM_lr); - printk("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n" - "sp : %08lx ip : %08lx fp : %08lx\n", - regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr, - regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); + printk("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n", + regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr); + printk("sp : %08lx ip : %08lx fp : %08lx\n", + regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); printk("r10: %08lx r9 : %08lx r8 : %08lx\n", regs->ARM_r10, regs->ARM_r9, regs->ARM_r8); diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index f1ead0f13c19..e2bd17237964 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -15,10 +15,12 @@ extern void __init at91rm9200_pm_init(void); extern void __init at91sam9_pm_init(void); extern void __init sama5_pm_init(void); +extern void __init sama5d2_pm_init(void); #else static inline void __init at91rm9200_pm_init(void) { } static inline void __init at91sam9_pm_init(void) { } static inline void __init sama5_pm_init(void) { } +static inline void __init sama5d2_pm_init(void) { } #endif #endif /* _AT91_GENERIC_H */ diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 283e79ab587d..667fddac3856 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -15,6 +15,7 @@ #include <linux/of_address.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/parser.h> #include <linux/suspend.h> #include <linux/clk/at91_pmc.h> @@ -22,6 +23,7 @@ #include <asm/cacheflush.h> #include <asm/fncpy.h> #include <asm/system_misc.h> +#include <asm/suspend.h> #include "generic.h" #include "pm.h" @@ -37,7 +39,17 @@ extern void at91_pinctrl_gpio_suspend(void); extern void at91_pinctrl_gpio_resume(void); #endif -static struct at91_pm_data pm_data; +static const match_table_t pm_modes __initconst = { + { 0, "standby" }, + { AT91_PM_SLOW_CLOCK, "ulp0" }, + { AT91_PM_BACKUP, "backup" }, + { -1, NULL }, +}; + +static struct at91_pm_data pm_data = { + .standby_mode = 0, + .suspend_mode = AT91_PM_SLOW_CLOCK, +}; #define at91_ramc_read(id, field) \ __raw_readl(pm_data.ramc[id] + field) @@ -58,15 +70,33 @@ static int at91_pm_valid_state(suspend_state_t state) } } +static int canary = 0xA5A5A5A5; -static suspend_state_t target_state; +static struct at91_pm_bu { + int suspended; + unsigned long reserved; + phys_addr_t canary; + phys_addr_t resume; +} *pm_bu; /* * Called after processes are frozen, but before we shutdown devices. */ static int at91_pm_begin(suspend_state_t state) { - target_state = state; + switch (state) { + case PM_SUSPEND_MEM: + pm_data.mode = pm_data.suspend_mode; + break; + + case PM_SUSPEND_STANDBY: + pm_data.mode = pm_data.standby_mode; + break; + + default: + pm_data.mode = -1; + } + return 0; } @@ -115,7 +145,7 @@ static int at91_pm_verify_clocks(void) */ int at91_suspend_entering_slow_clock(void) { - return (target_state == PM_SUSPEND_MEM); + return (pm_data.mode >= AT91_PM_SLOW_CLOCK); } EXPORT_SYMBOL(at91_suspend_entering_slow_clock); @@ -123,50 +153,65 @@ static void (*at91_suspend_sram_fn)(struct at91_pm_data *); extern void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data); extern u32 at91_pm_suspend_in_sram_sz; -static void at91_pm_suspend(suspend_state_t state) +static int at91_suspend_finish(unsigned long val) { - pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0; - flush_cache_all(); outer_disable(); at91_suspend_sram_fn(&pm_data); + return 0; +} + +static void at91_pm_suspend(suspend_state_t state) +{ + if (pm_data.mode == AT91_PM_BACKUP) { + pm_bu->suspended = 1; + + cpu_suspend(0, at91_suspend_finish); + + /* The SRAM is lost between suspend cycles */ + at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn, + &at91_pm_suspend_in_sram, + at91_pm_suspend_in_sram_sz); + } else { + at91_suspend_finish(0); + } + outer_resume(); } +/* + * STANDBY mode has *all* drivers suspended; ignores irqs not marked as 'wakeup' + * event sources; and reduces DRAM power. But otherwise it's identical to + * PM_SUSPEND_ON: cpu idle, and nothing fancy done with main or cpu clocks. + * + * AT91_PM_SLOW_CLOCK is like STANDBY plus slow clock mode, so drivers must + * suspend more deeply, the master clock switches to the clk32k and turns off + * the main oscillator + * + * AT91_PM_BACKUP turns off the whole SoC after placing the DDR in self refresh + */ static int at91_pm_enter(suspend_state_t state) { #ifdef CONFIG_PINCTRL_AT91 at91_pinctrl_gpio_suspend(); #endif + switch (state) { - /* - * Suspend-to-RAM is like STANDBY plus slow clock mode, so - * drivers must suspend more deeply, the master clock switches - * to the clk32k and turns off the main oscillator - */ case PM_SUSPEND_MEM: + case PM_SUSPEND_STANDBY: /* * Ensure that clocks are in a valid state. */ - if (!at91_pm_verify_clocks()) + if ((pm_data.mode >= AT91_PM_SLOW_CLOCK) && + !at91_pm_verify_clocks()) goto error; at91_pm_suspend(state); break; - /* - * STANDBY mode has *all* drivers suspended; ignores irqs not - * marked as 'wakeup' event sources; and reduces DRAM power. - * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and - * nothing fancy done with main or cpu clocks. - */ - case PM_SUSPEND_STANDBY: - at91_pm_suspend(state); - break; - case PM_SUSPEND_ON: cpu_do_idle(); break; @@ -177,8 +222,6 @@ static int at91_pm_enter(suspend_state_t state) } error: - target_state = PM_SUSPEND_ON; - #ifdef CONFIG_PINCTRL_AT91 at91_pinctrl_gpio_resume(); #endif @@ -190,7 +233,6 @@ error: */ static void at91_pm_end(void) { - target_state = PM_SUSPEND_ON; } @@ -436,6 +478,79 @@ static void __init at91_pm_sram_init(void) &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); } +static void __init at91_pm_backup_init(void) +{ + struct gen_pool *sram_pool; + struct device_node *np; + struct platform_device *pdev = NULL; + + if ((pm_data.standby_mode != AT91_PM_BACKUP) && + (pm_data.suspend_mode != AT91_PM_BACKUP)) + return; + + pm_bu = NULL; + + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc"); + if (!np) { + pr_warn("%s: failed to find shdwc!\n", __func__); + return; + } + + pm_data.shdwc = of_iomap(np, 0); + of_node_put(np); + + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu"); + if (!np) { + pr_warn("%s: failed to find sfrbu!\n", __func__); + goto sfrbu_fail; + } + + pm_data.sfrbu = of_iomap(np, 0); + of_node_put(np); + pm_bu = NULL; + + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam"); + if (!np) + goto securam_fail; + + pdev = of_find_device_by_node(np); + of_node_put(np); + if (!pdev) { + pr_warn("%s: failed to find securam device!\n", __func__); + goto securam_fail; + } + + sram_pool = gen_pool_get(&pdev->dev, NULL); + if (!sram_pool) { + pr_warn("%s: securam pool unavailable!\n", __func__); + goto securam_fail; + } + + pm_bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu)); + if (!pm_bu) { + pr_warn("%s: unable to alloc securam!\n", __func__); + goto securam_fail; + } + + pm_bu->suspended = 0; + pm_bu->canary = virt_to_phys(&canary); + pm_bu->resume = virt_to_phys(cpu_resume); + + return; + +sfrbu_fail: + iounmap(pm_data.shdwc); + pm_data.shdwc = NULL; +securam_fail: + iounmap(pm_data.sfrbu); + pm_data.sfrbu = NULL; + + if (pm_data.standby_mode == AT91_PM_BACKUP) + pm_data.standby_mode = AT91_PM_SLOW_CLOCK; + if (pm_data.suspend_mode == AT91_PM_BACKUP) + pm_data.suspend_mode = AT91_PM_SLOW_CLOCK; +} + struct pmc_info { unsigned long uhp_udp_mask; }; @@ -481,10 +596,14 @@ static void __init at91_pm_init(void (*pm_idle)(void)) at91_pm_sram_init(); - if (at91_suspend_sram_fn) + if (at91_suspend_sram_fn) { suspend_set_ops(&at91_pm_ops); - else + pr_info("AT91: PM: standby: %s, suspend: %s\n", + pm_modes[pm_data.standby_mode].pattern, + pm_modes[pm_data.suspend_mode].pattern); + } else { pr_info("AT91: PM not supported, due to no SRAM allocated\n"); + } } void __init at91rm9200_pm_init(void) @@ -510,3 +629,34 @@ void __init sama5_pm_init(void) at91_dt_ramc(); at91_pm_init(NULL); } + +void __init sama5d2_pm_init(void) +{ + at91_pm_backup_init(); + sama5_pm_init(); +} + +static int __init at91_pm_modes_select(char *str) +{ + char *s; + substring_t args[MAX_OPT_ARGS]; + int standby, suspend; + + if (!str) + return 0; + + s = strsep(&str, ","); + standby = match_token(s, pm_modes, args); + if (standby < 0) + return 0; + + suspend = match_token(str, pm_modes, args); + if (suspend < 0) + return 0; + + pm_data.standby_mode = standby; + pm_data.suspend_mode = suspend; + + return 0; +} +early_param("atmel.pm_modes", at91_pm_modes_select); diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index fc0f7d048187..f95d31496f08 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -22,6 +22,7 @@ #define AT91_MEMCTRL_DDRSDR 2 #define AT91_PM_SLOW_CLOCK 0x01 +#define AT91_PM_BACKUP 0x02 #ifndef __ASSEMBLY__ struct at91_pm_data { @@ -30,6 +31,10 @@ struct at91_pm_data { unsigned long uhp_udp_mask; unsigned int memctrl; unsigned int mode; + void __iomem *shdwc; + void __iomem *sfrbu; + unsigned int standby_mode; + unsigned int suspend_mode; }; #endif diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c index 30302cb16df0..c0a73e62b725 100644 --- a/arch/arm/mach-at91/pm_data-offsets.c +++ b/arch/arm/mach-at91/pm_data-offsets.c @@ -9,5 +9,8 @@ int main(void) DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1])); DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl)); DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode)); + DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc)); + DEFINE(PM_DATA_SFRBU, offsetof(struct at91_pm_data, sfrbu)); + return 0; } diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S index 96781daa671a..daca91feea6a 100644 --- a/arch/arm/mach-at91/pm_suspend.S +++ b/arch/arm/mach-at91/pm_suspend.S @@ -97,15 +97,61 @@ ENTRY(at91_pm_suspend_in_sram) str tmp1, .memtype ldr tmp1, [r0, #PM_DATA_MODE] str tmp1, .pm_mode + /* Both ldrne below are here to preload their address in the TLB */ + ldr tmp1, [r0, #PM_DATA_SHDWC] + str tmp1, .shdwc + cmp tmp1, #0 + ldrne tmp2, [tmp1, #0] + ldr tmp1, [r0, #PM_DATA_SFRBU] + str tmp1, .sfr + cmp tmp1, #0 + ldrne tmp2, [tmp1, #0x10] /* Active the self-refresh mode */ mov r0, #SRAMC_SELF_FRESH_ACTIVE bl at91_sramc_self_refresh ldr r0, .pm_mode - tst r0, #AT91_PM_SLOW_CLOCK - beq skip_disable_main_clock + cmp r0, #AT91_PM_SLOW_CLOCK + beq slow_clock + cmp r0, #AT91_PM_BACKUP + beq backup_mode + /* Wait for interrupt */ + ldr pmc, .pmc_base + at91_cpu_idle + b exit_suspend + +slow_clock: + bl at91_slowck_mode + b exit_suspend +backup_mode: + bl at91_backup_mode + b exit_suspend + +exit_suspend: + /* Exit the self-refresh mode */ + mov r0, #SRAMC_SELF_FRESH_EXIT + bl at91_sramc_self_refresh + + /* Restore registers, and return */ + ldmfd sp!, {r4 - r12, pc} +ENDPROC(at91_pm_suspend_in_sram) + +ENTRY(at91_backup_mode) + /*BUMEN*/ + ldr r0, .sfr + mov tmp1, #0x1 + str tmp1, [r0, #0x10] + + /* Shutdown */ + ldr r0, .shdwc + mov tmp1, #0xA5000000 + add tmp1, tmp1, #0x1 + str tmp1, [r0, #0] +ENDPROC(at91_backup_mode) + +ENTRY(at91_slowck_mode) ldr pmc, .pmc_base /* Save Master clock setting */ @@ -134,18 +180,9 @@ ENTRY(at91_pm_suspend_in_sram) orr tmp1, tmp1, #AT91_PMC_KEY str tmp1, [pmc, #AT91_CKGR_MOR] -skip_disable_main_clock: - ldr pmc, .pmc_base - /* Wait for interrupt */ at91_cpu_idle - ldr r0, .pm_mode - tst r0, #AT91_PM_SLOW_CLOCK - beq skip_enable_main_clock - - ldr pmc, .pmc_base - /* Turn on the main oscillator */ ldr tmp1, [pmc, #AT91_CKGR_MOR] orr tmp1, tmp1, #AT91_PMC_MOSCEN @@ -174,14 +211,8 @@ skip_disable_main_clock: wait_mckrdy -skip_enable_main_clock: - /* Exit the self-refresh mode */ - mov r0, #SRAMC_SELF_FRESH_EXIT - bl at91_sramc_self_refresh - - /* Restore registers, and return */ - ldmfd sp!, {r4 - r12, pc} -ENDPROC(at91_pm_suspend_in_sram) + mov pc, lr +ENDPROC(at91_slowck_mode) /* * void at91_sramc_self_refresh(unsigned int is_active) @@ -314,6 +345,10 @@ ENDPROC(at91_sramc_self_refresh) .word 0 .sramc1_base: .word 0 +.shdwc: + .word 0 +.sfr: + .word 0 .memtype: .word 0 .pm_mode: diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c index 6d157d0ead8e..3d0bf95a56ae 100644 --- a/arch/arm/mach-at91/sama5.c +++ b/arch/arm/mach-at91/sama5.c @@ -34,7 +34,6 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5") MACHINE_END static const char *const sama5_alt_dt_board_compat[] __initconst = { - "atmel,sama5d2", "atmel,sama5d4", NULL }; @@ -45,3 +44,21 @@ DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5") .dt_compat = sama5_alt_dt_board_compat, .l2c_aux_mask = ~0UL, MACHINE_END + +static void __init sama5d2_init(void) +{ + of_platform_default_populate(NULL, NULL, NULL); + sama5d2_pm_init(); +} + +static const char *const sama5d2_compat[] __initconst = { + "atmel,sama5d2", + NULL +}; + +DT_MACHINE_START(sama5d2, "Atmel SAMA5") + /* Maintainer: Atmel */ + .init_machine = sama5d2_init, + .dt_compat = sama5d2_compat, + .l2c_aux_mask = ~0UL, +MACHINE_END diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index efb80354f303..b5cc05dc2cb2 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c @@ -153,7 +153,8 @@ int __init davinci_pm_init(void) davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL); if (!davinci_sram_suspend) { pr_err("PM: cannot allocate SRAM memory\n"); - return -ENOMEM; + ret = -ENOMEM; + goto no_sram_mem; } davinci_sram_push(davinci_sram_suspend, davinci_cpu_suspend, @@ -161,6 +162,10 @@ int __init davinci_pm_init(void) suspend_set_ops(&davinci_pm_ops); + return 0; + +no_sram_mem: + iounmap(pm_config.ddrpsc_reg_base); no_ddrpsc_mem: iounmap(pm_config.ddrpll_reg_base); no_ddrpll_mem: diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 936c59d0e18b..782699e67600 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -536,6 +536,7 @@ config SOC_IMX7D select HAVE_IMX_ANATOP select HAVE_IMX_MMDC select HAVE_IMX_SRC + select IMX_GPCV2 help This enables support for Freescale i.MX7 Dual processor. diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 369f95a703ac..33ed5d53fa45 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -58,6 +58,17 @@ static unsigned int irq_banks = DEFAULT_NR_REG_BANKS; static unsigned int max_irqs = DEFAULT_IRQS; static unsigned int omap_secure_apis; +#ifdef CONFIG_CPU_PM +static unsigned int wakeupgen_context[MAX_NR_REG_BANKS]; +#endif + +struct omap_wakeupgen_ops { + void (*save_context)(void); + void (*restore_context)(void); +}; + +static struct omap_wakeupgen_ops *wakeupgen_ops; + /* * Static helper functions. */ @@ -264,6 +275,16 @@ static inline void omap5_irq_save_context(void) } +static inline void am43xx_irq_save_context(void) +{ + u32 i; + + for (i = 0; i < irq_banks; i++) { + wakeupgen_context[i] = wakeupgen_readl(i, 0); + wakeupgen_writel(0, i, CPU0_ID); + } +} + /* * Save WakeupGen interrupt context in SAR BANK3. Restore is done by * ROM code. WakeupGen IP is integrated along with GIC to manage the @@ -280,11 +301,8 @@ static void irq_save_context(void) if (!sar_base) sar_base = omap4_get_sar_ram_base(); - - if (soc_is_omap54xx()) - omap5_irq_save_context(); - else - omap4_irq_save_context(); + if (wakeupgen_ops && wakeupgen_ops->save_context) + wakeupgen_ops->save_context(); } /* @@ -306,6 +324,20 @@ static void irq_sar_clear(void) writel_relaxed(val, sar_base + offset); } +static void am43xx_irq_restore_context(void) +{ + u32 i; + + for (i = 0; i < irq_banks; i++) + wakeupgen_writel(wakeupgen_context[i], i, CPU0_ID); +} + +static void irq_restore_context(void) +{ + if (wakeupgen_ops && wakeupgen_ops->restore_context) + wakeupgen_ops->restore_context(); +} + /* * Save GIC and Wakeupgen interrupt context using secure API * for HS/EMU devices. @@ -319,6 +351,26 @@ static void irq_save_secure_context(void) if (ret != API_HAL_RET_VALUE_OK) pr_err("GIC and Wakeupgen context save failed\n"); } + +/* Define ops for context save and restore for each SoC */ +static struct omap_wakeupgen_ops omap4_wakeupgen_ops = { + .save_context = omap4_irq_save_context, + .restore_context = irq_sar_clear, +}; + +static struct omap_wakeupgen_ops omap5_wakeupgen_ops = { + .save_context = omap5_irq_save_context, + .restore_context = irq_sar_clear, +}; + +static struct omap_wakeupgen_ops am43xx_wakeupgen_ops = { + .save_context = am43xx_irq_save_context, + .restore_context = am43xx_irq_restore_context, +}; +#else +static struct omap_wakeupgen_ops omap4_wakeupgen_ops = {}; +static struct omap_wakeupgen_ops omap5_wakeupgen_ops = {}; +static struct omap_wakeupgen_ops am43xx_wakeupgen_ops = {}; #endif #ifdef CONFIG_HOTPLUG_CPU @@ -359,7 +411,7 @@ static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v) break; case CPU_CLUSTER_PM_EXIT: if (omap_type() == OMAP2_DEVICE_TYPE_GP) - irq_sar_clear(); + irq_restore_context(); break; } return NOTIFY_OK; @@ -494,9 +546,13 @@ static int __init wakeupgen_init(struct device_node *node, irq_banks = OMAP4_NR_BANKS; max_irqs = OMAP4_NR_IRQS; omap_secure_apis = 1; + wakeupgen_ops = &omap4_wakeupgen_ops; + } else if (soc_is_omap54xx()) { + wakeupgen_ops = &omap5_wakeupgen_ops; } else if (soc_is_am43xx()) { irq_banks = AM43XX_NR_REG_BANKS; max_irqs = AM43XX_IRQS; + wakeupgen_ops = &am43xx_wakeupgen_ops; } domain = irq_domain_add_hierarchy(parent_domain, 0, max_irqs, diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 63027e60cc20..366158a54fcd 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -71,7 +71,7 @@ void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) } #endif -int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) +int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) { clkdm_allow_idle(clkdm); return 0; diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 07dd692c4737..70670dfd7135 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -68,6 +68,9 @@ static struct omap_dm_timer clkev; static struct clock_event_device clockevent_gpt; +/* Clockevent hwmod for am335x and am437x suspend */ +static struct omap_hwmod *clockevent_gpt_hwmod; + #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER static unsigned long arch_timer_freq; @@ -125,6 +128,23 @@ static int omap2_gp_timer_set_periodic(struct clock_event_device *evt) return 0; } +static void omap_clkevt_idle(struct clock_event_device *unused) +{ + if (!clockevent_gpt_hwmod) + return; + + omap_hwmod_idle(clockevent_gpt_hwmod); +} + +static void omap_clkevt_unidle(struct clock_event_device *unused) +{ + if (!clockevent_gpt_hwmod) + return; + + omap_hwmod_enable(clockevent_gpt_hwmod); + __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); +} + static struct clock_event_device clockevent_gpt = { .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, @@ -358,6 +378,14 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, 3, /* Timer internal resynch latency */ 0xffffffff); + if (soc_is_am33xx() || soc_is_am43xx()) { + clockevent_gpt.suspend = omap_clkevt_idle; + clockevent_gpt.resume = omap_clkevt_unidle; + + clockevent_gpt_hwmod = + omap_hwmod_lookup(clockevent_gpt.name); + } + pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, clkev.rate); } diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c index ef0500a4c8ad..927cf563ea47 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rockchip.c @@ -70,6 +70,7 @@ static const char * const rockchip_board_dt_compat[] = { "rockchip,rk3188", "rockchip,rk3228", "rockchip,rk3288", + "rockchip,rv1108", NULL, }; diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 459214fa20b4..5ee5ad74a3d6 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -40,7 +40,6 @@ config CPU_S3C6410 config S3C64XX_PL080 def_bool DMADEVICES - select ARM_AMBA select AMBA_PL08X config S3C64XX_SETUP_SDHCI diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c6c4c9c8824b..4f68659abe6c 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -679,7 +679,7 @@ config ARCH_DMA_ADDR_T_64BIT bool config ARM_THUMB - bool "Support Thumb user binaries" if !CPU_THUMBONLY + bool "Support Thumb user binaries" if !CPU_THUMBONLY && EXPERT depends on CPU_THUMB_CAPABLE default y help @@ -690,6 +690,10 @@ config ARM_THUMB instruction set resulting in smaller binaries at the expense of slightly less efficient code. + If this option is disabled, and you run userspace that switches to + Thumb mode, signal handling will not work correctly, resulting in + segmentation faults or illegal instruction aborts. + If you don't know what this all is, saying Y is a safe choice. config ARM_THUMBEE diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index c742dfd2967b..cb57f598589c 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -2381,6 +2381,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) __arm_iommu_detach_device(dev); arm_iommu_release_mapping(mapping); + set_dma_ops(dev, NULL); } #else diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 73272f43ca01..b4e919ac73f6 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -126,6 +126,12 @@ config ARCH_QCOM help This enables support for the ARMv8 based Qualcomm chipsets. +config ARCH_REALTEK + bool "Realtek Platforms" + help + This enables support for the ARMv8 based Realtek chipsets, + like the RTD1295. + config ARCH_ROCKCHIP bool "Rockchip Platforms" select ARCH_HAS_RESET_CONTROLLER diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index 080232b0270e..78f7991a5906 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -14,6 +14,7 @@ dts-dirs += marvell dts-dirs += mediatek dts-dirs += nvidia dts-dirs += qcom +dts-dirs += realtek dts-dirs += renesas dts-dirs += rockchip dts-dirs += socionext diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile index 244e8b7565f9..546720096aef 100644 --- a/arch/arm64/boot/dts/allwinner/Makefile +++ b/arch/arm64/boot/dts/allwinner/Makefile @@ -1,6 +1,8 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-pc2.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-prime.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo2.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts index c680ed385da3..7c533b6d4ba9 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts @@ -52,6 +52,10 @@ aliases { serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; }; chosen { @@ -66,6 +70,10 @@ }; }; +&ehci0 { + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -91,16 +99,49 @@ status = "okay"; }; +&ohci0 { + status = "okay"; +}; + &ohci1 { status = "okay"; }; +/* On Exp and Euler connectors */ &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; status = "okay"; }; +/* On Wifi/BT connector, with RTS/CTS */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; + status = "disabled"; +}; + +/* On Pi-2 connector */ +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "disabled"; +}; + +/* On Euler connector */ +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; + status = "disabled"; +}; + +/* On Euler connector, RTS/CTS optional */ +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins>; + status = "disabled"; +}; + &usb_otg { dr_mode = "host"; status = "okay"; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index c7f669f5884f..90dc4ec79485 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -204,6 +204,28 @@ #phy-cells = <1>; }; + ehci0: usb@01c1a000 { + compatible = "allwinner,sun50i-a64-ehci", "generic-ehci"; + reg = <0x01c1a000 0x100>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_OHCI0>, + <&ccu CLK_BUS_EHCI0>, + <&ccu CLK_USB_OHCI0>; + resets = <&ccu RST_BUS_OHCI0>, + <&ccu RST_BUS_EHCI0>; + status = "disabled"; + }; + + ohci0: usb@01c1a400 { + compatible = "allwinner,sun50i-a64-ohci", "generic-ohci"; + reg = <0x01c1a400 0x100>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_OHCI0>, + <&ccu CLK_USB_OHCI0>; + resets = <&ccu RST_BUS_OHCI0>; + status = "disabled"; + }; + ehci1: usb@01c1b000 { compatible = "allwinner,sun50i-a64-ehci", "generic-ehci"; reg = <0x01c1b000 0x100>; @@ -295,6 +317,26 @@ pins = "PG8", "PG9"; function = "uart1"; }; + + uart2_pins: uart2-pins { + pins = "PB0", "PB1"; + function = "uart2"; + }; + + uart3_pins: uart3-pins { + pins = "PD0", "PD1"; + function = "uart3"; + }; + + uart4_pins: uart4-pins { + pins = "PD2", "PD3"; + function = "uart4"; + }; + + uart4_rts_cts_pins: uart4-rts-cts-pins { + pins = "PD4", "PD5"; + function = "uart4"; + }; }; uart0: serial@1c28000 { @@ -422,6 +464,25 @@ #gpio-cells = <3>; interrupt-controller; #interrupt-cells = <3>; + + r_rsb_pins: rsb@0 { + pins = "PL0", "PL1"; + function = "s_rsb"; + }; + }; + + r_rsb: rsb@1f03400 { + compatible = "allwinner,sun8i-a23-rsb"; + reg = <0x01f03400 0x400>; + interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&r_ccu 6>; + clock-frequency = <3000000>; + resets = <&r_ccu 2>; + pinctrl-names = "default"; + pinctrl-0 = <&r_rsb_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; }; }; }; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts new file mode 100644 index 000000000000..f6d71b0d482a --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun50i-h5.dtsi" + +#include <dt-bindings/gpio/gpio.h> + +/ { + model = "FriendlyARM NanoPi NEO 2"; + compatible = "friendlyarm,nanopi-neo2", "allwinner,sun50i-h5"; + + reg_vcc3v3: vcc3v3 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + pwr { + label = "nanopi:green:pwr"; + gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + status { + label = "nanopi:blue:status"; + gpios = <&pio 0 10 GPIO_ACTIVE_HIGH>; + }; + }; + + reg_usb0_vbus: usb0-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */ + status = "okay"; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci3 { + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci3 { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usbphy { + /* USB Type-A port's VBUS is always on */ + usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ + usb0_vbus-supply = <®_usb0_vbus>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts new file mode 100644 index 000000000000..28d92a612329 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz> + * + * Based on sun50i-h5-orangepi-pc2.dts, which is: + * Copyright (C) 2016 ARM Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun50i-h5.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> + +/ { + model = "Xunlong Orange Pi Prime"; + compatible = "xunlong,orangepi-prime", "allwinner,sun50i-h5"; + + reg_vcc3v3: vcc3v3 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + pwr { + label = "orangepi:green:pwr"; + gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + status { + label = "orangepi:red:status"; + gpios = <&pio 0 20 GPIO_ACTIVE_HIGH>; + }; + }; + + r-gpio-keys { + compatible = "gpio-keys"; + + sw4 { + label = "sw4"; + linux,code = <BTN_0>; + gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; + }; + }; + + reg_usb0_vbus: usb0-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */ + status = "okay"; + }; + + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&pio 2 14 GPIO_ACTIVE_LOW>; /* PC14 */ + }; +}; + +&codec { + allwinner,audio-routing = + "Line Out", "LINEOUT", + "MIC1", "Mic", + "Mic", "MBIAS"; + status = "okay"; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&ehci2 { + status = "okay"; +}; + +&ehci3 { + status = "okay"; +}; + +&ir { + pinctrl-names = "default"; + pinctrl-0 = <&ir_pins_a>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + status = "okay"; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins_a>; + vmmc-supply = <®_vcc3v3>; + mmc-pwrseq = <&wifi_pwrseq>; + bus-width = <4>; + non-removable; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ohci2 { + status = "okay"; +}; + +&ohci3 { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "disabled"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usbphy { + /* USB Type-A ports' VBUS is always on */ + usb0_id_det-gpios = <&pio 0 21 GPIO_ACTIVE_HIGH>; /* PA21 */ + usb0_vbus-supply = <®_usb0_vbus>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi index 4d314a253fd9..732e2e06f503 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi @@ -40,7 +40,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "sunxi-h3-h5.dtsi" +#include <arm/sunxi-h3-h5.dtsi> / { cpus { diff --git a/arch/arm64/boot/dts/allwinner/sunxi-h3-h5.dtsi b/arch/arm64/boot/dts/allwinner/sunxi-h3-h5.dtsi deleted file mode 120000 index 036f01dc2b9b..000000000000 --- a/arch/arm64/boot/dts/allwinner/sunxi-h3-h5.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/sunxi-h3-h5.dtsi
\ No newline at end of file diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile index b9ad2db7398b..8a0e09250978 100644 --- a/arch/arm64/boot/dts/amlogic/Makefile +++ b/arch/arm64/boot/dts/amlogic/Makefile @@ -1,3 +1,4 @@ +dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-odroidc2.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-p200.dtb @@ -7,15 +8,16 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-meta.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-telos.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-wetek-hub.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-wetek-play2.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-hwacom-amazetv.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-khadas-vim.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p230.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p231.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-hwacom-amazetv.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-gxm-nexbox-a1.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q200.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q201.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-gxm-nexbox-a1.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi index a84e27622639..dc478d094c11 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi @@ -121,19 +121,42 @@ }; }; -/* This UART is brought out to the DB9 connector */ -&uart_AO { +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; +}; + +ðmac { status = "okay"; - pinctrl-0 = <&uart_ao_a_pins>; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; pinctrl-names = "default"; }; +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + &ir { status = "okay"; pinctrl-0 = <&remote_input_ao_pins>; pinctrl-names = "default"; }; +&pwm_ef { + status = "okay"; + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; + clocks = <&clkc CLKID_FCLK_DIV4>; + clock-names = "clkin0"; +}; + /* Wireless SDIO Module */ &sd_emmc_a { status = "okay"; @@ -154,7 +177,7 @@ vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_boot>; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; }; @@ -198,32 +221,9 @@ vqmmc-supply = <&vddio_boot>; }; -&pwm_ef { - status = "okay"; - pinctrl-0 = <&pwm_e_pins>; - pinctrl-names = "default"; - clocks = <&clkc CLKID_FCLK_DIV4>; - clock-names = "clkin0"; -}; - -ðmac { - status = "okay"; -}; - -&cvbs_vdac_port { - cvbs_vdac_out: endpoint { - remote-endpoint = <&cvbs_connector_in>; - }; -}; - -&hdmi_tx { +/* This UART is brought out to the DB9 connector */ +&uart_AO { status = "okay"; - pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + pinctrl-0 = <&uart_ao_a_pins>; pinctrl-names = "default"; }; - -&hdmi_tx_tmds_port { - hdmi_tx_tmds_out: endpoint { - remote-endpoint = <&hdmi_connector_in>; - }; -}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts new file mode 100644 index 000000000000..fa462831ccaf --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2017 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/dts-v1/; + +#include "meson-gxbb.dtsi" +#include <dt-bindings/gpio/gpio.h> + +/ { + compatible = "friendlyarm,nanopi-k2", "amlogic,meson-gxbb"; + + aliases { + serial0 = &uart_AO; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + leds { + compatible = "gpio-leds"; + + stat { + label = "nanopi-k2:blue:stat"; + gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>; + default-state = "on"; + panic-indicator; + }; + }; + + vdd_5v: regulator-vdd-5v { + compatible = "regulator-fixed"; + regulator-name = "VDD_5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vddio_ao18: regulator-vddio-ao18 { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_AO18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + vddio_ao3v3: regulator-vddio-ao3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_AO3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + vddio_tf: regulator-vddio-tf { + compatible = "regulator-gpio"; + + regulator-name = "VDDIO_TF"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + + states = <3300000 0>, + <1800000 1>; + }; + + wifi_32k: wifi-32k { + compatible = "pwm-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */ + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; + clocks = <&wifi_32k>; + clock-names = "ext_clock"; + }; + + vcc1v8: regulator-vcc1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + vcc3v3: regulator-vcc3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; + }; +}; + +ðmac { + status = "okay"; + pinctrl-0 = <ð_rgmii_pins>; + pinctrl-names = "default"; + + phy-handle = <ð_phy0>; + phy-mode = "rgmii"; + + amlogic,tx-delay-ns = <2>; + + snps,reset-gpio = <&gpio GPIOZ_14 0>; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-active-low; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + eth_phy0: ethernet-phy@0 { + /* Realtek RTL8211F (0x001cc916) */ + reg = <0>; + }; + }; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; +}; + +&pwm_ef { + status = "okay"; + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; + clocks = <&clkc CLKID_FCLK_DIV4>; + clock-names = "clkin0"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vddio_ao18>; +}; + +/* SDIO */ +&sd_emmc_a { + status = "okay"; + pinctrl-0 = <&sdio_pins>, <&sdio_irq_pins>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <200000000>; + + non-removable; + disable-wp; + + mmc-pwrseq = <&sdio_pwrseq>; + + vmmc-supply = <&vddio_ao3v3>; + vqmmc-supply = <&vddio_ao18>; + + brcmf: wifi@1 { + compatible = "brcm,bcm4329-fmac"; + reg = <1>; + }; +}; + +/* SD */ +&sd_emmc_b { + status = "okay"; + pinctrl-0 = <&sdcard_pins>; + pinctrl-names = "default"; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <100000000>; + disable-wp; + + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; + cd-inverted; + + vmmc-supply = <&vddio_ao3v3>; + vqmmc-supply = <&vddio_tf>; +}; + +/* eMMC */ +&sd_emmc_c { + status = "disabled"; + pinctrl-0 = <&emmc_pins>; + pinctrl-names = "default"; + + bus-width = <8>; + cap-sd-highspeed; + max-frequency = <200000000>; + non-removable; + disable-wp; + cap-mmc-highspeed; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vcc3v3>; + vqmmc-supply = <&vcc1v8>; +}; + +/* DBG_UART */ +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; + +/* Bluetooth on AP6212 */ +&uart_A { + status = "disabled"; + pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>; + pinctrl-names = "default"; +}; + +/* 40-pin CON1 */ +&uart_C { + status = "disabled"; + pinctrl-0 = <&uart_c_pins>; + pinctrl-names = "default"; +}; + +&usb0_phy { + status = "okay"; + phy-supply = <&vdd_5v>; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts index 87198eafb04b..a1078b3e1c76 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts @@ -165,10 +165,10 @@ }; }; -&uart_AO { - status = "okay"; - pinctrl-0 = <&uart_ao_a_pins>; - pinctrl-names = "default"; +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; }; ðmac { @@ -195,12 +195,32 @@ }; }; +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + pinctrl-names = "default"; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + &ir { status = "okay"; pinctrl-0 = <&remote_input_ao_pins>; pinctrl-names = "default"; }; +&pwm_ef { + status = "okay"; + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; + clocks = <&clkc CLKID_FCLK_DIV4>; + clock-names = "clkin0"; +}; + /* Wireless SDIO Module */ &sd_emmc_a { status = "okay"; @@ -260,28 +280,8 @@ vqmmc-supply = <&vddio_boot>; }; -&pwm_ef { - status = "okay"; - pinctrl-0 = <&pwm_e_pins>; - pinctrl-names = "default"; - clocks = <&clkc CLKID_FCLK_DIV4>; - clock-names = "clkin0"; -}; - -&cvbs_vdac_port { - cvbs_vdac_out: endpoint { - remote-endpoint = <&cvbs_connector_in>; - }; -}; - -&hdmi_tx { +&uart_AO { status = "okay"; - pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + pinctrl-0 = <&uart_ao_a_pins>; pinctrl-names = "default"; }; - -&hdmi_tx_tmds_port { - hdmi_tx_tmds_out: endpoint { - remote-endpoint = <&hdmi_connector_in>; - }; -}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts index 54a9c6a6b392..d147c853ab05 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -137,16 +137,6 @@ }; }; -&scpi_clocks { - status = "disabled"; -}; - -&uart_AO { - status = "okay"; - pinctrl-0 = <&uart_ao_a_pins>; - pinctrl-names = "default"; -}; - ðmac { status = "okay"; pinctrl-0 = <ð_rgmii_pins>; @@ -172,6 +162,33 @@ }; }; +&gpio_ao { + /* + * WARNING: The USB Hub on the Odroid-C2 needs a reset signal + * to be turned high in order to be detected by the USB Controller + * This signal should be handled by a USB specific power sequence + * in order to reset the Hub when USB bus is powered down. + */ + usb-hub { + gpio-hog; + gpios = <GPIOAO_4 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb-hub-reset"; + }; +}; + +&i2c_A { + status = "okay"; + pinctrl-0 = <&i2c_a_pins>; + pinctrl-names = "default"; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; +}; + &pinctrl_aobus { gpio-line-names = "UART TX", "UART RX", "VCCK En", "TF 3V3/1V8 En", "USB HUB nRESET", "USB OTG Power En", @@ -223,55 +240,15 @@ ""; }; -&ir { - status = "okay"; - pinctrl-0 = <&remote_input_ao_pins>; - pinctrl-names = "default"; -}; - -&i2c_A { - status = "okay"; - pinctrl-0 = <&i2c_a_pins>; - pinctrl-names = "default"; -}; - -&gpio_ao { - /* - * WARNING: The USB Hub on the Odroid-C2 needs a reset signal - * to be turned high in order to be detected by the USB Controller - * This signal should be handled by a USB specific power sequence - * in order to reset the Hub when USB bus is powered down. - */ - usb-hub { - gpio-hog; - gpios = <GPIOAO_4 GPIO_ACTIVE_HIGH>; - output-high; - line-name = "usb-hub-reset"; - }; -}; - -&usb0_phy { - status = "okay"; - phy-supply = <&usb_otg_pwr>; -}; - -&usb1_phy { - status = "okay"; -}; - -&usb0 { - status = "okay"; -}; - -&usb1 { - status = "okay"; -}; - &saradc { status = "okay"; vref-supply = <&vcc1v8>; }; +&scpi_clocks { + status = "disabled"; +}; + /* SD */ &sd_emmc_b { status = "okay"; @@ -309,3 +286,26 @@ vmmc-supply = <&vcc3v3>; vqmmc-supply = <&vcc1v8>; }; + +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; + +&usb0_phy { + status = "okay"; + phy-supply = <&usb_otg_pwr>; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi index 3c6c0b7f4187..d904deb1018c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi @@ -126,7 +126,7 @@ clock-names = "ext_clock"; }; - cvbs-connector { + cvbs_connector: cvbs-connector { compatible = "composite-video-connector"; port { @@ -148,34 +148,36 @@ }; }; -/* This UART is brought out to the DB9 connector */ -&uart_AO { - status = "okay"; - pinctrl-0 = <&uart_ao_a_pins>; - pinctrl-names = "default"; +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; }; -&ir { +&hdmi_tx { status = "okay"; - pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; pinctrl-names = "default"; }; -&usb0_phy { - status = "okay"; - phy-supply = <&usb_pwr>; -}; - -&usb1_phy { - status = "okay"; +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; }; -&usb0 { +&ir { status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; }; -&usb1 { +&pwm_ef { status = "okay"; + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; + clocks = <&clkc CLKID_FCLK_DIV4>; + clock-names = "clkin0"; }; /* Wireless SDIO Module */ @@ -198,7 +200,7 @@ vmmc-supply = <&vddao_3v3>; vqmmc-supply = <&vddio_boot>; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; }; @@ -242,28 +244,26 @@ vqmmc-supply = <&vddio_boot>; }; -&pwm_ef { +/* This UART is brought out to the DB9 connector */ +&uart_AO { status = "okay"; - pinctrl-0 = <&pwm_e_pins>; + pinctrl-0 = <&uart_ao_a_pins>; pinctrl-names = "default"; - clocks = <&clkc CLKID_FCLK_DIV4>; - clock-names = "clkin0"; }; -&cvbs_vdac_port { - cvbs_vdac_out: endpoint { - remote-endpoint = <&cvbs_connector_in>; - }; +&usb0_phy { + status = "okay"; + phy-supply = <&usb_pwr>; }; -&hdmi_tx { +&usb1_phy { status = "okay"; - pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; - pinctrl-names = "default"; }; -&hdmi_tx_tmds_port { - hdmi_tx_tmds_out: endpoint { - remote-endpoint = <&hdmi_connector_in>; - }; +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi index aefa66dff72d..346753fb6324 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi @@ -111,18 +111,6 @@ }; }; -&uart_AO { - status = "okay"; - pinctrl-0 = <&uart_ao_a_pins>; - pinctrl-names = "default"; -}; - -&ir { - status = "okay"; - pinctrl-0 = <&remote_input_ao_pins>; - pinctrl-names = "default"; -}; - ðmac { status = "okay"; pinctrl-0 = <ð_rgmii_pins>; @@ -149,21 +137,18 @@ }; }; -&usb0_phy { - status = "okay"; - phy-supply = <&usb_vbus>; -}; - -&usb1_phy { - status = "okay"; -}; - -&usb0 { +&ir { status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; }; -&usb1 { +&pwm_ef { status = "okay"; + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; + clocks = <&clkc CLKID_FCLK_DIV4>; + clock-names = "clkin0"; }; /* Wireless SDIO Module */ @@ -186,7 +171,7 @@ vmmc-supply = <&vcc_3v3>; vqmmc-supply = <&vcc_1v8>; - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; }; @@ -229,10 +214,25 @@ vmmcq-sumpply = <&vcc_1v8>; }; -&pwm_ef { +&uart_AO { status = "okay"; - pinctrl-0 = <&pwm_e_pins>; + pinctrl-0 = <&uart_ao_a_pins>; pinctrl-names = "default"; - clocks = <&clkc CLKID_FCLK_DIV4>; - clock-names = "clkin0"; +}; + +&usb0_phy { + status = "okay"; + phy-supply = <&usb_vbus>; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts index f057fb48fee5..1878ac2b2b83 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts @@ -59,10 +59,10 @@ panic-indicator; }; }; +}; - cvbs-connector { - status = "disabled"; - }; +&cvbs_connector { + status = "disabled"; }; ðmac { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index 86105a69690a..dbd300fffa8a 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -97,13 +97,6 @@ }; }; -ðmac { - clocks = <&clkc CLKID_ETH>, - <&clkc CLKID_FCLK_DIV2>, - <&clkc CLKID_MPLL2>; - clock-names = "stmmaceth", "clkin0", "clkin1"; -}; - &aobus { pinctrl_aobus: pinctrl@14 { compatible = "amlogic,meson-gxbb-aobus-pinctrl"; @@ -249,9 +242,119 @@ function = "spdif_out_ao"; }; }; + + ao_cec_pins: ao_cec { + mux { + groups = "ao_cec"; + function = "cec_ao"; + }; + }; + + ee_cec_pins: ee_cec { + mux { + groups = "ee_cec"; + function = "cec_ao"; + }; + }; }; }; +&apb { + mali: gpu@c0000 { + compatible = "amlogic,meson-gxbb-mali", "arm,mali-450"; + reg = <0x0 0xc0000 0x0 0x40000>; + interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "gp", "gpmmu", "pp", "pmu", + "pp0", "ppmmu0", "pp1", "ppmmu1", + "pp2", "ppmmu2"; + clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; + clock-names = "bus", "core"; + + /* + * Mali clocking is provided by two identical clock paths + * MALI_0 and MALI_1 muxed to a single clock by a glitch + * free mux to safely change frequency while running. + */ + assigned-clocks = <&clkc CLKID_MALI_0_SEL>, + <&clkc CLKID_MALI_0>, + <&clkc CLKID_MALI>; /* Glitch free mux */ + assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>, + <0>, /* Do Nothing */ + <&clkc CLKID_MALI_0>; + assigned-clock-rates = <0>, /* Do Nothing */ + <666666666>, + <0>; /* Do Nothing */ + }; +}; + +&cbus { + spifc: spi@8c80 { + compatible = "amlogic,meson-gxbb-spifc"; + reg = <0x0 0x08c80 0x0 0x80>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc CLKID_SPI>; + status = "disabled"; + }; +}; + +ðmac { + clocks = <&clkc CLKID_ETH>, + <&clkc CLKID_FCLK_DIV2>, + <&clkc CLKID_MPLL2>; + clock-names = "stmmaceth", "clkin0", "clkin1"; +}; + +&hdmi_tx { + compatible = "amlogic,meson-gxbb-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; + resets = <&reset RESET_HDMITX_CAPB3>, + <&reset RESET_HDMI_SYSTEM_RESET>, + <&reset RESET_HDMI_TX>; + reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; + clocks = <&clkc CLKID_HDMI_PCLK>, + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; +}; + +&hiubus { + clkc: clock-controller@0 { + compatible = "amlogic,gxbb-clkc"; + #clock-cells = <1>; + reg = <0x0 0x0 0x0 0x3db>; + }; +}; + +&hwrng { + clocks = <&clkc CLKID_RNG0>; + clock-names = "core"; +}; + +&i2c_A { + clocks = <&clkc CLKID_I2C>; +}; + +&i2c_AO { + clocks = <&clkc CLKID_AO_I2C>; +}; + +&i2c_B { + clocks = <&clkc CLKID_I2C>; +}; + +&i2c_C { + clocks = <&clkc CLKID_I2C>; +}; + &periphs { pinctrl_periphs: pinctrl@4b0 { compatible = "amlogic,meson-gxbb-periphs-pinctrl"; @@ -262,7 +365,7 @@ gpio: bank@4b0 { reg = <0x0 0x004b0 0x0 0x28>, <0x0 0x004e8 0x0 0x14>, - <0x0 0x00120 0x0 0x14>, + <0x0 0x00520 0x0 0x14>, <0x0 0x00430 0x0 0x40>; reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; @@ -290,6 +393,22 @@ }; }; + spi_pins: spi { + mux { + groups = "spi_miso", + "spi_mosi", + "spi_sclk"; + function = "spi"; + }; + }; + + spi_ss0_pins: spi-ss0 { + mux { + groups = "spi_ss0"; + function = "spi"; + }; + }; + sdcard_pins: sdcard { mux { groups = "sdcard_d0", @@ -521,67 +640,6 @@ }; }; -&hiubus { - clkc: clock-controller@0 { - compatible = "amlogic,gxbb-clkc"; - #clock-cells = <1>; - reg = <0x0 0x0 0x0 0x3db>; - }; -}; - -&apb { - mali: gpu@c0000 { - compatible = "amlogic,meson-gxbb-mali", "arm,mali-450"; - reg = <0x0 0xc0000 0x0 0x40000>; - interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "gp", "gpmmu", "pp", "pmu", - "pp0", "ppmmu0", "pp1", "ppmmu1", - "pp2", "ppmmu2"; - clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; - clock-names = "bus", "core"; - - /* - * Mali clocking is provided by two identical clock paths - * MALI_0 and MALI_1 muxed to a single clock by a glitch - * free mux to safely change frequency while running. - */ - assigned-clocks = <&clkc CLKID_MALI_0_SEL>, - <&clkc CLKID_MALI_0>, - <&clkc CLKID_MALI>; /* Glitch free mux */ - assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>, - <0>, /* Do Nothing */ - <&clkc CLKID_MALI_0>; - assigned-clock-rates = <0>, /* Do Nothing */ - <666666666>, - <0>; /* Do Nothing */ - }; -}; - -&i2c_A { - clocks = <&clkc CLKID_I2C>; -}; - -&i2c_AO { - clocks = <&clkc CLKID_AO_I2C>; -}; - -&i2c_B { - clocks = <&clkc CLKID_I2C>; -}; - -&i2c_C { - clocks = <&clkc CLKID_I2C>; -}; - &saradc { compatible = "amlogic,meson-gxbb-saradc", "amlogic,meson-saradc"; clocks = <&xtal>, @@ -620,20 +678,3 @@ &vpu { compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; }; - -&hwrng { - clocks = <&clkc CLKID_RNG0>; - clock-names = "core"; -}; - -&hdmi_tx { - compatible = "amlogic,meson-gxbb-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; - resets = <&reset RESET_HDMITX_CAPB3>, - <&reset RESET_HDMI_SYSTEM_RESET>, - <&reset RESET_HDMI_TX>; - reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; - clocks = <&clkc CLKID_HDMI_PCLK>, - <&clkc CLKID_CLK81>, - <&clkc CLKID_GCLK_VENCI_INT0>; - clock-names = "isfr", "iahb", "venci"; -}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts index 3c8b0b51ef27..6a81f0168da5 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts @@ -95,7 +95,7 @@ }; &sd_emmc_a { - brcmf: bcrmf@1 { + brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts index 8873c058fad2..6633a5d8fdd3 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts @@ -140,10 +140,10 @@ }; }; -&uart_AO { - status = "okay"; - pinctrl-0 = <&uart_ao_a_pins>; - pinctrl-names = "default"; +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; }; ðmac { @@ -152,12 +152,32 @@ phy-handle = <&internal_phy>; }; +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + pinctrl-names = "default"; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + &ir { status = "okay"; pinctrl-0 = <&remote_input_ao_pins>; pinctrl-names = "default"; }; +&pwm_ef { + status = "okay"; + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; + clocks = <&clkc CLKID_FCLK_DIV4>; + clock-names = "clkin0"; +}; + /* Wireless SDIO Module */ &sd_emmc_a { status = "okay"; @@ -217,28 +237,8 @@ vqmmc-supply = <&vddio_boot>; }; -&pwm_ef { - status = "okay"; - pinctrl-0 = <&pwm_e_pins>; - pinctrl-names = "default"; - clocks = <&clkc CLKID_FCLK_DIV4>; - clock-names = "clkin0"; -}; - -&cvbs_vdac_port { - cvbs_vdac_out: endpoint { - remote-endpoint = <&cvbs_connector_in>; - }; -}; - -&hdmi_tx { +&uart_AO { status = "okay"; - pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + pinctrl-0 = <&uart_ao_a_pins>; pinctrl-names = "default"; }; - -&hdmi_tx_tmds_port { - hdmi_tx_tmds_out: endpoint { - remote-endpoint = <&hdmi_connector_in>; - }; -}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi index 0f78d836edaf..3314a0b3dad9 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi @@ -48,7 +48,7 @@ compatible = "amlogic,s905x", "amlogic,meson-gxl"; }; -/* S905X Only has access to its internal PHY */ +/* S905X only has access to its internal PHY */ ðmac { phy-mode = "rmii"; phy-handle = <&internal_phy>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi index d8e096dff10a..4dfc22b07bf0 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi @@ -190,9 +190,59 @@ function = "spdif_out_ao"; }; }; + + ao_cec_pins: ao_cec { + mux { + groups = "ao_cec"; + function = "cec_ao"; + }; + }; + + ee_cec_pins: ee_cec { + mux { + groups = "ee_cec"; + function = "cec_ao"; + }; + }; + }; +}; + +&hdmi_tx { + compatible = "amlogic,meson-gxl-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; + resets = <&reset RESET_HDMITX_CAPB3>, + <&reset RESET_HDMI_SYSTEM_RESET>, + <&reset RESET_HDMI_TX>; + reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; + clocks = <&clkc CLKID_HDMI_PCLK>, + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; +}; + +&hiubus { + clkc: clock-controller@0 { + compatible = "amlogic,gxl-clkc", "amlogic,gxbb-clkc"; + #clock-cells = <1>; + reg = <0x0 0x0 0x0 0x3db>; }; }; +&i2c_A { + clocks = <&clkc CLKID_I2C>; +}; + +&i2c_AO { + clocks = <&clkc CLKID_AO_I2C>; +}; + +&i2c_B { + clocks = <&clkc CLKID_I2C>; +}; + +&i2c_C { + clocks = <&clkc CLKID_I2C>; +}; + &periphs { pinctrl_periphs: pinctrl@4b0 { compatible = "amlogic,meson-gxl-periphs-pinctrl"; @@ -203,12 +253,12 @@ gpio: bank@4b0 { reg = <0x0 0x004b0 0x0 0x28>, <0x0 0x004e8 0x0 0x14>, - <0x0 0x00120 0x0 0x14>, + <0x0 0x00520 0x0 0x14>, <0x0 0x00430 0x0 0x40>; reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&pinctrl_periphs 0 14 101>; + gpio-ranges = <&pinctrl_periphs 0 10 101>; }; emmc_pins: emmc { @@ -231,6 +281,22 @@ }; }; + spi_pins: spi { + mux { + groups = "spi_miso", + "spi_mosi", + "spi_sclk"; + function = "spi"; + }; + }; + + spi_ss0_pins: spi-ss0 { + mux { + groups = "spi_ss0"; + function = "spi"; + }; + }; + sdcard_pins: sdcard { mux { groups = "sdcard_d0", @@ -354,6 +420,20 @@ }; }; + eth_link_led_pins: eth_link_led { + mux { + groups = "eth_link_led"; + function = "eth_led"; + }; + }; + + eth_act_led_pins: eth_act_led { + mux { + groups = "eth_act_led"; + function = "eth_led"; + }; + }; + pwm_a_pins: pwm_a { mux { groups = "pwm_a"; @@ -501,30 +581,6 @@ }; }; -&hiubus { - clkc: clock-controller@0 { - compatible = "amlogic,gxl-clkc", "amlogic,gxbb-clkc"; - #clock-cells = <1>; - reg = <0x0 0x0 0x0 0x3db>; - }; -}; - -&i2c_A { - clocks = <&clkc CLKID_I2C>; -}; - -&i2c_AO { - clocks = <&clkc CLKID_AO_I2C>; -}; - -&i2c_B { - clocks = <&clkc CLKID_I2C>; -}; - -&i2c_C { - clocks = <&clkc CLKID_I2C>; -}; - &saradc { compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; clocks = <&xtal>, @@ -563,15 +619,3 @@ &vpu { compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; }; - -&hdmi_tx { - compatible = "amlogic,meson-gxl-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; - resets = <&reset RESET_HDMITX_CAPB3>, - <&reset RESET_HDMI_SYSTEM_RESET>, - <&reset RESET_HDMI_TX>; - reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; - clocks = <&clkc CLKID_HDMI_PCLK>, - <&clkc CLKID_CLK81>, - <&clkc CLKID_GCLK_VENCI_INT0>; - clock-names = "isfr", "iahb", "venci"; -}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts index 11b0bf46a95c..5f626d683088 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts @@ -113,11 +113,49 @@ }; }; -/* This UART is brought out to the DB9 connector */ -&uart_AO { +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; +}; + +ðmac { status = "okay"; - pinctrl-0 = <&uart_ao_a_pins>; + + pinctrl-0 = <ð_pins>; pinctrl-names = "default"; + + /* Select external PHY by default */ + phy-handle = <&external_phy>; + + amlogic,tx-delay-ns = <2>; + + snps,reset-gpio = <&gpio GPIOZ_14 0>; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-active-low; + + /* External PHY is in RGMII */ + phy-mode = "rgmii"; +}; + +&external_mdio { + external_phy: ethernet-phy@0 { + compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22"; + reg = <0>; + max-speed = <1000>; + }; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + pinctrl-names = "default"; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; }; &ir { @@ -164,47 +202,8 @@ vqmmc-supply = <&vddio_boot>; }; -ðmac { - status = "okay"; - - pinctrl-0 = <ð_pins>; - pinctrl-names = "default"; - - /* Select external PHY by default */ - phy-handle = <&external_phy>; - - amlogic,tx-delay-ns = <2>; - - snps,reset-gpio = <&gpio GPIOZ_14 0>; - snps,reset-delays-us = <0 10000 1000000>; - snps,reset-active-low; - - /* External PHY is in RGMII */ - phy-mode = "rgmii"; -}; - -&external_mdio { - external_phy: ethernet-phy@0 { - compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22"; - reg = <0>; - max-speed = <1000>; - }; -}; - -&cvbs_vdac_port { - cvbs_vdac_out: endpoint { - remote-endpoint = <&cvbs_connector_in>; - }; -}; - -&hdmi_tx { +&uart_AO { status = "okay"; - pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + pinctrl-0 = <&uart_ao_a_pins>; pinctrl-names = "default"; }; - -&hdmi_tx_tmds_port { - hdmi_tx_tmds_out: endpoint { - remote-endpoint = <&hdmi_connector_in>; - }; -}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts new file mode 100644 index 000000000000..08f1dd69b679 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2016-2017 Andreas Färber + * + * Based on nexbox-a1: + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong <narmstrong@baylibre.com> + * + * Copyright (c) 2016 Endless Computers, Inc. + * Author: Carlo Caione <carlo@endlessm.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "meson-gxm.dtsi" + +/ { + compatible = "kingnovel,r-box-pro", "amlogic,s912", "amlogic,meson-gxm"; + model = "R-Box Pro"; + + aliases { + serial0 = &uart_AO; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; /* 2 GiB or 3 GiB */ + }; + + leds { + compatible = "gpio-leds"; + + blue { + label = "rbox-pro:blue:on"; + gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + red { + label = "rbox-pro:red:standby"; + gpios = <&gpio GPIODV_28 GPIO_ACTIVE_HIGH>; + default-state = "off"; + retain-state-suspended; + panic-indicator; + }; + }; + + vddio_boot: regulator-vddio-boot { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_BOOT"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + vddao_3v3: regulator-vddao-3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + vcc_3v3: regulator-vcc-3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; + }; + + wifi32k: wifi32k { + compatible = "pwm-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */ + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; + clocks = <&wifi32k>; + clock-names = "ext_clock"; + }; +}; + +ðmac { + status = "okay"; + + pinctrl-0 = <ð_pins>; + pinctrl-names = "default"; + + /* Select external PHY by default */ + phy-handle = <&external_phy>; + + snps,reset-gpio = <&gpio GPIOZ_14 0>; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-active-low; + + amlogic,tx-delay-ns = <2>; + + /* External PHY is in RGMII */ + phy-mode = "rgmii"; +}; + +&external_mdio { + external_phy: ethernet-phy@0 { + compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22"; + reg = <0>; + max-speed = <1000>; + }; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; +}; + +&pwm_ef { + status = "okay"; + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; + clocks = <&clkc CLKID_FCLK_DIV4>; + clock-names = "clkin0"; +}; + +/* Wireless SDIO Module */ +&sd_emmc_a { + status = "okay"; + pinctrl-0 = <&sdio_pins>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <100000000>; + + non-removable; + disable-wp; + + mmc-pwrseq = <&sdio_pwrseq>; + + vmmc-supply = <&vddao_3v3>; + vqmmc-supply = <&vddio_boot>; + + brcmf: brcmf@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +/* SD card */ +&sd_emmc_b { + status = "okay"; + pinctrl-0 = <&sdcard_pins>; + pinctrl-names = "default"; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <100000000>; + disable-wp; + + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; + cd-inverted; + + vmmc-supply = <&vddao_3v3>; + vqmmc-supply = <&vddio_boot>; +}; + +/* eMMC */ +&sd_emmc_c { + status = "okay"; + pinctrl-0 = <&emmc_pins>; + pinctrl-names = "default"; + + bus-width = <8>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <200000000>; + non-removable; + disable-wp; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vddio_boot>; +}; + +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts index 3ff95277a8ec..23191eb9397c 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts @@ -60,7 +60,6 @@ vci-supply = <&ldo28_reg>; reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>; enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>; - te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts index 17fae8112e4d..7286b1ebfd7a 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts @@ -1,7 +1,7 @@ /* * Device Tree file for Freescale LS1012A Freedom Board. * - * Copyright 2016, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. * * This file is dual-licensed: you can use it either under the terms * of the GPLv2 or the X11 license, at your option. Note that this dual diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts index e2a93d53d3d8..8c013b54db14 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts @@ -1,7 +1,7 @@ /* * Device Tree file for Freescale LS1012A QDS Board. * - * Copyright 2016, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. * * This file is dual-licensed: you can use it either under the terms * of the GPLv2 or the X11 license, at your option. Note that this dual @@ -97,6 +97,14 @@ status = "okay"; }; +&esdhc0 { + status = "okay"; +}; + +&esdhc1 { + status = "okay"; +}; + &i2c0 { status = "okay"; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts index ed77f6b0937b..c1a119effa61 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts @@ -1,7 +1,7 @@ /* * Device Tree file for Freescale LS1012A RDB Board. * - * Copyright 2016, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. * * This file is dual-licensed: you can use it either under the terms * of the GPLv2 or the X11 license, at your option. Note that this dual @@ -54,6 +54,19 @@ status = "okay"; }; +&esdhc0 { + sd-uhs-sdr104; + sd-uhs-sdr50; + sd-uhs-sdr25; + sd-uhs-sdr12; + status = "okay"; +}; + +&esdhc1 { + mmc-hs200-1_8v; + status = "okay"; +}; + &i2c0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi index b497ac196ccc..9a2ccd86ec12 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi @@ -1,7 +1,7 @@ /* * Device Tree Include file for Freescale Layerscape-1012A family SoC. * - * Copyright 2016, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. * * This file is dual-licensed: you can use it either under the terms * of the GPLv2 or the X11 license, at your option. Note that this dual @@ -117,12 +117,37 @@ #size-cells = <2>; ranges; + esdhc0: esdhc@1560000 { + compatible = "fsl,ls1012a-esdhc", "fsl,esdhc"; + reg = <0x0 0x1560000 0x0 0x10000>; + interrupts = <0 62 0x4>; + clocks = <&clockgen 4 0>; + voltage-ranges = <1800 1800 3300 3300>; + sdhci,auto-cmd12; + big-endian; + bus-width = <4>; + status = "disabled"; + }; + scfg: scfg@1570000 { compatible = "fsl,ls1012a-scfg", "syscon"; reg = <0x0 0x1570000 0x0 0x10000>; big-endian; }; + esdhc1: esdhc@1580000 { + compatible = "fsl,ls1012a-esdhc", "fsl,esdhc"; + reg = <0x0 0x1580000 0x0 0x10000>; + interrupts = <0 65 0x4>; + clocks = <&clockgen 4 0>; + voltage-ranges = <1800 1800 3300 3300>; + sdhci,auto-cmd12; + big-endian; + broken-cd; + bus-width = <4>; + status = "disabled"; + }; + crypto: crypto@1700000 { compatible = "fsl,sec-v5.4", "fsl,sec-v5.0", "fsl,sec-v4.0"; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi new file mode 100644 index 000000000000..169e171407a6 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi @@ -0,0 +1,45 @@ +/* + * QorIQ FMan v3 device tree nodes for ls1043 + * + * Copyright 2015-2016 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +&soc { + +/* include used FMan blocks */ +#include "qoriq-fman3-0.dtsi" +#include "qoriq-fman3-0-1g-0.dtsi" +#include "qoriq-fman3-0-1g-1.dtsi" +#include "qoriq-fman3-0-1g-2.dtsi" +#include "qoriq-fman3-0-1g-3.dtsi" +#include "qoriq-fman3-0-1g-4.dtsi" +#include "qoriq-fman3-0-1g-5.dtsi" +#include "qoriq-fman3-0-10g-0.dtsi" + +}; + +&fman0 { + /* these aliases provide the FMan ports mapping */ + enet0: ethernet@e0000 { + }; + + enet1: ethernet@e2000 { + }; + + enet2: ethernet@e4000 { + }; + + enet3: ethernet@e6000 { + }; + + enet4: ethernet@e8000 { + }; + + enet5: ethernet@ea000 { + }; + + enet6: ethernet@f0000 { + }; +}; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts index 0989d635b558..6341281485cf 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts @@ -1,7 +1,7 @@ /* * Device Tree Include file for Freescale Layerscape-1043A family SoC. * - * Copyright 2014-2015, Freescale Semiconductor + * Copyright 2014-2015 Freescale Semiconductor, Inc. * * Mingkai Hu <Mingkai.hu@freescale.com> * @@ -181,3 +181,5 @@ reg = <0>; }; }; + +#include "fsl-ls1043-post.dtsi" diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts index c37110bc1506..df5b180a95a8 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts @@ -1,7 +1,7 @@ /* * Device Tree Include file for Freescale Layerscape-1043A family SoC. * - * Copyright 2014-2015, Freescale Semiconductor + * Copyright 2014-2015 Freescale Semiconductor, Inc. * * Mingkai Hu <Mingkai.hu@freescale.com> * @@ -139,3 +139,76 @@ &duart1 { status = "okay"; }; + +#include "fsl-ls1043-post.dtsi" + +&fman0 { + ethernet@e0000 { + phy-handle = <&qsgmii_phy1>; + phy-connection-type = "qsgmii"; + }; + + ethernet@e2000 { + phy-handle = <&qsgmii_phy2>; + phy-connection-type = "qsgmii"; + }; + + ethernet@e4000 { + phy-handle = <&rgmii_phy1>; + phy-connection-type = "rgmii-txid"; + }; + + ethernet@e6000 { + phy-handle = <&rgmii_phy2>; + phy-connection-type = "rgmii-txid"; + }; + + ethernet@e8000 { + phy-handle = <&qsgmii_phy3>; + phy-connection-type = "qsgmii"; + }; + + ethernet@ea000 { + phy-handle = <&qsgmii_phy4>; + phy-connection-type = "qsgmii"; + }; + + ethernet@f0000 { /* 10GEC1 */ + phy-handle = <&aqr105_phy>; + phy-connection-type = "xgmii"; + }; + + mdio@fc000 { + rgmii_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + + rgmii_phy2: ethernet-phy@2 { + reg = <0x2>; + }; + + qsgmii_phy1: ethernet-phy@4 { + reg = <0x4>; + }; + + qsgmii_phy2: ethernet-phy@5 { + reg = <0x5>; + }; + + qsgmii_phy3: ethernet-phy@6 { + reg = <0x6>; + }; + + qsgmii_phy4: ethernet-phy@7 { + reg = <0x7>; + }; + }; + + mdio@fd000 { + aqr105_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c45"; + interrupts = <0 132 4>; + reg = <0x1>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 45cface08cbb..31fd77f82ced 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -1,7 +1,7 @@ /* * Device Tree Include file for Freescale Layerscape-1043A family SoC. * - * Copyright 2014-2015, Freescale Semiconductor + * Copyright 2014-2015 Freescale Semiconductor, Inc. * * Mingkai Hu <Mingkai.hu@freescale.com> * @@ -45,6 +45,7 @@ */ #include <dt-bindings/thermal/thermal.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> / { compatible = "fsl,ls1043a"; @@ -52,6 +53,17 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + fman0 = &fman0; + ethernet0 = &enet0; + ethernet1 = &enet1; + ethernet2 = &enet2; + ethernet3 = &enet3; + ethernet4 = &enet4; + ethernet5 = &enet5; + ethernet6 = &enet6; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -106,6 +118,33 @@ /* DRAM space 1, size: 2GiB DRAM */ }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + bman_fbpr: bman-fbpr { + compatible = "shared-dma-pool"; + size = <0 0x1000000>; + alignment = <0 0x1000000>; + no-map; + }; + + qman_fqd: qman-fqd { + compatible = "shared-dma-pool"; + size = <0 0x400000>; + alignment = <0 0x400000>; + no-map; + }; + + qman_pfdr: qman-pfdr { + compatible = "shared-dma-pool"; + size = <0 0x2000000>; + alignment = <0 0x2000000>; + no-map; + }; + }; + sysclk: sysclk { compatible = "fixed-clock"; #clock-cells = <0>; @@ -152,7 +191,7 @@ interrupts = <1 9 0xf08>; }; - soc { + soc: soc { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -223,6 +262,7 @@ ifc: ifc@1530000 { compatible = "fsl,ifc", "simple-bus"; reg = <0x0 0x1530000 0x0 0x10000>; + big-endian; interrupts = <0 43 0x4>; }; @@ -333,6 +373,28 @@ }; }; + qman: qman@1880000 { + compatible = "fsl,qman"; + reg = <0x0 0x1880000 0x0 0x10000>; + interrupts = <0 45 0x4>; + memory-region = <&qman_fqd &qman_pfdr>; + }; + + bman: bman@1890000 { + compatible = "fsl,bman"; + reg = <0x0 0x1890000 0x0 0x10000>; + interrupts = <0 45 0x4>; + memory-region = <&bman_fbpr>; + }; + + bportals: bman-portals@508000000 { + ranges = <0x0 0x5 0x08000000 0x8000000>; + }; + + qportals: qman-portals@500000000 { + ranges = <0x0 0x5 0x00000000 0x8000000>; + }; + dspi0: dspi@2100000 { compatible = "fsl,ls1043a-dspi", "fsl,ls1021a-v1.0-dspi"; #address-cells = <1>; @@ -688,3 +750,6 @@ }; }; + +#include "qoriq-qman-portals.dtsi" +#include "qoriq-bman-portals.dtsi" diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi new file mode 100644 index 000000000000..f5017dba0f17 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi @@ -0,0 +1,48 @@ +/* + * QorIQ FMan v3 device tree nodes for ls1046 + * + * Copyright 2015-2016 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +&soc { + +/* include used FMan blocks */ +#include "qoriq-fman3-0.dtsi" +#include "qoriq-fman3-0-1g-0.dtsi" +#include "qoriq-fman3-0-1g-1.dtsi" +#include "qoriq-fman3-0-1g-2.dtsi" +#include "qoriq-fman3-0-1g-3.dtsi" +#include "qoriq-fman3-0-1g-4.dtsi" +#include "qoriq-fman3-0-1g-5.dtsi" +#include "qoriq-fman3-0-10g-0.dtsi" +#include "qoriq-fman3-0-10g-1.dtsi" +}; + +&fman0 { + /* these aliases provide the FMan ports mapping */ + enet0: ethernet@e0000 { + }; + + enet1: ethernet@e2000 { + }; + + enet2: ethernet@e4000 { + }; + + enet3: ethernet@e6000 { + }; + + enet4: ethernet@e8000 { + }; + + enet5: ethernet@ea000 { + }; + + enet6: ethernet@f0000 { + }; + + enet7: ethernet@f2000 { + }; +}; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts index 290e5b014414..434383bade0e 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts @@ -1,7 +1,7 @@ /* * Device Tree Include file for Freescale Layerscape-1046A family SoC. * - * Copyright 2016, Freescale Semiconductor, Inc. + * Copyright 2016 Freescale Semiconductor, Inc. * * Shaohui Xie <Shaohui.Xie@nxp.com> * @@ -210,3 +210,5 @@ reg = <0>; }; }; + +#include "fsl-ls1046-post.dtsi" diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts index d1ccc000d05a..5dc2782e2a58 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts @@ -1,7 +1,7 @@ /* * Device Tree Include file for Freescale Layerscape-1046A family SoC. * - * Copyright 2016, Freescale Semiconductor, Inc. + * Copyright 2016 Freescale Semiconductor, Inc. * * Mingkai Hu <mingkai.hu@nxp.com> * @@ -72,6 +72,14 @@ status = "okay"; }; +&esdhc { + mmc-hs200-1_8v; + sd-uhs-sdr104; + sd-uhs-sdr50; + sd-uhs-sdr25; + sd-uhs-sdr12; +}; + &i2c0 { status = "okay"; @@ -148,3 +156,63 @@ reg = <1>; }; }; + +#include "fsl-ls1046-post.dtsi" + +&fman0 { + ethernet@e4000 { + phy-handle = <&rgmii_phy1>; + phy-connection-type = "rgmii"; + }; + + ethernet@e6000 { + phy-handle = <&rgmii_phy2>; + phy-connection-type = "rgmii"; + }; + + ethernet@e8000 { + phy-handle = <&sgmii_phy1>; + phy-connection-type = "sgmii"; + }; + + ethernet@ea000 { + phy-handle = <&sgmii_phy2>; + phy-connection-type = "sgmii"; + }; + + ethernet@f0000 { /* 10GEC1 */ + phy-handle = <&aqr106_phy>; + phy-connection-type = "xgmii"; + }; + + ethernet@f2000 { /* 10GEC2 */ + fixed-link = <0 1 1000 0 0>; + phy-connection-type = "xgmii"; + }; + + mdio@fc000 { + rgmii_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + + rgmii_phy2: ethernet-phy@2 { + reg = <0x2>; + }; + + sgmii_phy1: ethernet-phy@3 { + reg = <0x3>; + }; + + sgmii_phy2: ethernet-phy@4 { + reg = <0x4>; + }; + }; + + mdio@fd000 { + aqr106_phy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + interrupts = <0 131 4>; + reg = <0x0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index f4b8b7edaf9d..c161df66a9ea 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -1,7 +1,7 @@ /* * Device Tree Include file for Freescale Layerscape-1046A family SoC. * - * Copyright 2016, Freescale Semiconductor, Inc. + * Copyright 2016 Freescale Semiconductor, Inc. * * Mingkai Hu <mingkai.hu@nxp.com> * @@ -55,6 +55,15 @@ aliases { crypto = &crypto; + fman0 = &fman0; + ethernet0 = &enet0; + ethernet1 = &enet1; + ethernet2 = &enet2; + ethernet3 = &enet3; + ethernet4 = &enet4; + ethernet5 = &enet5; + ethernet6 = &enet6; + ethernet7 = &enet7; }; cpus { @@ -174,7 +183,7 @@ IRQ_TYPE_LEVEL_LOW)>; }; - soc { + soc: soc { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -190,6 +199,7 @@ ifc: ifc@1530000 { compatible = "fsl,ifc", "simple-bus"; reg = <0x0 0x1530000 0x0 0x10000>; + big-endian; interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; }; @@ -209,10 +219,10 @@ }; esdhc: esdhc@1560000 { - compatible = "fsl,esdhc"; + compatible = "fsl,ls1046a-esdhc", "fsl,esdhc"; reg = <0x0 0x1560000 0x0 0x10000>; interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; - clock-frequency = <0>; + clocks = <&clockgen 2 1>; voltage-ranges = <1800 1800 3300 3300>; sdhci,auto-cmd12; big-endian; @@ -268,6 +278,30 @@ }; }; + qman: qman@1880000 { + compatible = "fsl,qman"; + reg = <0x0 0x1880000 0x0 0x10000>; + interrupts = <0 45 0x4>; + memory-region = <&qman_fqd &qman_pfdr>; + + }; + + bman: bman@1890000 { + compatible = "fsl,bman"; + reg = <0x0 0x1890000 0x0 0x10000>; + interrupts = <0 45 0x4>; + memory-region = <&bman_fbpr>; + + }; + + qportals: qman-portals@500000000 { + ranges = <0x0 0x5 0x00000000 0x8000000>; + }; + + bportals: bman-portals@508000000 { + ranges = <0x0 0x5 0x08000000 0x8000000>; + }; + dcfg: dcfg@1ee0000 { compatible = "fsl,ls1046a-dcfg", "syscon"; reg = <0x0 0x1ee0000 0x0 0x10000>; @@ -594,4 +628,34 @@ clocks = <&clockgen 4 1>; }; }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + bman_fbpr: bman-fbpr { + compatible = "shared-dma-pool"; + size = <0 0x1000000>; + alignment = <0 0x1000000>; + no-map; + }; + + qman_fqd: qman-fqd { + compatible = "shared-dma-pool"; + size = <0 0x800000>; + alignment = <0 0x800000>; + no-map; + }; + + qman_pfdr: qman-pfdr { + compatible = "shared-dma-pool"; + size = <0 0x2000000>; + alignment = <0 0x2000000>; + no-map; + }; + }; }; + +#include "qoriq-qman-portals.dtsi" +#include "qoriq-bman-portals.dtsi" diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts index 8c3cae530f8f..30128051d0c0 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts @@ -110,6 +110,30 @@ }; }; +&ifc { + ranges = <0 0 0x5 0x80000000 0x08000000 + 2 0 0x5 0x30000000 0x00010000 + 3 0 0x5 0x20000000 0x00010000>; + status = "okay"; + + nor@0,0 { + compatible = "cfi-flash"; + reg = <0x0 0x0 0x8000000>; + bank-width = <2>; + device-width = <1>; + }; + + nand@2,0 { + compatible = "fsl,ifc-nand"; + reg = <0x2 0x0 0x10000>; + }; + + fpga: board-control@3,0 { + compatible = "fsl,ls1088aqds-fpga", "fsl,fpga-qixis"; + reg = <0x3 0x0 0x0000100>; + }; +}; + &duart0 { status = "okay"; }; @@ -118,6 +142,10 @@ status = "okay"; }; +&esdhc { + status = "okay"; +}; + &sata { status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts index 8a04fbb25cb4..213abb72de93 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts @@ -94,6 +94,22 @@ }; }; +&ifc { + ranges = <0 0 0x5 0x30000000 0x00010000 + 2 0 0x5 0x20000000 0x00010000>; + status = "okay"; + + nand@0,0 { + compatible = "fsl,ifc-nand"; + reg = <0x0 0x0 0x10000>; + }; + + fpga: board-control@2,0 { + compatible = "fsl,ls1088ardb-fpga", "fsl,fpga-qixis"; + reg = <0x2 0x0 0x0000100>; + }; +}; + &duart0 { status = "okay"; }; @@ -102,6 +118,10 @@ status = "okay"; }; +&esdhc { + status = "okay"; +}; + &sata { status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi index 2946fd797121..df16284ec5ec 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -44,6 +44,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/thermal/thermal.h> / { compatible = "fsl,ls1088a"; @@ -61,6 +62,7 @@ compatible = "arm,cortex-a53"; reg = <0x0>; clocks = <&clockgen 1 0>; + #cooling-cells = <2>; }; cpu1: cpu@1 { @@ -89,6 +91,7 @@ compatible = "arm,cortex-a53"; reg = <0x100>; clocks = <&clockgen 1 1>; + #cooling-cells = <2>; }; cpu5: cpu@101 { @@ -153,6 +156,91 @@ clocks = <&sysclk>; }; + tmu: tmu@1f80000 { + compatible = "fsl,qoriq-tmu"; + reg = <0x0 0x1f80000 0x0 0x10000>; + interrupts = <0 23 0x4>; + fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x30062>; + fsl,tmu-calibration = + /* Calibration data group 1 */ + <0x00000000 0x00000026 + 0x00000001 0x0000002d + 0x00000002 0x00000032 + 0x00000003 0x00000039 + 0x00000004 0x0000003f + 0x00000005 0x00000046 + 0x00000006 0x0000004d + 0x00000007 0x00000054 + 0x00000008 0x0000005a + 0x00000009 0x00000061 + 0x0000000a 0x0000006a + 0x0000000b 0x00000071 + /* Calibration data group 2 */ + 0x00010000 0x00000025 + 0x00010001 0x0000002c + 0x00010002 0x00000035 + 0x00010003 0x0000003d + 0x00010004 0x00000045 + 0x00010005 0x0000004e + 0x00010006 0x00000057 + 0x00010007 0x00000061 + 0x00010008 0x0000006b + 0x00010009 0x00000076 + /* Calibration data group 3 */ + 0x00020000 0x00000029 + 0x00020001 0x00000033 + 0x00020002 0x0000003d + 0x00020003 0x00000049 + 0x00020004 0x00000056 + 0x00020005 0x00000061 + 0x00020006 0x0000006d + /* Calibration data group 4 */ + 0x00030000 0x00000021 + 0x00030001 0x0000002a + 0x00030002 0x0000003c + 0x00030003 0x0000004e>; + little-endian; + #thermal-sensor-cells = <1>; + }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <1000>; + polling-delay = <5000>; + thermal-sensors = <&tmu 0>; + + trips { + cpu_alert: cpu-alert { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_crit: cpu-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + + map1 { + trip = <&cpu_alert>; + cooling-device = + <&cpu4 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + }; + }; + }; + duart0: serial@21c0500 { compatible = "fsl,ns16550", "ns16550a"; reg = <0x0 0x21c0500 0x0 0x100>; @@ -216,10 +304,6 @@ little-endian; #address-cells = <2>; #size-cells = <1>; - - ranges = <0 0 0x5 0x80000000 0x08000000 - 2 0 0x5 0x30000000 0x00010000 - 3 0 0x5 0x20000000 0x00010000>; status = "disabled"; }; @@ -263,11 +347,26 @@ status = "disabled"; }; + esdhc: esdhc@2140000 { + compatible = "fsl,ls1088a-esdhc", "fsl,esdhc"; + reg = <0x0 0x2140000 0x0 0x10000>; + interrupts = <0 28 0x4>; /* Level high type */ + clock-frequency = <0>; + voltage-ranges = <1800 1800 3300 3300>; + sdhci,auto-cmd12; + little-endian; + bus-width = <4>; + status = "disabled"; + }; + sata: sata@3200000 { compatible = "fsl,ls1088a-ahci", "fsl,ls1043a-ahci"; - reg = <0x0 0x3200000 0x0 0x10000>; + reg = <0x0 0x3200000 0x0 0x10000>, + <0x0 0x20140520 0x0 0x4>; + reg-names = "ahci", "sata-ecc"; interrupts = <0 133 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clockgen 4 3>; + dma-coherent; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts index c1e76dfca48e..ed209cd57283 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts @@ -1,7 +1,8 @@ /* * Device Tree file for Freescale LS2080a QDS Board. * - * Copyright (C) 2015-17, Freescale Semiconductor + * Copyright 2015-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Abhimanyu Saini <abhimanyu.saini@nxp.com> * Bhupesh Sharma <bhupesh.sharma@freescale.com> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts index 18ad19587311..67ec3f9c81a1 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts @@ -1,7 +1,8 @@ /* * Device Tree file for Freescale LS2080a RDB Board. * - * Copyright (C) 2016-17, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Abhimanyu Saini <abhimanyu.saini@nxp.com> * Bhupesh Sharma <bhupesh.sharma@freescale.com> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts index 290604b0a603..3ee718f0aaf8 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts @@ -1,7 +1,7 @@ /* * Device Tree file for Freescale LS2080a software Simulator model * - * Copyright (C) 2014-2015, Freescale Semiconductor + * Copyright 2014-2015 Freescale Semiconductor, Inc. * * Bhupesh Sharma <bhupesh.sharma@freescale.com> * diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi index 46a26c021421..d789c6814e6a 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi @@ -1,7 +1,7 @@ /* * Device Tree Include file for Freescale Layerscape-2080A family SoC. * - * Copyright (C) 2014-2016, Freescale Semiconductor + * Copyright 2014-2016 Freescale Semiconductor, Inc. * * Abhimanyu Saini <abhimanyu.saini@nxp.com> * Bhupesh Sharma <bhupesh.sharma@freescale.com> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts index ebcd6ee4da0d..4a1df5ce3229 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts @@ -1,7 +1,8 @@ /* * Device Tree file for Freescale LS2088A QDS Board. * - * Copyright (C) 2016-17, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Abhimanyu Saini <abhimanyu.saini@nxp.com> * diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts index 5992dc130faa..a76d4b4debd1 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts @@ -1,7 +1,8 @@ /* * Device Tree file for Freescale LS2088A RDB Board. * - * Copyright (C) 2016-17, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Abhimanyu Saini <abhimanyu.saini@nxp.com> * diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi index 33ce404cf7e4..5c695c658056 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi @@ -1,7 +1,8 @@ /* * Device Tree Include file for Freescale Layerscape-2088A family SoC. * - * Copyright (C) 2016-17, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Abhimanyu Saini <abhimanyu.saini@nxp.com> * diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi index 8b6204845973..b2374469a830 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi @@ -1,7 +1,8 @@ /* * Device Tree file for Freescale LS2080A QDS Board. * - * Copyright (C) 2016-17, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Abhimanyu Saini <abhimanyu.saini@nxp.com> * @@ -45,6 +46,7 @@ */ &esdhc { + mmc-hs200-1_8v; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi index 3737587ffb33..29af54be2665 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi @@ -1,7 +1,8 @@ /* * Device Tree file for Freescale LS2080A RDB Board. * - * Copyright (C) 2016-17, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Abhimanyu Saini <abhimanyu.saini@nxp.com> * @@ -45,6 +46,10 @@ */ &esdhc { + sd-uhs-sdr104; + sd-uhs-sdr50; + sd-uhs-sdr25; + sd-uhs-sdr12; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index abb2fff7d162..94cdd3045037 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -1,7 +1,8 @@ /* * Device Tree Include file for Freescale Layerscape-2080A family SoC. * - * Copyright (C) 2016-2017, Freescale Semiconductor + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Abhimanyu Saini <abhimanyu.saini@nxp.com> * @@ -471,7 +472,7 @@ compatible = "fsl,ls2080a-esdhc", "fsl,esdhc"; reg = <0x0 0x2140000 0x0 0x10000>; interrupts = <0 28 0x4>; /* Level high type */ - clock-frequency = <0>; /* Updated by bootloader */ + clocks = <&clockgen 4 1>; voltage-ranges = <1800 1800 3300 3300>; sdhci,auto-cmd12; little-endian; diff --git a/arch/arm64/boot/dts/freescale/qoriq-bman-portals.dtsi b/arch/arm64/boot/dts/freescale/qoriq-bman-portals.dtsi new file mode 100644 index 000000000000..c3c2be4f5072 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-bman-portals.dtsi @@ -0,0 +1,71 @@ +/* + * QorIQ BMan Portals device tree + * + * Copyright 2011-2016 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +&bportals { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + + bman-portal@0 { + /* + * bootloader fix-ups are expected to provide the + * "fsl,bman-portal-<hardware revision>" compatible + */ + compatible = "fsl,bman-portal"; + reg = <0x0 0x4000>, <0x4000000 0x4000>; + interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>; + }; + + bman-portal@10000 { + compatible = "fsl,bman-portal"; + reg = <0x10000 0x4000>, <0x4010000 0x4000>; + interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>; + }; + + bman-portal@20000 { + compatible = "fsl,bman-portal"; + reg = <0x20000 0x4000>, <0x4020000 0x4000>; + interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>; + }; + + bman-portal@30000 { + compatible = "fsl,bman-portal"; + reg = <0x30000 0x4000>, <0x4030000 0x4000>; + interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>; + }; + + bman-portal@40000 { + compatible = "fsl,bman-portal"; + reg = <0x40000 0x4000>, <0x4040000 0x4000>; + interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>; + }; + + bman-portal@50000 { + compatible = "fsl,bman-portal"; + reg = <0x50000 0x4000>, <0x4050000 0x4000>; + interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>; + }; + + bman-portal@60000 { + compatible = "fsl,bman-portal"; + reg = <0x60000 0x4000>, <0x4060000 0x4000>; + interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>; + }; + + bman-portal@70000 { + compatible = "fsl,bman-portal"; + reg = <0x70000 0x4000>, <0x4070000 0x4000>; + interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>; + }; + + bman-portal@80000 { + compatible = "fsl,bman-portal"; + reg = <0x80000 0x4000>, <0x4080000 0x4000>; + interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi new file mode 100644 index 000000000000..ecdffe731b98 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi @@ -0,0 +1,42 @@ +/* + * QorIQ FMan v3 10g port #0 device tree + * + * Copyright 2012-2015 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +fman@1a00000 { + fman0_rx_0x10: port@90000 { + cell-index = <0x10>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x90000 0x1000>; + fsl,fman-10g-port; + }; + + fman0_tx_0x30: port@b0000 { + cell-index = <0x30>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xb0000 0x1000>; + fsl,fman-10g-port; + }; + + ethernet@f0000 { + cell-index = <0x8>; + compatible = "fsl,fman-memac"; + reg = <0xf0000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x10 &fman0_tx_0x30>; + pcsphy-handle = <&pcsphy6>; + }; + + mdio@f1000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xf1000 0x1000>; + + pcsphy6: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi new file mode 100644 index 000000000000..a7f6af56b6a5 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi @@ -0,0 +1,42 @@ +/* + * QorIQ FMan v3 10g port #1 device tree + * + * Copyright 2012-2015 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +fman@1a00000 { + fman0_rx_0x11: port@91000 { + cell-index = <0x11>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x91000 0x1000>; + fsl,fman-10g-port; + }; + + fman0_tx_0x31: port@b1000 { + cell-index = <0x31>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xb1000 0x1000>; + fsl,fman-10g-port; + }; + + ethernet@f2000 { + cell-index = <0x9>; + compatible = "fsl,fman-memac"; + reg = <0xf2000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x11 &fman0_tx_0x31>; + pcsphy-handle = <&pcsphy7>; + }; + + mdio@f3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xf3000 0x1000>; + + pcsphy7: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi new file mode 100644 index 000000000000..d600786719fb --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi @@ -0,0 +1,41 @@ +/* + * QorIQ FMan v3 1g port #0 device tree + * + * Copyright 2012-2015 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +fman@1a00000 { + fman0_rx_0x08: port@88000 { + cell-index = <0x8>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x88000 0x1000>; + }; + + fman0_tx_0x28: port@a8000 { + cell-index = <0x28>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xa8000 0x1000>; + }; + + ethernet@e0000 { + cell-index = <0>; + compatible = "fsl,fman-memac"; + reg = <0xe0000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy0>; + }; + + mdio@e1000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe1000 0x1000>; + + pcsphy0: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi new file mode 100644 index 000000000000..3c0b76d43043 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi @@ -0,0 +1,41 @@ +/* + * QorIQ FMan v3 1g port #1 device tree + * + * Copyright 2012-2015 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +fman@1a00000 { + fman0_rx_0x09: port@89000 { + cell-index = <0x9>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x89000 0x1000>; + }; + + fman0_tx_0x29: port@a9000 { + cell-index = <0x29>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xa9000 0x1000>; + }; + + ethernet@e2000 { + cell-index = <1>; + compatible = "fsl,fman-memac"; + reg = <0xe2000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy1>; + }; + + mdio@e3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe3000 0x1000>; + + pcsphy1: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi new file mode 100644 index 000000000000..89633afca26a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi @@ -0,0 +1,41 @@ +/* + * QorIQ FMan v3 1g port #2 device tree + * + * Copyright 2012-2015 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +fman@1a00000 { + fman0_rx_0x0a: port@8a000 { + cell-index = <0xa>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x8a000 0x1000>; + }; + + fman0_tx_0x2a: port@aa000 { + cell-index = <0x2a>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xaa000 0x1000>; + }; + + ethernet@e4000 { + cell-index = <2>; + compatible = "fsl,fman-memac"; + reg = <0xe4000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x0a &fman0_tx_0x2a>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy2>; + }; + + mdio@e5000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe5000 0x1000>; + + pcsphy2: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi new file mode 100644 index 000000000000..87c2b705b1f9 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi @@ -0,0 +1,41 @@ +/* + * QorIQ FMan v3 1g port #3 device tree + * + * Copyright 2012-2015 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +fman@1a00000 { + fman0_rx_0x0b: port@8b000 { + cell-index = <0xb>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x8b000 0x1000>; + }; + + fman0_tx_0x2b: port@ab000 { + cell-index = <0x2b>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xab000 0x1000>; + }; + + ethernet@e6000 { + cell-index = <3>; + compatible = "fsl,fman-memac"; + reg = <0xe6000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x0b &fman0_tx_0x2b>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy3>; + }; + + mdio@e7000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe7000 0x1000>; + + pcsphy3: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi new file mode 100644 index 000000000000..8f4d74b96b67 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi @@ -0,0 +1,41 @@ +/* + * QorIQ FMan v3 1g port #4 device tree + * + * Copyright 2012-2015 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +fman@1a00000 { + fman0_rx_0x0c: port@8c000 { + cell-index = <0xc>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x8c000 0x1000>; + }; + + fman0_tx_0x2c: port@ac000 { + cell-index = <0x2c>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xac000 0x1000>; + }; + + ethernet@e8000 { + cell-index = <4>; + compatible = "fsl,fman-memac"; + reg = <0xe8000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x0c &fman0_tx_0x2c>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy4>; + }; + + mdio@e9000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe9000 0x1000>; + + pcsphy4: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi new file mode 100644 index 000000000000..d534f770f729 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi @@ -0,0 +1,41 @@ +/* + * QorIQ FMan v3 1g port #5 device tree + * + * Copyright 2012-2015 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +fman@1a00000 { + fman0_rx_0x0d: port@8d000 { + cell-index = <0xd>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x8d000 0x1000>; + }; + + fman0_tx_0x2d: port@ad000 { + cell-index = <0x2d>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xad000 0x1000>; + }; + + ethernet@ea000 { + cell-index = <5>; + compatible = "fsl,fman-memac"; + reg = <0xea000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x0d &fman0_tx_0x2d>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy5>; + }; + + mdio@eb000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xeb000 0x1000>; + + pcsphy5: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi new file mode 100644 index 000000000000..4dd06767f839 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi @@ -0,0 +1,81 @@ +/* + * QorIQ FMan v3 device tree + * + * Copyright 2012-2015 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +fman0: fman@1a00000 { + #address-cells = <1>; + #size-cells = <1>; + cell-index = <0>; + compatible = "fsl,fman"; + ranges = <0x0 0x0 0x1a00000 0x100000>; + reg = <0x0 0x1a00000 0x0 0x100000>; + interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clockgen 3 0>; + clock-names = "fmanclk"; + fsl,qman-channel-range = <0x800 0x10>; + + muram@0 { + compatible = "fsl,fman-muram"; + reg = <0x0 0x60000>; + }; + + fman0_oh_0x2: port@82000 { + cell-index = <0x2>; + compatible = "fsl,fman-v3-port-oh"; + reg = <0x82000 0x1000>; + }; + + fman0_oh_0x3: port@83000 { + cell-index = <0x3>; + compatible = "fsl,fman-v3-port-oh"; + reg = <0x83000 0x1000>; + }; + + fman0_oh_0x4: port@84000 { + cell-index = <0x4>; + compatible = "fsl,fman-v3-port-oh"; + reg = <0x84000 0x1000>; + }; + + fman0_oh_0x5: port@85000 { + cell-index = <0x5>; + compatible = "fsl,fman-v3-port-oh"; + reg = <0x85000 0x1000>; + }; + + fman0_oh_0x6: port@86000 { + cell-index = <0x6>; + compatible = "fsl,fman-v3-port-oh"; + reg = <0x86000 0x1000>; + }; + + fman0_oh_0x7: port@87000 { + cell-index = <0x7>; + compatible = "fsl,fman-v3-port-oh"; + reg = <0x87000 0x1000>; + }; + + mdio0: mdio@fc000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xfc000 0x1000>; + }; + + xmdio0: mdio@fd000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xfd000 0x1000>; + }; + + ptp_timer0: ptp-timer@fe000 { + compatible = "fsl,fman-ptp-timer"; + reg = <0xfe000 0x1000>; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/qoriq-qman-portals.dtsi b/arch/arm64/boot/dts/freescale/qoriq-qman-portals.dtsi new file mode 100644 index 000000000000..2a9aa060efda --- /dev/null +++ b/arch/arm64/boot/dts/freescale/qoriq-qman-portals.dtsi @@ -0,0 +1,80 @@ +/* + * QorIQ QMan Portals device tree + * + * Copyright 2011-2016 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + */ + +&qportals { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + + qportal0: qman-portal@0 { + /* + * bootloader fix-ups are expected to provide the + * "fsl,bman-portal-<hardware revision>" compatible + */ + compatible = "fsl,qman-portal"; + reg = <0x0 0x4000>, <0x4000000 0x4000>; + interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>; + cell-index = <0>; + }; + + qportal1: qman-portal@10000 { + compatible = "fsl,qman-portal"; + reg = <0x10000 0x4000>, <0x4010000 0x4000>; + interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>; + cell-index = <1>; + }; + + qportal2: qman-portal@20000 { + compatible = "fsl,qman-portal"; + reg = <0x20000 0x4000>, <0x4020000 0x4000>; + interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>; + cell-index = <2>; + }; + + qportal3: qman-portal@30000 { + compatible = "fsl,qman-portal"; + reg = <0x30000 0x4000>, <0x4030000 0x4000>; + interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>; + cell-index = <3>; + }; + + qportal4: qman-portal@40000 { + compatible = "fsl,qman-portal"; + reg = <0x40000 0x4000>, <0x4040000 0x4000>; + interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; + cell-index = <4>; + }; + + qportal5: qman-portal@50000 { + compatible = "fsl,qman-portal"; + reg = <0x50000 0x4000>, <0x4050000 0x4000>; + interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; + cell-index = <5>; + }; + + qportal6: qman-portal@60000 { + compatible = "fsl,qman-portal"; + reg = <0x60000 0x4000>, <0x4060000 0x4000>; + interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; + cell-index = <6>; + }; + + qportal7: qman-portal@70000 { + compatible = "fsl,qman-portal"; + reg = <0x70000 0x4000>, <0x4070000 0x4000>; + interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>; + cell-index = <7>; + }; + + qportal8: qman-portal@80000 { + compatible = "fsl,qman-portal"; + reg = <0x80000 0x4000>, <0x4080000 0x4000>; + interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; + cell-index = <8>; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-8040-db.dts b/arch/arm64/boot/dts/marvell/armada-8040-db.dts index dc0d084005b2..3cde649f96e4 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-db.dts +++ b/arch/arm64/boot/dts/marvell/armada-8040-db.dts @@ -169,6 +169,22 @@ status = "okay"; }; +&cps_mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +&cps_ethernet { + status = "okay"; +}; + +&cps_eth1 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; +}; + &ap_sdhci0 { status = "okay"; bus-width = <4>; diff --git a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts index f7bb0cc03147..100861aa7afd 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts +++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts @@ -95,6 +95,21 @@ status = "okay"; }; +&ap_sdhci0 { + bus-width = <8>; + /* + * Not stable in HS modes - phy needs "more calibration", so add + * the "slow-mode" and disable SDR104, SDR50 and DDR50 modes. + */ + marvell,xenon-phy-slow-mode; + no-1-8-v; + no-sd; + no-sdio; + non-removable; + status = "okay"; + vqmmc-supply = <&v_vddo_h>; +}; + &cpm_i2c0 { clock-frequency = <100000>; status = "okay"; @@ -105,6 +120,14 @@ status = "okay"; }; +&cpm_sdhci0 { + /* U6 */ + broken-cd; + bus-width = <4>; + status = "okay"; + vqmmc-supply = <&v_3_3>; +}; + &cpm_usb3_0 { /* J38? - USB2.0 only */ status = "okay"; diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi index fe41bf9c301e..9b9e36a627d8 100644 --- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi @@ -159,6 +159,7 @@ reg = <0x400000 0x1000>, <0x410000 0x1000>; msi-parent = <&gic_v2m0>; + clocks = <&ap_syscon 3>; dma-coherent; }; @@ -167,6 +168,7 @@ reg = <0x420000 0x1000>, <0x430000 0x1000>; msi-parent = <&gic_v2m0>; + clocks = <&ap_syscon 3>; dma-coherent; }; @@ -175,6 +177,7 @@ reg = <0x440000 0x1000>, <0x450000 0x1000>; msi-parent = <&gic_v2m0>; + clocks = <&ap_syscon 3>; dma-coherent; }; @@ -183,6 +186,7 @@ reg = <0x460000 0x1000>, <0x470000 0x1000>; msi-parent = <&gic_v2m0>; + clocks = <&ap_syscon 3>; dma-coherent; }; diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi index ac8df5201cd6..b4bc42ece754 100644 --- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi @@ -231,8 +231,7 @@ cpm_crypto: crypto@800000 { compatible = "inside-secure,safexcel-eip197"; reg = <0x800000 0x200000>; - interrupts = <GIC_SPI 34 (IRQ_TYPE_EDGE_RISING - | IRQ_TYPE_LEVEL_HIGH)>, + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi index 7740a75a8230..6e2058847ddc 100644 --- a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi @@ -221,8 +221,7 @@ cps_crypto: crypto@800000 { compatible = "inside-secure,safexcel-eip197"; reg = <0x800000 0x200000>; - interrupts = <GIC_SPI 34 (IRQ_TYPE_EDGE_RISING - | IRQ_TYPE_LEVEL_HIGH)>, + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index a17f5b9a5de6..f611647e9880 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -215,22 +215,16 @@ usb@78d9000 { extcon = <&usb_id>, <&usb_id>; status = "okay"; - }; - - ehci@78d9000 { - status = "okay"; - }; - - phy@78d9000 { - v1p8-supply = <&pm8916_l7>; - v3p3-supply = <&pm8916_l13>; - vddcx-supply = <&pm8916_s1>; - extcon = <&usb_id>, <&usb_id>; - dr_mode = "otg"; - status = "okay"; - switch-gpio = <&pm8916_gpios 4 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&usb_sw_sel_pm>; + adp-disable; + hnp-disable; + srp-disable; + ulpi { + phy { + v1p8-supply = <&pm8916_l7>; + v3p3-supply = <&pm8916_l13>; + extcon = <&usb_id>; + }; + }; }; lpass@07708000 { @@ -348,6 +342,14 @@ pinctrl-0 = <&usb_id_default>; }; + usb-switch { + compatible = "toshiba,tc7usb40mu"; + switch-gpios = <&pm8916_gpios 4 GPIO_ACTIVE_HIGH>; + extcon = <&usb_id>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_sw_sel_pm>; + }; + hdmi-out { compatible = "hdmi-connector"; type = "a"; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index ab3093995ded..c963ef2ec5f5 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -546,44 +546,40 @@ status = "disabled"; }; - usb_dev: usb@78d9000 { + otg: usb@78d9000 { compatible = "qcom,ci-hdrc"; - reg = <0x78d9000 0x400>; - dr_mode = "peripheral"; - interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; - usb-phy = <&usb_otg>; - status = "disabled"; - }; - - usb_host: ehci@78d9000 { - compatible = "qcom,ehci-host"; - reg = <0x78d9000 0x400>; - interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; - usb-phy = <&usb_otg>; - status = "disabled"; - }; - - usb_otg: phy@78d9000 { - compatible = "qcom,usb-otg-snps"; - reg = <0x78d9000 0x400>; + reg = <0x78d9000 0x200>, + <0x78d9200 0x200>; interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; - - qcom,vdd-levels = <500000 1000000 1320000>; - qcom,phy-init-sequence = <0x44 0x6B 0x24 0x13>; - dr_mode = "peripheral"; - qcom,otg-control = <2>; // PMIC - qcom,manual-pullup; - clocks = <&gcc GCC_USB_HS_AHB_CLK>, - <&gcc GCC_USB_HS_SYSTEM_CLK>, - <&gcc GCC_USB2A_PHY_SLEEP_CLK>; - clock-names = "iface", "core", "sleep"; - - resets = <&gcc GCC_USB2A_PHY_BCR>, - <&gcc GCC_USB_HS_BCR>; - reset-names = "phy", "link"; + <&gcc GCC_USB_HS_SYSTEM_CLK>; + clock-names = "iface", "core"; + assigned-clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>; + assigned-clock-rates = <80000000>; + resets = <&gcc GCC_USB_HS_BCR>; + reset-names = "core"; + phy_type = "ulpi"; + dr_mode = "otg"; + ahb-burst-config = <0>; + phy-names = "usb-phy"; + phys = <&usb_hs_phy>; status = "disabled"; + #reset-cells = <1>; + + ulpi { + usb_hs_phy: phy { + compatible = "qcom,usb-hs-phy-msm8916", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; + clock-names = "ref", "sleep"; + resets = <&gcc GCC_USB2A_PHY_BCR>, <&otg 0>; + reset-names = "phy", "por"; + qcom,init-seq = /bits/ 8 <0x0 0x44 + 0x1 0x6b 0x2 0x24 0x3 0x13>; + }; + }; }; intc: interrupt-controller@b000000 { diff --git a/arch/arm64/boot/dts/realtek/Makefile b/arch/arm64/boot/dts/realtek/Makefile new file mode 100644 index 000000000000..8521e921e59a --- /dev/null +++ b/arch/arm64/boot/dts/realtek/Makefile @@ -0,0 +1,5 @@ +dtb-$(CONFIG_ARCH_REALTEK) += rtd1295-zidoo-x9s.dtb + +always := $(dtb-y) +subdir-y := $(dts-dirs) +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/realtek/rtd1295-zidoo-x9s.dts b/arch/arm64/boot/dts/realtek/rtd1295-zidoo-x9s.dts new file mode 100644 index 000000000000..6efa8091bb30 --- /dev/null +++ b/arch/arm64/boot/dts/realtek/rtd1295-zidoo-x9s.dts @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016-2017 Andreas Färber + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/dts-v1/; + +/memreserve/ 0x0000000000000000 0x0000000000030000; +/memreserve/ 0x000000000001f000 0x0000000000001000; +/memreserve/ 0x0000000000030000 0x00000000000d0000; +/memreserve/ 0x0000000001b00000 0x00000000004be000; +/memreserve/ 0x0000000001ffe000 0x0000000000004000; + +#include "rtd1295.dtsi" + +/ { + compatible = "zidoo,x9s", "realtek,rtd1295"; + model = "Zidoo X9S"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x80000000>; + }; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/realtek/rtd1295.dtsi b/arch/arm64/boot/dts/realtek/rtd1295.dtsi new file mode 100644 index 000000000000..d8f84666c8ce --- /dev/null +++ b/arch/arm64/boot/dts/realtek/rtd1295.dtsi @@ -0,0 +1,131 @@ +/* + * Realtek RTD1295 SoC + * + * Copyright (c) 2016-2017 Andreas Färber + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/ { + compatible = "realtek,rtd1295"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x0>; + next-level-cache = <&l2>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x1>; + next-level-cache = <&l2>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x2>; + next-level-cache = <&l2>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x3>; + next-level-cache = <&l2>; + }; + + l2: l2-cache { + compatible = "cache"; + }; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + tee@10100000 { + reg = <0x10100000 0xf00000>; + no-map; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 + (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 + (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 + (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 + (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + /* Exclude up to 2 GiB of RAM */ + ranges = <0x80000000 0x80000000 0x80000000>; + + uart0: serial@98007800 { + compatible = "snps,dw-apb-uart"; + reg = <0x98007800 0x400>, + <0x98007000 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + clock-frequency = <27000000>; + status = "disabled"; + }; + + uart1: serial@9801b200 { + compatible = "snps,dw-apb-uart"; + reg = <0x9801b200 0x100>, + <0x9801b00c 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + clock-frequency = <432000000>; + status = "disabled"; + }; + + uart2: serial@9801b400 { + compatible = "snps,dw-apb-uart"; + reg = <0x9801b400 0x100>, + <0x9801b00c 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + clock-frequency = <432000000>; + status = "disabled"; + }; + + gic: interrupt-controller@ff011000 { + compatible = "arm,gic-400"; + reg = <0xff011000 0x1000>, + <0xff012000 0x2000>, + <0xff014000 0x2000>, + <0xff016000 0x2000>; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupt-controller; + #interrupt-cells = <3>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile index 1618e0a3c81d..b6c723d8f687 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x.dtb r8a7795-h3ulcb.dtb +dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-salvator-x.dtb dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb always := $(dtb-y) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts new file mode 100644 index 000000000000..b84c156ed696 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts @@ -0,0 +1,115 @@ +/* + * Device Tree Source for the Salvator-X board + * + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 + +/dts-v1/; +#include "r8a7795-es1.dtsi" +#include "salvator-x.dtsi" + +/ { + model = "Renesas Salvator-X board based on r8a7795 ES1.x"; + compatible = "renesas,salvator-x", "renesas,r8a7795"; + + memory@48000000 { + device_type = "memory"; + /* first 128MB is reserved for secure area. */ + reg = <0x0 0x48000000 0x0 0x38000000>; + }; + + memory@500000000 { + device_type = "memory"; + reg = <0x5 0x00000000 0x0 0x40000000>; + }; + + memory@600000000 { + device_type = "memory"; + reg = <0x6 0x00000000 0x0 0x40000000>; + }; + + memory@700000000 { + device_type = "memory"; + reg = <0x7 0x00000000 0x0 0x40000000>; + }; +}; + +&du { + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 721>, + <&cpg CPG_MOD 727>, + <&versaclock5 1>, + <&x21_clk>, + <&x22_clk>, + <&versaclock5 2>; + clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0", + "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3"; +}; + +&ehci2 { + status = "okay"; +}; + +&hdmi0 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + rcar_dw_hdmi0_out: endpoint { + remote-endpoint = <&hdmi0_con>; + }; + }; + }; +}; + +&hdmi0_con { + remote-endpoint = <&rcar_dw_hdmi0_out>; +}; + +&hdmi1 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + rcar_dw_hdmi1_out: endpoint { + remote-endpoint = <&hdmi1_con>; + }; + }; + }; +}; + +&hdmi1_con { + remote-endpoint = <&rcar_dw_hdmi1_out>; +}; + +&ohci2 { + status = "okay"; +}; + +&pfc { + usb2_pins: usb2 { + groups = "usb2"; + function = "usb2"; + }; +}; + +&sata { + status = "okay"; +}; + +&usb2_phy2 { + pinctrl-0 = <&usb2_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi new file mode 100644 index 000000000000..a0ba7bd21ea3 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -0,0 +1,84 @@ +/* + * Device Tree Source for the r8a7795 ES1.x SoC + * + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include "r8a7795.dtsi" + +&soc { + xhci1: usb@ee0400000 { + compatible = "renesas,xhci-r8a7795", "renesas,rcar-gen3-xhci"; + reg = <0 0xee040000 0 0xc00>; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 327>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 327>; + status = "disabled"; + }; + + fcpf2: fcp@fe952000 { + compatible = "renesas,fcpf"; + reg = <0 0xfe952000 0 0x200>; + clocks = <&cpg CPG_MOD 613>; + power-domains = <&sysc R8A7795_PD_A3VP>; + resets = <&cpg 613>; + }; + + vspi2: vsp@fe9c0000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe9c0000 0 0x8000>; + interrupts = <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 629>; + power-domains = <&sysc R8A7795_PD_A3VP>; + resets = <&cpg 629>; + + renesas,fcp = <&fcpvi2>; + }; + + fcpvi2: fcp@fe9cf000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe9cf000 0 0x200>; + clocks = <&cpg CPG_MOD 609>; + power-domains = <&sysc R8A7795_PD_A3VP>; + resets = <&cpg 609>; + }; + + vspd3: vsp@fea38000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea38000 0 0x4000>; + interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 620>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 620>; + + renesas,fcp = <&fcpvd3>; + }; + + fcpvd3: fcp@fea3f000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea3f000 0 0x200>; + clocks = <&cpg CPG_MOD 600>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 600>; + }; + + fdp1@fe948000 { + compatible = "renesas,fdp1"; + reg = <0 0xfe948000 0 0x2400>; + interrupts = <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 117>; + power-domains = <&sysc R8A7795_PD_A3VP>; + resets = <&cpg 117>; + renesas,fcp = <&fcpf2>; + }; +}; + +&du { + compatible = "renesas,du-r8a7795"; + vsps = <&vspd0 &vspd1 &vspd2 &vspd3>; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts index ab352159de65..95fe207cb6a3 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts @@ -9,24 +9,16 @@ * kind, whether express or implied. */ +#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 + /dts-v1/; -#include "r8a7795.dtsi" -#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/input/input.h> +#include "r8a7795-es1.dtsi" +#include "ulcb.dtsi" / { - model = "Renesas H3ULCB board based on r8a7795"; + model = "Renesas H3ULCB board based on r8a7795 ES1.x"; compatible = "renesas,h3ulcb", "renesas,r8a7795"; - aliases { - serial0 = &scif2; - ethernet0 = &avb; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - memory@48000000 { device_type = "memory"; /* first 128MB is reserved for secure area. */ @@ -47,330 +39,4 @@ device_type = "memory"; reg = <0x7 0x00000000 0x0 0x40000000>; }; - - leds { - compatible = "gpio-leds"; - - led5 { - gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; - }; - led6 { - gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>; - }; - }; - - keyboard { - compatible = "gpio-keys"; - - key-1 { - linux,code = <KEY_1>; - label = "SW3"; - wakeup-source; - debounce-interval = <20>; - gpios = <&gpio6 11 GPIO_ACTIVE_LOW>; - }; - }; - - x12_clk: x12 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24576000>; - }; - - reg_1p8v: regulator0 { - compatible = "regulator-fixed"; - regulator-name = "fixed-1.8V"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - regulator-always-on; - }; - - reg_3p3v: regulator1 { - compatible = "regulator-fixed"; - regulator-name = "fixed-3.3V"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - vcc_sdhi0: regulator-vcc-sdhi0 { - compatible = "regulator-fixed"; - - regulator-name = "SDHI0 Vcc"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - vccq_sdhi0: regulator-vccq-sdhi0 { - compatible = "regulator-gpio"; - - regulator-name = "SDHI0 VccQ"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; - gpios-states = <1>; - states = <3300000 1 - 1800000 0>; - }; - - audio_clkout: audio-clkout { - /* - * This is same as <&rcar_sound 0> - * but needed to avoid cs2000/rcar_sound probe dead-lock - */ - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <11289600>; - }; - - rsnd_ak4613: sound { - compatible = "simple-audio-card"; - - simple-audio-card,format = "left_j"; - simple-audio-card,bitclock-master = <&sndcpu>; - simple-audio-card,frame-master = <&sndcpu>; - - sndcpu: simple-audio-card,cpu { - sound-dai = <&rcar_sound>; - }; - - sndcodec: simple-audio-card,codec { - sound-dai = <&ak4613>; - }; - }; -}; - -&extal_clk { - clock-frequency = <16666666>; -}; - -&extalr_clk { - clock-frequency = <32768>; -}; - -&pfc { - pinctrl-0 = <&scif_clk_pins>; - pinctrl-names = "default"; - - scif2_pins: scif2 { - groups = "scif2_data_a"; - function = "scif2"; - }; - - scif_clk_pins: scif_clk { - groups = "scif_clk_a"; - function = "scif_clk"; - }; - - i2c2_pins: i2c2 { - groups = "i2c2_a"; - function = "i2c2"; - }; - - avb_pins: avb { - groups = "avb_mdc"; - function = "avb"; - }; - - sdhi0_pins: sd0 { - groups = "sdhi0_data4", "sdhi0_ctrl"; - function = "sdhi0"; - power-source = <3300>; - }; - - sdhi0_pins_uhs: sd0_uhs { - groups = "sdhi0_data4", "sdhi0_ctrl"; - function = "sdhi0"; - power-source = <1800>; - }; - - sdhi2_pins: sd2 { - groups = "sdhi2_data8", "sdhi2_ctrl"; - function = "sdhi2"; - power-source = <3300>; - }; - - sdhi2_pins_uhs: sd2_uhs { - groups = "sdhi2_data8", "sdhi2_ctrl"; - function = "sdhi2"; - power-source = <1800>; - }; - - sound_pins: sound { - groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a"; - function = "ssi"; - }; - - sound_clk_pins: sound-clk { - groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a", - "audio_clkout_a", "audio_clkout3_a"; - function = "audio_clk"; - }; - - usb1_pins: usb1 { - groups = "usb1"; - function = "usb1"; - }; -}; - -&scif2 { - pinctrl-0 = <&scif2_pins>; - pinctrl-names = "default"; - - status = "okay"; -}; - -&scif_clk { - clock-frequency = <14745600>; -}; - -&i2c2 { - pinctrl-0 = <&i2c2_pins>; - pinctrl-names = "default"; - - status = "okay"; - - clock-frequency = <100000>; - - ak4613: codec@10 { - compatible = "asahi-kasei,ak4613"; - #sound-dai-cells = <0>; - reg = <0x10>; - clocks = <&rcar_sound 3>; - - asahi-kasei,in1-single-end; - asahi-kasei,in2-single-end; - asahi-kasei,out1-single-end; - asahi-kasei,out2-single-end; - asahi-kasei,out3-single-end; - asahi-kasei,out4-single-end; - asahi-kasei,out5-single-end; - asahi-kasei,out6-single-end; - }; - - cs2000: clk-multiplier@4f { - #clock-cells = <0>; - compatible = "cirrus,cs2000-cp"; - reg = <0x4f>; - clocks = <&audio_clkout>, <&x12_clk>; - clock-names = "clk_in", "ref_clk"; - - assigned-clocks = <&cs2000>; - assigned-clock-rates = <24576000>; /* 1/1 divide */ - }; -}; - -&rcar_sound { - pinctrl-0 = <&sound_pins &sound_clk_pins>; - pinctrl-names = "default"; - - /* Single DAI */ - #sound-dai-cells = <0>; - - /* audio_clkout0/1/2/3 */ - #clock-cells = <1>; - clock-frequency = <11289600>; - - status = "okay"; - - /* update <audio_clk_b> to <cs2000> */ - clocks = <&cpg CPG_MOD 1005>, - <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>, - <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>, - <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>, - <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>, - <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>, - <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>, - <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>, - <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>, - <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>, - <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>, - <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, - <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, - <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>, - <&audio_clk_a>, <&cs2000>, - <&audio_clk_c>, - <&cpg CPG_CORE R8A7795_CLK_S0D4>; - - rcar_sound,dai { - dai0 { - playback = <&ssi0 &src0 &dvc0>; - capture = <&ssi1 &src1 &dvc1>; - }; - }; -}; - -&sdhi0 { - pinctrl-0 = <&sdhi0_pins>; - pinctrl-1 = <&sdhi0_pins_uhs>; - pinctrl-names = "default", "state_uhs"; - - vmmc-supply = <&vcc_sdhi0>; - vqmmc-supply = <&vccq_sdhi0>; - cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>; - bus-width = <4>; - sd-uhs-sdr50; - status = "okay"; -}; - -&sdhi2 { - /* used for on-board 8bit eMMC */ - pinctrl-0 = <&sdhi2_pins>; - pinctrl-1 = <&sdhi2_pins_uhs>; - pinctrl-names = "default", "state_uhs"; - - vmmc-supply = <®_3p3v>; - vqmmc-supply = <®_1p8v>; - bus-width = <8>; - non-removable; - status = "okay"; -}; - -&ssi1 { - shared-pin; -}; - -&wdt0 { - timeout-sec = <60>; - status = "okay"; -}; - -&audio_clk_a { - clock-frequency = <22579200>; -}; - -&avb { - pinctrl-0 = <&avb_pins>; - pinctrl-names = "default"; - renesas,no-ether-link; - phy-handle = <&phy0>; - status = "okay"; - - phy0: ethernet-phy@0 { - rxc-skew-ps = <1500>; - reg = <0>; - interrupt-parent = <&gpio2>; - interrupts = <11 IRQ_TYPE_LEVEL_LOW>; - }; -}; - -&usb2_phy1 { - pinctrl-0 = <&usb1_pins>; - pinctrl-names = "default"; - - status = "okay"; -}; - -&ehci1 { - status = "okay"; -}; - -&ohci1 { - status = "okay"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts index 639aa085d996..684fb3b9d154 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts @@ -8,577 +8,108 @@ * kind, whether express or implied. */ -/* - * SSI-AK4613 - * - * This command is required when Playback/Capture - * - * amixer set "DVC Out" 100% - * amixer set "DVC In" 100% - * - * You can use Mute - * - * amixer set "DVC Out Mute" on - * amixer set "DVC In Mute" on - * - * You can use Volume Ramp - * - * amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps" - * amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps" - * amixer set "DVC Out Ramp" on - * aplay xxx.wav & - * amixer set "DVC Out" 80% // Volume Down - * amixer set "DVC Out" 100% // Volume Up - */ +#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 /dts-v1/; #include "r8a7795.dtsi" -#include <dt-bindings/gpio/gpio.h> +#include "salvator-x.dtsi" / { - model = "Renesas Salvator-X board based on r8a7795"; + model = "Renesas Salvator-X board based on r8a7795 ES2.0+"; compatible = "renesas,salvator-x", "renesas,r8a7795"; - aliases { - serial0 = &scif2; - serial1 = &scif1; - ethernet0 = &avb; - }; - - chosen { - bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp"; - stdout-path = "serial0:115200n8"; - }; - memory@48000000 { device_type = "memory"; /* first 128MB is reserved for secure area. */ reg = <0x0 0x48000000 0x0 0x38000000>; }; - x12_clk: x12 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24576000>; - }; - - reg_1p8v: regulator0 { - compatible = "regulator-fixed"; - regulator-name = "fixed-1.8V"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - regulator-always-on; - }; - - reg_3p3v: regulator1 { - compatible = "regulator-fixed"; - regulator-name = "fixed-3.3V"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - vcc_sdhi0: regulator-vcc-sdhi0 { - compatible = "regulator-fixed"; - - regulator-name = "SDHI0 Vcc"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - vccq_sdhi0: regulator-vccq-sdhi0 { - compatible = "regulator-gpio"; - - regulator-name = "SDHI0 VccQ"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; - gpios-states = <1>; - states = <3300000 1 - 1800000 0>; - }; - - vcc_sdhi3: regulator-vcc-sdhi3 { - compatible = "regulator-fixed"; - - regulator-name = "SDHI3 Vcc"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - vccq_sdhi3: regulator-vccq-sdhi3 { - compatible = "regulator-gpio"; - - regulator-name = "SDHI3 VccQ"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>; - gpios-states = <1>; - states = <3300000 1 - 1800000 0>; + memory@500000000 { + device_type = "memory"; + reg = <0x5 0x00000000 0x0 0x40000000>; }; - vbus0_usb2: regulator-vbus0-usb2 { - compatible = "regulator-fixed"; - - regulator-name = "USB20_VBUS0"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - - gpio = <&gpio6 16 GPIO_ACTIVE_HIGH>; - enable-active-high; + memory@600000000 { + device_type = "memory"; + reg = <0x6 0x00000000 0x0 0x40000000>; }; - audio_clkout: audio_clkout { - /* - * This is same as <&rcar_sound 0> - * but needed to avoid cs2000/rcar_sound probe dead-lock - */ - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <11289600>; + memory@700000000 { + device_type = "memory"; + reg = <0x7 0x00000000 0x0 0x40000000>; }; +}; - rsnd_ak4613: sound { - compatible = "simple-audio-card"; - - simple-audio-card,format = "left_j"; - simple-audio-card,bitclock-master = <&sndcpu>; - simple-audio-card,frame-master = <&sndcpu>; - - sndcpu: simple-audio-card,cpu { - sound-dai = <&rcar_sound>; - }; - - sndcodec: simple-audio-card,codec { - sound-dai = <&ak4613>; - }; - }; +&du { + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 721>, + <&cpg CPG_MOD 727>, + <&versaclock5 1>, + <&x21_clk>, + <&x22_clk>, + <&versaclock5 2>; + clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0", + "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3"; +}; - vga-encoder { - compatible = "adi,adv7123"; +&ehci2 { + status = "okay"; +}; - ports { - #address-cells = <1>; - #size-cells = <0>; +&hdmi0 { + status = "okay"; - port@0 { - reg = <0>; - adv7123_in: endpoint { - remote-endpoint = <&du_out_rgb>; - }; - }; - port@1 { - reg = <1>; - adv7123_out: endpoint { - remote-endpoint = <&vga_in>; - }; + ports { + port@1 { + reg = <1>; + rcar_dw_hdmi0_out: endpoint { + remote-endpoint = <&hdmi0_con>; }; }; }; +}; - vga { - compatible = "vga-connector"; - - port { - vga_in: endpoint { - remote-endpoint = <&adv7123_out>; - }; - }; - }; +&hdmi0_con { + remote-endpoint = <&rcar_dw_hdmi0_out>; }; -&du { - pinctrl-0 = <&du_pins>; - pinctrl-names = "default"; +&hdmi1 { status = "okay"; ports { - port@0 { - endpoint { - remote-endpoint = <&adv7123_in>; - }; - }; - port@3 { - lvds_connector: endpoint { + port@1 { + reg = <1>; + rcar_dw_hdmi1_out: endpoint { + remote-endpoint = <&hdmi1_con>; }; }; }; }; -&extal_clk { - clock-frequency = <16666666>; +&hdmi1_con { + remote-endpoint = <&rcar_dw_hdmi1_out>; }; -&extalr_clk { - clock-frequency = <32768>; +&ohci2 { + status = "okay"; }; &pfc { - pinctrl-0 = <&scif_clk_pins>; - pinctrl-names = "default"; - - scif1_pins: scif1 { - groups = "scif1_data_a", "scif1_ctrl"; - function = "scif1"; - }; - scif2_pins: scif2 { - groups = "scif2_data_a"; - function = "scif2"; - }; - scif_clk_pins: scif_clk { - groups = "scif_clk_a"; - function = "scif_clk"; - }; - - i2c2_pins: i2c2 { - groups = "i2c2_a"; - function = "i2c2"; - }; - - avb_pins: avb { - mux { - groups = "avb_link", "avb_phy_int", "avb_mdc", - "avb_mii"; - function = "avb"; - }; - - pins_mdc { - groups = "avb_mdc"; - drive-strength = <24>; - }; - - pins_mii_tx { - pins = "PIN_AVB_TX_CTL", "PIN_AVB_TXC", "PIN_AVB_TD0", - "PIN_AVB_TD1", "PIN_AVB_TD2", "PIN_AVB_TD3"; - drive-strength = <12>; - }; - }; - - du_pins: du { - groups = "du_rgb888", "du_sync", "du_oddf", "du_clk_out_0"; - function = "du"; - }; - - sdhi0_pins: sd0 { - groups = "sdhi0_data4", "sdhi0_ctrl"; - function = "sdhi0"; - power-source = <3300>; - }; - - sdhi0_pins_uhs: sd0_uhs { - groups = "sdhi0_data4", "sdhi0_ctrl"; - function = "sdhi0"; - power-source = <1800>; - }; - - sdhi2_pins: sd2 { - groups = "sdhi2_data8", "sdhi2_ctrl"; - function = "sdhi2"; - power-source = <3300>; - }; - - sdhi2_pins_uhs: sd2_uhs { - groups = "sdhi2_data8", "sdhi2_ctrl"; - function = "sdhi2"; - power-source = <1800>; - }; - - sdhi3_pins: sd3 { - groups = "sdhi3_data4", "sdhi3_ctrl"; - function = "sdhi3"; - power-source = <3300>; - }; - - sdhi3_pins_uhs: sd3_uhs { - groups = "sdhi3_data4", "sdhi3_ctrl"; - function = "sdhi3"; - power-source = <1800>; - }; - - sound_pins: sound { - groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a"; - function = "ssi"; - }; - - sound_clk_pins: sound_clk { - groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a", - "audio_clkout_a", "audio_clkout3_a"; - function = "audio_clk"; - }; - - usb0_pins: usb0 { - groups = "usb0"; - function = "usb0"; - }; - - usb1_pins: usb1 { - mux { - groups = "usb1"; - function = "usb1"; - }; - - ovc { - pins = "GP_6_27"; - bias-pull-up; - }; - - pwen { - pins = "GP_6_26"; - bias-pull-down; - }; - }; - usb2_pins: usb2 { groups = "usb2"; function = "usb2"; }; }; -&scif1 { - pinctrl-0 = <&scif1_pins>; - pinctrl-names = "default"; - - uart-has-rtscts; - status = "okay"; -}; - -&scif2 { - pinctrl-0 = <&scif2_pins>; - pinctrl-names = "default"; - - status = "okay"; -}; - -&scif_clk { - clock-frequency = <14745600>; -}; - -&i2c2 { - pinctrl-0 = <&i2c2_pins>; - pinctrl-names = "default"; - - status = "okay"; - - clock-frequency = <100000>; - - ak4613: codec@10 { - compatible = "asahi-kasei,ak4613"; - #sound-dai-cells = <0>; - reg = <0x10>; - clocks = <&rcar_sound 3>; - - asahi-kasei,in1-single-end; - asahi-kasei,in2-single-end; - asahi-kasei,out1-single-end; - asahi-kasei,out2-single-end; - asahi-kasei,out3-single-end; - asahi-kasei,out4-single-end; - asahi-kasei,out5-single-end; - asahi-kasei,out6-single-end; - }; - - cs2000: clk_multiplier@4f { - #clock-cells = <0>; - compatible = "cirrus,cs2000-cp"; - reg = <0x4f>; - clocks = <&audio_clkout>, <&x12_clk>; - clock-names = "clk_in", "ref_clk"; - - assigned-clocks = <&cs2000>; - assigned-clock-rates = <24576000>; /* 1/1 divide */ - }; -}; - -&rcar_sound { - pinctrl-0 = <&sound_pins &sound_clk_pins>; - pinctrl-names = "default"; - - /* Single DAI */ - #sound-dai-cells = <0>; - - /* audio_clkout0/1/2/3 */ - #clock-cells = <1>; - clock-frequency = <11289600>; - - status = "okay"; - - /* update <audio_clk_b> to <cs2000> */ - clocks = <&cpg CPG_MOD 1005>, - <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>, - <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>, - <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>, - <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>, - <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>, - <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>, - <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>, - <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>, - <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>, - <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>, - <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, - <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, - <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>, - <&audio_clk_a>, <&cs2000>, - <&audio_clk_c>, - <&cpg CPG_CORE R8A7795_CLK_S0D4>; - - rcar_sound,dai { - dai0 { - playback = <&ssi0 &src0 &dvc0>; - capture = <&ssi1 &src1 &dvc1>; - }; - }; -}; - &sata { status = "okay"; }; -&sdhi0 { - pinctrl-0 = <&sdhi0_pins>; - pinctrl-1 = <&sdhi0_pins_uhs>; - pinctrl-names = "default", "state_uhs"; - - vmmc-supply = <&vcc_sdhi0>; - vqmmc-supply = <&vccq_sdhi0>; - cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>; - wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>; - bus-width = <4>; - sd-uhs-sdr50; - status = "okay"; -}; - -&sdhi2 { - /* used for on-board 8bit eMMC */ - pinctrl-0 = <&sdhi2_pins>; - pinctrl-1 = <&sdhi2_pins_uhs>; - pinctrl-names = "default", "state_uhs"; - - vmmc-supply = <®_3p3v>; - vqmmc-supply = <®_1p8v>; - bus-width = <8>; - non-removable; - status = "okay"; -}; - -&sdhi3 { - pinctrl-0 = <&sdhi3_pins>; - pinctrl-1 = <&sdhi3_pins_uhs>; - pinctrl-names = "default", "state_uhs"; - - vmmc-supply = <&vcc_sdhi3>; - vqmmc-supply = <&vccq_sdhi3>; - cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; - wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>; - bus-width = <4>; - sd-uhs-sdr50; - status = "okay"; -}; - -&ssi1 { - shared-pin; -}; - -&wdt0 { - timeout-sec = <60>; - status = "okay"; -}; - -&audio_clk_a { - clock-frequency = <22579200>; -}; - -&i2c_dvfs { - status = "okay"; -}; - -&avb { - pinctrl-0 = <&avb_pins>; - pinctrl-names = "default"; - renesas,no-ether-link; - phy-handle = <&phy0>; - status = "okay"; - - phy0: ethernet-phy@0 { - rxc-skew-ps = <1500>; - reg = <0>; - interrupt-parent = <&gpio2>; - interrupts = <11 IRQ_TYPE_LEVEL_LOW>; - }; -}; - -&xhci0 { - status = "okay"; -}; - -&usb2_phy0 { - pinctrl-0 = <&usb0_pins>; - pinctrl-names = "default"; - - vbus-supply = <&vbus0_usb2>; - status = "okay"; -}; - -&usb2_phy1 { - pinctrl-0 = <&usb1_pins>; - pinctrl-names = "default"; - - status = "okay"; -}; - &usb2_phy2 { pinctrl-0 = <&usb2_pins>; pinctrl-names = "default"; status = "okay"; }; - -&ehci0 { - status = "okay"; -}; - -&ehci1 { - status = "okay"; -}; - -&ehci2 { - status = "okay"; -}; - -&ohci0 { - status = "okay"; -}; - -&ohci1 { - status = "okay"; -}; - -&ohci2 { - status = "okay"; -}; - -&hsusb { - status = "okay"; -}; - -&pcie_bus_clk { - clock-frequency = <100000000>; -}; - -&pciec0 { - status = "okay"; -}; - -&pciec1 { - status = "okay"; -}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index e99d6443b3e4..24c607e30009 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -182,7 +182,7 @@ clock-frequency = <0>; }; - soc { + soc: soc { compatible = "simple-bus"; interrupt-parent = <&gic>; @@ -398,7 +398,7 @@ #power-domain-cells = <1>; }; - pfc: pfc@e6060000 { + pfc: pin-controller@e6060000 { compatible = "renesas,pfc-r8a7795"; reg = <0 0xe6060000 0 0x50c>; }; @@ -1274,16 +1274,6 @@ status = "disabled"; }; - xhci1: usb@ee0400000 { - compatible = "renesas,xhci-r8a7795", "renesas,rcar-gen3-xhci"; - reg = <0 0xee040000 0 0xc00>; - interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 327>; - power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; - resets = <&cpg 327>; - status = "disabled"; - }; - usb_dmac0: dma-controller@e65a0000 { compatible = "renesas,r8a7795-usb-dmac", "renesas,usb-dmac"; @@ -1568,14 +1558,6 @@ resets = <&cpg 614>; }; - fcpf2: fcp@fe952000 { - compatible = "renesas,fcpf"; - reg = <0 0xfe952000 0 0x200>; - clocks = <&cpg CPG_MOD 613>; - power-domains = <&sysc R8A7795_PD_A3VP>; - resets = <&cpg 613>; - }; - vspbd: vsp@fe960000 { compatible = "renesas,vsp2"; reg = <0 0xfe960000 0 0x8000>; @@ -1633,25 +1615,6 @@ resets = <&cpg 610>; }; - vspi2: vsp@fe9c0000 { - compatible = "renesas,vsp2"; - reg = <0 0xfe9c0000 0 0x8000>; - interrupts = <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 629>; - power-domains = <&sysc R8A7795_PD_A3VP>; - resets = <&cpg 629>; - - renesas,fcp = <&fcpvi2>; - }; - - fcpvi2: fcp@fe9cf000 { - compatible = "renesas,fcpv"; - reg = <0 0xfe9cf000 0 0x200>; - clocks = <&cpg CPG_MOD 609>; - power-domains = <&sysc R8A7795_PD_A3VP>; - resets = <&cpg 609>; - }; - vspd0: vsp@fea20000 { compatible = "renesas,vsp2"; reg = <0 0xfea20000 0 0x4000>; @@ -1709,25 +1672,6 @@ resets = <&cpg 601>; }; - vspd3: vsp@fea38000 { - compatible = "renesas,vsp2"; - reg = <0 0xfea38000 0 0x4000>; - interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 620>; - power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; - resets = <&cpg 620>; - - renesas,fcp = <&fcpvd3>; - }; - - fcpvd3: fcp@fea3f000 { - compatible = "renesas,fcpv"; - reg = <0 0xfea3f000 0 0x200>; - clocks = <&cpg CPG_MOD 600>; - power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; - resets = <&cpg 600>; - }; - fdp1@fe940000 { compatible = "renesas,fdp1"; reg = <0 0xfe940000 0 0x2400>; @@ -1748,18 +1692,57 @@ renesas,fcp = <&fcpf1>; }; - fdp1@fe948000 { - compatible = "renesas,fdp1"; - reg = <0 0xfe948000 0 0x2400>; - interrupts = <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 117>; - power-domains = <&sysc R8A7795_PD_A3VP>; - resets = <&cpg 117>; - renesas,fcp = <&fcpf2>; + hdmi0: hdmi0@fead0000 { + compatible = "renesas,r8a7795-hdmi", "renesas,rcar-gen3-hdmi"; + reg = <0 0xfead0000 0 0x10000>; + interrupts = <GIC_SPI 389 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 729>, <&cpg CPG_CORE R8A7795_CLK_HDMI>; + clock-names = "iahb", "isfr"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 729>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + dw_hdmi0_in: endpoint { + remote-endpoint = <&du_out_hdmi0>; + }; + }; + port@1 { + reg = <1>; + }; + }; + }; + + hdmi1: hdmi1@feae0000 { + compatible = "renesas,r8a7795-hdmi", "renesas,rcar-gen3-hdmi"; + reg = <0 0xfeae0000 0 0x10000>; + interrupts = <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 728>, <&cpg CPG_CORE R8A7795_CLK_HDMI>; + clock-names = "iahb", "isfr"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 728>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + dw_hdmi1_in: endpoint { + remote-endpoint = <&du_out_hdmi1>; + }; + }; + port@1 { + reg = <1>; + }; + }; }; du: display@feb00000 { - compatible = "renesas,du-r8a7795"; reg = <0 0xfeb00000 0 0x80000>, <0 0xfeb90000 0 0x14>; reg-names = "du", "lvds.0"; @@ -1775,8 +1758,6 @@ clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0"; status = "disabled"; - vsps = <&vspd0 &vspd1 &vspd2 &vspd3>; - ports { #address-cells = <1>; #size-cells = <0>; @@ -1789,11 +1770,13 @@ port@1 { reg = <1>; du_out_hdmi0: endpoint { + remote-endpoint = <&dw_hdmi0_in>; }; }; port@2 { reg = <2>; du_out_hdmi1: endpoint { + remote-endpoint = <&dw_hdmi1_in>; }; }; port@3 { diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts index 372b2a944716..38b58b7fca4b 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts +++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts @@ -9,180 +9,24 @@ * kind, whether express or implied. */ +#define CPG_AUDIO_CLK_I R8A7796_CLK_S0D4 + /dts-v1/; #include "r8a7796.dtsi" -#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/input/input.h> +#include "ulcb.dtsi" / { model = "Renesas M3ULCB board based on r8a7796"; compatible = "renesas,m3ulcb", "renesas,r8a7796"; - aliases { - serial0 = &scif2; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - memory@48000000 { device_type = "memory"; /* first 128MB is reserved for secure area. */ reg = <0x0 0x48000000 0x0 0x38000000>; }; - leds { - compatible = "gpio-leds"; - - led5 { - gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; - }; - led6 { - gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>; - }; - }; - - keyboard { - compatible = "gpio-keys"; - - key-1 { - linux,code = <KEY_1>; - label = "SW3"; - wakeup-source; - debounce-interval = <20>; - gpios = <&gpio6 11 GPIO_ACTIVE_LOW>; - }; - }; - - reg_1p8v: regulator0 { - compatible = "regulator-fixed"; - regulator-name = "fixed-1.8V"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - regulator-always-on; - }; - - reg_3p3v: regulator1 { - compatible = "regulator-fixed"; - regulator-name = "fixed-3.3V"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - vcc_sdhi0: regulator-vcc-sdhi0 { - compatible = "regulator-fixed"; - - regulator-name = "SDHI0 Vcc"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - vccq_sdhi0: regulator-vccq-sdhi0 { - compatible = "regulator-gpio"; - - regulator-name = "SDHI0 VccQ"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; - gpios-states = <1>; - states = <3300000 1 - 1800000 0>; - }; -}; - -&extal_clk { - clock-frequency = <16666666>; -}; - -&extalr_clk { - clock-frequency = <32768>; -}; - -&pfc { - pinctrl-0 = <&scif_clk_pins>; - pinctrl-names = "default"; - - scif2_pins: scif2 { - groups = "scif2_data_a"; - function = "scif2"; - }; - - scif_clk_pins: scif_clk { - groups = "scif_clk_a"; - function = "scif_clk"; - }; - - sdhi0_pins: sd0 { - groups = "sdhi0_data4", "sdhi0_ctrl"; - function = "sdhi0"; - power-source = <3300>; - }; - - sdhi0_pins_uhs: sd0_uhs { - groups = "sdhi0_data4", "sdhi0_ctrl"; - function = "sdhi0"; - power-source = <1800>; - }; - - sdhi2_pins: sd2 { - groups = "sdhi2_data8", "sdhi2_ctrl"; - function = "sdhi2"; - power-source = <3300>; - }; - - sdhi2_pins_uhs: sd2_uhs { - groups = "sdhi2_data8", "sdhi2_ctrl"; - function = "sdhi2"; - power-source = <1800>; + memory@600000000 { + device_type = "memory"; + reg = <0x6 0x00000000 0x0 0x40000000>; }; }; - -&sdhi0 { - pinctrl-0 = <&sdhi0_pins>; - pinctrl-1 = <&sdhi0_pins_uhs>; - pinctrl-names = "default", "state_uhs"; - - vmmc-supply = <&vcc_sdhi0>; - vqmmc-supply = <&vccq_sdhi0>; - cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>; - bus-width = <4>; - sd-uhs-sdr50; - status = "okay"; -}; - -&sdhi2 { - /* used for on-board 8bit eMMC */ - pinctrl-0 = <&sdhi2_pins>; - pinctrl-1 = <&sdhi2_pins_uhs>; - pinctrl-names = "default", "state_uhs"; - - vmmc-supply = <®_3p3v>; - vqmmc-supply = <®_1p8v>; - bus-width = <8>; - non-removable; - status = "okay"; -}; - -&scif2 { - pinctrl-0 = <&scif2_pins>; - pinctrl-names = "default"; - - status = "okay"; -}; - -&scif_clk { - clock-frequency = <14745600>; -}; - -&wdt0 { - timeout-sec = <60>; - status = "okay"; -}; diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts index c9f59b6ce33f..db4f162d6bdd 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts @@ -8,25 +8,16 @@ * kind, whether express or implied. */ +#define CPG_AUDIO_CLK_I R8A7796_CLK_S0D4 + /dts-v1/; #include "r8a7796.dtsi" -#include <dt-bindings/gpio/gpio.h> +#include "salvator-x.dtsi" / { model = "Renesas Salvator-X board based on r8a7796"; compatible = "renesas,salvator-x", "renesas,r8a7796"; - aliases { - serial0 = &scif2; - serial1 = &scif1; - ethernet0 = &avb; - }; - - chosen { - bootargs = "ignore_loglevel"; - stdout-path = "serial0:115200n8"; - }; - memory@48000000 { device_type = "memory"; /* first 128MB is reserved for secure area. */ @@ -37,233 +28,4 @@ device_type = "memory"; reg = <0x6 0x00000000 0x0 0x80000000>; }; - - reg_1p8v: regulator0 { - compatible = "regulator-fixed"; - regulator-name = "fixed-1.8V"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - regulator-always-on; - }; - - reg_3p3v: regulator1 { - compatible = "regulator-fixed"; - regulator-name = "fixed-3.3V"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - vcc_sdhi0: regulator-vcc-sdhi0 { - compatible = "regulator-fixed"; - - regulator-name = "SDHI0 Vcc"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - vccq_sdhi0: regulator-vccq-sdhi0 { - compatible = "regulator-gpio"; - - regulator-name = "SDHI0 VccQ"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; - gpios-states = <1>; - states = <3300000 1 - 1800000 0>; - }; - - vcc_sdhi3: regulator-vcc-sdhi3 { - compatible = "regulator-fixed"; - - regulator-name = "SDHI3 Vcc"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - vccq_sdhi3: regulator-vccq-sdhi3 { - compatible = "regulator-gpio"; - - regulator-name = "SDHI3 VccQ"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>; - gpios-states = <1>; - states = <3300000 1 - 1800000 0>; - }; -}; - -&pfc { - pinctrl-0 = <&scif_clk_pins>; - pinctrl-names = "default"; - - avb_pins: avb { - groups = "avb_mdc"; - function = "avb"; - }; - - scif1_pins: scif1 { - groups = "scif1_data_a", "scif1_ctrl"; - function = "scif1"; - }; - - scif2_pins: scif2 { - groups = "scif2_data_a"; - function = "scif2"; - }; - scif_clk_pins: scif_clk { - groups = "scif_clk_a"; - function = "scif_clk"; - }; - - i2c2_pins: i2c2 { - groups = "i2c2_a"; - function = "i2c2"; - }; - - sdhi0_pins: sd0 { - groups = "sdhi0_data4", "sdhi0_ctrl"; - function = "sdhi0"; - power-source = <3300>; - }; - - sdhi0_pins_uhs: sd0_uhs { - groups = "sdhi0_data4", "sdhi0_ctrl"; - function = "sdhi0"; - power-source = <1800>; - }; - - sdhi2_pins: sd2 { - groups = "sdhi2_data8", "sdhi2_ctrl"; - function = "sdhi2"; - power-source = <3300>; - }; - - sdhi2_pins_uhs: sd2_uhs { - groups = "sdhi2_data8", "sdhi2_ctrl"; - function = "sdhi2"; - power-source = <1800>; - }; - - sdhi3_pins: sd3 { - groups = "sdhi3_data4", "sdhi3_ctrl"; - function = "sdhi3"; - power-source = <3300>; - }; - - sdhi3_pins_uhs: sd3_uhs { - groups = "sdhi3_data4", "sdhi3_ctrl"; - function = "sdhi3"; - power-source = <1800>; - }; -}; - -&avb { - pinctrl-0 = <&avb_pins>; - pinctrl-names = "default"; - renesas,no-ether-link; - phy-handle = <&phy0>; - status = "okay"; - - phy0: ethernet-phy@0 { - rxc-skew-ps = <1500>; - reg = <0>; - interrupt-parent = <&gpio2>; - interrupts = <11 IRQ_TYPE_LEVEL_LOW>; - }; -}; - -&extal_clk { - clock-frequency = <16666666>; -}; - -&extalr_clk { - clock-frequency = <32768>; -}; - -&sdhi0 { - pinctrl-0 = <&sdhi0_pins>; - pinctrl-1 = <&sdhi0_pins_uhs>; - pinctrl-names = "default", "state_uhs"; - - vmmc-supply = <&vcc_sdhi0>; - vqmmc-supply = <&vccq_sdhi0>; - cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>; - wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>; - bus-width = <4>; - sd-uhs-sdr50; - status = "okay"; -}; - -&sdhi2 { - /* used for on-board 8bit eMMC */ - pinctrl-0 = <&sdhi2_pins>; - pinctrl-1 = <&sdhi2_pins_uhs>; - pinctrl-names = "default", "state_uhs"; - - vmmc-supply = <®_3p3v>; - vqmmc-supply = <®_1p8v>; - bus-width = <8>; - non-removable; - status = "okay"; -}; - -&sdhi3 { - pinctrl-0 = <&sdhi3_pins>; - pinctrl-1 = <&sdhi3_pins_uhs>; - pinctrl-names = "default", "state_uhs"; - - vmmc-supply = <&vcc_sdhi3>; - vqmmc-supply = <&vccq_sdhi3>; - cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; - wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>; - bus-width = <4>; - sd-uhs-sdr50; - status = "okay"; -}; - -&scif1 { - pinctrl-0 = <&scif1_pins>; - pinctrl-names = "default"; - - uart-has-rtscts; - status = "okay"; -}; - -&scif2 { - pinctrl-0 = <&scif2_pins>; - pinctrl-names = "default"; - status = "okay"; -}; - -&scif_clk { - clock-frequency = <14745600>; -}; - -&i2c2 { - pinctrl-0 = <&i2c2_pins>; - pinctrl-names = "default"; - - status = "okay"; -}; - -&wdt0 { - timeout-sec = <60>; - status = "okay"; -}; - -&i2c_dvfs { - status = "okay"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index 2ec1ed5f4991..b418a66f4cec 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -120,6 +120,29 @@ clock-frequency = <0>; }; + /* + * The external audio clocks are configured as 0 Hz fixed frequency + * clocks by default. + * Boards that provide audio clocks should override them. + */ + audio_clk_a: audio_clk_a { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + + audio_clk_b: audio_clk_b { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + + audio_clk_c: audio_clk_c { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + /* External CAN clock - to be overridden by boards that provide it */ can_clk: can { compatible = "fixed-clock"; @@ -134,6 +157,13 @@ clock-frequency = <0>; }; + /* External PCIe clock - can be overridden by the board */ + pcie_bus_clk: pcie_bus { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + soc { compatible = "simple-bus"; interrupt-parent = <&gic>; @@ -365,6 +395,76 @@ status = "disabled"; }; + pwm0: pwm@e6e30000 { + compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar"; + reg = <0 0xe6e30000 0 8>; + #pwm-cells = <2>; + clocks = <&cpg CPG_MOD 523>; + resets = <&cpg 523>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + status = "disabled"; + }; + + pwm1: pwm@e6e31000 { + compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar"; + reg = <0 0xe6e31000 0 8>; + #pwm-cells = <2>; + clocks = <&cpg CPG_MOD 523>; + resets = <&cpg 523>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + status = "disabled"; + }; + + pwm2: pwm@e6e32000 { + compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar"; + reg = <0 0xe6e32000 0 8>; + #pwm-cells = <2>; + clocks = <&cpg CPG_MOD 523>; + resets = <&cpg 523>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + status = "disabled"; + }; + + pwm3: pwm@e6e33000 { + compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar"; + reg = <0 0xe6e33000 0 8>; + #pwm-cells = <2>; + clocks = <&cpg CPG_MOD 523>; + resets = <&cpg 523>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + status = "disabled"; + }; + + pwm4: pwm@e6e34000 { + compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar"; + reg = <0 0xe6e34000 0 8>; + #pwm-cells = <2>; + clocks = <&cpg CPG_MOD 523>; + resets = <&cpg 523>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + status = "disabled"; + }; + + pwm5: pwm@e6e35000 { + compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar"; + reg = <0 0xe6e35000 0 8>; + #pwm-cells = <2>; + clocks = <&cpg CPG_MOD 523>; + resets = <&cpg 523>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + status = "disabled"; + }; + + pwm6: pwm@e6e36000 { + compatible = "renesas,pwm-r8a7796", "renesas,pwm-rcar"; + reg = <0 0xe6e36000 0 8>; + #pwm-cells = <2>; + clocks = <&cpg CPG_MOD 523>; + resets = <&cpg 523>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + status = "disabled"; + }; + i2c0: i2c@e6500000 { #address-cells = <1>; #size-cells = <0>; @@ -931,6 +1031,106 @@ dma-channels = <16>; }; + audma0: dma-controller@ec700000 { + compatible = "renesas,dmac-r8a7796", + "renesas,rcar-dmac"; + reg = <0 0xec700000 0 0x10000>; + interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 502>; + clock-names = "fck"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 502>; + #dma-cells = <1>; + dma-channels = <16>; + }; + + audma1: dma-controller@ec720000 { + compatible = "renesas,dmac-r8a7796", + "renesas,rcar-dmac"; + reg = <0 0xec720000 0 0x10000>; + interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 501>; + clock-names = "fck"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 501>; + #dma-cells = <1>; + dma-channels = <16>; + }; + + hsusb: usb@e6590000 { + /* placeholder */ + }; + + xhci0: usb@ee000000 { + /* placeholder */ + }; + + ohci0: usb@ee080000 { + /* placeholder */ + }; + + ehci0: usb@ee080100 { + /* placeholder */ + }; + + usb2_phy0: usb-phy@ee080200 { + /* placeholder */ + }; + + ohci1: usb@ee0a0000 { + /* placeholder */ + }; + + ehci1: usb@ee0a0100 { + /* placeholder */ + }; + + usb2_phy1: usb-phy@ee0a0200 { + /* placeholder */ + }; + sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7796"; reg = <0 0xee100000 0 0x2000>; @@ -1033,5 +1233,214 @@ }; }; }; + + rcar_sound: sound@ec500000 { + /* + * #sound-dai-cells is required + * + * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>; + * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>; + */ + /* + * #clock-cells is required for audio_clkout0/1/2/3 + * + * clkout : #clock-cells = <0>; <&rcar_sound>; + * clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>; + */ + compatible = "renesas,rcar_sound-r8a7796", "renesas,rcar_sound-gen3"; + reg = <0 0xec500000 0 0x1000>, /* SCU */ + <0 0xec5a0000 0 0x100>, /* ADG */ + <0 0xec540000 0 0x1000>, /* SSIU */ + <0 0xec541000 0 0x280>, /* SSI */ + <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/ + reg-names = "scu", "adg", "ssiu", "ssi", "audmapp"; + + clocks = <&cpg CPG_MOD 1005>, + <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>, + <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>, + <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>, + <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>, + <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>, + <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>, + <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>, + <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>, + <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>, + <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>, + <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, + <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, + <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>, + <&audio_clk_a>, <&audio_clk_b>, + <&audio_clk_c>, + <&cpg CPG_CORE R8A7796_CLK_S0D4>; + clock-names = "ssi-all", + "ssi.9", "ssi.8", "ssi.7", "ssi.6", + "ssi.5", "ssi.4", "ssi.3", "ssi.2", + "ssi.1", "ssi.0", + "src.9", "src.8", "src.7", "src.6", + "src.5", "src.4", "src.3", "src.2", + "src.1", "src.0", + "mix.1", "mix.0", + "ctu.1", "ctu.0", + "dvc.0", "dvc.1", + "clk_a", "clk_b", "clk_c", "clk_i"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + status = "disabled"; + + rcar_sound,dvc { + dvc0: dvc-0 { + dmas = <&audma1 0xbc>; + dma-names = "tx"; + }; + dvc1: dvc-1 { + dmas = <&audma1 0xbe>; + dma-names = "tx"; + }; + }; + + rcar_sound,mix { + mix0: mix-0 { }; + mix1: mix-1 { }; + }; + + rcar_sound,ctu { + ctu00: ctu-0 { }; + ctu01: ctu-1 { }; + ctu02: ctu-2 { }; + ctu03: ctu-3 { }; + ctu10: ctu-4 { }; + ctu11: ctu-5 { }; + ctu12: ctu-6 { }; + ctu13: ctu-7 { }; + }; + + rcar_sound,src { + src0: src-0 { + interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x85>, <&audma1 0x9a>; + dma-names = "rx", "tx"; + }; + src1: src-1 { + interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x87>, <&audma1 0x9c>; + dma-names = "rx", "tx"; + }; + src2: src-2 { + interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x89>, <&audma1 0x9e>; + dma-names = "rx", "tx"; + }; + src3: src-3 { + interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8b>, <&audma1 0xa0>; + dma-names = "rx", "tx"; + }; + src4: src-4 { + interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8d>, <&audma1 0xb0>; + dma-names = "rx", "tx"; + }; + src5: src-5 { + interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8f>, <&audma1 0xb2>; + dma-names = "rx", "tx"; + }; + src6: src-6 { + interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x91>, <&audma1 0xb4>; + dma-names = "rx", "tx"; + }; + src7: src-7 { + interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x93>, <&audma1 0xb6>; + dma-names = "rx", "tx"; + }; + src8: src-8 { + interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x95>, <&audma1 0xb8>; + dma-names = "rx", "tx"; + }; + src9: src-9 { + interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x97>, <&audma1 0xba>; + dma-names = "rx", "tx"; + }; + }; + + rcar_sound,ssi { + ssi0: ssi-0 { + interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi1: ssi-1 { + interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi2: ssi-2 { + interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi3: ssi-3 { + interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi4: ssi-4 { + interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi5: ssi-5 { + interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi6: ssi-6 { + interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi7: ssi-7 { + interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi8: ssi-8 { + interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi9: ssi-9 { + interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + }; + }; + + pciec0: pcie@fe000000 { + /* placeholder */ + }; + + pciec1: pcie@ee800000 { + /* placeholder */ + }; + + du: display@feb00000 { + /* placeholder */ + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + du_out_rgb: endpoint { + }; + }; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/renesas/salvator-x.dtsi b/arch/arm64/boot/dts/renesas/salvator-x.dtsi new file mode 100644 index 000000000000..937bdf8842f2 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/salvator-x.dtsi @@ -0,0 +1,644 @@ +/* + * Device Tree Source for the Salvator-X board + * + * Copyright (C) 2015-2016 Renesas Electronics Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/* + * SSI-AK4613 + * + * This command is required when Playback/Capture + * + * amixer set "DVC Out" 100% + * amixer set "DVC In" 100% + * + * You can use Mute + * + * amixer set "DVC Out Mute" on + * amixer set "DVC In Mute" on + * + * You can use Volume Ramp + * + * amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps" + * amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps" + * amixer set "DVC Out Ramp" on + * aplay xxx.wav & + * amixer set "DVC Out" 80% // Volume Down + * amixer set "DVC Out" 100% // Volume Up + */ + +#include <dt-bindings/gpio/gpio.h> + +/ { + model = "Renesas Salvator-X board"; + compatible = "renesas,salvator-x"; + + aliases { + serial0 = &scif2; + serial1 = &scif1; + ethernet0 = &avb; + }; + + chosen { + bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp"; + stdout-path = "serial0:115200n8"; + }; + + audio_clkout: audio_clkout { + /* + * This is same as <&rcar_sound 0> + * but needed to avoid cs2000/rcar_sound probe dead-lock + */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <11289600>; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 50000>; + + brightness-levels = <256 128 64 16 8 4 0>; + default-brightness-level = <6>; + + enable-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>; + }; + + reg_1p8v: regulator0 { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator1 { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + rsnd_ak4613: sound { + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&sndcpu>; + simple-audio-card,frame-master = <&sndcpu>; + + sndcpu: simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + sndcodec: simple-audio-card,codec { + sound-dai = <&ak4613>; + }; + }; + + vbus0_usb2: regulator-vbus0-usb2 { + compatible = "regulator-fixed"; + + regulator-name = "USB20_VBUS0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + gpio = <&gpio6 16 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vcc_sdhi0: regulator-vcc-sdhi0 { + compatible = "regulator-fixed"; + + regulator-name = "SDHI0 Vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vccq_sdhi0: regulator-vccq-sdhi0 { + compatible = "regulator-gpio"; + + regulator-name = "SDHI0 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + gpios-states = <1>; + states = <3300000 1 + 1800000 0>; + }; + + vcc_sdhi3: regulator-vcc-sdhi3 { + compatible = "regulator-fixed"; + + regulator-name = "SDHI3 Vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vccq_sdhi3: regulator-vccq-sdhi3 { + compatible = "regulator-gpio"; + + regulator-name = "SDHI3 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>; + gpios-states = <1>; + states = <3300000 1 + 1800000 0>; + }; + + hdmi0-out { + compatible = "hdmi-connector"; + label = "HDMI0 OUT"; + type = "a"; + + port { + hdmi0_con: endpoint { + }; + }; + }; + + hdmi1-out { + compatible = "hdmi-connector"; + label = "HDMI1 OUT"; + type = "a"; + + port { + hdmi1_con: endpoint { + }; + }; + }; + + vga { + compatible = "vga-connector"; + + port { + vga_in: endpoint { + remote-endpoint = <&adv7123_out>; + }; + }; + }; + + vga-encoder { + compatible = "adi,adv7123"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7123_in: endpoint { + remote-endpoint = <&du_out_rgb>; + }; + }; + port@1 { + reg = <1>; + adv7123_out: endpoint { + remote-endpoint = <&vga_in>; + }; + }; + }; + }; + + x12_clk: x12 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; + + /* External DU dot clocks */ + x21_clk: x21-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <33000000>; + }; + + x22_clk: x22-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <33000000>; + }; + + x23_clk: x23-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; +}; + +&audio_clk_a { + clock-frequency = <22579200>; +}; + +&avb { + pinctrl-0 = <&avb_pins>; + pinctrl-names = "default"; + renesas,no-ether-link; + phy-handle = <&phy0>; + status = "okay"; + + phy0: ethernet-phy@0 { + rxc-skew-ps = <1500>; + reg = <0>; + interrupt-parent = <&gpio2>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&du { + pinctrl-0 = <&du_pins>; + pinctrl-names = "default"; + status = "okay"; + + ports { + port@0 { + endpoint { + remote-endpoint = <&adv7123_in>; + }; + }; + port@3 { + lvds_connector: endpoint { + }; + }; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&extal_clk { + clock-frequency = <16666666>; +}; + +&extalr_clk { + clock-frequency = <32768>; +}; + +&hsusb { + status = "okay"; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "default"; + + status = "okay"; + + clock-frequency = <100000>; + + ak4613: codec@10 { + compatible = "asahi-kasei,ak4613"; + #sound-dai-cells = <0>; + reg = <0x10>; + clocks = <&rcar_sound 3>; + + asahi-kasei,in1-single-end; + asahi-kasei,in2-single-end; + asahi-kasei,out1-single-end; + asahi-kasei,out2-single-end; + asahi-kasei,out3-single-end; + asahi-kasei,out4-single-end; + asahi-kasei,out5-single-end; + asahi-kasei,out6-single-end; + }; + + cs2000: clk_multiplier@4f { + #clock-cells = <0>; + compatible = "cirrus,cs2000-cp"; + reg = <0x4f>; + clocks = <&audio_clkout>, <&x12_clk>; + clock-names = "clk_in", "ref_clk"; + + assigned-clocks = <&cs2000>; + assigned-clock-rates = <24576000>; /* 1/1 divide */ + }; +}; + +&i2c4 { + status = "okay"; + + versaclock5: clock-generator@6a { + compatible = "idt,5p49v5923"; + reg = <0x6a>; + #clock-cells = <1>; + clocks = <&x23_clk>; + clock-names = "xin"; + }; + + csa_vdd: adc@7c { + compatible = "maxim,max9611"; + reg = <0x7c>; + + shunt-resistor-micro-ohms = <5000>; + }; + + csa_dvfs: adc@7f { + compatible = "maxim,max9611"; + reg = <0x7f>; + + shunt-resistor-micro-ohms = <5000>; + }; +}; + +&i2c_dvfs { + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&pcie_bus_clk { + clock-frequency = <100000000>; +}; + +&pciec0 { + status = "okay"; +}; + +&pciec1 { + status = "okay"; +}; + +&pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + + avb_pins: avb { + mux { + groups = "avb_link", "avb_phy_int", "avb_mdc", + "avb_mii"; + function = "avb"; + }; + + pins_mdc { + groups = "avb_mdc"; + drive-strength = <24>; + }; + + pins_mii_tx { + pins = "PIN_AVB_TX_CTL", "PIN_AVB_TXC", "PIN_AVB_TD0", + "PIN_AVB_TD1", "PIN_AVB_TD2", "PIN_AVB_TD3"; + drive-strength = <12>; + }; + }; + + du_pins: du { + groups = "du_rgb888", "du_sync", "du_oddf", "du_clk_out_0"; + function = "du"; + }; + + i2c2_pins: i2c2 { + groups = "i2c2_a"; + function = "i2c2"; + }; + + pwm1_pins: pwm { + groups = "pwm1_a"; + function = "pwm1"; + }; + + scif1_pins: scif1 { + groups = "scif1_data_a", "scif1_ctrl"; + function = "scif1"; + }; + + scif2_pins: scif2 { + groups = "scif2_data_a"; + function = "scif2"; + }; + + scif_clk_pins: scif_clk { + groups = "scif_clk_a"; + function = "scif_clk"; + }; + + sdhi0_pins: sd0 { + groups = "sdhi0_data4", "sdhi0_ctrl"; + function = "sdhi0"; + power-source = <3300>; + }; + + sdhi0_pins_uhs: sd0_uhs { + groups = "sdhi0_data4", "sdhi0_ctrl"; + function = "sdhi0"; + power-source = <1800>; + }; + + sdhi2_pins: sd2 { + groups = "sdhi2_data8", "sdhi2_ctrl"; + function = "sdhi2"; + power-source = <3300>; + }; + + sdhi2_pins_uhs: sd2_uhs { + groups = "sdhi2_data8", "sdhi2_ctrl"; + function = "sdhi2"; + power-source = <1800>; + }; + + sdhi3_pins: sd3 { + groups = "sdhi3_data4", "sdhi3_ctrl"; + function = "sdhi3"; + power-source = <3300>; + }; + + sdhi3_pins_uhs: sd3_uhs { + groups = "sdhi3_data4", "sdhi3_ctrl"; + function = "sdhi3"; + power-source = <1800>; + }; + + sound_pins: sound { + groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a"; + function = "ssi"; + }; + + sound_clk_pins: sound_clk { + groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a", + "audio_clkout_a", "audio_clkout3_a"; + function = "audio_clk"; + }; + + usb0_pins: usb0 { + groups = "usb0"; + function = "usb0"; + }; + + usb1_pins: usb1 { + mux { + groups = "usb1"; + function = "usb1"; + }; + + ovc { + pins = "GP_6_27"; + bias-pull-up; + }; + + pwen { + pins = "GP_6_26"; + bias-pull-down; + }; + }; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&rcar_sound { + pinctrl-0 = <&sound_pins &sound_clk_pins>; + pinctrl-names = "default"; + + /* Single DAI */ + #sound-dai-cells = <0>; + + /* audio_clkout0/1/2/3 */ + #clock-cells = <1>; + clock-frequency = <11289600 12288000>; + + status = "okay"; + + /* update <audio_clk_b> to <cs2000> */ + clocks = <&cpg CPG_MOD 1005>, + <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>, + <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>, + <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>, + <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>, + <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>, + <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>, + <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>, + <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>, + <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>, + <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>, + <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, + <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, + <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>, + <&audio_clk_a>, <&cs2000>, + <&audio_clk_c>, + <&cpg CPG_CORE CPG_AUDIO_CLK_I>; + + rcar_sound,dai { + dai0 { + playback = <&ssi0 &src0 &dvc0>; + capture = <&ssi1 &src1 &dvc1>; + }; + }; +}; + +&scif1 { + pinctrl-0 = <&scif1_pins>; + pinctrl-names = "default"; + + uart-has-rtscts; + status = "okay"; +}; + +&scif2 { + pinctrl-0 = <&scif2_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&scif_clk { + clock-frequency = <14745600>; +}; + +&sdhi0 { + pinctrl-0 = <&sdhi0_pins>; + pinctrl-1 = <&sdhi0_pins_uhs>; + pinctrl-names = "default", "state_uhs"; + + vmmc-supply = <&vcc_sdhi0>; + vqmmc-supply = <&vccq_sdhi0>; + cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>; + bus-width = <4>; + sd-uhs-sdr50; + status = "okay"; +}; + +&sdhi2 { + /* used for on-board 8bit eMMC */ + pinctrl-0 = <&sdhi2_pins>; + pinctrl-1 = <&sdhi2_pins_uhs>; + pinctrl-names = "default", "state_uhs"; + + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_1p8v>; + bus-width = <8>; + mmc-hs200-1_8v; + non-removable; + status = "okay"; +}; + +&sdhi3 { + pinctrl-0 = <&sdhi3_pins>; + pinctrl-1 = <&sdhi3_pins_uhs>; + pinctrl-names = "default", "state_uhs"; + + vmmc-supply = <&vcc_sdhi3>; + vqmmc-supply = <&vccq_sdhi3>; + cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>; + bus-width = <4>; + sd-uhs-sdr50; + status = "okay"; +}; + +&ssi1 { + shared-pin; +}; + +&usb2_phy0 { + pinctrl-0 = <&usb0_pins>; + pinctrl-names = "default"; + + vbus-supply = <&vbus0_usb2>; + status = "okay"; +}; + +&usb2_phy1 { + pinctrl-0 = <&usb1_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&wdt0 { + timeout-sec = <60>; + status = "okay"; +}; + +&xhci0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi new file mode 100644 index 000000000000..b5c6ee07d7f9 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi @@ -0,0 +1,367 @@ +/* + * Device Tree Source for the R-Car Gen3 ULCB board + * + * Copyright (C) 2016 Renesas Electronics Corp. + * Copyright (C) 2016 Cogent Embedded, Inc. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> + +/ { + model = "Renesas R-Car Gen3 ULCB board"; + + aliases { + serial0 = &scif2; + ethernet0 = &avb; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + audio_clkout: audio-clkout { + /* + * This is same as <&rcar_sound 0> + * but needed to avoid cs2000/rcar_sound probe dead-lock + */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <11289600>; + }; + + keyboard { + compatible = "gpio-keys"; + + key-1 { + linux,code = <KEY_1>; + label = "SW3"; + wakeup-source; + debounce-interval = <20>; + gpios = <&gpio6 11 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led5 { + gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; + }; + led6 { + gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>; + }; + }; + + reg_1p8v: regulator0 { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator1 { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + rsnd_ak4613: sound { + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&sndcpu>; + simple-audio-card,frame-master = <&sndcpu>; + + sndcpu: simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + sndcodec: simple-audio-card,codec { + sound-dai = <&ak4613>; + }; + }; + + vcc_sdhi0: regulator-vcc-sdhi0 { + compatible = "regulator-fixed"; + + regulator-name = "SDHI0 Vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vccq_sdhi0: regulator-vccq-sdhi0 { + compatible = "regulator-gpio"; + + regulator-name = "SDHI0 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + gpios-states = <1>; + states = <3300000 1 + 1800000 0>; + }; + + x12_clk: x12 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; +}; + +&audio_clk_a { + clock-frequency = <22579200>; +}; + +&avb { + pinctrl-0 = <&avb_pins>; + pinctrl-names = "default"; + renesas,no-ether-link; + phy-handle = <&phy0>; + status = "okay"; + + phy0: ethernet-phy@0 { + rxc-skew-ps = <1500>; + reg = <0>; + interrupt-parent = <&gpio2>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&ehci1 { + status = "okay"; +}; + +&extal_clk { + clock-frequency = <16666666>; +}; + +&extalr_clk { + clock-frequency = <32768>; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "default"; + + status = "okay"; + + clock-frequency = <100000>; + + ak4613: codec@10 { + compatible = "asahi-kasei,ak4613"; + #sound-dai-cells = <0>; + reg = <0x10>; + clocks = <&rcar_sound 3>; + + asahi-kasei,in1-single-end; + asahi-kasei,in2-single-end; + asahi-kasei,out1-single-end; + asahi-kasei,out2-single-end; + asahi-kasei,out3-single-end; + asahi-kasei,out4-single-end; + asahi-kasei,out5-single-end; + asahi-kasei,out6-single-end; + }; + + cs2000: clk-multiplier@4f { + #clock-cells = <0>; + compatible = "cirrus,cs2000-cp"; + reg = <0x4f>; + clocks = <&audio_clkout>, <&x12_clk>; + clock-names = "clk_in", "ref_clk"; + + assigned-clocks = <&cs2000>; + assigned-clock-rates = <24576000>; /* 1/1 divide */ + }; +}; + +&ohci1 { + status = "okay"; +}; + +&pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + + avb_pins: avb { + mux { + groups = "avb_link", "avb_phy_int", "avb_mdc", + "avb_mii"; + function = "avb"; + }; + + pins_mdc { + groups = "avb_mdc"; + drive-strength = <24>; + }; + + pins_mii_tx { + pins = "PIN_AVB_TX_CTL", "PIN_AVB_TXC", "PIN_AVB_TD0", + "PIN_AVB_TD1", "PIN_AVB_TD2", "PIN_AVB_TD3"; + drive-strength = <12>; + }; + }; + + i2c2_pins: i2c2 { + groups = "i2c2_a"; + function = "i2c2"; + }; + + scif2_pins: scif2 { + groups = "scif2_data_a"; + function = "scif2"; + }; + + scif_clk_pins: scif_clk { + groups = "scif_clk_a"; + function = "scif_clk"; + }; + + sdhi0_pins: sd0 { + groups = "sdhi0_data4", "sdhi0_ctrl"; + function = "sdhi0"; + power-source = <3300>; + }; + + sdhi0_pins_uhs: sd0_uhs { + groups = "sdhi0_data4", "sdhi0_ctrl"; + function = "sdhi0"; + power-source = <1800>; + }; + + sdhi2_pins: sd2 { + groups = "sdhi2_data8", "sdhi2_ctrl"; + function = "sdhi2"; + power-source = <3300>; + }; + + sdhi2_pins_uhs: sd2_uhs { + groups = "sdhi2_data8", "sdhi2_ctrl"; + function = "sdhi2"; + power-source = <1800>; + }; + + sound_pins: sound { + groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a"; + function = "ssi"; + }; + + sound_clk_pins: sound-clk { + groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a", + "audio_clkout_a", "audio_clkout3_a"; + function = "audio_clk"; + }; + + usb1_pins: usb1 { + groups = "usb1"; + function = "usb1"; + }; +}; + +&rcar_sound { + pinctrl-0 = <&sound_pins &sound_clk_pins>; + pinctrl-names = "default"; + + /* Single DAI */ + #sound-dai-cells = <0>; + + /* audio_clkout0/1/2/3 */ + #clock-cells = <1>; + clock-frequency = <11289600 12288000>; + + status = "okay"; + + /* update <audio_clk_b> to <cs2000> */ + clocks = <&cpg CPG_MOD 1005>, + <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>, + <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>, + <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>, + <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>, + <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>, + <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>, + <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>, + <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>, + <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>, + <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>, + <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, + <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, + <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>, + <&audio_clk_a>, <&cs2000>, + <&audio_clk_c>, + <&cpg CPG_CORE CPG_AUDIO_CLK_I>; + + rcar_sound,dai { + dai0 { + playback = <&ssi0 &src0 &dvc0>; + capture = <&ssi1 &src1 &dvc1>; + }; + }; +}; + +&scif2 { + pinctrl-0 = <&scif2_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&scif_clk { + clock-frequency = <14745600>; +}; + +&sdhi0 { + pinctrl-0 = <&sdhi0_pins>; + pinctrl-1 = <&sdhi0_pins_uhs>; + pinctrl-names = "default", "state_uhs"; + + vmmc-supply = <&vcc_sdhi0>; + vqmmc-supply = <&vccq_sdhi0>; + cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>; + bus-width = <4>; + sd-uhs-sdr50; + status = "okay"; +}; + +&sdhi2 { + /* used for on-board 8bit eMMC */ + pinctrl-0 = <&sdhi2_pins>; + pinctrl-1 = <&sdhi2_pins_uhs>; + pinctrl-names = "default", "state_uhs"; + + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_1p8v>; + bus-width = <8>; + mmc-hs200-1_8v; + non-removable; + status = "okay"; +}; + +&ssi1 { + shared-pin; +}; + +&usb2_phy1 { + pinctrl-0 = <&usb1_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&wdt0 { + timeout-sec = <60>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index b5636bba6b1c..bcfa53b1e6b7 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-orion-r68-meta.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-px5-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-r88.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-evb.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb always := $(dtb-y) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 7e69f1fe78d6..0be96cee27bd 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -372,6 +372,39 @@ <32768>; }; + sdmmc: dwmmc@ff500000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff500000 0x0 0x4000>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + status = "disabled"; + }; + + sdio: dwmmc@ff510000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff510000 0x0 0x4000>; + interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, + <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + status = "disabled"; + }; + + emmc: dwmmc@ff520000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff520000 0x0 0x4000>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, + <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + status = "disabled"; + }; + gmac2io: ethernet@ff540000 { compatible = "rockchip,rk3328-gmac"; reg = <0x0 0xff540000 0x0 0x10000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts new file mode 100644 index 000000000000..ba1d9810ad1e --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts @@ -0,0 +1,718 @@ +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include <dt-bindings/pwm/pwm.h> +#include "rk3399.dtsi" + +/ { + model = "Firefly-RK3399 Board"; + compatible = "firefly,firefly-rk3399", "rockchip,rk3399"; + + backlight: backlight { + compatible = "pwm-backlight"; + enable-gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>; + pwms = <&pwm0 0 25000 0>; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + rt5640-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "rockchip,rt5640-codec"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Mic Jack", "MICBIAS1", + "IN1P", "Mic Jack", + "Headphone Jack", "HPOL", + "Headphone Jack", "HPOR"; + + simple-audio-card,cpu { + sound-dai = <&i2s1>; + }; + + simple-audio-card,codec { + sound-dai = <&rt5640>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk808 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; + + /* switched by pmic_sleep */ + vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_1v8>; + }; + + vcc3v3_pcie: vcc3v3-pcie-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_pwr_en>; + regulator-name = "vcc3v3_pcie"; + regulator-always-on; + regulator-boot-on; + vin-supply = <&dc_12v>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_sys>; + }; + + /* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */ + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + regulator-name = "vcc5v0_host"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + vin-supply = <&vcc_sys>; + }; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&emmc_phy { + status = "okay"; +}; + +&gmac { + assigned-clocks = <&cru SCLK_RMII_SRC>; + assigned-clock-parents = <&clkin_gmac>; + clock_in_out = "input"; + phy-supply = <&vcc_lan>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x28>; + rx_delay = <0x11>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + status = "okay"; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio1>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + vcc7-supply = <&vcc_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc_sys>; + vcc10-supply = <&vcc_sys>; + vcc11-supply = <&vcc_sys>; + vcc12-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc1v8_pmu>; + + regulators { + vdd_center: DCDC_REG1 { + regulator-name = "vdd_center"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc1v8_dvp: LDO_REG1 { + regulator-name = "vcc1v8_dvp"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc2v8_dvp: LDO_REG2 { + regulator-name = "vcc2v8_dvp"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_pmu: LDO_REG3 { + regulator-name = "vcc1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sdio: LDO_REG4 { + regulator-name = "vcc_sdio"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca3v0_codec: LDO_REG5 { + regulator-name = "vcca3v0_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v5: LDO_REG6 { + regulator-name = "vcc_1v5"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + vcca1v8_codec: LDO_REG7 { + regulator-name = "vcca1v8_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v0: LDO_REG8 { + regulator-name = "vcc_3v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc3v3_s3: vcc_lan: SWITCH_REG1 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_s0: SWITCH_REG2 { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <0>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: regulator@41 { + compatible = "silergy,syr828"; + reg = <0x41>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c1 { + i2c-scl-rising-time-ns = <300>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; + + rt5640: rt5640@1c { + compatible = "realtek,rt5640"; + reg = <0x1c>; + clocks = <&cru SCLK_I2S_8CH_OUT>; + clock-names = "mclk"; + realtek,in1-differential; + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&rt5640_hpcon>; + }; +}; + +&i2c3 { + i2c-scl-rising-time-ns = <450>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; +}; + +&i2c4 { + i2c-scl-rising-time-ns = <600>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + + accelerometer@68 { + compatible = "invensense,mpu6500"; + reg = <0x68>; + interrupt-parent = <&gpio1>; + interrupts = <RK_PC6 IRQ_TYPE_EDGE_RISING>; + }; +}; + +&i2s0 { + rockchip,playback-channels = <8>; + rockchip,capture-channels = <8>; + #sound-dai-cells = <0>; + status = "okay"; +}; + +&i2s1 { + rockchip,playback-channels = <2>; + rockchip,capture-channels = <2>; + #sound-dai-cells = <0>; + status = "okay"; +}; + +&i2s2 { + #sound-dai-cells = <0>; + status = "okay"; +}; + +&io_domains { + status = "okay"; + + bt656-supply = <&vcc1v8_dvp>; + audio-supply = <&vcca1v8_codec>; + sdmmc-supply = <&vcc_sdio>; + gpio1830-supply = <&vcc_3v0>; +}; + +&pcie_phy { + status = "okay"; +}; + +&pcie0 { + ep-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>; + num-lanes = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_clkreqn>; + status = "okay"; +}; + +&pmu_io_domains { + pmu1830-supply = <&vcc_3v0>; + status = "okay"; +}; + +&pinctrl { + buttons { + pwrbtn: pwrbtn { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + lcd-panel { + lcd_panel_reset: lcd-panel-reset { + rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pcie { + pcie_pwr_en: pcie-pwr-en { + rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie_3g_drv: pcie-3g-drv { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pmic { + vsel1_gpio: vsel1-gpio { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + vsel2_gpio: vsel2-gpio { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + rt5640 { + rt5640_hpcon: rt5640-hpcon { + rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb2 { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca1v8_s3>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + keep-power-in-suspend; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + non-removable; + status = "okay"; +}; + +&tsadc { + /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-mode = <1>; + /* tshut polarity 0:LOW 1:HIGH */ + rockchip,hw-tshut-polarity = <1>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; + + u2phy0_otg: otg-port { + status = "okay"; + }; + + u2phy0_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + status = "okay"; + }; + + u2phy1_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usbdrd3_0 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + status = "okay"; + dr_mode = "otg"; +}; + +&usbdrd3_1 { + status = "okay"; +}; + +&usbdrd_dwc3_1 { + status = "okay"; + dr_mode = "host"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi index 0d960b7f7625..eb5059344023 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi @@ -44,7 +44,7 @@ #include <dt-bindings/input/input.h> #include "rk3399.dtsi" -#include "rk3399-opp.dtsi" +#include "rk3399-op1-opp.dtsi" / { chosen { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi new file mode 100644 index 000000000000..be7fe635f7c1 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2016-2017 Fuzhou Rockchip Electronics Co., Ltd + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/ { + cluster0_opp: opp-table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp00 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <800000>; + clock-latency-ns = <40000>; + }; + opp01 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <825000>; + }; + opp02 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <850000>; + }; + opp03 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <900000>; + }; + opp04 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <975000>; + }; + opp05 { + opp-hz = /bits/ 64 <1416000000>; + opp-microvolt = <1100000>; + }; + opp06 { + opp-hz = /bits/ 64 <1512000000>; + opp-microvolt = <1150000>; + }; + }; + + cluster1_opp: opp-table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp00 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <800000>; + clock-latency-ns = <40000>; + }; + opp01 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <800000>; + }; + opp02 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <825000>; + }; + opp03 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <850000>; + }; + opp04 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <900000>; + }; + opp05 { + opp-hz = /bits/ 64 <1416000000>; + opp-microvolt = <975000>; + }; + opp06 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <1050000>; + }; + opp07 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1150000>; + }; + opp08 { + opp-hz = /bits/ 64 <2016000000>; + opp-microvolt = <1250000>; + }; + }; +}; + +&cpu_l0 { + operating-points-v2 = <&cluster0_opp>; +}; + +&cpu_l1 { + operating-points-v2 = <&cluster0_opp>; +}; + +&cpu_l2 { + operating-points-v2 = <&cluster0_opp>; +}; + +&cpu_l3 { + operating-points-v2 = <&cluster0_opp>; +}; + +&cpu_b0 { + operating-points-v2 = <&cluster1_opp>; +}; + +&cpu_b1 { + operating-points-v2 = <&cluster1_opp>; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi index dd82e16236a8..c83460db130a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi @@ -56,22 +56,18 @@ }; opp02 { opp-hz = /bits/ 64 <816000000>; - opp-microvolt = <800000>; + opp-microvolt = <850000>; }; opp03 { opp-hz = /bits/ 64 <1008000000>; - opp-microvolt = <875000>; + opp-microvolt = <925000>; }; opp04 { opp-hz = /bits/ 64 <1200000000>; - opp-microvolt = <925000>; + opp-microvolt = <1000000>; }; opp05 { opp-hz = /bits/ 64 <1416000000>; - opp-microvolt = <1050000>; - }; - opp06 { - opp-hz = /bits/ 64 <1512000000>; opp-microvolt = <1125000>; }; }; @@ -107,15 +103,11 @@ }; opp06 { opp-hz = /bits/ 64 <1608000000>; - opp-microvolt = <1075000>; + opp-microvolt = <1100000>; }; opp07 { opp-hz = /bits/ 64 <1800000000>; - opp-microvolt = <1150000>; - }; - opp08 { - opp-hz = /bits/ 64 <2016000000>; - opp-microvolt = <1250000>; + opp-microvolt = <1200000>; }; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index f4f3c96c798d..69c56f7316c4 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -56,6 +56,7 @@ #size-cells = <2>; aliases { + ethernet0 = &gmac; i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; @@ -220,7 +221,7 @@ #size-cells = <2>; #interrupt-cells = <1>; aspm-no-l0s; - bus-range = <0x0 0x1>; + bus-range = <0x0 0x1f>; clocks = <&cru ACLK_PCIE>, <&cru ACLK_PERF_PCIE>, <&cru PCLK_PCIE>, <&cru SCLK_PCIE_PM>; clock-names = "aclk", "aclk-perf", @@ -239,8 +240,8 @@ msi-map = <0x0 &its 0x0 0x1000>; phys = <&pcie_phy>; phy-names = "pcie-phy"; - ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x600000 - 0x81000000 0x0 0xfa600000 0x0 0xfa600000 0x0 0x100000>; + ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x1e00000 + 0x81000000 0x0 0xfbe00000 0x0 0xfbe00000 0x0 0x100000>; resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>, <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, @@ -769,11 +770,6 @@ status = "disabled"; }; - qos_sd: qos@ffa74000 { - compatible = "syscon"; - reg = <0x0 0xffa74000 0x0 0x20>; - }; - qos_emmc: qos@ffa58000 { compatible = "syscon"; reg = <0x0 0xffa58000 0x0 0x20>; @@ -784,6 +780,41 @@ reg = <0x0 0xffa5c000 0x0 0x20>; }; + qos_pcie: qos@ffa60080 { + compatible = "syscon"; + reg = <0x0 0xffa60080 0x0 0x20>; + }; + + qos_usb_host0: qos@ffa60100 { + compatible = "syscon"; + reg = <0x0 0xffa60100 0x0 0x20>; + }; + + qos_usb_host1: qos@ffa60180 { + compatible = "syscon"; + reg = <0x0 0xffa60180 0x0 0x20>; + }; + + qos_usb_otg0: qos@ffa70000 { + compatible = "syscon"; + reg = <0x0 0xffa70000 0x0 0x20>; + }; + + qos_usb_otg1: qos@ffa70080 { + compatible = "syscon"; + reg = <0x0 0xffa70080 0x0 0x20>; + }; + + qos_sd: qos@ffa74000 { + compatible = "syscon"; + reg = <0x0 0xffa74000 0x0 0x20>; + }; + + qos_sdioaudio: qos@ffa76000 { + compatible = "syscon"; + reg = <0x0 0xffa76000 0x0 0x20>; + }; + qos_hdcp: qos@ffa90000 { compatible = "syscon"; reg = <0x0 0xffa90000 0x0 0x20>; @@ -854,6 +885,11 @@ reg = <0x0 0xffad0000 0x0 0x20>; }; + qos_perihp: qos@ffad8080 { + compatible = "syscon"; + reg = <0x0 0xffad8080 0x0 0x20>; + }; + qos_gpu: qos@ffae0000 { compatible = "syscon"; reg = <0x0 0xffae0000 0x0 0x20>; @@ -1676,6 +1712,91 @@ }; }; + sdio0 { + sdio0_bus1: sdio0-bus1 { + rockchip,pins = + <2 RK_PC4 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_bus4: sdio0-bus4 { + rockchip,pins = + <2 RK_PC4 RK_FUNC_1 &pcfg_pull_up>, + <2 RK_PC5 RK_FUNC_1 &pcfg_pull_up>, + <2 RK_PC6 RK_FUNC_1 &pcfg_pull_up>, + <2 RK_PC7 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_cmd: sdio0-cmd { + rockchip,pins = + <2 RK_PD0 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_clk: sdio0-clk { + rockchip,pins = + <2 RK_PD1 RK_FUNC_1 &pcfg_pull_none>; + }; + + sdio0_cd: sdio0-cd { + rockchip,pins = + <2 RK_PD2 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_pwr: sdio0-pwr { + rockchip,pins = + <2 RK_PD3 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_bkpwr: sdio0-bkpwr { + rockchip,pins = + <2 RK_PD4 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_wp: sdio0-wp { + rockchip,pins = + <0 RK_PA3 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_int: sdio0-int { + rockchip,pins = + <0 RK_PA4 RK_FUNC_1 &pcfg_pull_up>; + }; + }; + + sdmmc { + sdmmc_bus1: sdmmc-bus1 { + rockchip,pins = + <4 RK_PB0 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = + <4 RK_PB0 RK_FUNC_1 &pcfg_pull_up>, + <4 RK_PB1 RK_FUNC_1 &pcfg_pull_up>, + <4 RK_PB2 RK_FUNC_1 &pcfg_pull_up>, + <4 RK_PB3 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdmmc_clk: sdmmc-clk { + rockchip,pins = + <4 RK_PB4 RK_FUNC_1 &pcfg_pull_none>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = + <4 RK_PB5 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdmmc_cd: sdmcc-cd { + rockchip,pins = + <0 RK_PA7 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdmmc_wp: sdmmc-wp { + rockchip,pins = + <0 RK_PB0 RK_FUNC_1 &pcfg_pull_up>; + }; + }; + sleep { ap_pwroff: ap-pwroff { rockchip,pins = <1 5 RK_FUNC_1 &pcfg_pull_none>; @@ -1691,6 +1812,11 @@ rockchip,pins = <4 21 RK_FUNC_1 &pcfg_pull_none>; }; + + spdif_bus_1: spdif-bus-1 { + rockchip,pins = + <3 RK_PC0 RK_FUNC_3 &pcfg_pull_none>; + }; }; spi0 { @@ -1950,6 +2076,19 @@ }; }; + hdmi { + hdmi_i2c_xfer: hdmi-i2c-xfer { + rockchip,pins = + <4 RK_PC1 RK_FUNC_3 &pcfg_pull_none>, + <4 RK_PC0 RK_FUNC_3 &pcfg_pull_none>; + }; + + hdmi_cec: hdmi-cec { + rockchip,pins = + <4 RK_PC7 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + pcie { pcie_clkreqn: pci-clkreqn { rockchip,pins = @@ -1960,6 +2099,16 @@ rockchip,pins = <4 24 RK_FUNC_1 &pcfg_pull_none>; }; + + pcie_clkreqn_cpm: pci-clkreqn-cpm { + rockchip,pins = + <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie_clkreqnb_cpm: pci-clkreqnb-cpm { + rockchip,pins = + <4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; + }; }; }; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 65cdd878cfbd..000de61802a1 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -68,6 +68,7 @@ CONFIG_PCIE_QCOM=y CONFIG_PCIE_ARMADA_8K=y CONFIG_PCI_AARDVARK=y CONFIG_PCIE_RCAR=y +CONFIG_PCIE_ROCKCHIP=m CONFIG_PCI_HOST_GENERIC=y CONFIG_PCI_XGENE=y CONFIG_ARM64_VA_BITS_48=y @@ -208,6 +209,8 @@ CONFIG_BRCMFMAC=m CONFIG_WL18XX=m CONFIG_WLCORE_SDIO=m CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_ADC=m +CONFIG_KEYBOARD_CROS_EC=y CONFIG_KEYBOARD_GPIO=y CONFIG_INPUT_MISC=y CONFIG_INPUT_PM8941_PWRKEY=y @@ -263,6 +266,7 @@ CONFIG_SPI_MESON_SPIFC=m CONFIG_SPI_ORION=y CONFIG_SPI_PL022=y CONFIG_SPI_QUP=y +CONFIG_SPI_ROCKCHIP=y CONFIG_SPI_S3C64XX=y CONFIG_SPI_SPIDEV=m CONFIG_SPMI=y @@ -292,6 +296,7 @@ CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y CONFIG_THERMAL_EMULATION=y CONFIG_EXYNOS_THERMAL=y +CONFIG_ROCKCHIP_THERMAL=m CONFIG_WATCHDOG=y CONFIG_S3C2410_WATCHDOG=y CONFIG_MESON_GXBB_WATCHDOG=m @@ -300,12 +305,14 @@ CONFIG_RENESAS_WDT=y CONFIG_BCM2835_WDT=y CONFIG_MFD_CROS_EC=y CONFIG_MFD_CROS_EC_I2C=y +CONFIG_MFD_CROS_EC_SPI=y CONFIG_MFD_EXYNOS_LPASS=m CONFIG_MFD_HI655X_PMIC=y CONFIG_MFD_MAX77620=y CONFIG_MFD_SPMI_PMIC=y CONFIG_MFD_RK808=y CONFIG_MFD_SEC_CORE=y +CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_HI655X=y @@ -320,6 +327,11 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=m +CONFIG_RC_DEVICES=y +CONFIG_RC_DECODERS=y +CONFIG_IR_MESON=m CONFIG_VIDEO_V4L2_SUBDEV_API=y # CONFIG_DVB_NET is not set CONFIG_V4L_MEM2MEM_DRIVERS=y @@ -473,8 +485,10 @@ CONFIG_ARCH_TEGRA_186_SOC=y CONFIG_EXTCON_USB_GPIO=y CONFIG_IIO=y CONFIG_EXYNOS_ADC=y +CONFIG_ROCKCHIP_SARADC=m CONFIG_PWM=y CONFIG_PWM_BCM2835=m +CONFIG_PWM_CROS_EC=m CONFIG_PWM_MESON=m CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_SAMSUNG=y @@ -484,6 +498,7 @@ CONFIG_PHY_HI6220_USB=y CONFIG_PHY_SUN4I_USB=y CONFIG_PHY_ROCKCHIP_INNO_USB2=y CONFIG_PHY_ROCKCHIP_EMMC=y +CONFIG_PHY_ROCKCHIP_PCIE=m CONFIG_PHY_XGENE=y CONFIG_PHY_TEGRA_XUSB=y CONFIG_ARM_SCPI_PROTOCOL=y diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 5d1700425efe..ac3fb7441510 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -142,6 +142,7 @@ typedef struct user_fpsimd_state elf_fpregset_t; ({ \ clear_bit(TIF_32BIT, ¤t->mm->context.flags); \ clear_thread_flag(TIF_32BIT); \ + current->personality &= ~READ_IMPLIES_EXEC; \ }) /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ @@ -187,6 +188,11 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; ((x)->e_flags & EF_ARM_EABI_MASK)) #define compat_start_thread compat_start_thread +/* + * Unlike the native SET_PERSONALITY macro, the compat version inherits + * READ_IMPLIES_EXEC across a fork() since this is the behaviour on + * arch/arm/. + */ #define COMPAT_SET_PERSONALITY(ex) \ ({ \ set_bit(TIF_32BIT, ¤t->mm->context.flags); \ diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index 85c4a8981d47..f32b42e8725d 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h @@ -48,16 +48,16 @@ do { \ } while (0) static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) { int op = (encoded_op >> 28) & 7; int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; + int oparg = (int)(encoded_op << 8) >> 20; + int cmparg = (int)(encoded_op << 20) >> 20; int oldval = 0, ret, tmp; if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; + oparg = 1U << (oparg & 0x1f); if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index 801a16dbbdf6..5b6eafccc5d8 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -30,5 +30,6 @@ struct stackframe { extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame); extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame, int (*fn)(struct stackframe *, void *), void *data); +extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk); #endif /* __ASM_STACKTRACE_H */ diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 817ce3365e20..22f554320581 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -639,8 +639,8 @@ void update_cpu_features(int cpu, * Mismatched CPU features are a recipe for disaster. Don't even * pretend to support them. */ - WARN_TAINT_ONCE(taint, TAINT_CPU_OUT_OF_SPEC, - "Unsupported CPU feature variation.\n"); + pr_warn_once("Unsupported CPU feature variation detected.\n"); + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); } u64 read_sanitised_ftr_reg(u32 id) diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index 4f0e3ebfea4b..108283443336 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -108,7 +108,10 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) if (!acpi_disabled) { struct pci_config_window *cfg = bridge->bus->sysdata; struct acpi_device *adev = to_acpi_device(cfg->parent); + struct device *bus_dev = &bridge->bus->dev; + ACPI_COMPANION_SET(&bridge->dev, adev); + set_dev_node(bus_dev, acpi_get_node(acpi_device_handle(adev))); } return 0; diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index c5c45942fb6e..d849d9804011 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -522,9 +522,9 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) pr_err("current sp %lx does not match saved sp %lx\n", orig_sp, stack_addr); pr_err("Saved registers for jprobe %p\n", jp); - show_regs(saved_regs); + __show_regs(saved_regs); pr_err("Current registers\n"); - show_regs(regs); + __show_regs(regs); BUG(); } unpause_graph_tracing(); diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index ae2a835898d7..af1ea258c212 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -210,6 +210,7 @@ void __show_regs(struct pt_regs *regs) void show_regs(struct pt_regs * regs) { __show_regs(regs); + dump_backtrace(regs, NULL); } static void tls_thread_flush(void) diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 2c822ef94f34..d4b740538ad5 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -194,6 +194,9 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys) } name = of_flat_dt_get_machine_name(); + if (!name) + return; + pr_info("Machine model: %s\n", name); dump_stack_set_arch_desc("%s (DT)", name); } diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 0805b44f986a..3ebfb1d00b53 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -140,7 +140,7 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) } } -static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) +void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) { struct stackframe frame; unsigned long irq_stack_ptr; @@ -728,8 +728,6 @@ static int bug_handler(struct pt_regs *regs, unsigned int esr) break; case BUG_TRAP_TYPE_WARN: - /* Ideally, report_bug() should backtrace for us... but no. */ - dump_backtrace(regs, NULL); break; default: diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 37b95dff0b07..c3f2b1048f83 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -250,7 +250,7 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, tsk->comm, task_pid_nr(tsk), inf->name, sig, addr, esr); show_pte(tsk->mm, addr); - show_regs(regs); + __show_regs(regs); } tsk->thread.fault_address = addr; diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 0c429ec6fde8..23c2d89a362e 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -31,6 +31,7 @@ #include <linux/fs.h> #include <linux/io.h> #include <linux/mm.h> +#include <linux/vmalloc.h> #include <asm/barrier.h> #include <asm/cputype.h> diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index 531cb9eb3319..ddff1164aff0 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -26,6 +26,8 @@ CONFIG_SUN_PARTITION=y CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y @@ -349,7 +351,6 @@ CONFIG_SCSI_A4000T=y CONFIG_SCSI_ZORRO7XX=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -361,6 +362,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -414,6 +416,7 @@ CONFIG_ZORRO8390=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -572,6 +575,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -590,6 +595,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index ca91d39555da..17384dc959a5 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -27,6 +27,8 @@ CONFIG_SUN_PARTITION=y CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y @@ -331,7 +333,6 @@ CONFIG_ISCSI_TCP=m CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -343,6 +344,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -388,6 +390,7 @@ CONFIG_VETH=m # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -531,6 +534,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -549,6 +554,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index 23a3d8a691e2..53a641d62f85 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -26,6 +26,8 @@ CONFIG_SUN_PARTITION=y CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y @@ -340,7 +342,6 @@ CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_ATARI_SCSI=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -352,6 +353,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -399,6 +401,7 @@ CONFIG_SMC91X=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -552,6 +555,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -570,6 +575,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index 95deb95140fe..3925ae3a5eb3 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -26,6 +26,8 @@ CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_M68040=y @@ -330,7 +332,6 @@ CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_BVME6000_SCSI=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -342,6 +343,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -387,6 +389,7 @@ CONFIG_BVME6000_NET=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -523,6 +526,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -541,6 +546,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index afae6958db2d..f4a134b390b4 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -27,6 +27,8 @@ CONFIG_SUN_PARTITION=y CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y @@ -331,7 +333,6 @@ CONFIG_ISCSI_TCP=m CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -343,6 +344,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -389,6 +391,7 @@ CONFIG_HPLANCE=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -533,6 +536,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -551,6 +556,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index b010734729a7..9ed0cef632b7 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -26,6 +26,8 @@ CONFIG_SUN_PARTITION=y CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y @@ -340,7 +342,6 @@ CONFIG_MAC_SCSI=y CONFIG_SCSI_MAC_ESP=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -352,6 +353,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -408,6 +410,7 @@ CONFIG_MAC8390=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -555,6 +558,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -573,6 +578,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index 0e414549b235..efed0d48fd53 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -22,6 +22,8 @@ CONFIG_UNIXWARE_DISKLABEL=y # CONFIG_EFI_PARTITION is not set CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y @@ -373,7 +375,6 @@ CONFIG_BVME6000_SCSI=y CONFIG_SUN3X_ESP=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -385,6 +386,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -454,6 +456,7 @@ CONFIG_SMC91X=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PLIP=m CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m @@ -635,6 +638,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -653,6 +658,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index b2e687a0ec3d..9040457c7f9c 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -26,6 +26,8 @@ CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_M68030=y @@ -329,7 +331,6 @@ CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MVME147_SCSI=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -341,6 +342,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -387,6 +389,7 @@ CONFIG_MVME147_NET=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -523,6 +526,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -541,6 +546,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index cbd8ee24d1bc..8b17f00e0484 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -26,6 +26,8 @@ CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_M68040=y @@ -330,7 +332,6 @@ CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MVME16x_SCSI=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -342,6 +343,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -387,6 +389,7 @@ CONFIG_MVME16x_NET=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -523,6 +526,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -541,6 +546,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index 1e82cc944339..5f3718c62c85 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -27,6 +27,8 @@ CONFIG_SUN_PARTITION=y CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_M68040=y @@ -336,7 +338,6 @@ CONFIG_ISCSI_TCP=m CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -348,6 +349,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -398,6 +400,7 @@ CONFIG_NE2000=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PLIP=m CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m @@ -546,6 +549,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -564,6 +569,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index f9e77f57a972..8c979a68fca5 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -26,6 +26,8 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_SUN3=y @@ -327,7 +329,6 @@ CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_SUN3_SCSI=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -339,6 +340,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -385,6 +387,7 @@ CONFIG_SUN3_82586=y # CONFIG_NET_VENDOR_SUN is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -525,6 +528,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -542,6 +547,7 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index 3c394fcfb368..a1e79530e806 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -26,6 +26,8 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m CONFIG_MQ_IOSCHED_DEADLINE=m +CONFIG_MQ_IOSCHED_KYBER=m +CONFIG_IOSCHED_BFQ=m CONFIG_KEXEC=y CONFIG_BOOTINFO_PROC=y CONFIG_SUN3X=y @@ -327,7 +329,6 @@ CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_SUN3X_ESP=y CONFIG_MD=y CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m @@ -339,6 +340,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y CONFIG_DM_LOG_WRITES=m +CONFIG_DM_INTEGRITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -385,6 +387,7 @@ CONFIG_SUN3LANCE=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -525,6 +528,8 @@ CONFIG_DLM=m # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_MAGIC_SYSRQ=y CONFIG_WW_MUTEX_SELFTEST=m +CONFIG_TEST_LIST_SORT=m +CONFIG_TEST_SORT=m CONFIG_ATOMIC64_SELFTEST=m CONFIG_ASYNC_RAID6_TEST=m CONFIG_TEST_HEXDUMP=m @@ -543,6 +548,7 @@ CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m +CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index 56830ff65333..83a4ef3a2495 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -1,14 +1,57 @@ generic-y += barrier.h +generic-y += bitops.h +generic-y += bitsperlong.h +generic-y += bug.h +generic-y += bugs.h generic-y += clkdev.h generic-y += device.h +generic-y += div64.h +generic-y += emergency-restart.h +generic-y += errno.h generic-y += exec.h generic-y += extable.h +generic-y += fb.h +generic-y += fcntl.h +generic-y += hardirq.h +generic-y += ioctl.h +generic-y += ioctls.h +generic-y += ipcbuf.h +generic-y += irq_regs.h generic-y += irq_work.h +generic-y += kdebug.h +generic-y += kmap_types.h +generic-y += kprobes.h +generic-y += linkage.h +generic-y += local.h +generic-y += local64.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h +generic-y += mman.h +generic-y += msgbuf.h +generic-y += param.h +generic-y += parport.h +generic-y += percpu.h +generic-y += poll.h generic-y += preempt.h +generic-y += resource.h +generic-y += sembuf.h +generic-y += serial.h +generic-y += shmbuf.h +generic-y += shmparam.h +generic-y += siginfo.h +generic-y += signal.h +generic-y += socket.h +generic-y += sockios.h +generic-y += stat.h +generic-y += statfs.h +generic-y += swab.h generic-y += syscalls.h +generic-y += termbits.h +generic-y += termios.h +generic-y += topology.h generic-y += trace_clock.h +generic-y += ucontext.h +generic-y += vga.h generic-y += word-at-a-time.h -generic-y += kprobes.h +generic-y += xor.h diff --git a/arch/microblaze/include/asm/bitops.h b/arch/microblaze/include/asm/bitops.h deleted file mode 100644 index a72468f15c8b..000000000000 --- a/arch/microblaze/include/asm/bitops.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/bitops.h> diff --git a/arch/microblaze/include/asm/bug.h b/arch/microblaze/include/asm/bug.h deleted file mode 100644 index b12fd89e42e9..000000000000 --- a/arch/microblaze/include/asm/bug.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/bug.h> diff --git a/arch/microblaze/include/asm/bugs.h b/arch/microblaze/include/asm/bugs.h deleted file mode 100644 index 61791e1ad9f5..000000000000 --- a/arch/microblaze/include/asm/bugs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/bugs.h> diff --git a/arch/microblaze/include/asm/div64.h b/arch/microblaze/include/asm/div64.h deleted file mode 100644 index 6cd978cefb28..000000000000 --- a/arch/microblaze/include/asm/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/div64.h> diff --git a/arch/microblaze/include/asm/emergency-restart.h b/arch/microblaze/include/asm/emergency-restart.h deleted file mode 100644 index 3711bd9d50bd..000000000000 --- a/arch/microblaze/include/asm/emergency-restart.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/emergency-restart.h> diff --git a/arch/microblaze/include/asm/fb.h b/arch/microblaze/include/asm/fb.h deleted file mode 100644 index 3a4988e8df45..000000000000 --- a/arch/microblaze/include/asm/fb.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/fb.h> diff --git a/arch/microblaze/include/asm/hardirq.h b/arch/microblaze/include/asm/hardirq.h deleted file mode 100644 index fb3c05a0cbbf..000000000000 --- a/arch/microblaze/include/asm/hardirq.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/hardirq.h> diff --git a/arch/microblaze/include/asm/irq_regs.h b/arch/microblaze/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/arch/microblaze/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/irq_regs.h> diff --git a/arch/microblaze/include/asm/kdebug.h b/arch/microblaze/include/asm/kdebug.h deleted file mode 100644 index 6ece1b037665..000000000000 --- a/arch/microblaze/include/asm/kdebug.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/kdebug.h> diff --git a/arch/microblaze/include/asm/kmap_types.h b/arch/microblaze/include/asm/kmap_types.h deleted file mode 100644 index 25975252d83d..000000000000 --- a/arch/microblaze/include/asm/kmap_types.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_MICROBLAZE_KMAP_TYPES_H -#define _ASM_MICROBLAZE_KMAP_TYPES_H - -#include <asm-generic/kmap_types.h> - -#endif /* _ASM_MICROBLAZE_KMAP_TYPES_H */ diff --git a/arch/microblaze/include/asm/linkage.h b/arch/microblaze/include/asm/linkage.h deleted file mode 100644 index 0540bbaad897..000000000000 --- a/arch/microblaze/include/asm/linkage.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/linkage.h> diff --git a/arch/microblaze/include/asm/local.h b/arch/microblaze/include/asm/local.h deleted file mode 100644 index c11c530f74d0..000000000000 --- a/arch/microblaze/include/asm/local.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/local.h> diff --git a/arch/microblaze/include/asm/local64.h b/arch/microblaze/include/asm/local64.h deleted file mode 100644 index 36c93b5cc239..000000000000 --- a/arch/microblaze/include/asm/local64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/local64.h> diff --git a/arch/microblaze/include/asm/parport.h b/arch/microblaze/include/asm/parport.h deleted file mode 100644 index cf252af64590..000000000000 --- a/arch/microblaze/include/asm/parport.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/parport.h> diff --git a/arch/microblaze/include/asm/percpu.h b/arch/microblaze/include/asm/percpu.h deleted file mode 100644 index 06a959d67234..000000000000 --- a/arch/microblaze/include/asm/percpu.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/percpu.h> diff --git a/arch/microblaze/include/asm/serial.h b/arch/microblaze/include/asm/serial.h deleted file mode 100644 index a0cb0caff152..000000000000 --- a/arch/microblaze/include/asm/serial.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/serial.h> diff --git a/arch/microblaze/include/asm/shmparam.h b/arch/microblaze/include/asm/shmparam.h deleted file mode 100644 index 93f30deb95d0..000000000000 --- a/arch/microblaze/include/asm/shmparam.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/shmparam.h> diff --git a/arch/microblaze/include/asm/topology.h b/arch/microblaze/include/asm/topology.h deleted file mode 100644 index 5428f333a02c..000000000000 --- a/arch/microblaze/include/asm/topology.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/topology.h> diff --git a/arch/microblaze/include/asm/ucontext.h b/arch/microblaze/include/asm/ucontext.h deleted file mode 100644 index 9bc07b9f30fb..000000000000 --- a/arch/microblaze/include/asm/ucontext.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ucontext.h> diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h index 032fed71223f..9774e1d9507b 100644 --- a/arch/microblaze/include/asm/unistd.h +++ b/arch/microblaze/include/asm/unistd.h @@ -38,6 +38,6 @@ #endif /* __ASSEMBLY__ */ -#define __NR_syscalls 398 +#define __NR_syscalls 399 #endif /* _ASM_MICROBLAZE_UNISTD_H */ diff --git a/arch/microblaze/include/asm/vga.h b/arch/microblaze/include/asm/vga.h deleted file mode 100644 index 89d82fd8fcf1..000000000000 --- a/arch/microblaze/include/asm/vga.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/vga.h> diff --git a/arch/microblaze/include/asm/xor.h b/arch/microblaze/include/asm/xor.h deleted file mode 100644 index c82eb12a5b18..000000000000 --- a/arch/microblaze/include/asm/xor.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/xor.h> diff --git a/arch/microblaze/include/uapi/asm/bitsperlong.h b/arch/microblaze/include/uapi/asm/bitsperlong.h deleted file mode 100644 index 6dc0bb0c13b2..000000000000 --- a/arch/microblaze/include/uapi/asm/bitsperlong.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/bitsperlong.h> diff --git a/arch/microblaze/include/uapi/asm/errno.h b/arch/microblaze/include/uapi/asm/errno.h deleted file mode 100644 index 4c82b503d92f..000000000000 --- a/arch/microblaze/include/uapi/asm/errno.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/errno.h> diff --git a/arch/microblaze/include/uapi/asm/fcntl.h b/arch/microblaze/include/uapi/asm/fcntl.h deleted file mode 100644 index 46ab12db5739..000000000000 --- a/arch/microblaze/include/uapi/asm/fcntl.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/fcntl.h> diff --git a/arch/microblaze/include/uapi/asm/ioctl.h b/arch/microblaze/include/uapi/asm/ioctl.h deleted file mode 100644 index b279fe06dfe5..000000000000 --- a/arch/microblaze/include/uapi/asm/ioctl.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ioctl.h> diff --git a/arch/microblaze/include/uapi/asm/ioctls.h b/arch/microblaze/include/uapi/asm/ioctls.h deleted file mode 100644 index ec34c760665e..000000000000 --- a/arch/microblaze/include/uapi/asm/ioctls.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ioctls.h> diff --git a/arch/microblaze/include/uapi/asm/ipcbuf.h b/arch/microblaze/include/uapi/asm/ipcbuf.h deleted file mode 100644 index 84c7e51cb6d0..000000000000 --- a/arch/microblaze/include/uapi/asm/ipcbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ipcbuf.h> diff --git a/arch/microblaze/include/uapi/asm/kvm_para.h b/arch/microblaze/include/uapi/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b957..000000000000 --- a/arch/microblaze/include/uapi/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/kvm_para.h> diff --git a/arch/microblaze/include/uapi/asm/mman.h b/arch/microblaze/include/uapi/asm/mman.h deleted file mode 100644 index 8eebf89f5ab1..000000000000 --- a/arch/microblaze/include/uapi/asm/mman.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/mman.h> diff --git a/arch/microblaze/include/uapi/asm/msgbuf.h b/arch/microblaze/include/uapi/asm/msgbuf.h deleted file mode 100644 index 809134c644a6..000000000000 --- a/arch/microblaze/include/uapi/asm/msgbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/msgbuf.h> diff --git a/arch/microblaze/include/uapi/asm/param.h b/arch/microblaze/include/uapi/asm/param.h deleted file mode 100644 index 965d45427975..000000000000 --- a/arch/microblaze/include/uapi/asm/param.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/param.h> diff --git a/arch/microblaze/include/uapi/asm/poll.h b/arch/microblaze/include/uapi/asm/poll.h deleted file mode 100644 index c98509d3149e..000000000000 --- a/arch/microblaze/include/uapi/asm/poll.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/poll.h> diff --git a/arch/microblaze/include/uapi/asm/resource.h b/arch/microblaze/include/uapi/asm/resource.h deleted file mode 100644 index 04bc4db8921b..000000000000 --- a/arch/microblaze/include/uapi/asm/resource.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/resource.h> diff --git a/arch/microblaze/include/uapi/asm/sembuf.h b/arch/microblaze/include/uapi/asm/sembuf.h deleted file mode 100644 index 7673b83cfef7..000000000000 --- a/arch/microblaze/include/uapi/asm/sembuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/sembuf.h> diff --git a/arch/microblaze/include/uapi/asm/shmbuf.h b/arch/microblaze/include/uapi/asm/shmbuf.h deleted file mode 100644 index 83c05fc2de38..000000000000 --- a/arch/microblaze/include/uapi/asm/shmbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/shmbuf.h> diff --git a/arch/microblaze/include/uapi/asm/siginfo.h b/arch/microblaze/include/uapi/asm/siginfo.h deleted file mode 100644 index 0815d29d82e5..000000000000 --- a/arch/microblaze/include/uapi/asm/siginfo.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/siginfo.h> diff --git a/arch/microblaze/include/uapi/asm/signal.h b/arch/microblaze/include/uapi/asm/signal.h deleted file mode 100644 index 7b1573ce19de..000000000000 --- a/arch/microblaze/include/uapi/asm/signal.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/signal.h> diff --git a/arch/microblaze/include/uapi/asm/socket.h b/arch/microblaze/include/uapi/asm/socket.h deleted file mode 100644 index 6b71384b9d8b..000000000000 --- a/arch/microblaze/include/uapi/asm/socket.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/socket.h> diff --git a/arch/microblaze/include/uapi/asm/sockios.h b/arch/microblaze/include/uapi/asm/sockios.h deleted file mode 100644 index def6d4746ee7..000000000000 --- a/arch/microblaze/include/uapi/asm/sockios.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/sockios.h> diff --git a/arch/microblaze/include/uapi/asm/stat.h b/arch/microblaze/include/uapi/asm/stat.h deleted file mode 100644 index 3dc90fa92c70..000000000000 --- a/arch/microblaze/include/uapi/asm/stat.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/stat.h> diff --git a/arch/microblaze/include/uapi/asm/statfs.h b/arch/microblaze/include/uapi/asm/statfs.h deleted file mode 100644 index 0b91fe198c20..000000000000 --- a/arch/microblaze/include/uapi/asm/statfs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/statfs.h> diff --git a/arch/microblaze/include/uapi/asm/swab.h b/arch/microblaze/include/uapi/asm/swab.h deleted file mode 100644 index 7847e563ab66..000000000000 --- a/arch/microblaze/include/uapi/asm/swab.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/swab.h> diff --git a/arch/microblaze/include/uapi/asm/termbits.h b/arch/microblaze/include/uapi/asm/termbits.h deleted file mode 100644 index 3935b106de79..000000000000 --- a/arch/microblaze/include/uapi/asm/termbits.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/termbits.h> diff --git a/arch/microblaze/include/uapi/asm/termios.h b/arch/microblaze/include/uapi/asm/termios.h deleted file mode 100644 index 280d78a9d966..000000000000 --- a/arch/microblaze/include/uapi/asm/termios.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/termios.h> diff --git a/arch/microblaze/include/uapi/asm/unistd.h b/arch/microblaze/include/uapi/asm/unistd.h index d8086159d996..a88b3c11cc20 100644 --- a/arch/microblaze/include/uapi/asm/unistd.h +++ b/arch/microblaze/include/uapi/asm/unistd.h @@ -413,5 +413,6 @@ #define __NR_pkey_mprotect 395 #define __NR_pkey_alloc 396 #define __NR_pkey_free 397 +#define __NR_statx 398 #endif /* _UAPI_ASM_MICROBLAZE_UNISTD_H */ diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index 12e093a03e60..e45ada8fb006 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -65,8 +65,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, if (attrs & DMA_ATTR_SKIP_CPU_SYNC) continue; - __dma_sync(page_to_phys(sg_page(sg)) + sg->offset, - sg->length, direction); + __dma_sync(sg_phys(sg), sg->length, direction); } return nents; diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index 6841c2df14d9..c48ff4ad2070 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -398,3 +398,4 @@ ENTRY(sys_call_table) .long sys_pkey_mprotect /* 395 */ .long sys_pkey_alloc .long sys_pkey_free + .long sys_statx diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 999066192715..545ccd46edb3 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -178,8 +178,10 @@ static __init int xilinx_clockevent_init(void) clockevent_xilinx_timer.shift); clockevent_xilinx_timer.max_delta_ns = clockevent_delta2ns((u32)~0, &clockevent_xilinx_timer); + clockevent_xilinx_timer.max_delta_ticks = (u32)~0; clockevent_xilinx_timer.min_delta_ns = clockevent_delta2ns(1, &clockevent_xilinx_timer); + clockevent_xilinx_timer.min_delta_ticks = 1; clockevent_xilinx_timer.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_xilinx_timer); diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 2828ecde133d..0b15978c0f88 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1,75 +1,75 @@ config MIPS bool default y - select ARCH_SUPPORTS_UPROBES + select ARCH_BINFMT_ELF_STATE + select ARCH_CLOCKSOURCE_DATA + select ARCH_DISCARD_MEMBLOCK + select ARCH_HAS_ELF_RANDOMIZE + select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO - select ARCH_USE_CMPXCHG_LOCKREF if 64BIT + select ARCH_SUPPORTS_UPROBES select ARCH_USE_BUILTIN_BSWAP - select HAVE_CONTEXT_TRACKING - select HAVE_GENERIC_DMA_COHERENT - select HAVE_IDE - select HAVE_IRQ_EXIT_ON_IRQ_STACK - select HAVE_OPROFILE - select HAVE_PERF_EVENTS - select PERF_USE_VMALLOC + select ARCH_USE_CMPXCHG_LOCKREF if 64BIT + select ARCH_WANT_IPC_PARSE_VERSION + select BUILDTIME_EXTABLE_SORT + select CLONE_BACKWARDS + select CPU_PM if CPU_IDLE + select GENERIC_ATOMIC64 if !64BIT + select GENERIC_CLOCKEVENTS + select GENERIC_CMOS_UPDATE + select GENERIC_CPU_AUTOPROBE + select GENERIC_IRQ_PROBE + select GENERIC_IRQ_SHOW + select GENERIC_PCI_IOMAP + select GENERIC_SCHED_CLOCK if !CAVIUM_OCTEON_SOC + select GENERIC_SMP_IDLE_THREAD + select GENERIC_TIME_VSYSCALL + select HANDLE_DOMAIN_IRQ + select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KGDB select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK + select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT select HAVE_CBPF_JIT if !CPU_MICROMIPS - select HAVE_FUNCTION_TRACER + select HAVE_CC_STACKPROTECTOR + select HAVE_CONTEXT_TRACKING + select HAVE_COPY_THREAD_TLS + select HAVE_C_RECORDMCOUNT + select HAVE_DEBUG_KMEMLEAK + select HAVE_DEBUG_STACKOVERFLOW + select HAVE_DMA_API_DEBUG + select HAVE_DMA_CONTIGUOUS select HAVE_DYNAMIC_FTRACE + select HAVE_EXIT_THREAD select HAVE_FTRACE_MCOUNT_RECORD - select HAVE_C_RECORDMCOUNT select HAVE_FUNCTION_GRAPH_TRACER + select HAVE_FUNCTION_TRACER + select HAVE_GENERIC_DMA_COHERENT + select HAVE_IDE + select HAVE_IRQ_EXIT_ON_IRQ_STACK + select HAVE_IRQ_TIME_ACCOUNTING select HAVE_KPROBES select HAVE_KRETPROBES - select HAVE_SYSCALL_TRACEPOINTS - select HAVE_DEBUG_KMEMLEAK - select HAVE_SYSCALL_TRACEPOINTS - select ARCH_HAS_ELF_RANDOMIZE - select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT - select RTC_LIB if !MACH_LOONGSON64 - select GENERIC_ATOMIC64 if !64BIT - select HAVE_DMA_CONTIGUOUS - select HAVE_DMA_API_DEBUG - select GENERIC_IRQ_PROBE - select GENERIC_IRQ_SHOW - select GENERIC_PCI_IOMAP - select HAVE_ARCH_JUMP_LABEL - select ARCH_WANT_IPC_PARSE_VERSION - select IRQ_FORCED_THREADING select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP - select ARCH_DISCARD_MEMBLOCK - select GENERIC_SMP_IDLE_THREAD - select BUILDTIME_EXTABLE_SORT - select GENERIC_CPU_AUTOPROBE - select GENERIC_CLOCKEVENTS - select GENERIC_SCHED_CLOCK if !CAVIUM_OCTEON_SOC - select GENERIC_CMOS_UPDATE select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI - select VIRT_TO_BUS - select MODULES_USE_ELF_REL if MODULES + select HAVE_OPROFILE + select HAVE_PERF_EVENTS + select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_SYSCALL_TRACEPOINTS + select HAVE_SYSCALL_TRACEPOINTS + select HAVE_VIRT_CPU_ACCOUNTING_GEN + select IRQ_FORCED_THREADING select MODULES_USE_ELF_RELA if MODULES && 64BIT - select CLONE_BACKWARDS - select HAVE_DEBUG_STACKOVERFLOW - select HAVE_CC_STACKPROTECTOR - select CPU_PM if CPU_IDLE - select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST - select ARCH_BINFMT_ELF_STATE + select MODULES_USE_ELF_REL if MODULES + select PERF_USE_VMALLOC + select RTC_LIB if !MACH_LOONGSON64 select SYSCTL_EXCEPTION_TRACE - select HAVE_VIRT_CPU_ACCOUNTING_GEN - select HAVE_IRQ_TIME_ACCOUNTING - select GENERIC_TIME_VSYSCALL - select ARCH_CLOCKSOURCE_DATA - select HANDLE_DOMAIN_IRQ - select HAVE_EXIT_THREAD - select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_COPY_THREAD_TLS + select VIRT_TO_BUS menu "Machine selection" diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index d34536e7653f..279b6d14ffeb 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h @@ -35,7 +35,12 @@ extern pte_t *pkmap_page_table; * easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ +#ifdef CONFIG_PHYS_ADDR_T_64BIT +#define LAST_PKMAP 512 +#else #define LAST_PKMAP 1024 +#endif + #define LAST_PKMAP_MASK (LAST_PKMAP-1) #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h index 8a7ecb4d5c64..bf9dd9eb4ceb 100644 --- a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h @@ -80,7 +80,6 @@ extern u32 cs5536_pci_conf_read4(int function, int reg); #define PCI_BAR3_REG 0x1c #define PCI_BAR4_REG 0x20 #define PCI_BAR5_REG 0x24 -#define PCI_BAR_COUNT 6 #define PCI_BAR_RANGE_MASK 0xFFFFFFFF /* CARDBUS CIS POINTER */ diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 1000c1b4c875..52f551ee492d 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -39,7 +39,6 @@ struct pci_controller { unsigned long io_offset; unsigned long io_map_base; struct resource *busn_resource; - unsigned long busn_offset; #ifndef CONFIG_PCI_DOMAINS_GENERIC unsigned int index; diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h index 6f94bed571c4..74afe8c76bdd 100644 --- a/arch/mips/include/asm/pgtable-32.h +++ b/arch/mips/include/asm/pgtable-32.h @@ -19,6 +19,10 @@ #define __ARCH_USE_5LEVEL_HACK #include <asm-generic/pgtable-nopmd.h> +#ifdef CONFIG_HIGHMEM +#include <asm/highmem.h> +#endif + extern int temp_tlb_entry; /* @@ -62,7 +66,8 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, #define VMALLOC_START MAP_BASE -#define PKMAP_BASE (0xfe000000UL) +#define PKMAP_END ((FIXADDR_START) & ~((LAST_PKMAP << PAGE_SHIFT)-1)) +#define PKMAP_BASE (PKMAP_END - PAGE_SIZE * LAST_PKMAP) #ifdef CONFIG_HIGHMEM # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE) diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 30a3b75e88eb..9d9b8fbae202 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -38,20 +38,6 @@ void arch_ftrace_update_code(int command) #endif -/* - * Check if the address is in kernel space - * - * Clone core_kernel_text() from kernel/extable.c, but doesn't call - * init_kernel_text() for Ftrace doesn't trace functions in init sections. - */ -static inline int in_kernel_space(unsigned long ip) -{ - if (ip >= (unsigned long)_stext && - ip <= (unsigned long)_etext) - return 1; - return 0; -} - #ifdef CONFIG_DYNAMIC_FTRACE #define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */ @@ -198,7 +184,7 @@ int ftrace_make_nop(struct module *mod, * If ip is in kernel space, no long call, otherwise, long call is * needed. */ - new = in_kernel_space(ip) ? INSN_NOP : INSN_B_1F; + new = core_kernel_text(ip) ? INSN_NOP : INSN_B_1F; #ifdef CONFIG_64BIT return ftrace_modify_code(ip, new); #else @@ -218,12 +204,12 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) unsigned int new; unsigned long ip = rec->ip; - new = in_kernel_space(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0]; + new = core_kernel_text(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0]; #ifdef CONFIG_64BIT return ftrace_modify_code(ip, new); #else - return ftrace_modify_code_2r(ip, new, in_kernel_space(ip) ? + return ftrace_modify_code_2r(ip, new, core_kernel_text(ip) ? INSN_NOP : insn_la_mcount[1]); #endif } @@ -289,7 +275,7 @@ unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long * instruction "lui v1, hi_16bit_of_mcount"(offset is 24), but for * kernel, move after the instruction "move ra, at"(offset is 16) */ - ip = self_ra - (in_kernel_space(self_ra) ? 16 : 24); + ip = self_ra - (core_kernel_text(self_ra) ? 16 : 24); /* * search the text until finding the non-store instruction or "s{d,w} @@ -394,7 +380,7 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra, * entries configured through the tracing/set_graph_function interface. */ - insns = in_kernel_space(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1; + insns = core_kernel_text(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1; trace.func = self_ra - (MCOUNT_INSN_SIZE * insns); /* Only trace if the calling function expects to */ diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 313a88b2973f..f3e301f95aef 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -1597,7 +1597,6 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) break; case CPU_P5600: case CPU_P6600: - case CPU_I6400: /* 8-bit event numbers */ raw_id = config & 0x1ff; base_id = raw_id & 0xff; @@ -1610,6 +1609,11 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) raw_event.range = P; #endif break; + case CPU_I6400: + /* 8-bit event numbers */ + base_id = config & 0xff; + raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; + break; case CPU_1004K: if (IS_BOTH_COUNTERS_1004K_EVENT(base_id)) raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 918d4c73e951..5351e1f3950d 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -120,7 +120,6 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long usp, struct thread_info *ti = task_thread_info(p); struct pt_regs *childregs, *regs = current_pt_regs(); unsigned long childksp; - p->set_child_tid = p->clear_child_tid = NULL; childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c index adc6911ba748..b19a3c506b1e 100644 --- a/arch/mips/mm/pgtable-32.c +++ b/arch/mips/mm/pgtable-32.c @@ -51,15 +51,15 @@ void __init pagetable_init(void) /* * Fixed mappings: */ - vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; - fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base); + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1); + fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base); #ifdef CONFIG_HIGHMEM /* * Permanent kmaps: */ vaddr = PKMAP_BASE; - fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); + fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); pgd = swapper_pg_dir + __pgd_offset(vaddr); pud = pud_offset(pgd, vaddr); diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c index 3a84f6c0c840..174575a9a112 100644 --- a/arch/mips/pci/pci-legacy.c +++ b/arch/mips/pci/pci-legacy.c @@ -86,8 +86,7 @@ static void pcibios_scanbus(struct pci_controller *hose) hose->mem_resource, hose->mem_offset); pci_add_resource_offset(&resources, hose->io_resource, hose->io_offset); - pci_add_resource_offset(&resources, - hose->busn_resource, hose->busn_offset); + pci_add_resource(&resources, hose->busn_resource); bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, &resources); hose->bus = bus; diff --git a/arch/openrisc/configs/or1ksim_defconfig b/arch/openrisc/configs/or1ksim_defconfig index 42fe5303a370..eb3fc581cf20 100644 --- a/arch/openrisc/configs/or1ksim_defconfig +++ b/arch/openrisc/configs/or1ksim_defconfig @@ -1,4 +1,4 @@ -CONFIG_CROSS_COMPILE="or32-linux-" +CONFIG_CROSS_COMPILE="or1k-linux-" CONFIG_NO_HZ=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y diff --git a/arch/openrisc/include/asm/fixmap.h b/arch/openrisc/include/asm/fixmap.h index 52733416c1f3..5a0159546f9e 100644 --- a/arch/openrisc/include/asm/fixmap.h +++ b/arch/openrisc/include/asm/fixmap.h @@ -27,6 +27,7 @@ #define FIXADDR_TOP ((unsigned long) (-2*PAGE_SIZE)) #include <linux/kernel.h> +#include <linux/bug.h> #include <asm/page.h> /* diff --git a/arch/openrisc/kernel/or32_ksyms.c b/arch/openrisc/kernel/or32_ksyms.c index ee3e604959e1..d7260fdb0351 100644 --- a/arch/openrisc/kernel/or32_ksyms.c +++ b/arch/openrisc/kernel/or32_ksyms.c @@ -15,7 +15,7 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/module.h> +#include <linux/export.h> #include <linux/elfcore.h> #include <linux/sched.h> #include <linux/in6.h> diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c index f8da545854f9..ccb7d128dd00 100644 --- a/arch/openrisc/kernel/process.c +++ b/arch/openrisc/kernel/process.c @@ -26,7 +26,7 @@ #include <linux/sched/task.h> #include <linux/sched/task_stack.h> #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/mm.h> #include <linux/stddef.h> #include <linux/unistd.h> @@ -167,8 +167,6 @@ copy_thread(unsigned long clone_flags, unsigned long usp, top_of_kernel_stack = sp; - p->set_child_tid = p->clear_child_tid = NULL; - /* Locate userspace context on stack... */ sp -= STACK_FRAME_OVERHEAD; /* redzone */ sp -= sizeof(struct pt_regs); diff --git a/arch/openrisc/lib/delay.c b/arch/openrisc/lib/delay.c index c82b09f4a106..8b13fdf43ec6 100644 --- a/arch/openrisc/lib/delay.c +++ b/arch/openrisc/lib/delay.c @@ -16,8 +16,9 @@ */ #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/init.h> +#include <asm/param.h> #include <asm/delay.h> #include <asm/timex.h> #include <asm/processor.h> diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index 451906d78136..7569627a032b 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h @@ -6,6 +6,8 @@ #if !defined(__ASSEMBLY__) extern int pdc_type; +extern unsigned long parisc_cell_num; /* cell number the CPU runs on (PAT) */ +extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT) */ /* Values for pdc_type */ #define PDC_TYPE_ILLEGAL -1 @@ -143,6 +145,18 @@ struct pdc_btlb_info { /* PDC_BLOCK_TLB, return of PDC_BTLB_INFO */ #endif /* !CONFIG_PA20 */ +struct pdc_mem_retinfo { /* PDC_MEM/PDC_MEM_MEMINFO (return info) */ + unsigned long pdt_size; + unsigned long pdt_entries; + unsigned long pdt_status; + unsigned long first_dbe_loc; + unsigned long good_mem; +}; + +struct pdc_mem_read_pdt { /* PDC_MEM/PDC_MEM_READ_PDT (return info) */ + unsigned long pdt_entries; +}; + #ifdef CONFIG_64BIT struct pdc_memory_table_raddr { /* PDC_MEM/PDC_MEM_TABLE (return info) */ unsigned long entries_returned; @@ -301,6 +315,10 @@ int pdc_get_initiator(struct hardware_path *, struct pdc_initiator *); int pdc_tod_read(struct pdc_tod *tod); int pdc_tod_set(unsigned long sec, unsigned long usec); +void pdc_pdt_init(void); /* in pdt.c */ +int pdc_mem_pdt_info(struct pdc_mem_retinfo *rinfo); +int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *rpdt_read, + unsigned long *pdt_entries_ptr); #ifdef CONFIG_64BIT int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr, struct pdc_memory_table *tbl, unsigned long entries); diff --git a/arch/parisc/include/asm/pdcpat.h b/arch/parisc/include/asm/pdcpat.h index e1d289092705..0ef789e41555 100644 --- a/arch/parisc/include/asm/pdcpat.h +++ b/arch/parisc/include/asm/pdcpat.h @@ -147,9 +147,9 @@ #define PDC_PAT_MEM_CELL_CLEAR 6L /* Clear PDT For Cell */ #define PDC_PAT_MEM_CELL_READ 7L /* Read PDT entries For Cell */ #define PDC_PAT_MEM_CELL_RESET 8L /* Reset clear bit For Cell */ -#define PDC_PAT_MEM_SETGM 9L /* Set Golden Memory value */ -#define PDC_PAT_MEM_ADD_PAGE 10L /* ADDs a page to the cell */ -#define PDC_PAT_MEM_ADDRESS 11L /* Get Physical Location From */ +#define PDC_PAT_MEM_SETGM 9L /* Set Good Memory value */ +#define PDC_PAT_MEM_ADD_PAGE 10L /* ADDs a page to the cell */ +#define PDC_PAT_MEM_ADDRESS 11L /* Get Physical Location From */ /* Memory Address */ #define PDC_PAT_MEM_GET_TXT_SIZE 12L /* Get Formatted Text Size */ #define PDC_PAT_MEM_GET_PD_TXT 13L /* Get PD Formatted Text */ @@ -212,6 +212,23 @@ struct pdc_pat_cpu_num { unsigned long cpu_loc; }; +struct pdc_pat_mem_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_INFO (return info) */ + unsigned int ke; /* bit 0: memory inside good memory? */ + unsigned int current_pdt_entries:16; + unsigned int max_pdt_entries:16; + unsigned long Cs_bitmap; + unsigned long Ic_bitmap; + unsigned long good_mem; + unsigned long first_dbe_loc; /* first location of double bit error */ + unsigned long clear_time; /* last PDT clear time (since Jan 1970) */ +}; + +struct pdc_pat_mem_read_pd_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_READ */ + unsigned long actual_count_bytes; + unsigned long pdt_entries; +}; + + struct pdc_pat_pd_addr_map_entry { unsigned char entry_type; /* 1 = Memory Descriptor Entry Type */ unsigned char reserve1[5]; @@ -290,18 +307,19 @@ extern int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsign extern int pdc_pat_cell_num_to_loc(void *, unsigned long); extern int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, unsigned long hpa); +extern int pdc_pat_cpu_stop_cpu(unsigned long hpa, unsigned long hpa_vec); extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, unsigned long count, unsigned long offset); - extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *val); extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val); - -/* Flag to indicate this is a PAT box...don't use this unless you -** really have to...it might go away some day. -*/ -extern int pdc_pat; /* arch/parisc/kernel/inventory.c */ +extern int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo); +extern int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, + unsigned long *pdt_entries_ptr, unsigned long max_entries); +extern int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, + unsigned long *pdt_entries_ptr, unsigned long count, + unsigned long offset); #endif /* __ASSEMBLY__ */ diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index 3a4ed9f91d57..71ca86cb0f16 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h @@ -511,6 +511,9 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, #define pte_same(A,B) (pte_val(A) == pte_val(B)) +struct seq_file; +extern void arch_report_meminfo(struct seq_file *m); + #endif /* !__ASSEMBLY__ */ diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index a3661ee6b060..ea4e6ae091d0 100644 --- a/arch/parisc/include/asm/processor.h +++ b/arch/parisc/include/asm/processor.h @@ -103,6 +103,8 @@ struct cpuinfo_parisc { unsigned long bh_count; /* number of times bh was invoked */ unsigned long fp_rev; unsigned long fp_model; + unsigned long cpu_num; /* CPU number from PAT firmware */ + unsigned long cpu_loc; /* CPU location from PAT firmware */ unsigned int state; struct parisc_device *dev; unsigned long loops_per_jiffy; diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index 6b113f39f30c..c3e114f67485 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -69,17 +69,6 @@ struct exception_table_entry { ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1) /* - * The page fault handler stores, in a per-cpu area, the following information - * if a fixup routine is available. - */ -struct exception_data { - unsigned long fault_ip; - unsigned long fault_gp; - unsigned long fault_space; - unsigned long fault_addr; -}; - -/* * load_sr2() preloads the space register %%sr2 - based on the value of * get_fs() - with either a value of 0 to access kernel space (KERNEL_DS which * is 0), or with the current value of %%sr3 to access user space (USER_DS) diff --git a/arch/parisc/include/uapi/asm/pdc.h b/arch/parisc/include/uapi/asm/pdc.h index 0609ff117f67..1f30b49772aa 100644 --- a/arch/parisc/include/uapi/asm/pdc.h +++ b/arch/parisc/include/uapi/asm/pdc.h @@ -131,12 +131,12 @@ #define PDC_TLB_SETUP 1 /* set up miss handling */ #define PDC_MEM 20 /* Manage memory */ -#define PDC_MEM_MEMINFO 0 -#define PDC_MEM_ADD_PAGE 1 -#define PDC_MEM_CLEAR_PDT 2 -#define PDC_MEM_READ_PDT 3 -#define PDC_MEM_RESET_CLEAR 4 -#define PDC_MEM_GOODMEM 5 +#define PDC_MEM_MEMINFO 0 /* Return PDT info */ +#define PDC_MEM_ADD_PAGE 1 /* Add page to PDT */ +#define PDC_MEM_CLEAR_PDT 2 /* Clear PDT */ +#define PDC_MEM_READ_PDT 3 /* Read PDT entry */ +#define PDC_MEM_RESET_CLEAR 4 /* Reset PDT clear flag */ +#define PDC_MEM_GOODMEM 5 /* Set good_mem value */ #define PDC_MEM_TABLE 128 /* Non contig mem map (sprockets) */ #define PDC_MEM_RETURN_ADDRESS_TABLE PDC_MEM_TABLE #define PDC_MEM_GET_MEMORY_SYSTEM_TABLES_SIZE 131 diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 69a11183d48d..c4294df69fb6 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -4,7 +4,7 @@ extra-y := head.o vmlinux.lds -obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ +obj-y := cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \ pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ ptrace.o hardware.o inventory.o drivers.o \ signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \ diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index 1c4fe61a592b..dfff8a0d6fd1 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c @@ -298,11 +298,6 @@ int main(void) DEFINE(HUGEPAGE_SIZE, PAGE_SIZE); #endif BLANK(); - DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip)); - DEFINE(EXCDATA_GP, offsetof(struct exception_data, fault_gp)); - DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space)); - DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr)); - BLANK(); DEFINE(ASM_PDC_RESULT_SIZE, NUM_PDC_RESULT * sizeof(unsigned long)); BLANK(); return 0; diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 9d797ae4fa22..39fe2e296607 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -957,6 +957,41 @@ int pdc_tod_read(struct pdc_tod *tod) } EXPORT_SYMBOL(pdc_tod_read); +int pdc_mem_pdt_info(struct pdc_mem_retinfo *rinfo) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&pdc_lock, flags); + retval = mem_pdc_call(PDC_MEM, PDC_MEM_MEMINFO, __pa(pdc_result), 0); + convert_to_wide(pdc_result); + memcpy(rinfo, pdc_result, sizeof(*rinfo)); + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} + +int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *pret, + unsigned long *pdt_entries_ptr) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&pdc_lock, flags); + retval = mem_pdc_call(PDC_MEM, PDC_MEM_READ_PDT, __pa(pdc_result), + __pa(pdc_result2)); + if (retval == PDC_OK) { + convert_to_wide(pdc_result); + memcpy(pret, pdc_result, sizeof(*pret)); + convert_to_wide(pdc_result2); + memcpy(pdt_entries_ptr, pdc_result2, + pret->pdt_entries * sizeof(*pdt_entries_ptr)); + } + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} + /** * pdc_tod_set - Set the Time-Of-Day clock. * @sec: The number of seconds since epoch. @@ -1273,6 +1308,28 @@ int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, unsigned long hpa) } /** + * pdc_pat_cpu_stop_cpu - Stop current cpu. + * @hpa: The Hard Physical Address of the CPU which should be informed when + * current cpu has stopped. + * @hpa_vec: Mask of interrupts which should be signalled on CPU at @hpa. + * + * Stop the CPU in which the call is made. Flushes caches and purges TLB and + * places CPU in a firmware loop. If the CPU is the last in a cell, an + * interrupt message is sent to the CPU at @hpa. + */ +int pdc_pat_cpu_stop_cpu(unsigned long hpa, unsigned long hpa_vec) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&pdc_lock, flags); + retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_STOP, hpa, hpa_vec); + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} + +/** * pdc_pat_get_irt_size - Retrieve the number of entries in the cell's interrupt table. * @num_entries: The return value. * @cell_num: The target cell. @@ -1383,6 +1440,79 @@ int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val) return retval; } + +/** + * pdc_pat_mem_pdc_info - Retrieve information about page deallocation table + * @rinfo: memory pdt information + * + */ +int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&pdc_lock, flags); + retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_PD_INFO, + __pa(&pdc_result)); + if (retval == PDC_OK) + memcpy(rinfo, &pdc_result, sizeof(*rinfo)); + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} + +/** + * pdc_pat_mem_read_cell_pdt - Read PDT entries from (old) PAT firmware + * @pret: array of PDT entries + * @pdt_entries_ptr: ptr to hold number of PDT entries + * @max_entries: maximum number of entries to be read + * + */ +int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, + unsigned long *pdt_entries_ptr, unsigned long max_entries) +{ + int retval; + unsigned long flags, entries; + + spin_lock_irqsave(&pdc_lock, flags); + /* PDC_PAT_MEM_CELL_READ is available on early PAT machines only */ + retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_READ, + __pa(&pdc_result), parisc_cell_num, __pa(&pdc_result2)); + + if (retval == PDC_OK) { + /* build up return value as for PDC_PAT_MEM_PD_READ */ + entries = min(pdc_result[0], max_entries); + pret->pdt_entries = entries; + pret->actual_count_bytes = entries * sizeof(unsigned long); + memcpy(pdt_entries_ptr, &pdc_result2, pret->actual_count_bytes); + } + + spin_unlock_irqrestore(&pdc_lock, flags); + WARN_ON(retval == PDC_OK && pdc_result[0] > max_entries); + + return retval; +} +/** + * pdc_pat_mem_read_pd_pdt - Read PDT entries from (newer) PAT firmware + * @pret: array of PDT entries + * @pdt_entries_ptr: ptr to hold number of PDT entries + * + */ +int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, + unsigned long *pdt_entries_ptr, unsigned long count, + unsigned long offset) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&pdc_lock, flags); + retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_PD_READ, + __pa(&pret), __pa(pdt_entries_ptr), + count, offset); + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} #endif /* CONFIG_64BIT */ diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c index c9789d9c73b4..b0fe19ac4d78 100644 --- a/arch/parisc/kernel/inventory.c +++ b/arch/parisc/kernel/inventory.c @@ -40,6 +40,11 @@ int pdc_type __read_mostly = PDC_TYPE_ILLEGAL; +/* cell number and location (PAT firmware only) */ +unsigned long parisc_cell_num __read_mostly; +unsigned long parisc_cell_loc __read_mostly; + + void __init setup_pdc(void) { long status; @@ -78,6 +83,10 @@ void __init setup_pdc(void) if (status == PDC_OK) { pdc_type = PDC_TYPE_PAT; pr_cont("64 bit PAT.\n"); + parisc_cell_num = cell_info.cell_num; + parisc_cell_loc = cell_info.cell_loc; + pr_info("PAT: Running on cell %lu and location %lu.\n", + parisc_cell_num, parisc_cell_loc); return; } #endif diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c new file mode 100644 index 000000000000..f3a797e670b0 --- /dev/null +++ b/arch/parisc/kernel/pdt.c @@ -0,0 +1,143 @@ +/* + * Page Deallocation Table (PDT) support + * + * The Page Deallocation Table (PDT) holds a table with pointers to bad + * memory (broken RAM modules) which is maintained by firmware. + * + * Copyright 2017 by Helge Deller <deller@gmx.de> + * + * TODO: + * - check regularily for new bad memory + * - add userspace interface with procfs or sysfs + * - increase number of PDT entries dynamically + */ + +#include <linux/memblock.h> +#include <linux/seq_file.h> + +#include <asm/pdc.h> +#include <asm/pdcpat.h> +#include <asm/sections.h> +#include <asm/pgtable.h> + +enum pdt_access_type { + PDT_NONE, + PDT_PDC, + PDT_PAT_NEW, + PDT_PAT_OLD +}; + +static enum pdt_access_type pdt_type; + +/* global PDT status information */ +static struct pdc_mem_retinfo pdt_status; + +#define MAX_PDT_TABLE_SIZE PAGE_SIZE +#define MAX_PDT_ENTRIES (MAX_PDT_TABLE_SIZE / sizeof(unsigned long)) +static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss; + + +/* report PDT entries via /proc/meminfo */ +void arch_report_meminfo(struct seq_file *m) +{ + if (pdt_type == PDT_NONE) + return; + + seq_printf(m, "PDT_max_entries: %7lu\n", + pdt_status.pdt_size); + seq_printf(m, "PDT_cur_entries: %7lu\n", + pdt_status.pdt_entries); +} + +/* + * pdc_pdt_init() + * + * Initialize kernel PDT structures, read initial PDT table from firmware, + * report all current PDT entries and mark bad memory with memblock_reserve() + * to avoid that the kernel will use broken memory areas. + * + */ +void __init pdc_pdt_init(void) +{ + int ret, i; + unsigned long entries; + struct pdc_mem_read_pdt pdt_read_ret; + + if (is_pdc_pat()) { + struct pdc_pat_mem_retinfo pat_rinfo; + + pdt_type = PDT_PAT_NEW; + ret = pdc_pat_mem_pdt_info(&pat_rinfo); + pdt_status.pdt_size = pat_rinfo.max_pdt_entries; + pdt_status.pdt_entries = pat_rinfo.current_pdt_entries; + pdt_status.pdt_status = 0; + pdt_status.first_dbe_loc = pat_rinfo.first_dbe_loc; + pdt_status.good_mem = pat_rinfo.good_mem; + } else { + pdt_type = PDT_PDC; + ret = pdc_mem_pdt_info(&pdt_status); + } + + if (ret != PDC_OK) { + pdt_type = PDT_NONE; + pr_info("PDT: Firmware does not provide any page deallocation" + " information.\n"); + return; + } + + entries = pdt_status.pdt_entries; + WARN_ON(entries > MAX_PDT_ENTRIES); + + pr_info("PDT: size %lu, entries %lu, status %lu, dbe_loc 0x%lx," + " good_mem %lu\n", + pdt_status.pdt_size, pdt_status.pdt_entries, + pdt_status.pdt_status, pdt_status.first_dbe_loc, + pdt_status.good_mem); + + if (entries == 0) { + pr_info("PDT: Firmware reports all memory OK.\n"); + return; + } + + if (pdt_status.first_dbe_loc && + pdt_status.first_dbe_loc <= __pa((unsigned long)&_end)) + pr_crit("CRITICAL: Bad memory inside kernel image memory area!\n"); + + pr_warn("PDT: Firmware reports %lu entries of faulty memory:\n", + entries); + + if (pdt_type == PDT_PDC) + ret = pdc_mem_pdt_read_entries(&pdt_read_ret, pdt_entry); + else { +#ifdef CONFIG_64BIT + struct pdc_pat_mem_read_pd_retinfo pat_pret; + + ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, + MAX_PDT_ENTRIES); + if (ret != PDC_OK) { + pdt_type = PDT_PAT_OLD; + ret = pdc_pat_mem_read_pd_pdt(&pat_pret, pdt_entry, + MAX_PDT_TABLE_SIZE, 0); + } +#else + ret = PDC_BAD_PROC; +#endif + } + + if (ret != PDC_OK) { + pdt_type = PDT_NONE; + pr_debug("PDT type %d, retval = %d\n", pdt_type, ret); + return; + } + + for (i = 0; i < pdt_status.pdt_entries; i++) { + if (i < 20) + pr_warn("PDT: BAD PAGE #%d at 0x%08lx (error_type = %lu)\n", + i, + pdt_entry[i] & PAGE_MASK, + pdt_entry[i] & 1); + + /* mark memory page bad */ + memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE); + } +} diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 4516a5b53f38..40ea7b432f00 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -58,6 +58,7 @@ #include <asm/asm-offsets.h> #include <asm/assembly.h> #include <asm/pdc.h> +#include <asm/pdcpat.h> #include <asm/pdc_chassis.h> #include <asm/pgalloc.h> #include <asm/unwind.h> @@ -116,6 +117,19 @@ void machine_halt(void) ** The LED/ChassisCodes are updated by the led_halt() ** function, called by the reboot notifier chain. */ + + /* prevent soft lockup/stalled CPU messages for endless loop. */ + rcu_sysrq_start(); + + /* stop all CPUs but the current one. */ + smp_send_stop(); + + /* stop current CPU if possible. */ + if (is_pdc_pat()) + pdc_pat_cpu_stop_cpu(0, 0); + + /* wait until power down. */ + while (1) ; } void (*chassis_power_off)(void); @@ -143,9 +157,7 @@ void machine_power_off(void) printk(KERN_EMERG "System shut down completed.\n" "Please power this system off now."); - /* prevent soft lockup/stalled CPU messages for endless loop. */ - rcu_sysrq_start(); - for (;;); + machine_halt(); } void (*pm_power_off)(void) = machine_power_off; diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index 85de47f4eb59..0ab32779dfa7 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -94,7 +94,7 @@ static int processor_probe(struct parisc_device *dev) unsigned long txn_addr; unsigned long cpuid; struct cpuinfo_parisc *p; - struct pdc_pat_cpu_num cpu_info __maybe_unused; + struct pdc_pat_cpu_num cpu_info = { }; #ifdef CONFIG_SMP if (num_online_cpus() >= nr_cpu_ids) { @@ -113,6 +113,7 @@ static int processor_probe(struct parisc_device *dev) */ cpuid = boot_cpu_data.cpu_count; txn_addr = dev->hpa.start; /* for legacy PDC */ + cpu_info.cpu_num = cpu_info.cpu_loc = cpuid; #ifdef CONFIG_64BIT if (is_pdc_pat()) { @@ -180,6 +181,8 @@ static int processor_probe(struct parisc_device *dev) p->hpa = dev->hpa.start; /* save CPU hpa */ p->cpuid = cpuid; /* save CPU id */ p->txn_addr = txn_addr; /* save CPU IRQ address */ + p->cpu_num = cpu_info.cpu_num; + p->cpu_loc = cpu_info.cpu_loc; #ifdef CONFIG_SMP /* ** FIXME: review if any other initialization is clobbered diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 63365106ea19..a2d844a84163 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -42,6 +42,7 @@ #include <asm/irq.h> /* for CPU_IRQ_REGION and friends */ #include <asm/mmu_context.h> #include <asm/page.h> +#include <asm/pdcpat.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/processor.h> @@ -112,6 +113,8 @@ halt_processor(void) /* REVISIT : does PM *know* this CPU isn't available? */ set_cpu_online(smp_processor_id(), false); local_irq_disable(); + if (is_pdc_pat()) + pdc_pat_cpu_stop_cpu(0, 0); for (;;) ; } diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 89421df70160..2d956aa0a38a 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -243,14 +243,30 @@ void __init time_init(void) static int __init init_cr16_clocksource(void) { /* - * The cr16 interval timers are not syncronized across CPUs, so mark - * them unstable and lower rating on SMP systems. + * The cr16 interval timers are not syncronized across CPUs on + * different sockets, so mark them unstable and lower rating on + * multi-socket SMP systems. */ if (num_online_cpus() > 1) { - clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; - clocksource_cr16.rating = 0; + int cpu; + unsigned long cpu0_loc; + cpu0_loc = per_cpu(cpu_data, 0).cpu_loc; + + for_each_online_cpu(cpu) { + if (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc) + continue; + + clocksource_cr16.name = "cr16_unstable"; + clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; + clocksource_cr16.rating = 0; + break; + } } + /* XXX: We may want to mark sched_clock stable here if cr16 clocks are + * in sync: + * (clocksource_cr16.flags == CLOCK_SOURCE_IS_CONTINUOUS) */ + /* register at clocksource framework */ clocksource_register_hz(&clocksource_cr16, 100 * PAGE0->mem_10msec); diff --git a/arch/parisc/lib/lusercopy.S b/arch/parisc/lib/lusercopy.S index 85c28bb80fb7..d4fe19806d57 100644 --- a/arch/parisc/lib/lusercopy.S +++ b/arch/parisc/lib/lusercopy.S @@ -56,12 +56,6 @@ mtsp %r1,%sr1 .endm - .macro fixup_branch lbl - ldil L%\lbl, %r1 - ldo R%\lbl(%r1), %r1 - bv %r0(%r1) - .endm - /* * unsigned long lclear_user(void *to, unsigned long n) * @@ -82,16 +76,16 @@ $lclu_loop: $lclu_done: bv %r0(%r2) copy %r25,%r28 - .exit -ENDPROC_CFI(lclear_user) - .section .fixup,"ax" -2: fixup_branch $lclu_done - ldo 1(%r25),%r25 - .previous +2: b $lclu_done + ldo 1(%r25),%r25 ASM_EXCEPTIONTABLE_ENTRY(1b,2b) + .exit +ENDPROC_CFI(lclear_user) + + .procend /* @@ -122,16 +116,15 @@ $lslen_done: $lslen_nzero: b $lslen_done ldo 1(%r26),%r26 /* special case for N == 0 */ -ENDPROC_CFI(lstrnlen_user) - .section .fixup,"ax" -3: fixup_branch $lslen_done +3: b $lslen_done copy %r24,%r26 /* reset r26 so 0 is returned on fault */ - .previous ASM_EXCEPTIONTABLE_ENTRY(1b,3b) ASM_EXCEPTIONTABLE_ENTRY(2b,3b) +ENDPROC_CFI(lstrnlen_user) + .procend diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 32ec22146141..fdc34cf4eb0e 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -29,8 +29,6 @@ #define BITSSET 0x1c0 /* for identifying LDCW */ -DEFINE_PER_CPU(struct exception_data, exception_data); - int show_unhandled_signals = 1; /* @@ -143,13 +141,6 @@ int fixup_exception(struct pt_regs *regs) fix = search_exception_tables(regs->iaoq[0]); if (fix) { - struct exception_data *d; - d = this_cpu_ptr(&exception_data); - d->fault_ip = regs->iaoq[0]; - d->fault_gp = regs->gr[27]; - d->fault_space = regs->isr; - d->fault_addr = regs->ior; - /* * Fix up get_user() and put_user(). * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 66f3a6345105..1ca9a2b4239f 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -381,6 +381,9 @@ static void __init setup_bootmem(void) request_resource(res, &data_resource); } request_resource(&sysram_resources[0], &pdcdata_resource); + + /* Initialize Page Deallocation Table (PDT) and check for bad memory. */ + pdc_pdt_init(); } static int __init parisc_text_address(unsigned long vaddr) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index f7c8f9972f61..0153275e9f75 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -208,6 +208,7 @@ config PPC select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_SYSCALL_TRACEPOINTS select HAVE_VIRT_CPU_ACCOUNTING + select HAVE_IRQ_TIME_ACCOUNTING select IRQ_DOMAIN select IRQ_FORCED_THREADING select MODULES_USE_ELF_RELA @@ -454,6 +455,17 @@ config PPC_TRANSACTIONAL_MEM ---help--- Support user-mode Transactional Memory on POWERPC. +config LD_HEAD_STUB_CATCH + bool "Reserve 256 bytes to cope with linker stubs in HEAD text" if EXPERT + depends on PPC64 + default n + help + Very large kernels can cause linker branch stubs to be generated by + code in head_64.S, which moves the head text sections out of their + specified location. This option can work around the problem. + + If unsure, say "N". + config DISABLE_MPROFILE_KERNEL bool "Disable use of mprofile-kernel for kernel tracing" depends on PPC64 && CPU_LITTLE_ENDIAN diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 3e0f0e1fadef..8d4ed73d5490 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -98,6 +98,7 @@ endif LDFLAGS_vmlinux-y := -Bstatic LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y) +LDFLAGS_vmlinux += $(call ld-option,--orphan-handling=warn) ifeq ($(CONFIG_PPC64),y) ifeq ($(call cc-option-yn,-mcmodel=medium),y) @@ -189,7 +190,17 @@ else CHECKFLAGS += -D__LITTLE_ENDIAN__ endif +ifdef CONFIG_PPC32 KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o +else +ifeq ($(call ld-ifversion, -ge, 225000000, y),y) +# Have the linker provide sfpr if possible. +# There is a corresponding test in arch/powerpc/lib/Makefile +KBUILD_LDFLAGS_MODULE += --save-restore-funcs +else +KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o +endif +endif ifeq ($(CONFIG_476FPE_ERR46),y) KBUILD_LDFLAGS_MODULE += --ppc476-workaround \ diff --git a/arch/powerpc/Makefile.postlink b/arch/powerpc/Makefile.postlink index eccfcc88afae..5db43ebbe2df 100644 --- a/arch/powerpc/Makefile.postlink +++ b/arch/powerpc/Makefile.postlink @@ -10,13 +10,26 @@ __archpost: -include include/config/auto.conf include scripts/Kbuild.include +quiet_cmd_head_check = CHKHEAD $@ + cmd_head_check = $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/head_check.sh "$(NM)" "$@" + quiet_cmd_relocs_check = CHKREL $@ - cmd_relocs_check = $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" +ifdef CONFIG_PPC_BOOK3S_64 + cmd_relocs_check = \ + $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" ; \ + $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$@" +else + cmd_relocs_check = \ + $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" +endif # `@true` prevents complaint when there is nothing to be done vmlinux: FORCE @true +ifdef CONFIG_PPC64 + $(call cmd,head_check) +endif ifdef CONFIG_RELOCATABLE $(call if_changed,relocs_check) endif @@ -25,7 +38,7 @@ endif @true clean: - @true + rm -f .tmp_symbols.txt PHONY += FORCE clean diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index e82f333cc84a..a7814a7b1523 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -95,13 +95,16 @@ libfdtheader := fdt.h libfdt.h libfdt_internal.h $(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o opal.o): \ $(addprefix $(obj)/,$(libfdtheader)) -src-wlib-y := string.S crt0.S crtsavres.S stdio.c decompress.c main.c \ +src-wlib-y := string.S crt0.S stdio.c decompress.c main.c \ $(libfdt) libfdt-wrapper.c \ ns16550.c serial.c simple_alloc.c div64.S util.S \ elf_util.c $(zlib-y) devtree.c stdlib.c \ oflib.c ofconsole.c cuboot.c mpsc.c cpm-serial.c \ uartlite.c mpc52xx-psc.c opal.c src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) += opal-calls.S +ifndef CONFIG_PPC64_BOOT_WRAPPER +src-wlib-y += crtsavres.S +endif src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c diff --git a/arch/powerpc/boot/crtsavres.S b/arch/powerpc/boot/crtsavres.S index f3d9b35c07d4..085fb2b9a8b8 100644 --- a/arch/powerpc/boot/crtsavres.S +++ b/arch/powerpc/boot/crtsavres.S @@ -37,12 +37,13 @@ * the executable file might be covered by the GNU General Public License. */ +#ifdef __powerpc64__ +#error "On PPC64, FPR save/restore functions are provided by the linker." +#endif + .file "crtsavres.S" .section ".text" -/* On PowerPC64 Linux, these functions are provided by the linker. */ -#ifndef __powerpc64__ - #define _GLOBAL(name) \ .type name,@function; \ .globl name; \ @@ -230,4 +231,3 @@ _GLOBAL(_rest32gpr_31_x) mtlr 0 mr 1,11 blr -#endif diff --git a/arch/powerpc/boot/dts/fsp2.dts b/arch/powerpc/boot/dts/fsp2.dts new file mode 100644 index 000000000000..475953ada707 --- /dev/null +++ b/arch/powerpc/boot/dts/fsp2.dts @@ -0,0 +1,608 @@ +/* + * Device Tree Source for FSP2 + * + * Copyright 2010,2012 IBM Corp. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without + * any warranty of any kind, whether express or implied. + */ + + +/dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <1>; + model = "ibm,fsp2"; + compatible = "ibm,fsp2"; + dcr-parent = <&{/cpus/cpu@0}>; + + aliases { + ethernet0 = &EMAC0; + ethernet1 = &EMAC1; + serial0 = &UART0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC, 476FSP2"; + reg = <0x0>; + clock-frequency = <0>; /* Filled in by cuboot */ + timebase-frequency = <0>; /* Filled in by cuboot */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + d-cache-size = <32768>; + i-cache-size = <32768>; + dcr-controller; + dcr-access-method = "native"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by + cuboot */ + }; + + clocks { + mmc_clk: mmc_clk { + compatible = "fixed-clock"; + clock-frequency = <50000000>; + clock-output-names = "mmc_clk"; + }; + }; + + UIC0: uic0 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <0>; + dcr-reg = <0x2c0 0x8>; + }; + + /* "interrupts" field is <bit level bit level> + first pair is non-critical, second is critical */ + UIC1_0: uic1_0 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <1>; + dcr-reg = <0x2c8 0x8>; + interrupt-parent = <&UIC0>; + interrupts = <21 0x4 4 0x84>; + }; + + /* PSI and DMA */ + UIC1_1: uic1_1 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <2>; + dcr-reg = <0x350 0x8>; + interrupt-parent = <&UIC0>; + interrupts = <22 0x4 5 0x84>; + }; + + /* Ethernet and USB */ + UIC1_2: uic1_2 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <3>; + dcr-reg = <0x358 0x8>; + interrupt-parent = <&UIC0>; + interrupts = <23 0x4 6 0x84>; + }; + + /* PLB Errors */ + UIC1_3: uic1_3 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <4>; + dcr-reg = <0x360 0x8>; + interrupt-parent = <&UIC0>; + interrupts = <24 0x4 7 0x84>; + }; + + UIC1_4: uic1_4 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <5>; + dcr-reg = <0x368 0x8>; + interrupt-parent = <&UIC0>; + interrupts = <25 0x4 8 0x84>; + }; + + UIC1_5: uic1_5 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <6>; + dcr-reg = <0x370 0x8>; + interrupt-parent = <&UIC0>; + interrupts = <26 0x4 9 0x84>; + }; + + /* 2nd level UICs for FSI */ + UIC2_0: uic2_0 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <7>; + dcr-reg = <0x2d0 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <16 0x4 0 0x84>; + }; + + UIC2_1: uic2_1 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <8>; + dcr-reg = <0x2d8 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <17 0x4 1 0x84>; + }; + + UIC2_2: uic2_2 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <9>; + dcr-reg = <0x2e0 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <18 0x4 2 0x84>; + }; + + UIC2_3: uic2_3 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <10>; + dcr-reg = <0x2e8 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <19 0x4 3 0x84>; + }; + + UIC2_4: uic2_4 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <11>; + dcr-reg = <0x2f0 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <20 0x4 4 0x84>; + }; + + UIC2_5: uic2_5 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <12>; + dcr-reg = <0x2f8 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <21 0x4 5 0x84>; + }; + + UIC2_6: uic2_6 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <13>; + dcr-reg = <0x300 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <22 0x4 6 0x84>; + }; + + UIC2_7: uic2_7 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <14>; + dcr-reg = <0x308 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <23 0x4 7 0x84>; + }; + + UIC2_8: uic2_8 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <15>; + dcr-reg = <0x310 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <24 0x4 8 0x84>; + }; + + UIC2_9: uic2_9 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <16>; + dcr-reg = <0x318 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <25 0x4 9 0x84>; + }; + + UIC2_10: uic2_10 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <17>; + dcr-reg = <0x320 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <26 0x4 10 0x84>; + }; + + UIC2_11: uic2_11 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <18>; + dcr-reg = <0x328 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <27 0x4 11 0x84>; + }; + + UIC2_12: uic2_12 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <19>; + dcr-reg = <0x330 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <28 0x4 12 0x84>; + }; + + UIC2_13: uic2_13 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <20>; + dcr-reg = <0x338 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <29 0x4 13 0x84>; + }; + + UIC2_14: uic2_14 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <21>; + dcr-reg = <0x340 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <30 0x4 14 0x84>; + }; + + UIC2_15: uic2_15 { + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <22>; + dcr-reg = <0x348 0x8>; + interrupt-parent = <&UIC1_0>; + interrupts = <31 0x4 15 0x84>; + }; + + mmc0: sdhci@020c0000 { + compatible = "st,sdhci-stih407", "st,sdhci"; + status = "disabled"; + reg = <0x020c0000 0x20000>; + reg-names = "mmc"; + interrupt-parent = <&UIC1_3>; + interrupts = <21 0x4 22 0x4>; + interrupt-names = "mmcirq"; + pinctrl-names = "default"; + pinctrl-0 = <>; + clock-names = "mmc"; + clocks = <&mmc_clk>; + }; + + plb6 { + compatible = "ibm,plb6"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + + MCW0: memory-controller-wrapper { + compatible = "ibm,cw-476fsp2"; + dcr-reg = <0x11111800 0x40>; + }; + + MCIF0: memory-controller { + compatible = "ibm,sdram-476fsp2", "ibm,sdram-4xx-ddr3"; + dcr-reg = <0x11120000 0x10000>; + mcer-device = <&MCW0>; + interrupt-parent = <&UIC0>; + interrupts = <10 0x84 /* ECC UE */ + 11 0x84>; /* ECC CE */ + }; + }; + + plb4 { + compatible = "ibm,plb4"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00000000 0x00000010 0x00000000 0x80000000 + 0x80000000 0x00000010 0x80000000 0x80000000>; + clock-frequency = <333333334>; + + plb6-system-hung-irq { + compatible = "ibm,bus-error-irq"; + #interrupt-cells = <2>; + interrupt-parent = <&UIC0>; + interrupts = <0 0x84>; + }; + + l2-error-irq { + compatible = "ibm,bus-error-irq"; + #interrupt-cells = <2>; + interrupt-parent = <&UIC0>; + interrupts = <20 0x84>; + }; + + plb6-plb4-irq { + compatible = "ibm,bus-error-irq"; + #interrupt-cells = <2>; + interrupt-parent = <&UIC0>; + interrupts = <1 0x84>; + }; + + plb4-ahb-irq { + compatible = "ibm,bus-error-irq"; + #interrupt-cells = <2>; + interrupt-parent = <&UIC1_3>; + interrupts = <20 0x84>; + }; + + opbd-error-irq { + compatible = "ibm,opbd-error-irq"; + #interrupt-cells = <2>; + interrupt-parent = <&UIC1_4>; + interrupts = <5 0x84>; + }; + + cmu-error-irq { + compatible = "ibm,cmu-error-irq"; + #interrupt-cells = <2>; + interrupt-parent = <&UIC0>; + interrupts = <28 0x84>; + }; + + conf-error-irq { + compatible = "ibm,conf-error-irq"; + #interrupt-cells = <2>; + interrupt-parent = <&UIC1_4>; + interrupts = <11 0x84>; + }; + + mc-ue-irq { + compatible = "ibm,mc-ue-irq"; + #interrupt-cells = <2>; + interrupt-parent = <&UIC0>; + interrupts = <10 0x84>; + }; + + reset-warning-irq { + compatible = "ibm,reset-warning-irq"; + #interrupt-cells = <2>; + interrupt-parent = <&UIC0>; + interrupts = <17 0x84>; + }; + + MAL0: mcmal0 { + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + compatible = "ibm,mcmal"; + dcr-reg = <0x80 0x80>; + num-tx-chans = <1>; + num-rx-chans = <1>; + interrupt-parent = <&MAL0>; + interrupts = <0 1 2 3 4>; + /* index interrupt-parent interrupt# type */ + interrupt-map = </*TXEOB*/ 0 &UIC1_2 4 0x4 + /*RXEOB*/ 1 &UIC1_2 3 0x4 + /*SERR*/ 2 &UIC1_2 7 0x4 + /*TXDE*/ 3 &UIC1_2 6 0x4 + /*RXDE*/ 4 &UIC1_2 5 0x4>; + }; + + MAL1: mcmal1 { + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + compatible = "ibm,mcmal"; + dcr-reg = <0x100 0x80>; + num-tx-chans = <1>; + num-rx-chans = <1>; + interrupt-parent = <&MAL1>; + interrupts = <0 1 2 3 4>; + /* index interrupt-parent interrupt# type */ + interrupt-map = </*TXEOB*/ 0 &UIC1_2 12 0x4 + /*RXEOB*/ 1 &UIC1_2 11 0x4 + /*SERR*/ 2 &UIC1_2 15 0x4 + /*TXDE*/ 3 &UIC1_2 14 0x4 + /*RXDE*/ 4 &UIC1_2 13 0x4>; + }; + + opb { + compatible = "ibm,opb"; + #address-cells = <1>; + #size-cells = <1>; + ranges; // pass-thru to parent bus + clock-frequency = <83333334>; + + EMAC0: ethernet@b0000000 { + linux,network-index = <0>; + device_type = "network"; + compatible = "ibm,emac4sync"; + has-inverted-stacr-oc; + interrupt-parent = <&UIC1_2>; + interrupts = <1 0x4 0 0x4>; + reg = <0xb0000000 0x100>; + local-mac-address = [000000000000]; /* Filled in by + cuboot */ + mal-device = <&MAL0>; + mal-tx-channel = <0>; + mal-rx-channel = <0>; + cell-index = <0>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <4096>; + rx-fifo-size-gige = <16384>; + tx-fifo-size-gige = <8192>; + phy-address = <1>; + phy-mode = "rgmii"; + phy-map = <00000003>; + rgmii-device = <&RGMII>; + rgmii-channel = <0>; + }; + + EMAC1: ethernet@b0000100 { + linux,network-index = <1>; + device_type = "network"; + compatible = "ibm,emac4sync"; + has-inverted-stacr-oc; + interrupt-parent = <&UIC1_2>; + interrupts = <9 0x4 8 0x4>; + reg = <0xb0000100 0x100>; + local-mac-address = [000000000000]; /* Filled in by + cuboot */ + mal-device = <&MAL1>; + mal-tx-channel = <0>; + mal-rx-channel = <0>; + cell-index = <1>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <4096>; + rx-fifo-size-gige = <16384>; + tx-fifo-size-gige = <8192>; + phy-address = <2>; + phy-mode = "rgmii"; + phy-map = <00000003>; + rgmii-device = <&RGMII>; + rgmii-channel = <1>; + }; + + RGMII: rgmii@b0000600 { + compatible = "ibm,rgmii"; + has-mdio; + reg = <0xb0000600 0x8>; + }; + + UART0: serial@b0020000 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xb0020000 0x8>; + virtual-reg = <0xb0020000>; + clock-frequency = <20833333>; + current-speed = <115200>; + interrupt-parent = <&UIC0>; + interrupts = <31 0x4>; + }; + }; + + OHCI1: ohci@02040000 { + compatible = "ohci-le"; + reg = <0x02040000 0xa0>; + interrupt-parent = <&UIC1_3>; + interrupts = <28 0x8 29 0x8>; + }; + + OHCI2: ohci@02080000 { + compatible = "ohci-le"; + reg = <0x02080000 0xa0>; + interrupt-parent = <&UIC1_3>; + interrupts = <30 0x8 31 0x8>; + }; + + EHCI: ehci@02000000 { + compatible = "usb-ehci"; + reg = <0x02000000 0xa4>; + interrupt-parent = <&UIC1_3>; + interrupts = <23 0x4>; + }; + + }; + + chosen { + linux,stdout-path = "/plb/opb/serial@b0020000"; + bootargs = "console=ttyS0,115200 rw log_buf_len=32768 debug"; + }; +}; diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts index b1d329246b08..e41b88a5eaee 100644 --- a/arch/powerpc/boot/dts/sequoia.dts +++ b/arch/powerpc/boot/dts/sequoia.dts @@ -229,7 +229,7 @@ }; partition@84000 { label = "user"; - reg = <0x00000000 0x01f7c000>; + reg = <0x00084000 0x01f7c000>; }; }; }; diff --git a/arch/powerpc/boot/ppc_asm.h b/arch/powerpc/boot/ppc_asm.h index b03373d8b386..68e388ee94fe 100644 --- a/arch/powerpc/boot/ppc_asm.h +++ b/arch/powerpc/boot/ppc_asm.h @@ -67,13 +67,15 @@ #define MSR_LE 0x0000000000000001 #define FIXUP_ENDIAN \ - tdi 0, 0, 0x48; /* Reverse endian of b . + 8 */ \ - b $+36; /* Skip trampoline if endian is good */ \ - .long 0x05009f42; /* bcl 20,31,$+4 */ \ - .long 0xa602487d; /* mflr r10 */ \ - .long 0x1c004a39; /* addi r10,r10,28 */ \ + tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ + b $+44; /* Skip trampoline if endian is good */ \ .long 0xa600607d; /* mfmsr r11 */ \ .long 0x01006b69; /* xori r11,r11,1 */ \ + .long 0x00004039; /* li r10,0 */ \ + .long 0x6401417d; /* mtmsrd r10,1 */ \ + .long 0x05009f42; /* bcl 20,31,$+4 */ \ + .long 0xa602487d; /* mflr r10 */ \ + .long 0x14004a39; /* addi r10,r10,20 */ \ .long 0xa6035a7d; /* mtsrr0 r10 */ \ .long 0xa6037b7d; /* mtsrr1 r11 */ \ .long 0x2400004c /* rfid */ diff --git a/arch/powerpc/configs/44x/fsp2_defconfig b/arch/powerpc/configs/44x/fsp2_defconfig new file mode 100644 index 000000000000..e8e6a6999852 --- /dev/null +++ b/arch/powerpc/configs/44x/fsp2_defconfig @@ -0,0 +1,126 @@ +CONFIG_44x=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_CROSS_MEMORY_ATTACH is not set +# CONFIG_FHANDLE is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_KALLSYMS_ALL=y +CONFIG_BPF_SYSCALL=y +CONFIG_EMBEDDED=y +CONFIG_PROFILING=y +CONFIG_OPROFILE=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_PPC_47x=y +# CONFIG_EBONY is not set +CONFIG_FSP2=y +CONFIG_476FPE_ERR46=y +CONFIG_SWIOTLB=y +CONFIG_KEXEC=y +CONFIG_CRASH_DUMP=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on rw" +# CONFIG_SUSPEND is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_IPV6 is not set +CONFIG_VLAN_8021Q=m +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_CONNECTOR=y +CONFIG_MTD=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=35000 +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_ATA=y +# CONFIG_SATA_PMP is not set +# CONFIG_ATA_SFF is not set +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_IBM_EMAC=m +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=32 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +CONFIG_I2C_IBM_IIC=y +CONFIG_PTP_1588_CLOCK=y +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_BOOKE_WDT=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y +CONFIG_MMC=y +CONFIG_MMC_DEBUG=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_M41T80=y +CONFIG_EXT2_FS=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_WBUF_VERIFY=y +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_CRAMFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_DEFAULT="n" +CONFIG_XZ_DEC=y +CONFIG_PRINTK_TIME=y +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=3 +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_PCBC=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h index 86eb87382031..7ab95798f170 100644 --- a/arch/powerpc/include/asm/head-64.h +++ b/arch/powerpc/include/asm/head-64.h @@ -49,8 +49,8 @@ * CLOSE_FIXED_SECTION() or elsewhere, there may be something * unexpected being added there. Remove the '. = x_len' line, rebuild, and * check what is pushing the section down. - * - If the build dies in linking, check arch/powerpc/kernel/vmlinux.lds.S - * for instructions. + * - If the build dies in linking, check arch/powerpc/tools/head_check.sh + * comments. * - If the kernel crashes or hangs in very early boot, it could be linker * stubs at the start of the main text. */ @@ -63,11 +63,29 @@ . = 0x0; \ start_##sname: +/* + * .linker_stub_catch section is used to catch linker stubs from being + * inserted in our .text section, above the start_text label (which breaks + * the ABS_ADDR calculation). See kernel/vmlinux.lds.S and tools/head_check.sh + * for more details. We would prefer to just keep a cacheline (0x80), but + * 0x100 seems to be how the linker aligns branch stub groups. + */ +#ifdef CONFIG_LD_HEAD_STUB_CATCH +#define OPEN_TEXT_SECTION(start) \ + .section ".linker_stub_catch","ax",@progbits; \ +linker_stub_catch: \ + . = 0x4; \ + text_start = (start) + 0x100; \ + .section ".text","ax",@progbits; \ + .balign 0x100; \ +start_text: +#else #define OPEN_TEXT_SECTION(start) \ text_start = (start); \ .section ".text","ax",@progbits; \ . = 0x0; \ start_text: +#endif #define ZERO_FIXED_SECTION(sname, start, end) \ sname##_start = (start); \ diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 1c09f8fe2ee8..77f60a0f1405 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -177,6 +177,8 @@ struct paca_struct { * to the sibling threads' paca. */ struct paca_struct **thread_sibling_pacas; + /* The PSSCR value that the kernel requested before going to stop */ + u64 requested_psscr; #endif #ifdef CONFIG_PPC_STD_MMU_64 diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 359c44341761..6baeeb9acd0d 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -770,15 +770,18 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #else #define FIXUP_ENDIAN \ tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ - b $+36; /* Skip trampoline if endian is good */ \ - .long 0x05009f42; /* bcl 20,31,$+4 */ \ - .long 0xa602487d; /* mflr r10 */ \ - .long 0x1c004a39; /* addi r10,r10,28 */ \ + b $+44; /* Skip trampoline if endian is good */ \ .long 0xa600607d; /* mfmsr r11 */ \ .long 0x01006b69; /* xori r11,r11,1 */ \ + .long 0x00004039; /* li r10,0 */ \ + .long 0x6401417d; /* mtmsrd r10,1 */ \ + .long 0x05009f42; /* bcl 20,31,$+4 */ \ + .long 0xa602487d; /* mflr r10 */ \ + .long 0x14004a39; /* addi r10,r10,20 */ \ .long 0xa6035a7d; /* mtsrr0 r10 */ \ .long 0xa6037b7d; /* mtsrr1 r11 */ \ .long 0x2400004c /* rfid */ + #endif /* !CONFIG_PPC_BOOK3E */ #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild index b15bf6bc0e94..0d960ef78a9a 100644 --- a/arch/powerpc/include/uapi/asm/Kbuild +++ b/arch/powerpc/include/uapi/asm/Kbuild @@ -1,2 +1,8 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm + +generic-y += param.h +generic-y += poll.h +generic-y += resource.h +generic-y += sockios.h +generic-y += statfs.h diff --git a/arch/powerpc/include/uapi/asm/param.h b/arch/powerpc/include/uapi/asm/param.h deleted file mode 100644 index 965d45427975..000000000000 --- a/arch/powerpc/include/uapi/asm/param.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/param.h> diff --git a/arch/powerpc/include/uapi/asm/poll.h b/arch/powerpc/include/uapi/asm/poll.h deleted file mode 100644 index c98509d3149e..000000000000 --- a/arch/powerpc/include/uapi/asm/poll.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/poll.h> diff --git a/arch/powerpc/include/uapi/asm/resource.h b/arch/powerpc/include/uapi/asm/resource.h deleted file mode 100644 index 04bc4db8921b..000000000000 --- a/arch/powerpc/include/uapi/asm/resource.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/resource.h> diff --git a/arch/powerpc/include/uapi/asm/sockios.h b/arch/powerpc/include/uapi/asm/sockios.h deleted file mode 100644 index 55cef7675a31..000000000000 --- a/arch/powerpc/include/uapi/asm/sockios.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _ASM_POWERPC_SOCKIOS_H -#define _ASM_POWERPC_SOCKIOS_H - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -/* Socket-level I/O control calls. */ -#define FIOSETOWN 0x8901 -#define SIOCSPGRP 0x8902 -#define FIOGETOWN 0x8903 -#define SIOCGPGRP 0x8904 -#define SIOCATMARK 0x8905 -#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ -#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ - -#endif /* _ASM_POWERPC_SOCKIOS_H */ diff --git a/arch/powerpc/include/uapi/asm/statfs.h b/arch/powerpc/include/uapi/asm/statfs.h deleted file mode 100644 index 5244834583a4..000000000000 --- a/arch/powerpc/include/uapi/asm/statfs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_POWERPC_STATFS_H -#define _ASM_POWERPC_STATFS_H - -#include <asm-generic/statfs.h> - -#endif diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 709e23425317..e15c178ba079 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -742,6 +742,7 @@ int main(void) OFFSET(PACA_THREAD_MASK, paca_struct, thread_mask); OFFSET(PACA_SUBCORE_SIBLING_MASK, paca_struct, subcore_sibling_mask); OFFSET(PACA_SIBLING_PACA_PTRS, paca_struct, thread_sibling_pacas); + OFFSET(PACA_REQ_PSSCR, paca_struct, requested_psscr); #endif DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER); diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index 4898d676dcae..98a6d07ecb5c 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S @@ -31,6 +31,7 @@ * registers for winkle support. */ #define _SDR1 GPR3 +#define _PTCR GPR3 #define _RPR GPR4 #define _SPURR GPR5 #define _PURR GPR6 @@ -39,7 +40,7 @@ #define _AMOR GPR9 #define _WORT GPR10 #define _WORC GPR11 -#define _PTCR GPR12 +#define _LPCR GPR12 #define PSSCR_EC_ESL_MASK_SHIFTED (PSSCR_EC | PSSCR_ESL) >> 16 @@ -55,12 +56,14 @@ save_sprs_to_stack: * here since any thread in the core might wake up first */ BEGIN_FTR_SECTION - mfspr r3,SPRN_PTCR - std r3,_PTCR(r1) /* * Note - SDR1 is dropped in Power ISA v3. Hence not restoring * SDR1 here */ + mfspr r3,SPRN_PTCR + std r3,_PTCR(r1) + mfspr r3,SPRN_LPCR + std r3,_LPCR(r1) FTR_SECTION_ELSE mfspr r3,SPRN_SDR1 std r3,_SDR1(r1) @@ -376,6 +379,7 @@ _GLOBAL(power9_idle_stop) mfspr r5,SPRN_PSSCR andc r5,r5,r4 or r3,r3,r5 + std r3, PACA_REQ_PSSCR(r13) mtspr SPRN_PSSCR,r3 LOAD_REG_ADDR(r5,power_enter_stop) li r4,1 @@ -495,12 +499,22 @@ pnv_restore_hyp_resource_arch300: LOAD_REG_ADDRBASE(r5,pnv_first_deep_stop_state) ld r4,ADDROFF(pnv_first_deep_stop_state)(r5) - mfspr r5,SPRN_PSSCR +BEGIN_FTR_SECTION_NESTED(71) + /* + * Assume that we are waking up from the state + * same as the Requested Level (RL) in the PSSCR + * which are Bits 60-63 + */ + ld r5,PACA_REQ_PSSCR(r13) + rldicl r5,r5,0,60 +FTR_SECTION_ELSE_NESTED(71) /* * 0-3 bits correspond to Power-Saving Level Status * which indicates the idle state we are waking up from */ + mfspr r5, SPRN_PSSCR rldicl r5,r5,4,60 +ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR_POWER9_DD1, 71) cmpd cr4,r5,r4 bge cr4,pnv_wakeup_tb_loss /* returns to caller */ @@ -731,13 +745,14 @@ timebase_resync: * Use cr3 which indicates that we are waking up with atleast partial * hypervisor state loss to determine if TIMEBASE RESYNC is needed. */ - ble cr3,clear_lock + ble cr3,.Ltb_resynced /* Time base re-sync */ bl opal_resync_timebase; /* - * If waking up from sleep, per core state is not lost, skip to - * clear_lock. + * If waking up from sleep (POWER8), per core state + * is not lost, skip to clear_lock. */ +.Ltb_resynced: blt cr4,clear_lock /* @@ -812,6 +827,10 @@ no_segments: mtctr r12 bctrl +BEGIN_FTR_SECTION + ld r4,_LPCR(r1) + mtspr SPRN_LPCR,r4 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) hypervisor_state_restored: mtspr SPRN_SRR1,r16 diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 2b33cfaac7b8..60714b8c9a2f 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -739,12 +739,20 @@ static int __init get_freq(char *name, int cells, unsigned long *val) static void start_cpu_decrementer(void) { #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) + unsigned int tcr; + /* Clear any pending timer interrupts */ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); - /* Enable decrementer interrupt */ - mtspr(SPRN_TCR, TCR_DIE); -#endif /* defined(CONFIG_BOOKE) || defined(CONFIG_40x) */ + tcr = mfspr(SPRN_TCR); + /* + * The watchdog may have already been enabled by u-boot. So leave + * TRC[WP] (Watchdog Period) alone. + */ + tcr &= TCR_WP_MASK; /* Clear all bits except for TCR[WP] */ + tcr |= TCR_DIE; /* Enable decrementer */ + mtspr(SPRN_TCR, tcr); +#endif } void __init generic_calibrate_decr(void) diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 2f793be3d2b1..ace6b6579961 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -58,7 +58,6 @@ SECTIONS #ifdef CONFIG_PPC64 KEEP(*(.head.text.first_256B)); #ifdef CONFIG_PPC_BOOK3E -# define END_FIXED 0x100 #else KEEP(*(.head.text.real_vectors)); *(.head.text.real_trampolines); @@ -66,12 +65,8 @@ SECTIONS *(.head.text.virt_trampolines); # if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) KEEP(*(.head.data.fwnmi_page)); -# define END_FIXED 0x8000 -# else -# define END_FIXED 0x7000 # endif #endif - ASSERT((. == END_FIXED), "vmlinux.lds.S: fixed section overflow error"); #else /* !CONFIG_PPC64 */ HEAD_TEXT #endif @@ -79,23 +74,6 @@ SECTIONS __head_end = .; - /* - * If the build dies here, it's likely code in head_64.S is referencing - * labels it can't reach, and the linker inserting stubs without the - * assembler's knowledge. To debug, remove the above assert and - * rebuild. Look for branch stubs in the fixed section region. - * - * Linker stub generation could be allowed in "trampoline" - * sections if absolutely necessary, but this would require - * some rework of the fixed sections. Before resorting to this, - * consider references that have sufficient addressing range, - * (e.g., hand coded trampolines) so the linker does not have - * to add stubs. - * - * Linker stubs at the top of the main text section are currently not - * detected, and will result in a crash at boot due to offsets being - * wrong. - */ #ifdef CONFIG_PPC64 /* * BLOCK(0) overrides the default output section alignment because @@ -103,18 +81,31 @@ SECTIONS * section placement to work. */ .text BLOCK(0) : AT(ADDR(.text) - LOAD_OFFSET) { +#ifdef CONFIG_LD_HEAD_STUB_CATCH + *(.linker_stub_catch); + . = . ; +#endif + #else .text : AT(ADDR(.text) - LOAD_OFFSET) { ALIGN_FUNCTION(); #endif /* careful! __ftr_alt_* sections need to be close to .text */ - *(.text .fixup __ftr_alt_* .ref.text) + *(.text.hot .text .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); SCHED_TEXT CPUIDLE_TEXT LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT SOFTIRQENTRY_TEXT + /* + * -Os builds call FP save/restore functions. The powerpc64 + * linker generates those on demand in the .sfpr section. + * .sfpr gets placed at the beginning of a group of input + * sections, which can break start-of-text offset if it is + * included with the main text sections, so put it by itself. + */ + *(.sfpr); MEM_KEEP(init.text) MEM_KEEP(exit.text) @@ -267,7 +258,9 @@ SECTIONS .data : AT(ADDR(.data) - LOAD_OFFSET) { DATA_DATA *(.sdata) + *(.sdata2) *(.got.plt) *(.got) + *(.plt) } #else .data : AT(ADDR(.data) - LOAD_OFFSET) { @@ -330,6 +323,16 @@ SECTIONS _end = . ; PROVIDE32 (end = .); - /* Sections to be discarded. */ + STABS_DEBUG + + DWARF_DEBUG + DISCARDS + /DISCARD/ : { + *(*.EMB.apuinfo) + *(.glink .iplt .plt .rela* .comment) + *(.gnu.version*) + *(.gnu.attributes) + *(.eh_frame) + } } diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index ed7dfce331e0..2c56f4636c2b 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -9,10 +9,17 @@ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE) -obj-y += string.o alloc.o crtsavres.o code-patching.o \ - feature-fixups.o +obj-y += string.o alloc.o code-patching.o feature-fixups.o -obj-$(CONFIG_PPC32) += div64.o copy_32.o +obj-$(CONFIG_PPC32) += div64.o copy_32.o crtsavres.o + +# See corresponding test in arch/powerpc/Makefile +# 64-bit linker creates .sfpr on demand for final link (vmlinux), +# so it is only needed for modules, and only for older linkers which +# do not support --save-restore-funcs +ifeq ($(call ld-ifversion, -lt, 225000000, y),y) +extra-$(CONFIG_PPC64) += crtsavres.o +endif obj64-y += copypage_64.o copyuser_64.o mem_64.o hweight_64.o \ copyuser_power7.o string_64.o copypage_power7.o memcpy_power7.o \ diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index a24b4039352c..706b7cc19846 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S @@ -82,14 +82,14 @@ _GLOBAL(__copy_tofrom_user_power7) #ifdef CONFIG_ALTIVEC cmpldi r5,16 - cmpldi cr1,r5,4096 + cmpldi cr1,r5,3328 std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) std r5,-STACKFRAMESIZE+STK_REG(R29)(r1) blt .Lshort_copy - bgt cr1,.Lvmx_copy + bge cr1,.Lvmx_copy #else cmpldi r5,16 diff --git a/arch/powerpc/lib/crtsavres.S b/arch/powerpc/lib/crtsavres.S index 18af0b3d3eb2..7e5e1c28e56a 100644 --- a/arch/powerpc/lib/crtsavres.S +++ b/arch/powerpc/lib/crtsavres.S @@ -44,10 +44,10 @@ #ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE -#ifndef CONFIG_PPC64 - .section ".text" +#ifndef CONFIG_PPC64 + /* Routines for saving integer registers, called by the compiler. */ /* Called with r11 pointing to the stack header word of the caller of the */ /* function, just beyond the end of the integer save area. */ @@ -314,8 +314,6 @@ _GLOBAL(_restvr_31) #else /* CONFIG_PPC64 */ - .section ".text.save.restore","ax",@progbits - .globl _savegpr0_14 _savegpr0_14: std r14,-144(r1) diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 9b0afe935cc1..01cb109ebf17 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -199,6 +199,18 @@ config CURRITUCK help This option enables support for the IBM Currituck (476fpe) evaluation board +config FSP2 + bool "IBM FSP2 (476fpe) Support" + depends on PPC_47x + default n + select 476FPE + select IBM_EMAC_EMAC4 if IBM_EMAC + select IBM_EMAC_RGMII if IBM_EMAC + select COMMON_CLK + select DEFAULT_UIMAGE + help + This option enables support for the IBM FSP2 (476fpe) board + config AKEBONO bool "IBM Akebono (476gtr) Support" depends on PPC_47x diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index 26d35b5941f7..72b824160660 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_ISS4xx) += iss4xx.o obj-$(CONFIG_CANYONLANDS)+= canyonlands.o obj-$(CONFIG_CURRITUCK) += ppc476.o obj-$(CONFIG_AKEBONO) += ppc476.o +obj-$(CONFIG_FSP2) += fsp2.o diff --git a/arch/powerpc/platforms/44x/fsp2.c b/arch/powerpc/platforms/44x/fsp2.c new file mode 100644 index 000000000000..92e98048404f --- /dev/null +++ b/arch/powerpc/platforms/44x/fsp2.c @@ -0,0 +1,62 @@ +/* + * FSP-2 board specific routines + * + * Based on earlier code: + * Matt Porter <mporter@kernel.crashing.org> + * Copyright 2002-2005 MontaVista Software Inc. + * + * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> + * Copyright (c) 2003-2005 Zultys Technologies + * + * Rewritten and ported to the merged powerpc tree: + * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/init.h> +#include <linux/of_platform.h> +#include <linux/rtc.h> + +#include <asm/machdep.h> +#include <asm/prom.h> +#include <asm/udbg.h> +#include <asm/time.h> +#include <asm/uic.h> +#include <asm/ppc4xx.h> + +static __initdata struct of_device_id fsp2_of_bus[] = { + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,plb6", }, + { .compatible = "ibm,opb", }, + {}, +}; + +static int __init fsp2_device_probe(void) +{ + of_platform_bus_probe(NULL, fsp2_of_bus, NULL); + return 0; +} +machine_device_initcall(fsp2, fsp2_device_probe); + +static int __init fsp2_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "ibm,fsp2")) + return 0; + return 1; +} + +define_machine(fsp2) { + .name = "FSP-2", + .probe = fsp2_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 445f30a2c5ef..46946a587004 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -30,8 +30,33 @@ /* Power ISA 3.0 allows for stop states 0x0 - 0xF */ #define MAX_STOP_STATE 0xF +#define P9_STOP_SPR_MSR 2000 +#define P9_STOP_SPR_PSSCR 855 + static u32 supported_cpuidle_states; +/* + * The default stop state that will be used by ppc_md.power_save + * function on platforms that support stop instruction. + */ +static u64 pnv_default_stop_val; +static u64 pnv_default_stop_mask; +static bool default_stop_found; + +/* + * First deep stop state. Used to figure out when to save/restore + * hypervisor context. + */ +u64 pnv_first_deep_stop_state = MAX_STOP_STATE; + +/* + * psscr value and mask of the deepest stop idle state. + * Used when a cpu is offlined. + */ +static u64 pnv_deepest_stop_psscr_val; +static u64 pnv_deepest_stop_psscr_mask; +static bool deepest_stop_found; + static int pnv_save_sprs_for_deep_states(void) { int cpu; @@ -48,6 +73,8 @@ static int pnv_save_sprs_for_deep_states(void) uint64_t hid4_val = mfspr(SPRN_HID4); uint64_t hid5_val = mfspr(SPRN_HID5); uint64_t hmeer_val = mfspr(SPRN_HMEER); + uint64_t msr_val = MSR_IDLE; + uint64_t psscr_val = pnv_deepest_stop_psscr_val; for_each_possible_cpu(cpu) { uint64_t pir = get_hard_smp_processor_id(cpu); @@ -61,6 +88,18 @@ static int pnv_save_sprs_for_deep_states(void) if (rc != 0) return rc; + if (cpu_has_feature(CPU_FTR_ARCH_300)) { + rc = opal_slw_set_reg(pir, P9_STOP_SPR_MSR, msr_val); + if (rc) + return rc; + + rc = opal_slw_set_reg(pir, + P9_STOP_SPR_PSSCR, psscr_val); + + if (rc) + return rc; + } + /* HIDs are per core registers */ if (cpu_thread_in_core(cpu) == 0) { @@ -72,17 +111,21 @@ static int pnv_save_sprs_for_deep_states(void) if (rc != 0) return rc; - rc = opal_slw_set_reg(pir, SPRN_HID1, hid1_val); - if (rc != 0) - return rc; + /* Only p8 needs to set extra HID regiters */ + if (!cpu_has_feature(CPU_FTR_ARCH_300)) { - rc = opal_slw_set_reg(pir, SPRN_HID4, hid4_val); - if (rc != 0) - return rc; + rc = opal_slw_set_reg(pir, SPRN_HID1, hid1_val); + if (rc != 0) + return rc; - rc = opal_slw_set_reg(pir, SPRN_HID5, hid5_val); - if (rc != 0) - return rc; + rc = opal_slw_set_reg(pir, SPRN_HID4, hid4_val); + if (rc != 0) + return rc; + + rc = opal_slw_set_reg(pir, SPRN_HID5, hid5_val); + if (rc != 0) + return rc; + } } } @@ -96,15 +139,24 @@ static void pnv_alloc_idle_core_states(void) u32 *core_idle_state; /* - * core_idle_state - First 8 bits track the idle state of each thread - * of the core. The 8th bit is the lock bit. Initially all thread bits - * are set. They are cleared when the thread enters deep idle state - * like sleep and winkle. Initially the lock bit is cleared. - * The lock bit has 2 purposes - * a. While the first thread is restoring core state, it prevents - * other threads in the core from switching to process context. - * b. While the last thread in the core is saving the core state, it - * prevents a different thread from waking up. + * core_idle_state - The lower 8 bits track the idle state of + * each thread of the core. + * + * The most significant bit is the lock bit. + * + * Initially all the bits corresponding to threads_per_core + * are set. They are cleared when the thread enters deep idle + * state like sleep and winkle/stop. + * + * Initially the lock bit is cleared. The lock bit has 2 + * purposes: + * a. While the first thread in the core waking up from + * idle is restoring core state, it prevents other + * threads in the core from switching to process + * context. + * b. While the last thread in the core is saving the + * core state, it prevents a different thread from + * waking up. */ for (i = 0; i < nr_cores; i++) { int first_cpu = i * threads_per_core; @@ -112,7 +164,7 @@ static void pnv_alloc_idle_core_states(void) size_t paca_ptr_array_size; core_idle_state = kmalloc_node(sizeof(u32), GFP_KERNEL, node); - *core_idle_state = PNV_CORE_IDLE_THREAD_BITS; + *core_idle_state = (1 << threads_per_core) - 1; paca_ptr_array_size = (threads_per_core * sizeof(struct paca_struct *)); @@ -232,14 +284,6 @@ static DEVICE_ATTR(fastsleep_workaround_applyonce, 0600, store_fastsleep_workaround_applyonce); /* - * The default stop state that will be used by ppc_md.power_save - * function on platforms that support stop instruction. - */ -static u64 pnv_default_stop_val; -static u64 pnv_default_stop_mask; -static bool default_stop_found; - -/* * Used for ppc_md.power_save which needs a function with no parameters */ static void power9_idle(void) @@ -247,20 +291,7 @@ static void power9_idle(void) power9_idle_stop(pnv_default_stop_val, pnv_default_stop_mask); } -/* - * First deep stop state. Used to figure out when to save/restore - * hypervisor context. - */ -u64 pnv_first_deep_stop_state = MAX_STOP_STATE; - -/* - * psscr value and mask of the deepest stop idle state. - * Used when a cpu is offlined. - */ -static u64 pnv_deepest_stop_psscr_val; -static u64 pnv_deepest_stop_psscr_mask; -static bool deepest_stop_found; - +#ifdef CONFIG_HOTPLUG_CPU /* * pnv_cpu_offline: A function that puts the CPU into the deepest * available platform idle state on a CPU-Offline. @@ -293,6 +324,7 @@ unsigned long pnv_cpu_offline(unsigned int cpu) return srr1; } +#endif /* * Power ISA 3.0 idle initialization. diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index f620572f891f..4ca6c26a56d5 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -99,10 +99,10 @@ opal_return: lwz r4,8(r1); ld r5,PPC_LR_STKOFF(r1); ld r6,PACASAVEDMSR(r13); - mtspr SPRN_SRR0,r5; - mtspr SPRN_SRR1,r6; mtcr r4; - rfid + mtspr SPRN_HSRR0,r5; + mtspr SPRN_HSRR1,r6; + hrfid opal_real_call: mfcr r11 diff --git a/arch/powerpc/tools/head_check.sh b/arch/powerpc/tools/head_check.sh new file mode 100644 index 000000000000..ad9e57209aa4 --- /dev/null +++ b/arch/powerpc/tools/head_check.sh @@ -0,0 +1,78 @@ +# Copyright © 2016 IBM Corporation + +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. + +# This script checks the head of a vmlinux for linker stubs that +# break our placement of fixed-location code for 64-bit. + +# based on relocs_check.pl +# Copyright © 2009 IBM Corporation + +# NOTE! +# +# If the build dies here, it's likely code in head_64.S/exception-64*.S or +# nearby, is branching to labels it can't reach directly, which results in the +# linker inserting branch stubs. This can move code around in ways that break +# the fixed section calculations (head-64.h). To debug this, disassemble the +# vmlinux and look for branch stubs (long_branch, plt_branch, etc.) in the +# fixed section region (0 - 0x8000ish). Check what code is calling those stubs, +# and perhaps change so a direct branch can reach. +# +# A ".linker_stub_catch" section is used to catch some stubs generated by +# early .text code, which tend to get placed at the start of the section. +# If there are too many such stubs, they can overflow this section. Expanding +# it may help (or reducing the number of stub branches). +# +# Linker stubs use the TOC pointer, so even if fixed section code could +# tolerate them being inserted into head code, they can't be allowed in low +# level entry code (boot, interrupt vectors, etc) until r2 is set up. This +# could cause the kernel to die in early boot. + +# Turn this on if you want more debug output: +# set -x + +if [ $# -lt 2 ]; then + echo "$0 [path to nm] [path to vmlinux]" 1>&2 + exit 1 +fi + +# Have Kbuild supply the path to nm so we handle cross compilation. +nm="$1" +vmlinux="$2" + +# gcc-4.6-era toolchain make _stext an A (absolute) symbol rather than T +$nm "$vmlinux" | grep -e " [TA] _stext$" -e " t start_first_256B$" -e " a text_start$" -e " t start_text$" -m4 > .tmp_symbols.txt + + +vma=$(cat .tmp_symbols.txt | grep -e " [TA] _stext$" | cut -d' ' -f1) + +expected_start_head_addr=$vma + +start_head_addr=$(cat .tmp_symbols.txt | grep " t start_first_256B$" | cut -d' ' -f1) + +if [ "$start_head_addr" != "$expected_start_head_addr" ]; then + echo "ERROR: head code starts at $start_head_addr, should be $expected_start_head_addr" + echo "ERROR: try to enable LD_HEAD_STUB_CATCH config option" + echo "ERROR: see comments in arch/powerpc/tools/head_check.sh" + + exit 1 +fi + +top_vma=$(echo $vma | cut -d'0' -f1) + +expected_start_text_addr=$(cat .tmp_symbols.txt | grep " a text_start$" | cut -d' ' -f1 | sed "s/^0/$top_vma/") + +start_text_addr=$(cat .tmp_symbols.txt | grep " t start_text$" | cut -d' ' -f1) + +if [ "$start_text_addr" != "$expected_start_text_addr" ]; then + echo "ERROR: start_text address is $start_text_addr, should be $expected_start_text_addr" + echo "ERROR: try to enable LD_HEAD_STUB_CATCH config option" + echo "ERROR: see comments in arch/powerpc/tools/head_check.sh" + + exit 1 +fi + +rm -f .tmp_symbols.txt diff --git a/arch/powerpc/tools/unrel_branch_check.sh b/arch/powerpc/tools/unrel_branch_check.sh new file mode 100755 index 000000000000..1e972df3107e --- /dev/null +++ b/arch/powerpc/tools/unrel_branch_check.sh @@ -0,0 +1,57 @@ +# Copyright © 2016 IBM Corporation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. +# +# This script checks the relocations of a vmlinux for "suspicious" +# branches from unrelocated code (head_64.S code). + +# Turn this on if you want more debug output: +# set -x + +# Have Kbuild supply the path to objdump so we handle cross compilation. +objdump="$1" +vmlinux="$2" + +#__end_interrupts should be located within the first 64K + +end_intr=0x$( +"$objdump" -R "$vmlinux" -d --start-address=0xc000000000000000 \ + --stop-address=0xc000000000010000 | +grep '\<__end_interrupts>:' | +awk '{print $1}' +) + +BRANCHES=$( +"$objdump" -R "$vmlinux" -D --start-address=0xc000000000000000 \ + --stop-address=${end_intr} | +grep -e "^c[0-9a-f]*:[[:space:]]*\([0-9a-f][0-9a-f][[:space:]]\)\{4\}[[:space:]]*b" | +grep -v '\<__start_initialization_multiplatform>' | +grep -v -e 'b.\?.\?ctr' | +grep -v -e 'b.\?.\?lr' | +sed 's/://' | +awk '{ print $1 ":" $6 ":0x" $7 ":" $8 " "}' +) + +for tuple in $BRANCHES +do + from=`echo $tuple | cut -d':' -f1` + branch=`echo $tuple | cut -d':' -f2` + to=`echo $tuple | cut -d':' -f3 | sed 's/cr[0-7],//'` + sym=`echo $tuple | cut -d':' -f4` + + if (( $to > $end_intr )) + then + if [ -z "$bad_branches" ]; then + echo "WARNING: Unrelocated relative branches" + bad_branches="yes" + fi + echo "$from $branch-> $to $sym" + fi +done + +if [ -z "$bad_branches" ]; then + exit 0 +fi diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index f11f65634aab..a728e1919613 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -1242,14 +1242,14 @@ bpt_cmds(void) { int cmd; unsigned long a; - int mode, i; + int i; struct bpt *bp; - const char badaddr[] = "Only kernel addresses are permitted " - "for breakpoints\n"; cmd = inchar(); switch (cmd) { -#ifndef CONFIG_8xx +#ifndef CONFIG_PPC_8xx + static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n"; + int mode; case 'd': /* bd - hardware data breakpoint */ mode = 7; cmd = inchar(); diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index e161fafb495b..e7ff58150e8f 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -184,7 +184,7 @@ config SCHED_OMIT_FRAME_POINTER config PGTABLE_LEVELS int - default 4 + default 5 source "init/Kconfig" diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile index 678d9863e3f0..ad4bd777768d 100644 --- a/arch/s390/crypto/Makefile +++ b/arch/s390/crypto/Makefile @@ -6,7 +6,8 @@ obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o sha_common.o obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o sha_common.o obj-$(CONFIG_CRYPTO_SHA512_S390) += sha512_s390.o sha_common.o obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o -obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o paes_s390.o +obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o +obj-$(CONFIG_CRYPTO_PAES_S390) += paes_s390.o obj-$(CONFIG_S390_PRNG) += prng.o obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o obj-$(CONFIG_CRYPTO_CRC32_S390) += crc32-vx_s390.o diff --git a/arch/s390/crypto/arch_random.c b/arch/s390/crypto/arch_random.c index 9317b3e645e2..36aefc07d10c 100644 --- a/arch/s390/crypto/arch_random.c +++ b/arch/s390/crypto/arch_random.c @@ -12,6 +12,7 @@ #include <linux/kernel.h> #include <linux/atomic.h> +#include <linux/random.h> #include <linux/static_key.h> #include <asm/cpacf.h> diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index 45092b12f54f..b3c88479feba 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild @@ -1,10 +1,12 @@ generic-y += asm-offsets.h generic-y += cacheflush.h generic-y += clkdev.h +generic-y += device.h generic-y += dma-contiguous.h generic-y += div64.h generic-y += emergency-restart.h generic-y += export.h +generic-y += fb.h generic-y += irq_regs.h generic-y += irq_work.h generic-y += kmap_types.h diff --git a/arch/s390/include/asm/device.h b/arch/s390/include/asm/device.h deleted file mode 100644 index 5203fc87f080..000000000000 --- a/arch/s390/include/asm/device.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -struct dev_archdata { -}; - -struct pdev_archdata { -}; diff --git a/arch/s390/include/asm/fb.h b/arch/s390/include/asm/fb.h deleted file mode 100644 index c7df38030992..000000000000 --- a/arch/s390/include/asm/fb.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _ASM_FB_H_ -#define _ASM_FB_H_ -#include <linux/fb.h> - -#define fb_pgprotect(...) do {} while (0) - -static inline int fb_is_primary_device(struct fb_info *info) -{ - return 0; -} - -#endif /* _ASM_FB_H_ */ diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 69b8a41fca84..624deaa44230 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -74,6 +74,7 @@ typedef struct { unsigned long pgste; } pgste_t; typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pud; } pud_t; +typedef struct { unsigned long p4d; } p4d_t; typedef struct { unsigned long pgd; } pgd_t; typedef pte_t *pgtable_t; @@ -82,12 +83,14 @@ typedef pte_t *pgtable_t; #define pte_val(x) ((x).pte) #define pmd_val(x) ((x).pmd) #define pud_val(x) ((x).pud) +#define p4d_val(x) ((x).p4d) #define pgd_val(x) ((x).pgd) #define __pgste(x) ((pgste_t) { (x) } ) #define __pte(x) ((pte_t) { (x) } ) #define __pmd(x) ((pmd_t) { (x) } ) #define __pud(x) ((pud_t) { (x) } ) +#define __p4d(x) ((p4d_t) { (x) } ) #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index 166f703dad7c..bb0ff1bb0c4a 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -51,12 +51,24 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) return _SEGMENT_ENTRY_EMPTY; if (mm->context.asce_limit <= (1UL << 42)) return _REGION3_ENTRY_EMPTY; - return _REGION2_ENTRY_EMPTY; + if (mm->context.asce_limit <= (1UL << 53)) + return _REGION2_ENTRY_EMPTY; + return _REGION1_ENTRY_EMPTY; } -int crst_table_upgrade(struct mm_struct *); +int crst_table_upgrade(struct mm_struct *mm, unsigned long limit); void crst_table_downgrade(struct mm_struct *); +static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long address) +{ + unsigned long *table = crst_table_alloc(mm); + + if (table) + crst_table_init(table, _REGION2_ENTRY_EMPTY); + return (p4d_t *) table; +} +#define p4d_free(mm, p4d) crst_table_free(mm, (unsigned long *) p4d) + static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) { unsigned long *table = crst_table_alloc(mm); @@ -86,9 +98,14 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) crst_table_free(mm, (unsigned long *) pmd); } -static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) +static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, p4d_t *p4d) +{ + pgd_val(*pgd) = _REGION1_ENTRY | __pa(p4d); +} + +static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4d, pud_t *pud) { - pgd_val(*pgd) = _REGION2_ENTRY | __pa(pud); + p4d_val(*p4d) = _REGION2_ENTRY | __pa(pud); } static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index e6e3b887bee3..3effb26f0e1a 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -24,7 +24,6 @@ * the S390 page table tree. */ #ifndef __ASSEMBLY__ -#include <asm-generic/5level-fixup.h> #include <linux/sched.h> #include <linux/mm_types.h> #include <linux/page-flags.h> @@ -87,12 +86,15 @@ extern unsigned long zero_page_mask; */ #define PMD_SHIFT 20 #define PUD_SHIFT 31 -#define PGDIR_SHIFT 42 +#define P4D_SHIFT 42 +#define PGDIR_SHIFT 53 #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) #define PUD_SIZE (1UL << PUD_SHIFT) #define PUD_MASK (~(PUD_SIZE-1)) +#define P4D_SIZE (1UL << P4D_SHIFT) +#define P4D_MASK (~(P4D_SIZE-1)) #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) @@ -105,6 +107,7 @@ extern unsigned long zero_page_mask; #define PTRS_PER_PTE 256 #define PTRS_PER_PMD 2048 #define PTRS_PER_PUD 2048 +#define PTRS_PER_P4D 2048 #define PTRS_PER_PGD 2048 #define FIRST_USER_ADDRESS 0UL @@ -115,6 +118,8 @@ extern unsigned long zero_page_mask; printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e)) #define pud_ERROR(e) \ printk("%s:%d: bad pud %p.\n", __FILE__, __LINE__, (void *) pud_val(e)) +#define p4d_ERROR(e) \ + printk("%s:%d: bad p4d %p.\n", __FILE__, __LINE__, (void *) p4d_val(e)) #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e)) @@ -310,8 +315,8 @@ static inline int is_module_addr(void *addr) #define _REGION3_ENTRY_SOFT_DIRTY 0x0000 /* SW region soft dirty bit */ #endif -#define _REGION_ENTRY_BITS 0xfffffffffffff227UL -#define _REGION_ENTRY_BITS_LARGE 0xffffffff8000fe27UL +#define _REGION_ENTRY_BITS 0xfffffffffffff22fUL +#define _REGION_ENTRY_BITS_LARGE 0xffffffff8000fe2fUL /* Bits in the segment table entry */ #define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL @@ -564,14 +569,14 @@ static inline void crdte(unsigned long old, unsigned long new, */ static inline int pgd_present(pgd_t pgd) { - if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) + if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R1) return 1; return (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) != 0UL; } static inline int pgd_none(pgd_t pgd) { - if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) + if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R1) return 0; return (pgd_val(pgd) & _REGION_ENTRY_INVALID) != 0UL; } @@ -589,6 +594,28 @@ static inline int pgd_bad(pgd_t pgd) return (pgd_val(pgd) & mask) != 0; } +static inline int p4d_present(p4d_t p4d) +{ + if ((p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) + return 1; + return (p4d_val(p4d) & _REGION_ENTRY_ORIGIN) != 0UL; +} + +static inline int p4d_none(p4d_t p4d) +{ + if ((p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) + return 0; + return p4d_val(p4d) == _REGION2_ENTRY_EMPTY; +} + +static inline unsigned long p4d_pfn(p4d_t p4d) +{ + unsigned long origin_mask; + + origin_mask = _REGION_ENTRY_ORIGIN; + return (p4d_val(p4d) & origin_mask) >> PAGE_SHIFT; +} + static inline int pud_present(pud_t pud) { if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) @@ -641,6 +668,13 @@ static inline int pud_bad(pud_t pud) return (pud_val(pud) & ~_REGION_ENTRY_BITS) != 0; } +static inline int p4d_bad(p4d_t p4d) +{ + if ((p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) + return pud_bad(__pud(p4d_val(p4d))); + return (p4d_val(p4d) & ~_REGION_ENTRY_BITS) != 0; +} + static inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) != _SEGMENT_ENTRY_EMPTY; @@ -794,8 +828,14 @@ static inline int pte_unused(pte_t pte) static inline void pgd_clear(pgd_t *pgd) { - if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) - pgd_val(*pgd) = _REGION2_ENTRY_EMPTY; + if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R1) + pgd_val(*pgd) = _REGION1_ENTRY_EMPTY; +} + +static inline void p4d_clear(p4d_t *p4d) +{ + if ((p4d_val(*p4d) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) + p4d_val(*p4d) = _REGION2_ENTRY_EMPTY; } static inline void pud_clear(pud_t *pud) @@ -1089,6 +1129,7 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) } #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) +#define p4d_index(address) (((address) >> P4D_SHIFT) & (PTRS_PER_P4D-1)) #define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) @@ -1098,19 +1139,31 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) #define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) #define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN) +#define p4d_deref(pud) (p4d_val(pud) & _REGION_ENTRY_ORIGIN) #define pgd_deref(pgd) (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) -static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address) +static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) { - pud_t *pud = (pud_t *) pgd; - if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) - pud = (pud_t *) pgd_deref(*pgd); - return pud + pud_index(address); + p4d_t *p4d = (p4d_t *) pgd; + + if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R1) + p4d = (p4d_t *) pgd_deref(*pgd); + return p4d + p4d_index(address); +} + +static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address) +{ + pud_t *pud = (pud_t *) p4d; + + if ((p4d_val(*p4d) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) + pud = (pud_t *) p4d_deref(*p4d); + return pud + pud_index(address); } static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) { pmd_t *pmd = (pmd_t *) pud; + if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) pmd = (pmd_t *) pud_deref(*pud); return pmd + pmd_index(address); @@ -1122,6 +1175,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) #define pmd_page(pmd) pfn_to_page(pmd_pfn(pmd)) #define pud_page(pud) pfn_to_page(pud_pfn(pud)) +#define p4d_page(pud) pfn_to_page(p4d_pfn(p4d)) /* Find an entry in the lowest level page table.. */ #define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr)) diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 60d395fdc864..f57c017a5c03 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -92,11 +92,11 @@ extern void execve_tail(void); */ #define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_31BIT) ? \ - (1UL << 31) : (1UL << 53)) + (1UL << 31) : -PAGE_SIZE) #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ (1UL << 30) : (1UL << 41)) #define TASK_SIZE TASK_SIZE_OF(current) -#define TASK_SIZE_MAX (1UL << 53) +#define TASK_SIZE_MAX (-PAGE_SIZE) #define STACK_TOP (test_thread_flag(TIF_31BIT) ? \ (1UL << 31) : (1UL << 42)) diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index 72df5f2de6b0..020a8814d511 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h @@ -59,7 +59,7 @@ static inline int __pcpu_sigp(u16 addr, u8 order, unsigned long parm, int cc; cc = ____pcpu_sigp(addr, order, parm, &_status); - if (status && cc == 1) + if (status && cc == SIGP_CC_STATUS_STORED) *status = _status; return cc; } diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index 853b2a3d8dee..7317b3108a88 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h @@ -137,6 +137,21 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, } /* + * p4d_free_tlb frees a pud table and clears the CRSTE for the + * region second table entry from the tlb. + * If the mm uses a four level page table the single p4d is freed + * as the pgd. p4d_free_tlb checks the asce_limit against 8PB + * to avoid the double free of the p4d in this case. + */ +static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, + unsigned long address) +{ + if (tlb->mm->context.asce_limit <= (1UL << 53)) + return; + tlb_remove_table(tlb, p4d); +} + +/* * pud_free_tlb frees a pud table and clears the CRSTE for the * region third table entry from the tlb. * If the mm uses a three level page table the single pud is freed diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index e408d9cc5b96..6315037335ba 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -231,12 +231,17 @@ ENTRY(sie64a) lctlg %c1,%c1,__LC_USER_ASCE # load primary asce .Lsie_done: # some program checks are suppressing. C code (e.g. do_protection_exception) -# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other -# instructions between sie64a and .Lsie_done should not cause program -# interrupts. So lets use a nop (47 00 00 00) as a landing pad. +# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There +# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable. +# Other instructions between sie64a and .Lsie_done should not cause program +# interrupts. So lets use 3 nops as a landing pad for all possible rewinds. # See also .Lcleanup_sie -.Lrewind_pad: - nop 0 +.Lrewind_pad6: + nopr 7 +.Lrewind_pad4: + nopr 7 +.Lrewind_pad2: + nopr 7 .globl sie_exit sie_exit: lg %r14,__SF_EMPTY+8(%r15) # load guest register save area @@ -249,7 +254,9 @@ sie_exit: stg %r14,__SF_EMPTY+16(%r15) # set exit reason code j sie_exit - EX_TABLE(.Lrewind_pad,.Lsie_fault) + EX_TABLE(.Lrewind_pad6,.Lsie_fault) + EX_TABLE(.Lrewind_pad4,.Lsie_fault) + EX_TABLE(.Lrewind_pad2,.Lsie_fault) EX_TABLE(sie_exit,.Lsie_fault) EXPORT_SYMBOL(sie64a) EXPORT_SYMBOL(sie_exit) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 363000a77ffc..1020a11a24e5 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -26,6 +26,7 @@ #include <linux/err.h> #include <linux/spinlock.h> #include <linux/kernel_stat.h> +#include <linux/kmemleak.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/irqflags.h> @@ -207,6 +208,8 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) kmem_cache_alloc(pcpu_mcesa_cache, GFP_KERNEL); if (!mcesa_origin) goto out; + /* The pointer is stored with mcesa_bits ORed in */ + kmemleak_not_leak((void *) mcesa_origin); mcesa_bits = MACHINE_HAS_GS ? 11 : 0; } } else { diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index f787b9d8f54c..442e5423ce3d 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -21,6 +21,7 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/uaccess.h> +#include <linux/cpu.h> #include <asm/fpu/api.h> #include "entry.h" diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 10516ae3b55e..b89d19f6f2ab 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -50,6 +50,56 @@ static struct page **vdso64_pagelist; */ unsigned int __read_mostly vdso_enabled = 1; +static int vdso_fault(const struct vm_special_mapping *sm, + struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct page **vdso_pagelist; + unsigned long vdso_pages; + + vdso_pagelist = vdso64_pagelist; + vdso_pages = vdso64_pages; +#ifdef CONFIG_COMPAT + if (is_compat_task()) { + vdso_pagelist = vdso32_pagelist; + vdso_pages = vdso32_pages; + } +#endif + + if (vmf->pgoff >= vdso_pages) + return VM_FAULT_SIGBUS; + + vmf->page = vdso_pagelist[vmf->pgoff]; + get_page(vmf->page); + return 0; +} + +static int vdso_mremap(const struct vm_special_mapping *sm, + struct vm_area_struct *vma) +{ + unsigned long vdso_pages; + + vdso_pages = vdso64_pages; +#ifdef CONFIG_COMPAT + if (is_compat_task()) + vdso_pages = vdso32_pages; +#endif + + if ((vdso_pages << PAGE_SHIFT) != vma->vm_end - vma->vm_start) + return -EINVAL; + + if (WARN_ON_ONCE(current->mm != vma->vm_mm)) + return -EFAULT; + + current->mm->context.vdso_base = vma->vm_start; + return 0; +} + +static const struct vm_special_mapping vdso_mapping = { + .name = "[vdso]", + .fault = vdso_fault, + .mremap = vdso_mremap, +}; + static int __init vdso_setup(char *s) { unsigned long val; @@ -181,7 +231,7 @@ static void vdso_init_cr5(void) int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { struct mm_struct *mm = current->mm; - struct page **vdso_pagelist; + struct vm_area_struct *vma; unsigned long vdso_pages; unsigned long vdso_base; int rc; @@ -194,13 +244,10 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) if (!uses_interp) return 0; - vdso_pagelist = vdso64_pagelist; vdso_pages = vdso64_pages; #ifdef CONFIG_COMPAT - if (is_compat_task()) { - vdso_pagelist = vdso32_pagelist; + if (is_compat_task()) vdso_pages = vdso32_pages; - } #endif /* * vDSO has a problem and was disabled, just don't "enable" it for @@ -209,8 +256,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) if (vdso_pages == 0) return 0; - current->mm->context.vdso_base = 0; - /* * pick a base address for the vDSO in process space. We try to put * it at vdso_base which is the "natural" base for it, but we might @@ -225,13 +270,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) } /* - * Put vDSO base into mm struct. We need to do this before calling - * install_special_mapping or the perf counter mmap tracking code - * will fail to recognise it as a vDSO (since arch_vma_name fails). - */ - current->mm->context.vdso_base = vdso_base; - - /* * our vma flags don't have VM_WRITE so by default, the process * isn't allowed to write those pages. * gdb can break that with ptrace interface, and thus trigger COW @@ -241,24 +279,23 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) * It's fine to use that for setting breakpoints in the vDSO code * pages though. */ - rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, - vdso_pagelist); - if (rc) - current->mm->context.vdso_base = 0; + vma = _install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT, + VM_READ|VM_EXEC| + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, + &vdso_mapping); + if (IS_ERR(vma)) { + rc = PTR_ERR(vma); + goto out_up; + } + + current->mm->context.vdso_base = vdso_base; + rc = 0; + out_up: up_write(&mm->mmap_sem); return rc; } -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso_base) - return "[vdso]"; - return NULL; -} - static int __init vdso_init(void) { int i; diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 072d84ba42a3..dd7178fbb4f3 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -110,11 +110,10 @@ static inline u64 scale_vtime(u64 vtime) return vtime; } -static void account_system_index_scaled(struct task_struct *p, - u64 cputime, u64 scaled, +static void account_system_index_scaled(struct task_struct *p, u64 cputime, enum cpu_usage_stat index) { - p->stimescaled += cputime_to_nsecs(scaled); + p->stimescaled += cputime_to_nsecs(scale_vtime(cputime)); account_system_index_time(p, cputime_to_nsecs(cputime), index); } @@ -176,14 +175,11 @@ static int do_account_vtime(struct task_struct *tsk) } if (system) - account_system_index_scaled(tsk, system, scale_vtime(system), - CPUTIME_SYSTEM); + account_system_index_scaled(tsk, system, CPUTIME_SYSTEM); if (hardirq) - account_system_index_scaled(tsk, hardirq, scale_vtime(hardirq), - CPUTIME_IRQ); + account_system_index_scaled(tsk, hardirq, CPUTIME_IRQ); if (softirq) - account_system_index_scaled(tsk, softirq, scale_vtime(softirq), - CPUTIME_SOFTIRQ); + account_system_index_scaled(tsk, softirq, CPUTIME_SOFTIRQ); steal = S390_lowcore.steal_timer; if ((s64) steal > 0) { diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c index 1b553d847140..049c3c455b32 100644 --- a/arch/s390/mm/dump_pagetables.c +++ b/arch/s390/mm/dump_pagetables.c @@ -149,7 +149,7 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, } static void walk_pud_level(struct seq_file *m, struct pg_state *st, - pgd_t *pgd, unsigned long addr) + p4d_t *p4d, unsigned long addr) { unsigned int prot; pud_t *pud; @@ -157,7 +157,7 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, for (i = 0; i < PTRS_PER_PUD && addr < max_addr; i++) { st->current_address = addr; - pud = pud_offset(pgd, addr); + pud = pud_offset(p4d, addr); if (!pud_none(*pud)) if (pud_large(*pud)) { prot = pud_val(*pud) & @@ -172,6 +172,23 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, } } +static void walk_p4d_level(struct seq_file *m, struct pg_state *st, + pgd_t *pgd, unsigned long addr) +{ + p4d_t *p4d; + int i; + + for (i = 0; i < PTRS_PER_P4D && addr < max_addr; i++) { + st->current_address = addr; + p4d = p4d_offset(pgd, addr); + if (!p4d_none(*p4d)) + walk_pud_level(m, st, p4d, addr); + else + note_page(m, st, _PAGE_INVALID, 2); + addr += P4D_SIZE; + } +} + static void walk_pgd_level(struct seq_file *m) { unsigned long addr = 0; @@ -184,7 +201,7 @@ static void walk_pgd_level(struct seq_file *m) st.current_address = addr; pgd = pgd_offset_k(addr); if (!pgd_none(*pgd)) - walk_pud_level(m, &st, pgd, addr); + walk_p4d_level(m, &st, pgd, addr); else note_page(m, &st, _PAGE_INVALID, 1); addr += PGDIR_SIZE; diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 5845d3028ffc..14f25798b001 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -130,7 +130,7 @@ static int bad_address(void *p) static void dump_pagetable(unsigned long asce, unsigned long address) { - unsigned long *table = __va(asce & PAGE_MASK); + unsigned long *table = __va(asce & _ASCE_ORIGIN); pr_alert("AS:%016lx ", asce); switch (asce & _ASCE_TYPE_MASK) { diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 7f6db1e6c048..4fb3d3cdb370 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -125,7 +125,7 @@ static void gmap_radix_tree_free(struct radix_tree_root *root) struct radix_tree_iter iter; unsigned long indices[16]; unsigned long index; - void **slot; + void __rcu **slot; int i, nr; /* A radix tree is freed by deleting all of its entries */ @@ -150,7 +150,7 @@ static void gmap_rmap_radix_tree_free(struct radix_tree_root *root) struct radix_tree_iter iter; unsigned long indices[16]; unsigned long index; - void **slot; + void __rcu **slot; int i, nr; /* A radix tree is freed by deleting all of its entries */ @@ -537,6 +537,7 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr) unsigned long *table; spinlock_t *ptl; pgd_t *pgd; + p4d_t *p4d; pud_t *pud; pmd_t *pmd; int rc; @@ -573,7 +574,9 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr) mm = gmap->mm; pgd = pgd_offset(mm, vmaddr); VM_BUG_ON(pgd_none(*pgd)); - pud = pud_offset(pgd, vmaddr); + p4d = p4d_offset(pgd, vmaddr); + VM_BUG_ON(p4d_none(*p4d)); + pud = pud_offset(p4d, vmaddr); VM_BUG_ON(pud_none(*pud)); /* large puds cannot yet be handled */ if (pud_large(*pud)) @@ -1008,7 +1011,7 @@ EXPORT_SYMBOL_GPL(gmap_read_table); static inline void gmap_insert_rmap(struct gmap *sg, unsigned long vmaddr, struct gmap_rmap *rmap) { - void **slot; + void __rcu **slot; BUG_ON(!gmap_is_shadow(sg)); slot = radix_tree_lookup_slot(&sg->host_to_rmap, vmaddr >> PAGE_SHIFT); diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index b7b779c40a5b..8ecc25e760fa 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -166,15 +166,15 @@ static int gup_huge_pud(pud_t *pudp, pud_t pud, unsigned long addr, return 1; } -static inline int gup_pud_range(pgd_t *pgdp, pgd_t pgd, unsigned long addr, +static inline int gup_pud_range(p4d_t *p4dp, p4d_t p4d, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { unsigned long next; pud_t *pudp, pud; - pudp = (pud_t *) pgdp; - if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) - pudp = (pud_t *) pgd_deref(pgd); + pudp = (pud_t *) p4dp; + if ((p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) + pudp = (pud_t *) p4d_deref(p4d); pudp += pud_index(addr); do { pud = *pudp; @@ -194,6 +194,29 @@ static inline int gup_pud_range(pgd_t *pgdp, pgd_t pgd, unsigned long addr, return 1; } +static inline int gup_p4d_range(pgd_t *pgdp, pgd_t pgd, unsigned long addr, + unsigned long end, int write, struct page **pages, int *nr) +{ + unsigned long next; + p4d_t *p4dp, p4d; + + p4dp = (p4d_t *) pgdp; + if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R1) + p4dp = (p4d_t *) pgd_deref(pgd); + p4dp += p4d_index(addr); + do { + p4d = *p4dp; + barrier(); + next = p4d_addr_end(addr, end); + if (p4d_none(p4d)) + return 0; + if (!gup_pud_range(p4dp, p4d, addr, next, write, pages, nr)) + return 0; + } while (p4dp++, addr = next, addr != end); + + return 1; +} + /* * Like get_user_pages_fast() except its IRQ-safe in that it won't fall * back to the regular GUP. @@ -228,7 +251,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, next = pgd_addr_end(addr, end); if (pgd_none(pgd)) break; - if (!gup_pud_range(pgdp, pgd, addr, next, write, pages, &nr)) + if (!gup_p4d_range(pgdp, pgd, addr, next, write, pages, &nr)) break; } while (pgdp++, addr = next, addr != end); local_irq_restore(flags); diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index 9b4050caa4e9..d3a5e39756f6 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c @@ -162,16 +162,20 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz) { pgd_t *pgdp; + p4d_t *p4dp; pud_t *pudp; pmd_t *pmdp = NULL; pgdp = pgd_offset(mm, addr); - pudp = pud_alloc(mm, pgdp, addr); - if (pudp) { - if (sz == PUD_SIZE) - return (pte_t *) pudp; - else if (sz == PMD_SIZE) - pmdp = pmd_alloc(mm, pudp, addr); + p4dp = p4d_alloc(mm, pgdp, addr); + if (p4dp) { + pudp = pud_alloc(mm, p4dp, addr); + if (pudp) { + if (sz == PUD_SIZE) + return (pte_t *) pudp; + else if (sz == PMD_SIZE) + pmdp = pmd_alloc(mm, pudp, addr); + } } return (pte_t *) pmdp; } @@ -179,16 +183,20 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { pgd_t *pgdp; + p4d_t *p4dp; pud_t *pudp; pmd_t *pmdp = NULL; pgdp = pgd_offset(mm, addr); if (pgd_present(*pgdp)) { - pudp = pud_offset(pgdp, addr); - if (pud_present(*pudp)) { - if (pud_large(*pudp)) - return (pte_t *) pudp; - pmdp = pmd_offset(pudp, addr); + p4dp = p4d_offset(pgdp, addr); + if (p4d_present(*p4dp)) { + pudp = pud_offset(p4dp, addr); + if (pud_present(*pudp)) { + if (pud_large(*pudp)) + return (pte_t *) pudp; + pmdp = pmd_offset(pudp, addr); + } } } return (pte_t *) pmdp; diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index b017daed6887..8c5f284044ef 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -120,7 +120,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, check_asce_limit: if (addr + len > current->mm->context.asce_limit) { - rc = crst_table_upgrade(mm); + rc = crst_table_upgrade(mm, addr + len); if (rc) return (unsigned long) rc; } @@ -184,7 +184,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, check_asce_limit: if (addr + len > current->mm->context.asce_limit) { - rc = crst_table_upgrade(mm); + rc = crst_table_upgrade(mm, addr + len); if (rc) return (unsigned long) rc; } diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index 49e721f3645e..180481589246 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c @@ -229,14 +229,14 @@ static void modify_pud_page(pud_t *pudp, unsigned long addr, pgt_set((unsigned long *)pudp, pud_val(new), addr, CRDTE_DTT_REGION3); } -static int walk_pud_level(pgd_t *pgd, unsigned long addr, unsigned long end, +static int walk_pud_level(p4d_t *p4d, unsigned long addr, unsigned long end, unsigned long flags) { unsigned long next; pud_t *pudp; int rc = 0; - pudp = pud_offset(pgd, addr); + pudp = pud_offset(p4d, addr); do { if (pud_none(*pudp)) return -EINVAL; @@ -259,6 +259,26 @@ static int walk_pud_level(pgd_t *pgd, unsigned long addr, unsigned long end, return rc; } +static int walk_p4d_level(pgd_t *pgd, unsigned long addr, unsigned long end, + unsigned long flags) +{ + unsigned long next; + p4d_t *p4dp; + int rc = 0; + + p4dp = p4d_offset(pgd, addr); + do { + if (p4d_none(*p4dp)) + return -EINVAL; + next = p4d_addr_end(addr, end); + rc = walk_pud_level(p4dp, addr, next, flags); + p4dp++; + addr = next; + cond_resched(); + } while (addr < end && !rc); + return rc; +} + static DEFINE_MUTEX(cpa_mutex); static int change_page_attr(unsigned long addr, unsigned long end, @@ -278,7 +298,7 @@ static int change_page_attr(unsigned long addr, unsigned long end, if (pgd_none(*pgdp)) break; next = pgd_addr_end(addr, end); - rc = walk_pud_level(pgdp, addr, next, flags); + rc = walk_p4d_level(pgdp, addr, next, flags); if (rc) break; cond_resched(); @@ -319,6 +339,7 @@ void __kernel_map_pages(struct page *page, int numpages, int enable) unsigned long address; int nr, i, j; pgd_t *pgd; + p4d_t *p4d; pud_t *pud; pmd_t *pmd; pte_t *pte; @@ -326,7 +347,8 @@ void __kernel_map_pages(struct page *page, int numpages, int enable) for (i = 0; i < numpages;) { address = page_to_phys(page + i); pgd = pgd_offset_k(address); - pud = pud_offset(pgd, address); + p4d = p4d_offset(pgd, address); + pud = pud_offset(p4d, address); pmd = pmd_offset(pud, address); pte = pte_offset_kernel(pmd, address); nr = (unsigned long)pte >> ilog2(sizeof(long)); diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c index f502cbe657af..18918e394ce4 100644 --- a/arch/s390/mm/pgalloc.c +++ b/arch/s390/mm/pgalloc.c @@ -76,29 +76,46 @@ static void __crst_table_upgrade(void *arg) __tlb_flush_local(); } -int crst_table_upgrade(struct mm_struct *mm) +int crst_table_upgrade(struct mm_struct *mm, unsigned long end) { unsigned long *table, *pgd; + int rc, notify; - /* upgrade should only happen from 3 to 4 levels */ - BUG_ON(mm->context.asce_limit != (1UL << 42)); - - table = crst_table_alloc(mm); - if (!table) + /* upgrade should only happen from 3 to 4, 3 to 5, or 4 to 5 levels */ + BUG_ON(mm->context.asce_limit < (1UL << 42)); + if (end >= TASK_SIZE_MAX) return -ENOMEM; - - spin_lock_bh(&mm->page_table_lock); - pgd = (unsigned long *) mm->pgd; - crst_table_init(table, _REGION2_ENTRY_EMPTY); - pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); - mm->pgd = (pgd_t *) table; - mm->context.asce_limit = 1UL << 53; - mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | _ASCE_TYPE_REGION2; - spin_unlock_bh(&mm->page_table_lock); - - on_each_cpu(__crst_table_upgrade, mm, 0); - return 0; + rc = 0; + notify = 0; + while (mm->context.asce_limit < end) { + table = crst_table_alloc(mm); + if (!table) { + rc = -ENOMEM; + break; + } + spin_lock_bh(&mm->page_table_lock); + pgd = (unsigned long *) mm->pgd; + if (mm->context.asce_limit == (1UL << 42)) { + crst_table_init(table, _REGION2_ENTRY_EMPTY); + p4d_populate(mm, (p4d_t *) table, (pud_t *) pgd); + mm->pgd = (pgd_t *) table; + mm->context.asce_limit = 1UL << 53; + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_REGION2; + } else { + crst_table_init(table, _REGION1_ENTRY_EMPTY); + pgd_populate(mm, (pgd_t *) table, (p4d_t *) pgd); + mm->pgd = (pgd_t *) table; + mm->context.asce_limit = -PAGE_SIZE; + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_REGION1; + } + notify = 1; + spin_unlock_bh(&mm->page_table_lock); + } + if (notify) + on_each_cpu(__crst_table_upgrade, mm, 0); + return rc; } void crst_table_downgrade(struct mm_struct *mm) @@ -274,7 +291,7 @@ static void __tlb_remove_table(void *_table) struct page *page = pfn_to_page(__pa(table) >> PAGE_SHIFT); switch (mask) { - case 0: /* pmd or pud */ + case 0: /* pmd, pud, or p4d */ free_pages((unsigned long) table, 2); break; case 1: /* lower 2K of a 4K page table */ diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 947b66a5cdba..d4d409ba206b 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -610,6 +610,7 @@ bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr) { spinlock_t *ptl; pgd_t *pgd; + p4d_t *p4d; pud_t *pud; pmd_t *pmd; pgste_t pgste; @@ -618,7 +619,10 @@ bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr) bool dirty; pgd = pgd_offset(mm, addr); - pud = pud_alloc(mm, pgd, addr); + p4d = p4d_alloc(mm, pgd, addr); + if (!p4d) + return false; + pud = pud_alloc(mm, p4d, addr); if (!pud) return false; pmd = pmd_alloc(mm, pud, addr); diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index c33c94b4be60..d8398962a723 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -38,6 +38,17 @@ static void __ref *vmem_alloc_pages(unsigned int order) return (void *) memblock_alloc(size, size); } +static inline p4d_t *vmem_p4d_alloc(void) +{ + p4d_t *p4d = NULL; + + p4d = vmem_alloc_pages(2); + if (!p4d) + return NULL; + clear_table((unsigned long *) p4d, _REGION2_ENTRY_EMPTY, PAGE_SIZE * 4); + return p4d; +} + static inline pud_t *vmem_pud_alloc(void) { pud_t *pud = NULL; @@ -85,6 +96,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size) unsigned long end = start + size; unsigned long address = start; pgd_t *pg_dir; + p4d_t *p4_dir; pud_t *pu_dir; pmd_t *pm_dir; pte_t *pt_dir; @@ -102,12 +114,19 @@ static int vmem_add_mem(unsigned long start, unsigned long size) while (address < end) { pg_dir = pgd_offset_k(address); if (pgd_none(*pg_dir)) { + p4_dir = vmem_p4d_alloc(); + if (!p4_dir) + goto out; + pgd_populate(&init_mm, pg_dir, p4_dir); + } + p4_dir = p4d_offset(pg_dir, address); + if (p4d_none(*p4_dir)) { pu_dir = vmem_pud_alloc(); if (!pu_dir) goto out; - pgd_populate(&init_mm, pg_dir, pu_dir); + p4d_populate(&init_mm, p4_dir, pu_dir); } - pu_dir = pud_offset(pg_dir, address); + pu_dir = pud_offset(p4_dir, address); if (MACHINE_HAS_EDAT2 && pud_none(*pu_dir) && address && !(address & ~PUD_MASK) && (address + PUD_SIZE <= end) && !debug_pagealloc_enabled()) { @@ -161,6 +180,7 @@ static void vmem_remove_range(unsigned long start, unsigned long size) unsigned long end = start + size; unsigned long address = start; pgd_t *pg_dir; + p4d_t *p4_dir; pud_t *pu_dir; pmd_t *pm_dir; pte_t *pt_dir; @@ -172,7 +192,12 @@ static void vmem_remove_range(unsigned long start, unsigned long size) address += PGDIR_SIZE; continue; } - pu_dir = pud_offset(pg_dir, address); + p4_dir = p4d_offset(pg_dir, address); + if (p4d_none(*p4_dir)) { + address += P4D_SIZE; + continue; + } + pu_dir = pud_offset(p4_dir, address); if (pud_none(*pu_dir)) { address += PUD_SIZE; continue; @@ -213,6 +238,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) unsigned long pgt_prot, sgt_prot; unsigned long address = start; pgd_t *pg_dir; + p4d_t *p4_dir; pud_t *pu_dir; pmd_t *pm_dir; pte_t *pt_dir; @@ -227,13 +253,21 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) for (address = start; address < end;) { pg_dir = pgd_offset_k(address); if (pgd_none(*pg_dir)) { + p4_dir = vmem_p4d_alloc(); + if (!p4_dir) + goto out; + pgd_populate(&init_mm, pg_dir, p4_dir); + } + + p4_dir = p4d_offset(pg_dir, address); + if (p4d_none(*p4_dir)) { pu_dir = vmem_pud_alloc(); if (!pu_dir) goto out; - pgd_populate(&init_mm, pg_dir, pu_dir); + p4d_populate(&init_mm, p4_dir, pu_dir); } - pu_dir = pud_offset(pg_dir, address); + pu_dir = pud_offset(p4_dir, address); if (pud_none(*pu_dir)) { pm_dir = vmem_pmd_alloc(); if (!pm_dir) diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c index be63fbd699fd..025ea20fc4b4 100644 --- a/arch/s390/tools/gen_facilities.c +++ b/arch/s390/tools/gen_facilities.c @@ -34,8 +34,6 @@ static struct facility_def facility_defs[] = { 18, /* long displacement facility */ #endif #ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES - 7, /* stfle */ - 17, /* message security assist */ 21, /* extended-immediate facility */ 25, /* store clock fast */ #endif diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 58243b0d21c0..1a83ec901446 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -83,6 +83,8 @@ config SPARC64 select ARCH_SUPPORTS_ATOMIC_RMW select HAVE_NMI select HAVE_REGS_AND_STACK_ACCESS_API + select ARCH_USE_QUEUED_RWLOCKS + select ARCH_USE_QUEUED_SPINLOCKS config ARCH_DEFCONFIG string @@ -92,6 +94,9 @@ config ARCH_DEFCONFIG config ARCH_PROC_KCORE_TEXT def_bool y +config CPU_BIG_ENDIAN + def_bool y + config ARCH_ATU bool default y if SPARC64 @@ -295,9 +300,13 @@ config NUMA depends on SPARC64 && SMP config NODES_SHIFT - int - default "4" + int "Maximum NUMA Nodes (as a power of 2)" + range 4 5 if SPARC64 + default "5" depends on NEED_MULTIPLE_NODES + help + Specify the maximum number of NUMA Nodes available on the target + system. Increases memory reserved to accommodate various tables. # Some NUMA nodes have memory ranges that span # other nodes. Even though a pfn is valid and diff --git a/arch/sparc/include/asm/cmpxchg_64.h b/arch/sparc/include/asm/cmpxchg_64.h index faa2f61058c2..4028f4f1e561 100644 --- a/arch/sparc/include/asm/cmpxchg_64.h +++ b/arch/sparc/include/asm/cmpxchg_64.h @@ -6,6 +6,17 @@ #ifndef __ARCH_SPARC64_CMPXCHG__ #define __ARCH_SPARC64_CMPXCHG__ +static inline unsigned long +__cmpxchg_u32(volatile int *m, int old, int new) +{ + __asm__ __volatile__("cas [%2], %3, %0" + : "=&r" (new) + : "0" (new), "r" (m), "r" (old) + : "memory"); + + return new; +} + static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val) { unsigned long tmp1, tmp2; @@ -44,10 +55,38 @@ static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long void __xchg_called_with_bad_pointer(void); +/* + * Use 4 byte cas instruction to achieve 2 byte xchg. Main logic + * here is to get the bit shift of the byte we are interested in. + * The XOR is handy for reversing the bits for big-endian byte order. + */ +static inline unsigned long +xchg16(__volatile__ unsigned short *m, unsigned short val) +{ + unsigned long maddr = (unsigned long)m; + int bit_shift = (((unsigned long)m & 2) ^ 2) << 3; + unsigned int mask = 0xffff << bit_shift; + unsigned int *ptr = (unsigned int *) (maddr & ~2); + unsigned int old32, new32, load32; + + /* Read the old value */ + load32 = *ptr; + + do { + old32 = load32; + new32 = (load32 & (~mask)) | val << bit_shift; + load32 = __cmpxchg_u32(ptr, old32, new32); + } while (load32 != old32); + + return (load32 & mask) >> bit_shift; +} + static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size) { switch (size) { + case 2: + return xchg16(ptr, x); case 4: return xchg32(ptr, x); case 8: @@ -65,10 +104,11 @@ static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, #include <asm-generic/cmpxchg-local.h> + static inline unsigned long -__cmpxchg_u32(volatile int *m, int old, int new) +__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) { - __asm__ __volatile__("cas [%2], %3, %0" + __asm__ __volatile__("casx [%2], %3, %0" : "=&r" (new) : "0" (new), "r" (m), "r" (old) : "memory"); @@ -76,15 +116,31 @@ __cmpxchg_u32(volatile int *m, int old, int new) return new; } +/* + * Use 4 byte cas instruction to achieve 1 byte cmpxchg. Main logic + * here is to get the bit shift of the byte we are interested in. + * The XOR is handy for reversing the bits for big-endian byte order + */ static inline unsigned long -__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) +__cmpxchg_u8(volatile unsigned char *m, unsigned char old, unsigned char new) { - __asm__ __volatile__("casx [%2], %3, %0" - : "=&r" (new) - : "0" (new), "r" (m), "r" (old) - : "memory"); - - return new; + unsigned long maddr = (unsigned long)m; + int bit_shift = (((unsigned long)m & 3) ^ 3) << 3; + unsigned int mask = 0xff << bit_shift; + unsigned int *ptr = (unsigned int *) (maddr & ~3); + unsigned int old32, new32, load; + unsigned int load32 = *ptr; + + do { + new32 = (load32 & ~mask) | (new << bit_shift); + old32 = (load32 & ~mask) | (old << bit_shift); + load32 = __cmpxchg_u32(ptr, old32, new32); + if (load32 == old32) + return old; + load = (load32 & mask) >> bit_shift; + } while (load == old); + + return load; } /* This function doesn't exist, so you'll get a linker error @@ -95,6 +151,8 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) { switch (size) { + case 1: + return __cmpxchg_u8(ptr, old, new); case 4: return __cmpxchg_u32(ptr, old, new); case 8: diff --git a/arch/sparc/include/asm/qrwlock.h b/arch/sparc/include/asm/qrwlock.h new file mode 100644 index 000000000000..d68a4b102100 --- /dev/null +++ b/arch/sparc/include/asm/qrwlock.h @@ -0,0 +1,7 @@ +#ifndef _ASM_SPARC_QRWLOCK_H +#define _ASM_SPARC_QRWLOCK_H + +#include <asm-generic/qrwlock_types.h> +#include <asm-generic/qrwlock.h> + +#endif /* _ASM_SPARC_QRWLOCK_H */ diff --git a/arch/sparc/include/asm/qspinlock.h b/arch/sparc/include/asm/qspinlock.h new file mode 100644 index 000000000000..5ae9a2802846 --- /dev/null +++ b/arch/sparc/include/asm/qspinlock.h @@ -0,0 +1,7 @@ +#ifndef _ASM_SPARC_QSPINLOCK_H +#define _ASM_SPARC_QSPINLOCK_H + +#include <asm-generic/qspinlock_types.h> +#include <asm-generic/qspinlock.h> + +#endif /* _ASM_SPARC_QSPINLOCK_H */ diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index 07c9f2e9bf57..f7028f5e1a5a 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h @@ -10,216 +10,12 @@ #include <asm/processor.h> #include <asm/barrier.h> - -/* To get debugging spinlocks which detect and catch - * deadlock situations, set CONFIG_DEBUG_SPINLOCK - * and rebuild your kernel. - */ - -/* Because we play games to save cycles in the non-contention case, we - * need to be extra careful about branch targets into the "spinning" - * code. They live in their own section, but the newer V9 branches - * have a shorter range than the traditional 32-bit sparc branch - * variants. The rule is that the branches that go into and out of - * the spinner sections must be pre-V9 branches. - */ - -#define arch_spin_is_locked(lp) ((lp)->lock != 0) - -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - -static inline void arch_spin_lock(arch_spinlock_t *lock) -{ - unsigned long tmp; - - __asm__ __volatile__( -"1: ldstub [%1], %0\n" -" brnz,pn %0, 2f\n" -" nop\n" -" .subsection 2\n" -"2: ldub [%1], %0\n" -" brnz,pt %0, 2b\n" -" nop\n" -" ba,a,pt %%xcc, 1b\n" -" .previous" - : "=&r" (tmp) - : "r" (lock) - : "memory"); -} - -static inline int arch_spin_trylock(arch_spinlock_t *lock) -{ - unsigned long result; - - __asm__ __volatile__( -" ldstub [%1], %0\n" - : "=r" (result) - : "r" (lock) - : "memory"); - - return (result == 0UL); -} - -static inline void arch_spin_unlock(arch_spinlock_t *lock) -{ - __asm__ __volatile__( -" stb %%g0, [%0]" - : /* No outputs */ - : "r" (lock) - : "memory"); -} - -static inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) -{ - unsigned long tmp1, tmp2; - - __asm__ __volatile__( -"1: ldstub [%2], %0\n" -" brnz,pn %0, 2f\n" -" nop\n" -" .subsection 2\n" -"2: rdpr %%pil, %1\n" -" wrpr %3, %%pil\n" -"3: ldub [%2], %0\n" -" brnz,pt %0, 3b\n" -" nop\n" -" ba,pt %%xcc, 1b\n" -" wrpr %1, %%pil\n" -" .previous" - : "=&r" (tmp1), "=&r" (tmp2) - : "r"(lock), "r"(flags) - : "memory"); -} - -/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */ - -static inline void arch_read_lock(arch_rwlock_t *lock) -{ - unsigned long tmp1, tmp2; - - __asm__ __volatile__ ( -"1: ldsw [%2], %0\n" -" brlz,pn %0, 2f\n" -"4: add %0, 1, %1\n" -" cas [%2], %0, %1\n" -" cmp %0, %1\n" -" bne,pn %%icc, 1b\n" -" nop\n" -" .subsection 2\n" -"2: ldsw [%2], %0\n" -" brlz,pt %0, 2b\n" -" nop\n" -" ba,a,pt %%xcc, 4b\n" -" .previous" - : "=&r" (tmp1), "=&r" (tmp2) - : "r" (lock) - : "memory"); -} - -static inline int arch_read_trylock(arch_rwlock_t *lock) -{ - int tmp1, tmp2; - - __asm__ __volatile__ ( -"1: ldsw [%2], %0\n" -" brlz,a,pn %0, 2f\n" -" mov 0, %0\n" -" add %0, 1, %1\n" -" cas [%2], %0, %1\n" -" cmp %0, %1\n" -" bne,pn %%icc, 1b\n" -" mov 1, %0\n" -"2:" - : "=&r" (tmp1), "=&r" (tmp2) - : "r" (lock) - : "memory"); - - return tmp1; -} - -static inline void arch_read_unlock(arch_rwlock_t *lock) -{ - unsigned long tmp1, tmp2; - - __asm__ __volatile__( -"1: lduw [%2], %0\n" -" sub %0, 1, %1\n" -" cas [%2], %0, %1\n" -" cmp %0, %1\n" -" bne,pn %%xcc, 1b\n" -" nop" - : "=&r" (tmp1), "=&r" (tmp2) - : "r" (lock) - : "memory"); -} - -static inline void arch_write_lock(arch_rwlock_t *lock) -{ - unsigned long mask, tmp1, tmp2; - - mask = 0x80000000UL; - - __asm__ __volatile__( -"1: lduw [%2], %0\n" -" brnz,pn %0, 2f\n" -"4: or %0, %3, %1\n" -" cas [%2], %0, %1\n" -" cmp %0, %1\n" -" bne,pn %%icc, 1b\n" -" nop\n" -" .subsection 2\n" -"2: lduw [%2], %0\n" -" brnz,pt %0, 2b\n" -" nop\n" -" ba,a,pt %%xcc, 4b\n" -" .previous" - : "=&r" (tmp1), "=&r" (tmp2) - : "r" (lock), "r" (mask) - : "memory"); -} - -static inline void arch_write_unlock(arch_rwlock_t *lock) -{ - __asm__ __volatile__( -" stw %%g0, [%0]" - : /* no outputs */ - : "r" (lock) - : "memory"); -} - -static inline int arch_write_trylock(arch_rwlock_t *lock) -{ - unsigned long mask, tmp1, tmp2, result; - - mask = 0x80000000UL; - - __asm__ __volatile__( -" mov 0, %2\n" -"1: lduw [%3], %0\n" -" brnz,pn %0, 2f\n" -" or %0, %4, %1\n" -" cas [%3], %0, %1\n" -" cmp %0, %1\n" -" bne,pn %%icc, 1b\n" -" nop\n" -" mov 1, %2\n" -"2:" - : "=&r" (tmp1), "=&r" (tmp2), "=&r" (result) - : "r" (lock), "r" (mask) - : "memory"); - - return result; -} +#include <asm/qrwlock.h> +#include <asm/qspinlock.h> #define arch_read_lock_flags(p, f) arch_read_lock(p) #define arch_write_lock_flags(p, f) arch_write_lock(p) -#define arch_read_can_lock(rw) (!((rw)->lock & 0x80000000UL)) -#define arch_write_can_lock(rw) (!(rw)->lock) - #define arch_spin_relax(lock) cpu_relax() #define arch_read_relax(lock) cpu_relax() #define arch_write_relax(lock) cpu_relax() diff --git a/arch/sparc/include/asm/spinlock_types.h b/arch/sparc/include/asm/spinlock_types.h index 9c454fdeaad8..bce8ef44dfa9 100644 --- a/arch/sparc/include/asm/spinlock_types.h +++ b/arch/sparc/include/asm/spinlock_types.h @@ -1,20 +1,24 @@ #ifndef __SPARC_SPINLOCK_TYPES_H #define __SPARC_SPINLOCK_TYPES_H -#ifndef __LINUX_SPINLOCK_TYPES_H -# error "please don't include this file directly" -#endif +#ifdef CONFIG_QUEUED_SPINLOCKS +#include <asm-generic/qspinlock_types.h> +#else typedef struct { volatile unsigned char lock; } arch_spinlock_t; #define __ARCH_SPIN_LOCK_UNLOCKED { 0 } +#endif /* CONFIG_QUEUED_SPINLOCKS */ +#ifdef CONFIG_QUEUED_RWLOCKS +#include <asm-generic/qrwlock_types.h> +#else typedef struct { volatile unsigned int lock; } arch_rwlock_t; #define __ARCH_RW_LOCK_UNLOCKED { 0 } - +#endif /* CONFIG_QUEUED_RWLOCKS */ #endif diff --git a/arch/tile/include/uapi/arch/abi.h b/arch/tile/include/uapi/arch/abi.h index c55a3d432644..328e62260272 100644 --- a/arch/tile/include/uapi/arch/abi.h +++ b/arch/tile/include/uapi/arch/abi.h @@ -20,58 +20,17 @@ #ifndef __ARCH_ABI_H__ -#if !defined __need_int_reg_t && !defined __DOXYGEN__ -# define __ARCH_ABI_H__ -# include <arch/chip.h> -#endif - -/* Provide the basic machine types. */ -#ifndef __INT_REG_BITS - -/** Number of bits in a register. */ -#if defined __tilegx__ -# define __INT_REG_BITS 64 -#elif defined __tilepro__ -# define __INT_REG_BITS 32 -#elif !defined __need_int_reg_t +#ifndef __tile__ /* support uncommon use of arch headers in non-tile builds */ # include <arch/chip.h> # define __INT_REG_BITS CHIP_WORD_SIZE() -#else -# error Unrecognized architecture with __need_int_reg_t -#endif - -#if __INT_REG_BITS == 64 - -#ifndef __ASSEMBLER__ -/** Unsigned type that can hold a register. */ -typedef unsigned long long __uint_reg_t; - -/** Signed type that can hold a register. */ -typedef long long __int_reg_t; -#endif - -/** String prefix to use for printf(). */ -#define __INT_REG_FMT "ll" - -#else - -#ifndef __ASSEMBLER__ -/** Unsigned type that can hold a register. */ -typedef unsigned long __uint_reg_t; - -/** Signed type that can hold a register. */ -typedef long __int_reg_t; -#endif - -/** String prefix to use for printf(). */ -#define __INT_REG_FMT "l" - #endif -#endif /* __INT_REG_BITS */ +#include <arch/intreg.h> +/* __need_int_reg_t is deprecated: just include <arch/intreg.h> */ #ifndef __need_int_reg_t +#define __ARCH_ABI_H__ #ifndef __ASSEMBLER__ /** Unsigned type that can hold a register. */ diff --git a/arch/tile/include/uapi/arch/intreg.h b/arch/tile/include/uapi/arch/intreg.h new file mode 100644 index 000000000000..1cf2fbf74306 --- /dev/null +++ b/arch/tile/include/uapi/arch/intreg.h @@ -0,0 +1,70 @@ +/* + * Copyright 2017 Tilera Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for + * more details. + */ + +/** + * @file + * + * Provide types and defines for the type that can hold a register, + * in the implementation namespace. + */ + +#ifndef __ARCH_INTREG_H__ +#define __ARCH_INTREG_H__ + +/* + * Get number of bits in a register. __INT_REG_BITS may be defined + * prior to including this header to force a particular bit width. + */ + +#ifndef __INT_REG_BITS +# if defined __tilegx__ +# define __INT_REG_BITS 64 +# elif defined __tilepro__ +# define __INT_REG_BITS 32 +# else +# error Unrecognized architecture +# endif +#endif + +#if __INT_REG_BITS == 64 + +# ifndef __ASSEMBLER__ +/** Unsigned type that can hold a register. */ +typedef unsigned long long __uint_reg_t; + +/** Signed type that can hold a register. */ +typedef long long __int_reg_t; +# endif + +/** String prefix to use for printf(). */ +# define __INT_REG_FMT "ll" + +#elif __INT_REG_BITS == 32 + +# ifndef __ASSEMBLER__ +/** Unsigned type that can hold a register. */ +typedef unsigned long __uint_reg_t; + +/** Signed type that can hold a register. */ +typedef long __int_reg_t; +# endif + +/** String prefix to use for printf(). */ +# define __INT_REG_FMT "l" + +#else +# error Unrecognized value of __INT_REG_BITS +#endif + +#endif /* !__ARCH_INTREG_H__ */ diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index 3a97e4d7205c..5f757e04bcd2 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c @@ -857,36 +857,6 @@ void __init mem_init(void) #endif } -/* - * this is for the non-NUMA, single node SMP system case. - * Specifically, in the case of x86, we will always add - * memory to the highmem for now. - */ -#ifndef CONFIG_NEED_MULTIPLE_NODES -int arch_add_memory(u64 start, u64 size, bool for_device) -{ - struct pglist_data *pgdata = &contig_page_data; - struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1; - unsigned long start_pfn = start >> PAGE_SHIFT; - unsigned long nr_pages = size >> PAGE_SHIFT; - - return __add_pages(zone, start_pfn, nr_pages); -} - -int remove_memory(u64 start, u64 size) -{ - return -EINVAL; -} - -#ifdef CONFIG_MEMORY_HOTREMOVE -int arch_remove_memory(u64 start, u64 size) -{ - /* TODO */ - return -EBUSY; -} -#endif -#endif - struct kmem_cache *pgd_cache; void __init pgtable_cache_init(void) diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index 0769066929c6..0a3bfd1fefcd 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -69,6 +69,20 @@ source "kernel/Kconfig.freezer" menu "System Type" +config UNICORE32_OLDABI + bool "Allow old ABI binaries to run with this kernel" + default y + select CLONE_BACKWARDS + select OLD_SIGACTION + select OLD_SIGSUSPEND3 + help + This option preserves the old syscall interface instead of the + asm-generic one. It also provides a compatibility layer to + intercept syscalls that have structure arguments which layout + in memory differs between the asm-generic ABI and this old one. + + If in doubt, say Y. + config MMU def_bool y diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index e9ad511c1043..ea47c4bf3aa7 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild @@ -45,14 +45,11 @@ generic-y += setup.h generic-y += shmbuf.h generic-y += shmparam.h generic-y += siginfo.h -generic-y += signal.h generic-y += sizes.h generic-y += socket.h generic-y += sockios.h -generic-y += stat.h generic-y += statfs.h generic-y += swab.h -generic-y += syscalls.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h diff --git a/arch/unicore32/include/asm/signal.h b/arch/unicore32/include/asm/signal.h new file mode 100644 index 000000000000..a87519883ea6 --- /dev/null +++ b/arch/unicore32/include/asm/signal.h @@ -0,0 +1,21 @@ +/* + * linux/arch/unicore32/include/asm/signal.h + * + * Code specific to UniCore ISA + * + * Copyright (C) 2014 GUAN Xuetao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __UNICORE32_ASM_SIGNAL_H__ +#define __UNICORE32_ASM_SIGNAL_H__ + +#ifdef CONFIG_UNICORE32_OLDABI +#define SA_RESTORER 0x04000000 +#endif + +#include <asm-generic/signal.h> + +#endif /* __UNICORE32_ASM_SIGNAL_H__ */ diff --git a/arch/unicore32/include/asm/syscalls.h b/arch/unicore32/include/asm/syscalls.h new file mode 100644 index 000000000000..362cf4d15b67 --- /dev/null +++ b/arch/unicore32/include/asm/syscalls.h @@ -0,0 +1,25 @@ +/* + * linux/arch/unicore32/include/asm/syscalls.h + * + * Code specific to UniCore ISA + * + * Copyright (C) 2014 GUAN Xuetao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __UNICORE32_ASM_SYSCALLS_H__ +#define __UNICORE32_ASM_SYSCALLS_H__ + +#include <asm-generic/syscalls.h> + +#ifdef CONFIG_UNICORE32_OLDABI +/* Wrapper functions */ +extern asmlinkage long sys_clone_wrapper(unsigned long clone_flags, + unsigned long newsp, int __user *parent_tidptr, + int tls_val, int __user *child_tidptr); +extern asmlinkage long sys_sigreturn_wrapper(struct pt_regs *regs); +#endif /* CONFIG_UNICORE32_OLDABI */ + +#endif /* __UNICORE32_ASM_SYSCALLS_H__ */ diff --git a/arch/unicore32/include/uapi/asm/sigcontext.h b/arch/unicore32/include/uapi/asm/sigcontext.h index 6a2d7671c052..cbc3446b9c03 100644 --- a/arch/unicore32/include/uapi/asm/sigcontext.h +++ b/arch/unicore32/include/uapi/asm/sigcontext.h @@ -18,6 +18,7 @@ * before the signal handler was invoked. Note: only add new entries * to the end of the structure. */ +#ifndef CONFIG_UNICORE32_OLDABI struct sigcontext { unsigned long trap_no; unsigned long error_code; @@ -25,5 +26,18 @@ struct sigcontext { unsigned long fault_address; struct pt_regs regs; }; +#else +struct pt_regs_sigcontext { + unsigned long uregs[33]; +}; + +struct sigcontext { + unsigned long trap_no; + unsigned long error_code; + unsigned long oldmask; + struct pt_regs_sigcontext regs; + unsigned long fault_address; +}; +#endif /* CONFIG_UNICORE32_OLDABI */ #endif diff --git a/arch/unicore32/include/uapi/asm/stat-oldabi.h b/arch/unicore32/include/uapi/asm/stat-oldabi.h new file mode 100644 index 000000000000..d36ce133cef8 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/stat-oldabi.h @@ -0,0 +1,71 @@ +/* + * Code specific to UniCore32 ISA + * + * Copyright (C) 2014 GUAN Xuetao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __UNICORE32_ASM_STAT_OLDABI_H__ +#define __UNICORE32_ASM_STAT_OLDABI_H__ + +#define STAT_HAVE_NSEC 1 + +struct stat { + unsigned long st_dev; /* Device. */ + unsigned long st_ino; /* File serial number. */ + unsigned int st_mode; /* File mode. */ + unsigned int st_nlink; /* Link count. */ + unsigned int st_uid; /* User ID of the file's owner. */ + unsigned int st_gid; /* Group ID of the file's group. */ + unsigned long st_rdev; /* Device number, if device. */ + unsigned long __pad1; + long st_size; /* Size of file, in bytes. */ + int st_blksize; /* Optimal block size for I/O. */ + int __pad2; + long st_blocks; /* Number 512-byte blocks allocated. */ + int st_atime; /* Time of last access. */ + unsigned int st_atime_nsec; + int st_mtime; /* Time of last modification. */ + unsigned int st_mtime_nsec; + int st_ctime; /* Time of last status change. */ + unsigned int st_ctime_nsec; + unsigned int __unused4; + unsigned int __unused5; +}; + +/* + * This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + * Note: The kernel zero's the padded region because glibc might read them + * in the hope that the kernel has stretched to using larger sizes. + */ +#define STAT64_HAS_BROKEN_ST_INO + +struct stat64 { + unsigned long long st_dev; /* Device. */ + unsigned char __pad0[4]; + unsigned long __st_ino; + unsigned int st_mode; /* File mode. */ + unsigned int st_nlink; /* Link count. */ + unsigned int st_uid; /* UID of the file's owner. */ + unsigned int st_gid; /* GID of the file's group. */ + unsigned long long st_rdev; /* Device number, if device. */ + + unsigned char __pad3[4]; + + long long st_size; /* Size of file, in bytes. */ + int st_blksize; /* Optimal block size for I/O. */ + long long st_blocks; /* Number 512-byte blocks allocated. */ + int st_atime; /* Time of last access. */ + unsigned int st_atime_nsec; + int st_mtime; /* Time of last modification. */ + unsigned int st_mtime_nsec; + int st_ctime; /* Time of last status change. */ + unsigned int st_ctime_nsec; + + unsigned long long st_ino; +}; + +#endif /* __UNICORE32_ASM_STAT_OLDABI_H__ */ diff --git a/arch/unicore32/include/uapi/asm/stat.h b/arch/unicore32/include/uapi/asm/stat.h new file mode 100644 index 000000000000..2cff377d44e3 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/stat.h @@ -0,0 +1,19 @@ +/* + * Code specific to UniCore32 ISA + * + * Copyright (C) 2014 GUAN Xuetao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __UNICORE32_ASM_STAT_H__ +#define __UNICORE32_ASM_STAT_H__ + +#ifndef CONFIG_UNICORE32_OLDABI +#include <asm-generic/stat.h> +#else +#include <asm/stat-oldabi.h> +#endif /* CONFIG_UNICORE32_OLDABI */ + +#endif /* __UNICORE32_ASM_STAT_H__ */ diff --git a/arch/unicore32/include/uapi/asm/unistd-oldabi.h b/arch/unicore32/include/uapi/asm/unistd-oldabi.h new file mode 100644 index 000000000000..0c24fcf3a301 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/unistd-oldabi.h @@ -0,0 +1,770 @@ +#ifndef CONFIG_UNICORE32_OLDABI +#error unistd-oldabi.h is ONLY used when CONFIG_UNICORE32_OLDABI defined +#endif + +#define __NR_SYSCALL_BASE 0x900000 + +#ifndef __SYSCALL +#define __SYSCALL(x, y) +#endif + +#define __NR_restart_syscall 0 +__SYSCALL(__NR_restart_syscall, sys_restart_syscall) +#define __NR_exit 1 +__SYSCALL(__NR_exit, sys_exit) +#define __NR_fork 2 +__SYSCALL(__NR_fork, sys_fork) +#define __NR_read 3 +__SYSCALL(__NR_read, sys_read) +#define __NR_write 4 +__SYSCALL(__NR_write, sys_write) +#define __NR_open 5 +__SYSCALL(__NR_open, sys_open) +#define __NR_close 6 +__SYSCALL(__NR_close, sys_close) + /* 7 was sys_waitpid */ +#define __NR_creat 8 +__SYSCALL(__NR_creat, sys_creat) +#define __NR_link 9 +__SYSCALL(__NR_link, sys_link) +#define __NR_unlink 10 +__SYSCALL(__NR_unlink, sys_unlink) +#define __NR_execve 11 +__SYSCALL(__NR_execve, sys_execve) +#define __NR_chdir 12 +__SYSCALL(__NR_chdir, sys_chdir) +#define __NR_time 13 +__SYSCALL(__NR_time, sys_time) +#define __NR_mknod 14 +__SYSCALL(__NR_mknod, sys_mknod) +#define __NR_chmod 15 +__SYSCALL(__NR_chmod, sys_chmod) +#define __NR_lchown 16 +__SYSCALL(__NR_lchown, sys_ni_syscall) + /* 17 was sys_break */ + /* 18 was sys_stat */ +#define __NR_lseek 19 +__SYSCALL(__NR_lseek, sys_lseek) +#define __NR_getpid 20 +__SYSCALL(__NR_getpid, sys_getpid) +#define __NR_mount 21 +__SYSCALL(__NR_mount, sys_mount) +#define __NR_umount 22 +__SYSCALL(__NR_umount, sys_oldumount) +#define __NR_setuid 23 +__SYSCALL(__NR_setuid, sys_ni_syscall) +#define __NR_getuid 24 +__SYSCALL(__NR_getuid, sys_ni_syscall) +#define __NR_stime 25 +__SYSCALL(__NR_stime, sys_stime) +#define __NR_ptrace 26 +__SYSCALL(__NR_ptrace, sys_ptrace) +#define __NR_alarm 27 +__SYSCALL(__NR_alarm, sys_alarm) + /* 28 was sys_fstat */ +#define __NR_pause 29 +__SYSCALL(__NR_pause, sys_pause) +#define __NR_utime 30 +__SYSCALL(__NR_utime, sys_utime) + /* 31 was sys_stty */ + /* 32 was sys_gtty */ +#define __NR_access 33 +__SYSCALL(__NR_access, sys_access) +#define __NR_nice 34 +__SYSCALL(__NR_nice, sys_nice) + /* 35 was sys_ftime */ +#define __NR_sync 36 +__SYSCALL(__NR_sync, sys_sync) +#define __NR_kill 37 +__SYSCALL(__NR_kill, sys_kill) +#define __NR_rename 38 +__SYSCALL(__NR_rename, sys_rename) +#define __NR_mkdir 39 +__SYSCALL(__NR_mkdir, sys_mkdir) +#define __NR_rmdir 40 +__SYSCALL(__NR_rmdir, sys_rmdir) +#define __NR_dup 41 +__SYSCALL(__NR_dup, sys_dup) +#define __NR_pipe 42 +__SYSCALL(__NR_pipe, sys_pipe) +#define __NR_times 43 +__SYSCALL(__NR_times, sys_times) + /* 44 was sys_prof */ +#define __NR_brk 45 +__SYSCALL(__NR_brk, sys_brk) +#define __NR_setgid 46 +__SYSCALL(__NR_setgid, sys_ni_syscall) +#define __NR_getgid 47 +__SYSCALL(__NR_getgid, sys_ni_syscall) + /* 48 was sys_signal */ +#define __NR_geteuid 49 +__SYSCALL(__NR_geteuid, sys_ni_syscall) +#define __NR_getegid 50 +__SYSCALL(__NR_getegid, sys_ni_syscall) +#define __NR_acct 51 +__SYSCALL(__NR_acct, sys_acct) +#define __NR_umount2 52 +__SYSCALL(__NR_umount2, sys_umount) + /* 53 was sys_lock */ +#define __NR_ioctl 54 +__SYSCALL(__NR_ioctl, sys_ioctl) +#define __NR_fcntl 55 +__SYSCALL(__NR_fcntl, sys_fcntl) + /* 56 was sys_mpx */ +#define __NR_setpgid 57 +__SYSCALL(__NR_setpgid, sys_setpgid) + /* 58 was sys_ulimit */ + /* 59 was sys_olduname */ +#define __NR_umask 60 +__SYSCALL(__NR_umask, sys_umask) +#define __NR_chroot 61 +__SYSCALL(__NR_chroot, sys_chroot) +#define __NR_ustat 62 +__SYSCALL(__NR_ustat, sys_ustat) +#define __NR_dup2 63 +__SYSCALL(__NR_dup2, sys_dup2) +#define __NR_getppid 64 +__SYSCALL(__NR_getppid, sys_getppid) +#define __NR_getpgrp 65 +__SYSCALL(__NR_getpgrp, sys_getpgrp) +#define __NR_setsid 66 +__SYSCALL(__NR_setsid, sys_setsid) +#define __NR_sigaction 67 +__SYSCALL(__NR_sigaction, sys_sigaction) + /* 68 was sys_sgetmask */ + /* 69 was sys_ssetmask */ +#define __NR_setreuid 70 +__SYSCALL(__NR_setreuid, sys_ni_syscall) +#define __NR_setregid 71 +__SYSCALL(__NR_setregid, sys_ni_syscall) +#define __NR_sigsuspend 72 +__SYSCALL(__NR_sigsuspend, sys_sigsuspend) +#define __NR_sigpending 73 +__SYSCALL(__NR_sigpending, sys_sigpending) +#define __NR_sethostname 74 +__SYSCALL(__NR_sethostname, sys_sethostname) +#define __NR_setrlimit 75 +__SYSCALL(__NR_setrlimit, sys_setrlimit) +#define __NR_getrlimit 76 +__SYSCALL(__NR_getrlimit, sys_old_getrlimit) + /* Back compat 2GB limited rlimit */ +#define __NR_getrusage 77 +__SYSCALL(__NR_getrusage, sys_getrusage) +#define __NR_gettimeofday 78 +__SYSCALL(__NR_gettimeofday, sys_gettimeofday) +#define __NR_settimeofday 79 +__SYSCALL(__NR_settimeofday, sys_settimeofday) +#define __NR_getgroups 80 +__SYSCALL(__NR_getgroups, sys_ni_syscall) +#define __NR_setgroups 81 +__SYSCALL(__NR_setgroups, sys_ni_syscall) +#define __NR_select 82 +__SYSCALL(__NR_select, sys_old_select) +#define __NR_symlink 83 +__SYSCALL(__NR_symlink, sys_symlink) + /* 84 was sys_lstat */ +#define __NR_readlink 85 +__SYSCALL(__NR_readlink, sys_readlink) +#define __NR_uselib 86 +__SYSCALL(__NR_uselib, sys_uselib) +#define __NR_swapon 87 +__SYSCALL(__NR_swapon, sys_swapon) +#define __NR_reboot 88 +__SYSCALL(__NR_reboot, sys_reboot) +#define __NR_readdir 89 +__SYSCALL(__NR_readdir, sys_old_readdir) +#define __NR_mmap 90 +__SYSCALL(__NR_mmap, sys_old_mmap) +#define __NR_munmap 91 +__SYSCALL(__NR_munmap, sys_munmap) +#define __NR_truncate 92 +__SYSCALL(__NR_truncate, sys_truncate) +#define __NR_ftruncate 93 +__SYSCALL(__NR_ftruncate, sys_ftruncate) +#define __NR_fchmod 94 +__SYSCALL(__NR_fchmod, sys_fchmod) +#define __NR_fchown 95 +__SYSCALL(__NR_fchown, sys_ni_syscall) +#define __NR_getpriority 96 +__SYSCALL(__NR_getpriority, sys_getpriority) +#define __NR_setpriority 97 +__SYSCALL(__NR_setpriority, sys_setpriority) + /* 98 was sys_profil */ +#define __NR_statfs 99 +__SYSCALL(__NR_statfs, sys_statfs) +#define __NR_fstatfs 100 +__SYSCALL(__NR_fstatfs, sys_fstatfs) + /* 101 was sys_ioperm */ +#define __NR_socketcall 102 +__SYSCALL(__NR_socketcall, sys_socketcall) +#define __NR_syslog 103 +__SYSCALL(__NR_syslog, sys_syslog) +#define __NR_setitimer 104 +__SYSCALL(__NR_setitimer, sys_setitimer) +#define __NR_getitimer 105 +__SYSCALL(__NR_getitimer, sys_getitimer) +#define __NR_stat 106 +__SYSCALL(__NR_stat, sys_newstat) +#define __NR_lstat 107 +__SYSCALL(__NR_lstat, sys_newlstat) +#define __NR_fstat 108 +__SYSCALL(__NR_fstat, sys_newfstat) + /* 109 was sys_uname */ + /* 110 was sys_iopl */ +#define __NR_vhangup 111 +__SYSCALL(__NR_vhangup, sys_vhangup) + /* 112 was sys_idle */ +#define __NR_syscall 113 +__SYSCALL(__NR_syscall, sys_ni_syscall) + /* syscall to call a syscall! */ +#define __NR_wait4 114 +__SYSCALL(__NR_wait4, sys_wait4) +#define __NR_swapoff 115 +__SYSCALL(__NR_swapoff, sys_swapoff) +#define __NR_sysinfo 116 +__SYSCALL(__NR_sysinfo, sys_sysinfo) +#define __NR_ipc 117 +__SYSCALL(__NR_ipc, sys_ipc) +#define __NR_fsync 118 +__SYSCALL(__NR_fsync, sys_fsync) +#define __NR_sigreturn 119 +__SYSCALL(__NR_sigreturn, sys_sigreturn_wrapper) +#define __NR_clone 120 +__SYSCALL(__NR_clone, sys_clone_wrapper) +#define __NR_setdomainname 121 +__SYSCALL(__NR_setdomainname, sys_setdomainname) +#define __NR_uname 122 +__SYSCALL(__NR_uname, sys_newuname) + /* 123 was sys_modify_ldt */ +#define __NR_adjtimex 124 +__SYSCALL(__NR_adjtimex, sys_adjtimex) +#define __NR_mprotect 125 +__SYSCALL(__NR_mprotect, sys_mprotect) +#define __NR_sigprocmask 126 +__SYSCALL(__NR_sigprocmask, sys_sigprocmask) + /* 127 was sys_create_module */ +#define __NR_init_module 128 +__SYSCALL(__NR_init_module, sys_init_module) +#define __NR_delete_module 129 +__SYSCALL(__NR_delete_module, sys_delete_module) + /* 130 was sys_get_kernel_syms */ +#define __NR_quotactl 131 +__SYSCALL(__NR_quotactl, sys_quotactl) +#define __NR_getpgid 132 +__SYSCALL(__NR_getpgid, sys_getpgid) +#define __NR_fchdir 133 +__SYSCALL(__NR_fchdir, sys_fchdir) +#define __NR_bdflush 134 +__SYSCALL(__NR_bdflush, sys_bdflush) +#define __NR_sysfs 135 +__SYSCALL(__NR_sysfs, sys_sysfs) +#define __NR_personality 136 +__SYSCALL(__NR_personality, sys_personality) + /* 137 was sys_afs_syscall */ +#define __NR_setfsuid 138 +__SYSCALL(__NR_setfsuid, sys_ni_syscall) +#define __NR_setfsgid 139 +__SYSCALL(__NR_setfsgid, sys_ni_syscall) +#define __NR__llseek 140 +__SYSCALL(__NR__llseek, sys_llseek) +#define __NR_getdents 141 +__SYSCALL(__NR_getdents, sys_getdents) +#define __NR__newselect 142 +__SYSCALL(__NR__newselect, sys_select) +#define __NR_flock 143 +__SYSCALL(__NR_flock, sys_flock) +#define __NR_msync 144 +__SYSCALL(__NR_msync, sys_msync) +#define __NR_readv 145 +__SYSCALL(__NR_readv, sys_readv) +#define __NR_writev 146 +__SYSCALL(__NR_writev, sys_writev) +#define __NR_getsid 147 +__SYSCALL(__NR_getsid, sys_getsid) +#define __NR_fdatasync 148 +__SYSCALL(__NR_fdatasync, sys_fdatasync) +#define __NR__sysctl 149 +__SYSCALL(__NR__sysctl, sys_sysctl) +#define __NR_mlock 150 +__SYSCALL(__NR_mlock, sys_mlock) +#define __NR_munlock 151 +__SYSCALL(__NR_munlock, sys_munlock) +#define __NR_mlockall 152 +__SYSCALL(__NR_mlockall, sys_mlockall) +#define __NR_munlockall 153 +__SYSCALL(__NR_munlockall, sys_munlockall) +#define __NR_sched_setparam 154 +__SYSCALL(__NR_sched_setparam, sys_sched_setparam) +#define __NR_sched_getparam 155 +__SYSCALL(__NR_sched_getparam, sys_sched_getparam) +#define __NR_sched_setscheduler 156 +__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler) +#define __NR_sched_getscheduler 157 +__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler) +#define __NR_sched_yield 158 +__SYSCALL(__NR_sched_yield, sys_sched_yield) +#define __NR_sched_get_priority_max 159 +__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max) +#define __NR_sched_get_priority_min 160 +__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min) +#define __NR_sched_rr_get_interval 161 +__SYSCALL(__NR_sched_rr_get_interval, sys_sched_rr_get_interval) +#define __NR_nanosleep 162 +__SYSCALL(__NR_nanosleep, sys_nanosleep) +#define __NR_mremap 163 +__SYSCALL(__NR_mremap, sys_mremap) +#define __NR_setresuid 164 +__SYSCALL(__NR_setresuid, sys_ni_syscall) +#define __NR_getresuid 165 +__SYSCALL(__NR_getresuid, sys_ni_syscall) + /* 166 was sys_vm86 */ + /* 167 was sys_query_module */ +#define __NR_poll 168 +__SYSCALL(__NR_poll, sys_poll) +#define __NR_nfsservctl 169 +__SYSCALL(__NR_nfsservctl, sys_ni_syscall) +#define __NR_setresgid 170 +__SYSCALL(__NR_setresgid, sys_ni_syscall) +#define __NR_getresgid 171 +__SYSCALL(__NR_getresgid, sys_ni_syscall) +#define __NR_prctl 172 +__SYSCALL(__NR_prctl, sys_prctl) +#define __NR_rt_sigreturn 173 +__SYSCALL(__NR_rt_sigreturn, sys_rt_sigreturn) +#define __NR_rt_sigaction 174 +__SYSCALL(__NR_rt_sigaction, sys_rt_sigaction) +#define __NR_rt_sigprocmask 175 +__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask) +#define __NR_rt_sigpending 176 +__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending) +#define __NR_rt_sigtimedwait 177 +__SYSCALL(__NR_rt_sigtimedwait, sys_rt_sigtimedwait) +#define __NR_rt_sigqueueinfo 178 +__SYSCALL(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo) +#define __NR_rt_sigsuspend 179 +__SYSCALL(__NR_rt_sigsuspend, sys_rt_sigsuspend) +#define __NR_pread64 180 +__SYSCALL(__NR_pread64, sys_pread64) +#define __NR_pwrite64 181 +__SYSCALL(__NR_pwrite64, sys_pwrite64) +#define __NR_chown 182 +__SYSCALL(__NR_chown, sys_ni_syscall) +#define __NR_getcwd 183 +__SYSCALL(__NR_getcwd, sys_getcwd) +#define __NR_capget 184 +__SYSCALL(__NR_capget, sys_capget) +#define __NR_capset 185 +__SYSCALL(__NR_capset, sys_capset) +#define __NR_sigaltstack 186 +__SYSCALL(__NR_sigaltstack, sys_sigaltstack) +#define __NR_sendfile 187 +__SYSCALL(__NR_sendfile, sys_sendfile) + /* 188 reserved */ + /* 189 reserved */ +#define __NR_vfork 190 +__SYSCALL(__NR_vfork, sys_vfork) +#define __NR_ugetrlimit 191 +__SYSCALL(__NR_ugetrlimit, sys_getrlimit) + /* SuS compliant getrlimit */ +#define __NR_mmap2 192 +__SYSCALL(__NR_mmap2, sys_mmap_pgoff) +#define __NR_truncate64 193 +__SYSCALL(__NR_truncate64, sys_truncate64) +#define __NR_ftruncate64 194 +__SYSCALL(__NR_ftruncate64, sys_ftruncate64) +#define __NR_stat64 195 +__SYSCALL(__NR_stat64, sys_stat64) +#define __NR_lstat64 196 +__SYSCALL(__NR_lstat64, sys_lstat64) +#define __NR_fstat64 197 +__SYSCALL(__NR_fstat64, sys_fstat64) +#define __NR_lchown32 198 +__SYSCALL(__NR_lchown32, sys_lchown) +#define __NR_getuid32 199 +__SYSCALL(__NR_getuid32, sys_getuid) +#define __NR_getgid32 200 +__SYSCALL(__NR_getgid32, sys_getgid) +#define __NR_geteuid32 201 +__SYSCALL(__NR_geteuid32, sys_geteuid) +#define __NR_getegid32 202 +__SYSCALL(__NR_getegid32, sys_getegid) +#define __NR_setreuid32 203 +__SYSCALL(__NR_setreuid32, sys_setreuid) +#define __NR_setregid32 204 +__SYSCALL(__NR_setregid32, sys_setregid) +#define __NR_getgroups32 205 +__SYSCALL(__NR_getgroups32, sys_getgroups) +#define __NR_setgroups32 206 +__SYSCALL(__NR_setgroups32, sys_setgroups) +#define __NR_fchown32 207 +__SYSCALL(__NR_fchown32, sys_fchown) +#define __NR_setresuid32 208 +__SYSCALL(__NR_setresuid32, sys_setresuid) +#define __NR_getresuid32 209 +__SYSCALL(__NR_getresuid32, sys_getresuid) +#define __NR_setresgid32 210 +__SYSCALL(__NR_setresgid32, sys_setresgid) +#define __NR_getresgid32 211 +__SYSCALL(__NR_getresgid32, sys_getresgid) +#define __NR_chown32 212 +__SYSCALL(__NR_chown32, sys_chown) +#define __NR_setuid32 213 +__SYSCALL(__NR_setuid32, sys_setuid) +#define __NR_setgid32 214 +__SYSCALL(__NR_setgid32, sys_setgid) +#define __NR_setfsuid32 215 +__SYSCALL(__NR_setfsuid32, sys_setfsuid) +#define __NR_setfsgid32 216 +__SYSCALL(__NR_setfsgid32, sys_setfsgid) +#define __NR_getdents64 217 +__SYSCALL(__NR_getdents64, sys_getdents64) +#define __NR_pivot_root 218 +__SYSCALL(__NR_pivot_root, sys_pivot_root) +#define __NR_mincore 219 +__SYSCALL(__NR_mincore, sys_mincore) +#define __NR_madvise 220 +__SYSCALL(__NR_madvise, sys_madvise) +#define __NR_fcntl64 221 +__SYSCALL(__NR_fcntl64, sys_fcntl64) + /* 222 for tux */ + /* 223 is unused */ +#define __NR_gettid 224 +__SYSCALL(__NR_gettid, sys_gettid) +#define __NR_readahead 225 +__SYSCALL(__NR_readahead, sys_readahead) +#define __NR_setxattr 226 +__SYSCALL(__NR_setxattr, sys_setxattr) +#define __NR_lsetxattr 227 +__SYSCALL(__NR_lsetxattr, sys_lsetxattr) +#define __NR_fsetxattr 228 +__SYSCALL(__NR_fsetxattr, sys_fsetxattr) +#define __NR_getxattr 229 +__SYSCALL(__NR_getxattr, sys_getxattr) +#define __NR_lgetxattr 230 +__SYSCALL(__NR_lgetxattr, sys_lgetxattr) +#define __NR_fgetxattr 231 +__SYSCALL(__NR_fgetxattr, sys_fgetxattr) +#define __NR_listxattr 232 +__SYSCALL(__NR_listxattr, sys_listxattr) +#define __NR_llistxattr 233 +__SYSCALL(__NR_llistxattr, sys_llistxattr) +#define __NR_flistxattr 234 +__SYSCALL(__NR_flistxattr, sys_flistxattr) +#define __NR_removexattr 235 +__SYSCALL(__NR_removexattr, sys_removexattr) +#define __NR_lremovexattr 236 +__SYSCALL(__NR_lremovexattr, sys_lremovexattr) +#define __NR_fremovexattr 237 +__SYSCALL(__NR_fremovexattr, sys_fremovexattr) +#define __NR_tkill 238 +__SYSCALL(__NR_tkill, sys_tkill) +#define __NR_sendfile64 239 +__SYSCALL(__NR_sendfile64, sys_sendfile64) +#define __NR_futex 240 +__SYSCALL(__NR_futex, sys_futex) +#define __NR_sched_setaffinity 241 +__SYSCALL(__NR_sched_setaffinity, sys_sched_setaffinity) +#define __NR_sched_getaffinity 242 +__SYSCALL(__NR_sched_getaffinity, sys_sched_getaffinity) +#define __NR_io_setup 243 +__SYSCALL(__NR_io_setup, sys_io_setup) +#define __NR_io_destroy 244 +__SYSCALL(__NR_io_destroy, sys_io_destroy) +#define __NR_io_getevents 245 +__SYSCALL(__NR_io_getevents, sys_io_getevents) +#define __NR_io_submit 246 +__SYSCALL(__NR_io_submit, sys_io_submit) +#define __NR_io_cancel 247 +__SYSCALL(__NR_io_cancel, sys_io_cancel) +#define __NR_exit_group 248 +__SYSCALL(__NR_exit_group, sys_exit_group) +#define __NR_lookup_dcookie 249 +__SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie) +#define __NR_epoll_create 250 +__SYSCALL(__NR_epoll_create, sys_epoll_create) +#define __NR_epoll_ctl 251 +__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl) +#define __NR_epoll_wait 252 +__SYSCALL(__NR_epoll_wait, sys_epoll_wait) +#define __NR_remap_file_pages 253 +__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages) + /* 254 for set_thread_area */ + /* 255 for get_thread_area */ +#define __NR_set_tid_address 256 +__SYSCALL(__NR_set_tid_address, sys_set_tid_address) +#define __NR_timer_create 257 +__SYSCALL(__NR_timer_create, sys_timer_create) +#define __NR_timer_settime 258 +__SYSCALL(__NR_timer_settime, sys_timer_settime) +#define __NR_timer_gettime 259 +__SYSCALL(__NR_timer_gettime, sys_timer_gettime) +#define __NR_timer_getoverrun 260 +__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun) +#define __NR_timer_delete 261 +__SYSCALL(__NR_timer_delete, sys_timer_delete) +#define __NR_clock_settime 262 +__SYSCALL(__NR_clock_settime, sys_clock_settime) +#define __NR_clock_gettime 263 +__SYSCALL(__NR_clock_gettime, sys_clock_gettime) +#define __NR_clock_getres 264 +__SYSCALL(__NR_clock_getres, sys_clock_getres) +#define __NR_clock_nanosleep 265 +__SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep) + /* 266 was sys_statfs64_wrapper */ + /* 267 was sys_fstatfs64_wrapper */ +#define __NR_tgkill 268 +__SYSCALL(__NR_tgkill, sys_tgkill) +#define __NR_utimes 269 +__SYSCALL(__NR_utimes, sys_utimes) + /* 270 was sys_fadvise64_64 */ + /* 271 was sys_pciconfig_iobase */ + /* 272 was sys_pciconfig_read */ + /* 273 was sys_pciconfig_write */ +#define __NR_mq_open 274 +__SYSCALL(__NR_mq_open, sys_mq_open) +#define __NR_mq_unlink 275 +__SYSCALL(__NR_mq_unlink, sys_mq_unlink) +#define __NR_mq_timedsend 276 +__SYSCALL(__NR_mq_timedsend, sys_mq_timedsend) +#define __NR_mq_timedreceive 277 +__SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive) +#define __NR_mq_notify 278 +__SYSCALL(__NR_mq_notify, sys_mq_notify) +#define __NR_mq_getsetattr 279 +__SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr) +#define __NR_waitid 280 +__SYSCALL(__NR_waitid, sys_waitid) +#define __NR_socket 281 +__SYSCALL(__NR_socket, sys_socket) +#define __NR_bind 282 +__SYSCALL(__NR_bind, sys_bind) +#define __NR_connect 283 +__SYSCALL(__NR_connect, sys_connect) +#define __NR_listen 284 +__SYSCALL(__NR_listen, sys_listen) +#define __NR_accept 285 +__SYSCALL(__NR_accept, sys_accept) +#define __NR_getsockname 286 +__SYSCALL(__NR_getsockname, sys_getsockname) +#define __NR_getpeername 287 +__SYSCALL(__NR_getpeername, sys_getpeername) +#define __NR_socketpair 288 +__SYSCALL(__NR_socketpair, sys_socketpair) +#define __NR_send 289 +__SYSCALL(__NR_send, sys_send) +#define __NR_sendto 290 +__SYSCALL(__NR_sendto, sys_sendto) +#define __NR_recv 291 +__SYSCALL(__NR_recv, sys_recv) +#define __NR_recvfrom 292 +__SYSCALL(__NR_recvfrom, sys_recvfrom) +#define __NR_shutdown 293 +__SYSCALL(__NR_shutdown, sys_shutdown) +#define __NR_setsockopt 294 +__SYSCALL(__NR_setsockopt, sys_setsockopt) +#define __NR_getsockopt 295 +__SYSCALL(__NR_getsockopt, sys_getsockopt) +#define __NR_sendmsg 296 +__SYSCALL(__NR_sendmsg, sys_sendmsg) +#define __NR_recvmsg 297 +__SYSCALL(__NR_recvmsg, sys_recvmsg) +#define __NR_semop 298 +__SYSCALL(__NR_semop, sys_semop) +#define __NR_semget 299 +__SYSCALL(__NR_semget, sys_semget) +#define __NR_semctl 300 +__SYSCALL(__NR_semctl, sys_semctl) +#define __NR_msgsnd 301 +__SYSCALL(__NR_msgsnd, sys_msgsnd) +#define __NR_msgrcv 302 +__SYSCALL(__NR_msgrcv, sys_msgrcv) +#define __NR_msgget 303 +__SYSCALL(__NR_msgget, sys_msgget) +#define __NR_msgctl 304 +__SYSCALL(__NR_msgctl, sys_msgctl) +#define __NR_shmat 305 +__SYSCALL(__NR_shmat, sys_shmat) +#define __NR_shmdt 306 +__SYSCALL(__NR_shmdt, sys_shmdt) +#define __NR_shmget 307 +__SYSCALL(__NR_shmget, sys_shmget) +#define __NR_shmctl 308 +__SYSCALL(__NR_shmctl, sys_shmctl) +#define __NR_add_key 309 +__SYSCALL(__NR_add_key, sys_add_key) +#define __NR_request_key 310 +__SYSCALL(__NR_request_key, sys_request_key) +#define __NR_keyctl 311 +__SYSCALL(__NR_keyctl, sys_keyctl) +#define __NR_semtimedop 312 +__SYSCALL(__NR_semtimedop, sys_semtimedop) + /* 313 was for vserver */ +#define __NR_ioprio_set 314 +__SYSCALL(__NR_ioprio_set, sys_ioprio_set) +#define __NR_ioprio_get 315 +__SYSCALL(__NR_ioprio_get, sys_ioprio_get) +#define __NR_inotify_init 316 +__SYSCALL(__NR_inotify_init, sys_inotify_init) +#define __NR_inotify_add_watch 317 +__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch) +#define __NR_inotify_rm_watch 318 +__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch) +#define __NR_mbind 319 +__SYSCALL(__NR_mbind, sys_mbind) +#define __NR_get_mempolicy 320 +__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy) +#define __NR_set_mempolicy 321 +__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy) +#define __NR_openat 322 +__SYSCALL(__NR_openat, sys_openat) +#define __NR_mkdirat 323 +__SYSCALL(__NR_mkdirat, sys_mkdirat) +#define __NR_mknodat 324 +__SYSCALL(__NR_mknodat, sys_mknodat) +#define __NR_fchownat 325 +__SYSCALL(__NR_fchownat, sys_fchownat) +#define __NR_futimesat 326 +__SYSCALL(__NR_futimesat, sys_futimesat) +#define __NR_fstatat64 327 +__SYSCALL(__NR_fstatat64, sys_fstatat64) +#define __NR_unlinkat 328 +__SYSCALL(__NR_unlinkat, sys_unlinkat) +#define __NR_renameat 329 +__SYSCALL(__NR_renameat, sys_renameat) +#define __NR_linkat 330 +__SYSCALL(__NR_linkat, sys_linkat) +#define __NR_symlinkat 331 +__SYSCALL(__NR_symlinkat, sys_symlinkat) +#define __NR_readlinkat 332 +__SYSCALL(__NR_readlinkat, sys_readlinkat) +#define __NR_fchmodat 333 +__SYSCALL(__NR_fchmodat, sys_fchmodat) +#define __NR_faccessat 334 +__SYSCALL(__NR_faccessat, sys_faccessat) +#define __NR_pselect6 335 +__SYSCALL(__NR_pselect6, sys_pselect6) +#define __NR_ppoll 336 +__SYSCALL(__NR_ppoll, sys_ppoll) +#define __NR_unshare 337 +__SYSCALL(__NR_unshare, sys_unshare) +#define __NR_set_robust_list 338 +__SYSCALL(__NR_set_robust_list, sys_set_robust_list) +#define __NR_get_robust_list 339 +__SYSCALL(__NR_get_robust_list, sys_get_robust_list) +#define __NR_splice 340 +__SYSCALL(__NR_splice, sys_splice) +#define __NR_uc32_sync_file_range 341 +__SYSCALL(__NR_uc32_sync_file_range, sys_sync_file_range2) +#define __NR_sync_file_range2 __NR_uc32_sync_file_range +#define __NR_tee 342 +__SYSCALL(__NR_tee, sys_tee) +#define __NR_vmsplice 343 +__SYSCALL(__NR_vmsplice, sys_vmsplice) +#define __NR_move_pages 344 +__SYSCALL(__NR_move_pages, sys_move_pages) +#define __NR_getcpu 345 +__SYSCALL(__NR_getcpu, sys_getcpu) +#define __NR_epoll_pwait 346 +__SYSCALL(__NR_epoll_pwait, sys_epoll_pwait) +#define __NR_kexec_load 347 +__SYSCALL(__NR_kexec_load, sys_kexec_load) +#define __NR_utimensat 348 +__SYSCALL(__NR_utimensat, sys_utimensat) +#define __NR_signalfd 349 +__SYSCALL(__NR_signalfd, sys_signalfd) +#define __NR_timerfd_create 350 +__SYSCALL(__NR_timerfd_create, sys_timerfd_create) +#define __NR_eventfd 351 +__SYSCALL(__NR_eventfd, sys_eventfd) +#define __NR_fallocate 352 +__SYSCALL(__NR_fallocate, sys_fallocate) +#define __NR_timerfd_settime 353 +__SYSCALL(__NR_timerfd_settime, sys_timerfd_settime) +#define __NR_timerfd_gettime 354 +__SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime) +#define __NR_signalfd4 355 +__SYSCALL(__NR_signalfd4, sys_signalfd4) +#define __NR_eventfd2 356 +__SYSCALL(__NR_eventfd2, sys_eventfd2) +#define __NR_epoll_create1 357 +__SYSCALL(__NR_epoll_create1, sys_epoll_create1) +#define __NR_dup3 358 +__SYSCALL(__NR_dup3, sys_dup3) +#define __NR_pipe2 359 +__SYSCALL(__NR_pipe2, sys_pipe2) +#define __NR_inotify_init1 360 +__SYSCALL(__NR_inotify_init1, sys_inotify_init1) +#define __NR_preadv 361 +__SYSCALL(__NR_preadv, sys_preadv) +#define __NR_pwritev 362 +__SYSCALL(__NR_pwritev, sys_pwritev) +#define __NR_rt_tgsigqueueinfo 363 +__SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) +#define __NR_perf_event_open 364 +__SYSCALL(__NR_perf_event_open, sys_perf_event_open) +#define __NR_recvmmsg 365 +__SYSCALL(__NR_recvmmsg, sys_recvmmsg) +#define __NR_accept4 366 +__SYSCALL(__NR_accept4, sys_accept4) +#define __NR_fanotify_init 367 +__SYSCALL(__NR_fanotify_init, sys_fanotify_init) +#define __NR_fanotify_mark 368 +__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark) +#define __NR_prlimit64 369 +__SYSCALL(__NR_prlimit64, sys_prlimit64) + +#undef __NR_syscalls +#define __NR_syscalls (__NR_prlimit64+1) + +#ifdef __KERNEL__ + +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION +#define __ARCH_WANT_SYS_RT_SIGSUSPEND +#define __ARCH_WANT_SYS_OLD_MMAP +#define __ARCH_WANT_SYS_OLD_SELECT +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_IPC +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FORK +#define __ARCH_WANT_SYS_VFORK +#define __ARCH_WANT_SYS_CLONE + +/* + * Unimplemented (or alternatively implemented) syscalls + */ +#define __IGNORE_fadvise64_64 1 +#define __IGNORE_migrate_pages 1 +#define __IGNORE_name_to_handle_at 1 +#define __IGNORE_open_by_handle_at 1 +#define __IGNORE_clock_adjtime 1 +#define __IGNORE_syncfs 1 +#define __IGNORE_sendmmsg 1 +#define __IGNORE_setns 1 +#define __IGNORE_statfs64 1 +#define __IGNORE_fstatfs64 1 +#define __IGNORE_process_vm_readv 1 +#define __IGNORE_process_vm_writev 1 +#define __IGNORE_kcmp 1 +#define __IGNORE_finit_module 1 +#define __IGNORE_sched_setattr 1 +#define __IGNORE_sched_getattr 1 +#define __IGNORE_renameat2 1 +#define __IGNORE_seccomp 1 +#define __IGNORE_getrandom 1 +#define __IGNORE_memfd_create 1 + +#endif /* __KERNEL__ */ diff --git a/arch/unicore32/include/uapi/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h index 1f63c476528e..9cf71c7bedb1 100644 --- a/arch/unicore32/include/uapi/asm/unistd.h +++ b/arch/unicore32/include/uapi/asm/unistd.h @@ -12,6 +12,14 @@ #define __ARCH_WANT_RENAMEAT +#ifndef CONFIG_UNICORE32_OLDABI + /* Use the standard ABI for syscalls. */ #include <asm-generic/unistd.h> #define __ARCH_WANT_SYS_CLONE + +#else + +#include <asm/unistd-oldabi.h> + +#endif /* CONFIG_UNICORE32_OLDABI */ diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index bcdedd80890e..3562d08192ae 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S @@ -668,6 +668,23 @@ __cr_alignment: #endif .ltorg +#ifdef CONFIG_UNICORE32_OLDABI +/* + * Special system call wrappers + */ +ENTRY(sys_clone_wrapper) + add ip, sp, #S_OFF + stw ip, [sp+], #4 + b sys_clone +ENDPROC(sys_clone_wrapper) + +ENTRY(sys_sigreturn_wrapper) + add r0, sp, #S_OFF + mov why, #0 @ prevent syscall restart handling + b __sys_sigreturn +ENDPROC(sys_sigreturn_wrapper) +#endif + ENTRY(sys_rt_sigreturn) add r0, sp, #S_OFF mov why, #0 @ prevent syscall restart handling diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c index 4ae51cf15ade..be75ef8c1e0c 100644 --- a/arch/unicore32/kernel/signal.c +++ b/arch/unicore32/kernel/signal.c @@ -23,9 +23,18 @@ /* * For UniCore syscalls, we encode the syscall number into the instruction. */ +#ifdef CONFIG_UNICORE32_OLDABI +#define SWI_SYS_SIGRETURN (0xff000000 | (__NR_SYSCALL_BASE) \ + | (__NR_sigreturn)) +#define SWI_SYS_RT_SIGRETURN (0xff000000 | (__NR_SYSCALL_BASE) \ + | (__NR_rt_sigreturn)) +#define SWI_SYS_RESTART (0xff000000 | (__NR_SYSCALL_BASE) \ + | (__NR_restart_syscall)) +#else #define SWI_SYS_SIGRETURN (0xff000000) /* error number for new abi */ #define SWI_SYS_RT_SIGRETURN (0xff000000 | (__NR_rt_sigreturn)) #define SWI_SYS_RESTART (0xff000000 | (__NR_restart_syscall)) +#endif #define KERN_SIGRETURN_CODE (KUSER_VECPAGE_BASE + 0x00000500) #define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes)) @@ -100,6 +109,38 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) return err; } +#ifdef CONFIG_UNICORE32_OLDABI +asmlinkage int __sys_sigreturn(struct pt_regs *regs) +{ + struct sigframe __user *frame; + + /* Always make any pending restarted system calls return -EINTR */ + current->restart_block.fn = do_no_restart_syscall; + + /* + * Since we stacked the signal on a 64-bit boundary, + * then 'sp' should be word aligned here. If it's + * not, then the user is trying to mess with us. + */ + if (regs->UCreg_sp & 7) + goto badframe; + + frame = (struct sigframe __user *)regs->UCreg_sp; + + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + + if (restore_sigframe(regs, frame)) + goto badframe; + + return regs->UCreg_00; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} +#endif + asmlinkage int __sys_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe __user *frame; diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index c1bdb9edcae7..76595408ff53 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c @@ -46,7 +46,7 @@ static inline void set_bios_x(void) pcibios_enabled = 1; set_memory_x(PAGE_OFFSET + BIOS_BEGIN, (BIOS_END - BIOS_BEGIN) >> PAGE_SHIFT); if (__supported_pte_mask & _PAGE_NX) - printk(KERN_INFO "PCI : PCI BIOS area is rw and x. Use pci=nobios if you want it NX.\n"); + printk(KERN_INFO "PCI: PCI BIOS area is rw and x. Use pci=nobios if you want it NX.\n"); } /* diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index d3a989e718f5..3cd6e12cfc46 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -141,7 +141,7 @@ int public_key_verify_signature(const struct public_key *pkey, * signature and returns that to us. */ ret = crypto_akcipher_verify(req); - if (ret == -EINPROGRESS) { + if ((ret == -EINPROGRESS) || (ret == -EBUSY)) { wait_for_completion(&compl.completion); ret = compl.err; } diff --git a/crypto/drbg.c b/crypto/drbg.c index fa749f470135..cdb27ac4b226 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -1767,9 +1767,8 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, break; case -EINPROGRESS: case -EBUSY: - ret = wait_for_completion_interruptible( - &drbg->ctr_completion); - if (!ret && !drbg->ctr_async_err) { + wait_for_completion(&drbg->ctr_completion); + if (!drbg->ctr_async_err) { reinit_completion(&drbg->ctr_completion); break; } diff --git a/crypto/gcm.c b/crypto/gcm.c index b7ad808be3d4..3841b5eafa7e 100644 --- a/crypto/gcm.c +++ b/crypto/gcm.c @@ -152,10 +152,8 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key, err = crypto_skcipher_encrypt(&data->req); if (err == -EINPROGRESS || err == -EBUSY) { - err = wait_for_completion_interruptible( - &data->result.completion); - if (!err) - err = data->result.err; + wait_for_completion(&data->result.completion); + err = data->result.err; } if (err) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 454bf9c34882..c16f74547804 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -4023,6 +4023,7 @@ static void rbd_queue_workfn(struct work_struct *work) switch (req_op(rq)) { case REQ_OP_DISCARD: + case REQ_OP_WRITE_ZEROES: op_type = OBJ_OP_DISCARD; break; case REQ_OP_WRITE: @@ -4420,6 +4421,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev) q->limits.discard_granularity = segment_size; q->limits.discard_alignment = segment_size; blk_queue_max_discard_sectors(q, segment_size / SECTOR_SIZE); + blk_queue_max_write_zeroes_sectors(q, segment_size / SECTOR_SIZE); if (!ceph_test_opt(rbd_dev->rbd_client->client, NOCRC)) q->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 36cfea38135f..a0fd60f0cc89 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -224,6 +224,7 @@ source "drivers/clk/meson/Kconfig" source "drivers/clk/mvebu/Kconfig" source "drivers/clk/qcom/Kconfig" source "drivers/clk/renesas/Kconfig" +source "drivers/clk/rockchip/Kconfig" source "drivers/clk/samsung/Kconfig" source "drivers/clk/sunxi-ng/Kconfig" source "drivers/clk/tegra/Kconfig" diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 96386ffc8483..9bb472cccca6 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -275,7 +275,8 @@ static int _next_div(const struct clk_div_table *table, int div, return div; } -static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, +static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent, + unsigned long rate, unsigned long *best_parent_rate, const struct clk_div_table *table, u8 width, unsigned long flags) @@ -314,8 +315,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, *best_parent_rate = parent_rate_saved; return i; } - parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), - rate * i); + parent_rate = clk_hw_round_rate(parent, rate * i); now = DIV_ROUND_UP_ULL((u64)parent_rate, i); if (_is_best_div(rate, now, best, flags)) { bestdiv = i; @@ -326,23 +326,24 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, if (!bestdiv) { bestdiv = _get_maxdiv(table, width, flags); - *best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1); + *best_parent_rate = clk_hw_round_rate(parent, 1); } return bestdiv; } -long divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate, const struct clk_div_table *table, - u8 width, unsigned long flags) +long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent, + unsigned long rate, unsigned long *prate, + const struct clk_div_table *table, + u8 width, unsigned long flags) { int div; - div = clk_divider_bestdiv(hw, rate, prate, table, width, flags); + div = clk_divider_bestdiv(hw, parent, rate, prate, table, width, flags); return DIV_ROUND_UP_ULL((u64)*prate, div); } -EXPORT_SYMBOL_GPL(divider_round_rate); +EXPORT_SYMBOL_GPL(divider_round_rate_parent); static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 19480bcc7046..2f29ee1a4d00 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -14,6 +14,7 @@ config COMMON_CLK_MESON8B config COMMON_CLK_GXBB bool depends on COMMON_CLK_AMLOGIC + select RESET_CONTROLLER help Support for the clock controller on AmLogic S905 devices, aka gxbb. Say Y if you want peripherals and CPU frequency scaling to work. diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig new file mode 100644 index 000000000000..60c05d900622 --- /dev/null +++ b/drivers/clk/rockchip/Kconfig @@ -0,0 +1,39 @@ +config COMMON_CLK_RV1108 + bool "Clock driver for Rockchip RV1108" + depends on (ARCH_ROCKCHIP && ARM) || COMPILE_TEST + default ARCH_ROCKCHIP && ARM + +config COMMON_CLK_RK3036 + bool "Clock driver for Rockchip RK3036" + depends on (ARCH_ROCKCHIP && ARM) || COMPILE_TEST + default ARCH_ROCKCHIP && ARM + +config COMMON_CLK_RK3188 + bool "Clock driver for Rockchip RK3066 and RK3188" + depends on (ARCH_ROCKCHIP && ARM) || COMPILE_TEST + default ARCH_ROCKCHIP && ARM + +config COMMON_CLK_RK3228 + bool "Clock driver for Rockchip RK3228 and RK3229" + depends on (ARCH_ROCKCHIP && ARM) || COMPILE_TEST + default ARCH_ROCKCHIP && ARM + +config COMMON_CLK_RK3288 + bool "Clock driver for Rockchip RK3288" + depends on (ARCH_ROCKCHIP && ARM) || COMPILE_TEST + default ARCH_ROCKCHIP && ARM + +config COMMON_CLK_RK3328 + bool "Clock driver for Rockchip RK3328" + depends on (ARCH_ROCKCHIP && ARM64) || COMPILE_TEST + default ARCH_ROCKCHIP && ARM64 + +config COMMON_CLK_RK3368 + bool "Clock driver for Rockchip RK3368" + depends on (ARCH_ROCKCHIP && ARM64) || COMPILE_TEST + default ARCH_ROCKCHIP && ARM64 + +config COMMON_CLK_RK3399 + bool "Clock driver for Rockchip RK3399" + depends on (ARCH_ROCKCHIP && ARM64) || COMPILE_TEST + default ARCH_ROCKCHIP && ARM64 diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index 26b220c988b2..497b7606217b 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -12,11 +12,11 @@ obj-y += clk-muxgrf.o obj-y += clk-ddr.o obj-$(CONFIG_RESET_CONTROLLER) += softrst.o -obj-y += clk-rv1108.o -obj-y += clk-rk3036.o -obj-y += clk-rk3188.o -obj-y += clk-rk3228.o -obj-y += clk-rk3288.o -obj-y += clk-rk3328.o -obj-y += clk-rk3368.o -obj-y += clk-rk3399.o +obj-$(CONFIG_COMMON_CLK_RV1108) += clk-rv1108.o +obj-$(CONFIG_COMMON_CLK_RK3036) += clk-rk3036.o +obj-$(CONFIG_COMMON_CLK_RK3188) += clk-rk3188.o +obj-$(CONFIG_COMMON_CLK_RK3228) += clk-rk3228.o +obj-$(CONFIG_COMMON_CLK_RK3288) += clk-rk3288.o +obj-$(CONFIG_COMMON_CLK_RK3328) += clk-rk3328.o +obj-$(CONFIG_COMMON_CLK_RK3368) += clk-rk3368.o +obj-$(CONFIG_COMMON_CLK_RK3399) += clk-rk3399.o diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index db6e5a9e6de6..d76da6d37c8b 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -86,25 +86,43 @@ static struct rockchip_pll_rate_table rk3228_pll_rates[] = { #define RK3228_DIV_PCLK_MASK 0x7 #define RK3228_DIV_PCLK_SHIFT 12 -#define RK3228_CLKSEL1(_core_peri_div) \ +#define RK3228_CLKSEL1(_core_aclk_div, _core_peri_div) \ { \ .reg = RK2928_CLKSEL_CON(1), \ .val = HIWORD_UPDATE(_core_peri_div, RK3228_DIV_PERI_MASK, \ - RK3228_DIV_PERI_SHIFT) \ - } + RK3228_DIV_PERI_SHIFT) | \ + HIWORD_UPDATE(_core_aclk_div, RK3228_DIV_ACLK_MASK, \ + RK3228_DIV_ACLK_SHIFT), \ +} -#define RK3228_CPUCLK_RATE(_prate, _core_peri_div) \ - { \ - .prate = _prate, \ - .divs = { \ - RK3228_CLKSEL1(_core_peri_div), \ - }, \ +#define RK3228_CPUCLK_RATE(_prate, _core_aclk_div, _core_peri_div) \ + { \ + .prate = _prate, \ + .divs = { \ + RK3228_CLKSEL1(_core_aclk_div, _core_peri_div), \ + }, \ } static struct rockchip_cpuclk_rate_table rk3228_cpuclk_rates[] __initdata = { - RK3228_CPUCLK_RATE(816000000, 4), - RK3228_CPUCLK_RATE(600000000, 4), - RK3228_CPUCLK_RATE(312000000, 4), + RK3228_CPUCLK_RATE(1800000000, 1, 7), + RK3228_CPUCLK_RATE(1704000000, 1, 7), + RK3228_CPUCLK_RATE(1608000000, 1, 7), + RK3228_CPUCLK_RATE(1512000000, 1, 7), + RK3228_CPUCLK_RATE(1488000000, 1, 5), + RK3228_CPUCLK_RATE(1416000000, 1, 5), + RK3228_CPUCLK_RATE(1392000000, 1, 5), + RK3228_CPUCLK_RATE(1296000000, 1, 5), + RK3228_CPUCLK_RATE(1200000000, 1, 5), + RK3228_CPUCLK_RATE(1104000000, 1, 5), + RK3228_CPUCLK_RATE(1008000000, 1, 5), + RK3228_CPUCLK_RATE(912000000, 1, 5), + RK3228_CPUCLK_RATE(816000000, 1, 3), + RK3228_CPUCLK_RATE(696000000, 1, 3), + RK3228_CPUCLK_RATE(600000000, 1, 3), + RK3228_CPUCLK_RATE(408000000, 1, 1), + RK3228_CPUCLK_RATE(312000000, 1, 1), + RK3228_CPUCLK_RATE(216000000, 1, 1), + RK3228_CPUCLK_RATE(96000000, 1, 1), }; static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = { @@ -252,15 +270,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 1, GFLAGS), COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0, RK2928_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS), - GATE(ARMCLK, "aclk_cpu", "aclk_cpu_src", 0, + GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0, RK2928_CLKGATE_CON(6), 0, GFLAGS), - COMPOSITE_NOMUX(0, "hclk_cpu", "aclk_cpu_src", 0, + COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0, RK2928_CLKSEL_CON(1), 8, 2, DFLAGS, RK2928_CLKGATE_CON(6), 1, GFLAGS), COMPOSITE_NOMUX(0, "pclk_bus_src", "aclk_cpu_src", 0, RK2928_CLKSEL_CON(1), 12, 3, DFLAGS, RK2928_CLKGATE_CON(6), 2, GFLAGS), - GATE(0, "pclk_cpu", "pclk_bus_src", 0, + GATE(PCLK_CPU, "pclk_cpu", "pclk_bus_src", 0, RK2928_CLKGATE_CON(6), 3, GFLAGS), GATE(0, "pclk_phy_pre", "pclk_bus_src", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS), @@ -268,58 +286,58 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(6), 13, GFLAGS), /* PD_VIDEO */ - COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0, + COMPOSITE(ACLK_VPU_PRE, "aclk_vpu_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(32), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), - FACTOR_GATE(0, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4, + FACTOR_GATE(HCLK_VPU_PRE, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 4, GFLAGS), - COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0, + COMPOSITE(ACLK_RKVDEC_PRE, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 2, GFLAGS), - FACTOR_GATE(0, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4, + FACTOR_GATE(HCLK_RKVDEC_PRE, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 5, GFLAGS), - COMPOSITE(0, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0, + COMPOSITE(SCLK_VDEC_CABAC, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(28), 14, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(3), 3, GFLAGS), - COMPOSITE(0, "sclk_vdec_core", mux_pll_src_4plls_p, 0, + COMPOSITE(SCLK_VDEC_CORE, "sclk_vdec_core", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(34), 13, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(3), 4, GFLAGS), /* PD_VIO */ - COMPOSITE(0, "aclk_iep_pre", mux_pll_src_4plls_p, 0, + COMPOSITE(ACLK_IEP_PRE, "aclk_iep_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(31), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 0, GFLAGS), - DIV(0, "hclk_vio_pre", "aclk_iep_pre", 0, + DIV(HCLK_VIO_PRE, "hclk_vio_pre", "aclk_iep_pre", 0, RK2928_CLKSEL_CON(2), 0, 5, DFLAGS), - COMPOSITE(0, "aclk_hdcp_pre", mux_pll_src_4plls_p, 0, + COMPOSITE(ACLK_HDCP_PRE, "aclk_hdcp_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(31), 13, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(1), 4, GFLAGS), MUX(0, "sclk_rga_src", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(33), 13, 2, MFLAGS), - COMPOSITE_NOMUX(0, "aclk_rga_pre", "sclk_rga_src", 0, + COMPOSITE_NOMUX(ACLK_RGA_PRE, "aclk_rga_pre", "sclk_rga_src", 0, RK2928_CLKSEL_CON(33), 8, 5, DFLAGS, RK2928_CLKGATE_CON(1), 2, GFLAGS), - COMPOSITE(0, "sclk_rga", mux_sclk_rga_p, 0, + COMPOSITE(SCLK_RGA, "sclk_rga", mux_sclk_rga_p, 0, RK2928_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 6, GFLAGS), - COMPOSITE(0, "aclk_vop_pre", mux_pll_src_4plls_p, 0, + COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(33), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(1), 1, GFLAGS), - COMPOSITE(0, "sclk_hdcp", mux_pll_src_3plls_p, 0, + COMPOSITE(SCLK_HDCP, "sclk_hdcp", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(23), 14, 2, MFLAGS, 8, 6, DFLAGS, RK2928_CLKGATE_CON(3), 5, GFLAGS), GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0, RK2928_CLKGATE_CON(3), 7, GFLAGS), - COMPOSITE(0, "sclk_hdmi_cec", mux_sclk_hdmi_cec_p, 0, + COMPOSITE(SCLK_HDMI_CEC, "sclk_hdmi_cec", mux_sclk_hdmi_cec_p, 0, RK2928_CLKSEL_CON(21), 14, 2, MFLAGS, 0, 14, DFLAGS, RK2928_CLKGATE_CON(3), 8, GFLAGS), @@ -354,18 +372,18 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS), - COMPOSITE(0, "sclk_crypto", mux_pll_src_2plls_p, 0, + COMPOSITE(SCLK_CRYPTO, "sclk_crypto", mux_pll_src_2plls_p, 0, RK2928_CLKSEL_CON(24), 5, 1, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(2), 7, GFLAGS), - COMPOSITE(0, "sclk_tsp", mux_pll_src_2plls_p, 0, + COMPOSITE(SCLK_TSP, "sclk_tsp", mux_pll_src_2plls_p, 0, RK2928_CLKSEL_CON(22), 15, 1, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(2), 6, GFLAGS), - GATE(0, "sclk_hsadc", "ext_hsadc", 0, + GATE(SCLK_HSADC, "sclk_hsadc", "ext_hsadc", 0, RK2928_CLKGATE_CON(10), 12, GFLAGS), - COMPOSITE(0, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0, RK2928_CLKSEL_CON(23), 5, 2, MFLAGS, 0, 6, DFLAGS, RK2928_CLKGATE_CON(2), 15, GFLAGS), @@ -448,9 +466,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "jtag", "ext_jtag", 0, RK2928_CLKGATE_CON(1), 3, GFLAGS), - GATE(0, "sclk_otgphy0", "xin24m", 0, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", 0, RK2928_CLKGATE_CON(1), 5, GFLAGS), - GATE(0, "sclk_otgphy1", "xin24m", 0, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", 0, RK2928_CLKGATE_CON(1), 6, GFLAGS), COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0, @@ -526,28 +544,28 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { */ /* PD_VOP */ - GATE(0, "aclk_rga", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 0, GFLAGS), + GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 0, GFLAGS), GATE(0, "aclk_rga_noc", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 11, GFLAGS), - GATE(0, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS), + GATE(ACLK_IEP, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS), GATE(0, "aclk_iep_noc", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 9, GFLAGS), GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 5, GFLAGS), GATE(0, "aclk_vop_noc", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 12, GFLAGS), - GATE(0, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS), + GATE(ACLK_HDCP, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS), GATE(0, "aclk_hdcp_noc", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(13), 10, GFLAGS), - GATE(0, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS), - GATE(0, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS), + GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS), + GATE(HCLK_IEP, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS), GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 6, GFLAGS), GATE(0, "hclk_vio_ahb_arbi", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 7, GFLAGS), GATE(0, "hclk_vio_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 8, GFLAGS), GATE(0, "hclk_vop_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 13, GFLAGS), - GATE(0, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS), - GATE(0, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS), + GATE(HCLK_VIO_H2P, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS), + GATE(HCLK_HDCP_MMU, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS), GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 6, GFLAGS), - GATE(0, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS), - GATE(0, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS), + GATE(PCLK_VIO_H2P, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS), + GATE(PCLK_HDCP, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS), /* PD_PERI */ GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 0, GFLAGS), @@ -557,12 +575,12 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 1, GFLAGS), GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 2, GFLAGS), GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 3, GFLAGS), - GATE(0, "hclk_host0", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 6, GFLAGS), + GATE(HCLK_HOST0, "hclk_host0", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 6, GFLAGS), GATE(0, "hclk_host0_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 7, GFLAGS), - GATE(0, "hclk_host1", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 8, GFLAGS), + GATE(HCLK_HOST1, "hclk_host1", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 8, GFLAGS), GATE(0, "hclk_host1_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 9, GFLAGS), - GATE(0, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 10, GFLAGS), - GATE(0, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 12, GFLAGS), + GATE(HCLK_HOST2, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 10, GFLAGS), + GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 12, GFLAGS), GATE(0, "hclk_otg_pmu", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 13, GFLAGS), GATE(0, "hclk_host2_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 14, GFLAGS), GATE(0, "hclk_peri_noc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 1, GFLAGS), @@ -571,7 +589,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "pclk_peri_noc", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 2, GFLAGS), /* PD_GPU */ - GATE(0, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 14, GFLAGS), + GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 14, GFLAGS), GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 15, GFLAGS), /* PD_BUS */ @@ -585,16 +603,16 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 8, GFLAGS), GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS), GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS), - GATE(0, "hclk_tsp", "hclk_cpu", 0, RK2928_CLKGATE_CON(10), 11, GFLAGS), - GATE(0, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), - GATE(0, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS), + GATE(HCLK_TSP, "hclk_tsp", "hclk_cpu", 0, RK2928_CLKGATE_CON(10), 11, GFLAGS), + GATE(HCLK_M_CRYPTO, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), + GATE(HCLK_S_CRYPTO, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS), GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS), GATE(0, "pclk_ddrmon", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS), GATE(0, "pclk_msch_noc", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(10), 2, GFLAGS), - GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), - GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 14, GFLAGS), + GATE(PCLK_EFUSE_1024, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), + GATE(PCLK_EFUSE_256, "pclk_efuse_256", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 14, GFLAGS), GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 15, GFLAGS), GATE(PCLK_I2C1, "pclk_i2c1", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 0, GFLAGS), GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS), @@ -622,13 +640,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS), GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), - GATE(0, "aclk_vpu", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 0, GFLAGS), + GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 0, GFLAGS), GATE(0, "aclk_vpu_noc", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 4, GFLAGS), - GATE(0, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 2, GFLAGS), + GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 2, GFLAGS), GATE(0, "aclk_rkvdec_noc", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 6, GFLAGS), - GATE(0, "hclk_vpu", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 1, GFLAGS), + GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 1, GFLAGS), GATE(0, "hclk_vpu_noc", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 5, GFLAGS), - GATE(0, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 3, GFLAGS), + GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 3, GFLAGS), GATE(0, "hclk_rkvdec_noc", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 7, GFLAGS), /* PD_MMC */ diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c index fa3cbef08776..6847120b61cd 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c @@ -1066,13 +1066,13 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { /* cif_testout */ MUX(0, "clk_testout1_pll_src", mux_pll_src_cpll_gpll_npll_p, 0, RK3399_CLKSEL_CON(38), 6, 2, MFLAGS), - COMPOSITE(0, "clk_testout1", mux_clk_testout1_p, 0, + COMPOSITE(SCLK_TESTCLKOUT1, "clk_testout1", mux_clk_testout1_p, 0, RK3399_CLKSEL_CON(38), 5, 1, MFLAGS, 0, 5, DFLAGS, RK3399_CLKGATE_CON(13), 14, GFLAGS), MUX(0, "clk_testout2_pll_src", mux_pll_src_cpll_gpll_npll_p, 0, RK3399_CLKSEL_CON(38), 14, 2, MFLAGS), - COMPOSITE(0, "clk_testout2", mux_clk_testout2_p, 0, + COMPOSITE(SCLK_TESTCLKOUT2, "clk_testout2", mux_clk_testout2_p, 0, RK3399_CLKSEL_CON(38), 13, 1, MFLAGS, 8, 5, DFLAGS, RK3399_CLKGATE_CON(13), 15, GFLAGS), diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index b0d551a8efe4..67acef3d2494 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -116,6 +116,18 @@ config SUN8I_A33_CCU default MACH_SUN8I depends on MACH_SUN8I || COMPILE_TEST +config SUN8I_A83T_CCU + bool "Support for the Allwinner A83T CCU" + select SUNXI_CCU_DIV + select SUNXI_CCU_GATE + select SUNXI_CCU_MP + select SUNXI_CCU_MULT + select SUNXI_CCU_MUX + select SUNXI_CCU_NKMP + select SUNXI_CCU_NM + select SUNXI_CCU_PHASE + default MACH_SUN8I + config SUN8I_H3_CCU bool "Support for the Allwinner H3 CCU" select SUNXI_CCU_DIV @@ -140,6 +152,11 @@ config SUN8I_V3S_CCU default MACH_SUN8I depends on MACH_SUN8I || COMPILE_TEST +config SUN8I_DE2_CCU + bool "Support for the Allwinner SoCs DE2 CCU" + select SUNXI_CCU_DIV + select SUNXI_CCU_GATE + config SUN9I_A80_CCU bool "Support for the Allwinner A80 CCU" select SUNXI_CCU_DIV @@ -156,6 +173,7 @@ config SUN8I_R_CCU bool "Support for Allwinner SoCs' PRCM CCUs" select SUNXI_CCU_DIV select SUNXI_CCU_GATE + select SUNXI_CCU_MP default MACH_SUN8I || (ARCH_SUNXI && ARM64) endif diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 0ec02fe14c50..0185c6ffadcb 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile @@ -23,8 +23,10 @@ obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o +obj-$(CONFIG_SUN8I_A83T_CCU) += ccu-sun8i-a83t.o obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o +obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index f54114c607df..2bb4cabf802f 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -211,6 +211,9 @@ static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); static const char * const ahb1_parents[] = { "osc32k", "osc24M", "axi", "pll-periph0" }; +static const struct ccu_mux_var_prediv ahb1_predivs[] = { + { .index = 3, .shift = 6, .width = 2 }, +}; static struct ccu_div ahb1_clk = { .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), @@ -218,11 +221,8 @@ static struct ccu_div ahb1_clk = { .shift = 12, .width = 2, - .variable_prediv = { - .index = 3, - .shift = 6, - .width = 2, - }, + .var_predivs = ahb1_predivs, + .n_var_predivs = ARRAY_SIZE(ahb1_predivs), }, .common = { diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c index 5c476f966a72..5372bf8be5e6 100644 --- a/drivers/clk/sunxi-ng/ccu-sun5i.c +++ b/drivers/clk/sunxi-ng/ccu-sun5i.c @@ -243,7 +243,7 @@ static SUNXI_CCU_GATE(ahb_ss_clk, "ahb-ss", "ahb", static SUNXI_CCU_GATE(ahb_dma_clk, "ahb-dma", "ahb", 0x060, BIT(6), 0); static SUNXI_CCU_GATE(ahb_bist_clk, "ahb-bist", "ahb", - 0x060, BIT(6), 0); + 0x060, BIT(7), 0); static SUNXI_CCU_GATE(ahb_mmc0_clk, "ahb-mmc0", "ahb", 0x060, BIT(8), 0); static SUNXI_CCU_GATE(ahb_mmc1_clk, "ahb-mmc1", "ahb", diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.h b/drivers/clk/sunxi-ng/ccu-sun5i.h index 8144487eb7ca..93a275fbd9a9 100644 --- a/drivers/clk/sunxi-ng/ccu-sun5i.h +++ b/drivers/clk/sunxi-ng/ccu-sun5i.h @@ -28,15 +28,17 @@ #define CLK_PLL_AUDIO_4X 6 #define CLK_PLL_AUDIO_8X 7 #define CLK_PLL_VIDEO0 8 -#define CLK_PLL_VIDEO0_2X 9 + +/* The PLL_VIDEO0_2X is exported for HDMI */ + #define CLK_PLL_VE 10 #define CLK_PLL_DDR_BASE 11 #define CLK_PLL_DDR 12 #define CLK_PLL_DDR_OTHER 13 #define CLK_PLL_PERIPH 14 #define CLK_PLL_VIDEO1 15 -#define CLK_PLL_VIDEO1_2X 16 +/* The PLL_VIDEO1_2X is exported for HDMI */ /* The CPU clock is exported */ #define CLK_AXI 18 diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c index 89e68d29bf45..4d6078fca9ac 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c @@ -195,6 +195,9 @@ static SUNXI_CCU_DIV_TABLE(axi_clk, "axi", "cpu", static const char * const ahb1_parents[] = { "osc32k", "osc24M", "axi", "pll-periph" }; +static const struct ccu_mux_var_prediv ahb1_predivs[] = { + { .index = 3, .shift = 6, .width = 2 }, +}; static struct ccu_div ahb1_clk = { .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), @@ -203,11 +206,8 @@ static struct ccu_div ahb1_clk = { .shift = 12, .width = 2, - .variable_prediv = { - .index = 3, - .shift = 6, - .width = 2, - }, + .var_predivs = ahb1_predivs, + .n_var_predivs = ARRAY_SIZE(ahb1_predivs), }, .common = { @@ -556,7 +556,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(lcd0_ch1_clk, "lcd0-ch1", lcd_ch1_parents, 0x12c, 0, 4, 24, 3, BIT(31), CLK_SET_RATE_PARENT); static SUNXI_CCU_M_WITH_MUX_GATE(lcd1_ch1_clk, "lcd1-ch1", lcd_ch1_parents, - 0x12c, 0, 4, 24, 3, BIT(31), + 0x130, 0, 4, 24, 3, BIT(31), CLK_SET_RATE_PARENT); static const char * const csi_sclk_parents[] = { "pll-video0", "pll-video1", diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c index 5c6d37bdf247..8a753ed0426d 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c @@ -169,6 +169,9 @@ static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); static const char * const ahb1_parents[] = { "osc32k", "osc24M", "axi" , "pll-periph" }; +static const struct ccu_mux_var_prediv ahb1_predivs[] = { + { .index = 3, .shift = 6, .width = 2 }, +}; static struct ccu_div ahb1_clk = { .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), @@ -176,11 +179,8 @@ static struct ccu_div ahb1_clk = { .shift = 12, .width = 2, - .variable_prediv = { - .index = 3, - .shift = 6, - .width = 2, - }, + .var_predivs = ahb1_predivs, + .n_var_predivs = ARRAY_SIZE(ahb1_predivs), }, .common = { diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c index 8d38e6510e29..10b38dc46f75 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c @@ -180,6 +180,9 @@ static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); static const char * const ahb1_parents[] = { "osc32k", "osc24M", "axi" , "pll-periph" }; +static const struct ccu_mux_var_prediv ahb1_predivs[] = { + { .index = 3, .shift = 6, .width = 2 }, +}; static struct ccu_div ahb1_clk = { .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), @@ -187,11 +190,8 @@ static struct ccu_div ahb1_clk = { .shift = 12, .width = 2, - .variable_prediv = { - .index = 3, - .shift = 6, - .width = 2, - }, + .var_predivs = ahb1_predivs, + .n_var_predivs = ARRAY_SIZE(ahb1_predivs), }, .common = { diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c new file mode 100644 index 000000000000..947f9f6e05d2 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c @@ -0,0 +1,922 @@ +/* + * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk-provider.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> + +#include "ccu_common.h" +#include "ccu_reset.h" + +#include "ccu_div.h" +#include "ccu_gate.h" +#include "ccu_mp.h" +#include "ccu_mux.h" +#include "ccu_nkmp.h" +#include "ccu_nm.h" +#include "ccu_phase.h" + +#include "ccu-sun8i-a83t.h" + +#define CCU_SUN8I_A83T_LOCK_REG 0x20c + +/* + * The CPU PLLs are actually NP clocks, with P being /1 or /4. However + * P should only be used for output frequencies lower than 228 MHz. + * Neither mainline Linux, U-boot, nor the vendor BSPs use these. + * + * For now we can just model it as a multiplier clock, and force P to /1. + */ +#define SUN8I_A83T_PLL_C0CPUX_REG 0x000 +#define SUN8I_A83T_PLL_C1CPUX_REG 0x004 + +static struct ccu_mult pll_c0cpux_clk = { + .enable = BIT(31), + .lock = BIT(0), + .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), + .common = { + .reg = SUN8I_A83T_PLL_C0CPUX_REG, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-c0cpux", "osc24M", + &ccu_mult_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +static struct ccu_mult pll_c1cpux_clk = { + .enable = BIT(31), + .lock = BIT(1), + .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), + .common = { + .reg = SUN8I_A83T_PLL_C1CPUX_REG, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-c1cpux", "osc24M", + &ccu_mult_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +/* + * The Audio PLL has d1, d2 dividers in addition to the usual N, M + * factors. Since we only need 2 frequencies from this PLL: 22.5792 MHz + * and 24.576 MHz, ignore them for now. Enforce the default for them, + * which is d1 = 0, d2 = 1. + */ +#define SUN8I_A83T_PLL_AUDIO_REG 0x008 + +static struct ccu_nm pll_audio_clk = { + .enable = BIT(31), + .lock = BIT(2), + .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), + .m = _SUNXI_CCU_DIV(0, 6), + .common = { + .reg = SUN8I_A83T_PLL_AUDIO_REG, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-audio", "osc24M", + &ccu_nm_ops, CLK_SET_RATE_UNGATE), + }, +}; + +/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */ +static struct ccu_nkmp pll_video0_clk = { + .enable = BIT(31), + .lock = BIT(3), + .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), + .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 2), /* output divider */ + .common = { + .reg = 0x010, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-video0", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +static struct ccu_nkmp pll_ve_clk = { + .enable = BIT(31), + .lock = BIT(4), + .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), + .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(18, 1), /* output divider */ + .common = { + .reg = 0x018, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-ve", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +static struct ccu_nkmp pll_ddr_clk = { + .enable = BIT(31), + .lock = BIT(5), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(18, 1), /* output divider */ + .common = { + .reg = 0x020, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-ddr", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +static struct ccu_nkmp pll_periph_clk = { + .enable = BIT(31), + .lock = BIT(6), + .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), + .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(18, 1), /* output divider */ + .common = { + .reg = 0x028, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-periph", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +static struct ccu_nkmp pll_gpu_clk = { + .enable = BIT(31), + .lock = BIT(7), + .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), + .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(18, 1), /* output divider */ + .common = { + .reg = 0x038, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-gpu", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +static struct ccu_nkmp pll_hsic_clk = { + .enable = BIT(31), + .lock = BIT(8), + .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), + .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(18, 1), /* output divider */ + .common = { + .reg = 0x044, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-hsic", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +static struct ccu_nkmp pll_de_clk = { + .enable = BIT(31), + .lock = BIT(9), + .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), + .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(18, 1), /* output divider */ + .common = { + .reg = 0x048, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-de", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +static struct ccu_nkmp pll_video1_clk = { + .enable = BIT(31), + .lock = BIT(10), + .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), + .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 2), /* external divider p */ + .common = { + .reg = 0x04c, + .lock_reg = CCU_SUN8I_A83T_LOCK_REG, + .features = CCU_FEATURE_LOCK_REG, + .hw.init = CLK_HW_INIT("pll-video1", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +static const char * const c0cpux_parents[] = { "osc24M", "pll-c0cpux" }; +static SUNXI_CCU_MUX(c0cpux_clk, "c0cpux", c0cpux_parents, + 0x50, 12, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); + +static const char * const c1cpux_parents[] = { "osc24M", "pll-c1cpux" }; +static SUNXI_CCU_MUX(c1cpux_clk, "c1cpux", c1cpux_parents, + 0x50, 28, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); + +static SUNXI_CCU_M(axi0_clk, "axi0", "c0cpux", 0x050, 0, 2, 0); +static SUNXI_CCU_M(axi1_clk, "axi1", "c1cpux", 0x050, 16, 2, 0); + +static const char * const ahb1_parents[] = { "osc16M-d512", "osc24M", + "pll-periph", + "pll-periph" }; +static const struct ccu_mux_var_prediv ahb1_predivs[] = { + { .index = 2, .shift = 6, .width = 2 }, + { .index = 3, .shift = 6, .width = 2 }, +}; +static struct ccu_div ahb1_clk = { + .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), + .mux = { + .shift = 12, + .width = 2, + + .var_predivs = ahb1_predivs, + .n_var_predivs = ARRAY_SIZE(ahb1_predivs), + }, + .common = { + .reg = 0x054, + .hw.init = CLK_HW_INIT_PARENTS("ahb1", + ahb1_parents, + &ccu_div_ops, + 0), + }, +}; + +static SUNXI_CCU_M(apb1_clk, "apb1", "ahb1", 0x054, 8, 2, 0); + +static const char * const apb2_parents[] = { "osc16M-d512", "osc24M", + "pll-periph", "pll-periph" }; + +static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058, + 0, 5, /* M */ + 16, 2, /* P */ + 24, 2, /* mux */ + 0); + +static const char * const ahb2_parents[] = { "ahb1", "pll-periph" }; +static const struct ccu_mux_fixed_prediv ahb2_prediv = { + .index = 1, .div = 2 +}; +static struct ccu_mux ahb2_clk = { + .mux = { + .shift = 0, + .width = 2, + .fixed_predivs = &ahb2_prediv, + .n_predivs = 1, + }, + .common = { + .reg = 0x05c, + .hw.init = CLK_HW_INIT_PARENTS("ahb2", + ahb2_parents, + &ccu_mux_ops, + 0), + }, +}; + +static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1", + 0x060, BIT(1), 0); +static SUNXI_CCU_GATE(bus_ss_clk, "bus-ss", "ahb1", + 0x060, BIT(5), 0); +static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1", + 0x060, BIT(6), 0); +static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1", + 0x060, BIT(8), 0); +static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1", + 0x060, BIT(9), 0); +static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1", + 0x060, BIT(10), 0); +static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1", + 0x060, BIT(13), 0); +static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1", + 0x060, BIT(14), 0); +static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb2", + 0x060, BIT(17), 0); +static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1", + 0x060, BIT(19), 0); +static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1", + 0x060, BIT(20), 0); +static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1", + 0x060, BIT(21), 0); +static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1", + 0x060, BIT(24), 0); +static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb2", + 0x060, BIT(26), 0); +static SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb2", + 0x060, BIT(27), 0); +static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb2", + 0x060, BIT(29), 0); + +static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1", + 0x064, BIT(0), 0); +static SUNXI_CCU_GATE(bus_tcon0_clk, "bus-tcon0", "ahb1", + 0x064, BIT(4), 0); +static SUNXI_CCU_GATE(bus_tcon1_clk, "bus-tcon1", "ahb1", + 0x064, BIT(5), 0); +static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1", + 0x064, BIT(8), 0); +static SUNXI_CCU_GATE(bus_hdmi_clk, "bus-hdmi", "ahb1", + 0x064, BIT(11), 0); +static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "ahb1", + 0x064, BIT(12), 0); +static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1", + 0x064, BIT(20), 0); +static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1", + 0x064, BIT(21), 0); +static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1", + 0x064, BIT(22), 0); + +static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", + 0x068, BIT(1), 0); +static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1", + 0x068, BIT(5), 0); +static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", + 0x068, BIT(12), 0); +static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", + 0x068, BIT(13), 0); +static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1", + 0x068, BIT(14), 0); +static SUNXI_CCU_GATE(bus_tdm_clk, "bus-tdm", "apb1", + 0x068, BIT(15), 0); + +static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", + 0x06c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", + 0x06c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", + 0x06c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", + 0x06c, BIT(16), 0); +static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", + 0x06c, BIT(17), 0); +static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", + 0x06c, BIT(18), 0); +static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", + 0x06c, BIT(19), 0); +static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", + 0x06c, BIT(20), 0); + +static const char * const cci400_parents[] = { "osc24M", "pll-periph", + "pll-hsic" }; +static struct ccu_div cci400_clk = { + .div = _SUNXI_CCU_DIV_FLAGS(0, 2, 0), + .mux = _SUNXI_CCU_MUX(24, 2), + .common = { + .reg = 0x078, + .hw.init = CLK_HW_INIT_PARENTS("cci400", + cci400_parents, + &ccu_div_ops, + CLK_IS_CRITICAL), + }, +}; + +static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" }; + +static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, + 0x080, + 0, 4, /* M */ + 16, 2, /* P */ + 24, 2, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, + 0x088, + 0, 4, /* M */ + 16, 2, /* P */ + 24, 2, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0-sample", "mmc0", + 0x088, 20, 3, 0); +static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0-output", "mmc0", + 0x088, 8, 3, 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, + 0x08c, + 0, 4, /* M */ + 16, 2, /* P */ + 24, 2, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1-sample", "mmc1", + 0x08c, 20, 3, 0); +static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1-output", "mmc1", + 0x08c, 8, 3, 0); + +/* TODO Support MMC2 clock's new timing mode. */ +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, + 0x090, + 0, 4, /* M */ + 16, 2, /* P */ + 24, 2, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2-sample", "mmc2", + 0x090, 20, 3, 0); +static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2-output", "mmc2", + 0x090, 8, 3, 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, + 0x09c, + 0, 4, /* M */ + 16, 2, /* P */ + 24, 2, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, + 0x0a0, + 0, 4, /* M */ + 16, 2, /* P */ + 24, 4, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, + 0x0a4, + 0, 4, /* M */ + 16, 2, /* P */ + 24, 4, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_M_WITH_GATE(i2s0_clk, "i2s0", "pll-audio", + 0x0b0, 0, 4, BIT(31), CLK_SET_RATE_PARENT); +static SUNXI_CCU_M_WITH_GATE(i2s1_clk, "i2s1", "pll-audio", + 0x0b4, 0, 4, BIT(31), CLK_SET_RATE_PARENT); +static SUNXI_CCU_M_WITH_GATE(i2s2_clk, "i2s2", "pll-audio", + 0x0b8, 0, 4, BIT(31), CLK_SET_RATE_PARENT); +static SUNXI_CCU_M_WITH_GATE(tdm_clk, "tdm", "pll-audio", + 0x0bc, 0, 4, BIT(31), CLK_SET_RATE_PARENT); +static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio", + 0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT); + +static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", + 0x0cc, BIT(8), 0); +static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", + 0x0cc, BIT(9), 0); +static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic", + 0x0cc, BIT(10), 0); +static struct ccu_gate usb_hsic_12m_clk = { + .enable = BIT(11), + .common = { + .reg = 0x0cc, + .prediv = 2, + .features = CCU_FEATURE_ALL_PREDIV, + .hw.init = CLK_HW_INIT("usb-hsic-12m", "osc24M", + &ccu_gate_ops, 0), + } +}; +static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M", + 0x0cc, BIT(16), 0); + +/* TODO divider has minimum of 2 */ +static SUNXI_CCU_M(dram_clk, "dram", "pll-ddr", 0x0f4, 0, 4, CLK_IS_CRITICAL); + +static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram", + 0x100, BIT(0), 0); +static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "dram", + 0x100, BIT(1), 0); + +static const char * const tcon0_parents[] = { "pll-video0" }; +static SUNXI_CCU_MUX_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents, + 0x118, 24, 3, BIT(31), CLK_SET_RATE_PARENT); + +static const char * const tcon1_parents[] = { "pll-video1" }; +static SUNXI_CCU_MUX_WITH_GATE(tcon1_clk, "tcon1", tcon1_parents, + 0x11c, 24, 3, BIT(31), CLK_SET_RATE_PARENT); + +static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x130, BIT(16), 0); + +static SUNXI_CCU_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x130, BIT(31), 0); + +static const char * const csi_mclk_parents[] = { "pll-de", "osc24M" }; +static const u8 csi_mclk_table[] = { 3, 5 }; +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk", + csi_mclk_parents, csi_mclk_table, + 0x134, + 0, 5, /* M */ + 10, 3, /* mux */ + BIT(15), /* gate */ + 0); + +static const char * const csi_sclk_parents[] = { "pll-periph", "pll-ve" }; +static const u8 csi_sclk_table[] = { 0, 5 }; +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk", + csi_sclk_parents, csi_sclk_table, + 0x134, + 16, 4, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x13c, + 16, 3, BIT(31), CLK_SET_RATE_PARENT); + +static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x144, BIT(31), 0); + +static const char * const hdmi_parents[] = { "pll-video1" }; +static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, + 0x150, + 0, 4, /* M */ + 24, 2, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", 0x154, BIT(31), 0); + +static const char * const mbus_parents[] = { "osc24M", "pll-periph", + "pll-ddr" }; +static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, + 0x15c, + 0, 3, /* M */ + 24, 2, /* mux */ + BIT(31), /* gate */ + CLK_IS_CRITICAL); + +static const char * const mipi_dsi0_parents[] = { "pll-video0" }; +static const u8 mipi_dsi0_table[] = { 8 }; +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi0_clk, "mipi-dsi0", + mipi_dsi0_parents, mipi_dsi0_table, + 0x168, + 0, 4, /* M */ + 24, 4, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static const char * const mipi_dsi1_parents[] = { "osc24M", "pll-video0" }; +static const u8 mipi_dsi1_table[] = { 0, 9 }; +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi1_clk, "mipi-dsi1", + mipi_dsi1_parents, mipi_dsi1_table, + 0x16c, + 0, 4, /* M */ + 24, 4, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_M_WITH_GATE(gpu_core_clk, "gpu-core", "pll-gpu", 0x1a0, + 0, 3, BIT(31), CLK_SET_RATE_PARENT); + +static const char * const gpu_memory_parents[] = { "pll-gpu", "pll-ddr" }; +static SUNXI_CCU_M_WITH_MUX_GATE(gpu_memory_clk, "gpu-memory", + gpu_memory_parents, + 0x1a4, + 0, 3, /* M */ + 24, 1, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_M_WITH_GATE(gpu_hyd_clk, "gpu-hyd", "pll-gpu", 0x1a8, + 0, 3, BIT(31), CLK_SET_RATE_PARENT); + +static struct ccu_common *sun8i_a83t_ccu_clks[] = { + &pll_c0cpux_clk.common, + &pll_c1cpux_clk.common, + &pll_audio_clk.common, + &pll_video0_clk.common, + &pll_ve_clk.common, + &pll_ddr_clk.common, + &pll_periph_clk.common, + &pll_gpu_clk.common, + &pll_hsic_clk.common, + &pll_de_clk.common, + &pll_video1_clk.common, + &c0cpux_clk.common, + &c1cpux_clk.common, + &axi0_clk.common, + &axi1_clk.common, + &ahb1_clk.common, + &ahb2_clk.common, + &apb1_clk.common, + &apb2_clk.common, + &bus_mipi_dsi_clk.common, + &bus_ss_clk.common, + &bus_dma_clk.common, + &bus_mmc0_clk.common, + &bus_mmc1_clk.common, + &bus_mmc2_clk.common, + &bus_nand_clk.common, + &bus_dram_clk.common, + &bus_emac_clk.common, + &bus_hstimer_clk.common, + &bus_spi0_clk.common, + &bus_spi1_clk.common, + &bus_otg_clk.common, + &bus_ehci0_clk.common, + &bus_ehci1_clk.common, + &bus_ohci0_clk.common, + &bus_ve_clk.common, + &bus_tcon0_clk.common, + &bus_tcon1_clk.common, + &bus_csi_clk.common, + &bus_hdmi_clk.common, + &bus_de_clk.common, + &bus_gpu_clk.common, + &bus_msgbox_clk.common, + &bus_spinlock_clk.common, + &bus_spdif_clk.common, + &bus_pio_clk.common, + &bus_i2s0_clk.common, + &bus_i2s1_clk.common, + &bus_i2s2_clk.common, + &bus_tdm_clk.common, + &bus_i2c0_clk.common, + &bus_i2c1_clk.common, + &bus_i2c2_clk.common, + &bus_uart0_clk.common, + &bus_uart1_clk.common, + &bus_uart2_clk.common, + &bus_uart3_clk.common, + &bus_uart4_clk.common, + &cci400_clk.common, + &nand_clk.common, + &mmc0_clk.common, + &mmc0_sample_clk.common, + &mmc0_output_clk.common, + &mmc1_clk.common, + &mmc1_sample_clk.common, + &mmc1_output_clk.common, + &mmc2_clk.common, + &mmc2_sample_clk.common, + &mmc2_output_clk.common, + &ss_clk.common, + &spi0_clk.common, + &spi1_clk.common, + &i2s0_clk.common, + &i2s1_clk.common, + &i2s2_clk.common, + &tdm_clk.common, + &spdif_clk.common, + &usb_phy0_clk.common, + &usb_phy1_clk.common, + &usb_hsic_clk.common, + &usb_hsic_12m_clk.common, + &usb_ohci0_clk.common, + &dram_clk.common, + &dram_ve_clk.common, + &dram_csi_clk.common, + &tcon0_clk.common, + &tcon1_clk.common, + &csi_misc_clk.common, + &mipi_csi_clk.common, + &csi_mclk_clk.common, + &csi_sclk_clk.common, + &ve_clk.common, + &avs_clk.common, + &hdmi_clk.common, + &hdmi_slow_clk.common, + &mbus_clk.common, + &mipi_dsi0_clk.common, + &mipi_dsi1_clk.common, + &gpu_core_clk.common, + &gpu_memory_clk.common, + &gpu_hyd_clk.common, +}; + +static struct clk_hw_onecell_data sun8i_a83t_hw_clks = { + .hws = { + [CLK_PLL_C0CPUX] = &pll_c0cpux_clk.common.hw, + [CLK_PLL_C1CPUX] = &pll_c1cpux_clk.common.hw, + [CLK_PLL_AUDIO] = &pll_audio_clk.common.hw, + [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, + [CLK_PLL_VE] = &pll_ve_clk.common.hw, + [CLK_PLL_DDR] = &pll_ddr_clk.common.hw, + [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw, + [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, + [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw, + [CLK_PLL_DE] = &pll_de_clk.common.hw, + [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, + [CLK_C0CPUX] = &c0cpux_clk.common.hw, + [CLK_C1CPUX] = &c1cpux_clk.common.hw, + [CLK_AXI0] = &axi0_clk.common.hw, + [CLK_AXI1] = &axi1_clk.common.hw, + [CLK_AHB1] = &ahb1_clk.common.hw, + [CLK_AHB2] = &ahb2_clk.common.hw, + [CLK_APB1] = &apb1_clk.common.hw, + [CLK_APB2] = &apb2_clk.common.hw, + [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw, + [CLK_BUS_SS] = &bus_ss_clk.common.hw, + [CLK_BUS_DMA] = &bus_dma_clk.common.hw, + [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, + [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, + [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, + [CLK_BUS_NAND] = &bus_nand_clk.common.hw, + [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, + [CLK_BUS_EMAC] = &bus_emac_clk.common.hw, + [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, + [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, + [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, + [CLK_BUS_OTG] = &bus_otg_clk.common.hw, + [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw, + [CLK_BUS_EHCI1] = &bus_ehci1_clk.common.hw, + [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw, + [CLK_BUS_VE] = &bus_ve_clk.common.hw, + [CLK_BUS_TCON0] = &bus_tcon0_clk.common.hw, + [CLK_BUS_TCON1] = &bus_tcon1_clk.common.hw, + [CLK_BUS_CSI] = &bus_csi_clk.common.hw, + [CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw, + [CLK_BUS_DE] = &bus_de_clk.common.hw, + [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, + [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw, + [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw, + [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw, + [CLK_BUS_PIO] = &bus_pio_clk.common.hw, + [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, + [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, + [CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw, + [CLK_BUS_TDM] = &bus_tdm_clk.common.hw, + [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, + [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, + [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, + [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, + [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, + [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, + [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, + [CLK_BUS_UART4] = &bus_uart4_clk.common.hw, + [CLK_CCI400] = &cci400_clk.common.hw, + [CLK_NAND] = &nand_clk.common.hw, + [CLK_MMC0] = &mmc0_clk.common.hw, + [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw, + [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw, + [CLK_MMC1] = &mmc1_clk.common.hw, + [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw, + [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw, + [CLK_MMC2] = &mmc2_clk.common.hw, + [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw, + [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw, + [CLK_SS] = &ss_clk.common.hw, + [CLK_SPI0] = &spi0_clk.common.hw, + [CLK_SPI1] = &spi1_clk.common.hw, + [CLK_I2S0] = &i2s0_clk.common.hw, + [CLK_I2S1] = &i2s1_clk.common.hw, + [CLK_I2S2] = &i2s2_clk.common.hw, + [CLK_TDM] = &tdm_clk.common.hw, + [CLK_SPDIF] = &spdif_clk.common.hw, + [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, + [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, + [CLK_USB_HSIC] = &usb_hsic_clk.common.hw, + [CLK_USB_HSIC_12M] = &usb_hsic_12m_clk.common.hw, + [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, + [CLK_DRAM] = &dram_clk.common.hw, + [CLK_DRAM_VE] = &dram_ve_clk.common.hw, + [CLK_DRAM_CSI] = &dram_csi_clk.common.hw, + [CLK_TCON0] = &tcon0_clk.common.hw, + [CLK_TCON1] = &tcon1_clk.common.hw, + [CLK_CSI_MISC] = &csi_misc_clk.common.hw, + [CLK_MIPI_CSI] = &mipi_csi_clk.common.hw, + [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw, + [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, + [CLK_VE] = &ve_clk.common.hw, + [CLK_AVS] = &avs_clk.common.hw, + [CLK_HDMI] = &hdmi_clk.common.hw, + [CLK_HDMI_SLOW] = &hdmi_slow_clk.common.hw, + [CLK_MBUS] = &mbus_clk.common.hw, + [CLK_MIPI_DSI0] = &mipi_dsi0_clk.common.hw, + [CLK_MIPI_DSI1] = &mipi_dsi1_clk.common.hw, + [CLK_GPU_CORE] = &gpu_core_clk.common.hw, + [CLK_GPU_MEMORY] = &gpu_memory_clk.common.hw, + [CLK_GPU_HYD] = &gpu_hyd_clk.common.hw, + }, + .num = CLK_NUMBER, +}; + +static struct ccu_reset_map sun8i_a83t_ccu_resets[] = { + [RST_USB_PHY0] = { 0x0cc, BIT(0) }, + [RST_USB_PHY1] = { 0x0cc, BIT(1) }, + [RST_USB_HSIC] = { 0x0cc, BIT(2) }, + [RST_DRAM] = { 0x0f4, BIT(31) }, + [RST_MBUS] = { 0x0fc, BIT(31) }, + [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) }, + [RST_BUS_SS] = { 0x2c0, BIT(5) }, + [RST_BUS_DMA] = { 0x2c0, BIT(6) }, + [RST_BUS_MMC0] = { 0x2c0, BIT(8) }, + [RST_BUS_MMC1] = { 0x2c0, BIT(9) }, + [RST_BUS_MMC2] = { 0x2c0, BIT(10) }, + [RST_BUS_NAND] = { 0x2c0, BIT(13) }, + [RST_BUS_DRAM] = { 0x2c0, BIT(14) }, + [RST_BUS_EMAC] = { 0x2c0, BIT(17) }, + [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) }, + [RST_BUS_SPI0] = { 0x2c0, BIT(20) }, + [RST_BUS_SPI1] = { 0x2c0, BIT(21) }, + [RST_BUS_OTG] = { 0x2c0, BIT(24) }, + [RST_BUS_EHCI0] = { 0x2c0, BIT(26) }, + [RST_BUS_EHCI1] = { 0x2c0, BIT(27) }, + [RST_BUS_OHCI0] = { 0x2c0, BIT(29) }, + [RST_BUS_VE] = { 0x2c4, BIT(0) }, + [RST_BUS_TCON0] = { 0x2c4, BIT(4) }, + [RST_BUS_TCON1] = { 0x2c4, BIT(5) }, + [RST_BUS_CSI] = { 0x2c4, BIT(8) }, + [RST_BUS_HDMI0] = { 0x2c4, BIT(10) }, + [RST_BUS_HDMI1] = { 0x2c4, BIT(11) }, + [RST_BUS_DE] = { 0x2c4, BIT(12) }, + [RST_BUS_GPU] = { 0x2c4, BIT(20) }, + [RST_BUS_MSGBOX] = { 0x2c4, BIT(21) }, + [RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) }, + [RST_BUS_LVDS] = { 0x2c8, BIT(0) }, + [RST_BUS_SPDIF] = { 0x2d0, BIT(1) }, + [RST_BUS_I2S0] = { 0x2d0, BIT(12) }, + [RST_BUS_I2S1] = { 0x2d0, BIT(13) }, + [RST_BUS_I2S2] = { 0x2d0, BIT(14) }, + [RST_BUS_TDM] = { 0x2d0, BIT(15) }, + [RST_BUS_I2C0] = { 0x2d8, BIT(0) }, + [RST_BUS_I2C1] = { 0x2d8, BIT(1) }, + [RST_BUS_I2C2] = { 0x2d8, BIT(2) }, + [RST_BUS_UART0] = { 0x2d8, BIT(16) }, + [RST_BUS_UART1] = { 0x2d8, BIT(17) }, + [RST_BUS_UART2] = { 0x2d8, BIT(18) }, + [RST_BUS_UART3] = { 0x2d8, BIT(19) }, + [RST_BUS_UART4] = { 0x2d8, BIT(20) }, +}; + +static const struct sunxi_ccu_desc sun8i_a83t_ccu_desc = { + .ccu_clks = sun8i_a83t_ccu_clks, + .num_ccu_clks = ARRAY_SIZE(sun8i_a83t_ccu_clks), + + .hw_clks = &sun8i_a83t_hw_clks, + + .resets = sun8i_a83t_ccu_resets, + .num_resets = ARRAY_SIZE(sun8i_a83t_ccu_resets), +}; + +#define SUN8I_A83T_PLL_P_SHIFT 16 +#define SUN8I_A83T_PLL_N_SHIFT 8 +#define SUN8I_A83T_PLL_N_WIDTH 8 + +static void sun8i_a83t_cpu_pll_fixup(void __iomem *reg) +{ + u32 val = readl(reg); + + /* bail out if P divider is not used */ + if (!(val & BIT(SUN8I_A83T_PLL_P_SHIFT))) + return; + + /* + * If P is used, output should be less than 288 MHz. When we + * set P to 1, we should also decrease the multiplier so the + * output doesn't go out of range, but not too much such that + * the multiplier stays above 12, the minimal operation value. + * + * To keep it simple, set the multiplier to 17, the reset value. + */ + val &= ~GENMASK(SUN8I_A83T_PLL_N_SHIFT + SUN8I_A83T_PLL_N_WIDTH - 1, + SUN8I_A83T_PLL_N_SHIFT); + val |= 17 << SUN8I_A83T_PLL_N_SHIFT; + + /* And clear P */ + val &= ~BIT(SUN8I_A83T_PLL_P_SHIFT); + + writel(val, reg); +} + +static int sun8i_a83t_ccu_probe(struct platform_device *pdev) +{ + struct resource *res; + void __iomem *reg; + u32 val; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(reg)) + return PTR_ERR(reg); + + /* Enforce d1 = 0, d2 = 0 for Audio PLL */ + val = readl(reg + SUN8I_A83T_PLL_AUDIO_REG); + val &= ~(BIT(16) | BIT(18)); + writel(val, reg + SUN8I_A83T_PLL_AUDIO_REG); + + /* Enforce P = 1 for both CPU cluster PLLs */ + sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C0CPUX_REG); + sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C1CPUX_REG); + + return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_a83t_ccu_desc); +} + +static const struct of_device_id sun8i_a83t_ccu_ids[] = { + { .compatible = "allwinner,sun8i-a83t-ccu" }, + { } +}; + +static struct platform_driver sun8i_a83t_ccu_driver = { + .probe = sun8i_a83t_ccu_probe, + .driver = { + .name = "sun8i-a83t-ccu", + .of_match_table = sun8i_a83t_ccu_ids, + }, +}; +builtin_platform_driver(sun8i_a83t_ccu_driver); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.h b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.h new file mode 100644 index 000000000000..d67edaf76748 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.h @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Chen-Yu Tsai + * + * Chen-Yu Tsai <wens@csie.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CCU_SUN8I_A83T_H_ +#define _CCU_SUN8I_A83T_H_ + +#include <dt-bindings/clock/sun8i-a83t-ccu.h> +#include <dt-bindings/reset/sun8i-a83t-ccu.h> + +#define CLK_PLL_C0CPUX 0 +#define CLK_PLL_C1CPUX 1 +#define CLK_PLL_AUDIO 2 +#define CLK_PLL_VIDEO0 3 +#define CLK_PLL_VE 4 +#define CLK_PLL_DDR 5 + +/* pll-periph is exported to the PRCM block */ + +#define CLK_PLL_GPU 7 +#define CLK_PLL_HSIC 8 + +/* pll-de is exported for the display engine */ + +#define CLK_PLL_VIDEO1 10 + +/* The CPUX clocks are exported */ + +#define CLK_AXI0 13 +#define CLK_AXI1 14 +#define CLK_AHB1 15 +#define CLK_AHB2 16 +#define CLK_APB1 17 +#define CLK_APB2 18 + +/* bus gates exported */ + +#define CLK_CCI400 58 + +/* module and usb clocks exported */ + +#define CLK_DRAM 82 + +/* dram gates and more module clocks exported */ + +#define CLK_MBUS 95 + +/* more module clocks exported */ + +#define CLK_NUMBER (CLK_GPU_HYD + 1) + +#endif /* _CCU_SUN8I_A83T_H_ */ diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c new file mode 100644 index 000000000000..5cdaf52669e4 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/of_address.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/reset.h> + +#include "ccu_common.h" +#include "ccu_div.h" +#include "ccu_gate.h" +#include "ccu_reset.h" + +#include "ccu-sun8i-de2.h" + +static SUNXI_CCU_GATE(bus_mixer0_clk, "bus-mixer0", "bus-de", + 0x04, BIT(0), 0); +static SUNXI_CCU_GATE(bus_mixer1_clk, "bus-mixer1", "bus-de", + 0x04, BIT(1), 0); +static SUNXI_CCU_GATE(bus_wb_clk, "bus-wb", "bus-de", + 0x04, BIT(2), 0); + +static SUNXI_CCU_GATE(mixer0_clk, "mixer0", "mixer0-div", + 0x00, BIT(0), CLK_SET_RATE_PARENT); +static SUNXI_CCU_GATE(mixer1_clk, "mixer1", "mixer1-div", + 0x00, BIT(1), CLK_SET_RATE_PARENT); +static SUNXI_CCU_GATE(wb_clk, "wb", "wb-div", + 0x00, BIT(2), CLK_SET_RATE_PARENT); + +static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4, + CLK_SET_RATE_PARENT); +static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de", 0x0c, 4, 4, + CLK_SET_RATE_PARENT); +static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4, + CLK_SET_RATE_PARENT); + +static struct ccu_common *sun8i_a83t_de2_clks[] = { + &mixer0_clk.common, + &mixer1_clk.common, + &wb_clk.common, + + &bus_mixer0_clk.common, + &bus_mixer1_clk.common, + &bus_wb_clk.common, + + &mixer0_div_clk.common, + &mixer1_div_clk.common, + &wb_div_clk.common, +}; + +static struct ccu_common *sun8i_v3s_de2_clks[] = { + &mixer0_clk.common, + &wb_clk.common, + + &bus_mixer0_clk.common, + &bus_wb_clk.common, + + &mixer0_div_clk.common, + &wb_div_clk.common, +}; + +static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = { + .hws = { + [CLK_MIXER0] = &mixer0_clk.common.hw, + [CLK_MIXER1] = &mixer1_clk.common.hw, + [CLK_WB] = &wb_clk.common.hw, + + [CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw, + [CLK_BUS_MIXER1] = &bus_mixer1_clk.common.hw, + [CLK_BUS_WB] = &bus_wb_clk.common.hw, + + [CLK_MIXER0_DIV] = &mixer0_div_clk.common.hw, + [CLK_MIXER1_DIV] = &mixer1_div_clk.common.hw, + [CLK_WB_DIV] = &wb_div_clk.common.hw, + }, + .num = CLK_NUMBER, +}; + +static struct clk_hw_onecell_data sun8i_v3s_de2_hw_clks = { + .hws = { + [CLK_MIXER0] = &mixer0_clk.common.hw, + [CLK_WB] = &wb_clk.common.hw, + + [CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw, + [CLK_BUS_WB] = &bus_wb_clk.common.hw, + + [CLK_MIXER0_DIV] = &mixer0_div_clk.common.hw, + [CLK_WB_DIV] = &wb_div_clk.common.hw, + }, + .num = CLK_NUMBER, +}; + +static struct ccu_reset_map sun8i_a83t_de2_resets[] = { + [RST_MIXER0] = { 0x08, BIT(0) }, + /* + * For A83T, H3 and R40, mixer1 reset line is shared with wb, so + * only RST_WB is exported here. + * For V3s there's just no mixer1, so it also shares this struct. + */ + [RST_WB] = { 0x08, BIT(2) }, +}; + +static struct ccu_reset_map sun50i_a64_de2_resets[] = { + [RST_MIXER0] = { 0x08, BIT(0) }, + [RST_MIXER1] = { 0x08, BIT(1) }, + [RST_WB] = { 0x08, BIT(2) }, +}; + +static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = { + .ccu_clks = sun8i_a83t_de2_clks, + .num_ccu_clks = ARRAY_SIZE(sun8i_a83t_de2_clks), + + .hw_clks = &sun8i_a83t_de2_hw_clks, + + .resets = sun8i_a83t_de2_resets, + .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), +}; + +static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = { + .ccu_clks = sun8i_a83t_de2_clks, + .num_ccu_clks = ARRAY_SIZE(sun8i_a83t_de2_clks), + + .hw_clks = &sun8i_a83t_de2_hw_clks, + + .resets = sun50i_a64_de2_resets, + .num_resets = ARRAY_SIZE(sun50i_a64_de2_resets), +}; + +static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = { + .ccu_clks = sun8i_v3s_de2_clks, + .num_ccu_clks = ARRAY_SIZE(sun8i_v3s_de2_clks), + + .hw_clks = &sun8i_v3s_de2_hw_clks, + + .resets = sun8i_a83t_de2_resets, + .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), +}; + +static int sunxi_de2_clk_probe(struct platform_device *pdev) +{ + struct resource *res; + struct clk *bus_clk, *mod_clk; + struct reset_control *rstc; + void __iomem *reg; + const struct sunxi_ccu_desc *ccu_desc; + int ret; + + ccu_desc = of_device_get_match_data(&pdev->dev); + if (!ccu_desc) + return -EINVAL; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(reg)) + return PTR_ERR(reg); + + bus_clk = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(bus_clk)) { + ret = PTR_ERR(bus_clk); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret); + return ret; + } + + mod_clk = devm_clk_get(&pdev->dev, "mod"); + if (IS_ERR(mod_clk)) { + ret = PTR_ERR(mod_clk); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "Couldn't get mod clk: %d\n", ret); + return ret; + } + + rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(rstc)) { + ret = PTR_ERR(rstc); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, + "Couldn't get reset control: %d\n", ret); + return ret; + } + + /* The clocks need to be enabled for us to access the registers */ + ret = clk_prepare_enable(bus_clk); + if (ret) { + dev_err(&pdev->dev, "Couldn't enable bus clk: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(mod_clk); + if (ret) { + dev_err(&pdev->dev, "Couldn't enable mod clk: %d\n", ret); + goto err_disable_bus_clk; + } + + /* The reset control needs to be asserted for the controls to work */ + ret = reset_control_deassert(rstc); + if (ret) { + dev_err(&pdev->dev, + "Couldn't deassert reset control: %d\n", ret); + goto err_disable_mod_clk; + } + + ret = sunxi_ccu_probe(pdev->dev.of_node, reg, ccu_desc); + if (ret) + goto err_assert_reset; + + return 0; + +err_assert_reset: + reset_control_assert(rstc); +err_disable_mod_clk: + clk_disable_unprepare(mod_clk); +err_disable_bus_clk: + clk_disable_unprepare(bus_clk); + return ret; +} + +static const struct of_device_id sunxi_de2_clk_ids[] = { + { + .compatible = "allwinner,sun8i-a83t-de2-clk", + .data = &sun8i_a83t_de2_clk_desc, + }, + { + .compatible = "allwinner,sun8i-v3s-de2-clk", + .data = &sun8i_v3s_de2_clk_desc, + }, + { + .compatible = "allwinner,sun50i-h5-de2-clk", + .data = &sun50i_a64_de2_clk_desc, + }, + /* + * The Allwinner A64 SoC needs some bit to be poke in syscon to make + * DE2 really working. + * So there's currently no A64 compatible here. + * H5 shares the same reset line with A64, so here H5 is using the + * clock description of A64. + */ + { } +}; + +static struct platform_driver sunxi_de2_clk_driver = { + .probe = sunxi_de2_clk_probe, + .driver = { + .name = "sunxi-de2-clks", + .of_match_table = sunxi_de2_clk_ids, + }, +}; +builtin_platform_driver(sunxi_de2_clk_driver); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h new file mode 100644 index 000000000000..530c006e0ae9 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Icenowy Zheng <icenowy@aosc.io> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CCU_SUN8I_DE2_H_ +#define _CCU_SUN8I_DE2_H_ + +#include <dt-bindings/clock/sun8i-de2.h> +#include <dt-bindings/reset/sun8i-de2.h> + +/* Intermediary clock dividers are not exported */ +#define CLK_MIXER0_DIV 3 +#define CLK_MIXER1_DIV 4 +#define CLK_WB_DIV 5 + +#define CLK_NUMBER (CLK_WB + 1) + +#endif /* _CCU_SUN8I_DE2_H_ */ diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 4cbc1b701b7c..62e4f0d2b2fc 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c @@ -141,6 +141,9 @@ static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); static const char * const ahb1_parents[] = { "osc32k", "osc24M", "axi" , "pll-periph0" }; +static const struct ccu_mux_var_prediv ahb1_predivs[] = { + { .index = 3, .shift = 6, .width = 2 }, +}; static struct ccu_div ahb1_clk = { .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), @@ -148,11 +151,8 @@ static struct ccu_div ahb1_clk = { .shift = 12, .width = 2, - .variable_prediv = { - .index = 3, - .shift = 6, - .width = 2, - }, + .var_predivs = ahb1_predivs, + .n_var_predivs = ARRAY_SIZE(ahb1_predivs), }, .common = { diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c index 119f47b568ea..e54816ec1dbe 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c @@ -27,6 +27,11 @@ static const char * const ar100_parents[] = { "osc32k", "osc24M", "pll-periph0", "iosc" }; +static const char * const a83t_ar100_parents[] = { "osc16M-d512", "osc24M", + "pll-periph0", "iosc" }; +static const struct ccu_mux_var_prediv ar100_predivs[] = { + { .index = 2, .shift = 8, .width = 5 }, +}; static struct ccu_div ar100_clk = { .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), @@ -35,11 +40,8 @@ static struct ccu_div ar100_clk = { .shift = 16, .width = 2, - .variable_prediv = { - .index = 2, - .shift = 8, - .width = 5, - }, + .var_predivs = ar100_predivs, + .n_var_predivs = ARRAY_SIZE(ar100_predivs), }, .common = { @@ -52,6 +54,27 @@ static struct ccu_div ar100_clk = { }, }; +static struct ccu_div a83t_ar100_clk = { + .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), + + .mux = { + .shift = 16, + .width = 2, + + .var_predivs = ar100_predivs, + .n_var_predivs = ARRAY_SIZE(ar100_predivs), + }, + + .common = { + .reg = 0x00, + .features = CCU_FEATURE_VARIABLE_PREDIV, + .hw.init = CLK_HW_INIT_PARENTS("ar100", + a83t_ar100_parents, + &ccu_div_ops, + 0), + }, +}; + static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0); static struct ccu_div apb0_clk = { @@ -66,6 +89,8 @@ static struct ccu_div apb0_clk = { }, }; +static SUNXI_CCU_M(a83t_apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0); + static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0", 0x28, BIT(0), 0); static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0", @@ -90,6 +115,46 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", BIT(31), /* gate */ 0); +static const char *const a83t_r_mod0_parents[] = { "osc16M", "osc24M" }; +static const struct ccu_mux_fixed_prediv a83t_ir_predivs[] = { + { .index = 0, .div = 16 }, +}; +static struct ccu_mp a83t_ir_clk = { + .enable = BIT(31), + + .m = _SUNXI_CCU_DIV(0, 4), + .p = _SUNXI_CCU_DIV(16, 2), + + .mux = { + .shift = 24, + .width = 2, + .fixed_predivs = a83t_ir_predivs, + .n_predivs = ARRAY_SIZE(a83t_ir_predivs), + }, + + .common = { + .reg = 0x54, + .features = CCU_FEATURE_VARIABLE_PREDIV, + .hw.init = CLK_HW_INIT_PARENTS("ir", + a83t_r_mod0_parents, + &ccu_mp_ops, + 0), + }, +}; + +static struct ccu_common *sun8i_a83t_r_ccu_clks[] = { + &a83t_ar100_clk.common, + &a83t_apb0_clk.common, + &apb0_pio_clk.common, + &apb0_ir_clk.common, + &apb0_timer_clk.common, + &apb0_rsb_clk.common, + &apb0_uart_clk.common, + &apb0_i2c_clk.common, + &apb0_twd_clk.common, + &a83t_ir_clk.common, +}; + static struct ccu_common *sun8i_h3_r_ccu_clks[] = { &ar100_clk.common, &apb0_clk.common, @@ -115,6 +180,23 @@ static struct ccu_common *sun50i_a64_r_ccu_clks[] = { &ir_clk.common, }; +static struct clk_hw_onecell_data sun8i_a83t_r_hw_clks = { + .hws = { + [CLK_AR100] = &a83t_ar100_clk.common.hw, + [CLK_AHB0] = &ahb0_clk.hw, + [CLK_APB0] = &a83t_apb0_clk.common.hw, + [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, + [CLK_APB0_IR] = &apb0_ir_clk.common.hw, + [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw, + [CLK_APB0_RSB] = &apb0_rsb_clk.common.hw, + [CLK_APB0_UART] = &apb0_uart_clk.common.hw, + [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw, + [CLK_APB0_TWD] = &apb0_twd_clk.common.hw, + [CLK_IR] = &a83t_ir_clk.common.hw, + }, + .num = CLK_NUMBER, +}; + static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = { .hws = { [CLK_AR100] = &ar100_clk.common.hw, @@ -148,6 +230,14 @@ static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = { .num = CLK_NUMBER, }; +static struct ccu_reset_map sun8i_a83t_r_ccu_resets[] = { + [RST_APB0_IR] = { 0xb0, BIT(1) }, + [RST_APB0_TIMER] = { 0xb0, BIT(2) }, + [RST_APB0_RSB] = { 0xb0, BIT(3) }, + [RST_APB0_UART] = { 0xb0, BIT(4) }, + [RST_APB0_I2C] = { 0xb0, BIT(6) }, +}; + static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = { [RST_APB0_IR] = { 0xb0, BIT(1) }, [RST_APB0_TIMER] = { 0xb0, BIT(2) }, @@ -163,6 +253,16 @@ static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = { [RST_APB0_I2C] = { 0xb0, BIT(6) }, }; +static const struct sunxi_ccu_desc sun8i_a83t_r_ccu_desc = { + .ccu_clks = sun8i_a83t_r_ccu_clks, + .num_ccu_clks = ARRAY_SIZE(sun8i_a83t_r_ccu_clks), + + .hw_clks = &sun8i_a83t_r_hw_clks, + + .resets = sun8i_a83t_r_ccu_resets, + .num_resets = ARRAY_SIZE(sun8i_a83t_r_ccu_resets), +}; + static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = { .ccu_clks = sun8i_h3_r_ccu_clks, .num_ccu_clks = ARRAY_SIZE(sun8i_h3_r_ccu_clks), @@ -198,6 +298,13 @@ static void __init sunxi_r_ccu_init(struct device_node *node, sunxi_ccu_probe(node, reg, desc); } +static void __init sun8i_a83t_r_ccu_setup(struct device_node *node) +{ + sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc); +} +CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu", + sun8i_a83t_r_ccu_setup); + static void __init sun8i_h3_r_ccu_setup(struct device_node *node) { sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index e58706b40ae9..a34a78d7fb28 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c @@ -132,6 +132,9 @@ static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x050, 0, 2, 0); static const char * const ahb1_parents[] = { "osc32k", "osc24M", "axi", "pll-periph0" }; +static const struct ccu_mux_var_prediv ahb1_predivs[] = { + { .index = 3, .shift = 6, .width = 2 }, +}; static struct ccu_div ahb1_clk = { .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), @@ -139,11 +142,8 @@ static struct ccu_div ahb1_clk = { .shift = 12, .width = 2, - .variable_prediv = { - .index = 3, - .shift = 6, - .width = 2, - }, + .var_predivs = ahb1_predivs, + .n_var_predivs = ARRAY_SIZE(ahb1_predivs), }, .common = { @@ -537,7 +537,7 @@ static struct ccu_reset_map sun8i_v3s_ccu_resets[] = { [RST_BUS_EMAC] = { 0x2c0, BIT(17) }, [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) }, [RST_BUS_SPI0] = { 0x2c0, BIT(20) }, - [RST_BUS_OTG] = { 0x2c0, BIT(23) }, + [RST_BUS_OTG] = { 0x2c0, BIT(24) }, [RST_BUS_EHCI0] = { 0x2c0, BIT(26) }, [RST_BUS_OHCI0] = { 0x2c0, BIT(29) }, diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c index 4057e6021aa9..c0e5c10d0091 100644 --- a/drivers/clk/sunxi-ng/ccu_div.c +++ b/drivers/clk/sunxi-ng/ccu_div.c @@ -14,23 +14,17 @@ #include "ccu_div.h" static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux, - unsigned long parent_rate, + struct clk_hw *parent, + unsigned long *parent_rate, unsigned long rate, void *data) { struct ccu_div *cd = data; - unsigned long val; - - /* - * We can't use divider_round_rate that assumes that there's - * several parents, while we might be called to evaluate - * several different parents. - */ - val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width, - cd->div.flags); - return divider_recalc_rate(&cd->common.hw, parent_rate, val, - cd->div.table, cd->div.flags); + return divider_round_rate_parent(&cd->common.hw, parent, + rate, parent_rate, + cd->div.table, cd->div.width, + cd->div.flags); } static void ccu_div_disable(struct clk_hw *hw) @@ -65,8 +59,8 @@ static unsigned long ccu_div_recalc_rate(struct clk_hw *hw, val = reg >> cd->div.shift; val &= (1 << cd->div.width) - 1; - ccu_mux_helper_adjust_parent_for_prediv(&cd->common, &cd->mux, -1, - &parent_rate); + parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1, + parent_rate); return divider_recalc_rate(hw, parent_rate, val, cd->div.table, cd->div.flags); @@ -77,18 +71,6 @@ static int ccu_div_determine_rate(struct clk_hw *hw, { struct ccu_div *cd = hw_to_ccu_div(hw); - if (clk_hw_get_num_parents(hw) == 1) { - req->rate = divider_round_rate(hw, req->rate, - &req->best_parent_rate, - cd->div.table, - cd->div.width, - cd->div.flags); - - req->best_parent_hw = clk_hw_get_parent(hw); - - return 0; - } - return ccu_mux_helper_determine_rate(&cd->common, &cd->mux, req, ccu_div_round_rate, cd); } @@ -101,8 +83,8 @@ static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long val; u32 reg; - ccu_mux_helper_adjust_parent_for_prediv(&cd->common, &cd->mux, -1, - &parent_rate); + parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1, + parent_rate); val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width, cd->div.flags); diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index b583f186a804..b917ad7a386c 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -41,7 +41,8 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate, } static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, - unsigned long parent_rate, + struct clk_hw *hw, + unsigned long *parent_rate, unsigned long rate, void *data) { @@ -52,9 +53,9 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, max_m = cmp->m.max ?: 1 << cmp->m.width; max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); - ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p); + ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p); - return parent_rate / p / m; + return *parent_rate / p / m; } static void ccu_mp_disable(struct clk_hw *hw) @@ -86,8 +87,8 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw, u32 reg; /* Adjust parent_rate according to pre-dividers */ - ccu_mux_helper_adjust_parent_for_prediv(&cmp->common, &cmp->mux, - -1, &parent_rate); + parent_rate = ccu_mux_helper_apply_prediv(&cmp->common, &cmp->mux, -1, + parent_rate); reg = readl(cmp->common.base + cmp->common.reg); @@ -122,8 +123,8 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate, u32 reg; /* Adjust parent_rate according to pre-dividers */ - ccu_mux_helper_adjust_parent_for_prediv(&cmp->common, &cmp->mux, - -1, &parent_rate); + parent_rate = ccu_mux_helper_apply_prediv(&cmp->common, &cmp->mux, -1, + parent_rate); max_m = cmp->m.max ?: 1 << cmp->m.width; max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c index 671141359895..20d0300867f2 100644 --- a/drivers/clk/sunxi-ng/ccu_mult.c +++ b/drivers/clk/sunxi-ng/ccu_mult.c @@ -33,9 +33,10 @@ static void ccu_mult_find_best(unsigned long parent, unsigned long rate, } static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, - unsigned long parent_rate, - unsigned long rate, - void *data) + struct clk_hw *parent, + unsigned long *parent_rate, + unsigned long rate, + void *data) { struct ccu_mult *cm = data; struct _ccu_mult _cm; @@ -47,9 +48,9 @@ static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, else _cm.max = (1 << cm->mult.width) + cm->mult.offset - 1; - ccu_mult_find_best(parent_rate, rate, &_cm); + ccu_mult_find_best(*parent_rate, rate, &_cm); - return parent_rate * _cm.mult; + return *parent_rate * _cm.mult; } static void ccu_mult_disable(struct clk_hw *hw) @@ -87,8 +88,8 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw, val = reg >> cm->mult.shift; val &= (1 << cm->mult.width) - 1; - ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1, - &parent_rate); + parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1, + parent_rate); return parent_rate * (val + cm->mult.offset); } @@ -115,8 +116,8 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate, else ccu_frac_helper_disable(&cm->common, &cm->frac); - ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1, - &parent_rate); + parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1, + parent_rate); _cm.min = cm->mult.min; diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c index c6bb1f523232..cfe4538304fb 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.c +++ b/drivers/clk/sunxi-ng/ccu_mux.c @@ -15,24 +15,20 @@ #include "ccu_gate.h" #include "ccu_mux.h" -void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common, - struct ccu_mux_internal *cm, - int parent_index, - unsigned long *parent_rate) +static u16 ccu_mux_get_prediv(struct ccu_common *common, + struct ccu_mux_internal *cm, + int parent_index) { u16 prediv = 1; u32 reg; - int i; if (!((common->features & CCU_FEATURE_FIXED_PREDIV) || (common->features & CCU_FEATURE_VARIABLE_PREDIV) || (common->features & CCU_FEATURE_ALL_PREDIV))) - return; + return 1; - if (common->features & CCU_FEATURE_ALL_PREDIV) { - *parent_rate = *parent_rate / common->prediv; - return; - } + if (common->features & CCU_FEATURE_ALL_PREDIV) + return common->prediv; reg = readl(common->base + common->reg); if (parent_index < 0) { @@ -40,28 +36,52 @@ void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common, parent_index &= (1 << cm->width) - 1; } - if (common->features & CCU_FEATURE_FIXED_PREDIV) + if (common->features & CCU_FEATURE_FIXED_PREDIV) { + int i; + for (i = 0; i < cm->n_predivs; i++) if (parent_index == cm->fixed_predivs[i].index) prediv = cm->fixed_predivs[i].div; + } - if (common->features & CCU_FEATURE_VARIABLE_PREDIV) - if (parent_index == cm->variable_prediv.index) { - u8 div; + if (common->features & CCU_FEATURE_VARIABLE_PREDIV) { + int i; - div = reg >> cm->variable_prediv.shift; - div &= (1 << cm->variable_prediv.width) - 1; - prediv = div + 1; - } + for (i = 0; i < cm->n_var_predivs; i++) + if (parent_index == cm->var_predivs[i].index) { + u8 div; + + div = reg >> cm->var_predivs[i].shift; + div &= (1 << cm->var_predivs[i].width) - 1; + prediv = div + 1; + } + } + + return prediv; +} - *parent_rate = *parent_rate / prediv; +unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common, + struct ccu_mux_internal *cm, + int parent_index, + unsigned long parent_rate) +{ + return parent_rate / ccu_mux_get_prediv(common, cm, parent_index); +} + +unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common, + struct ccu_mux_internal *cm, + int parent_index, + unsigned long parent_rate) +{ + return parent_rate * ccu_mux_get_prediv(common, cm, parent_index); } int ccu_mux_helper_determine_rate(struct ccu_common *common, struct ccu_mux_internal *cm, struct clk_rate_request *req, unsigned long (*round)(struct ccu_mux_internal *, - unsigned long, + struct clk_hw *, + unsigned long *, unsigned long, void *), void *data) @@ -75,41 +95,43 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common, best_parent = clk_hw_get_parent(hw); best_parent_rate = clk_hw_get_rate(best_parent); + adj_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1, + best_parent_rate); - adj_parent_rate = best_parent_rate; - ccu_mux_helper_adjust_parent_for_prediv(common, cm, -1, - &adj_parent_rate); + best_rate = round(cm, best_parent, &adj_parent_rate, + req->rate, data); - best_rate = round(cm, adj_parent_rate, req->rate, data); + /* + * adj_parent_rate might have been modified by our clock. + * Unapply the pre-divider if there's one, and give + * the actual frequency the parent needs to run at. + */ + best_parent_rate = ccu_mux_helper_unapply_prediv(common, cm, -1, + adj_parent_rate); goto out; } for (i = 0; i < clk_hw_get_num_parents(hw); i++) { - unsigned long tmp_rate, parent_rate, adj_parent_rate; + unsigned long tmp_rate, parent_rate; struct clk_hw *parent; parent = clk_hw_get_parent_by_index(hw, i); if (!parent) continue; - if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { - struct clk_rate_request parent_req = *req; - int ret = __clk_determine_rate(parent, &parent_req); - - if (ret) - continue; + parent_rate = ccu_mux_helper_apply_prediv(common, cm, i, + clk_hw_get_rate(parent)); - parent_rate = parent_req.rate; - } else { - parent_rate = clk_hw_get_rate(parent); - } + tmp_rate = round(cm, parent, &parent_rate, req->rate, data); - adj_parent_rate = parent_rate; - ccu_mux_helper_adjust_parent_for_prediv(common, cm, i, - &adj_parent_rate); - - tmp_rate = round(cm, adj_parent_rate, req->rate, data); + /* + * parent_rate might have been modified by our clock. + * Unapply the pre-divider if there's one, and give + * the actual frequency the parent needs to run at. + */ + parent_rate = ccu_mux_helper_unapply_prediv(common, cm, i, + parent_rate); if (tmp_rate == req->rate) { best_parent = parent; best_parent_rate = parent_rate; @@ -217,10 +239,8 @@ static unsigned long ccu_mux_recalc_rate(struct clk_hw *hw, { struct ccu_mux *cm = hw_to_ccu_mux(hw); - ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1, - &parent_rate); - - return parent_rate; + return ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1, + parent_rate); } const struct clk_ops ccu_mux_ops = { diff --git a/drivers/clk/sunxi-ng/ccu_mux.h b/drivers/clk/sunxi-ng/ccu_mux.h index 47aba3a48245..f20c0bd62a47 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.h +++ b/drivers/clk/sunxi-ng/ccu_mux.h @@ -10,6 +10,12 @@ struct ccu_mux_fixed_prediv { u16 div; }; +struct ccu_mux_var_prediv { + u8 index; + u8 shift; + u8 width; +}; + struct ccu_mux_internal { u8 shift; u8 width; @@ -18,11 +24,8 @@ struct ccu_mux_internal { const struct ccu_mux_fixed_prediv *fixed_predivs; u8 n_predivs; - struct { - u8 index; - u8 shift; - u8 width; - } variable_prediv; + const struct ccu_mux_var_prediv *var_predivs; + u8 n_var_predivs; }; #define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table) \ @@ -78,15 +81,16 @@ static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw) extern const struct clk_ops ccu_mux_ops; -void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common, - struct ccu_mux_internal *cm, - int parent_index, - unsigned long *parent_rate); +unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common, + struct ccu_mux_internal *cm, + int parent_index, + unsigned long parent_rate); int ccu_mux_helper_determine_rate(struct ccu_common *common, struct ccu_mux_internal *cm, struct clk_rate_request *req, unsigned long (*round)(struct ccu_mux_internal *, - unsigned long, + struct clk_hw *, + unsigned long *, unsigned long, void *), void *data); diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c index cba84afe1cf1..44b16dc8fea6 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.c +++ b/drivers/clk/sunxi-ng/ccu_nkm.c @@ -102,7 +102,8 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw, } static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, - unsigned long parent_rate, + struct clk_hw *hw, + unsigned long *parent_rate, unsigned long rate, void *data) { @@ -116,9 +117,9 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, _nkm.min_m = 1; _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; - ccu_nkm_find_best(parent_rate, rate, &_nkm); + ccu_nkm_find_best(*parent_rate, rate, &_nkm); - return parent_rate * _nkm.n * _nkm.k / _nkm.m; + return *parent_rate * _nkm.n * _nkm.k / _nkm.m; } static int ccu_nkm_determine_rate(struct clk_hw *hw, diff --git a/drivers/clk/sunxi-ng/ccu_reset.h b/drivers/clk/sunxi-ng/ccu_reset.h index 36a4679210bd..ff8f5ebca435 100644 --- a/drivers/clk/sunxi-ng/ccu_reset.h +++ b/drivers/clk/sunxi-ng/ccu_reset.h @@ -15,6 +15,7 @@ #define _CCU_RESET_H_ #include <linux/reset-controller.h> +#include <linux/spinlock.h> struct ccu_reset_map { u16 reg; diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index 12409a519cc5..45eaf06462ae 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -354,6 +354,7 @@ static int powernv_add_idle_states(void) for (i = 0; i < dt_idle_states; i++) { unsigned int exit_latency, target_residency; + bool stops_timebase = false; /* * If an idle state has exit latency beyond * POWERNV_THRESHOLD_LATENCY_NS then don't use it @@ -381,6 +382,9 @@ static int powernv_add_idle_states(void) } } + if (flags[i] & OPAL_PM_TIMEBASE_STOP) + stops_timebase = true; + /* * For nap and fastsleep, use default target_residency * values if f/w does not expose it. @@ -392,8 +396,7 @@ static int powernv_add_idle_states(void) add_powernv_state(nr_idle_states, "Nap", CPUIDLE_FLAG_NONE, nap_loop, target_residency, exit_latency, 0, 0); - } else if ((flags[i] & OPAL_PM_STOP_INST_FAST) && - !(flags[i] & OPAL_PM_TIMEBASE_STOP)) { + } else if (has_stop_states && !stops_timebase) { add_powernv_state(nr_idle_states, names[i], CPUIDLE_FLAG_NONE, stop_loop, target_residency, exit_latency, @@ -405,8 +408,8 @@ static int powernv_add_idle_states(void) * within this config dependency check. */ #ifdef CONFIG_TICK_ONESHOT - if (flags[i] & OPAL_PM_SLEEP_ENABLED || - flags[i] & OPAL_PM_SLEEP_ENABLED_ER1) { + else if (flags[i] & OPAL_PM_SLEEP_ENABLED || + flags[i] & OPAL_PM_SLEEP_ENABLED_ER1) { if (!rc) target_residency = 300000; /* Add FASTSLEEP state */ @@ -414,14 +417,15 @@ static int powernv_add_idle_states(void) CPUIDLE_FLAG_TIMER_STOP, fastsleep_loop, target_residency, exit_latency, 0, 0); - } else if ((flags[i] & OPAL_PM_STOP_INST_DEEP) && - (flags[i] & OPAL_PM_TIMEBASE_STOP)) { + } else if (has_stop_states && stops_timebase) { add_powernv_state(nr_idle_states, names[i], CPUIDLE_FLAG_TIMER_STOP, stop_loop, target_residency, exit_latency, psscr_val[i], psscr_mask[i]); } #endif + else + continue; nr_idle_states++; } out: diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index fb1e60f5002e..9c7951bb05ac 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -89,6 +89,20 @@ config PKEY requires to have at least one CEX card in coprocessor mode available at runtime. +config CRYPTO_PAES_S390 + tristate "PAES cipher algorithms" + depends on S390 + depends on ZCRYPT + depends on PKEY + select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER + help + This is the s390 hardware accelerated implementation of the + AES cipher algorithms for use with protected key. + + Select this option if you want to use the paes cipher + for example to use protected key encrypted devices. + config CRYPTO_SHA1_S390 tristate "SHA1 digest algorithm" depends on S390 @@ -137,7 +151,6 @@ config CRYPTO_AES_S390 depends on S390 select CRYPTO_ALGAPI select CRYPTO_BLKCIPHER - select PKEY help This is the s390 hardware accelerated implementation of the AES cipher algorithms (FIPS-197). diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index 44c01390d035..dc269cb288c2 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c @@ -47,6 +47,7 @@ DEFINE_DMI_ATTR_WITH_SHOW(product_name, 0444, DMI_PRODUCT_NAME); DEFINE_DMI_ATTR_WITH_SHOW(product_version, 0444, DMI_PRODUCT_VERSION); DEFINE_DMI_ATTR_WITH_SHOW(product_serial, 0400, DMI_PRODUCT_SERIAL); DEFINE_DMI_ATTR_WITH_SHOW(product_uuid, 0400, DMI_PRODUCT_UUID); +DEFINE_DMI_ATTR_WITH_SHOW(product_family, 0400, DMI_PRODUCT_FAMILY); DEFINE_DMI_ATTR_WITH_SHOW(board_vendor, 0444, DMI_BOARD_VENDOR); DEFINE_DMI_ATTR_WITH_SHOW(board_name, 0444, DMI_BOARD_NAME); DEFINE_DMI_ATTR_WITH_SHOW(board_version, 0444, DMI_BOARD_VERSION); @@ -191,6 +192,7 @@ static void __init dmi_id_init_attr_table(void) ADD_DMI_ATTR(product_version, DMI_PRODUCT_VERSION); ADD_DMI_ATTR(product_serial, DMI_PRODUCT_SERIAL); ADD_DMI_ATTR(product_uuid, DMI_PRODUCT_UUID); + ADD_DMI_ATTR(product_family, DMI_PRODUCT_FAMILY); ADD_DMI_ATTR(board_vendor, DMI_BOARD_VENDOR); ADD_DMI_ATTR(board_name, DMI_BOARD_NAME); ADD_DMI_ATTR(board_version, DMI_BOARD_VERSION); diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 54be60ead08f..93f7acdaac7a 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -430,6 +430,7 @@ static void __init dmi_decode(const struct dmi_header *dm, void *dummy) dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); dmi_save_uuid(dm, DMI_PRODUCT_UUID, 8); + dmi_save_ident(dm, DMI_PRODUCT_FAMILY, 26); break; case 2: /* Base Board Information */ dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c index ef1fafdad400..5a0fa939d70f 100644 --- a/drivers/firmware/efi/efi-pstore.c +++ b/drivers/firmware/efi/efi-pstore.c @@ -4,7 +4,7 @@ #include <linux/slab.h> #include <linux/ucs2_string.h> -#define DUMP_NAME_LEN 52 +#define DUMP_NAME_LEN 66 static bool efivars_pstore_disable = IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE); @@ -244,12 +244,12 @@ static int efi_pstore_write(struct pstore_record *record) efi_guid_t vendor = LINUX_EFI_CRASH_GUID; int i, ret = 0; - record->time.tv_sec = get_seconds(); - record->time.tv_nsec = 0; - record->id = generic_id(record->time.tv_sec, record->part, record->count); + /* Since we copy the entire length of name, make sure it is wiped. */ + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu-%c", record->type, record->part, record->count, record->time.tv_sec, record->compressed ? 'C' : 'D'); @@ -267,44 +267,20 @@ static int efi_pstore_write(struct pstore_record *record) return ret; }; -struct pstore_erase_data { - struct pstore_record *record; - efi_char16_t *name; -}; - /* * Clean up an entry with the same name */ static int efi_pstore_erase_func(struct efivar_entry *entry, void *data) { - struct pstore_erase_data *ed = data; + efi_char16_t *efi_name = data; efi_guid_t vendor = LINUX_EFI_CRASH_GUID; - efi_char16_t efi_name_old[DUMP_NAME_LEN]; - efi_char16_t *efi_name = ed->name; - unsigned long ucs2_len = ucs2_strlen(ed->name); - char name_old[DUMP_NAME_LEN]; - int i; + unsigned long ucs2_len = ucs2_strlen(efi_name); if (efi_guidcmp(entry->var.VendorGuid, vendor)) return 0; - if (ucs2_strncmp(entry->var.VariableName, - efi_name, (size_t)ucs2_len)) { - /* - * Check if an old format, which doesn't support - * holding multiple logs, remains. - */ - snprintf(name_old, sizeof(name_old), "dump-type%u-%u-%lu", - ed->record->type, ed->record->part, - ed->record->time.tv_sec); - - for (i = 0; i < DUMP_NAME_LEN; i++) - efi_name_old[i] = name_old[i]; - - if (ucs2_strncmp(entry->var.VariableName, efi_name_old, - ucs2_strlen(efi_name_old))) - return 0; - } + if (ucs2_strncmp(entry->var.VariableName, efi_name, (size_t)ucs2_len)) + return 0; if (entry->scanning) { /* @@ -321,35 +297,48 @@ static int efi_pstore_erase_func(struct efivar_entry *entry, void *data) return 1; } -static int efi_pstore_erase(struct pstore_record *record) +static int efi_pstore_erase_name(const char *name) { - struct pstore_erase_data edata; struct efivar_entry *entry = NULL; - char name[DUMP_NAME_LEN]; efi_char16_t efi_name[DUMP_NAME_LEN]; int found, i; - snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu", - record->type, record->part, record->count, - record->time.tv_sec); - - for (i = 0; i < DUMP_NAME_LEN; i++) + for (i = 0; i < DUMP_NAME_LEN; i++) { efi_name[i] = name[i]; - - edata.record = record; - edata.name = efi_name; + if (name[i] == '\0') + break; + } if (efivar_entry_iter_begin()) return -EINTR; - found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry); - if (found && !entry->scanning) { - efivar_entry_iter_end(); + found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, + efi_name, &entry); + efivar_entry_iter_end(); + + if (found && !entry->scanning) efivar_unregister(entry); - } else - efivar_entry_iter_end(); - return 0; + return found ? 0 : -ENOENT; +} + +static int efi_pstore_erase(struct pstore_record *record) +{ + char name[DUMP_NAME_LEN]; + int ret; + + snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu", + record->type, record->part, record->count, + record->time.tv_sec); + ret = efi_pstore_erase_name(name); + if (ret != -ENOENT) + return ret; + + snprintf(name, sizeof(name), "dump-type%u-%u-%lu", + record->type, record->part, record->time.tv_sec); + ret = efi_pstore_erase_name(name); + + return ret; } static struct pstore_info efi_pstore_info = { diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c index 1e7860f02f4f..31058d400bda 100644 --- a/drivers/firmware/google/vpd.c +++ b/drivers/firmware/google/vpd.c @@ -136,12 +136,12 @@ static int vpd_section_attrib_add(const u8 *key, s32 key_len, info->value = value; INIT_LIST_HEAD(&info->list); - list_add_tail(&info->list, &sec->attribs); ret = sysfs_create_bin_file(sec->kobj, &info->bin_attr); if (ret) goto free_info_key; + list_add_tail(&info->list, &sec->attribs); return 0; free_info_key: @@ -158,8 +158,8 @@ static void vpd_section_attrib_destroy(struct vpd_section *sec) struct vpd_attrib_info *temp; list_for_each_entry_safe(info, temp, &sec->attribs, list) { - kfree(info->key); sysfs_remove_bin_file(sec->kobj, &info->bin_attr); + kfree(info->key); kfree(info); } } @@ -244,7 +244,7 @@ static int vpd_section_destroy(struct vpd_section *sec) { if (sec->enabled) { vpd_section_attrib_destroy(sec); - kobject_del(sec->kobj); + kobject_put(sec->kobj); sysfs_remove_bin_file(vpd_kobj, &sec->bin_attr); kfree(sec->raw_name); iounmap(sec->baseaddr); @@ -331,7 +331,7 @@ static void __exit vpd_platform_exit(void) { vpd_section_destroy(&ro_vpd); vpd_section_destroy(&rw_vpd); - kobject_del(vpd_kobj); + kobject_put(vpd_kobj); } module_init(vpd_platform_init); diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 8be9719284b0..aa885a614e27 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -508,6 +508,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, bool has_connectors = !!new_crtc_state->connector_mask; + WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + if (!drm_mode_equal(&old_crtc_state->mode, &new_crtc_state->mode)) { DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n", crtc->base.id, crtc->name); @@ -551,6 +553,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) { const struct drm_connector_helper_funcs *funcs = connector->helper_private; + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + /* * This only sets crtc->connectors_changed for routing changes, * drivers must set crtc->connectors_changed themselves when @@ -650,6 +654,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev, for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { const struct drm_plane_helper_funcs *funcs; + WARN_ON(!drm_modeset_is_locked(&plane->mutex)); + funcs = plane->helper_private; drm_atomic_helper_plane_changed(state, old_plane_state, new_plane_state, plane); @@ -2663,7 +2669,12 @@ int drm_atomic_helper_resume(struct drm_device *dev, drm_modeset_acquire_init(&ctx, 0); while (1) { + err = drm_modeset_lock_all_ctx(dev, &ctx); + if (err) + goto out; + err = drm_atomic_helper_commit_duplicated_state(state, &ctx); +out: if (err != -EDEADLK) break; diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c index dca989eb2d42..24fe04d6307b 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.c +++ b/drivers/gpu/drm/i915/gvt/execlist.c @@ -779,8 +779,26 @@ static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id) vgpu_vreg(vgpu, ctx_status_ptr_reg) = ctx_status_ptr.dw; } +static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask) +{ + struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; + struct intel_engine_cs *engine; + struct intel_vgpu_workload *pos, *n; + unsigned int tmp; + + /* free the unsubmited workloads in the queues. */ + for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { + list_for_each_entry_safe(pos, n, + &vgpu->workload_q_head[engine->id], list) { + list_del_init(&pos->list); + free_workload(pos); + } + } +} + void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu) { + clean_workloads(vgpu, ALL_ENGINES); kmem_cache_destroy(vgpu->workloads); } @@ -811,17 +829,9 @@ void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu, { struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct intel_engine_cs *engine; - struct intel_vgpu_workload *pos, *n; unsigned int tmp; - for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { - /* free the unsubmited workload in the queue */ - list_for_each_entry_safe(pos, n, - &vgpu->workload_q_head[engine->id], list) { - list_del_init(&pos->list); - free_workload(pos); - } - + clean_workloads(vgpu, engine_mask); + for_each_engine_masked(engine, dev_priv, engine_mask, tmp) init_vgpu_execlist(vgpu, engine->id); - } } diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index c995e540ff96..0ffd69654592 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1366,18 +1366,28 @@ static int skl_misc_ctl_write(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes) { struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; - i915_reg_t reg = {.reg = offset}; + u32 v = *(u32 *)p_data; + + if (!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv)) + return intel_vgpu_default_mmio_write(vgpu, + offset, p_data, bytes); switch (offset) { case 0x4ddc: - vgpu_vreg(vgpu, offset) = 0x8000003c; - /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl */ - I915_WRITE(reg, vgpu_vreg(vgpu, offset)); + /* bypass WaCompressedResourceSamplerPbeMediaNewHashMode */ + vgpu_vreg(vgpu, offset) = v & ~(1 << 31); break; case 0x42080: - vgpu_vreg(vgpu, offset) = 0x8000; - /* WaCompressedResourceDisplayNewHashMode:skl */ - I915_WRITE(reg, vgpu_vreg(vgpu, offset)); + /* bypass WaCompressedResourceDisplayNewHashMode */ + vgpu_vreg(vgpu, offset) = v & ~(1 << 15); + break; + case 0xe194: + /* bypass WaCompressedResourceSamplerPbeMediaNewHashMode */ + vgpu_vreg(vgpu, offset) = v & ~(1 << 8); + break; + case 0x7014: + /* bypass WaCompressedResourceSamplerPbeMediaNewHashMode */ + vgpu_vreg(vgpu, offset) = v & ~(1 << 13); break; default: return -EINVAL; @@ -1634,7 +1644,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_DFH(GAM_ECOCHK, D_ALL, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(GEN7_COMMON_SLICE_CHICKEN1, D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(COMMON_SLICE_CHICKEN2, D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); + MMIO_DFH(COMMON_SLICE_CHICKEN2, D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, + skl_misc_ctl_write); MMIO_DFH(0x9030, D_ALL, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(0x20a0, D_ALL, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(0x2420, D_ALL, F_CMD_ACCESS, NULL, NULL); @@ -2568,7 +2579,8 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt) MMIO_D(0x6e570, D_BDW_PLUS); MMIO_D(0x65f10, D_BDW_PLUS); - MMIO_DFH(0xe194, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); + MMIO_DFH(0xe194, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, + skl_misc_ctl_write); MMIO_DFH(0xe188, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); MMIO_DFH(HALF_SLICE_CHICKEN2, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); MMIO_DFH(0x2580, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3036d4835b0f..c994fe6e65b2 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1272,10 +1272,6 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) dev_priv->ipc_enabled = false; - /* Everything is in place, we can now relax! */ - DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", - driver.name, driver.major, driver.minor, driver.patchlevel, - driver.date, pci_name(pdev), dev_priv->drm.primary->index); if (IS_ENABLED(CONFIG_DRM_I915_DEBUG)) DRM_INFO("DRM_I915_DEBUG enabled\n"); if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index a0563e18d753..50b8f1139ff9 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2313,7 +2313,7 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma, appgtt->base.allocate_va_range) { ret = appgtt->base.allocate_va_range(&appgtt->base, vma->node.start, - vma->node.size); + vma->size); if (ret) goto err_pages; } diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 129ed303a6c4..57d9f7f4ef15 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -59,9 +59,6 @@ static void i915_gem_shrinker_unlock(struct drm_device *dev, bool unlock) return; mutex_unlock(&dev->struct_mutex); - - /* expedite the RCU grace period to free some request slabs */ - synchronize_rcu_expedited(); } static bool any_vma_pinned(struct drm_i915_gem_object *obj) @@ -274,8 +271,6 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv) I915_SHRINK_ACTIVE); intel_runtime_pm_put(dev_priv); - synchronize_rcu(); /* wait for our earlier RCU delayed slab frees */ - return freed; } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index fd97fe00cd0d..190f6aa5d15e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2953,7 +2953,6 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) u32 pipestat_mask; u32 enable_mask; enum pipe pipe; - u32 val; pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV | PIPE_CRC_DONE_INTERRUPT_STATUS; @@ -2964,18 +2963,16 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) enable_mask = I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | + I915_LPE_PIPE_A_INTERRUPT | + I915_LPE_PIPE_B_INTERRUPT; + if (IS_CHERRYVIEW(dev_priv)) - enable_mask |= I915_DISPLAY_PIPE_C_EVENT_INTERRUPT; + enable_mask |= I915_DISPLAY_PIPE_C_EVENT_INTERRUPT | + I915_LPE_PIPE_C_INTERRUPT; WARN_ON(dev_priv->irq_mask != ~0); - val = (I915_LPE_PIPE_A_INTERRUPT | - I915_LPE_PIPE_B_INTERRUPT | - I915_LPE_PIPE_C_INTERRUPT); - - enable_mask |= val; - dev_priv->irq_mask = ~enable_mask; GEN5_IRQ_INIT(VLV_, dev_priv->irq_mask, enable_mask); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5a7c63e64381..65b837e96fe6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8280,7 +8280,7 @@ enum { /* MIPI DSI registers */ -#define _MIPI_PORT(port, a, c) ((port) ? c : a) /* ports A and C only */ +#define _MIPI_PORT(port, a, c) (((port) == PORT_A) ? a : c) /* ports A and C only */ #define _MMIO_MIPI(port, a, c) _MMIO(_MIPI_PORT(port, a, c)) #define MIPIO_TXESC_CLK_DIV1 _MMIO(0x160004) diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c index 668f00480d97..292fedf30b00 100644 --- a/drivers/gpu/drm/i915/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c @@ -149,44 +149,10 @@ static void lpe_audio_platdev_destroy(struct drm_i915_private *dev_priv) static void lpe_audio_irq_unmask(struct irq_data *d) { - struct drm_i915_private *dev_priv = d->chip_data; - unsigned long irqflags; - u32 val = (I915_LPE_PIPE_A_INTERRUPT | - I915_LPE_PIPE_B_INTERRUPT); - - if (IS_CHERRYVIEW(dev_priv)) - val |= I915_LPE_PIPE_C_INTERRUPT; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - - dev_priv->irq_mask &= ~val; - I915_WRITE(VLV_IIR, val); - I915_WRITE(VLV_IIR, val); - I915_WRITE(VLV_IMR, dev_priv->irq_mask); - POSTING_READ(VLV_IMR); - - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } static void lpe_audio_irq_mask(struct irq_data *d) { - struct drm_i915_private *dev_priv = d->chip_data; - unsigned long irqflags; - u32 val = (I915_LPE_PIPE_A_INTERRUPT | - I915_LPE_PIPE_B_INTERRUPT); - - if (IS_CHERRYVIEW(dev_priv)) - val |= I915_LPE_PIPE_C_INTERRUPT; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - - dev_priv->irq_mask |= val; - I915_WRITE(VLV_IMR, dev_priv->irq_mask); - I915_WRITE(VLV_IIR, val); - I915_WRITE(VLV_IIR, val); - POSTING_READ(VLV_IIR); - - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } static struct irq_chip lpe_audio_irqchip = { @@ -330,8 +296,6 @@ void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv) desc = irq_to_desc(dev_priv->lpe_audio.irq); - lpe_audio_irq_mask(&desc->irq_data); - lpe_audio_platdev_destroy(dev_priv); irq_free_desc(dev_priv->lpe_audio.irq); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index c8f7c631fc1f..dac4e003c1f3 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1989,7 +1989,7 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx, ce->ring = ring; ce->state = vma; - ce->initialised = engine->init_context == NULL; + ce->initialised |= engine->init_context == NULL; return 0; diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c index 1afb8b06e3e1..12b85b3278cd 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c @@ -320,7 +320,7 @@ static unsigned long max_dwords(struct drm_i915_gem_object *obj) static int igt_ctx_exec(void *arg) { struct drm_i915_private *i915 = arg; - struct drm_i915_gem_object *obj; + struct drm_i915_gem_object *obj = NULL; struct drm_file *file; IGT_TIMEOUT(end_time); LIST_HEAD(objects); @@ -359,7 +359,7 @@ static int igt_ctx_exec(void *arg) } for_each_engine(engine, i915, id) { - if (dw == 0) { + if (!obj) { obj = create_test_object(ctx, file, &objects); if (IS_ERR(obj)) { err = PTR_ERR(obj); @@ -376,8 +376,10 @@ static int igt_ctx_exec(void *arg) goto out_unlock; } - if (++dw == max_dwords(obj)) + if (++dw == max_dwords(obj)) { + obj = NULL; dw = 0; + } ndwords++; } ncontexts++; diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index d8fa7a9c9240..ce5f2d1f9994 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -245,8 +245,6 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, struct drm_connector_state *conn_state) { struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); - struct rockchip_dp_device *dp = to_dp(encoder); - int ret; /* * The hardware IC designed that VOP must output the RGB10 video @@ -258,16 +256,6 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, s->output_mode = ROCKCHIP_OUT_MODE_AAAA; s->output_type = DRM_MODE_CONNECTOR_eDP; - if (dp->data->chip_type == RK3399_EDP) { - /* - * For RK3399, VOP Lit must code the out mode to RGB888, - * VOP Big must code the out mode to RGB10. - */ - ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, - encoder); - if (ret > 0) - s->output_mode = ROCKCHIP_OUT_MODE_P888; - } return 0; } diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c index a2169dd3d26b..14fa1f8351e8 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -615,7 +615,6 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder) { struct cdn_dp_device *dp = encoder_to_dp(encoder); int ret, val; - struct rockchip_crtc_state *state; ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder); if (ret < 0) { @@ -625,14 +624,10 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder) DRM_DEV_DEBUG_KMS(dp->dev, "vop %s output to cdn-dp\n", (ret) ? "LIT" : "BIG"); - state = to_rockchip_crtc_state(encoder->crtc->state); - if (ret) { + if (ret) val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16); - state->output_mode = ROCKCHIP_OUT_MODE_P888; - } else { + else val = DP_SEL_VOP_LIT << 16; - state->output_mode = ROCKCHIP_OUT_MODE_AAAA; - } ret = cdn_dp_grf_write(dp, GRF_SOC_CON9, val); if (ret) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 3f7a82d1e095..45589d6ce65e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -875,6 +875,7 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, static void vop_crtc_enable(struct drm_crtc *crtc) { struct vop *vop = to_vop(crtc); + const struct vop_data *vop_data = vop->data; struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state); struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start; @@ -967,6 +968,13 @@ static void vop_crtc_enable(struct drm_crtc *crtc) DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n", s->output_type); } + + /* + * if vop is not support RGB10 output, need force RGB10 to RGB888. + */ + if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && + !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10)) + s->output_mode = ROCKCHIP_OUT_MODE_P888; VOP_CTRL_SET(vop, out_mode, s->output_mode); VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 5a4faa85dbd2..9979fd0c2282 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -142,6 +142,9 @@ struct vop_data { const struct vop_intr *intr; const struct vop_win_data *win; unsigned int win_size; + +#define VOP_FEATURE_OUTPUT_RGB10 BIT(0) + u64 feature; }; /* interrupt define */ diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 0da44442aab0..bafd698a28b1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -275,6 +275,7 @@ static const struct vop_intr rk3288_vop_intr = { static const struct vop_data rk3288_vop = { .init_table = rk3288_init_reg_table, .table_size = ARRAY_SIZE(rk3288_init_reg_table), + .feature = VOP_FEATURE_OUTPUT_RGB10, .intr = &rk3288_vop_intr, .ctrl = &rk3288_ctrl_data, .win = rk3288_vop_win_data, @@ -343,6 +344,7 @@ static const struct vop_reg_data rk3399_init_reg_table[] = { static const struct vop_data rk3399_vop_big = { .init_table = rk3399_init_reg_table, .table_size = ARRAY_SIZE(rk3399_init_reg_table), + .feature = VOP_FEATURE_OUTPUT_RGB10, .intr = &rk3399_vop_intr, .ctrl = &rk3399_ctrl_data, /* diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index fe40e5e499dd..d575e1852d8c 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -275,10 +275,12 @@ config HID_EMS_FF - Trio Linker Plus II config HID_ELECOM - tristate "ELECOM BM084 bluetooth mouse" + tristate "ELECOM HID devices" depends on HID ---help--- - Support for the ELECOM BM084 (bluetooth mouse). + Support for ELECOM devices: + - BM084 Bluetooth Mouse + - DEFT Trackball (Wired and wireless) config HID_ELO tristate "ELO USB 4000/4500 touchscreen" @@ -386,6 +388,13 @@ config HID_ICADE To compile this driver as a module, choose M here: the module will be called hid-icade. +config HID_ITE + tristate "ITE devices" + depends on HID + default !EXPERT + ---help--- + Support for ITE devices not fully compliant with HID standard. + config HID_TWINHAN tristate "Twinhan IR remote control" depends on HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index fef027bc7fa3..05ac8d375aeb 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_HID_HOLTEK) += hid-holtek-mouse.o obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o obj-$(CONFIG_HID_ICADE) += hid-icade.o +obj-$(CONFIG_HID_ITE) += hid-ite.o obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o obj-$(CONFIG_HID_KYE) += hid-kye.o diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 16df6cc90235..101ab2e63d18 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -69,6 +69,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define QUIRK_IS_MULTITOUCH BIT(3) #define QUIRK_NO_CONSUMER_USAGES BIT(4) #define QUIRK_USE_KBD_BACKLIGHT BIT(5) +#define QUIRK_T100_KEYBOARD BIT(6) #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ QUIRK_NO_INIT_REPORTS | \ @@ -548,6 +549,12 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, hid_info(hdev, "Fixing up Asus notebook report descriptor\n"); rdesc[55] = 0xdd; } + if (drvdata->quirks & QUIRK_T100_KEYBOARD && + *rsize == 76 && rdesc[73] == 0x81 && rdesc[74] == 0x01) { + hid_info(hdev, "Fixing up Asus T100 keyb report descriptor\n"); + rdesc[74] &= ~HID_MAIN_ITEM_CONSTANT; + } + return rdesc; } @@ -560,6 +567,9 @@ static const struct hid_device_id asus_devices[] = { USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2), QUIRK_USE_KBD_BACKLIGHT }, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD), + QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES }, { } }; MODULE_DEVICE_TABLE(hid, asus_devices); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 37084b645785..ec214a9117a1 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1855,6 +1855,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) }, @@ -1891,6 +1892,8 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_WN) }, { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_FA) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) }, @@ -1913,6 +1916,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2) }, { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_ZEN_AIO_KBD) }, { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c index 6e3848a8d8dd..e2c7465df69f 100644 --- a/drivers/hid/hid-elecom.c +++ b/drivers/hid/hid-elecom.c @@ -1,10 +1,8 @@ /* - * HID driver for Elecom BM084 (bluetooth mouse). - * Removes a non-existing horizontal wheel from - * the HID descriptor. - * (This module is based on "hid-ortek".) - * + * HID driver for ELECOM devices. * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com> + * Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com> + * Copyright (c) 2017 Diego Elio Pettenò <flameeyes@flameeyes.eu> */ /* @@ -23,15 +21,61 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { - if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) { - hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n"); - rdesc[47] = 0x00; + switch (hdev->product) { + case USB_DEVICE_ID_ELECOM_BM084: + /* The BM084 Bluetooth mouse includes a non-existing horizontal + * wheel in the HID descriptor. */ + if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) { + hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n"); + rdesc[47] = 0x00; + } + break; + case USB_DEVICE_ID_ELECOM_DEFT_WIRED: + case USB_DEVICE_ID_ELECOM_DEFT_WIRELESS: + /* The DEFT trackball has eight buttons, but its descriptor only + * reports five, disabling the three Fn buttons on the top of + * the mouse. + * + * Apply the following diff to the descriptor: + * + * Collection (Physical), Collection (Physical), + * Report ID (1), Report ID (1), + * Report Count (5), -> Report Count (8), + * Report Size (1), Report Size (1), + * Usage Page (Button), Usage Page (Button), + * Usage Minimum (01h), Usage Minimum (01h), + * Usage Maximum (05h), -> Usage Maximum (08h), + * Logical Minimum (0), Logical Minimum (0), + * Logical Maximum (1), Logical Maximum (1), + * Input (Variable), Input (Variable), + * Report Count (1), -> Report Count (0), + * Report Size (3), Report Size (3), + * Input (Constant), Input (Constant), + * Report Size (16), Report Size (16), + * Report Count (2), Report Count (2), + * Usage Page (Desktop), Usage Page (Desktop), + * Usage (X), Usage (X), + * Usage (Y), Usage (Y), + * Logical Minimum (-32768), Logical Minimum (-32768), + * Logical Maximum (32767), Logical Maximum (32767), + * Input (Variable, Relative), Input (Variable, Relative), + * End Collection, End Collection, + */ + if (*rsize == 213 && rdesc[13] == 5 && rdesc[21] == 5) { + hid_info(hdev, "Fixing up Elecom DEFT Fn buttons\n"); + rdesc[13] = 8; /* Button/Variable Report Count */ + rdesc[21] = 8; /* Button/Variable Usage Maximum */ + rdesc[29] = 0; /* Button/Constant Report Count */ + } + break; } return rdesc; } static const struct hid_device_id elecom_devices[] = { - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084)}, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) }, { } }; MODULE_DEVICE_TABLE(hid, elecom_devices); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 643390ba749d..8a027c112d90 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -173,6 +173,7 @@ #define USB_VENDOR_ID_ASUSTEK 0x0b05 #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 #define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b +#define USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD 0x17e0 #define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD 0x8585 #define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD 0x0101 #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854 @@ -358,6 +359,8 @@ #define USB_VENDOR_ID_ELECOM 0x056e #define USB_DEVICE_ID_ELECOM_BM084 0x0061 +#define USB_DEVICE_ID_ELECOM_DEFT_WIRED 0x00fe +#define USB_DEVICE_ID_ELECOM_DEFT_WIRELESS 0x00ff #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 #define USB_DEVICE_ID_DREAM_CHEEKY_WN 0x0004 @@ -559,6 +562,7 @@ #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 #define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396 +#define USB_DEVICE_ID_ITE8595 0x8595 #define USB_VENDOR_ID_JABRA 0x0b0e #define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412 diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index a1ebdd7d4d4d..ccdff1ee1f0c 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -656,6 +656,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case HID_GD_START: map_key_clear(BTN_START); break; case HID_GD_SELECT: map_key_clear(BTN_SELECT); break; + case HID_GD_RFKILL_BTN: + /* MS wireless radio ctl extension, also check CA */ + if (field->application == HID_GD_WIRELESS_RADIO_CTLS) { + map_key_clear(KEY_RFKILL); + /* We need to simulate the btn release */ + field->flags |= HID_MAIN_ITEM_RELATIVE; + break; + } + default: goto unknown; } diff --git a/drivers/hid/hid-ite.c b/drivers/hid/hid-ite.c new file mode 100644 index 000000000000..1882a4ab0f29 --- /dev/null +++ b/drivers/hid/hid-ite.c @@ -0,0 +1,56 @@ +/* + * HID driver for some ITE "special" devices + * Copyright (c) 2017 Hans de Goede <hdegoede@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/device.h> +#include <linux/input.h> +#include <linux/hid.h> +#include <linux/module.h> + +#include "hid-ids.h" + +static int ite_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) +{ + struct input_dev *input; + + if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput) + return 0; + + input = field->hidinput->input; + + /* + * The ITE8595 always reports 0 as value for the rfkill button. Luckily + * it is the only button in its report, and it sends a report on + * release only, so receiving a report means the button was pressed. + */ + if (usage->hid == HID_GD_RFKILL_BTN) { + input_event(input, EV_KEY, KEY_RFKILL, 1); + input_sync(input); + input_event(input, EV_KEY, KEY_RFKILL, 0); + input_sync(input); + return 1; + } + + return 0; +} + +static const struct hid_device_id ite_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, + { } +}; +MODULE_DEVICE_TABLE(hid, ite_devices); + +static struct hid_driver ite_driver = { + .name = "itetech", + .id_table = ite_devices, + .event = ite_event, +}; +module_hid_driver(ite_driver); + +MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 20b40ad26325..1d6c997b3001 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -349,6 +349,7 @@ static int magicmouse_raw_event(struct hid_device *hdev, if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { magicmouse_emit_buttons(msc, clicks & 3); + input_mt_report_pointer_emulation(input, true); input_report_rel(input, REL_X, x); input_report_rel(input, REL_Y, y); } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ @@ -388,16 +389,16 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd __clear_bit(BTN_RIGHT, input->keybit); __clear_bit(BTN_MIDDLE, input->keybit); __set_bit(BTN_MOUSE, input->keybit); - __set_bit(BTN_TOOL_FINGER, input->keybit); - __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); - __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); - __set_bit(BTN_TOOL_QUADTAP, input->keybit); - __set_bit(BTN_TOOL_QUINTTAP, input->keybit); - __set_bit(BTN_TOUCH, input->keybit); - __set_bit(INPUT_PROP_POINTER, input->propbit); __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); } + __set_bit(BTN_TOOL_FINGER, input->keybit); + __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); + __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); + __set_bit(BTN_TOOL_QUADTAP, input->keybit); + __set_bit(BTN_TOOL_QUINTTAP, input->keybit); + __set_bit(BTN_TOUCH, input->keybit); + __set_bit(INPUT_PROP_POINTER, input->propbit); __set_bit(EV_ABS, input->evbit); diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 8daa8ce64ebb..841aa43526eb 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -40,7 +40,7 @@ #include <linux/of.h> #include <linux/regulator/consumer.h> -#include <linux/i2c/i2c-hid.h> +#include <linux/platform_data/i2c-hid.h> #include "../hid-ids.h" diff --git a/drivers/hid/intel-ish-hid/Kconfig b/drivers/hid/intel-ish-hid/Kconfig index ea065b3684a2..519e4c8b53c4 100644 --- a/drivers/hid/intel-ish-hid/Kconfig +++ b/drivers/hid/intel-ish-hid/Kconfig @@ -1,5 +1,5 @@ menu "Intel ISH HID support" - depends on X86_64 && PCI + depends on (X86_64 || COMPILE_TEST) && PCI config INTEL_ISH_HID tristate "Intel Integrated Sensor Hub" diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c index 842d8416a7a6..9a60ec13cb10 100644 --- a/drivers/hid/intel-ish-hid/ipc/ipc.c +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c @@ -296,17 +296,12 @@ static int write_ipc_from_queue(struct ishtp_device *dev) /* If sending MNG_SYNC_FW_CLOCK, update clock again */ if (IPC_HEADER_GET_PROTOCOL(doorbell_val) == IPC_PROTOCOL_MNG && IPC_HEADER_GET_MNG_CMD(doorbell_val) == MNG_SYNC_FW_CLOCK) { - struct timespec ts_system; - struct timeval tv_utc; - uint64_t usec_system, usec_utc; + uint64_t usec_system, usec_utc; struct ipc_time_update_msg time_update; struct time_sync_format ts_format; - get_monotonic_boottime(&ts_system); - do_gettimeofday(&tv_utc); - usec_system = (timespec_to_ns(&ts_system)) / NSEC_PER_USEC; - usec_utc = (uint64_t)tv_utc.tv_sec * 1000000 + - ((uint32_t)tv_utc.tv_usec); + usec_system = ktime_to_us(ktime_get_boottime()); + usec_utc = ktime_to_us(ktime_get_real()); ts_format.ts1_source = HOST_SYSTEM_TIME_USEC; ts_format.ts2_source = HOST_UTC_TIME_USEC; ts_format.reserved = 0; @@ -575,15 +570,13 @@ static void fw_reset_work_fn(struct work_struct *unused) static void _ish_sync_fw_clock(struct ishtp_device *dev) { static unsigned long prev_sync; - struct timespec ts; uint64_t usec; if (prev_sync && jiffies - prev_sync < 20 * HZ) return; prev_sync = jiffies; - get_monotonic_boottime(&ts); - usec = (timespec_to_ns(&ts)) / NSEC_PER_USEC; + usec = ktime_to_us(ktime_get_boottime()); ipc_send_mng_msg(dev, MNG_SYNC_FW_CLOCK, &usec, sizeof(uint64_t)); } diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c index 5c643d7a07b2..157b44aacdff 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c @@ -136,10 +136,9 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf, if (1 + sizeof(struct device_info) * i >= payload_len) { dev_err(&client_data->cl_device->dev, - "[hid-ish]: [ENUM_DEVICES]: content size %lu is bigger than payload_len %u\n", + "[hid-ish]: [ENUM_DEVICES]: content size %zu is bigger than payload_len %zu\n", 1 + sizeof(struct device_info) - * i, - (unsigned int)payload_len); + * i, payload_len); } if (1 + sizeof(struct device_info) * i >= diff --git a/drivers/hid/intel-ish-hid/ishtp/client.c b/drivers/hid/intel-ish-hid/ishtp/client.c index aad61328f282..007443ef5fca 100644 --- a/drivers/hid/intel-ish-hid/ishtp/client.c +++ b/drivers/hid/intel-ish-hid/ishtp/client.c @@ -803,7 +803,7 @@ void ishtp_cl_send_msg(struct ishtp_device *dev, struct ishtp_cl *cl) * @ishtp_hdr: Pointer to message header * * Receive and dispatch ISHTP client messages. This function executes in ISR - * context + * or work queue context */ void recv_ishtp_cl_msg(struct ishtp_device *dev, struct ishtp_msg_hdr *ishtp_hdr) @@ -813,7 +813,6 @@ void recv_ishtp_cl_msg(struct ishtp_device *dev, struct ishtp_cl_rb *new_rb; unsigned char *buffer = NULL; struct ishtp_cl_rb *complete_rb = NULL; - unsigned long dev_flags; unsigned long flags; int rb_count; @@ -828,7 +827,7 @@ void recv_ishtp_cl_msg(struct ishtp_device *dev, goto eoi; } - spin_lock_irqsave(&dev->read_list_spinlock, dev_flags); + spin_lock_irqsave(&dev->read_list_spinlock, flags); rb_count = -1; list_for_each_entry(rb, &dev->read_list.list, list) { ++rb_count; @@ -840,8 +839,7 @@ void recv_ishtp_cl_msg(struct ishtp_device *dev, /* If no Rx buffer is allocated, disband the rb */ if (rb->buffer.size == 0 || rb->buffer.data == NULL) { - spin_unlock_irqrestore(&dev->read_list_spinlock, - dev_flags); + spin_unlock_irqrestore(&dev->read_list_spinlock, flags); dev_err(&cl->device->dev, "Rx buffer is not allocated.\n"); list_del(&rb->list); @@ -857,8 +855,7 @@ void recv_ishtp_cl_msg(struct ishtp_device *dev, * back FC, so communication will be stuck anyway) */ if (rb->buffer.size < ishtp_hdr->length + rb->buf_idx) { - spin_unlock_irqrestore(&dev->read_list_spinlock, - dev_flags); + spin_unlock_irqrestore(&dev->read_list_spinlock, flags); dev_err(&cl->device->dev, "message overflow. size %d len %d idx %ld\n", rb->buffer.size, ishtp_hdr->length, @@ -884,14 +881,13 @@ void recv_ishtp_cl_msg(struct ishtp_device *dev, * the whole msg arrived, send a new FC, and add a new * rb buffer for the next coming msg */ - spin_lock_irqsave(&cl->free_list_spinlock, flags); + spin_lock(&cl->free_list_spinlock); if (!list_empty(&cl->free_rb_list.list)) { new_rb = list_entry(cl->free_rb_list.list.next, struct ishtp_cl_rb, list); list_del_init(&new_rb->list); - spin_unlock_irqrestore(&cl->free_list_spinlock, - flags); + spin_unlock(&cl->free_list_spinlock); new_rb->cl = cl; new_rb->buf_idx = 0; INIT_LIST_HEAD(&new_rb->list); @@ -900,8 +896,7 @@ void recv_ishtp_cl_msg(struct ishtp_device *dev, ishtp_hbm_cl_flow_control_req(dev, cl); } else { - spin_unlock_irqrestore(&cl->free_list_spinlock, - flags); + spin_unlock(&cl->free_list_spinlock); } } /* One more fragment in message (even if this was last) */ @@ -914,7 +909,7 @@ void recv_ishtp_cl_msg(struct ishtp_device *dev, break; } - spin_unlock_irqrestore(&dev->read_list_spinlock, dev_flags); + spin_unlock_irqrestore(&dev->read_list_spinlock, flags); /* If it's nobody's message, just read and discard it */ if (!buffer) { uint8_t rd_msg_buf[ISHTP_RD_MSG_BUF_SIZE]; @@ -925,7 +920,8 @@ void recv_ishtp_cl_msg(struct ishtp_device *dev, } if (complete_rb) { - getnstimeofday(&cl->ts_rx); + cl = complete_rb->cl; + cl->ts_rx = ktime_get(); ++cl->recv_msg_cnt_ipc; ishtp_cl_read_complete(complete_rb); } @@ -940,7 +936,7 @@ eoi: * @hbm: hbm buffer * * Receive and dispatch ISHTP client messages using DMA. This function executes - * in ISR context + * in ISR or work queue context */ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, struct dma_xfer_hbm *hbm) @@ -950,10 +946,10 @@ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, struct ishtp_cl_rb *new_rb; unsigned char *buffer = NULL; struct ishtp_cl_rb *complete_rb = NULL; - unsigned long dev_flags; unsigned long flags; - spin_lock_irqsave(&dev->read_list_spinlock, dev_flags); + spin_lock_irqsave(&dev->read_list_spinlock, flags); + list_for_each_entry(rb, &dev->read_list.list, list) { cl = rb->cl; if (!cl || !(cl->host_client_id == hbm->host_client_id && @@ -965,8 +961,7 @@ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, * If no Rx buffer is allocated, disband the rb */ if (rb->buffer.size == 0 || rb->buffer.data == NULL) { - spin_unlock_irqrestore(&dev->read_list_spinlock, - dev_flags); + spin_unlock_irqrestore(&dev->read_list_spinlock, flags); dev_err(&cl->device->dev, "response buffer is not allocated.\n"); list_del(&rb->list); @@ -982,8 +977,7 @@ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, * back FC, so communication will be stuck anyway) */ if (rb->buffer.size < hbm->msg_length) { - spin_unlock_irqrestore(&dev->read_list_spinlock, - dev_flags); + spin_unlock_irqrestore(&dev->read_list_spinlock, flags); dev_err(&cl->device->dev, "message overflow. size %d len %d idx %ld\n", rb->buffer.size, hbm->msg_length, rb->buf_idx); @@ -1007,14 +1001,13 @@ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, * the whole msg arrived, send a new FC, and add a new * rb buffer for the next coming msg */ - spin_lock_irqsave(&cl->free_list_spinlock, flags); + spin_lock(&cl->free_list_spinlock); if (!list_empty(&cl->free_rb_list.list)) { new_rb = list_entry(cl->free_rb_list.list.next, struct ishtp_cl_rb, list); list_del_init(&new_rb->list); - spin_unlock_irqrestore(&cl->free_list_spinlock, - flags); + spin_unlock(&cl->free_list_spinlock); new_rb->cl = cl; new_rb->buf_idx = 0; INIT_LIST_HEAD(&new_rb->list); @@ -1023,8 +1016,7 @@ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, ishtp_hbm_cl_flow_control_req(dev, cl); } else { - spin_unlock_irqrestore(&cl->free_list_spinlock, - flags); + spin_unlock(&cl->free_list_spinlock); } /* One more fragment in message (this is always last) */ @@ -1037,7 +1029,7 @@ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, break; } - spin_unlock_irqrestore(&dev->read_list_spinlock, dev_flags); + spin_unlock_irqrestore(&dev->read_list_spinlock, flags); /* If it's nobody's message, just read and discard it */ if (!buffer) { dev_err(dev->devc, "Dropped Rx (DMA) msg - no request\n"); @@ -1045,7 +1037,8 @@ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, } if (complete_rb) { - getnstimeofday(&cl->ts_rx); + cl = complete_rb->cl; + cl->ts_rx = ktime_get(); ++cl->recv_msg_cnt_dma; ishtp_cl_read_complete(complete_rb); } diff --git a/drivers/hid/intel-ish-hid/ishtp/client.h b/drivers/hid/intel-ish-hid/ishtp/client.h index 444d069c2ed4..79eade547f5d 100644 --- a/drivers/hid/intel-ish-hid/ishtp/client.h +++ b/drivers/hid/intel-ish-hid/ishtp/client.h @@ -118,9 +118,9 @@ struct ishtp_cl { unsigned int out_flow_ctrl_cnt; /* Rx msg ... out FC timing */ - struct timespec ts_rx; - struct timespec ts_out_fc; - struct timespec ts_max_fc_delay; + ktime_t ts_rx; + ktime_t ts_out_fc; + ktime_t ts_max_fc_delay; void *client_data; }; diff --git a/drivers/hid/intel-ish-hid/ishtp/hbm.c b/drivers/hid/intel-ish-hid/ishtp/hbm.c index b7213608ce43..ae4a69f7f2f4 100644 --- a/drivers/hid/intel-ish-hid/ishtp/hbm.c +++ b/drivers/hid/intel-ish-hid/ishtp/hbm.c @@ -321,13 +321,10 @@ int ishtp_hbm_cl_flow_control_req(struct ishtp_device *dev, if (!rv) { ++cl->out_flow_ctrl_creds; ++cl->out_flow_ctrl_cnt; - getnstimeofday(&cl->ts_out_fc); - if (cl->ts_rx.tv_sec && cl->ts_rx.tv_nsec) { - struct timespec ts_diff; - - ts_diff = timespec_sub(cl->ts_out_fc, cl->ts_rx); - if (timespec_compare(&ts_diff, &cl->ts_max_fc_delay) - > 0) + cl->ts_out_fc = ktime_get(); + if (cl->ts_rx) { + ktime_t ts_diff = ktime_sub(cl->ts_out_fc, cl->ts_rx); + if (ktime_after(ts_diff, cl->ts_max_fc_delay)) cl->ts_max_fc_delay = ts_diff; } } else { diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index c7b9ab1907d8..3c37c3cbf6f1 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -138,6 +138,7 @@ struct wacom_battery { struct power_supply_desc bat_desc; struct power_supply *battery; char bat_name[WACOM_NAME_MAX]; + int bat_status; int battery_capacity; int bat_charging; int bat_connected; diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 0022c0dac88a..838c1ebfffa9 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1547,7 +1547,9 @@ static int wacom_battery_get_property(struct power_supply *psy, val->intval = battery->battery_capacity; break; case POWER_SUPPLY_PROP_STATUS: - if (battery->bat_charging) + if (battery->bat_status != WACOM_POWER_SUPPLY_STATUS_AUTO) + val->intval = battery->bat_status; + else if (battery->bat_charging) val->intval = POWER_SUPPLY_STATUS_CHARGING; else if (battery->battery_capacity == 100 && battery->ps_connected) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 4b225fb19a16..1992bb0732c2 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -57,15 +57,18 @@ static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; static void __wacom_notify_battery(struct wacom_battery *battery, - int bat_capacity, bool bat_charging, - bool bat_connected, bool ps_connected) + int bat_status, int bat_capacity, + bool bat_charging, bool bat_connected, + bool ps_connected) { - bool changed = battery->battery_capacity != bat_capacity || + bool changed = battery->bat_status != bat_status || + battery->battery_capacity != bat_capacity || battery->bat_charging != bat_charging || battery->bat_connected != bat_connected || battery->ps_connected != ps_connected; if (changed) { + battery->bat_status = bat_status; battery->battery_capacity = bat_capacity; battery->bat_charging = bat_charging; battery->bat_connected = bat_connected; @@ -77,13 +80,13 @@ static void __wacom_notify_battery(struct wacom_battery *battery, } static void wacom_notify_battery(struct wacom_wac *wacom_wac, - int bat_capacity, bool bat_charging, bool bat_connected, - bool ps_connected) + int bat_status, int bat_capacity, bool bat_charging, + bool bat_connected, bool ps_connected) { struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); - __wacom_notify_battery(&wacom->battery, bat_capacity, bat_charging, - bat_connected, ps_connected); + __wacom_notify_battery(&wacom->battery, bat_status, bat_capacity, + bat_charging, bat_connected, ps_connected); } static int wacom_penpartner_irq(struct wacom_wac *wacom) @@ -448,8 +451,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) rw = (data[7] >> 2 & 0x07); battery_capacity = batcap_gr[rw]; ps_connected = rw == 7; - wacom_notify_battery(wacom, battery_capacity, ps_connected, - 1, ps_connected); + wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, + battery_capacity, ps_connected, 1, + ps_connected); } exit: return retval; @@ -1071,7 +1075,8 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) wacom->led.groups[i].select = touch_ring_mode; } - __wacom_notify_battery(&remote->remotes[index].battery, bat_percent, + __wacom_notify_battery(&remote->remotes[index].battery, + WACOM_POWER_SUPPLY_STATUS_AUTO, bat_percent, bat_charging, 1, bat_charging); out: @@ -1157,7 +1162,8 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) bat_charging = (power_raw & 0x08) ? 1 : 0; ps_connected = (power_raw & 0x10) ? 1 : 0; battery_capacity = batcap_i4[power_raw & 0x07]; - wacom_notify_battery(wacom, battery_capacity, bat_charging, + wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, + battery_capacity, bat_charging, battery_capacity || bat_charging, ps_connected); break; @@ -1334,7 +1340,8 @@ static void wacom_intuos_pro2_bt_battery(struct wacom_wac *wacom) bool chg = data[284] & 0x80; int battery_status = data[284] & 0x7F; - wacom_notify_battery(wacom, battery_status, chg, 1, chg); + wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, + battery_status, chg, 1, chg); } static int wacom_intuos_pro2_bt_irq(struct wacom_wac *wacom, size_t len) @@ -1571,37 +1578,38 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) { unsigned char *data = wacom->data; - if (wacom->pen_input) + if (wacom->pen_input) { dev_dbg(wacom->pen_input->dev.parent, "%s: received report #%d\n", __func__, data[0]); - else if (wacom->touch_input) + + if (len == WACOM_PKGLEN_PENABLED || + data[0] == WACOM_REPORT_PENABLED) + return wacom_tpc_pen(wacom); + } + else if (wacom->touch_input) { dev_dbg(wacom->touch_input->dev.parent, "%s: received report #%d\n", __func__, data[0]); - switch (len) { - case WACOM_PKGLEN_TPC1FG: - return wacom_tpc_single_touch(wacom, len); - - case WACOM_PKGLEN_TPC2FG: - return wacom_tpc_mt_touch(wacom); + switch (len) { + case WACOM_PKGLEN_TPC1FG: + return wacom_tpc_single_touch(wacom, len); - case WACOM_PKGLEN_PENABLED: - return wacom_tpc_pen(wacom); + case WACOM_PKGLEN_TPC2FG: + return wacom_tpc_mt_touch(wacom); - default: - switch (data[0]) { - case WACOM_REPORT_TPC1FG: - case WACOM_REPORT_TPCHID: - case WACOM_REPORT_TPCST: - case WACOM_REPORT_TPC1FGE: - return wacom_tpc_single_touch(wacom, len); + default: + switch (data[0]) { + case WACOM_REPORT_TPC1FG: + case WACOM_REPORT_TPCHID: + case WACOM_REPORT_TPCST: + case WACOM_REPORT_TPC1FGE: + return wacom_tpc_single_touch(wacom, len); - case WACOM_REPORT_TPCMT: - case WACOM_REPORT_TPCMT2: - return wacom_mt_touch(wacom); + case WACOM_REPORT_TPCMT: + case WACOM_REPORT_TPCMT2: + return wacom_mt_touch(wacom); - case WACOM_REPORT_PENABLED: - return wacom_tpc_pen(wacom); + } } } @@ -1695,20 +1703,92 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage, } } -static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, +static void wacom_wac_battery_usage_mapping(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage) { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct wacom_features *features = &wacom_wac->features; - struct input_dev *input = wacom_wac->pad_input; unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); switch (equivalent_usage) { + case HID_DG_BATTERYSTRENGTH: case WACOM_HID_WD_BATTERY_LEVEL: case WACOM_HID_WD_BATTERY_CHARGING: features->quirks |= WACOM_QUIRK_BATTERY; break; + } +} + +static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) +{ + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); + + switch (equivalent_usage) { + case HID_DG_BATTERYSTRENGTH: + if (value == 0) { + wacom_wac->hid_data.bat_status = POWER_SUPPLY_STATUS_UNKNOWN; + } + else { + value = value * 100 / (field->logical_maximum - field->logical_minimum); + wacom_wac->hid_data.battery_capacity = value; + wacom_wac->hid_data.bat_connected = 1; + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; + } + break; + case WACOM_HID_WD_BATTERY_LEVEL: + value = value * 100 / (field->logical_maximum - field->logical_minimum); + wacom_wac->hid_data.battery_capacity = value; + wacom_wac->hid_data.bat_connected = 1; + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; + break; + case WACOM_HID_WD_BATTERY_CHARGING: + wacom_wac->hid_data.bat_charging = value; + wacom_wac->hid_data.ps_connected = value; + wacom_wac->hid_data.bat_connected = 1; + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; + break; + } +} + +static void wacom_wac_battery_pre_report(struct hid_device *hdev, + struct hid_report *report) +{ + return; +} + +static void wacom_wac_battery_report(struct hid_device *hdev, + struct hid_report *report) +{ + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + struct wacom_features *features = &wacom_wac->features; + + if (features->quirks & WACOM_QUIRK_BATTERY) { + int status = wacom_wac->hid_data.bat_status; + int capacity = wacom_wac->hid_data.battery_capacity; + bool charging = wacom_wac->hid_data.bat_charging; + bool connected = wacom_wac->hid_data.bat_connected; + bool powered = wacom_wac->hid_data.ps_connected; + + wacom_notify_battery(wacom_wac, status, capacity, charging, + connected, powered); + } +} + +static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, + struct hid_field *field, struct hid_usage *usage) +{ + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + struct wacom_features *features = &wacom_wac->features; + struct input_dev *input = wacom_wac->pad_input; + unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); + + switch (equivalent_usage) { case WACOM_HID_WD_ACCELEROMETER_X: __set_bit(INPUT_PROP_ACCELEROMETER, input->propbit); wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 0); @@ -1802,27 +1882,6 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, } } -static void wacom_wac_pad_battery_event(struct hid_device *hdev, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - struct wacom_wac *wacom_wac = &wacom->wacom_wac; - unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); - - switch (equivalent_usage) { - case WACOM_HID_WD_BATTERY_LEVEL: - wacom_wac->hid_data.battery_capacity = value; - wacom_wac->hid_data.bat_connected = 1; - break; - - case WACOM_HID_WD_BATTERY_CHARGING: - wacom_wac->hid_data.bat_charging = value; - wacom_wac->hid_data.ps_connected = value; - wacom_wac->hid_data.bat_connected = 1; - break; - } -} - static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { @@ -1896,24 +1955,6 @@ static void wacom_wac_pad_pre_report(struct hid_device *hdev, wacom_wac->hid_data.inrange_state = 0; } -static void wacom_wac_pad_battery_report(struct hid_device *hdev, - struct hid_report *report) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct wacom_features *features = &wacom_wac->features; - - if (features->quirks & WACOM_QUIRK_BATTERY) { - int capacity = wacom_wac->hid_data.battery_capacity; - bool charging = wacom_wac->hid_data.bat_charging; - bool connected = wacom_wac->hid_data.bat_connected; - bool powered = wacom_wac->hid_data.ps_connected; - - wacom_notify_battery(wacom_wac, capacity, charging, - connected, powered); - } -} - static void wacom_wac_pad_report(struct hid_device *hdev, struct hid_report *report) { @@ -1959,9 +2000,6 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev, case HID_DG_INRANGE: wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0); break; - case HID_DG_BATTERYSTRENGTH: - features->quirks |= WACOM_QUIRK_BATTERY; - break; case HID_DG_INVERT: wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_RUBBER, 0); @@ -2034,10 +2072,6 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field if (!(features->quirks & WACOM_QUIRK_SENSE)) wacom_wac->hid_data.sense_state = value; return; - case HID_DG_BATTERYSTRENGTH: - wacom_wac->hid_data.battery_capacity = value; - wacom_wac->hid_data.bat_connected = 1; - break; case HID_DG_INVERT: wacom_wac->hid_data.invert_state = value; return; @@ -2394,7 +2428,10 @@ void wacom_wac_usage_mapping(struct hid_device *hdev, if (WACOM_DIRECT_DEVICE(field)) features->device_type |= WACOM_DEVICETYPE_DIRECT; - if (WACOM_PAD_FIELD(field)) + /* usage tests must precede field tests */ + if (WACOM_BATTERY_USAGE(usage)) + wacom_wac_battery_usage_mapping(hdev, field, usage); + else if (WACOM_PAD_FIELD(field)) wacom_wac_pad_usage_mapping(hdev, field, usage); else if (WACOM_PEN_FIELD(field)) wacom_wac_pen_usage_mapping(hdev, field, usage); @@ -2413,11 +2450,12 @@ void wacom_wac_event(struct hid_device *hdev, struct hid_field *field, if (value > field->logical_maximum || value < field->logical_minimum) return; - if (WACOM_PAD_FIELD(field)) { - wacom_wac_pad_battery_event(hdev, field, usage, value); - if (wacom->wacom_wac.pad_input) - wacom_wac_pad_event(hdev, field, usage, value); - } else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) + /* usage tests must precede field tests */ + if (WACOM_BATTERY_USAGE(usage)) + wacom_wac_battery_event(hdev, field, usage, value); + else if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) + wacom_wac_pad_event(hdev, field, usage, value); + else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) wacom_wac_pen_event(hdev, field, usage, value); else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) wacom_wac_finger_event(hdev, field, usage, value); @@ -2451,6 +2489,8 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) if (wacom_wac->features.type != HID_GENERIC) return; + wacom_wac_battery_pre_report(hdev, report); + if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) wacom_wac_pad_pre_report(hdev, report); else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) @@ -2470,11 +2510,11 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) if (report->type != HID_INPUT_REPORT) return; - if (WACOM_PAD_FIELD(field)) { - wacom_wac_pad_battery_report(hdev, report); - if (wacom->wacom_wac.pad_input) - wacom_wac_pad_report(hdev, report); - } else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) + wacom_wac_battery_report(hdev, report); + + if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) + wacom_wac_pad_report(hdev, report); + else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) wacom_wac_pen_report(hdev, report); else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) wacom_wac_finger_report(hdev, report); @@ -2812,13 +2852,14 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS); } - wacom_notify_battery(wacom, battery, charging, 1, 0); + wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, + battery, charging, 1, 0); } else if (wacom->pid != 0) { /* disconnected while previously connected */ wacom->pid = 0; wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS); - wacom_notify_battery(wacom, 0, 0, 0, 0); + wacom_notify_battery(wacom, POWER_SUPPLY_STATUS_UNKNOWN, 0, 0, 0, 0); } return 0; @@ -2846,8 +2887,8 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) int battery = (data[8] & 0x3f) * 100 / 31; bool charging = !!(data[8] & 0x80); - wacom_notify_battery(wacom_wac, battery, charging, - battery || charging, 1); + wacom_notify_battery(wacom_wac, WACOM_POWER_SUPPLY_STATUS_AUTO, + battery, charging, battery || charging, 1); if (!wacom->battery.battery && !(features->quirks & WACOM_QUIRK_BATTERY)) { @@ -2859,7 +2900,7 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) wacom->battery.battery) { features->quirks &= ~WACOM_QUIRK_BATTERY; wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY); - wacom_notify_battery(wacom_wac, 0, 0, 0, 0); + wacom_notify_battery(wacom_wac, POWER_SUPPLY_STATUS_UNKNOWN, 0, 0, 0, 0); } return 0; } diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 570d29582b82..8a03654048bf 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -96,6 +96,8 @@ #define WACOM_DEVICETYPE_WL_MONITOR 0x0008 #define WACOM_DEVICETYPE_DIRECT 0x0010 +#define WACOM_POWER_SUPPLY_STATUS_AUTO -1 + #define WACOM_HID_UP_WACOMDIGITIZER 0xff0d0000 #define WACOM_HID_SP_PAD 0x00040000 #define WACOM_HID_SP_BUTTON 0x00090000 @@ -151,6 +153,10 @@ #define WACOM_HID_WT_X (WACOM_HID_UP_WACOMTOUCH | 0x130) #define WACOM_HID_WT_Y (WACOM_HID_UP_WACOMTOUCH | 0x131) +#define WACOM_BATTERY_USAGE(f) (((f)->hid == HID_DG_BATTERYSTRENGTH) || \ + ((f)->hid == WACOM_HID_WD_BATTERY_CHARGING) || \ + ((f)->hid == WACOM_HID_WD_BATTERY_LEVEL)) + #define WACOM_PAD_FIELD(f) (((f)->physical == HID_DG_TABLETFUNCTIONKEY) || \ ((f)->physical == WACOM_HID_WD_DIGITIZERFNKEYS) || \ ((f)->physical == WACOM_HID_WD_DIGITIZERINFO)) @@ -297,6 +303,7 @@ struct hid_data { int last_slot_field; int num_expected; int num_received; + int bat_status; int battery_capacity; int bat_charging; int bat_connected; diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c index 21d38c8af21e..7f4f9c4150e3 100644 --- a/drivers/iio/adc/bcm_iproc_adc.c +++ b/drivers/iio/adc/bcm_iproc_adc.c @@ -143,7 +143,7 @@ static void iproc_adc_reg_dump(struct iio_dev *indio_dev) iproc_adc_dbg_reg(dev, adc_priv, IPROC_SOFT_BYPASS_DATA); } -static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data) +static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data) { u32 channel_intr_status; u32 intr_status; @@ -167,7 +167,7 @@ static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data) return IRQ_NONE; } -static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data) +static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data) { irqreturn_t retval = IRQ_NONE; struct iproc_adc_priv *adc_priv; @@ -181,7 +181,7 @@ static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data) adc_priv = iio_priv(indio_dev); regmap_read(adc_priv->regmap, IPROC_INTERRUPT_STATUS, &intr_status); - dev_dbg(&indio_dev->dev, "iproc_adc_interrupt_thread(),INTRPT_STS:%x\n", + dev_dbg(&indio_dev->dev, "iproc_adc_interrupt_handler(),INTRPT_STS:%x\n", intr_status); intr_channels = (intr_status & IPROC_ADC_INTR_MASK) >> IPROC_ADC_INTR; @@ -566,8 +566,8 @@ static int iproc_adc_probe(struct platform_device *pdev) } ret = devm_request_threaded_irq(&pdev->dev, adc_priv->irqno, - iproc_adc_interrupt_thread, iproc_adc_interrupt_handler, + iproc_adc_interrupt_thread, IRQF_SHARED, "iproc-adc", indio_dev); if (ret) { dev_err(&pdev->dev, "request_irq error %d\n", ret); diff --git a/drivers/iio/adc/max9611.c b/drivers/iio/adc/max9611.c index ec82106480e1..b0526e4b9530 100644 --- a/drivers/iio/adc/max9611.c +++ b/drivers/iio/adc/max9611.c @@ -438,10 +438,10 @@ static ssize_t max9611_shunt_resistor_show(struct device *dev, struct max9611_dev *max9611 = iio_priv(dev_to_iio_dev(dev)); unsigned int i, r; - i = max9611->shunt_resistor_uohm / 1000; - r = max9611->shunt_resistor_uohm % 1000; + i = max9611->shunt_resistor_uohm / 1000000; + r = max9611->shunt_resistor_uohm % 1000000; - return sprintf(buf, "%u.%03u\n", i, r); + return sprintf(buf, "%u.%06u\n", i, r); } static IIO_DEVICE_ATTR(in_power_shunt_resistor, 0444, @@ -536,8 +536,8 @@ static int max9611_probe(struct i2c_client *client, int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*max9611)); - if (IS_ERR(indio_dev)) - return PTR_ERR(indio_dev); + if (!indio_dev) + return -ENOMEM; i2c_set_clientdata(client, indio_dev); diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c index b23527309088..81d4c39e414a 100644 --- a/drivers/iio/adc/sun4i-gpadc-iio.c +++ b/drivers/iio/adc/sun4i-gpadc-iio.c @@ -105,6 +105,8 @@ struct sun4i_gpadc_iio { bool no_irq; /* prevents concurrent reads of temperature and ADC */ struct mutex mutex; + struct thermal_zone_device *tzd; + struct device *sensor_device; }; #define SUN4I_GPADC_ADC_CHANNEL(_channel, _name) { \ @@ -502,7 +504,6 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, { struct sun4i_gpadc_iio *info = iio_priv(indio_dev); const struct of_device_id *of_dev; - struct thermal_zone_device *tzd; struct resource *mem; void __iomem *base; int ret; @@ -532,13 +533,14 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, if (!IS_ENABLED(CONFIG_THERMAL_OF)) return 0; - tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, info, - &sun4i_ts_tz_ops); - if (IS_ERR(tzd)) + info->sensor_device = &pdev->dev; + info->tzd = thermal_zone_of_sensor_register(info->sensor_device, 0, + info, &sun4i_ts_tz_ops); + if (IS_ERR(info->tzd)) dev_err(&pdev->dev, "could not register thermal sensor: %ld\n", - PTR_ERR(tzd)); + PTR_ERR(info->tzd)); - return PTR_ERR_OR_ZERO(tzd); + return PTR_ERR_OR_ZERO(info->tzd); } static int sun4i_gpadc_probe_mfd(struct platform_device *pdev, @@ -584,15 +586,15 @@ static int sun4i_gpadc_probe_mfd(struct platform_device *pdev, * of_node, and the device from this driver as third argument to * return the temperature. */ - struct thermal_zone_device *tzd; - tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0, - info, - &sun4i_ts_tz_ops); - if (IS_ERR(tzd)) { + info->sensor_device = pdev->dev.parent; + info->tzd = thermal_zone_of_sensor_register(info->sensor_device, + 0, info, + &sun4i_ts_tz_ops); + if (IS_ERR(info->tzd)) { dev_err(&pdev->dev, "could not register thermal sensor: %ld\n", - PTR_ERR(tzd)); - return PTR_ERR(tzd); + PTR_ERR(info->tzd)); + return PTR_ERR(info->tzd); } } else { indio_dev->num_channels = @@ -688,7 +690,13 @@ static int sun4i_gpadc_remove(struct platform_device *pdev) pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); - if (!info->no_irq && IS_ENABLED(CONFIG_THERMAL_OF)) + + if (!IS_ENABLED(CONFIG_THERMAL_OF)) + return 0; + + thermal_zone_of_sensor_unregister(info->sensor_device, info->tzd); + + if (!info->no_irq) iio_map_array_unregister(indio_dev); return 0; @@ -700,6 +708,7 @@ static const struct platform_device_id sun4i_gpadc_id[] = { { "sun6i-a31-gpadc-iio", (kernel_ulong_t)&sun6i_gpadc_data }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(platform, sun4i_gpadc_id); static struct platform_driver sun4i_gpadc_driver = { .driver = { @@ -711,6 +720,7 @@ static struct platform_driver sun4i_gpadc_driver = { .probe = sun4i_gpadc_probe, .remove = sun4i_gpadc_remove, }; +MODULE_DEVICE_TABLE(of, sun4i_gpadc_of_id); module_platform_driver(sun4i_gpadc_driver); diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 4282ceca3d8f..6cbed7eb118a 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -614,7 +614,7 @@ static int tiadc_probe(struct platform_device *pdev) return -EINVAL; } - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*indio_dev)); + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev)); if (indio_dev == NULL) { dev_err(&pdev->dev, "failed to allocate iio device\n"); return -ENOMEM; diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 978e1592c2a3..4061fed93f1f 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -451,7 +451,8 @@ static ssize_t iio_trigger_write_current(struct device *dev, return len; out_trigger_put: - iio_trigger_put(trig); + if (trig) + iio_trigger_put(trig); return ret; } diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index b30e0c1c6cc4..67838edd8b37 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -74,9 +74,9 @@ static const int int_time_mapping[] = {100000, 50000, 200000, 400000}; static const struct reg_field reg_field_it = REG_FIELD(LTR501_ALS_MEAS_RATE, 3, 4); static const struct reg_field reg_field_als_intr = - REG_FIELD(LTR501_INTR, 0, 0); -static const struct reg_field reg_field_ps_intr = REG_FIELD(LTR501_INTR, 1, 1); +static const struct reg_field reg_field_ps_intr = + REG_FIELD(LTR501_INTR, 0, 0); static const struct reg_field reg_field_als_rate = REG_FIELD(LTR501_ALS_MEAS_RATE, 0, 2); static const struct reg_field reg_field_ps_rate = diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index ddf9bee89f77..aa4df0dcc8c9 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -40,9 +40,9 @@ #define AS3935_AFE_PWR_BIT BIT(0) #define AS3935_INT 0x03 -#define AS3935_INT_MASK 0x07 +#define AS3935_INT_MASK 0x0f #define AS3935_EVENT_INT BIT(3) -#define AS3935_NOISE_INT BIT(1) +#define AS3935_NOISE_INT BIT(0) #define AS3935_DATA 0x07 #define AS3935_DATA_MASK 0x3F @@ -215,7 +215,7 @@ static irqreturn_t as3935_trigger_handler(int irq, void *private) st->buffer[0] = val & AS3935_DATA_MASK; iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer, - pf->timestamp); + iio_get_time_ns(indio_dev)); err_read: iio_trigger_notify_done(indio_dev->trig); @@ -244,7 +244,7 @@ static void as3935_event_work(struct work_struct *work) switch (val) { case AS3935_EVENT_INT: - iio_trigger_poll(st->trig); + iio_trigger_poll_chained(st->trig); break; case AS3935_NOISE_INT: dev_warn(&st->spi->dev, "noise level is too high\n"); @@ -269,8 +269,6 @@ static irqreturn_t as3935_interrupt_handler(int irq, void *private) static void calibrate_as3935(struct as3935_state *st) { - mutex_lock(&st->lock); - /* mask disturber interrupt bit */ as3935_write(st, AS3935_INT, BIT(5)); @@ -280,8 +278,6 @@ static void calibrate_as3935(struct as3935_state *st) mdelay(2); as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV)); - - mutex_unlock(&st->lock); } #ifdef CONFIG_PM_SLEEP @@ -318,6 +314,8 @@ static int as3935_resume(struct device *dev) val &= ~AS3935_AFE_PWR_BIT; ret = as3935_write(st, AS3935_AFE_GAIN, val); + calibrate_as3935(st); + err_resume: mutex_unlock(&st->lock); diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 131df9d3660f..16c30460ef04 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -176,6 +176,12 @@ static const char * const smbus_pnp_ids[] = { NULL }; +static const char * const forcepad_pnp_ids[] = { + "SYN300D", + "SYN3014", + NULL +}; + /* * Send a command to the synpatics touchpad by special commands */ @@ -397,6 +403,8 @@ static int synaptics_query_hardware(struct psmouse *psmouse, { int error; + memset(info, 0, sizeof(*info)); + error = synaptics_identify(psmouse, info); if (error) return error; @@ -480,13 +488,6 @@ static const struct min_max_quirk min_max_pnpid_table[] = { { } }; -/* This list has been kindly provided by Synaptics. */ -static const char * const forcepad_pnp_ids[] = { - "SYN300D", - "SYN3014", - NULL -}; - /***************************************************************************** * Synaptics communications functions ****************************************************************************/ @@ -1687,7 +1688,8 @@ enum { SYNAPTICS_INTERTOUCH_ON, }; -static int synaptics_intertouch = SYNAPTICS_INTERTOUCH_NOT_SET; +static int synaptics_intertouch = IS_ENABLED(CONFIG_RMI4_SMB) ? + SYNAPTICS_INTERTOUCH_NOT_SET : SYNAPTICS_INTERTOUCH_OFF; module_param_named(synaptics_intertouch, synaptics_intertouch, int, 0644); MODULE_PARM_DESC(synaptics_intertouch, "Use a secondary bus for the Synaptics device."); @@ -1737,8 +1739,16 @@ static int synaptics_setup_intertouch(struct psmouse *psmouse, if (synaptics_intertouch == SYNAPTICS_INTERTOUCH_NOT_SET) { if (!psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) && - !psmouse_matches_pnp_id(psmouse, smbus_pnp_ids)) + !psmouse_matches_pnp_id(psmouse, smbus_pnp_ids)) { + + if (!psmouse_matches_pnp_id(psmouse, forcepad_pnp_ids)) + psmouse_info(psmouse, + "Your touchpad (%s) says it can support a different bus. " + "If i2c-hid and hid-rmi are not used, you might want to try setting psmouse.synaptics_intertouch to 1 and report this to linux-input@vger.kernel.org.\n", + psmouse->ps2dev.serio->firmware_id); + return -ENXIO; + } } psmouse_info(psmouse, "Trying to set up SMBus access\n"); @@ -1810,6 +1820,15 @@ int synaptics_init(struct psmouse *psmouse) } if (SYN_CAP_INTERTOUCH(info.ext_cap_0c)) { + if ((!IS_ENABLED(CONFIG_RMI4_SMB) || + !IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS)) && + /* Forcepads need F21, which is not ready */ + !psmouse_matches_pnp_id(psmouse, forcepad_pnp_ids)) { + psmouse_warn(psmouse, + "The touchpad can support a better bus than the too old PS/2 protocol. " + "Make sure MOUSE_PS2_SYNAPTICS_SMBUS and RMI4_SMB are enabled to get a better touchpad experience.\n"); + } + error = synaptics_setup_intertouch(psmouse, &info, true); if (!error) return PSMOUSE_SYNAPTICS_SMBUS; diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c index 813dd68a5c82..0dbcf105f7db 100644 --- a/drivers/input/touchscreen/silead.c +++ b/drivers/input/touchscreen/silead.c @@ -526,6 +526,7 @@ static int __maybe_unused silead_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); + disable_irq(client->irq); silead_ts_set_power(client, SILEAD_POWER_OFF); return 0; } @@ -551,6 +552,8 @@ static int __maybe_unused silead_ts_resume(struct device *dev) return -ENODEV; } + enable_irq(client->irq); + return 0; } diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index d07dd5196ffc..8aa158a09180 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -2364,7 +2364,7 @@ static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_s id); return NULL; } else { - rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL); + rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_ATOMIC); if (!rs) return NULL; rs->state = CCPResetIdle; diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index 35910f945bfa..99e644cda4d1 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -581,7 +581,7 @@ static int atmel_ebi_probe(struct platform_device *pdev) return of_platform_populate(np, NULL, NULL, dev); } -static int atmel_ebi_resume(struct device *dev) +static __maybe_unused int atmel_ebi_resume(struct device *dev) { struct atmel_ebi *ebi = dev_get_drvdata(dev); struct atmel_ebi_dev *ebid; diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 6d1b4b707cc2..a80e17de906d 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -460,12 +460,12 @@ static int get_gpmc_timing_reg( if (l) time_ns_min = gpmc_clk_ticks_to_ns(l - 1, cs, cd) + 1; time_ns = gpmc_clk_ticks_to_ns(l, cs, cd); - pr_info("gpmc,%s = <%u> /* %u ns - %u ns; %i ticks%s*/\n", + pr_info("gpmc,%s = <%u>; /* %u ns - %u ns; %i ticks%s*/\n", name, time_ns, time_ns_min, time_ns, l, invalid ? "; invalid " : " "); } else { /* raw format */ - pr_info("gpmc,%s = <%u>%s\n", name, l, + pr_info("gpmc,%s = <%u>;%s\n", name, l, invalid ? " /* invalid */" : ""); } @@ -2083,8 +2083,11 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, } else { ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width); - if (ret < 0) + if (ret < 0) { + dev_err(&pdev->dev, "%s has no 'bank-width' property\n", + child->full_name); goto err; + } } /* Reserve wait pin if it is required and valid */ diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index d474378ed810..b1dd12729f19 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -202,7 +202,7 @@ static int nand_ooblayout_free_lp_hamming(struct mtd_info *mtd, int section, return 0; } -const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = { +static const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = { .ecc = nand_ooblayout_ecc_lp_hamming, .free = nand_ooblayout_free_lp_hamming, }; @@ -4361,7 +4361,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, /* Initialize the ->data_interface field. */ ret = nand_init_data_interface(chip); if (ret) - return ret; + goto err_nand_init; /* * Setup the data interface correctly on the chip and controller side. @@ -4373,7 +4373,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, */ ret = nand_setup_data_interface(chip); if (ret) - return ret; + goto err_nand_init; nand_maf_id = chip->id.data[0]; nand_dev_id = chip->id.data[1]; @@ -4404,6 +4404,12 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, mtd->size = i * chip->chipsize; return 0; + +err_nand_init: + /* Free manufacturer priv data. */ + nand_manufacturer_cleanup(chip); + + return ret; } EXPORT_SYMBOL(nand_scan_ident); @@ -4574,18 +4580,23 @@ int nand_scan_tail(struct mtd_info *mtd) /* New bad blocks should be marked in OOB, flash-based BBT, or both */ if (WARN_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) && - !(chip->bbt_options & NAND_BBT_USE_FLASH))) - return -EINVAL; + !(chip->bbt_options & NAND_BBT_USE_FLASH))) { + ret = -EINVAL; + goto err_ident; + } if (invalid_ecc_page_accessors(chip)) { pr_err("Invalid ECC page accessors setup\n"); - return -EINVAL; + ret = -EINVAL; + goto err_ident; } if (!(chip->options & NAND_OWN_BUFFERS)) { nbuf = kzalloc(sizeof(*nbuf), GFP_KERNEL); - if (!nbuf) - return -ENOMEM; + if (!nbuf) { + ret = -ENOMEM; + goto err_ident; + } nbuf->ecccalc = kmalloc(mtd->oobsize, GFP_KERNEL); if (!nbuf->ecccalc) { @@ -4608,8 +4619,10 @@ int nand_scan_tail(struct mtd_info *mtd) chip->buffers = nbuf; } else { - if (!chip->buffers) - return -ENOMEM; + if (!chip->buffers) { + ret = -ENOMEM; + goto err_ident; + } } /* Set the internal oob buffer location, just after the page data */ @@ -4842,7 +4855,11 @@ int nand_scan_tail(struct mtd_info *mtd) return 0; /* Build bad block table */ - return chip->scan_bbt(mtd); + ret = chip->scan_bbt(mtd); + if (ret) + goto err_free; + return 0; + err_free: if (nbuf) { kfree(nbuf->databuf); @@ -4850,6 +4867,13 @@ err_free: kfree(nbuf->ecccalc); kfree(nbuf); } + +err_ident: + /* Clean up nand_scan_ident(). */ + + /* Free manufacturer priv data. */ + nand_manufacturer_cleanup(chip); + return ret; } EXPORT_SYMBOL(nand_scan_tail); diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index 9d5ca0e540b5..92e2cf8e9ff9 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c @@ -6,7 +6,6 @@ * published by the Free Software Foundation. * */ -#include <linux/module.h> #include <linux/mtd/nand.h> #include <linux/sizes.h> diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c index 9cfc4035a420..1e0755997762 100644 --- a/drivers/mtd/nand/nand_samsung.c +++ b/drivers/mtd/nand/nand_samsung.c @@ -84,6 +84,9 @@ static void samsung_nand_decode_id(struct nand_chip *chip) case 7: chip->ecc_strength_ds = 60; break; + default: + WARN(1, "Could not decode ECC info"); + chip->ecc_step_ds = 0; } } } else { diff --git a/drivers/mtd/nand/tango_nand.c b/drivers/mtd/nand/tango_nand.c index 05b6e1065203..49b286c6c10f 100644 --- a/drivers/mtd/nand/tango_nand.c +++ b/drivers/mtd/nand/tango_nand.c @@ -55,10 +55,10 @@ * byte 1 for other packets in the page (PKT_N, for N > 0) * ERR_COUNT_PKT_N is the max error count over all but the first packet. */ -#define DECODE_OK_PKT_0(v) ((v) & BIT(7)) -#define DECODE_OK_PKT_N(v) ((v) & BIT(15)) #define ERR_COUNT_PKT_0(v) (((v) >> 0) & 0x3f) #define ERR_COUNT_PKT_N(v) (((v) >> 8) & 0x3f) +#define DECODE_FAIL_PKT_0(v) (((v) & BIT(7)) == 0) +#define DECODE_FAIL_PKT_N(v) (((v) & BIT(15)) == 0) /* Offsets relative to pbus_base */ #define PBUS_CS_CTRL 0x83c @@ -193,6 +193,8 @@ static int check_erased_page(struct nand_chip *chip, u8 *buf) chip->ecc.strength); if (res < 0) mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += res; bitflips = max(res, bitflips); buf += pkt_size; @@ -202,9 +204,11 @@ static int check_erased_page(struct nand_chip *chip, u8 *buf) return bitflips; } -static int decode_error_report(struct tango_nfc *nfc) +static int decode_error_report(struct nand_chip *chip) { u32 status, res; + struct mtd_info *mtd = nand_to_mtd(chip); + struct tango_nfc *nfc = to_tango_nfc(chip->controller); status = readl_relaxed(nfc->reg_base + NFC_XFER_STATUS); if (status & PAGE_IS_EMPTY) @@ -212,10 +216,14 @@ static int decode_error_report(struct tango_nfc *nfc) res = readl_relaxed(nfc->mem_base + ERROR_REPORT); - if (DECODE_OK_PKT_0(res) && DECODE_OK_PKT_N(res)) - return max(ERR_COUNT_PKT_0(res), ERR_COUNT_PKT_N(res)); + if (DECODE_FAIL_PKT_0(res) || DECODE_FAIL_PKT_N(res)) + return -EBADMSG; + + /* ERR_COUNT_PKT_N is max, not sum, but that's all we have */ + mtd->ecc_stats.corrected += + ERR_COUNT_PKT_0(res) + ERR_COUNT_PKT_N(res); - return -EBADMSG; + return max(ERR_COUNT_PKT_0(res), ERR_COUNT_PKT_N(res)); } static void tango_dma_callback(void *arg) @@ -282,7 +290,7 @@ static int tango_read_page(struct mtd_info *mtd, struct nand_chip *chip, if (err) return err; - res = decode_error_report(nfc); + res = decode_error_report(chip); if (res < 0) { chip->ecc.read_oob_raw(mtd, chip, page); res = check_erased_page(chip, buf); @@ -663,6 +671,7 @@ static const struct of_device_id tango_nand_ids[] = { { .compatible = "sigma,smp8758-nand" }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, tango_nand_ids); static struct platform_driver tango_nand_driver = { .probe = tango_nand_probe, diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h index 96046bb12ca1..14c0be98e0a4 100644 --- a/drivers/net/dsa/mv88e6xxx/global2.h +++ b/drivers/net/dsa/mv88e6xxx/global2.h @@ -114,13 +114,13 @@ static inline int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip, return -EOPNOTSUPP; } -int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev, - int src_port, u16 data) +static inline int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, + int src_dev, int src_port, u16 data) { return -EOPNOTSUPP; } -int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip) +static inline int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip) { return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 38a5c6764bb5..b512149684fd 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2771,6 +2771,9 @@ void t4_fatal_err(struct adapter *adap) { int port; + if (pci_channel_offline(adap->pdev)) + return; + /* Disable the SGE since ULDs are going to free resources that * could be exposed to the adapter. RDMA MWs for example... */ @@ -3882,9 +3885,10 @@ static pci_ers_result_t eeh_err_detected(struct pci_dev *pdev, spin_lock(&adap->stats_lock); for_each_port(adap, i) { struct net_device *dev = adap->port[i]; - - netif_device_detach(dev); - netif_carrier_off(dev); + if (dev) { + netif_device_detach(dev); + netif_carrier_off(dev); + } } spin_unlock(&adap->stats_lock); disable_interrupts(adap); @@ -3963,12 +3967,13 @@ static void eeh_resume(struct pci_dev *pdev) rtnl_lock(); for_each_port(adap, i) { struct net_device *dev = adap->port[i]; - - if (netif_running(dev)) { - link_start(dev); - cxgb_set_rxmode(dev); + if (dev) { + if (netif_running(dev)) { + link_start(dev); + cxgb_set_rxmode(dev); + } + netif_device_attach(dev); } - netif_device_attach(dev); } rtnl_unlock(); } diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index aded42b96f6d..3a34aa629f7d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -4557,8 +4557,13 @@ void t4_intr_enable(struct adapter *adapter) */ void t4_intr_disable(struct adapter *adapter) { - u32 whoami = t4_read_reg(adapter, PL_WHOAMI_A); - u32 pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ? + u32 whoami, pf; + + if (pci_channel_offline(adapter->pdev)) + return; + + whoami = t4_read_reg(adapter, PL_WHOAMI_A); + pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ? SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami); t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE_A), 0); diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c index 446c7b374ff5..a10de1e9c157 100644 --- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c @@ -381,7 +381,7 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev) { const struct of_device_id *id = of_match_device(fsl_pq_mdio_match, &pdev->dev); - const struct fsl_pq_mdio_data *data = id->data; + const struct fsl_pq_mdio_data *data; struct device_node *np = pdev->dev.of_node; struct resource res; struct device_node *tbi; @@ -389,6 +389,13 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev) struct mii_bus *new_bus; int err; + if (!id) { + dev_err(&pdev->dev, "Failed to match device\n"); + return -ENODEV; + } + + data = id->data; + dev_dbg(&pdev->dev, "found %s compatible node\n", id->compatible); new_bus = mdiobus_alloc_size(sizeof(*priv)); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index fe5546bb4153..af945edfee19 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -621,10 +621,9 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node), priv->irq_info[i].mask); -#ifdef CONFIG_SMP - if (irq_set_affinity_hint(irq, priv->irq_info[i].mask)) + if (IS_ENABLED(CONFIG_SMP) && + irq_set_affinity_hint(irq, priv->irq_info[i].mask)) mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq); -#endif return 0; } diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 537d1236a4fe..715b3aaf83ac 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -1730,7 +1730,8 @@ void qed_get_protocol_stats(struct qed_dev *cdev, qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats); break; default: - DP_ERR(cdev, "Invalid protocol type = %d\n", type); + DP_VERBOSE(cdev, QED_MSG_SP, + "Invalid protocol type = %d\n", type); return; } } diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index 8c3633c1d078..97e3bc60c3e7 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -576,6 +576,8 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case HDLCDRVCTL_CALIBRATE: if(!capable(CAP_SYS_RAWIO)) return -EPERM; + if (s->par.bitrate <= 0) + return -EINVAL; if (bi.data.calibrate > INT_MAX / s->par.bitrate) return -EINVAL; s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16; diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 9097e42bec2e..57297ba23987 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -1127,8 +1127,6 @@ static int marvell_read_status_page(struct phy_device *phydev, int page) if (adv < 0) return adv; - lpa &= adv; - if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) phydev->duplex = DUPLEX_FULL; else diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 8e73f5f36e71..f99c21f78b63 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -658,6 +658,18 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv) return 0; } +static int mdio_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + int rc; + + /* Some devices have extra OF data and an OF-style MODALIAS */ + rc = of_device_uevent_modalias(dev, env); + if (rc != -ENODEV) + return rc; + + return 0; +} + #ifdef CONFIG_PM static int mdio_bus_suspend(struct device *dev) { @@ -708,6 +720,7 @@ static const struct dev_pm_ops mdio_bus_pm_ops = { struct bus_type mdio_bus_type = { .name = "mdio_bus", .match = mdio_bus_match, + .uevent = mdio_uevent, .pm = MDIO_BUS_PM_OPS, }; EXPORT_SYMBOL(mdio_bus_type); diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c index 77a48a5164ff..df431e8a0631 100644 --- a/drivers/nubus/nubus.c +++ b/drivers/nubus/nubus.c @@ -13,7 +13,6 @@ #include <linux/nubus.h> #include <linux/errno.h> #include <linux/init.h> -#include <linux/delay.h> #include <linux/module.h> #include <linux/slab.h> #include <asm/setup.h> @@ -34,14 +33,6 @@ extern void oss_nubus_init(void); #define NUBUS_TEST_PATTERN 0x5A932BC7 -/* Define this if you like to live dangerously - it is known not to - work on pretty much every machine except the Quadra 630 and the LC - III. */ -#undef I_WANT_TO_PROBE_SLOT_ZERO - -/* This sometimes helps combat failure to boot */ -#undef TRY_TO_DODGE_WSOD - /* Globals */ struct nubus_dev *nubus_devices; @@ -101,9 +92,6 @@ static void nubus_rewind(unsigned char **ptr, int len, int map) { unsigned char *p = *ptr; - /* Sanity check */ - if (len > 65536) - pr_err("rewind of 0x%08x!\n", len); while (len) { do { p--; @@ -117,8 +105,6 @@ static void nubus_advance(unsigned char **ptr, int len, int map) { unsigned char *p = *ptr; - if (len > 65536) - pr_err("advance of 0x%08x!\n", len); while (len) { while (not_useful(p, map)) p++; @@ -130,10 +116,15 @@ static void nubus_advance(unsigned char **ptr, int len, int map) static void nubus_move(unsigned char **ptr, int len, int map) { + unsigned long slot_space = (unsigned long)*ptr & 0xFF000000; + if (len > 0) nubus_advance(ptr, len, map); else if (len < 0) nubus_rewind(ptr, -len, map); + + if (((unsigned long)*ptr & 0xFF000000) != slot_space) + pr_err("%s: moved out of slot address space!\n", __func__); } /* Now, functions to read the sResource tree */ @@ -454,10 +445,6 @@ nubus_get_functional_resource(struct nubus_board *board, int slot, pr_info(" Function 0x%02x:\n", parent->type); nubus_get_subdir(parent, &dir); - /* Apple seems to have botched the ROM on the IIx */ - if (slot == 0 && (unsigned long)dir.base % 2) - dir.base += 1; - pr_debug("%s: parent is 0x%p, dir is 0x%p\n", __func__, parent->base, dir.base); @@ -691,83 +678,6 @@ static int __init nubus_get_board_resource(struct nubus_board *board, int slot, return 0; } -/* Attempt to bypass the somewhat non-obvious arrangement of - sResources in the motherboard ROM */ -static void __init nubus_find_rom_dir(struct nubus_board* board) -{ - unsigned char *rp; - unsigned char *romdir; - struct nubus_dir dir; - struct nubus_dirent ent; - - /* Check for the extra directory just under the format block */ - rp = board->fblock; - nubus_rewind(&rp, 4, board->lanes); - if (nubus_get_rom(&rp, 4, board->lanes) != NUBUS_TEST_PATTERN) { - /* OK, the ROM was telling the truth */ - board->directory = board->fblock; - nubus_move(&board->directory, - nubus_expand32(board->doffset), - board->lanes); - return; - } - - /* On "slot zero", you have to walk down a few more - directories to get to the equivalent of a real card's root - directory. We don't know what they were smoking when they - came up with this. */ - romdir = nubus_rom_addr(board->slot); - nubus_rewind(&romdir, ROM_DIR_OFFSET, board->lanes); - dir.base = dir.ptr = romdir; - dir.done = 0; - dir.mask = board->lanes; - - /* This one points to an "Unknown Macintosh" directory */ - if (nubus_readdir(&dir, &ent) == -1) - goto badrom; - - if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG) - printk(KERN_INFO "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data); - /* This one takes us to where we want to go. */ - if (nubus_readdir(&dir, &ent) == -1) - goto badrom; - if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG) - printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data); - nubus_get_subdir(&ent, &dir); - - /* Resource ID 01, also an "Unknown Macintosh" */ - if (nubus_readdir(&dir, &ent) == -1) - goto badrom; - if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG) - printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data); - - /* FIXME: the first one is *not* always the right one. We - suspect this has something to do with the ROM revision. - "The HORROR ROM" (LC-series) uses 0x7e, while "The HORROR - Continues" (Q630) uses 0x7b. The DAFB Macs evidently use - something else. Please run "Slots" on your Mac (see - include/linux/nubus.h for where to get this program) and - tell us where the 'SiDirPtr' for Slot 0 is. If you feel - brave, you should also use MacsBug to walk down the ROM - directories like this function does and try to find the - path to that address... */ - if (nubus_readdir(&dir, &ent) == -1) - goto badrom; - if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG) - printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data); - - /* Bwahahahaha... */ - nubus_get_subdir(&ent, &dir); - board->directory = dir.base; - return; - - /* Even more evil laughter... */ - badrom: - board->directory = board->fblock; - nubus_move(&board->directory, nubus_expand32(board->doffset), board->lanes); - printk(KERN_ERR "nubus_get_rom_dir: ROM weirdness! Notify the developers...\n"); -} - /* Add a board (might be many devices) to the list */ static struct nubus_board * __init nubus_add_board(int slot, int bytelanes) { @@ -828,8 +738,11 @@ static struct nubus_board * __init nubus_add_board(int slot, int bytelanes) * since the initial Macintosh ROM releases skipped the check. */ - /* Attempt to work around slot zero weirdness */ - nubus_find_rom_dir(board); + /* Set up the directory pointer */ + board->directory = board->fblock; + nubus_move(&board->directory, nubus_expand32(board->doffset), + board->lanes); + nubus_get_root_dir(board, &dir); /* We're ready to rock */ @@ -849,9 +762,6 @@ static struct nubus_board * __init nubus_add_board(int slot, int bytelanes) nubus_get_board_resource(board, slot, &ent); } - /* Aaaarrrrgghh! The LC III motherboard has *two* board - resources. I have no idea WTF to do about this. */ - while (nubus_readdir(&dir, &ent) != -1) { struct nubus_dev *dev; struct nubus_dev **devp; @@ -898,8 +808,6 @@ void __init nubus_probe_slot(int slot) continue; dp = *rp; - if(dp == 0) - continue; /* The last byte of the format block consists of two nybbles which are "mirror images" of each other. @@ -908,7 +816,7 @@ void __init nubus_probe_slot(int slot) continue; /* Check that this value is actually *on* one of the bytelanes it claims are valid! */ - if ((dp & 0x0F) >= (1 << i)) + if (not_useful(rp, dp)) continue; /* Looks promising. Let's put it on the list. */ @@ -922,10 +830,6 @@ void __init nubus_scan_bus(void) { int slot; - /* This might not work on your machine */ -#ifdef I_WANT_TO_PROBE_SLOT_ZERO - nubus_probe_slot(0); -#endif for (slot = 9; slot < 15; slot++) { nubus_probe_slot(slot); } @@ -943,13 +847,6 @@ static int __init nubus_init(void) via_nubus_init(); } -#ifdef TRY_TO_DODGE_WSOD - /* Rogue Ethernet interrupts can kill the machine if we don't - do this. Obviously this is bogus. Hopefully the local VIA - gurus can fix the real cause of the problem. */ - mdelay(1000); -#endif - /* And probe */ pr_info("NuBus: Scanning NuBus slots.\n"); nubus_devices = NULL; diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 74cf5fffb1e1..c80e37a69305 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -896,7 +896,7 @@ int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val) { if (pci_dev_is_disconnected(dev)) { *val = ~0; - return -ENODEV; + return PCIBIOS_DEVICE_NOT_FOUND; } return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val); } @@ -906,7 +906,7 @@ int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val) { if (pci_dev_is_disconnected(dev)) { *val = ~0; - return -ENODEV; + return PCIBIOS_DEVICE_NOT_FOUND; } return pci_bus_read_config_word(dev->bus, dev->devfn, where, val); } @@ -917,7 +917,7 @@ int pci_read_config_dword(const struct pci_dev *dev, int where, { if (pci_dev_is_disconnected(dev)) { *val = ~0; - return -ENODEV; + return PCIBIOS_DEVICE_NOT_FOUND; } return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val); } @@ -926,7 +926,7 @@ EXPORT_SYMBOL(pci_read_config_dword); int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val) { if (pci_dev_is_disconnected(dev)) - return -ENODEV; + return PCIBIOS_DEVICE_NOT_FOUND; return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val); } EXPORT_SYMBOL(pci_write_config_byte); @@ -934,7 +934,7 @@ EXPORT_SYMBOL(pci_write_config_byte); int pci_write_config_word(const struct pci_dev *dev, int where, u16 val) { if (pci_dev_is_disconnected(dev)) - return -ENODEV; + return PCIBIOS_DEVICE_NOT_FOUND; return pci_bus_write_config_word(dev->bus, dev->devfn, where, val); } EXPORT_SYMBOL(pci_write_config_word); @@ -943,7 +943,7 @@ int pci_write_config_dword(const struct pci_dev *dev, int where, u32 val) { if (pci_dev_is_disconnected(dev)) - return -ENODEV; + return PCIBIOS_DEVICE_NOT_FOUND; return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val); } EXPORT_SYMBOL(pci_write_config_dword); diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig index b7e15526d676..d34b6dfbb351 100644 --- a/drivers/pci/dwc/Kconfig +++ b/drivers/pci/dwc/Kconfig @@ -16,6 +16,7 @@ config PCIE_DW_EP config PCI_DRA7XX bool "TI DRA7xx PCIe controller" + depends on SOC_DRA7XX || COMPILE_TEST depends on (PCI && PCI_MSI_IRQ_DOMAIN) || PCI_ENDPOINT depends on OF && HAS_IOMEM && TI_PIPE3 help diff --git a/drivers/pci/dwc/pcie-qcom.c b/drivers/pci/dwc/pcie-qcom.c index 5bf23d432fdb..289cda1b4897 100644 --- a/drivers/pci/dwc/pcie-qcom.c +++ b/drivers/pci/dwc/pcie-qcom.c @@ -86,10 +86,29 @@ struct qcom_pcie_resources_v2 { struct clk *pipe_clk; }; +struct qcom_pcie_resources_v3 { + struct clk *aux_clk; + struct clk *master_clk; + struct clk *slave_clk; + struct reset_control *axi_m_reset; + struct reset_control *axi_s_reset; + struct reset_control *pipe_reset; + struct reset_control *axi_m_vmid_reset; + struct reset_control *axi_s_xpu_reset; + struct reset_control *parf_reset; + struct reset_control *phy_reset; + struct reset_control *axi_m_sticky_reset; + struct reset_control *pipe_sticky_reset; + struct reset_control *pwr_reset; + struct reset_control *ahb_reset; + struct reset_control *phy_ahb_reset; +}; + union qcom_pcie_resources { struct qcom_pcie_resources_v0 v0; struct qcom_pcie_resources_v1 v1; struct qcom_pcie_resources_v2 v2; + struct qcom_pcie_resources_v3 v3; }; struct qcom_pcie; @@ -133,26 +152,6 @@ static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg) return dw_handle_msi_irq(pp); } -static void qcom_pcie_v0_v1_ltssm_enable(struct qcom_pcie *pcie) -{ - u32 val; - - /* enable link training */ - val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL); - val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE; - writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL); -} - -static void qcom_pcie_v2_ltssm_enable(struct qcom_pcie *pcie) -{ - u32 val; - - /* enable link training */ - val = readl(pcie->parf + PCIE20_PARF_LTSSM); - val |= BIT(8); - writel(val, pcie->parf + PCIE20_PARF_LTSSM); -} - static int qcom_pcie_establish_link(struct qcom_pcie *pcie) { struct dw_pcie *pci = pcie->pci; @@ -167,6 +166,16 @@ static int qcom_pcie_establish_link(struct qcom_pcie *pcie) return dw_pcie_wait_for_link(pci); } +static void qcom_pcie_v0_v1_ltssm_enable(struct qcom_pcie *pcie) +{ + u32 val; + + /* enable link training */ + val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL); + val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE; + writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL); +} + static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie) { struct qcom_pcie_resources_v0 *res = &pcie->res.v0; @@ -217,36 +226,6 @@ static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie) return PTR_ERR_OR_ZERO(res->phy_reset); } -static int qcom_pcie_get_resources_v1(struct qcom_pcie *pcie) -{ - struct qcom_pcie_resources_v1 *res = &pcie->res.v1; - struct dw_pcie *pci = pcie->pci; - struct device *dev = pci->dev; - - res->vdda = devm_regulator_get(dev, "vdda"); - if (IS_ERR(res->vdda)) - return PTR_ERR(res->vdda); - - res->iface = devm_clk_get(dev, "iface"); - if (IS_ERR(res->iface)) - return PTR_ERR(res->iface); - - res->aux = devm_clk_get(dev, "aux"); - if (IS_ERR(res->aux)) - return PTR_ERR(res->aux); - - res->master_bus = devm_clk_get(dev, "master_bus"); - if (IS_ERR(res->master_bus)) - return PTR_ERR(res->master_bus); - - res->slave_bus = devm_clk_get(dev, "slave_bus"); - if (IS_ERR(res->slave_bus)) - return PTR_ERR(res->slave_bus); - - res->core = devm_reset_control_get(dev, "core"); - return PTR_ERR_OR_ZERO(res->core); -} - static void qcom_pcie_deinit_v0(struct qcom_pcie *pcie) { struct qcom_pcie_resources_v0 *res = &pcie->res.v0; @@ -375,6 +354,36 @@ err_refclk: return ret; } +static int qcom_pcie_get_resources_v1(struct qcom_pcie *pcie) +{ + struct qcom_pcie_resources_v1 *res = &pcie->res.v1; + struct dw_pcie *pci = pcie->pci; + struct device *dev = pci->dev; + + res->vdda = devm_regulator_get(dev, "vdda"); + if (IS_ERR(res->vdda)) + return PTR_ERR(res->vdda); + + res->iface = devm_clk_get(dev, "iface"); + if (IS_ERR(res->iface)) + return PTR_ERR(res->iface); + + res->aux = devm_clk_get(dev, "aux"); + if (IS_ERR(res->aux)) + return PTR_ERR(res->aux); + + res->master_bus = devm_clk_get(dev, "master_bus"); + if (IS_ERR(res->master_bus)) + return PTR_ERR(res->master_bus); + + res->slave_bus = devm_clk_get(dev, "slave_bus"); + if (IS_ERR(res->slave_bus)) + return PTR_ERR(res->slave_bus); + + res->core = devm_reset_control_get(dev, "core"); + return PTR_ERR_OR_ZERO(res->core); +} + static void qcom_pcie_deinit_v1(struct qcom_pcie *pcie) { struct qcom_pcie_resources_v1 *res = &pcie->res.v1; @@ -455,6 +464,16 @@ err_res: return ret; } +static void qcom_pcie_v2_ltssm_enable(struct qcom_pcie *pcie) +{ + u32 val; + + /* enable link training */ + val = readl(pcie->parf + PCIE20_PARF_LTSSM); + val |= BIT(8); + writel(val, pcie->parf + PCIE20_PARF_LTSSM); +} + static int qcom_pcie_get_resources_v2(struct qcom_pcie *pcie) { struct qcom_pcie_resources_v2 *res = &pcie->res.v2; @@ -481,6 +500,17 @@ static int qcom_pcie_get_resources_v2(struct qcom_pcie *pcie) return PTR_ERR_OR_ZERO(res->pipe_clk); } +static void qcom_pcie_deinit_v2(struct qcom_pcie *pcie) +{ + struct qcom_pcie_resources_v2 *res = &pcie->res.v2; + + clk_disable_unprepare(res->pipe_clk); + clk_disable_unprepare(res->slave_clk); + clk_disable_unprepare(res->master_clk); + clk_disable_unprepare(res->cfg_clk); + clk_disable_unprepare(res->aux_clk); +} + static int qcom_pcie_init_v2(struct qcom_pcie *pcie) { struct qcom_pcie_resources_v2 *res = &pcie->res.v2; @@ -562,22 +592,290 @@ static int qcom_pcie_post_init_v2(struct qcom_pcie *pcie) return 0; } -static int qcom_pcie_link_up(struct dw_pcie *pci) +static int qcom_pcie_get_resources_v3(struct qcom_pcie *pcie) { - u16 val = readw(pci->dbi_base + PCIE20_CAP + PCI_EXP_LNKSTA); + struct qcom_pcie_resources_v3 *res = &pcie->res.v3; + struct dw_pcie *pci = pcie->pci; + struct device *dev = pci->dev; - return !!(val & PCI_EXP_LNKSTA_DLLLA); + res->aux_clk = devm_clk_get(dev, "aux"); + if (IS_ERR(res->aux_clk)) + return PTR_ERR(res->aux_clk); + + res->master_clk = devm_clk_get(dev, "master_bus"); + if (IS_ERR(res->master_clk)) + return PTR_ERR(res->master_clk); + + res->slave_clk = devm_clk_get(dev, "slave_bus"); + if (IS_ERR(res->slave_clk)) + return PTR_ERR(res->slave_clk); + + res->axi_m_reset = devm_reset_control_get(dev, "axi_m"); + if (IS_ERR(res->axi_m_reset)) + return PTR_ERR(res->axi_m_reset); + + res->axi_s_reset = devm_reset_control_get(dev, "axi_s"); + if (IS_ERR(res->axi_s_reset)) + return PTR_ERR(res->axi_s_reset); + + res->pipe_reset = devm_reset_control_get(dev, "pipe"); + if (IS_ERR(res->pipe_reset)) + return PTR_ERR(res->pipe_reset); + + res->axi_m_vmid_reset = devm_reset_control_get(dev, "axi_m_vmid"); + if (IS_ERR(res->axi_m_vmid_reset)) + return PTR_ERR(res->axi_m_vmid_reset); + + res->axi_s_xpu_reset = devm_reset_control_get(dev, "axi_s_xpu"); + if (IS_ERR(res->axi_s_xpu_reset)) + return PTR_ERR(res->axi_s_xpu_reset); + + res->parf_reset = devm_reset_control_get(dev, "parf"); + if (IS_ERR(res->parf_reset)) + return PTR_ERR(res->parf_reset); + + res->phy_reset = devm_reset_control_get(dev, "phy"); + if (IS_ERR(res->phy_reset)) + return PTR_ERR(res->phy_reset); + + res->axi_m_sticky_reset = devm_reset_control_get(dev, "axi_m_sticky"); + if (IS_ERR(res->axi_m_sticky_reset)) + return PTR_ERR(res->axi_m_sticky_reset); + + res->pipe_sticky_reset = devm_reset_control_get(dev, "pipe_sticky"); + if (IS_ERR(res->pipe_sticky_reset)) + return PTR_ERR(res->pipe_sticky_reset); + + res->pwr_reset = devm_reset_control_get(dev, "pwr"); + if (IS_ERR(res->pwr_reset)) + return PTR_ERR(res->pwr_reset); + + res->ahb_reset = devm_reset_control_get(dev, "ahb"); + if (IS_ERR(res->ahb_reset)) + return PTR_ERR(res->ahb_reset); + + res->phy_ahb_reset = devm_reset_control_get(dev, "phy_ahb"); + if (IS_ERR(res->phy_ahb_reset)) + return PTR_ERR(res->phy_ahb_reset); + + return 0; } -static void qcom_pcie_deinit_v2(struct qcom_pcie *pcie) +static void qcom_pcie_deinit_v3(struct qcom_pcie *pcie) { - struct qcom_pcie_resources_v2 *res = &pcie->res.v2; - - clk_disable_unprepare(res->pipe_clk); + struct qcom_pcie_resources_v3 *res = &pcie->res.v3; + + reset_control_assert(res->axi_m_reset); + reset_control_assert(res->axi_s_reset); + reset_control_assert(res->pipe_reset); + reset_control_assert(res->pipe_sticky_reset); + reset_control_assert(res->phy_reset); + reset_control_assert(res->phy_ahb_reset); + reset_control_assert(res->axi_m_sticky_reset); + reset_control_assert(res->pwr_reset); + reset_control_assert(res->ahb_reset); + clk_disable_unprepare(res->aux_clk); + clk_disable_unprepare(res->master_clk); clk_disable_unprepare(res->slave_clk); +} + +static int qcom_pcie_init_v3(struct qcom_pcie *pcie) +{ + struct qcom_pcie_resources_v3 *res = &pcie->res.v3; + struct dw_pcie *pci = pcie->pci; + struct device *dev = pci->dev; + u32 val; + int ret; + + ret = reset_control_assert(res->axi_m_reset); + if (ret) { + dev_err(dev, "cannot assert axi master reset\n"); + return ret; + } + + ret = reset_control_assert(res->axi_s_reset); + if (ret) { + dev_err(dev, "cannot asser axi slave reset\n"); + return ret; + } + + usleep_range(10000, 12000); + + ret = reset_control_assert(res->pipe_reset); + if (ret) { + dev_err(dev, "cannot assert pipe reset\n"); + return ret; + } + + ret = reset_control_assert(res->pipe_sticky_reset); + if (ret) { + dev_err(dev, "cannot assert pipe sticky reset\n"); + return ret; + } + + ret = reset_control_assert(res->phy_reset); + if (ret) { + dev_err(dev, "cannot assert phy reset\n"); + return ret; + } + + ret = reset_control_assert(res->phy_ahb_reset); + if (ret) { + dev_err(dev, "cannot assert phy ahb reset\n"); + return ret; + } + + usleep_range(10000, 12000); + + ret = reset_control_assert(res->axi_m_sticky_reset); + if (ret) { + dev_err(dev, "cannot assert axi master sticky reset\n"); + return ret; + } + + ret = reset_control_assert(res->pwr_reset); + if (ret) { + dev_err(dev, "cannot assert power reset\n"); + return ret; + } + + ret = reset_control_assert(res->ahb_reset); + if (ret) { + dev_err(dev, "cannot assert ahb reset\n"); + return ret; + } + + usleep_range(10000, 12000); + + ret = reset_control_deassert(res->phy_ahb_reset); + if (ret) { + dev_err(dev, "cannot deassert phy ahb reset\n"); + return ret; + } + + ret = reset_control_deassert(res->phy_reset); + if (ret) { + dev_err(dev, "cannot deassert phy reset\n"); + goto err_rst_phy; + } + + ret = reset_control_deassert(res->pipe_reset); + if (ret) { + dev_err(dev, "cannot deassert pipe reset\n"); + goto err_rst_pipe; + } + + ret = reset_control_deassert(res->pipe_sticky_reset); + if (ret) { + dev_err(dev, "cannot deassert pipe sticky reset\n"); + goto err_rst_pipe_sticky; + } + + usleep_range(10000, 12000); + + ret = reset_control_deassert(res->axi_m_reset); + if (ret) { + dev_err(dev, "cannot deassert axi master reset\n"); + goto err_rst_axi_m; + } + + ret = reset_control_deassert(res->axi_m_sticky_reset); + if (ret) { + dev_err(dev, "cannot deassert axi master sticky reset\n"); + goto err_rst_axi_m_sticky; + } + + ret = reset_control_deassert(res->axi_s_reset); + if (ret) { + dev_err(dev, "cannot deassert axi slave reset\n"); + goto err_rst_axi_s; + } + + ret = reset_control_deassert(res->pwr_reset); + if (ret) { + dev_err(dev, "cannot deassert power reset\n"); + goto err_rst_pwr; + } + + ret = reset_control_deassert(res->ahb_reset); + if (ret) { + dev_err(dev, "cannot deassert ahb reset\n"); + goto err_rst_ahb; + } + + usleep_range(10000, 12000); + + ret = clk_prepare_enable(res->aux_clk); + if (ret) { + dev_err(dev, "cannot prepare/enable iface clock\n"); + goto err_clk_aux; + } + + ret = clk_prepare_enable(res->master_clk); + if (ret) { + dev_err(dev, "cannot prepare/enable core clock\n"); + goto err_clk_axi_m; + } + + ret = clk_prepare_enable(res->slave_clk); + if (ret) { + dev_err(dev, "cannot prepare/enable phy clock\n"); + goto err_clk_axi_s; + } + + /* enable PCIe clocks and resets */ + val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); + val &= !BIT(0); + writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); + + /* change DBI base address */ + writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR); + + /* MAC PHY_POWERDOWN MUX DISABLE */ + val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL); + val &= ~BIT(29); + writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL); + + val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL); + val |= BIT(4); + writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL); + + val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2); + val |= BIT(31); + writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2); + + return 0; + +err_clk_axi_s: clk_disable_unprepare(res->master_clk); - clk_disable_unprepare(res->cfg_clk); +err_clk_axi_m: clk_disable_unprepare(res->aux_clk); +err_clk_aux: + reset_control_assert(res->ahb_reset); +err_rst_ahb: + reset_control_assert(res->pwr_reset); +err_rst_pwr: + reset_control_assert(res->axi_s_reset); +err_rst_axi_s: + reset_control_assert(res->axi_m_sticky_reset); +err_rst_axi_m_sticky: + reset_control_assert(res->axi_m_reset); +err_rst_axi_m: + reset_control_assert(res->pipe_sticky_reset); +err_rst_pipe_sticky: + reset_control_assert(res->pipe_reset); +err_rst_pipe: + reset_control_assert(res->phy_reset); +err_rst_phy: + reset_control_assert(res->phy_ahb_reset); + return ret; +} + +static int qcom_pcie_link_up(struct dw_pcie *pci) +{ + u16 val = readw(pci->dbi_base + PCIE20_CAP + PCI_EXP_LNKSTA); + + return !!(val & PCI_EXP_LNKSTA_DLLLA); } static void qcom_pcie_host_init(struct pcie_port *pp) @@ -665,6 +963,13 @@ static const struct dw_pcie_ops dw_pcie_ops = { .link_up = qcom_pcie_link_up, }; +static const struct qcom_pcie_ops ops_v3 = { + .get_resources = qcom_pcie_get_resources_v3, + .init = qcom_pcie_init_v3, + .deinit = qcom_pcie_deinit_v3, + .ltssm_enable = qcom_pcie_v2_ltssm_enable, +}; + static int qcom_pcie_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -754,6 +1059,7 @@ static const struct of_device_id qcom_pcie_match[] = { { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 }, { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 }, { .compatible = "qcom,pcie-msm8996", .data = &ops_v2 }, + { .compatible = "qcom,pcie-ipq4019", .data = &ops_v3 }, { } }; diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 7f47cd5e10a5..0cd5b30dccb1 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -180,6 +180,17 @@ config PCIE_ROCKCHIP There is 1 internal PCIe port available to support GEN2 with 4 slots. +config PCIE_MEDIATEK + bool "MediaTek PCIe controller" + depends on ARM && (ARCH_MEDIATEK || COMPILE_TEST) + depends on OF + depends on PCI + select PCIEPORTBUS + help + Say Y here if you want to enable PCIe controller support on + MT7623 series SoCs. There is one single root complex with 3 root + ports available. Each port supports Gen2 lane x1. + config VMD depends on PCI_MSI && X86_64 && SRCU tristate "Intel Volume Management Device Driver" diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index cab879578003..b10d104c85fd 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o +obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o obj-$(CONFIG_VMD) += vmd.o # The following drivers are for devices that use the generic ACPI diff --git a/drivers/pci/host/pci-ftpci100.c b/drivers/pci/host/pci-ftpci100.c index d26501c4145a..ebab33e99a0d 100644 --- a/drivers/pci/host/pci-ftpci100.c +++ b/drivers/pci/host/pci-ftpci100.c @@ -25,6 +25,7 @@ #include <linux/irqchip/chained_irq.h> #include <linux/bitops.h> #include <linux/irq.h> +#include <linux/clk.h> /* * Special configuration registers directly in the first few words @@ -37,6 +38,7 @@ #define PCI_CONFIG 0x28 /* PCI configuration command register */ #define PCI_DATA 0x2C +#define FARADAY_PCI_STATUS_CMD 0x04 /* Status and command */ #define FARADAY_PCI_PMC 0x40 /* Power management control */ #define FARADAY_PCI_PMCSR 0x44 /* Power management status */ #define FARADAY_PCI_CTRL1 0x48 /* Control register 1 */ @@ -45,6 +47,8 @@ #define FARADAY_PCI_MEM2_BASE_SIZE 0x54 /* Memory base and size #2 */ #define FARADAY_PCI_MEM3_BASE_SIZE 0x58 /* Memory base and size #3 */ +#define PCI_STATUS_66MHZ_CAPABLE BIT(21) + /* Bits 31..28 gives INTD..INTA status */ #define PCI_CTRL2_INTSTS_SHIFT 28 #define PCI_CTRL2_INTMASK_CMDERR BIT(27) @@ -117,6 +121,7 @@ struct faraday_pci { void __iomem *base; struct irq_domain *irqdomain; struct pci_bus *bus; + struct clk *bus_clk; }; static int faraday_res_to_memcfg(resource_size_t mem_base, @@ -428,6 +433,7 @@ static int faraday_pci_probe(struct platform_device *pdev) struct resource *mem; struct resource *io; struct pci_host_bridge *host; + struct clk *clk; int ret; u32 val; LIST_HEAD(res); @@ -444,6 +450,28 @@ static int faraday_pci_probe(struct platform_device *pdev) host->sysdata = p; p->dev = dev; + /* Retrieve and enable optional clocks */ + clk = devm_clk_get(dev, "PCLK"); + if (IS_ERR(clk)) { + dev_err(dev, "no PCLK available\n"); + } else { + ret = clk_prepare_enable(clk); + if (ret) { + dev_err(dev, "could not prepare PCLK\n"); + return ret; + } + } + p->bus_clk = devm_clk_get(dev, "PCICLK"); + if (IS_ERR(p->bus_clk)) { + dev_err(dev, "no PCICLK available\n"); + } else { + ret = clk_prepare_enable(p->bus_clk); + if (ret) { + dev_err(dev, "could not prepare PCICLK\n"); + return ret; + } + } + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); p->base = devm_ioremap_resource(dev, regs); if (IS_ERR(p->base)) @@ -515,6 +543,34 @@ static int faraday_pci_probe(struct platform_device *pdev) } } + /* Check bus clock if we can gear up to 66 MHz */ + if (!IS_ERR(p->bus_clk)) { + unsigned long rate; + u32 val; + + faraday_pci_read_config(p->bus, 0, + FARADAY_PCI_STATUS_CMD, 4, &val); + rate = clk_get_rate(p->bus_clk); + + if ((rate == 33000000) && (val & PCI_STATUS_66MHZ_CAPABLE)) { + dev_info(dev, "33MHz bus is 66MHz capable\n"); + p->bus->max_bus_speed = PCI_SPEED_66MHz; + ret = clk_set_rate(p->bus_clk, 66000000); + if (ret) + dev_err(dev, "failed to set bus clock\n"); + } else { + dev_info(dev, "33MHz only bus\n"); + p->bus->max_bus_speed = PCI_SPEED_33MHz; + } + + /* Bumping the clock may fail so read back the rate */ + rate = clk_get_rate(p->bus_clk); + if (rate == 33000000) + p->bus->cur_bus_speed = PCI_SPEED_33MHz; + if (rate == 66000000) + p->bus->cur_bus_speed = PCI_SPEED_66MHz; + } + ret = faraday_pci_parse_map_dma_ranges(p, dev->of_node); if (ret) return ret; diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 2618f875a600..043c759d80f8 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -233,8 +233,8 @@ struct tegra_msi { struct msi_controller chip; DECLARE_BITMAP(used, INT_PCI_MSI_NR); struct irq_domain *domain; - unsigned long pages; struct mutex lock; + u64 phys; int irq; }; @@ -1448,9 +1448,8 @@ static int tegra_msi_setup_irq(struct msi_controller *chip, irq_set_msi_desc(irq, desc); - msg.address_lo = virt_to_phys((void *)msi->pages); - /* 32 bit address only */ - msg.address_hi = 0; + msg.address_lo = lower_32_bits(msi->phys); + msg.address_hi = upper_32_bits(msi->phys); msg.data = hwirq; pci_write_msi_msg(irq, &msg); @@ -1499,7 +1498,6 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie) const struct tegra_pcie_soc *soc = pcie->soc; struct tegra_msi *msi = &pcie->msi; struct device *dev = pcie->dev; - unsigned long base; int err; u32 reg; @@ -1531,12 +1529,25 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie) goto err; } - /* setup AFI/FPCI range */ - msi->pages = __get_free_pages(GFP_KERNEL, 0); - base = virt_to_phys((void *)msi->pages); + /* + * The PCI host bridge on Tegra contains some logic that intercepts + * MSI writes, which means that the MSI target address doesn't have + * to point to actual physical memory. Rather than allocating one 4 + * KiB page of system memory that's never used, we can simply pick + * an arbitrary address within an area reserved for system memory + * in the FPCI address map. + * + * However, in order to avoid confusion, we pick an address that + * doesn't map to physical memory. The FPCI address map reserves a + * 1012 GiB region for system memory and memory-mapped I/O. Since + * none of the Tegra SoCs that contain this PCI host bridge can + * address more than 16 GiB of system memory, the last 4 KiB of + * these 1012 GiB is a good candidate. + */ + msi->phys = 0xfcfffff000; - afi_writel(pcie, base >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST); - afi_writel(pcie, base, AFI_MSI_AXI_BAR_ST); + afi_writel(pcie, msi->phys >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST); + afi_writel(pcie, msi->phys, AFI_MSI_AXI_BAR_ST); /* this register is in 4K increments */ afi_writel(pcie, 1, AFI_MSI_BAR_SZ); @@ -1585,8 +1596,6 @@ static int tegra_pcie_disable_msi(struct tegra_pcie *pcie) afi_writel(pcie, 0, AFI_MSI_EN_VEC6); afi_writel(pcie, 0, AFI_MSI_EN_VEC7); - free_pages(msi->pages, 0); - if (msi->irq > 0) free_irq(msi->irq, pcie); diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c new file mode 100644 index 000000000000..8ec8fa8732bf --- /dev/null +++ b/drivers/pci/host/pcie-mediatek.c @@ -0,0 +1,552 @@ +/* + * MediaTek PCIe host controller driver. + * + * Copyright (c) 2017 MediaTek Inc. + * Author: Ryder Lee <ryder.lee@mediatek.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/of_address.h> +#include <linux/of_pci.h> +#include <linux/of_platform.h> +#include <linux/pci.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/reset.h> + +/* PCIe shared registers */ +#define PCIE_SYS_CFG 0x00 +#define PCIE_INT_ENABLE 0x0c +#define PCIE_CFG_ADDR 0x20 +#define PCIE_CFG_DATA 0x24 + +/* PCIe per port registers */ +#define PCIE_BAR0_SETUP 0x10 +#define PCIE_BAR1_SETUP 0x14 +#define PCIE_BAR0_MEM_BASE 0x18 +#define PCIE_CLASS 0x34 +#define PCIE_LINK_STATUS 0x50 + +#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) +#define PCIE_PORT_PERST(x) BIT(1 + (x)) +#define PCIE_PORT_LINKUP BIT(0) +#define PCIE_BAR_MAP_MAX GENMASK(31, 16) + +#define PCIE_BAR_ENABLE BIT(0) +#define PCIE_REVISION_ID BIT(0) +#define PCIE_CLASS_CODE (0x60400 << 8) +#define PCIE_CONF_REG(regn) (((regn) & GENMASK(7, 2)) | \ + ((((regn) >> 8) & GENMASK(3, 0)) << 24)) +#define PCIE_CONF_FUN(fun) (((fun) << 8) & GENMASK(10, 8)) +#define PCIE_CONF_DEV(dev) (((dev) << 11) & GENMASK(15, 11)) +#define PCIE_CONF_BUS(bus) (((bus) << 16) & GENMASK(23, 16)) +#define PCIE_CONF_ADDR(regn, fun, dev, bus) \ + (PCIE_CONF_REG(regn) | PCIE_CONF_FUN(fun) | \ + PCIE_CONF_DEV(dev) | PCIE_CONF_BUS(bus)) + +/* MediaTek specific configuration registers */ +#define PCIE_FTS_NUM 0x70c +#define PCIE_FTS_NUM_MASK GENMASK(15, 8) +#define PCIE_FTS_NUM_L0(x) ((x) & 0xff << 8) + +#define PCIE_FC_CREDIT 0x73c +#define PCIE_FC_CREDIT_MASK (GENMASK(31, 31) | GENMASK(28, 16)) +#define PCIE_FC_CREDIT_VAL(x) ((x) << 16) + +/** + * struct mtk_pcie_port - PCIe port information + * @base: IO mapped register base + * @list: port list + * @pcie: pointer to PCIe host info + * @reset: pointer to port reset control + * @sys_ck: pointer to bus clock + * @phy: pointer to phy control block + * @lane: lane count + * @index: port index + */ +struct mtk_pcie_port { + void __iomem *base; + struct list_head list; + struct mtk_pcie *pcie; + struct reset_control *reset; + struct clk *sys_ck; + struct phy *phy; + u32 lane; + u32 index; +}; + +/** + * struct mtk_pcie - PCIe host information + * @dev: pointer to PCIe device + * @base: IO mapped register base + * @free_ck: free-run reference clock + * @io: IO resource + * @pio: PIO resource + * @mem: non-prefetchable memory resource + * @busn: bus range + * @offset: IO / Memory offset + * @ports: pointer to PCIe port information + */ +struct mtk_pcie { + struct device *dev; + void __iomem *base; + struct clk *free_ck; + + struct resource io; + struct resource pio; + struct resource mem; + struct resource busn; + struct { + resource_size_t mem; + resource_size_t io; + } offset; + struct list_head ports; +}; + +static inline bool mtk_pcie_link_is_up(struct mtk_pcie_port *port) +{ + return !!(readl(port->base + PCIE_LINK_STATUS) & PCIE_PORT_LINKUP); +} + +static void mtk_pcie_port_free(struct mtk_pcie_port *port) +{ + struct mtk_pcie *pcie = port->pcie; + struct device *dev = pcie->dev; + + devm_iounmap(dev, port->base); + list_del(&port->list); + devm_kfree(dev, port); +} + +static void mtk_pcie_put_resources(struct mtk_pcie *pcie) +{ + struct device *dev = pcie->dev; + struct mtk_pcie_port *port, *tmp; + + list_for_each_entry_safe(port, tmp, &pcie->ports, list) { + phy_power_off(port->phy); + clk_disable_unprepare(port->sys_ck); + mtk_pcie_port_free(port); + } + + clk_disable_unprepare(pcie->free_ck); + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); +} + +static void __iomem *mtk_pcie_map_bus(struct pci_bus *bus, + unsigned int devfn, int where) +{ + struct pci_host_bridge *host = pci_find_host_bridge(bus); + struct mtk_pcie *pcie = pci_host_bridge_priv(host); + + writel(PCIE_CONF_ADDR(where, PCI_FUNC(devfn), PCI_SLOT(devfn), + bus->number), pcie->base + PCIE_CFG_ADDR); + + return pcie->base + PCIE_CFG_DATA + (where & 3); +} + +static struct pci_ops mtk_pcie_ops = { + .map_bus = mtk_pcie_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, +}; + +static void mtk_pcie_configure_rc(struct mtk_pcie_port *port) +{ + struct mtk_pcie *pcie = port->pcie; + u32 func = PCI_FUNC(port->index << 3); + u32 slot = PCI_SLOT(port->index << 3); + u32 val; + + /* enable interrupt */ + val = readl(pcie->base + PCIE_INT_ENABLE); + val |= PCIE_PORT_INT_EN(port->index); + writel(val, pcie->base + PCIE_INT_ENABLE); + + /* map to all DDR region. We need to set it before cfg operation. */ + writel(PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, + port->base + PCIE_BAR0_SETUP); + + /* configure class Code and revision ID */ + writel(PCIE_CLASS_CODE | PCIE_REVISION_ID, + port->base + PCIE_CLASS); + + /* configure FC credit */ + writel(PCIE_CONF_ADDR(PCIE_FC_CREDIT, func, slot, 0), + pcie->base + PCIE_CFG_ADDR); + val = readl(pcie->base + PCIE_CFG_DATA); + val &= ~PCIE_FC_CREDIT_MASK; + val |= PCIE_FC_CREDIT_VAL(0x806c); + writel(PCIE_CONF_ADDR(PCIE_FC_CREDIT, func, slot, 0), + pcie->base + PCIE_CFG_ADDR); + writel(val, pcie->base + PCIE_CFG_DATA); + + /* configure RC FTS number to 250 when it leaves L0s */ + writel(PCIE_CONF_ADDR(PCIE_FTS_NUM, func, slot, 0), + pcie->base + PCIE_CFG_ADDR); + val = readl(pcie->base + PCIE_CFG_DATA); + val &= ~PCIE_FTS_NUM_MASK; + val |= PCIE_FTS_NUM_L0(0x50); + writel(PCIE_CONF_ADDR(PCIE_FTS_NUM, func, slot, 0), + pcie->base + PCIE_CFG_ADDR); + writel(val, pcie->base + PCIE_CFG_DATA); +} + +static void mtk_pcie_assert_ports(struct mtk_pcie_port *port) +{ + struct mtk_pcie *pcie = port->pcie; + u32 val; + + /* assert port PERST_N */ + val = readl(pcie->base + PCIE_SYS_CFG); + val |= PCIE_PORT_PERST(port->index); + writel(val, pcie->base + PCIE_SYS_CFG); + + /* de-assert port PERST_N */ + val = readl(pcie->base + PCIE_SYS_CFG); + val &= ~PCIE_PORT_PERST(port->index); + writel(val, pcie->base + PCIE_SYS_CFG); + + /* PCIe v2.0 need at least 100ms delay to train from Gen1 to Gen2 */ + msleep(100); +} + +static int mtk_pcie_enable_ports(struct mtk_pcie_port *port) +{ + struct device *dev = port->pcie->dev; + int err; + + err = clk_prepare_enable(port->sys_ck); + if (err) { + dev_err(dev, "failed to enable port%d clock\n", port->index); + goto err_sys_clk; + } + + reset_control_assert(port->reset); + reset_control_deassert(port->reset); + + err = phy_power_on(port->phy); + if (err) { + dev_err(dev, "failed to power on port%d phy\n", port->index); + goto err_phy_on; + } + + mtk_pcie_assert_ports(port); + + /* if link up, then setup root port configuration space */ + if (mtk_pcie_link_is_up(port)) { + mtk_pcie_configure_rc(port); + return 0; + } + + dev_info(dev, "Port%d link down\n", port->index); + + phy_power_off(port->phy); +err_phy_on: + clk_disable_unprepare(port->sys_ck); + mtk_pcie_port_free(port); +err_sys_clk: + return err; +} + +static int mtk_pcie_parse_ports(struct mtk_pcie *pcie, + struct mtk_pcie_port **p, + struct device_node *node, + int index) +{ + struct mtk_pcie_port *port; + struct resource *regs; + struct device *dev = pcie->dev; + struct platform_device *pdev = to_platform_device(dev); + char name[10]; + int err; + + *p = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); + if (!*p) + return -ENOMEM; + + port = *p; + + err = of_property_read_u32(node, "num-lanes", &port->lane); + if (err) { + dev_err(dev, "missing num-lanes property\n"); + return err; + } + + regs = platform_get_resource(pdev, IORESOURCE_MEM, index + 1); + port->base = devm_ioremap_resource(dev, regs); + if (IS_ERR(port->base)) { + dev_err(dev, "failed to map port%d base\n", index); + return PTR_ERR(port->base); + } + + snprintf(name, sizeof(name), "sys_ck%d", index); + port->sys_ck = devm_clk_get(dev, name); + if (IS_ERR(port->sys_ck)) { + dev_err(dev, "failed to get port%d clock\n", index); + return PTR_ERR(port->sys_ck); + } + + snprintf(name, sizeof(name), "pcie-rst%d", index); + port->reset = devm_reset_control_get(dev, name); + if (IS_ERR(port->reset)) { + dev_err(dev, "failed to get port%d reset\n", index); + return PTR_ERR(port->reset); + } + + snprintf(name, sizeof(name), "pcie-phy%d", index); + port->phy = devm_phy_get(dev, name); + if (IS_ERR(port->phy)) { + dev_err(dev, "failed to get port%d phy\n", index); + return PTR_ERR(port->phy); + } + + port->index = index; + port->pcie = pcie; + + INIT_LIST_HEAD(&port->list); + list_add_tail(&port->list, &pcie->ports); + + return 0; +} + +static int mtk_pcie_handle_shared_resource(struct mtk_pcie *pcie) +{ + struct device *dev = pcie->dev; + struct platform_device *pdev = to_platform_device(dev); + struct resource *regs; + int err; + + /* get shared registers */ + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pcie->base = devm_ioremap_resource(dev, regs); + if (IS_ERR(pcie->base)) { + dev_err(dev, "failed to map shared register\n"); + return PTR_ERR(pcie->base); + } + + pcie->free_ck = devm_clk_get(dev, "free_ck"); + if (IS_ERR(pcie->free_ck)) { + dev_err(dev, "failed to get free_ck\n"); + return PTR_ERR(pcie->free_ck); + } + + pm_runtime_enable(dev); + err = pm_runtime_get_sync(dev); + if (err) + goto err_pm; + + /* enable top level clock */ + err = clk_prepare_enable(pcie->free_ck); + if (err) { + dev_err(dev, "failed to enable free_ck\n"); + goto err_free_ck; + } + + return 0; + +err_free_ck: + pm_runtime_put_sync(dev); +err_pm: + pm_runtime_disable(dev); + + return err; +} + +static int mtk_pcie_parse_and_add_res(struct mtk_pcie *pcie) +{ + struct device *dev = pcie->dev; + struct device_node *node = dev->of_node, *child; + struct of_pci_range_parser parser; + struct of_pci_range range; + struct resource res; + int err, linkup = 0; + + /* parse shared resources */ + err = mtk_pcie_handle_shared_resource(pcie); + if (err) + return err; + + if (of_pci_range_parser_init(&parser, node)) { + dev_err(dev, "missing \"ranges\" property\n"); + return -EINVAL; + } + + for_each_of_pci_range(&parser, &range) { + err = of_pci_range_to_resource(&range, node, &res); + if (err < 0) + return err; + + switch (res.flags & IORESOURCE_TYPE_BITS) { + case IORESOURCE_IO: + pcie->offset.io = res.start - range.pci_addr; + + memcpy(&pcie->pio, &res, sizeof(res)); + pcie->pio.name = node->full_name; + + pcie->io.start = range.cpu_addr; + pcie->io.end = range.cpu_addr + range.size - 1; + pcie->io.flags = IORESOURCE_MEM; + pcie->io.name = "I/O"; + + memcpy(&res, &pcie->io, sizeof(res)); + break; + + case IORESOURCE_MEM: + pcie->offset.mem = res.start - range.pci_addr; + + memcpy(&pcie->mem, &res, sizeof(res)); + pcie->mem.name = "non-prefetchable"; + break; + } + } + + err = of_pci_parse_bus_range(node, &pcie->busn); + if (err < 0) { + dev_err(dev, "failed to parse ranges property: %d\n", err); + pcie->busn.name = node->name; + pcie->busn.start = 0; + pcie->busn.end = 0xff; + pcie->busn.flags = IORESOURCE_BUS; + } + + for_each_child_of_node(node, child) { + struct mtk_pcie_port *port; + int index; + + err = of_pci_get_devfn(child); + if (err < 0) { + dev_err(dev, "failed to parse devfn: %d\n", err); + return err; + } + + index = PCI_SLOT(err); + + if (!of_device_is_available(child)) + continue; + + err = mtk_pcie_parse_ports(pcie, &port, child, index); + if (err) + return err; + + /* enable each port, and then check link status */ + err = mtk_pcie_enable_ports(port); + if (!err) + linkup++; + } + + return !linkup; +} + +static int mtk_pcie_request_resources(struct mtk_pcie *pcie) +{ + struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); + struct list_head *windows = &host->windows; + struct device *dev = pcie->dev; + int err; + + pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io); + pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem); + pci_add_resource(windows, &pcie->busn); + + err = devm_request_pci_bus_resources(dev, windows); + if (err < 0) + return err; + + pci_remap_iospace(&pcie->pio, pcie->io.start); + + return 0; +} + +static int mtk_pcie_register_host(struct pci_host_bridge *host) +{ + struct mtk_pcie *pcie = pci_host_bridge_priv(host); + struct pci_bus *child; + int err; + + pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS); + host->busnr = pcie->busn.start; + host->dev.parent = pcie->dev; + host->ops = &mtk_pcie_ops; + + err = pci_register_host_bridge(host); + if (err < 0) + return err; + + pci_scan_child_bus(host->bus); + + pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); + pci_bus_size_bridges(host->bus); + pci_bus_assign_resources(host->bus); + + list_for_each_entry(child, &host->bus->children, node) + pcie_bus_configure_settings(child); + + pci_bus_add_devices(host->bus); + + return 0; +} + +static int mtk_pcie_probe(struct platform_device *pdev) +{ + struct mtk_pcie *pcie; + struct pci_host_bridge *host; + int err; + + host = pci_alloc_host_bridge(sizeof(*pcie)); + if (!host) + return -ENOMEM; + + pcie = pci_host_bridge_priv(host); + + pcie->dev = &pdev->dev; + platform_set_drvdata(pdev, pcie); + INIT_LIST_HEAD(&pcie->ports); + + err = mtk_pcie_parse_and_add_res(pcie); + if (err) + return err; + + err = mtk_pcie_request_resources(pcie); + if (err) + goto put_resources; + + err = mtk_pcie_register_host(host); + if (err) + goto put_resources; + + return 0; + +put_resources: + mtk_pcie_put_resources(pcie); + return err; +} + +static const struct of_device_id mtk_pcie_ids[] = { + { .compatible = "mediatek,mt7623-pcie"}, + { .compatible = "mediatek,mt2701-pcie"}, + {}, +}; + +static struct platform_driver mtk_pcie_driver = { + .probe = mtk_pcie_probe, + .driver = { + .name = "mtk-pcie", + .of_match_table = mtk_pcie_ids, + .suppress_bind_attrs = true, + }, +}; +builtin_platform_driver(mtk_pcie_driver); diff --git a/drivers/pci/host/pcie-xilinx-nwl.c b/drivers/pci/host/pcie-xilinx-nwl.c index 4b16b26ae909..706a3ea62d1d 100644 --- a/drivers/pci/host/pcie-xilinx-nwl.c +++ b/drivers/pci/host/pcie-xilinx-nwl.c @@ -172,6 +172,7 @@ struct nwl_pcie { u8 root_busno; struct nwl_msi msi; struct irq_domain *legacy_irq_domain; + raw_spinlock_t leg_mask_lock; }; static inline u32 nwl_bridge_readl(struct nwl_pcie *pcie, u32 off) @@ -383,11 +384,52 @@ static void nwl_pcie_msi_handler_low(struct irq_desc *desc) chained_irq_exit(chip, desc); } +static void nwl_mask_leg_irq(struct irq_data *data) +{ + struct irq_desc *desc = irq_to_desc(data->irq); + struct nwl_pcie *pcie; + unsigned long flags; + u32 mask; + u32 val; + + pcie = irq_desc_get_chip_data(desc); + mask = 1 << (data->hwirq - 1); + raw_spin_lock_irqsave(&pcie->leg_mask_lock, flags); + val = nwl_bridge_readl(pcie, MSGF_LEG_MASK); + nwl_bridge_writel(pcie, (val & (~mask)), MSGF_LEG_MASK); + raw_spin_unlock_irqrestore(&pcie->leg_mask_lock, flags); +} + +static void nwl_unmask_leg_irq(struct irq_data *data) +{ + struct irq_desc *desc = irq_to_desc(data->irq); + struct nwl_pcie *pcie; + unsigned long flags; + u32 mask; + u32 val; + + pcie = irq_desc_get_chip_data(desc); + mask = 1 << (data->hwirq - 1); + raw_spin_lock_irqsave(&pcie->leg_mask_lock, flags); + val = nwl_bridge_readl(pcie, MSGF_LEG_MASK); + nwl_bridge_writel(pcie, (val | mask), MSGF_LEG_MASK); + raw_spin_unlock_irqrestore(&pcie->leg_mask_lock, flags); +} + +static struct irq_chip nwl_leg_irq_chip = { + .name = "nwl_pcie:legacy", + .irq_enable = nwl_unmask_leg_irq, + .irq_disable = nwl_mask_leg_irq, + .irq_mask = nwl_mask_leg_irq, + .irq_unmask = nwl_unmask_leg_irq, +}; + static int nwl_legacy_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq) { - irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq); + irq_set_chip_and_handler(irq, &nwl_leg_irq_chip, handle_level_irq); irq_set_chip_data(irq, domain->host_data); + irq_set_status_flags(irq, IRQ_LEVEL); return 0; } @@ -526,6 +568,7 @@ static int nwl_pcie_init_irq_domain(struct nwl_pcie *pcie) return -ENOMEM; } + raw_spin_lock_init(&pcie->leg_mask_lock); nwl_pcie_init_msi_irq_domain(pcie); return 0; } diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index 51357377efbc..1d828a614ac0 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c @@ -43,9 +43,11 @@ static size_t find_smbios_instance_string(struct pci_dev *pdev, char *buf, { const struct dmi_device *dmi; struct dmi_dev_onboard *donboard; + int domain_nr; int bus; int devfn; + domain_nr = pci_domain_nr(pdev->bus); bus = pdev->bus->number; devfn = pdev->devfn; @@ -53,8 +55,9 @@ static size_t find_smbios_instance_string(struct pci_dev *pdev, char *buf, while ((dmi = dmi_find_device(DMI_DEV_TYPE_DEV_ONBOARD, NULL, dmi)) != NULL) { donboard = dmi->device_data; - if (donboard && donboard->bus == bus && - donboard->devfn == devfn) { + if (donboard && donboard->segment == domain_nr && + donboard->bus == bus && + donboard->devfn == devfn) { if (buf) { if (attribute == SMBIOS_ATTR_INSTANCE_SHOW) return scnprintf(buf, PAGE_SIZE, diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 563901cd9c06..2f6f6380fa1c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -455,7 +455,7 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev, pci_bus_for_each_resource(bus, r, i) { if (!r) continue; - if (res->start && resource_contains(r, res)) { + if (resource_contains(r, res)) { /* * If the window is prefetchable but the BAR is diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c index 77d2ca99d2ec..c39f32e42b4d 100644 --- a/drivers/pci/pcie/pcie-dpc.c +++ b/drivers/pci/pcie/pcie-dpc.c @@ -92,7 +92,7 @@ static irqreturn_t dpc_irq(int irq, void *context) pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status); pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_SOURCE_ID, &source); - if (!status) + if (!status || status == (u16)(~0)) return IRQ_NONE; dev_info(&dpc->dev->device, "DPC containment event, status:%#06x source:%#06x\n", @@ -144,7 +144,7 @@ static int dpc_probe(struct pcie_device *dev) dpc->rp = (cap & PCI_EXP_DPC_CAP_RP_EXT); - ctl |= PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN; + ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN; pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl); dev_info(&dev->device, "DPC error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n", diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 085fb787aa9e..16e6cd86ad71 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -304,7 +304,7 @@ static void quirk_extend_bar_to_page(struct pci_dev *dev) { int i; - for (i = 0; i < PCI_STD_RESOURCE_END; i++) { + for (i = 0; i <= PCI_STD_RESOURCE_END; i++) { struct resource *r = &dev->resource[i]; if (r->flags & IORESOURCE_MEM && resource_size(r) < PAGE_SIZE) { diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index afaf7b643eeb..01009b2a7d74 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -15,73 +15,6 @@ config GENERIC_PHY phy users can obtain reference to the PHY. All the users of this framework should select this config. -config PHY_BCM_NS_USB2 - tristate "Broadcom Northstar USB 2.0 PHY Driver" - depends on ARCH_BCM_IPROC || COMPILE_TEST - depends on HAS_IOMEM && OF - select GENERIC_PHY - help - Enable this to support Broadcom USB 2.0 PHY connected to the USB - controller on Northstar family. - -config PHY_BCM_NS_USB3 - tristate "Broadcom Northstar USB 3.0 PHY Driver" - depends on ARCH_BCM_IPROC || COMPILE_TEST - depends on HAS_IOMEM && OF - select GENERIC_PHY - help - Enable this to support Broadcom USB 3.0 PHY connected to the USB - controller on Northstar family. - -config PHY_BERLIN_USB - tristate "Marvell Berlin USB PHY Driver" - depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF - select GENERIC_PHY - help - Enable this to support the USB PHY on Marvell Berlin SoCs. - -config PHY_BERLIN_SATA - tristate "Marvell Berlin SATA PHY driver" - depends on ARCH_BERLIN && HAS_IOMEM && OF - select GENERIC_PHY - help - Enable this to support the SATA PHY on Marvell Berlin SoCs. - -config ARMADA375_USBCLUSTER_PHY - def_bool y - depends on MACH_ARMADA_375 || COMPILE_TEST - depends on OF && HAS_IOMEM - select GENERIC_PHY - -config PHY_DA8XX_USB - tristate "TI DA8xx USB PHY Driver" - depends on ARCH_DAVINCI_DA8XX - select GENERIC_PHY - select MFD_SYSCON - help - Enable this to support the USB PHY on DA8xx SoCs. - - This driver controls both the USB 1.1 PHY and the USB 2.0 PHY. - -config PHY_DM816X_USB - tristate "TI dm816x USB PHY driver" - depends on ARCH_OMAP2PLUS - depends on USB_SUPPORT - select GENERIC_PHY - select USB_PHY - help - Enable this for dm816x USB to work. - -config PHY_EXYNOS_MIPI_VIDEO - tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver" - depends on HAS_IOMEM - depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST - select GENERIC_PHY - default y if ARCH_S5PV210 || ARCH_EXYNOS - help - Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P - and EXYNOS SoCs. - config PHY_LPC18XX_USB_OTG tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver" depends on OF && (ARCH_LPC18XX || COMPILE_TEST) @@ -93,146 +26,6 @@ config PHY_LPC18XX_USB_OTG This driver is need for USB0 support on LPC18xx/43xx and takes care of enabling and clock setup. -config PHY_PXA_28NM_HSIC - tristate "Marvell USB HSIC 28nm PHY Driver" - depends on HAS_IOMEM - select GENERIC_PHY - help - Enable this to support Marvell USB HSIC PHY driver for Marvell - SoC. This driver will do the PHY initialization and shutdown. - The PHY driver will be used by Marvell ehci driver. - - To compile this driver as a module, choose M here. - -config PHY_PXA_28NM_USB2 - tristate "Marvell USB 2.0 28nm PHY Driver" - depends on HAS_IOMEM - select GENERIC_PHY - help - Enable this to support Marvell USB 2.0 PHY driver for Marvell - SoC. This driver will do the PHY initialization and shutdown. - The PHY driver will be used by Marvell udc/ehci/otg driver. - - To compile this driver as a module, choose M here. - -config PHY_MVEBU_SATA - def_bool y - depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD - depends on OF - select GENERIC_PHY - -config PHY_MIPHY28LP - tristate "STMicroelectronics MIPHY28LP PHY driver for STiH407" - depends on ARCH_STI - select GENERIC_PHY - help - Enable this to support the miphy transceiver (for SATA/PCIE/USB3) - that is part of STMicroelectronics STiH407 SoC. - -config PHY_RCAR_GEN2 - tristate "Renesas R-Car generation 2 USB PHY driver" - depends on ARCH_RENESAS - depends on GENERIC_PHY - help - Support for USB PHY found on Renesas R-Car generation 2 SoCs. - -config PHY_RCAR_GEN3_USB2 - tristate "Renesas R-Car generation 3 USB 2.0 PHY driver" - depends on ARCH_RENESAS - depends on EXTCON - select GENERIC_PHY - help - Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs. - -config OMAP_CONTROL_PHY - tristate "OMAP CONTROL PHY Driver" - depends on ARCH_OMAP2PLUS || COMPILE_TEST - help - Enable this to add support for the PHY part present in the control - module. This driver has API to power on the USB2 PHY and to write to - the mailbox. The mailbox is present only in omap4 and the register to - power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an - additional register to power on USB3 PHY/SATA PHY/PCIE PHY - (PIPE3 PHY). - -config OMAP_USB2 - tristate "OMAP USB2 PHY Driver" - depends on ARCH_OMAP2PLUS - depends on USB_SUPPORT - select GENERIC_PHY - select USB_PHY - select OMAP_CONTROL_PHY - depends on OMAP_OCP2SCP - help - Enable this to support the transceiver that is part of SOC. This - driver takes care of all the PHY functionality apart from comparator. - The USB OTG controller communicates with the comparator using this - driver. - -config TI_PIPE3 - tristate "TI PIPE3 PHY Driver" - depends on ARCH_OMAP2PLUS || COMPILE_TEST - select GENERIC_PHY - select OMAP_CONTROL_PHY - depends on OMAP_OCP2SCP - help - Enable this to support the PIPE3 PHY that is part of TI SOCs. This - driver takes care of all the PHY functionality apart from comparator. - This driver interacts with the "OMAP Control PHY Driver" to power - on/off the PHY. - -config TWL4030_USB - tristate "TWL4030 USB Transceiver Driver" - depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS - depends on USB_SUPPORT - depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't 'y' - select GENERIC_PHY - select USB_PHY - help - Enable this to support the USB OTG transceiver on TWL4030 - family chips (including the TWL5030 and TPS659x0 devices). - This transceiver supports high and full speed devices plus, - in host mode, low speed. - -config PHY_EXYNOS_DP_VIDEO - tristate "EXYNOS SoC series Display Port PHY driver" - depends on OF - depends on ARCH_EXYNOS || COMPILE_TEST - default ARCH_EXYNOS - select GENERIC_PHY - help - Support for Display Port PHY found on Samsung EXYNOS SoCs. - -config BCM_KONA_USB2_PHY - tristate "Broadcom Kona USB2 PHY Driver" - depends on HAS_IOMEM - select GENERIC_PHY - help - Enable this to support the Broadcom Kona USB 2.0 PHY. - -config PHY_EXYNOS5250_SATA - tristate "Exynos5250 Sata SerDes/PHY driver" - depends on SOC_EXYNOS5250 - depends on HAS_IOMEM - depends on OF - select GENERIC_PHY - select I2C - select I2C_S3C2410 - select MFD_SYSCON - help - Enable this to support SATA SerDes/Phy found on Samsung's - Exynos5250 based SoCs.This SerDes/Phy supports SATA 1.5 Gb/s, - SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host - port to accept one SATA device. - -config PHY_HIX5HD2_SATA - tristate "HIX5HD2 SATA PHY Driver" - depends on ARCH_HIX5HD2 && OF && HAS_IOMEM - select GENERIC_PHY - select MFD_SYSCON - help - Support for SATA PHY on Hisilicon hix5hd2 Soc. - config PHY_MT65XX_USB3 tristate "Mediatek USB3.0 PHY Driver" depends on ARCH_MEDIATEK && OF @@ -241,104 +34,6 @@ config PHY_MT65XX_USB3 Say 'Y' here to add support for Mediatek USB3.0 PHY driver, it supports multiple usb2.0 and usb3.0 ports. -config PHY_HI6220_USB - tristate "hi6220 USB PHY support" - depends on (ARCH_HISI && ARM64) || COMPILE_TEST - select GENERIC_PHY - select MFD_SYSCON - help - Enable this to support the HISILICON HI6220 USB PHY. - - To compile this driver as a module, choose M here. - -config PHY_SUN4I_USB - tristate "Allwinner sunxi SoC USB PHY driver" - depends on ARCH_SUNXI && HAS_IOMEM && OF - depends on RESET_CONTROLLER - depends on EXTCON - depends on POWER_SUPPLY - depends on USB_SUPPORT - select GENERIC_PHY - select USB_COMMON - help - Enable this to support the transceiver that is part of Allwinner - sunxi SoCs. - - This driver controls the entire USB PHY block, both the USB OTG - parts, as well as the 2 regular USB 2 host PHYs. - -config PHY_SUN9I_USB - tristate "Allwinner sun9i SoC USB PHY driver" - depends on ARCH_SUNXI && HAS_IOMEM && OF - depends on RESET_CONTROLLER - depends on USB_SUPPORT - select USB_COMMON - select GENERIC_PHY - help - Enable this to support the transceiver that is part of Allwinner - sun9i SoCs. - - This driver controls each individual USB 2 host PHY. - -config PHY_SAMSUNG_USB2 - tristate "Samsung USB 2.0 PHY driver" - depends on HAS_IOMEM - depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2 - select GENERIC_PHY - select MFD_SYSCON - default ARCH_EXYNOS - help - Enable this to support the Samsung USB 2.0 PHY driver for Samsung - SoCs. This driver provides the interface for USB 2.0 PHY. Support - for particular PHYs will be enabled based on the SoC type in addition - to this driver. - -config PHY_S5PV210_USB2 - bool "Support for S5PV210" - depends on PHY_SAMSUNG_USB2 - depends on ARCH_S5PV210 - help - Enable USB PHY support for S5PV210. This option requires that Samsung - USB 2.0 PHY driver is enabled and means that support for this - particular SoC is compiled in the driver. In case of S5PV210 two phys - are available - device and host. - -config PHY_EXYNOS4210_USB2 - bool - depends on PHY_SAMSUNG_USB2 - default CPU_EXYNOS4210 - -config PHY_EXYNOS4X12_USB2 - bool - depends on PHY_SAMSUNG_USB2 - default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412 - -config PHY_EXYNOS5250_USB2 - bool - depends on PHY_SAMSUNG_USB2 - default SOC_EXYNOS5250 || SOC_EXYNOS5420 - -config PHY_EXYNOS5_USBDRD - tristate "Exynos5 SoC series USB DRD PHY driver" - depends on ARCH_EXYNOS && OF - depends on HAS_IOMEM - depends on USB_DWC3_EXYNOS - select GENERIC_PHY - select MFD_SYSCON - default y - help - Enable USB DRD PHY support for Exynos 5 SoC series. - This driver provides PHY interface for USB 3.0 DRD controller - present on Exynos5 SoC series. - -config PHY_EXYNOS_PCIE - bool "Exynos PCIe PHY driver" - depends on OF && (ARCH_EXYNOS || COMPILE_TEST) - select GENERIC_PHY - help - Enable PCIe PHY support for Exynos SoC series. - This driver provides PHY interface for Exynos PCIe controller. - config PHY_PISTACHIO_USB tristate "IMG Pistachio USB2.0 PHY driver" depends on MACH_PISTACHIO @@ -346,83 +41,6 @@ config PHY_PISTACHIO_USB help Enable this to support the USB2.0 PHY on the IMG Pistachio SoC. -config PHY_QCOM_APQ8064_SATA - tristate "Qualcomm APQ8064 SATA SerDes/PHY driver" - depends on ARCH_QCOM - depends on HAS_IOMEM - depends on OF - select GENERIC_PHY - -config PHY_QCOM_IPQ806X_SATA - tristate "Qualcomm IPQ806x SATA SerDes/PHY driver" - depends on ARCH_QCOM - depends on HAS_IOMEM - depends on OF - select GENERIC_PHY - -config PHY_ROCKCHIP_USB - tristate "Rockchip USB2 PHY Driver" - depends on ARCH_ROCKCHIP && OF - select GENERIC_PHY - help - Enable this to support the Rockchip USB 2.0 PHY. - -config PHY_ROCKCHIP_INNO_USB2 - tristate "Rockchip INNO USB2PHY Driver" - depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF - depends on COMMON_CLK - depends on EXTCON - depends on USB_SUPPORT - select GENERIC_PHY - select USB_COMMON - help - Support for Rockchip USB2.0 PHY with Innosilicon IP block. - -config PHY_ROCKCHIP_EMMC - tristate "Rockchip EMMC PHY Driver" - depends on ARCH_ROCKCHIP && OF - select GENERIC_PHY - help - Enable this to support the Rockchip EMMC PHY. - -config PHY_ROCKCHIP_DP - tristate "Rockchip Display Port PHY Driver" - depends on ARCH_ROCKCHIP && OF - select GENERIC_PHY - help - Enable this to support the Rockchip Display Port PHY. - -config PHY_ROCKCHIP_PCIE - tristate "Rockchip PCIe PHY Driver" - depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST - select GENERIC_PHY - select MFD_SYSCON - help - Enable this to support the Rockchip PCIe PHY. - -config PHY_ROCKCHIP_TYPEC - tristate "Rockchip TYPEC PHY Driver" - depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST) - select EXTCON - select GENERIC_PHY - select RESET_CONTROLLER - help - Enable this to support the Rockchip USB TYPEC PHY. - -config PHY_ST_SPEAR1310_MIPHY - tristate "ST SPEAR1310-MIPHY driver" - select GENERIC_PHY - depends on MACH_SPEAR1310 || COMPILE_TEST - help - Support for ST SPEAr1310 MIPHY which can be used for PCIe and SATA. - -config PHY_ST_SPEAR1340_MIPHY - tristate "ST SPEAR1340-MIPHY driver" - select GENERIC_PHY - depends on MACH_SPEAR1340 || COMPILE_TEST - help - Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA. - config PHY_XGENE tristate "APM X-Gene 15Gbps PHY support" depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST) @@ -430,104 +48,17 @@ config PHY_XGENE help This option enables support for APM X-Gene SoC multi-purpose PHY. -config PHY_STIH407_USB - tristate "STMicroelectronics USB2 picoPHY driver for STiH407 family" - depends on RESET_CONTROLLER - depends on ARCH_STI || COMPILE_TEST - select GENERIC_PHY - help - Enable this support to enable the picoPHY device used by USB2 - and USB3 controllers on STMicroelectronics STiH407 SoC families. - -config PHY_QCOM_QMP - tristate "Qualcomm QMP PHY Driver" - depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST) - select GENERIC_PHY - help - Enable this to support the QMP PHY transceiver that is used - with controllers such as PCIe, UFS, and USB on Qualcomm chips. - -config PHY_QCOM_QUSB2 - tristate "Qualcomm QUSB2 PHY Driver" - depends on OF && (ARCH_QCOM || COMPILE_TEST) - depends on NVMEM || !NVMEM - select GENERIC_PHY - help - Enable this to support the HighSpeed QUSB2 PHY transceiver for USB - controllers on Qualcomm chips. This driver supports the high-speed - PHY which is usually paired with either the ChipIdea or Synopsys DWC3 - USB IPs on MSM SOCs. - -config PHY_QCOM_UFS - tristate "Qualcomm UFS PHY driver" - depends on OF && ARCH_QCOM - select GENERIC_PHY - help - Support for UFS PHY on QCOM chipsets. - -config PHY_QCOM_USB_HS - tristate "Qualcomm USB HS PHY module" - depends on USB_ULPI_BUS - depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in - select GENERIC_PHY - help - Support for the USB high-speed ULPI compliant phy on Qualcomm - chipsets. - -config PHY_QCOM_USB_HSIC - tristate "Qualcomm USB HSIC ULPI PHY module" - depends on USB_ULPI_BUS - select GENERIC_PHY - help - Support for the USB HSIC ULPI compliant PHY on QCOM chipsets. - -config PHY_TUSB1210 - tristate "TI TUSB1210 ULPI PHY module" - depends on USB_ULPI_BUS - select GENERIC_PHY - help - Support for TI TUSB1210 USB ULPI PHY. - -config PHY_BRCM_SATA - tristate "Broadcom SATA PHY driver" - depends on ARCH_BRCMSTB || ARCH_BCM_IPROC || BMIPS_GENERIC || COMPILE_TEST - depends on OF - select GENERIC_PHY - default ARCH_BCM_IPROC - help - Enable this to support the Broadcom SATA PHY. - If unsure, say N. - -config PHY_CYGNUS_PCIE - tristate "Broadcom Cygnus PCIe PHY driver" - depends on OF && (ARCH_BCM_CYGNUS || COMPILE_TEST) - select GENERIC_PHY - default ARCH_BCM_CYGNUS - help - Enable this to support the Broadcom Cygnus PCIe PHY. - If unsure, say N. - +source "drivers/phy/allwinner/Kconfig" +source "drivers/phy/amlogic/Kconfig" +source "drivers/phy/broadcom/Kconfig" +source "drivers/phy/hisilicon/Kconfig" +source "drivers/phy/marvell/Kconfig" +source "drivers/phy/qualcomm/Kconfig" +source "drivers/phy/renesas/Kconfig" +source "drivers/phy/rockchip/Kconfig" +source "drivers/phy/samsung/Kconfig" +source "drivers/phy/st/Kconfig" source "drivers/phy/tegra/Kconfig" - -config PHY_NS2_PCIE - tristate "Broadcom Northstar2 PCIe PHY driver" - depends on OF && MDIO_BUS_MUX_BCM_IPROC - select GENERIC_PHY - default ARCH_BCM_IPROC - help - Enable this to support the Broadcom Northstar2 PCIe PHY. - If unsure, say N. - -config PHY_MESON8B_USB2 - tristate "Meson8b and GXBB USB2 PHY driver" - default ARCH_MESON - depends on OF && (ARCH_MESON || COMPILE_TEST) - depends on USB_SUPPORT - select USB_COMMON - select GENERIC_PHY - help - Enable this to support the Meson USB2 PHYs found in Meson8b - and GXBB SoCs. - If unsure, say N. +source "drivers/phy/ti/Kconfig" endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index f8047b4639fa..c1bd1fa3c853 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -3,64 +3,20 @@ # obj-$(CONFIG_GENERIC_PHY) += phy-core.o -obj-$(CONFIG_PHY_BCM_NS_USB2) += phy-bcm-ns-usb2.o -obj-$(CONFIG_PHY_BCM_NS_USB3) += phy-bcm-ns-usb3.o -obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o -obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o -obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o -obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o -obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o -obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o -obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o -obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o -obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o -obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o -obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o -obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o -obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o -obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o -obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o -obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o -obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o -obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o -obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o -obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o -obj-$(CONFIG_PHY_HI6220_USB) += phy-hi6220-usb.o obj-$(CONFIG_PHY_MT65XX_USB3) += phy-mt65xx-usb3.o -obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o -obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o -obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o -phy-exynos-usb2-y += phy-samsung-usb2.o -phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o -phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o -phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o -phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o -obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o -obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o -obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o -obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o -obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o -obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o -obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o -obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o -obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o -obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o -obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o -obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o obj-$(CONFIG_PHY_XGENE) += phy-xgene.o -obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o -obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o -obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o -obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o -obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o -obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o -obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o -obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o -obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o -obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o -obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o -obj-$(CONFIG_ARCH_TEGRA) += tegra/ -obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o -obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o + +obj-$(CONFIG_ARCH_SUNXI) += allwinner/ +obj-$(CONFIG_ARCH_MESON) += amlogic/ +obj-$(CONFIG_ARCH_RENESAS) += renesas/ +obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ +obj-$(CONFIG_ARCH_TEGRA) += tegra/ +obj-y += broadcom/ \ + hisilicon/ \ + marvell/ \ + qualcomm/ \ + samsung/ \ + st/ \ + ti/ diff --git a/drivers/phy/allwinner/Kconfig b/drivers/phy/allwinner/Kconfig new file mode 100644 index 000000000000..cdc1e745ba47 --- /dev/null +++ b/drivers/phy/allwinner/Kconfig @@ -0,0 +1,31 @@ +# +# Phy drivers for Allwinner platforms +# +config PHY_SUN4I_USB + tristate "Allwinner sunxi SoC USB PHY driver" + depends on ARCH_SUNXI && HAS_IOMEM && OF + depends on RESET_CONTROLLER + depends on EXTCON + depends on POWER_SUPPLY + depends on USB_SUPPORT + select GENERIC_PHY + select USB_COMMON + help + Enable this to support the transceiver that is part of Allwinner + sunxi SoCs. + + This driver controls the entire USB PHY block, both the USB OTG + parts, as well as the 2 regular USB 2 host PHYs. + +config PHY_SUN9I_USB + tristate "Allwinner sun9i SoC USB PHY driver" + depends on ARCH_SUNXI && HAS_IOMEM && OF + depends on RESET_CONTROLLER + depends on USB_SUPPORT + select USB_COMMON + select GENERIC_PHY + help + Enable this to support the transceiver that is part of Allwinner + sun9i SoCs. + + This driver controls each individual USB 2 host PHY. diff --git a/drivers/phy/allwinner/Makefile b/drivers/phy/allwinner/Makefile new file mode 100644 index 000000000000..8605529c01a1 --- /dev/null +++ b/drivers/phy/allwinner/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o +obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index bbf06cfe5898..bbf06cfe5898 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c diff --git a/drivers/phy/phy-sun9i-usb.c b/drivers/phy/allwinner/phy-sun9i-usb.c index 28fce4bce638..28fce4bce638 100644 --- a/drivers/phy/phy-sun9i-usb.c +++ b/drivers/phy/allwinner/phy-sun9i-usb.c diff --git a/drivers/phy/amlogic/Kconfig b/drivers/phy/amlogic/Kconfig new file mode 100644 index 000000000000..edcd5b65179f --- /dev/null +++ b/drivers/phy/amlogic/Kconfig @@ -0,0 +1,14 @@ +# +# Phy drivers for Amlogic platforms +# +config PHY_MESON8B_USB2 + tristate "Meson8b and GXBB USB2 PHY driver" + default ARCH_MESON + depends on OF && (ARCH_MESON || COMPILE_TEST) + depends on USB_SUPPORT + select USB_COMMON + select GENERIC_PHY + help + Enable this to support the Meson USB2 PHYs found in Meson8b + and GXBB SoCs. + If unsure, say N. diff --git a/drivers/phy/amlogic/Makefile b/drivers/phy/amlogic/Makefile new file mode 100644 index 000000000000..47b6eecc3864 --- /dev/null +++ b/drivers/phy/amlogic/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o diff --git a/drivers/phy/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c index 30f56a6a411f..30f56a6a411f 100644 --- a/drivers/phy/phy-meson8b-usb2.c +++ b/drivers/phy/amlogic/phy-meson8b-usb2.c diff --git a/drivers/phy/broadcom/Kconfig b/drivers/phy/broadcom/Kconfig new file mode 100644 index 000000000000..d2d99023ec50 --- /dev/null +++ b/drivers/phy/broadcom/Kconfig @@ -0,0 +1,55 @@ +# +# Phy drivers for Broadcom platforms +# +config PHY_CYGNUS_PCIE + tristate "Broadcom Cygnus PCIe PHY driver" + depends on OF && (ARCH_BCM_CYGNUS || COMPILE_TEST) + select GENERIC_PHY + default ARCH_BCM_CYGNUS + help + Enable this to support the Broadcom Cygnus PCIe PHY. + If unsure, say N. + +config BCM_KONA_USB2_PHY + tristate "Broadcom Kona USB2 PHY Driver" + depends on HAS_IOMEM + select GENERIC_PHY + help + Enable this to support the Broadcom Kona USB 2.0 PHY. + +config PHY_BCM_NS_USB2 + tristate "Broadcom Northstar USB 2.0 PHY Driver" + depends on ARCH_BCM_IPROC || COMPILE_TEST + depends on HAS_IOMEM && OF + select GENERIC_PHY + help + Enable this to support Broadcom USB 2.0 PHY connected to the USB + controller on Northstar family. + +config PHY_BCM_NS_USB3 + tristate "Broadcom Northstar USB 3.0 PHY Driver" + depends on ARCH_BCM_IPROC || COMPILE_TEST + depends on HAS_IOMEM && OF + select GENERIC_PHY + help + Enable this to support Broadcom USB 3.0 PHY connected to the USB + controller on Northstar family. + +config PHY_NS2_PCIE + tristate "Broadcom Northstar2 PCIe PHY driver" + depends on OF && MDIO_BUS_MUX_BCM_IPROC + select GENERIC_PHY + default ARCH_BCM_IPROC + help + Enable this to support the Broadcom Northstar2 PCIe PHY. + If unsure, say N. + +config PHY_BRCM_SATA + tristate "Broadcom SATA PHY driver" + depends on ARCH_BRCMSTB || ARCH_BCM_IPROC || BMIPS_GENERIC || COMPILE_TEST + depends on OF + select GENERIC_PHY + default ARCH_BCM_IPROC + help + Enable this to support the Broadcom SATA PHY. + If unsure, say N. diff --git a/drivers/phy/broadcom/Makefile b/drivers/phy/broadcom/Makefile new file mode 100644 index 000000000000..357a7d16529f --- /dev/null +++ b/drivers/phy/broadcom/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o +obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o +obj-$(CONFIG_PHY_BCM_NS_USB2) += phy-bcm-ns-usb2.o +obj-$(CONFIG_PHY_BCM_NS_USB3) += phy-bcm-ns-usb3.o +obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o +obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o diff --git a/drivers/phy/phy-bcm-cygnus-pcie.c b/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c index 0f4ac5d63cff..0f4ac5d63cff 100644 --- a/drivers/phy/phy-bcm-cygnus-pcie.c +++ b/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c diff --git a/drivers/phy/phy-bcm-kona-usb2.c b/drivers/phy/broadcom/phy-bcm-kona-usb2.c index 7b67fe49e30b..7b67fe49e30b 100644 --- a/drivers/phy/phy-bcm-kona-usb2.c +++ b/drivers/phy/broadcom/phy-bcm-kona-usb2.c diff --git a/drivers/phy/phy-bcm-ns-usb2.c b/drivers/phy/broadcom/phy-bcm-ns-usb2.c index 58dff80e9386..58dff80e9386 100644 --- a/drivers/phy/phy-bcm-ns-usb2.c +++ b/drivers/phy/broadcom/phy-bcm-ns-usb2.c diff --git a/drivers/phy/phy-bcm-ns-usb3.c b/drivers/phy/broadcom/phy-bcm-ns-usb3.c index 22b5e7047fa6..22b5e7047fa6 100644 --- a/drivers/phy/phy-bcm-ns-usb3.c +++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c diff --git a/drivers/phy/phy-bcm-ns2-pcie.c b/drivers/phy/broadcom/phy-bcm-ns2-pcie.c index 4c7d11d2b378..4c7d11d2b378 100644 --- a/drivers/phy/phy-bcm-ns2-pcie.c +++ b/drivers/phy/broadcom/phy-bcm-ns2-pcie.c diff --git a/drivers/phy/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c index ccbc3d994998..ccbc3d994998 100644 --- a/drivers/phy/phy-brcm-sata.c +++ b/drivers/phy/broadcom/phy-brcm-sata.c diff --git a/drivers/phy/hisilicon/Kconfig b/drivers/phy/hisilicon/Kconfig new file mode 100644 index 000000000000..6164c4cd0f65 --- /dev/null +++ b/drivers/phy/hisilicon/Kconfig @@ -0,0 +1,20 @@ +# +# Phy drivers for Hisilicon platforms +# +config PHY_HI6220_USB + tristate "hi6220 USB PHY support" + depends on (ARCH_HISI && ARM64) || COMPILE_TEST + select GENERIC_PHY + select MFD_SYSCON + help + Enable this to support the HISILICON HI6220 USB PHY. + + To compile this driver as a module, choose M here. + +config PHY_HIX5HD2_SATA + tristate "HIX5HD2 SATA PHY Driver" + depends on ARCH_HIX5HD2 && OF && HAS_IOMEM + select GENERIC_PHY + select MFD_SYSCON + help + Support for SATA PHY on Hisilicon hix5hd2 Soc. diff --git a/drivers/phy/hisilicon/Makefile b/drivers/phy/hisilicon/Makefile new file mode 100644 index 000000000000..541b348187a8 --- /dev/null +++ b/drivers/phy/hisilicon/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_PHY_HI6220_USB) += phy-hi6220-usb.o +obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o diff --git a/drivers/phy/phy-hi6220-usb.c b/drivers/phy/hisilicon/phy-hi6220-usb.c index 398c1021deec..398c1021deec 100644 --- a/drivers/phy/phy-hi6220-usb.c +++ b/drivers/phy/hisilicon/phy-hi6220-usb.c diff --git a/drivers/phy/phy-hix5hd2-sata.c b/drivers/phy/hisilicon/phy-hix5hd2-sata.c index e5ab3aa78b9d..e5ab3aa78b9d 100644 --- a/drivers/phy/phy-hix5hd2-sata.c +++ b/drivers/phy/hisilicon/phy-hix5hd2-sata.c diff --git a/drivers/phy/marvell/Kconfig b/drivers/phy/marvell/Kconfig new file mode 100644 index 000000000000..048d8893bc2e --- /dev/null +++ b/drivers/phy/marvell/Kconfig @@ -0,0 +1,50 @@ +# +# Phy drivers for Marvell platforms +# +config ARMADA375_USBCLUSTER_PHY + def_bool y + depends on MACH_ARMADA_375 || COMPILE_TEST + depends on OF && HAS_IOMEM + select GENERIC_PHY + +config PHY_BERLIN_SATA + tristate "Marvell Berlin SATA PHY driver" + depends on ARCH_BERLIN && HAS_IOMEM && OF + select GENERIC_PHY + help + Enable this to support the SATA PHY on Marvell Berlin SoCs. + +config PHY_BERLIN_USB + tristate "Marvell Berlin USB PHY Driver" + depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF + select GENERIC_PHY + help + Enable this to support the USB PHY on Marvell Berlin SoCs. + +config PHY_MVEBU_SATA + def_bool y + depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD + depends on OF + select GENERIC_PHY + +config PHY_PXA_28NM_HSIC + tristate "Marvell USB HSIC 28nm PHY Driver" + depends on HAS_IOMEM + select GENERIC_PHY + help + Enable this to support Marvell USB HSIC PHY driver for Marvell + SoC. This driver will do the PHY initialization and shutdown. + The PHY driver will be used by Marvell ehci driver. + + To compile this driver as a module, choose M here. + +config PHY_PXA_28NM_USB2 + tristate "Marvell USB 2.0 28nm PHY Driver" + depends on HAS_IOMEM + select GENERIC_PHY + help + Enable this to support Marvell USB 2.0 PHY driver for Marvell + SoC. This driver will do the PHY initialization and shutdown. + The PHY driver will be used by Marvell udc/ehci/otg driver. + + To compile this driver as a module, choose M here. diff --git a/drivers/phy/marvell/Makefile b/drivers/phy/marvell/Makefile new file mode 100644 index 000000000000..3fc188f59118 --- /dev/null +++ b/drivers/phy/marvell/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o +obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o +obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o +obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o +obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o +obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o diff --git a/drivers/phy/phy-armada375-usb2.c b/drivers/phy/marvell/phy-armada375-usb2.c index 1a3db288c0a9..1a3db288c0a9 100644 --- a/drivers/phy/phy-armada375-usb2.c +++ b/drivers/phy/marvell/phy-armada375-usb2.c diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/marvell/phy-berlin-sata.c index 2c7a57f2d595..2c7a57f2d595 100644 --- a/drivers/phy/phy-berlin-sata.c +++ b/drivers/phy/marvell/phy-berlin-sata.c diff --git a/drivers/phy/phy-berlin-usb.c b/drivers/phy/marvell/phy-berlin-usb.c index 2017751ede26..2017751ede26 100644 --- a/drivers/phy/phy-berlin-usb.c +++ b/drivers/phy/marvell/phy-berlin-usb.c diff --git a/drivers/phy/phy-mvebu-sata.c b/drivers/phy/marvell/phy-mvebu-sata.c index 768ce92e81ce..768ce92e81ce 100644 --- a/drivers/phy/phy-mvebu-sata.c +++ b/drivers/phy/marvell/phy-mvebu-sata.c diff --git a/drivers/phy/phy-pxa-28nm-hsic.c b/drivers/phy/marvell/phy-pxa-28nm-hsic.c index 234aacf4db20..234aacf4db20 100644 --- a/drivers/phy/phy-pxa-28nm-hsic.c +++ b/drivers/phy/marvell/phy-pxa-28nm-hsic.c diff --git a/drivers/phy/phy-pxa-28nm-usb2.c b/drivers/phy/marvell/phy-pxa-28nm-usb2.c index 37e9c8ca4983..37e9c8ca4983 100644 --- a/drivers/phy/phy-pxa-28nm-usb2.c +++ b/drivers/phy/marvell/phy-pxa-28nm-usb2.c diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig new file mode 100644 index 000000000000..7bfa64baf837 --- /dev/null +++ b/drivers/phy/qualcomm/Kconfig @@ -0,0 +1,58 @@ +# +# Phy drivers for Qualcomm platforms +# +config PHY_QCOM_APQ8064_SATA + tristate "Qualcomm APQ8064 SATA SerDes/PHY driver" + depends on ARCH_QCOM + depends on HAS_IOMEM + depends on OF + select GENERIC_PHY + +config PHY_QCOM_IPQ806X_SATA + tristate "Qualcomm IPQ806x SATA SerDes/PHY driver" + depends on ARCH_QCOM + depends on HAS_IOMEM + depends on OF + select GENERIC_PHY + +config PHY_QCOM_QMP + tristate "Qualcomm QMP PHY Driver" + depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST) + select GENERIC_PHY + help + Enable this to support the QMP PHY transceiver that is used + with controllers such as PCIe, UFS, and USB on Qualcomm chips. + +config PHY_QCOM_QUSB2 + tristate "Qualcomm QUSB2 PHY Driver" + depends on OF && (ARCH_QCOM || COMPILE_TEST) + depends on NVMEM || !NVMEM + select GENERIC_PHY + help + Enable this to support the HighSpeed QUSB2 PHY transceiver for USB + controllers on Qualcomm chips. This driver supports the high-speed + PHY which is usually paired with either the ChipIdea or Synopsys DWC3 + USB IPs on MSM SOCs. + +config PHY_QCOM_UFS + tristate "Qualcomm UFS PHY driver" + depends on OF && ARCH_QCOM + select GENERIC_PHY + help + Support for UFS PHY on QCOM chipsets. + +config PHY_QCOM_USB_HS + tristate "Qualcomm USB HS PHY module" + depends on USB_ULPI_BUS + depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in + select GENERIC_PHY + help + Support for the USB high-speed ULPI compliant phy on Qualcomm + chipsets. + +config PHY_QCOM_USB_HSIC + tristate "Qualcomm USB HSIC ULPI PHY module" + depends on USB_ULPI_BUS + select GENERIC_PHY + help + Support for the USB HSIC ULPI compliant PHY on QCOM chipsets. diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile new file mode 100644 index 000000000000..2e183d7695fd --- /dev/null +++ b/drivers/phy/qualcomm/Makefile @@ -0,0 +1,9 @@ +obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o +obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o +obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o +obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o +obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o +obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o +obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o +obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o +obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o diff --git a/drivers/phy/phy-qcom-apq8064-sata.c b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c index 69ce2afac015..69ce2afac015 100644 --- a/drivers/phy/phy-qcom-apq8064-sata.c +++ b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c diff --git a/drivers/phy/phy-qcom-ipq806x-sata.c b/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c index 0ad127cc9298..0ad127cc9298 100644 --- a/drivers/phy/phy-qcom-ipq806x-sata.c +++ b/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c diff --git a/drivers/phy/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index 727e23be7cac..78ca62897784 100644 --- a/drivers/phy/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -844,7 +844,7 @@ static int qcom_qmp_phy_vreg_init(struct device *dev) int num = qmp->cfg->num_vregs; int i; - qmp->vregs = devm_kcalloc(dev, num, sizeof(qmp->vregs), GFP_KERNEL); + qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); if (!qmp->vregs) return -ENOMEM; @@ -983,16 +983,16 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id) * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. */ qphy->tx = of_iomap(np, 0); - if (IS_ERR(qphy->tx)) - return PTR_ERR(qphy->tx); + if (!qphy->tx) + return -ENOMEM; qphy->rx = of_iomap(np, 1); - if (IS_ERR(qphy->rx)) - return PTR_ERR(qphy->rx); + if (!qphy->rx) + return -ENOMEM; qphy->pcs = of_iomap(np, 2); - if (IS_ERR(qphy->pcs)) - return PTR_ERR(qphy->pcs); + if (!qphy->pcs) + return -ENOMEM; /* * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3 diff --git a/drivers/phy/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index 6c575244c0fb..6c575244c0fb 100644 --- a/drivers/phy/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c diff --git a/drivers/phy/phy-qcom-ufs-i.h b/drivers/phy/qualcomm/phy-qcom-ufs-i.h index 13b02b7de30b..13b02b7de30b 100644 --- a/drivers/phy/phy-qcom-ufs-i.h +++ b/drivers/phy/qualcomm/phy-qcom-ufs-i.h diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c index 12a1b498dc4b..12a1b498dc4b 100644 --- a/drivers/phy/phy-qcom-ufs-qmp-14nm.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.h b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.h index 3aefdbacbcd0..3aefdbacbcd0 100644 --- a/drivers/phy/phy-qcom-ufs-qmp-14nm.h +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.h diff --git a/drivers/phy/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c index 4f68acb58b73..4f68acb58b73 100644 --- a/drivers/phy/phy-qcom-ufs-qmp-20nm.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c diff --git a/drivers/phy/phy-qcom-ufs-qmp-20nm.h b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.h index 4f3076bb3d71..4f3076bb3d71 100644 --- a/drivers/phy/phy-qcom-ufs-qmp-20nm.h +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.h diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/qualcomm/phy-qcom-ufs.c index 43865ef340e2..43865ef340e2 100644 --- a/drivers/phy/phy-qcom-ufs.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs.c diff --git a/drivers/phy/phy-qcom-usb-hs.c b/drivers/phy/qualcomm/phy-qcom-usb-hs.c index 94dfbfd739c3..4b20abc3ae2f 100644 --- a/drivers/phy/phy-qcom-usb-hs.c +++ b/drivers/phy/qualcomm/phy-qcom-usb-hs.c @@ -11,12 +11,11 @@ #include <linux/clk.h> #include <linux/regulator/consumer.h> #include <linux/of_device.h> +#include <linux/phy/phy.h> #include <linux/reset.h> #include <linux/extcon.h> #include <linux/notifier.h> -#include "ulpi_phy.h" - #define ULPI_PWR_CLK_MNG_REG 0x88 # define ULPI_PWR_OTG_COMP_DISABLE BIT(0) diff --git a/drivers/phy/phy-qcom-usb-hsic.c b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c index 47690f9945b9..c110563a73cb 100644 --- a/drivers/phy/phy-qcom-usb-hsic.c +++ b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c @@ -8,13 +8,12 @@ #include <linux/module.h> #include <linux/ulpi/driver.h> #include <linux/ulpi/regs.h> +#include <linux/phy/phy.h> #include <linux/pinctrl/consumer.h> #include <linux/pinctrl/pinctrl-state.h> #include <linux/delay.h> #include <linux/clk.h> -#include "ulpi_phy.h" - #define ULPI_HSIC_CFG 0x30 #define ULPI_HSIC_IO_CAL 0x33 diff --git a/drivers/phy/renesas/Kconfig b/drivers/phy/renesas/Kconfig new file mode 100644 index 000000000000..432e2715e9c4 --- /dev/null +++ b/drivers/phy/renesas/Kconfig @@ -0,0 +1,17 @@ +# +# Phy drivers for Renesas platforms +# +config PHY_RCAR_GEN2 + tristate "Renesas R-Car generation 2 USB PHY driver" + depends on ARCH_RENESAS + depends on GENERIC_PHY + help + Support for USB PHY found on Renesas R-Car generation 2 SoCs. + +config PHY_RCAR_GEN3_USB2 + tristate "Renesas R-Car generation 3 USB 2.0 PHY driver" + depends on ARCH_RENESAS + depends on EXTCON + select GENERIC_PHY + help + Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs. diff --git a/drivers/phy/renesas/Makefile b/drivers/phy/renesas/Makefile new file mode 100644 index 000000000000..695241aebf69 --- /dev/null +++ b/drivers/phy/renesas/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o +obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/renesas/phy-rcar-gen2.c index 97d4dd6ea924..97d4dd6ea924 100644 --- a/drivers/phy/phy-rcar-gen2.c +++ b/drivers/phy/renesas/phy-rcar-gen2.c diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index 54c34298a000..54c34298a000 100644 --- a/drivers/phy/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig new file mode 100644 index 000000000000..f5325b2b679e --- /dev/null +++ b/drivers/phy/rockchip/Kconfig @@ -0,0 +1,51 @@ +# +# Phy drivers for Rockchip platforms +# +config PHY_ROCKCHIP_DP + tristate "Rockchip Display Port PHY Driver" + depends on ARCH_ROCKCHIP && OF + select GENERIC_PHY + help + Enable this to support the Rockchip Display Port PHY. + +config PHY_ROCKCHIP_EMMC + tristate "Rockchip EMMC PHY Driver" + depends on ARCH_ROCKCHIP && OF + select GENERIC_PHY + help + Enable this to support the Rockchip EMMC PHY. + +config PHY_ROCKCHIP_INNO_USB2 + tristate "Rockchip INNO USB2PHY Driver" + depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF + depends on COMMON_CLK + depends on EXTCON + depends on USB_SUPPORT + select GENERIC_PHY + select USB_COMMON + help + Support for Rockchip USB2.0 PHY with Innosilicon IP block. + +config PHY_ROCKCHIP_PCIE + tristate "Rockchip PCIe PHY Driver" + depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST + select GENERIC_PHY + select MFD_SYSCON + help + Enable this to support the Rockchip PCIe PHY. + +config PHY_ROCKCHIP_TYPEC + tristate "Rockchip TYPEC PHY Driver" + depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST) + select EXTCON + select GENERIC_PHY + select RESET_CONTROLLER + help + Enable this to support the Rockchip USB TYPEC PHY. + +config PHY_ROCKCHIP_USB + tristate "Rockchip USB2 PHY Driver" + depends on ARCH_ROCKCHIP && OF + select GENERIC_PHY + help + Enable this to support the Rockchip USB 2.0 PHY. diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile new file mode 100644 index 000000000000..bd0acdf38e0f --- /dev/null +++ b/drivers/phy/rockchip/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o +obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o +obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o +obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o +obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o +obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o diff --git a/drivers/phy/phy-rockchip-dp.c b/drivers/phy/rockchip/phy-rockchip-dp.c index 8b267a746576..8b267a746576 100644 --- a/drivers/phy/phy-rockchip-dp.c +++ b/drivers/phy/rockchip/phy-rockchip-dp.c diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/rockchip/phy-rockchip-emmc.c index f1b24f18e9b2..f1b24f18e9b2 100644 --- a/drivers/phy/phy-rockchip-emmc.c +++ b/drivers/phy/rockchip/phy-rockchip-emmc.c diff --git a/drivers/phy/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 8efe78a49916..8efe78a49916 100644 --- a/drivers/phy/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c diff --git a/drivers/phy/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c index 6904633cad68..6904633cad68 100644 --- a/drivers/phy/phy-rockchip-pcie.c +++ b/drivers/phy/rockchip/phy-rockchip-pcie.c diff --git a/drivers/phy/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c index 7cfb0f8995de..7cfb0f8995de 100644 --- a/drivers/phy/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/rockchip/phy-rockchip-usb.c index 3378eeb7a562..3378eeb7a562 100644 --- a/drivers/phy/phy-rockchip-usb.c +++ b/drivers/phy/rockchip/phy-rockchip-usb.c diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig new file mode 100644 index 000000000000..b7e0645a7bd9 --- /dev/null +++ b/drivers/phy/samsung/Kconfig @@ -0,0 +1,95 @@ +# +# Phy drivers for Samsung platforms +# +config PHY_EXYNOS_DP_VIDEO + tristate "EXYNOS SoC series Display Port PHY driver" + depends on OF + depends on ARCH_EXYNOS || COMPILE_TEST + default ARCH_EXYNOS + select GENERIC_PHY + help + Support for Display Port PHY found on Samsung EXYNOS SoCs. + +config PHY_EXYNOS_MIPI_VIDEO + tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver" + depends on HAS_IOMEM + depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST + select GENERIC_PHY + default y if ARCH_S5PV210 || ARCH_EXYNOS + help + Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P + and EXYNOS SoCs. + +config PHY_EXYNOS_PCIE + bool "Exynos PCIe PHY driver" + depends on OF && (ARCH_EXYNOS || COMPILE_TEST) + select GENERIC_PHY + help + Enable PCIe PHY support for Exynos SoC series. + This driver provides PHY interface for Exynos PCIe controller. + +config PHY_SAMSUNG_USB2 + tristate "Samsung USB 2.0 PHY driver" + depends on HAS_IOMEM + depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2 + select GENERIC_PHY + select MFD_SYSCON + default ARCH_EXYNOS + help + Enable this to support the Samsung USB 2.0 PHY driver for Samsung + SoCs. This driver provides the interface for USB 2.0 PHY. Support + for particular PHYs will be enabled based on the SoC type in addition + to this driver. + +config PHY_EXYNOS4210_USB2 + bool + depends on PHY_SAMSUNG_USB2 + default CPU_EXYNOS4210 + +config PHY_EXYNOS4X12_USB2 + bool + depends on PHY_SAMSUNG_USB2 + default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412 + +config PHY_EXYNOS5250_USB2 + bool + depends on PHY_SAMSUNG_USB2 + default SOC_EXYNOS5250 || SOC_EXYNOS5420 + +config PHY_S5PV210_USB2 + bool "Support for S5PV210" + depends on PHY_SAMSUNG_USB2 + depends on ARCH_S5PV210 + help + Enable USB PHY support for S5PV210. This option requires that Samsung + USB 2.0 PHY driver is enabled and means that support for this + particular SoC is compiled in the driver. In case of S5PV210 two phys + are available - device and host. + +config PHY_EXYNOS5_USBDRD + tristate "Exynos5 SoC series USB DRD PHY driver" + depends on ARCH_EXYNOS && OF + depends on HAS_IOMEM + depends on USB_DWC3_EXYNOS + select GENERIC_PHY + select MFD_SYSCON + default y + help + Enable USB DRD PHY support for Exynos 5 SoC series. + This driver provides PHY interface for USB 3.0 DRD controller + present on Exynos5 SoC series. + +config PHY_EXYNOS5250_SATA + tristate "Exynos5250 Sata SerDes/PHY driver" + depends on SOC_EXYNOS5250 + depends on HAS_IOMEM + depends on OF + select GENERIC_PHY + select I2C + select I2C_S3C2410 + select MFD_SYSCON + help + Enable this to support SATA SerDes/Phy found on Samsung's + Exynos5250 based SoCs.This SerDes/Phy supports SATA 1.5 Gb/s, + SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host + port to accept one SATA device. diff --git a/drivers/phy/samsung/Makefile b/drivers/phy/samsung/Makefile new file mode 100644 index 000000000000..20d7f2424772 --- /dev/null +++ b/drivers/phy/samsung/Makefile @@ -0,0 +1,11 @@ +obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o +obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o +obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o +obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o +phy-exynos-usb2-y += phy-samsung-usb2.o +phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o +phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o +phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o +phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o +obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o +obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/samsung/phy-exynos-dp-video.c index bb3279dbf88c..bb3279dbf88c 100644 --- a/drivers/phy/phy-exynos-dp-video.c +++ b/drivers/phy/samsung/phy-exynos-dp-video.c diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/samsung/phy-exynos-mipi-video.c index c198886f80a3..c198886f80a3 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/samsung/phy-exynos-mipi-video.c diff --git a/drivers/phy/phy-exynos-pcie.c b/drivers/phy/samsung/phy-exynos-pcie.c index a89c12faff39..a89c12faff39 100644 --- a/drivers/phy/phy-exynos-pcie.c +++ b/drivers/phy/samsung/phy-exynos-pcie.c diff --git a/drivers/phy/phy-exynos4210-usb2.c b/drivers/phy/samsung/phy-exynos4210-usb2.c index 1f50e1004828..1f50e1004828 100644 --- a/drivers/phy/phy-exynos4210-usb2.c +++ b/drivers/phy/samsung/phy-exynos4210-usb2.c diff --git a/drivers/phy/phy-exynos4x12-usb2.c b/drivers/phy/samsung/phy-exynos4x12-usb2.c index 7f27a91acf87..7f27a91acf87 100644 --- a/drivers/phy/phy-exynos4x12-usb2.c +++ b/drivers/phy/samsung/phy-exynos4x12-usb2.c diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 7c41daa2c625..7c41daa2c625 100644 --- a/drivers/phy/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c diff --git a/drivers/phy/phy-exynos5250-sata.c b/drivers/phy/samsung/phy-exynos5250-sata.c index 60e13afcd9b8..60e13afcd9b8 100644 --- a/drivers/phy/phy-exynos5250-sata.c +++ b/drivers/phy/samsung/phy-exynos5250-sata.c diff --git a/drivers/phy/phy-exynos5250-usb2.c b/drivers/phy/samsung/phy-exynos5250-usb2.c index aad806272305..aad806272305 100644 --- a/drivers/phy/phy-exynos5250-usb2.c +++ b/drivers/phy/samsung/phy-exynos5250-usb2.c diff --git a/drivers/phy/phy-s5pv210-usb2.c b/drivers/phy/samsung/phy-s5pv210-usb2.c index f6f72339bbc3..f6f72339bbc3 100644 --- a/drivers/phy/phy-s5pv210-usb2.c +++ b/drivers/phy/samsung/phy-s5pv210-usb2.c diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/samsung/phy-samsung-usb2.c index 1d22d93b552d..1d22d93b552d 100644 --- a/drivers/phy/phy-samsung-usb2.c +++ b/drivers/phy/samsung/phy-samsung-usb2.c diff --git a/drivers/phy/phy-samsung-usb2.h b/drivers/phy/samsung/phy-samsung-usb2.h index 6563e7ca0ac4..6563e7ca0ac4 100644 --- a/drivers/phy/phy-samsung-usb2.h +++ b/drivers/phy/samsung/phy-samsung-usb2.h diff --git a/drivers/phy/st/Kconfig b/drivers/phy/st/Kconfig new file mode 100644 index 000000000000..0814d3f87ec6 --- /dev/null +++ b/drivers/phy/st/Kconfig @@ -0,0 +1,33 @@ +# +# Phy drivers for STMicro platforms +# +config PHY_MIPHY28LP + tristate "STMicroelectronics MIPHY28LP PHY driver for STiH407" + depends on ARCH_STI + select GENERIC_PHY + help + Enable this to support the miphy transceiver (for SATA/PCIE/USB3) + that is part of STMicroelectronics STiH407 SoC. + +config PHY_ST_SPEAR1310_MIPHY + tristate "ST SPEAR1310-MIPHY driver" + select GENERIC_PHY + depends on MACH_SPEAR1310 || COMPILE_TEST + help + Support for ST SPEAr1310 MIPHY which can be used for PCIe and SATA. + +config PHY_ST_SPEAR1340_MIPHY + tristate "ST SPEAR1340-MIPHY driver" + select GENERIC_PHY + depends on MACH_SPEAR1340 || COMPILE_TEST + help + Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA. + +config PHY_STIH407_USB + tristate "STMicroelectronics USB2 picoPHY driver for STiH407 family" + depends on RESET_CONTROLLER + depends on ARCH_STI || COMPILE_TEST + select GENERIC_PHY + help + Enable this support to enable the picoPHY device used by USB2 + and USB3 controllers on STMicroelectronics STiH407 SoC families. diff --git a/drivers/phy/st/Makefile b/drivers/phy/st/Makefile new file mode 100644 index 000000000000..e2adfe2166d2 --- /dev/null +++ b/drivers/phy/st/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o +obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o +obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o +obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/st/phy-miphy28lp.c index 213e2e15339c..213e2e15339c 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/st/phy-miphy28lp.c diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/st/phy-spear1310-miphy.c index ed67e98e54ca..ed67e98e54ca 100644 --- a/drivers/phy/phy-spear1310-miphy.c +++ b/drivers/phy/st/phy-spear1310-miphy.c diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/st/phy-spear1340-miphy.c index 97280c0cf612..97280c0cf612 100644 --- a/drivers/phy/phy-spear1340-miphy.c +++ b/drivers/phy/st/phy-spear1340-miphy.c diff --git a/drivers/phy/phy-stih407-usb.c b/drivers/phy/st/phy-stih407-usb.c index b1f44ab669fb..b1f44ab669fb 100644 --- a/drivers/phy/phy-stih407-usb.c +++ b/drivers/phy/st/phy-stih407-usb.c diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig new file mode 100644 index 000000000000..20503562666c --- /dev/null +++ b/drivers/phy/ti/Kconfig @@ -0,0 +1,78 @@ +# +# Phy drivers for TI platforms +# +config PHY_DA8XX_USB + tristate "TI DA8xx USB PHY Driver" + depends on ARCH_DAVINCI_DA8XX + select GENERIC_PHY + select MFD_SYSCON + help + Enable this to support the USB PHY on DA8xx SoCs. + + This driver controls both the USB 1.1 PHY and the USB 2.0 PHY. + +config PHY_DM816X_USB + tristate "TI dm816x USB PHY driver" + depends on ARCH_OMAP2PLUS + depends on USB_SUPPORT + select GENERIC_PHY + select USB_PHY + help + Enable this for dm816x USB to work. + +config OMAP_CONTROL_PHY + tristate "OMAP CONTROL PHY Driver" + depends on ARCH_OMAP2PLUS || COMPILE_TEST + help + Enable this to add support for the PHY part present in the control + module. This driver has API to power on the USB2 PHY and to write to + the mailbox. The mailbox is present only in omap4 and the register to + power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an + additional register to power on USB3 PHY/SATA PHY/PCIE PHY + (PIPE3 PHY). + +config OMAP_USB2 + tristate "OMAP USB2 PHY Driver" + depends on ARCH_OMAP2PLUS + depends on USB_SUPPORT + select GENERIC_PHY + select USB_PHY + select OMAP_CONTROL_PHY + depends on OMAP_OCP2SCP + help + Enable this to support the transceiver that is part of SOC. This + driver takes care of all the PHY functionality apart from comparator. + The USB OTG controller communicates with the comparator using this + driver. + +config TI_PIPE3 + tristate "TI PIPE3 PHY Driver" + depends on ARCH_OMAP2PLUS || COMPILE_TEST + select GENERIC_PHY + select OMAP_CONTROL_PHY + depends on OMAP_OCP2SCP + help + Enable this to support the PIPE3 PHY that is part of TI SOCs. This + driver takes care of all the PHY functionality apart from comparator. + This driver interacts with the "OMAP Control PHY Driver" to power + on/off the PHY. + +config PHY_TUSB1210 + tristate "TI TUSB1210 ULPI PHY module" + depends on USB_ULPI_BUS + select GENERIC_PHY + help + Support for TI TUSB1210 USB ULPI PHY. + +config TWL4030_USB + tristate "TWL4030 USB Transceiver Driver" + depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS + depends on USB_SUPPORT + depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't 'y' + select GENERIC_PHY + select USB_PHY + help + Enable this to support the USB OTG transceiver on TWL4030 + family chips (including the TWL5030 and TPS659x0 devices). + This transceiver supports high and full speed devices plus, + in host mode, low speed. diff --git a/drivers/phy/ti/Makefile b/drivers/phy/ti/Makefile new file mode 100644 index 000000000000..0cc3a1a557a3 --- /dev/null +++ b/drivers/phy/ti/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o +obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o +obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o +obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o +obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o +obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o +obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o diff --git a/drivers/phy/phy-da8xx-usb.c b/drivers/phy/ti/phy-da8xx-usb.c index 1b82bff6330f..1b82bff6330f 100644 --- a/drivers/phy/phy-da8xx-usb.c +++ b/drivers/phy/ti/phy-da8xx-usb.c diff --git a/drivers/phy/phy-dm816x-usb.c b/drivers/phy/ti/phy-dm816x-usb.c index cbcce7cf0028..cbcce7cf0028 100644 --- a/drivers/phy/phy-dm816x-usb.c +++ b/drivers/phy/ti/phy-dm816x-usb.c diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/ti/phy-omap-control.c index e9c41b3fa0ee..e9c41b3fa0ee 100644 --- a/drivers/phy/phy-omap-control.c +++ b/drivers/phy/ti/phy-omap-control.c diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c index fe909fd8144f..fe909fd8144f 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/ti/phy-omap-usb2.c diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/ti/phy-ti-pipe3.c index 9c84d32c6f60..9c84d32c6f60 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/ti/phy-ti-pipe3.c diff --git a/drivers/phy/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c index 4f6d5e71507d..bb3fb031c478 100644 --- a/drivers/phy/phy-tusb1210.c +++ b/drivers/phy/ti/phy-tusb1210.c @@ -12,8 +12,7 @@ #include <linux/module.h> #include <linux/ulpi/driver.h> #include <linux/gpio/consumer.h> - -#include "ulpi_phy.h" +#include <linux/phy/ulpi_phy.h> #define TUSB1210_VENDOR_SPECIFIC2 0x80 #define TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT 0 diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/ti/phy-twl4030-usb.c index 2990b3965460..2990b3965460 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/ti/phy-twl4030-usb.c diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 1653cbda6a82..bd459a93b0e7 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -680,30 +680,16 @@ EXPORT_SYMBOL_GPL(pinctrl_generic_remove_group); * pinctrl_generic_free_groups() - removes all pin groups * @pctldev: pin controller device * - * Note that the caller must take care of locking. + * Note that the caller must take care of locking. The pinctrl groups + * are allocated with devm_kzalloc() so no need to free them here. */ static void pinctrl_generic_free_groups(struct pinctrl_dev *pctldev) { struct radix_tree_iter iter; - struct group_desc *group; - unsigned long *indices; void **slot; - int i = 0; - - indices = devm_kzalloc(pctldev->dev, sizeof(*indices) * - pctldev->num_groups, GFP_KERNEL); - if (!indices) - return; radix_tree_for_each_slot(slot, &pctldev->pin_group_tree, &iter, 0) - indices[i++] = iter.index; - - for (i = 0; i < pctldev->num_groups; i++) { - group = radix_tree_lookup(&pctldev->pin_group_tree, - indices[i]); - radix_tree_delete(&pctldev->pin_group_tree, indices[i]); - devm_kfree(pctldev->dev, group); - } + radix_tree_delete(&pctldev->pin_group_tree, iter.index); pctldev->num_groups = 0; } diff --git a/drivers/pinctrl/freescale/pinctrl-mxs.c b/drivers/pinctrl/freescale/pinctrl-mxs.c index 41b5b07d5a2b..6852010a6d70 100644 --- a/drivers/pinctrl/freescale/pinctrl-mxs.c +++ b/drivers/pinctrl/freescale/pinctrl-mxs.c @@ -194,6 +194,16 @@ static int mxs_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, return 0; } +static void mxs_pinctrl_rmwl(u32 value, u32 mask, u8 shift, void __iomem *reg) +{ + u32 tmp; + + tmp = readl(reg); + tmp &= ~(mask << shift); + tmp |= value << shift; + writel(tmp, reg); +} + static int mxs_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { @@ -211,8 +221,7 @@ static int mxs_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned selector, reg += bank * 0x20 + pin / 16 * 0x10; shift = pin % 16 * 2; - writel(0x3 << shift, reg + CLR); - writel(g->muxsel[i] << shift, reg + SET); + mxs_pinctrl_rmwl(g->muxsel[i], 0x3, shift, reg); } return 0; @@ -279,8 +288,7 @@ static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev, /* mA */ if (config & MA_PRESENT) { shift = pin % 8 * 4; - writel(0x3 << shift, reg + CLR); - writel(ma << shift, reg + SET); + mxs_pinctrl_rmwl(ma, 0x3, shift, reg); } /* vol */ diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 2debba62fac9..20f1b4493994 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1539,15 +1539,29 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) * is not listed below. */ static const struct dmi_system_id chv_no_valid_mask[] = { + /* See https://bugzilla.kernel.org/show_bug.cgi?id=194945 */ { - /* See https://bugzilla.kernel.org/show_bug.cgi?id=194945 */ - .ident = "Acer Chromebook (CYAN)", + .ident = "Intel_Strago based Chromebooks (All models)", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), - DMI_MATCH(DMI_PRODUCT_NAME, "Edgar"), - DMI_MATCH(DMI_BIOS_DATE, "05/21/2016"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_Strago"), }, - } + }, + { + .ident = "Acer Chromebook R11 (Cyan)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"), + }, + }, + { + .ident = "Samsung Chromebook 3 (Celes)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Celes"), + }, + }, + {} }; static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 0d6b7f4b82af..720a19fd38d2 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -35,7 +35,6 @@ static const struct pin_config_item conf_items[] = { PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, "input bias pull to pin specific state", NULL, false), PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL, false), - PCONFDUMP(PIN_CONFIG_BIDIRECTIONAL, "bi-directional pin operations", NULL, false), PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL, false), PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL, false), PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL, false), @@ -161,7 +160,6 @@ static const struct pinconf_generic_params dt_params[] = { { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 }, { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, - { "bi-directional", PIN_CONFIG_BIDIRECTIONAL, 1 }, { "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 }, { "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 }, { "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 }, @@ -174,7 +172,6 @@ static const struct pinconf_generic_params dt_params[] = { { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, { "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 }, { "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 }, - { "output-enable", PIN_CONFIG_OUTPUT, 1, }, { "output-high", PIN_CONFIG_OUTPUT, 1, }, { "output-low", PIN_CONFIG_OUTPUT, 0, }, { "power-source", PIN_CONFIG_POWER_SOURCE, 0 }, diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 9fd6d9087dc5..16b3ae5e4f44 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -826,30 +826,17 @@ EXPORT_SYMBOL_GPL(pinmux_generic_remove_function); * pinmux_generic_free_functions() - removes all functions * @pctldev: pin controller device * - * Note that the caller must take care of locking. + * Note that the caller must take care of locking. The pinctrl + * functions are allocated with devm_kzalloc() so no need to free + * them here. */ void pinmux_generic_free_functions(struct pinctrl_dev *pctldev) { struct radix_tree_iter iter; - struct function_desc *function; - unsigned long *indices; void **slot; - int i = 0; - - indices = devm_kzalloc(pctldev->dev, sizeof(*indices) * - pctldev->num_functions, GFP_KERNEL); - if (!indices) - return; radix_tree_for_each_slot(slot, &pctldev->pin_function_tree, &iter, 0) - indices[i++] = iter.index; - - for (i = 0; i < pctldev->num_functions; i++) { - function = radix_tree_lookup(&pctldev->pin_function_tree, - indices[i]); - radix_tree_delete(&pctldev->pin_function_tree, indices[i]); - devm_kfree(pctldev->dev, function); - } + radix_tree_delete(&pctldev->pin_function_tree, iter.index); pctldev->num_functions = 0; } diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c index 9aec1d2232dd..6624499eae72 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c @@ -394,7 +394,7 @@ static const struct sunxi_desc_pin sun8i_a83t_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 18), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "owa")), /* DOUT */ + SUNXI_FUNCTION(0x3, "spdif")), /* DOUT */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 19), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out")), diff --git a/drivers/platform/goldfish/goldfish_pipe.c b/drivers/platform/goldfish/goldfish_pipe.c index 2de1e603bd2b..5f3672153b12 100644 --- a/drivers/platform/goldfish/goldfish_pipe.c +++ b/drivers/platform/goldfish/goldfish_pipe.c @@ -704,7 +704,7 @@ static int get_free_pipe_id_locked(struct goldfish_pipe_dev *dev) /* Reallocate the array */ u32 new_capacity = 2 * dev->pipes_capacity; struct goldfish_pipe **pipes = - kcalloc(new_capacity, sizeof(*pipes), GFP_KERNEL); + kcalloc(new_capacity, sizeof(*pipes), GFP_ATOMIC); if (!pipes) return -ENOMEM; memcpy(pipes, dev->pipes, sizeof(*pipes) * dev->pipes_capacity); diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index d21c07ccc94e..61fabf6ddaec 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -34,6 +34,13 @@ config RESET_BERLIN help This enables the reset controller driver for Marvell Berlin SoCs. +config RESET_GEMINI + bool "Gemini Reset Driver" if COMPILE_TEST + default ARCH_GEMINI + select MFD_SYSCON + help + This enables the reset controller driver for Cortina Systems Gemini. + config RESET_IMX7 bool "i.MX7 Reset Driver" if COMPILE_TEST default SOC_IMX7D @@ -80,7 +87,7 @@ config RESET_SUNXI help This enables the reset driver for Allwinner SoCs. -config TI_SYSCON_RESET +config RESET_TI_SYSCON tristate "TI SYSCON Reset Driver" depends on HAS_IOMEM select MFD_SYSCON diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 02a74db94339..e422a04f7b85 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o obj-$(CONFIG_RESET_ATH79) += reset-ath79.o obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o +obj-$(CONFIG_RESET_GEMINI) += reset-gemini.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o obj-$(CONFIG_RESET_MESON) += reset-meson.o @@ -13,7 +14,7 @@ obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_RESET_STM32) += reset-stm32.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o -obj-$(CONFIG_TI_SYSCON_RESET) += reset-ti-syscon.o +obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_RESET_ZX2967) += reset-zx2967.o obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c index 35ce53edabf9..d5e5229308f2 100644 --- a/drivers/reset/hisilicon/hi6220_reset.c +++ b/drivers/reset/hisilicon/hi6220_reset.c @@ -155,3 +155,5 @@ static int __init hi6220_reset_init(void) } postcore_initcall(hi6220_reset_init); + +MODULE_LICENSE("GPL v2"); diff --git a/drivers/reset/reset-gemini.c b/drivers/reset/reset-gemini.c new file mode 100644 index 000000000000..a2478997c75b --- /dev/null +++ b/drivers/reset/reset-gemini.c @@ -0,0 +1,110 @@ +/* + * Cortina Gemini Reset controller driver + * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/err.h> +#include <linux/init.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/reset-controller.h> +#include <dt-bindings/reset/cortina,gemini-reset.h> + +/** + * struct gemini_reset - gemini reset controller + * @map: regmap to access the containing system controller + * @rcdev: reset controller device + */ +struct gemini_reset { + struct regmap *map; + struct reset_controller_dev rcdev; +}; + +#define GEMINI_GLOBAL_SOFT_RESET 0x0c + +#define to_gemini_reset(p) \ + container_of((p), struct gemini_reset, rcdev) + +/* + * This is a self-deasserting reset controller. + */ +static int gemini_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct gemini_reset *gr = to_gemini_reset(rcdev); + + /* Manual says to always set BIT 30 (CPU1) to 1 */ + return regmap_write(gr->map, + GEMINI_GLOBAL_SOFT_RESET, + BIT(GEMINI_RESET_CPU1) | BIT(id)); +} + +static int gemini_reset_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct gemini_reset *gr = to_gemini_reset(rcdev); + u32 val; + int ret; + + ret = regmap_read(gr->map, GEMINI_GLOBAL_SOFT_RESET, &val); + if (ret) + return ret; + + return !!(val & BIT(id)); +} + +static const struct reset_control_ops gemini_reset_ops = { + .reset = gemini_reset, + .status = gemini_reset_status, +}; + +static int gemini_reset_probe(struct platform_device *pdev) +{ + struct gemini_reset *gr; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + int ret; + + gr = devm_kzalloc(dev, sizeof(*gr), GFP_KERNEL); + if (!gr) + return -ENOMEM; + + gr->map = syscon_node_to_regmap(np); + if (IS_ERR(gr->map)) { + ret = PTR_ERR(gr->map); + dev_err(dev, "unable to get regmap (%d)", ret); + return ret; + } + gr->rcdev.owner = THIS_MODULE; + gr->rcdev.nr_resets = 32; + gr->rcdev.ops = &gemini_reset_ops; + gr->rcdev.of_node = pdev->dev.of_node; + + ret = devm_reset_controller_register(&pdev->dev, &gr->rcdev); + if (ret) + return ret; + + dev_info(dev, "registered Gemini reset controller\n"); + return 0; +} + +static const struct of_device_id gemini_reset_dt_ids[] = { + { .compatible = "cortina,gemini-syscon", }, + { /* sentinel */ }, +}; + +static struct platform_driver gemini_reset_driver = { + .probe = gemini_reset_probe, + .driver = { + .name = "gemini-reset", + .of_match_table = gemini_reset_dt_ids, + .suppress_bind_attrs = true, + }, +}; +builtin_platform_driver(gemini_reset_driver); diff --git a/drivers/reset/sti/reset-syscfg.c b/drivers/reset/sti/reset-syscfg.c index 9bd57a5eee72..7e0f2aa55ba7 100644 --- a/drivers/reset/sti/reset-syscfg.c +++ b/drivers/reset/sti/reset-syscfg.c @@ -145,16 +145,14 @@ static int syscfg_reset_controller_register(struct device *dev, const struct syscfg_reset_controller_data *data) { struct syscfg_reset_controller *rc; - size_t size; int i, err; rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL); if (!rc) return -ENOMEM; - size = sizeof(struct syscfg_reset_channel) * data->nr_channels; - - rc->channels = devm_kzalloc(dev, size, GFP_KERNEL); + rc->channels = devm_kcalloc(dev, data->nr_channels, + sizeof(*rc->channels), GFP_KERNEL); if (!rc->channels) return -ENOMEM; diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig index 0acb8c2f9475..31f014b57bfc 100644 --- a/drivers/s390/block/Kconfig +++ b/drivers/s390/block/Kconfig @@ -82,10 +82,3 @@ config SCM_BLOCK To compile this driver as a module, choose M here: the module will be called scm_block. - -config SCM_BLOCK_CLUSTER_WRITE - def_bool y - prompt "SCM force cluster writes" - depends on SCM_BLOCK - help - Force writes to Storage Class Memory (SCM) to be in done in clusters. diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile index c2f4e673e031..b64e2b32c753 100644 --- a/drivers/s390/block/Makefile +++ b/drivers/s390/block/Makefile @@ -19,7 +19,4 @@ obj-$(CONFIG_BLK_DEV_XPRAM) += xpram.o obj-$(CONFIG_DCSSBLK) += dcssblk.o scm_block-objs := scm_drv.o scm_blk.o -ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE -scm_block-objs += scm_blk_cluster.o -endif obj-$(CONFIG_SCM_BLOCK) += scm_block.o diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 1164b51d09f3..05e5762d045e 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -315,45 +315,58 @@ static int __init dasd_parse_range(const char *range) char *features_str = NULL; char *from_str = NULL; char *to_str = NULL; - size_t len = strlen(range) + 1; - char tmp[len]; + int rc = 0; + char *tmp; - strlcpy(tmp, range, len); + tmp = kstrdup(range, GFP_KERNEL); + if (!tmp) + return -ENOMEM; - if (dasd_evaluate_range_param(tmp, &from_str, &to_str, &features_str)) - goto out_err; + if (dasd_evaluate_range_param(tmp, &from_str, &to_str, &features_str)) { + rc = -EINVAL; + goto out; + } - if (dasd_busid(from_str, &from_id0, &from_id1, &from)) - goto out_err; + if (dasd_busid(from_str, &from_id0, &from_id1, &from)) { + rc = -EINVAL; + goto out; + } to = from; to_id0 = from_id0; to_id1 = from_id1; if (to_str) { - if (dasd_busid(to_str, &to_id0, &to_id1, &to)) - goto out_err; + if (dasd_busid(to_str, &to_id0, &to_id1, &to)) { + rc = -EINVAL; + goto out; + } if (from_id0 != to_id0 || from_id1 != to_id1 || from > to) { pr_err("%s is not a valid device range\n", range); - goto out_err; + rc = -EINVAL; + goto out; } } features = dasd_feature_list(features_str); - if (features < 0) - goto out_err; + if (features < 0) { + rc = -EINVAL; + goto out; + } /* each device in dasd= parameter should be set initially online */ features |= DASD_FEATURE_INITIAL_ONLINE; while (from <= to) { sprintf(bus_id, "%01x.%01x.%04x", from_id0, from_id1, from++); devmap = dasd_add_busid(bus_id, features); - if (IS_ERR(devmap)) - return PTR_ERR(devmap); + if (IS_ERR(devmap)) { + rc = PTR_ERR(devmap); + goto out; + } } - return 0; +out: + kfree(tmp); -out_err: - return -EINVAL; + return rc; } /* diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c index 152de6817875..71c0158aa0c3 100644 --- a/drivers/s390/block/scm_blk.c +++ b/drivers/s390/block/scm_blk.c @@ -13,6 +13,7 @@ #include <linux/mempool.h> #include <linux/module.h> #include <linux/blkdev.h> +#include <linux/blk-mq.h> #include <linux/genhd.h> #include <linux/slab.h> #include <linux/list.h> @@ -42,7 +43,6 @@ static void __scm_free_rq(struct scm_request *scmrq) struct aob_rq_header *aobrq = to_aobrq(scmrq); free_page((unsigned long) scmrq->aob); - __scm_free_rq_cluster(scmrq); kfree(scmrq->request); kfree(aobrq); } @@ -82,9 +82,6 @@ static int __scm_alloc_rq(void) if (!scmrq->request) goto free; - if (__scm_alloc_rq_cluster(scmrq)) - goto free; - INIT_LIST_HEAD(&scmrq->list); spin_lock_irq(&list_lock); list_add(&scmrq->list, &inactive_requests); @@ -114,13 +111,13 @@ static struct scm_request *scm_request_fetch(void) { struct scm_request *scmrq = NULL; - spin_lock(&list_lock); + spin_lock_irq(&list_lock); if (list_empty(&inactive_requests)) goto out; scmrq = list_first_entry(&inactive_requests, struct scm_request, list); list_del(&scmrq->list); out: - spin_unlock(&list_lock); + spin_unlock_irq(&list_lock); return scmrq; } @@ -234,130 +231,123 @@ static inline void scm_request_init(struct scm_blk_dev *bdev, scmrq->error = 0; /* We don't use all msbs - place aidaws at the end of the aob page. */ scmrq->next_aidaw = (void *) &aob->msb[nr_requests_per_io]; - scm_request_cluster_init(scmrq); -} - -static void scm_ensure_queue_restart(struct scm_blk_dev *bdev) -{ - if (atomic_read(&bdev->queued_reqs)) { - /* Queue restart is triggered by the next interrupt. */ - return; - } - blk_delay_queue(bdev->rq, SCM_QUEUE_DELAY); } -void scm_request_requeue(struct scm_request *scmrq) +static void scm_request_requeue(struct scm_request *scmrq) { struct scm_blk_dev *bdev = scmrq->bdev; int i; - scm_release_cluster(scmrq); for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++) - blk_requeue_request(bdev->rq, scmrq->request[i]); + blk_mq_requeue_request(scmrq->request[i], false); atomic_dec(&bdev->queued_reqs); scm_request_done(scmrq); - scm_ensure_queue_restart(bdev); + blk_mq_kick_requeue_list(bdev->rq); } -void scm_request_finish(struct scm_request *scmrq) +static void scm_request_finish(struct scm_request *scmrq) { struct scm_blk_dev *bdev = scmrq->bdev; int i; - scm_release_cluster(scmrq); - for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++) - blk_end_request_all(scmrq->request[i], scmrq->error); + for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++) { + if (scmrq->error) + blk_mq_end_request(scmrq->request[i], scmrq->error); + else + blk_mq_complete_request(scmrq->request[i]); + } atomic_dec(&bdev->queued_reqs); scm_request_done(scmrq); } -static int scm_request_start(struct scm_request *scmrq) +static void scm_request_start(struct scm_request *scmrq) { struct scm_blk_dev *bdev = scmrq->bdev; - int ret; atomic_inc(&bdev->queued_reqs); - if (!scmrq->aob->request.msb_count) { - scm_request_requeue(scmrq); - return -EINVAL; - } - - ret = eadm_start_aob(scmrq->aob); - if (ret) { + if (eadm_start_aob(scmrq->aob)) { SCM_LOG(5, "no subchannel"); scm_request_requeue(scmrq); } - return ret; } -static void scm_blk_request(struct request_queue *rq) +struct scm_queue { + struct scm_request *scmrq; + spinlock_t lock; +}; + +static int scm_blk_request(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *qd) { - struct scm_device *scmdev = rq->queuedata; + struct scm_device *scmdev = hctx->queue->queuedata; struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev); - struct scm_request *scmrq = NULL; - struct request *req; + struct scm_queue *sq = hctx->driver_data; + struct request *req = qd->rq; + struct scm_request *scmrq; - while ((req = blk_peek_request(rq))) { - if (!scm_permit_request(bdev, req)) - goto out; + spin_lock(&sq->lock); + if (!scm_permit_request(bdev, req)) { + spin_unlock(&sq->lock); + return BLK_MQ_RQ_QUEUE_BUSY; + } + scmrq = sq->scmrq; + if (!scmrq) { + scmrq = scm_request_fetch(); if (!scmrq) { - scmrq = scm_request_fetch(); - if (!scmrq) { - SCM_LOG(5, "no request"); - goto out; - } - scm_request_init(bdev, scmrq); + SCM_LOG(5, "no request"); + spin_unlock(&sq->lock); + return BLK_MQ_RQ_QUEUE_BUSY; } - scm_request_set(scmrq, req); + scm_request_init(bdev, scmrq); + sq->scmrq = scmrq; + } + scm_request_set(scmrq, req); - if (!scm_reserve_cluster(scmrq)) { - SCM_LOG(5, "cluster busy"); - scm_request_set(scmrq, NULL); - if (scmrq->aob->request.msb_count) - goto out; + if (scm_request_prepare(scmrq)) { + SCM_LOG(5, "aidaw alloc failed"); + scm_request_set(scmrq, NULL); - scm_request_done(scmrq); - return; - } + if (scmrq->aob->request.msb_count) + scm_request_start(scmrq); - if (scm_need_cluster_request(scmrq)) { - if (scmrq->aob->request.msb_count) { - /* Start cluster requests separately. */ - scm_request_set(scmrq, NULL); - if (scm_request_start(scmrq)) - return; - } else { - atomic_inc(&bdev->queued_reqs); - blk_start_request(req); - scm_initiate_cluster_request(scmrq); - } - scmrq = NULL; - continue; - } + sq->scmrq = NULL; + spin_unlock(&sq->lock); + return BLK_MQ_RQ_QUEUE_BUSY; + } + blk_mq_start_request(req); - if (scm_request_prepare(scmrq)) { - SCM_LOG(5, "aidaw alloc failed"); - scm_request_set(scmrq, NULL); - goto out; - } - blk_start_request(req); + if (qd->last || scmrq->aob->request.msb_count == nr_requests_per_io) { + scm_request_start(scmrq); + sq->scmrq = NULL; + } + spin_unlock(&sq->lock); + return BLK_MQ_RQ_QUEUE_OK; +} - if (scmrq->aob->request.msb_count < nr_requests_per_io) - continue; +static int scm_blk_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, + unsigned int idx) +{ + struct scm_queue *qd = kzalloc(sizeof(*qd), GFP_KERNEL); - if (scm_request_start(scmrq)) - return; + if (!qd) + return -ENOMEM; - scmrq = NULL; - } -out: - if (scmrq) - scm_request_start(scmrq); - else - scm_ensure_queue_restart(bdev); + spin_lock_init(&qd->lock); + hctx->driver_data = qd; + + return 0; +} + +static void scm_blk_exit_hctx(struct blk_mq_hw_ctx *hctx, unsigned int idx) +{ + struct scm_queue *qd = hctx->driver_data; + + WARN_ON(qd->scmrq); + kfree(hctx->driver_data); + hctx->driver_data = NULL; } static void __scmrq_log_error(struct scm_request *scmrq) @@ -377,21 +367,6 @@ static void __scmrq_log_error(struct scm_request *scmrq) scmrq->error); } -void scm_blk_irq(struct scm_device *scmdev, void *data, int error) -{ - struct scm_request *scmrq = data; - struct scm_blk_dev *bdev = scmrq->bdev; - - scmrq->error = error; - if (error) - __scmrq_log_error(scmrq); - - spin_lock(&bdev->lock); - list_add_tail(&scmrq->list, &bdev->finished_requests); - spin_unlock(&bdev->lock); - tasklet_hi_schedule(&bdev->tasklet); -} - static void scm_blk_handle_error(struct scm_request *scmrq) { struct scm_blk_dev *bdev = scmrq->bdev; @@ -419,49 +394,41 @@ restart: return; requeue: - spin_lock_irqsave(&bdev->rq_lock, flags); scm_request_requeue(scmrq); - spin_unlock_irqrestore(&bdev->rq_lock, flags); } -static void scm_blk_tasklet(struct scm_blk_dev *bdev) +void scm_blk_irq(struct scm_device *scmdev, void *data, int error) { - struct scm_request *scmrq; - unsigned long flags; - - spin_lock_irqsave(&bdev->lock, flags); - while (!list_empty(&bdev->finished_requests)) { - scmrq = list_first_entry(&bdev->finished_requests, - struct scm_request, list); - list_del(&scmrq->list); - spin_unlock_irqrestore(&bdev->lock, flags); + struct scm_request *scmrq = data; - if (scmrq->error && scmrq->retries-- > 0) { + scmrq->error = error; + if (error) { + __scmrq_log_error(scmrq); + if (scmrq->retries-- > 0) { scm_blk_handle_error(scmrq); - - /* Request restarted or requeued, handle next. */ - spin_lock_irqsave(&bdev->lock, flags); - continue; + return; } + } - if (scm_test_cluster_request(scmrq)) { - scm_cluster_request_irq(scmrq); - spin_lock_irqsave(&bdev->lock, flags); - continue; - } + scm_request_finish(scmrq); +} - scm_request_finish(scmrq); - spin_lock_irqsave(&bdev->lock, flags); - } - spin_unlock_irqrestore(&bdev->lock, flags); - /* Look out for more requests. */ - blk_run_queue(bdev->rq); +static void scm_blk_request_done(struct request *req) +{ + blk_mq_end_request(req, 0); } static const struct block_device_operations scm_blk_devops = { .owner = THIS_MODULE, }; +static const struct blk_mq_ops scm_mq_ops = { + .queue_rq = scm_blk_request, + .complete = scm_blk_request_done, + .init_hctx = scm_blk_init_hctx, + .exit_hctx = scm_blk_exit_hctx, +}; + int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev) { struct request_queue *rq; @@ -477,18 +444,22 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev) bdev->scmdev = scmdev; bdev->state = SCM_OPER; - spin_lock_init(&bdev->rq_lock); spin_lock_init(&bdev->lock); - INIT_LIST_HEAD(&bdev->finished_requests); atomic_set(&bdev->queued_reqs, 0); - tasklet_init(&bdev->tasklet, - (void (*)(unsigned long)) scm_blk_tasklet, - (unsigned long) bdev); - rq = blk_init_queue(scm_blk_request, &bdev->rq_lock); - if (!rq) + bdev->tag_set.ops = &scm_mq_ops; + bdev->tag_set.nr_hw_queues = nr_requests; + bdev->tag_set.queue_depth = nr_requests_per_io * nr_requests; + bdev->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; + + ret = blk_mq_alloc_tag_set(&bdev->tag_set); + if (ret) goto out; + rq = blk_mq_init_queue(&bdev->tag_set); + if (IS_ERR(rq)) + goto out_tag; + bdev->rq = rq; nr_max_blk = min(scmdev->nr_max_block, (unsigned int) (PAGE_SIZE / sizeof(struct aidaw))); @@ -498,7 +469,6 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev) blk_queue_max_segments(rq, nr_max_blk); queue_flag_set_unlocked(QUEUE_FLAG_NONROT, rq); queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, rq); - scm_blk_dev_cluster_setup(bdev); bdev->gendisk = alloc_disk(SCM_NR_PARTS); if (!bdev->gendisk) @@ -528,6 +498,8 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev) out_queue: blk_cleanup_queue(rq); +out_tag: + blk_mq_free_tag_set(&bdev->tag_set); out: atomic_dec(&nr_devices); return ret; @@ -535,9 +507,9 @@ out: void scm_blk_dev_cleanup(struct scm_blk_dev *bdev) { - tasklet_kill(&bdev->tasklet); del_gendisk(bdev->gendisk); blk_cleanup_queue(bdev->gendisk->queue); + blk_mq_free_tag_set(&bdev->tag_set); put_disk(bdev->gendisk); } @@ -558,7 +530,7 @@ static bool __init scm_blk_params_valid(void) if (!nr_requests_per_io || nr_requests_per_io > 64) return false; - return scm_cluster_size_valid(); + return true; } static int __init scm_blk_init(void) diff --git a/drivers/s390/block/scm_blk.h b/drivers/s390/block/scm_blk.h index 09218cdc5129..242d17a91920 100644 --- a/drivers/s390/block/scm_blk.h +++ b/drivers/s390/block/scm_blk.h @@ -4,6 +4,7 @@ #include <linux/interrupt.h> #include <linux/spinlock.h> #include <linux/blkdev.h> +#include <linux/blk-mq.h> #include <linux/genhd.h> #include <linux/list.h> @@ -14,18 +15,14 @@ #define SCM_QUEUE_DELAY 5 struct scm_blk_dev { - struct tasklet_struct tasklet; struct request_queue *rq; struct gendisk *gendisk; + struct blk_mq_tag_set tag_set; struct scm_device *scmdev; - spinlock_t rq_lock; /* guard the request queue */ - spinlock_t lock; /* guard the rest of the blockdev */ + spinlock_t lock; atomic_t queued_reqs; enum {SCM_OPER, SCM_WR_PROHIBIT} state; struct list_head finished_requests; -#ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE - struct list_head cluster_list; -#endif }; struct scm_request { @@ -36,13 +33,6 @@ struct scm_request { struct list_head list; u8 retries; int error; -#ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE - struct { - enum {CLUSTER_NONE, CLUSTER_READ, CLUSTER_WRITE} state; - struct list_head list; - void **buf; - } cluster; -#endif }; #define to_aobrq(rq) container_of((void *) rq, struct aob_rq_header, data) @@ -52,55 +42,11 @@ void scm_blk_dev_cleanup(struct scm_blk_dev *); void scm_blk_set_available(struct scm_blk_dev *); void scm_blk_irq(struct scm_device *, void *, int); -void scm_request_finish(struct scm_request *); -void scm_request_requeue(struct scm_request *); - struct aidaw *scm_aidaw_fetch(struct scm_request *scmrq, unsigned int bytes); int scm_drv_init(void); void scm_drv_cleanup(void); -#ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE -void __scm_free_rq_cluster(struct scm_request *); -int __scm_alloc_rq_cluster(struct scm_request *); -void scm_request_cluster_init(struct scm_request *); -bool scm_reserve_cluster(struct scm_request *); -void scm_release_cluster(struct scm_request *); -void scm_blk_dev_cluster_setup(struct scm_blk_dev *); -bool scm_need_cluster_request(struct scm_request *); -void scm_initiate_cluster_request(struct scm_request *); -void scm_cluster_request_irq(struct scm_request *); -bool scm_test_cluster_request(struct scm_request *); -bool scm_cluster_size_valid(void); -#else /* CONFIG_SCM_BLOCK_CLUSTER_WRITE */ -static inline void __scm_free_rq_cluster(struct scm_request *scmrq) {} -static inline int __scm_alloc_rq_cluster(struct scm_request *scmrq) -{ - return 0; -} -static inline void scm_request_cluster_init(struct scm_request *scmrq) {} -static inline bool scm_reserve_cluster(struct scm_request *scmrq) -{ - return true; -} -static inline void scm_release_cluster(struct scm_request *scmrq) {} -static inline void scm_blk_dev_cluster_setup(struct scm_blk_dev *bdev) {} -static inline bool scm_need_cluster_request(struct scm_request *scmrq) -{ - return false; -} -static inline void scm_initiate_cluster_request(struct scm_request *scmrq) {} -static inline void scm_cluster_request_irq(struct scm_request *scmrq) {} -static inline bool scm_test_cluster_request(struct scm_request *scmrq) -{ - return false; -} -static inline bool scm_cluster_size_valid(void) -{ - return true; -} -#endif /* CONFIG_SCM_BLOCK_CLUSTER_WRITE */ - extern debug_info_t *scm_debug; #define SCM_LOG(imp, txt) do { \ diff --git a/drivers/s390/block/scm_blk_cluster.c b/drivers/s390/block/scm_blk_cluster.c deleted file mode 100644 index 7497ddde2dd6..000000000000 --- a/drivers/s390/block/scm_blk_cluster.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Block driver for s390 storage class memory. - * - * Copyright IBM Corp. 2012 - * Author(s): Sebastian Ott <sebott@linux.vnet.ibm.com> - */ - -#include <linux/spinlock.h> -#include <linux/module.h> -#include <linux/blkdev.h> -#include <linux/genhd.h> -#include <linux/slab.h> -#include <linux/list.h> -#include <asm/eadm.h> -#include "scm_blk.h" - -static unsigned int write_cluster_size = 64; -module_param(write_cluster_size, uint, S_IRUGO); -MODULE_PARM_DESC(write_cluster_size, - "Number of pages used for contiguous writes."); - -#define CLUSTER_SIZE (write_cluster_size * PAGE_SIZE) - -void __scm_free_rq_cluster(struct scm_request *scmrq) -{ - int i; - - if (!scmrq->cluster.buf) - return; - - for (i = 0; i < 2 * write_cluster_size; i++) - free_page((unsigned long) scmrq->cluster.buf[i]); - - kfree(scmrq->cluster.buf); -} - -int __scm_alloc_rq_cluster(struct scm_request *scmrq) -{ - int i; - - scmrq->cluster.buf = kzalloc(sizeof(void *) * 2 * write_cluster_size, - GFP_KERNEL); - if (!scmrq->cluster.buf) - return -ENOMEM; - - for (i = 0; i < 2 * write_cluster_size; i++) { - scmrq->cluster.buf[i] = (void *) get_zeroed_page(GFP_DMA); - if (!scmrq->cluster.buf[i]) - return -ENOMEM; - } - INIT_LIST_HEAD(&scmrq->cluster.list); - return 0; -} - -void scm_request_cluster_init(struct scm_request *scmrq) -{ - scmrq->cluster.state = CLUSTER_NONE; -} - -static bool clusters_intersect(struct request *A, struct request *B) -{ - unsigned long firstA, lastA, firstB, lastB; - - firstA = ((u64) blk_rq_pos(A) << 9) / CLUSTER_SIZE; - lastA = (((u64) blk_rq_pos(A) << 9) + - blk_rq_bytes(A) - 1) / CLUSTER_SIZE; - - firstB = ((u64) blk_rq_pos(B) << 9) / CLUSTER_SIZE; - lastB = (((u64) blk_rq_pos(B) << 9) + - blk_rq_bytes(B) - 1) / CLUSTER_SIZE; - - return (firstB <= lastA && firstA <= lastB); -} - -bool scm_reserve_cluster(struct scm_request *scmrq) -{ - struct request *req = scmrq->request[scmrq->aob->request.msb_count]; - struct scm_blk_dev *bdev = scmrq->bdev; - struct scm_request *iter; - int pos, add = 1; - - if (write_cluster_size == 0) - return true; - - spin_lock(&bdev->lock); - list_for_each_entry(iter, &bdev->cluster_list, cluster.list) { - if (iter == scmrq) { - /* - * We don't have to use clusters_intersect here, since - * cluster requests are always started separately. - */ - add = 0; - continue; - } - for (pos = 0; pos < iter->aob->request.msb_count; pos++) { - if (clusters_intersect(req, iter->request[pos]) && - (rq_data_dir(req) == WRITE || - rq_data_dir(iter->request[pos]) == WRITE)) { - spin_unlock(&bdev->lock); - return false; - } - } - } - if (add) - list_add(&scmrq->cluster.list, &bdev->cluster_list); - spin_unlock(&bdev->lock); - - return true; -} - -void scm_release_cluster(struct scm_request *scmrq) -{ - struct scm_blk_dev *bdev = scmrq->bdev; - unsigned long flags; - - if (write_cluster_size == 0) - return; - - spin_lock_irqsave(&bdev->lock, flags); - list_del(&scmrq->cluster.list); - spin_unlock_irqrestore(&bdev->lock, flags); -} - -void scm_blk_dev_cluster_setup(struct scm_blk_dev *bdev) -{ - INIT_LIST_HEAD(&bdev->cluster_list); - blk_queue_io_opt(bdev->rq, CLUSTER_SIZE); -} - -static int scm_prepare_cluster_request(struct scm_request *scmrq) -{ - struct scm_blk_dev *bdev = scmrq->bdev; - struct scm_device *scmdev = bdev->gendisk->private_data; - struct request *req = scmrq->request[0]; - struct msb *msb = &scmrq->aob->msb[0]; - struct req_iterator iter; - struct aidaw *aidaw; - struct bio_vec bv; - int i = 0; - u64 addr; - - switch (scmrq->cluster.state) { - case CLUSTER_NONE: - scmrq->cluster.state = CLUSTER_READ; - /* fall through */ - case CLUSTER_READ: - msb->bs = MSB_BS_4K; - msb->oc = MSB_OC_READ; - msb->flags = MSB_FLAG_IDA; - msb->blk_count = write_cluster_size; - - addr = scmdev->address + ((u64) blk_rq_pos(req) << 9); - msb->scm_addr = round_down(addr, CLUSTER_SIZE); - - if (msb->scm_addr != - round_down(addr + (u64) blk_rq_bytes(req) - 1, - CLUSTER_SIZE)) - msb->blk_count = 2 * write_cluster_size; - - aidaw = scm_aidaw_fetch(scmrq, msb->blk_count * PAGE_SIZE); - if (!aidaw) - return -ENOMEM; - - scmrq->aob->request.msb_count = 1; - msb->data_addr = (u64) aidaw; - for (i = 0; i < msb->blk_count; i++) { - aidaw->data_addr = (u64) scmrq->cluster.buf[i]; - aidaw++; - } - - break; - case CLUSTER_WRITE: - aidaw = (void *) msb->data_addr; - msb->oc = MSB_OC_WRITE; - - for (addr = msb->scm_addr; - addr < scmdev->address + ((u64) blk_rq_pos(req) << 9); - addr += PAGE_SIZE) { - aidaw->data_addr = (u64) scmrq->cluster.buf[i]; - aidaw++; - i++; - } - rq_for_each_segment(bv, req, iter) { - aidaw->data_addr = (u64) page_address(bv.bv_page); - aidaw++; - i++; - } - for (; i < msb->blk_count; i++) { - aidaw->data_addr = (u64) scmrq->cluster.buf[i]; - aidaw++; - } - break; - } - return 0; -} - -bool scm_need_cluster_request(struct scm_request *scmrq) -{ - int pos = scmrq->aob->request.msb_count; - - if (rq_data_dir(scmrq->request[pos]) == READ) - return false; - - return blk_rq_bytes(scmrq->request[pos]) < CLUSTER_SIZE; -} - -/* Called with queue lock held. */ -void scm_initiate_cluster_request(struct scm_request *scmrq) -{ - if (scm_prepare_cluster_request(scmrq)) - goto requeue; - if (eadm_start_aob(scmrq->aob)) - goto requeue; - return; -requeue: - scm_request_requeue(scmrq); -} - -bool scm_test_cluster_request(struct scm_request *scmrq) -{ - return scmrq->cluster.state != CLUSTER_NONE; -} - -void scm_cluster_request_irq(struct scm_request *scmrq) -{ - struct scm_blk_dev *bdev = scmrq->bdev; - unsigned long flags; - - switch (scmrq->cluster.state) { - case CLUSTER_NONE: - BUG(); - break; - case CLUSTER_READ: - if (scmrq->error) { - scm_request_finish(scmrq); - break; - } - scmrq->cluster.state = CLUSTER_WRITE; - spin_lock_irqsave(&bdev->rq_lock, flags); - scm_initiate_cluster_request(scmrq); - spin_unlock_irqrestore(&bdev->rq_lock, flags); - break; - case CLUSTER_WRITE: - scm_request_finish(scmrq); - break; - } -} - -bool scm_cluster_size_valid(void) -{ - if (write_cluster_size == 1 || write_cluster_size > 128) - return false; - - return !(write_cluster_size & (write_cluster_size - 1)); -} diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 9be4596d8a08..e52706e60cf8 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -745,7 +745,7 @@ static ssize_t ap_domain_store(struct bus_type *bus, ap_domain_index = domain; spin_unlock_bh(&ap_domain_lock); - AP_DBF(DBF_DEBUG, "store new default domain=%d\n", domain); + AP_DBF(DBF_DEBUG, "stored new default domain=%d\n", domain); return count; } @@ -931,6 +931,7 @@ static int ap_select_domain(void) } if (best_domain >= 0){ ap_domain_index = best_domain; + AP_DBF(DBF_DEBUG, "new ap_domain_index=%d\n", ap_domain_index); spin_unlock_bh(&ap_domain_lock); return 0; } @@ -967,7 +968,7 @@ static void ap_scan_bus(struct work_struct *unused) ap_qid_t qid; int depth = 0, type = 0; unsigned int functions = 0; - int rc, id, dom, borked, domains; + int rc, id, dom, borked, domains, defdomdevs = 0; AP_DBF(DBF_DEBUG, "ap_scan_bus running\n"); @@ -1031,6 +1032,8 @@ static void ap_scan_bus(struct work_struct *unused) put_device(dev); if (!borked) { domains++; + if (dom == ap_domain_index) + defdomdevs++; continue; } } @@ -1088,6 +1091,8 @@ static void ap_scan_bus(struct work_struct *unused) continue; } domains++; + if (dom == ap_domain_index) + defdomdevs++; } /* end domain loop */ if (ac) { /* remove card dev if there are no queue devices */ @@ -1096,6 +1101,11 @@ static void ap_scan_bus(struct work_struct *unused) put_device(&ac->ap_dev.device); } } /* end device loop */ + + if (defdomdevs < 1) + AP_DBF(DBF_INFO, "no queue device with default domain %d available\n", + ap_domain_index); + out: mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ); } @@ -1164,14 +1174,14 @@ int __init ap_module_init(void) ap_init_configuration(); if (ap_configuration) - max_domain_id = ap_max_domain_id ? : (AP_DOMAINS - 1); + max_domain_id = + ap_max_domain_id ? ap_max_domain_id : AP_DOMAINS - 1; else max_domain_id = 15; if (ap_domain_index < -1 || ap_domain_index > max_domain_id) { pr_warn("%d is not a valid cryptographic domain\n", ap_domain_index); - rc = -EINVAL; - goto out_free; + ap_domain_index = -1; } /* In resume callback we need to know if the user had set the domain. * If so, we can not just reset it. @@ -1244,7 +1254,6 @@ out: unregister_reset_call(&ap_reset_call); if (ap_using_interrupts()) unregister_adapter_interrupt(&ap_airq); -out_free: kfree(ap_configuration); return rc; } diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index ea86da8c75f9..f61fa47135a6 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c @@ -178,9 +178,9 @@ static inline void prep_xcrb(struct ica_xcRB *pxcrb, pxcrb->user_defined = (cardnr == 0xFFFF ? AUTOSELECT : cardnr); pxcrb->request_control_blk_length = preqcblk->cprb_len + preqcblk->req_parml; - pxcrb->request_control_blk_addr = (void *) preqcblk; + pxcrb->request_control_blk_addr = (void __user *) preqcblk; pxcrb->reply_control_blk_length = preqcblk->rpl_msgbl; - pxcrb->reply_control_blk_addr = (void *) prepcblk; + pxcrb->reply_control_blk_addr = (void __user *) prepcblk; } /* @@ -1194,7 +1194,7 @@ static struct miscdevice pkey_dev = { /* * Module init */ -int __init pkey_init(void) +static int __init pkey_init(void) { cpacf_mask_t pckmo_functions; diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 93015f85d4a6..b1c27e28859b 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -821,8 +821,10 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, do { rc = zcrypt_rsa_modexpo(&mex); } while (rc == -EAGAIN); - if (rc) + if (rc) { + ZCRYPT_DBF(DBF_DEBUG, "ioctl ICARSAMODEXPO rc=%d", rc); return rc; + } return put_user(mex.outputdatalength, &umex->outputdatalength); } case ICARSACRT: { @@ -838,8 +840,10 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, do { rc = zcrypt_rsa_crt(&crt); } while (rc == -EAGAIN); - if (rc) + if (rc) { + ZCRYPT_DBF(DBF_DEBUG, "ioctl ICARSACRT rc=%d", rc); return rc; + } return put_user(crt.outputdatalength, &ucrt->outputdatalength); } case ZSECSENDCPRB: { @@ -855,6 +859,8 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, do { rc = zcrypt_send_cprb(&xcRB); } while (rc == -EAGAIN); + if (rc) + ZCRYPT_DBF(DBF_DEBUG, "ioctl ZSENDCPRB rc=%d", rc); if (copy_to_user(uxcRB, &xcRB, sizeof(xcRB))) return -EFAULT; return rc; @@ -872,6 +878,8 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, do { rc = zcrypt_send_ep11_cprb(&xcrb); } while (rc == -EAGAIN); + if (rc) + ZCRYPT_DBF(DBF_DEBUG, "ioctl ZSENDEP11CPRB rc=%d", rc); if (copy_to_user(uxcrb, &xcrb, sizeof(xcrb))) return -EFAULT; return rc; diff --git a/drivers/s390/crypto/zcrypt_cca_key.h b/drivers/s390/crypto/zcrypt_cca_key.h index ca0cdbe46368..12cff6262566 100644 --- a/drivers/s390/crypto/zcrypt_cca_key.h +++ b/drivers/s390/crypto/zcrypt_cca_key.h @@ -48,26 +48,6 @@ struct cca_token_hdr { #define CCA_TKN_HDR_ID_EXT 0x1E -/** - * mapping for the cca private ME section - */ -struct cca_private_ext_ME_sec { - unsigned char section_identifier; - unsigned char version; - unsigned short section_length; - unsigned char private_key_hash[20]; - unsigned char reserved1[4]; - unsigned char key_format; - unsigned char reserved2; - unsigned char key_name_hash[20]; - unsigned char key_use_flags[4]; - unsigned char reserved3[6]; - unsigned char reserved4[24]; - unsigned char confounder[24]; - unsigned char exponent[128]; - unsigned char modulus[128]; -} __attribute__((packed)); - #define CCA_PVT_USAGE_ALL 0x80 /** @@ -124,77 +104,6 @@ struct cca_pvt_ext_CRT_sec { #define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40 /** - * Set up private key fields of a type6 MEX message. - * Note that all numerics in the key token are big-endian, - * while the entries in the key block header are little-endian. - * - * @mex: pointer to user input data - * @p: pointer to memory area for the key - * - * Returns the size of the key area or -EFAULT - */ -static inline int zcrypt_type6_mex_key_de(struct ica_rsa_modexpo *mex, - void *p, int big_endian) -{ - static struct cca_token_hdr static_pvt_me_hdr = { - .token_identifier = 0x1E, - .token_length = 0x0183, - }; - static struct cca_private_ext_ME_sec static_pvt_me_sec = { - .section_identifier = 0x02, - .section_length = 0x016C, - .key_use_flags = {0x80,0x00,0x00,0x00}, - }; - static struct cca_public_sec static_pub_me_sec = { - .section_identifier = 0x04, - .section_length = 0x000F, - .exponent_len = 0x0003, - }; - static char pk_exponent[3] = { 0x01, 0x00, 0x01 }; - struct { - struct T6_keyBlock_hdr t6_hdr; - struct cca_token_hdr pvtMeHdr; - struct cca_private_ext_ME_sec pvtMeSec; - struct cca_public_sec pubMeSec; - char exponent[3]; - } __attribute__((packed)) *key = p; - unsigned char *temp; - - memset(key, 0, sizeof(*key)); - - if (big_endian) { - key->t6_hdr.blen = cpu_to_be16(0x189); - key->t6_hdr.ulen = cpu_to_be16(0x189 - 2); - } else { - key->t6_hdr.blen = cpu_to_le16(0x189); - key->t6_hdr.ulen = cpu_to_le16(0x189 - 2); - } - key->pvtMeHdr = static_pvt_me_hdr; - key->pvtMeSec = static_pvt_me_sec; - key->pubMeSec = static_pub_me_sec; - /* - * In a private key, the modulus doesn't appear in the public - * section. So, an arbitrary public exponent of 0x010001 will be - * used. - */ - memcpy(key->exponent, pk_exponent, 3); - - /* key parameter block */ - temp = key->pvtMeSec.exponent + - sizeof(key->pvtMeSec.exponent) - mex->inputdatalength; - if (copy_from_user(temp, mex->b_key, mex->inputdatalength)) - return -EFAULT; - - /* modulus */ - temp = key->pvtMeSec.modulus + - sizeof(key->pvtMeSec.modulus) - mex->inputdatalength; - if (copy_from_user(temp, mex->n_modulus, mex->inputdatalength)) - return -EFAULT; - key->pubMeSec.modulus_bit_len = 8 * mex->inputdatalength; - return sizeof(*key); -} - -/** * Set up private key fields of a type6 MEX message. The _pad variant * strips leading zeroes from the b_key. * Note that all numerics in the key token are big-endian, @@ -205,8 +114,7 @@ static inline int zcrypt_type6_mex_key_de(struct ica_rsa_modexpo *mex, * * Returns the size of the key area or -EFAULT */ -static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, - void *p, int big_endian) +static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, void *p) { static struct cca_token_hdr static_pub_hdr = { .token_identifier = 0x1E, @@ -251,13 +159,8 @@ static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, 2*mex->inputdatalength - i; key->pubHdr.token_length = key->pubSec.section_length + sizeof(key->pubHdr); - if (big_endian) { - key->t6_hdr.ulen = cpu_to_be16(key->pubHdr.token_length + 4); - key->t6_hdr.blen = cpu_to_be16(key->pubHdr.token_length + 6); - } else { - key->t6_hdr.ulen = cpu_to_le16(key->pubHdr.token_length + 4); - key->t6_hdr.blen = cpu_to_le16(key->pubHdr.token_length + 6); - } + key->t6_hdr.ulen = key->pubHdr.token_length + 4; + key->t6_hdr.blen = key->pubHdr.token_length + 6; return sizeof(*key) + 2*mex->inputdatalength - i; } @@ -271,8 +174,7 @@ static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, * * Returns the size of the key area or -EFAULT */ -static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, - void *p, int big_endian) +static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, void *p) { static struct cca_public_sec static_cca_pub_sec = { .section_identifier = 4, @@ -298,13 +200,8 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, size = sizeof(*key) + key_len + sizeof(*pub) + 3; /* parameter block.key block */ - if (big_endian) { - key->t6_hdr.blen = cpu_to_be16(size); - key->t6_hdr.ulen = cpu_to_be16(size - 2); - } else { - key->t6_hdr.blen = cpu_to_le16(size); - key->t6_hdr.ulen = cpu_to_le16(size - 2); - } + key->t6_hdr.blen = size; + key->t6_hdr.ulen = size - 2; /* key token header */ key->token.token_identifier = CCA_TKN_HDR_ID_EXT; diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c index e5563ffeb839..4fddb4319481 100644 --- a/drivers/s390/crypto/zcrypt_msgtype6.c +++ b/drivers/s390/crypto/zcrypt_msgtype6.c @@ -291,7 +291,7 @@ static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_queue *zq, return -EFAULT; /* Set up key which is located after the variable length text. */ - size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1); + size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength); if (size < 0) return size; size += sizeof(*msg) + mex->inputdatalength; @@ -353,7 +353,7 @@ static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_queue *zq, return -EFAULT; /* Set up key which is located after the variable length text. */ - size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1); + size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength); if (size < 0) return size; size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */ diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile index 5b6e396c1121..aab41a5cc317 100644 --- a/drivers/soc/imx/Makefile +++ b/drivers/soc/imx/Makefile @@ -1,2 +1,2 @@ -obj-y += gpc.o +obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_IMX7_PM_DOMAINS) += gpcv2.o diff --git a/drivers/staging/ccree/Kconfig b/drivers/staging/ccree/Kconfig index ae627049c499..4be87f503e3b 100644 --- a/drivers/staging/ccree/Kconfig +++ b/drivers/staging/ccree/Kconfig @@ -1,6 +1,6 @@ config CRYPTO_DEV_CCREE tristate "Support for ARM TrustZone CryptoCell C7XX family of Crypto accelerators" - depends on CRYPTO_HW && OF && HAS_DMA + depends on CRYPTO && CRYPTO_HW && OF && HAS_DMA default n select CRYPTO_HASH select CRYPTO_BLKCIPHER diff --git a/drivers/staging/media/atomisp/i2c/Makefile b/drivers/staging/media/atomisp/i2c/Makefile index 8ea01904c0ea..466517c7c8e6 100644 --- a/drivers/staging/media/atomisp/i2c/Makefile +++ b/drivers/staging/media/atomisp/i2c/Makefile @@ -19,5 +19,3 @@ obj-$(CONFIG_VIDEO_AP1302) += ap1302.o obj-$(CONFIG_VIDEO_LM3554) += lm3554.o -ccflags-y += -Werror - diff --git a/drivers/staging/media/atomisp/i2c/imx/Makefile b/drivers/staging/media/atomisp/i2c/imx/Makefile index 1d7f7ab94cac..6b13a3a66e49 100644 --- a/drivers/staging/media/atomisp/i2c/imx/Makefile +++ b/drivers/staging/media/atomisp/i2c/imx/Makefile @@ -4,5 +4,3 @@ imx1x5-objs := imx.o drv201.o ad5816g.o dw9714.o dw9719.o dw9718.o vcm.o otp.o o ov8858_driver-objs := ../ov8858.o dw9718.o vcm.o obj-$(CONFIG_VIDEO_OV8858) += ov8858_driver.o - -ccflags-y += -Werror diff --git a/drivers/staging/media/atomisp/i2c/ov5693/Makefile b/drivers/staging/media/atomisp/i2c/ov5693/Makefile index fceb9e9b881b..c9c0e1245858 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/Makefile +++ b/drivers/staging/media/atomisp/i2c/ov5693/Makefile @@ -1,3 +1 @@ obj-$(CONFIG_VIDEO_OV5693) += ov5693.o - -ccflags-y += -Werror diff --git a/drivers/staging/media/atomisp/pci/atomisp2/Makefile b/drivers/staging/media/atomisp/pci/atomisp2/Makefile index 3fa7c1c1479f..f126a89a08e9 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/Makefile +++ b/drivers/staging/media/atomisp/pci/atomisp2/Makefile @@ -351,5 +351,5 @@ DEFINES := -DHRT_HW -DHRT_ISP_CSS_CUSTOM_HOST -DHRT_USE_VIR_ADDRS -D__HOST__ DEFINES += -DATOMISP_POSTFIX=\"css2400b0_v21\" -DISP2400B0 DEFINES += -DSYSTEM_hive_isp_css_2400_system -DISP2400 -ccflags-y += $(INCLUDES) $(DEFINES) -fno-common -Werror +ccflags-y += $(INCLUDES) $(DEFINES) -fno-common diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index 574da15fe618..b8d5ea0ae26b 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig @@ -44,7 +44,7 @@ config HVC_RTAS config HVC_IUCV bool "z/VM IUCV Hypervisor console support (VM only)" - depends on S390 + depends on S390 && NET select HVC_DRIVER select IUCV default y diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 9e217b1361ea..fe4fe2440729 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -843,7 +843,10 @@ static ssize_t ci_role_show(struct device *dev, struct device_attribute *attr, { struct ci_hdrc *ci = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", ci_role(ci)->name); + if (ci->role != CI_ROLE_END) + return sprintf(buf, "%s\n", ci_role(ci)->name); + + return 0; } static ssize_t ci_role_store(struct device *dev, diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 6d23eede4d8c..1c31e8a08810 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -294,7 +294,8 @@ static int ci_role_show(struct seq_file *s, void *data) { struct ci_hdrc *ci = s->private; - seq_printf(s, "%s\n", ci_role(ci)->name); + if (ci->role != CI_ROLE_END) + seq_printf(s, "%s\n", ci_role(ci)->name); return 0; } diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 56d2d3213076..d68b125796f9 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1993,6 +1993,7 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci) int ci_hdrc_gadget_init(struct ci_hdrc *ci) { struct ci_role_driver *rdrv; + int ret; if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC)) return -ENXIO; @@ -2005,7 +2006,10 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci) rdrv->stop = udc_id_switch_for_host; rdrv->irq = udc_irq; rdrv->name = "gadget"; - ci->roles[CI_ROLE_GADGET] = rdrv; - return udc_start(ci); + ret = udc_start(ci); + if (!ret) + ci->roles[CI_ROLE_GADGET] = rdrv; + + return ret; } diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index e77a4ed4f021..9f4a0185dd60 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -108,6 +108,8 @@ struct imx_usbmisc { const struct usbmisc_ops *ops; }; +static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data); + static int usbmisc_imx25_init(struct imx_usbmisc_data *data) { struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); @@ -242,10 +244,15 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data) val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN | MX53_USB_UHx_CTRL_ULPI_INT_EN; writel(val, reg); - /* Disable internal 60Mhz clock */ - reg = usbmisc->base + MX53_USB_CLKONOFF_CTRL_OFFSET; - val = readl(reg) | MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF; - writel(val, reg); + if (is_imx53_usbmisc(data)) { + /* Disable internal 60Mhz clock */ + reg = usbmisc->base + + MX53_USB_CLKONOFF_CTRL_OFFSET; + val = readl(reg) | + MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF; + writel(val, reg); + } + } if (data->disable_oc) { reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; @@ -267,10 +274,15 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data) val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN | MX53_USB_UHx_CTRL_ULPI_INT_EN; writel(val, reg); - /* Disable internal 60Mhz clock */ - reg = usbmisc->base + MX53_USB_CLKONOFF_CTRL_OFFSET; - val = readl(reg) | MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF; - writel(val, reg); + + if (is_imx53_usbmisc(data)) { + /* Disable internal 60Mhz clock */ + reg = usbmisc->base + + MX53_USB_CLKONOFF_CTRL_OFFSET; + val = readl(reg) | + MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF; + writel(val, reg); + } } if (data->disable_oc) { reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; @@ -456,6 +468,10 @@ static const struct usbmisc_ops imx27_usbmisc_ops = { .init = usbmisc_imx27_init, }; +static const struct usbmisc_ops imx51_usbmisc_ops = { + .init = usbmisc_imx53_init, +}; + static const struct usbmisc_ops imx53_usbmisc_ops = { .init = usbmisc_imx53_init, }; @@ -479,6 +495,13 @@ static const struct usbmisc_ops imx7d_usbmisc_ops = { .set_wakeup = usbmisc_imx7d_set_wakeup, }; +static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) +{ + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); + + return usbmisc->ops == &imx53_usbmisc_ops; +} + int imx_usbmisc_init(struct imx_usbmisc_data *data) { struct imx_usbmisc *usbmisc; @@ -536,7 +559,7 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = { }, { .compatible = "fsl,imx51-usbmisc", - .data = &imx53_usbmisc_ops, + .data = &imx51_usbmisc_ops, }, { .compatible = "fsl,imx53-usbmisc", diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 9c7ee26ef388..bc6a9be2ccc5 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -245,6 +245,11 @@ static int dsps_check_status(struct musb *musb, void *unused) dsps_mod_timer_optional(glue); break; case OTG_STATE_A_WAIT_BCON: + /* keep VBUS on for host-only mode */ + if (musb->port_mode == MUSB_PORT_MODE_HOST) { + dsps_mod_timer_optional(glue); + break; + } musb_writeb(musb->mregs, MUSB_DEVCTL, 0); skip_session = 1; /* fall */ diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index b827a8113e26..ff01bed7112f 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -408,7 +408,7 @@ static void efifb_fixup_resources(struct pci_dev *dev) if (!base) return; - for (i = 0; i < PCI_STD_RESOURCE_END; i++) { + for (i = 0; i <= PCI_STD_RESOURCE_END; i++) { struct resource *res = &dev->resource[i]; if (!(res->flags & IORESOURCE_MEM)) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 24865da63d8f..f723c11bb763 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -16,7 +16,7 @@ * Boston, MA 021110-1307, USA. */ -#include <linux/vmalloc.h> +#include <linux/mm.h> #include <linux/rbtree.h> #include "ctree.h" #include "disk-io.h" @@ -2305,7 +2305,7 @@ struct btrfs_data_container *init_data_container(u32 total_bytes) size_t alloc_bytes; alloc_bytes = max_t(size_t, total_bytes, sizeof(*data)); - data = vmalloc(alloc_bytes); + data = kvmalloc(alloc_bytes, GFP_KERNEL); if (!data) return ERR_PTR(-ENOMEM); @@ -2339,9 +2339,9 @@ struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root, if (IS_ERR(fspath)) return (void *)fspath; - ifp = kmalloc(sizeof(*ifp), GFP_NOFS); + ifp = kmalloc(sizeof(*ifp), GFP_KERNEL); if (!ifp) { - vfree(fspath); + kvfree(fspath); return ERR_PTR(-ENOMEM); } @@ -2356,6 +2356,6 @@ void free_ipath(struct inode_fs_paths *ipath) { if (!ipath) return; - vfree(ipath->fspath); + kvfree(ipath->fspath); kfree(ipath); } diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index ab14c2e635ca..5f8006e4de9d 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -94,7 +94,7 @@ #include <linux/mutex.h> #include <linux/genhd.h> #include <linux/blkdev.h> -#include <linux/vmalloc.h> +#include <linux/mm.h> #include <linux/string.h> #include "ctree.h" #include "disk-io.h" @@ -1668,14 +1668,8 @@ static int btrfsic_read_block(struct btrfsic_state *state, dev_bytenr += (j - i) * PAGE_SIZE; i = j; } - for (i = 0; i < num_pages; i++) { + for (i = 0; i < num_pages; i++) block_ctx->datav[i] = kmap(block_ctx->pagev[i]); - if (!block_ctx->datav[i]) { - pr_info("btrfsic: kmap() failed (dev %s)!\n", - block_ctx->dev->name); - return -1; - } - } return block_ctx->len; } @@ -2822,44 +2816,47 @@ static void __btrfsic_submit_bio(struct bio *bio) dev_state = btrfsic_dev_state_lookup(bio->bi_bdev); if (NULL != dev_state && (bio_op(bio) == REQ_OP_WRITE) && bio_has_data(bio)) { - unsigned int i; + unsigned int i = 0; u64 dev_bytenr; u64 cur_bytenr; - struct bio_vec *bvec; + struct bio_vec bvec; + struct bvec_iter iter; int bio_is_patched; char **mapped_datav; + unsigned int segs = bio_segments(bio); dev_bytenr = 512 * bio->bi_iter.bi_sector; bio_is_patched = 0; if (dev_state->state->print_mask & BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH) pr_info("submit_bio(rw=%d,0x%x, bi_vcnt=%u, bi_sector=%llu (bytenr %llu), bi_bdev=%p)\n", - bio_op(bio), bio->bi_opf, bio->bi_vcnt, + bio_op(bio), bio->bi_opf, segs, (unsigned long long)bio->bi_iter.bi_sector, dev_bytenr, bio->bi_bdev); - mapped_datav = kmalloc_array(bio->bi_vcnt, + mapped_datav = kmalloc_array(segs, sizeof(*mapped_datav), GFP_NOFS); if (!mapped_datav) goto leave; cur_bytenr = dev_bytenr; - bio_for_each_segment_all(bvec, bio, i) { - BUG_ON(bvec->bv_len != PAGE_SIZE); - mapped_datav[i] = kmap(bvec->bv_page); + bio_for_each_segment(bvec, bio, iter) { + BUG_ON(bvec.bv_len != PAGE_SIZE); + mapped_datav[i] = kmap(bvec.bv_page); + i++; if (dev_state->state->print_mask & BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH_VERBOSE) pr_info("#%u: bytenr=%llu, len=%u, offset=%u\n", - i, cur_bytenr, bvec->bv_len, bvec->bv_offset); - cur_bytenr += bvec->bv_len; + i, cur_bytenr, bvec.bv_len, bvec.bv_offset); + cur_bytenr += bvec.bv_len; } btrfsic_process_written_block(dev_state, dev_bytenr, - mapped_datav, bio->bi_vcnt, + mapped_datav, segs, bio, &bio_is_patched, NULL, bio->bi_opf); - bio_for_each_segment_all(bvec, bio, i) - kunmap(bvec->bv_page); + bio_for_each_segment(bvec, bio, iter) + kunmap(bvec.bv_page); kfree(mapped_datav); } else if (NULL != dev_state && (bio->bi_opf & REQ_PREFLUSH)) { if (dev_state->state->print_mask & @@ -2923,13 +2920,10 @@ int btrfsic_mount(struct btrfs_fs_info *fs_info, fs_info->sectorsize, PAGE_SIZE); return -1; } - state = kzalloc(sizeof(*state), GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); + state = kvzalloc(sizeof(*state), GFP_KERNEL); if (!state) { - state = vzalloc(sizeof(*state)); - if (!state) { - pr_info("btrfs check-integrity: vzalloc() failed!\n"); - return -1; - } + pr_info("btrfs check-integrity: allocation failed!\n"); + return -1; } if (!btrfsic_is_initialized) { diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 10e6b282d09d..39cd164e5a62 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -32,6 +32,7 @@ #include <linux/writeback.h> #include <linux/bit_spinlock.h> #include <linux/slab.h> +#include <linux/sched/mm.h> #include "ctree.h" #include "disk-io.h" #include "transaction.h" @@ -42,48 +43,7 @@ #include "extent_io.h" #include "extent_map.h" -struct compressed_bio { - /* number of bios pending for this compressed extent */ - refcount_t pending_bios; - - /* the pages with the compressed data on them */ - struct page **compressed_pages; - - /* inode that owns this data */ - struct inode *inode; - - /* starting offset in the inode for our pages */ - u64 start; - - /* number of bytes in the inode we're working on */ - unsigned long len; - - /* number of bytes on disk */ - unsigned long compressed_len; - - /* the compression algorithm for this bio */ - int compress_type; - - /* number of compressed pages in the array */ - unsigned long nr_pages; - - /* IO errors */ - int errors; - int mirror_num; - - /* for reads, this is the bio we are copying the data into */ - struct bio *orig_bio; - - /* - * the start of a variable length array of checksums only - * used by reads - */ - u32 sums; -}; - -static int btrfs_decompress_bio(int type, struct page **pages_in, - u64 disk_start, struct bio *orig_bio, - size_t srclen); +static int btrfs_decompress_bio(struct compressed_bio *cb); static inline int compressed_bio_size(struct btrfs_fs_info *fs_info, unsigned long disk_size) @@ -173,11 +133,8 @@ static void end_compressed_bio_read(struct bio *bio) /* ok, we're the last bio for this extent, lets start * the decompression. */ - ret = btrfs_decompress_bio(cb->compress_type, - cb->compressed_pages, - cb->start, - cb->orig_bio, - cb->compressed_len); + ret = btrfs_decompress_bio(cb); + csum_failed: if (ret) cb->errors = 1; @@ -801,6 +758,7 @@ static struct list_head *find_workspace(int type) struct list_head *workspace; int cpus = num_online_cpus(); int idx = type - 1; + unsigned nofs_flag; struct list_head *idle_ws = &btrfs_comp_ws[idx].idle_ws; spinlock_t *ws_lock = &btrfs_comp_ws[idx].ws_lock; @@ -830,7 +788,15 @@ again: atomic_inc(total_ws); spin_unlock(ws_lock); + /* + * Allocation helpers call vmalloc that can't use GFP_NOFS, so we have + * to turn it off here because we might get called from the restricted + * context of btrfs_compress_bio/btrfs_compress_pages + */ + nofs_flag = memalloc_nofs_save(); workspace = btrfs_compress_op[idx]->alloc_workspace(); + memalloc_nofs_restore(nofs_flag); + if (IS_ERR(workspace)) { atomic_dec(total_ws); wake_up(ws_wait); @@ -961,19 +927,16 @@ int btrfs_compress_pages(int type, struct address_space *mapping, * be contiguous. They all correspond to the range of bytes covered by * the compressed extent. */ -static int btrfs_decompress_bio(int type, struct page **pages_in, - u64 disk_start, struct bio *orig_bio, - size_t srclen) +static int btrfs_decompress_bio(struct compressed_bio *cb) { struct list_head *workspace; int ret; + int type = cb->compress_type; workspace = find_workspace(type); - - ret = btrfs_compress_op[type-1]->decompress_bio(workspace, pages_in, - disk_start, orig_bio, - srclen); + ret = btrfs_compress_op[type - 1]->decompress_bio(workspace, cb); free_workspace(type, workspace); + return ret; } diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 39ec43ab8df1..89bcf975efb8 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -34,6 +34,45 @@ /* Maximum size of data before compression */ #define BTRFS_MAX_UNCOMPRESSED (SZ_128K) +struct compressed_bio { + /* number of bios pending for this compressed extent */ + refcount_t pending_bios; + + /* the pages with the compressed data on them */ + struct page **compressed_pages; + + /* inode that owns this data */ + struct inode *inode; + + /* starting offset in the inode for our pages */ + u64 start; + + /* number of bytes in the inode we're working on */ + unsigned long len; + + /* number of bytes on disk */ + unsigned long compressed_len; + + /* the compression algorithm for this bio */ + int compress_type; + + /* number of compressed pages in the array */ + unsigned long nr_pages; + + /* IO errors */ + int errors; + int mirror_num; + + /* for reads, this is the bio we are copying the data into */ + struct bio *orig_bio; + + /* + * the start of a variable length array of checksums only + * used by reads + */ + u32 sums; +}; + void btrfs_init_compress(void); void btrfs_exit_compress(void); @@ -78,10 +117,7 @@ struct btrfs_compress_op { unsigned long *total_out); int (*decompress_bio)(struct list_head *workspace, - struct page **pages_in, - u64 disk_start, - struct bio *orig_bio, - size_t srclen); + struct compressed_bio *cb); int (*decompress)(struct list_head *workspace, unsigned char *data_in, diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index a3a75f1de002..3f4daa9d6e2c 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -19,7 +19,7 @@ #include <linux/sched.h> #include <linux/slab.h> #include <linux/rbtree.h> -#include <linux/vmalloc.h> +#include <linux/mm.h> #include "ctree.h" #include "disk-io.h" #include "transaction.h" @@ -3667,14 +3667,14 @@ static noinline int __push_leaf_right(struct btrfs_fs_info *fs_info, /* make room in the right data area */ data_end = leaf_data_end(fs_info, right); memmove_extent_buffer(right, - btrfs_leaf_data(right) + data_end - push_space, - btrfs_leaf_data(right) + data_end, + BTRFS_LEAF_DATA_OFFSET + data_end - push_space, + BTRFS_LEAF_DATA_OFFSET + data_end, BTRFS_LEAF_DATA_SIZE(fs_info) - data_end); /* copy from the left data area */ - copy_extent_buffer(right, left, btrfs_leaf_data(right) + + copy_extent_buffer(right, left, BTRFS_LEAF_DATA_OFFSET + BTRFS_LEAF_DATA_SIZE(fs_info) - push_space, - btrfs_leaf_data(left) + leaf_data_end(fs_info, left), + BTRFS_LEAF_DATA_OFFSET + leaf_data_end(fs_info, left), push_space); memmove_extent_buffer(right, btrfs_item_nr_offset(push_items), @@ -3888,9 +3888,9 @@ static noinline int __push_leaf_left(struct btrfs_fs_info *fs_info, push_space = BTRFS_LEAF_DATA_SIZE(fs_info) - btrfs_item_offset_nr(right, push_items - 1); - copy_extent_buffer(left, right, btrfs_leaf_data(left) + + copy_extent_buffer(left, right, BTRFS_LEAF_DATA_OFFSET + leaf_data_end(fs_info, left) - push_space, - btrfs_leaf_data(right) + + BTRFS_LEAF_DATA_OFFSET + btrfs_item_offset_nr(right, push_items - 1), push_space); old_left_nritems = btrfs_header_nritems(left); @@ -3917,9 +3917,9 @@ static noinline int __push_leaf_left(struct btrfs_fs_info *fs_info, if (push_items < right_nritems) { push_space = btrfs_item_offset_nr(right, push_items - 1) - leaf_data_end(fs_info, right); - memmove_extent_buffer(right, btrfs_leaf_data(right) + + memmove_extent_buffer(right, BTRFS_LEAF_DATA_OFFSET + BTRFS_LEAF_DATA_SIZE(fs_info) - push_space, - btrfs_leaf_data(right) + + BTRFS_LEAF_DATA_OFFSET + leaf_data_end(fs_info, right), push_space); memmove_extent_buffer(right, btrfs_item_nr_offset(0), @@ -4069,8 +4069,8 @@ static noinline void copy_for_split(struct btrfs_trans_handle *trans, nritems * sizeof(struct btrfs_item)); copy_extent_buffer(right, l, - btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(fs_info) - - data_copy_size, btrfs_leaf_data(l) + + BTRFS_LEAF_DATA_OFFSET + BTRFS_LEAF_DATA_SIZE(fs_info) - + data_copy_size, BTRFS_LEAF_DATA_OFFSET + leaf_data_end(fs_info, l), data_copy_size); rt_data_off = BTRFS_LEAF_DATA_SIZE(fs_info) - btrfs_item_end_nr(l, mid); @@ -4607,8 +4607,8 @@ void btrfs_truncate_item(struct btrfs_fs_info *fs_info, /* shift the data */ if (from_end) { - memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + - data_end + size_diff, btrfs_leaf_data(leaf) + + memmove_extent_buffer(leaf, BTRFS_LEAF_DATA_OFFSET + + data_end + size_diff, BTRFS_LEAF_DATA_OFFSET + data_end, old_data_start + new_size - data_end); } else { struct btrfs_disk_key disk_key; @@ -4634,8 +4634,8 @@ void btrfs_truncate_item(struct btrfs_fs_info *fs_info, } } - memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + - data_end + size_diff, btrfs_leaf_data(leaf) + + memmove_extent_buffer(leaf, BTRFS_LEAF_DATA_OFFSET + + data_end + size_diff, BTRFS_LEAF_DATA_OFFSET + data_end, old_data_start - data_end); offset = btrfs_disk_key_offset(&disk_key); @@ -4707,8 +4707,8 @@ void btrfs_extend_item(struct btrfs_fs_info *fs_info, struct btrfs_path *path, } /* shift the data */ - memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + - data_end - data_size, btrfs_leaf_data(leaf) + + memmove_extent_buffer(leaf, BTRFS_LEAF_DATA_OFFSET + + data_end - data_size, BTRFS_LEAF_DATA_OFFSET + data_end, old_data - data_end); data_end = old_data; @@ -4790,8 +4790,8 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, (nritems - slot) * sizeof(struct btrfs_item)); /* shift the data */ - memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + - data_end - total_data, btrfs_leaf_data(leaf) + + memmove_extent_buffer(leaf, BTRFS_LEAF_DATA_OFFSET + + data_end - total_data, BTRFS_LEAF_DATA_OFFSET + data_end, old_data - data_end); data_end = old_data; } @@ -4983,9 +4983,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, if (slot + nr != nritems) { int data_end = leaf_data_end(fs_info, leaf); - memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + + memmove_extent_buffer(leaf, BTRFS_LEAF_DATA_OFFSET + data_end + dsize, - btrfs_leaf_data(leaf) + data_end, + BTRFS_LEAF_DATA_OFFSET + data_end, last_off - data_end); for (i = slot + nr; i < nritems; i++) { diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 643c70d2b2e6..f82f5baa31ad 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -48,7 +48,6 @@ struct btrfs_trans_handle; struct btrfs_transaction; struct btrfs_pending_snapshot; extern struct kmem_cache *btrfs_trans_handle_cachep; -extern struct kmem_cache *btrfs_transaction_cachep; extern struct kmem_cache *btrfs_bit_radix_cachep; extern struct kmem_cache *btrfs_path_cachep; extern struct kmem_cache *btrfs_free_space_cachep; @@ -716,6 +715,8 @@ struct btrfs_delayed_root; #define BTRFS_FS_BTREE_ERR 11 #define BTRFS_FS_LOG1_ERR 12 #define BTRFS_FS_LOG2_ERR 13 +#define BTRFS_FS_QUOTA_OVERRIDE 14 + /* * Indicate that a whole-filesystem exclusive operation is running * (device replace, resize, device add/delete, balance) @@ -748,8 +749,7 @@ struct btrfs_fs_info { struct rb_root block_group_cache_tree; /* keep track of unallocated space */ - spinlock_t free_chunk_lock; - u64 free_chunk_space; + atomic64_t free_chunk_space; struct extent_io_tree freed_extents[2]; struct extent_io_tree *pinned_extents; @@ -1292,6 +1292,8 @@ static inline u32 BTRFS_LEAF_DATA_SIZE(const struct btrfs_fs_info *info) return __BTRFS_LEAF_DATA_SIZE(info->nodesize); } +#define BTRFS_LEAF_DATA_OFFSET offsetof(struct btrfs_leaf, items) + static inline u32 BTRFS_MAX_ITEM_SIZE(const struct btrfs_fs_info *info) { return BTRFS_LEAF_DATA_SIZE(info) - sizeof(struct btrfs_item); @@ -2324,10 +2326,6 @@ static inline int btrfs_super_csum_size(struct btrfs_super_block *s) return btrfs_csum_sizes[t]; } -static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) -{ - return offsetof(struct btrfs_leaf, items); -} /* * The leaf data grows from end-to-front in the node. @@ -2538,11 +2536,11 @@ BTRFS_SETGET_STACK_FUNCS(stack_dev_replace_cursor_right, /* helper function to cast into the data area of the leaf. */ #define btrfs_item_ptr(leaf, slot, type) \ - ((type *)(btrfs_leaf_data(leaf) + \ + ((type *)(BTRFS_LEAF_DATA_OFFSET + \ btrfs_item_offset_nr(leaf, slot))) #define btrfs_item_ptr_offset(leaf, slot) \ - ((unsigned long)(btrfs_leaf_data(leaf) + \ + ((unsigned long)(BTRFS_LEAF_DATA_OFFSET + \ btrfs_item_offset_nr(leaf, slot))) static inline bool btrfs_mixed_space_info(struct btrfs_space_info *space_info) @@ -2680,7 +2678,9 @@ void btrfs_get_block_group_trimming(struct btrfs_block_group_cache *cache); void btrfs_put_block_group_trimming(struct btrfs_block_group_cache *cache); void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); -u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data); +u64 btrfs_data_alloc_profile(struct btrfs_fs_info *fs_info); +u64 btrfs_metadata_alloc_profile(struct btrfs_fs_info *fs_info); +u64 btrfs_system_alloc_profile(struct btrfs_fs_info *fs_info); void btrfs_clear_space_info_full(struct btrfs_fs_info *info); enum btrfs_reserve_flush_enum { @@ -2703,9 +2703,13 @@ enum btrfs_flush_state { COMMIT_TRANS = 6, }; -int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len); int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes); -void btrfs_free_reserved_data_space(struct inode *inode, u64 start, u64 len); +int btrfs_check_data_free_space(struct inode *inode, + struct extent_changeset **reserved, u64 start, u64 len); +void btrfs_free_reserved_data_space(struct inode *inode, + struct extent_changeset *reserved, u64 start, u64 len); +void btrfs_delalloc_release_space(struct inode *inode, + struct extent_changeset *reserved, u64 start, u64 len); void btrfs_free_reserved_data_space_noquota(struct inode *inode, u64 start, u64 len); void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, @@ -2722,8 +2726,8 @@ void btrfs_subvolume_release_metadata(struct btrfs_fs_info *fs_info, struct btrfs_block_rsv *rsv); int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes); void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes); -int btrfs_delalloc_reserve_space(struct inode *inode, u64 start, u64 len); -void btrfs_delalloc_release_space(struct inode *inode, u64 start, u64 len); +int btrfs_delalloc_reserve_space(struct inode *inode, + struct extent_changeset **reserved, u64 start, u64 len); void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, unsigned short type); struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_fs_info *fs_info, unsigned short type); @@ -3171,6 +3175,7 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, int btrfs_merge_bio_hook(struct page *page, unsigned long offset, size_t size, struct bio *bio, unsigned long bio_flags); +void btrfs_set_range_writeback(void *private_data, u64 start, u64 end); int btrfs_page_mkwrite(struct vm_fault *vmf); int btrfs_readpage(struct file *file, struct page *page); void btrfs_evict_inode(struct inode *inode); diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index 60a750678a82..c24d615e3d7f 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c @@ -468,7 +468,7 @@ int verify_dir_item(struct btrfs_fs_info *fs_info, if (btrfs_dir_name_len(leaf, dir_item) > namelen) { btrfs_crit(fs_info, "invalid dir item name len: %u", - (unsigned)btrfs_dir_data_len(leaf, dir_item)); + (unsigned)btrfs_dir_name_len(leaf, dir_item)); return 1; } diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8685d67185d0..cb79bce3a972 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -89,7 +89,6 @@ struct btrfs_end_io_wq { struct btrfs_fs_info *info; int error; enum btrfs_wq_endio_type metadata; - struct list_head list; struct btrfs_work work; }; @@ -118,9 +117,9 @@ void btrfs_end_io_wq_exit(void) * just before they are sent down the IO stack. */ struct async_submit_bio { - struct inode *inode; + void *private_data; + struct btrfs_fs_info *fs_info; struct bio *bio; - struct list_head list; extent_submit_bio_hook_t *submit_bio_start; extent_submit_bio_hook_t *submit_bio_done; int mirror_num; @@ -871,7 +870,7 @@ static void run_one_async_start(struct btrfs_work *work) int ret; async = container_of(work, struct async_submit_bio, work); - ret = async->submit_bio_start(async->inode, async->bio, + ret = async->submit_bio_start(async->private_data, async->bio, async->mirror_num, async->bio_flags, async->bio_offset); if (ret) @@ -885,7 +884,7 @@ static void run_one_async_done(struct btrfs_work *work) int limit; async = container_of(work, struct async_submit_bio, work); - fs_info = BTRFS_I(async->inode)->root->fs_info; + fs_info = async->fs_info; limit = btrfs_async_submit_limit(fs_info); limit = limit * 2 / 3; @@ -904,7 +903,7 @@ static void run_one_async_done(struct btrfs_work *work) return; } - async->submit_bio_done(async->inode, async->bio, async->mirror_num, + async->submit_bio_done(async->private_data, async->bio, async->mirror_num, async->bio_flags, async->bio_offset); } @@ -916,10 +915,9 @@ static void run_one_async_free(struct btrfs_work *work) kfree(async); } -int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, - struct bio *bio, int mirror_num, - unsigned long bio_flags, - u64 bio_offset, +int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct bio *bio, + int mirror_num, unsigned long bio_flags, + u64 bio_offset, void *private_data, extent_submit_bio_hook_t *submit_bio_start, extent_submit_bio_hook_t *submit_bio_done) { @@ -929,7 +927,8 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, if (!async) return -ENOMEM; - async->inode = inode; + async->private_data = private_data; + async->fs_info = fs_info; async->bio = bio; async->mirror_num = mirror_num; async->submit_bio_start = submit_bio_start; @@ -975,7 +974,7 @@ static int btree_csum_one_bio(struct bio *bio) return ret; } -static int __btree_submit_bio_start(struct inode *inode, struct bio *bio, +static int __btree_submit_bio_start(void *private_data, struct bio *bio, int mirror_num, unsigned long bio_flags, u64 bio_offset) { @@ -986,10 +985,11 @@ static int __btree_submit_bio_start(struct inode *inode, struct bio *bio, return btree_csum_one_bio(bio); } -static int __btree_submit_bio_done(struct inode *inode, struct bio *bio, +static int __btree_submit_bio_done(void *private_data, struct bio *bio, int mirror_num, unsigned long bio_flags, u64 bio_offset) { + struct inode *inode = private_data; int ret; /* @@ -1015,10 +1015,11 @@ static int check_async_write(unsigned long bio_flags) return 1; } -static int btree_submit_bio_hook(struct inode *inode, struct bio *bio, +static int btree_submit_bio_hook(void *private_data, struct bio *bio, int mirror_num, unsigned long bio_flags, u64 bio_offset) { + struct inode *inode = private_data; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); int async = check_async_write(bio_flags); int ret; @@ -1043,8 +1044,8 @@ static int btree_submit_bio_hook(struct inode *inode, struct bio *bio, * kthread helpers are used to submit writes so that * checksumming can happen in parallel across all CPUs */ - ret = btrfs_wq_submit_bio(fs_info, inode, bio, mirror_num, 0, - bio_offset, + ret = btrfs_wq_submit_bio(fs_info, bio, mirror_num, 0, + bio_offset, private_data, __btree_submit_bio_start, __btree_submit_bio_done); } @@ -1222,10 +1223,10 @@ int btrfs_write_tree_block(struct extent_buffer *buf) buf->start + buf->len - 1); } -int btrfs_wait_tree_block_writeback(struct extent_buffer *buf) +void btrfs_wait_tree_block_writeback(struct extent_buffer *buf) { - return filemap_fdatawait_range(buf->pages[0]->mapping, - buf->start, buf->start + buf->len - 1); + filemap_fdatawait_range(buf->pages[0]->mapping, + buf->start, buf->start + buf->len - 1); } struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, @@ -1347,8 +1348,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info, root->log_transid_committed = -1; root->last_log_commit = 0; if (!dummy) - extent_io_tree_init(&root->dirty_log_pages, - fs_info->btree_inode->i_mapping); + extent_io_tree_init(&root->dirty_log_pages, NULL); memset(&root->root_key, 0, sizeof(root->root_key)); memset(&root->root_item, 0, sizeof(root->root_item)); @@ -2309,7 +2309,7 @@ static void btrfs_init_btree_inode(struct btrfs_fs_info *fs_info) inode->i_mapping->a_ops = &btree_aops; RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node); - extent_io_tree_init(&BTRFS_I(inode)->io_tree, inode->i_mapping); + extent_io_tree_init(&BTRFS_I(inode)->io_tree, inode); BTRFS_I(inode)->io_tree.track_uptodate = 0; extent_map_tree_init(&BTRFS_I(inode)->extent_tree); @@ -2626,7 +2626,6 @@ int open_ctree(struct super_block *sb, spin_lock_init(&fs_info->fs_roots_radix_lock); spin_lock_init(&fs_info->delayed_iput_lock); spin_lock_init(&fs_info->defrag_inodes_lock); - spin_lock_init(&fs_info->free_chunk_lock); spin_lock_init(&fs_info->tree_mod_seq_lock); spin_lock_init(&fs_info->super_lock); spin_lock_init(&fs_info->qgroup_op_lock); @@ -2667,7 +2666,7 @@ int open_ctree(struct super_block *sb, fs_info->max_inline = BTRFS_DEFAULT_MAX_INLINE; fs_info->metadata_ratio = 0; fs_info->defrag_inodes = RB_ROOT; - fs_info->free_chunk_space = 0; + atomic64_set(&fs_info->free_chunk_space, 0); fs_info->tree_mod_log = RB_ROOT; fs_info->commit_interval = BTRFS_DEFAULT_COMMIT_INTERVAL; fs_info->avg_delayed_ref_runtime = NSEC_PER_SEC >> 6; /* div by 64 */ @@ -2704,10 +2703,8 @@ int open_ctree(struct super_block *sb, fs_info->block_group_cache_tree = RB_ROOT; fs_info->first_logical_byte = (u64)-1; - extent_io_tree_init(&fs_info->freed_extents[0], - fs_info->btree_inode->i_mapping); - extent_io_tree_init(&fs_info->freed_extents[1], - fs_info->btree_inode->i_mapping); + extent_io_tree_init(&fs_info->freed_extents[0], NULL); + extent_io_tree_init(&fs_info->freed_extents[1], NULL); fs_info->pinned_extents = &fs_info->freed_extents[0]; set_bit(BTRFS_FS_BARRIER, &fs_info->flags); @@ -3467,10 +3464,12 @@ static int write_dev_supers(struct btrfs_device *device, * we fua the first super. The others we allow * to go down lazy. */ - if (i == 0) - ret = btrfsic_submit_bh(REQ_OP_WRITE, REQ_FUA, bh); - else + if (i == 0) { + ret = btrfsic_submit_bh(REQ_OP_WRITE, + REQ_SYNC | REQ_FUA, bh); + } else { ret = btrfsic_submit_bh(REQ_OP_WRITE, REQ_SYNC, bh); + } if (ret) errors++; } @@ -3507,6 +3506,10 @@ static int write_dev_flush(struct btrfs_device *device, int wait) if (wait) { bio = device->flush_bio; if (!bio) + /* + * This means the alloc has failed with ENOMEM, however + * here we return 0, as its not a device error. + */ return 0; wait_for_completion(&device->flush_wait); @@ -3535,7 +3538,7 @@ static int write_dev_flush(struct btrfs_device *device, int wait) bio->bi_end_io = btrfs_end_empty_barrier; bio->bi_bdev = device->bdev; - bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; + bio->bi_opf = REQ_OP_WRITE | REQ_SYNC | REQ_PREFLUSH; init_completion(&device->flush_wait); bio->bi_private = &device->flush_wait; device->flush_bio = bio; @@ -3546,6 +3549,32 @@ static int write_dev_flush(struct btrfs_device *device, int wait) return 0; } +static int check_barrier_error(struct btrfs_fs_devices *fsdevs) +{ + int submit_flush_error = 0; + int dev_flush_error = 0; + struct btrfs_device *dev; + int tolerance; + + list_for_each_entry_rcu(dev, &fsdevs->devices, dev_list) { + if (!dev->bdev) { + submit_flush_error++; + dev_flush_error++; + continue; + } + if (dev->last_flush_error == -ENOMEM) + submit_flush_error++; + if (dev->last_flush_error && dev->last_flush_error != -ENOMEM) + dev_flush_error++; + } + + tolerance = fsdevs->fs_info->num_tolerated_disk_barrier_failures; + if (submit_flush_error > tolerance || dev_flush_error > tolerance) + return -EIO; + + return 0; +} + /* * send an empty flush down to each device in parallel, * then wait for them @@ -3573,6 +3602,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info) ret = write_dev_flush(dev, 0); if (ret) errors_send++; + dev->last_flush_error = ret; } /* wait for all the barriers */ @@ -3587,12 +3617,30 @@ static int barrier_all_devices(struct btrfs_fs_info *info) continue; ret = write_dev_flush(dev, 1); - if (ret) + if (ret) { + dev->last_flush_error = ret; errors_wait++; + } + } + + /* + * Try hard in case of flush. Lets say, in RAID1 we have + * the following situation + * dev1: EIO dev2: ENOMEM + * this is not a fatal error as we hope to recover from + * ENOMEM in the next attempt to flush. + * But the following is considered as fatal + * dev1: ENOMEM dev2: ENOMEM + * dev1: bdev == NULL dev2: ENOMEM + */ + if (errors_send || errors_wait) { + /* + * At some point we need the status of all disks + * to arrive at the volume status. So error checking + * is being pushed to a separate loop. + */ + return check_barrier_error(info->fs_devices); } - if (errors_send > info->num_tolerated_disk_barrier_failures || - errors_wait > info->num_tolerated_disk_barrier_failures) - return -EIO; return 0; } @@ -4576,11 +4624,6 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, cur_trans->state =TRANS_STATE_COMPLETED; wake_up(&cur_trans->commit_wait); - - /* - memset(cur_trans, 0, sizeof(*cur_trans)); - kmem_cache_free(btrfs_transaction_cachep, cur_trans); - */ } static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info) @@ -4636,6 +4679,12 @@ static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info) return 0; } +static struct btrfs_fs_info *btree_fs_info(void *private_data) +{ + struct inode *inode = private_data; + return btrfs_sb(inode->i_sb); +} + static const struct extent_io_ops btree_extent_io_ops = { /* mandatory callbacks */ .submit_bio_hook = btree_submit_bio_hook, @@ -4643,6 +4692,8 @@ static const struct extent_io_ops btree_extent_io_ops = { /* note we're sharing with inode.c for the merge bio hook */ .merge_bio_hook = btrfs_merge_bio_hook, .readpage_io_failed_hook = btree_io_failed_hook, + .set_range_writeback = btrfs_set_range_writeback, + .tree_fs_info = btree_fs_info, /* optional callbacks */ }; diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 21f1ceb85b76..4654d129aa76 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -120,14 +120,14 @@ u32 btrfs_csum_data(const char *data, u32 seed, size_t len); void btrfs_csum_final(u32 crc, u8 *result); int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, enum btrfs_wq_endio_type metadata); -int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, - struct bio *bio, int mirror_num, - unsigned long bio_flags, u64 bio_offset, +int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct bio *bio, + int mirror_num, unsigned long bio_flags, + u64 bio_offset, void *private_data, extent_submit_bio_hook_t *submit_bio_start, extent_submit_bio_hook_t *submit_bio_done); unsigned long btrfs_async_submit_limit(struct btrfs_fs_info *info); int btrfs_write_tree_block(struct extent_buffer *buf); -int btrfs_wait_tree_block_writeback(struct extent_buffer *buf); +void btrfs_wait_tree_block_writeback(struct extent_buffer *buf); int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); int btrfs_add_log_tree(struct btrfs_trans_handle *trans, diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index e390451c72e6..cb0b9248ee20 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -97,10 +97,11 @@ static int btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache, u64 num_bytes, int delalloc); static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, u64 num_bytes); -static int __reserve_metadata_bytes(struct btrfs_root *root, +static int __reserve_metadata_bytes(struct btrfs_fs_info *fs_info, struct btrfs_space_info *space_info, u64 orig_bytes, - enum btrfs_reserve_flush_enum flush); + enum btrfs_reserve_flush_enum flush, + bool system_chunk); static void space_info_add_new_bytes(struct btrfs_fs_info *fs_info, struct btrfs_space_info *space_info, u64 num_bytes); @@ -3364,6 +3365,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group, struct btrfs_fs_info *fs_info = block_group->fs_info; struct btrfs_root *root = fs_info->tree_root; struct inode *inode = NULL; + struct extent_changeset *data_reserved = NULL; u64 alloc_hint = 0; int dcs = BTRFS_DC_ERROR; u64 num_pages = 0; @@ -3483,7 +3485,7 @@ again: num_pages *= 16; num_pages *= PAGE_SIZE; - ret = btrfs_check_data_free_space(inode, 0, num_pages); + ret = btrfs_check_data_free_space(inode, &data_reserved, 0, num_pages); if (ret) goto out_put; @@ -3514,6 +3516,7 @@ out: block_group->disk_cache_state = dcs; spin_unlock(&block_group->lock); + extent_changeset_free(data_reserved); return ret; } @@ -3924,87 +3927,83 @@ static const char *alloc_name(u64 flags) }; } -static int update_space_info(struct btrfs_fs_info *info, u64 flags, - u64 total_bytes, u64 bytes_used, - u64 bytes_readonly, - struct btrfs_space_info **space_info) +static int create_space_info(struct btrfs_fs_info *info, u64 flags, + struct btrfs_space_info **new) { - struct btrfs_space_info *found; + + struct btrfs_space_info *space_info; int i; - int factor; int ret; - if (flags & (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1 | - BTRFS_BLOCK_GROUP_RAID10)) - factor = 2; - else - factor = 1; - - found = __find_space_info(info, flags); - if (found) { - spin_lock(&found->lock); - found->total_bytes += total_bytes; - found->disk_total += total_bytes * factor; - found->bytes_used += bytes_used; - found->disk_used += bytes_used * factor; - found->bytes_readonly += bytes_readonly; - if (total_bytes > 0) - found->full = 0; - space_info_add_new_bytes(info, found, total_bytes - - bytes_used - bytes_readonly); - spin_unlock(&found->lock); - *space_info = found; - return 0; - } - found = kzalloc(sizeof(*found), GFP_NOFS); - if (!found) + space_info = kzalloc(sizeof(*space_info), GFP_NOFS); + if (!space_info) return -ENOMEM; - ret = percpu_counter_init(&found->total_bytes_pinned, 0, GFP_KERNEL); + ret = percpu_counter_init(&space_info->total_bytes_pinned, 0, + GFP_KERNEL); if (ret) { - kfree(found); + kfree(space_info); return ret; } for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) - INIT_LIST_HEAD(&found->block_groups[i]); - init_rwsem(&found->groups_sem); - spin_lock_init(&found->lock); - found->flags = flags & BTRFS_BLOCK_GROUP_TYPE_MASK; - found->total_bytes = total_bytes; - found->disk_total = total_bytes * factor; - found->bytes_used = bytes_used; - found->disk_used = bytes_used * factor; - found->bytes_pinned = 0; - found->bytes_reserved = 0; - found->bytes_readonly = bytes_readonly; - found->bytes_may_use = 0; - found->full = 0; - found->max_extent_size = 0; - found->force_alloc = CHUNK_ALLOC_NO_FORCE; - found->chunk_alloc = 0; - found->flush = 0; - init_waitqueue_head(&found->wait); - INIT_LIST_HEAD(&found->ro_bgs); - INIT_LIST_HEAD(&found->tickets); - INIT_LIST_HEAD(&found->priority_tickets); - - ret = kobject_init_and_add(&found->kobj, &space_info_ktype, + INIT_LIST_HEAD(&space_info->block_groups[i]); + init_rwsem(&space_info->groups_sem); + spin_lock_init(&space_info->lock); + space_info->flags = flags & BTRFS_BLOCK_GROUP_TYPE_MASK; + space_info->force_alloc = CHUNK_ALLOC_NO_FORCE; + init_waitqueue_head(&space_info->wait); + INIT_LIST_HEAD(&space_info->ro_bgs); + INIT_LIST_HEAD(&space_info->tickets); + INIT_LIST_HEAD(&space_info->priority_tickets); + + ret = kobject_init_and_add(&space_info->kobj, &space_info_ktype, info->space_info_kobj, "%s", - alloc_name(found->flags)); + alloc_name(space_info->flags)); if (ret) { - kfree(found); + percpu_counter_destroy(&space_info->total_bytes_pinned); + kfree(space_info); return ret; } - *space_info = found; - list_add_rcu(&found->list, &info->space_info); + *new = space_info; + list_add_rcu(&space_info->list, &info->space_info); if (flags & BTRFS_BLOCK_GROUP_DATA) - info->data_sinfo = found; + info->data_sinfo = space_info; return ret; } +static void update_space_info(struct btrfs_fs_info *info, u64 flags, + u64 total_bytes, u64 bytes_used, + u64 bytes_readonly, + struct btrfs_space_info **space_info) +{ + struct btrfs_space_info *found; + int factor; + + if (flags & (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1 | + BTRFS_BLOCK_GROUP_RAID10)) + factor = 2; + else + factor = 1; + + found = __find_space_info(info, flags); + ASSERT(found); + spin_lock(&found->lock); + found->total_bytes += total_bytes; + found->disk_total += total_bytes * factor; + found->bytes_used += bytes_used; + found->disk_used += bytes_used * factor; + found->bytes_readonly += bytes_readonly; + if (total_bytes > 0) + found->full = 0; + space_info_add_new_bytes(info, found, total_bytes - + bytes_used - bytes_readonly); + spin_unlock(&found->lock); + *space_info = found; +} + static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) { u64 extra_flags = chunk_to_extended(flags) & @@ -4120,7 +4119,7 @@ static u64 get_alloc_profile(struct btrfs_fs_info *fs_info, u64 orig_flags) return btrfs_reduce_alloc_profile(fs_info, flags); } -u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data) +static u64 get_alloc_profile_by_root(struct btrfs_root *root, int data) { struct btrfs_fs_info *fs_info = root->fs_info; u64 flags; @@ -4137,6 +4136,21 @@ u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data) return ret; } +u64 btrfs_data_alloc_profile(struct btrfs_fs_info *fs_info) +{ + return get_alloc_profile(fs_info, BTRFS_BLOCK_GROUP_DATA); +} + +u64 btrfs_metadata_alloc_profile(struct btrfs_fs_info *fs_info) +{ + return get_alloc_profile(fs_info, BTRFS_BLOCK_GROUP_METADATA); +} + +u64 btrfs_system_alloc_profile(struct btrfs_fs_info *fs_info) +{ + return get_alloc_profile(fs_info, BTRFS_BLOCK_GROUP_SYSTEM); +} + static u64 btrfs_space_info_used(struct btrfs_space_info *s_info, bool may_use_included) { @@ -4186,7 +4200,7 @@ again: data_sinfo->force_alloc = CHUNK_ALLOC_FORCE; spin_unlock(&data_sinfo->lock); alloc: - alloc_target = btrfs_get_alloc_profile(root, 1); + alloc_target = btrfs_data_alloc_profile(fs_info); /* * It is ugly that we don't call nolock join * transaction for the free space inode case here. @@ -4277,12 +4291,8 @@ commit_trans: return ret; } -/* - * New check_data_free_space() with ability for precious data reservation - * Will replace old btrfs_check_data_free_space(), but for patch split, - * add a new function first and then replace it. - */ -int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len) +int btrfs_check_data_free_space(struct inode *inode, + struct extent_changeset **reserved, u64 start, u64 len) { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); int ret; @@ -4297,9 +4307,11 @@ int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len) return ret; /* Use new btrfs_qgroup_reserve_data to reserve precious data space. */ - ret = btrfs_qgroup_reserve_data(inode, start, len); - if (ret) + ret = btrfs_qgroup_reserve_data(inode, reserved, start, len); + if (ret < 0) btrfs_free_reserved_data_space_noquota(inode, start, len); + else + ret = 0; return ret; } @@ -4340,7 +4352,8 @@ void btrfs_free_reserved_data_space_noquota(struct inode *inode, u64 start, * This one will handle the per-inode data rsv map for accurate reserved * space framework. */ -void btrfs_free_reserved_data_space(struct inode *inode, u64 start, u64 len) +void btrfs_free_reserved_data_space(struct inode *inode, + struct extent_changeset *reserved, u64 start, u64 len) { struct btrfs_root *root = BTRFS_I(inode)->root; @@ -4350,7 +4363,7 @@ void btrfs_free_reserved_data_space(struct inode *inode, u64 start, u64 len) start = round_down(start, root->fs_info->sectorsize); btrfs_free_reserved_data_space_noquota(inode, start, len); - btrfs_qgroup_free_data(inode, start, len); + btrfs_qgroup_free_data(inode, reserved, start, len); } static void force_metadata_allocation(struct btrfs_fs_info *info) @@ -4462,9 +4475,8 @@ void check_system_chunk(struct btrfs_trans_handle *trans, } if (left < thresh) { - u64 flags; + u64 flags = btrfs_system_alloc_profile(fs_info); - flags = btrfs_get_alloc_profile(fs_info->chunk_root, 0); /* * Ignore failure to create system chunk. We might end up not * needing it, as we might not need to COW all nodes/leafs from @@ -4505,10 +4517,10 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, space_info = __find_space_info(fs_info, flags); if (!space_info) { - ret = update_space_info(fs_info, flags, 0, 0, 0, &space_info); - BUG_ON(ret); /* -ENOMEM */ + ret = create_space_info(fs_info, flags, &space_info); + if (ret) + return ret; } - BUG_ON(!space_info); /* Logic error */ again: spin_lock(&space_info->lock); @@ -4613,11 +4625,11 @@ out: return ret; } -static int can_overcommit(struct btrfs_root *root, +static int can_overcommit(struct btrfs_fs_info *fs_info, struct btrfs_space_info *space_info, u64 bytes, - enum btrfs_reserve_flush_enum flush) + enum btrfs_reserve_flush_enum flush, + bool system_chunk) { - struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; u64 profile; u64 space_size; @@ -4628,7 +4640,11 @@ static int can_overcommit(struct btrfs_root *root, if (space_info->flags & BTRFS_BLOCK_GROUP_DATA) return 0; - profile = btrfs_get_alloc_profile(root, 0); + if (system_chunk) + profile = btrfs_system_alloc_profile(fs_info); + else + profile = btrfs_metadata_alloc_profile(fs_info); + used = btrfs_space_info_used(space_info, false); /* @@ -4645,9 +4661,7 @@ static int can_overcommit(struct btrfs_root *root, used += space_info->bytes_may_use; - spin_lock(&fs_info->free_chunk_lock); - avail = fs_info->free_chunk_space; - spin_unlock(&fs_info->free_chunk_lock); + avail = atomic64_read(&fs_info->free_chunk_space); /* * If we have dup, raid1 or raid10 then only half of the free @@ -4715,10 +4729,9 @@ static inline int calc_reclaim_items_nr(struct btrfs_fs_info *fs_info, /* * shrink metadata reservation for delalloc */ -static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, - bool wait_ordered) +static void shrink_delalloc(struct btrfs_fs_info *fs_info, u64 to_reclaim, + u64 orig, bool wait_ordered) { - struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_block_rsv *block_rsv; struct btrfs_space_info *space_info; struct btrfs_trans_handle *trans; @@ -4775,7 +4788,7 @@ skip_async: else flush = BTRFS_RESERVE_NO_FLUSH; spin_lock(&space_info->lock); - if (can_overcommit(root, space_info, orig, flush)) { + if (can_overcommit(fs_info, space_info, orig, flush, false)) { spin_unlock(&space_info->lock); break; } @@ -4837,14 +4850,14 @@ static int may_commit_transaction(struct btrfs_fs_info *fs_info, spin_lock(&delayed_rsv->lock); if (percpu_counter_compare(&space_info->total_bytes_pinned, - bytes - delayed_rsv->size) >= 0) { + bytes - delayed_rsv->size) < 0) { spin_unlock(&delayed_rsv->lock); return -ENOSPC; } spin_unlock(&delayed_rsv->lock); commit: - trans = btrfs_join_transaction(fs_info->fs_root); + trans = btrfs_join_transaction(fs_info->extent_root); if (IS_ERR(trans)) return -ENOSPC; @@ -4862,7 +4875,7 @@ static int flush_space(struct btrfs_fs_info *fs_info, struct btrfs_space_info *space_info, u64 num_bytes, u64 orig_bytes, int state) { - struct btrfs_root *root = fs_info->fs_root; + struct btrfs_root *root = fs_info->extent_root; struct btrfs_trans_handle *trans; int nr; int ret = 0; @@ -4885,7 +4898,7 @@ static int flush_space(struct btrfs_fs_info *fs_info, break; case FLUSH_DELALLOC: case FLUSH_DELALLOC_WAIT: - shrink_delalloc(root, num_bytes * 2, orig_bytes, + shrink_delalloc(fs_info, num_bytes * 2, orig_bytes, state == FLUSH_DELALLOC_WAIT); break; case ALLOC_CHUNK: @@ -4895,7 +4908,7 @@ static int flush_space(struct btrfs_fs_info *fs_info, break; } ret = do_chunk_alloc(trans, fs_info, - btrfs_get_alloc_profile(root, 0), + btrfs_metadata_alloc_profile(fs_info), CHUNK_ALLOC_NO_FORCE); btrfs_end_transaction(trans); if (ret > 0 || ret == -ENOSPC) @@ -4916,8 +4929,9 @@ static int flush_space(struct btrfs_fs_info *fs_info, } static inline u64 -btrfs_calc_reclaim_metadata_size(struct btrfs_root *root, - struct btrfs_space_info *space_info) +btrfs_calc_reclaim_metadata_size(struct btrfs_fs_info *fs_info, + struct btrfs_space_info *space_info, + bool system_chunk) { struct reserve_ticket *ticket; u64 used; @@ -4932,14 +4946,15 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_root *root, return to_reclaim; to_reclaim = min_t(u64, num_online_cpus() * SZ_1M, SZ_16M); - if (can_overcommit(root, space_info, to_reclaim, - BTRFS_RESERVE_FLUSH_ALL)) + if (can_overcommit(fs_info, space_info, to_reclaim, + BTRFS_RESERVE_FLUSH_ALL, system_chunk)) return 0; used = space_info->bytes_used + space_info->bytes_reserved + space_info->bytes_pinned + space_info->bytes_readonly + space_info->bytes_may_use; - if (can_overcommit(root, space_info, SZ_1M, BTRFS_RESERVE_FLUSH_ALL)) + if (can_overcommit(fs_info, space_info, SZ_1M, + BTRFS_RESERVE_FLUSH_ALL, system_chunk)) expected = div_factor_fine(space_info->total_bytes, 95); else expected = div_factor_fine(space_info->total_bytes, 90); @@ -4953,17 +4968,18 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_root *root, return to_reclaim; } -static inline int need_do_async_reclaim(struct btrfs_space_info *space_info, - struct btrfs_root *root, u64 used) +static inline int need_do_async_reclaim(struct btrfs_fs_info *fs_info, + struct btrfs_space_info *space_info, + u64 used, bool system_chunk) { - struct btrfs_fs_info *fs_info = root->fs_info; u64 thresh = div_factor_fine(space_info->total_bytes, 98); /* If we're just plain full then async reclaim just slows us down. */ if ((space_info->bytes_used + space_info->bytes_reserved) >= thresh) return 0; - if (!btrfs_calc_reclaim_metadata_size(root, space_info)) + if (!btrfs_calc_reclaim_metadata_size(fs_info, space_info, + system_chunk)) return 0; return (used >= thresh && !btrfs_fs_closing(fs_info) && @@ -5000,8 +5016,8 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work) space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA); spin_lock(&space_info->lock); - to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info->fs_root, - space_info); + to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info, space_info, + false); if (!to_reclaim) { space_info->flush = 0; spin_unlock(&space_info->lock); @@ -5023,8 +5039,9 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work) spin_unlock(&space_info->lock); return; } - to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info->fs_root, - space_info); + to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info, + space_info, + false); ticket = list_first_entry(&space_info->tickets, struct reserve_ticket, list); if (last_tickets_id == space_info->tickets_id) { @@ -5062,8 +5079,8 @@ static void priority_reclaim_metadata_space(struct btrfs_fs_info *fs_info, int flush_state = FLUSH_DELAYED_ITEMS_NR; spin_lock(&space_info->lock); - to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info->fs_root, - space_info); + to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info, space_info, + false); if (!to_reclaim) { spin_unlock(&space_info->lock); return; @@ -5142,12 +5159,12 @@ static int wait_reserve_ticket(struct btrfs_fs_info *fs_info, * regain reservations will be made and this will fail if there is not enough * space already. */ -static int __reserve_metadata_bytes(struct btrfs_root *root, +static int __reserve_metadata_bytes(struct btrfs_fs_info *fs_info, struct btrfs_space_info *space_info, u64 orig_bytes, - enum btrfs_reserve_flush_enum flush) + enum btrfs_reserve_flush_enum flush, + bool system_chunk) { - struct btrfs_fs_info *fs_info = root->fs_info; struct reserve_ticket ticket; u64 used; int ret = 0; @@ -5169,7 +5186,8 @@ static int __reserve_metadata_bytes(struct btrfs_root *root, trace_btrfs_space_reservation(fs_info, "space_info", space_info->flags, orig_bytes, 1); ret = 0; - } else if (can_overcommit(root, space_info, orig_bytes, flush)) { + } else if (can_overcommit(fs_info, space_info, orig_bytes, flush, + system_chunk)) { space_info->bytes_may_use += orig_bytes; trace_btrfs_space_reservation(fs_info, "space_info", space_info->flags, orig_bytes, 1); @@ -5196,7 +5214,7 @@ static int __reserve_metadata_bytes(struct btrfs_root *root, orig_bytes, flush, "enospc"); queue_work(system_unbound_wq, - &root->fs_info->async_reclaim_work); + &fs_info->async_reclaim_work); } } else { list_add_tail(&ticket.list, @@ -5210,7 +5228,8 @@ static int __reserve_metadata_bytes(struct btrfs_root *root, * the async reclaim as we will panic. */ if (!test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags) && - need_do_async_reclaim(space_info, root, used) && + need_do_async_reclaim(fs_info, space_info, + used, system_chunk) && !work_busy(&fs_info->async_reclaim_work)) { trace_btrfs_trigger_flush(fs_info, space_info->flags, orig_bytes, flush, "preempt"); @@ -5268,9 +5287,10 @@ static int reserve_metadata_bytes(struct btrfs_root *root, struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; int ret; + bool system_chunk = (root == fs_info->chunk_root); - ret = __reserve_metadata_bytes(root, block_rsv->space_info, orig_bytes, - flush); + ret = __reserve_metadata_bytes(fs_info, block_rsv->space_info, + orig_bytes, flush, system_chunk); if (ret == -ENOSPC && unlikely(root->orphan_cleanup_state == ORPHAN_CLEANUP_STARTED)) { if (block_rsv != global_rsv && @@ -5393,8 +5413,7 @@ again: * adding the ticket space would be a double count. */ if (check_overcommit && - !can_overcommit(fs_info->extent_root, space_info, 0, - flush)) + !can_overcommit(fs_info, space_info, 0, flush, false)) break; if (num_bytes >= ticket->bytes) { list_del_init(&ticket->list); @@ -6123,6 +6142,8 @@ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes) * @inode: inode we're writing to * @start: start range we are writing to * @len: how long the range we are writing to + * @reserved: mandatory parameter, record actually reserved qgroup ranges of + * current reservation. * * This will do the following things * @@ -6140,16 +6161,17 @@ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes) * Return 0 for success * Return <0 for error(-ENOSPC or -EQUOT) */ -int btrfs_delalloc_reserve_space(struct inode *inode, u64 start, u64 len) +int btrfs_delalloc_reserve_space(struct inode *inode, + struct extent_changeset **reserved, u64 start, u64 len) { int ret; - ret = btrfs_check_data_free_space(inode, start, len); + ret = btrfs_check_data_free_space(inode, reserved, start, len); if (ret < 0) return ret; ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len); if (ret < 0) - btrfs_free_reserved_data_space(inode, start, len); + btrfs_free_reserved_data_space(inode, *reserved, start, len); return ret; } @@ -6168,10 +6190,11 @@ int btrfs_delalloc_reserve_space(struct inode *inode, u64 start, u64 len) * list if there are no delalloc bytes left. * Also it will handle the qgroup reserved space. */ -void btrfs_delalloc_release_space(struct inode *inode, u64 start, u64 len) +void btrfs_delalloc_release_space(struct inode *inode, + struct extent_changeset *reserved, u64 start, u64 len) { btrfs_delalloc_release_metadata(BTRFS_I(inode), len); - btrfs_free_reserved_data_space(inode, start, len); + btrfs_free_reserved_data_space(inode, reserved, start, len); } static int update_block_group(struct btrfs_trans_handle *trans, @@ -7955,7 +7978,7 @@ int btrfs_reserve_extent(struct btrfs_root *root, u64 ram_bytes, u64 flags; int ret; - flags = btrfs_get_alloc_profile(root, is_data); + flags = get_alloc_profile_by_root(root, is_data); again: WARN_ON(num_bytes < fs_info->sectorsize); ret = find_free_extent(fs_info, ram_bytes, num_bytes, empty_size, @@ -10058,19 +10081,9 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info) } trace_btrfs_add_block_group(info, cache, 0); - ret = update_space_info(info, cache->flags, found_key.offset, - btrfs_block_group_used(&cache->item), - cache->bytes_super, &space_info); - if (ret) { - btrfs_remove_free_space_cache(cache); - spin_lock(&info->block_group_cache_lock); - rb_erase(&cache->cache_node, - &info->block_group_cache_tree); - RB_CLEAR_NODE(&cache->cache_node); - spin_unlock(&info->block_group_cache_lock); - btrfs_put_block_group(cache); - goto error; - } + update_space_info(info, cache->flags, found_key.offset, + btrfs_block_group_used(&cache->item), + cache->bytes_super, &space_info); cache->space_info = space_info; @@ -10202,16 +10215,19 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, } #endif /* - * Call to ensure the corresponding space_info object is created and - * assigned to our block group, but don't update its counters just yet. - * We want our bg to be added to the rbtree with its ->space_info set. + * Ensure the corresponding space_info object is created and + * assigned to our block group. We want our bg to be added to the rbtree + * with its ->space_info set. */ - ret = update_space_info(fs_info, cache->flags, 0, 0, 0, - &cache->space_info); - if (ret) { - btrfs_remove_free_space_cache(cache); - btrfs_put_block_group(cache); - return ret; + cache->space_info = __find_space_info(fs_info, cache->flags); + if (!cache->space_info) { + ret = create_space_info(fs_info, cache->flags, + &cache->space_info); + if (ret) { + btrfs_remove_free_space_cache(cache); + btrfs_put_block_group(cache); + return ret; + } } ret = btrfs_add_block_group_cache(fs_info, cache); @@ -10226,18 +10242,8 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, * the rbtree, update the space info's counters. */ trace_btrfs_add_block_group(fs_info, cache, 1); - ret = update_space_info(fs_info, cache->flags, size, bytes_used, + update_space_info(fs_info, cache->flags, size, bytes_used, cache->bytes_super, &cache->space_info); - if (ret) { - btrfs_remove_free_space_cache(cache); - spin_lock(&fs_info->block_group_cache_lock); - rb_erase(&cache->cache_node, - &fs_info->block_group_cache_tree); - RB_CLEAR_NODE(&cache->cache_node); - spin_unlock(&fs_info->block_group_cache_lock); - btrfs_put_block_group(cache); - return ret; - } update_global_block_rsv(fs_info); __link_block_group(cache->space_info, cache); @@ -10785,21 +10791,21 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info) mixed = 1; flags = BTRFS_BLOCK_GROUP_SYSTEM; - ret = update_space_info(fs_info, flags, 0, 0, 0, &space_info); + ret = create_space_info(fs_info, flags, &space_info); if (ret) goto out; if (mixed) { flags = BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA; - ret = update_space_info(fs_info, flags, 0, 0, 0, &space_info); + ret = create_space_info(fs_info, flags, &space_info); } else { flags = BTRFS_BLOCK_GROUP_METADATA; - ret = update_space_info(fs_info, flags, 0, 0, 0, &space_info); + ret = create_space_info(fs_info, flags, &space_info); if (ret) goto out; flags = BTRFS_BLOCK_GROUP_DATA; - ret = update_space_info(fs_info, flags, 0, 0, 0, &space_info); + ret = create_space_info(fs_info, flags, &space_info); } out: return ret; diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index d8da3edf2ac3..5909f8214255 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -87,19 +87,9 @@ void btrfs_leak_debug_check(void) static inline void __btrfs_debug_check_extent_io_range(const char *caller, struct extent_io_tree *tree, u64 start, u64 end) { - struct inode *inode; - u64 isize; - - if (!tree->mapping) - return; - - inode = tree->mapping->host; - isize = i_size_read(inode); - if (end >= PAGE_SIZE && (end % 2) == 0 && end != isize - 1) { - btrfs_debug_rl(BTRFS_I(inode)->root->fs_info, - "%s: ino %llu isize %llu odd range [%llu,%llu]", - caller, btrfs_ino(BTRFS_I(inode)), isize, start, end); - } + if (tree->ops && tree->ops->check_extent_io_range) + tree->ops->check_extent_io_range(tree->private_data, caller, + start, end); } #else #define btrfs_leak_debug_add(new, head) do {} while (0) @@ -154,9 +144,9 @@ static noinline void flush_write_bio(void *data); static inline struct btrfs_fs_info * tree_fs_info(struct extent_io_tree *tree) { - if (!tree->mapping) - return NULL; - return btrfs_sb(tree->mapping->host->i_sb); + if (tree->ops) + return tree->ops->tree_fs_info(tree->private_data); + return NULL; } int __init extent_io_init(void) @@ -213,13 +203,13 @@ void extent_io_exit(void) } void extent_io_tree_init(struct extent_io_tree *tree, - struct address_space *mapping) + void *private_data) { tree->state = RB_ROOT; tree->ops = NULL; tree->dirty_bytes = 0; spin_lock_init(&tree->lock); - tree->mapping = mapping; + tree->private_data = private_data; } static struct extent_state *alloc_extent_state(gfp_t mask) @@ -369,8 +359,7 @@ static void merge_cb(struct extent_io_tree *tree, struct extent_state *new, struct extent_state *other) { if (tree->ops && tree->ops->merge_extent_hook) - tree->ops->merge_extent_hook(tree->mapping->host, new, - other); + tree->ops->merge_extent_hook(tree->private_data, new, other); } /* @@ -421,15 +410,14 @@ static void set_state_cb(struct extent_io_tree *tree, struct extent_state *state, unsigned *bits) { if (tree->ops && tree->ops->set_bit_hook) - tree->ops->set_bit_hook(tree->mapping->host, state, bits); + tree->ops->set_bit_hook(tree->private_data, state, bits); } static void clear_state_cb(struct extent_io_tree *tree, struct extent_state *state, unsigned *bits) { if (tree->ops && tree->ops->clear_bit_hook) - tree->ops->clear_bit_hook(BTRFS_I(tree->mapping->host), - state, bits); + tree->ops->clear_bit_hook(tree->private_data, state, bits); } static void set_state_bits(struct extent_io_tree *tree, @@ -478,7 +466,7 @@ static void split_cb(struct extent_io_tree *tree, struct extent_state *orig, u64 split) { if (tree->ops && tree->ops->split_extent_hook) - tree->ops->split_extent_hook(tree->mapping->host, orig, split); + tree->ops->split_extent_hook(tree->private_data, orig, split); } /* @@ -1402,17 +1390,7 @@ void extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end) */ static void set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end) { - unsigned long index = start >> PAGE_SHIFT; - unsigned long end_index = end >> PAGE_SHIFT; - struct page *page; - - while (index <= end_index) { - page = find_get_page(tree->mapping, index); - BUG_ON(!page); /* Pages should be in the extent_io_tree */ - set_page_writeback(page); - put_page(page); - index++; - } + tree->ops->set_range_writeback(tree->private_data, start, end); } /* find the first state struct with 'bits' set after 'start', and @@ -1961,11 +1939,12 @@ static void check_page_uptodate(struct extent_io_tree *tree, struct page *page) SetPageUptodate(page); } -int free_io_failure(struct btrfs_inode *inode, struct io_failure_record *rec) +int free_io_failure(struct extent_io_tree *failure_tree, + struct extent_io_tree *io_tree, + struct io_failure_record *rec) { int ret; int err = 0; - struct extent_io_tree *failure_tree = &inode->io_failure_tree; set_state_failrec(failure_tree, rec->start, NULL); ret = clear_extent_bits(failure_tree, rec->start, @@ -1974,7 +1953,7 @@ int free_io_failure(struct btrfs_inode *inode, struct io_failure_record *rec) if (ret) err = ret; - ret = clear_extent_bits(&inode->io_tree, rec->start, + ret = clear_extent_bits(io_tree, rec->start, rec->start + rec->len - 1, EXTENT_DAMAGED); if (ret && !err) @@ -1994,11 +1973,10 @@ int free_io_failure(struct btrfs_inode *inode, struct io_failure_record *rec) * currently, there can be no more than two copies of every data bit. thus, * exactly one rewrite is required. */ -int repair_io_failure(struct btrfs_inode *inode, u64 start, u64 length, - u64 logical, struct page *page, - unsigned int pg_offset, int mirror_num) +int repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start, + u64 length, u64 logical, struct page *page, + unsigned int pg_offset, int mirror_num) { - struct btrfs_fs_info *fs_info = inode->root->fs_info; struct bio *bio; struct btrfs_device *dev; u64 map_length = 0; @@ -2070,7 +2048,7 @@ int repair_io_failure(struct btrfs_inode *inode, u64 start, u64 length, btrfs_info_rl_in_rcu(fs_info, "read error corrected: ino %llu off %llu (dev %s sector %llu)", - btrfs_ino(inode), start, + ino, start, rcu_str_deref(dev->name), sector); btrfs_bio_counter_dec(fs_info); bio_put(bio); @@ -2090,8 +2068,7 @@ int repair_eb_io_failure(struct btrfs_fs_info *fs_info, for (i = 0; i < num_pages; i++) { struct page *p = eb->pages[i]; - ret = repair_io_failure(BTRFS_I(fs_info->btree_inode), start, - PAGE_SIZE, start, p, + ret = repair_io_failure(fs_info, 0, start, PAGE_SIZE, start, p, start - page_offset(p), mirror_num); if (ret) break; @@ -2105,24 +2082,24 @@ int repair_eb_io_failure(struct btrfs_fs_info *fs_info, * each time an IO finishes, we do a fast check in the IO failure tree * to see if we need to process or clean up an io_failure_record */ -int clean_io_failure(struct btrfs_inode *inode, u64 start, struct page *page, - unsigned int pg_offset) +int clean_io_failure(struct btrfs_fs_info *fs_info, + struct extent_io_tree *failure_tree, + struct extent_io_tree *io_tree, u64 start, + struct page *page, u64 ino, unsigned int pg_offset) { u64 private; struct io_failure_record *failrec; - struct btrfs_fs_info *fs_info = inode->root->fs_info; struct extent_state *state; int num_copies; int ret; private = 0; - ret = count_range_bits(&inode->io_failure_tree, &private, - (u64)-1, 1, EXTENT_DIRTY, 0); + ret = count_range_bits(failure_tree, &private, (u64)-1, 1, + EXTENT_DIRTY, 0); if (!ret) return 0; - ret = get_state_failrec(&inode->io_failure_tree, start, - &failrec); + ret = get_state_failrec(failure_tree, start, &failrec); if (ret) return 0; @@ -2138,25 +2115,25 @@ int clean_io_failure(struct btrfs_inode *inode, u64 start, struct page *page, if (fs_info->sb->s_flags & MS_RDONLY) goto out; - spin_lock(&inode->io_tree.lock); - state = find_first_extent_bit_state(&inode->io_tree, + spin_lock(&io_tree->lock); + state = find_first_extent_bit_state(io_tree, failrec->start, EXTENT_LOCKED); - spin_unlock(&inode->io_tree.lock); + spin_unlock(&io_tree->lock); if (state && state->start <= failrec->start && state->end >= failrec->start + failrec->len - 1) { num_copies = btrfs_num_copies(fs_info, failrec->logical, failrec->len); if (num_copies > 1) { - repair_io_failure(inode, start, failrec->len, - failrec->logical, page, - pg_offset, failrec->failed_mirror); + repair_io_failure(fs_info, ino, start, failrec->len, + failrec->logical, page, pg_offset, + failrec->failed_mirror); } } out: - free_io_failure(inode, failrec); + free_io_failure(failure_tree, io_tree, failrec); return 0; } @@ -2397,6 +2374,7 @@ static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset, struct io_failure_record *failrec; struct inode *inode = page->mapping->host; struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; + struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree; struct bio *bio; int read_mode = 0; int ret; @@ -2409,7 +2387,7 @@ static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset, ret = btrfs_check_repairable(inode, failed_bio, failrec, failed_mirror); if (!ret) { - free_io_failure(BTRFS_I(inode), failrec); + free_io_failure(failure_tree, tree, failrec); return -EIO; } @@ -2422,7 +2400,7 @@ static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset, (int)phy_offset, failed_bio->bi_end_io, NULL); if (!bio) { - free_io_failure(BTRFS_I(inode), failrec); + free_io_failure(failure_tree, tree, failrec); return -EIO; } bio_set_op_attrs(bio, REQ_OP_READ, read_mode); @@ -2431,10 +2409,10 @@ static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset, "Repair Read Error: submitting new read[%#x] to this_mirror=%d, in_validation=%d", read_mode, failrec->this_mirror, failrec->in_validation); - ret = tree->ops->submit_bio_hook(inode, bio, failrec->this_mirror, + ret = tree->ops->submit_bio_hook(tree->private_data, bio, failrec->this_mirror, failrec->bio_flags, 0); if (ret) { - free_io_failure(BTRFS_I(inode), failrec); + free_io_failure(failure_tree, tree, failrec); bio_put(bio); } @@ -2458,7 +2436,7 @@ void end_extent_writepage(struct page *page, int err, u64 start, u64 end) if (!uptodate) { ClearPageUptodate(page); SetPageError(page); - ret = ret < 0 ? ret : -EIO; + ret = err < 0 ? err : -EIO; mapping_set_error(page->mapping, ret); } } @@ -2538,7 +2516,7 @@ static void end_bio_extent_readpage(struct bio *bio) struct bio_vec *bvec; int uptodate = !bio->bi_error; struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); - struct extent_io_tree *tree; + struct extent_io_tree *tree, *failure_tree; u64 offset = 0; u64 start; u64 end; @@ -2559,6 +2537,7 @@ static void end_bio_extent_readpage(struct bio *bio) (u64)bio->bi_iter.bi_sector, bio->bi_error, io_bio->mirror_num); tree = &BTRFS_I(inode)->io_tree; + failure_tree = &BTRFS_I(inode)->io_failure_tree; /* We always issue full-page reads, but if some block * in a page fails to read, blk_update_request() will @@ -2588,8 +2567,10 @@ static void end_bio_extent_readpage(struct bio *bio) if (ret) uptodate = 0; else - clean_io_failure(BTRFS_I(inode), start, - page, 0); + clean_io_failure(BTRFS_I(inode)->root->fs_info, + failure_tree, tree, start, + page, + btrfs_ino(BTRFS_I(inode)), 0); } if (likely(uptodate)) @@ -2713,7 +2694,7 @@ struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask) struct btrfs_io_bio *btrfs_bio; struct bio *new; - new = bio_clone_bioset(bio, gfp_mask, btrfs_bioset); + new = bio_clone_fast(bio, gfp_mask, btrfs_bioset); if (new) { btrfs_bio = btrfs_io_bio(new); btrfs_bio->csum = NULL; @@ -2739,6 +2720,24 @@ struct bio *btrfs_io_bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs) return bio; } +struct bio *btrfs_bio_clone_partial(struct bio *orig, int offset, int size) +{ + struct bio *bio; + struct btrfs_io_bio *btrfs_bio; + + /* this will never fail when it's backed by a bioset */ + bio = bio_clone_fast(orig, GFP_NOFS, btrfs_bioset); + ASSERT(bio); + + btrfs_bio = btrfs_io_bio(bio); + btrfs_bio->csum = NULL; + btrfs_bio->csum_allocated = NULL; + btrfs_bio->end_io = NULL; + + bio_trim(bio, offset >> 9, size >> 9); + btrfs_bio->iter = bio->bi_iter; + return bio; +} static int __must_check submit_one_bio(struct bio *bio, int mirror_num, unsigned long bio_flags) @@ -2755,7 +2754,7 @@ static int __must_check submit_one_bio(struct bio *bio, int mirror_num, bio_get(bio); if (tree->ops) - ret = tree->ops->submit_bio_hook(page->mapping->host, bio, + ret = tree->ops->submit_bio_hook(tree->private_data, bio, mirror_num, bio_flags, start); else btrfsic_submit_bio(bio); @@ -3757,7 +3756,7 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb, * header 0 1 2 .. N ... data_N .. data_2 data_1 data_0 */ start = btrfs_item_nr_offset(nritems); - end = btrfs_leaf_data(eb) + leaf_data_end(fs_info, eb); + end = BTRFS_LEAF_DATA_OFFSET + leaf_data_end(fs_info, eb); memzero_extent_buffer(eb, start, end - start); } @@ -4377,6 +4376,123 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode, return NULL; } +/* + * To cache previous fiemap extent + * + * Will be used for merging fiemap extent + */ +struct fiemap_cache { + u64 offset; + u64 phys; + u64 len; + u32 flags; + bool cached; +}; + +/* + * Helper to submit fiemap extent. + * + * Will try to merge current fiemap extent specified by @offset, @phys, + * @len and @flags with cached one. + * And only when we fails to merge, cached one will be submitted as + * fiemap extent. + * + * Return value is the same as fiemap_fill_next_extent(). + */ +static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo, + struct fiemap_cache *cache, + u64 offset, u64 phys, u64 len, u32 flags) +{ + int ret = 0; + + if (!cache->cached) + goto assign; + + /* + * Sanity check, extent_fiemap() should have ensured that new + * fiemap extent won't overlap with cahced one. + * Not recoverable. + * + * NOTE: Physical address can overlap, due to compression + */ + if (cache->offset + cache->len > offset) { + WARN_ON(1); + return -EINVAL; + } + + /* + * Only merges fiemap extents if + * 1) Their logical addresses are continuous + * + * 2) Their physical addresses are continuous + * So truly compressed (physical size smaller than logical size) + * extents won't get merged with each other + * + * 3) Share same flags except FIEMAP_EXTENT_LAST + * So regular extent won't get merged with prealloc extent + */ + if (cache->offset + cache->len == offset && + cache->phys + cache->len == phys && + (cache->flags & ~FIEMAP_EXTENT_LAST) == + (flags & ~FIEMAP_EXTENT_LAST)) { + cache->len += len; + cache->flags |= flags; + goto try_submit_last; + } + + /* Not mergeable, need to submit cached one */ + ret = fiemap_fill_next_extent(fieinfo, cache->offset, cache->phys, + cache->len, cache->flags); + cache->cached = false; + if (ret) + return ret; +assign: + cache->cached = true; + cache->offset = offset; + cache->phys = phys; + cache->len = len; + cache->flags = flags; +try_submit_last: + if (cache->flags & FIEMAP_EXTENT_LAST) { + ret = fiemap_fill_next_extent(fieinfo, cache->offset, + cache->phys, cache->len, cache->flags); + cache->cached = false; + } + return ret; +} + +/* + * Sanity check for fiemap cache + * + * All fiemap cache should be submitted by emit_fiemap_extent() + * Iteration should be terminated either by last fiemap extent or + * fieinfo->fi_extents_max. + * So no cached fiemap should exist. + */ +static int check_fiemap_cache(struct btrfs_fs_info *fs_info, + struct fiemap_extent_info *fieinfo, + struct fiemap_cache *cache) +{ + int ret; + + if (!cache->cached) + return 0; + + /* Small and recoverbale problem, only to info developer */ +#ifdef CONFIG_BTRFS_DEBUG + WARN_ON(1); +#endif + btrfs_warn(fs_info, + "unhandled fiemap cache detected: offset=%llu phys=%llu len=%llu flags=0x%x", + cache->offset, cache->phys, cache->len, cache->flags); + ret = fiemap_fill_next_extent(fieinfo, cache->offset, cache->phys, + cache->len, cache->flags); + cache->cached = false; + if (ret > 0) + ret = 0; + return ret; +} + int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, __u64 start, __u64 len, get_extent_t *get_extent) { @@ -4394,6 +4510,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, struct extent_state *cached_state = NULL; struct btrfs_path *path; struct btrfs_root *root = BTRFS_I(inode)->root; + struct fiemap_cache cache = { 0 }; int end = 0; u64 em_start = 0; u64 em_len = 0; @@ -4573,8 +4690,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, flags |= FIEMAP_EXTENT_LAST; end = 1; } - ret = fiemap_fill_next_extent(fieinfo, em_start, disko, - em_len, flags); + ret = emit_fiemap_extent(fieinfo, &cache, em_start, disko, + em_len, flags); if (ret) { if (ret == 1) ret = 0; @@ -4582,6 +4699,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, } } out_free: + if (!ret) + ret = check_fiemap_cache(root->fs_info, fieinfo, &cache); free_extent_map(em); out: btrfs_free_path(path); diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 1eafa2f0ede3..d12c923f6c74 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -92,7 +92,7 @@ struct btrfs_inode; struct btrfs_io_bio; struct io_failure_record; -typedef int (extent_submit_bio_hook_t)(struct inode *inode, struct bio *bio, +typedef int (extent_submit_bio_hook_t)(void *private_data, struct bio *bio, int mirror_num, unsigned long bio_flags, u64 bio_offset); struct extent_io_ops { @@ -108,32 +108,36 @@ struct extent_io_ops { size_t size, struct bio *bio, unsigned long bio_flags); int (*readpage_io_failed_hook)(struct page *page, int failed_mirror); + struct btrfs_fs_info *(*tree_fs_info)(void *private_data); + void (*set_range_writeback)(void *private_data, u64 start, u64 end); /* * Optional hooks, called if the pointer is not NULL */ - int (*fill_delalloc)(struct inode *inode, struct page *locked_page, + int (*fill_delalloc)(void *private_data, struct page *locked_page, u64 start, u64 end, int *page_started, unsigned long *nr_written); int (*writepage_start_hook)(struct page *page, u64 start, u64 end); void (*writepage_end_io_hook)(struct page *page, u64 start, u64 end, struct extent_state *state, int uptodate); - void (*set_bit_hook)(struct inode *inode, struct extent_state *state, + void (*set_bit_hook)(void *private_data, struct extent_state *state, unsigned *bits); - void (*clear_bit_hook)(struct btrfs_inode *inode, + void (*clear_bit_hook)(void *private_data, struct extent_state *state, unsigned *bits); - void (*merge_extent_hook)(struct inode *inode, + void (*merge_extent_hook)(void *private_data, struct extent_state *new, struct extent_state *other); - void (*split_extent_hook)(struct inode *inode, + void (*split_extent_hook)(void *private_data, struct extent_state *orig, u64 split); + void (*check_extent_io_range)(void *private_data, const char *caller, + u64 start, u64 end); }; struct extent_io_tree { struct rb_root state; - struct address_space *mapping; + void *private_data; u64 dirty_bytes; int track_uptodate; spinlock_t lock; @@ -205,12 +209,46 @@ struct extent_buffer { */ struct extent_changeset { /* How many bytes are set/cleared in this operation */ - u64 bytes_changed; + unsigned int bytes_changed; /* Changed ranges */ struct ulist range_changed; }; +static inline void extent_changeset_init(struct extent_changeset *changeset) +{ + changeset->bytes_changed = 0; + ulist_init(&changeset->range_changed); +} + +static inline struct extent_changeset *extent_changeset_alloc(void) +{ + struct extent_changeset *ret; + + ret = kmalloc(sizeof(*ret), GFP_KERNEL); + if (!ret) + return NULL; + + extent_changeset_init(ret); + return ret; +} + +static inline void extent_changeset_release(struct extent_changeset *changeset) +{ + if (!changeset) + return; + changeset->bytes_changed = 0; + ulist_release(&changeset->range_changed); +} + +static inline void extent_changeset_free(struct extent_changeset *changeset) +{ + if (!changeset) + return; + extent_changeset_release(changeset); + kfree(changeset); +} + static inline void extent_set_compress_type(unsigned long *bio_flags, int compress_type) { @@ -230,8 +268,7 @@ typedef struct extent_map *(get_extent_t)(struct btrfs_inode *inode, u64 start, u64 len, int create); -void extent_io_tree_init(struct extent_io_tree *tree, - struct address_space *mapping); +void extent_io_tree_init(struct extent_io_tree *tree, void *private_data); int try_release_extent_mapping(struct extent_map_tree *map, struct extent_io_tree *tree, struct page *page, gfp_t mask); @@ -464,15 +501,18 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, gfp_t gfp_flags); struct bio *btrfs_io_bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs); struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask); +struct bio *btrfs_bio_clone_partial(struct bio *orig, int offset, int size); struct btrfs_fs_info; struct btrfs_inode; -int repair_io_failure(struct btrfs_inode *inode, u64 start, u64 length, - u64 logical, struct page *page, - unsigned int pg_offset, int mirror_num); -int clean_io_failure(struct btrfs_inode *inode, u64 start, - struct page *page, unsigned int pg_offset); +int repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start, + u64 length, u64 logical, struct page *page, + unsigned int pg_offset, int mirror_num); +int clean_io_failure(struct btrfs_fs_info *fs_info, + struct extent_io_tree *failure_tree, + struct extent_io_tree *io_tree, u64 start, + struct page *page, u64 ino, unsigned int pg_offset); void end_extent_writepage(struct page *page, int err, u64 start, u64 end); int repair_eb_io_failure(struct btrfs_fs_info *fs_info, struct extent_buffer *eb, int mirror_num); @@ -507,7 +547,9 @@ struct bio *btrfs_create_repair_bio(struct inode *inode, struct bio *failed_bio, struct io_failure_record *failrec, struct page *page, int pg_offset, int icsum, bio_end_io_t *endio_func, void *data); -int free_io_failure(struct btrfs_inode *inode, struct io_failure_record *rec); +int free_io_failure(struct extent_io_tree *failure_tree, + struct extent_io_tree *io_tree, + struct io_failure_record *rec); #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS noinline u64 find_lock_delalloc_range(struct inode *inode, struct extent_io_tree *tree, diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 64fcb31d7163..9f6062c82419 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -164,7 +164,8 @@ static int __btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio, u64 logical_offset, u32 *dst, int dio) { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); - struct bio_vec *bvec; + struct bio_vec bvec; + struct bvec_iter iter; struct btrfs_io_bio *btrfs_bio = btrfs_io_bio(bio); struct btrfs_csum_item *item = NULL; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; @@ -177,7 +178,7 @@ static int __btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio, u64 page_bytes_left; u32 diff; int nblocks; - int count = 0, i; + int count = 0; u16 csum_size = btrfs_super_csum_size(fs_info->super_copy); path = btrfs_alloc_path(); @@ -206,8 +207,6 @@ static int __btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio, if (bio->bi_iter.bi_size > PAGE_SIZE * 8) path->reada = READA_FORWARD; - WARN_ON(bio->bi_vcnt <= 0); - /* * the free space stuff is only read when it hasn't been * updated in the current transaction. So, we can safely @@ -223,13 +222,13 @@ static int __btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio, if (dio) offset = logical_offset; - bio_for_each_segment_all(bvec, bio, i) { - page_bytes_left = bvec->bv_len; + bio_for_each_segment(bvec, bio, iter) { + page_bytes_left = bvec.bv_len; if (count) goto next; if (!dio) - offset = page_offset(bvec->bv_page) + bvec->bv_offset; + offset = page_offset(bvec.bv_page) + bvec.bv_offset; count = btrfs_find_ordered_sum(inode, offset, disk_bytenr, (u32 *)csum, nblocks); if (count) @@ -440,15 +439,15 @@ int btrfs_csum_one_bio(struct inode *inode, struct bio *bio, struct btrfs_ordered_sum *sums; struct btrfs_ordered_extent *ordered = NULL; char *data; - struct bio_vec *bvec; + struct bvec_iter iter; + struct bio_vec bvec; int index; int nr_sectors; - int i, j; unsigned long total_bytes = 0; unsigned long this_sum_bytes = 0; + int i; u64 offset; - WARN_ON(bio->bi_vcnt <= 0); sums = kzalloc(btrfs_ordered_sum_size(fs_info, bio->bi_iter.bi_size), GFP_NOFS); if (!sums) @@ -465,19 +464,19 @@ int btrfs_csum_one_bio(struct inode *inode, struct bio *bio, sums->bytenr = (u64)bio->bi_iter.bi_sector << 9; index = 0; - bio_for_each_segment_all(bvec, bio, j) { + bio_for_each_segment(bvec, bio, iter) { if (!contig) - offset = page_offset(bvec->bv_page) + bvec->bv_offset; + offset = page_offset(bvec.bv_page) + bvec.bv_offset; if (!ordered) { ordered = btrfs_lookup_ordered_extent(inode, offset); BUG_ON(!ordered); /* Logic error */ } - data = kmap_atomic(bvec->bv_page); + data = kmap_atomic(bvec.bv_page); nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, - bvec->bv_len + fs_info->sectorsize + bvec.bv_len + fs_info->sectorsize - 1); for (i = 0; i < nr_sectors; i++) { @@ -504,12 +503,12 @@ int btrfs_csum_one_bio(struct inode *inode, struct bio *bio, + total_bytes; index = 0; - data = kmap_atomic(bvec->bv_page); + data = kmap_atomic(bvec.bv_page); } sums->sums[index] = ~(u32)0; sums->sums[index] - = btrfs_csum_data(data + bvec->bv_offset + = btrfs_csum_data(data + bvec.bv_offset + (i * fs_info->sectorsize), sums->sums[index], fs_info->sectorsize); diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index da1096eb1a40..0502bd2272fe 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1581,6 +1581,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, struct btrfs_root *root = BTRFS_I(inode)->root; struct page **pages = NULL; struct extent_state *cached_state = NULL; + struct extent_changeset *data_reserved = NULL; u64 release_bytes = 0; u64 lockstart; u64 lockend; @@ -1628,7 +1629,9 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, reserve_bytes = round_up(write_bytes + sector_offset, fs_info->sectorsize); - ret = btrfs_check_data_free_space(inode, pos, write_bytes); + extent_changeset_release(data_reserved); + ret = btrfs_check_data_free_space(inode, &data_reserved, pos, + write_bytes); if (ret < 0) { if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW | BTRFS_INODE_PREALLOC)) && @@ -1657,8 +1660,9 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, reserve_bytes); if (ret) { if (!only_release_metadata) - btrfs_free_reserved_data_space(inode, pos, - write_bytes); + btrfs_free_reserved_data_space(inode, + data_reserved, pos, + write_bytes); else btrfs_end_write_no_snapshoting(root); break; @@ -1740,8 +1744,9 @@ again: __pos = round_down(pos, fs_info->sectorsize) + (dirty_pages << PAGE_SHIFT); - btrfs_delalloc_release_space(inode, __pos, - release_bytes); + btrfs_delalloc_release_space(inode, + data_reserved, __pos, + release_bytes); } } @@ -1796,12 +1801,13 @@ again: btrfs_delalloc_release_metadata(BTRFS_I(inode), release_bytes); } else { - btrfs_delalloc_release_space(inode, - round_down(pos, fs_info->sectorsize), - release_bytes); + btrfs_delalloc_release_space(inode, data_reserved, + round_down(pos, fs_info->sectorsize), + release_bytes); } } + extent_changeset_free(data_reserved); return num_written ? num_written : ret; } @@ -2769,6 +2775,7 @@ static long btrfs_fallocate(struct file *file, int mode, { struct inode *inode = file_inode(file); struct extent_state *cached_state = NULL; + struct extent_changeset *data_reserved = NULL; struct falloc_range *range; struct falloc_range *tmp; struct list_head reserve_list; @@ -2898,8 +2905,8 @@ static long btrfs_fallocate(struct file *file, int mode, free_extent_map(em); break; } - ret = btrfs_qgroup_reserve_data(inode, cur_offset, - last_byte - cur_offset); + ret = btrfs_qgroup_reserve_data(inode, &data_reserved, + cur_offset, last_byte - cur_offset); if (ret < 0) { free_extent_map(em); break; @@ -2910,8 +2917,8 @@ static long btrfs_fallocate(struct file *file, int mode, * range, free reserved data space first, otherwise * it'll result in false ENOSPC error. */ - btrfs_free_reserved_data_space(inode, cur_offset, - last_byte - cur_offset); + btrfs_free_reserved_data_space(inode, data_reserved, + cur_offset, last_byte - cur_offset); } free_extent_map(em); cur_offset = last_byte; @@ -2930,8 +2937,9 @@ static long btrfs_fallocate(struct file *file, int mode, range->len, i_blocksize(inode), offset + len, &alloc_hint); else - btrfs_free_reserved_data_space(inode, range->start, - range->len); + btrfs_free_reserved_data_space(inode, + data_reserved, range->start, + range->len); list_del(&range->list); kfree(range); } @@ -2969,8 +2977,9 @@ out: inode_unlock(inode); /* Let go of our reservation. */ if (ret != 0) - btrfs_free_reserved_data_space(inode, alloc_start, - alloc_end - cur_offset); + btrfs_free_reserved_data_space(inode, data_reserved, + alloc_start, alloc_end - cur_offset); + extent_changeset_free(data_reserved); return ret; } diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c index fc0bd8406758..babd33258655 100644 --- a/fs/btrfs/free-space-tree.c +++ b/fs/btrfs/free-space-tree.c @@ -151,25 +151,6 @@ static inline u32 free_space_bitmap_size(u64 size, u32 sectorsize) return DIV_ROUND_UP((u32)div_u64(size, sectorsize), BITS_PER_BYTE); } -static u8 *alloc_bitmap(u32 bitmap_size) -{ - void *mem; - - /* - * The allocation size varies, observed numbers were < 4K up to 16K. - * Using vmalloc unconditionally would be too heavy, we'll try - * contiguous allocations first. - */ - if (bitmap_size <= PAGE_SIZE) - return kzalloc(bitmap_size, GFP_NOFS); - - mem = kzalloc(bitmap_size, GFP_NOFS | __GFP_NOWARN); - if (mem) - return mem; - - return __vmalloc(bitmap_size, GFP_NOFS | __GFP_ZERO, PAGE_KERNEL); -} - int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *block_group, @@ -189,7 +170,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans, bitmap_size = free_space_bitmap_size(block_group->key.offset, fs_info->sectorsize); - bitmap = alloc_bitmap(bitmap_size); + bitmap = kvzalloc(bitmap_size, GFP_NOFS); if (!bitmap) { ret = -ENOMEM; goto out; @@ -330,7 +311,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans, bitmap_size = free_space_bitmap_size(block_group->key.offset, fs_info->sectorsize); - bitmap = alloc_bitmap(bitmap_size); + bitmap = kvzalloc(bitmap_size, GFP_NOFS); if (!bitmap) { ret = -ENOMEM; goto out; @@ -1188,11 +1169,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info) btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID); clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); - ret = btrfs_commit_transaction(trans); - if (ret) - return ret; - - return 0; + return btrfs_commit_transaction(trans); abort: clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); @@ -1277,11 +1254,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info) free_extent_buffer(free_space_root->commit_root); kfree(free_space_root); - ret = btrfs_commit_transaction(trans); - if (ret) - return ret; - - return 0; + return btrfs_commit_transaction(trans); abort: btrfs_abort_transaction(trans, ret); diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 5c6c20ec64d8..d02019747d00 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c @@ -400,6 +400,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root, struct btrfs_path *path; struct inode *inode; struct btrfs_block_rsv *rsv; + struct extent_changeset *data_reserved = NULL; u64 num_bytes; u64 alloc_hint = 0; int ret; @@ -492,7 +493,7 @@ again: /* Just to make sure we have enough space */ prealloc += 8 * PAGE_SIZE; - ret = btrfs_delalloc_reserve_space(inode, 0, prealloc); + ret = btrfs_delalloc_reserve_space(inode, &data_reserved, 0, prealloc); if (ret) goto out_put; @@ -516,6 +517,7 @@ out: trans->bytes_reserved = num_bytes; btrfs_free_path(path); + extent_changeset_free(data_reserved); return ret; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 17cbe9306faf..2b4a7ad48f58 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -86,7 +86,6 @@ static const struct extent_io_ops btrfs_extent_io_ops; static struct kmem_cache *btrfs_inode_cachep; struct kmem_cache *btrfs_trans_handle_cachep; -struct kmem_cache *btrfs_transaction_cachep; struct kmem_cache *btrfs_path_cachep; struct kmem_cache *btrfs_free_space_cachep; @@ -350,7 +349,7 @@ out: * And at reserve time, it's always aligned to page size, so * just free one page here. */ - btrfs_qgroup_free_data(inode, 0, PAGE_SIZE); + btrfs_qgroup_free_data(inode, NULL, 0, PAGE_SIZE); btrfs_free_path(path); btrfs_end_transaction(trans); return ret; @@ -1569,10 +1568,11 @@ static inline int need_force_cow(struct inode *inode, u64 start, u64 end) /* * extent_io.c call back to do delayed allocation processing */ -static int run_delalloc_range(struct inode *inode, struct page *locked_page, +static int run_delalloc_range(void *private_data, struct page *locked_page, u64 start, u64 end, int *page_started, unsigned long *nr_written) { + struct inode *inode = private_data; int ret; int force_cow = need_force_cow(inode, start, end); @@ -1596,9 +1596,10 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, return ret; } -static void btrfs_split_extent_hook(struct inode *inode, +static void btrfs_split_extent_hook(void *private_data, struct extent_state *orig, u64 split) { + struct inode *inode = private_data; u64 size; /* not delalloc, ignore it */ @@ -1633,10 +1634,11 @@ static void btrfs_split_extent_hook(struct inode *inode, * extents, such as when we are doing sequential writes, so we can properly * account for the metadata space we'll need. */ -static void btrfs_merge_extent_hook(struct inode *inode, +static void btrfs_merge_extent_hook(void *private_data, struct extent_state *new, struct extent_state *other) { + struct inode *inode = private_data; u64 new_size, old_size; u32 num_extents; @@ -1736,9 +1738,10 @@ static void btrfs_del_delalloc_inode(struct btrfs_root *root, * bytes in this file, and to maintain the list of inodes that * have pending delalloc work to be done. */ -static void btrfs_set_bit_hook(struct inode *inode, +static void btrfs_set_bit_hook(void *private_data, struct extent_state *state, unsigned *bits) { + struct inode *inode = private_data; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); @@ -1790,10 +1793,11 @@ static void btrfs_set_bit_hook(struct inode *inode, /* * extent_io.c clear_bit_hook, see set_bit_hook for why */ -static void btrfs_clear_bit_hook(struct btrfs_inode *inode, +static void btrfs_clear_bit_hook(void *private_data, struct extent_state *state, unsigned *bits) { + struct btrfs_inode *inode = BTRFS_I((struct inode *)private_data); struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb); u64 len = state->end + 1 - state->start; u32 num_extents = count_max_extents(len); @@ -1901,10 +1905,11 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset, * At IO completion time the cums attached on the ordered extent record * are inserted into the btree */ -static int __btrfs_submit_bio_start(struct inode *inode, struct bio *bio, +static int __btrfs_submit_bio_start(void *private_data, struct bio *bio, int mirror_num, unsigned long bio_flags, u64 bio_offset) { + struct inode *inode = private_data; int ret = 0; ret = btrfs_csum_one_bio(inode, bio, 0, 0); @@ -1920,10 +1925,11 @@ static int __btrfs_submit_bio_start(struct inode *inode, struct bio *bio, * At IO completion time the cums attached on the ordered extent record * are inserted into the btree */ -static int __btrfs_submit_bio_done(struct inode *inode, struct bio *bio, +static int __btrfs_submit_bio_done(void *private_data, struct bio *bio, int mirror_num, unsigned long bio_flags, u64 bio_offset) { + struct inode *inode = private_data; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); int ret; @@ -1939,10 +1945,11 @@ static int __btrfs_submit_bio_done(struct inode *inode, struct bio *bio, * extent_io.c submission hook. This does the right thing for csum calculation * on write, or reading the csums from the tree before a read */ -static int btrfs_submit_bio_hook(struct inode *inode, struct bio *bio, - int mirror_num, unsigned long bio_flags, - u64 bio_offset) +static int btrfs_submit_bio_hook(void *private_data, struct bio *bio, + int mirror_num, unsigned long bio_flags, + u64 bio_offset) { + struct inode *inode = private_data; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; enum btrfs_wq_endio_type metadata = BTRFS_WQ_ENDIO_DATA; @@ -1976,8 +1983,8 @@ static int btrfs_submit_bio_hook(struct inode *inode, struct bio *bio, if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID) goto mapit; /* we're doing a write, do the async checksumming */ - ret = btrfs_wq_submit_bio(fs_info, inode, bio, mirror_num, - bio_flags, bio_offset, + ret = btrfs_wq_submit_bio(fs_info, bio, mirror_num, bio_flags, + bio_offset, inode, __btrfs_submit_bio_start, __btrfs_submit_bio_done); goto out; @@ -2035,6 +2042,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) struct btrfs_writepage_fixup *fixup; struct btrfs_ordered_extent *ordered; struct extent_state *cached_state = NULL; + struct extent_changeset *data_reserved = NULL; struct page *page; struct inode *inode; u64 page_start; @@ -2072,7 +2080,7 @@ again: goto again; } - ret = btrfs_delalloc_reserve_space(inode, page_start, + ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start, PAGE_SIZE); if (ret) { mapping_set_error(page->mapping, ret); @@ -2092,6 +2100,7 @@ out_page: unlock_page(page); put_page(page); kfree(fixup); + extent_changeset_free(data_reserved); } /* @@ -2143,6 +2152,7 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, struct btrfs_path *path; struct extent_buffer *leaf; struct btrfs_key ins; + u64 qg_released; int extent_inserted = 0; int ret; @@ -2198,13 +2208,17 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, ins.objectid = disk_bytenr; ins.offset = disk_num_bytes; ins.type = BTRFS_EXTENT_ITEM_KEY; - ret = btrfs_alloc_reserved_file_extent(trans, root->root_key.objectid, - btrfs_ino(BTRFS_I(inode)), file_pos, ram_bytes, &ins); + /* * Release the reserved range from inode dirty range map, as it is * already moved into delayed_ref_head */ - btrfs_qgroup_release_data(inode, file_pos, ram_bytes); + ret = btrfs_qgroup_release_data(inode, file_pos, ram_bytes); + if (ret < 0) + goto out; + qg_released = ret; + ret = btrfs_alloc_reserved_file_extent(trans, root->root_key.objectid, + btrfs_ino(BTRFS_I(inode)), file_pos, qg_released, &ins); out: btrfs_free_path(path); @@ -2926,7 +2940,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) * space for NOCOW range. * As NOCOW won't cause a new delayed ref, just free the space */ - btrfs_qgroup_free_data(inode, ordered_extent->file_offset, + btrfs_qgroup_free_data(inode, NULL, ordered_extent->file_offset, ordered_extent->len); btrfs_ordered_update_i_size(inode, 0, ordered_extent); if (nolock) @@ -2952,7 +2966,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) ret = test_range_bit(io_tree, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len - 1, - EXTENT_DEFRAG, 1, cached_state); + EXTENT_DEFRAG, 0, cached_state); if (ret) { u64 last_snapshot = btrfs_root_last_snapshot(&root->root_item); if (0 && last_snapshot >= BTRFS_I(inode)->generation) @@ -4762,6 +4776,7 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct btrfs_ordered_extent *ordered; struct extent_state *cached_state = NULL; + struct extent_changeset *data_reserved = NULL; char *kaddr; u32 blocksize = fs_info->sectorsize; pgoff_t index = from >> PAGE_SHIFT; @@ -4776,7 +4791,7 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, (!len || ((len & (blocksize - 1)) == 0))) goto out; - ret = btrfs_delalloc_reserve_space(inode, + ret = btrfs_delalloc_reserve_space(inode, &data_reserved, round_down(from, blocksize), blocksize); if (ret) goto out; @@ -4784,7 +4799,7 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, again: page = find_or_create_page(mapping, index, mask); if (!page) { - btrfs_delalloc_release_space(inode, + btrfs_delalloc_release_space(inode, data_reserved, round_down(from, blocksize), blocksize); ret = -ENOMEM; @@ -4856,11 +4871,12 @@ again: out_unlock: if (ret) - btrfs_delalloc_release_space(inode, block_start, + btrfs_delalloc_release_space(inode, data_reserved, block_start, blocksize); unlock_page(page); put_page(page); out: + extent_changeset_free(data_reserved); return ret; } @@ -5255,7 +5271,7 @@ static void evict_inode_truncate_pages(struct inode *inode) * Note, end is the bytenr of last byte, so we need + 1 here. */ if (state->state & EXTENT_DELALLOC) - btrfs_qgroup_free_data(inode, start, end - start + 1); + btrfs_qgroup_free_data(inode, NULL, start, end - start + 1); clear_extent_bit(io_tree, start, end, EXTENT_LOCKED | EXTENT_DIRTY | @@ -5868,7 +5884,6 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) struct inode *inode = file_inode(file); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; - struct btrfs_item *item; struct btrfs_dir_item *di; struct btrfs_key key; struct btrfs_key found_key; @@ -5919,7 +5934,6 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) continue; } - item = btrfs_item_nr(slot); btrfs_item_key_to_cpu(leaf, &found_key, slot); if (found_key.objectid != key.objectid) @@ -7480,11 +7494,11 @@ out: bool btrfs_page_exists_in_range(struct inode *inode, loff_t start, loff_t end) { struct radix_tree_root *root = &inode->i_mapping->page_tree; - int found = false; + bool found = false; void **pagep = NULL; struct page *page = NULL; - int start_idx; - int end_idx; + unsigned long start_idx; + unsigned long end_idx; start_idx = start >> PAGE_SHIFT; @@ -7978,9 +7992,12 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, bio_end_io_t *repair_endio, void *repair_arg) { struct io_failure_record *failrec; + struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; + struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree; struct bio *bio; int isector; int read_mode = 0; + int segs; int ret; BUG_ON(bio_op(failed_bio) == REQ_OP_WRITE); @@ -7992,13 +8009,13 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, ret = btrfs_check_dio_repairable(inode, failed_bio, failrec, failed_mirror); if (!ret) { - free_io_failure(BTRFS_I(inode), failrec); + free_io_failure(failure_tree, io_tree, failrec); return -EIO; } - if ((failed_bio->bi_vcnt > 1) - || (failed_bio->bi_io_vec->bv_len - > btrfs_inode_sectorsize(inode))) + segs = bio_segments(failed_bio); + if (segs > 1 || + (failed_bio->bi_io_vec->bv_len > btrfs_inode_sectorsize(inode))) read_mode |= REQ_FAILFAST_DEV; isector = start - btrfs_io_bio(failed_bio)->logical; @@ -8006,7 +8023,7 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, bio = btrfs_create_repair_bio(inode, failed_bio, failrec, page, pgoff, isector, repair_endio, repair_arg); if (!bio) { - free_io_failure(BTRFS_I(inode), failrec); + free_io_failure(failure_tree, io_tree, failrec); return -EIO; } bio_set_op_attrs(bio, REQ_OP_READ, read_mode); @@ -8017,7 +8034,7 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, ret = submit_dio_repair_bio(inode, bio, failrec->this_mirror); if (ret) { - free_io_failure(BTRFS_I(inode), failrec); + free_io_failure(failure_tree, io_tree, failrec); bio_put(bio); } @@ -8034,19 +8051,24 @@ struct btrfs_retry_complete { static void btrfs_retry_endio_nocsum(struct bio *bio) { struct btrfs_retry_complete *done = bio->bi_private; + struct inode *inode = done->inode; struct bio_vec *bvec; + struct extent_io_tree *io_tree, *failure_tree; int i; if (bio->bi_error) goto end; ASSERT(bio->bi_vcnt == 1); - ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(done->inode)); + io_tree = &BTRFS_I(inode)->io_tree; + failure_tree = &BTRFS_I(inode)->io_failure_tree; + ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(inode)); done->uptodate = 1; bio_for_each_segment_all(bvec, bio, i) - clean_io_failure(BTRFS_I(done->inode), done->start, - bvec->bv_page, 0); + clean_io_failure(BTRFS_I(inode)->root->fs_info, failure_tree, + io_tree, done->start, bvec->bv_page, + btrfs_ino(BTRFS_I(inode)), 0); end: complete(&done->done); bio_put(bio); @@ -8056,36 +8078,40 @@ static int __btrfs_correct_data_nocsum(struct inode *inode, struct btrfs_io_bio *io_bio) { struct btrfs_fs_info *fs_info; - struct bio_vec *bvec; + struct bio_vec bvec; + struct bvec_iter iter; struct btrfs_retry_complete done; u64 start; unsigned int pgoff; u32 sectorsize; int nr_sectors; - int i; int ret; + int err = 0; fs_info = BTRFS_I(inode)->root->fs_info; sectorsize = fs_info->sectorsize; start = io_bio->logical; done.inode = inode; + io_bio->bio.bi_iter = io_bio->iter; - bio_for_each_segment_all(bvec, &io_bio->bio, i) { - nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bvec->bv_len); - pgoff = bvec->bv_offset; + bio_for_each_segment(bvec, &io_bio->bio, iter) { + nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bvec.bv_len); + pgoff = bvec.bv_offset; next_block_or_try_again: done.uptodate = 0; done.start = start; init_completion(&done.done); - ret = dio_read_error(inode, &io_bio->bio, bvec->bv_page, + ret = dio_read_error(inode, &io_bio->bio, bvec.bv_page, pgoff, start, start + sectorsize - 1, io_bio->mirror_num, btrfs_retry_endio_nocsum, &done); - if (ret) - return ret; + if (ret) { + err = ret; + goto next; + } wait_for_completion(&done.done); @@ -8094,6 +8120,7 @@ next_block_or_try_again: goto next_block_or_try_again; } +next: start += sectorsize; nr_sectors--; @@ -8104,13 +8131,15 @@ next_block_or_try_again: } } - return 0; + return err; } static void btrfs_retry_endio(struct bio *bio) { struct btrfs_retry_complete *done = bio->bi_private; struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); + struct extent_io_tree *io_tree, *failure_tree; + struct inode *inode = done->inode; struct bio_vec *bvec; int uptodate; int ret; @@ -8124,13 +8153,19 @@ static void btrfs_retry_endio(struct bio *bio) ASSERT(bio->bi_vcnt == 1); ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(done->inode)); + io_tree = &BTRFS_I(inode)->io_tree; + failure_tree = &BTRFS_I(inode)->io_failure_tree; + bio_for_each_segment_all(bvec, bio, i) { - ret = __readpage_endio_check(done->inode, io_bio, i, - bvec->bv_page, bvec->bv_offset, - done->start, bvec->bv_len); + ret = __readpage_endio_check(inode, io_bio, i, bvec->bv_page, + bvec->bv_offset, done->start, + bvec->bv_len); if (!ret) - clean_io_failure(BTRFS_I(done->inode), done->start, - bvec->bv_page, bvec->bv_offset); + clean_io_failure(BTRFS_I(inode)->root->fs_info, + failure_tree, io_tree, done->start, + bvec->bv_page, + btrfs_ino(BTRFS_I(inode)), + bvec->bv_offset); else uptodate = 0; } @@ -8145,7 +8180,8 @@ static int __btrfs_subio_endio_read(struct inode *inode, struct btrfs_io_bio *io_bio, int err) { struct btrfs_fs_info *fs_info; - struct bio_vec *bvec; + struct bio_vec bvec; + struct bvec_iter iter; struct btrfs_retry_complete done; u64 start; u64 offset = 0; @@ -8153,7 +8189,7 @@ static int __btrfs_subio_endio_read(struct inode *inode, int nr_sectors; unsigned int pgoff; int csum_pos; - int i; + int uptodate = !!(err == 0); int ret; fs_info = BTRFS_I(inode)->root->fs_info; @@ -8162,24 +8198,27 @@ static int __btrfs_subio_endio_read(struct inode *inode, err = 0; start = io_bio->logical; done.inode = inode; + io_bio->bio.bi_iter = io_bio->iter; - bio_for_each_segment_all(bvec, &io_bio->bio, i) { - nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bvec->bv_len); + bio_for_each_segment(bvec, &io_bio->bio, iter) { + nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bvec.bv_len); - pgoff = bvec->bv_offset; + pgoff = bvec.bv_offset; next_block: - csum_pos = BTRFS_BYTES_TO_BLKS(fs_info, offset); - ret = __readpage_endio_check(inode, io_bio, csum_pos, - bvec->bv_page, pgoff, start, - sectorsize); - if (likely(!ret)) - goto next; + if (uptodate) { + csum_pos = BTRFS_BYTES_TO_BLKS(fs_info, offset); + ret = __readpage_endio_check(inode, io_bio, csum_pos, + bvec.bv_page, pgoff, + start, sectorsize); + if (likely(!ret)) + goto next; + } try_again: done.uptodate = 0; done.start = start; init_completion(&done.done); - ret = dio_read_error(inode, &io_bio->bio, bvec->bv_page, + ret = dio_read_error(inode, &io_bio->bio, bvec.bv_page, pgoff, start, start + sectorsize - 1, io_bio->mirror_num, btrfs_retry_endio, &done); @@ -8234,8 +8273,11 @@ static void btrfs_endio_direct_read(struct bio *bio) struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); int err = bio->bi_error; - if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED) + if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED) { err = btrfs_subio_endio_read(inode, io_bio, err); + if (!err) + bio->bi_error = 0; + } unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset, dip->logical_offset + dip->bytes - 1); @@ -8308,10 +8350,11 @@ static void btrfs_endio_direct_write(struct bio *bio) bio_put(bio); } -static int __btrfs_submit_bio_start_direct_io(struct inode *inode, +static int __btrfs_submit_bio_start_direct_io(void *private_data, struct bio *bio, int mirror_num, unsigned long bio_flags, u64 offset) { + struct inode *inode = private_data; int ret; ret = btrfs_csum_one_bio(inode, bio, offset, 1); BUG_ON(ret); /* -ENOMEM */ @@ -8358,16 +8401,6 @@ out: bio_put(bio); } -static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev, - u64 first_sector, gfp_t gfp_flags) -{ - struct bio *bio; - bio = btrfs_bio_alloc(bdev, first_sector, BIO_MAX_PAGES, gfp_flags); - if (bio) - bio_associate_current(bio); - return bio; -} - static inline int btrfs_lookup_and_bind_dio_csum(struct inode *inode, struct btrfs_dio_private *dip, struct bio *bio, @@ -8423,8 +8456,8 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, goto map; if (write && async_submit) { - ret = btrfs_wq_submit_bio(fs_info, inode, bio, 0, 0, - file_offset, + ret = btrfs_wq_submit_bio(fs_info, bio, 0, 0, + file_offset, inode, __btrfs_submit_bio_start_direct_io, __btrfs_submit_bio_done); goto err; @@ -8454,103 +8487,83 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, { struct inode *inode = dip->inode; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); - struct btrfs_root *root = BTRFS_I(inode)->root; struct bio *bio; struct bio *orig_bio = dip->orig_bio; - struct bio_vec *bvec; u64 start_sector = orig_bio->bi_iter.bi_sector; u64 file_offset = dip->logical_offset; - u64 submit_len = 0; u64 map_length; - u32 blocksize = fs_info->sectorsize; int async_submit = 0; - int nr_sectors; + u64 submit_len; + int clone_offset = 0; + int clone_len; int ret; - int i, j; map_length = orig_bio->bi_iter.bi_size; + submit_len = map_length; ret = btrfs_map_block(fs_info, btrfs_op(orig_bio), start_sector << 9, &map_length, NULL, 0); if (ret) return -EIO; - if (map_length >= orig_bio->bi_iter.bi_size) { + if (map_length >= submit_len) { bio = orig_bio; dip->flags |= BTRFS_DIO_ORIG_BIO_SUBMITTED; goto submit; } /* async crcs make it difficult to collect full stripe writes. */ - if (btrfs_get_alloc_profile(root, 1) & BTRFS_BLOCK_GROUP_RAID56_MASK) + if (btrfs_data_alloc_profile(fs_info) & BTRFS_BLOCK_GROUP_RAID56_MASK) async_submit = 0; else async_submit = 1; - bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); - if (!bio) - return -ENOMEM; - - bio->bi_opf = orig_bio->bi_opf; - bio->bi_private = dip; - bio->bi_end_io = btrfs_end_dio_bio; - btrfs_io_bio(bio)->logical = file_offset; + /* bio split */ + ASSERT(map_length <= INT_MAX); atomic_inc(&dip->pending_bios); + do { + clone_len = min_t(int, submit_len, map_length); - bio_for_each_segment_all(bvec, orig_bio, j) { - nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bvec->bv_len); - i = 0; -next_block: - if (unlikely(map_length < submit_len + blocksize || - bio_add_page(bio, bvec->bv_page, blocksize, - bvec->bv_offset + (i * blocksize)) < blocksize)) { - /* - * inc the count before we submit the bio so - * we know the end IO handler won't happen before - * we inc the count. Otherwise, the dip might get freed - * before we're done setting it up - */ - atomic_inc(&dip->pending_bios); - ret = __btrfs_submit_dio_bio(bio, inode, - file_offset, skip_sum, - async_submit); - if (ret) { - bio_put(bio); - atomic_dec(&dip->pending_bios); - goto out_err; - } - - start_sector += submit_len >> 9; - file_offset += submit_len; + /* + * This will never fail as it's passing GPF_NOFS and + * the allocation is backed by btrfs_bioset. + */ + bio = btrfs_bio_clone_partial(orig_bio, clone_offset, + clone_len); + bio->bi_private = dip; + bio->bi_end_io = btrfs_end_dio_bio; + btrfs_io_bio(bio)->logical = file_offset; + + ASSERT(submit_len >= clone_len); + submit_len -= clone_len; + if (submit_len == 0) + break; - submit_len = 0; + /* + * Increase the count before we submit the bio so we know + * the end IO handler won't happen before we increase the + * count. Otherwise, the dip might get freed before we're + * done setting it up. + */ + atomic_inc(&dip->pending_bios); - bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, - start_sector, GFP_NOFS); - if (!bio) - goto out_err; - bio->bi_opf = orig_bio->bi_opf; - bio->bi_private = dip; - bio->bi_end_io = btrfs_end_dio_bio; - btrfs_io_bio(bio)->logical = file_offset; + ret = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum, + async_submit); + if (ret) { + bio_put(bio); + atomic_dec(&dip->pending_bios); + goto out_err; + } - map_length = orig_bio->bi_iter.bi_size; - ret = btrfs_map_block(fs_info, btrfs_op(orig_bio), - start_sector << 9, - &map_length, NULL, 0); - if (ret) { - bio_put(bio); - goto out_err; - } + clone_offset += clone_len; + start_sector += clone_len >> 9; + file_offset += clone_len; - goto next_block; - } else { - submit_len += blocksize; - if (--nr_sectors) { - i++; - goto next_block; - } - } - } + map_length = submit_len; + ret = btrfs_map_block(fs_info, btrfs_op(orig_bio), + start_sector << 9, &map_length, NULL, 0); + if (ret) + goto out_err; + } while (submit_len > 0); submit: ret = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum, @@ -8577,16 +8590,16 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode, loff_t file_offset) { struct btrfs_dio_private *dip = NULL; - struct bio *io_bio = NULL; - struct btrfs_io_bio *btrfs_bio; + struct bio *bio = NULL; + struct btrfs_io_bio *io_bio; int skip_sum; bool write = (bio_op(dio_bio) == REQ_OP_WRITE); int ret = 0; skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; - io_bio = btrfs_bio_clone(dio_bio, GFP_NOFS); - if (!io_bio) { + bio = btrfs_bio_clone(dio_bio, GFP_NOFS); + if (!bio) { ret = -ENOMEM; goto free_ordered; } @@ -8602,17 +8615,17 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode, dip->logical_offset = file_offset; dip->bytes = dio_bio->bi_iter.bi_size; dip->disk_bytenr = (u64)dio_bio->bi_iter.bi_sector << 9; - io_bio->bi_private = dip; - dip->orig_bio = io_bio; + bio->bi_private = dip; + dip->orig_bio = bio; dip->dio_bio = dio_bio; atomic_set(&dip->pending_bios, 0); - btrfs_bio = btrfs_io_bio(io_bio); - btrfs_bio->logical = file_offset; + io_bio = btrfs_io_bio(bio); + io_bio->logical = file_offset; if (write) { - io_bio->bi_end_io = btrfs_endio_direct_write; + bio->bi_end_io = btrfs_endio_direct_write; } else { - io_bio->bi_end_io = btrfs_endio_direct_read; + bio->bi_end_io = btrfs_endio_direct_read; dip->subio_endio = btrfs_subio_endio_read; } @@ -8635,8 +8648,8 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode, if (!ret) return; - if (btrfs_bio->end_io) - btrfs_bio->end_io(btrfs_bio, ret); + if (io_bio->end_io) + io_bio->end_io(io_bio, ret); free_ordered: /* @@ -8648,16 +8661,16 @@ free_ordered: * same as btrfs_endio_direct_[write|read] because we can't call these * callbacks - they require an allocated dip and a clone of dio_bio. */ - if (io_bio && dip) { - io_bio->bi_error = -EIO; - bio_endio(io_bio); + if (bio && dip) { + bio->bi_error = -EIO; + bio_endio(bio); /* - * The end io callbacks free our dip, do the final put on io_bio + * The end io callbacks free our dip, do the final put on bio * and all the cleanup and final put for dio_bio (through * dio_end_io()). */ dip = NULL; - io_bio = NULL; + bio = NULL; } else { if (write) __endio_write_update_ordered(inode, @@ -8675,8 +8688,8 @@ free_ordered: */ dio_end_io(dio_bio, ret); } - if (io_bio) - bio_put(io_bio); + if (bio) + bio_put(bio); kfree(dip); } @@ -8720,6 +8733,7 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) struct inode *inode = file->f_mapping->host; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_dio_data dio_data = { 0 }; + struct extent_changeset *data_reserved = NULL; loff_t offset = iocb->ki_pos; size_t count = 0; int flags = 0; @@ -8756,7 +8770,8 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) inode_unlock(inode); relock = true; } - ret = btrfs_delalloc_reserve_space(inode, offset, count); + ret = btrfs_delalloc_reserve_space(inode, &data_reserved, + offset, count); if (ret) goto out; dio_data.outstanding_extents = count_max_extents(count); @@ -8788,8 +8803,8 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) current->journal_info = NULL; if (ret < 0 && ret != -EIOCBQUEUED) { if (dio_data.reserve) - btrfs_delalloc_release_space(inode, offset, - dio_data.reserve); + btrfs_delalloc_release_space(inode, data_reserved, + offset, dio_data.reserve); /* * On error we might have left some ordered extents * without submitting corresponding bios for them, so @@ -8804,8 +8819,8 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) dio_data.unsubmitted_oe_range_start, false); } else if (ret >= 0 && (size_t)ret < count) - btrfs_delalloc_release_space(inode, offset, - count - (size_t)ret); + btrfs_delalloc_release_space(inode, data_reserved, + offset, count - (size_t)ret); } out: if (wakeup) @@ -8813,6 +8828,7 @@ out: if (relock) inode_lock(inode); + extent_changeset_free(data_reserved); return ret; } @@ -9003,7 +9019,7 @@ again: * free the entire extent. */ if (PageDirty(page)) - btrfs_qgroup_free_data(inode, page_start, PAGE_SIZE); + btrfs_qgroup_free_data(inode, NULL, page_start, PAGE_SIZE); if (!inode_evicting) { clear_extent_bit(tree, page_start, page_end, EXTENT_LOCKED | EXTENT_DIRTY | @@ -9045,6 +9061,7 @@ int btrfs_page_mkwrite(struct vm_fault *vmf) struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct btrfs_ordered_extent *ordered; struct extent_state *cached_state = NULL; + struct extent_changeset *data_reserved = NULL; char *kaddr; unsigned long zero_start; loff_t size; @@ -9070,7 +9087,7 @@ int btrfs_page_mkwrite(struct vm_fault *vmf) * end up waiting indefinitely to get a lock on the page currently * being processed by btrfs_page_mkwrite() function. */ - ret = btrfs_delalloc_reserve_space(inode, page_start, + ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start, reserved_space); if (!ret) { ret = file_update_time(vmf->vma->vm_file); @@ -9124,8 +9141,8 @@ again: spin_lock(&BTRFS_I(inode)->lock); BTRFS_I(inode)->outstanding_extents++; spin_unlock(&BTRFS_I(inode)->lock); - btrfs_delalloc_release_space(inode, page_start, - PAGE_SIZE - reserved_space); + btrfs_delalloc_release_space(inode, data_reserved, + page_start, PAGE_SIZE - reserved_space); } } @@ -9176,13 +9193,16 @@ again: out_unlock: if (!ret) { sb_end_pagefault(inode->i_sb); + extent_changeset_free(data_reserved); return VM_FAULT_LOCKED; } unlock_page(page); out: - btrfs_delalloc_release_space(inode, page_start, reserved_space); + btrfs_delalloc_release_space(inode, data_reserved, page_start, + reserved_space); out_noreserve: sb_end_pagefault(inode->i_sb); + extent_changeset_free(data_reserved); return ret; } @@ -9404,8 +9424,8 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) inode = &ei->vfs_inode; extent_map_tree_init(&ei->extent_tree); - extent_io_tree_init(&ei->io_tree, &inode->i_data); - extent_io_tree_init(&ei->io_failure_tree, &inode->i_data); + extent_io_tree_init(&ei->io_tree, inode); + extent_io_tree_init(&ei->io_failure_tree, inode); ei->io_tree.track_uptodate = 1; ei->io_failure_tree.track_uptodate = 1; atomic_set(&ei->sync_writers, 0); @@ -9514,7 +9534,6 @@ void btrfs_destroy_cachep(void) rcu_barrier(); kmem_cache_destroy(btrfs_inode_cachep); kmem_cache_destroy(btrfs_trans_handle_cachep); - kmem_cache_destroy(btrfs_transaction_cachep); kmem_cache_destroy(btrfs_path_cachep); kmem_cache_destroy(btrfs_free_space_cachep); } @@ -9534,12 +9553,6 @@ int btrfs_init_cachep(void) if (!btrfs_trans_handle_cachep) goto fail; - btrfs_transaction_cachep = kmem_cache_create("btrfs_transaction", - sizeof(struct btrfs_transaction), 0, - SLAB_TEMPORARY | SLAB_MEM_SPREAD, NULL); - if (!btrfs_transaction_cachep) - goto fail; - btrfs_path_cachep = kmem_cache_create("btrfs_path", sizeof(struct btrfs_path), 0, SLAB_MEM_SPREAD, NULL); @@ -9564,6 +9577,24 @@ static int btrfs_getattr(const struct path *path, struct kstat *stat, u64 delalloc_bytes; struct inode *inode = d_inode(path->dentry); u32 blocksize = inode->i_sb->s_blocksize; + u32 bi_flags = BTRFS_I(inode)->flags; + + stat->result_mask |= STATX_BTIME; + stat->btime.tv_sec = BTRFS_I(inode)->i_otime.tv_sec; + stat->btime.tv_nsec = BTRFS_I(inode)->i_otime.tv_nsec; + if (bi_flags & BTRFS_INODE_APPEND) + stat->attributes |= STATX_ATTR_APPEND; + if (bi_flags & BTRFS_INODE_COMPRESS) + stat->attributes |= STATX_ATTR_COMPRESSED; + if (bi_flags & BTRFS_INODE_IMMUTABLE) + stat->attributes |= STATX_ATTR_IMMUTABLE; + if (bi_flags & BTRFS_INODE_NODUMP) + stat->attributes |= STATX_ATTR_NODUMP; + + stat->attributes_mask |= (STATX_ATTR_APPEND | + STATX_ATTR_COMPRESSED | + STATX_ATTR_IMMUTABLE | + STATX_ATTR_NODUMP); generic_fillattr(inode, stat); stat->dev = BTRFS_I(inode)->root->anon_dev; @@ -10538,7 +10569,7 @@ next: btrfs_end_transaction(trans); } if (cur_offset < end) - btrfs_free_reserved_data_space(inode, cur_offset, + btrfs_free_reserved_data_space(inode, NULL, cur_offset, end - cur_offset + 1); return ret; } @@ -10659,6 +10690,42 @@ static int btrfs_readpage_io_failed_hook(struct page *page, int failed_mirror) return -EAGAIN; } +static struct btrfs_fs_info *iotree_fs_info(void *private_data) +{ + struct inode *inode = private_data; + return btrfs_sb(inode->i_sb); +} + +static void btrfs_check_extent_io_range(void *private_data, const char *caller, + u64 start, u64 end) +{ + struct inode *inode = private_data; + u64 isize; + + isize = i_size_read(inode); + if (end >= PAGE_SIZE && (end % 2) == 0 && end != isize - 1) { + btrfs_debug_rl(BTRFS_I(inode)->root->fs_info, + "%s: ino %llu isize %llu odd range [%llu,%llu]", + caller, btrfs_ino(BTRFS_I(inode)), isize, start, end); + } +} + +void btrfs_set_range_writeback(void *private_data, u64 start, u64 end) +{ + struct inode *inode = private_data; + unsigned long index = start >> PAGE_SHIFT; + unsigned long end_index = end >> PAGE_SHIFT; + struct page *page; + + while (index <= end_index) { + page = find_get_page(inode->i_mapping, index); + ASSERT(page); /* Pages should be in the extent_io_tree */ + set_page_writeback(page); + put_page(page); + index++; + } +} + static const struct inode_operations btrfs_dir_inode_operations = { .getattr = btrfs_getattr, .lookup = btrfs_lookup, @@ -10702,6 +10769,8 @@ static const struct extent_io_ops btrfs_extent_io_ops = { .readpage_end_io_hook = btrfs_readpage_end_io_hook, .merge_bio_hook = btrfs_merge_bio_hook, .readpage_io_failed_hook = btrfs_readpage_io_failed_hook, + .tree_fs_info = iotree_fs_info, + .set_range_writeback = btrfs_set_range_writeback, /* optional callbacks */ .fill_delalloc = run_delalloc_range, @@ -10711,6 +10780,7 @@ static const struct extent_io_ops btrfs_extent_io_ops = { .clear_bit_hook = btrfs_clear_bit_hook, .merge_extent_hook = btrfs_merge_extent_hook, .split_extent_hook = btrfs_split_extent_hook, + .check_extent_io_range = btrfs_check_extent_io_range, }; /* diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index e176375f374f..b4e9941efb60 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -37,7 +37,7 @@ #include <linux/bit_spinlock.h> #include <linux/security.h> #include <linux/xattr.h> -#include <linux/vmalloc.h> +#include <linux/mm.h> #include <linux/slab.h> #include <linux/blkdev.h> #include <linux/uuid.h> @@ -1127,6 +1127,7 @@ static int cluster_pages_for_defrag(struct inode *inode, struct btrfs_ordered_extent *ordered; struct extent_state *cached_state = NULL; struct extent_io_tree *tree; + struct extent_changeset *data_reserved = NULL; gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping); file_end = (isize - 1) >> PAGE_SHIFT; @@ -1135,7 +1136,7 @@ static int cluster_pages_for_defrag(struct inode *inode, page_cnt = min_t(u64, (u64)num_pages, (u64)file_end - start_index + 1); - ret = btrfs_delalloc_reserve_space(inode, + ret = btrfs_delalloc_reserve_space(inode, &data_reserved, start_index << PAGE_SHIFT, page_cnt << PAGE_SHIFT); if (ret) @@ -1226,7 +1227,7 @@ again: spin_lock(&BTRFS_I(inode)->lock); BTRFS_I(inode)->outstanding_extents++; spin_unlock(&BTRFS_I(inode)->lock); - btrfs_delalloc_release_space(inode, + btrfs_delalloc_release_space(inode, data_reserved, start_index << PAGE_SHIFT, (page_cnt - i_done) << PAGE_SHIFT); } @@ -1247,15 +1248,17 @@ again: unlock_page(pages[i]); put_page(pages[i]); } + extent_changeset_free(data_reserved); return i_done; out: for (i = 0; i < i_done; i++) { unlock_page(pages[i]); put_page(pages[i]); } - btrfs_delalloc_release_space(inode, + btrfs_delalloc_release_space(inode, data_reserved, start_index << PAGE_SHIFT, page_cnt << PAGE_SHIFT); + extent_changeset_free(data_reserved); return ret; } @@ -4588,7 +4591,7 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_fs_info *fs_info, out: btrfs_free_path(path); - vfree(inodes); + kvfree(inodes); kfree(loi); return ret; @@ -4897,7 +4900,6 @@ static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) goto out; } - /* FIXME: check if the IDs really exist */ if (sa->assign) { ret = btrfs_add_qgroup_relation(trans, fs_info, sa->src, sa->dst); @@ -4956,7 +4958,6 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg) goto out; } - /* FIXME: check if the IDs really exist */ if (sa->create) { ret = btrfs_create_qgroup(trans, fs_info, sa->qgroupid); } else { @@ -5010,7 +5011,6 @@ static long btrfs_ioctl_qgroup_limit(struct file *file, void __user *arg) qgroupid = root->root_key.objectid; } - /* FIXME: check if the IDs really exist */ ret = btrfs_limit_qgroup(trans, fs_info, qgroupid, &sa->lim); err = btrfs_end_transaction(trans); diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index f48c8c14dc14..cde13cce01a0 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -18,13 +18,14 @@ #include <linux/kernel.h> #include <linux/slab.h> -#include <linux/vmalloc.h> +#include <linux/mm.h> #include <linux/init.h> #include <linux/err.h> #include <linux/sched.h> #include <linux/pagemap.h> #include <linux/bio.h> #include <linux/lzo.h> +#include <linux/refcount.h> #include "compression.h" #define LZO_LEN 4 @@ -40,9 +41,9 @@ static void lzo_free_workspace(struct list_head *ws) { struct workspace *workspace = list_entry(ws, struct workspace, list); - vfree(workspace->buf); - vfree(workspace->cbuf); - vfree(workspace->mem); + kvfree(workspace->buf); + kvfree(workspace->cbuf); + kvfree(workspace->mem); kfree(workspace); } @@ -50,13 +51,13 @@ static struct list_head *lzo_alloc_workspace(void) { struct workspace *workspace; - workspace = kzalloc(sizeof(*workspace), GFP_NOFS); + workspace = kzalloc(sizeof(*workspace), GFP_KERNEL); if (!workspace) return ERR_PTR(-ENOMEM); - workspace->mem = vmalloc(LZO1X_MEM_COMPRESS); - workspace->buf = vmalloc(lzo1x_worst_compress(PAGE_SIZE)); - workspace->cbuf = vmalloc(lzo1x_worst_compress(PAGE_SIZE)); + workspace->mem = kvmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); + workspace->buf = kvmalloc(lzo1x_worst_compress(PAGE_SIZE), GFP_KERNEL); + workspace->cbuf = kvmalloc(lzo1x_worst_compress(PAGE_SIZE), GFP_KERNEL); if (!workspace->mem || !workspace->buf || !workspace->cbuf) goto fail; @@ -141,7 +142,7 @@ static int lzo_compress_pages(struct list_head *ws, ret = lzo1x_1_compress(data_in, in_len, workspace->cbuf, &out_len, workspace->mem); if (ret != LZO_E_OK) { - pr_debug("BTRFS: deflate in loop returned %d\n", + pr_debug("BTRFS: lzo in loop returned %d\n", ret); ret = -EIO; goto out; @@ -254,16 +255,13 @@ out: return ret; } -static int lzo_decompress_bio(struct list_head *ws, - struct page **pages_in, - u64 disk_start, - struct bio *orig_bio, - size_t srclen) +static int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb) { struct workspace *workspace = list_entry(ws, struct workspace, list); int ret = 0, ret2; char *data_in; unsigned long page_in_index = 0; + size_t srclen = cb->compressed_len; unsigned long total_pages_in = DIV_ROUND_UP(srclen, PAGE_SIZE); unsigned long buf_start; unsigned long buf_offset = 0; @@ -278,6 +276,9 @@ static int lzo_decompress_bio(struct list_head *ws, unsigned long tot_len; char *buf; bool may_late_unmap, need_unmap; + struct page **pages_in = cb->compressed_pages; + u64 disk_start = cb->start; + struct bio *orig_bio = cb->orig_bio; data_in = kmap(pages_in[0]); tot_len = read_compress_length(data_in); diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index cdafbf92ef0c..fcae61e175f3 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c @@ -261,8 +261,11 @@ void btrfs_print_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *l) case BTRFS_BLOCK_GROUP_ITEM_KEY: bi = btrfs_item_ptr(l, i, struct btrfs_block_group_item); - pr_info("\t\tblock group used %llu\n", - btrfs_disk_block_group_used(l, bi)); + pr_info( + "\t\tblock group used %llu chunk_objectid %llu flags %llu\n", + btrfs_disk_block_group_used(l, bi), + btrfs_disk_block_group_chunk_objectid(l, bi), + btrfs_disk_block_group_flags(l, bi)); break; case BTRFS_CHUNK_ITEM_KEY: print_chunk(l, btrfs_item_ptr(l, i, diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index deffbeb74a0b..acfe37360084 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1406,38 +1406,6 @@ out: return ret; } -int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info) -{ - struct btrfs_qgroup_extent_record *record; - struct btrfs_delayed_ref_root *delayed_refs; - struct rb_node *node; - u64 qgroup_to_skip; - int ret = 0; - - delayed_refs = &trans->transaction->delayed_refs; - qgroup_to_skip = delayed_refs->qgroup_to_skip; - - /* - * No need to do lock, since this function will only be called in - * btrfs_commit_transaction(). - */ - node = rb_first(&delayed_refs->dirty_extent_root); - while (node) { - record = rb_entry(node, struct btrfs_qgroup_extent_record, - node); - if (WARN_ON(!record->old_roots)) - ret = btrfs_find_all_roots(NULL, fs_info, - record->bytenr, 0, &record->old_roots); - if (ret < 0) - break; - if (qgroup_to_skip) - ulist_del(record->old_roots, qgroup_to_skip, 0); - node = rb_next(node); - } - return ret; -} - int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info, struct btrfs_delayed_ref_root *delayed_refs, struct btrfs_qgroup_extent_record *record) @@ -1918,6 +1886,33 @@ static int qgroup_update_counters(struct btrfs_fs_info *fs_info, return 0; } +/* + * Helper to check if the @roots is a list of fs tree roots + * Return 0 for definitely not a fs/subvol tree roots ulist + * Return 1 for possible fs/subvol tree roots ulist(including empty) + */ +static int maybe_fs_roots(struct ulist *roots) +{ + struct ulist_node *unode; + struct ulist_iterator uiter; + + /* Empty one, still possible for fs roots */ + if (!roots || roots->nnodes == 0) + return 1; + + ULIST_ITER_INIT(&uiter); + unode = ulist_next(roots, &uiter); + if (!unode) + return 1; + + /* + * If it contains fs tree roots, then it must belongs to fs/subvol + * trees. + * If it contains non-fs tree, it won't be shared to fs/subvol trees. + */ + return is_fstree(unode->val); +} + int btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, @@ -1934,10 +1929,20 @@ btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) return 0; - if (new_roots) + if (new_roots) { + if (!maybe_fs_roots(new_roots)) + goto out_free; nr_new_roots = new_roots->nnodes; - if (old_roots) + } + if (old_roots) { + if (!maybe_fs_roots(old_roots)) + goto out_free; nr_old_roots = old_roots->nnodes; + } + + /* Quick exit, either not fs tree roots, or won't affect any qgroup */ + if (nr_old_roots == 0 && nr_new_roots == 0) + goto out_free; BUG_ON(!fs_info->quota_root); @@ -2017,6 +2022,19 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans, if (!ret) { /* + * old roots should be searched when inserting qgroup + * extent record + */ + if (WARN_ON(!record->old_roots)) { + /* Search commit root to find old_roots */ + ret = btrfs_find_all_roots(NULL, fs_info, + record->bytenr, 0, + &record->old_roots); + if (ret < 0) + goto cleanup; + } + + /* * Use SEQ_LAST as time_seq to do special search, which * doesn't lock tree or delayed_refs and search current * root. It's safe inside commit_transaction(). @@ -2025,8 +2043,11 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans, record->bytenr, SEQ_LAST, &new_roots); if (ret < 0) goto cleanup; - if (qgroup_to_skip) + if (qgroup_to_skip) { ulist_del(new_roots, qgroup_to_skip, 0); + ulist_del(record->old_roots, qgroup_to_skip, + 0); + } ret = btrfs_qgroup_account_extent(trans, fs_info, record->bytenr, record->num_bytes, record->old_roots, new_roots); @@ -2338,6 +2359,11 @@ static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes, bool enforce) if (num_bytes == 0) return 0; + + if (test_bit(BTRFS_FS_QUOTA_OVERRIDE, &fs_info->flags) && + capable(CAP_SYS_RESOURCE)) + enforce = false; + retry: spin_lock(&fs_info->qgroup_lock); quota_root = fs_info->quota_root; @@ -2806,55 +2832,130 @@ btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info) * Return <0 for error (including -EQUOT) * * NOTE: this function may sleep for memory allocation. + * if btrfs_qgroup_reserve_data() is called multiple times with + * same @reserved, caller must ensure when error happens it's OK + * to free *ALL* reserved space. */ -int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len) +int btrfs_qgroup_reserve_data(struct inode *inode, + struct extent_changeset **reserved_ret, u64 start, + u64 len) { struct btrfs_root *root = BTRFS_I(inode)->root; - struct extent_changeset changeset; struct ulist_node *unode; struct ulist_iterator uiter; + struct extent_changeset *reserved; + u64 orig_reserved; + u64 to_reserve; int ret; if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags) || !is_fstree(root->objectid) || len == 0) return 0; - changeset.bytes_changed = 0; - ulist_init(&changeset.range_changed); + /* @reserved parameter is mandatory for qgroup */ + if (WARN_ON(!reserved_ret)) + return -EINVAL; + if (!*reserved_ret) { + *reserved_ret = extent_changeset_alloc(); + if (!*reserved_ret) + return -ENOMEM; + } + reserved = *reserved_ret; + /* Record already reserved space */ + orig_reserved = reserved->bytes_changed; ret = set_record_extent_bits(&BTRFS_I(inode)->io_tree, start, - start + len -1, EXTENT_QGROUP_RESERVED, &changeset); + start + len -1, EXTENT_QGROUP_RESERVED, reserved); + + /* Newly reserved space */ + to_reserve = reserved->bytes_changed - orig_reserved; trace_btrfs_qgroup_reserve_data(inode, start, len, - changeset.bytes_changed, - QGROUP_RESERVE); + to_reserve, QGROUP_RESERVE); if (ret < 0) goto cleanup; - ret = qgroup_reserve(root, changeset.bytes_changed, true); + ret = qgroup_reserve(root, to_reserve, true); if (ret < 0) goto cleanup; - ulist_release(&changeset.range_changed); return ret; cleanup: - /* cleanup already reserved ranges */ + /* cleanup *ALL* already reserved ranges */ ULIST_ITER_INIT(&uiter); - while ((unode = ulist_next(&changeset.range_changed, &uiter))) + while ((unode = ulist_next(&reserved->range_changed, &uiter))) clear_extent_bit(&BTRFS_I(inode)->io_tree, unode->val, unode->aux, EXTENT_QGROUP_RESERVED, 0, 0, NULL, GFP_NOFS); - ulist_release(&changeset.range_changed); + extent_changeset_release(reserved); + return ret; +} + +/* Free ranges specified by @reserved, normally in error path */ +static int qgroup_free_reserved_data(struct inode *inode, + struct extent_changeset *reserved, u64 start, u64 len) +{ + struct btrfs_root *root = BTRFS_I(inode)->root; + struct ulist_node *unode; + struct ulist_iterator uiter; + struct extent_changeset changeset; + int freed = 0; + int ret; + + extent_changeset_init(&changeset); + len = round_up(start + len, root->fs_info->sectorsize); + start = round_down(start, root->fs_info->sectorsize); + + ULIST_ITER_INIT(&uiter); + while ((unode = ulist_next(&reserved->range_changed, &uiter))) { + u64 range_start = unode->val; + /* unode->aux is the inclusive end */ + u64 range_len = unode->aux - range_start + 1; + u64 free_start; + u64 free_len; + + extent_changeset_release(&changeset); + + /* Only free range in range [start, start + len) */ + if (range_start >= start + len || + range_start + range_len <= start) + continue; + free_start = max(range_start, start); + free_len = min(start + len, range_start + range_len) - + free_start; + /* + * TODO: To also modify reserved->ranges_reserved to reflect + * the modification. + * + * However as long as we free qgroup reserved according to + * EXTENT_QGROUP_RESERVED, we won't double free. + * So not need to rush. + */ + ret = clear_record_extent_bits(&BTRFS_I(inode)->io_failure_tree, + free_start, free_start + free_len - 1, + EXTENT_QGROUP_RESERVED, &changeset); + if (ret < 0) + goto out; + freed += changeset.bytes_changed; + } + btrfs_qgroup_free_refroot(root->fs_info, root->objectid, freed); + ret = freed; +out: + extent_changeset_release(&changeset); return ret; } -static int __btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len, - int free) +static int __btrfs_qgroup_release_data(struct inode *inode, + struct extent_changeset *reserved, u64 start, u64 len, + int free) { struct extent_changeset changeset; int trace_op = QGROUP_RELEASE; int ret; - changeset.bytes_changed = 0; - ulist_init(&changeset.range_changed); + /* In release case, we shouldn't have @reserved */ + WARN_ON(!free && reserved); + if (free && reserved) + return qgroup_free_reserved_data(inode, reserved, start, len); + extent_changeset_init(&changeset); ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len -1, EXTENT_QGROUP_RESERVED, &changeset); if (ret < 0) @@ -2868,8 +2969,9 @@ static int __btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len, btrfs_qgroup_free_refroot(BTRFS_I(inode)->root->fs_info, BTRFS_I(inode)->root->objectid, changeset.bytes_changed); + ret = changeset.bytes_changed; out: - ulist_release(&changeset.range_changed); + extent_changeset_release(&changeset); return ret; } @@ -2878,14 +2980,17 @@ out: * * Should be called when a range of pages get invalidated before reaching disk. * Or for error cleanup case. + * if @reserved is given, only reserved range in [@start, @start + @len) will + * be freed. * * For data written to disk, use btrfs_qgroup_release_data(). * * NOTE: This function may sleep for memory allocation. */ -int btrfs_qgroup_free_data(struct inode *inode, u64 start, u64 len) +int btrfs_qgroup_free_data(struct inode *inode, + struct extent_changeset *reserved, u64 start, u64 len) { - return __btrfs_qgroup_release_data(inode, start, len, 1); + return __btrfs_qgroup_release_data(inode, reserved, start, len, 1); } /* @@ -2905,7 +3010,7 @@ int btrfs_qgroup_free_data(struct inode *inode, u64 start, u64 len) */ int btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len) { - return __btrfs_qgroup_release_data(inode, start, len, 0); + return __btrfs_qgroup_release_data(inode, NULL, start, len, 0); } int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, @@ -2969,8 +3074,7 @@ void btrfs_qgroup_check_reserved_leak(struct inode *inode) struct ulist_iterator iter; int ret; - changeset.bytes_changed = 0; - ulist_init(&changeset.range_changed); + extent_changeset_init(&changeset); ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, 0, (u64)-1, EXTENT_QGROUP_RESERVED, &changeset); @@ -2987,5 +3091,5 @@ void btrfs_qgroup_check_reserved_leak(struct inode *inode) changeset.bytes_changed); } - ulist_release(&changeset.range_changed); + extent_changeset_release(&changeset); } diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h index fe04d3f295c6..102aa7fb342b 100644 --- a/fs/btrfs/qgroup.h +++ b/fs/btrfs/qgroup.h @@ -134,8 +134,6 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info); void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info); struct btrfs_delayed_extent_op; -int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info); /* * Inform qgroup to trace one dirty extent, its info is recorded in @record. * So qgroup can account it at transaction committing time. @@ -243,9 +241,11 @@ int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid, #endif /* New io_tree based accurate qgroup reserve API */ -int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len); +int btrfs_qgroup_reserve_data(struct inode *inode, + struct extent_changeset **reserved, u64 start, u64 len); int btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len); -int btrfs_qgroup_free_data(struct inode *inode, u64 start, u64 len); +int btrfs_qgroup_free_data(struct inode *inode, + struct extent_changeset *reserved, u64 start, u64 len); int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, bool enforce); diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index d8ea0eb76325..d68af3c61b49 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c @@ -31,7 +31,7 @@ #include <linux/hash.h> #include <linux/list_sort.h> #include <linux/raid/xor.h> -#include <linux/vmalloc.h> +#include <linux/mm.h> #include <asm/div64.h> #include "ctree.h" #include "extent_map.h" @@ -218,12 +218,9 @@ int btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info) * of a failing mount. */ table_size = sizeof(*table) + sizeof(*h) * num_entries; - table = kzalloc(table_size, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); - if (!table) { - table = vzalloc(table_size); - if (!table) - return -ENOMEM; - } + table = kvzalloc(table_size, GFP_KERNEL); + if (!table) + return -ENOMEM; spin_lock_init(&table->cache_lock); INIT_LIST_HEAD(&table->stripe_cache); diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c index a17e775a4a89..ab852b8e3e37 100644 --- a/fs/btrfs/reada.c +++ b/fs/btrfs/reada.c @@ -66,7 +66,6 @@ struct reada_extctl { struct reada_extent { u64 logical; struct btrfs_key top; - int err; struct list_head extctl; int refcnt; spinlock_t lock; diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index d60df51959f7..dc69b6ba29af 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3093,11 +3093,12 @@ int prealloc_file_extent_cluster(struct inode *inode, u64 prealloc_start = cluster->start - offset; u64 prealloc_end = cluster->end - offset; u64 cur_offset; + struct extent_changeset *data_reserved = NULL; BUG_ON(cluster->start != cluster->boundary[0]); inode_lock(inode); - ret = btrfs_check_data_free_space(inode, prealloc_start, + ret = btrfs_check_data_free_space(inode, &data_reserved, prealloc_start, prealloc_end + 1 - prealloc_start); if (ret) goto out; @@ -3113,8 +3114,8 @@ int prealloc_file_extent_cluster(struct inode *inode, lock_extent(&BTRFS_I(inode)->io_tree, start, end); num_bytes = end + 1 - start; if (cur_offset < start) - btrfs_free_reserved_data_space(inode, cur_offset, - start - cur_offset); + btrfs_free_reserved_data_space(inode, data_reserved, + cur_offset, start - cur_offset); ret = btrfs_prealloc_file_range(inode, 0, start, num_bytes, num_bytes, end + 1, &alloc_hint); @@ -3125,10 +3126,11 @@ int prealloc_file_extent_cluster(struct inode *inode, nr++; } if (cur_offset < prealloc_end) - btrfs_free_reserved_data_space(inode, cur_offset, - prealloc_end + 1 - cur_offset); + btrfs_free_reserved_data_space(inode, data_reserved, + cur_offset, prealloc_end + 1 - cur_offset); out: inode_unlock(inode); + extent_changeset_free(data_reserved); return ret; } @@ -4269,8 +4271,7 @@ static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info) INIT_LIST_HEAD(&rc->reloc_roots); backref_cache_init(&rc->backref_cache); mapping_tree_init(&rc->reloc_root_tree); - extent_io_tree_init(&rc->processed_blocks, - fs_info->btree_inode->i_mapping); + extent_io_tree_init(&rc->processed_blocks, NULL); return rc; } diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index c7b45eb2403d..096e503e3ddc 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -18,6 +18,7 @@ #include <linux/blkdev.h> #include <linux/ratelimit.h> +#include <linux/sched/mm.h> #include "ctree.h" #include "volumes.h" #include "disk-io.h" @@ -161,14 +162,6 @@ struct scrub_parity { unsigned long bitmap[0]; }; -struct scrub_wr_ctx { - struct scrub_bio *wr_curr_bio; - struct btrfs_device *tgtdev; - int pages_per_wr_bio; /* <= SCRUB_PAGES_PER_WR_BIO */ - atomic_t flush_all_writes; - struct mutex wr_lock; -}; - struct scrub_ctx { struct scrub_bio *bios[SCRUB_BIOS_PER_SCTX]; struct btrfs_fs_info *fs_info; @@ -183,11 +176,14 @@ struct scrub_ctx { atomic_t cancel_req; int readonly; int pages_per_rd_bio; - u32 sectorsize; - u32 nodesize; int is_dev_replace; - struct scrub_wr_ctx wr_ctx; + + struct scrub_bio *wr_curr_bio; + struct mutex wr_lock; + int pages_per_wr_bio; /* <= SCRUB_PAGES_PER_WR_BIO */ + atomic_t flush_all_writes; + struct btrfs_device *wr_tgtdev; /* * statistics @@ -289,10 +285,6 @@ static void scrub_remap_extent(struct btrfs_fs_info *fs_info, u64 *extent_physical, struct btrfs_device **extent_dev, int *extent_mirror_num); -static int scrub_setup_wr_ctx(struct scrub_wr_ctx *wr_ctx, - struct btrfs_device *dev, - int is_dev_replace); -static void scrub_free_wr_ctx(struct scrub_wr_ctx *wr_ctx); static int scrub_add_page_to_wr_bio(struct scrub_ctx *sctx, struct scrub_page *spage); static void scrub_wr_submit(struct scrub_ctx *sctx); @@ -643,8 +635,6 @@ static noinline_for_stack void scrub_free_ctx(struct scrub_ctx *sctx) if (!sctx) return; - scrub_free_wr_ctx(&sctx->wr_ctx); - /* this can happen when scrub is cancelled */ if (sctx->curr != -1) { struct scrub_bio *sbio = sctx->bios[sctx->curr]; @@ -664,6 +654,7 @@ static noinline_for_stack void scrub_free_ctx(struct scrub_ctx *sctx) kfree(sbio); } + kfree(sctx->wr_curr_bio); scrub_free_csums(sctx); kfree(sctx); } @@ -680,7 +671,6 @@ struct scrub_ctx *scrub_setup_ctx(struct btrfs_device *dev, int is_dev_replace) struct scrub_ctx *sctx; int i; struct btrfs_fs_info *fs_info = dev->fs_info; - int ret; sctx = kzalloc(sizeof(*sctx), GFP_KERNEL); if (!sctx) @@ -710,8 +700,6 @@ struct scrub_ctx *scrub_setup_ctx(struct btrfs_device *dev, int is_dev_replace) sctx->bios[i]->next_free = -1; } sctx->first_free = 0; - sctx->nodesize = fs_info->nodesize; - sctx->sectorsize = fs_info->sectorsize; atomic_set(&sctx->bios_in_flight, 0); atomic_set(&sctx->workers_pending, 0); atomic_set(&sctx->cancel_req, 0); @@ -722,12 +710,16 @@ struct scrub_ctx *scrub_setup_ctx(struct btrfs_device *dev, int is_dev_replace) spin_lock_init(&sctx->stat_lock); init_waitqueue_head(&sctx->list_wait); - ret = scrub_setup_wr_ctx(&sctx->wr_ctx, - fs_info->dev_replace.tgtdev, is_dev_replace); - if (ret) { - scrub_free_ctx(sctx); - return ERR_PTR(ret); + WARN_ON(sctx->wr_curr_bio != NULL); + mutex_init(&sctx->wr_lock); + sctx->wr_curr_bio = NULL; + if (is_dev_replace) { + WARN_ON(!dev->bdev); + sctx->pages_per_wr_bio = SCRUB_PAGES_PER_WR_BIO; + sctx->wr_tgtdev = dev; + atomic_set(&sctx->flush_all_writes, 0); } + return sctx; nomem: @@ -742,6 +734,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root, u32 nlink; int ret; int i; + unsigned nofs_flag; struct extent_buffer *eb; struct btrfs_inode_item *inode_item; struct scrub_warning *swarn = warn_ctx; @@ -780,7 +773,14 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root, nlink = btrfs_inode_nlink(eb, inode_item); btrfs_release_path(swarn->path); + /* + * init_path might indirectly call vmalloc, or use GFP_KERNEL. Scrub + * uses GFP_NOFS in this context, so we keep it consistent but it does + * not seem to be strictly necessary. + */ + nofs_flag = memalloc_nofs_save(); ipath = init_ipath(4096, local_root, swarn->path); + memalloc_nofs_restore(nofs_flag); if (IS_ERR(ipath)) { ret = PTR_ERR(ipath); ipath = NULL; @@ -954,7 +954,7 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx) ret = -EIO; goto out; } - ret = repair_io_failure(BTRFS_I(inode), offset, PAGE_SIZE, + ret = repair_io_failure(fs_info, inum, offset, PAGE_SIZE, fixup->logical, page, offset - page_offset(page), fixup->mirror_num); @@ -1898,35 +1898,34 @@ static int scrub_write_page_to_dev_replace(struct scrub_block *sblock, static int scrub_add_page_to_wr_bio(struct scrub_ctx *sctx, struct scrub_page *spage) { - struct scrub_wr_ctx *wr_ctx = &sctx->wr_ctx; struct scrub_bio *sbio; int ret; - mutex_lock(&wr_ctx->wr_lock); + mutex_lock(&sctx->wr_lock); again: - if (!wr_ctx->wr_curr_bio) { - wr_ctx->wr_curr_bio = kzalloc(sizeof(*wr_ctx->wr_curr_bio), + if (!sctx->wr_curr_bio) { + sctx->wr_curr_bio = kzalloc(sizeof(*sctx->wr_curr_bio), GFP_KERNEL); - if (!wr_ctx->wr_curr_bio) { - mutex_unlock(&wr_ctx->wr_lock); + if (!sctx->wr_curr_bio) { + mutex_unlock(&sctx->wr_lock); return -ENOMEM; } - wr_ctx->wr_curr_bio->sctx = sctx; - wr_ctx->wr_curr_bio->page_count = 0; + sctx->wr_curr_bio->sctx = sctx; + sctx->wr_curr_bio->page_count = 0; } - sbio = wr_ctx->wr_curr_bio; + sbio = sctx->wr_curr_bio; if (sbio->page_count == 0) { struct bio *bio; sbio->physical = spage->physical_for_dev_replace; sbio->logical = spage->logical; - sbio->dev = wr_ctx->tgtdev; + sbio->dev = sctx->wr_tgtdev; bio = sbio->bio; if (!bio) { bio = btrfs_io_bio_alloc(GFP_KERNEL, - wr_ctx->pages_per_wr_bio); + sctx->pages_per_wr_bio); if (!bio) { - mutex_unlock(&wr_ctx->wr_lock); + mutex_unlock(&sctx->wr_lock); return -ENOMEM; } sbio->bio = bio; @@ -1951,7 +1950,7 @@ again: if (sbio->page_count < 1) { bio_put(sbio->bio); sbio->bio = NULL; - mutex_unlock(&wr_ctx->wr_lock); + mutex_unlock(&sctx->wr_lock); return -EIO; } scrub_wr_submit(sctx); @@ -1961,23 +1960,22 @@ again: sbio->pagev[sbio->page_count] = spage; scrub_page_get(spage); sbio->page_count++; - if (sbio->page_count == wr_ctx->pages_per_wr_bio) + if (sbio->page_count == sctx->pages_per_wr_bio) scrub_wr_submit(sctx); - mutex_unlock(&wr_ctx->wr_lock); + mutex_unlock(&sctx->wr_lock); return 0; } static void scrub_wr_submit(struct scrub_ctx *sctx) { - struct scrub_wr_ctx *wr_ctx = &sctx->wr_ctx; struct scrub_bio *sbio; - if (!wr_ctx->wr_curr_bio) + if (!sctx->wr_curr_bio) return; - sbio = wr_ctx->wr_curr_bio; - wr_ctx->wr_curr_bio = NULL; + sbio = sctx->wr_curr_bio; + sctx->wr_curr_bio = NULL; WARN_ON(!sbio->bio->bi_bdev); scrub_pending_bio_inc(sctx); /* process all writes in a single worker thread. Then the block layer @@ -2081,7 +2079,7 @@ static int scrub_checksum_data(struct scrub_block *sblock) page = sblock->pagev[0]->page; buffer = kmap_atomic(page); - len = sctx->sectorsize; + len = sctx->fs_info->sectorsize; index = 0; for (;;) { u64 l = min_t(u64, len, PAGE_SIZE); @@ -2146,7 +2144,7 @@ static int scrub_checksum_tree_block(struct scrub_block *sblock) BTRFS_UUID_SIZE)) sblock->header_error = 1; - len = sctx->nodesize - BTRFS_CSUM_SIZE; + len = sctx->fs_info->nodesize - BTRFS_CSUM_SIZE; mapped_size = PAGE_SIZE - BTRFS_CSUM_SIZE; p = ((u8 *)mapped_buffer) + BTRFS_CSUM_SIZE; index = 0; @@ -2420,10 +2418,10 @@ static void scrub_missing_raid56_worker(struct btrfs_work *work) scrub_block_put(sblock); if (sctx->is_dev_replace && - atomic_read(&sctx->wr_ctx.flush_all_writes)) { - mutex_lock(&sctx->wr_ctx.wr_lock); + atomic_read(&sctx->flush_all_writes)) { + mutex_lock(&sctx->wr_lock); scrub_wr_submit(sctx); - mutex_unlock(&sctx->wr_ctx.wr_lock); + mutex_unlock(&sctx->wr_lock); } scrub_pending_bio_dec(sctx); @@ -2628,10 +2626,10 @@ static void scrub_bio_end_io_worker(struct btrfs_work *work) spin_unlock(&sctx->list_lock); if (sctx->is_dev_replace && - atomic_read(&sctx->wr_ctx.flush_all_writes)) { - mutex_lock(&sctx->wr_ctx.wr_lock); + atomic_read(&sctx->flush_all_writes)) { + mutex_lock(&sctx->wr_lock); scrub_wr_submit(sctx); - mutex_unlock(&sctx->wr_ctx.wr_lock); + mutex_unlock(&sctx->wr_lock); } scrub_pending_bio_dec(sctx); @@ -2726,8 +2724,8 @@ static int scrub_find_csum(struct scrub_ctx *sctx, u64 logical, u8 *csum) if (!sum) return 0; - index = ((u32)(logical - sum->bytenr)) / sctx->sectorsize; - num_sectors = sum->len / sctx->sectorsize; + index = ((u32)(logical - sum->bytenr)) / sctx->fs_info->sectorsize; + num_sectors = sum->len / sctx->fs_info->sectorsize; memcpy(csum, sum->sums + index, sctx->csum_size); if (index == num_sectors - 1) { list_del(&sum->list); @@ -2746,19 +2744,19 @@ static int scrub_extent(struct scrub_ctx *sctx, u64 logical, u64 len, u32 blocksize; if (flags & BTRFS_EXTENT_FLAG_DATA) { - blocksize = sctx->sectorsize; + blocksize = sctx->fs_info->sectorsize; spin_lock(&sctx->stat_lock); sctx->stat.data_extents_scrubbed++; sctx->stat.data_bytes_scrubbed += len; spin_unlock(&sctx->stat_lock); } else if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { - blocksize = sctx->nodesize; + blocksize = sctx->fs_info->nodesize; spin_lock(&sctx->stat_lock); sctx->stat.tree_extents_scrubbed++; sctx->stat.tree_bytes_scrubbed += len; spin_unlock(&sctx->stat_lock); } else { - blocksize = sctx->sectorsize; + blocksize = sctx->fs_info->sectorsize; WARN_ON(1); } @@ -2892,11 +2890,11 @@ static int scrub_extent_for_parity(struct scrub_parity *sparity, } if (flags & BTRFS_EXTENT_FLAG_DATA) { - blocksize = sctx->sectorsize; + blocksize = sctx->fs_info->sectorsize; } else if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { - blocksize = sctx->nodesize; + blocksize = sctx->fs_info->nodesize; } else { - blocksize = sctx->sectorsize; + blocksize = sctx->fs_info->sectorsize; WARN_ON(1); } @@ -3305,9 +3303,9 @@ out: logic_end - logic_start); scrub_parity_put(sparity); scrub_submit(sctx); - mutex_lock(&sctx->wr_ctx.wr_lock); + mutex_lock(&sctx->wr_lock); scrub_wr_submit(sctx); - mutex_unlock(&sctx->wr_ctx.wr_lock); + mutex_unlock(&sctx->wr_lock); btrfs_release_path(path); return ret < 0 ? ret : 0; @@ -3463,14 +3461,14 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, */ if (atomic_read(&fs_info->scrub_pause_req)) { /* push queued extents */ - atomic_set(&sctx->wr_ctx.flush_all_writes, 1); + atomic_set(&sctx->flush_all_writes, 1); scrub_submit(sctx); - mutex_lock(&sctx->wr_ctx.wr_lock); + mutex_lock(&sctx->wr_lock); scrub_wr_submit(sctx); - mutex_unlock(&sctx->wr_ctx.wr_lock); + mutex_unlock(&sctx->wr_lock); wait_event(sctx->list_wait, atomic_read(&sctx->bios_in_flight) == 0); - atomic_set(&sctx->wr_ctx.flush_all_writes, 0); + atomic_set(&sctx->flush_all_writes, 0); scrub_blocked_if_needed(fs_info); } @@ -3677,9 +3675,9 @@ skip: out: /* push queued extents */ scrub_submit(sctx); - mutex_lock(&sctx->wr_ctx.wr_lock); + mutex_lock(&sctx->wr_lock); scrub_wr_submit(sctx); - mutex_unlock(&sctx->wr_ctx.wr_lock); + mutex_unlock(&sctx->wr_lock); blk_finish_plug(&plug); btrfs_free_path(path); @@ -3916,11 +3914,11 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, * write requests are really completed when bios_in_flight * changes to 0. */ - atomic_set(&sctx->wr_ctx.flush_all_writes, 1); + atomic_set(&sctx->flush_all_writes, 1); scrub_submit(sctx); - mutex_lock(&sctx->wr_ctx.wr_lock); + mutex_lock(&sctx->wr_lock); scrub_wr_submit(sctx); - mutex_unlock(&sctx->wr_ctx.wr_lock); + mutex_unlock(&sctx->wr_lock); wait_event(sctx->list_wait, atomic_read(&sctx->bios_in_flight) == 0); @@ -3934,7 +3932,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, */ wait_event(sctx->list_wait, atomic_read(&sctx->workers_pending) == 0); - atomic_set(&sctx->wr_ctx.flush_all_writes, 0); + atomic_set(&sctx->flush_all_writes, 0); scrub_pause_off(fs_info); @@ -4337,32 +4335,6 @@ static void scrub_remap_extent(struct btrfs_fs_info *fs_info, btrfs_put_bbio(bbio); } -static int scrub_setup_wr_ctx(struct scrub_wr_ctx *wr_ctx, - struct btrfs_device *dev, - int is_dev_replace) -{ - WARN_ON(wr_ctx->wr_curr_bio != NULL); - - mutex_init(&wr_ctx->wr_lock); - wr_ctx->wr_curr_bio = NULL; - if (!is_dev_replace) - return 0; - - WARN_ON(!dev->bdev); - wr_ctx->pages_per_wr_bio = SCRUB_PAGES_PER_WR_BIO; - wr_ctx->tgtdev = dev; - atomic_set(&wr_ctx->flush_all_writes, 0); - return 0; -} - -static void scrub_free_wr_ctx(struct scrub_wr_ctx *wr_ctx) -{ - mutex_lock(&wr_ctx->wr_lock); - kfree(wr_ctx->wr_curr_bio); - wr_ctx->wr_curr_bio = NULL; - mutex_unlock(&wr_ctx->wr_lock); -} - static int copy_nocow_pages(struct scrub_ctx *sctx, u64 logical, u64 len, int mirror_num, u64 physical_for_dev_replace) { @@ -4665,7 +4637,7 @@ static int write_page_nocow(struct scrub_ctx *sctx, struct btrfs_device *dev; int ret; - dev = sctx->wr_ctx.tgtdev; + dev = sctx->wr_tgtdev; if (!dev) return -EIO; if (!dev->bdev) { diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index fc496a6f842a..7416b17c0eac 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -1083,7 +1083,7 @@ static int iterate_dir_item(struct btrfs_root *root, struct btrfs_path *path, buf = tmp; } if (!buf) { - buf = vmalloc(buf_len); + buf = kvmalloc(buf_len, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto out; @@ -2769,12 +2769,10 @@ out: struct recorded_ref { struct list_head list; - char *dir_path; char *name; struct fs_path *full_path; u64 dir; u64 dir_gen; - int dir_path_len; int name_len; }; @@ -2798,12 +2796,6 @@ static int __record_ref(struct list_head *head, u64 dir, ref->name = (char *)kbasename(ref->full_path->start); ref->name_len = ref->full_path->end - ref->name; - ref->dir_path = ref->full_path->start; - if (ref->name == ref->full_path->start) - ref->dir_path_len = 0; - else - ref->dir_path_len = ref->full_path->end - - ref->full_path->start - 1 - ref->name_len; list_add_tail(&ref->list, head); return 0; @@ -6397,13 +6389,10 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) alloc_size = sizeof(struct clone_root) * (arg->clone_sources_count + 1); - sctx->clone_roots = kzalloc(alloc_size, GFP_KERNEL | __GFP_NOWARN); + sctx->clone_roots = kzalloc(alloc_size, GFP_KERNEL); if (!sctx->clone_roots) { - sctx->clone_roots = vzalloc(alloc_size); - if (!sctx->clone_roots) { - ret = -ENOMEM; - goto out; - } + ret = -ENOMEM; + goto out; } alloc_size = arg->clone_sources_count * sizeof(*arg->clone_sources); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 4f1cdd5058f1..3371213924bd 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1898,7 +1898,6 @@ static inline void btrfs_descending_sort_devices( static int btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info, u64 *free_bytes) { - struct btrfs_root *root = fs_info->tree_root; struct btrfs_device_info *devices_info; struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; struct btrfs_device *device; @@ -1932,7 +1931,7 @@ static int btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info, return -ENOMEM; /* calc min stripe number for data space allocation */ - type = btrfs_get_alloc_profile(root, 1); + type = btrfs_data_alloc_profile(fs_info); if (type & BTRFS_BLOCK_GROUP_RAID0) { min_stripes = 2; num_stripes = nr_devices; diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 1f157fba8940..c2d5f3580b4c 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -447,11 +447,52 @@ static ssize_t btrfs_clone_alignment_show(struct kobject *kobj, BTRFS_ATTR(clone_alignment, btrfs_clone_alignment_show); +static ssize_t quota_override_show(struct kobject *kobj, + struct kobj_attribute *a, char *buf) +{ + struct btrfs_fs_info *fs_info = to_fs_info(kobj); + int quota_override; + + quota_override = test_bit(BTRFS_FS_QUOTA_OVERRIDE, &fs_info->flags); + return snprintf(buf, PAGE_SIZE, "%d\n", quota_override); +} + +static ssize_t quota_override_store(struct kobject *kobj, + struct kobj_attribute *a, + const char *buf, size_t len) +{ + struct btrfs_fs_info *fs_info = to_fs_info(kobj); + unsigned long knob; + int err; + + if (!fs_info) + return -EPERM; + + if (!capable(CAP_SYS_RESOURCE)) + return -EPERM; + + err = kstrtoul(buf, 10, &knob); + if (err) + return err; + if (knob > 1) + return -EINVAL; + + if (knob) + set_bit(BTRFS_FS_QUOTA_OVERRIDE, &fs_info->flags); + else + clear_bit(BTRFS_FS_QUOTA_OVERRIDE, &fs_info->flags); + + return len; +} + +BTRFS_ATTR_RW(quota_override, quota_override_show, quota_override_store); + static const struct attribute *btrfs_attrs[] = { BTRFS_ATTR_PTR(label), BTRFS_ATTR_PTR(nodesize), BTRFS_ATTR_PTR(sectorsize), BTRFS_ATTR_PTR(clone_alignment), + BTRFS_ATTR_PTR(quota_override), NULL, }; diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c index 133753232a94..d06b1c931d05 100644 --- a/fs/btrfs/tests/extent-io-tests.c +++ b/fs/btrfs/tests/extent-io-tests.c @@ -87,7 +87,7 @@ static int test_find_delalloc(u32 sectorsize) return -ENOMEM; } - extent_io_tree_init(&tmp, &inode->i_data); + extent_io_tree_init(&tmp, inode); /* * First go through and create and mark all of our pages dirty, we pin diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 2168654c90a1..e5177a212d7c 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -93,7 +93,7 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction) btrfs_put_block_group_trimming(cache); btrfs_put_block_group(cache); } - kmem_cache_free(btrfs_transaction_cachep, transaction); + kfree(transaction); } } @@ -228,7 +228,7 @@ loop: */ BUG_ON(type == TRANS_JOIN_NOLOCK); - cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS); + cur_trans = kmalloc(sizeof(*cur_trans), GFP_NOFS); if (!cur_trans) return -ENOMEM; @@ -238,11 +238,11 @@ loop: * someone started a transaction after we unlocked. Make sure * to redo the checks above */ - kmem_cache_free(btrfs_transaction_cachep, cur_trans); + kfree(cur_trans); goto loop; } else if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { spin_unlock(&fs_info->trans_lock); - kmem_cache_free(btrfs_transaction_cachep, cur_trans); + kfree(cur_trans); return -EROFS; } @@ -294,7 +294,7 @@ loop: spin_lock_init(&cur_trans->dropped_roots_lock); list_add_tail(&cur_trans->list, &fs_info->trans_list); extent_io_tree_init(&cur_trans->dirty_pages, - fs_info->btree_inode->i_mapping); + fs_info->btree_inode); fs_info->generation++; cur_trans->transid = fs_info->generation; fs_info->running_transaction = cur_trans; @@ -1374,9 +1374,6 @@ static int qgroup_account_snapshot(struct btrfs_trans_handle *trans, ret = commit_fs_roots(trans, fs_info); if (ret) goto out; - ret = btrfs_qgroup_prepare_account_extents(trans, fs_info); - if (ret < 0) - goto out; ret = btrfs_qgroup_account_extents(trans, fs_info); if (ret < 0) goto out; @@ -2180,13 +2177,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) goto scrub_continue; } - ret = btrfs_qgroup_prepare_account_extents(trans, fs_info); - if (ret) { - mutex_unlock(&fs_info->tree_log_mutex); - mutex_unlock(&fs_info->reloc_mutex); - goto scrub_continue; - } - /* * Since fs roots are all committed, we can get a quite accurate * new_roots. So let's do quota accounting. diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 017b67daa3bb..e28c113785bb 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2417,9 +2417,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path fs_info->fs_devices->total_devices++; fs_info->fs_devices->total_rw_bytes += device->total_bytes; - spin_lock(&fs_info->free_chunk_lock); - fs_info->free_chunk_space += device->total_bytes; - spin_unlock(&fs_info->free_chunk_lock); + atomic64_add(device->total_bytes, &fs_info->free_chunk_space); if (!blk_queue_nonrot(q)) fs_info->fs_devices->rotating = 1; @@ -2874,9 +2872,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, mutex_lock(&fs_info->chunk_mutex); btrfs_device_set_bytes_used(device, device->bytes_used - dev_extent_len); - spin_lock(&fs_info->free_chunk_lock); - fs_info->free_chunk_space += dev_extent_len; - spin_unlock(&fs_info->free_chunk_lock); + atomic64_add(dev_extent_len, &fs_info->free_chunk_space); btrfs_clear_space_info_full(fs_info); mutex_unlock(&fs_info->chunk_mutex); } @@ -4409,9 +4405,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) btrfs_device_set_total_bytes(device, new_size); if (device->writeable) { device->fs_devices->total_rw_bytes -= diff; - spin_lock(&fs_info->free_chunk_lock); - fs_info->free_chunk_space -= diff; - spin_unlock(&fs_info->free_chunk_lock); + atomic64_sub(diff, &fs_info->free_chunk_space); } mutex_unlock(&fs_info->chunk_mutex); @@ -4535,9 +4529,7 @@ done: btrfs_device_set_total_bytes(device, old_size); if (device->writeable) device->fs_devices->total_rw_bytes += diff; - spin_lock(&fs_info->free_chunk_lock); - fs_info->free_chunk_space += diff; - spin_unlock(&fs_info->free_chunk_lock); + atomic64_add(diff, &fs_info->free_chunk_space); mutex_unlock(&fs_info->chunk_mutex); } return ret; @@ -4882,9 +4874,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, btrfs_device_set_bytes_used(map->stripes[i].dev, num_bytes); } - spin_lock(&info->free_chunk_lock); - info->free_chunk_space -= (stripe_size * map->num_stripes); - spin_unlock(&info->free_chunk_lock); + atomic64_sub(stripe_size * map->num_stripes, &info->free_chunk_space); free_extent_map(em); check_raid56_incompat_flag(info, type); @@ -5029,20 +5019,19 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, static noinline int init_first_rw_device(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info) { - struct btrfs_root *extent_root = fs_info->extent_root; u64 chunk_offset; u64 sys_chunk_offset; u64 alloc_profile; int ret; chunk_offset = find_next_chunk(fs_info); - alloc_profile = btrfs_get_alloc_profile(extent_root, 0); + alloc_profile = btrfs_metadata_alloc_profile(fs_info); ret = __btrfs_alloc_chunk(trans, chunk_offset, alloc_profile); if (ret) return ret; sys_chunk_offset = find_next_chunk(fs_info); - alloc_profile = btrfs_get_alloc_profile(fs_info->chunk_root, 0); + alloc_profile = btrfs_system_alloc_profile(fs_info); ret = __btrfs_alloc_chunk(trans, sys_chunk_offset, alloc_profile); return ret; } @@ -6684,10 +6673,8 @@ static int read_one_dev(struct btrfs_fs_info *fs_info, device->in_fs_metadata = 1; if (device->writeable && !device->is_tgtdev_for_dev_replace) { device->fs_devices->total_rw_bytes += device->total_bytes; - spin_lock(&fs_info->free_chunk_lock); - fs_info->free_chunk_space += device->total_bytes - - device->bytes_used; - spin_unlock(&fs_info->free_chunk_lock); + atomic64_add(device->total_bytes - device->bytes_used, + &fs_info->free_chunk_space); } ret = 0; return ret; diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index c7d0fbc915ca..58b97b6f5f02 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -74,6 +74,7 @@ struct btrfs_device { int missing; int can_discard; int is_tgtdev_for_dev_replace; + int last_flush_error; #ifdef __BTRFS_NEED_DEVICE_DATA_ORDERED seqcount_t data_seqcount; @@ -279,6 +280,7 @@ struct btrfs_io_bio { u8 csum_inline[BTRFS_BIO_INLINE_CSUM_SIZE]; u8 *csum_allocated; btrfs_io_bio_end_io_t *end_io; + struct bvec_iter iter; struct bio bio; }; diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 135b10823c6d..c248f9286366 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -24,12 +24,13 @@ #include <linux/slab.h> #include <linux/zlib.h> #include <linux/zutil.h> -#include <linux/vmalloc.h> +#include <linux/mm.h> #include <linux/init.h> #include <linux/err.h> #include <linux/sched.h> #include <linux/pagemap.h> #include <linux/bio.h> +#include <linux/refcount.h> #include "compression.h" struct workspace { @@ -42,7 +43,7 @@ static void zlib_free_workspace(struct list_head *ws) { struct workspace *workspace = list_entry(ws, struct workspace, list); - vfree(workspace->strm.workspace); + kvfree(workspace->strm.workspace); kfree(workspace->buf); kfree(workspace); } @@ -52,14 +53,14 @@ static struct list_head *zlib_alloc_workspace(void) struct workspace *workspace; int workspacesize; - workspace = kzalloc(sizeof(*workspace), GFP_NOFS); + workspace = kzalloc(sizeof(*workspace), GFP_KERNEL); if (!workspace) return ERR_PTR(-ENOMEM); workspacesize = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL), zlib_inflate_workspacesize()); - workspace->strm.workspace = vmalloc(workspacesize); - workspace->buf = kmalloc(PAGE_SIZE, GFP_NOFS); + workspace->strm.workspace = kvmalloc(workspacesize, GFP_KERNEL); + workspace->buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!workspace->strm.workspace || !workspace->buf) goto fail; @@ -211,10 +212,7 @@ out: return ret; } -static int zlib_decompress_bio(struct list_head *ws, struct page **pages_in, - u64 disk_start, - struct bio *orig_bio, - size_t srclen) +static int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb) { struct workspace *workspace = list_entry(ws, struct workspace, list); int ret = 0, ret2; @@ -222,8 +220,12 @@ static int zlib_decompress_bio(struct list_head *ws, struct page **pages_in, char *data_in; size_t total_out = 0; unsigned long page_in_index = 0; + size_t srclen = cb->compressed_len; unsigned long total_pages_in = DIV_ROUND_UP(srclen, PAGE_SIZE); unsigned long buf_start; + struct page **pages_in = cb->compressed_pages; + u64 disk_start = cb->start; + struct bio *orig_bio = cb->orig_bio; data_in = kmap(pages_in[page_in_index]); workspace->strm.next_in = data_in; diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index e5e29f8c920b..7acd57da4f14 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -42,21 +42,6 @@ #define ENCRYPT 1 /** - * ecryptfs_to_hex - * @dst: Buffer to take hex character representation of contents of - * src; must be at least of size (src_size * 2) - * @src: Buffer to be converted to a hex string representation - * @src_size: number of bytes to convert - */ -void ecryptfs_to_hex(char *dst, char *src, size_t src_size) -{ - int x; - - for (x = 0; x < src_size; x++) - sprintf(&dst[x * 2], "%.2x", (unsigned char)src[x]); -} - -/** * ecryptfs_from_hex * @dst: Buffer to take the bytes from src hex; must be at least of * size (src_size / 2) diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 9c351bf757b2..c1b27ae613aa 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -31,6 +31,7 @@ #include <crypto/skcipher.h> #include <keys/user-type.h> #include <keys/encrypted-type.h> +#include <linux/kernel.h> #include <linux/fs.h> #include <linux/fs_stack.h> #include <linux/namei.h> @@ -51,7 +52,13 @@ #define ECRYPTFS_XATTR_NAME "user.ecryptfs" void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok); -extern void ecryptfs_to_hex(char *dst, char *src, size_t src_size); +static inline void +ecryptfs_to_hex(char *dst, char *src, size_t src_size) +{ + char *end = bin2hex(dst, src, src_size); + *end = '\0'; +} + extern void ecryptfs_from_hex(char *dst, char *src, int dst_size); struct ecryptfs_key_record { diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 3cf1546dca82..11d39ab7774e 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -1326,7 +1326,7 @@ parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat, if ((*new_auth_tok)->session_key.encrypted_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { printk(KERN_WARNING "Tag 1 packet contains key larger " - "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES"); + "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES\n"); rc = -EINVAL; goto out; } diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 9014479d0160..21a909d51ab9 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -426,7 +426,7 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, mount_crypt_stat->global_default_cipher_key_size); if (!cipher_code) { ecryptfs_printk(KERN_ERR, - "eCryptfs doesn't support cipher: %s", + "eCryptfs doesn't support cipher: %s\n", mount_crypt_stat->global_default_cipher_name); rc = -EINVAL; goto out; diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index e4141f257495..595e684a95a5 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c @@ -383,7 +383,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, goto memdup; } else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) { printk(KERN_WARNING "%s: Acceptable packet size range is " - "[%d-%zu], but amount of data written is [%zu].", + "[%d-%zu], but amount of data written is [%zu].\n", __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count); return -EINVAL; } diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index fd389935ecd1..3ec0e46de95f 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -4,6 +4,7 @@ * Copyright (C) 2001-2003 Andreas Gruenbacher, <agruen@suse.de> */ +#include <linux/quotaops.h> #include "ext4_jbd2.h" #include "ext4.h" #include "xattr.h" @@ -232,6 +233,9 @@ ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type) handle_t *handle; int error, retries = 0; + error = dquot_initialize(inode); + if (error) + return error; retry: handle = ext4_journal_start(inode, EXT4_HT_XATTR, ext4_jbd2_credits_xattr(inode)); diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 8e8046104f4d..32191548abed 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2523,7 +2523,6 @@ extern int ext4_search_dir(struct buffer_head *bh, int buf_size, struct inode *dir, struct ext4_filename *fname, - const struct qstr *d_name, unsigned int offset, struct ext4_dir_entry_2 **res_dir); extern int ext4_generic_delete_entry(handle_t *handle, @@ -3007,7 +3006,6 @@ extern int htree_inlinedir_to_tree(struct file *dir_file, int *has_inline_data); extern struct buffer_head *ext4_find_inline_entry(struct inode *dir, struct ext4_filename *fname, - const struct qstr *d_name, struct ext4_dir_entry_2 **res_dir, int *has_inline_data); extern int ext4_delete_inline_entry(handle_t *handle, diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 2a97dff87b96..3e36508610b7 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3413,13 +3413,13 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, struct ext4_sb_info *sbi; struct ext4_extent_header *eh; struct ext4_map_blocks split_map; - struct ext4_extent zero_ex; + struct ext4_extent zero_ex1, zero_ex2; struct ext4_extent *ex, *abut_ex; ext4_lblk_t ee_block, eof_block; unsigned int ee_len, depth, map_len = map->m_len; int allocated = 0, max_zeroout = 0; int err = 0; - int split_flag = 0; + int split_flag = EXT4_EXT_DATA_VALID2; ext_debug("ext4_ext_convert_to_initialized: inode %lu, logical" "block %llu, max_blocks %u\n", inode->i_ino, @@ -3436,7 +3436,8 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, ex = path[depth].p_ext; ee_block = le32_to_cpu(ex->ee_block); ee_len = ext4_ext_get_actual_len(ex); - zero_ex.ee_len = 0; + zero_ex1.ee_len = 0; + zero_ex2.ee_len = 0; trace_ext4_ext_convert_to_initialized_enter(inode, map, ex); @@ -3576,62 +3577,52 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, if (ext4_encrypted_inode(inode)) max_zeroout = 0; - /* If extent is less than s_max_zeroout_kb, zeroout directly */ - if (max_zeroout && (ee_len <= max_zeroout)) { - err = ext4_ext_zeroout(inode, ex); - if (err) - goto out; - zero_ex.ee_block = ex->ee_block; - zero_ex.ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)); - ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex)); - - err = ext4_ext_get_access(handle, inode, path + depth); - if (err) - goto out; - ext4_ext_mark_initialized(ex); - ext4_ext_try_to_merge(handle, inode, path, ex); - err = ext4_ext_dirty(handle, inode, path + path->p_depth); - goto out; - } - /* - * four cases: + * five cases: * 1. split the extent into three extents. - * 2. split the extent into two extents, zeroout the first half. - * 3. split the extent into two extents, zeroout the second half. + * 2. split the extent into two extents, zeroout the head of the first + * extent. + * 3. split the extent into two extents, zeroout the tail of the second + * extent. * 4. split the extent into two extents with out zeroout. + * 5. no splitting needed, just possibly zeroout the head and / or the + * tail of the extent. */ split_map.m_lblk = map->m_lblk; split_map.m_len = map->m_len; - if (max_zeroout && (allocated > map->m_len)) { + if (max_zeroout && (allocated > split_map.m_len)) { if (allocated <= max_zeroout) { - /* case 3 */ - zero_ex.ee_block = - cpu_to_le32(map->m_lblk); - zero_ex.ee_len = cpu_to_le16(allocated); - ext4_ext_store_pblock(&zero_ex, - ext4_ext_pblock(ex) + map->m_lblk - ee_block); - err = ext4_ext_zeroout(inode, &zero_ex); + /* case 3 or 5 */ + zero_ex1.ee_block = + cpu_to_le32(split_map.m_lblk + + split_map.m_len); + zero_ex1.ee_len = + cpu_to_le16(allocated - split_map.m_len); + ext4_ext_store_pblock(&zero_ex1, + ext4_ext_pblock(ex) + split_map.m_lblk + + split_map.m_len - ee_block); + err = ext4_ext_zeroout(inode, &zero_ex1); if (err) goto out; - split_map.m_lblk = map->m_lblk; split_map.m_len = allocated; - } else if (map->m_lblk - ee_block + map->m_len < max_zeroout) { - /* case 2 */ - if (map->m_lblk != ee_block) { - zero_ex.ee_block = ex->ee_block; - zero_ex.ee_len = cpu_to_le16(map->m_lblk - + } + if (split_map.m_lblk - ee_block + split_map.m_len < + max_zeroout) { + /* case 2 or 5 */ + if (split_map.m_lblk != ee_block) { + zero_ex2.ee_block = ex->ee_block; + zero_ex2.ee_len = cpu_to_le16(split_map.m_lblk - ee_block); - ext4_ext_store_pblock(&zero_ex, + ext4_ext_store_pblock(&zero_ex2, ext4_ext_pblock(ex)); - err = ext4_ext_zeroout(inode, &zero_ex); + err = ext4_ext_zeroout(inode, &zero_ex2); if (err) goto out; } + split_map.m_len += split_map.m_lblk - ee_block; split_map.m_lblk = ee_block; - split_map.m_len = map->m_lblk - ee_block + map->m_len; allocated = map->m_len; } } @@ -3642,8 +3633,11 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, err = 0; out: /* If we have gotten a failure, don't zero out status tree */ - if (!err) - err = ext4_zeroout_es(inode, &zero_ex); + if (!err) { + err = ext4_zeroout_es(inode, &zero_ex1); + if (!err) + err = ext4_zeroout_es(inode, &zero_ex2); + } return err ? err : allocated; } @@ -4883,6 +4877,8 @@ static long ext4_zero_range(struct file *file, loff_t offset, /* Zero out partial block at the edges of the range */ ret = ext4_zero_partial_blocks(handle, inode, offset, len); + if (ret >= 0) + ext4_update_inode_fsync_trans(handle, inode, 1); if (file->f_flags & O_SYNC) ext4_handle_sync(handle); @@ -5569,6 +5565,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) ext4_handle_sync(handle); inode->i_mtime = inode->i_ctime = current_time(inode); ext4_mark_inode_dirty(handle, inode); + ext4_update_inode_fsync_trans(handle, inode, 1); out_stop: ext4_journal_stop(handle); @@ -5742,6 +5739,8 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) up_write(&EXT4_I(inode)->i_data_sem); if (IS_SYNC(inode)) ext4_handle_sync(handle); + if (ret >= 0) + ext4_update_inode_fsync_trans(handle, inode, 1); out_stop: ext4_journal_stop(handle); diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 831fd6beebf0..02ce7e7bbdf5 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -474,57 +474,37 @@ static int ext4_find_unwritten_pgoff(struct inode *inode, endoff = (loff_t)end_blk << blkbits; index = startoff >> PAGE_SHIFT; - end = endoff >> PAGE_SHIFT; + end = (endoff - 1) >> PAGE_SHIFT; pagevec_init(&pvec, 0); do { int i, num; unsigned long nr_pages; - num = min_t(pgoff_t, end - index, PAGEVEC_SIZE); + num = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1; nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index, (pgoff_t)num); - if (nr_pages == 0) { - if (whence == SEEK_DATA) - break; - - BUG_ON(whence != SEEK_HOLE); - /* - * If this is the first time to go into the loop and - * offset is not beyond the end offset, it will be a - * hole at this offset - */ - if (lastoff == startoff || lastoff < endoff) - found = 1; - break; - } - - /* - * If this is the first time to go into the loop and - * offset is smaller than the first page offset, it will be a - * hole at this offset. - */ - if (lastoff == startoff && whence == SEEK_HOLE && - lastoff < page_offset(pvec.pages[0])) { - found = 1; + if (nr_pages == 0) break; - } for (i = 0; i < nr_pages; i++) { struct page *page = pvec.pages[i]; struct buffer_head *bh, *head; /* - * If the current offset is not beyond the end of given - * range, it will be a hole. + * If current offset is smaller than the page offset, + * there is a hole at this offset. */ - if (lastoff < endoff && whence == SEEK_HOLE && - page->index > end) { + if (whence == SEEK_HOLE && lastoff < endoff && + lastoff < page_offset(pvec.pages[i])) { found = 1; *offset = lastoff; goto out; } + if (page->index > end) + goto out; + lock_page(page); if (unlikely(page->mapping != inode->i_mapping)) { @@ -564,20 +544,18 @@ static int ext4_find_unwritten_pgoff(struct inode *inode, unlock_page(page); } - /* - * The no. of pages is less than our desired, that would be a - * hole in there. - */ - if (nr_pages < num && whence == SEEK_HOLE) { - found = 1; - *offset = lastoff; + /* The no. of pages is less than our desired, we are done. */ + if (nr_pages < num) break; - } index = pvec.pages[i - 1]->index + 1; pagevec_release(&pvec); } while (index <= end); + if (whence == SEEK_HOLE && lastoff < endoff) { + found = 1; + *offset = lastoff; + } out: pagevec_release(&pvec); return found; diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index d5dea4c293ef..8d141c0c8ff9 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -1627,7 +1627,6 @@ out: struct buffer_head *ext4_find_inline_entry(struct inode *dir, struct ext4_filename *fname, - const struct qstr *d_name, struct ext4_dir_entry_2 **res_dir, int *has_inline_data) { @@ -1649,7 +1648,7 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir, EXT4_INLINE_DOTDOT_SIZE; inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE; ret = ext4_search_dir(iloc.bh, inline_start, inline_size, - dir, fname, d_name, 0, res_dir); + dir, fname, 0, res_dir); if (ret == 1) goto out_find; if (ret < 0) @@ -1662,7 +1661,7 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir, inline_size = ext4_get_inline_size(dir) - EXT4_MIN_INLINE_DATA_SIZE; ret = ext4_search_dir(iloc.bh, inline_start, inline_size, - dir, fname, d_name, 0, res_dir); + dir, fname, 0, res_dir); if (ret == 1) goto out_find; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 1bd0bfa547f6..5cf82d03968c 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2124,15 +2124,29 @@ static int ext4_writepage(struct page *page, static int mpage_submit_page(struct mpage_da_data *mpd, struct page *page) { int len; - loff_t size = i_size_read(mpd->inode); + loff_t size; int err; BUG_ON(page->index != mpd->first_page); + clear_page_dirty_for_io(page); + /* + * We have to be very careful here! Nothing protects writeback path + * against i_size changes and the page can be writeably mapped into + * page tables. So an application can be growing i_size and writing + * data through mmap while writeback runs. clear_page_dirty_for_io() + * write-protects our page in page tables and the page cannot get + * written to again until we release page lock. So only after + * clear_page_dirty_for_io() we are safe to sample i_size for + * ext4_bio_write_page() to zero-out tail of the written page. We rely + * on the barrier provided by TestClearPageDirty in + * clear_page_dirty_for_io() to make sure i_size is really sampled only + * after page tables are updated. + */ + size = i_size_read(mpd->inode); if (page->index == size >> PAGE_SHIFT) len = size & ~PAGE_MASK; else len = PAGE_SIZE; - clear_page_dirty_for_io(page); err = ext4_bio_write_page(&mpd->io_submit, page, len, mpd->wbc, false); if (!err) mpd->wbc->nr_to_write--; @@ -3629,9 +3643,6 @@ static ssize_t ext4_direct_IO_write(struct kiocb *iocb, struct iov_iter *iter) get_block_func = ext4_dio_get_block_unwritten_async; dio_flags = DIO_LOCKING; } -#ifdef CONFIG_EXT4_FS_ENCRYPTION - BUG_ON(ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode)); -#endif ret = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, iter, get_block_func, ext4_end_io_dio, NULL, dio_flags); @@ -3713,7 +3724,7 @@ static ssize_t ext4_direct_IO_read(struct kiocb *iocb, struct iov_iter *iter) */ inode_lock_shared(inode); ret = filemap_write_and_wait_range(mapping, iocb->ki_pos, - iocb->ki_pos + count); + iocb->ki_pos + count - 1); if (ret) goto out_unlock; ret = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, @@ -4207,6 +4218,8 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) inode->i_mtime = inode->i_ctime = current_time(inode); ext4_mark_inode_dirty(handle, inode); + if (ret >= 0) + ext4_update_inode_fsync_trans(handle, inode, 1); out_stop: ext4_journal_stop(handle); out_dio: @@ -5637,8 +5650,9 @@ static int ext4_expand_extra_isize(struct inode *inode, /* No extended attributes present */ if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR) || header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) { - memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0, - new_extra_isize); + memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE + + EXT4_I(inode)->i_extra_isize, 0, + new_extra_isize - EXT4_I(inode)->i_extra_isize); EXT4_I(inode)->i_extra_isize = new_extra_isize; return 0; } diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 5083bce20ac4..b7928cddd539 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -3887,7 +3887,8 @@ ext4_mb_discard_group_preallocations(struct super_block *sb, err = ext4_mb_load_buddy(sb, group, &e4b); if (err) { - ext4_error(sb, "Error loading buddy information for %u", group); + ext4_warning(sb, "Error %d loading buddy information for %u", + err, group); put_bh(bitmap_bh); return 0; } @@ -4044,10 +4045,11 @@ repeat: BUG_ON(pa->pa_type != MB_INODE_PA); group = ext4_get_group_number(sb, pa->pa_pstart); - err = ext4_mb_load_buddy(sb, group, &e4b); + err = ext4_mb_load_buddy_gfp(sb, group, &e4b, + GFP_NOFS|__GFP_NOFAIL); if (err) { - ext4_error(sb, "Error loading buddy information for %u", - group); + ext4_error(sb, "Error %d loading buddy information for %u", + err, group); continue; } @@ -4303,11 +4305,14 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb, spin_unlock(&lg->lg_prealloc_lock); list_for_each_entry_safe(pa, tmp, &discard_list, u.pa_tmp_list) { + int err; group = ext4_get_group_number(sb, pa->pa_pstart); - if (ext4_mb_load_buddy(sb, group, &e4b)) { - ext4_error(sb, "Error loading buddy information for %u", - group); + err = ext4_mb_load_buddy_gfp(sb, group, &e4b, + GFP_NOFS|__GFP_NOFAIL); + if (err) { + ext4_error(sb, "Error %d loading buddy information for %u", + err, group); continue; } ext4_lock_group(sb, group); @@ -5127,8 +5132,8 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, ret = ext4_mb_load_buddy(sb, group, &e4b); if (ret) { - ext4_error(sb, "Error in loading buddy " - "information for %u", group); + ext4_warning(sb, "Error %d loading buddy information for %u", + ret, group); return ret; } bitmap = e4b.bd_bitmap; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index b81f7d46f344..404256caf9cf 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1155,12 +1155,11 @@ errout: static inline int search_dirblock(struct buffer_head *bh, struct inode *dir, struct ext4_filename *fname, - const struct qstr *d_name, unsigned int offset, struct ext4_dir_entry_2 **res_dir) { return ext4_search_dir(bh, bh->b_data, dir->i_sb->s_blocksize, dir, - fname, d_name, offset, res_dir); + fname, offset, res_dir); } /* @@ -1262,7 +1261,6 @@ static inline bool ext4_match(const struct ext4_filename *fname, */ int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size, struct inode *dir, struct ext4_filename *fname, - const struct qstr *d_name, unsigned int offset, struct ext4_dir_entry_2 **res_dir) { struct ext4_dir_entry_2 * de; @@ -1355,7 +1353,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, if (ext4_has_inline_data(dir)) { int has_inline_data = 1; - ret = ext4_find_inline_entry(dir, &fname, d_name, res_dir, + ret = ext4_find_inline_entry(dir, &fname, res_dir, &has_inline_data); if (has_inline_data) { if (inlined) @@ -1447,7 +1445,7 @@ restart: goto next; } set_buffer_verified(bh); - i = search_dirblock(bh, dir, &fname, d_name, + i = search_dirblock(bh, dir, &fname, block << EXT4_BLOCK_SIZE_BITS(sb), res_dir); if (i == 1) { EXT4_I(dir)->i_dir_start_lookup = block; @@ -1488,7 +1486,6 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, { struct super_block * sb = dir->i_sb; struct dx_frame frames[2], *frame; - const struct qstr *d_name = fname->usr_fname; struct buffer_head *bh; ext4_lblk_t block; int retval; @@ -1505,7 +1502,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, if (IS_ERR(bh)) goto errout; - retval = search_dirblock(bh, dir, fname, d_name, + retval = search_dirblock(bh, dir, fname, block << EXT4_BLOCK_SIZE_BITS(sb), res_dir); if (retval == 1) @@ -1530,7 +1527,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, bh = NULL; errout: - dxtrace(printk(KERN_DEBUG "%s not found\n", d_name->name)); + dxtrace(printk(KERN_DEBUG "%s not found\n", fname->usr_fname->name)); success: dx_release(frames); return bh; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 0b177da9ea82..d37c81f327e7 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -848,14 +848,9 @@ static inline void ext4_quota_off_umount(struct super_block *sb) { int type; - if (ext4_has_feature_quota(sb)) { - dquot_disable(sb, -1, - DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); - } else { - /* Use our quota_off function to clear inode flags etc. */ - for (type = 0; type < EXT4_MAXQUOTAS; type++) - ext4_quota_off(sb, type); - } + /* Use our quota_off function to clear inode flags etc. */ + for (type = 0; type < EXT4_MAXQUOTAS; type++) + ext4_quota_off(sb, type); } #else static inline void ext4_quota_off_umount(struct super_block *sb) @@ -1179,6 +1174,9 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len, return res; } + res = dquot_initialize(inode); + if (res) + return res; retry: handle = ext4_journal_start(inode, EXT4_HT_MISC, ext4_jbd2_credits_xattr(inode)); @@ -5485,7 +5483,7 @@ static int ext4_quota_off(struct super_block *sb, int type) goto out; err = dquot_quota_off(sb, type); - if (err) + if (err || ext4_has_feature_quota(sb)) goto out_put; inode_lock(inode); @@ -5505,6 +5503,7 @@ static int ext4_quota_off(struct super_block *sb, int type) out_unlock: inode_unlock(inode); out_put: + lockdep_set_quota_inode(inode, I_DATA_SEM_NORMAL); iput(inode); return err; out: diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 8fb7ce14e6eb..5d3c2536641c 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -888,6 +888,8 @@ inserted: else { u32 ref; + WARN_ON_ONCE(dquot_initialize_needed(inode)); + /* The old block is released after updating the inode. */ error = dquot_alloc_block(inode, @@ -954,6 +956,8 @@ inserted: /* We need to allocate a new block */ ext4_fsblk_t goal, block; + WARN_ON_ONCE(dquot_initialize_needed(inode)); + goal = ext4_group_first_block_no(sb, EXT4_I(inode)->i_block_group); @@ -1166,6 +1170,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, return -EINVAL; if (strlen(name) > 255) return -ERANGE; + ext4_write_lock_xattr(inode, &no_expand); error = ext4_reserve_inode_write(handle, inode, &is.iloc); @@ -1267,6 +1272,9 @@ ext4_xattr_set(struct inode *inode, int name_index, const char *name, int error, retries = 0; int credits = ext4_jbd2_credits_xattr(inode); + error = dquot_initialize(inode); + if (error) + return error; retry: handle = ext4_journal_start(inode, EXT4_HT_XATTR, credits); if (IS_ERR(handle)) { diff --git a/fs/fcntl.c b/fs/fcntl.c index f4e7267d117f..bbf80344c125 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -246,6 +246,8 @@ static int f_getowner_uids(struct file *filp, unsigned long arg) static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, struct file *filp) { + void __user *argp = (void __user *)arg; + struct flock flock; long err = -EINVAL; switch (cmd) { @@ -273,7 +275,11 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, case F_OFD_GETLK: #endif case F_GETLK: - err = fcntl_getlk(filp, cmd, (struct flock __user *) arg); + if (copy_from_user(&flock, argp, sizeof(flock))) + return -EFAULT; + err = fcntl_getlk(filp, cmd, &flock); + if (!err && copy_to_user(argp, &flock, sizeof(flock))) + return -EFAULT; break; #if BITS_PER_LONG != 32 /* 32-bit arches must use fcntl64() */ @@ -283,7 +289,9 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, /* Fallthrough */ case F_SETLK: case F_SETLKW: - err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg); + if (copy_from_user(&flock, argp, sizeof(flock))) + return -EFAULT; + err = fcntl_setlk(fd, filp, cmd, &flock); break; case F_GETOWN: /* @@ -383,7 +391,9 @@ out: SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, unsigned long, arg) { + void __user *argp = (void __user *)arg; struct fd f = fdget_raw(fd); + struct flock64 flock; long err = -EBADF; if (!f.file) @@ -401,14 +411,21 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, switch (cmd) { case F_GETLK64: case F_OFD_GETLK: - err = fcntl_getlk64(f.file, cmd, (struct flock64 __user *) arg); + err = -EFAULT; + if (copy_from_user(&flock, argp, sizeof(flock))) + break; + err = fcntl_getlk64(f.file, cmd, &flock); + if (!err && copy_to_user(argp, &flock, sizeof(flock))) + err = -EFAULT; break; case F_SETLK64: case F_SETLKW64: case F_OFD_SETLK: case F_OFD_SETLKW: - err = fcntl_setlk64(fd, f.file, cmd, - (struct flock64 __user *) arg); + err = -EFAULT; + if (copy_from_user(&flock, argp, sizeof(flock))) + break; + err = fcntl_setlk64(fd, f.file, cmd, &flock); break; default: err = do_fcntl(fd, cmd, arg, f.file); @@ -489,76 +506,92 @@ convert_fcntl_cmd(unsigned int cmd) return cmd; } +/* + * GETLK was successful and we need to return the data, but it needs to fit in + * the compat structure. + * l_start shouldn't be too big, unless the original start + end is greater than + * COMPAT_OFF_T_MAX, in which case the app was asking for trouble, so we return + * -EOVERFLOW in that case. l_len could be too big, in which case we just + * truncate it, and only allow the app to see that part of the conflicting lock + * that might make sense to it anyway + */ +static int fixup_compat_flock(struct flock *flock) +{ + if (flock->l_start > COMPAT_OFF_T_MAX) + return -EOVERFLOW; + if (flock->l_len > COMPAT_OFF_T_MAX) + flock->l_len = COMPAT_OFF_T_MAX; + return 0; +} + COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, compat_ulong_t, arg) { - mm_segment_t old_fs; - struct flock f; - long ret; - unsigned int conv_cmd; + struct fd f = fdget_raw(fd); + struct flock flock; + long err = -EBADF; + + if (!f.file) + return err; + + if (unlikely(f.file->f_mode & FMODE_PATH)) { + if (!check_fcntl_cmd(cmd)) + goto out_put; + } + + err = security_file_fcntl(f.file, cmd, arg); + if (err) + goto out_put; switch (cmd) { case F_GETLK: + err = get_compat_flock(&flock, compat_ptr(arg)); + if (err) + break; + err = fcntl_getlk(f.file, convert_fcntl_cmd(cmd), &flock); + if (err) + break; + err = fixup_compat_flock(&flock); + if (err) + return err; + err = put_compat_flock(&flock, compat_ptr(arg)); + break; + case F_GETLK64: + case F_OFD_GETLK: + err = get_compat_flock64(&flock, compat_ptr(arg)); + if (err) + break; + err = fcntl_getlk(f.file, convert_fcntl_cmd(cmd), &flock); + if (err) + break; + err = fixup_compat_flock(&flock); + if (err) + return err; + err = put_compat_flock64(&flock, compat_ptr(arg)); + break; case F_SETLK: case F_SETLKW: - ret = get_compat_flock(&f, compat_ptr(arg)); - if (ret != 0) + err = get_compat_flock(&flock, compat_ptr(arg)); + if (err) break; - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_fcntl(fd, cmd, (unsigned long)&f); - set_fs(old_fs); - if (cmd == F_GETLK && ret == 0) { - /* GETLK was successful and we need to return the data... - * but it needs to fit in the compat structure. - * l_start shouldn't be too big, unless the original - * start + end is greater than COMPAT_OFF_T_MAX, in which - * case the app was asking for trouble, so we return - * -EOVERFLOW in that case. - * l_len could be too big, in which case we just truncate it, - * and only allow the app to see that part of the conflicting - * lock that might make sense to it anyway - */ - - if (f.l_start > COMPAT_OFF_T_MAX) - ret = -EOVERFLOW; - if (f.l_len > COMPAT_OFF_T_MAX) - f.l_len = COMPAT_OFF_T_MAX; - if (ret == 0) - ret = put_compat_flock(&f, compat_ptr(arg)); - } + err = fcntl_setlk(fd, f.file, convert_fcntl_cmd(cmd), &flock); break; - - case F_GETLK64: case F_SETLK64: case F_SETLKW64: - case F_OFD_GETLK: case F_OFD_SETLK: case F_OFD_SETLKW: - ret = get_compat_flock64(&f, compat_ptr(arg)); - if (ret != 0) + err = get_compat_flock64(&flock, compat_ptr(arg)); + if (err) break; - old_fs = get_fs(); - set_fs(KERNEL_DS); - conv_cmd = convert_fcntl_cmd(cmd); - ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f); - set_fs(old_fs); - if ((conv_cmd == F_GETLK || conv_cmd == F_OFD_GETLK) && ret == 0) { - /* need to return lock information - see above for commentary */ - if (f.l_start > COMPAT_LOFF_T_MAX) - ret = -EOVERFLOW; - if (f.l_len > COMPAT_LOFF_T_MAX) - f.l_len = COMPAT_LOFF_T_MAX; - if (ret == 0) - ret = put_compat_flock64(&f, compat_ptr(arg)); - } + err = fcntl_setlk(fd, f.file, convert_fcntl_cmd(cmd), &flock); break; - default: - ret = sys_fcntl(fd, cmd, arg); + err = do_fcntl(fd, cmd, arg, f.file); break; } - return ret; +out_put: + fdput(f); + return err; } COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index f865b96374df..d2955daf17a4 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -659,7 +659,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) struct gfs2_log_header *lh; unsigned int tail; u32 hash; - int op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META; + int op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC; struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); lh = page_address(page); diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 9ee4832b6f8b..2d30a6da7013 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -680,6 +680,12 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask) rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_); handle->h_buffer_credits = nblocks; + /* + * Restore the original nofs context because the journal restart + * is basically the same thing as journal stop and start. + * start_this_handle will start a new nofs context. + */ + memalloc_nofs_restore(handle->saved_alloc_context); ret = start_this_handle(journal, handle, gfp_mask); return ret; } diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c index bd9b641ada2c..7ddcb445a3d9 100644 --- a/fs/jfs/resize.c +++ b/fs/jfs/resize.c @@ -98,7 +98,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) goto out; } - VolumeSize = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits; + VolumeSize = i_size_read(sb->s_bdev->bd_inode) >> sb->s_blocksize_bits; if (VolumeSize) { if (newLVSize > VolumeSize) { @@ -211,7 +211,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) txQuiesce(sb); /* Reset size of direct inode */ - sbi->direct_inode->i_size = sb->s_bdev->bd_inode->i_size; + sbi->direct_inode->i_size = i_size_read(sb->s_bdev->bd_inode); if (sbi->mntflag & JFS_INLINELOG) { /* diff --git a/fs/jfs/super.c b/fs/jfs/super.c index e8aad7d87b8c..78b41e1d5c67 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -313,7 +313,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, } case Opt_resize_nosize: { - *newLVSize = sb->s_bdev->bd_inode->i_size >> + *newLVSize = i_size_read(sb->s_bdev->bd_inode) >> sb->s_blocksize_bits; if (*newLVSize == 0) pr_err("JFS: Cannot determine volume size\n"); @@ -579,7 +579,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) goto out_unload; } inode->i_ino = 0; - inode->i_size = sb->s_bdev->bd_inode->i_size; + inode->i_size = i_size_read(sb->s_bdev->bd_inode); inode->i_mapping->a_ops = &jfs_metapage_aops; hlist_add_fake(&inode->i_hash); mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); diff --git a/fs/locks.c b/fs/locks.c index af2031a1fcff..afefeb4ad6de 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1858,8 +1858,8 @@ EXPORT_SYMBOL(generic_setlease); * * Call this to establish a lease on the file. The "lease" argument is not * used for F_UNLCK requests and may be NULL. For commands that set or alter - * an existing lease, the (*lease)->fl_lmops->lm_break operation must be set; - * if not, this function will return -ENOLCK (and generate a scary-looking + * an existing lease, the ``(*lease)->fl_lmops->lm_break`` operation must be + * set; if not, this function will return -ENOLCK (and generate a scary-looking * stack trace). * * The "priv" pointer is passed directly to the lm_setup function as-is. It @@ -1972,15 +1972,13 @@ EXPORT_SYMBOL(locks_lock_inode_wait); * @cmd: the type of lock to apply. * * Apply a %FL_FLOCK style lock to an open file descriptor. - * The @cmd can be one of + * The @cmd can be one of: * - * %LOCK_SH -- a shared lock. - * - * %LOCK_EX -- an exclusive lock. - * - * %LOCK_UN -- remove an existing lock. - * - * %LOCK_MAND -- a `mandatory' flock. This exists to emulate Windows Share Modes. + * - %LOCK_SH -- a shared lock. + * - %LOCK_EX -- an exclusive lock. + * - %LOCK_UN -- remove an existing lock. + * - %LOCK_MAND -- a 'mandatory' flock. + * This exists to emulate Windows Share Modes. * * %LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other * processes read and write access respectively. @@ -2086,26 +2084,22 @@ static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) /* Report the first existing lock that would conflict with l. * This implements the F_GETLK command of fcntl(). */ -int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l) +int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock) { struct file_lock file_lock; - struct flock flock; int error; - error = -EFAULT; - if (copy_from_user(&flock, l, sizeof(flock))) - goto out; error = -EINVAL; - if ((flock.l_type != F_RDLCK) && (flock.l_type != F_WRLCK)) + if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK) goto out; - error = flock_to_posix_lock(filp, &file_lock, &flock); + error = flock_to_posix_lock(filp, &file_lock, flock); if (error) goto out; if (cmd == F_OFD_GETLK) { error = -EINVAL; - if (flock.l_pid != 0) + if (flock->l_pid != 0) goto out; cmd = F_GETLK; @@ -2117,15 +2111,12 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l) if (error) goto out; - flock.l_type = file_lock.fl_type; + flock->l_type = file_lock.fl_type; if (file_lock.fl_type != F_UNLCK) { - error = posix_lock_to_flock(&flock, &file_lock); + error = posix_lock_to_flock(flock, &file_lock); if (error) goto rel_priv; } - error = -EFAULT; - if (!copy_to_user(l, &flock, sizeof(flock))) - error = 0; rel_priv: locks_release_private(&file_lock); out: @@ -2218,26 +2209,16 @@ check_fmode_for_setlk(struct file_lock *fl) * This implements both the F_SETLK and F_SETLKW commands of fcntl(). */ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, - struct flock __user *l) + struct flock *flock) { struct file_lock *file_lock = locks_alloc_lock(); - struct flock flock; - struct inode *inode; + struct inode *inode = locks_inode(filp); struct file *f; int error; if (file_lock == NULL) return -ENOLCK; - inode = locks_inode(filp); - - /* - * This might block, so we do it before checking the inode. - */ - error = -EFAULT; - if (copy_from_user(&flock, l, sizeof(flock))) - goto out; - /* Don't allow mandatory locks on files that may be memory mapped * and shared. */ @@ -2246,7 +2227,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, goto out; } - error = flock_to_posix_lock(filp, file_lock, &flock); + error = flock_to_posix_lock(filp, file_lock, flock); if (error) goto out; @@ -2261,7 +2242,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, switch (cmd) { case F_OFD_SETLK: error = -EINVAL; - if (flock.l_pid != 0) + if (flock->l_pid != 0) goto out; cmd = F_SETLK; @@ -2270,7 +2251,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, break; case F_OFD_SETLKW: error = -EINVAL; - if (flock.l_pid != 0) + if (flock->l_pid != 0) goto out; cmd = F_SETLKW; @@ -2315,26 +2296,22 @@ out: /* Report the first existing lock that would conflict with l. * This implements the F_GETLK command of fcntl(). */ -int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) +int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock) { struct file_lock file_lock; - struct flock64 flock; int error; - error = -EFAULT; - if (copy_from_user(&flock, l, sizeof(flock))) - goto out; error = -EINVAL; - if ((flock.l_type != F_RDLCK) && (flock.l_type != F_WRLCK)) + if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK) goto out; - error = flock64_to_posix_lock(filp, &file_lock, &flock); + error = flock64_to_posix_lock(filp, &file_lock, flock); if (error) goto out; if (cmd == F_OFD_GETLK) { error = -EINVAL; - if (flock.l_pid != 0) + if (flock->l_pid != 0) goto out; cmd = F_GETLK64; @@ -2346,13 +2323,9 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) if (error) goto out; - flock.l_type = file_lock.fl_type; + flock->l_type = file_lock.fl_type; if (file_lock.fl_type != F_UNLCK) - posix_lock_to_flock64(&flock, &file_lock); - - error = -EFAULT; - if (!copy_to_user(l, &flock, sizeof(flock))) - error = 0; + posix_lock_to_flock64(flock, &file_lock); locks_release_private(&file_lock); out: @@ -2363,26 +2336,16 @@ out: * This implements both the F_SETLK and F_SETLKW commands of fcntl(). */ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, - struct flock64 __user *l) + struct flock64 *flock) { struct file_lock *file_lock = locks_alloc_lock(); - struct flock64 flock; - struct inode *inode; + struct inode *inode = locks_inode(filp); struct file *f; int error; if (file_lock == NULL) return -ENOLCK; - /* - * This might block, so we do it before checking the inode. - */ - error = -EFAULT; - if (copy_from_user(&flock, l, sizeof(flock))) - goto out; - - inode = locks_inode(filp); - /* Don't allow mandatory locks on files that may be memory mapped * and shared. */ @@ -2391,7 +2354,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, goto out; } - error = flock64_to_posix_lock(filp, file_lock, &flock); + error = flock64_to_posix_lock(filp, file_lock, flock); if (error) goto out; @@ -2406,7 +2369,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, switch (cmd) { case F_OFD_SETLK: error = -EINVAL; - if (flock.l_pid != 0) + if (flock->l_pid != 0) goto out; cmd = F_SETLK64; @@ -2415,7 +2378,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, break; case F_OFD_SETLKW: error = -EINVAL; - if (flock.l_pid != 0) + if (flock->l_pid != 0) goto out; cmd = F_SETLKW64; diff --git a/fs/namei.c b/fs/namei.c index 6571a5f5112e..d7b88c7cd70c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -874,6 +874,8 @@ static int nd_jump_root(struct nameidata *nd) path_get(&nd->path); nd->inode = nd->path.dentry->d_inode; } + if (unlikely(nd->flags & LOOKUP_NO_JUMPS)) + return -ELOOP; nd->flags |= LOOKUP_JUMPED; return 0; } @@ -1054,14 +1056,18 @@ const char *get_link(struct nameidata *nd) } else { res = get(dentry, inode, &last->done); } + if (unlikely(nd->flags & LOOKUP_NO_JUMPS) && + unlikely(nd->flags & LOOKUP_JUMPED)) + return ERR_PTR(-ELOOP); if (IS_ERR_OR_NULL(res)) return res; } if (*res == '/') { if (!nd->root.mnt) set_root(nd); - if (unlikely(nd_jump_root(nd))) - return ERR_PTR(-ECHILD); + error = nd_jump_root(nd); + if (unlikely(error)) + return ERR_PTR(error); while (unlikely(*++res == '/')) ; } @@ -1245,12 +1251,16 @@ static int follow_managed(struct path *path, struct nameidata *nd) break; } - if (need_mntput && path->mnt == mnt) - mntput(path->mnt); + if (need_mntput) { + if (path->mnt == mnt) + mntput(path->mnt); + if (unlikely(nd->flags & LOOKUP_NO_JUMPS)) + ret = -ELOOP; + else + nd->flags |= LOOKUP_JUMPED; + } if (ret == -EISDIR || !ret) ret = 1; - if (need_mntput) - nd->flags |= LOOKUP_JUMPED; if (unlikely(ret < 0)) path_put_conditional(path, nd); return ret; @@ -1307,6 +1317,8 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, mounted = __lookup_mnt(path->mnt, path->dentry); if (!mounted) break; + if (unlikely(nd->flags & LOOKUP_NO_JUMPS)) + return false; path->mnt = &mounted->mnt; path->dentry = mounted->mnt.mnt_root; nd->flags |= LOOKUP_JUMPED; @@ -1327,8 +1339,11 @@ static int follow_dotdot_rcu(struct nameidata *nd) struct inode *inode = nd->inode; while (1) { - if (path_equal(&nd->path, &nd->root)) + if (unlikely(path_equal(&nd->path, &nd->root))) { + if (nd->flags & LOOKUP_NO_JUMPS) + return -ELOOP; break; + } if (nd->path.dentry != nd->path.mnt->mnt_root) { struct dentry *old = nd->path.dentry; struct dentry *parent = old->d_parent; @@ -1455,8 +1470,9 @@ static int path_parent_directory(struct path *path) static int follow_dotdot(struct nameidata *nd) { while(1) { - if (nd->path.dentry == nd->root.dentry && - nd->path.mnt == nd->root.mnt) { + if (unlikely(path_equal(&nd->path, &nd->root))) { + if (nd->flags & LOOKUP_NO_JUMPS) + return -ELOOP; break; } if (nd->path.dentry != nd->path.mnt->mnt_root) { @@ -2174,14 +2190,16 @@ static const char *path_init(struct nameidata *nd, unsigned flags) nd->m_seq = read_seqbegin(&mount_lock); if (*s == '/') { + int error; if (flags & LOOKUP_RCU) rcu_read_lock(); set_root(nd); - if (likely(!nd_jump_root(nd))) - return s; - nd->root.mnt = NULL; - rcu_read_unlock(); - return ERR_PTR(-ECHILD); + error = nd_jump_root(nd); + if (unlikely(error)) { + terminate_walk(nd); + s = ERR_PTR(error); + } + return s; } else if (nd->dfd == AT_FDCWD) { if (flags & LOOKUP_RCU) { struct fs_struct *fs = current->fs; @@ -2199,6 +2217,11 @@ static const char *path_init(struct nameidata *nd, unsigned flags) get_fs_pwd(current->fs, &nd->path); nd->inode = nd->path.dentry->d_inode; } + if (unlikely(flags & LOOKUP_NO_JUMPS)) { + nd->root = nd->path; + if (!(flags & LOOKUP_RCU)) + path_get(&nd->root); + } return s; } else { /* Caller must check execute permissions on the starting path component */ @@ -2226,6 +2249,11 @@ static const char *path_init(struct nameidata *nd, unsigned flags) path_get(&nd->path); nd->inode = nd->path.dentry->d_inode; } + if (unlikely(flags & LOOKUP_NO_JUMPS)) { + nd->root = nd->path; + if (!(flags & LOOKUP_RCU)) + path_get(&nd->root); + } fdput(f); return s; } diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index f5714ee01000..23542dc44a25 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -454,6 +454,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, goto out_err_free; /* fh */ + rc = -EIO; p = xdr_inline_decode(&stream, 4); if (!p) goto out_err_free; diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 929d09a5310a..319a47db218d 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -177,7 +177,7 @@ static ssize_t _nfs42_proc_copy(struct file *src, if (status) goto out; - if (!nfs_write_verifier_cmp(&res->write_res.verifier.verifier, + if (nfs_write_verifier_cmp(&res->write_res.verifier.verifier, &res->commit_res.verf->verifier)) { status = -EAGAIN; goto out; diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 692a7a8bfc7a..66776f022111 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -582,7 +582,6 @@ int nfs40_walk_client_list(struct nfs_client *new, */ nfs4_schedule_path_down_recovery(pos); default: - spin_lock(&nn->nfs_client_lock); goto out; } diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index adc6ec28d4b5..c383d0913b54 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -2094,12 +2094,26 @@ pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio) } EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_layout); +/* + * Check for any intersection between the request and the pgio->pg_lseg, + * and if none, put this pgio->pg_lseg away. + */ +static void +pnfs_generic_pg_check_range(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) +{ + if (pgio->pg_lseg && !pnfs_lseg_request_intersecting(pgio->pg_lseg, req)) { + pnfs_put_lseg(pgio->pg_lseg); + pgio->pg_lseg = NULL; + } +} + void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) { u64 rd_size = req->wb_bytes; pnfs_generic_pg_check_layout(pgio); + pnfs_generic_pg_check_range(pgio, req); if (pgio->pg_lseg == NULL) { if (pgio->pg_dreq == NULL) rd_size = i_size_read(pgio->pg_inode) - req_offset(req); @@ -2131,6 +2145,7 @@ pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req, u64 wb_size) { pnfs_generic_pg_check_layout(pgio); + pnfs_generic_pg_check_range(pgio, req); if (pgio->pg_lseg == NULL) { pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, req->wb_context, @@ -2191,16 +2206,10 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, seg_end = pnfs_end_offset(pgio->pg_lseg->pls_range.offset, pgio->pg_lseg->pls_range.length); req_start = req_offset(req); - WARN_ON_ONCE(req_start >= seg_end); + /* start of request is past the last byte of this segment */ - if (req_start >= seg_end) { - /* reference the new lseg */ - if (pgio->pg_ops->pg_cleanup) - pgio->pg_ops->pg_cleanup(pgio); - if (pgio->pg_ops->pg_init) - pgio->pg_ops->pg_init(pgio, req); + if (req_start >= seg_end) return 0; - } /* adjust 'size' iff there are fewer bytes left in the * segment than what nfs_generic_pg_test returned */ diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 2d05b756a8d6..99731e3e332f 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -593,6 +593,16 @@ pnfs_lseg_range_intersecting(const struct pnfs_layout_range *l1, return pnfs_is_range_intersecting(l1->offset, end1, l2->offset, end2); } +static inline bool +pnfs_lseg_request_intersecting(struct pnfs_layout_segment *lseg, struct nfs_page *req) +{ + u64 seg_last = pnfs_end_offset(lseg->pls_range.offset, lseg->pls_range.length); + u64 req_last = req_offset(req) + req->wb_bytes; + + return pnfs_is_range_intersecting(lseg->pls_range.offset, seg_last, + req_offset(req), req_last); +} + extern unsigned int layoutstats_timer; #ifdef NFS_DEBUG diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig index 0daac5112f7a..c0c9683934b7 100644 --- a/fs/overlayfs/Kconfig +++ b/fs/overlayfs/Kconfig @@ -1,5 +1,6 @@ config OVERLAY_FS tristate "Overlay filesystem support" + select EXPORTFS help An overlay filesystem combines two filesystems - an 'upper' filesystem and a 'lower' filesystem. When a name exists in both filesystems, the diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 9008ab9fbd2e..7a44533f4bbf 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -300,7 +300,11 @@ static int ovl_set_origin(struct dentry *dentry, struct dentry *lower, return PTR_ERR(fh); } - err = ovl_do_setxattr(upper, OVL_XATTR_ORIGIN, fh, fh ? fh->len : 0, 0); + /* + * Do not fail when upper doesn't support xattrs. + */ + err = ovl_check_setxattr(dentry, upper, OVL_XATTR_ORIGIN, fh, + fh ? fh->len : 0, 0); kfree(fh); return err; @@ -342,13 +346,14 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, if (tmpfile) temp = ovl_do_tmpfile(upperdir, stat->mode); else - temp = ovl_lookup_temp(workdir, dentry); - err = PTR_ERR(temp); - if (IS_ERR(temp)) - goto out1; - + temp = ovl_lookup_temp(workdir); err = 0; - if (!tmpfile) + if (IS_ERR(temp)) { + err = PTR_ERR(temp); + temp = NULL; + } + + if (!err && !tmpfile) err = ovl_create_real(wdir, temp, &cattr, NULL, true); if (new_creds) { @@ -454,6 +459,11 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, ovl_path_upper(parent, &parentpath); upperdir = parentpath.dentry; + /* Mark parent "impure" because it may now contain non-pure upper */ + err = ovl_set_impure(parent, upperdir); + if (err) + return err; + err = vfs_getattr(&parentpath, &pstat, STATX_ATIME | STATX_MTIME, AT_STATX_SYNC_AS_STAT); if (err) diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 723b98b90698..a63a71656e9b 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -41,7 +41,7 @@ void ovl_cleanup(struct inode *wdir, struct dentry *wdentry) } } -struct dentry *ovl_lookup_temp(struct dentry *workdir, struct dentry *dentry) +struct dentry *ovl_lookup_temp(struct dentry *workdir) { struct dentry *temp; char name[20]; @@ -68,7 +68,7 @@ static struct dentry *ovl_whiteout(struct dentry *workdir, struct dentry *whiteout; struct inode *wdir = workdir->d_inode; - whiteout = ovl_lookup_temp(workdir, dentry); + whiteout = ovl_lookup_temp(workdir); if (IS_ERR(whiteout)) return whiteout; @@ -127,17 +127,28 @@ int ovl_create_real(struct inode *dir, struct dentry *newdentry, return err; } -static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry) +static int ovl_set_opaque_xerr(struct dentry *dentry, struct dentry *upper, + int xerr) { int err; - err = ovl_do_setxattr(upperdentry, OVL_XATTR_OPAQUE, "y", 1, 0); + err = ovl_check_setxattr(dentry, upper, OVL_XATTR_OPAQUE, "y", 1, xerr); if (!err) ovl_dentry_set_opaque(dentry); return err; } +static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry) +{ + /* + * Fail with -EIO when trying to create opaque dir and upper doesn't + * support xattrs. ovl_rename() calls ovl_set_opaque_xerr(-EXDEV) to + * return a specific error for noxattr case. + */ + return ovl_set_opaque_xerr(dentry, upperdentry, -EIO); +} + /* Common operations required to be done after creation of file on upper */ static void ovl_instantiate(struct dentry *dentry, struct inode *inode, struct dentry *newdentry, bool hardlink) @@ -162,6 +173,11 @@ static bool ovl_type_merge(struct dentry *dentry) return OVL_TYPE_MERGE(ovl_path_type(dentry)); } +static bool ovl_type_origin(struct dentry *dentry) +{ + return OVL_TYPE_ORIGIN(ovl_path_type(dentry)); +} + static int ovl_create_upper(struct dentry *dentry, struct inode *inode, struct cattr *attr, struct dentry *hardlink) { @@ -250,7 +266,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, if (upper->d_parent->d_inode != udir) goto out_unlock; - opaquedir = ovl_lookup_temp(workdir, dentry); + opaquedir = ovl_lookup_temp(workdir); err = PTR_ERR(opaquedir); if (IS_ERR(opaquedir)) goto out_unlock; @@ -382,7 +398,7 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, if (err) goto out; - newdentry = ovl_lookup_temp(workdir, dentry); + newdentry = ovl_lookup_temp(workdir); err = PTR_ERR(newdentry); if (IS_ERR(newdentry)) goto out_unlock; @@ -846,18 +862,16 @@ static int ovl_set_redirect(struct dentry *dentry, bool samedir) if (IS_ERR(redirect)) return PTR_ERR(redirect); - err = ovl_do_setxattr(ovl_dentry_upper(dentry), OVL_XATTR_REDIRECT, - redirect, strlen(redirect), 0); + err = ovl_check_setxattr(dentry, ovl_dentry_upper(dentry), + OVL_XATTR_REDIRECT, + redirect, strlen(redirect), -EXDEV); if (!err) { spin_lock(&dentry->d_lock); ovl_dentry_set_redirect(dentry, redirect); spin_unlock(&dentry->d_lock); } else { kfree(redirect); - if (err == -EOPNOTSUPP) - ovl_clear_redirect_dir(dentry->d_sb); - else - pr_warn_ratelimited("overlay: failed to set redirect (%i)\n", err); + pr_warn_ratelimited("overlay: failed to set redirect (%i)\n", err); /* Fall back to userspace copy-up */ err = -EXDEV; } @@ -943,6 +957,25 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, old_upperdir = ovl_dentry_upper(old->d_parent); new_upperdir = ovl_dentry_upper(new->d_parent); + if (!samedir) { + /* + * When moving a merge dir or non-dir with copy up origin into + * a new parent, we are marking the new parent dir "impure". + * When ovl_iterate() iterates an "impure" upper dir, it will + * lookup the origin inodes of the entries to fill d_ino. + */ + if (ovl_type_origin(old)) { + err = ovl_set_impure(new->d_parent, new_upperdir); + if (err) + goto out_revert_creds; + } + if (!overwrite && ovl_type_origin(new)) { + err = ovl_set_impure(old->d_parent, old_upperdir); + if (err) + goto out_revert_creds; + } + } + trap = lock_rename(new_upperdir, old_upperdir); olddentry = lookup_one_len(old->d_name.name, old_upperdir, @@ -992,7 +1025,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, if (ovl_type_merge_or_lower(old)) err = ovl_set_redirect(old, samedir); else if (!old_opaque && ovl_type_merge(new->d_parent)) - err = ovl_set_opaque(old, olddentry); + err = ovl_set_opaque_xerr(old, olddentry, -EXDEV); if (err) goto out_dput; } @@ -1000,7 +1033,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, if (ovl_type_merge_or_lower(new)) err = ovl_set_redirect(new, samedir); else if (!new_opaque && ovl_type_merge(old->d_parent)) - err = ovl_set_opaque(new, newdentry); + err = ovl_set_opaque_xerr(new, newdentry, -EXDEV); if (err) goto out_dput; } diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index ad9547f82da5..d613e2c41242 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -240,6 +240,16 @@ int ovl_xattr_get(struct dentry *dentry, const char *name, return res; } +static bool ovl_can_list(const char *s) +{ + /* List all non-trusted xatts */ + if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0) + return true; + + /* Never list trusted.overlay, list other trusted for superuser only */ + return !ovl_is_private_xattr(s) && capable(CAP_SYS_ADMIN); +} + ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) { struct dentry *realdentry = ovl_dentry_real(dentry); @@ -263,7 +273,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) return -EIO; len -= slen; - if (ovl_is_private_xattr(s)) { + if (!ovl_can_list(s)) { res -= slen; memmove(s, s + slen, len); } else { diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index bad0f665a635..f3136c31e72a 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -169,17 +169,7 @@ invalid: static bool ovl_is_opaquedir(struct dentry *dentry) { - int res; - char val; - - if (!d_is_dir(dentry)) - return false; - - res = vfs_getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1); - if (res == 1 && val == 'y') - return true; - - return false; + return ovl_check_dir_xattr(dentry, OVL_XATTR_OPAQUE); } static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, @@ -351,6 +341,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, unsigned int ctr = 0; struct inode *inode = NULL; bool upperopaque = false; + bool upperimpure = false; char *upperredirect = NULL; struct dentry *this; unsigned int i; @@ -395,6 +386,8 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, poe = roe; } upperopaque = d.opaque; + if (upperdentry && d.is_dir) + upperimpure = ovl_is_impuredir(upperdentry); } if (!d.stop && poe->numlower) { @@ -463,6 +456,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, revert_creds(old_cred); oe->opaque = upperopaque; + oe->impure = upperimpure; oe->redirect = upperredirect; oe->__upperdentry = upperdentry; memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr); diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index caa36cb9c46d..0623cebeefff 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -24,6 +24,7 @@ enum ovl_path_type { #define OVL_XATTR_OPAQUE OVL_XATTR_PREFIX "opaque" #define OVL_XATTR_REDIRECT OVL_XATTR_PREFIX "redirect" #define OVL_XATTR_ORIGIN OVL_XATTR_PREFIX "origin" +#define OVL_XATTR_IMPURE OVL_XATTR_PREFIX "impure" /* * The tuple (fh,uuid) is a universal unique identifier for a copy up origin, @@ -203,10 +204,10 @@ struct dentry *ovl_dentry_real(struct dentry *dentry); struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry); void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); bool ovl_dentry_is_opaque(struct dentry *dentry); +bool ovl_dentry_is_impure(struct dentry *dentry); bool ovl_dentry_is_whiteout(struct dentry *dentry); void ovl_dentry_set_opaque(struct dentry *dentry); bool ovl_redirect_dir(struct super_block *sb); -void ovl_clear_redirect_dir(struct super_block *sb); const char *ovl_dentry_get_redirect(struct dentry *dentry); void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect); void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry); @@ -219,6 +220,17 @@ bool ovl_is_whiteout(struct dentry *dentry); struct file *ovl_path_open(struct path *path, int flags); int ovl_copy_up_start(struct dentry *dentry); void ovl_copy_up_end(struct dentry *dentry); +bool ovl_check_dir_xattr(struct dentry *dentry, const char *name); +int ovl_check_setxattr(struct dentry *dentry, struct dentry *upperdentry, + const char *name, const void *value, size_t size, + int xerr); +int ovl_set_impure(struct dentry *dentry, struct dentry *upperdentry); + +static inline bool ovl_is_impuredir(struct dentry *dentry) +{ + return ovl_check_dir_xattr(dentry, OVL_XATTR_IMPURE); +} + /* namei.c */ int ovl_path_next(int idx, struct dentry *dentry, struct path *path); @@ -263,7 +275,7 @@ static inline void ovl_copyattr(struct inode *from, struct inode *to) /* dir.c */ extern const struct inode_operations ovl_dir_inode_operations; -struct dentry *ovl_lookup_temp(struct dentry *workdir, struct dentry *dentry); +struct dentry *ovl_lookup_temp(struct dentry *workdir); struct cattr { dev_t rdev; umode_t mode; diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index b2023ddb8532..34bc4a9f5c61 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -28,6 +28,7 @@ struct ovl_fs { /* creds of process who forced instantiation of super block */ const struct cred *creator_cred; bool tmpfile; + bool noxattr; wait_queue_head_t copyup_wq; /* sb common to all layers */ struct super_block *same_sb; @@ -42,6 +43,7 @@ struct ovl_entry { u64 version; const char *redirect; bool opaque; + bool impure; bool copying; }; struct rcu_head rcu; diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 9828b7de8999..4882ffb37bae 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -891,6 +891,19 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) dput(temp); else pr_warn("overlayfs: upper fs does not support tmpfile.\n"); + + /* + * Check if upper/work fs supports trusted.overlay.* + * xattr + */ + err = ovl_do_setxattr(ufs->workdir, OVL_XATTR_OPAQUE, + "0", 1, 0); + if (err) { + ufs->noxattr = true; + pr_warn("overlayfs: upper fs does not support xattr.\n"); + } else { + vfs_removexattr(ufs->workdir, OVL_XATTR_OPAQUE); + } } } @@ -961,7 +974,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) path_put(&workpath); kfree(lowertmp); - oe->__upperdentry = upperpath.dentry; + if (upperpath.dentry) { + oe->__upperdentry = upperpath.dentry; + oe->impure = ovl_is_impuredir(upperpath.dentry); + } for (i = 0; i < numlower; i++) { oe->lowerstack[i].dentry = stack[i].dentry; oe->lowerstack[i].mnt = ufs->lower_mnt[i]; diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index cfdea47313a1..809048913889 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -175,6 +175,13 @@ bool ovl_dentry_is_opaque(struct dentry *dentry) return oe->opaque; } +bool ovl_dentry_is_impure(struct dentry *dentry) +{ + struct ovl_entry *oe = dentry->d_fsdata; + + return oe->impure; +} + bool ovl_dentry_is_whiteout(struct dentry *dentry) { return !dentry->d_inode && ovl_dentry_is_opaque(dentry); @@ -191,14 +198,7 @@ bool ovl_redirect_dir(struct super_block *sb) { struct ovl_fs *ofs = sb->s_fs_info; - return ofs->config.redirect_dir; -} - -void ovl_clear_redirect_dir(struct super_block *sb) -{ - struct ovl_fs *ofs = sb->s_fs_info; - - ofs->config.redirect_dir = false; + return ofs->config.redirect_dir && !ofs->noxattr; } const char *ovl_dentry_get_redirect(struct dentry *dentry) @@ -303,3 +303,59 @@ void ovl_copy_up_end(struct dentry *dentry) wake_up_locked(&ofs->copyup_wq); spin_unlock(&ofs->copyup_wq.lock); } + +bool ovl_check_dir_xattr(struct dentry *dentry, const char *name) +{ + int res; + char val; + + if (!d_is_dir(dentry)) + return false; + + res = vfs_getxattr(dentry, name, &val, 1); + if (res == 1 && val == 'y') + return true; + + return false; +} + +int ovl_check_setxattr(struct dentry *dentry, struct dentry *upperdentry, + const char *name, const void *value, size_t size, + int xerr) +{ + int err; + struct ovl_fs *ofs = dentry->d_sb->s_fs_info; + + if (ofs->noxattr) + return xerr; + + err = ovl_do_setxattr(upperdentry, name, value, size, 0); + + if (err == -EOPNOTSUPP) { + pr_warn("overlayfs: cannot set %s xattr on upper\n", name); + ofs->noxattr = true; + return xerr; + } + + return err; +} + +int ovl_set_impure(struct dentry *dentry, struct dentry *upperdentry) +{ + int err; + struct ovl_entry *oe = dentry->d_fsdata; + + if (oe->impure) + return 0; + + /* + * Do not fail when upper doesn't support xattrs. + * Upper inodes won't have origin nor redirect xattr anyway. + */ + err = ovl_check_setxattr(dentry, upperdentry, OVL_XATTR_IMPURE, + "y", 1, 0); + if (!err) + oe->impure = true; + + return err; +} diff --git a/fs/proc/base.c b/fs/proc/base.c index 45f6bf68fff3..f1e1927ccd48 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -821,7 +821,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf, if (!mmget_not_zero(mm)) goto free; - flags = write ? FOLL_WRITE : 0; + flags = FOLL_FORCE | (write ? FOLL_WRITE : 0); while (count > 0) { int this_len = min_t(int, count, PAGE_SIZE); diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index 792a4e5f9226..4d02c3b65061 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -349,48 +349,48 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record) switch (record->type) { case PSTORE_TYPE_DMESG: - scnprintf(name, sizeof(name), "dmesg-%s-%lld%s", + scnprintf(name, sizeof(name), "dmesg-%s-%llu%s", record->psi->name, record->id, record->compressed ? ".enc.z" : ""); break; case PSTORE_TYPE_CONSOLE: - scnprintf(name, sizeof(name), "console-%s-%lld", + scnprintf(name, sizeof(name), "console-%s-%llu", record->psi->name, record->id); break; case PSTORE_TYPE_FTRACE: - scnprintf(name, sizeof(name), "ftrace-%s-%lld", + scnprintf(name, sizeof(name), "ftrace-%s-%llu", record->psi->name, record->id); break; case PSTORE_TYPE_MCE: - scnprintf(name, sizeof(name), "mce-%s-%lld", + scnprintf(name, sizeof(name), "mce-%s-%llu", record->psi->name, record->id); break; case PSTORE_TYPE_PPC_RTAS: - scnprintf(name, sizeof(name), "rtas-%s-%lld", + scnprintf(name, sizeof(name), "rtas-%s-%llu", record->psi->name, record->id); break; case PSTORE_TYPE_PPC_OF: - scnprintf(name, sizeof(name), "powerpc-ofw-%s-%lld", + scnprintf(name, sizeof(name), "powerpc-ofw-%s-%llu", record->psi->name, record->id); break; case PSTORE_TYPE_PPC_COMMON: - scnprintf(name, sizeof(name), "powerpc-common-%s-%lld", + scnprintf(name, sizeof(name), "powerpc-common-%s-%llu", record->psi->name, record->id); break; case PSTORE_TYPE_PMSG: - scnprintf(name, sizeof(name), "pmsg-%s-%lld", + scnprintf(name, sizeof(name), "pmsg-%s-%llu", record->psi->name, record->id); break; case PSTORE_TYPE_PPC_OPAL: - scnprintf(name, sizeof(name), "powerpc-opal-%s-%lld", + scnprintf(name, sizeof(name), "powerpc-opal-%s-%llu", record->psi->name, record->id); break; case PSTORE_TYPE_UNKNOWN: - scnprintf(name, sizeof(name), "unknown-%s-%lld", + scnprintf(name, sizeof(name), "unknown-%s-%llu", record->psi->name, record->id); break; default: - scnprintf(name, sizeof(name), "type%d-%s-%lld", + scnprintf(name, sizeof(name), "type%d-%s-%llu", record->type, record->psi->name, record->id); break; } diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h index c416e653dc4f..58051265626f 100644 --- a/fs/pstore/internal.h +++ b/fs/pstore/internal.h @@ -30,5 +30,7 @@ extern void pstore_get_backend_records(struct pstore_info *psi, extern int pstore_mkfile(struct dentry *root, struct pstore_record *record); extern bool pstore_is_mounted(void); +extern void pstore_record_init(struct pstore_record *record, + struct pstore_info *psi); #endif diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index d468eec9b8a6..96fbff7b87c8 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -474,6 +474,20 @@ static size_t copy_kmsg_to_buffer(int hsize, size_t len) return total_len; } +void pstore_record_init(struct pstore_record *record, + struct pstore_info *psinfo) +{ + memset(record, 0, sizeof(*record)); + + record->psi = psinfo; + + /* Report zeroed timestamp if called before timekeeping has resumed. */ + if (__getnstimeofday(&record->time)) { + record->time.tv_sec = 0; + record->time.tv_nsec = 0; + } +} + /* * callback from kmsg_dump. (s2,l2) has the most recently * written bytes, older bytes are in (s1,l1). Save as much @@ -509,15 +523,14 @@ static void pstore_dump(struct kmsg_dumper *dumper, int header_size; int zipped_len = -1; size_t dump_size; - struct pstore_record record = { - .type = PSTORE_TYPE_DMESG, - .count = oopscount, - .reason = reason, - .part = part, - .compressed = false, - .buf = psinfo->buf, - .psi = psinfo, - }; + struct pstore_record record; + + pstore_record_init(&record, psinfo); + record.type = PSTORE_TYPE_DMESG; + record.count = oopscount; + record.reason = reason; + record.part = part; + record.buf = psinfo->buf; if (big_oops_buf && is_locked) { dst = big_oops_buf; @@ -587,12 +600,12 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) const char *e = s + c; while (s < e) { - struct pstore_record record = { - .type = PSTORE_TYPE_CONSOLE, - .psi = psinfo, - }; + struct pstore_record record; unsigned long flags; + pstore_record_init(&record, psinfo); + record.type = PSTORE_TYPE_CONSOLE; + if (c > psinfo->bufsize) c = psinfo->bufsize; @@ -770,8 +783,11 @@ static void decompress_record(struct pstore_record *record) int unzipped_len; char *decompressed; + if (!record->compressed) + return; + /* Only PSTORE_TYPE_DMESG support compression. */ - if (!record->compressed || record->type != PSTORE_TYPE_DMESG) { + if (record->type != PSTORE_TYPE_DMESG) { pr_warn("ignored compressed record type %d\n", record->type); return; } @@ -819,6 +835,7 @@ void pstore_get_backend_records(struct pstore_info *psi, struct dentry *root, int quiet) { int failed = 0; + unsigned int stop_loop = 65536; if (!psi || !root) return; @@ -832,7 +849,7 @@ void pstore_get_backend_records(struct pstore_info *psi, * may reallocate record.buf. On success, pstore_mkfile() will keep * the record.buf, so free it only on failure. */ - for (;;) { + for (; stop_loop; stop_loop--) { struct pstore_record *record; int rc; @@ -841,13 +858,15 @@ void pstore_get_backend_records(struct pstore_info *psi, pr_err("out of memory creating record\n"); break; } - record->psi = psi; + pstore_record_init(record, psi); record->size = psi->read(record); /* No more records left in backend? */ - if (record->size <= 0) + if (record->size <= 0) { + kfree(record); break; + } decompress_record(record); rc = pstore_mkfile(root, record); @@ -865,8 +884,11 @@ out: mutex_unlock(&psi->read_mutex); if (failed) - pr_warn("failed to load %d record(s) from '%s'\n", + pr_warn("failed to create %d record(s) from '%s'\n", failed, psi->name); + if (!stop_loop) + pr_err("looping? Too many records seen from '%s'\n", + psi->name); } static void pstore_dowork(struct work_struct *work) diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c index 209755e0d7c8..24db02de1787 100644 --- a/fs/pstore/pmsg.c +++ b/fs/pstore/pmsg.c @@ -22,16 +22,16 @@ static DEFINE_MUTEX(pmsg_lock); static ssize_t write_pmsg(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - struct pstore_record record = { - .type = PSTORE_TYPE_PMSG, - .size = count, - .psi = psinfo, - }; + struct pstore_record record; int ret; if (!count) return 0; + pstore_record_init(&record, psinfo); + record.type = PSTORE_TYPE_PMSG; + record.size = count; + /* check outside lock, page in any data. write_user also checks */ if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 5cb022c8cd33..7125b398d312 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -27,7 +27,6 @@ #include <linux/module.h> #include <linux/version.h> #include <linux/pstore.h> -#include <linux/time.h> #include <linux/io.h> #include <linux/ioport.h> #include <linux/platform_device.h> @@ -356,20 +355,15 @@ out: } static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz, - bool compressed) + struct pstore_record *record) { char *hdr; - struct timespec timestamp; size_t len; - /* Report zeroed timestamp if called before timekeeping has resumed. */ - if (__getnstimeofday(×tamp)) { - timestamp.tv_sec = 0; - timestamp.tv_nsec = 0; - } hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n", - (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000), - compressed ? 'C' : 'D'); + record->time.tv_sec, + record->time.tv_nsec / 1000, + record->compressed ? 'C' : 'D'); WARN_ON_ONCE(!hdr); len = hdr ? strlen(hdr) : 0; persistent_ram_write(prz, hdr, len); @@ -440,7 +434,7 @@ static int notrace ramoops_pstore_write(struct pstore_record *record) prz = cxt->dprzs[cxt->dump_write_cnt]; /* Build header and append record contents. */ - hlen = ramoops_write_kmsg_hdr(prz, record->compressed); + hlen = ramoops_write_kmsg_hdr(prz, record); size = record->size; if (size + hlen > prz->buffer_size) size = prz->buffer_size - hlen; diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index ebf80c7739e1..48813aeaab80 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1512,6 +1512,22 @@ int dquot_initialize(struct inode *inode) } EXPORT_SYMBOL(dquot_initialize); +bool dquot_initialize_needed(struct inode *inode) +{ + struct dquot **dquots; + int i; + + if (!dquot_active(inode)) + return false; + + dquots = i_dquot(inode); + for (i = 0; i < MAXQUOTAS; i++) + if (!dquots[i] && sb_has_quota_active(inode->i_sb, i)) + return true; + return false; +} +EXPORT_SYMBOL(dquot_initialize_needed); + /* * Release all quotas referenced by inode. * diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index da01f497180a..39bb1e838d8d 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -1112,7 +1112,7 @@ static int flush_commit_list(struct super_block *s, depth = reiserfs_write_unlock_nested(s); if (reiserfs_barrier_flush(s)) __sync_dirty_buffer(jl->j_commit_bh, - REQ_PREFLUSH | REQ_FUA); + REQ_SYNC | REQ_PREFLUSH | REQ_FUA); else sync_dirty_buffer(jl->j_commit_bh); reiserfs_write_lock_nested(s, depth); @@ -1271,7 +1271,7 @@ static int _update_journal_header_block(struct super_block *sb, if (reiserfs_barrier_flush(sb)) __sync_dirty_buffer(journal->j_header_bh, - REQ_PREFLUSH | REQ_FUA); + REQ_SYNC | REQ_PREFLUSH | REQ_FUA); else sync_dirty_buffer(journal->j_header_bh); diff --git a/fs/stat.c b/fs/stat.c index f494b182c7c7..4a8da5470eee 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -170,7 +170,7 @@ int vfs_statx(int dfd, const char __user *filename, int flags, unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT; if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | - AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0) + AT_EMPTY_PATH | KSTAT_QUERY_FLAGS | AT_NO_JUMPS)) != 0) return -EINVAL; if (flags & AT_SYMLINK_NOFOLLOW) @@ -179,6 +179,8 @@ int vfs_statx(int dfd, const char __user *filename, int flags, lookup_flags &= ~LOOKUP_AUTOMOUNT; if (flags & AT_EMPTY_PATH) lookup_flags |= LOOKUP_EMPTY; + if (flags & AT_NO_JUMPS) + lookup_flags |= LOOKUP_NO_JUMPS; retry: error = user_path_at(dfd, filename, lookup_flags, &path); diff --git a/include/asm-generic/page.h b/include/asm-generic/page.h index 67cfb7dbc284..8847a6e2ba45 100644 --- a/include/asm-generic/page.h +++ b/include/asm-generic/page.h @@ -92,7 +92,7 @@ extern unsigned long memory_end; #define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \ ((void *)(kaddr) < (void *)memory_end)) -#endif /* __ASSEMBLY__ */ +#endif /* !__ASSEMBLY__ */ #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 314a0b9219c6..9862afb3ae05 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -595,6 +595,7 @@ #define SBSS(sbss_align) \ . = ALIGN(sbss_align); \ .sbss : AT(ADDR(.sbss) - LOAD_OFFSET) { \ + *(.dynsbss) \ *(.sbss) \ *(.scommon) \ } @@ -641,11 +642,22 @@ .debug_str 0 : { *(.debug_str) } \ .debug_loc 0 : { *(.debug_loc) } \ .debug_macinfo 0 : { *(.debug_macinfo) } \ + .debug_pubtypes 0 : { *(.debug_pubtypes) } \ + /* DWARF 3 */ \ + .debug_ranges 0 : { *(.debug_ranges) } \ /* SGI/MIPS DWARF 2 extensions */ \ .debug_weaknames 0 : { *(.debug_weaknames) } \ .debug_funcnames 0 : { *(.debug_funcnames) } \ .debug_typenames 0 : { *(.debug_typenames) } \ .debug_varnames 0 : { *(.debug_varnames) } \ + /* GNU DWARF 2 extensions */ \ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } \ + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } \ + /* DWARF 4 */ \ + .debug_types 0 : { *(.debug_types) } \ + /* DWARF 5 */ \ + .debug_macro 0 : { *(.debug_macro) } \ + .debug_addr 0 : { *(.debug_addr) } /* Stabs debugging sections. */ #define STABS_DEBUG \ diff --git a/include/dt-bindings/clock/r7s72100-clock.h b/include/dt-bindings/clock/r7s72100-clock.h index bc256d31099a..dcd2072151fc 100644 --- a/include/dt-bindings/clock/r7s72100-clock.h +++ b/include/dt-bindings/clock/r7s72100-clock.h @@ -34,6 +34,8 @@ /* MSTP7 */ #define R7S72100_CLK_ETHER 4 +#define R7S72100_CLK_USB0 1 +#define R7S72100_CLK_USB1 0 /* MSTP8 */ #define R7S72100_CLK_MMCIF 4 diff --git a/include/dt-bindings/clock/r8a7791-clock.h b/include/dt-bindings/clock/r8a7791-clock.h index adc50dc31ab3..ef692134146b 100644 --- a/include/dt-bindings/clock/r8a7791-clock.h +++ b/include/dt-bindings/clock/r8a7791-clock.h @@ -109,6 +109,7 @@ #define R8A7791_CLK_SATA0 15 /* MSTP9 */ +#define R8A7791_CLK_GYROADC 1 #define R8A7791_CLK_GPIO7 4 #define R8A7791_CLK_GPIO6 5 #define R8A7791_CLK_GPIO5 7 diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h index b27e2b1a65e3..56f841c22801 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h @@ -61,6 +61,17 @@ #define SCLK_MAC_TX 130 #define SCLK_MAC_PHY 131 #define SCLK_MAC_OUT 132 +#define SCLK_VDEC_CABAC 133 +#define SCLK_VDEC_CORE 134 +#define SCLK_RGA 135 +#define SCLK_HDCP 136 +#define SCLK_HDMI_CEC 137 +#define SCLK_CRYPTO 138 +#define SCLK_TSP 139 +#define SCLK_HSADC 140 +#define SCLK_WIFI 141 +#define SCLK_OTGPHY0 142 +#define SCLK_OTGPHY1 143 /* dclk gates */ #define DCLK_VOP 190 @@ -68,15 +79,32 @@ /* aclk gates */ #define ACLK_DMAC 194 +#define ACLK_CPU 195 +#define ACLK_VPU_PRE 196 +#define ACLK_RKVDEC_PRE 197 +#define ACLK_RGA_PRE 198 +#define ACLK_IEP_PRE 199 +#define ACLK_HDCP_PRE 200 +#define ACLK_VOP_PRE 201 +#define ACLK_VPU 202 +#define ACLK_RKVDEC 203 +#define ACLK_IEP 204 +#define ACLK_RGA 205 +#define ACLK_HDCP 206 #define ACLK_PERI 210 #define ACLK_VOP 211 #define ACLK_GMAC 212 +#define ACLK_GPU 213 /* pclk gates */ #define PCLK_GPIO0 320 #define PCLK_GPIO1 321 #define PCLK_GPIO2 322 #define PCLK_GPIO3 323 +#define PCLK_VIO_H2P 324 +#define PCLK_HDCP 325 +#define PCLK_EFUSE_1024 326 +#define PCLK_EFUSE_256 327 #define PCLK_GRF 329 #define PCLK_I2C0 332 #define PCLK_I2C1 333 @@ -89,6 +117,7 @@ #define PCLK_TSADC 344 #define PCLK_PWM 350 #define PCLK_TIMER 353 +#define PCLK_CPU 354 #define PCLK_PERI 363 #define PCLK_HDMI_CTRL 364 #define PCLK_HDMI_PHY 365 @@ -104,6 +133,24 @@ #define HCLK_SDMMC 456 #define HCLK_SDIO 457 #define HCLK_EMMC 459 +#define HCLK_CPU 460 +#define HCLK_VPU_PRE 461 +#define HCLK_RKVDEC_PRE 462 +#define HCLK_VIO_PRE 463 +#define HCLK_VPU 464 +#define HCLK_RKVDEC 465 +#define HCLK_VIO 466 +#define HCLK_RGA 467 +#define HCLK_IEP 468 +#define HCLK_VIO_H2P 469 +#define HCLK_HDCP_MMU 470 +#define HCLK_HOST0 471 +#define HCLK_HOST1 472 +#define HCLK_HOST2 473 +#define HCLK_OTG 474 +#define HCLK_TSP 475 +#define HCLK_M_CRYPTO 476 +#define HCLK_S_CRYPTO 477 #define HCLK_PERI 478 #define CLK_NR_CLKS (HCLK_PERI + 1) diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h index 220a60f20d3b..22cb1dfa9004 100644 --- a/include/dt-bindings/clock/rk3399-cru.h +++ b/include/dt-bindings/clock/rk3399-cru.h @@ -132,6 +132,8 @@ #define SCLK_RMII_SRC 166 #define SCLK_PCIEPHY_REF100M 167 #define SCLK_DDRC 168 +#define SCLK_TESTCLKOUT1 169 +#define SCLK_TESTCLKOUT2 170 #define DCLK_VOP0 180 #define DCLK_VOP1 181 diff --git a/include/dt-bindings/clock/sun5i-ccu.h b/include/dt-bindings/clock/sun5i-ccu.h index aeb2e2f781fb..81f34d477aeb 100644 --- a/include/dt-bindings/clock/sun5i-ccu.h +++ b/include/dt-bindings/clock/sun5i-ccu.h @@ -19,6 +19,9 @@ #define CLK_HOSC 1 +#define CLK_PLL_VIDEO0_2X 9 + +#define CLK_PLL_VIDEO1_2X 16 #define CLK_CPU 17 #define CLK_AHB_OTG 23 diff --git a/include/dt-bindings/clock/sun8i-a83t-ccu.h b/include/dt-bindings/clock/sun8i-a83t-ccu.h new file mode 100644 index 000000000000..78af5085f630 --- /dev/null +++ b/include/dt-bindings/clock/sun8i-a83t-ccu.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2017 Chen-Yu Tsai <wens@csie.org> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_CLOCK_SUN8I_A83T_CCU_H_ +#define _DT_BINDINGS_CLOCK_SUN8I_A83T_CCU_H_ + +#define CLK_PLL_PERIPH 6 + +#define CLK_PLL_DE 9 + +#define CLK_C0CPUX 11 +#define CLK_C1CPUX 12 + +#define CLK_BUS_MIPI_DSI 19 +#define CLK_BUS_SS 20 +#define CLK_BUS_DMA 21 +#define CLK_BUS_MMC0 22 +#define CLK_BUS_MMC1 23 +#define CLK_BUS_MMC2 24 +#define CLK_BUS_NAND 25 +#define CLK_BUS_DRAM 26 +#define CLK_BUS_EMAC 27 +#define CLK_BUS_HSTIMER 28 +#define CLK_BUS_SPI0 29 +#define CLK_BUS_SPI1 30 +#define CLK_BUS_OTG 31 +#define CLK_BUS_EHCI0 32 +#define CLK_BUS_EHCI1 33 +#define CLK_BUS_OHCI0 34 + +#define CLK_BUS_VE 35 +#define CLK_BUS_TCON0 36 +#define CLK_BUS_TCON1 37 +#define CLK_BUS_CSI 38 +#define CLK_BUS_HDMI 39 +#define CLK_BUS_DE 40 +#define CLK_BUS_GPU 41 +#define CLK_BUS_MSGBOX 42 +#define CLK_BUS_SPINLOCK 43 + +#define CLK_BUS_SPDIF 44 +#define CLK_BUS_PIO 45 +#define CLK_BUS_I2S0 46 +#define CLK_BUS_I2S1 47 +#define CLK_BUS_I2S2 48 +#define CLK_BUS_TDM 49 + +#define CLK_BUS_I2C0 50 +#define CLK_BUS_I2C1 51 +#define CLK_BUS_I2C2 52 +#define CLK_BUS_UART0 53 +#define CLK_BUS_UART1 54 +#define CLK_BUS_UART2 55 +#define CLK_BUS_UART3 56 +#define CLK_BUS_UART4 57 + +#define CLK_NAND 59 +#define CLK_MMC0 60 +#define CLK_MMC0_SAMPLE 61 +#define CLK_MMC0_OUTPUT 62 +#define CLK_MMC1 63 +#define CLK_MMC1_SAMPLE 64 +#define CLK_MMC1_OUTPUT 65 +#define CLK_MMC2 66 +#define CLK_MMC2_SAMPLE 67 +#define CLK_MMC2_OUTPUT 68 +#define CLK_SS 69 +#define CLK_SPI0 70 +#define CLK_SPI1 71 +#define CLK_I2S0 72 +#define CLK_I2S1 73 +#define CLK_I2S2 74 +#define CLK_TDM 75 +#define CLK_SPDIF 76 +#define CLK_USB_PHY0 77 +#define CLK_USB_PHY1 78 +#define CLK_USB_HSIC 79 +#define CLK_USB_HSIC_12M 80 +#define CLK_USB_OHCI0 81 + +#define CLK_DRAM_VE 83 +#define CLK_DRAM_CSI 84 + +#define CLK_TCON0 85 +#define CLK_TCON1 86 +#define CLK_CSI_MISC 87 +#define CLK_MIPI_CSI 88 +#define CLK_CSI_MCLK 89 +#define CLK_CSI_SCLK 90 +#define CLK_VE 91 +#define CLK_AVS 92 +#define CLK_HDMI 93 +#define CLK_HDMI_SLOW 94 + +#define CLK_MIPI_DSI0 96 +#define CLK_MIPI_DSI1 97 +#define CLK_GPU_CORE 98 +#define CLK_GPU_MEMORY 99 +#define CLK_GPU_HYD 100 + +#endif /* _DT_BINDINGS_CLOCK_SUN8I_A83T_CCU_H_ */ diff --git a/include/dt-bindings/clock/sun8i-de2.h b/include/dt-bindings/clock/sun8i-de2.h new file mode 100644 index 000000000000..3bed63b524aa --- /dev/null +++ b/include/dt-bindings/clock/sun8i-de2.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.io> + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +#ifndef _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ +#define _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ + +#define CLK_BUS_MIXER0 0 +#define CLK_BUS_MIXER1 1 +#define CLK_BUS_WB 2 + +#define CLK_MIXER0 6 +#define CLK_MIXER1 7 +#define CLK_WB 8 + +#endif /* _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ */ diff --git a/include/dt-bindings/pinctrl/r7s72100-pinctrl.h b/include/dt-bindings/pinctrl/r7s72100-pinctrl.h new file mode 100644 index 000000000000..6b609fe10910 --- /dev/null +++ b/include/dt-bindings/pinctrl/r7s72100-pinctrl.h @@ -0,0 +1,16 @@ +/* + * Defines macros and constants for Renesas RZ/A1 pin controller pin + * muxing functions. + */ +#ifndef __DT_BINDINGS_PINCTRL_RENESAS_RZA1_H +#define __DT_BINDINGS_PINCTRL_RENESAS_RZA1_H + +#define RZA1_PINS_PER_PORT 16 + +/* + * Create the pin index from its bank and position numbers and store in + * the upper 16 bits the alternate function identifier + */ +#define RZA1_PINMUX(b, p, f) ((b) * RZA1_PINS_PER_PORT + (p) | (f << 16)) + +#endif /* __DT_BINDINGS_PINCTRL_RENESAS_RZA1_H */ diff --git a/include/dt-bindings/reset/cortina,gemini-reset.h b/include/dt-bindings/reset/cortina,gemini-reset.h new file mode 100644 index 000000000000..0b886aee65e3 --- /dev/null +++ b/include/dt-bindings/reset/cortina,gemini-reset.h @@ -0,0 +1,36 @@ +#ifndef _DT_BINDINGS_RESET_CORTINA_GEMINI_H +#define _DT_BINDINGS_RESET_CORTINA_GEMINI_H + +#define GEMINI_RESET_DRAM 0 +#define GEMINI_RESET_FLASH 1 +#define GEMINI_RESET_IDE 2 +#define GEMINI_RESET_RAID 3 +#define GEMINI_RESET_SECURITY 4 +#define GEMINI_RESET_GMAC0 5 +#define GEMINI_RESET_GMAC1 6 +#define GEMINI_RESET_PCI 7 +#define GEMINI_RESET_USB0 8 +#define GEMINI_RESET_USB1 9 +#define GEMINI_RESET_DMAC 10 +#define GEMINI_RESET_APB 11 +#define GEMINI_RESET_LPC 12 +#define GEMINI_RESET_LCD 13 +#define GEMINI_RESET_INTCON0 14 +#define GEMINI_RESET_INTCON1 15 +#define GEMINI_RESET_RTC 16 +#define GEMINI_RESET_TIMER 17 +#define GEMINI_RESET_UART 18 +#define GEMINI_RESET_SSP 19 +#define GEMINI_RESET_GPIO0 20 +#define GEMINI_RESET_GPIO1 21 +#define GEMINI_RESET_GPIO2 22 +#define GEMINI_RESET_WDOG 23 +#define GEMINI_RESET_EXTERN 24 +#define GEMINI_RESET_CIR 25 +#define GEMINI_RESET_SATA0 26 +#define GEMINI_RESET_SATA1 27 +#define GEMINI_RESET_TVC 28 +#define GEMINI_RESET_CPU1 30 +#define GEMINI_RESET_GLOBAL 31 + +#endif diff --git a/include/dt-bindings/reset/sun8i-a83t-ccu.h b/include/dt-bindings/reset/sun8i-a83t-ccu.h new file mode 100644 index 000000000000..784f6e11664e --- /dev/null +++ b/include/dt-bindings/reset/sun8i-a83t-ccu.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2017 Chen-Yu Tsai <wens@csie.org> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_RESET_SUN8I_A83T_CCU_H_ +#define _DT_BINDINGS_RESET_SUN8I_A83T_CCU_H_ + +#define RST_USB_PHY0 0 +#define RST_USB_PHY1 1 +#define RST_USB_HSIC 2 + +#define RST_DRAM 3 +#define RST_MBUS 4 + +#define RST_BUS_MIPI_DSI 5 +#define RST_BUS_SS 6 +#define RST_BUS_DMA 7 +#define RST_BUS_MMC0 8 +#define RST_BUS_MMC1 9 +#define RST_BUS_MMC2 10 +#define RST_BUS_NAND 11 +#define RST_BUS_DRAM 12 +#define RST_BUS_EMAC 13 +#define RST_BUS_HSTIMER 14 +#define RST_BUS_SPI0 15 +#define RST_BUS_SPI1 16 +#define RST_BUS_OTG 17 +#define RST_BUS_EHCI0 18 +#define RST_BUS_EHCI1 19 +#define RST_BUS_OHCI0 20 + +#define RST_BUS_VE 21 +#define RST_BUS_TCON0 22 +#define RST_BUS_TCON1 23 +#define RST_BUS_CSI 24 +#define RST_BUS_HDMI0 25 +#define RST_BUS_HDMI1 26 +#define RST_BUS_DE 27 +#define RST_BUS_GPU 28 +#define RST_BUS_MSGBOX 29 +#define RST_BUS_SPINLOCK 30 + +#define RST_BUS_LVDS 31 + +#define RST_BUS_SPDIF 32 +#define RST_BUS_I2S0 33 +#define RST_BUS_I2S1 34 +#define RST_BUS_I2S2 35 +#define RST_BUS_TDM 36 + +#define RST_BUS_I2C0 37 +#define RST_BUS_I2C1 38 +#define RST_BUS_I2C2 39 +#define RST_BUS_UART0 40 +#define RST_BUS_UART1 41 +#define RST_BUS_UART2 42 +#define RST_BUS_UART3 43 +#define RST_BUS_UART4 44 + +#endif /* _DT_BINDINGS_RESET_SUN8I_A83T_CCU_H_ */ diff --git a/include/dt-bindings/reset/sun8i-de2.h b/include/dt-bindings/reset/sun8i-de2.h new file mode 100644 index 000000000000..9526017432f0 --- /dev/null +++ b/include/dt-bindings/reset/sun8i-de2.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.io> + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +#ifndef _DT_BINDINGS_RESET_SUN8I_DE2_H_ +#define _DT_BINDINGS_RESET_SUN8I_DE2_H_ + +#define RST_MIXER0 0 +#define RST_MIXER1 1 +#define RST_WB 2 + +#endif /* _DT_BINDINGS_RESET_SUN8I_DE2_H_ */ diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index a428aec36ace..c59c62571e4f 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -412,9 +412,10 @@ extern const struct clk_ops clk_divider_ro_ops; unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate, unsigned int val, const struct clk_div_table *table, unsigned long flags); -long divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate, const struct clk_div_table *table, - u8 width, unsigned long flags); +long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent, + unsigned long rate, unsigned long *prate, + const struct clk_div_table *table, + u8 width, unsigned long flags); int divider_get_val(unsigned long rate, unsigned long parent_rate, const struct clk_div_table *table, u8 width, unsigned long flags); @@ -757,6 +758,15 @@ static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src) dst->core = src->core; } +static inline long divider_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate, + const struct clk_div_table *table, + u8 width, unsigned long flags) +{ + return divider_round_rate_parent(hw, clk_hw_get_parent(hw), + rate, prate, table, width, flags); +} + /* * FIXME clock api without lock protection */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 803e5a9b2654..aa4affb38c39 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1038,14 +1038,14 @@ static inline struct inode *locks_inode(const struct file *f) } #ifdef CONFIG_FILE_LOCKING -extern int fcntl_getlk(struct file *, unsigned int, struct flock __user *); +extern int fcntl_getlk(struct file *, unsigned int, struct flock *); extern int fcntl_setlk(unsigned int, struct file *, unsigned int, - struct flock __user *); + struct flock *); #if BITS_PER_LONG == 32 -extern int fcntl_getlk64(struct file *, unsigned int, struct flock64 __user *); +extern int fcntl_getlk64(struct file *, unsigned int, struct flock64 *); extern int fcntl_setlk64(unsigned int, struct file *, unsigned int, - struct flock64 __user *); + struct flock64 *); #endif extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg); diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h index c0d712d22b07..f738d50cc17d 100644 --- a/include/linux/gpio/machine.h +++ b/include/linux/gpio/machine.h @@ -56,7 +56,14 @@ struct gpiod_lookup_table { .flags = _flags, \ } +#ifdef CONFIG_GPIOLIB void gpiod_add_lookup_table(struct gpiod_lookup_table *table); void gpiod_remove_lookup_table(struct gpiod_lookup_table *table); +#else +static inline +void gpiod_add_lookup_table(struct gpiod_lookup_table *table) {} +static inline +void gpiod_remove_lookup_table(struct gpiod_lookup_table *table) {} +#endif #endif /* __LINUX_GPIO_MACHINE_H */ diff --git a/include/linux/hid.h b/include/linux/hid.h index 5be325d890d9..bebbf4893448 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -182,6 +182,11 @@ struct hid_item { #define HID_GD_KEYBOARD 0x00010006 #define HID_GD_KEYPAD 0x00010007 #define HID_GD_MULTIAXIS 0x00010008 +/* + * Microsoft Win8 Wireless Radio Controls extensions CA, see: + * http://www.usb.org/developers/hidpage/HUTRR40RadioHIDUsagesFinal.pdf + */ +#define HID_GD_WIRELESS_RADIO_CTLS 0x0001000c #define HID_GD_X 0x00010030 #define HID_GD_Y 0x00010031 #define HID_GD_Z 0x00010032 @@ -210,6 +215,10 @@ struct hid_item { #define HID_GD_DOWN 0x00010091 #define HID_GD_RIGHT 0x00010092 #define HID_GD_LEFT 0x00010093 +/* Microsoft Win8 Wireless Radio Controls CA usage codes */ +#define HID_GD_RFKILL_BTN 0x000100c6 +#define HID_GD_RFKILL_LED 0x000100c7 +#define HID_GD_RFKILL_SWITCH 0x000100c8 #define HID_DC_BATTERYSTRENGTH 0x00060020 diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 566fda587fcf..3f74ef2281e8 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -467,6 +467,7 @@ enum dmi_field { DMI_PRODUCT_VERSION, DMI_PRODUCT_SERIAL, DMI_PRODUCT_UUID, + DMI_PRODUCT_FAMILY, DMI_BOARD_VENDOR, DMI_BOARD_NAME, DMI_BOARD_VERSION, diff --git a/include/linux/namei.h b/include/linux/namei.h index 8b4794e83196..be763796b471 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -46,6 +46,8 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; #define LOOKUP_EMPTY 0x4000 #define LOOKUP_DOWN 0x8000 +#define LOOKUP_NO_JUMPS 0x10000 + extern int path_pts(struct path *path); extern int user_path_at_empty(int, const char __user *, unsigned, struct path *, int *empty); diff --git a/drivers/phy/ulpi_phy.h b/include/linux/phy/ulpi_phy.h index f2ebe490a4bc..f2ebe490a4bc 100644 --- a/drivers/phy/ulpi_phy.h +++ b/include/linux/phy/ulpi_phy.h diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h index 279e3c5326e3..7620eb127cff 100644 --- a/include/linux/pinctrl/pinconf-generic.h +++ b/include/linux/pinctrl/pinconf-generic.h @@ -42,8 +42,6 @@ * @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high * impedance to VDD). If the argument is != 0 pull-up is enabled, * if it is 0, pull-up is total, i.e. the pin is connected to VDD. - * @PIN_CONFIG_BIDIRECTIONAL: the pin will be configured to allow simultaneous - * input and output operations. * @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open * collector) which means it is usually wired with other output ports * which are then pulled up with an external resistor. Setting this @@ -98,7 +96,6 @@ enum pin_config_param { PIN_CONFIG_BIAS_PULL_DOWN, PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, PIN_CONFIG_BIAS_PULL_UP, - PIN_CONFIG_BIDIRECTIONAL, PIN_CONFIG_DRIVE_OPEN_DRAIN, PIN_CONFIG_DRIVE_OPEN_SOURCE, PIN_CONFIG_DRIVE_PUSH_PULL, diff --git a/include/linux/i2c/i2c-hid.h b/include/linux/platform_data/i2c-hid.h index 1fb088239d12..1fb088239d12 100644 --- a/include/linux/i2c/i2c-hid.h +++ b/include/linux/platform_data/i2c-hid.h diff --git a/include/linux/pstore.h b/include/linux/pstore.h index e2233f50f428..61f806a7fe29 100644 --- a/include/linux/pstore.h +++ b/include/linux/pstore.h @@ -138,7 +138,10 @@ struct pstore_record { * memory allocation may be broken during an Oops. Regardless, * @buf must be proccesed or copied before returning. The * backend is also expected to write @id with something that - 8 can help identify this record to a future @erase callback. + * can help identify this record to a future @erase callback. + * The @time field will be prepopulated with the current time, + * when available. The @size field will have the size of data + * in @buf. * * Returns 0 on success, and non-zero on error. * diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 9c6f768b7d32..dda22f45fc1b 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -44,6 +44,7 @@ void inode_sub_rsv_space(struct inode *inode, qsize_t number); void inode_reclaim_rsv_space(struct inode *inode, qsize_t number); int dquot_initialize(struct inode *inode); +bool dquot_initialize_needed(struct inode *inode); void dquot_drop(struct inode *inode); struct dquot *dqget(struct super_block *sb, struct kqid qid); static inline struct dquot *dqgrab(struct dquot *dquot) @@ -207,6 +208,11 @@ static inline int dquot_initialize(struct inode *inode) return 0; } +static inline bool dquot_initialize_needed(struct inode *inode) +{ + return false; +} + static inline void dquot_drop(struct inode *inode) { } diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index e37973526153..cd99a3658156 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h @@ -1410,42 +1410,6 @@ DEFINE_EVENT(btrfs__workqueue_done, btrfs_workqueue_destroy, TP_ARGS(wq) ); -DECLARE_EVENT_CLASS(btrfs__qgroup_data_map, - - TP_PROTO(struct inode *inode, u64 free_reserved), - - TP_ARGS(inode, free_reserved), - - TP_STRUCT__entry_btrfs( - __field( u64, rootid ) - __field( unsigned long, ino ) - __field( u64, free_reserved ) - ), - - TP_fast_assign_btrfs(btrfs_sb(inode->i_sb), - __entry->rootid = BTRFS_I(inode)->root->objectid; - __entry->ino = inode->i_ino; - __entry->free_reserved = free_reserved; - ), - - TP_printk_btrfs("rootid=%llu ino=%lu free_reserved=%llu", - __entry->rootid, __entry->ino, __entry->free_reserved) -); - -DEFINE_EVENT(btrfs__qgroup_data_map, btrfs_qgroup_init_data_rsv_map, - - TP_PROTO(struct inode *inode, u64 free_reserved), - - TP_ARGS(inode, free_reserved) -); - -DEFINE_EVENT(btrfs__qgroup_data_map, btrfs_qgroup_free_data_rsv_map, - - TP_PROTO(struct inode *inode, u64 free_reserved), - - TP_ARGS(inode, free_reserved) -); - #define BTRFS_QGROUP_OPERATIONS \ { QGROUP_RESERVE, "reserve" }, \ { QGROUP_RELEASE, "release" }, \ diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index 813afd6eee71..ca35ef523e40 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -68,5 +68,6 @@ #define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd with the server */ #define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the server */ +#define AT_NO_JUMPS 0x8000 /* No mountpoint crossing, no abs symlinks */ #endif /* _UAPI_LINUX_FCNTL_H */ diff --git a/kernel/locking/qrwlock.c b/kernel/locking/qrwlock.c index cc3ed0ccdfa2..2655f26ec882 100644 --- a/kernel/locking/qrwlock.c +++ b/kernel/locking/qrwlock.c @@ -20,6 +20,7 @@ #include <linux/cpumask.h> #include <linux/percpu.h> #include <linux/hardirq.h> +#include <linux/spinlock.h> #include <asm/qrwlock.h> /* diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 1db044f808b7..2a7d04049af4 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -18,12 +18,14 @@ #ifdef CONFIG_PRINTK -#define PRINTK_SAFE_CONTEXT_MASK 0x7fffffff -#define PRINTK_NMI_CONTEXT_MASK 0x80000000 +#define PRINTK_SAFE_CONTEXT_MASK 0x3fffffff +#define PRINTK_NMI_DEFERRED_CONTEXT_MASK 0x40000000 +#define PRINTK_NMI_CONTEXT_MASK 0x80000000 extern raw_spinlock_t logbuf_lock; __printf(1, 0) int vprintk_default(const char *fmt, va_list args); +__printf(1, 0) int vprintk_deferred(const char *fmt, va_list args); __printf(1, 0) int vprintk_func(const char *fmt, va_list args); void __printk_safe_enter(void); void __printk_safe_exit(void); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index a1aecf44ab07..9995b2dfaaff 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2746,16 +2746,13 @@ void wake_up_klogd(void) preempt_enable(); } -int printk_deferred(const char *fmt, ...) +int vprintk_deferred(const char *fmt, va_list args) { - va_list args; int r; - preempt_disable(); - va_start(args, fmt); r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, 0, fmt, args); - va_end(args); + preempt_disable(); __this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT); irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); preempt_enable(); @@ -2763,6 +2760,18 @@ int printk_deferred(const char *fmt, ...) return r; } +int printk_deferred(const char *fmt, ...) +{ + va_list args; + int r; + + va_start(args, fmt); + r = vprintk_deferred(fmt, args); + va_end(args); + + return r; +} + /* * printk rate limiting, lifted from the networking subsystem. * diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c index 033e50a7d706..03a42a539b20 100644 --- a/kernel/printk/printk_safe.c +++ b/kernel/printk/printk_safe.c @@ -308,12 +308,24 @@ static int vprintk_nmi(const char *fmt, va_list args) void printk_nmi_enter(void) { - this_cpu_or(printk_context, PRINTK_NMI_CONTEXT_MASK); + /* + * The size of the extra per-CPU buffer is limited. Use it only when + * the main one is locked. If this CPU is not in the safe context, + * the lock must be taken on another CPU and we could wait for it. + */ + if ((this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK) && + raw_spin_is_locked(&logbuf_lock)) { + this_cpu_or(printk_context, PRINTK_NMI_CONTEXT_MASK); + } else { + this_cpu_or(printk_context, PRINTK_NMI_DEFERRED_CONTEXT_MASK); + } } void printk_nmi_exit(void) { - this_cpu_and(printk_context, ~PRINTK_NMI_CONTEXT_MASK); + this_cpu_and(printk_context, + ~(PRINTK_NMI_CONTEXT_MASK | + PRINTK_NMI_DEFERRED_CONTEXT_MASK)); } #else @@ -351,12 +363,22 @@ void __printk_safe_exit(void) __printf(1, 0) int vprintk_func(const char *fmt, va_list args) { + /* Use extra buffer in NMI when logbuf_lock is taken or in safe mode. */ if (this_cpu_read(printk_context) & PRINTK_NMI_CONTEXT_MASK) return vprintk_nmi(fmt, args); + /* Use extra buffer to prevent a recursion deadlock in safe mode. */ if (this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK) return vprintk_safe(fmt, args); + /* + * Use the main logbuf when logbuf_lock is available in NMI. + * But avoid calling console drivers that might have their own locks. + */ + if (this_cpu_read(printk_context) & PRINTK_NMI_DEFERRED_CONTEXT_MASK) + return vprintk_deferred(fmt, args); + + /* No obstacles. */ return vprintk_default(fmt, args); } diff --git a/lib/nmi_backtrace.c b/lib/nmi_backtrace.c index 4e8a30d1c22f..0bc0a3535a8a 100644 --- a/lib/nmi_backtrace.c +++ b/lib/nmi_backtrace.c @@ -86,9 +86,11 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask, bool nmi_cpu_backtrace(struct pt_regs *regs) { + static arch_spinlock_t lock = __ARCH_SPIN_LOCK_UNLOCKED; int cpu = smp_processor_id(); if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { + arch_spin_lock(&lock); if (regs && cpu_in_idle(instruction_pointer(regs))) { pr_warn("NMI backtrace for cpu %d skipped: idling at pc %#lx\n", cpu, instruction_pointer(regs)); @@ -99,6 +101,7 @@ bool nmi_cpu_backtrace(struct pt_regs *regs) else dump_stack(); } + arch_spin_unlock(&lock); cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); return true; } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 59792d283ff8..b5ea036ca781 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2381,9 +2381,10 @@ static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int l return 0; } -static int tcp_repair_options_est(struct tcp_sock *tp, +static int tcp_repair_options_est(struct sock *sk, struct tcp_repair_opt __user *optbuf, unsigned int len) { + struct tcp_sock *tp = tcp_sk(sk); struct tcp_repair_opt opt; while (len >= sizeof(opt)) { @@ -2396,6 +2397,7 @@ static int tcp_repair_options_est(struct tcp_sock *tp, switch (opt.opt_code) { case TCPOPT_MSS: tp->rx_opt.mss_clamp = opt.opt_val; + tcp_mtup_init(sk); break; case TCPOPT_WINDOW: { @@ -2555,7 +2557,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, if (!tp->repair) err = -EINVAL; else if (sk->sk_state == TCP_ESTABLISHED) - err = tcp_repair_options_est(tp, + err = tcp_repair_options_est(sk, (struct tcp_repair_opt __user *)optval, optlen); else diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 60e2a62f7bef..cf2392b2ac71 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -7,7 +7,7 @@ * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> * Copyright 2007, Michael Wu <flamingice@sourmilk.net> * Copyright 2007-2010, Intel Corporation - * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright(c) 2015-2017 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -741,46 +741,43 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, ieee80211_agg_start_txq(sta, tid, true); } -void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) +void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid, + struct tid_ampdu_tx *tid_tx) { - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; - struct sta_info *sta; - struct tid_ampdu_tx *tid_tx; - trace_api_start_tx_ba_cb(sdata, ra, tid); + if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))) + return; + + if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) + ieee80211_agg_tx_operational(local, sta, tid); +} + +static struct tid_ampdu_tx * +ieee80211_lookup_tid_tx(struct ieee80211_sub_if_data *sdata, + const u8 *ra, u16 tid, struct sta_info **sta) +{ + struct tid_ampdu_tx *tid_tx; if (tid >= IEEE80211_NUM_TIDS) { ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", tid, IEEE80211_NUM_TIDS); - return; + return NULL; } - mutex_lock(&local->sta_mtx); - sta = sta_info_get_bss(sdata, ra); - if (!sta) { - mutex_unlock(&local->sta_mtx); + *sta = sta_info_get_bss(sdata, ra); + if (!*sta) { ht_dbg(sdata, "Could not find station: %pM\n", ra); - return; + return NULL; } - mutex_lock(&sta->ampdu_mlme.mtx); - tid_tx = rcu_dereference_protected_tid_tx(sta, tid); + tid_tx = rcu_dereference((*sta)->ampdu_mlme.tid_tx[tid]); - if (WARN_ON(!tid_tx)) { + if (WARN_ON(!tid_tx)) ht_dbg(sdata, "addBA was not requested!\n"); - goto unlock; - } - if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))) - goto unlock; - - if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) - ieee80211_agg_tx_operational(local, sta, tid); - - unlock: - mutex_unlock(&sta->ampdu_mlme.mtx); - mutex_unlock(&local->sta_mtx); + return tid_tx; } void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, @@ -788,19 +785,20 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, { struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_local *local = sdata->local; - struct ieee80211_ra_tid *ra_tid; - struct sk_buff *skb = dev_alloc_skb(0); + struct sta_info *sta; + struct tid_ampdu_tx *tid_tx; - if (unlikely(!skb)) - return; + trace_api_start_tx_ba_cb(sdata, ra, tid); - ra_tid = (struct ieee80211_ra_tid *) &skb->cb; - memcpy(&ra_tid->ra, ra, ETH_ALEN); - ra_tid->tid = tid; + rcu_read_lock(); + tid_tx = ieee80211_lookup_tid_tx(sdata, ra, tid, &sta); + if (!tid_tx) + goto out; - skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_START; - skb_queue_tail(&sdata->skb_queue, skb); - ieee80211_queue_work(&local->hw, &sdata->work); + set_bit(HT_AGG_STATE_START_CB, &tid_tx->state); + ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work); + out: + rcu_read_unlock(); } EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); @@ -860,37 +858,18 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) } EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); -void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) +void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid, + struct tid_ampdu_tx *tid_tx) { - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); - struct ieee80211_local *local = sdata->local; - struct sta_info *sta; - struct tid_ampdu_tx *tid_tx; + struct ieee80211_sub_if_data *sdata = sta->sdata; bool send_delba = false; - trace_api_stop_tx_ba_cb(sdata, ra, tid); - - if (tid >= IEEE80211_NUM_TIDS) { - ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", - tid, IEEE80211_NUM_TIDS); - return; - } - - ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n", ra, tid); - - mutex_lock(&local->sta_mtx); - - sta = sta_info_get_bss(sdata, ra); - if (!sta) { - ht_dbg(sdata, "Could not find station: %pM\n", ra); - goto unlock; - } + ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n", + sta->sta.addr, tid); - mutex_lock(&sta->ampdu_mlme.mtx); spin_lock_bh(&sta->lock); - tid_tx = rcu_dereference_protected_tid_tx(sta, tid); - if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { + if (!test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { ht_dbg(sdata, "unexpected callback to A-MPDU stop for %pM tid %d\n", sta->sta.addr, tid); @@ -906,12 +885,8 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) spin_unlock_bh(&sta->lock); if (send_delba) - ieee80211_send_delba(sdata, ra, tid, + ieee80211_send_delba(sdata, sta->sta.addr, tid, WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); - - mutex_unlock(&sta->ampdu_mlme.mtx); - unlock: - mutex_unlock(&local->sta_mtx); } void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, @@ -919,19 +894,20 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, { struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_local *local = sdata->local; - struct ieee80211_ra_tid *ra_tid; - struct sk_buff *skb = dev_alloc_skb(0); + struct sta_info *sta; + struct tid_ampdu_tx *tid_tx; - if (unlikely(!skb)) - return; + trace_api_stop_tx_ba_cb(sdata, ra, tid); - ra_tid = (struct ieee80211_ra_tid *) &skb->cb; - memcpy(&ra_tid->ra, ra, ETH_ALEN); - ra_tid->tid = tid; + rcu_read_lock(); + tid_tx = ieee80211_lookup_tid_tx(sdata, ra, tid, &sta); + if (!tid_tx) + goto out; - skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_STOP; - skb_queue_tail(&sdata->skb_queue, skb); - ieee80211_queue_work(&local->hw, &sdata->work); + set_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state); + ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work); + out: + rcu_read_unlock(); } EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe); diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index f4a528773563..6ca5442b1e03 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -7,6 +7,7 @@ * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> * Copyright 2007, Michael Wu <flamingice@sourmilk.net> * Copyright 2007-2010, Intel Corporation + * Copyright 2017 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -289,8 +290,6 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, { int i; - cancel_work_sync(&sta->ampdu_mlme.work); - for (i = 0; i < IEEE80211_NUM_TIDS; i++) { __ieee80211_stop_tx_ba_session(sta, i, reason); __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, @@ -298,6 +297,9 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, reason != AGG_STOP_DESTROY_STA && reason != AGG_STOP_PEER_REQUEST); } + + /* stopping might queue the work again - so cancel only afterwards */ + cancel_work_sync(&sta->ampdu_mlme.work); } void ieee80211_ba_session_work(struct work_struct *work) @@ -352,10 +354,16 @@ void ieee80211_ba_session_work(struct work_struct *work) spin_unlock_bh(&sta->lock); tid_tx = rcu_dereference_protected_tid_tx(sta, tid); - if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP, - &tid_tx->state)) + if (!tid_tx) + continue; + + if (test_and_clear_bit(HT_AGG_STATE_START_CB, &tid_tx->state)) + ieee80211_start_tx_ba_cb(sta, tid, tid_tx); + if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state)) ___ieee80211_stop_tx_ba_session(sta, tid, AGG_STOP_LOCAL_REQUEST); + if (test_and_clear_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state)) + ieee80211_stop_tx_ba_cb(sta, tid, tid_tx); } mutex_unlock(&sta->ampdu_mlme.mtx); } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f8f6c148f554..665501ac358f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1036,8 +1036,6 @@ struct ieee80211_rx_agg { enum sdata_queue_type { IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, - IEEE80211_SDATA_QUEUE_AGG_START = 1, - IEEE80211_SDATA_QUEUE_AGG_STOP = 2, IEEE80211_SDATA_QUEUE_RX_AGG_START = 3, IEEE80211_SDATA_QUEUE_RX_AGG_STOP = 4, }; @@ -1427,12 +1425,6 @@ ieee80211_get_sband(struct ieee80211_sub_if_data *sdata) return local->hw.wiphy->bands[band]; } -/* this struct represents 802.11n's RA/TID combination */ -struct ieee80211_ra_tid { - u8 ra[ETH_ALEN]; - u16 tid; -}; - /* this struct holds the value parsing from channel switch IE */ struct ieee80211_csa_ie { struct cfg80211_chan_def chandef; @@ -1794,8 +1786,10 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, enum ieee80211_agg_stop_reason reason); int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, enum ieee80211_agg_stop_reason reason); -void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); -void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); +void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid, + struct tid_ampdu_tx *tid_tx); +void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid, + struct tid_ampdu_tx *tid_tx); void ieee80211_ba_session_work(struct work_struct *work); void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 3bd5b81f5d81..8fae1a72e6a7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1237,7 +1237,6 @@ static void ieee80211_iface_work(struct work_struct *work) struct ieee80211_local *local = sdata->local; struct sk_buff *skb; struct sta_info *sta; - struct ieee80211_ra_tid *ra_tid; struct ieee80211_rx_agg *rx_agg; if (!ieee80211_sdata_running(sdata)) @@ -1253,15 +1252,7 @@ static void ieee80211_iface_work(struct work_struct *work) while ((skb = skb_dequeue(&sdata->skb_queue))) { struct ieee80211_mgmt *mgmt = (void *)skb->data; - if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) { - ra_tid = (void *)&skb->cb; - ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra, - ra_tid->tid); - } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) { - ra_tid = (void *)&skb->cb; - ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, - ra_tid->tid); - } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) { + if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) { rx_agg = (void *)&skb->cb; mutex_lock(&local->sta_mtx); sta = sta_info_get_bss(sdata, rx_agg->addr); diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 5609cacb20d5..ea0747d6a6da 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -116,6 +116,8 @@ enum ieee80211_sta_info_flags { #define HT_AGG_STATE_STOPPING 3 #define HT_AGG_STATE_WANT_START 4 #define HT_AGG_STATE_WANT_STOP 5 +#define HT_AGG_STATE_START_CB 6 +#define HT_AGG_STATE_STOP_CB 7 enum ieee80211_agg_stop_reason { AGG_STOP_DECLINED, diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 257ec66009da..7b05fd1497ce 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -1418,7 +1418,7 @@ static void mpls_ifup(struct net_device *dev, unsigned int flags) continue; alive++; nh_flags &= ~flags; - WRITE_ONCE(nh->nh_flags, flags); + WRITE_ONCE(nh->nh_flags, nh_flags); } endfor_nexthops(rt); WRITE_ONCE(rt->rt_nhn_alive, alive); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 9799a50bc604..a8be9b72e6cd 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -890,8 +890,13 @@ restart: } out: local_bh_enable(); - if (last) + if (last) { + /* nf ct hash resize happened, now clear the leftover. */ + if ((struct nf_conn *)cb->args[1] == last) + cb->args[1] = 0; + nf_ct_put(last); + } while (i) { i--; diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 13875d599a85..1c5b14a6cab3 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -512,16 +512,19 @@ static int sctp_error(struct net *net, struct nf_conn *tpl, struct sk_buff *skb, u8 pf, unsigned int hooknum) { const struct sctphdr *sh; - struct sctphdr _sctph; const char *logmsg; - sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph); - if (!sh) { + if (skb->len < dataoff + sizeof(struct sctphdr)) { logmsg = "nf_ct_sctp: short packet "; goto out_invalid; } if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && skb->ip_summed == CHECKSUM_NONE) { + if (!skb_make_writable(skb, dataoff + sizeof(struct sctphdr))) { + logmsg = "nf_ct_sctp: failed to read header "; + goto out_invalid; + } + sh = (const struct sctphdr *)(skb->data + dataoff); if (sh->checksum != sctp_compute_cksum(skb, dataoff)) { logmsg = "nf_ct_sctp: bad CRC "; goto out_invalid; diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index ef0be325a0c6..6c72922d20ca 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c @@ -566,7 +566,7 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data) * Else, when the conntrack is destoyed, nf_nat_cleanup_conntrack() * will delete entry from already-freed table. */ - ct->status &= ~IPS_NAT_DONE_MASK; + clear_bit(IPS_SRC_NAT_DONE_BIT, &ct->status); rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource, nf_nat_bysource_params); diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c index e97e2fb53f0a..fbdbaa00dd5f 100644 --- a/net/netfilter/nft_set_rbtree.c +++ b/net/netfilter/nft_set_rbtree.c @@ -116,17 +116,17 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, else if (d > 0) p = &parent->rb_right; else { - if (nft_set_elem_active(&rbe->ext, genmask)) { - if (nft_rbtree_interval_end(rbe) && - !nft_rbtree_interval_end(new)) - p = &parent->rb_left; - else if (!nft_rbtree_interval_end(rbe) && - nft_rbtree_interval_end(new)) - p = &parent->rb_right; - else { - *ext = &rbe->ext; - return -EEXIST; - } + if (nft_rbtree_interval_end(rbe) && + !nft_rbtree_interval_end(new)) { + p = &parent->rb_left; + } else if (!nft_rbtree_interval_end(rbe) && + nft_rbtree_interval_end(new)) { + p = &parent->rb_right; + } else if (nft_set_elem_active(&rbe->ext, genmask)) { + *ext = &rbe->ext; + return -EEXIST; + } else { + p = &parent->rb_left; } } } diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c index 24fedd4b117e..03f6b5840764 100644 --- a/net/sunrpc/xprtrdma/backchannel.c +++ b/net/sunrpc/xprtrdma/backchannel.c @@ -119,11 +119,9 @@ int xprt_rdma_bc_setup(struct rpc_xprt *xprt, unsigned int reqs) for (i = 0; i < (reqs << 1); i++) { rqst = kzalloc(sizeof(*rqst), GFP_KERNEL); - if (!rqst) { - pr_err("RPC: %s: Failed to create bc rpc_rqst\n", - __func__); + if (!rqst) goto out_free; - } + dprintk("RPC: %s: new rqst %p\n", __func__, rqst); rqst->rq_xprt = &r_xprt->rx_xprt; diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 16aff8ddc16f..d5b54c020dec 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -2432,7 +2432,12 @@ static void xs_tcp_setup_socket(struct work_struct *work) case -ENETUNREACH: case -EADDRINUSE: case -ENOBUFS: - /* retry with existing socket, after a delay */ + /* + * xs_tcp_force_close() wakes tasks with -EIO. + * We need to wake them first to ensure the + * correct error code. + */ + xprt_wake_pending_tasks(xprt, status); xs_tcp_force_close(xprt); goto out; } diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index 9ca667bcaee9..594c55541b16 100755 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright 2008, Intel Corporation # diff --git a/scripts/checkincludes.pl b/scripts/checkincludes.pl index 381c018a4612..ce9edefd6e0b 100755 --- a/scripts/checkincludes.pl +++ b/scripts/checkincludes.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # # checkincludes: find/remove files included more than once # diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4b9569fa931b..3465a7c5a154 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # (c) 2001, Dave Jones. (the file handling bit) # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) @@ -6,6 +6,7 @@ # Licensed under the terms of the GNU GPL License version 2 use strict; +use warnings; use POSIX; use File::Basename; use Cwd 'abs_path'; diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index 9d37aa4faf5c..7f4c41717e26 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Check the stack usage of functions # diff --git a/scripts/checkversion.pl b/scripts/checkversion.pl index 5e490a8ceca5..8b4f205234b5 100755 --- a/scripts/checkversion.pl +++ b/scripts/checkversion.pl @@ -1,4 +1,4 @@ -#! /usr/bin/perl +#! /usr/bin/env perl # # checkversion find uses of LINUX_VERSION_CODE or KERNEL_VERSION # without including <linux/version.h>, or cases of diff --git a/scripts/cleanfile b/scripts/cleanfile index cefd29e52298..72e3755327ae 100755 --- a/scripts/cleanfile +++ b/scripts/cleanfile @@ -1,9 +1,10 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # Clean a text file -- or directory of text files -- of stealth whitespace. # WARNING: this can be a highly destructive operation. Use with caution. # +use warnings; use bytes; use File::Basename; diff --git a/scripts/cleanpatch b/scripts/cleanpatch index 9680d03ad2b8..3e5a2303dc0e 100755 --- a/scripts/cleanpatch +++ b/scripts/cleanpatch @@ -1,9 +1,10 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # Clean a patch file -- or directory of patch files -- of stealth whitespace. # WARNING: this can be a highly destructive operation. Use with caution. # +use warnings; use bytes; use File::Basename; diff --git a/scripts/dtc/dt_to_config b/scripts/dtc/dt_to_config index 9a248b505c58..5dfd1bff351f 100755 --- a/scripts/dtc/dt_to_config +++ b/scripts/dtc/dt_to_config @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright 2016 by Frank Rowand # Copyright 2016 by Gaurav Minocha diff --git a/scripts/export_report.pl b/scripts/export_report.pl index 8f79b701de87..68ff426b347c 100755 --- a/scripts/export_report.pl +++ b/scripts/export_report.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # (C) Copyright IBM Corporation 2006. # Released under GPL v2. @@ -7,6 +7,7 @@ # Usage: export_report.pl -k Module.symvers [-o report_file ] -f *.mod.c # +use warnings; use Getopt::Std; use strict; diff --git a/scripts/extract-module-sig.pl b/scripts/extract-module-sig.pl index faac6f2e377f..0f161ea41261 100755 --- a/scripts/extract-module-sig.pl +++ b/scripts/extract-module-sig.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # extract-mod-sig <part> <module-file> # @@ -12,6 +12,7 @@ # -k: Just the key ID # -s: Just the crypto signature or PKCS#7 message # +use warnings; use strict; die "Format: $0 -[0adnks] module-file >out\n" diff --git a/scripts/extract-sys-certs.pl b/scripts/extract-sys-certs.pl index 8227ca10a494..2aa873b944e0 100755 --- a/scripts/extract-sys-certs.pl +++ b/scripts/extract-sys-certs.pl @@ -1,5 +1,6 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # +use warnings; use strict; use Math::BigInt; use Fcntl "SEEK_SET"; diff --git a/scripts/extract_xc3028.pl b/scripts/extract_xc3028.pl index 47877deae6d7..61d9b256c658 100755 --- a/scripts/extract_xc3028.pl +++ b/scripts/extract_xc3028.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright (c) Mauro Carvalho Chehab <mchehab@infradead.org> # Released under GPLv2 diff --git a/scripts/get_dvb_firmware b/scripts/get_dvb_firmware index 1a0a04125f71..f3f230225aba 100755 --- a/scripts/get_dvb_firmware +++ b/scripts/get_dvb_firmware @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # DVB firmware extractor # # (c) 2004 Andrew de Quincey diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 633f2dd3de27..3bd5f4f30235 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # (c) 2007, Joe Perches <joe@perches.com> # created from checkpatch.pl # @@ -10,6 +10,7 @@ # # Licensed under the terms of the GNU GPL License version 2 +use warnings; use strict; my $P = $0; diff --git a/scripts/headerdep.pl b/scripts/headerdep.pl index 8dd019bc5a73..86ebb9ee7570 100755 --- a/scripts/headerdep.pl +++ b/scripts/headerdep.pl @@ -1,4 +1,4 @@ -#! /usr/bin/perl +#! /usr/bin/env perl # # Detect cycles in the header file dependency graph # Vegard Nossum <vegardno@ifi.uio.no> diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl index 8b2da054cdc3..3091e4ee6ee1 100755 --- a/scripts/headers_check.pl +++ b/scripts/headers_check.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # headers_check.pl execute a number of trivial consistency checks # @@ -18,6 +18,7 @@ # # 3) Check for leaked CONFIG_ symbols +use warnings; use strict; use File::Basename; diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index b8c7b29affc5..a2e83ab17de3 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # Copyright 2005-2009 - Steven Rostedt # Licensed under the terms of the GNU GPL License version 2 @@ -42,6 +42,7 @@ # mv config_strip .config # make oldconfig # +use warnings; use strict; use Getopt::Long; diff --git a/scripts/kernel-doc b/scripts/kernel-doc index a26a5f2dce39..7b0a8f01fed5 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1,5 +1,6 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl +use warnings; use strict; ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## diff --git a/scripts/kernel-doc-xml-ref b/scripts/kernel-doc-xml-ref index 104a5a5ba2c8..e3b24bfc804c 100755 --- a/scripts/kernel-doc-xml-ref +++ b/scripts/kernel-doc-xml-ref @@ -1,5 +1,6 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl +use warnings; use strict; ## Copyright (C) 2015 Intel Corporation ## diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl index c21d16328d3f..70dcfb6b3de1 100755 --- a/scripts/markup_oops.pl +++ b/scripts/markup_oops.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl use File::Basename; use Math::BigInt; diff --git a/scripts/namespace.pl b/scripts/namespace.pl index 9f3c9d47a4a5..729c547fc9e1 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # namespace.pl. Mon Aug 30 2004 # @@ -62,7 +62,7 @@ # result. # -require 5; # at least perl 5 +use warnings; use strict; use File::Find; diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl index 6943fa7cc95b..f23d7be94394 100755 --- a/scripts/profile2linkerlist.pl +++ b/scripts/profile2linkerlist.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # # Takes a (sorted) output of readprofile and turns it into a list suitable for diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 1633c3e6c0b9..2033af758173 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # (c) 2008, Steven Rostedt <srostedt@redhat.com> # Licensed under the terms of the GNU GPL License version 2 # @@ -106,6 +106,7 @@ # 9) Move the result back to the original object. # +use warnings; use strict; my $P = $0; diff --git a/scripts/stackdelta b/scripts/stackdelta index 48eabf2f48f8..20a79f19a111 100755 --- a/scripts/stackdelta +++ b/scripts/stackdelta @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Read two files produced by the stackusage script, and show the # delta between them. diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c index dc48eedea92e..26ed23b18b77 100644 --- a/sound/usb/mixer_us16x08.c +++ b/sound/usb/mixer_us16x08.c @@ -698,16 +698,18 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, struct snd_usb_audio *chip = elem->head.mixer->chip; struct snd_us16x08_meter_store *store = elem->private_data; u8 meter_urb[64]; - char tmp[sizeof(mix_init_msg2)] = {0}; switch (kcontrol->private_value) { - case 0: - snd_us16x08_send_urb(chip, (char *)mix_init_msg1, - sizeof(mix_init_msg1)); + case 0: { + char tmp[sizeof(mix_init_msg1)]; + + memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1)); + snd_us16x08_send_urb(chip, tmp, 4); snd_us16x08_recv_urb(chip, meter_urb, sizeof(meter_urb)); kcontrol->private_value++; break; + } case 1: snd_us16x08_recv_urb(chip, meter_urb, sizeof(meter_urb)); @@ -718,15 +720,18 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, sizeof(meter_urb)); kcontrol->private_value++; break; - case 3: + case 3: { + char tmp[sizeof(mix_init_msg2)]; + memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2)); tmp[2] = snd_get_meter_comp_index(store); - snd_us16x08_send_urb(chip, tmp, sizeof(mix_init_msg2)); + snd_us16x08_send_urb(chip, tmp, 10); snd_us16x08_recv_urb(chip, meter_urb, sizeof(meter_urb)); kcontrol->private_value = 0; break; } + } for (set = 0; set < 6; set++) get_meter_levels_from_urb(set, store, meter_urb); @@ -1135,7 +1140,7 @@ static const struct snd_us16x08_control_params eq_controls[] = { .control_id = SND_US16X08_ID_EQLOWMIDWIDTH, .type = USB_MIXER_U8, .num_channels = 16, - .name = "EQ MidQLow Q", + .name = "EQ MidLow Q", }, { /* EQ mid high gain */ .kcontrol_new = &snd_us16x08_eq_gain_ctl, |