GIT 2e9c9cf44b17ef5fa1f360bc175ed7761daf3428 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog-mm.git commit Author: Wim Van Sebroeck Date: Thu Jan 11 22:42:41 2007 +0100 [WATCHDOG] advantechwdt.c - convert to platform_device part 2 Convert the reboot_notifier into the platform_device's shutdown method Signed-off-by: Wim Van Sebroeck commit c2bd11c7cbba45c3a1d850a8a29855cb4d61654c Author: Wim Van Sebroeck Date: Thu Jan 11 22:35:40 2007 +0100 [WATCHDOG] advantechwdt.c - convert to platform_device Convert the advantechwdt watchdog into a platform_device Signed-off-by: Wim Van Sebroeck commit 0349a363e23a0533e081ca320c837bc08247343e Author: Wim Van Sebroeck Date: Thu Jan 11 22:27:51 2007 +0100 [WATCHDOG] advantechwdt.c - move set_heartbeat to a seperate function Put the set_heartbeat/timeout code into a seperate function Signed-off-by: Wim Van Sebroeck commit 1d747be647c2239e39a9b5faa138c1e36222b37e Author: Wim Van Sebroeck Date: Thu Jan 11 22:19:28 2007 +0100 [WATCHDOG] advantechwdt.c - cleanup before platform_device patches This cleanup consists of: - make sure that the printk's use the module/driver-name - do the exit of the module exactly the opposite of the init of the module Signed-off-by: Wim Van Sebroeck commit 98c08e98f8e5af1caf106e9ee3d46f3eb1ba4858 Author: Wim Van Sebroeck Date: Wed Jan 10 23:38:56 2007 +0100 [WATCHDOG] acquirewdt.c - convert to platform_device part 2 Convert the reboot_notifier into the platform_device's shutdown method Signed-off-by: Wim Van Sebroeck commit ad5fe323182fd3adab4225c93eae36f3c555a884 Author: Wim Van Sebroeck Date: Wed Jan 10 23:36:13 2007 +0100 [WATCHDOG] acquirewdt.c - convert to platform_device Convert the acquirewdt watchdog into a platform_device Signed-off-by: Wim Van Sebroeck commit 76c11f0442257099cbb474301f2ffff38649d3d3 Author: Wim Van Sebroeck Date: Wed Jan 10 23:23:44 2007 +0100 [WATCHDOG] acquirewdt.c - clean before platform_device patches Clean the current code before we convert the driver to a platform_device. This clean consists of: - document the includes - make sure that the printk's use the module/driver-name - do the exit of the module exactly the opposite of the init of the module Signed-off-by: Wim Van Sebroeck commit f3dc07330c3e43a8d365eaa74693e320e6ed79d9 Author: Wim Van Sebroeck Date: Tue Jan 9 22:43:49 2007 +0100 [WATCHDOG] pcwd_usb.c - get heartbeat from dip switches The PCWD cards normally use the heartbeat that is set via the dip-switches of the card. There are only 3 switches, thus 8 combinations that each have a certain heartbeat. The card can however be programmed with a heartbeat from 1 till 65535 seconds. This is what our driver does: it programs the heartbeat on the card. There are however a lot of people that don't know that we set the heartbeat of the watchdog card to the value provided by the heartbeat module parameter. Instead they think that the heartbeat value is the same as set by the dip-switches. This patch changes the driver so that at startup you can take the heartbeat from the dip-switches. You do this by setting the heartbeat module parameter to 0. This patch also makes this the default behaviour. Signed-off-by: Wim Van Sebroeck commit f9146f26da9a4336e02e35bf20222dcb2ee62c7f Author: Wim Van Sebroeck Date: Tue Jan 9 22:38:54 2007 +0100 [WATCHDOG] pcwd.c - e-mail adres update update Simon Machell's e-mail adres Signed-off-by: Wim Van Sebroeck commit 2ef473de1ee62eb31b6b98885562cdb4389b01dc Author: Wim Van Sebroeck Date: Mon Jan 8 22:45:30 2007 +0100 [WATCHDOG] pcwd_usb.c - get heartbeat from dip switches The PCWD cards normally use the heartbeat that is set via the dip-switches of the card. There are only 3 switches, thus 8 combinations that each have a certain heartbeat. The card can however be programmed with a heartbeat from 1 till 65535 seconds. This is what our driver does: it programs the heartbeat on the card. There are however a lot of people that don't know that we set the heartbeat of the watchdog card to the value provided by the heartbeat module parameter. Instead they think that the heartbeat value is the same as set by the dip-switches. This patch changes the driver so that at startup you can take the heartbeat from the dip-switches. You do this by setting the heartbeat module parameter to 0. This patch also makes this the default behaviour. Signed-off-by: Wim Van Sebroeck commit d26d90967de9d51c08d5821e362cb2245f83c1a8 Author: Wim Van Sebroeck Date: Mon Jan 8 22:40:33 2007 +0100 [WATCHDOG] pcwd_usb.c - document includes document and review the include files. Signed-off-by: Wim Van Sebroeck commit 045798b56f59d02beef84d5aa7137786c50912c2 Author: Wim Van Sebroeck Date: Sun Jan 7 21:57:03 2007 +0100 [WATCHDOG] pcwd_pci.c - spinlock fixes the keepalive and get_temperature functions should use spinlocks also. Signed-off-by: Wim Van Sebroeck commit 39e3a0556a1e2d33f9491d43bae9fdaa09b0308a Author: Wim Van Sebroeck Date: Sun Jan 7 21:49:11 2007 +0100 [WATCHDOG] pcwd_pci.c - get heartbeat from dip switches The PCWD cards normally use the heartbeat that is set via the dip-switches of the card. There are only 3 switches, thus 8 combinations that each have a certain heartbeat. The card can however be programmed with a heartbeat from 1 till 65535 seconds. This is what our driver does: it programs the heartbeat on the card. There are however a lot of people that don't know that we set the heartbeat of the watchdog card to the value provided by the heartbeat module parameter. Instead they think that the heartbeat value is the same as set by the dip-switches. This patch changes the driver so that at startup you can take the heartbeat from the dip-switches. You do this by setting the heartbeat module parameter to 0. This patch also makes this the default behaviour. Signed-off-by: Wim Van Sebroeck commit 9cd446198e7646431a7f2ce7dbeec8df9f77012b Author: Akinobu Mita Date: Tue Dec 19 17:51:44 2006 +0900 [WATCHDOG] fix clk_get() error check The return value of clk_get() should be checked by IS_ERR(). Signed-off-by: Akinobu Mita Signed-off-by: Ben Dooks Signed-off-by: Wim Van Sebroeck commit 0b6dd8a640fbaf73b74949b6dc2be50263532576 Author: Ben Dooks Date: Mon Dec 18 10:31:32 2006 +0000 [WATCHDOG] s3c2410_wdt exit driver via labels Cleanup the s3c2410_wdt driver's exit point by using labels instead of multiple returns. Also remove the checks for the resources having been allocate in the exit, as we will now either have fully allocated or not allocated the resources at-all. Signed-off-by: Ben Dooks Signed-off-by: Wim Van Sebroeck drivers/char/watchdog/acquirewdt.c | 155 +++++++++++++++++++--------------- drivers/char/watchdog/advantechwdt.c | 142 +++++++++++++++++++------------ drivers/char/watchdog/pcwd.c | 26 +++++- drivers/char/watchdog/pcwd_pci.c | 32 ++++++- drivers/char/watchdog/pcwd_usb.c | 61 ++++++++----- drivers/char/watchdog/pnx4008_wdt.c | 3 - drivers/char/watchdog/s3c2410_wdt.c | 60 ++++++++----- 7 files changed, 299 insertions(+), 180 deletions(-) diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c index 154d67e..85269c3 100644 --- a/drivers/char/watchdog/acquirewdt.c +++ b/drivers/char/watchdog/acquirewdt.c @@ -48,46 +48,52 @@ * It can be 1, 2, 10, 20, 110 or 220 seconds. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include +/* + * Includes, defines, variables, module parameters, ... + */ +/* Includes */ +#include /* For module specific items */ +#include /* For new moduleparam's */ +#include /* For standard types (like size_t) */ +#include /* For the -ENODEV/... values */ +#include /* For printk/panic/... */ +#include /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ +#include /* For the watchdog specific items */ +#include /* For file operations */ +#include /* For io-port access */ +#include /* For platform_driver framework */ +#include /* For __init/__exit/... */ + +#include /* For copy_to_user/put_user/... */ +#include /* For inb/outb/... */ + +/* Module information */ +#define DRV_NAME "acquirewdt" +#define PFX DRV_NAME ": " #define WATCHDOG_NAME "Acquire WDT" -#define PFX WATCHDOG_NAME ": " #define WATCHDOG_HEARTBEAT 0 /* There is no way to see what the correct time-out period is */ +/* internal variables */ +static struct platform_device *acq_platform_device; /* the watchdog platform device */ static unsigned long acq_is_open; static char expect_close; -/* - * You must set these - there is no sane way to probe for this board. - */ - -static int wdt_stop = 0x43; +/* module parameters */ +static int wdt_stop = 0x43; /* You must set this - there is no sane way to probe for this board. */ module_param(wdt_stop, int, 0); MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); -static int wdt_start = 0x443; +static int wdt_start = 0x443; /* You must set this - there is no sane way to probe for this board. */ module_param(wdt_start, int, 0); MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); /* - * Kernel methods. + * Watchdog Operations */ static void acq_keepalive(void) @@ -103,7 +109,7 @@ static void acq_stop(void) } /* - * /dev/watchdog handling. + * /dev/watchdog handling */ static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) @@ -143,7 +149,7 @@ static int acq_ioctl(struct inode *inode { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .firmware_version = 1, - .identity = "Acquire WDT", + .identity = WATCHDOG_NAME, }; switch(cmd) @@ -214,20 +220,6 @@ static int acq_close(struct inode *inode } /* - * Notifier for system down - */ - -static int acq_notify_sys(struct notifier_block *this, unsigned long code, - void *unused) -{ - if(code==SYS_DOWN || code==SYS_HALT) { - /* Turn the WDT off */ - acq_stop(); - } - return NOTIFY_DONE; -} - -/* * Kernel Interfaces */ @@ -240,29 +232,20 @@ static const struct file_operations acq_ .release = acq_close, }; -static struct miscdevice acq_miscdev= -{ - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &acq_fops, +static struct miscdevice acq_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &acq_fops, }; /* - * The WDT card needs to learn about soft shutdowns in order to - * turn the timebomb registers off. + * Init & exit routines */ -static struct notifier_block acq_notifier = -{ - .notifier_call = acq_notify_sys, -}; - -static int __init acq_init(void) +static int __devinit acq_probe(struct platform_device *dev) { int ret; - printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); - if (wdt_stop != wdt_start) { if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", @@ -279,18 +262,11 @@ static int __init acq_init(void) goto unreg_stop; } - ret = register_reboot_notifier(&acq_notifier); - if (ret != 0) { - printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", - ret); - goto unreg_regions; - } - ret = misc_register(&acq_miscdev); if (ret != 0) { printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); - goto unreg_reboot; + goto unreg_regions; } printk (KERN_INFO PFX "initialized. (nowayout=%d)\n", @@ -298,8 +274,6 @@ static int __init acq_init(void) return 0; -unreg_reboot: - unregister_reboot_notifier(&acq_notifier); unreg_regions: release_region(wdt_start, 1); unreg_stop: @@ -309,13 +283,60 @@ out: return ret; } -static void __exit acq_exit(void) +static int __devexit acq_remove(struct platform_device *dev) { misc_deregister(&acq_miscdev); - unregister_reboot_notifier(&acq_notifier); + release_region(wdt_start,1); if(wdt_stop != wdt_start) release_region(wdt_stop,1); - release_region(wdt_start,1); + + return 0; +} + +static void acq_shutdown(struct platform_device *dev) +{ + /* Turn the WDT off if we have a soft shutdown */ + acq_stop(); +} + +static struct platform_driver acquirewdt_driver = { + .probe = acq_probe, + .remove = __devexit_p(acq_remove), + .shutdown = acq_shutdown, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + }, +}; + +static int __init acq_init(void) +{ + int err; + + printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); + + err = platform_driver_register(&acquirewdt_driver); + if (err) + return err; + + acq_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); + if (IS_ERR(acq_platform_device)) { + err = PTR_ERR(acq_platform_device); + goto unreg_platform_driver; + } + + return 0; + +unreg_platform_driver: + platform_driver_unregister(&acquirewdt_driver); + return err; +} + +static void __exit acq_exit(void) +{ + platform_device_unregister(acq_platform_device); + platform_driver_unregister(&acquirewdt_driver); + printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); } module_init(acq_init); diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c index 9d73276..8121cc2 100644 --- a/drivers/char/watchdog/advantechwdt.c +++ b/drivers/char/watchdog/advantechwdt.c @@ -35,18 +35,19 @@ #include #include #include #include -#include -#include +#include #include #include #include #include +#define DRV_NAME "advantechwdt" +#define PFX DRV_NAME ": " #define WATCHDOG_NAME "Advantech WDT" -#define PFX WATCHDOG_NAME ": " #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ +static struct platform_device *advwdt_platform_device; /* the watchdog platform device */ static unsigned long advwdt_is_open; static char adv_expect_close; @@ -75,10 +76,10 @@ MODULE_PARM_DESC(timeout, "Watchdog time static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); /* - * Kernel methods. + * Watchdog Operations */ static void @@ -94,6 +95,20 @@ advwdt_disable(void) inb_p(wdt_stop); } +static int +advwdt_set_heartbeat(int t) +{ + if ((t < 1) || (t > 63)) + return -EINVAL; + + timeout = t; + return 0; +} + +/* + * /dev/watchdog handling + */ + static ssize_t advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -126,7 +141,7 @@ advwdt_ioctl(struct inode *inode, struct static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, - .identity = "Advantech WDT", + .identity = WATCHDOG_NAME, }; switch (cmd) { @@ -146,9 +161,8 @@ advwdt_ioctl(struct inode *inode, struct case WDIOC_SETTIMEOUT: if (get_user(new_timeout, p)) return -EFAULT; - if ((new_timeout < 1) || (new_timeout > 63)) + if (advwdt_set_heartbeat(new_timeout)) return -EINVAL; - timeout = new_timeout; advwdt_ping(); /* Fall */ @@ -209,21 +223,6 @@ advwdt_close(struct inode *inode, struct } /* - * Notifier for system down - */ - -static int -advwdt_notify_sys(struct notifier_block *this, unsigned long code, - void *unused) -{ - if (code == SYS_DOWN || code == SYS_HALT) { - /* Turn the WDT off */ - advwdt_disable(); - } - return NOTIFY_DONE; -} - -/* * Kernel Interfaces */ @@ -237,33 +236,20 @@ static const struct file_operations advw }; static struct miscdevice advwdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &advwdt_fops, + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &advwdt_fops, }; /* - * The WDT needs to learn about soft shutdowns in order to - * turn the timebomb registers off. + * Init & exit routines */ -static struct notifier_block advwdt_notifier = { - .notifier_call = advwdt_notify_sys, -}; - -static int __init -advwdt_init(void) +static int __devinit +advwdt_probe(struct platform_device *dev) { int ret; - printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n"); - - if (timeout < 1 || timeout > 63) { - timeout = WATCHDOG_TIMEOUT; - printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n", - timeout); - } - if (wdt_stop != wdt_start) { if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", @@ -280,18 +266,18 @@ advwdt_init(void) goto unreg_stop; } - ret = register_reboot_notifier(&advwdt_notifier); - if (ret != 0) { - printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", - ret); - goto unreg_regions; + /* Check that the heartbeat value is within it's range ; if not reset to the default */ + if (advwdt_set_heartbeat(timeout)) { + advwdt_set_heartbeat(WATCHDOG_TIMEOUT); + printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n", + timeout); } ret = misc_register(&advwdt_miscdev); if (ret != 0) { printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); - goto unreg_reboot; + goto unreg_regions; } printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", @@ -299,8 +285,6 @@ advwdt_init(void) out: return ret; -unreg_reboot: - unregister_reboot_notifier(&advwdt_notifier); unreg_regions: release_region(wdt_start, 1); unreg_stop: @@ -309,14 +293,64 @@ unreg_stop: goto out; } -static void __exit -advwdt_exit(void) +static int __devexit +advwdt_remove(struct platform_device *dev) { misc_deregister(&advwdt_miscdev); - unregister_reboot_notifier(&advwdt_notifier); + release_region(wdt_start,1); if(wdt_stop != wdt_start) release_region(wdt_stop,1); - release_region(wdt_start,1); + + return 0; +} + +static void +advwdt_shutdown(struct platform_device *dev) +{ + /* Turn the WDT off if we have a soft shutdown */ + advwdt_disable(); +} + +static struct platform_driver advwdt_driver = { + .probe = advwdt_probe, + .remove = __devexit_p(advwdt_remove), + .shutdown = advwdt_shutdown, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + }, +}; + +static int __init +advwdt_init(void) +{ + int err; + + printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n"); + + err = platform_driver_register(&advwdt_driver); + if (err) + return err; + + advwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); + if (IS_ERR(advwdt_platform_device)) { + err = PTR_ERR(advwdt_platform_device); + goto unreg_platform_driver; + } + + return 0; + +unreg_platform_driver: + platform_driver_unregister(&advwdt_driver); + return err; +} + +static void __exit +advwdt_exit(void) +{ + platform_device_unregister(advwdt_platform_device); + platform_driver_unregister(&advwdt_driver); + printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); } module_init(advwdt_init); diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c index 8e1e6e4..aab6621 100644 --- a/drivers/char/watchdog/pcwd.c +++ b/drivers/char/watchdog/pcwd.c @@ -2,7 +2,7 @@ * PC Watchdog Driver * by Ken Hollis (khollis@bitgate.com) * - * Permission granted from Simon Machell (73244.1270@compuserve.com) + * Permission granted from Simon Machell (smachell@berkprod.com) * Written for the Linux Kernel, and GPLed by Ken Hollis * * 960107 Added request_region routines, modulized the whole thing. @@ -70,8 +70,8 @@ #include /* For copy_to_ #include /* For inb/outb/... */ /* Module and version information */ -#define WATCHDOG_VERSION "1.17" -#define WATCHDOG_DATE "12 Feb 2006" +#define WATCHDOG_VERSION "1.18" +#define WATCHDOG_DATE "06 Jan 2007" #define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" #define WATCHDOG_NAME "pcwd" #define PFX WATCHDOG_NAME ": " @@ -132,6 +132,18 @@ #define CMD_ISA_DELAY_TIME_4SECS 0x0B #define CMD_ISA_DELAY_TIME_8SECS 0x0C #define CMD_ISA_RESET_RELAYS 0x0D +/* Watchdog's Dip Switch heartbeat values */ +static const int heartbeat_tbl [] = { + 20, /* OFF-OFF-OFF = 20 Sec */ + 40, /* OFF-OFF-ON = 40 Sec */ + 60, /* OFF-ON-OFF = 1 Min */ + 300, /* OFF-ON-ON = 5 Min */ + 600, /* ON-OFF-OFF = 10 Min */ + 1800, /* ON-OFF-ON = 30 Min */ + 3600, /* ON-ON-OFF = 1 Hour */ + 7200, /* ON-ON-ON = 2 hour */ +}; + /* * We are using an kernel timer to do the pinging of the watchdog * every ~500ms. We try to set the internal heartbeat of the @@ -167,10 +179,10 @@ static int debug = QUIET; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); -#define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ +#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */ static int heartbeat = WATCHDOG_HEARTBEAT; module_param(heartbeat, int, 0); -MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); +MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); @@ -844,6 +856,10 @@ static int __devinit pcwatchdog_init(int /* Show info about the card itself */ pcwd_show_card_info(); + /* If heartbeat = 0 then we use the heartbeat from the dip-switches */ + if (heartbeat == 0) + heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)]; + /* Check that the heartbeat value is within it's range ; if not reset to the default */ if (pcwd_set_heartbeat(heartbeat)) { pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c index f4872c8..95ddcd8 100644 --- a/drivers/char/watchdog/pcwd_pci.c +++ b/drivers/char/watchdog/pcwd_pci.c @@ -1,7 +1,7 @@ /* * Berkshire PCI-PC Watchdog Card Driver * - * (c) Copyright 2003-2005 Wim Van Sebroeck . + * (c) Copyright 2003-2007 Wim Van Sebroeck . * * Based on source code of the following authors: * Ken Hollis , @@ -51,8 +51,8 @@ #include /* For copy_to_ #include /* For inb/outb/... */ /* Module and version information */ -#define WATCHDOG_VERSION "1.02" -#define WATCHDOG_DATE "03 Sep 2005" +#define WATCHDOG_VERSION "1.03" +#define WATCHDOG_DATE "06 Jan 2007" #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog" #define WATCHDOG_NAME "pcwd_pci" #define PFX WATCHDOG_NAME ": " @@ -96,6 +96,18 @@ #define CMD_READ_WATCHDOG_TIMEOUT 0x18 #define CMD_WRITE_WATCHDOG_TIMEOUT 0x19 #define CMD_GET_CLEAR_RESET_COUNT 0x84 +/* Watchdog's Dip Switch heartbeat values */ +static const int heartbeat_tbl [] = { + 5, /* OFF-OFF-OFF = 5 Sec */ + 10, /* OFF-OFF-ON = 10 Sec */ + 30, /* OFF-ON-OFF = 30 Sec */ + 60, /* OFF-ON-ON = 1 Min */ + 300, /* ON-OFF-OFF = 5 Min */ + 600, /* ON-OFF-ON = 10 Min */ + 1800, /* ON-ON-OFF = 30 Min */ + 3600, /* ON-ON-ON = 1 hour */ +}; + /* We can only use 1 card due to the /dev/watchdog restriction */ static int cards_found; @@ -119,10 +131,10 @@ static int debug = QUIET; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); -#define WATCHDOG_HEARTBEAT 2 /* 2 sec default heartbeat */ +#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */ static int heartbeat = WATCHDOG_HEARTBEAT; module_param(heartbeat, int, 0); -MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0= DEBUG) printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n"); @@ -373,7 +387,9 @@ static int pcipcwd_get_temperature(int * if (!pcipcwd_private.supports_temp) return -ENODEV; + spin_lock(&pcipcwd_private.io_lock); *temperature = inb_p(pcipcwd_private.io_addr); + spin_unlock(&pcipcwd_private.io_lock); /* * Convert celsius to fahrenheit, since this was @@ -711,6 +727,10 @@ static int __devinit pcipcwd_card_init(s /* Show info about the card itself */ pcipcwd_show_card_info(); + /* If heartbeat = 0 then we use the heartbeat from the dip-switches */ + if (heartbeat == 0) + heartbeat = heartbeat_tbl[(pcipcwd_get_option_switches() & 0x07)]; + /* Check that the heartbeat value is within it's range ; if not reset to the default */ if (pcipcwd_set_heartbeat(heartbeat)) { pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT); @@ -798,6 +818,8 @@ static int __init pcipcwd_init_module(vo static void __exit pcipcwd_cleanup_module(void) { pci_unregister_driver(&pcipcwd_driver); + + printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); } module_init(pcipcwd_init_module); diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c index 2da5ac9..1ad1f22 100644 --- a/drivers/char/watchdog/pcwd_usb.c +++ b/drivers/char/watchdog/pcwd_usb.c @@ -1,7 +1,7 @@ /* * Berkshire USB-PC Watchdog Card Driver * - * (c) Copyright 2004 Wim Van Sebroeck . + * (c) Copyright 2004-2007 Wim Van Sebroeck . * * Based on source code of the following authors: * Ken Hollis , @@ -24,26 +24,25 @@ * http://www.berkprod.com/ or http://www.pcwatchdog.com/ */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include /* For module specific items */ +#include /* For new moduleparam's */ +#include /* For standard types (like size_t) */ +#include /* For the -ENODEV/... values */ +#include /* For printk/panic/... */ +#include /* For mdelay function */ +#include /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ +#include /* For the watchdog specific items */ +#include /* For notifier support */ +#include /* For reboot_notifier stuff */ +#include /* For __init/__exit/... */ +#include /* For file operations */ +#include /* For USB functions */ +#include /* For kmalloc, ... */ +#include /* For mutex locking */ #include /* For HID_REQ_SET_REPORT & HID_DT_REPORT */ +#include /* For copy_to_user/put_user/... */ + #ifdef CONFIG_USB_DEBUG static int debug = 1; @@ -57,8 +56,8 @@ #define dbg(format, arg...) do { if (deb /* Module and Version Information */ -#define DRIVER_VERSION "1.01" -#define DRIVER_DATE "15 Mar 2005" +#define DRIVER_VERSION "1.02" +#define DRIVER_DATE "06 Jan 2007" #define DRIVER_AUTHOR "Wim Van Sebroeck " #define DRIVER_DESC "Berkshire USB-PC Watchdog driver" #define DRIVER_LICENSE "GPL" @@ -75,10 +74,10 @@ MODULE_ALIAS_MISCDEV(TEMP_MINOR); module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug enabled or not"); -#define WATCHDOG_HEARTBEAT 2 /* 2 sec default heartbeat */ +#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */ static int heartbeat = WATCHDOG_HEARTBEAT; module_param(heartbeat, int, 0); -MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0start); wdt_clk = clk_get(&pdev->dev, "wdt_ck"); - if (!wdt_clk) { + if (IS_ERR(wdt_clk)) { + ret = PTR_ERR(wdt_clk); release_resource(wdt_mem); kfree(wdt_mem); goto out; diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c index 18cb050..5a5cc2a 100644 --- a/drivers/char/watchdog/s3c2410_wdt.c +++ b/drivers/char/watchdog/s3c2410_wdt.c @@ -366,13 +366,15 @@ static int s3c2410wdt_probe(struct platf wdt_mem = request_mem_region(res->start, size, pdev->name); if (wdt_mem == NULL) { printk(KERN_INFO PFX "failed to get memory region\n"); - return -ENOENT; + ret = -ENOENT; + goto err_req; } wdt_base = ioremap(res->start, size); if (wdt_base == 0) { printk(KERN_INFO PFX "failed to ioremap() region\n"); - return -EINVAL; + ret = -EINVAL; + goto err_req; } DBG("probe: mapped wdt_base=%p\n", wdt_base); @@ -380,22 +382,21 @@ static int s3c2410wdt_probe(struct platf res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { printk(KERN_INFO PFX "failed to get irq resource\n"); - iounmap(wdt_base); - return -ENOENT; + ret = -ENOENT; + goto err_map; } ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev); if (ret != 0) { printk(KERN_INFO PFX "failed to install irq (%d)\n", ret); - iounmap(wdt_base); - return ret; + goto err_map; } wdt_clock = clk_get(&pdev->dev, "watchdog"); - if (wdt_clock == NULL) { + if (IS_ERR(wdt_clock)) { printk(KERN_INFO PFX "failed to find watchdog clock source\n"); - iounmap(wdt_base); - return -ENOENT; + ret = PTR_ERR(wdt_clock); + goto err_irq; } clk_enable(wdt_clock); @@ -418,8 +419,7 @@ static int s3c2410wdt_probe(struct platf if (ret) { printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n", WATCHDOG_MINOR, ret); - iounmap(wdt_base); - return ret; + goto err_clk; } if (tmr_atboot && started == 0) { @@ -434,26 +434,36 @@ static int s3c2410wdt_probe(struct platf } return 0; + + err_clk: + clk_disable(wdt_clock); + clk_put(wdt_clock); + + err_irq: + free_irq(wdt_irq->start, pdev); + + err_map: + iounmap(wdt_base); + + err_req: + release_resource(wdt_mem); + kfree(wdt_mem); + + return ret; } static int s3c2410wdt_remove(struct platform_device *dev) { - if (wdt_mem != NULL) { - release_resource(wdt_mem); - kfree(wdt_mem); - wdt_mem = NULL; - } + release_resource(wdt_mem); + kfree(wdt_mem); + wdt_mem = NULL; - if (wdt_irq != NULL) { - free_irq(wdt_irq->start, dev); - wdt_irq = NULL; - } + free_irq(wdt_irq->start, dev); + wdt_irq = NULL; - if (wdt_clock != NULL) { - clk_disable(wdt_clock); - clk_put(wdt_clock); - wdt_clock = NULL; - } + clk_disable(wdt_clock); + clk_put(wdt_clock); + wdt_clock = NULL; iounmap(wdt_base); misc_deregister(&s3c2410wdt_miscdev);