diff options
| -rw-r--r-- | drivers/watchdog/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/watchdog/mpcore_wdt.c | 21 |
2 files changed, 12 insertions, 11 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 0bf5020d0d32..b87ba23442d2 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
| @@ -175,7 +175,7 @@ config SA1100_WATCHDOG | |||
| 175 | 175 | ||
| 176 | config MPCORE_WATCHDOG | 176 | config MPCORE_WATCHDOG |
| 177 | tristate "MPcore watchdog" | 177 | tristate "MPcore watchdog" |
| 178 | depends on ARM_MPCORE_PLATFORM && LOCAL_TIMERS | 178 | depends on HAVE_ARM_TWD |
| 179 | help | 179 | help |
| 180 | Watchdog timer embedded into the MPcore system. | 180 | Watchdog timer embedded into the MPcore system. |
| 181 | 181 | ||
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c index 016c6a791cab..b8ec7aca3c8e 100644 --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c | |||
| @@ -31,8 +31,9 @@ | |||
| 31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
| 32 | #include <linux/uaccess.h> | 32 | #include <linux/uaccess.h> |
| 33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
| 34 | #include <linux/io.h> | ||
| 34 | 35 | ||
| 35 | #include <asm/hardware/arm_twd.h> | 36 | #include <asm/smp_twd.h> |
| 36 | 37 | ||
| 37 | struct mpcore_wdt { | 38 | struct mpcore_wdt { |
| 38 | unsigned long timer_alive; | 39 | unsigned long timer_alive; |
| @@ -44,7 +45,7 @@ struct mpcore_wdt { | |||
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | static struct platform_device *mpcore_wdt_dev; | 47 | static struct platform_device *mpcore_wdt_dev; |
| 47 | extern unsigned int mpcore_timer_rate; | 48 | static DEFINE_SPINLOCK(wdt_lock); |
| 48 | 49 | ||
| 49 | #define TIMER_MARGIN 60 | 50 | #define TIMER_MARGIN 60 |
| 50 | static int mpcore_margin = TIMER_MARGIN; | 51 | static int mpcore_margin = TIMER_MARGIN; |
| @@ -94,13 +95,15 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg) | |||
| 94 | */ | 95 | */ |
| 95 | static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt) | 96 | static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt) |
| 96 | { | 97 | { |
| 97 | unsigned int count; | 98 | unsigned long count; |
| 98 | 99 | ||
| 100 | spin_lock(&wdt_lock); | ||
| 99 | /* Assume prescale is set to 256 */ | 101 | /* Assume prescale is set to 256 */ |
| 100 | count = (mpcore_timer_rate / 256) * mpcore_margin; | 102 | count = __raw_readl(wdt->base + TWD_WDOG_COUNTER); |
| 103 | count = (0xFFFFFFFFU - count) * (HZ / 5); | ||
| 104 | count = (count / 256) * mpcore_margin; | ||
| 101 | 105 | ||
| 102 | /* Reload the counter */ | 106 | /* Reload the counter */ |
| 103 | spin_lock(&wdt_lock); | ||
| 104 | writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); | 107 | writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); |
| 105 | wdt->perturb = wdt->perturb ? 0 : 1; | 108 | wdt->perturb = wdt->perturb ? 0 : 1; |
| 106 | spin_unlock(&wdt_lock); | 109 | spin_unlock(&wdt_lock); |
| @@ -119,7 +122,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt) | |||
| 119 | { | 122 | { |
| 120 | dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); | 123 | dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); |
| 121 | 124 | ||
| 122 | spin_lock(&wdt_lock); | ||
| 123 | /* This loads the count register but does NOT start the count yet */ | 125 | /* This loads the count register but does NOT start the count yet */ |
| 124 | mpcore_wdt_keepalive(wdt); | 126 | mpcore_wdt_keepalive(wdt); |
| 125 | 127 | ||
| @@ -130,7 +132,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt) | |||
| 130 | /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ | 132 | /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ |
| 131 | writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); | 133 | writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); |
| 132 | } | 134 | } |
| 133 | spin_unlock(&wdt_lock); | ||
| 134 | } | 135 | } |
| 135 | 136 | ||
| 136 | static int mpcore_wdt_set_heartbeat(int t) | 137 | static int mpcore_wdt_set_heartbeat(int t) |
| @@ -360,7 +361,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
| 360 | mpcore_wdt_miscdev.parent = &dev->dev; | 361 | mpcore_wdt_miscdev.parent = &dev->dev; |
| 361 | ret = misc_register(&mpcore_wdt_miscdev); | 362 | ret = misc_register(&mpcore_wdt_miscdev); |
| 362 | if (ret) { | 363 | if (ret) { |
| 363 | dev_printk(KERN_ERR, _dev, | 364 | dev_printk(KERN_ERR, wdt->dev, |
| 364 | "cannot register miscdev on minor=%d (err=%d)\n", | 365 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 365 | WATCHDOG_MINOR, ret); | 366 | WATCHDOG_MINOR, ret); |
| 366 | goto err_misc; | 367 | goto err_misc; |
| @@ -369,13 +370,13 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
| 369 | ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, | 370 | ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, |
| 370 | "mpcore_wdt", wdt); | 371 | "mpcore_wdt", wdt); |
| 371 | if (ret) { | 372 | if (ret) { |
| 372 | dev_printk(KERN_ERR, _dev, | 373 | dev_printk(KERN_ERR, wdt->dev, |
| 373 | "cannot register IRQ%d for watchdog\n", wdt->irq); | 374 | "cannot register IRQ%d for watchdog\n", wdt->irq); |
| 374 | goto err_irq; | 375 | goto err_irq; |
| 375 | } | 376 | } |
| 376 | 377 | ||
| 377 | mpcore_wdt_stop(wdt); | 378 | mpcore_wdt_stop(wdt); |
| 378 | platform_set_drvdata(&dev->dev, wdt); | 379 | platform_set_drvdata(dev, wdt); |
| 379 | mpcore_wdt_dev = dev; | 380 | mpcore_wdt_dev = dev; |
| 380 | 381 | ||
| 381 | return 0; | 382 | return 0; |
