aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-12-29 16:32:35 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-12-29 16:32:35 -0500
commit33edcf133ba93ecba2e4b6472e97b689895d805c (patch)
tree327d7a20acef64005e7c5ccbfa1265be28aeb6ac /arch/powerpc/platforms
parentbe4d638c1597580ed2294d899d9f1a2cd10e462c (diff)
parent3c92ec8ae91ecf59d88c798301833d7cf83f2179 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/40x/ep405.c2
-rw-r--r--arch/powerpc/platforms/40x/kilauea.c2
-rw-r--r--arch/powerpc/platforms/40x/ppc40x_simple.c2
-rw-r--r--arch/powerpc/platforms/44x/ebony.c2
-rw-r--r--arch/powerpc/platforms/44x/ppc44x_simple.c2
-rw-r--r--arch/powerpc/platforms/44x/sam440ep.c2
-rw-r--r--arch/powerpc/platforms/52xx/lite5200_pm.c1
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c237
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.h53
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pm.c3
-rw-r--r--arch/powerpc/platforms/82xx/pq2.c2
-rw-r--r--arch/powerpc/platforms/85xx/Makefile2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ds.c11
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c8
-rw-r--r--arch/powerpc/platforms/85xx/smp.c104
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/86xx/Makefile3
-rw-r--r--arch/powerpc/platforms/86xx/gef_gpio.c143
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype12
-rw-r--r--arch/powerpc/platforms/cell/Kconfig23
-rw-r--r--arch/powerpc/platforms/cell/Makefile17
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c3
-rw-r--r--arch/powerpc/platforms/cell/celleb_setup.c9
-rw-r--r--arch/powerpc/platforms/cell/iommu.c5
-rw-r--r--arch/powerpc/platforms/cell/qpace_setup.c152
-rw-r--r--arch/powerpc/platforms/cell/setup.c6
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c27
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c8
-rw-r--r--arch/powerpc/platforms/chrp/pci.c3
-rw-r--r--arch/powerpc/platforms/embedded6xx/c2k.c6
-rw-r--r--arch/powerpc/platforms/embedded6xx/prpmc2800.c6
-rw-r--r--arch/powerpc/platforms/iseries/Kconfig1
-rw-r--r--arch/powerpc/platforms/maple/setup.c6
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c2
-rw-r--r--arch/powerpc/platforms/powermac/pci.c6
-rw-r--r--arch/powerpc/platforms/powermac/setup.c10
-rw-r--r--arch/powerpc/platforms/powermac/sleep.S5
-rw-r--r--arch/powerpc/platforms/powermac/smp.c2
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c33
-rw-r--r--arch/powerpc/platforms/ps3/mm.c2
-rw-r--r--arch/powerpc/platforms/ps3/setup.c8
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c38
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig2
-rw-r--r--arch/powerpc/platforms/pseries/cmm.c29
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c44
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c2
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c163
-rw-r--r--arch/powerpc/platforms/pseries/phyp_dump.c5
-rw-r--r--arch/powerpc/platforms/pseries/xics.c43
50 files changed, 885 insertions, 376 deletions
diff --git a/arch/powerpc/platforms/40x/ep405.c b/arch/powerpc/platforms/40x/ep405.c
index ae2e7f67c18e..4058fd1e7fc7 100644
--- a/arch/powerpc/platforms/40x/ep405.c
+++ b/arch/powerpc/platforms/40x/ep405.c
@@ -100,7 +100,7 @@ static void __init ep405_setup_arch(void)
100 /* Find & init the BCSR CPLD */ 100 /* Find & init the BCSR CPLD */
101 ep405_init_bcsr(); 101 ep405_init_bcsr();
102 102
103 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 103 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
104} 104}
105 105
106static int __init ep405_probe(void) 106static int __init ep405_probe(void)
diff --git a/arch/powerpc/platforms/40x/kilauea.c b/arch/powerpc/platforms/40x/kilauea.c
index 1dd24ffc0dc1..fd7d934dac8b 100644
--- a/arch/powerpc/platforms/40x/kilauea.c
+++ b/arch/powerpc/platforms/40x/kilauea.c
@@ -44,7 +44,7 @@ static int __init kilauea_probe(void)
44 if (!of_flat_dt_is_compatible(root, "amcc,kilauea")) 44 if (!of_flat_dt_is_compatible(root, "amcc,kilauea"))
45 return 0; 45 return 0;
46 46
47 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 47 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
48 48
49 return 1; 49 return 1;
50} 50}
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c
index 4498a86b46c3..f40ac9b8f99f 100644
--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
+++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
@@ -61,7 +61,7 @@ static int __init ppc40x_probe(void)
61 61
62 for (i = 0; i < ARRAY_SIZE(board); i++) { 62 for (i = 0; i < ARRAY_SIZE(board); i++) {
63 if (of_flat_dt_is_compatible(root, board[i])) { 63 if (of_flat_dt_is_compatible(root, board[i])) {
64 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 64 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
65 return 1; 65 return 1;
66 } 66 }
67 } 67 }
diff --git a/arch/powerpc/platforms/44x/ebony.c b/arch/powerpc/platforms/44x/ebony.c
index a0e8fe4662f6..88b9117fa691 100644
--- a/arch/powerpc/platforms/44x/ebony.c
+++ b/arch/powerpc/platforms/44x/ebony.c
@@ -54,7 +54,7 @@ static int __init ebony_probe(void)
54 if (!of_flat_dt_is_compatible(root, "ibm,ebony")) 54 if (!of_flat_dt_is_compatible(root, "ibm,ebony"))
55 return 0; 55 return 0;
56 56
57 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 57 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
58 58
59 return 1; 59 return 1;
60} 60}
diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c
index 29671262801f..76fdc51dac8b 100644
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
@@ -69,7 +69,7 @@ static int __init ppc44x_probe(void)
69 69
70 for (i = 0; i < ARRAY_SIZE(board); i++) { 70 for (i = 0; i < ARRAY_SIZE(board); i++) {
71 if (of_flat_dt_is_compatible(root, board[i])) { 71 if (of_flat_dt_is_compatible(root, board[i])) {
72 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 72 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
73 return 1; 73 return 1;
74 } 74 }
75 } 75 }
diff --git a/arch/powerpc/platforms/44x/sam440ep.c b/arch/powerpc/platforms/44x/sam440ep.c
index 47f10e647735..a78e8eb6da41 100644
--- a/arch/powerpc/platforms/44x/sam440ep.c
+++ b/arch/powerpc/platforms/44x/sam440ep.c
@@ -51,7 +51,7 @@ static int __init sam440ep_probe(void)
51 if (!of_flat_dt_is_compatible(root, "acube,sam440ep")) 51 if (!of_flat_dt_is_compatible(root, "acube,sam440ep"))
52 return 0; 52 return 0;
53 53
54 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; 54 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
55 55
56 return 1; 56 return 1;
57} 57}
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c
index fe92e65103ed..b5c753db125e 100644
--- a/arch/powerpc/platforms/52xx/lite5200_pm.c
+++ b/arch/powerpc/platforms/52xx/lite5200_pm.c
@@ -3,7 +3,6 @@
3#include <asm/io.h> 3#include <asm/io.h>
4#include <asm/time.h> 4#include <asm/time.h>
5#include <asm/mpc52xx.h> 5#include <asm/mpc52xx.h>
6#include "mpc52xx_pic.h"
7 6
8/* defined in lite5200_sleep.S and only used here */ 7/* defined in lite5200_sleep.S and only used here */
9extern void lite5200_low_power(void __iomem *sram, void __iomem *mbar); 8extern void lite5200_low_power(void __iomem *sram, void __iomem *mbar);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index b49a18527661..c3f2c21024e3 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -375,7 +375,7 @@ mpc52xx_add_bridge(struct device_node *node)
375 375
376 pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name); 376 pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
377 377
378 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 378 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
379 379
380 if (of_address_to_resource(node, 0, &rsrc) != 0) { 380 if (of_address_to_resource(node, 0, &rsrc) != 0) {
381 printk(KERN_ERR "Can't get %s resources\n", node->full_name); 381 printk(KERN_ERR "Can't get %s resources\n", node->full_name);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 8479394e9ab4..72865e8e4b51 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -2,20 +2,100 @@
2 * 2 *
3 * Programmable Interrupt Controller functions for the Freescale MPC52xx. 3 * Programmable Interrupt Controller functions for the Freescale MPC52xx.
4 * 4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
5 * Copyright (C) 2006 bplan GmbH 6 * Copyright (C) 2006 bplan GmbH
7 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
8 * Copyright (C) 2003 Montavista Software, Inc
6 * 9 *
7 * Based on the code from the 2.4 kernel by 10 * Based on the code from the 2.4 kernel by
8 * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg. 11 * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
9 * 12 *
10 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
11 * Copyright (C) 2003 Montavista Software, Inc
12 *
13 * This file is licensed under the terms of the GNU General Public License 13 * This file is licensed under the terms of the GNU General Public License
14 * version 2. This program is licensed "as is" without any warranty of any 14 * version 2. This program is licensed "as is" without any warranty of any
15 * kind, whether express or implied. 15 * kind, whether express or implied.
16 * 16 *
17 */ 17 */
18 18
19/*
20 * This is the device driver for the MPC5200 interrupt controller.
21 *
22 * hardware overview
23 * -----------------
24 * The MPC5200 interrupt controller groups the all interrupt sources into
25 * three groups called 'critical', 'main', and 'peripheral'. The critical
26 * group has 3 irqs, External IRQ0, slice timer 0 irq, and wake from deep
27 * sleep. Main group include the other 3 external IRQs, slice timer 1, RTC,
28 * gpios, and the general purpose timers. Peripheral group contains the
29 * remaining irq sources from all of the on-chip peripherals (PSCs, Ethernet,
30 * USB, DMA, etc).
31 *
32 * virqs
33 * -----
34 * The Linux IRQ subsystem requires that each irq source be assigned a
35 * system wide unique IRQ number starting at 1 (0 means no irq). Since
36 * systems can have multiple interrupt controllers, the virtual IRQ (virq)
37 * infrastructure lets each interrupt controller to define a local set
38 * of IRQ numbers and the virq infrastructure maps those numbers into
39 * a unique range of the global IRQ# space.
40 *
41 * To define a range of virq numbers for this controller, this driver first
42 * assigns a number to each of the irq groups (called the level 1 or L1
43 * value). Within each group individual irq sources are also assigned a
44 * number, as defined by the MPC5200 user guide, and refers to it as the
45 * level 2 or L2 value. The virq number is determined by shifting up the
46 * L1 value by MPC52xx_IRQ_L1_OFFSET and ORing it with the L2 value.
47 *
48 * For example, the TMR0 interrupt is irq 9 in the main group. The
49 * virq for TMR0 is calculated by ((1 << MPC52xx_IRQ_L1_OFFSET) | 9).
50 *
51 * The observant reader will also notice that this driver defines a 4th
52 * interrupt group called 'bestcomm'. The bestcomm group isn't physically
53 * part of the MPC5200 interrupt controller, but it is used here to assign
54 * a separate virq number for each bestcomm task (since any of the 16
55 * bestcomm tasks can cause the bestcomm interrupt to be raised). When a
56 * bestcomm interrupt occurs (peripheral group, irq 0) this driver determines
57 * which task needs servicing and returns the irq number for that task. This
58 * allows drivers which use bestcomm to define their own interrupt handlers.
59 *
60 * irq_chip structures
61 * -------------------
62 * For actually manipulating IRQs (masking, enabling, clearing, etc) this
63 * driver defines four separate 'irq_chip' structures, one for the main
64 * group, one for the peripherals group, one for the bestcomm group and one
65 * for external interrupts. The irq_chip structures provide the hooks needed
66 * to manipulate each IRQ source, and since each group is has a separate set
67 * of registers for controlling the irq, it makes sense to divide up the
68 * hooks along those lines.
69 *
70 * You'll notice that there is not an irq_chip for the critical group and
71 * you'll also notice that there is an irq_chip defined for external
72 * interrupts even though there is no external interrupt group. The reason
73 * for this is that the four external interrupts are all managed with the same
74 * register even though one of the external IRQs is in the critical group and
75 * the other three are in the main group. For this reason it makes sense for
76 * the 4 external irqs to be managed using a separate set of hooks. The
77 * reason there is no crit irq_chip is that of the 3 irqs in the critical
78 * group, only external interrupt is actually support at this time by this
79 * driver and since external interrupt is the only one used, it can just
80 * be directed to make use of the external irq irq_chip.
81 *
82 * device tree bindings
83 * --------------------
84 * The device tree bindings for this controller reflect the two level
85 * organization of irqs in the device. #interrupt-cells = <3> where the
86 * first cell is the group number [0..3], the second cell is the irq
87 * number in the group, and the third cell is the sense type (level/edge).
88 * For reference, the following is a list of the interrupt property values
89 * associated with external interrupt sources on the MPC5200 (just because
90 * it is non-obvious to determine what the interrupts property should be
91 * when reading the mpc5200 manual and it is a frequently asked question).
92 *
93 * External interrupts:
94 * <0 0 n> external irq0, n is sense (n=0: level high,
95 * <1 1 n> external irq1, n is sense n=1: edge rising,
96 * <1 2 n> external irq2, n is sense n=2: edge falling,
97 * <1 3 n> external irq3, n is sense n=3: level low)
98 */
19#undef DEBUG 99#undef DEBUG
20 100
21#include <linux/interrupt.h> 101#include <linux/interrupt.h>
@@ -24,11 +104,19 @@
24#include <asm/io.h> 104#include <asm/io.h>
25#include <asm/prom.h> 105#include <asm/prom.h>
26#include <asm/mpc52xx.h> 106#include <asm/mpc52xx.h>
27#include "mpc52xx_pic.h"
28 107
29/* 108/* HW IRQ mapping */
30 * 109#define MPC52xx_IRQ_L1_CRIT (0)
31*/ 110#define MPC52xx_IRQ_L1_MAIN (1)
111#define MPC52xx_IRQ_L1_PERP (2)
112#define MPC52xx_IRQ_L1_SDMA (3)
113
114#define MPC52xx_IRQ_L1_OFFSET (6)
115#define MPC52xx_IRQ_L1_MASK (0x00c0)
116#define MPC52xx_IRQ_L2_MASK (0x003f)
117
118#define MPC52xx_IRQ_HIGHTESTHWIRQ (0xd0)
119
32 120
33/* MPC5200 device tree match tables */ 121/* MPC5200 device tree match tables */
34static struct of_device_id mpc52xx_pic_ids[] __initdata = { 122static struct of_device_id mpc52xx_pic_ids[] __initdata = {
@@ -53,10 +141,7 @@ static unsigned char mpc52xx_map_senses[4] = {
53 IRQ_TYPE_LEVEL_LOW, 141 IRQ_TYPE_LEVEL_LOW,
54}; 142};
55 143
56/* 144/* Utility functions */
57 *
58*/
59
60static inline void io_be_setbit(u32 __iomem *addr, int bitno) 145static inline void io_be_setbit(u32 __iomem *addr, int bitno)
61{ 146{
62 out_be32(addr, in_be32(addr) | (1 << bitno)); 147 out_be32(addr, in_be32(addr) | (1 << bitno));
@@ -69,15 +154,14 @@ static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
69 154
70/* 155/*
71 * IRQ[0-3] interrupt irq_chip 156 * IRQ[0-3] interrupt irq_chip
72*/ 157 */
73
74static void mpc52xx_extirq_mask(unsigned int virq) 158static void mpc52xx_extirq_mask(unsigned int virq)
75{ 159{
76 int irq; 160 int irq;
77 int l2irq; 161 int l2irq;
78 162
79 irq = irq_map[virq].hwirq; 163 irq = irq_map[virq].hwirq;
80 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 164 l2irq = irq & MPC52xx_IRQ_L2_MASK;
81 165
82 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); 166 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
83 167
@@ -90,7 +174,7 @@ static void mpc52xx_extirq_unmask(unsigned int virq)
90 int l2irq; 174 int l2irq;
91 175
92 irq = irq_map[virq].hwirq; 176 irq = irq_map[virq].hwirq;
93 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 177 l2irq = irq & MPC52xx_IRQ_L2_MASK;
94 178
95 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); 179 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
96 180
@@ -103,7 +187,7 @@ static void mpc52xx_extirq_ack(unsigned int virq)
103 int l2irq; 187 int l2irq;
104 188
105 irq = irq_map[virq].hwirq; 189 irq = irq_map[virq].hwirq;
106 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 190 l2irq = irq & MPC52xx_IRQ_L2_MASK;
107 191
108 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); 192 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
109 193
@@ -117,7 +201,7 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
117 int l2irq; 201 int l2irq;
118 202
119 irq = irq_map[virq].hwirq; 203 irq = irq_map[virq].hwirq;
120 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 204 l2irq = irq & MPC52xx_IRQ_L2_MASK;
121 205
122 pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type); 206 pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type);
123 207
@@ -156,15 +240,14 @@ static struct irq_chip mpc52xx_extirq_irqchip = {
156 240
157/* 241/*
158 * Main interrupt irq_chip 242 * Main interrupt irq_chip
159*/ 243 */
160
161static void mpc52xx_main_mask(unsigned int virq) 244static void mpc52xx_main_mask(unsigned int virq)
162{ 245{
163 int irq; 246 int irq;
164 int l2irq; 247 int l2irq;
165 248
166 irq = irq_map[virq].hwirq; 249 irq = irq_map[virq].hwirq;
167 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 250 l2irq = irq & MPC52xx_IRQ_L2_MASK;
168 251
169 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); 252 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
170 253
@@ -177,7 +260,7 @@ static void mpc52xx_main_unmask(unsigned int virq)
177 int l2irq; 260 int l2irq;
178 261
179 irq = irq_map[virq].hwirq; 262 irq = irq_map[virq].hwirq;
180 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 263 l2irq = irq & MPC52xx_IRQ_L2_MASK;
181 264
182 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); 265 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
183 266
@@ -193,15 +276,14 @@ static struct irq_chip mpc52xx_main_irqchip = {
193 276
194/* 277/*
195 * Peripherals interrupt irq_chip 278 * Peripherals interrupt irq_chip
196*/ 279 */
197
198static void mpc52xx_periph_mask(unsigned int virq) 280static void mpc52xx_periph_mask(unsigned int virq)
199{ 281{
200 int irq; 282 int irq;
201 int l2irq; 283 int l2irq;
202 284
203 irq = irq_map[virq].hwirq; 285 irq = irq_map[virq].hwirq;
204 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 286 l2irq = irq & MPC52xx_IRQ_L2_MASK;
205 287
206 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); 288 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
207 289
@@ -214,7 +296,7 @@ static void mpc52xx_periph_unmask(unsigned int virq)
214 int l2irq; 296 int l2irq;
215 297
216 irq = irq_map[virq].hwirq; 298 irq = irq_map[virq].hwirq;
217 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 299 l2irq = irq & MPC52xx_IRQ_L2_MASK;
218 300
219 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); 301 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
220 302
@@ -230,15 +312,14 @@ static struct irq_chip mpc52xx_periph_irqchip = {
230 312
231/* 313/*
232 * SDMA interrupt irq_chip 314 * SDMA interrupt irq_chip
233*/ 315 */
234
235static void mpc52xx_sdma_mask(unsigned int virq) 316static void mpc52xx_sdma_mask(unsigned int virq)
236{ 317{
237 int irq; 318 int irq;
238 int l2irq; 319 int l2irq;
239 320
240 irq = irq_map[virq].hwirq; 321 irq = irq_map[virq].hwirq;
241 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 322 l2irq = irq & MPC52xx_IRQ_L2_MASK;
242 323
243 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); 324 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
244 325
@@ -251,7 +332,7 @@ static void mpc52xx_sdma_unmask(unsigned int virq)
251 int l2irq; 332 int l2irq;
252 333
253 irq = irq_map[virq].hwirq; 334 irq = irq_map[virq].hwirq;
254 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 335 l2irq = irq & MPC52xx_IRQ_L2_MASK;
255 336
256 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); 337 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
257 338
@@ -264,7 +345,7 @@ static void mpc52xx_sdma_ack(unsigned int virq)
264 int l2irq; 345 int l2irq;
265 346
266 irq = irq_map[virq].hwirq; 347 irq = irq_map[virq].hwirq;
267 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 348 l2irq = irq & MPC52xx_IRQ_L2_MASK;
268 349
269 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); 350 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
270 351
@@ -278,13 +359,12 @@ static struct irq_chip mpc52xx_sdma_irqchip = {
278 .ack = mpc52xx_sdma_ack, 359 .ack = mpc52xx_sdma_ack,
279}; 360};
280 361
281/* 362/**
282 * irq_host 363 * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property
283*/ 364 */
284
285static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct, 365static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
286 u32 * intspec, unsigned int intsize, 366 u32 *intspec, unsigned int intsize,
287 irq_hw_number_t * out_hwirq, 367 irq_hw_number_t *out_hwirq,
288 unsigned int *out_flags) 368 unsigned int *out_flags)
289{ 369{
290 int intrvect_l1; 370 int intrvect_l1;
@@ -299,10 +379,9 @@ static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
299 intrvect_l2 = (int)intspec[1]; 379 intrvect_l2 = (int)intspec[1];
300 intrvect_type = (int)intspec[2]; 380 intrvect_type = (int)intspec[2];
301 381
302 intrvect_linux = 382 intrvect_linux = (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) &
303 (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK; 383 MPC52xx_IRQ_L1_MASK;
304 intrvect_linux |= 384 intrvect_linux |= intrvect_l2 & MPC52xx_IRQ_L2_MASK;
305 (intrvect_l2 << MPC52xx_IRQ_L2_OFFSET) & MPC52xx_IRQ_L2_MASK;
306 385
307 pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1, 386 pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
308 intrvect_l2); 387 intrvect_l2);
@@ -313,11 +392,11 @@ static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
313 return 0; 392 return 0;
314} 393}
315 394
316/* 395/**
317 * this function retrieves the correct IRQ type out 396 * mpc52xx_irqx_gettype - determine the IRQ sense type (level/edge)
318 * of the MPC regs 397 *
319 * Only externals IRQs needs this 398 * Only external IRQs need this.
320*/ 399 */
321static int mpc52xx_irqx_gettype(int irq) 400static int mpc52xx_irqx_gettype(int irq)
322{ 401{
323 int type; 402 int type;
@@ -329,6 +408,9 @@ static int mpc52xx_irqx_gettype(int irq)
329 return mpc52xx_map_senses[type]; 408 return mpc52xx_map_senses[type];
330} 409}
331 410
411/**
412 * mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure
413 */
332static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, 414static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
333 irq_hw_number_t irq) 415 irq_hw_number_t irq)
334{ 416{
@@ -339,7 +421,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
339 int type; 421 int type;
340 422
341 l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET; 423 l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET;
342 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; 424 l2irq = irq & MPC52xx_IRQ_L2_MASK;
343 425
344 /* 426 /*
345 * Most of ours IRQs will be level low 427 * Most of ours IRQs will be level low
@@ -379,8 +461,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
379 break; 461 break;
380 462
381 default: 463 default:
382 pr_debug("%s: Error, unknown L1 IRQ (0x%x)\n", __func__, l1irq); 464 pr_err("%s: invalid virq requested (0x%x)\n", __func__, virq);
383 printk(KERN_ERR "Unknow IRQ!\n");
384 return -EINVAL; 465 return -EINVAL;
385 } 466 }
386 467
@@ -406,10 +487,15 @@ static struct irq_host_ops mpc52xx_irqhost_ops = {
406 .map = mpc52xx_irqhost_map, 487 .map = mpc52xx_irqhost_map,
407}; 488};
408 489
409/* 490/**
410 * init (public) 491 * mpc52xx_init_irq - Initialize and register with the virq subsystem
411*/ 492 *
412 493 * Hook for setting up IRQs on an mpc5200 system. A pointer to this function
494 * is to be put into the machine definition structure.
495 *
496 * This function searches the device tree for an MPC5200 interrupt controller,
497 * initializes it, and registers it with the virq subsystem.
498 */
413void __init mpc52xx_init_irq(void) 499void __init mpc52xx_init_irq(void)
414{ 500{
415 u32 intr_ctrl; 501 u32 intr_ctrl;
@@ -454,7 +540,6 @@ void __init mpc52xx_init_irq(void)
454 * As last step, add an irq host to translate the real 540 * As last step, add an irq host to translate the real
455 * hw irq information provided by the ofw to linux virq 541 * hw irq information provided by the ofw to linux virq
456 */ 542 */
457
458 mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR, 543 mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR,
459 MPC52xx_IRQ_HIGHTESTHWIRQ, 544 MPC52xx_IRQ_HIGHTESTHWIRQ,
460 &mpc52xx_irqhost_ops, -1); 545 &mpc52xx_irqhost_ops, -1);
@@ -462,12 +547,38 @@ void __init mpc52xx_init_irq(void)
462 if (!mpc52xx_irqhost) 547 if (!mpc52xx_irqhost)
463 panic(__FILE__ ": Cannot allocate the IRQ host\n"); 548 panic(__FILE__ ": Cannot allocate the IRQ host\n");
464 549
465 printk(KERN_INFO "MPC52xx PIC is up and running!\n"); 550 irq_set_default_host(mpc52xx_irqhost);
551
552 pr_info("MPC52xx PIC is up and running!\n");
466} 553}
467 554
468/* 555/**
469 * get_irq (public) 556 * mpc52xx_get_irq - Get pending interrupt number hook function
470*/ 557 *
558 * Called by the interupt handler to determine what IRQ handler needs to be
559 * executed.
560 *
561 * Status of pending interrupts is determined by reading the encoded status
562 * register. The encoded status register has three fields; one for each of the
563 * types of interrupts defined by the controller - 'critical', 'main' and
564 * 'peripheral'. This function reads the status register and returns the IRQ
565 * number associated with the highest priority pending interrupt. 'Critical'
566 * interrupts have the highest priority, followed by 'main' interrupts, and
567 * then 'peripheral'.
568 *
569 * The mpc5200 interrupt controller can be configured to boost the priority
570 * of individual 'peripheral' interrupts. If this is the case then a special
571 * value will appear in either the crit or main fields indicating a high
572 * or medium priority peripheral irq has occurred.
573 *
574 * This function checks each of the 3 irq request fields and returns the
575 * first pending interrupt that it finds.
576 *
577 * This function also identifies a 4th type of interrupt; 'bestcomm'. Each
578 * bestcomm DMA task can raise the bestcomm peripheral interrupt. When this
579 * occurs at task-specific IRQ# is decoded so that each task can have its
580 * own IRQ handler.
581 */
471unsigned int mpc52xx_get_irq(void) 582unsigned int mpc52xx_get_irq(void)
472{ 583{
473 u32 status; 584 u32 status;
@@ -478,25 +589,21 @@ unsigned int mpc52xx_get_irq(void)
478 irq = (status >> 8) & 0x3; 589 irq = (status >> 8) & 0x3;
479 if (irq == 2) /* high priority peripheral */ 590 if (irq == 2) /* high priority peripheral */
480 goto peripheral; 591 goto peripheral;
481 irq |= (MPC52xx_IRQ_L1_CRIT << MPC52xx_IRQ_L1_OFFSET) & 592 irq |= (MPC52xx_IRQ_L1_CRIT << MPC52xx_IRQ_L1_OFFSET);
482 MPC52xx_IRQ_L1_MASK;
483 } else if (status & 0x00200000) { /* main */ 593 } else if (status & 0x00200000) { /* main */
484 irq = (status >> 16) & 0x1f; 594 irq = (status >> 16) & 0x1f;
485 if (irq == 4) /* low priority peripheral */ 595 if (irq == 4) /* low priority peripheral */
486 goto peripheral; 596 goto peripheral;
487 irq |= (MPC52xx_IRQ_L1_MAIN << MPC52xx_IRQ_L1_OFFSET) & 597 irq |= (MPC52xx_IRQ_L1_MAIN << MPC52xx_IRQ_L1_OFFSET);
488 MPC52xx_IRQ_L1_MASK;
489 } else if (status & 0x20000000) { /* peripheral */ 598 } else if (status & 0x20000000) { /* peripheral */
490 peripheral: 599 peripheral:
491 irq = (status >> 24) & 0x1f; 600 irq = (status >> 24) & 0x1f;
492 if (irq == 0) { /* bestcomm */ 601 if (irq == 0) { /* bestcomm */
493 status = in_be32(&sdma->IntPend); 602 status = in_be32(&sdma->IntPend);
494 irq = ffs(status) - 1; 603 irq = ffs(status) - 1;
495 irq |= (MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET) & 604 irq |= (MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET);
496 MPC52xx_IRQ_L1_MASK;
497 } else { 605 } else {
498 irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET) & 606 irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET);
499 MPC52xx_IRQ_L1_MASK;
500 } 607 }
501 } 608 }
502 609
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.h b/arch/powerpc/platforms/52xx/mpc52xx_pic.h
deleted file mode 100644
index 1a26bcdb3049..000000000000
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * Header file for Freescale MPC52xx Interrupt controller
3 *
4 * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
5 * Copyright (C) 2003 MontaVista, Software, Inc.
6 *
7 * This file is licensed under the terms of the GNU General Public License
8 * version 2. This program is licensed "as is" without any warranty of any
9 * kind, whether express or implied.
10 */
11
12#ifndef __POWERPC_SYSDEV_MPC52xx_PIC_H__
13#define __POWERPC_SYSDEV_MPC52xx_PIC_H__
14
15#include <asm/types.h>
16
17
18/* HW IRQ mapping */
19#define MPC52xx_IRQ_L1_CRIT (0)
20#define MPC52xx_IRQ_L1_MAIN (1)
21#define MPC52xx_IRQ_L1_PERP (2)
22#define MPC52xx_IRQ_L1_SDMA (3)
23
24#define MPC52xx_IRQ_L1_OFFSET (6)
25#define MPC52xx_IRQ_L1_MASK (0x00c0)
26
27#define MPC52xx_IRQ_L2_OFFSET (0)
28#define MPC52xx_IRQ_L2_MASK (0x003f)
29
30#define MPC52xx_IRQ_HIGHTESTHWIRQ (0xd0)
31
32
33/* Interrupt controller Register set */
34struct mpc52xx_intr {
35 u32 per_mask; /* INTR + 0x00 */
36 u32 per_pri1; /* INTR + 0x04 */
37 u32 per_pri2; /* INTR + 0x08 */
38 u32 per_pri3; /* INTR + 0x0c */
39 u32 ctrl; /* INTR + 0x10 */
40 u32 main_mask; /* INTR + 0x14 */
41 u32 main_pri1; /* INTR + 0x18 */
42 u32 main_pri2; /* INTR + 0x1c */
43 u32 reserved1; /* INTR + 0x20 */
44 u32 enc_status; /* INTR + 0x24 */
45 u32 crit_status; /* INTR + 0x28 */
46 u32 main_status; /* INTR + 0x2c */
47 u32 per_status; /* INTR + 0x30 */
48 u32 reserved2; /* INTR + 0x34 */
49 u32 per_error; /* INTR + 0x38 */
50};
51
52#endif /* __POWERPC_SYSDEV_MPC52xx_PIC_H__ */
53
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
index c72d3304387f..a55b0b6813ed 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
@@ -5,9 +5,6 @@
5#include <asm/cacheflush.h> 5#include <asm/cacheflush.h>
6#include <asm/mpc52xx.h> 6#include <asm/mpc52xx.h>
7 7
8#include "mpc52xx_pic.h"
9
10
11/* these are defined in mpc52xx_sleep.S, and only used here */ 8/* these are defined in mpc52xx_sleep.S, and only used here */
12extern void mpc52xx_deep_sleep(void __iomem *sram, void __iomem *sdram_regs, 9extern void mpc52xx_deep_sleep(void __iomem *sram, void __iomem *sdram_regs,
13 struct mpc52xx_cdm __iomem *, struct mpc52xx_intr __iomem*); 10 struct mpc52xx_cdm __iomem *, struct mpc52xx_intr __iomem*);
diff --git a/arch/powerpc/platforms/82xx/pq2.c b/arch/powerpc/platforms/82xx/pq2.c
index 1b75902fad64..9761a59f175f 100644
--- a/arch/powerpc/platforms/82xx/pq2.c
+++ b/arch/powerpc/platforms/82xx/pq2.c
@@ -53,7 +53,7 @@ static void __init pq2_pci_add_bridge(struct device_node *np)
53 if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b) 53 if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b)
54 goto err; 54 goto err;
55 55
56 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 56 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
57 57
58 hose = pcibios_alloc_controller(np); 58 hose = pcibios_alloc_controller(np);
59 if (!hose) 59 if (!hose)
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index cb3054e1001d..f0798c09980f 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -1,6 +1,8 @@
1# 1#
2# Makefile for the PowerPC 85xx linux kernel. 2# Makefile for the PowerPC 85xx linux kernel.
3# 3#
4obj-$(CONFIG_SMP) += smp.o
5
4obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o 6obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
5obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o 7obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
6obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o 8obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 613bf8c2e30d..a8301c8ad537 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -63,6 +63,7 @@ void __init mpc85xx_ds_pic_init(void)
63 struct device_node *cascade_node = NULL; 63 struct device_node *cascade_node = NULL;
64 int cascade_irq; 64 int cascade_irq;
65#endif 65#endif
66 unsigned long root = of_get_flat_dt_root();
66 67
67 np = of_find_node_by_type(NULL, "open-pic"); 68 np = of_find_node_by_type(NULL, "open-pic");
68 if (np == NULL) { 69 if (np == NULL) {
@@ -76,11 +77,19 @@ void __init mpc85xx_ds_pic_init(void)
76 return; 77 return;
77 } 78 }
78 79
79 mpic = mpic_alloc(np, r.start, 80 if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) {
81 mpic = mpic_alloc(np, r.start,
82 MPIC_PRIMARY |
83 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
84 0, 256, " OpenPIC ");
85 } else {
86 mpic = mpic_alloc(np, r.start,
80 MPIC_PRIMARY | MPIC_WANTS_RESET | 87 MPIC_PRIMARY | MPIC_WANTS_RESET |
81 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | 88 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
82 MPIC_SINGLE_DEST_CPU, 89 MPIC_SINGLE_DEST_CPU,
83 0, 256, " OpenPIC "); 90 0, 256, " OpenPIC ");
91 }
92
84 BUG_ON(mpic == NULL); 93 BUG_ON(mpic == NULL);
85 of_node_put(np); 94 of_node_put(np);
86 95
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 2494c5155919..658a36fab3ab 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -231,7 +231,7 @@ static void __init mpc85xx_mds_setup_arch(void)
231 231
232static int __init board_fixups(void) 232static int __init board_fixups(void)
233{ 233{
234 char phy_id[BUS_ID_SIZE]; 234 char phy_id[20];
235 char *compstrs[2] = {"fsl,gianfar-mdio", "fsl,ucc-mdio"}; 235 char *compstrs[2] = {"fsl,gianfar-mdio", "fsl,ucc-mdio"};
236 struct device_node *mdio; 236 struct device_node *mdio;
237 struct resource res; 237 struct resource res;
@@ -241,13 +241,15 @@ static int __init board_fixups(void)
241 mdio = of_find_compatible_node(NULL, NULL, compstrs[i]); 241 mdio = of_find_compatible_node(NULL, NULL, compstrs[i]);
242 242
243 of_address_to_resource(mdio, 0, &res); 243 of_address_to_resource(mdio, 0, &res);
244 snprintf(phy_id, BUS_ID_SIZE, "%x:%02x", res.start, 1); 244 snprintf(phy_id, sizeof(phy_id), "%llx:%02x",
245 (unsigned long long)res.start, 1);
245 246
246 phy_register_fixup_for_id(phy_id, mpc8568_fixup_125_clock); 247 phy_register_fixup_for_id(phy_id, mpc8568_fixup_125_clock);
247 phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups); 248 phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);
248 249
249 /* Register a workaround for errata */ 250 /* Register a workaround for errata */
250 snprintf(phy_id, BUS_ID_SIZE, "%x:%02x", res.start, 7); 251 snprintf(phy_id, sizeof(phy_id), "%llx:%02x",
252 (unsigned long long)res.start, 7);
251 phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups); 253 phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);
252 254
253 of_node_put(mdio); 255 of_node_put(mdio);
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
new file mode 100644
index 000000000000..d652c713f496
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -0,0 +1,104 @@
1/*
2 * Author: Andy Fleming <afleming@freescale.com>
3 * Kumar Gala <galak@kernel.crashing.org>
4 *
5 * Copyright 2006-2008 Freescale Semiconductor Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/stddef.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/of.h>
18
19#include <asm/machdep.h>
20#include <asm/pgtable.h>
21#include <asm/page.h>
22#include <asm/mpic.h>
23#include <asm/cacheflush.h>
24
25#include <sysdev/fsl_soc.h>
26
27extern volatile unsigned long __secondary_hold_acknowledge;
28extern void __early_start(void);
29
30#define BOOT_ENTRY_ADDR_UPPER 0
31#define BOOT_ENTRY_ADDR_LOWER 1
32#define BOOT_ENTRY_R3_UPPER 2
33#define BOOT_ENTRY_R3_LOWER 3
34#define BOOT_ENTRY_RESV 4
35#define BOOT_ENTRY_PIR 5
36#define BOOT_ENTRY_R6_UPPER 6
37#define BOOT_ENTRY_R6_LOWER 7
38#define NUM_BOOT_ENTRY 8
39#define SIZE_BOOT_ENTRY (NUM_BOOT_ENTRY * sizeof(u32))
40
41static void __init
42smp_85xx_kick_cpu(int nr)
43{
44 unsigned long flags;
45 const u64 *cpu_rel_addr;
46 __iomem u32 *bptr_vaddr;
47 struct device_node *np;
48 int n = 0;
49
50 WARN_ON (nr < 0 || nr >= NR_CPUS);
51
52 pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
53
54 local_irq_save(flags);
55
56 np = of_get_cpu_node(nr, NULL);
57 cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
58
59 if (cpu_rel_addr == NULL) {
60 printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr);
61 return;
62 }
63
64 /* Map the spin table */
65 bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
66
67 out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr);
68 out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
69
70 /* Wait a bit for the CPU to ack. */
71 while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
72 mdelay(1);
73
74 iounmap(bptr_vaddr);
75
76 local_irq_restore(flags);
77
78 pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
79}
80
81static void __init
82smp_85xx_setup_cpu(int cpu_nr)
83{
84 mpic_setup_this_cpu();
85
86 /* Clear any pending timer interrupts */
87 mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
88
89 /* Enable decrementer interrupt */
90 mtspr(SPRN_TCR, TCR_DIE);
91}
92
93struct smp_ops_t smp_85xx_ops = {
94 .message_pass = smp_mpic_message_pass,
95 .probe = smp_mpic_probe,
96 .kick_cpu = smp_85xx_kick_cpu,
97 .setup_cpu = smp_85xx_setup_cpu,
98};
99
100void __init
101mpc85xx_smp_init(void)
102{
103 smp_ops = &smp_85xx_ops;
104}
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 77dd797a2580..8e5693935975 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -34,6 +34,8 @@ config MPC8610_HPCD
34config GEF_SBC610 34config GEF_SBC610
35 bool "GE Fanuc SBC610" 35 bool "GE Fanuc SBC610"
36 select DEFAULT_UIMAGE 36 select DEFAULT_UIMAGE
37 select GENERIC_GPIO
38 select ARCH_REQUIRE_GPIOLIB
37 select HAS_RAPIDIO 39 select HAS_RAPIDIO
38 help 40 help
39 This option enables support for GE Fanuc's SBC610. 41 This option enables support for GE Fanuc's SBC610.
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile
index 4a56ff619afd..31e540c2ebbc 100644
--- a/arch/powerpc/platforms/86xx/Makefile
+++ b/arch/powerpc/platforms/86xx/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_SMP) += mpc86xx_smp.o
7obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o 7obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o
8obj-$(CONFIG_SBC8641D) += sbc8641d.o 8obj-$(CONFIG_SBC8641D) += sbc8641d.o
9obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o 9obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o
10obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o 10gef-gpio-$(CONFIG_GPIOLIB) += gef_gpio.o
11obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o $(gef-gpio-y)
diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c
new file mode 100644
index 000000000000..85b2800f4cb7
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/gef_gpio.c
@@ -0,0 +1,143 @@
1/*
2 * Driver for GE Fanuc's FPGA based GPIO pins
3 *
4 * Author: Martyn Welch <martyn.welch@gefanuc.com>
5 *
6 * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13/* TODO
14 *
15 * Configuration of output modes (totem-pole/open-drain)
16 * Interrupt configuration - interrupts are always generated the FPGA relies on
17 * the I/O interrupt controllers mask to stop them propergating
18 */
19
20#include <linux/kernel.h>
21#include <linux/compiler.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <linux/of.h>
25#include <linux/of_device.h>
26#include <linux/of_platform.h>
27#include <linux/of_gpio.h>
28#include <linux/gpio.h>
29
30#define GEF_GPIO_DIRECT 0x00
31#define GEF_GPIO_IN 0x04
32#define GEF_GPIO_OUT 0x08
33#define GEF_GPIO_TRIG 0x0C
34#define GEF_GPIO_POLAR_A 0x10
35#define GEF_GPIO_POLAR_B 0x14
36#define GEF_GPIO_INT_STAT 0x18
37#define GEF_GPIO_OVERRUN 0x1C
38#define GEF_GPIO_MODE 0x20
39
40#define NUM_GPIO 19
41
42static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value)
43{
44 unsigned int data;
45
46 data = ioread32be(reg);
47 /* value: 0=low; 1=high */
48 if (value & 0x1)
49 data = data | (0x1 << offset);
50 else
51 data = data & ~(0x1 << offset);
52
53 iowrite32be(data, reg);
54}
55
56
57static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
58{
59 unsigned int data;
60 struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
61
62 data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
63 data = data | (0x1 << offset);
64 iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
65
66 return 0;
67}
68
69static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
70{
71 unsigned int data;
72 struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
73
74 /* Set direction before switching to input */
75 _gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
76
77 data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
78 data = data & ~(0x1 << offset);
79 iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
80
81 return 0;
82}
83
84static int gef_gpio_get(struct gpio_chip *chip, unsigned offset)
85{
86 unsigned int data;
87 int state = 0;
88 struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
89
90 data = ioread32be(mmchip->regs + GEF_GPIO_IN);
91 state = (int)((data >> offset) & 0x1);
92
93 return state;
94}
95
96static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
97{
98 struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
99
100 _gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
101}
102
103static int __init gef_gpio_init(void)
104{
105 struct device_node *np;
106
107 for_each_compatible_node(np, NULL, "gef,sbc610-gpio") {
108 int retval;
109 struct of_mm_gpio_chip *gef_gpio_chip;
110
111 pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
112
113 /* Allocate chip structure */
114 gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
115 if (!gef_gpio_chip) {
116 pr_err("%s: Unable to allocate structure\n",
117 np->full_name);
118 continue;
119 }
120
121 /* Setup pointers to chip functions */
122 gef_gpio_chip->of_gc.gpio_cells = 2;
123 gef_gpio_chip->of_gc.gc.ngpio = NUM_GPIO;
124 gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
125 gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
126 gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
127 gef_gpio_chip->of_gc.gc.set = gef_gpio_set;
128
129 /* This function adds a memory mapped GPIO chip */
130 retval = of_mm_gpiochip_add(np, gef_gpio_chip);
131 if (retval) {
132 kfree(gef_gpio_chip);
133 pr_err("%s: Unable to add GPIO\n", np->full_name);
134 }
135 }
136
137 return 0;
138};
139arch_initcall(gef_gpio_init);
140
141MODULE_DESCRIPTION("GE Fanuc I/O FPGA GPIO driver");
142MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
143MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 548efa55c8fe..3d0c776f888d 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -195,16 +195,24 @@ config SPE
195 195
196config PPC_STD_MMU 196config PPC_STD_MMU
197 bool 197 bool
198 depends on 6xx || POWER3 || POWER4 || PPC64 198 depends on 6xx || PPC64
199 default y 199 default y
200 200
201config PPC_STD_MMU_32 201config PPC_STD_MMU_32
202 def_bool y 202 def_bool y
203 depends on PPC_STD_MMU && PPC32 203 depends on PPC_STD_MMU && PPC32
204 204
205config PPC_STD_MMU_64
206 def_bool y
207 depends on PPC_STD_MMU && PPC64
208
209config PPC_MMU_NOHASH
210 def_bool y
211 depends on !PPC_STD_MMU
212
205config PPC_MM_SLICES 213config PPC_MM_SLICES
206 bool 214 bool
207 default y if HUGETLB_PAGE || PPC_64K_PAGES 215 default y if HUGETLB_PAGE || (PPC_STD_MMU_64 && PPC_64K_PAGES)
208 default n 216 default n
209 217
210config VIRT_CPU_ACCOUNTING 218config VIRT_CPU_ACCOUNTING
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index c14d7d8d96c8..5cc3279559a4 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -2,13 +2,18 @@ config PPC_CELL
2 bool 2 bool
3 default n 3 default n
4 4
5config PPC_CELL_NATIVE 5config PPC_CELL_COMMON
6 bool 6 bool
7 select PPC_CELL 7 select PPC_CELL
8 select PPC_DCR_MMIO 8 select PPC_DCR_MMIO
9 select PPC_OF_PLATFORM_PCI
10 select PPC_INDIRECT_IO 9 select PPC_INDIRECT_IO
11 select PPC_NATIVE 10 select PPC_NATIVE
11 select PPC_RTAS
12
13config PPC_CELL_NATIVE
14 bool
15 select PPC_CELL_COMMON
16 select PPC_OF_PLATFORM_PCI
12 select MPIC 17 select MPIC
13 select IBM_NEW_EMAC_EMAC4 18 select IBM_NEW_EMAC_EMAC4
14 select IBM_NEW_EMAC_RGMII 19 select IBM_NEW_EMAC_RGMII
@@ -20,7 +25,6 @@ config PPC_IBM_CELL_BLADE
20 bool "IBM Cell Blade" 25 bool "IBM Cell Blade"
21 depends on PPC_MULTIPLATFORM && PPC64 26 depends on PPC_MULTIPLATFORM && PPC64
22 select PPC_CELL_NATIVE 27 select PPC_CELL_NATIVE
23 select PPC_RTAS
24 select MMIO_NVRAM 28 select MMIO_NVRAM
25 select PPC_UDBG_16550 29 select PPC_UDBG_16550
26 select UDBG_RTAS_CONSOLE 30 select UDBG_RTAS_CONSOLE
@@ -28,16 +32,17 @@ config PPC_IBM_CELL_BLADE
28config PPC_CELLEB 32config PPC_CELLEB
29 bool "Toshiba's Cell Reference Set 'Celleb' Architecture" 33 bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
30 depends on PPC_MULTIPLATFORM && PPC64 34 depends on PPC_MULTIPLATFORM && PPC64
31 select PPC_CELL
32 select PPC_CELL_NATIVE 35 select PPC_CELL_NATIVE
33 select PPC_RTAS
34 select PPC_INDIRECT_IO
35 select PPC_OF_PLATFORM_PCI
36 select HAS_TXX9_SERIAL 36 select HAS_TXX9_SERIAL
37 select PPC_UDBG_BEAT 37 select PPC_UDBG_BEAT
38 select USB_OHCI_BIG_ENDIAN_MMIO 38 select USB_OHCI_BIG_ENDIAN_MMIO
39 select USB_EHCI_BIG_ENDIAN_MMIO 39 select USB_EHCI_BIG_ENDIAN_MMIO
40 40
41config PPC_CELL_QPACE
42 bool "IBM Cell - QPACE"
43 depends on PPC_MULTIPLATFORM && PPC64
44 select PPC_CELL_COMMON
45
41menu "Cell Broadband Engine options" 46menu "Cell Broadband Engine options"
42 depends on PPC_CELL 47 depends on PPC_CELL
43 48
@@ -102,7 +107,7 @@ config PPC_IBM_CELL_POWERBUTTON
102config CBE_THERM 107config CBE_THERM
103 tristate "CBE thermal support" 108 tristate "CBE thermal support"
104 default m 109 default m
105 depends on CBE_RAS 110 depends on CBE_RAS && SPU_BASE
106 111
107config CBE_CPUFREQ 112config CBE_CPUFREQ
108 tristate "CBE frequency scaling" 113 tristate "CBE frequency scaling"
@@ -136,5 +141,5 @@ endmenu
136 141
137config OPROFILE_CELL 142config OPROFILE_CELL
138 def_bool y 143 def_bool y
139 depends on PPC_CELL_NATIVE && (OPROFILE = m || OPROFILE = y) 144 depends on PPC_CELL_NATIVE && (OPROFILE = m || OPROFILE = y) && SPU_BASE
140 145
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 7fd830872c43..43eccb270301 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -1,7 +1,7 @@
1obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \ 1obj-$(CONFIG_PPC_CELL_COMMON) += cbe_regs.o interrupt.o pervasive.o
2 cbe_regs.o spider-pic.o \ 2
3 pervasive.o pmu.o io-workarounds.o \ 3obj-$(CONFIG_PPC_CELL_NATIVE) += iommu.o setup.o spider-pic.o \
4 spider-pci.o 4 pmu.o io-workarounds.o spider-pci.o
5obj-$(CONFIG_CBE_RAS) += ras.o 5obj-$(CONFIG_CBE_RAS) += ras.o
6 6
7obj-$(CONFIG_CBE_THERM) += cbe_thermal.o 7obj-$(CONFIG_CBE_THERM) += cbe_thermal.o
@@ -14,13 +14,12 @@ obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o
14 14
15ifeq ($(CONFIG_SMP),y) 15ifeq ($(CONFIG_SMP),y)
16obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o 16obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o
17obj-$(CONFIG_PPC_CELL_QPACE) += smp.o
17endif 18endif
18 19
19# needed only when building loadable spufs.ko 20# needed only when building loadable spufs.ko
20spu-priv1-$(CONFIG_PPC_CELL_NATIVE) += spu_priv1_mmio.o 21spu-priv1-$(CONFIG_PPC_CELL_COMMON) += spu_priv1_mmio.o
21 22spu-manage-$(CONFIG_PPC_CELL_COMMON) += spu_manage.o
22spu-manage-$(CONFIG_PPC_CELLEB) += spu_manage.o
23spu-manage-$(CONFIG_PPC_CELL_NATIVE) += spu_manage.o
24 23
25obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ 24obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \
26 spu_notify.o \ 25 spu_notify.o \
@@ -31,6 +30,8 @@ obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \
31 30
32obj-$(CONFIG_PCI_MSI) += axon_msi.o 31obj-$(CONFIG_PCI_MSI) += axon_msi.o
33 32
33# qpace setup
34obj-$(CONFIG_PPC_CELL_QPACE) += qpace_setup.o
34 35
35# celleb stuff 36# celleb stuff
36ifeq ($(CONFIG_PPC_CELLEB),y) 37ifeq ($(CONFIG_PPC_CELLEB),y)
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 442cf36aa172..0ce45c2b42f8 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -413,6 +413,9 @@ static int axon_msi_probe(struct of_device *device,
413 MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE | 413 MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE |
414 MSIC_CTRL_FIFO_SIZE); 414 MSIC_CTRL_FIFO_SIZE);
415 415
416 msic->read_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG)
417 & MSIC_FIFO_SIZE_MASK;
418
416 device->dev.platform_data = msic; 419 device->dev.platform_data = msic;
417 420
418 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs; 421 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
diff --git a/arch/powerpc/platforms/cell/celleb_setup.c b/arch/powerpc/platforms/cell/celleb_setup.c
index b11cb30decb2..07c234f6b2b6 100644
--- a/arch/powerpc/platforms/cell/celleb_setup.c
+++ b/arch/powerpc/platforms/cell/celleb_setup.c
@@ -45,7 +45,6 @@
45#include <asm/mmu.h> 45#include <asm/mmu.h>
46#include <asm/processor.h> 46#include <asm/processor.h>
47#include <asm/io.h> 47#include <asm/io.h>
48#include <asm/kexec.h>
49#include <asm/prom.h> 48#include <asm/prom.h>
50#include <asm/machdep.h> 49#include <asm/machdep.h>
51#include <asm/cputable.h> 50#include <asm/cputable.h>
@@ -226,9 +225,6 @@ define_machine(celleb_beat) {
226 .pci_setup_phb = celleb_setup_phb, 225 .pci_setup_phb = celleb_setup_phb,
227#ifdef CONFIG_KEXEC 226#ifdef CONFIG_KEXEC
228 .kexec_cpu_down = beat_kexec_cpu_down, 227 .kexec_cpu_down = beat_kexec_cpu_down,
229 .machine_kexec = default_machine_kexec,
230 .machine_kexec_prepare = default_machine_kexec_prepare,
231 .machine_crash_shutdown = default_machine_crash_shutdown,
232#endif 228#endif
233}; 229};
234 230
@@ -248,9 +244,4 @@ define_machine(celleb_native) {
248 .pci_probe_mode = celleb_pci_probe_mode, 244 .pci_probe_mode = celleb_pci_probe_mode,
249 .pci_setup_phb = celleb_setup_phb, 245 .pci_setup_phb = celleb_setup_phb,
250 .init_IRQ = celleb_init_IRQ_native, 246 .init_IRQ = celleb_init_IRQ_native,
251#ifdef CONFIG_KEXEC
252 .machine_kexec = default_machine_kexec,
253 .machine_kexec_prepare = default_machine_kexec_prepare,
254 .machine_crash_shutdown = default_machine_crash_shutdown,
255#endif
256}; 247};
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 3168272ab0d7..86db4dd170a0 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -1053,10 +1053,7 @@ static int __init cell_iommu_fixed_mapping_init(void)
1053 } 1053 }
1054 1054
1055 /* We must have dma-ranges properties for fixed mapping to work */ 1055 /* We must have dma-ranges properties for fixed mapping to work */
1056 for (np = NULL; (np = of_find_all_nodes(np));) { 1056 np = of_find_node_with_property(NULL, "dma-ranges");
1057 if (of_find_property(np, "dma-ranges", NULL))
1058 break;
1059 }
1060 of_node_put(np); 1057 of_node_put(np);
1061 1058
1062 if (!np) { 1059 if (!np) {
diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c
new file mode 100644
index 000000000000..be84e6a16b30
--- /dev/null
+++ b/arch/powerpc/platforms/cell/qpace_setup.c
@@ -0,0 +1,152 @@
1/*
2 * linux/arch/powerpc/platforms/cell/qpace_setup.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Adapted from 'alpha' version by Gary Thomas
6 * Modified by Cort Dougan (cort@cs.nmt.edu)
7 * Modified by PPC64 Team, IBM Corp
8 * Modified by Cell Team, IBM Deutschland Entwicklung GmbH
9 * Modified by Benjamin Krill <ben@codiert.org>, IBM Corp.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16
17#include <linux/sched.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/irq.h>
22#include <linux/console.h>
23#include <linux/of_platform.h>
24
25#include <asm/mmu.h>
26#include <asm/processor.h>
27#include <asm/io.h>
28#include <asm/kexec.h>
29#include <asm/pgtable.h>
30#include <asm/prom.h>
31#include <asm/rtas.h>
32#include <asm/dma.h>
33#include <asm/machdep.h>
34#include <asm/time.h>
35#include <asm/cputable.h>
36#include <asm/irq.h>
37#include <asm/spu.h>
38#include <asm/spu_priv1.h>
39#include <asm/udbg.h>
40#include <asm/cell-regs.h>
41
42#include "interrupt.h"
43#include "pervasive.h"
44#include "ras.h"
45#include "io-workarounds.h"
46
47static void qpace_show_cpuinfo(struct seq_file *m)
48{
49 struct device_node *root;
50 const char *model = "";
51
52 root = of_find_node_by_path("/");
53 if (root)
54 model = of_get_property(root, "model", NULL);
55 seq_printf(m, "machine\t\t: CHRP %s\n", model);
56 of_node_put(root);
57}
58
59static void qpace_progress(char *s, unsigned short hex)
60{
61 printk("*** %04x : %s\n", hex, s ? s : "");
62}
63
64static int __init qpace_publish_devices(void)
65{
66 int node;
67
68 /* Publish OF platform devices for southbridge IOs */
69 of_platform_bus_probe(NULL, NULL, NULL);
70
71 /* There is no device for the MIC memory controller, thus we create
72 * a platform device for it to attach the EDAC driver to.
73 */
74 for_each_online_node(node) {
75 if (cbe_get_cpu_mic_tm_regs(cbe_node_to_cpu(node)) == NULL)
76 continue;
77 platform_device_register_simple("cbe-mic", node, NULL, 0);
78 }
79
80 return 0;
81}
82machine_subsys_initcall(qpace, qpace_publish_devices);
83
84extern int qpace_notify(struct device *dev)
85{
86 /* set dma_ops for of_platform bus */
87 if (dev->bus && dev->bus->name
88 && !strcmp(dev->bus->name, "of_platform"))
89 set_dma_ops(dev, &dma_direct_ops);
90
91 return 0;
92}
93
94static void __init qpace_setup_arch(void)
95{
96#ifdef CONFIG_SPU_BASE
97 spu_priv1_ops = &spu_priv1_mmio_ops;
98 spu_management_ops = &spu_management_of_ops;
99#endif
100
101 cbe_regs_init();
102
103#ifdef CONFIG_CBE_RAS
104 cbe_ras_init();
105#endif
106
107#ifdef CONFIG_SMP
108 smp_init_cell();
109#endif
110
111 /* init to some ~sane value until calibrate_delay() runs */
112 loops_per_jiffy = 50000000;
113
114 cbe_pervasive_init();
115#ifdef CONFIG_DUMMY_CONSOLE
116 conswitchp = &dummy_con;
117#endif
118
119 /* set notifier function */
120 platform_notify = &qpace_notify;
121}
122
123static int __init qpace_probe(void)
124{
125 unsigned long root = of_get_flat_dt_root();
126
127 if (!of_flat_dt_is_compatible(root, "IBM,QPACE"))
128 return 0;
129
130 hpte_init_native();
131
132 return 1;
133}
134
135define_machine(qpace) {
136 .name = "QPACE",
137 .probe = qpace_probe,
138 .setup_arch = qpace_setup_arch,
139 .show_cpuinfo = qpace_show_cpuinfo,
140 .restart = rtas_restart,
141 .power_off = rtas_power_off,
142 .halt = rtas_halt,
143 .get_boot_time = rtas_get_boot_time,
144 .calibrate_decr = generic_calibrate_decr,
145 .progress = qpace_progress,
146 .init_IRQ = iic_init_IRQ,
147#ifdef CONFIG_KEXEC
148 .machine_kexec = default_machine_kexec,
149 .machine_kexec_prepare = default_machine_kexec_prepare,
150 .machine_crash_shutdown = default_machine_crash_shutdown,
151#endif
152};
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index ab721b50fbba..59305369f6b2 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -35,7 +35,6 @@
35#include <asm/mmu.h> 35#include <asm/mmu.h>
36#include <asm/processor.h> 36#include <asm/processor.h>
37#include <asm/io.h> 37#include <asm/io.h>
38#include <asm/kexec.h>
39#include <asm/pgtable.h> 38#include <asm/pgtable.h>
40#include <asm/prom.h> 39#include <asm/prom.h>
41#include <asm/rtas.h> 40#include <asm/rtas.h>
@@ -289,9 +288,4 @@ define_machine(cell) {
289 .progress = cell_progress, 288 .progress = cell_progress,
290 .init_IRQ = cell_init_irq, 289 .init_IRQ = cell_init_irq,
291 .pci_setup_phb = cell_setup_phb, 290 .pci_setup_phb = cell_setup_phb,
292#ifdef CONFIG_KEXEC
293 .machine_kexec = default_machine_kexec,
294 .machine_kexec_prepare = default_machine_kexec_prepare,
295 .machine_crash_shutdown = default_machine_crash_shutdown,
296#endif
297}; 291};
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 1b26071a86ca..7106b63d401b 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -273,12 +273,10 @@ spufs_mem_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
273 return VM_FAULT_NOPAGE; 273 return VM_FAULT_NOPAGE;
274 274
275 if (ctx->state == SPU_STATE_SAVED) { 275 if (ctx->state == SPU_STATE_SAVED) {
276 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 276 vma->vm_page_prot = pgprot_cached(vma->vm_page_prot);
277 & ~_PAGE_NO_CACHE);
278 pfn = vmalloc_to_pfn(ctx->csa.lscsa->ls + offset); 277 pfn = vmalloc_to_pfn(ctx->csa.lscsa->ls + offset);
279 } else { 278 } else {
280 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 279 vma->vm_page_prot = pgprot_noncached_wc(vma->vm_page_prot);
281 | _PAGE_NO_CACHE);
282 pfn = (ctx->spu->local_store_phys + offset) >> PAGE_SHIFT; 280 pfn = (ctx->spu->local_store_phys + offset) >> PAGE_SHIFT;
283 } 281 }
284 vm_insert_pfn(vma, address, pfn); 282 vm_insert_pfn(vma, address, pfn);
@@ -338,8 +336,7 @@ static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)
338 return -EINVAL; 336 return -EINVAL;
339 337
340 vma->vm_flags |= VM_IO | VM_PFNMAP; 338 vma->vm_flags |= VM_IO | VM_PFNMAP;
341 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 339 vma->vm_page_prot = pgprot_noncached_wc(vma->vm_page_prot);
342 | _PAGE_NO_CACHE);
343 340
344 vma->vm_ops = &spufs_mem_mmap_vmops; 341 vma->vm_ops = &spufs_mem_mmap_vmops;
345 return 0; 342 return 0;
@@ -452,8 +449,7 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
452 return -EINVAL; 449 return -EINVAL;
453 450
454 vma->vm_flags |= VM_IO | VM_PFNMAP; 451 vma->vm_flags |= VM_IO | VM_PFNMAP;
455 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 452 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
456 | _PAGE_NO_CACHE | _PAGE_GUARDED);
457 453
458 vma->vm_ops = &spufs_cntl_mmap_vmops; 454 vma->vm_ops = &spufs_cntl_mmap_vmops;
459 return 0; 455 return 0;
@@ -1155,8 +1151,7 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma)
1155 return -EINVAL; 1151 return -EINVAL;
1156 1152
1157 vma->vm_flags |= VM_IO | VM_PFNMAP; 1153 vma->vm_flags |= VM_IO | VM_PFNMAP;
1158 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 1154 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1159 | _PAGE_NO_CACHE | _PAGE_GUARDED);
1160 1155
1161 vma->vm_ops = &spufs_signal1_mmap_vmops; 1156 vma->vm_ops = &spufs_signal1_mmap_vmops;
1162 return 0; 1157 return 0;
@@ -1292,8 +1287,7 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma)
1292 return -EINVAL; 1287 return -EINVAL;
1293 1288
1294 vma->vm_flags |= VM_IO | VM_PFNMAP; 1289 vma->vm_flags |= VM_IO | VM_PFNMAP;
1295 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 1290 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1296 | _PAGE_NO_CACHE | _PAGE_GUARDED);
1297 1291
1298 vma->vm_ops = &spufs_signal2_mmap_vmops; 1292 vma->vm_ops = &spufs_signal2_mmap_vmops;
1299 return 0; 1293 return 0;
@@ -1414,8 +1408,7 @@ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma)
1414 return -EINVAL; 1408 return -EINVAL;
1415 1409
1416 vma->vm_flags |= VM_IO | VM_PFNMAP; 1410 vma->vm_flags |= VM_IO | VM_PFNMAP;
1417 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 1411 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1418 | _PAGE_NO_CACHE | _PAGE_GUARDED);
1419 1412
1420 vma->vm_ops = &spufs_mss_mmap_vmops; 1413 vma->vm_ops = &spufs_mss_mmap_vmops;
1421 return 0; 1414 return 0;
@@ -1476,8 +1469,7 @@ static int spufs_psmap_mmap(struct file *file, struct vm_area_struct *vma)
1476 return -EINVAL; 1469 return -EINVAL;
1477 1470
1478 vma->vm_flags |= VM_IO | VM_PFNMAP; 1471 vma->vm_flags |= VM_IO | VM_PFNMAP;
1479 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 1472 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1480 | _PAGE_NO_CACHE | _PAGE_GUARDED);
1481 1473
1482 vma->vm_ops = &spufs_psmap_mmap_vmops; 1474 vma->vm_ops = &spufs_psmap_mmap_vmops;
1483 return 0; 1475 return 0;
@@ -1536,8 +1528,7 @@ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma)
1536 return -EINVAL; 1528 return -EINVAL;
1537 1529
1538 vma->vm_flags |= VM_IO | VM_PFNMAP; 1530 vma->vm_flags |= VM_IO | VM_PFNMAP;
1539 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 1531 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1540 | _PAGE_NO_CACHE | _PAGE_GUARDED);
1541 1532
1542 vma->vm_ops = &spufs_mfc_mmap_vmops; 1533 vma->vm_ops = &spufs_mfc_mmap_vmops;
1543 return 0; 1534 return 0;
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index cb85d237e492..6296bfd9cb0b 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -95,8 +95,8 @@ spufs_new_inode(struct super_block *sb, int mode)
95 goto out; 95 goto out;
96 96
97 inode->i_mode = mode; 97 inode->i_mode = mode;
98 inode->i_uid = current->fsuid; 98 inode->i_uid = current_fsuid();
99 inode->i_gid = current->fsgid; 99 inode->i_gid = current_fsgid();
100 inode->i_blocks = 0; 100 inode->i_blocks = 0;
101 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 101 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
102out: 102out:
@@ -323,7 +323,7 @@ static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt)
323 goto out; 323 goto out;
324 } 324 }
325 325
326 filp = dentry_open(dentry, mnt, O_RDONLY); 326 filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
327 if (IS_ERR(filp)) { 327 if (IS_ERR(filp)) {
328 put_unused_fd(ret); 328 put_unused_fd(ret);
329 ret = PTR_ERR(filp); 329 ret = PTR_ERR(filp);
@@ -562,7 +562,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt)
562 goto out; 562 goto out;
563 } 563 }
564 564
565 filp = dentry_open(dentry, mnt, O_RDONLY); 565 filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
566 if (IS_ERR(filp)) { 566 if (IS_ERR(filp)) {
567 put_unused_fd(ret); 567 put_unused_fd(ret);
568 ret = PTR_ERR(filp); 568 ret = PTR_ERR(filp);
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index d3cde6b9d2df..f6b0c519d5a2 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -141,6 +141,7 @@ hydra_init(void)
141 of_node_put(np); 141 of_node_put(np);
142 return 0; 142 return 0;
143 } 143 }
144 of_node_put(np);
144 Hydra = ioremap(r.start, r.end-r.start); 145 Hydra = ioremap(r.start, r.end-r.start);
145 printk("Hydra Mac I/O at %llx\n", (unsigned long long)r.start); 146 printk("Hydra Mac I/O at %llx\n", (unsigned long long)r.start);
146 printk("Hydra Feature_Control was %x", 147 printk("Hydra Feature_Control was %x",
@@ -198,7 +199,7 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d
198 printk ("RTAS supporting Pegasos OF not found, please upgrade" 199 printk ("RTAS supporting Pegasos OF not found, please upgrade"
199 " your firmware\n"); 200 " your firmware\n");
200 } 201 }
201 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 202 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
202 /* keep the reference to the root node */ 203 /* keep the reference to the root node */
203} 204}
204 205
diff --git a/arch/powerpc/platforms/embedded6xx/c2k.c b/arch/powerpc/platforms/embedded6xx/c2k.c
index 32ba0fa0ad03..8cab5731850f 100644
--- a/arch/powerpc/platforms/embedded6xx/c2k.c
+++ b/arch/powerpc/platforms/embedded6xx/c2k.c
@@ -20,7 +20,6 @@
20#include <linux/seq_file.h> 20#include <linux/seq_file.h>
21#include <linux/time.h> 21#include <linux/time.h>
22#include <linux/of.h> 22#include <linux/of.h>
23#include <linux/kexec.h>
24 23
25#include <asm/machdep.h> 24#include <asm/machdep.h>
26#include <asm/prom.h> 25#include <asm/prom.h>
@@ -147,9 +146,4 @@ define_machine(c2k) {
147 .get_irq = mv64x60_get_irq, 146 .get_irq = mv64x60_get_irq,
148 .restart = c2k_restart, 147 .restart = c2k_restart,
149 .calibrate_decr = generic_calibrate_decr, 148 .calibrate_decr = generic_calibrate_decr,
150#ifdef CONFIG_KEXEC
151 .machine_kexec = default_machine_kexec,
152 .machine_kexec_prepare = default_machine_kexec_prepare,
153 .machine_crash_shutdown = default_machine_crash_shutdown,
154#endif
155}; 149};
diff --git a/arch/powerpc/platforms/embedded6xx/prpmc2800.c b/arch/powerpc/platforms/embedded6xx/prpmc2800.c
index 4c485e984236..670035f49a69 100644
--- a/arch/powerpc/platforms/embedded6xx/prpmc2800.c
+++ b/arch/powerpc/platforms/embedded6xx/prpmc2800.c
@@ -19,7 +19,6 @@
19#include <asm/prom.h> 19#include <asm/prom.h>
20#include <asm/system.h> 20#include <asm/system.h>
21#include <asm/time.h> 21#include <asm/time.h>
22#include <asm/kexec.h>
23 22
24#include <mm/mmu_decl.h> 23#include <mm/mmu_decl.h>
25 24
@@ -155,9 +154,4 @@ define_machine(prpmc2800){
155 .get_irq = mv64x60_get_irq, 154 .get_irq = mv64x60_get_irq,
156 .restart = prpmc2800_restart, 155 .restart = prpmc2800_restart,
157 .calibrate_decr = generic_calibrate_decr, 156 .calibrate_decr = generic_calibrate_decr,
158#ifdef CONFIG_KEXEC
159 .machine_kexec = default_machine_kexec,
160 .machine_kexec_prepare = default_machine_kexec_prepare,
161 .machine_crash_shutdown = default_machine_crash_shutdown,
162#endif
163}; 157};
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
index 45ffd8e542f4..ed3753d8c109 100644
--- a/arch/powerpc/platforms/iseries/Kconfig
+++ b/arch/powerpc/platforms/iseries/Kconfig
@@ -9,6 +9,7 @@ menu "iSeries device drivers"
9 9
10config VIODASD 10config VIODASD
11 tristate "iSeries Virtual I/O disk support" 11 tristate "iSeries Virtual I/O disk support"
12 depends on BLOCK
12 help 13 help
13 If you are running on an iSeries system and you want to use 14 If you are running on an iSeries system and you want to use
14 virtual disks created and managed by OS/400, say Y. 15 virtual disks created and managed by OS/400, say Y.
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index d4c61c3c9669..bfd60e4accee 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -50,7 +50,6 @@
50#include <asm/system.h> 50#include <asm/system.h>
51#include <asm/pgtable.h> 51#include <asm/pgtable.h>
52#include <asm/io.h> 52#include <asm/io.h>
53#include <asm/kexec.h>
54#include <asm/pci-bridge.h> 53#include <asm/pci-bridge.h>
55#include <asm/iommu.h> 54#include <asm/iommu.h>
56#include <asm/machdep.h> 55#include <asm/machdep.h>
@@ -335,9 +334,4 @@ define_machine(maple) {
335 .calibrate_decr = generic_calibrate_decr, 334 .calibrate_decr = generic_calibrate_decr,
336 .progress = maple_progress, 335 .progress = maple_progress,
337 .power_save = power4_idle, 336 .power_save = power4_idle,
338#ifdef CONFIG_KEXEC
339 .machine_kexec = default_machine_kexec,
340 .machine_kexec_prepare = default_machine_kexec_prepare,
341 .machine_crash_shutdown = default_machine_crash_shutdown,
342#endif
343}; 337};
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 792d3ce8112e..65c585b8b00d 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -310,7 +310,7 @@ static int pmu_set_cpu_speed(int low_speed)
310 _set_L3CR(save_l3cr); 310 _set_L3CR(save_l3cr);
311 311
312 /* Restore userland MMU context */ 312 /* Restore userland MMU context */
313 set_context(current->active_mm->context.id, current->active_mm->pgd); 313 switch_mmu_context(NULL, current->active_mm);
314 314
315#ifdef DEBUG_FREQ 315#ifdef DEBUG_FREQ
316 printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); 316 printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index bcf50d7056e9..54b7b76ed4f0 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -729,7 +729,7 @@ static void __init setup_bandit(struct pci_controller *hose,
729static int __init setup_uninorth(struct pci_controller *hose, 729static int __init setup_uninorth(struct pci_controller *hose,
730 struct resource *addr) 730 struct resource *addr)
731{ 731{
732 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; 732 ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
733 has_uninorth = 1; 733 has_uninorth = 1;
734 hose->ops = &macrisc_pci_ops; 734 hose->ops = &macrisc_pci_ops;
735 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); 735 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
@@ -996,7 +996,7 @@ void __init pmac_pci_init(void)
996 struct device_node *np, *root; 996 struct device_node *np, *root;
997 struct device_node *ht = NULL; 997 struct device_node *ht = NULL;
998 998
999 ppc_pci_flags = PPC_PCI_CAN_SKIP_ISA_ALIGN; 999 ppc_pci_set_flags(PPC_PCI_CAN_SKIP_ISA_ALIGN);
1000 1000
1001 root = of_find_node_by_path("/"); 1001 root = of_find_node_by_path("/");
1002 if (root == NULL) { 1002 if (root == NULL) {
@@ -1055,7 +1055,7 @@ void __init pmac_pci_init(void)
1055 * some offset between bus number and domains for now when we 1055 * some offset between bus number and domains for now when we
1056 * assign all busses should help for now 1056 * assign all busses should help for now
1057 */ 1057 */
1058 if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS) 1058 if (ppc_pci_has_flag(PPC_PCI_REASSIGN_ALL_BUS))
1059 pcibios_assign_bus_offset = 0x10; 1059 pcibios_assign_bus_offset = 0x10;
1060#endif 1060#endif
1061} 1061}
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 82c14d203d8b..9b78f5300c24 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -60,7 +60,6 @@
60#include <asm/system.h> 60#include <asm/system.h>
61#include <asm/pgtable.h> 61#include <asm/pgtable.h>
62#include <asm/io.h> 62#include <asm/io.h>
63#include <asm/kexec.h>
64#include <asm/pci-bridge.h> 63#include <asm/pci-bridge.h>
65#include <asm/ohare.h> 64#include <asm/ohare.h>
66#include <asm/mediabay.h> 65#include <asm/mediabay.h>
@@ -310,9 +309,7 @@ static void __init pmac_setup_arch(void)
310 } 309 }
311 310
312 /* See if newworld or oldworld */ 311 /* See if newworld or oldworld */
313 for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; ) 312 ic = of_find_node_with_property(NULL, "interrupt-controller");
314 if (of_get_property(ic, "interrupt-controller", NULL))
315 break;
316 if (ic) { 313 if (ic) {
317 pmac_newworld = 1; 314 pmac_newworld = 1;
318 of_node_put(ic); 315 of_node_put(ic);
@@ -740,11 +737,6 @@ define_machine(powermac) {
740 .pci_probe_mode = pmac_pci_probe_mode, 737 .pci_probe_mode = pmac_pci_probe_mode,
741 .power_save = power4_idle, 738 .power_save = power4_idle,
742 .enable_pmcs = power4_enable_pmcs, 739 .enable_pmcs = power4_enable_pmcs,
743#ifdef CONFIG_KEXEC
744 .machine_kexec = default_machine_kexec,
745 .machine_kexec_prepare = default_machine_kexec_prepare,
746 .machine_crash_shutdown = default_machine_crash_shutdown,
747#endif
748#endif /* CONFIG_PPC64 */ 740#endif /* CONFIG_PPC64 */
749#ifdef CONFIG_PPC32 741#ifdef CONFIG_PPC32
750 .pcibios_enable_device_hook = pmac_pci_enable_device_hook, 742 .pcibios_enable_device_hook = pmac_pci_enable_device_hook,
diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S
index adee28da353f..1c2802fabd57 100644
--- a/arch/powerpc/platforms/powermac/sleep.S
+++ b/arch/powerpc/platforms/powermac/sleep.S
@@ -17,6 +17,7 @@
17#include <asm/cache.h> 17#include <asm/cache.h>
18#include <asm/thread_info.h> 18#include <asm/thread_info.h>
19#include <asm/asm-offsets.h> 19#include <asm/asm-offsets.h>
20#include <asm/mmu.h>
20 21
21#define MAGIC 0x4c617273 /* 'Lars' */ 22#define MAGIC 0x4c617273 /* 'Lars' */
22 23
@@ -323,7 +324,7 @@ grackle_wake_up:
323 lwz r4,SL_IBAT3+4(r1) 324 lwz r4,SL_IBAT3+4(r1)
324 mtibatl 3,r4 325 mtibatl 3,r4
325 326
326BEGIN_FTR_SECTION 327BEGIN_MMU_FTR_SECTION
327 li r4,0 328 li r4,0
328 mtspr SPRN_DBAT4U,r4 329 mtspr SPRN_DBAT4U,r4
329 mtspr SPRN_DBAT4L,r4 330 mtspr SPRN_DBAT4L,r4
@@ -341,7 +342,7 @@ BEGIN_FTR_SECTION
341 mtspr SPRN_IBAT6L,r4 342 mtspr SPRN_IBAT6L,r4
342 mtspr SPRN_IBAT7U,r4 343 mtspr SPRN_IBAT7U,r4
343 mtspr SPRN_IBAT7L,r4 344 mtspr SPRN_IBAT7L,r4
344END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) 345END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
345 346
346 /* Flush all TLBs */ 347 /* Flush all TLBs */
347 lis r4,0x1000 348 lis r4,0x1000
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 40f72c2a4699..6b0711c15eca 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -739,7 +739,7 @@ static void __init smp_core99_setup(int ncpus)
739 739
740 /* XXX should get this from reg properties */ 740 /* XXX should get this from reg properties */
741 for (i = 1; i < ncpus; ++i) 741 for (i = 1; i < ncpus; ++i)
742 smp_hw_index[i] = i; 742 set_hard_smp_processor_id(i, i);
743 } 743 }
744#endif 744#endif
745 745
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index ffdd8e963fbd..dbc124e05646 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -314,11 +314,17 @@ static int __init ps3_setup_vuart_device(enum ps3_match_id match_id,
314 314
315 result = ps3_system_bus_device_register(&p->dev); 315 result = ps3_system_bus_device_register(&p->dev);
316 316
317 if (result) 317 if (result) {
318 pr_debug("%s:%d ps3_system_bus_device_register failed\n", 318 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
319 __func__, __LINE__); 319 __func__, __LINE__);
320 320 goto fail_device_register;
321 }
321 pr_debug(" <- %s:%d\n", __func__, __LINE__); 322 pr_debug(" <- %s:%d\n", __func__, __LINE__);
323 return 0;
324
325fail_device_register:
326 kfree(p);
327 pr_debug(" <- %s:%d fail\n", __func__, __LINE__);
322 return result; 328 return result;
323} 329}
324 330
@@ -463,11 +469,17 @@ static int __init ps3_register_sound_devices(void)
463 469
464 result = ps3_system_bus_device_register(&p->dev); 470 result = ps3_system_bus_device_register(&p->dev);
465 471
466 if (result) 472 if (result) {
467 pr_debug("%s:%d ps3_system_bus_device_register failed\n", 473 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
468 __func__, __LINE__); 474 __func__, __LINE__);
469 475 goto fail_device_register;
476 }
470 pr_debug(" <- %s:%d\n", __func__, __LINE__); 477 pr_debug(" <- %s:%d\n", __func__, __LINE__);
478 return 0;
479
480fail_device_register:
481 kfree(p);
482 pr_debug(" <- %s:%d failed\n", __func__, __LINE__);
471 return result; 483 return result;
472} 484}
473 485
@@ -485,17 +497,24 @@ static int __init ps3_register_graphics_devices(void)
485 if (!p) 497 if (!p)
486 return -ENOMEM; 498 return -ENOMEM;
487 499
488 p->dev.match_id = PS3_MATCH_ID_GRAPHICS; 500 p->dev.match_id = PS3_MATCH_ID_GPU;
489 p->dev.match_sub_id = PS3_MATCH_SUB_ID_FB; 501 p->dev.match_sub_id = PS3_MATCH_SUB_ID_GPU_FB;
490 p->dev.dev_type = PS3_DEVICE_TYPE_IOC0; 502 p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
491 503
492 result = ps3_system_bus_device_register(&p->dev); 504 result = ps3_system_bus_device_register(&p->dev);
493 505
494 if (result) 506 if (result) {
495 pr_debug("%s:%d ps3_system_bus_device_register failed\n", 507 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
496 __func__, __LINE__); 508 __func__, __LINE__);
509 goto fail_device_register;
510 }
497 511
498 pr_debug(" <- %s:%d\n", __func__, __LINE__); 512 pr_debug(" <- %s:%d\n", __func__, __LINE__);
513 return 0;
514
515fail_device_register:
516 kfree(p);
517 pr_debug(" <- %s:%d failed\n", __func__, __LINE__);
499 return result; 518 return result;
500} 519}
501 520
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 3a58ffabccd9..a4d49dd9e8a9 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -649,7 +649,7 @@ static int dma_sb_region_create(struct ps3_dma_region *r)
649{ 649{
650 int result; 650 int result;
651 651
652 pr_info(" -> %s:%d:\n", __func__, __LINE__); 652 DBG(" -> %s:%d:\n", __func__, __LINE__);
653 653
654 BUG_ON(!r); 654 BUG_ON(!r);
655 655
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 77bc330263c4..35f3e85cf60e 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -23,7 +23,6 @@
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/root_dev.h> 24#include <linux/root_dev.h>
25#include <linux/console.h> 25#include <linux/console.h>
26#include <linux/kexec.h>
27#include <linux/bootmem.h> 26#include <linux/bootmem.h>
28 27
29#include <asm/machdep.h> 28#include <asm/machdep.h>
@@ -42,6 +41,10 @@
42#define DBG pr_debug 41#define DBG pr_debug
43#endif 42#endif
44 43
44/* mutex synchronizing GPU accesses and video mode changes */
45DEFINE_MUTEX(ps3_gpu_mutex);
46EXPORT_SYMBOL_GPL(ps3_gpu_mutex);
47
45#if !defined(CONFIG_SMP) 48#if !defined(CONFIG_SMP)
46static void smp_send_stop(void) {} 49static void smp_send_stop(void) {}
47#endif 50#endif
@@ -277,8 +280,5 @@ define_machine(ps3) {
277 .halt = ps3_halt, 280 .halt = ps3_halt,
278#if defined(CONFIG_KEXEC) 281#if defined(CONFIG_KEXEC)
279 .kexec_cpu_down = ps3_kexec_cpu_down, 282 .kexec_cpu_down = ps3_kexec_cpu_down,
280 .machine_kexec = default_machine_kexec,
281 .machine_kexec_prepare = default_machine_kexec_prepare,
282 .machine_crash_shutdown = default_machine_crash_shutdown,
283#endif 283#endif
284}; 284};
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 661e9f77ebf6..ee0d22911621 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -31,7 +31,7 @@
31#include "platform.h" 31#include "platform.h"
32 32
33static struct device ps3_system_bus = { 33static struct device ps3_system_bus = {
34 .bus_id = "ps3_system", 34 .init_name = "ps3_system",
35}; 35};
36 36
37/* FIXME: need device usage counters! */ 37/* FIXME: need device usage counters! */
@@ -175,7 +175,7 @@ int ps3_open_hv_device(struct ps3_system_bus_device *dev)
175 return ps3_open_hv_device_sb(dev); 175 return ps3_open_hv_device_sb(dev);
176 176
177 case PS3_MATCH_ID_SOUND: 177 case PS3_MATCH_ID_SOUND:
178 case PS3_MATCH_ID_GRAPHICS: 178 case PS3_MATCH_ID_GPU:
179 return ps3_open_hv_device_gpu(dev); 179 return ps3_open_hv_device_gpu(dev);
180 180
181 case PS3_MATCH_ID_AV_SETTINGS: 181 case PS3_MATCH_ID_AV_SETTINGS:
@@ -213,7 +213,7 @@ int ps3_close_hv_device(struct ps3_system_bus_device *dev)
213 return ps3_close_hv_device_sb(dev); 213 return ps3_close_hv_device_sb(dev);
214 214
215 case PS3_MATCH_ID_SOUND: 215 case PS3_MATCH_ID_SOUND:
216 case PS3_MATCH_ID_GRAPHICS: 216 case PS3_MATCH_ID_GPU:
217 return ps3_close_hv_device_gpu(dev); 217 return ps3_close_hv_device_gpu(dev);
218 218
219 case PS3_MATCH_ID_AV_SETTINGS: 219 case PS3_MATCH_ID_AV_SETTINGS:
@@ -356,12 +356,12 @@ static int ps3_system_bus_match(struct device *_dev,
356 if (result) 356 if (result)
357 pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n", 357 pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n",
358 __func__, __LINE__, 358 __func__, __LINE__,
359 dev->match_id, dev->match_sub_id, dev->core.bus_id, 359 dev->match_id, dev->match_sub_id, dev_name(&dev->core),
360 drv->match_id, drv->match_sub_id, drv->core.name); 360 drv->match_id, drv->match_sub_id, drv->core.name);
361 else 361 else
362 pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n", 362 pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n",
363 __func__, __LINE__, 363 __func__, __LINE__,
364 dev->match_id, dev->match_sub_id, dev->core.bus_id, 364 dev->match_id, dev->match_sub_id, dev_name(&dev->core),
365 drv->match_id, drv->match_sub_id, drv->core.name); 365 drv->match_id, drv->match_sub_id, drv->core.name);
366 366
367 return result; 367 return result;
@@ -383,9 +383,9 @@ static int ps3_system_bus_probe(struct device *_dev)
383 result = drv->probe(dev); 383 result = drv->probe(dev);
384 else 384 else
385 pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__, 385 pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__,
386 dev->core.bus_id); 386 dev_name(&dev->core));
387 387
388 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); 388 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
389 return result; 389 return result;
390} 390}
391 391
@@ -407,7 +407,7 @@ static int ps3_system_bus_remove(struct device *_dev)
407 dev_dbg(&dev->core, "%s:%d %s: no remove method\n", 407 dev_dbg(&dev->core, "%s:%d %s: no remove method\n",
408 __func__, __LINE__, drv->core.name); 408 __func__, __LINE__, drv->core.name);
409 409
410 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); 410 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
411 return result; 411 return result;
412} 412}
413 413
@@ -432,7 +432,7 @@ static void ps3_system_bus_shutdown(struct device *_dev)
432 BUG_ON(!drv); 432 BUG_ON(!drv);
433 433
434 dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__, 434 dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__,
435 dev->core.bus_id, drv->core.name); 435 dev_name(&dev->core), drv->core.name);
436 436
437 if (drv->shutdown) 437 if (drv->shutdown)
438 drv->shutdown(dev); 438 drv->shutdown(dev);
@@ -453,7 +453,8 @@ static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *en
453{ 453{
454 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 454 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
455 455
456 if (add_uevent_var(env, "MODALIAS=ps3:%d", dev->match_id)) 456 if (add_uevent_var(env, "MODALIAS=ps3:%d:%d", dev->match_id,
457 dev->match_sub_id))
457 return -ENOMEM; 458 return -ENOMEM;
458 return 0; 459 return 0;
459} 460}
@@ -462,7 +463,8 @@ static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
462 char *buf) 463 char *buf)
463{ 464{
464 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 465 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
465 int len = snprintf(buf, PAGE_SIZE, "ps3:%d\n", dev->match_id); 466 int len = snprintf(buf, PAGE_SIZE, "ps3:%d:%d\n", dev->match_id,
467 dev->match_sub_id);
466 468
467 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; 469 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
468} 470}
@@ -742,22 +744,18 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
742 switch (dev->dev_type) { 744 switch (dev->dev_type) {
743 case PS3_DEVICE_TYPE_IOC0: 745 case PS3_DEVICE_TYPE_IOC0:
744 dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops; 746 dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops;
745 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), 747 dev_set_name(&dev->core, "ioc0_%02x", ++dev_ioc0_count);
746 "ioc0_%02x", ++dev_ioc0_count);
747 break; 748 break;
748 case PS3_DEVICE_TYPE_SB: 749 case PS3_DEVICE_TYPE_SB:
749 dev->core.archdata.dma_ops = &ps3_sb_dma_ops; 750 dev->core.archdata.dma_ops = &ps3_sb_dma_ops;
750 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), 751 dev_set_name(&dev->core, "sb_%02x", ++dev_sb_count);
751 "sb_%02x", ++dev_sb_count);
752 752
753 break; 753 break;
754 case PS3_DEVICE_TYPE_VUART: 754 case PS3_DEVICE_TYPE_VUART:
755 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), 755 dev_set_name(&dev->core, "vuart_%02x", ++dev_vuart_count);
756 "vuart_%02x", ++dev_vuart_count);
757 break; 756 break;
758 case PS3_DEVICE_TYPE_LPM: 757 case PS3_DEVICE_TYPE_LPM:
759 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), 758 dev_set_name(&dev->core, "lpm_%02x", ++dev_lpm_count);
760 "lpm_%02x", ++dev_lpm_count);
761 break; 759 break;
762 default: 760 default:
763 BUG(); 761 BUG();
@@ -766,7 +764,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
766 dev->core.archdata.of_node = NULL; 764 dev->core.archdata.of_node = NULL;
767 set_dev_node(&dev->core, 0); 765 set_dev_node(&dev->core, 0);
768 766
769 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id); 767 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core));
770 768
771 result = device_register(&dev->core); 769 result = device_register(&dev->core);
772 return result; 770 return result;
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 97619fd51e39..ddc2a307cd50 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -54,7 +54,7 @@ config PPC_SMLPAR
54 54
55config CMM 55config CMM
56 tristate "Collaborative memory management" 56 tristate "Collaborative memory management"
57 depends on PPC_SMLPAR 57 depends on PPC_SMLPAR && !CRASH_DUMP
58 default y 58 default y
59 help 59 help
60 Select this option, if you want to enable the kernel interface 60 Select this option, if you want to enable the kernel interface
diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c
index 5cd4d2761620..6567439fe78d 100644
--- a/arch/powerpc/platforms/pseries/cmm.c
+++ b/arch/powerpc/platforms/pseries/cmm.c
@@ -28,6 +28,7 @@
28#include <linux/kthread.h> 28#include <linux/kthread.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/oom.h> 30#include <linux/oom.h>
31#include <linux/reboot.h>
31#include <linux/sched.h> 32#include <linux/sched.h>
32#include <linux/stringify.h> 33#include <linux/stringify.h>
33#include <linux/swap.h> 34#include <linux/swap.h>
@@ -384,6 +385,26 @@ static void cmm_unregister_sysfs(struct sys_device *sysdev)
384} 385}
385 386
386/** 387/**
388 * cmm_reboot_notifier - Make sure pages are not still marked as "loaned"
389 *
390 **/
391static int cmm_reboot_notifier(struct notifier_block *nb,
392 unsigned long action, void *unused)
393{
394 if (action == SYS_RESTART) {
395 if (cmm_thread_ptr)
396 kthread_stop(cmm_thread_ptr);
397 cmm_thread_ptr = NULL;
398 cmm_free_pages(loaned_pages);
399 }
400 return NOTIFY_DONE;
401}
402
403static struct notifier_block cmm_reboot_nb = {
404 .notifier_call = cmm_reboot_notifier,
405};
406
407/**
387 * cmm_init - Module initialization 408 * cmm_init - Module initialization
388 * 409 *
389 * Return value: 410 * Return value:
@@ -399,9 +420,12 @@ static int cmm_init(void)
399 if ((rc = register_oom_notifier(&cmm_oom_nb)) < 0) 420 if ((rc = register_oom_notifier(&cmm_oom_nb)) < 0)
400 return rc; 421 return rc;
401 422
402 if ((rc = cmm_sysfs_register(&cmm_sysdev))) 423 if ((rc = register_reboot_notifier(&cmm_reboot_nb)))
403 goto out_oom_notifier; 424 goto out_oom_notifier;
404 425
426 if ((rc = cmm_sysfs_register(&cmm_sysdev)))
427 goto out_reboot_notifier;
428
405 if (cmm_disabled) 429 if (cmm_disabled)
406 return rc; 430 return rc;
407 431
@@ -415,6 +439,8 @@ static int cmm_init(void)
415 439
416out_unregister_sysfs: 440out_unregister_sysfs:
417 cmm_unregister_sysfs(&cmm_sysdev); 441 cmm_unregister_sysfs(&cmm_sysdev);
442out_reboot_notifier:
443 unregister_reboot_notifier(&cmm_reboot_nb);
418out_oom_notifier: 444out_oom_notifier:
419 unregister_oom_notifier(&cmm_oom_nb); 445 unregister_oom_notifier(&cmm_oom_nb);
420 return rc; 446 return rc;
@@ -431,6 +457,7 @@ static void cmm_exit(void)
431 if (cmm_thread_ptr) 457 if (cmm_thread_ptr)
432 kthread_stop(cmm_thread_ptr); 458 kthread_stop(cmm_thread_ptr);
433 unregister_oom_notifier(&cmm_oom_nb); 459 unregister_oom_notifier(&cmm_oom_nb);
460 unregister_reboot_notifier(&cmm_reboot_nb);
434 cmm_free_pages(loaned_pages); 461 cmm_free_pages(loaned_pages);
435 cmm_unregister_sysfs(&cmm_sysdev); 462 cmm_unregister_sysfs(&cmm_sysdev);
436} 463}
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 54816d75b578..989d6462c154 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -21,6 +21,8 @@
21 * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com> 21 * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
22 */ 22 */
23 23
24#undef DEBUG
25
24#include <linux/delay.h> 26#include <linux/delay.h>
25#include <linux/init.h> 27#include <linux/init.h>
26#include <linux/list.h> 28#include <linux/list.h>
@@ -488,10 +490,8 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
488 if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || 490 if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
489 pdn->eeh_mode & EEH_MODE_NOCHECK) { 491 pdn->eeh_mode & EEH_MODE_NOCHECK) {
490 ignored_check++; 492 ignored_check++;
491#ifdef DEBUG 493 pr_debug("EEH: Ignored check (%x) for %s %s\n",
492 printk ("EEH:ignored check (%x) for %s %s\n", 494 pdn->eeh_mode, pci_name (dev), dn->full_name);
493 pdn->eeh_mode, pci_name (dev), dn->full_name);
494#endif
495 return 0; 495 return 0;
496 } 496 }
497 497
@@ -1014,10 +1014,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
1014 eeh_subsystem_enabled = 1; 1014 eeh_subsystem_enabled = 1;
1015 pdn->eeh_mode |= EEH_MODE_SUPPORTED; 1015 pdn->eeh_mode |= EEH_MODE_SUPPORTED;
1016 1016
1017#ifdef DEBUG 1017 pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n",
1018 printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n", 1018 dn->full_name, pdn->eeh_config_addr,
1019 dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr); 1019 pdn->eeh_pe_config_addr);
1020#endif
1021 } else { 1020 } else {
1022 1021
1023 /* This device doesn't support EEH, but it may have an 1022 /* This device doesn't support EEH, but it may have an
@@ -1161,13 +1160,17 @@ static void eeh_add_device_late(struct pci_dev *dev)
1161 if (!dev || !eeh_subsystem_enabled) 1160 if (!dev || !eeh_subsystem_enabled)
1162 return; 1161 return;
1163 1162
1164#ifdef DEBUG 1163 pr_debug("EEH: Adding device %s\n", pci_name(dev));
1165 printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
1166#endif
1167 1164
1168 pci_dev_get (dev);
1169 dn = pci_device_to_OF_node(dev); 1165 dn = pci_device_to_OF_node(dev);
1170 pdn = PCI_DN(dn); 1166 pdn = PCI_DN(dn);
1167 if (pdn->pcidev == dev) {
1168 pr_debug("EEH: Already referenced !\n");
1169 return;
1170 }
1171 WARN_ON(pdn->pcidev);
1172
1173 pci_dev_get (dev);
1171 pdn->pcidev = dev; 1174 pdn->pcidev = dev;
1172 1175
1173 pci_addr_cache_insert_device(dev); 1176 pci_addr_cache_insert_device(dev);
@@ -1206,17 +1209,18 @@ static void eeh_remove_device(struct pci_dev *dev)
1206 return; 1209 return;
1207 1210
1208 /* Unregister the device with the EEH/PCI address search system */ 1211 /* Unregister the device with the EEH/PCI address search system */
1209#ifdef DEBUG 1212 pr_debug("EEH: Removing device %s\n", pci_name(dev));
1210 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
1211#endif
1212 pci_addr_cache_remove_device(dev);
1213 eeh_sysfs_remove_device(dev);
1214 1213
1215 dn = pci_device_to_OF_node(dev); 1214 dn = pci_device_to_OF_node(dev);
1216 if (PCI_DN(dn)->pcidev) { 1215 if (PCI_DN(dn)->pcidev == NULL) {
1217 PCI_DN(dn)->pcidev = NULL; 1216 pr_debug("EEH: Not referenced !\n");
1218 pci_dev_put (dev); 1217 return;
1219 } 1218 }
1219 PCI_DN(dn)->pcidev = NULL;
1220 pci_dev_put (dev);
1221
1222 pci_addr_cache_remove_device(dev);
1223 eeh_sysfs_remove_device(dev);
1220} 1224}
1221 1225
1222void eeh_remove_bus_device(struct pci_dev *dev) 1226void eeh_remove_bus_device(struct pci_dev *dev)
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 1f032483c026..a20ead87153d 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -116,7 +116,7 @@ static void pseries_cpu_die(unsigned int cpu)
116 cpu_status = query_cpu_stopped(pcpu); 116 cpu_status = query_cpu_stopped(pcpu);
117 if (cpu_status == 0 || cpu_status == -1) 117 if (cpu_status == 0 || cpu_status == -1)
118 break; 118 break;
119 msleep(200); 119 cpu_relax();
120 } 120 }
121 if (cpu_status != 0) { 121 if (cpu_status != 0) {
122 printk("Querying DEAD? cpu %i (%i) shows %i\n", 122 printk("Querying DEAD? cpu %i (%i) shows %i\n",
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 7190493e9bdc..5e1ed3d60ee5 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -25,6 +25,8 @@
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */ 26 */
27 27
28#undef DEBUG
29
28#include <linux/pci.h> 30#include <linux/pci.h>
29#include <asm/pci-bridge.h> 31#include <asm/pci-bridge.h>
30#include <asm/ppc-pci.h> 32#include <asm/ppc-pci.h>
@@ -69,74 +71,25 @@ EXPORT_SYMBOL_GPL(pcibios_find_pci_bus);
69 * Remove all of the PCI devices under this bus both from the 71 * Remove all of the PCI devices under this bus both from the
70 * linux pci device tree, and from the powerpc EEH address cache. 72 * linux pci device tree, and from the powerpc EEH address cache.
71 */ 73 */
72void 74void pcibios_remove_pci_devices(struct pci_bus *bus)
73pcibios_remove_pci_devices(struct pci_bus *bus)
74{ 75{
75 struct pci_dev *dev, *tmp; 76 struct pci_dev *dev, *tmp;
77 struct pci_bus *child_bus;
78
79 /* First go down child busses */
80 list_for_each_entry(child_bus, &bus->children, node)
81 pcibios_remove_pci_devices(child_bus);
76 82
83 pr_debug("PCI: Removing devices on bus %04x:%02x\n",
84 pci_domain_nr(bus), bus->number);
77 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { 85 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
86 pr_debug(" * Removing %s...\n", pci_name(dev));
78 eeh_remove_bus_device(dev); 87 eeh_remove_bus_device(dev);
79 pci_remove_bus_device(dev); 88 pci_remove_bus_device(dev);
80 } 89 }
81} 90}
82EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); 91EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
83 92
84/* Must be called before pci_bus_add_devices */
85void
86pcibios_fixup_new_pci_devices(struct pci_bus *bus)
87{
88 struct pci_dev *dev;
89
90 list_for_each_entry(dev, &bus->devices, bus_list) {
91 /* Skip already-added devices */
92 if (!dev->is_added) {
93 int i;
94
95 /* Fill device archdata and setup iommu table */
96 pcibios_setup_new_device(dev);
97
98 pci_read_irq_line(dev);
99 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
100 struct resource *r = &dev->resource[i];
101
102 if (r->parent || !r->start || !r->flags)
103 continue;
104 pci_claim_resource(dev, i);
105 }
106 }
107 }
108}
109EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
110
111static int
112pcibios_pci_config_bridge(struct pci_dev *dev)
113{
114 u8 sec_busno;
115 struct pci_bus *child_bus;
116
117 /* Get busno of downstream bus */
118 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
119
120 /* Add to children of PCI bridge dev->bus */
121 child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
122 if (!child_bus) {
123 printk (KERN_ERR "%s: could not add second bus\n", __func__);
124 return -EIO;
125 }
126 sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
127
128 pci_scan_child_bus(child_bus);
129
130 /* Fixup new pci devices */
131 pcibios_fixup_new_pci_devices(child_bus);
132
133 /* Make the discovered devices available */
134 pci_bus_add_devices(child_bus);
135
136 eeh_add_device_tree_late(child_bus);
137 return 0;
138}
139
140/** 93/**
141 * pcibios_add_pci_devices - adds new pci devices to bus 94 * pcibios_add_pci_devices - adds new pci devices to bus
142 * 95 *
@@ -147,10 +100,9 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
147 * is how this routine differs from other, similar pcibios 100 * is how this routine differs from other, similar pcibios
148 * routines.) 101 * routines.)
149 */ 102 */
150void 103void pcibios_add_pci_devices(struct pci_bus * bus)
151pcibios_add_pci_devices(struct pci_bus * bus)
152{ 104{
153 int slotno, num, mode; 105 int slotno, num, mode, pass, max;
154 struct pci_dev *dev; 106 struct pci_dev *dev;
155 struct device_node *dn = pci_bus_to_OF_node(bus); 107 struct device_node *dn = pci_bus_to_OF_node(bus);
156 108
@@ -162,26 +114,23 @@ pcibios_add_pci_devices(struct pci_bus * bus)
162 114
163 if (mode == PCI_PROBE_DEVTREE) { 115 if (mode == PCI_PROBE_DEVTREE) {
164 /* use ofdt-based probe */ 116 /* use ofdt-based probe */
165 of_scan_bus(dn, bus); 117 of_rescan_bus(dn, bus);
166 if (!list_empty(&bus->devices)) {
167 pcibios_fixup_new_pci_devices(bus);
168 pci_bus_add_devices(bus);
169 eeh_add_device_tree_late(bus);
170 }
171 } else if (mode == PCI_PROBE_NORMAL) { 118 } else if (mode == PCI_PROBE_NORMAL) {
172 /* use legacy probe */ 119 /* use legacy probe */
173 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); 120 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
174 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); 121 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
175 if (num) { 122 if (!num)
176 pcibios_fixup_new_pci_devices(bus); 123 return;
177 pci_bus_add_devices(bus); 124 pcibios_setup_bus_devices(bus);
178 eeh_add_device_tree_late(bus); 125 max = bus->secondary;
126 for (pass=0; pass < 2; pass++)
127 list_for_each_entry(dev, &bus->devices, bus_list) {
128 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
129 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
130 max = pci_scan_bridge(bus, dev, max, pass);
179 } 131 }
180
181 list_for_each_entry(dev, &bus->devices, bus_list)
182 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
183 pcibios_pci_config_bridge(dev);
184 } 132 }
133 pcibios_finish_adding_to_bus(bus);
185} 134}
186EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); 135EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
187 136
@@ -190,6 +139,8 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
190 struct pci_controller *phb; 139 struct pci_controller *phb;
191 int primary; 140 int primary;
192 141
142 pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name);
143
193 primary = list_empty(&hose_list); 144 primary = list_empty(&hose_list);
194 phb = pcibios_alloc_controller(dn); 145 phb = pcibios_alloc_controller(dn);
195 if (!phb) 146 if (!phb)
@@ -203,11 +154,59 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
203 eeh_add_device_tree_early(dn); 154 eeh_add_device_tree_early(dn);
204 155
205 scan_phb(phb); 156 scan_phb(phb);
206 pcibios_allocate_bus_resources(phb->bus); 157 pcibios_finish_adding_to_bus(phb->bus);
207 pcibios_fixup_new_pci_devices(phb->bus);
208 pci_bus_add_devices(phb->bus);
209 eeh_add_device_tree_late(phb->bus);
210 158
211 return phb; 159 return phb;
212} 160}
213EXPORT_SYMBOL_GPL(init_phb_dynamic); 161EXPORT_SYMBOL_GPL(init_phb_dynamic);
162
163/* RPA-specific bits for removing PHBs */
164int remove_phb_dynamic(struct pci_controller *phb)
165{
166 struct pci_bus *b = phb->bus;
167 struct resource *res;
168 int rc, i;
169
170 pr_debug("PCI: Removing PHB %04x:%02x... \n",
171 pci_domain_nr(b), b->number);
172
173 /* We cannot to remove a root bus that has children */
174 if (!(list_empty(&b->children) && list_empty(&b->devices)))
175 return -EBUSY;
176
177 /* We -know- there aren't any child devices anymore at this stage
178 * and thus, we can safely unmap the IO space as it's not in use
179 */
180 res = &phb->io_resource;
181 if (res->flags & IORESOURCE_IO) {
182 rc = pcibios_unmap_io_space(b);
183 if (rc) {
184 printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
185 __func__, b->name);
186 return 1;
187 }
188 }
189
190 /* Unregister the bridge device from sysfs and remove the PCI bus */
191 device_unregister(b->bridge);
192 phb->bus = NULL;
193 pci_remove_bus(b);
194
195 /* Now release the IO resource */
196 if (res->flags & IORESOURCE_IO)
197 release_resource(res);
198
199 /* Release memory resources */
200 for (i = 0; i < 3; ++i) {
201 res = &phb->mem_resources[i];
202 if (!(res->flags & IORESOURCE_MEM))
203 continue;
204 release_resource(res);
205 }
206
207 /* Free pci_controller data structure */
208 pcibios_free_controller(phb);
209
210 return 0;
211}
212EXPORT_SYMBOL_GPL(remove_phb_dynamic);
diff --git a/arch/powerpc/platforms/pseries/phyp_dump.c b/arch/powerpc/platforms/pseries/phyp_dump.c
index edbc012c2ebc..6cf35cd8d0b5 100644
--- a/arch/powerpc/platforms/pseries/phyp_dump.c
+++ b/arch/powerpc/platforms/pseries/phyp_dump.c
@@ -130,6 +130,9 @@ static unsigned long init_dump_header(struct phyp_dump_header *ph)
130static void print_dump_header(const struct phyp_dump_header *ph) 130static void print_dump_header(const struct phyp_dump_header *ph)
131{ 131{
132#ifdef DEBUG 132#ifdef DEBUG
133 if (ph == NULL)
134 return;
135
133 printk(KERN_INFO "dump header:\n"); 136 printk(KERN_INFO "dump header:\n");
134 /* setup some ph->sections required */ 137 /* setup some ph->sections required */
135 printk(KERN_INFO "version = %d\n", ph->version); 138 printk(KERN_INFO "version = %d\n", ph->version);
@@ -411,6 +414,8 @@ static int __init phyp_dump_setup(void)
411 of_node_put(rtas); 414 of_node_put(rtas);
412 } 415 }
413 416
417 ibm_configure_kernel_dump = rtas_token("ibm,configure-kernel-dump");
418
414 print_dump_header(dump_header); 419 print_dump_header(dump_header);
415 dump_area_length = init_dump_header(&phdr); 420 dump_area_length = init_dump_header(&phdr);
416 /* align down */ 421 /* align down */
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 424b335a71c8..84e058f1e1cc 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -579,7 +579,7 @@ static void xics_update_irq_servers(void)
579 int i, j; 579 int i, j;
580 struct device_node *np; 580 struct device_node *np;
581 u32 ilen; 581 u32 ilen;
582 const u32 *ireg, *isize; 582 const u32 *ireg;
583 u32 hcpuid; 583 u32 hcpuid;
584 584
585 /* Find the server numbers for the boot cpu. */ 585 /* Find the server numbers for the boot cpu. */
@@ -607,11 +607,6 @@ static void xics_update_irq_servers(void)
607 } 607 }
608 } 608 }
609 609
610 /* get the bit size of server numbers */
611 isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
612 if (isize)
613 interrupt_server_size = *isize;
614
615 of_node_put(np); 610 of_node_put(np);
616} 611}
617 612
@@ -682,6 +677,7 @@ void __init xics_init_IRQ(void)
682 struct device_node *np; 677 struct device_node *np;
683 u32 indx = 0; 678 u32 indx = 0;
684 int found = 0; 679 int found = 0;
680 const u32 *isize;
685 681
686 ppc64_boot_msg(0x20, "XICS Init"); 682 ppc64_boot_msg(0x20, "XICS Init");
687 683
@@ -701,6 +697,26 @@ void __init xics_init_IRQ(void)
701 if (found == 0) 697 if (found == 0)
702 return; 698 return;
703 699
700 /* get the bit size of server numbers */
701 found = 0;
702
703 for_each_compatible_node(np, NULL, "ibm,ppc-xics") {
704 isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
705
706 if (!isize)
707 continue;
708
709 if (!found) {
710 interrupt_server_size = *isize;
711 found = 1;
712 } else if (*isize != interrupt_server_size) {
713 printk(KERN_WARNING "XICS: "
714 "mismatched ibm,interrupt-server#-size\n");
715 interrupt_server_size = max(*isize,
716 interrupt_server_size);
717 }
718 }
719
704 xics_update_irq_servers(); 720 xics_update_irq_servers();
705 xics_init_host(); 721 xics_init_host();
706 722
@@ -728,9 +744,18 @@ static void xics_set_cpu_priority(unsigned char cppr)
728/* Have the calling processor join or leave the specified global queue */ 744/* Have the calling processor join or leave the specified global queue */
729static void xics_set_cpu_giq(unsigned int gserver, unsigned int join) 745static void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
730{ 746{
731 int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, 747 int index;
732 (1UL << interrupt_server_size) - 1 - gserver, join); 748 int status;
733 WARN_ON(status < 0); 749
750 if (!rtas_indicator_present(GLOBAL_INTERRUPT_QUEUE, NULL))
751 return;
752
753 index = (1UL << interrupt_server_size) - 1 - gserver;
754
755 status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, index, join);
756
757 WARN(status < 0, "set-indicator(%d, %d, %u) returned %d\n",
758 GLOBAL_INTERRUPT_QUEUE, index, join, status);
734} 759}
735 760
736void xics_setup_cpu(void) 761void xics_setup_cpu(void)