Commit 2febe49d authored by Russell King's avatar Russell King

[ARM PATCH] 1530/1: PXA2xx IRQ handling updates

From: Nicolas Pitre.

(manual entry since bk openlogging crapped out again)
parent c85c822d
...@@ -621,7 +621,7 @@ ENTRY(anakin_active_irqs) ...@@ -621,7 +621,7 @@ ENTRY(anakin_active_irqs)
rsb \irqstat, \irqnr, #0 rsb \irqstat, \irqnr, #0
and \irqstat, \irqstat, \irqnr and \irqstat, \irqstat, \irqnr
clz \irqnr, \irqstat clz \irqnr, \irqstat
rsb \irqnr, \irqnr, #23 rsb \irqnr, \irqnr, #(31 - PXA_IRQ_SKIP)
1001: 1001:
.endm .endm
......
...@@ -50,9 +50,9 @@ static struct irqchip pxa_internal_chip = { ...@@ -50,9 +50,9 @@ static struct irqchip pxa_internal_chip = {
* Use this instead of directly setting GRER/GFER. * Use this instead of directly setting GRER/GFER.
*/ */
static int GPIO_IRQ_rising_edge[3]; static long GPIO_IRQ_rising_edge[3];
static int GPIO_IRQ_falling_edge[3]; static long GPIO_IRQ_falling_edge[3];
static int GPIO_IRQ_mask[3]; static long GPIO_IRQ_mask[3];
static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
{ {
...@@ -189,7 +189,6 @@ static struct irqchip pxa_muxed_gpio_chip = { ...@@ -189,7 +189,6 @@ static struct irqchip pxa_muxed_gpio_chip = {
.ack = pxa_ack_muxed_gpio, .ack = pxa_ack_muxed_gpio,
.mask = pxa_mask_muxed_gpio, .mask = pxa_mask_muxed_gpio,
.unmask = pxa_unmask_muxed_gpio, .unmask = pxa_unmask_muxed_gpio,
.rerun = pxa_manual_rerun,
.type = pxa_gpio_irq_type, .type = pxa_gpio_irq_type,
}; };
...@@ -217,21 +216,18 @@ void __init pxa_init_irq(void) ...@@ -217,21 +216,18 @@ void __init pxa_init_irq(void)
/* GPIO 0 and 1 must have their mask bit always set */ /* GPIO 0 and 1 must have their mask bit always set */
GPIO_IRQ_mask[0] = 3; 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++) { for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
set_irq_chip(irq, &pxa_low_gpio_chip); set_irq_chip(irq, &pxa_low_gpio_chip);
set_irq_handler(irq, do_edge_IRQ); set_irq_handler(irq, do_edge_IRQ);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 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++) { for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(80); irq++) {
set_irq_chip(irq, &pxa_muxed_gpio_chip); set_irq_chip(irq, &pxa_muxed_gpio_chip);
set_irq_handler(irq, do_edge_IRQ); set_irq_handler(irq, do_edge_IRQ);
......
...@@ -33,57 +33,41 @@ ...@@ -33,57 +33,41 @@
#include "generic.h" #include "generic.h"
static void lubbock_ack_irq(unsigned int irq)
{ static unsigned long lubbock_irq_enabled;
int lubbock_irq = (irq - LUBBOCK_IRQ(0));
LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
}
static void lubbock_mask_irq(unsigned int irq) static void lubbock_mask_irq(unsigned int irq)
{ {
int lubbock_irq = (irq - LUBBOCK_IRQ(0)); 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) static void lubbock_unmask_irq(unsigned int irq)
{ {
int lubbock_irq = (irq - LUBBOCK_IRQ(0)); 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 = { static struct irqchip lubbock_irq_chip = {
.ack = lubbock_ack_irq, .ack = lubbock_mask_irq,
.mask = lubbock_mask_irq, .mask = lubbock_mask_irq,
.unmask = lubbock_unmask_irq, .unmask = lubbock_unmask_irq,
}; };
void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc, static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc,
struct pt_regs *regs) struct pt_regs *regs)
{ {
unsigned int enabled, pending; unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
/* get active pending irq mask */
enabled = LUB_IRQ_MASK_EN & 0x003f;
pending = LUB_IRQ_SET_CLR & enabled;
do { 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 ); GEDR(0) = GPIO_bit(0); /* clear our parent irq */
/* clear our parent irq */ if (likely(pending)) {
GEDR(0) = GPIO_bit(0); irq = LUBBOCK_IRQ(0) + __ffs(pending);
desc = irq_desc + irq;
/* process them */ desc->handle(irq, desc, regs);
irq = LUBBOCK_IRQ(0); }
desc = irq_desc + irq; pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
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;
} while (pending); } while (pending);
} }
......
...@@ -10,9 +10,10 @@ ...@@ -10,9 +10,10 @@
* published by the Free Software Foundation. * 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 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_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */
#define IRQ_GPIO1 PXA_IRQ(9) /* GPIO1 Edge Detect */ #define IRQ_GPIO1 PXA_IRQ(9) /* GPIO1 Edge Detect */
#define IRQ_GPIO_2_80 PXA_IRQ(10) /* GPIO[2-80] Edge Detect */ #define IRQ_GPIO_2_80 PXA_IRQ(10) /* GPIO[2-80] Edge Detect */
...@@ -20,6 +21,8 @@ ...@@ -20,6 +21,8 @@
#define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */ #define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */
#define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt */ #define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt */
#define IRQ_AC97 PXA_IRQ(14) /* AC97 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_LCD PXA_IRQ(17) /* LCD Controller Service Request */
#define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */ #define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */
#define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */ #define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment