[U-Boot,RFC,6/7] drivers: watchdog: add a driver for the MPC8xx watchdog
diff mbox series

Message ID 683f249a71ff77aa30224f41070422f68c28b1d8.1521044399.git.christophe.leroy@c-s.fr
State Superseded
Headers show
Series
  • Beginning of migration of MPC8xx to DM model
Related show

Commit Message

Christophe Leroy March 14, 2018, 5:16 p.m. UTC
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      |  6 +++++
 drivers/watchdog/mpc8xx_wdt.c | 51 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)

Patch
diff mbox series

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index fc46b6774d5..15d79ee5e17 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -78,4 +78,10 @@  config WDT_ORION
 	   Select this to enable Orion watchdog timer, which can be found on some
 	   Marvell Armada chips.
 
+config WDT_MPC8xx
+	bool "MPC8xx watchdog timer support"
+	depends on WDT && MPC8xx
+	help
+	   Select this to enable mpc8xx watchdog timer
+
 endmenu
diff --git a/drivers/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c
index ded80c4d6a9..29b185f45b3 100644
--- a/drivers/watchdog/mpc8xx_wdt.c
+++ b/drivers/watchdog/mpc8xx_wdt.c
@@ -5,6 +5,8 @@ 
  */
 
 #include <common.h>
+#include <dm.h>
+#include <wdt.h>
 #include <mpc8xx.h>
 #include <asm/cpm_8xx.h>
 #include <asm/io.h>
@@ -19,3 +21,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 */