aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 18:54:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 18:54:50 -0400
commit8954672d86d036643e3ce7ce3b2422c336db66d0 (patch)
treef68f4f97fe7a9e43d4ada455bbaf3a5af5725b34
parent3be1b98e073bdd4c1bb3144201a927c4a21330ba (diff)
parentb7dccbea6b079be01e07921264709f249009b8e8 (diff)
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq core updates from Thomas Gleixner: "Managerial summary: Core code: - final removal of IRQF_DISABLED - new state save/restore functions for virtualization support - wakeup support for stacked irqdomains - new function to solve the netpoll synchronization problem irqchips: - new driver for STi based devices - new driver for Vybrid MSCM - massive cleanup of the GIC driver by moving the GIC-addons to stacked irqdomains - the usual pile of fixes and updates to the various chip drivers" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits) irqchip: GICv3: Add support for irq_[get, set]_irqchip_state() irqchip: GIC: Add support for irq_[get, set]_irqchip_state() genirq: Allow the irqchip state of an IRQ to be save/restored genirq: MSI: Fix freeing of unallocated MSI irqchip: renesas-irqc: Add wake-up support irqchip: armada-370-xp: Allow using wakeup source irqchip: mips-gic: Add new functions to start/stop the GIC counter irqchip: tegra: Add Tegra210 support irqchip: digicolor: Move digicolor_set_gc to init section irqchip: renesas-irqc: Add functional clock to bindings irqchip: renesas-irqc: Add minimal runtime PM support irqchip: renesas-irqc: Add more register documentation DT: exynos: update PMU binding ARM: exynos4/5: convert pmu wakeup to stacked domains irqchip: gic: Don't complain in gic_get_cpumask() if UP system ARM: zynq: switch from gic_arch_extn to gic_set_irqchip_flags ARM: ux500: switch from gic_arch_extn to gic_set_irqchip_flags ARM: shmobile: remove use of gic_arch_extn.irq_set_wake irqchip: gic: Add an entry point to set up irqchip flags ARM: omap: convert wakeupgen to stacked domains ...
-rw-r--r--Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt14
-rw-r--r--Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt33
-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/renesas,irqc.txt4
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/st,sti-irq-syscfg.txt35
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu33
-rw-r--r--Documentation/scsi/ncr53c8xx.txt25
-rw-r--r--Documentation/scsi/tmscsim.txt4
-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-imx/Kconfig1
-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--arch/mips/loongson/loongson-3/hpet.c2
-rw-r--r--drivers/block/cpqarray.c4
-rw-r--r--drivers/bus/omap_l3_noc.c4
-rw-r--r--drivers/bus/omap_l3_smx.c10
-rw-r--r--drivers/irqchip/Kconfig7
-rw-r--r--drivers/irqchip/Makefile3
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c89
-rw-r--r--drivers/irqchip/irq-crossbar.c210
-rw-r--r--drivers/irqchip/irq-digicolor.c4
-rw-r--r--drivers/irqchip/irq-gic-v3.c83
-rw-r--r--drivers/irqchip/irq-gic.c129
-rw-r--r--drivers/irqchip/irq-mips-gic.c21
-rw-r--r--drivers/irqchip/irq-renesas-irqc.c58
-rw-r--r--drivers/irqchip/irq-st.c206
-rw-r--r--drivers/irqchip/irq-tegra.c377
-rw-r--r--drivers/irqchip/irq-vf610-mscm-ir.c212
-rw-r--r--drivers/mtd/nand/hisi504_nand.c3
-rw-r--r--include/dt-bindings/interrupt-controller/irq-st.h30
-rw-r--r--include/linux/hardirq.h2
-rw-r--r--include/linux/interrupt.h18
-rw-r--r--include/linux/irq.h7
-rw-r--r--include/linux/irqchip/arm-gic.h7
-rw-r--r--include/linux/irqchip/irq-crossbar.h11
-rw-r--r--include/linux/irqchip/mips-gic.h2
-rw-r--r--include/linux/irqflags.h43
-rw-r--r--kernel/irq/chip.c16
-rw-r--r--kernel/irq/manage.c127
-rw-r--r--kernel/irq/msi.c11
79 files changed, 2032 insertions, 669 deletions
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt
new file mode 100644
index 000000000000..44aa3c451ccf
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt
@@ -0,0 +1,14 @@
1Freescale Vybrid Miscellaneous System Control - CPU Configuration
2
3The MSCM IP contains multiple sub modules, this binding describes the first
4block of registers which contains CPU configuration information.
5
6Required properties:
7- compatible: "fsl,vf610-mscm-cpucfg", "syscon"
8- reg: the register range of the MSCM CPU configuration registers
9
10Example:
11 mscm_cpucfg: cpucfg@40001000 {
12 compatible = "fsl,vf610-mscm-cpucfg", "syscon";
13 reg = <0x40001000 0x800>;
14 }
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt
new file mode 100644
index 000000000000..669808b2af49
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt
@@ -0,0 +1,33 @@
1Freescale Vybrid Miscellaneous System Control - Interrupt Router
2
3The MSCM IP contains multiple sub modules, this binding describes the second
4block of registers which control the interrupt router. The interrupt router
5allows to configure the recipient of each peripheral interrupt. Furthermore
6it controls the directed processor interrupts. The module is available in all
7Vybrid SoC's but is only really useful in dual core configurations (VF6xx
8which comes with a Cortex-A5/Cortex-M4 combination).
9
10Required properties:
11- compatible: "fsl,vf610-mscm-ir"
12- reg: the register range of the MSCM Interrupt Router
13- fsl,cpucfg: The handle to the MSCM CPU configuration node, required
14 to get the current CPU ID
15- interrupt-controller: Identifies the node as an interrupt controller
16- #interrupt-cells: Two cells, interrupt number and cells.
17 The hardware interrupt number according to interrupt
18 assignment of the interrupt router is required.
19 Flags get passed only when using GIC as parent. Flags
20 encoding as documented by the GIC bindings.
21- interrupt-parent: Should be the phandle for the interrupt controller of
22 the CPU the device tree is intended to be used on. This
23 is either the node of the GIC or NVIC controller.
24
25Example:
26 mscm_ir: interrupt-controller@40001800 {
27 compatible = "fsl,vf610-mscm-ir";
28 reg = <0x40001800 0x400>;
29 fsl,cpucfg = <&mscm_cpucfg>;
30 interrupt-controller;
31 #interrupt-cells = <2>;
32 interrupt-parent = <&intc>;
33 }
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/renesas,irqc.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
index 1a88e62228e5..63633bdea7e4 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
@@ -4,7 +4,7 @@ Required properties:
4 4
5- compatible: has to be "renesas,irqc-<soctype>", "renesas,irqc" as fallback. 5- compatible: has to be "renesas,irqc-<soctype>", "renesas,irqc" as fallback.
6 Examples with soctypes are: 6 Examples with soctypes are:
7 - "renesas,irqc-r8a73a4" (R-Mobile AP6) 7 - "renesas,irqc-r8a73a4" (R-Mobile APE6)
8 - "renesas,irqc-r8a7790" (R-Car H2) 8 - "renesas,irqc-r8a7790" (R-Car H2)
9 - "renesas,irqc-r8a7791" (R-Car M2-W) 9 - "renesas,irqc-r8a7791" (R-Car M2-W)
10 - "renesas,irqc-r8a7792" (R-Car V2H) 10 - "renesas,irqc-r8a7792" (R-Car V2H)
@@ -12,6 +12,7 @@ Required properties:
12 - "renesas,irqc-r8a7794" (R-Car E2) 12 - "renesas,irqc-r8a7794" (R-Car E2)
13- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in 13- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
14 interrupts.txt in this directory 14 interrupts.txt in this directory
15- clocks: Must contain a reference to the functional clock.
15 16
16Optional properties: 17Optional properties:
17 18
@@ -29,4 +30,5 @@ Example:
29 <0 1 IRQ_TYPE_LEVEL_HIGH>, 30 <0 1 IRQ_TYPE_LEVEL_HIGH>,
30 <0 2 IRQ_TYPE_LEVEL_HIGH>, 31 <0 2 IRQ_TYPE_LEVEL_HIGH>,
31 <0 3 IRQ_TYPE_LEVEL_HIGH>; 32 <0 3 IRQ_TYPE_LEVEL_HIGH>;
33 clocks = <&mstp4_clks R8A7790_CLK_IRQC>;
32 }; 34 };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,sti-irq-syscfg.txt b/Documentation/devicetree/bindings/interrupt-controller/st,sti-irq-syscfg.txt
new file mode 100644
index 000000000000..ced6014061a3
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/st,sti-irq-syscfg.txt
@@ -0,0 +1,35 @@
1STMicroelectronics STi System Configuration Controlled IRQs
2-----------------------------------------------------------
3
4On STi based systems; External, CTI (Core Sight), PMU (Performance Management),
5and PL310 L2 Cache IRQs are controlled using System Configuration registers.
6This driver is used to unmask them prior to use.
7
8Required properties:
9- compatible : Should be set to one of:
10 "st,stih415-irq-syscfg"
11 "st,stih416-irq-syscfg"
12 "st,stih407-irq-syscfg"
13 "st,stid127-irq-syscfg"
14- st,syscfg : Phandle to Cortex-A9 IRQ system config registers
15- st,irq-device : Array of IRQs to enable - should be 2 in length
16- st,fiq-device : Array of FIQs to enable - should be 2 in length
17
18Optional properties:
19- st,invert-ext : External IRQs can be inverted at will. This property inverts
20 these IRQs using bitwise logic. A number of defines have been
21 provided for convenience:
22 ST_IRQ_SYSCFG_EXT_1_INV
23 ST_IRQ_SYSCFG_EXT_2_INV
24 ST_IRQ_SYSCFG_EXT_3_INV
25Example:
26
27irq-syscfg {
28 compatible = "st,stih416-irq-syscfg";
29 st,syscfg = <&syscfg_cpu>;
30 st,irq-device = <ST_IRQ_SYSCFG_PMU_0>,
31 <ST_IRQ_SYSCFG_PMU_1>;
32 st,fiq-device = <ST_IRQ_SYSCFG_DISABLED>,
33 <ST_IRQ_SYSCFG_DISABLED>;
34 st,invert-ext = <(ST_IRQ_SYSCFG_EXT_1_INV | ST_IRQ_SYSCFG_EXT_3_INV)>;
35};
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/Documentation/scsi/ncr53c8xx.txt b/Documentation/scsi/ncr53c8xx.txt
index 1d508dcbf859..8586efff1e99 100644
--- a/Documentation/scsi/ncr53c8xx.txt
+++ b/Documentation/scsi/ncr53c8xx.txt
@@ -786,7 +786,6 @@ port address 0x1400.
786 irqm:1 same as initial settings (assumed BIOS settings) 786 irqm:1 same as initial settings (assumed BIOS settings)
787 irqm:2 always totem pole 787 irqm:2 always totem pole
788 irqm:0x10 driver will not use IRQF_SHARED flag when requesting irq 788 irqm:0x10 driver will not use IRQF_SHARED flag when requesting irq
789 irqm:0x20 driver will not use IRQF_DISABLED flag when requesting irq
790 789
791 (Bits 0x10 and 0x20 can be combined with hardware irq mode option) 790 (Bits 0x10 and 0x20 can be combined with hardware irq mode option)
792 791
@@ -1231,30 +1230,6 @@ they only refer to system buffers that are well aligned. So, a work around
1231may only be needed under Linux when a scatter/gather list is not used and 1230may only be needed under Linux when a scatter/gather list is not used and
1232when the SCSI DATA IN phase is reentered after a phase mismatch. 1231when the SCSI DATA IN phase is reentered after a phase mismatch.
1233 1232
123414.5 IRQ sharing problems
1235
1236When an IRQ is shared by devices that are handled by different drivers, it
1237may happen that one driver complains about the request of the IRQ having
1238failed. Inder Linux-2.0, this may be due to one driver having requested the
1239IRQ using the IRQF_DISABLED flag but some other having requested the same IRQ
1240without this flag. Under both Linux-2.0 and linux-2.2, this may be caused by
1241one driver not having requested the IRQ with the IRQF_SHARED flag.
1242
1243By default, the ncr53c8xx and sym53c8xx drivers request IRQs with both the
1244IRQF_DISABLED and the IRQF_SHARED flag under Linux-2.0 and with only the IRQF_SHARED
1245flag under Linux-2.2.
1246
1247Under Linux-2.0, you can disable use of IRQF_DISABLED flag from the boot
1248command line by using the following option:
1249
1250 ncr53c8xx=irqm:0x20 (for the generic ncr53c8xx driver)
1251 sym53c8xx=irqm:0x20 (for the sym53c8xx driver)
1252
1253If this does not fix the problem, then you may want to check how all other
1254drivers are requesting the IRQ and report the problem. Note that if at least
1255a single driver does not request the IRQ with the IRQF_SHARED flag (share IRQ),
1256then the request of the IRQ obviously will not succeed for all the drivers.
1257
125815. SCSI problem troubleshooting 123315. SCSI problem troubleshooting
1259 1234
126015.1 Problem tracking 123515.1 Problem tracking
diff --git a/Documentation/scsi/tmscsim.txt b/Documentation/scsi/tmscsim.txt
index 0810132772a8..0e0322bf0020 100644
--- a/Documentation/scsi/tmscsim.txt
+++ b/Documentation/scsi/tmscsim.txt
@@ -107,10 +107,6 @@ produced errors and started to corrupt my disks. So don't do that! A 37.50
107MHz PCI bus works for me, though, but I don't recommend using higher clocks 107MHz PCI bus works for me, though, but I don't recommend using higher clocks
108than the 33.33 MHz being in the PCI spec. 108than the 33.33 MHz being in the PCI spec.
109 109
110If you want to share the IRQ with another device and the driver refuses to
111do so, you might succeed with changing the DC390_IRQ type in tmscsim.c to
112IRQF_SHARED | IRQF_DISABLED.
113
114 110
1153.Features 1113.Features
116---------- 112----------
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-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index e8627e04e1e6..c8dffcee9736 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -631,6 +631,7 @@ config SOC_IMX6SX
631 631
632config SOC_VF610 632config SOC_VF610
633 bool "Vybrid Family VF610 support" 633 bool "Vybrid Family VF610 support"
634 select IRQ_DOMAIN_HIERARCHY
634 select ARM_GIC 635 select ARM_GIC
635 select PINCTRL_VF610 636 select PINCTRL_VF610
636 select PL310_ERRATA_769419 if CACHE_L2X0 637 select PL310_ERRATA_769419 if CACHE_L2X0
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/arch/mips/loongson/loongson-3/hpet.c b/arch/mips/loongson/loongson-3/hpet.c
index e898d68668a9..5c21cd3bd339 100644
--- a/arch/mips/loongson/loongson-3/hpet.c
+++ b/arch/mips/loongson/loongson-3/hpet.c
@@ -162,7 +162,7 @@ static irqreturn_t hpet_irq_handler(int irq, void *data)
162 162
163static struct irqaction hpet_irq = { 163static struct irqaction hpet_irq = {
164 .handler = hpet_irq_handler, 164 .handler = hpet_irq_handler,
165 .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, 165 .flags = IRQF_NOBALANCING | IRQF_TIMER,
166 .name = "hpet", 166 .name = "hpet",
167}; 167};
168 168
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 2b9440384536..f749df9e15cd 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -405,8 +405,8 @@ static int cpqarray_register_ctlr(int i, struct pci_dev *pdev)
405 goto Enomem4; 405 goto Enomem4;
406 } 406 }
407 hba[i]->access.set_intr_mask(hba[i], 0); 407 hba[i]->access.set_intr_mask(hba[i], 0);
408 if (request_irq(hba[i]->intr, do_ida_intr, 408 if (request_irq(hba[i]->intr, do_ida_intr, IRQF_SHARED,
409 IRQF_DISABLED|IRQF_SHARED, hba[i]->devname, hba[i])) 409 hba[i]->devname, hba[i]))
410 { 410 {
411 printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", 411 printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n",
412 hba[i]->intr, hba[i]->devname); 412 hba[i]->intr, hba[i]->devname);
diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c
index 029bc73de001..11f7982cbdb3 100644
--- a/drivers/bus/omap_l3_noc.c
+++ b/drivers/bus/omap_l3_noc.c
@@ -284,7 +284,7 @@ static int omap_l3_probe(struct platform_device *pdev)
284 */ 284 */
285 l3->debug_irq = platform_get_irq(pdev, 0); 285 l3->debug_irq = platform_get_irq(pdev, 0);
286 ret = devm_request_irq(l3->dev, l3->debug_irq, l3_interrupt_handler, 286 ret = devm_request_irq(l3->dev, l3->debug_irq, l3_interrupt_handler,
287 IRQF_DISABLED, "l3-dbg-irq", l3); 287 0x0, "l3-dbg-irq", l3);
288 if (ret) { 288 if (ret) {
289 dev_err(l3->dev, "request_irq failed for %d\n", 289 dev_err(l3->dev, "request_irq failed for %d\n",
290 l3->debug_irq); 290 l3->debug_irq);
@@ -293,7 +293,7 @@ static int omap_l3_probe(struct platform_device *pdev)
293 293
294 l3->app_irq = platform_get_irq(pdev, 1); 294 l3->app_irq = platform_get_irq(pdev, 1);
295 ret = devm_request_irq(l3->dev, l3->app_irq, l3_interrupt_handler, 295 ret = devm_request_irq(l3->dev, l3->app_irq, l3_interrupt_handler,
296 IRQF_DISABLED, "l3-app-irq", l3); 296 0x0, "l3-app-irq", l3);
297 if (ret) 297 if (ret)
298 dev_err(l3->dev, "request_irq failed for %d\n", l3->app_irq); 298 dev_err(l3->dev, "request_irq failed for %d\n", l3->app_irq);
299 299
diff --git a/drivers/bus/omap_l3_smx.c b/drivers/bus/omap_l3_smx.c
index 597fdaee7315..360a5c0a4ee0 100644
--- a/drivers/bus/omap_l3_smx.c
+++ b/drivers/bus/omap_l3_smx.c
@@ -251,18 +251,16 @@ static int omap3_l3_probe(struct platform_device *pdev)
251 } 251 }
252 252
253 l3->debug_irq = platform_get_irq(pdev, 0); 253 l3->debug_irq = platform_get_irq(pdev, 0);
254 ret = request_irq(l3->debug_irq, omap3_l3_app_irq, 254 ret = request_irq(l3->debug_irq, omap3_l3_app_irq, IRQF_TRIGGER_RISING,
255 IRQF_DISABLED | IRQF_TRIGGER_RISING, 255 "l3-debug-irq", l3);
256 "l3-debug-irq", l3);
257 if (ret) { 256 if (ret) {
258 dev_err(&pdev->dev, "couldn't request debug irq\n"); 257 dev_err(&pdev->dev, "couldn't request debug irq\n");
259 goto err1; 258 goto err1;
260 } 259 }
261 260
262 l3->app_irq = platform_get_irq(pdev, 1); 261 l3->app_irq = platform_get_irq(pdev, 1);
263 ret = request_irq(l3->app_irq, omap3_l3_app_irq, 262 ret = request_irq(l3->app_irq, omap3_l3_app_irq, IRQF_TRIGGER_RISING,
264 IRQF_DISABLED | IRQF_TRIGGER_RISING, 263 "l3-app-irq", l3);
265 "l3-app-irq", l3);
266 if (ret) { 264 if (ret) {
267 dev_err(&pdev->dev, "couldn't request app irq\n"); 265 dev_err(&pdev->dev, "couldn't request app irq\n");
268 goto err2; 266 goto err2;
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index cc79d2a5a8c2..c8d260e33a90 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -110,6 +110,13 @@ config RENESAS_IRQC
110 bool 110 bool
111 select IRQ_DOMAIN 111 select IRQ_DOMAIN
112 112
113config ST_IRQCHIP
114 bool
115 select REGMAP
116 select MFD_SYSCON
117 help
118 Enables SysCfg Controlled IRQs on STi based platforms.
119
113config TB10X_IRQC 120config TB10X_IRQC
114 bool 121 bool
115 select IRQ_DOMAIN 122 select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 42965d2476bb..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
@@ -33,10 +34,12 @@ obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
33obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o 34obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
34obj-$(CONFIG_ARCH_NSPIRE) += irq-zevio.o 35obj-$(CONFIG_ARCH_NSPIRE) += irq-zevio.o
35obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o 36obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o
37obj-$(CONFIG_ST_IRQCHIP) += irq-st.o
36obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o 38obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
37obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o 39obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o
38obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o 40obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o
39obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o 41obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o
42obj-$(CONFIG_SOC_VF610) += irq-vf610-mscm-ir.o
40obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o 43obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o
41obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o 44obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o
42obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o 45obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index 4387dae14e45..daccc8bdbb42 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -38,6 +38,8 @@
38/* Interrupt Controller Registers Map */ 38/* Interrupt Controller Registers Map */
39#define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) 39#define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48)
40#define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C) 40#define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C)
41#define ARMADA_370_XP_INT_FABRIC_MASK_OFFS (0x54)
42#define ARMADA_370_XP_INT_CAUSE_PERF(cpu) (1 << cpu)
41 43
42#define ARMADA_370_XP_INT_CONTROL (0x00) 44#define ARMADA_370_XP_INT_CONTROL (0x00)
43#define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30) 45#define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30)
@@ -56,6 +58,7 @@
56#define ARMADA_370_XP_MAX_PER_CPU_IRQS (28) 58#define ARMADA_370_XP_MAX_PER_CPU_IRQS (28)
57 59
58#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5) 60#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5)
61#define ARMADA_370_XP_FABRIC_IRQ (3)
59 62
60#define IPI_DOORBELL_START (0) 63#define IPI_DOORBELL_START (0)
61#define IPI_DOORBELL_END (8) 64#define IPI_DOORBELL_END (8)
@@ -77,6 +80,17 @@ static DEFINE_MUTEX(msi_used_lock);
77static phys_addr_t msi_doorbell_addr; 80static phys_addr_t msi_doorbell_addr;
78#endif 81#endif
79 82
83static inline bool is_percpu_irq(irq_hw_number_t irq)
84{
85 switch (irq) {
86 case ARMADA_370_XP_TIMER0_PER_CPU_IRQ:
87 case ARMADA_370_XP_FABRIC_IRQ:
88 return true;
89 default:
90 return false;
91 }
92}
93
80/* 94/*
81 * In SMP mode: 95 * In SMP mode:
82 * For shared global interrupts, mask/unmask global enable bit 96 * For shared global interrupts, mask/unmask global enable bit
@@ -86,7 +100,7 @@ static void armada_370_xp_irq_mask(struct irq_data *d)
86{ 100{
87 irq_hw_number_t hwirq = irqd_to_hwirq(d); 101 irq_hw_number_t hwirq = irqd_to_hwirq(d);
88 102
89 if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) 103 if (!is_percpu_irq(hwirq))
90 writel(hwirq, main_int_base + 104 writel(hwirq, main_int_base +
91 ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS); 105 ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS);
92 else 106 else
@@ -98,7 +112,7 @@ static void armada_370_xp_irq_unmask(struct irq_data *d)
98{ 112{
99 irq_hw_number_t hwirq = irqd_to_hwirq(d); 113 irq_hw_number_t hwirq = irqd_to_hwirq(d);
100 114
101 if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) 115 if (!is_percpu_irq(hwirq))
102 writel(hwirq, main_int_base + 116 writel(hwirq, main_int_base +
103 ARMADA_370_XP_INT_SET_ENABLE_OFFS); 117 ARMADA_370_XP_INT_SET_ENABLE_OFFS);
104 else 118 else
@@ -281,20 +295,21 @@ static struct irq_chip armada_370_xp_irq_chip = {
281#ifdef CONFIG_SMP 295#ifdef CONFIG_SMP
282 .irq_set_affinity = armada_xp_set_affinity, 296 .irq_set_affinity = armada_xp_set_affinity,
283#endif 297#endif
298 .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
284}; 299};
285 300
286static int armada_370_xp_mpic_irq_map(struct irq_domain *h, 301static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
287 unsigned int virq, irq_hw_number_t hw) 302 unsigned int virq, irq_hw_number_t hw)
288{ 303{
289 armada_370_xp_irq_mask(irq_get_irq_data(virq)); 304 armada_370_xp_irq_mask(irq_get_irq_data(virq));
290 if (hw != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) 305 if (!is_percpu_irq(hw))
291 writel(hw, per_cpu_int_base + 306 writel(hw, per_cpu_int_base +
292 ARMADA_370_XP_INT_CLEAR_MASK_OFFS); 307 ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
293 else 308 else
294 writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); 309 writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS);
295 irq_set_status_flags(virq, IRQ_LEVEL); 310 irq_set_status_flags(virq, IRQ_LEVEL);
296 311
297 if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) { 312 if (is_percpu_irq(hw)) {
298 irq_set_percpu_devid(virq); 313 irq_set_percpu_devid(virq);
299 irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip, 314 irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip,
300 handle_percpu_devid_irq); 315 handle_percpu_devid_irq);
@@ -308,28 +323,6 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
308 return 0; 323 return 0;
309} 324}
310 325
311#ifdef CONFIG_SMP
312static void armada_mpic_send_doorbell(const struct cpumask *mask,
313 unsigned int irq)
314{
315 int cpu;
316 unsigned long map = 0;
317
318 /* Convert our logical CPU mask into a physical one. */
319 for_each_cpu(cpu, mask)
320 map |= 1 << cpu_logical_map(cpu);
321
322 /*
323 * Ensure that stores to Normal memory are visible to the
324 * other CPUs before issuing the IPI.
325 */
326 dsb();
327
328 /* submit softirq */
329 writel((map << 8) | irq, main_int_base +
330 ARMADA_370_XP_SW_TRIG_INT_OFFS);
331}
332
333static void armada_xp_mpic_smp_cpu_init(void) 326static void armada_xp_mpic_smp_cpu_init(void)
334{ 327{
335 u32 control; 328 u32 control;
@@ -352,11 +345,44 @@ static void armada_xp_mpic_smp_cpu_init(void)
352 writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); 345 writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
353} 346}
354 347
348static void armada_xp_mpic_perf_init(void)
349{
350 unsigned long cpuid = cpu_logical_map(smp_processor_id());
351
352 /* Enable Performance Counter Overflow interrupts */
353 writel(ARMADA_370_XP_INT_CAUSE_PERF(cpuid),
354 per_cpu_int_base + ARMADA_370_XP_INT_FABRIC_MASK_OFFS);
355}
356
357#ifdef CONFIG_SMP
358static void armada_mpic_send_doorbell(const struct cpumask *mask,
359 unsigned int irq)
360{
361 int cpu;
362 unsigned long map = 0;
363
364 /* Convert our logical CPU mask into a physical one. */
365 for_each_cpu(cpu, mask)
366 map |= 1 << cpu_logical_map(cpu);
367
368 /*
369 * Ensure that stores to Normal memory are visible to the
370 * other CPUs before issuing the IPI.
371 */
372 dsb();
373
374 /* submit softirq */
375 writel((map << 8) | irq, main_int_base +
376 ARMADA_370_XP_SW_TRIG_INT_OFFS);
377}
378
355static int armada_xp_mpic_secondary_init(struct notifier_block *nfb, 379static int armada_xp_mpic_secondary_init(struct notifier_block *nfb,
356 unsigned long action, void *hcpu) 380 unsigned long action, void *hcpu)
357{ 381{
358 if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) 382 if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) {
383 armada_xp_mpic_perf_init();
359 armada_xp_mpic_smp_cpu_init(); 384 armada_xp_mpic_smp_cpu_init();
385 }
360 386
361 return NOTIFY_OK; 387 return NOTIFY_OK;
362} 388}
@@ -369,8 +395,10 @@ static struct notifier_block armada_370_xp_mpic_cpu_notifier = {
369static int mpic_cascaded_secondary_init(struct notifier_block *nfb, 395static int mpic_cascaded_secondary_init(struct notifier_block *nfb,
370 unsigned long action, void *hcpu) 396 unsigned long action, void *hcpu)
371{ 397{
372 if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) 398 if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) {
399 armada_xp_mpic_perf_init();
373 enable_percpu_irq(parent_irq, IRQ_TYPE_NONE); 400 enable_percpu_irq(parent_irq, IRQ_TYPE_NONE);
401 }
374 402
375 return NOTIFY_OK; 403 return NOTIFY_OK;
376} 404}
@@ -379,7 +407,6 @@ static struct notifier_block mpic_cascaded_cpu_notifier = {
379 .notifier_call = mpic_cascaded_secondary_init, 407 .notifier_call = mpic_cascaded_secondary_init,
380 .priority = 100, 408 .priority = 100,
381}; 409};
382
383#endif /* CONFIG_SMP */ 410#endif /* CONFIG_SMP */
384 411
385static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { 412static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
@@ -588,9 +615,9 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
588 615
589 BUG_ON(!armada_370_xp_mpic_domain); 616 BUG_ON(!armada_370_xp_mpic_domain);
590 617
591#ifdef CONFIG_SMP 618 /* Setup for the boot CPU */
619 armada_xp_mpic_perf_init();
592 armada_xp_mpic_smp_cpu_init(); 620 armada_xp_mpic_smp_cpu_init();
593#endif
594 621
595 armada_370_xp_msi_init(node, main_int_res.start); 622 armada_370_xp_msi_init(node, main_int_res.start);
596 623
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-digicolor.c b/drivers/irqchip/irq-digicolor.c
index 930a2a2fac7f..3cbc658afe27 100644
--- a/drivers/irqchip/irq-digicolor.c
+++ b/drivers/irqchip/irq-digicolor.c
@@ -55,8 +55,8 @@ static void __exception_irq_entry digicolor_handle_irq(struct pt_regs *regs)
55 } while (1); 55 } while (1);
56} 56}
57 57
58static void digicolor_set_gc(void __iomem *reg_base, unsigned irq_base, 58static void __init digicolor_set_gc(void __iomem *reg_base, unsigned irq_base,
59 unsigned en_reg, unsigned ack_reg) 59 unsigned en_reg, unsigned ack_reg)
60{ 60{
61 struct irq_chip_generic *gc; 61 struct irq_chip_generic *gc;
62 62
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index fd8850def1b8..4f2fb62e6f37 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -195,6 +195,19 @@ static void gic_enable_redist(bool enable)
195/* 195/*
196 * Routines to disable, enable, EOI and route interrupts 196 * Routines to disable, enable, EOI and route interrupts
197 */ 197 */
198static int gic_peek_irq(struct irq_data *d, u32 offset)
199{
200 u32 mask = 1 << (gic_irq(d) % 32);
201 void __iomem *base;
202
203 if (gic_irq_in_rdist(d))
204 base = gic_data_rdist_sgi_base();
205 else
206 base = gic_data.dist_base;
207
208 return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask);
209}
210
198static void gic_poke_irq(struct irq_data *d, u32 offset) 211static void gic_poke_irq(struct irq_data *d, u32 offset)
199{ 212{
200 u32 mask = 1 << (gic_irq(d) % 32); 213 u32 mask = 1 << (gic_irq(d) % 32);
@@ -223,6 +236,61 @@ static void gic_unmask_irq(struct irq_data *d)
223 gic_poke_irq(d, GICD_ISENABLER); 236 gic_poke_irq(d, GICD_ISENABLER);
224} 237}
225 238
239static int gic_irq_set_irqchip_state(struct irq_data *d,
240 enum irqchip_irq_state which, bool val)
241{
242 u32 reg;
243
244 if (d->hwirq >= gic_data.irq_nr) /* PPI/SPI only */
245 return -EINVAL;
246
247 switch (which) {
248 case IRQCHIP_STATE_PENDING:
249 reg = val ? GICD_ISPENDR : GICD_ICPENDR;
250 break;
251
252 case IRQCHIP_STATE_ACTIVE:
253 reg = val ? GICD_ISACTIVER : GICD_ICACTIVER;
254 break;
255
256 case IRQCHIP_STATE_MASKED:
257 reg = val ? GICD_ICENABLER : GICD_ISENABLER;
258 break;
259
260 default:
261 return -EINVAL;
262 }
263
264 gic_poke_irq(d, reg);
265 return 0;
266}
267
268static int gic_irq_get_irqchip_state(struct irq_data *d,
269 enum irqchip_irq_state which, bool *val)
270{
271 if (d->hwirq >= gic_data.irq_nr) /* PPI/SPI only */
272 return -EINVAL;
273
274 switch (which) {
275 case IRQCHIP_STATE_PENDING:
276 *val = gic_peek_irq(d, GICD_ISPENDR);
277 break;
278
279 case IRQCHIP_STATE_ACTIVE:
280 *val = gic_peek_irq(d, GICD_ISACTIVER);
281 break;
282
283 case IRQCHIP_STATE_MASKED:
284 *val = !gic_peek_irq(d, GICD_ISENABLER);
285 break;
286
287 default:
288 return -EINVAL;
289 }
290
291 return 0;
292}
293
226static void gic_eoi_irq(struct irq_data *d) 294static void gic_eoi_irq(struct irq_data *d)
227{ 295{
228 gic_write_eoir(gic_irq(d)); 296 gic_write_eoir(gic_irq(d));
@@ -418,19 +486,6 @@ static void gic_cpu_init(void)
418} 486}
419 487
420#ifdef CONFIG_SMP 488#ifdef CONFIG_SMP
421static int gic_peek_irq(struct irq_data *d, u32 offset)
422{
423 u32 mask = 1 << (gic_irq(d) % 32);
424 void __iomem *base;
425
426 if (gic_irq_in_rdist(d))
427 base = gic_data_rdist_sgi_base();
428 else
429 base = gic_data.dist_base;
430
431 return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask);
432}
433
434static int gic_secondary_init(struct notifier_block *nfb, 489static int gic_secondary_init(struct notifier_block *nfb,
435 unsigned long action, void *hcpu) 490 unsigned long action, void *hcpu)
436{ 491{
@@ -601,6 +656,8 @@ static struct irq_chip gic_chip = {
601 .irq_eoi = gic_eoi_irq, 656 .irq_eoi = gic_eoi_irq,
602 .irq_set_type = gic_set_type, 657 .irq_set_type = gic_set_type,
603 .irq_set_affinity = gic_set_affinity, 658 .irq_set_affinity = gic_set_affinity,
659 .irq_get_irqchip_state = gic_irq_get_irqchip_state,
660 .irq_set_irqchip_state = gic_irq_set_irqchip_state,
604}; 661};
605 662
606#define GIC_ID_NR (1U << gic_data.rdists.id_bits) 663#define GIC_ID_NR (1U << gic_data.rdists.id_bits)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 471e1cdc1933..a6ce3476834e 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -151,13 +151,24 @@ static inline unsigned int gic_irq(struct irq_data *d)
151/* 151/*
152 * Routines to acknowledge, disable and enable interrupts 152 * Routines to acknowledge, disable and enable interrupts
153 */ 153 */
154static void gic_mask_irq(struct irq_data *d) 154static void gic_poke_irq(struct irq_data *d, u32 offset)
155{ 155{
156 u32 mask = 1 << (gic_irq(d) % 32); 156 u32 mask = 1 << (gic_irq(d) % 32);
157 writel_relaxed(mask, gic_dist_base(d) + offset + (gic_irq(d) / 32) * 4);
158}
159
160static int gic_peek_irq(struct irq_data *d, u32 offset)
161{
162 u32 mask = 1 << (gic_irq(d) % 32);
163 return !!(readl_relaxed(gic_dist_base(d) + offset + (gic_irq(d) / 32) * 4) & mask);
164}
165
166static void gic_mask_irq(struct irq_data *d)
167{
157 unsigned long flags; 168 unsigned long flags;
158 169
159 raw_spin_lock_irqsave(&irq_controller_lock, flags); 170 raw_spin_lock_irqsave(&irq_controller_lock, flags);
160 writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4); 171 gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR);
161 if (gic_arch_extn.irq_mask) 172 if (gic_arch_extn.irq_mask)
162 gic_arch_extn.irq_mask(d); 173 gic_arch_extn.irq_mask(d);
163 raw_spin_unlock_irqrestore(&irq_controller_lock, flags); 174 raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
@@ -165,13 +176,12 @@ static void gic_mask_irq(struct irq_data *d)
165 176
166static void gic_unmask_irq(struct irq_data *d) 177static void gic_unmask_irq(struct irq_data *d)
167{ 178{
168 u32 mask = 1 << (gic_irq(d) % 32);
169 unsigned long flags; 179 unsigned long flags;
170 180
171 raw_spin_lock_irqsave(&irq_controller_lock, flags); 181 raw_spin_lock_irqsave(&irq_controller_lock, flags);
172 if (gic_arch_extn.irq_unmask) 182 if (gic_arch_extn.irq_unmask)
173 gic_arch_extn.irq_unmask(d); 183 gic_arch_extn.irq_unmask(d);
174 writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4); 184 gic_poke_irq(d, GIC_DIST_ENABLE_SET);
175 raw_spin_unlock_irqrestore(&irq_controller_lock, flags); 185 raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
176} 186}
177 187
@@ -186,6 +196,55 @@ static void gic_eoi_irq(struct irq_data *d)
186 writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); 196 writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
187} 197}
188 198
199static int gic_irq_set_irqchip_state(struct irq_data *d,
200 enum irqchip_irq_state which, bool val)
201{
202 u32 reg;
203
204 switch (which) {
205 case IRQCHIP_STATE_PENDING:
206 reg = val ? GIC_DIST_PENDING_SET : GIC_DIST_PENDING_CLEAR;
207 break;
208
209 case IRQCHIP_STATE_ACTIVE:
210 reg = val ? GIC_DIST_ACTIVE_SET : GIC_DIST_ACTIVE_CLEAR;
211 break;
212
213 case IRQCHIP_STATE_MASKED:
214 reg = val ? GIC_DIST_ENABLE_CLEAR : GIC_DIST_ENABLE_SET;
215 break;
216
217 default:
218 return -EINVAL;
219 }
220
221 gic_poke_irq(d, reg);
222 return 0;
223}
224
225static int gic_irq_get_irqchip_state(struct irq_data *d,
226 enum irqchip_irq_state which, bool *val)
227{
228 switch (which) {
229 case IRQCHIP_STATE_PENDING:
230 *val = gic_peek_irq(d, GIC_DIST_PENDING_SET);
231 break;
232
233 case IRQCHIP_STATE_ACTIVE:
234 *val = gic_peek_irq(d, GIC_DIST_ACTIVE_SET);
235 break;
236
237 case IRQCHIP_STATE_MASKED:
238 *val = !gic_peek_irq(d, GIC_DIST_ENABLE_SET);
239 break;
240
241 default:
242 return -EINVAL;
243 }
244
245 return 0;
246}
247
189static int gic_set_type(struct irq_data *d, unsigned int type) 248static int gic_set_type(struct irq_data *d, unsigned int type)
190{ 249{
191 void __iomem *base = gic_dist_base(d); 250 void __iomem *base = gic_dist_base(d);
@@ -329,6 +388,8 @@ static struct irq_chip gic_chip = {
329 .irq_set_affinity = gic_set_affinity, 388 .irq_set_affinity = gic_set_affinity,
330#endif 389#endif
331 .irq_set_wake = gic_set_wake, 390 .irq_set_wake = gic_set_wake,
391 .irq_get_irqchip_state = gic_irq_get_irqchip_state,
392 .irq_set_irqchip_state = gic_irq_set_irqchip_state,
332}; 393};
333 394
334void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) 395void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
@@ -353,7 +414,7 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)
353 break; 414 break;
354 } 415 }
355 416
356 if (!mask) 417 if (!mask && num_possible_cpus() > 1)
357 pr_crit("GIC CPU mask not found - kernel will fail to boot.\n"); 418 pr_crit("GIC CPU mask not found - kernel will fail to boot.\n");
358 419
359 return mask; 420 return mask;
@@ -802,15 +863,12 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
802 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,
803 handle_fasteoi_irq, NULL, NULL); 864 handle_fasteoi_irq, NULL, NULL);
804 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 865 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
805
806 gic_routable_irq_domain_ops->map(d, irq, hw);
807 } 866 }
808 return 0; 867 return 0;
809} 868}
810 869
811static 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)
812{ 871{
813 gic_routable_irq_domain_ops->unmap(d, irq);
814} 872}
815 873
816static int gic_irq_domain_xlate(struct irq_domain *d, 874static int gic_irq_domain_xlate(struct irq_domain *d,
@@ -829,16 +887,8 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
829 *out_hwirq = intspec[1] + 16; 887 *out_hwirq = intspec[1] + 16;
830 888
831 /* 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 */
832 if (!intspec[0]) { 890 if (!intspec[0])
833 ret = gic_routable_irq_domain_ops->xlate(d, controller, 891 *out_hwirq += 16;
834 intspec,
835 intsize,
836 out_hwirq,
837 out_type);
838
839 if (IS_ERR_VALUE(ret))
840 return ret;
841 }
842 892
843 *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; 893 *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
844 894
@@ -895,37 +945,11 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
895 .xlate = gic_irq_domain_xlate, 945 .xlate = gic_irq_domain_xlate,
896}; 946};
897 947
898/* Default functions for routable irq domain */ 948void gic_set_irqchip_flags(unsigned long flags)
899static int gic_routable_irq_domain_map(struct irq_domain *d, unsigned int irq,
900 irq_hw_number_t hw)
901{ 949{
902 return 0; 950 gic_chip.flags |= flags;
903} 951}
904 952
905static void gic_routable_irq_domain_unmap(struct irq_domain *d,
906 unsigned int irq)
907{
908}
909
910static int gic_routable_irq_domain_xlate(struct irq_domain *d,
911 struct device_node *controller,
912 const u32 *intspec, unsigned int intsize,
913 unsigned long *out_hwirq,
914 unsigned int *out_type)
915{
916 *out_hwirq += 16;
917 return 0;
918}
919
920static const struct irq_domain_ops gic_default_routable_irq_domain_ops = {
921 .map = gic_routable_irq_domain_map,
922 .unmap = gic_routable_irq_domain_unmap,
923 .xlate = gic_routable_irq_domain_xlate,
924};
925
926const struct irq_domain_ops *gic_routable_irq_domain_ops =
927 &gic_default_routable_irq_domain_ops;
928
929void __init gic_init_bases(unsigned int gic_nr, int irq_start, 953void __init gic_init_bases(unsigned int gic_nr, int irq_start,
930 void __iomem *dist_base, void __iomem *cpu_base, 954 void __iomem *dist_base, void __iomem *cpu_base,
931 u32 percpu_offset, struct device_node *node) 955 u32 percpu_offset, struct device_node *node)
@@ -933,7 +957,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
933 irq_hw_number_t hwirq_base; 957 irq_hw_number_t hwirq_base;
934 struct gic_chip_data *gic; 958 struct gic_chip_data *gic;
935 int gic_irqs, irq_base, i; 959 int gic_irqs, irq_base, i;
936 int nr_routable_irqs;
937 960
938 BUG_ON(gic_nr >= MAX_GIC_NR); 961 BUG_ON(gic_nr >= MAX_GIC_NR);
939 962
@@ -989,15 +1012,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
989 gic->gic_irqs = gic_irqs; 1012 gic->gic_irqs = gic_irqs;
990 1013
991 if (node) { /* DT case */ 1014 if (node) { /* DT case */
992 const struct irq_domain_ops *ops = &gic_irq_domain_hierarchy_ops; 1015 gic->domain = irq_domain_add_linear(node, gic_irqs,
993 1016 &gic_irq_domain_hierarchy_ops,
994 if (!of_property_read_u32(node, "arm,routable-irqs", 1017 gic);
995 &nr_routable_irqs)) {
996 ops = &gic_irq_domain_ops;
997 gic_irqs = nr_routable_irqs;
998 }
999
1000 gic->domain = irq_domain_add_linear(node, gic_irqs, ops, gic);
1001 } else { /* Non-DT case */ 1018 } else { /* Non-DT case */
1002 /* 1019 /*
1003 * For primary GICs, skip over SGIs. 1020 * For primary GICs, skip over SGIs.
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 9acdc080e7ec..f2d269bca789 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -166,6 +166,27 @@ cycle_t gic_read_compare(void)
166 166
167 return (((cycle_t) hi) << 32) + lo; 167 return (((cycle_t) hi) << 32) + lo;
168} 168}
169
170void gic_start_count(void)
171{
172 u32 gicconfig;
173
174 /* Start the counter */
175 gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
176 gicconfig &= ~(1 << GIC_SH_CONFIG_COUNTSTOP_SHF);
177 gic_write(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
178}
179
180void gic_stop_count(void)
181{
182 u32 gicconfig;
183
184 /* Stop the counter */
185 gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
186 gicconfig |= 1 << GIC_SH_CONFIG_COUNTSTOP_SHF;
187 gic_write(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
188}
189
169#endif 190#endif
170 191
171static bool gic_local_irq_is_routable(int intr) 192static bool gic_local_irq_is_routable(int intr)
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c
index 384e6ed61d7c..cdf80b7794cd 100644
--- a/drivers/irqchip/irq-renesas-irqc.c
+++ b/drivers/irqchip/irq-renesas-irqc.c
@@ -17,6 +17,7 @@
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19 19
20#include <linux/clk.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/spinlock.h> 23#include <linux/spinlock.h>
@@ -29,15 +30,26 @@
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/module.h> 31#include <linux/module.h>
31#include <linux/platform_data/irq-renesas-irqc.h> 32#include <linux/platform_data/irq-renesas-irqc.h>
33#include <linux/pm_runtime.h>
32 34
33#define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */ 35#define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */
34 36
35#define IRQC_REQ_STS 0x00 37#define IRQC_REQ_STS 0x00 /* Interrupt Request Status Register */
36#define IRQC_EN_STS 0x04 38#define IRQC_EN_STS 0x04 /* Interrupt Enable Status Register */
37#define IRQC_EN_SET 0x08 39#define IRQC_EN_SET 0x08 /* Interrupt Enable Set Register */
38#define IRQC_INT_CPU_BASE(n) (0x000 + ((n) * 0x10)) 40#define IRQC_INT_CPU_BASE(n) (0x000 + ((n) * 0x10))
39#define DETECT_STATUS 0x100 41 /* SYS-CPU vs. RT-CPU */
42#define DETECT_STATUS 0x100 /* IRQn Detect Status Register */
43#define MONITOR 0x104 /* IRQn Signal Level Monitor Register */
44#define HLVL_STS 0x108 /* IRQn High Level Detect Status Register */
45#define LLVL_STS 0x10c /* IRQn Low Level Detect Status Register */
46#define S_R_EDGE_STS 0x110 /* IRQn Sync Rising Edge Detect Status Reg. */
47#define S_F_EDGE_STS 0x114 /* IRQn Sync Falling Edge Detect Status Reg. */
48#define A_R_EDGE_STS 0x118 /* IRQn Async Rising Edge Detect Status Reg. */
49#define A_F_EDGE_STS 0x11c /* IRQn Async Falling Edge Detect Status Reg. */
50#define CHTEN_STS 0x120 /* Chattering Reduction Status Register */
40#define IRQC_CONFIG(n) (0x180 + ((n) * 0x04)) 51#define IRQC_CONFIG(n) (0x180 + ((n) * 0x04))
52 /* IRQn Configuration Register */
41 53
42struct irqc_irq { 54struct irqc_irq {
43 int hw_irq; 55 int hw_irq;
@@ -55,6 +67,7 @@ struct irqc_priv {
55 struct platform_device *pdev; 67 struct platform_device *pdev;
56 struct irq_chip irq_chip; 68 struct irq_chip irq_chip;
57 struct irq_domain *irq_domain; 69 struct irq_domain *irq_domain;
70 struct clk *clk;
58}; 71};
59 72
60static void irqc_dbg(struct irqc_irq *i, char *str) 73static void irqc_dbg(struct irqc_irq *i, char *str)
@@ -94,7 +107,7 @@ static int irqc_irq_set_type(struct irq_data *d, unsigned int type)
94 struct irqc_priv *p = irq_data_get_irq_chip_data(d); 107 struct irqc_priv *p = irq_data_get_irq_chip_data(d);
95 int hw_irq = irqd_to_hwirq(d); 108 int hw_irq = irqd_to_hwirq(d);
96 unsigned char value = irqc_sense[type & IRQ_TYPE_SENSE_MASK]; 109 unsigned char value = irqc_sense[type & IRQ_TYPE_SENSE_MASK];
97 unsigned long tmp; 110 u32 tmp;
98 111
99 irqc_dbg(&p->irq[hw_irq], "sense"); 112 irqc_dbg(&p->irq[hw_irq], "sense");
100 113
@@ -108,11 +121,26 @@ static int irqc_irq_set_type(struct irq_data *d, unsigned int type)
108 return 0; 121 return 0;
109} 122}
110 123
124static int irqc_irq_set_wake(struct irq_data *d, unsigned int on)
125{
126 struct irqc_priv *p = irq_data_get_irq_chip_data(d);
127
128 if (!p->clk)
129 return 0;
130
131 if (on)
132 clk_enable(p->clk);
133 else
134 clk_disable(p->clk);
135
136 return 0;
137}
138
111static irqreturn_t irqc_irq_handler(int irq, void *dev_id) 139static irqreturn_t irqc_irq_handler(int irq, void *dev_id)
112{ 140{
113 struct irqc_irq *i = dev_id; 141 struct irqc_irq *i = dev_id;
114 struct irqc_priv *p = i->p; 142 struct irqc_priv *p = i->p;
115 unsigned long bit = BIT(i->hw_irq); 143 u32 bit = BIT(i->hw_irq);
116 144
117 irqc_dbg(i, "demux1"); 145 irqc_dbg(i, "demux1");
118 146
@@ -170,6 +198,15 @@ static int irqc_probe(struct platform_device *pdev)
170 p->pdev = pdev; 198 p->pdev = pdev;
171 platform_set_drvdata(pdev, p); 199 platform_set_drvdata(pdev, p);
172 200
201 p->clk = devm_clk_get(&pdev->dev, NULL);
202 if (IS_ERR(p->clk)) {
203 dev_warn(&pdev->dev, "unable to get clock\n");
204 p->clk = NULL;
205 }
206
207 pm_runtime_enable(&pdev->dev);
208 pm_runtime_get_sync(&pdev->dev);
209
173 /* get hold of manadatory IOMEM */ 210 /* get hold of manadatory IOMEM */
174 io = platform_get_resource(pdev, IORESOURCE_MEM, 0); 211 io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
175 if (!io) { 212 if (!io) {
@@ -210,7 +247,8 @@ static int irqc_probe(struct platform_device *pdev)
210 irq_chip->irq_mask = irqc_irq_disable; 247 irq_chip->irq_mask = irqc_irq_disable;
211 irq_chip->irq_unmask = irqc_irq_enable; 248 irq_chip->irq_unmask = irqc_irq_enable;
212 irq_chip->irq_set_type = irqc_irq_set_type; 249 irq_chip->irq_set_type = irqc_irq_set_type;
213 irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; 250 irq_chip->irq_set_wake = irqc_irq_set_wake;
251 irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND;
214 252
215 p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, 253 p->irq_domain = irq_domain_add_simple(pdev->dev.of_node,
216 p->number_of_irqs, 254 p->number_of_irqs,
@@ -250,6 +288,8 @@ err3:
250err2: 288err2:
251 iounmap(p->iomem); 289 iounmap(p->iomem);
252err1: 290err1:
291 pm_runtime_put(&pdev->dev);
292 pm_runtime_disable(&pdev->dev);
253 kfree(p); 293 kfree(p);
254err0: 294err0:
255 return ret; 295 return ret;
@@ -265,6 +305,8 @@ static int irqc_remove(struct platform_device *pdev)
265 305
266 irq_domain_remove(p->irq_domain); 306 irq_domain_remove(p->irq_domain);
267 iounmap(p->iomem); 307 iounmap(p->iomem);
308 pm_runtime_put(&pdev->dev);
309 pm_runtime_disable(&pdev->dev);
268 kfree(p); 310 kfree(p);
269 return 0; 311 return 0;
270} 312}
diff --git a/drivers/irqchip/irq-st.c b/drivers/irqchip/irq-st.c
new file mode 100644
index 000000000000..9af48a85c16f
--- /dev/null
+++ b/drivers/irqchip/irq-st.c
@@ -0,0 +1,206 @@
1/*
2 * Copyright (C) 2014 STMicroelectronics – All Rights Reserved
3 *
4 * Author: Lee Jones <lee.jones@linaro.org>
5 *
6 * This is a re-write of Christophe Kerello's PMU driver.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <dt-bindings/interrupt-controller/irq-st.h>
14#include <linux/err.h>
15#include <linux/mfd/syscon.h>
16#include <linux/of_device.h>
17#include <linux/platform_device.h>
18#include <linux/regmap.h>
19#include <linux/slab.h>
20
21#define STIH415_SYSCFG_642 0x0a8
22#define STIH416_SYSCFG_7543 0x87c
23#define STIH407_SYSCFG_5102 0x198
24#define STID127_SYSCFG_734 0x088
25
26#define ST_A9_IRQ_MASK 0x001FFFFF
27#define ST_A9_IRQ_MAX_CHANS 2
28
29#define ST_A9_IRQ_EN_CTI_0 BIT(0)
30#define ST_A9_IRQ_EN_CTI_1 BIT(1)
31#define ST_A9_IRQ_EN_PMU_0 BIT(2)
32#define ST_A9_IRQ_EN_PMU_1 BIT(3)
33#define ST_A9_IRQ_EN_PL310_L2 BIT(4)
34#define ST_A9_IRQ_EN_EXT_0 BIT(5)
35#define ST_A9_IRQ_EN_EXT_1 BIT(6)
36#define ST_A9_IRQ_EN_EXT_2 BIT(7)
37
38#define ST_A9_FIQ_N_SEL(dev, chan) (dev << (8 + (chan * 3)))
39#define ST_A9_IRQ_N_SEL(dev, chan) (dev << (14 + (chan * 3)))
40#define ST_A9_EXTIRQ_INV_SEL(dev) (dev << 20)
41
42struct st_irq_syscfg {
43 struct regmap *regmap;
44 unsigned int syscfg;
45 unsigned int config;
46 bool ext_inverted;
47};
48
49static const struct of_device_id st_irq_syscfg_match[] = {
50 {
51 .compatible = "st,stih415-irq-syscfg",
52 .data = (void *)STIH415_SYSCFG_642,
53 },
54 {
55 .compatible = "st,stih416-irq-syscfg",
56 .data = (void *)STIH416_SYSCFG_7543,
57 },
58 {
59 .compatible = "st,stih407-irq-syscfg",
60 .data = (void *)STIH407_SYSCFG_5102,
61 },
62 {
63 .compatible = "st,stid127-irq-syscfg",
64 .data = (void *)STID127_SYSCFG_734,
65 },
66 {}
67};
68
69static int st_irq_xlate(struct platform_device *pdev,
70 int device, int channel, bool irq)
71{
72 struct st_irq_syscfg *ddata = dev_get_drvdata(&pdev->dev);
73
74 /* Set the device enable bit. */
75 switch (device) {
76 case ST_IRQ_SYSCFG_EXT_0:
77 ddata->config |= ST_A9_IRQ_EN_EXT_0;
78 break;
79 case ST_IRQ_SYSCFG_EXT_1:
80 ddata->config |= ST_A9_IRQ_EN_EXT_1;
81 break;
82 case ST_IRQ_SYSCFG_EXT_2:
83 ddata->config |= ST_A9_IRQ_EN_EXT_2;
84 break;
85 case ST_IRQ_SYSCFG_CTI_0:
86 ddata->config |= ST_A9_IRQ_EN_CTI_0;
87 break;
88 case ST_IRQ_SYSCFG_CTI_1:
89 ddata->config |= ST_A9_IRQ_EN_CTI_1;
90 break;
91 case ST_IRQ_SYSCFG_PMU_0:
92 ddata->config |= ST_A9_IRQ_EN_PMU_0;
93 break;
94 case ST_IRQ_SYSCFG_PMU_1:
95 ddata->config |= ST_A9_IRQ_EN_PMU_1;
96 break;
97 case ST_IRQ_SYSCFG_pl310_L2:
98 ddata->config |= ST_A9_IRQ_EN_PL310_L2;
99 break;
100 case ST_IRQ_SYSCFG_DISABLED:
101 return 0;
102 default:
103 dev_err(&pdev->dev, "Unrecognised device %d\n", device);
104 return -EINVAL;
105 }
106
107 /* Select IRQ/FIQ channel for device. */
108 ddata->config |= irq ?
109 ST_A9_IRQ_N_SEL(device, channel) :
110 ST_A9_FIQ_N_SEL(device, channel);
111
112 return 0;
113}
114
115static int st_irq_syscfg_enable(struct platform_device *pdev)
116{
117 struct device_node *np = pdev->dev.of_node;
118 struct st_irq_syscfg *ddata = dev_get_drvdata(&pdev->dev);
119 int channels, ret, i;
120 u32 device, invert;
121
122 channels = of_property_count_u32_elems(np, "st,irq-device");
123 if (channels != ST_A9_IRQ_MAX_CHANS) {
124 dev_err(&pdev->dev, "st,enable-irq-device must have 2 elems\n");
125 return -EINVAL;
126 }
127
128 channels = of_property_count_u32_elems(np, "st,fiq-device");
129 if (channels != ST_A9_IRQ_MAX_CHANS) {
130 dev_err(&pdev->dev, "st,enable-fiq-device must have 2 elems\n");
131 return -EINVAL;
132 }
133
134 for (i = 0; i < ST_A9_IRQ_MAX_CHANS; i++) {
135 of_property_read_u32_index(np, "st,irq-device", i, &device);
136
137 ret = st_irq_xlate(pdev, device, i, true);
138 if (ret)
139 return ret;
140
141 of_property_read_u32_index(np, "st,fiq-device", i, &device);
142
143 ret = st_irq_xlate(pdev, device, i, false);
144 if (ret)
145 return ret;
146 }
147
148 /* External IRQs may be inverted. */
149 of_property_read_u32(np, "st,invert-ext", &invert);
150 ddata->config |= ST_A9_EXTIRQ_INV_SEL(invert);
151
152 return regmap_update_bits(ddata->regmap, ddata->syscfg,
153 ST_A9_IRQ_MASK, ddata->config);
154}
155
156static int st_irq_syscfg_probe(struct platform_device *pdev)
157{
158 struct device_node *np = pdev->dev.of_node;
159 const struct of_device_id *match;
160 struct st_irq_syscfg *ddata;
161
162 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
163 if (!ddata)
164 return -ENOMEM;
165
166 match = of_match_device(st_irq_syscfg_match, &pdev->dev);
167 if (!match)
168 return -ENODEV;
169
170 ddata->syscfg = (unsigned int)match->data;
171
172 ddata->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
173 if (IS_ERR(ddata->regmap)) {
174 dev_err(&pdev->dev, "syscfg phandle missing\n");
175 return PTR_ERR(ddata->regmap);
176 }
177
178 dev_set_drvdata(&pdev->dev, ddata);
179
180 return st_irq_syscfg_enable(pdev);
181}
182
183static int st_irq_syscfg_resume(struct device *dev)
184{
185 struct st_irq_syscfg *ddata = dev_get_drvdata(dev);
186
187 return regmap_update_bits(ddata->regmap, ddata->syscfg,
188 ST_A9_IRQ_MASK, ddata->config);
189}
190
191static SIMPLE_DEV_PM_OPS(st_irq_syscfg_pm_ops, NULL, st_irq_syscfg_resume);
192
193static struct platform_driver st_irq_syscfg_driver = {
194 .driver = {
195 .name = "st_irq_syscfg",
196 .pm = &st_irq_syscfg_pm_ops,
197 .of_match_table = st_irq_syscfg_match,
198 },
199 .probe = st_irq_syscfg_probe,
200};
201
202static int __init st_irq_syscfg_init(void)
203{
204 return platform_driver_register(&st_irq_syscfg_driver);
205}
206core_initcall(st_irq_syscfg_init);
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/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c
new file mode 100644
index 000000000000..9521057d4744
--- /dev/null
+++ b/drivers/irqchip/irq-vf610-mscm-ir.c
@@ -0,0 +1,212 @@
1/*
2 * Copyright (C) 2014-2015 Toradex AG
3 * Author: Stefan Agner <stefan@agner.ch>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 *
10 * IRQ chip driver for MSCM interrupt router available on Vybrid SoC's.
11 * The interrupt router is between the CPU's interrupt controller and the
12 * peripheral. The router allows to route the peripheral interrupts to
13 * one of the two available CPU's on Vybrid VF6xx SoC's (Cortex-A5 or
14 * Cortex-M4). The router will be configured transparently on a IRQ
15 * request.
16 *
17 * o All peripheral interrupts of the Vybrid SoC can be routed to
18 * CPU 0, CPU 1 or both. The routing is useful for dual-core
19 * variants of Vybrid SoC such as VF6xx. This driver routes the
20 * requested interrupt to the CPU currently running on.
21 *
22 * o It is required to setup the interrupt router even on single-core
23 * variants of Vybrid.
24 */
25
26#include <linux/cpu_pm.h>
27#include <linux/io.h>
28#include <linux/irq.h>
29#include <linux/irqdomain.h>
30#include <linux/mfd/syscon.h>
31#include <dt-bindings/interrupt-controller/arm-gic.h>
32#include <linux/of.h>
33#include <linux/of_address.h>
34#include <linux/slab.h>
35#include <linux/regmap.h>
36
37#include "irqchip.h"
38
39#define MSCM_CPxNUM 0x4
40
41#define MSCM_IRSPRC(n) (0x80 + 2 * (n))
42#define MSCM_IRSPRC_CPEN_MASK 0x3
43
44#define MSCM_IRSPRC_NUM 112
45
46struct vf610_mscm_ir_chip_data {
47 void __iomem *mscm_ir_base;
48 u16 cpu_mask;
49 u16 saved_irsprc[MSCM_IRSPRC_NUM];
50};
51
52static struct vf610_mscm_ir_chip_data *mscm_ir_data;
53
54static inline void vf610_mscm_ir_save(struct vf610_mscm_ir_chip_data *data)
55{
56 int i;
57
58 for (i = 0; i < MSCM_IRSPRC_NUM; i++)
59 data->saved_irsprc[i] = readw_relaxed(data->mscm_ir_base + MSCM_IRSPRC(i));
60}
61
62static inline void vf610_mscm_ir_restore(struct vf610_mscm_ir_chip_data *data)
63{
64 int i;
65
66 for (i = 0; i < MSCM_IRSPRC_NUM; i++)
67 writew_relaxed(data->saved_irsprc[i], data->mscm_ir_base + MSCM_IRSPRC(i));
68}
69
70static int vf610_mscm_ir_notifier(struct notifier_block *self,
71 unsigned long cmd, void *v)
72{
73 switch (cmd) {
74 case CPU_CLUSTER_PM_ENTER:
75 vf610_mscm_ir_save(mscm_ir_data);
76 break;
77 case CPU_CLUSTER_PM_ENTER_FAILED:
78 case CPU_CLUSTER_PM_EXIT:
79 vf610_mscm_ir_restore(mscm_ir_data);
80 break;
81 }
82
83 return NOTIFY_OK;
84}
85
86static struct notifier_block mscm_ir_notifier_block = {
87 .notifier_call = vf610_mscm_ir_notifier,
88};
89
90static void vf610_mscm_ir_enable(struct irq_data *data)
91{
92 irq_hw_number_t hwirq = data->hwirq;
93 struct vf610_mscm_ir_chip_data *chip_data = data->chip_data;
94 u16 irsprc;
95
96 irsprc = readw_relaxed(chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
97 irsprc &= MSCM_IRSPRC_CPEN_MASK;
98
99 WARN_ON(irsprc & ~chip_data->cpu_mask);
100
101 writew_relaxed(chip_data->cpu_mask,
102 chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
103
104 irq_chip_unmask_parent(data);
105}
106
107static void vf610_mscm_ir_disable(struct irq_data *data)
108{
109 irq_hw_number_t hwirq = data->hwirq;
110 struct vf610_mscm_ir_chip_data *chip_data = data->chip_data;
111
112 writew_relaxed(0x0, chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
113
114 irq_chip_mask_parent(data);
115}
116
117static struct irq_chip vf610_mscm_ir_irq_chip = {
118 .name = "mscm-ir",
119 .irq_mask = irq_chip_mask_parent,
120 .irq_unmask = irq_chip_unmask_parent,
121 .irq_eoi = irq_chip_eoi_parent,
122 .irq_enable = vf610_mscm_ir_enable,
123 .irq_disable = vf610_mscm_ir_disable,
124 .irq_retrigger = irq_chip_retrigger_hierarchy,
125 .irq_set_affinity = irq_chip_set_affinity_parent,
126};
127
128static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int virq,
129 unsigned int nr_irqs, void *arg)
130{
131 int i;
132 irq_hw_number_t hwirq;
133 struct of_phandle_args *irq_data = arg;
134 struct of_phandle_args gic_data;
135
136 if (irq_data->args_count != 2)
137 return -EINVAL;
138
139 hwirq = irq_data->args[0];
140 for (i = 0; i < nr_irqs; i++)
141 irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
142 &vf610_mscm_ir_irq_chip,
143 domain->host_data);
144
145 gic_data.np = domain->parent->of_node;
146 gic_data.args_count = 3;
147 gic_data.args[0] = GIC_SPI;
148 gic_data.args[1] = irq_data->args[0];
149 gic_data.args[2] = irq_data->args[1];
150 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
151}
152
153static const struct irq_domain_ops mscm_irq_domain_ops = {
154 .xlate = irq_domain_xlate_twocell,
155 .alloc = vf610_mscm_ir_domain_alloc,
156 .free = irq_domain_free_irqs_common,
157};
158
159static int __init vf610_mscm_ir_of_init(struct device_node *node,
160 struct device_node *parent)
161{
162 struct irq_domain *domain, *domain_parent;
163 struct regmap *mscm_cp_regmap;
164 int ret, cpuid;
165
166 domain_parent = irq_find_host(parent);
167 if (!domain_parent) {
168 pr_err("vf610_mscm_ir: interrupt-parent not found\n");
169 return -EINVAL;
170 }
171
172 mscm_ir_data = kzalloc(sizeof(*mscm_ir_data), GFP_KERNEL);
173 if (!mscm_ir_data)
174 return -ENOMEM;
175
176 mscm_ir_data->mscm_ir_base = of_io_request_and_map(node, 0, "mscm-ir");
177
178 if (!mscm_ir_data->mscm_ir_base) {
179 pr_err("vf610_mscm_ir: unable to map mscm register\n");
180 ret = -ENOMEM;
181 goto out_free;
182 }
183
184 mscm_cp_regmap = syscon_regmap_lookup_by_phandle(node, "fsl,cpucfg");
185 if (IS_ERR(mscm_cp_regmap)) {
186 ret = PTR_ERR(mscm_cp_regmap);
187 pr_err("vf610_mscm_ir: regmap lookup for cpucfg failed\n");
188 goto out_unmap;
189 }
190
191 regmap_read(mscm_cp_regmap, MSCM_CPxNUM, &cpuid);
192 mscm_ir_data->cpu_mask = 0x1 << cpuid;
193
194 domain = irq_domain_add_hierarchy(domain_parent, 0,
195 MSCM_IRSPRC_NUM, node,
196 &mscm_irq_domain_ops, mscm_ir_data);
197 if (!domain) {
198 ret = -ENOMEM;
199 goto out_unmap;
200 }
201
202 cpu_pm_register_notifier(&mscm_ir_notifier_block);
203
204 return 0;
205
206out_unmap:
207 iounmap(mscm_ir_data->mscm_ir_base);
208out_free:
209 kfree(mscm_ir_data);
210 return ret;
211}
212IRQCHIP_DECLARE(vf610_mscm_ir, "fsl,vf610-mscm-ir", vf610_mscm_ir_of_init);
diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c
index 289ad3ac3e80..8dcc7b8fee40 100644
--- a/drivers/mtd/nand/hisi504_nand.c
+++ b/drivers/mtd/nand/hisi504_nand.c
@@ -758,8 +758,7 @@ static int hisi_nfc_probe(struct platform_device *pdev)
758 758
759 hisi_nfc_host_init(host); 759 hisi_nfc_host_init(host);
760 760
761 ret = devm_request_irq(dev, irq, hinfc_irq_handle, IRQF_DISABLED, 761 ret = devm_request_irq(dev, irq, hinfc_irq_handle, 0x0, "nandc", host);
762 "nandc", host);
763 if (ret) { 762 if (ret) {
764 dev_err(dev, "failed to request IRQ\n"); 763 dev_err(dev, "failed to request IRQ\n");
765 goto err_res; 764 goto err_res;
diff --git a/include/dt-bindings/interrupt-controller/irq-st.h b/include/dt-bindings/interrupt-controller/irq-st.h
new file mode 100644
index 000000000000..4c59aceb9be0
--- /dev/null
+++ b/include/dt-bindings/interrupt-controller/irq-st.h
@@ -0,0 +1,30 @@
1/*
2 * include/linux/irqchip/irq-st.h
3 *
4 * Copyright (C) 2014 STMicroelectronics – All Rights Reserved
5 *
6 * Author: Lee Jones <lee.jones@linaro.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_ST_H
14#define _DT_BINDINGS_INTERRUPT_CONTROLLER_ST_H
15
16#define ST_IRQ_SYSCFG_EXT_0 0
17#define ST_IRQ_SYSCFG_EXT_1 1
18#define ST_IRQ_SYSCFG_EXT_2 2
19#define ST_IRQ_SYSCFG_CTI_0 3
20#define ST_IRQ_SYSCFG_CTI_1 4
21#define ST_IRQ_SYSCFG_PMU_0 5
22#define ST_IRQ_SYSCFG_PMU_1 6
23#define ST_IRQ_SYSCFG_pl310_L2 7
24#define ST_IRQ_SYSCFG_DISABLED 0xFFFFFFFF
25
26#define ST_IRQ_SYSCFG_EXT_1_INV 0x1
27#define ST_IRQ_SYSCFG_EXT_2_INV 0x2
28#define ST_IRQ_SYSCFG_EXT_3_INV 0x4
29
30#endif
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index cba442ec3c66..f4af03404b97 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -9,7 +9,7 @@
9 9
10 10
11extern void synchronize_irq(unsigned int irq); 11extern void synchronize_irq(unsigned int irq);
12extern void synchronize_hardirq(unsigned int irq); 12extern bool synchronize_hardirq(unsigned int irq);
13 13
14#if defined(CONFIG_TINY_RCU) 14#if defined(CONFIG_TINY_RCU)
15 15
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 2e88580194f0..950ae4501826 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -39,8 +39,6 @@
39 * These flags used only by the kernel as part of the 39 * These flags used only by the kernel as part of the
40 * irq handling routines. 40 * irq handling routines.
41 * 41 *
42 * IRQF_DISABLED - keep irqs disabled when calling the action handler.
43 * DEPRECATED. This flag is a NOOP and scheduled to be removed
44 * IRQF_SHARED - allow sharing the irq among several devices 42 * IRQF_SHARED - allow sharing the irq among several devices
45 * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur 43 * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur
46 * IRQF_TIMER - Flag to mark this interrupt as timer interrupt 44 * IRQF_TIMER - Flag to mark this interrupt as timer interrupt
@@ -64,7 +62,6 @@
64 * wakeup devices users need to implement wakeup detection in 62 * wakeup devices users need to implement wakeup detection in
65 * their interrupt handlers. 63 * their interrupt handlers.
66 */ 64 */
67#define IRQF_DISABLED 0x00000020
68#define IRQF_SHARED 0x00000080 65#define IRQF_SHARED 0x00000080
69#define IRQF_PROBE_SHARED 0x00000100 66#define IRQF_PROBE_SHARED 0x00000100
70#define __IRQF_TIMER 0x00000200 67#define __IRQF_TIMER 0x00000200
@@ -191,6 +188,7 @@ extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
191#endif 188#endif
192 189
193extern void disable_irq_nosync(unsigned int irq); 190extern void disable_irq_nosync(unsigned int irq);
191extern bool disable_hardirq(unsigned int irq);
194extern void disable_irq(unsigned int irq); 192extern void disable_irq(unsigned int irq);
195extern void disable_percpu_irq(unsigned int irq); 193extern void disable_percpu_irq(unsigned int irq);
196extern void enable_irq(unsigned int irq); 194extern void enable_irq(unsigned int irq);
@@ -363,6 +361,20 @@ static inline int disable_irq_wake(unsigned int irq)
363 return irq_set_irq_wake(irq, 0); 361 return irq_set_irq_wake(irq, 0);
364} 362}
365 363
364/*
365 * irq_get_irqchip_state/irq_set_irqchip_state specific flags
366 */
367enum irqchip_irq_state {
368 IRQCHIP_STATE_PENDING, /* Is interrupt pending? */
369 IRQCHIP_STATE_ACTIVE, /* Is interrupt in progress? */
370 IRQCHIP_STATE_MASKED, /* Is interrupt masked? */
371 IRQCHIP_STATE_LINE_LEVEL, /* Is IRQ line high? */
372};
373
374extern int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
375 bool *state);
376extern int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
377 bool state);
366 378
367#ifdef CONFIG_IRQ_FORCED_THREADING 379#ifdef CONFIG_IRQ_FORCED_THREADING
368extern bool force_irqthreads; 380extern bool force_irqthreads;
diff --git a/include/linux/irq.h b/include/linux/irq.h
index d09ec7a1243e..62c6901cab55 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -30,6 +30,7 @@
30struct seq_file; 30struct seq_file;
31struct module; 31struct module;
32struct msi_msg; 32struct msi_msg;
33enum irqchip_irq_state;
33 34
34/* 35/*
35 * IRQ line status. 36 * IRQ line status.
@@ -324,6 +325,8 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
324 * irq_request_resources 325 * irq_request_resources
325 * @irq_compose_msi_msg: optional to compose message content for MSI 326 * @irq_compose_msi_msg: optional to compose message content for MSI
326 * @irq_write_msi_msg: optional to write message content for MSI 327 * @irq_write_msi_msg: optional to write message content for MSI
328 * @irq_get_irqchip_state: return the internal state of an interrupt
329 * @irq_set_irqchip_state: set the internal state of a interrupt
327 * @flags: chip specific flags 330 * @flags: chip specific flags
328 */ 331 */
329struct irq_chip { 332struct irq_chip {
@@ -363,6 +366,9 @@ struct irq_chip {
363 void (*irq_compose_msi_msg)(struct irq_data *data, struct msi_msg *msg); 366 void (*irq_compose_msi_msg)(struct irq_data *data, struct msi_msg *msg);
364 void (*irq_write_msi_msg)(struct irq_data *data, struct msi_msg *msg); 367 void (*irq_write_msi_msg)(struct irq_data *data, struct msi_msg *msg);
365 368
369 int (*irq_get_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool *state);
370 int (*irq_set_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool state);
371
366 unsigned long flags; 372 unsigned long flags;
367}; 373};
368 374
@@ -460,6 +466,7 @@ extern void irq_chip_eoi_parent(struct irq_data *data);
460extern int irq_chip_set_affinity_parent(struct irq_data *data, 466extern int irq_chip_set_affinity_parent(struct irq_data *data,
461 const struct cpumask *dest, 467 const struct cpumask *dest,
462 bool force); 468 bool force);
469extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
463#endif 470#endif
464 471
465/* 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/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
index e6a6aac451db..3ea2e4754c40 100644
--- a/include/linux/irqchip/mips-gic.h
+++ b/include/linux/irqchip/mips-gic.h
@@ -240,6 +240,8 @@ extern unsigned int gic_get_count_width(void);
240extern cycle_t gic_read_compare(void); 240extern cycle_t gic_read_compare(void);
241extern void gic_write_compare(cycle_t cnt); 241extern void gic_write_compare(cycle_t cnt);
242extern void gic_write_cpu_compare(cycle_t cnt, int cpu); 242extern void gic_write_cpu_compare(cycle_t cnt, int cpu);
243extern void gic_start_count(void);
244extern void gic_stop_count(void);
243extern void gic_send_ipi(unsigned int intr); 245extern void gic_send_ipi(unsigned int intr);
244extern unsigned int plat_ipi_call_int_xlate(unsigned int); 246extern unsigned int plat_ipi_call_int_xlate(unsigned int);
245extern unsigned int plat_ipi_resched_int_xlate(unsigned int); 247extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
index d176d658fe25..5dd1272d1ab2 100644
--- a/include/linux/irqflags.h
+++ b/include/linux/irqflags.h
@@ -85,7 +85,7 @@
85 * The local_irq_*() APIs are equal to the raw_local_irq*() 85 * The local_irq_*() APIs are equal to the raw_local_irq*()
86 * if !TRACE_IRQFLAGS. 86 * if !TRACE_IRQFLAGS.
87 */ 87 */
88#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT 88#ifdef CONFIG_TRACE_IRQFLAGS
89#define local_irq_enable() \ 89#define local_irq_enable() \
90 do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0) 90 do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0)
91#define local_irq_disable() \ 91#define local_irq_disable() \
@@ -107,22 +107,6 @@
107 raw_local_irq_restore(flags); \ 107 raw_local_irq_restore(flags); \
108 } \ 108 } \
109 } while (0) 109 } while (0)
110#define local_save_flags(flags) \
111 do { \
112 raw_local_save_flags(flags); \
113 } while (0)
114
115#define irqs_disabled_flags(flags) \
116 ({ \
117 raw_irqs_disabled_flags(flags); \
118 })
119
120#define irqs_disabled() \
121 ({ \
122 unsigned long _flags; \
123 raw_local_save_flags(_flags); \
124 raw_irqs_disabled_flags(_flags); \
125 })
126 110
127#define safe_halt() \ 111#define safe_halt() \
128 do { \ 112 do { \
@@ -131,7 +115,7 @@
131 } while (0) 115 } while (0)
132 116
133 117
134#else /* !CONFIG_TRACE_IRQFLAGS_SUPPORT */ 118#else /* !CONFIG_TRACE_IRQFLAGS */
135 119
136#define local_irq_enable() do { raw_local_irq_enable(); } while (0) 120#define local_irq_enable() do { raw_local_irq_enable(); } while (0)
137#define local_irq_disable() do { raw_local_irq_disable(); } while (0) 121#define local_irq_disable() do { raw_local_irq_disable(); } while (0)
@@ -140,11 +124,28 @@
140 raw_local_irq_save(flags); \ 124 raw_local_irq_save(flags); \
141 } while (0) 125 } while (0)
142#define local_irq_restore(flags) do { raw_local_irq_restore(flags); } while (0) 126#define local_irq_restore(flags) do { raw_local_irq_restore(flags); } while (0)
143#define local_save_flags(flags) do { raw_local_save_flags(flags); } while (0)
144#define irqs_disabled() (raw_irqs_disabled())
145#define irqs_disabled_flags(flags) (raw_irqs_disabled_flags(flags))
146#define safe_halt() do { raw_safe_halt(); } while (0) 127#define safe_halt() do { raw_safe_halt(); } while (0)
147 128
129#endif /* CONFIG_TRACE_IRQFLAGS */
130
131#define local_save_flags(flags) raw_local_save_flags(flags)
132
133/*
134 * Some architectures don't define arch_irqs_disabled(), so even if either
135 * definition would be fine we need to use different ones for the time being
136 * to avoid build issues.
137 */
138#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
139#define irqs_disabled() \
140 ({ \
141 unsigned long _flags; \
142 raw_local_save_flags(_flags); \
143 raw_irqs_disabled_flags(_flags); \
144 })
145#else /* !CONFIG_TRACE_IRQFLAGS_SUPPORT */
146#define irqs_disabled() raw_irqs_disabled()
148#endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */ 147#endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */
149 148
149#define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
150
150#endif 151#endif
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/**
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 886d09e691d5..e68932bb308e 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -68,14 +68,20 @@ static void __synchronize_hardirq(struct irq_desc *desc)
68 * Do not use this for shutdown scenarios where you must be sure 68 * Do not use this for shutdown scenarios where you must be sure
69 * that all parts (hardirq and threaded handler) have completed. 69 * that all parts (hardirq and threaded handler) have completed.
70 * 70 *
71 * Returns: false if a threaded handler is active.
72 *
71 * This function may be called - with care - from IRQ context. 73 * This function may be called - with care - from IRQ context.
72 */ 74 */
73void synchronize_hardirq(unsigned int irq) 75bool synchronize_hardirq(unsigned int irq)
74{ 76{
75 struct irq_desc *desc = irq_to_desc(irq); 77 struct irq_desc *desc = irq_to_desc(irq);
76 78
77 if (desc) 79 if (desc) {
78 __synchronize_hardirq(desc); 80 __synchronize_hardirq(desc);
81 return !atomic_read(&desc->threads_active);
82 }
83
84 return true;
79} 85}
80EXPORT_SYMBOL(synchronize_hardirq); 86EXPORT_SYMBOL(synchronize_hardirq);
81 87
@@ -440,6 +446,32 @@ void disable_irq(unsigned int irq)
440} 446}
441EXPORT_SYMBOL(disable_irq); 447EXPORT_SYMBOL(disable_irq);
442 448
449/**
450 * disable_hardirq - disables an irq and waits for hardirq completion
451 * @irq: Interrupt to disable
452 *
453 * Disable the selected interrupt line. Enables and Disables are
454 * nested.
455 * This function waits for any pending hard IRQ handlers for this
456 * interrupt to complete before returning. If you use this function while
457 * holding a resource the hard IRQ handler may need you will deadlock.
458 *
459 * When used to optimistically disable an interrupt from atomic context
460 * the return value must be checked.
461 *
462 * Returns: false if a threaded handler is active.
463 *
464 * This function may be called - with care - from IRQ context.
465 */
466bool disable_hardirq(unsigned int irq)
467{
468 if (!__disable_irq_nosync(irq))
469 return synchronize_hardirq(irq);
470
471 return false;
472}
473EXPORT_SYMBOL_GPL(disable_hardirq);
474
443void __enable_irq(struct irq_desc *desc, unsigned int irq) 475void __enable_irq(struct irq_desc *desc, unsigned int irq)
444{ 476{
445 switch (desc->depth) { 477 switch (desc->depth) {
@@ -1766,3 +1798,94 @@ int request_percpu_irq(unsigned int irq, irq_handler_t handler,
1766 1798
1767 return retval; 1799 return retval;
1768} 1800}
1801
1802/**
1803 * irq_get_irqchip_state - returns the irqchip state of a interrupt.
1804 * @irq: Interrupt line that is forwarded to a VM
1805 * @which: One of IRQCHIP_STATE_* the caller wants to know about
1806 * @state: a pointer to a boolean where the state is to be storeed
1807 *
1808 * This call snapshots the internal irqchip state of an
1809 * interrupt, returning into @state the bit corresponding to
1810 * stage @which
1811 *
1812 * This function should be called with preemption disabled if the
1813 * interrupt controller has per-cpu registers.
1814 */
1815int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
1816 bool *state)
1817{
1818 struct irq_desc *desc;
1819 struct irq_data *data;
1820 struct irq_chip *chip;
1821 unsigned long flags;
1822 int err = -EINVAL;
1823
1824 desc = irq_get_desc_buslock(irq, &flags, 0);
1825 if (!desc)
1826 return err;
1827
1828 data = irq_desc_get_irq_data(desc);
1829
1830 do {
1831 chip = irq_data_get_irq_chip(data);
1832 if (chip->irq_get_irqchip_state)
1833 break;
1834#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
1835 data = data->parent_data;
1836#else
1837 data = NULL;
1838#endif
1839 } while (data);
1840
1841 if (data)
1842 err = chip->irq_get_irqchip_state(data, which, state);
1843
1844 irq_put_desc_busunlock(desc, flags);
1845 return err;
1846}
1847
1848/**
1849 * irq_set_irqchip_state - set the state of a forwarded interrupt.
1850 * @irq: Interrupt line that is forwarded to a VM
1851 * @which: State to be restored (one of IRQCHIP_STATE_*)
1852 * @val: Value corresponding to @which
1853 *
1854 * This call sets the internal irqchip state of an interrupt,
1855 * depending on the value of @which.
1856 *
1857 * This function should be called with preemption disabled if the
1858 * interrupt controller has per-cpu registers.
1859 */
1860int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
1861 bool val)
1862{
1863 struct irq_desc *desc;
1864 struct irq_data *data;
1865 struct irq_chip *chip;
1866 unsigned long flags;
1867 int err = -EINVAL;
1868
1869 desc = irq_get_desc_buslock(irq, &flags, 0);
1870 if (!desc)
1871 return err;
1872
1873 data = irq_desc_get_irq_data(desc);
1874
1875 do {
1876 chip = irq_data_get_irq_chip(data);
1877 if (chip->irq_set_irqchip_state)
1878 break;
1879#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
1880 data = data->parent_data;
1881#else
1882 data = NULL;
1883#endif
1884 } while (data);
1885
1886 if (data)
1887 err = chip->irq_set_irqchip_state(data, which, val);
1888
1889 irq_put_desc_busunlock(desc, flags);
1890 return err;
1891}
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index 3e18163f336f..474de5cb394d 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -310,8 +310,15 @@ void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
310 struct msi_desc *desc; 310 struct msi_desc *desc;
311 311
312 for_each_msi_entry(desc, dev) { 312 for_each_msi_entry(desc, dev) {
313 irq_domain_free_irqs(desc->irq, desc->nvec_used); 313 /*
314 desc->irq = 0; 314 * We might have failed to allocate an MSI early
315 * enough that there is no IRQ associated to this
316 * entry. If that's the case, don't do anything.
317 */
318 if (desc->irq) {
319 irq_domain_free_irqs(desc->irq, desc->nvec_used);
320 desc->irq = 0;
321 }
315 } 322 }
316} 323}
317 324