
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(+)
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 */