aboutsummaryrefslogtreecommitdiffstats
path: root/arch
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 /arch
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() ...
Diffstat (limited to 'arch')
-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
28 files changed, 88 insertions, 245 deletions
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);