diff options
| -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)) { |
