public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Rusty Lynch <rusty@linux.co.intel.com>
To: Rusty Lynch <rusty@linux.co.intel.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>, lkml <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH][2.5] Sysfs enabling watchdog infrastructure
Date: 21 Feb 2003 15:36:09 -0800	[thread overview]
Message-ID: <1045870570.1037.13.camel@vmhack> (raw)
In-Reply-To: <1045869699.1037.6.camel@vmhack>

The following is a patch against the 2.5.60 kernel that adds a new driver
for the hardware watchdog timers devices on the zt55xx line of cpci compute 
blades.  The driver is writen as a watchdog_driver utilizing the previously
submitted watchdog infrastructure.

    --rustyl

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1041  -> 1.1042 
#	drivers/char/watchdog/Kconfig	1.6     -> 1.7    
#	drivers/char/watchdog/Makefile	1.8     -> 1.9    
#	               (new)	        -> 1.1     drivers/char/watchdog/ztwd.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/21	rusty@penguin.co.intel.com	1.1042
# Adding a new watchdog driver for the ZT55XX line of CompactPCI
# single board computers.
# --------------------------------------------
#
diff -Nru a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
--- a/drivers/char/watchdog/Kconfig	Fri Feb 21 15:06:37 2003
+++ b/drivers/char/watchdog/Kconfig	Fri Feb 21 15:06:37 2003
@@ -354,4 +354,18 @@
 	  Documentation/modules.txt. The module will be called
 	  wafer5823wdt.o
 
+config ZT55XX_WDT
+	tristate "ZT55XX Single Board Computer Watchdog"
+	depends on WATCHDOG
+	help
+          This is a driver for the hardware watchdog on the ZT55XX line 
+          of CompactPCI single board computers originally sold by Ziatech,
+          and then Intel, and then Performance Technologies.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  If you want to compile it as a module, say M here and read
+	  Documentation/modules.txt. The module will be called
+	  ztwd.ko
+
 endmenu
diff -Nru a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
--- a/drivers/char/watchdog/Makefile	Fri Feb 21 15:06:37 2003
+++ b/drivers/char/watchdog/Makefile	Fri Feb 21 15:06:37 2003
@@ -31,3 +31,4 @@
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
 obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
 obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
+obj-$(CONFIG_ZT55XX_WDT) += ztwd.o
diff -Nru a/drivers/char/watchdog/ztwd.c b/drivers/char/watchdog/ztwd.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/watchdog/ztwd.c	Fri Feb 21 15:06:37 2003
@@ -0,0 +1,391 @@
+/*
+ * ztwd.c
+ *
+ * Intel/Ziatech ZT55xx watchdog driver
+ *
+ * Copyright (C) 2003 Rusty Lynch <rusty@linux.co.intel.com>
+ * 
+ * Based on original work from SOMA Networks. Original copyright:
+ * Copyright 2001-2003 SOMA Networks, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Contributors:
+ * Scott Murray <scottm@somanetworks.com>
+ * Rusty Lynch <rusty@linux.co.intel.com>
+ *
+ * Send feedback to <rusty@linux.co.intel.com>
+ */
+
+/*
+ * This driver implements the IO controlled watchdog device found
+ * on the ZT55XX line of single board computers. 
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/kobject.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/watchdog.h>
+#include <asm/io.h>
+
+#define DEBUG 1
+#ifdef DEBUG
+#define dbg(format, arg...)				\
+		 printk (KERN_DEBUG "%s: " format "\n",	\
+			 __FUNCTION__, ## arg);
+#define trace(format, arg...)				 \
+                 printk(KERN_INFO "%s(" format ")\n",    \
+		        __FUNCTION__ , ## arg);
+#else
+#define trace(format, arg...) do { } while (0)
+#define dbg(format, arg...) do { } while (0)
+#endif
+
+#define err(format, arg...) \
+                printk(KERN_ERR "%s: " format "\n", \
+		       __FUNCTION__ , ## arg)
+#define info(format, arg...) \
+                printk(KERN_INFO "%s: " format "\n", \
+		       __FUNCTION__ , ## arg)
+#define warn(format, arg...) \
+                printk(KERN_WARNING "%s: " format "\n", \
+		       __FUNCTION__ , ## arg)
+
+#define WD_CTL_REG	       0x79
+
+#define WD_TERMINALCOUNT_MASK  0x07
+#define WD_STAGE1_ACTION_MASK  0x08
+#define WD_STAGE1_ENABLE_MASK  0x10
+#define WD_STAGE2_ENABLE_MASK  0x20
+#define WD_STAGE2_MONITOR_MASK 0x40
+#define WD_STAGE1_MONITOR_MASK 0x80
+
+#define WD_TC_250MS	       0x00
+#define WD_TC_500MS	       0x01
+#define WD_TC_1S	       0x02
+#define WD_TC_8S	       0x03
+#define WD_TC_32S	       0x04
+#define WD_TC_64S	       0x05
+#define WD_TC_128S	       0x06
+#define WD_TC_256S	       0x07
+
+#define DEFAULT_TIMEOUT          64  /* seconds */
+
+static int nowayout = 0;
+static int bootstatus = 0;
+static int status = 0;
+static int pretimeout = 0;
+
+static int ztwd_start(struct watchdog_driver *d)
+{
+    	uint8_t value;
+
+	trace("%s", d->driver.name);
+	value = inb(WD_CTL_REG);
+	if (pretimeout)
+		value |= WD_STAGE1_ENABLE_MASK;
+	value |= WD_STAGE2_ENABLE_MASK;
+	outb(value, WD_CTL_REG);
+	return 0;
+}
+
+static int ztwd_stop(struct watchdog_driver *d)
+{
+    	uint8_t value;
+
+	trace("%s", d->driver.name);
+	if (nowayout) {
+		warn("Nowayout flag is set.  Request to stop timer denied!");
+		return -1;
+	}
+
+	value = inb(WD_CTL_REG);
+	value &= ~WD_STAGE1_ENABLE_MASK;
+	value &= ~WD_STAGE2_ENABLE_MASK;
+	outb(value, WD_CTL_REG);
+	return 0;
+}
+
+static int ztwd_keepalive(struct watchdog_driver *d) 
+{
+	trace("%s", d->driver.name);
+	inb(WD_CTL_REG);
+	status |= WDIOF_KEEPALIVEPING;
+	return 0;
+}
+
+static int ztwd_get_status(struct watchdog_driver *d, int *s) 
+{
+	uint8_t value;
+
+	trace("%s, %p", d->driver.name, s);
+	*s = status;
+	value = inb(WD_CTL_REG);
+	if (value & WD_STAGE1_MONITOR_MASK || value & WD_STAGE2_MONITOR_MASK)
+		*s |= WDIOF_CARDRESET;
+	return 0;
+}
+
+static int ztwd_get_bootstatus(struct watchdog_driver *d, int *bs) 
+{
+	trace("%s, %p", d->driver.name, bs);
+	*bs = bootstatus;
+	return 0;
+}
+
+static int ztwd_get_timeout(struct watchdog_driver *d, int *timeout)
+{
+	uint8_t value;
+
+	trace("%s, %p", d->driver.name, timeout);
+	if (!timeout) {
+		dbg("recieved a null timeout pointer!");
+		return -1;
+	}
+
+	value = inb(WD_CTL_REG);
+	switch (value & WD_TERMINALCOUNT_MASK) {
+	default:
+		dbg("unexpected value in terminal count");
+		return -EFAULT;
+	case WD_TC_250MS:
+	case WD_TC_500MS:
+	case WD_TC_1S:
+		*timeout = 1;
+		break;
+	case WD_TC_8S:
+		*timeout = 8;
+		break;
+	case WD_TC_32S:
+		*timeout = 32;
+		break;
+	case WD_TC_64S:
+		*timeout = 64;
+		break;
+	case WD_TC_128S:
+		*timeout = 128;
+		break;
+	case WD_TC_256S:
+		*timeout = 256;		
+	}
+	status |= WDIOF_SETTIMEOUT;
+	return 0;
+}
+
+static int ztwd_set_timeout(struct watchdog_driver *d, int timeout)
+{
+    	uint8_t value;
+
+	trace("%p, %i", d->driver.name, timeout);
+	if (timeout < 0) {
+	    	dbg("invalid time specifed"); 
+	    	return 1;
+	}
+
+	if (timeout == 0) {
+		ztwd_stop(d);
+		return 0;
+	}
+	if (timeout == 1)
+		timeout = WD_TC_1S;
+	else if (timeout <= 8)
+		timeout = WD_TC_8S;
+	else if (timeout <= 32)
+	    	timeout = WD_TC_32S;
+	else if (timeout <= 64)
+	    	timeout = WD_TC_64S;
+	else if (timeout <= 128)
+	    	timeout = WD_TC_128S;
+	else if (timeout <= 256)
+	    	timeout = WD_TC_256S;
+	else
+	    	timeout = WD_TC_256S;
+	
+	value = inb(WD_CTL_REG);
+	value &= ~WD_TC_256S;
+	value |= timeout;
+	dbg("timeout value set to %X", value);
+	outb (value, WD_CTL_REG);
+	return 0;
+}
+
+static int ztwd_get_options(struct watchdog_driver *d, int *c)
+{
+	trace("%s, %p", d->driver.name, c);
+	*c = WDIOS_DISABLECARD|WDIOS_ENABLECARD;
+	return 0;
+}
+
+static int ztwd_get_nowayout(struct watchdog_driver *d, int *n)
+{
+	trace("%s, %p", d->driver.name, n);
+	*n = nowayout;
+	return 0;
+}
+
+static int ztwd_set_nowayout(struct watchdog_driver *d, int n)
+{
+	trace("%s, %i", d->driver.name, n);
+	nowayout = n;
+	return 0;
+}
+
+static struct watchdog_ops ztwd_ops = {
+	.start                 = ztwd_start,
+	.stop                  = ztwd_stop,
+	.keepalive             = ztwd_keepalive,
+	.get_timeout           = ztwd_get_timeout,
+	.set_timeout           = ztwd_set_timeout,
+	.get_nowayout          = ztwd_get_nowayout,
+	.set_nowayout          = ztwd_set_nowayout,
+	.get_options           = ztwd_get_options,
+	.get_bootstatus        = ztwd_get_bootstatus,
+	.get_status            = ztwd_get_status,
+	/* get/set_temppanic not implemented */
+	/* get_firmware_version not implemented */
+};
+
+static struct watchdog_driver ztwd_driver = {
+	.ops = &ztwd_ops,
+	.driver = {
+		.name		= "ztwd",
+		.bus		= &system_bus_type,
+		.devclass       = &watchdog_devclass,
+	}
+};
+
+/* 
+ * ZT55XX specific controls 
+ */
+
+/* enabling the pretimeout (stage 1 timeout) will cause either a */
+/* NMI or INIT to happen when the stage 1 timer expires */
+static ssize_t pretimeout_enable_show(struct device_driver * d, char * buf)
+{
+	trace("%s, %p", d->name, buf);
+	return sprintf(buf, "%i\n",pretimeout);
+}
+static ssize_t pretimeout_enable_store(struct device_driver *d,
+				       const char * buf, 
+				       size_t count)
+{
+	trace("%s, %p, %i", d->name, buf, count);
+	if (sscanf(buf,"%i",&pretimeout) != 1)
+		return -EINVAL;
+
+	return count;
+}
+DRIVER_ATTR(pretimeout_enable,0644,pretimeout_enable_show,
+	    pretimeout_enable_store);
+
+/* 1 = NMI; 0 = INIT */
+static ssize_t pretimeout_action_show(struct device_driver * d, char * buf)
+{
+	uint8_t value;
+	
+	trace("%s, %p", d->name, buf);
+	value = inb(WD_CTL_REG);
+	return sprintf(buf, "%i\n",value&WD_STAGE1_ACTION_MASK?1:0);
+}
+static ssize_t pretimeout_action_store(struct device_driver *d,
+				       const char * buf, 
+				       size_t count)
+{
+	int tmp;
+	uint8_t value;
+
+	trace("%s, %p, %i", d->name, buf, count);
+	if (sscanf(buf,"%i",&tmp) != 1)
+		return -EINVAL;
+
+	value = inb(WD_CTL_REG);
+	if (tmp)
+		value |= WD_STAGE1_ACTION_MASK;
+	else
+		value &= ~WD_STAGE1_ACTION_MASK;
+	outb(value, WD_CTL_REG);
+	return count;
+}
+DRIVER_ATTR(pretimeout_action,0644,pretimeout_action_show,
+	    pretimeout_action_store);
+
+static int __init ztwd_init(void)
+{
+	int ret = 0;
+    	uint8_t value;
+
+	trace();
+	if (!request_region(WD_CTL_REG, 1, "ZT55XX Watchdog")) {
+		err("Unable to reserve io region 0x%2x", WD_CTL_REG);
+		return -EBUSY;
+	}
+
+	/* determine if the watchdog was previously tripped */
+	value = inb(WD_CTL_REG);	
+	if (value & WD_STAGE2_MONITOR_MASK) {
+		dbg("previous stage 2 watchdog timeout detected");
+		bootstatus = WDIOF_CARDRESET;
+
+		/* clear the stage 1 & 2 monitor flags */
+		value &= 0x3F;
+		outb(value, WD_CTL_REG);
+	}	
+
+	/* set the timeout before we give anyone */
+	/* a chance to start the watchdog device ticking */
+	if (ztwd_set_timeout(&ztwd_driver, DEFAULT_TIMEOUT))
+		return -EFAULT;
+
+	ret = watchdog_driver_register(&ztwd_driver);
+	if (ret) {
+		err("failed to register watchdog device");
+		return -ENODEV;
+	}
+
+	/* create zt55xx specific sysfs control files */
+	driver_create_file(&ztwd_driver.driver, 
+			   &driver_attr_pretimeout_enable);
+	driver_create_file(&ztwd_driver.driver, 
+			   &driver_attr_pretimeout_action);
+	return 0;
+}
+
+static void __exit ztwd_exit(void)
+{
+	trace();
+
+	/* remove zt55xx specific sysfs control files */
+	driver_remove_file(&ztwd_driver.driver, 
+			   &driver_attr_pretimeout_enable);
+	driver_remove_file(&ztwd_driver.driver, 
+			   &driver_attr_pretimeout_action);
+
+	release_region(WD_CTL_REG, 1);
+	watchdog_driver_unregister(&ztwd_driver);
+}
+
+module_init(ztwd_init);
+module_exit(ztwd_exit);
+MODULE_LICENSE("GPL");


      parent reply	other threads:[~2003-02-21 23:39 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-02-21 23:21 [PATCH][2.5] Sysfs enabling watchdog infrastructure Rusty Lynch
2003-02-21 23:31 ` Rusty Lynch
2003-02-21 23:36 ` Rusty Lynch [this message]

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=1045870570.1037.13.camel@vmhack \
    --to=rusty@linux.co.intel.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox