diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2006-06-29 05:24:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 13:26:24 -0400 |
commit | e76de9f8eb67b7acc1cc6f28c4be8583adf0a90c (patch) | |
tree | b2c1c4f58f11772880a48c63c1138fe3b2787c9c /kernel/irq | |
parent | ba9a2331bae5da8f65be3722b9e2d210f1987857 (diff) |
[PATCH] genirq: add SA_TRIGGER support
Enable drivers to request an IRQ with a given irq-flow (trigger/polarity)
setting.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/irq')
-rw-r--r-- | kernel/irq/manage.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 3ed7aee84865..627d401c2979 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -225,8 +225,14 @@ int setup_irq(unsigned int irq, struct irqaction *new) | |||
225 | p = &desc->action; | 225 | p = &desc->action; |
226 | old = *p; | 226 | old = *p; |
227 | if (old) { | 227 | if (old) { |
228 | /* Can't share interrupts unless both agree to */ | 228 | /* |
229 | if (!(old->flags & new->flags & SA_SHIRQ)) | 229 | * Can't share interrupts unless both agree to and are |
230 | * the same type (level, edge, polarity). So both flag | ||
231 | * fields must have SA_SHIRQ set and the bits which | ||
232 | * set the trigger type must match. | ||
233 | */ | ||
234 | if (!((old->flags & new->flags) & SA_SHIRQ) || | ||
235 | ((old->flags ^ new->flags) & SA_TRIGGER_MASK)) | ||
230 | goto mismatch; | 236 | goto mismatch; |
231 | 237 | ||
232 | #if defined(CONFIG_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) | 238 | #if defined(CONFIG_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) |
@@ -250,7 +256,22 @@ int setup_irq(unsigned int irq, struct irqaction *new) | |||
250 | #endif | 256 | #endif |
251 | if (!shared) { | 257 | if (!shared) { |
252 | irq_chip_set_defaults(desc->chip); | 258 | irq_chip_set_defaults(desc->chip); |
253 | compat_irq_chip_set_default_handler(desc); | 259 | |
260 | /* Setup the type (level, edge polarity) if configured: */ | ||
261 | if (new->flags & SA_TRIGGER_MASK) { | ||
262 | if (desc->chip && desc->chip->set_type) | ||
263 | desc->chip->set_type(irq, | ||
264 | new->flags & SA_TRIGGER_MASK); | ||
265 | else | ||
266 | /* | ||
267 | * SA_TRIGGER_* but the PIC does not support | ||
268 | * multiple flow-types? | ||
269 | */ | ||
270 | printk(KERN_WARNING "setup_irq(%d) SA_TRIGGER" | ||
271 | "set. No set_type function available\n", | ||
272 | irq); | ||
273 | } else | ||
274 | compat_irq_chip_set_default_handler(desc); | ||
254 | 275 | ||
255 | desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING | | 276 | desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING | |
256 | IRQ_INPROGRESS); | 277 | IRQ_INPROGRESS); |
@@ -262,7 +283,9 @@ int setup_irq(unsigned int irq, struct irqaction *new) | |||
262 | desc->chip->startup(irq); | 283 | desc->chip->startup(irq); |
263 | else | 284 | else |
264 | desc->chip->enable(irq); | 285 | desc->chip->enable(irq); |
265 | } | 286 | } else |
287 | /* Undo nested disables: */ | ||
288 | desc->depth = 1; | ||
266 | } | 289 | } |
267 | spin_unlock_irqrestore(&desc->lock, flags); | 290 | spin_unlock_irqrestore(&desc->lock, flags); |
268 | 291 | ||