Merge git://www.linux-watchdog.org/linux-watchdog
* git://www.linux-watchdog.org/linux-watchdog: watchdog: omap_wdt.c: fix the WDIOC_GETBOOTSTATUS ioctl if not implemented. watchdog: new driver for VIA chipsets watchdog: ath79_wdt: flush register writes drivers/watchdog/lantiq_wdt.c: drop iounmap for devm_ allocated data watchdog: documentation: describe nowayout in coversion-guide watchdog: documentation: update index file watchdog: Convert wm831x driver to devm_kzalloc() watchdog: add nowayout helpers to Watchdog Timer Driver Kernel API watchdog: convert drivers/watchdog/* to use module_platform_driver() watchdog: Use DEFINE_SPINLOCK() for static spinlocks watchdog: Convert Wolfson drivers to module_platform_driver
This commit is contained in:
commit
88266917b5
|
@ -1,5 +1,7 @@
|
||||||
00-INDEX
|
00-INDEX
|
||||||
- this file.
|
- this file.
|
||||||
|
convert_drivers_to_kernel_api.txt
|
||||||
|
- how-to for converting old watchdog drivers to the new kernel API.
|
||||||
hpwdt.txt
|
hpwdt.txt
|
||||||
- information on the HP iLO2 NMI watchdog
|
- information on the HP iLO2 NMI watchdog
|
||||||
pcwd-watchdog.txt
|
pcwd-watchdog.txt
|
||||||
|
|
|
@ -163,6 +163,25 @@ Here is a simple example for a watchdog device:
|
||||||
+};
|
+};
|
||||||
|
|
||||||
|
|
||||||
|
Handle the 'nowayout' feature
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
A few drivers use nowayout statically, i.e. there is no module parameter for it
|
||||||
|
and only CONFIG_WATCHDOG_NOWAYOUT determines if the feature is going to be
|
||||||
|
used. This needs to be converted by initializing the status variable of the
|
||||||
|
watchdog_device like this:
|
||||||
|
|
||||||
|
.status = WATCHDOG_NOWAYOUT_INIT_STATUS,
|
||||||
|
|
||||||
|
Most drivers, however, also allow runtime configuration of nowayout, usually
|
||||||
|
by adding a module parameter. The conversion for this would be something like:
|
||||||
|
|
||||||
|
watchdog_set_nowayout(&s3c2410_wdd, nowayout);
|
||||||
|
|
||||||
|
The module parameter itself needs to stay, everything else related to nowayout
|
||||||
|
can go, though. This will likely be some code in open(), close() or write().
|
||||||
|
|
||||||
|
|
||||||
Register the watchdog device
|
Register the watchdog device
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
The Linux WatchDog Timer Driver Core kernel API.
|
The Linux WatchDog Timer Driver Core kernel API.
|
||||||
===============================================
|
===============================================
|
||||||
Last reviewed: 22-Jul-2011
|
Last reviewed: 29-Nov-2011
|
||||||
|
|
||||||
Wim Van Sebroeck <wim@iguana.be>
|
Wim Van Sebroeck <wim@iguana.be>
|
||||||
|
|
||||||
|
@ -142,6 +142,14 @@ bit-operations. The status bits that are defined are:
|
||||||
* WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog.
|
* WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog.
|
||||||
If this bit is set then the watchdog timer will not be able to stop.
|
If this bit is set then the watchdog timer will not be able to stop.
|
||||||
|
|
||||||
|
To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog
|
||||||
|
timer device) you can either:
|
||||||
|
* set it statically in your watchdog_device struct with
|
||||||
|
.status = WATCHDOG_NOWAYOUT_INIT_STATUS,
|
||||||
|
(this will set the value the same as CONFIG_WATCHDOG_NOWAYOUT) or
|
||||||
|
* use the following helper function:
|
||||||
|
static inline void watchdog_set_nowayout(struct watchdog_device *wdd, int nowayout)
|
||||||
|
|
||||||
Note: The WatchDog Timer Driver Core supports the magic close feature and
|
Note: The WatchDog Timer Driver Core supports the magic close feature and
|
||||||
the nowayout feature. To use the magic close feature you must set the
|
the nowayout feature. To use the magic close feature you must set the
|
||||||
WDIOF_MAGICCLOSE bit in the options field of the watchdog's info structure.
|
WDIOF_MAGICCLOSE bit in the options field of the watchdog's info structure.
|
||||||
|
|
|
@ -772,6 +772,19 @@ config SMSC37B787_WDT
|
||||||
|
|
||||||
Most people will say N.
|
Most people will say N.
|
||||||
|
|
||||||
|
config VIA_WDT
|
||||||
|
tristate "VIA Watchdog Timer"
|
||||||
|
depends on X86
|
||||||
|
select WATCHDOG_CORE
|
||||||
|
---help---
|
||||||
|
This is the driver for the hardware watchdog timer on VIA
|
||||||
|
southbridge chipset CX700, VX800/VX820 or VX855/VX875.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here; the module
|
||||||
|
will be called via_wdt.
|
||||||
|
|
||||||
|
Most people will say N.
|
||||||
|
|
||||||
config W83627HF_WDT
|
config W83627HF_WDT
|
||||||
tristate "W83627HF/W83627DHG Watchdog Timer"
|
tristate "W83627HF/W83627DHG Watchdog Timer"
|
||||||
depends on X86
|
depends on X86
|
||||||
|
|
|
@ -99,6 +99,7 @@ obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o
|
||||||
obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
|
obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
|
||||||
obj-$(CONFIG_SMSC_SCH311X_WDT) += sch311x_wdt.o
|
obj-$(CONFIG_SMSC_SCH311X_WDT) += sch311x_wdt.o
|
||||||
obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o
|
obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o
|
||||||
|
obj-$(CONFIG_VIA_WDT) += via_wdt.o
|
||||||
obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
|
obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
|
||||||
obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o
|
obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o
|
||||||
obj-$(CONFIG_W83697UG_WDT) += w83697ug_wdt.o
|
obj-$(CONFIG_W83697UG_WDT) += w83697ug_wdt.o
|
||||||
|
|
|
@ -70,8 +70,8 @@ struct ar7_wdt {
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned long wdt_is_open;
|
static unsigned long wdt_is_open;
|
||||||
static spinlock_t wdt_lock;
|
|
||||||
static unsigned expect_close;
|
static unsigned expect_close;
|
||||||
|
static DEFINE_SPINLOCK(wdt_lock);
|
||||||
|
|
||||||
/* XXX currently fixed, allows max margin ~68.72 secs */
|
/* XXX currently fixed, allows max margin ~68.72 secs */
|
||||||
#define prescale_value 0xffff
|
#define prescale_value 0xffff
|
||||||
|
@ -280,8 +280,6 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
spin_lock_init(&wdt_lock);
|
|
||||||
|
|
||||||
ar7_regs_wdt =
|
ar7_regs_wdt =
|
||||||
platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
|
platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
|
||||||
if (!ar7_regs_wdt) {
|
if (!ar7_regs_wdt) {
|
||||||
|
@ -355,15 +353,4 @@ static struct platform_driver ar7_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ar7_wdt_init(void)
|
module_platform_driver(ar7_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&ar7_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit ar7_wdt_cleanup(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&ar7_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(ar7_wdt_init);
|
|
||||||
module_exit(ar7_wdt_cleanup);
|
|
||||||
|
|
|
@ -68,17 +68,23 @@ static int max_timeout;
|
||||||
static inline void ath79_wdt_keepalive(void)
|
static inline void ath79_wdt_keepalive(void)
|
||||||
{
|
{
|
||||||
ath79_reset_wr(AR71XX_RESET_REG_WDOG, wdt_freq * timeout);
|
ath79_reset_wr(AR71XX_RESET_REG_WDOG, wdt_freq * timeout);
|
||||||
|
/* flush write */
|
||||||
|
ath79_reset_rr(AR71XX_RESET_REG_WDOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ath79_wdt_enable(void)
|
static inline void ath79_wdt_enable(void)
|
||||||
{
|
{
|
||||||
ath79_wdt_keepalive();
|
ath79_wdt_keepalive();
|
||||||
ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
|
ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
|
||||||
|
/* flush write */
|
||||||
|
ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ath79_wdt_disable(void)
|
static inline void ath79_wdt_disable(void)
|
||||||
{
|
{
|
||||||
ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
|
ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
|
||||||
|
/* flush write */
|
||||||
|
ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ath79_wdt_set_timeout(int val)
|
static int ath79_wdt_set_timeout(int val)
|
||||||
|
|
|
@ -311,18 +311,7 @@ static struct platform_driver bcm63xx_wdt = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init bcm63xx_wdt_init(void)
|
module_platform_driver(bcm63xx_wdt);
|
||||||
{
|
|
||||||
return platform_driver_register(&bcm63xx_wdt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit bcm63xx_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&bcm63xx_wdt);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(bcm63xx_wdt_init);
|
|
||||||
module_exit(bcm63xx_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>");
|
MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>");
|
||||||
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
|
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
static int verbose;
|
static int verbose;
|
||||||
static int port = 0x91;
|
static int port = 0x91;
|
||||||
static int ticks = 10000;
|
static int ticks = 10000;
|
||||||
static spinlock_t cpu5wdt_lock;
|
static DEFINE_SPINLOCK(cpu5wdt_lock);
|
||||||
|
|
||||||
#define PFX "cpu5wdt: "
|
#define PFX "cpu5wdt: "
|
||||||
|
|
||||||
|
@ -223,7 +223,6 @@ static int __devinit cpu5wdt_init(void)
|
||||||
"port=0x%x, verbose=%i\n", port, verbose);
|
"port=0x%x, verbose=%i\n", port, verbose);
|
||||||
|
|
||||||
init_completion(&cpu5wdt_device.stop);
|
init_completion(&cpu5wdt_device.stop);
|
||||||
spin_lock_init(&cpu5wdt_lock);
|
|
||||||
cpu5wdt_device.queue = 0;
|
cpu5wdt_device.queue = 0;
|
||||||
setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0);
|
setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0);
|
||||||
cpu5wdt_device.default_ticks = ticks;
|
cpu5wdt_device.default_ticks = ticks;
|
||||||
|
|
|
@ -687,15 +687,4 @@ static struct platform_driver cpwd_driver = {
|
||||||
.remove = __devexit_p(cpwd_remove),
|
.remove = __devexit_p(cpwd_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init cpwd_init(void)
|
module_platform_driver(cpwd_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&cpwd_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit cpwd_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&cpwd_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(cpwd_init);
|
|
||||||
module_exit(cpwd_exit);
|
|
||||||
|
|
|
@ -271,18 +271,7 @@ static struct platform_driver platform_wdt_driver = {
|
||||||
.remove = __devexit_p(davinci_wdt_remove),
|
.remove = __devexit_p(davinci_wdt_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init davinci_wdt_init(void)
|
module_platform_driver(platform_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&platform_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit davinci_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&platform_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(davinci_wdt_init);
|
|
||||||
module_exit(davinci_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Texas Instruments");
|
MODULE_AUTHOR("Texas Instruments");
|
||||||
MODULE_DESCRIPTION("DaVinci Watchdog Driver");
|
MODULE_DESCRIPTION("DaVinci Watchdog Driver");
|
||||||
|
|
|
@ -358,17 +358,7 @@ static struct platform_driver dw_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init dw_wdt_watchdog_init(void)
|
module_platform_driver(dw_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&dw_wdt_driver);
|
|
||||||
}
|
|
||||||
module_init(dw_wdt_watchdog_init);
|
|
||||||
|
|
||||||
static void __exit dw_wdt_watchdog_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&dw_wdt_driver);
|
|
||||||
}
|
|
||||||
module_exit(dw_wdt_watchdog_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Jamie Iles");
|
MODULE_AUTHOR("Jamie Iles");
|
||||||
MODULE_DESCRIPTION("Synopsys DesignWare Watchdog Driver");
|
MODULE_DESCRIPTION("Synopsys DesignWare Watchdog Driver");
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
static unsigned long eurwdt_is_open;
|
static unsigned long eurwdt_is_open;
|
||||||
static int eurwdt_timeout;
|
static int eurwdt_timeout;
|
||||||
static char eur_expect_close;
|
static char eur_expect_close;
|
||||||
static spinlock_t eurwdt_lock;
|
static DEFINE_SPINLOCK(eurwdt_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* You must set these - there is no sane way to probe for this board.
|
* You must set these - there is no sane way to probe for this board.
|
||||||
|
@ -446,8 +446,6 @@ static int __init eurwdt_init(void)
|
||||||
goto outreg;
|
goto outreg;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_init(&eurwdt_lock);
|
|
||||||
|
|
||||||
ret = misc_register(&eurwdt_miscdev);
|
ret = misc_register(&eurwdt_miscdev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
|
printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
|
||||||
|
|
|
@ -68,7 +68,7 @@ static char asr_expect_close;
|
||||||
static unsigned int asr_type, asr_base, asr_length;
|
static unsigned int asr_type, asr_base, asr_length;
|
||||||
static unsigned int asr_read_addr, asr_write_addr;
|
static unsigned int asr_read_addr, asr_write_addr;
|
||||||
static unsigned char asr_toggle_mask, asr_disable_mask;
|
static unsigned char asr_toggle_mask, asr_disable_mask;
|
||||||
static spinlock_t asr_lock;
|
static DEFINE_SPINLOCK(asr_lock);
|
||||||
|
|
||||||
static void __asr_toggle(void)
|
static void __asr_toggle(void)
|
||||||
{
|
{
|
||||||
|
@ -386,8 +386,6 @@ static int __init ibmasr_init(void)
|
||||||
if (!asr_type)
|
if (!asr_type)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
spin_lock_init(&asr_lock);
|
|
||||||
|
|
||||||
rc = asr_get_base_address();
|
rc = asr_get_base_address();
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
#define PFX "indydog: "
|
#define PFX "indydog: "
|
||||||
static unsigned long indydog_alive;
|
static unsigned long indydog_alive;
|
||||||
static spinlock_t indydog_lock;
|
static DEFINE_SPINLOCK(indydog_lock);
|
||||||
|
|
||||||
#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
|
#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
|
||||||
|
|
||||||
|
@ -185,8 +185,6 @@ static int __init watchdog_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
spin_lock_init(&indydog_lock);
|
|
||||||
|
|
||||||
ret = register_reboot_notifier(&indydog_notifier);
|
ret = register_reboot_notifier(&indydog_notifier);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_ERR PFX
|
printk(KERN_ERR PFX
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
static int nowayout = WATCHDOG_NOWAYOUT;
|
static int nowayout = WATCHDOG_NOWAYOUT;
|
||||||
static unsigned long wdt_status;
|
static unsigned long wdt_status;
|
||||||
static unsigned long boot_status;
|
static unsigned long boot_status;
|
||||||
static spinlock_t wdt_lock;
|
static DEFINE_SPINLOCK(wdt_lock);
|
||||||
|
|
||||||
#define WDT_IN_USE 0
|
#define WDT_IN_USE 0
|
||||||
#define WDT_OK_TO_CLOSE 1
|
#define WDT_OK_TO_CLOSE 1
|
||||||
|
@ -226,9 +226,6 @@ static int __init iop_wdt_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
spin_lock_init(&wdt_lock);
|
|
||||||
|
|
||||||
|
|
||||||
/* check if the reset was caused by the watchdog timer */
|
/* check if the reset was caused by the watchdog timer */
|
||||||
boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;
|
boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
static int nowayout = WATCHDOG_NOWAYOUT;
|
static int nowayout = WATCHDOG_NOWAYOUT;
|
||||||
static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */
|
static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */
|
||||||
static unsigned long wdt_status;
|
static unsigned long wdt_status;
|
||||||
static spinlock_t wdt_lock;
|
static DEFINE_SPINLOCK(wdt_lock);
|
||||||
|
|
||||||
#define WDT_IN_USE 0
|
#define WDT_IN_USE 0
|
||||||
#define WDT_OK_TO_CLOSE 1
|
#define WDT_OK_TO_CLOSE 1
|
||||||
|
@ -189,7 +189,6 @@ static int __init ixp2000_wdt_init(void)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
|
wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
|
||||||
spin_lock_init(&wdt_lock);
|
|
||||||
return misc_register(&ixp2000_wdt_miscdev);
|
return misc_register(&ixp2000_wdt_miscdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,6 @@ static int __init ixp4xx_wdt_init(void)
|
||||||
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
spin_lock_init(&wdt_lock);
|
|
||||||
boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ?
|
boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ?
|
||||||
WDIOF_CARDRESET : 0;
|
WDIOF_CARDRESET : 0;
|
||||||
ret = misc_register(&ixp4xx_wdt_miscdev);
|
ret = misc_register(&ixp4xx_wdt_miscdev);
|
||||||
|
|
|
@ -295,18 +295,7 @@ static struct platform_driver jz4740_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module_platform_driver(jz4740_wdt_driver);
|
||||||
static int __init jz4740_wdt_init(void)
|
|
||||||
{
|
|
||||||
return platform_driver_register(&jz4740_wdt_driver);
|
|
||||||
}
|
|
||||||
module_init(jz4740_wdt_init);
|
|
||||||
|
|
||||||
static void __exit jz4740_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&jz4740_wdt_driver);
|
|
||||||
}
|
|
||||||
module_exit(jz4740_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
|
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
|
||||||
MODULE_DESCRIPTION("jz4740 Watchdog Driver");
|
MODULE_DESCRIPTION("jz4740 Watchdog Driver");
|
||||||
|
|
|
@ -42,7 +42,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
||||||
|
|
||||||
|
|
||||||
static unsigned long ks8695wdt_busy;
|
static unsigned long ks8695wdt_busy;
|
||||||
static spinlock_t ks8695_lock;
|
static DEFINE_SPINLOCK(ks8695_lock);
|
||||||
|
|
||||||
/* ......................................................................... */
|
/* ......................................................................... */
|
||||||
|
|
||||||
|
@ -288,7 +288,6 @@ static struct platform_driver ks8695wdt_driver = {
|
||||||
|
|
||||||
static int __init ks8695_wdt_init(void)
|
static int __init ks8695_wdt_init(void)
|
||||||
{
|
{
|
||||||
spin_lock_init(&ks8695_lock);
|
|
||||||
/* Check that the heartbeat value is within range;
|
/* Check that the heartbeat value is within range;
|
||||||
if not reset to the default */
|
if not reset to the default */
|
||||||
if (ks8695_wdt_settimeout(wdt_time)) {
|
if (ks8695_wdt_settimeout(wdt_time)) {
|
||||||
|
|
|
@ -222,9 +222,6 @@ ltq_wdt_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
misc_deregister(<q_wdt_miscdev);
|
misc_deregister(<q_wdt_miscdev);
|
||||||
|
|
||||||
if (ltq_wdt_membase)
|
|
||||||
iounmap(ltq_wdt_membase);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -364,18 +364,7 @@ static struct platform_driver max63xx_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init max63xx_wdt_init(void)
|
module_platform_driver(max63xx_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&max63xx_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit max63xx_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&max63xx_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(max63xx_wdt_init);
|
|
||||||
module_exit(max63xx_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>");
|
MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>");
|
||||||
MODULE_DESCRIPTION("max63xx Watchdog Driver");
|
MODULE_DESCRIPTION("max63xx Watchdog Driver");
|
||||||
|
|
|
@ -253,18 +253,7 @@ static struct platform_driver mtx1_wdt_driver = {
|
||||||
.driver.owner = THIS_MODULE,
|
.driver.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init mtx1_wdt_init(void)
|
module_platform_driver(mtx1_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&mtx1_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit mtx1_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&mtx1_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(mtx1_wdt_init);
|
|
||||||
module_exit(mtx1_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Michael Stickel, Florian Fainelli");
|
MODULE_AUTHOR("Michael Stickel, Florian Fainelli");
|
||||||
MODULE_DESCRIPTION("Driver for the MTX-1 watchdog");
|
MODULE_DESCRIPTION("Driver for the MTX-1 watchdog");
|
||||||
|
|
|
@ -334,18 +334,7 @@ static struct platform_driver nuc900wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init nuc900_wdt_init(void)
|
module_platform_driver(nuc900wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&nuc900wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit nuc900_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&nuc900wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(nuc900_wdt_init);
|
|
||||||
module_exit(nuc900_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
|
MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
|
||||||
MODULE_DESCRIPTION("Watchdog driver for NUC900");
|
MODULE_DESCRIPTION("Watchdog driver for NUC900");
|
||||||
|
|
|
@ -414,18 +414,7 @@ static struct platform_driver xwdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init xwdt_init(void)
|
module_platform_driver(xwdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&xwdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit xwdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&xwdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(xwdt_init);
|
|
||||||
module_exit(xwdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>");
|
MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>");
|
||||||
MODULE_DESCRIPTION("Xilinx Watchdog driver");
|
MODULE_DESCRIPTION("Xilinx Watchdog driver");
|
||||||
|
|
|
@ -55,7 +55,7 @@ module_param(timer_margin, uint, 0);
|
||||||
MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
|
MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
|
||||||
|
|
||||||
static unsigned int wdt_trgr_pattern = 0x1234;
|
static unsigned int wdt_trgr_pattern = 0x1234;
|
||||||
static spinlock_t wdt_lock;
|
static DEFINE_SPINLOCK(wdt_lock);
|
||||||
|
|
||||||
struct omap_wdt_dev {
|
struct omap_wdt_dev {
|
||||||
void __iomem *base; /* physical */
|
void __iomem *base; /* physical */
|
||||||
|
@ -232,6 +232,7 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
|
||||||
if (cpu_is_omap24xx())
|
if (cpu_is_omap24xx())
|
||||||
return put_user(omap_prcm_get_reset_sources(),
|
return put_user(omap_prcm_get_reset_sources(),
|
||||||
(int __user *)arg);
|
(int __user *)arg);
|
||||||
|
return put_user(0, (int __user *)arg);
|
||||||
case WDIOC_KEEPALIVE:
|
case WDIOC_KEEPALIVE:
|
||||||
pm_runtime_get_sync(wdev->dev);
|
pm_runtime_get_sync(wdev->dev);
|
||||||
spin_lock(&wdt_lock);
|
spin_lock(&wdt_lock);
|
||||||
|
@ -437,19 +438,7 @@ static struct platform_driver omap_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init omap_wdt_init(void)
|
module_platform_driver(omap_wdt_driver);
|
||||||
{
|
|
||||||
spin_lock_init(&wdt_lock);
|
|
||||||
return platform_driver_register(&omap_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit omap_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&omap_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(omap_wdt_init);
|
|
||||||
module_exit(omap_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("George G. Davis");
|
MODULE_AUTHOR("George G. Davis");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -41,7 +41,7 @@ static int heartbeat = -1; /* module parameter (seconds) */
|
||||||
static unsigned int wdt_max_duration; /* (seconds) */
|
static unsigned int wdt_max_duration; /* (seconds) */
|
||||||
static unsigned int wdt_tclk;
|
static unsigned int wdt_tclk;
|
||||||
static unsigned long wdt_status;
|
static unsigned long wdt_status;
|
||||||
static spinlock_t wdt_lock;
|
static DEFINE_SPINLOCK(wdt_lock);
|
||||||
|
|
||||||
static void orion_wdt_ping(void)
|
static void orion_wdt_ping(void)
|
||||||
{
|
{
|
||||||
|
@ -294,19 +294,7 @@ static struct platform_driver orion_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init orion_wdt_init(void)
|
module_platform_driver(orion_wdt_driver);
|
||||||
{
|
|
||||||
spin_lock_init(&wdt_lock);
|
|
||||||
return platform_driver_register(&orion_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit orion_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&orion_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(orion_wdt_init);
|
|
||||||
module_exit(orion_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
|
MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
|
||||||
MODULE_DESCRIPTION("Orion Processor Watchdog");
|
MODULE_DESCRIPTION("Orion Processor Watchdog");
|
||||||
|
|
|
@ -334,18 +334,7 @@ static struct platform_driver platform_wdt_driver = {
|
||||||
.remove = __devexit_p(pnx4008_wdt_remove),
|
.remove = __devexit_p(pnx4008_wdt_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init pnx4008_wdt_init(void)
|
module_platform_driver(platform_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&platform_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit pnx4008_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&platform_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(pnx4008_wdt_init);
|
|
||||||
module_exit(pnx4008_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
|
MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
|
||||||
MODULE_DESCRIPTION("PNX4008 Watchdog Driver");
|
MODULE_DESCRIPTION("PNX4008 Watchdog Driver");
|
||||||
|
|
|
@ -332,18 +332,7 @@ static struct platform_driver rc32434_wdt_driver = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init rc32434_wdt_init(void)
|
module_platform_driver(rc32434_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&rc32434_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit rc32434_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&rc32434_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(rc32434_wdt_init);
|
|
||||||
module_exit(rc32434_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Ondrej Zajicek <santiago@crfreenet.org>,"
|
MODULE_AUTHOR("Ondrej Zajicek <santiago@crfreenet.org>,"
|
||||||
"Florian Fainelli <florian@openwrt.org>");
|
"Florian Fainelli <florian@openwrt.org>");
|
||||||
|
|
|
@ -293,18 +293,7 @@ static struct platform_driver rdc321x_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init rdc321x_wdt_init(void)
|
module_platform_driver(rdc321x_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&rdc321x_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit rdc321x_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&rdc321x_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(rdc321x_wdt_init);
|
|
||||||
module_exit(rdc321x_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
|
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
|
||||||
MODULE_DESCRIPTION("RDC321x watchdog driver");
|
MODULE_DESCRIPTION("RDC321x watchdog driver");
|
||||||
|
|
|
@ -247,15 +247,4 @@ static struct platform_driver riowd_driver = {
|
||||||
.remove = __devexit_p(riowd_remove),
|
.remove = __devexit_p(riowd_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init riowd_init(void)
|
module_platform_driver(riowd_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&riowd_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit riowd_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&riowd_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(riowd_init);
|
|
||||||
module_exit(riowd_exit);
|
|
||||||
|
|
|
@ -378,6 +378,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
|
||||||
"cannot start\n");
|
"cannot start\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchdog_set_nowayout(&s3c2410_wdd, nowayout);
|
||||||
|
|
||||||
ret = watchdog_register_device(&s3c2410_wdd);
|
ret = watchdog_register_device(&s3c2410_wdd);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "cannot register watchdog (%d)\n", ret);
|
dev_err(dev, "cannot register watchdog (%d)\n", ret);
|
||||||
|
|
|
@ -272,18 +272,7 @@ static struct platform_driver platform_wdt_driver = {
|
||||||
.resume = stmp3xxx_wdt_resume,
|
.resume = stmp3xxx_wdt_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init stmp3xxx_wdt_init(void)
|
module_platform_driver(platform_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&platform_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit stmp3xxx_wdt_exit(void)
|
|
||||||
{
|
|
||||||
return platform_driver_unregister(&platform_wdt_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(stmp3xxx_wdt_init);
|
|
||||||
module_exit(stmp3xxx_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("STMP3XXX Watchdog Driver");
|
MODULE_DESCRIPTION("STMP3XXX Watchdog Driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -506,17 +506,7 @@ static struct platform_driver ts72xx_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int ts72xx_wdt_init(void)
|
module_platform_driver(ts72xx_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&ts72xx_wdt_driver);
|
|
||||||
}
|
|
||||||
module_init(ts72xx_wdt_init);
|
|
||||||
|
|
||||||
static __exit void ts72xx_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&ts72xx_wdt_driver);
|
|
||||||
}
|
|
||||||
module_exit(ts72xx_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
|
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
|
||||||
MODULE_DESCRIPTION("TS-72xx SBC Watchdog");
|
MODULE_DESCRIPTION("TS-72xx SBC Watchdog");
|
||||||
|
|
|
@ -256,17 +256,7 @@ static struct platform_driver twl4030_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit twl4030_wdt_init(void)
|
module_platform_driver(twl4030_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&twl4030_wdt_driver);
|
|
||||||
}
|
|
||||||
module_init(twl4030_wdt_init);
|
|
||||||
|
|
||||||
static void __devexit twl4030_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&twl4030_wdt_driver);
|
|
||||||
}
|
|
||||||
module_exit(twl4030_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Nokia Corporation");
|
MODULE_AUTHOR("Nokia Corporation");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -0,0 +1,267 @@
|
||||||
|
/*
|
||||||
|
* VIA Chipset Watchdog Driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Sigfox
|
||||||
|
* License terms: GNU General Public License (GPL) version 2
|
||||||
|
* Author: Marc Vertes <marc.vertes@sigfox.com>
|
||||||
|
* Based on a preliminary version from Harald Welte <HaraldWelte@viatech.com>
|
||||||
|
* Timer code by Wim Van Sebroeck <wim@iguana.be>
|
||||||
|
*
|
||||||
|
* Caveat: PnP must be enabled in BIOS to allow full access to watchdog
|
||||||
|
* control registers. If not, the watchdog must be configured in BIOS manually.
|
||||||
|
*/
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/jiffies.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/timer.h>
|
||||||
|
#include <linux/watchdog.h>
|
||||||
|
|
||||||
|
/* Configuration registers relative to the pci device */
|
||||||
|
#define VIA_WDT_MMIO_BASE 0xe8 /* MMIO region base address */
|
||||||
|
#define VIA_WDT_CONF 0xec /* watchdog enable state */
|
||||||
|
|
||||||
|
/* Relevant bits for the VIA_WDT_CONF register */
|
||||||
|
#define VIA_WDT_CONF_ENABLE 0x01 /* 1: enable watchdog */
|
||||||
|
#define VIA_WDT_CONF_MMIO 0x02 /* 1: enable watchdog MMIO */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MMIO region contains the watchog control register and the
|
||||||
|
* hardware timer counter.
|
||||||
|
*/
|
||||||
|
#define VIA_WDT_MMIO_LEN 8 /* MMIO region length in bytes */
|
||||||
|
#define VIA_WDT_CTL 0 /* MMIO addr+0: state/control reg. */
|
||||||
|
#define VIA_WDT_COUNT 4 /* MMIO addr+4: timer counter reg. */
|
||||||
|
|
||||||
|
/* Bits for the VIA_WDT_CTL register */
|
||||||
|
#define VIA_WDT_RUNNING 0x01 /* 0: stop, 1: running */
|
||||||
|
#define VIA_WDT_FIRED 0x02 /* 1: restarted by expired watchdog */
|
||||||
|
#define VIA_WDT_PWROFF 0x04 /* 0: reset, 1: poweroff */
|
||||||
|
#define VIA_WDT_DISABLED 0x08 /* 1: timer is disabled */
|
||||||
|
#define VIA_WDT_TRIGGER 0x80 /* 1: start a new countdown */
|
||||||
|
|
||||||
|
/* Hardware heartbeat in seconds */
|
||||||
|
#define WDT_HW_HEARTBEAT 1
|
||||||
|
|
||||||
|
/* Timer heartbeat (500ms) */
|
||||||
|
#define WDT_HEARTBEAT (HZ/2) /* should be <= ((WDT_HW_HEARTBEAT*HZ)/2) */
|
||||||
|
|
||||||
|
/* User space timeout in seconds */
|
||||||
|
#define WDT_TIMEOUT_MAX 1023 /* approx. 17 min. */
|
||||||
|
#define WDT_TIMEOUT 60
|
||||||
|
static int timeout = WDT_TIMEOUT;
|
||||||
|
module_param(timeout, int, 0);
|
||||||
|
MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, between 1 and 1023 "
|
||||||
|
"(default = " __MODULE_STRING(WDT_TIMEOUT) ")");
|
||||||
|
|
||||||
|
static int nowayout = WATCHDOG_NOWAYOUT;
|
||||||
|
module_param(nowayout, int, 0);
|
||||||
|
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
|
||||||
|
"(default = " __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
||||||
|
|
||||||
|
static struct watchdog_device wdt_dev;
|
||||||
|
static struct resource wdt_res;
|
||||||
|
static void __iomem *wdt_mem;
|
||||||
|
static unsigned int mmio;
|
||||||
|
static void wdt_timer_tick(unsigned long data);
|
||||||
|
static DEFINE_TIMER(timer, wdt_timer_tick, 0, 0);
|
||||||
|
/* The timer that pings the watchdog */
|
||||||
|
static unsigned long next_heartbeat; /* the next_heartbeat for the timer */
|
||||||
|
|
||||||
|
static inline void wdt_reset(void)
|
||||||
|
{
|
||||||
|
unsigned int ctl = readl(wdt_mem);
|
||||||
|
|
||||||
|
writel(ctl | VIA_WDT_TRIGGER, wdt_mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timer tick: the timer will make sure that the watchdog timer hardware
|
||||||
|
* is being reset in time. The conditions to do this are:
|
||||||
|
* 1) the watchog timer has been started and /dev/watchdog is open
|
||||||
|
* and there is still time left before userspace should send the
|
||||||
|
* next heartbeat/ping. (note: the internal heartbeat is much smaller
|
||||||
|
* then the external/userspace heartbeat).
|
||||||
|
* 2) the watchdog timer has been stopped by userspace.
|
||||||
|
*/
|
||||||
|
static void wdt_timer_tick(unsigned long data)
|
||||||
|
{
|
||||||
|
if (time_before(jiffies, next_heartbeat) ||
|
||||||
|
(!test_bit(WDOG_ACTIVE, &wdt_dev.status))) {
|
||||||
|
wdt_reset();
|
||||||
|
mod_timer(&timer, jiffies + WDT_HEARTBEAT);
|
||||||
|
} else
|
||||||
|
pr_crit("I will reboot your machine !\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wdt_ping(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
/* calculate when the next userspace timeout will be */
|
||||||
|
next_heartbeat = jiffies + timeout * HZ;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wdt_start(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
unsigned int ctl = readl(wdt_mem);
|
||||||
|
|
||||||
|
writel(timeout, wdt_mem + VIA_WDT_COUNT);
|
||||||
|
writel(ctl | VIA_WDT_RUNNING | VIA_WDT_TRIGGER, wdt_mem);
|
||||||
|
wdt_ping(wdd);
|
||||||
|
mod_timer(&timer, jiffies + WDT_HEARTBEAT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wdt_stop(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
unsigned int ctl = readl(wdt_mem);
|
||||||
|
|
||||||
|
writel(ctl & ~VIA_WDT_RUNNING, wdt_mem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wdt_set_timeout(struct watchdog_device *wdd,
|
||||||
|
unsigned int new_timeout)
|
||||||
|
{
|
||||||
|
if (new_timeout < 1 || new_timeout > WDT_TIMEOUT_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
writel(new_timeout, wdt_mem + VIA_WDT_COUNT);
|
||||||
|
timeout = new_timeout;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct watchdog_info wdt_info = {
|
||||||
|
.identity = "VIA watchdog",
|
||||||
|
.options = WDIOF_CARDRESET |
|
||||||
|
WDIOF_SETTIMEOUT |
|
||||||
|
WDIOF_MAGICCLOSE |
|
||||||
|
WDIOF_KEEPALIVEPING,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct watchdog_ops wdt_ops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.start = wdt_start,
|
||||||
|
.stop = wdt_stop,
|
||||||
|
.ping = wdt_ping,
|
||||||
|
.set_timeout = wdt_set_timeout,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct watchdog_device wdt_dev = {
|
||||||
|
.info = &wdt_info,
|
||||||
|
.ops = &wdt_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __devinit wdt_probe(struct pci_dev *pdev,
|
||||||
|
const struct pci_device_id *ent)
|
||||||
|
{
|
||||||
|
unsigned char conf;
|
||||||
|
int ret = -ENODEV;
|
||||||
|
|
||||||
|
if (pci_enable_device(pdev)) {
|
||||||
|
dev_err(&pdev->dev, "cannot enable PCI device\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a MMIO region which contains watchdog control register
|
||||||
|
* and counter, then configure the watchdog to use this region.
|
||||||
|
* This is possible only if PnP is properly enabled in BIOS.
|
||||||
|
* If not, the watchdog must be configured in BIOS manually.
|
||||||
|
*/
|
||||||
|
if (allocate_resource(&iomem_resource, &wdt_res, VIA_WDT_MMIO_LEN,
|
||||||
|
0xf0000000, 0xffffff00, 0xff, NULL, NULL)) {
|
||||||
|
dev_err(&pdev->dev, "MMIO allocation failed\n");
|
||||||
|
goto err_out_disable_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_write_config_dword(pdev, VIA_WDT_MMIO_BASE, wdt_res.start);
|
||||||
|
pci_read_config_byte(pdev, VIA_WDT_CONF, &conf);
|
||||||
|
conf |= VIA_WDT_CONF_ENABLE | VIA_WDT_CONF_MMIO;
|
||||||
|
pci_write_config_byte(pdev, VIA_WDT_CONF, conf);
|
||||||
|
|
||||||
|
pci_read_config_dword(pdev, VIA_WDT_MMIO_BASE, &mmio);
|
||||||
|
if (mmio) {
|
||||||
|
dev_info(&pdev->dev, "VIA Chipset watchdog MMIO: %x\n", mmio);
|
||||||
|
} else {
|
||||||
|
dev_err(&pdev->dev, "MMIO setting failed. Check BIOS.\n");
|
||||||
|
goto err_out_resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request_mem_region(mmio, VIA_WDT_MMIO_LEN, "via_wdt")) {
|
||||||
|
dev_err(&pdev->dev, "MMIO region busy\n");
|
||||||
|
goto err_out_resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
wdt_mem = ioremap(mmio, VIA_WDT_MMIO_LEN);
|
||||||
|
if (wdt_mem == NULL) {
|
||||||
|
dev_err(&pdev->dev, "cannot remap VIA wdt MMIO registers\n");
|
||||||
|
goto err_out_release;
|
||||||
|
}
|
||||||
|
|
||||||
|
wdt_dev.timeout = timeout;
|
||||||
|
watchdog_set_nowayout(&wdt_dev, nowayout);
|
||||||
|
if (readl(wdt_mem) & VIA_WDT_FIRED)
|
||||||
|
wdt_dev.bootstatus |= WDIOF_CARDRESET;
|
||||||
|
|
||||||
|
ret = watchdog_register_device(&wdt_dev);
|
||||||
|
if (ret)
|
||||||
|
goto err_out_iounmap;
|
||||||
|
|
||||||
|
/* start triggering, in case of watchdog already enabled by BIOS */
|
||||||
|
mod_timer(&timer, jiffies + WDT_HEARTBEAT);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_out_iounmap:
|
||||||
|
iounmap(wdt_mem);
|
||||||
|
err_out_release:
|
||||||
|
release_mem_region(mmio, VIA_WDT_MMIO_LEN);
|
||||||
|
err_out_resource:
|
||||||
|
release_resource(&wdt_res);
|
||||||
|
err_out_disable_device:
|
||||||
|
pci_disable_device(pdev);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __devexit wdt_remove(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
watchdog_unregister_device(&wdt_dev);
|
||||||
|
del_timer(&timer);
|
||||||
|
iounmap(wdt_mem);
|
||||||
|
release_mem_region(mmio, VIA_WDT_MMIO_LEN);
|
||||||
|
release_resource(&wdt_res);
|
||||||
|
pci_disable_device(pdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_PCI_DEVICE_TABLE(wdt_pci_table) = {
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700) },
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800) },
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct pci_driver wdt_driver = {
|
||||||
|
.name = "via_wdt",
|
||||||
|
.id_table = wdt_pci_table,
|
||||||
|
.probe = wdt_probe,
|
||||||
|
.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_AUTHOR("Marc Vertes");
|
||||||
|
MODULE_DESCRIPTION("Driver for watchdog timer on VIA chipset");
|
||||||
|
MODULE_LICENSE("GPL");
|
|
@ -199,7 +199,8 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
|
||||||
if (reg & WM831X_WDOG_DEBUG)
|
if (reg & WM831X_WDOG_DEBUG)
|
||||||
dev_warn(wm831x->dev, "Watchdog is paused\n");
|
dev_warn(wm831x->dev, "Watchdog is paused\n");
|
||||||
|
|
||||||
driver_data = kzalloc(sizeof(*driver_data), GFP_KERNEL);
|
driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data),
|
||||||
|
GFP_KERNEL);
|
||||||
if (!driver_data) {
|
if (!driver_data) {
|
||||||
dev_err(wm831x->dev, "Unable to alloacate watchdog device\n");
|
dev_err(wm831x->dev, "Unable to alloacate watchdog device\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
@ -213,11 +214,9 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
wm831x_wdt->info = &wm831x_wdt_info;
|
wm831x_wdt->info = &wm831x_wdt_info;
|
||||||
wm831x_wdt->ops = &wm831x_wdt_ops;
|
wm831x_wdt->ops = &wm831x_wdt_ops;
|
||||||
|
watchdog_set_nowayout(wm831x_wdt, nowayout);
|
||||||
watchdog_set_drvdata(wm831x_wdt, driver_data);
|
watchdog_set_drvdata(wm831x_wdt, driver_data);
|
||||||
|
|
||||||
if (nowayout)
|
|
||||||
wm831x_wdt->status |= WDOG_NO_WAY_OUT;
|
|
||||||
|
|
||||||
reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
|
reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
|
||||||
reg &= WM831X_WDOG_TO_MASK;
|
reg &= WM831X_WDOG_TO_MASK;
|
||||||
for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
|
for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
|
||||||
|
@ -252,7 +251,7 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
|
||||||
dev_err(wm831x->dev,
|
dev_err(wm831x->dev,
|
||||||
"Failed to request update GPIO: %d\n",
|
"Failed to request update GPIO: %d\n",
|
||||||
ret);
|
ret);
|
||||||
goto err_alloc;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = gpio_direction_output(pdata->update_gpio, 0);
|
ret = gpio_direction_output(pdata->update_gpio, 0);
|
||||||
|
@ -294,8 +293,6 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
|
||||||
err_gpio:
|
err_gpio:
|
||||||
if (driver_data->update_gpio)
|
if (driver_data->update_gpio)
|
||||||
gpio_free(driver_data->update_gpio);
|
gpio_free(driver_data->update_gpio);
|
||||||
err_alloc:
|
|
||||||
kfree(driver_data);
|
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -320,17 +317,7 @@ static struct platform_driver wm831x_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init wm831x_wdt_init(void)
|
module_platform_driver(wm831x_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&wm831x_wdt_driver);
|
|
||||||
}
|
|
||||||
module_init(wm831x_wdt_init);
|
|
||||||
|
|
||||||
static void __exit wm831x_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&wm831x_wdt_driver);
|
|
||||||
}
|
|
||||||
module_exit(wm831x_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Mark Brown");
|
MODULE_AUTHOR("Mark Brown");
|
||||||
MODULE_DESCRIPTION("WM831x Watchdog");
|
MODULE_DESCRIPTION("WM831x Watchdog");
|
||||||
|
|
|
@ -311,17 +311,7 @@ static struct platform_driver wm8350_wdt_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init wm8350_wdt_init(void)
|
module_platform_driver(wm8350_wdt_driver);
|
||||||
{
|
|
||||||
return platform_driver_register(&wm8350_wdt_driver);
|
|
||||||
}
|
|
||||||
module_init(wm8350_wdt_init);
|
|
||||||
|
|
||||||
static void __exit wm8350_wdt_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&wm8350_wdt_driver);
|
|
||||||
}
|
|
||||||
module_exit(wm8350_wdt_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Mark Brown");
|
MODULE_AUTHOR("Mark Brown");
|
||||||
MODULE_DESCRIPTION("WM8350 Watchdog");
|
MODULE_DESCRIPTION("WM8350 Watchdog");
|
||||||
|
|
|
@ -53,11 +53,7 @@ struct watchdog_info {
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#ifdef CONFIG_WATCHDOG_NOWAYOUT
|
#include <linux/bitops.h>
|
||||||
#define WATCHDOG_NOWAYOUT 1
|
|
||||||
#else
|
|
||||||
#define WATCHDOG_NOWAYOUT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct watchdog_ops;
|
struct watchdog_ops;
|
||||||
struct watchdog_device;
|
struct watchdog_device;
|
||||||
|
@ -122,6 +118,21 @@ struct watchdog_device {
|
||||||
#define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */
|
#define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_WATCHDOG_NOWAYOUT
|
||||||
|
#define WATCHDOG_NOWAYOUT 1
|
||||||
|
#define WATCHDOG_NOWAYOUT_INIT_STATUS (1 << WDOG_NO_WAY_OUT)
|
||||||
|
#else
|
||||||
|
#define WATCHDOG_NOWAYOUT 0
|
||||||
|
#define WATCHDOG_NOWAYOUT_INIT_STATUS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Use the following function to set the nowayout feature */
|
||||||
|
static inline void watchdog_set_nowayout(struct watchdog_device *wdd, int nowayout)
|
||||||
|
{
|
||||||
|
if (nowayout)
|
||||||
|
set_bit(WDOG_NO_WAY_OUT, &wdd->status);
|
||||||
|
}
|
||||||
|
|
||||||
/* Use the following functions to manipulate watchdog driver specific data */
|
/* Use the following functions to manipulate watchdog driver specific data */
|
||||||
static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data)
|
static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue