manage.c (7acdd53e5b2c55b6f7e3427e85e2f91fa814a4f9) | manage.c (009b4c3b8ad584b3462734127a5bec680d5d6af4) |
---|---|
1/* 2 * linux/kernel/irq/manage.c 3 * 4 * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar 5 * Copyright (C) 2005-2006 Thomas Gleixner 6 * 7 * This file contains driver APIs to the irq subsystem. 8 */ --- 16 unchanged lines hidden (view full) --- 25 * to complete before returning. If you use this function while 26 * holding a resource the IRQ handler may need you will deadlock. 27 * 28 * This function may be called - with care - from IRQ context. 29 */ 30void synchronize_irq(unsigned int irq) 31{ 32 struct irq_desc *desc = irq_to_desc(irq); | 1/* 2 * linux/kernel/irq/manage.c 3 * 4 * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar 5 * Copyright (C) 2005-2006 Thomas Gleixner 6 * 7 * This file contains driver APIs to the irq subsystem. 8 */ --- 16 unchanged lines hidden (view full) --- 25 * to complete before returning. If you use this function while 26 * holding a resource the IRQ handler may need you will deadlock. 27 * 28 * This function may be called - with care - from IRQ context. 29 */ 30void synchronize_irq(unsigned int irq) 31{ 32 struct irq_desc *desc = irq_to_desc(irq); |
33 unsigned int status; | 33 unsigned int state; |
34 35 if (!desc) 36 return; 37 38 do { 39 unsigned long flags; 40 41 /* 42 * Wait until we're out of the critical section. This might 43 * give the wrong answer due to the lack of memory barriers. 44 */ | 34 35 if (!desc) 36 return; 37 38 do { 39 unsigned long flags; 40 41 /* 42 * Wait until we're out of the critical section. This might 43 * give the wrong answer due to the lack of memory barriers. 44 */ |
45 while (desc->status & IRQ_INPROGRESS) | 45 while (desc->istate & IRQS_INPROGRESS) |
46 cpu_relax(); 47 48 /* Ok, that indicated we're done: double-check carefully. */ 49 raw_spin_lock_irqsave(&desc->lock, flags); | 46 cpu_relax(); 47 48 /* Ok, that indicated we're done: double-check carefully. */ 49 raw_spin_lock_irqsave(&desc->lock, flags); |
50 status = desc->status; | 50 state = desc->istate; |
51 raw_spin_unlock_irqrestore(&desc->lock, flags); 52 53 /* Oops, that failed? */ | 51 raw_spin_unlock_irqrestore(&desc->lock, flags); 52 53 /* Oops, that failed? */ |
54 } while (status & IRQ_INPROGRESS); | 54 } while (state & IRQS_INPROGRESS); |
55 56 /* 57 * We made sure that no hardirq handler is running. Now verify 58 * that no threaded handlers are active. 59 */ 60 wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active)); 61} 62EXPORT_SYMBOL(synchronize_irq); --- 569 unchanged lines hidden (view full) --- 632 633 /* 634 * Implausible though it may be we need to protect us against 635 * the following scenario: 636 * 637 * The thread is faster done than the hard interrupt handler 638 * on the other CPU. If we unmask the irq line then the 639 * interrupt can come in again and masks the line, leaves due | 55 56 /* 57 * We made sure that no hardirq handler is running. Now verify 58 * that no threaded handlers are active. 59 */ 60 wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active)); 61} 62EXPORT_SYMBOL(synchronize_irq); --- 569 unchanged lines hidden (view full) --- 632 633 /* 634 * Implausible though it may be we need to protect us against 635 * the following scenario: 636 * 637 * The thread is faster done than the hard interrupt handler 638 * on the other CPU. If we unmask the irq line then the 639 * interrupt can come in again and masks the line, leaves due |
640 * to IRQ_INPROGRESS and the irq line is masked forever. | 640 * to IRQS_INPROGRESS and the irq line is masked forever. |
641 */ | 641 */ |
642 if (unlikely(desc->status & IRQ_INPROGRESS)) { | 642 if (unlikely(desc->istate & IRQS_INPROGRESS)) { |
643 raw_spin_unlock_irq(&desc->lock); 644 chip_bus_sync_unlock(desc); 645 cpu_relax(); 646 goto again; 647 } 648 649 if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) { 650 desc->status &= ~IRQ_MASKED; --- 241 unchanged lines hidden (view full) --- 892 goto out_mask; 893 } else 894 compat_irq_chip_set_default_handler(desc); 895#if defined(CONFIG_IRQ_PER_CPU) 896 if (new->flags & IRQF_PERCPU) 897 desc->status |= IRQ_PER_CPU; 898#endif 899 | 643 raw_spin_unlock_irq(&desc->lock); 644 chip_bus_sync_unlock(desc); 645 cpu_relax(); 646 goto again; 647 } 648 649 if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) { 650 desc->status &= ~IRQ_MASKED; --- 241 unchanged lines hidden (view full) --- 892 goto out_mask; 893 } else 894 compat_irq_chip_set_default_handler(desc); 895#if defined(CONFIG_IRQ_PER_CPU) 896 if (new->flags & IRQF_PERCPU) 897 desc->status |= IRQ_PER_CPU; 898#endif 899 |
900 desc->status &= ~(IRQ_WAITING | IRQ_ONESHOT | IRQ_INPROGRESS); 901 desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED); | 900 desc->status &= ~(IRQ_WAITING | IRQ_ONESHOT); 901 desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \ 902 IRQS_INPROGRESS); |
902 903 if (new->flags & IRQF_ONESHOT) 904 desc->status |= IRQ_ONESHOT; 905 906 if (!(desc->status & IRQ_NOAUTOEN)) 907 irq_startup(desc); 908 else 909 /* Undo nested disables: */ --- 378 unchanged lines hidden --- | 903 904 if (new->flags & IRQF_ONESHOT) 905 desc->status |= IRQ_ONESHOT; 906 907 if (!(desc->status & IRQ_NOAUTOEN)) 908 irq_startup(desc); 909 else 910 /* Undo nested disables: */ --- 378 unchanged lines hidden --- |