diff options
author | Wim Van Sebroeck <wim@iguana.be> | 2006-09-10 12:48:15 +0200 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2006-10-02 23:05:28 +0200 |
commit | 99d2853ac953900962d8191788060e80766eb214 (patch) | |
tree | 318eb3eb9dbf15059c81bc201e9c83599b60fbf5 /drivers/char | |
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')
-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 465dfd3ba61..359168e63c1 100644 --- a/drivers/char/watchdog/pnx4008_wdt.c +++ b/drivers/char/watchdog/pnx4008_wdt.c @@ -28,6 +28,7 @@ #include <linux/device.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/spinlock.h> #include <asm/hardware.h> #include <asm/uaccess.h> @@ -80,6 +81,7 @@ static int nowayout = WATCHDOG_NOWAYOUT; static int heartbeat = DEFAULT_HEARTBEAT; +static spinlock_t io_lock; static unsigned long wdt_status; #define WDT_IN_USE 0 #define WDT_OK_TO_CLOSE 1 @@ -94,6 +96,8 @@ struct clk *wdt_clk; static void wdt_enable(void) { + spin_lock(&io_lock); + if (wdt_clk) clk_set_rate(wdt_clk, 1); @@ -113,13 +117,19 @@ static void wdt_enable(void) __raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base)); /*enable counter, stop when debugger active */ __raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base)); + + spin_unlock(&io_lock); } static void wdt_disable(void) { + spin_lock(&io_lock); + __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ if (wdt_clk) clk_set_rate(wdt_clk, 0); + + spin_unlock(&io_lock); } static int pnx4008_wdt_open(struct inode *inode, struct file *file) @@ -248,6 +258,8 @@ static int pnx4008_wdt_probe(struct platform_device *pdev) int ret = 0, size; struct resource *res; + spin_lock_init(&io_lock); + if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) heartbeat = DEFAULT_HEARTBEAT; |