Commit 55472bae authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents d7a02fa0 a9f0bda5
* Freescale i.MX System Controller Watchdog
i.MX system controller watchdog is for i.MX SoCs with system controller inside,
the watchdog is managed by system controller, users can ONLY communicate with
system controller from secure mode for watchdog operations, so Linux i.MX system
controller watchdog driver will call ARM SMC API and trap into ARM-Trusted-Firmware
for watchdog operations, ARM-Trusted-Firmware is running at secure EL3 mode and
it will request system controller to execute the watchdog operation passed from
Linux kernel.
Required properties:
- compatible: Should be :
"fsl,imx8qxp-sc-wdt"
followed by "fsl,imx-sc-wdt";
Optional properties:
- timeout-sec : Contains the watchdog timeout in seconds.
Examples:
watchdog {
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
timeout-sec = <60>;
};
...@@ -9,6 +9,7 @@ Required properties: ...@@ -9,6 +9,7 @@ Required properties:
"mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622 "mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622
"mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623 "mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623
"mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629 "mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
"mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
- reg : Specifies base physical address and size of the registers. - reg : Specifies base physical address and size of the registers.
......
...@@ -30,7 +30,7 @@ menuconfig WATCHDOG ...@@ -30,7 +30,7 @@ menuconfig WATCHDOG
if WATCHDOG if WATCHDOG
config WATCHDOG_CORE config WATCHDOG_CORE
bool "WatchDog Timer Driver Core" tristate "WatchDog Timer Driver Core"
---help--- ---help---
Say Y here if you want to use the new watchdog timer driver core. Say Y here if you want to use the new watchdog timer driver core.
This driver provides a framework for all watchdog timer drivers This driver provides a framework for all watchdog timer drivers
...@@ -63,6 +63,66 @@ config WATCHDOG_SYSFS ...@@ -63,6 +63,66 @@ config WATCHDOG_SYSFS
Say Y here if you want to enable watchdog device status read through Say Y here if you want to enable watchdog device status read through
sysfs attributes. 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 # General Watchdog drivers
# #
...@@ -90,6 +150,18 @@ config SOFT_WATCHDOG_PRETIMEOUT ...@@ -90,6 +150,18 @@ config SOFT_WATCHDOG_PRETIMEOUT
watchdog. Be aware that governors might affect the watchdog because it watchdog. Be aware that governors might affect the watchdog because it
is purely software, e.g. the panic governor will stall 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 config DA9052_WATCHDOG
tristate "Dialog DA9052 Watchdog" tristate "Dialog DA9052 Watchdog"
depends on PMIC_DA9052 || COMPILE_TEST depends on PMIC_DA9052 || COMPILE_TEST
...@@ -552,7 +624,7 @@ config COH901327_WATCHDOG ...@@ -552,7 +624,7 @@ config COH901327_WATCHDOG
compiled as a module. compiled as a module.
config NPCM7XX_WATCHDOG config NPCM7XX_WATCHDOG
bool "Nuvoton NPCM750 watchdog" tristate "Nuvoton NPCM750 watchdog"
depends on ARCH_NPCM || COMPILE_TEST depends on ARCH_NPCM || COMPILE_TEST
default y if ARCH_NPCM7XX default y if ARCH_NPCM7XX
select WATCHDOG_CORE select WATCHDOG_CORE
...@@ -641,6 +713,22 @@ config IMX2_WDT ...@@ -641,6 +713,22 @@ config IMX2_WDT
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called imx2_wdt. 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 config UX500_WATCHDOG
tristate "ST-Ericsson Ux500 watchdog" tristate "ST-Ericsson Ux500 watchdog"
depends on MFD_DB8500_PRCMU depends on MFD_DB8500_PRCMU
...@@ -1179,6 +1267,15 @@ config HP_WATCHDOG ...@@ -1179,6 +1267,15 @@ config HP_WATCHDOG
To compile this driver as a module, choose M here: the module will be To compile this driver as a module, choose M here: the module will be
called hpwdt. 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 config KEMPLD_WDT
tristate "Kontron COM Watchdog Timer" tristate "Kontron COM Watchdog Timer"
depends on MFD_KEMPLD depends on MFD_KEMPLD
...@@ -1190,15 +1287,6 @@ config KEMPLD_WDT ...@@ -1190,15 +1287,6 @@ config KEMPLD_WDT
This driver can also be built as a module. If so, the module will be This driver can also be built as a module. If so, the module will be
called kempld_wdt. 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 config SC1200_WDT
tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog" tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
depends on X86 depends on X86
...@@ -1647,7 +1735,7 @@ config BCM_KONA_WDT ...@@ -1647,7 +1735,7 @@ config BCM_KONA_WDT
config BCM_KONA_WDT_DEBUG config BCM_KONA_WDT_DEBUG
bool "DEBUGFS support for BCM Kona Watchdog" bool "DEBUGFS support for BCM Kona Watchdog"
depends on BCM_KONA_WDT || COMPILE_TEST depends on BCM_KONA_WDT
help help
If enabled, adds /sys/kernel/debug/bcm_kona_wdt/info which provides If enabled, adds /sys/kernel/debug/bcm_kona_wdt/info which provides
access to the driver's internal data structures as well as watchdog access to the driver's internal data structures as well as watchdog
...@@ -2024,53 +2112,4 @@ config USBPCWATCHDOG ...@@ -2024,53 +2112,4 @@ config USBPCWATCHDOG
Most people will say N. 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 endif # WATCHDOG
...@@ -68,6 +68,7 @@ obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o ...@@ -68,6 +68,7 @@ obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o
obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
obj-$(CONFIG_IMX2_WDT) += imx2_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_UX500_WATCHDOG) += ux500_wdt.o
obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o
obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
...@@ -205,6 +206,7 @@ obj-$(CONFIG_WATCHDOG_SUN4V) += sun4v_wdt.o ...@@ -205,6 +206,7 @@ obj-$(CONFIG_WATCHDOG_SUN4V) += sun4v_wdt.o
obj-$(CONFIG_XEN_WDT) += xen_wdt.o obj-$(CONFIG_XEN_WDT) += xen_wdt.o
# Architecture Independent # Architecture Independent
obj-$(CONFIG_BD70528_WATCHDOG) += bd70528_wdt.o
obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o
obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o
obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o
......
...@@ -277,8 +277,8 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -277,8 +277,8 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return -EINVAL; return -EINVAL;
timeout = new_timeout; timeout = new_timeout;
wdt_keepalive(); wdt_keepalive();
/* Fall through */
} }
/* Fall through */
case WDIOC_GETTIMEOUT: case WDIOC_GETTIMEOUT:
return put_user(timeout, p); return put_user(timeout, p);
default: default:
......
...@@ -244,6 +244,11 @@ static const struct watchdog_ops armada_37xx_wdt_ops = { ...@@ -244,6 +244,11 @@ static const struct watchdog_ops armada_37xx_wdt_ops = {
.get_timeleft = armada_37xx_wdt_get_timeleft, .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) static int armada_37xx_wdt_probe(struct platform_device *pdev)
{ {
struct armada_37xx_watchdog *dev; struct armada_37xx_watchdog *dev;
...@@ -278,12 +283,14 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev) ...@@ -278,12 +283,14 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev)
ret = clk_prepare_enable(dev->clk); ret = clk_prepare_enable(dev->clk);
if (ret) if (ret)
return 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); dev->clk_rate = clk_get_rate(dev->clk);
if (!dev->clk_rate) { if (!dev->clk_rate)
ret = -EINVAL; return -EINVAL;
goto disable_clk;
}
/* /*
* Since the timeout in seconds is given as 32 bit unsigned int, and * 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) ...@@ -307,35 +314,15 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &dev->wdt.status); set_bit(WDOG_HW_RUNNING, &dev->wdt.status);
watchdog_set_nowayout(&dev->wdt, nowayout); 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) if (ret)
goto disable_clk; return ret;
dev_info(&pdev->dev, "Initial timeout %d sec%s\n", dev_info(&pdev->dev, "Initial timeout %d sec%s\n",
dev->wdt.timeout, nowayout ? ", nowayout" : ""); dev->wdt.timeout, nowayout ? ", nowayout" : "");
return 0; 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) static int __maybe_unused armada_37xx_wdt_suspend(struct device *dev)
...@@ -370,8 +357,6 @@ MODULE_DEVICE_TABLE(of, armada_37xx_wdt_match); ...@@ -370,8 +357,6 @@ MODULE_DEVICE_TABLE(of, armada_37xx_wdt_match);
static struct platform_driver armada_37xx_wdt_driver = { static struct platform_driver armada_37xx_wdt_driver = {
.probe = armada_37xx_wdt_probe, .probe = armada_37xx_wdt_probe,
.remove = armada_37xx_wdt_remove,
.shutdown = armada_37xx_wdt_shutdown,
.driver = { .driver = {
.name = "armada_37xx_wdt", .name = "armada_37xx_wdt",
.of_match_table = of_match_ptr(armada_37xx_wdt_match), .of_match_table = of_match_ptr(armada_37xx_wdt_match),
......
...@@ -196,6 +196,11 @@ static const struct watchdog_ops asm9260_wdt_ops = { ...@@ -196,6 +196,11 @@ static const struct watchdog_ops asm9260_wdt_ops = {
.restart = asm9260_restart, .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) static int asm9260_wdt_get_dt_clks(struct asm9260_wdt_priv *priv)
{ {
int err; int err;
...@@ -219,26 +224,32 @@ static int asm9260_wdt_get_dt_clks(struct asm9260_wdt_priv *priv) ...@@ -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"); dev_err(priv->dev, "Failed to enable ahb_clk!\n");
return err; 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); err = clk_set_rate(priv->clk, CLOCK_FREQ);
if (err) { if (err) {
clk_disable_unprepare(priv->clk_ahb);
dev_err(priv->dev, "Failed to set rate!\n"); dev_err(priv->dev, "Failed to set rate!\n");
return err; return err;
} }
err = clk_prepare_enable(priv->clk); err = clk_prepare_enable(priv->clk);
if (err) { if (err) {
clk_disable_unprepare(priv->clk_ahb);
dev_err(priv->dev, "Failed to enable clk!\n"); dev_err(priv->dev, "Failed to enable clk!\n");
return err; return err;
} }
err = devm_add_action_or_reset(priv->dev,
asm9260_clk_disable_unprepare,
priv->clk);
if (err)
return err;
/* wdt has internal divider */ /* wdt has internal divider */
clk = clk_get_rate(priv->clk); clk = clk_get_rate(priv->clk);
if (!clk) { if (!clk) {
clk_disable_unprepare(priv->clk);
clk_disable_unprepare(priv->clk_ahb);
dev_err(priv->dev, "Failed, clk is 0!\n"); dev_err(priv->dev, "Failed, clk is 0!\n");
return -EINVAL; return -EINVAL;
} }
...@@ -274,25 +285,23 @@ static void asm9260_wdt_get_dt_mode(struct asm9260_wdt_priv *priv) ...@@ -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) static int asm9260_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct asm9260_wdt_priv *priv; struct asm9260_wdt_priv *priv;
struct watchdog_device *wdd; struct watchdog_device *wdd;
struct resource *res;
int ret; int ret;
static const char * const mode_name[] = { "hw", "sw", "debug", }; static const char * const mode_name[] = { "hw", "sw", "debug", };
priv = devm_kzalloc(&pdev->dev, sizeof(struct asm9260_wdt_priv), priv = devm_kzalloc(dev, sizeof(struct asm9260_wdt_priv), GFP_KERNEL);
GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
priv->dev = &pdev->dev; priv->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->iobase = devm_platform_ioremap_resource(pdev, 0);
priv->iobase = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->iobase)) if (IS_ERR(priv->iobase))
return PTR_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)) if (IS_ERR(priv->rst))
return PTR_ERR(priv->rst); return PTR_ERR(priv->rst);
...@@ -305,7 +314,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev) ...@@ -305,7 +314,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
wdd->ops = &asm9260_wdt_ops; wdd->ops = &asm9260_wdt_ops;
wdd->min_timeout = 1; wdd->min_timeout = 1;
wdd->max_timeout = BM_WDTC_MAX(priv->wdt_freq); wdd->max_timeout = BM_WDTC_MAX(priv->wdt_freq);
wdd->parent = &pdev->dev; wdd->parent = dev;
watchdog_set_drvdata(wdd, priv); watchdog_set_drvdata(wdd, priv);
...@@ -315,7 +324,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev) ...@@ -315,7 +324,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
* the max instead. * the max instead.
*/ */
wdd->timeout = ASM9260_WDT_DEFAULT_TIMEOUT; 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); asm9260_wdt_get_dt_mode(priv);
...@@ -327,49 +336,25 @@ static int asm9260_wdt_probe(struct platform_device *pdev) ...@@ -327,49 +336,25 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
* Not all supported platforms specify an interrupt for the * Not all supported platforms specify an interrupt for the
* watchdog, so let's make it optional. * watchdog, so let's make it optional.
*/ */
ret = devm_request_irq(&pdev->dev, priv->irq, ret = devm_request_irq(dev, priv->irq, asm9260_wdt_irq, 0,
asm9260_wdt_irq, 0, pdev->name, priv); pdev->name, priv);
if (ret < 0) 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); 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) if (ret)
goto clk_off; return ret;
platform_set_drvdata(pdev, priv); 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]); wdd->timeout, mode_name[priv->mode]);
return 0; 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[] = { static const struct of_device_id asm9260_wdt_of_match[] = {
...@@ -384,8 +369,6 @@ static struct platform_driver asm9260_wdt_driver = { ...@@ -384,8 +369,6 @@ static struct platform_driver asm9260_wdt_driver = {
.of_match_table = asm9260_wdt_of_match, .of_match_table = asm9260_wdt_of_match,
}, },
.probe = asm9260_wdt_probe, .probe = asm9260_wdt_probe,
.remove = asm9260_wdt_remove,
.shutdown = asm9260_wdt_shutdown,
}; };
module_platform_driver(asm9260_wdt_driver); module_platform_driver(asm9260_wdt_driver);
......
...@@ -187,22 +187,21 @@ static const struct watchdog_info aspeed_wdt_info = { ...@@ -187,22 +187,21 @@ static const struct watchdog_info aspeed_wdt_info = {
static int aspeed_wdt_probe(struct platform_device *pdev) static int aspeed_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
const struct aspeed_wdt_config *config; const struct aspeed_wdt_config *config;
const struct of_device_id *ofdid; const struct of_device_id *ofdid;
struct aspeed_wdt *wdt; struct aspeed_wdt *wdt;
struct resource *res;
struct device_node *np; struct device_node *np;
const char *reset_type; const char *reset_type;
u32 duration; u32 duration;
u32 status; u32 status;
int ret; int ret;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_platform_ioremap_resource(pdev, 0);
wdt->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(wdt->base)) if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base); return PTR_ERR(wdt->base);
...@@ -214,12 +213,12 @@ static int aspeed_wdt_probe(struct platform_device *pdev) ...@@ -214,12 +213,12 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
wdt->wdd.info = &aspeed_wdt_info; wdt->wdd.info = &aspeed_wdt_info;
wdt->wdd.ops = &aspeed_wdt_ops; wdt->wdd.ops = &aspeed_wdt_ops;
wdt->wdd.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT_MS; 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; 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); ofdid = of_match_node(aspeed_wdt_of_table, np);
if (!ofdid) if (!ofdid)
...@@ -288,10 +287,10 @@ static int aspeed_wdt_probe(struct platform_device *pdev) ...@@ -288,10 +287,10 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
u32 max_duration = config->ext_pulse_width_mask + 1; u32 max_duration = config->ext_pulse_width_mask + 1;
if (duration == 0 || duration > max_duration) { if (duration == 0 || duration > max_duration) {
dev_err(&pdev->dev, "Invalid pulse duration: %uus\n", dev_err(dev, "Invalid pulse duration: %uus\n",
duration); duration);
duration = max(1U, min(max_duration, duration)); duration = max(1U, min(max_duration, duration));
dev_info(&pdev->dev, "Pulse duration set to %uus\n", dev_info(dev, "Pulse duration set to %uus\n",
duration); duration);
} }
...@@ -314,9 +313,9 @@ static int aspeed_wdt_probe(struct platform_device *pdev) ...@@ -314,9 +313,9 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY) if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
wdt->wdd.bootstatus = WDIOF_CARDRESET; wdt->wdd.bootstatus = WDIOF_CARDRESET;
ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd); ret = devm_watchdog_register_device(dev, &wdt->wdd);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register\n"); dev_err(dev, "failed to register\n");
return ret; return ret;
} }
......
...@@ -327,7 +327,6 @@ static inline int of_at91wdt_init(struct device_node *np, struct at91wdt *wdt) ...@@ -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) static int __init at91wdt_probe(struct platform_device *pdev)
{ {
struct resource *r;
int err; int err;
struct at91wdt *wdt; struct at91wdt *wdt;
...@@ -346,8 +345,7 @@ static int __init at91wdt_probe(struct platform_device *pdev) ...@@ -346,8 +345,7 @@ static int __init at91wdt_probe(struct platform_device *pdev)
wdt->wdd.min_timeout = 1; wdt->wdd.min_timeout = 1;
wdt->wdd.max_timeout = 0xFFFF; wdt->wdd.max_timeout = 0xFFFF;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_platform_ioremap_resource(pdev, 0);
wdt->base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(wdt->base)) if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base); return PTR_ERR(wdt->base);
......
...@@ -250,15 +250,13 @@ static struct miscdevice ath79_wdt_miscdev = { ...@@ -250,15 +250,13 @@ static struct miscdevice ath79_wdt_miscdev = {
static int ath79_wdt_probe(struct platform_device *pdev) static int ath79_wdt_probe(struct platform_device *pdev)
{ {
struct resource *res;
u32 ctrl; u32 ctrl;
int err; int err;
if (wdt_base) if (wdt_base)
return -EBUSY; return -EBUSY;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt_base = devm_platform_ioremap_resource(pdev, 0);
wdt_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(wdt_base)) if (IS_ERR(wdt_base))
return PTR_ERR(wdt_base); return PTR_ERR(wdt_base);
......
...@@ -125,80 +125,57 @@ static const struct of_device_id atlas7_wdt_ids[] = { ...@@ -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) 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 atlas7_wdog *wdt;
struct resource *res;
struct clk *clk; struct clk *clk;
int ret; int ret;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_platform_ioremap_resource(pdev, 0);
wdt->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(wdt->base)) if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base); return PTR_ERR(wdt->base);
clk = of_clk_get(np, 0); clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) if (IS_ERR(clk))
return PTR_ERR(clk); return PTR_ERR(clk);
ret = clk_prepare_enable(clk); ret = clk_prepare_enable(clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "clk enable failed\n"); dev_err(dev, "clk enable failed\n");
goto err; return ret;
} }
ret = devm_add_action_or_reset(dev, atlas7_clk_disable_unprepare, clk);
if (ret)
return ret;
/* disable watchdog hardware */ /* disable watchdog hardware */
writel(0, wdt->base + ATLAS7_WDT_CNT_CTRL); writel(0, wdt->base + ATLAS7_WDT_CNT_CTRL);
wdt->tick_rate = clk_get_rate(clk); wdt->tick_rate = clk_get_rate(clk);
if (!wdt->tick_rate) { if (!wdt->tick_rate)
ret = -EINVAL; return -EINVAL;
goto err1;
}
wdt->clk = clk; wdt->clk = clk;
atlas7_wdd.min_timeout = 1; atlas7_wdd.min_timeout = 1;
atlas7_wdd.max_timeout = UINT_MAX / wdt->tick_rate; 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_nowayout(&atlas7_wdd, nowayout);
watchdog_set_drvdata(&atlas7_wdd, wdt); watchdog_set_drvdata(&atlas7_wdd, wdt);
platform_set_drvdata(pdev, &atlas7_wdd); platform_set_drvdata(pdev, &atlas7_wdd);
ret = watchdog_register_device(&atlas7_wdd); watchdog_stop_on_reboot(&atlas7_wdd);
if (ret) watchdog_stop_on_unregister(&atlas7_wdd);
goto err1; return devm_watchdog_register_device(dev, &atlas7_wdd);
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;
} }
static int __maybe_unused atlas7_wdt_suspend(struct device *dev) static int __maybe_unused atlas7_wdt_suspend(struct device *dev)
...@@ -236,8 +213,6 @@ static struct platform_driver atlas7_wdt_driver = { ...@@ -236,8 +213,6 @@ static struct platform_driver atlas7_wdt_driver = {
.of_match_table = atlas7_wdt_ids, .of_match_table = atlas7_wdt_ids,
}, },
.probe = atlas7_wdt_probe, .probe = atlas7_wdt_probe,
.remove = atlas7_wdt_remove,
.shutdown = atlas7_wdt_shutdown,
}; };
module_platform_driver(atlas7_wdt_driver); module_platform_driver(atlas7_wdt_driver);
......
...@@ -177,7 +177,6 @@ static int bcm2835_wdt_probe(struct platform_device *pdev) ...@@ -177,7 +177,6 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
wdt = devm_kzalloc(dev, sizeof(struct bcm2835_wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(struct bcm2835_wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
platform_set_drvdata(pdev, wdt);
spin_lock_init(&wdt->lock); spin_lock_init(&wdt->lock);
......
...@@ -107,11 +107,15 @@ static const struct watchdog_ops bcm7038_wdt_ops = { ...@@ -107,11 +107,15 @@ static const struct watchdog_ops bcm7038_wdt_ops = {
.get_timeleft = bcm7038_wdt_get_timeleft, .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) static int bcm7038_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct bcm7038_watchdog *wdt; struct bcm7038_watchdog *wdt;
struct resource *res;
int err; int err;
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
...@@ -120,8 +124,7 @@ static int bcm7038_wdt_probe(struct platform_device *pdev) ...@@ -120,8 +124,7 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt); platform_set_drvdata(pdev, wdt);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_platform_ioremap_resource(pdev, 0);
wdt->base = devm_ioremap_resource(dev, res);
if (IS_ERR(wdt->base)) if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base); return PTR_ERR(wdt->base);
...@@ -129,6 +132,11 @@ static int bcm7038_wdt_probe(struct platform_device *pdev) ...@@ -129,6 +132,11 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
/* If unable to get clock, use default frequency */ /* If unable to get clock, use default frequency */
if (!IS_ERR(wdt->clk)) { if (!IS_ERR(wdt->clk)) {
err = clk_prepare_enable(wdt->clk); 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) if (err)
return err; return err;
wdt->rate = clk_get_rate(wdt->clk); wdt->rate = clk_get_rate(wdt->clk);
...@@ -148,10 +156,11 @@ static int bcm7038_wdt_probe(struct platform_device *pdev) ...@@ -148,10 +156,11 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
wdt->wdd.parent = dev; wdt->wdd.parent = dev;
watchdog_set_drvdata(&wdt->wdd, wdt); 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) { if (err) {
dev_err(dev, "Failed to register watchdog device\n"); dev_err(dev, "Failed to register watchdog device\n");
clk_disable_unprepare(wdt->clk);
return err; return err;
} }
...@@ -160,19 +169,6 @@ static int bcm7038_wdt_probe(struct platform_device *pdev) ...@@ -160,19 +169,6 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
return 0; 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 #ifdef CONFIG_PM_SLEEP
static int bcm7038_wdt_suspend(struct device *dev) static int bcm7038_wdt_suspend(struct device *dev)
{ {
...@@ -198,14 +194,6 @@ static int bcm7038_wdt_resume(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, static SIMPLE_DEV_PM_OPS(bcm7038_wdt_pm_ops, bcm7038_wdt_suspend,
bcm7038_wdt_resume); 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[] = { static const struct of_device_id bcm7038_wdt_match[] = {
{ .compatible = "brcm,bcm7038-wdt" }, { .compatible = "brcm,bcm7038-wdt" },
{}, {},
...@@ -214,8 +202,6 @@ MODULE_DEVICE_TABLE(of, bcm7038_wdt_match); ...@@ -214,8 +202,6 @@ MODULE_DEVICE_TABLE(of, bcm7038_wdt_match);
static struct platform_driver bcm7038_wdt_driver = { static struct platform_driver bcm7038_wdt_driver = {
.probe = bcm7038_wdt_probe, .probe = bcm7038_wdt_probe,
.remove = bcm7038_wdt_remove,
.shutdown = bcm7038_wdt_shutdown,
.driver = { .driver = {
.name = "bcm7038-wdt", .name = "bcm7038-wdt",
.of_match_table = bcm7038_wdt_match, .of_match_table = bcm7038_wdt_match,
......
...@@ -271,16 +271,10 @@ static struct watchdog_device bcm_kona_wdt_wdd = { ...@@ -271,16 +271,10 @@ static struct watchdog_device bcm_kona_wdt_wdd = {
.timeout = SECWDOG_MAX_COUNT >> SECWDOG_DEFAULT_RESOLUTION, .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) static int bcm_kona_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct bcm_kona_wdt *wdt; struct bcm_kona_wdt *wdt;
struct resource *res;
int ret; int ret;
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
...@@ -289,8 +283,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev) ...@@ -289,8 +283,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
spin_lock_init(&wdt->lock); spin_lock_init(&wdt->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_platform_ioremap_resource(pdev, 0);
wdt->base = devm_ioremap_resource(dev, res);
if (IS_ERR(wdt->base)) if (IS_ERR(wdt->base))
return -ENODEV; return -ENODEV;
...@@ -303,7 +296,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev) ...@@ -303,7 +296,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt); platform_set_drvdata(pdev, wdt);
watchdog_set_drvdata(&bcm_kona_wdt_wdd, 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); ret = bcm_kona_wdt_set_timeout_reg(&bcm_kona_wdt_wdd, 0);
if (ret) { if (ret) {
...@@ -311,7 +304,9 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev) ...@@ -311,7 +304,9 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
return ret; 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) { if (ret) {
dev_err(dev, "Failed to register watchdog device"); dev_err(dev, "Failed to register watchdog device");
return ret; return ret;
...@@ -326,8 +321,6 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev) ...@@ -326,8 +321,6 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
static int bcm_kona_wdt_remove(struct platform_device *pdev) static int bcm_kona_wdt_remove(struct platform_device *pdev)
{ {
bcm_kona_wdt_debug_exit(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"); dev_dbg(&pdev->dev, "Watchdog driver disabled");
return 0; return 0;
...@@ -346,7 +339,6 @@ static struct platform_driver bcm_kona_wdt_driver = { ...@@ -346,7 +339,6 @@ static struct platform_driver bcm_kona_wdt_driver = {
}, },
.probe = bcm_kona_wdt_probe, .probe = bcm_kona_wdt_probe,
.remove = bcm_kona_wdt_remove, .remove = bcm_kona_wdt_remove,
.shutdown = bcm_kona_wdt_shutdown,
}; };
module_platform_driver(bcm_kona_wdt_driver); module_platform_driver(bcm_kona_wdt_driver);
......
// 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");
...@@ -274,6 +274,11 @@ static const struct watchdog_ops cdns_wdt_ops = { ...@@ -274,6 +274,11 @@ static const struct watchdog_ops cdns_wdt_ops = {
.set_timeout = cdns_wdt_settimeout, .set_timeout = cdns_wdt_settimeout,
}; };
static void cdns_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
/************************Platform Operations*****************************/ /************************Platform Operations*****************************/
/** /**
* cdns_wdt_probe - Probe call for the device. * cdns_wdt_probe - Probe call for the device.
...@@ -285,13 +290,13 @@ static const struct watchdog_ops cdns_wdt_ops = { ...@@ -285,13 +290,13 @@ static const struct watchdog_ops cdns_wdt_ops = {
*/ */
static int cdns_wdt_probe(struct platform_device *pdev) static int cdns_wdt_probe(struct platform_device *pdev)
{ {
struct resource *res; struct device *dev = &pdev->dev;
int ret, irq; int ret, irq;
unsigned long clock_f; unsigned long clock_f;
struct cdns_wdt *wdt; struct cdns_wdt *wdt;
struct watchdog_device *cdns_wdt_device; 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) if (!wdt)
return -ENOMEM; return -ENOMEM;
...@@ -302,19 +307,18 @@ static int cdns_wdt_probe(struct platform_device *pdev) ...@@ -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->min_timeout = CDNS_WDT_MIN_TIMEOUT;
cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT; cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->regs = devm_platform_ioremap_resource(pdev, 0);
wdt->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(wdt->regs)) if (IS_ERR(wdt->regs))
return PTR_ERR(wdt->regs); return PTR_ERR(wdt->regs);
/* Register the interrupt */ /* 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); irq = platform_get_irq(pdev, 0);
if (!wdt->rst && irq >= 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); pdev->name, pdev);
if (ret) { if (ret) {
dev_err(&pdev->dev, dev_err(dev,
"cannot register interrupt handler err=%d\n", "cannot register interrupt handler err=%d\n",
ret); ret);
return ret; return ret;
...@@ -322,30 +326,28 @@ static int cdns_wdt_probe(struct platform_device *pdev) ...@@ -322,30 +326,28 @@ static int cdns_wdt_probe(struct platform_device *pdev)
} }
/* Initialize the members of cdns_wdt structure */ /* Initialize the members of cdns_wdt structure */
cdns_wdt_device->parent = &pdev->dev; cdns_wdt_device->parent = 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;
}
watchdog_init_timeout(cdns_wdt_device, wdt_timeout, dev);
watchdog_set_nowayout(cdns_wdt_device, nowayout); watchdog_set_nowayout(cdns_wdt_device, nowayout);
watchdog_stop_on_reboot(cdns_wdt_device); watchdog_stop_on_reboot(cdns_wdt_device);
watchdog_set_drvdata(cdns_wdt_device, wdt); 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)) { if (IS_ERR(wdt->clk)) {
dev_err(&pdev->dev, "input clock not found\n"); dev_err(dev, "input clock not found\n");
ret = PTR_ERR(wdt->clk); return PTR_ERR(wdt->clk);
return ret;
} }
ret = clk_prepare_enable(wdt->clk); ret = clk_prepare_enable(wdt->clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "unable to enable clock\n"); dev_err(dev, "unable to enable clock\n");
return ret; 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); clock_f = clk_get_rate(wdt->clk);
if (clock_f <= CDNS_WDT_CLK_75MHZ) { if (clock_f <= CDNS_WDT_CLK_75MHZ) {
...@@ -358,56 +360,20 @@ static int cdns_wdt_probe(struct platform_device *pdev) ...@@ -358,56 +360,20 @@ static int cdns_wdt_probe(struct platform_device *pdev)
spin_lock_init(&wdt->io_lock); 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) { if (ret) {
dev_err(&pdev->dev, "Failed to register wdt device\n"); dev_err(dev, "Failed to register wdt device\n");
goto err_clk_disable; return ret;
} }
platform_set_drvdata(pdev, wdt); 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, wdt->regs, cdns_wdt_device->timeout,
nowayout ? ", nowayout" : ""); nowayout ? ", nowayout" : "");
return 0; 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); ...@@ -462,8 +428,6 @@ MODULE_DEVICE_TABLE(of, cdns_wdt_of_match);
/* Driver Structure */ /* Driver Structure */
static struct platform_driver cdns_wdt_driver = { static struct platform_driver cdns_wdt_driver = {
.probe = cdns_wdt_probe, .probe = cdns_wdt_probe,
.remove = cdns_wdt_remove,
.shutdown = cdns_wdt_shutdown,
.driver = { .driver = {
.name = "cdns-wdt", .name = "cdns-wdt",
.of_match_table = cdns_wdt_of_match, .of_match_table = cdns_wdt_of_match,
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Watchdog driver for the ST-Ericsson AB COH 901 327 IP core * Watchdog driver for the ST-Ericsson AB COH 901 327 IP core
* Author: Linus Walleij <linus.walleij@stericsson.com> * Author: Linus Walleij <linus.walleij@stericsson.com>
*/ */
#include <linux/module.h> #include <linux/moduleparam.h>
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
...@@ -243,27 +243,15 @@ static struct watchdog_device coh901327_wdt = { ...@@ -243,27 +243,15 @@ static struct watchdog_device coh901327_wdt = {
.timeout = U300_WDOG_DEFAULT_TIMEOUT, .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) static int __init coh901327_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
int ret; int ret;
u16 val; u16 val;
struct resource *res;
parent = dev; parent = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); virtbase = devm_platform_ioremap_resource(pdev, 0);
virtbase = devm_ioremap_resource(dev, res);
if (IS_ERR(virtbase)) if (IS_ERR(virtbase))
return PTR_ERR(virtbase); return PTR_ERR(virtbase);
...@@ -408,19 +396,13 @@ static struct platform_driver coh901327_driver = { ...@@ -408,19 +396,13 @@ static struct platform_driver coh901327_driver = {
.driver = { .driver = {
.name = "coh901327_wdog", .name = "coh901327_wdog",
.of_match_table = coh901327_dt_match, .of_match_table = coh901327_dt_match,
.suppress_bind_attrs = true,
}, },
.remove = __exit_p(coh901327_remove),
.suspend = coh901327_suspend, .suspend = coh901327_suspend,
.resume = coh901327_resume, .resume = coh901327_resume,
}; };
builtin_platform_driver_probe(coh901327_driver, coh901327_probe);
module_platform_driver_probe(coh901327_driver, coh901327_probe); /* not really modular, but ... */
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
MODULE_DESCRIPTION("COH 901 327 Watchdog");
module_param(margin, uint, 0); module_param(margin, uint, 0);
MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:coh901327-watchdog");
...@@ -150,13 +150,13 @@ static const struct watchdog_ops da9052_wdt_ops = { ...@@ -150,13 +150,13 @@ static const struct watchdog_ops da9052_wdt_ops = {
static int da9052_wdt_probe(struct platform_device *pdev) static int da9052_wdt_probe(struct platform_device *pdev)
{ {
struct da9052 *da9052 = dev_get_drvdata(pdev->dev.parent); struct device *dev = &pdev->dev;
struct da9052 *da9052 = dev_get_drvdata(dev->parent);
struct da9052_wdt_data *driver_data; struct da9052_wdt_data *driver_data;
struct watchdog_device *da9052_wdt; struct watchdog_device *da9052_wdt;
int ret; int ret;
driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
GFP_KERNEL);
if (!driver_data) if (!driver_data)
return -ENOMEM; return -ENOMEM;
driver_data->da9052 = da9052; driver_data->da9052 = da9052;
...@@ -166,18 +166,17 @@ static int da9052_wdt_probe(struct platform_device *pdev) ...@@ -166,18 +166,17 @@ static int da9052_wdt_probe(struct platform_device *pdev)
da9052_wdt->timeout = DA9052_DEF_TIMEOUT; da9052_wdt->timeout = DA9052_DEF_TIMEOUT;
da9052_wdt->info = &da9052_wdt_info; da9052_wdt->info = &da9052_wdt_info;
da9052_wdt->ops = &da9052_wdt_ops; da9052_wdt->ops = &da9052_wdt_ops;
da9052_wdt->parent = &pdev->dev; da9052_wdt->parent = dev;
watchdog_set_drvdata(da9052_wdt, driver_data); watchdog_set_drvdata(da9052_wdt, driver_data);
ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG,
DA9052_CONTROLD_TWDSCALE, 0); DA9052_CONTROLD_TWDSCALE, 0);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to disable watchdog bits, %d\n", dev_err(dev, "Failed to disable watchdog bits, %d\n", ret);
ret);
return 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) { if (ret != 0) {
dev_err(da9052->dev, "watchdog_register_device() failed: %d\n", dev_err(da9052->dev, "watchdog_register_device() failed: %d\n",
ret); ret);
......
...@@ -119,13 +119,13 @@ static const struct watchdog_ops da9055_wdt_ops = { ...@@ -119,13 +119,13 @@ static const struct watchdog_ops da9055_wdt_ops = {
static int da9055_wdt_probe(struct platform_device *pdev) 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 da9055_wdt_data *driver_data;
struct watchdog_device *da9055_wdt; struct watchdog_device *da9055_wdt;
int ret; int ret;
driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
GFP_KERNEL);
if (!driver_data) if (!driver_data)
return -ENOMEM; return -ENOMEM;
...@@ -136,17 +136,17 @@ static int da9055_wdt_probe(struct platform_device *pdev) ...@@ -136,17 +136,17 @@ static int da9055_wdt_probe(struct platform_device *pdev)
da9055_wdt->timeout = DA9055_DEF_TIMEOUT; da9055_wdt->timeout = DA9055_DEF_TIMEOUT;
da9055_wdt->info = &da9055_wdt_info; da9055_wdt->info = &da9055_wdt_info;
da9055_wdt->ops = &da9055_wdt_ops; da9055_wdt->ops = &da9055_wdt_ops;
da9055_wdt->parent = &pdev->dev; da9055_wdt->parent = dev;
watchdog_set_nowayout(da9055_wdt, nowayout); watchdog_set_nowayout(da9055_wdt, nowayout);
watchdog_set_drvdata(da9055_wdt, driver_data); watchdog_set_drvdata(da9055_wdt, driver_data);
ret = da9055_wdt_stop(da9055_wdt); ret = da9055_wdt_stop(da9055_wdt);
if (ret < 0) { 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; return ret;
} }
ret = devm_watchdog_register_device(&pdev->dev, &driver_data->wdt); ret = devm_watchdog_register_device(dev, &driver_data->wdt);
if (ret != 0) if (ret != 0)
dev_err(da9055->dev, "watchdog_register_device() failed: %d\n", dev_err(da9055->dev, "watchdog_register_device() failed: %d\n",
ret); ret);
......
...@@ -46,14 +46,9 @@ static unsigned int da9062_wdt_timeout_to_sel(unsigned int secs) ...@@ -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) static int da9062_reset_watchdog_timer(struct da9062_watchdog *wdt)
{ {
int ret; return regmap_update_bits(wdt->hw->regmap, DA9062AA_CONTROL_F,
ret = regmap_update_bits(wdt->hw->regmap,
DA9062AA_CONTROL_F,
DA9062AA_WATCHDOG_MASK, DA9062AA_WATCHDOG_MASK,
DA9062AA_WATCHDOG_MASK); DA9062AA_WATCHDOG_MASK);
return ret;
} }
static int da9062_wdt_update_timeout_register(struct da9062_watchdog *wdt, static int da9062_wdt_update_timeout_register(struct da9062_watchdog *wdt,
...@@ -190,15 +185,16 @@ MODULE_DEVICE_TABLE(of, da9062_compatible_id_table); ...@@ -190,15 +185,16 @@ MODULE_DEVICE_TABLE(of, da9062_compatible_id_table);
static int da9062_wdt_probe(struct platform_device *pdev) static int da9062_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
int ret; int ret;
struct da9062 *chip; struct da9062 *chip;
struct da9062_watchdog *wdt; struct da9062_watchdog *wdt;
chip = dev_get_drvdata(pdev->dev.parent); chip = dev_get_drvdata(dev->parent);
if (!chip) if (!chip)
return -EINVAL; return -EINVAL;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
...@@ -211,13 +207,13 @@ static int da9062_wdt_probe(struct platform_device *pdev) ...@@ -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.min_hw_heartbeat_ms = DA9062_RESET_PROTECTION_MS;
wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT; wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS; 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_restart_priority(&wdt->wdtdev, 128);
watchdog_set_drvdata(&wdt->wdtdev, wdt); 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) { if (ret < 0) {
dev_err(wdt->hw->dev, dev_err(wdt->hw->dev,
"watchdog registration failed (%d)\n", ret); "watchdog registration failed (%d)\n", ret);
......
...@@ -188,17 +188,18 @@ static const struct watchdog_ops da9063_watchdog_ops = { ...@@ -188,17 +188,18 @@ static const struct watchdog_ops da9063_watchdog_ops = {
static int da9063_wdt_probe(struct platform_device *pdev) static int da9063_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct da9063 *da9063; struct da9063 *da9063;
struct watchdog_device *wdd; struct watchdog_device *wdd;
if (!pdev->dev.parent) if (!dev->parent)
return -EINVAL; return -EINVAL;
da9063 = dev_get_drvdata(pdev->dev.parent); da9063 = dev_get_drvdata(dev->parent);
if (!da9063) if (!da9063)
return -EINVAL; return -EINVAL;
wdd = devm_kzalloc(&pdev->dev, sizeof(*wdd), GFP_KERNEL); wdd = devm_kzalloc(dev, sizeof(*wdd), GFP_KERNEL);
if (!wdd) if (!wdd)
return -ENOMEM; return -ENOMEM;
...@@ -207,22 +208,24 @@ static int da9063_wdt_probe(struct platform_device *pdev) ...@@ -207,22 +208,24 @@ static int da9063_wdt_probe(struct platform_device *pdev)
wdd->min_timeout = DA9063_WDT_MIN_TIMEOUT; wdd->min_timeout = DA9063_WDT_MIN_TIMEOUT;
wdd->max_timeout = DA9063_WDT_MAX_TIMEOUT; wdd->max_timeout = DA9063_WDT_MAX_TIMEOUT;
wdd->min_hw_heartbeat_ms = DA9063_RESET_PROTECTION_MS; wdd->min_hw_heartbeat_ms = DA9063_RESET_PROTECTION_MS;
wdd->timeout = DA9063_WDG_TIMEOUT; wdd->parent = dev;
wdd->parent = &pdev->dev;
wdd->status = WATCHDOG_NOWAYOUT_INIT_STATUS; wdd->status = WATCHDOG_NOWAYOUT_INIT_STATUS;
watchdog_set_restart_priority(wdd, 128); watchdog_set_restart_priority(wdd, 128);
watchdog_set_drvdata(wdd, da9063); 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 */ /* Change the timeout to the default value if the watchdog is running */
if (da9063_wdt_is_running(da9063)) { 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); 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 = { static struct platform_driver da9063_wdt_driver = {
......
...@@ -191,11 +191,15 @@ static const struct watchdog_ops davinci_wdt_ops = { ...@@ -191,11 +191,15 @@ static const struct watchdog_ops davinci_wdt_ops = {
.restart = davinci_wdt_restart, .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) static int davinci_wdt_probe(struct platform_device *pdev)
{ {
int ret = 0; int ret = 0;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct resource *wdt_mem;
struct watchdog_device *wdd; struct watchdog_device *wdd;
struct davinci_wdt_device *davinci_wdt; struct davinci_wdt_device *davinci_wdt;
...@@ -207,15 +211,19 @@ static int davinci_wdt_probe(struct platform_device *pdev) ...@@ -207,15 +211,19 @@ static int davinci_wdt_probe(struct platform_device *pdev)
if (IS_ERR(davinci_wdt->clk)) { if (IS_ERR(davinci_wdt->clk)) {
if (PTR_ERR(davinci_wdt->clk) != -EPROBE_DEFER) 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); return PTR_ERR(davinci_wdt->clk);
} }
ret = clk_prepare_enable(davinci_wdt->clk); ret = clk_prepare_enable(davinci_wdt->clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to prepare clock\n"); dev_err(dev, "failed to prepare clock\n");
return ret; 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); platform_set_drvdata(pdev, davinci_wdt);
...@@ -225,7 +233,7 @@ static int davinci_wdt_probe(struct platform_device *pdev) ...@@ -225,7 +233,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
wdd->min_timeout = 1; wdd->min_timeout = 1;
wdd->max_timeout = MAX_HEARTBEAT; wdd->max_timeout = MAX_HEARTBEAT;
wdd->timeout = DEFAULT_HEARTBEAT; wdd->timeout = DEFAULT_HEARTBEAT;
wdd->parent = &pdev->dev; wdd->parent = dev;
watchdog_init_timeout(wdd, heartbeat, dev); watchdog_init_timeout(wdd, heartbeat, dev);
...@@ -235,33 +243,15 @@ static int davinci_wdt_probe(struct platform_device *pdev) ...@@ -235,33 +243,15 @@ static int davinci_wdt_probe(struct platform_device *pdev)
watchdog_set_nowayout(wdd, 1); watchdog_set_nowayout(wdd, 1);
watchdog_set_restart_priority(wdd, 128); watchdog_set_restart_priority(wdd, 128);
wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); davinci_wdt->base = devm_platform_ioremap_resource(pdev, 0);
davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem); if (IS_ERR(davinci_wdt->base))
if (IS_ERR(davinci_wdt->base)) { return PTR_ERR(davinci_wdt->base);
ret = PTR_ERR(davinci_wdt->base);
goto err_clk_disable;
}
ret = watchdog_register_device(wdd); ret = devm_watchdog_register_device(dev, wdd);
if (ret) { if (ret) {
dev_err(dev, "cannot register watchdog device\n"); dev_err(dev, "cannot register watchdog device\n");
goto err_clk_disable;
}
return 0;
err_clk_disable:
clk_disable_unprepare(davinci_wdt->clk);
return ret; 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; return 0;
} }
...@@ -278,7 +268,6 @@ static struct platform_driver platform_wdt_driver = { ...@@ -278,7 +268,6 @@ static struct platform_driver platform_wdt_driver = {
.of_match_table = davinci_wdt_of_match, .of_match_table = davinci_wdt_of_match,
}, },
.probe = davinci_wdt_probe, .probe = davinci_wdt_probe,
.remove = davinci_wdt_remove,
}; };
module_platform_driver(platform_wdt_driver); module_platform_driver(platform_wdt_driver);
......
...@@ -116,7 +116,6 @@ static struct watchdog_device dc_wdt_wdd = { ...@@ -116,7 +116,6 @@ static struct watchdog_device dc_wdt_wdd = {
static int dc_wdt_probe(struct platform_device *pdev) static int dc_wdt_probe(struct platform_device *pdev)
{ {
struct resource *res;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct dc_wdt *wdt; struct dc_wdt *wdt;
int ret; int ret;
...@@ -125,8 +124,7 @@ static int dc_wdt_probe(struct platform_device *pdev) ...@@ -125,8 +124,7 @@ static int dc_wdt_probe(struct platform_device *pdev)
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_platform_ioremap_resource(pdev, 0);
wdt->base = devm_ioremap_resource(dev, res);
if (IS_ERR(wdt->base)) if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base); return PTR_ERR(wdt->base);
......
...@@ -238,15 +238,13 @@ static int dw_wdt_drv_probe(struct platform_device *pdev) ...@@ -238,15 +238,13 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct watchdog_device *wdd; struct watchdog_device *wdd;
struct dw_wdt *dw_wdt; struct dw_wdt *dw_wdt;
struct resource *mem;
int ret; int ret;
dw_wdt = devm_kzalloc(dev, sizeof(*dw_wdt), GFP_KERNEL); dw_wdt = devm_kzalloc(dev, sizeof(*dw_wdt), GFP_KERNEL);
if (!dw_wdt) if (!dw_wdt)
return -ENOMEM; return -ENOMEM;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); dw_wdt->regs = devm_platform_ioremap_resource(pdev, 0);
dw_wdt->regs = devm_ioremap_resource(dev, mem);
if (IS_ERR(dw_wdt->regs)) if (IS_ERR(dw_wdt->regs))
return PTR_ERR(dw_wdt->regs); return PTR_ERR(dw_wdt->regs);
......
...@@ -117,10 +117,7 @@ static int ebc_c384_wdt_probe(struct device *dev, unsigned int id) ...@@ -117,10 +117,7 @@ static int ebc_c384_wdt_probe(struct device *dev, unsigned int id)
wdd->max_timeout = WATCHDOG_MAX_TIMEOUT; wdd->max_timeout = WATCHDOG_MAX_TIMEOUT;
watchdog_set_nowayout(wdd, nowayout); watchdog_set_nowayout(wdd, nowayout);
watchdog_init_timeout(wdd, timeout, dev);
if (watchdog_init_timeout(wdd, timeout, dev))
dev_warn(dev, "Invalid timeout (%u seconds), using default (%u seconds)\n",
timeout, WATCHDOG_TIMEOUT);
return devm_watchdog_register_device(dev, wdd); return devm_watchdog_register_device(dev, wdd);
} }
......
...@@ -89,18 +89,17 @@ static const struct watchdog_ops ep93xx_wdt_ops = { ...@@ -89,18 +89,17 @@ static const struct watchdog_ops ep93xx_wdt_ops = {
static int ep93xx_wdt_probe(struct platform_device *pdev) static int ep93xx_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct ep93xx_wdt_priv *priv; struct ep93xx_wdt_priv *priv;
struct watchdog_device *wdd; struct watchdog_device *wdd;
struct resource *res;
unsigned long val; unsigned long val;
int ret; int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->mmio = devm_platform_ioremap_resource(pdev, 0);
priv->mmio = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->mmio)) if (IS_ERR(priv->mmio))
return PTR_ERR(priv->mmio); return PTR_ERR(priv->mmio);
...@@ -112,20 +111,20 @@ static int ep93xx_wdt_probe(struct platform_device *pdev) ...@@ -112,20 +111,20 @@ static int ep93xx_wdt_probe(struct platform_device *pdev)
wdd->ops = &ep93xx_wdt_ops; wdd->ops = &ep93xx_wdt_ops;
wdd->min_timeout = 1; wdd->min_timeout = 1;
wdd->max_hw_heartbeat_ms = 200; wdd->max_hw_heartbeat_ms = 200;
wdd->parent = &pdev->dev; wdd->parent = dev;
watchdog_set_nowayout(wdd, nowayout); watchdog_set_nowayout(wdd, nowayout);
wdd->timeout = WDT_TIMEOUT; wdd->timeout = WDT_TIMEOUT;
watchdog_init_timeout(wdd, timeout, &pdev->dev); watchdog_init_timeout(wdd, timeout, dev);
watchdog_set_drvdata(wdd, priv); watchdog_set_drvdata(wdd, priv);
ret = devm_watchdog_register_device(&pdev->dev, wdd); ret = devm_watchdog_register_device(dev, wdd);
if (ret) if (ret)
return ret; return ret;
dev_info(&pdev->dev, "EP93XX watchdog driver %s\n", dev_info(dev, "EP93XX watchdog driver %s\n",
(val & 0x08) ? " (nCS1 disable detected)" : ""); (val & 0x08) ? " (nCS1 disable detected)" : "");
return 0; return 0;
......
...@@ -338,8 +338,11 @@ static int f71862fg_pin_configure(unsigned short ioaddr) ...@@ -338,8 +338,11 @@ static int f71862fg_pin_configure(unsigned short ioaddr)
static int watchdog_start(void) static int watchdog_start(void)
{ {
int err;
u8 tmp;
/* Make sure we don't die as soon as the watchdog is enabled below */ /* Make sure we don't die as soon as the watchdog is enabled below */
int err = watchdog_keepalive(); err = watchdog_keepalive();
if (err) if (err)
return err; return err;
...@@ -386,19 +389,18 @@ static int watchdog_start(void) ...@@ -386,19 +389,18 @@ static int watchdog_start(void)
break; break;
case f81866: 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. * GPIO1 Control Register when 27h BIT3:2 = 01 & BIT0 = 0.
* The PIN 70(GPIO15/WDTRST) is controlled by 2Ch: * The PIN 70(GPIO15/WDTRST) is controlled by 2Ch:
* BIT5: 0 -> WDTRST# * BIT5: 0 -> WDTRST#
* 1 -> GPIO15 * 1 -> GPIO15
*/ */
superio_clear_bit(watchdog.sioaddr, SIO_F81866_REG_GPIO1, tmp = superio_inb(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL);
BIT(5)); 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; break;
default: default:
......
...@@ -124,7 +124,6 @@ static const struct watchdog_info ftwdt010_wdt_info = { ...@@ -124,7 +124,6 @@ static const struct watchdog_info ftwdt010_wdt_info = {
static int ftwdt010_wdt_probe(struct platform_device *pdev) static int ftwdt010_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct resource *res;
struct ftwdt010_wdt *gwdt; struct ftwdt010_wdt *gwdt;
unsigned int reg; unsigned int reg;
int irq; int irq;
...@@ -134,8 +133,7 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev) ...@@ -134,8 +133,7 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)
if (!gwdt) if (!gwdt)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); gwdt->base = devm_platform_ioremap_resource(pdev, 0);
gwdt->base = devm_ioremap_resource(dev, res);
if (IS_ERR(gwdt->base)) if (IS_ERR(gwdt->base))
return PTR_ERR(gwdt->base); return PTR_ERR(gwdt->base);
...@@ -171,7 +169,7 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev) ...@@ -171,7 +169,7 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)
ret = devm_watchdog_register_device(dev, &gwdt->wdd); ret = devm_watchdog_register_device(dev, &gwdt->wdd);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register watchdog\n"); dev_err(dev, "failed to register watchdog\n");
return ret; return ret;
} }
......
...@@ -154,25 +154,14 @@ static int gpio_wdt_probe(struct platform_device *pdev) ...@@ -154,25 +154,14 @@ static int gpio_wdt_probe(struct platform_device *pdev)
priv->wdd.parent = dev; priv->wdd.parent = dev;
priv->wdd.timeout = SOFT_TIMEOUT_DEF; 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); watchdog_stop_on_reboot(&priv->wdd);
if (priv->always_running) if (priv->always_running)
gpio_wdt_start(&priv->wdd); gpio_wdt_start(&priv->wdd);
ret = watchdog_register_device(&priv->wdd); return devm_watchdog_register_device(dev, &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;
} }
static const struct of_device_id gpio_wdt_dt_ids[] = { static const struct of_device_id gpio_wdt_dt_ids[] = {
...@@ -187,7 +176,6 @@ static struct platform_driver gpio_wdt_driver = { ...@@ -187,7 +176,6 @@ static struct platform_driver gpio_wdt_driver = {
.of_match_table = gpio_wdt_dt_ids, .of_match_table = gpio_wdt_dt_ids,
}, },
.probe = gpio_wdt_probe, .probe = gpio_wdt_probe,
.remove = gpio_wdt_remove,
}; };
#ifdef CONFIG_GPIO_WATCHDOG_ARCH_INITCALL #ifdef CONFIG_GPIO_WATCHDOG_ARCH_INITCALL
......
...@@ -311,8 +311,7 @@ static int hpwdt_init_one(struct pci_dev *dev, ...@@ -311,8 +311,7 @@ static int hpwdt_init_one(struct pci_dev *dev,
goto error_init_nmi_decoding; goto error_init_nmi_decoding;
watchdog_set_nowayout(&hpwdt_dev, nowayout); watchdog_set_nowayout(&hpwdt_dev, nowayout);
if (watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL)) watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL);
dev_warn(&dev->dev, "Invalid soft_margin: %d.\n", soft_margin);
if (pretimeout && hpwdt_dev.timeout <= PRETIMEOUT_SEC) { if (pretimeout && hpwdt_dev.timeout <= PRETIMEOUT_SEC) {
dev_warn(&dev->dev, "timeout <= pretimeout. Setting pretimeout to zero\n"); dev_warn(&dev->dev, "timeout <= pretimeout. Setting pretimeout to zero\n");
......
...@@ -311,10 +311,7 @@ static int esb_probe(struct pci_dev *pdev, ...@@ -311,10 +311,7 @@ static int esb_probe(struct pci_dev *pdev,
edev->wdd.min_timeout = ESB_HEARTBEAT_MIN; edev->wdd.min_timeout = ESB_HEARTBEAT_MIN;
edev->wdd.max_timeout = ESB_HEARTBEAT_MAX; edev->wdd.max_timeout = ESB_HEARTBEAT_MAX;
edev->wdd.timeout = ESB_HEARTBEAT_DEFAULT; edev->wdd.timeout = ESB_HEARTBEAT_DEFAULT;
if (watchdog_init_timeout(&edev->wdd, heartbeat, NULL)) 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_set_nowayout(&edev->wdd, nowayout); watchdog_set_nowayout(&edev->wdd, nowayout);
watchdog_stop_on_reboot(&edev->wdd); watchdog_stop_on_reboot(&edev->wdd);
watchdog_stop_on_unregister(&edev->wdd); watchdog_stop_on_unregister(&edev->wdd);
...@@ -328,8 +325,8 @@ static int esb_probe(struct pci_dev *pdev, ...@@ -328,8 +325,8 @@ static int esb_probe(struct pci_dev *pdev,
goto err_unmap; goto err_unmap;
} }
dev_info(&pdev->dev, dev_info(&pdev->dev,
"initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", "initialized. heartbeat=%d sec (nowayout=%d)\n",
edev->base, edev->wdd.timeout, nowayout); edev->wdd.timeout, nowayout);
return 0; return 0;
err_unmap: err_unmap:
......
...@@ -545,6 +545,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev) ...@@ -545,6 +545,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
} }
watchdog_stop_on_reboot(&p->wddev); watchdog_stop_on_reboot(&p->wddev);
watchdog_stop_on_unregister(&p->wddev);
ret = devm_watchdog_register_device(dev, &p->wddev); ret = devm_watchdog_register_device(dev, &p->wddev);
if (ret != 0) { if (ret != 0) {
pr_err("cannot register watchdog device (err=%d)\n", ret); pr_err("cannot register watchdog device (err=%d)\n", ret);
...@@ -557,17 +558,6 @@ static int iTCO_wdt_probe(struct platform_device *pdev) ...@@ -557,17 +558,6 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
return 0; 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 #ifdef CONFIG_PM_SLEEP
/* /*
* Suspend-to-idle requires this, because it stops the ticks and timekeeping, so * 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 = { ...@@ -620,7 +610,6 @@ static const struct dev_pm_ops iTCO_wdt_pm = {
static struct platform_driver iTCO_wdt_driver = { static struct platform_driver iTCO_wdt_driver = {
.probe = iTCO_wdt_probe, .probe = iTCO_wdt_probe,
.remove = iTCO_wdt_remove,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.pm = ITCO_WDT_PM_OPS, .pm = ITCO_WDT_PM_OPS,
......
...@@ -178,59 +178,69 @@ static const struct watchdog_ops pdc_wdt_ops = { ...@@ -178,59 +178,69 @@ static const struct watchdog_ops pdc_wdt_ops = {
.restart = pdc_wdt_restart, .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) static int pdc_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
u64 div; u64 div;
int ret, val; int ret, val;
unsigned long clk_rate; unsigned long clk_rate;
struct resource *res;
struct pdc_wdt_dev *pdc_wdt; 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) if (!pdc_wdt)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pdc_wdt->base = devm_platform_ioremap_resource(pdev, 0);
pdc_wdt->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pdc_wdt->base)) if (IS_ERR(pdc_wdt->base))
return PTR_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)) { 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); 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)) { 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); return PTR_ERR(pdc_wdt->wdt_clk);
} }
ret = clk_prepare_enable(pdc_wdt->sys_clk); ret = clk_prepare_enable(pdc_wdt->sys_clk);
if (ret) { 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; 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); ret = clk_prepare_enable(pdc_wdt->wdt_clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "could not prepare or enable wdt clock\n"); dev_err(dev, "could not prepare or enable wdt clock\n");
goto disable_sys_clk; 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 */ /* We use the clock rate to calculate the max timeout */
clk_rate = clk_get_rate(pdc_wdt->wdt_clk); clk_rate = clk_get_rate(pdc_wdt->wdt_clk);
if (clk_rate == 0) { if (clk_rate == 0) {
dev_err(&pdev->dev, "failed to get clock rate\n"); dev_err(dev, "failed to get clock rate\n");
ret = -EINVAL; return -EINVAL;
goto disable_wdt_clk;
} }
if (order_base_2(clk_rate) > PDC_WDT_CONFIG_DELAY_MASK + 1) { if (order_base_2(clk_rate) > PDC_WDT_CONFIG_DELAY_MASK + 1) {
dev_err(&pdev->dev, "invalid clock rate\n"); dev_err(dev, "invalid clock rate\n");
ret = -EINVAL; return -EINVAL;
goto disable_wdt_clk;
} }
if (order_base_2(clk_rate) == 0) if (order_base_2(clk_rate) == 0)
...@@ -245,10 +255,10 @@ static int pdc_wdt_probe(struct platform_device *pdev) ...@@ -245,10 +255,10 @@ static int pdc_wdt_probe(struct platform_device *pdev)
do_div(div, clk_rate); do_div(div, clk_rate);
pdc_wdt->wdt_dev.max_timeout = div; pdc_wdt->wdt_dev.max_timeout = div;
pdc_wdt->wdt_dev.timeout = PDC_WDT_DEF_TIMEOUT; 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_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); pdc_wdt_stop(&pdc_wdt->wdt_dev);
...@@ -259,24 +269,22 @@ static int pdc_wdt_probe(struct platform_device *pdev) ...@@ -259,24 +269,22 @@ static int pdc_wdt_probe(struct platform_device *pdev)
case PDC_WDT_TICKLE_STATUS_TICKLE: case PDC_WDT_TICKLE_STATUS_TICKLE:
case PDC_WDT_TICKLE_STATUS_TIMEOUT: case PDC_WDT_TICKLE_STATUS_TIMEOUT:
pdc_wdt->wdt_dev.bootstatus |= WDIOF_CARDRESET; pdc_wdt->wdt_dev.bootstatus |= WDIOF_CARDRESET;
dev_info(&pdev->dev, dev_info(dev, "watchdog module last reset due to timeout\n");
"watchdog module last reset due to timeout\n");
break; break;
case PDC_WDT_TICKLE_STATUS_HRESET: case PDC_WDT_TICKLE_STATUS_HRESET:
dev_info(&pdev->dev, dev_info(dev,
"watchdog module last reset due to hard reset\n"); "watchdog module last reset due to hard reset\n");
break; break;
case PDC_WDT_TICKLE_STATUS_SRESET: case PDC_WDT_TICKLE_STATUS_SRESET:
dev_info(&pdev->dev, dev_info(dev,
"watchdog module last reset due to soft reset\n"); "watchdog module last reset due to soft reset\n");
break; break;
case PDC_WDT_TICKLE_STATUS_USER: case PDC_WDT_TICKLE_STATUS_USER:
dev_info(&pdev->dev, dev_info(dev,
"watchdog module last reset due to user reset\n"); "watchdog module last reset due to user reset\n");
break; break;
default: default:
dev_info(&pdev->dev, dev_info(dev, "contains an illegal status code (%08x)\n", val);
"contains an illegal status code (%08x)\n", val);
break; break;
} }
...@@ -285,36 +293,9 @@ static int pdc_wdt_probe(struct platform_device *pdev) ...@@ -285,36 +293,9 @@ static int pdc_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pdc_wdt); platform_set_drvdata(pdev, pdc_wdt);
ret = watchdog_register_device(&pdc_wdt->wdt_dev); watchdog_stop_on_reboot(&pdc_wdt->wdt_dev);
if (ret) watchdog_stop_on_unregister(&pdc_wdt->wdt_dev);
goto disable_wdt_clk; return devm_watchdog_register_device(dev, &pdc_wdt->wdt_dev);
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;
} }
static const struct of_device_id pdc_wdt_match[] = { static const struct of_device_id pdc_wdt_match[] = {
...@@ -329,8 +310,6 @@ static struct platform_driver pdc_wdt_driver = { ...@@ -329,8 +310,6 @@ static struct platform_driver pdc_wdt_driver = {
.of_match_table = pdc_wdt_match, .of_match_table = pdc_wdt_match,
}, },
.probe = pdc_wdt_probe, .probe = pdc_wdt_probe,
.remove = pdc_wdt_remove,
.shutdown = pdc_wdt_shutdown,
}; };
module_platform_driver(pdc_wdt_driver); module_platform_driver(pdc_wdt_driver);
......
...@@ -178,8 +178,10 @@ static void __imx2_wdt_set_timeout(struct watchdog_device *wdog, ...@@ -178,8 +178,10 @@ static void __imx2_wdt_set_timeout(struct watchdog_device *wdog,
static int imx2_wdt_set_timeout(struct watchdog_device *wdog, static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
unsigned int new_timeout) 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; wdog->timeout = new_timeout;
return 0; return 0;
} }
...@@ -247,7 +249,6 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) ...@@ -247,7 +249,6 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
{ {
struct imx2_wdt_device *wdev; struct imx2_wdt_device *wdev;
struct watchdog_device *wdog; struct watchdog_device *wdog;
struct resource *res;
void __iomem *base; void __iomem *base;
int ret; int ret;
u32 val; u32 val;
...@@ -256,8 +257,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) ...@@ -256,8 +257,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
if (!wdev) if (!wdev)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_platform_ioremap_resource(pdev, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base)) if (IS_ERR(base))
return PTR_ERR(base); return PTR_ERR(base);
......
// 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");
...@@ -110,12 +110,13 @@ static const struct watchdog_ops mid_wdt_ops = { ...@@ -110,12 +110,13 @@ static const struct watchdog_ops mid_wdt_ops = {
static int mid_wdt_probe(struct platform_device *pdev) static int mid_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct watchdog_device *wdt_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; int ret;
if (!pdata) { if (!pdata) {
dev_err(&pdev->dev, "missing platform data\n"); dev_err(dev, "missing platform data\n");
return -EINVAL; return -EINVAL;
} }
...@@ -125,7 +126,7 @@ static int mid_wdt_probe(struct platform_device *pdev) ...@@ -125,7 +126,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
return ret; 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) if (!wdt_dev)
return -ENOMEM; return -ENOMEM;
...@@ -134,16 +135,15 @@ static int mid_wdt_probe(struct platform_device *pdev) ...@@ -134,16 +135,15 @@ static int mid_wdt_probe(struct platform_device *pdev)
wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN; wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN;
wdt_dev->max_timeout = MID_WDT_TIMEOUT_MAX; wdt_dev->max_timeout = MID_WDT_TIMEOUT_MAX;
wdt_dev->timeout = MID_WDT_DEFAULT_TIMEOUT; 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", IRQF_SHARED | IRQF_NO_SUSPEND, "watchdog",
wdt_dev); wdt_dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "error requesting warning irq %d\n", dev_err(dev, "error requesting warning irq %d\n", pdata->irq);
pdata->irq);
return ret; return ret;
} }
...@@ -163,13 +163,13 @@ static int mid_wdt_probe(struct platform_device *pdev) ...@@ -163,13 +163,13 @@ static int mid_wdt_probe(struct platform_device *pdev)
/* Make sure the watchdog is serviced */ /* Make sure the watchdog is serviced */
set_bit(WDOG_HW_RUNNING, &wdt_dev->status); 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) { if (ret) {
dev_err(&pdev->dev, "error registering watchdog device\n"); dev_err(dev, "error registering watchdog device\n");
return ret; return ret;
} }
dev_info(&pdev->dev, "Intel MID watchdog device probed\n"); dev_info(dev, "Intel MID watchdog device probed\n");
return 0; return 0;
} }
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -224,7 +223,7 @@ static int intel_scu_set_heartbeat(u32 t) ...@@ -224,7 +223,7 @@ static int intel_scu_set_heartbeat(u32 t)
watchdog_device.timer_tbl_ptr->freq_hz); watchdog_device.timer_tbl_ptr->freq_hz);
pr_debug("set_heartbeat: timer_set is %x (hex)\n", pr_debug("set_heartbeat: timer_set is %x (hex)\n",
watchdog_device.timer_set); 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", pr_debug("set_heartbeat: threshold is %x (hex)\n",
watchdog_device.threshold); watchdog_device.threshold);
pr_debug("set_heartbeat: soft_threshold is %x (hex)\n", pr_debug("set_heartbeat: soft_threshold is %x (hex)\n",
...@@ -545,21 +544,4 @@ static int __init intel_scu_watchdog_init(void) ...@@ -545,21 +544,4 @@ static int __init intel_scu_watchdog_init(void)
iounmap(watchdog_device.timer_load_count_addr); iounmap(watchdog_device.timer_load_count_addr);
return ret; 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); 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);
...@@ -163,12 +163,12 @@ MODULE_DEVICE_TABLE(of, jz4740_wdt_of_matches); ...@@ -163,12 +163,12 @@ MODULE_DEVICE_TABLE(of, jz4740_wdt_of_matches);
static int jz4740_wdt_probe(struct platform_device *pdev) static int jz4740_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct jz4740_wdt_drvdata *drvdata; struct jz4740_wdt_drvdata *drvdata;
struct watchdog_device *jz4740_wdt; struct watchdog_device *jz4740_wdt;
struct resource *res;
int ret; int ret;
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct jz4740_wdt_drvdata), drvdata = devm_kzalloc(dev, sizeof(struct jz4740_wdt_drvdata),
GFP_KERNEL); GFP_KERNEL);
if (!drvdata) if (!drvdata)
return -ENOMEM; return -ENOMEM;
...@@ -182,27 +182,24 @@ static int jz4740_wdt_probe(struct platform_device *pdev) ...@@ -182,27 +182,24 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
jz4740_wdt->timeout = heartbeat; jz4740_wdt->timeout = heartbeat;
jz4740_wdt->min_timeout = 1; jz4740_wdt->min_timeout = 1;
jz4740_wdt->max_timeout = MAX_HEARTBEAT; jz4740_wdt->max_timeout = MAX_HEARTBEAT;
jz4740_wdt->parent = &pdev->dev; jz4740_wdt->parent = dev;
watchdog_set_nowayout(jz4740_wdt, nowayout); watchdog_set_nowayout(jz4740_wdt, nowayout);
watchdog_set_drvdata(jz4740_wdt, drvdata); watchdog_set_drvdata(jz4740_wdt, drvdata);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); drvdata->base = devm_platform_ioremap_resource(pdev, 0);
drvdata->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(drvdata->base)) if (IS_ERR(drvdata->base))
return PTR_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)) { 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); 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) if (ret < 0)
return ret; return ret;
platform_set_drvdata(pdev, drvdata);
return 0; return 0;
} }
......
...@@ -492,7 +492,9 @@ static int kempld_wdt_probe(struct platform_device *pdev) ...@@ -492,7 +492,9 @@ static int kempld_wdt_probe(struct platform_device *pdev)
} }
platform_set_drvdata(pdev, wdt_data); 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) if (ret)
return ret; return ret;
...@@ -501,26 +503,6 @@ static int kempld_wdt_probe(struct platform_device *pdev) ...@@ -501,26 +503,6 @@ static int kempld_wdt_probe(struct platform_device *pdev)
return 0; 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 #ifdef CONFIG_PM
/* Disable watchdog if it is active during suspend */ /* Disable watchdog if it is active during suspend */
static int kempld_wdt_suspend(struct platform_device *pdev, static int kempld_wdt_suspend(struct platform_device *pdev,
...@@ -567,8 +549,6 @@ static struct platform_driver kempld_wdt_driver = { ...@@ -567,8 +549,6 @@ static struct platform_driver kempld_wdt_driver = {
.name = "kempld-wdt", .name = "kempld-wdt",
}, },
.probe = kempld_wdt_probe, .probe = kempld_wdt_probe,
.remove = kempld_wdt_remove,
.shutdown = kempld_wdt_shutdown,
.suspend = kempld_wdt_suspend, .suspend = kempld_wdt_suspend,
.resume = kempld_wdt_resume, .resume = kempld_wdt_resume,
}; };
......
...@@ -203,7 +203,6 @@ static int ltq_wdt_probe(struct platform_device *pdev) ...@@ -203,7 +203,6 @@ static int ltq_wdt_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct ltq_wdt_priv *priv; struct ltq_wdt_priv *priv;
struct watchdog_device *wdt; struct watchdog_device *wdt;
struct resource *res;
struct clk *clk; struct clk *clk;
const struct ltq_wdt_hw *ltq_wdt_hw; const struct ltq_wdt_hw *ltq_wdt_hw;
int ret; int ret;
...@@ -213,8 +212,7 @@ static int ltq_wdt_probe(struct platform_device *pdev) ...@@ -213,8 +212,7 @@ static int ltq_wdt_probe(struct platform_device *pdev)
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->membase = devm_platform_ioremap_resource(pdev, 0);
priv->membase = devm_ioremap_resource(dev, res);
if (IS_ERR(priv->membase)) if (IS_ERR(priv->membase))
return PTR_ERR(priv->membase); return PTR_ERR(priv->membase);
......
...@@ -83,38 +83,44 @@ static const struct watchdog_ops ls1x_wdt_ops = { ...@@ -83,38 +83,44 @@ static const struct watchdog_ops ls1x_wdt_ops = {
.set_timeout = ls1x_wdt_set_timeout, .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) static int ls1x_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct ls1x_wdt_drvdata *drvdata; struct ls1x_wdt_drvdata *drvdata;
struct watchdog_device *ls1x_wdt; struct watchdog_device *ls1x_wdt;
unsigned long clk_rate; unsigned long clk_rate;
struct resource *res;
int err; int err;
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata) if (!drvdata)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); drvdata->base = devm_platform_ioremap_resource(pdev, 0);
drvdata->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(drvdata->base)) if (IS_ERR(drvdata->base))
return PTR_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)) if (IS_ERR(drvdata->clk))
return PTR_ERR(drvdata->clk); return PTR_ERR(drvdata->clk);
err = clk_prepare_enable(drvdata->clk); err = clk_prepare_enable(drvdata->clk);
if (err) { if (err) {
dev_err(&pdev->dev, "clk enable failed\n"); dev_err(dev, "clk enable failed\n");
return err; 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); clk_rate = clk_get_rate(drvdata->clk);
if (!clk_rate) { if (!clk_rate)
err = -EINVAL; return -EINVAL;
goto err0;
}
drvdata->clk_rate = clk_rate; drvdata->clk_rate = clk_rate;
ls1x_wdt = &drvdata->wdt; ls1x_wdt = &drvdata->wdt;
...@@ -123,41 +129,27 @@ static int ls1x_wdt_probe(struct platform_device *pdev) ...@@ -123,41 +129,27 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
ls1x_wdt->timeout = DEFAULT_HEARTBEAT; ls1x_wdt->timeout = DEFAULT_HEARTBEAT;
ls1x_wdt->min_timeout = 1; ls1x_wdt->min_timeout = 1;
ls1x_wdt->max_hw_heartbeat_ms = U32_MAX / clk_rate * 1000; 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_nowayout(ls1x_wdt, nowayout);
watchdog_set_drvdata(ls1x_wdt, drvdata); watchdog_set_drvdata(ls1x_wdt, drvdata);
err = watchdog_register_device(&drvdata->wdt); err = devm_watchdog_register_device(dev, &drvdata->wdt);
if (err) { if (err) {
dev_err(&pdev->dev, "failed to register watchdog device\n"); dev_err(dev, "failed to register watchdog device\n");
goto err0; return err;
} }
platform_set_drvdata(pdev, drvdata); platform_set_drvdata(pdev, drvdata);
dev_info(&pdev->dev, "Loongson1 Watchdog driver registered\n"); dev_info(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);
return 0; return 0;
} }
static struct platform_driver ls1x_wdt_driver = { static struct platform_driver ls1x_wdt_driver = {
.probe = ls1x_wdt_probe, .probe = ls1x_wdt_probe,
.remove = ls1x_wdt_remove,
.driver = { .driver = {
.name = "ls1x-wdt", .name = "ls1x-wdt",
}, },
......
...@@ -200,19 +200,22 @@ static const struct watchdog_ops lpc18xx_wdt_ops = { ...@@ -200,19 +200,22 @@ static const struct watchdog_ops lpc18xx_wdt_ops = {
.restart = lpc18xx_wdt_restart, .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) static int lpc18xx_wdt_probe(struct platform_device *pdev)
{ {
struct lpc18xx_wdt_dev *lpc18xx_wdt; struct lpc18xx_wdt_dev *lpc18xx_wdt;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct resource *res;
int ret; int ret;
lpc18xx_wdt = devm_kzalloc(dev, sizeof(*lpc18xx_wdt), GFP_KERNEL); lpc18xx_wdt = devm_kzalloc(dev, sizeof(*lpc18xx_wdt), GFP_KERNEL);
if (!lpc18xx_wdt) if (!lpc18xx_wdt)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); lpc18xx_wdt->base = devm_platform_ioremap_resource(pdev, 0);
lpc18xx_wdt->base = devm_ioremap_resource(dev, res);
if (IS_ERR(lpc18xx_wdt->base)) if (IS_ERR(lpc18xx_wdt->base))
return PTR_ERR(lpc18xx_wdt->base); return PTR_ERR(lpc18xx_wdt->base);
...@@ -233,19 +236,26 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev) ...@@ -233,19 +236,26 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev)
dev_err(dev, "could not prepare or enable sys clock\n"); dev_err(dev, "could not prepare or enable sys clock\n");
return ret; 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); ret = clk_prepare_enable(lpc18xx_wdt->wdt_clk);
if (ret) { if (ret) {
dev_err(dev, "could not prepare or enable wdt clock\n"); 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 */ /* We use the clock rate to calculate timeouts */
lpc18xx_wdt->clk_rate = clk_get_rate(lpc18xx_wdt->wdt_clk); lpc18xx_wdt->clk_rate = clk_get_rate(lpc18xx_wdt->wdt_clk);
if (lpc18xx_wdt->clk_rate == 0) { if (lpc18xx_wdt->clk_rate == 0) {
dev_err(dev, "failed to get clock rate\n"); dev_err(dev, "failed to get clock rate\n");
ret = -EINVAL; return -EINVAL;
goto disable_wdt_clk;
} }
lpc18xx_wdt->wdt_dev.info = &lpc18xx_wdt_info; lpc18xx_wdt->wdt_dev.info = &lpc18xx_wdt_info;
...@@ -276,24 +286,8 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev) ...@@ -276,24 +286,8 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, lpc18xx_wdt); platform_set_drvdata(pdev, lpc18xx_wdt);
ret = watchdog_register_device(&lpc18xx_wdt->wdt_dev); watchdog_stop_on_reboot(&lpc18xx_wdt->wdt_dev);
if (ret) return devm_watchdog_register_device(dev, &lpc18xx_wdt->wdt_dev);
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);
} }
static int lpc18xx_wdt_remove(struct platform_device *pdev) static int lpc18xx_wdt_remove(struct platform_device *pdev)
...@@ -303,10 +297,6 @@ 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"); dev_warn(&pdev->dev, "I quit now, hardware will probably reboot!\n");
del_timer(&lpc18xx_wdt->timer); 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; return 0;
} }
...@@ -323,7 +313,6 @@ static struct platform_driver lpc18xx_wdt_driver = { ...@@ -323,7 +313,6 @@ static struct platform_driver lpc18xx_wdt_driver = {
}, },
.probe = lpc18xx_wdt_probe, .probe = lpc18xx_wdt_probe,
.remove = lpc18xx_wdt_remove, .remove = lpc18xx_wdt_remove,
.shutdown = lpc18xx_wdt_shutdown,
}; };
module_platform_driver(lpc18xx_wdt_driver); module_platform_driver(lpc18xx_wdt_driver);
......
...@@ -177,6 +177,7 @@ static inline void zf_set_timer(unsigned short new, unsigned char n) ...@@ -177,6 +177,7 @@ static inline void zf_set_timer(unsigned short new, unsigned char n)
switch (n) { switch (n) {
case WD1: case WD1:
zf_writew(COUNTER_1, new); zf_writew(COUNTER_1, new);
/* fall through */
case WD2: case WD2:
zf_writeb(COUNTER_2, new > 0xff ? 0xff : new); zf_writeb(COUNTER_2, new > 0xff ? 0xff : new);
default: default:
...@@ -318,7 +319,7 @@ static long zf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -318,7 +319,7 @@ static long zf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case WDIOC_GETBOOTSTATUS: case WDIOC_GETBOOTSTATUS:
return put_user(0, p); return put_user(0, p);
case WDIOC_KEEPALIVE: case WDIOC_KEEPALIVE:
zf_ping(0); zf_ping(NULL);
break; break;
default: default:
return -ENOTTY; return -ENOTTY;
......
...@@ -187,9 +187,7 @@ static void max63xx_mmap_set(struct max63xx_wdt *wdt, u8 set) ...@@ -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) 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_platform_ioremap_resource(p, 0);
wdt->base = devm_ioremap_resource(&p->dev, mem);
if (IS_ERR(wdt->base)) if (IS_ERR(wdt->base))
return PTR_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) ...@@ -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) static int max63xx_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct max63xx_wdt *wdt; struct max63xx_wdt *wdt;
struct max63xx_timeout *table; struct max63xx_timeout *table;
int err; int err;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
...@@ -217,7 +216,7 @@ static int max63xx_wdt_probe(struct platform_device *pdev) ...@@ -217,7 +216,7 @@ static int max63xx_wdt_probe(struct platform_device *pdev)
wdt->timeout = max63xx_select_timeout(table, heartbeat); wdt->timeout = max63xx_select_timeout(table, heartbeat);
if (!wdt->timeout) { 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); heartbeat);
return -EINVAL; return -EINVAL;
} }
...@@ -229,30 +228,22 @@ static int max63xx_wdt_probe(struct platform_device *pdev) ...@@ -229,30 +228,22 @@ static int max63xx_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &wdt->wdd); platform_set_drvdata(pdev, &wdt->wdd);
watchdog_set_drvdata(&wdt->wdd, wdt); watchdog_set_drvdata(&wdt->wdd, wdt);
wdt->wdd.parent = &pdev->dev; wdt->wdd.parent = dev;
wdt->wdd.timeout = wdt->timeout->twd; wdt->wdd.timeout = wdt->timeout->twd;
wdt->wdd.info = &max63xx_wdt_info; wdt->wdd.info = &max63xx_wdt_info;
wdt->wdd.ops = &max63xx_wdt_ops; wdt->wdd.ops = &max63xx_wdt_ops;
watchdog_set_nowayout(&wdt->wdd, nowayout); watchdog_set_nowayout(&wdt->wdd, nowayout);
err = watchdog_register_device(&wdt->wdd); err = devm_watchdog_register_device(dev, &wdt->wdd);
if (err) if (err)
return 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); wdt->timeout->twd, wdt->timeout->tdelay);
return 0; 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[] = { static const struct platform_device_id max63xx_id_table[] = {
{ "max6369_wdt", (kernel_ulong_t)max6369_table, }, { "max6369_wdt", (kernel_ulong_t)max6369_table, },
{ "max6370_wdt", (kernel_ulong_t)max6369_table, }, { "max6370_wdt", (kernel_ulong_t)max6369_table, },
...@@ -266,7 +257,6 @@ MODULE_DEVICE_TABLE(platform, max63xx_id_table); ...@@ -266,7 +257,6 @@ MODULE_DEVICE_TABLE(platform, max63xx_id_table);
static struct platform_driver max63xx_wdt_driver = { static struct platform_driver max63xx_wdt_driver = {
.probe = max63xx_wdt_probe, .probe = max63xx_wdt_probe,
.remove = max63xx_wdt_remove,
.id_table = max63xx_id_table, .id_table = max63xx_id_table,
.driver = { .driver = {
.name = "max63xx_wdt", .name = "max63xx_wdt",
......
...@@ -112,17 +112,18 @@ static const struct watchdog_ops max77620_wdt_ops = { ...@@ -112,17 +112,18 @@ static const struct watchdog_ops max77620_wdt_ops = {
static int max77620_wdt_probe(struct platform_device *pdev) static int max77620_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct max77620_wdt *wdt; struct max77620_wdt *wdt;
struct watchdog_device *wdt_dev; struct watchdog_device *wdt_dev;
unsigned int regval; unsigned int regval;
int ret; int ret;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
wdt->dev = &pdev->dev; wdt->dev = dev;
wdt->rmap = dev_get_regmap(pdev->dev.parent, NULL); wdt->rmap = dev_get_regmap(dev->parent, NULL);
if (!wdt->rmap) { if (!wdt->rmap) {
dev_err(wdt->dev, "Failed to get parent regmap\n"); dev_err(wdt->dev, "Failed to get parent regmap\n");
return -ENODEV; return -ENODEV;
...@@ -183,25 +184,16 @@ static int max77620_wdt_probe(struct platform_device *pdev) ...@@ -183,25 +184,16 @@ static int max77620_wdt_probe(struct platform_device *pdev)
watchdog_set_nowayout(wdt_dev, nowayout); watchdog_set_nowayout(wdt_dev, nowayout);
watchdog_set_drvdata(wdt_dev, wdt); 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) { 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 ret;
} }
return 0; 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[] = { static const struct platform_device_id max77620_wdt_devtype[] = {
{ .name = "max77620-watchdog", }, { .name = "max77620-watchdog", },
{ }, { },
...@@ -213,7 +205,6 @@ static struct platform_driver max77620_wdt_driver = { ...@@ -213,7 +205,6 @@ static struct platform_driver max77620_wdt_driver = {
.name = "max77620-watchdog", .name = "max77620-watchdog",
}, },
.probe = max77620_wdt_probe, .probe = max77620_wdt_probe,
.remove = max77620_wdt_remove,
.id_table = max77620_wdt_devtype, .id_table = max77620_wdt_devtype,
}; };
......
...@@ -127,19 +127,20 @@ static struct watchdog_device a21_wdt = { ...@@ -127,19 +127,20 @@ static struct watchdog_device a21_wdt = {
static int a21_wdt_probe(struct platform_device *pdev) static int a21_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct a21_wdt_drv *drv; struct a21_wdt_drv *drv;
unsigned int reset = 0; unsigned int reset = 0;
int num_gpios; int num_gpios;
int ret; int ret;
int i; 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) if (!drv)
return -ENOMEM; return -ENOMEM;
num_gpios = gpiod_count(&pdev->dev, NULL); num_gpios = gpiod_count(dev, NULL);
if (num_gpios != NUM_GPIOS) { 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); num_gpios, NUM_GPIOS);
return -ENODEV; return -ENODEV;
} }
...@@ -152,12 +153,9 @@ static int a21_wdt_probe(struct platform_device *pdev) ...@@ -152,12 +153,9 @@ static int a21_wdt_probe(struct platform_device *pdev)
gflags = GPIOD_ASIS; gflags = GPIOD_ASIS;
else else
gflags = GPIOD_IN; gflags = GPIOD_IN;
drv->gpios[i] = devm_gpiod_get_index(&pdev->dev, NULL, i, drv->gpios[i] = devm_gpiod_get_index(dev, NULL, i, gflags);
gflags); if (IS_ERR(drv->gpios[i]))
if (IS_ERR(drv->gpios[i])) { return PTR_ERR(drv->gpios[i]);
ret = PTR_ERR(drv->gpios[i]);
return ret;
}
gpiod_set_consumer_name(drv->gpios[i], "MEN A21 Watchdog"); gpiod_set_consumer_name(drv->gpios[i], "MEN A21 Watchdog");
...@@ -173,10 +171,10 @@ static int a21_wdt_probe(struct platform_device *pdev) ...@@ -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_nowayout(&a21_wdt, nowayout);
watchdog_set_drvdata(&a21_wdt, drv); watchdog_set_drvdata(&a21_wdt, drv);
a21_wdt.parent = &pdev->dev; a21_wdt.parent = dev;
reset = a21_wdt_get_bootstatus(drv); reset = a21_wdt_get_bootstatus(drv);
if (reset == 2) if (reset == 2)
...@@ -189,15 +187,15 @@ static int a21_wdt_probe(struct platform_device *pdev) ...@@ -189,15 +187,15 @@ static int a21_wdt_probe(struct platform_device *pdev)
a21_wdt.bootstatus |= WDIOF_EXTERN2; a21_wdt.bootstatus |= WDIOF_EXTERN2;
drv->wdt = a21_wdt; 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) { if (ret) {
dev_err(&pdev->dev, "Cannot register watchdog device\n"); dev_err(dev, "Cannot register watchdog device\n");
return ret; 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; return 0;
} }
......
...@@ -117,12 +117,12 @@ static const struct watchdog_ops menf21bmc_wdt_ops = { ...@@ -117,12 +117,12 @@ static const struct watchdog_ops menf21bmc_wdt_ops = {
static int menf21bmc_wdt_probe(struct platform_device *pdev) static int menf21bmc_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
int ret, bmc_timeout; int ret, bmc_timeout;
struct menf21bmc_wdt *drv_data; 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, drv_data = devm_kzalloc(dev, sizeof(struct menf21bmc_wdt), GFP_KERNEL);
sizeof(struct menf21bmc_wdt), GFP_KERNEL);
if (!drv_data) if (!drv_data)
return -ENOMEM; return -ENOMEM;
...@@ -130,7 +130,7 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev) ...@@ -130,7 +130,7 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev)
drv_data->wdt.info = &menf21bmc_wdt_info; drv_data->wdt.info = &menf21bmc_wdt_info;
drv_data->wdt.min_timeout = BMC_WD_TIMEOUT_MIN; drv_data->wdt.min_timeout = BMC_WD_TIMEOUT_MIN;
drv_data->wdt.max_timeout = BMC_WD_TIMEOUT_MAX; 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; drv_data->i2c_client = i2c_client;
/* /*
...@@ -140,40 +140,28 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev) ...@@ -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_timeout = i2c_smbus_read_word_data(drv_data->i2c_client,
BMC_CMD_WD_TIME); BMC_CMD_WD_TIME);
if (bmc_timeout < 0) { 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; 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_nowayout(&drv_data->wdt, nowayout);
watchdog_set_drvdata(&drv_data->wdt, drv_data); watchdog_set_drvdata(&drv_data->wdt, drv_data);
platform_set_drvdata(pdev, drv_data); platform_set_drvdata(pdev, drv_data);
ret = menf21bmc_wdt_set_bootstatus(drv_data); ret = menf21bmc_wdt_set_bootstatus(drv_data);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "failed to set Watchdog bootstatus\n"); dev_err(dev, "failed to set Watchdog bootstatus\n");
return ret; return ret;
} }
ret = watchdog_register_device(&drv_data->wdt); ret = devm_watchdog_register_device(dev, &drv_data->wdt);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register Watchdog device\n"); dev_err(dev, "failed to register Watchdog device\n");
return ret; return ret;
} }
dev_info(&pdev->dev, "MEN 14F021P00 BMC Watchdog device enabled\n"); dev_info(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);
return 0; return 0;
} }
...@@ -191,7 +179,6 @@ static struct platform_driver menf21bmc_wdt = { ...@@ -191,7 +179,6 @@ static struct platform_driver menf21bmc_wdt = {
.name = DEVNAME, .name = DEVNAME,
}, },
.probe = menf21bmc_wdt_probe, .probe = menf21bmc_wdt_probe,
.remove = menf21bmc_wdt_remove,
.shutdown = menf21bmc_wdt_shutdown, .shutdown = menf21bmc_wdt_shutdown,
}; };
......
...@@ -136,32 +136,40 @@ static const struct of_device_id meson_gxbb_wdt_dt_ids[] = { ...@@ -136,32 +136,40 @@ static const struct of_device_id meson_gxbb_wdt_dt_ids[] = {
}; };
MODULE_DEVICE_TABLE(of, 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) static int meson_gxbb_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct meson_gxbb_wdt *data; struct meson_gxbb_wdt *data;
struct resource *res;
int ret; int ret;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); data->reg_base = devm_platform_ioremap_resource(pdev, 0);
data->reg_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(data->reg_base)) if (IS_ERR(data->reg_base))
return PTR_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)) if (IS_ERR(data->clk))
return PTR_ERR(data->clk); return PTR_ERR(data->clk);
ret = clk_prepare_enable(data->clk); ret = clk_prepare_enable(data->clk);
if (ret) if (ret)
return 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); 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.info = &meson_gxbb_wdt_info;
data->wdt_dev.ops = &meson_gxbb_wdt_ops; data->wdt_dev.ops = &meson_gxbb_wdt_ops;
data->wdt_dev.max_hw_heartbeat_ms = GXBB_WDT_TCNT_SETUP_MASK; 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) ...@@ -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); meson_gxbb_wdt_set_timeout(&data->wdt_dev, data->wdt_dev.timeout);
ret = watchdog_register_device(&data->wdt_dev); watchdog_stop_on_reboot(&data->wdt_dev);
if (ret) { return devm_watchdog_register_device(dev, &data->wdt_dev);
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);
} }
static struct platform_driver meson_gxbb_wdt_driver = { static struct platform_driver meson_gxbb_wdt_driver = {
.probe = meson_gxbb_wdt_probe, .probe = meson_gxbb_wdt_probe,
.remove = meson_gxbb_wdt_remove,
.shutdown = meson_gxbb_wdt_shutdown,
.driver = { .driver = {
.name = "meson-gxbb-wdt", .name = "meson-gxbb-wdt",
.pm = &meson_gxbb_wdt_pm_ops, .pm = &meson_gxbb_wdt_pm_ops,
......
...@@ -164,28 +164,27 @@ MODULE_DEVICE_TABLE(of, meson_wdt_dt_ids); ...@@ -164,28 +164,27 @@ MODULE_DEVICE_TABLE(of, meson_wdt_dt_ids);
static int meson_wdt_probe(struct platform_device *pdev) static int meson_wdt_probe(struct platform_device *pdev)
{ {
struct resource *res; struct device *dev = &pdev->dev;
struct meson_wdt_dev *meson_wdt; struct meson_wdt_dev *meson_wdt;
const struct of_device_id *of_id; const struct of_device_id *of_id;
int err; 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) if (!meson_wdt)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); meson_wdt->wdt_base = devm_platform_ioremap_resource(pdev, 0);
meson_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(meson_wdt->wdt_base)) if (IS_ERR(meson_wdt->wdt_base))
return PTR_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) { if (!of_id) {
dev_err(&pdev->dev, "Unable to initialize WDT data\n"); dev_err(dev, "Unable to initialize WDT data\n");
return -ENODEV; return -ENODEV;
} }
meson_wdt->data = of_id->data; 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.info = &meson_wdt_info;
meson_wdt->wdt_dev.ops = &meson_wdt_ops; meson_wdt->wdt_dev.ops = &meson_wdt_ops;
meson_wdt->wdt_dev.max_timeout = meson_wdt->wdt_dev.max_timeout =
...@@ -197,18 +196,18 @@ static int meson_wdt_probe(struct platform_device *pdev) ...@@ -197,18 +196,18 @@ static int meson_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(&meson_wdt->wdt_dev, meson_wdt); 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_nowayout(&meson_wdt->wdt_dev, nowayout);
watchdog_set_restart_priority(&meson_wdt->wdt_dev, 128); watchdog_set_restart_priority(&meson_wdt->wdt_dev, 128);
meson_wdt_stop(&meson_wdt->wdt_dev); meson_wdt_stop(&meson_wdt->wdt_dev);
watchdog_stop_on_reboot(&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) if (err)
return 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); meson_wdt->wdt_dev.timeout, nowayout);
return 0; return 0;
......
...@@ -233,20 +233,21 @@ static int mlxreg_wdt_init_timeout(struct mlxreg_wdt *wdt, ...@@ -233,20 +233,21 @@ static int mlxreg_wdt_init_timeout(struct mlxreg_wdt *wdt,
static int mlxreg_wdt_probe(struct platform_device *pdev) static int mlxreg_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct mlxreg_core_platform_data *pdata; struct mlxreg_core_platform_data *pdata;
struct mlxreg_wdt *wdt; struct mlxreg_wdt *wdt;
int rc; int rc;
pdata = dev_get_platdata(&pdev->dev); pdata = dev_get_platdata(dev);
if (!pdata) { if (!pdata) {
dev_err(&pdev->dev, "Failed to get platform data.\n"); dev_err(dev, "Failed to get platform data.\n");
return -EINVAL; return -EINVAL;
} }
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
wdt->wdd.parent = &pdev->dev; wdt->wdd.parent = dev;
wdt->regmap = pdata->regmap; wdt->regmap = pdata->regmap;
mlxreg_wdt_config(wdt, pdata); mlxreg_wdt_config(wdt, pdata);
...@@ -266,12 +267,11 @@ static int mlxreg_wdt_probe(struct platform_device *pdev) ...@@ -266,12 +267,11 @@ static int mlxreg_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
} }
mlxreg_wdt_check_card_reset(wdt); 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: register_error:
if (rc) if (rc)
dev_err(&pdev->dev, dev_err(dev, "Cannot register watchdog device (err=%d)\n", rc);
"Cannot register watchdog device (err=%d)\n", rc);
return rc; return rc;
} }
......
...@@ -91,8 +91,6 @@ static int moxart_wdt_probe(struct platform_device *pdev) ...@@ -91,8 +91,6 @@ static int moxart_wdt_probe(struct platform_device *pdev)
{ {
struct moxart_wdt_dev *moxart_wdt; struct moxart_wdt_dev *moxart_wdt;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct resource *res;
struct clk *clk; struct clk *clk;
int err; int err;
unsigned int max_timeout; unsigned int max_timeout;
...@@ -104,12 +102,11 @@ static int moxart_wdt_probe(struct platform_device *pdev) ...@@ -104,12 +102,11 @@ static int moxart_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, moxart_wdt); platform_set_drvdata(pdev, moxart_wdt);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); moxart_wdt->base = devm_platform_ioremap_resource(pdev, 0);
moxart_wdt->base = devm_ioremap_resource(dev, res);
if (IS_ERR(moxart_wdt->base)) if (IS_ERR(moxart_wdt->base))
return PTR_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)) { if (IS_ERR(clk)) {
pr_err("%s: of_clk_get failed\n", __func__); pr_err("%s: of_clk_get failed\n", __func__);
return PTR_ERR(clk); return PTR_ERR(clk);
...@@ -136,7 +133,8 @@ static int moxart_wdt_probe(struct platform_device *pdev) ...@@ -136,7 +133,8 @@ static int moxart_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(&moxart_wdt->dev, moxart_wdt); 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) if (err)
return err; return err;
...@@ -146,15 +144,6 @@ static int moxart_wdt_probe(struct platform_device *pdev) ...@@ -146,15 +144,6 @@ static int moxart_wdt_probe(struct platform_device *pdev)
return 0; 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[] = { static const struct of_device_id moxart_watchdog_match[] = {
{ .compatible = "moxa,moxart-watchdog" }, { .compatible = "moxa,moxart-watchdog" },
{ }, { },
...@@ -163,7 +152,6 @@ MODULE_DEVICE_TABLE(of, moxart_watchdog_match); ...@@ -163,7 +152,6 @@ MODULE_DEVICE_TABLE(of, moxart_watchdog_match);
static struct platform_driver moxart_wdt_driver = { static struct platform_driver moxart_wdt_driver = {
.probe = moxart_wdt_probe, .probe = moxart_wdt_probe,
.remove = moxart_wdt_remove,
.driver = { .driver = {
.name = "moxart-watchdog", .name = "moxart-watchdog",
.of_match_table = moxart_watchdog_match, .of_match_table = moxart_watchdog_match,
......
...@@ -149,8 +149,7 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev) ...@@ -149,8 +149,7 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
if (!ddata) if (!ddata)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); ddata->base = devm_platform_ioremap_resource(ofdev, 0);
ddata->base = devm_ioremap_resource(dev, res);
if (IS_ERR(ddata->base)) if (IS_ERR(ddata->base))
return PTR_ERR(ddata->base); return PTR_ERR(ddata->base);
...@@ -205,9 +204,10 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev) ...@@ -205,9 +204,10 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
if (ddata->wdd.timeout < ddata->wdd.min_timeout) if (ddata->wdd.timeout < ddata->wdd.min_timeout)
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) { 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; return ret;
} }
...@@ -219,17 +219,6 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev) ...@@ -219,17 +219,6 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
return 0; 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[] = { static const struct of_device_id mpc8xxx_wdt_match[] = {
{ {
.compatible = "mpc83xx_wdt", .compatible = "mpc83xx_wdt",
...@@ -260,7 +249,6 @@ MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match); ...@@ -260,7 +249,6 @@ MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match);
static struct platform_driver mpc8xxx_wdt_driver = { static struct platform_driver mpc8xxx_wdt_driver = {
.probe = mpc8xxx_wdt_probe, .probe = mpc8xxx_wdt_probe,
.remove = mpc8xxx_wdt_remove,
.driver = { .driver = {
.name = "mpc8xxx_wdt", .name = "mpc8xxx_wdt",
.of_match_table = mpc8xxx_wdt_match, .of_match_table = mpc8xxx_wdt_match,
......
...@@ -133,21 +133,19 @@ static struct watchdog_device mt7621_wdt_dev = { ...@@ -133,21 +133,19 @@ static struct watchdog_device mt7621_wdt_dev = {
static int mt7621_wdt_probe(struct platform_device *pdev) static int mt7621_wdt_probe(struct platform_device *pdev)
{ {
struct resource *res; struct device *dev = &pdev->dev;
mt7621_wdt_base = devm_platform_ioremap_resource(pdev, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mt7621_wdt_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mt7621_wdt_base)) if (IS_ERR(mt7621_wdt_base))
return PTR_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)) if (!IS_ERR(mt7621_wdt_reset))
reset_control_deassert(mt7621_wdt_reset); reset_control_deassert(mt7621_wdt_reset);
mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause(); mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause();
watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout, watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout,
&pdev->dev); dev);
watchdog_set_nowayout(&mt7621_wdt_dev, nowayout); watchdog_set_nowayout(&mt7621_wdt_dev, nowayout);
if (mt7621_wdt_is_running(&mt7621_wdt_dev)) { if (mt7621_wdt_is_running(&mt7621_wdt_dev)) {
/* /*
...@@ -164,7 +162,7 @@ static int mt7621_wdt_probe(struct platform_device *pdev) ...@@ -164,7 +162,7 @@ static int mt7621_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &mt7621_wdt_dev.status); 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) static void mt7621_wdt_shutdown(struct platform_device *pdev)
......
...@@ -153,18 +153,17 @@ static const struct watchdog_ops mtk_wdt_ops = { ...@@ -153,18 +153,17 @@ static const struct watchdog_ops mtk_wdt_ops = {
static int mtk_wdt_probe(struct platform_device *pdev) static int mtk_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct mtk_wdt_dev *mtk_wdt; struct mtk_wdt_dev *mtk_wdt;
struct resource *res;
int err; 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) if (!mtk_wdt)
return -ENOMEM; return -ENOMEM;
platform_set_drvdata(pdev, mtk_wdt); platform_set_drvdata(pdev, mtk_wdt);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mtk_wdt->wdt_base = devm_platform_ioremap_resource(pdev, 0);
mtk_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mtk_wdt->wdt_base)) if (IS_ERR(mtk_wdt->wdt_base))
return PTR_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) ...@@ -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.timeout = WDT_MAX_TIMEOUT;
mtk_wdt->wdt_dev.max_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.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_nowayout(&mtk_wdt->wdt_dev, nowayout);
watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128); watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128);
...@@ -183,33 +182,17 @@ static int mtk_wdt_probe(struct platform_device *pdev) ...@@ -183,33 +182,17 @@ static int mtk_wdt_probe(struct platform_device *pdev)
mtk_wdt_stop(&mtk_wdt->wdt_dev); 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)) if (unlikely(err))
return err; return err;
dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", dev_info(dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n",
mtk_wdt->wdt_dev.timeout, nowayout); mtk_wdt->wdt_dev.timeout, nowayout);
return 0; 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);
return 0;
}
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int mtk_wdt_suspend(struct device *dev) static int mtk_wdt_suspend(struct device *dev)
{ {
...@@ -247,8 +230,6 @@ static const struct dev_pm_ops mtk_wdt_pm_ops = { ...@@ -247,8 +230,6 @@ static const struct dev_pm_ops mtk_wdt_pm_ops = {
static struct platform_driver mtk_wdt_driver = { static struct platform_driver mtk_wdt_driver = {
.probe = mtk_wdt_probe, .probe = mtk_wdt_probe,
.remove = mtk_wdt_remove,
.shutdown = mtk_wdt_shutdown,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.pm = &mtk_wdt_pm_ops, .pm = &mtk_wdt_pm_ops,
......
...@@ -217,9 +217,7 @@ static int ni903x_acpi_add(struct acpi_device *device) ...@@ -217,9 +217,7 @@ static int ni903x_acpi_add(struct acpi_device *device)
wdd->parent = dev; wdd->parent = dev;
watchdog_set_drvdata(wdd, wdt); watchdog_set_drvdata(wdd, wdt);
watchdog_set_nowayout(wdd, nowayout); watchdog_set_nowayout(wdd, nowayout);
ret = watchdog_init_timeout(wdd, timeout, dev); watchdog_init_timeout(wdd, timeout, dev);
if (ret)
dev_err(dev, "unable to set timeout value, using default\n");
ret = watchdog_register_device(wdd); ret = watchdog_register_device(wdd);
if (ret) { if (ret) {
......
...@@ -211,10 +211,7 @@ static int nic7018_probe(struct platform_device *pdev) ...@@ -211,10 +211,7 @@ static int nic7018_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdd, wdt); watchdog_set_drvdata(wdd, wdt);
watchdog_set_nowayout(wdd, nowayout); watchdog_set_nowayout(wdd, nowayout);
watchdog_init_timeout(wdd, timeout, dev);
ret = watchdog_init_timeout(wdd, timeout, dev);
if (ret)
dev_warn(dev, "unable to set timeout value, using default\n");
/* Unlock WDT register */ /* Unlock WDT register */
outb(UNLOCK, wdt->io_base + WDT_REG_LOCK); outb(UNLOCK, wdt->io_base + WDT_REG_LOCK);
......
...@@ -181,16 +181,14 @@ static int npcm_wdt_probe(struct platform_device *pdev) ...@@ -181,16 +181,14 @@ static int npcm_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct npcm_wdt *wdt; struct npcm_wdt *wdt;
struct resource *res;
int irq; int irq;
int ret; int ret;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->reg = devm_platform_ioremap_resource(pdev, 0);
wdt->reg = devm_ioremap_resource(dev, res);
if (IS_ERR(wdt->reg)) if (IS_ERR(wdt->reg))
return PTR_ERR(wdt->reg); return PTR_ERR(wdt->reg);
...@@ -216,8 +214,8 @@ static int npcm_wdt_probe(struct platform_device *pdev) ...@@ -216,8 +214,8 @@ static int npcm_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
} }
ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0, ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0, "watchdog",
"watchdog", wdt); wdt);
if (ret) if (ret)
return ret; return ret;
......
...@@ -242,7 +242,6 @@ static struct miscdevice nuc900wdt_miscdev = { ...@@ -242,7 +242,6 @@ static struct miscdevice nuc900wdt_miscdev = {
static int nuc900wdt_probe(struct platform_device *pdev) static int nuc900wdt_probe(struct platform_device *pdev)
{ {
struct resource *res;
int ret = 0; int ret = 0;
nuc900_wdt = devm_kzalloc(&pdev->dev, sizeof(*nuc900_wdt), nuc900_wdt = devm_kzalloc(&pdev->dev, sizeof(*nuc900_wdt),
...@@ -254,8 +253,7 @@ static int nuc900wdt_probe(struct platform_device *pdev) ...@@ -254,8 +253,7 @@ static int nuc900wdt_probe(struct platform_device *pdev)
spin_lock_init(&nuc900_wdt->wdt_lock); spin_lock_init(&nuc900_wdt->wdt_lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); nuc900_wdt->wdt_base = devm_platform_ioremap_resource(pdev, 0);
nuc900_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(nuc900_wdt->wdt_base)) if (IS_ERR(nuc900_wdt->wdt_base))
return PTR_ERR(nuc900_wdt->wdt_base); return PTR_ERR(nuc900_wdt->wdt_base);
......
...@@ -151,43 +151,46 @@ static u32 xwdt_selftest(struct xwdt_device *xdev) ...@@ -151,43 +151,46 @@ static u32 xwdt_selftest(struct xwdt_device *xdev)
return XWT_TIMER_FAILED; return XWT_TIMER_FAILED;
} }
static void xwdt_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
static int xwdt_probe(struct platform_device *pdev) static int xwdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
int rc; int rc;
u32 pfreq = 0, enable_once = 0; u32 pfreq = 0, enable_once = 0;
struct resource *res;
struct xwdt_device *xdev; struct xwdt_device *xdev;
struct watchdog_device *xilinx_wdt_wdd; 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) if (!xdev)
return -ENOMEM; return -ENOMEM;
xilinx_wdt_wdd = &xdev->xilinx_wdt_wdd; xilinx_wdt_wdd = &xdev->xilinx_wdt_wdd;
xilinx_wdt_wdd->info = &xilinx_wdt_ident; xilinx_wdt_wdd->info = &xilinx_wdt_ident;
xilinx_wdt_wdd->ops = &xilinx_wdt_ops; 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_platform_ioremap_resource(pdev, 0);
xdev->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(xdev->base)) if (IS_ERR(xdev->base))
return PTR_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); &xdev->wdt_interval);
if (rc) if (rc)
dev_warn(&pdev->dev, dev_warn(dev, "Parameter \"xlnx,wdt-interval\" not found\n");
"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); &enable_once);
if (rc) if (rc)
dev_warn(&pdev->dev, dev_warn(dev,
"Parameter \"xlnx,wdt-enable-once\" not found\n"); "Parameter \"xlnx,wdt-enable-once\" not found\n");
watchdog_set_nowayout(xilinx_wdt_wdd, enable_once); 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 (IS_ERR(xdev->clk)) {
if (PTR_ERR(xdev->clk) != -ENOENT) if (PTR_ERR(xdev->clk) != -ENOENT)
return PTR_ERR(xdev->clk); return PTR_ERR(xdev->clk);
...@@ -198,10 +201,10 @@ static int xwdt_probe(struct platform_device *pdev) ...@@ -198,10 +201,10 @@ static int xwdt_probe(struct platform_device *pdev)
*/ */
xdev->clk = NULL; 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); &pfreq);
if (rc) if (rc)
dev_warn(&pdev->dev, dev_warn(dev,
"The watchdog clock freq cannot be obtained\n"); "The watchdog clock freq cannot be obtained\n");
} else { } else {
pfreq = clk_get_rate(xdev->clk); pfreq = clk_get_rate(xdev->clk);
...@@ -220,43 +223,33 @@ static int xwdt_probe(struct platform_device *pdev) ...@@ -220,43 +223,33 @@ static int xwdt_probe(struct platform_device *pdev)
rc = clk_prepare_enable(xdev->clk); rc = clk_prepare_enable(xdev->clk);
if (rc) { if (rc) {
dev_err(&pdev->dev, "unable to enable clock\n"); dev_err(dev, "unable to enable clock\n");
return rc; return rc;
} }
rc = devm_add_action_or_reset(dev, xwdt_clk_disable_unprepare,
xdev->clk);
if (rc)
return rc;
rc = xwdt_selftest(xdev); rc = xwdt_selftest(xdev);
if (rc == XWT_TIMER_FAILED) { if (rc == XWT_TIMER_FAILED) {
dev_err(&pdev->dev, "SelfTest routine error\n"); dev_err(dev, "SelfTest routine error\n");
goto err_clk_disable; return rc;
} }
rc = watchdog_register_device(xilinx_wdt_wdd); rc = devm_watchdog_register_device(dev, xilinx_wdt_wdd);
if (rc) { if (rc) {
dev_err(&pdev->dev, "Cannot register watchdog (err=%d)\n", rc); dev_err(dev, "Cannot register watchdog (err=%d)\n", rc);
goto err_clk_disable; return rc;
} }
clk_disable(xdev->clk); 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); xdev->base, xilinx_wdt_wdd->timeout);
platform_set_drvdata(pdev, xdev); 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; return 0;
} }
...@@ -305,7 +298,6 @@ MODULE_DEVICE_TABLE(of, xwdt_of_match); ...@@ -305,7 +298,6 @@ MODULE_DEVICE_TABLE(of, xwdt_of_match);
static struct platform_driver xwdt_driver = { static struct platform_driver xwdt_driver = {
.probe = xwdt_probe, .probe = xwdt_probe,
.remove = xwdt_remove,
.driver = { .driver = {
.name = WATCHDOG_NAME, .name = WATCHDOG_NAME,
.of_match_table = xwdt_of_match, .of_match_table = xwdt_of_match,
......
...@@ -231,7 +231,6 @@ static const struct watchdog_ops omap_wdt_ops = { ...@@ -231,7 +231,6 @@ static const struct watchdog_ops omap_wdt_ops = {
static int omap_wdt_probe(struct platform_device *pdev) static int omap_wdt_probe(struct platform_device *pdev)
{ {
struct omap_wd_timer_platform_data *pdata = dev_get_platdata(&pdev->dev); struct omap_wd_timer_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct resource *res;
struct omap_wdt_dev *wdev; struct omap_wdt_dev *wdev;
int ret; int ret;
...@@ -245,8 +244,7 @@ static int omap_wdt_probe(struct platform_device *pdev) ...@@ -245,8 +244,7 @@ static int omap_wdt_probe(struct platform_device *pdev)
mutex_init(&wdev->lock); mutex_init(&wdev->lock);
/* reserve static register mappings */ /* reserve static register mappings */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdev->base = devm_platform_ioremap_resource(pdev, 0);
wdev->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(wdev->base)) if (IS_ERR(wdev->base))
return PTR_ERR(wdev->base); return PTR_ERR(wdev->base);
......
...@@ -349,13 +349,6 @@ static unsigned int orion_wdt_get_timeleft(struct watchdog_device *wdt_dev) ...@@ -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; 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 = { static const struct watchdog_info orion_wdt_info = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.identity = "Orion Watchdog", .identity = "Orion Watchdog",
...@@ -366,7 +359,6 @@ static const struct watchdog_ops orion_wdt_ops = { ...@@ -366,7 +359,6 @@ static const struct watchdog_ops orion_wdt_ops = {
.start = orion_wdt_start, .start = orion_wdt_start,
.stop = orion_wdt_stop, .stop = orion_wdt_stop,
.ping = orion_wdt_ping, .ping = orion_wdt_ping,
.set_timeout = orion_wdt_set_timeout,
.get_timeleft = orion_wdt_get_timeleft, .get_timeleft = orion_wdt_get_timeleft,
}; };
...@@ -502,8 +494,7 @@ static int orion_wdt_get_regs(struct platform_device *pdev, ...@@ -502,8 +494,7 @@ static int orion_wdt_get_regs(struct platform_device *pdev,
of_device_is_compatible(node, "marvell,armada-xp-wdt")) { of_device_is_compatible(node, "marvell,armada-xp-wdt")) {
/* Dedicated RSTOUT register, can be requested. */ /* Dedicated RSTOUT register, can be requested. */
res = platform_get_resource(pdev, IORESOURCE_MEM, 1); dev->rstout = devm_platform_ioremap_resource(pdev, 1);
dev->rstout = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(dev->rstout)) if (IS_ERR(dev->rstout))
return PTR_ERR(dev->rstout); return PTR_ERR(dev->rstout);
...@@ -511,8 +502,7 @@ static int orion_wdt_get_regs(struct platform_device *pdev, ...@@ -511,8 +502,7 @@ static int orion_wdt_get_regs(struct platform_device *pdev,
of_device_is_compatible(node, "marvell,armada-380-wdt")) { of_device_is_compatible(node, "marvell,armada-380-wdt")) {
/* Dedicated RSTOUT register, can be requested. */ /* Dedicated RSTOUT register, can be requested. */
res = platform_get_resource(pdev, IORESOURCE_MEM, 1); dev->rstout = devm_platform_ioremap_resource(pdev, 1);
dev->rstout = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(dev->rstout)) if (IS_ERR(dev->rstout))
return PTR_ERR(dev->rstout); return PTR_ERR(dev->rstout);
......
...@@ -168,70 +168,61 @@ static struct watchdog_device pic32_dmt_wdd = { ...@@ -168,70 +168,61 @@ static struct watchdog_device pic32_dmt_wdd = {
.ops = &pic32_dmt_fops, .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) static int pic32_dmt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
int ret; int ret;
struct pic32_dmt *dmt; struct pic32_dmt *dmt;
struct resource *mem;
struct watchdog_device *wdd = &pic32_dmt_wdd; 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) if (!dmt)
return -ENOMEM; return -ENOMEM;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); dmt->regs = devm_platform_ioremap_resource(pdev, 0);
dmt->regs = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(dmt->regs)) if (IS_ERR(dmt->regs))
return PTR_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)) { 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); return PTR_ERR(dmt->clk);
} }
ret = clk_prepare_enable(dmt->clk); ret = clk_prepare_enable(dmt->clk);
if (ret) if (ret)
return 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); wdd->timeout = pic32_dmt_get_timeout_secs(dmt);
if (!wdd->timeout) { if (!wdd->timeout) {
dev_err(&pdev->dev, dev_err(dev, "failed to read watchdog register timeout\n");
"failed to read watchdog register timeout\n"); return -EINVAL;
ret = -EINVAL;
goto out_disable_clk;
} }
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; wdd->bootstatus = pic32_dmt_bootstatus(dmt) ? WDIOF_CARDRESET : 0;
watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT);
watchdog_set_drvdata(wdd, dmt); watchdog_set_drvdata(wdd, dmt);
ret = watchdog_register_device(wdd); ret = devm_watchdog_register_device(dev, wdd);
if (ret) { if (ret) {
dev_err(&pdev->dev, "watchdog register failed, err %d\n", ret); dev_err(dev, "watchdog register failed, err %d\n", ret);
goto out_disable_clk; return ret;
} }
platform_set_drvdata(pdev, wdd); platform_set_drvdata(pdev, wdd);
return 0; 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[] = { static const struct of_device_id pic32_dmt_of_ids[] = {
...@@ -242,7 +233,6 @@ MODULE_DEVICE_TABLE(of, pic32_dmt_of_ids); ...@@ -242,7 +233,6 @@ MODULE_DEVICE_TABLE(of, pic32_dmt_of_ids);
static struct platform_driver pic32_dmt_driver = { static struct platform_driver pic32_dmt_driver = {
.probe = pic32_dmt_probe, .probe = pic32_dmt_probe,
.remove = pic32_dmt_remove,
.driver = { .driver = {
.name = "pic32-dmt", .name = "pic32-dmt",
.of_match_table = of_match_ptr(pic32_dmt_of_ids), .of_match_table = of_match_ptr(pic32_dmt_of_ids),
......
...@@ -166,89 +166,77 @@ static const struct of_device_id pic32_wdt_dt_ids[] = { ...@@ -166,89 +166,77 @@ static const struct of_device_id pic32_wdt_dt_ids[] = {
}; };
MODULE_DEVICE_TABLE(of, 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) static int pic32_wdt_drv_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
int ret; int ret;
struct watchdog_device *wdd = &pic32_wdd; struct watchdog_device *wdd = &pic32_wdd;
struct pic32_wdt *wdt; 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) if (!wdt)
return -ENOMEM; return -ENOMEM;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->regs = devm_platform_ioremap_resource(pdev, 0);
wdt->regs = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(wdt->regs)) if (IS_ERR(wdt->regs))
return PTR_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) if (!wdt->rst_base)
return -ENOMEM; return -ENOMEM;
wdt->clk = devm_clk_get(&pdev->dev, NULL); wdt->clk = devm_clk_get(dev, NULL);
if (IS_ERR(wdt->clk)) { 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); return PTR_ERR(wdt->clk);
} }
ret = clk_prepare_enable(wdt->clk); ret = clk_prepare_enable(wdt->clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "clk enable failed\n"); dev_err(dev, "clk enable failed\n");
return ret; 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)) { if (pic32_wdt_is_win_enabled(wdt)) {
dev_err(&pdev->dev, "windowed-clear mode is not supported.\n"); dev_err(dev, "windowed-clear mode is not supported.\n");
ret = -ENODEV; return -ENODEV;
goto out_disable_clk;
} }
wdd->timeout = pic32_wdt_get_timeout_secs(wdt, &pdev->dev); wdd->timeout = pic32_wdt_get_timeout_secs(wdt, dev);
if (!wdd->timeout) { if (!wdd->timeout) {
dev_err(&pdev->dev, dev_err(dev, "failed to read watchdog register timeout\n");
"failed to read watchdog register timeout\n"); return -EINVAL;
ret = -EINVAL;
goto out_disable_clk;
} }
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; wdd->bootstatus = pic32_wdt_bootstatus(wdt) ? WDIOF_CARDRESET : 0;
watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT);
watchdog_set_drvdata(wdd, wdt); watchdog_set_drvdata(wdd, wdt);
ret = watchdog_register_device(wdd); ret = devm_watchdog_register_device(dev, wdd);
if (ret) { if (ret) {
dev_err(&pdev->dev, "watchdog register failed, err %d\n", ret); dev_err(dev, "watchdog register failed, err %d\n", ret);
goto out_disable_clk; return ret;
} }
platform_set_drvdata(pdev, wdd); 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; return 0;
} }
static struct platform_driver pic32_wdt_driver = { static struct platform_driver pic32_wdt_driver = {
.probe = pic32_wdt_drv_probe, .probe = pic32_wdt_drv_probe,
.remove = pic32_wdt_drv_remove,
.driver = { .driver = {
.name = "pic32-wdt", .name = "pic32-wdt",
.of_match_table = of_match_ptr(pic32_wdt_dt_ids), .of_match_table = of_match_ptr(pic32_wdt_dt_ids),
......
...@@ -132,15 +132,16 @@ static const struct watchdog_ops pm8916_wdt_ops = { ...@@ -132,15 +132,16 @@ static const struct watchdog_ops pm8916_wdt_ops = {
static int pm8916_wdt_probe(struct platform_device *pdev) static int pm8916_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct pm8916_wdt *wdt; struct pm8916_wdt *wdt;
struct device *parent; struct device *parent;
int err, irq; int err, irq;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
parent = pdev->dev.parent; parent = dev->parent;
/* /*
* The pm8916-pon-wdt is a child of the pon device, which is a child * 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) ...@@ -150,20 +151,20 @@ static int pm8916_wdt_probe(struct platform_device *pdev)
*/ */
wdt->regmap = dev_get_regmap(parent->parent, NULL); wdt->regmap = dev_get_regmap(parent->parent, NULL);
if (!wdt->regmap) { if (!wdt->regmap) {
dev_err(&pdev->dev, "failed to locate regmap\n"); dev_err(dev, "failed to locate regmap\n");
return -ENODEV; return -ENODEV;
} }
err = device_property_read_u32(parent, "reg", &wdt->baseaddr); err = device_property_read_u32(parent, "reg", &wdt->baseaddr);
if (err) { 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; return err;
} }
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq > 0) { if (irq > 0) {
if (devm_request_irq(&pdev->dev, irq, pm8916_wdt_isr, 0, if (devm_request_irq(dev, irq, pm8916_wdt_isr, 0, "pm8916_wdt",
"pm8916_wdt", wdt)) wdt))
irq = 0; irq = 0;
} }
...@@ -172,23 +173,23 @@ static int pm8916_wdt_probe(struct platform_device *pdev) ...@@ -172,23 +173,23 @@ static int pm8916_wdt_probe(struct platform_device *pdev)
wdt->baseaddr + PON_PMIC_WD_RESET_S2_CTL, wdt->baseaddr + PON_PMIC_WD_RESET_S2_CTL,
RESET_TYPE_HARD); RESET_TYPE_HARD);
if (err) { if (err) {
dev_err(&pdev->dev, "failed configure watchdog\n"); dev_err(dev, "failed configure watchdog\n");
return err; return err;
} }
wdt->wdev.info = (irq > 0) ? &pm8916_wdt_pt_ident : &pm8916_wdt_ident, wdt->wdev.info = (irq > 0) ? &pm8916_wdt_pt_ident : &pm8916_wdt_ident,
wdt->wdev.ops = &pm8916_wdt_ops, 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.min_timeout = PM8916_WDT_MIN_TIMEOUT;
wdt->wdev.max_timeout = PM8916_WDT_MAX_TIMEOUT; wdt->wdev.max_timeout = PM8916_WDT_MAX_TIMEOUT;
wdt->wdev.timeout = PM8916_WDT_DEFAULT_TIMEOUT; wdt->wdev.timeout = PM8916_WDT_DEFAULT_TIMEOUT;
wdt->wdev.pretimeout = 0; wdt->wdev.pretimeout = 0;
watchdog_set_drvdata(&wdt->wdev, wdt); 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); 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[] = { static const struct of_device_id pm8916_wdt_id_table[] = {
......
...@@ -183,54 +183,50 @@ static struct watchdog_device pnx4008_wdd = { ...@@ -183,54 +183,50 @@ static struct watchdog_device pnx4008_wdd = {
.max_timeout = MAX_HEARTBEAT, .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) static int pnx4008_wdt_probe(struct platform_device *pdev)
{ {
struct resource *r; struct device *dev = &pdev->dev;
int ret = 0; 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_platform_ioremap_resource(pdev, 0);
wdt_base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(wdt_base)) if (IS_ERR(wdt_base))
return PTR_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)) if (IS_ERR(wdt_clk))
return PTR_ERR(wdt_clk); return PTR_ERR(wdt_clk);
ret = clk_prepare_enable(wdt_clk); ret = clk_prepare_enable(wdt_clk);
if (ret) if (ret)
return 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) ? pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
WDIOF_CARDRESET : 0; WDIOF_CARDRESET : 0;
pnx4008_wdd.parent = &pdev->dev; pnx4008_wdd.parent = dev;
watchdog_set_nowayout(&pnx4008_wdd, nowayout); watchdog_set_nowayout(&pnx4008_wdd, nowayout);
watchdog_set_restart_priority(&pnx4008_wdd, 128); 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) { if (ret < 0) {
dev_err(&pdev->dev, "cannot register watchdog device\n"); dev_err(dev, "cannot register watchdog device\n");
goto disable_clk;
}
dev_info(&pdev->dev, "heartbeat %d sec\n", pnx4008_wdd.timeout);
return 0;
disable_clk:
clk_disable_unprepare(wdt_clk);
return ret; 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; return 0;
} }
...@@ -249,7 +245,6 @@ static struct platform_driver platform_wdt_driver = { ...@@ -249,7 +245,6 @@ static struct platform_driver platform_wdt_driver = {
.of_match_table = of_match_ptr(pnx4008_wdt_match), .of_match_table = of_match_ptr(pnx4008_wdt_match),
}, },
.probe = pnx4008_wdt_probe, .probe = pnx4008_wdt_probe,
.remove = pnx4008_wdt_remove,
}; };
module_platform_driver(platform_wdt_driver); module_platform_driver(platform_wdt_driver);
......
...@@ -142,22 +142,28 @@ static const struct watchdog_info qcom_wdt_info = { ...@@ -142,22 +142,28 @@ static const struct watchdog_info qcom_wdt_info = {
.identity = KBUILD_MODNAME, .identity = KBUILD_MODNAME,
}; };
static void qcom_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
static int qcom_wdt_probe(struct platform_device *pdev) static int qcom_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct qcom_wdt *wdt; struct qcom_wdt *wdt;
struct resource *res; struct resource *res;
struct device_node *np = pdev->dev.of_node; struct device_node *np = dev->of_node;
const u32 *regs; const u32 *regs;
u32 percpu_offset; u32 percpu_offset;
int ret; int ret;
regs = of_device_get_match_data(&pdev->dev); regs = of_device_get_match_data(dev);
if (!regs) { if (!regs) {
dev_err(&pdev->dev, "Unsupported QCOM WDT module\n"); dev_err(dev, "Unsupported QCOM WDT module\n");
return -ENODEV; return -ENODEV;
} }
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
...@@ -172,21 +178,25 @@ static int qcom_wdt_probe(struct platform_device *pdev) ...@@ -172,21 +178,25 @@ static int qcom_wdt_probe(struct platform_device *pdev)
res->start += percpu_offset; res->start += percpu_offset;
res->end += 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)) if (IS_ERR(wdt->base))
return PTR_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)) { 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); return PTR_ERR(wdt->clk);
} }
ret = clk_prepare_enable(wdt->clk); ret = clk_prepare_enable(wdt->clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to setup clock\n"); dev_err(dev, "failed to setup clock\n");
return ret; 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 * 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) ...@@ -199,16 +209,15 @@ static int qcom_wdt_probe(struct platform_device *pdev)
wdt->rate = clk_get_rate(wdt->clk); wdt->rate = clk_get_rate(wdt->clk);
if (wdt->rate == 0 || if (wdt->rate == 0 ||
wdt->rate > 0x10000000U) { wdt->rate > 0x10000000U) {
dev_err(&pdev->dev, "invalid clock rate\n"); dev_err(dev, "invalid clock rate\n");
ret = -EINVAL; return -EINVAL;
goto err_clk_unprepare;
} }
wdt->wdd.info = &qcom_wdt_info; wdt->wdd.info = &qcom_wdt_info;
wdt->wdd.ops = &qcom_wdt_ops; wdt->wdd.ops = &qcom_wdt_ops;
wdt->wdd.min_timeout = 1; wdt->wdd.min_timeout = 1;
wdt->wdd.max_timeout = 0x10000000U / wdt->rate; wdt->wdd.max_timeout = 0x10000000U / wdt->rate;
wdt->wdd.parent = &pdev->dev; wdt->wdd.parent = dev;
wdt->layout = regs; wdt->layout = regs;
if (readl(wdt_addr(wdt, WDT_STS)) & 1) if (readl(wdt_addr(wdt, WDT_STS)) & 1)
...@@ -220,29 +229,16 @@ static int qcom_wdt_probe(struct platform_device *pdev) ...@@ -220,29 +229,16 @@ static int qcom_wdt_probe(struct platform_device *pdev)
* the max instead. * the max instead.
*/ */
wdt->wdd.timeout = min(wdt->wdd.max_timeout, 30U); 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) { if (ret) {
dev_err(&pdev->dev, "failed to register watchdog\n"); dev_err(dev, "failed to register watchdog\n");
goto err_clk_unprepare; return ret;
} }
platform_set_drvdata(pdev, wdt); platform_set_drvdata(pdev, wdt);
return 0; 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) static int __maybe_unused qcom_wdt_suspend(struct device *dev)
...@@ -277,7 +273,6 @@ MODULE_DEVICE_TABLE(of, qcom_wdt_of_table); ...@@ -277,7 +273,6 @@ MODULE_DEVICE_TABLE(of, qcom_wdt_of_table);
static struct platform_driver qcom_watchdog_driver = { static struct platform_driver qcom_watchdog_driver = {
.probe = qcom_wdt_probe, .probe = qcom_wdt_probe,
.remove = qcom_wdt_remove,
.driver = { .driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.of_match_table = qcom_wdt_of_table, .of_match_table = qcom_wdt_of_table,
......
...@@ -151,7 +151,6 @@ static const struct soc_device_attribute rwdt_quirks_match[] = { ...@@ -151,7 +151,6 @@ static const struct soc_device_attribute rwdt_quirks_match[] = {
.data = (void *)1, /* needs single CPU */ .data = (void *)1, /* needs single CPU */
}, { }, {
.soc_id = "r8a7792", .soc_id = "r8a7792",
.revision = "*",
.data = (void *)0, /* needs SMP disabled */ .data = (void *)0, /* needs SMP disabled */
}, },
{ /* sentinel */ } { /* sentinel */ }
...@@ -177,7 +176,6 @@ static inline bool rwdt_blacklisted(struct device *dev) { return false; } ...@@ -177,7 +176,6 @@ static inline bool rwdt_blacklisted(struct device *dev) { return false; }
static int rwdt_probe(struct platform_device *pdev) static int rwdt_probe(struct platform_device *pdev)
{ {
struct rwdt_priv *priv; struct rwdt_priv *priv;
struct resource *res;
struct clk *clk; struct clk *clk;
unsigned long clks_per_sec; unsigned long clks_per_sec;
int ret, i; int ret, i;
...@@ -189,8 +187,7 @@ static int rwdt_probe(struct platform_device *pdev) ...@@ -189,8 +187,7 @@ static int rwdt_probe(struct platform_device *pdev)
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_platform_ioremap_resource(pdev, 0);
priv->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->base)) if (IS_ERR(priv->base))
return PTR_ERR(priv->base); return PTR_ERR(priv->base);
...@@ -238,9 +235,7 @@ static int rwdt_probe(struct platform_device *pdev) ...@@ -238,9 +235,7 @@ static int rwdt_probe(struct platform_device *pdev)
watchdog_stop_on_unregister(&priv->wdev); watchdog_stop_on_unregister(&priv->wdev);
/* This overrides the default timeout only if DT configuration was found */ /* This overrides the default timeout only if DT configuration was found */
ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev); watchdog_init_timeout(&priv->wdev, 0, &pdev->dev);
if (ret)
dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n");
ret = watchdog_register_device(&priv->wdev); ret = watchdog_register_device(&priv->wdev);
if (ret < 0) if (ret < 0)
......
...@@ -146,11 +146,12 @@ static const struct watchdog_ops rn5t618_wdt_ops = { ...@@ -146,11 +146,12 @@ static const struct watchdog_ops rn5t618_wdt_ops = {
static int rn5t618_wdt_probe(struct platform_device *pdev) 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; struct rn5t618_wdt *wdt;
int min_timeout, max_timeout; 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) if (!wdt)
return -ENOMEM; return -ENOMEM;
...@@ -163,10 +164,10 @@ static int rn5t618_wdt_probe(struct platform_device *pdev) ...@@ -163,10 +164,10 @@ static int rn5t618_wdt_probe(struct platform_device *pdev)
wdt->wdt_dev.min_timeout = min_timeout; wdt->wdt_dev.min_timeout = min_timeout;
wdt->wdt_dev.max_timeout = max_timeout; wdt->wdt_dev.max_timeout = max_timeout;
wdt->wdt_dev.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_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); watchdog_set_nowayout(&wdt->wdt_dev, nowayout);
platform_set_drvdata(pdev, wdt); platform_set_drvdata(pdev, wdt);
......
...@@ -141,19 +141,18 @@ static struct watchdog_device rt288x_wdt_dev = { ...@@ -141,19 +141,18 @@ static struct watchdog_device rt288x_wdt_dev = {
static int rt288x_wdt_probe(struct platform_device *pdev) static int rt288x_wdt_probe(struct platform_device *pdev)
{ {
struct resource *res; struct device *dev = &pdev->dev;
int ret; int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rt288x_wdt_base = devm_platform_ioremap_resource(pdev, 0);
rt288x_wdt_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(rt288x_wdt_base)) if (IS_ERR(rt288x_wdt_base))
return PTR_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)) if (IS_ERR(rt288x_wdt_clk))
return PTR_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)) if (!IS_ERR(rt288x_wdt_reset))
reset_control_deassert(rt288x_wdt_reset); reset_control_deassert(rt288x_wdt_reset);
...@@ -161,31 +160,20 @@ static int rt288x_wdt_probe(struct platform_device *pdev) ...@@ -161,31 +160,20 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause(); rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause();
rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq); 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, watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout,
&pdev->dev); dev);
watchdog_set_nowayout(&rt288x_wdt_dev, nowayout); 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) if (!ret)
dev_info(&pdev->dev, "Initialized\n"); dev_info(dev, "Initialized\n");
return 0; 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[] = { static const struct of_device_id rt288x_wdt_match[] = {
{ .compatible = "ralink,rt2880-wdt" }, { .compatible = "ralink,rt2880-wdt" },
{}, {},
...@@ -194,8 +182,6 @@ MODULE_DEVICE_TABLE(of, rt288x_wdt_match); ...@@ -194,8 +182,6 @@ MODULE_DEVICE_TABLE(of, rt288x_wdt_match);
static struct platform_driver rt288x_wdt_driver = { static struct platform_driver rt288x_wdt_driver = {
.probe = rt288x_wdt_probe, .probe = rt288x_wdt_probe,
.remove = rt288x_wdt_remove,
.shutdown = rt288x_wdt_shutdown,
.driver = { .driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.of_match_table = rt288x_wdt_match, .of_match_table = rt288x_wdt_match,
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -95,37 +94,43 @@ static const struct of_device_id rtd119x_wdt_dt_ids[] = { ...@@ -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) static int rtd119x_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct rtd119x_watchdog_device *data; struct rtd119x_watchdog_device *data;
struct resource *res;
int ret; int ret;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); data->base = devm_platform_ioremap_resource(pdev, 0);
data->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(data->base)) if (IS_ERR(data->base))
return PTR_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)) if (IS_ERR(data->clk))
return PTR_ERR(data->clk); return PTR_ERR(data->clk);
ret = clk_prepare_enable(data->clk); ret = clk_prepare_enable(data->clk);
if (ret) { if (ret)
clk_put(data->clk); return ret;
ret = devm_add_action_or_reset(dev, rtd119x_clk_disable_unprepare,
data->clk);
if (ret)
return ret; return ret;
}
data->wdt_dev.info = &rtd119x_wdt_info; data->wdt_dev.info = &rtd119x_wdt_info;
data->wdt_dev.ops = &rtd119x_wdt_ops; data->wdt_dev.ops = &rtd119x_wdt_ops;
data->wdt_dev.timeout = 120; data->wdt_dev.timeout = 120;
data->wdt_dev.max_timeout = 0xffffffff / clk_get_rate(data->clk); data->wdt_dev.max_timeout = 0xffffffff / clk_get_rate(data->clk);
data->wdt_dev.min_timeout = 1; 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_stop_on_reboot(&data->wdt_dev);
watchdog_set_drvdata(&data->wdt_dev, data); watchdog_set_drvdata(&data->wdt_dev, data);
...@@ -135,31 +140,11 @@ static int rtd119x_wdt_probe(struct platform_device *pdev) ...@@ -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_set_timeout(&data->wdt_dev, data->wdt_dev.timeout);
rtd119x_wdt_stop(&data->wdt_dev); rtd119x_wdt_stop(&data->wdt_dev);
ret = devm_watchdog_register_device(&pdev->dev, &data->wdt_dev); return devm_watchdog_register_device(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;
} }
static struct platform_driver rtd119x_wdt_driver = { static struct platform_driver rtd119x_wdt_driver = {
.probe = rtd119x_wdt_probe, .probe = rtd119x_wdt_probe,
.remove = rtd119x_wdt_remove,
.driver = { .driver = {
.name = "rtd1295-watchdog", .name = "rtd1295-watchdog",
.of_match_table = rtd119x_wdt_dt_ids, .of_match_table = rtd119x_wdt_dt_ids,
......
...@@ -166,35 +166,34 @@ static const struct watchdog_ops rza_wdt_ops = { ...@@ -166,35 +166,34 @@ static const struct watchdog_ops rza_wdt_ops = {
static int rza_wdt_probe(struct platform_device *pdev) static int rza_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct rza_wdt *priv; struct rza_wdt *priv;
struct resource *res;
unsigned long rate; unsigned long rate;
int ret; int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_platform_ioremap_resource(pdev, 0);
priv->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->base)) if (IS_ERR(priv->base))
return PTR_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)) if (IS_ERR(priv->clk))
return PTR_ERR(priv->clk); return PTR_ERR(priv->clk);
rate = clk_get_rate(priv->clk); rate = clk_get_rate(priv->clk);
if (rate < 16384) { if (rate < 16384) {
dev_err(&pdev->dev, "invalid clock rate (%ld)\n", rate); dev_err(dev, "invalid clock rate (%ld)\n", rate);
return -ENOENT; return -ENOENT;
} }
priv->wdev.info = &rza_wdt_ident, priv->wdev.info = &rza_wdt_ident,
priv->wdev.ops = &rza_wdt_ops, 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) { if (priv->cks == CKS_4BIT) {
/* Assume slowest clock rate possible (CKS=0xF) */ /* Assume slowest clock rate possible (CKS=0xF) */
priv->wdev.max_timeout = (DIVIDER_4BIT * U8_MAX) / rate; priv->wdev.max_timeout = (DIVIDER_4BIT * U8_MAX) / rate;
...@@ -209,19 +208,19 @@ static int rza_wdt_probe(struct platform_device *pdev) ...@@ -209,19 +208,19 @@ static int rza_wdt_probe(struct platform_device *pdev)
* max_hw_heartbeat_ms. * max_hw_heartbeat_ms.
*/ */
priv->wdev.max_hw_heartbeat_ms = (1000 * U8_MAX) / rate; priv->wdev.max_hw_heartbeat_ms = (1000 * U8_MAX) / rate;
dev_dbg(&pdev->dev, "max hw timeout of %dms\n", dev_dbg(dev, "max hw timeout of %dms\n",
priv->wdev.max_hw_heartbeat_ms); priv->wdev.max_hw_heartbeat_ms);
} }
priv->wdev.min_timeout = 1; priv->wdev.min_timeout = 1;
priv->wdev.timeout = DEFAULT_TIMEOUT; 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); 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) if (ret)
dev_err(&pdev->dev, "Cannot register watchdog device\n"); dev_err(dev, "Cannot register watchdog device\n");
return ret; return ret;
} }
......
...@@ -522,7 +522,6 @@ static int s3c2410wdt_probe(struct platform_device *pdev) ...@@ -522,7 +522,6 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct s3c2410_wdt *wdt; struct s3c2410_wdt *wdt;
struct resource *wdt_mem;
struct resource *wdt_irq; struct resource *wdt_irq;
unsigned int wtcon; unsigned int wtcon;
int started = 0; int started = 0;
...@@ -554,8 +553,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev) ...@@ -554,8 +553,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
} }
/* get the memory region for the watchdog timer */ /* get the memory region for the watchdog timer */
wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->reg_base = devm_platform_ioremap_resource(pdev, 0);
wdt->reg_base = devm_ioremap_resource(dev, wdt_mem);
if (IS_ERR(wdt->reg_base)) { if (IS_ERR(wdt->reg_base)) {
ret = PTR_ERR(wdt->reg_base); ret = PTR_ERR(wdt->reg_base);
goto err; goto err;
......
...@@ -199,15 +199,15 @@ static int sama5d4_wdt_init(struct sama5d4_wdt *wdt) ...@@ -199,15 +199,15 @@ static int sama5d4_wdt_init(struct sama5d4_wdt *wdt)
static int sama5d4_wdt_probe(struct platform_device *pdev) static int sama5d4_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct watchdog_device *wdd; struct watchdog_device *wdd;
struct sama5d4_wdt *wdt; struct sama5d4_wdt *wdt;
struct resource *res;
void __iomem *regs; void __iomem *regs;
u32 irq = 0; u32 irq = 0;
u32 timeout; u32 timeout;
int ret; int ret;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
...@@ -221,33 +221,31 @@ static int sama5d4_wdt_probe(struct platform_device *pdev) ...@@ -221,33 +221,31 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdd, wdt); watchdog_set_drvdata(wdd, wdt);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_platform_ioremap_resource(pdev, 0);
regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(regs)) if (IS_ERR(regs))
return PTR_ERR(regs); return PTR_ERR(regs);
wdt->reg_base = 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) 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) if (ret)
return ret; return ret;
if ((wdt->mr & AT91_WDT_WDFIEN) && irq) { 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_SHARED | IRQF_IRQPOLL |
IRQF_NO_SUSPEND, pdev->name, pdev); IRQF_NO_SUSPEND, pdev->name, pdev);
if (ret) { if (ret) {
dev_err(&pdev->dev, dev_err(dev, "cannot register interrupt handler\n");
"cannot register interrupt handler\n");
return ret; return ret;
} }
} }
watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev); watchdog_init_timeout(wdd, wdt_timeout, dev);
timeout = WDT_SEC2TICKS(wdd->timeout); timeout = WDT_SEC2TICKS(wdd->timeout);
...@@ -260,31 +258,21 @@ static int sama5d4_wdt_probe(struct platform_device *pdev) ...@@ -260,31 +258,21 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
watchdog_set_nowayout(wdd, nowayout); watchdog_set_nowayout(wdd, nowayout);
ret = watchdog_register_device(wdd); watchdog_stop_on_unregister(wdd);
ret = devm_watchdog_register_device(dev, wdd);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register watchdog device\n"); dev_err(dev, "failed to register watchdog device\n");
return ret; return ret;
} }
platform_set_drvdata(pdev, wdt); 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); wdd->timeout, nowayout);
return 0; 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[] = { static const struct of_device_id sama5d4_wdt_of_match[] = {
{ .compatible = "atmel,sama5d4-wdt", }, { .compatible = "atmel,sama5d4-wdt", },
{ } { }
...@@ -312,7 +300,6 @@ static SIMPLE_DEV_PM_OPS(sama5d4_wdt_pm_ops, NULL, ...@@ -312,7 +300,6 @@ static SIMPLE_DEV_PM_OPS(sama5d4_wdt_pm_ops, NULL,
static struct platform_driver sama5d4_wdt_driver = { static struct platform_driver sama5d4_wdt_driver = {
.probe = sama5d4_wdt_probe, .probe = sama5d4_wdt_probe,
.remove = sama5d4_wdt_remove,
.driver = { .driver = {
.name = "sama5d4_wdt", .name = "sama5d4_wdt",
.pm = &sama5d4_wdt_pm_ops, .pm = &sama5d4_wdt_pm_ops,
......
...@@ -67,7 +67,7 @@ static DEFINE_SPINLOCK(sbwd_lock); ...@@ -67,7 +67,7 @@ static DEFINE_SPINLOCK(sbwd_lock);
* *
* wdog is the iomem address of the cfg register * 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); spin_lock(&sbwd_lock);
__raw_writeb(0, wdog); __raw_writeb(0, wdog);
...@@ -81,7 +81,7 @@ void sbwdog_set(char __iomem *wdog, unsigned long t) ...@@ -81,7 +81,7 @@ void sbwdog_set(char __iomem *wdog, unsigned long t)
* *
* wdog is the iomem address of the cfg register * 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); spin_lock(&sbwd_lock);
__raw_writeb(__raw_readb(wdog) | 1, wdog); __raw_writeb(__raw_readb(wdog) | 1, wdog);
......
...@@ -231,7 +231,6 @@ static int sbsa_gwdt_probe(struct platform_device *pdev) ...@@ -231,7 +231,6 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct watchdog_device *wdd; struct watchdog_device *wdd;
struct sbsa_gwdt *gwdt; struct sbsa_gwdt *gwdt;
struct resource *res;
int ret, irq; int ret, irq;
u32 status; u32 status;
...@@ -240,13 +239,11 @@ static int sbsa_gwdt_probe(struct platform_device *pdev) ...@@ -240,13 +239,11 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
platform_set_drvdata(pdev, gwdt); platform_set_drvdata(pdev, gwdt);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); cf_base = devm_platform_ioremap_resource(pdev, 0);
cf_base = devm_ioremap_resource(dev, res);
if (IS_ERR(cf_base)) if (IS_ERR(cf_base))
return PTR_ERR(cf_base); return PTR_ERR(cf_base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1); rf_base = devm_platform_ioremap_resource(pdev, 1);
rf_base = devm_ioremap_resource(dev, res);
if (IS_ERR(rf_base)) if (IS_ERR(rf_base))
return PTR_ERR(rf_base); return PTR_ERR(rf_base);
...@@ -313,7 +310,8 @@ static int sbsa_gwdt_probe(struct platform_device *pdev) ...@@ -313,7 +310,8 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
*/ */
sbsa_gwdt_set_timeout(wdd, wdd->timeout); 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) if (ret)
return ret; return ret;
...@@ -324,22 +322,6 @@ static int sbsa_gwdt_probe(struct platform_device *pdev) ...@@ -324,22 +322,6 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
return 0; 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 */ /* Disable watchdog if it is active during suspend */
static int __maybe_unused sbsa_gwdt_suspend(struct device *dev) static int __maybe_unused sbsa_gwdt_suspend(struct device *dev)
{ {
...@@ -385,8 +367,6 @@ static struct platform_driver sbsa_gwdt_driver = { ...@@ -385,8 +367,6 @@ static struct platform_driver sbsa_gwdt_driver = {
.of_match_table = sbsa_gwdt_of_match, .of_match_table = sbsa_gwdt_of_match,
}, },
.probe = sbsa_gwdt_probe, .probe = sbsa_gwdt_probe,
.remove = sbsa_gwdt_remove,
.shutdown = sbsa_gwdt_shutdown,
.id_table = sbsa_gwdt_pdev_match, .id_table = sbsa_gwdt_pdev_match,
}; };
......
...@@ -220,7 +220,6 @@ static struct watchdog_device sh_wdt_dev = { ...@@ -220,7 +220,6 @@ static struct watchdog_device sh_wdt_dev = {
static int sh_wdt_probe(struct platform_device *pdev) static int sh_wdt_probe(struct platform_device *pdev)
{ {
struct sh_wdt *wdt; struct sh_wdt *wdt;
struct resource *res;
int rc; int rc;
/* /*
...@@ -245,8 +244,7 @@ static int sh_wdt_probe(struct platform_device *pdev) ...@@ -245,8 +244,7 @@ static int sh_wdt_probe(struct platform_device *pdev)
wdt->clk = NULL; wdt->clk = NULL;
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_platform_ioremap_resource(pdev, 0);
wdt->base = devm_ioremap_resource(wdt->dev, res);
if (IS_ERR(wdt->base)) if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base); return PTR_ERR(wdt->base);
......
...@@ -146,22 +146,23 @@ static struct watchdog_device sirfsoc_wdd = { ...@@ -146,22 +146,23 @@ static struct watchdog_device sirfsoc_wdd = {
static int sirfsoc_wdt_probe(struct platform_device *pdev) static int sirfsoc_wdt_probe(struct platform_device *pdev)
{ {
struct resource *res; struct device *dev = &pdev->dev;
int ret; int ret;
void __iomem *base; void __iomem *base;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_platform_ioremap_resource(pdev, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base)) if (IS_ERR(base))
return PTR_ERR(base); return PTR_ERR(base);
watchdog_set_drvdata(&sirfsoc_wdd, (__force void *)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); 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) if (ret)
return ret; return ret;
...@@ -170,19 +171,6 @@ static int sirfsoc_wdt_probe(struct platform_device *pdev) ...@@ -170,19 +171,6 @@ static int sirfsoc_wdt_probe(struct platform_device *pdev)
return 0; 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 #ifdef CONFIG_PM_SLEEP
static int sirfsoc_wdt_suspend(struct device *dev) static int sirfsoc_wdt_suspend(struct device *dev)
{ {
...@@ -220,8 +208,6 @@ static struct platform_driver sirfsoc_wdt_driver = { ...@@ -220,8 +208,6 @@ static struct platform_driver sirfsoc_wdt_driver = {
.of_match_table = sirfsoc_wdt_of_match, .of_match_table = sirfsoc_wdt_of_match,
}, },
.probe = sirfsoc_wdt_probe, .probe = sirfsoc_wdt_probe,
.remove = sirfsoc_wdt_remove,
.shutdown = sirfsoc_wdt_shutdown,
}; };
module_platform_driver(sirfsoc_wdt_driver); module_platform_driver(sirfsoc_wdt_driver);
......
...@@ -395,9 +395,7 @@ static int sp5100_tco_probe(struct platform_device *pdev) ...@@ -395,9 +395,7 @@ static int sp5100_tco_probe(struct platform_device *pdev)
wdd->min_timeout = 1; wdd->min_timeout = 1;
wdd->max_timeout = 0xffff; wdd->max_timeout = 0xffff;
if (watchdog_init_timeout(wdd, heartbeat, NULL)) watchdog_init_timeout(wdd, heartbeat, NULL);
dev_info(dev, "timeout value invalid, using %d\n",
wdd->timeout);
watchdog_set_nowayout(wdd, nowayout); watchdog_set_nowayout(wdd, nowayout);
watchdog_stop_on_reboot(wdd); watchdog_stop_on_reboot(wdd);
watchdog_stop_on_unregister(wdd); watchdog_stop_on_unregister(wdd);
......
...@@ -245,9 +245,7 @@ static u32 sprd_wdt_get_timeleft(struct watchdog_device *wdd) ...@@ -245,9 +245,7 @@ static u32 sprd_wdt_get_timeleft(struct watchdog_device *wdd)
u32 val; u32 val;
val = sprd_wdt_get_cnt_value(wdt); val = sprd_wdt_get_cnt_value(wdt);
val = val / SPRD_WDT_CNT_STEP; return val / SPRD_WDT_CNT_STEP;
return val;
} }
static const struct watchdog_ops sprd_wdt_ops = { static const struct watchdog_ops sprd_wdt_ops = {
...@@ -269,70 +267,68 @@ static const struct watchdog_info sprd_wdt_info = { ...@@ -269,70 +267,68 @@ static const struct watchdog_info sprd_wdt_info = {
static int sprd_wdt_probe(struct platform_device *pdev) static int sprd_wdt_probe(struct platform_device *pdev)
{ {
struct resource *wdt_res; struct device *dev = &pdev->dev;
struct sprd_wdt *wdt; struct sprd_wdt *wdt;
int ret; int ret;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
wdt_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_platform_ioremap_resource(pdev, 0);
wdt->base = devm_ioremap_resource(&pdev->dev, wdt_res);
if (IS_ERR(wdt->base)) if (IS_ERR(wdt->base))
return PTR_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)) { 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); 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)) { 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); return PTR_ERR(wdt->rtc_enable);
} }
wdt->irq = platform_get_irq(pdev, 0); wdt->irq = platform_get_irq(pdev, 0);
if (wdt->irq < 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; return wdt->irq;
} }
ret = devm_request_irq(&pdev->dev, wdt->irq, sprd_wdt_isr, ret = devm_request_irq(dev, wdt->irq, sprd_wdt_isr, IRQF_NO_SUSPEND,
IRQF_NO_SUSPEND, "sprd-wdt", (void *)wdt); "sprd-wdt", (void *)wdt);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register irq\n"); dev_err(dev, "failed to register irq\n");
return ret; return ret;
} }
wdt->wdd.info = &sprd_wdt_info; wdt->wdd.info = &sprd_wdt_info;
wdt->wdd.ops = &sprd_wdt_ops; 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.min_timeout = SPRD_WDT_MIN_TIMEOUT;
wdt->wdd.max_timeout = SPRD_WDT_MAX_TIMEOUT; wdt->wdd.max_timeout = SPRD_WDT_MAX_TIMEOUT;
wdt->wdd.timeout = SPRD_WDT_MAX_TIMEOUT; wdt->wdd.timeout = SPRD_WDT_MAX_TIMEOUT;
ret = sprd_wdt_enable(wdt); ret = sprd_wdt_enable(wdt);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to enable wdt\n"); dev_err(dev, "failed to enable wdt\n");
return ret; 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) { if (ret) {
sprd_wdt_disable(wdt); dev_err(dev, "Failed to add wdt disable action\n");
dev_err(&pdev->dev, "Failed to add wdt disable action\n");
return ret; return ret;
} }
watchdog_set_nowayout(&wdt->wdd, WATCHDOG_NOWAYOUT); 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) { if (ret) {
sprd_wdt_disable(wdt); sprd_wdt_disable(wdt);
dev_err(&pdev->dev, "failed to register watchdog\n"); dev_err(dev, "failed to register watchdog\n");
return ret; return ret;
} }
platform_set_drvdata(pdev, wdt); platform_set_drvdata(pdev, wdt);
......
...@@ -142,13 +142,18 @@ static struct watchdog_device st_wdog_dev = { ...@@ -142,13 +142,18 @@ static struct watchdog_device st_wdog_dev = {
.ops = &st_wdog_ops, .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) static int st_wdog_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
const struct of_device_id *match; 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 st_wdog *st_wdog;
struct regmap *regmap; struct regmap *regmap;
struct resource *res;
struct clk *clk; struct clk *clk;
void __iomem *base; void __iomem *base;
uint32_t mode; uint32_t mode;
...@@ -156,7 +161,7 @@ static int st_wdog_probe(struct platform_device *pdev) ...@@ -156,7 +161,7 @@ static int st_wdog_probe(struct platform_device *pdev)
ret = of_property_read_u32(np, "st,lpc-mode", &mode); ret = of_property_read_u32(np, "st,lpc-mode", &mode);
if (ret) { 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; return -EINVAL;
} }
...@@ -164,35 +169,34 @@ static int st_wdog_probe(struct platform_device *pdev) ...@@ -164,35 +169,34 @@ static int st_wdog_probe(struct platform_device *pdev)
if (mode != ST_LPC_MODE_WDT) if (mode != ST_LPC_MODE_WDT)
return -ENODEV; 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) if (!st_wdog)
return -ENOMEM; return -ENOMEM;
match = of_match_device(st_wdog_match, &pdev->dev); match = of_match_device(st_wdog_match, dev);
if (!match) { if (!match) {
dev_err(&pdev->dev, "Couldn't match device\n"); dev_err(dev, "Couldn't match device\n");
return -ENODEV; return -ENODEV;
} }
st_wdog->syscfg = (struct st_wdog_syscfg *)match->data; st_wdog->syscfg = (struct st_wdog_syscfg *)match->data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_platform_ioremap_resource(pdev, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base)) if (IS_ERR(base))
return PTR_ERR(base); return PTR_ERR(base);
regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
if (IS_ERR(regmap)) { 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); return PTR_ERR(regmap);
} }
clk = devm_clk_get(&pdev->dev, NULL); clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) { 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); return PTR_ERR(clk);
} }
st_wdog->dev = &pdev->dev; st_wdog->dev = dev;
st_wdog->base = base; st_wdog->base = base;
st_wdog->clk = clk; st_wdog->clk = clk;
st_wdog->regmap = regmap; st_wdog->regmap = regmap;
...@@ -200,39 +204,38 @@ static int st_wdog_probe(struct platform_device *pdev) ...@@ -200,39 +204,38 @@ static int st_wdog_probe(struct platform_device *pdev)
st_wdog->clkrate = clk_get_rate(st_wdog->clk); st_wdog->clkrate = clk_get_rate(st_wdog->clk);
if (!st_wdog->clkrate) { 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; return -EINVAL;
} }
st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate; 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); ret = clk_prepare_enable(clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Unable to enable clock\n"); dev_err(dev, "Unable to enable clock\n");
return ret; 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_drvdata(&st_wdog_dev, st_wdog);
watchdog_set_nowayout(&st_wdog_dev, WATCHDOG_NOWAYOUT); watchdog_set_nowayout(&st_wdog_dev, WATCHDOG_NOWAYOUT);
/* Init Watchdog timeout with value in DT */ /* Init Watchdog timeout with value in DT */
ret = watchdog_init_timeout(&st_wdog_dev, 0, &pdev->dev); ret = watchdog_init_timeout(&st_wdog_dev, 0, dev);
if (ret) { if (ret)
dev_err(&pdev->dev, "Unable to initialise watchdog timeout\n");
clk_disable_unprepare(clk);
return ret; return ret;
}
ret = watchdog_register_device(&st_wdog_dev); ret = devm_watchdog_register_device(dev, &st_wdog_dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Unable to register watchdog\n"); dev_err(dev, "Unable to register watchdog\n");
clk_disable_unprepare(clk);
return ret; return ret;
} }
st_wdog_setup(st_wdog, true); 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"); st_wdog->warm_reset ? "warm" : "cold");
return ret; return ret;
...@@ -243,8 +246,6 @@ static int st_wdog_remove(struct platform_device *pdev) ...@@ -243,8 +246,6 @@ static int st_wdog_remove(struct platform_device *pdev)
struct st_wdog *st_wdog = watchdog_get_drvdata(&st_wdog_dev); struct st_wdog *st_wdog = watchdog_get_drvdata(&st_wdog_dev);
st_wdog_setup(st_wdog, false); st_wdog_setup(st_wdog, false);
watchdog_unregister_device(&st_wdog_dev);
clk_disable_unprepare(st_wdog->clk);
return 0; return 0;
} }
......
...@@ -34,36 +34,44 @@ ...@@ -34,36 +34,44 @@
#define KR_KEY_EWA 0x5555 /* write access enable */ #define KR_KEY_EWA 0x5555 /* write access enable */
#define KR_KEY_DWA 0x0000 /* write access disable */ #define KR_KEY_DWA 0x0000 /* write access disable */
/* IWDG_PR register bit values */ /* IWDG_PR register */
#define PR_4 0x00 /* prescaler set to 4 */ #define PR_SHIFT 2
#define PR_8 0x01 /* prescaler set to 8 */ #define PR_MIN BIT(PR_SHIFT)
#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_RLR register values */ /* IWDG_RLR register values */
#define RLR_MIN 0x07C /* min value supported by reload register */ #define RLR_MIN 0x2 /* min value recommended */
#define RLR_MAX 0xFFF /* max value supported by reload register */ #define RLR_MAX GENMASK(11, 0) /* max value of reload register */
/* IWDG_SR register bit mask */ /* IWDG_SR register bit mask */
#define FLAG_PVU BIT(0) /* Watchdog prescaler value update */ #define SR_PVU BIT(0) /* Watchdog prescaler value update */
#define FLAG_RVU BIT(1) /* Watchdog counter reload value update */ #define SR_RVU BIT(1) /* Watchdog counter reload value update */
/* set timeout to 100000 us */ /* set timeout to 100000 us */
#define TIMEOUT_US 100000 #define TIMEOUT_US 100000
#define SLEEP_US 1000 #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 stm32_iwdg {
struct watchdog_device wdd; struct watchdog_device wdd;
const struct stm32_iwdg_data *data;
void __iomem *regs; void __iomem *regs;
struct clk *clk_lsi; struct clk *clk_lsi;
struct clk *clk_pclk; struct clk *clk_pclk;
unsigned int rate; unsigned int rate;
bool has_pclk;
}; };
static inline u32 reg_read(void __iomem *base, u32 reg) 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) ...@@ -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) static int stm32_iwdg_start(struct watchdog_device *wdd)
{ {
struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd);
u32 val = FLAG_PVU | FLAG_RVU; u32 tout, presc, iwdg_rlr, iwdg_pr, iwdg_sr;
u32 reload;
int ret; int ret;
dev_dbg(wdd->parent, "%s\n", __func__); dev_dbg(wdd->parent, "%s\n", __func__);
/* prescaler fixed to 256 */ tout = clamp_t(unsigned int, wdd->timeout,
reload = clamp_t(unsigned int, ((wdd->timeout * wdt->rate) / 256) - 1, wdd->min_timeout, wdd->max_hw_heartbeat_ms / 1000);
RLR_MIN, RLR_MAX);
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 */ /* enable write access */
reg_write(wdt->regs, IWDG_KR, KR_KEY_EWA); reg_write(wdt->regs, IWDG_KR, KR_KEY_EWA);
/* set prescaler & reload registers */ /* set prescaler & reload registers */
reg_write(wdt->regs, IWDG_PR, PR_256); /* prescaler fix to 256 */ reg_write(wdt->regs, IWDG_PR, iwdg_pr);
reg_write(wdt->regs, IWDG_RLR, reload); reg_write(wdt->regs, IWDG_RLR, iwdg_rlr);
reg_write(wdt->regs, IWDG_KR, KR_KEY_ENABLE); reg_write(wdt->regs, IWDG_KR, KR_KEY_ENABLE);
/* wait for the registers to be updated (max 100ms) */ /* wait for the registers to be updated (max 100ms) */
ret = readl_relaxed_poll_timeout(wdt->regs + IWDG_SR, val, ret = readl_relaxed_poll_timeout(wdt->regs + IWDG_SR, iwdg_sr,
!(val & (FLAG_PVU | FLAG_RVU)), !(iwdg_sr & (SR_PVU | SR_RVU)),
SLEEP_US, TIMEOUT_US); SLEEP_US, TIMEOUT_US);
if (ret) { if (ret) {
dev_err(wdd->parent, dev_err(wdd->parent, "Fail to set prescaler, reload regs\n");
"Fail to set prescaler or reload registers\n");
return ret; return ret;
} }
...@@ -138,38 +150,52 @@ static int stm32_iwdg_set_timeout(struct watchdog_device *wdd, ...@@ -138,38 +150,52 @@ static int stm32_iwdg_set_timeout(struct watchdog_device *wdd,
return 0; return 0;
} }
static void stm32_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
static int stm32_iwdg_clk_init(struct platform_device *pdev, static int stm32_iwdg_clk_init(struct platform_device *pdev,
struct stm32_iwdg *wdt) struct stm32_iwdg *wdt)
{ {
struct device *dev = &pdev->dev;
u32 ret; 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)) { 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); return PTR_ERR(wdt->clk_lsi);
} }
/* optional peripheral clock */ /* optional peripheral clock */
if (wdt->has_pclk) { if (wdt->data->has_pclk) {
wdt->clk_pclk = devm_clk_get(&pdev->dev, "pclk"); wdt->clk_pclk = devm_clk_get(dev, "pclk");
if (IS_ERR(wdt->clk_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); return PTR_ERR(wdt->clk_pclk);
} }
ret = clk_prepare_enable(wdt->clk_pclk); ret = clk_prepare_enable(wdt->clk_pclk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Unable to prepare pclk clock\n"); dev_err(dev, "Unable to prepare pclk clock\n");
return ret; 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); ret = clk_prepare_enable(wdt->clk_lsi);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Unable to prepare lsi clock\n"); dev_err(dev, "Unable to prepare lsi clock\n");
clk_disable_unprepare(wdt->clk_pclk);
return ret; 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); wdt->rate = clk_get_rate(wdt->clk_lsi);
...@@ -191,35 +217,31 @@ static const struct watchdog_ops stm32_iwdg_ops = { ...@@ -191,35 +217,31 @@ static const struct watchdog_ops stm32_iwdg_ops = {
}; };
static const struct of_device_id stm32_iwdg_of_match[] = { static const struct of_device_id stm32_iwdg_of_match[] = {
{ .compatible = "st,stm32-iwdg", .data = (void *)!HAS_PCLK }, { .compatible = "st,stm32-iwdg", .data = &stm32_iwdg_data },
{ .compatible = "st,stm32mp1-iwdg", .data = (void *)HAS_PCLK }, { .compatible = "st,stm32mp1-iwdg", .data = &stm32mp1_iwdg_data },
{ /* end node */ } { /* end node */ }
}; };
MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match); MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match);
static int stm32_iwdg_probe(struct platform_device *pdev) static int stm32_iwdg_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct watchdog_device *wdd; struct watchdog_device *wdd;
const struct of_device_id *match;
struct stm32_iwdg *wdt; struct stm32_iwdg *wdt;
struct resource *res;
int ret; int ret;
match = of_match_device(stm32_iwdg_of_match, &pdev->dev); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!match)
return -ENODEV;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; 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. */ /* This is the timer base. */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->regs = devm_platform_ioremap_resource(pdev, 0);
wdt->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(wdt->regs)) { 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); return PTR_ERR(wdt->regs);
} }
...@@ -229,50 +251,30 @@ static int stm32_iwdg_probe(struct platform_device *pdev) ...@@ -229,50 +251,30 @@ static int stm32_iwdg_probe(struct platform_device *pdev)
/* Initialize struct watchdog_device. */ /* Initialize struct watchdog_device. */
wdd = &wdt->wdd; wdd = &wdt->wdd;
wdd->parent = dev;
wdd->info = &stm32_iwdg_info; wdd->info = &stm32_iwdg_info;
wdd->ops = &stm32_iwdg_ops; wdd->ops = &stm32_iwdg_ops;
wdd->min_timeout = ((RLR_MIN + 1) * 256) / wdt->rate; wdd->min_timeout = DIV_ROUND_UP((RLR_MIN + 1) * PR_MIN, wdt->rate);
wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * 256 * 1000) / wdt->rate; wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * wdt->data->max_prescaler *
wdd->parent = &pdev->dev; 1000) / wdt->rate;
watchdog_set_drvdata(wdd, wdt); watchdog_set_drvdata(wdd, wdt);
watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT);
watchdog_init_timeout(wdd, 0, dev);
ret = watchdog_init_timeout(wdd, 0, &pdev->dev); ret = devm_watchdog_register_device(dev, wdd);
if (ret)
dev_warn(&pdev->dev,
"unable to set timeout value, using default\n");
ret = watchdog_register_device(wdd);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register watchdog device\n"); dev_err(dev, "failed to register watchdog device\n");
goto err; return ret;
} }
platform_set_drvdata(pdev, wdt); 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; return 0;
} }
static struct platform_driver stm32_iwdg_driver = { static struct platform_driver stm32_iwdg_driver = {
.probe = stm32_iwdg_probe, .probe = stm32_iwdg_probe,
.remove = stm32_iwdg_remove,
.driver = { .driver = {
.name = "iwdg", .name = "iwdg",
.of_match_table = of_match_ptr(stm32_iwdg_of_match), .of_match_table = of_match_ptr(stm32_iwdg_of_match),
......
...@@ -89,23 +89,24 @@ static struct notifier_block wdt_notifier = { ...@@ -89,23 +89,24 @@ static struct notifier_block wdt_notifier = {
static int stmp3xxx_wdt_probe(struct platform_device *pdev) static int stmp3xxx_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
int ret; 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.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) { if (ret < 0) {
dev_err(&pdev->dev, "cannot register watchdog device\n"); dev_err(dev, "cannot register watchdog device\n");
return ret; return ret;
} }
if (register_reboot_notifier(&wdt_notifier)) 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", dev_info(dev, "initialized watchdog with heartbeat %ds\n",
stmp3xxx_wdd.timeout); stmp3xxx_wdd.timeout);
return 0; return 0;
} }
...@@ -113,7 +114,6 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev) ...@@ -113,7 +114,6 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
static int stmp3xxx_wdt_remove(struct platform_device *pdev) static int stmp3xxx_wdt_remove(struct platform_device *pdev)
{ {
unregister_reboot_notifier(&wdt_notifier); unregister_reboot_notifier(&wdt_notifier);
watchdog_unregister_device(&stmp3xxx_wdd);
return 0; return 0;
} }
......
...@@ -81,18 +81,19 @@ static const struct watchdog_ops pmic_watchdog_ops = { ...@@ -81,18 +81,19 @@ static const struct watchdog_ops pmic_watchdog_ops = {
static int pmic_wdt_probe(struct platform_device *pdev) static int pmic_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
int ret; int ret;
struct stpmic1 *pmic; struct stpmic1 *pmic;
struct stpmic1_wdt *wdt; struct stpmic1_wdt *wdt;
if (!pdev->dev.parent) if (!dev->parent)
return -EINVAL; return -EINVAL;
pmic = dev_get_drvdata(pdev->dev.parent); pmic = dev_get_drvdata(dev->parent);
if (!pmic) if (!pmic)
return -EINVAL; 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) if (!wdt)
return -ENOMEM; return -ENOMEM;
...@@ -102,15 +103,15 @@ static int pmic_wdt_probe(struct platform_device *pdev) ...@@ -102,15 +103,15 @@ static int pmic_wdt_probe(struct platform_device *pdev)
wdt->wdtdev.ops = &pmic_watchdog_ops; wdt->wdtdev.ops = &pmic_watchdog_ops;
wdt->wdtdev.min_timeout = PMIC_WDT_MIN_TIMEOUT; wdt->wdtdev.min_timeout = PMIC_WDT_MIN_TIMEOUT;
wdt->wdtdev.max_timeout = PMIC_WDT_MAX_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; 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_nowayout(&wdt->wdtdev, nowayout);
watchdog_set_drvdata(&wdt->wdtdev, wdt); 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) if (ret)
return ret; return ret;
......
...@@ -233,20 +233,19 @@ MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids); ...@@ -233,20 +233,19 @@ MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids);
static int sunxi_wdt_probe(struct platform_device *pdev) static int sunxi_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct sunxi_wdt_dev *sunxi_wdt; struct sunxi_wdt_dev *sunxi_wdt;
struct resource *res;
int err; 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) if (!sunxi_wdt)
return -EINVAL; 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) if (!sunxi_wdt->wdt_regs)
return -ENODEV; return -ENODEV;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); sunxi_wdt->wdt_base = devm_platform_ioremap_resource(pdev, 0);
sunxi_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(sunxi_wdt->wdt_base)) if (IS_ERR(sunxi_wdt->wdt_base))
return PTR_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) ...@@ -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.timeout = WDT_MAX_TIMEOUT;
sunxi_wdt->wdt_dev.max_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.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_nowayout(&sunxi_wdt->wdt_dev, nowayout);
watchdog_set_restart_priority(&sunxi_wdt->wdt_dev, 128); watchdog_set_restart_priority(&sunxi_wdt->wdt_dev, 128);
...@@ -266,11 +265,11 @@ static int sunxi_wdt_probe(struct platform_device *pdev) ...@@ -266,11 +265,11 @@ static int sunxi_wdt_probe(struct platform_device *pdev)
sunxi_wdt_stop(&sunxi_wdt->wdt_dev); sunxi_wdt_stop(&sunxi_wdt->wdt_dev);
watchdog_stop_on_reboot(&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)) if (unlikely(err))
return err; return err;
dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)", dev_info(dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)",
sunxi_wdt->wdt_dev.timeout, nowayout); sunxi_wdt->wdt_dev.timeout, nowayout);
return 0; return 0;
......
...@@ -108,10 +108,14 @@ static const struct watchdog_ops tangox_wdt_ops = { ...@@ -108,10 +108,14 @@ static const struct watchdog_ops tangox_wdt_ops = {
.restart = tangox_wdt_restart, .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) static int tangox_wdt_probe(struct platform_device *pdev)
{ {
struct tangox_wdt_device *dev; struct tangox_wdt_device *dev;
struct resource *res;
u32 config; u32 config;
int err; int err;
...@@ -119,8 +123,7 @@ static int tangox_wdt_probe(struct platform_device *pdev) ...@@ -119,8 +123,7 @@ static int tangox_wdt_probe(struct platform_device *pdev)
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dev->base = devm_platform_ioremap_resource(pdev, 0);
dev->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(dev->base)) if (IS_ERR(dev->base))
return PTR_ERR(dev->base); return PTR_ERR(dev->base);
...@@ -131,12 +134,14 @@ static int tangox_wdt_probe(struct platform_device *pdev) ...@@ -131,12 +134,14 @@ static int tangox_wdt_probe(struct platform_device *pdev)
err = clk_prepare_enable(dev->clk); err = clk_prepare_enable(dev->clk);
if (err) if (err)
return 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); dev->clk_rate = clk_get_rate(dev->clk);
if (!dev->clk_rate) { if (!dev->clk_rate)
err = -EINVAL; return -EINVAL;
goto err;
}
dev->wdt.parent = &pdev->dev; dev->wdt.parent = &pdev->dev;
dev->wdt.info = &tangox_wdt_info; dev->wdt.info = &tangox_wdt_info;
...@@ -170,30 +175,15 @@ static int tangox_wdt_probe(struct platform_device *pdev) ...@@ -170,30 +175,15 @@ static int tangox_wdt_probe(struct platform_device *pdev)
watchdog_set_restart_priority(&dev->wdt, 128); 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) if (err)
goto err; return err;
platform_set_drvdata(pdev, dev); platform_set_drvdata(pdev, dev);
dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n"); 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; return 0;
} }
...@@ -206,7 +196,6 @@ MODULE_DEVICE_TABLE(of, tangox_wdt_dt_ids); ...@@ -206,7 +196,6 @@ MODULE_DEVICE_TABLE(of, tangox_wdt_dt_ids);
static struct platform_driver tangox_wdt_driver = { static struct platform_driver tangox_wdt_driver = {
.probe = tangox_wdt_probe, .probe = tangox_wdt_probe,
.remove = tangox_wdt_remove,
.driver = { .driver = {
.name = "tangox-wdt", .name = "tangox-wdt",
.of_match_table = tangox_wdt_dt_ids, .of_match_table = tangox_wdt_dt_ids,
......
...@@ -181,15 +181,14 @@ static const struct watchdog_ops tegra_wdt_ops = { ...@@ -181,15 +181,14 @@ static const struct watchdog_ops tegra_wdt_ops = {
static int tegra_wdt_probe(struct platform_device *pdev) static int tegra_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct watchdog_device *wdd; struct watchdog_device *wdd;
struct tegra_wdt *wdt; struct tegra_wdt *wdt;
struct resource *res;
void __iomem *regs; void __iomem *regs;
int ret; int ret;
/* This is the timer base. */ /* This is the timer base. */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_platform_ioremap_resource(pdev, 0);
regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(regs)) if (IS_ERR(regs))
return PTR_ERR(regs); return PTR_ERR(regs);
...@@ -197,7 +196,7 @@ static int tegra_wdt_probe(struct platform_device *pdev) ...@@ -197,7 +196,7 @@ static int tegra_wdt_probe(struct platform_device *pdev)
* Allocate our watchdog driver data, which has the * Allocate our watchdog driver data, which has the
* struct watchdog_device nested within it. * 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) if (!wdt)
return -ENOMEM; return -ENOMEM;
...@@ -212,39 +211,27 @@ static int tegra_wdt_probe(struct platform_device *pdev) ...@@ -212,39 +211,27 @@ static int tegra_wdt_probe(struct platform_device *pdev)
wdd->ops = &tegra_wdt_ops; wdd->ops = &tegra_wdt_ops;
wdd->min_timeout = MIN_WDT_TIMEOUT; wdd->min_timeout = MIN_WDT_TIMEOUT;
wdd->max_timeout = MAX_WDT_TIMEOUT; wdd->max_timeout = MAX_WDT_TIMEOUT;
wdd->parent = &pdev->dev; wdd->parent = dev;
watchdog_set_drvdata(wdd, wdt); watchdog_set_drvdata(wdd, wdt);
watchdog_set_nowayout(wdd, nowayout); 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) { if (ret) {
dev_err(&pdev->dev, dev_err(dev, "failed to register watchdog device\n");
"failed to register watchdog device\n");
return ret; return ret;
} }
platform_set_drvdata(pdev, wdt); platform_set_drvdata(pdev, wdt);
dev_info(&pdev->dev, dev_info(dev, "initialized (heartbeat = %d sec, nowayout = %d)\n",
"initialized (heartbeat = %d sec, nowayout = %d)\n",
heartbeat, nowayout); heartbeat, nowayout);
return 0; 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 #ifdef CONFIG_PM_SLEEP
static int tegra_wdt_runtime_suspend(struct device *dev) static int tegra_wdt_runtime_suspend(struct device *dev)
{ {
...@@ -280,7 +267,6 @@ static const struct dev_pm_ops tegra_wdt_pm_ops = { ...@@ -280,7 +267,6 @@ static const struct dev_pm_ops tegra_wdt_pm_ops = {
static struct platform_driver tegra_wdt_driver = { static struct platform_driver tegra_wdt_driver = {
.probe = tegra_wdt_probe, .probe = tegra_wdt_probe,
.remove = tegra_wdt_remove,
.driver = { .driver = {
.name = "tegra-wdt", .name = "tegra-wdt",
.pm = &tegra_wdt_pm_ops, .pm = &tegra_wdt_pm_ops,
......
...@@ -70,11 +70,12 @@ static struct watchdog_ops tqmx86_wdt_ops = { ...@@ -70,11 +70,12 @@ static struct watchdog_ops tqmx86_wdt_ops = {
static int tqmx86_wdt_probe(struct platform_device *pdev) static int tqmx86_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct tqmx86_wdt *priv; struct tqmx86_wdt *priv;
struct resource *res; struct resource *res;
int err; int err;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
...@@ -82,14 +83,13 @@ static int tqmx86_wdt_probe(struct platform_device *pdev) ...@@ -82,14 +83,13 @@ static int tqmx86_wdt_probe(struct platform_device *pdev)
if (!res) if (!res)
return -ENODEV; return -ENODEV;
priv->io_base = devm_ioport_map(&pdev->dev, res->start, priv->io_base = devm_ioport_map(dev, res->start, resource_size(res));
resource_size(res));
if (!priv->io_base) if (!priv->io_base)
return -ENOMEM; return -ENOMEM;
watchdog_set_drvdata(&priv->wdd, priv); watchdog_set_drvdata(&priv->wdd, priv);
priv->wdd.parent = &pdev->dev; priv->wdd.parent = dev;
priv->wdd.info = &tqmx86_wdt_info; priv->wdd.info = &tqmx86_wdt_info;
priv->wdd.ops = &tqmx86_wdt_ops; priv->wdd.ops = &tqmx86_wdt_ops;
priv->wdd.min_timeout = 1; priv->wdd.min_timeout = 1;
...@@ -97,16 +97,16 @@ static int tqmx86_wdt_probe(struct platform_device *pdev) ...@@ -97,16 +97,16 @@ static int tqmx86_wdt_probe(struct platform_device *pdev)
priv->wdd.max_hw_heartbeat_ms = 4096*1000; priv->wdd.max_hw_heartbeat_ms = 4096*1000;
priv->wdd.timeout = WDT_TIMEOUT; 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); watchdog_set_nowayout(&priv->wdd, WATCHDOG_NOWAYOUT);
tqmx86_wdt_set_timeout(&priv->wdd, priv->wdd.timeout); 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) if (err)
return err; return err;
dev_info(&pdev->dev, "TQMx86 watchdog\n"); dev_info(dev, "TQMx86 watchdog\n");
return 0; return 0;
} }
......
...@@ -108,7 +108,8 @@ static const struct watchdog_info ts4800_wdt_info = { ...@@ -108,7 +108,8 @@ static const struct watchdog_info ts4800_wdt_info = {
static int ts4800_wdt_probe(struct platform_device *pdev) 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 device_node *syscon_np;
struct watchdog_device *wdd; struct watchdog_device *wdd;
struct ts4800_wdt *wdt; struct ts4800_wdt *wdt;
...@@ -117,18 +118,18 @@ static int ts4800_wdt_probe(struct platform_device *pdev) ...@@ -117,18 +118,18 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
syscon_np = of_parse_phandle(np, "syscon", 0); syscon_np = of_parse_phandle(np, "syscon", 0);
if (!syscon_np) { if (!syscon_np) {
dev_err(&pdev->dev, "no syscon property\n"); dev_err(dev, "no syscon property\n");
return -ENODEV; return -ENODEV;
} }
ret = of_property_read_u32_index(np, "syscon", 1, &reg); ret = of_property_read_u32_index(np, "syscon", 1, &reg);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "no offset in syscon\n"); dev_err(dev, "no offset in syscon\n");
return ret; return ret;
} }
/* allocate memory for watchdog struct */ /* allocate memory for watchdog struct */
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
...@@ -137,13 +138,13 @@ static int ts4800_wdt_probe(struct platform_device *pdev) ...@@ -137,13 +138,13 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
wdt->regmap = syscon_node_to_regmap(syscon_np); wdt->regmap = syscon_node_to_regmap(syscon_np);
of_node_put(syscon_np); of_node_put(syscon_np);
if (IS_ERR(wdt->regmap)) { 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); return PTR_ERR(wdt->regmap);
} }
/* Initialize struct watchdog_device */ /* Initialize struct watchdog_device */
wdd = &wdt->wdd; wdd = &wdt->wdd;
wdd->parent = &pdev->dev; wdd->parent = dev;
wdd->info = &ts4800_wdt_info; wdd->info = &ts4800_wdt_info;
wdd->ops = &ts4800_wdt_ops; wdd->ops = &ts4800_wdt_ops;
wdd->min_timeout = ts4800_wdt_map[0].timeout; wdd->min_timeout = ts4800_wdt_map[0].timeout;
...@@ -151,7 +152,7 @@ static int ts4800_wdt_probe(struct platform_device *pdev) ...@@ -151,7 +152,7 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdd, wdt); watchdog_set_drvdata(wdd, wdt);
watchdog_set_nowayout(wdd, nowayout); 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 * 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) ...@@ -169,31 +170,20 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
*/ */
ts4800_wdt_stop(wdd); ts4800_wdt_stop(wdd);
ret = watchdog_register_device(wdd); ret = devm_watchdog_register_device(dev, wdd);
if (ret) { if (ret) {
dev_err(&pdev->dev, dev_err(dev, "failed to register watchdog device\n");
"failed to register watchdog device\n");
return ret; return ret;
} }
platform_set_drvdata(pdev, wdt); platform_set_drvdata(pdev, wdt);
dev_info(&pdev->dev, dev_info(dev, "initialized (timeout = %d sec, nowayout = %d)\n",
"initialized (timeout = %d sec, nowayout = %d)\n",
wdd->timeout, nowayout); wdd->timeout, nowayout);
return 0; 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[] = { static const struct of_device_id ts4800_wdt_of_match[] = {
{ .compatible = "technologic,ts4800-wdt", }, { .compatible = "technologic,ts4800-wdt", },
{ }, { },
...@@ -202,7 +192,6 @@ MODULE_DEVICE_TABLE(of, ts4800_wdt_of_match); ...@@ -202,7 +192,6 @@ MODULE_DEVICE_TABLE(of, ts4800_wdt_of_match);
static struct platform_driver ts4800_wdt_driver = { static struct platform_driver ts4800_wdt_driver = {
.probe = ts4800_wdt_probe, .probe = ts4800_wdt_probe,
.remove = ts4800_wdt_remove,
.driver = { .driver = {
.name = "ts4800_wdt", .name = "ts4800_wdt",
.of_match_table = ts4800_wdt_of_match, .of_match_table = ts4800_wdt_of_match,
......
...@@ -122,22 +122,20 @@ static const struct watchdog_ops ts72xx_wdt_ops = { ...@@ -122,22 +122,20 @@ static const struct watchdog_ops ts72xx_wdt_ops = {
static int ts72xx_wdt_probe(struct platform_device *pdev) static int ts72xx_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct ts72xx_wdt_priv *priv; struct ts72xx_wdt_priv *priv;
struct watchdog_device *wdd; struct watchdog_device *wdd;
struct resource *res;
int ret; int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->control_reg = devm_platform_ioremap_resource(pdev, 0);
priv->control_reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->control_reg)) if (IS_ERR(priv->control_reg))
return PTR_ERR(priv->control_reg); return PTR_ERR(priv->control_reg);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1); priv->feed_reg = devm_platform_ioremap_resource(pdev, 1);
priv->feed_reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->feed_reg)) if (IS_ERR(priv->feed_reg))
return PTR_ERR(priv->feed_reg); return PTR_ERR(priv->feed_reg);
...@@ -146,20 +144,20 @@ static int ts72xx_wdt_probe(struct platform_device *pdev) ...@@ -146,20 +144,20 @@ static int ts72xx_wdt_probe(struct platform_device *pdev)
wdd->ops = &ts72xx_wdt_ops; wdd->ops = &ts72xx_wdt_ops;
wdd->min_timeout = 1; wdd->min_timeout = 1;
wdd->max_hw_heartbeat_ms = 8000; wdd->max_hw_heartbeat_ms = 8000;
wdd->parent = &pdev->dev; wdd->parent = dev;
watchdog_set_nowayout(wdd, nowayout); watchdog_set_nowayout(wdd, nowayout);
wdd->timeout = TS72XX_WDT_DEFAULT_TIMEOUT; wdd->timeout = TS72XX_WDT_DEFAULT_TIMEOUT;
watchdog_init_timeout(wdd, timeout, &pdev->dev); watchdog_init_timeout(wdd, timeout, dev);
watchdog_set_drvdata(wdd, priv); watchdog_set_drvdata(wdd, priv);
ret = devm_watchdog_register_device(&pdev->dev, wdd); ret = devm_watchdog_register_device(dev, wdd);
if (ret) if (ret)
return ret; return ret;
dev_info(&pdev->dev, "TS-72xx Watchdog driver\n"); dev_info(dev, "TS-72xx Watchdog driver\n");
return 0; return 0;
} }
......
...@@ -70,10 +70,10 @@ static const struct watchdog_ops twl4030_wdt_ops = { ...@@ -70,10 +70,10 @@ static const struct watchdog_ops twl4030_wdt_ops = {
static int twl4030_wdt_probe(struct platform_device *pdev) static int twl4030_wdt_probe(struct platform_device *pdev)
{ {
int ret = 0; struct device *dev = &pdev->dev;
struct watchdog_device *wdt; struct watchdog_device *wdt;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) if (!wdt)
return -ENOMEM; return -ENOMEM;
...@@ -83,27 +83,14 @@ static int twl4030_wdt_probe(struct platform_device *pdev) ...@@ -83,27 +83,14 @@ static int twl4030_wdt_probe(struct platform_device *pdev)
wdt->timeout = 30; wdt->timeout = 30;
wdt->min_timeout = 1; wdt->min_timeout = 1;
wdt->max_timeout = 30; wdt->max_timeout = 30;
wdt->parent = &pdev->dev; wdt->parent = dev;
watchdog_set_nowayout(wdt, nowayout); watchdog_set_nowayout(wdt, nowayout);
platform_set_drvdata(pdev, wdt); platform_set_drvdata(pdev, wdt);
twl4030_wdt_stop(wdt); twl4030_wdt_stop(wdt);
ret = watchdog_register_device(wdt); return devm_watchdog_register_device(dev, 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;
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -137,7 +124,6 @@ MODULE_DEVICE_TABLE(of, twl_wdt_of_match); ...@@ -137,7 +124,6 @@ MODULE_DEVICE_TABLE(of, twl_wdt_of_match);
static struct platform_driver twl4030_wdt_driver = { static struct platform_driver twl4030_wdt_driver = {
.probe = twl4030_wdt_probe, .probe = twl4030_wdt_probe,
.remove = twl4030_wdt_remove,
.suspend = twl4030_wdt_suspend, .suspend = twl4030_wdt_suspend,
.resume = twl4030_wdt_resume, .resume = twl4030_wdt_resume,
.driver = { .driver = {
......
...@@ -103,7 +103,6 @@ static struct watchdog_device txx9wdt = { ...@@ -103,7 +103,6 @@ static struct watchdog_device txx9wdt = {
static int __init txx9wdt_probe(struct platform_device *dev) static int __init txx9wdt_probe(struct platform_device *dev)
{ {
struct resource *res;
int ret; int ret;
txx9_imclk = clk_get(NULL, "imbus_clk"); txx9_imclk = clk_get(NULL, "imbus_clk");
...@@ -119,8 +118,7 @@ static int __init txx9wdt_probe(struct platform_device *dev) ...@@ -119,8 +118,7 @@ static int __init txx9wdt_probe(struct platform_device *dev)
goto exit; goto exit;
} }
res = platform_get_resource(dev, IORESOURCE_MEM, 0); txx9wdt_reg = devm_platform_ioremap_resource(dev, 0);
txx9wdt_reg = devm_ioremap_resource(&dev->dev, res);
if (IS_ERR(txx9wdt_reg)) { if (IS_ERR(txx9wdt_reg)) {
ret = PTR_ERR(txx9wdt_reg); ret = PTR_ERR(txx9wdt_reg);
goto exit; goto exit;
......
...@@ -191,8 +191,6 @@ static int uniphier_wdt_probe(struct platform_device *pdev) ...@@ -191,8 +191,6 @@ static int uniphier_wdt_probe(struct platform_device *pdev)
if (!wdev) if (!wdev)
return -ENOMEM; return -ENOMEM;
platform_set_drvdata(pdev, wdev);
parent = of_get_parent(dev->of_node); /* parent should be syscon node */ parent = of_get_parent(dev->of_node); /* parent should be syscon node */
regmap = syscon_node_to_regmap(parent); regmap = syscon_node_to_regmap(parent);
of_node_put(parent); of_node_put(parent);
......
...@@ -86,8 +86,9 @@ static struct watchdog_device ux500_wdt = { ...@@ -86,8 +86,9 @@ static struct watchdog_device ux500_wdt = {
static int ux500_wdt_probe(struct platform_device *pdev) static int ux500_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
int ret; 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) {
if (pdata->timeout > 0) if (pdata->timeout > 0)
...@@ -96,7 +97,7 @@ static int ux500_wdt_probe(struct platform_device *pdev) ...@@ -96,7 +97,7 @@ static int ux500_wdt_probe(struct platform_device *pdev)
ux500_wdt.max_timeout = WATCHDOG_MAX28; ux500_wdt.max_timeout = WATCHDOG_MAX28;
} }
ux500_wdt.parent = &pdev->dev; ux500_wdt.parent = dev;
watchdog_set_nowayout(&ux500_wdt, nowayout); watchdog_set_nowayout(&ux500_wdt, nowayout);
/* disable auto off on sleep */ /* disable auto off on sleep */
...@@ -105,18 +106,11 @@ static int ux500_wdt_probe(struct platform_device *pdev) ...@@ -105,18 +106,11 @@ static int ux500_wdt_probe(struct platform_device *pdev)
/* set HW initial value */ /* set HW initial value */
prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000); prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
ret = watchdog_register_device(&ux500_wdt); ret = devm_watchdog_register_device(dev, &ux500_wdt);
if (ret) if (ret)
return ret; return ret;
dev_info(&pdev->dev, "initialized\n"); dev_info(dev, "initialized\n");
return 0;
}
static int ux500_wdt_remove(struct platform_device *dev)
{
watchdog_unregister_device(&ux500_wdt);
return 0; return 0;
} }
...@@ -153,7 +147,6 @@ static int ux500_wdt_resume(struct platform_device *pdev) ...@@ -153,7 +147,6 @@ static int ux500_wdt_resume(struct platform_device *pdev)
static struct platform_driver ux500_wdt_driver = { static struct platform_driver ux500_wdt_driver = {
.probe = ux500_wdt_probe, .probe = ux500_wdt_probe,
.remove = ux500_wdt_remove,
.suspend = ux500_wdt_suspend, .suspend = ux500_wdt_suspend,
.resume = ux500_wdt_resume, .resume = ux500_wdt_resume,
.driver = { .driver = {
......
...@@ -105,34 +105,48 @@ static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) ...@@ -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 * 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). * (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 * 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, int watchdog_init_timeout(struct watchdog_device *wdd,
unsigned int timeout_parm, struct device *dev) 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; unsigned int t = 0;
int ret = 0; int ret = 0;
watchdog_check_min_max_timeout(wdd); watchdog_check_min_max_timeout(wdd);
/* try to get the timeout module parameter first */ /* check the driver supplied value (likely a module parameter) first */
if (!watchdog_timeout_invalid(wdd, timeout_parm) && timeout_parm) { if (timeout_parm) {
if (!watchdog_timeout_invalid(wdd, timeout_parm)) {
wdd->timeout = timeout_parm; wdd->timeout = timeout_parm;
return ret; return 0;
} }
if (timeout_parm) pr_err("%s: driver supplied timeout (%u) out of range\n",
dev_str, timeout_parm);
ret = -EINVAL; ret = -EINVAL;
}
/* try to get the timeout_sec property */ /* try to get the timeout_sec property */
if (dev == NULL || dev->of_node == NULL) if (dev && dev->of_node &&
return ret; of_property_read_u32(dev->of_node, "timeout-sec", &t) == 0) {
of_property_read_u32(dev->of_node, "timeout-sec", &t); if (t && !watchdog_timeout_invalid(wdd, t)) {
if (!watchdog_timeout_invalid(wdd, t) && t)
wdd->timeout = t; wdd->timeout = t;
else return 0;
}
pr_err("%s: DT supplied timeout (%u) out of range\n", dev_str, t);
ret = -EINVAL; ret = -EINVAL;
}
if (ret < 0 && wdd->timeout)
pr_warn("%s: falling back to default timeout (%u)\n", dev_str,
wdd->timeout);
return ret; return ret;
} }
......
...@@ -287,7 +287,7 @@ static unsigned int wdat_wdt_get_timeleft(struct watchdog_device *wdd) ...@@ -287,7 +287,7 @@ static unsigned int wdat_wdt_get_timeleft(struct watchdog_device *wdd)
struct wdat_wdt *wdat = to_wdat_wdt(wdd); struct wdat_wdt *wdat = to_wdat_wdt(wdd);
u32 periods = 0; 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; return periods * wdat->period / 1000;
} }
...@@ -308,6 +308,7 @@ static const struct watchdog_ops wdat_wdt_ops = { ...@@ -308,6 +308,7 @@ static const struct watchdog_ops wdat_wdt_ops = {
static int wdat_wdt_probe(struct platform_device *pdev) static int wdat_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
const struct acpi_wdat_entry *entries; const struct acpi_wdat_entry *entries;
const struct acpi_table_wdat *tbl; const struct acpi_table_wdat *tbl;
struct wdat_wdt *wdat; struct wdat_wdt *wdat;
...@@ -321,11 +322,11 @@ static int wdat_wdt_probe(struct platform_device *pdev) ...@@ -321,11 +322,11 @@ static int wdat_wdt_probe(struct platform_device *pdev)
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -ENODEV; return -ENODEV;
wdat = devm_kzalloc(&pdev->dev, sizeof(*wdat), GFP_KERNEL); wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL);
if (!wdat) if (!wdat)
return -ENOMEM; return -ENOMEM;
regs = devm_kcalloc(&pdev->dev, pdev->num_resources, sizeof(*regs), regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs),
GFP_KERNEL); GFP_KERNEL);
if (!regs) if (!regs)
return -ENOMEM; return -ENOMEM;
...@@ -350,15 +351,15 @@ static int wdat_wdt_probe(struct platform_device *pdev) ...@@ -350,15 +351,15 @@ static int wdat_wdt_probe(struct platform_device *pdev)
res = &pdev->resource[i]; res = &pdev->resource[i];
if (resource_type(res) == IORESOURCE_MEM) { if (resource_type(res) == IORESOURCE_MEM) {
reg = devm_ioremap_resource(&pdev->dev, res); reg = devm_ioremap_resource(dev, res);
if (IS_ERR(reg)) if (IS_ERR(reg))
return PTR_ERR(reg); return PTR_ERR(reg);
} else if (resource_type(res) == IORESOURCE_IO) { } 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) if (!reg)
return -ENOMEM; return -ENOMEM;
} else { } else {
dev_err(&pdev->dev, "Unsupported resource\n"); dev_err(dev, "Unsupported resource\n");
return -EINVAL; return -EINVAL;
} }
...@@ -376,12 +377,11 @@ static int wdat_wdt_probe(struct platform_device *pdev) ...@@ -376,12 +377,11 @@ static int wdat_wdt_probe(struct platform_device *pdev)
action = entries[i].action; action = entries[i].action;
if (action >= MAX_WDAT_ACTIONS) { if (action >= MAX_WDAT_ACTIONS) {
dev_dbg(&pdev->dev, "Skipping unknown action: %u\n", dev_dbg(dev, "Skipping unknown action: %u\n", action);
action);
continue; continue;
} }
instr = devm_kzalloc(&pdev->dev, sizeof(*instr), GFP_KERNEL); instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL);
if (!instr) if (!instr)
return -ENOMEM; return -ENOMEM;
...@@ -398,7 +398,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) ...@@ -398,7 +398,7 @@ static int wdat_wdt_probe(struct platform_device *pdev)
} else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
r.flags = IORESOURCE_IO; r.flags = IORESOURCE_IO;
} else { } else {
dev_dbg(&pdev->dev, "Unsupported address space: %d\n", dev_dbg(dev, "Unsupported address space: %d\n",
gas->space_id); gas->space_id);
continue; continue;
} }
...@@ -413,14 +413,15 @@ static int wdat_wdt_probe(struct platform_device *pdev) ...@@ -413,14 +413,15 @@ static int wdat_wdt_probe(struct platform_device *pdev)
} }
if (!instr->reg) { if (!instr->reg) {
dev_err(&pdev->dev, "I/O resource not found\n"); dev_err(dev, "I/O resource not found\n");
return -EINVAL; return -EINVAL;
} }
instructions = wdat->instructions[action]; instructions = wdat->instructions[action];
if (!instructions) { if (!instructions) {
instructions = devm_kzalloc(&pdev->dev, instructions = devm_kzalloc(dev,
sizeof(*instructions), GFP_KERNEL); sizeof(*instructions),
GFP_KERNEL);
if (!instructions) if (!instructions)
return -ENOMEM; return -ENOMEM;
...@@ -441,7 +442,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) ...@@ -441,7 +442,7 @@ static int wdat_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdat); platform_set_drvdata(pdev, wdat);
watchdog_set_nowayout(&wdat->wdd, nowayout); 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 #ifdef CONFIG_PM_SLEEP
......
...@@ -180,8 +180,9 @@ static const struct watchdog_ops wm831x_wdt_ops = { ...@@ -180,8 +180,9 @@ static const struct watchdog_ops wm831x_wdt_ops = {
static int wm831x_wdt_probe(struct platform_device *pdev) static int wm831x_wdt_probe(struct platform_device *pdev)
{ {
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct device *dev = &pdev->dev;
struct wm831x_pdata *chip_pdata = dev_get_platdata(pdev->dev.parent); 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_watchdog_pdata *pdata;
struct wm831x_wdt_drvdata *driver_data; struct wm831x_wdt_drvdata *driver_data;
struct watchdog_device *wm831x_wdt; struct watchdog_device *wm831x_wdt;
...@@ -198,8 +199,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev) ...@@ -198,8 +199,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
if (reg & WM831X_WDOG_DEBUG) if (reg & WM831X_WDOG_DEBUG)
dev_warn(wm831x->dev, "Watchdog is paused\n"); dev_warn(wm831x->dev, "Watchdog is paused\n");
driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
GFP_KERNEL);
if (!driver_data) if (!driver_data)
return -ENOMEM; return -ENOMEM;
...@@ -210,7 +210,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev) ...@@ -210,7 +210,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
wm831x_wdt->info = &wm831x_wdt_info; wm831x_wdt->info = &wm831x_wdt_info;
wm831x_wdt->ops = &wm831x_wdt_ops; wm831x_wdt->ops = &wm831x_wdt_ops;
wm831x_wdt->parent = &pdev->dev; wm831x_wdt->parent = dev;
watchdog_set_nowayout(wm831x_wdt, nowayout); watchdog_set_nowayout(wm831x_wdt, nowayout);
watchdog_set_drvdata(wm831x_wdt, driver_data); watchdog_set_drvdata(wm831x_wdt, driver_data);
...@@ -240,8 +240,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev) ...@@ -240,8 +240,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT; reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT;
if (pdata->update_gpio) { if (pdata->update_gpio) {
ret = devm_gpio_request_one(&pdev->dev, ret = devm_gpio_request_one(dev, pdata->update_gpio,
pdata->update_gpio,
GPIOF_OUT_INIT_LOW, GPIOF_OUT_INIT_LOW,
"Watchdog update"); "Watchdog update");
if (ret < 0) { if (ret < 0) {
...@@ -268,7 +267,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev) ...@@ -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) { if (ret != 0) {
dev_err(wm831x->dev, "watchdog_register_device() failed: %d\n", dev_err(wm831x->dev, "watchdog_register_device() failed: %d\n",
ret); ret);
......
...@@ -122,34 +122,32 @@ static struct watchdog_device xen_wdt_dev = { ...@@ -122,34 +122,32 @@ static struct watchdog_device xen_wdt_dev = {
static int xen_wdt_probe(struct platform_device *pdev) static int xen_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct sched_watchdog wd = { .id = ~0 }; struct sched_watchdog wd = { .id = ~0 };
int ret = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wd); int ret = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wd);
if (ret == -ENOSYS) { if (ret == -ENOSYS) {
dev_err(&pdev->dev, "watchdog not supported by hypervisor\n"); dev_err(dev, "watchdog not supported by hypervisor\n");
return -ENODEV; return -ENODEV;
} }
if (ret != -EINVAL) { if (ret != -EINVAL) {
dev_err(&pdev->dev, "unexpected hypervisor error (%d)\n", ret); dev_err(dev, "unexpected hypervisor error (%d)\n", ret);
return -ENODEV; return -ENODEV;
} }
if (watchdog_init_timeout(&xen_wdt_dev, timeout, NULL)) watchdog_init_timeout(&xen_wdt_dev, timeout, NULL);
dev_info(&pdev->dev, "timeout value invalid, using %d\n",
xen_wdt_dev.timeout);
watchdog_set_nowayout(&xen_wdt_dev, nowayout); watchdog_set_nowayout(&xen_wdt_dev, nowayout);
watchdog_stop_on_reboot(&xen_wdt_dev); watchdog_stop_on_reboot(&xen_wdt_dev);
watchdog_stop_on_unregister(&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) { if (ret) {
dev_err(&pdev->dev, "cannot register watchdog device (%d)\n", dev_err(dev, "cannot register watchdog device (%d)\n", ret);
ret);
return ret; return ret;
} }
dev_info(&pdev->dev, "initialized (timeout=%ds, nowayout=%d)\n", dev_info(dev, "initialized (timeout=%ds, nowayout=%d)\n",
xen_wdt_dev.timeout, nowayout); xen_wdt_dev.timeout, nowayout);
return 0; return 0;
......
...@@ -658,11 +658,7 @@ static int ziirave_wdt_probe(struct i2c_client *client, ...@@ -658,11 +658,7 @@ static int ziirave_wdt_probe(struct i2c_client *client,
w_priv->wdd.parent = &client->dev; w_priv->wdd.parent = &client->dev;
w_priv->wdd.groups = ziirave_wdt_groups; w_priv->wdd.groups = ziirave_wdt_groups;
ret = watchdog_init_timeout(&w_priv->wdd, wdt_timeout, &client->dev); watchdog_init_timeout(&w_priv->wdd, wdt_timeout, &client->dev);
if (ret) {
dev_info(&client->dev,
"Unable to select timeout value, using default\n");
}
/* /*
* The default value set in the watchdog should be perfectly valid, so * The default value set in the watchdog should be perfectly valid, so
......
...@@ -188,11 +188,15 @@ static void zx2967_wdt_reset_sysctrl(struct device *dev) ...@@ -188,11 +188,15 @@ static void zx2967_wdt_reset_sysctrl(struct device *dev)
of_node_put(out_args.np); 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) static int zx2967_wdt_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct zx2967_wdt *wdt; struct zx2967_wdt *wdt;
struct resource *base;
int ret; int ret;
struct reset_control *rstc; struct reset_control *rstc;
...@@ -207,10 +211,9 @@ static int zx2967_wdt_probe(struct platform_device *pdev) ...@@ -207,10 +211,9 @@ static int zx2967_wdt_probe(struct platform_device *pdev)
wdt->wdt_device.timeout = ZX2967_WDT_DEFAULT_TIMEOUT; wdt->wdt_device.timeout = ZX2967_WDT_DEFAULT_TIMEOUT;
wdt->wdt_device.max_timeout = ZX2967_WDT_MAX_TIMEOUT; wdt->wdt_device.max_timeout = ZX2967_WDT_MAX_TIMEOUT;
wdt->wdt_device.min_timeout = ZX2967_WDT_MIN_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_platform_ioremap_resource(pdev, 0);
wdt->reg_base = devm_ioremap_resource(dev, base);
if (IS_ERR(wdt->reg_base)) if (IS_ERR(wdt->reg_base))
return PTR_ERR(wdt->reg_base); return PTR_ERR(wdt->reg_base);
...@@ -227,13 +230,16 @@ static int zx2967_wdt_probe(struct platform_device *pdev) ...@@ -227,13 +230,16 @@ static int zx2967_wdt_probe(struct platform_device *pdev)
dev_err(dev, "failed to enable clock\n"); dev_err(dev, "failed to enable clock\n");
return ret; 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); clk_set_rate(wdt->clock, ZX2967_WDT_CLK_FREQ);
rstc = devm_reset_control_get_exclusive(dev, NULL); rstc = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(rstc)) { if (IS_ERR(rstc)) {
dev_err(dev, "failed to get rstc"); dev_err(dev, "failed to get rstc");
ret = PTR_ERR(rstc); return PTR_ERR(rstc);
goto err;
} }
reset_control_assert(rstc); reset_control_assert(rstc);
...@@ -244,28 +250,14 @@ static int zx2967_wdt_probe(struct platform_device *pdev) ...@@ -244,28 +250,14 @@ static int zx2967_wdt_probe(struct platform_device *pdev)
ZX2967_WDT_DEFAULT_TIMEOUT, dev); ZX2967_WDT_DEFAULT_TIMEOUT, dev);
watchdog_set_nowayout(&wdt->wdt_device, WATCHDOG_NOWAYOUT); 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) if (ret)
goto err; return ret;
dev_info(dev, "watchdog enabled (timeout=%d sec, nowayout=%d)", dev_info(dev, "watchdog enabled (timeout=%d sec, nowayout=%d)",
wdt->wdt_device.timeout, WATCHDOG_NOWAYOUT); wdt->wdt_device.timeout, WATCHDOG_NOWAYOUT);
return 0; 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[] = { static const struct of_device_id zx2967_wdt_match[] = {
...@@ -276,7 +268,6 @@ MODULE_DEVICE_TABLE(of, zx2967_wdt_match); ...@@ -276,7 +268,6 @@ MODULE_DEVICE_TABLE(of, zx2967_wdt_match);
static struct platform_driver zx2967_wdt_driver = { static struct platform_driver zx2967_wdt_driver = {
.probe = zx2967_wdt_probe, .probe = zx2967_wdt_probe,
.remove = zx2967_wdt_remove,
.driver = { .driver = {
.name = "zx2967-wdt", .name = "zx2967-wdt",
.of_match_table = of_match_ptr(zx2967_wdt_match), .of_match_table = of_match_ptr(zx2967_wdt_match),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment