diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 76578d72208f..20df09630c8e 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -39,7 +39,16 @@ #include "io.h" #include "debug.h" + +/* + * For type visibility (http://b/236036821) + */ +const struct dwc3 *const ANDROID_GKI_struct_dwc3; +EXPORT_SYMBOL_GPL(ANDROID_GKI_struct_dwc3); + +#ifndef __GENKSYMS__ #include "../host/xhci.h" +#endif #define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */ @@ -107,10 +116,11 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc) void dwc3_enable_susphy(struct dwc3 *dwc, bool enable) { + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); u32 reg; int i; - for (i = 0; i < dwc->num_usb3_ports; i++) { + for (i = 0; i < vdwc->num_usb3_ports; i++) { reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(i)); if (enable && !dwc->dis_u3_susphy_quirk) reg |= DWC3_GUSB3PIPECTL_SUSPHY; @@ -120,7 +130,7 @@ void dwc3_enable_susphy(struct dwc3 *dwc, bool enable) dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(i), reg); } - for (i = 0; i < dwc->num_usb2_ports; i++) { + for (i = 0; i < vdwc->num_usb2_ports; i++) { reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i)); if (enable && !dwc->dis_u2_susphy_quirk) reg |= DWC3_GUSB2PHYCFG_SUSPHY; @@ -146,6 +156,7 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode) static void __dwc3_set_mode(struct work_struct *work) { struct dwc3 *dwc = work_to_dwc(work); + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); unsigned long flags; int ret; u32 reg; @@ -228,10 +239,14 @@ static void __dwc3_set_mode(struct work_struct *work) } else { if (dwc->usb2_phy) otg_set_vbus(dwc->usb2_phy->otg, true); - for (i = 0; i < dwc->num_usb2_ports; i++) - phy_set_mode(dwc->usb2_generic_phy[i], PHY_MODE_USB_HOST); - for (i = 0; i < dwc->num_usb3_ports; i++) - phy_set_mode(dwc->usb3_generic_phy[i], PHY_MODE_USB_HOST); + + phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST); + for (i = 1; i < vdwc->num_usb2_ports; i++) + phy_set_mode(vdwc->usb2_generic_phy[i], PHY_MODE_USB_HOST); + phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST); + for (i = 1; i < vdwc->num_usb3_ports; i++) + phy_set_mode(vdwc->usb3_generic_phy[i], PHY_MODE_USB_HOST); + if (dwc->dis_split_quirk) { reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); reg |= DWC3_GUCTL3_SPLITDISABLE; @@ -246,8 +261,8 @@ static void __dwc3_set_mode(struct work_struct *work) if (dwc->usb2_phy) otg_set_vbus(dwc->usb2_phy->otg, false); - phy_set_mode(dwc->usb2_generic_phy[0], PHY_MODE_USB_DEVICE); - phy_set_mode(dwc->usb3_generic_phy[0], PHY_MODE_USB_DEVICE); + phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE); + phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_DEVICE); ret = dwc3_gadget_init(dwc); if (ret) @@ -847,16 +862,17 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index) */ static int dwc3_phy_setup(struct dwc3 *dwc) { + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); int i; int ret; - for (i = 0; i < dwc->num_usb3_ports; i++) { + for (i = 0; i < vdwc->num_usb3_ports; i++) { ret = dwc3_ss_phy_setup(dwc, i); if (ret) return ret; } - for (i = 0; i < dwc->num_usb2_ports; i++) { + for (i = 0; i < vdwc->num_usb2_ports; i++) { ret = dwc3_hs_phy_setup(dwc, i); if (ret) return ret; @@ -899,6 +915,7 @@ static void dwc3_clk_disable(struct dwc3 *dwc) static void dwc3_core_exit(struct dwc3 *dwc) { + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); int i; dwc3_event_buffers_cleanup(dwc); @@ -906,18 +923,22 @@ static void dwc3_core_exit(struct dwc3 *dwc) usb_phy_set_suspend(dwc->usb2_phy, 1); usb_phy_set_suspend(dwc->usb3_phy, 1); - for (i = 0; i < dwc->num_usb2_ports; i++) - phy_power_off(dwc->usb2_generic_phy[i]); - for (i = 0; i < dwc->num_usb3_ports; i++) - phy_power_off(dwc->usb3_generic_phy[i]); + phy_power_off(dwc->usb2_generic_phy); + for (i = 1; i < vdwc->num_usb2_ports; i++) + phy_power_off(vdwc->usb2_generic_phy[i]); + phy_power_off(dwc->usb3_generic_phy); + for (i = 1; i < vdwc->num_usb3_ports; i++) + phy_power_off(vdwc->usb3_generic_phy[i]); usb_phy_shutdown(dwc->usb2_phy); usb_phy_shutdown(dwc->usb3_phy); - for (i = 0; i < dwc->num_usb2_ports; i++) - phy_exit(dwc->usb2_generic_phy[i]); - for (i = 0; i < dwc->num_usb3_ports; i++) - phy_exit(dwc->usb3_generic_phy[i]); + phy_exit(dwc->usb2_generic_phy); + for (i = 1; i < vdwc->num_usb2_ports; i++) + phy_exit(vdwc->usb2_generic_phy[i]); + phy_exit(dwc->usb3_generic_phy); + for (i = 1; i < vdwc->num_usb3_ports; i++) + phy_exit(vdwc->usb3_generic_phy[i]); dwc3_clk_disable(dwc); reset_control_assert(dwc->reset); @@ -1150,6 +1171,7 @@ static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc) */ static int dwc3_core_init(struct dwc3 *dwc) { + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); unsigned int hw_mode; u32 reg; int ret; @@ -1189,14 +1211,22 @@ static int dwc3_core_init(struct dwc3 *dwc) usb_phy_init(dwc->usb2_phy); usb_phy_init(dwc->usb3_phy); - for (i = 0; i < dwc->num_usb2_ports; i++) { - ret = phy_init(dwc->usb2_generic_phy[i]); + ret = phy_init(dwc->usb2_generic_phy); + if (ret < 0) + goto err0a; + + for (i = 1; i < vdwc->num_usb2_ports; i++) { + ret = phy_init(vdwc->usb2_generic_phy[i]); if (ret < 0) goto exit_usb2_phy; } - for (i = 0; i < dwc->num_usb3_ports; i++) { - ret = phy_init(dwc->usb3_generic_phy[i]); + ret = phy_init(dwc->usb3_generic_phy); + if (ret < 0) + goto exit_usb2_phy; + + for (i = 1; i < vdwc->num_usb3_ports; i++) { + ret = phy_init(vdwc->usb3_generic_phy[i]); if (ret < 0) goto exit_usb3_phy; } @@ -1226,14 +1256,22 @@ static int dwc3_core_init(struct dwc3 *dwc) usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); - for (i = 0; i < dwc->num_usb2_ports; i++) { - ret = phy_power_on(dwc->usb2_generic_phy[i]); + ret = phy_power_on(dwc->usb2_generic_phy); + if (ret < 0) + goto set_suspend_phy; + + for (i = 1; i < vdwc->num_usb2_ports; i++) { + ret = phy_power_on(vdwc->usb2_generic_phy[i]); if (ret < 0) goto power_off_usb2_phy; } - for (i = 0; i < dwc->num_usb3_ports; i++) { - ret = phy_power_on(dwc->usb3_generic_phy[i]); + ret = phy_power_on(dwc->usb3_generic_phy); + if (ret < 0) + goto power_off_usb2_phy; + + for (i = 1; i < vdwc->num_usb3_ports; i++) { + ret = phy_power_on(vdwc->usb3_generic_phy[i]); if (ret < 0) goto power_off_usb3_phy; } @@ -1377,26 +1415,31 @@ static int dwc3_core_init(struct dwc3 *dwc) * (http://b/233985973) */ power_off_usb3_phy: - for (j = i - 1; j >= 0; j--) - phy_power_off(dwc->usb3_generic_phy[j]); - i = dwc->num_usb2_ports; + for (j = i - 1; j > 0; j--) + phy_power_off(vdwc->usb3_generic_phy[j]); + phy_power_off(dwc->usb3_generic_phy); + i = vdwc->num_usb2_ports; power_off_usb2_phy: - for (j = i - 1; j >= 0; j--) - phy_power_off(dwc->usb2_generic_phy[j]); - i = dwc->num_usb3_ports; + for (j = i - 1; j > 0; j--) + phy_power_off(vdwc->usb2_generic_phy[j]); + phy_power_off(dwc->usb2_generic_phy); + i = vdwc->num_usb3_ports; +set_suspend_phy: usb_phy_set_suspend(dwc->usb2_phy, 1); usb_phy_set_suspend(dwc->usb3_phy, 1); exit_usb3_phy: - for (j = i - 1; j >= 0; j--) - phy_exit(dwc->usb3_generic_phy[j]); - i = dwc->num_usb2_ports; + for (j = i - 1; j > 0; j--) + phy_exit(vdwc->usb3_generic_phy[j]); + phy_exit(dwc->usb3_generic_phy); + i = vdwc->num_usb2_ports; exit_usb2_phy: - for (j = i - 1; j >= 0; j--) - phy_exit(dwc->usb2_generic_phy[j]); + for (j = i - 1; j > 0; j--) + phy_exit(vdwc->usb2_generic_phy[j]); + phy_exit(dwc->usb2_generic_phy); usb_phy_shutdown(dwc->usb2_phy); usb_phy_shutdown(dwc->usb3_phy); @@ -1410,8 +1453,10 @@ err0: static int dwc3_core_get_phy(struct dwc3 *dwc) { + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); struct device *dev = dwc->dev; struct device_node *node = dev->of_node; + struct phy *temp_phy = NULL; char phy_name[9]; int ret; int i; @@ -1440,38 +1485,48 @@ static int dwc3_core_get_phy(struct dwc3 *dwc) return dev_err_probe(dev, ret, "no usb3 phy configured\n"); } - for (i = 0; i < dwc->num_usb2_ports; i++) { - if (dwc->num_usb2_ports == 1) + for (i = 0; i < vdwc->num_usb2_ports; i++) { + if (vdwc->num_usb2_ports == 1) snprintf(phy_name, sizeof(phy_name), "usb2-phy"); else snprintf(phy_name, sizeof(phy_name), "usb2-%d", i); - dwc->usb2_generic_phy[i] = devm_phy_get(dev, phy_name); - if (IS_ERR(dwc->usb2_generic_phy[i])) { - ret = PTR_ERR(dwc->usb2_generic_phy[i]); + temp_phy = devm_phy_get(dev, phy_name); + if (IS_ERR(temp_phy)) { + ret = PTR_ERR(temp_phy); if (ret == -ENOSYS || ret == -ENODEV) - dwc->usb2_generic_phy[i] = NULL; + temp_phy = NULL; else return dev_err_probe(dev, ret, "failed to lookup phy %s\n", phy_name); } + + if (i == 0) + dwc->usb2_generic_phy = temp_phy; + else + vdwc->usb2_generic_phy[i] = temp_phy; } - for (i = 0; i < dwc->num_usb3_ports; i++) { - if (dwc->num_usb3_ports == 1) + for (i = 0; i < vdwc->num_usb3_ports; i++) { + if (vdwc->num_usb3_ports == 1) snprintf(phy_name, sizeof(phy_name), "usb3-phy"); else snprintf(phy_name, sizeof(phy_name), "usb3-%d", i); - dwc->usb3_generic_phy[i] = devm_phy_get(dev, phy_name); - if (IS_ERR(dwc->usb3_generic_phy[i])) { - ret = PTR_ERR(dwc->usb3_generic_phy[i]); + temp_phy = devm_phy_get(dev, phy_name); + if (IS_ERR(temp_phy)) { + ret = PTR_ERR(temp_phy); if (ret == -ENOSYS || ret == -ENODEV) - dwc->usb3_generic_phy[i] = NULL; + temp_phy = NULL; else return dev_err_probe(dev, ret, "failed to lookup phy %s\n", phy_name); } + + if (i == 0) + dwc->usb3_generic_phy = temp_phy; + else + vdwc->usb3_generic_phy[i] = temp_phy; } return 0; @@ -1479,6 +1534,7 @@ static int dwc3_core_get_phy(struct dwc3 *dwc) static int dwc3_core_init_mode(struct dwc3 *dwc) { + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); struct device *dev = dwc->dev; int ret; int i; @@ -1489,8 +1545,8 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) if (dwc->usb2_phy) otg_set_vbus(dwc->usb2_phy->otg, false); - phy_set_mode(dwc->usb2_generic_phy[0], PHY_MODE_USB_DEVICE); - phy_set_mode(dwc->usb3_generic_phy[0], PHY_MODE_USB_DEVICE); + phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE); + phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_DEVICE); ret = dwc3_gadget_init(dwc); if (ret) @@ -1502,10 +1558,12 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) if (dwc->usb2_phy) otg_set_vbus(dwc->usb2_phy->otg, true); - for (i = 0; i < dwc->num_usb2_ports; i++) - phy_set_mode(dwc->usb2_generic_phy[i], PHY_MODE_USB_HOST); - for (i = 0; i < dwc->num_usb3_ports; i++) - phy_set_mode(dwc->usb3_generic_phy[i], PHY_MODE_USB_HOST); + phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST); + for (i = 1; i < vdwc->num_usb2_ports; i++) + phy_set_mode(vdwc->usb2_generic_phy[i], PHY_MODE_USB_HOST); + phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST); + for (i = 1; i < vdwc->num_usb3_ports; i++) + phy_set_mode(vdwc->usb3_generic_phy[i], PHY_MODE_USB_HOST); ret = dwc3_host_init(dwc); if (ret) @@ -1865,6 +1923,7 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc) static int dwc3_get_num_ports(struct dwc3 *dwc) { + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); void __iomem *base; u8 major_revision; u32 offset; @@ -1891,9 +1950,9 @@ static int dwc3_get_num_ports(struct dwc3 *dwc) val = readl(base + offset + 0x08); if (major_revision == 0x03) { - dwc->num_usb3_ports += XHCI_EXT_PORT_COUNT(val); + vdwc->num_usb3_ports += XHCI_EXT_PORT_COUNT(val); } else if (major_revision <= 0x02) { - dwc->num_usb2_ports += XHCI_EXT_PORT_COUNT(val); + vdwc->num_usb2_ports += XHCI_EXT_PORT_COUNT(val); } else { dev_warn(dwc->dev, "unrecognized port major revision %d\n", major_revision); @@ -1901,11 +1960,11 @@ static int dwc3_get_num_ports(struct dwc3 *dwc) } while (1); dev_dbg(dwc->dev, "hs-ports: %u ss-ports: %u\n", - dwc->num_usb2_ports, dwc->num_usb3_ports); + vdwc->num_usb2_ports, vdwc->num_usb3_ports); iounmap(base); - if (dwc->num_usb2_ports > DWC3_USB2_MAX_PORTS || - dwc->num_usb3_ports > DWC3_USB3_MAX_PORTS) + if (vdwc->num_usb2_ports > DWC3_USB2_MAX_PORTS || + vdwc->num_usb3_ports > DWC3_USB3_MAX_PORTS) return -EINVAL; return 0; @@ -1917,16 +1976,18 @@ static int dwc3_probe(struct platform_device *pdev) struct resource *res, dwc_res; unsigned int hw_mode; struct dwc3 *dwc; + struct dwc3_vendor *vdwc; int ret; int i; void __iomem *regs; - dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL); - if (!dwc) + vdwc = devm_kzalloc(dev, sizeof(*vdwc), GFP_KERNEL); + if (!vdwc) return -ENOMEM; + dwc = &vdwc->dwc; dwc->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -2053,8 +2114,8 @@ static int dwc3_probe(struct platform_device *pdev) if (ret) goto disable_clks; } else { - dwc->num_usb2_ports = 1; - dwc->num_usb3_ports = 1; + vdwc->num_usb2_ports = 1; + vdwc->num_usb3_ports = 1; } spin_lock_init(&dwc->lock); @@ -2115,20 +2176,24 @@ err5: usb_phy_set_suspend(dwc->usb2_phy, 1); usb_phy_set_suspend(dwc->usb3_phy, 1); - for (i = 0; i < dwc->num_usb3_ports; i++) - phy_power_off(dwc->usb3_generic_phy[i]); + phy_power_off(dwc->usb3_generic_phy); + for (i = 1; i < vdwc->num_usb3_ports; i++) + phy_power_off(vdwc->usb3_generic_phy[i]); - for (i = 0; i < dwc->num_usb2_ports; i++) - phy_power_off(dwc->usb2_generic_phy[i]); + phy_power_off(dwc->usb2_generic_phy); + for (i = 1; i < vdwc->num_usb2_ports; i++) + phy_power_off(vdwc->usb2_generic_phy[i]); usb_phy_shutdown(dwc->usb2_phy); usb_phy_shutdown(dwc->usb3_phy); - for (i = 0; i < dwc->num_usb3_ports; i++) - phy_exit(dwc->usb3_generic_phy[i]); + phy_exit(dwc->usb3_generic_phy); + for (i = 1; i < vdwc->num_usb3_ports; i++) + phy_exit(vdwc->usb3_generic_phy[i]); - for (i = 0; i < dwc->num_usb2_ports; i++) - phy_exit(dwc->usb2_generic_phy[i]); + phy_exit(dwc->usb2_generic_phy); + for (i = 1; i < vdwc->num_usb2_ports; i++) + phy_exit(vdwc->usb2_generic_phy[i]); dwc3_ulpi_exit(dwc); @@ -2214,6 +2279,7 @@ assert_reset: static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) { + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); u32 reg; int i; @@ -2234,7 +2300,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) /* Let controller to suspend HSPHY before PHY driver suspends */ if (dwc->dis_u2_susphy_quirk || dwc->dis_enblslpm_quirk) { - for (i = 0; i < dwc->num_usb2_ports; i++) { + for (i = 0; i < vdwc->num_usb2_ports; i++) { reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i)); reg |= DWC3_GUSB2PHYCFG_ENBLSLPM | DWC3_GUSB2PHYCFG_SUSPHY; @@ -2244,10 +2310,12 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) usleep_range(5000, 6000); } - for (i = 0; i < dwc->num_usb2_ports; i++) - phy_pm_runtime_put_sync(dwc->usb2_generic_phy[i]); - for (i = 0; i < dwc->num_usb3_ports; i++) - phy_pm_runtime_put_sync(dwc->usb3_generic_phy[i]); + phy_pm_runtime_put_sync(dwc->usb2_generic_phy); + for (i = 1; i < vdwc->num_usb2_ports; i++) + phy_pm_runtime_put_sync(vdwc->usb2_generic_phy[i]); + phy_pm_runtime_put_sync(dwc->usb3_generic_phy); + for (i = 1; i < vdwc->num_usb3_ports; i++) + phy_pm_runtime_put_sync(vdwc->usb3_generic_phy[i]); break; case DWC3_GCTL_PRTCAP_OTG: /* do nothing during runtime_suspend */ @@ -2272,6 +2340,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) { + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); int ret; u32 reg; int i; @@ -2294,7 +2363,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) break; } /* Restore GUSB2PHYCFG bits that were modified in suspend */ - for (i = 0; i < dwc->num_usb2_ports; i++) { + for (i = 0; i < vdwc->num_usb2_ports; i++) { reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i)); if (dwc->dis_u2_susphy_quirk) reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; @@ -2305,10 +2374,12 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg); } - for (i = 0; i < dwc->num_usb2_ports; i++) - phy_pm_runtime_get_sync(dwc->usb2_generic_phy[i]); - for (i = 0; i < dwc->num_usb3_ports; i++) - phy_pm_runtime_get_sync(dwc->usb3_generic_phy[i]); + phy_pm_runtime_get_sync(dwc->usb2_generic_phy); + for (i = 1; i < vdwc->num_usb2_ports; i++) + phy_pm_runtime_get_sync(vdwc->usb2_generic_phy[i]); + phy_pm_runtime_get_sync(dwc->usb3_generic_phy); + for (i = 1; i < vdwc->num_usb3_ports; i++) + phy_pm_runtime_get_sync(vdwc->usb3_generic_phy[i]); break; case DWC3_GCTL_PRTCAP_OTG: /* nothing to do on runtime_resume */ @@ -2510,12 +2581,6 @@ static struct platform_driver dwc3_driver = { module_platform_driver(dwc3_driver); -/* - * For type visibility (http://b/236036821) - */ -const struct dwc3 *const ANDROID_GKI_struct_dwc3; -EXPORT_SYMBOL_GPL(ANDROID_GKI_struct_dwc3); - MODULE_ALIAS("platform:dwc3"); MODULE_AUTHOR("Felipe Balbi "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index b44dca8dcbba..fab2f4e3a2bb 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1048,10 +1048,8 @@ struct dwc3_scratchpad_array { * @usb_psy: pointer to power supply interface. * @usb2_phy: pointer to USB2 PHY * @usb3_phy: pointer to USB3 PHY - * @usb2_generic_phy: pointer to array of USB2 PHYs - * @usb3_generic_phy: pointer to array of USB3 PHYs - * @num_usb2_ports: number of USB2 ports - * @num_usb3_ports: number of USB3 ports + * @usb2_generic_phy: pointer to USB2 PHY + * @usb3_generic_phy: pointer to USB3 PHY * @phys_ready: flag to indicate that PHYs are ready * @ulpi: pointer to ulpi interface * @ulpi_ready: flag to indicate that ULPI is initialized @@ -1188,11 +1186,8 @@ struct dwc3 { struct usb_phy *usb2_phy; struct usb_phy *usb3_phy; - struct phy *usb2_generic_phy[DWC3_USB2_MAX_PORTS]; - struct phy *usb3_generic_phy[DWC3_USB3_MAX_PORTS]; - - u8 num_usb2_ports; - u8 num_usb3_ports; + struct phy *usb2_generic_phy; + struct phy *usb3_generic_phy; bool phys_ready; @@ -1377,6 +1372,23 @@ struct dwc3 { ANDROID_KABI_RESERVE(4); }; +/** + * struct dwc3_vendor - contains parameters without modifying the format of DWC3 core + * @dwc: contains dwc3 core reference + * @num_usb2_ports: number of USB2 ports + * @num_usb3_ports: number of USB3 ports + * @usb2_generic_phy: pointer to array of USB2 PHYs + * @usb3_generic_phy: pointer to array of USB3 PHYs + */ +struct dwc3_vendor { + struct dwc3 dwc; + u8 num_usb2_ports; + u8 num_usb3_ports; + + struct phy *usb2_generic_phy[DWC3_USB2_MAX_PORTS]; + struct phy *usb3_generic_phy[DWC3_USB3_MAX_PORTS]; +}; + #define INCRX_BURST_MODE 0 #define INCRX_UNDEF_LENGTH_BURST_MODE 1 diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c index 1b235927ca44..68f3eabb145f 100644 --- a/drivers/usb/dwc3/drd.c +++ b/drivers/usb/dwc3/drd.c @@ -332,6 +332,7 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus) int id; int i; unsigned long flags; + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); if (dwc->dr_mode != USB_DR_MODE_OTG) return; @@ -387,9 +388,10 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus) } else { if (dwc->usb2_phy) otg_set_vbus(dwc->usb2_phy->otg, true); - for (i = 0; i < dwc->num_usb2_ports; i++) { - if (dwc->usb2_generic_phy[i]) { - phy_set_mode(dwc->usb2_generic_phy[i], + phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST); + for (i = 1; i < vdwc->num_usb2_ports; i++) { + if (vdwc->usb2_generic_phy[i]) { + phy_set_mode(vdwc->usb2_generic_phy[i], PHY_MODE_USB_HOST); } } @@ -404,8 +406,8 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus) if (dwc->usb2_phy) otg_set_vbus(dwc->usb2_phy->otg, false); - if (dwc->usb2_generic_phy[0]) - phy_set_mode(dwc->usb2_generic_phy[0], + if (dwc->usb2_generic_phy) + phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE); ret = dwc3_gadget_init(dwc); if (ret)