aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-03-01 17:19:05 -0500
committerTony Lindgren <tony@atomide.com>2010-03-01 17:19:05 -0500
commitd702d12167a2c05a346f49aac7a311d597762495 (patch)
treebaae42c299cce34d6df24b5d01f8b1d0b481bd9a /drivers/watchdog
parent9418c65f9bd861d0f7e39aab9cfb3aa6f2275d11 (diff)
parentac0f6f927db539e03e1f3f61bcd4ed57d5cde7a9 (diff)
Merge with mainline to remove plat-omap/Kconfig conflict
Conflicts: arch/arm/plat-omap/Kconfig
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/ar7_wdt.c18
-rw-r--r--drivers/watchdog/bfin_wdt.c13
-rw-r--r--drivers/watchdog/pnx4008_wdt.c39
3 files changed, 47 insertions, 23 deletions
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index 2e94b71b20d9..2bb95cd308c1 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -34,6 +34,7 @@
34#include <linux/ioport.h> 34#include <linux/ioport.h>
35#include <linux/io.h> 35#include <linux/io.h>
36#include <linux/uaccess.h> 36#include <linux/uaccess.h>
37#include <linux/clk.h>
37 38
38#include <asm/addrspace.h> 39#include <asm/addrspace.h>
39#include <asm/mach-ar7/ar7.h> 40#include <asm/mach-ar7/ar7.h>
@@ -80,6 +81,8 @@ static struct resource *ar7_regs_wdt;
80/* Pointer to the remapped WDT IO space */ 81/* Pointer to the remapped WDT IO space */
81static struct ar7_wdt *ar7_wdt; 82static struct ar7_wdt *ar7_wdt;
82 83
84static struct clk *vbus_clk;
85
83static void ar7_wdt_kick(u32 value) 86static void ar7_wdt_kick(u32 value)
84{ 87{
85 WRITE_REG(ar7_wdt->kick_lock, 0x5555); 88 WRITE_REG(ar7_wdt->kick_lock, 0x5555);
@@ -138,17 +141,19 @@ static void ar7_wdt_disable(u32 value)
138static void ar7_wdt_update_margin(int new_margin) 141static void ar7_wdt_update_margin(int new_margin)
139{ 142{
140 u32 change; 143 u32 change;
144 u32 vbus_rate;
141 145
142 change = new_margin * (ar7_vbus_freq() / prescale_value); 146 vbus_rate = clk_get_rate(vbus_clk);
147 change = new_margin * (vbus_rate / prescale_value);
143 if (change < 1) 148 if (change < 1)
144 change = 1; 149 change = 1;
145 if (change > 0xffff) 150 if (change > 0xffff)
146 change = 0xffff; 151 change = 0xffff;
147 ar7_wdt_change(change); 152 ar7_wdt_change(change);
148 margin = change * prescale_value / ar7_vbus_freq(); 153 margin = change * prescale_value / vbus_rate;
149 printk(KERN_INFO DRVNAME 154 printk(KERN_INFO DRVNAME
150 ": timer margin %d seconds (prescale %d, change %d, freq %d)\n", 155 ": timer margin %d seconds (prescale %d, change %d, freq %d)\n",
151 margin, prescale_value, change, ar7_vbus_freq()); 156 margin, prescale_value, change, vbus_rate);
152} 157}
153 158
154static void ar7_wdt_enable_wdt(void) 159static void ar7_wdt_enable_wdt(void)
@@ -298,6 +303,13 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev)
298 goto out_mem_region; 303 goto out_mem_region;
299 } 304 }
300 305
306 vbus_clk = clk_get(NULL, "vbus");
307 if (IS_ERR(vbus_clk)) {
308 printk(KERN_ERR DRVNAME ": could not get vbus clock\n");
309 rc = PTR_ERR(vbus_clk);
310 goto out_mem_region;
311 }
312
301 ar7_wdt_disable_wdt(); 313 ar7_wdt_disable_wdt();
302 ar7_wdt_prescale(prescale_value); 314 ar7_wdt_prescale(prescale_value);
303 ar7_wdt_update_margin(margin); 315 ar7_wdt_update_margin(margin);
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index c7b3f9df2317..2159e668751c 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -1,9 +1,8 @@
1/* 1/*
2 * Blackfin On-Chip Watchdog Driver 2 * Blackfin On-Chip Watchdog Driver
3 * Supports BF53[123]/BF53[467]/BF54[2489]/BF561
4 * 3 *
5 * Originally based on softdog.c 4 * Originally based on softdog.c
6 * Copyright 2006-2007 Analog Devices Inc. 5 * Copyright 2006-2010 Analog Devices Inc.
7 * Copyright 2006-2007 Michele d'Amico 6 * Copyright 2006-2007 Michele d'Amico
8 * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk> 7 * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>
9 * 8 *
@@ -137,13 +136,15 @@ static int bfin_wdt_running(void)
137 */ 136 */
138static int bfin_wdt_set_timeout(unsigned long t) 137static int bfin_wdt_set_timeout(unsigned long t)
139{ 138{
140 u32 cnt; 139 u32 cnt, max_t, sclk;
141 unsigned long flags; 140 unsigned long flags;
142 141
143 stampit(); 142 sclk = get_sclk();
143 max_t = -1 / sclk;
144 cnt = t * sclk;
145 stamp("maxtimeout=%us newtimeout=%lus (cnt=%#x)", max_t, t, cnt);
144 146
145 cnt = t * get_sclk(); 147 if (t > max_t) {
146 if (cnt < get_sclk()) {
147 printk(KERN_WARNING PFX "timeout value is too large\n"); 148 printk(KERN_WARNING PFX "timeout value is too large\n");
148 return -EINVAL; 149 return -EINVAL;
149 } 150 }
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 430a5848a9a5..c7a9479934af 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -96,9 +96,6 @@ static void wdt_enable(void)
96{ 96{
97 spin_lock(&io_lock); 97 spin_lock(&io_lock);
98 98
99 if (wdt_clk)
100 clk_set_rate(wdt_clk, 1);
101
102 /* stop counter, initiate counter reset */ 99 /* stop counter, initiate counter reset */
103 __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base)); 100 __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base));
104 /*wait for reset to complete. 100% guarantee event */ 101 /*wait for reset to complete. 100% guarantee event */
@@ -125,19 +122,25 @@ static void wdt_disable(void)
125 spin_lock(&io_lock); 122 spin_lock(&io_lock);
126 123
127 __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ 124 __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */
128 if (wdt_clk)
129 clk_set_rate(wdt_clk, 0);
130 125
131 spin_unlock(&io_lock); 126 spin_unlock(&io_lock);
132} 127}
133 128
134static int pnx4008_wdt_open(struct inode *inode, struct file *file) 129static int pnx4008_wdt_open(struct inode *inode, struct file *file)
135{ 130{
131 int ret;
132
136 if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 133 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
137 return -EBUSY; 134 return -EBUSY;
138 135
139 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 136 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
140 137
138 ret = clk_enable(wdt_clk);
139 if (ret) {
140 clear_bit(WDT_IN_USE, &wdt_status);
141 return ret;
142 }
143
141 wdt_enable(); 144 wdt_enable();
142 145
143 return nonseekable_open(inode, file); 146 return nonseekable_open(inode, file);
@@ -225,6 +228,7 @@ static int pnx4008_wdt_release(struct inode *inode, struct file *file)
225 printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n"); 228 printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n");
226 229
227 wdt_disable(); 230 wdt_disable();
231 clk_disable(wdt_clk);
228 clear_bit(WDT_IN_USE, &wdt_status); 232 clear_bit(WDT_IN_USE, &wdt_status);
229 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 233 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
230 234
@@ -273,25 +277,33 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
273 } 277 }
274 wdt_base = (void __iomem *)IO_ADDRESS(res->start); 278 wdt_base = (void __iomem *)IO_ADDRESS(res->start);
275 279
276 wdt_clk = clk_get(&pdev->dev, "wdt_ck"); 280 wdt_clk = clk_get(&pdev->dev, NULL);
277 if (IS_ERR(wdt_clk)) { 281 if (IS_ERR(wdt_clk)) {
278 ret = PTR_ERR(wdt_clk); 282 ret = PTR_ERR(wdt_clk);
279 release_resource(wdt_mem); 283 release_resource(wdt_mem);
280 kfree(wdt_mem); 284 kfree(wdt_mem);
281 goto out; 285 goto out;
282 } else 286 }
283 clk_set_rate(wdt_clk, 1); 287
288 ret = clk_enable(wdt_clk);
289 if (ret) {
290 release_resource(wdt_mem);
291 kfree(wdt_mem);
292 goto out;
293 }
284 294
285 ret = misc_register(&pnx4008_wdt_miscdev); 295 ret = misc_register(&pnx4008_wdt_miscdev);
286 if (ret < 0) { 296 if (ret < 0) {
287 printk(KERN_ERR MODULE_NAME "cannot register misc device\n"); 297 printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
288 release_resource(wdt_mem); 298 release_resource(wdt_mem);
289 kfree(wdt_mem); 299 kfree(wdt_mem);
290 clk_set_rate(wdt_clk, 0); 300 clk_disable(wdt_clk);
301 clk_put(wdt_clk);
291 } else { 302 } else {
292 boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? 303 boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
293 WDIOF_CARDRESET : 0; 304 WDIOF_CARDRESET : 0;
294 wdt_disable(); /*disable for now */ 305 wdt_disable(); /*disable for now */
306 clk_disable(wdt_clk);
295 set_bit(WDT_DEVICE_INITED, &wdt_status); 307 set_bit(WDT_DEVICE_INITED, &wdt_status);
296 } 308 }
297 309
@@ -302,11 +314,10 @@ out:
302static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) 314static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
303{ 315{
304 misc_deregister(&pnx4008_wdt_miscdev); 316 misc_deregister(&pnx4008_wdt_miscdev);
305 if (wdt_clk) { 317
306 clk_set_rate(wdt_clk, 0); 318 clk_disable(wdt_clk);
307 clk_put(wdt_clk); 319 clk_put(wdt_clk);
308 wdt_clk = NULL; 320
309 }
310 if (wdt_mem) { 321 if (wdt_mem) {
311 release_resource(wdt_mem); 322 release_resource(wdt_mem);
312 kfree(wdt_mem); 323 kfree(wdt_mem);