usb: musb: omap2430: don't loop indefinitely in interrupt.
authorNeilBrown <neilb@suse.de>
Mon, 13 Aug 2012 02:32:58 +0000 (12:32 +1000)
committerGrazvydas Ignotas <notasas@gmail.com>
Sat, 2 Mar 2013 20:11:57 +0000 (22:11 +0200)
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>
Conflicts:

drivers/usb/musb/omap2430.c

drivers/usb/musb/omap2430.c

index 9c3ca10..74f2fb9 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/pm_runtime.h>
 #include <linux/err.h>
+#include <linux/delay.h>
 
 #include "musb_core.h"
 #include "omap2430.h"
@@ -145,6 +146,7 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
 
        if (is_on) {
                if (musb->xceiv->state == OTG_STATE_A_IDLE) {
+                       int loops = 100;
                        /* start the session */
                        devctl |= MUSB_DEVCTL_SESSION;
                        musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
@@ -154,9 +156,11 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
                         */
                        while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
 
+                               mdelay(5);
                                cpu_relax();
 
-                               if (time_after(jiffies, timeout)) {
+                               if (time_after(jiffies, timeout)
+                                   || loops-- <= 0) {
                                        dev_err(musb->controller,
                                        "configured as A device timeout");
                                        ret = -EINVAL;