aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/irq/manage.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 7230d914eaa2..80eab7a04205 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -405,7 +405,6 @@ void free_irq(unsigned int irq, void *dev_id)
405 struct irq_desc *desc; 405 struct irq_desc *desc;
406 struct irqaction **p; 406 struct irqaction **p;
407 unsigned long flags; 407 unsigned long flags;
408 irqreturn_t (*handler)(int, void *) = NULL;
409 408
410 WARN_ON(in_interrupt()); 409 WARN_ON(in_interrupt());
411 if (irq >= NR_IRQS) 410 if (irq >= NR_IRQS)
@@ -445,8 +444,21 @@ void free_irq(unsigned int irq, void *dev_id)
445 444
446 /* Make sure it's not being used on another CPU */ 445 /* Make sure it's not being used on another CPU */
447 synchronize_irq(irq); 446 synchronize_irq(irq);
448 if (action->flags & IRQF_SHARED) 447#ifdef CONFIG_DEBUG_SHIRQ
449 handler = action->handler; 448 /*
449 * It's a shared IRQ -- the driver ought to be
450 * prepared for it to happen even now it's
451 * being freed, so let's make sure.... We do
452 * this after actually deregistering it, to
453 * make sure that a 'real' IRQ doesn't run in
454 * parallel with our fake
455 */
456 if (action->flags & IRQF_SHARED) {
457 local_irq_save(flags);
458 action->handler(irq, dev_id);
459 local_irq_restore(flags);
460 }
461#endif
450 kfree(action); 462 kfree(action);
451 return; 463 return;
452 } 464 }
@@ -454,19 +466,6 @@ void free_irq(unsigned int irq, void *dev_id)
454 spin_unlock_irqrestore(&desc->lock, flags); 466 spin_unlock_irqrestore(&desc->lock, flags);
455 return; 467 return;
456 } 468 }
457#ifdef CONFIG_DEBUG_SHIRQ
458 if (handler) {
459 /*
460 * It's a shared IRQ -- the driver ought to be prepared for it
461 * to happen even now it's being freed, so let's make sure....
462 * We do this after actually deregistering it, to make sure that
463 * a 'real' IRQ doesn't run in parallel with our fake
464 */
465 local_irq_save(flags);
466 handler(irq, dev_id);
467 local_irq_restore(flags);
468 }
469#endif
470} 469}
471EXPORT_SYMBOL(free_irq); 470EXPORT_SYMBOL(free_irq);
472 471