aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2014-10-13 10:01:09 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2014-11-02 20:12:51 -0500
commit9178ba294b6839eeff1a91bed95515d783f3ee6c (patch)
tree61252a8808bba5208c7b7c0f0af31301278272de
parent0df1f2487d2f0d04703f142813d53615d62a1da4 (diff)
powerpc: Convert power off logic to pm_power_off
The generic Linux framework to power off the machine is a function pointer called pm_power_off. The trick about this pointer is that device drivers can potentially implement it rather than board files. Today on powerpc we set pm_power_off to invoke our generic full machine power off logic which then calls ppc_md.power_off to invoke machine specific power off. However, when we want to add a power off GPIO via the "gpio-poweroff" driver, this card house falls apart. That driver only registers itself if pm_power_off is NULL to ensure it doesn't override board specific logic. However, since we always set pm_power_off to the generic power off logic (which will just not power off the machine if no ppc_md.power_off call is implemented), we can't implement power off via the generic GPIO power off driver. To fix this up, let's get rid of the ppc_md.power_off logic and just always use pm_power_off as was intended. Then individual drivers such as the GPIO power off driver can implement power off logic via that function pointer. With this patch set applied and a few patches on top of QEMU that implement a power off GPIO on the virt e500 machine, I can successfully turn off my virtual machine after halt. Signed-off-by: Alexander Graf <agraf@suse.de> [mpe: Squash into one patch and update changelog based on cover letter] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/include/asm/machdep.h1
-rw-r--r--arch/powerpc/kernel/setup-common.c6
-rw-r--r--arch/powerpc/platforms/44x/ppc476.c2
-rw-r--r--arch/powerpc/platforms/52xx/efika.c3
-rw-r--r--arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c8
-rw-r--r--arch/powerpc/platforms/85xx/corenet_generic.c2
-rw-r--r--arch/powerpc/platforms/85xx/sgy_cts1000.c4
-rw-r--r--arch/powerpc/platforms/cell/celleb_setup.c4
-rw-r--r--arch/powerpc/platforms/cell/qpace_setup.c2
-rw-r--r--arch/powerpc/platforms/cell/setup.c2
-rw-r--r--arch/powerpc/platforms/chrp/setup.c3
-rw-r--r--arch/powerpc/platforms/embedded6xx/gamecube.c3
-rw-r--r--arch/powerpc/platforms/embedded6xx/linkstation.c4
-rw-r--r--arch/powerpc/platforms/embedded6xx/wii.c3
-rw-r--r--arch/powerpc/platforms/maple/setup.c4
-rw-r--r--arch/powerpc/platforms/powermac/setup.c3
-rw-r--r--arch/powerpc/platforms/powernv/setup.c4
-rw-r--r--arch/powerpc/platforms/ps3/setup.c2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c59
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c2
-rw-r--r--arch/powerpc/xmon/xmon.c3
21 files changed, 66 insertions, 58 deletions
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 307347f8ddbd..f15f15c92544 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -142,7 +142,6 @@ struct machdep_calls {
142#endif 142#endif
143 143
144 void (*restart)(char *cmd); 144 void (*restart)(char *cmd);
145 void (*power_off)(void);
146 void (*halt)(void); 145 void (*halt)(void);
147 void (*panic)(char *str); 146 void (*panic)(char *str);
148 void (*cpu_die)(void); 147 void (*cpu_die)(void);
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 1362cd62b3fa..44c8d03558ac 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -139,8 +139,8 @@ void machine_restart(char *cmd)
139void machine_power_off(void) 139void machine_power_off(void)
140{ 140{
141 machine_shutdown(); 141 machine_shutdown();
142 if (ppc_md.power_off) 142 if (pm_power_off)
143 ppc_md.power_off(); 143 pm_power_off();
144#ifdef CONFIG_SMP 144#ifdef CONFIG_SMP
145 smp_send_stop(); 145 smp_send_stop();
146#endif 146#endif
@@ -151,7 +151,7 @@ void machine_power_off(void)
151/* Used by the G5 thermal driver */ 151/* Used by the G5 thermal driver */
152EXPORT_SYMBOL_GPL(machine_power_off); 152EXPORT_SYMBOL_GPL(machine_power_off);
153 153
154void (*pm_power_off)(void) = machine_power_off; 154void (*pm_power_off)(void);
155EXPORT_SYMBOL_GPL(pm_power_off); 155EXPORT_SYMBOL_GPL(pm_power_off);
156 156
157void machine_halt(void) 157void machine_halt(void)
diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c
index 58db9d083969..c11ce6516c8f 100644
--- a/arch/powerpc/platforms/44x/ppc476.c
+++ b/arch/powerpc/platforms/44x/ppc476.c
@@ -94,7 +94,7 @@ static int avr_probe(struct i2c_client *client,
94{ 94{
95 avr_i2c_client = client; 95 avr_i2c_client = client;
96 ppc_md.restart = avr_reset_system; 96 ppc_md.restart = avr_reset_system;
97 ppc_md.power_off = avr_power_off_system; 97 pm_power_off = avr_power_off_system;
98 return 0; 98 return 0;
99} 99}
100 100
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index 3feffde9128d..6af651e69129 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -212,6 +212,8 @@ static int __init efika_probe(void)
212 DMA_MODE_READ = 0x44; 212 DMA_MODE_READ = 0x44;
213 DMA_MODE_WRITE = 0x48; 213 DMA_MODE_WRITE = 0x48;
214 214
215 pm_power_off = rtas_power_off;
216
215 return 1; 217 return 1;
216} 218}
217 219
@@ -225,7 +227,6 @@ define_machine(efika)
225 .init_IRQ = mpc52xx_init_irq, 227 .init_IRQ = mpc52xx_init_irq,
226 .get_irq = mpc52xx_get_irq, 228 .get_irq = mpc52xx_get_irq,
227 .restart = rtas_restart, 229 .restart = rtas_restart,
228 .power_off = rtas_power_off,
229 .halt = rtas_halt, 230 .halt = rtas_halt,
230 .set_rtc_time = rtas_set_rtc_time, 231 .set_rtc_time = rtas_set_rtc_time,
231 .get_rtc_time = rtas_get_rtc_time, 232 .get_rtc_time = rtas_get_rtc_time,
diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
index 463fa91ee5b6..15e8021ddef9 100644
--- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
+++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
@@ -167,10 +167,10 @@ static int mcu_probe(struct i2c_client *client, const struct i2c_device_id *id)
167 if (ret) 167 if (ret)
168 goto err; 168 goto err;
169 169
170 /* XXX: this is potentially racy, but there is no lock for ppc_md */ 170 /* XXX: this is potentially racy, but there is no lock for pm_power_off */
171 if (!ppc_md.power_off) { 171 if (!pm_power_off) {
172 glob_mcu = mcu; 172 glob_mcu = mcu;
173 ppc_md.power_off = mcu_power_off; 173 pm_power_off = mcu_power_off;
174 dev_info(&client->dev, "will provide power-off service\n"); 174 dev_info(&client->dev, "will provide power-off service\n");
175 } 175 }
176 176
@@ -197,7 +197,7 @@ static int mcu_remove(struct i2c_client *client)
197 device_remove_file(&client->dev, &dev_attr_status); 197 device_remove_file(&client->dev, &dev_attr_status);
198 198
199 if (glob_mcu == mcu) { 199 if (glob_mcu == mcu) {
200 ppc_md.power_off = NULL; 200 pm_power_off = NULL;
201 glob_mcu = NULL; 201 glob_mcu = NULL;
202 } 202 }
203 203
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index e56b89a792ed..1f309ccb096e 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -170,7 +170,7 @@ static int __init corenet_generic_probe(void)
170 170
171 ppc_md.get_irq = ehv_pic_get_irq; 171 ppc_md.get_irq = ehv_pic_get_irq;
172 ppc_md.restart = fsl_hv_restart; 172 ppc_md.restart = fsl_hv_restart;
173 ppc_md.power_off = fsl_hv_halt; 173 pm_power_off = fsl_hv_halt;
174 ppc_md.halt = fsl_hv_halt; 174 ppc_md.halt = fsl_hv_halt;
175#ifdef CONFIG_SMP 175#ifdef CONFIG_SMP
176 /* 176 /*
diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c
index 8162b0412117..e149c9ec26ae 100644
--- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
+++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
@@ -120,7 +120,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
120 120
121 /* Register our halt function */ 121 /* Register our halt function */
122 ppc_md.halt = gpio_halt_cb; 122 ppc_md.halt = gpio_halt_cb;
123 ppc_md.power_off = gpio_halt_cb; 123 pm_power_off = gpio_halt_cb;
124 124
125 printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" 125 printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
126 " irq).\n", gpio, trigger, irq); 126 " irq).\n", gpio, trigger, irq);
@@ -137,7 +137,7 @@ static int gpio_halt_remove(struct platform_device *pdev)
137 free_irq(irq, halt_node); 137 free_irq(irq, halt_node);
138 138
139 ppc_md.halt = NULL; 139 ppc_md.halt = NULL;
140 ppc_md.power_off = NULL; 140 pm_power_off = NULL;
141 141
142 gpio_free(gpio); 142 gpio_free(gpio);
143 143
diff --git a/arch/powerpc/platforms/cell/celleb_setup.c b/arch/powerpc/platforms/cell/celleb_setup.c
index 34e8ce2976aa..90be8ec51686 100644
--- a/arch/powerpc/platforms/cell/celleb_setup.c
+++ b/arch/powerpc/platforms/cell/celleb_setup.c
@@ -142,6 +142,7 @@ static int __init celleb_probe_beat(void)
142 powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS 142 powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS
143 | FW_FEATURE_BEAT | FW_FEATURE_LPAR; 143 | FW_FEATURE_BEAT | FW_FEATURE_LPAR;
144 hpte_init_beat_v3(); 144 hpte_init_beat_v3();
145 pm_power_off = beat_power_off;
145 146
146 return 1; 147 return 1;
147} 148}
@@ -190,6 +191,7 @@ static int __init celleb_probe_native(void)
190 191
191 powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS; 192 powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS;
192 hpte_init_native(); 193 hpte_init_native();
194 pm_power_off = rtas_power_off;
193 195
194 return 1; 196 return 1;
195} 197}
@@ -204,7 +206,6 @@ define_machine(celleb_beat) {
204 .setup_arch = celleb_setup_arch_beat, 206 .setup_arch = celleb_setup_arch_beat,
205 .show_cpuinfo = celleb_show_cpuinfo, 207 .show_cpuinfo = celleb_show_cpuinfo,
206 .restart = beat_restart, 208 .restart = beat_restart,
207 .power_off = beat_power_off,
208 .halt = beat_halt, 209 .halt = beat_halt,
209 .get_rtc_time = beat_get_rtc_time, 210 .get_rtc_time = beat_get_rtc_time,
210 .set_rtc_time = beat_set_rtc_time, 211 .set_rtc_time = beat_set_rtc_time,
@@ -230,7 +231,6 @@ define_machine(celleb_native) {
230 .setup_arch = celleb_setup_arch_native, 231 .setup_arch = celleb_setup_arch_native,
231 .show_cpuinfo = celleb_show_cpuinfo, 232 .show_cpuinfo = celleb_show_cpuinfo,
232 .restart = rtas_restart, 233 .restart = rtas_restart,
233 .power_off = rtas_power_off,
234 .halt = rtas_halt, 234 .halt = rtas_halt,
235 .get_boot_time = rtas_get_boot_time, 235 .get_boot_time = rtas_get_boot_time,
236 .get_rtc_time = rtas_get_rtc_time, 236 .get_rtc_time = rtas_get_rtc_time,
diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c
index 6e3409d590ac..d328140dc6f5 100644
--- a/arch/powerpc/platforms/cell/qpace_setup.c
+++ b/arch/powerpc/platforms/cell/qpace_setup.c
@@ -127,6 +127,7 @@ static int __init qpace_probe(void)
127 return 0; 127 return 0;
128 128
129 hpte_init_native(); 129 hpte_init_native();
130 pm_power_off = rtas_power_off;
130 131
131 return 1; 132 return 1;
132} 133}
@@ -137,7 +138,6 @@ define_machine(qpace) {
137 .setup_arch = qpace_setup_arch, 138 .setup_arch = qpace_setup_arch,
138 .show_cpuinfo = qpace_show_cpuinfo, 139 .show_cpuinfo = qpace_show_cpuinfo,
139 .restart = rtas_restart, 140 .restart = rtas_restart,
140 .power_off = rtas_power_off,
141 .halt = rtas_halt, 141 .halt = rtas_halt,
142 .get_boot_time = rtas_get_boot_time, 142 .get_boot_time = rtas_get_boot_time,
143 .get_rtc_time = rtas_get_rtc_time, 143 .get_rtc_time = rtas_get_rtc_time,
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 6ae25fb62015..d62aa982d530 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -259,6 +259,7 @@ static int __init cell_probe(void)
259 return 0; 259 return 0;
260 260
261 hpte_init_native(); 261 hpte_init_native();
262 pm_power_off = rtas_power_off;
262 263
263 return 1; 264 return 1;
264} 265}
@@ -269,7 +270,6 @@ define_machine(cell) {
269 .setup_arch = cell_setup_arch, 270 .setup_arch = cell_setup_arch,
270 .show_cpuinfo = cell_show_cpuinfo, 271 .show_cpuinfo = cell_show_cpuinfo,
271 .restart = rtas_restart, 272 .restart = rtas_restart,
272 .power_off = rtas_power_off,
273 .halt = rtas_halt, 273 .halt = rtas_halt,
274 .get_boot_time = rtas_get_boot_time, 274 .get_boot_time = rtas_get_boot_time,
275 .get_rtc_time = rtas_get_rtc_time, 275 .get_rtc_time = rtas_get_rtc_time,
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 5b77b1919fd2..860a59eb8ea2 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -585,6 +585,8 @@ static int __init chrp_probe(void)
585 DMA_MODE_READ = 0x44; 585 DMA_MODE_READ = 0x44;
586 DMA_MODE_WRITE = 0x48; 586 DMA_MODE_WRITE = 0x48;
587 587
588 pm_power_off = rtas_power_off;
589
588 return 1; 590 return 1;
589} 591}
590 592
@@ -597,7 +599,6 @@ define_machine(chrp) {
597 .show_cpuinfo = chrp_show_cpuinfo, 599 .show_cpuinfo = chrp_show_cpuinfo,
598 .init_IRQ = chrp_init_IRQ, 600 .init_IRQ = chrp_init_IRQ,
599 .restart = rtas_restart, 601 .restart = rtas_restart,
600 .power_off = rtas_power_off,
601 .halt = rtas_halt, 602 .halt = rtas_halt,
602 .time_init = chrp_time_init, 603 .time_init = chrp_time_init,
603 .set_rtc_time = chrp_set_rtc_time, 604 .set_rtc_time = chrp_set_rtc_time,
diff --git a/arch/powerpc/platforms/embedded6xx/gamecube.c b/arch/powerpc/platforms/embedded6xx/gamecube.c
index bd4ba5d7d568..fe0ed6ee285e 100644
--- a/arch/powerpc/platforms/embedded6xx/gamecube.c
+++ b/arch/powerpc/platforms/embedded6xx/gamecube.c
@@ -67,6 +67,8 @@ static int __init gamecube_probe(void)
67 if (!of_flat_dt_is_compatible(dt_root, "nintendo,gamecube")) 67 if (!of_flat_dt_is_compatible(dt_root, "nintendo,gamecube"))
68 return 0; 68 return 0;
69 69
70 pm_power_off = gamecube_power_off;
71
70 return 1; 72 return 1;
71} 73}
72 74
@@ -80,7 +82,6 @@ define_machine(gamecube) {
80 .probe = gamecube_probe, 82 .probe = gamecube_probe,
81 .init_early = gamecube_init_early, 83 .init_early = gamecube_init_early,
82 .restart = gamecube_restart, 84 .restart = gamecube_restart,
83 .power_off = gamecube_power_off,
84 .halt = gamecube_halt, 85 .halt = gamecube_halt,
85 .init_IRQ = flipper_pic_probe, 86 .init_IRQ = flipper_pic_probe,
86 .get_irq = flipper_pic_get_irq, 87 .get_irq = flipper_pic_get_irq,
diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c
index 168e1d80b2e5..540eeb58d3f0 100644
--- a/arch/powerpc/platforms/embedded6xx/linkstation.c
+++ b/arch/powerpc/platforms/embedded6xx/linkstation.c
@@ -147,6 +147,9 @@ static int __init linkstation_probe(void)
147 147
148 if (!of_flat_dt_is_compatible(root, "linkstation")) 148 if (!of_flat_dt_is_compatible(root, "linkstation"))
149 return 0; 149 return 0;
150
151 pm_power_off = linkstation_power_off;
152
150 return 1; 153 return 1;
151} 154}
152 155
@@ -158,7 +161,6 @@ define_machine(linkstation){
158 .show_cpuinfo = linkstation_show_cpuinfo, 161 .show_cpuinfo = linkstation_show_cpuinfo,
159 .get_irq = mpic_get_irq, 162 .get_irq = mpic_get_irq,
160 .restart = linkstation_restart, 163 .restart = linkstation_restart,
161 .power_off = linkstation_power_off,
162 .halt = linkstation_halt, 164 .halt = linkstation_halt,
163 .calibrate_decr = generic_calibrate_decr, 165 .calibrate_decr = generic_calibrate_decr,
164}; 166};
diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c
index 388e29bab8f6..352592d3e44e 100644
--- a/arch/powerpc/platforms/embedded6xx/wii.c
+++ b/arch/powerpc/platforms/embedded6xx/wii.c
@@ -211,6 +211,8 @@ static int __init wii_probe(void)
211 if (!of_flat_dt_is_compatible(dt_root, "nintendo,wii")) 211 if (!of_flat_dt_is_compatible(dt_root, "nintendo,wii"))
212 return 0; 212 return 0;
213 213
214 pm_power_off = wii_power_off;
215
214 return 1; 216 return 1;
215} 217}
216 218
@@ -226,7 +228,6 @@ define_machine(wii) {
226 .init_early = wii_init_early, 228 .init_early = wii_init_early,
227 .setup_arch = wii_setup_arch, 229 .setup_arch = wii_setup_arch,
228 .restart = wii_restart, 230 .restart = wii_restart,
229 .power_off = wii_power_off,
230 .halt = wii_halt, 231 .halt = wii_halt,
231 .init_IRQ = wii_pic_probe, 232 .init_IRQ = wii_pic_probe,
232 .get_irq = flipper_pic_get_irq, 233 .get_irq = flipper_pic_get_irq,
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index cb1b0b35a0c6..56b85cd61aaf 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -169,7 +169,7 @@ static void __init maple_use_rtas_reboot_and_halt_if_present(void)
169 if (rtas_service_present("system-reboot") && 169 if (rtas_service_present("system-reboot") &&
170 rtas_service_present("power-off")) { 170 rtas_service_present("power-off")) {
171 ppc_md.restart = rtas_restart; 171 ppc_md.restart = rtas_restart;
172 ppc_md.power_off = rtas_power_off; 172 pm_power_off = rtas_power_off;
173 ppc_md.halt = rtas_halt; 173 ppc_md.halt = rtas_halt;
174 } 174 }
175} 175}
@@ -312,6 +312,7 @@ static int __init maple_probe(void)
312 alloc_dart_table(); 312 alloc_dart_table();
313 313
314 hpte_init_native(); 314 hpte_init_native();
315 pm_power_off = maple_power_off;
315 316
316 return 1; 317 return 1;
317} 318}
@@ -325,7 +326,6 @@ define_machine(maple) {
325 .pci_irq_fixup = maple_pci_irq_fixup, 326 .pci_irq_fixup = maple_pci_irq_fixup,
326 .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, 327 .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
327 .restart = maple_restart, 328 .restart = maple_restart,
328 .power_off = maple_power_off,
329 .halt = maple_halt, 329 .halt = maple_halt,
330 .get_boot_time = maple_get_boot_time, 330 .get_boot_time = maple_get_boot_time,
331 .set_rtc_time = maple_set_rtc_time, 331 .set_rtc_time = maple_set_rtc_time,
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index b127a29ac526..713d36d45d1d 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -632,6 +632,8 @@ static int __init pmac_probe(void)
632 smu_cmdbuf_abs = memblock_alloc_base(4096, 4096, 0x80000000UL); 632 smu_cmdbuf_abs = memblock_alloc_base(4096, 4096, 0x80000000UL);
633#endif /* CONFIG_PMAC_SMU */ 633#endif /* CONFIG_PMAC_SMU */
634 634
635 pm_power_off = pmac_power_off;
636
635 return 1; 637 return 1;
636} 638}
637 639
@@ -663,7 +665,6 @@ define_machine(powermac) {
663 .get_irq = NULL, /* changed later */ 665 .get_irq = NULL, /* changed later */
664 .pci_irq_fixup = pmac_pci_irq_fixup, 666 .pci_irq_fixup = pmac_pci_irq_fixup,
665 .restart = pmac_restart, 667 .restart = pmac_restart,
666 .power_off = pmac_power_off,
667 .halt = pmac_halt, 668 .halt = pmac_halt,
668 .time_init = pmac_time_init, 669 .time_init = pmac_time_init,
669 .get_boot_time = pmac_get_boot_time, 670 .get_boot_time = pmac_get_boot_time,
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 3f9546d8a51f..941831d67cb2 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -268,7 +268,7 @@ static void __init pnv_setup_machdep_opal(void)
268 ppc_md.get_rtc_time = opal_get_rtc_time; 268 ppc_md.get_rtc_time = opal_get_rtc_time;
269 ppc_md.set_rtc_time = opal_set_rtc_time; 269 ppc_md.set_rtc_time = opal_set_rtc_time;
270 ppc_md.restart = pnv_restart; 270 ppc_md.restart = pnv_restart;
271 ppc_md.power_off = pnv_power_off; 271 pm_power_off = pnv_power_off;
272 ppc_md.halt = pnv_halt; 272 ppc_md.halt = pnv_halt;
273 ppc_md.machine_check_exception = opal_machine_check; 273 ppc_md.machine_check_exception = opal_machine_check;
274 ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery; 274 ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery;
@@ -285,7 +285,7 @@ static void __init pnv_setup_machdep_rtas(void)
285 ppc_md.set_rtc_time = rtas_set_rtc_time; 285 ppc_md.set_rtc_time = rtas_set_rtc_time;
286 } 286 }
287 ppc_md.restart = rtas_restart; 287 ppc_md.restart = rtas_restart;
288 ppc_md.power_off = rtas_power_off; 288 pm_power_off = rtas_power_off;
289 ppc_md.halt = rtas_halt; 289 ppc_md.halt = rtas_halt;
290} 290}
291#endif /* CONFIG_PPC_POWERNV_RTAS */ 291#endif /* CONFIG_PPC_POWERNV_RTAS */
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 3f509f86432c..009a2004b876 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -248,6 +248,7 @@ static int __init ps3_probe(void)
248 ps3_mm_init(); 248 ps3_mm_init();
249 ps3_mm_vas_create(&htab_size); 249 ps3_mm_vas_create(&htab_size);
250 ps3_hpte_init(htab_size); 250 ps3_hpte_init(htab_size);
251 pm_power_off = ps3_power_off;
251 252
252 DBG(" <- %s:%d\n", __func__, __LINE__); 253 DBG(" <- %s:%d\n", __func__, __LINE__);
253 return 1; 254 return 1;
@@ -278,7 +279,6 @@ define_machine(ps3) {
278 .calibrate_decr = ps3_calibrate_decr, 279 .calibrate_decr = ps3_calibrate_decr,
279 .progress = ps3_progress, 280 .progress = ps3_progress,
280 .restart = ps3_restart, 281 .restart = ps3_restart,
281 .power_off = ps3_power_off,
282 .halt = ps3_halt, 282 .halt = ps3_halt,
283#if defined(CONFIG_KEXEC) 283#if defined(CONFIG_KEXEC)
284 .kexec_cpu_down = ps3_kexec_cpu_down, 284 .kexec_cpu_down = ps3_kexec_cpu_down,
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 125c589eeef5..db0fc0c07568 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -659,6 +659,34 @@ static void __init pSeries_init_early(void)
659 pr_debug(" <- pSeries_init_early()\n"); 659 pr_debug(" <- pSeries_init_early()\n");
660} 660}
661 661
662/**
663 * pseries_power_off - tell firmware about how to power off the system.
664 *
665 * This function calls either the power-off rtas token in normal cases
666 * or the ibm,power-off-ups token (if present & requested) in case of
667 * a power failure. If power-off token is used, power on will only be
668 * possible with power button press. If ibm,power-off-ups token is used
669 * it will allow auto poweron after power is restored.
670 */
671static void pseries_power_off(void)
672{
673 int rc;
674 int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups");
675
676 if (rtas_flash_term_hook)
677 rtas_flash_term_hook(SYS_POWER_OFF);
678
679 if (rtas_poweron_auto == 0 ||
680 rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) {
681 rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
682 printk(KERN_INFO "RTAS power-off returned %d\n", rc);
683 } else {
684 rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL);
685 printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc);
686 }
687 for (;;);
688}
689
662/* 690/*
663 * Called very early, MMU is off, device-tree isn't unflattened 691 * Called very early, MMU is off, device-tree isn't unflattened
664 */ 692 */
@@ -741,6 +769,8 @@ static int __init pSeries_probe(void)
741 else 769 else
742 hpte_init_native(); 770 hpte_init_native();
743 771
772 pm_power_off = pseries_power_off;
773
744 pr_debug("Machine is%s LPAR !\n", 774 pr_debug("Machine is%s LPAR !\n",
745 (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not"); 775 (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not");
746 776
@@ -754,34 +784,6 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus)
754 return PCI_PROBE_NORMAL; 784 return PCI_PROBE_NORMAL;
755} 785}
756 786
757/**
758 * pSeries_power_off - tell firmware about how to power off the system.
759 *
760 * This function calls either the power-off rtas token in normal cases
761 * or the ibm,power-off-ups token (if present & requested) in case of
762 * a power failure. If power-off token is used, power on will only be
763 * possible with power button press. If ibm,power-off-ups token is used
764 * it will allow auto poweron after power is restored.
765 */
766static void pSeries_power_off(void)
767{
768 int rc;
769 int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups");
770
771 if (rtas_flash_term_hook)
772 rtas_flash_term_hook(SYS_POWER_OFF);
773
774 if (rtas_poweron_auto == 0 ||
775 rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) {
776 rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
777 printk(KERN_INFO "RTAS power-off returned %d\n", rc);
778 } else {
779 rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL);
780 printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc);
781 }
782 for (;;);
783}
784
785#ifndef CONFIG_PCI 787#ifndef CONFIG_PCI
786void pSeries_final_fixup(void) { } 788void pSeries_final_fixup(void) { }
787#endif 789#endif
@@ -796,7 +798,6 @@ define_machine(pseries) {
796 .pcibios_fixup = pSeries_final_fixup, 798 .pcibios_fixup = pSeries_final_fixup,
797 .pci_probe_mode = pSeries_pci_probe_mode, 799 .pci_probe_mode = pSeries_pci_probe_mode,
798 .restart = rtas_restart, 800 .restart = rtas_restart,
799 .power_off = pSeries_power_off,
800 .halt = rtas_halt, 801 .halt = rtas_halt,
801 .panic = rtas_os_term, 802 .panic = rtas_os_term,
802 .get_boot_time = rtas_get_boot_time, 803 .get_boot_time = rtas_get_boot_time,
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index ffd1169ebaab..1e04568da3b9 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -238,7 +238,7 @@ void fsl_hv_restart(char *cmd)
238/* 238/*
239 * Halt the current partition 239 * Halt the current partition
240 * 240 *
241 * This function should be assigned to the ppc_md.power_off and ppc_md.halt 241 * This function should be assigned to the pm_power_off and ppc_md.halt
242 * function pointers, to shut down the partition when we're running under 242 * function pointers, to shut down the partition when we're running under
243 * the Freescale hypervisor. 243 * the Freescale hypervisor.
244 */ 244 */
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index b988b5addf86..506d25681fe3 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -981,7 +981,8 @@ static void bootcmds(void)
981 else if (cmd == 'h') 981 else if (cmd == 'h')
982 ppc_md.halt(); 982 ppc_md.halt();
983 else if (cmd == 'p') 983 else if (cmd == 'p')
984 ppc_md.power_off(); 984 if (pm_power_off)
985 pm_power_off();
985} 986}
986 987
987static int cpu_cmd(void) 988static int cpu_cmd(void)