diff options
author | Milton Miller <miltonm@bga.com> | 2008-10-09 21:56:34 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-10-13 01:24:18 -0400 |
commit | b4963255ad5a426f04a0bb15c4315fa4bb40cde9 (patch) | |
tree | 18ed300d89d30e20ade63a94f49934b24e76afec /arch/powerpc/platforms | |
parent | a244a957ab15ddbeccf4018ef4b3ac8f5fd1566d (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')
-rw-r--r-- | arch/powerpc/platforms/pseries/xics.c | 33 |
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 */ | ||
731 | static 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 | ||
731 | void xics_setup_cpu(void) | 738 | void 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 | ||
746 | void xics_teardown_cpu(void) | 745 | void 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. */ |
796 | void xics_migrate_irqs_away(void) | 791 | void 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 */ |