diff options
| -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 | ||
