diff options
author | Roger Quadros <rogerq@ti.com> | 2014-01-08 02:15:33 -0500 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2014-01-21 03:29:01 -0500 |
commit | 76a0775d46da052f123b8598a3dfc3b330b8de4f (patch) | |
tree | 87888ffb32af1071d1e242ff43dc7848a03edbb0 /drivers/mfd | |
parent | 3b1ba0cbcc1bc16b39dbd6cc4585a1d365f351f3 (diff) |
mfd: omap-usb-tll: Don't hold lock during pm_runtime_get/put_sync()
pm_runtime_get/put_sync() can sleep so don't hold spinlock while
calling them.
This patch prevents a BUG() during system suspend when
CONFIG_DEBUG_ATOMIC_SLEEP is enabled.
Bug is present in Kernel versions v3.9 onwards.
Reported-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Roger Quadros <rogerq@ti.com>
Tested-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/omap-usb-tll.c | 36 |
1 files changed, 12 insertions, 24 deletions
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c index ee7468c1cb60..5ee50f779ef6 100644 --- a/drivers/mfd/omap-usb-tll.c +++ b/drivers/mfd/omap-usb-tll.c | |||
@@ -333,21 +333,17 @@ int omap_tll_init(struct usbhs_omap_platform_data *pdata) | |||
333 | unsigned reg; | 333 | unsigned reg; |
334 | struct usbtll_omap *tll; | 334 | struct usbtll_omap *tll; |
335 | 335 | ||
336 | spin_lock(&tll_lock); | 336 | if (!tll_dev) |
337 | |||
338 | if (!tll_dev) { | ||
339 | spin_unlock(&tll_lock); | ||
340 | return -ENODEV; | 337 | return -ENODEV; |
341 | } | ||
342 | 338 | ||
343 | tll = dev_get_drvdata(tll_dev); | 339 | pm_runtime_get_sync(tll_dev); |
344 | 340 | ||
341 | spin_lock(&tll_lock); | ||
342 | tll = dev_get_drvdata(tll_dev); | ||
345 | needs_tll = false; | 343 | needs_tll = false; |
346 | for (i = 0; i < tll->nch; i++) | 344 | for (i = 0; i < tll->nch; i++) |
347 | needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]); | 345 | needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]); |
348 | 346 | ||
349 | pm_runtime_get_sync(tll_dev); | ||
350 | |||
351 | if (needs_tll) { | 347 | if (needs_tll) { |
352 | void __iomem *base = tll->base; | 348 | void __iomem *base = tll->base; |
353 | 349 | ||
@@ -398,9 +394,8 @@ int omap_tll_init(struct usbhs_omap_platform_data *pdata) | |||
398 | } | 394 | } |
399 | } | 395 | } |
400 | 396 | ||
401 | pm_runtime_put_sync(tll_dev); | ||
402 | |||
403 | spin_unlock(&tll_lock); | 397 | spin_unlock(&tll_lock); |
398 | pm_runtime_put_sync(tll_dev); | ||
404 | 399 | ||
405 | return 0; | 400 | return 0; |
406 | } | 401 | } |
@@ -411,17 +406,14 @@ int omap_tll_enable(struct usbhs_omap_platform_data *pdata) | |||
411 | int i; | 406 | int i; |
412 | struct usbtll_omap *tll; | 407 | struct usbtll_omap *tll; |
413 | 408 | ||
414 | spin_lock(&tll_lock); | 409 | if (!tll_dev) |
415 | |||
416 | if (!tll_dev) { | ||
417 | spin_unlock(&tll_lock); | ||
418 | return -ENODEV; | 410 | return -ENODEV; |
419 | } | ||
420 | |||
421 | tll = dev_get_drvdata(tll_dev); | ||
422 | 411 | ||
423 | pm_runtime_get_sync(tll_dev); | 412 | pm_runtime_get_sync(tll_dev); |
424 | 413 | ||
414 | spin_lock(&tll_lock); | ||
415 | tll = dev_get_drvdata(tll_dev); | ||
416 | |||
425 | for (i = 0; i < tll->nch; i++) { | 417 | for (i = 0; i < tll->nch; i++) { |
426 | if (omap_usb_mode_needs_tll(pdata->port_mode[i])) { | 418 | if (omap_usb_mode_needs_tll(pdata->port_mode[i])) { |
427 | int r; | 419 | int r; |
@@ -448,13 +440,10 @@ int omap_tll_disable(struct usbhs_omap_platform_data *pdata) | |||
448 | int i; | 440 | int i; |
449 | struct usbtll_omap *tll; | 441 | struct usbtll_omap *tll; |
450 | 442 | ||
451 | spin_lock(&tll_lock); | 443 | if (!tll_dev) |
452 | |||
453 | if (!tll_dev) { | ||
454 | spin_unlock(&tll_lock); | ||
455 | return -ENODEV; | 444 | return -ENODEV; |
456 | } | ||
457 | 445 | ||
446 | spin_lock(&tll_lock); | ||
458 | tll = dev_get_drvdata(tll_dev); | 447 | tll = dev_get_drvdata(tll_dev); |
459 | 448 | ||
460 | for (i = 0; i < tll->nch; i++) { | 449 | for (i = 0; i < tll->nch; i++) { |
@@ -464,9 +453,8 @@ int omap_tll_disable(struct usbhs_omap_platform_data *pdata) | |||
464 | } | 453 | } |
465 | } | 454 | } |
466 | 455 | ||
467 | pm_runtime_put_sync(tll_dev); | ||
468 | |||
469 | spin_unlock(&tll_lock); | 456 | spin_unlock(&tll_lock); |
457 | pm_runtime_put_sync(tll_dev); | ||
470 | 458 | ||
471 | return 0; | 459 | return 0; |
472 | } | 460 | } |