diff options
author | Paul Walmsley <paul@pwsan.com> | 2011-03-11 00:40:05 -0500 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2011-03-11 00:40:05 -0500 |
commit | 0503add9d251db22ba2f610fb8d9b7743a9786da (patch) | |
tree | e6004caaa317724550ba8001ee256ba1cbd60fa0 /drivers/watchdog/omap_wdt.c | |
parent | 0dde52a9f5330eec240660191a94b51bd911ffcd (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/omap_wdt.c')
-rw-r--r-- | drivers/watchdog/omap_wdt.c | 25 |
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 | ||
352 | static int __devexit omap_wdt_remove(struct platform_device *pdev) | 368 | static 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; |