diff options
-rw-r--r-- | drivers/char/watchdog/w83697hf_wdt.c | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index f62f1723871..4e0bd4e714e 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -49,9 +49,9 @@ static char expect_close; static spinlock_t io_lock; /* You must set this - there is no sane way to probe for this board. */ -static int wdt_io = 0x2E; +static int wdt_io = 0x2e; module_param(wdt_io, int, 0); -MODULE_PARM_DESC(wdt_io, "w83697hf WDT io port (default 0x2E)"); +MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)"); static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ module_param(timeout, int, 0); @@ -331,28 +331,62 @@ static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, }; +static int +w83697hf_check_wdt(void) +{ + if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { + printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io); + return -EIO; + } + + printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io); + w83697hf_unlock(); + if (w83697hf_get_reg(0x20) == 0x60) { + printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io); + w83697hf_lock(); + return 0; + } + w83697hf_lock(); /* Reprotect in case it was a compatible device */ + + printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io); + release_region(wdt_io, 2); + return -EIO; +} + static int __init wdt_init(void) { - int ret; + int ret, autodetect; spin_lock_init(&io_lock); printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); + autodetect = wdt_io == 0; + if (autodetect) + wdt_io = 0x2e; + + if (!w83697hf_check_wdt()) + goto found; + + if (autodetect) { + wdt_io = 0x4e; + if (!w83697hf_check_wdt()) + goto found; + } + + printk (KERN_ERR PFX "No W83697HF/HG could be found\n"); + ret = -EIO; + goto out; + +found: + if (wdt_set_heartbeat(timeout)) { wdt_set_heartbeat(WATCHDOG_TIMEOUT); printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", WATCHDOG_TIMEOUT); } - if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { - printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", - wdt_io); - ret = -EIO; - goto out; - } - w83697hf_init(); ret = register_reboot_notifier(&wdt_notifier); |