aboutsummaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorWim Van Sebroeck <wim@iguana.be>2008-10-02 09:32:45 +0000
committerWim Van Sebroeck <wim@iguana.be>2008-10-10 13:17:43 +0000
commit6d0f0dfdbc8bdb0c52759224b0d423c35f828397 (patch)
tree878f982d59c70af592fef43f1fbddcafba134254 /drivers/watchdog
parent22ac92322c83334b562024414b770e48927ae963 (diff)
[WATCHDOG] orion5x_wdt.c: add spinlocking
Add spin_locking to orion5x_wdt.c to prevent races. Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/orion5x_wdt.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/watchdog/orion5x_wdt.c b/drivers/watchdog/orion5x_wdt.c
index 14477631498..14a339f58b6 100644
--- a/drivers/watchdog/orion5x_wdt.c
+++ b/drivers/watchdog/orion5x_wdt.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+#include <linux/spinlock.h>
/*
* Watchdog timer block registers.
@@ -35,11 +36,14 @@
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",