diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2005-06-23 03:14:39 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-06-23 03:14:39 -0400 |
commit | d7152fe14cad075d6dd4ee4194acd131aed0244e (patch) | |
tree | eb814e3a04b0ca396eed9b1c1d30ebb3a667daff /arch/ppc64 | |
parent | dad32bbf43b496bcd32a83f73a1e7fd0a02cfd3e (diff) |
[PATCH] Maple powerdown patch
Currently reset and powerdown are not implemented on the Maple board,
and attempting to do so will (incorrectly return). This implements
the proper communication with the service processor, allowing correct
reset and powerdown on the Maple board, by communicating with the
service processor. If somehow it's unable to communicate with the
service processor it will loop forever instead.
Note that powerdown on the Maple will power down the CPUs, but not the
fans or other board components due to hardware and firmware
limitations.
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Frank Rowand <frowand@mvista.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/ppc64')
-rw-r--r-- | arch/ppc64/kernel/maple_setup.c | 62 | ||||
-rw-r--r-- | arch/ppc64/kernel/setup.c | 18 |
2 files changed, 79 insertions, 1 deletions
diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c index 3dabedb8553b..da8900b51f40 100644 --- a/arch/ppc64/kernel/maple_setup.c +++ b/arch/ppc64/kernel/maple_setup.c | |||
@@ -78,17 +78,77 @@ extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel); | |||
78 | extern void generic_find_legacy_serial_ports(u64 *physport, | 78 | extern void generic_find_legacy_serial_ports(u64 *physport, |
79 | unsigned int *default_speed); | 79 | unsigned int *default_speed); |
80 | 80 | ||
81 | |||
82 | static void maple_restart(char *cmd) | 81 | static void maple_restart(char *cmd) |
83 | { | 82 | { |
83 | unsigned int maple_nvram_base; | ||
84 | unsigned int maple_nvram_offset; | ||
85 | unsigned int maple_nvram_command; | ||
86 | struct device_node *rtcs; | ||
87 | |||
88 | /* find NVRAM device */ | ||
89 | rtcs = find_compatible_devices("nvram", "AMD8111"); | ||
90 | if (rtcs && rtcs->addrs) { | ||
91 | maple_nvram_base = rtcs->addrs[0].address; | ||
92 | } else { | ||
93 | printk(KERN_EMERG "Maple: Unable to find NVRAM\n"); | ||
94 | printk(KERN_EMERG "Maple: Manual Restart Required\n"); | ||
95 | return; | ||
96 | } | ||
97 | |||
98 | /* find service processor device */ | ||
99 | rtcs = find_devices("service-processor"); | ||
100 | if (!rtcs) { | ||
101 | printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); | ||
102 | printk(KERN_EMERG "Maple: Manual Restart Required\n"); | ||
103 | return; | ||
104 | } | ||
105 | maple_nvram_offset = *(unsigned int*) get_property(rtcs, | ||
106 | "restart-addr", NULL); | ||
107 | maple_nvram_command = *(unsigned int*) get_property(rtcs, | ||
108 | "restart-value", NULL); | ||
109 | |||
110 | /* send command */ | ||
111 | outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); | ||
112 | for (;;) ; | ||
84 | } | 113 | } |
85 | 114 | ||
86 | static void maple_power_off(void) | 115 | static void maple_power_off(void) |
87 | { | 116 | { |
117 | unsigned int maple_nvram_base; | ||
118 | unsigned int maple_nvram_offset; | ||
119 | unsigned int maple_nvram_command; | ||
120 | struct device_node *rtcs; | ||
121 | |||
122 | /* find NVRAM device */ | ||
123 | rtcs = find_compatible_devices("nvram", "AMD8111"); | ||
124 | if (rtcs && rtcs->addrs) { | ||
125 | maple_nvram_base = rtcs->addrs[0].address; | ||
126 | } else { | ||
127 | printk(KERN_EMERG "Maple: Unable to find NVRAM\n"); | ||
128 | printk(KERN_EMERG "Maple: Manual Power-Down Required\n"); | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | /* find service processor device */ | ||
133 | rtcs = find_devices("service-processor"); | ||
134 | if (!rtcs) { | ||
135 | printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); | ||
136 | printk(KERN_EMERG "Maple: Manual Power-Down Required\n"); | ||
137 | return; | ||
138 | } | ||
139 | maple_nvram_offset = *(unsigned int*) get_property(rtcs, | ||
140 | "power-off-addr", NULL); | ||
141 | maple_nvram_command = *(unsigned int*) get_property(rtcs, | ||
142 | "power-off-value", NULL); | ||
143 | |||
144 | /* send command */ | ||
145 | outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); | ||
146 | for (;;) ; | ||
88 | } | 147 | } |
89 | 148 | ||
90 | static void maple_halt(void) | 149 | static void maple_halt(void) |
91 | { | 150 | { |
151 | maple_power_off(); | ||
92 | } | 152 | } |
93 | 153 | ||
94 | #ifdef CONFIG_SMP | 154 | #ifdef CONFIG_SMP |
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 8a1ca695f8a7..7d060ddb5e93 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c | |||
@@ -683,6 +683,12 @@ void machine_restart(char *cmd) | |||
683 | if (ppc_md.nvram_sync) | 683 | if (ppc_md.nvram_sync) |
684 | ppc_md.nvram_sync(); | 684 | ppc_md.nvram_sync(); |
685 | ppc_md.restart(cmd); | 685 | ppc_md.restart(cmd); |
686 | #ifdef CONFIG_SMP | ||
687 | smp_send_stop(); | ||
688 | #endif | ||
689 | printk(KERN_EMERG "System Halted, OK to turn off power\n"); | ||
690 | local_irq_disable(); | ||
691 | while (1) ; | ||
686 | } | 692 | } |
687 | 693 | ||
688 | EXPORT_SYMBOL(machine_restart); | 694 | EXPORT_SYMBOL(machine_restart); |
@@ -692,6 +698,12 @@ void machine_power_off(void) | |||
692 | if (ppc_md.nvram_sync) | 698 | if (ppc_md.nvram_sync) |
693 | ppc_md.nvram_sync(); | 699 | ppc_md.nvram_sync(); |
694 | ppc_md.power_off(); | 700 | ppc_md.power_off(); |
701 | #ifdef CONFIG_SMP | ||
702 | smp_send_stop(); | ||
703 | #endif | ||
704 | printk(KERN_EMERG "System Halted, OK to turn off power\n"); | ||
705 | local_irq_disable(); | ||
706 | while (1) ; | ||
695 | } | 707 | } |
696 | 708 | ||
697 | EXPORT_SYMBOL(machine_power_off); | 709 | EXPORT_SYMBOL(machine_power_off); |
@@ -701,6 +713,12 @@ void machine_halt(void) | |||
701 | if (ppc_md.nvram_sync) | 713 | if (ppc_md.nvram_sync) |
702 | ppc_md.nvram_sync(); | 714 | ppc_md.nvram_sync(); |
703 | ppc_md.halt(); | 715 | ppc_md.halt(); |
716 | #ifdef CONFIG_SMP | ||
717 | smp_send_stop(); | ||
718 | #endif | ||
719 | printk(KERN_EMERG "System Halted, OK to turn off power\n"); | ||
720 | local_irq_disable(); | ||
721 | while (1) ; | ||
704 | } | 722 | } |
705 | 723 | ||
706 | EXPORT_SYMBOL(machine_halt); | 724 | EXPORT_SYMBOL(machine_halt); |