usb: gadget: tegra: handle the case when host reboots
Rakesh Bodla [Tue, 1 Jul 2014 12:38:36 +0000 (17:38 +0530)]
Some hosts during booting first supply vbus and then
send setup packets after x seconds. In this case we detect
as non-standard. Handle this case by setting to SDP.

Also adding condition to avoid unnecessary icon
notifications.

Bug 200017121

Change-Id: I1f0d9a2e2725a0cd3a4324f5208764ee2e4978cf
Signed-off-by: Rakesh Bodla <rbodla@nvidia.com>
Reviewed-on: http://git-master/r/433179
(cherry picked from commit 1073c32cebc1314e4d3be7967d707a743ded05ea)
Reviewed-on: http://git-master/r/436033
Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>

drivers/usb/gadget/tegra_udc.c

index 36deb86..d8efe20 100644 (file)
@@ -1478,7 +1478,6 @@ static int tegra_usb_set_charging_current(struct tegra_udc *udc)
                                                                 0, max_ua);
        }
 
-
        if (!udc->vbus_in_lp0) {
                tegra_udc_set_extcon_state(udc);
                udc->connect_type_lp0 = CONNECT_TYPE_NONE;
@@ -1574,6 +1573,7 @@ static int tegra_vbus_session(struct usb_gadget *gadget, int is_active)
                spin_unlock_irqrestore(&udc->lock, flags);
                tegra_usb_phy_power_off(udc->phy);
                tegra_usb_set_charging_current(udc);
+               udc->current_limit = 0;
        } else if (!udc->vbus_active && is_active) {
                tegra_usb_phy_power_on(udc->phy);
                /* setup the controller in the device mode */
@@ -1611,8 +1611,19 @@ static int tegra_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 
        udc = container_of(gadget, struct tegra_udc, gadget);
 
-       udc->current_limit = mA;
-       schedule_work(&udc->current_work);
+       /* Some hosts during booting first supply vbus and then
+          send setup packets after x seconds. In this case we detect
+          as non-standard. Handle this case by setting to SDP */
+       if (udc->connect_type != CONNECT_TYPE_NONE
+               && udc->connect_type != CONNECT_TYPE_SDP
+                       && udc->connect_type != CONNECT_TYPE_CDP)
+               tegra_udc_set_charger_type(udc, CONNECT_TYPE_SDP);
+
+       /* Avoid unnecessary work if there is no change in current limit */
+       if (udc->current_limit != mA) {
+               udc->current_limit = mA;
+               schedule_work(&udc->current_work);
+       }
 
        if (udc->transceiver)
                return usb_phy_set_power(udc->transceiver, mA);