aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/omap_wdt.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/watchdog/omap_wdt.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/watchdog/omap_wdt.c')
-rw-r--r--drivers/watchdog/omap_wdt.c68
1 files changed, 31 insertions, 37 deletions
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 76b58abf4451..2b4acb86c191 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -38,11 +38,11 @@
38#include <linux/err.h> 38#include <linux/err.h>
39#include <linux/platform_device.h> 39#include <linux/platform_device.h>
40#include <linux/moduleparam.h> 40#include <linux/moduleparam.h>
41#include <linux/clk.h>
42#include <linux/bitops.h> 41#include <linux/bitops.h>
43#include <linux/io.h> 42#include <linux/io.h>
44#include <linux/uaccess.h> 43#include <linux/uaccess.h>
45#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/pm_runtime.h>
46#include <mach/hardware.h> 46#include <mach/hardware.h>
47#include <plat/prcm.h> 47#include <plat/prcm.h>
48 48
@@ -61,8 +61,6 @@ struct omap_wdt_dev {
61 void __iomem *base; /* physical */ 61 void __iomem *base; /* physical */
62 struct device *dev; 62 struct device *dev;
63 int omap_wdt_users; 63 int omap_wdt_users;
64 struct clk *ick;
65 struct clk *fck;
66 struct resource *mem; 64 struct resource *mem;
67 struct miscdevice omap_wdt_miscdev; 65 struct miscdevice omap_wdt_miscdev;
68}; 66};
@@ -126,6 +124,8 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
126 u32 pre_margin = GET_WLDR_VAL(timer_margin); 124 u32 pre_margin = GET_WLDR_VAL(timer_margin);
127 void __iomem *base = wdev->base; 125 void __iomem *base = wdev->base;
128 126
127 pm_runtime_get_sync(wdev->dev);
128
129 /* just count up at 32 KHz */ 129 /* just count up at 32 KHz */
130 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04) 130 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
131 cpu_relax(); 131 cpu_relax();
@@ -133,6 +133,8 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
133 __raw_writel(pre_margin, base + OMAP_WATCHDOG_LDR); 133 __raw_writel(pre_margin, base + OMAP_WATCHDOG_LDR);
134 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04) 134 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
135 cpu_relax(); 135 cpu_relax();
136
137 pm_runtime_put_sync(wdev->dev);
136} 138}
137 139
138/* 140/*
@@ -146,8 +148,7 @@ static int omap_wdt_open(struct inode *inode, struct file *file)
146 if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users))) 148 if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users)))
147 return -EBUSY; 149 return -EBUSY;
148 150
149 clk_enable(wdev->ick); /* Enable the interface clock */ 151 pm_runtime_get_sync(wdev->dev);
150 clk_enable(wdev->fck); /* Enable the functional clock */
151 152
152 /* initialize prescaler */ 153 /* initialize prescaler */
153 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01) 154 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
@@ -163,6 +164,8 @@ static int omap_wdt_open(struct inode *inode, struct file *file)
163 omap_wdt_ping(wdev); /* trigger loading of new timeout value */ 164 omap_wdt_ping(wdev); /* trigger loading of new timeout value */
164 omap_wdt_enable(wdev); 165 omap_wdt_enable(wdev);
165 166
167 pm_runtime_put_sync(wdev->dev);
168
166 return nonseekable_open(inode, file); 169 return nonseekable_open(inode, file);
167} 170}
168 171
@@ -174,11 +177,11 @@ static int omap_wdt_release(struct inode *inode, struct file *file)
174 * Shut off the timer unless NOWAYOUT is defined. 177 * Shut off the timer unless NOWAYOUT is defined.
175 */ 178 */
176#ifndef CONFIG_WATCHDOG_NOWAYOUT 179#ifndef CONFIG_WATCHDOG_NOWAYOUT
180 pm_runtime_get_sync(wdev->dev);
177 181
178 omap_wdt_disable(wdev); 182 omap_wdt_disable(wdev);
179 183
180 clk_disable(wdev->ick); 184 pm_runtime_put_sync(wdev->dev);
181 clk_disable(wdev->fck);
182#else 185#else
183 printk(KERN_CRIT "omap_wdt: Unexpected close, not stopping!\n"); 186 printk(KERN_CRIT "omap_wdt: Unexpected close, not stopping!\n");
184#endif 187#endif
@@ -194,9 +197,11 @@ static ssize_t omap_wdt_write(struct file *file, const char __user *data,
194 197
195 /* Refresh LOAD_TIME. */ 198 /* Refresh LOAD_TIME. */
196 if (len) { 199 if (len) {
200 pm_runtime_get_sync(wdev->dev);
197 spin_lock(&wdt_lock); 201 spin_lock(&wdt_lock);
198 omap_wdt_ping(wdev); 202 omap_wdt_ping(wdev);
199 spin_unlock(&wdt_lock); 203 spin_unlock(&wdt_lock);
204 pm_runtime_put_sync(wdev->dev);
200 } 205 }
201 return len; 206 return len;
202} 207}
@@ -228,15 +233,18 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
228 return put_user(omap_prcm_get_reset_sources(), 233 return put_user(omap_prcm_get_reset_sources(),
229 (int __user *)arg); 234 (int __user *)arg);
230 case WDIOC_KEEPALIVE: 235 case WDIOC_KEEPALIVE:
236 pm_runtime_get_sync(wdev->dev);
231 spin_lock(&wdt_lock); 237 spin_lock(&wdt_lock);
232 omap_wdt_ping(wdev); 238 omap_wdt_ping(wdev);
233 spin_unlock(&wdt_lock); 239 spin_unlock(&wdt_lock);
240 pm_runtime_put_sync(wdev->dev);
234 return 0; 241 return 0;
235 case WDIOC_SETTIMEOUT: 242 case WDIOC_SETTIMEOUT:
236 if (get_user(new_margin, (int __user *)arg)) 243 if (get_user(new_margin, (int __user *)arg))
237 return -EFAULT; 244 return -EFAULT;
238 omap_wdt_adjust_timeout(new_margin); 245 omap_wdt_adjust_timeout(new_margin);
239 246
247 pm_runtime_get_sync(wdev->dev);
240 spin_lock(&wdt_lock); 248 spin_lock(&wdt_lock);
241 omap_wdt_disable(wdev); 249 omap_wdt_disable(wdev);
242 omap_wdt_set_timeout(wdev); 250 omap_wdt_set_timeout(wdev);
@@ -244,6 +252,7 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
244 252
245 omap_wdt_ping(wdev); 253 omap_wdt_ping(wdev);
246 spin_unlock(&wdt_lock); 254 spin_unlock(&wdt_lock);
255 pm_runtime_put_sync(wdev->dev);
247 /* Fall */ 256 /* Fall */
248 case WDIOC_GETTIMEOUT: 257 case WDIOC_GETTIMEOUT:
249 return put_user(timer_margin, (int __user *)arg); 258 return put_user(timer_margin, (int __user *)arg);
@@ -258,6 +267,7 @@ static const struct file_operations omap_wdt_fops = {
258 .unlocked_ioctl = omap_wdt_ioctl, 267 .unlocked_ioctl = omap_wdt_ioctl,
259 .open = omap_wdt_open, 268 .open = omap_wdt_open,
260 .release = omap_wdt_release, 269 .release = omap_wdt_release,
270 .llseek = no_llseek,
261}; 271};
262 272
263static int __devinit omap_wdt_probe(struct platform_device *pdev) 273static int __devinit omap_wdt_probe(struct platform_device *pdev)
@@ -292,19 +302,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
292 302
293 wdev->omap_wdt_users = 0; 303 wdev->omap_wdt_users = 0;
294 wdev->mem = mem; 304 wdev->mem = mem;
295 305 wdev->dev = &pdev->dev;
296 wdev->ick = clk_get(&pdev->dev, "ick");
297 if (IS_ERR(wdev->ick)) {
298 ret = PTR_ERR(wdev->ick);
299 wdev->ick = NULL;
300 goto err_clk;
301 }
302 wdev->fck = clk_get(&pdev->dev, "fck");
303 if (IS_ERR(wdev->fck)) {
304 ret = PTR_ERR(wdev->fck);
305 wdev->fck = NULL;
306 goto err_clk;
307 }
308 306
309 wdev->base = ioremap(res->start, resource_size(res)); 307 wdev->base = ioremap(res->start, resource_size(res));
310 if (!wdev->base) { 308 if (!wdev->base) {
@@ -314,8 +312,8 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
314 312
315 platform_set_drvdata(pdev, wdev); 313 platform_set_drvdata(pdev, wdev);
316 314
317 clk_enable(wdev->ick); 315 pm_runtime_enable(wdev->dev);
318 clk_enable(wdev->fck); 316 pm_runtime_get_sync(wdev->dev);
319 317
320 omap_wdt_disable(wdev); 318 omap_wdt_disable(wdev);
321 omap_wdt_adjust_timeout(timer_margin); 319 omap_wdt_adjust_timeout(timer_margin);
@@ -333,11 +331,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
333 __raw_readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF, 331 __raw_readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF,
334 timer_margin); 332 timer_margin);
335 333
336 /* autogate OCP interface clock */ 334 pm_runtime_put_sync(wdev->dev);
337 __raw_writel(0x01, wdev->base + OMAP_WATCHDOG_SYS_CONFIG);
338
339 clk_disable(wdev->ick);
340 clk_disable(wdev->fck);
341 335
342 omap_wdt_dev = pdev; 336 omap_wdt_dev = pdev;
343 337
@@ -349,12 +343,6 @@ err_misc:
349 343
350err_ioremap: 344err_ioremap:
351 wdev->base = NULL; 345 wdev->base = NULL;
352
353err_clk:
354 if (wdev->ick)
355 clk_put(wdev->ick);
356 if (wdev->fck)
357 clk_put(wdev->fck);
358 kfree(wdev); 346 kfree(wdev);
359 347
360err_kzalloc: 348err_kzalloc:
@@ -370,8 +358,11 @@ static void omap_wdt_shutdown(struct platform_device *pdev)
370{ 358{
371 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); 359 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
372 360
373 if (wdev->omap_wdt_users) 361 if (wdev->omap_wdt_users) {
362 pm_runtime_get_sync(wdev->dev);
374 omap_wdt_disable(wdev); 363 omap_wdt_disable(wdev);
364 pm_runtime_put_sync(wdev->dev);
365 }
375} 366}
376 367
377static int __devexit omap_wdt_remove(struct platform_device *pdev) 368static int __devexit omap_wdt_remove(struct platform_device *pdev)
@@ -386,8 +377,6 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev)
386 release_mem_region(res->start, resource_size(res)); 377 release_mem_region(res->start, resource_size(res));
387 platform_set_drvdata(pdev, NULL); 378 platform_set_drvdata(pdev, NULL);
388 379
389 clk_put(wdev->ick);
390 clk_put(wdev->fck);
391 iounmap(wdev->base); 380 iounmap(wdev->base);
392 381
393 kfree(wdev); 382 kfree(wdev);
@@ -408,8 +397,11 @@ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
408{ 397{
409 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); 398 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
410 399
411 if (wdev->omap_wdt_users) 400 if (wdev->omap_wdt_users) {
401 pm_runtime_get_sync(wdev->dev);
412 omap_wdt_disable(wdev); 402 omap_wdt_disable(wdev);
403 pm_runtime_put_sync(wdev->dev);
404 }
413 405
414 return 0; 406 return 0;
415} 407}
@@ -419,8 +411,10 @@ static int omap_wdt_resume(struct platform_device *pdev)
419 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); 411 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
420 412
421 if (wdev->omap_wdt_users) { 413 if (wdev->omap_wdt_users) {
414 pm_runtime_get_sync(wdev->dev);
422 omap_wdt_enable(wdev); 415 omap_wdt_enable(wdev);
423 omap_wdt_ping(wdev); 416 omap_wdt_ping(wdev);
417 pm_runtime_put_sync(wdev->dev);
424 } 418 }
425 419
426 return 0; 420 return 0;