diff options
Diffstat (limited to 'arch/arm')
74 files changed, 780 insertions, 619 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cf4c0c99aa25..4b62f4caf0ce 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1,8 +1,8 @@ config ARM bool default y - select ARCH_BINFMT_ELF_RANDOMIZE_PIE select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE + select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAS_GCOV_PROFILE_ALL @@ -286,6 +286,11 @@ config GENERIC_BUG def_bool y depends on BUG +config PGTABLE_LEVELS + int + default 3 if ARM_LPAE + default 2 + source "init/Kconfig" source "kernel/Kconfig.freezer" diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 1943fc333e7c..8a099bc10c1e 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -15,7 +15,7 @@ / { compatible = "ti,am4372", "ti,am43"; - interrupt-parent = <&gic>; + interrupt-parent = <&wakeupgen>; aliases { @@ -48,6 +48,15 @@ #interrupt-cells = <3>; reg = <0x48241000 0x1000>, <0x48240100 0x0100>; + interrupt-parent = <&gic>; + }; + + wakeupgen: interrupt-controller@48281000 { + compatible = "ti,omap4-wugen-mpu"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x48281000 0x1000>; + interrupt-parent = <&gic>; }; l2-cache-controller@48242000 { diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts index f84d9715a4a9..26956cb50835 100644 --- a/arch/arm/boot/dts/am437x-gp-evm.dts +++ b/arch/arm/boot/dts/am437x-gp-evm.dts @@ -352,7 +352,6 @@ reg = <0x24>; compatible = "ti,tps65218"; interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */ - interrupt-parent = <&gic>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts index 832d24318f62..8ae29c955c11 100644 --- a/arch/arm/boot/dts/am437x-sk-evm.dts +++ b/arch/arm/boot/dts/am437x-sk-evm.dts @@ -392,7 +392,6 @@ tps@24 { compatible = "ti,tps65218"; reg = <0x24>; - interrupt-parent = <&gic>; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index 257c099c347e..1d7109196872 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -369,7 +369,6 @@ reg = <0x24>; compatible = "ti,tps65218"; interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */ - interrupt-parent = <&gic>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index 6463f9ef2b54..bd48dba16748 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts @@ -454,7 +454,6 @@ mcp_rtc: rtc@6f { compatible = "microchip,mcp7941x"; reg = <0x6f>; - interrupt-parent = <&gic>; interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_LOW>; /* IRQ_SYS_1N */ pinctrl-names = "default"; @@ -477,7 +476,7 @@ &uart3 { status = "okay"; - interrupts-extended = <&gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&crossbar_mpu GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>, <&dra7_pmx_core 0x248>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index 7563d7ce01bb..b1bd06c6c2a8 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -444,7 +444,7 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&uart1_pins>; - interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, <&dra7_pmx_core 0x3e0>; }; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index c4659a979c41..a0afce7ad482 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -13,14 +13,13 @@ #include "skeleton.dtsi" #define MAX_SOURCES 400 -#define DIRECT_IRQ(irq) (MAX_SOURCES + irq) / { #address-cells = <1>; #size-cells = <1>; compatible = "ti,dra7xx"; - interrupt-parent = <&gic>; + interrupt-parent = <&crossbar_mpu>; aliases { i2c0 = &i2c1; @@ -50,18 +49,27 @@ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupt-parent = <&gic>; }; gic: interrupt-controller@48211000 { compatible = "arm,cortex-a15-gic"; interrupt-controller; #interrupt-cells = <3>; - arm,routable-irqs = <192>; reg = <0x48211000 0x1000>, <0x48212000 0x1000>, <0x48214000 0x2000>, <0x48216000 0x2000>; interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + interrupt-parent = <&gic>; + }; + + wakeupgen: interrupt-controller@48281000 { + compatible = "ti,omap5-wugen-mpu", "ti,omap4-wugen-mpu"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x48281000 0x1000>; + interrupt-parent = <&gic>; }; /* @@ -91,8 +99,8 @@ ti,hwmods = "l3_main_1", "l3_main_2"; reg = <0x44000000 0x1000000>, <0x45000000 0x1000>; - interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI DIRECT_IRQ(10) IRQ_TYPE_LEVEL_HIGH>; + interrupts-extended = <&crossbar_mpu GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, + <&wakeupgen GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; prm: prm@4ae06000 { compatible = "ti,dra7-prm"; @@ -344,7 +352,7 @@ uart1: serial@4806a000 { compatible = "ti,omap4-uart"; reg = <0x4806a000 0x100>; - interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; + interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart1"; clock-frequency = <48000000>; status = "disabled"; @@ -355,7 +363,7 @@ uart2: serial@4806c000 { compatible = "ti,omap4-uart"; reg = <0x4806c000 0x100>; - interrupts-extended = <&gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart2"; clock-frequency = <48000000>; status = "disabled"; @@ -366,7 +374,7 @@ uart3: serial@48020000 { compatible = "ti,omap4-uart"; reg = <0x48020000 0x100>; - interrupts-extended = <&gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart3"; clock-frequency = <48000000>; status = "disabled"; @@ -377,7 +385,7 @@ uart4: serial@4806e000 { compatible = "ti,omap4-uart"; reg = <0x4806e000 0x100>; - interrupts-extended = <&gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart4"; clock-frequency = <48000000>; status = "disabled"; @@ -388,7 +396,7 @@ uart5: serial@48066000 { compatible = "ti,omap4-uart"; reg = <0x48066000 0x100>; - interrupts-extended = <&gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart5"; clock-frequency = <48000000>; status = "disabled"; @@ -399,7 +407,7 @@ uart6: serial@48068000 { compatible = "ti,omap4-uart"; reg = <0x48068000 0x100>; - interrupts-extended = <&gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart6"; clock-frequency = <48000000>; status = "disabled"; @@ -410,7 +418,7 @@ uart7: serial@48420000 { compatible = "ti,omap4-uart"; reg = <0x48420000 0x100>; - interrupts-extended = <&gic GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart7"; clock-frequency = <48000000>; status = "disabled"; @@ -419,7 +427,7 @@ uart8: serial@48422000 { compatible = "ti,omap4-uart"; reg = <0x48422000 0x100>; - interrupts-extended = <&gic GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart8"; clock-frequency = <48000000>; status = "disabled"; @@ -428,7 +436,7 @@ uart9: serial@48424000 { compatible = "ti,omap4-uart"; reg = <0x48424000 0x100>; - interrupts-extended = <&gic GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart9"; clock-frequency = <48000000>; status = "disabled"; @@ -437,7 +445,7 @@ uart10: serial@4ae2b000 { compatible = "ti,omap4-uart"; reg = <0x4ae2b000 0x100>; - interrupts-extended = <&gic GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart10"; clock-frequency = <48000000>; status = "disabled"; @@ -1335,9 +1343,12 @@ status = "disabled"; }; - crossbar_mpu: crossbar@4a020000 { + crossbar_mpu: crossbar@4a002a48 { compatible = "ti,irq-crossbar"; reg = <0x4a002a48 0x130>; + interrupt-controller; + interrupt-parent = <&wakeupgen>; + #interrupt-cells = <3>; ti,max-irqs = <160>; ti,max-crossbar-sources = <MAX_SOURCES>; ti,reg-size = <2>; diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index 40ed539ce474..daf28110d487 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -158,7 +158,6 @@ pinctrl-0 = <&tps65917_pins_default>; interrupts = <GIC_SPI 2 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */ - interrupt-parent = <&gic>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/dra72x.dtsi b/arch/arm/boot/dts/dra72x.dtsi index e5a3d23a3df1..f7fb0d0ef25a 100644 --- a/arch/arm/boot/dts/dra72x.dtsi +++ b/arch/arm/boot/dts/dra72x.dtsi @@ -25,6 +25,7 @@ pmu { compatible = "arm,cortex-a15-pmu"; - interrupts = <GIC_SPI DIRECT_IRQ(131) IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&wakeupgen>; + interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; }; }; diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi index 10173fab1a15..00eeed789b4b 100644 --- a/arch/arm/boot/dts/dra74x.dtsi +++ b/arch/arm/boot/dts/dra74x.dtsi @@ -41,8 +41,9 @@ pmu { compatible = "arm,cortex-a15-pmu"; - interrupts = <GIC_SPI DIRECT_IRQ(131) IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI DIRECT_IRQ(132) IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&wakeupgen>; + interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; }; ocp { diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi index ac6b0ae42caf..14ab515aa83c 100644 --- a/arch/arm/boot/dts/exynos3250.dtsi +++ b/arch/arm/boot/dts/exynos3250.dtsi @@ -131,6 +131,9 @@ pmu_system_controller: system-controller@10020000 { compatible = "samsung,exynos3250-pmu", "syscon"; reg = <0x10020000 0x4000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; }; mipi_phy: video-phy@10020710 { @@ -185,6 +188,7 @@ compatible = "samsung,exynos3250-rtc"; reg = <0x10070000 0x100>; interrupts = <0 73 0>, <0 74 0>; + interrupt-parent = <&pmu_system_controller>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index 77ea547768f4..e20cdc24c3bb 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -154,6 +154,9 @@ pmu_system_controller: system-controller@10020000 { compatible = "samsung,exynos4210-pmu", "syscon"; reg = <0x10020000 0x4000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; }; dsi_0: dsi@11C80000 { @@ -266,6 +269,7 @@ rtc@10070000 { compatible = "samsung,s3c6410-rtc"; reg = <0x10070000 0x100>; + interrupt-parent = <&pmu_system_controller>; interrupts = <0 44 0>, <0 45 0>; clocks = <&clock CLK_RTC>; clock-names = "rtc"; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index adbde1adad95..77f656eb8e6b 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -205,6 +205,9 @@ clock-names = "clkout16"; clocks = <&clock CLK_FIN_PLL>; #clock-cells = <1>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; }; sysreg_system_controller: syscon@10050000 { @@ -241,6 +244,7 @@ rtc: rtc@101E0000 { clocks = <&clock CLK_RTC>; clock-names = "rtc"; + interrupt-parent = <&pmu_system_controller>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index c0e98cf3514f..b3d2d53820e3 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -327,6 +327,7 @@ rtc: rtc@101E0000 { clocks = <&clock CLK_RTC>; clock-names = "rtc"; + interrupt-parent = <&pmu_system_controller>; status = "disabled"; }; @@ -770,6 +771,9 @@ clock-names = "clkout16"; clocks = <&clock CLK_FIN_PLL>; #clock-cells = <1>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; }; sysreg_system_controller: syscon@10050000 { diff --git a/arch/arm/boot/dts/omap4-duovero.dtsi b/arch/arm/boot/dts/omap4-duovero.dtsi index e860ccd9d09c..f2a94fa62552 100644 --- a/arch/arm/boot/dts/omap4-duovero.dtsi +++ b/arch/arm/boot/dts/omap4-duovero.dtsi @@ -173,14 +173,12 @@ twl: twl@48 { reg = <0x48>; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */ - interrupt-parent = <&gic>; }; twl6040: twl@4b { compatible = "ti,twl6040"; reg = <0x4b>; interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */ - interrupt-parent = <&gic>; ti,audpwron-gpio = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* gpio_160 */ vio-supply = <&v1v8>; diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi index 150513506c19..7c15fb2e2fe4 100644 --- a/arch/arm/boot/dts/omap4-panda-common.dtsi +++ b/arch/arm/boot/dts/omap4-panda-common.dtsi @@ -372,7 +372,6 @@ reg = <0x48>; /* IRQ# = 7 */ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */ - interrupt-parent = <&gic>; }; twl6040: twl@4b { @@ -384,7 +383,6 @@ /* IRQ# = 119 */ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */ - interrupt-parent = <&gic>; ti,audpwron-gpio = <&gpio4 31 GPIO_ACTIVE_HIGH>; /* gpio line 127 */ vio-supply = <&v1v8>; @@ -479,17 +477,17 @@ }; &uart2 { - interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH + interrupts-extended = <&wakeupgen GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH &omap4_pmx_core OMAP4_UART2_RX>; }; &uart3 { - interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH + interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH &omap4_pmx_core OMAP4_UART3_RX>; }; &uart4 { - interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH + interrupts-extended = <&wakeupgen GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH &omap4_pmx_core OMAP4_UART4_RX>; }; diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index 3e1da43068f6..8aca8dae968a 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -363,7 +363,6 @@ reg = <0x48>; /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */ - interrupt-parent = <&gic>; }; twl6040: twl@4b { @@ -375,7 +374,6 @@ /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */ - interrupt-parent = <&gic>; ti,audpwron-gpio = <&gpio4 31 0>; /* gpio line 127 */ vio-supply = <&v1v8>; @@ -570,21 +568,21 @@ }; &uart2 { - interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH + interrupts-extended = <&wakeupgen GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH &omap4_pmx_core OMAP4_UART2_RX>; pinctrl-names = "default"; pinctrl-0 = <&uart2_pins>; }; &uart3 { - interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH + interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH &omap4_pmx_core OMAP4_UART3_RX>; pinctrl-names = "default"; pinctrl-0 = <&uart3_pins>; }; &uart4 { - interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH + interrupts-extended = <&wakeupgen GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH &omap4_pmx_core OMAP4_UART4_RX>; pinctrl-names = "default"; pinctrl-0 = <&uart4_pins>; diff --git a/arch/arm/boot/dts/omap4-var-som-om44.dtsi b/arch/arm/boot/dts/omap4-var-som-om44.dtsi index 062701e1a898..a4f1ba2e1903 100644 --- a/arch/arm/boot/dts/omap4-var-som-om44.dtsi +++ b/arch/arm/boot/dts/omap4-var-som-om44.dtsi @@ -185,7 +185,6 @@ reg = <0x48>; /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */ - interrupt-parent = <&gic>; }; twl6040: twl@4b { @@ -197,7 +196,6 @@ /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */ - interrupt-parent = <&gic>; ti,audpwron-gpio = <&gpio6 22 0>; /* gpio 182 */ vio-supply = <&v1v8>; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 87401d9f4d8b..f2091d1c9c36 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -14,7 +14,7 @@ / { compatible = "ti,omap4430", "ti,omap4"; - interrupt-parent = <&gic>; + interrupt-parent = <&wakeupgen>; aliases { i2c0 = &i2c1; @@ -56,6 +56,7 @@ #interrupt-cells = <3>; reg = <0x48241000 0x1000>, <0x48240100 0x0100>; + interrupt-parent = <&gic>; }; L2: l2-cache-controller@48242000 { @@ -70,6 +71,15 @@ clocks = <&mpu_periphclk>; reg = <0x48240600 0x20>; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_HIGH)>; + interrupt-parent = <&gic>; + }; + + wakeupgen: interrupt-controller@48281000 { + compatible = "ti,omap4-wugen-mpu"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x48281000 0x1000>; + interrupt-parent = <&gic>; }; /* @@ -319,7 +329,7 @@ uart2: serial@4806c000 { compatible = "ti,omap4-uart"; reg = <0x4806c000 0x100>; - interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart2"; clock-frequency = <48000000>; }; @@ -327,7 +337,7 @@ uart3: serial@48020000 { compatible = "ti,omap4-uart"; reg = <0x48020000 0x100>; - interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart3"; clock-frequency = <48000000>; }; @@ -335,7 +345,7 @@ uart4: serial@4806e000 { compatible = "ti,omap4-uart"; reg = <0x4806e000 0x100>; - interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart4"; clock-frequency = <48000000>; }; diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts index b54b271e153b..61ad2ea34720 100644 --- a/arch/arm/boot/dts/omap5-cm-t54.dts +++ b/arch/arm/boot/dts/omap5-cm-t54.dts @@ -412,7 +412,6 @@ palmas: palmas@48 { compatible = "ti,palmas"; interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */ - interrupt-parent = <&gic>; reg = <0x48>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts index 159720d6c956..74777a6e200a 100644 --- a/arch/arm/boot/dts/omap5-uevm.dts +++ b/arch/arm/boot/dts/omap5-uevm.dts @@ -311,7 +311,6 @@ palmas: palmas@48 { compatible = "ti,palmas"; interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */ - interrupt-parent = <&gic>; reg = <0x48>; interrupt-controller; #interrupt-cells = <2>; @@ -521,7 +520,6 @@ pinctrl-0 = <&twl6040_pins>; interrupts = <GIC_SPI 119 IRQ_TYPE_NONE>; /* IRQ_SYS_2N cascaded to gic */ - interrupt-parent = <&gic>; ti,audpwron-gpio = <&gpio5 13 0>; /* gpio line 141 */ vio-supply = <&smps7_reg>; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 4a485b63a141..77b5f70d0ebc 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -18,7 +18,7 @@ #size-cells = <1>; compatible = "ti,omap5"; - interrupt-parent = <&gic>; + interrupt-parent = <&wakeupgen>; aliases { i2c0 = &i2c1; @@ -79,6 +79,7 @@ <GIC_PPI 14 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>; + interrupt-parent = <&gic>; }; pmu { @@ -95,6 +96,15 @@ <0x48212000 0x1000>, <0x48214000 0x2000>, <0x48216000 0x2000>; + interrupt-parent = <&gic>; + }; + + wakeupgen: interrupt-controller@48281000 { + compatible = "ti,omap5-wugen-mpu", "ti,omap4-wugen-mpu"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x48281000 0x1000>; + interrupt-parent = <&gic>; }; /* @@ -458,7 +468,7 @@ uart1: serial@4806a000 { compatible = "ti,omap4-uart"; reg = <0x4806a000 0x100>; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart1"; clock-frequency = <48000000>; }; @@ -466,7 +476,7 @@ uart2: serial@4806c000 { compatible = "ti,omap4-uart"; reg = <0x4806c000 0x100>; - interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart2"; clock-frequency = <48000000>; }; @@ -474,7 +484,7 @@ uart3: serial@48020000 { compatible = "ti,omap4-uart"; reg = <0x48020000 0x100>; - interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart3"; clock-frequency = <48000000>; }; @@ -482,7 +492,7 @@ uart4: serial@4806e000 { compatible = "ti,omap4-uart"; reg = <0x4806e000 0x100>; - interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart4"; clock-frequency = <48000000>; }; @@ -490,7 +500,7 @@ uart5: serial@48066000 { compatible = "ti,omap4-uart"; reg = <0x48066000 0x100>; - interrupts-extended = <&gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart5"; clock-frequency = <48000000>; }; @@ -498,7 +508,7 @@ uart6: serial@48068000 { compatible = "ti,omap4-uart"; reg = <0x48068000 0x100>; - interrupts-extended = <&gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart6"; clock-frequency = <48000000>; }; @@ -883,14 +893,12 @@ usbhsohci: ohci@4a064800 { compatible = "ti,ohci-omap3"; reg = <0x4a064800 0x400>; - interrupt-parent = <&gic>; interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; }; usbhsehci: ehci@4a064c00 { compatible = "ti,ehci-omap"; reg = <0x4a064c00 0x400>; - interrupt-parent = <&gic>; interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; }; }; diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi index ea28ebadab1a..eeb7afecbbe6 100644 --- a/arch/arm/boot/dts/stih416.dtsi +++ b/arch/arm/boot/dts/stih416.dtsi @@ -10,7 +10,7 @@ #include "stih416-clock.dtsi" #include "stih416-pinctrl.dtsi" -#include <dt-bindings/phy/phy-miphy365x.h> +#include <dt-bindings/phy/phy.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/reset-controller/stih416-resets.h> / { @@ -306,7 +306,7 @@ reg = <0xfe380000 0x1000>; interrupts = <GIC_SPI 157 IRQ_TYPE_NONE>; interrupt-names = "hostc"; - phys = <&phy_port0 MIPHY_TYPE_SATA>; + phys = <&phy_port0 PHY_TYPE_SATA>; phy-names = "sata-phy"; resets = <&powerdown STIH416_SATA0_POWERDOWN>, <&softreset STIH416_SATA0_SOFTRESET>; diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 4296b5398bf5..f58a3d9d5f13 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi @@ -8,7 +8,7 @@ / { compatible = "nvidia,tegra114"; - interrupt-parent = <&gic>; + interrupt-parent = <&lic>; host1x@50000000 { compatible = "nvidia,tegra114-host1x", "simple-bus"; @@ -134,6 +134,19 @@ <0x50046000 0x2000>; interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupt-parent = <&gic>; + }; + + lic: interrupt-controller@60004000 { + compatible = "nvidia,tegra114-ictlr", "nvidia,tegra30-ictlr"; + reg = <0x60004000 0x100>, + <0x60004100 0x50>, + <0x60004200 0x50>, + <0x60004300 0x50>, + <0x60004400 0x50>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; }; timer@60005000 { @@ -766,5 +779,6 @@ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupt-parent = <&gic>; }; }; diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 4be06c6ea0c8..db85695aa7aa 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -10,7 +10,7 @@ / { compatible = "nvidia,tegra124"; - interrupt-parent = <&gic>; + interrupt-parent = <&lic>; #address-cells = <2>; #size-cells = <2>; @@ -173,6 +173,7 @@ <0x0 0x50046000 0x0 0x2000>; interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupt-parent = <&gic>; }; gpu@0,57000000 { @@ -190,6 +191,18 @@ status = "disabled"; }; + lic: interrupt-controller@60004000 { + compatible = "nvidia,tegra124-ictlr", "nvidia,tegra30-ictlr"; + reg = <0x0 0x60004000 0x0 0x100>, + <0x0 0x60004100 0x0 0x100>, + <0x0 0x60004200 0x0 0x100>, + <0x0 0x60004300 0x0 0x100>, + <0x0 0x60004400 0x0 0x100>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + }; + timer@0,60005000 { compatible = "nvidia,tegra124-timer", "nvidia,tegra20-timer"; reg = <0x0 0x60005000 0x0 0x400>; @@ -955,5 +968,6 @@ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupt-parent = <&gic>; }; }; diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index e5527f742696..adf6b048d0bb 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -7,7 +7,7 @@ / { compatible = "nvidia,tegra20"; - interrupt-parent = <&intc>; + interrupt-parent = <&lic>; host1x@50000000 { compatible = "nvidia,tegra20-host1x", "simple-bus"; @@ -142,6 +142,7 @@ timer@50040600 { compatible = "arm,cortex-a9-twd-timer"; + interrupt-parent = <&intc>; reg = <0x50040600 0x20>; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; @@ -154,6 +155,7 @@ 0x50040100 0x0100>; interrupt-controller; #interrupt-cells = <3>; + interrupt-parent = <&intc>; }; cache-controller@50043000 { @@ -165,6 +167,17 @@ cache-level = <2>; }; + lic: interrupt-controller@60004000 { + compatible = "nvidia,tegra20-ictlr"; + reg = <0x60004000 0x100>, + <0x60004100 0x50>, + <0x60004200 0x50>, + <0x60004300 0x50>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&intc>; + }; + timer@60005000 { compatible = "nvidia,tegra20-timer"; reg = <0x60005000 0x60>; diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index db4810df142c..60e205a0f63d 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -8,7 +8,7 @@ / { compatible = "nvidia,tegra30"; - interrupt-parent = <&intc>; + interrupt-parent = <&lic>; pcie-controller@00003000 { compatible = "nvidia,tegra30-pcie"; @@ -228,6 +228,7 @@ timer@50040600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x50040600 0x20>; + interrupt-parent = <&intc>; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; clocks = <&tegra_car TEGRA30_CLK_TWD>; @@ -239,6 +240,7 @@ 0x50040100 0x0100>; interrupt-controller; #interrupt-cells = <3>; + interrupt-parent = <&intc>; }; cache-controller@50043000 { @@ -250,6 +252,18 @@ cache-level = <2>; }; + lic: interrupt-controller@60004000 { + compatible = "nvidia,tegra30-ictlr"; + reg = <0x60004000 0x100>, + <0x60004100 0x50>, + <0x60004200 0x50>, + <0x60004300 0x50>, + <0x60004400 0x50>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&intc>; + }; + timer@60005000 { compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer"; reg = <0x60005000 0x400>; diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c index 6eaddc47c43d..37dc0fe1093f 100644 --- a/arch/arm/common/bL_switcher.c +++ b/arch/arm/common/bL_switcher.c @@ -151,8 +151,6 @@ static int bL_switch_to(unsigned int new_cluster_id) unsigned int mpidr, this_cpu, that_cpu; unsigned int ob_mpidr, ob_cpu, ob_cluster, ib_mpidr, ib_cpu, ib_cluster; struct completion inbound_alive; - struct tick_device *tdev; - enum clock_event_mode tdev_mode; long volatile *handshake_ptr; int ipi_nr, ret; @@ -219,13 +217,7 @@ static int bL_switch_to(unsigned int new_cluster_id) /* redirect GIC's SGIs to our counterpart */ gic_migrate_target(bL_gic_id[ib_cpu][ib_cluster]); - tdev = tick_get_device(this_cpu); - if (tdev && !cpumask_equal(tdev->evtdev->cpumask, cpumask_of(this_cpu))) - tdev = NULL; - if (tdev) { - tdev_mode = tdev->evtdev->mode; - clockevents_set_mode(tdev->evtdev, CLOCK_EVT_MODE_SHUTDOWN); - } + tick_suspend_local(); ret = cpu_pm_enter(); @@ -251,11 +243,7 @@ static int bL_switch_to(unsigned int new_cluster_id) ret = cpu_pm_exit(); - if (tdev) { - clockevents_set_mode(tdev->evtdev, tdev_mode); - clockevents_program_event(tdev->evtdev, - tdev->evtdev->next_event, 1); - } + tick_resume_local(); trace_cpu_migrate_finish(ktime_get_real_ns(), ib_mpidr); local_fiq_enable(); diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index afb9cafd3786..c1ff8ab12914 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -125,10 +125,6 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs); extern void elf_set_personality(const struct elf32_hdr *); #define SET_PERSONALITY(ex) elf_set_personality(&(ex)) -struct mm_struct; -extern unsigned long arch_randomize_brk(struct mm_struct *mm); -#define arch_randomize_brk arch_randomize_brk - #ifdef CONFIG_MMU #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 struct linux_binprm; diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h index 70f9b9bfb1f9..5f337dc5c108 100644 --- a/arch/arm/include/asm/jump_label.h +++ b/arch/arm/include/asm/jump_label.h @@ -1,7 +1,7 @@ #ifndef _ASM_ARM_JUMP_LABEL_H #define _ASM_ARM_JUMP_LABEL_H -#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ #include <linux/types.h> @@ -27,8 +27,6 @@ l_yes: return true; } -#endif /* __KERNEL__ */ - typedef u32 jump_label_t; struct jump_entry { @@ -37,4 +35,5 @@ struct jump_entry { jump_label_t key; }; +#endif /* __ASSEMBLY__ */ #endif diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index 816db0bf2dd8..d995821f1698 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -185,6 +185,7 @@ #define HSR_COND (0xfU << HSR_COND_SHIFT) #define FSC_FAULT (0x04) +#define FSC_ACCESS (0x08) #define FSC_PERM (0x0c) /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */ diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 41008cd7c53f..d71607c16601 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -27,6 +27,8 @@ #include <asm/fpstate.h> #include <kvm/arm_arch_timer.h> +#define __KVM_HAVE_ARCH_INTC_INITIALIZED + #if defined(CONFIG_KVM_ARM_MAX_VCPUS) #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS #else @@ -165,19 +167,10 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); +int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); +int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); /* We do not have shadow page tables, hence the empty hooks */ -static inline int kvm_age_hva(struct kvm *kvm, unsigned long start, - unsigned long end) -{ - return 0; -} - -static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) -{ - return 0; -} - static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, unsigned long address) { diff --git a/arch/arm/include/asm/kvm_mmio.h b/arch/arm/include/asm/kvm_mmio.h index 3f83db2f6cf0..d8e90c8cb5fa 100644 --- a/arch/arm/include/asm/kvm_mmio.h +++ b/arch/arm/include/asm/kvm_mmio.h @@ -28,28 +28,6 @@ struct kvm_decode { bool sign_extend; }; -/* - * The in-kernel MMIO emulation code wants to use a copy of run->mmio, - * which is an anonymous type. Use our own type instead. - */ -struct kvm_exit_mmio { - phys_addr_t phys_addr; - u8 data[8]; - u32 len; - bool is_write; - void *private; -}; - -static inline void kvm_prepare_mmio(struct kvm_run *run, - struct kvm_exit_mmio *mmio) -{ - run->mmio.phys_addr = mmio->phys_addr; - run->mmio.len = mmio->len; - run->mmio.is_write = mmio->is_write; - memcpy(run->mmio.data, mmio->data, mmio->len); - run->exit_reason = KVM_EXIT_MMIO; -} - int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run); int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, phys_addr_t fault_ipa); diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h index 90c12e1e695c..0f79e4dec7f9 100644 --- a/arch/arm/include/asm/mach/time.h +++ b/arch/arm/include/asm/mach/time.h @@ -12,8 +12,7 @@ extern void timer_tick(void); -struct timespec; -typedef void (*clock_access_fn)(struct timespec *); +typedef void (*clock_access_fn)(struct timespec64 *); extern int register_persistent_clock(clock_access_fn read_boot, clock_access_fn read_persistent); diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h index 0db25bc32864..2499867dd0d8 100644 --- a/arch/arm/include/uapi/asm/kvm.h +++ b/arch/arm/include/uapi/asm/kvm.h @@ -198,6 +198,9 @@ struct kvm_arch_memory_slot { /* Highest supported SPI, from VGIC_NR_IRQS */ #define KVM_ARM_IRQ_GIC_MAX 127 +/* One single KVM irqchip, ie. the VGIC */ +#define KVM_NR_IRQCHIPS 1 + /* PSCI interface */ #define KVM_PSCI_FN_BASE 0x95c1ba5e #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n)) diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 2d2d6087b9b1..488eaac56028 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -190,7 +190,6 @@ int main(void) DEFINE(VCPU_HxFAR, offsetof(struct kvm_vcpu, arch.fault.hxfar)); DEFINE(VCPU_HPFAR, offsetof(struct kvm_vcpu, arch.fault.hpfar)); DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc)); -#ifdef CONFIG_KVM_ARM_VGIC DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr)); DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr)); @@ -200,14 +199,11 @@ int main(void) DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr)); DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr)); DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); -#ifdef CONFIG_KVM_ARM_TIMER DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl)); DEFINE(VCPU_TIMER_CNTV_CVAL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval)); DEFINE(KVM_TIMER_CNTVOFF, offsetof(struct kvm, arch.timer.cntvoff)); DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled)); -#endif DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); -#endif DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr)); #endif return 0; diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 7fc70ae21185..dc7d0a95bd36 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -648,7 +648,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) * Per-cpu breakpoints are not supported by our stepping * mechanism. */ - if (!bp->hw.bp_target) + if (!bp->hw.target) return -EINVAL; /* diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 0cc7e58c47cc..a66e37e211a9 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -76,7 +76,7 @@ void timer_tick(void) } #endif -static void dummy_clock_access(struct timespec *ts) +static void dummy_clock_access(struct timespec64 *ts) { ts->tv_sec = 0; ts->tv_nsec = 0; @@ -85,12 +85,12 @@ static void dummy_clock_access(struct timespec *ts) static clock_access_fn __read_persistent_clock = dummy_clock_access; static clock_access_fn __read_boot_clock = dummy_clock_access;; -void read_persistent_clock(struct timespec *ts) +void read_persistent_clock64(struct timespec64 *ts) { __read_persistent_clock(ts); } -void read_boot_clock(struct timespec *ts) +void read_boot_clock64(struct timespec64 *ts) { __read_boot_clock(ts); } diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 338ace78ed18..f1f79d104309 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig @@ -18,6 +18,7 @@ if VIRTUALIZATION config KVM bool "Kernel-based Virtual Machine (KVM) support" + depends on MMU && OF select PREEMPT_NOTIFIERS select ANON_INODES select HAVE_KVM_CPU_RELAX_INTERCEPT @@ -26,10 +27,12 @@ config KVM select KVM_ARM_HOST select KVM_GENERIC_DIRTYLOG_READ_PROTECT select SRCU - depends on ARM_VIRT_EXT && ARM_LPAE + select MMU_NOTIFIER + select HAVE_KVM_EVENTFD + select HAVE_KVM_IRQFD + depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER ---help--- - Support hosting virtualized guest machines. You will also - need to select one or more of the processor modules below. + Support hosting virtualized guest machines. This module provides access to the hardware capabilities through a character device node named /dev/kvm. @@ -37,10 +40,7 @@ config KVM If unsure, say N. config KVM_ARM_HOST - bool "KVM host support for ARM cpus." - depends on KVM - depends on MMU - select MMU_NOTIFIER + bool ---help--- Provides host support for ARM processors. @@ -55,20 +55,4 @@ config KVM_ARM_MAX_VCPUS large, so only choose a reasonable number that you expect to actually use. -config KVM_ARM_VGIC - bool "KVM support for Virtual GIC" - depends on KVM_ARM_HOST && OF - select HAVE_KVM_IRQCHIP - default y - ---help--- - Adds support for a hardware assisted, in-kernel GIC emulation. - -config KVM_ARM_TIMER - bool "KVM support for Architected Timers" - depends on KVM_ARM_VGIC && ARM_ARCH_TIMER - select HAVE_KVM_IRQCHIP - default y - ---help--- - Adds support for the Architected Timers in virtual machines - endif # VIRTUALIZATION diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index 443b8bea43e9..139e46c08b6e 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile @@ -7,7 +7,7 @@ ifeq ($(plus_virt),+virt) plus_virt_def := -DREQUIRES_VIRT=1 endif -ccflags-y += -Ivirt/kvm -Iarch/arm/kvm +ccflags-y += -Iarch/arm/kvm CFLAGS_arm.o := -I. $(plus_virt_def) CFLAGS_mmu.o := -I. @@ -15,12 +15,12 @@ AFLAGS_init.o := -Wa,-march=armv7-a$(plus_virt) AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt) KVM := ../../../virt/kvm -kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o +kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o obj-y += kvm-arm.o init.o interrupts.o obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o -obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o -obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o -obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2-emul.o -obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o +obj-y += $(KVM)/arm/vgic.o +obj-y += $(KVM)/arm/vgic-v2.o +obj-y += $(KVM)/arm/vgic-v2-emul.o +obj-y += $(KVM)/arm/arch_timer.o diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 5560f74f9eee..6f536451ab78 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -61,8 +61,6 @@ static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); static u8 kvm_next_vmid; static DEFINE_SPINLOCK(kvm_vmid_lock); -static bool vgic_present; - static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) { BUG_ON(preemptible()); @@ -173,8 +171,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) int r; switch (ext) { case KVM_CAP_IRQCHIP: - r = vgic_present; - break; + case KVM_CAP_IRQFD: + case KVM_CAP_IOEVENTFD: case KVM_CAP_DEVICE_CTRL: case KVM_CAP_USER_MEMORY: case KVM_CAP_SYNC_MMU: @@ -183,6 +181,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_ARM_PSCI: case KVM_CAP_ARM_PSCI_0_2: case KVM_CAP_READONLY_MEM: + case KVM_CAP_MP_STATE: r = 1; break; case KVM_CAP_COALESCED_MMIO: @@ -268,7 +267,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) { - return 0; + return kvm_timer_should_fire(vcpu); } int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) @@ -313,13 +312,29 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, struct kvm_mp_state *mp_state) { - return -EINVAL; + if (vcpu->arch.pause) + mp_state->mp_state = KVM_MP_STATE_STOPPED; + else + mp_state->mp_state = KVM_MP_STATE_RUNNABLE; + + return 0; } int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, struct kvm_mp_state *mp_state) { - return -EINVAL; + switch (mp_state->mp_state) { + case KVM_MP_STATE_RUNNABLE: + vcpu->arch.pause = false; + break; + case KVM_MP_STATE_STOPPED: + vcpu->arch.pause = true; + break; + default: + return -EINVAL; + } + + return 0; } /** @@ -452,6 +467,11 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) return 0; } +bool kvm_arch_intc_initialized(struct kvm *kvm) +{ + return vgic_initialized(kvm); +} + static void vcpu_pause(struct kvm_vcpu *vcpu) { wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu); @@ -831,8 +851,6 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm, switch (dev_id) { case KVM_ARM_DEVICE_VGIC_V2: - if (!vgic_present) - return -ENXIO; return kvm_vgic_addr(kvm, type, &dev_addr->addr, true); default: return -ENODEV; @@ -847,10 +865,7 @@ long kvm_arch_vm_ioctl(struct file *filp, switch (ioctl) { case KVM_CREATE_IRQCHIP: { - if (vgic_present) - return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2); - else - return -ENXIO; + return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2); } case KVM_ARM_SET_DEVICE_ADDR: { struct kvm_arm_device_addr dev_addr; @@ -1035,10 +1050,6 @@ static int init_hyp_mode(void) if (err) goto out_free_context; -#ifdef CONFIG_KVM_ARM_VGIC - vgic_present = true; -#endif - /* * Init HYP architected timer support */ diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c index 384bab67c462..d503fbb787d3 100644 --- a/arch/arm/kvm/guest.c +++ b/arch/arm/kvm/guest.c @@ -109,22 +109,6 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) return -EINVAL; } -#ifndef CONFIG_KVM_ARM_TIMER - -#define NUM_TIMER_REGS 0 - -static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) -{ - return 0; -} - -static bool is_timer_reg(u64 index) -{ - return false; -} - -#else - #define NUM_TIMER_REGS 3 static bool is_timer_reg(u64 index) @@ -152,8 +136,6 @@ static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) return 0; } -#endif - static int set_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) { void __user *uaddr = (void __user *)(long)reg->addr; diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 14d488388480..35e4a3a0c476 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S @@ -402,7 +402,6 @@ vcpu .req r0 @ vcpu pointer always in r0 * Assumes vcpu pointer in vcpu reg */ .macro save_vgic_state -#ifdef CONFIG_KVM_ARM_VGIC /* Get VGIC VCTRL base into r2 */ ldr r2, [vcpu, #VCPU_KVM] ldr r2, [r2, #KVM_VGIC_VCTRL] @@ -460,7 +459,6 @@ ARM_BE8(rev r6, r6 ) subs r4, r4, #1 bne 1b 2: -#endif .endm /* @@ -469,7 +467,6 @@ ARM_BE8(rev r6, r6 ) * Assumes vcpu pointer in vcpu reg */ .macro restore_vgic_state -#ifdef CONFIG_KVM_ARM_VGIC /* Get VGIC VCTRL base into r2 */ ldr r2, [vcpu, #VCPU_KVM] ldr r2, [r2, #KVM_VGIC_VCTRL] @@ -501,7 +498,6 @@ ARM_BE8(rev r6, r6 ) subs r4, r4, #1 bne 1b 2: -#endif .endm #define CNTHCTL_PL1PCTEN (1 << 0) @@ -515,7 +511,6 @@ ARM_BE8(rev r6, r6 ) * Clobbers r2-r5 */ .macro save_timer_state -#ifdef CONFIG_KVM_ARM_TIMER ldr r4, [vcpu, #VCPU_KVM] ldr r2, [r4, #KVM_TIMER_ENABLED] cmp r2, #0 @@ -537,7 +532,6 @@ ARM_BE8(rev r6, r6 ) mcrr p15, 4, r2, r2, c14 @ CNTVOFF 1: -#endif @ Allow physical timer/counter access for the host mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL orr r2, r2, #(CNTHCTL_PL1PCEN | CNTHCTL_PL1PCTEN) @@ -559,7 +553,6 @@ ARM_BE8(rev r6, r6 ) bic r2, r2, #CNTHCTL_PL1PCEN mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL -#ifdef CONFIG_KVM_ARM_TIMER ldr r4, [vcpu, #VCPU_KVM] ldr r2, [r4, #KVM_TIMER_ENABLED] cmp r2, #0 @@ -579,7 +572,6 @@ ARM_BE8(rev r6, r6 ) and r2, r2, #3 mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL 1: -#endif .endm .equ vmentry, 0 diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c index 5d3bfc0eb3f0..974b1c606d04 100644 --- a/arch/arm/kvm/mmio.c +++ b/arch/arm/kvm/mmio.c @@ -121,12 +121,11 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) return 0; } -static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, - struct kvm_exit_mmio *mmio) +static int decode_hsr(struct kvm_vcpu *vcpu, bool *is_write, int *len) { unsigned long rt; - int len; - bool is_write, sign_extend; + int access_size; + bool sign_extend; if (kvm_vcpu_dabt_isextabt(vcpu)) { /* cache operation on I/O addr, tell guest unsupported */ @@ -140,17 +139,15 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, return 1; } - len = kvm_vcpu_dabt_get_as(vcpu); - if (unlikely(len < 0)) - return len; + access_size = kvm_vcpu_dabt_get_as(vcpu); + if (unlikely(access_size < 0)) + return access_size; - is_write = kvm_vcpu_dabt_iswrite(vcpu); + *is_write = kvm_vcpu_dabt_iswrite(vcpu); sign_extend = kvm_vcpu_dabt_issext(vcpu); rt = kvm_vcpu_dabt_get_rd(vcpu); - mmio->is_write = is_write; - mmio->phys_addr = fault_ipa; - mmio->len = len; + *len = access_size; vcpu->arch.mmio_decode.sign_extend = sign_extend; vcpu->arch.mmio_decode.rt = rt; @@ -165,20 +162,20 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, phys_addr_t fault_ipa) { - struct kvm_exit_mmio mmio; unsigned long data; unsigned long rt; int ret; + bool is_write; + int len; + u8 data_buf[8]; /* - * Prepare MMIO operation. First stash it in a private - * structure that we can use for in-kernel emulation. If the - * kernel can't handle it, copy it into run->mmio and let user - * space do its magic. + * Prepare MMIO operation. First decode the syndrome data we get + * from the CPU. Then try if some in-kernel emulation feels + * responsible, otherwise let user space do its magic. */ - if (kvm_vcpu_dabt_isvalid(vcpu)) { - ret = decode_hsr(vcpu, fault_ipa, &mmio); + ret = decode_hsr(vcpu, &is_write, &len); if (ret) return ret; } else { @@ -188,21 +185,34 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, rt = vcpu->arch.mmio_decode.rt; - if (mmio.is_write) { - data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), - mmio.len); + if (is_write) { + data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), len); + + trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data); + mmio_write_buf(data_buf, len, data); - trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, mmio.len, - fault_ipa, data); - mmio_write_buf(mmio.data, mmio.len, data); + ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_ipa, len, + data_buf); } else { - trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, mmio.len, + trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, len, fault_ipa, 0); + + ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_ipa, len, + data_buf); } - if (vgic_handle_mmio(vcpu, run, &mmio)) + /* Now prepare kvm_run for the potential return to userland. */ + run->mmio.is_write = is_write; + run->mmio.phys_addr = fault_ipa; + run->mmio.len = len; + memcpy(run->mmio.data, data_buf, len); + + if (!ret) { + /* We handled the access successfully in the kernel. */ + kvm_handle_mmio_return(vcpu, run); return 1; + } - kvm_prepare_mmio(run, &mmio); + run->exit_reason = KVM_EXIT_MMIO; return 0; } diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 5656d79c5a44..15b050d46fc9 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -1330,10 +1330,51 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, out_unlock: spin_unlock(&kvm->mmu_lock); + kvm_set_pfn_accessed(pfn); kvm_release_pfn_clean(pfn); return ret; } +/* + * Resolve the access fault by making the page young again. + * Note that because the faulting entry is guaranteed not to be + * cached in the TLB, we don't need to invalidate anything. + */ +static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa) +{ + pmd_t *pmd; + pte_t *pte; + pfn_t pfn; + bool pfn_valid = false; + + trace_kvm_access_fault(fault_ipa); + + spin_lock(&vcpu->kvm->mmu_lock); + + pmd = stage2_get_pmd(vcpu->kvm, NULL, fault_ipa); + if (!pmd || pmd_none(*pmd)) /* Nothing there */ + goto out; + + if (kvm_pmd_huge(*pmd)) { /* THP, HugeTLB */ + *pmd = pmd_mkyoung(*pmd); + pfn = pmd_pfn(*pmd); + pfn_valid = true; + goto out; + } + + pte = pte_offset_kernel(pmd, fault_ipa); + if (pte_none(*pte)) /* Nothing there either */ + goto out; + + *pte = pte_mkyoung(*pte); /* Just a page... */ + pfn = pte_pfn(*pte); + pfn_valid = true; +out: + spin_unlock(&vcpu->kvm->mmu_lock); + if (pfn_valid) + kvm_set_pfn_accessed(pfn); +} + /** * kvm_handle_guest_abort - handles all 2nd stage aborts * @vcpu: the VCPU pointer @@ -1364,7 +1405,8 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) /* Check the stage-2 fault is trans. fault or write fault */ fault_status = kvm_vcpu_trap_get_fault_type(vcpu); - if (fault_status != FSC_FAULT && fault_status != FSC_PERM) { + if (fault_status != FSC_FAULT && fault_status != FSC_PERM && + fault_status != FSC_ACCESS) { kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n", kvm_vcpu_trap_get_class(vcpu), (unsigned long)kvm_vcpu_trap_get_fault(vcpu), @@ -1400,6 +1442,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) /* Userspace should not be able to register out-of-bounds IPAs */ VM_BUG_ON(fault_ipa >= KVM_PHYS_SIZE); + if (fault_status == FSC_ACCESS) { + handle_access_fault(vcpu, fault_ipa); + ret = 1; + goto out_unlock; + } + ret = user_mem_abort(vcpu, fault_ipa, memslot, hva, fault_status); if (ret == 0) ret = 1; @@ -1408,15 +1456,16 @@ out_unlock: return ret; } -static void handle_hva_to_gpa(struct kvm *kvm, - unsigned long start, - unsigned long end, - void (*handler)(struct kvm *kvm, - gpa_t gpa, void *data), - void *data) +static int handle_hva_to_gpa(struct kvm *kvm, + unsigned long start, + unsigned long end, + int (*handler)(struct kvm *kvm, + gpa_t gpa, void *data), + void *data) { struct kvm_memslots *slots; struct kvm_memory_slot *memslot; + int ret = 0; slots = kvm_memslots(kvm); @@ -1440,14 +1489,17 @@ static void handle_hva_to_gpa(struct kvm *kvm, for (; gfn < gfn_end; ++gfn) { gpa_t gpa = gfn << PAGE_SHIFT; - handler(kvm, gpa, data); + ret |= handler(kvm, gpa, data); } } + + return ret; } -static void kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) +static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) { unmap_stage2_range(kvm, gpa, PAGE_SIZE); + return 0; } int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) @@ -1473,7 +1525,7 @@ int kvm_unmap_hva_range(struct kvm *kvm, return 0; } -static void kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data) +static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data) { pte_t *pte = (pte_t *)data; @@ -1485,6 +1537,7 @@ static void kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data) * through this calling path. */ stage2_set_pte(kvm, NULL, gpa, pte, 0); + return 0; } @@ -1501,6 +1554,67 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte); } +static int kvm_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) +{ + pmd_t *pmd; + pte_t *pte; + + pmd = stage2_get_pmd(kvm, NULL, gpa); + if (!pmd || pmd_none(*pmd)) /* Nothing there */ + return 0; + + if (kvm_pmd_huge(*pmd)) { /* THP, HugeTLB */ + if (pmd_young(*pmd)) { + *pmd = pmd_mkold(*pmd); + return 1; + } + + return 0; + } + + pte = pte_offset_kernel(pmd, gpa); + if (pte_none(*pte)) + return 0; + + if (pte_young(*pte)) { + *pte = pte_mkold(*pte); /* Just a page... */ + return 1; + } + + return 0; +} + +static int kvm_test_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) +{ + pmd_t *pmd; + pte_t *pte; + + pmd = stage2_get_pmd(kvm, NULL, gpa); + if (!pmd || pmd_none(*pmd)) /* Nothing there */ + return 0; + + if (kvm_pmd_huge(*pmd)) /* THP, HugeTLB */ + return pmd_young(*pmd); + + pte = pte_offset_kernel(pmd, gpa); + if (!pte_none(*pte)) /* Just a page... */ + return pte_young(*pte); + + return 0; +} + +int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end) +{ + trace_kvm_age_hva(start, end); + return handle_hva_to_gpa(kvm, start, end, kvm_age_hva_handler, NULL); +} + +int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) +{ + trace_kvm_test_age_hva(hva); + return handle_hva_to_gpa(kvm, hva, hva, kvm_test_age_hva_handler, NULL); +} + void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu) { mmu_free_memory_cache(&vcpu->arch.mmu_page_cache); diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h index 6817664b46b8..0ec35392d208 100644 --- a/arch/arm/kvm/trace.h +++ b/arch/arm/kvm/trace.h @@ -68,6 +68,21 @@ TRACE_EVENT(kvm_guest_fault, __entry->hxfar, __entry->vcpu_pc) ); +TRACE_EVENT(kvm_access_fault, + TP_PROTO(unsigned long ipa), + TP_ARGS(ipa), + + TP_STRUCT__entry( + __field( unsigned long, ipa ) + ), + + TP_fast_assign( + __entry->ipa = ipa; + ), + + TP_printk("IPA: %lx", __entry->ipa) +); + TRACE_EVENT(kvm_irq_line, TP_PROTO(unsigned int type, int vcpu_idx, int irq_num, int level), TP_ARGS(type, vcpu_idx, irq_num, level), @@ -210,6 +225,39 @@ TRACE_EVENT(kvm_set_spte_hva, TP_printk("mmu notifier set pte hva: %#08lx", __entry->hva) ); +TRACE_EVENT(kvm_age_hva, + TP_PROTO(unsigned long start, unsigned long end), + TP_ARGS(start, end), + + TP_STRUCT__entry( + __field( unsigned long, start ) + __field( unsigned long, end ) + ), + + TP_fast_assign( + __entry->start = start; + __entry->end = end; + ), + + TP_printk("mmu notifier age hva: %#08lx -- %#08lx", + __entry->start, __entry->end) +); + +TRACE_EVENT(kvm_test_age_hva, + TP_PROTO(unsigned long hva), + TP_ARGS(hva), + + TP_STRUCT__entry( + __field( unsigned long, hva ) + ), + + TP_fast_assign( + __entry->hva = hva; + ), + + TP_printk("mmu notifier test age hva: %#08lx", __entry->hva) +); + TRACE_EVENT(kvm_hvc, TP_PROTO(unsigned long vcpu_pc, unsigned long r0, unsigned long imm), TP_ARGS(vcpu_pc, r0, imm), diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c index 8a275f297522..91fe97144570 100644 --- a/arch/arm/mach-dove/pcie.c +++ b/arch/arm/mach-dove/pcie.c @@ -155,17 +155,13 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); static struct pci_bus __init * dove_pcie_scan_bus(int nr, struct pci_sys_data *sys) { - struct pci_bus *bus; - - if (nr < num_pcie_ports) { - bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys, - &sys->resources); - } else { - bus = NULL; + if (nr >= num_pcie_ports) { BUG(); + return NULL; } - return bus; + return pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys, + &sys->resources); } static int __init dove_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 9e9dfdfad9d7..f44c2e05c82e 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -166,16 +166,14 @@ static void __init exynos_init_io(void) exynos_map_io(); } +/* + * Apparently, these SoCs are not able to wake-up from suspend using + * the PMU. Too bad. Should they suddenly become capable of such a + * feat, the matches below should be moved to suspend.c. + */ static const struct of_device_id exynos_dt_pmu_match[] = { - { .compatible = "samsung,exynos3250-pmu" }, - { .compatible = "samsung,exynos4210-pmu" }, - { .compatible = "samsung,exynos4212-pmu" }, - { .compatible = "samsung,exynos4412-pmu" }, - { .compatible = "samsung,exynos4415-pmu" }, - { .compatible = "samsung,exynos5250-pmu" }, { .compatible = "samsung,exynos5260-pmu" }, { .compatible = "samsung,exynos5410-pmu" }, - { .compatible = "samsung,exynos5420-pmu" }, { /*sentinel*/ }, }; @@ -186,9 +184,6 @@ static void exynos_map_pmu(void) np = of_find_matching_node(NULL, exynos_dt_pmu_match); if (np) pmu_base_addr = of_iomap(np, 0); - - if (!pmu_base_addr) - panic("failed to find exynos pmu register\n"); } static void __init exynos_init_irq(void) diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 318d127df147..2146d918aedd 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -18,7 +18,9 @@ #include <linux/syscore_ops.h> #include <linux/cpu_pm.h> #include <linux/io.h> -#include <linux/irqchip/arm-gic.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/of_address.h> #include <linux/err.h> #include <linux/regulator/machine.h> @@ -43,8 +45,8 @@ #define EXYNOS5420_CPU_STATE 0x28 /** - * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping - * @hwirq: Hardware IRQ signal of the GIC + * struct exynos_wkup_irq - PMU IRQ to mask mapping + * @hwirq: Hardware IRQ signal of the PMU * @mask: Mask in PMU wake-up mask register */ struct exynos_wkup_irq { @@ -93,14 +95,14 @@ static const struct exynos_wkup_irq exynos3250_wkup_irq[] = { }; static const struct exynos_wkup_irq exynos4_wkup_irq[] = { - { 76, BIT(1) }, /* RTC alarm */ - { 77, BIT(2) }, /* RTC tick */ + { 44, BIT(1) }, /* RTC alarm */ + { 45, BIT(2) }, /* RTC tick */ { /* sentinel */ }, }; static const struct exynos_wkup_irq exynos5250_wkup_irq[] = { - { 75, BIT(1) }, /* RTC alarm */ - { 76, BIT(2) }, /* RTC tick */ + { 43, BIT(1) }, /* RTC alarm */ + { 44, BIT(2) }, /* RTC tick */ { /* sentinel */ }, }; @@ -167,6 +169,113 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) return -ENOENT; } +static struct irq_chip exynos_pmu_chip = { + .name = "PMU", + .irq_eoi = irq_chip_eoi_parent, + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_wake = exynos_irq_set_wake, +#ifdef CONFIG_SMP + .irq_set_affinity = irq_chip_set_affinity_parent, +#endif +}; + +static int exynos_pmu_domain_xlate(struct irq_domain *domain, + struct device_node *controller, + const u32 *intspec, + unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + if (domain->of_node != controller) + return -EINVAL; /* Shouldn't happen, really... */ + if (intsize != 3) + return -EINVAL; /* Not GIC compliant */ + if (intspec[0] != 0) + return -EINVAL; /* No PPI should point to this domain */ + + *out_hwirq = intspec[1]; + *out_type = intspec[2]; + return 0; +} + +static int exynos_pmu_domain_alloc(struct irq_domain *domain, + unsigned int virq, + unsigned int nr_irqs, void *data) +{ + struct of_phandle_args *args = data; + struct of_phandle_args parent_args; + irq_hw_number_t hwirq; + int i; + + if (args->args_count != 3) + return -EINVAL; /* Not GIC compliant */ + if (args->args[0] != 0) + return -EINVAL; /* No PPI should point to this domain */ + + hwirq = args->args[1]; + + for (i = 0; i < nr_irqs; i++) + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, + &exynos_pmu_chip, NULL); + + parent_args = *args; + parent_args.np = domain->parent->of_node; + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args); +} + +static struct irq_domain_ops exynos_pmu_domain_ops = { + .xlate = exynos_pmu_domain_xlate, + .alloc = exynos_pmu_domain_alloc, + .free = irq_domain_free_irqs_common, +}; + +static int __init exynos_pmu_irq_init(struct device_node *node, + struct device_node *parent) +{ + struct irq_domain *parent_domain, *domain; + + if (!parent) { + pr_err("%s: no parent, giving up\n", node->full_name); + return -ENODEV; + } + + parent_domain = irq_find_host(parent); + if (!parent_domain) { + pr_err("%s: unable to obtain parent domain\n", node->full_name); + return -ENXIO; + } + + pmu_base_addr = of_iomap(node, 0); + + if (!pmu_base_addr) { + pr_err("%s: failed to find exynos pmu register\n", + node->full_name); + return -ENOMEM; + } + + domain = irq_domain_add_hierarchy(parent_domain, 0, 0, + node, &exynos_pmu_domain_ops, + NULL); + if (!domain) { + iounmap(pmu_base_addr); + return -ENOMEM; + } + + return 0; +} + +#define EXYNOS_PMU_IRQ(symbol, name) OF_DECLARE_2(irqchip, symbol, name, exynos_pmu_irq_init) + +EXYNOS_PMU_IRQ(exynos3250_pmu_irq, "samsung,exynos3250-pmu"); +EXYNOS_PMU_IRQ(exynos4210_pmu_irq, "samsung,exynos4210-pmu"); +EXYNOS_PMU_IRQ(exynos4212_pmu_irq, "samsung,exynos4212-pmu"); +EXYNOS_PMU_IRQ(exynos4412_pmu_irq, "samsung,exynos4412-pmu"); +EXYNOS_PMU_IRQ(exynos4415_pmu_irq, "samsung,exynos4415-pmu"); +EXYNOS_PMU_IRQ(exynos5250_pmu_irq, "samsung,exynos5250-pmu"); +EXYNOS_PMU_IRQ(exynos5420_pmu_irq, "samsung,exynos5420-pmu"); + static int exynos_cpu_do_idle(void) { /* issue the standby signal into the pm unit. */ @@ -615,17 +724,19 @@ static struct syscore_ops exynos_pm_syscore_ops; void __init exynos_pm_init(void) { const struct of_device_id *match; + struct device_node *np; u32 tmp; - of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match); - if (!match) { + np = of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match); + if (!np) { pr_err("Failed to find PMU node\n"); return; } - pm_data = (struct exynos_pm_data *) match->data; - /* Platform-specific GIC callback */ - gic_arch_extn.irq_set_wake = exynos_irq_set_wake; + if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) + pr_warn("Outdated DT detected, suspend/resume will NOT work\n"); + + pm_data = (struct exynos_pm_data *) match->data; /* All wakeup disable */ tmp = pmu_raw_readl(S5P_WAKEUP_MASK); diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index e8627e04e1e6..c8dffcee9736 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -631,6 +631,7 @@ config SOC_IMX6SX config SOC_VF610 bool "Vybrid Family VF610 support" + select IRQ_DOMAIN_HIERARCHY select ARM_GIC select PINCTRL_VF610 select PL310_ERRATA_769419 if CACHE_L2X0 diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c index 445e553f4a28..097ea4cb1136 100644 --- a/arch/arm/mach-mv78xx0/pcie.c +++ b/arch/arm/mach-mv78xx0/pcie.c @@ -197,17 +197,13 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); static struct pci_bus __init * mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys) { - struct pci_bus *bus; - - if (nr < num_pcie_ports) { - bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys, - &sys->resources); - } else { - bus = NULL; + if (nr >= num_pcie_ports) { BUG(); + return NULL; } - return bus; + return pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys, + &sys->resources); } static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot, diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 7622dbb05083..4b8e9f4d59ea 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -14,7 +14,7 @@ #include <linux/cpuidle.h> #include <linux/cpu_pm.h> #include <linux/export.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <asm/cpuidle.h> @@ -83,7 +83,6 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, { struct idle_statedata *cx = state_ptr + index; u32 mpuss_can_lose_context = 0; - int cpu_id = smp_processor_id(); /* * CPU0 has to wait and stay ON until CPU1 is OFF state. @@ -111,7 +110,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, mpuss_can_lose_context = (cx->mpu_state == PWRDM_POWER_RET) && (cx->mpu_logic_state == PWRDM_POWER_OFF); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); + tick_broadcast_enter(); /* * Call idle CPU PM enter notifier chain so that @@ -168,7 +167,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, if (dev->cpu == 0 && mpuss_can_lose_context) cpu_cluster_pm_exit(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); + tick_broadcast_exit(); fail: cpuidle_coupled_parallel_barrier(dev, &abort_barrier); @@ -183,8 +182,7 @@ fail: */ static void omap_setup_broadcast_timer(void *arg) { - int cpu = smp_processor_id(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); + tick_broadcast_enable(); } static struct cpuidle_driver omap4_idle_driver = { diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index dc6e79c4484a..9a8611ab5dfa 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -150,9 +150,13 @@ static int nop_mmc_set_power(struct device *dev, int power_on, int vdd) static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data *mmc_controller, int controller_nr) { - if (gpio_is_valid(mmc_controller->switch_pin) && - (mmc_controller->switch_pin < OMAP_MAX_GPIO_LINES)) - omap_mux_init_gpio(mmc_controller->switch_pin, + if (gpio_is_valid(mmc_controller->gpio_cd) && + (mmc_controller->gpio_cd < OMAP_MAX_GPIO_LINES)) + omap_mux_init_gpio(mmc_controller->gpio_cd, + OMAP_PIN_INPUT_PULLUP); + if (gpio_is_valid(mmc_controller->gpio_cod) && + (mmc_controller->gpio_cod < OMAP_MAX_GPIO_LINES)) + omap_mux_init_gpio(mmc_controller->gpio_cod, OMAP_PIN_INPUT_PULLUP); if (gpio_is_valid(mmc_controller->gpio_wp) && (mmc_controller->gpio_wp < OMAP_MAX_GPIO_LINES)) @@ -250,15 +254,20 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, mmc->internal_clock = !c->ext_clock; mmc->reg_offset = 0; - mmc->switch_pin = c->gpio_cd; + if (c->cover_only) { + /* detect if mobile phone cover removed */ + mmc->gpio_cd = -EINVAL; + mmc->gpio_cod = c->gpio_cd; + } else { + /* card detect pin on the mmc socket itself */ + mmc->gpio_cd = c->gpio_cd; + mmc->gpio_cod = -EINVAL; + } mmc->gpio_wp = c->gpio_wp; mmc->remux = c->remux; mmc->init_card = c->init_card; - if (c->cover_only) - mmc->cover = 1; - if (c->nonremovable) mmc->nonremovable = 1; @@ -358,7 +367,15 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) if (!mmc_pdata) continue; - mmc_pdata->switch_pin = c->gpio_cd; + if (c->cover_only) { + /* detect if mobile phone cover removed */ + mmc_pdata->gpio_cd = -EINVAL; + mmc_pdata->gpio_cod = c->gpio_cd; + } else { + /* card detect pin on the mmc socket itself */ + mmc_pdata->gpio_cd = c->gpio_cd; + mmc_pdata->gpio_cod = -EINVAL; + } mmc_pdata->gpio_wp = c->gpio_wp; res = omap_device_register(pdev); diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index f961c46453b9..3b56722dfd8a 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -20,11 +20,12 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/cpu.h> #include <linux/notifier.h> #include <linux/cpu_pm.h> -#include <linux/irqchip/arm-gic.h> #include "omap-wakeupgen.h" #include "omap-secure.h" @@ -78,29 +79,12 @@ static inline void sar_writel(u32 val, u32 offset, u8 idx) static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index) { - unsigned int spi_irq; - - /* - * PPIs and SGIs are not supported. - */ - if (irq < OMAP44XX_IRQ_GIC_START) - return -EINVAL; - - /* - * Subtract the GIC offset. - */ - spi_irq = irq - OMAP44XX_IRQ_GIC_START; - if (spi_irq > MAX_IRQS) { - pr_err("omap wakeupGen: Invalid IRQ%d\n", irq); - return -EINVAL; - } - /* * Each WakeupGen register controls 32 interrupt. * i.e. 1 bit per SPI IRQ */ - *reg_index = spi_irq >> 5; - *bit_posn = spi_irq %= 32; + *reg_index = irq >> 5; + *bit_posn = irq %= 32; return 0; } @@ -141,6 +125,7 @@ static void wakeupgen_mask(struct irq_data *d) raw_spin_lock_irqsave(&wakeupgen_lock, flags); _wakeupgen_clear(d->hwirq, irq_target_cpu[d->hwirq]); raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); + irq_chip_mask_parent(d); } /* @@ -153,6 +138,7 @@ static void wakeupgen_unmask(struct irq_data *d) raw_spin_lock_irqsave(&wakeupgen_lock, flags); _wakeupgen_set(d->hwirq, irq_target_cpu[d->hwirq]); raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); + irq_chip_unmask_parent(d); } #ifdef CONFIG_HOTPLUG_CPU @@ -400,15 +386,91 @@ int omap_secure_apis_support(void) return omap_secure_apis; } +static struct irq_chip wakeupgen_chip = { + .name = "WUGEN", + .irq_eoi = irq_chip_eoi_parent, + .irq_mask = wakeupgen_mask, + .irq_unmask = wakeupgen_unmask, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, +#ifdef CONFIG_SMP + .irq_set_affinity = irq_chip_set_affinity_parent, +#endif +}; + +static int wakeupgen_domain_xlate(struct irq_domain *domain, + struct device_node *controller, + const u32 *intspec, + unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + if (domain->of_node != controller) + return -EINVAL; /* Shouldn't happen, really... */ + if (intsize != 3) + return -EINVAL; /* Not GIC compliant */ + if (intspec[0] != 0) + return -EINVAL; /* No PPI should point to this domain */ + + *out_hwirq = intspec[1]; + *out_type = intspec[2]; + return 0; +} + +static int wakeupgen_domain_alloc(struct irq_domain *domain, + unsigned int virq, + unsigned int nr_irqs, void *data) +{ + struct of_phandle_args *args = data; + struct of_phandle_args parent_args; + irq_hw_number_t hwirq; + int i; + + if (args->args_count != 3) + return -EINVAL; /* Not GIC compliant */ + if (args->args[0] != 0) + return -EINVAL; /* No PPI should point to this domain */ + + hwirq = args->args[1]; + if (hwirq >= MAX_IRQS) + return -EINVAL; /* Can't deal with this */ + + for (i = 0; i < nr_irqs; i++) + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, + &wakeupgen_chip, NULL); + + parent_args = *args; + parent_args.np = domain->parent->of_node; + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args); +} + +static struct irq_domain_ops wakeupgen_domain_ops = { + .xlate = wakeupgen_domain_xlate, + .alloc = wakeupgen_domain_alloc, + .free = irq_domain_free_irqs_common, +}; + /* * Initialise the wakeupgen module. */ -int __init omap_wakeupgen_init(void) +static int __init wakeupgen_init(struct device_node *node, + struct device_node *parent) { + struct irq_domain *parent_domain, *domain; int i; unsigned int boot_cpu = smp_processor_id(); u32 val; + if (!parent) { + pr_err("%s: no parent, giving up\n", node->full_name); + return -ENODEV; + } + + parent_domain = irq_find_host(parent); + if (!parent_domain) { + pr_err("%s: unable to obtain parent domain\n", node->full_name); + return -ENXIO; + } /* Not supported on OMAP4 ES1.0 silicon */ if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n"); @@ -416,7 +478,7 @@ int __init omap_wakeupgen_init(void) } /* Static mapping, never released */ - wakeupgen_base = ioremap(OMAP_WKUPGEN_BASE, SZ_4K); + wakeupgen_base = of_iomap(node, 0); if (WARN_ON(!wakeupgen_base)) return -ENOMEM; @@ -429,6 +491,14 @@ int __init omap_wakeupgen_init(void) max_irqs = AM43XX_IRQS; } + domain = irq_domain_add_hierarchy(parent_domain, 0, max_irqs, + node, &wakeupgen_domain_ops, + NULL); + if (!domain) { + iounmap(wakeupgen_base); + return -ENOMEM; + } + /* Clear all IRQ bitmasks at wakeupGen level */ for (i = 0; i < irq_banks; i++) { wakeupgen_writel(0, i, CPU0_ID); @@ -437,14 +507,6 @@ int __init omap_wakeupgen_init(void) } /* - * Override GIC architecture specific functions to add - * OMAP WakeupGen interrupt controller along with GIC - */ - gic_arch_extn.irq_mask = wakeupgen_mask; - gic_arch_extn.irq_unmask = wakeupgen_unmask; - gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE; - - /* * FIXME: Add support to set_smp_affinity() once the core * GIC code has necessary hooks in place. */ @@ -474,3 +536,9 @@ int __init omap_wakeupgen_init(void) return 0; } + +/* + * We cannot use the IRQCHIP_DECLARE macro that lives in + * drivers/irqchip, so we're forced to roll our own. Not very nice. + */ +OF_DECLARE_2(irqchip, ti_wakeupgen, "ti,omap4-wugen-mpu", wakeupgen_init); diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h index b3c8eccfae79..a3491ad12368 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.h +++ b/arch/arm/mach-omap2/omap-wakeupgen.h @@ -33,7 +33,6 @@ #define OMAP_TIMESTAMPCYCLELO 0xc08 #define OMAP_TIMESTAMPCYCLEHI 0xc0c -extern int __init omap_wakeupgen_init(void); extern void __iomem *omap_get_wakeupgen_base(void); extern int omap_secure_apis_support(void); #endif diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index cee0fe1ee6ff..7bb116a6f86f 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -22,7 +22,6 @@ #include <linux/of_platform.h> #include <linux/export.h> #include <linux/irqchip/arm-gic.h> -#include <linux/irqchip/irq-crossbar.h> #include <linux/of_address.h> #include <linux/reboot.h> #include <linux/genalloc.h> @@ -242,26 +241,26 @@ static int __init omap4_sar_ram_init(void) } omap_early_initcall(omap4_sar_ram_init); -static const struct of_device_id gic_match[] = { - { .compatible = "arm,cortex-a9-gic", }, - { .compatible = "arm,cortex-a15-gic", }, +static const struct of_device_id intc_match[] = { + { .compatible = "ti,omap4-wugen-mpu", }, + { .compatible = "ti,omap5-wugen-mpu", }, { }, }; -static struct device_node *gic_node; +static struct device_node *intc_node; unsigned int omap4_xlate_irq(unsigned int hwirq) { struct of_phandle_args irq_data; unsigned int irq; - if (!gic_node) - gic_node = of_find_matching_node(NULL, gic_match); + if (!intc_node) + intc_node = of_find_matching_node(NULL, intc_match); - if (WARN_ON(!gic_node)) + if (WARN_ON(!intc_node)) return hwirq; - irq_data.np = gic_node; + irq_data.np = intc_node; irq_data.args_count = 3; irq_data.args[0] = 0; irq_data.args[1] = hwirq - OMAP44XX_IRQ_GIC_START; @@ -278,6 +277,12 @@ void __init omap_gic_of_init(void) { struct device_node *np; + intc_node = of_find_matching_node(NULL, intc_match); + if (WARN_ON(!intc_node)) { + pr_err("No WUGEN found in DT, system will misbehave.\n"); + pr_err("UPDATE YOUR DEVICE TREE!\n"); + } + /* Extract GIC distributor and TWD bases for OMAP4460 ROM Errata WA */ if (!cpu_is_omap446x()) goto skip_errata_init; @@ -291,9 +296,5 @@ void __init omap_gic_of_init(void) WARN_ON(!twd_base); skip_errata_init: - omap_wakeupgen_init(); -#ifdef CONFIG_IRQ_CROSSBAR - irqcrossbar_init(); -#endif irqchip_init(); } diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index 87a12d6930ff..b02f3947be51 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c @@ -540,37 +540,33 @@ void __init orion5x_pci_set_cardbus_mode(void) int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys) { - int ret = 0; - vga_base = ORION5X_PCIE_MEM_PHYS_BASE; if (nr == 0) { orion_pcie_set_local_bus_nr(PCIE_BASE, sys->busnr); - ret = pcie_setup(sys); - } else if (nr == 1 && !orion5x_pci_disabled) { + return pcie_setup(sys); + } + + if (nr == 1 && !orion5x_pci_disabled) { orion5x_pci_set_bus_nr(sys->busnr); - ret = pci_setup(sys); + return pci_setup(sys); } - return ret; + return 0; } struct pci_bus __init *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys) { - struct pci_bus *bus; + if (nr == 0) + return pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys, + &sys->resources); - if (nr == 0) { - bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys, - &sys->resources); - } else if (nr == 1 && !orion5x_pci_disabled) { - bus = pci_scan_root_bus(NULL, sys->busnr, &pci_ops, sys, - &sys->resources); - } else { - bus = NULL; - BUG(); - } + if (nr == 1 && !orion5x_pci_disabled) + return pci_scan_root_bus(NULL, sys->busnr, &pci_ops, sys, + &sys->resources); - return bus; + BUG(); + return NULL; } int __init orion5x_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index a762b23ac830..6dc4f025e674 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -758,8 +758,10 @@ static void raumfeld_power_signal_charged(void) struct power_supply *psy = power_supply_get_by_name(raumfeld_power_supplicants[0]); - if (psy) + if (psy) { power_supply_set_battery_charged(psy); + power_supply_put(psy); + } } static int raumfeld_power_resume(void) diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c index 9e3618028acc..fd63ae6532fc 100644 --- a/arch/arm/mach-shmobile/intc-sh73a0.c +++ b/arch/arm/mach-shmobile/intc-sh73a0.c @@ -252,11 +252,6 @@ static irqreturn_t sh73a0_intcs_demux(int irq, void *dev_id) return IRQ_HANDLED; } -static int sh73a0_set_wake(struct irq_data *data, unsigned int on) -{ - return 0; /* always allow wakeup */ -} - #define PINTER0_PHYS 0xe69000a0 #define PINTER1_PHYS 0xe69000a4 #define PINTER0_VIRT IOMEM(0xe69000a0) @@ -318,8 +313,8 @@ void __init sh73a0_init_irq(void) void __iomem *gic_cpu_base = IOMEM(0xf0000100); void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); + gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE); gic_init(0, 29, gic_dist_base, gic_cpu_base); - gic_arch_extn.irq_set_wake = sh73a0_set_wake; register_intc_controller(&intcs_desc); register_intc_controller(&intc_pint0_desc); diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 27dceaf9e688..c03e562be12b 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -713,18 +713,13 @@ void __init r8a7779_init_late(void) } #ifdef CONFIG_USE_OF -static int r8a7779_set_wake(struct irq_data *data, unsigned int on) -{ - return 0; /* always allow wakeup */ -} - void __init r8a7779_init_irq_dt(void) { #ifdef CONFIG_ARCH_SHMOBILE_LEGACY void __iomem *gic_dist_base = ioremap_nocache(0xf0001000, 0x1000); void __iomem *gic_cpu_base = ioremap_nocache(0xf0000100, 0x1000); #endif - gic_arch_extn.irq_set_wake = r8a7779_set_wake; + gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE); #ifdef CONFIG_ARCH_SHMOBILE_LEGACY gic_init(0, 29, gic_dist_base, gic_cpu_base); diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c index f2b586d7b15d..155807fa6fdd 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra114.c +++ b/arch/arm/mach-tegra/cpuidle-tegra114.c @@ -15,7 +15,7 @@ */ #include <asm/firmware.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <linux/cpuidle.h> #include <linux/cpu_pm.h> #include <linux/kernel.h> @@ -44,7 +44,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev, tegra_set_cpu_in_lp2(); cpu_pm_enter(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); + tick_broadcast_enter(); call_firmware_op(prepare_idle); @@ -52,7 +52,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev, if (call_firmware_op(do_idle, 0) == -ENOSYS) cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); + tick_broadcast_exit(); cpu_pm_exit(); tegra_clear_cpu_in_lp2(); diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c index e22b0d9fdc88..88de2dce2e87 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra20.c +++ b/arch/arm/mach-tegra/cpuidle-tegra20.c @@ -20,7 +20,7 @@ */ #include <linux/clk/tegra.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <linux/cpuidle.h> #include <linux/cpu_pm.h> #include <linux/kernel.h> @@ -135,11 +135,11 @@ static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev, if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready()) return false; - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); + tick_broadcast_enter(); tegra_idle_lp2_last(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); + tick_broadcast_exit(); if (cpu_online(1)) tegra20_wake_cpu1_from_reset(); @@ -152,13 +152,13 @@ static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); + tick_broadcast_enter(); cpu_suspend(0, tegra20_sleep_cpu_secondary_finish); tegra20_cpu_clear_resettable(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); + tick_broadcast_exit(); return true; } diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c index a2400ab44daa..4dbe1dae937c 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra30.c +++ b/arch/arm/mach-tegra/cpuidle-tegra30.c @@ -20,7 +20,7 @@ */ #include <linux/clk/tegra.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <linux/cpuidle.h> #include <linux/cpu_pm.h> #include <linux/kernel.h> @@ -75,11 +75,11 @@ static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev, return false; } - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); + tick_broadcast_enter(); tegra_idle_lp2_last(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); + tick_broadcast_exit(); return true; } @@ -89,13 +89,13 @@ static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); + tick_broadcast_enter(); smp_wmb(); cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); + tick_broadcast_exit(); return true; } diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h index ee79808e93a3..81dc950b4881 100644 --- a/arch/arm/mach-tegra/iomap.h +++ b/arch/arm/mach-tegra/iomap.h @@ -31,21 +31,6 @@ #define TEGRA_ARM_INT_DIST_BASE 0x50041000 #define TEGRA_ARM_INT_DIST_SIZE SZ_4K -#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000 -#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64 - -#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100 -#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64 - -#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200 -#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64 - -#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300 -#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64 - -#define TEGRA_QUINARY_ICTLR_BASE 0x60004400 -#define TEGRA_QUINARY_ICTLR_SIZE SZ_64 - #define TEGRA_TMR1_BASE 0x60005000 #define TEGRA_TMR1_SIZE SZ_8 diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index ab95f5391a2b..3b9098d27ea5 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -30,43 +30,9 @@ #include "board.h" #include "iomap.h" -#define ICTLR_CPU_IEP_VFIQ 0x08 -#define ICTLR_CPU_IEP_FIR 0x14 -#define ICTLR_CPU_IEP_FIR_SET 0x18 -#define ICTLR_CPU_IEP_FIR_CLR 0x1c - -#define ICTLR_CPU_IER 0x20 -#define ICTLR_CPU_IER_SET 0x24 -#define ICTLR_CPU_IER_CLR 0x28 -#define ICTLR_CPU_IEP_CLASS 0x2C - -#define ICTLR_COP_IER 0x30 -#define ICTLR_COP_IER_SET 0x34 -#define ICTLR_COP_IER_CLR 0x38 -#define ICTLR_COP_IEP_CLASS 0x3c - -#define FIRST_LEGACY_IRQ 32 -#define TEGRA_MAX_NUM_ICTLRS 5 - #define SGI_MASK 0xFFFF -static int num_ictlrs; - -static void __iomem *ictlr_reg_base[] = { - IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE), -}; - #ifdef CONFIG_PM_SLEEP -static u32 cop_ier[TEGRA_MAX_NUM_ICTLRS]; -static u32 cop_iep[TEGRA_MAX_NUM_ICTLRS]; -static u32 cpu_ier[TEGRA_MAX_NUM_ICTLRS]; -static u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS]; - -static u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS]; static void __iomem *tegra_gic_cpu_base; #endif @@ -83,140 +49,7 @@ bool tegra_pending_sgi(void) return false; } -static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) -{ - void __iomem *base; - u32 mask; - - BUG_ON(irq < FIRST_LEGACY_IRQ || - irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32); - - base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32]; - mask = BIT((irq - FIRST_LEGACY_IRQ) % 32); - - __raw_writel(mask, base + reg); -} - -static void tegra_mask(struct irq_data *d) -{ - if (d->hwirq < FIRST_LEGACY_IRQ) - return; - - tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IER_CLR); -} - -static void tegra_unmask(struct irq_data *d) -{ - if (d->hwirq < FIRST_LEGACY_IRQ) - return; - - tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IER_SET); -} - -static void tegra_ack(struct irq_data *d) -{ - if (d->hwirq < FIRST_LEGACY_IRQ) - return; - - tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_CLR); -} - -static void tegra_eoi(struct irq_data *d) -{ - if (d->hwirq < FIRST_LEGACY_IRQ) - return; - - tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_CLR); -} - -static int tegra_retrigger(struct irq_data *d) -{ - if (d->hwirq < FIRST_LEGACY_IRQ) - return 0; - - tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_SET); - - return 1; -} - #ifdef CONFIG_PM_SLEEP -static int tegra_set_wake(struct irq_data *d, unsigned int enable) -{ - u32 irq = d->hwirq; - u32 index, mask; - - if (irq < FIRST_LEGACY_IRQ || - irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32) - return -EINVAL; - - index = ((irq - FIRST_LEGACY_IRQ) / 32); - mask = BIT((irq - FIRST_LEGACY_IRQ) % 32); - if (enable) - ictlr_wake_mask[index] |= mask; - else - ictlr_wake_mask[index] &= ~mask; - - return 0; -} - -static int tegra_legacy_irq_suspend(void) -{ - unsigned long flags; - int i; - - local_irq_save(flags); - for (i = 0; i < num_ictlrs; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; - /* Save interrupt state */ - cpu_ier[i] = readl_relaxed(ictlr + ICTLR_CPU_IER); - cpu_iep[i] = readl_relaxed(ictlr + ICTLR_CPU_IEP_CLASS); - cop_ier[i] = readl_relaxed(ictlr + ICTLR_COP_IER); - cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS); - - /* Disable COP interrupts */ - writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR); - - /* Disable CPU interrupts */ - writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR); - - /* Enable the wakeup sources of ictlr */ - writel_relaxed(ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET); - } - local_irq_restore(flags); - - return 0; -} - -static void tegra_legacy_irq_resume(void) -{ - unsigned long flags; - int i; - - local_irq_save(flags); - for (i = 0; i < num_ictlrs; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; - writel_relaxed(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS); - writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR); - writel_relaxed(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET); - writel_relaxed(cop_iep[i], ictlr + ICTLR_COP_IEP_CLASS); - writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR); - writel_relaxed(cop_ier[i], ictlr + ICTLR_COP_IER_SET); - } - local_irq_restore(flags); -} - -static struct syscore_ops tegra_legacy_irq_syscore_ops = { - .suspend = tegra_legacy_irq_suspend, - .resume = tegra_legacy_irq_resume, -}; - -int tegra_legacy_irq_syscore_init(void) -{ - register_syscore_ops(&tegra_legacy_irq_syscore_ops); - - return 0; -} - static int tegra_gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) { @@ -251,45 +84,19 @@ static void tegra114_gic_cpu_pm_registration(void) cpu_pm_register_notifier(&tegra_gic_notifier_block); } #else -#define tegra_set_wake NULL static void tegra114_gic_cpu_pm_registration(void) { } #endif +static const struct of_device_id tegra_ictlr_match[] __initconst = { + { .compatible = "nvidia,tegra20-ictlr" }, + { .compatible = "nvidia,tegra30-ictlr" }, + { } +}; + void __init tegra_init_irq(void) { - int i; - void __iomem *distbase; - - distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE); - num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f; - - if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) { - WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.", - num_ictlrs, ARRAY_SIZE(ictlr_reg_base)); - num_ictlrs = ARRAY_SIZE(ictlr_reg_base); - } - - for (i = 0; i < num_ictlrs; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; - writel(~0, ictlr + ICTLR_CPU_IER_CLR); - writel(0, ictlr + ICTLR_CPU_IEP_CLASS); - } - - gic_arch_extn.irq_ack = tegra_ack; - gic_arch_extn.irq_eoi = tegra_eoi; - gic_arch_extn.irq_mask = tegra_mask; - gic_arch_extn.irq_unmask = tegra_unmask; - gic_arch_extn.irq_retrigger = tegra_retrigger; - gic_arch_extn.irq_set_wake = tegra_set_wake; - gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND; - - /* - * Check if there is a devicetree present, since the GIC will be - * initialized elsewhere under DT. - */ - if (!of_have_populated_dt()) - gic_init(0, 29, distbase, - IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); + if (WARN_ON(!of_find_matching_node(NULL, tegra_ictlr_match))) + pr_warn("Outdated DT detected, suspend/resume will NOT work\n"); tegra114_gic_cpu_pm_registration(); } diff --git a/arch/arm/mach-tegra/irq.h b/arch/arm/mach-tegra/irq.h index bc05ce5613fb..5142649bba05 100644 --- a/arch/arm/mach-tegra/irq.h +++ b/arch/arm/mach-tegra/irq.h @@ -19,10 +19,4 @@ bool tegra_pending_sgi(void); -#ifdef CONFIG_PM_SLEEP -int tegra_legacy_irq_syscore_init(void); -#else -static inline int tegra_legacy_irq_syscore_init(void) { return 0; } -#endif - #endif diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index 914341bcef25..861d88486dbe 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c @@ -82,7 +82,6 @@ static void __init tegra_dt_init_irq(void) { tegra_init_irq(); irqchip_init(); - tegra_legacy_irq_syscore_init(); } static void __init tegra_dt_init(void) diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index dbb2970ee7da..6ced0f680262 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -52,7 +52,7 @@ void ux500_restart(enum reboot_mode mode, const char *cmd) */ void __init ux500_init_irq(void) { - gic_arch_extn.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; + gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND); irqchip_init(); /* diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index c887196cfdbe..58ef2a700414 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -186,7 +186,7 @@ static void __init zynq_map_io(void) static void __init zynq_irq_init(void) { - gic_arch_extn.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; + gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND); irqchip_init(); } diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index c27447653903..e315dfe3af1b 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -2027,6 +2027,13 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size, if (!iommu) return false; + /* + * currently arm_iommu_create_mapping() takes a max of size_t + * for size param. So check this limit for now. + */ + if (size > SIZE_MAX) + return false; + mapping = arm_iommu_create_mapping(dev->bus, dma_base, size); if (IS_ERR(mapping)) { pr_warn("Failed to create %llu-byte IOMMU mapping for device %s\n", diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 1609b022a72f..3d0e9aed4b40 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -335,6 +335,9 @@ void __init bootmem_init(void) find_limits(&min, &max_low, &max_high); + early_memtest((phys_addr_t)min << PAGE_SHIFT, + (phys_addr_t)max_low << PAGE_SHIFT); + /* * Sparsemem tries to allocate bootmem in memory_present(), * so must be done after the fixed reservations diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 5e85ed371364..407dc786583a 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -169,14 +169,22 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, return addr; } +unsigned long arch_mmap_rnd(void) +{ + unsigned long rnd; + + /* 8 bits of randomness in 20 address space bits */ + rnd = (unsigned long)get_random_int() % (1 << 8); + + return rnd << PAGE_SHIFT; +} + void arch_pick_mmap_layout(struct mm_struct *mm) { unsigned long random_factor = 0UL; - /* 8 bits of randomness in 20 address space bits */ - if ((current->flags & PF_RANDOMIZE) && - !(current->personality & ADDR_NO_RANDOMIZE)) - random_factor = (get_random_int() % (1 << 8)) << PAGE_SHIFT; + if (current->flags & PF_RANDOMIZE) + random_factor = arch_mmap_rnd(); if (mmap_is_legacy()) { mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index 61b4d705c267..2438b96004c1 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c @@ -44,24 +44,20 @@ static u64 notrace omap_32k_read_sched_clock(void) } /** - * omap_read_persistent_clock - Return time from a persistent clock. + * omap_read_persistent_clock64 - Return time from a persistent clock. * * Reads the time from a source which isn't disabled during PM, the * 32k sync timer. Convert the cycles elapsed since last read into - * nsecs and adds to a monotonically increasing timespec. + * nsecs and adds to a monotonically increasing timespec64. */ -static struct timespec persistent_ts; +static struct timespec64 persistent_ts; static cycles_t cycles; static unsigned int persistent_mult, persistent_shift; -static DEFINE_SPINLOCK(read_persistent_clock_lock); -static void omap_read_persistent_clock(struct timespec *ts) +static void omap_read_persistent_clock64(struct timespec64 *ts) { unsigned long long nsecs; cycles_t last_cycles; - unsigned long flags; - - spin_lock_irqsave(&read_persistent_clock_lock, flags); last_cycles = cycles; cycles = sync32k_cnt_reg ? readl_relaxed(sync32k_cnt_reg) : 0; @@ -69,11 +65,9 @@ static void omap_read_persistent_clock(struct timespec *ts) nsecs = clocksource_cyc2ns(cycles - last_cycles, persistent_mult, persistent_shift); - timespec_add_ns(&persistent_ts, nsecs); + timespec64_add_ns(&persistent_ts, nsecs); *ts = persistent_ts; - - spin_unlock_irqrestore(&read_persistent_clock_lock, flags); } /** @@ -103,7 +97,7 @@ int __init omap_init_clocksource_32k(void __iomem *vbase) /* * 120000 rough estimate from the calculations in - * __clocksource_updatefreq_scale. + * __clocksource_update_freq_scale. */ clocks_calc_mult_shift(&persistent_mult, &persistent_shift, 32768, NSEC_PER_SEC, 120000); @@ -116,7 +110,7 @@ int __init omap_init_clocksource_32k(void __iomem *vbase) } sched_clock_register(omap_32k_read_sched_clock, 32, 32768); - register_persistent_clock(NULL, omap_read_persistent_clock); + register_persistent_clock(NULL, omap_read_persistent_clock64); pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n"); return 0; |