Merge git://www.linux-watchdog.org/linux-watchdog
Pull first set of watchdog updates from Wim Van Sebroeck: "This pull contains: - The removal of ixp2000_wdt - The addition of ie6xx_wdt - Some documentation fixes - Small fixes and improvements (Note: Part 2 will contain generic watchdog core changes + conversion of some more drivers)" * git://www.linux-watchdog.org/linux-watchdog: Documentation/watchdog: Fix the file descriptor leak when no cmdline arg given Documentation/watchdog: close the fd when cmdline arg given Documentation/watchdog: Fix a small typo watchdog: s3c2410_wdt: Set timeout to actually achieved timeout watchdog: wm831x: Convert to gpio_request_one() watchdog: via_wdt: depends on PCI watchdog: ie6xx_wdt needs io.h watchdog: ie6xx_wdt.c: fix printk format warning watchdog: Add watchdog driver for Intel Atom E6XX watchdog: it87_wdt: Add support for IT8728F watchdog. watchdog: i6300esb: don't depend on X86 watchdog: Use module_pci_driver watchdog: sch311x_wdt.c: Remove RESGEN watchdog: s3c2410-wdt: Use of_match_ptr(). watchdog: Device tree support for pnx4008-wdt watchdog: ar7_wdt.c: use devm_request_and_ioremap watchdog: remove ixp2000 driver watchdog: sp5100_tco.c: quiet sparse noise about using plain integer was NULL pointer
This commit is contained in:
commit
0b87da68a0
|
@ -0,0 +1,13 @@
|
|||
* NXP PNX watchdog timer
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "nxp,pnx4008-wdt"
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
|
||||
Example:
|
||||
|
||||
watchdog@4003C000 {
|
||||
compatible = "nxp,pnx4008-wdt";
|
||||
reg = <0x4003C000 0x1000>;
|
||||
};
|
|
@ -7,6 +7,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/watchdog.h>
|
||||
|
@ -29,6 +30,14 @@ static void keep_alive(void)
|
|||
* The main program. Run the program with "-d" to disable the card,
|
||||
* or "-e" to enable the card.
|
||||
*/
|
||||
|
||||
void term(int sig)
|
||||
{
|
||||
close(fd);
|
||||
fprintf(stderr, "Stopping watchdog ticks...\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int flags;
|
||||
|
@ -47,26 +56,31 @@ int main(int argc, char *argv[])
|
|||
ioctl(fd, WDIOC_SETOPTIONS, &flags);
|
||||
fprintf(stderr, "Watchdog card disabled.\n");
|
||||
fflush(stderr);
|
||||
exit(0);
|
||||
goto end;
|
||||
} else if (!strncasecmp(argv[1], "-e", 2)) {
|
||||
flags = WDIOS_ENABLECARD;
|
||||
ioctl(fd, WDIOC_SETOPTIONS, &flags);
|
||||
fprintf(stderr, "Watchdog card enabled.\n");
|
||||
fflush(stderr);
|
||||
exit(0);
|
||||
goto end;
|
||||
} else {
|
||||
fprintf(stderr, "-d to disable, -e to enable.\n");
|
||||
fprintf(stderr, "run by itself to tick the card.\n");
|
||||
fflush(stderr);
|
||||
exit(0);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Watchdog Ticking Away!\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
signal(SIGINT, term);
|
||||
|
||||
while(1) {
|
||||
keep_alive();
|
||||
sleep(1);
|
||||
}
|
||||
end:
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ It contains following fields:
|
|||
* bootstatus: status of the device after booting (reported with watchdog
|
||||
WDIOF_* status bits).
|
||||
* driver_data: a pointer to the drivers private data of a watchdog device.
|
||||
This data should only be accessed via the watchdog_set_drvadata and
|
||||
This data should only be accessed via the watchdog_set_drvdata and
|
||||
watchdog_get_drvdata routines.
|
||||
* status: this field contains a number of status bits that give extra
|
||||
information about the status of the device (Like: is the watchdog timer
|
||||
|
|
|
@ -129,17 +129,6 @@ config 977_WATCHDOG
|
|||
|
||||
Not sure? It's safe to say N.
|
||||
|
||||
config IXP2000_WATCHDOG
|
||||
tristate "IXP2000 Watchdog"
|
||||
depends on ARCH_IXP2000
|
||||
help
|
||||
Say Y here if to include support for the watchdog timer
|
||||
in the Intel IXP2000(2400, 2800, 2850) network processors.
|
||||
This driver can be built as a module by choosing M. The module
|
||||
will be called ixp2000_wdt.
|
||||
|
||||
Say N if you are unsure.
|
||||
|
||||
config IXP4XX_WATCHDOG
|
||||
tristate "IXP4xx Watchdog"
|
||||
depends on ARCH_IXP4XX
|
||||
|
@ -543,7 +532,7 @@ config WAFER_WDT
|
|||
|
||||
config I6300ESB_WDT
|
||||
tristate "Intel 6300ESB Timer/Watchdog"
|
||||
depends on X86 && PCI
|
||||
depends on PCI
|
||||
---help---
|
||||
Hardware driver for the watchdog timer built into the Intel
|
||||
6300ESB controller hub.
|
||||
|
@ -551,6 +540,19 @@ config I6300ESB_WDT
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called i6300esb.
|
||||
|
||||
config IE6XX_WDT
|
||||
tristate "Intel Atom E6xx Watchdog"
|
||||
depends on X86 && PCI
|
||||
select WATCHDOG_CORE
|
||||
select MFD_CORE
|
||||
select LPC_SCH
|
||||
---help---
|
||||
Hardware driver for the watchdog timer built into the Intel
|
||||
Atom E6XX (TunnelCreek) processor.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ie6xx_wdt.
|
||||
|
||||
config INTEL_SCU_WATCHDOG
|
||||
bool "Intel SCU Watchdog for Mobile Platforms"
|
||||
depends on X86_MRST
|
||||
|
@ -607,7 +609,12 @@ config IT87_WDT
|
|||
depends on X86 && EXPERIMENTAL
|
||||
---help---
|
||||
This is the driver for the hardware watchdog on the ITE IT8702,
|
||||
IT8712, IT8716, IT8718, IT8720, IT8721, IT8726 Super I/O chips.
|
||||
IT8712, IT8716, IT8718, IT8720, IT8721, IT8726 and IT8728
|
||||
Super I/O chips.
|
||||
|
||||
If the driver does not work, then make sure that the game port in
|
||||
the BIOS is enabled.
|
||||
|
||||
This watchdog simply watches your kernel to make sure it doesn't
|
||||
freeze, and if it does, it reboots your computer after a certain
|
||||
amount of time.
|
||||
|
@ -780,7 +787,7 @@ config SMSC37B787_WDT
|
|||
|
||||
config VIA_WDT
|
||||
tristate "VIA Watchdog Timer"
|
||||
depends on X86
|
||||
depends on X86 && PCI
|
||||
select WATCHDOG_CORE
|
||||
---help---
|
||||
This is the driver for the hardware watchdog timer on VIA
|
||||
|
|
|
@ -36,7 +36,6 @@ obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
|
|||
obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o
|
||||
obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
|
||||
obj-$(CONFIG_977_WATCHDOG) += wdt977.o
|
||||
obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
|
||||
obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
|
||||
obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
|
||||
obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
|
||||
|
@ -81,6 +80,7 @@ obj-$(CONFIG_IB700_WDT) += ib700wdt.o
|
|||
obj-$(CONFIG_IBMASR) += ibmasr.o
|
||||
obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
|
||||
obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
|
||||
obj-$(CONFIG_IE6XX_WDT) += ie6xx_wdt.o
|
||||
obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o
|
||||
ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y)
|
||||
obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o
|
||||
|
|
|
@ -282,29 +282,19 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev)
|
|||
platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
|
||||
if (!ar7_regs_wdt) {
|
||||
pr_err("could not get registers resource\n");
|
||||
rc = -ENODEV;
|
||||
goto out;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!request_mem_region(ar7_regs_wdt->start,
|
||||
resource_size(ar7_regs_wdt), LONGNAME)) {
|
||||
pr_warn("watchdog I/O region busy\n");
|
||||
rc = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ar7_wdt = ioremap(ar7_regs_wdt->start, resource_size(ar7_regs_wdt));
|
||||
ar7_wdt = devm_request_and_ioremap(&pdev->dev, ar7_regs_wdt);
|
||||
if (!ar7_wdt) {
|
||||
pr_err("could not ioremap registers\n");
|
||||
rc = -ENXIO;
|
||||
goto out_mem_region;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
vbus_clk = clk_get(NULL, "vbus");
|
||||
if (IS_ERR(vbus_clk)) {
|
||||
pr_err("could not get vbus clock\n");
|
||||
rc = PTR_ERR(vbus_clk);
|
||||
goto out_mem_region;
|
||||
return PTR_ERR(vbus_clk);
|
||||
}
|
||||
|
||||
ar7_wdt_disable_wdt();
|
||||
|
@ -314,24 +304,21 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev)
|
|||
rc = misc_register(&ar7_wdt_miscdev);
|
||||
if (rc) {
|
||||
pr_err("unable to register misc device\n");
|
||||
goto out_alloc;
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
out_alloc:
|
||||
iounmap(ar7_wdt);
|
||||
out_mem_region:
|
||||
release_mem_region(ar7_regs_wdt->start, resource_size(ar7_regs_wdt));
|
||||
out:
|
||||
clk_put(vbus_clk);
|
||||
vbus_clk = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __devexit ar7_wdt_remove(struct platform_device *pdev)
|
||||
{
|
||||
misc_deregister(&ar7_wdt_miscdev);
|
||||
iounmap(ar7_wdt);
|
||||
release_mem_region(ar7_regs_wdt->start, resource_size(ar7_regs_wdt));
|
||||
|
||||
clk_put(vbus_clk);
|
||||
vbus_clk = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -861,16 +861,6 @@ static struct pci_driver hpwdt_driver = {
|
|||
.remove = __devexit_p(hpwdt_exit),
|
||||
};
|
||||
|
||||
static void __exit hpwdt_cleanup(void)
|
||||
{
|
||||
pci_unregister_driver(&hpwdt_driver);
|
||||
}
|
||||
|
||||
static int __init hpwdt_init(void)
|
||||
{
|
||||
return pci_register_driver(&hpwdt_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Tom Mingarelli");
|
||||
MODULE_DESCRIPTION("hp watchdog driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -889,5 +879,4 @@ module_param(allow_kdump, int, 0);
|
|||
MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs");
|
||||
#endif /* !CONFIG_HPWDT_NMI_DECODING */
|
||||
|
||||
module_init(hpwdt_init);
|
||||
module_exit(hpwdt_cleanup);
|
||||
module_pci_driver(hpwdt_driver);
|
||||
|
|
|
@ -492,19 +492,7 @@ static struct pci_driver esb_driver = {
|
|||
.shutdown = esb_shutdown,
|
||||
};
|
||||
|
||||
static int __init watchdog_init(void)
|
||||
{
|
||||
return pci_register_driver(&esb_driver);
|
||||
}
|
||||
|
||||
static void __exit watchdog_cleanup(void)
|
||||
{
|
||||
pci_unregister_driver(&esb_driver);
|
||||
pr_info("Watchdog Module Unloaded\n");
|
||||
}
|
||||
|
||||
module_init(watchdog_init);
|
||||
module_exit(watchdog_cleanup);
|
||||
module_pci_driver(esb_driver);
|
||||
|
||||
MODULE_AUTHOR("Ross Biro and David Härdeman");
|
||||
MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
|
||||
|
|
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
* Intel Atom E6xx Watchdog driver
|
||||
*
|
||||
* Copyright (C) 2011 Alexander Stein
|
||||
* <alexander.stein@systec-electronic.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General
|
||||
* Public License as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* The full GNU General Public License is included in this
|
||||
* distribution in the file called COPYING.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/watchdog.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#define DRIVER_NAME "ie6xx_wdt"
|
||||
|
||||
#define PV1 0x00
|
||||
#define PV2 0x04
|
||||
|
||||
#define RR0 0x0c
|
||||
#define RR1 0x0d
|
||||
#define WDT_RELOAD 0x01
|
||||
#define WDT_TOUT 0x02
|
||||
|
||||
#define WDTCR 0x10
|
||||
#define WDT_PRE_SEL 0x04
|
||||
#define WDT_RESET_SEL 0x08
|
||||
#define WDT_RESET_EN 0x10
|
||||
#define WDT_TOUT_EN 0x20
|
||||
|
||||
#define DCR 0x14
|
||||
|
||||
#define WDTLR 0x18
|
||||
#define WDT_LOCK 0x01
|
||||
#define WDT_ENABLE 0x02
|
||||
#define WDT_TOUT_CNF 0x03
|
||||
|
||||
#define MIN_TIME 1
|
||||
#define MAX_TIME (10 * 60) /* 10 minutes */
|
||||
#define DEFAULT_TIME 60
|
||||
|
||||
static unsigned int timeout = DEFAULT_TIME;
|
||||
module_param(timeout, uint, 0);
|
||||
MODULE_PARM_DESC(timeout,
|
||||
"Default Watchdog timer setting ("
|
||||
__MODULE_STRING(DEFAULT_TIME) "s)."
|
||||
"The range is from 1 to 600");
|
||||
|
||||
static bool nowayout = WATCHDOG_NOWAYOUT;
|
||||
module_param(nowayout, bool, 0);
|
||||
MODULE_PARM_DESC(nowayout,
|
||||
"Watchdog cannot be stopped once started (default="
|
||||
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
||||
|
||||
static u8 resetmode = 0x10;
|
||||
module_param(resetmode, byte, 0);
|
||||
MODULE_PARM_DESC(resetmode,
|
||||
"Resetmode bits: 0x08 warm reset (cold reset otherwise), "
|
||||
"0x10 reset enable, 0x20 disable toggle GPIO[4] (default=0x10)");
|
||||
|
||||
static struct {
|
||||
unsigned short sch_wdtba;
|
||||
struct spinlock unlock_sequence;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs;
|
||||
#endif
|
||||
} ie6xx_wdt_data;
|
||||
|
||||
/*
|
||||
* This is needed to write to preload and reload registers
|
||||
* struct ie6xx_wdt_data.unlock_sequence must be used
|
||||
* to prevent sequence interrupts
|
||||
*/
|
||||
static void ie6xx_wdt_unlock_registers(void)
|
||||
{
|
||||
outb(0x80, ie6xx_wdt_data.sch_wdtba + RR0);
|
||||
outb(0x86, ie6xx_wdt_data.sch_wdtba + RR0);
|
||||
}
|
||||
|
||||
static int ie6xx_wdt_ping(struct watchdog_device *wdd)
|
||||
{
|
||||
spin_lock(&ie6xx_wdt_data.unlock_sequence);
|
||||
ie6xx_wdt_unlock_registers();
|
||||
outb(WDT_RELOAD, ie6xx_wdt_data.sch_wdtba + RR1);
|
||||
spin_unlock(&ie6xx_wdt_data.unlock_sequence);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ie6xx_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
|
||||
{
|
||||
u32 preload;
|
||||
u64 clock;
|
||||
u8 wdtcr;
|
||||
|
||||
/* Watchdog clock is PCI Clock (33MHz) */
|
||||
clock = 33000000;
|
||||
/* and the preload value is loaded into [34:15] of the down counter */
|
||||
preload = (t * clock) >> 15;
|
||||
/*
|
||||
* Manual states preload must be one less.
|
||||
* Does not wrap as t is at least 1
|
||||
*/
|
||||
preload -= 1;
|
||||
|
||||
spin_lock(&ie6xx_wdt_data.unlock_sequence);
|
||||
|
||||
/* Set ResetMode & Enable prescaler for range 10ms to 10 min */
|
||||
wdtcr = resetmode & 0x38;
|
||||
outb(wdtcr, ie6xx_wdt_data.sch_wdtba + WDTCR);
|
||||
|
||||
ie6xx_wdt_unlock_registers();
|
||||
outl(0, ie6xx_wdt_data.sch_wdtba + PV1);
|
||||
|
||||
ie6xx_wdt_unlock_registers();
|
||||
outl(preload, ie6xx_wdt_data.sch_wdtba + PV2);
|
||||
|
||||
ie6xx_wdt_unlock_registers();
|
||||
outb(WDT_RELOAD | WDT_TOUT, ie6xx_wdt_data.sch_wdtba + RR1);
|
||||
|
||||
spin_unlock(&ie6xx_wdt_data.unlock_sequence);
|
||||
|
||||
wdd->timeout = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ie6xx_wdt_start(struct watchdog_device *wdd)
|
||||
{
|
||||
ie6xx_wdt_set_timeout(wdd, wdd->timeout);
|
||||
|
||||
/* Enable the watchdog timer */
|
||||
spin_lock(&ie6xx_wdt_data.unlock_sequence);
|
||||
outb(WDT_ENABLE, ie6xx_wdt_data.sch_wdtba + WDTLR);
|
||||
spin_unlock(&ie6xx_wdt_data.unlock_sequence);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ie6xx_wdt_stop(struct watchdog_device *wdd)
|
||||
{
|
||||
if (inb(ie6xx_wdt_data.sch_wdtba + WDTLR) & WDT_LOCK)
|
||||
return -1;
|
||||
|
||||
/* Disable the watchdog timer */
|
||||
spin_lock(&ie6xx_wdt_data.unlock_sequence);
|
||||
outb(0, ie6xx_wdt_data.sch_wdtba + WDTLR);
|
||||
spin_unlock(&ie6xx_wdt_data.unlock_sequence);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct watchdog_info ie6xx_wdt_info = {
|
||||
.identity = "Intel Atom E6xx Watchdog",
|
||||
.options = WDIOF_SETTIMEOUT |
|
||||
WDIOF_MAGICCLOSE |
|
||||
WDIOF_KEEPALIVEPING,
|
||||
};
|
||||
|
||||
static const struct watchdog_ops ie6xx_wdt_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.start = ie6xx_wdt_start,
|
||||
.stop = ie6xx_wdt_stop,
|
||||
.ping = ie6xx_wdt_ping,
|
||||
.set_timeout = ie6xx_wdt_set_timeout,
|
||||
};
|
||||
|
||||
static struct watchdog_device ie6xx_wdt_dev = {
|
||||
.info = &ie6xx_wdt_info,
|
||||
.ops = &ie6xx_wdt_ops,
|
||||
.min_timeout = MIN_TIME,
|
||||
.max_timeout = MAX_TIME,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
static int ie6xx_wdt_dbg_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
seq_printf(s, "PV1 = 0x%08x\n",
|
||||
inl(ie6xx_wdt_data.sch_wdtba + PV1));
|
||||
seq_printf(s, "PV2 = 0x%08x\n",
|
||||
inl(ie6xx_wdt_data.sch_wdtba + PV2));
|
||||
seq_printf(s, "RR = 0x%08x\n",
|
||||
inw(ie6xx_wdt_data.sch_wdtba + RR0));
|
||||
seq_printf(s, "WDTCR = 0x%08x\n",
|
||||
inw(ie6xx_wdt_data.sch_wdtba + WDTCR));
|
||||
seq_printf(s, "DCR = 0x%08x\n",
|
||||
inl(ie6xx_wdt_data.sch_wdtba + DCR));
|
||||
seq_printf(s, "WDTLR = 0x%08x\n",
|
||||
inw(ie6xx_wdt_data.sch_wdtba + WDTLR));
|
||||
|
||||
seq_printf(s, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ie6xx_wdt_dbg_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, ie6xx_wdt_dbg_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations ie6xx_wdt_dbg_operations = {
|
||||
.open = ie6xx_wdt_dbg_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static void __devinit ie6xx_wdt_debugfs_init(void)
|
||||
{
|
||||
/* /sys/kernel/debug/ie6xx_wdt */
|
||||
ie6xx_wdt_data.debugfs = debugfs_create_file("ie6xx_wdt",
|
||||
S_IFREG | S_IRUGO, NULL, NULL, &ie6xx_wdt_dbg_operations);
|
||||
}
|
||||
|
||||
static void __devexit ie6xx_wdt_debugfs_exit(void)
|
||||
{
|
||||
debugfs_remove(ie6xx_wdt_data.debugfs);
|
||||
}
|
||||
|
||||
#else
|
||||
static void __devinit ie6xx_wdt_debugfs_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void __devexit ie6xx_wdt_debugfs_exit(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __devinit ie6xx_wdt_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
u8 wdtlr;
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
if (!request_region(res->start, resource_size(res), pdev->name)) {
|
||||
dev_err(&pdev->dev, "Watchdog region 0x%llx already in use!\n",
|
||||
(u64)res->start);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ie6xx_wdt_data.sch_wdtba = res->start;
|
||||
dev_dbg(&pdev->dev, "WDT = 0x%X\n", ie6xx_wdt_data.sch_wdtba);
|
||||
|
||||
ie6xx_wdt_dev.timeout = timeout;
|
||||
watchdog_set_nowayout(&ie6xx_wdt_dev, nowayout);
|
||||
|
||||
spin_lock_init(&ie6xx_wdt_data.unlock_sequence);
|
||||
|
||||
wdtlr = inb(ie6xx_wdt_data.sch_wdtba + WDTLR);
|
||||
if (wdtlr & WDT_LOCK)
|
||||
dev_warn(&pdev->dev,
|
||||
"Watchdog Timer is Locked (Reg=0x%x)\n", wdtlr);
|
||||
|
||||
ie6xx_wdt_debugfs_init();
|
||||
|
||||
ret = watchdog_register_device(&ie6xx_wdt_dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Watchdog timer: cannot register device (err =%d)\n",
|
||||
ret);
|
||||
goto misc_register_error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
misc_register_error:
|
||||
ie6xx_wdt_debugfs_exit();
|
||||
release_region(res->start, resource_size(res));
|
||||
ie6xx_wdt_data.sch_wdtba = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit ie6xx_wdt_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
ie6xx_wdt_stop(NULL);
|
||||
watchdog_unregister_device(&ie6xx_wdt_dev);
|
||||
ie6xx_wdt_debugfs_exit();
|
||||
release_region(res->start, resource_size(res));
|
||||
ie6xx_wdt_data.sch_wdtba = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ie6xx_wdt_driver = {
|
||||
.probe = ie6xx_wdt_probe,
|
||||
.remove = __devexit_p(ie6xx_wdt_remove),
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ie6xx_wdt_init(void)
|
||||
{
|
||||
/* Check boot parameters to verify that their initial values */
|
||||
/* are in range. */
|
||||
if ((timeout < MIN_TIME) ||
|
||||
(timeout > MAX_TIME)) {
|
||||
pr_err("Watchdog timer: value of timeout %d (dec) "
|
||||
"is out of range from %d to %d (dec)\n",
|
||||
timeout, MIN_TIME, MAX_TIME);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return platform_driver_register(&ie6xx_wdt_driver);
|
||||
}
|
||||
|
||||
static void __exit ie6xx_wdt_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ie6xx_wdt_driver);
|
||||
}
|
||||
|
||||
late_initcall(ie6xx_wdt_init);
|
||||
module_exit(ie6xx_wdt_exit);
|
||||
|
||||
MODULE_AUTHOR("Alexander Stein <alexander.stein@systec-electronic.com>");
|
||||
MODULE_DESCRIPTION("Intel Atom E6xx Watchdog Device Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
|
||||
MODULE_ALIAS("platform:" DRIVER_NAME);
|
|
@ -12,7 +12,8 @@
|
|||
* http://www.ite.com.tw/
|
||||
*
|
||||
* Support of the watchdog timers, which are available on
|
||||
* IT8702, IT8712, IT8716, IT8718, IT8720, IT8721 and IT8726.
|
||||
* IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726
|
||||
* and IT8728.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -84,6 +85,7 @@
|
|||
#define IT8720_ID 0x8720
|
||||
#define IT8721_ID 0x8721
|
||||
#define IT8726_ID 0x8726 /* the data sheet suggest wrongly 0x8716 */
|
||||
#define IT8728_ID 0x8728
|
||||
|
||||
/* GPIO Configuration Registers LDN=0x07 */
|
||||
#define WDTCTRL 0x71
|
||||
|
@ -95,7 +97,7 @@
|
|||
#define WDT_CIRINT 0x80
|
||||
#define WDT_MOUSEINT 0x40
|
||||
#define WDT_KYBINT 0x20
|
||||
#define WDT_GAMEPORT 0x10 /* not in it8718, it8720, it8721 */
|
||||
#define WDT_GAMEPORT 0x10 /* not in it8718, it8720, it8721, it8728 */
|
||||
#define WDT_FORCE 0x02
|
||||
#define WDT_ZERO 0x01
|
||||
|
||||
|
@ -616,6 +618,7 @@ static int __init it87_wdt_init(void)
|
|||
case IT8718_ID:
|
||||
case IT8720_ID:
|
||||
case IT8721_ID:
|
||||
case IT8728_ID:
|
||||
max_units = 65535;
|
||||
try_gameport = 0;
|
||||
break;
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
/*
|
||||
* drivers/char/watchdog/ixp2000_wdt.c
|
||||
*
|
||||
* Watchdog driver for Intel IXP2000 network processors
|
||||
*
|
||||
* Adapted from the IXP4xx watchdog driver by Lennert Buytenhek.
|
||||
* The original version carries these notices:
|
||||
*
|
||||
* Author: Deepak Saxena <dsaxena@plexity.net>
|
||||
*
|
||||
* Copyright 2004 (c) MontaVista, Software, Inc.
|
||||
* Based on sa1100 driver, Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/watchdog.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
static bool nowayout = WATCHDOG_NOWAYOUT;
|
||||
static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */
|
||||
static unsigned long wdt_status;
|
||||
static DEFINE_SPINLOCK(wdt_lock);
|
||||
|
||||
#define WDT_IN_USE 0
|
||||
#define WDT_OK_TO_CLOSE 1
|
||||
|
||||
static unsigned long wdt_tick_rate;
|
||||
|
||||
static void wdt_enable(void)
|
||||
{
|
||||
spin_lock(&wdt_lock);
|
||||
ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE);
|
||||
ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE);
|
||||
ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
|
||||
ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE);
|
||||
spin_unlock(&wdt_lock);
|
||||
}
|
||||
|
||||
static void wdt_disable(void)
|
||||
{
|
||||
spin_lock(&wdt_lock);
|
||||
ixp2000_reg_write(IXP2000_T4_CTL, 0);
|
||||
spin_unlock(&wdt_lock);
|
||||
}
|
||||
|
||||
static void wdt_keepalive(void)
|
||||
{
|
||||
spin_lock(&wdt_lock);
|
||||
ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
|
||||
spin_unlock(&wdt_lock);
|
||||
}
|
||||
|
||||
static int ixp2000_wdt_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
if (test_and_set_bit(WDT_IN_USE, &wdt_status))
|
||||
return -EBUSY;
|
||||
|
||||
clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
|
||||
|
||||
wdt_enable();
|
||||
|
||||
return nonseekable_open(inode, file);
|
||||
}
|
||||
|
||||
static ssize_t ixp2000_wdt_write(struct file *file, const char *data,
|
||||
size_t len, loff_t *ppos)
|
||||
{
|
||||
if (len) {
|
||||
if (!nowayout) {
|
||||
size_t i;
|
||||
|
||||
clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
|
||||
|
||||
for (i = 0; i != len; i++) {
|
||||
char c;
|
||||
|
||||
if (get_user(c, data + i))
|
||||
return -EFAULT;
|
||||
if (c == 'V')
|
||||
set_bit(WDT_OK_TO_CLOSE, &wdt_status);
|
||||
}
|
||||
}
|
||||
wdt_keepalive();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static const struct watchdog_info ident = {
|
||||
.options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
|
||||
WDIOF_KEEPALIVEPING,
|
||||
.identity = "IXP2000 Watchdog",
|
||||
};
|
||||
|
||||
static long ixp2000_wdt_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int ret = -ENOTTY;
|
||||
int time;
|
||||
|
||||
switch (cmd) {
|
||||
case WDIOC_GETSUPPORT:
|
||||
ret = copy_to_user((struct watchdog_info *)arg, &ident,
|
||||
sizeof(ident)) ? -EFAULT : 0;
|
||||
break;
|
||||
|
||||
case WDIOC_GETSTATUS:
|
||||
ret = put_user(0, (int *)arg);
|
||||
break;
|
||||
|
||||
case WDIOC_GETBOOTSTATUS:
|
||||
ret = put_user(0, (int *)arg);
|
||||
break;
|
||||
|
||||
case WDIOC_KEEPALIVE:
|
||||
wdt_enable();
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case WDIOC_SETTIMEOUT:
|
||||
ret = get_user(time, (int *)arg);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
if (time <= 0 || time > 60) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
heartbeat = time;
|
||||
wdt_keepalive();
|
||||
/* Fall through */
|
||||
|
||||
case WDIOC_GETTIMEOUT:
|
||||
ret = put_user(heartbeat, (int *)arg);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ixp2000_wdt_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
|
||||
wdt_disable();
|
||||
else
|
||||
pr_crit("Device closed unexpectedly - timer will not stop\n");
|
||||
clear_bit(WDT_IN_USE, &wdt_status);
|
||||
clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct file_operations ixp2000_wdt_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.write = ixp2000_wdt_write,
|
||||
.unlocked_ioctl = ixp2000_wdt_ioctl,
|
||||
.open = ixp2000_wdt_open,
|
||||
.release = ixp2000_wdt_release,
|
||||
};
|
||||
|
||||
static struct miscdevice ixp2000_wdt_miscdev = {
|
||||
.minor = WATCHDOG_MINOR,
|
||||
.name = "watchdog",
|
||||
.fops = &ixp2000_wdt_fops,
|
||||
};
|
||||
|
||||
static int __init ixp2000_wdt_init(void)
|
||||
{
|
||||
if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
|
||||
pr_info("Unable to use IXP2000 watchdog due to IXP2800 erratum #25\n");
|
||||
return -EIO;
|
||||
}
|
||||
wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
|
||||
return misc_register(&ixp2000_wdt_miscdev);
|
||||
}
|
||||
|
||||
static void __exit ixp2000_wdt_exit(void)
|
||||
{
|
||||
misc_deregister(&ixp2000_wdt_miscdev);
|
||||
}
|
||||
|
||||
module_init(ixp2000_wdt_init);
|
||||
module_exit(ixp2000_wdt_exit);
|
||||
|
||||
MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
|
||||
MODULE_DESCRIPTION("IXP2000 Network Processor Watchdog");
|
||||
|
||||
module_param(heartbeat, int, 0);
|
||||
MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 60s)");
|
||||
|
||||
module_param(nowayout, bool, 0);
|
||||
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
|
||||
|
|
@ -707,6 +707,7 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
|
|||
goto err_out_disable_device;
|
||||
}
|
||||
|
||||
spin_lock_init(&pcipcwd_private.io_lock);
|
||||
pcipcwd_private.pdev = pdev;
|
||||
pcipcwd_private.io_addr = pci_resource_start(pdev, 0);
|
||||
|
||||
|
@ -814,22 +815,7 @@ static struct pci_driver pcipcwd_driver = {
|
|||
.remove = __devexit_p(pcipcwd_card_exit),
|
||||
};
|
||||
|
||||
static int __init pcipcwd_init_module(void)
|
||||
{
|
||||
spin_lock_init(&pcipcwd_private.io_lock);
|
||||
|
||||
return pci_register_driver(&pcipcwd_driver);
|
||||
}
|
||||
|
||||
static void __exit pcipcwd_cleanup_module(void)
|
||||
{
|
||||
pci_unregister_driver(&pcipcwd_driver);
|
||||
|
||||
pr_info("Watchdog Module Unloaded\n");
|
||||
}
|
||||
|
||||
module_init(pcipcwd_init_module);
|
||||
module_exit(pcipcwd_cleanup_module);
|
||||
module_pci_driver(pcipcwd_driver);
|
||||
|
||||
MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>");
|
||||
MODULE_DESCRIPTION("Berkshire PCI-PC Watchdog driver");
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
/* WatchDog Timer - Chapter 23 Page 207 */
|
||||
|
@ -201,10 +202,19 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id pnx4008_wdt_match[] = {
|
||||
{ .compatible = "nxp,pnx4008-wdt" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pnx4008_wdt_match);
|
||||
#endif
|
||||
|
||||
static struct platform_driver platform_wdt_driver = {
|
||||
.driver = {
|
||||
.name = "pnx4008-watchdog",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(pnx4008_wdt_match),
|
||||
},
|
||||
.probe = pnx4008_wdt_probe,
|
||||
.remove = __devexit_p(pnx4008_wdt_remove),
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <linux/cpufreq.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <mach/map.h>
|
||||
|
||||
|
@ -201,7 +202,7 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou
|
|||
writel(count, wdt_base + S3C2410_WTDAT);
|
||||
writel(wtcon, wdt_base + S3C2410_WTCON);
|
||||
|
||||
wdd->timeout = timeout;
|
||||
wdd->timeout = (count * divisor) / freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -503,8 +504,6 @@ static const struct of_device_id s3c2410_wdt_match[] = {
|
|||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
|
||||
#else
|
||||
#define s3c2410_wdt_match NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver s3c2410wdt_driver = {
|
||||
|
@ -516,7 +515,7 @@ static struct platform_driver s3c2410wdt_driver = {
|
|||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "s3c2410-wdt",
|
||||
.of_match_table = s3c2410_wdt_match,
|
||||
.of_match_table = of_match_ptr(s3c2410_wdt_match),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#define DRV_NAME "sch311x_wdt"
|
||||
|
||||
/* Runtime registers */
|
||||
#define RESGEN 0x1d
|
||||
#define GP60 0x47
|
||||
#define WDT_TIME_OUT 0x65
|
||||
#define WDT_VAL 0x66
|
||||
|
@ -69,10 +68,6 @@ static unsigned short force_id;
|
|||
module_param(force_id, ushort, 0);
|
||||
MODULE_PARM_DESC(force_id, "Override the detected device ID");
|
||||
|
||||
static unsigned short therm_trip;
|
||||
module_param(therm_trip, ushort, 0);
|
||||
MODULE_PARM_DESC(therm_trip, "Should a ThermTrip trigger the reset generator");
|
||||
|
||||
#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
|
||||
static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
|
||||
module_param(timeout, int, 0);
|
||||
|
@ -358,26 +353,16 @@ static struct miscdevice sch311x_wdt_miscdev = {
|
|||
static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
unsigned char val;
|
||||
int err;
|
||||
|
||||
spin_lock_init(&sch311x_wdt_data.io_lock);
|
||||
|
||||
if (!request_region(sch311x_wdt_data.runtime_reg + RESGEN, 1,
|
||||
DRV_NAME)) {
|
||||
dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
|
||||
sch311x_wdt_data.runtime_reg + RESGEN,
|
||||
sch311x_wdt_data.runtime_reg + RESGEN);
|
||||
err = -EBUSY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!request_region(sch311x_wdt_data.runtime_reg + GP60, 1, DRV_NAME)) {
|
||||
dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
|
||||
sch311x_wdt_data.runtime_reg + GP60,
|
||||
sch311x_wdt_data.runtime_reg + GP60);
|
||||
err = -EBUSY;
|
||||
goto exit_release_region;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!request_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4,
|
||||
|
@ -386,7 +371,7 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
|
|||
sch311x_wdt_data.runtime_reg + WDT_TIME_OUT,
|
||||
sch311x_wdt_data.runtime_reg + WDT_CTRL);
|
||||
err = -EBUSY;
|
||||
goto exit_release_region2;
|
||||
goto exit_release_region;
|
||||
}
|
||||
|
||||
/* Make sure that the watchdog is not running */
|
||||
|
@ -414,24 +399,13 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
|
|||
/* Get status at boot */
|
||||
sch311x_wdt_get_status(&sch311x_wdt_data.boot_status);
|
||||
|
||||
/* enable watchdog */
|
||||
/* -- Reset Generator --
|
||||
* Bit 0 Enable Watchdog Timer Generation: 0* = Enabled, 1 = Disabled
|
||||
* Bit 1 Thermtrip Source Select: O* = No Source, 1 = Source
|
||||
* Bit 2 WDT2_CTL: WDT input bit
|
||||
* Bit 3-7 Reserved
|
||||
*/
|
||||
outb(0, sch311x_wdt_data.runtime_reg + RESGEN);
|
||||
val = therm_trip ? 0x06 : 0x04;
|
||||
outb(val, sch311x_wdt_data.runtime_reg + RESGEN);
|
||||
|
||||
sch311x_wdt_miscdev.parent = dev;
|
||||
|
||||
err = misc_register(&sch311x_wdt_miscdev);
|
||||
if (err != 0) {
|
||||
dev_err(dev, "cannot register miscdev on minor=%d (err=%d)\n",
|
||||
WATCHDOG_MINOR, err);
|
||||
goto exit_release_region3;
|
||||
goto exit_release_region2;
|
||||
}
|
||||
|
||||
dev_info(dev,
|
||||
|
@ -440,12 +414,10 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
|
|||
|
||||
return 0;
|
||||
|
||||
exit_release_region3:
|
||||
release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
|
||||
exit_release_region2:
|
||||
release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
|
||||
release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
|
||||
exit_release_region:
|
||||
release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1);
|
||||
release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
|
||||
sch311x_wdt_data.runtime_reg = 0;
|
||||
exit:
|
||||
return err;
|
||||
|
@ -461,7 +433,6 @@ static int __devexit sch311x_wdt_remove(struct platform_device *pdev)
|
|||
misc_deregister(&sch311x_wdt_miscdev);
|
||||
release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
|
||||
release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
|
||||
release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1);
|
||||
sch311x_wdt_data.runtime_reg = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -313,7 +313,7 @@ static unsigned char __devinit sp5100_tco_setupdevice(void)
|
|||
tcobase_phys = val;
|
||||
|
||||
tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE);
|
||||
if (tcobase == 0) {
|
||||
if (!tcobase) {
|
||||
pr_err("failed to get tcobase address\n");
|
||||
goto unreg_mem_region;
|
||||
}
|
||||
|
|
|
@ -202,6 +202,9 @@ static int __devinit wdt_probe(struct pci_dev *pdev,
|
|||
goto err_out_release;
|
||||
}
|
||||
|
||||
if (timeout < 1 || timeout > WDT_TIMEOUT_MAX)
|
||||
timeout = WDT_TIMEOUT;
|
||||
|
||||
wdt_dev.timeout = timeout;
|
||||
watchdog_set_nowayout(&wdt_dev, nowayout);
|
||||
if (readl(wdt_mem) & VIA_WDT_FIRED)
|
||||
|
@ -250,20 +253,7 @@ static struct pci_driver wdt_driver = {
|
|||
.remove = __devexit_p(wdt_remove),
|
||||
};
|
||||
|
||||
static int __init wdt_init(void)
|
||||
{
|
||||
if (timeout < 1 || timeout > WDT_TIMEOUT_MAX)
|
||||
timeout = WDT_TIMEOUT;
|
||||
return pci_register_driver(&wdt_driver);
|
||||
}
|
||||
|
||||
static void __exit wdt_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&wdt_driver);
|
||||
}
|
||||
|
||||
module_init(wdt_init);
|
||||
module_exit(wdt_exit);
|
||||
module_pci_driver(wdt_driver);
|
||||
|
||||
MODULE_AUTHOR("Marc Vertes");
|
||||
MODULE_DESCRIPTION("Driver for watchdog timer on VIA chipset");
|
||||
|
|
|
@ -739,39 +739,7 @@ static struct pci_driver wdtpci_driver = {
|
|||
.remove = __devexit_p(wdtpci_remove_one),
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* wdtpci_cleanup:
|
||||
*
|
||||
* 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 xx seconds or reboot.
|
||||
*/
|
||||
|
||||
static void __exit wdtpci_cleanup(void)
|
||||
{
|
||||
pci_unregister_driver(&wdtpci_driver);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wdtpci_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 wdtpci_init(void)
|
||||
{
|
||||
return pci_register_driver(&wdtpci_driver);
|
||||
}
|
||||
|
||||
|
||||
module_init(wdtpci_init);
|
||||
module_exit(wdtpci_cleanup);
|
||||
module_pci_driver(wdtpci_driver);
|
||||
|
||||
MODULE_AUTHOR("JP Nollmann, Alan Cox");
|
||||
MODULE_DESCRIPTION("Driver for the ICS PCI-WDT500/501 watchdog cards");
|
||||
|
|
|
@ -247,8 +247,9 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
|
|||
reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT;
|
||||
|
||||
if (pdata->update_gpio) {
|
||||
ret = gpio_request(pdata->update_gpio,
|
||||
"Watchdog update");
|
||||
ret = gpio_request_one(pdata->update_gpio,
|
||||
GPIOF_DIR_OUT | GPIOF_INIT_LOW,
|
||||
"Watchdog update");
|
||||
if (ret < 0) {
|
||||
dev_err(wm831x->dev,
|
||||
"Failed to request update GPIO: %d\n",
|
||||
|
@ -256,14 +257,6 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
|
|||
goto err;
|
||||
}
|
||||
|
||||
ret = gpio_direction_output(pdata->update_gpio, 0);
|
||||
if (ret != 0) {
|
||||
dev_err(wm831x->dev,
|
||||
"gpio_direction_output returned: %d\n",
|
||||
ret);
|
||||
goto err_gpio;
|
||||
}
|
||||
|
||||
driver_data->update_gpio = pdata->update_gpio;
|
||||
|
||||
/* Make sure the watchdog takes hardware updates */
|
||||
|
|
Loading…
Reference in New Issue