diff options
| author | Russell King <rmk@flint.arm.linux.org.uk> | 2003-05-13 17:40:41 +0100 |
|---|---|---|
| committer | Russell King <rmk@flint.arm.linux.org.uk> | 2003-05-13 17:40:41 +0100 |
| commit | 2febe49d11d8ba8af8fc51fb4be0e6e295ad7fdb (patch) | |
| tree | 37de67f45e5aa72fc4c3a1ee84fe24c25f0ce66b | |
| parent | c85c822d901a657f926da2dd9064fde1a81e8149 (diff) | |
[ARM PATCH] 1530/1: PXA2xx IRQ handling updates
From: Nicolas Pitre.
(manual entry since bk openlogging crapped out again)
| -rw-r--r-- | arch/arm/kernel/entry-armv.S | 2 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/irq.c | 22 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/lubbock.c | 50 | ||||
| -rw-r--r-- | include/asm-arm/arch-pxa/irqs.h | 5 |
4 files changed, 31 insertions, 48 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 4a4941676330..dfb295004ea1 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -621,7 +621,7 @@ ENTRY(anakin_active_irqs) rsb \irqstat, \irqnr, #0 and \irqstat, \irqstat, \irqnr clz \irqnr, \irqstat - rsb \irqnr, \irqnr, #23 + rsb \irqnr, \irqnr, #(31 - PXA_IRQ_SKIP) 1001: .endm diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 1f443317e2c1..674cb381f8c0 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -50,9 +50,9 @@ static struct irqchip pxa_internal_chip = { * Use this instead of directly setting GRER/GFER. */ -static int GPIO_IRQ_rising_edge[3]; -static int GPIO_IRQ_falling_edge[3]; -static int GPIO_IRQ_mask[3]; +static long GPIO_IRQ_rising_edge[3]; +static long GPIO_IRQ_falling_edge[3]; +static long GPIO_IRQ_mask[3]; static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) { @@ -189,7 +189,6 @@ static struct irqchip pxa_muxed_gpio_chip = { .ack = pxa_ack_muxed_gpio, .mask = pxa_mask_muxed_gpio, .unmask = pxa_unmask_muxed_gpio, - .rerun = pxa_manual_rerun, .type = pxa_gpio_irq_type, }; @@ -217,21 +216,18 @@ void __init pxa_init_irq(void) /* GPIO 0 and 1 must have their mask bit always set */ GPIO_IRQ_mask[0] = 3; + for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) { + set_irq_chip(irq, &pxa_internal_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID); + } + for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { set_irq_chip(irq, &pxa_low_gpio_chip); set_irq_handler(irq, do_edge_IRQ); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - for (irq = PXA_IRQ(11); irq <= PXA_IRQ(31); irq++) { - set_irq_chip(irq, &pxa_internal_chip); - set_irq_handler(irq, do_level_IRQ); - set_irq_flags(irq, IRQF_VALID); - } - /* Those are reserved */ - set_irq_flags(PXA_IRQ(15), 0); - set_irq_flags(PXA_IRQ(16), 0); - for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(80); irq++) { set_irq_chip(irq, &pxa_muxed_gpio_chip); set_irq_handler(irq, do_edge_IRQ); diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 185a703a1abb..e69ec2a5b739 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -33,57 +33,41 @@ #include "generic.h" -static void lubbock_ack_irq(unsigned int irq) -{ - int lubbock_irq = (irq - LUBBOCK_IRQ(0)); - LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq); -} + +static unsigned long lubbock_irq_enabled; static void lubbock_mask_irq(unsigned int irq) { int lubbock_irq = (irq - LUBBOCK_IRQ(0)); - LUB_IRQ_MASK_EN &= ~(1 << lubbock_irq); + LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq)); } static void lubbock_unmask_irq(unsigned int irq) { int lubbock_irq = (irq - LUBBOCK_IRQ(0)); - LUB_IRQ_MASK_EN |= (1 << lubbock_irq); + /* the irq can be acknowledged only if deasserted, so it's done here */ + LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq); + LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq)); } static struct irqchip lubbock_irq_chip = { - .ack = lubbock_ack_irq, + .ack = lubbock_mask_irq, .mask = lubbock_mask_irq, .unmask = lubbock_unmask_irq, }; -void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc, - struct pt_regs *regs) +static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { - unsigned int enabled, pending; - - /* get active pending irq mask */ - enabled = LUB_IRQ_MASK_EN & 0x003f; - pending = LUB_IRQ_SET_CLR & enabled; - + unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; do { -//printk("%s a: set_clr %#x, mask_en %#x LR/DR %d/%d\n", __FUNCTION__, LUB_IRQ_SET_CLR, LUB_IRQ_MASK_EN, GPLR(0)&1, GEDR(0)&1 ); - /* clear our parent irq */ - GEDR(0) = GPIO_bit(0); - - /* process them */ - irq = LUBBOCK_IRQ(0); - desc = irq_desc + irq; - do { - if (pending & 1) - desc->handle(irq, desc, regs); - irq++; - desc++; - pending >>= 1; - } while (pending); -//printk("%s b: set_clr %#x, mask_en %#x LR/DR %d/%d\n", __FUNCTION__, LUB_IRQ_SET_CLR, LUB_IRQ_MASK_EN, GPLR(0)&1, GEDR(0)&1 ); - enabled = LUB_IRQ_MASK_EN & 0x003f; - pending = LUB_IRQ_SET_CLR & enabled; + GEDR(0) = GPIO_bit(0); /* clear our parent irq */ + if (likely(pending)) { + irq = LUBBOCK_IRQ(0) + __ffs(pending); + desc = irq_desc + irq; + desc->handle(irq, desc, regs); + } + pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; } while (pending); } diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h index 54d78076afd4..6d452434eabc 100644 --- a/include/asm-arm/arch-pxa/irqs.h +++ b/include/asm-arm/arch-pxa/irqs.h @@ -10,9 +10,10 @@ * published by the Free Software Foundation. */ -#define PXA_IRQ_SKIP 8 /* The first 8 IRQs are reserved */ +#define PXA_IRQ_SKIP 7 /* The first 7 IRQs are not yet used */ #define PXA_IRQ(x) ((x) - PXA_IRQ_SKIP) +#define IRQ_HWUART PXA_IRQ(7) /* HWUART Transmit/Receive/Error */ #define IRQ_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */ #define IRQ_GPIO1 PXA_IRQ(9) /* GPIO1 Edge Detect */ #define IRQ_GPIO_2_80 PXA_IRQ(10) /* GPIO[2-80] Edge Detect */ @@ -20,6 +21,8 @@ #define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */ #define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt */ #define IRQ_AC97 PXA_IRQ(14) /* AC97 Interrupt */ +#define IRQ_ASSP PXA_IRQ(15) /* Audio SSP Service Request */ +#define IRQ_NSSP PXA_IRQ(16) /* Network SSP Service Request */ #define IRQ_LCD PXA_IRQ(17) /* LCD Controller Service Request */ #define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */ #define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */ |
