LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] [WATCHDOG] it8712f_wdt support for 16-bit timeout values, WDIOC_GETSTATUS
@ 2008-02-11  3:11 Andrew Paprocki
  2008-02-14 21:50 ` Andrew Morton
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Paprocki @ 2008-02-11  3:11 UTC (permalink / raw)
  To: linux-kernel; +Cc: wim

This patch adds support for 16-bit watchdog timeout values which are
available in chip revisions >= 0x08. Values <= 65535 are seconds precision,
otherwise minutes precision is used up to a maximum value of 3932100. Added
implementation for WDIOC_GETSTATUS which checks the WDT status bit in the
WDT control register.

Signed-off-by: Andrew Paprocki <andrew@ishiboo.com>
---
  drivers/watchdog/it8712f_wdt.c |   82
++++++++++++++++++++++++++++++++--------
  1 files changed, 66 insertions(+), 16 deletions(-)

diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
index 1b6d7d1..803c699 100644
--- a/drivers/watchdog/it8712f_wdt.c
+++ b/drivers/watchdog/it8712f_wdt.c
@@ -7,7 +7,8 @@
   *
   *	drivers/char/watchdog/scx200_wdt.c
   *	drivers/hwmon/it87.c
- *	IT8712F EC-LPC I/O Preliminary Specification 0.9.2.pdf
+ *	IT8712F EC-LPC I/O Preliminary Specification 0.8.2
+ *	IT8712F EC-LPC I/O Preliminary Specification 0.9.3
   *
   *	This program is free software; you can redistribute it and/or
   *	modify it under the terms of the GNU General Public License as
@@ -40,6 +41,7 @@ MODULE_DESCRIPTION("IT8712F Watchdog Driver");
  MODULE_LICENSE("GPL");
  MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

+static int max_units = 255;
  static int margin = 60;		/* in seconds */
  module_param(margin, int, 0);
  MODULE_PARM_DESC(margin, "Watchdog margin in seconds");
@@ -51,6 +53,7 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown
on close");
  static struct semaphore it8712f_wdt_sem;
  static unsigned expect_close;
  static spinlock_t io_lock;
+static unsigned char revision;

  /* Dog Food address - We use the game port address */
  static unsigned short address;
@@ -108,6 +111,15 @@ superio_inw(int reg)
  	return val;
  }

+static void
+superio_outw(int val, int reg)
+{
+        outb(reg++, REG);
+        outb((val >> 8) & 0xff, VAL);
+        outb(reg, REG);
+        outb(val & 0xff, VAL);
+}
+
  static inline void
  superio_select(int ldn)
  {
@@ -143,15 +155,33 @@ static void
  it8712f_wdt_update_margin(void)
  {
  	int config = WDT_OUT_KRST | WDT_OUT_PWROK;
+        int units = margin;
+
+        /* Switch to minutes precision if the configured margin
+         * value does not fit within the register width.
+         */
+        if (units <= max_units) {
+                config |= WDT_UNIT_SEC; /* else UNIT is MINUTES */
+                printk(KERN_INFO NAME ": timer margin %d seconds\n",
units);
+        } else {
+                units /= 60;
+                printk(KERN_INFO NAME ": timer margin %d minutes\n",
units);
+        }
+        superio_outb(config, WDT_CONFIG);
+
+        if (revision >= 0x08)
+                superio_outw(units, WDT_TIMEOUT);
+        else
+                superio_outb(units, WDT_TIMEOUT);
+}

-	printk(KERN_INFO NAME ": timer margin %d seconds\n", margin);
-
-	/* The timeout register only has 8bits wide */
-	if (margin < 256)
-		config |= WDT_UNIT_SEC;	/* else UNIT are MINUTES */
-	superio_outb(config, WDT_CONFIG);
-
-	superio_outb((margin > 255) ? (margin / 60) : margin, WDT_TIMEOUT);
+static int
+it8712f_wdt_get_status(void)
+{
+        if (superio_inb(WDT_CONTROL) & 0x01)
+                return WDIOF_CARDRESET;
+        else
+                return 0;
  }

  static void
@@ -234,7 +264,7 @@ it8712f_wdt_ioctl(struct inode *inode, struct file
*file,
  		.firmware_version = 1,
  		.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
  	};
-	int new_margin;
+	int value;

  	switch (cmd) {
  	default:
@@ -244,17 +274,27 @@ it8712f_wdt_ioctl(struct inode *inode, struct file
*file,
  			return -EFAULT;
  		return 0;
  	case WDIOC_GETSTATUS:
+                superio_enter();
+                superio_select(LDN_GPIO);
+
+                value = it8712f_wdt_get_status();
+
+                superio_exit();
+
+		return put_user(value, p);
  	case WDIOC_GETBOOTSTATUS:
-		return put_user(0, p);
+                return put_user(0, p);
  	case WDIOC_KEEPALIVE:
  		it8712f_wdt_ping();
  		return 0;
  	case WDIOC_SETTIMEOUT:
-		if (get_user(new_margin, p))
+		if (get_user(value, p))
  			return -EFAULT;
-		if (new_margin < 1)
+		if (value < 1)
  			return -EINVAL;
-		margin = new_margin;
+                if (value > (max_units * 60))
+                        return -EINVAL;
+		margin = value;
  		superio_enter();
  		superio_select(LDN_GPIO);

@@ -262,6 +302,7 @@ it8712f_wdt_ioctl(struct inode *inode, struct file
*file,

  		superio_exit();
  		it8712f_wdt_ping();
+                /* Fall through */
  	case WDIOC_GETTIMEOUT:
  		if (put_user(margin, p))
  			return -EFAULT;
@@ -336,9 +377,18 @@ it8712f_wdt_find(unsigned short *address)
  	}

  	err = 0;
-	printk(KERN_DEBUG NAME ": Found IT%04xF chip revision %d - "
+        revision = superio_inb(DEVREV) & 0x0f;
+
+        /* Later revisions have 16-bit values per datasheet 0.9.1 */
+        if (revision >= 0x08)
+                max_units = 65535;
+
+        if (margin > (max_units * 60))
+                margin = (max_units * 60);
+
+	printk(KERN_INFO NAME ": Found IT%04xF chip revision %d - "
  		"using DogFood address 0x%x\n",
-		chip_type, superio_inb(DEVREV) & 0x0f, *address);
+		chip_type, revision, *address);

  exit:
  	superio_exit();

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] [WATCHDOG] it8712f_wdt support for 16-bit timeout values, WDIOC_GETSTATUS
  2008-02-11  3:11 [PATCH] [WATCHDOG] it8712f_wdt support for 16-bit timeout values, WDIOC_GETSTATUS Andrew Paprocki
@ 2008-02-14 21:50 ` Andrew Morton
  2008-02-15  4:01   ` Andrew Paprocki
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2008-02-14 21:50 UTC (permalink / raw)
  To: Andrew Paprocki; +Cc: linux-kernel, wim

On Sun, 10 Feb 2008 22:11:15 -0500
"Andrew Paprocki" <andrew@ishiboo.com> wrote:

> This patch adds support for 16-bit watchdog timeout values which are
> available in chip revisions >= 0x08. Values <= 65535 are seconds precision,
> otherwise minutes precision is used up to a maximum value of 3932100. Added
> implementation for WDIOC_GETSTATUS which checks the WDT status bit in the
> WDT control register.
> 
> Signed-off-by: Andrew Paprocki <andrew@ishiboo.com>
> ---
>   drivers/watchdog/it8712f_wdt.c |   82
> ++++++++++++++++++++++++++++++++--------
>   1 files changed, 66 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
> index 1b6d7d1..803c699 100644
> --- a/drivers/watchdog/it8712f_wdt.c
> +++ b/drivers/watchdog/it8712f_wdt.c

The patch is wordwrapped, space-stuffed and has tabs replaced with spaces. 
You hit the trifecta!

Please resend.  If you'd prefer to use an attachment rather than spending
half an hour wrestling your email client, feel free to do so ;)


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] [WATCHDOG] it8712f_wdt support for 16-bit timeout values, WDIOC_GETSTATUS
  2008-02-14 21:50 ` Andrew Morton
@ 2008-02-15  4:01   ` Andrew Paprocki
  0 siblings, 0 replies; 3+ messages in thread
From: Andrew Paprocki @ 2008-02-15  4:01 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, wim

[-- Attachment #1: Type: text/plain, Size: 1321 bytes --]

Sorry, try the attached file. I tried to send via IMAP draft, but I
suppose it is still not configured right.

Thanks,
-Andrew

On Thu, Feb 14, 2008 at 4:50 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Sun, 10 Feb 2008 22:11:15 -0500
>  "Andrew Paprocki" <andrew@ishiboo.com> wrote:
>
>  > This patch adds support for 16-bit watchdog timeout values which are
>  > available in chip revisions >= 0x08. Values <= 65535 are seconds precision,
>  > otherwise minutes precision is used up to a maximum value of 3932100. Added
>  > implementation for WDIOC_GETSTATUS which checks the WDT status bit in the
>  > WDT control register.
>  >
>  > Signed-off-by: Andrew Paprocki <andrew@ishiboo.com>
>  > ---
>  >   drivers/watchdog/it8712f_wdt.c |   82
>  > ++++++++++++++++++++++++++++++++--------
>  >   1 files changed, 66 insertions(+), 16 deletions(-)
>  >
>  > diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
>  > index 1b6d7d1..803c699 100644
>  > --- a/drivers/watchdog/it8712f_wdt.c
>  > +++ b/drivers/watchdog/it8712f_wdt.c
>
>  The patch is wordwrapped, space-stuffed and has tabs replaced with spaces.
>  You hit the trifecta!
>
>  Please resend.  If you'd prefer to use an attachment rather than spending
>  half an hour wrestling your email client, feel free to do so ;)
>
>

[-- Attachment #2: 0001-WATCHDOG-it8712f_wdt-support-for-16-bit-timeout-values-WDIOC_GETSTATUS.txt --]
[-- Type: text/plain, Size: 4949 bytes --]

From 23ce04e580f6fa2a24e247c3ad851de0f7e6a875 Mon Sep 17 00:00:00 2001
From: Andrew Paprocki <andrew@ishiboo.com>
Date: Thu, 14 Feb 2008 22:52:44 -0500
Subject: [PATCH] [WATCHDOG] it8712f_wdt support for 16-bit timeout values, WDIOC_GETSTATUS

This patch adds support for 16-bit watchdog timeout values which are
available in chip revisions >= 0x08. Values <= 65535 are seconds precision,
otherwise minutes precision is used up to a maximum value of 3932100. Added
implementation for WDIOC_GETSTATUS which checks the WDT status bit in the
WDT control register.

Signed-off-by: Andrew Paprocki <andrew@ishiboo.com>
---
 drivers/watchdog/it8712f_wdt.c |   78 ++++++++++++++++++++++++++++++++-------
 1 files changed, 64 insertions(+), 14 deletions(-)

diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
index 1b6d7d1..1efcad3 100644
--- a/drivers/watchdog/it8712f_wdt.c
+++ b/drivers/watchdog/it8712f_wdt.c
@@ -7,7 +7,8 @@
  *
  *	drivers/char/watchdog/scx200_wdt.c
  *	drivers/hwmon/it87.c
- *	IT8712F EC-LPC I/O Preliminary Specification 0.9.2.pdf
+ *	IT8712F EC-LPC I/O Preliminary Specification 0.8.2
+ *	IT8712F EC-LPC I/O Preliminary Specification 0.9.3
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License as
@@ -40,6 +41,7 @@ MODULE_DESCRIPTION("IT8712F Watchdog Driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

+static int max_units = 255;
 static int margin = 60;		/* in seconds */
 module_param(margin, int, 0);
 MODULE_PARM_DESC(margin, "Watchdog margin in seconds");
@@ -51,6 +53,7 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
 static struct semaphore it8712f_wdt_sem;
 static unsigned expect_close;
 static spinlock_t io_lock;
+static unsigned char revision;

 /* Dog Food address - We use the game port address */
 static unsigned short address;
@@ -108,6 +111,15 @@ superio_inw(int reg)
 	return val;
 }

+static void
+superio_outw(int val, int reg)
+{
+	outb(reg++, REG);
+	outb((val >> 8) & 0xff, VAL);
+	outb(reg, REG);
+	outb(val & 0xff, VAL);
+}
+
 static inline void
 superio_select(int ldn)
 {
@@ -143,15 +155,33 @@ static void
 it8712f_wdt_update_margin(void)
 {
 	int config = WDT_OUT_KRST | WDT_OUT_PWROK;
-
-	printk(KERN_INFO NAME ": timer margin %d seconds\n", margin);
-
-	/* The timeout register only has 8bits wide */
-	if (margin < 256)
-		config |= WDT_UNIT_SEC;	/* else UNIT are MINUTES */
+	int units = margin;
+
+	/* Switch to minutes precision if the configured margin
+	 * value does not fit within the register width.
+	 */
+	if (units <= max_units) {
+		config |= WDT_UNIT_SEC; /* else UNIT is MINUTES */
+		printk(KERN_INFO NAME ": timer margin %d seconds\n", units);
+	} else {
+		units /= 60;
+		printk(KERN_INFO NAME ": timer margin %d minutes\n", units);
+	}
 	superio_outb(config, WDT_CONFIG);

-	superio_outb((margin > 255) ? (margin / 60) : margin, WDT_TIMEOUT);
+	if (revision >= 0x08)
+		superio_outw(units, WDT_TIMEOUT);
+	else
+		superio_outb(units, WDT_TIMEOUT);
+}
+
+static int
+it8712f_wdt_get_status(void)
+{
+	if (superio_inb(WDT_CONTROL) & 0x01)
+		return WDIOF_CARDRESET;
+	else
+		return 0;
 }

 static void
@@ -234,7 +264,7 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file,
 		.firmware_version = 1,
 		.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
 	};
-	int new_margin;
+	int value;

 	switch (cmd) {
 	default:
@@ -244,17 +274,27 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file,
 			return -EFAULT;
 		return 0;
 	case WDIOC_GETSTATUS:
+		superio_enter();
+		superio_select(LDN_GPIO);
+
+		value = it8712f_wdt_get_status();
+
+		superio_exit();
+
+		return put_user(value, p);
 	case WDIOC_GETBOOTSTATUS:
 		return put_user(0, p);
 	case WDIOC_KEEPALIVE:
 		it8712f_wdt_ping();
 		return 0;
 	case WDIOC_SETTIMEOUT:
-		if (get_user(new_margin, p))
+		if (get_user(value, p))
 			return -EFAULT;
-		if (new_margin < 1)
+		if (value < 1)
+			return -EINVAL;
+		if (value > (max_units * 60))
 			return -EINVAL;
-		margin = new_margin;
+		margin = value;
 		superio_enter();
 		superio_select(LDN_GPIO);

@@ -262,6 +302,7 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file,

 		superio_exit();
 		it8712f_wdt_ping();
+		/* Fall through */
 	case WDIOC_GETTIMEOUT:
 		if (put_user(margin, p))
 			return -EFAULT;
@@ -336,9 +377,18 @@ it8712f_wdt_find(unsigned short *address)
 	}

 	err = 0;
-	printk(KERN_DEBUG NAME ": Found IT%04xF chip revision %d - "
+	revision = superio_inb(DEVREV) & 0x0f;
+
+	/* Later revisions have 16-bit values per datasheet 0.9.1 */
+	if (revision >= 0x08)
+		max_units = 65535;
+
+	if (margin > (max_units * 60))
+		margin = (max_units * 60);
+
+	printk(KERN_INFO NAME ": Found IT%04xF chip revision %d - "
 		"using DogFood address 0x%x\n",
-		chip_type, superio_inb(DEVREV) & 0x0f, *address);
+		chip_type, revision, *address);

 exit:
 	superio_exit();
--
1.4.4.4


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-02-15  4:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-11  3:11 [PATCH] [WATCHDOG] it8712f_wdt support for 16-bit timeout values, WDIOC_GETSTATUS Andrew Paprocki
2008-02-14 21:50 ` Andrew Morton
2008-02-15  4:01   ` Andrew Paprocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).