summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@flint.arm.linux.org.uk>2003-05-13 17:40:41 +0100
committerRussell King <rmk@flint.arm.linux.org.uk>2003-05-13 17:40:41 +0100
commit2febe49d11d8ba8af8fc51fb4be0e6e295ad7fdb (patch)
tree37de67f45e5aa72fc4c3a1ee84fe24c25f0ce66b
parentc85c822d901a657f926da2dd9064fde1a81e8149 (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.S2
-rw-r--r--arch/arm/mach-pxa/irq.c22
-rw-r--r--arch/arm/mach-pxa/lubbock.c50
-rw-r--r--include/asm-arm/arch-pxa/irqs.h5
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 */