aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/orion5x_wdt.c
diff options
context:
space:
mode:
authorWim Van Sebroeck <wim@iguana.be>2008-10-02 05:32:45 -0400
committerWim Van Sebroeck <wim@iguana.be>2008-10-10 09:17:43 -0400
commit6d0f0dfdbc8bdb0c52759224b0d423c35f828397 (patch)
tree878f982d59c70af592fef43f1fbddcafba134254 /drivers/watchdog/orion5x_wdt.c
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/orion5x_wdt.c')
-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 144776314989..14a339f58b6a 100644
--- a/drivers/watchdog/orion5x_wdt.c
+++ b/drivers/watchdog/orion5x_wdt.c
@@ -20,6 +20,7 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/uaccess.h> 21#include <linux/uaccess.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/spinlock.h>
23 24
24/* 25/*
25 * Watchdog timer block registers. 26 * Watchdog timer block registers.
@@ -35,11 +36,14 @@
35static int nowayout = WATCHDOG_NOWAYOUT; 36static int nowayout = WATCHDOG_NOWAYOUT;
36static int heartbeat = WDT_MAX_DURATION; /* (seconds) */ 37static int heartbeat = WDT_MAX_DURATION; /* (seconds) */
37static unsigned long wdt_status; 38static unsigned long wdt_status;
39static spinlock_t wdt_lock;
38 40
39static void wdt_enable(void) 41static void wdt_enable(void)
40{ 42{
41 u32 reg; 43 u32 reg;
42 44
45 spin_lock(&wdt_lock);
46
43 /* Set watchdog duration */ 47 /* Set watchdog duration */
44 writel(ORION5X_TCLK * heartbeat, WDT_VAL); 48 writel(ORION5X_TCLK * heartbeat, WDT_VAL);
45 49
@@ -57,12 +61,16 @@ static void wdt_enable(void)
57 reg = readl(CPU_RESET_MASK); 61 reg = readl(CPU_RESET_MASK);
58 reg |= WDT_RESET; 62 reg |= WDT_RESET;
59 writel(reg, CPU_RESET_MASK); 63 writel(reg, CPU_RESET_MASK);
64
65 spin_unlock(&wdt_lock);
60} 66}
61 67
62static void wdt_disable(void) 68static void wdt_disable(void)
63{ 69{
64 u32 reg; 70 u32 reg;
65 71
72 spin_lock(&wdt_lock);
73
66 /* Disable reset on watchdog */ 74 /* Disable reset on watchdog */
67 reg = readl(CPU_RESET_MASK); 75 reg = readl(CPU_RESET_MASK);
68 reg &= ~WDT_RESET; 76 reg &= ~WDT_RESET;
@@ -72,6 +80,16 @@ static void wdt_disable(void)
72 reg = readl(TIMER_CTRL); 80 reg = readl(TIMER_CTRL);
73 reg &= ~WDT_EN; 81 reg &= ~WDT_EN;
74 writel(reg, TIMER_CTRL); 82 writel(reg, TIMER_CTRL);
83
84 spin_unlock(&wdt_lock);
85}
86
87static int orion5x_wdt_get_timeleft(int *time_left)
88{
89 spin_lock(&wdt_lock);
90 *time_left = readl(WDT_VAL) / ORION5X_TCLK;
91 spin_unlock(&wdt_lock);
92 return 0;
75} 93}
76 94
77static int orion5x_wdt_open(struct inode *inode, struct file *file) 95static 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)
83 return nonseekable_open(inode, file); 101 return nonseekable_open(inode, file);
84} 102}
85 103
86static int orion5x_wdt_get_timeleft(int *time_left)
87{
88 *time_left = readl(WDT_VAL) / ORION5X_TCLK;
89 return 0;
90}
91
92static ssize_t orion5x_wdt_write(struct file *file, const char *data, 104static ssize_t orion5x_wdt_write(struct file *file, const char *data,
93 size_t len, loff_t *ppos) 105 size_t len, loff_t *ppos)
94{ 106{
@@ -201,6 +213,8 @@ static int __init orion5x_wdt_init(void)
201{ 213{
202 int ret; 214 int ret;
203 215
216 spin_lock_init(&wdt_lock);
217
204 ret = misc_register(&orion5x_wdt_miscdev); 218 ret = misc_register(&orion5x_wdt_miscdev);
205 if (ret == 0) 219 if (ret == 0)
206 printk("Orion5x Watchdog Timer: heartbeat %d sec\n", 220 printk("Orion5x Watchdog Timer: heartbeat %d sec\n",