diff options
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 61c679db4687..0ec9ed831737 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -607,7 +607,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
607 | */ | 607 | */ |
608 | get_task_struct(t); | 608 | get_task_struct(t); |
609 | new->thread = t; | 609 | new->thread = t; |
610 | wake_up_process(t); | ||
611 | } | 610 | } |
612 | 611 | ||
613 | /* | 612 | /* |
@@ -690,6 +689,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
690 | (int)(new->flags & IRQF_TRIGGER_MASK)); | 689 | (int)(new->flags & IRQF_TRIGGER_MASK)); |
691 | } | 690 | } |
692 | 691 | ||
692 | new->irq = irq; | ||
693 | *old_ptr = new; | 693 | *old_ptr = new; |
694 | 694 | ||
695 | /* Reset broken irq detection when installing new handler */ | 695 | /* Reset broken irq detection when installing new handler */ |
@@ -707,7 +707,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
707 | 707 | ||
708 | spin_unlock_irqrestore(&desc->lock, flags); | 708 | spin_unlock_irqrestore(&desc->lock, flags); |
709 | 709 | ||
710 | new->irq = irq; | 710 | /* |
711 | * Strictly no need to wake it up, but hung_task complains | ||
712 | * when no hard interrupt wakes the thread up. | ||
713 | */ | ||
714 | if (new->thread) | ||
715 | wake_up_process(new->thread); | ||
716 | |||
711 | register_irq_proc(irq, desc); | 717 | register_irq_proc(irq, desc); |
712 | new->dir = NULL; | 718 | new->dir = NULL; |
713 | register_handler_proc(irq, new); | 719 | register_handler_proc(irq, new); |
@@ -761,7 +767,6 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
761 | { | 767 | { |
762 | struct irq_desc *desc = irq_to_desc(irq); | 768 | struct irq_desc *desc = irq_to_desc(irq); |
763 | struct irqaction *action, **action_ptr; | 769 | struct irqaction *action, **action_ptr; |
764 | struct task_struct *irqthread; | ||
765 | unsigned long flags; | 770 | unsigned long flags; |
766 | 771 | ||
767 | WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq); | 772 | WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq); |
@@ -809,9 +814,6 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
809 | desc->chip->disable(irq); | 814 | desc->chip->disable(irq); |
810 | } | 815 | } |
811 | 816 | ||
812 | irqthread = action->thread; | ||
813 | action->thread = NULL; | ||
814 | |||
815 | spin_unlock_irqrestore(&desc->lock, flags); | 817 | spin_unlock_irqrestore(&desc->lock, flags); |
816 | 818 | ||
817 | unregister_handler_proc(irq, action); | 819 | unregister_handler_proc(irq, action); |
@@ -819,12 +821,6 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
819 | /* Make sure it's not being used on another CPU: */ | 821 | /* Make sure it's not being used on another CPU: */ |
820 | synchronize_irq(irq); | 822 | synchronize_irq(irq); |
821 | 823 | ||
822 | if (irqthread) { | ||
823 | if (!test_bit(IRQTF_DIED, &action->thread_flags)) | ||
824 | kthread_stop(irqthread); | ||
825 | put_task_struct(irqthread); | ||
826 | } | ||
827 | |||
828 | #ifdef CONFIG_DEBUG_SHIRQ | 824 | #ifdef CONFIG_DEBUG_SHIRQ |
829 | /* | 825 | /* |
830 | * It's a shared IRQ -- the driver ought to be prepared for an IRQ | 826 | * It's a shared IRQ -- the driver ought to be prepared for an IRQ |
@@ -840,6 +836,13 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
840 | local_irq_restore(flags); | 836 | local_irq_restore(flags); |
841 | } | 837 | } |
842 | #endif | 838 | #endif |
839 | |||
840 | if (action->thread) { | ||
841 | if (!test_bit(IRQTF_DIED, &action->thread_flags)) | ||
842 | kthread_stop(action->thread); | ||
843 | put_task_struct(action->thread); | ||
844 | } | ||
845 | |||
843 | return action; | 846 | return action; |
844 | } | 847 | } |
845 | 848 | ||