usb: cdns3: gadget: move wait configuration operation
authorPeter Chen <peter.chen@nxp.com>
Tue, 1 Sep 2020 02:33:52 +0000 (10:33 +0800)
committerFelipe Balbi <balbi@kernel.org>
Fri, 2 Oct 2020 06:57:40 +0000 (09:57 +0300)
After commit f4cfe5ce607d ("usb: cdns3: gadget: improve the
set_configuration handling"), the software will inform the
hardware the request has finished at cdns3_ep0_complete_setup.
The configuration set bit is only set after request has finished,
so it needs to move waiting operation after that. Meanwhile,
if it is timeout, it will show warning message and return error.

Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
drivers/usb/cdns3/ep0.c
drivers/usb/cdns3/gadget.c

index d9779abc65b2b79e3dd70889a9d786a0436269a4..4761c852d9c4b8bc686206669f3a72cefd229185 100644 (file)
@@ -717,9 +717,17 @@ static int cdns3_gadget_ep0_queue(struct usb_ep *ep,
 
        /* send STATUS stage. Should be called only for SET_CONFIGURATION */
        if (priv_dev->ep0_stage == CDNS3_STATUS_STAGE) {
+               u32 val;
+
                cdns3_select_ep(priv_dev, 0x00);
                cdns3_set_hw_configuration(priv_dev);
                cdns3_ep0_complete_setup(priv_dev, 0, 1);
+               /* wait until configuration set */
+               ret = readl_poll_timeout_atomic(&priv_dev->regs->usb_sts, val,
+                                         val & USB_STS_CFGSTS_MASK, 1, 100);
+               if (ret == -ETIMEDOUT)
+                       dev_warn(priv_dev->dev, "timeout for waiting configuration set\n");
+
                request->actual = 0;
                priv_dev->status_completion_no_call = true;
                priv_dev->pending_status_request = request;
@@ -731,7 +739,7 @@ static int cdns3_gadget_ep0_queue(struct usb_ep *ep,
                 * ep0_queue is back.
                 */
                queue_work(system_freezable_wq, &priv_dev->pending_status_wq);
-               return 0;
+               return ret;
        }
 
        if (!list_empty(&priv_ep->pending_req_list)) {
index 4c939dad9c339ef4bf291742991e693a1e8e3d25..aca347b7da578fdcc81a13851d8b9a651e4c357e 100644 (file)
@@ -1310,7 +1310,6 @@ void cdns3_set_hw_configuration(struct cdns3_device *priv_dev)
 {
        struct cdns3_endpoint *priv_ep;
        struct usb_ep *ep;
-       int val;
 
        if (priv_dev->hw_configured_flag)
                return;
@@ -1320,10 +1319,6 @@ void cdns3_set_hw_configuration(struct cdns3_device *priv_dev)
        cdns3_set_register_bit(&priv_dev->regs->usb_conf,
                               USB_CONF_U1EN | USB_CONF_U2EN);
 
-       /* wait until configuration set */
-       readl_poll_timeout_atomic(&priv_dev->regs->usb_sts, val,
-                                 val & USB_STS_CFGSTS_MASK, 1, 100);
-
        priv_dev->hw_configured_flag = 1;
 
        list_for_each_entry(ep, &priv_dev->gadget.ep_list, ep_list) {