diff options
Diffstat (limited to 'drivers/watchdog')
59 files changed, 923 insertions, 637 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index ad1bb9382a96..7f809fd4a57f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -76,6 +76,16 @@ config DA9052_WATCHDOG Alternatively say M to compile the driver as a module, which will be called da9052_wdt. +config DA9055_WATCHDOG + tristate "Dialog Semiconductor DA9055 Watchdog" + depends on MFD_DA9055 + help + If you say yes here you get support for watchdog on the Dialog + Semiconductor DA9055 PMIC. + + This driver can also be built as a module. If so, the module + will be called da9055_wdt. + config WM831X_WATCHDOG tristate "WM831x watchdog" depends on MFD_WM831X @@ -232,6 +242,7 @@ config EP93XX_WATCHDOG config OMAP_WATCHDOG tristate "OMAP Watchdog" depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS + select WATCHDOG_CORE help Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog. Say 'Y' here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer. @@ -300,6 +311,7 @@ config COH901327_WATCHDOG config TWL4030_WATCHDOG tristate "TWL4030 Watchdog" depends on TWL4030_CORE + select WATCHDOG_CORE help Support for TI TWL4030 watchdog. Say 'Y' here to enable the watchdog timer support for TWL4030 chips. @@ -342,7 +354,7 @@ config MAX63XX_WATCHDOG config IMX2_WDT tristate "IMX2+ Watchdog" - depends on IMX_HAVE_PLATFORM_IMX2_WDT + depends on ARCH_MXC help This is the driver for the hardware watchdog on the Freescale IMX2 and later processors. @@ -431,7 +443,7 @@ config ALIM7101_WDT config F71808E_WDT tristate "Fintek F71808E, F71862FG, F71869, F71882FG and F71889FG Watchdog" - depends on X86 && EXPERIMENTAL + depends on X86 help This is the driver for the hardware watchdog on the Fintek F71808E, F71862FG, F71869, F71882FG and F71889FG Super I/O controllers. @@ -622,7 +634,7 @@ config IT8712F_WDT config IT87_WDT tristate "IT87 Watchdog Timer" - depends on X86 && EXPERIMENTAL + depends on X86 ---help--- This is the driver for the hardware watchdog on the ITE IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726 and IT8728 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 572b39bed06a..97bbdb3a4648 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -164,6 +164,7 @@ obj-$(CONFIG_XEN_WDT) += xen_wdt.o # Architecture Independent obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o +obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 4397881c83f4..24a517777fa0 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c @@ -240,7 +240,7 @@ static struct miscdevice acq_miscdev = { * Init & exit routines */ -static int __devinit acq_probe(struct platform_device *dev) +static int acq_probe(struct platform_device *dev) { int ret; @@ -275,7 +275,7 @@ out: return ret; } -static int __devexit acq_remove(struct platform_device *dev) +static int acq_remove(struct platform_device *dev) { misc_deregister(&acq_miscdev); release_region(wdt_start, 1); @@ -293,7 +293,7 @@ static void acq_shutdown(struct platform_device *dev) static struct platform_driver acquirewdt_driver = { .probe = acq_probe, - .remove = __devexit_p(acq_remove), + .remove = acq_remove, .shutdown = acq_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index 64ae9e9fed94..cc6702fc5268 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c @@ -238,7 +238,7 @@ static struct miscdevice advwdt_miscdev = { * Init & exit routines */ -static int __devinit advwdt_probe(struct platform_device *dev) +static int advwdt_probe(struct platform_device *dev) { int ret; @@ -282,7 +282,7 @@ unreg_stop: goto out; } -static int __devexit advwdt_remove(struct platform_device *dev) +static int advwdt_remove(struct platform_device *dev) { misc_deregister(&advwdt_miscdev); release_region(wdt_start, 1); @@ -300,7 +300,7 @@ static void advwdt_shutdown(struct platform_device *dev) static struct platform_driver advwdt_driver = { .probe = advwdt_probe, - .remove = __devexit_p(advwdt_remove), + .remove = advwdt_remove, .shutdown = advwdt_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index dc30dbd21cf1..3003e2a9580b 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c @@ -274,7 +274,7 @@ static struct miscdevice ar7_wdt_miscdev = { .fops = &ar7_wdt_fops, }; -static int __devinit ar7_wdt_probe(struct platform_device *pdev) +static int ar7_wdt_probe(struct platform_device *pdev) { int rc; @@ -314,7 +314,7 @@ out: return rc; } -static int __devexit ar7_wdt_remove(struct platform_device *pdev) +static int ar7_wdt_remove(struct platform_device *pdev) { misc_deregister(&ar7_wdt_miscdev); clk_put(vbus_clk); @@ -330,7 +330,7 @@ static void ar7_wdt_shutdown(struct platform_device *pdev) static struct platform_driver ar7_wdt_driver = { .probe = ar7_wdt_probe, - .remove = __devexit_p(ar7_wdt_remove), + .remove = ar7_wdt_remove, .shutdown = ar7_wdt_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index 7ef99a169e3b..89831ed24a4f 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c @@ -199,7 +199,7 @@ static struct miscdevice at91wdt_miscdev = { .fops = &at91wdt_fops, }; -static int __devinit at91wdt_probe(struct platform_device *pdev) +static int at91wdt_probe(struct platform_device *pdev) { int res; @@ -216,7 +216,7 @@ static int __devinit at91wdt_probe(struct platform_device *pdev) return 0; } -static int __devexit at91wdt_remove(struct platform_device *pdev) +static int at91wdt_remove(struct platform_device *pdev) { int res; @@ -254,7 +254,7 @@ static int at91wdt_resume(struct platform_device *pdev) static struct platform_driver at91wdt_driver = { .probe = at91wdt_probe, - .remove = __devexit_p(at91wdt_remove), + .remove = at91wdt_remove, .shutdown = at91wdt_shutdown, .suspend = at91wdt_suspend, .resume = at91wdt_resume, diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 05e1be85fdee..dc42e44b6bc1 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -32,6 +32,7 @@ #include <linux/timer.h> #include <linux/bitops.h> #include <linux/uaccess.h> +#include <linux/of.h> #include "at91sam9_wdt.h" @@ -302,11 +303,21 @@ static int __exit at91wdt_remove(struct platform_device *pdev) return res; } +#if defined(CONFIG_OF) +static const struct of_device_id at91_wdt_dt_ids[] __initconst = { + { .compatible = "atmel,at91sam9260-wdt" }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, at91_wdt_dt_ids); +#endif + static struct platform_driver at91wdt_driver = { .remove = __exit_p(at91wdt_remove), .driver = { .name = "at91_wdt", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(at91_wdt_dt_ids), }, }; diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c index 1f9371f49c40..38a999e60c0d 100644 --- a/drivers/watchdog/ath79_wdt.c +++ b/drivers/watchdog/ath79_wdt.c @@ -224,7 +224,7 @@ static struct miscdevice ath79_wdt_miscdev = { .fops = &ath79_wdt_fops, }; -static int __devinit ath79_wdt_probe(struct platform_device *pdev) +static int ath79_wdt_probe(struct platform_device *pdev) { u32 ctrl; int err; @@ -270,7 +270,7 @@ err_clk_put: return err; } -static int __devexit ath79_wdt_remove(struct platform_device *pdev) +static int ath79_wdt_remove(struct platform_device *pdev) { misc_deregister(&ath79_wdt_miscdev); clk_disable(wdt_clk); @@ -284,7 +284,8 @@ static void ath97_wdt_shutdown(struct platform_device *pdev) } static struct platform_driver ath79_wdt_driver = { - .remove = __devexit_p(ath79_wdt_remove), + .probe = ath79_wdt_probe, + .remove = ath79_wdt_remove, .shutdown = ath97_wdt_shutdown, .driver = { .name = DRIVER_NAME, @@ -292,17 +293,7 @@ static struct platform_driver ath79_wdt_driver = { }, }; -static int __init ath79_wdt_init(void) -{ - return platform_driver_probe(&ath79_wdt_driver, ath79_wdt_probe); -} -module_init(ath79_wdt_init); - -static void __exit ath79_wdt_exit(void) -{ - platform_driver_unregister(&ath79_wdt_driver); -} -module_exit(ath79_wdt_exit); +module_platform_driver(ath79_wdt_driver); MODULE_DESCRIPTION("Atheros AR71XX/AR724X/AR913X hardware watchdog driver"); MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org"); diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 551880bfd629..b2b80d4ac818 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -236,7 +236,7 @@ static struct miscdevice bcm63xx_wdt_miscdev = { }; -static int __devinit bcm63xx_wdt_probe(struct platform_device *pdev) +static int bcm63xx_wdt_probe(struct platform_device *pdev) { int ret; struct resource *r; @@ -286,7 +286,7 @@ unmap: return ret; } -static int __devexit bcm63xx_wdt_remove(struct platform_device *pdev) +static int bcm63xx_wdt_remove(struct platform_device *pdev) { if (!nowayout) bcm63xx_wdt_pause(); @@ -304,7 +304,7 @@ static void bcm63xx_wdt_shutdown(struct platform_device *pdev) static struct platform_driver bcm63xx_wdt_driver = { .probe = bcm63xx_wdt_probe, - .remove = __devexit_p(bcm63xx_wdt_remove), + .remove = bcm63xx_wdt_remove, .shutdown = bcm63xx_wdt_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index 38bc383e0677..5d36d6fb4969 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c @@ -356,7 +356,7 @@ static const struct watchdog_info bfin_wdt_info = { * Registers the misc device. Actual device * initialization is handled by bfin_wdt_open(). */ -static int __devinit bfin_wdt_probe(struct platform_device *pdev) +static int bfin_wdt_probe(struct platform_device *pdev) { int ret; @@ -379,7 +379,7 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev) * Unregisters the misc device. Actual device * deinitialization is handled by bfin_wdt_close(). */ -static int __devexit bfin_wdt_remove(struct platform_device *pdev) +static int bfin_wdt_remove(struct platform_device *pdev) { misc_deregister(&bfin_wdt_miscdev); return 0; @@ -401,7 +401,7 @@ static struct platform_device *bfin_wdt_device; static struct platform_driver bfin_wdt_driver = { .probe = bfin_wdt_probe, - .remove = __devexit_p(bfin_wdt_remove), + .remove = bfin_wdt_remove, .shutdown = bfin_wdt_shutdown, .suspend = bfin_wdt_suspend, .resume = bfin_wdt_resume, diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c index 7e888393de1f..f270bb7bc456 100644 --- a/drivers/watchdog/cpu5wdt.c +++ b/drivers/watchdog/cpu5wdt.c @@ -215,7 +215,7 @@ static struct miscdevice cpu5wdt_misc = { /* init/exit function */ -static int __devinit cpu5wdt_init(void) +static int cpu5wdt_init(void) { unsigned int val; int err; @@ -256,16 +256,17 @@ no_port: return err; } -static int __devinit cpu5wdt_init_module(void) +static int cpu5wdt_init_module(void) { return cpu5wdt_init(); } -static void __devexit cpu5wdt_exit(void) +static void cpu5wdt_exit(void) { if (cpu5wdt_device.queue) { cpu5wdt_device.queue = 0; wait_for_completion(&cpu5wdt_device.stop); + del_timer(&cpu5wdt_device.timer); } misc_deregister(&cpu5wdt_misc); @@ -274,7 +275,7 @@ static void __devexit cpu5wdt_exit(void) } -static void __devexit cpu5wdt_exit_module(void) +static void cpu5wdt_exit_module(void) { cpu5wdt_exit(); } diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 95b1b954de1b..11d55ce5ca81 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -528,7 +528,7 @@ static const struct file_operations cpwd_fops = { .llseek = no_llseek, }; -static int __devinit cpwd_probe(struct platform_device *op) +static int cpwd_probe(struct platform_device *op) { struct device_node *options; const char *str_prop; @@ -640,7 +640,7 @@ out_free: goto out; } -static int __devexit cpwd_remove(struct platform_device *op) +static int cpwd_remove(struct platform_device *op) { struct cpwd *p = dev_get_drvdata(&op->dev); int i; @@ -684,7 +684,7 @@ static struct platform_driver cpwd_driver = { .of_match_table = cpwd_match, }, .probe = cpwd_probe, - .remove = __devexit_p(cpwd_remove), + .remove = cpwd_remove, }; module_platform_driver(cpwd_driver); diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index f7abbaeebcaf..367445009c64 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c @@ -53,10 +53,6 @@ static const struct { static void da9052_wdt_release_resources(struct kref *r) { - struct da9052_wdt_data *driver_data = - container_of(r, struct da9052_wdt_data, kref); - - kfree(driver_data); } static int da9052_wdt_set_timeout(struct watchdog_device *wdt_dev, @@ -179,7 +175,7 @@ static const struct watchdog_ops da9052_wdt_ops = { }; -static int __devinit da9052_wdt_probe(struct platform_device *pdev) +static int da9052_wdt_probe(struct platform_device *pdev) { struct da9052 *da9052 = dev_get_drvdata(pdev->dev.parent); struct da9052_wdt_data *driver_data; @@ -224,7 +220,7 @@ err: return ret; } -static int __devexit da9052_wdt_remove(struct platform_device *pdev) +static int da9052_wdt_remove(struct platform_device *pdev) { struct da9052_wdt_data *driver_data = dev_get_drvdata(&pdev->dev); @@ -236,7 +232,7 @@ static int __devexit da9052_wdt_remove(struct platform_device *pdev) static struct platform_driver da9052_wdt_driver = { .probe = da9052_wdt_probe, - .remove = __devexit_p(da9052_wdt_remove), + .remove = da9052_wdt_remove, .driver = { .name = "da9052-watchdog", }, diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c new file mode 100644 index 000000000000..f5ad10546fc9 --- /dev/null +++ b/drivers/watchdog/da9055_wdt.c @@ -0,0 +1,211 @@ +/* + * System monitoring driver for DA9055 PMICs. + * + * Copyright(c) 2012 Dialog Semiconductor Ltd. + * + * Author: David Dajun Chen <dchen@diasemi.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/platform_device.h> +#include <linux/watchdog.h> +#include <linux/delay.h> + +#include <linux/mfd/da9055/core.h> +#include <linux/mfd/da9055/reg.h> + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, + "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +#define DA9055_DEF_TIMEOUT 4 +#define DA9055_TWDMIN 256 + +struct da9055_wdt_data { + struct watchdog_device wdt; + struct da9055 *da9055; + struct kref kref; +}; + +static const struct { + u8 reg_val; + int user_time; /* In seconds */ +} da9055_wdt_maps[] = { + { 0, 0 }, + { 1, 2 }, + { 2, 4 }, + { 3, 8 }, + { 4, 16 }, + { 5, 32 }, + { 5, 33 }, /* Actual time 32.768s so included both 32s and 33s */ + { 6, 65 }, + { 6, 66 }, /* Actual time 65.536s so include both, 65s and 66s */ + { 7, 131 }, +}; + +static int da9055_wdt_set_timeout(struct watchdog_device *wdt_dev, + unsigned int timeout) +{ + struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev); + struct da9055 *da9055 = driver_data->da9055; + int ret, i; + + for (i = 0; i < ARRAY_SIZE(da9055_wdt_maps); i++) + if (da9055_wdt_maps[i].user_time == timeout) + break; + + if (i == ARRAY_SIZE(da9055_wdt_maps)) + ret = -EINVAL; + else + ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B, + DA9055_TWDSCALE_MASK, + da9055_wdt_maps[i].reg_val << + DA9055_TWDSCALE_SHIFT); + if (ret < 0) { + dev_err(da9055->dev, + "Failed to update timescale bit, %d\n", ret); + return ret; + } + + wdt_dev->timeout = timeout; + + return 0; +} + +static int da9055_wdt_ping(struct watchdog_device *wdt_dev) +{ + struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev); + struct da9055 *da9055 = driver_data->da9055; + + /* + * We have a minimum time for watchdog window called TWDMIN. A write + * to the watchdog before this elapsed time will cause an error. + */ + mdelay(DA9055_TWDMIN); + + /* Reset the watchdog timer */ + return da9055_reg_update(da9055, DA9055_REG_CONTROL_E, + DA9055_WATCHDOG_MASK, 1); +} + +static void da9055_wdt_release_resources(struct kref *r) +{ +} + +static void da9055_wdt_ref(struct watchdog_device *wdt_dev) +{ + struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev); + + kref_get(&driver_data->kref); +} + +static void da9055_wdt_unref(struct watchdog_device *wdt_dev) +{ + struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev); + + kref_put(&driver_data->kref, da9055_wdt_release_resources); +} + +static int da9055_wdt_start(struct watchdog_device *wdt_dev) +{ + return da9055_wdt_set_timeout(wdt_dev, wdt_dev->timeout); +} + +static int da9055_wdt_stop(struct watchdog_device *wdt_dev) +{ + return da9055_wdt_set_timeout(wdt_dev, 0); +} + +static struct watchdog_info da9055_wdt_info = { + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, + .identity = "DA9055 Watchdog", +}; + +static const struct watchdog_ops da9055_wdt_ops = { + .owner = THIS_MODULE, + .start = da9055_wdt_start, + .stop = da9055_wdt_stop, + .ping = da9055_wdt_ping, + .set_timeout = da9055_wdt_set_timeout, + .ref = da9055_wdt_ref, + .unref = da9055_wdt_unref, +}; + +static int da9055_wdt_probe(struct platform_device *pdev) +{ + struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent); + struct da9055_wdt_data *driver_data; + struct watchdog_device *da9055_wdt; + int ret; + + driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), + GFP_KERNEL); + if (!driver_data) { + dev_err(da9055->dev, "Failed to allocate watchdog device\n"); + return -ENOMEM; + } + + driver_data->da9055 = da9055; + + da9055_wdt = &driver_data->wdt; + + da9055_wdt->timeout = DA9055_DEF_TIMEOUT; + da9055_wdt->info = &da9055_wdt_info; + da9055_wdt->ops = &da9055_wdt_ops; + watchdog_set_nowayout(da9055_wdt, nowayout); + watchdog_set_drvdata(da9055_wdt, driver_data); + + kref_init(&driver_data->kref); + + ret = da9055_wdt_stop(da9055_wdt); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to stop watchdog, %d\n", ret); + goto err; + } + + dev_set_drvdata(&pdev->dev, driver_data); + + ret = watchdog_register_device(&driver_data->wdt); + if (ret != 0) + dev_err(da9055->dev, "watchdog_register_device() failed: %d\n", + ret); + +err: + return ret; +} + +static int da9055_wdt_remove(struct platform_device *pdev) +{ + struct da9055_wdt_data *driver_data = dev_get_drvdata(&pdev->dev); + + watchdog_unregister_device(&driver_data->wdt); + kref_put(&driver_data->kref, da9055_wdt_release_resources); + + return 0; +} + +static struct platform_driver da9055_wdt_driver = { + .probe = da9055_wdt_probe, + .remove = da9055_wdt_remove, + .driver = { + .name = "da9055-watchdog", + }, +}; + +module_platform_driver(da9055_wdt_driver); + +MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); +MODULE_DESCRIPTION("DA9055 watchdog"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:da9055-watchdog"); diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index c8c5c8032bcb..e8e87246ea6d 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c @@ -199,7 +199,7 @@ static struct miscdevice davinci_wdt_miscdev = { .fops = &davinci_wdt_fops, }; -static int __devinit davinci_wdt_probe(struct platform_device *pdev) +static int davinci_wdt_probe(struct platform_device *pdev) { int ret = 0, size; struct device *dev = &pdev->dev; @@ -208,7 +208,7 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev) if (WARN_ON(IS_ERR(wdt_clk))) return PTR_ERR(wdt_clk); - clk_enable(wdt_clk); + clk_prepare_enable(wdt_clk); if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) heartbeat = DEFAULT_HEARTBEAT; @@ -248,7 +248,7 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev) return ret; } -static int __devexit davinci_wdt_remove(struct platform_device *pdev) +static int davinci_wdt_remove(struct platform_device *pdev) { misc_deregister(&davinci_wdt_miscdev); if (wdt_mem) { @@ -256,19 +256,26 @@ static int __devexit davinci_wdt_remove(struct platform_device *pdev) wdt_mem = NULL; } - clk_disable(wdt_clk); + clk_disable_unprepare(wdt_clk); clk_put(wdt_clk); return 0; } +static const struct of_device_id davinci_wdt_of_match[] = { + { .compatible = "ti,davinci-wdt", }, + {}, +}; +MODULE_DEVICE_TABLE(of, davinci_wdt_of_match); + static struct platform_driver platform_wdt_driver = { .driver = { .name = "watchdog", .owner = THIS_MODULE, + .of_match_table = davinci_wdt_of_match, }, .probe = davinci_wdt_probe, - .remove = __devexit_p(davinci_wdt_remove), + .remove = davinci_wdt_remove, }; module_platform_driver(platform_wdt_driver); diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 06de1211a444..a0eba3c40e25 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -293,7 +293,7 @@ static struct miscdevice dw_wdt_miscdev = { .minor = WATCHDOG_MINOR, }; -static int __devinit dw_wdt_drv_probe(struct platform_device *pdev) +static int dw_wdt_drv_probe(struct platform_device *pdev) { int ret; struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -333,7 +333,7 @@ out_put_clk: return ret; } -static int __devexit dw_wdt_drv_remove(struct platform_device *pdev) +static int dw_wdt_drv_remove(struct platform_device *pdev) { misc_deregister(&dw_wdt_miscdev); @@ -345,7 +345,7 @@ static int __devexit dw_wdt_drv_remove(struct platform_device *pdev) static struct platform_driver dw_wdt_driver = { .probe = dw_wdt_drv_probe, - .remove = __devexit_p(dw_wdt_drv_remove), + .remove = dw_wdt_drv_remove, .driver = { .name = "dw_wdt", .owner = THIS_MODULE, diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c index 77050037597a..e0574844c313 100644 --- a/drivers/watchdog/ep93xx_wdt.c +++ b/drivers/watchdog/ep93xx_wdt.c @@ -112,7 +112,7 @@ static struct watchdog_device ep93xx_wdt_wdd = { .ops = &ep93xx_wdt_ops, }; -static int __devinit ep93xx_wdt_probe(struct platform_device *pdev) +static int ep93xx_wdt_probe(struct platform_device *pdev) { struct resource *res; unsigned long val; @@ -156,7 +156,7 @@ static int __devinit ep93xx_wdt_probe(struct platform_device *pdev) return 0; } -static int __devexit ep93xx_wdt_remove(struct platform_device *pdev) +static int ep93xx_wdt_remove(struct platform_device *pdev) { watchdog_unregister_device(&ep93xx_wdt_wdd); return 0; @@ -168,7 +168,7 @@ static struct platform_driver ep93xx_wdt_driver = { .name = "ep93xx-wdt", }, .probe = ep93xx_wdt_probe, - .remove = __devexit_p(ep93xx_wdt_remove), + .remove = ep93xx_wdt_remove, }; module_platform_driver(ep93xx_wdt_driver); diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index 17f4cae770c6..b9c5b58e59d3 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -262,7 +262,7 @@ static struct miscdevice gef_wdt_miscdev = { }; -static int __devinit gef_wdt_probe(struct platform_device *dev) +static int gef_wdt_probe(struct platform_device *dev) { int timeout = 10; u32 freq; @@ -285,7 +285,7 @@ static int __devinit gef_wdt_probe(struct platform_device *dev) return misc_register(&gef_wdt_miscdev); } -static int __devexit gef_wdt_remove(struct platform_device *dev) +static int gef_wdt_remove(struct platform_device *dev) { misc_deregister(&gef_wdt_miscdev); diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index dc563b680abd..fcd599d4e225 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c @@ -215,7 +215,7 @@ static struct miscdevice geodewdt_miscdev = { .fops = &geodewdt_fops, }; -static int __devinit geodewdt_probe(struct platform_device *dev) +static int geodewdt_probe(struct platform_device *dev) { int ret; @@ -243,7 +243,7 @@ static int __devinit geodewdt_probe(struct platform_device *dev) return ret; } -static int __devexit geodewdt_remove(struct platform_device *dev) +static int geodewdt_remove(struct platform_device *dev) { misc_deregister(&geodewdt_miscdev); return 0; @@ -256,7 +256,7 @@ static void geodewdt_shutdown(struct platform_device *dev) static struct platform_driver geodewdt_driver = { .probe = geodewdt_probe, - .remove = __devexit_p(geodewdt_remove), + .remove = geodewdt_remove, .shutdown = geodewdt_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index ae60406ea8a1..11796b9b864e 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -39,7 +39,7 @@ #endif /* CONFIG_HPWDT_NMI_DECODING */ #include <asm/nmi.h> -#define HPWDT_VERSION "1.3.0" +#define HPWDT_VERSION "1.3.1" #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) #define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) #define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) @@ -212,7 +212,7 @@ asm(".text \n\t" * 0 : SUCCESS * <0 : FAILURE */ -static int __devinit cru_detect(unsigned long map_entry, +static int cru_detect(unsigned long map_entry, unsigned long map_offset) { void *bios32_map; @@ -268,7 +268,7 @@ static int __devinit cru_detect(unsigned long map_entry, /* * bios_checksum */ -static int __devinit bios_checksum(const char __iomem *ptr, int len) +static int bios_checksum(const char __iomem *ptr, int len) { char sum = 0; int i; @@ -293,7 +293,7 @@ static int __devinit bios_checksum(const char __iomem *ptr, int len) * 0 : SUCCESS * <0 : FAILURE */ -static int __devinit bios32_present(const char __iomem *p) +static int bios32_present(const char __iomem *p) { struct bios32_service_dir *bios_32_ptr; int length; @@ -323,7 +323,7 @@ static int __devinit bios32_present(const char __iomem *p) return -ENODEV; } -static int __devinit detect_cru_service(void) +static int detect_cru_service(void) { char __iomem *p, *q; int rc = -1; @@ -395,7 +395,7 @@ asm(".text \n\t" * This function checks whether or not a SMBIOS/DMI record is * the 64bit CRU info or not */ -static void __devinit dmi_find_cru(const struct dmi_header *dm, void *dummy) +static void dmi_find_cru(const struct dmi_header *dm, void *dummy) { struct smbios_cru64_info *smbios_cru64_ptr; unsigned long cru_physical_address; @@ -414,7 +414,7 @@ static void __devinit dmi_find_cru(const struct dmi_header *dm, void *dummy) } } -static int __devinit detect_cru_service(void) +static int detect_cru_service(void) { cru_rom_addr = NULL; @@ -647,7 +647,7 @@ static struct miscdevice hpwdt_miscdev = { #ifdef CONFIG_HPWDT_NMI_DECODING #ifdef CONFIG_X86_LOCAL_APIC -static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev) +static void hpwdt_check_nmi_decoding(struct pci_dev *dev) { /* * If nmi_watchdog is turned off then we can turn on @@ -656,7 +656,7 @@ static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev) hpwdt_nmi_decoding = 1; } #else -static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev) +static void hpwdt_check_nmi_decoding(struct pci_dev *dev) { dev_warn(&dev->dev, "NMI decoding is disabled. " "Your kernel does not support a NMI Watchdog.\n"); @@ -671,7 +671,7 @@ static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev) * This check is independent of architecture and needs to be made for * any ProLiant system. */ -static void __devinit dmi_find_icru(const struct dmi_header *dm, void *dummy) +static void dmi_find_icru(const struct dmi_header *dm, void *dummy) { struct smbios_proliant_info *smbios_proliant_ptr; @@ -682,7 +682,7 @@ static void __devinit dmi_find_icru(const struct dmi_header *dm, void *dummy) } } -static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) +static int hpwdt_init_nmi_decoding(struct pci_dev *dev) { int retval; @@ -762,11 +762,11 @@ static void hpwdt_exit_nmi_decoding(void) iounmap(cru_rom_addr); } #else /* !CONFIG_HPWDT_NMI_DECODING */ -static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev) +static void hpwdt_check_nmi_decoding(struct pci_dev *dev) { } -static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) +static int hpwdt_init_nmi_decoding(struct pci_dev *dev) { return 0; } @@ -776,7 +776,7 @@ static void hpwdt_exit_nmi_decoding(void) } #endif /* CONFIG_HPWDT_NMI_DECODING */ -static int __devinit hpwdt_init_one(struct pci_dev *dev, +static int hpwdt_init_one(struct pci_dev *dev, const struct pci_device_id *ent) { int retval; @@ -848,7 +848,7 @@ error_pci_iomap: return retval; } -static void __devexit hpwdt_exit(struct pci_dev *dev) +static void hpwdt_exit(struct pci_dev *dev) { if (!nowayout) hpwdt_stop(); @@ -863,7 +863,7 @@ static struct pci_driver hpwdt_driver = { .name = "hpwdt", .id_table = hpwdt_devices, .probe = hpwdt_init_one, - .remove = __devexit_p(hpwdt_exit), + .remove = hpwdt_exit, }; MODULE_AUTHOR("Tom Mingarelli"); diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index 276877d5b6a3..2b2ea13d03ea 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c @@ -344,7 +344,7 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl); * Init & exit routines */ -static unsigned char __devinit esb_getdevice(struct pci_dev *pdev) +static unsigned char esb_getdevice(struct pci_dev *pdev) { if (pci_enable_device(pdev)) { pr_err("failed to enable device\n"); @@ -375,7 +375,7 @@ err_devput: return 0; } -static void __devinit esb_initdevice(void) +static void esb_initdevice(void) { u8 val1; u16 val2; @@ -416,7 +416,7 @@ static void __devinit esb_initdevice(void) esb_timer_set_heartbeat(heartbeat); } -static int __devinit esb_probe(struct pci_dev *pdev, +static int esb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int ret; @@ -465,7 +465,7 @@ err_unmap: return ret; } -static void __devexit esb_remove(struct pci_dev *pdev) +static void esb_remove(struct pci_dev *pdev) { /* Stop the timer before we leave */ if (!nowayout) @@ -488,7 +488,7 @@ static struct pci_driver esb_driver = { .name = ESB_MODULE_NAME, .id_table = esb_pci_tbl, .probe = esb_probe, - .remove = __devexit_p(esb_remove), + .remove = esb_remove, .shutdown = esb_shutdown, }; diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 545d387de411..6130321da387 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -364,7 +364,7 @@ static struct watchdog_device iTCO_wdt_watchdog_dev = { * Init & exit routines */ -static void __devexit iTCO_wdt_cleanup(void) +static void iTCO_wdt_cleanup(void) { /* Stop the timer before we leave */ if (!nowayout) @@ -390,7 +390,7 @@ static void __devexit iTCO_wdt_cleanup(void) iTCO_wdt_private.gcs = NULL; } -static int __devinit iTCO_wdt_probe(struct platform_device *dev) +static int iTCO_wdt_probe(struct platform_device *dev) { int ret = -ENODEV; unsigned long val32; @@ -533,7 +533,7 @@ out: return ret; } -static int __devexit iTCO_wdt_remove(struct platform_device *dev) +static int iTCO_wdt_remove(struct platform_device *dev) { if (iTCO_wdt_private.tco_res || iTCO_wdt_private.smi_res) iTCO_wdt_cleanup(); @@ -548,7 +548,7 @@ static void iTCO_wdt_shutdown(struct platform_device *dev) static struct platform_driver iTCO_wdt_driver = { .probe = iTCO_wdt_probe, - .remove = __devexit_p(iTCO_wdt_remove), + .remove = iTCO_wdt_remove, .shutdown = iTCO_wdt_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 184c0bfc87a4..eb6b5cc98ec6 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c @@ -277,7 +277,7 @@ static struct miscdevice ibwdt_miscdev = { * Init & exit routines */ -static int __devinit ibwdt_probe(struct platform_device *dev) +static int ibwdt_probe(struct platform_device *dev) { int res; @@ -319,7 +319,7 @@ out_nostopreg: return res; } -static int __devexit ibwdt_remove(struct platform_device *dev) +static int ibwdt_remove(struct platform_device *dev) { misc_deregister(&ibwdt_miscdev); release_region(WDT_START, 1); @@ -337,7 +337,7 @@ static void ibwdt_shutdown(struct platform_device *dev) static struct platform_driver ibwdt_driver = { .probe = ibwdt_probe, - .remove = __devexit_p(ibwdt_remove), + .remove = ibwdt_remove, .shutdown = ibwdt_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c index 8f541b940053..e24ef6a6e064 100644 --- a/drivers/watchdog/ie6xx_wdt.c +++ b/drivers/watchdog/ie6xx_wdt.c @@ -225,7 +225,7 @@ static const struct file_operations ie6xx_wdt_dbg_operations = { .release = single_release, }; -static void __devinit ie6xx_wdt_debugfs_init(void) +static void ie6xx_wdt_debugfs_init(void) { /* /sys/kernel/debug/ie6xx_wdt */ ie6xx_wdt_data.debugfs = debugfs_create_file("ie6xx_wdt", @@ -238,7 +238,7 @@ static void ie6xx_wdt_debugfs_exit(void) } #else -static void __devinit ie6xx_wdt_debugfs_init(void) +static void ie6xx_wdt_debugfs_init(void) { } @@ -247,7 +247,7 @@ static void ie6xx_wdt_debugfs_exit(void) } #endif -static int __devinit ie6xx_wdt_probe(struct platform_device *pdev) +static int ie6xx_wdt_probe(struct platform_device *pdev) { struct resource *res; u8 wdtlr; @@ -295,7 +295,7 @@ misc_register_error: return ret; } -static int __devexit ie6xx_wdt_remove(struct platform_device *pdev) +static int ie6xx_wdt_remove(struct platform_device *pdev) { struct resource *res; @@ -311,7 +311,7 @@ static int __devexit ie6xx_wdt_remove(struct platform_device *pdev) static struct platform_driver ie6xx_wdt_driver = { .probe = ie6xx_wdt_probe, - .remove = __devexit_p(ie6xx_wdt_remove), + .remove = ie6xx_wdt_remove, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index bcfab2b00ad2..9a45d0294cf4 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -33,7 +33,6 @@ #include <linux/uaccess.h> #include <linux/timer.h> #include <linux/jiffies.h> -#include <mach/hardware.h> #define DRIVER_NAME "imx2-wdt" diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c index 978615ef899d..a61408fa0c94 100644 --- a/drivers/watchdog/jz4740_wdt.c +++ b/drivers/watchdog/jz4740_wdt.c @@ -144,7 +144,7 @@ static const struct watchdog_ops jz4740_wdt_ops = { .set_timeout = jz4740_wdt_set_timeout, }; -static int __devinit jz4740_wdt_probe(struct platform_device *pdev) +static int jz4740_wdt_probe(struct platform_device *pdev) { struct jz4740_wdt_drvdata *drvdata; struct watchdog_device *jz4740_wdt; @@ -197,7 +197,7 @@ err_out: return ret; } -static int __devexit jz4740_wdt_remove(struct platform_device *pdev) +static int jz4740_wdt_remove(struct platform_device *pdev) { struct jz4740_wdt_drvdata *drvdata = platform_get_drvdata(pdev); @@ -210,7 +210,7 @@ static int __devexit jz4740_wdt_remove(struct platform_device *pdev) static struct platform_driver jz4740_wdt_driver = { .probe = jz4740_wdt_probe, - .remove = __devexit_p(jz4740_wdt_remove), + .remove = jz4740_wdt_remove, .driver = { .name = "jz4740-wdt", .owner = THIS_MODULE, diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c index c1a4d3bf581d..dce9ecffd44a 100644 --- a/drivers/watchdog/ks8695_wdt.c +++ b/drivers/watchdog/ks8695_wdt.c @@ -235,7 +235,7 @@ static struct miscdevice ks8695wdt_miscdev = { .fops = &ks8695wdt_fops, }; -static int __devinit ks8695wdt_probe(struct platform_device *pdev) +static int ks8695wdt_probe(struct platform_device *pdev) { int res; @@ -252,7 +252,7 @@ static int __devinit ks8695wdt_probe(struct platform_device *pdev) return 0; } -static int __devexit ks8695wdt_remove(struct platform_device *pdev) +static int ks8695wdt_remove(struct platform_device *pdev) { int res; @@ -290,7 +290,7 @@ static int ks8695wdt_resume(struct platform_device *pdev) static struct platform_driver ks8695wdt_driver = { .probe = ks8695wdt_probe, - .remove = __devexit_p(ks8695wdt_remove), + .remove = ks8695wdt_remove, .shutdown = ks8695wdt_shutdown, .suspend = ks8695wdt_suspend, .resume = ks8695wdt_resume, diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c index 2e74c3a8ee58..79fe01b42339 100644 --- a/drivers/watchdog/lantiq_wdt.c +++ b/drivers/watchdog/lantiq_wdt.c @@ -186,7 +186,7 @@ static struct miscdevice ltq_wdt_miscdev = { .fops = <q_wdt_fops, }; -static int __devinit +static int ltq_wdt_probe(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -220,7 +220,7 @@ ltq_wdt_probe(struct platform_device *pdev) return misc_register(<q_wdt_miscdev); } -static int __devexit +static int ltq_wdt_remove(struct platform_device *pdev) { misc_deregister(<q_wdt_miscdev); @@ -236,7 +236,7 @@ MODULE_DEVICE_TABLE(of, ltq_wdt_match); static struct platform_driver ltq_wdt_driver = { .probe = ltq_wdt_probe, - .remove = __devexit_p(ltq_wdt_remove), + .remove = ltq_wdt_remove, .driver = { .name = "wdt", .owner = THIS_MODULE, diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c index 8f4a74e91619..773c661723ca 100644 --- a/drivers/watchdog/max63xx_wdt.c +++ b/drivers/watchdog/max63xx_wdt.c @@ -174,7 +174,7 @@ static struct watchdog_device max63xx_wdt_dev = { .ops = &max63xx_wdt_ops, }; -static int __devinit max63xx_wdt_probe(struct platform_device *pdev) +static int max63xx_wdt_probe(struct platform_device *pdev) { struct resource *wdt_mem; struct max63xx_timeout *table; @@ -209,7 +209,7 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev) return watchdog_register_device(&max63xx_wdt_dev); } -static int __devexit max63xx_wdt_remove(struct platform_device *pdev) +static int max63xx_wdt_remove(struct platform_device *pdev) { watchdog_unregister_device(&max63xx_wdt_dev); return 0; @@ -228,7 +228,7 @@ MODULE_DEVICE_TABLE(platform, max63xx_id_table); static struct platform_driver max63xx_wdt_driver = { .probe = max63xx_wdt_probe, - .remove = __devexit_p(max63xx_wdt_remove), + .remove = max63xx_wdt_remove, .id_table = max63xx_id_table, .driver = { .name = "max63xx_wdt", diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c index 37e4b52dbce9..97d62ee50341 100644 --- a/drivers/watchdog/mixcomwd.c +++ b/drivers/watchdog/mixcomwd.c @@ -73,7 +73,7 @@ static struct { int ioport; int id; -} mixcomwd_io_info[] __devinitdata = { +} mixcomwd_io_info[] = { /* The Mixcom cards */ {0x0d90, MIXCOM_ID}, {0x0e90, MIXCOM_ID}, diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index e6a038ae8dc2..da2752063bb7 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -188,7 +188,7 @@ static struct miscdevice mpc8xxx_wdt_miscdev = { }; static const struct of_device_id mpc8xxx_wdt_match[]; -static int __devinit mpc8xxx_wdt_probe(struct platform_device *ofdev) +static int mpc8xxx_wdt_probe(struct platform_device *ofdev) { int ret; const struct of_device_id *match; @@ -245,7 +245,7 @@ err_unmap: return ret; } -static int __devexit mpc8xxx_wdt_remove(struct platform_device *ofdev) +static int mpc8xxx_wdt_remove(struct platform_device *ofdev) { mpc8xxx_wdt_pr_warn("watchdog removed"); del_timer_sync(&wdt_timer); @@ -281,7 +281,7 @@ MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match); static struct platform_driver mpc8xxx_wdt_driver = { .probe = mpc8xxx_wdt_probe, - .remove = __devexit_p(mpc8xxx_wdt_remove), + .remove = mpc8xxx_wdt_remove, .driver = { .name = "mpc8xxx_wdt", .owner = THIS_MODULE, diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c index 7c741dc987bd..233cfadcb21f 100644 --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c @@ -80,8 +80,7 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg) /* Check it really was our interrupt */ if (readl(wdt->base + TWD_WDOG_INTSTAT)) { - dev_printk(KERN_CRIT, wdt->dev, - "Triggered - Reboot ignored.\n"); + dev_crit(wdt->dev, "Triggered - Reboot ignored\n"); /* Clear the interrupt on the watchdog */ writel(1, wdt->base + TWD_WDOG_INTSTAT); return IRQ_HANDLED; @@ -123,7 +122,7 @@ static void mpcore_wdt_stop(struct mpcore_wdt *wdt) static void mpcore_wdt_start(struct mpcore_wdt *wdt) { - dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); + dev_info(wdt->dev, "enabling watchdog\n"); /* This loads the count register but does NOT start the count yet */ mpcore_wdt_keepalive(wdt); @@ -180,8 +179,8 @@ static int mpcore_wdt_release(struct inode *inode, struct file *file) if (wdt->expect_close == 42) mpcore_wdt_stop(wdt); else { - dev_printk(KERN_CRIT, wdt->dev, - "unexpected close, not stopping watchdog!\n"); + dev_crit(wdt->dev, + "unexpected close, not stopping watchdog!\n"); mpcore_wdt_keepalive(wdt); } clear_bit(0, &wdt->timer_alive); @@ -327,7 +326,7 @@ static struct miscdevice mpcore_wdt_miscdev = { .fops = &mpcore_wdt_fops, }; -static int __devinit mpcore_wdt_probe(struct platform_device *pdev) +static int mpcore_wdt_probe(struct platform_device *pdev) { struct mpcore_wdt *wdt; struct resource *res; @@ -351,9 +350,9 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev) ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0, "mpcore_wdt", wdt); if (ret) { - dev_printk(KERN_ERR, wdt->dev, - "cannot register IRQ%d for watchdog\n", - wdt->irq); + dev_err(wdt->dev, + "cannot register IRQ%d for watchdog\n", + wdt->irq); return ret; } } @@ -365,9 +364,9 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev) mpcore_wdt_miscdev.parent = &pdev->dev; ret = misc_register(&mpcore_wdt_miscdev); if (ret) { - dev_printk(KERN_ERR, wdt->dev, + dev_err(wdt->dev, "cannot register miscdev on minor=%d (err=%d)\n", - WATCHDOG_MINOR, ret); + WATCHDOG_MINOR, ret); return ret; } @@ -378,7 +377,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev) return 0; } -static int __devexit mpcore_wdt_remove(struct platform_device *pdev) +static int mpcore_wdt_remove(struct platform_device *pdev) { platform_set_drvdata(pdev, NULL); @@ -415,7 +414,7 @@ MODULE_ALIAS("platform:mpcore_wdt"); static struct platform_driver mpcore_wdt_driver = { .probe = mpcore_wdt_probe, - .remove = __devexit_p(mpcore_wdt_remove), + .remove = mpcore_wdt_remove, .suspend = mpcore_wdt_suspend, .resume = mpcore_wdt_resume, .shutdown = mpcore_wdt_shutdown, diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index c29e31d99fe8..14dab6ff87aa 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -204,7 +204,7 @@ static struct miscdevice mtx1_wdt_misc = { }; -static int __devinit mtx1_wdt_probe(struct platform_device *pdev) +static int mtx1_wdt_probe(struct platform_device *pdev) { int ret; @@ -233,7 +233,7 @@ static int __devinit mtx1_wdt_probe(struct platform_device *pdev) return 0; } -static int __devexit mtx1_wdt_remove(struct platform_device *pdev) +static int mtx1_wdt_remove(struct platform_device *pdev) { /* FIXME: do we need to lock this test ? */ if (mtx1_wdt_device.queue) { @@ -248,7 +248,7 @@ static int __devexit mtx1_wdt_remove(struct platform_device *pdev) static struct platform_driver mtx1_wdt_driver = { .probe = mtx1_wdt_probe, - .remove = __devexit_p(mtx1_wdt_remove), + .remove = mtx1_wdt_remove, .driver.name = "mtx1-wdt", .driver.owner = THIS_MODULE, }; diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c index c53d025e70df..c7fb878ca493 100644 --- a/drivers/watchdog/mv64x60_wdt.c +++ b/drivers/watchdog/mv64x60_wdt.c @@ -253,7 +253,7 @@ static struct miscdevice mv64x60_wdt_miscdev = { .fops = &mv64x60_wdt_fops, }; -static int __devinit mv64x60_wdt_probe(struct platform_device *dev) +static int mv64x60_wdt_probe(struct platform_device *dev) { struct mv64x60_wdt_pdata *pdata = dev->dev.platform_data; struct resource *r; @@ -287,7 +287,7 @@ static int __devinit mv64x60_wdt_probe(struct platform_device *dev) return misc_register(&mv64x60_wdt_miscdev); } -static int __devexit mv64x60_wdt_remove(struct platform_device *dev) +static int mv64x60_wdt_remove(struct platform_device *dev) { misc_deregister(&mv64x60_wdt_miscdev); @@ -300,7 +300,7 @@ static int __devexit mv64x60_wdt_remove(struct platform_device *dev) static struct platform_driver mv64x60_wdt_driver = { .probe = mv64x60_wdt_probe, - .remove = __devexit_p(mv64x60_wdt_remove), + .remove = mv64x60_wdt_remove, .driver = { .owner = THIS_MODULE, .name = MV64x60_WDT_NAME, diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c index ea4c7448b754..04c45a102992 100644 --- a/drivers/watchdog/nuc900_wdt.c +++ b/drivers/watchdog/nuc900_wdt.c @@ -242,7 +242,7 @@ static struct miscdevice nuc900wdt_miscdev = { .fops = &nuc900wdt_fops, }; -static int __devinit nuc900wdt_probe(struct platform_device *pdev) +static int nuc900wdt_probe(struct platform_device *pdev) { int ret = 0; @@ -309,7 +309,7 @@ err_get: return ret; } -static int __devexit nuc900wdt_remove(struct platform_device *pdev) +static int nuc900wdt_remove(struct platform_device *pdev) { misc_deregister(&nuc900wdt_miscdev); @@ -328,7 +328,7 @@ static int __devexit nuc900wdt_remove(struct platform_device *pdev) static struct platform_driver nuc900wdt_driver = { .probe = nuc900wdt_probe, - .remove = __devexit_p(nuc900wdt_remove), + .remove = nuc900wdt_remove, .driver = { .name = "nuc900-wdt", .owner = THIS_MODULE, diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c index 6bbb9efc6125..59cf19eeea07 100644 --- a/drivers/watchdog/nv_tco.c +++ b/drivers/watchdog/nv_tco.c @@ -302,7 +302,7 @@ MODULE_DEVICE_TABLE(pci, tco_pci_tbl); * Init & exit routines */ -static unsigned char __devinit nv_tco_getdevice(void) +static unsigned char nv_tco_getdevice(void) { struct pci_dev *dev = NULL; u32 val; @@ -376,7 +376,7 @@ out: return 0; } -static int __devinit nv_tco_init(struct platform_device *dev) +static int nv_tco_init(struct platform_device *dev) { int ret; @@ -423,7 +423,7 @@ unreg_region: return ret; } -static void __devexit nv_tco_cleanup(void) +static void nv_tco_cleanup(void) { u32 val; @@ -445,7 +445,7 @@ static void __devexit nv_tco_cleanup(void) release_region(tcobase, 0x10); } -static int __devexit nv_tco_remove(struct platform_device *dev) +static int nv_tco_remove(struct platform_device *dev) { if (tcobase) nv_tco_cleanup(); @@ -468,7 +468,7 @@ static void nv_tco_shutdown(struct platform_device *dev) static struct platform_driver nv_tco_driver = { .probe = nv_tco_init, - .remove = __devexit_p(nv_tco_remove), + .remove = nv_tco_remove, .shutdown = nv_tco_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index 294fb4e00521..2761ddb08501 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c @@ -289,7 +289,7 @@ static struct miscdevice xwdt_miscdev = { .fops = &xwdt_fops, }; -static int __devinit xwdt_probe(struct platform_device *pdev) +static int xwdt_probe(struct platform_device *pdev) { int rc; u32 *tmptr; @@ -383,7 +383,7 @@ err_out: return rc; } -static int __devexit xwdt_remove(struct platform_device *dev) +static int xwdt_remove(struct platform_device *dev) { misc_deregister(&xwdt_miscdev); iounmap(xdev.base); @@ -393,7 +393,7 @@ static int __devexit xwdt_remove(struct platform_device *dev) } /* Match table for of_platform binding */ -static struct of_device_id __devinitdata xwdt_of_match[] = { +static struct of_device_id xwdt_of_match[] = { { .compatible = "xlnx,xps-timebase-wdt-1.01.a", }, {}, }; @@ -401,7 +401,7 @@ MODULE_DEVICE_TABLE(of, xwdt_of_match); static struct platform_driver xwdt_driver = { .probe = xwdt_probe, - .remove = __devexit_p(xwdt_remove), + .remove = xwdt_remove, .driver = { .owner = THIS_MODULE, .name = WATCHDOG_NAME, diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index f5db18dbc0f9..b0e541d022e6 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -31,44 +31,34 @@ #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> -#include <linux/fs.h> #include <linux/mm.h> -#include <linux/miscdevice.h> #include <linux/watchdog.h> #include <linux/reboot.h> #include <linux/init.h> #include <linux/err.h> #include <linux/platform_device.h> #include <linux/moduleparam.h> -#include <linux/bitops.h> #include <linux/io.h> -#include <linux/uaccess.h> #include <linux/slab.h> #include <linux/pm_runtime.h> -#include <mach/hardware.h> -#include <plat/cpu.h> -#include <plat/prcm.h> +#include <linux/platform_data/omap-wd-timer.h> #include "omap_wdt.h" -static struct platform_device *omap_wdt_dev; - static unsigned timer_margin; module_param(timer_margin, uint, 0); MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); -static unsigned int wdt_trgr_pattern = 0x1234; -static DEFINE_SPINLOCK(wdt_lock); - struct omap_wdt_dev { void __iomem *base; /* physical */ struct device *dev; - int omap_wdt_users; + bool omap_wdt_users; struct resource *mem; - struct miscdevice omap_wdt_miscdev; + int wdt_trgr_pattern; + struct mutex lock; /* to avoid races with PM */ }; -static void omap_wdt_ping(struct omap_wdt_dev *wdev) +static void omap_wdt_reload(struct omap_wdt_dev *wdev) { void __iomem *base = wdev->base; @@ -76,8 +66,8 @@ static void omap_wdt_ping(struct omap_wdt_dev *wdev) while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08) cpu_relax(); - wdt_trgr_pattern = ~wdt_trgr_pattern; - __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR)); + wdev->wdt_trgr_pattern = ~wdev->wdt_trgr_pattern; + __raw_writel(wdev->wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR)); /* wait for posted write to complete */ while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08) @@ -113,18 +103,10 @@ static void omap_wdt_disable(struct omap_wdt_dev *wdev) cpu_relax(); } -static void omap_wdt_adjust_timeout(unsigned new_timeout) -{ - if (new_timeout < TIMER_MARGIN_MIN) - new_timeout = TIMER_MARGIN_DEFAULT; - if (new_timeout > TIMER_MARGIN_MAX) - new_timeout = TIMER_MARGIN_MAX; - timer_margin = new_timeout; -} - -static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev) +static void omap_wdt_set_timer(struct omap_wdt_dev *wdev, + unsigned int timeout) { - u32 pre_margin = GET_WLDR_VAL(timer_margin); + u32 pre_margin = GET_WLDR_VAL(timeout); void __iomem *base = wdev->base; /* just count up at 32 KHz */ @@ -136,16 +118,14 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev) cpu_relax(); } -/* - * Allow only one task to hold it open - */ -static int omap_wdt_open(struct inode *inode, struct file *file) +static int omap_wdt_start(struct watchdog_device *wdog) { - struct omap_wdt_dev *wdev = platform_get_drvdata(omap_wdt_dev); + struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); void __iomem *base = wdev->base; - if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users))) - return -EBUSY; + mutex_lock(&wdev->lock); + + wdev->omap_wdt_users = true; pm_runtime_get_sync(wdev->dev); @@ -157,225 +137,168 @@ static int omap_wdt_open(struct inode *inode, struct file *file) while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01) cpu_relax(); - file->private_data = (void *) wdev; - - omap_wdt_set_timeout(wdev); - omap_wdt_ping(wdev); /* trigger loading of new timeout value */ + omap_wdt_set_timer(wdev, wdog->timeout); + omap_wdt_reload(wdev); /* trigger loading of new timeout value */ omap_wdt_enable(wdev); - return nonseekable_open(inode, file); + mutex_unlock(&wdev->lock); + + return 0; } -static int omap_wdt_release(struct inode *inode, struct file *file) +static int omap_wdt_stop(struct watchdog_device *wdog) { - struct omap_wdt_dev *wdev = file->private_data; + struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); - /* - * Shut off the timer unless NOWAYOUT is defined. - */ -#ifndef CONFIG_WATCHDOG_NOWAYOUT + mutex_lock(&wdev->lock); omap_wdt_disable(wdev); - pm_runtime_put_sync(wdev->dev); -#else - pr_crit("Unexpected close, not stopping!\n"); -#endif - wdev->omap_wdt_users = 0; - + wdev->omap_wdt_users = false; + mutex_unlock(&wdev->lock); return 0; } -static ssize_t omap_wdt_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) +static int omap_wdt_ping(struct watchdog_device *wdog) { - struct omap_wdt_dev *wdev = file->private_data; + struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); - /* Refresh LOAD_TIME. */ - if (len) { - spin_lock(&wdt_lock); - omap_wdt_ping(wdev); - spin_unlock(&wdt_lock); - } - return len; + mutex_lock(&wdev->lock); + omap_wdt_reload(wdev); + mutex_unlock(&wdev->lock); + + return 0; } -static long omap_wdt_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) +static int omap_wdt_set_timeout(struct watchdog_device *wdog, + unsigned int timeout) { - struct omap_wdt_dev *wdev; - int new_margin; - static const struct watchdog_info ident = { - .identity = "OMAP Watchdog", - .options = WDIOF_SETTIMEOUT, - .firmware_version = 0, - }; - - wdev = file->private_data; - - switch (cmd) { - case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info __user *)arg, &ident, - sizeof(ident)); - case WDIOC_GETSTATUS: - return put_user(0, (int __user *)arg); - case WDIOC_GETBOOTSTATUS: -#ifdef CONFIG_ARCH_OMAP1 - if (cpu_is_omap16xx()) - return put_user(__raw_readw(ARM_SYSST), - (int __user *)arg); -#endif -#ifdef CONFIG_ARCH_OMAP2PLUS - if (cpu_is_omap24xx()) - return put_user(omap_prcm_get_reset_sources(), - (int __user *)arg); -#endif - return put_user(0, (int __user *)arg); - case WDIOC_KEEPALIVE: - spin_lock(&wdt_lock); - omap_wdt_ping(wdev); - spin_unlock(&wdt_lock); - return 0; - case WDIOC_SETTIMEOUT: - if (get_user(new_margin, (int __user *)arg)) - return -EFAULT; - omap_wdt_adjust_timeout(new_margin); - - spin_lock(&wdt_lock); - omap_wdt_disable(wdev); - omap_wdt_set_timeout(wdev); - omap_wdt_enable(wdev); + struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); - omap_wdt_ping(wdev); - spin_unlock(&wdt_lock); - /* Fall */ - case WDIOC_GETTIMEOUT: - return put_user(timer_margin, (int __user *)arg); - default: - return -ENOTTY; - } + mutex_lock(&wdev->lock); + omap_wdt_disable(wdev); + omap_wdt_set_timer(wdev, timeout); + omap_wdt_enable(wdev); + omap_wdt_reload(wdev); + wdog->timeout = timeout; + mutex_unlock(&wdev->lock); + + return 0; } -static const struct file_operations omap_wdt_fops = { - .owner = THIS_MODULE, - .write = omap_wdt_write, - .unlocked_ioctl = omap_wdt_ioctl, - .open = omap_wdt_open, - .release = omap_wdt_release, - .llseek = no_llseek, +static const struct watchdog_info omap_wdt_info = { + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, + .identity = "OMAP Watchdog", }; -static int __devinit omap_wdt_probe(struct platform_device *pdev) +static const struct watchdog_ops omap_wdt_ops = { + .owner = THIS_MODULE, + .start = omap_wdt_start, + .stop = omap_wdt_stop, + .ping = omap_wdt_ping, + .set_timeout = omap_wdt_set_timeout, +}; + +static int omap_wdt_probe(struct platform_device *pdev) { + struct omap_wd_timer_platform_data *pdata = pdev->dev.platform_data; + bool nowayout = WATCHDOG_NOWAYOUT; + struct watchdog_device *omap_wdt; struct resource *res, *mem; struct omap_wdt_dev *wdev; + u32 rs; int ret; + omap_wdt = devm_kzalloc(&pdev->dev, sizeof(*omap_wdt), GFP_KERNEL); + if (!omap_wdt) + return -ENOMEM; + /* reserve static register mappings */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENOENT; - goto err_get_resource; - } + if (!res) + return -ENOENT; - if (omap_wdt_dev) { - ret = -EBUSY; - goto err_busy; - } + mem = devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), pdev->name); + if (!mem) + return -EBUSY; - mem = request_mem_region(res->start, resource_size(res), pdev->name); - if (!mem) { - ret = -EBUSY; - goto err_busy; - } + wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL); + if (!wdev) + return -ENOMEM; - wdev = kzalloc(sizeof(struct omap_wdt_dev), GFP_KERNEL); - if (!wdev) { - ret = -ENOMEM; - goto err_kzalloc; - } + wdev->omap_wdt_users = false; + wdev->mem = mem; + wdev->dev = &pdev->dev; + wdev->wdt_trgr_pattern = 0x1234; + mutex_init(&wdev->lock); - wdev->omap_wdt_users = 0; - wdev->mem = mem; - wdev->dev = &pdev->dev; + wdev->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!wdev->base) + return -ENOMEM; - wdev->base = ioremap(res->start, resource_size(res)); - if (!wdev->base) { - ret = -ENOMEM; - goto err_ioremap; - } + omap_wdt->info = &omap_wdt_info; + omap_wdt->ops = &omap_wdt_ops; + omap_wdt->min_timeout = TIMER_MARGIN_MIN; + omap_wdt->max_timeout = TIMER_MARGIN_MAX; - platform_set_drvdata(pdev, wdev); + if (timer_margin >= TIMER_MARGIN_MIN && + timer_margin <= TIMER_MARGIN_MAX) + omap_wdt->timeout = timer_margin; + else + omap_wdt->timeout = TIMER_MARGIN_DEFAULT; + + watchdog_set_drvdata(omap_wdt, wdev); + watchdog_set_nowayout(omap_wdt, nowayout); + + platform_set_drvdata(pdev, omap_wdt); pm_runtime_enable(wdev->dev); pm_runtime_get_sync(wdev->dev); - omap_wdt_disable(wdev); - omap_wdt_adjust_timeout(timer_margin); + if (pdata && pdata->read_reset_sources) + rs = pdata->read_reset_sources(); + else + rs = 0; + omap_wdt->bootstatus = (rs & (1 << OMAP_MPU_WD_RST_SRC_ID_SHIFT)) ? + WDIOF_CARDRESET : 0; - wdev->omap_wdt_miscdev.parent = &pdev->dev; - wdev->omap_wdt_miscdev.minor = WATCHDOG_MINOR; - wdev->omap_wdt_miscdev.name = "watchdog"; - wdev->omap_wdt_miscdev.fops = &omap_wdt_fops; + omap_wdt_disable(wdev); - ret = misc_register(&(wdev->omap_wdt_miscdev)); - if (ret) - goto err_misc; + ret = watchdog_register_device(omap_wdt); + if (ret) { + pm_runtime_disable(wdev->dev); + return ret; + } pr_info("OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n", __raw_readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF, - timer_margin); + omap_wdt->timeout); pm_runtime_put_sync(wdev->dev); - omap_wdt_dev = pdev; - return 0; - -err_misc: - pm_runtime_disable(wdev->dev); - platform_set_drvdata(pdev, NULL); - iounmap(wdev->base); - -err_ioremap: - wdev->base = NULL; - kfree(wdev); - -err_kzalloc: - release_mem_region(res->start, resource_size(res)); - -err_busy: -err_get_resource: - - return ret; } static void omap_wdt_shutdown(struct platform_device *pdev) { - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); + struct watchdog_device *wdog = platform_get_drvdata(pdev); + struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); + mutex_lock(&wdev->lock); if (wdev->omap_wdt_users) { omap_wdt_disable(wdev); pm_runtime_put_sync(wdev->dev); } + mutex_unlock(&wdev->lock); } -static int __devexit omap_wdt_remove(struct platform_device *pdev) +static int omap_wdt_remove(struct platform_device *pdev) { - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct watchdog_device *wdog = platform_get_drvdata(pdev); + struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); pm_runtime_disable(wdev->dev); - if (!res) - return -ENOENT; - - misc_deregister(&(wdev->omap_wdt_miscdev)); - release_mem_region(res->start, resource_size(res)); - platform_set_drvdata(pdev, NULL); - - iounmap(wdev->base); - - kfree(wdev); - omap_wdt_dev = NULL; + watchdog_unregister_device(wdog); return 0; } @@ -390,25 +313,31 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev) static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state) { - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); + struct watchdog_device *wdog = platform_get_drvdata(pdev); + struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); + mutex_lock(&wdev->lock); if (wdev->omap_wdt_users) { omap_wdt_disable(wdev); pm_runtime_put_sync(wdev->dev); } + mutex_unlock(&wdev->lock); return 0; } static int omap_wdt_resume(struct platform_device *pdev) { - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); + struct watchdog_device *wdog = platform_get_drvdata(pdev); + struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); + mutex_lock(&wdev->lock); if (wdev->omap_wdt_users) { pm_runtime_get_sync(wdev->dev); omap_wdt_enable(wdev); - omap_wdt_ping(wdev); + omap_wdt_reload(wdev); } + mutex_unlock(&wdev->lock); return 0; } @@ -426,7 +355,7 @@ MODULE_DEVICE_TABLE(of, omap_wdt_of_match); static struct platform_driver omap_wdt_driver = { .probe = omap_wdt_probe, - .remove = __devexit_p(omap_wdt_remove), + .remove = omap_wdt_remove, .shutdown = omap_wdt_shutdown, .suspend = omap_wdt_suspend, .resume = omap_wdt_resume, @@ -441,5 +370,4 @@ module_platform_driver(omap_wdt_driver); MODULE_AUTHOR("George G. Davis"); MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); MODULE_ALIAS("platform:omap_wdt"); diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index c20f96b579d9..7c18b3bffcf7 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c @@ -142,7 +142,7 @@ static struct watchdog_device orion_wdt = { .ops = &orion_wdt_ops, }; -static int __devinit orion_wdt_probe(struct platform_device *pdev) +static int orion_wdt_probe(struct platform_device *pdev) { struct resource *res; int ret; @@ -156,6 +156,8 @@ static int __devinit orion_wdt_probe(struct platform_device *pdev) wdt_tclk = clk_get_rate(clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; wdt_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!wdt_reg) return -ENOMEM; @@ -181,7 +183,7 @@ static int __devinit orion_wdt_probe(struct platform_device *pdev) return 0; } -static int __devexit orion_wdt_remove(struct platform_device *pdev) +static int orion_wdt_remove(struct platform_device *pdev) { watchdog_unregister_device(&orion_wdt); clk_disable_unprepare(clk); @@ -193,7 +195,7 @@ static void orion_wdt_shutdown(struct platform_device *pdev) orion_wdt_stop(&orion_wdt); } -static const struct of_device_id orion_wdt_of_match_table[] __devinitdata = { +static const struct of_device_id orion_wdt_of_match_table[] = { { .compatible = "marvell,orion-wdt", }, {}, }; @@ -201,7 +203,7 @@ MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table); static struct platform_driver orion_wdt_driver = { .probe = orion_wdt_probe, - .remove = __devexit_p(orion_wdt_remove), + .remove = orion_wdt_remove, .shutdown = orion_wdt_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c index 75694cf24f86..33e49a7f889f 100644 --- a/drivers/watchdog/pcwd.c +++ b/drivers/watchdog/pcwd.c @@ -801,7 +801,7 @@ static inline int get_revision(void) * The initial rate is once per second at board start up, then twice * per second for normal operation. */ -static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) +static int pcwd_isa_match(struct device *dev, unsigned int id) { int base_addr = pcwd_ioports[id]; int port0, last_port0; /* Reg 0, in case it's REV A */ @@ -846,7 +846,7 @@ static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) return retval; } -static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id) +static int pcwd_isa_probe(struct device *dev, unsigned int id) { int ret; @@ -949,7 +949,7 @@ error_request_region: return ret; } -static int __devexit pcwd_isa_remove(struct device *dev, unsigned int id) +static int pcwd_isa_remove(struct device *dev, unsigned int id) { if (debug >= DEBUG) pr_debug("pcwd_isa_remove id=%d\n", id); @@ -984,7 +984,7 @@ static void pcwd_isa_shutdown(struct device *dev, unsigned int id) static struct isa_driver pcwd_isa_driver = { .match = pcwd_isa_match, .probe = pcwd_isa_probe, - .remove = __devexit_p(pcwd_isa_remove), + .remove = pcwd_isa_remove, .shutdown = pcwd_isa_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c index ee6900da8678..7890f84edf76 100644 --- a/drivers/watchdog/pcwd_pci.c +++ b/drivers/watchdog/pcwd_pci.c @@ -682,7 +682,7 @@ static struct notifier_block pcipcwd_notifier = { * Init & exit routines */ -static int __devinit pcipcwd_card_init(struct pci_dev *pdev, +static int pcipcwd_card_init(struct pci_dev *pdev, const struct pci_device_id *ent) { int ret = -EIO; @@ -785,7 +785,7 @@ err_out_disable_device: return ret; } -static void __devexit pcipcwd_card_exit(struct pci_dev *pdev) +static void pcipcwd_card_exit(struct pci_dev *pdev) { /* Stop the timer before we leave */ if (!nowayout) @@ -812,7 +812,7 @@ static struct pci_driver pcipcwd_driver = { .name = WATCHDOG_NAME, .id_table = pcipcwd_pci_tbl, .probe = pcipcwd_card_init, - .remove = __devexit_p(pcipcwd_card_exit), + .remove = pcipcwd_card_exit, }; module_pci_driver(pcipcwd_driver); diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 87722e126058..dcba5dab6c29 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -146,7 +146,7 @@ static struct watchdog_device pnx4008_wdd = { .max_timeout = MAX_HEARTBEAT, }; -static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) +static int pnx4008_wdt_probe(struct platform_device *pdev) { struct resource *r; int ret = 0; @@ -192,7 +192,7 @@ out: return ret; } -static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) +static int pnx4008_wdt_remove(struct platform_device *pdev) { watchdog_unregister_device(&pnx4008_wdd); @@ -217,7 +217,7 @@ static struct platform_driver platform_wdt_driver = { .of_match_table = of_match_ptr(pnx4008_wdt_match), }, .probe = pnx4008_wdt_probe, - .remove = __devexit_p(pnx4008_wdt_remove), + .remove = pnx4008_wdt_remove, }; module_platform_driver(platform_wdt_driver); diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index 547353a50ebb..f78bc008cbb7 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c @@ -260,7 +260,7 @@ static struct miscdevice rc32434_wdt_miscdev = { .fops = &rc32434_wdt_fops, }; -static int __devinit rc32434_wdt_probe(struct platform_device *pdev) +static int rc32434_wdt_probe(struct platform_device *pdev) { int ret; struct resource *r; @@ -306,7 +306,7 @@ unmap: return ret; } -static int __devexit rc32434_wdt_remove(struct platform_device *pdev) +static int rc32434_wdt_remove(struct platform_device *pdev) { misc_deregister(&rc32434_wdt_miscdev); iounmap(wdt_reg); @@ -320,7 +320,7 @@ static void rc32434_wdt_shutdown(struct platform_device *pdev) static struct platform_driver rc32434_wdt_driver = { .probe = rc32434_wdt_probe, - .remove = __devexit_p(rc32434_wdt_remove), + .remove = rc32434_wdt_remove, .shutdown = rc32434_wdt_shutdown, .driver = { .name = "rc32434_wdt", diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 042ccc56ae26..b0f116c2fd53 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -225,7 +225,7 @@ static struct miscdevice rdc321x_wdt_misc = { .fops = &rdc321x_wdt_fops, }; -static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) +static int rdc321x_wdt_probe(struct platform_device *pdev) { int err; struct resource *r; @@ -272,7 +272,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) return 0; } -static int __devexit rdc321x_wdt_remove(struct platform_device *pdev) +static int rdc321x_wdt_remove(struct platform_device *pdev) { if (rdc321x_wdt_device.queue) { rdc321x_wdt_device.queue = 0; @@ -286,7 +286,7 @@ static int __devexit rdc321x_wdt_remove(struct platform_device *pdev) static struct platform_driver rdc321x_wdt_driver = { .probe = rdc321x_wdt_probe, - .remove = __devexit_p(rdc321x_wdt_remove), + .remove = rdc321x_wdt_remove, .driver = { .owner = THIS_MODULE, .name = "rdc321x-wdt", diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index 49e1b1c2135c..0040451aec1d 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -174,7 +174,7 @@ static struct miscdevice riowd_miscdev = { .fops = &riowd_fops }; -static int __devinit riowd_probe(struct platform_device *op) +static int riowd_probe(struct platform_device *op) { struct riowd *p; int err = -EINVAL; @@ -220,7 +220,7 @@ out: return err; } -static int __devexit riowd_remove(struct platform_device *op) +static int riowd_remove(struct platform_device *op) { struct riowd *p = dev_get_drvdata(&op->dev); @@ -246,7 +246,7 @@ static struct platform_driver riowd_driver = { .of_match_table = riowd_match, }, .probe = riowd_probe, - .remove = __devexit_p(riowd_remove), + .remove = riowd_remove, }; module_platform_driver(riowd_driver); diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 9245b4d23bfe..27bcd4e2c4a4 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -303,7 +303,7 @@ static inline void s3c2410wdt_cpufreq_deregister(void) } #endif -static int __devinit s3c2410wdt_probe(struct platform_device *pdev) +static int s3c2410wdt_probe(struct platform_device *pdev) { struct device *dev; unsigned int wtcon; @@ -354,7 +354,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) goto err_map; } - clk_enable(wdt_clock); + clk_prepare_enable(wdt_clock); ret = s3c2410wdt_cpufreq_register(); if (ret < 0) { @@ -421,7 +421,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) s3c2410wdt_cpufreq_deregister(); err_clk: - clk_disable(wdt_clock); + clk_disable_unprepare(wdt_clock); clk_put(wdt_clock); wdt_clock = NULL; @@ -437,7 +437,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) return ret; } -static int __devexit s3c2410wdt_remove(struct platform_device *dev) +static int s3c2410wdt_remove(struct platform_device *dev) { watchdog_unregister_device(&s3c2410_wdd); @@ -445,7 +445,7 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev) s3c2410wdt_cpufreq_deregister(); - clk_disable(wdt_clock); + clk_disable_unprepare(wdt_clock); clk_put(wdt_clock); wdt_clock = NULL; @@ -508,7 +508,7 @@ MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); static struct platform_driver s3c2410wdt_driver = { .probe = s3c2410wdt_probe, - .remove = __devexit_p(s3c2410wdt_remove), + .remove = s3c2410wdt_remove, .shutdown = s3c2410wdt_shutdown, .suspend = s3c2410wdt_suspend, .resume = s3c2410wdt_resume, diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index 9681ada0f252..af7b136b1874 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c @@ -356,7 +356,7 @@ static struct miscdevice sch311x_wdt_miscdev = { * Init & exit routines */ -static int __devinit sch311x_wdt_probe(struct platform_device *pdev) +static int sch311x_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; int err; @@ -429,7 +429,7 @@ exit: return err; } -static int __devexit sch311x_wdt_remove(struct platform_device *pdev) +static int sch311x_wdt_remove(struct platform_device *pdev) { /* Stop the timer before we leave */ if (!nowayout) @@ -451,7 +451,7 @@ static void sch311x_wdt_shutdown(struct platform_device *dev) static struct platform_driver sch311x_wdt_driver = { .probe = sch311x_wdt_probe, - .remove = __devexit_p(sch311x_wdt_remove), + .remove = sch311x_wdt_remove, .shutdown = sch311x_wdt_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index e5b59bebcdb1..6a89e4045fbd 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -217,7 +217,7 @@ static struct watchdog_device sh_wdt_dev = { .ops = &sh_wdt_ops, }; -static int __devinit sh_wdt_probe(struct platform_device *pdev) +static int sh_wdt_probe(struct platform_device *pdev) { struct sh_wdt *wdt; struct resource *res; @@ -298,7 +298,7 @@ err: return rc; } -static int __devexit sh_wdt_remove(struct platform_device *pdev) +static int sh_wdt_remove(struct platform_device *pdev) { struct sh_wdt *wdt = platform_get_drvdata(pdev); @@ -324,7 +324,7 @@ static struct platform_driver sh_wdt_driver = { }, .probe = sh_wdt_probe, - .remove = __devexit_p(sh_wdt_remove), + .remove = sh_wdt_remove, .shutdown = sh_wdt_shutdown, }; diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c index ae5e82cb83fa..2b0e000d4377 100644 --- a/drivers/watchdog/sp5100_tco.c +++ b/drivers/watchdog/sp5100_tco.c @@ -13,7 +13,9 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * See AMD Publication 43009 "AMD SB700/710/750 Register Reference Guide" + * See AMD Publication 43009 "AMD SB700/710/750 Register Reference Guide", + * AMD Publication 45482 "AMD SB800-Series Southbridges Register + * Reference Guide" */ /* @@ -38,18 +40,24 @@ #include "sp5100_tco.h" /* Module and version information */ -#define TCO_VERSION "0.01" +#define TCO_VERSION "0.03" #define TCO_MODULE_NAME "SP5100 TCO timer" #define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION /* internal variables */ static u32 tcobase_phys; +static u32 resbase_phys; +static u32 tco_wdt_fired; static void __iomem *tcobase; static unsigned int pm_iobase; static DEFINE_SPINLOCK(tco_lock); /* Guards the hardware */ static unsigned long timer_alive; static char tco_expect_close; static struct pci_dev *sp5100_tco_pci; +static struct resource wdt_res = { + .name = "Watchdog Timer", + .flags = IORESOURCE_MEM, +}; /* the watchdog platform device */ static struct platform_device *sp5100_tco_platform_device; @@ -64,9 +72,15 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default=" static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started" +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started." " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +static unsigned int force_addr; +module_param(force_addr, uint, 0); +MODULE_PARM_DESC(force_addr, "Force the use of specified MMIO address." + " ONLY USE THIS PARAMETER IF YOU REALLY KNOW" + " WHAT YOU ARE DOING (default=none)"); + /* * Some TCO specific functions */ @@ -122,6 +136,79 @@ static int tco_timer_set_heartbeat(int t) return 0; } +static void tco_timer_enable(void) +{ + int val; + + if (sp5100_tco_pci->revision >= 0x40) { + /* For SB800 or later */ + /* Set the Watchdog timer resolution to 1 sec */ + outb(SB800_PM_WATCHDOG_CONFIG, SB800_IO_PM_INDEX_REG); + val = inb(SB800_IO_PM_DATA_REG); + val |= SB800_PM_WATCHDOG_SECOND_RES; + outb(val, SB800_IO_PM_DATA_REG); + + /* Enable watchdog decode bit and watchdog timer */ + outb(SB800_PM_WATCHDOG_CONTROL, SB800_IO_PM_INDEX_REG); + val = inb(SB800_IO_PM_DATA_REG); + val |= SB800_PCI_WATCHDOG_DECODE_EN; + val &= ~SB800_PM_WATCHDOG_DISABLE; + outb(val, SB800_IO_PM_DATA_REG); + } else { + /* For SP5100 or SB7x0 */ + /* Enable watchdog decode bit */ + pci_read_config_dword(sp5100_tco_pci, + SP5100_PCI_WATCHDOG_MISC_REG, + &val); + + val |= SP5100_PCI_WATCHDOG_DECODE_EN; + + pci_write_config_dword(sp5100_tco_pci, + SP5100_PCI_WATCHDOG_MISC_REG, + val); + + /* Enable Watchdog timer and set the resolution to 1 sec */ + outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG); + val = inb(SP5100_IO_PM_DATA_REG); + val |= SP5100_PM_WATCHDOG_SECOND_RES; + val &= ~SP5100_PM_WATCHDOG_DISABLE; + outb(val, SP5100_IO_PM_DATA_REG); + } +} + +static void tco_timer_disable(void) +{ + int val; + + if (sp5100_tco_pci->revision >= 0x40) { + /* For SB800 or later */ + /* Enable watchdog decode bit and Disable watchdog timer */ + outb(SB800_PM_WATCHDOG_CONTROL, SB800_IO_PM_INDEX_REG); + val = inb(SB800_IO_PM_DATA_REG); + val |= SB800_PCI_WATCHDOG_DECODE_EN; + val |= SB800_PM_WATCHDOG_DISABLE; + outb(val, SB800_IO_PM_DATA_REG); + } else { + /* For SP5100 or SB7x0 */ + /* Enable watchdog decode bit */ + pci_read_config_dword(sp5100_tco_pci, + SP5100_PCI_WATCHDOG_MISC_REG, + &val); + + val |= SP5100_PCI_WATCHDOG_DECODE_EN; + + pci_write_config_dword(sp5100_tco_pci, + SP5100_PCI_WATCHDOG_MISC_REG, + val); + + /* Disable Watchdog timer */ + outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG); + val = inb(SP5100_IO_PM_DATA_REG); + val |= SP5100_PM_WATCHDOG_DISABLE; + outb(val, SP5100_IO_PM_DATA_REG); + } +} + /* * /dev/watchdog handling */ @@ -270,11 +357,12 @@ MODULE_DEVICE_TABLE(pci, sp5100_tco_pci_tbl); /* * Init & exit routines */ - -static unsigned char __devinit sp5100_tco_setupdevice(void) +static unsigned char sp5100_tco_setupdevice(void) { struct pci_dev *dev = NULL; + const char *dev_name = NULL; u32 val; + u32 index_reg, data_reg, base_addr; /* Match the PCI device */ for_each_pci_dev(dev) { @@ -287,29 +375,160 @@ static unsigned char __devinit sp5100_tco_setupdevice(void) if (!sp5100_tco_pci) return 0; + pr_info("PCI Revision ID: 0x%x\n", sp5100_tco_pci->revision); + + /* + * Determine type of southbridge chipset. + */ + if (sp5100_tco_pci->revision >= 0x40) { + dev_name = SB800_DEVNAME; + index_reg = SB800_IO_PM_INDEX_REG; + data_reg = SB800_IO_PM_DATA_REG; + base_addr = SB800_PM_WATCHDOG_BASE; + } else { + dev_name = SP5100_DEVNAME; + index_reg = SP5100_IO_PM_INDEX_REG; + data_reg = SP5100_IO_PM_DATA_REG; + base_addr = SP5100_PM_WATCHDOG_BASE; + } + /* Request the IO ports used by this driver */ pm_iobase = SP5100_IO_PM_INDEX_REG; - if (!request_region(pm_iobase, SP5100_PM_IOPORTS_SIZE, "SP5100 TCO")) { + if (!request_region(pm_iobase, SP5100_PM_IOPORTS_SIZE, dev_name)) { pr_err("I/O address 0x%04x already in use\n", pm_iobase); goto exit; } - /* Find the watchdog base address. */ - outb(SP5100_PM_WATCHDOG_BASE3, SP5100_IO_PM_INDEX_REG); - val = inb(SP5100_IO_PM_DATA_REG); - outb(SP5100_PM_WATCHDOG_BASE2, SP5100_IO_PM_INDEX_REG); - val = val << 8 | inb(SP5100_IO_PM_DATA_REG); - outb(SP5100_PM_WATCHDOG_BASE1, SP5100_IO_PM_INDEX_REG); - val = val << 8 | inb(SP5100_IO_PM_DATA_REG); - outb(SP5100_PM_WATCHDOG_BASE0, SP5100_IO_PM_INDEX_REG); - /* Low three bits of BASE0 are reserved. */ - val = val << 8 | (inb(SP5100_IO_PM_DATA_REG) & 0xf8); + /* + * First, Find the watchdog timer MMIO address from indirect I/O. + */ + outb(base_addr+3, index_reg); + val = inb(data_reg); + outb(base_addr+2, index_reg); + val = val << 8 | inb(data_reg); + outb(base_addr+1, index_reg); + val = val << 8 | inb(data_reg); + outb(base_addr+0, index_reg); + /* Low three bits of BASE are reserved */ + val = val << 8 | (inb(data_reg) & 0xf8); + + pr_debug("Got 0x%04x from indirect I/O\n", val); + + /* Check MMIO address conflict */ + if (request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, + dev_name)) + goto setup_wdt; + else + pr_debug("MMIO address 0x%04x already in use\n", val); + + /* + * Secondly, Find the watchdog timer MMIO address + * from SBResource_MMIO register. + */ + if (sp5100_tco_pci->revision >= 0x40) { + /* Read SBResource_MMIO from AcpiMmioEn(PM_Reg: 24h) */ + outb(SB800_PM_ACPI_MMIO_EN+3, SB800_IO_PM_INDEX_REG); + val = inb(SB800_IO_PM_DATA_REG); + outb(SB800_PM_ACPI_MMIO_EN+2, SB800_IO_PM_INDEX_REG); + val = val << 8 | inb(SB800_IO_PM_DATA_REG); + outb(SB800_PM_ACPI_MMIO_EN+1, SB800_IO_PM_INDEX_REG); + val = val << 8 | inb(SB800_IO_PM_DATA_REG); + outb(SB800_PM_ACPI_MMIO_EN+0, SB800_IO_PM_INDEX_REG); + val = val << 8 | inb(SB800_IO_PM_DATA_REG); + } else { + /* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */ + pci_read_config_dword(sp5100_tco_pci, + SP5100_SB_RESOURCE_MMIO_BASE, &val); + } + + /* The SBResource_MMIO is enabled and mapped memory space? */ + if ((val & (SB800_ACPI_MMIO_DECODE_EN | SB800_ACPI_MMIO_SEL)) == + SB800_ACPI_MMIO_DECODE_EN) { + /* Clear unnecessary the low twelve bits */ + val &= ~0xFFF; + /* Add the Watchdog Timer offset to base address. */ + val += SB800_PM_WDT_MMIO_OFFSET; + /* Check MMIO address conflict */ + if (request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, + dev_name)) { + pr_debug("Got 0x%04x from SBResource_MMIO register\n", + val); + goto setup_wdt; + } else + pr_debug("MMIO address 0x%04x already in use\n", val); + } else + pr_debug("SBResource_MMIO is disabled(0x%04x)\n", val); + + /* + * Lastly re-programming the watchdog timer MMIO address, + * This method is a last resort... + * + * Before re-programming, to ensure that the watchdog timer + * is disabled, disable the watchdog timer. + */ + tco_timer_disable(); + + if (force_addr) { + /* + * Force the use of watchdog timer MMIO address, and aligned to + * 8byte boundary. + */ + force_addr &= ~0x7; + val = force_addr; + + pr_info("Force the use of 0x%04x as MMIO address\n", val); + } else { + /* + * Get empty slot into the resource tree for watchdog timer. + */ + if (allocate_resource(&iomem_resource, + &wdt_res, + SP5100_WDT_MEM_MAP_SIZE, + 0xf0000000, + 0xfffffff8, + 0x8, + NULL, + NULL)) { + pr_err("MMIO allocation failed\n"); + goto unreg_region; + } + + val = resbase_phys = wdt_res.start; + pr_debug("Got 0x%04x from resource tree\n", val); + } + + /* Restore to the low three bits, if chipset is SB8x0(or later) */ + if (sp5100_tco_pci->revision >= 0x40) { + u8 reserved_bit; + reserved_bit = inb(base_addr) & 0x7; + val |= (u32)reserved_bit; + } + + /* Re-programming the watchdog timer base address */ + outb(base_addr+0, index_reg); + /* Low three bits of BASE are reserved */ + outb((val >> 0) & 0xf8, data_reg); + outb(base_addr+1, index_reg); + outb((val >> 8) & 0xff, data_reg); + outb(base_addr+2, index_reg); + outb((val >> 16) & 0xff, data_reg); + outb(base_addr+3, index_reg); + outb((val >> 24) & 0xff, data_reg); + + /* + * Clear unnecessary the low three bits, + * if chipset is SB8x0(or later) + */ + if (sp5100_tco_pci->revision >= 0x40) + val &= ~0x7; if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, - "SP5100 TCO")) { - pr_err("mmio address 0x%04x already in use\n", val); - goto unreg_region; + dev_name)) { + pr_err("MMIO address 0x%04x already in use\n", val); + goto unreg_resource; } + +setup_wdt: tcobase_phys = val; tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE); @@ -318,26 +537,18 @@ static unsigned char __devinit sp5100_tco_setupdevice(void) goto unreg_mem_region; } - /* Enable watchdog decode bit */ - pci_read_config_dword(sp5100_tco_pci, - SP5100_PCI_WATCHDOG_MISC_REG, - &val); - - val |= SP5100_PCI_WATCHDOG_DECODE_EN; + pr_info("Using 0x%04x for watchdog MMIO address\n", val); - pci_write_config_dword(sp5100_tco_pci, - SP5100_PCI_WATCHDOG_MISC_REG, - val); + /* Setup the watchdog timer */ + tco_timer_enable(); - /* Enable Watchdog timer and set the resolution to 1 sec. */ - outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG); - val = inb(SP5100_IO_PM_DATA_REG); - val |= SP5100_PM_WATCHDOG_SECOND_RES; - val &= ~SP5100_PM_WATCHDOG_DISABLE; - outb(val, SP5100_IO_PM_DATA_REG); - - /* Check that the watchdog action is set to reset the system. */ + /* Check that the watchdog action is set to reset the system */ val = readl(SP5100_WDT_CONTROL(tcobase)); + /* + * Save WatchDogFired status, because WatchDogFired flag is + * cleared here. + */ + tco_wdt_fired = val & SP5100_PM_WATCHDOG_FIRED; val &= ~SP5100_PM_WATCHDOG_ACTION_RESET; writel(val, SP5100_WDT_CONTROL(tcobase)); @@ -355,32 +566,30 @@ static unsigned char __devinit sp5100_tco_setupdevice(void) unreg_mem_region: release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); +unreg_resource: + if (resbase_phys) + release_resource(&wdt_res); unreg_region: release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); exit: return 0; } -static int __devinit sp5100_tco_init(struct platform_device *dev) +static int sp5100_tco_init(struct platform_device *dev) { int ret; - u32 val; + char addr_str[16]; - /* Check whether or not the hardware watchdog is there. If found, then + /* + * Check whether or not the hardware watchdog is there. If found, then * set it up. */ if (!sp5100_tco_setupdevice()) return -ENODEV; /* Check to see if last reboot was due to watchdog timeout */ - pr_info("Watchdog reboot %sdetected\n", - readl(SP5100_WDT_CONTROL(tcobase)) & SP5100_PM_WATCHDOG_FIRED ? - "" : "not "); - - /* Clear out the old status */ - val = readl(SP5100_WDT_CONTROL(tcobase)); - val &= ~SP5100_PM_WATCHDOG_FIRED; - writel(val, SP5100_WDT_CONTROL(tcobase)); + pr_info("Last reboot was %striggered by watchdog.\n", + tco_wdt_fired ? "" : "not "); /* * Check that the heartbeat value is within it's range. @@ -400,19 +609,29 @@ static int __devinit sp5100_tco_init(struct platform_device *dev) clear_bit(0, &timer_alive); - pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", - tcobase, heartbeat, nowayout); + /* Show module parameters */ + if (force_addr == tcobase_phys) + /* The force_addr is vaild */ + sprintf(addr_str, "0x%04x", force_addr); + else + strcpy(addr_str, "none"); + + pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d, " + "force_addr=%s)\n", + tcobase, heartbeat, nowayout, addr_str); return 0; exit: iounmap(tcobase); release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); + if (resbase_phys) + release_resource(&wdt_res); release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); return ret; } -static void __devexit sp5100_tco_cleanup(void) +static void sp5100_tco_cleanup(void) { /* Stop the timer before we leave */ if (!nowayout) @@ -422,10 +641,12 @@ static void __devexit sp5100_tco_cleanup(void) misc_deregister(&sp5100_tco_miscdev); iounmap(tcobase); release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); + if (resbase_phys) + release_resource(&wdt_res); release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); } -static int __devexit sp5100_tco_remove(struct platform_device *dev) +static int sp5100_tco_remove(struct platform_device *dev) { if (tcobase) sp5100_tco_cleanup(); @@ -439,7 +660,7 @@ static void sp5100_tco_shutdown(struct platform_device *dev) static struct platform_driver sp5100_tco_driver = { .probe = sp5100_tco_init, - .remove = __devexit_p(sp5100_tco_remove), + .remove = sp5100_tco_remove, .shutdown = sp5100_tco_shutdown, .driver = { .owner = THIS_MODULE, @@ -451,7 +672,7 @@ static int __init sp5100_tco_init_module(void) { int err; - pr_info("SP5100 TCO WatchDog Timer Driver v%s\n", TCO_VERSION); + pr_info("SP5100/SB800 TCO WatchDog Timer Driver v%s\n", TCO_VERSION); err = platform_driver_register(&sp5100_tco_driver); if (err) @@ -475,13 +696,13 @@ static void __exit sp5100_tco_cleanup_module(void) { platform_device_unregister(sp5100_tco_platform_device); platform_driver_unregister(&sp5100_tco_driver); - pr_info("SP5100 TCO Watchdog Module Unloaded\n"); + pr_info("SP5100/SB800 TCO Watchdog Module Unloaded\n"); } module_init(sp5100_tco_init_module); module_exit(sp5100_tco_cleanup_module); MODULE_AUTHOR("Priyanka Gupta"); -MODULE_DESCRIPTION("TCO timer driver for SP5100 chipset"); +MODULE_DESCRIPTION("TCO timer driver for SP5100/SB800 chipset"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/drivers/watchdog/sp5100_tco.h b/drivers/watchdog/sp5100_tco.h index a5a16cc90a34..71594a0c14b7 100644 --- a/drivers/watchdog/sp5100_tco.h +++ b/drivers/watchdog/sp5100_tco.h @@ -9,33 +9,57 @@ /* * Some address definitions for the Watchdog */ - #define SP5100_WDT_MEM_MAP_SIZE 0x08 #define SP5100_WDT_CONTROL(base) ((base) + 0x00) /* Watchdog Control */ #define SP5100_WDT_COUNT(base) ((base) + 0x04) /* Watchdog Count */ -#define SP5100_WDT_START_STOP_BIT 1 +#define SP5100_WDT_START_STOP_BIT (1 << 0) #define SP5100_WDT_TRIGGER_BIT (1 << 7) -#define SP5100_PCI_WATCHDOG_MISC_REG 0x41 -#define SP5100_PCI_WATCHDOG_DECODE_EN (1 << 3) - #define SP5100_PM_IOPORTS_SIZE 0x02 -/* These two IO registers are hardcoded and there doesn't seem to be a way to +/* + * These two IO registers are hardcoded and there doesn't seem to be a way to * read them from a register. */ + +/* For SP5100/SB7x0 chipset */ #define SP5100_IO_PM_INDEX_REG 0xCD6 #define SP5100_IO_PM_DATA_REG 0xCD7 +#define SP5100_SB_RESOURCE_MMIO_BASE 0x9C + #define SP5100_PM_WATCHDOG_CONTROL 0x69 -#define SP5100_PM_WATCHDOG_BASE0 0x6C -#define SP5100_PM_WATCHDOG_BASE1 0x6D -#define SP5100_PM_WATCHDOG_BASE2 0x6E -#define SP5100_PM_WATCHDOG_BASE3 0x6F +#define SP5100_PM_WATCHDOG_BASE 0x6C #define SP5100_PM_WATCHDOG_FIRED (1 << 1) #define SP5100_PM_WATCHDOG_ACTION_RESET (1 << 2) -#define SP5100_PM_WATCHDOG_DISABLE 1 +#define SP5100_PCI_WATCHDOG_MISC_REG 0x41 +#define SP5100_PCI_WATCHDOG_DECODE_EN (1 << 3) + +#define SP5100_PM_WATCHDOG_DISABLE (1 << 0) #define SP5100_PM_WATCHDOG_SECOND_RES (3 << 1) + +#define SP5100_DEVNAME "SP5100 TCO" + + +/* For SB8x0(or later) chipset */ +#define SB800_IO_PM_INDEX_REG 0xCD6 +#define SB800_IO_PM_DATA_REG 0xCD7 + +#define SB800_PM_ACPI_MMIO_EN 0x24 +#define SB800_PM_WATCHDOG_CONTROL 0x48 +#define SB800_PM_WATCHDOG_BASE 0x48 +#define SB800_PM_WATCHDOG_CONFIG 0x4C + +#define SB800_PCI_WATCHDOG_DECODE_EN (1 << 0) +#define SB800_PM_WATCHDOG_DISABLE (1 << 2) +#define SB800_PM_WATCHDOG_SECOND_RES (3 << 0) +#define SB800_ACPI_MMIO_DECODE_EN (1 << 0) +#define SB800_ACPI_MMIO_SEL (1 << 2) + + +#define SB800_PM_WDT_MMIO_OFFSET 0xB00 + +#define SB800_DEVNAME "SB800 TCO" diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index e4841c36798b..8872642505c0 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -130,16 +130,10 @@ static int wdt_config(struct watchdog_device *wdd, bool ping) int ret; if (!ping) { - ret = clk_prepare(wdt->clk); - if (ret) { - dev_err(&wdt->adev->dev, "clock prepare fail"); - return ret; - } - ret = clk_enable(wdt->clk); + ret = clk_prepare_enable(wdt->clk); if (ret) { dev_err(&wdt->adev->dev, "clock enable fail"); - clk_unprepare(wdt->clk); return ret; } } @@ -190,8 +184,7 @@ static int wdt_disable(struct watchdog_device *wdd) readl_relaxed(wdt->base + WDTLOCK); spin_unlock(&wdt->lock); - clk_disable(wdt->clk); - clk_unprepare(wdt->clk); + clk_disable_unprepare(wdt->clk); return 0; } @@ -210,7 +203,7 @@ static const struct watchdog_ops wdt_ops = { .get_timeleft = wdt_timeleft, }; -static int __devinit +static int sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id) { struct sp805_wdt *wdt; @@ -272,7 +265,7 @@ err: return ret; } -static int __devexit sp805_wdt_remove(struct amba_device *adev) +static int sp805_wdt_remove(struct amba_device *adev) { struct sp805_wdt *wdt = amba_get_drvdata(adev); @@ -284,8 +277,7 @@ static int __devexit sp805_wdt_remove(struct amba_device *adev) return 0; } -#ifdef CONFIG_PM -static int sp805_wdt_suspend(struct device *dev) +static int __maybe_unused sp805_wdt_suspend(struct device *dev) { struct sp805_wdt *wdt = dev_get_drvdata(dev); @@ -295,7 +287,7 @@ static int sp805_wdt_suspend(struct device *dev) return 0; } -static int sp805_wdt_resume(struct device *dev) +static int __maybe_unused sp805_wdt_resume(struct device *dev) { struct sp805_wdt *wdt = dev_get_drvdata(dev); @@ -304,7 +296,6 @@ static int sp805_wdt_resume(struct device *dev) return 0; } -#endif /* CONFIG_PM */ static SIMPLE_DEV_PM_OPS(sp805_wdt_dev_pm_ops, sp805_wdt_suspend, sp805_wdt_resume); @@ -326,7 +317,7 @@ static struct amba_driver sp805_wdt_driver = { }, .id_table = sp805_wdt_ids, .probe = sp805_wdt_probe, - .remove = __devexit_p(sp805_wdt_remove), + .remove = sp805_wdt_remove, }; module_amba_driver(sp805_wdt_driver); diff --git a/drivers/watchdog/stmp3xxx_wdt.c b/drivers/watchdog/stmp3xxx_wdt.c index 21d96b92bfd7..1f4f69728fee 100644 --- a/drivers/watchdog/stmp3xxx_wdt.c +++ b/drivers/watchdog/stmp3xxx_wdt.c @@ -204,7 +204,7 @@ static struct miscdevice stmp3xxx_wdt_miscdev = { .fops = &stmp3xxx_wdt_fops, }; -static int __devinit stmp3xxx_wdt_probe(struct platform_device *pdev) +static int stmp3xxx_wdt_probe(struct platform_device *pdev) { int ret = 0; @@ -229,7 +229,7 @@ static int __devinit stmp3xxx_wdt_probe(struct platform_device *pdev) return ret; } -static int __devexit stmp3xxx_wdt_remove(struct platform_device *pdev) +static int stmp3xxx_wdt_remove(struct platform_device *pdev) { misc_deregister(&stmp3xxx_wdt_miscdev); return 0; @@ -269,7 +269,7 @@ static struct platform_driver platform_wdt_driver = { .name = "stmp3xxx_wdt", }, .probe = stmp3xxx_wdt_probe, - .remove = __devexit_p(stmp3xxx_wdt_remove), + .remove = stmp3xxx_wdt_remove, .suspend = stmp3xxx_wdt_suspend, .resume = stmp3xxx_wdt_resume, }; diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c index 8df050d800e6..b8a92459f10f 100644 --- a/drivers/watchdog/ts72xx_wdt.c +++ b/drivers/watchdog/ts72xx_wdt.c @@ -390,7 +390,7 @@ static struct miscdevice ts72xx_wdt_miscdev = { .fops = &ts72xx_wdt_fops, }; -static __devinit int ts72xx_wdt_probe(struct platform_device *pdev) +static int ts72xx_wdt_probe(struct platform_device *pdev) { struct ts72xx_wdt *wdt; struct resource *r1, *r2; @@ -476,7 +476,7 @@ fail: return error; } -static __devexit int ts72xx_wdt_remove(struct platform_device *pdev) +static int ts72xx_wdt_remove(struct platform_device *pdev) { struct ts72xx_wdt *wdt = platform_get_drvdata(pdev); struct resource *res; @@ -499,7 +499,7 @@ static __devexit int ts72xx_wdt_remove(struct platform_device *pdev) static struct platform_driver ts72xx_wdt_driver = { .probe = ts72xx_wdt_probe, - .remove = __devexit_p(ts72xx_wdt_remove), + .remove = ts72xx_wdt_remove, .driver = { .name = "ts72xx-wdt", .owner = THIS_MODULE, diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c index 249f11305d26..0f03106f7516 100644 --- a/drivers/watchdog/twl4030_wdt.c +++ b/drivers/watchdog/twl4030_wdt.c @@ -22,26 +22,12 @@ #include <linux/types.h> #include <linux/slab.h> #include <linux/kernel.h> -#include <linux/fs.h> #include <linux/watchdog.h> #include <linux/platform_device.h> -#include <linux/miscdevice.h> -#include <linux/uaccess.h> #include <linux/i2c/twl.h> #define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3 -#define TWL4030_WDT_STATE_OPEN 0x1 -#define TWL4030_WDT_STATE_ACTIVE 0x8 - -static struct platform_device *twl4030_wdt_dev; - -struct twl4030_wdt { - struct miscdevice miscdev; - int timer_margin; - unsigned long state; -}; - static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " @@ -49,175 +35,75 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " static int twl4030_wdt_write(unsigned char val) { - return twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val, + return twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, val, TWL4030_WATCHDOG_CFG_REG_OFFS); } -static int twl4030_wdt_enable(struct twl4030_wdt *wdt) +static int twl4030_wdt_start(struct watchdog_device *wdt) { - return twl4030_wdt_write(wdt->timer_margin + 1); + return twl4030_wdt_write(wdt->timeout + 1); } -static int twl4030_wdt_disable(struct twl4030_wdt *wdt) +static int twl4030_wdt_stop(struct watchdog_device *wdt) { return twl4030_wdt_write(0); } -static int twl4030_wdt_set_timeout(struct twl4030_wdt *wdt, int timeout) -{ - if (timeout < 0 || timeout > 30) { - dev_warn(wdt->miscdev.parent, - "Timeout can only be in the range [0-30] seconds"); - return -EINVAL; - } - wdt->timer_margin = timeout; - return twl4030_wdt_enable(wdt); -} - -static ssize_t twl4030_wdt_write_fop(struct file *file, - const char __user *data, size_t len, loff_t *ppos) -{ - struct twl4030_wdt *wdt = file->private_data; - - if (len) - twl4030_wdt_enable(wdt); - - return len; -} - -static long twl4030_wdt_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) +static int twl4030_wdt_set_timeout(struct watchdog_device *wdt, + unsigned int timeout) { - void __user *argp = (void __user *)arg; - int __user *p = argp; - int new_margin; - struct twl4030_wdt *wdt = file->private_data; - - static const struct watchdog_info twl4030_wd_ident = { - .identity = "TWL4030 Watchdog", - .options = WDIOF_SETTIMEOUT, - .firmware_version = 0, - }; - - switch (cmd) { - case WDIOC_GETSUPPORT: - return copy_to_user(argp, &twl4030_wd_ident, - sizeof(twl4030_wd_ident)) ? -EFAULT : 0; - - case WDIOC_GETSTATUS: - case WDIOC_GETBOOTSTATUS: - return put_user(0, p); - - case WDIOC_KEEPALIVE: - twl4030_wdt_enable(wdt); - break; - - case WDIOC_SETTIMEOUT: - if (get_user(new_margin, p)) - return -EFAULT; - if (twl4030_wdt_set_timeout(wdt, new_margin)) - return -EINVAL; - return put_user(wdt->timer_margin, p); - - case WDIOC_GETTIMEOUT: - return put_user(wdt->timer_margin, p); - - default: - return -ENOTTY; - } - + wdt->timeout = timeout; return 0; } -static int twl4030_wdt_open(struct inode *inode, struct file *file) -{ - struct twl4030_wdt *wdt = platform_get_drvdata(twl4030_wdt_dev); - - /* /dev/watchdog can only be opened once */ - if (test_and_set_bit(0, &wdt->state)) - return -EBUSY; - - wdt->state |= TWL4030_WDT_STATE_ACTIVE; - file->private_data = (void *) wdt; - - twl4030_wdt_enable(wdt); - return nonseekable_open(inode, file); -} - -static int twl4030_wdt_release(struct inode *inode, struct file *file) -{ - struct twl4030_wdt *wdt = file->private_data; - if (nowayout) { - dev_alert(wdt->miscdev.parent, - "Unexpected close, watchdog still running!\n"); - twl4030_wdt_enable(wdt); - } else { - if (twl4030_wdt_disable(wdt)) - return -EFAULT; - wdt->state &= ~TWL4030_WDT_STATE_ACTIVE; - } - - clear_bit(0, &wdt->state); - return 0; -} +static const struct watchdog_info twl4030_wdt_info = { + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, + .identity = "TWL4030 Watchdog", +}; -static const struct file_operations twl4030_wdt_fops = { +static const struct watchdog_ops twl4030_wdt_ops = { .owner = THIS_MODULE, - .llseek = no_llseek, - .open = twl4030_wdt_open, - .release = twl4030_wdt_release, - .unlocked_ioctl = twl4030_wdt_ioctl, - .write = twl4030_wdt_write_fop, + .start = twl4030_wdt_start, + .stop = twl4030_wdt_stop, + .set_timeout = twl4030_wdt_set_timeout, }; -static int __devinit twl4030_wdt_probe(struct platform_device *pdev) +static int twl4030_wdt_probe(struct platform_device *pdev) { int ret = 0; - struct twl4030_wdt *wdt; + struct watchdog_device *wdt; - wdt = kzalloc(sizeof(struct twl4030_wdt), GFP_KERNEL); + wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; - wdt->state = 0; - wdt->timer_margin = 30; - wdt->miscdev.parent = &pdev->dev; - wdt->miscdev.fops = &twl4030_wdt_fops; - wdt->miscdev.minor = WATCHDOG_MINOR; - wdt->miscdev.name = "watchdog"; + wdt->info = &twl4030_wdt_info; + wdt->ops = &twl4030_wdt_ops; + wdt->status = 0; + wdt->timeout = 30; + wdt->min_timeout = 1; + wdt->max_timeout = 30; + watchdog_set_nowayout(wdt, nowayout); platform_set_drvdata(pdev, wdt); - twl4030_wdt_dev = pdev; - - twl4030_wdt_disable(wdt); + twl4030_wdt_stop(wdt); - ret = misc_register(&wdt->miscdev); + ret = watchdog_register_device(wdt); if (ret) { - dev_err(wdt->miscdev.parent, - "Failed to register misc device\n"); platform_set_drvdata(pdev, NULL); - kfree(wdt); - twl4030_wdt_dev = NULL; return ret; } + return 0; } -static int __devexit twl4030_wdt_remove(struct platform_device *pdev) +static int twl4030_wdt_remove(struct platform_device *pdev) { - struct twl4030_wdt *wdt = platform_get_drvdata(pdev); - - if (wdt->state & TWL4030_WDT_STATE_ACTIVE) - if (twl4030_wdt_disable(wdt)) - return -EFAULT; - - wdt->state &= ~TWL4030_WDT_STATE_ACTIVE; - misc_deregister(&wdt->miscdev); + struct watchdog_device *wdt = platform_get_drvdata(pdev); + watchdog_unregister_device(wdt); platform_set_drvdata(pdev, NULL); - kfree(wdt); - twl4030_wdt_dev = NULL; return 0; } @@ -225,18 +111,18 @@ static int __devexit twl4030_wdt_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int twl4030_wdt_suspend(struct platform_device *pdev, pm_message_t state) { - struct twl4030_wdt *wdt = platform_get_drvdata(pdev); - if (wdt->state & TWL4030_WDT_STATE_ACTIVE) - return twl4030_wdt_disable(wdt); + struct watchdog_device *wdt = platform_get_drvdata(pdev); + if (watchdog_active(wdt)) + return twl4030_wdt_stop(wdt); return 0; } static int twl4030_wdt_resume(struct platform_device *pdev) { - struct twl4030_wdt *wdt = platform_get_drvdata(pdev); - if (wdt->state & TWL4030_WDT_STATE_ACTIVE) - return twl4030_wdt_enable(wdt); + struct watchdog_device *wdt = platform_get_drvdata(pdev); + if (watchdog_active(wdt)) + return twl4030_wdt_start(wdt); return 0; } @@ -245,14 +131,21 @@ static int twl4030_wdt_resume(struct platform_device *pdev) #define twl4030_wdt_resume NULL #endif +static const struct of_device_id twl_wdt_of_match[] = { + { .compatible = "ti,twl4030-wdt", }, + { }, +}; +MODULE_DEVICE_TABLE(of, twl_wdt_of_match); + static struct platform_driver twl4030_wdt_driver = { .probe = twl4030_wdt_probe, - .remove = __devexit_p(twl4030_wdt_remove), + .remove = twl4030_wdt_remove, .suspend = twl4030_wdt_suspend, .resume = twl4030_wdt_resume, .driver = { - .owner = THIS_MODULE, - .name = "twl4030_wdt", + .owner = THIS_MODULE, + .name = "twl4030_wdt", + .of_match_table = twl_wdt_of_match, }, }; @@ -260,6 +153,5 @@ module_platform_driver(twl4030_wdt_driver); MODULE_AUTHOR("Nokia Corporation"); MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); MODULE_ALIAS("platform:twl4030_wdt"); diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c index aa50da3ccfe3..1a68f760cf86 100644 --- a/drivers/watchdog/via_wdt.c +++ b/drivers/watchdog/via_wdt.c @@ -155,7 +155,7 @@ static struct watchdog_device wdt_dev = { .max_timeout = WDT_TIMEOUT_MAX, }; -static int __devinit wdt_probe(struct pci_dev *pdev, +static int wdt_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned char conf; @@ -229,7 +229,7 @@ err_out_disable_device: return ret; } -static void __devexit wdt_remove(struct pci_dev *pdev) +static void wdt_remove(struct pci_dev *pdev) { watchdog_unregister_device(&wdt_dev); del_timer(&timer); @@ -250,7 +250,7 @@ static struct pci_driver wdt_driver = { .name = "via_wdt", .id_table = wdt_pci_table, .probe = wdt_probe, - .remove = __devexit_p(wdt_remove), + .remove = wdt_remove, }; module_pci_driver(wdt_driver); diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c index e32654efdbb6..36a54c0e32dd 100644 --- a/drivers/watchdog/wdt_pci.c +++ b/drivers/watchdog/wdt_pci.c @@ -605,7 +605,7 @@ static struct notifier_block wdtpci_notifier = { }; -static int __devinit wdtpci_init_one(struct pci_dev *dev, +static int wdtpci_init_one(struct pci_dev *dev, const struct pci_device_id *ent) { int ret = -EIO; @@ -705,7 +705,7 @@ out_pci: } -static void __devexit wdtpci_remove_one(struct pci_dev *pdev) +static void wdtpci_remove_one(struct pci_dev *pdev) { /* here we assume only one device will ever have * been picked up and registered by probe function */ @@ -736,7 +736,7 @@ static struct pci_driver wdtpci_driver = { .name = "wdt_pci", .id_table = wdtpci_pci_tbl, .probe = wdtpci_init_one, - .remove = __devexit_p(wdtpci_remove_one), + .remove = wdtpci_remove_one, }; module_pci_driver(wdtpci_driver); diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index 87d66d236c3e..9dcb6d082277 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c @@ -181,7 +181,7 @@ static const struct watchdog_ops wm831x_wdt_ops = { .set_timeout = wm831x_wdt_set_timeout, }; -static int __devinit wm831x_wdt_probe(struct platform_device *pdev) +static int wm831x_wdt_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *chip_pdata; @@ -292,7 +292,7 @@ err: return ret; } -static int __devexit wm831x_wdt_remove(struct platform_device *pdev) +static int wm831x_wdt_remove(struct platform_device *pdev) { struct wm831x_wdt_drvdata *driver_data = dev_get_drvdata(&pdev->dev); @@ -306,7 +306,7 @@ static int __devexit wm831x_wdt_remove(struct platform_device *pdev) static struct platform_driver wm831x_wdt_driver = { .probe = wm831x_wdt_probe, - .remove = __devexit_p(wm831x_wdt_remove), + .remove = wm831x_wdt_remove, .driver = { .name = "wm831x-watchdog", }, diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c index 3c76693447fd..34d272ada23d 100644 --- a/drivers/watchdog/wm8350_wdt.c +++ b/drivers/watchdog/wm8350_wdt.c @@ -140,7 +140,7 @@ static struct watchdog_device wm8350_wdt = { .max_timeout = 4, }; -static int __devinit wm8350_wdt_probe(struct platform_device *pdev) +static int wm8350_wdt_probe(struct platform_device *pdev) { struct wm8350 *wm8350 = platform_get_drvdata(pdev); @@ -158,7 +158,7 @@ static int __devinit wm8350_wdt_probe(struct platform_device *pdev) return watchdog_register_device(&wm8350_wdt); } -static int __devexit wm8350_wdt_remove(struct platform_device *pdev) +static int wm8350_wdt_remove(struct platform_device *pdev) { watchdog_unregister_device(&wm8350_wdt); return 0; @@ -166,7 +166,7 @@ static int __devexit wm8350_wdt_remove(struct platform_device *pdev) static struct platform_driver wm8350_wdt_driver = { .probe = wm8350_wdt_probe, - .remove = __devexit_p(wm8350_wdt_remove), + .remove = wm8350_wdt_remove, .driver = { .name = "wm8350-wdt", }, diff --git a/drivers/watchdog/xen_wdt.c b/drivers/watchdog/xen_wdt.c index e4a25b51165c..92ad33d0cb71 100644 --- a/drivers/watchdog/xen_wdt.c +++ b/drivers/watchdog/xen_wdt.c @@ -244,7 +244,7 @@ static struct miscdevice xen_wdt_miscdev = { .fops = &xen_wdt_fops, }; -static int __devinit xen_wdt_probe(struct platform_device *dev) +static int xen_wdt_probe(struct platform_device *dev) { struct sched_watchdog wd = { .id = ~0 }; int ret = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wd); @@ -280,7 +280,7 @@ static int __devinit xen_wdt_probe(struct platform_device *dev) return ret; } -static int __devexit xen_wdt_remove(struct platform_device *dev) +static int xen_wdt_remove(struct platform_device *dev) { /* Stop the timer before we leave */ if (!nowayout) @@ -315,7 +315,7 @@ static int xen_wdt_resume(struct platform_device *dev) static struct platform_driver xen_wdt_driver = { .probe = xen_wdt_probe, - .remove = __devexit_p(xen_wdt_remove), + .remove = xen_wdt_remove, .shutdown = xen_wdt_shutdown, .suspend = xen_wdt_suspend, .resume = xen_wdt_resume, |