diff options
Diffstat (limited to 'drivers/watchdog/at91sam9_wdt.c')
-rw-r--r-- | drivers/watchdog/at91sam9_wdt.c | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index c809a8936b8..72e13787448 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -38,7 +38,7 @@ DECLARE_GLOBAL_DATA_PTR; */ static int at91_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) { - struct at91_wdt_priv *priv = dev_get_priv(dev); + struct at91_wdt_priv *wdt = dev_get_priv(dev); u64 timeout; u32 ticks; @@ -49,7 +49,7 @@ static int at91_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) ticks = WDT_SEC2TICKS(timeout); /* Check if disabled */ - if (readl(priv->regs + AT91_WDT_MR) & AT91_WDT_MR_WDDIS) { + if (readl(wdt->regs + AT91_WDT_MR) & wdt->wddis) { printf("sorry, watchdog is disabled\n"); return -1; } @@ -60,31 +60,41 @@ static int at91_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) * Since WDV is a 12-bit counter, the maximum period is * 4096 / 256 = 16 seconds. */ - priv->regval = AT91_WDT_MR_WDRSTEN /* causes watchdog reset */ - | AT91_WDT_MR_WDDBGHLT /* disabled in debug mode */ - | AT91_WDT_MR_WDD(0xfff) /* restart at any time */ - | AT91_WDT_MR_WDV(ticks); /* timer value */ - writel(priv->regval, priv->regs + AT91_WDT_MR); + + if (wdt->mode == AT91_WDT_MODE_SAM9260) { + wdt->mr = AT91_WDT_MR_WDRSTEN /* causes watchdog reset */ + | AT91_WDT_MR_WDDBGHLT /* disabled in debug mode */ + | AT91_WDT_MR_WDD(0xfff) /* restart at any time */ + | AT91_WDT_MR_WDV(ticks); /* timer value */ + writel(wdt->mr, wdt->regs + AT91_WDT_MR); + } else if (wdt->mode == AT91_WDT_MODE_SAM9X60) { + writel(AT91_SAM9X60_WLR_COUNTER(ticks), /* timer value */ + wdt->regs + AT91_SAM9X60_WLR); + + wdt->mr = AT91_SAM9X60_MR_PERIODRST /* causes watchdog reset */ + | AT91_SAM9X60_MR_WDDBGHLT; /* disabled in debug mode */ + writel(wdt->mr, wdt->regs + AT91_WDT_MR); + } return 0; } static int at91_wdt_stop(struct udevice *dev) { - struct at91_wdt_priv *priv = dev_get_priv(dev); + struct at91_wdt_priv *wdt = dev_get_priv(dev); /* Disable Watchdog Timer */ - priv->regval |= AT91_WDT_MR_WDDIS; - writel(priv->regval, priv->regs + AT91_WDT_MR); + wdt->mr |= wdt->wddis; + writel(wdt->mr, wdt->regs + AT91_WDT_MR); return 0; } static int at91_wdt_reset(struct udevice *dev) { - struct at91_wdt_priv *priv = dev_get_priv(dev); + struct at91_wdt_priv *wdt = dev_get_priv(dev); - writel(AT91_WDT_CR_WDRSTT | AT91_WDT_CR_KEY, priv->regs + AT91_WDT_CR); + writel(AT91_WDT_CR_WDRSTT | AT91_WDT_CR_KEY, wdt->regs + AT91_WDT_CR); return 0; } @@ -96,18 +106,31 @@ static const struct wdt_ops at91_wdt_ops = { }; static const struct udevice_id at91_wdt_ids[] = { - { .compatible = "atmel,at91sam9260-wdt" }, + { .compatible = "atmel,at91sam9260-wdt", + .data = AT91_WDT_MODE_SAM9260 }, + { .compatible = "atmel,sama5d4-wdt", + .data = AT91_WDT_MODE_SAM9260 }, + { .compatible = "microchip,sam9x60-wdt", + .data = AT91_WDT_MODE_SAM9X60 }, + { .compatible = "microchip,sama7g5-wdt", + .data = AT91_WDT_MODE_SAM9X60 }, {} }; static int at91_wdt_probe(struct udevice *dev) { - struct at91_wdt_priv *priv = dev_get_priv(dev); + struct at91_wdt_priv *wdt = dev_get_priv(dev); - priv->regs = dev_remap_addr(dev); - if (!priv->regs) + wdt->regs = dev_remap_addr(dev); + if (!wdt->regs) return -EINVAL; + wdt->mode = dev_get_driver_data(dev); + if (wdt->mode == AT91_WDT_MODE_SAM9260) + wdt->wddis = AT91_WDT_MR_WDDIS; + else if (wdt->mode == AT91_WDT_MODE_SAM9X60) + wdt->wddis = AT91_SAM9X60_MR_WDDIS; + debug("%s: Probing wdt%u\n", __func__, dev_seq(dev)); return 0; |