diff options
author | Dimitri Sivanich <sivanich@sgi.com> | 2006-03-25 03:08:23 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-25 08:23:01 -0800 |
commit | f5163427453bc6ca2dd497eeb3e7a30d1c74b487 (patch) | |
tree | 6fc334c30d12ee269e58d96e515543de48e9cf53 /kernel/irq/manage.c | |
parent | 6cc6b1226b71132a1d6e95449d78e051f1f3b506 (diff) | |
download | op-kernel-dev-f5163427453bc6ca2dd497eeb3e7a30d1c74b487.zip op-kernel-dev-f5163427453bc6ca2dd497eeb3e7a30d1c74b487.tar.gz |
[PATCH] Add SA_PERCPU_IRQ flag support
Add support for SA_PERCPU_IRQ (only mmtimer.c uses this at this stage).
Signed-off-by: Dimitri Sivanich <sivanich@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 97d5559..6edfcef 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -204,10 +204,14 @@ int setup_irq(unsigned int irq, struct irqaction * new) p = &desc->action; if ((old = *p) != NULL) { /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) { - spin_unlock_irqrestore(&desc->lock,flags); - return -EBUSY; - } + if (!(old->flags & new->flags & SA_SHIRQ)) + goto mismatch; + +#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) + /* All handlers must agree on per-cpuness */ + if ((old->flags & IRQ_PER_CPU) != (new->flags & IRQ_PER_CPU)) + goto mismatch; +#endif /* add new interrupt at end of irq queue */ do { @@ -218,7 +222,10 @@ int setup_irq(unsigned int irq, struct irqaction * new) } *p = new; - +#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) + if (new->flags & SA_PERCPU_IRQ) + desc->status |= IRQ_PER_CPU; +#endif if (!shared) { desc->depth = 0; desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | @@ -236,6 +243,12 @@ int setup_irq(unsigned int irq, struct irqaction * new) register_handler_proc(irq, new); return 0; + +mismatch: + spin_unlock_irqrestore(&desc->lock, flags); + printk(KERN_ERR "%s: irq handler mismatch\n", __FUNCTION__); + dump_stack(); + return -EBUSY; } /** |