diff options
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index f7ce0021e1c4..d64bafb1afd0 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -723,13 +723,16 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) { } | |||
723 | * context. So we need to disable bh here to avoid deadlocks and other | 723 | * context. So we need to disable bh here to avoid deadlocks and other |
724 | * side effects. | 724 | * side effects. |
725 | */ | 725 | */ |
726 | static void | 726 | static irqreturn_t |
727 | irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action) | 727 | irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action) |
728 | { | 728 | { |
729 | irqreturn_t ret; | ||
730 | |||
729 | local_bh_disable(); | 731 | local_bh_disable(); |
730 | action->thread_fn(action->irq, action->dev_id); | 732 | ret = action->thread_fn(action->irq, action->dev_id); |
731 | irq_finalize_oneshot(desc, action, false); | 733 | irq_finalize_oneshot(desc, action, false); |
732 | local_bh_enable(); | 734 | local_bh_enable(); |
735 | return ret; | ||
733 | } | 736 | } |
734 | 737 | ||
735 | /* | 738 | /* |
@@ -737,10 +740,14 @@ irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action) | |||
737 | * preemtible - many of them need to sleep and wait for slow busses to | 740 | * preemtible - many of them need to sleep and wait for slow busses to |
738 | * complete. | 741 | * complete. |
739 | */ | 742 | */ |
740 | static void irq_thread_fn(struct irq_desc *desc, struct irqaction *action) | 743 | static irqreturn_t irq_thread_fn(struct irq_desc *desc, |
744 | struct irqaction *action) | ||
741 | { | 745 | { |
742 | action->thread_fn(action->irq, action->dev_id); | 746 | irqreturn_t ret; |
747 | |||
748 | ret = action->thread_fn(action->irq, action->dev_id); | ||
743 | irq_finalize_oneshot(desc, action, false); | 749 | irq_finalize_oneshot(desc, action, false); |
750 | return ret; | ||
744 | } | 751 | } |
745 | 752 | ||
746 | /* | 753 | /* |
@@ -753,7 +760,8 @@ static int irq_thread(void *data) | |||
753 | }; | 760 | }; |
754 | struct irqaction *action = data; | 761 | struct irqaction *action = data; |
755 | struct irq_desc *desc = irq_to_desc(action->irq); | 762 | struct irq_desc *desc = irq_to_desc(action->irq); |
756 | void (*handler_fn)(struct irq_desc *desc, struct irqaction *action); | 763 | irqreturn_t (*handler_fn)(struct irq_desc *desc, |
764 | struct irqaction *action); | ||
757 | int wake; | 765 | int wake; |
758 | 766 | ||
759 | if (force_irqthreads & test_bit(IRQTF_FORCED_THREAD, | 767 | if (force_irqthreads & test_bit(IRQTF_FORCED_THREAD, |
@@ -783,8 +791,12 @@ static int irq_thread(void *data) | |||
783 | desc->istate |= IRQS_PENDING; | 791 | desc->istate |= IRQS_PENDING; |
784 | raw_spin_unlock_irq(&desc->lock); | 792 | raw_spin_unlock_irq(&desc->lock); |
785 | } else { | 793 | } else { |
794 | irqreturn_t action_ret; | ||
795 | |||
786 | raw_spin_unlock_irq(&desc->lock); | 796 | raw_spin_unlock_irq(&desc->lock); |
787 | handler_fn(desc, action); | 797 | action_ret = handler_fn(desc, action); |
798 | if (!noirqdebug) | ||
799 | note_interrupt(action->irq, desc, action_ret); | ||
788 | } | 800 | } |
789 | 801 | ||
790 | wake = atomic_dec_and_test(&desc->threads_active); | 802 | wake = atomic_dec_and_test(&desc->threads_active); |