summaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-13 09:20:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-13 09:20:42 -0400
commit55472bae5331f33582d9f0e8919fed8bebcda0da (patch)
tree4e9d910e8f5de08d1ceb45509ff42641fcd0a6e7 /drivers/watchdog
parentd7a02fa0a8f9ec1b81d57628ca9834563208ef33 (diff)
parenta9f0bda567e32a2b44165b067adfc4a4f56d1815 (diff)
downloadlinux-55472bae5331f33582d9f0e8919fed8bebcda0da.tar.bz2
Merge tag 'linux-watchdog-5.2-rc1' of git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck: - a new watchdog driver for the ROHM BD70528 watchdog block - a new watchdog driver for the i.MX system controller watchdog - conversions to use device managed functions and other improvements - refactor watchdog_init_timeout - make watchdog core configurable as module - pretimeout governors improvements - a lot of other fixes * tag 'linux-watchdog-5.2-rc1' of git://www.linux-watchdog.org/linux-watchdog: (114 commits) watchdog: Enforce that at least one pretimeout governor is enabled watchdog: stm32: add dynamic prescaler support watchdog: Improve Kconfig entry ordering and dependencies watchdog: npcm: Enable modular builds watchdog: Make watchdog core configurable as module watchdog: Move pretimeout governor configuration up watchdog: Use depends instead of select for pretimeout governors watchdog: rtd119x: drop unused module.h include watchdog: intel_scu: make it explicitly non-modular watchdog: coh901327: make it explicitly non-modular watchdog: ziirave_wdt: drop warning after calling watchdog_init_timeout watchdog: xen_wdt: drop warning after calling watchdog_init_timeout watchdog: stm32_iwdg: drop warning after calling watchdog_init_timeout watchdog: st_lpc_wdt: drop warning after calling watchdog_init_timeout watchdog: sp5100_tco: drop warning after calling watchdog_init_timeout watchdog: renesas_wdt: drop warning after calling watchdog_init_timeout watchdog: nic7018_wdt: drop warning after calling watchdog_init_timeout watchdog: ni903x_wdt: drop warning after calling watchdog_init_timeout watchdog: imx_sc_wdt: drop warning after calling watchdog_init_timeout watchdog: i6300esb: drop warning after calling watchdog_init_timeout ...
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/Kconfig161
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/alim7101_wdt.c2
-rw-r--r--drivers/watchdog/armada_37xx_wdt.c43
-rw-r--r--drivers/watchdog/asm9260_wdt.c77
-rw-r--r--drivers/watchdog/aspeed_wdt.c25
-rw-r--r--drivers/watchdog/at91sam9_wdt.c4
-rw-r--r--drivers/watchdog/ath79_wdt.c4
-rw-r--r--drivers/watchdog/atlas7_wdt.c65
-rw-r--r--drivers/watchdog/bcm2835_wdt.c1
-rw-r--r--drivers/watchdog/bcm7038_wdt.c42
-rw-r--r--drivers/watchdog/bcm_kona_wdt.c18
-rw-r--r--drivers/watchdog/bd70528_wdt.c290
-rw-r--r--drivers/watchdog/cadence_wdt.c90
-rw-r--r--drivers/watchdog/coh901327_wdt.c28
-rw-r--r--drivers/watchdog/da9052_wdt.c13
-rw-r--r--drivers/watchdog/da9055_wdt.c12
-rw-r--r--drivers/watchdog/da9062_wdt.c20
-rw-r--r--drivers/watchdog/da9063_wdt.c21
-rw-r--r--drivers/watchdog/davinci_wdt.c45
-rw-r--r--drivers/watchdog/digicolor_wdt.c4
-rw-r--r--drivers/watchdog/dw_wdt.c4
-rw-r--r--drivers/watchdog/ebc-c384_wdt.c5
-rw-r--r--drivers/watchdog/ep93xx_wdt.c17
-rw-r--r--drivers/watchdog/f71808e_wdt.c18
-rw-r--r--drivers/watchdog/ftwdt010_wdt.c6
-rw-r--r--drivers/watchdog/gpio_wdt.c16
-rw-r--r--drivers/watchdog/hpwdt.c3
-rw-r--r--drivers/watchdog/i6300esb.c9
-rw-r--r--drivers/watchdog/iTCO_wdt.c13
-rw-r--r--drivers/watchdog/imgpdc_wdt.c95
-rw-r--r--drivers/watchdog/imx2_wdt.c8
-rw-r--r--drivers/watchdog/imx_sc_wdt.c175
-rw-r--r--drivers/watchdog/intel-mid_wdt.c22
-rw-r--r--drivers/watchdog/intel_scu_watchdog.c20
-rw-r--r--drivers/watchdog/jz4740_wdt.c17
-rw-r--r--drivers/watchdog/kempld_wdt.c28
-rw-r--r--drivers/watchdog/lantiq_wdt.c4
-rw-r--r--drivers/watchdog/loongson1_wdt.c52
-rw-r--r--drivers/watchdog/lpc18xx_wdt.c47
-rw-r--r--drivers/watchdog/machzwd.c3
-rw-r--r--drivers/watchdog/max63xx_wdt.c24
-rw-r--r--drivers/watchdog/max77620_wdt.c23
-rw-r--r--drivers/watchdog/mena21_wdt.c28
-rw-r--r--drivers/watchdog/menf21bmc_wdt.c33
-rw-r--r--drivers/watchdog/meson_gxbb_wdt.c49
-rw-r--r--drivers/watchdog/meson_wdt.c19
-rw-r--r--drivers/watchdog/mlx_wdt.c14
-rw-r--r--drivers/watchdog/moxart_wdt.c20
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c20
-rw-r--r--drivers/watchdog/mt7621_wdt.c12
-rw-r--r--drivers/watchdog/mtk_wdt.c37
-rw-r--r--drivers/watchdog/ni903x_wdt.c4
-rw-r--r--drivers/watchdog/nic7018_wdt.c5
-rw-r--r--drivers/watchdog/npcm_wdt.c10
-rw-r--r--drivers/watchdog/nuc900_wdt.c4
-rw-r--r--drivers/watchdog/of_xilinx_wdt.c62
-rw-r--r--drivers/watchdog/omap_wdt.c4
-rw-r--r--drivers/watchdog/orion_wdt.c14
-rw-r--r--drivers/watchdog/pic32-dmt.c50
-rw-r--r--drivers/watchdog/pic32-wdt.c62
-rw-r--r--drivers/watchdog/pm8916_wdt.c21
-rw-r--r--drivers/watchdog/pnx4008_wdt.c45
-rw-r--r--drivers/watchdog/qcom-wdt.c55
-rw-r--r--drivers/watchdog/renesas_wdt.c9
-rw-r--r--drivers/watchdog/rn5t618_wdt.c9
-rw-r--r--drivers/watchdog/rt2880_wdt.c32
-rw-r--r--drivers/watchdog/rtd119x_wdt.c47
-rw-r--r--drivers/watchdog/rza_wdt.c25
-rw-r--r--drivers/watchdog/s3c2410_wdt.c4
-rw-r--r--drivers/watchdog/sama5d4_wdt.c39
-rw-r--r--drivers/watchdog/sb_wdog.c4
-rw-r--r--drivers/watchdog/sbsa_gwdt.c28
-rw-r--r--drivers/watchdog/shwdt.c4
-rw-r--r--drivers/watchdog/sirfsoc_wdt.c28
-rw-r--r--drivers/watchdog/sp5100_tco.c4
-rw-r--r--drivers/watchdog/sprd_wdt.c42
-rw-r--r--drivers/watchdog/st_lpc_wdt.c53
-rw-r--r--drivers/watchdog/stm32_iwdg.c150
-rw-r--r--drivers/watchdog/stmp3xxx_rtc_wdt.c16
-rw-r--r--drivers/watchdog/stpmic1_wdt.c13
-rw-r--r--drivers/watchdog/sunxi_wdt.c19
-rw-r--r--drivers/watchdog/tangox_wdt.c41
-rw-r--r--drivers/watchdog/tegra_wdt.c30
-rw-r--r--drivers/watchdog/tqmx86_wdt.c14
-rw-r--r--drivers/watchdog/ts4800_wdt.c33
-rw-r--r--drivers/watchdog/ts72xx_wdt.c18
-rw-r--r--drivers/watchdog/twl4030_wdt.c22
-rw-r--r--drivers/watchdog/txx9wdt.c4
-rw-r--r--drivers/watchdog/uniphier_wdt.c2
-rw-r--r--drivers/watchdog/ux500_wdt.c17
-rw-r--r--drivers/watchdog/watchdog_core.c42
-rw-r--r--drivers/watchdog/wdat_wdt.c29
-rw-r--r--drivers/watchdog/wm831x_wdt.c19
-rw-r--r--drivers/watchdog/xen_wdt.c18
-rw-r--r--drivers/watchdog/ziirave_wdt.c6
-rw-r--r--drivers/watchdog/zx2967_wdt.c37
97 files changed, 1465 insertions, 1537 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 242eea859637..7ea60371bda0 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -30,7 +30,7 @@ menuconfig WATCHDOG
if WATCHDOG
config WATCHDOG_CORE
- bool "WatchDog Timer Driver Core"
+ tristate "WatchDog Timer Driver Core"
---help---
Say Y here if you want to use the new watchdog timer driver core.
This driver provides a framework for all watchdog timer drivers
@@ -63,6 +63,66 @@ config WATCHDOG_SYSFS
Say Y here if you want to enable watchdog device status read through
sysfs attributes.
+comment "Watchdog Pretimeout Governors"
+
+config WATCHDOG_PRETIMEOUT_GOV
+ bool "Enable watchdog pretimeout governors"
+ depends on WATCHDOG_CORE
+ help
+ The option allows to select watchdog pretimeout governors.
+
+config WATCHDOG_PRETIMEOUT_GOV_SEL
+ tristate
+ depends on WATCHDOG_PRETIMEOUT_GOV
+ default m
+ select WATCHDOG_PRETIMEOUT_GOV_PANIC if WATCHDOG_PRETIMEOUT_GOV_NOOP=n
+
+if WATCHDOG_PRETIMEOUT_GOV
+
+config WATCHDOG_PRETIMEOUT_GOV_NOOP
+ tristate "Noop watchdog pretimeout governor"
+ depends on WATCHDOG_CORE
+ default WATCHDOG_CORE
+ help
+ Noop watchdog pretimeout governor, only an informational
+ message is added to kernel log buffer.
+
+config WATCHDOG_PRETIMEOUT_GOV_PANIC
+ tristate "Panic watchdog pretimeout governor"
+ depends on WATCHDOG_CORE
+ default WATCHDOG_CORE
+ help
+ Panic watchdog pretimeout governor, on watchdog pretimeout
+ event put the kernel into panic.
+
+choice
+ prompt "Default Watchdog Pretimeout Governor"
+ default WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
+ help
+ This option selects a default watchdog pretimeout governor.
+ The governor takes its action, if a watchdog is capable
+ to report a pretimeout event.
+
+config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP
+ bool "noop"
+ depends on WATCHDOG_PRETIMEOUT_GOV_NOOP
+ help
+ Use noop watchdog pretimeout governor by default. If noop
+ governor is selected by a user, write a short message to
+ the kernel log buffer and don't do any system changes.
+
+config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
+ bool "panic"
+ depends on WATCHDOG_PRETIMEOUT_GOV_PANIC
+ help
+ Use panic watchdog pretimeout governor by default, if
+ a watchdog pretimeout event happens, consider that
+ a watchdog feeder is dead and reboot is unavoidable.
+
+endchoice
+
+endif # WATCHDOG_PRETIMEOUT_GOV
+
#
# General Watchdog drivers
#
@@ -90,6 +150,18 @@ config SOFT_WATCHDOG_PRETIMEOUT
watchdog. Be aware that governors might affect the watchdog because it
is purely software, e.g. the panic governor will stall it!
+config BD70528_WATCHDOG
+ tristate "ROHM BD70528 PMIC Watchdog"
+ depends on MFD_ROHM_BD70528
+ select WATCHDOG_CORE
+ help
+ Support for the watchdog in the ROHM BD70528 PMIC. Watchdog trigger
+ cause system reset.
+
+ Say Y here to include support for the ROHM BD70528 watchdog.
+ Alternatively say M to compile the driver as a module,
+ which will be called bd70528_wdt.
+
config DA9052_WATCHDOG
tristate "Dialog DA9052 Watchdog"
depends on PMIC_DA9052 || COMPILE_TEST
@@ -552,7 +624,7 @@ config COH901327_WATCHDOG
compiled as a module.
config NPCM7XX_WATCHDOG
- bool "Nuvoton NPCM750 watchdog"
+ tristate "Nuvoton NPCM750 watchdog"
depends on ARCH_NPCM || COMPILE_TEST
default y if ARCH_NPCM7XX
select WATCHDOG_CORE
@@ -641,6 +713,22 @@ config IMX2_WDT
To compile this driver as a module, choose M here: the
module will be called imx2_wdt.
+config IMX_SC_WDT
+ tristate "IMX SC Watchdog"
+ depends on HAVE_ARM_SMCCC
+ select WATCHDOG_CORE
+ help
+ This is the driver for the system controller watchdog
+ on the NXP i.MX SoCs with system controller inside, the
+ watchdog driver will call ARM SMC API and trap into
+ ARM-Trusted-Firmware for operations, ARM-Trusted-Firmware
+ will request system controller to execute the operations.
+ If you have one of these processors and wish to have
+ watchdog support enabled, say Y, otherwise say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called imx_sc_wdt.
+
config UX500_WATCHDOG
tristate "ST-Ericsson Ux500 watchdog"
depends on MFD_DB8500_PRCMU
@@ -1179,6 +1267,15 @@ config HP_WATCHDOG
To compile this driver as a module, choose M here: the module will be
called hpwdt.
+config HPWDT_NMI_DECODING
+ bool "NMI support for the HP ProLiant iLO2+ Hardware Watchdog Timer"
+ depends on HP_WATCHDOG
+ default y
+ help
+ Enables the NMI handler for the watchdog pretimeout NMI and the iLO
+ "Generate NMI to System" virtual button. When an NMI is claimed
+ by the driver, panic is called.
+
config KEMPLD_WDT
tristate "Kontron COM Watchdog Timer"
depends on MFD_KEMPLD
@@ -1190,15 +1287,6 @@ config KEMPLD_WDT
This driver can also be built as a module. If so, the module will be
called kempld_wdt.
-config HPWDT_NMI_DECODING
- bool "NMI support for the HP ProLiant iLO2+ Hardware Watchdog Timer"
- depends on HP_WATCHDOG
- default y
- help
- Enables the NMI handler for the watchdog pretimeout NMI and the iLO
- "Generate NMI to System" virtual button. When an NMI is claimed
- by the driver, panic is called.
-
config SC1200_WDT
tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
depends on X86
@@ -1647,7 +1735,7 @@ config BCM_KONA_WDT
config BCM_KONA_WDT_DEBUG
bool "DEBUGFS support for BCM Kona Watchdog"
- depends on BCM_KONA_WDT || COMPILE_TEST
+ depends on BCM_KONA_WDT
help
If enabled, adds /sys/kernel/debug/bcm_kona_wdt/info which provides
access to the driver's internal data structures as well as watchdog
@@ -2024,53 +2112,4 @@ config USBPCWATCHDOG
Most people will say N.
-comment "Watchdog Pretimeout Governors"
-
-config WATCHDOG_PRETIMEOUT_GOV
- bool "Enable watchdog pretimeout governors"
- help
- The option allows to select watchdog pretimeout governors.
-
-if WATCHDOG_PRETIMEOUT_GOV
-
-choice
- prompt "Default Watchdog Pretimeout Governor"
- default WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
- help
- This option selects a default watchdog pretimeout governor.
- The governor takes its action, if a watchdog is capable
- to report a pretimeout event.
-
-config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP
- bool "noop"
- select WATCHDOG_PRETIMEOUT_GOV_NOOP
- help
- Use noop watchdog pretimeout governor by default. If noop
- governor is selected by a user, write a short message to
- the kernel log buffer and don't do any system changes.
-
-config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
- bool "panic"
- select WATCHDOG_PRETIMEOUT_GOV_PANIC
- help
- Use panic watchdog pretimeout governor by default, if
- a watchdog pretimeout event happens, consider that
- a watchdog feeder is dead and reboot is unavoidable.
-
-endchoice
-
-config WATCHDOG_PRETIMEOUT_GOV_NOOP
- tristate "Noop watchdog pretimeout governor"
- help
- Noop watchdog pretimeout governor, only an informational
- message is added to kernel log buffer.
-
-config WATCHDOG_PRETIMEOUT_GOV_PANIC
- tristate "Panic watchdog pretimeout governor"
- help
- Panic watchdog pretimeout governor, on watchdog pretimeout
- event put the kernel into panic.
-
-endif # WATCHDOG_PRETIMEOUT_GOV
-
endif # WATCHDOG
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index ba930e464657..7caa920e7e60 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o
obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
+obj-$(CONFIG_IMX_SC_WDT) += imx_sc_wdt.o
obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o
obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
@@ -205,6 +206,7 @@ obj-$(CONFIG_WATCHDOG_SUN4V) += sun4v_wdt.o
obj-$(CONFIG_XEN_WDT) += xen_wdt.o
# Architecture Independent
+obj-$(CONFIG_BD70528_WATCHDOG) += bd70528_wdt.o
obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o
obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o
obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 7e9884960eb9..689b8a0593c1 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -277,8 +277,8 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return -EINVAL;
timeout = new_timeout;
wdt_keepalive();
- /* Fall through */
}
+ /* Fall through */
case WDIOC_GETTIMEOUT:
return put_user(timeout, p);
default:
diff --git a/drivers/watchdog/armada_37xx_wdt.c b/drivers/watchdog/armada_37xx_wdt.c
index 4b4054f54df9..e5dcb26d85f0 100644
--- a/drivers/watchdog/armada_37xx_wdt.c
+++ b/drivers/watchdog/armada_37xx_wdt.c
@@ -244,6 +244,11 @@ static const struct watchdog_ops armada_37xx_wdt_ops = {
.get_timeleft = armada_37xx_wdt_get_timeleft,
};
+static void armada_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int armada_37xx_wdt_probe(struct platform_device *pdev)
{
struct armada_37xx_watchdog *dev;
@@ -278,12 +283,14 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev)
ret = clk_prepare_enable(dev->clk);
if (ret)
return ret;
+ ret = devm_add_action_or_reset(&pdev->dev,
+ armada_clk_disable_unprepare, dev->clk);
+ if (ret)
+ return ret;
dev->clk_rate = clk_get_rate(dev->clk);
- if (!dev->clk_rate) {
- ret = -EINVAL;
- goto disable_clk;
- }
+ if (!dev->clk_rate)
+ return -EINVAL;
/*
* Since the timeout in seconds is given as 32 bit unsigned int, and
@@ -307,35 +314,15 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &dev->wdt.status);
watchdog_set_nowayout(&dev->wdt, nowayout);
- ret = watchdog_register_device(&dev->wdt);
+ watchdog_stop_on_reboot(&dev->wdt);
+ ret = devm_watchdog_register_device(&pdev->dev, &dev->wdt);
if (ret)
- goto disable_clk;
+ return ret;
dev_info(&pdev->dev, "Initial timeout %d sec%s\n",
dev->wdt.timeout, nowayout ? ", nowayout" : "");
return 0;
-
-disable_clk:
- clk_disable_unprepare(dev->clk);
- return ret;
-}
-
-static int armada_37xx_wdt_remove(struct platform_device *pdev)
-{
- struct watchdog_device *wdt = platform_get_drvdata(pdev);
- struct armada_37xx_watchdog *dev = watchdog_get_drvdata(wdt);
-
- watchdog_unregister_device(wdt);
- clk_disable_unprepare(dev->clk);
- return 0;
-}
-
-static void armada_37xx_wdt_shutdown(struct platform_device *pdev)
-{
- struct watchdog_device *wdt = platform_get_drvdata(pdev);
-
- armada_37xx_wdt_stop(wdt);
}
static int __maybe_unused armada_37xx_wdt_suspend(struct device *dev)
@@ -370,8 +357,6 @@ MODULE_DEVICE_TABLE(of, armada_37xx_wdt_match);
static struct platform_driver armada_37xx_wdt_driver = {
.probe = armada_37xx_wdt_probe,
- .remove = armada_37xx_wdt_remove,
- .shutdown = armada_37xx_wdt_shutdown,
.driver = {
.name = "armada_37xx_wdt",
.of_match_table = of_match_ptr(armada_37xx_wdt_match),
diff --git a/drivers/watchdog/asm9260_wdt.c b/drivers/watchdog/asm9260_wdt.c
index 9768e44ffeb8..c5b9aae544dd 100644
--- a/drivers/watchdog/asm9260_wdt.c
+++ b/drivers/watchdog/asm9260_wdt.c
@@ -196,6 +196,11 @@ static const struct watchdog_ops asm9260_wdt_ops = {
.restart = asm9260_restart,
};
+static void asm9260_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int asm9260_wdt_get_dt_clks(struct asm9260_wdt_priv *priv)
{
int err;
@@ -219,26 +224,32 @@ static int asm9260_wdt_get_dt_clks(struct asm9260_wdt_priv *priv)
dev_err(priv->dev, "Failed to enable ahb_clk!\n");
return err;
}
+ err = devm_add_action_or_reset(priv->dev,
+ asm9260_clk_disable_unprepare,
+ priv->clk_ahb);
+ if (err)
+ return err;
err = clk_set_rate(priv->clk, CLOCK_FREQ);
if (err) {
- clk_disable_unprepare(priv->clk_ahb);
dev_err(priv->dev, "Failed to set rate!\n");
return err;
}
err = clk_prepare_enable(priv->clk);
if (err) {
- clk_disable_unprepare(priv->clk_ahb);
dev_err(priv->dev, "Failed to enable clk!\n");
return err;
}
+ err = devm_add_action_or_reset(priv->dev,
+ asm9260_clk_disable_unprepare,
+ priv->clk);
+ if (err)
+ return err;
/* wdt has internal divider */
clk = clk_get_rate(priv->clk);
if (!clk) {
- clk_disable_unprepare(priv->clk);
- clk_disable_unprepare(priv->clk_ahb);
dev_err(priv->dev, "Failed, clk is 0!\n");
return -EINVAL;
}
@@ -274,25 +285,23 @@ static void asm9260_wdt_get_dt_mode(struct asm9260_wdt_priv *priv)
static int asm9260_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct asm9260_wdt_priv *priv;
struct watchdog_device *wdd;
- struct resource *res;
int ret;
static const char * const mode_name[] = { "hw", "sw", "debug", };
- priv = devm_kzalloc(&pdev->dev, sizeof(struct asm9260_wdt_priv),
- GFP_KERNEL);
+ priv = devm_kzalloc(dev, sizeof(struct asm9260_wdt_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- priv->dev = &pdev->dev;
+ priv->dev = dev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->iobase = devm_ioremap_resource(&pdev->dev, res);
+ priv->iobase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->iobase))
return PTR_ERR(priv->iobase);
- priv->rst = devm_reset_control_get_exclusive(&pdev->dev, "wdt_rst");
+ priv->rst = devm_reset_control_get_exclusive(dev, "wdt_rst");
if (IS_ERR(priv->rst))
return PTR_ERR(priv->rst);
@@ -305,7 +314,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
wdd->ops = &asm9260_wdt_ops;
wdd->min_timeout = 1;
wdd->max_timeout = BM_WDTC_MAX(priv->wdt_freq);
- wdd->parent = &pdev->dev;
+ wdd->parent = dev;
watchdog_set_drvdata(wdd, priv);
@@ -315,7 +324,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
* the max instead.
*/
wdd->timeout = ASM9260_WDT_DEFAULT_TIMEOUT;
- watchdog_init_timeout(wdd, 0, &pdev->dev);
+ watchdog_init_timeout(wdd, 0, dev);
asm9260_wdt_get_dt_mode(priv);
@@ -327,49 +336,25 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
* Not all supported platforms specify an interrupt for the
* watchdog, so let's make it optional.
*/
- ret = devm_request_irq(&pdev->dev, priv->irq,
- asm9260_wdt_irq, 0, pdev->name, priv);
+ ret = devm_request_irq(dev, priv->irq, asm9260_wdt_irq, 0,
+ pdev->name, priv);
if (ret < 0)
- dev_warn(&pdev->dev, "failed to request IRQ\n");
+ dev_warn(dev, "failed to request IRQ\n");
}
watchdog_set_restart_priority(wdd, 128);
- ret = watchdog_register_device(wdd);
+ watchdog_stop_on_reboot(wdd);
+ watchdog_stop_on_unregister(wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret)
- goto clk_off;
+ return ret;
platform_set_drvdata(pdev, priv);
- dev_info(&pdev->dev, "Watchdog enabled (timeout: %d sec, mode: %s)\n",
+ dev_info(dev, "Watchdog enabled (timeout: %d sec, mode: %s)\n",
wdd->timeout, mode_name[priv->mode]);
return 0;
-
-clk_off:
- clk_disable_unprepare(priv->clk);
- clk_disable_unprepare(priv->clk_ahb);
- return ret;
-}
-
-static void asm9260_wdt_shutdown(struct platform_device *pdev)
-{
- struct asm9260_wdt_priv *priv = platform_get_drvdata(pdev);
-
- asm9260_wdt_disable(&priv->wdd);
-}
-
-static int asm9260_wdt_remove(struct platform_device *pdev)
-{
- struct asm9260_wdt_priv *priv = platform_get_drvdata(pdev);
-
- asm9260_wdt_disable(&priv->wdd);
-
- watchdog_unregister_device(&priv->wdd);
-
- clk_disable_unprepare(priv->clk);
- clk_disable_unprepare(priv->clk_ahb);
-
- return 0;
}
static const struct of_device_id asm9260_wdt_of_match[] = {
@@ -384,8 +369,6 @@ static struct platform_driver asm9260_wdt_driver = {
.of_match_table = asm9260_wdt_of_match,
},
.probe = asm9260_wdt_probe,
- .remove = asm9260_wdt_remove,
- .shutdown = asm9260_wdt_shutdown,
};
module_platform_driver(asm9260_wdt_driver);
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index 1abe4d021fd2..34117745c65f 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -187,22 +187,21 @@ static const struct watchdog_info aspeed_wdt_info = {
static int aspeed_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
const struct aspeed_wdt_config *config;
const struct of_device_id *ofdid;
struct aspeed_wdt *wdt;
- struct resource *res;
struct device_node *np;
const char *reset_type;
u32 duration;
u32 status;
int ret;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->base = devm_ioremap_resource(&pdev->dev, res);
+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
@@ -214,12 +213,12 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
wdt->wdd.info = &aspeed_wdt_info;
wdt->wdd.ops = &aspeed_wdt_ops;
wdt->wdd.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT_MS;
- wdt->wdd.parent = &pdev->dev;
+ wdt->wdd.parent = dev;
wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT;
- watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
+ watchdog_init_timeout(&wdt->wdd, 0, dev);
- np = pdev->dev.of_node;
+ np = dev->of_node;
ofdid = of_match_node(aspeed_wdt_of_table, np);
if (!ofdid)
@@ -288,11 +287,11 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
u32 max_duration = config->ext_pulse_width_mask + 1;
if (duration == 0 || duration > max_duration) {
- dev_err(&pdev->dev, "Invalid pulse duration: %uus\n",
- duration);
+ dev_err(dev, "Invalid pulse duration: %uus\n",
+ duration);
duration = max(1U, min(max_duration, duration));
- dev_info(&pdev->dev, "Pulse duration set to %uus\n",
- duration);
+ dev_info(dev, "Pulse duration set to %uus\n",
+ duration);
}
/*
@@ -314,9 +313,9 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
wdt->wdd.bootstatus = WDIOF_CARDRESET;
- ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
+ ret = devm_watchdog_register_device(dev, &wdt->wdd);
if (ret) {
- dev_err(&pdev->dev, "failed to register\n");
+ dev_err(dev, "failed to register\n");
return ret;
}
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index f4050a229eb5..292b5a1ca831 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -327,7 +327,6 @@ static inline int of_at91wdt_init(struct device_node *np, struct at91wdt *wdt)
static int __init at91wdt_probe(struct platform_device *pdev)
{
- struct resource *r;
int err;
struct at91wdt *wdt;
@@ -346,8 +345,7 @@ static int __init at91wdt_probe(struct platform_device *pdev)
wdt->wdd.min_timeout = 1;
wdt->wdd.max_timeout = 0xFFFF;
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->base = devm_ioremap_resource(&pdev->dev, r);
+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c
index 4f56b63f9691..02234c254b10 100644
--- a/drivers/watchdog/ath79_wdt.c
+++ b/drivers/watchdog/ath79_wdt.c
@@ -250,15 +250,13 @@ static struct miscdevice ath79_wdt_miscdev = {
static int ath79_wdt_probe(struct platform_device *pdev)
{
- struct resource *res;
u32 ctrl;
int err;
if (wdt_base)
return -EBUSY;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt_base = devm_ioremap_resource(&pdev->dev, res);
+ wdt_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt_base))
return PTR_ERR(wdt_base);
diff --git a/drivers/watchdog/atlas7_wdt.c b/drivers/watchdog/atlas7_wdt.c
index 4abdcabd8219..79337d2a8a8e 100644
--- a/drivers/watchdog/atlas7_wdt.c
+++ b/drivers/watchdog/atlas7_wdt.c
@@ -125,80 +125,57 @@ static const struct of_device_id atlas7_wdt_ids[] = {
{}
};
+static void atlas7_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int atlas7_wdt_probe(struct platform_device *pdev)
{
- struct device_node *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
struct atlas7_wdog *wdt;
- struct resource *res;
struct clk *clk;
int ret;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->base = devm_ioremap_resource(&pdev->dev, res);
+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
- clk = of_clk_get(np, 0);
+ clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk))
return PTR_ERR(clk);
ret = clk_prepare_enable(clk);
if (ret) {
- dev_err(&pdev->dev, "clk enable failed\n");
- goto err;
+ dev_err(dev, "clk enable failed\n");
+ return ret;
}
+ ret = devm_add_action_or_reset(dev, atlas7_clk_disable_unprepare, clk);
+ if (ret)
+ return ret;
/* disable watchdog hardware */
writel(0, wdt->base + ATLAS7_WDT_CNT_CTRL);
wdt->tick_rate = clk_get_rate(clk);
- if (!wdt->tick_rate) {
- ret = -EINVAL;
- goto err1;
- }
+ if (!wdt->tick_rate)
+ return -EINVAL;
wdt->clk = clk;
atlas7_wdd.min_timeout = 1;
atlas7_wdd.max_timeout = UINT_MAX / wdt->tick_rate;
- watchdog_init_timeout(&atlas7_wdd, 0, &pdev->dev);
+ watchdog_init_timeout(&atlas7_wdd, 0, dev);
watchdog_set_nowayout(&atlas7_wdd, nowayout);
watchdog_set_drvdata(&atlas7_wdd, wdt);
platform_set_drvdata(pdev, &atlas7_wdd);
- ret = watchdog_register_device(&atlas7_wdd);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- clk_disable_unprepare(clk);
-err:
- clk_put(clk);
- return ret;
-}
-
-static void atlas7_wdt_shutdown(struct platform_device *pdev)
-{
- struct watchdog_device *wdd = platform_get_drvdata(pdev);
- struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd);
-
- atlas7_wdt_disable(wdd);
- clk_disable_unprepare(wdt->clk);
-}
-
-static int atlas7_wdt_remove(struct platform_device *pdev)
-{
- struct watchdog_device *wdd = platform_get_drvdata(pdev);
- struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd);
-
- atlas7_wdt_shutdown(pdev);
- clk_put(wdt->clk);
- return 0;
+ watchdog_stop_on_reboot(&atlas7_wdd);
+ watchdog_stop_on_unregister(&atlas7_wdd);
+ return devm_watchdog_register_device(dev, &atlas7_wdd);
}
static int __maybe_unused atlas7_wdt_suspend(struct device *dev)
@@ -236,8 +213,6 @@ static struct platform_driver atlas7_wdt_driver = {
.of_match_table = atlas7_wdt_ids,
},
.probe = atlas7_wdt_probe,
- .remove = atlas7_wdt_remove,
- .shutdown = atlas7_wdt_shutdown,
};
module_platform_driver(atlas7_wdt_driver);
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index 1834524ae373..560c1c54c177 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -177,7 +177,6 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
wdt = devm_kzalloc(dev, sizeof(struct bcm2835_wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
- platform_set_drvdata(pdev, wdt);
spin_lock_init(&wdt->lock);
diff --git a/drivers/watchdog/bcm7038_wdt.c b/drivers/watchdog/bcm7038_wdt.c
index ce3f646e8077..d3d88f6703d7 100644
--- a/drivers/watchdog/bcm7038_wdt.c
+++ b/drivers/watchdog/bcm7038_wdt.c
@@ -107,11 +107,15 @@ static const struct watchdog_ops bcm7038_wdt_ops = {
.get_timeleft = bcm7038_wdt_get_timeleft,
};
+static void bcm7038_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int bcm7038_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct bcm7038_watchdog *wdt;
- struct resource *res;
int err;
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
@@ -120,8 +124,7 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->base = devm_ioremap_resource(dev, res);
+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
@@ -131,6 +134,11 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
err = clk_prepare_enable(wdt->clk);
if (err)
return err;
+ err = devm_add_action_or_reset(dev,
+ bcm7038_clk_disable_unprepare,
+ wdt->clk);
+ if (err)
+ return err;
wdt->rate = clk_get_rate(wdt->clk);
/* Prevent divide-by-zero exception */
if (!wdt->rate)
@@ -148,10 +156,11 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
wdt->wdd.parent = dev;
watchdog_set_drvdata(&wdt->wdd, wdt);
- err = watchdog_register_device(&wdt->wdd);
+ watchdog_stop_on_reboot(&wdt->wdd);
+ watchdog_stop_on_unregister(&wdt->wdd);
+ err = devm_watchdog_register_device(dev, &wdt->wdd);
if (err) {
dev_err(dev, "Failed to register watchdog device\n");
- clk_disable_unprepare(wdt->clk);
return err;
}
@@ -160,19 +169,6 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int bcm7038_wdt_remove(struct platform_device *pdev)
-{
- struct bcm7038_watchdog *wdt = platform_get_drvdata(pdev);
-
- if (!nowayout)
- bcm7038_wdt_stop(&wdt->wdd);
-
- watchdog_unregister_device(&wdt->wdd);
- clk_disable_unprepare(wdt->clk);
-
- return 0;
-}
-
#ifdef CONFIG_PM_SLEEP
static int bcm7038_wdt_suspend(struct device *dev)
{
@@ -198,14 +194,6 @@ static int bcm7038_wdt_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(bcm7038_wdt_pm_ops, bcm7038_wdt_suspend,
bcm7038_wdt_resume);
-static void bcm7038_wdt_shutdown(struct platform_device *pdev)
-{
- struct bcm7038_watchdog *wdt = platform_get_drvdata(pdev);
-
- if (watchdog_active(&wdt->wdd))
- bcm7038_wdt_stop(&wdt->wdd);
-}
-
static const struct of_device_id bcm7038_wdt_match[] = {
{ .compatible = "brcm,bcm7038-wdt" },
{},
@@ -214,8 +202,6 @@ MODULE_DEVICE_TABLE(of, bcm7038_wdt_match);
static struct platform_driver bcm7038_wdt_driver = {
.probe = bcm7038_wdt_probe,
- .remove = bcm7038_wdt_remove,
- .shutdown = bcm7038_wdt_shutdown,
.driver = {
.name = "bcm7038-wdt",
.of_match_table = bcm7038_wdt_match,
diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c
index 4249b47902bd..e2ad44816359 100644
--- a/drivers/watchdog/bcm_kona_wdt.c
+++ b/drivers/watchdog/bcm_kona_wdt.c
@@ -271,16 +271,10 @@ static struct watchdog_device bcm_kona_wdt_wdd = {
.timeout = SECWDOG_MAX_COUNT >> SECWDOG_DEFAULT_RESOLUTION,
};
-static void bcm_kona_wdt_shutdown(struct platform_device *pdev)
-{
- bcm_kona_wdt_stop(&bcm_kona_wdt_wdd);
-}
-
static int bcm_kona_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct bcm_kona_wdt *wdt;
- struct resource *res;
int ret;
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
@@ -289,8 +283,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
spin_lock_init(&wdt->lock);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->base = devm_ioremap_resource(dev, res);
+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return -ENODEV;
@@ -303,7 +296,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt);
watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
- bcm_kona_wdt_wdd.parent = &pdev->dev;
+ bcm_kona_wdt_wdd.parent = dev;
ret = bcm_kona_wdt_set_timeout_reg(&bcm_kona_wdt_wdd, 0);
if (ret) {
@@ -311,7 +304,9 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
return ret;
}
- ret = watchdog_register_device(&bcm_kona_wdt_wdd);
+ watchdog_stop_on_reboot(&bcm_kona_wdt_wdd);
+ watchdog_stop_on_unregister(&bcm_kona_wdt_wdd);
+ ret = devm_watchdog_register_device(dev, &bcm_kona_wdt_wdd);
if (ret) {
dev_err(dev, "Failed to register watchdog device");
return ret;
@@ -326,8 +321,6 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
static int bcm_kona_wdt_remove(struct platform_device *pdev)
{
bcm_kona_wdt_debug_exit(pdev);
- bcm_kona_wdt_shutdown(pdev);
- watchdog_unregister_device(&bcm_kona_wdt_wdd);
dev_dbg(&pdev->dev, "Watchdog driver disabled");
return 0;
@@ -346,7 +339,6 @@ static struct platform_driver bcm_kona_wdt_driver = {
},
.probe = bcm_kona_wdt_probe,
.remove = bcm_kona_wdt_remove,
- .shutdown = bcm_kona_wdt_shutdown,
};
module_platform_driver(bcm_kona_wdt_driver);
diff --git a/drivers/watchdog/bd70528_wdt.c b/drivers/watchdog/bd70528_wdt.c
new file mode 100644
index 000000000000..b0152fef4fc7
--- /dev/null
+++ b/drivers/watchdog/bd70528_wdt.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 ROHM Semiconductors
+// ROHM BD70528MWV watchdog driver
+
+#include <linux/bcd.h>
+#include <linux/kernel.h>
+#include <linux/mfd/rohm-bd70528.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/watchdog.h>
+
+/*
+ * Max time we can set is 1 hour, 59 minutes and 59 seconds
+ * and Minimum time is 1 second
+ */
+#define WDT_MAX_MS ((2 * 60 * 60 - 1) * 1000)
+#define WDT_MIN_MS 1000
+#define DEFAULT_TIMEOUT 60
+
+#define WD_CTRL_MAGIC1 0x55
+#define WD_CTRL_MAGIC2 0xAA
+
+struct wdtbd70528 {
+ struct device *dev;
+ struct regmap *regmap;
+ struct rohm_regmap_dev *mfd;
+ struct watchdog_device wdt;
+};
+
+/**
+ * bd70528_wdt_set - arm or disarm watchdog timer
+ *
+ * @data: device data for the PMIC instance we want to operate on
+ * @enable: new state of WDT. zero to disable, non zero to enable
+ * @old_state: previous state of WDT will be filled here
+ *
+ * Arm or disarm WDT on BD70528 PMIC. Expected to be called only by
+ * BD70528 RTC and BD70528 WDT drivers. The rtc_timer_lock must be taken
+ * by calling bd70528_wdt_lock before calling bd70528_wdt_set.
+ */
+int bd70528_wdt_set(struct rohm_regmap_dev *data, int enable, int *old_state)
+{
+ int ret, i;
+ unsigned int tmp;
+ struct bd70528_data *bd70528 = container_of(data, struct bd70528_data,
+ chip);
+ u8 wd_ctrl_arr[3] = { WD_CTRL_MAGIC1, WD_CTRL_MAGIC2, 0 };
+ u8 *wd_ctrl = &wd_ctrl_arr[2];
+
+ ret = regmap_read(bd70528->chip.regmap, BD70528_REG_WDT_CTRL, &tmp);
+ if (ret)
+ return ret;
+
+ *wd_ctrl = (u8)tmp;
+
+ if (old_state) {
+ if (*wd_ctrl & BD70528_MASK_WDT_EN)
+ *old_state |= BD70528_WDT_STATE_BIT;
+ else
+ *old_state &= ~BD70528_WDT_STATE_BIT;
+ if ((!enable) == (!(*old_state & BD70528_WDT_STATE_BIT)))
+ return 0;
+ }
+
+ if (enable) {
+ if (*wd_ctrl & BD70528_MASK_WDT_EN)
+ return 0;
+ *wd_ctrl |= BD70528_MASK_WDT_EN;
+ } else {
+ if (*wd_ctrl & BD70528_MASK_WDT_EN)
+ *wd_ctrl &= ~BD70528_MASK_WDT_EN;
+ else
+ return 0;
+ }
+
+ for (i = 0; i < 3; i++) {
+ ret = regmap_write(bd70528->chip.regmap, BD70528_REG_WDT_CTRL,
+ wd_ctrl_arr[i]);
+ if (ret)
+ return ret;
+ }
+
+ ret = regmap_read(bd70528->chip.regmap, BD70528_REG_WDT_CTRL, &tmp);
+ if ((tmp & BD70528_MASK_WDT_EN) != (*wd_ctrl & BD70528_MASK_WDT_EN)) {
+ dev_err(bd70528->chip.dev,
+ "Watchdog ctrl mismatch (hw) 0x%x (set) 0x%x\n",
+ tmp, *wd_ctrl);
+ ret = -EIO;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(bd70528_wdt_set);
+
+/**
+ * bd70528_wdt_lock - take WDT lock
+ *
+ * @bd70528: device data for the PMIC instance we want to operate on
+ *
+ * Lock WDT for arming/disarming in order to avoid race condition caused
+ * by WDT state changes initiated by WDT and RTC drivers.
+ */
+void bd70528_wdt_lock(struct rohm_regmap_dev *data)
+{
+ struct bd70528_data *bd70528 = container_of(data, struct bd70528_data,
+ chip);
+
+ mutex_lock(&bd70528->rtc_timer_lock);
+}
+EXPORT_SYMBOL(bd70528_wdt_lock);
+
+/**
+ * bd70528_wdt_unlock - unlock WDT lock
+ *
+ * @bd70528: device data for the PMIC instance we want to operate on
+ *
+ * Unlock WDT lock which has previously been taken by call to
+ * bd70528_wdt_lock.
+ */
+void bd70528_wdt_unlock(struct rohm_regmap_dev *data)
+{
+ struct bd70528_data *bd70528 = container_of(data, struct bd70528_data,
+ chip);
+
+ mutex_unlock(&bd70528->rtc_timer_lock);
+}
+EXPORT_SYMBOL(bd70528_wdt_unlock);
+
+static int bd70528_wdt_set_locked(struct wdtbd70528 *w, int enable)
+{
+ return bd70528_wdt_set(w->mfd, enable, NULL);
+}
+
+static int bd70528_wdt_change(struct wdtbd70528 *w, int enable)
+{
+ int ret;
+
+ bd70528_wdt_lock(w->mfd);
+ ret = bd70528_wdt_set_locked(w, enable);
+ bd70528_wdt_unlock(w->mfd);
+
+ return ret;
+}
+
+static int bd70528_wdt_start(struct watchdog_device *wdt)
+{
+ struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
+
+ dev_dbg(w->dev, "WDT ping...\n");
+ return bd70528_wdt_change(w, 1);
+}
+
+static int bd70528_wdt_stop(struct watchdog_device *wdt)
+{
+ struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
+
+ dev_dbg(w->dev, "WDT stopping...\n");
+ return bd70528_wdt_change(w, 0);
+}
+
+static int bd70528_wdt_set_timeout(struct watchdog_device *wdt,
+ unsigned int timeout)
+{
+ unsigned int hours;
+ unsigned int minutes;
+ unsigned int seconds;
+ int ret;
+ struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
+
+ seconds = timeout;
+ hours = timeout / (60 * 60);
+ /* Maximum timeout is 1h 59m 59s => hours is 1 or 0 */
+ if (hours)
+ seconds -= (60 * 60);
+ minutes = seconds / 60;
+ seconds = seconds % 60;
+
+ bd70528_wdt_lock(w->mfd);
+
+ ret = bd70528_wdt_set_locked(w, 0);
+ if (ret)
+ goto out_unlock;
+
+ ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_HOUR,
+ BD70528_MASK_WDT_HOUR, hours);
+ if (ret) {
+ dev_err(w->dev, "Failed to set WDT hours\n");
+ goto out_en_unlock;
+ }
+ ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_MINUTE,
+ BD70528_MASK_WDT_MINUTE, bin2bcd(minutes));
+ if (ret) {
+ dev_err(w->dev, "Failed to set WDT minutes\n");
+ goto out_en_unlock;
+ }
+ ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_SEC,
+ BD70528_MASK_WDT_SEC, bin2bcd(seconds));
+ if (ret)
+ dev_err(w->dev, "Failed to set WDT seconds\n");
+ else
+ dev_dbg(w->dev, "WDT tmo set to %u\n", timeout);
+
+out_en_unlock:
+ ret = bd70528_wdt_set_locked(w, 1);
+out_unlock:
+ bd70528_wdt_unlock(w->mfd);
+
+ return ret;
+}
+
+static const struct watchdog_info bd70528_wdt_info = {
+ .identity = "bd70528-wdt",
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
+};
+
+static const struct watchdog_ops bd70528_wdt_ops = {
+ .start = bd70528_wdt_start,
+ .stop = bd70528_wdt_stop,
+ .set_timeout = bd70528_wdt_set_timeout,
+};
+
+static int bd70528_wdt_probe(struct platform_device *pdev)
+{
+ struct rohm_regmap_dev *bd70528;
+ struct wdtbd70528 *w;
+ int ret;
+ unsigned int reg;
+
+ bd70528 = dev_get_drvdata(pdev->dev.parent);
+ if (!bd70528) {
+ dev_err(&pdev->dev, "No MFD driver data\n");
+ return -EINVAL;
+ }
+ w = devm_kzalloc(&pdev->dev, sizeof(*w), GFP_KERNEL);
+ if (!w)
+ return -ENOMEM;
+
+ w->regmap = bd70528->regmap;
+ w->mfd = bd70528;
+ w->dev = &pdev->dev;
+
+ w->wdt.info = &bd70528_wdt_info;
+ w->wdt.ops = &bd70528_wdt_ops;
+ w->wdt.min_hw_heartbeat_ms = WDT_MIN_MS;
+ w->wdt.max_hw_heartbeat_ms = WDT_MAX_MS;
+ w->wdt.parent = pdev->dev.parent;
+ w->wdt.timeout = DEFAULT_TIMEOUT;
+ watchdog_set_drvdata(&w->wdt, w);
+ watchdog_init_timeout(&w->wdt, 0, pdev->dev.parent);
+
+ ret = bd70528_wdt_set_timeout(&w->wdt, w->wdt.timeout);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to set the watchdog timeout\n");
+ return ret;
+ }
+
+ bd70528_wdt_lock(w->mfd);
+ ret = regmap_read(w->regmap, BD70528_REG_WDT_CTRL, &reg);
+ bd70528_wdt_unlock(w->mfd);
+
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to get the watchdog state\n");
+ return ret;
+ }
+ if (reg & BD70528_MASK_WDT_EN) {
+ dev_dbg(&pdev->dev, "watchdog was running during probe\n");
+ set_bit(WDOG_HW_RUNNING, &w->wdt.status);
+ }
+
+ ret = devm_watchdog_register_device(&pdev->dev, &w->wdt);
+ if (ret < 0)
+ dev_err(&pdev->dev, "watchdog registration failed: %d\n", ret);
+
+ return ret;
+}
+
+static struct platform_driver bd70528_wdt = {
+ .driver = {
+ .name = "bd70528-wdt"
+ },
+ .probe = bd70528_wdt_probe,
+};
+
+module_platform_driver(bd70528_wdt);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("BD70528 watchdog driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c
index c3924356d173..a22f2d431a35 100644
--- a/drivers/watchdog/cadence_wdt.c
+++ b/drivers/watchdog/cadence_wdt.c
@@ -274,6 +274,11 @@ static const struct watchdog_ops cdns_wdt_ops = {
.set_timeout = cdns_wdt_settimeout,
};
+static void cdns_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
/************************Platform Operations*****************************/
/**
* cdns_wdt_probe - Probe call for the device.
@@ -285,13 +290,13 @@ static const struct watchdog_ops cdns_wdt_ops = {
*/
static int cdns_wdt_probe(struct platform_device *pdev)
{
- struct resource *res;
+ struct device *dev = &pdev->dev;
int ret, irq;
unsigned long clock_f;
struct cdns_wdt *wdt;
struct watchdog_device *cdns_wdt_device;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -302,19 +307,18 @@ static int cdns_wdt_probe(struct platform_device *pdev)
cdns_wdt_device->min_timeout = CDNS_WDT_MIN_TIMEOUT;
cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->regs = devm_ioremap_resource(&pdev->dev, res);
+ wdt->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->regs))
return PTR_ERR(wdt->regs);
/* Register the interrupt */
- wdt->rst = of_property_read_bool(pdev->dev.of_node, "reset-on-timeout");
+ wdt->rst = of_property_read_bool(dev->of_node, "reset-on-timeout");
irq = platform_get_irq(pdev, 0);
if (!wdt->rst && irq >= 0) {
- ret = devm_request_irq(&pdev->dev, irq, cdns_wdt_irq_handler, 0,
+ ret = devm_request_irq(dev, irq, cdns_wdt_irq_handler, 0,
pdev->name, pdev);
if (ret) {
- dev_err(&pdev->dev,
+ dev_err(dev,
"cannot register interrupt handler err=%d\n",
ret);
return ret;
@@ -322,30 +326,28 @@ static int cdns_wdt_probe(struct platform_device *pdev)
}
/* Initialize the members of cdns_wdt structure */
- cdns_wdt_device->parent = &pdev->dev;
-
- ret = watchdog_init_timeout(cdns_wdt_device, wdt_timeout, &pdev->dev);
- if (ret) {
- dev_err(&pdev->dev, "unable to set timeout value\n");
- return ret;
- }
+ cdns_wdt_device->parent = dev;
+ watchdog_init_timeout(cdns_wdt_device, wdt_timeout, dev);
watchdog_set_nowayout(cdns_wdt_device, nowayout);
watchdog_stop_on_reboot(cdns_wdt_device);
watchdog_set_drvdata(cdns_wdt_device, wdt);
- wdt->clk = devm_clk_get(&pdev->dev, NULL);
+ wdt->clk = devm_clk_get(dev, NULL);
if (IS_ERR(wdt->clk)) {
- dev_err(&pdev->dev, "input clock not found\n");
- ret = PTR_ERR(wdt->clk);
- return ret;
+ dev_err(dev, "input clock not found\n");
+ return PTR_ERR(wdt->clk);
}
ret = clk_prepare_enable(wdt->clk);
if (ret) {
- dev_err(&pdev->dev, "unable to enable clock\n");
+ dev_err(dev, "unable to enable clock\n");
return ret;
}
+ ret = devm_add_action_or_reset(dev, cdns_clk_disable_unprepare,
+ wdt->clk);
+ if (ret)
+ return ret;
clock_f = clk_get_rate(wdt->clk);
if (clock_f <= CDNS_WDT_CLK_75MHZ) {
@@ -358,56 +360,20 @@ static int cdns_wdt_probe(struct platform_device *pdev)
spin_lock_init(&wdt->io_lock);
- ret = watchdog_register_device(cdns_wdt_device);
+ watchdog_stop_on_reboot(cdns_wdt_device);
+ watchdog_stop_on_unregister(cdns_wdt_device);
+ ret = devm_watchdog_register_device(dev, cdns_wdt_device);
if (ret) {
- dev_err(&pdev->dev, "Failed to register wdt device\n");
- goto err_clk_disable;
+ dev_err(dev, "Failed to register wdt device\n");
+ return ret;
}
platform_set_drvdata(pdev, wdt);
- dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
+ dev_info(dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
wdt->regs, cdns_wdt_device->timeout,
nowayout ? ", nowayout" : "");
return 0;
-
-err_clk_disable:
- clk_disable_unprepare(wdt->clk);
-
- return ret;
-}
-
-/**
- * cdns_wdt_remove - Probe call for the device.
- *
- * @pdev: handle to the platform device structure.
- * Return: 0 on success, otherwise negative error.
- *
- * Unregister the device after releasing the resources.
- */
-static int cdns_wdt_remove(struct platform_device *pdev)
-{
- struct cdns_wdt *wdt = platform_get_drvdata(pdev);
-
- cdns_wdt_stop(&wdt->cdns_wdt_device);
- watchdog_unregister_device(&wdt->cdns_wdt_device);
- clk_disable_unprepare(wdt->clk);
-
- return 0;
-}
-
-/**
- * cdns_wdt_shutdown - Stop the device.
- *
- * @pdev: handle to the platform structure.
- *
- */
-static void cdns_wdt_shutdown(struct platform_device *pdev)
-{
- struct cdns_wdt *wdt = platform_get_drvdata(pdev);
-
- cdns_wdt_stop(&wdt->cdns_wdt_device);
- clk_disable_unprepare(wdt->clk);
}
/**
@@ -462,8 +428,6 @@ MODULE_DEVICE_TABLE(of, cdns_wdt_of_match);
/* Driver Structure */
static struct platform_driver cdns_wdt_driver = {
.probe = cdns_wdt_probe,
- .remove = cdns_wdt_remove,
- .shutdown = cdns_wdt_shutdown,
.driver = {
.name = "cdns-wdt",
.of_match_table = cdns_wdt_of_match,
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index f29d1edc5bad..260c50b08483 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -6,7 +6,7 @@
* Watchdog driver for the ST-Ericsson AB COH 901 327 IP core
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
-#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/mod_devicetable.h>
#include <linux/types.h>
#include <linux/watchdog.h>
@@ -243,27 +243,15 @@ static struct watchdog_device coh901327_wdt = {
.timeout = U300_WDOG_DEFAULT_TIMEOUT,
};
-static int __exit coh901327_remove(struct platform_device *pdev)
-{
- watchdog_unregister_device(&coh901327_wdt);
- coh901327_disable();
- free_irq(irq, pdev);
- clk_disable_unprepare(clk);
- clk_put(clk);
- return 0;
-}
-
static int __init coh901327_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int ret;
u16 val;
- struct resource *res;
parent = dev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- virtbase = devm_ioremap_resource(dev, res);
+ virtbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(virtbase))
return PTR_ERR(virtbase);
@@ -408,19 +396,13 @@ static struct platform_driver coh901327_driver = {
.driver = {
.name = "coh901327_wdog",
.of_match_table = coh901327_dt_match,
+ .suppress_bind_attrs = true,
},
- .remove = __exit_p(coh901327_remove),
.suspend = coh901327_suspend,
.resume = coh901327_resume,
};
+builtin_platform_driver_probe(coh901327_driver, coh901327_probe);
-module_platform_driver_probe(coh901327_driver, coh901327_probe);
-
-MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
-MODULE_DESCRIPTION("COH 901 327 Watchdog");
-
+/* not really modular, but ... */
module_param(margin, uint, 0);
MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
-
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:coh901327-watchdog");
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
index e263bad99574..a2feef1ff307 100644
--- a/drivers/watchdog/da9052_wdt.c
+++ b/drivers/watchdog/da9052_wdt.c
@@ -150,13 +150,13 @@ static const struct watchdog_ops da9052_wdt_ops = {
static int da9052_wdt_probe(struct platform_device *pdev)
{
- struct da9052 *da9052 = dev_get_drvdata(pdev->dev.parent);
+ struct device *dev = &pdev->dev;
+ struct da9052 *da9052 = dev_get_drvdata(dev->parent);
struct da9052_wdt_data *driver_data;
struct watchdog_device *da9052_wdt;
int ret;
- driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data),
- GFP_KERNEL);
+ driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
if (!driver_data)
return -ENOMEM;
driver_data->da9052 = da9052;
@@ -166,18 +166,17 @@ static int da9052_wdt_probe(struct platform_device *pdev)
da9052_wdt->timeout = DA9052_DEF_TIMEOUT;
da9052_wdt->info = &da9052_wdt_info;
da9052_wdt->ops = &da9052_wdt_ops;
- da9052_wdt->parent = &pdev->dev;
+ da9052_wdt->parent = dev;
watchdog_set_drvdata(da9052_wdt, driver_data);
ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG,
DA9052_CONTROLD_TWDSCALE, 0);
if (ret < 0) {
- dev_err(&pdev->dev, "Failed to disable watchdog bits, %d\n",
- ret);
+ dev_err(dev, "Failed to disable watchdog bits, %d\n", ret);
return ret;
}
- ret = devm_watchdog_register_device(&pdev->dev, &driver_data->wdt);
+ ret = devm_watchdog_register_device(dev, &driver_data->wdt);
if (ret != 0) {
dev_err(da9052->dev, "watchdog_register_device() failed: %d\n",
ret);
diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c
index 26a5b2984094..389a4bdd208c 100644
--- a/drivers/watchdog/da9055_wdt.c
+++ b/drivers/watchdog/da9055_wdt.c
@@ -119,13 +119,13 @@ static const struct watchdog_ops da9055_wdt_ops = {
static int da9055_wdt_probe(struct platform_device *pdev)
{
- struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent);
+ struct device *dev = &pdev->dev;
+ struct da9055 *da9055 = dev_get_drvdata(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);
+ driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
if (!driver_data)
return -ENOMEM;
@@ -136,17 +136,17 @@ static int da9055_wdt_probe(struct platform_device *pdev)
da9055_wdt->timeout = DA9055_DEF_TIMEOUT;
da9055_wdt->info = &da9055_wdt_info;
da9055_wdt->ops = &da9055_wdt_ops;
- da9055_wdt->parent = &pdev->dev;
+ da9055_wdt->parent = dev;
watchdog_set_nowayout(da9055_wdt, nowayout);
watchdog_set_drvdata(da9055_wdt, driver_data);
ret = da9055_wdt_stop(da9055_wdt);
if (ret < 0) {
- dev_err(&pdev->dev, "Failed to stop watchdog, %d\n", ret);
+ dev_err(dev, "Failed to stop watchdog, %d\n", ret);
return ret;
}
- ret = devm_watchdog_register_device(&pdev->dev, &driver_data->wdt);
+ ret = devm_watchdog_register_device(dev, &driver_data->wdt);
if (ret != 0)
dev_err(da9055->dev, "watchdog_register_device() failed: %d\n",
ret);
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
index fe169d8e1fb2..aac749cfaccb 100644
--- a/drivers/watchdog/da9062_wdt.c
+++ b/drivers/watchdog/da9062_wdt.c
@@ -46,14 +46,9 @@ static unsigned int da9062_wdt_timeout_to_sel(unsigned int secs)
static int da9062_reset_watchdog_timer(struct da9062_watchdog *wdt)
{
- int ret;
-
- ret = regmap_update_bits(wdt->hw->regmap,
- DA9062AA_CONTROL_F,
- DA9062AA_WATCHDOG_MASK,
- DA9062AA_WATCHDOG_MASK);
-
- return ret;
+ return regmap_update_bits(wdt->hw->regmap, DA9062AA_CONTROL_F,
+ DA9062AA_WATCHDOG_MASK,
+ DA9062AA_WATCHDOG_MASK);
}
static int da9062_wdt_update_timeout_register(struct da9062_watchdog *wdt,
@@ -190,15 +185,16 @@ MODULE_DEVICE_TABLE(of, da9062_compatible_id_table);
static int da9062_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int ret;
struct da9062 *chip;
struct da9062_watchdog *wdt;
- chip = dev_get_drvdata(pdev->dev.parent);
+ chip = dev_get_drvdata(dev->parent);
if (!chip)
return -EINVAL;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -211,13 +207,13 @@ static int da9062_wdt_probe(struct platform_device *pdev)
wdt->wdtdev.min_hw_heartbeat_ms = DA9062_RESET_PROTECTION_MS;
wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
- wdt->wdtdev.parent = &pdev->dev;
+ wdt->wdtdev.parent = dev;
watchdog_set_restart_priority(&wdt->wdtdev, 128);
watchdog_set_drvdata(&wdt->wdtdev, wdt);
- ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev);
+ ret = devm_watchdog_register_device(dev, &wdt->wdtdev);
if (ret < 0) {
dev_err(wdt->hw->dev,
"watchdog registration failed (%d)\n", ret);
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
index 384dca16af8b..3d65e92a4e3f 100644
--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -188,17 +188,18 @@ static const struct watchdog_ops da9063_watchdog_ops = {
static int da9063_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct da9063 *da9063;
struct watchdog_device *wdd;
- if (!pdev->dev.parent)
+ if (!dev->parent)
return -EINVAL;
- da9063 = dev_get_drvdata(pdev->dev.parent);
+ da9063 = dev_get_drvdata(dev->parent);
if (!da9063)
return -EINVAL;
- wdd = devm_kzalloc(&pdev->dev, sizeof(*wdd), GFP_KERNEL);
+ wdd = devm_kzalloc(dev, sizeof(*wdd), GFP_KERNEL);
if (!wdd)
return -ENOMEM;
@@ -207,22 +208,24 @@ static int da9063_wdt_probe(struct platform_device *pdev)
wdd->min_timeout = DA9063_WDT_MIN_TIMEOUT;
wdd->max_timeout = DA9063_WDT_MAX_TIMEOUT;
wdd->min_hw_heartbeat_ms = DA9063_RESET_PROTECTION_MS;
- wdd->timeout = DA9063_WDG_TIMEOUT;
- wdd->parent = &pdev->dev;
-
+ wdd->parent = dev;
wdd->status = WATCHDOG_NOWAYOUT_INIT_STATUS;
watchdog_set_restart_priority(wdd, 128);
-
watchdog_set_drvdata(wdd, da9063);
+ /* Set default timeout, maybe override it with DT value, scale it */
+ wdd->timeout = DA9063_WDG_TIMEOUT;
+ watchdog_init_timeout(wdd, 0, dev);
+ da9063_wdt_set_timeout(wdd, wdd->timeout);
+
/* Change the timeout to the default value if the watchdog is running */
if (da9063_wdt_is_running(da9063)) {
- da9063_wdt_update_timeout(da9063, DA9063_WDG_TIMEOUT);
+ da9063_wdt_update_timeout(da9063, wdd->timeout);
set_bit(WDOG_HW_RUNNING, &wdd->status);
}
- return devm_watchdog_register_device(&pdev->dev, wdd);
+ return devm_watchdog_register_device(dev, wdd);
}
static struct platform_driver da9063_wdt_driver = {
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index ebb85d60b6d5..7b2ee35b5ffd 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -191,11 +191,15 @@ static const struct watchdog_ops davinci_wdt_ops = {
.restart = davinci_wdt_restart,
};
+static void davinci_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int davinci_wdt_probe(struct platform_device *pdev)
{
int ret = 0;
struct device *dev = &pdev->dev;
- struct resource *wdt_mem;
struct watchdog_device *wdd;
struct davinci_wdt_device *davinci_wdt;
@@ -207,15 +211,19 @@ static int davinci_wdt_probe(struct platform_device *pdev)
if (IS_ERR(davinci_wdt->clk)) {
if (PTR_ERR(davinci_wdt->clk) != -EPROBE_DEFER)
- dev_err(&pdev->dev, "failed to get clock node\n");
+ dev_err(dev, "failed to get clock node\n");
return PTR_ERR(davinci_wdt->clk);
}
ret = clk_prepare_enable(davinci_wdt->clk);
if (ret) {
- dev_err(&pdev->dev, "failed to prepare clock\n");
+ dev_err(dev, "failed to prepare clock\n");
return ret;
}
+ ret = devm_add_action_or_reset(dev, davinci_clk_disable_unprepare,
+ davinci_wdt->clk);
+ if (ret)
+ return ret;
platform_set_drvdata(pdev, davinci_wdt);
@@ -225,7 +233,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
wdd->min_timeout = 1;
wdd->max_timeout = MAX_HEARTBEAT;
wdd->timeout = DEFAULT_HEARTBEAT;
- wdd->parent = &pdev->dev;
+ wdd->parent = dev;
watchdog_init_timeout(wdd, heartbeat, dev);
@@ -235,35 +243,17 @@ static int davinci_wdt_probe(struct platform_device *pdev)
watchdog_set_nowayout(wdd, 1);
watchdog_set_restart_priority(wdd, 128);
- wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem);
- if (IS_ERR(davinci_wdt->base)) {
- ret = PTR_ERR(davinci_wdt->base);
- goto err_clk_disable;
- }
+ davinci_wdt->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(davinci_wdt->base))
+ return PTR_ERR(davinci_wdt->base);
- ret = watchdog_register_device(wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "cannot register watchdog device\n");
- goto err_clk_disable;
+ return ret;
}
return 0;
-
-err_clk_disable:
- clk_disable_unprepare(davinci_wdt->clk);
-
- return ret;
-}
-
-static int davinci_wdt_remove(struct platform_device *pdev)
-{
- struct davinci_wdt_device *davinci_wdt = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&davinci_wdt->wdd);
- clk_disable_unprepare(davinci_wdt->clk);
-
- return 0;
}
static const struct of_device_id davinci_wdt_of_match[] = {
@@ -278,7 +268,6 @@ static struct platform_driver platform_wdt_driver = {
.of_match_table = davinci_wdt_of_match,
},
.probe = davinci_wdt_probe,
- .remove = davinci_wdt_remove,
};
module_platform_driver(platform_wdt_driver);
diff --git a/drivers/watchdog/digicolor_wdt.c b/drivers/watchdog/digicolor_wdt.c
index a9e11df155b8..8af6e9a67d0d 100644
--- a/drivers/watchdog/digicolor_wdt.c
+++ b/drivers/watchdog/digicolor_wdt.c
@@ -116,7 +116,6 @@ static struct watchdog_device dc_wdt_wdd = {
static int dc_wdt_probe(struct platform_device *pdev)
{
- struct resource *res;
struct device *dev = &pdev->dev;
struct dc_wdt *wdt;
int ret;
@@ -125,8 +124,7 @@ static int dc_wdt_probe(struct platform_device *pdev)
if (!wdt)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->base = devm_ioremap_resource(dev, res);
+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index aa95f57cc1c3..39e43750ab08 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -238,15 +238,13 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct watchdog_device *wdd;
struct dw_wdt *dw_wdt;
- struct resource *mem;
int ret;
dw_wdt = devm_kzalloc(dev, sizeof(*dw_wdt), GFP_KERNEL);
if (!dw_wdt)
return -ENOMEM;
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dw_wdt->regs = devm_ioremap_resource(dev, mem);
+ dw_wdt->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dw_wdt->regs))
return PTR_ERR(dw_wdt->regs);
diff --git a/drivers/watchdog/ebc-c384_wdt.c b/drivers/watchdog/ebc-c384_wdt.c
index 4c4c8ce78021..c176f59fea28 100644
--- a/drivers/watchdog/ebc-c384_wdt.c
+++ b/drivers/watchdog/ebc-c384_wdt.c
@@ -117,10 +117,7 @@ static int ebc_c384_wdt_probe(struct device *dev, unsigned int id)
wdd->max_timeout = WATCHDOG_MAX_TIMEOUT;
watchdog_set_nowayout(wdd, nowayout);
-
- if (watchdog_init_timeout(wdd, timeout, dev))
- dev_warn(dev, "Invalid timeout (%u seconds), using default (%u seconds)\n",
- timeout, WATCHDOG_TIMEOUT);
+ watchdog_init_timeout(wdd, timeout, dev);
return devm_watchdog_register_device(dev, wdd);
}
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index f9b14e6efd9a..38e26f160b9a 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -89,18 +89,17 @@ static const struct watchdog_ops ep93xx_wdt_ops = {
static int ep93xx_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct ep93xx_wdt_priv *priv;
struct watchdog_device *wdd;
- struct resource *res;
unsigned long val;
int ret;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->mmio = devm_ioremap_resource(&pdev->dev, res);
+ priv->mmio = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->mmio))
return PTR_ERR(priv->mmio);
@@ -112,21 +111,21 @@ static int ep93xx_wdt_probe(struct platform_device *pdev)
wdd->ops = &ep93xx_wdt_ops;
wdd->min_timeout = 1;
wdd->max_hw_heartbeat_ms = 200;
- wdd->parent = &pdev->dev;
+ wdd->parent = dev;
watchdog_set_nowayout(wdd, nowayout);
wdd->timeout = WDT_TIMEOUT;
- watchdog_init_timeout(wdd, timeout, &pdev->dev);
+ watchdog_init_timeout(wdd, timeout, dev);
watchdog_set_drvdata(wdd, priv);
- ret = devm_watchdog_register_device(&pdev->dev, wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret)
return ret;
- dev_info(&pdev->dev, "EP93XX watchdog driver %s\n",
- (val & 0x08) ? " (nCS1 disable detected)" : "");
+ dev_info(dev, "EP93XX watchdog driver %s\n",
+ (val & 0x08) ? " (nCS1 disable detected)" : "");
return 0;
}
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index 021c6ace9462..041172e6c469 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -338,8 +338,11 @@ static int f71862fg_pin_configure(unsigned short ioaddr)
static int watchdog_start(void)
{
+ int err;
+ u8 tmp;
+
/* Make sure we don't die as soon as the watchdog is enabled below */
- int err = watchdog_keepalive();
+ err = watchdog_keepalive();
if (err)
return err;
@@ -386,19 +389,18 @@ static int watchdog_start(void)
break;
case f81866:
- /* Set pin 70 to WDTRST# */
- superio_clear_bit(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL,
- BIT(3) | BIT(0));
- superio_set_bit(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL,
- BIT(2));
/*
* GPIO1 Control Register when 27h BIT3:2 = 01 & BIT0 = 0.
* The PIN 70(GPIO15/WDTRST) is controlled by 2Ch:
* BIT5: 0 -> WDTRST#
* 1 -> GPIO15
*/
- superio_clear_bit(watchdog.sioaddr, SIO_F81866_REG_GPIO1,
- BIT(5));
+ tmp = superio_inb(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL);
+ tmp &= ~(BIT(3) | BIT(0));
+ tmp |= BIT(2);
+ superio_outb(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL, tmp);
+
+ superio_clear_bit(watchdog.sioaddr, SIO_F81866_REG_GPIO1, 5);
break;
default:
diff --git a/drivers/watchdog/ftwdt010_wdt.c b/drivers/watchdog/ftwdt010_wdt.c
index a9c2912ee280..9ea0e56fa7ee 100644
--- a/drivers/watchdog/ftwdt010_wdt.c
+++ b/drivers/watchdog/ftwdt010_wdt.c
@@ -124,7 +124,6 @@ static const struct watchdog_info ftwdt010_wdt_info = {
static int ftwdt010_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct resource *res;
struct ftwdt010_wdt *gwdt;
unsigned int reg;
int irq;
@@ -134,8 +133,7 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)
if (!gwdt)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- gwdt->base = devm_ioremap_resource(dev, res);
+ gwdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(gwdt->base))
return PTR_ERR(gwdt->base);
@@ -171,7 +169,7 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)
ret = devm_watchdog_register_device(dev, &gwdt->wdd);
if (ret) {
- dev_err(&pdev->dev, "failed to register watchdog\n");
+ dev_err(dev, "failed to register watchdog\n");
return ret;
}
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index ea77cae03c9d..bc24674b4d9e 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -154,25 +154,14 @@ static int gpio_wdt_probe(struct platform_device *pdev)
priv->wdd.parent = dev;
priv->wdd.timeout = SOFT_TIMEOUT_DEF;
- watchdog_init_timeout(&priv->wdd, 0, &pdev->dev);
+ watchdog_init_timeout(&priv->wdd, 0, dev);
watchdog_stop_on_reboot(&priv->wdd);
if (priv->always_running)
gpio_wdt_start(&priv->wdd);
- ret = watchdog_register_device(&priv->wdd);
-
- return ret;
-}
-
-static int gpio_wdt_remove(struct platform_device *pdev)
-{
- struct gpio_wdt_priv *priv = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&priv->wdd);
-
- return 0;
+ return devm_watchdog_register_device(dev, &priv->wdd);
}
static const struct of_device_id gpio_wdt_dt_ids[] = {
@@ -187,7 +176,6 @@ static struct platform_driver gpio_wdt_driver = {
.of_match_table = gpio_wdt_dt_ids,
},
.probe = gpio_wdt_probe,
- .remove = gpio_wdt_remove,
};
#ifdef CONFIG_GPIO_WATCHDOG_ARCH_INITCALL
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index ef30c7e9728d..db1bf6f546ae 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -311,8 +311,7 @@ static int hpwdt_init_one(struct pci_dev *dev,
goto error_init_nmi_decoding;
watchdog_set_nowayout(&hpwdt_dev, nowayout);
- if (watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL))
- dev_warn(&dev->dev, "Invalid soft_margin: %d.\n", soft_margin);
+ watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL);
if (pretimeout && hpwdt_dev.timeout <= PRETIMEOUT_SEC) {
dev_warn(&dev->dev, "timeout <= pretimeout. Setting pretimeout to zero\n");
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index 950c71a8bb22..17941c03996b 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -311,10 +311,7 @@ static int esb_probe(struct pci_dev *pdev,
edev->wdd.min_timeout = ESB_HEARTBEAT_MIN;
edev->wdd.max_timeout = ESB_HEARTBEAT_MAX;
edev->wdd.timeout = ESB_HEARTBEAT_DEFAULT;
- if (watchdog_init_timeout(&edev->wdd, heartbeat, NULL))
- dev_info(&pdev->dev,
- "heartbeat value must be " ESB_HEARTBEAT_RANGE
- ", using %u\n", edev->wdd.timeout);
+ watchdog_init_timeout(&edev->wdd, heartbeat, NULL);
watchdog_set_nowayout(&edev->wdd, nowayout);
watchdog_stop_on_reboot(&edev->wdd);
watchdog_stop_on_unregister(&edev->wdd);
@@ -328,8 +325,8 @@ static int esb_probe(struct pci_dev *pdev,
goto err_unmap;
}
dev_info(&pdev->dev,
- "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
- edev->base, edev->wdd.timeout, nowayout);
+ "initialized. heartbeat=%d sec (nowayout=%d)\n",
+ edev->wdd.timeout, nowayout);
return 0;
err_unmap:
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 0a5318b7865e..89cea6ce9a08 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -545,6 +545,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
}
watchdog_stop_on_reboot(&p->wddev);
+ watchdog_stop_on_unregister(&p->wddev);
ret = devm_watchdog_register_device(dev, &p->wddev);
if (ret != 0) {
pr_err("cannot register watchdog device (err=%d)\n", ret);
@@ -557,17 +558,6 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int iTCO_wdt_remove(struct platform_device *pdev)
-{
- struct iTCO_wdt_private *p = platform_get_drvdata(pdev);
-
- /* Stop the timer before we leave */
- if (!nowayout)
- iTCO_wdt_stop(&p->wddev);
-
- return 0;
-}
-
#ifdef CONFIG_PM_SLEEP
/*
* Suspend-to-idle requires this, because it stops the ticks and timekeeping, so
@@ -620,7 +610,6 @@ static const struct dev_pm_ops iTCO_wdt_pm = {
static struct platform_driver iTCO_wdt_driver = {
.probe = iTCO_wdt_probe,
- .remove = iTCO_wdt_remove,
.driver = {
.name = DRV_NAME,
.pm = ITCO_WDT_PM_OPS,
diff --git a/drivers/watchdog/imgpdc_wdt.c b/drivers/watchdog/imgpdc_wdt.c
index a3134ffa59f8..0fc31aadeee3 100644
--- a/drivers/watchdog/imgpdc_wdt.c
+++ b/drivers/watchdog/imgpdc_wdt.c
@@ -178,59 +178,69 @@ static const struct watchdog_ops pdc_wdt_ops = {
.restart = pdc_wdt_restart,
};
+static void pdc_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int pdc_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
u64 div;
int ret, val;
unsigned long clk_rate;
- struct resource *res;
struct pdc_wdt_dev *pdc_wdt;
- pdc_wdt = devm_kzalloc(&pdev->dev, sizeof(*pdc_wdt), GFP_KERNEL);
+ pdc_wdt = devm_kzalloc(dev, sizeof(*pdc_wdt), GFP_KERNEL);
if (!pdc_wdt)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pdc_wdt->base = devm_ioremap_resource(&pdev->dev, res);
+ pdc_wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdc_wdt->base))
return PTR_ERR(pdc_wdt->base);
- pdc_wdt->sys_clk = devm_clk_get(&pdev->dev, "sys");
+ pdc_wdt->sys_clk = devm_clk_get(dev, "sys");
if (IS_ERR(pdc_wdt->sys_clk)) {
- dev_err(&pdev->dev, "failed to get the sys clock\n");
+ dev_err(dev, "failed to get the sys clock\n");
return PTR_ERR(pdc_wdt->sys_clk);
}
- pdc_wdt->wdt_clk = devm_clk_get(&pdev->dev, "wdt");
+ pdc_wdt->wdt_clk = devm_clk_get(dev, "wdt");
if (IS_ERR(pdc_wdt->wdt_clk)) {
- dev_err(&pdev->dev, "failed to get the wdt clock\n");
+ dev_err(dev, "failed to get the wdt clock\n");
return PTR_ERR(pdc_wdt->wdt_clk);
}
ret = clk_prepare_enable(pdc_wdt->sys_clk);
if (ret) {
- dev_err(&pdev->dev, "could not prepare or enable sys clock\n");
+ dev_err(dev, "could not prepare or enable sys clock\n");
return ret;
}
+ ret = devm_add_action_or_reset(dev, pdc_clk_disable_unprepare,
+ pdc_wdt->sys_clk);
+ if (ret)
+ return ret;
ret = clk_prepare_enable(pdc_wdt->wdt_clk);
if (ret) {
- dev_err(&pdev->dev, "could not prepare or enable wdt clock\n");
- goto disable_sys_clk;
+ dev_err(dev, "could not prepare or enable wdt clock\n");
+ return ret;
}
+ ret = devm_add_action_or_reset(dev, pdc_clk_disable_unprepare,
+ pdc_wdt->wdt_clk);
+ if (ret)
+ return ret;
/* We use the clock rate to calculate the max timeout */
clk_rate = clk_get_rate(pdc_wdt->wdt_clk);
if (clk_rate == 0) {
- dev_err(&pdev->dev, "failed to get clock rate\n");
- ret = -EINVAL;
- goto disable_wdt_clk;
+ dev_err(dev, "failed to get clock rate\n");
+ return -EINVAL;
}
if (order_base_2(clk_rate) > PDC_WDT_CONFIG_DELAY_MASK + 1) {
- dev_err(&pdev->dev, "invalid clock rate\n");
- ret = -EINVAL;
- goto disable_wdt_clk;
+ dev_err(dev, "invalid clock rate\n");
+ return -EINVAL;
}
if (order_base_2(clk_rate) == 0)
@@ -245,10 +255,10 @@ static int pdc_wdt_probe(struct platform_device *pdev)
do_div(div, clk_rate);
pdc_wdt->wdt_dev.max_timeout = div;
pdc_wdt->wdt_dev.timeout = PDC_WDT_DEF_TIMEOUT;
- pdc_wdt->wdt_dev.parent = &pdev->dev;
+ pdc_wdt->wdt_dev.parent = dev;
watchdog_set_drvdata(&pdc_wdt->wdt_dev, pdc_wdt);
- watchdog_init_timeout(&pdc_wdt->wdt_dev, heartbeat, &pdev->dev);
+ watchdog_init_timeout(&pdc_wdt->wdt_dev, heartbeat, dev);
pdc_wdt_stop(&pdc_wdt->wdt_dev);
@@ -259,24 +269,22 @@ static int pdc_wdt_probe(struct platform_device *pdev)
case PDC_WDT_TICKLE_STATUS_TICKLE:
case PDC_WDT_TICKLE_STATUS_TIMEOUT:
pdc_wdt->wdt_dev.bootstatus |= WDIOF_CARDRESET;
- dev_info(&pdev->dev,
- "watchdog module last reset due to timeout\n");
+ dev_info(dev, "watchdog module last reset due to timeout\n");
break;
case PDC_WDT_TICKLE_STATUS_HRESET:
- dev_info(&pdev->dev,
+ dev_info(dev,
"watchdog module last reset due to hard reset\n");
break;
case PDC_WDT_TICKLE_STATUS_SRESET:
- dev_info(&pdev->dev,
+ dev_info(dev,
"watchdog module last reset due to soft reset\n");
break;
case PDC_WDT_TICKLE_STATUS_USER:
- dev_info(&pdev->dev,
+ dev_info(dev,
"watchdog module last reset due to user reset\n");
break;
default:
- dev_info(&pdev->dev,
- "contains an illegal status code (%08x)\n", val);
+ dev_info(dev, "contains an illegal status code (%08x)\n", val);
break;
}
@@ -285,36 +293,9 @@ static int pdc_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pdc_wdt);
- ret = watchdog_register_device(&pdc_wdt->wdt_dev);
- if (ret)
- goto disable_wdt_clk;
-
- return 0;
-
-disable_wdt_clk:
- clk_disable_unprepare(pdc_wdt->wdt_clk);
-disable_sys_clk:
- clk_disable_unprepare(pdc_wdt->sys_clk);
- return ret;
-}
-
-static void pdc_wdt_shutdown(struct platform_device *pdev)
-{
- struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev);
-
- pdc_wdt_stop(&pdc_wdt->wdt_dev);
-}
-
-static int pdc_wdt_remove(struct platform_device *pdev)
-{
- struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev);
-
- pdc_wdt_stop(&pdc_wdt->wdt_dev);
- watchdog_unregister_device(&pdc_wdt->wdt_dev);
- clk_disable_unprepare(pdc_wdt->wdt_clk);
- clk_disable_unprepare(pdc_wdt->sys_clk);
-
- return 0;
+ watchdog_stop_on_reboot(&pdc_wdt->wdt_dev);
+ watchdog_stop_on_unregister(&pdc_wdt->wdt_dev);
+ return devm_watchdog_register_device(dev, &pdc_wdt->wdt_dev);
}
static const struct of_device_id pdc_wdt_match[] = {
@@ -329,8 +310,6 @@ static struct platform_driver pdc_wdt_driver = {
.of_match_table = pdc_wdt_match,
},
.probe = pdc_wdt_probe,
- .remove = pdc_wdt_remove,
- .shutdown = pdc_wdt_shutdown,
};
module_platform_driver(pdc_wdt_driver);
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 2b52514eaa86..a606005dd65f 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -178,8 +178,10 @@ static void __imx2_wdt_set_timeout(struct watchdog_device *wdog,
static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
unsigned int new_timeout)
{
- __imx2_wdt_set_timeout(wdog, new_timeout);
+ unsigned int actual;
+ actual = min(new_timeout, wdog->max_hw_heartbeat_ms * 1000);
+ __imx2_wdt_set_timeout(wdog, actual);
wdog->timeout = new_timeout;
return 0;
}
@@ -247,7 +249,6 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
{
struct imx2_wdt_device *wdev;
struct watchdog_device *wdog;
- struct resource *res;
void __iomem *base;
int ret;
u32 val;
@@ -256,8 +257,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
if (!wdev)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&pdev->dev, res);
+ base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
diff --git a/drivers/watchdog/imx_sc_wdt.c b/drivers/watchdog/imx_sc_wdt.c
new file mode 100644
index 000000000000..49848b66186c
--- /dev/null
+++ b/drivers/watchdog/imx_sc_wdt.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018-2019 NXP.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
+
+#define DEFAULT_TIMEOUT 60
+/*
+ * Software timer tick implemented in scfw side, support 10ms to 0xffffffff ms
+ * in theory, but for normal case, 1s~128s is enough, you can change this max
+ * value in case it's not enough.
+ */
+#define MAX_TIMEOUT 128
+
+#define IMX_SIP_TIMER 0xC2000002
+#define IMX_SIP_TIMER_START_WDOG 0x01
+#define IMX_SIP_TIMER_STOP_WDOG 0x02
+#define IMX_SIP_TIMER_SET_WDOG_ACT 0x03
+#define IMX_SIP_TIMER_PING_WDOG 0x04
+#define IMX_SIP_TIMER_SET_TIMEOUT_WDOG 0x05
+#define IMX_SIP_TIMER_GET_WDOG_STAT 0x06
+#define IMX_SIP_TIMER_SET_PRETIME_WDOG 0x07
+
+#define SC_TIMER_WDOG_ACTION_PARTITION 0
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0000);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static int imx_sc_wdt_ping(struct watchdog_device *wdog)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_PING_WDOG,
+ 0, 0, 0, 0, 0, 0, &res);
+
+ return 0;
+}
+
+static int imx_sc_wdt_start(struct watchdog_device *wdog)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_START_WDOG,
+ 0, 0, 0, 0, 0, 0, &res);
+ if (res.a0)
+ return -EACCES;
+
+ arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_WDOG_ACT,
+ SC_TIMER_WDOG_ACTION_PARTITION,
+ 0, 0, 0, 0, 0, &res);
+ return res.a0 ? -EACCES : 0;
+}
+
+static int imx_sc_wdt_stop(struct watchdog_device *wdog)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_STOP_WDOG,
+ 0, 0, 0, 0, 0, 0, &res);
+
+ return res.a0 ? -EACCES : 0;
+}
+
+static int imx_sc_wdt_set_timeout(struct watchdog_device *wdog,
+ unsigned int timeout)
+{
+ struct arm_smccc_res res;
+
+ wdog->timeout = timeout;
+ arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_TIMEOUT_WDOG,
+ timeout * 1000, 0, 0, 0, 0, 0, &res);
+
+ return res.a0 ? -EACCES : 0;
+}
+
+static const struct watchdog_ops imx_sc_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = imx_sc_wdt_start,
+ .stop = imx_sc_wdt_stop,
+ .ping = imx_sc_wdt_ping,
+ .set_timeout = imx_sc_wdt_set_timeout,
+};
+
+static const struct watchdog_info imx_sc_wdt_info = {
+ .identity = "i.MX SC watchdog timer",
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE | WDIOF_PRETIMEOUT,
+};
+
+static int imx_sc_wdt_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct watchdog_device *imx_sc_wdd;
+ int ret;
+
+ imx_sc_wdd = devm_kzalloc(dev, sizeof(*imx_sc_wdd), GFP_KERNEL);
+ if (!imx_sc_wdd)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, imx_sc_wdd);
+
+ imx_sc_wdd->info = &imx_sc_wdt_info;
+ imx_sc_wdd->ops = &imx_sc_wdt_ops;
+ imx_sc_wdd->min_timeout = 1;
+ imx_sc_wdd->max_timeout = MAX_TIMEOUT;
+ imx_sc_wdd->parent = dev;
+ imx_sc_wdd->timeout = DEFAULT_TIMEOUT;
+
+ watchdog_init_timeout(imx_sc_wdd, 0, dev);
+ watchdog_stop_on_reboot(imx_sc_wdd);
+ watchdog_stop_on_unregister(imx_sc_wdd);
+
+ ret = devm_watchdog_register_device(dev, imx_sc_wdd);
+ if (ret) {
+ dev_err(dev, "Failed to register watchdog device\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __maybe_unused imx_sc_wdt_suspend(struct device *dev)
+{
+ struct watchdog_device *imx_sc_wdd = dev_get_drvdata(dev);
+
+ if (watchdog_active(imx_sc_wdd))
+ imx_sc_wdt_stop(imx_sc_wdd);
+
+ return 0;
+}
+
+static int __maybe_unused imx_sc_wdt_resume(struct device *dev)
+{
+ struct watchdog_device *imx_sc_wdd = dev_get_drvdata(dev);
+
+ if (watchdog_active(imx_sc_wdd))
+ imx_sc_wdt_start(imx_sc_wdd);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(imx_sc_wdt_pm_ops,
+ imx_sc_wdt_suspend, imx_sc_wdt_resume);
+
+static const struct of_device_id imx_sc_wdt_dt_ids[] = {
+ { .compatible = "fsl,imx-sc-wdt", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_sc_wdt_dt_ids);
+
+static struct platform_driver imx_sc_wdt_driver = {
+ .probe = imx_sc_wdt_probe,
+ .driver = {
+ .name = "imx-sc-wdt",
+ .of_match_table = imx_sc_wdt_dt_ids,
+ .pm = &imx_sc_wdt_pm_ops,
+ },
+};
+module_platform_driver(imx_sc_wdt_driver);
+
+MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX system controller watchdog driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c
index 72c108a12c19..6cf7cc1ff615 100644
--- a/drivers/watchdog/intel-mid_wdt.c
+++ b/drivers/watchdog/intel-mid_wdt.c
@@ -110,12 +110,13 @@ static const struct watchdog_ops mid_wdt_ops = {
static int mid_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct watchdog_device *wdt_dev;
- struct intel_mid_wdt_pdata *pdata = pdev->dev.platform_data;
+ struct intel_mid_wdt_pdata *pdata = dev->platform_data;
int ret;
if (!pdata) {
- dev_err(&pdev->dev, "missing platform data\n");
+ dev_err(dev, "missing platform data\n");
return -EINVAL;
}
@@ -125,7 +126,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
return ret;
}
- wdt_dev = devm_kzalloc(&pdev->dev, sizeof(*wdt_dev), GFP_KERNEL);
+ wdt_dev = devm_kzalloc(dev, sizeof(*wdt_dev), GFP_KERNEL);
if (!wdt_dev)
return -ENOMEM;
@@ -134,16 +135,15 @@ static int mid_wdt_probe(struct platform_device *pdev)
wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN;
wdt_dev->max_timeout = MID_WDT_TIMEOUT_MAX;
wdt_dev->timeout = MID_WDT_DEFAULT_TIMEOUT;
- wdt_dev->parent = &pdev->dev;
+ wdt_dev->parent = dev;
- watchdog_set_drvdata(wdt_dev, &pdev->dev);
+ watchdog_set_drvdata(wdt_dev, dev);
- ret = devm_request_irq(&pdev->dev, pdata->irq, mid_wdt_irq,
+ ret = devm_request_irq(dev, pdata->irq, mid_wdt_irq,
IRQF_SHARED | IRQF_NO_SUSPEND, "watchdog",
wdt_dev);
if (ret) {
- dev_err(&pdev->dev, "error requesting warning irq %d\n",
- pdata->irq);
+ dev_err(dev, "error requesting warning irq %d\n", pdata->irq);
return ret;
}
@@ -163,13 +163,13 @@ static int mid_wdt_probe(struct platform_device *pdev)
/* Make sure the watchdog is serviced */
set_bit(WDOG_HW_RUNNING, &wdt_dev->status);
- ret = devm_watchdog_register_device(&pdev->dev, wdt_dev);
+ ret = devm_watchdog_register_device(dev, wdt_dev);
if (ret) {
- dev_err(&pdev->dev, "error registering watchdog device\n");
+ dev_err(dev, "error registering watchdog device\n");
return ret;
}
- dev_info(&pdev->dev, "Intel MID watchdog device probed\n");
+ dev_info(dev, "Intel MID watchdog device probed\n");
return 0;
}
diff --git a/drivers/watchdog/intel_scu_watchdog.c b/drivers/watchdog/intel_scu_watchdog.c
index 3181a72c7ddf..f7baf75d38c0 100644
--- a/drivers/watchdog/intel_scu_watchdog.c
+++ b/drivers/watchdog/intel_scu_watchdog.c
@@ -25,7 +25,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/compiler.h>
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
@@ -224,7 +223,7 @@ static int intel_scu_set_heartbeat(u32 t)
watchdog_device.timer_tbl_ptr->freq_hz);
pr_debug("set_heartbeat: timer_set is %x (hex)\n",
watchdog_device.timer_set);
- pr_debug("set_hearbeat: timer_margin is %x (hex)\n", timer_margin);
+ pr_debug("set_heartbeat: timer_margin is %x (hex)\n", timer_margin);
pr_debug("set_heartbeat: threshold is %x (hex)\n",
watchdog_device.threshold);
pr_debug("set_heartbeat: soft_threshold is %x (hex)\n",
@@ -545,21 +544,4 @@ register_reboot_error:
iounmap(watchdog_device.timer_load_count_addr);
return ret;
}
-
-static void __exit intel_scu_watchdog_exit(void)
-{
-
- misc_deregister(&watchdog_device.miscdev);
- unregister_reboot_notifier(&watchdog_device.intel_scu_notifier);
- /* disable the timer */
- iowrite32(0x00000002, watchdog_device.timer_control_addr);
- iounmap(watchdog_device.timer_load_count_addr);
-}
-
late_initcall(intel_scu_watchdog_init);
-module_exit(intel_scu_watchdog_exit);
-
-MODULE_AUTHOR("Intel Corporation");
-MODULE_DESCRIPTION("Intel SCU Watchdog Device Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(WDT_VER);
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index ec4d99a830ba..d1bc7cbd4f2b 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -163,12 +163,12 @@ MODULE_DEVICE_TABLE(of, jz4740_wdt_of_matches);
static int jz4740_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct jz4740_wdt_drvdata *drvdata;
struct watchdog_device *jz4740_wdt;
- struct resource *res;
int ret;
- drvdata = devm_kzalloc(&pdev->dev, sizeof(struct jz4740_wdt_drvdata),
+ drvdata = devm_kzalloc(dev, sizeof(struct jz4740_wdt_drvdata),
GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
@@ -182,27 +182,24 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
jz4740_wdt->timeout = heartbeat;
jz4740_wdt->min_timeout = 1;
jz4740_wdt->max_timeout = MAX_HEARTBEAT;
- jz4740_wdt->parent = &pdev->dev;
+ jz4740_wdt->parent = dev;
watchdog_set_nowayout(jz4740_wdt, nowayout);
watchdog_set_drvdata(jz4740_wdt, drvdata);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- drvdata->base = devm_ioremap_resource(&pdev->dev, res);
+ drvdata->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(drvdata->base))
return PTR_ERR(drvdata->base);
- drvdata->rtc_clk = devm_clk_get(&pdev->dev, "rtc");
+ drvdata->rtc_clk = devm_clk_get(dev, "rtc");
if (IS_ERR(drvdata->rtc_clk)) {
- dev_err(&pdev->dev, "cannot find RTC clock\n");
+ dev_err(dev, "cannot find RTC clock\n");
return PTR_ERR(drvdata->rtc_clk);
}
- ret = devm_watchdog_register_device(&pdev->dev, &drvdata->wdt);
+ ret = devm_watchdog_register_device(dev, &drvdata->wdt);
if (ret < 0)
return ret;
- platform_set_drvdata(pdev, drvdata);
-
return 0;
}
diff --git a/drivers/watchdog/kempld_wdt.c b/drivers/watchdog/kempld_wdt.c
index e268add43010..543eb0f27a42 100644
--- a/drivers/watchdog/kempld_wdt.c
+++ b/drivers/watchdog/kempld_wdt.c
@@ -467,7 +467,7 @@ static int kempld_wdt_probe(struct platform_device *pdev)
KEMPLD_WDT_CFG_GLOBAL_LOCK)) {
if (!nowayout)
dev_warn(dev,
- "Forcing nowayout - watchdog lock enabled!\n");
+ "Forcing nowayout - watchdog lock enabled!\n");
nowayout = true;
}
@@ -492,7 +492,9 @@ static int kempld_wdt_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, wdt_data);
- ret = watchdog_register_device(wdd);
+ watchdog_stop_on_reboot(wdd);
+ watchdog_stop_on_unregister(wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret)
return ret;
@@ -501,26 +503,6 @@ static int kempld_wdt_probe(struct platform_device *pdev)
return 0;
}
-static void kempld_wdt_shutdown(struct platform_device *pdev)
-{
- struct kempld_wdt_data *wdt_data = platform_get_drvdata(pdev);
-
- kempld_wdt_stop(&wdt_data->wdd);
-}
-
-static int kempld_wdt_remove(struct platform_device *pdev)
-{
- struct kempld_wdt_data *wdt_data = platform_get_drvdata(pdev);
- struct watchdog_device *wdd = &wdt_data->wdd;
- int ret = 0;
-
- if (!nowayout)
- ret = kempld_wdt_stop(wdd);
- watchdog_unregister_device(wdd);
-
- return ret;
-}
-
#ifdef CONFIG_PM
/* Disable watchdog if it is active during suspend */
static int kempld_wdt_suspend(struct platform_device *pdev,
@@ -567,8 +549,6 @@ static struct platform_driver kempld_wdt_driver = {
.name = "kempld-wdt",
},
.probe = kempld_wdt_probe,
- .remove = kempld_wdt_remove,
- .shutdown = kempld_wdt_shutdown,
.suspend = kempld_wdt_suspend,
.resume = kempld_wdt_resume,
};
diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
index 83da84d6074b..4caf02ba5d49 100644
--- a/drivers/watchdog/lantiq_wdt.c
+++ b/drivers/watchdog/lantiq_wdt.c
@@ -203,7 +203,6 @@ static int ltq_wdt_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct ltq_wdt_priv *priv;
struct watchdog_device *wdt;
- struct resource *res;
struct clk *clk;
const struct ltq_wdt_hw *ltq_wdt_hw;
int ret;
@@ -213,8 +212,7 @@ static int ltq_wdt_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->membase = devm_ioremap_resource(dev, res);
+ priv->membase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->membase))
return PTR_ERR(priv->membase);
diff --git a/drivers/watchdog/loongson1_wdt.c b/drivers/watchdog/loongson1_wdt.c
index 3aee50c64a36..d8075e2affa7 100644
--- a/drivers/watchdog/loongson1_wdt.c
+++ b/drivers/watchdog/loongson1_wdt.c
@@ -83,38 +83,44 @@ static const struct watchdog_ops ls1x_wdt_ops = {
.set_timeout = ls1x_wdt_set_timeout,
};
+static void ls1x_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int ls1x_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct ls1x_wdt_drvdata *drvdata;
struct watchdog_device *ls1x_wdt;
unsigned long clk_rate;
- struct resource *res;
int err;
- drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- drvdata->base = devm_ioremap_resource(&pdev->dev, res);
+ drvdata->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(drvdata->base))
return PTR_ERR(drvdata->base);
- drvdata->clk = devm_clk_get(&pdev->dev, pdev->name);
+ drvdata->clk = devm_clk_get(dev, pdev->name);
if (IS_ERR(drvdata->clk))
return PTR_ERR(drvdata->clk);
err = clk_prepare_enable(drvdata->clk);
if (err) {
- dev_err(&pdev->dev, "clk enable failed\n");
+ dev_err(dev, "clk enable failed\n");
return err;
}
+ err = devm_add_action_or_reset(dev, ls1x_clk_disable_unprepare,
+ drvdata->clk);
+ if (err)
+ return err;
clk_rate = clk_get_rate(drvdata->clk);
- if (!clk_rate) {
- err = -EINVAL;
- goto err0;
- }
+ if (!clk_rate)
+ return -EINVAL;
drvdata->clk_rate = clk_rate;
ls1x_wdt = &drvdata->wdt;
@@ -123,41 +129,27 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
ls1x_wdt->timeout = DEFAULT_HEARTBEAT;
ls1x_wdt->min_timeout = 1;
ls1x_wdt->max_hw_heartbeat_ms = U32_MAX / clk_rate * 1000;
- ls1x_wdt->parent = &pdev->dev;
+ ls1x_wdt->parent = dev;
- watchdog_init_timeout(ls1x_wdt, heartbeat, &pdev->dev);
+ watchdog_init_timeout(ls1x_wdt, heartbeat, dev);
watchdog_set_nowayout(ls1x_wdt, nowayout);
watchdog_set_drvdata(ls1x_wdt, drvdata);
- err = watchdog_register_device(&drvdata->wdt);
+ err = devm_watchdog_register_device(dev, &drvdata->wdt);
if (err) {
- dev_err(&pdev->dev, "failed to register watchdog device\n");
- goto err0;
+ dev_err(dev, "failed to register watchdog device\n");
+ return err;
}
platform_set_drvdata(pdev, drvdata);
- dev_info(&pdev->dev, "Loongson1 Watchdog driver registered\n");
-
- return 0;
-err0:
- clk_disable_unprepare(drvdata->clk);
- return err;
-}
-
-static int ls1x_wdt_remove(struct platform_device *pdev)
-{
- struct ls1x_wdt_drvdata *drvdata = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&drvdata->wdt);
- clk_disable_unprepare(drvdata->clk);
+ dev_info(dev, "Loongson1 Watchdog driver registered\n");
return 0;
}
static struct platform_driver ls1x_wdt_driver = {
.probe = ls1x_wdt_probe,
- .remove = ls1x_wdt_remove,
.driver = {
.name = "ls1x-wdt",
},
diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c
index 331cadb459ac..0e82abd71d35 100644
--- a/drivers/watchdog/lpc18xx_wdt.c
+++ b/drivers/watchdog/lpc18xx_wdt.c
@@ -200,19 +200,22 @@ static const struct watchdog_ops lpc18xx_wdt_ops = {
.restart = lpc18xx_wdt_restart,
};
+static void lpc18xx_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int lpc18xx_wdt_probe(struct platform_device *pdev)
{
struct lpc18xx_wdt_dev *lpc18xx_wdt;
struct device *dev = &pdev->dev;
- struct resource *res;
int ret;
lpc18xx_wdt = devm_kzalloc(dev, sizeof(*lpc18xx_wdt), GFP_KERNEL);
if (!lpc18xx_wdt)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- lpc18xx_wdt->base = devm_ioremap_resource(dev, res);
+ lpc18xx_wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(lpc18xx_wdt->base))
return PTR_ERR(lpc18xx_wdt->base);
@@ -233,19 +236,26 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev)
dev_err(dev, "could not prepare or enable sys clock\n");
return ret;
}
+ ret = devm_add_action_or_reset(dev, lpc18xx_clk_disable_unprepare,
+ lpc18xx_wdt->reg_clk);
+ if (ret)
+ return ret;
ret = clk_prepare_enable(lpc18xx_wdt->wdt_clk);
if (ret) {
dev_err(dev, "could not prepare or enable wdt clock\n");
- goto disable_reg_clk;
+ return ret;
}
+ ret = devm_add_action_or_reset(dev, lpc18xx_clk_disable_unprepare,
+ lpc18xx_wdt->wdt_clk);
+ if (ret)
+ return ret;
/* We use the clock rate to calculate timeouts */
lpc18xx_wdt->clk_rate = clk_get_rate(lpc18xx_wdt->wdt_clk);
if (lpc18xx_wdt->clk_rate == 0) {
dev_err(dev, "failed to get clock rate\n");
- ret = -EINVAL;
- goto disable_wdt_clk;
+ return -EINVAL;
}
lpc18xx_wdt->wdt_dev.info = &lpc18xx_wdt_info;
@@ -276,24 +286,8 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, lpc18xx_wdt);
- ret = watchdog_register_device(&lpc18xx_wdt->wdt_dev);
- if (ret)
- goto disable_wdt_clk;
-
- return 0;
-
-disable_wdt_clk:
- clk_disable_unprepare(lpc18xx_wdt->wdt_clk);
-disable_reg_clk:
- clk_disable_unprepare(lpc18xx_wdt->reg_clk);
- return ret;
-}
-
-static void lpc18xx_wdt_shutdown(struct platform_device *pdev)
-{
- struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev);
-
- lpc18xx_wdt_stop(&lpc18xx_wdt->wdt_dev);
+ watchdog_stop_on_reboot(&lpc18xx_wdt->wdt_dev);
+ return devm_watchdog_register_device(dev, &lpc18xx_wdt->wdt_dev);
}
static int lpc18xx_wdt_remove(struct platform_device *pdev)
@@ -303,10 +297,6 @@ static int lpc18xx_wdt_remove(struct platform_device *pdev)
dev_warn(&pdev->dev, "I quit now, hardware will probably reboot!\n");
del_timer(&lpc18xx_wdt->timer);
- watchdog_unregister_device(&lpc18xx_wdt->wdt_dev);
- clk_disable_unprepare(lpc18xx_wdt->wdt_clk);
- clk_disable_unprepare(lpc18xx_wdt->reg_clk);
-
return 0;
}
@@ -323,7 +313,6 @@ static struct platform_driver lpc18xx_wdt_driver = {
},
.probe = lpc18xx_wdt_probe,
.remove = lpc18xx_wdt_remove,
- .shutdown = lpc18xx_wdt_shutdown,
};
module_platform_driver(lpc18xx_wdt_driver);
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index 53759415cf06..c0c9e948adbc 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -177,6 +177,7 @@ static inline void zf_set_timer(unsigned short new, unsigned char n)
switch (n) {
case WD1:
zf_writew(COUNTER_1, new);
+ /* fall through */
case WD2:
zf_writeb(COUNTER_2, new > 0xff ? 0xff : new);
default:
@@ -318,7 +319,7 @@ static long zf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case WDIOC_GETBOOTSTATUS:
return put_user(0, p);
case WDIOC_KEEPALIVE:
- zf_ping(0);
+ zf_ping(NULL);
break;
default:
return -ENOTTY;
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c
index bf6a068245ba..3a899628a834 100644
--- a/drivers/watchdog/max63xx_wdt.c
+++ b/drivers/watchdog/max63xx_wdt.c
@@ -187,9 +187,7 @@ static void max63xx_mmap_set(struct max63xx_wdt *wdt, u8 set)
static int max63xx_mmap_init(struct platform_device *p, struct max63xx_wdt *wdt)
{
- struct resource *mem = platform_get_resource(p, IORESOURCE_MEM, 0);
-
- wdt->base = devm_ioremap_resource(&p->dev, mem);
+ wdt->base = devm_platform_ioremap_resource(p, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
@@ -202,11 +200,12 @@ static int max63xx_mmap_init(struct platform_device *p, struct max63xx_wdt *wdt)
static int max63xx_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct max63xx_wdt *wdt;
struct max63xx_timeout *table;
int err;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -217,7 +216,7 @@ static int max63xx_wdt_probe(struct platform_device *pdev)
wdt->timeout = max63xx_select_timeout(table, heartbeat);
if (!wdt->timeout) {
- dev_err(&pdev->dev, "unable to satisfy %ds heartbeat request\n",
+ dev_err(dev, "unable to satisfy %ds heartbeat request\n",
heartbeat);
return -EINVAL;
}
@@ -229,30 +228,22 @@ static int max63xx_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &wdt->wdd);
watchdog_set_drvdata(&wdt->wdd, wdt);
- wdt->wdd.parent = &pdev->dev;
+ wdt->wdd.parent = dev;
wdt->wdd.timeout = wdt->timeout->twd;
wdt->wdd.info = &max63xx_wdt_info;
wdt->wdd.ops = &max63xx_wdt_ops;
watchdog_set_nowayout(&wdt->wdd, nowayout);
- err = watchdog_register_device(&wdt->wdd);
+ err = devm_watchdog_register_device(dev, &wdt->wdd);
if (err)
return err;
- dev_info(&pdev->dev, "using %ds heartbeat with %ds initial delay\n",
+ dev_info(dev, "using %ds heartbeat with %ds initial delay\n",
wdt->timeout->twd, wdt->timeout->tdelay);
return 0;
}
-static int max63xx_wdt_remove(struct platform_device *pdev)
-{
- struct watchdog_device *wdd = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(wdd);
- return 0;
-}
-
static const struct platform_device_id max63xx_id_table[] = {
{ "max6369_wdt", (kernel_ulong_t)max6369_table, },
{ "max6370_wdt", (kernel_ulong_t)max6369_table, },
@@ -266,7 +257,6 @@ MODULE_DEVICE_TABLE(platform, max63xx_id_table);
static struct platform_driver max63xx_wdt_driver = {
.probe = max63xx_wdt_probe,
- .remove = max63xx_wdt_remove,
.id_table = max63xx_id_table,
.driver = {
.name = "max63xx_wdt",
diff --git a/drivers/watchdog/max77620_wdt.c b/drivers/watchdog/max77620_wdt.c
index 70c9cd3ba938..3ca6b9337932 100644
--- a/drivers/watchdog/max77620_wdt.c
+++ b/drivers/watchdog/max77620_wdt.c
@@ -112,17 +112,18 @@ static const struct watchdog_ops max77620_wdt_ops = {
static int max77620_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct max77620_wdt *wdt;
struct watchdog_device *wdt_dev;
unsigned int regval;
int ret;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
- wdt->dev = &pdev->dev;
- wdt->rmap = dev_get_regmap(pdev->dev.parent, NULL);
+ wdt->dev = dev;
+ wdt->rmap = dev_get_regmap(dev->parent, NULL);
if (!wdt->rmap) {
dev_err(wdt->dev, "Failed to get parent regmap\n");
return -ENODEV;
@@ -183,25 +184,16 @@ static int max77620_wdt_probe(struct platform_device *pdev)
watchdog_set_nowayout(wdt_dev, nowayout);
watchdog_set_drvdata(wdt_dev, wdt);
- ret = watchdog_register_device(wdt_dev);
+ watchdog_stop_on_unregister(wdt_dev);
+ ret = devm_watchdog_register_device(dev, wdt_dev);
if (ret < 0) {
- dev_err(&pdev->dev, "watchdog registration failed: %d\n", ret);
+ dev_err(dev, "watchdog registration failed: %d\n", ret);
return ret;
}
return 0;
}
-static int max77620_wdt_remove(struct platform_device *pdev)
-{
- struct max77620_wdt *wdt = platform_get_drvdata(pdev);
-
- max77620_wdt_stop(&wdt->wdt_dev);
- watchdog_unregister_device(&wdt->wdt_dev);
-
- return 0;
-}
-
static const struct platform_device_id max77620_wdt_devtype[] = {
{ .name = "max77620-watchdog", },
{ },
@@ -213,7 +205,6 @@ static struct platform_driver max77620_wdt_driver = {
.name = "max77620-watchdog",
},
.probe = max77620_wdt_probe,
- .remove = max77620_wdt_remove,
.id_table = max77620_wdt_devtype,
};
diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c
index 6db69883ece6..e9ca4e0e25dc 100644
--- a/drivers/watchdog/mena21_wdt.c
+++ b/drivers/watchdog/mena21_wdt.c
@@ -127,19 +127,20 @@ static struct watchdog_device a21_wdt = {
static int a21_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct a21_wdt_drv *drv;
unsigned int reset = 0;
int num_gpios;
int ret;
int i;
- drv = devm_kzalloc(&pdev->dev, sizeof(struct a21_wdt_drv), GFP_KERNEL);
+ drv = devm_kzalloc(dev, sizeof(struct a21_wdt_drv), GFP_KERNEL);
if (!drv)
return -ENOMEM;
- num_gpios = gpiod_count(&pdev->dev, NULL);
+ num_gpios = gpiod_count(dev, NULL);
if (num_gpios != NUM_GPIOS) {
- dev_err(&pdev->dev, "gpios DT property wrong, got %d want %d",
+ dev_err(dev, "gpios DT property wrong, got %d want %d",
num_gpios, NUM_GPIOS);
return -ENODEV;
}
@@ -152,12 +153,9 @@ static int a21_wdt_probe(struct platform_device *pdev)
gflags = GPIOD_ASIS;
else
gflags = GPIOD_IN;
- drv->gpios[i] = devm_gpiod_get_index(&pdev->dev, NULL, i,
- gflags);
- if (IS_ERR(drv->gpios[i])) {
- ret = PTR_ERR(drv->gpios[i]);
- return ret;
- }
+ drv->gpios[i] = devm_gpiod_get_index(dev, NULL, i, gflags);
+ if (IS_ERR(drv->gpios[i]))
+ return PTR_ERR(drv->gpios[i]);
gpiod_set_consumer_name(drv->gpios[i], "MEN A21 Watchdog");
@@ -173,10 +171,10 @@ static int a21_wdt_probe(struct platform_device *pdev)
}
}
- watchdog_init_timeout(&a21_wdt, 30, &pdev->dev);
+ watchdog_init_timeout(&a21_wdt, 30, dev);
watchdog_set_nowayout(&a21_wdt, nowayout);
watchdog_set_drvdata(&a21_wdt, drv);
- a21_wdt.parent = &pdev->dev;
+ a21_wdt.parent = dev;
reset = a21_wdt_get_bootstatus(drv);
if (reset == 2)
@@ -189,15 +187,15 @@ static int a21_wdt_probe(struct platform_device *pdev)
a21_wdt.bootstatus |= WDIOF_EXTERN2;
drv->wdt = a21_wdt;
- dev_set_drvdata(&pdev->dev, drv);
+ dev_set_drvdata(dev, drv);
- ret = devm_watchdog_register_device(&pdev->dev, &a21_wdt);
+ ret = devm_watchdog_register_device(dev, &a21_wdt);
if (ret) {
- dev_err(&pdev->dev, "Cannot register watchdog device\n");
+ dev_err(dev, "Cannot register watchdog device\n");
return ret;
}
- dev_info(&pdev->dev, "MEN A21 watchdog timer driver enabled\n");
+ dev_info(dev, "MEN A21 watchdog timer driver enabled\n");
return 0;
}
diff --git a/drivers/watchdog/menf21bmc_wdt.c b/drivers/watchdog/menf21bmc_wdt.c
index 3aefddebb386..b1dbff553cdc 100644
--- a/drivers/watchdog/menf21bmc_wdt.c
+++ b/drivers/watchdog/menf21bmc_wdt.c
@@ -117,12 +117,12 @@ static const struct watchdog_ops menf21bmc_wdt_ops = {
static int menf21bmc_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int ret, bmc_timeout;
struct menf21bmc_wdt *drv_data;
- struct i2c_client *i2c_client = to_i2c_client(pdev->dev.parent);
+ struct i2c_client *i2c_client = to_i2c_client(dev->parent);
- drv_data = devm_kzalloc(&pdev->dev,
- sizeof(struct menf21bmc_wdt), GFP_KERNEL);
+ drv_data = devm_kzalloc(dev, sizeof(struct menf21bmc_wdt), GFP_KERNEL);
if (!drv_data)
return -ENOMEM;
@@ -130,7 +130,7 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev)
drv_data->wdt.info = &menf21bmc_wdt_info;
drv_data->wdt.min_timeout = BMC_WD_TIMEOUT_MIN;
drv_data->wdt.max_timeout = BMC_WD_TIMEOUT_MAX;
- drv_data->wdt.parent = &pdev->dev;
+ drv_data->wdt.parent = dev;
drv_data->i2c_client = i2c_client;
/*
@@ -140,40 +140,28 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev)
bmc_timeout = i2c_smbus_read_word_data(drv_data->i2c_client,
BMC_CMD_WD_TIME);
if (bmc_timeout < 0) {
- dev_err(&pdev->dev, "failed to get current WDT timeout\n");
+ dev_err(dev, "failed to get current WDT timeout\n");
return bmc_timeout;
}
- watchdog_init_timeout(&drv_data->wdt, bmc_timeout / 10, &pdev->dev);
+ watchdog_init_timeout(&drv_data->wdt, bmc_timeout / 10, dev);
watchdog_set_nowayout(&drv_data->wdt, nowayout);
watchdog_set_drvdata(&drv_data->wdt, drv_data);
platform_set_drvdata(pdev, drv_data);
ret = menf21bmc_wdt_set_bootstatus(drv_data);
if (ret < 0) {
- dev_err(&pdev->dev, "failed to set Watchdog bootstatus\n");
+ dev_err(dev, "failed to set Watchdog bootstatus\n");
return ret;
}
- ret = watchdog_register_device(&drv_data->wdt);
+ ret = devm_watchdog_register_device(dev, &drv_data->wdt);
if (ret) {
- dev_err(&pdev->dev, "failed to register Watchdog device\n");
+ dev_err(dev, "failed to register Watchdog device\n");
return ret;
}
- dev_info(&pdev->dev, "MEN 14F021P00 BMC Watchdog device enabled\n");
-
- return 0;
-}
-
-static int menf21bmc_wdt_remove(struct platform_device *pdev)
-{
- struct menf21bmc_wdt *drv_data = platform_get_drvdata(pdev);
-
- dev_warn(&pdev->dev,
- "Unregister MEN 14F021P00 BMC Watchdog device, board may reset\n");
-
- watchdog_unregister_device(&drv_data->wdt);
+ dev_info(dev, "MEN 14F021P00 BMC Watchdog device enabled\n");
return 0;
}
@@ -191,7 +179,6 @@ static struct platform_driver menf21bmc_wdt = {
.name = DEVNAME,
},
.probe = menf21bmc_wdt_probe,
- .remove = menf21bmc_wdt_remove,
.shutdown = menf21bmc_wdt_shutdown,
};
diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c
index 69adeab3fde7..d17c1a6ed723 100644
--- a/drivers/watchdog/meson_gxbb_wdt.c
+++ b/drivers/watchdog/meson_gxbb_wdt.c
@@ -136,32 +136,40 @@ static const struct of_device_id meson_gxbb_wdt_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, meson_gxbb_wdt_dt_ids);
+static void meson_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int meson_gxbb_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct meson_gxbb_wdt *data;
- struct resource *res;
int ret;
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- data->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ data->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->reg_base))
return PTR_ERR(data->reg_base);
- data->clk = devm_clk_get(&pdev->dev, NULL);
+ data->clk = devm_clk_get(dev, NULL);
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);
ret = clk_prepare_enable(data->clk);
if (ret)
return ret;
+ ret = devm_add_action_or_reset(dev, meson_clk_disable_unprepare,
+ data->clk);
+ if (ret)
+ return ret;
platform_set_drvdata(pdev, data);
- data->wdt_dev.parent = &pdev->dev;
+ data->wdt_dev.parent = dev;
data->wdt_dev.info = &meson_gxbb_wdt_info;
data->wdt_dev.ops = &meson_gxbb_wdt_ops;
data->wdt_dev.max_hw_heartbeat_ms = GXBB_WDT_TCNT_SETUP_MASK;
@@ -178,37 +186,12 @@ static int meson_gxbb_wdt_probe(struct platform_device *pdev)
meson_gxbb_wdt_set_timeout(&data->wdt_dev, data->wdt_dev.timeout);
- ret = watchdog_register_device(&data->wdt_dev);
- if (ret) {
- clk_disable_unprepare(data->clk);
- return ret;
- }
-
- return 0;
-}
-
-static int meson_gxbb_wdt_remove(struct platform_device *pdev)
-{
- struct meson_gxbb_wdt *data = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&data->wdt_dev);
-
- clk_disable_unprepare(data->clk);
-
- return 0;
-}
-
-static void meson_gxbb_wdt_shutdown(struct platform_device *pdev)
-{
- struct meson_gxbb_wdt *data = platform_get_drvdata(pdev);
-
- meson_gxbb_wdt_stop(&data->wdt_dev);
+ watchdog_stop_on_reboot(&data->wdt_dev);
+ return devm_watchdog_register_device(dev, &data->wdt_dev);
}
static struct platform_driver meson_gxbb_wdt_driver = {
.probe = meson_gxbb_wdt_probe,
- .remove = meson_gxbb_wdt_remove,
- .shutdown = meson_gxbb_wdt_shutdown,
.driver = {
.name = "meson-gxbb-wdt",
.pm = &meson_gxbb_wdt_pm_ops,
diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c
index cd0275a6cdac..01889cef81e1 100644
--- a/drivers/watchdog/meson_wdt.c
+++ b/drivers/watchdog/meson_wdt.c
@@ -164,28 +164,27 @@ MODULE_DEVICE_TABLE(of, meson_wdt_dt_ids);
static int meson_wdt_probe(struct platform_device *pdev)
{
- struct resource *res;
+ struct device *dev = &pdev->dev;
struct meson_wdt_dev *meson_wdt;
const struct of_device_id *of_id;
int err;
- meson_wdt = devm_kzalloc(&pdev->dev, sizeof(*meson_wdt), GFP_KERNEL);
+ meson_wdt = devm_kzalloc(dev, sizeof(*meson_wdt), GFP_KERNEL);
if (!meson_wdt)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- meson_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
+ meson_wdt->wdt_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(meson_wdt->wdt_base))
return PTR_ERR(meson_wdt->wdt_base);
- of_id = of_match_device(meson_wdt_dt_ids, &pdev->dev);
+ of_id = of_match_device(meson_wdt_dt_ids, dev);
if (!of_id) {
- dev_err(&pdev->dev, "Unable to initialize WDT data\n");
+ dev_err(dev, "Unable to initialize WDT data\n");
return -ENODEV;
}
meson_wdt->data = of_id->data;
- meson_wdt->wdt_dev.parent = &pdev->dev;
+ meson_wdt->wdt_dev.parent = dev;
meson_wdt->wdt_dev.info = &meson_wdt_info;
meson_wdt->wdt_dev.ops = &meson_wdt_ops;
meson_wdt->wdt_dev.max_timeout =
@@ -197,18 +196,18 @@ static int meson_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(&meson_wdt->wdt_dev, meson_wdt);
- watchdog_init_timeout(&meson_wdt->wdt_dev, timeout, &pdev->dev);
+ watchdog_init_timeout(&meson_wdt->wdt_dev, timeout, dev);
watchdog_set_nowayout(&meson_wdt->wdt_dev, nowayout);
watchdog_set_restart_priority(&meson_wdt->wdt_dev, 128);
meson_wdt_stop(&meson_wdt->wdt_dev);
watchdog_stop_on_reboot(&meson_wdt->wdt_dev);
- err = devm_watchdog_register_device(&pdev->dev, &meson_wdt->wdt_dev);
+ err = devm_watchdog_register_device(dev, &meson_wdt->wdt_dev);
if (err)
return err;
- dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)",
+ dev_info(dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)",
meson_wdt->wdt_dev.timeout, nowayout);
return 0;
diff --git a/drivers/watchdog/mlx_wdt.c b/drivers/watchdog/mlx_wdt.c
index 70c2cbf9c993..03b9ac4b99af 100644
--- a/drivers/watchdog/mlx_wdt.c
+++ b/drivers/watchdog/mlx_wdt.c
@@ -233,20 +233,21 @@ static int mlxreg_wdt_init_timeout(struct mlxreg_wdt *wdt,
static int mlxreg_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct mlxreg_core_platform_data *pdata;
struct mlxreg_wdt *wdt;
int rc;
- pdata = dev_get_platdata(&pdev->dev);
+ pdata = dev_get_platdata(dev);
if (!pdata) {
- dev_err(&pdev->dev, "Failed to get platform data.\n");
+ dev_err(dev, "Failed to get platform data.\n");
return -EINVAL;
}
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
- wdt->wdd.parent = &pdev->dev;
+ wdt->wdd.parent = dev;
wdt->regmap = pdata->regmap;
mlxreg_wdt_config(wdt, pdata);
@@ -266,12 +267,11 @@ static int mlxreg_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
}
mlxreg_wdt_check_card_reset(wdt);
- rc = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
+ rc = devm_watchdog_register_device(dev, &wdt->wdd);
register_error:
if (rc)
- dev_err(&pdev->dev,
- "Cannot register watchdog device (err=%d)\n", rc);
+ dev_err(dev, "Cannot register watchdog device (err=%d)\n", rc);
return rc;
}
diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
index 430c3ab84c07..6340a1f5f471 100644
--- a/drivers/watchdog/moxart_wdt.c
+++ b/drivers/watchdog/moxart_wdt.c
@@ -91,8 +91,6 @@ static int moxart_wdt_probe(struct platform_device *pdev)
{
struct moxart_wdt_dev *moxart_wdt;
struct device *dev = &pdev->dev;
- struct device_node *node = dev->of_node;
- struct resource *res;
struct clk *clk;
int err;
unsigned int max_timeout;
@@ -104,12 +102,11 @@ static int moxart_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, moxart_wdt);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- moxart_wdt->base = devm_ioremap_resource(dev, res);
+ moxart_wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(moxart_wdt->base))
return PTR_ERR(moxart_wdt->base);
- clk = of_clk_get(node, 0);
+ clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) {
pr_err("%s: of_clk_get failed\n", __func__);
return PTR_ERR(clk);
@@ -136,7 +133,8 @@ static int moxart_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(&moxart_wdt->dev, moxart_wdt);
- err = watchdog_register_device(&moxart_wdt->dev);
+ watchdog_stop_on_unregister(&moxart_wdt->dev);
+ err = devm_watchdog_register_device(dev, &moxart_wdt->dev);
if (err)
return err;
@@ -146,15 +144,6 @@ static int moxart_wdt_probe(struct platform_device *pdev)
return 0;
}
-static int moxart_wdt_remove(struct platform_device *pdev)
-{
- struct moxart_wdt_dev *moxart_wdt = platform_get_drvdata(pdev);
-
- moxart_wdt_stop(&moxart_wdt->dev);
-
- return 0;
-}
-
static const struct of_device_id moxart_watchdog_match[] = {
{ .compatible = "moxa,moxart-watchdog" },
{ },
@@ -163,7 +152,6 @@ MODULE_DEVICE_TABLE(of, moxart_watchdog_match);
static struct platform_driver moxart_wdt_driver = {
.probe = moxart_wdt_probe,
- .remove = moxart_wdt_remove,
.driver = {
.name = "moxart-watchdog",
.of_match_table = moxart_watchdog_match,
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 069072e6747d..9b6d6a5a27ad 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -149,8 +149,7 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
if (!ddata)
return -ENOMEM;
- res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
- ddata->base = devm_ioremap_resource(dev, res);
+ ddata->base = devm_platform_ioremap_resource(ofdev, 0);
if (IS_ERR(ddata->base))
return PTR_ERR(ddata->base);
@@ -205,9 +204,10 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
if (ddata->wdd.timeout < ddata->wdd.min_timeout)
ddata->wdd.timeout = ddata->wdd.min_timeout;
- ret = watchdog_register_device(&ddata->wdd);
+ ret = devm_watchdog_register_device(dev, &ddata->wdd);
if (ret) {
- dev_err(dev, "cannot register watchdog device (err=%d)\n", ret);
+ dev_err(dev, "cannot register watchdog device (err=%d)\n",
+ ret);
return ret;
}
@@ -219,17 +219,6 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
return 0;
}
-static int mpc8xxx_wdt_remove(struct platform_device *ofdev)
-{
- struct mpc8xxx_wdt_ddata *ddata = platform_get_drvdata(ofdev);
-
- dev_crit(&ofdev->dev, "Watchdog removed, expect the %s soon!\n",
- reset ? "reset" : "machine check exception");
- watchdog_unregister_device(&ddata->wdd);
-
- return 0;
-}
-
static const struct of_device_id mpc8xxx_wdt_match[] = {
{
.compatible = "mpc83xx_wdt",
@@ -260,7 +249,6 @@ MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match);
static struct platform_driver mpc8xxx_wdt_driver = {
.probe = mpc8xxx_wdt_probe,
- .remove = mpc8xxx_wdt_remove,
.driver = {
.name = "mpc8xxx_wdt",
.of_match_table = mpc8xxx_wdt_match,
diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c
index 81208cd3f4ec..cbb3c0dde136 100644
--- a/drivers/watchdog/mt7621_wdt.c
+++ b/drivers/watchdog/mt7621_wdt.c
@@ -133,21 +133,19 @@ static struct watchdog_device mt7621_wdt_dev = {
static int mt7621_wdt_probe(struct platform_device *pdev)
{
- struct resource *res;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- mt7621_wdt_base = devm_ioremap_resource(&pdev->dev, res);
+ struct device *dev = &pdev->dev;
+ mt7621_wdt_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mt7621_wdt_base))
return PTR_ERR(mt7621_wdt_base);
- mt7621_wdt_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+ mt7621_wdt_reset = devm_reset_control_get_exclusive(dev, NULL);
if (!IS_ERR(mt7621_wdt_reset))
reset_control_deassert(mt7621_wdt_reset);
mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause();
watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout,
- &pdev->dev);
+ dev);
watchdog_set_nowayout(&mt7621_wdt_dev, nowayout);
if (mt7621_wdt_is_running(&mt7621_wdt_dev)) {
/*
@@ -164,7 +162,7 @@ static int mt7621_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &mt7621_wdt_dev.status);
}
- return devm_watchdog_register_device(&pdev->dev, &mt7621_wdt_dev);
+ return devm_watchdog_register_device(dev, &mt7621_wdt_dev);
}
static void mt7621_wdt_shutdown(struct platform_device *pdev)
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index 4baf64f21aa1..9c3d0033260d 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -153,18 +153,17 @@ static const struct watchdog_ops mtk_wdt_ops = {
static int mtk_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct mtk_wdt_dev *mtk_wdt;
- struct resource *res;
int err;
- mtk_wdt = devm_kzalloc(&pdev->dev, sizeof(*mtk_wdt), GFP_KERNEL);
+ mtk_wdt = devm_kzalloc(dev, sizeof(*mtk_wdt), GFP_KERNEL);
if (!mtk_wdt)
return -ENOMEM;
platform_set_drvdata(pdev, mtk_wdt);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- mtk_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
+ mtk_wdt->wdt_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mtk_wdt->wdt_base))
return PTR_ERR(mtk_wdt->wdt_base);
@@ -173,9 +172,9 @@ static int mtk_wdt_probe(struct platform_device *pdev)
mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT;
mtk_wdt->wdt_dev.max_timeout = WDT_MAX_TIMEOUT;
mtk_wdt->wdt_dev.min_timeout = WDT_MIN_TIMEOUT;
- mtk_wdt->wdt_dev.parent = &pdev->dev;
+ mtk_wdt->wdt_dev.parent = dev;
- watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev);
+ watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, dev);
watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout);
watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128);
@@ -183,29 +182,13 @@ static int mtk_wdt_probe(struct platform_device *pdev)
mtk_wdt_stop(&mtk_wdt->wdt_dev);
- err = watchdog_register_device(&mtk_wdt->wdt_dev);
+ watchdog_stop_on_reboot(&mtk_wdt->wdt_dev);
+ err = devm_watchdog_register_device(dev, &mtk_wdt->wdt_dev);
if (unlikely(err))
return err;
- dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n",
- mtk_wdt->wdt_dev.timeout, nowayout);
-
- return 0;
-}
-
-static void mtk_wdt_shutdown(struct platform_device *pdev)
-{
- struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
-
- if (watchdog_active(&mtk_wdt->wdt_dev))
- mtk_wdt_stop(&mtk_wdt->wdt_dev);
-}
-
-static int mtk_wdt_remove(struct platform_device *pdev)
-{
- struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&mtk_wdt->wdt_dev);
+ dev_info(dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n",
+ mtk_wdt->wdt_dev.timeout, nowayout);
return 0;
}
@@ -247,8 +230,6 @@ static const struct dev_pm_ops mtk_wdt_pm_ops = {
static struct platform_driver mtk_wdt_driver = {
.probe = mtk_wdt_probe,
- .remove = mtk_wdt_remove,
- .shutdown = mtk_wdt_shutdown,
.driver = {
.name = DRV_NAME,
.pm = &mtk_wdt_pm_ops,
diff --git a/drivers/watchdog/ni903x_wdt.c b/drivers/watchdog/ni903x_wdt.c
index dc67742e9018..fbc1df86c6cc 100644
--- a/drivers/watchdog/ni903x_wdt.c
+++ b/drivers/watchdog/ni903x_wdt.c
@@ -217,9 +217,7 @@ static int ni903x_acpi_add(struct acpi_device *device)
wdd->parent = dev;
watchdog_set_drvdata(wdd, wdt);
watchdog_set_nowayout(wdd, nowayout);
- ret = watchdog_init_timeout(wdd, timeout, dev);
- if (ret)
- dev_err(dev, "unable to set timeout value, using default\n");
+ watchdog_init_timeout(wdd, timeout, dev);
ret = watchdog_register_device(wdd);
if (ret) {
diff --git a/drivers/watchdog/nic7018_wdt.c b/drivers/watchdog/nic7018_wdt.c
index dcd265685837..82843abe38f8 100644
--- a/drivers/watchdog/nic7018_wdt.c
+++ b/drivers/watchdog/nic7018_wdt.c
@@ -211,10 +211,7 @@ static int nic7018_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdd, wdt);
watchdog_set_nowayout(wdd, nowayout);
-
- ret = watchdog_init_timeout(wdd, timeout, dev);
- if (ret)
- dev_warn(dev, "unable to set timeout value, using default\n");
+ watchdog_init_timeout(wdd, timeout, dev);
/* Unlock WDT register */
outb(UNLOCK, wdt->io_base + WDT_REG_LOCK);
diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c
index 0d4213652ecc..9d6c1689b12c 100644
--- a/drivers/watchdog/npcm_wdt.c
+++ b/drivers/watchdog/npcm_wdt.c
@@ -181,16 +181,14 @@ static int npcm_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct npcm_wdt *wdt;
- struct resource *res;
int irq;
int ret;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->reg = devm_ioremap_resource(dev, res);
+ wdt->reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->reg))
return PTR_ERR(wdt->reg);
@@ -216,8 +214,8 @@ static int npcm_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
}
- ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0,
- "watchdog", wdt);
+ ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0, "watchdog",
+ wdt);
if (ret)
return ret;
diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c
index 8a36350bab7b..f36eae34e848 100644
--- a/drivers/watchdog/nuc900_wdt.c
+++ b/drivers/watchdog/nuc900_wdt.c
@@ -242,7 +242,6 @@ static struct miscdevice nuc900wdt_miscdev = {
static int nuc900wdt_probe(struct platform_device *pdev)
{
- struct resource *res;
int ret = 0;
nuc900_wdt = devm_kzalloc(&pdev->dev, sizeof(*nuc900_wdt),
@@ -254,8 +253,7 @@ static int nuc900wdt_probe(struct platform_device *pdev)
spin_lock_init(&nuc900_wdt->wdt_lock);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- nuc900_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
+ nuc900_wdt->wdt_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(nuc900_wdt->wdt_base))
return PTR_ERR(nuc900_wdt->wdt_base);
diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c
index d3f7eb046678..03786992b701 100644
--- a/drivers/watchdog/of_xilinx_wdt.c
+++ b/drivers/watchdog/of_xilinx_wdt.c
@@ -151,43 +151,46 @@ static u32 xwdt_selftest(struct xwdt_device *xdev)
return XWT_TIMER_FAILED;
}
+static void xwdt_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int xwdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int rc;
u32 pfreq = 0, enable_once = 0;
- struct resource *res;
struct xwdt_device *xdev;
struct watchdog_device *xilinx_wdt_wdd;
- xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
+ xdev = devm_kzalloc(dev, sizeof(*xdev), GFP_KERNEL);
if (!xdev)
return -ENOMEM;
xilinx_wdt_wdd = &xdev->xilinx_wdt_wdd;
xilinx_wdt_wdd->info = &xilinx_wdt_ident;
xilinx_wdt_wdd->ops = &xilinx_wdt_ops;
- xilinx_wdt_wdd->parent = &pdev->dev;
+ xilinx_wdt_wdd->parent = dev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- xdev->base = devm_ioremap_resource(&pdev->dev, res);
+ xdev->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(xdev->base))
return PTR_ERR(xdev->base);
- rc = of_property_read_u32(pdev->dev.of_node, "xlnx,wdt-interval",
+ rc = of_property_read_u32(dev->of_node, "xlnx,wdt-interval",
&xdev->wdt_interval);
if (rc)
- dev_warn(&pdev->dev,
- "Parameter \"xlnx,wdt-interval\" not found\n");
+ dev_warn(dev, "Parameter \"xlnx,wdt-interval\" not found\n");
- rc = of_property_read_u32(pdev->dev.of_node, "xlnx,wdt-enable-once",
+ rc = of_property_read_u32(dev->of_node, "xlnx,wdt-enable-once",
&enable_once);
if (rc)
- dev_warn(&pdev->dev,
+ dev_warn(dev,
"Parameter \"xlnx,wdt-enable-once\" not found\n");
watchdog_set_nowayout(xilinx_wdt_wdd, enable_once);
- xdev->clk = devm_clk_get(&pdev->dev, NULL);
+ xdev->clk = devm_clk_get(dev, NULL);
if (IS_ERR(xdev->clk)) {
if (PTR_ERR(xdev->clk) != -ENOENT)
return PTR_ERR(xdev->clk);
@@ -198,10 +201,10 @@ static int xwdt_probe(struct platform_device *pdev)
*/
xdev->clk = NULL;
- rc = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
+ rc = of_property_read_u32(dev->of_node, "clock-frequency",
&pfreq);
if (rc)
- dev_warn(&pdev->dev,
+ dev_warn(dev,
"The watchdog clock freq cannot be obtained\n");
} else {
pfreq = clk_get_rate(xdev->clk);
@@ -220,44 +223,34 @@ static int xwdt_probe(struct platform_device *pdev)
rc = clk_prepare_enable(xdev->clk);
if (rc) {
- dev_err(&pdev->dev, "unable to enable clock\n");
+ dev_err(dev, "unable to enable clock\n");
return rc;
}
+ rc = devm_add_action_or_reset(dev, xwdt_clk_disable_unprepare,
+ xdev->clk);
+ if (rc)
+ return rc;
rc = xwdt_selftest(xdev);
if (rc == XWT_TIMER_FAILED) {
- dev_err(&pdev->dev, "SelfTest routine error\n");
- goto err_clk_disable;
+ dev_err(dev, "SelfTest routine error\n");
+ return rc;
}
- rc = watchdog_register_device(xilinx_wdt_wdd);
+ rc = devm_watchdog_register_device(dev, xilinx_wdt_wdd);
if (rc) {
- dev_err(&pdev->dev, "Cannot register watchdog (err=%d)\n", rc);
- goto err_clk_disable;
+ dev_err(dev, "Cannot register watchdog (err=%d)\n", rc);
+ return rc;
}
clk_disable(xdev->clk);
- dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n",
+ dev_info(dev, "Xilinx Watchdog Timer at %p with timeout %ds\n",
xdev->base, xilinx_wdt_wdd->timeout);
platform_set_drvdata(pdev, xdev);
return 0;
-err_clk_disable:
- clk_disable_unprepare(xdev->clk);
-
- return rc;
-}
-
-static int xwdt_remove(struct platform_device *pdev)
-{
- struct xwdt_device *xdev = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&xdev->xilinx_wdt_wdd);
- clk_disable_unprepare(xdev->clk);
-
- return 0;
}
/**
@@ -305,7 +298,6 @@ MODULE_DEVICE_TABLE(of, xwdt_of_match);
static struct platform_driver xwdt_driver = {
.probe = xwdt_probe,
- .remove = xwdt_remove,
.driver = {
.name = WATCHDOG_NAME,
.of_match_table = xwdt_of_match,
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index cbd752f9ac56..d49688d93f6a 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -231,7 +231,6 @@ static const struct watchdog_ops omap_wdt_ops = {
static int omap_wdt_probe(struct platform_device *pdev)
{
struct omap_wd_timer_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct resource *res;
struct omap_wdt_dev *wdev;
int ret;
@@ -245,8 +244,7 @@ static int omap_wdt_probe(struct platform_device *pdev)
mutex_init(&wdev->lock);
/* reserve static register mappings */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdev->base = devm_ioremap_resource(&pdev->dev, res);
+ wdev->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdev->base))
return PTR_ERR(wdev->base);
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index 9db3b09f7568..cdb0d174c5e2 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -349,13 +349,6 @@ static unsigned int orion_wdt_get_timeleft(struct watchdog_device *wdt_dev)
return readl(dev->reg + dev->data->wdt_counter_offset) / dev->clk_rate;
}
-static int orion_wdt_set_timeout(struct watchdog_device *wdt_dev,
- unsigned int timeout)
-{
- wdt_dev->timeout = timeout;
- return 0;
-}
-
static const struct watchdog_info orion_wdt_info = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.identity = "Orion Watchdog",
@@ -366,7 +359,6 @@ static const struct watchdog_ops orion_wdt_ops = {
.start = orion_wdt_start,
.stop = orion_wdt_stop,
.ping = orion_wdt_ping,
- .set_timeout = orion_wdt_set_timeout,
.get_timeleft = orion_wdt_get_timeleft,
};
@@ -502,8 +494,7 @@ static int orion_wdt_get_regs(struct platform_device *pdev,
of_device_is_compatible(node, "marvell,armada-xp-wdt")) {
/* Dedicated RSTOUT register, can be requested. */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- dev->rstout = devm_ioremap_resource(&pdev->dev, res);
+ dev->rstout = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(dev->rstout))
return PTR_ERR(dev->rstout);
@@ -511,8 +502,7 @@ static int orion_wdt_get_regs(struct platform_device *pdev,
of_device_is_compatible(node, "marvell,armada-380-wdt")) {
/* Dedicated RSTOUT register, can be requested. */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- dev->rstout = devm_ioremap_resource(&pdev->dev, res);
+ dev->rstout = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(dev->rstout))
return PTR_ERR(dev->rstout);
diff --git a/drivers/watchdog/pic32-dmt.c b/drivers/watchdog/pic32-dmt.c
index c797305f8338..9a3c53e03c60 100644
--- a/drivers/watchdog/pic32-dmt.c
+++ b/drivers/watchdog/pic32-dmt.c
@@ -168,70 +168,61 @@ static struct watchdog_device pic32_dmt_wdd = {
.ops = &pic32_dmt_fops,
};
+static void pic32_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int pic32_dmt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int ret;
struct pic32_dmt *dmt;
- struct resource *mem;
struct watchdog_device *wdd = &pic32_dmt_wdd;
- dmt = devm_kzalloc(&pdev->dev, sizeof(*dmt), GFP_KERNEL);
+ dmt = devm_kzalloc(dev, sizeof(*dmt), GFP_KERNEL);
if (!dmt)
return -ENOMEM;
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dmt->regs = devm_ioremap_resource(&pdev->dev, mem);
+ dmt->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dmt->regs))
return PTR_ERR(dmt->regs);
- dmt->clk = devm_clk_get(&pdev->dev, NULL);
+ dmt->clk = devm_clk_get(dev, NULL);
if (IS_ERR(dmt->clk)) {
- dev_err(&pdev->dev, "clk not found\n");
+ dev_err(dev, "clk not found\n");
return PTR_ERR(dmt->clk);
}
ret = clk_prepare_enable(dmt->clk);
if (ret)
return ret;
+ ret = devm_add_action_or_reset(dev, pic32_clk_disable_unprepare,
+ dmt->clk);
+ if (ret)
+ return ret;
wdd->timeout = pic32_dmt_get_timeout_secs(dmt);
if (!wdd->timeout) {
- dev_err(&pdev->dev,
- "failed to read watchdog register timeout\n");
- ret = -EINVAL;
- goto out_disable_clk;
+ dev_err(dev, "failed to read watchdog register timeout\n");
+ return -EINVAL;
}
- dev_info(&pdev->dev, "timeout %d\n", wdd->timeout);
+ dev_info(dev, "timeout %d\n", wdd->timeout);
wdd->bootstatus = pic32_dmt_bootstatus(dmt) ? WDIOF_CARDRESET : 0;
watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT);
watchdog_set_drvdata(wdd, dmt);
- ret = watchdog_register_device(wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
- dev_err(&pdev->dev, "watchdog register failed, err %d\n", ret);
- goto out_disable_clk;
+ dev_err(dev, "watchdog register failed, err %d\n", ret);
+ return ret;
}
platform_set_drvdata(pdev, wdd);
return 0;
-
-out_disable_clk:
- clk_disable_unprepare(dmt->clk);
- return ret;
-}
-
-static int pic32_dmt_remove(struct platform_device *pdev)
-{
- struct watchdog_device *wdd = platform_get_drvdata(pdev);
- struct pic32_dmt *dmt = watchdog_get_drvdata(wdd);
-
- watchdog_unregister_device(wdd);
- clk_disable_unprepare(dmt->clk);
-
- return 0;
}
static const struct of_device_id pic32_dmt_of_ids[] = {
@@ -242,7 +233,6 @@ MODULE_DEVICE_TABLE(of, pic32_dmt_of_ids);
static struct platform_driver pic32_dmt_driver = {
.probe = pic32_dmt_probe,
- .remove = pic32_dmt_remove,
.driver = {
.name = "pic32-dmt",
.of_match_table = of_match_ptr(pic32_dmt_of_ids),
diff --git a/drivers/watchdog/pic32-wdt.c b/drivers/watchdog/pic32-wdt.c
index e2761068dc6f..540500940cc0 100644
--- a/drivers/watchdog/pic32-wdt.c
+++ b/drivers/watchdog/pic32-wdt.c
@@ -166,89 +166,77 @@ static const struct of_device_id pic32_wdt_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, pic32_wdt_dt_ids);
+static void pic32_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int pic32_wdt_drv_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int ret;
struct watchdog_device *wdd = &pic32_wdd;
struct pic32_wdt *wdt;
- struct resource *mem;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->regs = devm_ioremap_resource(&pdev->dev, mem);
+ wdt->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->regs))
return PTR_ERR(wdt->regs);
- wdt->rst_base = devm_ioremap(&pdev->dev, PIC32_BASE_RESET, 0x10);
+ wdt->rst_base = devm_ioremap(dev, PIC32_BASE_RESET, 0x10);
if (!wdt->rst_base)
return -ENOMEM;
- wdt->clk = devm_clk_get(&pdev->dev, NULL);
+ wdt->clk = devm_clk_get(dev, NULL);
if (IS_ERR(wdt->clk)) {
- dev_err(&pdev->dev, "clk not found\n");
+ dev_err(dev, "clk not found\n");
return PTR_ERR(wdt->clk);
}
ret = clk_prepare_enable(wdt->clk);
if (ret) {
- dev_err(&pdev->dev, "clk enable failed\n");
+ dev_err(dev, "clk enable failed\n");
return ret;
}
+ ret = devm_add_action_or_reset(dev, pic32_clk_disable_unprepare,
+ wdt->clk);
+ if (ret)
+ return ret;
if (pic32_wdt_is_win_enabled(wdt)) {
- dev_err(&pdev->dev, "windowed-clear mode is not supported.\n");
- ret = -ENODEV;
- goto out_disable_clk;
+ dev_err(dev, "windowed-clear mode is not supported.\n");
+ return -ENODEV;
}
- wdd->timeout = pic32_wdt_get_timeout_secs(wdt, &pdev->dev);
+ wdd->timeout = pic32_wdt_get_timeout_secs(wdt, dev);
if (!wdd->timeout) {
- dev_err(&pdev->dev,
- "failed to read watchdog register timeout\n");
- ret = -EINVAL;
- goto out_disable_clk;
+ dev_err(dev, "failed to read watchdog register timeout\n");
+ return -EINVAL;
}
- dev_info(&pdev->dev, "timeout %d\n", wdd->timeout);
+ dev_info(dev, "timeout %d\n", wdd->timeout);
wdd->bootstatus = pic32_wdt_bootstatus(wdt) ? WDIOF_CARDRESET : 0;
watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT);
watchdog_set_drvdata(wdd, wdt);
- ret = watchdog_register_device(wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
- dev_err(&pdev->dev, "watchdog register failed, err %d\n", ret);
- goto out_disable_clk;
+ dev_err(dev, "watchdog register failed, err %d\n", ret);
+ return ret;
}
platform_set_drvdata(pdev, wdd);
return 0;
-
-out_disable_clk:
- clk_disable_unprepare(wdt->clk);
-
- return ret;
-}
-
-static int pic32_wdt_drv_remove(struct platform_device *pdev)
-{
- struct watchdog_device *wdd = platform_get_drvdata(pdev);
- struct pic32_wdt *wdt = watchdog_get_drvdata(wdd);
-
- watchdog_unregister_device(wdd);
- clk_disable_unprepare(wdt->clk);
-
- return 0;
}
static struct platform_driver pic32_wdt_driver = {
.probe = pic32_wdt_drv_probe,
- .remove = pic32_wdt_drv_remove,
.driver = {
.name = "pic32-wdt",
.of_match_table = of_match_ptr(pic32_wdt_dt_ids),
diff --git a/drivers/watchdog/pm8916_wdt.c b/drivers/watchdog/pm8916_wdt.c
index 7f10041fcf5b..2d3652004e39 100644
--- a/drivers/watchdog/pm8916_wdt.c
+++ b/drivers/watchdog/pm8916_wdt.c
@@ -132,15 +132,16 @@ static const struct watchdog_ops pm8916_wdt_ops = {
static int pm8916_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct pm8916_wdt *wdt;
struct device *parent;
int err, irq;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
- parent = pdev->dev.parent;
+ parent = dev->parent;
/*
* The pm8916-pon-wdt is a child of the pon device, which is a child
@@ -150,20 +151,20 @@ static int pm8916_wdt_probe(struct platform_device *pdev)
*/
wdt->regmap = dev_get_regmap(parent->parent, NULL);
if (!wdt->regmap) {
- dev_err(&pdev->dev, "failed to locate regmap\n");
+ dev_err(dev, "failed to locate regmap\n");
return -ENODEV;
}
err = device_property_read_u32(parent, "reg", &wdt->baseaddr);
if (err) {
- dev_err(&pdev->dev, "failed to get pm8916-pon address\n");
+ dev_err(dev, "failed to get pm8916-pon address\n");
return err;
}
irq = platform_get_irq(pdev, 0);
if (irq > 0) {
- if (devm_request_irq(&pdev->dev, irq, pm8916_wdt_isr, 0,
- "pm8916_wdt", wdt))
+ if (devm_request_irq(dev, irq, pm8916_wdt_isr, 0, "pm8916_wdt",
+ wdt))
irq = 0;
}
@@ -172,23 +173,23 @@ static int pm8916_wdt_probe(struct platform_device *pdev)
wdt->baseaddr + PON_PMIC_WD_RESET_S2_CTL,
RESET_TYPE_HARD);
if (err) {
- dev_err(&pdev->dev, "failed configure watchdog\n");
+ dev_err(dev, "failed configure watchdog\n");
return err;
}
wdt->wdev.info = (irq > 0) ? &pm8916_wdt_pt_ident : &pm8916_wdt_ident,
wdt->wdev.ops = &pm8916_wdt_ops,
- wdt->wdev.parent = &pdev->dev;
+ wdt->wdev.parent = dev;
wdt->wdev.min_timeout = PM8916_WDT_MIN_TIMEOUT;
wdt->wdev.max_timeout = PM8916_WDT_MAX_TIMEOUT;
wdt->wdev.timeout = PM8916_WDT_DEFAULT_TIMEOUT;
wdt->wdev.pretimeout = 0;
watchdog_set_drvdata(&wdt->wdev, wdt);
- watchdog_init_timeout(&wdt->wdev, 0, &pdev->dev);
+ watchdog_init_timeout(&wdt->wdev, 0, dev);
pm8916_wdt_configure_timers(&wdt->wdev);
- return devm_watchdog_register_device(&pdev->dev, &wdt->wdev);
+ return devm_watchdog_register_device(dev, &wdt->wdev);
}
static const struct of_device_id pm8916_wdt_id_table[] = {
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 8e261799c84e..d9e03544aeae 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -183,54 +183,50 @@ static struct watchdog_device pnx4008_wdd = {
.max_timeout = MAX_HEARTBEAT,
};
+static void pnx4008_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int pnx4008_wdt_probe(struct platform_device *pdev)
{
- struct resource *r;
+ struct device *dev = &pdev->dev;
int ret = 0;
- watchdog_init_timeout(&pnx4008_wdd, heartbeat, &pdev->dev);
+ watchdog_init_timeout(&pnx4008_wdd, heartbeat, dev);
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt_base = devm_ioremap_resource(&pdev->dev, r);
+ wdt_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt_base))
return PTR_ERR(wdt_base);
- wdt_clk = devm_clk_get(&pdev->dev, NULL);
+ wdt_clk = devm_clk_get(dev, NULL);
if (IS_ERR(wdt_clk))
return PTR_ERR(wdt_clk);
ret = clk_prepare_enable(wdt_clk);
if (ret)
return ret;
+ ret = devm_add_action_or_reset(dev, pnx4008_clk_disable_unprepare,
+ wdt_clk);
+ if (ret)
+ return ret;
pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
WDIOF_CARDRESET : 0;
- pnx4008_wdd.parent = &pdev->dev;
+ pnx4008_wdd.parent = dev;
watchdog_set_nowayout(&pnx4008_wdd, nowayout);
watchdog_set_restart_priority(&pnx4008_wdd, 128);
- pnx4008_wdt_stop(&pnx4008_wdd); /* disable for now */
+ if (readl(WDTIM_CTRL(wdt_base)) & COUNT_ENAB)
+ set_bit(WDOG_HW_RUNNING, &pnx4008_wdd.status);
- ret = watchdog_register_device(&pnx4008_wdd);
+ ret = devm_watchdog_register_device(dev, &pnx4008_wdd);
if (ret < 0) {
- dev_err(&pdev->dev, "cannot register watchdog device\n");
- goto disable_clk;
+ dev_err(dev, "cannot register watchdog device\n");
+ return ret;
}
- dev_info(&pdev->dev, "heartbeat %d sec\n", pnx4008_wdd.timeout);
-
- return 0;
-
-disable_clk:
- clk_disable_unprepare(wdt_clk);
- return ret;
-}
-
-static int pnx4008_wdt_remove(struct platform_device *pdev)
-{
- watchdog_unregister_device(&pnx4008_wdd);
-
- clk_disable_unprepare(wdt_clk);
+ dev_info(dev, "heartbeat %d sec\n", pnx4008_wdd.timeout);
return 0;
}
@@ -249,7 +245,6 @@ static struct platform_driver platform_wdt_driver = {
.of_match_table = of_match_ptr(pnx4008_wdt_match),
},
.probe = pnx4008_wdt_probe,
- .remove = pnx4008_wdt_remove,
};
module_platform_driver(platform_wdt_driver);
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index 5dfd604477a4..6d29c33b1316 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -142,22 +142,28 @@ static const struct watchdog_info qcom_wdt_info = {
.identity = KBUILD_MODNAME,
};
+static void qcom_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int qcom_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct qcom_wdt *wdt;
struct resource *res;
- struct device_node *np = pdev->dev.of_node;
+ struct device_node *np = dev->of_node;
const u32 *regs;
u32 percpu_offset;
int ret;
- regs = of_device_get_match_data(&pdev->dev);
+ regs = of_device_get_match_data(dev);
if (!regs) {
- dev_err(&pdev->dev, "Unsupported QCOM WDT module\n");
+ dev_err(dev, "Unsupported QCOM WDT module\n");
return -ENODEV;
}
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -172,21 +178,25 @@ static int qcom_wdt_probe(struct platform_device *pdev)
res->start += percpu_offset;
res->end += percpu_offset;
- wdt->base = devm_ioremap_resource(&pdev->dev, res);
+ wdt->base = devm_ioremap_resource(dev, res);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
- wdt->clk = devm_clk_get(&pdev->dev, NULL);
+ wdt->clk = devm_clk_get(dev, NULL);
if (IS_ERR(wdt->clk)) {
- dev_err(&pdev->dev, "failed to get input clock\n");
+ dev_err(dev, "failed to get input clock\n");
return PTR_ERR(wdt->clk);
}
ret = clk_prepare_enable(wdt->clk);
if (ret) {
- dev_err(&pdev->dev, "failed to setup clock\n");
+ dev_err(dev, "failed to setup clock\n");
return ret;
}
+ ret = devm_add_action_or_reset(dev, qcom_clk_disable_unprepare,
+ wdt->clk);
+ if (ret)
+ return ret;
/*
* We use the clock rate to calculate the max timeout, so ensure it's
@@ -199,16 +209,15 @@ static int qcom_wdt_probe(struct platform_device *pdev)
wdt->rate = clk_get_rate(wdt->clk);
if (wdt->rate == 0 ||
wdt->rate > 0x10000000U) {
- dev_err(&pdev->dev, "invalid clock rate\n");
- ret = -EINVAL;
- goto err_clk_unprepare;
+ dev_err(dev, "invalid clock rate\n");
+ return -EINVAL;
}
wdt->wdd.info = &qcom_wdt_info;
wdt->wdd.ops = &qcom_wdt_ops;
wdt->wdd.min_timeout = 1;
wdt->wdd.max_timeout = 0x10000000U / wdt->rate;
- wdt->wdd.parent = &pdev->dev;
+ wdt->wdd.parent = dev;
wdt->layout = regs;
if (readl(wdt_addr(wdt, WDT_STS)) & 1)
@@ -220,29 +229,16 @@ static int qcom_wdt_probe(struct platform_device *pdev)
* the max instead.
*/
wdt->wdd.timeout = min(wdt->wdd.max_timeout, 30U);
- watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
+ watchdog_init_timeout(&wdt->wdd, 0, dev);
- ret = watchdog_register_device(&wdt->wdd);
+ ret = devm_watchdog_register_device(dev, &wdt->wdd);
if (ret) {
- dev_err(&pdev->dev, "failed to register watchdog\n");
- goto err_clk_unprepare;
+ dev_err(dev, "failed to register watchdog\n");
+ return ret;
}
platform_set_drvdata(pdev, wdt);
return 0;
-
-err_clk_unprepare:
- clk_disable_unprepare(wdt->clk);
- return ret;
-}
-
-static int qcom_wdt_remove(struct platform_device *pdev)
-{
- struct qcom_wdt *wdt = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&wdt->wdd);
- clk_disable_unprepare(wdt->clk);
- return 0;
}
static int __maybe_unused qcom_wdt_suspend(struct device *dev)
@@ -277,7 +273,6 @@ MODULE_DEVICE_TABLE(of, qcom_wdt_of_table);
static struct platform_driver qcom_watchdog_driver = {
.probe = qcom_wdt_probe,
- .remove = qcom_wdt_remove,
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = qcom_wdt_of_table,
diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c
index 622ede529912..565dbc1ec638 100644
--- a/drivers/watchdog/renesas_wdt.c
+++ b/drivers/watchdog/renesas_wdt.c
@@ -151,7 +151,6 @@ static const struct soc_device_attribute rwdt_quirks_match[] = {
.data = (void *)1, /* needs single CPU */
}, {
.soc_id = "r8a7792",
- .revision = "*",
.data = (void *)0, /* needs SMP disabled */
},
{ /* sentinel */ }
@@ -177,7 +176,6 @@ static inline bool rwdt_blacklisted(struct device *dev) { return false; }
static int rwdt_probe(struct platform_device *pdev)
{
struct rwdt_priv *priv;
- struct resource *res;
struct clk *clk;
unsigned long clks_per_sec;
int ret, i;
@@ -189,8 +187,7 @@ static int rwdt_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->base = devm_ioremap_resource(&pdev->dev, res);
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
@@ -238,9 +235,7 @@ static int rwdt_probe(struct platform_device *pdev)
watchdog_stop_on_unregister(&priv->wdev);
/* This overrides the default timeout only if DT configuration was found */
- ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev);
- if (ret)
- dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n");
+ watchdog_init_timeout(&priv->wdev, 0, &pdev->dev);
ret = watchdog_register_device(&priv->wdev);
if (ret < 0)
diff --git a/drivers/watchdog/rn5t618_wdt.c b/drivers/watchdog/rn5t618_wdt.c
index e60f55702ab7..21fcb36f9074 100644
--- a/drivers/watchdog/rn5t618_wdt.c
+++ b/drivers/watchdog/rn5t618_wdt.c
@@ -146,11 +146,12 @@ static const struct watchdog_ops rn5t618_wdt_ops = {
static int rn5t618_wdt_probe(struct platform_device *pdev)
{
- struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent);
+ struct device *dev = &pdev->dev;
+ struct rn5t618 *rn5t618 = dev_get_drvdata(dev->parent);
struct rn5t618_wdt *wdt;
int min_timeout, max_timeout;
- wdt = devm_kzalloc(&pdev->dev, sizeof(struct rn5t618_wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(struct rn5t618_wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -163,10 +164,10 @@ static int rn5t618_wdt_probe(struct platform_device *pdev)
wdt->wdt_dev.min_timeout = min_timeout;
wdt->wdt_dev.max_timeout = max_timeout;
wdt->wdt_dev.timeout = max_timeout;
- wdt->wdt_dev.parent = &pdev->dev;
+ wdt->wdt_dev.parent = dev;
watchdog_set_drvdata(&wdt->wdt_dev, wdt);
- watchdog_init_timeout(&wdt->wdt_dev, timeout, &pdev->dev);
+ watchdog_init_timeout(&wdt->wdt_dev, timeout, dev);
watchdog_set_nowayout(&wdt->wdt_dev, nowayout);
platform_set_drvdata(pdev, wdt);
diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c
index db7c57d82cfd..905e60f45eec 100644
--- a/drivers/watchdog/rt2880_wdt.c
+++ b/drivers/watchdog/rt2880_wdt.c
@@ -141,19 +141,18 @@ static struct watchdog_device rt288x_wdt_dev = {
static int rt288x_wdt_probe(struct platform_device *pdev)
{
- struct resource *res;
+ struct device *dev = &pdev->dev;
int ret;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rt288x_wdt_base = devm_ioremap_resource(&pdev->dev, res);
+ rt288x_wdt_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rt288x_wdt_base))
return PTR_ERR(rt288x_wdt_base);
- rt288x_wdt_clk = devm_clk_get(&pdev->dev, NULL);
+ rt288x_wdt_clk = devm_clk_get(dev, NULL);
if (IS_ERR(rt288x_wdt_clk))
return PTR_ERR(rt288x_wdt_clk);
- rt288x_wdt_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+ rt288x_wdt_reset = devm_reset_control_get_exclusive(dev, NULL);
if (!IS_ERR(rt288x_wdt_reset))
reset_control_deassert(rt288x_wdt_reset);
@@ -161,31 +160,20 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause();
rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq);
- rt288x_wdt_dev.parent = &pdev->dev;
+ rt288x_wdt_dev.parent = dev;
watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout,
- &pdev->dev);
+ dev);
watchdog_set_nowayout(&rt288x_wdt_dev, nowayout);
- ret = watchdog_register_device(&rt288x_wdt_dev);
+ watchdog_stop_on_reboot(&rt288x_wdt_dev);
+ ret = devm_watchdog_register_device(dev, &rt288x_wdt_dev);
if (!ret)
- dev_info(&pdev->dev, "Initialized\n");
+ dev_info(dev, "Initialized\n");
return 0;
}
-static int rt288x_wdt_remove(struct platform_device *pdev)
-{
- watchdog_unregister_device(&rt288x_wdt_dev);
-
- return 0;
-}
-
-static void rt288x_wdt_shutdown(struct platform_device *pdev)
-{
- rt288x_wdt_stop(&rt288x_wdt_dev);
-}
-
static const struct of_device_id rt288x_wdt_match[] = {
{ .compatible = "ralink,rt2880-wdt" },
{},
@@ -194,8 +182,6 @@ MODULE_DEVICE_TABLE(of, rt288x_wdt_match);
static struct platform_driver rt288x_wdt_driver = {
.probe = rt288x_wdt_probe,
- .remove = rt288x_wdt_remove,
- .shutdown = rt288x_wdt_shutdown,
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = rt288x_wdt_match,
diff --git a/drivers/watchdog/rtd119x_wdt.c b/drivers/watchdog/rtd119x_wdt.c
index d001c17ddfde..834b94ff3f90 100644
--- a/drivers/watchdog/rtd119x_wdt.c
+++ b/drivers/watchdog/rtd119x_wdt.c
@@ -9,7 +9,6 @@
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/io.h>
-#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
@@ -95,37 +94,43 @@ static const struct of_device_id rtd119x_wdt_dt_ids[] = {
{ }
};
+static void rtd119x_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int rtd119x_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct rtd119x_watchdog_device *data;
- struct resource *res;
int ret;
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- data->base = devm_ioremap_resource(&pdev->dev, res);
+ data->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->base))
return PTR_ERR(data->base);
- data->clk = of_clk_get(pdev->dev.of_node, 0);
+ data->clk = devm_clk_get(dev, NULL);
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);
ret = clk_prepare_enable(data->clk);
- if (ret) {
- clk_put(data->clk);
+ if (ret)
+ return ret;
+ ret = devm_add_action_or_reset(dev, rtd119x_clk_disable_unprepare,
+ data->clk);
+ if (ret)
return ret;
- }
data->wdt_dev.info = &rtd119x_wdt_info;
data->wdt_dev.ops = &rtd119x_wdt_ops;
data->wdt_dev.timeout = 120;
data->wdt_dev.max_timeout = 0xffffffff / clk_get_rate(data->clk);
data->wdt_dev.min_timeout = 1;
- data->wdt_dev.parent = &pdev->dev;
+ data->wdt_dev.parent = dev;
watchdog_stop_on_reboot(&data->wdt_dev);
watchdog_set_drvdata(&data->wdt_dev, data);
@@ -135,31 +140,11 @@ static int rtd119x_wdt_probe(struct platform_device *pdev)
rtd119x_wdt_set_timeout(&data->wdt_dev, data->wdt_dev.timeout);
rtd119x_wdt_stop(&data->wdt_dev);
- ret = devm_watchdog_register_device(&pdev->dev, &data->wdt_dev);
- if (ret) {
- clk_disable_unprepare(data->clk);
- clk_put(data->clk);
- return ret;
- }
-
- return 0;
-}
-
-static int rtd119x_wdt_remove(struct platform_device *pdev)
-{
- struct rtd119x_watchdog_device *data = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&data->wdt_dev);
-
- clk_disable_unprepare(data->clk);
- clk_put(data->clk);
-
- return 0;
+ return devm_watchdog_register_device(dev, &data->wdt_dev);
}
static struct platform_driver rtd119x_wdt_driver = {
.probe = rtd119x_wdt_probe,
- .remove = rtd119x_wdt_remove,
.driver = {
.name = "rtd1295-watchdog",
.of_match_table = rtd119x_wdt_dt_ids,
diff --git a/drivers/watchdog/rza_wdt.c b/drivers/watchdog/rza_wdt.c
index 781bb572e6af..7b6c365f7cd3 100644
--- a/drivers/watchdog/rza_wdt.c
+++ b/drivers/watchdog/rza_wdt.c
@@ -166,35 +166,34 @@ static const struct watchdog_ops rza_wdt_ops = {
static int rza_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct rza_wdt *priv;
- struct resource *res;
unsigned long rate;
int ret;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->base = devm_ioremap_resource(&pdev->dev, res);
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
- priv->clk = devm_clk_get(&pdev->dev, NULL);
+ priv->clk = devm_clk_get(dev, NULL);
if (IS_ERR(priv->clk))
return PTR_ERR(priv->clk);
rate = clk_get_rate(priv->clk);
if (rate < 16384) {
- dev_err(&pdev->dev, "invalid clock rate (%ld)\n", rate);
+ dev_err(dev, "invalid clock rate (%ld)\n", rate);
return -ENOENT;
}
priv->wdev.info = &rza_wdt_ident,
priv->wdev.ops = &rza_wdt_ops,
- priv->wdev.parent = &pdev->dev;
+ priv->wdev.parent = dev;
- priv->cks = (u8)(uintptr_t)of_device_get_match_data(&pdev->dev);
+ priv->cks = (u8)(uintptr_t) of_device_get_match_data(dev);
if (priv->cks == CKS_4BIT) {
/* Assume slowest clock rate possible (CKS=0xF) */
priv->wdev.max_timeout = (DIVIDER_4BIT * U8_MAX) / rate;
@@ -209,19 +208,19 @@ static int rza_wdt_probe(struct platform_device *pdev)
* max_hw_heartbeat_ms.
*/
priv->wdev.max_hw_heartbeat_ms = (1000 * U8_MAX) / rate;
- dev_dbg(&pdev->dev, "max hw timeout of %dms\n",
- priv->wdev.max_hw_heartbeat_ms);
+ dev_dbg(dev, "max hw timeout of %dms\n",
+ priv->wdev.max_hw_heartbeat_ms);
}
priv->wdev.min_timeout = 1;
priv->wdev.timeout = DEFAULT_TIMEOUT;
- watchdog_init_timeout(&priv->wdev, 0, &pdev->dev);
+ watchdog_init_timeout(&priv->wdev, 0, dev);
watchdog_set_drvdata(&priv->wdev, priv);
- ret = devm_watchdog_register_device(&pdev->dev, &priv->wdev);
+ ret = devm_watchdog_register_device(dev, &priv->wdev);
if (ret)
- dev_err(&pdev->dev, "Cannot register watchdog device\n");
+ dev_err(dev, "Cannot register watchdog device\n");
return ret;
}
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index adaa43543f0a..4267b9e8734b 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -522,7 +522,6 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct s3c2410_wdt *wdt;
- struct resource *wdt_mem;
struct resource *wdt_irq;
unsigned int wtcon;
int started = 0;
@@ -554,8 +553,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
}
/* get the memory region for the watchdog timer */
- wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->reg_base = devm_ioremap_resource(dev, wdt_mem);
+ wdt->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->reg_base)) {
ret = PTR_ERR(wdt->reg_base);
goto err;
diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c
index 1e93c1b0e3cf..111695223aae 100644
--- a/drivers/watchdog/sama5d4_wdt.c
+++ b/drivers/watchdog/sama5d4_wdt.c
@@ -199,15 +199,15 @@ static int sama5d4_wdt_init(struct sama5d4_wdt *wdt)
static int sama5d4_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct watchdog_device *wdd;
struct sama5d4_wdt *wdt;
- struct resource *res;
void __iomem *regs;
u32 irq = 0;
u32 timeout;
int ret;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -221,33 +221,31 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdd, wdt);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- regs = devm_ioremap_resource(&pdev->dev, res);
+ regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs))
return PTR_ERR(regs);
wdt->reg_base = regs;
- irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ irq = irq_of_parse_and_map(dev->of_node, 0);
if (!irq)
- dev_warn(&pdev->dev, "failed to get IRQ from DT\n");
+ dev_warn(dev, "failed to get IRQ from DT\n");
- ret = of_sama5d4_wdt_init(pdev->dev.of_node, wdt);
+ ret = of_sama5d4_wdt_init(dev->of_node, wdt);
if (ret)
return ret;
if ((wdt->mr & AT91_WDT_WDFIEN) && irq) {
- ret = devm_request_irq(&pdev->dev, irq, sama5d4_wdt_irq_handler,
+ ret = devm_request_irq(dev, irq, sama5d4_wdt_irq_handler,
IRQF_SHARED | IRQF_IRQPOLL |
IRQF_NO_SUSPEND, pdev->name, pdev);
if (ret) {
- dev_err(&pdev->dev,
- "cannot register interrupt handler\n");
+ dev_err(dev, "cannot register interrupt handler\n");
return ret;
}
}
- watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
+ watchdog_init_timeout(wdd, wdt_timeout, dev);
timeout = WDT_SEC2TICKS(wdd->timeout);
@@ -260,31 +258,21 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
watchdog_set_nowayout(wdd, nowayout);
- ret = watchdog_register_device(wdd);
+ watchdog_stop_on_unregister(wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
- dev_err(&pdev->dev, "failed to register watchdog device\n");
+ dev_err(dev, "failed to register watchdog device\n");
return ret;
}
platform_set_drvdata(pdev, wdt);
- dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
+ dev_info(dev, "initialized (timeout = %d sec, nowayout = %d)\n",
wdd->timeout, nowayout);
return 0;
}
-static int sama5d4_wdt_remove(struct platform_device *pdev)
-{
- struct sama5d4_wdt *wdt = platform_get_drvdata(pdev);
-
- sama5d4_wdt_stop(&wdt->wdd);
-
- watchdog_unregister_device(&wdt->wdd);
-
- return 0;
-}
-
static const struct of_device_id sama5d4_wdt_of_match[] = {
{ .compatible = "atmel,sama5d4-wdt", },
{ }
@@ -312,7 +300,6 @@ static SIMPLE_DEV_PM_OPS(sama5d4_wdt_pm_ops, NULL,
static struct platform_driver sama5d4_wdt_driver = {
.probe = sama5d4_wdt_probe,
- .remove = sama5d4_wdt_remove,
.driver = {
.name = "sama5d4_wdt",
.pm = &sama5d4_wdt_pm_ops,
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index 0692d42e5c67..5a6ced7a7e8f 100644
--- a/drivers/watchdog/sb_wdog.c
+++ b/drivers/watchdog/sb_wdog.c
@@ -67,7 +67,7 @@ static DEFINE_SPINLOCK(sbwd_lock);
*
* wdog is the iomem address of the cfg register
*/
-void sbwdog_set(char __iomem *wdog, unsigned long t)
+static void sbwdog_set(char __iomem *wdog, unsigned long t)
{
spin_lock(&sbwd_lock);
__raw_writeb(0, wdog);
@@ -81,7 +81,7 @@ void sbwdog_set(char __iomem *wdog, unsigned long t)
*
* wdog is the iomem address of the cfg register
*/
-void sbwdog_pet(char __iomem *wdog)
+static void sbwdog_pet(char __iomem *wdog)
{
spin_lock(&sbwd_lock);
__raw_writeb(__raw_readb(wdog) | 1, wdog);
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
index e221e47396ab..3219422f67a9 100644
--- a/drivers/watchdog/sbsa_gwdt.c
+++ b/drivers/watchdog/sbsa_gwdt.c
@@ -231,7 +231,6 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct watchdog_device *wdd;
struct sbsa_gwdt *gwdt;
- struct resource *res;
int ret, irq;
u32 status;
@@ -240,13 +239,11 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, gwdt);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- cf_base = devm_ioremap_resource(dev, res);
+ cf_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(cf_base))
return PTR_ERR(cf_base);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- rf_base = devm_ioremap_resource(dev, res);
+ rf_base = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(rf_base))
return PTR_ERR(rf_base);
@@ -313,7 +310,8 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
*/
sbsa_gwdt_set_timeout(wdd, wdd->timeout);
- ret = watchdog_register_device(wdd);
+ watchdog_stop_on_reboot(wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret)
return ret;
@@ -324,22 +322,6 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
return 0;
}
-static void sbsa_gwdt_shutdown(struct platform_device *pdev)
-{
- struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
-
- sbsa_gwdt_stop(&gwdt->wdd);
-}
-
-static int sbsa_gwdt_remove(struct platform_device *pdev)
-{
- struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&gwdt->wdd);
-
- return 0;
-}
-
/* Disable watchdog if it is active during suspend */
static int __maybe_unused sbsa_gwdt_suspend(struct device *dev)
{
@@ -385,8 +367,6 @@ static struct platform_driver sbsa_gwdt_driver = {
.of_match_table = sbsa_gwdt_of_match,
},
.probe = sbsa_gwdt_probe,
- .remove = sbsa_gwdt_remove,
- .shutdown = sbsa_gwdt_shutdown,
.id_table = sbsa_gwdt_pdev_match,
};
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index a7d6425db807..e7617b7df70b 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -220,7 +220,6 @@ static struct watchdog_device sh_wdt_dev = {
static int sh_wdt_probe(struct platform_device *pdev)
{
struct sh_wdt *wdt;
- struct resource *res;
int rc;
/*
@@ -245,8 +244,7 @@ static int sh_wdt_probe(struct platform_device *pdev)
wdt->clk = NULL;
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->base = devm_ioremap_resource(wdt->dev, res);
+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c
index ac0c9d2c4aee..e79a4097d50b 100644
--- a/drivers/watchdog/sirfsoc_wdt.c
+++ b/drivers/watchdog/sirfsoc_wdt.c
@@ -146,22 +146,23 @@ static struct watchdog_device sirfsoc_wdd = {
static int sirfsoc_wdt_probe(struct platform_device *pdev)
{
- struct resource *res;
+ struct device *dev = &pdev->dev;
int ret;
void __iomem *base;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&pdev->dev, res);
+ base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
watchdog_set_drvdata(&sirfsoc_wdd, (__force void *)base);
- watchdog_init_timeout(&sirfsoc_wdd, timeout, &pdev->dev);
+ watchdog_init_timeout(&sirfsoc_wdd, timeout, dev);
watchdog_set_nowayout(&sirfsoc_wdd, nowayout);
- sirfsoc_wdd.parent = &pdev->dev;
+ sirfsoc_wdd.parent = dev;
- ret = watchdog_register_device(&sirfsoc_wdd);
+ watchdog_stop_on_reboot(&sirfsoc_wdd);
+ watchdog_stop_on_unregister(&sirfsoc_wdd);
+ ret = devm_watchdog_register_device(dev, &sirfsoc_wdd);
if (ret)
return ret;
@@ -170,19 +171,6 @@ static int sirfsoc_wdt_probe(struct platform_device *pdev)
return 0;
}
-static void sirfsoc_wdt_shutdown(struct platform_device *pdev)
-{
- struct watchdog_device *wdd = platform_get_drvdata(pdev);
-
- sirfsoc_wdt_disable(wdd);
-}
-
-static int sirfsoc_wdt_remove(struct platform_device *pdev)
-{
- sirfsoc_wdt_shutdown(pdev);
- return 0;
-}
-
#ifdef CONFIG_PM_SLEEP
static int sirfsoc_wdt_suspend(struct device *dev)
{
@@ -220,8 +208,6 @@ static struct platform_driver sirfsoc_wdt_driver = {
.of_match_table = sirfsoc_wdt_of_match,
},
.probe = sirfsoc_wdt_probe,
- .remove = sirfsoc_wdt_remove,
- .shutdown = sirfsoc_wdt_shutdown,
};
module_platform_driver(sirfsoc_wdt_driver);
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index 41aaae2d5287..553735b256e2 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -395,9 +395,7 @@ static int sp5100_tco_probe(struct platform_device *pdev)
wdd->min_timeout = 1;
wdd->max_timeout = 0xffff;
- if (watchdog_init_timeout(wdd, heartbeat, NULL))
- dev_info(dev, "timeout value invalid, using %d\n",
- wdd->timeout);
+ watchdog_init_timeout(wdd, heartbeat, NULL);
watchdog_set_nowayout(wdd, nowayout);
watchdog_stop_on_reboot(wdd);
watchdog_stop_on_unregister(wdd);
diff --git a/drivers/watchdog/sprd_wdt.c b/drivers/watchdog/sprd_wdt.c
index ff9397d9638a..14874e9b207b 100644
--- a/drivers/watchdog/sprd_wdt.c
+++ b/drivers/watchdog/sprd_wdt.c
@@ -245,9 +245,7 @@ static u32 sprd_wdt_get_timeleft(struct watchdog_device *wdd)
u32 val;
val = sprd_wdt_get_cnt_value(wdt);
- val = val / SPRD_WDT_CNT_STEP;
-
- return val;
+ return val / SPRD_WDT_CNT_STEP;
}
static const struct watchdog_ops sprd_wdt_ops = {
@@ -269,70 +267,68 @@ static const struct watchdog_info sprd_wdt_info = {
static int sprd_wdt_probe(struct platform_device *pdev)
{
- struct resource *wdt_res;
+ struct device *dev = &pdev->dev;
struct sprd_wdt *wdt;
int ret;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
- wdt_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->base = devm_ioremap_resource(&pdev->dev, wdt_res);
+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
- wdt->enable = devm_clk_get(&pdev->dev, "enable");
+ wdt->enable = devm_clk_get(dev, "enable");
if (IS_ERR(wdt->enable)) {
- dev_err(&pdev->dev, "can't get the enable clock\n");
+ dev_err(dev, "can't get the enable clock\n");
return PTR_ERR(wdt->enable);
}
- wdt->rtc_enable = devm_clk_get(&pdev->dev, "rtc_enable");
+ wdt->rtc_enable = devm_clk_get(dev, "rtc_enable");
if (IS_ERR(wdt->rtc_enable)) {
- dev_err(&pdev->dev, "can't get the rtc enable clock\n");
+ dev_err(dev, "can't get the rtc enable clock\n");
return PTR_ERR(wdt->rtc_enable);
}
wdt->irq = platform_get_irq(pdev, 0);
if (wdt->irq < 0) {
- dev_err(&pdev->dev, "failed to get IRQ resource\n");
+ dev_err(dev, "failed to get IRQ resource\n");
return wdt->irq;
}
- ret = devm_request_irq(&pdev->dev, wdt->irq, sprd_wdt_isr,
- IRQF_NO_SUSPEND, "sprd-wdt", (void *)wdt);
+ ret = devm_request_irq(dev, wdt->irq, sprd_wdt_isr, IRQF_NO_SUSPEND,
+ "sprd-wdt", (void *)wdt);
if (ret) {
- dev_err(&pdev->dev, "failed to register irq\n");
+ dev_err(dev, "failed to register irq\n");
return ret;
}
wdt->wdd.info = &sprd_wdt_info;
wdt->wdd.ops = &sprd_wdt_ops;
- wdt->wdd.parent = &pdev->dev;
+ wdt->wdd.parent = dev;
wdt->wdd.min_timeout = SPRD_WDT_MIN_TIMEOUT;
wdt->wdd.max_timeout = SPRD_WDT_MAX_TIMEOUT;
wdt->wdd.timeout = SPRD_WDT_MAX_TIMEOUT;
ret = sprd_wdt_enable(wdt);
if (ret) {
- dev_err(&pdev->dev, "failed to enable wdt\n");
+ dev_err(dev, "failed to enable wdt\n");
return ret;
}
- ret = devm_add_action(&pdev->dev, sprd_wdt_disable, wdt);
+ ret = devm_add_action_or_reset(dev, sprd_wdt_disable, wdt);
if (ret) {
- sprd_wdt_disable(wdt);
- dev_err(&pdev->dev, "Failed to add wdt disable action\n");
+ dev_err(dev, "Failed to add wdt disable action\n");
return ret;
}
watchdog_set_nowayout(&wdt->wdd, WATCHDOG_NOWAYOUT);
- watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
+ watchdog_init_timeout(&wdt->wdd, 0, dev);
- ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
+ ret = devm_watchdog_register_device(dev, &wdt->wdd);
if (ret) {
sprd_wdt_disable(wdt);
- dev_err(&pdev->dev, "failed to register watchdog\n");
+ dev_err(dev, "failed to register watchdog\n");
return ret;
}
platform_set_drvdata(pdev, wdt);
diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c
index 177829b379da..7a90184eb950 100644
--- a/drivers/watchdog/st_lpc_wdt.c
+++ b/drivers/watchdog/st_lpc_wdt.c
@@ -142,13 +142,18 @@ static struct watchdog_device st_wdog_dev = {
.ops = &st_wdog_ops,
};
+static void st_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int st_wdog_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
const struct of_device_id *match;
- struct device_node *np = pdev->dev.of_node;
+ struct device_node *np = dev->of_node;
struct st_wdog *st_wdog;
struct regmap *regmap;
- struct resource *res;
struct clk *clk;
void __iomem *base;
uint32_t mode;
@@ -156,7 +161,7 @@ static int st_wdog_probe(struct platform_device *pdev)
ret = of_property_read_u32(np, "st,lpc-mode", &mode);
if (ret) {
- dev_err(&pdev->dev, "An LPC mode must be provided\n");
+ dev_err(dev, "An LPC mode must be provided\n");
return -EINVAL;
}
@@ -164,35 +169,34 @@ static int st_wdog_probe(struct platform_device *pdev)
if (mode != ST_LPC_MODE_WDT)
return -ENODEV;
- st_wdog = devm_kzalloc(&pdev->dev, sizeof(*st_wdog), GFP_KERNEL);
+ st_wdog = devm_kzalloc(dev, sizeof(*st_wdog), GFP_KERNEL);
if (!st_wdog)
return -ENOMEM;
- match = of_match_device(st_wdog_match, &pdev->dev);
+ match = of_match_device(st_wdog_match, dev);
if (!match) {
- dev_err(&pdev->dev, "Couldn't match device\n");
+ dev_err(dev, "Couldn't match device\n");
return -ENODEV;
}
st_wdog->syscfg = (struct st_wdog_syscfg *)match->data;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&pdev->dev, res);
+ base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
if (IS_ERR(regmap)) {
- dev_err(&pdev->dev, "No syscfg phandle specified\n");
+ dev_err(dev, "No syscfg phandle specified\n");
return PTR_ERR(regmap);
}
- clk = devm_clk_get(&pdev->dev, NULL);
+ clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) {
- dev_err(&pdev->dev, "Unable to request clock\n");
+ dev_err(dev, "Unable to request clock\n");
return PTR_ERR(clk);
}
- st_wdog->dev = &pdev->dev;
+ st_wdog->dev = dev;
st_wdog->base = base;
st_wdog->clk = clk;
st_wdog->regmap = regmap;
@@ -200,39 +204,38 @@ static int st_wdog_probe(struct platform_device *pdev)
st_wdog->clkrate = clk_get_rate(st_wdog->clk);
if (!st_wdog->clkrate) {
- dev_err(&pdev->dev, "Unable to fetch clock rate\n");
+ dev_err(dev, "Unable to fetch clock rate\n");
return -EINVAL;
}
st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate;
- st_wdog_dev.parent = &pdev->dev;
+ st_wdog_dev.parent = dev;
ret = clk_prepare_enable(clk);
if (ret) {
- dev_err(&pdev->dev, "Unable to enable clock\n");
+ dev_err(dev, "Unable to enable clock\n");
return ret;
}
+ ret = devm_add_action_or_reset(dev, st_clk_disable_unprepare, clk);
+ if (ret)
+ return ret;
watchdog_set_drvdata(&st_wdog_dev, st_wdog);
watchdog_set_nowayout(&st_wdog_dev, WATCHDOG_NOWAYOUT);
/* Init Watchdog timeout with value in DT */
- ret = watchdog_init_timeout(&st_wdog_dev, 0, &pdev->dev);
- if (ret) {
- dev_err(&pdev->dev, "Unable to initialise watchdog timeout\n");
- clk_disable_unprepare(clk);
+ ret = watchdog_init_timeout(&st_wdog_dev, 0, dev);
+ if (ret)
return ret;
- }
- ret = watchdog_register_device(&st_wdog_dev);
+ ret = devm_watchdog_register_device(dev, &st_wdog_dev);
if (ret) {
- dev_err(&pdev->dev, "Unable to register watchdog\n");
- clk_disable_unprepare(clk);
+ dev_err(dev, "Unable to register watchdog\n");
return ret;
}
st_wdog_setup(st_wdog, true);
- dev_info(&pdev->dev, "LPC Watchdog driver registered, reset type is %s",
+ dev_info(dev, "LPC Watchdog driver registered, reset type is %s",
st_wdog->warm_reset ? "warm" : "cold");
return ret;
@@ -243,8 +246,6 @@ static int st_wdog_remove(struct platform_device *pdev)
struct st_wdog *st_wdog = watchdog_get_drvdata(&st_wdog_dev);
st_wdog_setup(st_wdog, false);
- watchdog_unregister_device(&st_wdog_dev);
- clk_disable_unprepare(st_wdog->clk);
return 0;
}
diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
index e00e3b3526c6..d569a3634d9b 100644
--- a/drivers/watchdog/stm32_iwdg.c
+++ b/drivers/watchdog/stm32_iwdg.c
@@ -34,36 +34,44 @@
#define KR_KEY_EWA 0x5555 /* write access enable */
#define KR_KEY_DWA 0x0000 /* write access disable */
-/* IWDG_PR register bit values */
-#define PR_4 0x00 /* prescaler set to 4 */
-#define PR_8 0x01 /* prescaler set to 8 */
-#define PR_16 0x02 /* prescaler set to 16 */
-#define PR_32 0x03 /* prescaler set to 32 */
-#define PR_64 0x04 /* prescaler set to 64 */
-#define PR_128 0x05 /* prescaler set to 128 */
-#define PR_256 0x06 /* prescaler set to 256 */
+/* IWDG_PR register */
+#define PR_SHIFT 2
+#define PR_MIN BIT(PR_SHIFT)
/* IWDG_RLR register values */
-#define RLR_MIN 0x07C /* min value supported by reload register */
-#define RLR_MAX 0xFFF /* max value supported by reload register */
+#define RLR_MIN 0x2 /* min value recommended */
+#define RLR_MAX GENMASK(11, 0) /* max value of reload register */
/* IWDG_SR register bit mask */
-#define FLAG_PVU BIT(0) /* Watchdog prescaler value update */
-#define FLAG_RVU BIT(1) /* Watchdog counter reload value update */
+#define SR_PVU BIT(0) /* Watchdog prescaler value update */
+#define SR_RVU BIT(1) /* Watchdog counter reload value update */
/* set timeout to 100000 us */
#define TIMEOUT_US 100000
#define SLEEP_US 1000
-#define HAS_PCLK true
+struct stm32_iwdg_data {
+ bool has_pclk;
+ u32 max_prescaler;
+};
+
+static const struct stm32_iwdg_data stm32_iwdg_data = {
+ .has_pclk = false,
+ .max_prescaler = 256,
+};
+
+static const struct stm32_iwdg_data stm32mp1_iwdg_data = {
+ .has_pclk = true,
+ .max_prescaler = 1024,
+};
struct stm32_iwdg {
struct watchdog_device wdd;
+ const struct stm32_iwdg_data *data;
void __iomem *regs;
struct clk *clk_lsi;
struct clk *clk_pclk;
unsigned int rate;
- bool has_pclk;
};
static inline u32 reg_read(void __iomem *base, u32 reg)
@@ -79,31 +87,35 @@ static inline void reg_write(void __iomem *base, u32 reg, u32 val)
static int stm32_iwdg_start(struct watchdog_device *wdd)
{
struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd);
- u32 val = FLAG_PVU | FLAG_RVU;
- u32 reload;
+ u32 tout, presc, iwdg_rlr, iwdg_pr, iwdg_sr;
int ret;
dev_dbg(wdd->parent, "%s\n", __func__);
- /* prescaler fixed to 256 */
- reload = clamp_t(unsigned int, ((wdd->timeout * wdt->rate) / 256) - 1,
- RLR_MIN, RLR_MAX);
+ tout = clamp_t(unsigned int, wdd->timeout,
+ wdd->min_timeout, wdd->max_hw_heartbeat_ms / 1000);
+
+ presc = DIV_ROUND_UP(tout * wdt->rate, RLR_MAX + 1);
+
+ /* The prescaler is align on power of 2 and start at 2 ^ PR_SHIFT. */
+ presc = roundup_pow_of_two(presc);
+ iwdg_pr = presc <= 1 << PR_SHIFT ? 0 : ilog2(presc) - PR_SHIFT;
+ iwdg_rlr = ((tout * wdt->rate) / presc) - 1;
/* enable write access */
reg_write(wdt->regs, IWDG_KR, KR_KEY_EWA);
/* set prescaler & reload registers */
- reg_write(wdt->regs, IWDG_PR, PR_256); /* prescaler fix to 256 */
- reg_write(wdt->regs, IWDG_RLR, reload);
+ reg_write(wdt->regs, IWDG_PR, iwdg_pr);
+ reg_write(wdt->regs, IWDG_RLR, iwdg_rlr);
reg_write(wdt->regs, IWDG_KR, KR_KEY_ENABLE);
/* wait for the registers to be updated (max 100ms) */
- ret = readl_relaxed_poll_timeout(wdt->regs + IWDG_SR, val,
- !(val & (FLAG_PVU | FLAG_RVU)),
+ ret = readl_relaxed_poll_timeout(wdt->regs + IWDG_SR, iwdg_sr,
+ !(iwdg_sr & (SR_PVU | SR_RVU)),
SLEEP_US, TIMEOUT_US);
if (ret) {
- dev_err(wdd->parent,
- "Fail to set prescaler or reload registers\n");
+ dev_err(wdd->parent, "Fail to set prescaler, reload regs\n");
return ret;
}
@@ -138,38 +150,52 @@ static int stm32_iwdg_set_timeout(struct watchdog_device *wdd,
return 0;
}
+static void stm32_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int stm32_iwdg_clk_init(struct platform_device *pdev,
struct stm32_iwdg *wdt)
{
+ struct device *dev = &pdev->dev;
u32 ret;
- wdt->clk_lsi = devm_clk_get(&pdev->dev, "lsi");
+ wdt->clk_lsi = devm_clk_get(dev, "lsi");
if (IS_ERR(wdt->clk_lsi)) {
- dev_err(&pdev->dev, "Unable to get lsi clock\n");
+ dev_err(dev, "Unable to get lsi clock\n");
return PTR_ERR(wdt->clk_lsi);
}
/* optional peripheral clock */
- if (wdt->has_pclk) {
- wdt->clk_pclk = devm_clk_get(&pdev->dev, "pclk");
+ if (wdt->data->has_pclk) {
+ wdt->clk_pclk = devm_clk_get(dev, "pclk");
if (IS_ERR(wdt->clk_pclk)) {
- dev_err(&pdev->dev, "Unable to get pclk clock\n");
+ dev_err(dev, "Unable to get pclk clock\n");
return PTR_ERR(wdt->clk_pclk);
}
ret = clk_prepare_enable(wdt->clk_pclk);
if (ret) {
- dev_err(&pdev->dev, "Unable to prepare pclk clock\n");
+ dev_err(dev, "Unable to prepare pclk clock\n");
return ret;
}
+ ret = devm_add_action_or_reset(dev,
+ stm32_clk_disable_unprepare,
+ wdt->clk_pclk);
+ if (ret)
+ return ret;
}
ret = clk_prepare_enable(wdt->clk_lsi);
if (ret) {
- dev_err(&pdev->dev, "Unable to prepare lsi clock\n");
- clk_disable_unprepare(wdt->clk_pclk);
+ dev_err(dev, "Unable to prepare lsi clock\n");
return ret;
}
+ ret = devm_add_action_or_reset(dev, stm32_clk_disable_unprepare,
+ wdt->clk_lsi);
+ if (ret)
+ return ret;
wdt->rate = clk_get_rate(wdt->clk_lsi);
@@ -191,35 +217,31 @@ static const struct watchdog_ops stm32_iwdg_ops = {
};
static const struct of_device_id stm32_iwdg_of_match[] = {
- { .compatible = "st,stm32-iwdg", .data = (void *)!HAS_PCLK },
- { .compatible = "st,stm32mp1-iwdg", .data = (void *)HAS_PCLK },
+ { .compatible = "st,stm32-iwdg", .data = &stm32_iwdg_data },
+ { .compatible = "st,stm32mp1-iwdg", .data = &stm32mp1_iwdg_data },
{ /* end node */ }
};
MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match);
static int stm32_iwdg_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct watchdog_device *wdd;
- const struct of_device_id *match;
struct stm32_iwdg *wdt;
- struct resource *res;
int ret;
- match = of_match_device(stm32_iwdg_of_match, &pdev->dev);
- if (!match)
- return -ENODEV;
-
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
- wdt->has_pclk = match->data;
+ wdt->data = of_device_get_match_data(&pdev->dev);
+ if (!wdt->data)
+ return -ENODEV;
/* This is the timer base. */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->regs = devm_ioremap_resource(&pdev->dev, res);
+ wdt->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->regs)) {
- dev_err(&pdev->dev, "Could not get resource\n");
+ dev_err(dev, "Could not get resource\n");
return PTR_ERR(wdt->regs);
}
@@ -229,50 +251,30 @@ static int stm32_iwdg_probe(struct platform_device *pdev)
/* Initialize struct watchdog_device. */
wdd = &wdt->wdd;
+ wdd->parent = dev;
wdd->info = &stm32_iwdg_info;
wdd->ops = &stm32_iwdg_ops;
- wdd->min_timeout = ((RLR_MIN + 1) * 256) / wdt->rate;
- wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * 256 * 1000) / wdt->rate;
- wdd->parent = &pdev->dev;
+ wdd->min_timeout = DIV_ROUND_UP((RLR_MIN + 1) * PR_MIN, wdt->rate);
+ wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * wdt->data->max_prescaler *
+ 1000) / wdt->rate;
watchdog_set_drvdata(wdd, wdt);
watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT);
+ watchdog_init_timeout(wdd, 0, dev);
- ret = watchdog_init_timeout(wdd, 0, &pdev->dev);
- if (ret)
- dev_warn(&pdev->dev,
- "unable to set timeout value, using default\n");
-
- ret = watchdog_register_device(wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
- dev_err(&pdev->dev, "failed to register watchdog device\n");
- goto err;
+ dev_err(dev, "failed to register watchdog device\n");
+ return ret;
}
platform_set_drvdata(pdev, wdt);
return 0;
-err:
- clk_disable_unprepare(wdt->clk_lsi);
- clk_disable_unprepare(wdt->clk_pclk);
-
- return ret;
-}
-
-static int stm32_iwdg_remove(struct platform_device *pdev)
-{
- struct stm32_iwdg *wdt = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&wdt->wdd);
- clk_disable_unprepare(wdt->clk_lsi);
- clk_disable_unprepare(wdt->clk_pclk);
-
- return 0;
}
static struct platform_driver stm32_iwdg_driver = {
.probe = stm32_iwdg_probe,
- .remove = stm32_iwdg_remove,
.driver = {
.name = "iwdg",
.of_match_table = of_match_ptr(stm32_iwdg_of_match),
diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c
index 994c54cc68e9..671f4ba7b4ed 100644
--- a/drivers/watchdog/stmp3xxx_rtc_wdt.c
+++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c
@@ -89,31 +89,31 @@ static struct notifier_block wdt_notifier = {
static int stmp3xxx_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int ret;
- watchdog_set_drvdata(&stmp3xxx_wdd, &pdev->dev);
+ watchdog_set_drvdata(&stmp3xxx_wdd, dev);
stmp3xxx_wdd.timeout = clamp_t(unsigned, heartbeat, 1, STMP3XXX_MAX_TIMEOUT);
- stmp3xxx_wdd.parent = &pdev->dev;
+ stmp3xxx_wdd.parent = dev;
- ret = watchdog_register_device(&stmp3xxx_wdd);
+ ret = devm_watchdog_register_device(dev, &stmp3xxx_wdd);
if (ret < 0) {
- dev_err(&pdev->dev, "cannot register watchdog device\n");
+ dev_err(dev, "cannot register watchdog device\n");
return ret;
}
if (register_reboot_notifier(&wdt_notifier))
- dev_warn(&pdev->dev, "cannot register reboot notifier\n");
+ dev_warn(dev, "cannot register reboot notifier\n");
- dev_info(&pdev->dev, "initialized watchdog with heartbeat %ds\n",
- stmp3xxx_wdd.timeout);
+ dev_info(dev, "initialized watchdog with heartbeat %ds\n",
+ stmp3xxx_wdd.timeout);
return 0;
}
static int stmp3xxx_wdt_remove(struct platform_device *pdev)
{
unregister_reboot_notifier(&wdt_notifier);
- watchdog_unregister_device(&stmp3xxx_wdd);
return 0;
}
diff --git a/drivers/watchdog/stpmic1_wdt.c b/drivers/watchdog/stpmic1_wdt.c
index ad431d8ad95f..45d0c543466f 100644
--- a/drivers/watchdog/stpmic1_wdt.c
+++ b/drivers/watchdog/stpmic1_wdt.c
@@ -81,18 +81,19 @@ static const struct watchdog_ops pmic_watchdog_ops = {
static int pmic_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int ret;
struct stpmic1 *pmic;
struct stpmic1_wdt *wdt;
- if (!pdev->dev.parent)
+ if (!dev->parent)
return -EINVAL;
- pmic = dev_get_drvdata(pdev->dev.parent);
+ pmic = dev_get_drvdata(dev->parent);
if (!pmic)
return -EINVAL;
- wdt = devm_kzalloc(&pdev->dev, sizeof(struct stpmic1_wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(struct stpmic1_wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -102,15 +103,15 @@ static int pmic_wdt_probe(struct platform_device *pdev)
wdt->wdtdev.ops = &pmic_watchdog_ops;
wdt->wdtdev.min_timeout = PMIC_WDT_MIN_TIMEOUT;
wdt->wdtdev.max_timeout = PMIC_WDT_MAX_TIMEOUT;
- wdt->wdtdev.parent = &pdev->dev;
+ wdt->wdtdev.parent = dev;
wdt->wdtdev.timeout = PMIC_WDT_DEFAULT_TIMEOUT;
- watchdog_init_timeout(&wdt->wdtdev, 0, &pdev->dev);
+ watchdog_init_timeout(&wdt->wdtdev, 0, dev);
watchdog_set_nowayout(&wdt->wdtdev, nowayout);
watchdog_set_drvdata(&wdt->wdtdev, wdt);
- ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev);
+ ret = devm_watchdog_register_device(dev, &wdt->wdtdev);
if (ret)
return ret;
diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c
index c6c73656997e..9c22f7753c6b 100644
--- a/drivers/watchdog/sunxi_wdt.c
+++ b/drivers/watchdog/sunxi_wdt.c
@@ -233,20 +233,19 @@ MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids);
static int sunxi_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct sunxi_wdt_dev *sunxi_wdt;
- struct resource *res;
int err;
- sunxi_wdt = devm_kzalloc(&pdev->dev, sizeof(*sunxi_wdt), GFP_KERNEL);
+ sunxi_wdt = devm_kzalloc(dev, sizeof(*sunxi_wdt), GFP_KERNEL);
if (!sunxi_wdt)
return -EINVAL;
- sunxi_wdt->wdt_regs = of_device_get_match_data(&pdev->dev);
+ sunxi_wdt->wdt_regs = of_device_get_match_data(dev);
if (!sunxi_wdt->wdt_regs)
return -ENODEV;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- sunxi_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
+ sunxi_wdt->wdt_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(sunxi_wdt->wdt_base))
return PTR_ERR(sunxi_wdt->wdt_base);
@@ -255,9 +254,9 @@ static int sunxi_wdt_probe(struct platform_device *pdev)
sunxi_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT;
sunxi_wdt->wdt_dev.max_timeout = WDT_MAX_TIMEOUT;
sunxi_wdt->wdt_dev.min_timeout = WDT_MIN_TIMEOUT;
- sunxi_wdt->wdt_dev.parent = &pdev->dev;
+ sunxi_wdt->wdt_dev.parent = dev;
- watchdog_init_timeout(&sunxi_wdt->wdt_dev, timeout, &pdev->dev);
+ watchdog_init_timeout(&sunxi_wdt->wdt_dev, timeout, dev);
watchdog_set_nowayout(&sunxi_wdt->wdt_dev, nowayout);
watchdog_set_restart_priority(&sunxi_wdt->wdt_dev, 128);
@@ -266,12 +265,12 @@ static int sunxi_wdt_probe(struct platform_device *pdev)
sunxi_wdt_stop(&sunxi_wdt->wdt_dev);
watchdog_stop_on_reboot(&sunxi_wdt->wdt_dev);
- err = devm_watchdog_register_device(&pdev->dev, &sunxi_wdt->wdt_dev);
+ err = devm_watchdog_register_device(dev, &sunxi_wdt->wdt_dev);
if (unlikely(err))
return err;
- dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)",
- sunxi_wdt->wdt_dev.timeout, nowayout);
+ dev_info(dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)",
+ sunxi_wdt->wdt_dev.timeout, nowayout);
return 0;
}
diff --git a/drivers/watchdog/tangox_wdt.c b/drivers/watchdog/tangox_wdt.c
index d0b53f3c0d17..1afb0e9d808c 100644
--- a/drivers/watchdog/tangox_wdt.c
+++ b/drivers/watchdog/tangox_wdt.c
@@ -108,10 +108,14 @@ static const struct watchdog_ops tangox_wdt_ops = {
.restart = tangox_wdt_restart,
};
+static void tangox_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int tangox_wdt_probe(struct platform_device *pdev)
{
struct tangox_wdt_device *dev;
- struct resource *res;
u32 config;
int err;
@@ -119,8 +123,7 @@ static int tangox_wdt_probe(struct platform_device *pdev)
if (!dev)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dev->base = devm_ioremap_resource(&pdev->dev, res);
+ dev->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dev->base))
return PTR_ERR(dev->base);
@@ -131,12 +134,14 @@ static int tangox_wdt_probe(struct platform_device *pdev)
err = clk_prepare_enable(dev->clk);
if (err)
return err;
+ err = devm_add_action_or_reset(&pdev->dev,
+ tangox_clk_disable_unprepare, dev->clk);
+ if (err)
+ return err;
dev->clk_rate = clk_get_rate(dev->clk);
- if (!dev->clk_rate) {
- err = -EINVAL;
- goto err;
- }
+ if (!dev->clk_rate)
+ return -EINVAL;
dev->wdt.parent = &pdev->dev;
dev->wdt.info = &tangox_wdt_info;
@@ -170,31 +175,16 @@ static int tangox_wdt_probe(struct platform_device *pdev)
watchdog_set_restart_priority(&dev->wdt, 128);
- err = watchdog_register_device(&dev->wdt);
+ watchdog_stop_on_unregister(&dev->wdt);
+ err = devm_watchdog_register_device(&pdev->dev, &dev->wdt);
if (err)
- goto err;
+ return err;
platform_set_drvdata(pdev, dev);
dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n");
return 0;
-
- err:
- clk_disable_unprepare(dev->clk);
- return err;
-}
-
-static int tangox_wdt_remove(struct platform_device *pdev)
-{
- struct tangox_wdt_device *dev = platform_get_drvdata(pdev);
-
- tangox_wdt_stop(&dev->wdt);
- clk_disable_unprepare(dev->clk);
-
- watchdog_unregister_device(&dev->wdt);
-
- return 0;
}
static const struct of_device_id tangox_wdt_dt_ids[] = {
@@ -206,7 +196,6 @@ MODULE_DEVICE_TABLE(of, tangox_wdt_dt_ids);
static struct platform_driver tangox_wdt_driver = {
.probe = tangox_wdt_probe,
- .remove = tangox_wdt_remove,
.driver = {
.name = "tangox-wdt",
.of_match_table = tangox_wdt_dt_ids,
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c
index 877dd39bd41f..a58b000acc4f 100644
--- a/drivers/watchdog/tegra_wdt.c
+++ b/drivers/watchdog/tegra_wdt.c
@@ -181,15 +181,14 @@ static const struct watchdog_ops tegra_wdt_ops = {
static int tegra_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct watchdog_device *wdd;
struct tegra_wdt *wdt;
- struct resource *res;
void __iomem *regs;
int ret;
/* This is the timer base. */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- regs = devm_ioremap_resource(&pdev->dev, res);
+ regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs))
return PTR_ERR(regs);
@@ -197,7 +196,7 @@ static int tegra_wdt_probe(struct platform_device *pdev)
* Allocate our watchdog driver data, which has the
* struct watchdog_device nested within it.
*/
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -212,39 +211,27 @@ static int tegra_wdt_probe(struct platform_device *pdev)
wdd->ops = &tegra_wdt_ops;
wdd->min_timeout = MIN_WDT_TIMEOUT;
wdd->max_timeout = MAX_WDT_TIMEOUT;
- wdd->parent = &pdev->dev;
+ wdd->parent = dev;
watchdog_set_drvdata(wdd, wdt);
watchdog_set_nowayout(wdd, nowayout);
- ret = devm_watchdog_register_device(&pdev->dev, wdd);
+ watchdog_stop_on_unregister(wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
- dev_err(&pdev->dev,
- "failed to register watchdog device\n");
+ dev_err(dev, "failed to register watchdog device\n");
return ret;
}
platform_set_drvdata(pdev, wdt);
- dev_info(&pdev->dev,
- "initialized (heartbeat = %d sec, nowayout = %d)\n",
+ dev_info(dev, "initialized (heartbeat = %d sec, nowayout = %d)\n",
heartbeat, nowayout);
return 0;
}
-static int tegra_wdt_remove(struct platform_device *pdev)
-{
- struct tegra_wdt *wdt = platform_get_drvdata(pdev);
-
- tegra_wdt_stop(&wdt->wdd);
-
- dev_info(&pdev->dev, "removed wdt\n");
-
- return 0;
-}
-
#ifdef CONFIG_PM_SLEEP
static int tegra_wdt_runtime_suspend(struct device *dev)
{
@@ -280,7 +267,6 @@ static const struct dev_pm_ops tegra_wdt_pm_ops = {
static struct platform_driver tegra_wdt_driver = {
.probe = tegra_wdt_probe,
- .remove = tegra_wdt_remove,
.driver = {
.name = "tegra-wdt",
.pm = &tegra_wdt_pm_ops,
diff --git a/drivers/watchdog/tqmx86_wdt.c b/drivers/watchdog/tqmx86_wdt.c
index 52941207a12a..72d0b0adde38 100644
--- a/drivers/watchdog/tqmx86_wdt.c
+++ b/drivers/watchdog/tqmx86_wdt.c
@@ -70,11 +70,12 @@ static struct watchdog_ops tqmx86_wdt_ops = {
static int tqmx86_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct tqmx86_wdt *priv;
struct resource *res;
int err;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -82,14 +83,13 @@ static int tqmx86_wdt_probe(struct platform_device *pdev)
if (!res)
return -ENODEV;
- priv->io_base = devm_ioport_map(&pdev->dev, res->start,
- resource_size(res));
+ priv->io_base = devm_ioport_map(dev, res->start, resource_size(res));
if (!priv->io_base)
return -ENOMEM;
watchdog_set_drvdata(&priv->wdd, priv);
- priv->wdd.parent = &pdev->dev;
+ priv->wdd.parent = dev;
priv->wdd.info = &tqmx86_wdt_info;
priv->wdd.ops = &tqmx86_wdt_ops;
priv->wdd.min_timeout = 1;
@@ -97,16 +97,16 @@ static int tqmx86_wdt_probe(struct platform_device *pdev)
priv->wdd.max_hw_heartbeat_ms = 4096*1000;
priv->wdd.timeout = WDT_TIMEOUT;
- watchdog_init_timeout(&priv->wdd, timeout, &pdev->dev);
+ watchdog_init_timeout(&priv->wdd, timeout, dev);
watchdog_set_nowayout(&priv->wdd, WATCHDOG_NOWAYOUT);
tqmx86_wdt_set_timeout(&priv->wdd, priv->wdd.timeout);
- err = devm_watchdog_register_device(&pdev->dev, &priv->wdd);
+ err = devm_watchdog_register_device(dev, &priv->wdd);
if (err)
return err;
- dev_info(&pdev->dev, "TQMx86 watchdog\n");
+ dev_info(dev, "TQMx86 watchdog\n");
return 0;
}
diff --git a/drivers/watchdog/ts4800_wdt.c b/drivers/watchdog/ts4800_wdt.c
index 89843b16b04a..9dc6d7f45806 100644
--- a/drivers/watchdog/ts4800_wdt.c
+++ b/drivers/watchdog/ts4800_wdt.c
@@ -108,7 +108,8 @@ static const struct watchdog_info ts4800_wdt_info = {
static int ts4800_wdt_probe(struct platform_device *pdev)
{
- struct device_node *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
struct device_node *syscon_np;
struct watchdog_device *wdd;
struct ts4800_wdt *wdt;
@@ -117,18 +118,18 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
syscon_np = of_parse_phandle(np, "syscon", 0);
if (!syscon_np) {
- dev_err(&pdev->dev, "no syscon property\n");
+ dev_err(dev, "no syscon property\n");
return -ENODEV;
}
ret = of_property_read_u32_index(np, "syscon", 1, &reg);
if (ret < 0) {
- dev_err(&pdev->dev, "no offset in syscon\n");
+ dev_err(dev, "no offset in syscon\n");
return ret;
}
/* allocate memory for watchdog struct */
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -137,13 +138,13 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
wdt->regmap = syscon_node_to_regmap(syscon_np);
of_node_put(syscon_np);
if (IS_ERR(wdt->regmap)) {
- dev_err(&pdev->dev, "cannot get parent's regmap\n");
+ dev_err(dev, "cannot get parent's regmap\n");
return PTR_ERR(wdt->regmap);
}
/* Initialize struct watchdog_device */
wdd = &wdt->wdd;
- wdd->parent = &pdev->dev;
+ wdd->parent = dev;
wdd->info = &ts4800_wdt_info;
wdd->ops = &ts4800_wdt_ops;
wdd->min_timeout = ts4800_wdt_map[0].timeout;
@@ -151,7 +152,7 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdd, wdt);
watchdog_set_nowayout(wdd, nowayout);
- watchdog_init_timeout(wdd, 0, &pdev->dev);
+ watchdog_init_timeout(wdd, 0, dev);
/*
* As this watchdog supports only a few values, ts4800_wdt_set_timeout
@@ -169,31 +170,20 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
*/
ts4800_wdt_stop(wdd);
- ret = watchdog_register_device(wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
- dev_err(&pdev->dev,
- "failed to register watchdog device\n");
+ dev_err(dev, "failed to register watchdog device\n");
return ret;
}
platform_set_drvdata(pdev, wdt);
- dev_info(&pdev->dev,
- "initialized (timeout = %d sec, nowayout = %d)\n",
+ dev_info(dev, "initialized (timeout = %d sec, nowayout = %d)\n",
wdd->timeout, nowayout);
return 0;
}
-static int ts4800_wdt_remove(struct platform_device *pdev)
-{
- struct ts4800_wdt *wdt = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&wdt->wdd);
-
- return 0;
-}
-
static const struct of_device_id ts4800_wdt_of_match[] = {
{ .compatible = "technologic,ts4800-wdt", },
{ },
@@ -202,7 +192,6 @@ MODULE_DEVICE_TABLE(of, ts4800_wdt_of_match);
static struct platform_driver ts4800_wdt_driver = {
.probe = ts4800_wdt_probe,
- .remove = ts4800_wdt_remove,
.driver = {
.name = "ts4800_wdt",
.of_match_table = ts4800_wdt_of_match,
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c
index 811e43c39ec4..bf918f5fa131 100644
--- a/drivers/watchdog/ts72xx_wdt.c
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -122,22 +122,20 @@ static const struct watchdog_ops ts72xx_wdt_ops = {
static int ts72xx_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct ts72xx_wdt_priv *priv;
struct watchdog_device *wdd;
- struct resource *res;
int ret;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->control_reg = devm_ioremap_resource(&pdev->dev, res);
+ priv->control_reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->control_reg))
return PTR_ERR(priv->control_reg);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- priv->feed_reg = devm_ioremap_resource(&pdev->dev, res);
+ priv->feed_reg = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(priv->feed_reg))
return PTR_ERR(priv->feed_reg);
@@ -146,20 +144,20 @@ static int ts72xx_wdt_probe(struct platform_device *pdev)
wdd->ops = &ts72xx_wdt_ops;
wdd->min_timeout = 1;
wdd->max_hw_heartbeat_ms = 8000;
- wdd->parent = &pdev->dev;
+ wdd->parent = dev;
watchdog_set_nowayout(wdd, nowayout);
wdd->timeout = TS72XX_WDT_DEFAULT_TIMEOUT;
- watchdog_init_timeout(wdd, timeout, &pdev->dev);
+ watchdog_init_timeout(wdd, timeout, dev);
watchdog_set_drvdata(wdd, priv);
- ret = devm_watchdog_register_device(&pdev->dev, wdd);
+ ret = devm_watchdog_register_device(dev, wdd);
if (ret)
return ret;
- dev_info(&pdev->dev, "TS-72xx Watchdog driver\n");
+ dev_info(dev, "TS-72xx Watchdog driver\n");
return 0;
}
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index 569fe85e52da..74c5737cd934 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -70,10 +70,10 @@ static const struct watchdog_ops twl4030_wdt_ops = {
static int twl4030_wdt_probe(struct platform_device *pdev)
{
- int ret = 0;
+ struct device *dev = &pdev->dev;
struct watchdog_device *wdt;
- wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -83,27 +83,14 @@ static int twl4030_wdt_probe(struct platform_device *pdev)
wdt->timeout = 30;
wdt->min_timeout = 1;
wdt->max_timeout = 30;
- wdt->parent = &pdev->dev;
+ wdt->parent = dev;
watchdog_set_nowayout(wdt, nowayout);
platform_set_drvdata(pdev, wdt);
twl4030_wdt_stop(wdt);
- ret = watchdog_register_device(wdt);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int twl4030_wdt_remove(struct platform_device *pdev)
-{
- struct watchdog_device *wdt = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(wdt);
-
- return 0;
+ return devm_watchdog_register_device(dev, wdt);
}
#ifdef CONFIG_PM
@@ -137,7 +124,6 @@ MODULE_DEVICE_TABLE(of, twl_wdt_of_match);
static struct platform_driver twl4030_wdt_driver = {
.probe = twl4030_wdt_probe,
- .remove = twl4030_wdt_remove,
.suspend = twl4030_wdt_suspend,
.resume = twl4030_wdt_resume,
.driver = {
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index 6f7a9deb27d0..fcb4da5b1f4c 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -103,7 +103,6 @@ static struct watchdog_device txx9wdt = {
static int __init txx9wdt_probe(struct platform_device *dev)
{
- struct resource *res;
int ret;
txx9_imclk = clk_get(NULL, "imbus_clk");
@@ -119,8 +118,7 @@ static int __init txx9wdt_probe(struct platform_device *dev)
goto exit;
}
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- txx9wdt_reg = devm_ioremap_resource(&dev->dev, res);
+ txx9wdt_reg = devm_platform_ioremap_resource(dev, 0);
if (IS_ERR(txx9wdt_reg)) {
ret = PTR_ERR(txx9wdt_reg);
goto exit;
diff --git a/drivers/watchdog/uniphier_wdt.c b/drivers/watchdog/uniphier_wdt.c
index e20a7a459d69..8e9242c23022 100644
--- a/drivers/watchdog/uniphier_wdt.c
+++ b/drivers/watchdog/uniphier_wdt.c
@@ -191,8 +191,6 @@ static int uniphier_wdt_probe(struct platform_device *pdev)
if (!wdev)
return -ENOMEM;
- platform_set_drvdata(pdev, wdev);
-
parent = of_get_parent(dev->of_node); /* parent should be syscon node */
regmap = syscon_node_to_regmap(parent);
of_node_put(parent);
diff --git a/drivers/watchdog/ux500_wdt.c b/drivers/watchdog/ux500_wdt.c
index 37c084353cce..9fa7f95f7554 100644
--- a/drivers/watchdog/ux500_wdt.c
+++ b/drivers/watchdog/ux500_wdt.c
@@ -86,8 +86,9 @@ static struct watchdog_device ux500_wdt = {
static int ux500_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int ret;
- struct ux500_wdt_data *pdata = dev_get_platdata(&pdev->dev);
+ struct ux500_wdt_data *pdata = dev_get_platdata(dev);
if (pdata) {
if (pdata->timeout > 0)
@@ -96,7 +97,7 @@ static int ux500_wdt_probe(struct platform_device *pdev)
ux500_wdt.max_timeout = WATCHDOG_MAX28;
}
- ux500_wdt.parent = &pdev->dev;
+ ux500_wdt.parent = dev;
watchdog_set_nowayout(&ux500_wdt, nowayout);
/* disable auto off on sleep */
@@ -105,18 +106,11 @@ static int ux500_wdt_probe(struct platform_device *pdev)
/* set HW initial value */
prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
- ret = watchdog_register_device(&ux500_wdt);
+ ret = devm_watchdog_register_device(dev, &ux500_wdt);
if (ret)
return ret;
- dev_info(&pdev->dev, "initialized\n");
-
- return 0;
-}
-
-static int ux500_wdt_remove(struct platform_device *dev)
-{
- watchdog_unregister_device(&ux500_wdt);
+ dev_info(dev, "initialized\n");
return 0;
}
@@ -153,7 +147,6 @@ static int ux500_wdt_resume(struct platform_device *pdev)
static struct platform_driver ux500_wdt_driver = {
.probe = ux500_wdt_probe,
- .remove = ux500_wdt_remove,
.suspend = ux500_wdt_suspend,
.resume = ux500_wdt_resume,
.driver = {
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
index eb8fa25f8eb2..62be9e52a4de 100644
--- a/drivers/watchdog/watchdog_core.c
+++ b/drivers/watchdog/watchdog_core.c
@@ -105,34 +105,48 @@ static void watchdog_check_min_max_timeout(struct watchdog_device *wdd)
* timeout module parameter (if it is valid value) or the timeout-sec property
* (only if it is a valid value and the timeout_parm is out of bounds).
* If none of them are valid then we keep the old value (which should normally
- * be the default timeout value).
+ * be the default timeout value). Note that for the module parameter, '0' means
+ * 'use default' while it is an invalid value for the timeout-sec property.
+ * It should simply be dropped if you want to use the default value then.
*
- * A zero is returned on success and -EINVAL for failure.
+ * A zero is returned on success or -EINVAL if all provided values are out of
+ * bounds.
*/
int watchdog_init_timeout(struct watchdog_device *wdd,
unsigned int timeout_parm, struct device *dev)
{
+ const char *dev_str = wdd->parent ? dev_name(wdd->parent) :
+ (const char *)wdd->info->identity;
unsigned int t = 0;
int ret = 0;
watchdog_check_min_max_timeout(wdd);
- /* try to get the timeout module parameter first */
- if (!watchdog_timeout_invalid(wdd, timeout_parm) && timeout_parm) {
- wdd->timeout = timeout_parm;
- return ret;
- }
- if (timeout_parm)
+ /* check the driver supplied value (likely a module parameter) first */
+ if (timeout_parm) {
+ if (!watchdog_timeout_invalid(wdd, timeout_parm)) {
+ wdd->timeout = timeout_parm;
+ return 0;
+ }
+ pr_err("%s: driver supplied timeout (%u) out of range\n",
+ dev_str, timeout_parm);
ret = -EINVAL;
+ }
/* try to get the timeout_sec property */
- if (dev == NULL || dev->of_node == NULL)
- return ret;
- of_property_read_u32(dev->of_node, "timeout-sec", &t);
- if (!watchdog_timeout_invalid(wdd, t) && t)
- wdd->timeout = t;
- else
+ if (dev && dev->of_node &&
+ of_property_read_u32(dev->of_node, "timeout-sec", &t) == 0) {
+ if (t && !watchdog_timeout_invalid(wdd, t)) {
+ wdd->timeout = t;
+ return 0;
+ }
+ pr_err("%s: DT supplied timeout (%u) out of range\n", dev_str, t);
ret = -EINVAL;
+ }
+
+ if (ret < 0 && wdd->timeout)
+ pr_warn("%s: falling back to default timeout (%u)\n", dev_str,
+ wdd->timeout);
return ret;
}
diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c
index 56ad19608a9b..430ee4e9b185 100644
--- a/drivers/watchdog/wdat_wdt.c
+++ b/drivers/watchdog/wdat_wdt.c
@@ -287,7 +287,7 @@ static unsigned int wdat_wdt_get_timeleft(struct watchdog_device *wdd)
struct wdat_wdt *wdat = to_wdat_wdt(wdd);
u32 periods = 0;
- wdat_wdt_run_action(wdat, ACPI_WDAT_GET_COUNTDOWN, 0, &periods);
+ wdat_wdt_run_action(wdat, ACPI_WDAT_GET_CURRENT_COUNTDOWN, 0, &periods);
return periods * wdat->period / 1000;
}
@@ -308,6 +308,7 @@ static const struct watchdog_ops wdat_wdt_ops = {
static int wdat_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
const struct acpi_wdat_entry *entries;
const struct acpi_table_wdat *tbl;
struct wdat_wdt *wdat;
@@ -321,11 +322,11 @@ static int wdat_wdt_probe(struct platform_device *pdev)
if (ACPI_FAILURE(status))
return -ENODEV;
- wdat = devm_kzalloc(&pdev->dev, sizeof(*wdat), GFP_KERNEL);
+ wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL);
if (!wdat)
return -ENOMEM;
- regs = devm_kcalloc(&pdev->dev, pdev->num_resources, sizeof(*regs),
+ regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs),
GFP_KERNEL);
if (!regs)
return -ENOMEM;
@@ -350,15 +351,15 @@ static int wdat_wdt_probe(struct platform_device *pdev)
res = &pdev->resource[i];
if (resource_type(res) == IORESOURCE_MEM) {
- reg = devm_ioremap_resource(&pdev->dev, res);
+ reg = devm_ioremap_resource(dev, res);
if (IS_ERR(reg))
return PTR_ERR(reg);
} else if (resource_type(res) == IORESOURCE_IO) {
- reg = devm_ioport_map(&pdev->dev, res->start, 1);
+ reg = devm_ioport_map(dev, res->start, 1);
if (!reg)
return -ENOMEM;
} else {
- dev_err(&pdev->dev, "Unsupported resource\n");
+ dev_err(dev, "Unsupported resource\n");
return -EINVAL;
}
@@ -376,12 +377,11 @@ static int wdat_wdt_probe(struct platform_device *pdev)
action = entries[i].action;
if (action >= MAX_WDAT_ACTIONS) {
- dev_dbg(&pdev->dev, "Skipping unknown action: %u\n",
- action);
+ dev_dbg(dev, "Skipping unknown action: %u\n", action);
continue;
}
- instr = devm_kzalloc(&pdev->dev, sizeof(*instr), GFP_KERNEL);
+ instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL);
if (!instr)
return -ENOMEM;
@@ -398,7 +398,7 @@ static int wdat_wdt_probe(struct platform_device *pdev)
} else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
r.flags = IORESOURCE_IO;
} else {
- dev_dbg(&pdev->dev, "Unsupported address space: %d\n",
+ dev_dbg(dev, "Unsupported address space: %d\n",
gas->space_id);
continue;
}
@@ -413,14 +413,15 @@ static int wdat_wdt_probe(struct platform_device *pdev)
}
if (!instr->reg) {
- dev_err(&pdev->dev, "I/O resource not found\n");
+ dev_err(dev, "I/O resource not found\n");
return -EINVAL;
}
instructions = wdat->instructions[action];
if (!instructions) {
- instructions = devm_kzalloc(&pdev->dev,
- sizeof(*instructions), GFP_KERNEL);
+ instructions = devm_kzalloc(dev,
+ sizeof(*instructions),
+ GFP_KERNEL);
if (!instructions)
return -ENOMEM;
@@ -441,7 +442,7 @@ static int wdat_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdat);
watchdog_set_nowayout(&wdat->wdd, nowayout);
- return devm_watchdog_register_device(&pdev->dev, &wdat->wdd);
+ return devm_watchdog_register_device(dev, &wdat->wdd);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 116c2f47b463..9b6565a3fab4 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -180,8 +180,9 @@ static const struct watchdog_ops wm831x_wdt_ops = {
static int wm831x_wdt_probe(struct platform_device *pdev)
{
- struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
- struct wm831x_pdata *chip_pdata = dev_get_platdata(pdev->dev.parent);
+ struct device *dev = &pdev->dev;
+ struct wm831x *wm831x = dev_get_drvdata(dev->parent);
+ struct wm831x_pdata *chip_pdata = dev_get_platdata(dev->parent);
struct wm831x_watchdog_pdata *pdata;
struct wm831x_wdt_drvdata *driver_data;
struct watchdog_device *wm831x_wdt;
@@ -198,8 +199,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
if (reg & WM831X_WDOG_DEBUG)
dev_warn(wm831x->dev, "Watchdog is paused\n");
- driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data),
- GFP_KERNEL);
+ driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
if (!driver_data)
return -ENOMEM;
@@ -210,7 +210,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
wm831x_wdt->info = &wm831x_wdt_info;
wm831x_wdt->ops = &wm831x_wdt_ops;
- wm831x_wdt->parent = &pdev->dev;
+ wm831x_wdt->parent = dev;
watchdog_set_nowayout(wm831x_wdt, nowayout);
watchdog_set_drvdata(wm831x_wdt, driver_data);
@@ -240,10 +240,9 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT;
if (pdata->update_gpio) {
- ret = devm_gpio_request_one(&pdev->dev,
- pdata->update_gpio,
- GPIOF_OUT_INIT_LOW,
- "Watchdog update");
+ ret = devm_gpio_request_one(dev, pdata->update_gpio,
+ GPIOF_OUT_INIT_LOW,
+ "Watchdog update");
if (ret < 0) {
dev_err(wm831x->dev,
"Failed to request update GPIO: %d\n",
@@ -268,7 +267,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
}
}
- ret = devm_watchdog_register_device(&pdev->dev, &driver_data->wdt);
+ ret = devm_watchdog_register_device(dev, &driver_data->wdt);
if (ret != 0) {
dev_err(wm831x->dev, "watchdog_register_device() failed: %d\n",
ret);
diff --git a/drivers/watchdog/xen_wdt.c b/drivers/watchdog/xen_wdt.c
index f1c016d015b3..25a1af5e1787 100644
--- a/drivers/watchdog/xen_wdt.c
+++ b/drivers/watchdog/xen_wdt.c
@@ -122,35 +122,33 @@ static struct watchdog_device xen_wdt_dev = {
static int xen_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct sched_watchdog wd = { .id = ~0 };
int ret = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wd);
if (ret == -ENOSYS) {
- dev_err(&pdev->dev, "watchdog not supported by hypervisor\n");
+ dev_err(dev, "watchdog not supported by hypervisor\n");
return -ENODEV;
}
if (ret != -EINVAL) {
- dev_err(&pdev->dev, "unexpected hypervisor error (%d)\n", ret);
+ dev_err(dev, "unexpected hypervisor error (%d)\n", ret);
return -ENODEV;
}
- if (watchdog_init_timeout(&xen_wdt_dev, timeout, NULL))
- dev_info(&pdev->dev, "timeout value invalid, using %d\n",
- xen_wdt_dev.timeout);
+ watchdog_init_timeout(&xen_wdt_dev, timeout, NULL);
watchdog_set_nowayout(&xen_wdt_dev, nowayout);
watchdog_stop_on_reboot(&xen_wdt_dev);
watchdog_stop_on_unregister(&xen_wdt_dev);
- ret = devm_watchdog_register_device(&pdev->dev, &xen_wdt_dev);
+ ret = devm_watchdog_register_device(dev, &xen_wdt_dev);
if (ret) {
- dev_err(&pdev->dev, "cannot register watchdog device (%d)\n",
- ret);
+ dev_err(dev, "cannot register watchdog device (%d)\n", ret);
return ret;
}
- dev_info(&pdev->dev, "initialized (timeout=%ds, nowayout=%d)\n",
- xen_wdt_dev.timeout, nowayout);
+ dev_info(dev, "initialized (timeout=%ds, nowayout=%d)\n",
+ xen_wdt_dev.timeout, nowayout);
return 0;
}
diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c
index d3594aa3a374..43e6b575c32c 100644
--- a/drivers/watchdog/ziirave_wdt.c
+++ b/drivers/watchdog/ziirave_wdt.c
@@ -658,11 +658,7 @@ static int ziirave_wdt_probe(struct i2c_client *client,
w_priv->wdd.parent = &client->dev;
w_priv->wdd.groups = ziirave_wdt_groups;
- ret = watchdog_init_timeout(&w_priv->wdd, wdt_timeout, &client->dev);
- if (ret) {
- dev_info(&client->dev,
- "Unable to select timeout value, using default\n");
- }
+ watchdog_init_timeout(&w_priv->wdd, wdt_timeout, &client->dev);
/*
* The default value set in the watchdog should be perfectly valid, so
diff --git a/drivers/watchdog/zx2967_wdt.c b/drivers/watchdog/zx2967_wdt.c
index 9261f7c77f6d..c8549bf07cc9 100644
--- a/drivers/watchdog/zx2967_wdt.c
+++ b/drivers/watchdog/zx2967_wdt.c
@@ -188,11 +188,15 @@ static void zx2967_wdt_reset_sysctrl(struct device *dev)
of_node_put(out_args.np);
}
+static void zx2967_clk_disable_unprepare(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
static int zx2967_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct zx2967_wdt *wdt;
- struct resource *base;
int ret;
struct reset_control *rstc;
@@ -207,10 +211,9 @@ static int zx2967_wdt_probe(struct platform_device *pdev)
wdt->wdt_device.timeout = ZX2967_WDT_DEFAULT_TIMEOUT;
wdt->wdt_device.max_timeout = ZX2967_WDT_MAX_TIMEOUT;
wdt->wdt_device.min_timeout = ZX2967_WDT_MIN_TIMEOUT;
- wdt->wdt_device.parent = &pdev->dev;
+ wdt->wdt_device.parent = dev;
- base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- wdt->reg_base = devm_ioremap_resource(dev, base);
+ wdt->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->reg_base))
return PTR_ERR(wdt->reg_base);
@@ -227,13 +230,16 @@ static int zx2967_wdt_probe(struct platform_device *pdev)
dev_err(dev, "failed to enable clock\n");
return ret;
}
+ ret = devm_add_action_or_reset(dev, zx2967_clk_disable_unprepare,
+ wdt->clock);
+ if (ret)
+ return ret;
clk_set_rate(wdt->clock, ZX2967_WDT_CLK_FREQ);
rstc = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(rstc)) {
dev_err(dev, "failed to get rstc");
- ret = PTR_ERR(rstc);
- goto err;
+ return PTR_ERR(rstc);
}
reset_control_assert(rstc);
@@ -244,28 +250,14 @@ static int zx2967_wdt_probe(struct platform_device *pdev)
ZX2967_WDT_DEFAULT_TIMEOUT, dev);
watchdog_set_nowayout(&wdt->wdt_device, WATCHDOG_NOWAYOUT);
- ret = watchdog_register_device(&wdt->wdt_device);
+ ret = devm_watchdog_register_device(dev, &wdt->wdt_device);
if (ret)
- goto err;
+ return ret;
dev_info(dev, "watchdog enabled (timeout=%d sec, nowayout=%d)",
wdt->wdt_device.timeout, WATCHDOG_NOWAYOUT);
return 0;
-
-err:
- clk_disable_unprepare(wdt->clock);
- return ret;
-}
-
-static int zx2967_wdt_remove(struct platform_device *pdev)
-{
- struct zx2967_wdt *wdt = platform_get_drvdata(pdev);
-
- watchdog_unregister_device(&wdt->wdt_device);
- clk_disable_unprepare(wdt->clock);
-
- return 0;
}
static const struct of_device_id zx2967_wdt_match[] = {
@@ -276,7 +268,6 @@ MODULE_DEVICE_TABLE(of, zx2967_wdt_match);
static struct platform_driver zx2967_wdt_driver = {
.probe = zx2967_wdt_probe,
- .remove = zx2967_wdt_remove,
.driver = {
.name = "zx2967-wdt",
.of_match_table = of_match_ptr(zx2967_wdt_match),