Commit 99d2853a authored by Wim Van Sebroeck's avatar Wim Van Sebroeck

[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: default avatarWim Van Sebroeck <wim@iguana.be>
parent f6764497
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/spinlock.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -80,6 +81,7 @@ ...@@ -80,6 +81,7 @@
static int nowayout = WATCHDOG_NOWAYOUT; static int nowayout = WATCHDOG_NOWAYOUT;
static int heartbeat = DEFAULT_HEARTBEAT; static int heartbeat = DEFAULT_HEARTBEAT;
static spinlock_t io_lock;
static unsigned long wdt_status; static unsigned long wdt_status;
#define WDT_IN_USE 0 #define WDT_IN_USE 0
#define WDT_OK_TO_CLOSE 1 #define WDT_OK_TO_CLOSE 1
...@@ -94,6 +96,8 @@ struct clk *wdt_clk; ...@@ -94,6 +96,8 @@ struct clk *wdt_clk;
static void wdt_enable(void) static void wdt_enable(void)
{ {
spin_lock(&io_lock);
if (wdt_clk) if (wdt_clk)
clk_set_rate(wdt_clk, 1); clk_set_rate(wdt_clk, 1);
...@@ -113,13 +117,19 @@ static void wdt_enable(void) ...@@ -113,13 +117,19 @@ static void wdt_enable(void)
__raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base)); __raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base));
/*enable counter, stop when debugger active */ /*enable counter, stop when debugger active */
__raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base)); __raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base));
spin_unlock(&io_lock);
} }
static void wdt_disable(void) static void wdt_disable(void)
{ {
spin_lock(&io_lock);
__raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */
if (wdt_clk) if (wdt_clk)
clk_set_rate(wdt_clk, 0); clk_set_rate(wdt_clk, 0);
spin_unlock(&io_lock);
} }
static int pnx4008_wdt_open(struct inode *inode, struct file *file) 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,6 +258,8 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
int ret = 0, size; int ret = 0, size;
struct resource *res; struct resource *res;
spin_lock_init(&io_lock);
if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
heartbeat = DEFAULT_HEARTBEAT; heartbeat = DEFAULT_HEARTBEAT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment