diff options
author | Jeff Garzik <jeff@garzik.org> | 2007-02-17 15:09:59 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-17 15:09:59 -0500 |
commit | 48c871c1f6a7c7044dd76774fb469e65c7e2e4e8 (patch) | |
tree | da3aa535c98cc0957851354ceb0fbff7482d7a9d /kernel/irq/manage.c | |
parent | 1a1689344add3333d28d1b5495d8043a3877d01c (diff) | |
parent | 4409d28140d9a6e6e3f4f1fdaf7234c4b965d954 (diff) |
Merge branch 'gfar' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc into upstream
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 8b961adc3bd2..7c85d69188ef 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -328,12 +328,14 @@ int setup_irq(unsigned int irq, struct irqaction *new) | |||
328 | return 0; | 328 | return 0; |
329 | 329 | ||
330 | mismatch: | 330 | mismatch: |
331 | #ifdef CONFIG_DEBUG_SHIRQ | ||
331 | if (!(new->flags & IRQF_PROBE_SHARED)) { | 332 | if (!(new->flags & IRQF_PROBE_SHARED)) { |
332 | printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq); | 333 | printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq); |
333 | if (old_name) | 334 | if (old_name) |
334 | printk(KERN_ERR "current handler: %s\n", old_name); | 335 | printk(KERN_ERR "current handler: %s\n", old_name); |
335 | dump_stack(); | 336 | dump_stack(); |
336 | } | 337 | } |
338 | #endif | ||
337 | spin_unlock_irqrestore(&desc->lock, flags); | 339 | spin_unlock_irqrestore(&desc->lock, flags); |
338 | return -EBUSY; | 340 | return -EBUSY; |
339 | } | 341 | } |
@@ -357,6 +359,7 @@ void free_irq(unsigned int irq, void *dev_id) | |||
357 | struct irq_desc *desc; | 359 | struct irq_desc *desc; |
358 | struct irqaction **p; | 360 | struct irqaction **p; |
359 | unsigned long flags; | 361 | unsigned long flags; |
362 | irqreturn_t (*handler)(int, void *) = NULL; | ||
360 | 363 | ||
361 | WARN_ON(in_interrupt()); | 364 | WARN_ON(in_interrupt()); |
362 | if (irq >= NR_IRQS) | 365 | if (irq >= NR_IRQS) |
@@ -396,6 +399,8 @@ void free_irq(unsigned int irq, void *dev_id) | |||
396 | 399 | ||
397 | /* Make sure it's not being used on another CPU */ | 400 | /* Make sure it's not being used on another CPU */ |
398 | synchronize_irq(irq); | 401 | synchronize_irq(irq); |
402 | if (action->flags & IRQF_SHARED) | ||
403 | handler = action->handler; | ||
399 | kfree(action); | 404 | kfree(action); |
400 | return; | 405 | return; |
401 | } | 406 | } |
@@ -403,6 +408,17 @@ void free_irq(unsigned int irq, void *dev_id) | |||
403 | spin_unlock_irqrestore(&desc->lock, flags); | 408 | spin_unlock_irqrestore(&desc->lock, flags); |
404 | return; | 409 | return; |
405 | } | 410 | } |
411 | #ifdef CONFIG_DEBUG_SHIRQ | ||
412 | if (handler) { | ||
413 | /* | ||
414 | * It's a shared IRQ -- the driver ought to be prepared for it | ||
415 | * to happen even now it's being freed, so let's make sure.... | ||
416 | * We do this after actually deregistering it, to make sure that | ||
417 | * a 'real' IRQ doesn't run in parallel with our fake | ||
418 | */ | ||
419 | handler(irq, dev_id); | ||
420 | } | ||
421 | #endif | ||
406 | } | 422 | } |
407 | EXPORT_SYMBOL(free_irq); | 423 | EXPORT_SYMBOL(free_irq); |
408 | 424 | ||
@@ -475,6 +491,25 @@ int request_irq(unsigned int irq, irq_handler_t handler, | |||
475 | 491 | ||
476 | select_smp_affinity(irq); | 492 | select_smp_affinity(irq); |
477 | 493 | ||
494 | #ifdef CONFIG_DEBUG_SHIRQ | ||
495 | if (irqflags & IRQF_SHARED) { | ||
496 | /* | ||
497 | * It's a shared IRQ -- the driver ought to be prepared for it | ||
498 | * to happen immediately, so let's make sure.... | ||
499 | * We do this before actually registering it, to make sure that | ||
500 | * a 'real' IRQ doesn't run in parallel with our fake | ||
501 | */ | ||
502 | if (irqflags & IRQF_DISABLED) { | ||
503 | unsigned long flags; | ||
504 | |||
505 | local_irq_save(flags); | ||
506 | handler(irq, dev_id); | ||
507 | local_irq_restore(flags); | ||
508 | } else | ||
509 | handler(irq, dev_id); | ||
510 | } | ||
511 | #endif | ||
512 | |||
478 | retval = setup_irq(irq, action); | 513 | retval = setup_irq(irq, action); |
479 | if (retval) | 514 | if (retval) |
480 | kfree(action); | 515 | kfree(action); |