diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-10-27 00:46:20 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-10-27 00:46:20 -0400 |
| commit | 6ad390a25a9d1d8606b9b826878f0a30639dc2b3 (patch) | |
| tree | 05aff14f02776bc0d59a1f777cb92df6f4456ba9 /kernel/irq/manage.c | |
| parent | d6069dae4700cf5290a75002c46b9be8ea7eef3c (diff) | |
| parent | 3f48e7354358519e5b93f7f755ec270b3f8eafa0 (diff) | |
Merge branch 'next' into for-linus
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 | ||
