From: Mehmet Fide <[email protected]> "usb start" on a Colibri VF50 or VF61 ends in a data abort and a watchdog reset.
vf_usb_of_to_plat() takes the controller index from dev_seq(), but the usbphy0 and usbphy1 aliases count as "usb" aliases when the uclass numbers its devices, so the two controllers get 2 and 3 and index past the two entries of phy_bases[] and nc_reg_bases[]. usb_oc_config() then writes through an address read from beyond the table. Follow the fsl,usbphy phandle, as ehci-mx6 does, and map the PHY node to the index of the table instead of trusting the sequence number. Signed-off-by: Mehmet Fide <[email protected]> --- Changes in v4: - sent alone before, now patch 1 of the series - reworded the commit message, no code change - the test note moved here: on a Colibri VF50 V1.2A on an Iris carrier, "usb start" brings up the controller instead of resetting the board drivers/usb/host/ehci-vf.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c index 96d1363a76e..32fe05920d0 100644 --- a/drivers/usb/host/ehci-vf.c +++ b/drivers/usb/host/ehci-vf.c @@ -221,8 +221,23 @@ static int vf_usb_of_to_plat(struct udevice *dev) const void *dt_blob = gd->fdt_blob; int node = dev_of_offset(dev); const char *mode; + fdt_addr_t phy_addr; + ofnode phy_node; + int i; - priv->portnr = dev_seq(dev); + phy_node = ofnode_parse_phandle(dev_ofnode(dev), "fsl,usbphy", 0); + if (!ofnode_valid(phy_node)) + return -EINVAL; + + phy_addr = ofnode_get_addr(phy_node); + for (i = 0; i < ARRAY_SIZE(phy_bases); i++) { + if (phy_addr == phy_bases[i]) + break; + } + if (i == ARRAY_SIZE(phy_bases)) + return -EINVAL; + + priv->portnr = i; priv->ehci = dev_read_addr_ptr(dev); mode = fdt_getprop(dt_blob, node, "dr_mode", NULL); -- 2.55.0
