diff options
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 801addda3c43..540f6c49f3fa 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -370,16 +370,18 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
370 | return 0; | 370 | return 0; |
371 | } | 371 | } |
372 | 372 | ||
373 | ret = chip->set_type(irq, flags & IRQF_TRIGGER_MASK); | 373 | /* caller masked out all except trigger mode flags */ |
374 | ret = chip->set_type(irq, flags); | ||
374 | 375 | ||
375 | if (ret) | 376 | if (ret) |
376 | pr_err("setting trigger mode %d for irq %u failed (%pF)\n", | 377 | pr_err("setting trigger mode %d for irq %u failed (%pF)\n", |
377 | (int)(flags & IRQF_TRIGGER_MASK), | 378 | (int)flags, irq, chip->set_type); |
378 | irq, chip->set_type); | ||
379 | else { | 379 | else { |
380 | if (flags & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | ||
381 | flags |= IRQ_LEVEL; | ||
380 | /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */ | 382 | /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */ |
381 | desc->status &= ~IRQ_TYPE_SENSE_MASK; | 383 | desc->status &= ~(IRQ_LEVEL | IRQ_TYPE_SENSE_MASK); |
382 | desc->status |= flags & IRQ_TYPE_SENSE_MASK; | 384 | desc->status |= flags; |
383 | } | 385 | } |
384 | 386 | ||
385 | return ret; | 387 | return ret; |
@@ -459,7 +461,8 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new) | |||
459 | 461 | ||
460 | /* Setup the type (level, edge polarity) if configured: */ | 462 | /* Setup the type (level, edge polarity) if configured: */ |
461 | if (new->flags & IRQF_TRIGGER_MASK) { | 463 | if (new->flags & IRQF_TRIGGER_MASK) { |
462 | ret = __irq_set_trigger(desc, irq, new->flags); | 464 | ret = __irq_set_trigger(desc, irq, |
465 | new->flags & IRQF_TRIGGER_MASK); | ||
463 | 466 | ||
464 | if (ret) { | 467 | if (ret) { |
465 | spin_unlock_irqrestore(&desc->lock, flags); | 468 | spin_unlock_irqrestore(&desc->lock, flags); |
@@ -673,6 +676,18 @@ int request_irq(unsigned int irq, irq_handler_t handler, | |||
673 | struct irq_desc *desc; | 676 | struct irq_desc *desc; |
674 | int retval; | 677 | int retval; |
675 | 678 | ||
679 | /* | ||
680 | * handle_IRQ_event() always ignores IRQF_DISABLED except for | ||
681 | * the _first_ irqaction (sigh). That can cause oopsing, but | ||
682 | * the behavior is classified as "will not fix" so we need to | ||
683 | * start nudging drivers away from using that idiom. | ||
684 | */ | ||
685 | if ((irqflags & (IRQF_SHARED|IRQF_DISABLED)) | ||
686 | == (IRQF_SHARED|IRQF_DISABLED)) | ||
687 | pr_warning("IRQ %d/%s: IRQF_DISABLED is not " | ||
688 | "guaranteed on shared IRQs\n", | ||
689 | irq, devname); | ||
690 | |||
676 | #ifdef CONFIG_LOCKDEP | 691 | #ifdef CONFIG_LOCKDEP |
677 | /* | 692 | /* |
678 | * Lockdep wants atomic interrupt handlers: | 693 | * Lockdep wants atomic interrupt handlers: |