drivers: watchdog: add a DM driver for the MPC8xx watchdog
authorChristophe Leroy <christophe.leroy@c-s.fr>
Wed, 21 Nov 2018 08:51:45 +0000 (08:51 +0000)
committerTom Rini <trini@konsulko.com>
Mon, 3 Dec 2018 15:44:10 +0000 (10:44 -0500)
This patch adds a DM driver for the MPC8xx watchdog.
Basically, the watchdog is enabled by default from the start and
SYPCR register has to be writen once to set the timeout and/or
deactivate the watchdog. Once written, it cannot be written again.

It means that wdt_stop() can be called before wdt_start() to stop the
watchdog, but cannot be called if wdt_start() has been called.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
drivers/watchdog/Kconfig
drivers/watchdog/mpc8xx_wdt.c

index 4a9ebb6..b6974ad 100644 (file)
@@ -144,4 +144,11 @@ config WDT_MT7621
           Select this to enable Ralink / Mediatek watchdog timer,
           which can be found on some MediaTek chips.
 
+config WDT_MPC8xx
+       bool "MPC8xx watchdog timer support"
+       depends on WDT && MPC8xx
+       select CONFIG_MPC8xx_WATCHDOG
+       help
+          Select this to enable mpc8xx watchdog timer
+
 endmenu
index ccb06ac..c24c2a9 100644 (file)
@@ -4,6 +4,8 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <wdt.h>
 #include <mpc8xx.h>
 #include <asm/cpm_8xx.h>
 #include <asm/io.h>
@@ -16,3 +18,52 @@ void hw_watchdog_reset(void)
        out_be16(&immap->im_siu_conf.sc_swsr, 0xaa39);  /* write magic2 */
 }
 
+#ifdef CONFIG_WDT_MPC8xx
+static int mpc8xx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+       immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
+
+       out_be32(&immap->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR);
+
+       if (!(in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE))
+               return -EBUSY;
+       return 0;
+
+}
+
+static int mpc8xx_wdt_stop(struct udevice *dev)
+{
+       immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
+
+       out_be32(&immap->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR & ~SYPCR_SWE);
+
+       if (in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE)
+               return -EBUSY;
+       return 0;
+}
+
+static int mpc8xx_wdt_reset(struct udevice *dev)
+{
+       hw_watchdog_reset();
+
+       return 0;
+}
+
+static const struct wdt_ops mpc8xx_wdt_ops = {
+       .start = mpc8xx_wdt_start,
+       .reset = mpc8xx_wdt_reset,
+       .stop = mpc8xx_wdt_stop,
+};
+
+static const struct udevice_id mpc8xx_wdt_ids[] = {
+       { .compatible = "fsl,pq1-wdt" },
+       {}
+};
+
+U_BOOT_DRIVER(wdt_mpc8xx) = {
+       .name = "wdt_mpc8xx",
+       .id = UCLASS_WDT,
+       .of_match = mpc8xx_wdt_ids,
+       .ops = &mpc8xx_wdt_ops,
+};
+#endif /* CONFIG_WDT_MPC8xx */