usb: support usb gadget for hikey960
authorFan Ning <fanning4@hisilicon.com>
Tue, 1 Aug 2017 08:33:13 +0000 (16:33 +0800)
committerDouglas RAILLARD <douglas.raillard@arm.com>
Tue, 14 Aug 2018 15:32:09 +0000 (16:32 +0100)
Signed-off-by: Fan Ning <fanning4@hisilicon.com>
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-otg.c
drivers/usb/dwc3/gadget.c

index 001989936785274897ecbc9470eae1875cb986dc..8ef5a5a765d9dc43ddd1e7a3ff042d516dc8fecc 100644 (file)
@@ -78,6 +78,8 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
                        mode = USB_DR_MODE_HOST;
                else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
                        mode = USB_DR_MODE_PERIPHERAL;
+               else if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE))
+                       mode = USB_DR_MODE_OTG;
        }
 
        if (mode != dwc->dr_mode) {
@@ -1631,8 +1633,11 @@ static int dwc3_runtime_checks(struct dwc3 *dwc)
 {
        switch (dwc->current_dr_role) {
        case DWC3_GCTL_PRTCAP_DEVICE:
+       case DWC3_GCTL_PRTCAP_OTG:
+#ifndef CONFIG_USB_DWC3_HISI
                if (dwc->connected)
                        return -EBUSY;
+#endif
                break;
        case DWC3_GCTL_PRTCAP_HOST:
        default:
@@ -1657,6 +1662,7 @@ static int dwc3_runtime_suspend(struct device *dev)
 
        device_init_wakeup(dev, true);
 
+       pm_runtime_put(dev);
        return 0;
 }
 
@@ -1682,6 +1688,8 @@ static int dwc3_runtime_resume(struct device *dev)
        }
 
        pm_runtime_mark_last_busy(dev);
+       /* maybe drop this? */
+       pm_runtime_get(dev);
 
        return 0;
 }
@@ -1748,6 +1756,31 @@ static const struct dev_pm_ops dwc3_dev_pm_ops = {
                           dwc3_runtime_idle)
 };
 
+int dwc3_resume_device(struct dwc3 *dwc)
+{
+       int status;
+
+       pr_info("[dwc3_resume_device] +\n");
+       status = dwc3_runtime_resume(dwc->dev);
+       if (status < 0) {
+               pr_err("dwc3_runtime_resume err, status:%d\n", status);
+       }
+       pr_info("[dwc3_resume_device] -\n");
+       return status;
+}
+
+void dwc3_suspend_device(struct dwc3 *dwc)
+{
+       int status;
+
+       pr_info("[dwc3_suspend_device] +\n");
+       status = dwc3_runtime_suspend(dwc->dev);
+       if (status < 0) {
+               pr_err("dwc3_runtime_suspend err, status:%d\n", status);
+       }
+       pr_info("[dwc3_suspend_device] -\n");
+}
+
 #ifdef CONFIG_OF
 static const struct of_device_id of_dwc3_match[] = {
        {
index b933ae4ca31e8bc63cafc60a88fb00455234c34e..34a082ea96e38887310a584b87aeb066b8acb0d9 100644 (file)
@@ -245,8 +245,10 @@ int dwc3_otg_work(struct dwc3_otg *dwc_otg, int evt)
        switch (evt) {
        case DWC3_OTG_EVT_ID_SET:
                dwc3_otg_stop_host(dwc_otg);
+               dwc3_suspend_device(dwc_otg->dwc);
                break;
        case DWC3_OTG_EVT_ID_CLEAR:
+               ret = dwc3_resume_device(dwc_otg->dwc);
                if (ret) {
                        pr_err("%s: resume device failed!\n", __func__);
                        return ret;
@@ -254,10 +256,12 @@ int dwc3_otg_work(struct dwc3_otg *dwc_otg, int evt)
                ret = dwc3_otg_start_host(dwc_otg);
                if (ret) {
                        pr_err("%s: start host failed!\n", __func__);
+                       dwc3_suspend_device(dwc_otg->dwc);
                        return ret;
                }
                break;
        case DWC3_OTG_EVT_VBUS_SET:
+               ret = dwc3_resume_device(dwc_otg->dwc);
                if (ret) {
                        pr_err("%s: resume device failed!\n", __func__);
                        return ret;
@@ -265,11 +269,13 @@ int dwc3_otg_work(struct dwc3_otg *dwc_otg, int evt)
                ret = dwc3_otg_start_peripheral(dwc_otg);
                if (ret) {
                        pr_err("%s: start peripheral failed!\n", __func__);
+                       dwc3_suspend_device(dwc_otg->dwc);
                        return ret;
                }
                break;
        case DWC3_OTG_EVT_VBUS_CLEAR:
                ret = dwc3_otg_stop_peripheral(dwc_otg);
+               dwc3_suspend_device(dwc_otg->dwc);
                break;
        default:
                break;
index a38bd7f987393372686c1403ab917a70753f5349..d77fd731324edc89a843ba9f9fe7cd04a3e148b5 100644 (file)
@@ -270,7 +270,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
 {
        const struct usb_endpoint_descriptor *desc = dep->endpoint.desc;
        struct dwc3             *dwc = dep->dwc;
-       u32                     timeout = 1000;
+       u32                     timeout = 3000;
        u32                     reg;
 
        int                     cmd_status = 0;
@@ -3210,7 +3210,9 @@ int dwc3_gadget_init(struct dwc3 *dwc)
        dwc->gadget.speed               = USB_SPEED_UNKNOWN;
        dwc->gadget.sg_supported        = true;
        dwc->gadget.name                = "dwc3-gadget";
+#ifndef CONFIG_USB_DWC3_HISI
        dwc->gadget.is_otg              = dwc->dr_mode == USB_DR_MODE_OTG;
+#endif
 
        /*
         * FIXME We might be setting max_speed to <SUPER, however versions