[PATCH] ppc64: do not return from maple halt, power off, restart

Frank Rowand frowand at mvista.com
Wed Jun 8 07:43:54 EST 2005


I updated David Gibson's patch to reflect the comments on the list.

I tested this patch on linux-2.6.12-rc6.


Benjamin Herrenschmidt wrote:
<snip>
>>maple_halt() should do the same thing as maple_power_off().  (It could
>>even just call maple_power_off().)
> 
> 
> That's debatable... lots of people claim that halt() should just ...
> halt the kernel and not power off the computer :) I would personally
> have it do power off, but since that doesn't work ...

I changed maple_halt() to call maple_power_off(), to be consistent
with the other ppc64 halt functions.  If someone changed it to
just halt, it wouldn't bother me.

>>maple_restart(), maple_power_off(), and maple_halt() should not ever
>>return.  The returns could be replaced with the code from my patch
>>that started this thread.
> 
> 
> I think the "return" case should be handled at the toplevel function in
> setup.c that calls ppc_md.

Good idea.  I updated setup.c to catch the return case for restart,
power down, and halt.  I used "#ifdef CONFIG_SMP" instead of adding
a null smp_send_stop() to include/smp.h.  This #ifdef is already
used in several other places in setup.c.

I also changed the printk()s in David's patch from KERN_INFO to
KERN_EMERG to match the shutdown messages in kernel/sys.c.

How does this version of the patch look to everyone?

-Frank


Signed-off-by: Frank Rowand <frowand at mvista.com>
Signed-off-by: David Gibson <dwg at au1.ibm.com>

===== maple_setup.c 1.5 vs edited =====

Index: linux-2.6.12-rc6/arch/ppc64/kernel/maple_setup.c
===================================================================
--- linux-2.6.12-rc6.orig/arch/ppc64/kernel/maple_setup.c
+++ linux-2.6.12-rc6/arch/ppc64/kernel/maple_setup.c
@@ -78,17 +78,77 @@ extern int maple_pci_get_legacy_ide_irq(
 extern void generic_find_legacy_serial_ports(u64 *physport,
 		unsigned int *default_speed);
 
-
 static void maple_restart(char *cmd)
 {
+	unsigned int maple_nvram_base;
+	unsigned int maple_nvram_offset;
+	unsigned int maple_nvram_command;
+	struct device_node *rtcs;
+
+	/* find NVRAM device */
+	rtcs = find_compatible_devices("nvram", "AMD8111");
+	if (rtcs && rtcs->addrs) {
+		maple_nvram_base = rtcs->addrs[0].address;
+	} else {
+		printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
+		printk(KERN_EMERG "Maple: Manual Restart Required\n");
+		return;
+	}
+
+	/* find service processor device */
+	rtcs = find_devices("service-processor");
+	if (!rtcs) {
+		printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
+		printk(KERN_EMERG "Maple: Manual Restart Required\n");
+		return;
+	}
+	maple_nvram_offset = *(unsigned int*) get_property(rtcs,
+			"restart-addr", NULL);
+	maple_nvram_command = *(unsigned int*) get_property(rtcs,
+			"restart-value", NULL);
+
+	/* send command */
+	outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
+	for (;;) ;
 }
 
 static void maple_power_off(void)
 {
+	unsigned int maple_nvram_base;
+	unsigned int maple_nvram_offset;
+	unsigned int maple_nvram_command;
+	struct device_node *rtcs;
+
+	/* find NVRAM device */
+	rtcs = find_compatible_devices("nvram", "AMD8111");
+	if (rtcs && rtcs->addrs) {
+		maple_nvram_base = rtcs->addrs[0].address;
+	} else {
+		printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
+		printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
+		return;
+	}
+
+	/* find service processor device */
+	rtcs = find_devices("service-processor");
+	if (!rtcs) {
+		printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
+		printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
+		return;
+	}
+	maple_nvram_offset = *(unsigned int*) get_property(rtcs,
+			"power-off-addr", NULL);
+	maple_nvram_command = *(unsigned int*) get_property(rtcs,
+			"power-off-value", NULL);
+
+	/* send command */
+	outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
+	for (;;) ;
 }
 
 static void maple_halt(void)
 {
+	maple_power_off();
 }
 
 #ifdef CONFIG_SMP
Index: linux-2.6.12-rc6/arch/ppc64/kernel/setup.c
===================================================================
--- linux-2.6.12-rc6.orig/arch/ppc64/kernel/setup.c
+++ linux-2.6.12-rc6/arch/ppc64/kernel/setup.c
@@ -678,6 +678,12 @@ void machine_restart(char *cmd)
 	if (ppc_md.nvram_sync)
 		ppc_md.nvram_sync();
 	ppc_md.restart(cmd);
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+	local_irq_disable();
+	while (1) ;
 }
 
 EXPORT_SYMBOL(machine_restart);
@@ -687,6 +693,12 @@ void machine_power_off(void)
 	if (ppc_md.nvram_sync)
 		ppc_md.nvram_sync();
 	ppc_md.power_off();
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+	local_irq_disable();
+	while (1) ;
 }
 
 EXPORT_SYMBOL(machine_power_off);
@@ -696,6 +708,12 @@ void machine_halt(void)
 	if (ppc_md.nvram_sync)
 		ppc_md.nvram_sync();
 	ppc_md.halt();
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+	local_irq_disable();
+	while (1) ;
 }
 
 EXPORT_SYMBOL(machine_halt);



More information about the Linuxppc64-dev mailing list