提交 67d2c36e 编写于 作者: L Linus Torvalds

Merge watchdog driver updates

Automated merge from

	master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog

failed due to duplicate different changes to Kconfig file. Manually fixed
up. Hopefully.
...@@ -2,43 +2,68 @@ ...@@ -2,43 +2,68 @@
# Makefile for the WatchDog device drivers. # Makefile for the WatchDog device drivers.
# #
# Only one watchdog can succeed. We probe the ISA/PCI/USB based
# watchdog-cards first, then the architecture specific watchdog
# drivers and then the architecture independant "softdog" driver.
# This means that if your ISA/PCI/USB card isn't detected that
# you can fall back to an architecture specific driver and if
# that also fails then you can fall back to the software watchdog
# to give you some cover.
# ISA-based Watchdog Cards
obj-$(CONFIG_PCWATCHDOG) += pcwd.o obj-$(CONFIG_PCWATCHDOG) += pcwd.o
obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
obj-$(CONFIG_IB700_WDT) += ib700wdt.o
obj-$(CONFIG_MIXCOMWD) += mixcomwd.o obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
obj-$(CONFIG_WDT) += wdt.o obj-$(CONFIG_WDT) += wdt.o
# PCI-based Watchdog Cards
obj-$(CONFIG_PCIPCWATCHDOG) += pcwd_pci.o
obj-$(CONFIG_WDTPCI) += wdt_pci.o obj-$(CONFIG_WDTPCI) += wdt_pci.o
# USB-based Watchdog Cards
obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
# ARM Architecture
obj-$(CONFIG_21285_WATCHDOG) += wdt285.o obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
obj-$(CONFIG_977_WATCHDOG) += wdt977.o obj-$(CONFIG_977_WATCHDOG) += wdt977.o
obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
obj-$(CONFIG_MACHZ_WDT) += machzwd.o obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
obj-$(CONFIG_SH_WDT) += shwdt.o
obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o # X86 (i386 + ia64 + x86_64) Architecture
obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
obj-$(CONFIG_SC520_WDT) += sc520_wdt.o obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
obj-$(CONFIG_IB700_WDT) += ib700wdt.o
obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o
obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
obj-$(CONFIG_INDYDOG) += indydog.o obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
obj-$(CONFIG_PCIPCWATCHDOG) += pcwd_pci.o obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o obj-$(CONFIG_MACHZ_WDT) += machzwd.o
obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o # PowerPC Architecture
obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
# PPC64 Architecture
obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
# Only one watchdog can succeed. We probe the hardware watchdog # MIPS Architecture
# drivers first, then the softdog driver. This means if your hardware obj-$(CONFIG_INDYDOG) += indydog.o
# watchdog dies or is 'borrowed' for some reason the software watchdog
# still gives you some cover. # S390 Architecture
# SUPERH Architecture
obj-$(CONFIG_SH_WDT) += shwdt.o
# SPARC64 Architecture
# Architecture Independant
obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
...@@ -182,7 +182,7 @@ static struct file_operations ixp2000_wdt_fops = ...@@ -182,7 +182,7 @@ static struct file_operations ixp2000_wdt_fops =
static struct miscdevice ixp2000_wdt_miscdev = static struct miscdevice ixp2000_wdt_miscdev =
{ {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "IXP2000 Watchdog", .name = "watchdog",
.fops = &ixp2000_wdt_fops, .fops = &ixp2000_wdt_fops,
}; };
......
...@@ -176,7 +176,7 @@ static struct file_operations ixp4xx_wdt_fops = ...@@ -176,7 +176,7 @@ static struct file_operations ixp4xx_wdt_fops =
static struct miscdevice ixp4xx_wdt_miscdev = static struct miscdevice ixp4xx_wdt_miscdev =
{ {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "IXP4xx Watchdog", .name = "watchdog",
.fops = &ixp4xx_wdt_fops, .fops = &ixp4xx_wdt_fops,
}; };
......
...@@ -27,7 +27,10 @@ ...@@ -27,7 +27,10 @@
* Fixed tmr_count / wdt_count confusion * Fixed tmr_count / wdt_count confusion
* Added configurable debug * Added configurable debug
* *
* 11-Jan-2004 BJD Fixed divide-by-2 in timeout code * 11-Jan-2005 BJD Fixed divide-by-2 in timeout code
*
* 25-Jan-2005 DA Added suspend/resume support
* Replaced reboot notifier with .shutdown method
* *
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/ */
...@@ -40,8 +43,6 @@ ...@@ -40,8 +43,6 @@
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -317,20 +318,6 @@ static int s3c2410wdt_ioctl(struct inode *inode, struct file *file, ...@@ -317,20 +318,6 @@ static int s3c2410wdt_ioctl(struct inode *inode, struct file *file,
} }
} }
/*
* Notifier for system down
*/
static int s3c2410wdt_notify_sys(struct notifier_block *this, unsigned long code,
void *unused)
{
if(code==SYS_DOWN || code==SYS_HALT) {
/* Turn the WDT off */
s3c2410wdt_stop();
}
return NOTIFY_DONE;
}
/* kernel interface */ /* kernel interface */
static struct file_operations s3c2410wdt_fops = { static struct file_operations s3c2410wdt_fops = {
...@@ -348,10 +335,6 @@ static struct miscdevice s3c2410wdt_miscdev = { ...@@ -348,10 +335,6 @@ static struct miscdevice s3c2410wdt_miscdev = {
.fops = &s3c2410wdt_fops, .fops = &s3c2410wdt_fops,
}; };
static struct notifier_block s3c2410wdt_notifier = {
.notifier_call = s3c2410wdt_notify_sys,
};
/* interrupt handler code */ /* interrupt handler code */
static irqreturn_t s3c2410wdt_irq(int irqno, void *param, static irqreturn_t s3c2410wdt_irq(int irqno, void *param,
...@@ -432,18 +415,10 @@ static int s3c2410wdt_probe(struct device *dev) ...@@ -432,18 +415,10 @@ static int s3c2410wdt_probe(struct device *dev)
} }
} }
ret = register_reboot_notifier(&s3c2410wdt_notifier);
if (ret) {
printk (KERN_ERR PFX "cannot register reboot notifier (%d)\n",
ret);
return ret;
}
ret = misc_register(&s3c2410wdt_miscdev); ret = misc_register(&s3c2410wdt_miscdev);
if (ret) { if (ret) {
printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n", printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n",
WATCHDOG_MINOR, ret); WATCHDOG_MINOR, ret);
unregister_reboot_notifier(&s3c2410wdt_notifier);
return ret; return ret;
} }
...@@ -479,15 +454,63 @@ static int s3c2410wdt_remove(struct device *dev) ...@@ -479,15 +454,63 @@ static int s3c2410wdt_remove(struct device *dev)
return 0; return 0;
} }
static void s3c2410wdt_shutdown(struct device *dev)
{
s3c2410wdt_stop();
}
#ifdef CONFIG_PM
static unsigned long wtcon_save;
static unsigned long wtdat_save;
static int s3c2410wdt_suspend(struct device *dev, u32 state, u32 level)
{
if (level == SUSPEND_POWER_DOWN) {
/* Save watchdog state, and turn it off. */
wtcon_save = readl(wdt_base + S3C2410_WTCON);
wtdat_save = readl(wdt_base + S3C2410_WTDAT);
/* Note that WTCNT doesn't need to be saved. */
s3c2410wdt_stop();
}
return 0;
}
static int s3c2410wdt_resume(struct device *dev, u32 level)
{
if (level == RESUME_POWER_ON) {
/* Restore watchdog state. */
writel(wtdat_save, wdt_base + S3C2410_WTDAT);
writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */
writel(wtcon_save, wdt_base + S3C2410_WTCON);
printk(KERN_INFO PFX "watchdog %sabled\n",
(wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
}
return 0;
}
#else
#define s3c2410wdt_suspend NULL
#define s3c2410wdt_resume NULL
#endif /* CONFIG_PM */
static struct device_driver s3c2410wdt_driver = { static struct device_driver s3c2410wdt_driver = {
.name = "s3c2410-wdt", .name = "s3c2410-wdt",
.bus = &platform_bus_type, .bus = &platform_bus_type,
.probe = s3c2410wdt_probe, .probe = s3c2410wdt_probe,
.remove = s3c2410wdt_remove, .remove = s3c2410wdt_remove,
.shutdown = s3c2410wdt_shutdown,
.suspend = s3c2410wdt_suspend,
.resume = s3c2410wdt_resume,
}; };
static char banner[] __initdata = KERN_INFO "S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics\n"; static char banner[] __initdata = KERN_INFO "S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics\n";
static int __init watchdog_init(void) static int __init watchdog_init(void)
...@@ -499,13 +522,13 @@ static int __init watchdog_init(void) ...@@ -499,13 +522,13 @@ static int __init watchdog_init(void)
static void __exit watchdog_exit(void) static void __exit watchdog_exit(void)
{ {
driver_unregister(&s3c2410wdt_driver); driver_unregister(&s3c2410wdt_driver);
unregister_reboot_notifier(&s3c2410wdt_notifier);
} }
module_init(watchdog_init); module_init(watchdog_init);
module_exit(watchdog_exit); module_exit(watchdog_exit);
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, "
"Dimitry Andric <dimitry.andric@tomtom.com>");
MODULE_DESCRIPTION("S3C2410 Watchdog Device Driver"); MODULE_DESCRIPTION("S3C2410 Watchdog Device Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
...@@ -206,7 +206,7 @@ static struct file_operations scx200_wdt_fops = { ...@@ -206,7 +206,7 @@ static struct file_operations scx200_wdt_fops = {
static struct miscdevice scx200_wdt_miscdev = { static struct miscdevice scx200_wdt_miscdev = {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = NAME, .name = "watchdog",
.fops = &scx200_wdt_fops, .fops = &scx200_wdt_fops,
}; };
......
...@@ -77,7 +77,7 @@ static void watchdog_fire(unsigned long); ...@@ -77,7 +77,7 @@ static void watchdog_fire(unsigned long);
static struct timer_list watchdog_ticktock = static struct timer_list watchdog_ticktock =
TIMER_INITIALIZER(watchdog_fire, 0, 0); TIMER_INITIALIZER(watchdog_fire, 0, 0);
static unsigned long timer_alive; static unsigned long driver_open, orphan_timer;
static char expect_close; static char expect_close;
...@@ -87,6 +87,9 @@ static char expect_close; ...@@ -87,6 +87,9 @@ static char expect_close;
static void watchdog_fire(unsigned long data) static void watchdog_fire(unsigned long data)
{ {
if (test_and_clear_bit(0, &orphan_timer))
module_put(THIS_MODULE);
if (soft_noboot) if (soft_noboot)
printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n"); printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n");
else else
...@@ -128,9 +131,9 @@ static int softdog_set_heartbeat(int t) ...@@ -128,9 +131,9 @@ static int softdog_set_heartbeat(int t)
static int softdog_open(struct inode *inode, struct file *file) static int softdog_open(struct inode *inode, struct file *file)
{ {
if(test_and_set_bit(0, &timer_alive)) if (test_and_set_bit(0, &driver_open))
return -EBUSY; return -EBUSY;
if (nowayout) if (!test_and_clear_bit(0, &orphan_timer))
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
/* /*
* Activate timer * Activate timer
...@@ -147,11 +150,13 @@ static int softdog_release(struct inode *inode, struct file *file) ...@@ -147,11 +150,13 @@ static int softdog_release(struct inode *inode, struct file *file)
*/ */
if (expect_close == 42) { if (expect_close == 42) {
softdog_stop(); softdog_stop();
module_put(THIS_MODULE);
} else { } else {
printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
set_bit(0, &orphan_timer);
softdog_keepalive(); softdog_keepalive();
} }
clear_bit(0, &timer_alive); clear_bit(0, &driver_open);
expect_close = 0; expect_close = 0;
return 0; return 0;
} }
......
...@@ -93,6 +93,12 @@ w83627hf_init(void) ...@@ -93,6 +93,12 @@ w83627hf_init(void)
w83627hf_select_wd_register(); w83627hf_select_wd_register();
outb_p(0xF6, WDT_EFER); /* Select CRF6 */
t=inb_p(WDT_EFDR); /* read CRF6 */
if (t != 0) {
printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout);
outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */
}
outb_p(0xF5, WDT_EFER); /* Select CRF5 */ outb_p(0xF5, WDT_EFER); /* Select CRF5 */
t=inb_p(WDT_EFDR); /* read CRF5 */ t=inb_p(WDT_EFDR); /* read CRF5 */
t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册