[PATCH 2/2] usb: ehci-vf: enable the vbus supply of the port
Mehmet Fide <[email protected]>
| Newsgroups | org.u-boot-project.lists.u-boot |
|---|---|
| Message-ID | <[email protected]> |
From: Mehmet Fide <[email protected]> The driver never looks at the vbus-supply of its port, so on a board where VBUS is switched by a regulator, as it is on the Colibri VF50 and VF61 carriers, the port stays unpowered and no device is ever found. Take the regulator the way ehci-mx6 does: look it up in probe, enable it in host mode and disable it in device mode when the controller comes up, and turn it off again when the controller is removed. Tested on a Colibri VF50 V1.2A on an Iris carrier, U-Boot 2026.07 from NAND, with a USB stick in the host port: Colibri VFxx # usb start Bus usb@400b4000: 2 USB Device(s) found scanning usb for storage devices... 1 Storage Device(s) found Colibri VFxx # usb storage Device 0: Vendor: SanDisk Rev: DL17 Prod: SanDisk 3.2 Gen1 Type: Removable Hard Disk Capacity: 61584.0 MB = 60.1 GB (126124032 x 512) Reading the partition table and blocks off the stick works. Signed-off-by: Mehmet Fide <[email protected]> --- drivers/usb/host/ehci-vf.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c index fb305569a15..4ac7f8bf53f 100644 --- a/drivers/usb/host/ehci-vf.c +++ b/drivers/usb/host/ehci-vf.c @@ -21,6 +21,7 @@ #include <asm/mach-imx/regs-usbphy.h> #include <linux/delay.h> #include <usb/ehci-ci.h> +#include <power/regulator.h> #include <linux/libfdt.h> #include <fdtdec.h> @@ -54,6 +55,7 @@ struct ehci_vf_priv_data { struct anadig_reg __iomem *anatop_addr; void __iomem *phy_addr; void __iomem *misc_addr; + struct udevice *vbus_supply; int portnr; }; @@ -144,6 +146,16 @@ static int ehci_vf_common_init(struct ehci_vf_priv_data *priv) usb_internal_phy_clock_gate(priv->phy_addr); usb_phy_enable(priv->phy_addr, priv->ehci); + if (CONFIG_IS_ENABLED(DM_REGULATOR) && priv->vbus_supply) { + ret = regulator_set_enable_if_allowed(priv->vbus_supply, + priv->init_type != + USB_INIT_DEVICE); + if (ret && ret != -ENOSYS) { + printf("Error enabling VBUS supply (ret=%i)\n", ret); + return ret; + } + } + return 0; } @@ -288,6 +300,13 @@ static int ehci_usb_probe(struct udevice *dev) struct ehci_hcor *hcor; int ret; + if (CONFIG_IS_ENABLED(DM_REGULATOR)) { + ret = device_get_supply_regulator(dev, "vbus-supply", + &priv->vbus_supply); + if (ret) + debug("%s: no vbus supply\n", dev->name); + } + ret = ehci_vf_common_init(priv); if (ret) return ret; @@ -315,12 +334,22 @@ static const struct udevice_id vf_usb_ids[] = { { } }; +static int ehci_usb_remove(struct udevice *dev) +{ + struct ehci_vf_priv_data *priv = dev_get_priv(dev); + + if (CONFIG_IS_ENABLED(DM_REGULATOR) && priv->vbus_supply) + regulator_set_enable_if_allowed(priv->vbus_supply, false); + + return ehci_deregister(dev); +} + U_BOOT_DRIVER(ehci_vf) = { .name = "ehci_vf", .id = UCLASS_USB, .of_match = vf_usb_ids, .probe = ehci_usb_probe, - .remove = ehci_deregister, + .remove = ehci_usb_remove, .ops = &ehci_usb_ops, .of_to_plat = vf_usb_of_to_plat, .plat_auto = sizeof(struct usb_plat), -- 2.54.0