aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/watchdog/w83697hf_wdt.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c
index f62f17238712..4e0bd4e714e3 100644
--- a/drivers/char/watchdog/w83697hf_wdt.c
+++ b/drivers/char/watchdog/w83697hf_wdt.c
@@ -49,9 +49,9 @@ static char expect_close;
49static spinlock_t io_lock; 49static spinlock_t io_lock;
50 50
51/* You must set this - there is no sane way to probe for this board. */ 51/* You must set this - there is no sane way to probe for this board. */
52static int wdt_io = 0x2E; 52static int wdt_io = 0x2e;
53module_param(wdt_io, int, 0); 53module_param(wdt_io, int, 0);
54MODULE_PARM_DESC(wdt_io, "w83697hf WDT io port (default 0x2E)"); 54MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)");
55 55
56static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 56static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
57module_param(timeout, int, 0); 57module_param(timeout, int, 0);
@@ -331,28 +331,62 @@ static struct notifier_block wdt_notifier = {
331 .notifier_call = wdt_notify_sys, 331 .notifier_call = wdt_notify_sys,
332}; 332};
333 333
334static int
335w83697hf_check_wdt(void)
336{
337 if (!request_region(wdt_io, 2, WATCHDOG_NAME)) {
338 printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io);
339 return -EIO;
340 }
341
342 printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io);
343 w83697hf_unlock();
344 if (w83697hf_get_reg(0x20) == 0x60) {
345 printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io);
346 w83697hf_lock();
347 return 0;
348 }
349 w83697hf_lock(); /* Reprotect in case it was a compatible device */
350
351 printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io);
352 release_region(wdt_io, 2);
353 return -EIO;
354}
355
334static int __init 356static int __init
335wdt_init(void) 357wdt_init(void)
336{ 358{
337 int ret; 359 int ret, autodetect;
338 360
339 spin_lock_init(&io_lock); 361 spin_lock_init(&io_lock);
340 362
341 printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); 363 printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n");
342 364
365 autodetect = wdt_io == 0;
366 if (autodetect)
367 wdt_io = 0x2e;
368
369 if (!w83697hf_check_wdt())
370 goto found;
371
372 if (autodetect) {
373 wdt_io = 0x4e;
374 if (!w83697hf_check_wdt())
375 goto found;
376 }
377
378 printk (KERN_ERR PFX "No W83697HF/HG could be found\n");
379 ret = -EIO;
380 goto out;
381
382found:
383
343 if (wdt_set_heartbeat(timeout)) { 384 if (wdt_set_heartbeat(timeout)) {
344 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 385 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
345 printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", 386 printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n",
346 WATCHDOG_TIMEOUT); 387 WATCHDOG_TIMEOUT);
347 } 388 }
348 389
349 if (!request_region(wdt_io, 2, WATCHDOG_NAME)) {
350 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
351 wdt_io);
352 ret = -EIO;
353 goto out;
354 }
355
356 w83697hf_init(); 390 w83697hf_init();
357 391
358 ret = register_reboot_notifier(&wdt_notifier); 392 ret = register_reboot_notifier(&wdt_notifier);