X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsh%2Fkernel%2Firq.c;h=9a7d936263fd90cd21eb9f120c4bdbe18049d298;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=a37e2d1cffcee150c3d611edb88b454c1f10ee0e;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index a37e2d1cf..9a7d93626 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -31,10 +31,10 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -137,14 +137,16 @@ unlock: int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action) { int status = 1; /* Force the "do bottom halves" bit */ - int retval = 0; + int ret, retval = 0; if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); do { - status |= action->flags; - retval |= action->handler(irq, action->dev_id, regs); + ret = action->handler(irq, action->dev_id, regs); + if (ret == IRQ_HANDLED) + status |= action->flags; + retval |= ret; action = action->next; } while (action); @@ -436,7 +438,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; @@ -575,6 +577,49 @@ unsigned long probe_irq_on(void) EXPORT_SYMBOL(probe_irq_on); +/* Return a mask of triggered interrupts (this + * can handle only legacy ISA interrupts). + */ + +/* + * probe_irq_mask - scan a bitmap of interrupt lines + * @val: mask of interrupts to consider + * + * Scan the ISA bus interrupt lines and return a bitmap of + * active interrupts. The interrupt probe logic state is then + * returned to its previous value. + * + * Note: we need to scan all the irq's even though we will + * only return ISA irq numbers - just so that we reset them + * all to a known state. + */ +unsigned int probe_irq_mask(unsigned long val) +{ + int i; + unsigned int mask; + + mask = 0; + for (i = 0; i < NR_IRQS; i++) { + irq_desc_t *desc = irq_desc + i; + unsigned int status; + + spin_lock_irq(&desc->lock); + status = desc->status; + + if (status & IRQ_AUTODETECT) { + if (i < 16 && !(status & IRQ_WAITING)) + mask |= 1 << i; + + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); + } + spin_unlock_irq(&desc->lock); + } + up(&probe_sem); + + return mask & val; +} + int probe_irq_off(unsigned long val) { int i, irq_found, nr_irqs;