diff options
Diffstat (limited to 'drivers/watchdog')
44 files changed, 367 insertions, 699 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 6285867a935..877b107f77a 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -314,13 +314,6 @@ config NUC900_WATCHDOG To compile this driver as a module, choose M here: the module will be called nuc900_wdt. -config ADX_WATCHDOG - tristate "Avionic Design Xanthos watchdog" - depends on ARCH_PXA_ADX - help - Say Y here if you want support for the watchdog timer on Avionic - Design Xanthos boards. - config TS72XX_WATCHDOG tristate "TS-72XX SBC Watchdog" depends on MACH_TS72XX @@ -779,6 +772,19 @@ config SMSC37B787_WDT 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 tristate "W83627HF/W83627DHG Watchdog Timer" depends on X86 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 55bd5740e91..e8f479a1640 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -51,7 +51,6 @@ obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o -obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o @@ -100,6 +99,7 @@ obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o obj-$(CONFIG_SMSC_SCH311X_WDT) += sch311x_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_W83697HF_WDT) += w83697hf_wdt.o obj-$(CONFIG_W83697UG_WDT) += w83697ug_wdt.o diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c deleted file mode 100644 index af6e6b16475..00000000000 --- a/drivers/watchdog/adx_wdt.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2008-2009 Avionic Design GmbH - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/fs.h> -#include <linux/gfp.h> -#include <linux/io.h> -#include <linux/miscdevice.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/uaccess.h> -#include <linux/watchdog.h> - -#define WATCHDOG_NAME "adx-wdt" - -/* register offsets */ -#define ADX_WDT_CONTROL 0x00 -#define ADX_WDT_CONTROL_ENABLE (1 << 0) -#define ADX_WDT_CONTROL_nRESET (1 << 1) -#define ADX_WDT_TIMEOUT 0x08 - -static struct platform_device *adx_wdt_dev; -static unsigned long driver_open; - -#define WDT_STATE_STOP 0 -#define WDT_STATE_START 1 - -struct adx_wdt { - void __iomem *base; - unsigned long timeout; - unsigned int state; - unsigned int wake; - spinlock_t lock; -}; - -static const struct watchdog_info adx_wdt_info = { - .identity = "Avionic Design Xanthos Watchdog", - .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, -}; - -static void adx_wdt_start_locked(struct adx_wdt *wdt) -{ - u32 ctrl; - - ctrl = readl(wdt->base + ADX_WDT_CONTROL); - ctrl |= ADX_WDT_CONTROL_ENABLE; - writel(ctrl, wdt->base + ADX_WDT_CONTROL); - wdt->state = WDT_STATE_START; -} - -static void adx_wdt_start(struct adx_wdt *wdt) -{ - unsigned long flags; - - spin_lock_irqsave(&wdt->lock, flags); - adx_wdt_start_locked(wdt); - spin_unlock_irqrestore(&wdt->lock, flags); -} - -static void adx_wdt_stop_locked(struct adx_wdt *wdt) -{ - u32 ctrl; - - ctrl = readl(wdt->base + ADX_WDT_CONTROL); - ctrl &= ~ADX_WDT_CONTROL_ENABLE; - writel(ctrl, wdt->base + ADX_WDT_CONTROL); - wdt->state = WDT_STATE_STOP; -} - -static void adx_wdt_stop(struct adx_wdt *wdt) -{ - unsigned long flags; - - spin_lock_irqsave(&wdt->lock, flags); - adx_wdt_stop_locked(wdt); - spin_unlock_irqrestore(&wdt->lock, flags); -} - -static void adx_wdt_set_timeout(struct adx_wdt *wdt, unsigned long seconds) -{ - unsigned long timeout = seconds * 1000; - unsigned long flags; - unsigned int state; - - spin_lock_irqsave(&wdt->lock, flags); - state = wdt->state; - adx_wdt_stop_locked(wdt); - writel(timeout, wdt->base + ADX_WDT_TIMEOUT); - - if (state == WDT_STATE_START) - adx_wdt_start_locked(wdt); - - wdt->timeout = timeout; - spin_unlock_irqrestore(&wdt->lock, flags); -} - -static void adx_wdt_get_timeout(struct adx_wdt *wdt, unsigned long *seconds) -{ - *seconds = wdt->timeout / 1000; -} - -static void adx_wdt_keepalive(struct adx_wdt *wdt) -{ - unsigned long flags; - - spin_lock_irqsave(&wdt->lock, flags); - writel(wdt->timeout, wdt->base + ADX_WDT_TIMEOUT); - spin_unlock_irqrestore(&wdt->lock, flags); -} - -static int adx_wdt_open(struct inode *inode, struct file *file) -{ - struct adx_wdt *wdt = platform_get_drvdata(adx_wdt_dev); - - if (test_and_set_bit(0, &driver_open)) - return -EBUSY; - - file->private_data = wdt; - adx_wdt_set_timeout(wdt, 30); - adx_wdt_start(wdt); - - return nonseekable_open(inode, file); -} - -static int adx_wdt_release(struct inode *inode, struct file *file) -{ - struct adx_wdt *wdt = file->private_data; - - adx_wdt_stop(wdt); - clear_bit(0, &driver_open); - - return 0; -} - -static long adx_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct adx_wdt *wdt = file->private_data; - void __user *argp = (void __user *)arg; - unsigned long __user *p = argp; - unsigned long seconds = 0; - unsigned int options; - long ret = -EINVAL; - - switch (cmd) { - case WDIOC_GETSUPPORT: - if (copy_to_user(argp, &adx_wdt_info, sizeof(adx_wdt_info))) - return -EFAULT; - else - return 0; - - case WDIOC_GETSTATUS: - case WDIOC_GETBOOTSTATUS: - return put_user(0, p); - - case WDIOC_KEEPALIVE: - adx_wdt_keepalive(wdt); - return 0; - - case WDIOC_SETTIMEOUT: - if (get_user(seconds, p)) - return -EFAULT; - - adx_wdt_set_timeout(wdt, seconds); - - /* fallthrough */ - case WDIOC_GETTIMEOUT: - adx_wdt_get_timeout(wdt, &seconds); - return put_user(seconds, p); - - case WDIOC_SETOPTIONS: - if (copy_from_user(&options, argp, sizeof(options))) - return -EFAULT; - - if (options & WDIOS_DISABLECARD) { - adx_wdt_stop(wdt); - ret = 0; - } - - if (options & WDIOS_ENABLECARD) { - adx_wdt_start(wdt); - ret = 0; - } - - return ret; - - default: - break; - } - - return -ENOTTY; -} - -static ssize_t adx_wdt_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) -{ - struct adx_wdt *wdt = file->private_data; - - if (len) - adx_wdt_keepalive(wdt); - - return len; -} - -static const struct file_operations adx_wdt_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = adx_wdt_open, - .release = adx_wdt_release, - .unlocked_ioctl = adx_wdt_ioctl, - .write = adx_wdt_write, -}; - -static struct miscdevice adx_wdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &adx_wdt_fops, -}; - -static int __devinit adx_wdt_probe(struct platform_device *pdev) -{ - struct resource *res; - struct adx_wdt *wdt; - int ret = 0; - u32 ctrl; - - wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); - if (!wdt) { - dev_err(&pdev->dev, "cannot allocate WDT structure\n"); - return -ENOMEM; - } - - spin_lock_init(&wdt->lock); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "cannot obtain I/O memory region\n"); - return -ENXIO; - } - - res = devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), res->name); - if (!res) { - dev_err(&pdev->dev, "cannot request I/O memory region\n"); - return -ENXIO; - } - - wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, - resource_size(res)); - if (!wdt->base) { - dev_err(&pdev->dev, "cannot remap I/O memory region\n"); - return -ENXIO; - } - - /* disable watchdog and reboot on timeout */ - ctrl = readl(wdt->base + ADX_WDT_CONTROL); - ctrl &= ~ADX_WDT_CONTROL_ENABLE; - ctrl &= ~ADX_WDT_CONTROL_nRESET; - writel(ctrl, wdt->base + ADX_WDT_CONTROL); - - platform_set_drvdata(pdev, wdt); - adx_wdt_dev = pdev; - - ret = misc_register(&adx_wdt_miscdev); - if (ret) { - dev_err(&pdev->dev, "cannot register miscdev on minor %d " - "(err=%d)\n", WATCHDOG_MINOR, ret); - return ret; - } - - return 0; -} - -static int __devexit adx_wdt_remove(struct platform_device *pdev) -{ - struct adx_wdt *wdt = platform_get_drvdata(pdev); - - misc_deregister(&adx_wdt_miscdev); - adx_wdt_stop(wdt); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static void adx_wdt_shutdown(struct platform_device *pdev) -{ - struct adx_wdt *wdt = platform_get_drvdata(pdev); - adx_wdt_stop(wdt); -} - -#ifdef CONFIG_PM -static int adx_wdt_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct adx_wdt *wdt = platform_get_drvdata(pdev); - - wdt->wake = (wdt->state == WDT_STATE_START) ? 1 : 0; - adx_wdt_stop(wdt); - - return 0; -} - -static int adx_wdt_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct adx_wdt *wdt = platform_get_drvdata(pdev); - - if (wdt->wake) - adx_wdt_start(wdt); - - return 0; -} - -static const struct dev_pm_ops adx_wdt_pm_ops = { - .suspend = adx_wdt_suspend, - .resume = adx_wdt_resume, -}; - -# define ADX_WDT_PM_OPS (&adx_wdt_pm_ops) -#else -# define ADX_WDT_PM_OPS NULL -#endif - -static struct platform_driver adx_wdt_driver = { - .probe = adx_wdt_probe, - .remove = __devexit_p(adx_wdt_remove), - .shutdown = adx_wdt_shutdown, - .driver = { - .name = WATCHDOG_NAME, - .owner = THIS_MODULE, - .pm = ADX_WDT_PM_OPS, - }, -}; - -static int __init adx_wdt_init(void) -{ - return platform_driver_register(&adx_wdt_driver); -} - -static void __exit adx_wdt_exit(void) -{ - platform_driver_unregister(&adx_wdt_driver); -} - -module_init(adx_wdt_init); -module_exit(adx_wdt_exit); - -MODULE_DESCRIPTION("Avionic Design Xanthos Watchdog Driver"); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index b2922178359..502773ad5ac 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c @@ -70,8 +70,8 @@ struct ar7_wdt { }; static unsigned long wdt_is_open; -static spinlock_t wdt_lock; static unsigned expect_close; +static DEFINE_SPINLOCK(wdt_lock); /* XXX currently fixed, allows max margin ~68.72 secs */ #define prescale_value 0xffff @@ -280,8 +280,6 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev) { int rc; - spin_lock_init(&wdt_lock); - ar7_regs_wdt = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); if (!ar7_regs_wdt) { @@ -355,15 +353,4 @@ static struct platform_driver ar7_wdt_driver = { }, }; -static int __init ar7_wdt_init(void) -{ - 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); +module_platform_driver(ar7_wdt_driver); diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 87445b2d72a..00562566ef5 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -35,6 +35,11 @@ #define DRV_NAME "AT91SAM9 Watchdog" +#define wdt_read(field) \ + __raw_readl(at91wdt_private.base + field) +#define wdt_write(field, val) \ + __raw_writel((val), at91wdt_private.base + field) + /* AT91SAM9 watchdog runs a 12bit counter @ 256Hz, * use this to convert a watchdog * value from/to milliseconds. @@ -63,6 +68,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " static void at91_ping(unsigned long data); static struct { + void __iomem *base; unsigned long next_heartbeat; /* the next_heartbeat for the timer */ unsigned long open; char expect_close; @@ -77,7 +83,7 @@ static struct { */ static inline void at91_wdt_reset(void) { - at91_sys_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT); + wdt_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT); } /* @@ -132,7 +138,7 @@ static int at91_wdt_settimeout(unsigned int timeout) unsigned int mr; /* Check if disabled */ - mr = at91_sys_read(AT91_WDT_MR); + mr = wdt_read(AT91_WDT_MR); if (mr & AT91_WDT_WDDIS) { printk(KERN_ERR DRV_NAME": sorry, watchdog is disabled\n"); return -EIO; @@ -149,7 +155,7 @@ static int at91_wdt_settimeout(unsigned int timeout) | AT91_WDT_WDDBGHLT /* disabled in debug mode */ | AT91_WDT_WDD /* restart at any time */ | (timeout & AT91_WDT_WDV); /* timer value */ - at91_sys_write(AT91_WDT_MR, reg); + wdt_write(AT91_WDT_MR, reg); return 0; } @@ -248,12 +254,22 @@ static struct miscdevice at91wdt_miscdev = { static int __init at91wdt_probe(struct platform_device *pdev) { + struct resource *r; int res; if (at91wdt_miscdev.parent) return -EBUSY; at91wdt_miscdev.parent = &pdev->dev; + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + at91wdt_private.base = ioremap(r->start, resource_size(r)); + if (!at91wdt_private.base) { + dev_err(&pdev->dev, "failed to map registers, aborting.\n"); + return -ENOMEM; + } + /* Set watchdog */ res = at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000)); if (res) diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h index 757f9cab5c8..c6fbb2e6c41 100644 --- a/drivers/watchdog/at91sam9_wdt.h +++ b/drivers/watchdog/at91sam9_wdt.h @@ -16,11 +16,11 @@ #ifndef AT91_WDT_H #define AT91_WDT_H -#define AT91_WDT_CR (AT91_WDT + 0x00) /* Watchdog Control Register */ +#define AT91_WDT_CR 0x00 /* Watchdog Control Register */ #define AT91_WDT_WDRSTT (1 << 0) /* Restart */ #define AT91_WDT_KEY (0xa5 << 24) /* KEY Password */ -#define AT91_WDT_MR (AT91_WDT + 0x04) /* Watchdog Mode Register */ +#define AT91_WDT_MR 0x04 /* Watchdog Mode Register */ #define AT91_WDT_WDV (0xfff << 0) /* Counter Value */ #define AT91_WDT_WDFIEN (1 << 12) /* Fault Interrupt Enable */ #define AT91_WDT_WDRSTEN (1 << 13) /* Reset Processor */ @@ -30,7 +30,7 @@ #define AT91_WDT_WDDBGHLT (1 << 28) /* Debug Halt */ #define AT91_WDT_WDIDLEHLT (1 << 29) /* Idle Halt */ -#define AT91_WDT_SR (AT91_WDT + 0x08) /* Watchdog Status Register */ +#define AT91_WDT_SR 0x08 /* Watchdog Status Register */ #define AT91_WDT_WDUNF (1 << 0) /* Watchdog Underflow */ #define AT91_WDT_WDERR (1 << 1) /* Watchdog Error */ diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c index 725c84bfdd7..9db808349f8 100644 --- a/drivers/watchdog/ath79_wdt.c +++ b/drivers/watchdog/ath79_wdt.c @@ -68,17 +68,23 @@ static int max_timeout; static inline void ath79_wdt_keepalive(void) { 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) { ath79_wdt_keepalive(); 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) { 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) diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 5064e831752..8dc7de641e2 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -311,18 +311,7 @@ static struct platform_driver bcm63xx_wdt = { } }; -static int __init bcm63xx_wdt_init(void) -{ - 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_platform_driver(bcm63xx_wdt); MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c index 03f449a430d..5b89f7d6cd0 100644 --- a/drivers/watchdog/coh901327_wdt.c +++ b/drivers/watchdog/coh901327_wdt.c @@ -76,8 +76,6 @@ static int irq; static void __iomem *virtbase; static unsigned long coh901327_users; static unsigned long boot_status; -static u16 wdogenablestore; -static u16 irqmaskstore; static struct device *parent; /* @@ -461,6 +459,10 @@ out: } #ifdef CONFIG_PM + +static u16 wdogenablestore; +static u16 irqmaskstore; + static int coh901327_suspend(struct platform_device *pdev, pm_message_t state) { irqmaskstore = readw(virtbase + U300_WDOG_IMR) & 0x0001U; diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c index edd3475f41d..251c863d71d 100644 --- a/drivers/watchdog/cpu5wdt.c +++ b/drivers/watchdog/cpu5wdt.c @@ -39,7 +39,7 @@ static int verbose; static int port = 0x91; static int ticks = 10000; -static spinlock_t cpu5wdt_lock; +static DEFINE_SPINLOCK(cpu5wdt_lock); #define PFX "cpu5wdt: " @@ -223,7 +223,6 @@ static int __devinit cpu5wdt_init(void) "port=0x%x, verbose=%i\n", port, verbose); init_completion(&cpu5wdt_device.stop); - spin_lock_init(&cpu5wdt_lock); cpu5wdt_device.queue = 0; setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); cpu5wdt_device.default_ticks = ticks; diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 1e013e8457b..1b793dfd868 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -687,15 +687,4 @@ static struct platform_driver cpwd_driver = { .remove = __devexit_p(cpwd_remove), }; -static int __init cpwd_init(void) -{ - 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); +module_platform_driver(cpwd_driver); diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 51b5551b4e3..c8c5c8032bc 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c @@ -271,18 +271,7 @@ static struct platform_driver platform_wdt_driver = { .remove = __devexit_p(davinci_wdt_remove), }; -static int __init davinci_wdt_init(void) -{ - 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_platform_driver(platform_wdt_driver); MODULE_AUTHOR("Texas Instruments"); MODULE_DESCRIPTION("DaVinci Watchdog Driver"); diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index f10f8c0abba..1b0e3dd81c1 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -358,17 +358,7 @@ static struct platform_driver dw_wdt_driver = { }, }; -static int __init dw_wdt_watchdog_init(void) -{ - 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_platform_driver(dw_wdt_driver); MODULE_AUTHOR("Jamie Iles"); MODULE_DESCRIPTION("Synopsys DesignWare Watchdog Driver"); diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c index 41018d429ab..3946c51099c 100644 --- a/drivers/watchdog/eurotechwdt.c +++ b/drivers/watchdog/eurotechwdt.c @@ -64,7 +64,7 @@ static unsigned long eurwdt_is_open; static int eurwdt_timeout; 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. @@ -446,8 +446,6 @@ static int __init eurwdt_init(void) goto outreg; } - spin_lock_init(&eurwdt_lock); - ret = misc_register(&eurwdt_miscdev); if (ret) { printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 3774c9b8dac..8464ea1c36a 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -231,6 +231,7 @@ static int __devinit cru_detect(unsigned long map_entry, cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE; + set_memory_x((unsigned long)bios32_entrypoint, (2 * PAGE_SIZE)); asminline_call(&cmn_regs, bios32_entrypoint); if (cmn_regs.u1.ral != 0) { @@ -248,8 +249,10 @@ static int __devinit cru_detect(unsigned long map_entry, if ((physical_bios_base + physical_bios_offset)) { cru_rom_addr = ioremap(cru_physical_address, cru_length); - if (cru_rom_addr) + if (cru_rom_addr) { + set_memory_x((unsigned long)cru_rom_addr, cru_length); retval = 0; + } } printk(KERN_DEBUG "hpwdt: CRU Base Address: 0x%lx\n", diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index ba6ad662635..99796c5d913 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -384,10 +384,10 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -static int turn_SMI_watchdog_clear_off = 0; +static int turn_SMI_watchdog_clear_off = 1; module_param(turn_SMI_watchdog_clear_off, int, 0); MODULE_PARM_DESC(turn_SMI_watchdog_clear_off, - "Turn off SMI clearing watchdog (default=0)"); + "Turn off SMI clearing watchdog (depends on TCO-version)(default=1)"); /* * Some TCO specific functions @@ -813,7 +813,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, ret = -EIO; goto out_unmap; } - if (turn_SMI_watchdog_clear_off) { + if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) { /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ val32 = inl(SMI_EN); val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c index 195e0f798e7..c7481ad5162 100644 --- a/drivers/watchdog/ibmasr.c +++ b/drivers/watchdog/ibmasr.c @@ -68,7 +68,7 @@ static char asr_expect_close; static unsigned int asr_type, asr_base, asr_length; static unsigned int asr_read_addr, asr_write_addr; static unsigned char asr_toggle_mask, asr_disable_mask; -static spinlock_t asr_lock; +static DEFINE_SPINLOCK(asr_lock); static void __asr_toggle(void) { @@ -386,8 +386,6 @@ static int __init ibmasr_init(void) if (!asr_type) return -ENODEV; - spin_lock_init(&asr_lock); - rc = asr_get_base_address(); if (rc) return rc; diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c index 1cc5609666d..1475e09f9af 100644 --- a/drivers/watchdog/indydog.c +++ b/drivers/watchdog/indydog.c @@ -28,7 +28,7 @@ #define PFX "indydog: " static unsigned long indydog_alive; -static spinlock_t indydog_lock; +static DEFINE_SPINLOCK(indydog_lock); #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ @@ -185,8 +185,6 @@ static int __init watchdog_init(void) { int ret; - spin_lock_init(&indydog_lock); - ret = register_reboot_notifier(&indydog_notifier); if (ret) { printk(KERN_ERR PFX diff --git a/drivers/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c index aef94789019..82fa7a92a8d 100644 --- a/drivers/watchdog/iop_wdt.c +++ b/drivers/watchdog/iop_wdt.c @@ -37,7 +37,7 @@ static int nowayout = WATCHDOG_NOWAYOUT; static unsigned long wdt_status; static unsigned long boot_status; -static spinlock_t wdt_lock; +static DEFINE_SPINLOCK(wdt_lock); #define WDT_IN_USE 0 #define WDT_OK_TO_CLOSE 1 @@ -226,9 +226,6 @@ static int __init iop_wdt_init(void) { int ret; - spin_lock_init(&wdt_lock); - - /* check if the reset was caused by the watchdog timer */ boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c index e86952a7168..084f71aa855 100644 --- a/drivers/watchdog/ixp2000_wdt.c +++ b/drivers/watchdog/ixp2000_wdt.c @@ -32,7 +32,7 @@ static int nowayout = WATCHDOG_NOWAYOUT; static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ static unsigned long wdt_status; -static spinlock_t wdt_lock; +static DEFINE_SPINLOCK(wdt_lock); #define WDT_IN_USE 0 #define WDT_OK_TO_CLOSE 1 @@ -189,7 +189,6 @@ static int __init ixp2000_wdt_init(void) return -EIO; } wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; - spin_lock_init(&wdt_lock); return misc_register(&ixp2000_wdt_miscdev); } diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c index e02c0ecda26..4fc2e9ac26f 100644 --- a/drivers/watchdog/ixp4xx_wdt.c +++ b/drivers/watchdog/ixp4xx_wdt.c @@ -181,7 +181,6 @@ static int __init ixp4xx_wdt_init(void) return -ENODEV; } - spin_lock_init(&wdt_lock); boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ? WDIOF_CARDRESET : 0; ret = misc_register(&ixp4xx_wdt_miscdev); diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c index 684ba01fb54..17ef300bccc 100644 --- a/drivers/watchdog/jz4740_wdt.c +++ b/drivers/watchdog/jz4740_wdt.c @@ -295,18 +295,7 @@ static struct 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_platform_driver(jz4740_wdt_driver); MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); MODULE_DESCRIPTION("jz4740 Watchdog Driver"); diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c index 811471903e8..51757a520e8 100644 --- a/drivers/watchdog/ks8695_wdt.c +++ b/drivers/watchdog/ks8695_wdt.c @@ -42,7 +42,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 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) { - spin_lock_init(&ks8695_lock); /* Check that the heartbeat value is within range; if not reset to the default */ if (ks8695_wdt_settimeout(wdt_time)) { diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c index 102aed0efbf..d3a63be2e28 100644 --- a/drivers/watchdog/lantiq_wdt.c +++ b/drivers/watchdog/lantiq_wdt.c @@ -222,9 +222,6 @@ ltq_wdt_remove(struct platform_device *pdev) { misc_deregister(<q_wdt_miscdev); - if (ltq_wdt_membase) - iounmap(ltq_wdt_membase); - return 0; } diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c index 73ba2fd8e59..af63ecfbfa6 100644 --- a/drivers/watchdog/max63xx_wdt.c +++ b/drivers/watchdog/max63xx_wdt.c @@ -364,18 +364,7 @@ static struct platform_driver max63xx_wdt_driver = { }, }; -static int __init max63xx_wdt_init(void) -{ - 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_platform_driver(max63xx_wdt_driver); MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>"); MODULE_DESCRIPTION("max63xx Watchdog Driver"); diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index ac37bb82392..c29e31d99fe 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -253,18 +253,7 @@ static struct platform_driver mtx1_wdt_driver = { .driver.owner = THIS_MODULE, }; -static int __init mtx1_wdt_init(void) -{ - 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_platform_driver(mtx1_wdt_driver); MODULE_AUTHOR("Michael Stickel, Florian Fainelli"); MODULE_DESCRIPTION("Driver for the MTX-1 watchdog"); diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c index 6cee33d4b16..50359bad917 100644 --- a/drivers/watchdog/nuc900_wdt.c +++ b/drivers/watchdog/nuc900_wdt.c @@ -334,18 +334,7 @@ static struct platform_driver nuc900wdt_driver = { }, }; -static int __init nuc900_wdt_init(void) -{ - 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_platform_driver(nuc900wdt_driver); MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); MODULE_DESCRIPTION("Watchdog driver for NUC900"); diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index 4ec741ac952..f359ab85c3b 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c @@ -414,18 +414,7 @@ static struct platform_driver xwdt_driver = { }, }; -static int __init xwdt_init(void) -{ - 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_platform_driver(xwdt_driver); MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>"); MODULE_DESCRIPTION("Xilinx Watchdog driver"); diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 2b4acb86c19..4b33e3fd726 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -55,7 +55,7 @@ module_param(timer_margin, uint, 0); MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); static unsigned int wdt_trgr_pattern = 0x1234; -static spinlock_t wdt_lock; +static DEFINE_SPINLOCK(wdt_lock); struct omap_wdt_dev { void __iomem *base; /* physical */ @@ -232,6 +232,7 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd, if (cpu_is_omap24xx()) return put_user(omap_prcm_get_reset_sources(), (int __user *)arg); + return put_user(0, (int __user *)arg); case WDIOC_KEEPALIVE: pm_runtime_get_sync(wdev->dev); spin_lock(&wdt_lock); @@ -437,19 +438,7 @@ static struct platform_driver omap_wdt_driver = { }, }; -static int __init omap_wdt_init(void) -{ - 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_platform_driver(omap_wdt_driver); MODULE_AUTHOR("George G. Davis"); MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index 2d9fb96a9ee..4ad78f86851 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c @@ -41,7 +41,7 @@ static int heartbeat = -1; /* module parameter (seconds) */ static unsigned int wdt_max_duration; /* (seconds) */ static unsigned int wdt_tclk; static unsigned long wdt_status; -static spinlock_t wdt_lock; +static DEFINE_SPINLOCK(wdt_lock); static void orion_wdt_ping(void) { @@ -294,19 +294,7 @@ static struct platform_driver orion_wdt_driver = { }, }; -static int __init orion_wdt_init(void) -{ - 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_platform_driver(orion_wdt_driver); MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>"); MODULE_DESCRIPTION("Orion Processor Watchdog"); diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index 748a74bd85e..d8de1ddd176 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c @@ -827,37 +827,4 @@ static void usb_pcwd_disconnect(struct usb_interface *interface) printk(KERN_INFO PFX "USB PC Watchdog disconnected\n"); } - - -/** - * usb_pcwd_init - */ -static int __init usb_pcwd_init(void) -{ - int result; - - /* register this driver with the USB subsystem */ - result = usb_register(&usb_pcwd_driver); - if (result) { - printk(KERN_ERR PFX "usb_register failed. Error number %d\n", - result); - return result; - } - - printk(KERN_INFO PFX DRIVER_DESC " v" DRIVER_VERSION "\n"); - return 0; -} - - -/** - * usb_pcwd_exit - */ -static void __exit usb_pcwd_exit(void) -{ - /* deregister this driver with the USB subsystem */ - usb_deregister(&usb_pcwd_driver); -} - - -module_init(usb_pcwd_init); -module_exit(usb_pcwd_exit); +module_usb_driver(usb_pcwd_driver); diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 61493322556..bd143c9dd3e 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -334,18 +334,7 @@ static struct platform_driver platform_wdt_driver = { .remove = __devexit_p(pnx4008_wdt_remove), }; -static int __init pnx4008_wdt_init(void) -{ - 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_platform_driver(platform_wdt_driver); MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); MODULE_DESCRIPTION("PNX4008 Watchdog Driver"); diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index d4c29b5311a..bf7bc8aa1c0 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c @@ -332,18 +332,7 @@ static struct platform_driver rc32434_wdt_driver = { } }; -static int __init rc32434_wdt_init(void) -{ - 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_platform_driver(rc32434_wdt_driver); MODULE_AUTHOR("Ondrej Zajicek <santiago@crfreenet.org>," "Florian Fainelli <florian@openwrt.org>"); diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 428f8a1583e..042ccc56ae2 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -293,18 +293,7 @@ static struct platform_driver rdc321x_wdt_driver = { }, }; -static int __init rdc321x_wdt_init(void) -{ - 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_platform_driver(rdc321x_wdt_driver); MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); MODULE_DESCRIPTION("RDC321x watchdog driver"); diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index 109b533896b..c7e17ceafa6 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -247,15 +247,4 @@ static struct platform_driver riowd_driver = { .remove = __devexit_p(riowd_remove), }; -static int __init riowd_init(void) -{ - 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); +module_platform_driver(riowd_driver); diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 5de7e4fa5b8..4bc3744e14e 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -378,6 +378,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) "cannot start\n"); } + watchdog_set_nowayout(&s3c2410_wdd, nowayout); + ret = watchdog_register_device(&s3c2410_wdd); if (ret) { dev_err(dev, "cannot register watchdog (%d)\n", ret); @@ -401,8 +403,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n", (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in", - (wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis", - (wtcon & S3C2410_WTCON_INTEN) ? "" : "en"); + (wtcon & S3C2410_WTCON_RSTEN) ? "en" : "dis", + (wtcon & S3C2410_WTCON_INTEN) ? "en" : "dis"); return 0; diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index cc2cfbe33b3..eef1524ae52 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -351,7 +351,7 @@ static int __devexit sp805_wdt_remove(struct amba_device *adev) return 0; } -static struct amba_id sp805_wdt_ids[] __initdata = { +static struct amba_id sp805_wdt_ids[] = { { .id = 0x00141805, .mask = 0x00ffffff, @@ -359,6 +359,8 @@ static struct amba_id sp805_wdt_ids[] __initdata = { { 0, 0 }, }; +MODULE_DEVICE_TABLE(amba, sp805_wdt_ids); + static struct amba_driver sp805_wdt_driver = { .drv = { .name = MODULE_NAME, diff --git a/drivers/watchdog/stmp3xxx_wdt.c b/drivers/watchdog/stmp3xxx_wdt.c index ac2346a452e..4c2a4e8698f 100644 --- a/drivers/watchdog/stmp3xxx_wdt.c +++ b/drivers/watchdog/stmp3xxx_wdt.c @@ -272,18 +272,7 @@ static struct platform_driver platform_wdt_driver = { .resume = stmp3xxx_wdt_resume, }; -static int __init stmp3xxx_wdt_init(void) -{ - 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_platform_driver(platform_wdt_driver); MODULE_DESCRIPTION("STMP3XXX Watchdog Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c index 5a90a4a871d..1490293dc7d 100644 --- a/drivers/watchdog/ts72xx_wdt.c +++ b/drivers/watchdog/ts72xx_wdt.c @@ -506,17 +506,7 @@ static struct platform_driver ts72xx_wdt_driver = { }, }; -static __init int ts72xx_wdt_init(void) -{ - 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_platform_driver(ts72xx_wdt_driver); MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); MODULE_DESCRIPTION("TS-72xx SBC Watchdog"); diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c index b5045ca7e61..0764c6239b9 100644 --- a/drivers/watchdog/twl4030_wdt.c +++ b/drivers/watchdog/twl4030_wdt.c @@ -256,17 +256,7 @@ static struct platform_driver twl4030_wdt_driver = { }, }; -static int __devinit twl4030_wdt_init(void) -{ - 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_platform_driver(twl4030_wdt_driver); MODULE_AUTHOR("Nokia Corporation"); MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c new file mode 100644 index 00000000000..026b4bbfa0a --- /dev/null +++ b/drivers/watchdog/via_wdt.c @@ -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"); diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index dd5d6754875..576a388a116 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c @@ -4,7 +4,7 @@ * (c) Copyright 2007 Vlad Drukker <vlad@storewiz.com> * added support for W83627THF. * - * (c) Copyright 2003,2007 Pádraig Brady <P@draigBrady.com> + * (c) Copyright 2003,2007 Pádraig Brady <P@draigBrady.com> * * Based on advantechwdt.c which is based on wdt.c. * Original copyright messages: @@ -401,6 +401,6 @@ module_init(wdt_init); module_exit(wdt_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Pádraig Brady <P@draigBrady.com>"); +MODULE_AUTHOR("Pádraig Brady <P@draigBrady.com>"); MODULE_DESCRIPTION("w83627hf/thf WDT driver"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index 7be38556aed..263c883f080 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c @@ -150,7 +150,7 @@ static int wm831x_wdt_set_timeout(struct watchdog_device *wdt_dev, if (wm831x_wdt_cfgs[i].time == timeout) break; if (i == ARRAY_SIZE(wm831x_wdt_cfgs)) - ret = -EINVAL; + return -EINVAL; ret = wm831x_reg_unlock(wm831x); if (ret == 0) { @@ -199,7 +199,8 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev) if (reg & WM831X_WDOG_DEBUG) 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) { dev_err(wm831x->dev, "Unable to alloacate watchdog device\n"); ret = -ENOMEM; @@ -213,11 +214,9 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev) wm831x_wdt->info = &wm831x_wdt_info; wm831x_wdt->ops = &wm831x_wdt_ops; + watchdog_set_nowayout(wm831x_wdt, nowayout); 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_WDOG_TO_MASK; 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, "Failed to request update GPIO: %d\n", ret); - goto err_alloc; + goto err; } ret = gpio_direction_output(pdata->update_gpio, 0); @@ -294,8 +293,6 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev) err_gpio: if (driver_data->update_gpio) gpio_free(driver_data->update_gpio); -err_alloc: - kfree(driver_data); err: return ret; } @@ -320,17 +317,7 @@ static struct platform_driver wm831x_wdt_driver = { }, }; -static int __init wm831x_wdt_init(void) -{ - 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_platform_driver(wm831x_wdt_driver); MODULE_AUTHOR("Mark Brown"); MODULE_DESCRIPTION("WM831x Watchdog"); diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c index b68d928c8f9..909c78650d3 100644 --- a/drivers/watchdog/wm8350_wdt.c +++ b/drivers/watchdog/wm8350_wdt.c @@ -311,17 +311,7 @@ static struct platform_driver wm8350_wdt_driver = { }, }; -static int __init wm8350_wdt_init(void) -{ - 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_platform_driver(wm8350_wdt_driver); MODULE_AUTHOR("Mark Brown"); MODULE_DESCRIPTION("WM8350 Watchdog"); |