All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ondrej Zajicek <santiago@crfreenet.org>
To: olivers137@aol.com, wim@iguana.be, linux-kernel@vger.kernel.org
Subject: [PATCH] it87_wdt: Add support for watchdogs with 8b timers
Date: Tue, 14 Sep 2010 02:54:16 +0200	[thread overview]
Message-ID: <20100914005416.GB25251@localhost> (raw)

This patch adds support for watchdogs with 8b timers, like ones in
IT8702F and older revisions of IT8712F Super IO chip, to it87_wdt
driver. This patch should be used after the patch
'it87_wdt: Add support for IT8720F watchdog'.

Signed-off-by: Ondrej Zajicek <santiago@crfreenet.org>

---

diff -uprN b/drivers/watchdog/Kconfig c/drivers/watchdog/Kconfig
--- b/drivers/watchdog/Kconfig	2010-09-13 19:03:43.000000000 +0200
+++ c/drivers/watchdog/Kconfig	2010-09-14 01:46:50.000000000 +0200
@@ -547,11 +547,11 @@ config IT87_WDT
 	tristate "IT87 Watchdog Timer"
 	depends on X86 && EXPERIMENTAL
 	---help---
-	  This is the driver for the hardware watchdog on the ITE
-	  IT8716, IT8718, IT8720, IT8726, IT8712(Version J,K) Super I/O
-	  chips. 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.
+	  This is the driver for the hardware watchdog on the ITE IT8702,
+	  IT8712, IT8716, IT8718, IT8720, IT8726, IT8712 Super I/O chips.
+	  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 it87_wdt.
diff -uprN b/drivers/watchdog/it87_wdt.c c/drivers/watchdog/it87_wdt.c
--- b/drivers/watchdog/it87_wdt.c	2010-09-13 22:31:48.000000000 +0200
+++ c/drivers/watchdog/it87_wdt.c	2010-09-14 02:11:44.000000000 +0200
@@ -12,7 +12,7 @@
  *		    http://www.ite.com.tw/
  *
  *	Support of the watchdog timers, which are available on
- *	IT8716, IT8718, IT8720, IT8726 and IT8712 (J,K version).
+ *	IT8702, IT8712, IT8716, IT8718, IT8720 and IT8726.
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -76,6 +76,7 @@
 
 /* Chip Id numbers */
 #define NO_DEV_ID	0xffff
+#define IT8702_ID	0x8702
 #define IT8705_ID	0x8705
 #define IT8712_ID	0x8712
 #define IT8716_ID	0x8716
@@ -133,7 +134,7 @@
 #define WDTS_USE_GP	4
 #define WDTS_EXPECTED	5
 
-static	unsigned int base, gpact, ciract;
+static	unsigned int base, gpact, ciract, max_units;
 static	unsigned long wdt_status;
 static	DEFINE_SPINLOCK(spinlock);
 
@@ -211,6 +212,33 @@ static inline void superio_outw(int val,
 	outb(val, VAL);
 }
 
+/* Internal function, should be called after superio_select(GPIO) */
+static void wdt_update_timeout(void)
+{
+	unsigned char cfg = WDT_KRST | WDT_PWROK;
+	int tm = timeout;
+
+	if (testmode)
+		cfg = 0;
+
+	if (tm <= max_units)
+		cfg |= WDT_TOV1;
+	else
+		tm /= 60;
+
+	superio_outb(cfg, WDTCFG);
+	superio_outb(tm, WDTVALLSB);
+	if (max_units > 255)
+		superio_outb(tm>>8, WDTVALMSB);
+}
+
+static int wdt_round_time(int t)
+{
+	t += 59;
+	t -= t % 60;
+	return t;
+}
+
 /* watchdog timer handling */
 
 static void wdt_keepalive(void)
@@ -235,12 +263,7 @@ static void wdt_start(void)
 		superio_outb(WDT_GAMEPORT, WDTCTRL);
 	else
 		superio_outb(WDT_CIRINT, WDTCTRL);
-	if (!testmode)
-		superio_outb(WDT_TOV1 | WDT_KRST | WDT_PWROK, WDTCFG);
-	else
-		superio_outb(WDT_TOV1, WDTCFG);
-	superio_outb(timeout>>8, WDTVALMSB);
-	superio_outb(timeout, WDTVALLSB);
+	wdt_update_timeout();
 
 	superio_exit();
 	spin_unlock_irqrestore(&spinlock, flags);
@@ -256,8 +279,9 @@ static void wdt_stop(void)
 	superio_select(GPIO);
 	superio_outb(0x00, WDTCTRL);
 	superio_outb(WDT_TOV1, WDTCFG);
-	superio_outb(0x00, WDTVALMSB);
 	superio_outb(0x00, WDTVALLSB);
+	if (max_units > 255)
+		superio_outb(0x00, WDTVALMSB);
 
 	superio_exit();
 	spin_unlock_irqrestore(&spinlock, flags);
@@ -267,8 +291,8 @@ static void wdt_stop(void)
  *	wdt_set_timeout - set a new timeout value with watchdog ioctl
  *	@t: timeout value in seconds
  *
- *	The hardware device has a 16 bit watchdog timer, thus the
- *	timeout time ranges between 1 and 65535 seconds.
+ *	The hardware device has a 8 or 16 bit watchdog timer (depends on
+ *	chip version) that can be configured to count seconds or minutes.
  *
  *	Used within WDIOC_SETTIMEOUT watchdog device ioctl.
  */
@@ -277,19 +301,19 @@ static int wdt_set_timeout(int t)
 {
 	unsigned long flags;
 
-	if (t < 1 || t > 65535)
+	if (t < 1 || t > max_units * 60)
 		return -EINVAL;
 
-	timeout = t;
+	if (t > max_units)
+		timeout = wdt_round_time(t);
+	else
+		timeout = t;
 
 	spin_lock_irqsave(&spinlock, flags);
 	if (test_bit(WDTS_TIMER_RUN, &wdt_status)) {
 		superio_enter();
-
 		superio_select(GPIO);
-		superio_outb(t>>8, WDTVALMSB);
-		superio_outb(t, WDTVALLSB);
-
+		wdt_update_timeout();
 		superio_exit();
 	}
 	spin_unlock_irqrestore(&spinlock, flags);
@@ -535,6 +559,8 @@ static int __init it87_wdt_init(void)
 	u8  chip_rev;
 	unsigned long flags;
 
+	wdt_status = 0;
+
 	spin_lock_irqsave(&spinlock, flags);
 	superio_enter();
 	chip_type = superio_inw(CHIPID);
@@ -543,16 +569,21 @@ static int __init it87_wdt_init(void)
 	spin_unlock_irqrestore(&spinlock, flags);
 
 	switch (chip_type) {
+	case IT8702_ID:
+		max_units = 255;
+		break;
+	case IT8712_ID:
+		max_units = (chip_rev < 8) ? 255 : 65535;
+		break;
 	case IT8716_ID:
 	case IT8726_ID:
+		max_units = 65535;
 		break;
 	case IT8718_ID:
 	case IT8720_ID:
+		max_units = 65535;
 		try_gameport = 0;
 		break;
-	case IT8712_ID:
-		if (chip_rev > 7)
-			break;
 	case IT8705_ID:
 		printk(KERN_ERR PFX
 		       "Unsupported Chip found, Chip %04x Revision %02x\n",
@@ -628,13 +659,16 @@ static int __init it87_wdt_init(void)
 		spin_unlock_irqrestore(&spinlock, flags);
 	}
 
-	if (timeout < 1 || timeout > 65535) {
+	if (timeout < 1 || timeout > max_units * 60) {
 		timeout = DEFAULT_TIMEOUT;
 		printk(KERN_WARNING PFX
 		       "Timeout value out of range, use default %d sec\n",
 		       DEFAULT_TIMEOUT);
 	}
 
+	if (timeout > max_units)
+		timeout = wdt_round_time(timeout);
+
 	rc = register_reboot_notifier(&wdt_notifier);
 	if (rc) {
 		printk(KERN_ERR PFX
@@ -661,7 +695,7 @@ static int __init it87_wdt_init(void)
 		outb(0x09, CIR_IER(base));
 	}
 
-	printk(KERN_INFO PFX "Chip it%04x revision %d initialized. "
+	printk(KERN_INFO PFX "Chip IT%04x revision %d initialized. "
 		"timeout=%d sec (nowayout=%d testmode=%d exclusive=%d "
 		"nogameport=%d)\n", chip_type, chip_rev, timeout,
 		nowayout, testmode, exclusive, nogameport);
@@ -703,8 +737,9 @@ static void __exit it87_wdt_exit(void)
 	superio_select(GPIO);
 	superio_outb(0x00, WDTCTRL);
 	superio_outb(0x00, WDTCFG);
-	superio_outb(0x00, WDTVALMSB);
 	superio_outb(0x00, WDTVALLSB);
+	if (max_units > 255)
+		superio_outb(0x00, WDTVALMSB);
 	if (test_bit(WDTS_USE_GP, &wdt_status)) {
 		superio_select(GAMEPORT);
 		superio_outb(gpact, ACTREG);


-- 
Elen sila lumenn' omentielvo

Ondrej 'SanTiago' Zajicek (email: santiago@crfreenet.org)
OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net)
"To err is human -- to blame it on a computer is even more so."

             reply	other threads:[~2010-09-14  0:45 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-14  0:54 Ondrej Zajicek [this message]
2010-09-21 23:43 ` [PATCH] it87_wdt: Add support for watchdogs with 8b timers Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100914005416.GB25251@localhost \
    --to=santiago@crfreenet.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=olivers137@aol.com \
    --cc=wim@iguana.be \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.