aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/xics.c
diff options
context:
space:
mode:
authorMilton Miller <miltonm@bga.com>2008-10-09 21:56:34 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-13 01:24:18 -0400
commitb4963255ad5a426f04a0bb15c4315fa4bb40cde9 (patch)
tree18ed300d89d30e20ade63a94f49934b24e76afec /arch/powerpc/platforms/pseries/xics.c
parenta244a957ab15ddbeccf4018ef4b3ac8f5fd1566d (diff)
powerpc/xics: Factor out cpu joining/unjoining the GIQ
This factors out processors joining and unjoining the Global Interrupt Queue into a separate function. There is a bit of math to calculate the arguments to rtas to join or leave the global interrupt queue, and a warning on failure afterwards. Make a helper for the 3 callers. Signed-off-by: Milton Miller <miltonm@bga.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries/xics.c')
-rw-r--r--arch/powerpc/platforms/pseries/xics.c33
1 files changed, 13 insertions, 20 deletions
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 27327fc86055..0bb553331f4f 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -727,20 +727,19 @@ static void xics_set_cpu_priority(unsigned char cppr)
727 iosync(); 727 iosync();
728} 728}
729 729
730/* Have the calling processor join or leave the specified global queue */
731static void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
732{
733 int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
734 (1UL << interrupt_server_size) - 1 - gserver, join);
735 WARN_ON(status < 0);
736}
730 737
731void xics_setup_cpu(void) 738void xics_setup_cpu(void)
732{ 739{
733 xics_set_cpu_priority(0xff); 740 xics_set_cpu_priority(0xff);
734 741
735 /* 742 xics_set_cpu_giq(default_distrib_server, 1);
736 * Put the calling processor into the GIQ. This is really only
737 * necessary from a secondary thread as the OF start-cpu interface
738 * performs this function for us on primary threads.
739 *
740 * XXX: undo of teardown on kexec needs this too, as may hotplug
741 */
742 rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
743 (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
744} 743}
745 744
746void xics_teardown_cpu(void) 745void xics_teardown_cpu(void)
@@ -749,9 +748,7 @@ void xics_teardown_cpu(void)
749 748
750 xics_set_cpu_priority(0); 749 xics_set_cpu_priority(0);
751 750
752 /* 751 /* Clear any pending IPI request */
753 * Clear IPI
754 */
755 if (firmware_has_feature(FW_FEATURE_LPAR)) 752 if (firmware_has_feature(FW_FEATURE_LPAR))
756 lpar_qirr_info(cpu, 0xff); 753 lpar_qirr_info(cpu, 0xff);
757 else 754 else
@@ -785,9 +782,7 @@ void xics_kexec_teardown_cpu(int secondary)
785 * so leave the master cpu in the group. 782 * so leave the master cpu in the group.
786 */ 783 */
787 if (secondary) 784 if (secondary)
788 rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, 785 xics_set_cpu_giq(default_distrib_server, 0);
789 (1UL << interrupt_server_size) - 1 -
790 default_distrib_server, 0);
791} 786}
792 787
793#ifdef CONFIG_HOTPLUG_CPU 788#ifdef CONFIG_HOTPLUG_CPU
@@ -795,7 +790,6 @@ void xics_kexec_teardown_cpu(int secondary)
795/* Interrupts are disabled. */ 790/* Interrupts are disabled. */
796void xics_migrate_irqs_away(void) 791void xics_migrate_irqs_away(void)
797{ 792{
798 int status;
799 int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); 793 int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
800 unsigned int irq, virq; 794 unsigned int irq, virq;
801 795
@@ -806,10 +800,8 @@ void xics_migrate_irqs_away(void)
806 /* Reject any interrupt that was queued to us... */ 800 /* Reject any interrupt that was queued to us... */
807 xics_set_cpu_priority(0); 801 xics_set_cpu_priority(0);
808 802
809 /* remove ourselves from the global interrupt queue */ 803 /* Remove ourselves from the global interrupt queue */
810 status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, 804 xics_set_cpu_giq(default_distrib_server, 0);
811 (1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
812 WARN_ON(status < 0);
813 805
814 /* Allow IPIs again... */ 806 /* Allow IPIs again... */
815 xics_set_cpu_priority(DEFAULT_PRIORITY); 807 xics_set_cpu_priority(DEFAULT_PRIORITY);
@@ -817,6 +809,7 @@ void xics_migrate_irqs_away(void)
817 for_each_irq(virq) { 809 for_each_irq(virq) {
818 struct irq_desc *desc; 810 struct irq_desc *desc;
819 int xics_status[2]; 811 int xics_status[2];
812 int status;
820 unsigned long flags; 813 unsigned long flags;
821 814
822 /* We cant set affinity on ISA interrupts */ 815 /* We cant set affinity on ISA interrupts */