OSDN Git Service

Merge tag 'linux-watchdog-5.2-rc1' of git://www.linux-watchdog.org/linux-watchdog
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 May 2019 13:20:42 +0000 (09:20 -0400)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 May 2019 13:20:42 +0000 (09:20 -0400)
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
  ...

99 files changed:
Documentation/devicetree/bindings/watchdog/fsl-imx-sc-wdt.txt [new file with mode: 0644]
Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/alim7101_wdt.c
drivers/watchdog/armada_37xx_wdt.c
drivers/watchdog/asm9260_wdt.c
drivers/watchdog/aspeed_wdt.c
drivers/watchdog/at91sam9_wdt.c
drivers/watchdog/ath79_wdt.c
drivers/watchdog/atlas7_wdt.c
drivers/watchdog/bcm2835_wdt.c
drivers/watchdog/bcm7038_wdt.c
drivers/watchdog/bcm_kona_wdt.c
drivers/watchdog/bd70528_wdt.c [new file with mode: 0644]
drivers/watchdog/cadence_wdt.c
drivers/watchdog/coh901327_wdt.c
drivers/watchdog/da9052_wdt.c
drivers/watchdog/da9055_wdt.c
drivers/watchdog/da9062_wdt.c
drivers/watchdog/da9063_wdt.c
drivers/watchdog/davinci_wdt.c
drivers/watchdog/digicolor_wdt.c
drivers/watchdog/dw_wdt.c
drivers/watchdog/ebc-c384_wdt.c
drivers/watchdog/ep93xx_wdt.c
drivers/watchdog/f71808e_wdt.c
drivers/watchdog/ftwdt010_wdt.c
drivers/watchdog/gpio_wdt.c
drivers/watchdog/hpwdt.c
drivers/watchdog/i6300esb.c
drivers/watchdog/iTCO_wdt.c
drivers/watchdog/imgpdc_wdt.c
drivers/watchdog/imx2_wdt.c
drivers/watchdog/imx_sc_wdt.c [new file with mode: 0644]
drivers/watchdog/intel-mid_wdt.c
drivers/watchdog/intel_scu_watchdog.c
drivers/watchdog/jz4740_wdt.c
drivers/watchdog/kempld_wdt.c
drivers/watchdog/lantiq_wdt.c
drivers/watchdog/loongson1_wdt.c
drivers/watchdog/lpc18xx_wdt.c
drivers/watchdog/machzwd.c
drivers/watchdog/max63xx_wdt.c
drivers/watchdog/max77620_wdt.c
drivers/watchdog/mena21_wdt.c
drivers/watchdog/menf21bmc_wdt.c
drivers/watchdog/meson_gxbb_wdt.c
drivers/watchdog/meson_wdt.c
drivers/watchdog/mlx_wdt.c
drivers/watchdog/moxart_wdt.c
drivers/watchdog/mpc8xxx_wdt.c
drivers/watchdog/mt7621_wdt.c
drivers/watchdog/mtk_wdt.c
drivers/watchdog/ni903x_wdt.c
drivers/watchdog/nic7018_wdt.c
drivers/watchdog/npcm_wdt.c
drivers/watchdog/nuc900_wdt.c
drivers/watchdog/of_xilinx_wdt.c
drivers/watchdog/omap_wdt.c
drivers/watchdog/orion_wdt.c
drivers/watchdog/pic32-dmt.c
drivers/watchdog/pic32-wdt.c
drivers/watchdog/pm8916_wdt.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/qcom-wdt.c
drivers/watchdog/renesas_wdt.c
drivers/watchdog/rn5t618_wdt.c
drivers/watchdog/rt2880_wdt.c
drivers/watchdog/rtd119x_wdt.c
drivers/watchdog/rza_wdt.c
drivers/watchdog/s3c2410_wdt.c
drivers/watchdog/sama5d4_wdt.c
drivers/watchdog/sb_wdog.c
drivers/watchdog/sbsa_gwdt.c
drivers/watchdog/shwdt.c
drivers/watchdog/sirfsoc_wdt.c
drivers/watchdog/sp5100_tco.c
drivers/watchdog/sprd_wdt.c
drivers/watchdog/st_lpc_wdt.c
drivers/watchdog/stm32_iwdg.c
drivers/watchdog/stmp3xxx_rtc_wdt.c
drivers/watchdog/stpmic1_wdt.c
drivers/watchdog/sunxi_wdt.c
drivers/watchdog/tangox_wdt.c
drivers/watchdog/tegra_wdt.c
drivers/watchdog/tqmx86_wdt.c
drivers/watchdog/ts4800_wdt.c
drivers/watchdog/ts72xx_wdt.c
drivers/watchdog/twl4030_wdt.c
drivers/watchdog/txx9wdt.c
drivers/watchdog/uniphier_wdt.c
drivers/watchdog/ux500_wdt.c
drivers/watchdog/watchdog_core.c
drivers/watchdog/wdat_wdt.c
drivers/watchdog/wm831x_wdt.c
drivers/watchdog/xen_wdt.c
drivers/watchdog/ziirave_wdt.c
drivers/watchdog/zx2967_wdt.c

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