Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: dwc3: core: Refactor PHY logic to support Multiport Controller

Currently the DWC3 driver supports only single port controller
which requires at least one HS PHY and at most one SS PHY.

But the DWC3 USB controller can be connected to multiple ports and
each port can have their own PHYs. Each port of the multiport
controller can either be HS+SS capable or HS only capable
Proper quantification of them is required to modify GUSB2PHYCFG
and GUSB3PIPECTL registers appropriately.

DWC3 multiport controllers are capable to service at most 15 High Speed
PHYs and 4 Supser Speed PHYs. Add support for detecting, obtaining and
configuring PHYs supported by a multiport controller.

Signed-off-by: Krishna Kurapati <quic_kriskura@quicinc.com>
Reviewed-by: Bjorn Andersson <quic_bjorande@quicinc.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
Tested-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20240420044901.884098-5-quic_kriskura@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Krishna Kurapati and committed by
Greg Kroah-Hartman
30a46746 89d7f962

+201 -84
+181 -74
drivers/usb/dwc3/core.c
··· 124 124 int ret; 125 125 u32 reg; 126 126 u32 desired_dr_role; 127 + int i; 127 128 128 129 mutex_lock(&dwc->mutex); 129 130 spin_lock_irqsave(&dwc->lock, flags); ··· 202 201 } else { 203 202 if (dwc->usb2_phy) 204 203 otg_set_vbus(dwc->usb2_phy->otg, true); 205 - phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST); 206 - phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST); 204 + 205 + for (i = 0; i < dwc->num_usb2_ports; i++) 206 + phy_set_mode(dwc->usb2_generic_phy[i], PHY_MODE_USB_HOST); 207 + for (i = 0; i < dwc->num_usb3_ports; i++) 208 + phy_set_mode(dwc->usb3_generic_phy[i], PHY_MODE_USB_HOST); 209 + 207 210 if (dwc->dis_split_quirk) { 208 211 reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); 209 212 reg |= DWC3_GUCTL3_SPLITDISABLE; ··· 222 217 223 218 if (dwc->usb2_phy) 224 219 otg_set_vbus(dwc->usb2_phy->otg, false); 225 - phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE); 226 - phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_DEVICE); 220 + phy_set_mode(dwc->usb2_generic_phy[0], PHY_MODE_USB_DEVICE); 221 + phy_set_mode(dwc->usb3_generic_phy[0], PHY_MODE_USB_DEVICE); 227 222 228 223 ret = dwc3_gadget_init(dwc); 229 224 if (ret) ··· 594 589 return ret; 595 590 } 596 591 597 - /** 598 - * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core 599 - * @dwc: Pointer to our controller context structure 600 - * 601 - * Returns 0 on success. The USB PHY interfaces are configured but not 602 - * initialized. The PHY interfaces and the PHYs get initialized together with 603 - * the core in dwc3_core_init. 604 - */ 605 - static int dwc3_phy_setup(struct dwc3 *dwc) 592 + static int dwc3_ss_phy_setup(struct dwc3 *dwc, int index) 606 593 { 607 594 unsigned int hw_mode; 608 595 u32 reg; 609 596 610 597 hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); 611 598 612 - reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); 599 + reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(index)); 613 600 614 601 /* 615 602 * Make sure UX_EXIT_PX is cleared as that causes issues with some ··· 656 659 if (dwc->dis_del_phy_power_chg_quirk) 657 660 reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE; 658 661 659 - dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); 662 + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(index), reg); 660 663 661 - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); 664 + return 0; 665 + } 666 + 667 + static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index) 668 + { 669 + unsigned int hw_mode; 670 + u32 reg; 671 + 672 + hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); 673 + 674 + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(index)); 662 675 663 676 /* Select the HS PHY interface */ 664 677 switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) { ··· 680 673 } else if (dwc->hsphy_interface && 681 674 !strncmp(dwc->hsphy_interface, "ulpi", 4)) { 682 675 reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI; 683 - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); 676 + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg); 684 677 } else { 685 678 /* Relying on default value. */ 686 679 if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI)) ··· 747 740 if (dwc->ulpi_ext_vbus_drv) 748 741 reg |= DWC3_GUSB2PHYCFG_ULPIEXTVBUSDRV; 749 742 750 - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); 743 + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg); 744 + 745 + return 0; 746 + } 747 + 748 + /** 749 + * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core 750 + * @dwc: Pointer to our controller context structure 751 + * 752 + * Returns 0 on success. The USB PHY interfaces are configured but not 753 + * initialized. The PHY interfaces and the PHYs get initialized together with 754 + * the core in dwc3_core_init. 755 + */ 756 + static int dwc3_phy_setup(struct dwc3 *dwc) 757 + { 758 + int i; 759 + int ret; 760 + 761 + for (i = 0; i < dwc->num_usb3_ports; i++) { 762 + ret = dwc3_ss_phy_setup(dwc, i); 763 + if (ret) 764 + return ret; 765 + } 766 + 767 + for (i = 0; i < dwc->num_usb2_ports; i++) { 768 + ret = dwc3_hs_phy_setup(dwc, i); 769 + if (ret) 770 + return ret; 771 + } 751 772 752 773 return 0; 753 774 } ··· 783 748 static int dwc3_phy_init(struct dwc3 *dwc) 784 749 { 785 750 int ret; 751 + int i; 752 + int j; 786 753 787 754 usb_phy_init(dwc->usb2_phy); 788 755 usb_phy_init(dwc->usb3_phy); 789 756 790 - ret = phy_init(dwc->usb2_generic_phy); 791 - if (ret < 0) 792 - goto err_shutdown_usb3_phy; 757 + for (i = 0; i < dwc->num_usb2_ports; i++) { 758 + ret = phy_init(dwc->usb2_generic_phy[i]); 759 + if (ret < 0) 760 + goto err_exit_usb2_phy; 761 + } 793 762 794 - ret = phy_init(dwc->usb3_generic_phy); 795 - if (ret < 0) 796 - goto err_exit_usb2_phy; 763 + for (j = 0; j < dwc->num_usb3_ports; j++) { 764 + ret = phy_init(dwc->usb3_generic_phy[j]); 765 + if (ret < 0) 766 + goto err_exit_usb3_phy; 767 + } 797 768 798 769 return 0; 799 770 771 + err_exit_usb3_phy: 772 + while (--j >= 0) 773 + phy_exit(dwc->usb3_generic_phy[j]); 774 + 800 775 err_exit_usb2_phy: 801 - phy_exit(dwc->usb2_generic_phy); 802 - err_shutdown_usb3_phy: 776 + while (--i >= 0) 777 + phy_exit(dwc->usb2_generic_phy[i]); 778 + 803 779 usb_phy_shutdown(dwc->usb3_phy); 804 780 usb_phy_shutdown(dwc->usb2_phy); 805 781 ··· 819 773 820 774 static void dwc3_phy_exit(struct dwc3 *dwc) 821 775 { 822 - phy_exit(dwc->usb3_generic_phy); 823 - phy_exit(dwc->usb2_generic_phy); 776 + int i; 777 + 778 + for (i = 0; i < dwc->num_usb3_ports; i++) 779 + phy_exit(dwc->usb3_generic_phy[i]); 780 + 781 + for (i = 0; i < dwc->num_usb2_ports; i++) 782 + phy_exit(dwc->usb2_generic_phy[i]); 824 783 825 784 usb_phy_shutdown(dwc->usb3_phy); 826 785 usb_phy_shutdown(dwc->usb2_phy); ··· 834 783 static int dwc3_phy_power_on(struct dwc3 *dwc) 835 784 { 836 785 int ret; 786 + int i; 787 + int j; 837 788 838 789 usb_phy_set_suspend(dwc->usb2_phy, 0); 839 790 usb_phy_set_suspend(dwc->usb3_phy, 0); 840 791 841 - ret = phy_power_on(dwc->usb2_generic_phy); 842 - if (ret < 0) 843 - goto err_suspend_usb3_phy; 792 + for (i = 0; i < dwc->num_usb2_ports; i++) { 793 + ret = phy_power_on(dwc->usb2_generic_phy[i]); 794 + if (ret < 0) 795 + goto err_power_off_usb2_phy; 796 + } 844 797 845 - ret = phy_power_on(dwc->usb3_generic_phy); 846 - if (ret < 0) 847 - goto err_power_off_usb2_phy; 798 + for (j = 0; j < dwc->num_usb3_ports; j++) { 799 + ret = phy_power_on(dwc->usb3_generic_phy[j]); 800 + if (ret < 0) 801 + goto err_power_off_usb3_phy; 802 + } 848 803 849 804 return 0; 850 805 806 + err_power_off_usb3_phy: 807 + while (--j >= 0) 808 + phy_power_off(dwc->usb3_generic_phy[j]); 809 + 851 810 err_power_off_usb2_phy: 852 - phy_power_off(dwc->usb2_generic_phy); 853 - err_suspend_usb3_phy: 811 + while (--i >= 0) 812 + phy_power_off(dwc->usb2_generic_phy[i]); 813 + 854 814 usb_phy_set_suspend(dwc->usb3_phy, 1); 855 815 usb_phy_set_suspend(dwc->usb2_phy, 1); 856 816 ··· 870 808 871 809 static void dwc3_phy_power_off(struct dwc3 *dwc) 872 810 { 873 - phy_power_off(dwc->usb3_generic_phy); 874 - phy_power_off(dwc->usb2_generic_phy); 811 + int i; 812 + 813 + for (i = 0; i < dwc->num_usb3_ports; i++) 814 + phy_power_off(dwc->usb3_generic_phy[i]); 815 + 816 + for (i = 0; i < dwc->num_usb2_ports; i++) 817 + phy_power_off(dwc->usb2_generic_phy[i]); 875 818 876 819 usb_phy_set_suspend(dwc->usb3_phy, 1); 877 820 usb_phy_set_suspend(dwc->usb2_phy, 1); ··· 1268 1201 unsigned int hw_mode; 1269 1202 u32 reg; 1270 1203 int ret; 1204 + int i; 1271 1205 1272 1206 hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); 1273 1207 ··· 1312 1244 if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD && 1313 1245 !DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) { 1314 1246 if (!dwc->dis_u3_susphy_quirk) { 1315 - reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); 1316 - reg |= DWC3_GUSB3PIPECTL_SUSPHY; 1317 - dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); 1247 + for (i = 0; i < dwc->num_usb3_ports; i++) { 1248 + reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(i)); 1249 + reg |= DWC3_GUSB3PIPECTL_SUSPHY; 1250 + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(i), reg); 1251 + } 1318 1252 } 1319 1253 1320 1254 if (!dwc->dis_u2_susphy_quirk) { 1321 - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); 1322 - reg |= DWC3_GUSB2PHYCFG_SUSPHY; 1323 - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); 1255 + for (i = 0; i < dwc->num_usb2_ports; i++) { 1256 + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i)); 1257 + reg |= DWC3_GUSB2PHYCFG_SUSPHY; 1258 + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg); 1259 + } 1324 1260 } 1325 1261 } 1326 1262 ··· 1447 1375 { 1448 1376 struct device *dev = dwc->dev; 1449 1377 struct device_node *node = dev->of_node; 1378 + char phy_name[9]; 1450 1379 int ret; 1380 + int i; 1451 1381 1452 1382 if (node) { 1453 1383 dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); ··· 1475 1401 return dev_err_probe(dev, ret, "no usb3 phy configured\n"); 1476 1402 } 1477 1403 1478 - dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy"); 1479 - if (IS_ERR(dwc->usb2_generic_phy)) { 1480 - ret = PTR_ERR(dwc->usb2_generic_phy); 1481 - if (ret == -ENOSYS || ret == -ENODEV) 1482 - dwc->usb2_generic_phy = NULL; 1404 + for (i = 0; i < dwc->num_usb2_ports; i++) { 1405 + if (dwc->num_usb2_ports == 1) 1406 + snprintf(phy_name, sizeof(phy_name), "usb2-phy"); 1483 1407 else 1484 - return dev_err_probe(dev, ret, "no usb2 phy configured\n"); 1408 + snprintf(phy_name, sizeof(phy_name), "usb2-%d", i); 1409 + 1410 + dwc->usb2_generic_phy[i] = devm_phy_get(dev, phy_name); 1411 + if (IS_ERR(dwc->usb2_generic_phy[i])) { 1412 + ret = PTR_ERR(dwc->usb2_generic_phy[i]); 1413 + if (ret == -ENOSYS || ret == -ENODEV) 1414 + dwc->usb2_generic_phy[i] = NULL; 1415 + else 1416 + return dev_err_probe(dev, ret, "failed to lookup phy %s\n", 1417 + phy_name); 1418 + } 1485 1419 } 1486 1420 1487 - dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy"); 1488 - if (IS_ERR(dwc->usb3_generic_phy)) { 1489 - ret = PTR_ERR(dwc->usb3_generic_phy); 1490 - if (ret == -ENOSYS || ret == -ENODEV) 1491 - dwc->usb3_generic_phy = NULL; 1421 + for (i = 0; i < dwc->num_usb3_ports; i++) { 1422 + if (dwc->num_usb3_ports == 1) 1423 + snprintf(phy_name, sizeof(phy_name), "usb3-phy"); 1492 1424 else 1493 - return dev_err_probe(dev, ret, "no usb3 phy configured\n"); 1425 + snprintf(phy_name, sizeof(phy_name), "usb3-%d", i); 1426 + 1427 + dwc->usb3_generic_phy[i] = devm_phy_get(dev, phy_name); 1428 + if (IS_ERR(dwc->usb3_generic_phy[i])) { 1429 + ret = PTR_ERR(dwc->usb3_generic_phy[i]); 1430 + if (ret == -ENOSYS || ret == -ENODEV) 1431 + dwc->usb3_generic_phy[i] = NULL; 1432 + else 1433 + return dev_err_probe(dev, ret, "failed to lookup phy %s\n", 1434 + phy_name); 1435 + } 1494 1436 } 1495 1437 1496 1438 return 0; ··· 1516 1426 { 1517 1427 struct device *dev = dwc->dev; 1518 1428 int ret; 1429 + int i; 1519 1430 1520 1431 switch (dwc->dr_mode) { 1521 1432 case USB_DR_MODE_PERIPHERAL: ··· 1524 1433 1525 1434 if (dwc->usb2_phy) 1526 1435 otg_set_vbus(dwc->usb2_phy->otg, false); 1527 - phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE); 1528 - phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_DEVICE); 1436 + phy_set_mode(dwc->usb2_generic_phy[0], PHY_MODE_USB_DEVICE); 1437 + phy_set_mode(dwc->usb3_generic_phy[0], PHY_MODE_USB_DEVICE); 1529 1438 1530 1439 ret = dwc3_gadget_init(dwc); 1531 1440 if (ret) ··· 1536 1445 1537 1446 if (dwc->usb2_phy) 1538 1447 otg_set_vbus(dwc->usb2_phy->otg, true); 1539 - phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST); 1540 - phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST); 1448 + for (i = 0; i < dwc->num_usb2_ports; i++) 1449 + phy_set_mode(dwc->usb2_generic_phy[i], PHY_MODE_USB_HOST); 1450 + for (i = 0; i < dwc->num_usb3_ports; i++) 1451 + phy_set_mode(dwc->usb3_generic_phy[i], PHY_MODE_USB_HOST); 1541 1452 1542 1453 ret = dwc3_host_init(dwc); 1543 1454 if (ret) ··· 2033 1940 2034 1941 iounmap(base); 2035 1942 1943 + if (dwc->num_usb2_ports > DWC3_USB2_MAX_PORTS || 1944 + dwc->num_usb3_ports > DWC3_USB3_MAX_PORTS) 1945 + return -EINVAL; 1946 + 2036 1947 return 0; 2037 1948 } 2038 1949 ··· 2274 2177 { 2275 2178 unsigned long flags; 2276 2179 u32 reg; 2180 + int i; 2277 2181 2278 2182 switch (dwc->current_dr_role) { 2279 2183 case DWC3_GCTL_PRTCAP_DEVICE: ··· 2293 2195 /* Let controller to suspend HSPHY before PHY driver suspends */ 2294 2196 if (dwc->dis_u2_susphy_quirk || 2295 2197 dwc->dis_enblslpm_quirk) { 2296 - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); 2297 - reg |= DWC3_GUSB2PHYCFG_ENBLSLPM | 2298 - DWC3_GUSB2PHYCFG_SUSPHY; 2299 - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); 2198 + for (i = 0; i < dwc->num_usb2_ports; i++) { 2199 + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i)); 2200 + reg |= DWC3_GUSB2PHYCFG_ENBLSLPM | 2201 + DWC3_GUSB2PHYCFG_SUSPHY; 2202 + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg); 2203 + } 2300 2204 2301 2205 /* Give some time for USB2 PHY to suspend */ 2302 2206 usleep_range(5000, 6000); 2303 2207 } 2304 2208 2305 - phy_pm_runtime_put_sync(dwc->usb2_generic_phy); 2306 - phy_pm_runtime_put_sync(dwc->usb3_generic_phy); 2209 + for (i = 0; i < dwc->num_usb2_ports; i++) 2210 + phy_pm_runtime_put_sync(dwc->usb2_generic_phy[i]); 2211 + for (i = 0; i < dwc->num_usb3_ports; i++) 2212 + phy_pm_runtime_put_sync(dwc->usb3_generic_phy[i]); 2307 2213 break; 2308 2214 case DWC3_GCTL_PRTCAP_OTG: 2309 2215 /* do nothing during runtime_suspend */ ··· 2337 2235 unsigned long flags; 2338 2236 int ret; 2339 2237 u32 reg; 2238 + int i; 2340 2239 2341 2240 switch (dwc->current_dr_role) { 2342 2241 case DWC3_GCTL_PRTCAP_DEVICE: ··· 2357 2254 break; 2358 2255 } 2359 2256 /* Restore GUSB2PHYCFG bits that were modified in suspend */ 2360 - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); 2361 - if (dwc->dis_u2_susphy_quirk) 2362 - reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; 2257 + for (i = 0; i < dwc->num_usb2_ports; i++) { 2258 + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i)); 2259 + if (dwc->dis_u2_susphy_quirk) 2260 + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; 2363 2261 2364 - if (dwc->dis_enblslpm_quirk) 2365 - reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; 2262 + if (dwc->dis_enblslpm_quirk) 2263 + reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; 2366 2264 2367 - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); 2265 + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg); 2266 + } 2368 2267 2369 - phy_pm_runtime_get_sync(dwc->usb2_generic_phy); 2370 - phy_pm_runtime_get_sync(dwc->usb3_generic_phy); 2268 + for (i = 0; i < dwc->num_usb2_ports; i++) 2269 + phy_pm_runtime_get_sync(dwc->usb2_generic_phy[i]); 2270 + for (i = 0; i < dwc->num_usb3_ports; i++) 2271 + phy_pm_runtime_get_sync(dwc->usb3_generic_phy[i]); 2371 2272 break; 2372 2273 case DWC3_GCTL_PRTCAP_OTG: 2373 2274 /* nothing to do on runtime_resume */
+11 -4
drivers/usb/dwc3/core.h
··· 33 33 34 34 #include <linux/power_supply.h> 35 35 36 + /* 37 + * DWC3 Multiport controllers support up to 15 High-Speed PHYs 38 + * and 4 SuperSpeed PHYs. 39 + */ 40 + #define DWC3_USB2_MAX_PORTS 15 41 + #define DWC3_USB3_MAX_PORTS 4 42 + 36 43 #define DWC3_MSG_MAX 500 37 44 38 45 /* Global constants */ ··· 1044 1037 * @usb_psy: pointer to power supply interface. 1045 1038 * @usb2_phy: pointer to USB2 PHY 1046 1039 * @usb3_phy: pointer to USB3 PHY 1047 - * @usb2_generic_phy: pointer to USB2 PHY 1048 - * @usb3_generic_phy: pointer to USB3 PHY 1040 + * @usb2_generic_phy: pointer to array of USB2 PHYs 1041 + * @usb3_generic_phy: pointer to array of USB3 PHYs 1049 1042 * @num_usb2_ports: number of USB2 ports 1050 1043 * @num_usb3_ports: number of USB3 ports 1051 1044 * @phys_ready: flag to indicate that PHYs are ready ··· 1193 1186 struct usb_phy *usb2_phy; 1194 1187 struct usb_phy *usb3_phy; 1195 1188 1196 - struct phy *usb2_generic_phy; 1197 - struct phy *usb3_generic_phy; 1189 + struct phy *usb2_generic_phy[DWC3_USB2_MAX_PORTS]; 1190 + struct phy *usb3_generic_phy[DWC3_USB3_MAX_PORTS]; 1198 1191 1199 1192 u8 num_usb2_ports; 1200 1193 u8 num_usb3_ports;
+9 -6
drivers/usb/dwc3/drd.c
··· 331 331 u32 reg; 332 332 int id; 333 333 unsigned long flags; 334 + int i; 334 335 335 336 if (dwc->dr_mode != USB_DR_MODE_OTG) 336 337 return; ··· 387 386 } else { 388 387 if (dwc->usb2_phy) 389 388 otg_set_vbus(dwc->usb2_phy->otg, true); 390 - if (dwc->usb2_generic_phy) 391 - phy_set_mode(dwc->usb2_generic_phy, 392 - PHY_MODE_USB_HOST); 389 + for (i = 0; i < dwc->num_usb2_ports; i++) { 390 + if (dwc->usb2_generic_phy[i]) { 391 + phy_set_mode(dwc->usb2_generic_phy[i], 392 + PHY_MODE_USB_HOST); 393 + } 394 + } 393 395 } 394 396 break; 395 397 case DWC3_OTG_ROLE_DEVICE: ··· 404 400 405 401 if (dwc->usb2_phy) 406 402 otg_set_vbus(dwc->usb2_phy->otg, false); 407 - if (dwc->usb2_generic_phy) 408 - phy_set_mode(dwc->usb2_generic_phy, 409 - PHY_MODE_USB_DEVICE); 403 + if (dwc->usb2_generic_phy[0]) 404 + phy_set_mode(dwc->usb2_generic_phy[0], PHY_MODE_USB_DEVICE); 410 405 ret = dwc3_gadget_init(dwc); 411 406 if (ret) 412 407 dev_err(dwc->dev, "failed to initialize peripheral\n");