[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>
This commit is contained in:
Thibaut Varene 2006-05-03 17:27:35 -06:00 committed by Kyle McMartin
parent c95f2e5f2f
commit 8ffaeaf42e
4 changed files with 107 additions and 22 deletions

View File

@ -11,7 +11,7 @@
* Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
* Copyright 2003 Grant Grundler <grundler parisc-linux org> * Copyright 2003 Grant Grundler <grundler parisc-linux org>
* Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org> * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org>
* Copyright 2004 Thibaut VARENE <varenet@parisc-linux.org> * Copyright 2004,2006 Thibaut VARENE <varenet@parisc-linux.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * 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)
#endif #endif
/** /**
* pdc_chassis_disp - Updates display * pdc_chassis_disp - Updates chassis code
* @retval: -1 on error, 0 on success * @retval: -1 on error, 0 on success
*
* Works on old PDC only (E class, others?)
*/ */
int pdc_chassis_disp(unsigned long disp) int pdc_chassis_disp(unsigned long disp)
{ {
@ -268,6 +266,22 @@ int pdc_chassis_disp(unsigned long disp)
return retval; return retval;
} }
/**
* pdc_chassis_warn - Fetches chassis warnings
* @retval: -1 on error, 0 on success
*/
int pdc_chassis_warn(unsigned long *warn)
{
int retval = 0;
spin_lock_irq(&pdc_lock);
retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result));
*warn = pdc_result[0];
spin_unlock_irq(&pdc_lock);
return retval;
}
/** /**
* pdc_coproc_cfg - To identify coprocessors attached to the processor. * pdc_coproc_cfg - To identify coprocessors attached to the processor.
* @pdc_coproc_info: Return buffer address. * @pdc_coproc_info: Return buffer address.

View File

@ -1,8 +1,8 @@
/* /*
* interfaces to log Chassis Codes via PDC (firmware) * interfaces to Chassis Codes via PDC (firmware)
* *
* Copyright (C) 2002 Laurent Canet <canetl@esiee.fr> * Copyright (C) 2002 Laurent Canet <canetl@esiee.fr>
* Copyright (C) 2002-2004 Thibaut VARENE <varenet@parisc-linux.org> * Copyright (C) 2002-2006 Thibaut VARENE <varenet@parisc-linux.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as * it under the terms of the GNU General Public License, version 2, as
@ -16,6 +16,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* TODO: poll chassis warns, trigger (configurable) machine shutdown when
* needed.
*/ */
#undef PDC_CHASSIS_DEBUG #undef PDC_CHASSIS_DEBUG
@ -30,6 +33,7 @@
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/proc_fs.h>
#include <asm/pdc_chassis.h> #include <asm/pdc_chassis.h>
#include <asm/processor.h> #include <asm/processor.h>
@ -38,7 +42,6 @@
#ifdef CONFIG_PDC_CHASSIS #ifdef CONFIG_PDC_CHASSIS
static int pdc_chassis_old __read_mostly = 0;
static unsigned int pdc_chassis_enabled __read_mostly = 1; static unsigned int pdc_chassis_enabled __read_mostly = 1;
@ -64,7 +67,7 @@ __setup("pdcchassis=", pdc_chassis_setup);
* Currently, only E class and A180 are known to work with this. * Currently, only E class and A180 are known to work with this.
* Inspired by Christoph Plattner * Inspired by Christoph Plattner
*/ */
#if 0
static void __init pdc_chassis_checkold(void) static void __init pdc_chassis_checkold(void)
{ {
switch(CPU_HVERSION) { switch(CPU_HVERSION) {
@ -73,7 +76,6 @@ static void __init pdc_chassis_checkold(void)
case 0x482: /* E45 */ case 0x482: /* E45 */
case 0x483: /* E55 */ case 0x483: /* E55 */
case 0x516: /* A180 */ case 0x516: /* A180 */
pdc_chassis_old = 1;
break; break;
default: default:
@ -81,7 +83,7 @@ static void __init pdc_chassis_checkold(void)
} }
DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old); DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old);
} }
#endif
/** /**
* pdc_chassis_panic_event() - Called by the panic handler. * pdc_chassis_panic_event() - Called by the panic handler.
@ -136,14 +138,13 @@ void __init parisc_pdc_chassis_init(void)
DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__);
/* Let see if we have something to handle... */ /* Let see if we have something to handle... */
/* Check for PDC_PAT or old LED Panel */ /* Check for PDC_PAT */
pdc_chassis_checkold();
if (is_pdc_pat()) { if (is_pdc_pat()) {
printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n"); printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n");
handle = 1; handle = 1;
} }
else if (unlikely(pdc_chassis_old)) { else {
printk(KERN_INFO "Enabling old style chassis LED panel support.\n"); printk(KERN_INFO "Enabling regular chassis codes support.\n");
handle = 1; handle = 1;
} }
@ -215,9 +216,12 @@ int pdc_chassis_send_status(int message)
} }
} else retval = -1; } else retval = -1;
#else #else
if (unlikely(pdc_chassis_old)) { if (1) {
switch (message) { switch (message) {
case PDC_CHASSIS_DIRECT_BSTART: case PDC_CHASSIS_DIRECT_BSTART:
retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_INIT));
break;
case PDC_CHASSIS_DIRECT_BCOMPLETE: case PDC_CHASSIS_DIRECT_BCOMPLETE:
retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN)); retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN));
break; break;
@ -244,3 +248,50 @@ int pdc_chassis_send_status(int message)
#endif /* CONFIG_PDC_CHASSIS */ #endif /* CONFIG_PDC_CHASSIS */
return retval; return retval;
} }
#ifdef CONFIG_PDC_CHASSIS_WARN
#ifdef CONFIG_PROC_FS
static int pdc_chassis_warn_pread(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
char *out = page;
int len, ret;
unsigned long warn;
u32 warnreg;
ret = pdc_chassis_warn(&warn);
if (ret != PDC_OK)
return -EIO;
warnreg = (warn & 0xFFFFFFFF);
if ((warnreg >> 24) & 0xFF)
out += sprintf(out, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", ((warnreg >> 24) & 0xFF));
out += sprintf(out, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK");
out += sprintf(out, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK");
out += sprintf(out, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK");
len = out - page - off;
if (len < count) {
*eof = 1;
if (len <= 0) return 0;
} else {
len = count;
}
*start = page + off;
return len;
}
static int __init pdc_chassis_create_procfs(void)
{
printk(KERN_INFO "Enabling PDC chassis warnings support.\n");
create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread,
NULL);
return 0;
}
__initcall(pdc_chassis_create_procfs);
#endif /* CONFIG_PROC_FS */
#endif /* CONFIG_PDC_CHASSIS_WARN */

View File

@ -140,18 +140,37 @@ config CHASSIS_LCD_LED
If unsure, say Y. If unsure, say Y.
config PDC_CHASSIS config PDC_CHASSIS
bool "PDC chassis State Panel support" bool "PDC chassis state codes support"
default y default y
help help
Say Y here if you want to enable support for the LED State front Say Y here if you want to enable support for Chassis codes.
panel as found on E class, and support for the GSP Virtual Front That includes support for LED State front panel as found on E
Panel (LED State and message logging) as found on high end class, and support for the GSP Virtual Front Panel (LED State and
servers such as A, L and N-class. message logging) as found on high end servers such as A, L and
N-class.
This has nothing to do with Chassis LCD and LED support. This driver will also display progress messages on LCD display,
such as "INI", "RUN" and "FLT", and might thus clobber messages
shown by the LED/LCD driver.
This driver updates the state panel (LED and/or LCD) upon system
state change (eg: boot, shutdown or panic).
If unsure, say Y. If unsure, say Y.
config PDC_CHASSIS_WARN
bool "PDC chassis warnings support"
depends on PROC_FS
default y
help
Say Y here if you want to enable support for Chassis warnings.
This will add a proc entry '/proc/chassis' giving some information
about the overall health state of the system.
This includes NVRAM battery level, overtemp or failures such as
fans or power units.
If unsure, say Y.
config PDC_STABLE config PDC_STABLE
tristate "PDC Stable Storage support" tristate "PDC Stable Storage support"
depends on SYSFS depends on SYSFS

View File

@ -719,6 +719,7 @@ void setup_pdc(void); /* in inventory.c */
int pdc_add_valid(unsigned long address); int pdc_add_valid(unsigned long address);
int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
int pdc_chassis_disp(unsigned long disp); int pdc_chassis_disp(unsigned long disp);
int pdc_chassis_warn(unsigned long *warn);
int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info);
int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
void *iodc_data, unsigned int iodc_data_size); void *iodc_data, unsigned int iodc_data_size);