]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00215792 USB:fix gadget issue when boot kernel with USB connected
authormake shi <b15407@freescale.com>
Thu, 5 Jul 2012 05:57:59 +0000 (13:57 +0800)
committerOliver Wendt <ow@karo-electronics.de>
Mon, 30 Sep 2013 12:12:21 +0000 (14:12 +0200)
- USB gadget disconnected when system boot kernel with USB connected. Commit
68b1c60f7f6c436340206679a18d61d9 induce the issue, call dr_discharge_line(1)
to ensure no abnormal usb wakeup interrupt happen after plug out the cable.
There are two cases cause dr_discharge_line(1) of fsl_otg_event() be called.
One case is switch the otg mode form Host mode to Device mode. Another case is
boot kernel with USB connected. The host_first_call is true when system boot
kernel with USB connected, otherwise it is false. So dr_discharge_line(true)
should not be called in fsl_otg_event() if host_first_call is true.

- USBOH3 clock is still on after plug out the cable when boot kernel with USB
connected, If the suspended bit is 0x1 and stopped is 0x0,the case is regarded
as suspend connected to usb charger. USB clock will be turn on, otherwise the
second suspend is processed without USB clock and it causes system hang. But
system boot kernel with cable connected, suspended is 0x1 and stopped is 0x0.
USB clock will be on by mistake. And stopped is cleared in dr_controller_run()
when system boot kernel with USB connected. We should check the suspended and
stopped bit before call dr_controller_run() to fix the issue.

Signed-off-by: make shi <b15407@freescale.com>
drivers/usb/gadget/arcotg_udc.c
drivers/usb/otg/fsl_otg.c

index 90eb9864b0a84175bc228771d284ec0a7085911b..a7bc4801d83cf203f4cf04a46a45f612c1ff032f 100755 (executable)
@@ -3453,6 +3453,15 @@ static int fsl_udc_resume(struct platform_device *pdev)
                goto end;
        }
 
+       /*
+        * To fix suspend issue connected to usb charger,if stopped is 0
+        * suspended is 1,clock on and out of low power mode to avoid
+        * next system suspend no clock to cause system hang.
+        */
+       if (udc_controller->suspended && !udc_controller->stopped) {
+               dr_clk_gate(true);
+               dr_phy_low_power_mode(udc_controller, false);
+       }
        /* Enable DR irq reg and set controller Run */
        if (udc_controller->stopped) {
                /* the clock is already on at usb wakeup routine */
@@ -3491,10 +3500,7 @@ end:
                dr_clk_gate(false);
        }
 
-       if (!(--udc_controller->suspended) && !udc_controller->stopped) {
-               dr_clk_gate(true);
-               dr_phy_low_power_mode(udc_controller, false);
-       }
+       --udc_controller->suspended;
        enable_irq(udc_controller->irq);
        mutex_unlock(&udc_resume_mutex);
        printk(KERN_DEBUG "USB Gadget resume ends\n");
index 186fdafe4dbc3b53261dcb412b518f3125d0a791..4205ed9aaec9437dbb42557ee2385c7738558649 100755 (executable)
@@ -747,7 +747,7 @@ static void fsl_otg_event(struct work_struct *work)
                fsm->a_conn = 0;
 
        if (fsm->id) {          /* switch to gadget */
-               if (pdata->dr_discharge_line)
+               if ((og->host_first_call == false) && pdata->dr_discharge_line)
                        pdata->dr_discharge_line(true);
                fsl_otg_start_host(fsm, 0);
                if (pdata->wake_up_enable)