aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/512x/Kconfig1
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads.c3
-rw-r--r--arch/powerpc/platforms/512x/mpc512x.h11
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_shared.c25
-rw-r--r--arch/powerpc/platforms/52xx/lite5200.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc5200_simple.c1
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c16
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads-pci-pic.c8
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_mds.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_rdk.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc837x_rdb.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c2
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c8
-rw-r--r--arch/powerpc/platforms/85xx/smp.c49
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c2
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c5
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c25
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c6
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c34
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c1
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c8
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c60
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c10
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c4
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h31
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c119
-rw-r--r--arch/powerpc/platforms/pseries/setup.c77
-rw-r--r--arch/powerpc/platforms/pseries/smp.c1
29 files changed, 259 insertions, 258 deletions
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index b62508b113db..c16999802ecf 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -2,7 +2,6 @@ config PPC_MPC512x
2 bool "512x-based boards" 2 bool "512x-based boards"
3 depends on 6xx 3 depends on 6xx
4 select FSL_SOC 4 select FSL_SOC
5 select FB_FSL_DIU
6 select IPIC 5 select IPIC
7 select PPC_CLOCK 6 select PPC_CLOCK
8 select PPC_PCI_CHOICE 7 select PPC_PCI_CHOICE
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c
index dcef6ade48e1..0a134e0469ef 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads.c
@@ -42,7 +42,10 @@ static void __init mpc5121_ads_setup_arch(void)
42 for_each_compatible_node(np, "pci", "fsl,mpc5121-pci") 42 for_each_compatible_node(np, "pci", "fsl,mpc5121-pci")
43 mpc83xx_add_bridge(np); 43 mpc83xx_add_bridge(np);
44#endif 44#endif
45
46#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
45 mpc512x_setup_diu(); 47 mpc512x_setup_diu();
48#endif
46} 49}
47 50
48static void __init mpc5121_ads_init_IRQ(void) 51static void __init mpc5121_ads_init_IRQ(void)
diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platforms/512x/mpc512x.h
index 1ab6d11d0b19..c32b399eb952 100644
--- a/arch/powerpc/platforms/512x/mpc512x.h
+++ b/arch/powerpc/platforms/512x/mpc512x.h
@@ -16,6 +16,13 @@ extern void __init mpc512x_init(void);
16extern int __init mpc5121_clk_init(void); 16extern int __init mpc5121_clk_init(void);
17void __init mpc512x_declare_of_platform_devices(void); 17void __init mpc512x_declare_of_platform_devices(void);
18extern void mpc512x_restart(char *cmd); 18extern void mpc512x_restart(char *cmd);
19extern void mpc512x_init_diu(void); 19
20extern void mpc512x_setup_diu(void); 20#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
21void mpc512x_init_diu(void);
22void mpc512x_setup_diu(void);
23#else
24#define mpc512x_init_diu NULL
25#define mpc512x_setup_diu NULL
26#endif
27
21#endif /* __MPC512X_H__ */ 28#endif /* __MPC512X_H__ */
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index 1650e090ef3a..35f14fda108a 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -58,6 +58,8 @@ void mpc512x_restart(char *cmd)
58 ; 58 ;
59} 59}
60 60
61#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
62
61struct fsl_diu_shared_fb { 63struct fsl_diu_shared_fb {
62 u8 gamma[0x300]; /* 32-bit aligned! */ 64 u8 gamma[0x300]; /* 32-bit aligned! */
63 struct diu_ad ad0; /* 32-bit aligned! */ 65 struct diu_ad ad0; /* 32-bit aligned! */
@@ -66,25 +68,6 @@ struct fsl_diu_shared_fb {
66 bool in_use; 68 bool in_use;
67}; 69};
68 70
69u32 mpc512x_get_pixel_format(enum fsl_diu_monitor_port port,
70 unsigned int bits_per_pixel)
71{
72 switch (bits_per_pixel) {
73 case 32:
74 return 0x88883316;
75 case 24:
76 return 0x88082219;
77 case 16:
78 return 0x65053118;
79 }
80 return 0x00000400;
81}
82
83void mpc512x_set_gamma_table(enum fsl_diu_monitor_port port,
84 char *gamma_table_base)
85{
86}
87
88void mpc512x_set_monitor_port(enum fsl_diu_monitor_port port) 71void mpc512x_set_monitor_port(enum fsl_diu_monitor_port port)
89{ 72{
90} 73}
@@ -320,14 +303,14 @@ void __init mpc512x_setup_diu(void)
320 } 303 }
321 } 304 }
322 305
323 diu_ops.get_pixel_format = mpc512x_get_pixel_format;
324 diu_ops.set_gamma_table = mpc512x_set_gamma_table;
325 diu_ops.set_monitor_port = mpc512x_set_monitor_port; 306 diu_ops.set_monitor_port = mpc512x_set_monitor_port;
326 diu_ops.set_pixel_clock = mpc512x_set_pixel_clock; 307 diu_ops.set_pixel_clock = mpc512x_set_pixel_clock;
327 diu_ops.valid_monitor_port = mpc512x_valid_monitor_port; 308 diu_ops.valid_monitor_port = mpc512x_valid_monitor_port;
328 diu_ops.release_bootmem = mpc512x_release_bootmem; 309 diu_ops.release_bootmem = mpc512x_release_bootmem;
329} 310}
330 311
312#endif
313
331void __init mpc512x_init_IRQ(void) 314void __init mpc512x_init_IRQ(void)
332{ 315{
333 struct device_node *np; 316 struct device_node *np;
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 448d862bcf3d..1843bc932011 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -4,7 +4,7 @@
4 * Written by: Grant Likely <grant.likely@secretlab.ca> 4 * Written by: Grant Likely <grant.likely@secretlab.ca>
5 * 5 *
6 * Copyright (C) Secret Lab Technologies Ltd. 2006. All rights reserved. 6 * Copyright (C) Secret Lab Technologies Ltd. 2006. All rights reserved.
7 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. 7 * Copyright 2006 Freescale Semiconductor, Inc. All rights reserved.
8 * 8 *
9 * Description: 9 * Description:
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c
index 9cf36020cf0d..792a301a0bf0 100644
--- a/arch/powerpc/platforms/52xx/mpc5200_simple.c
+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c
@@ -50,6 +50,7 @@ static void __init mpc5200_simple_setup_arch(void)
50 50
51/* list of the supported boards */ 51/* list of the supported boards */
52static const char *board[] __initdata = { 52static const char *board[] __initdata = {
53 "anonymous,a3m071",
53 "anonymous,a4m072", 54 "anonymous,a4m072",
54 "anon,charon", 55 "anon,charon",
55 "ifm,o2d", 56 "ifm,o2d",
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index 2351f9e0fb6f..16150fa430f9 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -578,18 +578,4 @@ static struct platform_driver mpc52xx_lpbfifo_driver = {
578 .probe = mpc52xx_lpbfifo_probe, 578 .probe = mpc52xx_lpbfifo_probe,
579 .remove = __devexit_p(mpc52xx_lpbfifo_remove), 579 .remove = __devexit_p(mpc52xx_lpbfifo_remove),
580}; 580};
581 581module_platform_driver(mpc52xx_lpbfifo_driver);
582/***********************************************************************
583 * Module init/exit
584 */
585static int __init mpc52xx_lpbfifo_init(void)
586{
587 return platform_driver_register(&mpc52xx_lpbfifo_driver);
588}
589module_init(mpc52xx_lpbfifo_init);
590
591static void __exit mpc52xx_lpbfifo_exit(void)
592{
593 platform_driver_unregister(&mpc52xx_lpbfifo_driver);
594}
595module_exit(mpc52xx_lpbfifo_exit);
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 328d221fd1c0..74861a7fb807 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -16,7 +16,6 @@
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/irq.h> 17#include <linux/irq.h>
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/bootmem.h>
20#include <linux/slab.h> 19#include <linux/slab.h>
21 20
22#include <asm/io.h> 21#include <asm/io.h>
@@ -149,7 +148,7 @@ int __init pq2ads_pci_init_irq(void)
149 priv->regs = of_iomap(np, 0); 148 priv->regs = of_iomap(np, 0);
150 if (!priv->regs) { 149 if (!priv->regs) {
151 printk(KERN_ERR "Cannot map PCI PIC registers.\n"); 150 printk(KERN_ERR "Cannot map PCI PIC registers.\n");
152 goto out_free_bootmem; 151 goto out_free_kmalloc;
153 } 152 }
154 153
155 /* mask all PCI interrupts */ 154 /* mask all PCI interrupts */
@@ -171,9 +170,8 @@ int __init pq2ads_pci_init_irq(void)
171 170
172out_unmap_regs: 171out_unmap_regs:
173 iounmap(priv->regs); 172 iounmap(priv->regs);
174out_free_bootmem: 173out_free_kmalloc:
175 free_bootmem((unsigned long)priv, 174 kfree(priv);
176 sizeof(struct pq2ads_pci_pic));
177 of_node_put(np); 175 of_node_put(np);
178out_unmap_irq: 176out_unmap_irq:
179 irq_dispose_mapping(irq); 177 irq_dispose_mapping(irq);
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index d440435e055c..8d762203eeff 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. 2 * Copyright 2006 Freescale Semiconductor, Inc. All rights reserved.
3 * 3 *
4 * Description: 4 * Description:
5 * MPC832xE MDS board specific routines. 5 * MPC832xE MDS board specific routines.
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 1b1f6c8a1a12..1a26d2f83401 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. 2 * Copyright 2006 Freescale Semiconductor, Inc. All rights reserved.
3 * 3 *
4 * Author: Li Yang <LeoLi@freescale.com> 4 * Author: Li Yang <LeoLi@freescale.com>
5 * Yin Olivia <Hong-hua.Yin@freescale.com> 5 * Yin Olivia <Hong-hua.Yin@freescale.com>
diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
index f8769d713d61..b63b42d11d6c 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_rdk.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * MPC8360E-RDK board file. 2 * MPC8360E-RDK board file.
3 * 3 *
4 * Copyright (c) 2006 Freescale Semicondutor, Inc. 4 * Copyright (c) 2006 Freescale Semiconductor, Inc.
5 * Copyright (c) 2007-2008 MontaVista Software, Inc. 5 * Copyright (c) 2007-2008 MontaVista Software, Inc.
6 * 6 *
7 * Author: Anton Vorontsov <avorontsov@ru.mvista.com> 7 * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
index eca1f0960fff..9813c81e8e5b 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * arch/powerpc/platforms/83xx/mpc837x_rdb.c 2 * arch/powerpc/platforms/83xx/mpc837x_rdb.c
3 * 3 *
4 * Copyright (C) 2007 Freescale Semicondutor, Inc. All rights reserved. 4 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
5 * 5 *
6 * MPC837x RDB board specific routines 6 * MPC837x RDB board specific routines
7 * 7 *
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 8498f7323470..bd12588fa252 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2006-2010, 2012 Freescale Semicondutor, Inc. 2 * Copyright (C) 2006-2010, 2012 Freescale Semiconductor, Inc.
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * Author: Andy Fleming <afleming@freescale.com> 5 * Author: Andy Fleming <afleming@freescale.com>
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 848a3e98e1c1..7328b8d74129 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -249,7 +249,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
249 goto exit; 249 goto exit;
250 } 250 }
251 251
252 iprop = of_get_property(law_node, "fsl,num-laws", 0); 252 iprop = of_get_property(law_node, "fsl,num-laws", NULL);
253 if (!iprop) { 253 if (!iprop) {
254 pr_err("p1022ds: LAW node is missing fsl,num-laws property\n"); 254 pr_err("p1022ds: LAW node is missing fsl,num-laws property\n");
255 goto exit; 255 goto exit;
@@ -539,7 +539,7 @@ static void __init p1022_ds_setup_arch(void)
539 }; 539 };
540 540
541 /* 541 /*
542 * prom_update_property() is called before 542 * of_update_property() is called before
543 * kmalloc() is available, so the 'new' object 543 * kmalloc() is available, so the 'new' object
544 * should be allocated in the global area. 544 * should be allocated in the global area.
545 * The easiest way is to do that is to 545 * The easiest way is to do that is to
@@ -548,7 +548,7 @@ static void __init p1022_ds_setup_arch(void)
548 */ 548 */
549 pr_info("p1022ds: disabling %s node", 549 pr_info("p1022ds: disabling %s node",
550 np2->full_name); 550 np2->full_name);
551 prom_update_property(np2, &nor_status); 551 of_update_property(np2, &nor_status);
552 of_node_put(np2); 552 of_node_put(np2);
553 } 553 }
554 554
@@ -564,7 +564,7 @@ static void __init p1022_ds_setup_arch(void)
564 564
565 pr_info("p1022ds: disabling %s node", 565 pr_info("p1022ds: disabling %s node",
566 np2->full_name); 566 np2->full_name);
567 prom_update_property(np2, &nand_status); 567 of_update_property(np2, &nand_status);
568 of_node_put(np2); 568 of_node_put(np2);
569 } 569 }
570 570
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 6fcfa12e5c56..148c2f2d9780 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -128,6 +128,19 @@ static void __cpuinit smp_85xx_mach_cpu_die(void)
128} 128}
129#endif 129#endif
130 130
131static inline void flush_spin_table(void *spin_table)
132{
133 flush_dcache_range((ulong)spin_table,
134 (ulong)spin_table + sizeof(struct epapr_spin_table));
135}
136
137static inline u32 read_spin_table_addr_l(void *spin_table)
138{
139 flush_dcache_range((ulong)spin_table,
140 (ulong)spin_table + sizeof(struct epapr_spin_table));
141 return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
142}
143
131static int __cpuinit smp_85xx_kick_cpu(int nr) 144static int __cpuinit smp_85xx_kick_cpu(int nr)
132{ 145{
133 unsigned long flags; 146 unsigned long flags;
@@ -161,8 +174,8 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
161 174
162 /* Map the spin table */ 175 /* Map the spin table */
163 if (ioremappable) 176 if (ioremappable)
164 spin_table = ioremap(*cpu_rel_addr, 177 spin_table = ioremap_prot(*cpu_rel_addr,
165 sizeof(struct epapr_spin_table)); 178 sizeof(struct epapr_spin_table), _PAGE_COHERENT);
166 else 179 else
167 spin_table = phys_to_virt(*cpu_rel_addr); 180 spin_table = phys_to_virt(*cpu_rel_addr);
168 181
@@ -173,7 +186,16 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
173 generic_set_cpu_up(nr); 186 generic_set_cpu_up(nr);
174 187
175 if (system_state == SYSTEM_RUNNING) { 188 if (system_state == SYSTEM_RUNNING) {
189 /*
190 * To keep it compatible with old boot program which uses
191 * cache-inhibit spin table, we need to flush the cache
192 * before accessing spin table to invalidate any staled data.
193 * We also need to flush the cache after writing to spin
194 * table to push data out.
195 */
196 flush_spin_table(spin_table);
176 out_be32(&spin_table->addr_l, 0); 197 out_be32(&spin_table->addr_l, 0);
198 flush_spin_table(spin_table);
177 199
178 /* 200 /*
179 * We don't set the BPTR register here since it already points 201 * We don't set the BPTR register here since it already points
@@ -181,9 +203,14 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
181 */ 203 */
182 mpic_reset_core(hw_cpu); 204 mpic_reset_core(hw_cpu);
183 205
184 /* wait until core is ready... */ 206 /*
185 if (!spin_event_timeout(in_be32(&spin_table->addr_l) == 1, 207 * wait until core is ready...
186 10000, 100)) { 208 * We need to invalidate the stale data, in case the boot
209 * loader uses a cache-inhibited spin table.
210 */
211 if (!spin_event_timeout(
212 read_spin_table_addr_l(spin_table) == 1,
213 10000, 100)) {
187 pr_err("%s: timeout waiting for core %d to reset\n", 214 pr_err("%s: timeout waiting for core %d to reset\n",
188 __func__, hw_cpu); 215 __func__, hw_cpu);
189 ret = -ENOENT; 216 ret = -ENOENT;
@@ -194,12 +221,10 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
194 __secondary_hold_acknowledge = -1; 221 __secondary_hold_acknowledge = -1;
195 } 222 }
196#endif 223#endif
224 flush_spin_table(spin_table);
197 out_be32(&spin_table->pir, hw_cpu); 225 out_be32(&spin_table->pir, hw_cpu);
198 out_be32(&spin_table->addr_l, __pa(__early_start)); 226 out_be32(&spin_table->addr_l, __pa(__early_start));
199 227 flush_spin_table(spin_table);
200 if (!ioremappable)
201 flush_dcache_range((ulong)spin_table,
202 (ulong)spin_table + sizeof(struct epapr_spin_table));
203 228
204 /* Wait a bit for the CPU to ack. */ 229 /* Wait a bit for the CPU to ack. */
205 if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu, 230 if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu,
@@ -213,13 +238,11 @@ out:
213#else 238#else
214 smp_generic_kick_cpu(nr); 239 smp_generic_kick_cpu(nr);
215 240
241 flush_spin_table(spin_table);
216 out_be32(&spin_table->pir, hw_cpu); 242 out_be32(&spin_table->pir, hw_cpu);
217 out_be64((u64 *)(&spin_table->addr_h), 243 out_be64((u64 *)(&spin_table->addr_h),
218 __pa((u64)*((unsigned long long *)generic_secondary_smp_init))); 244 __pa((u64)*((unsigned long long *)generic_secondary_smp_init)));
219 245 flush_spin_table(spin_table);
220 if (!ioremappable)
221 flush_dcache_range((ulong)spin_table,
222 (ulong)spin_table + sizeof(struct epapr_spin_table));
223#endif 246#endif
224 247
225 local_irq_restore(flags); 248 local_irq_restore(flags);
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index a817398a56da..04d9d317f741 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -353,5 +353,7 @@ define_machine(mpc86xx_hpcd) {
353 .time_init = mpc86xx_time_init, 353 .time_init = mpc86xx_time_init,
354 .calibrate_decr = generic_calibrate_decr, 354 .calibrate_decr = generic_calibrate_decr,
355 .progress = udbg_progress, 355 .progress = udbg_progress,
356#ifdef CONFIG_PCI
356 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 357 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
358#endif
357}; 359};
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 64171198535c..311b804353b1 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -55,6 +55,7 @@ static unsigned int low_freq;
55static unsigned int hi_freq; 55static unsigned int hi_freq;
56static unsigned int cur_freq; 56static unsigned int cur_freq;
57static unsigned int sleep_freq; 57static unsigned int sleep_freq;
58static unsigned long transition_latency;
58 59
59/* 60/*
60 * Different models uses different mechanisms to switch the frequency 61 * Different models uses different mechanisms to switch the frequency
@@ -403,7 +404,7 @@ static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
403 if (policy->cpu != 0) 404 if (policy->cpu != 0)
404 return -ENODEV; 405 return -ENODEV;
405 406
406 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; 407 policy->cpuinfo.transition_latency = transition_latency;
407 policy->cur = cur_freq; 408 policy->cur = cur_freq;
408 409
409 cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu); 410 cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
@@ -658,12 +659,14 @@ static int __init pmac_cpufreq_setup(void)
658 if (!value) 659 if (!value)
659 goto out; 660 goto out;
660 cur_freq = (*value) / 1000; 661 cur_freq = (*value) / 1000;
662 transition_latency = CPUFREQ_ETERNAL;
661 663
662 /* Check for 7447A based MacRISC3 */ 664 /* Check for 7447A based MacRISC3 */
663 if (of_machine_is_compatible("MacRISC3") && 665 if (of_machine_is_compatible("MacRISC3") &&
664 of_get_property(cpunode, "dynamic-power-step", NULL) && 666 of_get_property(cpunode, "dynamic-power-step", NULL) &&
665 PVR_VER(mfspr(SPRN_PVR)) == 0x8003) { 667 PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
666 pmac_cpufreq_init_7447A(cpunode); 668 pmac_cpufreq_init_7447A(cpunode);
669 transition_latency = 8000000;
667 /* Check for other MacRISC3 machines */ 670 /* Check for other MacRISC3 machines */
668 } else if (of_machine_is_compatible("PowerBook3,4") || 671 } else if (of_machine_is_compatible("PowerBook3,4") ||
669 of_machine_is_compatible("PowerBook3,5") || 672 of_machine_is_compatible("PowerBook3,5") ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 471aa3ccd9fd..53d052e95cfc 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -34,24 +34,12 @@
34#include "powernv.h" 34#include "powernv.h"
35#include "pci.h" 35#include "pci.h"
36 36
37static int __pe_printk(const char *level, const struct pnv_ioda_pe *pe,
38 struct va_format *vaf)
39{
40 char pfix[32];
41
42 if (pe->pdev)
43 strlcpy(pfix, dev_name(&pe->pdev->dev), sizeof(pfix));
44 else
45 sprintf(pfix, "%04x:%02x ",
46 pci_domain_nr(pe->pbus), pe->pbus->number);
47 return printk("pci %s%s: [PE# %.3d] %pV", level, pfix, pe->pe_number, vaf);
48}
49
50#define define_pe_printk_level(func, kern_level) \ 37#define define_pe_printk_level(func, kern_level) \
51static int func(const struct pnv_ioda_pe *pe, const char *fmt, ...) \ 38static int func(const struct pnv_ioda_pe *pe, const char *fmt, ...) \
52{ \ 39{ \
53 struct va_format vaf; \ 40 struct va_format vaf; \
54 va_list args; \ 41 va_list args; \
42 char pfix[32]; \
55 int r; \ 43 int r; \
56 \ 44 \
57 va_start(args, fmt); \ 45 va_start(args, fmt); \
@@ -59,7 +47,16 @@ static int func(const struct pnv_ioda_pe *pe, const char *fmt, ...) \
59 vaf.fmt = fmt; \ 47 vaf.fmt = fmt; \
60 vaf.va = &args; \ 48 vaf.va = &args; \
61 \ 49 \
62 r = __pe_printk(kern_level, pe, &vaf); \ 50 if (pe->pdev) \
51 strlcpy(pfix, dev_name(&pe->pdev->dev), \
52 sizeof(pfix)); \
53 else \
54 sprintf(pfix, "%04x:%02x ", \
55 pci_domain_nr(pe->pbus), \
56 pe->pbus->number); \
57 r = printk(kern_level "pci %s: [PE# %.3d] %pV", \
58 pfix, pe->pe_number, &vaf); \
59 \
63 va_end(args); \ 60 va_end(args); \
64 \ 61 \
65 return r; \ 62 return r; \
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index 56d26bc4fd41..09787139834d 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -280,13 +280,13 @@ static void os_area_set_property(struct device_node *node,
280 280
281 if (tmp) { 281 if (tmp) {
282 pr_debug("%s:%d found %s\n", __func__, __LINE__, prop->name); 282 pr_debug("%s:%d found %s\n", __func__, __LINE__, prop->name);
283 prom_remove_property(node, tmp); 283 of_remove_property(node, tmp);
284 } 284 }
285 285
286 result = prom_add_property(node, prop); 286 result = of_add_property(node, prop);
287 287
288 if (result) 288 if (result)
289 pr_debug("%s:%d prom_set_property failed\n", __func__, 289 pr_debug("%s:%d of_set_property failed\n", __func__,
290 __LINE__); 290 __LINE__);
291} 291}
292 292
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 0f1b706506ed..a1a7b9a67ffd 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -13,17 +13,16 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/kref.h> 14#include <linux/kref.h>
15#include <linux/notifier.h> 15#include <linux/notifier.h>
16#include <linux/proc_fs.h>
17#include <linux/spinlock.h> 16#include <linux/spinlock.h>
18#include <linux/cpu.h> 17#include <linux/cpu.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/of.h>
20#include "offline_states.h" 20#include "offline_states.h"
21 21
22#include <asm/prom.h> 22#include <asm/prom.h>
23#include <asm/machdep.h> 23#include <asm/machdep.h>
24#include <asm/uaccess.h> 24#include <asm/uaccess.h>
25#include <asm/rtas.h> 25#include <asm/rtas.h>
26#include <asm/pSeries_reconfig.h>
27 26
28struct cc_workarea { 27struct cc_workarea {
29 u32 drc_index; 28 u32 drc_index;
@@ -255,9 +254,6 @@ static struct device_node *derive_parent(const char *path)
255 254
256int dlpar_attach_node(struct device_node *dn) 255int dlpar_attach_node(struct device_node *dn)
257{ 256{
258#ifdef CONFIG_PROC_DEVICETREE
259 struct proc_dir_entry *ent;
260#endif
261 int rc; 257 int rc;
262 258
263 of_node_set_flag(dn, OF_DYNAMIC); 259 of_node_set_flag(dn, OF_DYNAMIC);
@@ -266,44 +262,26 @@ int dlpar_attach_node(struct device_node *dn)
266 if (!dn->parent) 262 if (!dn->parent)
267 return -ENOMEM; 263 return -ENOMEM;
268 264
269 rc = pSeries_reconfig_notify(PSERIES_RECONFIG_ADD, dn); 265 rc = of_attach_node(dn);
270 if (rc) { 266 if (rc) {
271 printk(KERN_ERR "Failed to add device node %s\n", 267 printk(KERN_ERR "Failed to add device node %s\n",
272 dn->full_name); 268 dn->full_name);
273 return rc; 269 return rc;
274 } 270 }
275 271
276 of_attach_node(dn);
277
278#ifdef CONFIG_PROC_DEVICETREE
279 ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
280 if (ent)
281 proc_device_tree_add_node(dn, ent);
282#endif
283
284 of_node_put(dn->parent); 272 of_node_put(dn->parent);
285 return 0; 273 return 0;
286} 274}
287 275
288int dlpar_detach_node(struct device_node *dn) 276int dlpar_detach_node(struct device_node *dn)
289{ 277{
290#ifdef CONFIG_PROC_DEVICETREE 278 int rc;
291 struct device_node *parent = dn->parent;
292 struct property *prop = dn->properties;
293
294 while (prop) {
295 remove_proc_entry(prop->name, dn->pde);
296 prop = prop->next;
297 }
298 279
299 if (dn->pde) 280 rc = of_detach_node(dn);
300 remove_proc_entry(dn->pde->name, parent->pde); 281 if (rc)
301#endif 282 return rc;
302 283
303 pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, dn);
304 of_detach_node(dn);
305 of_node_put(dn); /* Must decrement the refcount */ 284 of_node_put(dn); /* Must decrement the refcount */
306
307 return 0; 285 return 0;
308} 286}
309 287
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 0b0eff0cce35..7b56118f531c 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -56,6 +56,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
56 {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, 56 {FW_FEATURE_MULTITCE, "hcall-multi-tce"},
57 {FW_FEATURE_SPLPAR, "hcall-splpar"}, 57 {FW_FEATURE_SPLPAR, "hcall-splpar"},
58 {FW_FEATURE_VPHN, "hcall-vphn"}, 58 {FW_FEATURE_VPHN, "hcall-vphn"},
59 {FW_FEATURE_SET_MODE, "hcall-set-mode"},
59}; 60};
60 61
61/* Build up the firmware features bitmask using the contents of 62/* Build up the firmware features bitmask using the contents of
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 64c97d8ac0c5..a38956269fbf 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -23,12 +23,12 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/sched.h> /* for idle_task_exit */ 24#include <linux/sched.h> /* for idle_task_exit */
25#include <linux/cpu.h> 25#include <linux/cpu.h>
26#include <linux/of.h>
26#include <asm/prom.h> 27#include <asm/prom.h>
27#include <asm/rtas.h> 28#include <asm/rtas.h>
28#include <asm/firmware.h> 29#include <asm/firmware.h>
29#include <asm/machdep.h> 30#include <asm/machdep.h>
30#include <asm/vdso_datapage.h> 31#include <asm/vdso_datapage.h>
31#include <asm/pSeries_reconfig.h>
32#include <asm/xics.h> 32#include <asm/xics.h>
33#include "plpar_wrappers.h" 33#include "plpar_wrappers.h"
34#include "offline_states.h" 34#include "offline_states.h"
@@ -333,10 +333,10 @@ static int pseries_smp_notifier(struct notifier_block *nb,
333 int err = 0; 333 int err = 0;
334 334
335 switch (action) { 335 switch (action) {
336 case PSERIES_RECONFIG_ADD: 336 case OF_RECONFIG_ATTACH_NODE:
337 err = pseries_add_processor(node); 337 err = pseries_add_processor(node);
338 break; 338 break;
339 case PSERIES_RECONFIG_REMOVE: 339 case OF_RECONFIG_DETACH_NODE:
340 pseries_remove_processor(node); 340 pseries_remove_processor(node);
341 break; 341 break;
342 } 342 }
@@ -399,7 +399,7 @@ static int __init pseries_cpu_hotplug_init(void)
399 399
400 /* Processors can be added/removed only on LPAR */ 400 /* Processors can be added/removed only on LPAR */
401 if (firmware_has_feature(FW_FEATURE_LPAR)) { 401 if (firmware_has_feature(FW_FEATURE_LPAR)) {
402 pSeries_reconfig_notifier_register(&pseries_smp_nb); 402 of_reconfig_notifier_register(&pseries_smp_nb);
403 cpu_maps_update_begin(); 403 cpu_maps_update_begin();
404 if (cede_offline_enabled && parse_cede_parameters() == 0) { 404 if (cede_offline_enabled && parse_cede_parameters() == 0) {
405 default_offline_state = CPU_STATE_INACTIVE; 405 default_offline_state = CPU_STATE_INACTIVE;
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index ecdb0a6b3171..2372c609fa2b 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -16,7 +16,6 @@
16 16
17#include <asm/firmware.h> 17#include <asm/firmware.h>
18#include <asm/machdep.h> 18#include <asm/machdep.h>
19#include <asm/pSeries_reconfig.h>
20#include <asm/sparsemem.h> 19#include <asm/sparsemem.h>
21 20
22static unsigned long get_memblock_size(void) 21static unsigned long get_memblock_size(void)
@@ -187,42 +186,69 @@ static int pseries_add_memory(struct device_node *np)
187 return (ret < 0) ? -EINVAL : 0; 186 return (ret < 0) ? -EINVAL : 0;
188} 187}
189 188
190static int pseries_drconf_memory(unsigned long *base, unsigned int action) 189static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
191{ 190{
191 struct of_drconf_cell *new_drmem, *old_drmem;
192 unsigned long memblock_size; 192 unsigned long memblock_size;
193 int rc; 193 u32 entries;
194 u32 *p;
195 int i, rc = -EINVAL;
194 196
195 memblock_size = get_memblock_size(); 197 memblock_size = get_memblock_size();
196 if (!memblock_size) 198 if (!memblock_size)
197 return -EINVAL; 199 return -EINVAL;
198 200
199 if (action == PSERIES_DRCONF_MEM_ADD) { 201 p = (u32 *)of_get_property(pr->dn, "ibm,dynamic-memory", NULL);
200 rc = memblock_add(*base, memblock_size); 202 if (!p)
201 rc = (rc < 0) ? -EINVAL : 0; 203 return -EINVAL;
202 } else if (action == PSERIES_DRCONF_MEM_REMOVE) { 204
203 rc = pseries_remove_memblock(*base, memblock_size); 205 /* The first int of the property is the number of lmb's described
204 } else { 206 * by the property. This is followed by an array of of_drconf_cell
205 rc = -EINVAL; 207 * entries. Get the niumber of entries and skip to the array of
208 * of_drconf_cell's.
209 */
210 entries = *p++;
211 old_drmem = (struct of_drconf_cell *)p;
212
213 p = (u32 *)pr->prop->value;
214 p++;
215 new_drmem = (struct of_drconf_cell *)p;
216
217 for (i = 0; i < entries; i++) {
218 if ((old_drmem[i].flags & DRCONF_MEM_ASSIGNED) &&
219 (!(new_drmem[i].flags & DRCONF_MEM_ASSIGNED))) {
220 rc = pseries_remove_memblock(old_drmem[i].base_addr,
221 memblock_size);
222 break;
223 } else if ((!(old_drmem[i].flags & DRCONF_MEM_ASSIGNED)) &&
224 (new_drmem[i].flags & DRCONF_MEM_ASSIGNED)) {
225 rc = memblock_add(old_drmem[i].base_addr,
226 memblock_size);
227 rc = (rc < 0) ? -EINVAL : 0;
228 break;
229 }
206 } 230 }
207 231
208 return rc; 232 return rc;
209} 233}
210 234
211static int pseries_memory_notifier(struct notifier_block *nb, 235static int pseries_memory_notifier(struct notifier_block *nb,
212 unsigned long action, void *node) 236 unsigned long action, void *node)
213{ 237{
238 struct of_prop_reconfig *pr;
214 int err = 0; 239 int err = 0;
215 240
216 switch (action) { 241 switch (action) {
217 case PSERIES_RECONFIG_ADD: 242 case OF_RECONFIG_ATTACH_NODE:
218 err = pseries_add_memory(node); 243 err = pseries_add_memory(node);
219 break; 244 break;
220 case PSERIES_RECONFIG_REMOVE: 245 case OF_RECONFIG_DETACH_NODE:
221 err = pseries_remove_memory(node); 246 err = pseries_remove_memory(node);
222 break; 247 break;
223 case PSERIES_DRCONF_MEM_ADD: 248 case OF_RECONFIG_UPDATE_PROPERTY:
224 case PSERIES_DRCONF_MEM_REMOVE: 249 pr = (struct of_prop_reconfig *)node;
225 err = pseries_drconf_memory(node, action); 250 if (!strcmp(pr->prop->name, "ibm,dynamic-memory"))
251 err = pseries_update_drconf_memory(pr);
226 break; 252 break;
227 } 253 }
228 return notifier_from_errno(err); 254 return notifier_from_errno(err);
@@ -235,7 +261,7 @@ static struct notifier_block pseries_mem_nb = {
235static int __init pseries_memory_hotplug_init(void) 261static int __init pseries_memory_hotplug_init(void)
236{ 262{
237 if (firmware_has_feature(FW_FEATURE_LPAR)) 263 if (firmware_has_feature(FW_FEATURE_LPAR))
238 pSeries_reconfig_notifier_register(&pseries_mem_nb); 264 of_reconfig_notifier_register(&pseries_mem_nb);
239 265
240 return 0; 266 return 0;
241} 267}
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 6153eea27ce7..e2685badb5db 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -36,13 +36,13 @@
36#include <linux/dma-mapping.h> 36#include <linux/dma-mapping.h>
37#include <linux/crash_dump.h> 37#include <linux/crash_dump.h>
38#include <linux/memory.h> 38#include <linux/memory.h>
39#include <linux/of.h>
39#include <asm/io.h> 40#include <asm/io.h>
40#include <asm/prom.h> 41#include <asm/prom.h>
41#include <asm/rtas.h> 42#include <asm/rtas.h>
42#include <asm/iommu.h> 43#include <asm/iommu.h>
43#include <asm/pci-bridge.h> 44#include <asm/pci-bridge.h>
44#include <asm/machdep.h> 45#include <asm/machdep.h>
45#include <asm/pSeries_reconfig.h>
46#include <asm/firmware.h> 46#include <asm/firmware.h>
47#include <asm/tce.h> 47#include <asm/tce.h>
48#include <asm/ppc-pci.h> 48#include <asm/ppc-pci.h>
@@ -760,7 +760,7 @@ static void remove_ddw(struct device_node *np)
760 __remove_ddw(np, ddw_avail, liobn); 760 __remove_ddw(np, ddw_avail, liobn);
761 761
762delprop: 762delprop:
763 ret = prom_remove_property(np, win64); 763 ret = of_remove_property(np, win64);
764 if (ret) 764 if (ret)
765 pr_warning("%s: failed to remove direct window property: %d\n", 765 pr_warning("%s: failed to remove direct window property: %d\n",
766 np->full_name, ret); 766 np->full_name, ret);
@@ -1070,7 +1070,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
1070 goto out_free_window; 1070 goto out_free_window;
1071 } 1071 }
1072 1072
1073 ret = prom_add_property(pdn, win64); 1073 ret = of_add_property(pdn, win64);
1074 if (ret) { 1074 if (ret) {
1075 dev_err(&dev->dev, "unable to add dma window property for %s: %d", 1075 dev_err(&dev->dev, "unable to add dma window property for %s: %d",
1076 pdn->full_name, ret); 1076 pdn->full_name, ret);
@@ -1294,7 +1294,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
1294 struct direct_window *window; 1294 struct direct_window *window;
1295 1295
1296 switch (action) { 1296 switch (action) {
1297 case PSERIES_RECONFIG_REMOVE: 1297 case OF_RECONFIG_DETACH_NODE:
1298 if (pci && pci->iommu_table) 1298 if (pci && pci->iommu_table)
1299 iommu_free_table(pci->iommu_table, np->full_name); 1299 iommu_free_table(pci->iommu_table, np->full_name);
1300 1300
@@ -1357,7 +1357,7 @@ void iommu_init_early_pSeries(void)
1357 } 1357 }
1358 1358
1359 1359
1360 pSeries_reconfig_notifier_register(&iommu_reconfig_nb); 1360 of_reconfig_notifier_register(&iommu_reconfig_nb);
1361 register_memory_notifier(&iommu_mem_nb); 1361 register_memory_notifier(&iommu_mem_nb);
1362 1362
1363 set_pci_dma_ops(&dma_iommu_ops); 1363 set_pci_dma_ops(&dma_iommu_ops);
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index dd30b12edfe4..6573808cc5f3 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -116,7 +116,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
116 } 116 }
117 117
118 if (!more) { 118 if (!more) {
119 prom_update_property(dn, new_prop); 119 of_update_property(dn, new_prop);
120 new_prop = NULL; 120 new_prop = NULL;
121 } 121 }
122 122
@@ -172,7 +172,7 @@ static int update_dt_node(u32 phandle)
172 172
173 case 0x80000000: 173 case 0x80000000:
174 prop = of_find_property(dn, prop_name, NULL); 174 prop = of_find_property(dn, prop_name, NULL);
175 prom_remove_property(dn, prop); 175 of_remove_property(dn, prop);
176 prop = NULL; 176 prop = NULL;
177 break; 177 break;
178 178
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index 13e8cc43adf7..e6cc34a67053 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -273,4 +273,35 @@ static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
273 lbuf[1]); 273 lbuf[1]);
274} 274}
275 275
276/* Set various resource mode parameters */
277static inline long plpar_set_mode(unsigned long mflags, unsigned long resource,
278 unsigned long value1, unsigned long value2)
279{
280 return plpar_hcall_norets(H_SET_MODE, mflags, resource, value1, value2);
281}
282
283/*
284 * Enable relocation on exceptions on this partition
285 *
286 * Note: this call has a partition wide scope and can take a while to complete.
287 * If it returns H_LONG_BUSY_* it should be retried periodically until it
288 * returns H_SUCCESS.
289 */
290static inline long enable_reloc_on_exceptions(void)
291{
292 /* mflags = 3: Exceptions at 0xC000000000004000 */
293 return plpar_set_mode(3, 3, 0, 0);
294}
295
296/*
297 * Disable relocation on exceptions on this partition
298 *
299 * Note: this call has a partition wide scope and can take a while to complete.
300 * If it returns H_LONG_BUSY_* it should be retried periodically until it
301 * returns H_SUCCESS.
302 */
303static inline long disable_reloc_on_exceptions(void) {
304 return plpar_set_mode(0, 3, 0, 0);
305}
306
276#endif /* _PSERIES_PLPAR_WRAPPERS_H */ 307#endif /* _PSERIES_PLPAR_WRAPPERS_H */
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 2f4668136b20..d6491bd481d0 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -16,55 +16,13 @@
16#include <linux/notifier.h> 16#include <linux/notifier.h>
17#include <linux/proc_fs.h> 17#include <linux/proc_fs.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/of.h>
19 20
20#include <asm/prom.h> 21#include <asm/prom.h>
21#include <asm/machdep.h> 22#include <asm/machdep.h>
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
23#include <asm/pSeries_reconfig.h>
24#include <asm/mmu.h> 24#include <asm/mmu.h>
25 25
26
27
28/*
29 * Routines for "runtime" addition and removal of device tree nodes.
30 */
31#ifdef CONFIG_PROC_DEVICETREE
32/*
33 * Add a node to /proc/device-tree.
34 */
35static void add_node_proc_entries(struct device_node *np)
36{
37 struct proc_dir_entry *ent;
38
39 ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde);
40 if (ent)
41 proc_device_tree_add_node(np, ent);
42}
43
44static void remove_node_proc_entries(struct device_node *np)
45{
46 struct property *pp = np->properties;
47 struct device_node *parent = np->parent;
48
49 while (pp) {
50 remove_proc_entry(pp->name, np->pde);
51 pp = pp->next;
52 }
53 if (np->pde)
54 remove_proc_entry(np->pde->name, parent->pde);
55}
56#else /* !CONFIG_PROC_DEVICETREE */
57static void add_node_proc_entries(struct device_node *np)
58{
59 return;
60}
61
62static void remove_node_proc_entries(struct device_node *np)
63{
64 return;
65}
66#endif /* CONFIG_PROC_DEVICETREE */
67
68/** 26/**
69 * derive_parent - basically like dirname(1) 27 * derive_parent - basically like dirname(1)
70 * @path: the full_name of a node to be added to the tree 28 * @path: the full_name of a node to be added to the tree
@@ -97,28 +55,6 @@ static struct device_node *derive_parent(const char *path)
97 return parent; 55 return parent;
98} 56}
99 57
100static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
101
102int pSeries_reconfig_notifier_register(struct notifier_block *nb)
103{
104 return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb);
105}
106EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_register);
107
108void pSeries_reconfig_notifier_unregister(struct notifier_block *nb)
109{
110 blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb);
111}
112EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_unregister);
113
114int pSeries_reconfig_notify(unsigned long action, void *p)
115{
116 int err = blocking_notifier_call_chain(&pSeries_reconfig_chain,
117 action, p);
118
119 return notifier_to_errno(err);
120}
121
122static int pSeries_reconfig_add_node(const char *path, struct property *proplist) 58static int pSeries_reconfig_add_node(const char *path, struct property *proplist)
123{ 59{
124 struct device_node *np; 60 struct device_node *np;
@@ -142,16 +78,12 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
142 goto out_err; 78 goto out_err;
143 } 79 }
144 80
145 err = pSeries_reconfig_notify(PSERIES_RECONFIG_ADD, np); 81 err = of_attach_node(np);
146 if (err) { 82 if (err) {
147 printk(KERN_ERR "Failed to add device node %s\n", path); 83 printk(KERN_ERR "Failed to add device node %s\n", path);
148 goto out_err; 84 goto out_err;
149 } 85 }
150 86
151 of_attach_node(np);
152
153 add_node_proc_entries(np);
154
155 of_node_put(np->parent); 87 of_node_put(np->parent);
156 88
157 return 0; 89 return 0;
@@ -179,11 +111,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
179 return -EBUSY; 111 return -EBUSY;
180 } 112 }
181 113
182 remove_node_proc_entries(np);
183
184 pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, np);
185 of_detach_node(np); 114 of_detach_node(np);
186
187 of_node_put(parent); 115 of_node_put(parent);
188 of_node_put(np); /* Must decrement the refcount */ 116 of_node_put(np); /* Must decrement the refcount */
189 return 0; 117 return 0;
@@ -397,7 +325,7 @@ static int do_add_property(char *buf, size_t bufsize)
397 if (!prop) 325 if (!prop)
398 return -ENOMEM; 326 return -ENOMEM;
399 327
400 prom_add_property(np, prop); 328 of_add_property(np, prop);
401 329
402 return 0; 330 return 0;
403} 331}
@@ -421,16 +349,15 @@ static int do_remove_property(char *buf, size_t bufsize)
421 349
422 prop = of_find_property(np, buf, NULL); 350 prop = of_find_property(np, buf, NULL);
423 351
424 return prom_remove_property(np, prop); 352 return of_remove_property(np, prop);
425} 353}
426 354
427static int do_update_property(char *buf, size_t bufsize) 355static int do_update_property(char *buf, size_t bufsize)
428{ 356{
429 struct device_node *np; 357 struct device_node *np;
430 struct pSeries_reconfig_prop_update upd_value;
431 unsigned char *value; 358 unsigned char *value;
432 char *name, *end, *next_prop; 359 char *name, *end, *next_prop;
433 int rc, length; 360 int length;
434 struct property *newprop; 361 struct property *newprop;
435 buf = parse_node(buf, bufsize, &np); 362 buf = parse_node(buf, bufsize, &np);
436 end = buf + bufsize; 363 end = buf + bufsize;
@@ -452,41 +379,7 @@ static int do_update_property(char *buf, size_t bufsize)
452 if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) 379 if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
453 slb_set_size(*(int *)value); 380 slb_set_size(*(int *)value);
454 381
455 upd_value.node = np; 382 return of_update_property(np, newprop);
456 upd_value.property = newprop;
457 pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value);
458
459 rc = prom_update_property(np, newprop);
460 if (rc)
461 return rc;
462
463 /* For memory under the ibm,dynamic-reconfiguration-memory node
464 * of the device tree, adding and removing memory is just an update
465 * to the ibm,dynamic-memory property instead of adding/removing a
466 * memory node in the device tree. For these cases we still need to
467 * involve the notifier chain.
468 */
469 if (!strcmp(name, "ibm,dynamic-memory")) {
470 int action;
471
472 next_prop = parse_next_property(next_prop, end, &name,
473 &length, &value);
474 if (!next_prop)
475 return -EINVAL;
476
477 if (!strcmp(name, "add"))
478 action = PSERIES_DRCONF_MEM_ADD;
479 else
480 action = PSERIES_DRCONF_MEM_REMOVE;
481
482 rc = pSeries_reconfig_notify(action, value);
483 if (rc) {
484 prom_update_property(np, newprop);
485 return rc;
486 }
487 }
488
489 return 0;
490} 383}
491 384
492/** 385/**
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index e3cb7ae61658..ca55882465d6 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -40,6 +40,8 @@
40#include <linux/seq_file.h> 40#include <linux/seq_file.h>
41#include <linux/root_dev.h> 41#include <linux/root_dev.h>
42#include <linux/cpuidle.h> 42#include <linux/cpuidle.h>
43#include <linux/of.h>
44#include <linux/kexec.h>
43 45
44#include <asm/mmu.h> 46#include <asm/mmu.h>
45#include <asm/processor.h> 47#include <asm/processor.h>
@@ -63,7 +65,6 @@
63#include <asm/smp.h> 65#include <asm/smp.h>
64#include <asm/firmware.h> 66#include <asm/firmware.h>
65#include <asm/eeh.h> 67#include <asm/eeh.h>
66#include <asm/pSeries_reconfig.h>
67 68
68#include "plpar_wrappers.h" 69#include "plpar_wrappers.h"
69#include "pseries.h" 70#include "pseries.h"
@@ -258,7 +259,7 @@ static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long act
258 int err = NOTIFY_OK; 259 int err = NOTIFY_OK;
259 260
260 switch (action) { 261 switch (action) {
261 case PSERIES_RECONFIG_ADD: 262 case OF_RECONFIG_ATTACH_NODE:
262 pci = np->parent->data; 263 pci = np->parent->data;
263 if (pci) { 264 if (pci) {
264 update_dn_pci_info(np, pci->phb); 265 update_dn_pci_info(np, pci->phb);
@@ -367,6 +368,65 @@ static void pSeries_idle(void)
367 } 368 }
368} 369}
369 370
371/*
372 * Enable relocation on during exceptions. This has partition wide scope and
373 * may take a while to complete, if it takes longer than one second we will
374 * just give up rather than wasting any more time on this - if that turns out
375 * to ever be a problem in practice we can move this into a kernel thread to
376 * finish off the process later in boot.
377 */
378static int __init pSeries_enable_reloc_on_exc(void)
379{
380 long rc;
381 unsigned int delay, total_delay = 0;
382
383 while (1) {
384 rc = enable_reloc_on_exceptions();
385 if (!H_IS_LONG_BUSY(rc))
386 return rc;
387
388 delay = get_longbusy_msecs(rc);
389 total_delay += delay;
390 if (total_delay > 1000) {
391 pr_warn("Warning: Giving up waiting to enable "
392 "relocation on exceptions (%u msec)!\n",
393 total_delay);
394 return rc;
395 }
396
397 mdelay(delay);
398 }
399}
400
401#ifdef CONFIG_KEXEC
402static long pSeries_disable_reloc_on_exc(void)
403{
404 long rc;
405
406 while (1) {
407 rc = disable_reloc_on_exceptions();
408 if (!H_IS_LONG_BUSY(rc))
409 return rc;
410 mdelay(get_longbusy_msecs(rc));
411 }
412}
413
414static void pSeries_machine_kexec(struct kimage *image)
415{
416 long rc;
417
418 if (firmware_has_feature(FW_FEATURE_SET_MODE) &&
419 (image->type != KEXEC_TYPE_CRASH)) {
420 rc = pSeries_disable_reloc_on_exc();
421 if (rc != H_SUCCESS)
422 pr_warning("Warning: Failed to disable relocation on "
423 "exceptions: %ld\n", rc);
424 }
425
426 default_machine_kexec(image);
427}
428#endif
429
370static void __init pSeries_setup_arch(void) 430static void __init pSeries_setup_arch(void)
371{ 431{
372 panic_timeout = 10; 432 panic_timeout = 10;
@@ -389,7 +449,7 @@ static void __init pSeries_setup_arch(void)
389 /* Find and initialize PCI host bridges */ 449 /* Find and initialize PCI host bridges */
390 init_pci_config_tokens(); 450 init_pci_config_tokens();
391 find_and_init_phbs(); 451 find_and_init_phbs();
392 pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb); 452 of_reconfig_notifier_register(&pci_dn_reconfig_nb);
393 453
394 pSeries_nvram_init(); 454 pSeries_nvram_init();
395 455
@@ -402,6 +462,14 @@ static void __init pSeries_setup_arch(void)
402 ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; 462 ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
403 else 463 else
404 ppc_md.enable_pmcs = power4_enable_pmcs; 464 ppc_md.enable_pmcs = power4_enable_pmcs;
465
466 if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
467 long rc;
468 if ((rc = pSeries_enable_reloc_on_exc()) != H_SUCCESS) {
469 pr_warn("Unable to enable relocation on exceptions: "
470 "%ld\n", rc);
471 }
472 }
405} 473}
406 474
407static int __init pSeries_init_panel(void) 475static int __init pSeries_init_panel(void)
@@ -659,4 +727,7 @@ define_machine(pseries) {
659 .progress = rtas_progress, 727 .progress = rtas_progress,
660 .system_reset_exception = pSeries_system_reset_exception, 728 .system_reset_exception = pSeries_system_reset_exception,
661 .machine_check_exception = pSeries_machine_check_exception, 729 .machine_check_exception = pSeries_machine_check_exception,
730#ifdef CONFIG_KEXEC
731 .machine_kexec = pSeries_machine_kexec,
732#endif
662}; 733};
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 71706bc34a0d..9fc0a4941908 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -38,7 +38,6 @@
38#include <asm/cputable.h> 38#include <asm/cputable.h>
39#include <asm/firmware.h> 39#include <asm/firmware.h>
40#include <asm/rtas.h> 40#include <asm/rtas.h>
41#include <asm/pSeries_reconfig.h>
42#include <asm/mpic.h> 41#include <asm/mpic.h>
43#include <asm/vdso_datapage.h> 42#include <asm/vdso_datapage.h>
44#include <asm/cputhreads.h> 43#include <asm/cputhreads.h>