From 8ed9a61b544cb8b1ff968da8c21bbc8332ad6ebb Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Thu, 3 Oct 2024 11:46:36 +0530 Subject: [PATCH] ANDROID: usb: dwc3: core: Introduce vendor struct to deal with ABI breakage Adding commits [1]/[2] to DWC3 driver essentially breaks the ABI as it modifies dwc3 structure by adding phy related variables to it. Fix this by moving the newly added variable to a vendor opts structure. Also to not break boot on pixel devices, use the already present phy structure in dwc for single port controllers and first port of multiport controllers. For the other ports, use the phy structures present in vendor dwc. [1]: https://lore.kernel.org/all/20240420044901.884098-3-quic_kriskura@quicinc.com/ [2]: https://lore.kernel.org/all/20240420044901.884098-5-quic_kriskura@quicinc.com/ Bug: 233985973 Change-Id: I76575bcd9a8f6c49077e4200cbda1c684af427c6 Signed-off-by: Krishna Kurapati --- drivers/usb/dwc3/core.c | 241 +++++++++++++++++++++++++--------------- drivers/usb/dwc3/core.h | 30 +++-- drivers/usb/dwc3/drd.c | 12 +- 3 files changed, 181 insertions(+), 102 deletions(-) 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)