diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-01 17:33:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-01 17:33:35 -0400 |
commit | 17e6b00ac422b49d44a0b8d98402a211f726282d (patch) | |
tree | c7e9143030d20625a0bd94e12ddaf9421890c375 | |
parent | 5e359bf2219d8622eb0931701e45af55db323228 (diff) | |
parent | e324c4dc4a5991d5b1171f434884a4026345e4b4 (diff) |
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner:
"This updated pull request does not contain the last few GIC related
patches which were reported to cause a regression. There is a fix
available, but I let it breed for a couple of days first.
The irq departement provides:
- new infrastructure to support non PCI based MSI interrupts
- a couple of new irq chip drivers
- the usual pile of fixlets and updates to irq chip drivers
- preparatory changes for removal of the irq argument from interrupt
flow handlers
- preparatory changes to remove IRQF_VALID"
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (129 commits)
irqchip/imx-gpcv2: IMX GPCv2 driver for wakeup sources
irqchip: Add bcm2836 interrupt controller for Raspberry Pi 2
irqchip: Add documentation for the bcm2836 interrupt controller
irqchip/bcm2835: Add support for being used as a second level controller
irqchip/bcm2835: Refactor handle_IRQ() calls out of MAKE_HWIRQ
PCI: xilinx: Fix typo in function name
irqchip/gic: Ensure gic_cpu_if_up/down() programs correct GIC instance
irqchip/gic: Only allow the primary GIC to set the CPU map
PCI/MSI: pci-xgene-msi: Consolidate chained IRQ handler install/remove
unicore32/irq: Prepare puv3_gpio_handler for irq argument removal
tile/pci_gx: Prepare trio_handle_level_irq for irq argument removal
m68k/irq: Prepare irq handlers for irq argument removal
C6X/megamode-pic: Prepare megamod_irq_cascade for irq argument removal
blackfin: Prepare irq handlers for irq argument removal
arc/irq: Prepare idu_cascade_isr for irq argument removal
sparc/irq: Use access helper irq_data_get_affinity_mask()
sparc/irq: Use helper irq_data_get_irq_handler_data()
parisc/irq: Use access helper irq_data_get_affinity_mask()
mn10300/irq: Use access helper irq_data_get_affinity_mask()
irqchip/i8259: Prepare i8259_irq_dispatch for irq argument removal
...
161 files changed, 2211 insertions, 852 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt index 7da578d72123..2d6c8bb4d827 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt | |||
@@ -5,9 +5,14 @@ The BCM2835 contains a custom top-level interrupt controller, which supports | |||
5 | controller, or the HW block containing it, is referred to occasionally | 5 | controller, or the HW block containing it, is referred to occasionally |
6 | as "armctrl" in the SoC documentation, hence naming of this binding. | 6 | as "armctrl" in the SoC documentation, hence naming of this binding. |
7 | 7 | ||
8 | The BCM2836 contains the same interrupt controller with the same | ||
9 | interrupts, but the per-CPU interrupt controller is the root, and an | ||
10 | interrupt there indicates that the ARMCTRL has an interrupt to handle. | ||
11 | |||
8 | Required properties: | 12 | Required properties: |
9 | 13 | ||
10 | - compatible : should be "brcm,bcm2835-armctrl-ic" | 14 | - compatible : should be "brcm,bcm2835-armctrl-ic" or |
15 | "brcm,bcm2836-armctrl-ic" | ||
11 | - reg : Specifies base physical address and size of the registers. | 16 | - reg : Specifies base physical address and size of the registers. |
12 | - interrupt-controller : Identifies the node as an interrupt controller | 17 | - interrupt-controller : Identifies the node as an interrupt controller |
13 | - #interrupt-cells : Specifies the number of cells needed to encode an | 18 | - #interrupt-cells : Specifies the number of cells needed to encode an |
@@ -20,6 +25,12 @@ Required properties: | |||
20 | The 2nd cell contains the interrupt number within the bank. Valid values | 25 | The 2nd cell contains the interrupt number within the bank. Valid values |
21 | are 0..7 for bank 0, and 0..31 for bank 1. | 26 | are 0..7 for bank 0, and 0..31 for bank 1. |
22 | 27 | ||
28 | Additional required properties for brcm,bcm2836-armctrl-ic: | ||
29 | - interrupt-parent : Specifies the parent interrupt controller when this | ||
30 | controller is the second level. | ||
31 | - interrupts : Specifies the interrupt on the parent for this interrupt | ||
32 | controller to handle. | ||
33 | |||
23 | The interrupt sources are as follows: | 34 | The interrupt sources are as follows: |
24 | 35 | ||
25 | Bank 0: | 36 | Bank 0: |
@@ -102,9 +113,21 @@ Bank 2: | |||
102 | 113 | ||
103 | Example: | 114 | Example: |
104 | 115 | ||
116 | /* BCM2835, first level */ | ||
105 | intc: interrupt-controller { | 117 | intc: interrupt-controller { |
106 | compatible = "brcm,bcm2835-armctrl-ic"; | 118 | compatible = "brcm,bcm2835-armctrl-ic"; |
107 | reg = <0x7e00b200 0x200>; | 119 | reg = <0x7e00b200 0x200>; |
108 | interrupt-controller; | 120 | interrupt-controller; |
109 | #interrupt-cells = <2>; | 121 | #interrupt-cells = <2>; |
110 | }; | 122 | }; |
123 | |||
124 | /* BCM2836, second level */ | ||
125 | intc: interrupt-controller { | ||
126 | compatible = "brcm,bcm2836-armctrl-ic"; | ||
127 | reg = <0x7e00b200 0x200>; | ||
128 | interrupt-controller; | ||
129 | #interrupt-cells = <2>; | ||
130 | |||
131 | interrupt-parent = <&local_intc>; | ||
132 | interrupts = <8>; | ||
133 | }; | ||
diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.txt new file mode 100644 index 000000000000..f320dcd6e69b --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.txt | |||
@@ -0,0 +1,37 @@ | |||
1 | BCM2836 per-CPU interrupt controller | ||
2 | |||
3 | The BCM2836 has a per-cpu interrupt controller for the timer, PMU | ||
4 | events, and SMP IPIs. One of the CPUs may receive interrupts for the | ||
5 | peripheral (GPU) events, which chain to the BCM2835-style interrupt | ||
6 | controller. | ||
7 | |||
8 | Required properties: | ||
9 | |||
10 | - compatible: Should be "brcm,bcm2836-l1-intc" | ||
11 | - reg: Specifies base physical address and size of the | ||
12 | registers | ||
13 | - interrupt-controller: Identifies the node as an interrupt controller | ||
14 | - #interrupt-cells: Specifies the number of cells needed to encode an | ||
15 | interrupt source. The value shall be 1 | ||
16 | |||
17 | Please refer to interrupts.txt in this directory for details of the common | ||
18 | Interrupt Controllers bindings used by client devices. | ||
19 | |||
20 | The interrupt sources are as follows: | ||
21 | |||
22 | 0: CNTPSIRQ | ||
23 | 1: CNTPNSIRQ | ||
24 | 2: CNTHPIRQ | ||
25 | 3: CNTVIRQ | ||
26 | 8: GPU_FAST | ||
27 | 9: PMU_FAST | ||
28 | |||
29 | Example: | ||
30 | |||
31 | local_intc: local_intc { | ||
32 | compatible = "brcm,bcm2836-l1-intc"; | ||
33 | reg = <0x40000000 0x100>; | ||
34 | interrupt-controller; | ||
35 | #interrupt-cells = <1>; | ||
36 | interrupt-parent = <&local_intc>; | ||
37 | }; | ||
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 51f2c8654253..2804648c8ff4 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c | |||
@@ -59,7 +59,7 @@ int irq_select_affinity(unsigned int irq) | |||
59 | cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); | 59 | cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); |
60 | last_cpu = cpu; | 60 | last_cpu = cpu; |
61 | 61 | ||
62 | cpumask_copy(data->affinity, cpumask_of(cpu)); | 62 | cpumask_copy(irq_data_get_affinity_mask(data), cpumask_of(cpu)); |
63 | chip->irq_set_affinity(data, cpumask_of(cpu), false); | 63 | chip->irq_set_affinity(data, cpumask_of(cpu), false); |
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index 2fb86589054d..d9e44b62df05 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c | |||
@@ -252,9 +252,10 @@ static struct irq_chip idu_irq_chip = { | |||
252 | 252 | ||
253 | static int idu_first_irq; | 253 | static int idu_first_irq; |
254 | 254 | ||
255 | static void idu_cascade_isr(unsigned int core_irq, struct irq_desc *desc) | 255 | static void idu_cascade_isr(unsigned int __core_irq, struct irq_desc *desc) |
256 | { | 256 | { |
257 | struct irq_domain *domain = irq_desc_get_handler_data(desc); | 257 | struct irq_domain *domain = irq_desc_get_handler_data(desc); |
258 | unsigned int core_irq = irq_desc_get_irq(desc); | ||
258 | unsigned int idu_irq; | 259 | unsigned int idu_irq; |
259 | 260 | ||
260 | idu_irq = core_irq - idu_first_irq; | 261 | idu_irq = core_irq - idu_first_irq; |
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 7ca891999547..6bfa6407a27c 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c | |||
@@ -62,8 +62,6 @@ static void __init r8a7779_map_io(void) | |||
62 | 62 | ||
63 | static void __init r8a7779_init_irq_dt(void) | 63 | static void __init r8a7779_init_irq_dt(void) |
64 | { | 64 | { |
65 | gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE); | ||
66 | |||
67 | irqchip_init(); | 65 | irqchip_init(); |
68 | 66 | ||
69 | /* route all interrupts to ARM */ | 67 | /* route all interrupts to ARM */ |
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index b316e18a76aa..41b81c4fbe63 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c | |||
@@ -56,7 +56,6 @@ void __init ux500_init_irq(void) | |||
56 | struct device_node *np; | 56 | struct device_node *np; |
57 | struct resource r; | 57 | struct resource r; |
58 | 58 | ||
59 | gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND); | ||
60 | irqchip_init(); | 59 | irqchip_init(); |
61 | np = of_find_compatible_node(NULL, NULL, "stericsson,db8500-prcmu"); | 60 | np = of_find_compatible_node(NULL, NULL, "stericsson,db8500-prcmu"); |
62 | of_address_to_resource(np, 0, &r); | 61 | of_address_to_resource(np, 0, &r); |
diff --git a/arch/arm/mach-vexpress/tc2_pm.c b/arch/arm/mach-vexpress/tc2_pm.c index b3328cd46c33..1aa4ccece69f 100644 --- a/arch/arm/mach-vexpress/tc2_pm.c +++ b/arch/arm/mach-vexpress/tc2_pm.c | |||
@@ -80,7 +80,7 @@ static void tc2_pm_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster) | |||
80 | * to the CPU by disabling the GIC CPU IF to prevent wfi | 80 | * to the CPU by disabling the GIC CPU IF to prevent wfi |
81 | * from completing execution behind power controller back | 81 | * from completing execution behind power controller back |
82 | */ | 82 | */ |
83 | gic_cpu_if_down(); | 83 | gic_cpu_if_down(0); |
84 | } | 84 | } |
85 | 85 | ||
86 | static void tc2_pm_cluster_powerdown_prepare(unsigned int cluster) | 86 | static void tc2_pm_cluster_powerdown_prepare(unsigned int cluster) |
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 6bd4a43e1a78..5a6e4e20ca0a 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c | |||
@@ -186,7 +186,6 @@ static void __init zynq_map_io(void) | |||
186 | 186 | ||
187 | static void __init zynq_irq_init(void) | 187 | static void __init zynq_irq_init(void) |
188 | { | 188 | { |
189 | gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND); | ||
190 | irqchip_init(); | 189 | irqchip_init(); |
191 | } | 190 | } |
192 | 191 | ||
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c index 2d48b6a46166..d51ff8f1c541 100644 --- a/arch/avr32/mach-at32ap/extint.c +++ b/arch/avr32/mach-at32ap/extint.c | |||
@@ -128,9 +128,9 @@ static int eic_set_irq_type(struct irq_data *d, unsigned int flow_type) | |||
128 | 128 | ||
129 | irqd_set_trigger_type(d, flow_type); | 129 | irqd_set_trigger_type(d, flow_type); |
130 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | 130 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
131 | __irq_set_handler_locked(irq, handle_level_irq); | 131 | irq_set_handler_locked(d, handle_level_irq); |
132 | else | 132 | else |
133 | __irq_set_handler_locked(irq, handle_edge_irq); | 133 | irq_set_handler_locked(d, handle_edge_irq); |
134 | 134 | ||
135 | return IRQ_SET_MASK_OK_NOCOPY; | 135 | return IRQ_SET_MASK_OK_NOCOPY; |
136 | } | 136 | } |
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index 903c7d81d0d5..157a5e0e789f 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c | |||
@@ -286,7 +286,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
286 | struct pio_device *pio = irq_desc_get_chip_data(desc); | 286 | struct pio_device *pio = irq_desc_get_chip_data(desc); |
287 | unsigned gpio_irq; | 287 | unsigned gpio_irq; |
288 | 288 | ||
289 | gpio_irq = (unsigned) irq_get_handler_data(irq); | 289 | gpio_irq = (unsigned) irq_desc_get_handler_data(desc); |
290 | for (;;) { | 290 | for (;;) { |
291 | u32 isr; | 291 | u32 isr; |
292 | 292 | ||
@@ -312,7 +312,6 @@ gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq) | |||
312 | unsigned i; | 312 | unsigned i; |
313 | 313 | ||
314 | irq_set_chip_data(irq, pio); | 314 | irq_set_chip_data(irq, pio); |
315 | irq_set_handler_data(irq, (void *)gpio_irq); | ||
316 | 315 | ||
317 | for (i = 0; i < 32; i++, gpio_irq++) { | 316 | for (i = 0; i < 32; i++, gpio_irq++) { |
318 | irq_set_chip_data(gpio_irq, pio); | 317 | irq_set_chip_data(gpio_irq, pio); |
@@ -320,7 +319,8 @@ gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq) | |||
320 | handle_simple_irq); | 319 | handle_simple_irq); |
321 | } | 320 | } |
322 | 321 | ||
323 | irq_set_chained_handler(irq, gpio_irq_handler); | 322 | irq_set_chained_handler_and_data(irq, gpio_irq_handler, |
323 | (void *)gpio_irq); | ||
324 | } | 324 | } |
325 | 325 | ||
326 | /*--------------------------------------------------------------------------*/ | 326 | /*--------------------------------------------------------------------------*/ |
diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c index 2137a209a22b..14b2f74554dc 100644 --- a/arch/blackfin/mach-bf537/ints-priority.c +++ b/arch/blackfin/mach-bf537/ints-priority.c | |||
@@ -182,9 +182,11 @@ static struct irq_chip bf537_mac_rx_irqchip = { | |||
182 | .irq_unmask = bf537_mac_rx_unmask_irq, | 182 | .irq_unmask = bf537_mac_rx_unmask_irq, |
183 | }; | 183 | }; |
184 | 184 | ||
185 | static void bf537_demux_mac_rx_irq(unsigned int int_irq, | 185 | static void bf537_demux_mac_rx_irq(unsigned int __int_irq, |
186 | struct irq_desc *desc) | 186 | struct irq_desc *desc) |
187 | { | 187 | { |
188 | unsigned int int_irq = irq_desc_get_irq(desc); | ||
189 | |||
188 | if (bfin_read_DMA1_IRQ_STATUS() & (DMA_DONE | DMA_ERR)) | 190 | if (bfin_read_DMA1_IRQ_STATUS() & (DMA_DONE | DMA_ERR)) |
189 | bfin_handle_irq(IRQ_MAC_RX); | 191 | bfin_handle_irq(IRQ_MAC_RX); |
190 | else | 192 | else |
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 7236bdfc71e6..a6d1b03cdf36 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -194,7 +194,8 @@ void bfin_internal_unmask_irq(unsigned int irq) | |||
194 | #ifdef CONFIG_SMP | 194 | #ifdef CONFIG_SMP |
195 | static void bfin_internal_unmask_irq_chip(struct irq_data *d) | 195 | static void bfin_internal_unmask_irq_chip(struct irq_data *d) |
196 | { | 196 | { |
197 | bfin_internal_unmask_irq_affinity(d->irq, d->affinity); | 197 | bfin_internal_unmask_irq_affinity(d->irq, |
198 | irq_data_get_affinity_mask(d)); | ||
198 | } | 199 | } |
199 | 200 | ||
200 | static int bfin_internal_set_affinity(struct irq_data *d, | 201 | static int bfin_internal_set_affinity(struct irq_data *d, |
@@ -685,12 +686,12 @@ void bfin_demux_mac_status_irq(unsigned int int_err_irq, | |||
685 | } | 686 | } |
686 | #endif | 687 | #endif |
687 | 688 | ||
688 | static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) | 689 | static inline void bfin_set_irq_handler(struct irq_data *d, irq_flow_handler_t handle) |
689 | { | 690 | { |
690 | #ifdef CONFIG_IPIPE | 691 | #ifdef CONFIG_IPIPE |
691 | handle = handle_level_irq; | 692 | handle = handle_level_irq; |
692 | #endif | 693 | #endif |
693 | __irq_set_handler_locked(irq, handle); | 694 | irq_set_handler_locked(d, handle); |
694 | } | 695 | } |
695 | 696 | ||
696 | #ifdef CONFIG_GPIO_ADI | 697 | #ifdef CONFIG_GPIO_ADI |
@@ -802,9 +803,9 @@ static int bfin_gpio_irq_type(struct irq_data *d, unsigned int type) | |||
802 | } | 803 | } |
803 | 804 | ||
804 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | 805 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) |
805 | bfin_set_irq_handler(irq, handle_edge_irq); | 806 | bfin_set_irq_handler(d, handle_edge_irq); |
806 | else | 807 | else |
807 | bfin_set_irq_handler(irq, handle_level_irq); | 808 | bfin_set_irq_handler(d, handle_level_irq); |
808 | 809 | ||
809 | return 0; | 810 | return 0; |
810 | } | 811 | } |
@@ -824,9 +825,9 @@ static void bfin_demux_gpio_block(unsigned int irq) | |||
824 | } | 825 | } |
825 | } | 826 | } |
826 | 827 | ||
827 | void bfin_demux_gpio_irq(unsigned int inta_irq, | 828 | void bfin_demux_gpio_irq(unsigned int __inta_irq, struct irq_desc *desc) |
828 | struct irq_desc *desc) | ||
829 | { | 829 | { |
830 | unsigned int inta_irq = irq_desc_get_irq(desc); | ||
830 | unsigned int irq; | 831 | unsigned int irq; |
831 | 832 | ||
832 | switch (inta_irq) { | 833 | switch (inta_irq) { |
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c index 74e3371eb824..d487698e978a 100644 --- a/arch/c6x/platforms/megamod-pic.c +++ b/arch/c6x/platforms/megamod-pic.c | |||
@@ -93,10 +93,11 @@ static struct irq_chip megamod_chip = { | |||
93 | .irq_unmask = unmask_megamod, | 93 | .irq_unmask = unmask_megamod, |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static void megamod_irq_cascade(unsigned int irq, struct irq_desc *desc) | 96 | static void megamod_irq_cascade(unsigned int __irq, struct irq_desc *desc) |
97 | { | 97 | { |
98 | struct megamod_cascade_data *cascade; | 98 | struct megamod_cascade_data *cascade; |
99 | struct megamod_pic *pic; | 99 | struct megamod_pic *pic; |
100 | unsigned int irq; | ||
100 | u32 events; | 101 | u32 events; |
101 | int n, idx; | 102 | int n, idx; |
102 | 103 | ||
@@ -282,8 +283,8 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np) | |||
282 | soc_writel(~0, &pic->regs->evtmask[i]); | 283 | soc_writel(~0, &pic->regs->evtmask[i]); |
283 | soc_writel(~0, &pic->regs->evtclr[i]); | 284 | soc_writel(~0, &pic->regs->evtclr[i]); |
284 | 285 | ||
285 | irq_set_handler_data(irq, &cascade_data[i]); | 286 | irq_set_chained_handler_and_data(irq, megamod_irq_cascade, |
286 | irq_set_chained_handler(irq, megamod_irq_cascade); | 287 | &cascade_data[i]); |
287 | } | 288 | } |
288 | 289 | ||
289 | /* Finally, set up the MUX registers */ | 290 | /* Finally, set up the MUX registers */ |
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index bc9501e36e77..d2fae054d988 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c | |||
@@ -610,9 +610,9 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery, | |||
610 | chip->name, irq_type->name); | 610 | chip->name, irq_type->name); |
611 | chip = irq_type; | 611 | chip = irq_type; |
612 | } | 612 | } |
613 | __irq_set_chip_handler_name_locked(irq, chip, trigger == IOSAPIC_EDGE ? | 613 | irq_set_chip_handler_name_locked(irq_get_irq_data(irq), chip, |
614 | handle_edge_irq : handle_level_irq, | 614 | trigger == IOSAPIC_EDGE ? handle_edge_irq : handle_level_irq, |
615 | NULL); | 615 | NULL); |
616 | return 0; | 616 | return 0; |
617 | } | 617 | } |
618 | 618 | ||
@@ -838,7 +838,7 @@ iosapic_unregister_intr (unsigned int gsi) | |||
838 | if (iosapic_intr_info[irq].count == 0) { | 838 | if (iosapic_intr_info[irq].count == 0) { |
839 | #ifdef CONFIG_SMP | 839 | #ifdef CONFIG_SMP |
840 | /* Clear affinity */ | 840 | /* Clear affinity */ |
841 | cpumask_setall(irq_get_irq_data(irq)->affinity); | 841 | cpumask_setall(irq_get_affinity_mask(irq)); |
842 | #endif | 842 | #endif |
843 | /* Clear the interrupt information */ | 843 | /* Clear the interrupt information */ |
844 | iosapic_intr_info[irq].dest = 0; | 844 | iosapic_intr_info[irq].dest = 0; |
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 812a1e6b3179..de4fc00dea98 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c | |||
@@ -67,7 +67,7 @@ static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 }; | |||
67 | void set_irq_affinity_info (unsigned int irq, int hwid, int redir) | 67 | void set_irq_affinity_info (unsigned int irq, int hwid, int redir) |
68 | { | 68 | { |
69 | if (irq < NR_IRQS) { | 69 | if (irq < NR_IRQS) { |
70 | cpumask_copy(irq_get_irq_data(irq)->affinity, | 70 | cpumask_copy(irq_get_affinity_mask(irq), |
71 | cpumask_of(cpu_logical_id(hwid))); | 71 | cpumask_of(cpu_logical_id(hwid))); |
72 | irq_redir[irq] = (char) (redir & 0xff); | 72 | irq_redir[irq] = (char) (redir & 0xff); |
73 | } | 73 | } |
@@ -119,8 +119,8 @@ static void migrate_irqs(void) | |||
119 | if (irqd_is_per_cpu(data)) | 119 | if (irqd_is_per_cpu(data)) |
120 | continue; | 120 | continue; |
121 | 121 | ||
122 | if (cpumask_any_and(data->affinity, cpu_online_mask) | 122 | if (cpumask_any_and(irq_data_get_affinity_mask(data), |
123 | >= nr_cpu_ids) { | 123 | cpu_online_mask) >= nr_cpu_ids) { |
124 | /* | 124 | /* |
125 | * Save it for phase 2 processing | 125 | * Save it for phase 2 processing |
126 | */ | 126 | */ |
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index d70bf15c690a..af4eaec0f7c3 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c | |||
@@ -23,7 +23,7 @@ static int ia64_set_msi_irq_affinity(struct irq_data *idata, | |||
23 | if (irq_prepare_move(irq, cpu)) | 23 | if (irq_prepare_move(irq, cpu)) |
24 | return -1; | 24 | return -1; |
25 | 25 | ||
26 | __get_cached_msi_msg(idata->msi_desc, &msg); | 26 | __get_cached_msi_msg(irq_data_get_msi_desc(idata), &msg); |
27 | 27 | ||
28 | addr = msg.address_lo; | 28 | addr = msg.address_lo; |
29 | addr &= MSI_ADDR_DEST_ID_MASK; | 29 | addr &= MSI_ADDR_DEST_ID_MASK; |
@@ -36,7 +36,7 @@ static int ia64_set_msi_irq_affinity(struct irq_data *idata, | |||
36 | msg.data = data; | 36 | msg.data = data; |
37 | 37 | ||
38 | pci_write_msi_msg(irq, &msg); | 38 | pci_write_msi_msg(irq, &msg); |
39 | cpumask_copy(idata->affinity, cpumask_of(cpu)); | 39 | cpumask_copy(irq_data_get_affinity_mask(idata), cpumask_of(cpu)); |
40 | 40 | ||
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
@@ -148,7 +148,7 @@ static int dmar_msi_set_affinity(struct irq_data *data, | |||
148 | msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu)); | 148 | msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu)); |
149 | 149 | ||
150 | dmar_msi_write(irq, &msg); | 150 | dmar_msi_write(irq, &msg); |
151 | cpumask_copy(data->affinity, mask); | 151 | cpumask_copy(irq_data_get_affinity_mask(data), mask); |
152 | 152 | ||
153 | return 0; | 153 | return 0; |
154 | } | 154 | } |
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index a0eb27b66d13..fb25065b22c6 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c | |||
@@ -175,7 +175,7 @@ static int sn_set_msi_irq_affinity(struct irq_data *data, | |||
175 | * Release XIO resources for the old MSI PCI address | 175 | * Release XIO resources for the old MSI PCI address |
176 | */ | 176 | */ |
177 | 177 | ||
178 | __get_cached_msi_msg(data->msi_desc, &msg); | 178 | __get_cached_msi_msg(irq_data_get_msi_desc(data), &msg); |
179 | sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; | 179 | sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; |
180 | pdev = sn_pdev->pdi_linux_pcidev; | 180 | pdev = sn_pdev->pdi_linux_pcidev; |
181 | provider = SN_PCIDEV_BUSPROVIDER(pdev); | 181 | provider = SN_PCIDEV_BUSPROVIDER(pdev); |
@@ -206,7 +206,7 @@ static int sn_set_msi_irq_affinity(struct irq_data *data, | |||
206 | msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff); | 206 | msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff); |
207 | 207 | ||
208 | pci_write_msi_msg(irq, &msg); | 208 | pci_write_msi_msg(irq, &msg); |
209 | cpumask_copy(data->affinity, cpu_mask); | 209 | cpumask_copy(irq_data_get_affinity_mask(data), cpu_mask); |
210 | 210 | ||
211 | return 0; | 211 | return 0; |
212 | } | 212 | } |
diff --git a/arch/m68k/coldfire/intc-5272.c b/arch/m68k/coldfire/intc-5272.c index d1e2fbad327c..47371de60427 100644 --- a/arch/m68k/coldfire/intc-5272.c +++ b/arch/m68k/coldfire/intc-5272.c | |||
@@ -143,8 +143,10 @@ static int intc_irq_set_type(struct irq_data *d, unsigned int type) | |||
143 | * We need to be careful with the masking/acking due to the side effects | 143 | * We need to be careful with the masking/acking due to the side effects |
144 | * of masking an interrupt. | 144 | * of masking an interrupt. |
145 | */ | 145 | */ |
146 | static void intc_external_irq(unsigned int irq, struct irq_desc *desc) | 146 | static void intc_external_irq(unsigned int __irq, struct irq_desc *desc) |
147 | { | 147 | { |
148 | unsigned int irq = irq_desc_get_irq(desc); | ||
149 | |||
148 | irq_desc_get_chip(desc)->irq_ack(&desc->irq_data); | 150 | irq_desc_get_chip(desc)->irq_ack(&desc->irq_data); |
149 | handle_simple_irq(irq, desc); | 151 | handle_simple_irq(irq, desc); |
150 | } | 152 | } |
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index bb11dceed7ed..191610d97689 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c | |||
@@ -63,13 +63,15 @@ void __init oss_nubus_init(void) | |||
63 | * Handle miscellaneous OSS interrupts. | 63 | * Handle miscellaneous OSS interrupts. |
64 | */ | 64 | */ |
65 | 65 | ||
66 | static void oss_irq(unsigned int irq, struct irq_desc *desc) | 66 | static void oss_irq(unsigned int __irq, struct irq_desc *desc) |
67 | { | 67 | { |
68 | int events = oss->irq_pending & | 68 | int events = oss->irq_pending & |
69 | (OSS_IP_IOPSCC | OSS_IP_SCSI | OSS_IP_IOPISM); | 69 | (OSS_IP_IOPSCC | OSS_IP_SCSI | OSS_IP_IOPISM); |
70 | 70 | ||
71 | #ifdef DEBUG_IRQS | 71 | #ifdef DEBUG_IRQS |
72 | if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) { | 72 | if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) { |
73 | unsigned int irq = irq_desc_get_irq(desc); | ||
74 | |||
73 | printk("oss_irq: irq %u events = 0x%04X\n", irq, | 75 | printk("oss_irq: irq %u events = 0x%04X\n", irq, |
74 | (int) oss->irq_pending); | 76 | (int) oss->irq_pending); |
75 | } | 77 | } |
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index 272dde481d17..3b9e302e7a37 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c | |||
@@ -113,9 +113,10 @@ void __init psc_init(void) | |||
113 | * PSC interrupt handler. It's a lot like the VIA interrupt handler. | 113 | * PSC interrupt handler. It's a lot like the VIA interrupt handler. |
114 | */ | 114 | */ |
115 | 115 | ||
116 | static void psc_irq(unsigned int irq, struct irq_desc *desc) | 116 | static void psc_irq(unsigned int __irq, struct irq_desc *desc) |
117 | { | 117 | { |
118 | unsigned int offset = (unsigned int)irq_desc_get_handler_data(desc); | 118 | unsigned int offset = (unsigned int)irq_desc_get_handler_data(desc); |
119 | unsigned int irq = irq_desc_get_irq(desc); | ||
119 | int pIFR = pIFRbase + offset; | 120 | int pIFR = pIFRbase + offset; |
120 | int pIER = pIERbase + offset; | 121 | int pIER = pIERbase + offset; |
121 | int irq_num; | 122 | int irq_num; |
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index 719feee1e043..90bec7d71f85 100644 --- a/arch/microblaze/kernel/intc.c +++ b/arch/microblaze/kernel/intc.c | |||
@@ -11,12 +11,11 @@ | |||
11 | 11 | ||
12 | #include <linux/irqdomain.h> | 12 | #include <linux/irqdomain.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/irqchip.h> | ||
14 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
15 | #include <linux/io.h> | 16 | #include <linux/io.h> |
16 | #include <linux/bug.h> | 17 | #include <linux/bug.h> |
17 | 18 | ||
18 | #include "../../drivers/irqchip/irqchip.h" | ||
19 | |||
20 | static void __iomem *intc_baseaddr; | 19 | static void __iomem *intc_baseaddr; |
21 | 20 | ||
22 | /* No one else should require these constants, so define them locally here. */ | 21 | /* No one else should require these constants, so define them locally here. */ |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c6d28bce0b40..4ab9a794bbcd 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1071,10 +1071,6 @@ config HOTPLUG_CPU | |||
1071 | config SYS_SUPPORTS_HOTPLUG_CPU | 1071 | config SYS_SUPPORTS_HOTPLUG_CPU |
1072 | bool | 1072 | bool |
1073 | 1073 | ||
1074 | config I8259 | ||
1075 | bool | ||
1076 | select IRQ_DOMAIN | ||
1077 | |||
1078 | config MIPS_BONITO64 | 1074 | config MIPS_BONITO64 |
1079 | bool | 1075 | bool |
1080 | 1076 | ||
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index afb009603f7f..2021be20d9d9 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/irqchip.h> | 18 | #include <linux/irqchip.h> |
19 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
20 | #include "../../../drivers/irqchip/irqchip.h" | ||
21 | 20 | ||
22 | #include <asm/irq_cpu.h> | 21 | #include <asm/irq_cpu.h> |
23 | #include <asm/mipsregs.h> | 22 | #include <asm/mipsregs.h> |
diff --git a/arch/mips/bmips/irq.c b/arch/mips/bmips/irq.c index 14552e58ff7e..e7fc6f9348ba 100644 --- a/arch/mips/bmips/irq.c +++ b/arch/mips/bmips/irq.c | |||
@@ -34,5 +34,5 @@ void __init arch_init_irq(void) | |||
34 | irqchip_init(); | 34 | irqchip_init(); |
35 | } | 35 | } |
36 | 36 | ||
37 | OF_DECLARE_2(irqchip, mips_cpu_intc, "mti,cpu-interrupt-controller", | 37 | IRQCHIP_DECLARE(mips_cpu_intc, "mti,cpu-interrupt-controller", |
38 | mips_cpu_irq_of_init); | 38 | mips_cpu_irq_of_init); |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 3f5cf8aff6f3..3156c8d253c1 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -61,7 +61,6 @@ obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o | |||
61 | obj-$(CONFIG_MIPS_VPE_APSP_API_CMP) += rtlx-cmp.o | 61 | obj-$(CONFIG_MIPS_VPE_APSP_API_CMP) += rtlx-cmp.o |
62 | obj-$(CONFIG_MIPS_VPE_APSP_API_MT) += rtlx-mt.o | 62 | obj-$(CONFIG_MIPS_VPE_APSP_API_MT) += rtlx-mt.o |
63 | 63 | ||
64 | obj-$(CONFIG_I8259) += i8259.o | ||
65 | obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o | 64 | obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o |
66 | obj-$(CONFIG_MIPS_MSC) += irq-msc01.o | 65 | obj-$(CONFIG_MIPS_MSC) += irq-msc01.o |
67 | obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o | 66 | obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o |
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c index cffaaf4aae3c..2a5bb849b10e 100644 --- a/arch/mips/pci/msi-octeon.c +++ b/arch/mips/pci/msi-octeon.c | |||
@@ -200,7 +200,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
200 | if (type == PCI_CAP_ID_MSI && nvec > 1) | 200 | if (type == PCI_CAP_ID_MSI && nvec > 1) |
201 | return 1; | 201 | return 1; |
202 | 202 | ||
203 | list_for_each_entry(entry, &dev->msi_list, list) { | 203 | for_each_pci_msi_entry(entry, dev) { |
204 | ret = arch_setup_msi_irq(dev, entry); | 204 | ret = arch_setup_msi_irq(dev, entry); |
205 | if (ret < 0) | 205 | if (ret < 0) |
206 | return ret; | 206 | return ret; |
diff --git a/arch/mn10300/kernel/cevt-mn10300.c b/arch/mn10300/kernel/cevt-mn10300.c index 3aae9f5a98aa..d9b34dd44f04 100644 --- a/arch/mn10300/kernel/cevt-mn10300.c +++ b/arch/mn10300/kernel/cevt-mn10300.c | |||
@@ -116,7 +116,7 @@ int __init init_clockevents(void) | |||
116 | { | 116 | { |
117 | struct irq_data *data; | 117 | struct irq_data *data; |
118 | data = irq_get_irq_data(cd->irq); | 118 | data = irq_get_irq_data(cd->irq); |
119 | cpumask_copy(data->affinity, cpumask_of(cpu)); | 119 | cpumask_copy(irq_data_get_affinity_mask(data), cpumask_of(cpu)); |
120 | iact->flags |= IRQF_NOBALANCING; | 120 | iact->flags |= IRQF_NOBALANCING; |
121 | } | 121 | } |
122 | #endif | 122 | #endif |
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c index 480de70f4059..c716437baa2c 100644 --- a/arch/mn10300/kernel/irq.c +++ b/arch/mn10300/kernel/irq.c | |||
@@ -87,7 +87,8 @@ static void mn10300_cpupic_mask_ack(struct irq_data *d) | |||
87 | tmp2 = GxICR(irq); | 87 | tmp2 = GxICR(irq); |
88 | 88 | ||
89 | irq_affinity_online[irq] = | 89 | irq_affinity_online[irq] = |
90 | cpumask_any_and(d->affinity, cpu_online_mask); | 90 | cpumask_any_and(irq_data_get_affinity_mask(d), |
91 | cpu_online_mask); | ||
91 | CROSS_GxICR(irq, irq_affinity_online[irq]) = | 92 | CROSS_GxICR(irq, irq_affinity_online[irq]) = |
92 | (tmp & (GxICR_LEVEL | GxICR_ENABLE)) | GxICR_DETECT; | 93 | (tmp & (GxICR_LEVEL | GxICR_ENABLE)) | GxICR_DETECT; |
93 | tmp = CROSS_GxICR(irq, irq_affinity_online[irq]); | 94 | tmp = CROSS_GxICR(irq, irq_affinity_online[irq]); |
@@ -124,7 +125,7 @@ static void mn10300_cpupic_unmask_clear(struct irq_data *d) | |||
124 | } else { | 125 | } else { |
125 | tmp = GxICR(irq); | 126 | tmp = GxICR(irq); |
126 | 127 | ||
127 | irq_affinity_online[irq] = cpumask_any_and(d->affinity, | 128 | irq_affinity_online[irq] = cpumask_any_and(irq_data_get_affinity_mask(d), |
128 | cpu_online_mask); | 129 | cpu_online_mask); |
129 | CROSS_GxICR(irq, irq_affinity_online[irq]) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT; | 130 | CROSS_GxICR(irq, irq_affinity_online[irq]) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT; |
130 | tmp = CROSS_GxICR(irq, irq_affinity_online[irq]); | 131 | tmp = CROSS_GxICR(irq, irq_affinity_online[irq]); |
@@ -316,15 +317,16 @@ void migrate_irqs(void) | |||
316 | self = smp_processor_id(); | 317 | self = smp_processor_id(); |
317 | for (irq = 0; irq < NR_IRQS; irq++) { | 318 | for (irq = 0; irq < NR_IRQS; irq++) { |
318 | struct irq_data *data = irq_get_irq_data(irq); | 319 | struct irq_data *data = irq_get_irq_data(irq); |
320 | struct cpumask *mask = irq_data_get_affinity_mask(data); | ||
319 | 321 | ||
320 | if (irqd_is_per_cpu(data)) | 322 | if (irqd_is_per_cpu(data)) |
321 | continue; | 323 | continue; |
322 | 324 | ||
323 | if (cpumask_test_cpu(self, data->affinity) && | 325 | if (cpumask_test_cpu(self, mask) && |
324 | !cpumask_intersects(&irq_affinity[irq], cpu_online_mask)) { | 326 | !cpumask_intersects(&irq_affinity[irq], cpu_online_mask)) { |
325 | int cpu_id; | 327 | int cpu_id; |
326 | cpu_id = cpumask_first(cpu_online_mask); | 328 | cpu_id = cpumask_first(cpu_online_mask); |
327 | cpumask_set_cpu(cpu_id, data->affinity); | 329 | cpumask_set_cpu(cpu_id, mask); |
328 | } | 330 | } |
329 | /* We need to operate irq_affinity_online atomically. */ | 331 | /* We need to operate irq_affinity_online atomically. */ |
330 | arch_local_cli_save(flags); | 332 | arch_local_cli_save(flags); |
@@ -335,8 +337,7 @@ void migrate_irqs(void) | |||
335 | GxICR(irq) = x & GxICR_LEVEL; | 337 | GxICR(irq) = x & GxICR_LEVEL; |
336 | tmp = GxICR(irq); | 338 | tmp = GxICR(irq); |
337 | 339 | ||
338 | new = cpumask_any_and(data->affinity, | 340 | new = cpumask_any_and(mask, cpu_online_mask); |
339 | cpu_online_mask); | ||
340 | irq_affinity_online[irq] = new; | 341 | irq_affinity_online[irq] = new; |
341 | 342 | ||
342 | CROSS_GxICR(irq, new) = | 343 | CROSS_GxICR(irq, new) = |
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index f3191db6e2e9..413ec3c3f9cc 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c | |||
@@ -131,7 +131,7 @@ static int cpu_set_affinity_irq(struct irq_data *d, const struct cpumask *dest, | |||
131 | if (cpu_dest < 0) | 131 | if (cpu_dest < 0) |
132 | return -1; | 132 | return -1; |
133 | 133 | ||
134 | cpumask_copy(d->affinity, dest); | 134 | cpumask_copy(irq_data_get_affinity_mask(d), dest); |
135 | 135 | ||
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
@@ -339,7 +339,7 @@ unsigned long txn_affinity_addr(unsigned int irq, int cpu) | |||
339 | { | 339 | { |
340 | #ifdef CONFIG_SMP | 340 | #ifdef CONFIG_SMP |
341 | struct irq_data *d = irq_get_irq_data(irq); | 341 | struct irq_data *d = irq_get_irq_data(irq); |
342 | cpumask_copy(d->affinity, cpumask_of(cpu)); | 342 | cpumask_copy(irq_data_get_affinity_mask(d), cpumask_of(cpu)); |
343 | #endif | 343 | #endif |
344 | 344 | ||
345 | return per_cpu(cpu_data, cpu).txn_addr; | 345 | return per_cpu(cpu_data, cpu).txn_addr; |
@@ -508,7 +508,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) | |||
508 | unsigned long eirr_val; | 508 | unsigned long eirr_val; |
509 | int irq, cpu = smp_processor_id(); | 509 | int irq, cpu = smp_processor_id(); |
510 | #ifdef CONFIG_SMP | 510 | #ifdef CONFIG_SMP |
511 | struct irq_desc *desc; | 511 | struct irq_data *irq_data; |
512 | cpumask_t dest; | 512 | cpumask_t dest; |
513 | #endif | 513 | #endif |
514 | 514 | ||
@@ -522,9 +522,9 @@ void do_cpu_irq_mask(struct pt_regs *regs) | |||
522 | irq = eirr_to_irq(eirr_val); | 522 | irq = eirr_to_irq(eirr_val); |
523 | 523 | ||
524 | #ifdef CONFIG_SMP | 524 | #ifdef CONFIG_SMP |
525 | desc = irq_to_desc(irq); | 525 | irq_data = irq_get_irq_data(irq); |
526 | cpumask_copy(&dest, desc->irq_data.affinity); | 526 | cpumask_copy(&dest, irq_data_get_affinity_mask(irq_data)); |
527 | if (irqd_is_per_cpu(&desc->irq_data) && | 527 | if (irqd_is_per_cpu(irq_data) && |
528 | !cpumask_test_cpu(smp_processor_id(), &dest)) { | 528 | !cpumask_test_cpu(smp_processor_id(), &dest)) { |
529 | int cpu = cpumask_first(&dest); | 529 | int cpu = cpumask_first(&dest); |
530 | 530 | ||
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c index ca3a062ed1b9..11090ab4bf59 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c | |||
@@ -123,7 +123,8 @@ cpld_pic_cascade(unsigned int irq, struct irq_desc *desc) | |||
123 | } | 123 | } |
124 | 124 | ||
125 | static int | 125 | static int |
126 | cpld_pic_host_match(struct irq_domain *h, struct device_node *node) | 126 | cpld_pic_host_match(struct irq_domain *h, struct device_node *node, |
127 | enum irq_domain_bus_token bus_token) | ||
127 | { | 128 | { |
128 | return cpld_pic_node == node; | 129 | return cpld_pic_node == node; |
129 | } | 130 | } |
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index fe51de4fcf13..306888acb737 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c | |||
@@ -213,7 +213,7 @@ static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg) | |||
213 | return -ENODEV; | 213 | return -ENODEV; |
214 | } | 214 | } |
215 | 215 | ||
216 | entry = list_first_entry(&dev->msi_list, struct msi_desc, list); | 216 | entry = first_pci_msi_entry(dev); |
217 | 217 | ||
218 | for (; dn; dn = of_get_next_parent(dn)) { | 218 | for (; dn; dn = of_get_next_parent(dn)) { |
219 | if (entry->msi_attrib.is_64) { | 219 | if (entry->msi_attrib.is_64) { |
@@ -269,7 +269,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
269 | if (rc) | 269 | if (rc) |
270 | return rc; | 270 | return rc; |
271 | 271 | ||
272 | list_for_each_entry(entry, &dev->msi_list, list) { | 272 | for_each_pci_msi_entry(entry, dev) { |
273 | virq = irq_create_direct_mapping(msic->irq_domain); | 273 | virq = irq_create_direct_mapping(msic->irq_domain); |
274 | if (virq == NO_IRQ) { | 274 | if (virq == NO_IRQ) { |
275 | dev_warn(&dev->dev, | 275 | dev_warn(&dev->dev, |
@@ -292,7 +292,7 @@ static void axon_msi_teardown_msi_irqs(struct pci_dev *dev) | |||
292 | 292 | ||
293 | dev_dbg(&dev->dev, "axon_msi: tearing down msi irqs\n"); | 293 | dev_dbg(&dev->dev, "axon_msi: tearing down msi irqs\n"); |
294 | 294 | ||
295 | list_for_each_entry(entry, &dev->msi_list, list) { | 295 | for_each_pci_msi_entry(entry, dev) { |
296 | if (entry->irq == NO_IRQ) | 296 | if (entry->irq == NO_IRQ) |
297 | continue; | 297 | continue; |
298 | 298 | ||
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 3af8324c122e..a15f1efc295f 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c | |||
@@ -222,7 +222,8 @@ void iic_request_IPIs(void) | |||
222 | #endif /* CONFIG_SMP */ | 222 | #endif /* CONFIG_SMP */ |
223 | 223 | ||
224 | 224 | ||
225 | static int iic_host_match(struct irq_domain *h, struct device_node *node) | 225 | static int iic_host_match(struct irq_domain *h, struct device_node *node, |
226 | enum irq_domain_bus_token bus_token) | ||
226 | { | 227 | { |
227 | return of_device_is_compatible(node, | 228 | return of_device_is_compatible(node, |
228 | "IBM,CBEA-Internal-Interrupt-Controller"); | 229 | "IBM,CBEA-Internal-Interrupt-Controller"); |
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c index 4cde8e7da4b8..b7866e01483d 100644 --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c | |||
@@ -108,7 +108,8 @@ static int flipper_pic_map(struct irq_domain *h, unsigned int virq, | |||
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
110 | 110 | ||
111 | static int flipper_pic_match(struct irq_domain *h, struct device_node *np) | 111 | static int flipper_pic_match(struct irq_domain *h, struct device_node *np, |
112 | enum irq_domain_bus_token bus_token) | ||
112 | { | 113 | { |
113 | return 1; | 114 | return 1; |
114 | } | 115 | } |
diff --git a/arch/powerpc/platforms/pasemi/msi.c b/arch/powerpc/platforms/pasemi/msi.c index 27f2b187a91b..e66ef1943338 100644 --- a/arch/powerpc/platforms/pasemi/msi.c +++ b/arch/powerpc/platforms/pasemi/msi.c | |||
@@ -66,7 +66,7 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev) | |||
66 | 66 | ||
67 | pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev); | 67 | pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev); |
68 | 68 | ||
69 | list_for_each_entry(entry, &pdev->msi_list, list) { | 69 | for_each_pci_msi_entry(entry, pdev) { |
70 | if (entry->irq == NO_IRQ) | 70 | if (entry->irq == NO_IRQ) |
71 | continue; | 71 | continue; |
72 | 72 | ||
@@ -94,7 +94,7 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
94 | msg.address_hi = 0; | 94 | msg.address_hi = 0; |
95 | msg.address_lo = PASEMI_MSI_ADDR; | 95 | msg.address_lo = PASEMI_MSI_ADDR; |
96 | 96 | ||
97 | list_for_each_entry(entry, &pdev->msi_list, list) { | 97 | for_each_pci_msi_entry(entry, pdev) { |
98 | /* Allocate 16 interrupts for now, since that's the grouping for | 98 | /* Allocate 16 interrupts for now, since that's the grouping for |
99 | * affinity. This can be changed later if it turns out 32 is too | 99 | * affinity. This can be changed later if it turns out 32 is too |
100 | * few MSIs for someone, but restrictions will apply to how the | 100 | * few MSIs for someone, but restrictions will apply to how the |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 59cfc9d63c2d..6f4f8b060def 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
@@ -268,7 +268,8 @@ static struct irqaction gatwick_cascade_action = { | |||
268 | .name = "cascade", | 268 | .name = "cascade", |
269 | }; | 269 | }; |
270 | 270 | ||
271 | static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node) | 271 | static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node, |
272 | enum irq_domain_bus_token bus_token) | ||
272 | { | 273 | { |
273 | /* We match all, we don't always have a node anyway */ | 274 | /* We match all, we don't always have a node anyway */ |
274 | return 1; | 275 | return 1; |
diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c index e2e7d75f52f3..2c91ee7800b9 100644 --- a/arch/powerpc/platforms/powernv/opal-irqchip.c +++ b/arch/powerpc/platforms/powernv/opal-irqchip.c | |||
@@ -134,7 +134,8 @@ static void opal_handle_irq_work(struct irq_work *work) | |||
134 | opal_handle_events(be64_to_cpu(last_outstanding_events)); | 134 | opal_handle_events(be64_to_cpu(last_outstanding_events)); |
135 | } | 135 | } |
136 | 136 | ||
137 | static int opal_event_match(struct irq_domain *h, struct device_node *node) | 137 | static int opal_event_match(struct irq_domain *h, struct device_node *node, |
138 | enum irq_domain_bus_token bus_token) | ||
138 | { | 139 | { |
139 | return h->of_node == node; | 140 | return h->of_node == node; |
140 | } | 141 | } |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 765d8ed558d0..bc6d4e02e29c 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -61,7 +61,7 @@ int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
61 | if (pdev->no_64bit_msi && !phb->msi32_support) | 61 | if (pdev->no_64bit_msi && !phb->msi32_support) |
62 | return -ENODEV; | 62 | return -ENODEV; |
63 | 63 | ||
64 | list_for_each_entry(entry, &pdev->msi_list, list) { | 64 | for_each_pci_msi_entry(entry, pdev) { |
65 | if (!entry->msi_attrib.is_64 && !phb->msi32_support) { | 65 | if (!entry->msi_attrib.is_64 && !phb->msi32_support) { |
66 | pr_warn("%s: Supports only 64-bit MSIs\n", | 66 | pr_warn("%s: Supports only 64-bit MSIs\n", |
67 | pci_name(pdev)); | 67 | pci_name(pdev)); |
@@ -103,7 +103,7 @@ void pnv_teardown_msi_irqs(struct pci_dev *pdev) | |||
103 | if (WARN_ON(!phb)) | 103 | if (WARN_ON(!phb)) |
104 | return; | 104 | return; |
105 | 105 | ||
106 | list_for_each_entry(entry, &pdev->msi_list, list) { | 106 | for_each_pci_msi_entry(entry, pdev) { |
107 | if (entry->irq == NO_IRQ) | 107 | if (entry->irq == NO_IRQ) |
108 | continue; | 108 | continue; |
109 | irq_set_msi_desc(entry->irq, NULL); | 109 | irq_set_msi_desc(entry->irq, NULL); |
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index a6c42f34303a..638c4060938e 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c | |||
@@ -678,7 +678,8 @@ static int ps3_host_map(struct irq_domain *h, unsigned int virq, | |||
678 | return 0; | 678 | return 0; |
679 | } | 679 | } |
680 | 680 | ||
681 | static int ps3_host_match(struct irq_domain *h, struct device_node *np) | 681 | static int ps3_host_match(struct irq_domain *h, struct device_node *np, |
682 | enum irq_domain_bus_token bus_token) | ||
682 | { | 683 | { |
683 | /* Match all */ | 684 | /* Match all */ |
684 | return 1; | 685 | return 1; |
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index c22bb647cce6..272e9ec1ab54 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c | |||
@@ -118,7 +118,7 @@ static void rtas_teardown_msi_irqs(struct pci_dev *pdev) | |||
118 | { | 118 | { |
119 | struct msi_desc *entry; | 119 | struct msi_desc *entry; |
120 | 120 | ||
121 | list_for_each_entry(entry, &pdev->msi_list, list) { | 121 | for_each_pci_msi_entry(entry, pdev) { |
122 | if (entry->irq == NO_IRQ) | 122 | if (entry->irq == NO_IRQ) |
123 | continue; | 123 | continue; |
124 | 124 | ||
@@ -350,7 +350,7 @@ static int check_msix_entries(struct pci_dev *pdev) | |||
350 | * So we must reject such requests. */ | 350 | * So we must reject such requests. */ |
351 | 351 | ||
352 | expected = 0; | 352 | expected = 0; |
353 | list_for_each_entry(entry, &pdev->msi_list, list) { | 353 | for_each_pci_msi_entry(entry, pdev) { |
354 | if (entry->msi_attrib.entry_nr != expected) { | 354 | if (entry->msi_attrib.entry_nr != expected) { |
355 | pr_debug("rtas_msi: bad MSI-X entries.\n"); | 355 | pr_debug("rtas_msi: bad MSI-X entries.\n"); |
356 | return -EINVAL; | 356 | return -EINVAL; |
@@ -462,7 +462,7 @@ again: | |||
462 | } | 462 | } |
463 | 463 | ||
464 | i = 0; | 464 | i = 0; |
465 | list_for_each_entry(entry, &pdev->msi_list, list) { | 465 | for_each_pci_msi_entry(entry, pdev) { |
466 | hwirq = rtas_query_irq_number(pdn, i++); | 466 | hwirq = rtas_query_irq_number(pdn, i++); |
467 | if (hwirq < 0) { | 467 | if (hwirq < 0) { |
468 | pr_debug("rtas_msi: error (%d) getting hwirq\n", rc); | 468 | pr_debug("rtas_msi: error (%d) getting hwirq\n", rc); |
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c index 2d20f10a4203..eca0b00794fa 100644 --- a/arch/powerpc/sysdev/ehv_pic.c +++ b/arch/powerpc/sysdev/ehv_pic.c | |||
@@ -177,7 +177,8 @@ unsigned int ehv_pic_get_irq(void) | |||
177 | return irq_linear_revmap(global_ehv_pic->irqhost, irq); | 177 | return irq_linear_revmap(global_ehv_pic->irqhost, irq); |
178 | } | 178 | } |
179 | 179 | ||
180 | static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node) | 180 | static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node, |
181 | enum irq_domain_bus_token bus_token) | ||
181 | { | 182 | { |
182 | /* Exact match, unless ehv_pic node is NULL */ | 183 | /* Exact match, unless ehv_pic node is NULL */ |
183 | return h->of_node == NULL || h->of_node == node; | 184 | return h->of_node == NULL || h->of_node == node; |
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 5236e5427c38..5916da1856a7 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
@@ -129,7 +129,7 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev) | |||
129 | struct msi_desc *entry; | 129 | struct msi_desc *entry; |
130 | struct fsl_msi *msi_data; | 130 | struct fsl_msi *msi_data; |
131 | 131 | ||
132 | list_for_each_entry(entry, &pdev->msi_list, list) { | 132 | for_each_pci_msi_entry(entry, pdev) { |
133 | if (entry->irq == NO_IRQ) | 133 | if (entry->irq == NO_IRQ) |
134 | continue; | 134 | continue; |
135 | msi_data = irq_get_chip_data(entry->irq); | 135 | msi_data = irq_get_chip_data(entry->irq); |
@@ -219,7 +219,7 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | list_for_each_entry(entry, &pdev->msi_list, list) { | 222 | for_each_pci_msi_entry(entry, pdev) { |
223 | /* | 223 | /* |
224 | * Loop over all the MSI devices until we find one that has an | 224 | * Loop over all the MSI devices until we find one that has an |
225 | * available interrupt. | 225 | * available interrupt. |
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index 31c33475c7b7..e1a9c2c2d5d3 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c | |||
@@ -162,7 +162,8 @@ static struct resource pic_edgectrl_iores = { | |||
162 | .flags = IORESOURCE_BUSY, | 162 | .flags = IORESOURCE_BUSY, |
163 | }; | 163 | }; |
164 | 164 | ||
165 | static int i8259_host_match(struct irq_domain *h, struct device_node *node) | 165 | static int i8259_host_match(struct irq_domain *h, struct device_node *node, |
166 | enum irq_domain_bus_token bus_token) | ||
166 | { | 167 | { |
167 | return h->of_node == NULL || h->of_node == node; | 168 | return h->of_node == NULL || h->of_node == node; |
168 | } | 169 | } |
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index d78f1364b639..6b2b68914810 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c | |||
@@ -671,7 +671,8 @@ static struct irq_chip ipic_edge_irq_chip = { | |||
671 | .irq_set_type = ipic_set_irq_type, | 671 | .irq_set_type = ipic_set_irq_type, |
672 | }; | 672 | }; |
673 | 673 | ||
674 | static int ipic_host_match(struct irq_domain *h, struct device_node *node) | 674 | static int ipic_host_match(struct irq_domain *h, struct device_node *node, |
675 | enum irq_domain_bus_token bus_token) | ||
675 | { | 676 | { |
676 | /* Exact match, unless ipic node is NULL */ | 677 | /* Exact match, unless ipic node is NULL */ |
677 | return h->of_node == NULL || h->of_node == node; | 678 | return h->of_node == NULL || h->of_node == node; |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index c8e73332eaad..97a8ae8f94dd 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -1007,7 +1007,8 @@ static struct irq_chip mpic_irq_ht_chip = { | |||
1007 | #endif /* CONFIG_MPIC_U3_HT_IRQS */ | 1007 | #endif /* CONFIG_MPIC_U3_HT_IRQS */ |
1008 | 1008 | ||
1009 | 1009 | ||
1010 | static int mpic_host_match(struct irq_domain *h, struct device_node *node) | 1010 | static int mpic_host_match(struct irq_domain *h, struct device_node *node, |
1011 | enum irq_domain_bus_token bus_token) | ||
1011 | { | 1012 | { |
1012 | /* Exact match, unless mpic node is NULL */ | 1013 | /* Exact match, unless mpic node is NULL */ |
1013 | return h->of_node == NULL || h->of_node == node; | 1014 | return h->of_node == NULL || h->of_node == node; |
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c index fc46ef3b816e..70fbd5694a8b 100644 --- a/arch/powerpc/sysdev/mpic_u3msi.c +++ b/arch/powerpc/sysdev/mpic_u3msi.c | |||
@@ -108,7 +108,7 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev) | |||
108 | { | 108 | { |
109 | struct msi_desc *entry; | 109 | struct msi_desc *entry; |
110 | 110 | ||
111 | list_for_each_entry(entry, &pdev->msi_list, list) { | 111 | for_each_pci_msi_entry(entry, pdev) { |
112 | if (entry->irq == NO_IRQ) | 112 | if (entry->irq == NO_IRQ) |
113 | continue; | 113 | continue; |
114 | 114 | ||
@@ -140,7 +140,7 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
140 | return -ENXIO; | 140 | return -ENXIO; |
141 | } | 141 | } |
142 | 142 | ||
143 | list_for_each_entry(entry, &pdev->msi_list, list) { | 143 | for_each_pci_msi_entry(entry, pdev) { |
144 | hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1); | 144 | hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1); |
145 | if (hwirq < 0) { | 145 | if (hwirq < 0) { |
146 | pr_debug("u3msi: failed allocating hwirq\n"); | 146 | pr_debug("u3msi: failed allocating hwirq\n"); |
diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c index 87f9623ca805..af3c144b92c1 100644 --- a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c | |||
@@ -51,7 +51,7 @@ static int hsta_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
51 | return -EINVAL; | 51 | return -EINVAL; |
52 | } | 52 | } |
53 | 53 | ||
54 | list_for_each_entry(entry, &dev->msi_list, list) { | 54 | for_each_pci_msi_entry(entry, dev) { |
55 | irq = msi_bitmap_alloc_hwirqs(&ppc4xx_hsta_msi.bmp, 1); | 55 | irq = msi_bitmap_alloc_hwirqs(&ppc4xx_hsta_msi.bmp, 1); |
56 | if (irq < 0) { | 56 | if (irq < 0) { |
57 | pr_debug("%s: Failed to allocate msi interrupt\n", | 57 | pr_debug("%s: Failed to allocate msi interrupt\n", |
@@ -109,7 +109,7 @@ static void hsta_teardown_msi_irqs(struct pci_dev *dev) | |||
109 | struct msi_desc *entry; | 109 | struct msi_desc *entry; |
110 | int irq; | 110 | int irq; |
111 | 111 | ||
112 | list_for_each_entry(entry, &dev->msi_list, list) { | 112 | for_each_pci_msi_entry(entry, dev) { |
113 | if (entry->irq == NO_IRQ) | 113 | if (entry->irq == NO_IRQ) |
114 | continue; | 114 | continue; |
115 | 115 | ||
diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c index 6eb21f2ea585..24d0470c1698 100644 --- a/arch/powerpc/sysdev/ppc4xx_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_msi.c | |||
@@ -93,7 +93,7 @@ static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
93 | if (!msi_data->msi_virqs) | 93 | if (!msi_data->msi_virqs) |
94 | return -ENOMEM; | 94 | return -ENOMEM; |
95 | 95 | ||
96 | list_for_each_entry(entry, &dev->msi_list, list) { | 96 | for_each_pci_msi_entry(entry, dev) { |
97 | int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); | 97 | int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); |
98 | if (int_no >= 0) | 98 | if (int_no >= 0) |
99 | break; | 99 | break; |
@@ -127,7 +127,7 @@ void ppc4xx_teardown_msi_irqs(struct pci_dev *dev) | |||
127 | 127 | ||
128 | dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n"); | 128 | dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n"); |
129 | 129 | ||
130 | list_for_each_entry(entry, &dev->msi_list, list) { | 130 | for_each_pci_msi_entry(entry, dev) { |
131 | if (entry->irq == NO_IRQ) | 131 | if (entry->irq == NO_IRQ) |
132 | continue; | 132 | continue; |
133 | irq_set_msi_desc(entry->irq, NULL); | 133 | irq_set_msi_desc(entry->irq, NULL); |
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index 6512cd8caa51..47b352e4bc74 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c | |||
@@ -244,7 +244,8 @@ static struct irq_chip qe_ic_irq_chip = { | |||
244 | .irq_mask_ack = qe_ic_mask_irq, | 244 | .irq_mask_ack = qe_ic_mask_irq, |
245 | }; | 245 | }; |
246 | 246 | ||
247 | static int qe_ic_host_match(struct irq_domain *h, struct device_node *node) | 247 | static int qe_ic_host_match(struct irq_domain *h, struct device_node *node, |
248 | enum irq_domain_bus_token bus_token) | ||
248 | { | 249 | { |
249 | /* Exact match, unless qe_ic node is NULL */ | 250 | /* Exact match, unless qe_ic node is NULL */ |
250 | return h->of_node == NULL || h->of_node == node; | 251 | return h->of_node == NULL || h->of_node == node; |
diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c index 68c7e5cc98e0..11ac964d5175 100644 --- a/arch/powerpc/sysdev/xics/ics-opal.c +++ b/arch/powerpc/sysdev/xics/ics-opal.c | |||
@@ -72,7 +72,7 @@ static unsigned int ics_opal_startup(struct irq_data *d) | |||
72 | * card, using the MSI mask bits. Firmware doesn't appear to unmask | 72 | * card, using the MSI mask bits. Firmware doesn't appear to unmask |
73 | * at that level, so we do it here by hand. | 73 | * at that level, so we do it here by hand. |
74 | */ | 74 | */ |
75 | if (d->msi_desc) | 75 | if (irq_data_get_msi_desc(d)) |
76 | pci_msi_unmask_irq(d); | 76 | pci_msi_unmask_irq(d); |
77 | #endif | 77 | #endif |
78 | 78 | ||
diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c index 0af97deb83f3..d1c625c4cc5a 100644 --- a/arch/powerpc/sysdev/xics/ics-rtas.c +++ b/arch/powerpc/sysdev/xics/ics-rtas.c | |||
@@ -75,7 +75,7 @@ static unsigned int ics_rtas_startup(struct irq_data *d) | |||
75 | * card, using the MSI mask bits. Firmware doesn't appear to unmask | 75 | * card, using the MSI mask bits. Firmware doesn't appear to unmask |
76 | * at that level, so we do it here by hand. | 76 | * at that level, so we do it here by hand. |
77 | */ | 77 | */ |
78 | if (d->msi_desc) | 78 | if (irq_data_get_msi_desc(d)) |
79 | pci_msi_unmask_irq(d); | 79 | pci_msi_unmask_irq(d); |
80 | #endif | 80 | #endif |
81 | /* unmask it */ | 81 | /* unmask it */ |
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index 08c248eb491b..47e43b7b076b 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c | |||
@@ -298,7 +298,8 @@ int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask, | |||
298 | } | 298 | } |
299 | #endif /* CONFIG_SMP */ | 299 | #endif /* CONFIG_SMP */ |
300 | 300 | ||
301 | static int xics_host_match(struct irq_domain *h, struct device_node *node) | 301 | static int xics_host_match(struct irq_domain *h, struct device_node *node, |
302 | enum irq_domain_bus_token bus_token) | ||
302 | { | 303 | { |
303 | struct ics *ics; | 304 | struct ics *ics; |
304 | 305 | ||
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 17c04c7269e7..7ef12a3ace3a 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -409,7 +409,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
409 | 409 | ||
410 | /* Request MSI interrupts */ | 410 | /* Request MSI interrupts */ |
411 | hwirq = 0; | 411 | hwirq = 0; |
412 | list_for_each_entry(msi, &pdev->msi_list, list) { | 412 | for_each_pci_msi_entry(msi, pdev) { |
413 | rc = -EIO; | 413 | rc = -EIO; |
414 | irq = irq_alloc_desc(0); /* Alloc irq on node 0 */ | 414 | irq = irq_alloc_desc(0); /* Alloc irq on node 0 */ |
415 | if (irq < 0) | 415 | if (irq < 0) |
@@ -435,7 +435,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
435 | return (msi_vecs == nvec) ? 0 : msi_vecs; | 435 | return (msi_vecs == nvec) ? 0 : msi_vecs; |
436 | 436 | ||
437 | out_msi: | 437 | out_msi: |
438 | list_for_each_entry(msi, &pdev->msi_list, list) { | 438 | for_each_pci_msi_entry(msi, pdev) { |
439 | if (hwirq-- == 0) | 439 | if (hwirq-- == 0) |
440 | break; | 440 | break; |
441 | irq_set_msi_desc(msi->irq, NULL); | 441 | irq_set_msi_desc(msi->irq, NULL); |
@@ -465,7 +465,7 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev) | |||
465 | return; | 465 | return; |
466 | 466 | ||
467 | /* Release MSI interrupts */ | 467 | /* Release MSI interrupts */ |
468 | list_for_each_entry(msi, &pdev->msi_list, list) { | 468 | for_each_pci_msi_entry(msi, pdev) { |
469 | if (msi->msi_attrib.is_msix) | 469 | if (msi->msi_attrib.is_msix) |
470 | __pci_msix_desc_mask_irq(msi, 1); | 470 | __pci_msix_desc_mask_irq(msi, 1); |
471 | else | 471 | else |
diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c index 1087dba9b015..6f97a8f0d0d6 100644 --- a/arch/sh/boards/mach-se/7343/irq.c +++ b/arch/sh/boards/mach-se/7343/irq.c | |||
@@ -31,7 +31,7 @@ struct irq_domain *se7343_irq_domain; | |||
31 | 31 | ||
32 | static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) | 32 | static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) |
33 | { | 33 | { |
34 | struct irq_data *data = irq_get_irq_data(irq); | 34 | struct irq_data *data = irq_desc_get_irq_data(desc); |
35 | struct irq_chip *chip = irq_data_get_irq_chip(data); | 35 | struct irq_chip *chip = irq_data_get_irq_chip(data); |
36 | unsigned long mask; | 36 | unsigned long mask; |
37 | int bit; | 37 | int bit; |
diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c index 00e699232621..60aebd14ccf8 100644 --- a/arch/sh/boards/mach-se/7722/irq.c +++ b/arch/sh/boards/mach-se/7722/irq.c | |||
@@ -30,7 +30,7 @@ struct irq_domain *se7722_irq_domain; | |||
30 | 30 | ||
31 | static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) | 31 | static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) |
32 | { | 32 | { |
33 | struct irq_data *data = irq_get_irq_data(irq); | 33 | struct irq_data *data = irq_desc_get_irq_data(desc); |
34 | struct irq_chip *chip = irq_data_get_irq_chip(data); | 34 | struct irq_chip *chip = irq_data_get_irq_chip(data); |
35 | unsigned long mask; | 35 | unsigned long mask; |
36 | int bit; | 36 | int bit; |
diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c index 5d1d3ec9a6cd..9f2033898652 100644 --- a/arch/sh/boards/mach-se/7724/irq.c +++ b/arch/sh/boards/mach-se/7724/irq.c | |||
@@ -92,8 +92,9 @@ static struct irq_chip se7724_irq_chip __read_mostly = { | |||
92 | .irq_unmask = enable_se7724_irq, | 92 | .irq_unmask = enable_se7724_irq, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc) | 95 | static void se7724_irq_demux(unsigned int __irq, struct irq_desc *desc) |
96 | { | 96 | { |
97 | unsigned int irq = irq_desc_get_irq(desc); | ||
97 | struct fpga_irq set = get_fpga_irq(irq); | 98 | struct fpga_irq set = get_fpga_irq(irq); |
98 | unsigned short intv = __raw_readw(set.sraddr); | 99 | unsigned short intv = __raw_readw(set.sraddr); |
99 | unsigned int ext_irq = set.base; | 100 | unsigned int ext_irq = set.base; |
diff --git a/arch/sh/boards/mach-x3proto/gpio.c b/arch/sh/boards/mach-x3proto/gpio.c index f035a7ac6456..24555c364d5b 100644 --- a/arch/sh/boards/mach-x3proto/gpio.c +++ b/arch/sh/boards/mach-x3proto/gpio.c | |||
@@ -62,7 +62,7 @@ static int x3proto_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) | |||
62 | 62 | ||
63 | static void x3proto_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 63 | static void x3proto_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) |
64 | { | 64 | { |
65 | struct irq_data *data = irq_get_irq_data(irq); | 65 | struct irq_data *data = irq_desc_get_irq_data(desc); |
66 | struct irq_chip *chip = irq_data_get_irq_chip(data); | 66 | struct irq_chip *chip = irq_data_get_irq_chip(data); |
67 | unsigned long mask; | 67 | unsigned long mask; |
68 | int pin; | 68 | int pin; |
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index eb10ff84015c..6c0378c0b8b5 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c | |||
@@ -227,16 +227,17 @@ void migrate_irqs(void) | |||
227 | for_each_active_irq(irq) { | 227 | for_each_active_irq(irq) { |
228 | struct irq_data *data = irq_get_irq_data(irq); | 228 | struct irq_data *data = irq_get_irq_data(irq); |
229 | 229 | ||
230 | if (data->node == cpu) { | 230 | if (irq_data_get_node(data) == cpu) { |
231 | unsigned int newcpu = cpumask_any_and(data->affinity, | 231 | struct cpumask *mask = irq_data_get_affinity_mask(data); |
232 | unsigned int newcpu = cpumask_any_and(mask, | ||
232 | cpu_online_mask); | 233 | cpu_online_mask); |
233 | if (newcpu >= nr_cpu_ids) { | 234 | if (newcpu >= nr_cpu_ids) { |
234 | pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n", | 235 | pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n", |
235 | irq, cpu); | 236 | irq, cpu); |
236 | 237 | ||
237 | cpumask_setall(data->affinity); | 238 | cpumask_setall(mask); |
238 | } | 239 | } |
239 | irq_set_affinity(irq, data->affinity); | 240 | irq_set_affinity(irq, mask); |
240 | } | 241 | } |
241 | } | 242 | } |
242 | } | 243 | } |
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 4033c23bdfa6..e22416ce56ea 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
@@ -210,21 +210,21 @@ struct irq_handler_data { | |||
210 | 210 | ||
211 | static inline unsigned int irq_data_to_handle(struct irq_data *data) | 211 | static inline unsigned int irq_data_to_handle(struct irq_data *data) |
212 | { | 212 | { |
213 | struct irq_handler_data *ihd = data->handler_data; | 213 | struct irq_handler_data *ihd = irq_data_get_irq_handler_data(data); |
214 | 214 | ||
215 | return ihd->dev_handle; | 215 | return ihd->dev_handle; |
216 | } | 216 | } |
217 | 217 | ||
218 | static inline unsigned int irq_data_to_ino(struct irq_data *data) | 218 | static inline unsigned int irq_data_to_ino(struct irq_data *data) |
219 | { | 219 | { |
220 | struct irq_handler_data *ihd = data->handler_data; | 220 | struct irq_handler_data *ihd = irq_data_get_irq_handler_data(data); |
221 | 221 | ||
222 | return ihd->dev_ino; | 222 | return ihd->dev_ino; |
223 | } | 223 | } |
224 | 224 | ||
225 | static inline unsigned long irq_data_to_sysino(struct irq_data *data) | 225 | static inline unsigned long irq_data_to_sysino(struct irq_data *data) |
226 | { | 226 | { |
227 | struct irq_handler_data *ihd = data->handler_data; | 227 | struct irq_handler_data *ihd = irq_data_get_irq_handler_data(data); |
228 | 228 | ||
229 | return ihd->sysino; | 229 | return ihd->sysino; |
230 | } | 230 | } |
@@ -370,13 +370,15 @@ static int irq_choose_cpu(unsigned int irq, const struct cpumask *affinity) | |||
370 | 370 | ||
371 | static void sun4u_irq_enable(struct irq_data *data) | 371 | static void sun4u_irq_enable(struct irq_data *data) |
372 | { | 372 | { |
373 | struct irq_handler_data *handler_data = data->handler_data; | 373 | struct irq_handler_data *handler_data; |
374 | 374 | ||
375 | handler_data = irq_data_get_irq_handler_data(data); | ||
375 | if (likely(handler_data)) { | 376 | if (likely(handler_data)) { |
376 | unsigned long cpuid, imap, val; | 377 | unsigned long cpuid, imap, val; |
377 | unsigned int tid; | 378 | unsigned int tid; |
378 | 379 | ||
379 | cpuid = irq_choose_cpu(data->irq, data->affinity); | 380 | cpuid = irq_choose_cpu(data->irq, |
381 | irq_data_get_affinity_mask(data)); | ||
380 | imap = handler_data->imap; | 382 | imap = handler_data->imap; |
381 | 383 | ||
382 | tid = sun4u_compute_tid(imap, cpuid); | 384 | tid = sun4u_compute_tid(imap, cpuid); |
@@ -393,8 +395,9 @@ static void sun4u_irq_enable(struct irq_data *data) | |||
393 | static int sun4u_set_affinity(struct irq_data *data, | 395 | static int sun4u_set_affinity(struct irq_data *data, |
394 | const struct cpumask *mask, bool force) | 396 | const struct cpumask *mask, bool force) |
395 | { | 397 | { |
396 | struct irq_handler_data *handler_data = data->handler_data; | 398 | struct irq_handler_data *handler_data; |
397 | 399 | ||
400 | handler_data = irq_data_get_irq_handler_data(data); | ||
398 | if (likely(handler_data)) { | 401 | if (likely(handler_data)) { |
399 | unsigned long cpuid, imap, val; | 402 | unsigned long cpuid, imap, val; |
400 | unsigned int tid; | 403 | unsigned int tid; |
@@ -438,15 +441,17 @@ static void sun4u_irq_disable(struct irq_data *data) | |||
438 | 441 | ||
439 | static void sun4u_irq_eoi(struct irq_data *data) | 442 | static void sun4u_irq_eoi(struct irq_data *data) |
440 | { | 443 | { |
441 | struct irq_handler_data *handler_data = data->handler_data; | 444 | struct irq_handler_data *handler_data; |
442 | 445 | ||
446 | handler_data = irq_data_get_irq_handler_data(data); | ||
443 | if (likely(handler_data)) | 447 | if (likely(handler_data)) |
444 | upa_writeq(ICLR_IDLE, handler_data->iclr); | 448 | upa_writeq(ICLR_IDLE, handler_data->iclr); |
445 | } | 449 | } |
446 | 450 | ||
447 | static void sun4v_irq_enable(struct irq_data *data) | 451 | static void sun4v_irq_enable(struct irq_data *data) |
448 | { | 452 | { |
449 | unsigned long cpuid = irq_choose_cpu(data->irq, data->affinity); | 453 | unsigned long cpuid = irq_choose_cpu(data->irq, |
454 | irq_data_get_affinity_mask(data)); | ||
450 | unsigned int ino = irq_data_to_sysino(data); | 455 | unsigned int ino = irq_data_to_sysino(data); |
451 | int err; | 456 | int err; |
452 | 457 | ||
@@ -508,7 +513,7 @@ static void sun4v_virq_enable(struct irq_data *data) | |||
508 | unsigned long cpuid; | 513 | unsigned long cpuid; |
509 | int err; | 514 | int err; |
510 | 515 | ||
511 | cpuid = irq_choose_cpu(data->irq, data->affinity); | 516 | cpuid = irq_choose_cpu(data->irq, irq_data_get_affinity_mask(data)); |
512 | 517 | ||
513 | err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); | 518 | err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); |
514 | if (err != HV_EOK) | 519 | if (err != HV_EOK) |
@@ -881,8 +886,8 @@ void fixup_irqs(void) | |||
881 | if (desc->action && !irqd_is_per_cpu(data)) { | 886 | if (desc->action && !irqd_is_per_cpu(data)) { |
882 | if (data->chip->irq_set_affinity) | 887 | if (data->chip->irq_set_affinity) |
883 | data->chip->irq_set_affinity(data, | 888 | data->chip->irq_set_affinity(data, |
884 | data->affinity, | 889 | irq_data_get_affinity_mask(data), |
885 | false); | 890 | false); |
886 | } | 891 | } |
887 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 892 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
888 | } | 893 | } |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 9bbb8f2bbfcc..0299f052a2ef 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
@@ -126,7 +126,7 @@ static int leon_set_affinity(struct irq_data *data, const struct cpumask *dest, | |||
126 | int oldcpu, newcpu; | 126 | int oldcpu, newcpu; |
127 | 127 | ||
128 | mask = (unsigned long)data->chip_data; | 128 | mask = (unsigned long)data->chip_data; |
129 | oldcpu = irq_choose_cpu(data->affinity); | 129 | oldcpu = irq_choose_cpu(irq_data_get_affinity_mask(data)); |
130 | newcpu = irq_choose_cpu(dest); | 130 | newcpu = irq_choose_cpu(dest); |
131 | 131 | ||
132 | if (oldcpu == newcpu) | 132 | if (oldcpu == newcpu) |
@@ -149,7 +149,7 @@ static void leon_unmask_irq(struct irq_data *data) | |||
149 | int cpu; | 149 | int cpu; |
150 | 150 | ||
151 | mask = (unsigned long)data->chip_data; | 151 | mask = (unsigned long)data->chip_data; |
152 | cpu = irq_choose_cpu(data->affinity); | 152 | cpu = irq_choose_cpu(irq_data_get_affinity_mask(data)); |
153 | spin_lock_irqsave(&leon_irq_lock, flags); | 153 | spin_lock_irqsave(&leon_irq_lock, flags); |
154 | oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu)); | 154 | oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu)); |
155 | LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask | mask)); | 155 | LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask | mask)); |
@@ -162,7 +162,7 @@ static void leon_mask_irq(struct irq_data *data) | |||
162 | int cpu; | 162 | int cpu; |
163 | 163 | ||
164 | mask = (unsigned long)data->chip_data; | 164 | mask = (unsigned long)data->chip_data; |
165 | cpu = irq_choose_cpu(data->affinity); | 165 | cpu = irq_choose_cpu(irq_data_get_affinity_mask(data)); |
166 | spin_lock_irqsave(&leon_irq_lock, flags); | 166 | spin_lock_irqsave(&leon_irq_lock, flags); |
167 | oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu)); | 167 | oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu)); |
168 | LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask & ~mask)); | 168 | LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask & ~mask)); |
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 3a0e1a986bfe..3a14a35592fe 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -914,7 +914,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) | |||
914 | void arch_teardown_msi_irq(unsigned int irq) | 914 | void arch_teardown_msi_irq(unsigned int irq) |
915 | { | 915 | { |
916 | struct msi_desc *entry = irq_get_msi_desc(irq); | 916 | struct msi_desc *entry = irq_get_msi_desc(irq); |
917 | struct pci_dev *pdev = entry->dev; | 917 | struct pci_dev *pdev = msi_desc_to_pci_dev(entry); |
918 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; | 918 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; |
919 | 919 | ||
920 | if (pbm->teardown_msi_irq) | 920 | if (pbm->teardown_msi_irq) |
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index a1bb2675b280..a87d0e47c168 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c | |||
@@ -188,7 +188,7 @@ void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs) | |||
188 | 188 | ||
189 | static void sun4d_mask_irq(struct irq_data *data) | 189 | static void sun4d_mask_irq(struct irq_data *data) |
190 | { | 190 | { |
191 | struct sun4d_handler_data *handler_data = data->handler_data; | 191 | struct sun4d_handler_data *handler_data = irq_data_get_irq_handler_data(data); |
192 | unsigned int real_irq; | 192 | unsigned int real_irq; |
193 | #ifdef CONFIG_SMP | 193 | #ifdef CONFIG_SMP |
194 | int cpuid = handler_data->cpuid; | 194 | int cpuid = handler_data->cpuid; |
@@ -206,7 +206,7 @@ static void sun4d_mask_irq(struct irq_data *data) | |||
206 | 206 | ||
207 | static void sun4d_unmask_irq(struct irq_data *data) | 207 | static void sun4d_unmask_irq(struct irq_data *data) |
208 | { | 208 | { |
209 | struct sun4d_handler_data *handler_data = data->handler_data; | 209 | struct sun4d_handler_data *handler_data = irq_data_get_irq_handler_data(data); |
210 | unsigned int real_irq; | 210 | unsigned int real_irq; |
211 | #ifdef CONFIG_SMP | 211 | #ifdef CONFIG_SMP |
212 | int cpuid = handler_data->cpuid; | 212 | int cpuid = handler_data->cpuid; |
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 8bb3b3fddea7..da737c712fa8 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c | |||
@@ -188,9 +188,10 @@ static unsigned long sun4m_imask[0x50] = { | |||
188 | 188 | ||
189 | static void sun4m_mask_irq(struct irq_data *data) | 189 | static void sun4m_mask_irq(struct irq_data *data) |
190 | { | 190 | { |
191 | struct sun4m_handler_data *handler_data = data->handler_data; | 191 | struct sun4m_handler_data *handler_data; |
192 | int cpu = smp_processor_id(); | 192 | int cpu = smp_processor_id(); |
193 | 193 | ||
194 | handler_data = irq_data_get_irq_handler_data(data); | ||
194 | if (handler_data->mask) { | 195 | if (handler_data->mask) { |
195 | unsigned long flags; | 196 | unsigned long flags; |
196 | 197 | ||
@@ -206,9 +207,10 @@ static void sun4m_mask_irq(struct irq_data *data) | |||
206 | 207 | ||
207 | static void sun4m_unmask_irq(struct irq_data *data) | 208 | static void sun4m_unmask_irq(struct irq_data *data) |
208 | { | 209 | { |
209 | struct sun4m_handler_data *handler_data = data->handler_data; | 210 | struct sun4m_handler_data *handler_data; |
210 | int cpu = smp_processor_id(); | 211 | int cpu = smp_processor_id(); |
211 | 212 | ||
213 | handler_data = irq_data_get_irq_handler_data(data); | ||
212 | if (handler_data->mask) { | 214 | if (handler_data->mask) { |
213 | unsigned long flags; | 215 | unsigned long flags; |
214 | 216 | ||
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index b1df847d0686..b3f73fd764a3 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c | |||
@@ -304,11 +304,12 @@ static struct irq_chip tilegx_legacy_irq_chip = { | |||
304 | * to Linux which just calls handle_level_irq() after clearing the | 304 | * to Linux which just calls handle_level_irq() after clearing the |
305 | * MAC INTx Assert status bit associated with this interrupt. | 305 | * MAC INTx Assert status bit associated with this interrupt. |
306 | */ | 306 | */ |
307 | static void trio_handle_level_irq(unsigned int irq, struct irq_desc *desc) | 307 | static void trio_handle_level_irq(unsigned int __irq, struct irq_desc *desc) |
308 | { | 308 | { |
309 | struct pci_controller *controller = irq_desc_get_handler_data(desc); | 309 | struct pci_controller *controller = irq_desc_get_handler_data(desc); |
310 | gxio_trio_context_t *trio_context = controller->trio; | 310 | gxio_trio_context_t *trio_context = controller->trio; |
311 | uint64_t intx = (uint64_t)irq_desc_get_chip_data(desc); | 311 | uint64_t intx = (uint64_t)irq_desc_get_chip_data(desc); |
312 | unsigned int irq = irq_desc_get_irq(desc); | ||
312 | int mac = controller->mac; | 313 | int mac = controller->mac; |
313 | unsigned int reg_offset; | 314 | unsigned int reg_offset; |
314 | uint64_t level_mask; | 315 | uint64_t level_mask; |
@@ -1442,7 +1443,7 @@ static struct pci_ops tile_cfg_ops = { | |||
1442 | /* MSI support starts here. */ | 1443 | /* MSI support starts here. */ |
1443 | static unsigned int tilegx_msi_startup(struct irq_data *d) | 1444 | static unsigned int tilegx_msi_startup(struct irq_data *d) |
1444 | { | 1445 | { |
1445 | if (d->msi_desc) | 1446 | if (irq_data_get_msi_desc(d)) |
1446 | pci_msi_unmask_irq(d); | 1447 | pci_msi_unmask_irq(d); |
1447 | 1448 | ||
1448 | return 0; | 1449 | return 0; |
diff --git a/arch/unicore32/kernel/irq.c b/arch/unicore32/kernel/irq.c index 0be5ccd7ccd2..c53729d92e8d 100644 --- a/arch/unicore32/kernel/irq.c +++ b/arch/unicore32/kernel/irq.c | |||
@@ -112,10 +112,9 @@ static struct irq_chip puv3_low_gpio_chip = { | |||
112 | * irq_controller_lock held, and IRQs disabled. Decode the IRQ | 112 | * irq_controller_lock held, and IRQs disabled. Decode the IRQ |
113 | * and call the handler. | 113 | * and call the handler. |
114 | */ | 114 | */ |
115 | static void | 115 | static void puv3_gpio_handler(unsigned int __irq, struct irq_desc *desc) |
116 | puv3_gpio_handler(unsigned int irq, struct irq_desc *desc) | ||
117 | { | 116 | { |
118 | unsigned int mask; | 117 | unsigned int mask, irq; |
119 | 118 | ||
120 | mask = readl(GPIO_GEDR); | 119 | mask = readl(GPIO_GEDR); |
121 | do { | 120 | do { |
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index d22f4b5bbc04..ff31ab464213 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c | |||
@@ -179,7 +179,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
179 | if (ret) | 179 | if (ret) |
180 | goto error; | 180 | goto error; |
181 | i = 0; | 181 | i = 0; |
182 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 182 | for_each_pci_msi_entry(msidesc, dev) { |
183 | irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], | 183 | irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], |
184 | (type == PCI_CAP_ID_MSI) ? nvec : 1, | 184 | (type == PCI_CAP_ID_MSI) ? nvec : 1, |
185 | (type == PCI_CAP_ID_MSIX) ? | 185 | (type == PCI_CAP_ID_MSIX) ? |
@@ -230,7 +230,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
230 | if (type == PCI_CAP_ID_MSI && nvec > 1) | 230 | if (type == PCI_CAP_ID_MSI && nvec > 1) |
231 | return 1; | 231 | return 1; |
232 | 232 | ||
233 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 233 | for_each_pci_msi_entry(msidesc, dev) { |
234 | __pci_read_msi_msg(msidesc, &msg); | 234 | __pci_read_msi_msg(msidesc, &msg); |
235 | pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) | | 235 | pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) | |
236 | ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff); | 236 | ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff); |
@@ -274,7 +274,7 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
274 | int ret = 0; | 274 | int ret = 0; |
275 | struct msi_desc *msidesc; | 275 | struct msi_desc *msidesc; |
276 | 276 | ||
277 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 277 | for_each_pci_msi_entry(msidesc, dev) { |
278 | struct physdev_map_pirq map_irq; | 278 | struct physdev_map_pirq map_irq; |
279 | domid_t domid; | 279 | domid_t domid; |
280 | 280 | ||
@@ -386,7 +386,7 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev) | |||
386 | { | 386 | { |
387 | struct msi_desc *msidesc; | 387 | struct msi_desc *msidesc; |
388 | 388 | ||
389 | msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); | 389 | msidesc = first_pci_msi_entry(dev); |
390 | if (msidesc->msi_attrib.is_msix) | 390 | if (msidesc->msi_attrib.is_msix) |
391 | xen_pci_frontend_disable_msix(dev); | 391 | xen_pci_frontend_disable_msix(dev); |
392 | else | 392 | else |
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index 6df31cacc4b8..4ac3d23161cf 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c | |||
@@ -177,23 +177,25 @@ void migrate_irqs(void) | |||
177 | 177 | ||
178 | for_each_active_irq(i) { | 178 | for_each_active_irq(i) { |
179 | struct irq_data *data = irq_get_irq_data(i); | 179 | struct irq_data *data = irq_get_irq_data(i); |
180 | struct cpumask *mask; | ||
180 | unsigned int newcpu; | 181 | unsigned int newcpu; |
181 | 182 | ||
182 | if (irqd_is_per_cpu(data)) | 183 | if (irqd_is_per_cpu(data)) |
183 | continue; | 184 | continue; |
184 | 185 | ||
185 | if (!cpumask_test_cpu(cpu, data->affinity)) | 186 | mask = irq_data_get_affinity_mask(data); |
187 | if (!cpumask_test_cpu(cpu, mask)) | ||
186 | continue; | 188 | continue; |
187 | 189 | ||
188 | newcpu = cpumask_any_and(data->affinity, cpu_online_mask); | 190 | newcpu = cpumask_any_and(mask, cpu_online_mask); |
189 | 191 | ||
190 | if (newcpu >= nr_cpu_ids) { | 192 | if (newcpu >= nr_cpu_ids) { |
191 | pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n", | 193 | pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n", |
192 | i, cpu); | 194 | i, cpu); |
193 | 195 | ||
194 | cpumask_setall(data->affinity); | 196 | cpumask_setall(mask); |
195 | } | 197 | } |
196 | irq_set_affinity(i, data->affinity); | 198 | irq_set_affinity(i, mask); |
197 | } | 199 | } |
198 | } | 200 | } |
199 | #endif /* CONFIG_HOTPLUG_CPU */ | 201 | #endif /* CONFIG_HOTPLUG_CPU */ |
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 527d291706e8..6b2a84e7f2be 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_REGMAP) += regmap/ | |||
22 | obj-$(CONFIG_SOC_BUS) += soc.o | 22 | obj-$(CONFIG_SOC_BUS) += soc.o |
23 | obj-$(CONFIG_PINCTRL) += pinctrl.o | 23 | obj-$(CONFIG_PINCTRL) += pinctrl.o |
24 | obj-$(CONFIG_DEV_COREDUMP) += devcoredump.o | 24 | obj-$(CONFIG_DEV_COREDUMP) += devcoredump.o |
25 | obj-$(CONFIG_GENERIC_MSI_IRQ_DOMAIN) += platform-msi.o | ||
25 | 26 | ||
26 | ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG | 27 | ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG |
27 | 28 | ||
diff --git a/drivers/base/core.c b/drivers/base/core.c index fc5a558f62f9..f6947d0abc2f 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -708,6 +708,9 @@ void device_initialize(struct device *dev) | |||
708 | INIT_LIST_HEAD(&dev->devres_head); | 708 | INIT_LIST_HEAD(&dev->devres_head); |
709 | device_pm_init(dev); | 709 | device_pm_init(dev); |
710 | set_dev_node(dev, -1); | 710 | set_dev_node(dev, -1); |
711 | #ifdef CONFIG_GENERIC_MSI_IRQ | ||
712 | INIT_LIST_HEAD(&dev->msi_list); | ||
713 | #endif | ||
711 | } | 714 | } |
712 | EXPORT_SYMBOL_GPL(device_initialize); | 715 | EXPORT_SYMBOL_GPL(device_initialize); |
713 | 716 | ||
diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c new file mode 100644 index 000000000000..1857a5dd0816 --- /dev/null +++ b/drivers/base/platform-msi.c | |||
@@ -0,0 +1,282 @@ | |||
1 | /* | ||
2 | * MSI framework for platform devices | ||
3 | * | ||
4 | * Copyright (C) 2015 ARM Limited, All Rights Reserved. | ||
5 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/device.h> | ||
21 | #include <linux/idr.h> | ||
22 | #include <linux/irq.h> | ||
23 | #include <linux/irqdomain.h> | ||
24 | #include <linux/msi.h> | ||
25 | #include <linux/slab.h> | ||
26 | |||
27 | #define DEV_ID_SHIFT 24 | ||
28 | |||
29 | /* | ||
30 | * Internal data structure containing a (made up, but unique) devid | ||
31 | * and the callback to write the MSI message. | ||
32 | */ | ||
33 | struct platform_msi_priv_data { | ||
34 | irq_write_msi_msg_t write_msg; | ||
35 | int devid; | ||
36 | }; | ||
37 | |||
38 | /* The devid allocator */ | ||
39 | static DEFINE_IDA(platform_msi_devid_ida); | ||
40 | |||
41 | #ifdef GENERIC_MSI_DOMAIN_OPS | ||
42 | /* | ||
43 | * Convert an msi_desc to a globaly unique identifier (per-device | ||
44 | * devid + msi_desc position in the msi_list). | ||
45 | */ | ||
46 | static irq_hw_number_t platform_msi_calc_hwirq(struct msi_desc *desc) | ||
47 | { | ||
48 | u32 devid; | ||
49 | |||
50 | devid = desc->platform.msi_priv_data->devid; | ||
51 | |||
52 | return (devid << (32 - DEV_ID_SHIFT)) | desc->platform.msi_index; | ||
53 | } | ||
54 | |||
55 | static void platform_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc) | ||
56 | { | ||
57 | arg->desc = desc; | ||
58 | arg->hwirq = platform_msi_calc_hwirq(desc); | ||
59 | } | ||
60 | |||
61 | static int platform_msi_init(struct irq_domain *domain, | ||
62 | struct msi_domain_info *info, | ||
63 | unsigned int virq, irq_hw_number_t hwirq, | ||
64 | msi_alloc_info_t *arg) | ||
65 | { | ||
66 | struct irq_data *data; | ||
67 | |||
68 | irq_domain_set_hwirq_and_chip(domain, virq, hwirq, | ||
69 | info->chip, info->chip_data); | ||
70 | |||
71 | /* | ||
72 | * Save the MSI descriptor in handler_data so that the | ||
73 | * irq_write_msi_msg callback can retrieve it (and the | ||
74 | * associated device). | ||
75 | */ | ||
76 | data = irq_domain_get_irq_data(domain, virq); | ||
77 | data->handler_data = arg->desc; | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | #else | ||
82 | #define platform_msi_set_desc NULL | ||
83 | #define platform_msi_init NULL | ||
84 | #endif | ||
85 | |||
86 | static void platform_msi_update_dom_ops(struct msi_domain_info *info) | ||
87 | { | ||
88 | struct msi_domain_ops *ops = info->ops; | ||
89 | |||
90 | BUG_ON(!ops); | ||
91 | |||
92 | if (ops->msi_init == NULL) | ||
93 | ops->msi_init = platform_msi_init; | ||
94 | if (ops->set_desc == NULL) | ||
95 | ops->set_desc = platform_msi_set_desc; | ||
96 | } | ||
97 | |||
98 | static void platform_msi_write_msg(struct irq_data *data, struct msi_msg *msg) | ||
99 | { | ||
100 | struct msi_desc *desc = irq_data_get_irq_handler_data(data); | ||
101 | struct platform_msi_priv_data *priv_data; | ||
102 | |||
103 | priv_data = desc->platform.msi_priv_data; | ||
104 | |||
105 | priv_data->write_msg(desc, msg); | ||
106 | } | ||
107 | |||
108 | static void platform_msi_update_chip_ops(struct msi_domain_info *info) | ||
109 | { | ||
110 | struct irq_chip *chip = info->chip; | ||
111 | |||
112 | BUG_ON(!chip); | ||
113 | if (!chip->irq_mask) | ||
114 | chip->irq_mask = irq_chip_mask_parent; | ||
115 | if (!chip->irq_unmask) | ||
116 | chip->irq_unmask = irq_chip_unmask_parent; | ||
117 | if (!chip->irq_eoi) | ||
118 | chip->irq_eoi = irq_chip_eoi_parent; | ||
119 | if (!chip->irq_set_affinity) | ||
120 | chip->irq_set_affinity = msi_domain_set_affinity; | ||
121 | if (!chip->irq_write_msi_msg) | ||
122 | chip->irq_write_msi_msg = platform_msi_write_msg; | ||
123 | } | ||
124 | |||
125 | static void platform_msi_free_descs(struct device *dev) | ||
126 | { | ||
127 | struct msi_desc *desc, *tmp; | ||
128 | |||
129 | list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) { | ||
130 | list_del(&desc->list); | ||
131 | free_msi_entry(desc); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | static int platform_msi_alloc_descs(struct device *dev, int nvec, | ||
136 | struct platform_msi_priv_data *data) | ||
137 | |||
138 | { | ||
139 | int i; | ||
140 | |||
141 | for (i = 0; i < nvec; i++) { | ||
142 | struct msi_desc *desc; | ||
143 | |||
144 | desc = alloc_msi_entry(dev); | ||
145 | if (!desc) | ||
146 | break; | ||
147 | |||
148 | desc->platform.msi_priv_data = data; | ||
149 | desc->platform.msi_index = i; | ||
150 | desc->nvec_used = 1; | ||
151 | |||
152 | list_add_tail(&desc->list, dev_to_msi_list(dev)); | ||
153 | } | ||
154 | |||
155 | if (i != nvec) { | ||
156 | /* Clean up the mess */ | ||
157 | platform_msi_free_descs(dev); | ||
158 | |||
159 | return -ENOMEM; | ||
160 | } | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * platform_msi_create_irq_domain - Create a platform MSI interrupt domain | ||
167 | * @np: Optional device-tree node of the interrupt controller | ||
168 | * @info: MSI domain info | ||
169 | * @parent: Parent irq domain | ||
170 | * | ||
171 | * Updates the domain and chip ops and creates a platform MSI | ||
172 | * interrupt domain. | ||
173 | * | ||
174 | * Returns: | ||
175 | * A domain pointer or NULL in case of failure. | ||
176 | */ | ||
177 | struct irq_domain *platform_msi_create_irq_domain(struct device_node *np, | ||
178 | struct msi_domain_info *info, | ||
179 | struct irq_domain *parent) | ||
180 | { | ||
181 | struct irq_domain *domain; | ||
182 | |||
183 | if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS) | ||
184 | platform_msi_update_dom_ops(info); | ||
185 | if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) | ||
186 | platform_msi_update_chip_ops(info); | ||
187 | |||
188 | domain = msi_create_irq_domain(np, info, parent); | ||
189 | if (domain) | ||
190 | domain->bus_token = DOMAIN_BUS_PLATFORM_MSI; | ||
191 | |||
192 | return domain; | ||
193 | } | ||
194 | |||
195 | /** | ||
196 | * platform_msi_domain_alloc_irqs - Allocate MSI interrupts for @dev | ||
197 | * @dev: The device for which to allocate interrupts | ||
198 | * @nvec: The number of interrupts to allocate | ||
199 | * @write_msi_msg: Callback to write an interrupt message for @dev | ||
200 | * | ||
201 | * Returns: | ||
202 | * Zero for success, or an error code in case of failure | ||
203 | */ | ||
204 | int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec, | ||
205 | irq_write_msi_msg_t write_msi_msg) | ||
206 | { | ||
207 | struct platform_msi_priv_data *priv_data; | ||
208 | int err; | ||
209 | |||
210 | /* | ||
211 | * Limit the number of interrupts to 256 per device. Should we | ||
212 | * need to bump this up, DEV_ID_SHIFT should be adjusted | ||
213 | * accordingly (which would impact the max number of MSI | ||
214 | * capable devices). | ||
215 | */ | ||
216 | if (!dev->msi_domain || !write_msi_msg || !nvec || | ||
217 | nvec > (1 << (32 - DEV_ID_SHIFT))) | ||
218 | return -EINVAL; | ||
219 | |||
220 | if (dev->msi_domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) { | ||
221 | dev_err(dev, "Incompatible msi_domain, giving up\n"); | ||
222 | return -EINVAL; | ||
223 | } | ||
224 | |||
225 | /* Already had a helping of MSI? Greed... */ | ||
226 | if (!list_empty(dev_to_msi_list(dev))) | ||
227 | return -EBUSY; | ||
228 | |||
229 | priv_data = kzalloc(sizeof(*priv_data), GFP_KERNEL); | ||
230 | if (!priv_data) | ||
231 | return -ENOMEM; | ||
232 | |||
233 | priv_data->devid = ida_simple_get(&platform_msi_devid_ida, | ||
234 | 0, 1 << DEV_ID_SHIFT, GFP_KERNEL); | ||
235 | if (priv_data->devid < 0) { | ||
236 | err = priv_data->devid; | ||
237 | goto out_free_data; | ||
238 | } | ||
239 | |||
240 | priv_data->write_msg = write_msi_msg; | ||
241 | |||
242 | err = platform_msi_alloc_descs(dev, nvec, priv_data); | ||
243 | if (err) | ||
244 | goto out_free_id; | ||
245 | |||
246 | err = msi_domain_alloc_irqs(dev->msi_domain, dev, nvec); | ||
247 | if (err) | ||
248 | goto out_free_desc; | ||
249 | |||
250 | return 0; | ||
251 | |||
252 | out_free_desc: | ||
253 | platform_msi_free_descs(dev); | ||
254 | out_free_id: | ||
255 | ida_simple_remove(&platform_msi_devid_ida, priv_data->devid); | ||
256 | out_free_data: | ||
257 | kfree(priv_data); | ||
258 | |||
259 | return err; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * platform_msi_domain_free_irqs - Free MSI interrupts for @dev | ||
264 | * @dev: The device for which to free interrupts | ||
265 | */ | ||
266 | void platform_msi_domain_free_irqs(struct device *dev) | ||
267 | { | ||
268 | struct msi_desc *desc; | ||
269 | |||
270 | desc = first_msi_entry(dev); | ||
271 | if (desc) { | ||
272 | struct platform_msi_priv_data *data; | ||
273 | |||
274 | data = desc->platform.msi_priv_data; | ||
275 | |||
276 | ida_simple_remove(&platform_msi_devid_ida, data->devid); | ||
277 | kfree(data); | ||
278 | } | ||
279 | |||
280 | msi_domain_free_irqs(dev->msi_domain, dev); | ||
281 | platform_msi_free_descs(dev); | ||
282 | } | ||
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 120d81543e53..27b52c8729cd 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig | |||
@@ -61,6 +61,10 @@ config ATMEL_AIC5_IRQ | |||
61 | select MULTI_IRQ_HANDLER | 61 | select MULTI_IRQ_HANDLER |
62 | select SPARSE_IRQ | 62 | select SPARSE_IRQ |
63 | 63 | ||
64 | config I8259 | ||
65 | bool | ||
66 | select IRQ_DOMAIN | ||
67 | |||
64 | config BCM7038_L1_IRQ | 68 | config BCM7038_L1_IRQ |
65 | bool | 69 | bool |
66 | select GENERIC_IRQ_CHIP | 70 | select GENERIC_IRQ_CHIP |
@@ -177,3 +181,9 @@ config RENESAS_H8300H_INTC | |||
177 | config RENESAS_H8S_INTC | 181 | config RENESAS_H8S_INTC |
178 | bool | 182 | bool |
179 | select IRQ_DOMAIN | 183 | select IRQ_DOMAIN |
184 | |||
185 | config IMX_GPCV2 | ||
186 | bool | ||
187 | select IRQ_DOMAIN | ||
188 | help | ||
189 | Enables the wakeup IRQs for IMX platforms with GPCv2 block | ||
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index b8d4e9691890..bb3048f00e64 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | obj-$(CONFIG_IRQCHIP) += irqchip.o | 1 | obj-$(CONFIG_IRQCHIP) += irqchip.o |
2 | 2 | ||
3 | obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o | 3 | obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o |
4 | obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o | ||
4 | obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o | 5 | obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o |
5 | obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o | 6 | obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o |
6 | obj-$(CONFIG_ARCH_MMP) += irq-mmp.o | 7 | obj-$(CONFIG_ARCH_MMP) += irq-mmp.o |
@@ -22,11 +23,12 @@ obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o | |||
22 | obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o | 23 | obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o |
23 | obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o | 24 | obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o |
24 | obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o | 25 | obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o |
25 | obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o | 26 | obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o |
26 | obj-$(CONFIG_ARM_NVIC) += irq-nvic.o | 27 | obj-$(CONFIG_ARM_NVIC) += irq-nvic.o |
27 | obj-$(CONFIG_ARM_VIC) += irq-vic.o | 28 | obj-$(CONFIG_ARM_VIC) += irq-vic.o |
28 | obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o | 29 | obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o |
29 | obj-$(CONFIG_ATMEL_AIC5_IRQ) += irq-atmel-aic-common.o irq-atmel-aic5.o | 30 | obj-$(CONFIG_ATMEL_AIC5_IRQ) += irq-atmel-aic-common.o irq-atmel-aic5.o |
31 | obj-$(CONFIG_I8259) += irq-i8259.o | ||
30 | obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o | 32 | obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o |
31 | obj-$(CONFIG_IRQ_MIPS_CPU) += irq-mips-cpu.o | 33 | obj-$(CONFIG_IRQ_MIPS_CPU) += irq-mips-cpu.o |
32 | obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o | 34 | obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o |
@@ -52,3 +54,4 @@ obj-$(CONFIG_RENESAS_H8300H_INTC) += irq-renesas-h8300h.o | |||
52 | obj-$(CONFIG_RENESAS_H8S_INTC) += irq-renesas-h8s.o | 54 | obj-$(CONFIG_RENESAS_H8S_INTC) += irq-renesas-h8s.o |
53 | obj-$(CONFIG_ARCH_SA1100) += irq-sa11x0.o | 55 | obj-$(CONFIG_ARCH_SA1100) += irq-sa11x0.o |
54 | obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o | 56 | obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o |
57 | obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o | ||
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index 5c82e3bdafdf..e9c6f2a5b52d 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c | |||
@@ -15,13 +15,12 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/syscore_ops.h> | 16 | #include <linux/syscore_ops.h> |
17 | #include <linux/irqdomain.h> | 17 | #include <linux/irqdomain.h> |
18 | #include <linux/irqchip.h> | ||
18 | #include <linux/irqchip/chained_irq.h> | 19 | #include <linux/irqchip/chained_irq.h> |
19 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
20 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
21 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
22 | 23 | ||
23 | #include "irqchip.h" | ||
24 | |||
25 | #define COMBINER_ENABLE_SET 0x0 | 24 | #define COMBINER_ENABLE_SET 0x0 |
26 | #define COMBINER_ENABLE_CLEAR 0x4 | 25 | #define COMBINER_ENABLE_CLEAR 0x4 |
27 | #define COMBINER_INT_STATUS 0xC | 26 | #define COMBINER_INT_STATUS 0xC |
@@ -66,10 +65,12 @@ static void combiner_unmask_irq(struct irq_data *data) | |||
66 | __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET); | 65 | __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET); |
67 | } | 66 | } |
68 | 67 | ||
69 | static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | 68 | static void combiner_handle_cascade_irq(unsigned int __irq, |
69 | struct irq_desc *desc) | ||
70 | { | 70 | { |
71 | struct combiner_chip_data *chip_data = irq_get_handler_data(irq); | 71 | struct combiner_chip_data *chip_data = irq_desc_get_handler_data(desc); |
72 | struct irq_chip *chip = irq_get_chip(irq); | 72 | struct irq_chip *chip = irq_desc_get_chip(desc); |
73 | unsigned int irq = irq_desc_get_irq(desc); | ||
73 | unsigned int cascade_irq, combiner_irq; | 74 | unsigned int cascade_irq, combiner_irq; |
74 | unsigned long status; | 75 | unsigned long status; |
75 | 76 | ||
@@ -122,9 +123,8 @@ static struct irq_chip combiner_chip = { | |||
122 | static void __init combiner_cascade_irq(struct combiner_chip_data *combiner_data, | 123 | static void __init combiner_cascade_irq(struct combiner_chip_data *combiner_data, |
123 | unsigned int irq) | 124 | unsigned int irq) |
124 | { | 125 | { |
125 | if (irq_set_handler_data(irq, combiner_data) != 0) | 126 | irq_set_chained_handler_and_data(irq, combiner_handle_cascade_irq, |
126 | BUG(); | 127 | combiner_data); |
127 | irq_set_chained_handler(irq, combiner_handle_cascade_irq); | ||
128 | } | 128 | } |
129 | 129 | ||
130 | static void __init combiner_init_one(struct combiner_chip_data *combiner_data, | 130 | static void __init combiner_init_one(struct combiner_chip_data *combiner_data, |
@@ -185,14 +185,14 @@ static void __init combiner_init(void __iomem *combiner_base, | |||
185 | 185 | ||
186 | combiner_data = kcalloc(max_nr, sizeof (*combiner_data), GFP_KERNEL); | 186 | combiner_data = kcalloc(max_nr, sizeof (*combiner_data), GFP_KERNEL); |
187 | if (!combiner_data) { | 187 | if (!combiner_data) { |
188 | pr_warning("%s: could not allocate combiner data\n", __func__); | 188 | pr_warn("%s: could not allocate combiner data\n", __func__); |
189 | return; | 189 | return; |
190 | } | 190 | } |
191 | 191 | ||
192 | combiner_irq_domain = irq_domain_add_linear(np, nr_irq, | 192 | combiner_irq_domain = irq_domain_add_linear(np, nr_irq, |
193 | &combiner_irq_domain_ops, combiner_data); | 193 | &combiner_irq_domain_ops, combiner_data); |
194 | if (WARN_ON(!combiner_irq_domain)) { | 194 | if (WARN_ON(!combiner_irq_domain)) { |
195 | pr_warning("%s: irq domain init failed\n", __func__); | 195 | pr_warn("%s: irq domain init failed\n", __func__); |
196 | return; | 196 | return; |
197 | } | 197 | } |
198 | 198 | ||
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 0d3b0fe2f175..39b72da0c143 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/irqchip.h> | ||
21 | #include <linux/irqchip/chained_irq.h> | 22 | #include <linux/irqchip/chained_irq.h> |
22 | #include <linux/cpu.h> | 23 | #include <linux/cpu.h> |
23 | #include <linux/io.h> | 24 | #include <linux/io.h> |
@@ -33,8 +34,6 @@ | |||
33 | #include <asm/smp_plat.h> | 34 | #include <asm/smp_plat.h> |
34 | #include <asm/mach/irq.h> | 35 | #include <asm/mach/irq.h> |
35 | 36 | ||
36 | #include "irqchip.h" | ||
37 | |||
38 | /* Interrupt Controller Registers Map */ | 37 | /* Interrupt Controller Registers Map */ |
39 | #define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) | 38 | #define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) |
40 | #define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C) | 39 | #define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C) |
@@ -451,7 +450,7 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *r, bool b) {} | |||
451 | static void armada_370_xp_mpic_handle_cascade_irq(unsigned int irq, | 450 | static void armada_370_xp_mpic_handle_cascade_irq(unsigned int irq, |
452 | struct irq_desc *desc) | 451 | struct irq_desc *desc) |
453 | { | 452 | { |
454 | struct irq_chip *chip = irq_get_chip(irq); | 453 | struct irq_chip *chip = irq_desc_get_chip(desc); |
455 | unsigned long irqmap, irqn, irqsrc, cpuid; | 454 | unsigned long irqmap, irqn, irqsrc, cpuid; |
456 | unsigned int cascade_irq; | 455 | unsigned int cascade_irq; |
457 | 456 | ||
diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c index dae3604b32a9..8a0c7f288198 100644 --- a/drivers/irqchip/irq-atmel-aic.c +++ b/drivers/irqchip/irq-atmel-aic.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/bitmap.h> | 19 | #include <linux/bitmap.h> |
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/irqchip.h> | ||
22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
23 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
24 | #include <linux/of_irq.h> | 25 | #include <linux/of_irq.h> |
@@ -31,7 +32,6 @@ | |||
31 | #include <asm/mach/irq.h> | 32 | #include <asm/mach/irq.h> |
32 | 33 | ||
33 | #include "irq-atmel-aic-common.h" | 34 | #include "irq-atmel-aic-common.h" |
34 | #include "irqchip.h" | ||
35 | 35 | ||
36 | /* Number of irq lines managed by AIC */ | 36 | /* Number of irq lines managed by AIC */ |
37 | #define NR_AIC_IRQS 32 | 37 | #define NR_AIC_IRQS 32 |
@@ -225,7 +225,7 @@ static void __init at91sam9g45_aic_irq_fixup(struct device_node *root) | |||
225 | aic_common_rtt_irq_fixup(root); | 225 | aic_common_rtt_irq_fixup(root); |
226 | } | 226 | } |
227 | 227 | ||
228 | static const struct of_device_id __initdata aic_irq_fixups[] = { | 228 | static const struct of_device_id aic_irq_fixups[] __initconst = { |
229 | { .compatible = "atmel,at91rm9200", .data = at91rm9200_aic_irq_fixup }, | 229 | { .compatible = "atmel,at91rm9200", .data = at91rm9200_aic_irq_fixup }, |
230 | { .compatible = "atmel,at91sam9g45", .data = at91sam9g45_aic_irq_fixup }, | 230 | { .compatible = "atmel,at91sam9g45", .data = at91sam9g45_aic_irq_fixup }, |
231 | { .compatible = "atmel,at91sam9n12", .data = at91rm9200_aic_irq_fixup }, | 231 | { .compatible = "atmel,at91sam9n12", .data = at91rm9200_aic_irq_fixup }, |
diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 459bf4429d36..9da9942ac83c 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/bitmap.h> | 19 | #include <linux/bitmap.h> |
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/irqchip.h> | ||
22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
23 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
24 | #include <linux/of_irq.h> | 25 | #include <linux/of_irq.h> |
@@ -31,7 +32,6 @@ | |||
31 | #include <asm/mach/irq.h> | 32 | #include <asm/mach/irq.h> |
32 | 33 | ||
33 | #include "irq-atmel-aic-common.h" | 34 | #include "irq-atmel-aic-common.h" |
34 | #include "irqchip.h" | ||
35 | 35 | ||
36 | /* Number of irq lines managed by AIC */ | 36 | /* Number of irq lines managed by AIC */ |
37 | #define NR_AIC5_IRQS 128 | 37 | #define NR_AIC5_IRQS 128 |
@@ -290,7 +290,7 @@ static void __init sama5d3_aic_irq_fixup(struct device_node *root) | |||
290 | aic_common_rtc_irq_fixup(root); | 290 | aic_common_rtc_irq_fixup(root); |
291 | } | 291 | } |
292 | 292 | ||
293 | static const struct of_device_id __initdata aic5_irq_fixups[] = { | 293 | static const struct of_device_id aic5_irq_fixups[] __initconst = { |
294 | { .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup }, | 294 | { .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup }, |
295 | { .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup }, | 295 | { .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup }, |
296 | { /* sentinel */ }, | 296 | { /* sentinel */ }, |
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c index e68c3b60a681..ed4ca9deca70 100644 --- a/drivers/irqchip/irq-bcm2835.c +++ b/drivers/irqchip/irq-bcm2835.c | |||
@@ -48,13 +48,12 @@ | |||
48 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
49 | #include <linux/of_address.h> | 49 | #include <linux/of_address.h> |
50 | #include <linux/of_irq.h> | 50 | #include <linux/of_irq.h> |
51 | #include <linux/irqchip.h> | ||
51 | #include <linux/irqdomain.h> | 52 | #include <linux/irqdomain.h> |
52 | 53 | ||
53 | #include <asm/exception.h> | 54 | #include <asm/exception.h> |
54 | #include <asm/mach/irq.h> | 55 | #include <asm/mach/irq.h> |
55 | 56 | ||
56 | #include "irqchip.h" | ||
57 | |||
58 | /* Put the bank and irq (32 bits) into the hwirq */ | 57 | /* Put the bank and irq (32 bits) into the hwirq */ |
59 | #define MAKE_HWIRQ(b, n) ((b << 5) | (n)) | 58 | #define MAKE_HWIRQ(b, n) ((b << 5) | (n)) |
60 | #define HWIRQ_BANK(i) (i >> 5) | 59 | #define HWIRQ_BANK(i) (i >> 5) |
@@ -76,10 +75,10 @@ | |||
76 | #define NR_BANKS 3 | 75 | #define NR_BANKS 3 |
77 | #define IRQS_PER_BANK 32 | 76 | #define IRQS_PER_BANK 32 |
78 | 77 | ||
79 | static int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; | 78 | static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; |
80 | static int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; | 79 | static const int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; |
81 | static int reg_disable[] __initconst = { 0x24, 0x1c, 0x20 }; | 80 | static const int reg_disable[] __initconst = { 0x24, 0x1c, 0x20 }; |
82 | static int bank_irqs[] __initconst = { 8, 32, 32 }; | 81 | static const int bank_irqs[] __initconst = { 8, 32, 32 }; |
83 | 82 | ||
84 | static const int shortcuts[] = { | 83 | static const int shortcuts[] = { |
85 | 7, 9, 10, 18, 19, /* Bank 1 */ | 84 | 7, 9, 10, 18, 19, /* Bank 1 */ |
@@ -97,6 +96,7 @@ struct armctrl_ic { | |||
97 | static struct armctrl_ic intc __read_mostly; | 96 | static struct armctrl_ic intc __read_mostly; |
98 | static void __exception_irq_entry bcm2835_handle_irq( | 97 | static void __exception_irq_entry bcm2835_handle_irq( |
99 | struct pt_regs *regs); | 98 | struct pt_regs *regs); |
99 | static void bcm2836_chained_handle_irq(unsigned int irq, struct irq_desc *desc); | ||
100 | 100 | ||
101 | static void armctrl_mask_irq(struct irq_data *d) | 101 | static void armctrl_mask_irq(struct irq_data *d) |
102 | { | 102 | { |
@@ -140,7 +140,8 @@ static const struct irq_domain_ops armctrl_ops = { | |||
140 | }; | 140 | }; |
141 | 141 | ||
142 | static int __init armctrl_of_init(struct device_node *node, | 142 | static int __init armctrl_of_init(struct device_node *node, |
143 | struct device_node *parent) | 143 | struct device_node *parent, |
144 | bool is_2836) | ||
144 | { | 145 | { |
145 | void __iomem *base; | 146 | void __iomem *base; |
146 | int irq, b, i; | 147 | int irq, b, i; |
@@ -169,54 +170,90 @@ static int __init armctrl_of_init(struct device_node *node, | |||
169 | } | 170 | } |
170 | } | 171 | } |
171 | 172 | ||
172 | set_handle_irq(bcm2835_handle_irq); | 173 | if (is_2836) { |
174 | int parent_irq = irq_of_parse_and_map(node, 0); | ||
175 | |||
176 | if (!parent_irq) { | ||
177 | panic("%s: unable to get parent interrupt.\n", | ||
178 | node->full_name); | ||
179 | } | ||
180 | irq_set_chained_handler(parent_irq, bcm2836_chained_handle_irq); | ||
181 | } else { | ||
182 | set_handle_irq(bcm2835_handle_irq); | ||
183 | } | ||
184 | |||
173 | return 0; | 185 | return 0; |
174 | } | 186 | } |
175 | 187 | ||
188 | static int __init bcm2835_armctrl_of_init(struct device_node *node, | ||
189 | struct device_node *parent) | ||
190 | { | ||
191 | return armctrl_of_init(node, parent, false); | ||
192 | } | ||
193 | |||
194 | static int __init bcm2836_armctrl_of_init(struct device_node *node, | ||
195 | struct device_node *parent) | ||
196 | { | ||
197 | return armctrl_of_init(node, parent, true); | ||
198 | } | ||
199 | |||
200 | |||
176 | /* | 201 | /* |
177 | * Handle each interrupt across the entire interrupt controller. This reads the | 202 | * Handle each interrupt across the entire interrupt controller. This reads the |
178 | * status register before handling each interrupt, which is necessary given that | 203 | * status register before handling each interrupt, which is necessary given that |
179 | * handle_IRQ may briefly re-enable interrupts for soft IRQ handling. | 204 | * handle_IRQ may briefly re-enable interrupts for soft IRQ handling. |
180 | */ | 205 | */ |
181 | 206 | ||
182 | static void armctrl_handle_bank(int bank, struct pt_regs *regs) | 207 | static u32 armctrl_translate_bank(int bank) |
183 | { | 208 | { |
184 | u32 stat, irq; | 209 | u32 stat = readl_relaxed(intc.pending[bank]); |
185 | 210 | ||
186 | while ((stat = readl_relaxed(intc.pending[bank]))) { | 211 | return MAKE_HWIRQ(bank, ffs(stat) - 1); |
187 | irq = MAKE_HWIRQ(bank, ffs(stat) - 1); | 212 | } |
188 | handle_IRQ(irq_linear_revmap(intc.domain, irq), regs); | 213 | |
189 | } | 214 | static u32 armctrl_translate_shortcut(int bank, u32 stat) |
215 | { | ||
216 | return MAKE_HWIRQ(bank, shortcuts[ffs(stat >> SHORTCUT_SHIFT) - 1]); | ||
190 | } | 217 | } |
191 | 218 | ||
192 | static void armctrl_handle_shortcut(int bank, struct pt_regs *regs, | 219 | static u32 get_next_armctrl_hwirq(void) |
193 | u32 stat) | ||
194 | { | 220 | { |
195 | u32 irq = MAKE_HWIRQ(bank, shortcuts[ffs(stat >> SHORTCUT_SHIFT) - 1]); | 221 | u32 stat = readl_relaxed(intc.pending[0]) & BANK0_VALID_MASK; |
196 | handle_IRQ(irq_linear_revmap(intc.domain, irq), regs); | 222 | |
223 | if (stat == 0) | ||
224 | return ~0; | ||
225 | else if (stat & BANK0_HWIRQ_MASK) | ||
226 | return MAKE_HWIRQ(0, ffs(stat & BANK0_HWIRQ_MASK) - 1); | ||
227 | else if (stat & SHORTCUT1_MASK) | ||
228 | return armctrl_translate_shortcut(1, stat & SHORTCUT1_MASK); | ||
229 | else if (stat & SHORTCUT2_MASK) | ||
230 | return armctrl_translate_shortcut(2, stat & SHORTCUT2_MASK); | ||
231 | else if (stat & BANK1_HWIRQ) | ||
232 | return armctrl_translate_bank(1); | ||
233 | else if (stat & BANK2_HWIRQ) | ||
234 | return armctrl_translate_bank(2); | ||
235 | else | ||
236 | BUG(); | ||
197 | } | 237 | } |
198 | 238 | ||
199 | static void __exception_irq_entry bcm2835_handle_irq( | 239 | static void __exception_irq_entry bcm2835_handle_irq( |
200 | struct pt_regs *regs) | 240 | struct pt_regs *regs) |
201 | { | 241 | { |
202 | u32 stat, irq; | 242 | u32 hwirq; |
203 | 243 | ||
204 | while ((stat = readl_relaxed(intc.pending[0]) & BANK0_VALID_MASK)) { | 244 | while ((hwirq = get_next_armctrl_hwirq()) != ~0) |
205 | if (stat & BANK0_HWIRQ_MASK) { | 245 | handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs); |
206 | irq = MAKE_HWIRQ(0, ffs(stat & BANK0_HWIRQ_MASK) - 1); | 246 | } |
207 | handle_IRQ(irq_linear_revmap(intc.domain, irq), regs); | 247 | |
208 | } else if (stat & SHORTCUT1_MASK) { | 248 | static void bcm2836_chained_handle_irq(unsigned int irq, struct irq_desc *desc) |
209 | armctrl_handle_shortcut(1, regs, stat & SHORTCUT1_MASK); | 249 | { |
210 | } else if (stat & SHORTCUT2_MASK) { | 250 | u32 hwirq; |
211 | armctrl_handle_shortcut(2, regs, stat & SHORTCUT2_MASK); | 251 | |
212 | } else if (stat & BANK1_HWIRQ) { | 252 | while ((hwirq = get_next_armctrl_hwirq()) != ~0) |
213 | armctrl_handle_bank(1, regs); | 253 | generic_handle_irq(irq_linear_revmap(intc.domain, hwirq)); |
214 | } else if (stat & BANK2_HWIRQ) { | ||
215 | armctrl_handle_bank(2, regs); | ||
216 | } else { | ||
217 | BUG(); | ||
218 | } | ||
219 | } | ||
220 | } | 254 | } |
221 | 255 | ||
222 | IRQCHIP_DECLARE(bcm2835_armctrl_ic, "brcm,bcm2835-armctrl-ic", armctrl_of_init); | 256 | IRQCHIP_DECLARE(bcm2835_armctrl_ic, "brcm,bcm2835-armctrl-ic", |
257 | bcm2835_armctrl_of_init); | ||
258 | IRQCHIP_DECLARE(bcm2836_armctrl_ic, "brcm,bcm2836-armctrl-ic", | ||
259 | bcm2836_armctrl_of_init); | ||
diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c new file mode 100644 index 000000000000..f68708281fcf --- /dev/null +++ b/drivers/irqchip/irq-bcm2836.c | |||
@@ -0,0 +1,275 @@ | |||
1 | /* | ||
2 | * Root interrupt controller for the BCM2836 (Raspberry Pi 2). | ||
3 | * | ||
4 | * Copyright 2015 Broadcom | ||
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 as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/cpu.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/of_irq.h> | ||
20 | #include <linux/irqchip.h> | ||
21 | #include <linux/irqdomain.h> | ||
22 | #include <asm/exception.h> | ||
23 | |||
24 | /* | ||
25 | * The low 2 bits identify the CPU that the GPU IRQ goes to, and the | ||
26 | * next 2 bits identify the CPU that the GPU FIQ goes to. | ||
27 | */ | ||
28 | #define LOCAL_GPU_ROUTING 0x00c | ||
29 | /* When setting bits 0-3, enables PMU interrupts on that CPU. */ | ||
30 | #define LOCAL_PM_ROUTING_SET 0x010 | ||
31 | /* When setting bits 0-3, disables PMU interrupts on that CPU. */ | ||
32 | #define LOCAL_PM_ROUTING_CLR 0x014 | ||
33 | /* | ||
34 | * The low 4 bits of this are the CPU's timer IRQ enables, and the | ||
35 | * next 4 bits are the CPU's timer FIQ enables (which override the IRQ | ||
36 | * bits). | ||
37 | */ | ||
38 | #define LOCAL_TIMER_INT_CONTROL0 0x040 | ||
39 | /* | ||
40 | * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and | ||
41 | * the next 4 bits are the CPU's per-mailbox FIQ enables (which | ||
42 | * override the IRQ bits). | ||
43 | */ | ||
44 | #define LOCAL_MAILBOX_INT_CONTROL0 0x050 | ||
45 | /* | ||
46 | * The CPU's interrupt status register. Bits are defined by the the | ||
47 | * LOCAL_IRQ_* bits below. | ||
48 | */ | ||
49 | #define LOCAL_IRQ_PENDING0 0x060 | ||
50 | /* Same status bits as above, but for FIQ. */ | ||
51 | #define LOCAL_FIQ_PENDING0 0x070 | ||
52 | /* | ||
53 | * Mailbox0 write-to-set bits. There are 16 mailboxes, 4 per CPU, and | ||
54 | * these bits are organized by mailbox number and then CPU number. We | ||
55 | * use mailbox 0 for IPIs. The mailbox's interrupt is raised while | ||
56 | * any bit is set. | ||
57 | */ | ||
58 | #define LOCAL_MAILBOX0_SET0 0x080 | ||
59 | /* Mailbox0 write-to-clear bits. */ | ||
60 | #define LOCAL_MAILBOX0_CLR0 0x0c0 | ||
61 | |||
62 | #define LOCAL_IRQ_CNTPSIRQ 0 | ||
63 | #define LOCAL_IRQ_CNTPNSIRQ 1 | ||
64 | #define LOCAL_IRQ_CNTHPIRQ 2 | ||
65 | #define LOCAL_IRQ_CNTVIRQ 3 | ||
66 | #define LOCAL_IRQ_MAILBOX0 4 | ||
67 | #define LOCAL_IRQ_MAILBOX1 5 | ||
68 | #define LOCAL_IRQ_MAILBOX2 6 | ||
69 | #define LOCAL_IRQ_MAILBOX3 7 | ||
70 | #define LOCAL_IRQ_GPU_FAST 8 | ||
71 | #define LOCAL_IRQ_PMU_FAST 9 | ||
72 | #define LAST_IRQ LOCAL_IRQ_PMU_FAST | ||
73 | |||
74 | struct bcm2836_arm_irqchip_intc { | ||
75 | struct irq_domain *domain; | ||
76 | void __iomem *base; | ||
77 | }; | ||
78 | |||
79 | static struct bcm2836_arm_irqchip_intc intc __read_mostly; | ||
80 | |||
81 | static void bcm2836_arm_irqchip_mask_per_cpu_irq(unsigned int reg_offset, | ||
82 | unsigned int bit, | ||
83 | int cpu) | ||
84 | { | ||
85 | void __iomem *reg = intc.base + reg_offset + 4 * cpu; | ||
86 | |||
87 | writel(readl(reg) & ~BIT(bit), reg); | ||
88 | } | ||
89 | |||
90 | static void bcm2836_arm_irqchip_unmask_per_cpu_irq(unsigned int reg_offset, | ||
91 | unsigned int bit, | ||
92 | int cpu) | ||
93 | { | ||
94 | void __iomem *reg = intc.base + reg_offset + 4 * cpu; | ||
95 | |||
96 | writel(readl(reg) | BIT(bit), reg); | ||
97 | } | ||
98 | |||
99 | static void bcm2836_arm_irqchip_mask_timer_irq(struct irq_data *d) | ||
100 | { | ||
101 | bcm2836_arm_irqchip_mask_per_cpu_irq(LOCAL_TIMER_INT_CONTROL0, | ||
102 | d->hwirq - LOCAL_IRQ_CNTPSIRQ, | ||
103 | smp_processor_id()); | ||
104 | } | ||
105 | |||
106 | static void bcm2836_arm_irqchip_unmask_timer_irq(struct irq_data *d) | ||
107 | { | ||
108 | bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_TIMER_INT_CONTROL0, | ||
109 | d->hwirq - LOCAL_IRQ_CNTPSIRQ, | ||
110 | smp_processor_id()); | ||
111 | } | ||
112 | |||
113 | static struct irq_chip bcm2836_arm_irqchip_timer = { | ||
114 | .name = "bcm2836-timer", | ||
115 | .irq_mask = bcm2836_arm_irqchip_mask_timer_irq, | ||
116 | .irq_unmask = bcm2836_arm_irqchip_unmask_timer_irq, | ||
117 | }; | ||
118 | |||
119 | static void bcm2836_arm_irqchip_mask_pmu_irq(struct irq_data *d) | ||
120 | { | ||
121 | writel(1 << smp_processor_id(), intc.base + LOCAL_PM_ROUTING_CLR); | ||
122 | } | ||
123 | |||
124 | static void bcm2836_arm_irqchip_unmask_pmu_irq(struct irq_data *d) | ||
125 | { | ||
126 | writel(1 << smp_processor_id(), intc.base + LOCAL_PM_ROUTING_SET); | ||
127 | } | ||
128 | |||
129 | static struct irq_chip bcm2836_arm_irqchip_pmu = { | ||
130 | .name = "bcm2836-pmu", | ||
131 | .irq_mask = bcm2836_arm_irqchip_mask_pmu_irq, | ||
132 | .irq_unmask = bcm2836_arm_irqchip_unmask_pmu_irq, | ||
133 | }; | ||
134 | |||
135 | static void bcm2836_arm_irqchip_mask_gpu_irq(struct irq_data *d) | ||
136 | { | ||
137 | } | ||
138 | |||
139 | static void bcm2836_arm_irqchip_unmask_gpu_irq(struct irq_data *d) | ||
140 | { | ||
141 | } | ||
142 | |||
143 | static struct irq_chip bcm2836_arm_irqchip_gpu = { | ||
144 | .name = "bcm2836-gpu", | ||
145 | .irq_mask = bcm2836_arm_irqchip_mask_gpu_irq, | ||
146 | .irq_unmask = bcm2836_arm_irqchip_unmask_gpu_irq, | ||
147 | }; | ||
148 | |||
149 | static void bcm2836_arm_irqchip_register_irq(int hwirq, struct irq_chip *chip) | ||
150 | { | ||
151 | int irq = irq_create_mapping(intc.domain, hwirq); | ||
152 | |||
153 | irq_set_percpu_devid(irq); | ||
154 | irq_set_chip_and_handler(irq, chip, handle_percpu_devid_irq); | ||
155 | irq_set_status_flags(irq, IRQ_NOAUTOEN); | ||
156 | } | ||
157 | |||
158 | static void | ||
159 | __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) | ||
160 | { | ||
161 | int cpu = smp_processor_id(); | ||
162 | u32 stat; | ||
163 | |||
164 | stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu); | ||
165 | if (stat & 0x10) { | ||
166 | #ifdef CONFIG_SMP | ||
167 | void __iomem *mailbox0 = (intc.base + | ||
168 | LOCAL_MAILBOX0_CLR0 + 16 * cpu); | ||
169 | u32 mbox_val = readl(mailbox0); | ||
170 | u32 ipi = ffs(mbox_val) - 1; | ||
171 | |||
172 | writel(1 << ipi, mailbox0); | ||
173 | handle_IPI(ipi, regs); | ||
174 | #endif | ||
175 | } else { | ||
176 | u32 hwirq = ffs(stat) - 1; | ||
177 | |||
178 | handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | #ifdef CONFIG_SMP | ||
183 | static void bcm2836_arm_irqchip_send_ipi(const struct cpumask *mask, | ||
184 | unsigned int ipi) | ||
185 | { | ||
186 | int cpu; | ||
187 | void __iomem *mailbox0_base = intc.base + LOCAL_MAILBOX0_SET0; | ||
188 | |||
189 | /* | ||
190 | * Ensure that stores to normal memory are visible to the | ||
191 | * other CPUs before issuing the IPI. | ||
192 | */ | ||
193 | dsb(); | ||
194 | |||
195 | for_each_cpu(cpu, mask) { | ||
196 | writel(1 << ipi, mailbox0_base + 16 * cpu); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | /* Unmasks the IPI on the CPU when it's online. */ | ||
201 | static int bcm2836_arm_irqchip_cpu_notify(struct notifier_block *nfb, | ||
202 | unsigned long action, void *hcpu) | ||
203 | { | ||
204 | unsigned int cpu = (unsigned long)hcpu; | ||
205 | unsigned int int_reg = LOCAL_MAILBOX_INT_CONTROL0; | ||
206 | unsigned int mailbox = 0; | ||
207 | |||
208 | if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) | ||
209 | bcm2836_arm_irqchip_unmask_per_cpu_irq(int_reg, mailbox, cpu); | ||
210 | else if (action == CPU_DYING) | ||
211 | bcm2836_arm_irqchip_mask_per_cpu_irq(int_reg, mailbox, cpu); | ||
212 | |||
213 | return NOTIFY_OK; | ||
214 | } | ||
215 | |||
216 | static struct notifier_block bcm2836_arm_irqchip_cpu_notifier = { | ||
217 | .notifier_call = bcm2836_arm_irqchip_cpu_notify, | ||
218 | .priority = 100, | ||
219 | }; | ||
220 | #endif | ||
221 | |||
222 | static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = { | ||
223 | .xlate = irq_domain_xlate_onecell | ||
224 | }; | ||
225 | |||
226 | static void | ||
227 | bcm2836_arm_irqchip_smp_init(void) | ||
228 | { | ||
229 | #ifdef CONFIG_SMP | ||
230 | /* Unmask IPIs to the boot CPU. */ | ||
231 | bcm2836_arm_irqchip_cpu_notify(&bcm2836_arm_irqchip_cpu_notifier, | ||
232 | CPU_STARTING, | ||
233 | (void *)smp_processor_id()); | ||
234 | register_cpu_notifier(&bcm2836_arm_irqchip_cpu_notifier); | ||
235 | |||
236 | set_smp_cross_call(bcm2836_arm_irqchip_send_ipi); | ||
237 | #endif | ||
238 | } | ||
239 | |||
240 | static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node, | ||
241 | struct device_node *parent) | ||
242 | { | ||
243 | intc.base = of_iomap(node, 0); | ||
244 | if (!intc.base) { | ||
245 | panic("%s: unable to map local interrupt registers\n", | ||
246 | node->full_name); | ||
247 | } | ||
248 | |||
249 | intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1, | ||
250 | &bcm2836_arm_irqchip_intc_ops, | ||
251 | NULL); | ||
252 | if (!intc.domain) | ||
253 | panic("%s: unable to create IRQ domain\n", node->full_name); | ||
254 | |||
255 | bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPSIRQ, | ||
256 | &bcm2836_arm_irqchip_timer); | ||
257 | bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPNSIRQ, | ||
258 | &bcm2836_arm_irqchip_timer); | ||
259 | bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTHPIRQ, | ||
260 | &bcm2836_arm_irqchip_timer); | ||
261 | bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTVIRQ, | ||
262 | &bcm2836_arm_irqchip_timer); | ||
263 | bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_GPU_FAST, | ||
264 | &bcm2836_arm_irqchip_gpu); | ||
265 | bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_PMU_FAST, | ||
266 | &bcm2836_arm_irqchip_pmu); | ||
267 | |||
268 | bcm2836_arm_irqchip_smp_init(); | ||
269 | |||
270 | set_handle_irq(bcm2836_arm_irqchip_handle_irq); | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | IRQCHIP_DECLARE(bcm2836_arm_irqchip_l1_intc, "brcm,bcm2836-l1-intc", | ||
275 | bcm2836_arm_irqchip_l1_intc_of_init); | ||
diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c index d3b8c8be15f6..409bdc6366c2 100644 --- a/drivers/irqchip/irq-bcm7038-l1.c +++ b/drivers/irqchip/irq-bcm7038-l1.c | |||
@@ -29,10 +29,9 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/smp.h> | 30 | #include <linux/smp.h> |
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/irqchip.h> | ||
32 | #include <linux/irqchip/chained_irq.h> | 33 | #include <linux/irqchip/chained_irq.h> |
33 | 34 | ||
34 | #include "irqchip.h" | ||
35 | |||
36 | #define IRQS_PER_WORD 32 | 35 | #define IRQS_PER_WORD 32 |
37 | #define REG_BYTES_PER_IRQ_WORD (sizeof(u32) * 4) | 36 | #define REG_BYTES_PER_IRQ_WORD (sizeof(u32) * 4) |
38 | #define MAX_WORDS 8 | 37 | #define MAX_WORDS 8 |
@@ -257,8 +256,8 @@ static int __init bcm7038_l1_init_one(struct device_node *dn, | |||
257 | pr_err("failed to map parent interrupt %d\n", parent_irq); | 256 | pr_err("failed to map parent interrupt %d\n", parent_irq); |
258 | return -EINVAL; | 257 | return -EINVAL; |
259 | } | 258 | } |
260 | irq_set_handler_data(parent_irq, intc); | 259 | irq_set_chained_handler_and_data(parent_irq, bcm7038_l1_irq_handle, |
261 | irq_set_chained_handler(parent_irq, bcm7038_l1_irq_handle); | 260 | intc); |
262 | 261 | ||
263 | return 0; | 262 | return 0; |
264 | } | 263 | } |
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c index 3ba5cc780fcb..d3f976913a6f 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c | |||
@@ -26,10 +26,9 @@ | |||
26 | #include <linux/irqdomain.h> | 26 | #include <linux/irqdomain.h> |
27 | #include <linux/reboot.h> | 27 | #include <linux/reboot.h> |
28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
29 | #include <linux/irqchip.h> | ||
29 | #include <linux/irqchip/chained_irq.h> | 30 | #include <linux/irqchip/chained_irq.h> |
30 | 31 | ||
31 | #include "irqchip.h" | ||
32 | |||
33 | /* Register offset in the L2 interrupt controller */ | 32 | /* Register offset in the L2 interrupt controller */ |
34 | #define IRQEN 0x00 | 33 | #define IRQEN 0x00 |
35 | #define IRQSTAT 0x04 | 34 | #define IRQSTAT 0x04 |
@@ -38,6 +37,11 @@ | |||
38 | #define MAX_MAPPINGS (MAX_WORDS * 2) | 37 | #define MAX_MAPPINGS (MAX_WORDS * 2) |
39 | #define IRQS_PER_WORD 32 | 38 | #define IRQS_PER_WORD 32 |
40 | 39 | ||
40 | struct bcm7120_l1_intc_data { | ||
41 | struct bcm7120_l2_intc_data *b; | ||
42 | u32 irq_map_mask[MAX_WORDS]; | ||
43 | }; | ||
44 | |||
41 | struct bcm7120_l2_intc_data { | 45 | struct bcm7120_l2_intc_data { |
42 | unsigned int n_words; | 46 | unsigned int n_words; |
43 | void __iomem *map_base[MAX_MAPPINGS]; | 47 | void __iomem *map_base[MAX_MAPPINGS]; |
@@ -47,14 +51,15 @@ struct bcm7120_l2_intc_data { | |||
47 | struct irq_domain *domain; | 51 | struct irq_domain *domain; |
48 | bool can_wake; | 52 | bool can_wake; |
49 | u32 irq_fwd_mask[MAX_WORDS]; | 53 | u32 irq_fwd_mask[MAX_WORDS]; |
50 | u32 irq_map_mask[MAX_WORDS]; | 54 | struct bcm7120_l1_intc_data *l1_data; |
51 | int num_parent_irqs; | 55 | int num_parent_irqs; |
52 | const __be32 *map_mask_prop; | 56 | const __be32 *map_mask_prop; |
53 | }; | 57 | }; |
54 | 58 | ||
55 | static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) | 59 | static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) |
56 | { | 60 | { |
57 | struct bcm7120_l2_intc_data *b = irq_desc_get_handler_data(desc); | 61 | struct bcm7120_l1_intc_data *data = irq_desc_get_handler_data(desc); |
62 | struct bcm7120_l2_intc_data *b = data->b; | ||
58 | struct irq_chip *chip = irq_desc_get_chip(desc); | 63 | struct irq_chip *chip = irq_desc_get_chip(desc); |
59 | unsigned int idx; | 64 | unsigned int idx; |
60 | 65 | ||
@@ -69,7 +74,8 @@ static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) | |||
69 | 74 | ||
70 | irq_gc_lock(gc); | 75 | irq_gc_lock(gc); |
71 | pending = irq_reg_readl(gc, b->stat_offset[idx]) & | 76 | pending = irq_reg_readl(gc, b->stat_offset[idx]) & |
72 | gc->mask_cache; | 77 | gc->mask_cache & |
78 | data->irq_map_mask[idx]; | ||
73 | irq_gc_unlock(gc); | 79 | irq_gc_unlock(gc); |
74 | 80 | ||
75 | for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { | 81 | for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { |
@@ -81,11 +87,10 @@ static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) | |||
81 | chained_irq_exit(chip, desc); | 87 | chained_irq_exit(chip, desc); |
82 | } | 88 | } |
83 | 89 | ||
84 | static void bcm7120_l2_intc_suspend(struct irq_data *d) | 90 | static void bcm7120_l2_intc_suspend(struct irq_chip_generic *gc) |
85 | { | 91 | { |
86 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
87 | struct irq_chip_type *ct = irq_data_get_chip_type(d); | ||
88 | struct bcm7120_l2_intc_data *b = gc->private; | 92 | struct bcm7120_l2_intc_data *b = gc->private; |
93 | struct irq_chip_type *ct = gc->chip_types; | ||
89 | 94 | ||
90 | irq_gc_lock(gc); | 95 | irq_gc_lock(gc); |
91 | if (b->can_wake) | 96 | if (b->can_wake) |
@@ -94,10 +99,9 @@ static void bcm7120_l2_intc_suspend(struct irq_data *d) | |||
94 | irq_gc_unlock(gc); | 99 | irq_gc_unlock(gc); |
95 | } | 100 | } |
96 | 101 | ||
97 | static void bcm7120_l2_intc_resume(struct irq_data *d) | 102 | static void bcm7120_l2_intc_resume(struct irq_chip_generic *gc) |
98 | { | 103 | { |
99 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 104 | struct irq_chip_type *ct = gc->chip_types; |
100 | struct irq_chip_type *ct = irq_data_get_chip_type(d); | ||
101 | 105 | ||
102 | /* Restore the saved mask */ | 106 | /* Restore the saved mask */ |
103 | irq_gc_lock(gc); | 107 | irq_gc_lock(gc); |
@@ -107,8 +111,9 @@ static void bcm7120_l2_intc_resume(struct irq_data *d) | |||
107 | 111 | ||
108 | static int bcm7120_l2_intc_init_one(struct device_node *dn, | 112 | static int bcm7120_l2_intc_init_one(struct device_node *dn, |
109 | struct bcm7120_l2_intc_data *data, | 113 | struct bcm7120_l2_intc_data *data, |
110 | int irq) | 114 | int irq, u32 *valid_mask) |
111 | { | 115 | { |
116 | struct bcm7120_l1_intc_data *l1_data = &data->l1_data[irq]; | ||
112 | int parent_irq; | 117 | int parent_irq; |
113 | unsigned int idx; | 118 | unsigned int idx; |
114 | 119 | ||
@@ -120,20 +125,28 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn, | |||
120 | 125 | ||
121 | /* For multiple parent IRQs with multiple words, this looks like: | 126 | /* For multiple parent IRQs with multiple words, this looks like: |
122 | * <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...> | 127 | * <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...> |
128 | * | ||
129 | * We need to associate a given parent interrupt with its corresponding | ||
130 | * map_mask in order to mask the status register with it because we | ||
131 | * have the same handler being called for multiple parent interrupts. | ||
132 | * | ||
133 | * This is typically something needed on BCM7xxx (STB chips). | ||
123 | */ | 134 | */ |
124 | for (idx = 0; idx < data->n_words; idx++) { | 135 | for (idx = 0; idx < data->n_words; idx++) { |
125 | if (data->map_mask_prop) { | 136 | if (data->map_mask_prop) { |
126 | data->irq_map_mask[idx] |= | 137 | l1_data->irq_map_mask[idx] |= |
127 | be32_to_cpup(data->map_mask_prop + | 138 | be32_to_cpup(data->map_mask_prop + |
128 | irq * data->n_words + idx); | 139 | irq * data->n_words + idx); |
129 | } else { | 140 | } else { |
130 | data->irq_map_mask[idx] = 0xffffffff; | 141 | l1_data->irq_map_mask[idx] = 0xffffffff; |
131 | } | 142 | } |
143 | valid_mask[idx] |= l1_data->irq_map_mask[idx]; | ||
132 | } | 144 | } |
133 | 145 | ||
134 | irq_set_handler_data(parent_irq, data); | 146 | l1_data->b = data; |
135 | irq_set_chained_handler(parent_irq, bcm7120_l2_intc_irq_handle); | ||
136 | 147 | ||
148 | irq_set_chained_handler_and_data(parent_irq, | ||
149 | bcm7120_l2_intc_irq_handle, l1_data); | ||
137 | return 0; | 150 | return 0; |
138 | } | 151 | } |
139 | 152 | ||
@@ -214,6 +227,7 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, | |||
214 | struct irq_chip_type *ct; | 227 | struct irq_chip_type *ct; |
215 | int ret = 0; | 228 | int ret = 0; |
216 | unsigned int idx, irq, flags; | 229 | unsigned int idx, irq, flags; |
230 | u32 valid_mask[MAX_WORDS] = { }; | ||
217 | 231 | ||
218 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 232 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
219 | if (!data) | 233 | if (!data) |
@@ -226,9 +240,16 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, | |||
226 | goto out_unmap; | 240 | goto out_unmap; |
227 | } | 241 | } |
228 | 242 | ||
243 | data->l1_data = kcalloc(data->num_parent_irqs, sizeof(*data->l1_data), | ||
244 | GFP_KERNEL); | ||
245 | if (!data->l1_data) { | ||
246 | ret = -ENOMEM; | ||
247 | goto out_free_l1_data; | ||
248 | } | ||
249 | |||
229 | ret = iomap_regs_fn(dn, data); | 250 | ret = iomap_regs_fn(dn, data); |
230 | if (ret < 0) | 251 | if (ret < 0) |
231 | goto out_unmap; | 252 | goto out_free_l1_data; |
232 | 253 | ||
233 | for (idx = 0; idx < data->n_words; idx++) { | 254 | for (idx = 0; idx < data->n_words; idx++) { |
234 | __raw_writel(data->irq_fwd_mask[idx], | 255 | __raw_writel(data->irq_fwd_mask[idx], |
@@ -237,16 +258,16 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, | |||
237 | } | 258 | } |
238 | 259 | ||
239 | for (irq = 0; irq < data->num_parent_irqs; irq++) { | 260 | for (irq = 0; irq < data->num_parent_irqs; irq++) { |
240 | ret = bcm7120_l2_intc_init_one(dn, data, irq); | 261 | ret = bcm7120_l2_intc_init_one(dn, data, irq, valid_mask); |
241 | if (ret) | 262 | if (ret) |
242 | goto out_unmap; | 263 | goto out_free_l1_data; |
243 | } | 264 | } |
244 | 265 | ||
245 | data->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * data->n_words, | 266 | data->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * data->n_words, |
246 | &irq_generic_chip_ops, NULL); | 267 | &irq_generic_chip_ops, NULL); |
247 | if (!data->domain) { | 268 | if (!data->domain) { |
248 | ret = -ENOMEM; | 269 | ret = -ENOMEM; |
249 | goto out_unmap; | 270 | goto out_free_l1_data; |
250 | } | 271 | } |
251 | 272 | ||
252 | /* MIPS chips strapped for BE will automagically configure the | 273 | /* MIPS chips strapped for BE will automagically configure the |
@@ -270,7 +291,7 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, | |||
270 | irq = idx * IRQS_PER_WORD; | 291 | irq = idx * IRQS_PER_WORD; |
271 | gc = irq_get_domain_generic_chip(data->domain, irq); | 292 | gc = irq_get_domain_generic_chip(data->domain, irq); |
272 | 293 | ||
273 | gc->unused = 0xffffffff & ~data->irq_map_mask[idx]; | 294 | gc->unused = 0xffffffff & ~valid_mask[idx]; |
274 | gc->private = data; | 295 | gc->private = data; |
275 | ct = gc->chip_types; | 296 | ct = gc->chip_types; |
276 | 297 | ||
@@ -280,8 +301,15 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, | |||
280 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | 301 | ct->chip.irq_mask = irq_gc_mask_clr_bit; |
281 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 302 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
282 | ct->chip.irq_ack = irq_gc_noop; | 303 | ct->chip.irq_ack = irq_gc_noop; |
283 | ct->chip.irq_suspend = bcm7120_l2_intc_suspend; | 304 | gc->suspend = bcm7120_l2_intc_suspend; |
284 | ct->chip.irq_resume = bcm7120_l2_intc_resume; | 305 | gc->resume = bcm7120_l2_intc_resume; |
306 | |||
307 | /* | ||
308 | * Initialize mask-cache, in case we need it for | ||
309 | * saving/restoring fwd mask even w/o any child interrupts | ||
310 | * installed | ||
311 | */ | ||
312 | gc->mask_cache = irq_reg_readl(gc, ct->regs.mask); | ||
285 | 313 | ||
286 | if (data->can_wake) { | 314 | if (data->can_wake) { |
287 | /* This IRQ chip can wake the system, set all | 315 | /* This IRQ chip can wake the system, set all |
@@ -300,6 +328,8 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, | |||
300 | 328 | ||
301 | out_free_domain: | 329 | out_free_domain: |
302 | irq_domain_remove(data->domain); | 330 | irq_domain_remove(data->domain); |
331 | out_free_l1_data: | ||
332 | kfree(data->l1_data); | ||
303 | out_unmap: | 333 | out_unmap: |
304 | for (idx = 0; idx < MAX_MAPPINGS; idx++) { | 334 | for (idx = 0; idx < MAX_MAPPINGS; idx++) { |
305 | if (data->map_base[idx]) | 335 | if (data->map_base[idx]) |
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index d6bcc6be0777..aedda06191eb 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include <linux/irqchip.h> | 32 | #include <linux/irqchip.h> |
33 | #include <linux/irqchip/chained_irq.h> | 33 | #include <linux/irqchip/chained_irq.h> |
34 | 34 | ||
35 | #include "irqchip.h" | ||
36 | |||
37 | /* Register offsets in the L2 interrupt controller */ | 35 | /* Register offsets in the L2 interrupt controller */ |
38 | #define CPU_STATUS 0x00 | 36 | #define CPU_STATUS 0x00 |
39 | #define CPU_SET 0x04 | 37 | #define CPU_SET 0x04 |
@@ -51,11 +49,13 @@ struct brcmstb_l2_intc_data { | |||
51 | u32 saved_mask; /* for suspend/resume */ | 49 | u32 saved_mask; /* for suspend/resume */ |
52 | }; | 50 | }; |
53 | 51 | ||
54 | static void brcmstb_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) | 52 | static void brcmstb_l2_intc_irq_handle(unsigned int __irq, |
53 | struct irq_desc *desc) | ||
55 | { | 54 | { |
56 | struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc); | 55 | struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc); |
57 | struct irq_chip_generic *gc = irq_get_domain_generic_chip(b->domain, 0); | 56 | struct irq_chip_generic *gc = irq_get_domain_generic_chip(b->domain, 0); |
58 | struct irq_chip *chip = irq_desc_get_chip(desc); | 57 | struct irq_chip *chip = irq_desc_get_chip(desc); |
58 | unsigned int irq = irq_desc_get_irq(desc); | ||
59 | u32 status; | 59 | u32 status; |
60 | 60 | ||
61 | chained_irq_enter(chip, desc); | 61 | chained_irq_enter(chip, desc); |
@@ -172,8 +172,8 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np, | |||
172 | } | 172 | } |
173 | 173 | ||
174 | /* Set the IRQ chaining logic */ | 174 | /* Set the IRQ chaining logic */ |
175 | irq_set_handler_data(data->parent_irq, data); | 175 | irq_set_chained_handler_and_data(data->parent_irq, |
176 | irq_set_chained_handler(data->parent_irq, brcmstb_l2_intc_irq_handle); | 176 | brcmstb_l2_intc_irq_handle, data); |
177 | 177 | ||
178 | gc = irq_get_domain_generic_chip(data->domain, 0); | 178 | gc = irq_get_domain_generic_chip(data->domain, 0); |
179 | gc->reg_base = data->base; | 179 | gc->reg_base = data->base; |
diff --git a/drivers/irqchip/irq-clps711x.c b/drivers/irqchip/irq-clps711x.c index 33127f131d78..2dd929eed9e0 100644 --- a/drivers/irqchip/irq-clps711x.c +++ b/drivers/irqchip/irq-clps711x.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/irqchip.h> | ||
14 | #include <linux/irqdomain.h> | 15 | #include <linux/irqdomain.h> |
15 | #include <linux/of_address.h> | 16 | #include <linux/of_address.h> |
16 | #include <linux/of_irq.h> | 17 | #include <linux/of_irq.h> |
@@ -19,8 +20,6 @@ | |||
19 | #include <asm/exception.h> | 20 | #include <asm/exception.h> |
20 | #include <asm/mach/irq.h> | 21 | #include <asm/mach/irq.h> |
21 | 22 | ||
22 | #include "irqchip.h" | ||
23 | |||
24 | #define CLPS711X_INTSR1 (0x0240) | 23 | #define CLPS711X_INTSR1 (0x0240) |
25 | #define CLPS711X_INTMR1 (0x0280) | 24 | #define CLPS711X_INTMR1 (0x0280) |
26 | #define CLPS711X_BLEOI (0x0600) | 25 | #define CLPS711X_BLEOI (0x0600) |
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index c12bb93334ff..a7f5626930f5 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c | |||
@@ -11,13 +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/irqchip.h> | ||
14 | #include <linux/irqdomain.h> | 15 | #include <linux/irqdomain.h> |
15 | #include <linux/of_address.h> | 16 | #include <linux/of_address.h> |
16 | #include <linux/of_irq.h> | 17 | #include <linux/of_irq.h> |
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
18 | 19 | ||
19 | #include "irqchip.h" | ||
20 | |||
21 | #define IRQ_FREE -1 | 20 | #define IRQ_FREE -1 |
22 | #define IRQ_RESERVED -2 | 21 | #define IRQ_RESERVED -2 |
23 | #define IRQ_SKIP -3 | 22 | #define IRQ_SKIP -3 |
diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c index 3cbc658afe27..dad85e74c37c 100644 --- a/drivers/irqchip/irq-digicolor.c +++ b/drivers/irqchip/irq-digicolor.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/irqchip.h> | ||
15 | #include <linux/of.h> | 16 | #include <linux/of.h> |
16 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
17 | #include <linux/of_irq.h> | 18 | #include <linux/of_irq.h> |
@@ -20,8 +21,6 @@ | |||
20 | 21 | ||
21 | #include <asm/exception.h> | 22 | #include <asm/exception.h> |
22 | 23 | ||
23 | #include "irqchip.h" | ||
24 | |||
25 | #define UC_IRQ_CONTROL 0x04 | 24 | #define UC_IRQ_CONTROL 0x04 |
26 | 25 | ||
27 | #define IC_FLAG_CLEAR_LO 0x00 | 26 | #define IC_FLAG_CLEAR_LO 0x00 |
diff --git a/drivers/irqchip/irq-dw-apb-ictl.c b/drivers/irqchip/irq-dw-apb-ictl.c index 53bb7326a60a..efd95d9955e7 100644 --- a/drivers/irqchip/irq-dw-apb-ictl.c +++ b/drivers/irqchip/irq-dw-apb-ictl.c | |||
@@ -13,36 +13,36 @@ | |||
13 | 13 | ||
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <linux/irqchip.h> | ||
16 | #include <linux/irqchip/chained_irq.h> | 17 | #include <linux/irqchip/chained_irq.h> |
17 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
18 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
19 | 20 | ||
20 | #include "irqchip.h" | ||
21 | |||
22 | #define APB_INT_ENABLE_L 0x00 | 21 | #define APB_INT_ENABLE_L 0x00 |
23 | #define APB_INT_ENABLE_H 0x04 | 22 | #define APB_INT_ENABLE_H 0x04 |
24 | #define APB_INT_MASK_L 0x08 | 23 | #define APB_INT_MASK_L 0x08 |
25 | #define APB_INT_MASK_H 0x0c | 24 | #define APB_INT_MASK_H 0x0c |
26 | #define APB_INT_FINALSTATUS_L 0x30 | 25 | #define APB_INT_FINALSTATUS_L 0x30 |
27 | #define APB_INT_FINALSTATUS_H 0x34 | 26 | #define APB_INT_FINALSTATUS_H 0x34 |
27 | #define APB_INT_BASE_OFFSET 0x04 | ||
28 | 28 | ||
29 | static void dw_apb_ictl_handler(unsigned int irq, struct irq_desc *desc) | 29 | static void dw_apb_ictl_handler(unsigned int irq, struct irq_desc *desc) |
30 | { | 30 | { |
31 | struct irq_chip *chip = irq_get_chip(irq); | 31 | struct irq_domain *d = irq_desc_get_handler_data(desc); |
32 | struct irq_chip_generic *gc = irq_get_handler_data(irq); | 32 | struct irq_chip *chip = irq_desc_get_chip(desc); |
33 | struct irq_domain *d = gc->private; | ||
34 | u32 stat; | ||
35 | int n; | 33 | int n; |
36 | 34 | ||
37 | chained_irq_enter(chip, desc); | 35 | chained_irq_enter(chip, desc); |
38 | 36 | ||
39 | for (n = 0; n < gc->num_ct; n++) { | 37 | for (n = 0; n < d->revmap_size; n += 32) { |
40 | stat = readl_relaxed(gc->reg_base + | 38 | struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, n); |
41 | APB_INT_FINALSTATUS_L + 4 * n); | 39 | u32 stat = readl_relaxed(gc->reg_base + APB_INT_FINALSTATUS_L); |
40 | |||
42 | while (stat) { | 41 | while (stat) { |
43 | u32 hwirq = ffs(stat) - 1; | 42 | u32 hwirq = ffs(stat) - 1; |
44 | generic_handle_irq(irq_find_mapping(d, | 43 | u32 virq = irq_find_mapping(d, gc->irq_base + hwirq); |
45 | gc->irq_base + hwirq + 32 * n)); | 44 | |
45 | generic_handle_irq(virq); | ||
46 | stat &= ~(1 << hwirq); | 46 | stat &= ~(1 << hwirq); |
47 | } | 47 | } |
48 | } | 48 | } |
@@ -73,7 +73,7 @@ static int __init dw_apb_ictl_init(struct device_node *np, | |||
73 | struct irq_domain *domain; | 73 | struct irq_domain *domain; |
74 | struct irq_chip_generic *gc; | 74 | struct irq_chip_generic *gc; |
75 | void __iomem *iobase; | 75 | void __iomem *iobase; |
76 | int ret, nrirqs, irq; | 76 | int ret, nrirqs, irq, i; |
77 | u32 reg; | 77 | u32 reg; |
78 | 78 | ||
79 | /* Map the parent interrupt for the chained handler */ | 79 | /* Map the parent interrupt for the chained handler */ |
@@ -128,35 +128,25 @@ static int __init dw_apb_ictl_init(struct device_node *np, | |||
128 | goto err_unmap; | 128 | goto err_unmap; |
129 | } | 129 | } |
130 | 130 | ||
131 | ret = irq_alloc_domain_generic_chips(domain, 32, (nrirqs > 32) ? 2 : 1, | 131 | ret = irq_alloc_domain_generic_chips(domain, 32, 1, np->name, |
132 | np->name, handle_level_irq, clr, 0, | 132 | handle_level_irq, clr, 0, |
133 | IRQ_GC_MASK_CACHE_PER_TYPE | | ||
134 | IRQ_GC_INIT_MASK_CACHE); | 133 | IRQ_GC_INIT_MASK_CACHE); |
135 | if (ret) { | 134 | if (ret) { |
136 | pr_err("%s: unable to alloc irq domain gc\n", np->full_name); | 135 | pr_err("%s: unable to alloc irq domain gc\n", np->full_name); |
137 | goto err_unmap; | 136 | goto err_unmap; |
138 | } | 137 | } |
139 | 138 | ||
140 | gc = irq_get_domain_generic_chip(domain, 0); | 139 | for (i = 0; i < DIV_ROUND_UP(nrirqs, 32); i++) { |
141 | gc->private = domain; | 140 | gc = irq_get_domain_generic_chip(domain, i * 32); |
142 | gc->reg_base = iobase; | 141 | gc->reg_base = iobase + i * APB_INT_BASE_OFFSET; |
143 | 142 | gc->chip_types[0].regs.mask = APB_INT_MASK_L; | |
144 | gc->chip_types[0].regs.mask = APB_INT_MASK_L; | 143 | gc->chip_types[0].regs.enable = APB_INT_ENABLE_L; |
145 | gc->chip_types[0].regs.enable = APB_INT_ENABLE_L; | 144 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; |
146 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; | 145 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; |
147 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; | 146 | gc->chip_types[0].chip.irq_resume = dw_apb_ictl_resume; |
148 | gc->chip_types[0].chip.irq_resume = dw_apb_ictl_resume; | ||
149 | |||
150 | if (nrirqs > 32) { | ||
151 | gc->chip_types[1].regs.mask = APB_INT_MASK_H; | ||
152 | gc->chip_types[1].regs.enable = APB_INT_ENABLE_H; | ||
153 | gc->chip_types[1].chip.irq_mask = irq_gc_mask_set_bit; | ||
154 | gc->chip_types[1].chip.irq_unmask = irq_gc_mask_clr_bit; | ||
155 | gc->chip_types[1].chip.irq_resume = dw_apb_ictl_resume; | ||
156 | } | 147 | } |
157 | 148 | ||
158 | irq_set_handler_data(irq, gc); | 149 | irq_set_chained_handler_and_data(irq, dw_apb_ictl_handler, domain); |
159 | irq_set_chained_handler(irq, dw_apb_ictl_handler); | ||
160 | 150 | ||
161 | return 0; | 151 | return 0; |
162 | 152 | ||
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index fdf706555d72..db04fc1f56b2 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c | |||
@@ -45,13 +45,11 @@ | |||
45 | 45 | ||
46 | struct v2m_data { | 46 | struct v2m_data { |
47 | spinlock_t msi_cnt_lock; | 47 | spinlock_t msi_cnt_lock; |
48 | struct msi_controller mchip; | ||
49 | struct resource res; /* GICv2m resource */ | 48 | struct resource res; /* GICv2m resource */ |
50 | void __iomem *base; /* GICv2m virt address */ | 49 | void __iomem *base; /* GICv2m virt address */ |
51 | u32 spi_start; /* The SPI number that MSIs start */ | 50 | u32 spi_start; /* The SPI number that MSIs start */ |
52 | u32 nr_spis; /* The number of SPIs for MSIs */ | 51 | u32 nr_spis; /* The number of SPIs for MSIs */ |
53 | unsigned long *bm; /* MSI vector bitmap */ | 52 | unsigned long *bm; /* MSI vector bitmap */ |
54 | struct irq_domain *domain; | ||
55 | }; | 53 | }; |
56 | 54 | ||
57 | static void gicv2m_mask_msi_irq(struct irq_data *d) | 55 | static void gicv2m_mask_msi_irq(struct irq_data *d) |
@@ -213,11 +211,25 @@ static bool is_msi_spi_valid(u32 base, u32 num) | |||
213 | return true; | 211 | return true; |
214 | } | 212 | } |
215 | 213 | ||
214 | static struct irq_chip gicv2m_pmsi_irq_chip = { | ||
215 | .name = "pMSI", | ||
216 | }; | ||
217 | |||
218 | static struct msi_domain_ops gicv2m_pmsi_ops = { | ||
219 | }; | ||
220 | |||
221 | static struct msi_domain_info gicv2m_pmsi_domain_info = { | ||
222 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS), | ||
223 | .ops = &gicv2m_pmsi_ops, | ||
224 | .chip = &gicv2m_pmsi_irq_chip, | ||
225 | }; | ||
226 | |||
216 | static int __init gicv2m_init_one(struct device_node *node, | 227 | static int __init gicv2m_init_one(struct device_node *node, |
217 | struct irq_domain *parent) | 228 | struct irq_domain *parent) |
218 | { | 229 | { |
219 | int ret; | 230 | int ret; |
220 | struct v2m_data *v2m; | 231 | struct v2m_data *v2m; |
232 | struct irq_domain *inner_domain, *pci_domain, *plat_domain; | ||
221 | 233 | ||
222 | v2m = kzalloc(sizeof(struct v2m_data), GFP_KERNEL); | 234 | v2m = kzalloc(sizeof(struct v2m_data), GFP_KERNEL); |
223 | if (!v2m) { | 235 | if (!v2m) { |
@@ -261,32 +273,28 @@ static int __init gicv2m_init_one(struct device_node *node, | |||
261 | goto err_iounmap; | 273 | goto err_iounmap; |
262 | } | 274 | } |
263 | 275 | ||
264 | v2m->domain = irq_domain_add_tree(NULL, &gicv2m_domain_ops, v2m); | 276 | inner_domain = irq_domain_add_tree(node, &gicv2m_domain_ops, v2m); |
265 | if (!v2m->domain) { | 277 | if (!inner_domain) { |
266 | pr_err("Failed to create GICv2m domain\n"); | 278 | pr_err("Failed to create GICv2m domain\n"); |
267 | ret = -ENOMEM; | 279 | ret = -ENOMEM; |
268 | goto err_free_bm; | 280 | goto err_free_bm; |
269 | } | 281 | } |
270 | 282 | ||
271 | v2m->domain->parent = parent; | 283 | inner_domain->bus_token = DOMAIN_BUS_NEXUS; |
272 | v2m->mchip.of_node = node; | 284 | inner_domain->parent = parent; |
273 | v2m->mchip.domain = pci_msi_create_irq_domain(node, | 285 | pci_domain = pci_msi_create_irq_domain(node, &gicv2m_msi_domain_info, |
274 | &gicv2m_msi_domain_info, | 286 | inner_domain); |
275 | v2m->domain); | 287 | plat_domain = platform_msi_create_irq_domain(node, |
276 | if (!v2m->mchip.domain) { | 288 | &gicv2m_pmsi_domain_info, |
277 | pr_err("Failed to create MSI domain\n"); | 289 | inner_domain); |
290 | if (!pci_domain || !plat_domain) { | ||
291 | pr_err("Failed to create MSI domains\n"); | ||
278 | ret = -ENOMEM; | 292 | ret = -ENOMEM; |
279 | goto err_free_domains; | 293 | goto err_free_domains; |
280 | } | 294 | } |
281 | 295 | ||
282 | spin_lock_init(&v2m->msi_cnt_lock); | 296 | spin_lock_init(&v2m->msi_cnt_lock); |
283 | 297 | ||
284 | ret = of_pci_msi_chip_add(&v2m->mchip); | ||
285 | if (ret) { | ||
286 | pr_err("Failed to add msi_chip.\n"); | ||
287 | goto err_free_domains; | ||
288 | } | ||
289 | |||
290 | pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name, | 298 | pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name, |
291 | (unsigned long)v2m->res.start, (unsigned long)v2m->res.end, | 299 | (unsigned long)v2m->res.start, (unsigned long)v2m->res.end, |
292 | v2m->spi_start, (v2m->spi_start + v2m->nr_spis)); | 300 | v2m->spi_start, (v2m->spi_start + v2m->nr_spis)); |
@@ -294,10 +302,12 @@ static int __init gicv2m_init_one(struct device_node *node, | |||
294 | return 0; | 302 | return 0; |
295 | 303 | ||
296 | err_free_domains: | 304 | err_free_domains: |
297 | if (v2m->mchip.domain) | 305 | if (plat_domain) |
298 | irq_domain_remove(v2m->mchip.domain); | 306 | irq_domain_remove(plat_domain); |
299 | if (v2m->domain) | 307 | if (pci_domain) |
300 | irq_domain_remove(v2m->domain); | 308 | irq_domain_remove(pci_domain); |
309 | if (inner_domain) | ||
310 | irq_domain_remove(inner_domain); | ||
301 | err_free_bm: | 311 | err_free_bm: |
302 | kfree(v2m->bm); | 312 | kfree(v2m->bm); |
303 | err_iounmap: | 313 | err_iounmap: |
diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c new file mode 100644 index 000000000000..cf351c637464 --- /dev/null +++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013-2015 ARM Limited, All Rights Reserved. | ||
3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
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 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #include <linux/msi.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/of_irq.h> | ||
21 | #include <linux/of_pci.h> | ||
22 | |||
23 | static void its_mask_msi_irq(struct irq_data *d) | ||
24 | { | ||
25 | pci_msi_mask_irq(d); | ||
26 | irq_chip_mask_parent(d); | ||
27 | } | ||
28 | |||
29 | static void its_unmask_msi_irq(struct irq_data *d) | ||
30 | { | ||
31 | pci_msi_unmask_irq(d); | ||
32 | irq_chip_unmask_parent(d); | ||
33 | } | ||
34 | |||
35 | static struct irq_chip its_msi_irq_chip = { | ||
36 | .name = "ITS-MSI", | ||
37 | .irq_unmask = its_unmask_msi_irq, | ||
38 | .irq_mask = its_mask_msi_irq, | ||
39 | .irq_eoi = irq_chip_eoi_parent, | ||
40 | .irq_write_msi_msg = pci_msi_domain_write_msg, | ||
41 | }; | ||
42 | |||
43 | struct its_pci_alias { | ||
44 | struct pci_dev *pdev; | ||
45 | u32 dev_id; | ||
46 | u32 count; | ||
47 | }; | ||
48 | |||
49 | static int its_pci_msi_vec_count(struct pci_dev *pdev) | ||
50 | { | ||
51 | int msi, msix; | ||
52 | |||
53 | msi = max(pci_msi_vec_count(pdev), 0); | ||
54 | msix = max(pci_msix_vec_count(pdev), 0); | ||
55 | |||
56 | return max(msi, msix); | ||
57 | } | ||
58 | |||
59 | static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data) | ||
60 | { | ||
61 | struct its_pci_alias *dev_alias = data; | ||
62 | |||
63 | dev_alias->dev_id = alias; | ||
64 | if (pdev != dev_alias->pdev) | ||
65 | dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int its_pci_msi_prepare(struct irq_domain *domain, struct device *dev, | ||
71 | int nvec, msi_alloc_info_t *info) | ||
72 | { | ||
73 | struct pci_dev *pdev; | ||
74 | struct its_pci_alias dev_alias; | ||
75 | struct msi_domain_info *msi_info; | ||
76 | |||
77 | if (!dev_is_pci(dev)) | ||
78 | return -EINVAL; | ||
79 | |||
80 | msi_info = msi_get_domain_info(domain->parent); | ||
81 | |||
82 | pdev = to_pci_dev(dev); | ||
83 | dev_alias.pdev = pdev; | ||
84 | dev_alias.count = nvec; | ||
85 | |||
86 | pci_for_each_dma_alias(pdev, its_get_pci_alias, &dev_alias); | ||
87 | |||
88 | /* ITS specific DeviceID, as the core ITS ignores dev. */ | ||
89 | info->scratchpad[0].ul = dev_alias.dev_id; | ||
90 | |||
91 | return msi_info->ops->msi_prepare(domain->parent, | ||
92 | dev, dev_alias.count, info); | ||
93 | } | ||
94 | |||
95 | static struct msi_domain_ops its_pci_msi_ops = { | ||
96 | .msi_prepare = its_pci_msi_prepare, | ||
97 | }; | ||
98 | |||
99 | static struct msi_domain_info its_pci_msi_domain_info = { | ||
100 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ||
101 | MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX), | ||
102 | .ops = &its_pci_msi_ops, | ||
103 | .chip = &its_msi_irq_chip, | ||
104 | }; | ||
105 | |||
106 | static struct of_device_id its_device_id[] = { | ||
107 | { .compatible = "arm,gic-v3-its", }, | ||
108 | {}, | ||
109 | }; | ||
110 | |||
111 | static int __init its_pci_msi_init(void) | ||
112 | { | ||
113 | struct device_node *np; | ||
114 | struct irq_domain *parent; | ||
115 | |||
116 | for (np = of_find_matching_node(NULL, its_device_id); np; | ||
117 | np = of_find_matching_node(np, its_device_id)) { | ||
118 | if (!of_property_read_bool(np, "msi-controller")) | ||
119 | continue; | ||
120 | |||
121 | parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS); | ||
122 | if (!parent || !msi_get_domain_info(parent)) { | ||
123 | pr_err("%s: unable to locate ITS domain\n", | ||
124 | np->full_name); | ||
125 | continue; | ||
126 | } | ||
127 | |||
128 | if (!pci_msi_create_irq_domain(np, &its_pci_msi_domain_info, | ||
129 | parent)) { | ||
130 | pr_err("%s: unable to create PCI domain\n", | ||
131 | np->full_name); | ||
132 | continue; | ||
133 | } | ||
134 | |||
135 | pr_info("PCI/MSI: %s domain created\n", np->full_name); | ||
136 | } | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | early_initcall(its_pci_msi_init); | ||
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c new file mode 100644 index 000000000000..a86550562779 --- /dev/null +++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013-2015 ARM Limited, All Rights Reserved. | ||
3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
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 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #include <linux/device.h> | ||
19 | #include <linux/msi.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_irq.h> | ||
22 | |||
23 | static struct irq_chip its_pmsi_irq_chip = { | ||
24 | .name = "ITS-pMSI", | ||
25 | }; | ||
26 | |||
27 | static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev, | ||
28 | int nvec, msi_alloc_info_t *info) | ||
29 | { | ||
30 | struct msi_domain_info *msi_info; | ||
31 | u32 dev_id; | ||
32 | int ret; | ||
33 | |||
34 | msi_info = msi_get_domain_info(domain->parent); | ||
35 | |||
36 | /* Suck the DeviceID out of the msi-parent property */ | ||
37 | ret = of_property_read_u32_index(dev->of_node, "msi-parent", | ||
38 | 1, &dev_id); | ||
39 | if (ret) | ||
40 | return ret; | ||
41 | |||
42 | /* ITS specific DeviceID, as the core ITS ignores dev. */ | ||
43 | info->scratchpad[0].ul = dev_id; | ||
44 | |||
45 | return msi_info->ops->msi_prepare(domain->parent, | ||
46 | dev, nvec, info); | ||
47 | } | ||
48 | |||
49 | static struct msi_domain_ops its_pmsi_ops = { | ||
50 | .msi_prepare = its_pmsi_prepare, | ||
51 | }; | ||
52 | |||
53 | static struct msi_domain_info its_pmsi_domain_info = { | ||
54 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS), | ||
55 | .ops = &its_pmsi_ops, | ||
56 | .chip = &its_pmsi_irq_chip, | ||
57 | }; | ||
58 | |||
59 | static struct of_device_id its_device_id[] = { | ||
60 | { .compatible = "arm,gic-v3-its", }, | ||
61 | {}, | ||
62 | }; | ||
63 | |||
64 | static int __init its_pmsi_init(void) | ||
65 | { | ||
66 | struct device_node *np; | ||
67 | struct irq_domain *parent; | ||
68 | |||
69 | for (np = of_find_matching_node(NULL, its_device_id); np; | ||
70 | np = of_find_matching_node(np, its_device_id)) { | ||
71 | if (!of_property_read_bool(np, "msi-controller")) | ||
72 | continue; | ||
73 | |||
74 | parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS); | ||
75 | if (!parent || !msi_get_domain_info(parent)) { | ||
76 | pr_err("%s: unable to locate ITS domain\n", | ||
77 | np->full_name); | ||
78 | continue; | ||
79 | } | ||
80 | |||
81 | if (!platform_msi_create_irq_domain(np, &its_pmsi_domain_info, | ||
82 | parent)) { | ||
83 | pr_err("%s: unable to create platform domain\n", | ||
84 | np->full_name); | ||
85 | continue; | ||
86 | } | ||
87 | |||
88 | pr_info("Platform MSI: %s domain created\n", np->full_name); | ||
89 | } | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | early_initcall(its_pmsi_init); | ||
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index c00e2db351ba..26b55c53755f 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
@@ -30,14 +30,13 @@ | |||
30 | #include <linux/percpu.h> | 30 | #include <linux/percpu.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | 32 | ||
33 | #include <linux/irqchip.h> | ||
33 | #include <linux/irqchip/arm-gic-v3.h> | 34 | #include <linux/irqchip/arm-gic-v3.h> |
34 | 35 | ||
35 | #include <asm/cacheflush.h> | 36 | #include <asm/cacheflush.h> |
36 | #include <asm/cputype.h> | 37 | #include <asm/cputype.h> |
37 | #include <asm/exception.h> | 38 | #include <asm/exception.h> |
38 | 39 | ||
39 | #include "irqchip.h" | ||
40 | |||
41 | #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) | 40 | #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) |
42 | 41 | ||
43 | #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) | 42 | #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) |
@@ -54,14 +53,12 @@ struct its_collection { | |||
54 | 53 | ||
55 | /* | 54 | /* |
56 | * The ITS structure - contains most of the infrastructure, with the | 55 | * The ITS structure - contains most of the infrastructure, with the |
57 | * msi_controller, the command queue, the collections, and the list of | 56 | * top-level MSI domain, the command queue, the collections, and the |
58 | * devices writing to it. | 57 | * list of devices writing to it. |
59 | */ | 58 | */ |
60 | struct its_node { | 59 | struct its_node { |
61 | raw_spinlock_t lock; | 60 | raw_spinlock_t lock; |
62 | struct list_head entry; | 61 | struct list_head entry; |
63 | struct msi_controller msi_chip; | ||
64 | struct irq_domain *domain; | ||
65 | void __iomem *base; | 62 | void __iomem *base; |
66 | unsigned long phys_base; | 63 | unsigned long phys_base; |
67 | struct its_cmd_block *cmd_base; | 64 | struct its_cmd_block *cmd_base; |
@@ -643,26 +640,6 @@ static struct irq_chip its_irq_chip = { | |||
643 | .irq_compose_msi_msg = its_irq_compose_msi_msg, | 640 | .irq_compose_msi_msg = its_irq_compose_msi_msg, |
644 | }; | 641 | }; |
645 | 642 | ||
646 | static void its_mask_msi_irq(struct irq_data *d) | ||
647 | { | ||
648 | pci_msi_mask_irq(d); | ||
649 | irq_chip_mask_parent(d); | ||
650 | } | ||
651 | |||
652 | static void its_unmask_msi_irq(struct irq_data *d) | ||
653 | { | ||
654 | pci_msi_unmask_irq(d); | ||
655 | irq_chip_unmask_parent(d); | ||
656 | } | ||
657 | |||
658 | static struct irq_chip its_msi_irq_chip = { | ||
659 | .name = "ITS-MSI", | ||
660 | .irq_unmask = its_unmask_msi_irq, | ||
661 | .irq_mask = its_mask_msi_irq, | ||
662 | .irq_eoi = irq_chip_eoi_parent, | ||
663 | .irq_write_msi_msg = pci_msi_domain_write_msg, | ||
664 | }; | ||
665 | |||
666 | /* | 643 | /* |
667 | * How we allocate LPIs: | 644 | * How we allocate LPIs: |
668 | * | 645 | * |
@@ -831,7 +808,7 @@ static void its_free_tables(struct its_node *its) | |||
831 | } | 808 | } |
832 | } | 809 | } |
833 | 810 | ||
834 | static int its_alloc_tables(struct its_node *its) | 811 | static int its_alloc_tables(const char *node_name, struct its_node *its) |
835 | { | 812 | { |
836 | int err; | 813 | int err; |
837 | int i; | 814 | int i; |
@@ -874,7 +851,7 @@ static int its_alloc_tables(struct its_node *its) | |||
874 | if (order >= MAX_ORDER) { | 851 | if (order >= MAX_ORDER) { |
875 | order = MAX_ORDER - 1; | 852 | order = MAX_ORDER - 1; |
876 | pr_warn("%s: Device Table too large, reduce its page order to %u\n", | 853 | pr_warn("%s: Device Table too large, reduce its page order to %u\n", |
877 | its->msi_chip.of_node->full_name, order); | 854 | node_name, order); |
878 | } | 855 | } |
879 | } | 856 | } |
880 | 857 | ||
@@ -944,7 +921,7 @@ retry_baser: | |||
944 | 921 | ||
945 | if (val != tmp) { | 922 | if (val != tmp) { |
946 | pr_err("ITS: %s: GITS_BASER%d doesn't stick: %lx %lx\n", | 923 | pr_err("ITS: %s: GITS_BASER%d doesn't stick: %lx %lx\n", |
947 | its->msi_chip.of_node->full_name, i, | 924 | node_name, i, |
948 | (unsigned long) val, (unsigned long) tmp); | 925 | (unsigned long) val, (unsigned long) tmp); |
949 | err = -ENXIO; | 926 | err = -ENXIO; |
950 | goto out_free; | 927 | goto out_free; |
@@ -1209,85 +1186,50 @@ static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq) | |||
1209 | return 0; | 1186 | return 0; |
1210 | } | 1187 | } |
1211 | 1188 | ||
1212 | struct its_pci_alias { | ||
1213 | struct pci_dev *pdev; | ||
1214 | u32 dev_id; | ||
1215 | u32 count; | ||
1216 | }; | ||
1217 | |||
1218 | static int its_pci_msi_vec_count(struct pci_dev *pdev) | ||
1219 | { | ||
1220 | int msi, msix; | ||
1221 | |||
1222 | msi = max(pci_msi_vec_count(pdev), 0); | ||
1223 | msix = max(pci_msix_vec_count(pdev), 0); | ||
1224 | |||
1225 | return max(msi, msix); | ||
1226 | } | ||
1227 | |||
1228 | static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data) | ||
1229 | { | ||
1230 | struct its_pci_alias *dev_alias = data; | ||
1231 | |||
1232 | dev_alias->dev_id = alias; | ||
1233 | if (pdev != dev_alias->pdev) | ||
1234 | dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev); | ||
1235 | |||
1236 | return 0; | ||
1237 | } | ||
1238 | |||
1239 | static int its_msi_prepare(struct irq_domain *domain, struct device *dev, | 1189 | static int its_msi_prepare(struct irq_domain *domain, struct device *dev, |
1240 | int nvec, msi_alloc_info_t *info) | 1190 | int nvec, msi_alloc_info_t *info) |
1241 | { | 1191 | { |
1242 | struct pci_dev *pdev; | ||
1243 | struct its_node *its; | 1192 | struct its_node *its; |
1244 | struct its_device *its_dev; | 1193 | struct its_device *its_dev; |
1245 | struct its_pci_alias dev_alias; | 1194 | struct msi_domain_info *msi_info; |
1246 | 1195 | u32 dev_id; | |
1247 | if (!dev_is_pci(dev)) | ||
1248 | return -EINVAL; | ||
1249 | 1196 | ||
1250 | pdev = to_pci_dev(dev); | 1197 | /* |
1251 | dev_alias.pdev = pdev; | 1198 | * We ignore "dev" entierely, and rely on the dev_id that has |
1252 | dev_alias.count = nvec; | 1199 | * been passed via the scratchpad. This limits this domain's |
1200 | * usefulness to upper layers that definitely know that they | ||
1201 | * are built on top of the ITS. | ||
1202 | */ | ||
1203 | dev_id = info->scratchpad[0].ul; | ||
1253 | 1204 | ||
1254 | pci_for_each_dma_alias(pdev, its_get_pci_alias, &dev_alias); | 1205 | msi_info = msi_get_domain_info(domain); |
1255 | its = domain->parent->host_data; | 1206 | its = msi_info->data; |
1256 | 1207 | ||
1257 | its_dev = its_find_device(its, dev_alias.dev_id); | 1208 | its_dev = its_find_device(its, dev_id); |
1258 | if (its_dev) { | 1209 | if (its_dev) { |
1259 | /* | 1210 | /* |
1260 | * We already have seen this ID, probably through | 1211 | * We already have seen this ID, probably through |
1261 | * another alias (PCI bridge of some sort). No need to | 1212 | * another alias (PCI bridge of some sort). No need to |
1262 | * create the device. | 1213 | * create the device. |
1263 | */ | 1214 | */ |
1264 | dev_dbg(dev, "Reusing ITT for devID %x\n", dev_alias.dev_id); | 1215 | pr_debug("Reusing ITT for devID %x\n", dev_id); |
1265 | goto out; | 1216 | goto out; |
1266 | } | 1217 | } |
1267 | 1218 | ||
1268 | its_dev = its_create_device(its, dev_alias.dev_id, dev_alias.count); | 1219 | its_dev = its_create_device(its, dev_id, nvec); |
1269 | if (!its_dev) | 1220 | if (!its_dev) |
1270 | return -ENOMEM; | 1221 | return -ENOMEM; |
1271 | 1222 | ||
1272 | dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n", | 1223 | pr_debug("ITT %d entries, %d bits\n", nvec, ilog2(nvec)); |
1273 | dev_alias.count, ilog2(dev_alias.count)); | ||
1274 | out: | 1224 | out: |
1275 | info->scratchpad[0].ptr = its_dev; | 1225 | info->scratchpad[0].ptr = its_dev; |
1276 | info->scratchpad[1].ptr = dev; | ||
1277 | return 0; | 1226 | return 0; |
1278 | } | 1227 | } |
1279 | 1228 | ||
1280 | static struct msi_domain_ops its_pci_msi_ops = { | 1229 | static struct msi_domain_ops its_msi_domain_ops = { |
1281 | .msi_prepare = its_msi_prepare, | 1230 | .msi_prepare = its_msi_prepare, |
1282 | }; | 1231 | }; |
1283 | 1232 | ||
1284 | static struct msi_domain_info its_pci_msi_domain_info = { | ||
1285 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ||
1286 | MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX), | ||
1287 | .ops = &its_pci_msi_ops, | ||
1288 | .chip = &its_msi_irq_chip, | ||
1289 | }; | ||
1290 | |||
1291 | static int its_irq_gic_domain_alloc(struct irq_domain *domain, | 1233 | static int its_irq_gic_domain_alloc(struct irq_domain *domain, |
1292 | unsigned int virq, | 1234 | unsigned int virq, |
1293 | irq_hw_number_t hwirq) | 1235 | irq_hw_number_t hwirq) |
@@ -1323,9 +1265,9 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
1323 | 1265 | ||
1324 | irq_domain_set_hwirq_and_chip(domain, virq + i, | 1266 | irq_domain_set_hwirq_and_chip(domain, virq + i, |
1325 | hwirq, &its_irq_chip, its_dev); | 1267 | hwirq, &its_irq_chip, its_dev); |
1326 | dev_dbg(info->scratchpad[1].ptr, "ID:%d pID:%d vID:%d\n", | 1268 | pr_debug("ID:%d pID:%d vID:%d\n", |
1327 | (int)(hwirq - its_dev->event_map.lpi_base), | 1269 | (int)(hwirq - its_dev->event_map.lpi_base), |
1328 | (int)hwirq, virq + i); | 1270 | (int) hwirq, virq + i); |
1329 | } | 1271 | } |
1330 | 1272 | ||
1331 | return 0; | 1273 | return 0; |
@@ -1426,6 +1368,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
1426 | struct resource res; | 1368 | struct resource res; |
1427 | struct its_node *its; | 1369 | struct its_node *its; |
1428 | void __iomem *its_base; | 1370 | void __iomem *its_base; |
1371 | struct irq_domain *inner_domain; | ||
1429 | u32 val; | 1372 | u32 val; |
1430 | u64 baser, tmp; | 1373 | u64 baser, tmp; |
1431 | int err; | 1374 | int err; |
@@ -1469,7 +1412,6 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
1469 | INIT_LIST_HEAD(&its->its_device_list); | 1412 | INIT_LIST_HEAD(&its->its_device_list); |
1470 | its->base = its_base; | 1413 | its->base = its_base; |
1471 | its->phys_base = res.start; | 1414 | its->phys_base = res.start; |
1472 | its->msi_chip.of_node = node; | ||
1473 | its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1; | 1415 | its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1; |
1474 | 1416 | ||
1475 | its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL); | 1417 | its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL); |
@@ -1479,7 +1421,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
1479 | } | 1421 | } |
1480 | its->cmd_write = its->cmd_base; | 1422 | its->cmd_write = its->cmd_base; |
1481 | 1423 | ||
1482 | err = its_alloc_tables(its); | 1424 | err = its_alloc_tables(node->full_name, its); |
1483 | if (err) | 1425 | if (err) |
1484 | goto out_free_cmd; | 1426 | goto out_free_cmd; |
1485 | 1427 | ||
@@ -1515,26 +1457,27 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
1515 | writeq_relaxed(0, its->base + GITS_CWRITER); | 1457 | writeq_relaxed(0, its->base + GITS_CWRITER); |
1516 | writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR); | 1458 | writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR); |
1517 | 1459 | ||
1518 | if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) { | 1460 | if (of_property_read_bool(node, "msi-controller")) { |
1519 | its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its); | 1461 | struct msi_domain_info *info; |
1520 | if (!its->domain) { | 1462 | |
1463 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
1464 | if (!info) { | ||
1521 | err = -ENOMEM; | 1465 | err = -ENOMEM; |
1522 | goto out_free_tables; | 1466 | goto out_free_tables; |
1523 | } | 1467 | } |
1524 | 1468 | ||
1525 | its->domain->parent = parent; | 1469 | inner_domain = irq_domain_add_tree(node, &its_domain_ops, its); |
1526 | 1470 | if (!inner_domain) { | |
1527 | its->msi_chip.domain = pci_msi_create_irq_domain(node, | ||
1528 | &its_pci_msi_domain_info, | ||
1529 | its->domain); | ||
1530 | if (!its->msi_chip.domain) { | ||
1531 | err = -ENOMEM; | 1471 | err = -ENOMEM; |
1532 | goto out_free_domains; | 1472 | kfree(info); |
1473 | goto out_free_tables; | ||
1533 | } | 1474 | } |
1534 | 1475 | ||
1535 | err = of_pci_msi_chip_add(&its->msi_chip); | 1476 | inner_domain->parent = parent; |
1536 | if (err) | 1477 | inner_domain->bus_token = DOMAIN_BUS_NEXUS; |
1537 | goto out_free_domains; | 1478 | info->ops = &its_msi_domain_ops; |
1479 | info->data = its; | ||
1480 | inner_domain->host_data = info; | ||
1538 | } | 1481 | } |
1539 | 1482 | ||
1540 | spin_lock(&its_lock); | 1483 | spin_lock(&its_lock); |
@@ -1543,11 +1486,6 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
1543 | 1486 | ||
1544 | return 0; | 1487 | return 0; |
1545 | 1488 | ||
1546 | out_free_domains: | ||
1547 | if (its->msi_chip.domain) | ||
1548 | irq_domain_remove(its->msi_chip.domain); | ||
1549 | if (its->domain) | ||
1550 | irq_domain_remove(its->domain); | ||
1551 | out_free_tables: | 1489 | out_free_tables: |
1552 | its_free_tables(its); | 1490 | its_free_tables(its); |
1553 | out_free_cmd: | 1491 | out_free_cmd: |
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index c52f7ba205b4..e406bc5f13e4 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/percpu.h> | 25 | #include <linux/percpu.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | 27 | ||
28 | #include <linux/irqchip.h> | ||
28 | #include <linux/irqchip/arm-gic-v3.h> | 29 | #include <linux/irqchip/arm-gic-v3.h> |
29 | 30 | ||
30 | #include <asm/cputype.h> | 31 | #include <asm/cputype.h> |
@@ -32,7 +33,6 @@ | |||
32 | #include <asm/smp_plat.h> | 33 | #include <asm/smp_plat.h> |
33 | 34 | ||
34 | #include "irq-gic-common.h" | 35 | #include "irq-gic-common.h" |
35 | #include "irqchip.h" | ||
36 | 36 | ||
37 | struct redist_region { | 37 | struct redist_region { |
38 | void __iomem *redist_base; | 38 | void __iomem *redist_base; |
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4dd88264dff5..aa3e7b8a69c4 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
39 | #include <linux/percpu.h> | 39 | #include <linux/percpu.h> |
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | #include <linux/irqchip.h> | ||
41 | #include <linux/irqchip/chained_irq.h> | 42 | #include <linux/irqchip/chained_irq.h> |
42 | #include <linux/irqchip/arm-gic.h> | 43 | #include <linux/irqchip/arm-gic.h> |
43 | #include <linux/irqchip/arm-gic-acpi.h> | 44 | #include <linux/irqchip/arm-gic-acpi.h> |
@@ -48,7 +49,6 @@ | |||
48 | #include <asm/smp_plat.h> | 49 | #include <asm/smp_plat.h> |
49 | 50 | ||
50 | #include "irq-gic-common.h" | 51 | #include "irq-gic-common.h" |
51 | #include "irqchip.h" | ||
52 | 52 | ||
53 | union gic_base { | 53 | union gic_base { |
54 | void __iomem *common_base; | 54 | void __iomem *common_base; |
@@ -288,8 +288,8 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) | |||
288 | 288 | ||
289 | static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | 289 | static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) |
290 | { | 290 | { |
291 | struct gic_chip_data *chip_data = irq_get_handler_data(irq); | 291 | struct gic_chip_data *chip_data = irq_desc_get_handler_data(desc); |
292 | struct irq_chip *chip = irq_get_chip(irq); | 292 | struct irq_chip *chip = irq_desc_get_chip(desc); |
293 | unsigned int cascade_irq, gic_irq; | 293 | unsigned int cascade_irq, gic_irq; |
294 | unsigned long status; | 294 | unsigned long status; |
295 | 295 | ||
@@ -324,16 +324,17 @@ static struct irq_chip gic_chip = { | |||
324 | #endif | 324 | #endif |
325 | .irq_get_irqchip_state = gic_irq_get_irqchip_state, | 325 | .irq_get_irqchip_state = gic_irq_get_irqchip_state, |
326 | .irq_set_irqchip_state = gic_irq_set_irqchip_state, | 326 | .irq_set_irqchip_state = gic_irq_set_irqchip_state, |
327 | .flags = IRQCHIP_SET_TYPE_MASKED, | 327 | .flags = IRQCHIP_SET_TYPE_MASKED | |
328 | IRQCHIP_SKIP_SET_WAKE | | ||
329 | IRQCHIP_MASK_ON_SUSPEND, | ||
328 | }; | 330 | }; |
329 | 331 | ||
330 | void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) | 332 | void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) |
331 | { | 333 | { |
332 | if (gic_nr >= MAX_GIC_NR) | 334 | if (gic_nr >= MAX_GIC_NR) |
333 | BUG(); | 335 | BUG(); |
334 | if (irq_set_handler_data(irq, &gic_data[gic_nr]) != 0) | 336 | irq_set_chained_handler_and_data(irq, gic_handle_cascade_irq, |
335 | BUG(); | 337 | &gic_data[gic_nr]); |
336 | irq_set_chained_handler(irq, gic_handle_cascade_irq); | ||
337 | } | 338 | } |
338 | 339 | ||
339 | static u8 gic_get_cpumask(struct gic_chip_data *gic) | 340 | static u8 gic_get_cpumask(struct gic_chip_data *gic) |
@@ -355,9 +356,9 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic) | |||
355 | return mask; | 356 | return mask; |
356 | } | 357 | } |
357 | 358 | ||
358 | static void gic_cpu_if_up(void) | 359 | static void gic_cpu_if_up(struct gic_chip_data *gic) |
359 | { | 360 | { |
360 | void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]); | 361 | void __iomem *cpu_base = gic_data_cpu_base(gic); |
361 | u32 bypass = 0; | 362 | u32 bypass = 0; |
362 | 363 | ||
363 | /* | 364 | /* |
@@ -401,34 +402,47 @@ static void gic_cpu_init(struct gic_chip_data *gic) | |||
401 | int i; | 402 | int i; |
402 | 403 | ||
403 | /* | 404 | /* |
404 | * Get what the GIC says our CPU mask is. | 405 | * Setting up the CPU map is only relevant for the primary GIC |
406 | * because any nested/secondary GICs do not directly interface | ||
407 | * with the CPU(s). | ||
405 | */ | 408 | */ |
406 | BUG_ON(cpu >= NR_GIC_CPU_IF); | 409 | if (gic == &gic_data[0]) { |
407 | cpu_mask = gic_get_cpumask(gic); | 410 | /* |
408 | gic_cpu_map[cpu] = cpu_mask; | 411 | * Get what the GIC says our CPU mask is. |
412 | */ | ||
413 | BUG_ON(cpu >= NR_GIC_CPU_IF); | ||
414 | cpu_mask = gic_get_cpumask(gic); | ||
415 | gic_cpu_map[cpu] = cpu_mask; | ||
409 | 416 | ||
410 | /* | 417 | /* |
411 | * Clear our mask from the other map entries in case they're | 418 | * Clear our mask from the other map entries in case they're |
412 | * still undefined. | 419 | * still undefined. |
413 | */ | 420 | */ |
414 | for (i = 0; i < NR_GIC_CPU_IF; i++) | 421 | for (i = 0; i < NR_GIC_CPU_IF; i++) |
415 | if (i != cpu) | 422 | if (i != cpu) |
416 | gic_cpu_map[i] &= ~cpu_mask; | 423 | gic_cpu_map[i] &= ~cpu_mask; |
424 | } | ||
417 | 425 | ||
418 | gic_cpu_config(dist_base, NULL); | 426 | gic_cpu_config(dist_base, NULL); |
419 | 427 | ||
420 | writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK); | 428 | writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK); |
421 | gic_cpu_if_up(); | 429 | gic_cpu_if_up(gic); |
422 | } | 430 | } |
423 | 431 | ||
424 | void gic_cpu_if_down(void) | 432 | int gic_cpu_if_down(unsigned int gic_nr) |
425 | { | 433 | { |
426 | void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]); | 434 | void __iomem *cpu_base; |
427 | u32 val = 0; | 435 | u32 val = 0; |
428 | 436 | ||
437 | if (gic_nr >= MAX_GIC_NR) | ||
438 | return -EINVAL; | ||
439 | |||
440 | cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); | ||
429 | val = readl(cpu_base + GIC_CPU_CTRL); | 441 | val = readl(cpu_base + GIC_CPU_CTRL); |
430 | val &= ~GICC_ENABLE; | 442 | val &= ~GICC_ENABLE; |
431 | writel_relaxed(val, cpu_base + GIC_CPU_CTRL); | 443 | writel_relaxed(val, cpu_base + GIC_CPU_CTRL); |
444 | |||
445 | return 0; | ||
432 | } | 446 | } |
433 | 447 | ||
434 | #ifdef CONFIG_CPU_PM | 448 | #ifdef CONFIG_CPU_PM |
@@ -564,7 +578,7 @@ static void gic_cpu_restore(unsigned int gic_nr) | |||
564 | dist_base + GIC_DIST_PRI + i * 4); | 578 | dist_base + GIC_DIST_PRI + i * 4); |
565 | 579 | ||
566 | writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK); | 580 | writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK); |
567 | gic_cpu_if_up(); | 581 | gic_cpu_if_up(&gic_data[gic_nr]); |
568 | } | 582 | } |
569 | 583 | ||
570 | static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) | 584 | static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) |
@@ -880,11 +894,6 @@ static const struct irq_domain_ops gic_irq_domain_ops = { | |||
880 | .xlate = gic_irq_domain_xlate, | 894 | .xlate = gic_irq_domain_xlate, |
881 | }; | 895 | }; |
882 | 896 | ||
883 | void gic_set_irqchip_flags(unsigned long flags) | ||
884 | { | ||
885 | gic_chip.flags |= flags; | ||
886 | } | ||
887 | |||
888 | void __init gic_init_bases(unsigned int gic_nr, int irq_start, | 897 | void __init gic_init_bases(unsigned int gic_nr, int irq_start, |
889 | void __iomem *dist_base, void __iomem *cpu_base, | 898 | void __iomem *dist_base, void __iomem *cpu_base, |
890 | u32 percpu_offset, struct device_node *node) | 899 | u32 percpu_offset, struct device_node *node) |
@@ -930,13 +939,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
930 | } | 939 | } |
931 | 940 | ||
932 | /* | 941 | /* |
933 | * Initialize the CPU interface map to all CPUs. | ||
934 | * It will be refined as each CPU probes its ID. | ||
935 | */ | ||
936 | for (i = 0; i < NR_GIC_CPU_IF; i++) | ||
937 | gic_cpu_map[i] = 0xff; | ||
938 | |||
939 | /* | ||
940 | * Find out how many interrupts are supported. | 942 | * Find out how many interrupts are supported. |
941 | * The GIC only supports up to 1020 interrupt sources. | 943 | * The GIC only supports up to 1020 interrupt sources. |
942 | */ | 944 | */ |
@@ -981,6 +983,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
981 | return; | 983 | return; |
982 | 984 | ||
983 | if (gic_nr == 0) { | 985 | if (gic_nr == 0) { |
986 | /* | ||
987 | * Initialize the CPU interface map to all CPUs. | ||
988 | * It will be refined as each CPU probes its ID. | ||
989 | * This is only necessary for the primary GIC. | ||
990 | */ | ||
991 | for (i = 0; i < NR_GIC_CPU_IF; i++) | ||
992 | gic_cpu_map[i] = 0xff; | ||
984 | #ifdef CONFIG_SMP | 993 | #ifdef CONFIG_SMP |
985 | set_smp_cross_call(gic_raise_softirq); | 994 | set_smp_cross_call(gic_raise_softirq); |
986 | register_cpu_notifier(&gic_cpu_notifier); | 995 | register_cpu_notifier(&gic_cpu_notifier); |
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c index 0cae45d10695..a0128c7c98dd 100644 --- a/drivers/irqchip/irq-hip04.c +++ b/drivers/irqchip/irq-hip04.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/irqdomain.h> | 41 | #include <linux/irqdomain.h> |
42 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/irqchip.h> | ||
44 | #include <linux/irqchip/arm-gic.h> | 45 | #include <linux/irqchip/arm-gic.h> |
45 | 46 | ||
46 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
@@ -48,7 +49,6 @@ | |||
48 | #include <asm/smp_plat.h> | 49 | #include <asm/smp_plat.h> |
49 | 50 | ||
50 | #include "irq-gic-common.h" | 51 | #include "irq-gic-common.h" |
51 | #include "irqchip.h" | ||
52 | 52 | ||
53 | #define HIP04_MAX_IRQS 510 | 53 | #define HIP04_MAX_IRQS 510 |
54 | 54 | ||
@@ -202,7 +202,9 @@ static struct irq_chip hip04_irq_chip = { | |||
202 | #ifdef CONFIG_SMP | 202 | #ifdef CONFIG_SMP |
203 | .irq_set_affinity = hip04_irq_set_affinity, | 203 | .irq_set_affinity = hip04_irq_set_affinity, |
204 | #endif | 204 | #endif |
205 | .flags = IRQCHIP_SET_TYPE_MASKED, | 205 | .flags = IRQCHIP_SET_TYPE_MASKED | |
206 | IRQCHIP_SKIP_SET_WAKE | | ||
207 | IRQCHIP_MASK_ON_SUSPEND, | ||
206 | }; | 208 | }; |
207 | 209 | ||
208 | static u16 hip04_get_cpumask(struct hip04_irq_data *intc) | 210 | static u16 hip04_get_cpumask(struct hip04_irq_data *intc) |
diff --git a/arch/mips/kernel/i8259.c b/drivers/irqchip/irq-i8259.c index 74f6752814d3..4836102ba312 100644 --- a/arch/mips/kernel/i8259.c +++ b/drivers/irqchip/irq-i8259.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/ioport.h> | 13 | #include <linux/ioport.h> |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/irqchip.h> | ||
15 | #include <linux/irqdomain.h> | 16 | #include <linux/irqdomain.h> |
16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
17 | #include <linux/of_irq.h> | 18 | #include <linux/of_irq.h> |
@@ -22,8 +23,6 @@ | |||
22 | #include <asm/i8259.h> | 23 | #include <asm/i8259.h> |
23 | #include <asm/io.h> | 24 | #include <asm/io.h> |
24 | 25 | ||
25 | #include "../../drivers/irqchip/irqchip.h" | ||
26 | |||
27 | /* | 26 | /* |
28 | * This is the 'legacy' 8259A Programmable Interrupt Controller, | 27 | * This is the 'legacy' 8259A Programmable Interrupt Controller, |
29 | * present in the majority of PC/AT boxes. | 28 | * present in the majority of PC/AT boxes. |
@@ -353,10 +352,11 @@ void __init init_i8259_irqs(void) | |||
353 | __init_i8259_irqs(NULL); | 352 | __init_i8259_irqs(NULL); |
354 | } | 353 | } |
355 | 354 | ||
356 | static void i8259_irq_dispatch(unsigned int irq, struct irq_desc *desc) | 355 | static void i8259_irq_dispatch(unsigned int __irq, struct irq_desc *desc) |
357 | { | 356 | { |
358 | struct irq_domain *domain = irq_get_handler_data(irq); | 357 | struct irq_domain *domain = irq_desc_get_handler_data(desc); |
359 | int hwirq = i8259_irq(); | 358 | int hwirq = i8259_irq(); |
359 | unsigned int irq; | ||
360 | 360 | ||
361 | if (hwirq < 0) | 361 | if (hwirq < 0) |
362 | return; | 362 | return; |
diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c index 8071c2eb0248..841604b81004 100644 --- a/drivers/irqchip/irq-imgpdc.c +++ b/drivers/irqchip/irq-imgpdc.c | |||
@@ -218,8 +218,9 @@ static int pdc_irq_set_wake(struct irq_data *data, unsigned int on) | |||
218 | return 0; | 218 | return 0; |
219 | } | 219 | } |
220 | 220 | ||
221 | static void pdc_intc_perip_isr(unsigned int irq, struct irq_desc *desc) | 221 | static void pdc_intc_perip_isr(unsigned int __irq, struct irq_desc *desc) |
222 | { | 222 | { |
223 | unsigned int irq = irq_desc_get_irq(desc); | ||
223 | struct pdc_intc_priv *priv; | 224 | struct pdc_intc_priv *priv; |
224 | unsigned int i, irq_no; | 225 | unsigned int i, irq_no; |
225 | 226 | ||
@@ -451,13 +452,13 @@ static int pdc_intc_probe(struct platform_device *pdev) | |||
451 | /* Setup chained handlers for the peripheral IRQs */ | 452 | /* Setup chained handlers for the peripheral IRQs */ |
452 | for (i = 0; i < priv->nr_perips; ++i) { | 453 | for (i = 0; i < priv->nr_perips; ++i) { |
453 | irq = priv->perip_irqs[i]; | 454 | irq = priv->perip_irqs[i]; |
454 | irq_set_handler_data(irq, priv); | 455 | irq_set_chained_handler_and_data(irq, pdc_intc_perip_isr, |
455 | irq_set_chained_handler(irq, pdc_intc_perip_isr); | 456 | priv); |
456 | } | 457 | } |
457 | 458 | ||
458 | /* Setup chained handler for the syswake IRQ */ | 459 | /* Setup chained handler for the syswake IRQ */ |
459 | irq_set_handler_data(priv->syswake_irq, priv); | 460 | irq_set_chained_handler_and_data(priv->syswake_irq, |
460 | irq_set_chained_handler(priv->syswake_irq, pdc_intc_syswake_isr); | 461 | pdc_intc_syswake_isr, priv); |
461 | 462 | ||
462 | dev_info(&pdev->dev, | 463 | dev_info(&pdev->dev, |
463 | "PDC IRQ controller initialised (%u perip IRQs, %u syswake IRQs)\n", | 464 | "PDC IRQ controller initialised (%u perip IRQs, %u syswake IRQs)\n", |
diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c new file mode 100644 index 000000000000..e48d3305456f --- /dev/null +++ b/drivers/irqchip/irq-imx-gpcv2.c | |||
@@ -0,0 +1,278 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/of_address.h> | ||
10 | #include <linux/of_irq.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/irqchip.h> | ||
13 | #include <linux/syscore_ops.h> | ||
14 | |||
15 | #define IMR_NUM 4 | ||
16 | #define GPC_MAX_IRQS (IMR_NUM * 32) | ||
17 | |||
18 | #define GPC_IMR1_CORE0 0x30 | ||
19 | #define GPC_IMR1_CORE1 0x40 | ||
20 | |||
21 | struct gpcv2_irqchip_data { | ||
22 | struct raw_spinlock rlock; | ||
23 | void __iomem *gpc_base; | ||
24 | u32 wakeup_sources[IMR_NUM]; | ||
25 | u32 saved_irq_mask[IMR_NUM]; | ||
26 | u32 cpu2wakeup; | ||
27 | }; | ||
28 | |||
29 | static struct gpcv2_irqchip_data *imx_gpcv2_instance; | ||
30 | |||
31 | /* | ||
32 | * Interface for the low level wakeup code. | ||
33 | */ | ||
34 | u32 imx_gpcv2_get_wakeup_source(u32 **sources) | ||
35 | { | ||
36 | if (!imx_gpcv2_instance) | ||
37 | return 0; | ||
38 | |||
39 | if (sources) | ||
40 | *sources = imx_gpcv2_instance->wakeup_sources; | ||
41 | |||
42 | return IMR_NUM; | ||
43 | } | ||
44 | |||
45 | static int gpcv2_wakeup_source_save(void) | ||
46 | { | ||
47 | struct gpcv2_irqchip_data *cd; | ||
48 | void __iomem *reg; | ||
49 | int i; | ||
50 | |||
51 | cd = imx_gpcv2_instance; | ||
52 | if (!cd) | ||
53 | return 0; | ||
54 | |||
55 | for (i = 0; i < IMR_NUM; i++) { | ||
56 | reg = cd->gpc_base + cd->cpu2wakeup + i * 4; | ||
57 | cd->saved_irq_mask[i] = readl_relaxed(reg); | ||
58 | writel_relaxed(cd->wakeup_sources[i], reg); | ||
59 | } | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static void gpcv2_wakeup_source_restore(void) | ||
65 | { | ||
66 | struct gpcv2_irqchip_data *cd; | ||
67 | void __iomem *reg; | ||
68 | int i; | ||
69 | |||
70 | cd = imx_gpcv2_instance; | ||
71 | if (!cd) | ||
72 | return; | ||
73 | |||
74 | for (i = 0; i < IMR_NUM; i++) { | ||
75 | reg = cd->gpc_base + cd->cpu2wakeup + i * 4; | ||
76 | writel_relaxed(cd->saved_irq_mask[i], reg); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | static struct syscore_ops imx_gpcv2_syscore_ops = { | ||
81 | .suspend = gpcv2_wakeup_source_save, | ||
82 | .resume = gpcv2_wakeup_source_restore, | ||
83 | }; | ||
84 | |||
85 | static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on) | ||
86 | { | ||
87 | struct gpcv2_irqchip_data *cd = d->chip_data; | ||
88 | unsigned int idx = d->hwirq / 32; | ||
89 | unsigned long flags; | ||
90 | void __iomem *reg; | ||
91 | u32 mask, val; | ||
92 | |||
93 | raw_spin_lock_irqsave(&cd->rlock, flags); | ||
94 | reg = cd->gpc_base + cd->cpu2wakeup + idx * 4; | ||
95 | mask = 1 << d->hwirq % 32; | ||
96 | val = cd->wakeup_sources[idx]; | ||
97 | |||
98 | cd->wakeup_sources[idx] = on ? (val & ~mask) : (val | mask); | ||
99 | raw_spin_unlock_irqrestore(&cd->rlock, flags); | ||
100 | |||
101 | /* | ||
102 | * Do *not* call into the parent, as the GIC doesn't have any | ||
103 | * wake-up facility... | ||
104 | */ | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static void imx_gpcv2_irq_unmask(struct irq_data *d) | ||
110 | { | ||
111 | struct gpcv2_irqchip_data *cd = d->chip_data; | ||
112 | void __iomem *reg; | ||
113 | u32 val; | ||
114 | |||
115 | raw_spin_lock(&cd->rlock); | ||
116 | reg = cd->gpc_base + cd->cpu2wakeup + d->hwirq / 32 * 4; | ||
117 | val = readl_relaxed(reg); | ||
118 | val &= ~(1 << d->hwirq % 32); | ||
119 | writel_relaxed(val, reg); | ||
120 | raw_spin_unlock(&cd->rlock); | ||
121 | |||
122 | irq_chip_unmask_parent(d); | ||
123 | } | ||
124 | |||
125 | static void imx_gpcv2_irq_mask(struct irq_data *d) | ||
126 | { | ||
127 | struct gpcv2_irqchip_data *cd = d->chip_data; | ||
128 | void __iomem *reg; | ||
129 | u32 val; | ||
130 | |||
131 | raw_spin_lock(&cd->rlock); | ||
132 | reg = cd->gpc_base + cd->cpu2wakeup + d->hwirq / 32 * 4; | ||
133 | val = readl_relaxed(reg); | ||
134 | val |= 1 << (d->hwirq % 32); | ||
135 | writel_relaxed(val, reg); | ||
136 | raw_spin_unlock(&cd->rlock); | ||
137 | |||
138 | irq_chip_mask_parent(d); | ||
139 | } | ||
140 | |||
141 | static struct irq_chip gpcv2_irqchip_data_chip = { | ||
142 | .name = "GPCv2", | ||
143 | .irq_eoi = irq_chip_eoi_parent, | ||
144 | .irq_mask = imx_gpcv2_irq_mask, | ||
145 | .irq_unmask = imx_gpcv2_irq_unmask, | ||
146 | .irq_set_wake = imx_gpcv2_irq_set_wake, | ||
147 | .irq_retrigger = irq_chip_retrigger_hierarchy, | ||
148 | #ifdef CONFIG_SMP | ||
149 | .irq_set_affinity = irq_chip_set_affinity_parent, | ||
150 | #endif | ||
151 | }; | ||
152 | |||
153 | static int imx_gpcv2_domain_xlate(struct irq_domain *domain, | ||
154 | struct device_node *controller, | ||
155 | const u32 *intspec, | ||
156 | unsigned int intsize, | ||
157 | unsigned long *out_hwirq, | ||
158 | unsigned int *out_type) | ||
159 | { | ||
160 | /* Shouldn't happen, really... */ | ||
161 | if (domain->of_node != controller) | ||
162 | return -EINVAL; | ||
163 | |||
164 | /* Not GIC compliant */ | ||
165 | if (intsize != 3) | ||
166 | return -EINVAL; | ||
167 | |||
168 | /* No PPI should point to this domain */ | ||
169 | if (intspec[0] != 0) | ||
170 | return -EINVAL; | ||
171 | |||
172 | *out_hwirq = intspec[1]; | ||
173 | *out_type = intspec[2]; | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int imx_gpcv2_domain_alloc(struct irq_domain *domain, | ||
178 | unsigned int irq, unsigned int nr_irqs, | ||
179 | void *data) | ||
180 | { | ||
181 | struct of_phandle_args *args = data; | ||
182 | struct of_phandle_args parent_args; | ||
183 | irq_hw_number_t hwirq; | ||
184 | int i; | ||
185 | |||
186 | /* Not GIC compliant */ | ||
187 | if (args->args_count != 3) | ||
188 | return -EINVAL; | ||
189 | |||
190 | /* No PPI should point to this domain */ | ||
191 | if (args->args[0] != 0) | ||
192 | return -EINVAL; | ||
193 | |||
194 | /* Can't deal with this */ | ||
195 | hwirq = args->args[1]; | ||
196 | if (hwirq >= GPC_MAX_IRQS) | ||
197 | return -EINVAL; | ||
198 | |||
199 | for (i = 0; i < nr_irqs; i++) { | ||
200 | irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i, | ||
201 | &gpcv2_irqchip_data_chip, domain->host_data); | ||
202 | } | ||
203 | |||
204 | parent_args = *args; | ||
205 | parent_args.np = domain->parent->of_node; | ||
206 | return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args); | ||
207 | } | ||
208 | |||
209 | static struct irq_domain_ops gpcv2_irqchip_data_domain_ops = { | ||
210 | .xlate = imx_gpcv2_domain_xlate, | ||
211 | .alloc = imx_gpcv2_domain_alloc, | ||
212 | .free = irq_domain_free_irqs_common, | ||
213 | }; | ||
214 | |||
215 | static int __init imx_gpcv2_irqchip_init(struct device_node *node, | ||
216 | struct device_node *parent) | ||
217 | { | ||
218 | struct irq_domain *parent_domain, *domain; | ||
219 | struct gpcv2_irqchip_data *cd; | ||
220 | int i; | ||
221 | |||
222 | if (!parent) { | ||
223 | pr_err("%s: no parent, giving up\n", node->full_name); | ||
224 | return -ENODEV; | ||
225 | } | ||
226 | |||
227 | parent_domain = irq_find_host(parent); | ||
228 | if (!parent_domain) { | ||
229 | pr_err("%s: unable to get parent domain\n", node->full_name); | ||
230 | return -ENXIO; | ||
231 | } | ||
232 | |||
233 | cd = kzalloc(sizeof(struct gpcv2_irqchip_data), GFP_KERNEL); | ||
234 | if (!cd) { | ||
235 | pr_err("kzalloc failed!\n"); | ||
236 | return -ENOMEM; | ||
237 | } | ||
238 | |||
239 | cd->gpc_base = of_iomap(node, 0); | ||
240 | if (!cd->gpc_base) { | ||
241 | pr_err("fsl-gpcv2: unable to map gpc registers\n"); | ||
242 | kfree(cd); | ||
243 | return -ENOMEM; | ||
244 | } | ||
245 | |||
246 | domain = irq_domain_add_hierarchy(parent_domain, 0, GPC_MAX_IRQS, | ||
247 | node, &gpcv2_irqchip_data_domain_ops, cd); | ||
248 | if (!domain) { | ||
249 | iounmap(cd->gpc_base); | ||
250 | kfree(cd); | ||
251 | return -ENOMEM; | ||
252 | } | ||
253 | irq_set_default_host(domain); | ||
254 | |||
255 | /* Initially mask all interrupts */ | ||
256 | for (i = 0; i < IMR_NUM; i++) { | ||
257 | writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE0 + i * 4); | ||
258 | writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE1 + i * 4); | ||
259 | cd->wakeup_sources[i] = ~0; | ||
260 | } | ||
261 | |||
262 | /* Let CORE0 as the default CPU to wake up by GPC */ | ||
263 | cd->cpu2wakeup = GPC_IMR1_CORE0; | ||
264 | |||
265 | /* | ||
266 | * Due to hardware design failure, need to make sure GPR | ||
267 | * interrupt(#32) is unmasked during RUN mode to avoid entering | ||
268 | * DSM by mistake. | ||
269 | */ | ||
270 | writel_relaxed(~0x1, cd->gpc_base + cd->cpu2wakeup); | ||
271 | |||
272 | imx_gpcv2_instance = cd; | ||
273 | register_syscore_ops(&imx_gpcv2_syscore_ops); | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | IRQCHIP_DECLARE(imx_gpcv2, "fsl,imx7d-gpc", imx_gpcv2_irqchip_init); | ||
diff --git a/drivers/irqchip/irq-ingenic.c b/drivers/irqchip/irq-ingenic.c index 005de3f932ae..fc5953dea509 100644 --- a/drivers/irqchip/irq-ingenic.c +++ b/drivers/irqchip/irq-ingenic.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
21 | #include <linux/irqchip.h> | ||
21 | #include <linux/irqchip/ingenic.h> | 22 | #include <linux/irqchip/ingenic.h> |
22 | #include <linux/of_address.h> | 23 | #include <linux/of_address.h> |
23 | #include <linux/of_irq.h> | 24 | #include <linux/of_irq.h> |
@@ -28,8 +29,6 @@ | |||
28 | #include <asm/io.h> | 29 | #include <asm/io.h> |
29 | #include <asm/mach-jz4740/irq.h> | 30 | #include <asm/mach-jz4740/irq.h> |
30 | 31 | ||
31 | #include "irqchip.h" | ||
32 | |||
33 | struct ingenic_intc_data { | 32 | struct ingenic_intc_data { |
34 | void __iomem *base; | 33 | void __iomem *base; |
35 | unsigned num_chips; | 34 | unsigned num_chips; |
diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c index 81e3cf5b9a1f..c1517267b5db 100644 --- a/drivers/irqchip/irq-keystone.c +++ b/drivers/irqchip/irq-keystone.c | |||
@@ -20,13 +20,12 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/moduleparam.h> | 21 | #include <linux/moduleparam.h> |
22 | #include <linux/irqdomain.h> | 22 | #include <linux/irqdomain.h> |
23 | #include <linux/irqchip.h> | ||
23 | #include <linux/irqchip/chained_irq.h> | 24 | #include <linux/irqchip/chained_irq.h> |
24 | #include <linux/of.h> | 25 | #include <linux/of.h> |
25 | #include <linux/of_platform.h> | 26 | #include <linux/of_platform.h> |
26 | #include <linux/mfd/syscon.h> | 27 | #include <linux/mfd/syscon.h> |
27 | #include <linux/regmap.h> | 28 | #include <linux/regmap.h> |
28 | #include "irqchip.h" | ||
29 | |||
30 | 29 | ||
31 | /* The source ID bits start from 4 to 31 (total 28 bits)*/ | 30 | /* The source ID bits start from 4 to 31 (total 28 bits)*/ |
32 | #define BIT_OFS 4 | 31 | #define BIT_OFS 4 |
@@ -84,8 +83,9 @@ static void keystone_irq_ack(struct irq_data *d) | |||
84 | /* nothing to do here */ | 83 | /* nothing to do here */ |
85 | } | 84 | } |
86 | 85 | ||
87 | static void keystone_irq_handler(unsigned irq, struct irq_desc *desc) | 86 | static void keystone_irq_handler(unsigned __irq, struct irq_desc *desc) |
88 | { | 87 | { |
88 | unsigned int irq = irq_desc_get_irq(desc); | ||
89 | struct keystone_irq_device *kirq = irq_desc_get_handler_data(desc); | 89 | struct keystone_irq_device *kirq = irq_desc_get_handler_data(desc); |
90 | unsigned long pending; | 90 | unsigned long pending; |
91 | int src, virq; | 91 | int src, virq; |
diff --git a/drivers/irqchip/irq-metag-ext.c b/drivers/irqchip/irq-metag-ext.c index 2cb474ad8809..5f4c52928d16 100644 --- a/drivers/irqchip/irq-metag-ext.c +++ b/drivers/irqchip/irq-metag-ext.c | |||
@@ -404,7 +404,6 @@ static int meta_intc_irq_set_type(struct irq_data *data, unsigned int flow_type) | |||
404 | #ifdef CONFIG_METAG_SUSPEND_MEM | 404 | #ifdef CONFIG_METAG_SUSPEND_MEM |
405 | struct meta_intc_priv *priv = &meta_intc_priv; | 405 | struct meta_intc_priv *priv = &meta_intc_priv; |
406 | #endif | 406 | #endif |
407 | unsigned int irq = data->irq; | ||
408 | irq_hw_number_t hw = data->hwirq; | 407 | irq_hw_number_t hw = data->hwirq; |
409 | unsigned int bit = 1 << meta_intc_offset(hw); | 408 | unsigned int bit = 1 << meta_intc_offset(hw); |
410 | void __iomem *level_addr = meta_intc_level_addr(hw); | 409 | void __iomem *level_addr = meta_intc_level_addr(hw); |
@@ -413,11 +412,11 @@ static int meta_intc_irq_set_type(struct irq_data *data, unsigned int flow_type) | |||
413 | 412 | ||
414 | /* update the chip/handler */ | 413 | /* update the chip/handler */ |
415 | if (flow_type & IRQ_TYPE_LEVEL_MASK) | 414 | if (flow_type & IRQ_TYPE_LEVEL_MASK) |
416 | __irq_set_chip_handler_name_locked(irq, &meta_intc_level_chip, | 415 | irq_set_chip_handler_name_locked(data, &meta_intc_level_chip, |
417 | handle_level_irq, NULL); | 416 | handle_level_irq, NULL); |
418 | else | 417 | else |
419 | __irq_set_chip_handler_name_locked(irq, &meta_intc_edge_chip, | 418 | irq_set_chip_handler_name_locked(data, &meta_intc_edge_chip, |
420 | handle_edge_irq, NULL); | 419 | handle_edge_irq, NULL); |
421 | 420 | ||
422 | /* and clear/set the bit in HWLEVELEXT */ | 421 | /* and clear/set the bit in HWLEVELEXT */ |
423 | __global_lock2(flags); | 422 | __global_lock2(flags); |
diff --git a/drivers/irqchip/irq-metag.c b/drivers/irqchip/irq-metag.c index c16c186d97d3..3d23ce3edb5c 100644 --- a/drivers/irqchip/irq-metag.c +++ b/drivers/irqchip/irq-metag.c | |||
@@ -286,8 +286,7 @@ static void metag_internal_irq_init_cpu(struct metag_internal_irq_priv *priv, | |||
286 | int irq = tbisig_map(signum); | 286 | int irq = tbisig_map(signum); |
287 | 287 | ||
288 | /* Register the multiplexed IRQ handler */ | 288 | /* Register the multiplexed IRQ handler */ |
289 | irq_set_handler_data(irq, priv); | 289 | irq_set_chained_handler_and_data(irq, metag_internal_irq_demux, priv); |
290 | irq_set_chained_handler(irq, metag_internal_irq_demux); | ||
291 | irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); | 290 | irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); |
292 | } | 291 | } |
293 | 292 | ||
diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c index a43c41988009..8c504f562e9d 100644 --- a/drivers/irqchip/irq-mips-cpu.c +++ b/drivers/irqchip/irq-mips-cpu.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/irq.h> | 33 | #include <linux/irq.h> |
34 | #include <linux/irqchip.h> | ||
34 | #include <linux/irqdomain.h> | 35 | #include <linux/irqdomain.h> |
35 | 36 | ||
36 | #include <asm/irq_cpu.h> | 37 | #include <asm/irq_cpu.h> |
@@ -38,8 +39,6 @@ | |||
38 | #include <asm/mipsmtregs.h> | 39 | #include <asm/mipsmtregs.h> |
39 | #include <asm/setup.h> | 40 | #include <asm/setup.h> |
40 | 41 | ||
41 | #include "irqchip.h" | ||
42 | |||
43 | static inline void unmask_mips_irq(struct irq_data *d) | 42 | static inline void unmask_mips_irq(struct irq_data *d) |
44 | { | 43 | { |
45 | set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); | 44 | set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); |
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index ff4be0515a0d..dae591457883 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/irqchip.h> | ||
14 | #include <linux/irqchip/mips-gic.h> | 15 | #include <linux/irqchip/mips-gic.h> |
15 | #include <linux/of_address.h> | 16 | #include <linux/of_address.h> |
16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
@@ -22,8 +23,6 @@ | |||
22 | 23 | ||
23 | #include <dt-bindings/interrupt-controller/mips-gic.h> | 24 | #include <dt-bindings/interrupt-controller/mips-gic.h> |
24 | 25 | ||
25 | #include "irqchip.h" | ||
26 | |||
27 | unsigned int gic_present; | 26 | unsigned int gic_present; |
28 | 27 | ||
29 | struct gic_pcpu_mask { | 28 | struct gic_pcpu_mask { |
@@ -358,15 +357,12 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
358 | break; | 357 | break; |
359 | } | 358 | } |
360 | 359 | ||
361 | if (is_edge) { | 360 | if (is_edge) |
362 | __irq_set_chip_handler_name_locked(d->irq, | 361 | irq_set_chip_handler_name_locked(d, &gic_edge_irq_controller, |
363 | &gic_edge_irq_controller, | 362 | handle_edge_irq, NULL); |
364 | handle_edge_irq, NULL); | 363 | else |
365 | } else { | 364 | irq_set_chip_handler_name_locked(d, &gic_level_irq_controller, |
366 | __irq_set_chip_handler_name_locked(d->irq, | 365 | handle_level_irq, NULL); |
367 | &gic_level_irq_controller, | ||
368 | handle_level_irq, NULL); | ||
369 | } | ||
370 | spin_unlock_irqrestore(&gic_lock, flags); | 366 | spin_unlock_irqrestore(&gic_lock, flags); |
371 | 367 | ||
372 | return 0; | 368 | return 0; |
@@ -396,7 +392,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, | |||
396 | clear_bit(irq, pcpu_masks[i].pcpu_mask); | 392 | clear_bit(irq, pcpu_masks[i].pcpu_mask); |
397 | set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask); | 393 | set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask); |
398 | 394 | ||
399 | cpumask_copy(d->affinity, cpumask); | 395 | cpumask_copy(irq_data_get_affinity_mask(d), cpumask); |
400 | spin_unlock_irqrestore(&gic_lock, flags); | 396 | spin_unlock_irqrestore(&gic_lock, flags); |
401 | 397 | ||
402 | return IRQ_SET_MASK_OK_NOCOPY; | 398 | return IRQ_SET_MASK_OK_NOCOPY; |
diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c index c0da57bdb89d..781ed6e71dbb 100644 --- a/drivers/irqchip/irq-mmp.c +++ b/drivers/irqchip/irq-mmp.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
18 | #include <linux/irqchip.h> | ||
18 | #include <linux/irqdomain.h> | 19 | #include <linux/irqdomain.h> |
19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
20 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
@@ -24,8 +25,6 @@ | |||
24 | #include <asm/exception.h> | 25 | #include <asm/exception.h> |
25 | #include <asm/hardirq.h> | 26 | #include <asm/hardirq.h> |
26 | 27 | ||
27 | #include "irqchip.h" | ||
28 | |||
29 | #define MAX_ICU_NR 16 | 28 | #define MAX_ICU_NR 16 |
30 | 29 | ||
31 | #define PJ1_INT_SEL 0x10c | 30 | #define PJ1_INT_SEL 0x10c |
@@ -130,8 +129,9 @@ struct irq_chip icu_irq_chip = { | |||
130 | .irq_unmask = icu_unmask_irq, | 129 | .irq_unmask = icu_unmask_irq, |
131 | }; | 130 | }; |
132 | 131 | ||
133 | static void icu_mux_irq_demux(unsigned int irq, struct irq_desc *desc) | 132 | static void icu_mux_irq_demux(unsigned int __irq, struct irq_desc *desc) |
134 | { | 133 | { |
134 | unsigned int irq = irq_desc_get_irq(desc); | ||
135 | struct irq_domain *domain; | 135 | struct irq_domain *domain; |
136 | struct icu_chip_data *data; | 136 | struct icu_chip_data *data; |
137 | int i; | 137 | int i; |
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c index 00b3cc908f76..a24b06a1718b 100644 --- a/drivers/irqchip/irq-moxart.c +++ b/drivers/irqchip/irq-moxart.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/irqchip.h> | ||
15 | #include <linux/of.h> | 16 | #include <linux/of.h> |
16 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
17 | #include <linux/of_irq.h> | 18 | #include <linux/of_irq.h> |
@@ -19,8 +20,6 @@ | |||
19 | 20 | ||
20 | #include <asm/exception.h> | 21 | #include <asm/exception.h> |
21 | 22 | ||
22 | #include "irqchip.h" | ||
23 | |||
24 | #define IRQ_SOURCE_REG 0 | 23 | #define IRQ_SOURCE_REG 0 |
25 | #define IRQ_MASK_REG 0x04 | 24 | #define IRQ_MASK_REG 0x04 |
26 | #define IRQ_CLEAR_REG 0x08 | 25 | #define IRQ_CLEAR_REG 0x08 |
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c index 15c13039bba2..c8753da4c156 100644 --- a/drivers/irqchip/irq-mtk-sysirq.c +++ b/drivers/irqchip/irq-mtk-sysirq.c | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <linux/irqchip.h> | ||
16 | #include <linux/irqdomain.h> | 17 | #include <linux/irqdomain.h> |
17 | #include <linux/of.h> | 18 | #include <linux/of.h> |
18 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
@@ -21,8 +22,6 @@ | |||
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
23 | 24 | ||
24 | #include "irqchip.h" | ||
25 | |||
26 | struct mtk_sysirq_chip_data { | 25 | struct mtk_sysirq_chip_data { |
27 | spinlock_t lock; | 26 | spinlock_t lock; |
28 | void __iomem *intpol_base; | 27 | void __iomem *intpol_base; |
diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index 04bf97b289cf..1faf812f3dc8 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/irqchip.h> | ||
22 | #include <linux/irqdomain.h> | 23 | #include <linux/irqdomain.h> |
23 | #include <linux/io.h> | 24 | #include <linux/io.h> |
24 | #include <linux/of.h> | 25 | #include <linux/of.h> |
@@ -27,8 +28,6 @@ | |||
27 | #include <linux/stmp_device.h> | 28 | #include <linux/stmp_device.h> |
28 | #include <asm/exception.h> | 29 | #include <asm/exception.h> |
29 | 30 | ||
30 | #include "irqchip.h" | ||
31 | |||
32 | #define HW_ICOLL_VECTOR 0x0000 | 31 | #define HW_ICOLL_VECTOR 0x0000 |
33 | #define HW_ICOLL_LEVELACK 0x0010 | 32 | #define HW_ICOLL_LEVELACK 0x0010 |
34 | #define HW_ICOLL_CTRL 0x0020 | 33 | #define HW_ICOLL_CTRL 0x0020 |
diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c index 5fac9100f6cb..a878b8d03868 100644 --- a/drivers/irqchip/irq-nvic.c +++ b/drivers/irqchip/irq-nvic.c | |||
@@ -21,13 +21,12 @@ | |||
21 | #include <linux/of.h> | 21 | #include <linux/of.h> |
22 | #include <linux/of_address.h> | 22 | #include <linux/of_address.h> |
23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
24 | #include <linux/irqchip.h> | ||
24 | #include <linux/irqdomain.h> | 25 | #include <linux/irqdomain.h> |
25 | 26 | ||
26 | #include <asm/v7m.h> | 27 | #include <asm/v7m.h> |
27 | #include <asm/exception.h> | 28 | #include <asm/exception.h> |
28 | 29 | ||
29 | #include "irqchip.h" | ||
30 | |||
31 | #define NVIC_ISER 0x000 | 30 | #define NVIC_ISER 0x000 |
32 | #define NVIC_ICER 0x080 | 31 | #define NVIC_ICER 0x080 |
33 | #define NVIC_IPR 0x300 | 32 | #define NVIC_IPR 0x300 |
diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c index a569c6dbd1d1..8587d0f8d8c0 100644 --- a/drivers/irqchip/irq-omap-intc.c +++ b/drivers/irqchip/irq-omap-intc.c | |||
@@ -17,13 +17,12 @@ | |||
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | 18 | ||
19 | #include <asm/exception.h> | 19 | #include <asm/exception.h> |
20 | #include <linux/irqchip.h> | ||
20 | #include <linux/irqdomain.h> | 21 | #include <linux/irqdomain.h> |
21 | #include <linux/of.h> | 22 | #include <linux/of.h> |
22 | #include <linux/of_address.h> | 23 | #include <linux/of_address.h> |
23 | #include <linux/of_irq.h> | 24 | #include <linux/of_irq.h> |
24 | 25 | ||
25 | #include "irqchip.h" | ||
26 | |||
27 | /* Define these here for now until we drop all board-files */ | 26 | /* Define these here for now until we drop all board-files */ |
28 | #define OMAP24XX_IC_BASE 0x480fe000 | 27 | #define OMAP24XX_IC_BASE 0x480fe000 |
29 | #define OMAP34XX_IC_BASE 0x48200000 | 28 | #define OMAP34XX_IC_BASE 0x48200000 |
@@ -331,37 +330,12 @@ static int __init omap_init_irq(u32 base, struct device_node *node) | |||
331 | static asmlinkage void __exception_irq_entry | 330 | static asmlinkage void __exception_irq_entry |
332 | omap_intc_handle_irq(struct pt_regs *regs) | 331 | omap_intc_handle_irq(struct pt_regs *regs) |
333 | { | 332 | { |
334 | u32 irqnr = 0; | 333 | u32 irqnr; |
335 | int handled_irq = 0; | ||
336 | int i; | ||
337 | |||
338 | do { | ||
339 | for (i = 0; i < omap_nr_pending; i++) { | ||
340 | irqnr = intc_readl(INTC_PENDING_IRQ0 + (0x20 * i)); | ||
341 | if (irqnr) | ||
342 | goto out; | ||
343 | } | ||
344 | |||
345 | out: | ||
346 | if (!irqnr) | ||
347 | break; | ||
348 | 334 | ||
349 | irqnr = intc_readl(INTC_SIR); | 335 | irqnr = intc_readl(INTC_SIR); |
350 | irqnr &= ACTIVEIRQ_MASK; | 336 | irqnr &= ACTIVEIRQ_MASK; |
351 | 337 | WARN_ONCE(!irqnr, "Spurious IRQ ?\n"); | |
352 | if (irqnr) { | 338 | handle_domain_irq(domain, irqnr, regs); |
353 | handle_domain_irq(domain, irqnr, regs); | ||
354 | handled_irq = 1; | ||
355 | } | ||
356 | } while (irqnr); | ||
357 | |||
358 | /* | ||
359 | * If an irq is masked or deasserted while active, we will | ||
360 | * keep ending up here with no irq handled. So remove it from | ||
361 | * the INTC with an ack. | ||
362 | */ | ||
363 | if (!handled_irq) | ||
364 | omap_ack_irq(NULL); | ||
365 | } | 339 | } |
366 | 340 | ||
367 | void __init omap3_init_irq(void) | 341 | void __init omap3_init_irq(void) |
diff --git a/drivers/irqchip/irq-or1k-pic.c b/drivers/irqchip/irq-or1k-pic.c index e93d079fe069..6a9a3e79218b 100644 --- a/drivers/irqchip/irq-or1k-pic.c +++ b/drivers/irqchip/irq-or1k-pic.c | |||
@@ -9,12 +9,11 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
12 | #include <linux/irqchip.h> | ||
12 | #include <linux/of.h> | 13 | #include <linux/of.h> |
13 | #include <linux/of_irq.h> | 14 | #include <linux/of_irq.h> |
14 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
15 | 16 | ||
16 | #include "irqchip.h" | ||
17 | |||
18 | /* OR1K PIC implementation */ | 17 | /* OR1K PIC implementation */ |
19 | 18 | ||
20 | struct or1k_pic_dev { | 19 | struct or1k_pic_dev { |
diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c index ad0c0f6f1d65..5ea999a724b5 100644 --- a/drivers/irqchip/irq-orion.c +++ b/drivers/irqchip/irq-orion.c | |||
@@ -10,14 +10,13 @@ | |||
10 | 10 | ||
11 | #include <linux/io.h> | 11 | #include <linux/io.h> |
12 | #include <linux/irq.h> | 12 | #include <linux/irq.h> |
13 | #include <linux/irqchip.h> | ||
13 | #include <linux/of.h> | 14 | #include <linux/of.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 <asm/exception.h> | 17 | #include <asm/exception.h> |
17 | #include <asm/mach/irq.h> | 18 | #include <asm/mach/irq.h> |
18 | 19 | ||
19 | #include "irqchip.h" | ||
20 | |||
21 | /* | 20 | /* |
22 | * Orion SoC main interrupt controller | 21 | * Orion SoC main interrupt controller |
23 | */ | 22 | */ |
@@ -109,7 +108,7 @@ IRQCHIP_DECLARE(orion_intc, "marvell,orion-intc", orion_irq_init); | |||
109 | 108 | ||
110 | static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) | 109 | static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) |
111 | { | 110 | { |
112 | struct irq_domain *d = irq_get_handler_data(irq); | 111 | struct irq_domain *d = irq_desc_get_handler_data(desc); |
113 | 112 | ||
114 | struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0); | 113 | struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0); |
115 | u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) & | 114 | u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) & |
@@ -198,8 +197,8 @@ static int __init orion_bridge_irq_init(struct device_node *np, | |||
198 | writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK); | 197 | writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK); |
199 | writel(0, gc->reg_base + ORION_BRIDGE_IRQ_CAUSE); | 198 | writel(0, gc->reg_base + ORION_BRIDGE_IRQ_CAUSE); |
200 | 199 | ||
201 | irq_set_handler_data(irq, domain); | 200 | irq_set_chained_handler_and_data(irq, orion_bridge_irq_handler, |
202 | irq_set_chained_handler(irq, orion_bridge_irq_handler); | 201 | domain); |
203 | 202 | ||
204 | return 0; | 203 | return 0; |
205 | } | 204 | } |
diff --git a/drivers/irqchip/irq-renesas-h8300h.c b/drivers/irqchip/irq-renesas-h8300h.c index 1870e6bd3dd9..6fd30d5ee14d 100644 --- a/drivers/irqchip/irq-renesas-h8300h.c +++ b/drivers/irqchip/irq-renesas-h8300h.c | |||
@@ -11,8 +11,6 @@ | |||
11 | #include <linux/of_irq.h> | 11 | #include <linux/of_irq.h> |
12 | #include <asm/io.h> | 12 | #include <asm/io.h> |
13 | 13 | ||
14 | #include "irqchip.h" | ||
15 | |||
16 | static const char ipr_bit[] = { | 14 | static const char ipr_bit[] = { |
17 | 7, 6, 5, 5, | 15 | 7, 6, 5, 5, |
18 | 4, 4, 4, 4, 3, 3, 3, 3, | 16 | 4, 4, 4, 4, 3, 3, 3, 3, |
diff --git a/drivers/irqchip/irq-renesas-h8s.c b/drivers/irqchip/irq-renesas-h8s.c index 64425f4de7d9..8098ead1eb22 100644 --- a/drivers/irqchip/irq-renesas-h8s.c +++ b/drivers/irqchip/irq-renesas-h8s.c | |||
@@ -5,10 +5,10 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/irq.h> | 7 | #include <linux/irq.h> |
8 | #include <linux/irqchip.h> | ||
8 | #include <linux/of_address.h> | 9 | #include <linux/of_address.h> |
9 | #include <linux/of_irq.h> | 10 | #include <linux/of_irq.h> |
10 | #include <asm/io.h> | 11 | #include <asm/io.h> |
11 | #include "irqchip.h" | ||
12 | 12 | ||
13 | static void *intc_baseaddr; | 13 | static void *intc_baseaddr; |
14 | #define IPRA ((unsigned long)intc_baseaddr) | 14 | #define IPRA ((unsigned long)intc_baseaddr) |
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c index 778bd076aeea..2aa3add711a6 100644 --- a/drivers/irqchip/irq-renesas-irqc.c +++ b/drivers/irqchip/irq-renesas-irqc.c | |||
@@ -53,7 +53,6 @@ | |||
53 | struct irqc_irq { | 53 | struct irqc_irq { |
54 | int hw_irq; | 54 | int hw_irq; |
55 | int requested_irq; | 55 | int requested_irq; |
56 | int domain_irq; | ||
57 | struct irqc_priv *p; | 56 | struct irqc_priv *p; |
58 | }; | 57 | }; |
59 | 58 | ||
@@ -70,8 +69,8 @@ struct irqc_priv { | |||
70 | 69 | ||
71 | static void irqc_dbg(struct irqc_irq *i, char *str) | 70 | static void irqc_dbg(struct irqc_irq *i, char *str) |
72 | { | 71 | { |
73 | dev_dbg(&i->p->pdev->dev, "%s (%d:%d:%d)\n", | 72 | dev_dbg(&i->p->pdev->dev, "%s (%d:%d)\n", |
74 | str, i->requested_irq, i->hw_irq, i->domain_irq); | 73 | str, i->requested_irq, i->hw_irq); |
75 | } | 74 | } |
76 | 75 | ||
77 | static void irqc_irq_enable(struct irq_data *d) | 76 | static void irqc_irq_enable(struct irq_data *d) |
@@ -145,7 +144,7 @@ static irqreturn_t irqc_irq_handler(int irq, void *dev_id) | |||
145 | if (ioread32(p->iomem + DETECT_STATUS) & bit) { | 144 | if (ioread32(p->iomem + DETECT_STATUS) & bit) { |
146 | iowrite32(bit, p->iomem + DETECT_STATUS); | 145 | iowrite32(bit, p->iomem + DETECT_STATUS); |
147 | irqc_dbg(i, "demux2"); | 146 | irqc_dbg(i, "demux2"); |
148 | generic_handle_irq(i->domain_irq); | 147 | generic_handle_irq(irq_find_mapping(p->irq_domain, i->hw_irq)); |
149 | return IRQ_HANDLED; | 148 | return IRQ_HANDLED; |
150 | } | 149 | } |
151 | return IRQ_NONE; | 150 | return IRQ_NONE; |
@@ -156,13 +155,9 @@ static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq, | |||
156 | { | 155 | { |
157 | struct irqc_priv *p = h->host_data; | 156 | struct irqc_priv *p = h->host_data; |
158 | 157 | ||
159 | p->irq[hw].domain_irq = virq; | ||
160 | p->irq[hw].hw_irq = hw; | ||
161 | |||
162 | irqc_dbg(&p->irq[hw], "map"); | 158 | irqc_dbg(&p->irq[hw], "map"); |
163 | irq_set_chip_data(virq, h->host_data); | 159 | irq_set_chip_data(virq, h->host_data); |
164 | irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); | 160 | irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); |
165 | set_irq_flags(virq, IRQF_VALID); /* kill me now */ | ||
166 | return 0; | 161 | return 0; |
167 | } | 162 | } |
168 | 163 | ||
@@ -215,6 +210,7 @@ static int irqc_probe(struct platform_device *pdev) | |||
215 | break; | 210 | break; |
216 | 211 | ||
217 | p->irq[k].p = p; | 212 | p->irq[k].p = p; |
213 | p->irq[k].hw_irq = k; | ||
218 | p->irq[k].requested_irq = irq->start; | 214 | p->irq[k].requested_irq = irq->start; |
219 | } | 215 | } |
220 | 216 | ||
@@ -243,8 +239,8 @@ static int irqc_probe(struct platform_device *pdev) | |||
243 | irq_chip->irq_set_wake = irqc_irq_set_wake; | 239 | irq_chip->irq_set_wake = irqc_irq_set_wake; |
244 | irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; | 240 | irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; |
245 | 241 | ||
246 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, | 242 | p->irq_domain = irq_domain_add_linear(pdev->dev.of_node, |
247 | p->number_of_irqs, 0, | 243 | p->number_of_irqs, |
248 | &irqc_irq_domain_ops, p); | 244 | &irqc_irq_domain_ops, p); |
249 | if (!p->irq_domain) { | 245 | if (!p->irq_domain) { |
250 | ret = -ENXIO; | 246 | ret = -ENXIO; |
diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c index e96717f45ea1..506d9f20ca51 100644 --- a/drivers/irqchip/irq-s3c24xx.c +++ b/drivers/irqchip/irq-s3c24xx.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/irqdomain.h> | 27 | #include <linux/irqdomain.h> |
28 | #include <linux/irqchip.h> | ||
28 | #include <linux/irqchip/chained_irq.h> | 29 | #include <linux/irqchip/chained_irq.h> |
29 | #include <linux/of.h> | 30 | #include <linux/of.h> |
30 | #include <linux/of_irq.h> | 31 | #include <linux/of_irq.h> |
@@ -40,8 +41,6 @@ | |||
40 | #include <plat/regs-irqtype.h> | 41 | #include <plat/regs-irqtype.h> |
41 | #include <plat/pm.h> | 42 | #include <plat/pm.h> |
42 | 43 | ||
43 | #include "irqchip.h" | ||
44 | |||
45 | #define S3C_IRQTYPE_NONE 0 | 44 | #define S3C_IRQTYPE_NONE 0 |
46 | #define S3C_IRQTYPE_EINT 1 | 45 | #define S3C_IRQTYPE_EINT 1 |
47 | #define S3C_IRQTYPE_EDGE 2 | 46 | #define S3C_IRQTYPE_EDGE 2 |
@@ -299,16 +298,14 @@ static struct irq_chip s3c_irq_eint0t4 = { | |||
299 | .irq_set_type = s3c_irqext0_type, | 298 | .irq_set_type = s3c_irqext0_type, |
300 | }; | 299 | }; |
301 | 300 | ||
302 | static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc) | 301 | static void s3c_irq_demux(unsigned int __irq, struct irq_desc *desc) |
303 | { | 302 | { |
304 | struct irq_chip *chip = irq_desc_get_chip(desc); | 303 | struct irq_chip *chip = irq_desc_get_chip(desc); |
305 | struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc); | 304 | struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc); |
306 | struct s3c_irq_intc *intc = irq_data->intc; | 305 | struct s3c_irq_intc *intc = irq_data->intc; |
307 | struct s3c_irq_intc *sub_intc = irq_data->sub_intc; | 306 | struct s3c_irq_intc *sub_intc = irq_data->sub_intc; |
308 | unsigned long src; | 307 | unsigned int n, offset, irq; |
309 | unsigned long msk; | 308 | unsigned long src, msk; |
310 | unsigned int n; | ||
311 | unsigned int offset; | ||
312 | 309 | ||
313 | /* we're using individual domains for the non-dt case | 310 | /* we're using individual domains for the non-dt case |
314 | * and one big domain for the dt case where the subintc | 311 | * and one big domain for the dt case where the subintc |
diff --git a/drivers/irqchip/irq-sirfsoc.c b/drivers/irqchip/irq-sirfsoc.c index a469355df352..10cb21b9ba3d 100644 --- a/drivers/irqchip/irq-sirfsoc.c +++ b/drivers/irqchip/irq-sirfsoc.c | |||
@@ -11,40 +11,44 @@ | |||
11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
12 | #include <linux/of.h> | 12 | #include <linux/of.h> |
13 | #include <linux/of_address.h> | 13 | #include <linux/of_address.h> |
14 | #include <linux/irqchip.h> | ||
14 | #include <linux/irqdomain.h> | 15 | #include <linux/irqdomain.h> |
15 | #include <linux/syscore_ops.h> | 16 | #include <linux/syscore_ops.h> |
16 | #include <asm/mach/irq.h> | 17 | #include <asm/mach/irq.h> |
17 | #include <asm/exception.h> | 18 | #include <asm/exception.h> |
18 | #include "irqchip.h" | ||
19 | 19 | ||
20 | #define SIRFSOC_INT_RISC_MASK0 0x0018 | 20 | #define SIRFSOC_INT_RISC_MASK0 0x0018 |
21 | #define SIRFSOC_INT_RISC_MASK1 0x001C | 21 | #define SIRFSOC_INT_RISC_MASK1 0x001C |
22 | #define SIRFSOC_INT_RISC_LEVEL0 0x0020 | 22 | #define SIRFSOC_INT_RISC_LEVEL0 0x0020 |
23 | #define SIRFSOC_INT_RISC_LEVEL1 0x0024 | 23 | #define SIRFSOC_INT_RISC_LEVEL1 0x0024 |
24 | #define SIRFSOC_INIT_IRQ_ID 0x0038 | 24 | #define SIRFSOC_INIT_IRQ_ID 0x0038 |
25 | #define SIRFSOC_INT_BASE_OFFSET 0x0004 | ||
25 | 26 | ||
26 | #define SIRFSOC_NUM_IRQS 64 | 27 | #define SIRFSOC_NUM_IRQS 64 |
28 | #define SIRFSOC_NUM_BANKS (SIRFSOC_NUM_IRQS / 32) | ||
27 | 29 | ||
28 | static struct irq_domain *sirfsoc_irqdomain; | 30 | static struct irq_domain *sirfsoc_irqdomain; |
29 | 31 | ||
30 | static __init void | 32 | static __init void sirfsoc_alloc_gc(void __iomem *base) |
31 | sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) | ||
32 | { | 33 | { |
33 | struct irq_chip_generic *gc; | ||
34 | struct irq_chip_type *ct; | ||
35 | int ret; | ||
36 | unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; | 34 | unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; |
37 | unsigned int set = IRQ_LEVEL; | 35 | unsigned int set = IRQ_LEVEL; |
38 | 36 | struct irq_chip_generic *gc; | |
39 | ret = irq_alloc_domain_generic_chips(sirfsoc_irqdomain, num, 1, "irq_sirfsoc", | 37 | struct irq_chip_type *ct; |
40 | handle_level_irq, clr, set, IRQ_GC_INIT_MASK_CACHE); | 38 | int i; |
41 | 39 | ||
42 | gc = irq_get_domain_generic_chip(sirfsoc_irqdomain, irq_start); | 40 | irq_alloc_domain_generic_chips(sirfsoc_irqdomain, 32, 1, "irq_sirfsoc", |
43 | gc->reg_base = base; | 41 | handle_level_irq, clr, set, |
44 | ct = gc->chip_types; | 42 | IRQ_GC_INIT_MASK_CACHE); |
45 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | 43 | |
46 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 44 | for (i = 0; i < SIRFSOC_NUM_BANKS; i++) { |
47 | ct->regs.mask = SIRFSOC_INT_RISC_MASK0; | 45 | gc = irq_get_domain_generic_chip(sirfsoc_irqdomain, i * 32); |
46 | gc->reg_base = base + i * SIRFSOC_INT_BASE_OFFSET; | ||
47 | ct = gc->chip_types; | ||
48 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | ||
49 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | ||
50 | ct->regs.mask = SIRFSOC_INT_RISC_MASK0; | ||
51 | } | ||
48 | } | 52 | } |
49 | 53 | ||
50 | static void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) | 54 | static void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) |
@@ -64,10 +68,8 @@ static int __init sirfsoc_irq_init(struct device_node *np, | |||
64 | panic("unable to map intc cpu registers\n"); | 68 | panic("unable to map intc cpu registers\n"); |
65 | 69 | ||
66 | sirfsoc_irqdomain = irq_domain_add_linear(np, SIRFSOC_NUM_IRQS, | 70 | sirfsoc_irqdomain = irq_domain_add_linear(np, SIRFSOC_NUM_IRQS, |
67 | &irq_generic_chip_ops, base); | 71 | &irq_generic_chip_ops, base); |
68 | 72 | sirfsoc_alloc_gc(base); | |
69 | sirfsoc_alloc_gc(base, 0, 32); | ||
70 | sirfsoc_alloc_gc(base + 4, 32, SIRFSOC_NUM_IRQS - 32); | ||
71 | 73 | ||
72 | writel_relaxed(0, base + SIRFSOC_INT_RISC_LEVEL0); | 74 | writel_relaxed(0, base + SIRFSOC_INT_RISC_LEVEL0); |
73 | writel_relaxed(0, base + SIRFSOC_INT_RISC_LEVEL1); | 75 | writel_relaxed(0, base + SIRFSOC_INT_RISC_LEVEL1); |
diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c index 83d6aa6464ee..4ad3e7c69aa7 100644 --- a/drivers/irqchip/irq-sun4i.c +++ b/drivers/irqchip/irq-sun4i.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
19 | #include <linux/irqchip.h> | ||
19 | #include <linux/of.h> | 20 | #include <linux/of.h> |
20 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
21 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
@@ -23,8 +24,6 @@ | |||
23 | #include <asm/exception.h> | 24 | #include <asm/exception.h> |
24 | #include <asm/mach/irq.h> | 25 | #include <asm/mach/irq.h> |
25 | 26 | ||
26 | #include "irqchip.h" | ||
27 | |||
28 | #define SUN4I_IRQ_VECTOR_REG 0x00 | 27 | #define SUN4I_IRQ_VECTOR_REG 0x00 |
29 | #define SUN4I_IRQ_PROTECTION_REG 0x08 | 28 | #define SUN4I_IRQ_PROTECTION_REG 0x08 |
30 | #define SUN4I_IRQ_NMI_CTRL_REG 0x0c | 29 | #define SUN4I_IRQ_NMI_CTRL_REG 0x0c |
diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c index 6b2b582433bd..772a82cacbf7 100644 --- a/drivers/irqchip/irq-sunxi-nmi.c +++ b/drivers/irqchip/irq-sunxi-nmi.c | |||
@@ -17,8 +17,8 @@ | |||
17 | #include <linux/of_irq.h> | 17 | #include <linux/of_irq.h> |
18 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
19 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
20 | #include <linux/irqchip.h> | ||
20 | #include <linux/irqchip/chained_irq.h> | 21 | #include <linux/irqchip/chained_irq.h> |
21 | #include "irqchip.h" | ||
22 | 22 | ||
23 | #define SUNXI_NMI_SRC_TYPE_MASK 0x00000003 | 23 | #define SUNXI_NMI_SRC_TYPE_MASK 0x00000003 |
24 | 24 | ||
@@ -61,7 +61,7 @@ static inline u32 sunxi_sc_nmi_read(struct irq_chip_generic *gc, u32 off) | |||
61 | static void sunxi_sc_nmi_handle_irq(unsigned int irq, struct irq_desc *desc) | 61 | static void sunxi_sc_nmi_handle_irq(unsigned int irq, struct irq_desc *desc) |
62 | { | 62 | { |
63 | struct irq_domain *domain = irq_desc_get_handler_data(desc); | 63 | struct irq_domain *domain = irq_desc_get_handler_data(desc); |
64 | struct irq_chip *chip = irq_get_chip(irq); | 64 | struct irq_chip *chip = irq_desc_get_chip(desc); |
65 | unsigned int virq = irq_find_mapping(domain, 0); | 65 | unsigned int virq = irq_find_mapping(domain, 0); |
66 | 66 | ||
67 | chained_irq_enter(chip, desc); | 67 | chained_irq_enter(chip, desc); |
@@ -182,8 +182,7 @@ static int __init sunxi_sc_nmi_irq_init(struct device_node *node, | |||
182 | sunxi_sc_nmi_write(gc, reg_offs->enable, 0); | 182 | sunxi_sc_nmi_write(gc, reg_offs->enable, 0); |
183 | sunxi_sc_nmi_write(gc, reg_offs->pend, 0x1); | 183 | sunxi_sc_nmi_write(gc, reg_offs->pend, 0x1); |
184 | 184 | ||
185 | irq_set_handler_data(irq, domain); | 185 | irq_set_chained_handler_and_data(irq, sunxi_sc_nmi_handle_irq, domain); |
186 | irq_set_chained_handler(irq, sunxi_sc_nmi_handle_irq); | ||
187 | 186 | ||
188 | return 0; | 187 | return 0; |
189 | 188 | ||
diff --git a/drivers/irqchip/irq-tb10x.c b/drivers/irqchip/irq-tb10x.c index accc20036a3c..331829661366 100644 --- a/drivers/irqchip/irq-tb10x.c +++ b/drivers/irqchip/irq-tb10x.c | |||
@@ -22,13 +22,13 @@ | |||
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/irqdomain.h> | 23 | #include <linux/irqdomain.h> |
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/irqchip.h> | ||
25 | #include <linux/of_irq.h> | 26 | #include <linux/of_irq.h> |
26 | #include <linux/of_address.h> | 27 | #include <linux/of_address.h> |
27 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
28 | #include <linux/io.h> | 29 | #include <linux/io.h> |
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/bitops.h> | 31 | #include <linux/bitops.h> |
31 | #include "irqchip.h" | ||
32 | 32 | ||
33 | #define AB_IRQCTL_INT_ENABLE 0x00 | 33 | #define AB_IRQCTL_INT_ENABLE 0x00 |
34 | #define AB_IRQCTL_INT_STATUS 0x04 | 34 | #define AB_IRQCTL_INT_STATUS 0x04 |
@@ -97,9 +97,10 @@ static int tb10x_irq_set_type(struct irq_data *data, unsigned int flow_type) | |||
97 | return IRQ_SET_MASK_OK; | 97 | return IRQ_SET_MASK_OK; |
98 | } | 98 | } |
99 | 99 | ||
100 | static void tb10x_irq_cascade(unsigned int irq, struct irq_desc *desc) | 100 | static void tb10x_irq_cascade(unsigned int __irq, struct irq_desc *desc) |
101 | { | 101 | { |
102 | struct irq_domain *domain = irq_desc_get_handler_data(desc); | 102 | struct irq_domain *domain = irq_desc_get_handler_data(desc); |
103 | unsigned int irq = irq_desc_get_irq(desc); | ||
103 | 104 | ||
104 | generic_handle_irq(irq_find_mapping(domain, irq)); | 105 | generic_handle_irq(irq_find_mapping(domain, irq)); |
105 | } | 106 | } |
@@ -173,8 +174,8 @@ static int __init of_tb10x_init_irq(struct device_node *ictl, | |||
173 | for (i = 0; i < nrirqs; i++) { | 174 | for (i = 0; i < nrirqs; i++) { |
174 | unsigned int irq = irq_of_parse_and_map(ictl, i); | 175 | unsigned int irq = irq_of_parse_and_map(ictl, i); |
175 | 176 | ||
176 | irq_set_handler_data(irq, domain); | 177 | irq_set_chained_handler_and_data(irq, tb10x_irq_cascade, |
177 | irq_set_chained_handler(irq, tb10x_irq_cascade); | 178 | domain); |
178 | } | 179 | } |
179 | 180 | ||
180 | ab_irqctl_writereg(gc, AB_IRQCTL_INT_ENABLE, 0); | 181 | ab_irqctl_writereg(gc, AB_IRQCTL_INT_ENABLE, 0); |
diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c index f67bbd80433e..2fd89eb88f3a 100644 --- a/drivers/irqchip/irq-tegra.c +++ b/drivers/irqchip/irq-tegra.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
27 | #include <linux/irqchip.h> | ||
27 | #include <linux/irqdomain.h> | 28 | #include <linux/irqdomain.h> |
28 | #include <linux/of_address.h> | 29 | #include <linux/of_address.h> |
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
@@ -31,8 +32,6 @@ | |||
31 | 32 | ||
32 | #include <dt-bindings/interrupt-controller/arm-gic.h> | 33 | #include <dt-bindings/interrupt-controller/arm-gic.h> |
33 | 34 | ||
34 | #include "irqchip.h" | ||
35 | |||
36 | #define ICTLR_CPU_IEP_VFIQ 0x08 | 35 | #define ICTLR_CPU_IEP_VFIQ 0x08 |
37 | #define ICTLR_CPU_IEP_FIR 0x14 | 36 | #define ICTLR_CPU_IEP_FIR 0x14 |
38 | #define ICTLR_CPU_IEP_FIR_SET 0x18 | 37 | #define ICTLR_CPU_IEP_FIR_SET 0x18 |
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c index 888111b76ea0..16123f688768 100644 --- a/drivers/irqchip/irq-versatile-fpga.c +++ b/drivers/irqchip/irq-versatile-fpga.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/bitops.h> | 4 | #include <linux/bitops.h> |
5 | #include <linux/irq.h> | 5 | #include <linux/irq.h> |
6 | #include <linux/io.h> | 6 | #include <linux/io.h> |
7 | #include <linux/irqchip.h> | ||
7 | #include <linux/irqchip/versatile-fpga.h> | 8 | #include <linux/irqchip/versatile-fpga.h> |
8 | #include <linux/irqdomain.h> | 9 | #include <linux/irqdomain.h> |
9 | #include <linux/module.h> | 10 | #include <linux/module.h> |
@@ -14,8 +15,6 @@ | |||
14 | #include <asm/exception.h> | 15 | #include <asm/exception.h> |
15 | #include <asm/mach/irq.h> | 16 | #include <asm/mach/irq.h> |
16 | 17 | ||
17 | #include "irqchip.h" | ||
18 | |||
19 | #define IRQ_STATUS 0x00 | 18 | #define IRQ_STATUS 0x00 |
20 | #define IRQ_RAW_STATUS 0x04 | 19 | #define IRQ_RAW_STATUS 0x04 |
21 | #define IRQ_ENABLE_SET 0x08 | 20 | #define IRQ_ENABLE_SET 0x08 |
@@ -66,9 +65,10 @@ static void fpga_irq_unmask(struct irq_data *d) | |||
66 | writel(mask, f->base + IRQ_ENABLE_SET); | 65 | writel(mask, f->base + IRQ_ENABLE_SET); |
67 | } | 66 | } |
68 | 67 | ||
69 | static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc) | 68 | static void fpga_irq_handle(unsigned int __irq, struct irq_desc *desc) |
70 | { | 69 | { |
71 | struct fpga_irq_data *f = irq_desc_get_handler_data(desc); | 70 | struct fpga_irq_data *f = irq_desc_get_handler_data(desc); |
71 | unsigned int irq = irq_desc_get_irq(desc); | ||
72 | u32 status = readl(f->base + IRQ_STATUS); | 72 | u32 status = readl(f->base + IRQ_STATUS); |
73 | 73 | ||
74 | if (status == 0) { | 74 | if (status == 0) { |
@@ -156,8 +156,8 @@ void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, | |||
156 | f->valid = valid; | 156 | f->valid = valid; |
157 | 157 | ||
158 | if (parent_irq != -1) { | 158 | if (parent_irq != -1) { |
159 | irq_set_handler_data(parent_irq, f); | 159 | irq_set_chained_handler_and_data(parent_irq, fpga_irq_handle, |
160 | irq_set_chained_handler(parent_irq, fpga_irq_handle); | 160 | f); |
161 | } | 161 | } |
162 | 162 | ||
163 | /* This will also allocate irq descriptors */ | 163 | /* This will also allocate irq descriptors */ |
diff --git a/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c index f5c01cbcc73a..2c2255886401 100644 --- a/drivers/irqchip/irq-vf610-mscm-ir.c +++ b/drivers/irqchip/irq-vf610-mscm-ir.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/cpu_pm.h> | 26 | #include <linux/cpu_pm.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
29 | #include <linux/irqchip.h> | ||
29 | #include <linux/irqdomain.h> | 30 | #include <linux/irqdomain.h> |
30 | #include <linux/mfd/syscon.h> | 31 | #include <linux/mfd/syscon.h> |
31 | #include <dt-bindings/interrupt-controller/arm-gic.h> | 32 | #include <dt-bindings/interrupt-controller/arm-gic.h> |
@@ -34,8 +35,6 @@ | |||
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
35 | #include <linux/regmap.h> | 36 | #include <linux/regmap.h> |
36 | 37 | ||
37 | #include "irqchip.h" | ||
38 | |||
39 | #define MSCM_CPxNUM 0x4 | 38 | #define MSCM_CPxNUM 0x4 |
40 | 39 | ||
41 | #define MSCM_IRSPRC(n) (0x80 + 2 * (n)) | 40 | #define MSCM_IRSPRC(n) (0x80 + 2 * (n)) |
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index d4ce331ea4a0..03846dff4212 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
27 | #include <linux/irqchip.h> | ||
27 | #include <linux/irqchip/chained_irq.h> | 28 | #include <linux/irqchip/chained_irq.h> |
28 | #include <linux/irqdomain.h> | 29 | #include <linux/irqdomain.h> |
29 | #include <linux/of.h> | 30 | #include <linux/of.h> |
@@ -37,8 +38,6 @@ | |||
37 | #include <asm/exception.h> | 38 | #include <asm/exception.h> |
38 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
39 | 40 | ||
40 | #include "irqchip.h" | ||
41 | |||
42 | #define VIC_IRQ_STATUS 0x00 | 41 | #define VIC_IRQ_STATUS 0x00 |
43 | #define VIC_FIQ_STATUS 0x04 | 42 | #define VIC_FIQ_STATUS 0x04 |
44 | #define VIC_INT_SELECT 0x0c /* 1 = FIQ, 0 = IRQ */ | 43 | #define VIC_INT_SELECT 0x0c /* 1 = FIQ, 0 = IRQ */ |
@@ -297,8 +296,8 @@ static void __init vic_register(void __iomem *base, unsigned int parent_irq, | |||
297 | vic_id++; | 296 | vic_id++; |
298 | 297 | ||
299 | if (parent_irq) { | 298 | if (parent_irq) { |
300 | irq_set_handler_data(parent_irq, v); | 299 | irq_set_chained_handler_and_data(parent_irq, |
301 | irq_set_chained_handler(parent_irq, vic_handle_irq_cascaded); | 300 | vic_handle_irq_cascaded, v); |
302 | } | 301 | } |
303 | 302 | ||
304 | v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, | 303 | v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, |
diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c index 0b297009b856..8371d9978d31 100644 --- a/drivers/irqchip/irq-vt8500.c +++ b/drivers/irqchip/irq-vt8500.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
30 | #include <linux/irqchip.h> | ||
30 | #include <linux/irqdomain.h> | 31 | #include <linux/irqdomain.h> |
31 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
32 | #include <linux/bitops.h> | 33 | #include <linux/bitops.h> |
@@ -39,8 +40,6 @@ | |||
39 | #include <asm/exception.h> | 40 | #include <asm/exception.h> |
40 | #include <asm/mach/irq.h> | 41 | #include <asm/mach/irq.h> |
41 | 42 | ||
42 | #include "irqchip.h" | ||
43 | |||
44 | #define VT8500_ICPC_IRQ 0x20 | 43 | #define VT8500_ICPC_IRQ 0x20 |
45 | #define VT8500_ICPC_FIQ 0x24 | 44 | #define VT8500_ICPC_FIQ 0x24 |
46 | #define VT8500_ICDC 0x40 /* Destination Control 64*u32 */ | 45 | #define VT8500_ICDC 0x40 /* Destination Control 64*u32 */ |
@@ -127,15 +126,15 @@ static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type) | |||
127 | return -EINVAL; | 126 | return -EINVAL; |
128 | case IRQF_TRIGGER_HIGH: | 127 | case IRQF_TRIGGER_HIGH: |
129 | dctr |= VT8500_TRIGGER_HIGH; | 128 | dctr |= VT8500_TRIGGER_HIGH; |
130 | __irq_set_handler_locked(d->irq, handle_level_irq); | 129 | irq_set_handler_locked(d, handle_level_irq); |
131 | break; | 130 | break; |
132 | case IRQF_TRIGGER_FALLING: | 131 | case IRQF_TRIGGER_FALLING: |
133 | dctr |= VT8500_TRIGGER_FALLING; | 132 | dctr |= VT8500_TRIGGER_FALLING; |
134 | __irq_set_handler_locked(d->irq, handle_edge_irq); | 133 | irq_set_handler_locked(d, handle_edge_irq); |
135 | break; | 134 | break; |
136 | case IRQF_TRIGGER_RISING: | 135 | case IRQF_TRIGGER_RISING: |
137 | dctr |= VT8500_TRIGGER_RISING; | 136 | dctr |= VT8500_TRIGGER_RISING; |
138 | __irq_set_handler_locked(d->irq, handle_edge_irq); | 137 | irq_set_handler_locked(d, handle_edge_irq); |
139 | break; | 138 | break; |
140 | } | 139 | } |
141 | writeb(dctr, base + VT8500_ICDC + d->hwirq); | 140 | writeb(dctr, base + VT8500_ICDC + d->hwirq); |
diff --git a/drivers/irqchip/irq-xtensa-mx.c b/drivers/irqchip/irq-xtensa-mx.c index e1c2f9632893..bb3ac5fe5846 100644 --- a/drivers/irqchip/irq-xtensa-mx.c +++ b/drivers/irqchip/irq-xtensa-mx.c | |||
@@ -11,12 +11,11 @@ | |||
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/irqdomain.h> | 12 | #include <linux/irqdomain.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/irqchip.h> | ||
14 | #include <linux/of.h> | 15 | #include <linux/of.h> |
15 | 16 | ||
16 | #include <asm/mxregs.h> | 17 | #include <asm/mxregs.h> |
17 | 18 | ||
18 | #include "irqchip.h" | ||
19 | |||
20 | #define HW_IRQ_IPI_COUNT 2 | 19 | #define HW_IRQ_IPI_COUNT 2 |
21 | #define HW_IRQ_MX_BASE 2 | 20 | #define HW_IRQ_MX_BASE 2 |
22 | #define HW_IRQ_EXTERN_BASE 3 | 21 | #define HW_IRQ_EXTERN_BASE 3 |
diff --git a/drivers/irqchip/irq-xtensa-pic.c b/drivers/irqchip/irq-xtensa-pic.c index 7d71126d1ce5..472ae1770964 100644 --- a/drivers/irqchip/irq-xtensa-pic.c +++ b/drivers/irqchip/irq-xtensa-pic.c | |||
@@ -15,10 +15,9 @@ | |||
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/irqdomain.h> | 16 | #include <linux/irqdomain.h> |
17 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
18 | #include <linux/irqchip.h> | ||
18 | #include <linux/of.h> | 19 | #include <linux/of.h> |
19 | 20 | ||
20 | #include "irqchip.h" | ||
21 | |||
22 | unsigned int cached_irq_mask; | 21 | unsigned int cached_irq_mask; |
23 | 22 | ||
24 | /* | 23 | /* |
diff --git a/drivers/irqchip/irq-zevio.c b/drivers/irqchip/irq-zevio.c index e4ef74ed454a..4c48fa88a03d 100644 --- a/drivers/irqchip/irq-zevio.c +++ b/drivers/irqchip/irq-zevio.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/irqchip.h> | ||
14 | #include <linux/of.h> | 15 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 16 | #include <linux/of_address.h> |
16 | #include <linux/of_irq.h> | 17 | #include <linux/of_irq.h> |
@@ -18,8 +19,6 @@ | |||
18 | #include <asm/mach/irq.h> | 19 | #include <asm/mach/irq.h> |
19 | #include <asm/exception.h> | 20 | #include <asm/exception.h> |
20 | 21 | ||
21 | #include "irqchip.h" | ||
22 | |||
23 | #define IO_STATUS 0x000 | 22 | #define IO_STATUS 0x000 |
24 | #define IO_RAW_STATUS 0x004 | 23 | #define IO_RAW_STATUS 0x004 |
25 | #define IO_ENABLE 0x008 | 24 | #define IO_ENABLE 0x008 |
diff --git a/drivers/irqchip/irqchip.h b/drivers/irqchip/irqchip.h deleted file mode 100644 index 0f67ae32464f..000000000000 --- a/drivers/irqchip/irqchip.h +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Thomas Petazzoni | ||
3 | * | ||
4 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/irqchip.h> | ||
diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c index acb721b31bcf..4cbd9c5dc1e6 100644 --- a/drivers/irqchip/spear-shirq.c +++ b/drivers/irqchip/spear-shirq.c | |||
@@ -18,14 +18,13 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
21 | #include <linux/irqchip.h> | ||
21 | #include <linux/irqdomain.h> | 22 | #include <linux/irqdomain.h> |
22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
23 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
24 | #include <linux/of_irq.h> | 25 | #include <linux/of_irq.h> |
25 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
26 | 27 | ||
27 | #include "irqchip.h" | ||
28 | |||
29 | /* | 28 | /* |
30 | * struct spear_shirq: shared irq structure | 29 | * struct spear_shirq: shared irq structure |
31 | * | 30 | * |
@@ -183,9 +182,9 @@ static struct spear_shirq *spear320_shirq_blocks[] = { | |||
183 | &spear320_shirq_intrcomm_ras, | 182 | &spear320_shirq_intrcomm_ras, |
184 | }; | 183 | }; |
185 | 184 | ||
186 | static void shirq_handler(unsigned irq, struct irq_desc *desc) | 185 | static void shirq_handler(unsigned __irq, struct irq_desc *desc) |
187 | { | 186 | { |
188 | struct spear_shirq *shirq = irq_get_handler_data(irq); | 187 | struct spear_shirq *shirq = irq_desc_get_handler_data(desc); |
189 | u32 pend; | 188 | u32 pend; |
190 | 189 | ||
191 | pend = readl(shirq->base + shirq->status_reg) & shirq->mask; | 190 | pend = readl(shirq->base + shirq->status_reg) & shirq->mask; |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 3cf7a01f557f..2956d725649f 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * driver. | 18 | * driver. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/device.h> | ||
21 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
22 | #include <linux/list.h> | 23 | #include <linux/list.h> |
23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
@@ -576,3 +577,23 @@ err: | |||
576 | kfree(desc); | 577 | kfree(desc); |
577 | } | 578 | } |
578 | } | 579 | } |
580 | |||
581 | /** | ||
582 | * of_msi_configure - Set the msi_domain field of a device | ||
583 | * @dev: device structure to associate with an MSI irq domain | ||
584 | * @np: device node for that device | ||
585 | */ | ||
586 | void of_msi_configure(struct device *dev, struct device_node *np) | ||
587 | { | ||
588 | struct device_node *msi_np; | ||
589 | struct irq_domain *d; | ||
590 | |||
591 | msi_np = of_parse_phandle(np, "msi-parent", 0); | ||
592 | if (!msi_np) | ||
593 | return; | ||
594 | |||
595 | d = irq_find_matching_host(msi_np, DOMAIN_BUS_PLATFORM_MSI); | ||
596 | if (!d) | ||
597 | d = irq_find_host(msi_np); | ||
598 | dev_set_msi_domain(dev, d); | ||
599 | } | ||
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index ddf8e42c9367..8a002d6151f2 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -184,6 +184,7 @@ static struct platform_device *of_platform_device_create_pdata( | |||
184 | dev->dev.bus = &platform_bus_type; | 184 | dev->dev.bus = &platform_bus_type; |
185 | dev->dev.platform_data = platform_data; | 185 | dev->dev.platform_data = platform_data; |
186 | of_dma_configure(&dev->dev, dev->dev.of_node); | 186 | of_dma_configure(&dev->dev, dev->dev.of_node); |
187 | of_msi_configure(&dev->dev, dev->dev.of_node); | ||
187 | 188 | ||
188 | if (of_device_add(dev) != 0) { | 189 | if (of_device_add(dev) != 0) { |
189 | of_dma_deconfigure(&dev->dev); | 190 | of_dma_deconfigure(&dev->dev); |
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 9ee04b4b68bf..144c77dfe4b1 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -691,7 +691,7 @@ static int iosapic_set_affinity_irq(struct irq_data *d, | |||
691 | if (dest_cpu < 0) | 691 | if (dest_cpu < 0) |
692 | return -1; | 692 | return -1; |
693 | 693 | ||
694 | cpumask_copy(d->affinity, cpumask_of(dest_cpu)); | 694 | cpumask_copy(irq_data_get_affinity_mask(d), cpumask_of(dest_cpu)); |
695 | vi->txn_addr = txn_affinity_addr(d->irq, dest_cpu); | 695 | vi->txn_addr = txn_affinity_addr(d->irq, dest_cpu); |
696 | 696 | ||
697 | spin_lock_irqsave(&iosapic_lock, flags); | 697 | spin_lock_irqsave(&iosapic_lock, flags); |
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c index f1d0749ebbf0..e71da991949b 100644 --- a/drivers/pci/host/pci-keystone-dw.c +++ b/drivers/pci/host/pci-keystone-dw.c | |||
@@ -104,14 +104,13 @@ static void ks_dw_pcie_msi_irq_ack(struct irq_data *d) | |||
104 | { | 104 | { |
105 | u32 offset, reg_offset, bit_pos; | 105 | u32 offset, reg_offset, bit_pos; |
106 | struct keystone_pcie *ks_pcie; | 106 | struct keystone_pcie *ks_pcie; |
107 | unsigned int irq = d->irq; | ||
108 | struct msi_desc *msi; | 107 | struct msi_desc *msi; |
109 | struct pcie_port *pp; | 108 | struct pcie_port *pp; |
110 | 109 | ||
111 | msi = irq_get_msi_desc(irq); | 110 | msi = irq_data_get_msi_desc(d); |
112 | pp = sys_to_pcie(msi->dev->bus->sysdata); | 111 | pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); |
113 | ks_pcie = to_keystone_pcie(pp); | 112 | ks_pcie = to_keystone_pcie(pp); |
114 | offset = irq - irq_linear_revmap(pp->irq_domain, 0); | 113 | offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); |
115 | update_reg_offset_bit_pos(offset, ®_offset, &bit_pos); | 114 | update_reg_offset_bit_pos(offset, ®_offset, &bit_pos); |
116 | 115 | ||
117 | writel(BIT(bit_pos), | 116 | writel(BIT(bit_pos), |
@@ -142,15 +141,14 @@ void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) | |||
142 | static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) | 141 | static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) |
143 | { | 142 | { |
144 | struct keystone_pcie *ks_pcie; | 143 | struct keystone_pcie *ks_pcie; |
145 | unsigned int irq = d->irq; | ||
146 | struct msi_desc *msi; | 144 | struct msi_desc *msi; |
147 | struct pcie_port *pp; | 145 | struct pcie_port *pp; |
148 | u32 offset; | 146 | u32 offset; |
149 | 147 | ||
150 | msi = irq_get_msi_desc(irq); | 148 | msi = irq_data_get_msi_desc(d); |
151 | pp = sys_to_pcie(msi->dev->bus->sysdata); | 149 | pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); |
152 | ks_pcie = to_keystone_pcie(pp); | 150 | ks_pcie = to_keystone_pcie(pp); |
153 | offset = irq - irq_linear_revmap(pp->irq_domain, 0); | 151 | offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); |
154 | 152 | ||
155 | /* Mask the end point if PVM implemented */ | 153 | /* Mask the end point if PVM implemented */ |
156 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 154 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
@@ -164,15 +162,14 @@ static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) | |||
164 | static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d) | 162 | static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d) |
165 | { | 163 | { |
166 | struct keystone_pcie *ks_pcie; | 164 | struct keystone_pcie *ks_pcie; |
167 | unsigned int irq = d->irq; | ||
168 | struct msi_desc *msi; | 165 | struct msi_desc *msi; |
169 | struct pcie_port *pp; | 166 | struct pcie_port *pp; |
170 | u32 offset; | 167 | u32 offset; |
171 | 168 | ||
172 | msi = irq_get_msi_desc(irq); | 169 | msi = irq_data_get_msi_desc(d); |
173 | pp = sys_to_pcie(msi->dev->bus->sysdata); | 170 | pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); |
174 | ks_pcie = to_keystone_pcie(pp); | 171 | ks_pcie = to_keystone_pcie(pp); |
175 | offset = irq - irq_linear_revmap(pp->irq_domain, 0); | 172 | offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); |
176 | 173 | ||
177 | /* Mask the end point if PVM implemented */ | 174 | /* Mask the end point if PVM implemented */ |
178 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 175 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 734da589cdfb..81253e70b1c5 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c | |||
@@ -110,8 +110,9 @@ static int ks_pcie_establish_link(struct keystone_pcie *ks_pcie) | |||
110 | return -EINVAL; | 110 | return -EINVAL; |
111 | } | 111 | } |
112 | 112 | ||
113 | static void ks_pcie_msi_irq_handler(unsigned int irq, struct irq_desc *desc) | 113 | static void ks_pcie_msi_irq_handler(unsigned int __irq, struct irq_desc *desc) |
114 | { | 114 | { |
115 | unsigned int irq = irq_desc_get_irq(desc); | ||
115 | struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); | 116 | struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); |
116 | u32 offset = irq - ks_pcie->msi_host_irqs[0]; | 117 | u32 offset = irq - ks_pcie->msi_host_irqs[0]; |
117 | struct pcie_port *pp = &ks_pcie->pp; | 118 | struct pcie_port *pp = &ks_pcie->pp; |
@@ -137,8 +138,10 @@ static void ks_pcie_msi_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
137 | * Traverse through pending legacy interrupts and invoke handler for each. Also | 138 | * Traverse through pending legacy interrupts and invoke handler for each. Also |
138 | * takes care of interrupt controller level mask/ack operation. | 139 | * takes care of interrupt controller level mask/ack operation. |
139 | */ | 140 | */ |
140 | static void ks_pcie_legacy_irq_handler(unsigned int irq, struct irq_desc *desc) | 141 | static void ks_pcie_legacy_irq_handler(unsigned int __irq, |
142 | struct irq_desc *desc) | ||
141 | { | 143 | { |
144 | unsigned int irq = irq_desc_get_irq(desc); | ||
142 | struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); | 145 | struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); |
143 | struct pcie_port *pp = &ks_pcie->pp; | 146 | struct pcie_port *pp = &ks_pcie->pp; |
144 | u32 irq_offset = irq - ks_pcie->legacy_host_irqs[0]; | 147 | u32 irq_offset = irq - ks_pcie->legacy_host_irqs[0]; |
@@ -212,9 +215,9 @@ static void ks_pcie_setup_interrupts(struct keystone_pcie *ks_pcie) | |||
212 | 215 | ||
213 | /* Legacy IRQ */ | 216 | /* Legacy IRQ */ |
214 | for (i = 0; i < ks_pcie->num_legacy_host_irqs; i++) { | 217 | for (i = 0; i < ks_pcie->num_legacy_host_irqs; i++) { |
215 | irq_set_handler_data(ks_pcie->legacy_host_irqs[i], ks_pcie); | 218 | irq_set_chained_handler_and_data(ks_pcie->legacy_host_irqs[i], |
216 | irq_set_chained_handler(ks_pcie->legacy_host_irqs[i], | 219 | ks_pcie_legacy_irq_handler, |
217 | ks_pcie_legacy_irq_handler); | 220 | ks_pcie); |
218 | } | 221 | } |
219 | ks_dw_pcie_enable_legacy_irqs(ks_pcie); | 222 | ks_dw_pcie_enable_legacy_irqs(ks_pcie); |
220 | 223 | ||
diff --git a/drivers/pci/host/pci-xgene-msi.c b/drivers/pci/host/pci-xgene-msi.c index 398c9bfe13a9..996327cfa1e1 100644 --- a/drivers/pci/host/pci-xgene-msi.c +++ b/drivers/pci/host/pci-xgene-msi.c | |||
@@ -40,8 +40,8 @@ struct xgene_msi_group { | |||
40 | 40 | ||
41 | struct xgene_msi { | 41 | struct xgene_msi { |
42 | struct device_node *node; | 42 | struct device_node *node; |
43 | struct msi_controller mchip; | 43 | struct irq_domain *inner_domain; |
44 | struct irq_domain *domain; | 44 | struct irq_domain *msi_domain; |
45 | u64 msi_addr; | 45 | u64 msi_addr; |
46 | void __iomem *msi_regs; | 46 | void __iomem *msi_regs; |
47 | unsigned long *bitmap; | 47 | unsigned long *bitmap; |
@@ -251,17 +251,17 @@ static const struct irq_domain_ops msi_domain_ops = { | |||
251 | 251 | ||
252 | static int xgene_allocate_domains(struct xgene_msi *msi) | 252 | static int xgene_allocate_domains(struct xgene_msi *msi) |
253 | { | 253 | { |
254 | msi->domain = irq_domain_add_linear(NULL, NR_MSI_VEC, | 254 | msi->inner_domain = irq_domain_add_linear(NULL, NR_MSI_VEC, |
255 | &msi_domain_ops, msi); | 255 | &msi_domain_ops, msi); |
256 | if (!msi->domain) | 256 | if (!msi->inner_domain) |
257 | return -ENOMEM; | 257 | return -ENOMEM; |
258 | 258 | ||
259 | msi->mchip.domain = pci_msi_create_irq_domain(msi->mchip.of_node, | 259 | msi->msi_domain = pci_msi_create_irq_domain(msi->node, |
260 | &xgene_msi_domain_info, | 260 | &xgene_msi_domain_info, |
261 | msi->domain); | 261 | msi->inner_domain); |
262 | 262 | ||
263 | if (!msi->mchip.domain) { | 263 | if (!msi->msi_domain) { |
264 | irq_domain_remove(msi->domain); | 264 | irq_domain_remove(msi->inner_domain); |
265 | return -ENOMEM; | 265 | return -ENOMEM; |
266 | } | 266 | } |
267 | 267 | ||
@@ -270,10 +270,10 @@ static int xgene_allocate_domains(struct xgene_msi *msi) | |||
270 | 270 | ||
271 | static void xgene_free_domains(struct xgene_msi *msi) | 271 | static void xgene_free_domains(struct xgene_msi *msi) |
272 | { | 272 | { |
273 | if (msi->mchip.domain) | 273 | if (msi->msi_domain) |
274 | irq_domain_remove(msi->mchip.domain); | 274 | irq_domain_remove(msi->msi_domain); |
275 | if (msi->domain) | 275 | if (msi->inner_domain) |
276 | irq_domain_remove(msi->domain); | 276 | irq_domain_remove(msi->inner_domain); |
277 | } | 277 | } |
278 | 278 | ||
279 | static int xgene_msi_init_allocator(struct xgene_msi *xgene_msi) | 279 | static int xgene_msi_init_allocator(struct xgene_msi *xgene_msi) |
@@ -339,7 +339,7 @@ static void xgene_msi_isr(unsigned int irq, struct irq_desc *desc) | |||
339 | * CPU0 | 339 | * CPU0 |
340 | */ | 340 | */ |
341 | hw_irq = hwirq_to_canonical_hwirq(hw_irq); | 341 | hw_irq = hwirq_to_canonical_hwirq(hw_irq); |
342 | virq = irq_find_mapping(xgene_msi->domain, hw_irq); | 342 | virq = irq_find_mapping(xgene_msi->inner_domain, hw_irq); |
343 | WARN_ON(!virq); | 343 | WARN_ON(!virq); |
344 | if (virq != 0) | 344 | if (virq != 0) |
345 | generic_handle_irq(virq); | 345 | generic_handle_irq(virq); |
@@ -367,10 +367,8 @@ static int xgene_msi_remove(struct platform_device *pdev) | |||
367 | 367 | ||
368 | for (i = 0; i < NR_HW_IRQS; i++) { | 368 | for (i = 0; i < NR_HW_IRQS; i++) { |
369 | virq = msi->msi_groups[i].gic_irq; | 369 | virq = msi->msi_groups[i].gic_irq; |
370 | if (virq != 0) { | 370 | if (virq != 0) |
371 | irq_set_chained_handler(virq, NULL); | 371 | irq_set_chained_handler_and_data(virq, NULL, NULL); |
372 | irq_set_handler_data(virq, NULL); | ||
373 | } | ||
374 | } | 372 | } |
375 | kfree(msi->msi_groups); | 373 | kfree(msi->msi_groups); |
376 | 374 | ||
@@ -420,8 +418,8 @@ static int xgene_msi_hwirq_alloc(unsigned int cpu) | |||
420 | } | 418 | } |
421 | 419 | ||
422 | if (err) { | 420 | if (err) { |
423 | irq_set_chained_handler(msi_group->gic_irq, NULL); | 421 | irq_set_chained_handler_and_data(msi_group->gic_irq, |
424 | irq_set_handler_data(msi_group->gic_irq, NULL); | 422 | NULL, NULL); |
425 | return err; | 423 | return err; |
426 | } | 424 | } |
427 | } | 425 | } |
@@ -440,8 +438,8 @@ static void xgene_msi_hwirq_free(unsigned int cpu) | |||
440 | if (!msi_group->gic_irq) | 438 | if (!msi_group->gic_irq) |
441 | continue; | 439 | continue; |
442 | 440 | ||
443 | irq_set_chained_handler(msi_group->gic_irq, NULL); | 441 | irq_set_chained_handler_and_data(msi_group->gic_irq, NULL, |
444 | irq_set_handler_data(msi_group->gic_irq, NULL); | 442 | NULL); |
445 | } | 443 | } |
446 | } | 444 | } |
447 | 445 | ||
@@ -496,7 +494,7 @@ static int xgene_msi_probe(struct platform_device *pdev) | |||
496 | goto error; | 494 | goto error; |
497 | } | 495 | } |
498 | xgene_msi->msi_addr = res->start; | 496 | xgene_msi->msi_addr = res->start; |
499 | 497 | xgene_msi->node = pdev->dev.of_node; | |
500 | xgene_msi->num_cpus = num_possible_cpus(); | 498 | xgene_msi->num_cpus = num_possible_cpus(); |
501 | 499 | ||
502 | rc = xgene_msi_init_allocator(xgene_msi); | 500 | rc = xgene_msi_init_allocator(xgene_msi); |
@@ -560,19 +558,10 @@ static int xgene_msi_probe(struct platform_device *pdev) | |||
560 | 558 | ||
561 | cpu_notifier_register_done(); | 559 | cpu_notifier_register_done(); |
562 | 560 | ||
563 | xgene_msi->mchip.of_node = pdev->dev.of_node; | ||
564 | rc = of_pci_msi_chip_add(&xgene_msi->mchip); | ||
565 | if (rc) { | ||
566 | dev_err(&pdev->dev, "failed to add MSI controller chip\n"); | ||
567 | goto error_notifier; | ||
568 | } | ||
569 | |||
570 | dev_info(&pdev->dev, "APM X-Gene PCIe MSI driver loaded\n"); | 561 | dev_info(&pdev->dev, "APM X-Gene PCIe MSI driver loaded\n"); |
571 | 562 | ||
572 | return 0; | 563 | return 0; |
573 | 564 | ||
574 | error_notifier: | ||
575 | unregister_hotcpu_notifier(&xgene_msi_cpu_notifier); | ||
576 | error: | 565 | error: |
577 | xgene_msi_remove(pdev); | 566 | xgene_msi_remove(pdev); |
578 | return rc; | 567 | return rc; |
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 8d52ce73f842..52aa6e34002b 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -255,7 +255,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) | |||
255 | static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) | 255 | static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) |
256 | { | 256 | { |
257 | int irq, pos0, i; | 257 | int irq, pos0, i; |
258 | struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); | 258 | struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(desc)); |
259 | 259 | ||
260 | pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, | 260 | pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, |
261 | order_base_2(no_irqs)); | 261 | order_base_2(no_irqs)); |
@@ -326,8 +326,8 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, | |||
326 | static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) | 326 | static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) |
327 | { | 327 | { |
328 | struct irq_data *data = irq_get_irq_data(irq); | 328 | struct irq_data *data = irq_get_irq_data(irq); |
329 | struct msi_desc *msi = irq_data_get_msi(data); | 329 | struct msi_desc *msi = irq_data_get_msi_desc(data); |
330 | struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); | 330 | struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); |
331 | 331 | ||
332 | clear_irq_range(pp, irq, 1, data->hwirq); | 332 | clear_irq_range(pp, irq, 1, data->hwirq); |
333 | } | 333 | } |
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index 1aeaa914bd30..3c7a0d580b1e 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c | |||
@@ -227,18 +227,16 @@ static struct pci_ops xilinx_pcie_ops = { | |||
227 | */ | 227 | */ |
228 | static void xilinx_pcie_destroy_msi(unsigned int irq) | 228 | static void xilinx_pcie_destroy_msi(unsigned int irq) |
229 | { | 229 | { |
230 | struct irq_desc *desc; | ||
231 | struct msi_desc *msi; | 230 | struct msi_desc *msi; |
232 | struct xilinx_pcie_port *port; | 231 | struct xilinx_pcie_port *port; |
233 | 232 | ||
234 | desc = irq_to_desc(irq); | 233 | if (!test_bit(irq, msi_irq_in_use)) { |
235 | msi = irq_desc_get_msi_desc(desc); | 234 | msi = irq_get_msi_desc(irq); |
236 | port = sys_to_pcie(msi->dev->bus->sysdata); | 235 | port = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); |
237 | |||
238 | if (!test_bit(irq, msi_irq_in_use)) | ||
239 | dev_err(port->dev, "Trying to free unused MSI#%d\n", irq); | 236 | dev_err(port->dev, "Trying to free unused MSI#%d\n", irq); |
240 | else | 237 | } else { |
241 | clear_bit(irq, msi_irq_in_use); | 238 | clear_bit(irq, msi_irq_in_use); |
239 | } | ||
242 | } | 240 | } |
243 | 241 | ||
244 | /** | 242 | /** |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 2f9b1c0d1f96..d4497141d083 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -39,14 +39,13 @@ struct irq_domain * __weak arch_get_pci_msi_domain(struct pci_dev *dev) | |||
39 | 39 | ||
40 | static struct irq_domain *pci_msi_get_domain(struct pci_dev *dev) | 40 | static struct irq_domain *pci_msi_get_domain(struct pci_dev *dev) |
41 | { | 41 | { |
42 | struct irq_domain *domain = NULL; | 42 | struct irq_domain *domain; |
43 | 43 | ||
44 | if (dev->bus->msi) | 44 | domain = dev_get_msi_domain(&dev->dev); |
45 | domain = dev->bus->msi->domain; | 45 | if (domain) |
46 | if (!domain) | 46 | return domain; |
47 | domain = arch_get_pci_msi_domain(dev); | ||
48 | 47 | ||
49 | return domain; | 48 | return arch_get_pci_msi_domain(dev); |
50 | } | 49 | } |
51 | 50 | ||
52 | static int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | 51 | static int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) |
@@ -116,7 +115,7 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
116 | if (type == PCI_CAP_ID_MSI && nvec > 1) | 115 | if (type == PCI_CAP_ID_MSI && nvec > 1) |
117 | return 1; | 116 | return 1; |
118 | 117 | ||
119 | list_for_each_entry(entry, &dev->msi_list, list) { | 118 | for_each_pci_msi_entry(entry, dev) { |
120 | ret = arch_setup_msi_irq(dev, entry); | 119 | ret = arch_setup_msi_irq(dev, entry); |
121 | if (ret < 0) | 120 | if (ret < 0) |
122 | return ret; | 121 | return ret; |
@@ -136,7 +135,7 @@ void default_teardown_msi_irqs(struct pci_dev *dev) | |||
136 | int i; | 135 | int i; |
137 | struct msi_desc *entry; | 136 | struct msi_desc *entry; |
138 | 137 | ||
139 | list_for_each_entry(entry, &dev->msi_list, list) | 138 | for_each_pci_msi_entry(entry, dev) |
140 | if (entry->irq) | 139 | if (entry->irq) |
141 | for (i = 0; i < entry->nvec_used; i++) | 140 | for (i = 0; i < entry->nvec_used; i++) |
142 | arch_teardown_msi_irq(entry->irq + i); | 141 | arch_teardown_msi_irq(entry->irq + i); |
@@ -153,7 +152,7 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq) | |||
153 | 152 | ||
154 | entry = NULL; | 153 | entry = NULL; |
155 | if (dev->msix_enabled) { | 154 | if (dev->msix_enabled) { |
156 | list_for_each_entry(entry, &dev->msi_list, list) { | 155 | for_each_pci_msi_entry(entry, dev) { |
157 | if (irq == entry->irq) | 156 | if (irq == entry->irq) |
158 | break; | 157 | break; |
159 | } | 158 | } |
@@ -193,7 +192,8 @@ u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) | |||
193 | 192 | ||
194 | mask_bits &= ~mask; | 193 | mask_bits &= ~mask; |
195 | mask_bits |= flag; | 194 | mask_bits |= flag; |
196 | pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits); | 195 | pci_write_config_dword(msi_desc_to_pci_dev(desc), desc->mask_pos, |
196 | mask_bits); | ||
197 | 197 | ||
198 | return mask_bits; | 198 | return mask_bits; |
199 | } | 199 | } |
@@ -234,7 +234,7 @@ static void msix_mask_irq(struct msi_desc *desc, u32 flag) | |||
234 | 234 | ||
235 | static void msi_set_mask_bit(struct irq_data *data, u32 flag) | 235 | static void msi_set_mask_bit(struct irq_data *data, u32 flag) |
236 | { | 236 | { |
237 | struct msi_desc *desc = irq_data_get_msi(data); | 237 | struct msi_desc *desc = irq_data_get_msi_desc(data); |
238 | 238 | ||
239 | if (desc->msi_attrib.is_msix) { | 239 | if (desc->msi_attrib.is_msix) { |
240 | msix_mask_irq(desc, flag); | 240 | msix_mask_irq(desc, flag); |
@@ -267,13 +267,15 @@ void default_restore_msi_irqs(struct pci_dev *dev) | |||
267 | { | 267 | { |
268 | struct msi_desc *entry; | 268 | struct msi_desc *entry; |
269 | 269 | ||
270 | list_for_each_entry(entry, &dev->msi_list, list) | 270 | for_each_pci_msi_entry(entry, dev) |
271 | default_restore_msi_irq(dev, entry->irq); | 271 | default_restore_msi_irq(dev, entry->irq); |
272 | } | 272 | } |
273 | 273 | ||
274 | void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | 274 | void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) |
275 | { | 275 | { |
276 | BUG_ON(entry->dev->current_state != PCI_D0); | 276 | struct pci_dev *dev = msi_desc_to_pci_dev(entry); |
277 | |||
278 | BUG_ON(dev->current_state != PCI_D0); | ||
277 | 279 | ||
278 | if (entry->msi_attrib.is_msix) { | 280 | if (entry->msi_attrib.is_msix) { |
279 | void __iomem *base = entry->mask_base + | 281 | void __iomem *base = entry->mask_base + |
@@ -283,7 +285,6 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | |||
283 | msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); | 285 | msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); |
284 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA); | 286 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA); |
285 | } else { | 287 | } else { |
286 | struct pci_dev *dev = entry->dev; | ||
287 | int pos = dev->msi_cap; | 288 | int pos = dev->msi_cap; |
288 | u16 data; | 289 | u16 data; |
289 | 290 | ||
@@ -303,7 +304,9 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | |||
303 | 304 | ||
304 | void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | 305 | void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) |
305 | { | 306 | { |
306 | if (entry->dev->current_state != PCI_D0) { | 307 | struct pci_dev *dev = msi_desc_to_pci_dev(entry); |
308 | |||
309 | if (dev->current_state != PCI_D0) { | ||
307 | /* Don't touch the hardware now */ | 310 | /* Don't touch the hardware now */ |
308 | } else if (entry->msi_attrib.is_msix) { | 311 | } else if (entry->msi_attrib.is_msix) { |
309 | void __iomem *base; | 312 | void __iomem *base; |
@@ -314,7 +317,6 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | |||
314 | writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); | 317 | writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); |
315 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA); | 318 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA); |
316 | } else { | 319 | } else { |
317 | struct pci_dev *dev = entry->dev; | ||
318 | int pos = dev->msi_cap; | 320 | int pos = dev->msi_cap; |
319 | u16 msgctl; | 321 | u16 msgctl; |
320 | 322 | ||
@@ -348,21 +350,22 @@ EXPORT_SYMBOL_GPL(pci_write_msi_msg); | |||
348 | 350 | ||
349 | static void free_msi_irqs(struct pci_dev *dev) | 351 | static void free_msi_irqs(struct pci_dev *dev) |
350 | { | 352 | { |
353 | struct list_head *msi_list = dev_to_msi_list(&dev->dev); | ||
351 | struct msi_desc *entry, *tmp; | 354 | struct msi_desc *entry, *tmp; |
352 | struct attribute **msi_attrs; | 355 | struct attribute **msi_attrs; |
353 | struct device_attribute *dev_attr; | 356 | struct device_attribute *dev_attr; |
354 | int i, count = 0; | 357 | int i, count = 0; |
355 | 358 | ||
356 | list_for_each_entry(entry, &dev->msi_list, list) | 359 | for_each_pci_msi_entry(entry, dev) |
357 | if (entry->irq) | 360 | if (entry->irq) |
358 | for (i = 0; i < entry->nvec_used; i++) | 361 | for (i = 0; i < entry->nvec_used; i++) |
359 | BUG_ON(irq_has_action(entry->irq + i)); | 362 | BUG_ON(irq_has_action(entry->irq + i)); |
360 | 363 | ||
361 | pci_msi_teardown_msi_irqs(dev); | 364 | pci_msi_teardown_msi_irqs(dev); |
362 | 365 | ||
363 | list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) { | 366 | list_for_each_entry_safe(entry, tmp, msi_list, list) { |
364 | if (entry->msi_attrib.is_msix) { | 367 | if (entry->msi_attrib.is_msix) { |
365 | if (list_is_last(&entry->list, &dev->msi_list)) | 368 | if (list_is_last(&entry->list, msi_list)) |
366 | iounmap(entry->mask_base); | 369 | iounmap(entry->mask_base); |
367 | } | 370 | } |
368 | 371 | ||
@@ -387,18 +390,6 @@ static void free_msi_irqs(struct pci_dev *dev) | |||
387 | } | 390 | } |
388 | } | 391 | } |
389 | 392 | ||
390 | static struct msi_desc *alloc_msi_entry(struct pci_dev *dev) | ||
391 | { | ||
392 | struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL); | ||
393 | if (!desc) | ||
394 | return NULL; | ||
395 | |||
396 | INIT_LIST_HEAD(&desc->list); | ||
397 | desc->dev = dev; | ||
398 | |||
399 | return desc; | ||
400 | } | ||
401 | |||
402 | static void pci_intx_for_msi(struct pci_dev *dev, int enable) | 393 | static void pci_intx_for_msi(struct pci_dev *dev, int enable) |
403 | { | 394 | { |
404 | if (!(dev->dev_flags & PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG)) | 395 | if (!(dev->dev_flags & PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG)) |
@@ -433,7 +424,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) | |||
433 | 424 | ||
434 | if (!dev->msix_enabled) | 425 | if (!dev->msix_enabled) |
435 | return; | 426 | return; |
436 | BUG_ON(list_empty(&dev->msi_list)); | 427 | BUG_ON(list_empty(dev_to_msi_list(&dev->dev))); |
437 | 428 | ||
438 | /* route the table */ | 429 | /* route the table */ |
439 | pci_intx_for_msi(dev, 0); | 430 | pci_intx_for_msi(dev, 0); |
@@ -441,7 +432,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) | |||
441 | PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL); | 432 | PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL); |
442 | 433 | ||
443 | arch_restore_msi_irqs(dev); | 434 | arch_restore_msi_irqs(dev); |
444 | list_for_each_entry(entry, &dev->msi_list, list) | 435 | for_each_pci_msi_entry(entry, dev) |
445 | msix_mask_irq(entry, entry->masked); | 436 | msix_mask_irq(entry, entry->masked); |
446 | 437 | ||
447 | pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0); | 438 | pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0); |
@@ -486,7 +477,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev) | |||
486 | int count = 0; | 477 | int count = 0; |
487 | 478 | ||
488 | /* Determine how many msi entries we have */ | 479 | /* Determine how many msi entries we have */ |
489 | list_for_each_entry(entry, &pdev->msi_list, list) | 480 | for_each_pci_msi_entry(entry, pdev) |
490 | ++num_msi; | 481 | ++num_msi; |
491 | if (!num_msi) | 482 | if (!num_msi) |
492 | return 0; | 483 | return 0; |
@@ -495,7 +486,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev) | |||
495 | msi_attrs = kzalloc(sizeof(void *) * (num_msi + 1), GFP_KERNEL); | 486 | msi_attrs = kzalloc(sizeof(void *) * (num_msi + 1), GFP_KERNEL); |
496 | if (!msi_attrs) | 487 | if (!msi_attrs) |
497 | return -ENOMEM; | 488 | return -ENOMEM; |
498 | list_for_each_entry(entry, &pdev->msi_list, list) { | 489 | for_each_pci_msi_entry(entry, pdev) { |
499 | msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); | 490 | msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); |
500 | if (!msi_dev_attr) | 491 | if (!msi_dev_attr) |
501 | goto error_attrs; | 492 | goto error_attrs; |
@@ -553,7 +544,7 @@ static struct msi_desc *msi_setup_entry(struct pci_dev *dev, int nvec) | |||
553 | struct msi_desc *entry; | 544 | struct msi_desc *entry; |
554 | 545 | ||
555 | /* MSI Entry Initialization */ | 546 | /* MSI Entry Initialization */ |
556 | entry = alloc_msi_entry(dev); | 547 | entry = alloc_msi_entry(&dev->dev); |
557 | if (!entry) | 548 | if (!entry) |
558 | return NULL; | 549 | return NULL; |
559 | 550 | ||
@@ -584,7 +575,7 @@ static int msi_verify_entries(struct pci_dev *dev) | |||
584 | { | 575 | { |
585 | struct msi_desc *entry; | 576 | struct msi_desc *entry; |
586 | 577 | ||
587 | list_for_each_entry(entry, &dev->msi_list, list) { | 578 | for_each_pci_msi_entry(entry, dev) { |
588 | if (!dev->no_64bit_msi || !entry->msg.address_hi) | 579 | if (!dev->no_64bit_msi || !entry->msg.address_hi) |
589 | continue; | 580 | continue; |
590 | dev_err(&dev->dev, "Device has broken 64-bit MSI but arch" | 581 | dev_err(&dev->dev, "Device has broken 64-bit MSI but arch" |
@@ -621,7 +612,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) | |||
621 | mask = msi_mask(entry->msi_attrib.multi_cap); | 612 | mask = msi_mask(entry->msi_attrib.multi_cap); |
622 | msi_mask_irq(entry, mask, mask); | 613 | msi_mask_irq(entry, mask, mask); |
623 | 614 | ||
624 | list_add_tail(&entry->list, &dev->msi_list); | 615 | list_add_tail(&entry->list, dev_to_msi_list(&dev->dev)); |
625 | 616 | ||
626 | /* Configure MSI capability structure */ | 617 | /* Configure MSI capability structure */ |
627 | ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); | 618 | ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); |
@@ -682,7 +673,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, | |||
682 | int i; | 673 | int i; |
683 | 674 | ||
684 | for (i = 0; i < nvec; i++) { | 675 | for (i = 0; i < nvec; i++) { |
685 | entry = alloc_msi_entry(dev); | 676 | entry = alloc_msi_entry(&dev->dev); |
686 | if (!entry) { | 677 | if (!entry) { |
687 | if (!i) | 678 | if (!i) |
688 | iounmap(base); | 679 | iounmap(base); |
@@ -699,7 +690,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, | |||
699 | entry->mask_base = base; | 690 | entry->mask_base = base; |
700 | entry->nvec_used = 1; | 691 | entry->nvec_used = 1; |
701 | 692 | ||
702 | list_add_tail(&entry->list, &dev->msi_list); | 693 | list_add_tail(&entry->list, dev_to_msi_list(&dev->dev)); |
703 | } | 694 | } |
704 | 695 | ||
705 | return 0; | 696 | return 0; |
@@ -711,7 +702,7 @@ static void msix_program_entries(struct pci_dev *dev, | |||
711 | struct msi_desc *entry; | 702 | struct msi_desc *entry; |
712 | int i = 0; | 703 | int i = 0; |
713 | 704 | ||
714 | list_for_each_entry(entry, &dev->msi_list, list) { | 705 | for_each_pci_msi_entry(entry, dev) { |
715 | int offset = entries[i].entry * PCI_MSIX_ENTRY_SIZE + | 706 | int offset = entries[i].entry * PCI_MSIX_ENTRY_SIZE + |
716 | PCI_MSIX_ENTRY_VECTOR_CTRL; | 707 | PCI_MSIX_ENTRY_VECTOR_CTRL; |
717 | 708 | ||
@@ -792,7 +783,7 @@ out_avail: | |||
792 | struct msi_desc *entry; | 783 | struct msi_desc *entry; |
793 | int avail = 0; | 784 | int avail = 0; |
794 | 785 | ||
795 | list_for_each_entry(entry, &dev->msi_list, list) { | 786 | for_each_pci_msi_entry(entry, dev) { |
796 | if (entry->irq != 0) | 787 | if (entry->irq != 0) |
797 | avail++; | 788 | avail++; |
798 | } | 789 | } |
@@ -881,8 +872,8 @@ void pci_msi_shutdown(struct pci_dev *dev) | |||
881 | if (!pci_msi_enable || !dev || !dev->msi_enabled) | 872 | if (!pci_msi_enable || !dev || !dev->msi_enabled) |
882 | return; | 873 | return; |
883 | 874 | ||
884 | BUG_ON(list_empty(&dev->msi_list)); | 875 | BUG_ON(list_empty(dev_to_msi_list(&dev->dev))); |
885 | desc = list_first_entry(&dev->msi_list, struct msi_desc, list); | 876 | desc = first_pci_msi_entry(dev); |
886 | 877 | ||
887 | pci_msi_set_enable(dev, 0); | 878 | pci_msi_set_enable(dev, 0); |
888 | pci_intx_for_msi(dev, 1); | 879 | pci_intx_for_msi(dev, 1); |
@@ -988,7 +979,7 @@ void pci_msix_shutdown(struct pci_dev *dev) | |||
988 | return; | 979 | return; |
989 | 980 | ||
990 | /* Return the device with MSI-X masked as initial states */ | 981 | /* Return the device with MSI-X masked as initial states */ |
991 | list_for_each_entry(entry, &dev->msi_list, list) { | 982 | for_each_pci_msi_entry(entry, dev) { |
992 | /* Keep cached states to be restored */ | 983 | /* Keep cached states to be restored */ |
993 | __pci_msix_desc_mask_irq(entry, 1); | 984 | __pci_msix_desc_mask_irq(entry, 1); |
994 | } | 985 | } |
@@ -1028,7 +1019,6 @@ EXPORT_SYMBOL(pci_msi_enabled); | |||
1028 | 1019 | ||
1029 | void pci_msi_init_pci_dev(struct pci_dev *dev) | 1020 | void pci_msi_init_pci_dev(struct pci_dev *dev) |
1030 | { | 1021 | { |
1031 | INIT_LIST_HEAD(&dev->msi_list); | ||
1032 | } | 1022 | } |
1033 | 1023 | ||
1034 | /** | 1024 | /** |
@@ -1125,6 +1115,19 @@ int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | |||
1125 | } | 1115 | } |
1126 | EXPORT_SYMBOL(pci_enable_msix_range); | 1116 | EXPORT_SYMBOL(pci_enable_msix_range); |
1127 | 1117 | ||
1118 | struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc) | ||
1119 | { | ||
1120 | return to_pci_dev(desc->dev); | ||
1121 | } | ||
1122 | |||
1123 | void *msi_desc_to_pci_sysdata(struct msi_desc *desc) | ||
1124 | { | ||
1125 | struct pci_dev *dev = msi_desc_to_pci_dev(desc); | ||
1126 | |||
1127 | return dev->bus->sysdata; | ||
1128 | } | ||
1129 | EXPORT_SYMBOL_GPL(msi_desc_to_pci_sysdata); | ||
1130 | |||
1128 | #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN | 1131 | #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN |
1129 | /** | 1132 | /** |
1130 | * pci_msi_domain_write_msg - Helper to write MSI message to PCI config space | 1133 | * pci_msi_domain_write_msg - Helper to write MSI message to PCI config space |
@@ -1133,7 +1136,7 @@ EXPORT_SYMBOL(pci_enable_msix_range); | |||
1133 | */ | 1136 | */ |
1134 | void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg) | 1137 | void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg) |
1135 | { | 1138 | { |
1136 | struct msi_desc *desc = irq_data->msi_desc; | 1139 | struct msi_desc *desc = irq_data_get_msi_desc(irq_data); |
1137 | 1140 | ||
1138 | /* | 1141 | /* |
1139 | * For MSI-X desc->irq is always equal to irq_data->irq. For | 1142 | * For MSI-X desc->irq is always equal to irq_data->irq. For |
@@ -1257,12 +1260,19 @@ struct irq_domain *pci_msi_create_irq_domain(struct device_node *node, | |||
1257 | struct msi_domain_info *info, | 1260 | struct msi_domain_info *info, |
1258 | struct irq_domain *parent) | 1261 | struct irq_domain *parent) |
1259 | { | 1262 | { |
1263 | struct irq_domain *domain; | ||
1264 | |||
1260 | if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS) | 1265 | if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS) |
1261 | pci_msi_domain_update_dom_ops(info); | 1266 | pci_msi_domain_update_dom_ops(info); |
1262 | if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) | 1267 | if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) |
1263 | pci_msi_domain_update_chip_ops(info); | 1268 | pci_msi_domain_update_chip_ops(info); |
1264 | 1269 | ||
1265 | return msi_create_irq_domain(node, info, parent); | 1270 | domain = msi_create_irq_domain(node, info, parent); |
1271 | if (!domain) | ||
1272 | return NULL; | ||
1273 | |||
1274 | domain->bus_token = DOMAIN_BUS_PCI_MSI; | ||
1275 | return domain; | ||
1266 | } | 1276 | } |
1267 | 1277 | ||
1268 | /** | 1278 | /** |
diff --git a/drivers/pci/of.c b/drivers/pci/of.c index f0929934bb7a..2e99a500cb83 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/irqdomain.h> | ||
12 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
13 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
14 | #include <linux/of.h> | 15 | #include <linux/of.h> |
@@ -59,3 +60,32 @@ struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus) | |||
59 | return of_node_get(bus->bridge->parent->of_node); | 60 | return of_node_get(bus->bridge->parent->of_node); |
60 | return NULL; | 61 | return NULL; |
61 | } | 62 | } |
63 | |||
64 | struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus) | ||
65 | { | ||
66 | #ifdef CONFIG_IRQ_DOMAIN | ||
67 | struct device_node *np; | ||
68 | struct irq_domain *d; | ||
69 | |||
70 | if (!bus->dev.of_node) | ||
71 | return NULL; | ||
72 | |||
73 | /* Start looking for a phandle to an MSI controller. */ | ||
74 | np = of_parse_phandle(bus->dev.of_node, "msi-parent", 0); | ||
75 | |||
76 | /* | ||
77 | * If we don't have an msi-parent property, look for a domain | ||
78 | * directly attached to the host bridge. | ||
79 | */ | ||
80 | if (!np) | ||
81 | np = bus->dev.of_node; | ||
82 | |||
83 | d = irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI); | ||
84 | if (d) | ||
85 | return d; | ||
86 | |||
87 | return irq_find_host(np); | ||
88 | #else | ||
89 | return NULL; | ||
90 | #endif | ||
91 | } | ||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 04cfc60f7860..8177f3b04491 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -661,6 +661,35 @@ static void pci_set_bus_speed(struct pci_bus *bus) | |||
661 | } | 661 | } |
662 | } | 662 | } |
663 | 663 | ||
664 | static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus) | ||
665 | { | ||
666 | struct irq_domain *d; | ||
667 | |||
668 | /* | ||
669 | * Any firmware interface that can resolve the msi_domain | ||
670 | * should be called from here. | ||
671 | */ | ||
672 | d = pci_host_bridge_of_msi_domain(bus); | ||
673 | |||
674 | return d; | ||
675 | } | ||
676 | |||
677 | static void pci_set_bus_msi_domain(struct pci_bus *bus) | ||
678 | { | ||
679 | struct irq_domain *d; | ||
680 | |||
681 | /* | ||
682 | * Either bus is the root, and we must obtain it from the | ||
683 | * firmware, or we inherit it from the bridge device. | ||
684 | */ | ||
685 | if (pci_is_root_bus(bus)) | ||
686 | d = pci_host_bridge_msi_domain(bus); | ||
687 | else | ||
688 | d = dev_get_msi_domain(&bus->self->dev); | ||
689 | |||
690 | dev_set_msi_domain(&bus->dev, d); | ||
691 | } | ||
692 | |||
664 | static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | 693 | static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, |
665 | struct pci_dev *bridge, int busnr) | 694 | struct pci_dev *bridge, int busnr) |
666 | { | 695 | { |
@@ -714,6 +743,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
714 | bridge->subordinate = child; | 743 | bridge->subordinate = child; |
715 | 744 | ||
716 | add_dev: | 745 | add_dev: |
746 | pci_set_bus_msi_domain(child); | ||
717 | ret = device_register(&child->dev); | 747 | ret = device_register(&child->dev); |
718 | WARN_ON(ret < 0); | 748 | WARN_ON(ret < 0); |
719 | 749 | ||
@@ -1594,6 +1624,17 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1594 | pci_enable_acs(dev); | 1624 | pci_enable_acs(dev); |
1595 | } | 1625 | } |
1596 | 1626 | ||
1627 | static void pci_set_msi_domain(struct pci_dev *dev) | ||
1628 | { | ||
1629 | /* | ||
1630 | * If no domain has been set through the pcibios_add_device | ||
1631 | * callback, inherit the default from the bus device. | ||
1632 | */ | ||
1633 | if (!dev_get_msi_domain(&dev->dev)) | ||
1634 | dev_set_msi_domain(&dev->dev, | ||
1635 | dev_get_msi_domain(&dev->bus->dev)); | ||
1636 | } | ||
1637 | |||
1597 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | 1638 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |
1598 | { | 1639 | { |
1599 | int ret; | 1640 | int ret; |
@@ -1635,6 +1676,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
1635 | ret = pcibios_add_device(dev); | 1676 | ret = pcibios_add_device(dev); |
1636 | WARN_ON(ret < 0); | 1677 | WARN_ON(ret < 0); |
1637 | 1678 | ||
1679 | /* Setup MSI irq domain */ | ||
1680 | pci_set_msi_domain(dev); | ||
1681 | |||
1638 | /* Notifier could use PCI capabilities */ | 1682 | /* Notifier could use PCI capabilities */ |
1639 | dev->match_driver = false; | 1683 | dev->match_driver = false; |
1640 | ret = device_add(&dev->dev); | 1684 | ret = device_add(&dev->dev); |
@@ -2008,6 +2052,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
2008 | b->bridge = get_device(&bridge->dev); | 2052 | b->bridge = get_device(&bridge->dev); |
2009 | device_enable_async_suspend(b->bridge); | 2053 | device_enable_async_suspend(b->bridge); |
2010 | pci_set_bus_of_node(b); | 2054 | pci_set_bus_of_node(b); |
2055 | pci_set_bus_msi_domain(b); | ||
2011 | 2056 | ||
2012 | if (!parent) | 2057 | if (!parent) |
2013 | set_dev_node(b->bridge, pcibus_to_node(b)); | 2058 | set_dev_node(b->bridge, pcibus_to_node(b)); |
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 8b7a900cd28b..c777b97207d5 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c | |||
@@ -265,7 +265,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev, | |||
265 | } | 265 | } |
266 | 266 | ||
267 | i = 0; | 267 | i = 0; |
268 | list_for_each_entry(entry, &dev->msi_list, list) { | 268 | for_each_pci_msi_entry(entry, dev) { |
269 | op.msix_entries[i].entry = entry->msi_attrib.entry_nr; | 269 | op.msix_entries[i].entry = entry->msi_attrib.entry_nr; |
270 | /* Vector is useless at this point. */ | 270 | /* Vector is useless at this point. */ |
271 | op.msix_entries[i].vector = -1; | 271 | op.msix_entries[i].vector = -1; |
diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index 46427b48e2f1..358df7510186 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c | |||
@@ -22,7 +22,7 @@ void _intc_enable(struct irq_data *data, unsigned long handle) | |||
22 | 22 | ||
23 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { | 23 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { |
24 | #ifdef CONFIG_SMP | 24 | #ifdef CONFIG_SMP |
25 | if (!cpumask_test_cpu(cpu, data->affinity)) | 25 | if (!cpumask_test_cpu(cpu, irq_data_get_affinity_mask(data))) |
26 | continue; | 26 | continue; |
27 | #endif | 27 | #endif |
28 | addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); | 28 | addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); |
@@ -50,7 +50,7 @@ static void intc_disable(struct irq_data *data) | |||
50 | 50 | ||
51 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { | 51 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { |
52 | #ifdef CONFIG_SMP | 52 | #ifdef CONFIG_SMP |
53 | if (!cpumask_test_cpu(cpu, data->affinity)) | 53 | if (!cpumask_test_cpu(cpu, irq_data_get_affinity_mask(data))) |
54 | continue; | 54 | continue; |
55 | #endif | 55 | #endif |
56 | addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); | 56 | addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); |
@@ -72,7 +72,7 @@ static int intc_set_affinity(struct irq_data *data, | |||
72 | if (!cpumask_intersects(cpumask, cpu_online_mask)) | 72 | if (!cpumask_intersects(cpumask, cpu_online_mask)) |
73 | return -1; | 73 | return -1; |
74 | 74 | ||
75 | cpumask_copy(data->affinity, cpumask); | 75 | cpumask_copy(irq_data_get_affinity_mask(data), cpumask); |
76 | 76 | ||
77 | return IRQ_SET_MASK_OK_NOCOPY; | 77 | return IRQ_SET_MASK_OK_NOCOPY; |
78 | } | 78 | } |
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 156b790072b4..043419dcee92 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c | |||
@@ -67,7 +67,7 @@ void intc_set_prio_level(unsigned int irq, unsigned int level) | |||
67 | 67 | ||
68 | static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc) | 68 | static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc) |
69 | { | 69 | { |
70 | generic_handle_irq((unsigned int)irq_get_handler_data(irq)); | 70 | generic_handle_irq((unsigned int)irq_desc_get_handler_data(desc)); |
71 | } | 71 | } |
72 | 72 | ||
73 | static void __init intc_register_irq(struct intc_desc *desc, | 73 | static void __init intc_register_irq(struct intc_desc *desc, |
diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c index f5f1b821241a..bafc51c6f0ba 100644 --- a/drivers/sh/intc/virq.c +++ b/drivers/sh/intc/virq.c | |||
@@ -83,12 +83,11 @@ EXPORT_SYMBOL_GPL(intc_irq_lookup); | |||
83 | 83 | ||
84 | static int add_virq_to_pirq(unsigned int irq, unsigned int virq) | 84 | static int add_virq_to_pirq(unsigned int irq, unsigned int virq) |
85 | { | 85 | { |
86 | struct intc_virq_list **last, *entry; | 86 | struct intc_virq_list *entry; |
87 | struct irq_data *data = irq_get_irq_data(irq); | 87 | struct intc_virq_list **last = NULL; |
88 | 88 | ||
89 | /* scan for duplicates */ | 89 | /* scan for duplicates */ |
90 | last = (struct intc_virq_list **)&data->handler_data; | 90 | for_each_virq(entry, irq_get_handler_data(irq)) { |
91 | for_each_virq(entry, data->handler_data) { | ||
92 | if (entry->irq == virq) | 91 | if (entry->irq == virq) |
93 | return 0; | 92 | return 0; |
94 | last = &entry->next; | 93 | last = &entry->next; |
@@ -102,14 +101,18 @@ static int add_virq_to_pirq(unsigned int irq, unsigned int virq) | |||
102 | 101 | ||
103 | entry->irq = virq; | 102 | entry->irq = virq; |
104 | 103 | ||
105 | *last = entry; | 104 | if (last) |
105 | *last = entry; | ||
106 | else | ||
107 | irq_set_handler_data(irq, entry); | ||
106 | 108 | ||
107 | return 0; | 109 | return 0; |
108 | } | 110 | } |
109 | 111 | ||
110 | static void intc_virq_handler(unsigned int irq, struct irq_desc *desc) | 112 | static void intc_virq_handler(unsigned int __irq, struct irq_desc *desc) |
111 | { | 113 | { |
112 | struct irq_data *data = irq_get_irq_data(irq); | 114 | unsigned int irq = irq_desc_get_irq(desc); |
115 | struct irq_data *data = irq_desc_get_irq_data(desc); | ||
113 | struct irq_chip *chip = irq_data_get_irq_chip(data); | 116 | struct irq_chip *chip = irq_data_get_irq_chip(data); |
114 | struct intc_virq_list *entry, *vlist = irq_data_get_irq_handler_data(data); | 117 | struct intc_virq_list *entry, *vlist = irq_data_get_irq_handler_data(data); |
115 | struct intc_desc_int *d = get_intc_desc(irq); | 118 | struct intc_desc_int *d = get_intc_desc(irq); |
@@ -118,12 +121,14 @@ static void intc_virq_handler(unsigned int irq, struct irq_desc *desc) | |||
118 | 121 | ||
119 | for_each_virq(entry, vlist) { | 122 | for_each_virq(entry, vlist) { |
120 | unsigned long addr, handle; | 123 | unsigned long addr, handle; |
124 | struct irq_desc *vdesc = irq_to_desc(entry->irq); | ||
121 | 125 | ||
122 | handle = (unsigned long)irq_get_handler_data(entry->irq); | 126 | if (vdesc) { |
123 | addr = INTC_REG(d, _INTC_ADDR_E(handle), 0); | 127 | handle = (unsigned long)irq_desc_get_handler_data(vdesc); |
124 | 128 | addr = INTC_REG(d, _INTC_ADDR_E(handle), 0); | |
125 | if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0)) | 129 | if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0)) |
126 | generic_handle_irq(entry->irq); | 130 | generic_handle_irq_desc(entry->irq, vdesc); |
131 | } | ||
127 | } | 132 | } |
128 | 133 | ||
129 | chip->irq_unmask(data); | 134 | chip->irq_unmask(data); |
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index a4d8c043a710..bdfb3c84c3cb 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c | |||
@@ -453,8 +453,8 @@ static void periph_interrupt(struct spmi_pmic_arb_dev *pa, u8 apid) | |||
453 | 453 | ||
454 | static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc) | 454 | static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc) |
455 | { | 455 | { |
456 | struct spmi_pmic_arb_dev *pa = irq_get_handler_data(irq); | 456 | struct spmi_pmic_arb_dev *pa = irq_desc_get_handler_data(desc); |
457 | struct irq_chip *chip = irq_get_chip(irq); | 457 | struct irq_chip *chip = irq_desc_get_chip(desc); |
458 | void __iomem *intr = pa->intr; | 458 | void __iomem *intr = pa->intr; |
459 | int first = pa->min_apid >> 5; | 459 | int first = pa->min_apid >> 5; |
460 | int last = pa->max_apid >> 5; | 460 | int last = pa->max_apid >> 5; |
@@ -945,8 +945,7 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) | |||
945 | goto err_put_ctrl; | 945 | goto err_put_ctrl; |
946 | } | 946 | } |
947 | 947 | ||
948 | irq_set_handler_data(pa->irq, pa); | 948 | irq_set_chained_handler_and_data(pa->irq, pmic_arb_chained_irq, pa); |
949 | irq_set_chained_handler(pa->irq, pmic_arb_chained_irq); | ||
950 | 949 | ||
951 | err = spmi_controller_add(ctrl); | 950 | err = spmi_controller_add(ctrl); |
952 | if (err) | 951 | if (err) |
@@ -955,8 +954,7 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) | |||
955 | return 0; | 954 | return 0; |
956 | 955 | ||
957 | err_domain_remove: | 956 | err_domain_remove: |
958 | irq_set_chained_handler(pa->irq, NULL); | 957 | irq_set_chained_handler_and_data(pa->irq, NULL, NULL); |
959 | irq_set_handler_data(pa->irq, NULL); | ||
960 | irq_domain_remove(pa->domain); | 958 | irq_domain_remove(pa->domain); |
961 | err_put_ctrl: | 959 | err_put_ctrl: |
962 | spmi_controller_put(ctrl); | 960 | spmi_controller_put(ctrl); |
@@ -968,8 +966,7 @@ static int spmi_pmic_arb_remove(struct platform_device *pdev) | |||
968 | struct spmi_controller *ctrl = platform_get_drvdata(pdev); | 966 | struct spmi_controller *ctrl = platform_get_drvdata(pdev); |
969 | struct spmi_pmic_arb_dev *pa = spmi_controller_get_drvdata(ctrl); | 967 | struct spmi_pmic_arb_dev *pa = spmi_controller_get_drvdata(ctrl); |
970 | spmi_controller_remove(ctrl); | 968 | spmi_controller_remove(ctrl); |
971 | irq_set_chained_handler(pa->irq, NULL); | 969 | irq_set_chained_handler_and_data(pa->irq, NULL, NULL); |
972 | irq_set_handler_data(pa->irq, NULL); | ||
973 | irq_domain_remove(pa->domain); | 970 | irq_domain_remove(pa->domain); |
974 | spmi_controller_put(ctrl); | 971 | spmi_controller_put(ctrl); |
975 | return 0; | 972 | return 0; |
diff --git a/include/linux/device.h b/include/linux/device.h index 1225f98e9240..49fdcc4b8adf 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -714,6 +714,8 @@ struct device_dma_parameters { | |||
714 | * along with subsystem-level and driver-level callbacks. | 714 | * along with subsystem-level and driver-level callbacks. |
715 | * @pins: For device pin management. | 715 | * @pins: For device pin management. |
716 | * See Documentation/pinctrl.txt for details. | 716 | * See Documentation/pinctrl.txt for details. |
717 | * @msi_list: Hosts MSI descriptors | ||
718 | * @msi_domain: The generic MSI domain this device is using. | ||
717 | * @numa_node: NUMA node this device is close to. | 719 | * @numa_node: NUMA node this device is close to. |
718 | * @dma_mask: Dma mask (if dma'ble device). | 720 | * @dma_mask: Dma mask (if dma'ble device). |
719 | * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all | 721 | * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all |
@@ -774,9 +776,15 @@ struct device { | |||
774 | struct dev_pm_info power; | 776 | struct dev_pm_info power; |
775 | struct dev_pm_domain *pm_domain; | 777 | struct dev_pm_domain *pm_domain; |
776 | 778 | ||
779 | #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN | ||
780 | struct irq_domain *msi_domain; | ||
781 | #endif | ||
777 | #ifdef CONFIG_PINCTRL | 782 | #ifdef CONFIG_PINCTRL |
778 | struct dev_pin_info *pins; | 783 | struct dev_pin_info *pins; |
779 | #endif | 784 | #endif |
785 | #ifdef CONFIG_GENERIC_MSI_IRQ | ||
786 | struct list_head msi_list; | ||
787 | #endif | ||
780 | 788 | ||
781 | #ifdef CONFIG_NUMA | 789 | #ifdef CONFIG_NUMA |
782 | int numa_node; /* NUMA node this device is close to */ | 790 | int numa_node; /* NUMA node this device is close to */ |
@@ -861,6 +869,22 @@ static inline void set_dev_node(struct device *dev, int node) | |||
861 | } | 869 | } |
862 | #endif | 870 | #endif |
863 | 871 | ||
872 | static inline struct irq_domain *dev_get_msi_domain(const struct device *dev) | ||
873 | { | ||
874 | #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN | ||
875 | return dev->msi_domain; | ||
876 | #else | ||
877 | return NULL; | ||
878 | #endif | ||
879 | } | ||
880 | |||
881 | static inline void dev_set_msi_domain(struct device *dev, struct irq_domain *d) | ||
882 | { | ||
883 | #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN | ||
884 | dev->msi_domain = d; | ||
885 | #endif | ||
886 | } | ||
887 | |||
864 | static inline void *dev_get_drvdata(const struct device *dev) | 888 | static inline void *dev_get_drvdata(const struct device *dev) |
865 | { | 889 | { |
866 | return dev->driver_data; | 890 | return dev->driver_data; |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 51744bcf74ee..6f8b34066442 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -324,8 +324,10 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) | |||
324 | * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips | 324 | * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips |
325 | * @irq_cpu_online: configure an interrupt source for a secondary CPU | 325 | * @irq_cpu_online: configure an interrupt source for a secondary CPU |
326 | * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU | 326 | * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU |
327 | * @irq_suspend: function called from core code on suspend once per chip | 327 | * @irq_suspend: function called from core code on suspend once per |
328 | * @irq_resume: function called from core code on resume once per chip | 328 | * chip, when one or more interrupts are installed |
329 | * @irq_resume: function called from core code on resume once per chip, | ||
330 | * when one ore more interrupts are installed | ||
329 | * @irq_pm_shutdown: function called from core code on shutdown once per chip | 331 | * @irq_pm_shutdown: function called from core code on shutdown once per chip |
330 | * @irq_calc_mask: Optional function to set irq_data.mask for special cases | 332 | * @irq_calc_mask: Optional function to set irq_data.mask for special cases |
331 | * @irq_print_chip: optional to print special chip info in show_interrupts | 333 | * @irq_print_chip: optional to print special chip info in show_interrupts |
@@ -488,8 +490,7 @@ extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type); | |||
488 | #endif | 490 | #endif |
489 | 491 | ||
490 | /* Handling of unhandled and spurious interrupts: */ | 492 | /* Handling of unhandled and spurious interrupts: */ |
491 | extern void note_interrupt(unsigned int irq, struct irq_desc *desc, | 493 | extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret); |
492 | irqreturn_t action_ret); | ||
493 | 494 | ||
494 | 495 | ||
495 | /* Enable/disable irq debugging output: */ | 496 | /* Enable/disable irq debugging output: */ |
@@ -640,7 +641,7 @@ static inline struct msi_desc *irq_get_msi_desc(unsigned int irq) | |||
640 | return d ? d->msi_desc : NULL; | 641 | return d ? d->msi_desc : NULL; |
641 | } | 642 | } |
642 | 643 | ||
643 | static inline struct msi_desc *irq_data_get_msi(struct irq_data *d) | 644 | static inline struct msi_desc *irq_data_get_msi_desc(struct irq_data *d) |
644 | { | 645 | { |
645 | return d->msi_desc; | 646 | return d->msi_desc; |
646 | } | 647 | } |
@@ -762,6 +763,12 @@ struct irq_chip_type { | |||
762 | * @reg_base: Register base address (virtual) | 763 | * @reg_base: Register base address (virtual) |
763 | * @reg_readl: Alternate I/O accessor (defaults to readl if NULL) | 764 | * @reg_readl: Alternate I/O accessor (defaults to readl if NULL) |
764 | * @reg_writel: Alternate I/O accessor (defaults to writel if NULL) | 765 | * @reg_writel: Alternate I/O accessor (defaults to writel if NULL) |
766 | * @suspend: Function called from core code on suspend once per | ||
767 | * chip; can be useful instead of irq_chip::suspend to | ||
768 | * handle chip details even when no interrupts are in use | ||
769 | * @resume: Function called from core code on resume once per chip; | ||
770 | * can be useful instead of irq_chip::suspend to handle | ||
771 | * chip details even when no interrupts are in use | ||
765 | * @irq_base: Interrupt base nr for this chip | 772 | * @irq_base: Interrupt base nr for this chip |
766 | * @irq_cnt: Number of interrupts handled by this chip | 773 | * @irq_cnt: Number of interrupts handled by this chip |
767 | * @mask_cache: Cached mask register shared between all chip types | 774 | * @mask_cache: Cached mask register shared between all chip types |
@@ -788,6 +795,8 @@ struct irq_chip_generic { | |||
788 | void __iomem *reg_base; | 795 | void __iomem *reg_base; |
789 | u32 (*reg_readl)(void __iomem *addr); | 796 | u32 (*reg_readl)(void __iomem *addr); |
790 | void (*reg_writel)(u32 val, void __iomem *addr); | 797 | void (*reg_writel)(u32 val, void __iomem *addr); |
798 | void (*suspend)(struct irq_chip_generic *gc); | ||
799 | void (*resume)(struct irq_chip_generic *gc); | ||
791 | unsigned int irq_base; | 800 | unsigned int irq_base; |
792 | unsigned int irq_cnt; | 801 | unsigned int irq_cnt; |
793 | u32 mask_cache; | 802 | u32 mask_cache; |
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index ffbc034c8810..bf982e021fbd 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h | |||
@@ -360,6 +360,7 @@ | |||
360 | #ifndef __ASSEMBLY__ | 360 | #ifndef __ASSEMBLY__ |
361 | 361 | ||
362 | #include <linux/stringify.h> | 362 | #include <linux/stringify.h> |
363 | #include <asm/msi.h> | ||
363 | 364 | ||
364 | /* | 365 | /* |
365 | * We need a value to serve as a irq-type for LPIs. Choose one that will | 366 | * We need a value to serve as a irq-type for LPIs. Choose one that will |
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 9de976b4f9a7..65da435d01c1 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h | |||
@@ -95,11 +95,10 @@ | |||
95 | 95 | ||
96 | struct device_node; | 96 | struct device_node; |
97 | 97 | ||
98 | void gic_set_irqchip_flags(unsigned long flags); | ||
99 | void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, | 98 | void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, |
100 | u32 offset, struct device_node *); | 99 | u32 offset, struct device_node *); |
101 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); | 100 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); |
102 | void gic_cpu_if_down(void); | 101 | int gic_cpu_if_down(unsigned int gic_nr); |
103 | 102 | ||
104 | static inline void gic_init(unsigned int nr, int start, | 103 | static inline void gic_init(unsigned int nr, int start, |
105 | void __iomem *dist , void __iomem *cpu) | 104 | void __iomem *dist , void __iomem *cpu) |
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 744ac0ec98eb..d3ca79236fb0 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h | |||
@@ -45,6 +45,20 @@ struct irq_data; | |||
45 | /* Number of irqs reserved for a legacy isa controller */ | 45 | /* Number of irqs reserved for a legacy isa controller */ |
46 | #define NUM_ISA_INTERRUPTS 16 | 46 | #define NUM_ISA_INTERRUPTS 16 |
47 | 47 | ||
48 | /* | ||
49 | * Should several domains have the same device node, but serve | ||
50 | * different purposes (for example one domain is for PCI/MSI, and the | ||
51 | * other for wired IRQs), they can be distinguished using a | ||
52 | * bus-specific token. Most domains are expected to only carry | ||
53 | * DOMAIN_BUS_ANY. | ||
54 | */ | ||
55 | enum irq_domain_bus_token { | ||
56 | DOMAIN_BUS_ANY = 0, | ||
57 | DOMAIN_BUS_PCI_MSI, | ||
58 | DOMAIN_BUS_PLATFORM_MSI, | ||
59 | DOMAIN_BUS_NEXUS, | ||
60 | }; | ||
61 | |||
48 | /** | 62 | /** |
49 | * struct irq_domain_ops - Methods for irq_domain objects | 63 | * struct irq_domain_ops - Methods for irq_domain objects |
50 | * @match: Match an interrupt controller device node to a host, returns | 64 | * @match: Match an interrupt controller device node to a host, returns |
@@ -61,7 +75,8 @@ struct irq_data; | |||
61 | * to setup the irq_desc when returning from map(). | 75 | * to setup the irq_desc when returning from map(). |
62 | */ | 76 | */ |
63 | struct irq_domain_ops { | 77 | struct irq_domain_ops { |
64 | int (*match)(struct irq_domain *d, struct device_node *node); | 78 | int (*match)(struct irq_domain *d, struct device_node *node, |
79 | enum irq_domain_bus_token bus_token); | ||
65 | int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw); | 80 | int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw); |
66 | void (*unmap)(struct irq_domain *d, unsigned int virq); | 81 | void (*unmap)(struct irq_domain *d, unsigned int virq); |
67 | int (*xlate)(struct irq_domain *d, struct device_node *node, | 82 | int (*xlate)(struct irq_domain *d, struct device_node *node, |
@@ -116,6 +131,7 @@ struct irq_domain { | |||
116 | 131 | ||
117 | /* Optional data */ | 132 | /* Optional data */ |
118 | struct device_node *of_node; | 133 | struct device_node *of_node; |
134 | enum irq_domain_bus_token bus_token; | ||
119 | struct irq_domain_chip_generic *gc; | 135 | struct irq_domain_chip_generic *gc; |
120 | #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY | 136 | #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY |
121 | struct irq_domain *parent; | 137 | struct irq_domain *parent; |
@@ -161,9 +177,15 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, | |||
161 | irq_hw_number_t first_hwirq, | 177 | irq_hw_number_t first_hwirq, |
162 | const struct irq_domain_ops *ops, | 178 | const struct irq_domain_ops *ops, |
163 | void *host_data); | 179 | void *host_data); |
164 | extern struct irq_domain *irq_find_host(struct device_node *node); | 180 | extern struct irq_domain *irq_find_matching_host(struct device_node *node, |
181 | enum irq_domain_bus_token bus_token); | ||
165 | extern void irq_set_default_host(struct irq_domain *host); | 182 | extern void irq_set_default_host(struct irq_domain *host); |
166 | 183 | ||
184 | static inline struct irq_domain *irq_find_host(struct device_node *node) | ||
185 | { | ||
186 | return irq_find_matching_host(node, DOMAIN_BUS_ANY); | ||
187 | } | ||
188 | |||
167 | /** | 189 | /** |
168 | * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain. | 190 | * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain. |
169 | * @of_node: pointer to interrupt controller's device tree node. | 191 | * @of_node: pointer to interrupt controller's device tree node. |
diff --git a/include/linux/msi.h b/include/linux/msi.h index 8ac4a68ffae2..ad939d0ba816 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h | |||
@@ -14,38 +14,85 @@ extern int pci_msi_ignore_mask; | |||
14 | /* Helper functions */ | 14 | /* Helper functions */ |
15 | struct irq_data; | 15 | struct irq_data; |
16 | struct msi_desc; | 16 | struct msi_desc; |
17 | struct pci_dev; | ||
18 | struct platform_msi_priv_data; | ||
17 | void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg); | 19 | void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg); |
18 | void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); | 20 | void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); |
19 | 21 | ||
22 | typedef void (*irq_write_msi_msg_t)(struct msi_desc *desc, | ||
23 | struct msi_msg *msg); | ||
24 | |||
25 | /** | ||
26 | * platform_msi_desc - Platform device specific msi descriptor data | ||
27 | * @msi_priv_data: Pointer to platform private data | ||
28 | * @msi_index: The index of the MSI descriptor for multi MSI | ||
29 | */ | ||
30 | struct platform_msi_desc { | ||
31 | struct platform_msi_priv_data *msi_priv_data; | ||
32 | u16 msi_index; | ||
33 | }; | ||
34 | |||
35 | /** | ||
36 | * struct msi_desc - Descriptor structure for MSI based interrupts | ||
37 | * @list: List head for management | ||
38 | * @irq: The base interrupt number | ||
39 | * @nvec_used: The number of vectors used | ||
40 | * @dev: Pointer to the device which uses this descriptor | ||
41 | * @msg: The last set MSI message cached for reuse | ||
42 | * | ||
43 | * @masked: [PCI MSI/X] Mask bits | ||
44 | * @is_msix: [PCI MSI/X] True if MSI-X | ||
45 | * @multiple: [PCI MSI/X] log2 num of messages allocated | ||
46 | * @multi_cap: [PCI MSI/X] log2 num of messages supported | ||
47 | * @maskbit: [PCI MSI/X] Mask-Pending bit supported? | ||
48 | * @is_64: [PCI MSI/X] Address size: 0=32bit 1=64bit | ||
49 | * @entry_nr: [PCI MSI/X] Entry which is described by this descriptor | ||
50 | * @default_irq:[PCI MSI/X] The default pre-assigned non-MSI irq | ||
51 | * @mask_pos: [PCI MSI] Mask register position | ||
52 | * @mask_base: [PCI MSI-X] Mask register base address | ||
53 | * @platform: [platform] Platform device specific msi descriptor data | ||
54 | */ | ||
20 | struct msi_desc { | 55 | struct msi_desc { |
21 | struct { | 56 | /* Shared device/bus type independent data */ |
22 | __u8 is_msix : 1; | 57 | struct list_head list; |
23 | __u8 multiple: 3; /* log2 num of messages allocated */ | 58 | unsigned int irq; |
24 | __u8 multi_cap : 3; /* log2 num of messages supported */ | 59 | unsigned int nvec_used; |
25 | __u8 maskbit : 1; /* mask-pending bit supported ? */ | 60 | struct device *dev; |
26 | __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ | 61 | struct msi_msg msg; |
27 | __u16 entry_nr; /* specific enabled entry */ | ||
28 | unsigned default_irq; /* default pre-assigned irq */ | ||
29 | } msi_attrib; | ||
30 | |||
31 | u32 masked; /* mask bits */ | ||
32 | unsigned int irq; | ||
33 | unsigned int nvec_used; /* number of messages */ | ||
34 | struct list_head list; | ||
35 | 62 | ||
36 | union { | 63 | union { |
37 | void __iomem *mask_base; | 64 | /* PCI MSI/X specific data */ |
38 | u8 mask_pos; | 65 | struct { |
39 | }; | 66 | u32 masked; |
40 | struct pci_dev *dev; | 67 | struct { |
68 | __u8 is_msix : 1; | ||
69 | __u8 multiple : 3; | ||
70 | __u8 multi_cap : 3; | ||
71 | __u8 maskbit : 1; | ||
72 | __u8 is_64 : 1; | ||
73 | __u16 entry_nr; | ||
74 | unsigned default_irq; | ||
75 | } msi_attrib; | ||
76 | union { | ||
77 | u8 mask_pos; | ||
78 | void __iomem *mask_base; | ||
79 | }; | ||
80 | }; | ||
41 | 81 | ||
42 | /* Last set MSI message */ | 82 | /* |
43 | struct msi_msg msg; | 83 | * Non PCI variants add their data structure here. New |
84 | * entries need to use a named structure. We want | ||
85 | * proper name spaces for this. The PCI part is | ||
86 | * anonymous for now as it would require an immediate | ||
87 | * tree wide cleanup. | ||
88 | */ | ||
89 | struct platform_msi_desc platform; | ||
90 | }; | ||
44 | }; | 91 | }; |
45 | 92 | ||
46 | /* Helpers to hide struct msi_desc implementation details */ | 93 | /* Helpers to hide struct msi_desc implementation details */ |
47 | #define msi_desc_to_dev(desc) (&(desc)->dev.dev) | 94 | #define msi_desc_to_dev(desc) ((desc)->dev) |
48 | #define dev_to_msi_list(dev) (&to_pci_dev((dev))->msi_list) | 95 | #define dev_to_msi_list(dev) (&(dev)->msi_list) |
49 | #define first_msi_entry(dev) \ | 96 | #define first_msi_entry(dev) \ |
50 | list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list) | 97 | list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list) |
51 | #define for_each_msi_entry(desc, dev) \ | 98 | #define for_each_msi_entry(desc, dev) \ |
@@ -56,12 +103,17 @@ struct msi_desc { | |||
56 | #define for_each_pci_msi_entry(desc, pdev) \ | 103 | #define for_each_pci_msi_entry(desc, pdev) \ |
57 | for_each_msi_entry((desc), &(pdev)->dev) | 104 | for_each_msi_entry((desc), &(pdev)->dev) |
58 | 105 | ||
59 | static inline struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc) | 106 | struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc); |
107 | void *msi_desc_to_pci_sysdata(struct msi_desc *desc); | ||
108 | #else /* CONFIG_PCI_MSI */ | ||
109 | static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc) | ||
60 | { | 110 | { |
61 | return desc->dev; | 111 | return NULL; |
62 | } | 112 | } |
63 | #endif /* CONFIG_PCI_MSI */ | 113 | #endif /* CONFIG_PCI_MSI */ |
64 | 114 | ||
115 | struct msi_desc *alloc_msi_entry(struct device *dev); | ||
116 | void free_msi_entry(struct msi_desc *entry); | ||
65 | void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg); | 117 | void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg); |
66 | void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg); | 118 | void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg); |
67 | void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg); | 119 | void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg); |
@@ -108,9 +160,6 @@ struct msi_controller { | |||
108 | struct device *dev; | 160 | struct device *dev; |
109 | struct device_node *of_node; | 161 | struct device_node *of_node; |
110 | struct list_head list; | 162 | struct list_head list; |
111 | #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN | ||
112 | struct irq_domain *domain; | ||
113 | #endif | ||
114 | 163 | ||
115 | int (*setup_irq)(struct msi_controller *chip, struct pci_dev *dev, | 164 | int (*setup_irq)(struct msi_controller *chip, struct pci_dev *dev, |
116 | struct msi_desc *desc); | 165 | struct msi_desc *desc); |
@@ -221,6 +270,12 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, | |||
221 | void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev); | 270 | void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev); |
222 | struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain); | 271 | struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain); |
223 | 272 | ||
273 | struct irq_domain *platform_msi_create_irq_domain(struct device_node *np, | ||
274 | struct msi_domain_info *info, | ||
275 | struct irq_domain *parent); | ||
276 | int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec, | ||
277 | irq_write_msi_msg_t write_msi_msg); | ||
278 | void platform_msi_domain_free_irqs(struct device *dev); | ||
224 | #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */ | 279 | #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */ |
225 | 280 | ||
226 | #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN | 281 | #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN |
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index d884929a7747..4bcbd586a672 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h | |||
@@ -74,6 +74,7 @@ static inline int of_irq_to_resource_table(struct device_node *dev, | |||
74 | */ | 74 | */ |
75 | extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); | 75 | extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); |
76 | extern struct device_node *of_irq_find_parent(struct device_node *child); | 76 | extern struct device_node *of_irq_find_parent(struct device_node *child); |
77 | extern void of_msi_configure(struct device *dev, struct device_node *np); | ||
77 | 78 | ||
78 | #else /* !CONFIG_OF */ | 79 | #else /* !CONFIG_OF */ |
79 | static inline unsigned int irq_of_parse_and_map(struct device_node *dev, | 80 | static inline unsigned int irq_of_parse_and_map(struct device_node *dev, |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 4fee9cd7a7df..1a64733c48c7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -369,7 +369,6 @@ struct pci_dev { | |||
369 | struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ | 369 | struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ |
370 | struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */ | 370 | struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */ |
371 | #ifdef CONFIG_PCI_MSI | 371 | #ifdef CONFIG_PCI_MSI |
372 | struct list_head msi_list; | ||
373 | const struct attribute_group **msi_irq_groups; | 372 | const struct attribute_group **msi_irq_groups; |
374 | #endif | 373 | #endif |
375 | struct pci_vpd *vpd; | 374 | struct pci_vpd *vpd; |
@@ -1892,10 +1891,12 @@ int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off, | |||
1892 | /* PCI <-> OF binding helpers */ | 1891 | /* PCI <-> OF binding helpers */ |
1893 | #ifdef CONFIG_OF | 1892 | #ifdef CONFIG_OF |
1894 | struct device_node; | 1893 | struct device_node; |
1894 | struct irq_domain; | ||
1895 | void pci_set_of_node(struct pci_dev *dev); | 1895 | void pci_set_of_node(struct pci_dev *dev); |
1896 | void pci_release_of_node(struct pci_dev *dev); | 1896 | void pci_release_of_node(struct pci_dev *dev); |
1897 | void pci_set_bus_of_node(struct pci_bus *bus); | 1897 | void pci_set_bus_of_node(struct pci_bus *bus); |
1898 | void pci_release_bus_of_node(struct pci_bus *bus); | 1898 | void pci_release_bus_of_node(struct pci_bus *bus); |
1899 | struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus); | ||
1899 | 1900 | ||
1900 | /* Arch may override this (weak) */ | 1901 | /* Arch may override this (weak) */ |
1901 | struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus); | 1902 | struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus); |
@@ -1918,6 +1919,8 @@ static inline void pci_set_bus_of_node(struct pci_bus *bus) { } | |||
1918 | static inline void pci_release_bus_of_node(struct pci_bus *bus) { } | 1919 | static inline void pci_release_bus_of_node(struct pci_bus *bus) { } |
1919 | static inline struct device_node * | 1920 | static inline struct device_node * |
1920 | pci_device_to_OF_node(const struct pci_dev *pdev) { return NULL; } | 1921 | pci_device_to_OF_node(const struct pci_dev *pdev) { return NULL; } |
1922 | static inline struct irq_domain * | ||
1923 | pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; } | ||
1921 | #endif /* CONFIG_OF */ | 1924 | #endif /* CONFIG_OF */ |
1922 | 1925 | ||
1923 | #ifdef CONFIG_EEH | 1926 | #ifdef CONFIG_EEH |
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index ae216824e8ca..6e40a9539763 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -63,7 +63,7 @@ int irq_set_irq_type(unsigned int irq, unsigned int type) | |||
63 | return -EINVAL; | 63 | return -EINVAL; |
64 | 64 | ||
65 | type &= IRQ_TYPE_SENSE_MASK; | 65 | type &= IRQ_TYPE_SENSE_MASK; |
66 | ret = __irq_set_trigger(desc, irq, type); | 66 | ret = __irq_set_trigger(desc, type); |
67 | irq_put_desc_busunlock(desc, flags); | 67 | irq_put_desc_busunlock(desc, flags); |
68 | return ret; | 68 | return ret; |
69 | } | 69 | } |
@@ -187,7 +187,7 @@ int irq_startup(struct irq_desc *desc, bool resend) | |||
187 | irq_enable(desc); | 187 | irq_enable(desc); |
188 | } | 188 | } |
189 | if (resend) | 189 | if (resend) |
190 | check_irq_resend(desc, desc->irq_data.irq); | 190 | check_irq_resend(desc); |
191 | return ret; | 191 | return ret; |
192 | } | 192 | } |
193 | 193 | ||
@@ -315,7 +315,7 @@ void handle_nested_irq(unsigned int irq) | |||
315 | raw_spin_lock_irq(&desc->lock); | 315 | raw_spin_lock_irq(&desc->lock); |
316 | 316 | ||
317 | desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); | 317 | desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); |
318 | kstat_incr_irqs_this_cpu(irq, desc); | 318 | kstat_incr_irqs_this_cpu(desc); |
319 | 319 | ||
320 | action = desc->action; | 320 | action = desc->action; |
321 | if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) { | 321 | if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) { |
@@ -328,7 +328,7 @@ void handle_nested_irq(unsigned int irq) | |||
328 | 328 | ||
329 | action_ret = action->thread_fn(action->irq, action->dev_id); | 329 | action_ret = action->thread_fn(action->irq, action->dev_id); |
330 | if (!noirqdebug) | 330 | if (!noirqdebug) |
331 | note_interrupt(irq, desc, action_ret); | 331 | note_interrupt(desc, action_ret); |
332 | 332 | ||
333 | raw_spin_lock_irq(&desc->lock); | 333 | raw_spin_lock_irq(&desc->lock); |
334 | irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS); | 334 | irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS); |
@@ -391,7 +391,7 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc) | |||
391 | goto out_unlock; | 391 | goto out_unlock; |
392 | 392 | ||
393 | desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); | 393 | desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); |
394 | kstat_incr_irqs_this_cpu(irq, desc); | 394 | kstat_incr_irqs_this_cpu(desc); |
395 | 395 | ||
396 | if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { | 396 | if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { |
397 | desc->istate |= IRQS_PENDING; | 397 | desc->istate |= IRQS_PENDING; |
@@ -443,7 +443,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) | |||
443 | goto out_unlock; | 443 | goto out_unlock; |
444 | 444 | ||
445 | desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); | 445 | desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); |
446 | kstat_incr_irqs_this_cpu(irq, desc); | 446 | kstat_incr_irqs_this_cpu(desc); |
447 | 447 | ||
448 | /* | 448 | /* |
449 | * If its disabled or no action available | 449 | * If its disabled or no action available |
@@ -515,7 +515,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) | |||
515 | goto out; | 515 | goto out; |
516 | 516 | ||
517 | desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); | 517 | desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); |
518 | kstat_incr_irqs_this_cpu(irq, desc); | 518 | kstat_incr_irqs_this_cpu(desc); |
519 | 519 | ||
520 | /* | 520 | /* |
521 | * If its disabled or no action available | 521 | * If its disabled or no action available |
@@ -583,7 +583,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) | |||
583 | goto out_unlock; | 583 | goto out_unlock; |
584 | } | 584 | } |
585 | 585 | ||
586 | kstat_incr_irqs_this_cpu(irq, desc); | 586 | kstat_incr_irqs_this_cpu(desc); |
587 | 587 | ||
588 | /* Start handling the irq */ | 588 | /* Start handling the irq */ |
589 | desc->irq_data.chip->irq_ack(&desc->irq_data); | 589 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
@@ -646,7 +646,7 @@ void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc) | |||
646 | goto out_eoi; | 646 | goto out_eoi; |
647 | } | 647 | } |
648 | 648 | ||
649 | kstat_incr_irqs_this_cpu(irq, desc); | 649 | kstat_incr_irqs_this_cpu(desc); |
650 | 650 | ||
651 | do { | 651 | do { |
652 | if (unlikely(!desc->action)) | 652 | if (unlikely(!desc->action)) |
@@ -675,7 +675,7 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc) | |||
675 | { | 675 | { |
676 | struct irq_chip *chip = irq_desc_get_chip(desc); | 676 | struct irq_chip *chip = irq_desc_get_chip(desc); |
677 | 677 | ||
678 | kstat_incr_irqs_this_cpu(irq, desc); | 678 | kstat_incr_irqs_this_cpu(desc); |
679 | 679 | ||
680 | if (chip->irq_ack) | 680 | if (chip->irq_ack) |
681 | chip->irq_ack(&desc->irq_data); | 681 | chip->irq_ack(&desc->irq_data); |
@@ -705,7 +705,7 @@ void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc) | |||
705 | void *dev_id = raw_cpu_ptr(action->percpu_dev_id); | 705 | void *dev_id = raw_cpu_ptr(action->percpu_dev_id); |
706 | irqreturn_t res; | 706 | irqreturn_t res; |
707 | 707 | ||
708 | kstat_incr_irqs_this_cpu(irq, desc); | 708 | kstat_incr_irqs_this_cpu(desc); |
709 | 709 | ||
710 | if (chip->irq_ack) | 710 | if (chip->irq_ack) |
711 | chip->irq_ack(&desc->irq_data); | 711 | chip->irq_ack(&desc->irq_data); |
@@ -1020,7 +1020,7 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data) | |||
1020 | /** | 1020 | /** |
1021 | * irq_chip_set_vcpu_affinity_parent - Set vcpu affinity on the parent interrupt | 1021 | * irq_chip_set_vcpu_affinity_parent - Set vcpu affinity on the parent interrupt |
1022 | * @data: Pointer to interrupt specific data | 1022 | * @data: Pointer to interrupt specific data |
1023 | * @dest: The vcpu affinity information | 1023 | * @vcpu_info: The vcpu affinity information |
1024 | */ | 1024 | */ |
1025 | int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info) | 1025 | int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info) |
1026 | { | 1026 | { |
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c index 15b370daf234..abd286afbd27 100644 --- a/kernel/irq/generic-chip.c +++ b/kernel/irq/generic-chip.c | |||
@@ -553,6 +553,9 @@ static int irq_gc_suspend(void) | |||
553 | if (data) | 553 | if (data) |
554 | ct->chip.irq_suspend(data); | 554 | ct->chip.irq_suspend(data); |
555 | } | 555 | } |
556 | |||
557 | if (gc->suspend) | ||
558 | gc->suspend(gc); | ||
556 | } | 559 | } |
557 | return 0; | 560 | return 0; |
558 | } | 561 | } |
@@ -564,6 +567,9 @@ static void irq_gc_resume(void) | |||
564 | list_for_each_entry(gc, &gc_list, list) { | 567 | list_for_each_entry(gc, &gc_list, list) { |
565 | struct irq_chip_type *ct = gc->chip_types; | 568 | struct irq_chip_type *ct = gc->chip_types; |
566 | 569 | ||
570 | if (gc->resume) | ||
571 | gc->resume(gc); | ||
572 | |||
567 | if (ct->chip.irq_resume) { | 573 | if (ct->chip.irq_resume) { |
568 | struct irq_data *data = irq_gc_get_irq_data(gc); | 574 | struct irq_data *data = irq_gc_get_irq_data(gc); |
569 | 575 | ||
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 635480270858..b6eeea8a80c5 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -30,7 +30,7 @@ | |||
30 | void handle_bad_irq(unsigned int irq, struct irq_desc *desc) | 30 | void handle_bad_irq(unsigned int irq, struct irq_desc *desc) |
31 | { | 31 | { |
32 | print_irq_desc(irq, desc); | 32 | print_irq_desc(irq, desc); |
33 | kstat_incr_irqs_this_cpu(irq, desc); | 33 | kstat_incr_irqs_this_cpu(desc); |
34 | ack_bad_irq(irq); | 34 | ack_bad_irq(irq); |
35 | } | 35 | } |
36 | 36 | ||
@@ -176,7 +176,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) | |||
176 | add_interrupt_randomness(irq, flags); | 176 | add_interrupt_randomness(irq, flags); |
177 | 177 | ||
178 | if (!noirqdebug) | 178 | if (!noirqdebug) |
179 | note_interrupt(irq, desc, retval); | 179 | note_interrupt(desc, retval); |
180 | return retval; | 180 | return retval; |
181 | } | 181 | } |
182 | 182 | ||
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index 61008b8433ab..eee4b385cffb 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h | |||
@@ -59,10 +59,9 @@ enum { | |||
59 | #include "debug.h" | 59 | #include "debug.h" |
60 | #include "settings.h" | 60 | #include "settings.h" |
61 | 61 | ||
62 | extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | 62 | extern int __irq_set_trigger(struct irq_desc *desc, unsigned long flags); |
63 | unsigned long flags); | 63 | extern void __disable_irq(struct irq_desc *desc); |
64 | extern void __disable_irq(struct irq_desc *desc, unsigned int irq); | 64 | extern void __enable_irq(struct irq_desc *desc); |
65 | extern void __enable_irq(struct irq_desc *desc, unsigned int irq); | ||
66 | 65 | ||
67 | extern int irq_startup(struct irq_desc *desc, bool resend); | 66 | extern int irq_startup(struct irq_desc *desc, bool resend); |
68 | extern void irq_shutdown(struct irq_desc *desc); | 67 | extern void irq_shutdown(struct irq_desc *desc); |
@@ -86,7 +85,7 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *act | |||
86 | irqreturn_t handle_irq_event(struct irq_desc *desc); | 85 | irqreturn_t handle_irq_event(struct irq_desc *desc); |
87 | 86 | ||
88 | /* Resending of interrupts :*/ | 87 | /* Resending of interrupts :*/ |
89 | void check_irq_resend(struct irq_desc *desc, unsigned int irq); | 88 | void check_irq_resend(struct irq_desc *desc); |
90 | bool irq_wait_for_poll(struct irq_desc *desc); | 89 | bool irq_wait_for_poll(struct irq_desc *desc); |
91 | void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action); | 90 | void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action); |
92 | 91 | ||
@@ -187,7 +186,7 @@ static inline bool irqd_has_set(struct irq_data *d, unsigned int mask) | |||
187 | return __irqd_to_state(d) & mask; | 186 | return __irqd_to_state(d) & mask; |
188 | } | 187 | } |
189 | 188 | ||
190 | static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc) | 189 | static inline void kstat_incr_irqs_this_cpu(struct irq_desc *desc) |
191 | { | 190 | { |
192 | __this_cpu_inc(*desc->kstat_irqs); | 191 | __this_cpu_inc(*desc->kstat_irqs); |
193 | __this_cpu_inc(kstat.irqs_sum); | 192 | __this_cpu_inc(kstat.irqs_sum); |
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 4afc457613dd..0a2a4b697bcb 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c | |||
@@ -582,7 +582,7 @@ int irq_set_percpu_devid(unsigned int irq) | |||
582 | 582 | ||
583 | void kstat_incr_irq_this_cpu(unsigned int irq) | 583 | void kstat_incr_irq_this_cpu(unsigned int irq) |
584 | { | 584 | { |
585 | kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); | 585 | kstat_incr_irqs_this_cpu(irq_to_desc(irq)); |
586 | } | 586 | } |
587 | 587 | ||
588 | /** | 588 | /** |
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 8c3577fef78c..79baaf8a7813 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c | |||
@@ -187,10 +187,12 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, | |||
187 | EXPORT_SYMBOL_GPL(irq_domain_add_legacy); | 187 | EXPORT_SYMBOL_GPL(irq_domain_add_legacy); |
188 | 188 | ||
189 | /** | 189 | /** |
190 | * irq_find_host() - Locates a domain for a given device node | 190 | * irq_find_matching_host() - Locates a domain for a given device node |
191 | * @node: device-tree node of the interrupt controller | 191 | * @node: device-tree node of the interrupt controller |
192 | * @bus_token: domain-specific data | ||
192 | */ | 193 | */ |
193 | struct irq_domain *irq_find_host(struct device_node *node) | 194 | struct irq_domain *irq_find_matching_host(struct device_node *node, |
195 | enum irq_domain_bus_token bus_token) | ||
194 | { | 196 | { |
195 | struct irq_domain *h, *found = NULL; | 197 | struct irq_domain *h, *found = NULL; |
196 | int rc; | 198 | int rc; |
@@ -199,13 +201,19 @@ struct irq_domain *irq_find_host(struct device_node *node) | |||
199 | * it might potentially be set to match all interrupts in | 201 | * it might potentially be set to match all interrupts in |
200 | * the absence of a device node. This isn't a problem so far | 202 | * the absence of a device node. This isn't a problem so far |
201 | * yet though... | 203 | * yet though... |
204 | * | ||
205 | * bus_token == DOMAIN_BUS_ANY matches any domain, any other | ||
206 | * values must generate an exact match for the domain to be | ||
207 | * selected. | ||
202 | */ | 208 | */ |
203 | mutex_lock(&irq_domain_mutex); | 209 | mutex_lock(&irq_domain_mutex); |
204 | list_for_each_entry(h, &irq_domain_list, link) { | 210 | list_for_each_entry(h, &irq_domain_list, link) { |
205 | if (h->ops->match) | 211 | if (h->ops->match) |
206 | rc = h->ops->match(h, node); | 212 | rc = h->ops->match(h, node, bus_token); |
207 | else | 213 | else |
208 | rc = (h->of_node != NULL) && (h->of_node == node); | 214 | rc = ((h->of_node != NULL) && (h->of_node == node) && |
215 | ((bus_token == DOMAIN_BUS_ANY) || | ||
216 | (h->bus_token == bus_token))); | ||
209 | 217 | ||
210 | if (rc) { | 218 | if (rc) { |
211 | found = h; | 219 | found = h; |
@@ -215,7 +223,7 @@ struct irq_domain *irq_find_host(struct device_node *node) | |||
215 | mutex_unlock(&irq_domain_mutex); | 223 | mutex_unlock(&irq_domain_mutex); |
216 | return found; | 224 | return found; |
217 | } | 225 | } |
218 | EXPORT_SYMBOL_GPL(irq_find_host); | 226 | EXPORT_SYMBOL_GPL(irq_find_matching_host); |
219 | 227 | ||
220 | /** | 228 | /** |
221 | * irq_set_default_host() - Set a "default" irq domain | 229 | * irq_set_default_host() - Set a "default" irq domain |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index f9744853b656..ad1b064f94fe 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -115,6 +115,14 @@ EXPORT_SYMBOL(synchronize_irq); | |||
115 | #ifdef CONFIG_SMP | 115 | #ifdef CONFIG_SMP |
116 | cpumask_var_t irq_default_affinity; | 116 | cpumask_var_t irq_default_affinity; |
117 | 117 | ||
118 | static int __irq_can_set_affinity(struct irq_desc *desc) | ||
119 | { | ||
120 | if (!desc || !irqd_can_balance(&desc->irq_data) || | ||
121 | !desc->irq_data.chip || !desc->irq_data.chip->irq_set_affinity) | ||
122 | return 0; | ||
123 | return 1; | ||
124 | } | ||
125 | |||
118 | /** | 126 | /** |
119 | * irq_can_set_affinity - Check if the affinity of a given irq can be set | 127 | * irq_can_set_affinity - Check if the affinity of a given irq can be set |
120 | * @irq: Interrupt to check | 128 | * @irq: Interrupt to check |
@@ -122,13 +130,7 @@ cpumask_var_t irq_default_affinity; | |||
122 | */ | 130 | */ |
123 | int irq_can_set_affinity(unsigned int irq) | 131 | int irq_can_set_affinity(unsigned int irq) |
124 | { | 132 | { |
125 | struct irq_desc *desc = irq_to_desc(irq); | 133 | return __irq_can_set_affinity(irq_to_desc(irq)); |
126 | |||
127 | if (!desc || !irqd_can_balance(&desc->irq_data) || | ||
128 | !desc->irq_data.chip || !desc->irq_data.chip->irq_set_affinity) | ||
129 | return 0; | ||
130 | |||
131 | return 1; | ||
132 | } | 134 | } |
133 | 135 | ||
134 | /** | 136 | /** |
@@ -359,14 +361,13 @@ EXPORT_SYMBOL_GPL(irq_set_affinity_notifier); | |||
359 | /* | 361 | /* |
360 | * Generic version of the affinity autoselector. | 362 | * Generic version of the affinity autoselector. |
361 | */ | 363 | */ |
362 | static int | 364 | static int setup_affinity(struct irq_desc *desc, struct cpumask *mask) |
363 | setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) | ||
364 | { | 365 | { |
365 | struct cpumask *set = irq_default_affinity; | 366 | struct cpumask *set = irq_default_affinity; |
366 | int node = irq_desc_get_node(desc); | 367 | int node = irq_desc_get_node(desc); |
367 | 368 | ||
368 | /* Excludes PER_CPU and NO_BALANCE interrupts */ | 369 | /* Excludes PER_CPU and NO_BALANCE interrupts */ |
369 | if (!irq_can_set_affinity(irq)) | 370 | if (!__irq_can_set_affinity(desc)) |
370 | return 0; | 371 | return 0; |
371 | 372 | ||
372 | /* | 373 | /* |
@@ -393,10 +394,10 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) | |||
393 | return 0; | 394 | return 0; |
394 | } | 395 | } |
395 | #else | 396 | #else |
396 | static inline int | 397 | /* Wrapper for ALPHA specific affinity selector magic */ |
397 | setup_affinity(unsigned int irq, struct irq_desc *d, struct cpumask *mask) | 398 | static inline int setup_affinity(struct irq_desc *d, struct cpumask *mask) |
398 | { | 399 | { |
399 | return irq_select_affinity(irq); | 400 | return irq_select_affinity(irq_desc_get_irq(d)); |
400 | } | 401 | } |
401 | #endif | 402 | #endif |
402 | 403 | ||
@@ -410,20 +411,20 @@ int irq_select_affinity_usr(unsigned int irq, struct cpumask *mask) | |||
410 | int ret; | 411 | int ret; |
411 | 412 | ||
412 | raw_spin_lock_irqsave(&desc->lock, flags); | 413 | raw_spin_lock_irqsave(&desc->lock, flags); |
413 | ret = setup_affinity(irq, desc, mask); | 414 | ret = setup_affinity(desc, mask); |
414 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 415 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
415 | return ret; | 416 | return ret; |
416 | } | 417 | } |
417 | 418 | ||
418 | #else | 419 | #else |
419 | static inline int | 420 | static inline int |
420 | setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) | 421 | setup_affinity(struct irq_desc *desc, struct cpumask *mask) |
421 | { | 422 | { |
422 | return 0; | 423 | return 0; |
423 | } | 424 | } |
424 | #endif | 425 | #endif |
425 | 426 | ||
426 | void __disable_irq(struct irq_desc *desc, unsigned int irq) | 427 | void __disable_irq(struct irq_desc *desc) |
427 | { | 428 | { |
428 | if (!desc->depth++) | 429 | if (!desc->depth++) |
429 | irq_disable(desc); | 430 | irq_disable(desc); |
@@ -436,7 +437,7 @@ static int __disable_irq_nosync(unsigned int irq) | |||
436 | 437 | ||
437 | if (!desc) | 438 | if (!desc) |
438 | return -EINVAL; | 439 | return -EINVAL; |
439 | __disable_irq(desc, irq); | 440 | __disable_irq(desc); |
440 | irq_put_desc_busunlock(desc, flags); | 441 | irq_put_desc_busunlock(desc, flags); |
441 | return 0; | 442 | return 0; |
442 | } | 443 | } |
@@ -503,12 +504,13 @@ bool disable_hardirq(unsigned int irq) | |||
503 | } | 504 | } |
504 | EXPORT_SYMBOL_GPL(disable_hardirq); | 505 | EXPORT_SYMBOL_GPL(disable_hardirq); |
505 | 506 | ||
506 | void __enable_irq(struct irq_desc *desc, unsigned int irq) | 507 | void __enable_irq(struct irq_desc *desc) |
507 | { | 508 | { |
508 | switch (desc->depth) { | 509 | switch (desc->depth) { |
509 | case 0: | 510 | case 0: |
510 | err_out: | 511 | err_out: |
511 | WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); | 512 | WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", |
513 | irq_desc_get_irq(desc)); | ||
512 | break; | 514 | break; |
513 | case 1: { | 515 | case 1: { |
514 | if (desc->istate & IRQS_SUSPENDED) | 516 | if (desc->istate & IRQS_SUSPENDED) |
@@ -516,7 +518,7 @@ void __enable_irq(struct irq_desc *desc, unsigned int irq) | |||
516 | /* Prevent probing on this irq: */ | 518 | /* Prevent probing on this irq: */ |
517 | irq_settings_set_noprobe(desc); | 519 | irq_settings_set_noprobe(desc); |
518 | irq_enable(desc); | 520 | irq_enable(desc); |
519 | check_irq_resend(desc, irq); | 521 | check_irq_resend(desc); |
520 | /* fall-through */ | 522 | /* fall-through */ |
521 | } | 523 | } |
522 | default: | 524 | default: |
@@ -546,7 +548,7 @@ void enable_irq(unsigned int irq) | |||
546 | KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq)) | 548 | KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq)) |
547 | goto out; | 549 | goto out; |
548 | 550 | ||
549 | __enable_irq(desc, irq); | 551 | __enable_irq(desc); |
550 | out: | 552 | out: |
551 | irq_put_desc_busunlock(desc, flags); | 553 | irq_put_desc_busunlock(desc, flags); |
552 | } | 554 | } |
@@ -637,8 +639,7 @@ int can_request_irq(unsigned int irq, unsigned long irqflags) | |||
637 | return canrequest; | 639 | return canrequest; |
638 | } | 640 | } |
639 | 641 | ||
640 | int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | 642 | int __irq_set_trigger(struct irq_desc *desc, unsigned long flags) |
641 | unsigned long flags) | ||
642 | { | 643 | { |
643 | struct irq_chip *chip = desc->irq_data.chip; | 644 | struct irq_chip *chip = desc->irq_data.chip; |
644 | int ret, unmask = 0; | 645 | int ret, unmask = 0; |
@@ -648,7 +649,8 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
648 | * IRQF_TRIGGER_* but the PIC does not support multiple | 649 | * IRQF_TRIGGER_* but the PIC does not support multiple |
649 | * flow-types? | 650 | * flow-types? |
650 | */ | 651 | */ |
651 | pr_debug("No set_type function for IRQ %d (%s)\n", irq, | 652 | pr_debug("No set_type function for IRQ %d (%s)\n", |
653 | irq_desc_get_irq(desc), | ||
652 | chip ? (chip->name ? : "unknown") : "unknown"); | 654 | chip ? (chip->name ? : "unknown") : "unknown"); |
653 | return 0; | 655 | return 0; |
654 | } | 656 | } |
@@ -685,7 +687,7 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
685 | break; | 687 | break; |
686 | default: | 688 | default: |
687 | pr_err("Setting trigger mode %lu for irq %u failed (%pF)\n", | 689 | pr_err("Setting trigger mode %lu for irq %u failed (%pF)\n", |
688 | flags, irq, chip->irq_set_type); | 690 | flags, irq_desc_get_irq(desc), chip->irq_set_type); |
689 | } | 691 | } |
690 | if (unmask) | 692 | if (unmask) |
691 | unmask_irq(desc); | 693 | unmask_irq(desc); |
@@ -1221,8 +1223,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
1221 | 1223 | ||
1222 | /* Setup the type (level, edge polarity) if configured: */ | 1224 | /* Setup the type (level, edge polarity) if configured: */ |
1223 | if (new->flags & IRQF_TRIGGER_MASK) { | 1225 | if (new->flags & IRQF_TRIGGER_MASK) { |
1224 | ret = __irq_set_trigger(desc, irq, | 1226 | ret = __irq_set_trigger(desc, |
1225 | new->flags & IRQF_TRIGGER_MASK); | 1227 | new->flags & IRQF_TRIGGER_MASK); |
1226 | 1228 | ||
1227 | if (ret) | 1229 | if (ret) |
1228 | goto out_mask; | 1230 | goto out_mask; |
@@ -1253,7 +1255,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
1253 | } | 1255 | } |
1254 | 1256 | ||
1255 | /* Set default affinity mask once everything is setup */ | 1257 | /* Set default affinity mask once everything is setup */ |
1256 | setup_affinity(irq, desc, mask); | 1258 | setup_affinity(desc, mask); |
1257 | 1259 | ||
1258 | } else if (new->flags & IRQF_TRIGGER_MASK) { | 1260 | } else if (new->flags & IRQF_TRIGGER_MASK) { |
1259 | unsigned int nmsk = new->flags & IRQF_TRIGGER_MASK; | 1261 | unsigned int nmsk = new->flags & IRQF_TRIGGER_MASK; |
@@ -1280,7 +1282,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
1280 | */ | 1282 | */ |
1281 | if (shared && (desc->istate & IRQS_SPURIOUS_DISABLED)) { | 1283 | if (shared && (desc->istate & IRQS_SPURIOUS_DISABLED)) { |
1282 | desc->istate &= ~IRQS_SPURIOUS_DISABLED; | 1284 | desc->istate &= ~IRQS_SPURIOUS_DISABLED; |
1283 | __enable_irq(desc, irq); | 1285 | __enable_irq(desc); |
1284 | } | 1286 | } |
1285 | 1287 | ||
1286 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 1288 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
@@ -1650,7 +1652,7 @@ void enable_percpu_irq(unsigned int irq, unsigned int type) | |||
1650 | if (type != IRQ_TYPE_NONE) { | 1652 | if (type != IRQ_TYPE_NONE) { |
1651 | int ret; | 1653 | int ret; |
1652 | 1654 | ||
1653 | ret = __irq_set_trigger(desc, irq, type); | 1655 | ret = __irq_set_trigger(desc, type); |
1654 | 1656 | ||
1655 | if (ret) { | 1657 | if (ret) { |
1656 | WARN(1, "failed to set type for IRQ%d\n", irq); | 1658 | WARN(1, "failed to set type for IRQ%d\n", irq); |
@@ -1875,6 +1877,7 @@ int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which, | |||
1875 | irq_put_desc_busunlock(desc, flags); | 1877 | irq_put_desc_busunlock(desc, flags); |
1876 | return err; | 1878 | return err; |
1877 | } | 1879 | } |
1880 | EXPORT_SYMBOL_GPL(irq_get_irqchip_state); | ||
1878 | 1881 | ||
1879 | /** | 1882 | /** |
1880 | * irq_set_irqchip_state - set the state of a forwarded interrupt. | 1883 | * irq_set_irqchip_state - set the state of a forwarded interrupt. |
@@ -1920,3 +1923,4 @@ int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which, | |||
1920 | irq_put_desc_busunlock(desc, flags); | 1923 | irq_put_desc_busunlock(desc, flags); |
1921 | return err; | 1924 | return err; |
1922 | } | 1925 | } |
1926 | EXPORT_SYMBOL_GPL(irq_set_irqchip_state); | ||
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 7bf1f1bbb7fa..7e6512b9dc1f 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c | |||
@@ -18,6 +18,23 @@ | |||
18 | /* Temparory solution for building, will be removed later */ | 18 | /* Temparory solution for building, will be removed later */ |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | 20 | ||
21 | struct msi_desc *alloc_msi_entry(struct device *dev) | ||
22 | { | ||
23 | struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL); | ||
24 | if (!desc) | ||
25 | return NULL; | ||
26 | |||
27 | INIT_LIST_HEAD(&desc->list); | ||
28 | desc->dev = dev; | ||
29 | |||
30 | return desc; | ||
31 | } | ||
32 | |||
33 | void free_msi_entry(struct msi_desc *entry) | ||
34 | { | ||
35 | kfree(entry); | ||
36 | } | ||
37 | |||
21 | void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | 38 | void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg) |
22 | { | 39 | { |
23 | *msg = entry->msg; | 40 | *msg = entry->msg; |
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c index d22786a6dbde..21c62617a35a 100644 --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c | |||
@@ -68,7 +68,7 @@ void irq_pm_remove_action(struct irq_desc *desc, struct irqaction *action) | |||
68 | desc->cond_suspend_depth--; | 68 | desc->cond_suspend_depth--; |
69 | } | 69 | } |
70 | 70 | ||
71 | static bool suspend_device_irq(struct irq_desc *desc, int irq) | 71 | static bool suspend_device_irq(struct irq_desc *desc) |
72 | { | 72 | { |
73 | if (!desc->action || desc->no_suspend_depth) | 73 | if (!desc->action || desc->no_suspend_depth) |
74 | return false; | 74 | return false; |
@@ -85,7 +85,7 @@ static bool suspend_device_irq(struct irq_desc *desc, int irq) | |||
85 | } | 85 | } |
86 | 86 | ||
87 | desc->istate |= IRQS_SUSPENDED; | 87 | desc->istate |= IRQS_SUSPENDED; |
88 | __disable_irq(desc, irq); | 88 | __disable_irq(desc); |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * Hardware which has no wakeup source configuration facility | 91 | * Hardware which has no wakeup source configuration facility |
@@ -126,7 +126,7 @@ void suspend_device_irqs(void) | |||
126 | if (irq_settings_is_nested_thread(desc)) | 126 | if (irq_settings_is_nested_thread(desc)) |
127 | continue; | 127 | continue; |
128 | raw_spin_lock_irqsave(&desc->lock, flags); | 128 | raw_spin_lock_irqsave(&desc->lock, flags); |
129 | sync = suspend_device_irq(desc, irq); | 129 | sync = suspend_device_irq(desc); |
130 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 130 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
131 | 131 | ||
132 | if (sync) | 132 | if (sync) |
@@ -135,7 +135,7 @@ void suspend_device_irqs(void) | |||
135 | } | 135 | } |
136 | EXPORT_SYMBOL_GPL(suspend_device_irqs); | 136 | EXPORT_SYMBOL_GPL(suspend_device_irqs); |
137 | 137 | ||
138 | static void resume_irq(struct irq_desc *desc, int irq) | 138 | static void resume_irq(struct irq_desc *desc) |
139 | { | 139 | { |
140 | irqd_clear(&desc->irq_data, IRQD_WAKEUP_ARMED); | 140 | irqd_clear(&desc->irq_data, IRQD_WAKEUP_ARMED); |
141 | 141 | ||
@@ -150,7 +150,7 @@ static void resume_irq(struct irq_desc *desc, int irq) | |||
150 | desc->depth++; | 150 | desc->depth++; |
151 | resume: | 151 | resume: |
152 | desc->istate &= ~IRQS_SUSPENDED; | 152 | desc->istate &= ~IRQS_SUSPENDED; |
153 | __enable_irq(desc, irq); | 153 | __enable_irq(desc); |
154 | } | 154 | } |
155 | 155 | ||
156 | static void resume_irqs(bool want_early) | 156 | static void resume_irqs(bool want_early) |
@@ -169,7 +169,7 @@ static void resume_irqs(bool want_early) | |||
169 | continue; | 169 | continue; |
170 | 170 | ||
171 | raw_spin_lock_irqsave(&desc->lock, flags); | 171 | raw_spin_lock_irqsave(&desc->lock, flags); |
172 | resume_irq(desc, irq); | 172 | resume_irq(desc); |
173 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 173 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
174 | } | 174 | } |
175 | } | 175 | } |
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c index 7a5237a1bce5..dd95f44f99b2 100644 --- a/kernel/irq/resend.c +++ b/kernel/irq/resend.c | |||
@@ -53,7 +53,7 @@ static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0); | |||
53 | * | 53 | * |
54 | * Is called with interrupts disabled and desc->lock held. | 54 | * Is called with interrupts disabled and desc->lock held. |
55 | */ | 55 | */ |
56 | void check_irq_resend(struct irq_desc *desc, unsigned int irq) | 56 | void check_irq_resend(struct irq_desc *desc) |
57 | { | 57 | { |
58 | /* | 58 | /* |
59 | * We do not resend level type interrupts. Level type | 59 | * We do not resend level type interrupts. Level type |
@@ -74,6 +74,8 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq) | |||
74 | if (!desc->irq_data.chip->irq_retrigger || | 74 | if (!desc->irq_data.chip->irq_retrigger || |
75 | !desc->irq_data.chip->irq_retrigger(&desc->irq_data)) { | 75 | !desc->irq_data.chip->irq_retrigger(&desc->irq_data)) { |
76 | #ifdef CONFIG_HARDIRQS_SW_RESEND | 76 | #ifdef CONFIG_HARDIRQS_SW_RESEND |
77 | unsigned int irq = irq_desc_get_irq(desc); | ||
78 | |||
77 | /* | 79 | /* |
78 | * If the interrupt is running in the thread | 80 | * If the interrupt is running in the thread |
79 | * context of the parent irq we need to be | 81 | * context of the parent irq we need to be |
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index e2514b0e439e..32144175458d 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -60,7 +60,7 @@ bool irq_wait_for_poll(struct irq_desc *desc) | |||
60 | /* | 60 | /* |
61 | * Recovery handler for misrouted interrupts. | 61 | * Recovery handler for misrouted interrupts. |
62 | */ | 62 | */ |
63 | static int try_one_irq(int irq, struct irq_desc *desc, bool force) | 63 | static int try_one_irq(struct irq_desc *desc, bool force) |
64 | { | 64 | { |
65 | irqreturn_t ret = IRQ_NONE; | 65 | irqreturn_t ret = IRQ_NONE; |
66 | struct irqaction *action; | 66 | struct irqaction *action; |
@@ -133,7 +133,7 @@ static int misrouted_irq(int irq) | |||
133 | if (i == irq) /* Already tried */ | 133 | if (i == irq) /* Already tried */ |
134 | continue; | 134 | continue; |
135 | 135 | ||
136 | if (try_one_irq(i, desc, false)) | 136 | if (try_one_irq(desc, false)) |
137 | ok = 1; | 137 | ok = 1; |
138 | } | 138 | } |
139 | out: | 139 | out: |
@@ -164,7 +164,7 @@ static void poll_spurious_irqs(unsigned long dummy) | |||
164 | continue; | 164 | continue; |
165 | 165 | ||
166 | local_irq_disable(); | 166 | local_irq_disable(); |
167 | try_one_irq(i, desc, true); | 167 | try_one_irq(desc, true); |
168 | local_irq_enable(); | 168 | local_irq_enable(); |
169 | } | 169 | } |
170 | out: | 170 | out: |
@@ -188,10 +188,9 @@ static inline int bad_action_ret(irqreturn_t action_ret) | |||
188 | * (The other 100-of-100,000 interrupts may have been a correctly | 188 | * (The other 100-of-100,000 interrupts may have been a correctly |
189 | * functioning device sharing an IRQ with the failing one) | 189 | * functioning device sharing an IRQ with the failing one) |
190 | */ | 190 | */ |
191 | static void | 191 | static void __report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret) |
192 | __report_bad_irq(unsigned int irq, struct irq_desc *desc, | ||
193 | irqreturn_t action_ret) | ||
194 | { | 192 | { |
193 | unsigned int irq = irq_desc_get_irq(desc); | ||
195 | struct irqaction *action; | 194 | struct irqaction *action; |
196 | unsigned long flags; | 195 | unsigned long flags; |
197 | 196 | ||
@@ -224,14 +223,13 @@ __report_bad_irq(unsigned int irq, struct irq_desc *desc, | |||
224 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 223 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
225 | } | 224 | } |
226 | 225 | ||
227 | static void | 226 | static void report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret) |
228 | report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret) | ||
229 | { | 227 | { |
230 | static int count = 100; | 228 | static int count = 100; |
231 | 229 | ||
232 | if (count > 0) { | 230 | if (count > 0) { |
233 | count--; | 231 | count--; |
234 | __report_bad_irq(irq, desc, action_ret); | 232 | __report_bad_irq(desc, action_ret); |
235 | } | 233 | } |
236 | } | 234 | } |
237 | 235 | ||
@@ -272,15 +270,16 @@ try_misrouted_irq(unsigned int irq, struct irq_desc *desc, | |||
272 | 270 | ||
273 | #define SPURIOUS_DEFERRED 0x80000000 | 271 | #define SPURIOUS_DEFERRED 0x80000000 |
274 | 272 | ||
275 | void note_interrupt(unsigned int irq, struct irq_desc *desc, | 273 | void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret) |
276 | irqreturn_t action_ret) | ||
277 | { | 274 | { |
275 | unsigned int irq; | ||
276 | |||
278 | if (desc->istate & IRQS_POLL_INPROGRESS || | 277 | if (desc->istate & IRQS_POLL_INPROGRESS || |
279 | irq_settings_is_polled(desc)) | 278 | irq_settings_is_polled(desc)) |
280 | return; | 279 | return; |
281 | 280 | ||
282 | if (bad_action_ret(action_ret)) { | 281 | if (bad_action_ret(action_ret)) { |
283 | report_bad_irq(irq, desc, action_ret); | 282 | report_bad_irq(desc, action_ret); |
284 | return; | 283 | return; |
285 | } | 284 | } |
286 | 285 | ||
@@ -398,6 +397,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc, | |||
398 | desc->last_unhandled = jiffies; | 397 | desc->last_unhandled = jiffies; |
399 | } | 398 | } |
400 | 399 | ||
400 | irq = irq_desc_get_irq(desc); | ||
401 | if (unlikely(try_misrouted_irq(irq, desc, action_ret))) { | 401 | if (unlikely(try_misrouted_irq(irq, desc, action_ret))) { |
402 | int ok = misrouted_irq(irq); | 402 | int ok = misrouted_irq(irq); |
403 | if (action_ret == IRQ_NONE) | 403 | if (action_ret == IRQ_NONE) |
@@ -413,7 +413,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc, | |||
413 | /* | 413 | /* |
414 | * The interrupt is stuck | 414 | * The interrupt is stuck |
415 | */ | 415 | */ |
416 | __report_bad_irq(irq, desc, action_ret); | 416 | __report_bad_irq(desc, action_ret); |
417 | /* | 417 | /* |
418 | * Now kill the IRQ | 418 | * Now kill the IRQ |
419 | */ | 419 | */ |