diff options
author | Wim Van Sebroeck <wim@iguana.be> | 2009-02-23 08:08:36 -0500 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2009-03-25 05:01:50 -0400 |
commit | e455b6b4ed66be0c2aa6e41fd9027c1ce585a490 (patch) | |
tree | fcc99995d1ccf7a441e3ca09cbfa9c6f4eca0ec7 /drivers/watchdog | |
parent | 0aaae66179f269b7b37d0b526029c5783bed1da3 (diff) |
[WATCHDOG] rc32434_wdt: add spin_locking
Add spin_locks to prevent races.
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/rc32434_wdt.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index eee29923a14d..bffd4a2b1151 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/watchdog.h> /* For the watchdog specific items */ | 28 | #include <linux/watchdog.h> /* For the watchdog specific items */ |
29 | #include <linux/init.h> /* For __init/__exit/... */ | 29 | #include <linux/init.h> /* For __init/__exit/... */ |
30 | #include <linux/platform_device.h> /* For platform_driver framework */ | 30 | #include <linux/platform_device.h> /* For platform_driver framework */ |
31 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ | ||
31 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | 32 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ |
32 | 33 | ||
33 | #include <asm/mach-rc32434/integ.h> /* For the Watchdog registers */ | 34 | #include <asm/mach-rc32434/integ.h> /* For the Watchdog registers */ |
@@ -38,6 +39,7 @@ | |||
38 | 39 | ||
39 | static struct { | 40 | static struct { |
40 | unsigned long inuse; | 41 | unsigned long inuse; |
42 | spinlock_t io_lock; | ||
41 | } rc32434_wdt_device; | 43 | } rc32434_wdt_device; |
42 | 44 | ||
43 | static struct integ __iomem *wdt_reg; | 45 | static struct integ __iomem *wdt_reg; |
@@ -81,7 +83,9 @@ static int rc32434_wdt_set(int new_timeout) | |||
81 | return -EINVAL; | 83 | return -EINVAL; |
82 | } | 84 | } |
83 | timeout = new_timeout; | 85 | timeout = new_timeout; |
86 | spin_lock(&rc32434_wdt_device.io_lock); | ||
84 | writel(SEC2WTCOMP(timeout), &wdt_reg->wtcompare); | 87 | writel(SEC2WTCOMP(timeout), &wdt_reg->wtcompare); |
88 | spin_unlock(&rc32434_wdt_device.io_lock); | ||
85 | 89 | ||
86 | return 0; | 90 | return 0; |
87 | } | 91 | } |
@@ -90,6 +94,8 @@ static void rc32434_wdt_start(void) | |||
90 | { | 94 | { |
91 | u32 or, nand; | 95 | u32 or, nand; |
92 | 96 | ||
97 | spin_lock(&rc32434_wdt_device.io_lock); | ||
98 | |||
93 | /* zero the counter before enabling */ | 99 | /* zero the counter before enabling */ |
94 | writel(0, &wdt_reg->wtcount); | 100 | writel(0, &wdt_reg->wtcount); |
95 | 101 | ||
@@ -112,20 +118,26 @@ static void rc32434_wdt_start(void) | |||
112 | 118 | ||
113 | SET_BITS(wdt_reg->wtc, or, nand); | 119 | SET_BITS(wdt_reg->wtc, or, nand); |
114 | 120 | ||
121 | spin_unlock(&rc32434_wdt_device.io_lock); | ||
115 | printk(KERN_INFO PFX "Started watchdog timer.\n"); | 122 | printk(KERN_INFO PFX "Started watchdog timer.\n"); |
116 | } | 123 | } |
117 | 124 | ||
118 | static void rc32434_wdt_stop(void) | 125 | static void rc32434_wdt_stop(void) |
119 | { | 126 | { |
127 | spin_lock(&rc32434_wdt_device.io_lock); | ||
128 | |||
120 | /* Disable WDT */ | 129 | /* Disable WDT */ |
121 | SET_BITS(wdt_reg->wtc, 0, 1 << RC32434_WTC_EN); | 130 | SET_BITS(wdt_reg->wtc, 0, 1 << RC32434_WTC_EN); |
122 | 131 | ||
132 | spin_unlock(&rc32434_wdt_device.io_lock); | ||
123 | printk(KERN_INFO PFX "Stopped watchdog timer.\n"); | 133 | printk(KERN_INFO PFX "Stopped watchdog timer.\n"); |
124 | } | 134 | } |
125 | 135 | ||
126 | static void rc32434_wdt_ping(void) | 136 | static void rc32434_wdt_ping(void) |
127 | { | 137 | { |
138 | spin_lock(&rc32434_wdt_device.io_lock); | ||
128 | writel(0, &wdt_reg->wtcount); | 139 | writel(0, &wdt_reg->wtcount); |
140 | spin_unlock(&rc32434_wdt_device.io_lock); | ||
129 | } | 141 | } |
130 | 142 | ||
131 | static int rc32434_wdt_open(struct inode *inode, struct file *file) | 143 | static int rc32434_wdt_open(struct inode *inode, struct file *file) |
@@ -270,6 +282,8 @@ static int __devinit rc32434_wdt_probe(struct platform_device *pdev) | |||
270 | return -ENXIO; | 282 | return -ENXIO; |
271 | } | 283 | } |
272 | 284 | ||
285 | spin_lock_init(&rc32434_wdt_device.io_lock); | ||
286 | |||
273 | /* Check that the heartbeat value is within it's range; | 287 | /* Check that the heartbeat value is within it's range; |
274 | * if not reset to the default */ | 288 | * if not reset to the default */ |
275 | if (rc32434_wdt_set(timeout)) { | 289 | if (rc32434_wdt_set(timeout)) { |