Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'irqchip-core-4.1-3' of git://git.infradead.org/users/jcooper/linux into irq/core

irqchip core change for v4.1 (round 3) from Jason Cooper

Purge the gic_arch_extn hacks and abuse by using the new stacked domains

NOTE: Due to the nature of these changes, patches crossing subsystems have
been kept together in their own branches.

- tegra
- Handle the LIC properly

- omap
- Convert crossbar to stacked domains
- kill arm,routable-irqs in GIC binding

- exynos
- Convert PMU wakeup to stacked domains

- shmobile, ux500, zynq (irq_set_wake branch)
- Switch from abusing gic_arch_extn to using gic_set_irqchip_flags

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