aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/manage.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r--kernel/irq/manage.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index d7f7b5fd2476..0a3fd5b524c9 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -230,9 +230,11 @@ void disable_irq_nosync(unsigned int irq)
230 if (!desc) 230 if (!desc)
231 return; 231 return;
232 232
233 chip_bus_lock(irq, desc);
233 spin_lock_irqsave(&desc->lock, flags); 234 spin_lock_irqsave(&desc->lock, flags);
234 __disable_irq(desc, irq, false); 235 __disable_irq(desc, irq, false);
235 spin_unlock_irqrestore(&desc->lock, flags); 236 spin_unlock_irqrestore(&desc->lock, flags);
237 chip_bus_sync_unlock(irq, desc);
236} 238}
237EXPORT_SYMBOL(disable_irq_nosync); 239EXPORT_SYMBOL(disable_irq_nosync);
238 240
@@ -294,7 +296,8 @@ void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
294 * matches the last disable, processing of interrupts on this 296 * matches the last disable, processing of interrupts on this
295 * IRQ line is re-enabled. 297 * IRQ line is re-enabled.
296 * 298 *
297 * This function may be called from IRQ context. 299 * This function may be called from IRQ context only when
300 * desc->chip->bus_lock and desc->chip->bus_sync_unlock are NULL !
298 */ 301 */
299void enable_irq(unsigned int irq) 302void enable_irq(unsigned int irq)
300{ 303{
@@ -304,9 +307,11 @@ void enable_irq(unsigned int irq)
304 if (!desc) 307 if (!desc)
305 return; 308 return;
306 309
310 chip_bus_lock(irq, desc);
307 spin_lock_irqsave(&desc->lock, flags); 311 spin_lock_irqsave(&desc->lock, flags);
308 __enable_irq(desc, irq, false); 312 __enable_irq(desc, irq, false);
309 spin_unlock_irqrestore(&desc->lock, flags); 313 spin_unlock_irqrestore(&desc->lock, flags);
314 chip_bus_sync_unlock(irq, desc);
310} 315}
311EXPORT_SYMBOL(enable_irq); 316EXPORT_SYMBOL(enable_irq);
312 317
@@ -468,12 +473,14 @@ static int irq_wait_for_interrupt(struct irqaction *action)
468 */ 473 */
469static void irq_finalize_oneshot(unsigned int irq, struct irq_desc *desc) 474static void irq_finalize_oneshot(unsigned int irq, struct irq_desc *desc)
470{ 475{
476 chip_bus_lock(irq, desc);
471 spin_lock_irq(&desc->lock); 477 spin_lock_irq(&desc->lock);
472 if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) { 478 if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) {
473 desc->status &= ~IRQ_MASKED; 479 desc->status &= ~IRQ_MASKED;
474 desc->chip->unmask(irq); 480 desc->chip->unmask(irq);
475 } 481 }
476 spin_unlock_irq(&desc->lock); 482 spin_unlock_irq(&desc->lock);
483 chip_bus_sync_unlock(irq, desc);
477} 484}
478 485
479#ifdef CONFIG_SMP 486#ifdef CONFIG_SMP
@@ -904,7 +911,14 @@ EXPORT_SYMBOL_GPL(remove_irq);
904 */ 911 */
905void free_irq(unsigned int irq, void *dev_id) 912void free_irq(unsigned int irq, void *dev_id)
906{ 913{
914 struct irq_desc *desc = irq_to_desc(irq);
915
916 if (!desc)
917 return;
918
919 chip_bus_lock(irq, desc);
907 kfree(__free_irq(irq, dev_id)); 920 kfree(__free_irq(irq, dev_id));
921 chip_bus_sync_unlock(irq, desc);
908} 922}
909EXPORT_SYMBOL(free_irq); 923EXPORT_SYMBOL(free_irq);
910 924
@@ -1011,7 +1025,10 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
1011 action->name = devname; 1025 action->name = devname;
1012 action->dev_id = dev_id; 1026 action->dev_id = dev_id;
1013 1027
1028 chip_bus_lock(irq, desc);
1014 retval = __setup_irq(irq, desc, action); 1029 retval = __setup_irq(irq, desc, action);
1030 chip_bus_sync_unlock(irq, desc);
1031
1015 if (retval) 1032 if (retval)
1016 kfree(action); 1033 kfree(action);
1017 1034