aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorWim Van Sebroeck <wim@iguana.be>2006-09-10 06:48:15 -0400
committerWim Van Sebroeck <wim@iguana.be>2006-10-02 17:05:28 -0400
commit99d2853ac953900962d8191788060e80766eb214 (patch)
tree318eb3eb9dbf15059c81bc201e9c83599b60fbf5 /drivers/char
parentf676449785d333078acb60ccf2046d0d3c59548f (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')
-rw-r--r--drivers/char/watchdog/pnx4008_wdt.c12
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 @@
80static int nowayout = WATCHDOG_NOWAYOUT; 81static int nowayout = WATCHDOG_NOWAYOUT;
81static int heartbeat = DEFAULT_HEARTBEAT; 82static int heartbeat = DEFAULT_HEARTBEAT;
82 83
84static spinlock_t io_lock;
83static unsigned long wdt_status; 85static 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
95static void wdt_enable(void) 97static 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
118static void wdt_disable(void) 124static 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
125static int pnx4008_wdt_open(struct inode *inode, struct file *file) 135static 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