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)
rsb \irqstat, \irqnr, #0
and \irqstat, \irqstat, \irqnr
clz \irqnr, \irqstat
rsb \irqnr, \irqnr, #23
rsb \irqnr, \irqnr, #(31 - PXA_IRQ_SKIP)
1001:
.endm
......
......@@ -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);
......
......@@ -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,
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);
GEDR(0) = GPIO_bit(0); /* clear our parent irq */
if (likely(pending)) {
irq = LUBBOCK_IRQ(0) + __ffs(pending);
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;
}
pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
} while (pending);
}
......
......@@ -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 */
......
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