diff options
author | Wim Van Sebroeck <wim@iguana.be> | 2006-09-10 06:48:15 -0400 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2006-10-02 17:05:28 -0400 |
commit | 99d2853ac953900962d8191788060e80766eb214 (patch) | |
tree | 318eb3eb9dbf15059c81bc201e9c83599b60fbf5 /drivers/char/watchdog/pnx4008_wdt.c | |
parent | f676449785d333078acb60ccf2046d0d3c59548f (diff) |
[WATCHDOG] pnx4008_wdt.c - spinlock fixes.
Add io spinlocks to prevent possible race
conditions between start and stop operations
that are issued from different child processes
where the master process opened /dev/watchdog.
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/char/watchdog/pnx4008_wdt.c')
-rw-r--r-- | drivers/char/watchdog/pnx4008_wdt.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/char/watchdog/pnx4008_wdt.c b/drivers/char/watchdog/pnx4008_wdt.c index 465dfd3ba61a..359168e63c1d 100644 --- a/drivers/char/watchdog/pnx4008_wdt.c +++ b/drivers/char/watchdog/pnx4008_wdt.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/device.h> | 28 | #include <linux/device.h> |
29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
31 | #include <linux/spinlock.h> | ||
31 | 32 | ||
32 | #include <asm/hardware.h> | 33 | #include <asm/hardware.h> |
33 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
@@ -80,6 +81,7 @@ | |||
80 | static int nowayout = WATCHDOG_NOWAYOUT; | 81 | static int nowayout = WATCHDOG_NOWAYOUT; |
81 | static int heartbeat = DEFAULT_HEARTBEAT; | 82 | static int heartbeat = DEFAULT_HEARTBEAT; |
82 | 83 | ||
84 | static spinlock_t io_lock; | ||
83 | static unsigned long wdt_status; | 85 | static unsigned long wdt_status; |
84 | #define WDT_IN_USE 0 | 86 | #define WDT_IN_USE 0 |
85 | #define WDT_OK_TO_CLOSE 1 | 87 | #define WDT_OK_TO_CLOSE 1 |
@@ -94,6 +96,8 @@ struct clk *wdt_clk; | |||
94 | 96 | ||
95 | static void wdt_enable(void) | 97 | static void wdt_enable(void) |
96 | { | 98 | { |
99 | spin_lock(&io_lock); | ||
100 | |||
97 | if (wdt_clk) | 101 | if (wdt_clk) |
98 | clk_set_rate(wdt_clk, 1); | 102 | clk_set_rate(wdt_clk, 1); |
99 | 103 | ||
@@ -113,13 +117,19 @@ static void wdt_enable(void) | |||
113 | __raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base)); | 117 | __raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base)); |
114 | /*enable counter, stop when debugger active */ | 118 | /*enable counter, stop when debugger active */ |
115 | __raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base)); | 119 | __raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base)); |
120 | |||
121 | spin_unlock(&io_lock); | ||
116 | } | 122 | } |
117 | 123 | ||
118 | static void wdt_disable(void) | 124 | static void wdt_disable(void) |
119 | { | 125 | { |
126 | spin_lock(&io_lock); | ||
127 | |||
120 | __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ | 128 | __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ |
121 | if (wdt_clk) | 129 | if (wdt_clk) |
122 | clk_set_rate(wdt_clk, 0); | 130 | clk_set_rate(wdt_clk, 0); |
131 | |||
132 | spin_unlock(&io_lock); | ||
123 | } | 133 | } |
124 | 134 | ||
125 | static int pnx4008_wdt_open(struct inode *inode, struct file *file) | 135 | static int pnx4008_wdt_open(struct inode *inode, struct file *file) |
@@ -248,6 +258,8 @@ static int pnx4008_wdt_probe(struct platform_device *pdev) | |||
248 | int ret = 0, size; | 258 | int ret = 0, size; |
249 | struct resource *res; | 259 | struct resource *res; |
250 | 260 | ||
261 | spin_lock_init(&io_lock); | ||
262 | |||
251 | if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) | 263 | if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) |
252 | heartbeat = DEFAULT_HEARTBEAT; | 264 | heartbeat = DEFAULT_HEARTBEAT; |
253 | 265 | ||