aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/manage.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r--kernel/irq/manage.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 0a7840aeb0f..d6c4adc2804 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -620,8 +620,9 @@ static irqreturn_t irq_nested_primary_handler(int irq, void *dev_id)
620 620
621static int irq_wait_for_interrupt(struct irqaction *action) 621static int irq_wait_for_interrupt(struct irqaction *action)
622{ 622{
623 set_current_state(TASK_INTERRUPTIBLE);
624
623 while (!kthread_should_stop()) { 625 while (!kthread_should_stop()) {
624 set_current_state(TASK_INTERRUPTIBLE);
625 626
626 if (test_and_clear_bit(IRQTF_RUNTHREAD, 627 if (test_and_clear_bit(IRQTF_RUNTHREAD,
627 &action->thread_flags)) { 628 &action->thread_flags)) {
@@ -629,7 +630,9 @@ static int irq_wait_for_interrupt(struct irqaction *action)
629 return 0; 630 return 0;
630 } 631 }
631 schedule(); 632 schedule();
633 set_current_state(TASK_INTERRUPTIBLE);
632 } 634 }
635 __set_current_state(TASK_RUNNING);
633 return -1; 636 return -1;
634} 637}
635 638
@@ -883,6 +886,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
883 886
884 if (desc->irq_data.chip == &no_irq_chip) 887 if (desc->irq_data.chip == &no_irq_chip)
885 return -ENOSYS; 888 return -ENOSYS;
889 if (!try_module_get(desc->owner))
890 return -ENODEV;
886 /* 891 /*
887 * Some drivers like serial.c use request_irq() heavily, 892 * Some drivers like serial.c use request_irq() heavily,
888 * so we have to be careful not to interfere with a 893 * so we have to be careful not to interfere with a
@@ -906,8 +911,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
906 */ 911 */
907 nested = irq_settings_is_nested_thread(desc); 912 nested = irq_settings_is_nested_thread(desc);
908 if (nested) { 913 if (nested) {
909 if (!new->thread_fn) 914 if (!new->thread_fn) {
910 return -EINVAL; 915 ret = -EINVAL;
916 goto out_mput;
917 }
911 /* 918 /*
912 * Replace the primary handler which was provided from 919 * Replace the primary handler which was provided from
913 * the driver for non nested interrupt handling by the 920 * the driver for non nested interrupt handling by the
@@ -929,8 +936,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
929 936
930 t = kthread_create(irq_thread, new, "irq/%d-%s", irq, 937 t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
931 new->name); 938 new->name);
932 if (IS_ERR(t)) 939 if (IS_ERR(t)) {
933 return PTR_ERR(t); 940 ret = PTR_ERR(t);
941 goto out_mput;
942 }
934 /* 943 /*
935 * We keep the reference to the task struct even if 944 * We keep the reference to the task struct even if
936 * the thread dies to avoid that the interrupt code 945 * the thread dies to avoid that the interrupt code
@@ -1095,6 +1104,8 @@ out_thread:
1095 kthread_stop(t); 1104 kthread_stop(t);
1096 put_task_struct(t); 1105 put_task_struct(t);
1097 } 1106 }
1107out_mput:
1108 module_put(desc->owner);
1098 return ret; 1109 return ret;
1099} 1110}
1100 1111
@@ -1203,6 +1214,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
1203 put_task_struct(action->thread); 1214 put_task_struct(action->thread);
1204 } 1215 }
1205 1216
1217 module_put(desc->owner);
1206 return action; 1218 return action;
1207} 1219}
1208 1220