Merge ../linux-2.6-watchdog-mm

This commit is contained in:
Wim Van Sebroeck 2007-02-09 21:35:36 +01:00
commit 9af9fc45dd
5 changed files with 123 additions and 59 deletions

View File

@ -2,7 +2,7 @@
* PC Watchdog Driver * PC Watchdog Driver
* by Ken Hollis (khollis@bitgate.com) * 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 * Written for the Linux Kernel, and GPLed by Ken Hollis
* *
* 960107 Added request_region routines, modulized the whole thing. * 960107 Added request_region routines, modulized the whole thing.
@ -70,8 +70,8 @@
#include <asm/io.h> /* For inb/outb/... */ #include <asm/io.h> /* For inb/outb/... */
/* Module and version information */ /* Module and version information */
#define WATCHDOG_VERSION "1.17" #define WATCHDOG_VERSION "1.18"
#define WATCHDOG_DATE "12 Feb 2006" #define WATCHDOG_DATE "06 Jan 2007"
#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" #define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog"
#define WATCHDOG_NAME "pcwd" #define WATCHDOG_NAME "pcwd"
#define PFX WATCHDOG_NAME ": " #define PFX WATCHDOG_NAME ": "
@ -132,6 +132,18 @@
#define CMD_ISA_DELAY_TIME_8SECS 0x0C #define CMD_ISA_DELAY_TIME_8SECS 0x0C
#define CMD_ISA_RESET_RELAYS 0x0D #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 * We are using an kernel timer to do the pinging of the watchdog
* every ~500ms. We try to set the internal heartbeat of the * 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_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=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; static int heartbeat = WATCHDOG_HEARTBEAT;
module_param(heartbeat, int, 0); 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; static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0); module_param(nowayout, int, 0);
@ -844,6 +856,10 @@ static int __devinit pcwatchdog_init(int base_addr)
/* Show info about the card itself */ /* Show info about the card itself */
pcwd_show_card_info(); 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 */ /* Check that the heartbeat value is within it's range ; if not reset to the default */
if (pcwd_set_heartbeat(heartbeat)) { if (pcwd_set_heartbeat(heartbeat)) {
pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); pcwd_set_heartbeat(WATCHDOG_HEARTBEAT);

View File

@ -1,7 +1,7 @@
/* /*
* Berkshire PCI-PC Watchdog Card Driver * Berkshire PCI-PC Watchdog Card Driver
* *
* (c) Copyright 2003-2005 Wim Van Sebroeck <wim@iguana.be>. * (c) Copyright 2003-2007 Wim Van Sebroeck <wim@iguana.be>.
* *
* Based on source code of the following authors: * Based on source code of the following authors:
* Ken Hollis <kenji@bitgate.com>, * Ken Hollis <kenji@bitgate.com>,
@ -51,8 +51,8 @@
#include <asm/io.h> /* For inb/outb/... */ #include <asm/io.h> /* For inb/outb/... */
/* Module and version information */ /* Module and version information */
#define WATCHDOG_VERSION "1.02" #define WATCHDOG_VERSION "1.03"
#define WATCHDOG_DATE "03 Sep 2005" #define WATCHDOG_DATE "06 Jan 2007"
#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog" #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
#define WATCHDOG_NAME "pcwd_pci" #define WATCHDOG_NAME "pcwd_pci"
#define PFX WATCHDOG_NAME ": " #define PFX WATCHDOG_NAME ": "
@ -96,6 +96,18 @@
#define CMD_WRITE_WATCHDOG_TIMEOUT 0x19 #define CMD_WRITE_WATCHDOG_TIMEOUT 0x19
#define CMD_GET_CLEAR_RESET_COUNT 0x84 #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 */ /* We can only use 1 card due to the /dev/watchdog restriction */
static int cards_found; static int cards_found;
@ -119,10 +131,10 @@ static int debug = QUIET;
module_param(debug, int, 0); module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=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; static int heartbeat = WATCHDOG_HEARTBEAT;
module_param(heartbeat, int, 0); module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
static int nowayout = WATCHDOG_NOWAYOUT; static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0); module_param(nowayout, int, 0);
@ -286,7 +298,9 @@ static int pcipcwd_stop(void)
static int pcipcwd_keepalive(void) static int pcipcwd_keepalive(void)
{ {
/* Re-trigger watchdog by writing to port 0 */ /* Re-trigger watchdog by writing to port 0 */
spin_lock(&pcipcwd_private.io_lock);
outb_p(0x42, pcipcwd_private.io_addr); /* send out any data */ outb_p(0x42, pcipcwd_private.io_addr); /* send out any data */
spin_unlock(&pcipcwd_private.io_lock);
if (debug >= DEBUG) if (debug >= DEBUG)
printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n"); printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n");
@ -373,7 +387,9 @@ static int pcipcwd_get_temperature(int *temperature)
if (!pcipcwd_private.supports_temp) if (!pcipcwd_private.supports_temp)
return -ENODEV; return -ENODEV;
spin_lock(&pcipcwd_private.io_lock);
*temperature = inb_p(pcipcwd_private.io_addr); *temperature = inb_p(pcipcwd_private.io_addr);
spin_unlock(&pcipcwd_private.io_lock);
/* /*
* Convert celsius to fahrenheit, since this was * Convert celsius to fahrenheit, since this was
@ -711,6 +727,10 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
/* Show info about the card itself */ /* Show info about the card itself */
pcipcwd_show_card_info(); 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 */ /* Check that the heartbeat value is within it's range ; if not reset to the default */
if (pcipcwd_set_heartbeat(heartbeat)) { if (pcipcwd_set_heartbeat(heartbeat)) {
pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT); pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
@ -798,6 +818,8 @@ static int __init pcipcwd_init_module(void)
static void __exit pcipcwd_cleanup_module(void) static void __exit pcipcwd_cleanup_module(void)
{ {
pci_unregister_driver(&pcipcwd_driver); pci_unregister_driver(&pcipcwd_driver);
printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
} }
module_init(pcipcwd_init_module); module_init(pcipcwd_init_module);

View File

@ -1,7 +1,7 @@
/* /*
* Berkshire USB-PC Watchdog Card Driver * Berkshire USB-PC Watchdog Card Driver
* *
* (c) Copyright 2004 Wim Van Sebroeck <wim@iguana.be>. * (c) Copyright 2004-2007 Wim Van Sebroeck <wim@iguana.be>.
* *
* Based on source code of the following authors: * Based on source code of the following authors:
* Ken Hollis <kenji@bitgate.com>, * Ken Hollis <kenji@bitgate.com>,
@ -24,26 +24,25 @@
* http://www.berkprod.com/ or http://www.pcwatchdog.com/ * http://www.berkprod.com/ or http://www.pcwatchdog.com/
*/ */
#include <linux/kernel.h> #include <linux/module.h> /* For module specific items */
#include <linux/errno.h> #include <linux/moduleparam.h> /* For new moduleparam's */
#include <linux/init.h> #include <linux/types.h> /* For standard types (like size_t) */
#include <linux/slab.h> #include <linux/errno.h> /* For the -ENODEV/... values */
#include <linux/module.h> #include <linux/kernel.h> /* For printk/panic/... */
#include <linux/moduleparam.h> #include <linux/delay.h> /* For mdelay function */
#include <linux/types.h> #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
#include <linux/delay.h> #include <linux/watchdog.h> /* For the watchdog specific items */
#include <linux/miscdevice.h> #include <linux/notifier.h> /* For notifier support */
#include <linux/watchdog.h> #include <linux/reboot.h> /* For reboot_notifier stuff */
#include <linux/notifier.h> #include <linux/init.h> /* For __init/__exit/... */
#include <linux/reboot.h> #include <linux/fs.h> /* For file operations */
#include <linux/fs.h> #include <linux/usb.h> /* For USB functions */
#include <linux/smp_lock.h> #include <linux/slab.h> /* For kmalloc, ... */
#include <linux/completion.h> #include <linux/mutex.h> /* For mutex locking */
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/mutex.h>
#include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */ #include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */
#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
#ifdef CONFIG_USB_DEBUG #ifdef CONFIG_USB_DEBUG
static int debug = 1; static int debug = 1;
@ -57,8 +56,8 @@
/* Module and Version Information */ /* Module and Version Information */
#define DRIVER_VERSION "1.01" #define DRIVER_VERSION "1.02"
#define DRIVER_DATE "15 Mar 2005" #define DRIVER_DATE "06 Jan 2007"
#define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>" #define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>"
#define DRIVER_DESC "Berkshire USB-PC Watchdog driver" #define DRIVER_DESC "Berkshire USB-PC Watchdog driver"
#define DRIVER_LICENSE "GPL" #define DRIVER_LICENSE "GPL"
@ -75,10 +74,10 @@ MODULE_ALIAS_MISCDEV(TEMP_MINOR);
module_param(debug, int, 0); module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug enabled or not"); 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; static int heartbeat = WATCHDOG_HEARTBEAT;
module_param(heartbeat, int, 0); module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
static int nowayout = WATCHDOG_NOWAYOUT; static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0); module_param(nowayout, int, 0);
@ -110,6 +109,18 @@ MODULE_DEVICE_TABLE (usb, usb_pcwd_table);
#define CMD_ENABLE_WATCHDOG 0x30 /* Enable / Disable Watchdog */ #define CMD_ENABLE_WATCHDOG 0x30 /* Enable / Disable Watchdog */
#define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG #define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG
/* 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 */ /* We can only use 1 card due to the /dev/watchdog restriction */
static int cards_found; static int cards_found;
@ -682,6 +693,10 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
((option_switches & 0x10) ? "ON" : "OFF"), ((option_switches & 0x10) ? "ON" : "OFF"),
((option_switches & 0x08) ? "ON" : "OFF")); ((option_switches & 0x08) ? "ON" : "OFF"));
/* If heartbeat = 0 then we use the heartbeat from the dip-switches */
if (heartbeat == 0)
heartbeat = heartbeat_tbl[(option_switches & 0x07)];
/* Check that the heartbeat value is within it's range ; if not reset to the default */ /* Check that the heartbeat value is within it's range ; if not reset to the default */
if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) { if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) {
usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT); usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT);

View File

@ -283,7 +283,8 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
wdt_base = (void __iomem *)IO_ADDRESS(res->start); wdt_base = (void __iomem *)IO_ADDRESS(res->start);
wdt_clk = clk_get(&pdev->dev, "wdt_ck"); 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); release_resource(wdt_mem);
kfree(wdt_mem); kfree(wdt_mem);
goto out; goto out;

View File

@ -366,13 +366,15 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
wdt_mem = request_mem_region(res->start, size, pdev->name); wdt_mem = request_mem_region(res->start, size, pdev->name);
if (wdt_mem == NULL) { if (wdt_mem == NULL) {
printk(KERN_INFO PFX "failed to get memory region\n"); printk(KERN_INFO PFX "failed to get memory region\n");
return -ENOENT; ret = -ENOENT;
goto err_req;
} }
wdt_base = ioremap(res->start, size); wdt_base = ioremap(res->start, size);
if (wdt_base == 0) { if (wdt_base == 0) {
printk(KERN_INFO PFX "failed to ioremap() region\n"); 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); DBG("probe: mapped wdt_base=%p\n", wdt_base);
@ -380,22 +382,21 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (res == NULL) { if (res == NULL) {
printk(KERN_INFO PFX "failed to get irq resource\n"); printk(KERN_INFO PFX "failed to get irq resource\n");
iounmap(wdt_base); ret = -ENOENT;
return -ENOENT; goto err_map;
} }
ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev); ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev);
if (ret != 0) { if (ret != 0) {
printk(KERN_INFO PFX "failed to install irq (%d)\n", ret); printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
iounmap(wdt_base); goto err_map;
return ret;
} }
wdt_clock = clk_get(&pdev->dev, "watchdog"); 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"); printk(KERN_INFO PFX "failed to find watchdog clock source\n");
iounmap(wdt_base); ret = PTR_ERR(wdt_clock);
return -ENOENT; goto err_irq;
} }
clk_enable(wdt_clock); clk_enable(wdt_clock);
@ -418,8 +419,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
if (ret) { if (ret) {
printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n", printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n",
WATCHDOG_MINOR, ret); WATCHDOG_MINOR, ret);
iounmap(wdt_base); goto err_clk;
return ret;
} }
if (tmr_atboot && started == 0) { if (tmr_atboot && started == 0) {
@ -434,26 +434,36 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
} }
return 0; 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) static int s3c2410wdt_remove(struct platform_device *dev)
{ {
if (wdt_mem != NULL) { release_resource(wdt_mem);
release_resource(wdt_mem); kfree(wdt_mem);
kfree(wdt_mem); wdt_mem = NULL;
wdt_mem = NULL;
}
if (wdt_irq != NULL) { free_irq(wdt_irq->start, dev);
free_irq(wdt_irq->start, dev); wdt_irq = NULL;
wdt_irq = NULL;
}
if (wdt_clock != NULL) { clk_disable(wdt_clock);
clk_disable(wdt_clock); clk_put(wdt_clock);
clk_put(wdt_clock); wdt_clock = NULL;
wdt_clock = NULL;
}
iounmap(wdt_base); iounmap(wdt_base);
misc_deregister(&s3c2410wdt_miscdev); misc_deregister(&s3c2410wdt_miscdev);