diff options
author | NeilBrown <neilb@suse.de> | 2012-08-12 22:32:58 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-08-14 04:03:00 -0400 |
commit | 12a19b5f836c1a1b838e668f9aa804d017d8c58b (patch) | |
tree | d57cc77e5cb43656d9388b70d53b0628c8406c1a /drivers/usb/musb/omap2430.c | |
parent | 07a67bbb95ea7977846bd851dab5f4f2be8e488c (diff) |
usb: musb: omap2430: don't loop indefinitely in interrupt.
When called during resume_irqs, omap2430_musb_set_vbus() is run with
interrupts disabled, In that case 'jiffies' never changes so the loop
can loop forever.
So impose a maximum loop count and add an 'mdelay' to ensure we wait
a reasonable amount of time for bit to be cleared.
This fixes a hang on resume.
Signed-of-by: NeilBrown <neilb@suse.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb/omap2430.c')
-rw-r--r-- | drivers/usb/musb/omap2430.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index e32aff9920f2..af5f4214673d 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
36 | #include <linux/err.h> | 36 | #include <linux/err.h> |
37 | #include <linux/delay.h> | ||
37 | #include <linux/usb/musb-omap.h> | 38 | #include <linux/usb/musb-omap.h> |
38 | 39 | ||
39 | #include "musb_core.h" | 40 | #include "musb_core.h" |
@@ -150,6 +151,7 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) | |||
150 | 151 | ||
151 | if (is_on) { | 152 | if (is_on) { |
152 | if (musb->xceiv->state == OTG_STATE_A_IDLE) { | 153 | if (musb->xceiv->state == OTG_STATE_A_IDLE) { |
154 | int loops = 100; | ||
153 | /* start the session */ | 155 | /* start the session */ |
154 | devctl |= MUSB_DEVCTL_SESSION; | 156 | devctl |= MUSB_DEVCTL_SESSION; |
155 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | 157 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); |
@@ -159,9 +161,11 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) | |||
159 | */ | 161 | */ |
160 | while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) { | 162 | while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) { |
161 | 163 | ||
164 | mdelay(5); | ||
162 | cpu_relax(); | 165 | cpu_relax(); |
163 | 166 | ||
164 | if (time_after(jiffies, timeout)) { | 167 | if (time_after(jiffies, timeout) |
168 | || loops-- <= 0) { | ||
165 | dev_err(musb->controller, | 169 | dev_err(musb->controller, |
166 | "configured as A device timeout"); | 170 | "configured as A device timeout"); |
167 | ret = -EINVAL; | 171 | ret = -EINVAL; |