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 | |
| 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')
| -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 | ||
