aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_core.c
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2014-02-04 08:29:33 -0500
committerFelipe Balbi <balbi@ti.com>2014-02-18 11:32:26 -0500
commit33f8d75f5771993ef16ed6bd56d7210f54226203 (patch)
tree5b00defb25c73b993608528758489ef67a0ac6ea /drivers/usb/musb/musb_core.c
parent3c4653c1f62ea5f1706084090a5a3bcf3402dc8f (diff)
usb: musb: core: Fix remote-wakeup resume
During resume don't touch SUSPENDM/RESUME bits of POWER register while restoring controller context. These bits might be changed by the controller during resume operation and so will be different than what they were during suspend. e.g. SUSPENDM bit is set by software during USB global suspend but automatically cleared by the controller during remote wakeup or during resume. Setting this bit back while restoring context causes undesired behaviour. i.e. Babble interrupt is generated and USB is broken. Signed-off-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb/musb_core.c')
-rw-r--r--drivers/usb/musb/musb_core.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index fc192ad9cc6a..a501542dfeb5 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2157,11 +2157,19 @@ static void musb_restore_context(struct musb *musb)
2157 void __iomem *musb_base = musb->mregs; 2157 void __iomem *musb_base = musb->mregs;
2158 void __iomem *ep_target_regs; 2158 void __iomem *ep_target_regs;
2159 void __iomem *epio; 2159 void __iomem *epio;
2160 u8 power;
2160 2161
2161 musb_writew(musb_base, MUSB_FRAME, musb->context.frame); 2162 musb_writew(musb_base, MUSB_FRAME, musb->context.frame);
2162 musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode); 2163 musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode);
2163 musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); 2164 musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl);
2164 musb_writeb(musb_base, MUSB_POWER, musb->context.power); 2165
2166 /* Don't affect SUSPENDM/RESUME bits in POWER reg */
2167 power = musb_readb(musb_base, MUSB_POWER);
2168 power &= MUSB_POWER_SUSPENDM | MUSB_POWER_RESUME;
2169 musb->context.power &= ~(MUSB_POWER_SUSPENDM | MUSB_POWER_RESUME);
2170 power |= musb->context.power;
2171 musb_writeb(musb_base, MUSB_POWER, power);
2172
2165 musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe); 2173 musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe);
2166 musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); 2174 musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe);
2167 musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); 2175 musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe);