aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2011-03-11 00:40:05 -0500
committerPaul Walmsley <paul@pwsan.com>2011-03-11 00:40:05 -0500
commit0503add9d251db22ba2f610fb8d9b7743a9786da (patch)
treee6004caaa317724550ba8001ee256ba1cbd60fa0 /drivers/watchdog
parent0dde52a9f5330eec240660191a94b51bd911ffcd (diff)
Watchdog: omap_wdt: add fine grain runtime-pm
The omap_wdt should only be in full active state when the registers are being accessed. Otherwise the device can be on lower power mode. This patch is based on a patch created by Kalle Jokiniemi: https://patchwork.kernel.org/patch/618231/ which is itself based on a patch created by Atal Shargorodsky: http://lkml.org/lkml/2009/3/10/266. Signed-off-by: Paul Walmsley <paul@pwsan.com> Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi@nokia.com> Tested-by: Kalle Jokiniemi <kalle.jokiniemi@nokia.com> Cc: Wim Van Sebroeck <wim@iguana.be> Acked-by: Wim Van Sebroeck <wim@iguana.be> Acked-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/omap_wdt.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 3dd4971160ef..2b4acb86c191 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -124,6 +124,8 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
124 u32 pre_margin = GET_WLDR_VAL(timer_margin); 124 u32 pre_margin = GET_WLDR_VAL(timer_margin);
125 void __iomem *base = wdev->base; 125 void __iomem *base = wdev->base;
126 126
127 pm_runtime_get_sync(wdev->dev);
128
127 /* just count up at 32 KHz */ 129 /* just count up at 32 KHz */
128 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04) 130 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
129 cpu_relax(); 131 cpu_relax();
@@ -131,6 +133,8 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
131 __raw_writel(pre_margin, base + OMAP_WATCHDOG_LDR); 133 __raw_writel(pre_margin, base + OMAP_WATCHDOG_LDR);
132 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04) 134 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
133 cpu_relax(); 135 cpu_relax();
136
137 pm_runtime_put_sync(wdev->dev);
134} 138}
135 139
136/* 140/*
@@ -160,6 +164,8 @@ static int omap_wdt_open(struct inode *inode, struct file *file)
160 omap_wdt_ping(wdev); /* trigger loading of new timeout value */ 164 omap_wdt_ping(wdev); /* trigger loading of new timeout value */
161 omap_wdt_enable(wdev); 165 omap_wdt_enable(wdev);
162 166
167 pm_runtime_put_sync(wdev->dev);
168
163 return nonseekable_open(inode, file); 169 return nonseekable_open(inode, file);
164} 170}
165 171
@@ -171,6 +177,7 @@ static int omap_wdt_release(struct inode *inode, struct file *file)
171 * Shut off the timer unless NOWAYOUT is defined. 177 * Shut off the timer unless NOWAYOUT is defined.
172 */ 178 */
173#ifndef CONFIG_WATCHDOG_NOWAYOUT 179#ifndef CONFIG_WATCHDOG_NOWAYOUT
180 pm_runtime_get_sync(wdev->dev);
174 181
175 omap_wdt_disable(wdev); 182 omap_wdt_disable(wdev);
176 183
@@ -190,9 +197,11 @@ static ssize_t omap_wdt_write(struct file *file, const char __user *data,
190 197
191 /* Refresh LOAD_TIME. */ 198 /* Refresh LOAD_TIME. */
192 if (len) { 199 if (len) {
200 pm_runtime_get_sync(wdev->dev);
193 spin_lock(&wdt_lock); 201 spin_lock(&wdt_lock);
194 omap_wdt_ping(wdev); 202 omap_wdt_ping(wdev);
195 spin_unlock(&wdt_lock); 203 spin_unlock(&wdt_lock);
204 pm_runtime_put_sync(wdev->dev);
196 } 205 }
197 return len; 206 return len;
198} 207}
@@ -224,15 +233,18 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
224 return put_user(omap_prcm_get_reset_sources(), 233 return put_user(omap_prcm_get_reset_sources(),
225 (int __user *)arg); 234 (int __user *)arg);
226 case WDIOC_KEEPALIVE: 235 case WDIOC_KEEPALIVE:
236 pm_runtime_get_sync(wdev->dev);
227 spin_lock(&wdt_lock); 237 spin_lock(&wdt_lock);
228 omap_wdt_ping(wdev); 238 omap_wdt_ping(wdev);
229 spin_unlock(&wdt_lock); 239 spin_unlock(&wdt_lock);
240 pm_runtime_put_sync(wdev->dev);
230 return 0; 241 return 0;
231 case WDIOC_SETTIMEOUT: 242 case WDIOC_SETTIMEOUT:
232 if (get_user(new_margin, (int __user *)arg)) 243 if (get_user(new_margin, (int __user *)arg))
233 return -EFAULT; 244 return -EFAULT;
234 omap_wdt_adjust_timeout(new_margin); 245 omap_wdt_adjust_timeout(new_margin);
235 246
247 pm_runtime_get_sync(wdev->dev);
236 spin_lock(&wdt_lock); 248 spin_lock(&wdt_lock);
237 omap_wdt_disable(wdev); 249 omap_wdt_disable(wdev);
238 omap_wdt_set_timeout(wdev); 250 omap_wdt_set_timeout(wdev);
@@ -240,6 +252,7 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
240 252
241 omap_wdt_ping(wdev); 253 omap_wdt_ping(wdev);
242 spin_unlock(&wdt_lock); 254 spin_unlock(&wdt_lock);
255 pm_runtime_put_sync(wdev->dev);
243 /* Fall */ 256 /* Fall */
244 case WDIOC_GETTIMEOUT: 257 case WDIOC_GETTIMEOUT:
245 return put_user(timer_margin, (int __user *)arg); 258 return put_user(timer_margin, (int __user *)arg);
@@ -345,8 +358,11 @@ static void omap_wdt_shutdown(struct platform_device *pdev)
345{ 358{
346 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); 359 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
347 360
348 if (wdev->omap_wdt_users) 361 if (wdev->omap_wdt_users) {
362 pm_runtime_get_sync(wdev->dev);
349 omap_wdt_disable(wdev); 363 omap_wdt_disable(wdev);
364 pm_runtime_put_sync(wdev->dev);
365 }
350} 366}
351 367
352static int __devexit omap_wdt_remove(struct platform_device *pdev) 368static int __devexit omap_wdt_remove(struct platform_device *pdev)
@@ -381,8 +397,11 @@ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
381{ 397{
382 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); 398 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
383 399
384 if (wdev->omap_wdt_users) 400 if (wdev->omap_wdt_users) {
401 pm_runtime_get_sync(wdev->dev);
385 omap_wdt_disable(wdev); 402 omap_wdt_disable(wdev);
403 pm_runtime_put_sync(wdev->dev);
404 }
386 405
387 return 0; 406 return 0;
388} 407}
@@ -392,8 +411,10 @@ static int omap_wdt_resume(struct platform_device *pdev)
392 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); 411 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
393 412
394 if (wdev->omap_wdt_users) { 413 if (wdev->omap_wdt_users) {
414 pm_runtime_get_sync(wdev->dev);
395 omap_wdt_enable(wdev); 415 omap_wdt_enable(wdev);
396 omap_wdt_ping(wdev); 416 omap_wdt_ping(wdev);
417 pm_runtime_put_sync(wdev->dev);
397 } 418 }
398 419
399 return 0; 420 return 0;