diff options
author | Milton Miller <miltonm@bga.com> | 2008-10-10 05:56:34 +0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-10-13 09:24:18 +0400 |
commit | b4963255ad5a426f04a0bb15c4315fa4bb40cde9 (patch) | |
tree | 18ed300d89d30e20ade63a94f49934b24e76afec /arch/powerpc/platforms/pseries/xics.c | |
parent | a244a957ab15ddbeccf4018ef4b3ac8f5fd1566d (diff) | |
download | linux-b4963255ad5a426f04a0bb15c4315fa4bb40cde9.tar.xz |
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.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) iosync(); } +/* Have the calling processor join or leave the specified global queue */ +static void xics_set_cpu_giq(unsigned int gserver, unsigned int join) +{ + int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, + (1UL << interrupt_server_size) - 1 - gserver, join); + WARN_ON(status < 0); +} void xics_setup_cpu(void) { xics_set_cpu_priority(0xff); - /* - * Put the calling processor into the GIQ. This is really only - * necessary from a secondary thread as the OF start-cpu interface - * performs this function for us on primary threads. - * - * XXX: undo of teardown on kexec needs this too, as may hotplug - */ - rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, - (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); + xics_set_cpu_giq(default_distrib_server, 1); } void xics_teardown_cpu(void) @@ -749,9 +748,7 @@ void xics_teardown_cpu(void) xics_set_cpu_priority(0); - /* - * Clear IPI - */ + /* Clear any pending IPI request */ if (firmware_has_feature(FW_FEATURE_LPAR)) lpar_qirr_info(cpu, 0xff); else @@ -785,9 +782,7 @@ void xics_kexec_teardown_cpu(int secondary) * so leave the master cpu in the group. */ if (secondary) - rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, - (1UL << interrupt_server_size) - 1 - - default_distrib_server, 0); + xics_set_cpu_giq(default_distrib_server, 0); } #ifdef CONFIG_HOTPLUG_CPU @@ -795,7 +790,6 @@ void xics_kexec_teardown_cpu(int secondary) /* Interrupts are disabled. */ void xics_migrate_irqs_away(void) { - int status; int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); unsigned int irq, virq; @@ -806,10 +800,8 @@ void xics_migrate_irqs_away(void) /* Reject any interrupt that was queued to us... */ xics_set_cpu_priority(0); - /* remove ourselves from the global interrupt queue */ - status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, - (1UL << interrupt_server_size) - 1 - default_distrib_server, 0); - WARN_ON(status < 0); + /* Remove ourselves from the global interrupt queue */ + xics_set_cpu_giq(default_distrib_server, 0); /* Allow IPIs again... */ xics_set_cpu_priority(DEFAULT_PRIORITY); @@ -817,6 +809,7 @@ void xics_migrate_irqs_away(void) for_each_irq(virq) { struct irq_desc *desc; int xics_status[2]; + int status; unsigned long flags; /* We cant set affinity on ISA interrupts */ |