[WATCHDOG] orion5x_wdt.c: add spinlocking
authorWim Van Sebroeck <wim@iguana.be>
Thu, 2 Oct 2008 09:32:45 +0000 (09:32 +0000)
committerWim Van Sebroeck <wim@iguana.be>
Fri, 10 Oct 2008 13:17:43 +0000 (13:17 +0000)
Add spin_locking to orion5x_wdt.c to prevent races.

Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
drivers/watchdog/orion5x_wdt.c

index 144776314989a1378602c2f4d6c3b65f6f38d3b6..14a339f58b6a7627c3a4f82665a1fe70ecd8c907 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/spinlock.h>
 
 /*
  * Watchdog timer block registers.
 static int nowayout = WATCHDOG_NOWAYOUT;
 static int heartbeat =  WDT_MAX_DURATION;      /* (seconds) */
 static unsigned long wdt_status;
+static spinlock_t wdt_lock;
 
 static void wdt_enable(void)
 {
        u32 reg;
 
+       spin_lock(&wdt_lock);
+
        /* Set watchdog duration */
        writel(ORION5X_TCLK * heartbeat, WDT_VAL);
 
@@ -57,12 +61,16 @@ static void wdt_enable(void)
        reg = readl(CPU_RESET_MASK);
        reg |= WDT_RESET;
        writel(reg, CPU_RESET_MASK);
+
+       spin_unlock(&wdt_lock);
 }
 
 static void wdt_disable(void)
 {
        u32 reg;
 
+       spin_lock(&wdt_lock);
+
        /* Disable reset on watchdog */
        reg = readl(CPU_RESET_MASK);
        reg &= ~WDT_RESET;
@@ -72,6 +80,16 @@ static void wdt_disable(void)
        reg = readl(TIMER_CTRL);
        reg &= ~WDT_EN;
        writel(reg, TIMER_CTRL);
+
+       spin_unlock(&wdt_lock);
+}
+
+static int orion5x_wdt_get_timeleft(int *time_left)
+{
+       spin_lock(&wdt_lock);
+       *time_left = readl(WDT_VAL) / ORION5X_TCLK;
+       spin_unlock(&wdt_lock);
+       return 0;
 }
 
 static int orion5x_wdt_open(struct inode *inode, struct file *file)
@@ -83,12 +101,6 @@ static int orion5x_wdt_open(struct inode *inode, struct file *file)
        return nonseekable_open(inode, file);
 }
 
-static int orion5x_wdt_get_timeleft(int *time_left)
-{
-       *time_left = readl(WDT_VAL) / ORION5X_TCLK;
-       return 0;
-}
-
 static ssize_t orion5x_wdt_write(struct file *file, const char *data,
                                        size_t len, loff_t *ppos)
 {
@@ -201,6 +213,8 @@ static int __init orion5x_wdt_init(void)
 {
        int ret;
 
+       spin_lock_init(&wdt_lock);
+
        ret = misc_register(&orion5x_wdt_miscdev);
        if (ret == 0)
                printk("Orion5x Watchdog Timer: heartbeat %d sec\n",