aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilton Miller <miltonm@bga.com>2011-05-10 15:30:44 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-05-19 02:54:46 -0400
commit41fb5e62604c5ddd00a784ffb7672dd8df5d76f2 (patch)
tree9d0629053e1c528adb7a9f29e4850453732cc4ed
parent1e8c23013ed0d535e531b3b9cc30200e884f3ff0 (diff)
powerpc: Make IRQ_NOREQUEST last to clear, first to set
When creating an irq, don't allow a concurent driver request until we have caled map, which will likley call set_chip_and_handler to change the irq_chip and its operations. Similarly, when tearing down an IRQ, make sure no new uses come along while we change the irq back to the nop chip and then reset the descriptor to freed status. Signed-off-by: Milton Miller <miltonm@bga.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/kernel/irq.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 4368b5ed5604..a24d37d4cf51 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -586,14 +586,14 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
586 irq_map[i].host = host; 586 irq_map[i].host = host;
587 smp_wmb(); 587 smp_wmb();
588 588
589 /* Clear norequest flags */
590 irq_clear_status_flags(i, IRQ_NOREQUEST);
591
592 /* Legacy flags are left to default at this point, 589 /* Legacy flags are left to default at this point,
593 * one can then use irq_create_mapping() to 590 * one can then use irq_create_mapping() to
594 * explicitly change them 591 * explicitly change them
595 */ 592 */
596 ops->map(host, i, i); 593 ops->map(host, i, i);
594
595 /* Clear norequest flags */
596 irq_clear_status_flags(i, IRQ_NOREQUEST);
597 } 597 }
598 break; 598 break;
599 case IRQ_HOST_MAP_LINEAR: 599 case IRQ_HOST_MAP_LINEAR:
@@ -664,8 +664,6 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
664 goto error; 664 goto error;
665 } 665 }
666 666
667 irq_clear_status_flags(virq, IRQ_NOREQUEST);
668
669 /* map it */ 667 /* map it */
670 smp_wmb(); 668 smp_wmb();
671 irq_map[virq].hwirq = hwirq; 669 irq_map[virq].hwirq = hwirq;
@@ -676,6 +674,8 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
676 goto errdesc; 674 goto errdesc;
677 } 675 }
678 676
677 irq_clear_status_flags(virq, IRQ_NOREQUEST);
678
679 return 0; 679 return 0;
680 680
681errdesc: 681errdesc:
@@ -819,6 +819,8 @@ void irq_dispose_mapping(unsigned int virq)
819 if (host->revmap_type == IRQ_HOST_MAP_LEGACY) 819 if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
820 return; 820 return;
821 821
822 irq_set_status_flags(virq, IRQ_NOREQUEST);
823
822 /* remove chip and handler */ 824 /* remove chip and handler */
823 irq_set_chip_and_handler(virq, NULL, NULL); 825 irq_set_chip_and_handler(virq, NULL, NULL);
824 826
@@ -848,8 +850,6 @@ void irq_dispose_mapping(unsigned int virq)
848 smp_mb(); 850 smp_mb();
849 irq_map[virq].hwirq = host->inval_irq; 851 irq_map[virq].hwirq = host->inval_irq;
850 852
851 irq_set_status_flags(virq, IRQ_NOREQUEST);
852
853 irq_free_descs(virq, 1); 853 irq_free_descs(virq, 1);
854 /* Free it */ 854 /* Free it */
855 irq_free_virt(virq, 1); 855 irq_free_virt(virq, 1);