diff options
-rw-r--r-- | arch/powerpc/platforms/pseries/smp.c | 32 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/xics.c | 61 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/xics.h | 12 |
3 files changed, 48 insertions, 57 deletions
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 9d8f8c84ab89..e00f96baa381 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <asm/paca.h> | 37 | #include <asm/paca.h> |
38 | #include <asm/time.h> | 38 | #include <asm/time.h> |
39 | #include <asm/machdep.h> | 39 | #include <asm/machdep.h> |
40 | #include "xics.h" | ||
41 | #include <asm/cputable.h> | 40 | #include <asm/cputable.h> |
42 | #include <asm/firmware.h> | 41 | #include <asm/firmware.h> |
43 | #include <asm/system.h> | 42 | #include <asm/system.h> |
@@ -49,6 +48,7 @@ | |||
49 | 48 | ||
50 | #include "plpar_wrappers.h" | 49 | #include "plpar_wrappers.h" |
51 | #include "pseries.h" | 50 | #include "pseries.h" |
51 | #include "xics.h" | ||
52 | 52 | ||
53 | 53 | ||
54 | /* | 54 | /* |
@@ -105,36 +105,6 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | #ifdef CONFIG_XICS | 107 | #ifdef CONFIG_XICS |
108 | static inline void smp_xics_do_message(int cpu, int msg) | ||
109 | { | ||
110 | set_bit(msg, &xics_ipi_message[cpu].value); | ||
111 | mb(); | ||
112 | xics_cause_IPI(cpu); | ||
113 | } | ||
114 | |||
115 | static void smp_xics_message_pass(int target, int msg) | ||
116 | { | ||
117 | unsigned int i; | ||
118 | |||
119 | if (target < NR_CPUS) { | ||
120 | smp_xics_do_message(target, msg); | ||
121 | } else { | ||
122 | for_each_online_cpu(i) { | ||
123 | if (target == MSG_ALL_BUT_SELF | ||
124 | && i == smp_processor_id()) | ||
125 | continue; | ||
126 | smp_xics_do_message(i, msg); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static int __init smp_xics_probe(void) | ||
132 | { | ||
133 | xics_request_IPIs(); | ||
134 | |||
135 | return cpus_weight(cpu_possible_map); | ||
136 | } | ||
137 | |||
138 | static void __devinit smp_xics_setup_cpu(int cpu) | 108 | static void __devinit smp_xics_setup_cpu(int cpu) |
139 | { | 109 | { |
140 | if (cpu != boot_cpuid) | 110 | if (cpu != boot_cpuid) |
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index c95697912fea..c0cb356833fa 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -71,11 +71,6 @@ static unsigned int interrupt_server_size = 8; | |||
71 | 71 | ||
72 | static struct irq_host *xics_host; | 72 | static struct irq_host *xics_host; |
73 | 73 | ||
74 | /* | ||
75 | * XICS only has a single IPI, so encode the messages per CPU | ||
76 | */ | ||
77 | struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; | ||
78 | |||
79 | /* RTAS service tokens */ | 74 | /* RTAS service tokens */ |
80 | static int ibm_get_xive; | 75 | static int ibm_get_xive; |
81 | static int ibm_set_xive; | 76 | static int ibm_set_xive; |
@@ -201,6 +196,15 @@ static void xics_update_irq_servers(void) | |||
201 | } | 196 | } |
202 | 197 | ||
203 | #ifdef CONFIG_SMP | 198 | #ifdef CONFIG_SMP |
199 | /* | ||
200 | * XICS only has a single IPI, so encode the messages per CPU | ||
201 | */ | ||
202 | struct xics_ipi_struct { | ||
203 | unsigned long value; | ||
204 | } ____cacheline_aligned; | ||
205 | |||
206 | static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; | ||
207 | |||
204 | static int get_irq_server(unsigned int virq, unsigned int strict_check) | 208 | static int get_irq_server(unsigned int virq, unsigned int strict_check) |
205 | { | 209 | { |
206 | int server; | 210 | int server; |
@@ -387,7 +391,6 @@ static unsigned int xics_get_irq_lpar(void) | |||
387 | } | 391 | } |
388 | 392 | ||
389 | #ifdef CONFIG_SMP | 393 | #ifdef CONFIG_SMP |
390 | |||
391 | static irqreturn_t xics_ipi_dispatch(int cpu) | 394 | static irqreturn_t xics_ipi_dispatch(int cpu) |
392 | { | 395 | { |
393 | WARN_ON(cpu_is_offline(cpu)); | 396 | WARN_ON(cpu_is_offline(cpu)); |
@@ -419,6 +422,33 @@ static irqreturn_t xics_ipi_dispatch(int cpu) | |||
419 | return IRQ_HANDLED; | 422 | return IRQ_HANDLED; |
420 | } | 423 | } |
421 | 424 | ||
425 | static inline void smp_xics_do_message(int cpu, int msg) | ||
426 | { | ||
427 | set_bit(msg, &xics_ipi_message[cpu].value); | ||
428 | mb(); | ||
429 | if (firmware_has_feature(FW_FEATURE_LPAR)) | ||
430 | lpar_qirr_info(cpu, IPI_PRIORITY); | ||
431 | else | ||
432 | direct_qirr_info(cpu, IPI_PRIORITY); | ||
433 | } | ||
434 | |||
435 | void smp_xics_message_pass(int target, int msg) | ||
436 | { | ||
437 | unsigned int i; | ||
438 | |||
439 | if (target < NR_CPUS) { | ||
440 | smp_xics_do_message(target, msg); | ||
441 | } else { | ||
442 | for_each_online_cpu(i) { | ||
443 | if (target == MSG_ALL_BUT_SELF | ||
444 | && i == smp_processor_id()) | ||
445 | continue; | ||
446 | smp_xics_do_message(i, msg); | ||
447 | } | ||
448 | } | ||
449 | } | ||
450 | |||
451 | |||
422 | static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id) | 452 | static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id) |
423 | { | 453 | { |
424 | int cpu = smp_processor_id(); | 454 | int cpu = smp_processor_id(); |
@@ -436,15 +466,6 @@ static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id) | |||
436 | 466 | ||
437 | return xics_ipi_dispatch(cpu); | 467 | return xics_ipi_dispatch(cpu); |
438 | } | 468 | } |
439 | |||
440 | void xics_cause_IPI(int cpu) | ||
441 | { | ||
442 | if (firmware_has_feature(FW_FEATURE_LPAR)) | ||
443 | lpar_qirr_info(cpu, IPI_PRIORITY); | ||
444 | else | ||
445 | direct_qirr_info(cpu, IPI_PRIORITY); | ||
446 | } | ||
447 | |||
448 | #endif /* CONFIG_SMP */ | 469 | #endif /* CONFIG_SMP */ |
449 | 470 | ||
450 | static void xics_set_cpu_priority(unsigned char cppr) | 471 | static void xics_set_cpu_priority(unsigned char cppr) |
@@ -697,7 +718,7 @@ void __init xics_init_IRQ(void) | |||
697 | 718 | ||
698 | 719 | ||
699 | #ifdef CONFIG_SMP | 720 | #ifdef CONFIG_SMP |
700 | void xics_request_IPIs(void) | 721 | static void xics_request_ipi(void) |
701 | { | 722 | { |
702 | unsigned int ipi; | 723 | unsigned int ipi; |
703 | int rc; | 724 | int rc; |
@@ -718,6 +739,14 @@ void xics_request_IPIs(void) | |||
718 | "IPI", NULL); | 739 | "IPI", NULL); |
719 | BUG_ON(rc); | 740 | BUG_ON(rc); |
720 | } | 741 | } |
742 | |||
743 | int __init smp_xics_probe(void) | ||
744 | { | ||
745 | xics_request_ipi(); | ||
746 | |||
747 | return cpus_weight(cpu_possible_map); | ||
748 | } | ||
749 | |||
721 | #endif /* CONFIG_SMP */ | 750 | #endif /* CONFIG_SMP */ |
722 | 751 | ||
723 | void xics_teardown_cpu(void) | 752 | void xics_teardown_cpu(void) |
diff --git a/arch/powerpc/platforms/pseries/xics.h b/arch/powerpc/platforms/pseries/xics.h index 1c5321ae8f2f..d1d5a83039ae 100644 --- a/arch/powerpc/platforms/pseries/xics.h +++ b/arch/powerpc/platforms/pseries/xics.h | |||
@@ -12,20 +12,12 @@ | |||
12 | #ifndef _POWERPC_KERNEL_XICS_H | 12 | #ifndef _POWERPC_KERNEL_XICS_H |
13 | #define _POWERPC_KERNEL_XICS_H | 13 | #define _POWERPC_KERNEL_XICS_H |
14 | 14 | ||
15 | #include <linux/cache.h> | ||
16 | |||
17 | extern void xics_init_IRQ(void); | 15 | extern void xics_init_IRQ(void); |
18 | extern void xics_setup_cpu(void); | 16 | extern void xics_setup_cpu(void); |
19 | extern void xics_teardown_cpu(void); | 17 | extern void xics_teardown_cpu(void); |
20 | extern void xics_kexec_teardown_cpu(int secondary); | 18 | extern void xics_kexec_teardown_cpu(int secondary); |
21 | extern void xics_cause_IPI(int cpu); | ||
22 | extern void xics_request_IPIs(void); | ||
23 | extern void xics_migrate_irqs_away(void); | 19 | extern void xics_migrate_irqs_away(void); |
24 | 20 | extern int smp_xics_probe(void); | |
25 | struct xics_ipi_struct { | 21 | extern void smp_xics_message_pass(int target, int msg); |
26 | volatile unsigned long value; | ||
27 | } ____cacheline_aligned; | ||
28 | |||
29 | extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; | ||
30 | 22 | ||
31 | #endif /* _POWERPC_KERNEL_XICS_H */ | 23 | #endif /* _POWERPC_KERNEL_XICS_H */ |