mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Andreas Steinmetz <ast@domdv.de>
To: linux-kernel@vger.kernel.org
Subject: [PATCH] Quancom ISA Watchdog 1/2 (2.4.13pre6)
Date: Tue, 23 Oct 2001 13:20:49 +0200 (CEST)	[thread overview]
Message-ID: <XFMail.20011023132049.ast@domdv.de> (raw)

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

The attached patch is a driver for the Quancom ISA Watchdog cards 1 and 2.

Vendor information:

http://www.quancom.de/qprod01/eng/pb/watchdog1.htm
http://www.quancom.de/qprod01/eng/pb/watchdog2.htm

Quancom did ship (quite a while ago) the cards with a 2.2.x driver for Watchdog
1/2/3 based on wdt.c, thus the driver is GPL. As I don't have the Watchdog 3
version (Watchdog 1 and 2 are the same from the driver's view) I did strip down
the driver to Watchdog 1/2 and ported it to 2.4.x.


Andreas Steinmetz
D.O.M. Datenverarbeitung GmbH

[-- Attachment #2: quancom.patch --]
[-- Type: text/plain, Size: 7334 bytes --]

diff -rNu linux/drivers/char/Config.in linux-fixed/drivers/char/Config.in
--- linux/drivers/char/Config.in	Tue Oct 23 12:57:58 2001
+++ linux-fixed/drivers/char/Config.in	Tue Oct 23 13:12:07 2001
@@ -167,6 +167,7 @@
       fi
    fi
    tristate '  ZF MachZ Watchdog' CONFIG_MACHZ_WDT
+   tristate '  Quancom Watchdog1/2' CONFIG_QUANCOM
 fi
 endmenu
 
diff -rNu linux/drivers/char/Makefile linux-fixed/drivers/char/Makefile
--- linux/drivers/char/Makefile	Tue Oct 23 12:57:59 2001
+++ linux-fixed/drivers/char/Makefile	Tue Oct 23 13:12:07 2001
@@ -229,6 +229,7 @@
 obj-$(CONFIG_977_WATCHDOG) += wdt977.o
 obj-$(CONFIG_I810_TCO) += i810-tco.o
 obj-$(CONFIG_MACHZ_WDT) += machzwd.o
+obj-$(CONFIG_QUANCOM) += quancom.o
 obj-$(CONFIG_SH_WDT) += shwdt.o
 obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
 
diff -rNu linux/drivers/char/quancom.c linux-fixed/drivers/char/quancom.c
--- linux/drivers/char/quancom.c	Thu Jan  1 01:00:00 1970
+++ linux-fixed/drivers/char/quancom.c	Tue Oct 23 13:12:07 2001
@@ -0,0 +1,285 @@
+/*
+ * Quancom WATCHDOG1/2 driver (www.quancom.de)
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+
+static int wdog_is_open=0;
+
+/*
+ *	You must set these - there is no sane way to probe for this board.
+ *	You can use wdt=x to set these now.
+ */
+ 
+static int io=0x1d0;
+
+#define DRIVER_VERSION 1
+#define DRIVER_REVISION 02
+
+#ifndef MODULE
+
+/**
+ *	wdog_setup:
+ *	@str: command line string
+ *
+ *	Setup options. The board isn't really probe-able so we have to
+ *	get the user to tell us the configuration. Sane people build it 
+ *	modular but the others come here.
+ */
+ 
+static int __init wdog_setup(char *str)
+{
+	int ints[4];
+
+	str = get_options (str, ARRAY_SIZE(ints), ints);
+
+	if (ints[0] > 0)
+	{
+		io = ints[1];
+	}
+
+	return 1;
+}
+
+__setup("wdt=", wdog_setup);
+
+#endif /* !MODULE */
+
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "WDT io port (default=0x1d0)");
+ 
+/*
+ *	Kernel methods.
+ */
+
+static ssize_t wdog_read(struct file * file, char * buf, size_t count,
+	loff_t * ppos)
+{
+	/* No can do */
+	return -EINVAL;
+}
+
+static int wdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	unsigned long arg) 
+{
+	/* No can do */
+	return -EINVAL;
+}
+
+/**
+ *	wdog_write:
+ *	@file: file handle to the watchdog
+ *	@buf: buffer to write (unused as data does not matter here 
+ *	@count: count of bytes
+ *	@ppos: pointer to the position to write. No seeks allowed
+ *
+ *	A write to a watchdog device is defined as a keepalive signal. Any
+ *	write of data will do, as we we don't define content meaning.
+ */
+ 
+static ssize_t wdog_write(struct file *file, const char *buf, size_t count, lof
f_t *ppos)
+{
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	if(count)
+	{
+		outb_p(0x00,io);
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ *	wdog_open:
+ *	@inode: inode of device
+ *	@file: file handle to device
+ *
+ *	One of our two misc devices has been opened. The watchdog device is
+ *	single open and on opening we load the counters. Counter zero is a 
+ *	100Hz cascade, into counter 1 which downcounts to reboot. When the
+ *	counter triggers counter 2 downcounts the length of the reset pulse
+ *	which set set to be as long as possible. 
+ */
+ 
+static int wdog_open(struct inode *inode, struct file *file)
+{
+	switch(MINOR(inode->i_rdev))
+	{
+		case WATCHDOG_MINOR:
+			if(wdog_is_open)
+				return -EBUSY;
+			/*
+			 *	Activate 
+			 */
+	 
+			wdog_is_open=1;
+			outb_p(0x00,io);
+			return 0;
+		default:
+			return -ENODEV;
+	}
+}
+
+/**
+ *	wdog_close:
+ *	@inode: inode to board
+ *	@file: file handle to board
+ *
+ *	The watchdog has a configurable API. There is a religious dispute 
+ *	between people who want their watchdog to be able to shut down and 
+ *	those who want to be sure if the watchdog manager dies the machine
+ *	reboots. In the former case we disable the counters, in the latter
+ *	case you have to open it again very soon.
+ */
+ 
+static int wdog_release(struct inode *inode, struct file *file)
+{
+	lock_kernel();
+	if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
+	{
+#ifndef CONFIG_WATCHDOG_NOWAYOUT	
+		outb_p(0x00,io+1);
+#endif		
+		wdog_is_open=0;
+	}
+	unlock_kernel();
+	return 0;
+}
+
+/**
+ *	notify_sys:
+ *	@this: our notifier block
+ *	@code: the event being reported
+ *	@unused: unused
+ *
+ *	Our notifier is called on system shutdowns. We want to turn the card
+ *	off at reboot otherwise the machine will reboot again during memory
+ *	test or worse yet during the following fsck. This would suck, in fact
+ *	trust me - if it happens it does suck.
+ */
+
+static int wdog_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if(code==SYS_DOWN || code==SYS_HALT)
+	{
+		outb_p(0x00,io+1);
+	}
+	return NOTIFY_DONE;
+}
+ 
+/*
+ *	Kernel Interfaces
+ */
+ 
+ 
+static struct file_operations wdog_fops = {
+	owner:		THIS_MODULE,
+	llseek:		no_llseek,
+	read:		wdog_read,
+	write:		wdog_write,
+	ioctl:		wdog_ioctl,
+	open:		wdog_open,
+	release:	wdog_release,
+};
+
+static struct miscdevice wdog_miscdev=
+{
+	WATCHDOG_MINOR,
+	"watchdog",
+	&wdog_fops
+};
+
+/*
+ *	The WDT card needs to learn about soft shutdowns in order to
+ *	turn the timebomb registers off. 
+ */
+ 
+static struct notifier_block wdog_notifier=
+{
+	wdog_notify_sys,
+	NULL,
+	0
+};
+
+/**
+ *	cleanup_module:
+ *
+ *	Unload the watchdog. You cannot do this with any file handles open.
+ *	If your watchdog is set to continue ticking on close and you unload
+ *	it, well it keeps ticking. We won't get the interrupt but the board
+ *	will not touch PC memory so all is fine. You just have to load a new
+ *	module in 60 seconds or reboot.
+ */
+ 
+static void __exit wdog_exit(void)
+{
+	misc_deregister(&wdog_miscdev);
+	unregister_reboot_notifier(&wdog_notifier);
+	release_region(io,16);
+}
+
+/**
+ * 	wdog_init:
+ *
+ *	Set up the WDT watchdog board. All we have to do is grab the
+ *	resources we require and bitch if anyone beat us to them.
+ *	The open() function will actually kick the board off.
+ */
+ 
+static int __init wdog_init(void)
+{
+	int ret;
+
+	ret = misc_register(&wdog_miscdev);
+	if (ret) {
+		printk(KERN_ERR "wdt: can't misc_register on minor=%d\n", WATCHDOG_MINOR);
+		goto out;
+	}
+	if (!request_region(io, 16, "Watchdog1/2")) {
+		printk(KERN_ERR "wdt: IO %X is not free.\n", io);
+		ret = -EBUSY;
+		goto outmisc;
+	}
+	ret = register_reboot_notifier(&wdog_notifier);
+	if(ret) {
+		printk(KERN_ERR "wdt: can't register reboot notifier (err=%d)\n", ret);
+		goto outreg;
+	}
+
+	ret = 0;
+	printk(KERN_INFO "Quancom Watchdog1/2 driver v%d.%02d at 0x%X\n",
+		DRIVER_VERSION, DRIVER_REVISION, io);
+out:
+	return ret;
+
+outreg:
+	release_region(io,16);
+outmisc:
+	misc_deregister(&wdog_miscdev);
+	goto out;
+}
+
+module_init(wdog_init);
+module_exit(wdog_exit);
+

                 reply	other threads:[~2001-10-23 11:23 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=XFMail.20011023132049.ast@domdv.de \
    --to=ast@domdv.de \
    --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

all inboxes | Powered by JetHome®