diff options
-rw-r--r-- | include/linux/irq.h | 9 | ||||
-rw-r--r-- | kernel/irq/chip.c | 4 | ||||
-rw-r--r-- | kernel/irq/internals.h | 2 | ||||
-rw-r--r-- | kernel/irq/manage.c | 16 |
4 files changed, 26 insertions, 5 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index aefb30bbcf0e..ef6b66dc9d03 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -308,6 +308,15 @@ struct irq_chip { | |||
308 | #endif | 308 | #endif |
309 | }; | 309 | }; |
310 | 310 | ||
311 | /* | ||
312 | * irq_chip specific flags | ||
313 | * | ||
314 | * IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type() | ||
315 | */ | ||
316 | enum { | ||
317 | IRQCHIP_SET_TYPE_MASKED = (1 << 0), | ||
318 | }; | ||
319 | |||
311 | /* This include will go away once we isolated irq_desc usage to core code */ | 320 | /* This include will go away once we isolated irq_desc usage to core code */ |
312 | #include <linux/irqdesc.h> | 321 | #include <linux/irqdesc.h> |
313 | 322 | ||
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 9e9220da4deb..4687457fe7f0 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -367,7 +367,7 @@ static inline void mask_ack_irq(struct irq_desc *desc) | |||
367 | irq_state_set_masked(desc); | 367 | irq_state_set_masked(desc); |
368 | } | 368 | } |
369 | 369 | ||
370 | static inline void mask_irq(struct irq_desc *desc) | 370 | void mask_irq(struct irq_desc *desc) |
371 | { | 371 | { |
372 | if (desc->irq_data.chip->irq_mask) { | 372 | if (desc->irq_data.chip->irq_mask) { |
373 | desc->irq_data.chip->irq_mask(&desc->irq_data); | 373 | desc->irq_data.chip->irq_mask(&desc->irq_data); |
@@ -375,7 +375,7 @@ static inline void mask_irq(struct irq_desc *desc) | |||
375 | } | 375 | } |
376 | } | 376 | } |
377 | 377 | ||
378 | static inline void unmask_irq(struct irq_desc *desc) | 378 | void unmask_irq(struct irq_desc *desc) |
379 | { | 379 | { |
380 | if (desc->irq_data.chip->irq_unmask) { | 380 | if (desc->irq_data.chip->irq_unmask) { |
381 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | 381 | desc->irq_data.chip->irq_unmask(&desc->irq_data); |
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index 6776453c454c..1d500fbde0d4 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h | |||
@@ -84,6 +84,8 @@ extern int irq_startup(struct irq_desc *desc); | |||
84 | extern void irq_shutdown(struct irq_desc *desc); | 84 | extern void irq_shutdown(struct irq_desc *desc); |
85 | extern void irq_enable(struct irq_desc *desc); | 85 | extern void irq_enable(struct irq_desc *desc); |
86 | extern void irq_disable(struct irq_desc *desc); | 86 | extern void irq_disable(struct irq_desc *desc); |
87 | extern void mask_irq(struct irq_desc *desc); | ||
88 | extern void unmask_irq(struct irq_desc *desc); | ||
87 | 89 | ||
88 | extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr); | 90 | extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr); |
89 | 91 | ||
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index b5de828e58d9..50809c79c7ad 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -554,8 +554,8 @@ void compat_irq_chip_set_default_handler(struct irq_desc *desc) | |||
554 | int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | 554 | int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, |
555 | unsigned long flags) | 555 | unsigned long flags) |
556 | { | 556 | { |
557 | int ret; | ||
558 | struct irq_chip *chip = desc->irq_data.chip; | 557 | struct irq_chip *chip = desc->irq_data.chip; |
558 | int ret, unmask = 0; | ||
559 | 559 | ||
560 | if (!chip || !chip->irq_set_type) { | 560 | if (!chip || !chip->irq_set_type) { |
561 | /* | 561 | /* |
@@ -568,6 +568,14 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
568 | } | 568 | } |
569 | 569 | ||
570 | flags &= IRQ_TYPE_SENSE_MASK; | 570 | flags &= IRQ_TYPE_SENSE_MASK; |
571 | |||
572 | if (chip->flags & IRQCHIP_SET_TYPE_MASKED) { | ||
573 | if (!(desc->istate & IRQS_MASKED)) | ||
574 | mask_irq(desc); | ||
575 | if (!(desc->istate & IRQS_DISABLED)) | ||
576 | unmask = 1; | ||
577 | } | ||
578 | |||
571 | /* caller masked out all except trigger mode flags */ | 579 | /* caller masked out all except trigger mode flags */ |
572 | ret = chip->irq_set_type(&desc->irq_data, flags); | 580 | ret = chip->irq_set_type(&desc->irq_data, flags); |
573 | 581 | ||
@@ -588,11 +596,13 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
588 | 596 | ||
589 | if (chip != desc->irq_data.chip) | 597 | if (chip != desc->irq_data.chip) |
590 | irq_chip_set_defaults(desc->irq_data.chip); | 598 | irq_chip_set_defaults(desc->irq_data.chip); |
591 | return 0; | 599 | ret = 0; |
592 | default: | 600 | default: |
593 | pr_err("setting trigger mode %lu for irq %u failed (%pF)\n", | 601 | pr_err("setting trigger mode %lu for irq %u failed (%pF)\n", |
594 | flags, irq, chip->irq_set_type); | 602 | flags, irq, chip->irq_set_type); |
595 | } | 603 | } |
604 | if (unmask) | ||
605 | unmask_irq(desc); | ||
596 | return ret; | 606 | return ret; |
597 | } | 607 | } |
598 | 608 | ||
@@ -669,7 +679,7 @@ again: | |||
669 | 679 | ||
670 | #ifdef CONFIG_SMP | 680 | #ifdef CONFIG_SMP |
671 | /* | 681 | /* |
672 | * Check whether we need to change the affinity of the interrupt thread. | 682 | * Check whether we need to chasnge the affinity of the interrupt thread. |
673 | */ | 683 | */ |
674 | static void | 684 | static void |
675 | irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) | 685 | irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) |