diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-05-07 15:44:04 +0000 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2014-05-16 14:05:18 +0200 |
commit | 37ebbcff78375bfa69eb69748ef00f577b7c1c6c (patch) | |
tree | 6881b33163a27f0cd233178af737590edaf76378 | |
parent | 67bb90fd743ecf637f2e36eb9a39afcad08ef523 (diff) | |
download | lwn-37ebbcff78375bfa69eb69748ef00f577b7c1c6c.tar.gz lwn-37ebbcff78375bfa69eb69748ef00f577b7c1c6c.zip |
arm: iop13xx: Use sparse irqs for MSI
No need for a private allocator. The core code handles it
already.
Allocate the non MSI irqs right at boot time via machine_desc->nr_irqs
and let the sparse core handle the MSI space.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Grant Likely <grant.likely@linaro.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/20140507154333.809210026@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/include/mach/irqs.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/include/mach/time.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/iq81340mc.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/iq81340sc.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/msi.c | 51 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/setup.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/tpmi.c | 1 |
8 files changed, 19 insertions, 42 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index db3c5414223e..a2c1a18a7275 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -480,6 +480,7 @@ config ARCH_IOP13XX select PCI select PLAT_IOP select VMSPLIT_1G + select SPARSE_IRQ help Support for Intel's IOP13XX (XScale) family of processors. 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) #define NR_IOP13XX_IRQS (IRQ_IOP13XX_HPI + 1) #endif -#define NR_IRQS NR_IOP13XX_IRQS - #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 @@ #ifndef _IOP13XX_TIME_H_ #define _IOP13XX_TIME_H_ + +#include <mach/irqs.h> + #define IRQ_IOP_TIMER0 IRQ_IOP13XX_TIMER0 #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") .init_time = iq81340mc_timer_init, .init_machine = iq81340mc_init, .restart = iop13xx_restart, + .nr_irqs = NR_IOP13XX_IRQS, MACHINE_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") .init_time = iq81340sc_timer_init, .init_machine = iq81340sc_init, .restart = iop13xx_restart, + .nr_irqs = NR_IOP13XX_IRQS, MACHINE_END diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c index 560d5b2dec22..655072dd9fe8 100644 --- a/arch/arm/mach-iop13xx/msi.c +++ b/arch/arm/mach-iop13xx/msi.c @@ -24,10 +24,6 @@ #include <asm/mach/irq.h> #include <asm/irq.h> - -#define IOP13XX_NUM_MSI_IRQS 128 -static DECLARE_BITMAP(msi_irq_in_use, IOP13XX_NUM_MSI_IRQS); - /* IMIPR0 CP6 R8 Page 1 */ static u32 read_imipr_0(void) @@ -121,41 +117,6 @@ void __init iop13xx_msi_init(void) irq_set_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler); } -/* - * Dynamic irq allocate and deallocation - */ -int create_irq(void) -{ - int irq, pos; - -again: - pos = find_first_zero_bit(msi_irq_in_use, IOP13XX_NUM_MSI_IRQS); - irq = IRQ_IOP13XX_MSI_0 + pos; - if (irq > NR_IRQS) - return -ENOSPC; - /* test_and_set_bit operates on 32-bits at a time */ - if (test_and_set_bit(pos, msi_irq_in_use)) - goto again; - - dynamic_irq_init(irq); - - return irq; -} - -void destroy_irq(unsigned int irq) -{ - int pos = irq - IRQ_IOP13XX_MSI_0; - - dynamic_irq_cleanup(irq); - - clear_bit(pos, msi_irq_in_use); -} - -void arch_teardown_msi_irq(unsigned int irq) -{ - destroy_irq(irq); -} - static void iop13xx_msi_nop(struct irq_data *d) { return; @@ -172,12 +133,17 @@ static struct irq_chip iop13xx_msi_chip = { int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) { - int id, irq = create_irq(); + int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1); struct msi_msg msg; if (irq < 0) return irq; + if (irq >= NR_IOP13XX_IRQS) { + irq_free_desc(irq); + return -ENOSPC; + } + irq_set_msi_desc(irq, desc); msg.address_hi = 0x0; @@ -191,3 +157,8 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) return 0; } + +void arch_teardown_msi_irq(unsigned int irq) +{ + irq_free_desc(irq); +} 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 @@ #include <mach/hardware.h> #include <asm/irq.h> #include <asm/hardware/iop_adma.h> +#include <mach/irqs.h> #define IOP13XX_UART_XTAL 33334000 #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 @@ #include <linux/io.h> #include <asm/irq.h> #include <asm/sizes.h> +#include <mach/irqs.h> /* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */ #define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12)) |