aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/gic.txt6
-rw-r--r--Documentation/devicetree/bindings/arm/omap/crossbar.txt18
-rw-r--r--Documentation/devicetree/bindings/arm/samsung/pmu.txt17
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra-ictlr.txt43
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu33
-rw-r--r--arch/arm/boot/dts/am4372.dtsi11
-rw-r--r--arch/arm/boot/dts/am437x-gp-evm.dts1
-rw-r--r--arch/arm/boot/dts/am437x-sk-evm.dts1
-rw-r--r--arch/arm/boot/dts/am43x-epos-evm.dts1
-rw-r--r--arch/arm/boot/dts/am57xx-beagle-x15.dts3
-rw-r--r--arch/arm/boot/dts/dra7-evm.dts2
-rw-r--r--arch/arm/boot/dts/dra7.dtsi43
-rw-r--r--arch/arm/boot/dts/dra72-evm.dts1
-rw-r--r--arch/arm/boot/dts/dra72x.dtsi3
-rw-r--r--arch/arm/boot/dts/dra74x.dtsi5
-rw-r--r--arch/arm/boot/dts/exynos3250.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos4.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos5420.dtsi4
-rw-r--r--arch/arm/boot/dts/omap4-duovero.dtsi2
-rw-r--r--arch/arm/boot/dts/omap4-panda-common.dtsi8
-rw-r--r--arch/arm/boot/dts/omap4-sdp.dts8
-rw-r--r--arch/arm/boot/dts/omap4-var-som-om44.dtsi2
-rw-r--r--arch/arm/boot/dts/omap4.dtsi18
-rw-r--r--arch/arm/boot/dts/omap5-cm-t54.dts1
-rw-r--r--arch/arm/boot/dts/omap5-uevm.dts2
-rw-r--r--arch/arm/boot/dts/omap5.dtsi26
-rw-r--r--arch/arm/boot/dts/tegra114.dtsi16
-rw-r--r--arch/arm/boot/dts/tegra124.dtsi16
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi15
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi16
-rw-r--r--arch/arm/mach-exynos/exynos.c15
-rw-r--r--arch/arm/mach-exynos/suspend.c135
-rw-r--r--arch/arm/mach-omap2/omap-wakeupgen.c128
-rw-r--r--arch/arm/mach-omap2/omap-wakeupgen.h1
-rw-r--r--arch/arm/mach-omap2/omap4-common.c27
-rw-r--r--arch/arm/mach-shmobile/intc-sh73a0.c7
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c7
-rw-r--r--arch/arm/mach-tegra/iomap.h15
-rw-r--r--arch/arm/mach-tegra/irq.c209
-rw-r--r--arch/arm/mach-tegra/irq.h6
-rw-r--r--arch/arm/mach-tegra/tegra.c1
-rw-r--r--arch/arm/mach-ux500/cpu.c2
-rw-r--r--arch/arm/mach-zynq/common.c2
-rw-r--r--drivers/irqchip/Makefile1
-rw-r--r--drivers/irqchip/irq-crossbar.c210
-rw-r--r--drivers/irqchip/irq-gic.c58
-rw-r--r--drivers/irqchip/irq-tegra.c377
-rw-r--r--include/linux/irq.h1
-rw-r--r--include/linux/irqchip/arm-gic.h7
-rw-r--r--include/linux/irqchip/irq-crossbar.h11
-rw-r--r--kernel/irq/chip.c16
52 files changed, 1032 insertions, 538 deletions
diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt
index c97484b73e72..1e0d21201d3a 100644
--- a/Documentation/devicetree/bindings/arm/gic.txt
+++ b/Documentation/devicetree/bindings/arm/gic.txt
@@ -56,11 +56,6 @@ Optional
56 regions, used when the GIC doesn't have banked registers. The offset is 56 regions, used when the GIC doesn't have banked registers. The offset is
57 cpu-offset * cpu-nr. 57 cpu-offset * cpu-nr.
58 58
59- arm,routable-irqs : Total number of gic irq inputs which are not directly
60 connected from the peripherals, but are routed dynamically
61 by a crossbar/multiplexer preceding the GIC. The GIC irq
62 input line is assigned dynamically when the corresponding
63 peripheral's crossbar line is mapped.
64Example: 59Example:
65 60
66 intc: interrupt-controller@fff11000 { 61 intc: interrupt-controller@fff11000 {
@@ -68,7 +63,6 @@ Example:
68 #interrupt-cells = <3>; 63 #interrupt-cells = <3>;
69 #address-cells = <1>; 64 #address-cells = <1>;
70 interrupt-controller; 65 interrupt-controller;
71 arm,routable-irqs = <160>;
72 reg = <0xfff11000 0x1000>, 66 reg = <0xfff11000 0x1000>,
73 <0xfff10100 0x100>; 67 <0xfff10100 0x100>;
74 }; 68 };
diff --git a/Documentation/devicetree/bindings/arm/omap/crossbar.txt b/Documentation/devicetree/bindings/arm/omap/crossbar.txt
index 4139db353d0a..a9b28d74d902 100644
--- a/Documentation/devicetree/bindings/arm/omap/crossbar.txt
+++ b/Documentation/devicetree/bindings/arm/omap/crossbar.txt
@@ -9,7 +9,9 @@ inputs.
9Required properties: 9Required properties:
10- compatible : Should be "ti,irq-crossbar" 10- compatible : Should be "ti,irq-crossbar"
11- reg: Base address and the size of the crossbar registers. 11- reg: Base address and the size of the crossbar registers.
12- ti,max-irqs: Total number of irqs available at the interrupt controller. 12- interrupt-controller: indicates that this block is an interrupt controller.
13- interrupt-parent: the interrupt controller this block is connected to.
14- ti,max-irqs: Total number of irqs available at the parent interrupt controller.
13- ti,max-crossbar-sources: Maximum number of crossbar sources that can be routed. 15- ti,max-crossbar-sources: Maximum number of crossbar sources that can be routed.
14- ti,reg-size: Size of a individual register in bytes. Every individual 16- ti,reg-size: Size of a individual register in bytes. Every individual
15 register is assumed to be of same size. Valid sizes are 1, 2, 4. 17 register is assumed to be of same size. Valid sizes are 1, 2, 4.
@@ -27,13 +29,13 @@ Optional properties:
27 when the interrupt controller irq is unused (when not provided, default is 0) 29 when the interrupt controller irq is unused (when not provided, default is 0)
28 30
29Examples: 31Examples:
30 crossbar_mpu: @4a020000 { 32 crossbar_mpu: crossbar@4a002a48 {
31 compatible = "ti,irq-crossbar"; 33 compatible = "ti,irq-crossbar";
32 reg = <0x4a002a48 0x130>; 34 reg = <0x4a002a48 0x130>;
33 ti,max-irqs = <160>; 35 ti,max-irqs = <160>;
34 ti,max-crossbar-sources = <400>; 36 ti,max-crossbar-sources = <400>;
35 ti,reg-size = <2>; 37 ti,reg-size = <2>;
36 ti,irqs-reserved = <0 1 2 3 5 6 131 132 139 140>; 38 ti,irqs-reserved = <0 1 2 3 5 6 131 132>;
37 ti,irqs-skip = <10 133 139 140>; 39 ti,irqs-skip = <10 133 139 140>;
38 }; 40 };
39 41
@@ -44,10 +46,6 @@ Documentation/devicetree/bindings/arm/gic.txt for further details.
44 46
45An interrupt consumer on an SoC using crossbar will use: 47An interrupt consumer on an SoC using crossbar will use:
46 interrupts = <GIC_SPI request_number interrupt_level> 48 interrupts = <GIC_SPI request_number interrupt_level>
47When the request number is between 0 to that described by
48"ti,max-crossbar-sources", it is assumed to be a crossbar mapping. If the
49request_number is greater than "ti,max-crossbar-sources", then it is mapped as a
50quirky hardware mapping direct to GIC.
51 49
52Example: 50Example:
53 device_x@0x4a023000 { 51 device_x@0x4a023000 {
@@ -55,9 +53,3 @@ Example:
55 interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; 53 interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
56 ... 54 ...
57 }; 55 };
58
59 device_y@0x4a033000 {
60 /* Direct mapped GIC SPI 1 used */
61 interrupts = <GIC_SPI DIRECT_IRQ(1) IRQ_TYPE_LEVEL_HIGH>;
62 ...
63 };
diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
index 67b211381f2b..2d6356d8daf4 100644
--- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
@@ -29,10 +29,27 @@ Properties:
29 - clocks : list of phandles and specifiers to all input clocks listed in 29 - clocks : list of phandles and specifiers to all input clocks listed in
30 clock-names property. 30 clock-names property.
31 31
32Optional properties:
33
34Some PMUs are capable of behaving as an interrupt controller (mostly
35to wake up a suspended PMU). In which case, they can have the
36following properties:
37
38- interrupt-controller: indicate that said PMU is an interrupt controller
39
40- #interrupt-cells: must be identical to the that of the parent interrupt
41 controller.
42
43- interrupt-parent: a phandle indicating which interrupt controller
44 this PMU signals interrupts to.
45
32Example : 46Example :
33pmu_system_controller: system-controller@10040000 { 47pmu_system_controller: system-controller@10040000 {
34 compatible = "samsung,exynos5250-pmu", "syscon"; 48 compatible = "samsung,exynos5250-pmu", "syscon";
35 reg = <0x10040000 0x5000>; 49 reg = <0x10040000 0x5000>;
50 interrupt-controller;
51 #interrupt-cells = <3>;
52 interrupt-parent = <&gic>;
36 #clock-cells = <1>; 53 #clock-cells = <1>;
37 clock-names = "clkout0", "clkout1", "clkout2", "clkout3", 54 clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
38 "clkout4", "clkout8", "clkout9"; 55 "clkout4", "clkout8", "clkout9";
diff --git a/Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra-ictlr.txt b/Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra-ictlr.txt
new file mode 100644
index 000000000000..1099fe0788fa
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra-ictlr.txt
@@ -0,0 +1,43 @@
1NVIDIA Legacy Interrupt Controller
2
3All Tegra SoCs contain a legacy interrupt controller that routes
4interrupts to the GIC, and also serves as a wakeup source. It is also
5referred to as "ictlr", hence the name of the binding.
6
7The HW block exposes a number of interrupt controllers, each
8implementing a set of 32 interrupts.
9
10Required properties:
11
12- compatible : should be: "nvidia,tegra<chip>-ictlr". The LIC on
13 subsequent SoCs remained backwards-compatible with Tegra30, so on
14 Tegra generations later than Tegra30 the compatible value should
15 include "nvidia,tegra30-ictlr".
16- reg : Specifies base physical address and size of the registers.
17 Each controller must be described separately (Tegra20 has 4 of them,
18 whereas Tegra30 and later have 5"
19- interrupt-controller : Identifies the node as an interrupt controller.
20- #interrupt-cells : Specifies the number of cells needed to encode an
21 interrupt source. The value must be 3.
22- interrupt-parent : a phandle to the GIC these interrupts are routed
23 to.
24
25Notes:
26
27- Because this HW ultimately routes interrupts to the GIC, the
28 interrupt specifier must be that of the GIC.
29- Only SPIs can use the ictlr as an interrupt parent. SGIs and PPIs
30 are explicitly forbidden.
31
32Example:
33
34 ictlr: interrupt-controller@60004000 {
35 compatible = "nvidia,tegra20-ictlr", "nvidia,tegra-ictlr";
36 reg = <0x60004000 64>,
37 <0x60004100 64>,
38 <0x60004200 64>,
39 <0x60004300 64>;
40 interrupt-controller;
41 #interrupt-cells = <3>;
42 interrupt-parent = <&intc>;
43 };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu b/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu
new file mode 100644
index 000000000000..43effa0a4fe7
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu
@@ -0,0 +1,33 @@
1TI OMAP4 Wake-up Generator
2
3All TI OMAP4/5 (and their derivatives) an interrupt controller that
4routes interrupts to the GIC, and also serves as a wakeup source. It
5is also referred to as "WUGEN-MPU", hence the name of the binding.
6
7Reguired properties:
8
9- compatible : should contain at least "ti,omap4-wugen-mpu" or
10 "ti,omap5-wugen-mpu"
11- reg : Specifies base physical address and size of the registers.
12- interrupt-controller : Identifies the node as an interrupt controller.
13- #interrupt-cells : Specifies the number of cells needed to encode an
14 interrupt source. The value must be 3.
15- interrupt-parent : a phandle to the GIC these interrupts are routed
16 to.
17
18Notes:
19
20- Because this HW ultimately routes interrupts to the GIC, the
21 interrupt specifier must be that of the GIC.
22- Only SPIs can use the WUGEN as an interrupt parent. SGIs and PPIs
23 are explicitly forbiden.
24
25Example:
26
27 wakeupgen: interrupt-controller@48281000 {
28 compatible = "ti,omap5-wugen-mpu", "ti,omap4-wugen-mpu";
29 interrupt-controller;
30 #interrupt-cells = <3>;
31 reg = <0x48281000 0x1000>;
32 interrupt-parent = <&gic>;
33 };
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 @@
15 15
16/ { 16/ {
17 compatible = "ti,am4372", "ti,am43"; 17 compatible = "ti,am4372", "ti,am43";
18 interrupt-parent = <&gic>; 18 interrupt-parent = <&wakeupgen>;
19 19
20 20
21 aliases { 21 aliases {
@@ -48,6 +48,15 @@
48 #interrupt-cells = <3>; 48 #interrupt-cells = <3>;
49 reg = <0x48241000 0x1000>, 49 reg = <0x48241000 0x1000>,
50 <0x48240100 0x0100>; 50 <0x48240100 0x0100>;
51 interrupt-parent = <&gic>;
52 };
53
54 wakeupgen: interrupt-controller@48281000 {
55 compatible = "ti,omap4-wugen-mpu";
56 interrupt-controller;
57 #interrupt-cells = <3>;
58 reg = <0x48281000 0x1000>;
59 interrupt-parent = <&gic>;
51 }; 60 };
52 61
53 l2-cache-controller@48242000 { 62 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 @@
352 reg = <0x24>; 352 reg = <0x24>;
353 compatible = "ti,tps65218"; 353 compatible = "ti,tps65218";
354 interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */ 354 interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */
355 interrupt-parent = <&gic>;
356 interrupt-controller; 355 interrupt-controller;
357 #interrupt-cells = <2>; 356 #interrupt-cells = <2>;
358 357
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 @@
392 tps@24 { 392 tps@24 {
393 compatible = "ti,tps65218"; 393 compatible = "ti,tps65218";
394 reg = <0x24>; 394 reg = <0x24>;
395 interrupt-parent = <&gic>;
396 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; 395 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
397 interrupt-controller; 396 interrupt-controller;
398 #interrupt-cells = <2>; 397 #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 @@
369 reg = <0x24>; 369 reg = <0x24>;
370 compatible = "ti,tps65218"; 370 compatible = "ti,tps65218";
371 interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */ 371 interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */
372 interrupt-parent = <&gic>;
373 interrupt-controller; 372 interrupt-controller;
374 #interrupt-cells = <2>; 373 #interrupt-cells = <2>;
375 374
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 @@
454 mcp_rtc: rtc@6f { 454 mcp_rtc: rtc@6f {
455 compatible = "microchip,mcp7941x"; 455 compatible = "microchip,mcp7941x";
456 reg = <0x6f>; 456 reg = <0x6f>;
457 interrupt-parent = <&gic>;
458 interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_LOW>; /* IRQ_SYS_1N */ 457 interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_LOW>; /* IRQ_SYS_1N */
459 458
460 pinctrl-names = "default"; 459 pinctrl-names = "default";
@@ -477,7 +476,7 @@
477 476
478&uart3 { 477&uart3 {
479 status = "okay"; 478 status = "okay";
480 interrupts-extended = <&gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>, 479 interrupts-extended = <&crossbar_mpu GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
481 <&dra7_pmx_core 0x248>; 480 <&dra7_pmx_core 0x248>;
482 481
483 pinctrl-names = "default"; 482 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 @@
444 status = "okay"; 444 status = "okay";
445 pinctrl-names = "default"; 445 pinctrl-names = "default";
446 pinctrl-0 = <&uart1_pins>; 446 pinctrl-0 = <&uart1_pins>;
447 interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, 447 interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
448 <&dra7_pmx_core 0x3e0>; 448 <&dra7_pmx_core 0x3e0>;
449}; 449};
450 450
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 @@
13#include "skeleton.dtsi" 13#include "skeleton.dtsi"
14 14
15#define MAX_SOURCES 400 15#define MAX_SOURCES 400
16#define DIRECT_IRQ(irq) (MAX_SOURCES + irq)
17 16
18/ { 17/ {
19 #address-cells = <1>; 18 #address-cells = <1>;
20 #size-cells = <1>; 19 #size-cells = <1>;
21 20
22 compatible = "ti,dra7xx"; 21 compatible = "ti,dra7xx";
23 interrupt-parent = <&gic>; 22 interrupt-parent = <&crossbar_mpu>;
24 23
25 aliases { 24 aliases {
26 i2c0 = &i2c1; 25 i2c0 = &i2c1;
@@ -50,18 +49,27 @@
50 <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, 49 <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
51 <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, 50 <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
52 <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; 51 <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
52 interrupt-parent = <&gic>;
53 }; 53 };
54 54
55 gic: interrupt-controller@48211000 { 55 gic: interrupt-controller@48211000 {
56 compatible = "arm,cortex-a15-gic"; 56 compatible = "arm,cortex-a15-gic";
57 interrupt-controller; 57 interrupt-controller;
58 #interrupt-cells = <3>; 58 #interrupt-cells = <3>;
59 arm,routable-irqs = <192>;
60 reg = <0x48211000 0x1000>, 59 reg = <0x48211000 0x1000>,
61 <0x48212000 0x1000>, 60 <0x48212000 0x1000>,
62 <0x48214000 0x2000>, 61 <0x48214000 0x2000>,
63 <0x48216000 0x2000>; 62 <0x48216000 0x2000>;
64 interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; 63 interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
64 interrupt-parent = <&gic>;
65 };
66
67 wakeupgen: interrupt-controller@48281000 {
68 compatible = "ti,omap5-wugen-mpu", "ti,omap4-wugen-mpu";
69 interrupt-controller;
70 #interrupt-cells = <3>;
71 reg = <0x48281000 0x1000>;
72 interrupt-parent = <&gic>;
65 }; 73 };
66 74
67 /* 75 /*
@@ -91,8 +99,8 @@
91 ti,hwmods = "l3_main_1", "l3_main_2"; 99 ti,hwmods = "l3_main_1", "l3_main_2";
92 reg = <0x44000000 0x1000000>, 100 reg = <0x44000000 0x1000000>,
93 <0x45000000 0x1000>; 101 <0x45000000 0x1000>;
94 interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, 102 interrupts-extended = <&crossbar_mpu GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
95 <GIC_SPI DIRECT_IRQ(10) IRQ_TYPE_LEVEL_HIGH>; 103 <&wakeupgen GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
96 104
97 prm: prm@4ae06000 { 105 prm: prm@4ae06000 {
98 compatible = "ti,dra7-prm"; 106 compatible = "ti,dra7-prm";
@@ -344,7 +352,7 @@
344 uart1: serial@4806a000 { 352 uart1: serial@4806a000 {
345 compatible = "ti,omap4-uart"; 353 compatible = "ti,omap4-uart";
346 reg = <0x4806a000 0x100>; 354 reg = <0x4806a000 0x100>;
347 interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; 355 interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
348 ti,hwmods = "uart1"; 356 ti,hwmods = "uart1";
349 clock-frequency = <48000000>; 357 clock-frequency = <48000000>;
350 status = "disabled"; 358 status = "disabled";
@@ -355,7 +363,7 @@
355 uart2: serial@4806c000 { 363 uart2: serial@4806c000 {
356 compatible = "ti,omap4-uart"; 364 compatible = "ti,omap4-uart";
357 reg = <0x4806c000 0x100>; 365 reg = <0x4806c000 0x100>;
358 interrupts-extended = <&gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; 366 interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
359 ti,hwmods = "uart2"; 367 ti,hwmods = "uart2";
360 clock-frequency = <48000000>; 368 clock-frequency = <48000000>;
361 status = "disabled"; 369 status = "disabled";
@@ -366,7 +374,7 @@
366 uart3: serial@48020000 { 374 uart3: serial@48020000 {
367 compatible = "ti,omap4-uart"; 375 compatible = "ti,omap4-uart";
368 reg = <0x48020000 0x100>; 376 reg = <0x48020000 0x100>;
369 interrupts-extended = <&gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; 377 interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
370 ti,hwmods = "uart3"; 378 ti,hwmods = "uart3";
371 clock-frequency = <48000000>; 379 clock-frequency = <48000000>;
372 status = "disabled"; 380 status = "disabled";
@@ -377,7 +385,7 @@
377 uart4: serial@4806e000 { 385 uart4: serial@4806e000 {
378 compatible = "ti,omap4-uart"; 386 compatible = "ti,omap4-uart";
379 reg = <0x4806e000 0x100>; 387 reg = <0x4806e000 0x100>;
380 interrupts-extended = <&gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; 388 interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
381 ti,hwmods = "uart4"; 389 ti,hwmods = "uart4";
382 clock-frequency = <48000000>; 390 clock-frequency = <48000000>;
383 status = "disabled"; 391 status = "disabled";
@@ -388,7 +396,7 @@
388 uart5: serial@48066000 { 396 uart5: serial@48066000 {
389 compatible = "ti,omap4-uart"; 397 compatible = "ti,omap4-uart";
390 reg = <0x48066000 0x100>; 398 reg = <0x48066000 0x100>;
391 interrupts-extended = <&gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; 399 interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
392 ti,hwmods = "uart5"; 400 ti,hwmods = "uart5";
393 clock-frequency = <48000000>; 401 clock-frequency = <48000000>;
394 status = "disabled"; 402 status = "disabled";
@@ -399,7 +407,7 @@
399 uart6: serial@48068000 { 407 uart6: serial@48068000 {
400 compatible = "ti,omap4-uart"; 408 compatible = "ti,omap4-uart";
401 reg = <0x48068000 0x100>; 409 reg = <0x48068000 0x100>;
402 interrupts-extended = <&gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; 410 interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
403 ti,hwmods = "uart6"; 411 ti,hwmods = "uart6";
404 clock-frequency = <48000000>; 412 clock-frequency = <48000000>;
405 status = "disabled"; 413 status = "disabled";
@@ -410,7 +418,7 @@
410 uart7: serial@48420000 { 418 uart7: serial@48420000 {
411 compatible = "ti,omap4-uart"; 419 compatible = "ti,omap4-uart";
412 reg = <0x48420000 0x100>; 420 reg = <0x48420000 0x100>;
413 interrupts-extended = <&gic GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>; 421 interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>;
414 ti,hwmods = "uart7"; 422 ti,hwmods = "uart7";
415 clock-frequency = <48000000>; 423 clock-frequency = <48000000>;
416 status = "disabled"; 424 status = "disabled";
@@ -419,7 +427,7 @@
419 uart8: serial@48422000 { 427 uart8: serial@48422000 {
420 compatible = "ti,omap4-uart"; 428 compatible = "ti,omap4-uart";
421 reg = <0x48422000 0x100>; 429 reg = <0x48422000 0x100>;
422 interrupts-extended = <&gic GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>; 430 interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
423 ti,hwmods = "uart8"; 431 ti,hwmods = "uart8";
424 clock-frequency = <48000000>; 432 clock-frequency = <48000000>;
425 status = "disabled"; 433 status = "disabled";
@@ -428,7 +436,7 @@
428 uart9: serial@48424000 { 436 uart9: serial@48424000 {
429 compatible = "ti,omap4-uart"; 437 compatible = "ti,omap4-uart";
430 reg = <0x48424000 0x100>; 438 reg = <0x48424000 0x100>;
431 interrupts-extended = <&gic GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>; 439 interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
432 ti,hwmods = "uart9"; 440 ti,hwmods = "uart9";
433 clock-frequency = <48000000>; 441 clock-frequency = <48000000>;
434 status = "disabled"; 442 status = "disabled";
@@ -437,7 +445,7 @@
437 uart10: serial@4ae2b000 { 445 uart10: serial@4ae2b000 {
438 compatible = "ti,omap4-uart"; 446 compatible = "ti,omap4-uart";
439 reg = <0x4ae2b000 0x100>; 447 reg = <0x4ae2b000 0x100>;
440 interrupts-extended = <&gic GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>; 448 interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
441 ti,hwmods = "uart10"; 449 ti,hwmods = "uart10";
442 clock-frequency = <48000000>; 450 clock-frequency = <48000000>;
443 status = "disabled"; 451 status = "disabled";
@@ -1335,9 +1343,12 @@
1335 status = "disabled"; 1343 status = "disabled";
1336 }; 1344 };
1337 1345
1338 crossbar_mpu: crossbar@4a020000 { 1346 crossbar_mpu: crossbar@4a002a48 {
1339 compatible = "ti,irq-crossbar"; 1347 compatible = "ti,irq-crossbar";
1340 reg = <0x4a002a48 0x130>; 1348 reg = <0x4a002a48 0x130>;
1349 interrupt-controller;
1350 interrupt-parent = <&wakeupgen>;
1351 #interrupt-cells = <3>;
1341 ti,max-irqs = <160>; 1352 ti,max-irqs = <160>;
1342 ti,max-crossbar-sources = <MAX_SOURCES>; 1353 ti,max-crossbar-sources = <MAX_SOURCES>;
1343 ti,reg-size = <2>; 1354 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 @@
158 pinctrl-0 = <&tps65917_pins_default>; 158 pinctrl-0 = <&tps65917_pins_default>;
159 159
160 interrupts = <GIC_SPI 2 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */ 160 interrupts = <GIC_SPI 2 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
161 interrupt-parent = <&gic>;
162 interrupt-controller; 161 interrupt-controller;
163 #interrupt-cells = <2>; 162 #interrupt-cells = <2>;
164 163
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 @@
25 25
26 pmu { 26 pmu {
27 compatible = "arm,cortex-a15-pmu"; 27 compatible = "arm,cortex-a15-pmu";
28 interrupts = <GIC_SPI DIRECT_IRQ(131) IRQ_TYPE_LEVEL_HIGH>; 28 interrupt-parent = <&wakeupgen>;
29 interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
29 }; 30 };
30}; 31};
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 @@
41 41
42 pmu { 42 pmu {
43 compatible = "arm,cortex-a15-pmu"; 43 compatible = "arm,cortex-a15-pmu";
44 interrupts = <GIC_SPI DIRECT_IRQ(131) IRQ_TYPE_LEVEL_HIGH>, 44 interrupt-parent = <&wakeupgen>;
45 <GIC_SPI DIRECT_IRQ(132) IRQ_TYPE_LEVEL_HIGH>; 45 interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
46 <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
46 }; 47 };
47 48
48 ocp { 49 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 @@
131 pmu_system_controller: system-controller@10020000 { 131 pmu_system_controller: system-controller@10020000 {
132 compatible = "samsung,exynos3250-pmu", "syscon"; 132 compatible = "samsung,exynos3250-pmu", "syscon";
133 reg = <0x10020000 0x4000>; 133 reg = <0x10020000 0x4000>;
134 interrupt-controller;
135 #interrupt-cells = <3>;
136 interrupt-parent = <&gic>;
134 }; 137 };
135 138
136 mipi_phy: video-phy@10020710 { 139 mipi_phy: video-phy@10020710 {
@@ -185,6 +188,7 @@
185 compatible = "samsung,exynos3250-rtc"; 188 compatible = "samsung,exynos3250-rtc";
186 reg = <0x10070000 0x100>; 189 reg = <0x10070000 0x100>;
187 interrupts = <0 73 0>, <0 74 0>; 190 interrupts = <0 73 0>, <0 74 0>;
191 interrupt-parent = <&pmu_system_controller>;
188 status = "disabled"; 192 status = "disabled";
189 }; 193 };
190 194
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 @@
154 pmu_system_controller: system-controller@10020000 { 154 pmu_system_controller: system-controller@10020000 {
155 compatible = "samsung,exynos4210-pmu", "syscon"; 155 compatible = "samsung,exynos4210-pmu", "syscon";
156 reg = <0x10020000 0x4000>; 156 reg = <0x10020000 0x4000>;
157 interrupt-controller;
158 #interrupt-cells = <3>;
159 interrupt-parent = <&gic>;
157 }; 160 };
158 161
159 dsi_0: dsi@11C80000 { 162 dsi_0: dsi@11C80000 {
@@ -266,6 +269,7 @@
266 rtc@10070000 { 269 rtc@10070000 {
267 compatible = "samsung,s3c6410-rtc"; 270 compatible = "samsung,s3c6410-rtc";
268 reg = <0x10070000 0x100>; 271 reg = <0x10070000 0x100>;
272 interrupt-parent = <&pmu_system_controller>;
269 interrupts = <0 44 0>, <0 45 0>; 273 interrupts = <0 44 0>, <0 45 0>;
270 clocks = <&clock CLK_RTC>; 274 clocks = <&clock CLK_RTC>;
271 clock-names = "rtc"; 275 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 @@
205 clock-names = "clkout16"; 205 clock-names = "clkout16";
206 clocks = <&clock CLK_FIN_PLL>; 206 clocks = <&clock CLK_FIN_PLL>;
207 #clock-cells = <1>; 207 #clock-cells = <1>;
208 interrupt-controller;
209 #interrupt-cells = <3>;
210 interrupt-parent = <&gic>;
208 }; 211 };
209 212
210 sysreg_system_controller: syscon@10050000 { 213 sysreg_system_controller: syscon@10050000 {
@@ -241,6 +244,7 @@
241 rtc: rtc@101E0000 { 244 rtc: rtc@101E0000 {
242 clocks = <&clock CLK_RTC>; 245 clocks = <&clock CLK_RTC>;
243 clock-names = "rtc"; 246 clock-names = "rtc";
247 interrupt-parent = <&pmu_system_controller>;
244 status = "disabled"; 248 status = "disabled";
245 }; 249 };
246 250
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 @@
327 rtc: rtc@101E0000 { 327 rtc: rtc@101E0000 {
328 clocks = <&clock CLK_RTC>; 328 clocks = <&clock CLK_RTC>;
329 clock-names = "rtc"; 329 clock-names = "rtc";
330 interrupt-parent = <&pmu_system_controller>;
330 status = "disabled"; 331 status = "disabled";
331 }; 332 };
332 333
@@ -770,6 +771,9 @@
770 clock-names = "clkout16"; 771 clock-names = "clkout16";
771 clocks = <&clock CLK_FIN_PLL>; 772 clocks = <&clock CLK_FIN_PLL>;
772 #clock-cells = <1>; 773 #clock-cells = <1>;
774 interrupt-controller;
775 #interrupt-cells = <3>;
776 interrupt-parent = <&gic>;
773 }; 777 };
774 778
775 sysreg_system_controller: syscon@10050000 { 779 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 @@
173 twl: twl@48 { 173 twl: twl@48 {
174 reg = <0x48>; 174 reg = <0x48>;
175 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */ 175 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
176 interrupt-parent = <&gic>;
177 }; 176 };
178 177
179 twl6040: twl@4b { 178 twl6040: twl@4b {
180 compatible = "ti,twl6040"; 179 compatible = "ti,twl6040";
181 reg = <0x4b>; 180 reg = <0x4b>;
182 interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */ 181 interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
183 interrupt-parent = <&gic>;
184 ti,audpwron-gpio = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* gpio_160 */ 182 ti,audpwron-gpio = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* gpio_160 */
185 183
186 vio-supply = <&v1v8>; 184 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 @@
372 reg = <0x48>; 372 reg = <0x48>;
373 /* IRQ# = 7 */ 373 /* IRQ# = 7 */
374 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */ 374 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
375 interrupt-parent = <&gic>;
376 }; 375 };
377 376
378 twl6040: twl@4b { 377 twl6040: twl@4b {
@@ -384,7 +383,6 @@
384 383
385 /* IRQ# = 119 */ 384 /* IRQ# = 119 */
386 interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */ 385 interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
387 interrupt-parent = <&gic>;
388 ti,audpwron-gpio = <&gpio4 31 GPIO_ACTIVE_HIGH>; /* gpio line 127 */ 386 ti,audpwron-gpio = <&gpio4 31 GPIO_ACTIVE_HIGH>; /* gpio line 127 */
389 387
390 vio-supply = <&v1v8>; 388 vio-supply = <&v1v8>;
@@ -479,17 +477,17 @@
479}; 477};
480 478
481&uart2 { 479&uart2 {
482 interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH 480 interrupts-extended = <&wakeupgen GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH
483 &omap4_pmx_core OMAP4_UART2_RX>; 481 &omap4_pmx_core OMAP4_UART2_RX>;
484}; 482};
485 483
486&uart3 { 484&uart3 {
487 interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH 485 interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
488 &omap4_pmx_core OMAP4_UART3_RX>; 486 &omap4_pmx_core OMAP4_UART3_RX>;
489}; 487};
490 488
491&uart4 { 489&uart4 {
492 interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH 490 interrupts-extended = <&wakeupgen GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH
493 &omap4_pmx_core OMAP4_UART4_RX>; 491 &omap4_pmx_core OMAP4_UART4_RX>;
494}; 492};
495 493
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 @@
363 reg = <0x48>; 363 reg = <0x48>;
364 /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */ 364 /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
365 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */ 365 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
366 interrupt-parent = <&gic>;
367 }; 366 };
368 367
369 twl6040: twl@4b { 368 twl6040: twl@4b {
@@ -375,7 +374,6 @@
375 374
376 /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */ 375 /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
377 interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */ 376 interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
378 interrupt-parent = <&gic>;
379 ti,audpwron-gpio = <&gpio4 31 0>; /* gpio line 127 */ 377 ti,audpwron-gpio = <&gpio4 31 0>; /* gpio line 127 */
380 378
381 vio-supply = <&v1v8>; 379 vio-supply = <&v1v8>;
@@ -570,21 +568,21 @@
570}; 568};
571 569
572&uart2 { 570&uart2 {
573 interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH 571 interrupts-extended = <&wakeupgen GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH
574 &omap4_pmx_core OMAP4_UART2_RX>; 572 &omap4_pmx_core OMAP4_UART2_RX>;
575 pinctrl-names = "default"; 573 pinctrl-names = "default";
576 pinctrl-0 = <&uart2_pins>; 574 pinctrl-0 = <&uart2_pins>;
577}; 575};
578 576
579&uart3 { 577&uart3 {
580 interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH 578 interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
581 &omap4_pmx_core OMAP4_UART3_RX>; 579 &omap4_pmx_core OMAP4_UART3_RX>;
582 pinctrl-names = "default"; 580 pinctrl-names = "default";
583 pinctrl-0 = <&uart3_pins>; 581 pinctrl-0 = <&uart3_pins>;
584}; 582};
585 583
586&uart4 { 584&uart4 {
587 interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH 585 interrupts-extended = <&wakeupgen GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH
588 &omap4_pmx_core OMAP4_UART4_RX>; 586 &omap4_pmx_core OMAP4_UART4_RX>;
589 pinctrl-names = "default"; 587 pinctrl-names = "default";
590 pinctrl-0 = <&uart4_pins>; 588 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 @@
185 reg = <0x48>; 185 reg = <0x48>;
186 /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */ 186 /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
187 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */ 187 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
188 interrupt-parent = <&gic>;
189 }; 188 };
190 189
191 twl6040: twl@4b { 190 twl6040: twl@4b {
@@ -197,7 +196,6 @@
197 196
198 /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */ 197 /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
199 interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */ 198 interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
200 interrupt-parent = <&gic>;
201 ti,audpwron-gpio = <&gpio6 22 0>; /* gpio 182 */ 199 ti,audpwron-gpio = <&gpio6 22 0>; /* gpio 182 */
202 200
203 vio-supply = <&v1v8>; 201 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 @@
14 14
15/ { 15/ {
16 compatible = "ti,omap4430", "ti,omap4"; 16 compatible = "ti,omap4430", "ti,omap4";
17 interrupt-parent = <&gic>; 17 interrupt-parent = <&wakeupgen>;
18 18
19 aliases { 19 aliases {
20 i2c0 = &i2c1; 20 i2c0 = &i2c1;
@@ -56,6 +56,7 @@
56 #interrupt-cells = <3>; 56 #interrupt-cells = <3>;
57 reg = <0x48241000 0x1000>, 57 reg = <0x48241000 0x1000>,
58 <0x48240100 0x0100>; 58 <0x48240100 0x0100>;
59 interrupt-parent = <&gic>;
59 }; 60 };
60 61
61 L2: l2-cache-controller@48242000 { 62 L2: l2-cache-controller@48242000 {
@@ -70,6 +71,15 @@
70 clocks = <&mpu_periphclk>; 71 clocks = <&mpu_periphclk>;
71 reg = <0x48240600 0x20>; 72 reg = <0x48240600 0x20>;
72 interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_HIGH)>; 73 interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_HIGH)>;
74 interrupt-parent = <&gic>;
75 };
76
77 wakeupgen: interrupt-controller@48281000 {
78 compatible = "ti,omap4-wugen-mpu";
79 interrupt-controller;
80 #interrupt-cells = <3>;
81 reg = <0x48281000 0x1000>;
82 interrupt-parent = <&gic>;
73 }; 83 };
74 84
75 /* 85 /*
@@ -319,7 +329,7 @@
319 uart2: serial@4806c000 { 329 uart2: serial@4806c000 {
320 compatible = "ti,omap4-uart"; 330 compatible = "ti,omap4-uart";
321 reg = <0x4806c000 0x100>; 331 reg = <0x4806c000 0x100>;
322 interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; 332 interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
323 ti,hwmods = "uart2"; 333 ti,hwmods = "uart2";
324 clock-frequency = <48000000>; 334 clock-frequency = <48000000>;
325 }; 335 };
@@ -327,7 +337,7 @@
327 uart3: serial@48020000 { 337 uart3: serial@48020000 {
328 compatible = "ti,omap4-uart"; 338 compatible = "ti,omap4-uart";
329 reg = <0x48020000 0x100>; 339 reg = <0x48020000 0x100>;
330 interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; 340 interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
331 ti,hwmods = "uart3"; 341 ti,hwmods = "uart3";
332 clock-frequency = <48000000>; 342 clock-frequency = <48000000>;
333 }; 343 };
@@ -335,7 +345,7 @@
335 uart4: serial@4806e000 { 345 uart4: serial@4806e000 {
336 compatible = "ti,omap4-uart"; 346 compatible = "ti,omap4-uart";
337 reg = <0x4806e000 0x100>; 347 reg = <0x4806e000 0x100>;
338 interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; 348 interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
339 ti,hwmods = "uart4"; 349 ti,hwmods = "uart4";
340 clock-frequency = <48000000>; 350 clock-frequency = <48000000>;
341 }; 351 };
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 @@
412 palmas: palmas@48 { 412 palmas: palmas@48 {
413 compatible = "ti,palmas"; 413 compatible = "ti,palmas";
414 interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */ 414 interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
415 interrupt-parent = <&gic>;
416 reg = <0x48>; 415 reg = <0x48>;
417 interrupt-controller; 416 interrupt-controller;
418 #interrupt-cells = <2>; 417 #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 @@
311 palmas: palmas@48 { 311 palmas: palmas@48 {
312 compatible = "ti,palmas"; 312 compatible = "ti,palmas";
313 interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */ 313 interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
314 interrupt-parent = <&gic>;
315 reg = <0x48>; 314 reg = <0x48>;
316 interrupt-controller; 315 interrupt-controller;
317 #interrupt-cells = <2>; 316 #interrupt-cells = <2>;
@@ -521,7 +520,6 @@
521 pinctrl-0 = <&twl6040_pins>; 520 pinctrl-0 = <&twl6040_pins>;
522 521
523 interrupts = <GIC_SPI 119 IRQ_TYPE_NONE>; /* IRQ_SYS_2N cascaded to gic */ 522 interrupts = <GIC_SPI 119 IRQ_TYPE_NONE>; /* IRQ_SYS_2N cascaded to gic */
524 interrupt-parent = <&gic>;
525 ti,audpwron-gpio = <&gpio5 13 0>; /* gpio line 141 */ 523 ti,audpwron-gpio = <&gpio5 13 0>; /* gpio line 141 */
526 524
527 vio-supply = <&smps7_reg>; 525 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 @@
18 #size-cells = <1>; 18 #size-cells = <1>;
19 19
20 compatible = "ti,omap5"; 20 compatible = "ti,omap5";
21 interrupt-parent = <&gic>; 21 interrupt-parent = <&wakeupgen>;
22 22
23 aliases { 23 aliases {
24 i2c0 = &i2c1; 24 i2c0 = &i2c1;
@@ -79,6 +79,7 @@
79 <GIC_PPI 14 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, 79 <GIC_PPI 14 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>,
80 <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, 80 <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>,
81 <GIC_PPI 10 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>; 81 <GIC_PPI 10 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>;
82 interrupt-parent = <&gic>;
82 }; 83 };
83 84
84 pmu { 85 pmu {
@@ -95,6 +96,15 @@
95 <0x48212000 0x1000>, 96 <0x48212000 0x1000>,
96 <0x48214000 0x2000>, 97 <0x48214000 0x2000>,
97 <0x48216000 0x2000>; 98 <0x48216000 0x2000>;
99 interrupt-parent = <&gic>;
100 };
101
102 wakeupgen: interrupt-controller@48281000 {
103 compatible = "ti,omap5-wugen-mpu", "ti,omap4-wugen-mpu";
104 interrupt-controller;
105 #interrupt-cells = <3>;
106 reg = <0x48281000 0x1000>;
107 interrupt-parent = <&gic>;
98 }; 108 };
99 109
100 /* 110 /*
@@ -458,7 +468,7 @@
458 uart1: serial@4806a000 { 468 uart1: serial@4806a000 {
459 compatible = "ti,omap4-uart"; 469 compatible = "ti,omap4-uart";
460 reg = <0x4806a000 0x100>; 470 reg = <0x4806a000 0x100>;
461 interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; 471 interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
462 ti,hwmods = "uart1"; 472 ti,hwmods = "uart1";
463 clock-frequency = <48000000>; 473 clock-frequency = <48000000>;
464 }; 474 };
@@ -466,7 +476,7 @@
466 uart2: serial@4806c000 { 476 uart2: serial@4806c000 {
467 compatible = "ti,omap4-uart"; 477 compatible = "ti,omap4-uart";
468 reg = <0x4806c000 0x100>; 478 reg = <0x4806c000 0x100>;
469 interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; 479 interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
470 ti,hwmods = "uart2"; 480 ti,hwmods = "uart2";
471 clock-frequency = <48000000>; 481 clock-frequency = <48000000>;
472 }; 482 };
@@ -474,7 +484,7 @@
474 uart3: serial@48020000 { 484 uart3: serial@48020000 {
475 compatible = "ti,omap4-uart"; 485 compatible = "ti,omap4-uart";
476 reg = <0x48020000 0x100>; 486 reg = <0x48020000 0x100>;
477 interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; 487 interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
478 ti,hwmods = "uart3"; 488 ti,hwmods = "uart3";
479 clock-frequency = <48000000>; 489 clock-frequency = <48000000>;
480 }; 490 };
@@ -482,7 +492,7 @@
482 uart4: serial@4806e000 { 492 uart4: serial@4806e000 {
483 compatible = "ti,omap4-uart"; 493 compatible = "ti,omap4-uart";
484 reg = <0x4806e000 0x100>; 494 reg = <0x4806e000 0x100>;
485 interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; 495 interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
486 ti,hwmods = "uart4"; 496 ti,hwmods = "uart4";
487 clock-frequency = <48000000>; 497 clock-frequency = <48000000>;
488 }; 498 };
@@ -490,7 +500,7 @@
490 uart5: serial@48066000 { 500 uart5: serial@48066000 {
491 compatible = "ti,omap4-uart"; 501 compatible = "ti,omap4-uart";
492 reg = <0x48066000 0x100>; 502 reg = <0x48066000 0x100>;
493 interrupts-extended = <&gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; 503 interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
494 ti,hwmods = "uart5"; 504 ti,hwmods = "uart5";
495 clock-frequency = <48000000>; 505 clock-frequency = <48000000>;
496 }; 506 };
@@ -498,7 +508,7 @@
498 uart6: serial@48068000 { 508 uart6: serial@48068000 {
499 compatible = "ti,omap4-uart"; 509 compatible = "ti,omap4-uart";
500 reg = <0x48068000 0x100>; 510 reg = <0x48068000 0x100>;
501 interrupts-extended = <&gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; 511 interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
502 ti,hwmods = "uart6"; 512 ti,hwmods = "uart6";
503 clock-frequency = <48000000>; 513 clock-frequency = <48000000>;
504 }; 514 };
@@ -883,14 +893,12 @@
883 usbhsohci: ohci@4a064800 { 893 usbhsohci: ohci@4a064800 {
884 compatible = "ti,ohci-omap3"; 894 compatible = "ti,ohci-omap3";
885 reg = <0x4a064800 0x400>; 895 reg = <0x4a064800 0x400>;
886 interrupt-parent = <&gic>;
887 interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; 896 interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
888 }; 897 };
889 898
890 usbhsehci: ehci@4a064c00 { 899 usbhsehci: ehci@4a064c00 {
891 compatible = "ti,ehci-omap"; 900 compatible = "ti,ehci-omap";
892 reg = <0x4a064c00 0x400>; 901 reg = <0x4a064c00 0x400>;
893 interrupt-parent = <&gic>;
894 interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; 902 interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
895 }; 903 };
896 }; 904 };
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 @@
8 8
9/ { 9/ {
10 compatible = "nvidia,tegra114"; 10 compatible = "nvidia,tegra114";
11 interrupt-parent = <&gic>; 11 interrupt-parent = <&lic>;
12 12
13 host1x@50000000 { 13 host1x@50000000 {
14 compatible = "nvidia,tegra114-host1x", "simple-bus"; 14 compatible = "nvidia,tegra114-host1x", "simple-bus";
@@ -134,6 +134,19 @@
134 <0x50046000 0x2000>; 134 <0x50046000 0x2000>;
135 interrupts = <GIC_PPI 9 135 interrupts = <GIC_PPI 9
136 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; 136 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
137 interrupt-parent = <&gic>;
138 };
139
140 lic: interrupt-controller@60004000 {
141 compatible = "nvidia,tegra114-ictlr", "nvidia,tegra30-ictlr";
142 reg = <0x60004000 0x100>,
143 <0x60004100 0x50>,
144 <0x60004200 0x50>,
145 <0x60004300 0x50>,
146 <0x60004400 0x50>;
147 interrupt-controller;
148 #interrupt-cells = <3>;
149 interrupt-parent = <&gic>;
137 }; 150 };
138 151
139 timer@60005000 { 152 timer@60005000 {
@@ -766,5 +779,6 @@
766 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, 779 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
767 <GIC_PPI 10 780 <GIC_PPI 10
768 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; 781 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
782 interrupt-parent = <&gic>;
769 }; 783 };
770}; 784};
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 @@
10 10
11/ { 11/ {
12 compatible = "nvidia,tegra124"; 12 compatible = "nvidia,tegra124";
13 interrupt-parent = <&gic>; 13 interrupt-parent = <&lic>;
14 #address-cells = <2>; 14 #address-cells = <2>;
15 #size-cells = <2>; 15 #size-cells = <2>;
16 16
@@ -173,6 +173,7 @@
173 <0x0 0x50046000 0x0 0x2000>; 173 <0x0 0x50046000 0x0 0x2000>;
174 interrupts = <GIC_PPI 9 174 interrupts = <GIC_PPI 9
175 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; 175 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
176 interrupt-parent = <&gic>;
176 }; 177 };
177 178
178 gpu@0,57000000 { 179 gpu@0,57000000 {
@@ -190,6 +191,18 @@
190 status = "disabled"; 191 status = "disabled";
191 }; 192 };
192 193
194 lic: interrupt-controller@60004000 {
195 compatible = "nvidia,tegra124-ictlr", "nvidia,tegra30-ictlr";
196 reg = <0x0 0x60004000 0x0 0x100>,
197 <0x0 0x60004100 0x0 0x100>,
198 <0x0 0x60004200 0x0 0x100>,
199 <0x0 0x60004300 0x0 0x100>,
200 <0x0 0x60004400 0x0 0x100>;
201 interrupt-controller;
202 #interrupt-cells = <3>;
203 interrupt-parent = <&gic>;
204 };
205
193 timer@0,60005000 { 206 timer@0,60005000 {
194 compatible = "nvidia,tegra124-timer", "nvidia,tegra20-timer"; 207 compatible = "nvidia,tegra124-timer", "nvidia,tegra20-timer";
195 reg = <0x0 0x60005000 0x0 0x400>; 208 reg = <0x0 0x60005000 0x0 0x400>;
@@ -955,5 +968,6 @@
955 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, 968 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
956 <GIC_PPI 10 969 <GIC_PPI 10
957 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; 970 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
971 interrupt-parent = <&gic>;
958 }; 972 };
959}; 973};
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 @@
7 7
8/ { 8/ {
9 compatible = "nvidia,tegra20"; 9 compatible = "nvidia,tegra20";
10 interrupt-parent = <&intc>; 10 interrupt-parent = <&lic>;
11 11
12 host1x@50000000 { 12 host1x@50000000 {
13 compatible = "nvidia,tegra20-host1x", "simple-bus"; 13 compatible = "nvidia,tegra20-host1x", "simple-bus";
@@ -142,6 +142,7 @@
142 142
143 timer@50040600 { 143 timer@50040600 {
144 compatible = "arm,cortex-a9-twd-timer"; 144 compatible = "arm,cortex-a9-twd-timer";
145 interrupt-parent = <&intc>;
145 reg = <0x50040600 0x20>; 146 reg = <0x50040600 0x20>;
146 interrupts = <GIC_PPI 13 147 interrupts = <GIC_PPI 13
147 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; 148 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
@@ -154,6 +155,7 @@
154 0x50040100 0x0100>; 155 0x50040100 0x0100>;
155 interrupt-controller; 156 interrupt-controller;
156 #interrupt-cells = <3>; 157 #interrupt-cells = <3>;
158 interrupt-parent = <&intc>;
157 }; 159 };
158 160
159 cache-controller@50043000 { 161 cache-controller@50043000 {
@@ -165,6 +167,17 @@
165 cache-level = <2>; 167 cache-level = <2>;
166 }; 168 };
167 169
170 lic: interrupt-controller@60004000 {
171 compatible = "nvidia,tegra20-ictlr";
172 reg = <0x60004000 0x100>,
173 <0x60004100 0x50>,
174 <0x60004200 0x50>,
175 <0x60004300 0x50>;
176 interrupt-controller;
177 #interrupt-cells = <3>;
178 interrupt-parent = <&intc>;
179 };
180
168 timer@60005000 { 181 timer@60005000 {
169 compatible = "nvidia,tegra20-timer"; 182 compatible = "nvidia,tegra20-timer";
170 reg = <0x60005000 0x60>; 183 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 @@
8 8
9/ { 9/ {
10 compatible = "nvidia,tegra30"; 10 compatible = "nvidia,tegra30";
11 interrupt-parent = <&intc>; 11 interrupt-parent = <&lic>;
12 12
13 pcie-controller@00003000 { 13 pcie-controller@00003000 {
14 compatible = "nvidia,tegra30-pcie"; 14 compatible = "nvidia,tegra30-pcie";
@@ -228,6 +228,7 @@
228 timer@50040600 { 228 timer@50040600 {
229 compatible = "arm,cortex-a9-twd-timer"; 229 compatible = "arm,cortex-a9-twd-timer";
230 reg = <0x50040600 0x20>; 230 reg = <0x50040600 0x20>;
231 interrupt-parent = <&intc>;
231 interrupts = <GIC_PPI 13 232 interrupts = <GIC_PPI 13
232 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; 233 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
233 clocks = <&tegra_car TEGRA30_CLK_TWD>; 234 clocks = <&tegra_car TEGRA30_CLK_TWD>;
@@ -239,6 +240,7 @@
239 0x50040100 0x0100>; 240 0x50040100 0x0100>;
240 interrupt-controller; 241 interrupt-controller;
241 #interrupt-cells = <3>; 242 #interrupt-cells = <3>;
243 interrupt-parent = <&intc>;
242 }; 244 };
243 245
244 cache-controller@50043000 { 246 cache-controller@50043000 {
@@ -250,6 +252,18 @@
250 cache-level = <2>; 252 cache-level = <2>;
251 }; 253 };
252 254
255 lic: interrupt-controller@60004000 {
256 compatible = "nvidia,tegra30-ictlr";
257 reg = <0x60004000 0x100>,
258 <0x60004100 0x50>,
259 <0x60004200 0x50>,
260 <0x60004300 0x50>,
261 <0x60004400 0x50>;
262 interrupt-controller;
263 #interrupt-cells = <3>;
264 interrupt-parent = <&intc>;
265 };
266
253 timer@60005000 { 267 timer@60005000 {
254 compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer"; 268 compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
255 reg = <0x60005000 0x400>; 269 reg = <0x60005000 0x400>;
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)
166 exynos_map_io(); 166 exynos_map_io();
167} 167}
168 168
169/*
170 * Apparently, these SoCs are not able to wake-up from suspend using
171 * the PMU. Too bad. Should they suddenly become capable of such a
172 * feat, the matches below should be moved to suspend.c.
173 */
169static const struct of_device_id exynos_dt_pmu_match[] = { 174static const struct of_device_id exynos_dt_pmu_match[] = {
170 { .compatible = "samsung,exynos3250-pmu" },
171 { .compatible = "samsung,exynos4210-pmu" },
172 { .compatible = "samsung,exynos4212-pmu" },
173 { .compatible = "samsung,exynos4412-pmu" },
174 { .compatible = "samsung,exynos4415-pmu" },
175 { .compatible = "samsung,exynos5250-pmu" },
176 { .compatible = "samsung,exynos5260-pmu" }, 175 { .compatible = "samsung,exynos5260-pmu" },
177 { .compatible = "samsung,exynos5410-pmu" }, 176 { .compatible = "samsung,exynos5410-pmu" },
178 { .compatible = "samsung,exynos5420-pmu" },
179 { /*sentinel*/ }, 177 { /*sentinel*/ },
180}; 178};
181 179
@@ -186,9 +184,6 @@ static void exynos_map_pmu(void)
186 np = of_find_matching_node(NULL, exynos_dt_pmu_match); 184 np = of_find_matching_node(NULL, exynos_dt_pmu_match);
187 if (np) 185 if (np)
188 pmu_base_addr = of_iomap(np, 0); 186 pmu_base_addr = of_iomap(np, 0);
189
190 if (!pmu_base_addr)
191 panic("failed to find exynos pmu register\n");
192} 187}
193 188
194static void __init exynos_init_irq(void) 189static 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 @@
18#include <linux/syscore_ops.h> 18#include <linux/syscore_ops.h>
19#include <linux/cpu_pm.h> 19#include <linux/cpu_pm.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/irqchip/arm-gic.h> 21#include <linux/irq.h>
22#include <linux/irqdomain.h>
23#include <linux/of_address.h>
22#include <linux/err.h> 24#include <linux/err.h>
23#include <linux/regulator/machine.h> 25#include <linux/regulator/machine.h>
24 26
@@ -43,8 +45,8 @@
43#define EXYNOS5420_CPU_STATE 0x28 45#define EXYNOS5420_CPU_STATE 0x28
44 46
45/** 47/**
46 * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping 48 * struct exynos_wkup_irq - PMU IRQ to mask mapping
47 * @hwirq: Hardware IRQ signal of the GIC 49 * @hwirq: Hardware IRQ signal of the PMU
48 * @mask: Mask in PMU wake-up mask register 50 * @mask: Mask in PMU wake-up mask register
49 */ 51 */
50struct exynos_wkup_irq { 52struct exynos_wkup_irq {
@@ -93,14 +95,14 @@ static const struct exynos_wkup_irq exynos3250_wkup_irq[] = {
93}; 95};
94 96
95static const struct exynos_wkup_irq exynos4_wkup_irq[] = { 97static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
96 { 76, BIT(1) }, /* RTC alarm */ 98 { 44, BIT(1) }, /* RTC alarm */
97 { 77, BIT(2) }, /* RTC tick */ 99 { 45, BIT(2) }, /* RTC tick */
98 { /* sentinel */ }, 100 { /* sentinel */ },
99}; 101};
100 102
101static const struct exynos_wkup_irq exynos5250_wkup_irq[] = { 103static const struct exynos_wkup_irq exynos5250_wkup_irq[] = {
102 { 75, BIT(1) }, /* RTC alarm */ 104 { 43, BIT(1) }, /* RTC alarm */
103 { 76, BIT(2) }, /* RTC tick */ 105 { 44, BIT(2) }, /* RTC tick */
104 { /* sentinel */ }, 106 { /* sentinel */ },
105}; 107};
106 108
@@ -167,6 +169,113 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
167 return -ENOENT; 169 return -ENOENT;
168} 170}
169 171
172static struct irq_chip exynos_pmu_chip = {
173 .name = "PMU",
174 .irq_eoi = irq_chip_eoi_parent,
175 .irq_mask = irq_chip_mask_parent,
176 .irq_unmask = irq_chip_unmask_parent,
177 .irq_retrigger = irq_chip_retrigger_hierarchy,
178 .irq_set_wake = exynos_irq_set_wake,
179#ifdef CONFIG_SMP
180 .irq_set_affinity = irq_chip_set_affinity_parent,
181#endif
182};
183
184static int exynos_pmu_domain_xlate(struct irq_domain *domain,
185 struct device_node *controller,
186 const u32 *intspec,
187 unsigned int intsize,
188 unsigned long *out_hwirq,
189 unsigned int *out_type)
190{
191 if (domain->of_node != controller)
192 return -EINVAL; /* Shouldn't happen, really... */
193 if (intsize != 3)
194 return -EINVAL; /* Not GIC compliant */
195 if (intspec[0] != 0)
196 return -EINVAL; /* No PPI should point to this domain */
197
198 *out_hwirq = intspec[1];
199 *out_type = intspec[2];
200 return 0;
201}
202
203static int exynos_pmu_domain_alloc(struct irq_domain *domain,
204 unsigned int virq,
205 unsigned int nr_irqs, void *data)
206{
207 struct of_phandle_args *args = data;
208 struct of_phandle_args parent_args;
209 irq_hw_number_t hwirq;
210 int i;
211
212 if (args->args_count != 3)
213 return -EINVAL; /* Not GIC compliant */
214 if (args->args[0] != 0)
215 return -EINVAL; /* No PPI should point to this domain */
216
217 hwirq = args->args[1];
218
219 for (i = 0; i < nr_irqs; i++)
220 irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
221 &exynos_pmu_chip, NULL);
222
223 parent_args = *args;
224 parent_args.np = domain->parent->of_node;
225 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
226}
227
228static struct irq_domain_ops exynos_pmu_domain_ops = {
229 .xlate = exynos_pmu_domain_xlate,
230 .alloc = exynos_pmu_domain_alloc,
231 .free = irq_domain_free_irqs_common,
232};
233
234static int __init exynos_pmu_irq_init(struct device_node *node,
235 struct device_node *parent)
236{
237 struct irq_domain *parent_domain, *domain;
238
239 if (!parent) {
240 pr_err("%s: no parent, giving up\n", node->full_name);
241 return -ENODEV;
242 }
243
244 parent_domain = irq_find_host(parent);
245 if (!parent_domain) {
246 pr_err("%s: unable to obtain parent domain\n", node->full_name);
247 return -ENXIO;
248 }
249
250 pmu_base_addr = of_iomap(node, 0);
251
252 if (!pmu_base_addr) {
253 pr_err("%s: failed to find exynos pmu register\n",
254 node->full_name);
255 return -ENOMEM;
256 }
257
258 domain = irq_domain_add_hierarchy(parent_domain, 0, 0,
259 node, &exynos_pmu_domain_ops,
260 NULL);
261 if (!domain) {
262 iounmap(pmu_base_addr);
263 return -ENOMEM;
264 }
265
266 return 0;
267}
268
269#define EXYNOS_PMU_IRQ(symbol, name) OF_DECLARE_2(irqchip, symbol, name, exynos_pmu_irq_init)
270
271EXYNOS_PMU_IRQ(exynos3250_pmu_irq, "samsung,exynos3250-pmu");
272EXYNOS_PMU_IRQ(exynos4210_pmu_irq, "samsung,exynos4210-pmu");
273EXYNOS_PMU_IRQ(exynos4212_pmu_irq, "samsung,exynos4212-pmu");
274EXYNOS_PMU_IRQ(exynos4412_pmu_irq, "samsung,exynos4412-pmu");
275EXYNOS_PMU_IRQ(exynos4415_pmu_irq, "samsung,exynos4415-pmu");
276EXYNOS_PMU_IRQ(exynos5250_pmu_irq, "samsung,exynos5250-pmu");
277EXYNOS_PMU_IRQ(exynos5420_pmu_irq, "samsung,exynos5420-pmu");
278
170static int exynos_cpu_do_idle(void) 279static int exynos_cpu_do_idle(void)
171{ 280{
172 /* issue the standby signal into the pm unit. */ 281 /* issue the standby signal into the pm unit. */
@@ -615,17 +724,19 @@ static struct syscore_ops exynos_pm_syscore_ops;
615void __init exynos_pm_init(void) 724void __init exynos_pm_init(void)
616{ 725{
617 const struct of_device_id *match; 726 const struct of_device_id *match;
727 struct device_node *np;
618 u32 tmp; 728 u32 tmp;
619 729
620 of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match); 730 np = of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match);
621 if (!match) { 731 if (!np) {
622 pr_err("Failed to find PMU node\n"); 732 pr_err("Failed to find PMU node\n");
623 return; 733 return;
624 } 734 }
625 pm_data = (struct exynos_pm_data *) match->data;
626 735
627 /* Platform-specific GIC callback */ 736 if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL)))
628 gic_arch_extn.irq_set_wake = exynos_irq_set_wake; 737 pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
738
739 pm_data = (struct exynos_pm_data *) match->data;
629 740
630 /* All wakeup disable */ 741 /* All wakeup disable */
631 tmp = pmu_raw_readl(S5P_WAKEUP_MASK); 742 tmp = pmu_raw_readl(S5P_WAKEUP_MASK);
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 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/irqdomain.h>
24#include <linux/of_address.h>
23#include <linux/platform_device.h> 25#include <linux/platform_device.h>
24#include <linux/cpu.h> 26#include <linux/cpu.h>
25#include <linux/notifier.h> 27#include <linux/notifier.h>
26#include <linux/cpu_pm.h> 28#include <linux/cpu_pm.h>
27#include <linux/irqchip/arm-gic.h>
28 29
29#include "omap-wakeupgen.h" 30#include "omap-wakeupgen.h"
30#include "omap-secure.h" 31#include "omap-secure.h"
@@ -78,29 +79,12 @@ static inline void sar_writel(u32 val, u32 offset, u8 idx)
78 79
79static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index) 80static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index)
80{ 81{
81 unsigned int spi_irq;
82
83 /*
84 * PPIs and SGIs are not supported.
85 */
86 if (irq < OMAP44XX_IRQ_GIC_START)
87 return -EINVAL;
88
89 /*
90 * Subtract the GIC offset.
91 */
92 spi_irq = irq - OMAP44XX_IRQ_GIC_START;
93 if (spi_irq > MAX_IRQS) {
94 pr_err("omap wakeupGen: Invalid IRQ%d\n", irq);
95 return -EINVAL;
96 }
97
98 /* 82 /*
99 * Each WakeupGen register controls 32 interrupt. 83 * Each WakeupGen register controls 32 interrupt.
100 * i.e. 1 bit per SPI IRQ 84 * i.e. 1 bit per SPI IRQ
101 */ 85 */
102 *reg_index = spi_irq >> 5; 86 *reg_index = irq >> 5;
103 *bit_posn = spi_irq %= 32; 87 *bit_posn = irq %= 32;
104 88
105 return 0; 89 return 0;
106} 90}
@@ -141,6 +125,7 @@ static void wakeupgen_mask(struct irq_data *d)
141 raw_spin_lock_irqsave(&wakeupgen_lock, flags); 125 raw_spin_lock_irqsave(&wakeupgen_lock, flags);
142 _wakeupgen_clear(d->hwirq, irq_target_cpu[d->hwirq]); 126 _wakeupgen_clear(d->hwirq, irq_target_cpu[d->hwirq]);
143 raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); 127 raw_spin_unlock_irqrestore(&wakeupgen_lock, flags);
128 irq_chip_mask_parent(d);
144} 129}
145 130
146/* 131/*
@@ -153,6 +138,7 @@ static void wakeupgen_unmask(struct irq_data *d)
153 raw_spin_lock_irqsave(&wakeupgen_lock, flags); 138 raw_spin_lock_irqsave(&wakeupgen_lock, flags);
154 _wakeupgen_set(d->hwirq, irq_target_cpu[d->hwirq]); 139 _wakeupgen_set(d->hwirq, irq_target_cpu[d->hwirq]);
155 raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); 140 raw_spin_unlock_irqrestore(&wakeupgen_lock, flags);
141 irq_chip_unmask_parent(d);
156} 142}
157 143
158#ifdef CONFIG_HOTPLUG_CPU 144#ifdef CONFIG_HOTPLUG_CPU
@@ -400,15 +386,91 @@ int omap_secure_apis_support(void)
400 return omap_secure_apis; 386 return omap_secure_apis;
401} 387}
402 388
389static struct irq_chip wakeupgen_chip = {
390 .name = "WUGEN",
391 .irq_eoi = irq_chip_eoi_parent,
392 .irq_mask = wakeupgen_mask,
393 .irq_unmask = wakeupgen_unmask,
394 .irq_retrigger = irq_chip_retrigger_hierarchy,
395 .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
396#ifdef CONFIG_SMP
397 .irq_set_affinity = irq_chip_set_affinity_parent,
398#endif
399};
400
401static int wakeupgen_domain_xlate(struct irq_domain *domain,
402 struct device_node *controller,
403 const u32 *intspec,
404 unsigned int intsize,
405 unsigned long *out_hwirq,
406 unsigned int *out_type)
407{
408 if (domain->of_node != controller)
409 return -EINVAL; /* Shouldn't happen, really... */
410 if (intsize != 3)
411 return -EINVAL; /* Not GIC compliant */
412 if (intspec[0] != 0)
413 return -EINVAL; /* No PPI should point to this domain */
414
415 *out_hwirq = intspec[1];
416 *out_type = intspec[2];
417 return 0;
418}
419
420static int wakeupgen_domain_alloc(struct irq_domain *domain,
421 unsigned int virq,
422 unsigned int nr_irqs, void *data)
423{
424 struct of_phandle_args *args = data;
425 struct of_phandle_args parent_args;
426 irq_hw_number_t hwirq;
427 int i;
428
429 if (args->args_count != 3)
430 return -EINVAL; /* Not GIC compliant */
431 if (args->args[0] != 0)
432 return -EINVAL; /* No PPI should point to this domain */
433
434 hwirq = args->args[1];
435 if (hwirq >= MAX_IRQS)
436 return -EINVAL; /* Can't deal with this */
437
438 for (i = 0; i < nr_irqs; i++)
439 irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
440 &wakeupgen_chip, NULL);
441
442 parent_args = *args;
443 parent_args.np = domain->parent->of_node;
444 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
445}
446
447static struct irq_domain_ops wakeupgen_domain_ops = {
448 .xlate = wakeupgen_domain_xlate,
449 .alloc = wakeupgen_domain_alloc,
450 .free = irq_domain_free_irqs_common,
451};
452
403/* 453/*
404 * Initialise the wakeupgen module. 454 * Initialise the wakeupgen module.
405 */ 455 */
406int __init omap_wakeupgen_init(void) 456static int __init wakeupgen_init(struct device_node *node,
457 struct device_node *parent)
407{ 458{
459 struct irq_domain *parent_domain, *domain;
408 int i; 460 int i;
409 unsigned int boot_cpu = smp_processor_id(); 461 unsigned int boot_cpu = smp_processor_id();
410 u32 val; 462 u32 val;
411 463
464 if (!parent) {
465 pr_err("%s: no parent, giving up\n", node->full_name);
466 return -ENODEV;
467 }
468
469 parent_domain = irq_find_host(parent);
470 if (!parent_domain) {
471 pr_err("%s: unable to obtain parent domain\n", node->full_name);
472 return -ENXIO;
473 }
412 /* Not supported on OMAP4 ES1.0 silicon */ 474 /* Not supported on OMAP4 ES1.0 silicon */
413 if (omap_rev() == OMAP4430_REV_ES1_0) { 475 if (omap_rev() == OMAP4430_REV_ES1_0) {
414 WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n"); 476 WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n");
@@ -416,7 +478,7 @@ int __init omap_wakeupgen_init(void)
416 } 478 }
417 479
418 /* Static mapping, never released */ 480 /* Static mapping, never released */
419 wakeupgen_base = ioremap(OMAP_WKUPGEN_BASE, SZ_4K); 481 wakeupgen_base = of_iomap(node, 0);
420 if (WARN_ON(!wakeupgen_base)) 482 if (WARN_ON(!wakeupgen_base))
421 return -ENOMEM; 483 return -ENOMEM;
422 484
@@ -429,6 +491,14 @@ int __init omap_wakeupgen_init(void)
429 max_irqs = AM43XX_IRQS; 491 max_irqs = AM43XX_IRQS;
430 } 492 }
431 493
494 domain = irq_domain_add_hierarchy(parent_domain, 0, max_irqs,
495 node, &wakeupgen_domain_ops,
496 NULL);
497 if (!domain) {
498 iounmap(wakeupgen_base);
499 return -ENOMEM;
500 }
501
432 /* Clear all IRQ bitmasks at wakeupGen level */ 502 /* Clear all IRQ bitmasks at wakeupGen level */
433 for (i = 0; i < irq_banks; i++) { 503 for (i = 0; i < irq_banks; i++) {
434 wakeupgen_writel(0, i, CPU0_ID); 504 wakeupgen_writel(0, i, CPU0_ID);
@@ -437,14 +507,6 @@ int __init omap_wakeupgen_init(void)
437 } 507 }
438 508
439 /* 509 /*
440 * Override GIC architecture specific functions to add
441 * OMAP WakeupGen interrupt controller along with GIC
442 */
443 gic_arch_extn.irq_mask = wakeupgen_mask;
444 gic_arch_extn.irq_unmask = wakeupgen_unmask;
445 gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE;
446
447 /*
448 * FIXME: Add support to set_smp_affinity() once the core 510 * FIXME: Add support to set_smp_affinity() once the core
449 * GIC code has necessary hooks in place. 511 * GIC code has necessary hooks in place.
450 */ 512 */
@@ -474,3 +536,9 @@ int __init omap_wakeupgen_init(void)
474 536
475 return 0; 537 return 0;
476} 538}
539
540/*
541 * We cannot use the IRQCHIP_DECLARE macro that lives in
542 * drivers/irqchip, so we're forced to roll our own. Not very nice.
543 */
544OF_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 @@
33#define OMAP_TIMESTAMPCYCLELO 0xc08 33#define OMAP_TIMESTAMPCYCLELO 0xc08
34#define OMAP_TIMESTAMPCYCLEHI 0xc0c 34#define OMAP_TIMESTAMPCYCLEHI 0xc0c
35 35
36extern int __init omap_wakeupgen_init(void);
37extern void __iomem *omap_get_wakeupgen_base(void); 36extern void __iomem *omap_get_wakeupgen_base(void);
38extern int omap_secure_apis_support(void); 37extern int omap_secure_apis_support(void);
39#endif 38#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 @@
22#include <linux/of_platform.h> 22#include <linux/of_platform.h>
23#include <linux/export.h> 23#include <linux/export.h>
24#include <linux/irqchip/arm-gic.h> 24#include <linux/irqchip/arm-gic.h>
25#include <linux/irqchip/irq-crossbar.h>
26#include <linux/of_address.h> 25#include <linux/of_address.h>
27#include <linux/reboot.h> 26#include <linux/reboot.h>
28#include <linux/genalloc.h> 27#include <linux/genalloc.h>
@@ -242,26 +241,26 @@ static int __init omap4_sar_ram_init(void)
242} 241}
243omap_early_initcall(omap4_sar_ram_init); 242omap_early_initcall(omap4_sar_ram_init);
244 243
245static const struct of_device_id gic_match[] = { 244static const struct of_device_id intc_match[] = {
246 { .compatible = "arm,cortex-a9-gic", }, 245 { .compatible = "ti,omap4-wugen-mpu", },
247 { .compatible = "arm,cortex-a15-gic", }, 246 { .compatible = "ti,omap5-wugen-mpu", },
248 { }, 247 { },
249}; 248};
250 249
251static struct device_node *gic_node; 250static struct device_node *intc_node;
252 251
253unsigned int omap4_xlate_irq(unsigned int hwirq) 252unsigned int omap4_xlate_irq(unsigned int hwirq)
254{ 253{
255 struct of_phandle_args irq_data; 254 struct of_phandle_args irq_data;
256 unsigned int irq; 255 unsigned int irq;
257 256
258 if (!gic_node) 257 if (!intc_node)
259 gic_node = of_find_matching_node(NULL, gic_match); 258 intc_node = of_find_matching_node(NULL, intc_match);
260 259
261 if (WARN_ON(!gic_node)) 260 if (WARN_ON(!intc_node))
262 return hwirq; 261 return hwirq;
263 262
264 irq_data.np = gic_node; 263 irq_data.np = intc_node;
265 irq_data.args_count = 3; 264 irq_data.args_count = 3;
266 irq_data.args[0] = 0; 265 irq_data.args[0] = 0;
267 irq_data.args[1] = hwirq - OMAP44XX_IRQ_GIC_START; 266 irq_data.args[1] = hwirq - OMAP44XX_IRQ_GIC_START;
@@ -278,6 +277,12 @@ void __init omap_gic_of_init(void)
278{ 277{
279 struct device_node *np; 278 struct device_node *np;
280 279
280 intc_node = of_find_matching_node(NULL, intc_match);
281 if (WARN_ON(!intc_node)) {
282 pr_err("No WUGEN found in DT, system will misbehave.\n");
283 pr_err("UPDATE YOUR DEVICE TREE!\n");
284 }
285
281 /* Extract GIC distributor and TWD bases for OMAP4460 ROM Errata WA */ 286 /* Extract GIC distributor and TWD bases for OMAP4460 ROM Errata WA */
282 if (!cpu_is_omap446x()) 287 if (!cpu_is_omap446x())
283 goto skip_errata_init; 288 goto skip_errata_init;
@@ -291,9 +296,5 @@ void __init omap_gic_of_init(void)
291 WARN_ON(!twd_base); 296 WARN_ON(!twd_base);
292 297
293skip_errata_init: 298skip_errata_init:
294 omap_wakeupgen_init();
295#ifdef CONFIG_IRQ_CROSSBAR
296 irqcrossbar_init();
297#endif
298 irqchip_init(); 299 irqchip_init();
299} 300}
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)
252 return IRQ_HANDLED; 252 return IRQ_HANDLED;
253} 253}
254 254
255static int sh73a0_set_wake(struct irq_data *data, unsigned int on)
256{
257 return 0; /* always allow wakeup */
258}
259
260#define PINTER0_PHYS 0xe69000a0 255#define PINTER0_PHYS 0xe69000a0
261#define PINTER1_PHYS 0xe69000a4 256#define PINTER1_PHYS 0xe69000a4
262#define PINTER0_VIRT IOMEM(0xe69000a0) 257#define PINTER0_VIRT IOMEM(0xe69000a0)
@@ -318,8 +313,8 @@ void __init sh73a0_init_irq(void)
318 void __iomem *gic_cpu_base = IOMEM(0xf0000100); 313 void __iomem *gic_cpu_base = IOMEM(0xf0000100);
319 void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); 314 void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
320 315
316 gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE);
321 gic_init(0, 29, gic_dist_base, gic_cpu_base); 317 gic_init(0, 29, gic_dist_base, gic_cpu_base);
322 gic_arch_extn.irq_set_wake = sh73a0_set_wake;
323 318
324 register_intc_controller(&intcs_desc); 319 register_intc_controller(&intcs_desc);
325 register_intc_controller(&intc_pint0_desc); 320 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)
713} 713}
714 714
715#ifdef CONFIG_USE_OF 715#ifdef CONFIG_USE_OF
716static int r8a7779_set_wake(struct irq_data *data, unsigned int on)
717{
718 return 0; /* always allow wakeup */
719}
720
721void __init r8a7779_init_irq_dt(void) 716void __init r8a7779_init_irq_dt(void)
722{ 717{
723#ifdef CONFIG_ARCH_SHMOBILE_LEGACY 718#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
724 void __iomem *gic_dist_base = ioremap_nocache(0xf0001000, 0x1000); 719 void __iomem *gic_dist_base = ioremap_nocache(0xf0001000, 0x1000);
725 void __iomem *gic_cpu_base = ioremap_nocache(0xf0000100, 0x1000); 720 void __iomem *gic_cpu_base = ioremap_nocache(0xf0000100, 0x1000);
726#endif 721#endif
727 gic_arch_extn.irq_set_wake = r8a7779_set_wake; 722 gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE);
728 723
729#ifdef CONFIG_ARCH_SHMOBILE_LEGACY 724#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
730 gic_init(0, 29, gic_dist_base, gic_cpu_base); 725 gic_init(0, 29, gic_dist_base, gic_cpu_base);
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 @@
31#define TEGRA_ARM_INT_DIST_BASE 0x50041000 31#define TEGRA_ARM_INT_DIST_BASE 0x50041000
32#define TEGRA_ARM_INT_DIST_SIZE SZ_4K 32#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
33 33
34#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000
35#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64
36
37#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100
38#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64
39
40#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200
41#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64
42
43#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300
44#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64
45
46#define TEGRA_QUINARY_ICTLR_BASE 0x60004400
47#define TEGRA_QUINARY_ICTLR_SIZE SZ_64
48
49#define TEGRA_TMR1_BASE 0x60005000 34#define TEGRA_TMR1_BASE 0x60005000
50#define TEGRA_TMR1_SIZE SZ_8 35#define TEGRA_TMR1_SIZE SZ_8
51 36
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 @@
30#include "board.h" 30#include "board.h"
31#include "iomap.h" 31#include "iomap.h"
32 32
33#define ICTLR_CPU_IEP_VFIQ 0x08
34#define ICTLR_CPU_IEP_FIR 0x14
35#define ICTLR_CPU_IEP_FIR_SET 0x18
36#define ICTLR_CPU_IEP_FIR_CLR 0x1c
37
38#define ICTLR_CPU_IER 0x20
39#define ICTLR_CPU_IER_SET 0x24
40#define ICTLR_CPU_IER_CLR 0x28
41#define ICTLR_CPU_IEP_CLASS 0x2C
42
43#define ICTLR_COP_IER 0x30
44#define ICTLR_COP_IER_SET 0x34
45#define ICTLR_COP_IER_CLR 0x38
46#define ICTLR_COP_IEP_CLASS 0x3c
47
48#define FIRST_LEGACY_IRQ 32
49#define TEGRA_MAX_NUM_ICTLRS 5
50
51#define SGI_MASK 0xFFFF 33#define SGI_MASK 0xFFFF
52 34
53static int num_ictlrs;
54
55static void __iomem *ictlr_reg_base[] = {
56 IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
57 IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
58 IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
59 IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
60 IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
61};
62
63#ifdef CONFIG_PM_SLEEP 35#ifdef CONFIG_PM_SLEEP
64static u32 cop_ier[TEGRA_MAX_NUM_ICTLRS];
65static u32 cop_iep[TEGRA_MAX_NUM_ICTLRS];
66static u32 cpu_ier[TEGRA_MAX_NUM_ICTLRS];
67static u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS];
68
69static u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS];
70static void __iomem *tegra_gic_cpu_base; 36static void __iomem *tegra_gic_cpu_base;
71#endif 37#endif
72 38
@@ -83,140 +49,7 @@ bool tegra_pending_sgi(void)
83 return false; 49 return false;
84} 50}
85 51
86static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
87{
88 void __iomem *base;
89 u32 mask;
90
91 BUG_ON(irq < FIRST_LEGACY_IRQ ||
92 irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32);
93
94 base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32];
95 mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
96
97 __raw_writel(mask, base + reg);
98}
99
100static void tegra_mask(struct irq_data *d)
101{
102 if (d->hwirq < FIRST_LEGACY_IRQ)
103 return;
104
105 tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IER_CLR);
106}
107
108static void tegra_unmask(struct irq_data *d)
109{
110 if (d->hwirq < FIRST_LEGACY_IRQ)
111 return;
112
113 tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IER_SET);
114}
115
116static void tegra_ack(struct irq_data *d)
117{
118 if (d->hwirq < FIRST_LEGACY_IRQ)
119 return;
120
121 tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_CLR);
122}
123
124static void tegra_eoi(struct irq_data *d)
125{
126 if (d->hwirq < FIRST_LEGACY_IRQ)
127 return;
128
129 tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_CLR);
130}
131
132static int tegra_retrigger(struct irq_data *d)
133{
134 if (d->hwirq < FIRST_LEGACY_IRQ)
135 return 0;
136
137 tegra_irq_write_mask(d->hwirq, ICTLR_CPU_IEP_FIR_SET);
138
139 return 1;
140}
141
142#ifdef CONFIG_PM_SLEEP 52#ifdef CONFIG_PM_SLEEP
143static int tegra_set_wake(struct irq_data *d, unsigned int enable)
144{
145 u32 irq = d->hwirq;
146 u32 index, mask;
147
148 if (irq < FIRST_LEGACY_IRQ ||
149 irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32)
150 return -EINVAL;
151
152 index = ((irq - FIRST_LEGACY_IRQ) / 32);
153 mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
154 if (enable)
155 ictlr_wake_mask[index] |= mask;
156 else
157 ictlr_wake_mask[index] &= ~mask;
158
159 return 0;
160}
161
162static int tegra_legacy_irq_suspend(void)
163{
164 unsigned long flags;
165 int i;
166
167 local_irq_save(flags);
168 for (i = 0; i < num_ictlrs; i++) {
169 void __iomem *ictlr = ictlr_reg_base[i];
170 /* Save interrupt state */
171 cpu_ier[i] = readl_relaxed(ictlr + ICTLR_CPU_IER);
172 cpu_iep[i] = readl_relaxed(ictlr + ICTLR_CPU_IEP_CLASS);
173 cop_ier[i] = readl_relaxed(ictlr + ICTLR_COP_IER);
174 cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS);
175
176 /* Disable COP interrupts */
177 writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
178
179 /* Disable CPU interrupts */
180 writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
181
182 /* Enable the wakeup sources of ictlr */
183 writel_relaxed(ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET);
184 }
185 local_irq_restore(flags);
186
187 return 0;
188}
189
190static void tegra_legacy_irq_resume(void)
191{
192 unsigned long flags;
193 int i;
194
195 local_irq_save(flags);
196 for (i = 0; i < num_ictlrs; i++) {
197 void __iomem *ictlr = ictlr_reg_base[i];
198 writel_relaxed(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS);
199 writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
200 writel_relaxed(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET);
201 writel_relaxed(cop_iep[i], ictlr + ICTLR_COP_IEP_CLASS);
202 writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
203 writel_relaxed(cop_ier[i], ictlr + ICTLR_COP_IER_SET);
204 }
205 local_irq_restore(flags);
206}
207
208static struct syscore_ops tegra_legacy_irq_syscore_ops = {
209 .suspend = tegra_legacy_irq_suspend,
210 .resume = tegra_legacy_irq_resume,
211};
212
213int tegra_legacy_irq_syscore_init(void)
214{
215 register_syscore_ops(&tegra_legacy_irq_syscore_ops);
216
217 return 0;
218}
219
220static int tegra_gic_notifier(struct notifier_block *self, 53static int tegra_gic_notifier(struct notifier_block *self,
221 unsigned long cmd, void *v) 54 unsigned long cmd, void *v)
222{ 55{
@@ -251,45 +84,19 @@ static void tegra114_gic_cpu_pm_registration(void)
251 cpu_pm_register_notifier(&tegra_gic_notifier_block); 84 cpu_pm_register_notifier(&tegra_gic_notifier_block);
252} 85}
253#else 86#else
254#define tegra_set_wake NULL
255static void tegra114_gic_cpu_pm_registration(void) { } 87static void tegra114_gic_cpu_pm_registration(void) { }
256#endif 88#endif
257 89
90static const struct of_device_id tegra_ictlr_match[] __initconst = {
91 { .compatible = "nvidia,tegra20-ictlr" },
92 { .compatible = "nvidia,tegra30-ictlr" },
93 { }
94};
95
258void __init tegra_init_irq(void) 96void __init tegra_init_irq(void)
259{ 97{
260 int i; 98 if (WARN_ON(!of_find_matching_node(NULL, tegra_ictlr_match)))
261 void __iomem *distbase; 99 pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
262
263 distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
264 num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f;
265
266 if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) {
267 WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.",
268 num_ictlrs, ARRAY_SIZE(ictlr_reg_base));
269 num_ictlrs = ARRAY_SIZE(ictlr_reg_base);
270 }
271
272 for (i = 0; i < num_ictlrs; i++) {
273 void __iomem *ictlr = ictlr_reg_base[i];
274 writel(~0, ictlr + ICTLR_CPU_IER_CLR);
275 writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
276 }
277
278 gic_arch_extn.irq_ack = tegra_ack;
279 gic_arch_extn.irq_eoi = tegra_eoi;
280 gic_arch_extn.irq_mask = tegra_mask;
281 gic_arch_extn.irq_unmask = tegra_unmask;
282 gic_arch_extn.irq_retrigger = tegra_retrigger;
283 gic_arch_extn.irq_set_wake = tegra_set_wake;
284 gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND;
285
286 /*
287 * Check if there is a devicetree present, since the GIC will be
288 * initialized elsewhere under DT.
289 */
290 if (!of_have_populated_dt())
291 gic_init(0, 29, distbase,
292 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
293 100
294 tegra114_gic_cpu_pm_registration(); 101 tegra114_gic_cpu_pm_registration();
295} 102}
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 @@
19 19
20bool tegra_pending_sgi(void); 20bool tegra_pending_sgi(void);
21 21
22#ifdef CONFIG_PM_SLEEP
23int tegra_legacy_irq_syscore_init(void);
24#else
25static inline int tegra_legacy_irq_syscore_init(void) { return 0; }
26#endif
27
28#endif 22#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)
82{ 82{
83 tegra_init_irq(); 83 tegra_init_irq();
84 irqchip_init(); 84 irqchip_init();
85 tegra_legacy_irq_syscore_init();
86} 85}
87 86
88static void __init tegra_dt_init(void) 87static 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)
52*/ 52*/
53void __init ux500_init_irq(void) 53void __init ux500_init_irq(void)
54{ 54{
55 gic_arch_extn.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; 55 gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND);
56 irqchip_init(); 56 irqchip_init();
57 57
58 /* 58 /*
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)
186 186
187static void __init zynq_irq_init(void) 187static void __init zynq_irq_init(void)
188{ 188{
189 gic_arch_extn.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; 189 gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND);
190 irqchip_init(); 190 irqchip_init();
191} 191}
192 192
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f117092ae014..552a74027601 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o
6obj-$(CONFIG_ARCH_MMP) += irq-mmp.o 6obj-$(CONFIG_ARCH_MMP) += irq-mmp.o
7obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o 7obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o
8obj-$(CONFIG_ARCH_MXS) += irq-mxs.o 8obj-$(CONFIG_ARCH_MXS) += irq-mxs.o
9obj-$(CONFIG_ARCH_TEGRA) += irq-tegra.o
9obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o 10obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
10obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o 11obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o
11obj-$(CONFIG_METAG) += irq-metag-ext.o 12obj-$(CONFIG_METAG) += irq-metag-ext.o
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index bbbaf5de65d2..692fe2bc8197 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -11,11 +11,12 @@
11 */ 11 */
12#include <linux/err.h> 12#include <linux/err.h>
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/irqdomain.h>
14#include <linux/of_address.h> 15#include <linux/of_address.h>
15#include <linux/of_irq.h> 16#include <linux/of_irq.h>
16#include <linux/slab.h> 17#include <linux/slab.h>
17#include <linux/irqchip/arm-gic.h> 18
18#include <linux/irqchip/irq-crossbar.h> 19#include "irqchip.h"
19 20
20#define IRQ_FREE -1 21#define IRQ_FREE -1
21#define IRQ_RESERVED -2 22#define IRQ_RESERVED -2
@@ -24,6 +25,7 @@
24 25
25/** 26/**
26 * struct crossbar_device - crossbar device description 27 * struct crossbar_device - crossbar device description
28 * @lock: spinlock serializing access to @irq_map
27 * @int_max: maximum number of supported interrupts 29 * @int_max: maximum number of supported interrupts
28 * @safe_map: safe default value to initialize the crossbar 30 * @safe_map: safe default value to initialize the crossbar
29 * @max_crossbar_sources: Maximum number of crossbar sources 31 * @max_crossbar_sources: Maximum number of crossbar sources
@@ -33,6 +35,7 @@
33 * @write: register write function pointer 35 * @write: register write function pointer
34 */ 36 */
35struct crossbar_device { 37struct crossbar_device {
38 raw_spinlock_t lock;
36 uint int_max; 39 uint int_max;
37 uint safe_map; 40 uint safe_map;
38 uint max_crossbar_sources; 41 uint max_crossbar_sources;
@@ -44,72 +47,101 @@ struct crossbar_device {
44 47
45static struct crossbar_device *cb; 48static struct crossbar_device *cb;
46 49
47static inline void crossbar_writel(int irq_no, int cb_no) 50static void crossbar_writel(int irq_no, int cb_no)
48{ 51{
49 writel(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]); 52 writel(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
50} 53}
51 54
52static inline void crossbar_writew(int irq_no, int cb_no) 55static void crossbar_writew(int irq_no, int cb_no)
53{ 56{
54 writew(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]); 57 writew(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
55} 58}
56 59
57static inline void crossbar_writeb(int irq_no, int cb_no) 60static void crossbar_writeb(int irq_no, int cb_no)
58{ 61{
59 writeb(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]); 62 writeb(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
60} 63}
61 64
62static inline int get_prev_map_irq(int cb_no) 65static struct irq_chip crossbar_chip = {
63{ 66 .name = "CBAR",
64 int i; 67 .irq_eoi = irq_chip_eoi_parent,
65 68 .irq_mask = irq_chip_mask_parent,
66 for (i = cb->int_max - 1; i >= 0; i--) 69 .irq_unmask = irq_chip_unmask_parent,
67 if (cb->irq_map[i] == cb_no) 70 .irq_retrigger = irq_chip_retrigger_hierarchy,
68 return i; 71 .irq_set_wake = irq_chip_set_wake_parent,
69 72#ifdef CONFIG_SMP
70 return -ENODEV; 73 .irq_set_affinity = irq_chip_set_affinity_parent,
71} 74#endif
75};
72 76
73static inline int allocate_free_irq(int cb_no) 77static int allocate_gic_irq(struct irq_domain *domain, unsigned virq,
78 irq_hw_number_t hwirq)
74{ 79{
80 struct of_phandle_args args;
75 int i; 81 int i;
82 int err;
76 83
84 raw_spin_lock(&cb->lock);
77 for (i = cb->int_max - 1; i >= 0; i--) { 85 for (i = cb->int_max - 1; i >= 0; i--) {
78 if (cb->irq_map[i] == IRQ_FREE) { 86 if (cb->irq_map[i] == IRQ_FREE) {
79 cb->irq_map[i] = cb_no; 87 cb->irq_map[i] = hwirq;
80 return i; 88 break;
81 } 89 }
82 } 90 }
91 raw_spin_unlock(&cb->lock);
83 92
84 return -ENODEV; 93 if (i < 0)
85} 94 return -ENODEV;
86 95
87static inline bool needs_crossbar_write(irq_hw_number_t hw) 96 args.np = domain->parent->of_node;
88{ 97 args.args_count = 3;
89 int cb_no; 98 args.args[0] = 0; /* SPI */
99 args.args[1] = i;
100 args.args[2] = IRQ_TYPE_LEVEL_HIGH;
90 101
91 if (hw > GIC_IRQ_START) { 102 err = irq_domain_alloc_irqs_parent(domain, virq, 1, &args);
92 cb_no = cb->irq_map[hw - GIC_IRQ_START]; 103 if (err)
93 if (cb_no != IRQ_RESERVED && cb_no != IRQ_SKIP) 104 cb->irq_map[i] = IRQ_FREE;
94 return true; 105 else
95 } 106 cb->write(i, hwirq);
96 107
97 return false; 108 return err;
98} 109}
99 110
100static int crossbar_domain_map(struct irq_domain *d, unsigned int irq, 111static int crossbar_domain_alloc(struct irq_domain *d, unsigned int virq,
101 irq_hw_number_t hw) 112 unsigned int nr_irqs, void *data)
102{ 113{
103 if (needs_crossbar_write(hw)) 114 struct of_phandle_args *args = data;
104 cb->write(hw - GIC_IRQ_START, cb->irq_map[hw - GIC_IRQ_START]); 115 irq_hw_number_t hwirq;
116 int i;
117
118 if (args->args_count != 3)
119 return -EINVAL; /* Not GIC compliant */
120 if (args->args[0] != 0)
121 return -EINVAL; /* No PPI should point to this domain */
122
123 hwirq = args->args[1];
124 if ((hwirq + nr_irqs) > cb->max_crossbar_sources)
125 return -EINVAL; /* Can't deal with this */
126
127 for (i = 0; i < nr_irqs; i++) {
128 int err = allocate_gic_irq(d, virq + i, hwirq + i);
129
130 if (err)
131 return err;
132
133 irq_domain_set_hwirq_and_chip(d, virq + i, hwirq + i,
134 &crossbar_chip, NULL);
135 }
105 136
106 return 0; 137 return 0;
107} 138}
108 139
109/** 140/**
110 * crossbar_domain_unmap - unmap a crossbar<->irq connection 141 * crossbar_domain_free - unmap/free a crossbar<->irq connection
111 * @d: domain of irq to unmap 142 * @domain: domain of irq to unmap
112 * @irq: virq number 143 * @virq: virq number
144 * @nr_irqs: number of irqs to free
113 * 145 *
114 * We do not maintain a use count of total number of map/unmap 146 * We do not maintain a use count of total number of map/unmap
115 * calls for a particular irq to find out if a irq can be really 147 * calls for a particular irq to find out if a irq can be really
@@ -117,14 +149,20 @@ static int crossbar_domain_map(struct irq_domain *d, unsigned int irq,
117 * after which irq is anyways unusable. So an explicit map has to be called 149 * after which irq is anyways unusable. So an explicit map has to be called
118 * after that. 150 * after that.
119 */ 151 */
120static void crossbar_domain_unmap(struct irq_domain *d, unsigned int irq) 152static void crossbar_domain_free(struct irq_domain *domain, unsigned int virq,
153 unsigned int nr_irqs)
121{ 154{
122 irq_hw_number_t hw = irq_get_irq_data(irq)->hwirq; 155 int i;
123 156
124 if (needs_crossbar_write(hw)) { 157 raw_spin_lock(&cb->lock);
125 cb->irq_map[hw - GIC_IRQ_START] = IRQ_FREE; 158 for (i = 0; i < nr_irqs; i++) {
126 cb->write(hw - GIC_IRQ_START, cb->safe_map); 159 struct irq_data *d = irq_domain_get_irq_data(domain, virq + i);
160
161 irq_domain_reset_irq_data(d);
162 cb->irq_map[d->hwirq] = IRQ_FREE;
163 cb->write(d->hwirq, cb->safe_map);
127 } 164 }
165 raw_spin_unlock(&cb->lock);
128} 166}
129 167
130static int crossbar_domain_xlate(struct irq_domain *d, 168static int crossbar_domain_xlate(struct irq_domain *d,
@@ -133,44 +171,22 @@ static int crossbar_domain_xlate(struct irq_domain *d,
133 unsigned long *out_hwirq, 171 unsigned long *out_hwirq,
134 unsigned int *out_type) 172 unsigned int *out_type)
135{ 173{
136 int ret; 174 if (d->of_node != controller)
137 int req_num = intspec[1]; 175 return -EINVAL; /* Shouldn't happen, really... */
138 int direct_map_num; 176 if (intsize != 3)
139 177 return -EINVAL; /* Not GIC compliant */
140 if (req_num >= cb->max_crossbar_sources) { 178 if (intspec[0] != 0)
141 direct_map_num = req_num - cb->max_crossbar_sources; 179 return -EINVAL; /* No PPI should point to this domain */
142 if (direct_map_num < cb->int_max) { 180
143 ret = cb->irq_map[direct_map_num]; 181 *out_hwirq = intspec[1];
144 if (ret == IRQ_RESERVED || ret == IRQ_SKIP) { 182 *out_type = intspec[2];
145 /* We use the interrupt num as h/w irq num */
146 ret = direct_map_num;
147 goto found;
148 }
149 }
150
151 pr_err("%s: requested crossbar number %d > max %d\n",
152 __func__, req_num, cb->max_crossbar_sources);
153 return -EINVAL;
154 }
155
156 ret = get_prev_map_irq(req_num);
157 if (ret >= 0)
158 goto found;
159
160 ret = allocate_free_irq(req_num);
161
162 if (ret < 0)
163 return ret;
164
165found:
166 *out_hwirq = ret + GIC_IRQ_START;
167 return 0; 183 return 0;
168} 184}
169 185
170static const struct irq_domain_ops routable_irq_domain_ops = { 186static const struct irq_domain_ops crossbar_domain_ops = {
171 .map = crossbar_domain_map, 187 .alloc = crossbar_domain_alloc,
172 .unmap = crossbar_domain_unmap, 188 .free = crossbar_domain_free,
173 .xlate = crossbar_domain_xlate 189 .xlate = crossbar_domain_xlate,
174}; 190};
175 191
176static int __init crossbar_of_init(struct device_node *node) 192static int __init crossbar_of_init(struct device_node *node)
@@ -293,7 +309,8 @@ static int __init crossbar_of_init(struct device_node *node)
293 cb->write(i, cb->safe_map); 309 cb->write(i, cb->safe_map);
294 } 310 }
295 311
296 register_routable_domain_ops(&routable_irq_domain_ops); 312 raw_spin_lock_init(&cb->lock);
313
297 return 0; 314 return 0;
298 315
299err_reg_offset: 316err_reg_offset:
@@ -309,18 +326,37 @@ err_cb:
309 return ret; 326 return ret;
310} 327}
311 328
312static const struct of_device_id crossbar_match[] __initconst = { 329static int __init irqcrossbar_init(struct device_node *node,
313 { .compatible = "ti,irq-crossbar" }, 330 struct device_node *parent)
314 {}
315};
316
317int __init irqcrossbar_init(void)
318{ 331{
319 struct device_node *np; 332 struct irq_domain *parent_domain, *domain;
320 np = of_find_matching_node(NULL, crossbar_match); 333 int err;
321 if (!np) 334
335 if (!parent) {
336 pr_err("%s: no parent, giving up\n", node->full_name);
322 return -ENODEV; 337 return -ENODEV;
338 }
339
340 parent_domain = irq_find_host(parent);
341 if (!parent_domain) {
342 pr_err("%s: unable to obtain parent domain\n", node->full_name);
343 return -ENXIO;
344 }
345
346 err = crossbar_of_init(node);
347 if (err)
348 return err;
349
350 domain = irq_domain_add_hierarchy(parent_domain, 0,
351 cb->max_crossbar_sources,
352 node, &crossbar_domain_ops,
353 NULL);
354 if (!domain) {
355 pr_err("%s: failed to allocated domain\n", node->full_name);
356 return -ENOMEM;
357 }
323 358
324 crossbar_of_init(np);
325 return 0; 359 return 0;
326} 360}
361
362IRQCHIP_DECLARE(ti_irqcrossbar, "ti,irq-crossbar", irqcrossbar_init);
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index d6d6b74801d4..a6ce3476834e 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -863,15 +863,12 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
863 irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, 863 irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
864 handle_fasteoi_irq, NULL, NULL); 864 handle_fasteoi_irq, NULL, NULL);
865 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 865 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
866
867 gic_routable_irq_domain_ops->map(d, irq, hw);
868 } 866 }
869 return 0; 867 return 0;
870} 868}
871 869
872static void gic_irq_domain_unmap(struct irq_domain *d, unsigned int irq) 870static void gic_irq_domain_unmap(struct irq_domain *d, unsigned int irq)
873{ 871{
874 gic_routable_irq_domain_ops->unmap(d, irq);
875} 872}
876 873
877static int gic_irq_domain_xlate(struct irq_domain *d, 874static int gic_irq_domain_xlate(struct irq_domain *d,
@@ -890,16 +887,8 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
890 *out_hwirq = intspec[1] + 16; 887 *out_hwirq = intspec[1] + 16;
891 888
892 /* For SPIs, we need to add 16 more to get the GIC irq ID number */ 889 /* For SPIs, we need to add 16 more to get the GIC irq ID number */
893 if (!intspec[0]) { 890 if (!intspec[0])
894 ret = gic_routable_irq_domain_ops->xlate(d, controller, 891 *out_hwirq += 16;
895 intspec,
896 intsize,
897 out_hwirq,
898 out_type);
899
900 if (IS_ERR_VALUE(ret))
901 return ret;
902 }
903 892
904 *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; 893 *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
905 894
@@ -956,37 +945,11 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
956 .xlate = gic_irq_domain_xlate, 945 .xlate = gic_irq_domain_xlate,
957}; 946};
958 947
959/* Default functions for routable irq domain */ 948void gic_set_irqchip_flags(unsigned long flags)
960static int gic_routable_irq_domain_map(struct irq_domain *d, unsigned int irq,
961 irq_hw_number_t hw)
962{
963 return 0;
964}
965
966static void gic_routable_irq_domain_unmap(struct irq_domain *d,
967 unsigned int irq)
968{
969}
970
971static int gic_routable_irq_domain_xlate(struct irq_domain *d,
972 struct device_node *controller,
973 const u32 *intspec, unsigned int intsize,
974 unsigned long *out_hwirq,
975 unsigned int *out_type)
976{ 949{
977 *out_hwirq += 16; 950 gic_chip.flags |= flags;
978 return 0;
979} 951}
980 952
981static const struct irq_domain_ops gic_default_routable_irq_domain_ops = {
982 .map = gic_routable_irq_domain_map,
983 .unmap = gic_routable_irq_domain_unmap,
984 .xlate = gic_routable_irq_domain_xlate,
985};
986
987const struct irq_domain_ops *gic_routable_irq_domain_ops =
988 &gic_default_routable_irq_domain_ops;
989
990void __init gic_init_bases(unsigned int gic_nr, int irq_start, 953void __init gic_init_bases(unsigned int gic_nr, int irq_start,
991 void __iomem *dist_base, void __iomem *cpu_base, 954 void __iomem *dist_base, void __iomem *cpu_base,
992 u32 percpu_offset, struct device_node *node) 955 u32 percpu_offset, struct device_node *node)
@@ -994,7 +957,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
994 irq_hw_number_t hwirq_base; 957 irq_hw_number_t hwirq_base;
995 struct gic_chip_data *gic; 958 struct gic_chip_data *gic;
996 int gic_irqs, irq_base, i; 959 int gic_irqs, irq_base, i;
997 int nr_routable_irqs;
998 960
999 BUG_ON(gic_nr >= MAX_GIC_NR); 961 BUG_ON(gic_nr >= MAX_GIC_NR);
1000 962
@@ -1050,15 +1012,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
1050 gic->gic_irqs = gic_irqs; 1012 gic->gic_irqs = gic_irqs;
1051 1013
1052 if (node) { /* DT case */ 1014 if (node) { /* DT case */
1053 const struct irq_domain_ops *ops = &gic_irq_domain_hierarchy_ops; 1015 gic->domain = irq_domain_add_linear(node, gic_irqs,
1054 1016 &gic_irq_domain_hierarchy_ops,
1055 if (!of_property_read_u32(node, "arm,routable-irqs", 1017 gic);
1056 &nr_routable_irqs)) {
1057 ops = &gic_irq_domain_ops;
1058 gic_irqs = nr_routable_irqs;
1059 }
1060
1061 gic->domain = irq_domain_add_linear(node, gic_irqs, ops, gic);
1062 } else { /* Non-DT case */ 1018 } else { /* Non-DT case */
1063 /* 1019 /*
1064 * For primary GICs, skip over SGIs. 1020 * For primary GICs, skip over SGIs.
diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c
new file mode 100644
index 000000000000..51c485d9a877
--- /dev/null
+++ b/drivers/irqchip/irq-tegra.c
@@ -0,0 +1,377 @@
1/*
2 * Driver code for Tegra's Legacy Interrupt Controller
3 *
4 * Author: Marc Zyngier <marc.zyngier@arm.com>
5 *
6 * Heavily based on the original arch/arm/mach-tegra/irq.c code:
7 * Copyright (C) 2011 Google, Inc.
8 *
9 * Author:
10 * Colin Cross <ccross@android.com>
11 *
12 * Copyright (C) 2010,2013, NVIDIA Corporation
13 *
14 * This software is licensed under the terms of the GNU General Public
15 * License version 2, as published by the Free Software Foundation, and
16 * may be copied, distributed, and modified under those terms.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 */
24
25#include <linux/io.h>
26#include <linux/irq.h>
27#include <linux/irqdomain.h>
28#include <linux/of_address.h>
29#include <linux/slab.h>
30#include <linux/syscore_ops.h>
31
32#include <dt-bindings/interrupt-controller/arm-gic.h>
33
34#include "irqchip.h"
35
36#define ICTLR_CPU_IEP_VFIQ 0x08
37#define ICTLR_CPU_IEP_FIR 0x14
38#define ICTLR_CPU_IEP_FIR_SET 0x18
39#define ICTLR_CPU_IEP_FIR_CLR 0x1c
40
41#define ICTLR_CPU_IER 0x20
42#define ICTLR_CPU_IER_SET 0x24
43#define ICTLR_CPU_IER_CLR 0x28
44#define ICTLR_CPU_IEP_CLASS 0x2C
45
46#define ICTLR_COP_IER 0x30
47#define ICTLR_COP_IER_SET 0x34
48#define ICTLR_COP_IER_CLR 0x38
49#define ICTLR_COP_IEP_CLASS 0x3c
50
51#define TEGRA_MAX_NUM_ICTLRS 6
52
53static unsigned int num_ictlrs;
54
55struct tegra_ictlr_soc {
56 unsigned int num_ictlrs;
57};
58
59static const struct tegra_ictlr_soc tegra20_ictlr_soc = {
60 .num_ictlrs = 4,
61};
62
63static const struct tegra_ictlr_soc tegra30_ictlr_soc = {
64 .num_ictlrs = 5,
65};
66
67static const struct tegra_ictlr_soc tegra210_ictlr_soc = {
68 .num_ictlrs = 6,
69};
70
71static const struct of_device_id ictlr_matches[] = {
72 { .compatible = "nvidia,tegra210-ictlr", .data = &tegra210_ictlr_soc },
73 { .compatible = "nvidia,tegra30-ictlr", .data = &tegra30_ictlr_soc },
74 { .compatible = "nvidia,tegra20-ictlr", .data = &tegra20_ictlr_soc },
75 { }
76};
77
78struct tegra_ictlr_info {
79 void __iomem *base[TEGRA_MAX_NUM_ICTLRS];
80#ifdef CONFIG_PM_SLEEP
81 u32 cop_ier[TEGRA_MAX_NUM_ICTLRS];
82 u32 cop_iep[TEGRA_MAX_NUM_ICTLRS];
83 u32 cpu_ier[TEGRA_MAX_NUM_ICTLRS];
84 u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS];
85
86 u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS];
87#endif
88};
89
90static struct tegra_ictlr_info *lic;
91
92static inline void tegra_ictlr_write_mask(struct irq_data *d, unsigned long reg)
93{
94 void __iomem *base = d->chip_data;
95 u32 mask;
96
97 mask = BIT(d->hwirq % 32);
98 writel_relaxed(mask, base + reg);
99}
100
101static void tegra_mask(struct irq_data *d)
102{
103 tegra_ictlr_write_mask(d, ICTLR_CPU_IER_CLR);
104 irq_chip_mask_parent(d);
105}
106
107static void tegra_unmask(struct irq_data *d)
108{
109 tegra_ictlr_write_mask(d, ICTLR_CPU_IER_SET);
110 irq_chip_unmask_parent(d);
111}
112
113static void tegra_eoi(struct irq_data *d)
114{
115 tegra_ictlr_write_mask(d, ICTLR_CPU_IEP_FIR_CLR);
116 irq_chip_eoi_parent(d);
117}
118
119static int tegra_retrigger(struct irq_data *d)
120{
121 tegra_ictlr_write_mask(d, ICTLR_CPU_IEP_FIR_SET);
122 return irq_chip_retrigger_hierarchy(d);
123}
124
125#ifdef CONFIG_PM_SLEEP
126static int tegra_set_wake(struct irq_data *d, unsigned int enable)
127{
128 u32 irq = d->hwirq;
129 u32 index, mask;
130
131 index = (irq / 32);
132 mask = BIT(irq % 32);
133 if (enable)
134 lic->ictlr_wake_mask[index] |= mask;
135 else
136 lic->ictlr_wake_mask[index] &= ~mask;
137
138 /*
139 * Do *not* call into the parent, as the GIC doesn't have any
140 * wake-up facility...
141 */
142 return 0;
143}
144
145static int tegra_ictlr_suspend(void)
146{
147 unsigned long flags;
148 unsigned int i;
149
150 local_irq_save(flags);
151 for (i = 0; i < num_ictlrs; i++) {
152 void __iomem *ictlr = lic->base[i];
153
154 /* Save interrupt state */
155 lic->cpu_ier[i] = readl_relaxed(ictlr + ICTLR_CPU_IER);
156 lic->cpu_iep[i] = readl_relaxed(ictlr + ICTLR_CPU_IEP_CLASS);
157 lic->cop_ier[i] = readl_relaxed(ictlr + ICTLR_COP_IER);
158 lic->cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS);
159
160 /* Disable COP interrupts */
161 writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
162
163 /* Disable CPU interrupts */
164 writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
165
166 /* Enable the wakeup sources of ictlr */
167 writel_relaxed(lic->ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET);
168 }
169 local_irq_restore(flags);
170
171 return 0;
172}
173
174static void tegra_ictlr_resume(void)
175{
176 unsigned long flags;
177 unsigned int i;
178
179 local_irq_save(flags);
180 for (i = 0; i < num_ictlrs; i++) {
181 void __iomem *ictlr = lic->base[i];
182
183 writel_relaxed(lic->cpu_iep[i],
184 ictlr + ICTLR_CPU_IEP_CLASS);
185 writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
186 writel_relaxed(lic->cpu_ier[i],
187 ictlr + ICTLR_CPU_IER_SET);
188 writel_relaxed(lic->cop_iep[i],
189 ictlr + ICTLR_COP_IEP_CLASS);
190 writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
191 writel_relaxed(lic->cop_ier[i],
192 ictlr + ICTLR_COP_IER_SET);
193 }
194 local_irq_restore(flags);
195}
196
197static struct syscore_ops tegra_ictlr_syscore_ops = {
198 .suspend = tegra_ictlr_suspend,
199 .resume = tegra_ictlr_resume,
200};
201
202static void tegra_ictlr_syscore_init(void)
203{
204 register_syscore_ops(&tegra_ictlr_syscore_ops);
205}
206#else
207#define tegra_set_wake NULL
208static inline void tegra_ictlr_syscore_init(void) {}
209#endif
210
211static struct irq_chip tegra_ictlr_chip = {
212 .name = "LIC",
213 .irq_eoi = tegra_eoi,
214 .irq_mask = tegra_mask,
215 .irq_unmask = tegra_unmask,
216 .irq_retrigger = tegra_retrigger,
217 .irq_set_wake = tegra_set_wake,
218 .flags = IRQCHIP_MASK_ON_SUSPEND,
219#ifdef CONFIG_SMP
220 .irq_set_affinity = irq_chip_set_affinity_parent,
221#endif
222};
223
224static int tegra_ictlr_domain_xlate(struct irq_domain *domain,
225 struct device_node *controller,
226 const u32 *intspec,
227 unsigned int intsize,
228 unsigned long *out_hwirq,
229 unsigned int *out_type)
230{
231 if (domain->of_node != controller)
232 return -EINVAL; /* Shouldn't happen, really... */
233 if (intsize != 3)
234 return -EINVAL; /* Not GIC compliant */
235 if (intspec[0] != GIC_SPI)
236 return -EINVAL; /* No PPI should point to this domain */
237
238 *out_hwirq = intspec[1];
239 *out_type = intspec[2];
240 return 0;
241}
242
243static int tegra_ictlr_domain_alloc(struct irq_domain *domain,
244 unsigned int virq,
245 unsigned int nr_irqs, void *data)
246{
247 struct of_phandle_args *args = data;
248 struct of_phandle_args parent_args;
249 struct tegra_ictlr_info *info = domain->host_data;
250 irq_hw_number_t hwirq;
251 unsigned int i;
252
253 if (args->args_count != 3)
254 return -EINVAL; /* Not GIC compliant */
255 if (args->args[0] != GIC_SPI)
256 return -EINVAL; /* No PPI should point to this domain */
257
258 hwirq = args->args[1];
259 if (hwirq >= (num_ictlrs * 32))
260 return -EINVAL;
261
262 for (i = 0; i < nr_irqs; i++) {
263 int ictlr = (hwirq + i) / 32;
264
265 irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
266 &tegra_ictlr_chip,
267 &info->base[ictlr]);
268 }
269
270 parent_args = *args;
271 parent_args.np = domain->parent->of_node;
272 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
273}
274
275static void tegra_ictlr_domain_free(struct irq_domain *domain,
276 unsigned int virq,
277 unsigned int nr_irqs)
278{
279 unsigned int i;
280
281 for (i = 0; i < nr_irqs; i++) {
282 struct irq_data *d = irq_domain_get_irq_data(domain, virq + i);
283 irq_domain_reset_irq_data(d);
284 }
285}
286
287static const struct irq_domain_ops tegra_ictlr_domain_ops = {
288 .xlate = tegra_ictlr_domain_xlate,
289 .alloc = tegra_ictlr_domain_alloc,
290 .free = tegra_ictlr_domain_free,
291};
292
293static int __init tegra_ictlr_init(struct device_node *node,
294 struct device_node *parent)
295{
296 struct irq_domain *parent_domain, *domain;
297 const struct of_device_id *match;
298 const struct tegra_ictlr_soc *soc;
299 unsigned int i;
300 int err;
301
302 if (!parent) {
303 pr_err("%s: no parent, giving up\n", node->full_name);
304 return -ENODEV;
305 }
306
307 parent_domain = irq_find_host(parent);
308 if (!parent_domain) {
309 pr_err("%s: unable to obtain parent domain\n", node->full_name);
310 return -ENXIO;
311 }
312
313 match = of_match_node(ictlr_matches, node);
314 if (!match) /* Should never happen... */
315 return -ENODEV;
316
317 soc = match->data;
318
319 lic = kzalloc(sizeof(*lic), GFP_KERNEL);
320 if (!lic)
321 return -ENOMEM;
322
323 for (i = 0; i < TEGRA_MAX_NUM_ICTLRS; i++) {
324 void __iomem *base;
325
326 base = of_iomap(node, i);
327 if (!base)
328 break;
329
330 lic->base[i] = base;
331
332 /* Disable all interrupts */
333 writel_relaxed(~0UL, base + ICTLR_CPU_IER_CLR);
334 /* All interrupts target IRQ */
335 writel_relaxed(0, base + ICTLR_CPU_IEP_CLASS);
336
337 num_ictlrs++;
338 }
339
340 if (!num_ictlrs) {
341 pr_err("%s: no valid regions, giving up\n", node->full_name);
342 err = -ENOMEM;
343 goto out_free;
344 }
345
346 WARN(num_ictlrs != soc->num_ictlrs,
347 "%s: Found %u interrupt controllers in DT; expected %u.\n",
348 node->full_name, num_ictlrs, soc->num_ictlrs);
349
350
351 domain = irq_domain_add_hierarchy(parent_domain, 0, num_ictlrs * 32,
352 node, &tegra_ictlr_domain_ops,
353 lic);
354 if (!domain) {
355 pr_err("%s: failed to allocated domain\n", node->full_name);
356 err = -ENOMEM;
357 goto out_unmap;
358 }
359
360 tegra_ictlr_syscore_init();
361
362 pr_info("%s: %d interrupts forwarded to %s\n",
363 node->full_name, num_ictlrs * 32, parent->full_name);
364
365 return 0;
366
367out_unmap:
368 for (i = 0; i < num_ictlrs; i++)
369 iounmap(lic->base[i]);
370out_free:
371 kfree(lic);
372 return err;
373}
374
375IRQCHIP_DECLARE(tegra20_ictlr, "nvidia,tegra20-ictlr", tegra_ictlr_init);
376IRQCHIP_DECLARE(tegra30_ictlr, "nvidia,tegra30-ictlr", tegra_ictlr_init);
377IRQCHIP_DECLARE(tegra210_ictlr, "nvidia,tegra210-ictlr", tegra_ictlr_init);
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 77dd2e7f93f4..62c6901cab55 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -466,6 +466,7 @@ extern void irq_chip_eoi_parent(struct irq_data *data);
466extern int irq_chip_set_affinity_parent(struct irq_data *data, 466extern int irq_chip_set_affinity_parent(struct irq_data *data,
467 const struct cpumask *dest, 467 const struct cpumask *dest,
468 bool force); 468 bool force);
469extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
469#endif 470#endif
470 471
471/* Handling of unhandled and spurious interrupts: */ 472/* Handling of unhandled and spurious interrupts: */
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 71d706d5f169..36ec4ae74634 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -97,6 +97,7 @@ struct device_node;
97 97
98extern struct irq_chip gic_arch_extn; 98extern struct irq_chip gic_arch_extn;
99 99
100void gic_set_irqchip_flags(unsigned long flags);
100void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, 101void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
101 u32 offset, struct device_node *); 102 u32 offset, struct device_node *);
102void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); 103void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
@@ -115,11 +116,5 @@ int gic_get_cpu_id(unsigned int cpu);
115void gic_migrate_target(unsigned int new_cpu_id); 116void gic_migrate_target(unsigned int new_cpu_id);
116unsigned long gic_get_sgir_physaddr(void); 117unsigned long gic_get_sgir_physaddr(void);
117 118
118extern const struct irq_domain_ops *gic_routable_irq_domain_ops;
119static inline void __init register_routable_domain_ops
120 (const struct irq_domain_ops *ops)
121{
122 gic_routable_irq_domain_ops = ops;
123}
124#endif /* __ASSEMBLY */ 119#endif /* __ASSEMBLY */
125#endif 120#endif
diff --git a/include/linux/irqchip/irq-crossbar.h b/include/linux/irqchip/irq-crossbar.h
deleted file mode 100644
index e5537b81df8d..000000000000
--- a/include/linux/irqchip/irq-crossbar.h
+++ /dev/null
@@ -1,11 +0,0 @@
1/*
2 * drivers/irqchip/irq-crossbar.h
3 *
4 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11int irqcrossbar_init(void);
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 6f1c7a566b95..eb9a4ea394ab 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -948,6 +948,22 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data)
948 948
949 return -ENOSYS; 949 return -ENOSYS;
950} 950}
951
952/**
953 * irq_chip_set_wake_parent - Set/reset wake-up on the parent interrupt
954 * @data: Pointer to interrupt specific data
955 * @on: Whether to set or reset the wake-up capability of this irq
956 *
957 * Conditional, as the underlying parent chip might not implement it.
958 */
959int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
960{
961 data = data->parent_data;
962 if (data->chip->irq_set_wake)
963 return data->chip->irq_set_wake(data, on);
964
965 return -ENOSYS;
966}
951#endif 967#endif
952 968
953/** 969/**