aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/coh901327_wdt.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@stericsson.com>2009-07-21 00:40:46 +0200
committerWim Van Sebroeck <wim@iguana.be>2009-08-02 19:56:30 +0000
commit5973bee46fe66db94fab198979dec87f263fc2a8 (patch)
treef252e44eeea16d183e993d8e8deb7cf87e8db124 /drivers/watchdog/coh901327_wdt.c
parented680c4ad478d0fee9740f7d029087f181346564 (diff)
downloadkernel_samsung_aries-5973bee46fe66db94fab198979dec87f263fc2a8.zip
kernel_samsung_aries-5973bee46fe66db94fab198979dec87f263fc2a8.tar.gz
kernel_samsung_aries-5973bee46fe66db94fab198979dec87f263fc2a8.tar.bz2
[WATCHDOG] Fix COH 901 327 watchdog enablement
Since the COH 901 327 found in U300 is clocked at 32 kHz we need to wait for the interrupt clearing flag to propagate through hardware in order not to accidentally fire off any interrupts when we enable them. Signed-off-by: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog/coh901327_wdt.c')
-rw-r--r--drivers/watchdog/coh901327_wdt.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index fecb307..aec7cef 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -18,6 +18,7 @@
#include <linux/bitops.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
+#include <linux/delay.h>
#define DRV_NAME "WDOG COH 901 327"
@@ -92,6 +93,8 @@ static struct clk *clk;
static void coh901327_enable(u16 timeout)
{
u16 val;
+ unsigned long freq;
+ unsigned long delay_ns;
clk_enable(clk);
/* Restart timer if it is disabled */
@@ -102,6 +105,14 @@ static void coh901327_enable(u16 timeout)
/* Acknowledge any pending interrupt so it doesn't just fire off */
writew(U300_WDOG_IER_WILL_BARK_IRQ_ACK_ENABLE,
virtbase + U300_WDOG_IER);
+ /*
+ * The interrupt is cleared in the 32 kHz clock domain.
+ * Wait 3 32 kHz cycles for it to take effect
+ */
+ freq = clk_get_rate(clk);
+ delay_ns = (1000000000 + freq - 1) / freq; /* Freq to ns and round up */
+ delay_ns = 3 * delay_ns; /* Wait 3 cycles */
+ ndelay(delay_ns);
/* Enable the watchdog interrupt */
writew(U300_WDOG_IMR_WILL_BARK_IRQ_ENABLE, virtbase + U300_WDOG_IMR);
/* Activate the watchdog timer */