diff options
author | Thibaut Varene <varenet@parisc-linux.org> | 2006-05-03 19:27:35 -0400 |
---|---|---|
committer | Kyle McMartin <kyle@hera.kernel.org> | 2006-06-27 19:28:37 -0400 |
commit | 8ffaeaf42e91930888df09d696a8a6ebe056d0e0 (patch) | |
tree | 7b1785ccab10b69c06f91184e382f8d96b1cc04d | |
parent | c95f2e5f2f6f61d734a025414c9eb81872a5c831 (diff) |
[PARISC] PDC_CHASSIS is implemented on all machines
This patch removes a limitation of the original code, so that CHASSIS
codes can be sent to all machines. On machines with a LCD panel, this
code displays "INI" during bootup, "RUN" when the system is booted and
running, "FLT" when a panic occurs, etc.
This part of the code can be enabled/disabled through CONFIG_PDC_CHASSIS
This patch also adds minimalistic support for Chassis warnings, through
a proc entry '/proc/chassis', which will reflect the warnings status (PSU
or fans failure when they happen, NVRAM battery level and temperature
thresholds overflows).
This part of the code can be enabled/disabled through CONFIG_PDC_CHASSIS_WARN
Signed-off-by: Thibaut VARENE <varenet@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
-rw-r--r-- | arch/parisc/kernel/firmware.c | 22 | ||||
-rw-r--r-- | arch/parisc/kernel/pdc_chassis.c | 73 | ||||
-rw-r--r-- | drivers/parisc/Kconfig | 33 | ||||
-rw-r--r-- | include/asm-parisc/pdc.h | 1 |
4 files changed, 107 insertions, 22 deletions
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 2dc06b8e1817..0596f27340cc 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) | 11 | * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) |
12 | * Copyright 2003 Grant Grundler <grundler parisc-linux org> | 12 | * Copyright 2003 Grant Grundler <grundler parisc-linux org> |
13 | * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org> | 13 | * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org> |
14 | * Copyright 2004 Thibaut VARENE <varenet@parisc-linux.org> | 14 | * Copyright 2004,2006 Thibaut VARENE <varenet@parisc-linux.org> |
15 | * | 15 | * |
16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
17 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
@@ -252,10 +252,8 @@ int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) | |||
252 | #endif | 252 | #endif |
253 | 253 | ||
254 | /** | 254 | /** |
255 | * pdc_chassis_disp - Updates display | 255 | * pdc_chassis_disp - Updates chassis code |
256 | * @retval: -1 on error, 0 on success | 256 | * @retval: -1 on error, 0 on success |
257 | * | ||
258 | * Works on old PDC only (E class, others?) | ||
259 | */ | 257 | */ |
260 | int pdc_chassis_disp(unsigned long disp) | 258 | int pdc_chassis_disp(unsigned long disp) |
261 | { | 259 | { |
@@ -269,6 +267,22 @@ int pdc_chassis_disp(unsigned long disp) | |||
269 | } | 267 | } |
270 | 268 | ||
271 | /** | 269 | /** |
270 | * pdc_chassis_warn - Fetches chassis warnings | ||
271 | * @retval: -1 on error, 0 on success | ||
272 | */ | ||
273 | int pdc_chassis_warn(unsigned long *warn) | ||
274 | { | ||
275 | int retval = 0; | ||
276 | |||
277 | spin_lock_irq(&pdc_lock); | ||
278 | retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result)); | ||
279 | *warn = pdc_result[0]; | ||
280 | spin_unlock_irq(&pdc_lock); | ||
281 | |||
282 | return retval; | ||
283 | } | ||
284 | |||
285 | /** | ||
272 | * pdc_coproc_cfg - To identify coprocessors attached to the processor. | 286 | * pdc_coproc_cfg - To identify coprocessors attached to the processor. |
273 | * @pdc_coproc_info: Return buffer address. | 287 | * @pdc_coproc_info: Return buffer address. |
274 | * | 288 | * |
diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c index a45e2e2ffd9f..51e86c0365c1 100644 --- a/arch/parisc/kernel/pdc_chassis.c +++ b/arch/parisc/kernel/pdc_chassis.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * interfaces to log Chassis Codes via PDC (firmware) | 2 | * interfaces to Chassis Codes via PDC (firmware) |
3 | * | 3 | * |
4 | * Copyright (C) 2002 Laurent Canet <canetl@esiee.fr> | 4 | * Copyright (C) 2002 Laurent Canet <canetl@esiee.fr> |
5 | * Copyright (C) 2002-2004 Thibaut VARENE <varenet@parisc-linux.org> | 5 | * Copyright (C) 2002-2006 Thibaut VARENE <varenet@parisc-linux.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License, version 2, as | 8 | * it under the terms of the GNU General Public License, version 2, as |
@@ -16,6 +16,9 @@ | |||
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | * | ||
20 | * TODO: poll chassis warns, trigger (configurable) machine shutdown when | ||
21 | * needed. | ||
19 | */ | 22 | */ |
20 | 23 | ||
21 | #undef PDC_CHASSIS_DEBUG | 24 | #undef PDC_CHASSIS_DEBUG |
@@ -30,6 +33,7 @@ | |||
30 | #include <linux/reboot.h> | 33 | #include <linux/reboot.h> |
31 | #include <linux/notifier.h> | 34 | #include <linux/notifier.h> |
32 | #include <linux/cache.h> | 35 | #include <linux/cache.h> |
36 | #include <linux/proc_fs.h> | ||
33 | 37 | ||
34 | #include <asm/pdc_chassis.h> | 38 | #include <asm/pdc_chassis.h> |
35 | #include <asm/processor.h> | 39 | #include <asm/processor.h> |
@@ -38,7 +42,6 @@ | |||
38 | 42 | ||
39 | 43 | ||
40 | #ifdef CONFIG_PDC_CHASSIS | 44 | #ifdef CONFIG_PDC_CHASSIS |
41 | static int pdc_chassis_old __read_mostly = 0; | ||
42 | static unsigned int pdc_chassis_enabled __read_mostly = 1; | 45 | static unsigned int pdc_chassis_enabled __read_mostly = 1; |
43 | 46 | ||
44 | 47 | ||
@@ -64,7 +67,7 @@ __setup("pdcchassis=", pdc_chassis_setup); | |||
64 | * Currently, only E class and A180 are known to work with this. | 67 | * Currently, only E class and A180 are known to work with this. |
65 | * Inspired by Christoph Plattner | 68 | * Inspired by Christoph Plattner |
66 | */ | 69 | */ |
67 | 70 | #if 0 | |
68 | static void __init pdc_chassis_checkold(void) | 71 | static void __init pdc_chassis_checkold(void) |
69 | { | 72 | { |
70 | switch(CPU_HVERSION) { | 73 | switch(CPU_HVERSION) { |
@@ -73,7 +76,6 @@ static void __init pdc_chassis_checkold(void) | |||
73 | case 0x482: /* E45 */ | 76 | case 0x482: /* E45 */ |
74 | case 0x483: /* E55 */ | 77 | case 0x483: /* E55 */ |
75 | case 0x516: /* A180 */ | 78 | case 0x516: /* A180 */ |
76 | pdc_chassis_old = 1; | ||
77 | break; | 79 | break; |
78 | 80 | ||
79 | default: | 81 | default: |
@@ -81,7 +83,7 @@ static void __init pdc_chassis_checkold(void) | |||
81 | } | 83 | } |
82 | DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old); | 84 | DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old); |
83 | } | 85 | } |
84 | 86 | #endif | |
85 | 87 | ||
86 | /** | 88 | /** |
87 | * pdc_chassis_panic_event() - Called by the panic handler. | 89 | * pdc_chassis_panic_event() - Called by the panic handler. |
@@ -136,14 +138,13 @@ void __init parisc_pdc_chassis_init(void) | |||
136 | DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); | 138 | DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); |
137 | 139 | ||
138 | /* Let see if we have something to handle... */ | 140 | /* Let see if we have something to handle... */ |
139 | /* Check for PDC_PAT or old LED Panel */ | 141 | /* Check for PDC_PAT */ |
140 | pdc_chassis_checkold(); | ||
141 | if (is_pdc_pat()) { | 142 | if (is_pdc_pat()) { |
142 | printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n"); | 143 | printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n"); |
143 | handle = 1; | 144 | handle = 1; |
144 | } | 145 | } |
145 | else if (unlikely(pdc_chassis_old)) { | 146 | else { |
146 | printk(KERN_INFO "Enabling old style chassis LED panel support.\n"); | 147 | printk(KERN_INFO "Enabling regular chassis codes support.\n"); |
147 | handle = 1; | 148 | handle = 1; |
148 | } | 149 | } |
149 | 150 | ||
@@ -215,9 +216,12 @@ int pdc_chassis_send_status(int message) | |||
215 | } | 216 | } |
216 | } else retval = -1; | 217 | } else retval = -1; |
217 | #else | 218 | #else |
218 | if (unlikely(pdc_chassis_old)) { | 219 | if (1) { |
219 | switch (message) { | 220 | switch (message) { |
220 | case PDC_CHASSIS_DIRECT_BSTART: | 221 | case PDC_CHASSIS_DIRECT_BSTART: |
222 | retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_INIT)); | ||
223 | break; | ||
224 | |||
221 | case PDC_CHASSIS_DIRECT_BCOMPLETE: | 225 | case PDC_CHASSIS_DIRECT_BCOMPLETE: |
222 | retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN)); | 226 | retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN)); |
223 | break; | 227 | break; |
@@ -244,3 +248,50 @@ int pdc_chassis_send_status(int message) | |||
244 | #endif /* CONFIG_PDC_CHASSIS */ | 248 | #endif /* CONFIG_PDC_CHASSIS */ |
245 | return retval; | 249 | return retval; |
246 | } | 250 | } |
251 | |||
252 | #ifdef CONFIG_PDC_CHASSIS_WARN | ||
253 | #ifdef CONFIG_PROC_FS | ||
254 | static int pdc_chassis_warn_pread(char *page, char **start, off_t off, | ||
255 | int count, int *eof, void *data) | ||
256 | { | ||
257 | char *out = page; | ||
258 | int len, ret; | ||
259 | unsigned long warn; | ||
260 | u32 warnreg; | ||
261 | |||
262 | ret = pdc_chassis_warn(&warn); | ||
263 | if (ret != PDC_OK) | ||
264 | return -EIO; | ||
265 | |||
266 | warnreg = (warn & 0xFFFFFFFF); | ||
267 | |||
268 | if ((warnreg >> 24) & 0xFF) | ||
269 | out += sprintf(out, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", ((warnreg >> 24) & 0xFF)); | ||
270 | |||
271 | out += sprintf(out, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK"); | ||
272 | out += sprintf(out, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK"); | ||
273 | out += sprintf(out, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK"); | ||
274 | |||
275 | len = out - page - off; | ||
276 | if (len < count) { | ||
277 | *eof = 1; | ||
278 | if (len <= 0) return 0; | ||
279 | } else { | ||
280 | len = count; | ||
281 | } | ||
282 | *start = page + off; | ||
283 | return len; | ||
284 | } | ||
285 | |||
286 | static int __init pdc_chassis_create_procfs(void) | ||
287 | { | ||
288 | printk(KERN_INFO "Enabling PDC chassis warnings support.\n"); | ||
289 | create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread, | ||
290 | NULL); | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | __initcall(pdc_chassis_create_procfs); | ||
295 | |||
296 | #endif /* CONFIG_PROC_FS */ | ||
297 | #endif /* CONFIG_PDC_CHASSIS_WARN */ | ||
diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig index 3f5de867acd7..1d3b84b4af3f 100644 --- a/drivers/parisc/Kconfig +++ b/drivers/parisc/Kconfig | |||
@@ -140,18 +140,37 @@ config CHASSIS_LCD_LED | |||
140 | If unsure, say Y. | 140 | If unsure, say Y. |
141 | 141 | ||
142 | config PDC_CHASSIS | 142 | config PDC_CHASSIS |
143 | bool "PDC chassis State Panel support" | 143 | bool "PDC chassis state codes support" |
144 | default y | 144 | default y |
145 | help | 145 | help |
146 | Say Y here if you want to enable support for the LED State front | 146 | Say Y here if you want to enable support for Chassis codes. |
147 | panel as found on E class, and support for the GSP Virtual Front | 147 | That includes support for LED State front panel as found on E |
148 | Panel (LED State and message logging) as found on high end | 148 | class, and support for the GSP Virtual Front Panel (LED State and |
149 | servers such as A, L and N-class. | 149 | message logging) as found on high end servers such as A, L and |
150 | 150 | N-class. | |
151 | This has nothing to do with Chassis LCD and LED support. | 151 | This driver will also display progress messages on LCD display, |
152 | such as "INI", "RUN" and "FLT", and might thus clobber messages | ||
153 | shown by the LED/LCD driver. | ||
154 | This driver updates the state panel (LED and/or LCD) upon system | ||
155 | state change (eg: boot, shutdown or panic). | ||
152 | 156 | ||
153 | If unsure, say Y. | 157 | If unsure, say Y. |
154 | 158 | ||
159 | |||
160 | config PDC_CHASSIS_WARN | ||
161 | bool "PDC chassis warnings support" | ||
162 | depends on PROC_FS | ||
163 | default y | ||
164 | help | ||
165 | Say Y here if you want to enable support for Chassis warnings. | ||
166 | This will add a proc entry '/proc/chassis' giving some information | ||
167 | about the overall health state of the system. | ||
168 | This includes NVRAM battery level, overtemp or failures such as | ||
169 | fans or power units. | ||
170 | |||
171 | If unsure, say Y. | ||
172 | |||
173 | |||
155 | config PDC_STABLE | 174 | config PDC_STABLE |
156 | tristate "PDC Stable Storage support" | 175 | tristate "PDC Stable Storage support" |
157 | depends on SYSFS | 176 | depends on SYSFS |
diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index 08364f957e7a..7d8a71a28546 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h | |||
@@ -719,6 +719,7 @@ void setup_pdc(void); /* in inventory.c */ | |||
719 | int pdc_add_valid(unsigned long address); | 719 | int pdc_add_valid(unsigned long address); |
720 | int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); | 720 | int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); |
721 | int pdc_chassis_disp(unsigned long disp); | 721 | int pdc_chassis_disp(unsigned long disp); |
722 | int pdc_chassis_warn(unsigned long *warn); | ||
722 | int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); | 723 | int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); |
723 | int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, | 724 | int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, |
724 | void *iodc_data, unsigned int iodc_data_size); | 725 | void *iodc_data, unsigned int iodc_data_size); |