diff options
Diffstat (limited to 'kernel/irq/proc.c')
-rw-r--r-- | kernel/irq/proc.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index e3a8c9577ba6..a50ddc9417ff 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/kernel_stat.h> | 14 | #include <linux/kernel_stat.h> |
15 | #include <linux/mutex.h> | ||
15 | 16 | ||
16 | #include "internals.h" | 17 | #include "internals.h" |
17 | 18 | ||
@@ -323,18 +324,29 @@ void register_handler_proc(unsigned int irq, struct irqaction *action) | |||
323 | 324 | ||
324 | void register_irq_proc(unsigned int irq, struct irq_desc *desc) | 325 | void register_irq_proc(unsigned int irq, struct irq_desc *desc) |
325 | { | 326 | { |
327 | static DEFINE_MUTEX(register_lock); | ||
326 | char name [MAX_NAMELEN]; | 328 | char name [MAX_NAMELEN]; |
327 | 329 | ||
328 | if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip) || desc->dir) | 330 | if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) |
329 | return; | 331 | return; |
330 | 332 | ||
333 | /* | ||
334 | * irq directories are registered only when a handler is | ||
335 | * added, not when the descriptor is created, so multiple | ||
336 | * tasks might try to register at the same time. | ||
337 | */ | ||
338 | mutex_lock(®ister_lock); | ||
339 | |||
340 | if (desc->dir) | ||
341 | goto out_unlock; | ||
342 | |||
331 | memset(name, 0, MAX_NAMELEN); | 343 | memset(name, 0, MAX_NAMELEN); |
332 | sprintf(name, "%d", irq); | 344 | sprintf(name, "%d", irq); |
333 | 345 | ||
334 | /* create /proc/irq/1234 */ | 346 | /* create /proc/irq/1234 */ |
335 | desc->dir = proc_mkdir(name, root_irq_dir); | 347 | desc->dir = proc_mkdir(name, root_irq_dir); |
336 | if (!desc->dir) | 348 | if (!desc->dir) |
337 | return; | 349 | goto out_unlock; |
338 | 350 | ||
339 | #ifdef CONFIG_SMP | 351 | #ifdef CONFIG_SMP |
340 | /* create /proc/irq/<irq>/smp_affinity */ | 352 | /* create /proc/irq/<irq>/smp_affinity */ |
@@ -355,6 +367,9 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc) | |||
355 | 367 | ||
356 | proc_create_data("spurious", 0444, desc->dir, | 368 | proc_create_data("spurious", 0444, desc->dir, |
357 | &irq_spurious_proc_fops, (void *)(long)irq); | 369 | &irq_spurious_proc_fops, (void *)(long)irq); |
370 | |||
371 | out_unlock: | ||
372 | mutex_unlock(®ister_lock); | ||
358 | } | 373 | } |
359 | 374 | ||
360 | void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) | 375 | void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) |