summaryrefslogtreecommitdiff
path: root/drivers/usb/musb/musb_core.c
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2012-07-26 18:08:09 +0300
committerXavier Boudet <x-boudet@ti.com>2012-07-26 17:21:09 +0200
commit651c1e3dd877011714b0f6d50d7c653e731df6db (patch)
tree3868c055a43209b0fab7be6700dfd4a893087e0f /drivers/usb/musb/musb_core.c
parent692a9a995256d0813a7c494913f66c28f8d53e58 (diff)
usb: musb: fix suspend/resume after gadget driver is loaded and unloaded
If the MUSB controller is already suspended via runtime suspend then it will be disabled (and clocks gated) thus accessing the controller while system suspend to save state will cause L3 bus errors. This problem can be reproduced by loading a gadget driver, unloading it and putting the system to suspend. There is no need to save/restore controller state in this case as the corresponding runtime suspend/resume functions are already doing that. This patch makes sure we don't access the MUSB controller registers in the suspend path if it is already disabled. Signed-off-by: Roger Quadros <rogerq@ti.com>
Diffstat (limited to 'drivers/usb/musb/musb_core.c')
-rw-r--r--drivers/usb/musb/musb_core.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index c78108eb398d..f94d91e80aff 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2327,7 +2327,11 @@ static int musb_suspend(struct device *dev)
}
spin_unlock_irqrestore(&musb->lock, flags);
- musb_save_context(musb);
+
+ /* Need to save state only if it is not yet runtime suspended */
+ if (!musb->suspended) {
+ musb_save_context(musb);
+ }
return 0;
}
@@ -2340,7 +2344,13 @@ static int musb_resume_noirq(struct device *dev)
* module got reset through the PSC (vs just being disabled).
*/
- musb_restore_context(musb);
+ /*
+ * Restore state only if device was not runtime suspended before
+ * the system suspend
+ */
+ if (!musb->suspended) {
+ musb_restore_context(musb);
+ }
return 0;
}
@@ -2349,6 +2359,7 @@ static int musb_runtime_suspend(struct device *dev)
struct musb *musb = dev_to_musb(dev);
musb_save_context(musb);
+ musb->suspended = true;
return 0;
}
@@ -2370,6 +2381,7 @@ static int musb_runtime_resume(struct device *dev)
if (!first)
musb_restore_context(musb);
first = 0;
+ musb->suspended = false;
return 0;
}