<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.mediawiki.compulab.com/w/index.php?action=history&amp;feed=atom&amp;title=Sbc-fitpc2-wdt.patch</id>
	<title>Sbc-fitpc2-wdt.patch - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.mediawiki.compulab.com/w/index.php?action=history&amp;feed=atom&amp;title=Sbc-fitpc2-wdt.patch"/>
	<link rel="alternate" type="text/html" href="https://www.mediawiki.compulab.com/w/index.php?title=Sbc-fitpc2-wdt.patch&amp;action=history"/>
	<updated>2026-05-03T10:25:27Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://www.mediawiki.compulab.com/w/index.php?title=Sbc-fitpc2-wdt.patch&amp;diff=623&amp;oldid=prev</id>
		<title>Denis at 11:14, 19 August 2009</title>
		<link rel="alternate" type="text/html" href="https://www.mediawiki.compulab.com/w/index.php?title=Sbc-fitpc2-wdt.patch&amp;diff=623&amp;oldid=prev"/>
		<updated>2009-08-19T11:14:54Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;This is a patch kernel patch for '''SBC-FITPC2 Watchdog'''. It will be included in official linux tree in future versions.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig&lt;br /&gt;
index b1ccc04..1940a08 100644&lt;br /&gt;
--- a/drivers/watchdog/Kconfig&lt;br /&gt;
+++ b/drivers/watchdog/Kconfig&lt;br /&gt;
@@ -369,6 +369,28 @@ config SC520_WDT&lt;br /&gt;
 	  You can compile this driver directly into the kernel, or use&lt;br /&gt;
 	  it as a module.  The module will be called sc520_wdt.&lt;br /&gt;
 &lt;br /&gt;
+config SBC_FITPC2_WATCHDOG&lt;br /&gt;
+	tristate &amp;quot;Compulab SBC-FITPC2 watchdog&amp;quot;&lt;br /&gt;
+	depends on X86&lt;br /&gt;
+	---help---&lt;br /&gt;
+	  This is the driver for the built-in watchdog timer on the fit-PC2&lt;br /&gt;
+	  Single-board computer made by Compulab.&lt;br /&gt;
+&lt;br /&gt;
+	  It`s possible to enable watchdog timer either from BIOS (F2) or from booted Linux.&lt;br /&gt;
+	  When &amp;quot;Watchdog Timer Value&amp;quot; enabled one can set 31-255 s operational range.&lt;br /&gt;
+&lt;br /&gt;
+	  Entering BIOS setup temporary disables watchdog operation regardless to current state,&lt;br /&gt;
+	  so system will not be restarted while user in BIOS setup.&lt;br /&gt;
+&lt;br /&gt;
+	  Once watchdog was enabled the system will be restarted every&lt;br /&gt;
+	  &amp;quot;Watchdog Timer Value&amp;quot; period, so to prevent it user can restart or&lt;br /&gt;
+	  disable the watchdog.&lt;br /&gt;
+&lt;br /&gt;
+	  To compile this driver as a module, choose M here: the&lt;br /&gt;
+	  module will be called sbc_fitpc2_wdt.&lt;br /&gt;
+&lt;br /&gt;
+	  Most people will say N.&lt;br /&gt;
+&lt;br /&gt;
 config EUROTECH_WDT&lt;br /&gt;
 	tristate &amp;quot;Eurotech CPU-1220/1410 Watchdog Timer&amp;quot;&lt;br /&gt;
 	depends on X86&lt;br /&gt;
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile&lt;br /&gt;
index 3d77429..6c58e7c 100644&lt;br /&gt;
--- a/drivers/watchdog/Makefile&lt;br /&gt;
+++ b/drivers/watchdog/Makefile&lt;br /&gt;
@@ -64,6 +64,7 @@ obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o&lt;br /&gt;
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o&lt;br /&gt;
 obj-$(CONFIG_GEODE_WDT) += geodewdt.o&lt;br /&gt;
 obj-$(CONFIG_SC520_WDT) += sc520_wdt.o&lt;br /&gt;
+obj-$(CONFIG_SBC_FITPC2_WATCHDOG) += sbc_fitpc2_wdt.o&lt;br /&gt;
 obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o&lt;br /&gt;
 obj-$(CONFIG_IB700_WDT) += ib700wdt.o&lt;br /&gt;
 obj-$(CONFIG_IBMASR) += ibmasr.o&lt;br /&gt;
diff -Nru /dev/null b/drivers/watchdog/sbc_fitpc2_wdt.c&lt;br /&gt;
--- /dev/null&lt;br /&gt;
+++ b/drivers/watchdog/sbc_fitpc2_wdt.c	2009-08-04 09:38:02.670583765 +0000&lt;br /&gt;
@@ -0,0 +1,267 @@&lt;br /&gt;
+/*&lt;br /&gt;
+ * Watchdog driver for SBC-FITPC2 board&lt;br /&gt;
+ *&lt;br /&gt;
+ * Author: Denis Turischev &amp;lt;denis@compulab.co.il&amp;gt;&lt;br /&gt;
+ *&lt;br /&gt;
+ * Adapted from the IXP2000 watchdog driver by Deepak Saxena.&lt;br /&gt;
+ *&lt;br /&gt;
+ * This file is licensed under  the terms of the GNU General Public&lt;br /&gt;
+ * License version 2. This program is licensed &amp;quot;as is&amp;quot; without any&lt;br /&gt;
+ * warranty of any kind, whether express or implied.&lt;br /&gt;
+ */&lt;br /&gt;
+&lt;br /&gt;
+#define pr_fmt(fmt) KBUILD_MODNAME &amp;quot; WATCHDOG: &amp;quot; fmt&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;lt;linux/module.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/types.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/miscdevice.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/watchdog.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/ioport.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/delay.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/fs.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/init.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/moduleparam.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/dmi.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/io.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/uaccess.h&amp;gt;&lt;br /&gt;
+&lt;br /&gt;
+#include &amp;lt;asm/system.h&amp;gt;&lt;br /&gt;
+&lt;br /&gt;
+static int nowayout = WATCHDOG_NOWAYOUT;&lt;br /&gt;
+static unsigned int margin = 60;	/* (secs) Default is 1 minute */&lt;br /&gt;
+static unsigned long wdt_status;&lt;br /&gt;
+static DEFINE_SPINLOCK(wdt_lock);&lt;br /&gt;
+&lt;br /&gt;
+#define WDT_IN_USE		0&lt;br /&gt;
+#define WDT_OK_TO_CLOSE		1&lt;br /&gt;
+&lt;br /&gt;
+#define COMMAND_PORT		0x4c&lt;br /&gt;
+#define DATA_PORT		0x48&lt;br /&gt;
+&lt;br /&gt;
+#define IFACE_ON_COMMAND	1&lt;br /&gt;
+#define REBOOT_COMMAND		2&lt;br /&gt;
+&lt;br /&gt;
+#define WATCHDOG_NAME 		&amp;quot;SBC-FITPC2 Watchdog&amp;quot;&lt;br /&gt;
+&lt;br /&gt;
+static void wdt_send_data(unsigned char command, unsigned char data)&lt;br /&gt;
+{&lt;br /&gt;
+	outb(command, COMMAND_PORT);&lt;br /&gt;
+	mdelay(100);&lt;br /&gt;
+	outb(data, DATA_PORT);&lt;br /&gt;
+	mdelay(200);&lt;br /&gt;
+}&lt;br /&gt;
+&lt;br /&gt;
+static void wdt_enable(void)&lt;br /&gt;
+{&lt;br /&gt;
+	spin_lock(&amp;amp;wdt_lock);&lt;br /&gt;
+	wdt_send_data(IFACE_ON_COMMAND, 1);&lt;br /&gt;
+	wdt_send_data(REBOOT_COMMAND, margin);&lt;br /&gt;
+	spin_unlock(&amp;amp;wdt_lock);&lt;br /&gt;
+}&lt;br /&gt;
+&lt;br /&gt;
+static void wdt_disable(void)&lt;br /&gt;
+{&lt;br /&gt;
+	spin_lock(&amp;amp;wdt_lock);&lt;br /&gt;
+	wdt_send_data(IFACE_ON_COMMAND, 0);&lt;br /&gt;
+	wdt_send_data(REBOOT_COMMAND, 0);&lt;br /&gt;
+	spin_unlock(&amp;amp;wdt_lock);&lt;br /&gt;
+}&lt;br /&gt;
+&lt;br /&gt;
+static int fitpc2_wdt_open(struct inode *inode, struct file *file)&lt;br /&gt;
+{&lt;br /&gt;
+	if (test_and_set_bit(WDT_IN_USE, &amp;amp;wdt_status))&lt;br /&gt;
+		return -EBUSY;&lt;br /&gt;
+&lt;br /&gt;
+	clear_bit(WDT_OK_TO_CLOSE, &amp;amp;wdt_status);&lt;br /&gt;
+&lt;br /&gt;
+	wdt_enable();&lt;br /&gt;
+&lt;br /&gt;
+	return nonseekable_open(inode, file);&lt;br /&gt;
+}&lt;br /&gt;
+&lt;br /&gt;
+static ssize_t fitpc2_wdt_write(struct file *file, const char *data,&lt;br /&gt;
+						size_t len, loff_t *ppos)&lt;br /&gt;
+{&lt;br /&gt;
+	size_t i;&lt;br /&gt;
+&lt;br /&gt;
+	if (!len)&lt;br /&gt;
+		return 0;&lt;br /&gt;
+&lt;br /&gt;
+	if (nowayout) {&lt;br /&gt;
+		len = 0;&lt;br /&gt;
+		goto out;&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	clear_bit(WDT_OK_TO_CLOSE, &amp;amp;wdt_status);&lt;br /&gt;
+&lt;br /&gt;
+	for (i = 0; i != len; i++) {&lt;br /&gt;
+		char c;&lt;br /&gt;
+&lt;br /&gt;
+		if (get_user(c, data + i))&lt;br /&gt;
+			return -EFAULT;&lt;br /&gt;
+&lt;br /&gt;
+		if (c == 'V')&lt;br /&gt;
+			set_bit(WDT_OK_TO_CLOSE, &amp;amp;wdt_status);&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+out:&lt;br /&gt;
+	wdt_enable();&lt;br /&gt;
+&lt;br /&gt;
+	return len;&lt;br /&gt;
+}&lt;br /&gt;
+&lt;br /&gt;
+&lt;br /&gt;
+static struct watchdog_info ident = {&lt;br /&gt;
+	.options	= WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |&lt;br /&gt;
+				WDIOF_KEEPALIVEPING,&lt;br /&gt;
+	.identity	= WATCHDOG_NAME,&lt;br /&gt;
+};&lt;br /&gt;
+&lt;br /&gt;
+&lt;br /&gt;
+static long fitpc2_wdt_ioctl(struct file *file, unsigned int cmd,&lt;br /&gt;
+							unsigned long arg)&lt;br /&gt;
+{&lt;br /&gt;
+	int ret = -ENOTTY;&lt;br /&gt;
+	int time;&lt;br /&gt;
+&lt;br /&gt;
+	switch (cmd) {&lt;br /&gt;
+	case WDIOC_GETSUPPORT:&lt;br /&gt;
+		ret = copy_to_user((struct watchdog_info *)arg, &amp;amp;ident,&lt;br /&gt;
+				   sizeof(ident)) ? -EFAULT : 0;&lt;br /&gt;
+		break;&lt;br /&gt;
+&lt;br /&gt;
+	case WDIOC_GETSTATUS:&lt;br /&gt;
+		ret = put_user(0, (int *)arg);&lt;br /&gt;
+		break;&lt;br /&gt;
+&lt;br /&gt;
+	case WDIOC_GETBOOTSTATUS:&lt;br /&gt;
+		ret = put_user(0, (int *)arg);&lt;br /&gt;
+		break;&lt;br /&gt;
+&lt;br /&gt;
+	case WDIOC_KEEPALIVE:&lt;br /&gt;
+		wdt_enable();&lt;br /&gt;
+		ret = 0;&lt;br /&gt;
+		break;&lt;br /&gt;
+&lt;br /&gt;
+	case WDIOC_SETTIMEOUT:&lt;br /&gt;
+		ret = get_user(time, (int *)arg);&lt;br /&gt;
+		if (ret)&lt;br /&gt;
+			break;&lt;br /&gt;
+&lt;br /&gt;
+		if (time &amp;lt; 31 || time &amp;gt; 255) {&lt;br /&gt;
+			ret = -EINVAL;&lt;br /&gt;
+			break;&lt;br /&gt;
+		}&lt;br /&gt;
+&lt;br /&gt;
+		margin = time;&lt;br /&gt;
+		wdt_enable();&lt;br /&gt;
+		/* Fall through */&lt;br /&gt;
+&lt;br /&gt;
+	case WDIOC_GETTIMEOUT:&lt;br /&gt;
+		ret = put_user(margin, (int *)arg);&lt;br /&gt;
+		break;&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	return ret;&lt;br /&gt;
+}&lt;br /&gt;
+&lt;br /&gt;
+static int fitpc2_wdt_release(struct inode *inode, struct file *file)&lt;br /&gt;
+{&lt;br /&gt;
+	if (test_bit(WDT_OK_TO_CLOSE, &amp;amp;wdt_status)) {&lt;br /&gt;
+		wdt_disable();&lt;br /&gt;
+		pr_info(&amp;quot;Device disabled\n&amp;quot;);&lt;br /&gt;
+	} else {&lt;br /&gt;
+		pr_warning(&amp;quot;Device closed unexpectedly -&amp;quot;&lt;br /&gt;
+			&amp;quot; timer will not stop\n&amp;quot;);&lt;br /&gt;
+		wdt_enable();&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	clear_bit(WDT_IN_USE, &amp;amp;wdt_status);&lt;br /&gt;
+	clear_bit(WDT_OK_TO_CLOSE, &amp;amp;wdt_status);&lt;br /&gt;
+&lt;br /&gt;
+	return 0;&lt;br /&gt;
+}&lt;br /&gt;
+&lt;br /&gt;
+&lt;br /&gt;
+static const struct file_operations fitpc2_wdt_fops = {&lt;br /&gt;
+	.owner		= THIS_MODULE,&lt;br /&gt;
+	.llseek		= no_llseek,&lt;br /&gt;
+	.write		= fitpc2_wdt_write,&lt;br /&gt;
+	.unlocked_ioctl	= fitpc2_wdt_ioctl,&lt;br /&gt;
+	.open		= fitpc2_wdt_open,&lt;br /&gt;
+	.release	= fitpc2_wdt_release,&lt;br /&gt;
+};&lt;br /&gt;
+&lt;br /&gt;
+static struct miscdevice fitpc2_wdt_miscdev = {&lt;br /&gt;
+	.minor		= WATCHDOG_MINOR,&lt;br /&gt;
+	.name		= &amp;quot;watchdog&amp;quot;,&lt;br /&gt;
+	.fops		= &amp;amp;fitpc2_wdt_fops,&lt;br /&gt;
+};&lt;br /&gt;
+&lt;br /&gt;
+static int __init fitpc2_wdt_init(void)&lt;br /&gt;
+{&lt;br /&gt;
+	int err;&lt;br /&gt;
+&lt;br /&gt;
+	if (strcmp(&amp;quot;SBC-FITPC2&amp;quot;, dmi_get_system_info(DMI_BOARD_NAME))) {&lt;br /&gt;
+		pr_info(&amp;quot;board name is: %s. Should be SBC-FITPC2\n&amp;quot;,&lt;br /&gt;
+			dmi_get_system_info(DMI_BOARD_NAME));&lt;br /&gt;
+		return -ENODEV;&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	if (!request_region(COMMAND_PORT, 1, WATCHDOG_NAME)) {&lt;br /&gt;
+		pr_err(&amp;quot;I/O address 0x%04x already in use\n&amp;quot;, COMMAND_PORT);&lt;br /&gt;
+		return -EIO;&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	if (!request_region(DATA_PORT, 1, WATCHDOG_NAME)) {&lt;br /&gt;
+		pr_err(&amp;quot;I/O address 0x%04x already in use\n&amp;quot;, DATA_PORT);&lt;br /&gt;
+		err = -EIO;&lt;br /&gt;
+		goto err_data_port;&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	if (margin &amp;lt; 31 || margin &amp;gt; 255) {&lt;br /&gt;
+		pr_err(&amp;quot;margin must be in range 31 - 255&amp;quot;&lt;br /&gt;
+		       &amp;quot; seconds, you tried to set %d\n&amp;quot;, margin);&lt;br /&gt;
+		err = -EINVAL;&lt;br /&gt;
+		goto err_margin;&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	err = misc_register(&amp;amp;fitpc2_wdt_miscdev);&lt;br /&gt;
+	if (!err) {&lt;br /&gt;
+		pr_err(&amp;quot;cannot register miscdev on minor=%d (err=%d)\n&amp;quot;,&lt;br /&gt;
+							WATCHDOG_MINOR, err);&lt;br /&gt;
+		goto err_margin;&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	return 0;&lt;br /&gt;
+&lt;br /&gt;
+err_margin:&lt;br /&gt;
+	release_region(DATA_PORT, 1);&lt;br /&gt;
+err_data_port:&lt;br /&gt;
+	release_region(COMMAND_PORT, 1);&lt;br /&gt;
+&lt;br /&gt;
+	return err;&lt;br /&gt;
+}&lt;br /&gt;
+&lt;br /&gt;
+static void __exit fitpc2_wdt_exit(void)&lt;br /&gt;
+{&lt;br /&gt;
+	misc_deregister(&amp;amp;fitpc2_wdt_miscdev);&lt;br /&gt;
+	release_region(DATA_PORT, 1);&lt;br /&gt;
+	release_region(COMMAND_PORT, 1);&lt;br /&gt;
+}&lt;br /&gt;
+&lt;br /&gt;
+module_init(fitpc2_wdt_init);&lt;br /&gt;
+module_exit(fitpc2_wdt_exit);&lt;br /&gt;
+&lt;br /&gt;
+MODULE_AUTHOR(&amp;quot;Denis Turischev &amp;lt;denis@compulab.co.il&amp;gt;&amp;quot;);&lt;br /&gt;
+MODULE_DESCRIPTION(&amp;quot;SBC-FITPC2 Watchdog&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+module_param(margin, int, 0);&lt;br /&gt;
+MODULE_PARM_DESC(margin, &amp;quot;Watchdog margin in seconds (default 60s)&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+module_param(nowayout, int, 0);&lt;br /&gt;
+MODULE_PARM_DESC(nowayout, &amp;quot;Watchdog cannot be stopped once started&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+MODULE_LICENSE(&amp;quot;GPL&amp;quot;);&lt;br /&gt;
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);&lt;br /&gt;
+&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Denis</name></author>
		
	</entry>
</feed>