diff options
Diffstat (limited to 'kernel/irq/manage.c')
| -rw-r--r-- | kernel/irq/manage.c | 17 | 
1 files changed, 13 insertions, 4 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 0a7840aeb0fb..9b956fa20308 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c  | |||
| @@ -883,6 +883,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
| 883 | 883 | ||
| 884 | if (desc->irq_data.chip == &no_irq_chip) | 884 | if (desc->irq_data.chip == &no_irq_chip) | 
| 885 | return -ENOSYS; | 885 | return -ENOSYS; | 
| 886 | if (!try_module_get(desc->owner)) | ||
| 887 | return -ENODEV; | ||
| 886 | /* | 888 | /* | 
| 887 | * Some drivers like serial.c use request_irq() heavily, | 889 | * Some drivers like serial.c use request_irq() heavily, | 
| 888 | * so we have to be careful not to interfere with a | 890 | * so we have to be careful not to interfere with a | 
| @@ -906,8 +908,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
| 906 | */ | 908 | */ | 
| 907 | nested = irq_settings_is_nested_thread(desc); | 909 | nested = irq_settings_is_nested_thread(desc); | 
| 908 | if (nested) { | 910 | if (nested) { | 
| 909 | if (!new->thread_fn) | 911 | if (!new->thread_fn) { | 
| 910 | return -EINVAL; | 912 | ret = -EINVAL; | 
| 913 | goto out_mput; | ||
| 914 | } | ||
| 911 | /* | 915 | /* | 
| 912 | * Replace the primary handler which was provided from | 916 | * Replace the primary handler which was provided from | 
| 913 | * the driver for non nested interrupt handling by the | 917 | * the driver for non nested interrupt handling by the | 
| @@ -929,8 +933,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
| 929 | 933 | ||
| 930 | t = kthread_create(irq_thread, new, "irq/%d-%s", irq, | 934 | t = kthread_create(irq_thread, new, "irq/%d-%s", irq, | 
| 931 | new->name); | 935 | new->name); | 
| 932 | if (IS_ERR(t)) | 936 | if (IS_ERR(t)) { | 
| 933 | return PTR_ERR(t); | 937 | ret = PTR_ERR(t); | 
| 938 | goto out_mput; | ||
| 939 | } | ||
| 934 | /* | 940 | /* | 
| 935 | * We keep the reference to the task struct even if | 941 | * We keep the reference to the task struct even if | 
| 936 | * the thread dies to avoid that the interrupt code | 942 | * the thread dies to avoid that the interrupt code | 
| @@ -1095,6 +1101,8 @@ out_thread: | |||
| 1095 | kthread_stop(t); | 1101 | kthread_stop(t); | 
| 1096 | put_task_struct(t); | 1102 | put_task_struct(t); | 
| 1097 | } | 1103 | } | 
| 1104 | out_mput: | ||
| 1105 | module_put(desc->owner); | ||
| 1098 | return ret; | 1106 | return ret; | 
| 1099 | } | 1107 | } | 
| 1100 | 1108 | ||
| @@ -1203,6 +1211,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
| 1203 | put_task_struct(action->thread); | 1211 | put_task_struct(action->thread); | 
| 1204 | } | 1212 | } | 
| 1205 | 1213 | ||
| 1214 | module_put(desc->owner); | ||
| 1206 | return action; | 1215 | return action; | 
| 1207 | } | 1216 | } | 
| 1208 | 1217 | ||
