aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Leroy2018-11-21 08:51:45 +0000
committerTom Rini2018-12-03 10:44:10 -0500
commit749c9aae9d59c5f15832b51a75f8959c25316ab1 (patch)
treec015c00af11ab535a83030393c13ecc6ba901710
parentf55db0afa23de5beedb63c011a879ebbe0f61613 (diff)
drivers: watchdog: add a DM driver for the MPC8xx watchdog
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>
-rw-r--r--drivers/watchdog/Kconfig7
-rw-r--r--drivers/watchdog/mpc8xx_wdt.c51
2 files changed, 58 insertions, 0 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 4a9ebb6e268..b6974ad619a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -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
diff --git a/drivers/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c
index ccb06ac425f..c24c2a9da6d 100644
--- a/drivers/watchdog/mpc8xx_wdt.c
+++ b/drivers/watchdog/mpc8xx_wdt.c
@@ -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 */