aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/40x/Kconfig1
-rw-r--r--arch/powerpc/platforms/40x/virtex.c2
-rw-r--r--arch/powerpc/platforms/40x/walnut.c1
-rw-r--r--arch/powerpc/platforms/44x/warp.c2
-rw-r--r--arch/powerpc/platforms/512x/Kconfig20
-rw-r--r--arch/powerpc/platforms/512x/Makefile4
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads.c104
-rw-r--r--arch/powerpc/platforms/82xx/mpc8272_ads.c3
-rw-r--r--arch/powerpc/platforms/82xx/pq2fads.c3
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc83xx.h2
-rw-r--r--arch/powerpc/platforms/83xx/usb.c17
-rw-r--r--arch/powerpc/platforms/8xx/adder875.c6
-rw-r--r--arch/powerpc/platforms/8xx/ep88xc.c1
-rw-r--r--arch/powerpc/platforms/Kconfig2
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype10
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/cell/Kconfig7
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c99
-rw-r--r--arch/powerpc/platforms/cell/setup.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c6
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c29
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c7
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c28
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h5
-rw-r--r--arch/powerpc/platforms/cell/spufs/sputrace.c250
-rw-r--r--arch/powerpc/platforms/embedded6xx/storcenter.c25
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c2
-rw-r--r--arch/powerpc/platforms/pseries/kexec.c2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c1
-rw-r--r--arch/powerpc/platforms/pseries/xics.c118
-rw-r--r--arch/powerpc/platforms/pseries/xics.h3
33 files changed, 592 insertions, 175 deletions
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index 74f31177e47a..a9260e21451e 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -72,6 +72,7 @@ config WALNUT
72 default y 72 default y
73 select 405GP 73 select 405GP
74 select PCI 74 select PCI
75 select OF_RTC
75 help 76 help
76 This option enables support for the IBM PPC405GP evaluation board. 77 This option enables support for the IBM PPC405GP evaluation board.
77 78
diff --git a/arch/powerpc/platforms/40x/virtex.c b/arch/powerpc/platforms/40x/virtex.c
index 88b66444dfb2..0422590040db 100644
--- a/arch/powerpc/platforms/40x/virtex.c
+++ b/arch/powerpc/platforms/40x/virtex.c
@@ -37,7 +37,7 @@ static int __init virtex_probe(void)
37{ 37{
38 unsigned long root = of_get_flat_dt_root(); 38 unsigned long root = of_get_flat_dt_root();
39 39
40 if (!of_flat_dt_is_compatible(root, "xilinx,virtex")) 40 if (!of_flat_dt_is_compatible(root, "xlnx,virtex"))
41 return 0; 41 return 0;
42 42
43 return 1; 43 return 1;
diff --git a/arch/powerpc/platforms/40x/walnut.c b/arch/powerpc/platforms/40x/walnut.c
index 5d9edd917f92..b8b257efeb77 100644
--- a/arch/powerpc/platforms/40x/walnut.c
+++ b/arch/powerpc/platforms/40x/walnut.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/of_platform.h> 20#include <linux/of_platform.h>
21#include <linux/rtc.h>
21 22
22#include <asm/machdep.h> 23#include <asm/machdep.h>
23#include <asm/prom.h> 24#include <asm/prom.h>
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 8f01563dbd2a..da5b7b7599db 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -137,7 +137,7 @@ static int __init pika_dtm_start(void)
137 } 137 }
138 of_node_put(np); 138 of_node_put(np);
139 139
140 fpga = ioremap(res.start + 0x20, 4); 140 fpga = ioremap(res.start, 0x24);
141 if (fpga == NULL) 141 if (fpga == NULL)
142 return -ENOENT; 142 return -ENOENT;
143 143
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
new file mode 100644
index 000000000000..c6fa49e23dc0
--- /dev/null
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -0,0 +1,20 @@
1config PPC_MPC512x
2 bool
3 select FSL_SOC
4 select IPIC
5 default n
6
7config PPC_MPC5121
8 bool
9 select PPC_MPC512x
10 default n
11
12config MPC5121_ADS
13 bool "Freescale MPC5121E ADS"
14 depends on PPC_MULTIPLATFORM && PPC32
15 select DEFAULT_UIMAGE
16 select WANT_DEVICE_TREE
17 select PPC_MPC5121
18 help
19 This option enables support for the MPC5121E ADS board.
20 default n
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
new file mode 100644
index 000000000000..232c89f2039a
--- /dev/null
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -0,0 +1,4 @@
1#
2# Makefile for the Freescale PowerPC 512x linux kernel.
3#
4obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c
new file mode 100644
index 000000000000..50bd3a319022
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc5121_ads.c
@@ -0,0 +1,104 @@
1/*
2 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby, <jrigby@freescale.com>, Thur Mar 29 2007
5 *
6 * Description:
7 * MPC5121 ADS board setup
8 *
9 * This is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/of_platform.h>
20
21#include <asm/machdep.h>
22#include <asm/ipic.h>
23#include <asm/prom.h>
24#include <asm/time.h>
25
26/**
27 * mpc512x_find_ips_freq - Find the IPS bus frequency for a device
28 * @node: device node
29 *
30 * Returns IPS bus frequency, or 0 if the bus frequency cannot be found.
31 */
32unsigned long
33mpc512x_find_ips_freq(struct device_node *node)
34{
35 struct device_node *np;
36 const unsigned int *p_ips_freq = NULL;
37
38 of_node_get(node);
39 while (node) {
40 p_ips_freq = of_get_property(node, "bus-frequency", NULL);
41 if (p_ips_freq)
42 break;
43
44 np = of_get_parent(node);
45 of_node_put(node);
46 node = np;
47 }
48 if (node)
49 of_node_put(node);
50
51 return p_ips_freq ? *p_ips_freq : 0;
52}
53EXPORT_SYMBOL(mpc512x_find_ips_freq);
54
55static struct of_device_id __initdata of_bus_ids[] = {
56 { .name = "soc", },
57 { .name = "localbus", },
58 {},
59};
60
61static void __init mpc5121_ads_declare_of_platform_devices(void)
62{
63 /* Find every child of the SOC node and add it to of_platform */
64 if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
65 printk(KERN_ERR __FILE__ ": "
66 "Error while probing of_platform bus\n");
67}
68
69static void __init mpc5121_ads_init_IRQ(void)
70{
71 struct device_node *np;
72
73 np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
74 if (!np)
75 return;
76
77 ipic_init(np, 0);
78 of_node_put(np);
79
80 /*
81 * Initialize the default interrupt mapping priorities,
82 * in case the boot rom changed something on us.
83 */
84 ipic_set_default_priority();
85}
86
87/*
88 * Called very early, MMU is off, device-tree isn't unflattened
89 */
90static int __init mpc5121_ads_probe(void)
91{
92 unsigned long root = of_get_flat_dt_root();
93
94 return of_flat_dt_is_compatible(root, "fsl,mpc5121ads");
95}
96
97define_machine(mpc5121_ads) {
98 .name = "MPC5121 ADS",
99 .probe = mpc5121_ads_probe,
100 .init = mpc5121_ads_declare_of_platform_devices,
101 .init_IRQ = mpc5121_ads_init_IRQ,
102 .get_irq = ipic_get_irq,
103 .calibrate_decr = generic_calibrate_decr,
104};
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
index 3fce6b375dbc..7d3018751988 100644
--- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -134,13 +134,12 @@ static void __init mpc8272_ads_setup_arch(void)
134 } 134 }
135 135
136 bcsr = of_iomap(np, 0); 136 bcsr = of_iomap(np, 0);
137 of_node_put(np);
137 if (!bcsr) { 138 if (!bcsr) {
138 printk(KERN_ERR "Cannot map BCSR registers\n"); 139 printk(KERN_ERR "Cannot map BCSR registers\n");
139 return; 140 return;
140 } 141 }
141 142
142 of_node_put(np);
143
144 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN); 143 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
145 setbits32(&bcsr[1], BCSR1_FETH_RST); 144 setbits32(&bcsr[1], BCSR1_FETH_RST);
146 145
diff --git a/arch/powerpc/platforms/82xx/pq2fads.c b/arch/powerpc/platforms/82xx/pq2fads.c
index 68196e349994..e1dceeec4994 100644
--- a/arch/powerpc/platforms/82xx/pq2fads.c
+++ b/arch/powerpc/platforms/82xx/pq2fads.c
@@ -130,13 +130,12 @@ static void __init pq2fads_setup_arch(void)
130 } 130 }
131 131
132 bcsr = of_iomap(np, 0); 132 bcsr = of_iomap(np, 0);
133 of_node_put(np);
133 if (!bcsr) { 134 if (!bcsr) {
134 printk(KERN_ERR "Cannot map BCSR registers\n"); 135 printk(KERN_ERR "Cannot map BCSR registers\n");
135 return; 136 return;
136 } 137 }
137 138
138 of_node_put(np);
139
140 /* Enable the serial and ethernet ports */ 139 /* Enable the serial and ethernet ports */
141 140
142 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN); 141 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 9f0fd88b2b1f..e7f706b624fe 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -101,7 +101,7 @@ static void __init mpc832x_rdb_setup_arch(void)
101#ifdef CONFIG_QUICC_ENGINE 101#ifdef CONFIG_QUICC_ENGINE
102 qe_reset(); 102 qe_reset();
103 103
104 if ((np = of_find_node_by_name(np, "par_io")) != NULL) { 104 if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) {
105 par_io_init(np); 105 par_io_init(np);
106 of_node_put(np); 106 of_node_put(np);
107 107
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index 88bb748aff0d..68065e62fc3d 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -14,6 +14,8 @@
14#define MPC83XX_SCCR_USB_DRCM_11 0x00300000 14#define MPC83XX_SCCR_USB_DRCM_11 0x00300000
15#define MPC83XX_SCCR_USB_DRCM_01 0x00100000 15#define MPC83XX_SCCR_USB_DRCM_01 0x00100000
16#define MPC83XX_SCCR_USB_DRCM_10 0x00200000 16#define MPC83XX_SCCR_USB_DRCM_10 0x00200000
17#define MPC8315_SCCR_USB_MASK 0x00c00000
18#define MPC8315_SCCR_USB_DRCM_11 0x00c00000
17#define MPC837X_SCCR_USB_DRCM_11 0x00c00000 19#define MPC837X_SCCR_USB_DRCM_11 0x00c00000
18 20
19/* system i/o configuration register low */ 21/* system i/o configuration register low */
diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c
index 681230a30acd..471fdd8f4108 100644
--- a/arch/powerpc/platforms/83xx/usb.c
+++ b/arch/powerpc/platforms/83xx/usb.c
@@ -104,6 +104,7 @@ int mpc831x_usb_cfg(void)
104 u32 temp; 104 u32 temp;
105 void __iomem *immap, *usb_regs; 105 void __iomem *immap, *usb_regs;
106 struct device_node *np = NULL; 106 struct device_node *np = NULL;
107 struct device_node *immr_node = NULL;
107 const void *prop; 108 const void *prop;
108 struct resource res; 109 struct resource res;
109 int ret = 0; 110 int ret = 0;
@@ -124,10 +125,15 @@ int mpc831x_usb_cfg(void)
124 } 125 }
125 126
126 /* Configure clock */ 127 /* Configure clock */
127 temp = in_be32(immap + MPC83XX_SCCR_OFFS); 128 immr_node = of_get_parent(np);
128 temp &= ~MPC83XX_SCCR_USB_MASK; 129 if (immr_node && of_device_is_compatible(immr_node, "fsl,mpc8315-immr"))
129 temp |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */ 130 clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
130 out_be32(immap + MPC83XX_SCCR_OFFS, temp); 131 MPC8315_SCCR_USB_MASK,
132 MPC8315_SCCR_USB_DRCM_11);
133 else
134 clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
135 MPC83XX_SCCR_USB_MASK,
136 MPC83XX_SCCR_USB_DRCM_11);
131 137
132 /* Configure pin mux for ULPI. There is no pin mux for UTMI */ 138 /* Configure pin mux for ULPI. There is no pin mux for UTMI */
133 if (prop && !strcmp(prop, "ulpi")) { 139 if (prop && !strcmp(prop, "ulpi")) {
@@ -144,6 +150,9 @@ int mpc831x_usb_cfg(void)
144 150
145 iounmap(immap); 151 iounmap(immap);
146 152
153 if (immr_node)
154 of_node_put(immr_node);
155
147 /* Map USB SOC space */ 156 /* Map USB SOC space */
148 ret = of_address_to_resource(np, 0, &res); 157 ret = of_address_to_resource(np, 0, &res);
149 if (ret) { 158 if (ret) {
diff --git a/arch/powerpc/platforms/8xx/adder875.c b/arch/powerpc/platforms/8xx/adder875.c
index c6bc0783c3b0..82363e98f50e 100644
--- a/arch/powerpc/platforms/8xx/adder875.c
+++ b/arch/powerpc/platforms/8xx/adder875.c
@@ -15,12 +15,12 @@
15 15
16#include <asm/time.h> 16#include <asm/time.h>
17#include <asm/machdep.h> 17#include <asm/machdep.h>
18#include <asm/commproc.h> 18#include <asm/cpm1.h>
19#include <asm/fs_pd.h> 19#include <asm/fs_pd.h>
20#include <asm/udbg.h> 20#include <asm/udbg.h>
21#include <asm/prom.h> 21#include <asm/prom.h>
22 22
23#include <sysdev/commproc.h> 23#include "mpc8xx.h"
24 24
25struct cpm_pin { 25struct cpm_pin {
26 int port, pin, flags; 26 int port, pin, flags;
@@ -108,7 +108,7 @@ define_machine(adder875) {
108 .name = "Adder MPC875", 108 .name = "Adder MPC875",
109 .probe = adder875_probe, 109 .probe = adder875_probe,
110 .setup_arch = adder875_setup, 110 .setup_arch = adder875_setup,
111 .init_IRQ = m8xx_pic_init, 111 .init_IRQ = mpc8xx_pics_init,
112 .get_irq = mpc8xx_get_irq, 112 .get_irq = mpc8xx_get_irq,
113 .restart = mpc8xx_restart, 113 .restart = mpc8xx_restart,
114 .calibrate_decr = generic_calibrate_decr, 114 .calibrate_decr = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/8xx/ep88xc.c b/arch/powerpc/platforms/8xx/ep88xc.c
index a8dffa005775..7d9ac6040d63 100644
--- a/arch/powerpc/platforms/8xx/ep88xc.c
+++ b/arch/powerpc/platforms/8xx/ep88xc.c
@@ -15,7 +15,6 @@
15#include <asm/machdep.h> 15#include <asm/machdep.h>
16#include <asm/io.h> 16#include <asm/io.h>
17#include <asm/udbg.h> 17#include <asm/udbg.h>
18#include <asm/commproc.h>
19#include <asm/cpm1.h> 18#include <asm/cpm1.h>
20 19
21#include "mpc8xx.h" 20#include "mpc8xx.h"
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index fdce10c4f074..fcedbec07f94 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -24,6 +24,7 @@ config PPC_83xx
24 select MPC83xx 24 select MPC83xx
25 select IPIC 25 select IPIC
26 select WANT_DEVICE_TREE 26 select WANT_DEVICE_TREE
27 select FSL_EMB_PERFMON
27 28
28config PPC_86xx 29config PPC_86xx
29 bool "Freescale 86xx" 30 bool "Freescale 86xx"
@@ -41,6 +42,7 @@ config CLASSIC32
41source "arch/powerpc/platforms/pseries/Kconfig" 42source "arch/powerpc/platforms/pseries/Kconfig"
42source "arch/powerpc/platforms/iseries/Kconfig" 43source "arch/powerpc/platforms/iseries/Kconfig"
43source "arch/powerpc/platforms/chrp/Kconfig" 44source "arch/powerpc/platforms/chrp/Kconfig"
45source "arch/powerpc/platforms/512x/Kconfig"
44source "arch/powerpc/platforms/52xx/Kconfig" 46source "arch/powerpc/platforms/52xx/Kconfig"
45source "arch/powerpc/platforms/powermac/Kconfig" 47source "arch/powerpc/platforms/powermac/Kconfig"
46source "arch/powerpc/platforms/prep/Kconfig" 48source "arch/powerpc/platforms/prep/Kconfig"
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 7fc41104d53e..69941ba70975 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -14,7 +14,7 @@ choice
14 There are five families of 32 bit PowerPC chips supported. 14 There are five families of 32 bit PowerPC chips supported.
15 The most common ones are the desktop and server CPUs (601, 603, 15 The most common ones are the desktop and server CPUs (601, 603,
16 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their 16 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their
17 embedded 52xx/82xx/83xx/86xx counterparts. 17 embedded 512x/52xx/82xx/83xx/86xx counterparts.
18 The other embeeded parts, namely 4xx, 8xx, e200 (55xx) and e500 18 The other embeeded parts, namely 4xx, 8xx, e200 (55xx) and e500
19 (85xx) each form a family of their own that is not compatible 19 (85xx) each form a family of their own that is not compatible
20 with the others. 20 with the others.
@@ -22,7 +22,7 @@ choice
22 If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx. 22 If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
23 23
24config 6xx 24config 6xx
25 bool "52xx/6xx/7xx/74xx/82xx/83xx/86xx" 25 bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx"
26 select PPC_FPU 26 select PPC_FPU
27 27
28config PPC_85xx 28config PPC_85xx
@@ -94,6 +94,7 @@ config 8xx
94 bool 94 bool
95 95
96config E500 96config E500
97 select FSL_EMB_PERFMON
97 bool 98 bool
98 99
99config PPC_FPU 100config PPC_FPU
@@ -115,6 +116,9 @@ config FSL_BOOKE
115 depends on E200 || E500 116 depends on E200 || E500
116 default y 117 default y
117 118
119config FSL_EMB_PERFMON
120 bool
121
118config PTE_64BIT 122config PTE_64BIT
119 bool 123 bool
120 depends on 44x || E500 124 depends on 44x || E500
@@ -221,7 +225,7 @@ config NR_CPUS
221 225
222config NOT_COHERENT_CACHE 226config NOT_COHERENT_CACHE
223 bool 227 bool
224 depends on 4xx || 8xx || E200 228 depends on 4xx || 8xx || E200 || PPC_MPC512x
225 default y 229 default y
226 230
227config CHECK_CACHE_COHERENCY 231config CHECK_CACHE_COHERENCY
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 6d9079da5f5a..a984894466d9 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -11,6 +11,7 @@ endif
11obj-$(CONFIG_PPC_CHRP) += chrp/ 11obj-$(CONFIG_PPC_CHRP) += chrp/
12obj-$(CONFIG_40x) += 40x/ 12obj-$(CONFIG_40x) += 40x/
13obj-$(CONFIG_44x) += 44x/ 13obj-$(CONFIG_44x) += 44x/
14obj-$(CONFIG_PPC_MPC512x) += 512x/
14obj-$(CONFIG_PPC_MPC52xx) += 52xx/ 15obj-$(CONFIG_PPC_MPC52xx) += 52xx/
15obj-$(CONFIG_PPC_8xx) += 8xx/ 16obj-$(CONFIG_PPC_8xx) += 8xx/
16obj-$(CONFIG_PPC_82xx) += 82xx/ 17obj-$(CONFIG_PPC_82xx) += 82xx/
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 3a963b4a9be0..2f169991896d 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -54,6 +54,13 @@ config SPU_FS_64K_LS
54 uses 4K pages. This can improve performances of applications 54 uses 4K pages. This can improve performances of applications
55 using multiple SPEs by lowering the TLB pressure on them. 55 using multiple SPEs by lowering the TLB pressure on them.
56 56
57config SPU_TRACE
58 tristate "SPU event tracing support"
59 depends on SPU_FS && MARKERS
60 help
61 This option allows reading a trace of spu-related events through
62 the sputrace file in procfs.
63
57config SPU_BASE 64config SPU_BASE
58 bool 65 bool
59 default n 66 default n
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 095988f13bf4..d95e71dee91f 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -13,7 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/pci.h> 14#include <linux/pci.h>
15#include <linux/msi.h> 15#include <linux/msi.h>
16#include <linux/reboot.h> 16#include <linux/of_platform.h>
17 17
18#include <asm/dcr.h> 18#include <asm/dcr.h>
19#include <asm/machdep.h> 19#include <asm/machdep.h>
@@ -65,14 +65,12 @@
65 65
66struct axon_msic { 66struct axon_msic {
67 struct irq_host *irq_host; 67 struct irq_host *irq_host;
68 __le32 *fifo; 68 __le32 *fifo_virt;
69 dma_addr_t fifo_phys;
69 dcr_host_t dcr_host; 70 dcr_host_t dcr_host;
70 struct list_head list;
71 u32 read_offset; 71 u32 read_offset;
72}; 72};
73 73
74static LIST_HEAD(axon_msic_list);
75
76static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) 74static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
77{ 75{
78 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); 76 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
@@ -94,7 +92,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
94 92
95 while (msic->read_offset != write_offset) { 93 while (msic->read_offset != write_offset) {
96 idx = msic->read_offset / sizeof(__le32); 94 idx = msic->read_offset / sizeof(__le32);
97 msi = le32_to_cpu(msic->fifo[idx]); 95 msi = le32_to_cpu(msic->fifo_virt[idx]);
98 msi &= 0xFFFF; 96 msi &= 0xFFFF;
99 97
100 pr_debug("axon_msi: woff %x roff %x msi %x\n", 98 pr_debug("axon_msi: woff %x roff %x msi %x\n",
@@ -139,6 +137,7 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
139 137
140 tmp = dn; 138 tmp = dn;
141 dn = of_find_node_by_phandle(*ph); 139 dn = of_find_node_by_phandle(*ph);
140 of_node_put(tmp);
142 if (!dn) { 141 if (!dn) {
143 dev_dbg(&dev->dev, 142 dev_dbg(&dev->dev,
144 "axon_msi: msi-translator doesn't point to a node\n"); 143 "axon_msi: msi-translator doesn't point to a node\n");
@@ -156,7 +155,6 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
156 155
157out_error: 156out_error:
158 of_node_put(dn); 157 of_node_put(dn);
159 of_node_put(tmp);
160 158
161 return msic; 159 return msic;
162} 160}
@@ -292,30 +290,24 @@ static struct irq_host_ops msic_host_ops = {
292 .map = msic_host_map, 290 .map = msic_host_map,
293}; 291};
294 292
295static int axon_msi_notify_reboot(struct notifier_block *nb, 293static int axon_msi_shutdown(struct of_device *device)
296 unsigned long code, void *data)
297{ 294{
298 struct axon_msic *msic; 295 struct axon_msic *msic = device->dev.platform_data;
299 u32 tmp; 296 u32 tmp;
300 297
301 list_for_each_entry(msic, &axon_msic_list, list) { 298 pr_debug("axon_msi: disabling %s\n",
302 pr_debug("axon_msi: disabling %s\n", 299 msic->irq_host->of_node->full_name);
303 msic->irq_host->of_node->full_name); 300 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
304 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); 301 tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
305 tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; 302 msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
306 msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
307 }
308 303
309 return 0; 304 return 0;
310} 305}
311 306
312static struct notifier_block axon_msi_reboot_notifier = { 307static int axon_msi_probe(struct of_device *device,
313 .notifier_call = axon_msi_notify_reboot 308 const struct of_device_id *device_id)
314};
315
316static int axon_msi_setup_one(struct device_node *dn)
317{ 309{
318 struct page *page; 310 struct device_node *dn = device->node;
319 struct axon_msic *msic; 311 struct axon_msic *msic;
320 unsigned int virq; 312 unsigned int virq;
321 int dcr_base, dcr_len; 313 int dcr_base, dcr_len;
@@ -346,16 +338,14 @@ static int axon_msi_setup_one(struct device_node *dn)
346 goto out_free_msic; 338 goto out_free_msic;
347 } 339 }
348 340
349 page = alloc_pages_node(of_node_to_nid(dn), GFP_KERNEL, 341 msic->fifo_virt = dma_alloc_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES,
350 get_order(MSIC_FIFO_SIZE_BYTES)); 342 &msic->fifo_phys, GFP_KERNEL);
351 if (!page) { 343 if (!msic->fifo_virt) {
352 printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n", 344 printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n",
353 dn->full_name); 345 dn->full_name);
354 goto out_free_msic; 346 goto out_free_msic;
355 } 347 }
356 348
357 msic->fifo = page_address(page);
358
359 msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP, 349 msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP,
360 NR_IRQS, &msic_host_ops, 0); 350 NR_IRQS, &msic_host_ops, 0);
361 if (!msic->irq_host) { 351 if (!msic->irq_host) {
@@ -378,14 +368,18 @@ static int axon_msi_setup_one(struct device_node *dn)
378 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq); 368 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
379 369
380 /* Enable the MSIC hardware */ 370 /* Enable the MSIC hardware */
381 msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, (u64)msic->fifo >> 32); 371 msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, msic->fifo_phys >> 32);
382 msic_dcr_write(msic, MSIC_BASE_ADDR_LO_REG, 372 msic_dcr_write(msic, MSIC_BASE_ADDR_LO_REG,
383 (u64)msic->fifo & 0xFFFFFFFF); 373 msic->fifo_phys & 0xFFFFFFFF);
384 msic_dcr_write(msic, MSIC_CTRL_REG, 374 msic_dcr_write(msic, MSIC_CTRL_REG,
385 MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE | 375 MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE |
386 MSIC_CTRL_FIFO_SIZE); 376 MSIC_CTRL_FIFO_SIZE);
387 377
388 list_add(&msic->list, &axon_msic_list); 378 device->dev.platform_data = msic;
379
380 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
381 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
382 ppc_md.msi_check_device = axon_msi_check_device;
389 383
390 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); 384 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name);
391 385
@@ -394,7 +388,8 @@ static int axon_msi_setup_one(struct device_node *dn)
394out_free_host: 388out_free_host:
395 kfree(msic->irq_host); 389 kfree(msic->irq_host);
396out_free_fifo: 390out_free_fifo:
397 __free_pages(virt_to_page(msic->fifo), get_order(MSIC_FIFO_SIZE_BYTES)); 391 dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt,
392 msic->fifo_phys);
398out_free_msic: 393out_free_msic:
399 kfree(msic); 394 kfree(msic);
400out: 395out:
@@ -402,28 +397,24 @@ out:
402 return -1; 397 return -1;
403} 398}
404 399
405static int axon_msi_init(void) 400static const struct of_device_id axon_msi_device_id[] = {
406{ 401 {
407 struct device_node *dn; 402 .compatible = "ibm,axon-msic"
408 int found = 0; 403 },
409 404 {}
410 pr_debug("axon_msi: initialising ...\n"); 405};
411
412 for_each_compatible_node(dn, NULL, "ibm,axon-msic") {
413 if (axon_msi_setup_one(dn) == 0)
414 found++;
415 }
416
417 if (found) {
418 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
419 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
420 ppc_md.msi_check_device = axon_msi_check_device;
421
422 register_reboot_notifier(&axon_msi_reboot_notifier);
423 406
424 pr_debug("axon_msi: registered callbacks!\n"); 407static struct of_platform_driver axon_msi_driver = {
425 } 408 .match_table = axon_msi_device_id,
409 .probe = axon_msi_probe,
410 .shutdown = axon_msi_shutdown,
411 .driver = {
412 .name = "axon-msi"
413 },
414};
426 415
427 return 0; 416static int __init axon_msi_init(void)
417{
418 return of_register_platform_driver(&axon_msi_driver);
428} 419}
429arch_initcall(axon_msi_init); 420subsys_initcall(axon_msi_init);
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index e6534b519c9a..a7f609b3b876 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -98,7 +98,7 @@ static int __init cell_publish_devices(void)
98 } 98 }
99 return 0; 99 return 0;
100} 100}
101machine_device_initcall(cell, cell_publish_devices); 101machine_subsys_initcall(cell, cell_publish_devices);
102 102
103static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) 103static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
104{ 104{
diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile
index d3a349fb42e5..99610a6361f2 100644
--- a/arch/powerpc/platforms/cell/spufs/Makefile
+++ b/arch/powerpc/platforms/cell/spufs/Makefile
@@ -4,6 +4,8 @@ spufs-y += inode.o file.o context.o syscalls.o coredump.o
4spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o 4spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o
5spufs-y += switch.o fault.o lscsa_alloc.o 5spufs-y += switch.o fault.o lscsa_alloc.o
6 6
7obj-$(CONFIG_SPU_TRACE) += sputrace.o
8
7# Rules to build switch.o with the help of SPU tool chain 9# Rules to build switch.o with the help of SPU tool chain
8SPU_CROSS := spu- 10SPU_CROSS := spu-
9SPU_CC := $(SPU_CROSS)gcc 11SPU_CC := $(SPU_CROSS)gcc
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 3fcd06418b01..1018acd1746b 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -29,6 +29,7 @@
29#include <linux/poll.h> 29#include <linux/poll.h>
30#include <linux/ptrace.h> 30#include <linux/ptrace.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/marker.h>
32 33
33#include <asm/io.h> 34#include <asm/io.h>
34#include <asm/semaphore.h> 35#include <asm/semaphore.h>
@@ -358,6 +359,8 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
358 struct spu_context *ctx = vma->vm_file->private_data; 359 struct spu_context *ctx = vma->vm_file->private_data;
359 unsigned long area, offset = address - vma->vm_start; 360 unsigned long area, offset = address - vma->vm_start;
360 361
362 spu_context_nospu_trace(spufs_ps_nopfn__enter, ctx);
363
361 offset += vma->vm_pgoff << PAGE_SHIFT; 364 offset += vma->vm_pgoff << PAGE_SHIFT;
362 if (offset >= ps_size) 365 if (offset >= ps_size)
363 return NOPFN_SIGBUS; 366 return NOPFN_SIGBUS;
@@ -375,11 +378,14 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
375 378
376 if (ctx->state == SPU_STATE_SAVED) { 379 if (ctx->state == SPU_STATE_SAVED) {
377 up_read(&current->mm->mmap_sem); 380 up_read(&current->mm->mmap_sem);
381 spu_context_nospu_trace(spufs_ps_nopfn__sleep, ctx);
378 spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); 382 spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
383 spu_context_trace(spufs_ps_nopfn__wake, ctx, ctx->spu);
379 down_read(&current->mm->mmap_sem); 384 down_read(&current->mm->mmap_sem);
380 } else { 385 } else {
381 area = ctx->spu->problem_phys + ps_offs; 386 area = ctx->spu->problem_phys + ps_offs;
382 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); 387 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
388 spu_context_trace(spufs_ps_nopfn__insert, ctx, ctx->spu);
383 } 389 }
384 390
385 spu_release(ctx); 391 spu_release(ctx);
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index c0e968a4c211..90784c029f25 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -322,7 +322,7 @@ static struct spu_context *
322spufs_assert_affinity(unsigned int flags, struct spu_gang *gang, 322spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
323 struct file *filp) 323 struct file *filp)
324{ 324{
325 struct spu_context *tmp, *neighbor; 325 struct spu_context *tmp, *neighbor, *err;
326 int count, node; 326 int count, node;
327 int aff_supp; 327 int aff_supp;
328 328
@@ -354,11 +354,15 @@ spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
354 if (!list_empty(&neighbor->aff_list) && !(neighbor->aff_head) && 354 if (!list_empty(&neighbor->aff_list) && !(neighbor->aff_head) &&
355 !list_is_last(&neighbor->aff_list, &gang->aff_list_head) && 355 !list_is_last(&neighbor->aff_list, &gang->aff_list_head) &&
356 !list_entry(neighbor->aff_list.next, struct spu_context, 356 !list_entry(neighbor->aff_list.next, struct spu_context,
357 aff_list)->aff_head) 357 aff_list)->aff_head) {
358 return ERR_PTR(-EEXIST); 358 err = ERR_PTR(-EEXIST);
359 goto out_put_neighbor;
360 }
359 361
360 if (gang != neighbor->gang) 362 if (gang != neighbor->gang) {
361 return ERR_PTR(-EINVAL); 363 err = ERR_PTR(-EINVAL);
364 goto out_put_neighbor;
365 }
362 366
363 count = 1; 367 count = 1;
364 list_for_each_entry(tmp, &gang->aff_list_head, aff_list) 368 list_for_each_entry(tmp, &gang->aff_list_head, aff_list)
@@ -372,11 +376,17 @@ spufs_assert_affinity(unsigned int flags, struct spu_gang *gang,
372 break; 376 break;
373 } 377 }
374 378
375 if (node == MAX_NUMNODES) 379 if (node == MAX_NUMNODES) {
376 return ERR_PTR(-EEXIST); 380 err = ERR_PTR(-EEXIST);
381 goto out_put_neighbor;
382 }
377 } 383 }
378 384
379 return neighbor; 385 return neighbor;
386
387out_put_neighbor:
388 put_spu_context(neighbor);
389 return err;
380} 390}
381 391
382static void 392static void
@@ -454,9 +464,12 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
454 if (ret) 464 if (ret)
455 goto out_aff_unlock; 465 goto out_aff_unlock;
456 466
457 if (affinity) 467 if (affinity) {
458 spufs_set_affinity(flags, SPUFS_I(dentry->d_inode)->i_ctx, 468 spufs_set_affinity(flags, SPUFS_I(dentry->d_inode)->i_ctx,
459 neighbor); 469 neighbor);
470 if (neighbor)
471 put_spu_context(neighbor);
472 }
460 473
461 /* 474 /*
462 * get references for dget and mntget, will be released 475 * get references for dget and mntget, will be released
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index c01a09da1e56..b4814c740d8a 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -410,8 +410,11 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
410 * since we have TIF_SINGLESTEP set, thus the kernel will do 410 * since we have TIF_SINGLESTEP set, thus the kernel will do
411 * it upon return from the syscall anyawy 411 * it upon return from the syscall anyawy
412 */ 412 */
413 if ((status & SPU_STATUS_STOPPED_BY_STOP) 413 if (unlikely(status & SPU_STATUS_SINGLE_STEP))
414 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) { 414 ret = -ERESTARTSYS;
415
416 else if (unlikely((status & SPU_STATUS_STOPPED_BY_STOP)
417 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff)) {
415 force_sig(SIGTRAP, current); 418 force_sig(SIGTRAP, current);
416 ret = -ERESTARTSYS; 419 ret = -ERESTARTSYS;
417 } 420 }
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 00d914232af1..5915343e2599 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -39,6 +39,7 @@
39#include <linux/pid_namespace.h> 39#include <linux/pid_namespace.h>
40#include <linux/proc_fs.h> 40#include <linux/proc_fs.h>
41#include <linux/seq_file.h> 41#include <linux/seq_file.h>
42#include <linux/marker.h>
42 43
43#include <asm/io.h> 44#include <asm/io.h>
44#include <asm/mmu_context.h> 45#include <asm/mmu_context.h>
@@ -216,8 +217,8 @@ void do_notify_spus_active(void)
216 */ 217 */
217static void spu_bind_context(struct spu *spu, struct spu_context *ctx) 218static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
218{ 219{
219 pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, 220 spu_context_trace(spu_bind_context__enter, ctx, spu);
220 spu->number, spu->node); 221
221 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); 222 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
222 223
223 if (ctx->flags & SPU_CREATE_NOSCHED) 224 if (ctx->flags & SPU_CREATE_NOSCHED)
@@ -399,8 +400,8 @@ static int has_affinity(struct spu_context *ctx)
399 */ 400 */
400static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) 401static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
401{ 402{
402 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, 403 spu_context_trace(spu_unbind_context__enter, ctx, spu);
403 spu->pid, spu->number, spu->node); 404
404 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); 405 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
405 406
406 if (spu->ctx->flags & SPU_CREATE_NOSCHED) 407 if (spu->ctx->flags & SPU_CREATE_NOSCHED)
@@ -528,6 +529,8 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
528 struct spu *spu, *aff_ref_spu; 529 struct spu *spu, *aff_ref_spu;
529 int node, n; 530 int node, n;
530 531
532 spu_context_nospu_trace(spu_get_idle__enter, ctx);
533
531 if (ctx->gang) { 534 if (ctx->gang) {
532 mutex_lock(&ctx->gang->aff_mutex); 535 mutex_lock(&ctx->gang->aff_mutex);
533 if (has_affinity(ctx)) { 536 if (has_affinity(ctx)) {
@@ -546,8 +549,7 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
546 if (atomic_dec_and_test(&ctx->gang->aff_sched_count)) 549 if (atomic_dec_and_test(&ctx->gang->aff_sched_count))
547 ctx->gang->aff_ref_spu = NULL; 550 ctx->gang->aff_ref_spu = NULL;
548 mutex_unlock(&ctx->gang->aff_mutex); 551 mutex_unlock(&ctx->gang->aff_mutex);
549 552 goto not_found;
550 return NULL;
551 } 553 }
552 mutex_unlock(&ctx->gang->aff_mutex); 554 mutex_unlock(&ctx->gang->aff_mutex);
553 } 555 }
@@ -565,12 +567,14 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
565 mutex_unlock(&cbe_spu_info[node].list_mutex); 567 mutex_unlock(&cbe_spu_info[node].list_mutex);
566 } 568 }
567 569
570 not_found:
571 spu_context_nospu_trace(spu_get_idle__not_found, ctx);
568 return NULL; 572 return NULL;
569 573
570 found: 574 found:
571 spu->alloc_state = SPU_USED; 575 spu->alloc_state = SPU_USED;
572 mutex_unlock(&cbe_spu_info[node].list_mutex); 576 mutex_unlock(&cbe_spu_info[node].list_mutex);
573 pr_debug("Got SPU %d %d\n", spu->number, spu->node); 577 spu_context_trace(spu_get_idle__found, ctx, spu);
574 spu_init_channels(spu); 578 spu_init_channels(spu);
575 return spu; 579 return spu;
576} 580}
@@ -587,6 +591,8 @@ static struct spu *find_victim(struct spu_context *ctx)
587 struct spu *spu; 591 struct spu *spu;
588 int node, n; 592 int node, n;
589 593
594 spu_context_nospu_trace(spu_find_vitim__enter, ctx);
595
590 /* 596 /*
591 * Look for a possible preemption candidate on the local node first. 597 * Look for a possible preemption candidate on the local node first.
592 * If there is no candidate look at the other nodes. This isn't 598 * If there is no candidate look at the other nodes. This isn't
@@ -640,6 +646,8 @@ static struct spu *find_victim(struct spu_context *ctx)
640 goto restart; 646 goto restart;
641 } 647 }
642 648
649 spu_context_trace(__spu_deactivate__unload, ctx, spu);
650
643 mutex_lock(&cbe_spu_info[node].list_mutex); 651 mutex_lock(&cbe_spu_info[node].list_mutex);
644 cbe_spu_info[node].nr_active--; 652 cbe_spu_info[node].nr_active--;
645 spu_unbind_context(spu, victim); 653 spu_unbind_context(spu, victim);
@@ -822,6 +830,7 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
822 */ 830 */
823void spu_deactivate(struct spu_context *ctx) 831void spu_deactivate(struct spu_context *ctx)
824{ 832{
833 spu_context_nospu_trace(spu_deactivate__enter, ctx);
825 __spu_deactivate(ctx, 1, MAX_PRIO); 834 __spu_deactivate(ctx, 1, MAX_PRIO);
826} 835}
827 836
@@ -835,6 +844,7 @@ void spu_deactivate(struct spu_context *ctx)
835 */ 844 */
836void spu_yield(struct spu_context *ctx) 845void spu_yield(struct spu_context *ctx)
837{ 846{
847 spu_context_nospu_trace(spu_yield__enter, ctx);
838 if (!(ctx->flags & SPU_CREATE_NOSCHED)) { 848 if (!(ctx->flags & SPU_CREATE_NOSCHED)) {
839 mutex_lock(&ctx->state_mutex); 849 mutex_lock(&ctx->state_mutex);
840 __spu_deactivate(ctx, 0, MAX_PRIO); 850 __spu_deactivate(ctx, 0, MAX_PRIO);
@@ -864,11 +874,15 @@ static noinline void spusched_tick(struct spu_context *ctx)
864 goto out; 874 goto out;
865 875
866 spu = ctx->spu; 876 spu = ctx->spu;
877
878 spu_context_trace(spusched_tick__preempt, ctx, spu);
879
867 new = grab_runnable_context(ctx->prio + 1, spu->node); 880 new = grab_runnable_context(ctx->prio + 1, spu->node);
868 if (new) { 881 if (new) {
869 spu_unschedule(spu, ctx); 882 spu_unschedule(spu, ctx);
870 spu_add_to_rq(ctx); 883 spu_add_to_rq(ctx);
871 } else { 884 } else {
885 spu_context_nospu_trace(spusched_tick__newslice, ctx);
872 ctx->time_slice++; 886 ctx->time_slice++;
873 } 887 }
874out: 888out:
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 0e114038ea6f..795a1b52538b 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -325,4 +325,9 @@ extern void spu_free_lscsa(struct spu_state *csa);
325extern void spuctx_switch_state(struct spu_context *ctx, 325extern void spuctx_switch_state(struct spu_context *ctx,
326 enum spu_utilization_state new_state); 326 enum spu_utilization_state new_state);
327 327
328#define spu_context_trace(name, ctx, spu) \
329 trace_mark(name, "%p %p", ctx, spu);
330#define spu_context_nospu_trace(name, ctx) \
331 trace_mark(name, "%p", ctx);
332
328#endif 333#endif
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c
new file mode 100644
index 000000000000..2b1953f6f12e
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/sputrace.c
@@ -0,0 +1,250 @@
1/*
2 * Copyright (C) 2007 IBM Deutschland Entwicklung GmbH
3 * Released under GPL v2.
4 *
5 * Partially based on net/ipv4/tcp_probe.c.
6 *
7 * Simple tracing facility for spu contexts.
8 */
9#include <linux/sched.h>
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/marker.h>
13#include <linux/proc_fs.h>
14#include <linux/wait.h>
15#include <asm/atomic.h>
16#include <asm/uaccess.h>
17#include "spufs.h"
18
19struct spu_probe {
20 const char *name;
21 const char *format;
22 marker_probe_func *probe_func;
23};
24
25struct sputrace {
26 ktime_t tstamp;
27 int owner_tid; /* owner */
28 int curr_tid;
29 const char *name;
30 int number;
31};
32
33static int bufsize __read_mostly = 16384;
34MODULE_PARM_DESC(bufsize, "Log buffer size (number of records)");
35module_param(bufsize, int, 0);
36
37
38static DEFINE_SPINLOCK(sputrace_lock);
39static DECLARE_WAIT_QUEUE_HEAD(sputrace_wait);
40static ktime_t sputrace_start;
41static unsigned long sputrace_head, sputrace_tail;
42static struct sputrace *sputrace_log;
43
44static int sputrace_used(void)
45{
46 return (sputrace_head - sputrace_tail) % bufsize;
47}
48
49static inline int sputrace_avail(void)
50{
51 return bufsize - sputrace_used();
52}
53
54static int sputrace_sprint(char *tbuf, int n)
55{
56 const struct sputrace *t = sputrace_log + sputrace_tail % bufsize;
57 struct timespec tv =
58 ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));
59
60 return snprintf(tbuf, n,
61 "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n",
62 (unsigned long) tv.tv_sec,
63 (unsigned long) tv.tv_nsec,
64 t->owner_tid,
65 t->name,
66 t->curr_tid,
67 t->number);
68}
69
70static ssize_t sputrace_read(struct file *file, char __user *buf,
71 size_t len, loff_t *ppos)
72{
73 int error = 0, cnt = 0;
74
75 if (!buf || len < 0)
76 return -EINVAL;
77
78 while (cnt < len) {
79 char tbuf[128];
80 int width;
81
82 error = wait_event_interruptible(sputrace_wait,
83 sputrace_used() > 0);
84 if (error)
85 break;
86
87 spin_lock(&sputrace_lock);
88 if (sputrace_head == sputrace_tail) {
89 spin_unlock(&sputrace_lock);
90 continue;
91 }
92
93 width = sputrace_sprint(tbuf, sizeof(tbuf));
94 if (width < len)
95 sputrace_tail = (sputrace_tail + 1) % bufsize;
96 spin_unlock(&sputrace_lock);
97
98 if (width >= len)
99 break;
100
101 error = copy_to_user(buf + cnt, tbuf, width);
102 if (error)
103 break;
104 cnt += width;
105 }
106
107 return cnt == 0 ? error : cnt;
108}
109
110static int sputrace_open(struct inode *inode, struct file *file)
111{
112 spin_lock(&sputrace_lock);
113 sputrace_head = sputrace_tail = 0;
114 sputrace_start = ktime_get();
115 spin_unlock(&sputrace_lock);
116
117 return 0;
118}
119
120static const struct file_operations sputrace_fops = {
121 .owner = THIS_MODULE,
122 .open = sputrace_open,
123 .read = sputrace_read,
124};
125
126static void sputrace_log_item(const char *name, struct spu_context *ctx,
127 struct spu *spu)
128{
129 spin_lock(&sputrace_lock);
130 if (sputrace_avail() > 1) {
131 struct sputrace *t = sputrace_log + sputrace_head;
132
133 t->tstamp = ktime_get();
134 t->owner_tid = ctx->tid;
135 t->name = name;
136 t->curr_tid = current->pid;
137 t->number = spu ? spu->number : -1;
138
139 sputrace_head = (sputrace_head + 1) % bufsize;
140 } else {
141 printk(KERN_WARNING
142 "sputrace: lost samples due to full buffer.\n");
143 }
144 spin_unlock(&sputrace_lock);
145
146 wake_up(&sputrace_wait);
147}
148
149static void spu_context_event(const struct marker *mdata,
150 void *private, const char *format, ...)
151{
152 struct spu_probe *p = mdata->private;
153 va_list ap;
154 struct spu_context *ctx;
155 struct spu *spu;
156
157 va_start(ap, format);
158 ctx = va_arg(ap, struct spu_context *);
159 spu = va_arg(ap, struct spu *);
160
161 sputrace_log_item(p->name, ctx, spu);
162 va_end(ap);
163}
164
165static void spu_context_nospu_event(const struct marker *mdata,
166 void *private, const char *format, ...)
167{
168 struct spu_probe *p = mdata->private;
169 va_list ap;
170 struct spu_context *ctx;
171
172 va_start(ap, format);
173 ctx = va_arg(ap, struct spu_context *);
174
175 sputrace_log_item(p->name, ctx, NULL);
176 va_end(ap);
177}
178
179struct spu_probe spu_probes[] = {
180 { "spu_bind_context__enter", "%p %p", spu_context_event },
181 { "spu_unbind_context__enter", "%p %p", spu_context_event },
182 { "spu_get_idle__enter", "%p", spu_context_nospu_event },
183 { "spu_get_idle__found", "%p %p", spu_context_event },
184 { "spu_get_idle__not_found", "%p", spu_context_nospu_event },
185 { "spu_find_victim__enter", "%p", spu_context_nospu_event },
186 { "spusched_tick__preempt", "%p %p", spu_context_event },
187 { "spusched_tick__newslice", "%p", spu_context_nospu_event },
188 { "spu_yield__enter", "%p", spu_context_nospu_event },
189 { "spu_deactivate__enter", "%p", spu_context_nospu_event },
190 { "__spu_deactivate__unload", "%p %p", spu_context_event },
191 { "spufs_ps_nopfn__enter", "%p", spu_context_nospu_event },
192 { "spufs_ps_nopfn__sleep", "%p", spu_context_nospu_event },
193 { "spufs_ps_nopfn__wake", "%p %p", spu_context_event },
194 { "spufs_ps_nopfn__insert", "%p %p", spu_context_event },
195 { "spu_acquire_saved__enter", "%p", spu_context_nospu_event },
196 { "destroy_spu_context__enter", "%p", spu_context_nospu_event },
197};
198
199static int __init sputrace_init(void)
200{
201 struct proc_dir_entry *entry;
202 int i, error = -ENOMEM;
203
204 sputrace_log = kcalloc(sizeof(struct sputrace),
205 bufsize, GFP_KERNEL);
206 if (!sputrace_log)
207 goto out;
208
209 entry = create_proc_entry("sputrace", S_IRUSR, NULL);
210 if (!entry)
211 goto out_free_log;
212 entry->proc_fops = &sputrace_fops;
213
214 for (i = 0; i < ARRAY_SIZE(spu_probes); i++) {
215 struct spu_probe *p = &spu_probes[i];
216
217 error = marker_probe_register(p->name, p->format,
218 p->probe_func, p);
219 if (error)
220 printk(KERN_INFO "Unable to register probe %s\n",
221 p->name);
222
223 error = marker_arm(p->name);
224 if (error)
225 printk(KERN_INFO "Unable to arm probe %s\n", p->name);
226 }
227
228 return 0;
229
230out_free_log:
231 kfree(sputrace_log);
232out:
233 return -ENOMEM;
234}
235
236static void __exit sputrace_exit(void)
237{
238 int i;
239
240 for (i = 0; i < ARRAY_SIZE(spu_probes); i++)
241 marker_probe_unregister(spu_probes[i].name);
242
243 remove_proc_entry("sputrace", NULL);
244 kfree(sputrace_log);
245}
246
247module_init(sputrace_init);
248module_exit(sputrace_exit);
249
250MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/platforms/embedded6xx/storcenter.c b/arch/powerpc/platforms/embedded6xx/storcenter.c
index e12e9d298716..8864e4884980 100644
--- a/arch/powerpc/platforms/embedded6xx/storcenter.c
+++ b/arch/powerpc/platforms/embedded6xx/storcenter.c
@@ -132,33 +132,18 @@ static void __init storcenter_init_IRQ(void)
132 132
133 paddr = (phys_addr_t)of_translate_address(dnp, prop); 133 paddr = (phys_addr_t)of_translate_address(dnp, prop);
134 mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 134 mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET,
135 4, 32, " EPIC "); 135 16, 32, " OpenPIC ");
136 136
137 of_node_put(dnp); 137 of_node_put(dnp);
138 138
139 BUG_ON(mpic == NULL); 139 BUG_ON(mpic == NULL);
140 140
141 /* PCI IRQs */
142 /* 141 /*
143 * 2.6.12 patch: 142 * 16 Serial Interrupts followed by 16 Internal Interrupts.
144 * openpic_set_sources(0, 5, OpenPIC_Addr + 0x10200); 143 * I2C is the second internal, so it is at 17, 0x11020.
145 * openpic_set_sources(5, 2, OpenPIC_Addr + 0x11120);
146 * first_irq, num_irqs, __iomem first_ISR
147 * o_ss: i, src: 0, fdf50200
148 * o_ss: i, src: 1, fdf50220
149 * o_ss: i, src: 2, fdf50240
150 * o_ss: i, src: 3, fdf50260
151 * o_ss: i, src: 4, fdf50280
152 * o_ss: i, src: 5, fdf51120
153 * o_ss: i, src: 6, fdf51140
154 */ 144 */
155 mpic_assign_isu(mpic, 0, paddr + 0x10200); 145 mpic_assign_isu(mpic, 0, paddr + 0x10200);
156 mpic_assign_isu(mpic, 1, paddr + 0x10220); 146 mpic_assign_isu(mpic, 1, paddr + 0x11000);
157 mpic_assign_isu(mpic, 2, paddr + 0x10240);
158 mpic_assign_isu(mpic, 3, paddr + 0x10260);
159 mpic_assign_isu(mpic, 4, paddr + 0x10280);
160 mpic_assign_isu(mpic, 5, paddr + 0x11120);
161 mpic_assign_isu(mpic, 6, paddr + 0x11140);
162 147
163 mpic_init(mpic); 148 mpic_init(mpic);
164} 149}
@@ -178,7 +163,7 @@ static int __init storcenter_probe(void)
178{ 163{
179 unsigned long root = of_get_flat_dt_root(); 164 unsigned long root = of_get_flat_dt_root();
180 165
181 return of_flat_dt_is_compatible(root, "storcenter"); 166 return of_flat_dt_is_compatible(root, "iomega,storcenter");
182} 167}
183 168
184define_machine(storcenter){ 169define_machine(storcenter){
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index c4ad54e0f288..1f032483c026 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -58,7 +58,7 @@ static void pseries_mach_cpu_die(void)
58{ 58{
59 local_irq_disable(); 59 local_irq_disable();
60 idle_task_exit(); 60 idle_task_exit();
61 xics_teardown_cpu(0); 61 xics_teardown_cpu();
62 unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow())); 62 unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow()));
63 rtas_stop_self(); 63 rtas_stop_self();
64 /* Should never get here... */ 64 /* Should never get here... */
diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c
index 412a5e7aff2d..e9dd5fe081c9 100644
--- a/arch/powerpc/platforms/pseries/kexec.c
+++ b/arch/powerpc/platforms/pseries/kexec.c
@@ -54,7 +54,7 @@ void __init setup_kexec_cpu_down_mpic(void)
54static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary) 54static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
55{ 55{
56 pseries_kexec_cpu_down(crash_shutdown, secondary); 56 pseries_kexec_cpu_down(crash_shutdown, secondary);
57 xics_teardown_cpu(secondary); 57 xics_kexec_teardown_cpu(secondary);
58} 58}
59 59
60void __init setup_kexec_cpu_down_xics(void) 60void __init setup_kexec_cpu_down_xics(void)
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index c02f8742c54d..2800fced8c7c 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -167,6 +167,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
167 167
168 if ((child = of_get_next_child(np, NULL))) { 168 if ((child = of_get_next_child(np, NULL))) {
169 of_node_put(child); 169 of_node_put(child);
170 of_node_put(parent);
170 return -EBUSY; 171 return -EBUSY;
171 } 172 }
172 173
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 8f8dd9c3ca6b..ca52b587166d 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -160,6 +160,46 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
160 160
161/* High level handlers and init code */ 161/* High level handlers and init code */
162 162
163static void xics_update_irq_servers(void)
164{
165 int i, j;
166 struct device_node *np;
167 u32 ilen;
168 const u32 *ireg, *isize;
169 u32 hcpuid;
170
171 /* Find the server numbers for the boot cpu. */
172 np = of_get_cpu_node(boot_cpuid, NULL);
173 BUG_ON(!np);
174
175 ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
176 if (!ireg) {
177 of_node_put(np);
178 return;
179 }
180
181 i = ilen / sizeof(int);
182 hcpuid = get_hard_smp_processor_id(boot_cpuid);
183
184 /* Global interrupt distribution server is specified in the last
185 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
186 * entry fom this property for current boot cpu id and use it as
187 * default distribution server
188 */
189 for (j = 0; j < i; j += 2) {
190 if (ireg[j] == hcpuid) {
191 default_server = hcpuid;
192 default_distrib_server = ireg[j+1];
193
194 isize = of_get_property(np,
195 "ibm,interrupt-server#-size", NULL);
196 if (isize)
197 interrupt_server_size = *isize;
198 }
199 }
200
201 of_node_put(np);
202}
163 203
164#ifdef CONFIG_SMP 204#ifdef CONFIG_SMP
165static int get_irq_server(unsigned int virq, unsigned int strict_check) 205static int get_irq_server(unsigned int virq, unsigned int strict_check)
@@ -169,6 +209,9 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
169 cpumask_t cpumask = irq_desc[virq].affinity; 209 cpumask_t cpumask = irq_desc[virq].affinity;
170 cpumask_t tmp = CPU_MASK_NONE; 210 cpumask_t tmp = CPU_MASK_NONE;
171 211
212 if (! cpu_isset(default_server, cpu_online_map))
213 xics_update_irq_servers();
214
172 if (!distribute_irqs) 215 if (!distribute_irqs)
173 return default_server; 216 return default_server;
174 217
@@ -658,39 +701,11 @@ static void __init xics_setup_8259_cascade(void)
658 set_irq_chained_handler(cascade, pseries_8259_cascade); 701 set_irq_chained_handler(cascade, pseries_8259_cascade);
659} 702}
660 703
661static struct device_node *cpuid_to_of_node(int cpu)
662{
663 struct device_node *np;
664 u32 hcpuid = get_hard_smp_processor_id(cpu);
665
666 for_each_node_by_type(np, "cpu") {
667 int i, len;
668 const u32 *intserv;
669
670 intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
671 &len);
672
673 if (!intserv)
674 intserv = of_get_property(np, "reg", &len);
675
676 i = len / sizeof(u32);
677
678 while (i--)
679 if (intserv[i] == hcpuid)
680 return np;
681 }
682
683 return NULL;
684}
685
686void __init xics_init_IRQ(void) 704void __init xics_init_IRQ(void)
687{ 705{
688 int i, j;
689 struct device_node *np; 706 struct device_node *np;
690 u32 ilen, indx = 0; 707 u32 indx = 0;
691 const u32 *ireg, *isize;
692 int found = 0; 708 int found = 0;
693 u32 hcpuid;
694 709
695 ppc64_boot_msg(0x20, "XICS Init"); 710 ppc64_boot_msg(0x20, "XICS Init");
696 711
@@ -709,34 +724,7 @@ void __init xics_init_IRQ(void)
709 return; 724 return;
710 725
711 xics_init_host(); 726 xics_init_host();
712 727 xics_update_irq_servers();
713 /* Find the server numbers for the boot cpu. */
714 np = cpuid_to_of_node(boot_cpuid);
715 BUG_ON(!np);
716 ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
717 if (!ireg)
718 goto skip_gserver_check;
719 i = ilen / sizeof(int);
720 hcpuid = get_hard_smp_processor_id(boot_cpuid);
721
722 /* Global interrupt distribution server is specified in the last
723 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
724 * entry fom this property for current boot cpu id and use it as
725 * default distribution server
726 */
727 for (j = 0; j < i; j += 2) {
728 if (ireg[j] == hcpuid) {
729 default_server = hcpuid;
730 default_distrib_server = ireg[j+1];
731
732 isize = of_get_property(np,
733 "ibm,interrupt-server#-size", NULL);
734 if (isize)
735 interrupt_server_size = *isize;
736 }
737 }
738skip_gserver_check:
739 of_node_put(np);
740 728
741 if (firmware_has_feature(FW_FEATURE_LPAR)) 729 if (firmware_has_feature(FW_FEATURE_LPAR))
742 ppc_md.get_irq = xics_get_irq_lpar; 730 ppc_md.get_irq = xics_get_irq_lpar;
@@ -775,11 +763,9 @@ void xics_request_IPIs(void)
775} 763}
776#endif /* CONFIG_SMP */ 764#endif /* CONFIG_SMP */
777 765
778void xics_teardown_cpu(int secondary) 766void xics_teardown_cpu()
779{ 767{
780 int cpu = smp_processor_id(); 768 int cpu = smp_processor_id();
781 unsigned int ipi;
782 struct irq_desc *desc;
783 769
784 xics_set_cpu_priority(0); 770 xics_set_cpu_priority(0);
785 771
@@ -790,9 +776,17 @@ void xics_teardown_cpu(int secondary)
790 lpar_qirr_info(cpu, 0xff); 776 lpar_qirr_info(cpu, 0xff);
791 else 777 else
792 direct_qirr_info(cpu, 0xff); 778 direct_qirr_info(cpu, 0xff);
779}
780
781void xics_kexec_teardown_cpu(int secondary)
782{
783 unsigned int ipi;
784 struct irq_desc *desc;
785
786 xics_teardown_cpu();
793 787
794 /* 788 /*
795 * we need to EOI the IPI if we got here from kexec down IPI 789 * we need to EOI the IPI
796 * 790 *
797 * probably need to check all the other interrupts too 791 * probably need to check all the other interrupts too
798 * should we be flagging idle loop instead? 792 * should we be flagging idle loop instead?
@@ -880,8 +874,8 @@ void xics_migrate_irqs_away(void)
880 virq, cpu); 874 virq, cpu);
881 875
882 /* Reset affinity to all cpus */ 876 /* Reset affinity to all cpus */
877 irq_desc[virq].affinity = CPU_MASK_ALL;
883 desc->chip->set_affinity(virq, CPU_MASK_ALL); 878 desc->chip->set_affinity(virq, CPU_MASK_ALL);
884 irq_desc[irq].affinity = CPU_MASK_ALL;
885unlock: 879unlock:
886 spin_unlock_irqrestore(&desc->lock, flags); 880 spin_unlock_irqrestore(&desc->lock, flags);
887 } 881 }
diff --git a/arch/powerpc/platforms/pseries/xics.h b/arch/powerpc/platforms/pseries/xics.h
index 9ffd809d29e2..c26bcff47b6d 100644
--- a/arch/powerpc/platforms/pseries/xics.h
+++ b/arch/powerpc/platforms/pseries/xics.h
@@ -16,7 +16,8 @@
16 16
17extern void xics_init_IRQ(void); 17extern void xics_init_IRQ(void);
18extern void xics_setup_cpu(void); 18extern void xics_setup_cpu(void);
19extern void xics_teardown_cpu(int secondary); 19extern void xics_teardown_cpu(void);
20extern void xics_kexec_teardown_cpu(int secondary);
20extern void xics_cause_IPI(int cpu); 21extern void xics_cause_IPI(int cpu);
21extern void xics_request_IPIs(void); 22extern void xics_request_IPIs(void);
22extern void xics_migrate_irqs_away(void); 23extern void xics_migrate_irqs_away(void);