Commit c22f5d5b authored by Michael Weber's avatar Michael Weber Committed by David S. Miller

sparc64: Use SUNW,power-off to power off some Ultra systems.

parent e1dccf46
......@@ -34,20 +34,28 @@ static void power_handler(int irq, void *dev_id, struct pt_regs *regs)
#endif /* CONFIG_PCI */
extern void machine_halt(void);
extern void machine_alt_power_off(void);
static void (*poweroff_method)(void) = machine_alt_power_off;
extern int serial_console;
void machine_power_off(void)
{
if (!serial_console) {
#ifdef CONFIG_PCI
if (power_reg != 0UL && !serial_console) {
/* Both register bits seem to have the
* same effect, so until I figure out
* what the difference is...
*/
writel(POWER_COURTESY_OFF | POWER_SYSTEM_OFF, power_reg);
}
if (power_reg != 0UL) {
/* Both register bits seem to have the
* same effect, so until I figure out
* what the difference is...
*/
writel(POWER_COURTESY_OFF | POWER_SYSTEM_OFF, power_reg);
} else
#endif /* CONFIG_PCI */
if (poweroff_method != NULL) {
poweroff_method();
/* not reached */
}
}
machine_halt();
}
......@@ -98,6 +106,7 @@ void __init power_init(void)
found:
power_reg = (unsigned long)ioremap(edev->resource[0].start, 0x4);
printk("power: Control reg at %016lx ... ", power_reg);
poweroff_method = machine_halt; /* able to use the standard halt */
if (edev->irqs[0] != PCI_IRQ_NONE) {
if (kernel_thread(powerd, 0, CLONE_FS) < 0) {
printk("Failed to start power daemon.\n");
......
......@@ -142,6 +142,21 @@ void machine_halt(void)
panic("Halt failed!");
}
void machine_alt_power_off(void)
{
sti();
mdelay(8);
cli();
#ifdef CONFIG_SUN_CONSOLE
if (!serial_console && prom_palette)
prom_palette(1);
#endif
if (prom_keyboard)
prom_keyboard();
prom_halt_power_off();
panic("Power-off failed!");
}
void machine_restart(char * cmd)
{
char *p;
......
......@@ -97,6 +97,19 @@ prom_halt(void)
goto again; /* PROM is out to get me -DaveM */
}
void
prom_halt_power_off(void)
{
#ifdef CONFIG_SMP
smp_promstop_others();
udelay(8000);
#endif
p1275_cmd ("SUNW,power-off", P1275_INOUT(0,0));
/* if nothing else helps, we just halt */
prom_halt ();
}
/* Set prom sync handler to call function 'funcp'. */
void
prom_setcallback(callback_func_t funcp)
......
......@@ -113,6 +113,9 @@ extern void prom_cmdline(void);
*/
extern void prom_halt(void) __attribute__ ((noreturn));
/* Halt and power-off the machine. */
extern void prom_halt_power_off(void) __attribute__ ((noreturn));
/* Set the PROM 'sync' callback function to the passed function pointer.
* When the user gives the 'sync' command at the prom prompt while the
* kernel is still active, the prom will call this routine.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment