aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Anderson <dianders@chromium.org>2015-05-08 00:27:44 -0400
committerWim Van Sebroeck <wim@iguana.be>2015-06-22 09:54:31 -0400
commit7fb466a7a7362de19b8f2aa07cffa79e527cf070 (patch)
tree8f3253b98f415320f7cf003bfc5ec0d118ef4fd3
parent30dd4a8f08b570b5ed978fd937fdb5c31194be41 (diff)
watchdog: dw_wdt: No need for a spinlock
Right now the dw_wdt uses a spinlock to protect dw_wdt_open(). The problem is that while holding the spinlock we call: -> dw_wdt_set_top() -> dw_wdt_top_in_seconds() -> clk_get_rate() -> clk_prepare_lock() -> mutex_lock() Locking a mutex while holding a spinlock is not allowed and leads to warnings like "BUG: spinlock wrong CPU on CPU#1", among other problems. There's no reason to use a spinlock. Only dw_wdt_open() was protected and the test_and_set_bit() at the start of that function protects us anyway. Signed-off-by: Doug Anderson <dianders@chromium.org> Tested-by: Jisheng Zhang <jszhang@marvell.com> Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
-rw-r--r--drivers/watchdog/dw_wdt.c7
1 files changed, 0 insertions, 7 deletions
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index d0bb9499d12c..a284abdb4fb6 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -35,7 +35,6 @@
35#include <linux/pm.h> 35#include <linux/pm.h>
36#include <linux/platform_device.h> 36#include <linux/platform_device.h>
37#include <linux/reboot.h> 37#include <linux/reboot.h>
38#include <linux/spinlock.h>
39#include <linux/timer.h> 38#include <linux/timer.h>
40#include <linux/uaccess.h> 39#include <linux/uaccess.h>
41#include <linux/watchdog.h> 40#include <linux/watchdog.h>
@@ -61,7 +60,6 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
61#define WDT_TIMEOUT (HZ / 2) 60#define WDT_TIMEOUT (HZ / 2)
62 61
63static struct { 62static struct {
64 spinlock_t lock;
65 void __iomem *regs; 63 void __iomem *regs;
66 struct clk *clk; 64 struct clk *clk;
67 unsigned long in_use; 65 unsigned long in_use;
@@ -177,7 +175,6 @@ static int dw_wdt_open(struct inode *inode, struct file *filp)
177 /* Make sure we don't get unloaded. */ 175 /* Make sure we don't get unloaded. */
178 __module_get(THIS_MODULE); 176 __module_get(THIS_MODULE);
179 177
180 spin_lock(&dw_wdt.lock);
181 if (!dw_wdt_is_enabled()) { 178 if (!dw_wdt_is_enabled()) {
182 /* 179 /*
183 * The watchdog is not currently enabled. Set the timeout to 180 * The watchdog is not currently enabled. Set the timeout to
@@ -190,8 +187,6 @@ static int dw_wdt_open(struct inode *inode, struct file *filp)
190 187
191 dw_wdt_set_next_heartbeat(); 188 dw_wdt_set_next_heartbeat();
192 189
193 spin_unlock(&dw_wdt.lock);
194
195 return nonseekable_open(inode, filp); 190 return nonseekable_open(inode, filp);
196} 191}
197 192
@@ -348,8 +343,6 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
348 if (ret) 343 if (ret)
349 return ret; 344 return ret;
350 345
351 spin_lock_init(&dw_wdt.lock);
352
353 ret = misc_register(&dw_wdt_miscdev); 346 ret = misc_register(&dw_wdt_miscdev);
354 if (ret) 347 if (ret)
355 goto out_disable_clk; 348 goto out_disable_clk;