Commit 9af9fc45 authored by Wim Van Sebroeck's avatar Wim Van Sebroeck

Merge ../linux-2.6-watchdog-mm

parents 62d0cfcb f3dc0733
......@@ -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 <asm/io.h> /* 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_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 base_addr)
/* 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);
......
/*
* 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:
* Ken Hollis <kenji@bitgate.com>,
......@@ -51,8 +51,8 @@
#include <asm/io.h> /* 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_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<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;
module_param(nowayout, int, 0);
......@@ -286,7 +298,9 @@ static int pcipcwd_stop(void)
static int pcipcwd_keepalive(void)
{
/* 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 */
spin_unlock(&pcipcwd_private.io_lock);
if (debug >= DEBUG)
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)
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(struct pci_dev *pdev,
/* 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(void)
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);
......
/*
* 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:
* Ken Hollis <kenji@bitgate.com>,
......@@ -24,26 +24,25 @@
* http://www.berkprod.com/ or http://www.pcwatchdog.com/
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/mutex.h>
#include <linux/module.h> /* For module specific items */
#include <linux/moduleparam.h> /* For new moduleparam's */
#include <linux/types.h> /* For standard types (like size_t) */
#include <linux/errno.h> /* For the -ENODEV/... values */
#include <linux/kernel.h> /* For printk/panic/... */
#include <linux/delay.h> /* For mdelay function */
#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
#include <linux/watchdog.h> /* For the watchdog specific items */
#include <linux/notifier.h> /* For notifier support */
#include <linux/reboot.h> /* For reboot_notifier stuff */
#include <linux/init.h> /* For __init/__exit/... */
#include <linux/fs.h> /* For file operations */
#include <linux/usb.h> /* For USB functions */
#include <linux/slab.h> /* For kmalloc, ... */
#include <linux/mutex.h> /* For mutex locking */
#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
static int debug = 1;
......@@ -57,8 +56,8 @@
/* 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 <wim@iguana.be>"
#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. (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;
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_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 */
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 & 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 */
if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) {
usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT);
......
......@@ -283,7 +283,8 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
wdt_base = (void __iomem *)IO_ADDRESS(res->start);
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;
......
......@@ -366,13 +366,15 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
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 platform_device *pdev)
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 platform_device *pdev)
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 platform_device *pdev)
}
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment