aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/pnx4008_wdt.c39
1 files changed, 25 insertions, 14 deletions
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);