aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/pseries/smp.c32
-rw-r--r--arch/powerpc/platforms/pseries/xics.c61
-rw-r--r--arch/powerpc/platforms/pseries/xics.h12
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
108static 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
115static 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
131static int __init smp_xics_probe(void)
132{
133 xics_request_IPIs();
134
135 return cpus_weight(cpu_possible_map);
136}
137
138static void __devinit smp_xics_setup_cpu(int cpu) 108static 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
72static struct irq_host *xics_host; 72static struct irq_host *xics_host;
73 73
74/*
75 * XICS only has a single IPI, so encode the messages per CPU
76 */
77struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
78
79/* RTAS service tokens */ 74/* RTAS service tokens */
80static int ibm_get_xive; 75static int ibm_get_xive;
81static int ibm_set_xive; 76static 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 */
202struct xics_ipi_struct {
203 unsigned long value;
204 } ____cacheline_aligned;
205
206static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
207
204static int get_irq_server(unsigned int virq, unsigned int strict_check) 208static 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
391static irqreturn_t xics_ipi_dispatch(int cpu) 394static 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
425static 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
435void 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
422static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id) 452static 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
440void 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
450static void xics_set_cpu_priority(unsigned char cppr) 471static 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
700void xics_request_IPIs(void) 721static 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
743int __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
723void xics_teardown_cpu(void) 752void 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
17extern void xics_init_IRQ(void); 15extern void xics_init_IRQ(void);
18extern void xics_setup_cpu(void); 16extern void xics_setup_cpu(void);
19extern void xics_teardown_cpu(void); 17extern void xics_teardown_cpu(void);
20extern void xics_kexec_teardown_cpu(int secondary); 18extern void xics_kexec_teardown_cpu(int secondary);
21extern void xics_cause_IPI(int cpu);
22extern void xics_request_IPIs(void);
23extern void xics_migrate_irqs_away(void); 19extern void xics_migrate_irqs_away(void);
24 20extern int smp_xics_probe(void);
25struct xics_ipi_struct { 21extern void smp_xics_message_pass(int target, int msg);
26 volatile unsigned long value;
27} ____cacheline_aligned;
28
29extern 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 */