aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/manage.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-12-31 07:35:57 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-12-31 07:35:57 -0500
commit2ca1a615835d9f4990f42102ab1f2ef434e7e89c (patch)
tree726cf3d5f29a6c66c44e4bd68e7ebed2fd83d059 /kernel/irq/manage.c
parente12f0102ac81d660c9f801d0a0e10ccf4537a9de (diff)
parent6a94cb73064c952255336cc57731904174b2c58f (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: arch/x86/kernel/io_apic.c
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r--kernel/irq/manage.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 10ad2f87ed9a..61c4a9b62165 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -368,16 +368,18 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
368 return 0; 368 return 0;
369 } 369 }
370 370
371 ret = chip->set_type(irq, flags & IRQF_TRIGGER_MASK); 371 /* caller masked out all except trigger mode flags */
372 ret = chip->set_type(irq, flags);
372 373
373 if (ret) 374 if (ret)
374 pr_err("setting trigger mode %d for irq %u failed (%pF)\n", 375 pr_err("setting trigger mode %d for irq %u failed (%pF)\n",
375 (int)(flags & IRQF_TRIGGER_MASK), 376 (int)flags, irq, chip->set_type);
376 irq, chip->set_type);
377 else { 377 else {
378 if (flags & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
379 flags |= IRQ_LEVEL;
378 /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */ 380 /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */
379 desc->status &= ~IRQ_TYPE_SENSE_MASK; 381 desc->status &= ~(IRQ_LEVEL | IRQ_TYPE_SENSE_MASK);
380 desc->status |= flags & IRQ_TYPE_SENSE_MASK; 382 desc->status |= flags;
381 } 383 }
382 384
383 return ret; 385 return ret;
@@ -457,7 +459,8 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
457 459
458 /* Setup the type (level, edge polarity) if configured: */ 460 /* Setup the type (level, edge polarity) if configured: */
459 if (new->flags & IRQF_TRIGGER_MASK) { 461 if (new->flags & IRQF_TRIGGER_MASK) {
460 ret = __irq_set_trigger(desc, irq, new->flags); 462 ret = __irq_set_trigger(desc, irq,
463 new->flags & IRQF_TRIGGER_MASK);
461 464
462 if (ret) { 465 if (ret) {
463 spin_unlock_irqrestore(&desc->lock, flags); 466 spin_unlock_irqrestore(&desc->lock, flags);
@@ -671,6 +674,18 @@ int request_irq(unsigned int irq, irq_handler_t handler,
671 struct irq_desc *desc; 674 struct irq_desc *desc;
672 int retval; 675 int retval;
673 676
677 /*
678 * handle_IRQ_event() always ignores IRQF_DISABLED except for
679 * the _first_ irqaction (sigh). That can cause oopsing, but
680 * the behavior is classified as "will not fix" so we need to
681 * start nudging drivers away from using that idiom.
682 */
683 if ((irqflags & (IRQF_SHARED|IRQF_DISABLED))
684 == (IRQF_SHARED|IRQF_DISABLED))
685 pr_warning("IRQ %d/%s: IRQF_DISABLED is not "
686 "guaranteed on shared IRQs\n",
687 irq, devname);
688
674#ifdef CONFIG_LOCKDEP 689#ifdef CONFIG_LOCKDEP
675 /* 690 /*
676 * Lockdep wants atomic interrupt handlers: 691 * Lockdep wants atomic interrupt handlers: