--- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -188,7 +188,7 @@ config SA1100_WATCHDOG config MPCORE_WATCHDOG tristate "MPcore watchdog" - depends on HAVE_ARM_TWD + depends on ARCH_CNS3XXX help Watchdog timer embedded into the MPcore system. --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c @@ -32,11 +32,14 @@ #include #include #include +#include +#include #include struct mpcore_wdt { unsigned long timer_alive; + unsigned long timer_rate; struct device *dev; void __iomem *base; int irq; @@ -98,14 +101,12 @@ static void mpcore_wdt_keepalive(struct unsigned long count; spin_lock(&wdt_lock); - /* Assume prescale is set to 256 */ - count = __raw_readl(wdt->base + TWD_WDOG_COUNTER); - count = (0xFFFFFFFFU - count) * (HZ / 5); - count = (count / 256) * mpcore_margin; + count = (wdt->timer_rate / 256) * mpcore_margin; /* Reload the counter */ writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); wdt->perturb = wdt->perturb ? 0 : 1; + spin_unlock(&wdt_lock); } @@ -329,6 +330,8 @@ static int __devinit mpcore_wdt_probe(st struct mpcore_wdt *wdt; struct resource *res; int ret; + unsigned long count; + u64 waitjiffies; /* We only accept one device, and it must have an id of -1 */ if (dev->id != -1) @@ -375,6 +378,22 @@ static int __devinit mpcore_wdt_probe(st goto err_irq; } + waitjiffies = get_jiffies_64() + 1; + while (get_jiffies_64() < waitjiffies) + udelay(10); + + waitjiffies += 5; + + __raw_writel(0x00000001, wdt->base + TWD_WDOG_CONTROL); + __raw_writel(0xFFFFFFFFU, wdt->base + TWD_WDOG_LOAD); + + while (get_jiffies_64() < waitjiffies) + udelay(10); + + count = __raw_readl(wdt->base + TWD_WDOG_COUNTER); + + wdt->timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); + mpcore_wdt_stop(wdt); platform_set_drvdata(dev, wdt); mpcore_wdt_dev = dev;