diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-12-09 14:11:42 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-12-09 14:11:42 +1100 |
commit | f64b6501aab19d1e2842b5cf9ff8e37a98c8f67a (patch) | |
tree | 49dc76b3610413a89cf0f2fbdcdbaeb3716c7731 /drivers | |
parent | b4e51c70d03744c64a51fd8ea65a4c74d7faf610 (diff) | |
parent | 9f8a4c809d177dfef42eacc0d37d5fe479c7287c (diff) |
Merge remote branch 'watchdog/master'
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/watchdog/Kconfig | 9 | ||||
-rw-r--r-- | drivers/watchdog/f71808e_wdt.c | 66 | ||||
-rw-r--r-- | drivers/watchdog/w83627hf_wdt.c | 8 |
3 files changed, 62 insertions, 21 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index a5ad77ef4266..8a3aa2f050c8 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -722,14 +722,15 @@ config SMSC37B787_WDT Most people will say N. config W83627HF_WDT - tristate "W83627HF Watchdog Timer" + tristate "W83627HF/W83627DHG Watchdog Timer" depends on X86 ---help--- This is the driver for the hardware watchdog on the W83627HF chipset as used in Advantech PC-9578 and Tyan S2721-533 motherboards - (and likely others). This watchdog simply watches your kernel to - make sure it doesn't freeze, and if it does, it reboots your computer - after a certain amount of time. + (and likely others). The driver also supports the W83627DHG chip. + This watchdog simply watches your kernel to make sure it doesn't + freeze, and if it does, it reboots your computer after a certain + amount of time. To compile this driver as a module, choose M here: the module will be called w83627hf_wdt. diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index 65e579635dba..f573948998b0 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c @@ -42,18 +42,20 @@ #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ #define SIO_REG_DEVREV 0x22 /* Device revision */ #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ +#define SIO_REG_ROM_ADDR_SEL 0x27 /* ROM address select */ +#define SIO_REG_MFUNCT1 0x29 /* Multi function select 1 */ +#define SIO_REG_MFUNCT2 0x2a /* Multi function select 2 */ +#define SIO_REG_MFUNCT3 0x2b /* Multi function select 3 */ #define SIO_REG_ENABLE 0x30 /* Logical device enable */ #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ -#define SIO_F71808_ID 0x0901 /* Chipset ID */ -#define SIO_F71858_ID 0x0507 /* Chipset ID */ +#define SIO_F71808_ID 0x0901 /* Chipset ID */ +#define SIO_F71858_ID 0x0507 /* Chipset ID */ #define SIO_F71862_ID 0x0601 /* Chipset ID */ #define SIO_F71882_ID 0x0541 /* Chipset ID */ #define SIO_F71889_ID 0x0723 /* Chipset ID */ -#define F71882FG_REG_START 0x01 - #define F71808FG_REG_WDO_CONF 0xf0 #define F71808FG_REG_WDT_CONF 0xf5 #define F71808FG_REG_WD_TIME 0xf6 @@ -70,13 +72,15 @@ #define WATCHDOG_MAX_TIMEOUT (60 * 255) #define WATCHDOG_PULSE_WIDTH 125 /* 125 ms, default pulse width for watchdog signal */ +#define WATCHDOG_F71862FG_PIN 63 /* default watchdog reset output + pin number 63 */ static unsigned short force_id; module_param(force_id, ushort, 0); MODULE_PARM_DESC(force_id, "Override the detected device ID"); static const int max_timeout = WATCHDOG_MAX_TIMEOUT; -static int timeout = 60; /* default timeout in seconds */ +static int timeout = WATCHDOG_TIMEOUT; /* default timeout in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=" @@ -89,6 +93,12 @@ MODULE_PARM_DESC(pulse_width, "Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms" " (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")"); +static unsigned int f71862fg_pin = WATCHDOG_F71862FG_PIN; +module_param(f71862fg_pin, uint, 0); +MODULE_PARM_DESC(f71862fg_pin, + "Watchdog f71862fg reset output pin configuration. Choose pin 56 or 63" + " (default=" __MODULE_STRING(WATCHDOG_F71862FG_PIN)")"); + static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0444); MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); @@ -282,6 +292,28 @@ exit_unlock: return err; } +static int f71862fg_pin_configure(unsigned short ioaddr) +{ + /* When ioaddr is non-zero the calling function has to take care of + mutex handling and superio preparation! */ + + if (f71862fg_pin == 63) { + if (ioaddr) { + /* SPI must be disabled first to use this pin! */ + superio_clear_bit(ioaddr, SIO_REG_ROM_ADDR_SEL, 6); + superio_set_bit(ioaddr, SIO_REG_MFUNCT3, 4); + } + } else if (f71862fg_pin == 56) { + if (ioaddr) + superio_set_bit(ioaddr, SIO_REG_MFUNCT1, 1); + } else { + printk(KERN_ERR DRVNAME ": Invalid argument f71862fg_pin=%d\n", + f71862fg_pin); + return -EINVAL; + } + return 0; +} + static int watchdog_start(void) { /* Make sure we don't die as soon as the watchdog is enabled below */ @@ -299,19 +331,25 @@ static int watchdog_start(void) switch (watchdog.type) { case f71808fg: /* Set pin 21 to GPIO23/WDTRST#, then to WDTRST# */ - superio_clear_bit(watchdog.sioaddr, 0x2a, 3); - superio_clear_bit(watchdog.sioaddr, 0x2b, 3); + superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT2, 3); + superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT3, 3); + break; + + case f71862fg: + err = f71862fg_pin_configure(watchdog.sioaddr); + if (err) + goto exit_superio; break; case f71882fg: /* Set pin 56 to WDTRST# */ - superio_set_bit(watchdog.sioaddr, 0x29, 1); + superio_set_bit(watchdog.sioaddr, SIO_REG_MFUNCT1, 1); break; case f71889fg: /* set pin 40 to WDTRST# */ - superio_outb(watchdog.sioaddr, 0x2b, - superio_inb(watchdog.sioaddr, 0x2b) & 0xcf); + superio_outb(watchdog.sioaddr, SIO_REG_MFUNCT3, + superio_inb(watchdog.sioaddr, SIO_REG_MFUNCT3) & 0xcf); break; default: @@ -711,16 +749,16 @@ static int __init f71808e_find(int sioaddr) case SIO_F71808_ID: watchdog.type = f71808fg; break; + case SIO_F71862_ID: + watchdog.type = f71862fg; + err = f71862fg_pin_configure(0); /* validate module parameter */ + break; case SIO_F71882_ID: watchdog.type = f71882fg; break; case SIO_F71889_ID: watchdog.type = f71889fg; break; - case SIO_F71862_ID: - /* These have a watchdog, though it isn't implemented (yet). */ - err = -ENOSYS; - goto exit; case SIO_F71858_ID: /* Confirmed (by datasheet) not to have a watchdog. */ err = -ENODEV; diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index 0f5288df0091..e5c91d4404ed 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c @@ -42,7 +42,7 @@ #include <asm/system.h> -#define WATCHDOG_NAME "w83627hf/thf/hg WDT" +#define WATCHDOG_NAME "w83627hf/thf/hg/dhg WDT" #define PFX WATCHDOG_NAME ": " #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ @@ -89,7 +89,7 @@ static void w83627hf_select_wd_register(void) c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */ outb_p(0x2b, WDT_EFER); outb_p(c, WDT_EFDR); /* set GPIO3 to WDT0 */ - } else if (c == 0x88) { /* W83627EHF */ + } else if (c == 0x88 || c == 0xa0) { /* W83627EHF / W83627DHG */ outb_p(0x2d, WDT_EFER); /* select GPIO5 */ c = inb_p(WDT_EFDR) & ~0x01; /* PIN77 -> WDT0# */ outb_p(0x2d, WDT_EFER); @@ -129,6 +129,8 @@ static void w83627hf_init(void) t = inb_p(WDT_EFDR); /* read CRF5 */ t &= ~0x0C; /* set second mode & disable keyboard turning off watchdog */ + t |= 0x02; /* enable the WDTO# output low pulse + to the KBRST# pin (PIN60) */ outb_p(t, WDT_EFDR); /* Write back to CRF5 */ outb_p(0xF7, WDT_EFER); /* Select CRF7 */ @@ -321,7 +323,7 @@ static int __init wdt_init(void) { int ret; - printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF/THF/HG Super I/O chip initialising.\n"); + printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF/THF/HG/DHG Super I/O chip initialising.\n"); if (wdt_set_heartbeat(timeout)) { wdt_set_heartbeat(WATCHDOG_TIMEOUT); |