usb: bdc: fix "xsf for ep not enabled" errror
authorAl Cooper <alcooperx@gmail.com>
Wed, 19 Jul 2017 19:11:46 +0000 (15:11 -0400)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Tue, 15 Aug 2017 11:18:58 +0000 (14:18 +0300)
This patch essentially clears the port status change bits at the
correct times. It is necessary because the driver was not handling
the change bits correctly for events during device
connection/disconnection and bus enumeration. So, one of them (PCC)
was left stuck sometimes causing the "xsf for ep not enabled"
error we get on first connection. This was found by the Android team.
This was debugged and fixed by Sasi Kumar.

Signed-off-by: Al Cooper <alcooperx@gmail.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/gadget/udc/bdc/bdc_udc.c

index aae7458d8986945925093ada5b59143e0215a333..c8434614645695132a34dee946c559de752d2e5c 100644 (file)
@@ -249,6 +249,7 @@ void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport)
                        disconn = true;
                else if ((uspc & BDC_PCS) && !BDC_PST(uspc))
                        connected = true;
+               clear_flags |= BDC_PCC;
        }
 
        /* Change in VBus and VBus is present */
@@ -259,16 +260,16 @@ void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport)
                        bdc_softconn(bdc);
                        usb_gadget_set_state(&bdc->gadget, USB_STATE_POWERED);
                }
-               clear_flags = BDC_VBC;
+               clear_flags |= BDC_VBC;
        } else if ((uspc & BDC_PRS) || (uspc & BDC_PRC) || disconn) {
                /* Hot reset, warm reset, 2.0 bus reset or disconn */
                dev_dbg(bdc->dev, "Port reset or disconn\n");
                bdc_uspc_disconnected(bdc, disconn);
-               clear_flags = BDC_PCC|BDC_PCS|BDC_PRS|BDC_PRC;
+               clear_flags |= BDC_PRC;
        } else if ((uspc & BDC_PSC) && (uspc & BDC_PCS)) {
                /* Change in Link state */
                handle_link_state_change(bdc, uspc);
-               clear_flags = BDC_PSC|BDC_PCS;
+               clear_flags |= BDC_PSC;
        }
 
        /*