linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Watchdog: Winsystems EPX-C3 SBC
@ 2006-01-14  2:59 Calin A. Culianu
  2006-01-14 19:24 ` Alan Cox
  0 siblings, 1 reply; 4+ messages in thread
From: Calin A. Culianu @ 2006-01-14  2:59 UTC (permalink / raw)
  To: linux-kernel, akpm; +Cc: Willy Tarreau

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1223 bytes --]


Hi all,

This is a 2.6 patch that adds support for the watchdog timer built into 
the EPX-C3 single board computer manufactured by Winsystems, Inc.

Driver details:

This is for x86 only.  This watchdog is pretty basic and simple.  It is 
only configurable via jumpers on the SBC, and it only has either a 1.5s or 
200s interval.  The watchdog can either be auto-configured to start as 
soon as the machine powers up (bad idea for the 1.5s interval!) or it can 
be enabled and disabled by writing to io port 0x1ee.  Petting the watchdog 
involves writing any value to io port 0x1ef.

The only unfortunate thing about this watchdog (and it is not at all 
uncommmon in watchdogs that linux supports) is that it is not a PCI or 
ISA-PNP device and as such it isn't at all probeable.  Either the watchdog 
exists as 2 bytes at 0x1ee, or it doesn't.  Thus, using this driver on a 
machine that doesn't have that watchdog can potentially hang/crash the 
system, etc.  So only use this driver if you in fact are on a Winsystems 
EPX-C3 SBC.

Anyway this driver fits into the already-existing watchdog framework quite 
nicely and I already tested it on my EPX-C3 and it works like a 
charm.

Please accept it! :)

Thanks,

-Calin

[-- Attachment #2: Type: TEXT/PLAIN, Size: 7811 bytes --]

diff -urN linux-2.6.15.prepatch/drivers/char/watchdog/Kconfig linux-2.6.15/drivers/char/watchdog/Kconfig
--- linux-2.6.15.prepatch/drivers/char/watchdog/Kconfig	2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/drivers/char/watchdog/Kconfig	2006-01-13 14:24:30.000000000 -0500
@@ -395,6 +395,28 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called machzwd.
 
+config SBC_EPX_C3_WATCHDOG
+	tristate "Winsystems SBC EPX-C3 watchdog"
+	depends on WATCHDOG && X86
+	---help---
+	  This is the driver for the built-in watchdog timer on the EPX-C3
+	  Single-board computer made by Winsystems, Inc.  
+	  
+	  *Note*: This hardware watchdog is not probeable and thus there 
+	  is no way to know if writing to its IO address will corrupt 
+	  your system or have any real effect.  The only way to be sure
+	  that this driver does what you want is to make sure you 
+	  are runnning it on an EPX-C3 from Winsystems with the watchdog
+	  timer at IO address 0x1ee and 0x1ef.  It will write to both those
+	  IO ports.  Basically, the assumption is made that if you compile
+	  this driver into your kernel and/or load it as a module, that you
+	  know what you are doing and that you are in fact running on an
+	  EPX-C3 board!	  	  
+  
+	  To compile this driver as a module, choose M here: the
+	  module will be called sbc_epx_c3.
+	  
+	  
 # PowerPC Architecture
 
 config 8xx_WDT
diff -urN linux-2.6.15.prepatch/drivers/char/watchdog/Makefile linux-2.6.15/drivers/char/watchdog/Makefile
--- linux-2.6.15.prepatch/drivers/char/watchdog/Makefile	2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/drivers/char/watchdog/Makefile	2006-01-13 14:24:40.000000000 -0500
@@ -52,6 +52,7 @@
 obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
 obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
 obj-$(CONFIG_MACHZ_WDT) += machzwd.o
+obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
 
 # PowerPC Architecture
 obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
diff -urN linux-2.6.15.prepatch/drivers/char/watchdog/sbc_epx_c3.c linux-2.6.15/drivers/char/watchdog/sbc_epx_c3.c
--- linux-2.6.15.prepatch/drivers/char/watchdog/sbc_epx_c3.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.15/drivers/char/watchdog/sbc_epx_c3.c	2006-01-13 14:47:48.000000000 -0500
@@ -0,0 +1,214 @@
+/*
+ *	SBC EPX C3 0.1	A Hardware Watchdog Device for the Winsystems EPX-C3 single board computer
+ *
+ *	(c) Copyright 2006 Calin A. Culianu <calin@ajvar.org>, All Rights Reserved.
+ *
+ *	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.
+ *
+ *	based on softdog.c by Alan Cox <alan@redhat.com>
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define PFX "epx_c3: "
+static int epx_c3_alive;
+
+#define WATCHDOG_TIMEOUT 1		/* 1 sec default timeout */
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+#define EPXC3_WATCHDOG_CTL_REG 0x1ee /* write 1 to enable, 0 to disable */
+#define EPXC3_WATCHDOG_PET_REG 0x1ef /* write anything to pet once enabled */
+
+static void epx_c3_start(void)
+{
+	outb(1, EPXC3_WATCHDOG_CTL_REG);
+}
+
+static void epx_c3_stop(void)
+{
+
+	outb(0, EPXC3_WATCHDOG_CTL_REG);
+
+	printk(KERN_INFO PFX "Stopped watchdog timer.\n");
+}
+
+static void epx_c3_pet(void)
+{
+	outb(1, EPXC3_WATCHDOG_PET_REG);
+}
+
+/*
+ *	Allow only one person to hold it open
+ */
+static int epx_c3_open(struct inode *inode, struct file *file)
+{
+	if (epx_c3_alive)
+		return -EBUSY;
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	/* Activate timer */
+	epx_c3_start();
+	epx_c3_pet();
+
+	epx_c3_alive = 1;
+	printk(KERN_INFO "Started watchdog timer.\n");
+
+	return nonseekable_open(inode, file);
+}
+
+static int epx_c3_release(struct inode *inode, struct file *file)
+{
+	/* Shut off the timer.
+	 * Lock it in if it's a module and we defined ...NOWAYOUT */
+	if (!nowayout)
+		epx_c3_stop();		/* Turn the WDT off */
+
+	epx_c3_alive = 0;
+
+	return 0;
+}
+
+static ssize_t epx_c3_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+	/* Refresh the timer. */
+	if (len) {
+		epx_c3_pet();
+	}
+	return len;
+}
+
+static int epx_c3_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	int options, retval = -EINVAL;
+	static struct watchdog_info ident = {
+		.options		= WDIOF_KEEPALIVEPING |
+					  WDIOF_MAGICCLOSE,
+		.firmware_version	= 0,
+		.identity		= "Winsystems EPX-C3 H/W Watchdog",
+	};
+
+	switch (cmd) {
+		default:
+			return -ENOIOCTLCMD;
+		case WDIOC_GETSUPPORT:
+			if (copy_to_user((struct watchdog_info *)arg,
+					 &ident, sizeof(ident)))
+				return -EFAULT;
+			return 0;
+		case WDIOC_GETSTATUS:
+		case WDIOC_GETBOOTSTATUS:
+			return put_user(0,(int *)arg);
+		case WDIOC_KEEPALIVE:
+			epx_c3_pet();
+			return 0;
+		case WDIOC_GETTIMEOUT:
+			return put_user(WATCHDOG_TIMEOUT,(int *)arg);
+		case WDIOC_SETOPTIONS:
+		{
+			if (get_user(options, (int *)arg))
+				return -EFAULT;
+
+			if (options & WDIOS_DISABLECARD) {
+				epx_c3_stop();
+				retval = 0;
+			}
+
+			if (options & WDIOS_ENABLECARD) {
+				epx_c3_start();
+				retval = 0;
+			}
+
+			return retval;
+		}
+	}
+}
+
+static int epx_c3_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		epx_c3_stop();		/* Turn the WDT off */
+
+	return NOTIFY_DONE;
+}
+
+static struct file_operations epx_c3_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= epx_c3_write,
+	.ioctl		= epx_c3_ioctl,
+	.open		= epx_c3_open,
+	.release	= epx_c3_release,
+};
+
+static struct miscdevice epx_c3_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &epx_c3_fops,
+};
+
+static struct notifier_block epx_c3_notifier = {
+	.notifier_call = epx_c3_notify_sys,
+};
+
+static char banner[] __initdata =
+	KERN_INFO PFX "Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n";
+
+static int __init watchdog_init(void)
+{
+	int ret;
+
+	ret = register_reboot_notifier(&epx_c3_notifier);
+	if (ret) {
+		printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+			ret);
+		return ret;
+	}
+
+	ret = misc_register(&epx_c3_miscdev);
+	if (ret) {
+		printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+			WATCHDOG_MINOR, ret);
+		unregister_reboot_notifier(&epx_c3_notifier);
+		return ret;
+	}
+
+	printk(banner);
+
+	return 0;
+}
+
+static void __exit watchdog_exit(void)
+{
+	misc_deregister(&epx_c3_miscdev);
+	unregister_reboot_notifier(&epx_c3_notifier);
+}
+
+module_init(watchdog_init);
+module_exit(watchdog_exit);
+
+MODULE_AUTHOR("Calin A. Culianu <calin@ajvar.org>");
+MODULE_DESCRIPTION("Hardware Watchdog Device for Winsystems EPX-C3 SBC.  Note that there is no way to probe for this device -- so only use it if you are *sure* you are runnning on this specific SBC system from Winsystems!  It writes to IO ports 0x1ee and 0x1ef!");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

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

* Re: [PATCH] Watchdog: Winsystems EPX-C3 SBC
  2006-01-14  2:59 [PATCH] Watchdog: Winsystems EPX-C3 SBC Calin A. Culianu
@ 2006-01-14 19:24 ` Alan Cox
  2006-01-14 20:08   ` Willy Tarreau
  2006-01-29 23:47   ` Marcelo Tosatti
  0 siblings, 2 replies; 4+ messages in thread
From: Alan Cox @ 2006-01-14 19:24 UTC (permalink / raw)
  To: Calin A. Culianu; +Cc: linux-kernel, akpm, Willy Tarreau

Some quick comments:

+       if (len) {
+               epx_c3_pet();
+       }

Doesn't need brackets (minor style)

Otherwise it looks excellent but should use request_region and friends
to claim the two ports it uses.

The see the "Sign your work:" bit of Documentation/SubmittingPatches are
it looks ready to go in.

Alan


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

* Re: [PATCH] Watchdog: Winsystems EPX-C3 SBC
  2006-01-14 19:24 ` Alan Cox
@ 2006-01-14 20:08   ` Willy Tarreau
  2006-01-29 23:47   ` Marcelo Tosatti
  1 sibling, 0 replies; 4+ messages in thread
From: Willy Tarreau @ 2006-01-14 20:08 UTC (permalink / raw)
  To: Alan Cox; +Cc: Calin A. Culianu, linux-kernel, akpm

On Sat, Jan 14, 2006 at 07:24:09PM +0000, Alan Cox wrote:
> Some quick comments:
> 
> +       if (len) {
> +               epx_c3_pet();
> +       }
> 
> Doesn't need brackets (minor style)
> 
> Otherwise it looks excellent but should use request_region and friends
> to claim the two ports it uses.

You just remind me that I had to comment out the request_region in another
watchdog driver I wrote, because the hardware was mapped on I/O port 0xF2
which is within the FPU I/O space :

   00f0-00ff : fpu

I did not know how to correctly fix this problem, and I could live without
the check, but I found it dirty and never proposed it for inclusion.

It's not the first time I notice that write-only hardware share a reserved
I/O range with other components, and I don't know how to cope with this.
Perhaps it sounds logical not to request_region() as the hardware is meant
to be 100% transparent afterall ?

> The see the "Sign your work:" bit of Documentation/SubmittingPatches are
> it looks ready to go in.
> 
> Alan

Willy


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

* Re: [PATCH] Watchdog: Winsystems EPX-C3 SBC
  2006-01-14 19:24 ` Alan Cox
  2006-01-14 20:08   ` Willy Tarreau
@ 2006-01-29 23:47   ` Marcelo Tosatti
  1 sibling, 0 replies; 4+ messages in thread
From: Marcelo Tosatti @ 2006-01-29 23:47 UTC (permalink / raw)
  To: Alan Cox; +Cc: Calin A. Culianu, linux-kernel, akpm, Willy Tarreau

On Sat, Jan 14, 2006 at 07:24:09PM +0000, Alan Cox wrote:
> Some quick comments:
> 
> +       if (len) {
> +               epx_c3_pet();
> +       }
> 
> Doesn't need brackets (minor style)
> 
> Otherwise it looks excellent but should use request_region and friends
> to claim the two ports it uses.

It misses locking to protect against two concurrent writers in case of  
a shared /dev/wdt file-descriptor? 


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

end of thread, other threads:[~2006-01-30  3:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-14  2:59 [PATCH] Watchdog: Winsystems EPX-C3 SBC Calin A. Culianu
2006-01-14 19:24 ` Alan Cox
2006-01-14 20:08   ` Willy Tarreau
2006-01-29 23:47   ` Marcelo Tosatti

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).