aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2006-09-07 11:57:00 +0200
committerWim Van Sebroeck <wim@iguana.be>2006-10-04 22:45:11 +0200
commitc81b2996253a94278057f83a24dfa9053f0dee7a (patch)
treedd611ff336f4859a8518fbd95a0e949569f57593 /drivers
parent0cd544763bacad14d0d15fb16d29999b450cb77f (diff)
[WATCHDOG] w83697hf/hg WDT driver - patch 10
This is patch 10 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - check whether the device is really present (we *can* probe for the device now). Signed-off-by: Samuel Tardieu <sam@rfc1149.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
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 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);