aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-04 18:59:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-04 18:59:13 -0400
commitd09cc3659db494aca4b3bb2393c533fb4946b794 (patch)
tree158d1dd5fa5fddf1c99da677a193b8561c11274d
parent82e627eb5e07d7993216c9e63fb5550cf6ed25d7 (diff)
parentc0ffa793994a7a69c37a96dabf38323eae1dffa6 (diff)
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next
Pull core irq updates from Thomas Gleixner: "The irq department delivers: - Another tree wide update to get rid of the horrible create_irq interface along with its even more horrible variants. That also gets rid of the last leftovers of the initial sparse irq hackery. arch/driver specific changes have been either acked or ignored. - A fix for the spurious interrupt detection logic with threaded interrupts. - A new ARM SoC interrupt controller - The usual pile of fixes and improvements all over the place" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (40 commits) Documentation: brcmstb-l2: Add Broadcom STB Level-2 interrupt controller binding irqchip: brcmstb-l2: Add Broadcom Set Top Box Level-2 interrupt controller genirq: Improve documentation to match current implementation ARM: iop13xx: fix msi support with sparse IRQ genirq: Provide !SMP stub for irq_set_affinity_notifier() irqchip: armada-370-xp: Move the devicetree binding documentation irqchip: gic: Use mask field in GICC_IAR genirq: Remove dynamic_irq mess ia64: Use irq_init_desc genirq: Replace dynamic_irq_init/cleanup genirq: Remove irq_reserve_irq[s] genirq: Replace reserve_irqs in core code s390: Avoid call to irq_reserve_irqs() s390: Remove pointless arch_show_interrupts() s390: pci: Check return value of alloc_irq_desc() proper sh: intc: Remove pointless irq_reserve_irqs() invocation x86, irq: Remove pointless irq_reserve_irqs() call genirq: Make create/destroy_irq() ia64 private tile: Use SPARSE_IRQ tile: pci: Use irq_alloc/free_hwirq() ...
-rw-r--r--Documentation/IRQ-domain.txt3
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.txt29
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/marvell,armada-370-xp-mpic.txt (renamed from Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt)0
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mach-iop13xx/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-iop13xx/include/mach/time.h3
-rw-r--r--arch/arm/mach-iop13xx/iq81340mc.c1
-rw-r--r--arch/arm/mach-iop13xx/iq81340sc.c1
-rw-r--r--arch/arm/mach-iop13xx/msi.c52
-rw-r--r--arch/arm/mach-iop13xx/setup.c1
-rw-r--r--arch/arm/mach-iop13xx/tpmi.c1
-rw-r--r--arch/ia64/Kconfig1
-rw-r--r--arch/ia64/include/asm/hw_irq.h1
-rw-r--r--arch/ia64/include/asm/irq.h3
-rw-r--r--arch/ia64/include/asm/irq_remapping.h2
-rw-r--r--arch/ia64/kernel/iosapic.c2
-rw-r--r--arch/ia64/kernel/irq_ia64.c15
-rw-r--r--arch/mips/pci/msi-xlp.c10
-rw-r--r--arch/mips/pci/pci-xlr.c10
-rw-r--r--arch/s390/kernel/irq.c5
-rw-r--r--arch/s390/pci/pci.c6
-rw-r--r--arch/tile/Kconfig2
-rw-r--r--arch/tile/include/asm/irq.h6
-rw-r--r--arch/tile/kernel/irq.c40
-rw-r--r--arch/tile/kernel/pci_gx.c17
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/include/asm/io_apic.h2
-rw-r--r--arch/x86/include/asm/irq_remapping.h3
-rw-r--r--arch/x86/kernel/apic/io_apic.c130
-rw-r--r--arch/x86/kernel/hpet.c5
-rw-r--r--arch/x86/platform/uv/uv_irq.c10
-rw-r--r--drivers/iommu/dmar.c8
-rw-r--r--drivers/iommu/irq_remapping.c12
-rw-r--r--drivers/irqchip/Kconfig6
-rw-r--r--drivers/irqchip/Makefile1
-rw-r--r--drivers/irqchip/irq-brcmstb-l2.c202
-rw-r--r--drivers/irqchip/irq-gic.c2
-rw-r--r--drivers/net/ethernet/tile/tilegx.c6
-rw-r--r--drivers/pci/htirq.c13
-rw-r--r--drivers/sh/intc/core.c6
-rw-r--r--drivers/tty/hvc/hvc_tile.c8
-rw-r--r--drivers/tty/serial/tilegx.c8
-rw-r--r--drivers/usb/host/ehci-tilegx.c8
-rw-r--r--drivers/usb/host/ohci-tilegx.c8
-rw-r--r--drivers/xen/events/events_base.c17
-rw-r--r--include/linux/interrupt.h46
-rw-r--r--include/linux/irq.h38
-rw-r--r--include/linux/irqchip/arm-gic.h2
-rw-r--r--include/linux/irqdesc.h4
-rw-r--r--kernel/irq/Kconfig9
-rw-r--r--kernel/irq/chip.c5
-rw-r--r--kernel/irq/internals.h8
-rw-r--r--kernel/irq/irqdesc.c95
-rw-r--r--kernel/irq/irqdomain.c6
-rw-r--r--kernel/irq/manage.c4
-rw-r--r--kernel/irq/spurious.c106
56 files changed, 597 insertions, 396 deletions
diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
index 03df71aeb38c..8a8b82c9ca53 100644
--- a/Documentation/IRQ-domain.txt
+++ b/Documentation/IRQ-domain.txt
@@ -41,8 +41,7 @@ An interrupt controller driver creates and registers an irq_domain by
41calling one of the irq_domain_add_*() functions (each mapping method 41calling one of the irq_domain_add_*() functions (each mapping method
42has a different allocator function, more on that later). The function 42has a different allocator function, more on that later). The function
43will return a pointer to the irq_domain on success. The caller must 43will return a pointer to the irq_domain on success. The caller must
44provide the allocator function with an irq_domain_ops structure with 44provide the allocator function with an irq_domain_ops structure.
45the .map callback populated as a minimum.
46 45
47In most cases, the irq_domain will begin empty without any mappings 46In most cases, the irq_domain will begin empty without any mappings
48between hwirq and IRQ numbers. Mappings are added to the irq_domain 47between hwirq and IRQ numbers. Mappings are added to the irq_domain
diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.txt
new file mode 100644
index 000000000000..448273a30a11
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.txt
@@ -0,0 +1,29 @@
1Broadcom Generic Level 2 Interrupt Controller
2
3Required properties:
4
5- compatible: should be "brcm,l2-intc"
6- reg: specifies the base physical address and size of the registers
7- interrupt-controller: identifies the node as an interrupt controller
8- #interrupt-cells: specifies the number of cells needed to encode an
9 interrupt source. Should be 1.
10- interrupt-parent: specifies the phandle to the parent interrupt controller
11 this controller is cacaded from
12- interrupts: specifies the interrupt line in the interrupt-parent irq space
13 to be used for cascading
14
15Optional properties:
16
17- brcm,irq-can-wake: If present, this means the L2 controller can be used as a
18 wakeup source for system suspend/resume.
19
20Example:
21
22hif_intr2_intc: interrupt-controller@f0441000 {
23 compatible = "brcm,l2-intc";
24 reg = <0xf0441000 0x30>;
25 interrupt-controller;
26 #interrupt-cells = <1>;
27 interrupt-parent = <&intc>;
28 interrupts = <0x0 0x20 0x0>;
29};
diff --git a/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt b/Documentation/devicetree/bindings/interrupt-controller/marvell,armada-370-xp-mpic.txt
index 5fc03134a999..5fc03134a999 100644
--- a/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/marvell,armada-370-xp-mpic.txt
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 071dce78959a..ad89a033f17f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -480,6 +480,7 @@ config ARCH_IOP13XX
480 select PCI 480 select PCI
481 select PLAT_IOP 481 select PLAT_IOP
482 select VMSPLIT_1G 482 select VMSPLIT_1G
483 select SPARSE_IRQ
483 help 484 help
484 Support for Intel's IOP13XX (XScale) family of processors. 485 Support for Intel's IOP13XX (XScale) family of processors.
485 486
diff --git a/arch/arm/mach-iop13xx/include/mach/irqs.h b/arch/arm/mach-iop13xx/include/mach/irqs.h
index 054e7acb5bfa..e8d24d32121a 100644
--- a/arch/arm/mach-iop13xx/include/mach/irqs.h
+++ b/arch/arm/mach-iop13xx/include/mach/irqs.h
@@ -191,6 +191,4 @@ static inline u32 read_intpnd_3(void)
191#define NR_IOP13XX_IRQS (IRQ_IOP13XX_HPI + 1) 191#define NR_IOP13XX_IRQS (IRQ_IOP13XX_HPI + 1)
192#endif 192#endif
193 193
194#define NR_IRQS NR_IOP13XX_IRQS
195
196#endif /* _IOP13XX_IRQ_H_ */ 194#endif /* _IOP13XX_IRQ_H_ */
diff --git a/arch/arm/mach-iop13xx/include/mach/time.h b/arch/arm/mach-iop13xx/include/mach/time.h
index f1c00d6d560b..15bc9bb78a6b 100644
--- a/arch/arm/mach-iop13xx/include/mach/time.h
+++ b/arch/arm/mach-iop13xx/include/mach/time.h
@@ -1,5 +1,8 @@
1#ifndef _IOP13XX_TIME_H_ 1#ifndef _IOP13XX_TIME_H_
2#define _IOP13XX_TIME_H_ 2#define _IOP13XX_TIME_H_
3
4#include <mach/irqs.h>
5
3#define IRQ_IOP_TIMER0 IRQ_IOP13XX_TIMER0 6#define IRQ_IOP_TIMER0 IRQ_IOP13XX_TIMER0
4 7
5#define IOP_TMR_EN 0x02 8#define IOP_TMR_EN 0x02
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
index 02a8228ac2d3..9cd07d396093 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -93,4 +93,5 @@ MACHINE_START(IQ81340MC, "Intel IQ81340MC")
93 .init_time = iq81340mc_timer_init, 93 .init_time = iq81340mc_timer_init,
94 .init_machine = iq81340mc_init, 94 .init_machine = iq81340mc_init,
95 .restart = iop13xx_restart, 95 .restart = iop13xx_restart,
96 .nr_irqs = NR_IOP13XX_IRQS,
96MACHINE_END 97MACHINE_END
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
index 1b80f10722b3..b3ec11cb707e 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -95,4 +95,5 @@ MACHINE_START(IQ81340SC, "Intel IQ81340SC")
95 .init_time = iq81340sc_timer_init, 95 .init_time = iq81340sc_timer_init,
96 .init_machine = iq81340sc_init, 96 .init_machine = iq81340sc_init,
97 .restart = iop13xx_restart, 97 .restart = iop13xx_restart,
98 .nr_irqs = NR_IOP13XX_IRQS,
98MACHINE_END 99MACHINE_END
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index 560d5b2dec22..e7730cf9c15d 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -23,10 +23,7 @@
23#include <linux/msi.h> 23#include <linux/msi.h>
24#include <asm/mach/irq.h> 24#include <asm/mach/irq.h>
25#include <asm/irq.h> 25#include <asm/irq.h>
26 26#include <mach/irqs.h>
27
28#define IOP13XX_NUM_MSI_IRQS 128
29static DECLARE_BITMAP(msi_irq_in_use, IOP13XX_NUM_MSI_IRQS);
30 27
31/* IMIPR0 CP6 R8 Page 1 28/* IMIPR0 CP6 R8 Page 1
32 */ 29 */
@@ -121,41 +118,6 @@ void __init iop13xx_msi_init(void)
121 irq_set_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler); 118 irq_set_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler);
122} 119}
123 120
124/*
125 * Dynamic irq allocate and deallocation
126 */
127int create_irq(void)
128{
129 int irq, pos;
130
131again:
132 pos = find_first_zero_bit(msi_irq_in_use, IOP13XX_NUM_MSI_IRQS);
133 irq = IRQ_IOP13XX_MSI_0 + pos;
134 if (irq > NR_IRQS)
135 return -ENOSPC;
136 /* test_and_set_bit operates on 32-bits at a time */
137 if (test_and_set_bit(pos, msi_irq_in_use))
138 goto again;
139
140 dynamic_irq_init(irq);
141
142 return irq;
143}
144
145void destroy_irq(unsigned int irq)
146{
147 int pos = irq - IRQ_IOP13XX_MSI_0;
148
149 dynamic_irq_cleanup(irq);
150
151 clear_bit(pos, msi_irq_in_use);
152}
153
154void arch_teardown_msi_irq(unsigned int irq)
155{
156 destroy_irq(irq);
157}
158
159static void iop13xx_msi_nop(struct irq_data *d) 121static void iop13xx_msi_nop(struct irq_data *d)
160{ 122{
161 return; 123 return;
@@ -172,12 +134,17 @@ static struct irq_chip iop13xx_msi_chip = {
172 134
173int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) 135int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
174{ 136{
175 int id, irq = create_irq(); 137 int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1);
176 struct msi_msg msg; 138 struct msi_msg msg;
177 139
178 if (irq < 0) 140 if (irq < 0)
179 return irq; 141 return irq;
180 142
143 if (irq >= NR_IOP13XX_IRQS) {
144 irq_free_desc(irq);
145 return -ENOSPC;
146 }
147
181 irq_set_msi_desc(irq, desc); 148 irq_set_msi_desc(irq, desc);
182 149
183 msg.address_hi = 0x0; 150 msg.address_hi = 0x0;
@@ -191,3 +158,8 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
191 158
192 return 0; 159 return 0;
193} 160}
161
162void arch_teardown_msi_irq(unsigned int irq)
163{
164 irq_free_desc(irq);
165}
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c
index 96e6c7a6793b..bca96f433495 100644
--- a/arch/arm/mach-iop13xx/setup.c
+++ b/arch/arm/mach-iop13xx/setup.c
@@ -27,6 +27,7 @@
27#include <mach/hardware.h> 27#include <mach/hardware.h>
28#include <asm/irq.h> 28#include <asm/irq.h>
29#include <asm/hardware/iop_adma.h> 29#include <asm/hardware/iop_adma.h>
30#include <mach/irqs.h>
30 31
31#define IOP13XX_UART_XTAL 33334000 32#define IOP13XX_UART_XTAL 33334000
32#define IOP13XX_SETUP_DEBUG 0 33#define IOP13XX_SETUP_DEBUG 0
diff --git a/arch/arm/mach-iop13xx/tpmi.c b/arch/arm/mach-iop13xx/tpmi.c
index 6fdad7a0425a..db511ec2b1df 100644
--- a/arch/arm/mach-iop13xx/tpmi.c
+++ b/arch/arm/mach-iop13xx/tpmi.c
@@ -24,6 +24,7 @@
24#include <linux/io.h> 24#include <linux/io.h>
25#include <asm/irq.h> 25#include <asm/irq.h>
26#include <asm/sizes.h> 26#include <asm/sizes.h>
27#include <mach/irqs.h>
27 28
28/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */ 29/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */
29#define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12)) 30#define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 12c3afee0f6f..2f3abcf8f6bc 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -32,6 +32,7 @@ config IA64
32 select GENERIC_IRQ_PROBE 32 select GENERIC_IRQ_PROBE
33 select GENERIC_PENDING_IRQ if SMP 33 select GENERIC_PENDING_IRQ if SMP
34 select GENERIC_IRQ_SHOW 34 select GENERIC_IRQ_SHOW
35 select GENERIC_IRQ_LEGACY
35 select ARCH_WANT_OPTIONAL_GPIOLIB 36 select ARCH_WANT_OPTIONAL_GPIOLIB
36 select ARCH_HAVE_NMI_SAFE_CMPXCHG 37 select ARCH_HAVE_NMI_SAFE_CMPXCHG
37 select GENERIC_IOMAP 38 select GENERIC_IOMAP
diff --git a/arch/ia64/include/asm/hw_irq.h b/arch/ia64/include/asm/hw_irq.h
index a681d02cb324..029bab36cd91 100644
--- a/arch/ia64/include/asm/hw_irq.h
+++ b/arch/ia64/include/asm/hw_irq.h
@@ -132,7 +132,6 @@ extern int reserve_irq_vector (int vector);
132extern void __setup_vector_irq(int cpu); 132extern void __setup_vector_irq(int cpu);
133extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); 133extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
134extern void ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action); 134extern void ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action);
135extern int check_irq_used (int irq);
136extern void destroy_and_reserve_irq (unsigned int irq); 135extern void destroy_and_reserve_irq (unsigned int irq);
137 136
138#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)) 137#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG))
diff --git a/arch/ia64/include/asm/irq.h b/arch/ia64/include/asm/irq.h
index 91b920fd7d53..820667cbea7e 100644
--- a/arch/ia64/include/asm/irq.h
+++ b/arch/ia64/include/asm/irq.h
@@ -31,4 +31,7 @@ bool is_affinity_mask_valid(const struct cpumask *cpumask);
31 31
32#define is_affinity_mask_valid is_affinity_mask_valid 32#define is_affinity_mask_valid is_affinity_mask_valid
33 33
34int create_irq(void);
35void destroy_irq(unsigned int irq);
36
34#endif /* _ASM_IA64_IRQ_H */ 37#endif /* _ASM_IA64_IRQ_H */
diff --git a/arch/ia64/include/asm/irq_remapping.h b/arch/ia64/include/asm/irq_remapping.h
index a8687b1d8906..e3b3556e2e1b 100644
--- a/arch/ia64/include/asm/irq_remapping.h
+++ b/arch/ia64/include/asm/irq_remapping.h
@@ -1,4 +1,6 @@
1#ifndef __IA64_INTR_REMAPPING_H 1#ifndef __IA64_INTR_REMAPPING_H
2#define __IA64_INTR_REMAPPING_H 2#define __IA64_INTR_REMAPPING_H
3#define irq_remapping_enabled 0 3#define irq_remapping_enabled 0
4#define dmar_alloc_hwirq create_irq
5#define dmar_free_hwirq destroy_irq
4#endif 6#endif
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 19f107be734e..cd44a57c73be 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -735,7 +735,7 @@ iosapic_register_intr (unsigned int gsi,
735 rte = find_rte(irq, gsi); 735 rte = find_rte(irq, gsi);
736 if(iosapic_intr_info[irq].count == 0) { 736 if(iosapic_intr_info[irq].count == 0) {
737 assign_irq_vector(irq); 737 assign_irq_vector(irq);
738 dynamic_irq_init(irq); 738 irq_init_desc(irq);
739 } else if (rte->refcnt != NO_REF_RTE) { 739 } else if (rte->refcnt != NO_REF_RTE) {
740 rte->refcnt++; 740 rte->refcnt++;
741 goto unlock_iosapic_lock; 741 goto unlock_iosapic_lock;
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 0884f5ecbcc3..03ea78ed64a9 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -93,14 +93,6 @@ static int irq_status[NR_IRQS] = {
93 [0 ... NR_IRQS -1] = IRQ_UNUSED 93 [0 ... NR_IRQS -1] = IRQ_UNUSED
94}; 94};
95 95
96int check_irq_used(int irq)
97{
98 if (irq_status[irq] == IRQ_USED)
99 return 1;
100
101 return -1;
102}
103
104static inline int find_unassigned_irq(void) 96static inline int find_unassigned_irq(void)
105{ 97{
106 int irq; 98 int irq;
@@ -390,8 +382,7 @@ void destroy_and_reserve_irq(unsigned int irq)
390{ 382{
391 unsigned long flags; 383 unsigned long flags;
392 384
393 dynamic_irq_cleanup(irq); 385 irq_init_desc(irq);
394
395 spin_lock_irqsave(&vector_lock, flags); 386 spin_lock_irqsave(&vector_lock, flags);
396 __clear_irq_vector(irq); 387 __clear_irq_vector(irq);
397 irq_status[irq] = IRQ_RSVD; 388 irq_status[irq] = IRQ_RSVD;
@@ -424,13 +415,13 @@ int create_irq(void)
424 out: 415 out:
425 spin_unlock_irqrestore(&vector_lock, flags); 416 spin_unlock_irqrestore(&vector_lock, flags);
426 if (irq >= 0) 417 if (irq >= 0)
427 dynamic_irq_init(irq); 418 irq_init_desc(irq);
428 return irq; 419 return irq;
429} 420}
430 421
431void destroy_irq(unsigned int irq) 422void destroy_irq(unsigned int irq)
432{ 423{
433 dynamic_irq_cleanup(irq); 424 irq_init_desc(irq);
434 clear_irq_vector(irq); 425 clear_irq_vector(irq);
435} 426}
436 427
diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index afd8405e0188..3249685e03ad 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -206,14 +206,8 @@ static struct irq_chip xlp_msix_chip = {
206 .irq_unmask = unmask_msi_irq, 206 .irq_unmask = unmask_msi_irq,
207}; 207};
208 208
209void destroy_irq(unsigned int irq)
210{
211 /* nothing to do yet */
212}
213
214void arch_teardown_msi_irq(unsigned int irq) 209void arch_teardown_msi_irq(unsigned int irq)
215{ 210{
216 destroy_irq(irq);
217} 211}
218 212
219/* 213/*
@@ -298,10 +292,8 @@ static int xlp_setup_msi(uint64_t lnkbase, int node, int link,
298 292
299 xirq = xirq + msivec; /* msi mapped to global irq space */ 293 xirq = xirq + msivec; /* msi mapped to global irq space */
300 ret = irq_set_msi_desc(xirq, desc); 294 ret = irq_set_msi_desc(xirq, desc);
301 if (ret < 0) { 295 if (ret < 0)
302 destroy_irq(xirq);
303 return ret; 296 return ret;
304 }
305 297
306 write_msi_msg(xirq, &msg); 298 write_msi_msg(xirq, &msg);
307 return 0; 299 return 0;
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
index 4427abbd48b5..0dde80332d3a 100644
--- a/arch/mips/pci/pci-xlr.c
+++ b/arch/mips/pci/pci-xlr.c
@@ -214,14 +214,8 @@ static int get_irq_vector(const struct pci_dev *dev)
214} 214}
215 215
216#ifdef CONFIG_PCI_MSI 216#ifdef CONFIG_PCI_MSI
217void destroy_irq(unsigned int irq)
218{
219 /* nothing to do yet */
220}
221
222void arch_teardown_msi_irq(unsigned int irq) 217void arch_teardown_msi_irq(unsigned int irq)
223{ 218{
224 destroy_irq(irq);
225} 219}
226 220
227int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) 221int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
@@ -263,10 +257,8 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
263 MSI_DATA_DELIVERY_FIXED; 257 MSI_DATA_DELIVERY_FIXED;
264 258
265 ret = irq_set_msi_desc(irq, desc); 259 ret = irq_set_msi_desc(irq, desc);
266 if (ret < 0) { 260 if (ret < 0)
267 destroy_irq(irq);
268 return ret; 261 return ret;
269 }
270 262
271 write_msi_msg(irq, &msg); 263 write_msi_msg(irq, &msg);
272 return 0; 264 return 0;
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index c7463aa0014b..99b0b09646ca 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -92,7 +92,6 @@ static const struct irq_class irqclass_sub_desc[NR_ARCH_IRQS] = {
92 92
93void __init init_IRQ(void) 93void __init init_IRQ(void)
94{ 94{
95 irq_reserve_irqs(0, THIN_INTERRUPT);
96 init_cio_interrupts(); 95 init_cio_interrupts();
97 init_airq_interrupts(); 96 init_airq_interrupts();
98 init_ext_interrupts(); 97 init_ext_interrupts();
@@ -151,9 +150,9 @@ out:
151 return 0; 150 return 0;
152} 151}
153 152
154int arch_show_interrupts(struct seq_file *p, int prec) 153unsigned int arch_dynirq_lower_bound(unsigned int from)
155{ 154{
156 return 0; 155 return from < THIN_INTERRUPT ? THIN_INTERRUPT : from;
157} 156}
158 157
159/* 158/*
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index bdf02570d1df..9ddc51eeb8d6 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -401,11 +401,11 @@ static void zpci_irq_handler(struct airq_struct *airq)
401int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) 401int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
402{ 402{
403 struct zpci_dev *zdev = get_zdev(pdev); 403 struct zpci_dev *zdev = get_zdev(pdev);
404 unsigned int hwirq, irq, msi_vecs; 404 unsigned int hwirq, msi_vecs;
405 unsigned long aisb; 405 unsigned long aisb;
406 struct msi_desc *msi; 406 struct msi_desc *msi;
407 struct msi_msg msg; 407 struct msi_msg msg;
408 int rc; 408 int rc, irq;
409 409
410 if (type == PCI_CAP_ID_MSI && nvec > 1) 410 if (type == PCI_CAP_ID_MSI && nvec > 1)
411 return 1; 411 return 1;
@@ -433,7 +433,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
433 list_for_each_entry(msi, &pdev->msi_list, list) { 433 list_for_each_entry(msi, &pdev->msi_list, list) {
434 rc = -EIO; 434 rc = -EIO;
435 irq = irq_alloc_desc(0); /* Alloc irq on node 0 */ 435 irq = irq_alloc_desc(0); /* Alloc irq on node 0 */
436 if (irq == NO_IRQ) 436 if (irq < 0)
437 goto out_msi; 437 goto out_msi;
438 rc = irq_set_msi_desc(irq, msi); 438 rc = irq_set_msi_desc(irq, msi);
439 if (rc) 439 if (rc)
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 85258ca43ff5..4f3006b600e3 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -125,6 +125,8 @@ config HVC_TILE
125 125
126config TILEGX 126config TILEGX
127 bool "Building for TILE-Gx (64-bit) processor" 127 bool "Building for TILE-Gx (64-bit) processor"
128 select SPARSE_IRQ
129 select GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
128 select HAVE_FUNCTION_TRACER 130 select HAVE_FUNCTION_TRACER
129 select HAVE_FUNCTION_TRACE_MCOUNT_TEST 131 select HAVE_FUNCTION_TRACE_MCOUNT_TEST
130 select HAVE_FUNCTION_GRAPH_TRACER 132 select HAVE_FUNCTION_GRAPH_TRACER
diff --git a/arch/tile/include/asm/irq.h b/arch/tile/include/asm/irq.h
index 33cff9a3058b..1fe86911838b 100644
--- a/arch/tile/include/asm/irq.h
+++ b/arch/tile/include/asm/irq.h
@@ -18,10 +18,12 @@
18#include <linux/hardirq.h> 18#include <linux/hardirq.h>
19 19
20/* The hypervisor interface provides 32 IRQs. */ 20/* The hypervisor interface provides 32 IRQs. */
21#define NR_IRQS 32 21#define NR_IRQS 32
22 22
23/* IRQ numbers used for linux IPIs. */ 23/* IRQ numbers used for linux IPIs. */
24#define IRQ_RESCHEDULE 0 24#define IRQ_RESCHEDULE 0
25/* Interrupts for dynamic allocation start at 1. Let the core allocate irq0 */
26#define NR_IRQS_LEGACY 1
25 27
26#define irq_canonicalize(irq) (irq) 28#define irq_canonicalize(irq) (irq)
27 29
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c
index 906a76bdb31d..637f2ffaa5f5 100644
--- a/arch/tile/kernel/irq.c
+++ b/arch/tile/kernel/irq.c
@@ -54,13 +54,6 @@ static DEFINE_PER_CPU(unsigned long, irq_disable_mask)
54 */ 54 */
55static DEFINE_PER_CPU(int, irq_depth); 55static DEFINE_PER_CPU(int, irq_depth);
56 56
57/* State for allocating IRQs on Gx. */
58#if CHIP_HAS_IPI()
59static unsigned long available_irqs = ((1UL << NR_IRQS) - 1) &
60 (~(1UL << IRQ_RESCHEDULE));
61static DEFINE_SPINLOCK(available_irqs_lock);
62#endif
63
64#if CHIP_HAS_IPI() 57#if CHIP_HAS_IPI()
65/* Use SPRs to manipulate device interrupts. */ 58/* Use SPRs to manipulate device interrupts. */
66#define mask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_SET_K, irq_mask) 59#define mask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_SET_K, irq_mask)
@@ -278,38 +271,11 @@ int arch_show_interrupts(struct seq_file *p, int prec)
278 return 0; 271 return 0;
279} 272}
280 273
281/*
282 * Generic, controller-independent functions:
283 */
284
285#if CHIP_HAS_IPI() 274#if CHIP_HAS_IPI()
286int create_irq(void) 275int arch_setup_hwirq(unsigned int irq, int node)
287{ 276{
288 unsigned long flags; 277 return irq >= NR_IRQS ? -EINVAL : 0;
289 int result;
290
291 spin_lock_irqsave(&available_irqs_lock, flags);
292 if (available_irqs == 0)
293 result = -ENOMEM;
294 else {
295 result = __ffs(available_irqs);
296 available_irqs &= ~(1UL << result);
297 dynamic_irq_init(result);
298 }
299 spin_unlock_irqrestore(&available_irqs_lock, flags);
300
301 return result;
302} 278}
303EXPORT_SYMBOL(create_irq);
304 279
305void destroy_irq(unsigned int irq) 280void arch_teardown_hwirq(unsigned int irq) { }
306{
307 unsigned long flags;
308
309 spin_lock_irqsave(&available_irqs_lock, flags);
310 available_irqs |= (1UL << irq);
311 dynamic_irq_cleanup(irq);
312 spin_unlock_irqrestore(&available_irqs_lock, flags);
313}
314EXPORT_SYMBOL(destroy_irq);
315#endif 281#endif
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index 077b7bc437e5..e39f9c542807 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -350,10 +350,9 @@ static int tile_init_irqs(struct pci_controller *controller)
350 int cpu; 350 int cpu;
351 351
352 /* Ask the kernel to allocate an IRQ. */ 352 /* Ask the kernel to allocate an IRQ. */
353 irq = create_irq(); 353 irq = irq_alloc_hwirq(-1);
354 if (irq < 0) { 354 if (!irq) {
355 pr_err("PCI: no free irq vectors, failed for %d\n", i); 355 pr_err("PCI: no free irq vectors, failed for %d\n", i);
356
357 goto free_irqs; 356 goto free_irqs;
358 } 357 }
359 controller->irq_intx_table[i] = irq; 358 controller->irq_intx_table[i] = irq;
@@ -382,7 +381,7 @@ static int tile_init_irqs(struct pci_controller *controller)
382 381
383free_irqs: 382free_irqs:
384 for (j = 0; j < i; j++) 383 for (j = 0; j < i; j++)
385 destroy_irq(controller->irq_intx_table[j]); 384 irq_free_hwirq(controller->irq_intx_table[j]);
386 385
387 return -1; 386 return -1;
388} 387}
@@ -1500,9 +1499,9 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
1500 int irq; 1499 int irq;
1501 int ret; 1500 int ret;
1502 1501
1503 irq = create_irq(); 1502 irq = irq_alloc_hwirq(-1);
1504 if (irq < 0) 1503 if (!irq)
1505 return irq; 1504 return -ENOSPC;
1506 1505
1507 /* 1506 /*
1508 * Since we use a 64-bit Mem-Map to accept the MSI write, we fail 1507 * Since we use a 64-bit Mem-Map to accept the MSI write, we fail
@@ -1601,11 +1600,11 @@ hv_msi_config_failure:
1601 /* Free mem-map */ 1600 /* Free mem-map */
1602msi_mem_map_alloc_failure: 1601msi_mem_map_alloc_failure:
1603is_64_failure: 1602is_64_failure:
1604 destroy_irq(irq); 1603 irq_free_hwirq(irq);
1605 return ret; 1604 return ret;
1606} 1605}
1607 1606
1608void arch_teardown_msi_irq(unsigned int irq) 1607void arch_teardown_msi_irq(unsigned int irq)
1609{ 1608{
1610 destroy_irq(irq); 1609 irq_free_hwirq(irq);
1611} 1610}
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7d5feb5908dd..7a01d4335029 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -833,6 +833,7 @@ config X86_LOCAL_APIC
833config X86_IO_APIC 833config X86_IO_APIC
834 def_bool y 834 def_bool y
835 depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC || PCI_MSI 835 depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC || PCI_MSI
836 select GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
836 837
837config X86_REROUTE_FOR_BROKEN_BOOT_IRQS 838config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
838 bool "Reroute for broken boot IRQs" 839 bool "Reroute for broken boot IRQs"
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 459e50a424d1..90f97b4b9347 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -168,8 +168,6 @@ extern int save_ioapic_entries(void);
168extern void mask_ioapic_entries(void); 168extern void mask_ioapic_entries(void);
169extern int restore_ioapic_entries(void); 169extern int restore_ioapic_entries(void);
170 170
171extern int get_nr_irqs_gsi(void);
172
173extern void setup_ioapic_ids_from_mpc(void); 171extern void setup_ioapic_ids_from_mpc(void);
174extern void setup_ioapic_ids_from_mpc_nocheck(void); 172extern void setup_ioapic_ids_from_mpc_nocheck(void);
175 173
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
index d806b228d2c0..b7747c4c2cf2 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -103,4 +103,7 @@ static inline bool setup_remapped_irq(int irq,
103} 103}
104#endif /* CONFIG_IRQ_REMAP */ 104#endif /* CONFIG_IRQ_REMAP */
105 105
106#define dmar_alloc_hwirq() irq_alloc_hwirq(-1)
107#define dmar_free_hwirq irq_free_hwirq
108
106#endif /* __X86_IRQ_REMAPPING_H */ 109#endif /* __X86_IRQ_REMAPPING_H */
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 992060e09897..9d0a9795a0f8 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -206,9 +206,6 @@ int __init arch_early_irq_init(void)
206 count = ARRAY_SIZE(irq_cfgx); 206 count = ARRAY_SIZE(irq_cfgx);
207 node = cpu_to_node(0); 207 node = cpu_to_node(0);
208 208
209 /* Make sure the legacy interrupts are marked in the bitmap */
210 irq_reserve_irqs(0, legacy_pic->nr_legacy_irqs);
211
212 for (i = 0; i < count; i++) { 209 for (i = 0; i < count; i++) {
213 irq_set_chip_data(i, &cfg[i]); 210 irq_set_chip_data(i, &cfg[i]);
214 zalloc_cpumask_var_node(&cfg[i].domain, GFP_KERNEL, node); 211 zalloc_cpumask_var_node(&cfg[i].domain, GFP_KERNEL, node);
@@ -281,18 +278,6 @@ static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
281 return cfg; 278 return cfg;
282} 279}
283 280
284static int alloc_irqs_from(unsigned int from, unsigned int count, int node)
285{
286 return irq_alloc_descs_from(from, count, node);
287}
288
289static void free_irq_at(unsigned int at, struct irq_cfg *cfg)
290{
291 free_irq_cfg(at, cfg);
292 irq_free_desc(at);
293}
294
295
296struct io_apic { 281struct io_apic {
297 unsigned int index; 282 unsigned int index;
298 unsigned int unused[3]; 283 unsigned int unused[3];
@@ -2916,98 +2901,39 @@ static int __init ioapic_init_ops(void)
2916device_initcall(ioapic_init_ops); 2901device_initcall(ioapic_init_ops);
2917 2902
2918/* 2903/*
2919 * Dynamic irq allocate and deallocation 2904 * Dynamic irq allocate and deallocation. Should be replaced by irq domains!
2920 */ 2905 */
2921unsigned int __create_irqs(unsigned int from, unsigned int count, int node) 2906int arch_setup_hwirq(unsigned int irq, int node)
2922{ 2907{
2923 struct irq_cfg **cfg; 2908 struct irq_cfg *cfg;
2924 unsigned long flags; 2909 unsigned long flags;
2925 int irq, i; 2910 int ret;
2926
2927 if (from < nr_irqs_gsi)
2928 from = nr_irqs_gsi;
2929 2911
2930 cfg = kzalloc_node(count * sizeof(cfg[0]), GFP_KERNEL, node); 2912 cfg = alloc_irq_cfg(irq, node);
2931 if (!cfg) 2913 if (!cfg)
2932 return 0; 2914 return -ENOMEM;
2933
2934 irq = alloc_irqs_from(from, count, node);
2935 if (irq < 0)
2936 goto out_cfgs;
2937
2938 for (i = 0; i < count; i++) {
2939 cfg[i] = alloc_irq_cfg(irq + i, node);
2940 if (!cfg[i])
2941 goto out_irqs;
2942 }
2943 2915
2944 raw_spin_lock_irqsave(&vector_lock, flags); 2916 raw_spin_lock_irqsave(&vector_lock, flags);
2945 for (i = 0; i < count; i++) 2917 ret = __assign_irq_vector(irq, cfg, apic->target_cpus());
2946 if (__assign_irq_vector(irq + i, cfg[i], apic->target_cpus()))
2947 goto out_vecs;
2948 raw_spin_unlock_irqrestore(&vector_lock, flags);
2949
2950 for (i = 0; i < count; i++) {
2951 irq_set_chip_data(irq + i, cfg[i]);
2952 irq_clear_status_flags(irq + i, IRQ_NOREQUEST);
2953 }
2954
2955 kfree(cfg);
2956 return irq;
2957
2958out_vecs:
2959 for (i--; i >= 0; i--)
2960 __clear_irq_vector(irq + i, cfg[i]);
2961 raw_spin_unlock_irqrestore(&vector_lock, flags); 2918 raw_spin_unlock_irqrestore(&vector_lock, flags);
2962out_irqs:
2963 for (i = 0; i < count; i++)
2964 free_irq_at(irq + i, cfg[i]);
2965out_cfgs:
2966 kfree(cfg);
2967 return 0;
2968}
2969 2919
2970unsigned int create_irq_nr(unsigned int from, int node) 2920 if (!ret)
2971{ 2921 irq_set_chip_data(irq, cfg);
2972 return __create_irqs(from, 1, node); 2922 else
2973} 2923 free_irq_cfg(irq, cfg);
2974 2924 return ret;
2975int create_irq(void)
2976{
2977 int node = cpu_to_node(0);
2978 unsigned int irq_want;
2979 int irq;
2980
2981 irq_want = nr_irqs_gsi;
2982 irq = create_irq_nr(irq_want, node);
2983
2984 if (irq == 0)
2985 irq = -1;
2986
2987 return irq;
2988} 2925}
2989 2926
2990void destroy_irq(unsigned int irq) 2927void arch_teardown_hwirq(unsigned int irq)
2991{ 2928{
2992 struct irq_cfg *cfg = irq_get_chip_data(irq); 2929 struct irq_cfg *cfg = irq_get_chip_data(irq);
2993 unsigned long flags; 2930 unsigned long flags;
2994 2931
2995 irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE);
2996
2997 free_remapped_irq(irq); 2932 free_remapped_irq(irq);
2998
2999 raw_spin_lock_irqsave(&vector_lock, flags); 2933 raw_spin_lock_irqsave(&vector_lock, flags);
3000 __clear_irq_vector(irq, cfg); 2934 __clear_irq_vector(irq, cfg);
3001 raw_spin_unlock_irqrestore(&vector_lock, flags); 2935 raw_spin_unlock_irqrestore(&vector_lock, flags);
3002 free_irq_at(irq, cfg); 2936 free_irq_cfg(irq, cfg);
3003}
3004
3005void destroy_irqs(unsigned int irq, unsigned int count)
3006{
3007 unsigned int i;
3008
3009 for (i = 0; i < count; i++)
3010 destroy_irq(irq + i);
3011} 2937}
3012 2938
3013/* 2939/*
@@ -3136,8 +3062,8 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
3136 3062
3137int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 3063int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
3138{ 3064{
3139 unsigned int irq, irq_want;
3140 struct msi_desc *msidesc; 3065 struct msi_desc *msidesc;
3066 unsigned int irq;
3141 int node, ret; 3067 int node, ret;
3142 3068
3143 /* Multiple MSI vectors only supported with interrupt remapping */ 3069 /* Multiple MSI vectors only supported with interrupt remapping */
@@ -3145,28 +3071,25 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
3145 return 1; 3071 return 1;
3146 3072
3147 node = dev_to_node(&dev->dev); 3073 node = dev_to_node(&dev->dev);
3148 irq_want = nr_irqs_gsi; 3074
3149 list_for_each_entry(msidesc, &dev->msi_list, list) { 3075 list_for_each_entry(msidesc, &dev->msi_list, list) {
3150 irq = create_irq_nr(irq_want, node); 3076 irq = irq_alloc_hwirq(node);
3151 if (irq == 0) 3077 if (!irq)
3152 return -ENOSPC; 3078 return -ENOSPC;
3153 3079
3154 irq_want = irq + 1;
3155
3156 ret = setup_msi_irq(dev, msidesc, irq, 0); 3080 ret = setup_msi_irq(dev, msidesc, irq, 0);
3157 if (ret < 0) 3081 if (ret < 0) {
3158 goto error; 3082 irq_free_hwirq(irq);
3083 return ret;
3084 }
3085
3159 } 3086 }
3160 return 0; 3087 return 0;
3161
3162error:
3163 destroy_irq(irq);
3164 return ret;
3165} 3088}
3166 3089
3167void native_teardown_msi_irq(unsigned int irq) 3090void native_teardown_msi_irq(unsigned int irq)
3168{ 3091{
3169 destroy_irq(irq); 3092 irq_free_hwirq(irq);
3170} 3093}
3171 3094
3172#ifdef CONFIG_DMAR_TABLE 3095#ifdef CONFIG_DMAR_TABLE
@@ -3420,11 +3343,6 @@ static void __init probe_nr_irqs_gsi(void)
3420 printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); 3343 printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
3421} 3344}
3422 3345
3423int get_nr_irqs_gsi(void)
3424{
3425 return nr_irqs_gsi;
3426}
3427
3428unsigned int arch_dynirq_lower_bound(unsigned int from) 3346unsigned int arch_dynirq_lower_bound(unsigned int from)
3429{ 3347{
3430 return from < nr_irqs_gsi ? nr_irqs_gsi : from; 3348 return from < nr_irqs_gsi ? nr_irqs_gsi : from;
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 4177bfbc80b0..5f5a147d1cd2 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -479,7 +479,7 @@ static int hpet_msi_next_event(unsigned long delta,
479static int hpet_setup_msi_irq(unsigned int irq) 479static int hpet_setup_msi_irq(unsigned int irq)
480{ 480{
481 if (x86_msi.setup_hpet_msi(irq, hpet_blockid)) { 481 if (x86_msi.setup_hpet_msi(irq, hpet_blockid)) {
482 destroy_irq(irq); 482 irq_free_hwirq(irq);
483 return -EINVAL; 483 return -EINVAL;
484 } 484 }
485 return 0; 485 return 0;
@@ -487,9 +487,8 @@ static int hpet_setup_msi_irq(unsigned int irq)
487 487
488static int hpet_assign_irq(struct hpet_dev *dev) 488static int hpet_assign_irq(struct hpet_dev *dev)
489{ 489{
490 unsigned int irq; 490 unsigned int irq = irq_alloc_hwirq(-1);
491 491
492 irq = create_irq_nr(0, -1);
493 if (!irq) 492 if (!irq)
494 return -EINVAL; 493 return -EINVAL;
495 494
diff --git a/arch/x86/platform/uv/uv_irq.c b/arch/x86/platform/uv/uv_irq.c
index acf7752da952..b233681af4de 100644
--- a/arch/x86/platform/uv/uv_irq.c
+++ b/arch/x86/platform/uv/uv_irq.c
@@ -238,11 +238,9 @@ uv_set_irq_affinity(struct irq_data *data, const struct cpumask *mask,
238int uv_setup_irq(char *irq_name, int cpu, int mmr_blade, 238int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
239 unsigned long mmr_offset, int limit) 239 unsigned long mmr_offset, int limit)
240{ 240{
241 int irq, ret; 241 int ret, irq = irq_alloc_hwirq(uv_blade_to_memory_nid(mmr_blade));
242 242
243 irq = create_irq_nr(NR_IRQS_LEGACY, uv_blade_to_memory_nid(mmr_blade)); 243 if (!irq)
244
245 if (irq <= 0)
246 return -EBUSY; 244 return -EBUSY;
247 245
248 ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset, 246 ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset,
@@ -250,7 +248,7 @@ int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
250 if (ret == irq) 248 if (ret == irq)
251 uv_set_irq_2_mmr_info(irq, mmr_offset, mmr_blade); 249 uv_set_irq_2_mmr_info(irq, mmr_offset, mmr_blade);
252 else 250 else
253 destroy_irq(irq); 251 irq_free_hwirq(irq);
254 252
255 return ret; 253 return ret;
256} 254}
@@ -285,6 +283,6 @@ void uv_teardown_irq(unsigned int irq)
285 n = n->rb_right; 283 n = n->rb_right;
286 } 284 }
287 spin_unlock_irqrestore(&uv_irq_lock, irqflags); 285 spin_unlock_irqrestore(&uv_irq_lock, irqflags);
288 destroy_irq(irq); 286 irq_free_hwirq(irq);
289} 287}
290EXPORT_SYMBOL_GPL(uv_teardown_irq); 288EXPORT_SYMBOL_GPL(uv_teardown_irq);
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 39f8b717fe84..9a4f05e5b23f 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -994,7 +994,7 @@ static void free_iommu(struct intel_iommu *iommu)
994 if (iommu->irq) { 994 if (iommu->irq) {
995 free_irq(iommu->irq, iommu); 995 free_irq(iommu->irq, iommu);
996 irq_set_handler_data(iommu->irq, NULL); 996 irq_set_handler_data(iommu->irq, NULL);
997 destroy_irq(iommu->irq); 997 dmar_free_hwirq(iommu->irq);
998 } 998 }
999 999
1000 if (iommu->qi) { 1000 if (iommu->qi) {
@@ -1550,8 +1550,8 @@ int dmar_set_interrupt(struct intel_iommu *iommu)
1550 if (iommu->irq) 1550 if (iommu->irq)
1551 return 0; 1551 return 0;
1552 1552
1553 irq = create_irq(); 1553 irq = dmar_alloc_hwirq();
1554 if (!irq) { 1554 if (irq <= 0) {
1555 pr_err("IOMMU: no free vectors\n"); 1555 pr_err("IOMMU: no free vectors\n");
1556 return -EINVAL; 1556 return -EINVAL;
1557 } 1557 }
@@ -1563,7 +1563,7 @@ int dmar_set_interrupt(struct intel_iommu *iommu)
1563 if (ret) { 1563 if (ret) {
1564 irq_set_handler_data(irq, NULL); 1564 irq_set_handler_data(irq, NULL);
1565 iommu->irq = 0; 1565 iommu->irq = 0;
1566 destroy_irq(irq); 1566 dmar_free_hwirq(irq);
1567 return ret; 1567 return ret;
1568 } 1568 }
1569 1569
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 228632c99adb..33c439524080 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -51,7 +51,7 @@ static void irq_remapping_disable_io_apic(void)
51 51
52static int do_setup_msi_irqs(struct pci_dev *dev, int nvec) 52static int do_setup_msi_irqs(struct pci_dev *dev, int nvec)
53{ 53{
54 int node, ret, sub_handle, nvec_pow2, index = 0; 54 int ret, sub_handle, nvec_pow2, index = 0;
55 unsigned int irq; 55 unsigned int irq;
56 struct msi_desc *msidesc; 56 struct msi_desc *msidesc;
57 57
@@ -61,8 +61,7 @@ static int do_setup_msi_irqs(struct pci_dev *dev, int nvec)
61 WARN_ON(msidesc->msi_attrib.multiple); 61 WARN_ON(msidesc->msi_attrib.multiple);
62 WARN_ON(msidesc->nvec_used); 62 WARN_ON(msidesc->nvec_used);
63 63
64 node = dev_to_node(&dev->dev); 64 irq = irq_alloc_hwirqs(nvec, dev_to_node(&dev->dev));
65 irq = __create_irqs(get_nr_irqs_gsi(), nvec, node);
66 if (irq == 0) 65 if (irq == 0)
67 return -ENOSPC; 66 return -ENOSPC;
68 67
@@ -89,7 +88,7 @@ static int do_setup_msi_irqs(struct pci_dev *dev, int nvec)
89 return 0; 88 return 0;
90 89
91error: 90error:
92 destroy_irqs(irq, nvec); 91 irq_free_hwirqs(irq, nvec);
93 92
94 /* 93 /*
95 * Restore altered MSI descriptor fields and prevent just destroyed 94 * Restore altered MSI descriptor fields and prevent just destroyed
@@ -109,12 +108,11 @@ static int do_setup_msix_irqs(struct pci_dev *dev, int nvec)
109 unsigned int irq; 108 unsigned int irq;
110 109
111 node = dev_to_node(&dev->dev); 110 node = dev_to_node(&dev->dev);
112 irq = get_nr_irqs_gsi();
113 sub_handle = 0; 111 sub_handle = 0;
114 112
115 list_for_each_entry(msidesc, &dev->msi_list, list) { 113 list_for_each_entry(msidesc, &dev->msi_list, list) {
116 114
117 irq = create_irq_nr(irq, node); 115 irq = irq_alloc_hwirq(node);
118 if (irq == 0) 116 if (irq == 0)
119 return -1; 117 return -1;
120 118
@@ -137,7 +135,7 @@ static int do_setup_msix_irqs(struct pci_dev *dev, int nvec)
137 return 0; 135 return 0;
138 136
139error: 137error:
140 destroy_irq(irq); 138 irq_free_hwirq(irq);
141 return ret; 139 return ret;
142} 140}
143 141
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index d770f7406631..bbb746e35500 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -30,6 +30,12 @@ config ARM_VIC_NR
30 The maximum number of VICs available in the system, for 30 The maximum number of VICs available in the system, for
31 power management. 31 power management.
32 32
33config BRCMSTB_L2_IRQ
34 bool
35 depends on ARM
36 select GENERIC_IRQ_CHIP
37 select IRQ_DOMAIN
38
33config DW_APB_ICTL 39config DW_APB_ICTL
34 bool 40 bool
35 select IRQ_DOMAIN 41 select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f180f8d5fb7b..62a13e5ef98f 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
29obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o 29obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o
30obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o 30obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o
31obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o 31obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o
32obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c
new file mode 100644
index 000000000000..8ee2a36d5840
--- /dev/null
+++ b/drivers/irqchip/irq-brcmstb-l2.c
@@ -0,0 +1,202 @@
1/*
2 * Generic Broadcom Set Top Box Level 2 Interrupt controller driver
3 *
4 * Copyright (C) 2014 Broadcom Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/of.h>
23#include <linux/of_irq.h>
24#include <linux/of_address.h>
25#include <linux/of_platform.h>
26#include <linux/interrupt.h>
27#include <linux/irq.h>
28#include <linux/io.h>
29#include <linux/irqdomain.h>
30#include <linux/irqchip.h>
31#include <linux/irqchip/chained_irq.h>
32
33#include <asm/mach/irq.h>
34
35#include "irqchip.h"
36
37/* Register offsets in the L2 interrupt controller */
38#define CPU_STATUS 0x00
39#define CPU_SET 0x04
40#define CPU_CLEAR 0x08
41#define CPU_MASK_STATUS 0x0c
42#define CPU_MASK_SET 0x10
43#define CPU_MASK_CLEAR 0x14
44
45/* L2 intc private data structure */
46struct brcmstb_l2_intc_data {
47 int parent_irq;
48 void __iomem *base;
49 struct irq_domain *domain;
50 bool can_wake;
51 u32 saved_mask; /* for suspend/resume */
52};
53
54static void brcmstb_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
55{
56 struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc);
57 struct irq_chip *chip = irq_desc_get_chip(desc);
58 u32 status;
59
60 chained_irq_enter(chip, desc);
61
62 status = __raw_readl(b->base + CPU_STATUS) &
63 ~(__raw_readl(b->base + CPU_MASK_STATUS));
64
65 if (status == 0) {
66 do_bad_IRQ(irq, desc);
67 goto out;
68 }
69
70 do {
71 irq = ffs(status) - 1;
72 /* ack at our level */
73 __raw_writel(1 << irq, b->base + CPU_CLEAR);
74 status &= ~(1 << irq);
75 generic_handle_irq(irq_find_mapping(b->domain, irq));
76 } while (status);
77out:
78 chained_irq_exit(chip, desc);
79}
80
81static void brcmstb_l2_intc_suspend(struct irq_data *d)
82{
83 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
84 struct brcmstb_l2_intc_data *b = gc->private;
85
86 irq_gc_lock(gc);
87 /* Save the current mask */
88 b->saved_mask = __raw_readl(b->base + CPU_MASK_STATUS);
89
90 if (b->can_wake) {
91 /* Program the wakeup mask */
92 __raw_writel(~gc->wake_active, b->base + CPU_MASK_SET);
93 __raw_writel(gc->wake_active, b->base + CPU_MASK_CLEAR);
94 }
95 irq_gc_unlock(gc);
96}
97
98static void brcmstb_l2_intc_resume(struct irq_data *d)
99{
100 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
101 struct brcmstb_l2_intc_data *b = gc->private;
102
103 irq_gc_lock(gc);
104 /* Clear unmasked non-wakeup interrupts */
105 __raw_writel(~b->saved_mask & ~gc->wake_active, b->base + CPU_CLEAR);
106
107 /* Restore the saved mask */
108 __raw_writel(b->saved_mask, b->base + CPU_MASK_SET);
109 __raw_writel(~b->saved_mask, b->base + CPU_MASK_CLEAR);
110 irq_gc_unlock(gc);
111}
112
113int __init brcmstb_l2_intc_of_init(struct device_node *np,
114 struct device_node *parent)
115{
116 unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
117 struct brcmstb_l2_intc_data *data;
118 struct irq_chip_generic *gc;
119 struct irq_chip_type *ct;
120 int ret;
121
122 data = kzalloc(sizeof(*data), GFP_KERNEL);
123 if (!data)
124 return -ENOMEM;
125
126 data->base = of_iomap(np, 0);
127 if (!data->base) {
128 pr_err("failed to remap intc L2 registers\n");
129 ret = -ENOMEM;
130 goto out_free;
131 }
132
133 /* Disable all interrupts by default */
134 __raw_writel(0xffffffff, data->base + CPU_MASK_SET);
135 __raw_writel(0xffffffff, data->base + CPU_CLEAR);
136
137 data->parent_irq = irq_of_parse_and_map(np, 0);
138 if (data->parent_irq < 0) {
139 pr_err("failed to find parent interrupt\n");
140 ret = data->parent_irq;
141 goto out_unmap;
142 }
143
144 data->domain = irq_domain_add_linear(np, 32,
145 &irq_generic_chip_ops, NULL);
146 if (!data->domain) {
147 ret = -ENOMEM;
148 goto out_unmap;
149 }
150
151 /* Allocate a single Generic IRQ chip for this node */
152 ret = irq_alloc_domain_generic_chips(data->domain, 32, 1,
153 np->full_name, handle_level_irq, clr, 0, 0);
154 if (ret) {
155 pr_err("failed to allocate generic irq chip\n");
156 goto out_free_domain;
157 }
158
159 /* Set the IRQ chaining logic */
160 irq_set_handler_data(data->parent_irq, data);
161 irq_set_chained_handler(data->parent_irq, brcmstb_l2_intc_irq_handle);
162
163 gc = irq_get_domain_generic_chip(data->domain, 0);
164 gc->reg_base = data->base;
165 gc->private = data;
166 ct = gc->chip_types;
167
168 ct->chip.irq_ack = irq_gc_ack_set_bit;
169 ct->regs.ack = CPU_CLEAR;
170
171 ct->chip.irq_mask = irq_gc_mask_disable_reg;
172 ct->regs.disable = CPU_MASK_SET;
173
174 ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
175 ct->regs.enable = CPU_MASK_CLEAR;
176
177 ct->chip.irq_suspend = brcmstb_l2_intc_suspend;
178 ct->chip.irq_resume = brcmstb_l2_intc_resume;
179
180 if (of_property_read_bool(np, "brcm,irq-can-wake")) {
181 data->can_wake = true;
182 /* This IRQ chip can wake the system, set all child interrupts
183 * in wake_enabled mask
184 */
185 gc->wake_enabled = 0xffffffff;
186 ct->chip.irq_set_wake = irq_gc_set_wake;
187 }
188
189 pr_info("registered L2 intc (mem: 0x%p, parent irq: %d)\n",
190 data->base, data->parent_irq);
191
192 return 0;
193
194out_free_domain:
195 irq_domain_remove(data->domain);
196out_unmap:
197 iounmap(data->base);
198out_free:
199 kfree(data);
200 return ret;
201}
202IRQCHIP_DECLARE(brcmstb_l2_intc, "brcm,l2-intc", brcmstb_l2_intc_of_init);
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 57d165e026f4..7e11c9d6ae8c 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -291,7 +291,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
291 291
292 do { 292 do {
293 irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); 293 irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
294 irqnr = irqstat & ~0x1c00; 294 irqnr = irqstat & GICC_IAR_INT_ID_MASK;
295 295
296 if (likely(irqnr > 15 && irqnr < 1021)) { 296 if (likely(irqnr > 15 && irqnr < 1021)) {
297 irqnr = irq_find_mapping(gic->domain, irqnr); 297 irqnr = irq_find_mapping(gic->domain, irqnr);
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index 7e1c91d41a87..449011b0e007 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -1208,8 +1208,8 @@ static int tile_net_setup_interrupts(struct net_device *dev)
1208 1208
1209 irq = md->ingress_irq; 1209 irq = md->ingress_irq;
1210 if (irq < 0) { 1210 if (irq < 0) {
1211 irq = create_irq(); 1211 irq = irq_alloc_hwirq(-1);
1212 if (irq < 0) { 1212 if (!irq) {
1213 netdev_err(dev, 1213 netdev_err(dev,
1214 "create_irq failed: mpipe[%d] %d\n", 1214 "create_irq failed: mpipe[%d] %d\n",
1215 instance, irq); 1215 instance, irq);
@@ -1223,7 +1223,7 @@ static int tile_net_setup_interrupts(struct net_device *dev)
1223 if (rc != 0) { 1223 if (rc != 0) {
1224 netdev_err(dev, "request_irq failed: mpipe[%d] %d\n", 1224 netdev_err(dev, "request_irq failed: mpipe[%d] %d\n",
1225 instance, rc); 1225 instance, rc);
1226 destroy_irq(irq); 1226 irq_free_hwirq(irq);
1227 return rc; 1227 return rc;
1228 } 1228 }
1229 md->ingress_irq = irq; 1229 md->ingress_irq = irq;
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
index 6e373ea57b32..d68b030ab533 100644
--- a/drivers/pci/htirq.c
+++ b/drivers/pci/htirq.c
@@ -87,12 +87,9 @@ void unmask_ht_irq(struct irq_data *data)
87int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) 87int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
88{ 88{
89 struct ht_irq_cfg *cfg; 89 struct ht_irq_cfg *cfg;
90 int max_irq, pos, irq;
90 unsigned long flags; 91 unsigned long flags;
91 u32 data; 92 u32 data;
92 int max_irq;
93 int pos;
94 int irq;
95 int node;
96 93
97 pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ); 94 pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ);
98 if (!pos) 95 if (!pos)
@@ -120,10 +117,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
120 cfg->msg.address_lo = 0xffffffff; 117 cfg->msg.address_lo = 0xffffffff;
121 cfg->msg.address_hi = 0xffffffff; 118 cfg->msg.address_hi = 0xffffffff;
122 119
123 node = dev_to_node(&dev->dev); 120 irq = irq_alloc_hwirq(dev_to_node(&dev->dev));
124 irq = create_irq_nr(0, node); 121 if (!irq) {
125
126 if (irq <= 0) {
127 kfree(cfg); 122 kfree(cfg);
128 return -EBUSY; 123 return -EBUSY;
129 } 124 }
@@ -166,7 +161,7 @@ void ht_destroy_irq(unsigned int irq)
166 cfg = irq_get_handler_data(irq); 161 cfg = irq_get_handler_data(irq);
167 irq_set_chip(irq, NULL); 162 irq_set_chip(irq, NULL);
168 irq_set_handler_data(irq, NULL); 163 irq_set_handler_data(irq, NULL);
169 destroy_irq(irq); 164 irq_free_hwirq(irq);
170 165
171 kfree(cfg); 166 kfree(cfg);
172} 167}
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
index 8f32a1323a79..81f22980b2de 100644
--- a/drivers/sh/intc/core.c
+++ b/drivers/sh/intc/core.c
@@ -80,12 +80,6 @@ static void __init intc_register_irq(struct intc_desc *desc,
80 unsigned int data[2], primary; 80 unsigned int data[2], primary;
81 unsigned long flags; 81 unsigned long flags;
82 82
83 /*
84 * Register the IRQ position with the global IRQ map, then insert
85 * it in to the radix tree.
86 */
87 irq_reserve_irq(irq);
88
89 raw_spin_lock_irqsave(&intc_big_lock, flags); 83 raw_spin_lock_irqsave(&intc_big_lock, flags);
90 radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq)); 84 radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq));
91 raw_spin_unlock_irqrestore(&intc_big_lock, flags); 85 raw_spin_unlock_irqrestore(&intc_big_lock, flags);
diff --git a/drivers/tty/hvc/hvc_tile.c b/drivers/tty/hvc/hvc_tile.c
index af8cdaa1dcb9..147d49e95db2 100644
--- a/drivers/tty/hvc/hvc_tile.c
+++ b/drivers/tty/hvc/hvc_tile.c
@@ -133,14 +133,14 @@ static int hvc_tile_probe(struct platform_device *pdev)
133 int tile_hvc_irq; 133 int tile_hvc_irq;
134 134
135 /* Create our IRQ and register it. */ 135 /* Create our IRQ and register it. */
136 tile_hvc_irq = create_irq(); 136 tile_hvc_irq = irq_alloc_hwirq(-1);
137 if (tile_hvc_irq < 0) 137 if (!tile_hvc_irq)
138 return -ENXIO; 138 return -ENXIO;
139 139
140 tile_irq_activate(tile_hvc_irq, TILE_IRQ_PERCPU); 140 tile_irq_activate(tile_hvc_irq, TILE_IRQ_PERCPU);
141 hp = hvc_alloc(0, tile_hvc_irq, &hvc_tile_get_put_ops, 128); 141 hp = hvc_alloc(0, tile_hvc_irq, &hvc_tile_get_put_ops, 128);
142 if (IS_ERR(hp)) { 142 if (IS_ERR(hp)) {
143 destroy_irq(tile_hvc_irq); 143 irq_free_hwirq(tile_hvc_irq);
144 return PTR_ERR(hp); 144 return PTR_ERR(hp);
145 } 145 }
146 dev_set_drvdata(&pdev->dev, hp); 146 dev_set_drvdata(&pdev->dev, hp);
@@ -155,7 +155,7 @@ static int hvc_tile_remove(struct platform_device *pdev)
155 155
156 rc = hvc_remove(hp); 156 rc = hvc_remove(hp);
157 if (rc == 0) 157 if (rc == 0)
158 destroy_irq(hp->data); 158 irq_free_hwirq(hp->data);
159 159
160 return rc; 160 return rc;
161} 161}
diff --git a/drivers/tty/serial/tilegx.c b/drivers/tty/serial/tilegx.c
index f92d7e6bd876..613ccf09dc2a 100644
--- a/drivers/tty/serial/tilegx.c
+++ b/drivers/tty/serial/tilegx.c
@@ -359,8 +359,8 @@ static int tilegx_startup(struct uart_port *port)
359 } 359 }
360 360
361 /* Create our IRQs. */ 361 /* Create our IRQs. */
362 port->irq = create_irq(); 362 port->irq = irq_alloc_hwirq(-1);
363 if (port->irq < 0) 363 if (!port->irq)
364 goto err_uart_dest; 364 goto err_uart_dest;
365 tile_irq_activate(port->irq, TILE_IRQ_PERCPU); 365 tile_irq_activate(port->irq, TILE_IRQ_PERCPU);
366 366
@@ -395,7 +395,7 @@ static int tilegx_startup(struct uart_port *port)
395err_free_irq: 395err_free_irq:
396 free_irq(port->irq, port); 396 free_irq(port->irq, port);
397err_dest_irq: 397err_dest_irq:
398 destroy_irq(port->irq); 398 irq_free_hwirq(port->irq);
399err_uart_dest: 399err_uart_dest:
400 gxio_uart_destroy(context); 400 gxio_uart_destroy(context);
401 ret = -ENXIO; 401 ret = -ENXIO;
@@ -435,7 +435,7 @@ static void tilegx_shutdown(struct uart_port *port)
435 435
436 if (port->irq > 0) { 436 if (port->irq > 0) {
437 free_irq(port->irq, port); 437 free_irq(port->irq, port);
438 destroy_irq(port->irq); 438 irq_free_hwirq(port->irq);
439 port->irq = 0; 439 port->irq = 0;
440 } 440 }
441 441
diff --git a/drivers/usb/host/ehci-tilegx.c b/drivers/usb/host/ehci-tilegx.c
index f3713d32c9a1..0d247673c3ca 100644
--- a/drivers/usb/host/ehci-tilegx.c
+++ b/drivers/usb/host/ehci-tilegx.c
@@ -142,8 +142,8 @@ static int ehci_hcd_tilegx_drv_probe(struct platform_device *pdev)
142 ehci->hcs_params = readl(&ehci->caps->hcs_params); 142 ehci->hcs_params = readl(&ehci->caps->hcs_params);
143 143
144 /* Create our IRQs and register them. */ 144 /* Create our IRQs and register them. */
145 pdata->irq = create_irq(); 145 pdata->irq = irq_alloc_hwirq(-1);
146 if (pdata->irq < 0) { 146 if (!pdata->irq) {
147 ret = -ENXIO; 147 ret = -ENXIO;
148 goto err_no_irq; 148 goto err_no_irq;
149 } 149 }
@@ -175,7 +175,7 @@ static int ehci_hcd_tilegx_drv_probe(struct platform_device *pdev)
175 } 175 }
176 176
177err_have_irq: 177err_have_irq:
178 destroy_irq(pdata->irq); 178 irq_free_hwirq(pdata->irq);
179err_no_irq: 179err_no_irq:
180 tilegx_stop_ehc(); 180 tilegx_stop_ehc();
181 usb_put_hcd(hcd); 181 usb_put_hcd(hcd);
@@ -193,7 +193,7 @@ static int ehci_hcd_tilegx_drv_remove(struct platform_device *pdev)
193 usb_put_hcd(hcd); 193 usb_put_hcd(hcd);
194 tilegx_stop_ehc(); 194 tilegx_stop_ehc();
195 gxio_usb_host_destroy(&pdata->usb_ctx); 195 gxio_usb_host_destroy(&pdata->usb_ctx);
196 destroy_irq(pdata->irq); 196 irq_free_hwirq(pdata->irq);
197 197
198 return 0; 198 return 0;
199} 199}
diff --git a/drivers/usb/host/ohci-tilegx.c b/drivers/usb/host/ohci-tilegx.c
index 0b183e0b0a8a..bef6dfb0405a 100644
--- a/drivers/usb/host/ohci-tilegx.c
+++ b/drivers/usb/host/ohci-tilegx.c
@@ -129,8 +129,8 @@ static int ohci_hcd_tilegx_drv_probe(struct platform_device *pdev)
129 tilegx_start_ohc(); 129 tilegx_start_ohc();
130 130
131 /* Create our IRQs and register them. */ 131 /* Create our IRQs and register them. */
132 pdata->irq = create_irq(); 132 pdata->irq = irq_alloc_hwirq(-1);
133 if (pdata->irq < 0) { 133 if (!pdata->irq) {
134 ret = -ENXIO; 134 ret = -ENXIO;
135 goto err_no_irq; 135 goto err_no_irq;
136 } 136 }
@@ -164,7 +164,7 @@ static int ohci_hcd_tilegx_drv_probe(struct platform_device *pdev)
164 } 164 }
165 165
166err_have_irq: 166err_have_irq:
167 destroy_irq(pdata->irq); 167 irq_free_hwirq(pdata->irq);
168err_no_irq: 168err_no_irq:
169 tilegx_stop_ohc(); 169 tilegx_stop_ohc();
170 usb_put_hcd(hcd); 170 usb_put_hcd(hcd);
@@ -182,7 +182,7 @@ static int ohci_hcd_tilegx_drv_remove(struct platform_device *pdev)
182 usb_put_hcd(hcd); 182 usb_put_hcd(hcd);
183 tilegx_stop_ohc(); 183 tilegx_stop_ohc();
184 gxio_usb_host_destroy(&pdata->usb_ctx); 184 gxio_usb_host_destroy(&pdata->usb_ctx);
185 destroy_irq(pdata->irq); 185 irq_free_hwirq(pdata->irq);
186 186
187 return 0; 187 return 0;
188} 188}
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index dfa12a4a0a48..c919d3d5c845 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -390,22 +390,7 @@ static void xen_irq_init(unsigned irq)
390 390
391static int __must_check xen_allocate_irqs_dynamic(int nvec) 391static int __must_check xen_allocate_irqs_dynamic(int nvec)
392{ 392{
393 int first = 0; 393 int i, irq = irq_alloc_descs(-1, 0, nvec, -1);
394 int i, irq;
395
396#ifdef CONFIG_X86_IO_APIC
397 /*
398 * For an HVM guest or domain 0 which see "real" (emulated or
399 * actual respectively) GSIs we allocate dynamic IRQs
400 * e.g. those corresponding to event channels or MSIs
401 * etc. from the range above those "real" GSIs to avoid
402 * collisions.
403 */
404 if (xen_initial_domain() || xen_hvm_domain())
405 first = get_nr_irqs_gsi();
406#endif
407
408 irq = irq_alloc_descs_from(first, nvec, -1);
409 394
410 if (irq >= 0) { 395 if (irq >= 0) {
411 for (i = 0; i < nvec; i++) 396 for (i = 0; i < nvec; i++)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index cb19f09d7e3e..698ad053d064 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -199,6 +199,26 @@ extern int check_wakeup_irqs(void);
199static inline int check_wakeup_irqs(void) { return 0; } 199static inline int check_wakeup_irqs(void) { return 0; }
200#endif 200#endif
201 201
202/**
203 * struct irq_affinity_notify - context for notification of IRQ affinity changes
204 * @irq: Interrupt to which notification applies
205 * @kref: Reference count, for internal use
206 * @work: Work item, for internal use
207 * @notify: Function to be called on change. This will be
208 * called in process context.
209 * @release: Function to be called on release. This will be
210 * called in process context. Once registered, the
211 * structure must only be freed when this function is
212 * called or later.
213 */
214struct irq_affinity_notify {
215 unsigned int irq;
216 struct kref kref;
217 struct work_struct work;
218 void (*notify)(struct irq_affinity_notify *, const cpumask_t *mask);
219 void (*release)(struct kref *ref);
220};
221
202#if defined(CONFIG_SMP) 222#if defined(CONFIG_SMP)
203 223
204extern cpumask_var_t irq_default_affinity; 224extern cpumask_var_t irq_default_affinity;
@@ -242,26 +262,6 @@ extern int irq_select_affinity(unsigned int irq);
242 262
243extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m); 263extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m);
244 264
245/**
246 * struct irq_affinity_notify - context for notification of IRQ affinity changes
247 * @irq: Interrupt to which notification applies
248 * @kref: Reference count, for internal use
249 * @work: Work item, for internal use
250 * @notify: Function to be called on change. This will be
251 * called in process context.
252 * @release: Function to be called on release. This will be
253 * called in process context. Once registered, the
254 * structure must only be freed when this function is
255 * called or later.
256 */
257struct irq_affinity_notify {
258 unsigned int irq;
259 struct kref kref;
260 struct work_struct work;
261 void (*notify)(struct irq_affinity_notify *, const cpumask_t *mask);
262 void (*release)(struct kref *ref);
263};
264
265extern int 265extern int
266irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify); 266irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify);
267 267
@@ -289,6 +289,12 @@ static inline int irq_set_affinity_hint(unsigned int irq,
289{ 289{
290 return -EINVAL; 290 return -EINVAL;
291} 291}
292
293static inline int
294irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)
295{
296 return 0;
297}
292#endif /* CONFIG_SMP */ 298#endif /* CONFIG_SMP */
293 299
294/* 300/*
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 5c57efb863d0..0d998d8b01d8 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -525,24 +525,6 @@ static inline void irq_set_percpu_devid_flags(unsigned int irq)
525 IRQ_NOPROBE | IRQ_PER_CPU_DEVID); 525 IRQ_NOPROBE | IRQ_PER_CPU_DEVID);
526} 526}
527 527
528/* Handle dynamic irq creation and destruction */
529extern unsigned int create_irq_nr(unsigned int irq_want, int node);
530extern unsigned int __create_irqs(unsigned int from, unsigned int count,
531 int node);
532extern int create_irq(void);
533extern void destroy_irq(unsigned int irq);
534extern void destroy_irqs(unsigned int irq, unsigned int count);
535
536/*
537 * Dynamic irq helper functions. Obsolete. Use irq_alloc_desc* and
538 * irq_free_desc instead.
539 */
540extern void dynamic_irq_cleanup(unsigned int irq);
541static inline void dynamic_irq_init(unsigned int irq)
542{
543 dynamic_irq_cleanup(irq);
544}
545
546/* Set/get chip/data for an IRQ: */ 528/* Set/get chip/data for an IRQ: */
547extern int irq_set_chip(unsigned int irq, struct irq_chip *chip); 529extern int irq_set_chip(unsigned int irq, struct irq_chip *chip);
548extern int irq_set_handler_data(unsigned int irq, void *data); 530extern int irq_set_handler_data(unsigned int irq, void *data);
@@ -625,17 +607,29 @@ int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
625 irq_alloc_descs(-1, from, cnt, node) 607 irq_alloc_descs(-1, from, cnt, node)
626 608
627void irq_free_descs(unsigned int irq, unsigned int cnt); 609void irq_free_descs(unsigned int irq, unsigned int cnt);
628int irq_reserve_irqs(unsigned int from, unsigned int cnt);
629
630static inline void irq_free_desc(unsigned int irq) 610static inline void irq_free_desc(unsigned int irq)
631{ 611{
632 irq_free_descs(irq, 1); 612 irq_free_descs(irq, 1);
633} 613}
634 614
635static inline int irq_reserve_irq(unsigned int irq) 615#ifdef CONFIG_GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
616unsigned int irq_alloc_hwirqs(int cnt, int node);
617static inline unsigned int irq_alloc_hwirq(int node)
618{
619 return irq_alloc_hwirqs(1, node);
620}
621void irq_free_hwirqs(unsigned int from, int cnt);
622static inline void irq_free_hwirq(unsigned int irq)
636{ 623{
637 return irq_reserve_irqs(irq, 1); 624 return irq_free_hwirqs(irq, 1);
638} 625}
626int arch_setup_hwirq(unsigned int irq, int node);
627void arch_teardown_hwirq(unsigned int irq);
628#endif
629
630#ifdef CONFIG_GENERIC_IRQ_LEGACY
631void irq_init_desc(unsigned int irq);
632#endif
639 633
640#ifndef irq_reg_writel 634#ifndef irq_reg_writel
641# define irq_reg_writel(val, addr) writel(val, addr) 635# define irq_reg_writel(val, addr) writel(val, addr)
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 7ed92d0560d5..45e2d8c15bd2 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -21,6 +21,8 @@
21#define GIC_CPU_ACTIVEPRIO 0xd0 21#define GIC_CPU_ACTIVEPRIO 0xd0
22#define GIC_CPU_IDENT 0xfc 22#define GIC_CPU_IDENT 0xfc
23 23
24#define GICC_IAR_INT_ID_MASK 0x3ff
25
24#define GIC_DIST_CTRL 0x000 26#define GIC_DIST_CTRL 0x000
25#define GIC_DIST_CTR 0x004 27#define GIC_DIST_CTR 0x004
26#define GIC_DIST_IGROUP 0x080 28#define GIC_DIST_IGROUP 0x080
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 26e2661d3935..472c021a2d4f 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -27,6 +27,8 @@ struct irq_desc;
27 * @irq_count: stats field to detect stalled irqs 27 * @irq_count: stats field to detect stalled irqs
28 * @last_unhandled: aging timer for unhandled count 28 * @last_unhandled: aging timer for unhandled count
29 * @irqs_unhandled: stats field for spurious unhandled interrupts 29 * @irqs_unhandled: stats field for spurious unhandled interrupts
30 * @threads_handled: stats field for deferred spurious detection of threaded handlers
31 * @threads_handled_last: comparator field for deferred spurious detection of theraded handlers
30 * @lock: locking for SMP 32 * @lock: locking for SMP
31 * @affinity_hint: hint to user space for preferred irq affinity 33 * @affinity_hint: hint to user space for preferred irq affinity
32 * @affinity_notify: context for notification of affinity changes 34 * @affinity_notify: context for notification of affinity changes
@@ -52,6 +54,8 @@ struct irq_desc {
52 unsigned int irq_count; /* For detecting broken IRQs */ 54 unsigned int irq_count; /* For detecting broken IRQs */
53 unsigned long last_unhandled; /* Aging timer for unhandled count */ 55 unsigned long last_unhandled; /* Aging timer for unhandled count */
54 unsigned int irqs_unhandled; 56 unsigned int irqs_unhandled;
57 atomic_t threads_handled;
58 int threads_handled_last;
55 raw_spinlock_t lock; 59 raw_spinlock_t lock;
56 struct cpumask *percpu_enabled; 60 struct cpumask *percpu_enabled;
57#ifdef CONFIG_SMP 61#ifdef CONFIG_SMP
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 07cbdfea9ae2..d269cecdfbf0 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -5,6 +5,10 @@ menu "IRQ subsystem"
5config MAY_HAVE_SPARSE_IRQ 5config MAY_HAVE_SPARSE_IRQ
6 bool 6 bool
7 7
8# Legacy support, required for itanic
9config GENERIC_IRQ_LEGACY
10 bool
11
8# Enable the generic irq autoprobe mechanism 12# Enable the generic irq autoprobe mechanism
9config GENERIC_IRQ_PROBE 13config GENERIC_IRQ_PROBE
10 bool 14 bool
@@ -17,6 +21,11 @@ config GENERIC_IRQ_SHOW
17config GENERIC_IRQ_SHOW_LEVEL 21config GENERIC_IRQ_SHOW_LEVEL
18 bool 22 bool
19 23
24# Facility to allocate a hardware interrupt. This is legacy support
25# and should not be used in new code. Use irq domains instead.
26config GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
27 bool
28
20# Support for delayed migration from interrupt context 29# Support for delayed migration from interrupt context
21config GENERIC_PENDING_IRQ 30config GENERIC_PENDING_IRQ
22 bool 31 bool
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 6397df2d6945..a2b28a2fd7b1 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -40,10 +40,9 @@ int irq_set_chip(unsigned int irq, struct irq_chip *chip)
40 irq_put_desc_unlock(desc, flags); 40 irq_put_desc_unlock(desc, flags);
41 /* 41 /*
42 * For !CONFIG_SPARSE_IRQ make the irq show up in 42 * For !CONFIG_SPARSE_IRQ make the irq show up in
43 * allocated_irqs. For the CONFIG_SPARSE_IRQ case, it is 43 * allocated_irqs.
44 * already marked, and this call is harmless.
45 */ 44 */
46 irq_reserve_irq(irq); 45 irq_mark_irq(irq);
47 return 0; 46 return 0;
48} 47}
49EXPORT_SYMBOL(irq_set_chip); 48EXPORT_SYMBOL(irq_set_chip);
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index ddf1ffeb79f1..099ea2e0eb88 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -33,7 +33,7 @@ enum {
33}; 33};
34 34
35/* 35/*
36 * Bit masks for desc->state 36 * Bit masks for desc->core_internal_state__do_not_mess_with_it
37 * 37 *
38 * IRQS_AUTODETECT - autodetection in progress 38 * IRQS_AUTODETECT - autodetection in progress
39 * IRQS_SPURIOUS_DISABLED - was disabled due to spurious interrupt 39 * IRQS_SPURIOUS_DISABLED - was disabled due to spurious interrupt
@@ -76,6 +76,12 @@ extern void mask_irq(struct irq_desc *desc);
76extern void unmask_irq(struct irq_desc *desc); 76extern void unmask_irq(struct irq_desc *desc);
77extern void unmask_threaded_irq(struct irq_desc *desc); 77extern void unmask_threaded_irq(struct irq_desc *desc);
78 78
79#ifdef CONFIG_SPARSE_IRQ
80static inline void irq_mark_irq(unsigned int irq) { }
81#else
82extern void irq_mark_irq(unsigned int irq);
83#endif
84
79extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr); 85extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
80 86
81irqreturn_t handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action); 87irqreturn_t handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action);
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index bb07f2928f4b..7339e42a85ab 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -278,7 +278,12 @@ EXPORT_SYMBOL(irq_to_desc);
278 278
279static void free_desc(unsigned int irq) 279static void free_desc(unsigned int irq)
280{ 280{
281 dynamic_irq_cleanup(irq); 281 struct irq_desc *desc = irq_to_desc(irq);
282 unsigned long flags;
283
284 raw_spin_lock_irqsave(&desc->lock, flags);
285 desc_set_defaults(irq, desc, desc_node(desc), NULL);
286 raw_spin_unlock_irqrestore(&desc->lock, flags);
282} 287}
283 288
284static inline int alloc_descs(unsigned int start, unsigned int cnt, int node, 289static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,
@@ -299,6 +304,20 @@ static int irq_expand_nr_irqs(unsigned int nr)
299 return -ENOMEM; 304 return -ENOMEM;
300} 305}
301 306
307void irq_mark_irq(unsigned int irq)
308{
309 mutex_lock(&sparse_irq_lock);
310 bitmap_set(allocated_irqs, irq, 1);
311 mutex_unlock(&sparse_irq_lock);
312}
313
314#ifdef CONFIG_GENERIC_IRQ_LEGACY
315void irq_init_desc(unsigned int irq)
316{
317 free_desc(irq);
318}
319#endif
320
302#endif /* !CONFIG_SPARSE_IRQ */ 321#endif /* !CONFIG_SPARSE_IRQ */
303 322
304/** 323/**
@@ -396,30 +415,56 @@ err:
396} 415}
397EXPORT_SYMBOL_GPL(__irq_alloc_descs); 416EXPORT_SYMBOL_GPL(__irq_alloc_descs);
398 417
418#ifdef CONFIG_GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
399/** 419/**
400 * irq_reserve_irqs - mark irqs allocated 420 * irq_alloc_hwirqs - Allocate an irq descriptor and initialize the hardware
401 * @from: mark from irq number 421 * @cnt: number of interrupts to allocate
402 * @cnt: number of irqs to mark 422 * @node: node on which to allocate
403 * 423 *
404 * Returns 0 on success or an appropriate error code 424 * Returns an interrupt number > 0 or 0, if the allocation fails.
405 */ 425 */
406int irq_reserve_irqs(unsigned int from, unsigned int cnt) 426unsigned int irq_alloc_hwirqs(int cnt, int node)
407{ 427{
408 unsigned int start; 428 int i, irq = __irq_alloc_descs(-1, 0, cnt, node, NULL);
409 int ret = 0;
410 429
411 if (!cnt || (from + cnt) > nr_irqs) 430 if (irq < 0)
412 return -EINVAL; 431 return 0;
413 432
414 mutex_lock(&sparse_irq_lock); 433 for (i = irq; cnt > 0; i++, cnt--) {
415 start = bitmap_find_next_zero_area(allocated_irqs, nr_irqs, from, cnt, 0); 434 if (arch_setup_hwirq(i, node))
416 if (start == from) 435 goto err;
417 bitmap_set(allocated_irqs, start, cnt); 436 irq_clear_status_flags(i, _IRQ_NOREQUEST);
418 else 437 }
419 ret = -EEXIST; 438 return irq;
420 mutex_unlock(&sparse_irq_lock); 439
421 return ret; 440err:
441 for (i--; i >= irq; i--) {
442 irq_set_status_flags(i, _IRQ_NOREQUEST | _IRQ_NOPROBE);
443 arch_teardown_hwirq(i);
444 }
445 irq_free_descs(irq, cnt);
446 return 0;
447}
448EXPORT_SYMBOL_GPL(irq_alloc_hwirqs);
449
450/**
451 * irq_free_hwirqs - Free irq descriptor and cleanup the hardware
452 * @from: Free from irq number
453 * @cnt: number of interrupts to free
454 *
455 */
456void irq_free_hwirqs(unsigned int from, int cnt)
457{
458 int i;
459
460 for (i = from; cnt > 0; i++, cnt--) {
461 irq_set_status_flags(i, _IRQ_NOREQUEST | _IRQ_NOPROBE);
462 arch_teardown_hwirq(i);
463 }
464 irq_free_descs(from, cnt);
422} 465}
466EXPORT_SYMBOL_GPL(irq_free_hwirqs);
467#endif
423 468
424/** 469/**
425 * irq_get_next_irq - get next allocated irq number 470 * irq_get_next_irq - get next allocated irq number
@@ -482,20 +527,6 @@ int irq_set_percpu_devid(unsigned int irq)
482 return 0; 527 return 0;
483} 528}
484 529
485/**
486 * dynamic_irq_cleanup - cleanup a dynamically allocated irq
487 * @irq: irq number to initialize
488 */
489void dynamic_irq_cleanup(unsigned int irq)
490{
491 struct irq_desc *desc = irq_to_desc(irq);
492 unsigned long flags;
493
494 raw_spin_lock_irqsave(&desc->lock, flags);
495 desc_set_defaults(irq, desc, desc_node(desc), NULL);
496 raw_spin_unlock_irqrestore(&desc->lock, flags);
497}
498
499void kstat_incr_irq_this_cpu(unsigned int irq) 530void kstat_incr_irq_this_cpu(unsigned int irq)
500{ 531{
501 kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); 532 kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index f14033700c25..eb5e10e32e05 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -27,14 +27,14 @@ static struct irq_domain *irq_default_domain;
27 * __irq_domain_add() - Allocate a new irq_domain data structure 27 * __irq_domain_add() - Allocate a new irq_domain data structure
28 * @of_node: optional device-tree node of the interrupt controller 28 * @of_node: optional device-tree node of the interrupt controller
29 * @size: Size of linear map; 0 for radix mapping only 29 * @size: Size of linear map; 0 for radix mapping only
30 * @hwirq_max: Maximum number of interrupts supported by controller
30 * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no 31 * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no
31 * direct mapping 32 * direct mapping
32 * @ops: map/unmap domain callbacks 33 * @ops: map/unmap domain callbacks
33 * @host_data: Controller private data pointer 34 * @host_data: Controller private data pointer
34 * 35 *
35 * Allocates and initialize and irq_domain structure. Caller is expected to 36 * Allocates and initialize and irq_domain structure.
36 * register allocated irq_domain with irq_domain_register(). Returns pointer 37 * Returns pointer to IRQ domain, or NULL on failure.
37 * to IRQ domain, or NULL on failure.
38 */ 38 */
39struct irq_domain *__irq_domain_add(struct device_node *of_node, int size, 39struct irq_domain *__irq_domain_add(struct device_node *of_node, int size,
40 irq_hw_number_t hwirq_max, int direct_max, 40 irq_hw_number_t hwirq_max, int direct_max,
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index d34131ca372b..3dc6a61bf06a 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -886,8 +886,8 @@ static int irq_thread(void *data)
886 irq_thread_check_affinity(desc, action); 886 irq_thread_check_affinity(desc, action);
887 887
888 action_ret = handler_fn(desc, action); 888 action_ret = handler_fn(desc, action);
889 if (!noirqdebug) 889 if (action_ret == IRQ_HANDLED)
890 note_interrupt(action->irq, desc, action_ret); 890 atomic_inc(&desc->threads_handled);
891 891
892 wake_threads_waitq(desc); 892 wake_threads_waitq(desc);
893 } 893 }
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index a1d8cc63b56e..e2514b0e439e 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -270,6 +270,8 @@ try_misrouted_irq(unsigned int irq, struct irq_desc *desc,
270 return action && (action->flags & IRQF_IRQPOLL); 270 return action && (action->flags & IRQF_IRQPOLL);
271} 271}
272 272
273#define SPURIOUS_DEFERRED 0x80000000
274
273void note_interrupt(unsigned int irq, struct irq_desc *desc, 275void note_interrupt(unsigned int irq, struct irq_desc *desc,
274 irqreturn_t action_ret) 276 irqreturn_t action_ret)
275{ 277{
@@ -277,15 +279,111 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
277 irq_settings_is_polled(desc)) 279 irq_settings_is_polled(desc))
278 return; 280 return;
279 281
280 /* we get here again via the threaded handler */
281 if (action_ret == IRQ_WAKE_THREAD)
282 return;
283
284 if (bad_action_ret(action_ret)) { 282 if (bad_action_ret(action_ret)) {
285 report_bad_irq(irq, desc, action_ret); 283 report_bad_irq(irq, desc, action_ret);
286 return; 284 return;
287 } 285 }
288 286
287 /*
288 * We cannot call note_interrupt from the threaded handler
289 * because we need to look at the compound of all handlers
290 * (primary and threaded). Aside of that in the threaded
291 * shared case we have no serialization against an incoming
292 * hardware interrupt while we are dealing with a threaded
293 * result.
294 *
295 * So in case a thread is woken, we just note the fact and
296 * defer the analysis to the next hardware interrupt.
297 *
298 * The threaded handlers store whether they sucessfully
299 * handled an interrupt and we check whether that number
300 * changed versus the last invocation.
301 *
302 * We could handle all interrupts with the delayed by one
303 * mechanism, but for the non forced threaded case we'd just
304 * add pointless overhead to the straight hardirq interrupts
305 * for the sake of a few lines less code.
306 */
307 if (action_ret & IRQ_WAKE_THREAD) {
308 /*
309 * There is a thread woken. Check whether one of the
310 * shared primary handlers returned IRQ_HANDLED. If
311 * not we defer the spurious detection to the next
312 * interrupt.
313 */
314 if (action_ret == IRQ_WAKE_THREAD) {
315 int handled;
316 /*
317 * We use bit 31 of thread_handled_last to
318 * denote the deferred spurious detection
319 * active. No locking necessary as
320 * thread_handled_last is only accessed here
321 * and we have the guarantee that hard
322 * interrupts are not reentrant.
323 */
324 if (!(desc->threads_handled_last & SPURIOUS_DEFERRED)) {
325 desc->threads_handled_last |= SPURIOUS_DEFERRED;
326 return;
327 }
328 /*
329 * Check whether one of the threaded handlers
330 * returned IRQ_HANDLED since the last
331 * interrupt happened.
332 *
333 * For simplicity we just set bit 31, as it is
334 * set in threads_handled_last as well. So we
335 * avoid extra masking. And we really do not
336 * care about the high bits of the handled
337 * count. We just care about the count being
338 * different than the one we saw before.
339 */
340 handled = atomic_read(&desc->threads_handled);
341 handled |= SPURIOUS_DEFERRED;
342 if (handled != desc->threads_handled_last) {
343 action_ret = IRQ_HANDLED;
344 /*
345 * Note: We keep the SPURIOUS_DEFERRED
346 * bit set. We are handling the
347 * previous invocation right now.
348 * Keep it for the current one, so the
349 * next hardware interrupt will
350 * account for it.
351 */
352 desc->threads_handled_last = handled;
353 } else {
354 /*
355 * None of the threaded handlers felt
356 * responsible for the last interrupt
357 *
358 * We keep the SPURIOUS_DEFERRED bit
359 * set in threads_handled_last as we
360 * need to account for the current
361 * interrupt as well.
362 */
363 action_ret = IRQ_NONE;
364 }
365 } else {
366 /*
367 * One of the primary handlers returned
368 * IRQ_HANDLED. So we don't care about the
369 * threaded handlers on the same line. Clear
370 * the deferred detection bit.
371 *
372 * In theory we could/should check whether the
373 * deferred bit is set and take the result of
374 * the previous run into account here as
375 * well. But it's really not worth the
376 * trouble. If every other interrupt is
377 * handled we never trigger the spurious
378 * detector. And if this is just the one out
379 * of 100k unhandled ones which is handled
380 * then we merily delay the spurious detection
381 * by one hard interrupt. Not a real problem.
382 */
383 desc->threads_handled_last &= ~SPURIOUS_DEFERRED;
384 }
385 }
386
289 if (unlikely(action_ret == IRQ_NONE)) { 387 if (unlikely(action_ret == IRQ_NONE)) {
290 /* 388 /*
291 * If we are seeing only the odd spurious IRQ caused by 389 * If we are seeing only the odd spurious IRQ caused by