From fcb670b794c9839c026757bf2d5cd564323ce199 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 19 Sep 2022 21:19:23 +0200 Subject: [PATCH 1/7] usb: Add missing guard around env_get() in usb_hub The env_get() might be undefined in case ENV_SUPPORT is disabled, which may happen e.g. in SPL. Add missing ifdef guard around the env_get() to prevent build failure. Signed-off-by: Marek Vasut Tested-by: Fabio Estevam --- common/usb_hub.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/usb_hub.c b/common/usb_hub.c index d73638950b9..95f1449b5cb 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -168,7 +168,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub) int i; struct usb_device *dev; unsigned pgood_delay = hub->desc.bPwrOn2PwrGood * 2; - const char *env; + const char __maybe_unused *env; dev = hub->pusb_dev; @@ -193,10 +193,12 @@ static void usb_hub_power_on(struct usb_hub_device *hub) * but allow this time to be increased via env variable as some * devices break the spec and require longer warm-up times */ +#if CONFIG_IS_ENABLED(ENV_SUPPORT) env = env_get("usb_pgood_delay"); if (env) pgood_delay = max(pgood_delay, (unsigned)simple_strtol(env, NULL, 0)); +#endif debug("pgood_delay=%dms\n", pgood_delay); /* From 7cc1af902dfad290ab39b0ee52128b18d83a151a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 23 Aug 2022 19:06:51 +0200 Subject: [PATCH 2/7] usb: gadget: Clean up Makefile ifdeffery Take the USB_ETHER ifdef block apart and make use of obj-$(VAR) instead to include the source files in build. The duplicate CI_UDC entry is now removed, the USB_DEVICE ifdef is now reduced to core.o ep.o addition, the ether.o can be conditionally compiled in using USB_ETHER. No functional change. Signed-off-by: Marek Vasut Reviewed-by: Patrice Chotard --- drivers/usb/gadget/Makefile | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index dd09ee01959..9c04403da30 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_USB_GADGET_DWC2_OTG) += dwc2_udc_otg.o obj-$(CONFIG_USB_GADGET_DWC2_OTG_PHY) += dwc2_udc_otg_phy.o obj-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o obj-$(CONFIG_USB_GADGET_MAX3420) += max3420_udc.o -obj-$(CONFIG_CI_UDC) += ci_udc.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_USB_GADGET_DOWNLOAD) += g_dnl.o obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o @@ -33,14 +32,12 @@ obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o obj-$(CONFIG_USB_FUNCTION_ACM) += f_acm.o endif endif -ifdef CONFIG_USB_ETHER -obj-y += ether.o + +obj-$(CONFIG_CI_UDC) += ci_udc.o + +obj-$(CONFIG_USB_ETHER) += ether.o obj-$(CONFIG_USB_ETH_RNDIS) += rndis.o -obj-$(CONFIG_CI_UDC) += ci_udc.o -else + # Devices not related to the new gadget layer depend on CONFIG_USB_DEVICE -ifdef CONFIG_USB_DEVICE -obj-y += core.o -obj-y += ep0.o -endif -endif +# This is really only N900 and USBTTY now. +obj-$(CONFIG_USB_DEVICE) += core.o ep0.o From 84e561407a5f62a8746dcf8f920e4682690435a0 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 6 Sep 2022 08:15:26 +0200 Subject: [PATCH 3/7] phy: Add generic_{setup,shutdown}_phy() helpers In drivers usb/host/{ehci,ohci}-generic.c, {ehci,ohci}_setup_phy() and {ehci,ohci}_shutdown_phy() shares 95% of common code. Factorize this code in new generic_{setup,shudown}_phy() functions. Signed-off-by: Patrice Chotard Cc: Marek Vasut Cc: Simon Glass --- drivers/phy/phy-uclass.c | 42 ++++++++++++++++++++++++++++++++++++++++ include/generic-phy.h | 30 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c index 8b84da3ce0d..3fef5135a9c 100644 --- a/drivers/phy/phy-uclass.c +++ b/drivers/phy/phy-uclass.c @@ -455,6 +455,48 @@ int generic_phy_power_off_bulk(struct phy_bulk *bulk) return ret; } +int generic_setup_phy(struct udevice *dev, struct phy *phy, int index) +{ + int ret = 0; + + if (!phy) + return 0; + + ret = generic_phy_get_by_index(dev, index, phy); + if (ret) { + if (ret != -ENOENT) + return ret; + } else { + ret = generic_phy_init(phy); + if (ret) + return ret; + + ret = generic_phy_power_on(phy); + if (ret) + ret = generic_phy_exit(phy); + } + + return ret; +} + +int generic_shutdown_phy(struct phy *phy) +{ + int ret = 0; + + if (!phy) + return 0; + + if (generic_phy_valid(phy)) { + ret = generic_phy_power_off(phy); + if (ret) + return ret; + + ret = generic_phy_exit(phy); + } + + return ret; +} + UCLASS_DRIVER(phy) = { .id = UCLASS_PHY, .name = "phy", diff --git a/include/generic-phy.h b/include/generic-phy.h index d40ce589b64..f8eddeff67a 100644 --- a/include/generic-phy.h +++ b/include/generic-phy.h @@ -342,6 +342,26 @@ int generic_phy_power_on_bulk(struct phy_bulk *bulk); */ int generic_phy_power_off_bulk(struct phy_bulk *bulk); +/** + * generic_setup_phy() - Get, initialize and power on phy. + * + * @dev: The consumer device. + * @phy: A pointer to the PHY port + * @index: The index in the list of available PHYs + * + * Return: 0 if OK, or negative error code. + */ +int generic_setup_phy(struct udevice *dev, struct phy *phy, int index); + +/** + * generic_shutdown_phy() - Power off and de-initialize phy. + * + * @phy: A pointer to the PHY port. + * + * Return: 0 if OK, or negative error code. + */ +int generic_shutdown_phy(struct phy *phy); + #else /* CONFIG_PHY */ static inline int generic_phy_init(struct phy *phy) @@ -407,6 +427,16 @@ static inline int generic_phy_power_off_bulk(struct phy_bulk *bulk) return 0; } +static inline int generic_setup_phy(struct udevice *dev, struct phy *phy, int index) +{ + return 0; +} + +static inline int generic_shutdown_phy(struct phy *phy) +{ + return 0; +} + #endif /* CONFIG_PHY */ /** From 10005004db73f83a736e6dbc3f8440c9db3a9fd6 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 6 Sep 2022 08:15:27 +0200 Subject: [PATCH 4/7] usb: ohci: Make usage of generic_{setup,shutdown}_phy() helpers Replace ohci_setup_phy() and ohci_shutdown_phy () by respectively generic_setup_phy() and generic_shutdown_phy(). Signed-off-by: Patrice Chotard Cc: Marek Vasut Cc: Simon Glass --- drivers/usb/host/ohci-generic.c | 56 ++------------------------------- 1 file changed, 3 insertions(+), 53 deletions(-) diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c index 5d23058aaf6..2d8d38ce9a4 100644 --- a/drivers/usb/host/ohci-generic.c +++ b/drivers/usb/host/ohci-generic.c @@ -23,56 +23,6 @@ struct generic_ohci { int reset_count; /* number of reset in reset list */ }; -static int ohci_setup_phy(struct udevice *dev, int index) -{ - struct generic_ohci *priv = dev_get_priv(dev); - int ret; - - ret = generic_phy_get_by_index(dev, index, &priv->phy); - if (ret) { - if (ret != -ENOENT) { - dev_err(dev, "failed to get usb phy\n"); - return ret; - } - } else { - ret = generic_phy_init(&priv->phy); - if (ret) { - dev_dbg(dev, "failed to init usb phy\n"); - return ret; - } - - ret = generic_phy_power_on(&priv->phy); - if (ret) { - dev_dbg(dev, "failed to power on usb phy\n"); - return generic_phy_exit(&priv->phy); - } - } - - return 0; -} - -static int ohci_shutdown_phy(struct udevice *dev) -{ - struct generic_ohci *priv = dev_get_priv(dev); - int ret = 0; - - if (generic_phy_valid(&priv->phy)) { - ret = generic_phy_power_off(&priv->phy); - if (ret) { - dev_dbg(dev, "failed to power off usb phy\n"); - return ret; - } - - ret = generic_phy_exit(&priv->phy); - if (ret) { - dev_dbg(dev, "failed to power off usb phy\n"); - return ret; - } - } - - return 0; -} - static int ohci_usb_probe(struct udevice *dev) { struct ohci_regs *regs = dev_read_addr_ptr(dev); @@ -135,7 +85,7 @@ static int ohci_usb_probe(struct udevice *dev) goto clk_err; } - err = ohci_setup_phy(dev, 0); + err = generic_setup_phy(dev, &priv->phy, 0); if (err) goto reset_err; @@ -146,7 +96,7 @@ static int ohci_usb_probe(struct udevice *dev) return 0; phy_err: - ret = ohci_shutdown_phy(dev); + ret = generic_shutdown_phy(&priv->phy); if (ret) dev_err(dev, "failed to shutdown usb phy\n"); @@ -171,7 +121,7 @@ static int ohci_usb_remove(struct udevice *dev) if (ret) return ret; - ret = ohci_shutdown_phy(dev); + ret = generic_shutdown_phy(&priv->phy); if (ret) return ret; From 083f8aa978a837542ffa53e5247d36d2b1734e44 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 6 Sep 2022 08:15:28 +0200 Subject: [PATCH 5/7] usb: ehci: Make usage of generic_{setup,shutdown}_phy() helpers Replace ehci_setup_phy() and ehci_shutdown_phy () by respectively generic_setup_phy() and generic_shutdown_phy(). Signed-off-by: Patrice Chotard Cc: Marek Vasut Cc: Simon Glass --- drivers/usb/host/ehci-generic.c | 6 +++--- drivers/usb/host/ehci-msm.c | 4 ++-- drivers/usb/host/ehci-mx6.c | 6 +++--- drivers/usb/host/ehci-pci.c | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c index 75c73bfe4e8..a765a307a32 100644 --- a/drivers/usb/host/ehci-generic.c +++ b/drivers/usb/host/ehci-generic.c @@ -96,7 +96,7 @@ static int ehci_usb_probe(struct udevice *dev) if (err) goto reset_err; - err = ehci_setup_phy(dev, &priv->phy, 0); + err = generic_setup_phy(dev, &priv->phy, 0); if (err) goto regulator_err; @@ -111,7 +111,7 @@ static int ehci_usb_probe(struct udevice *dev) return 0; phy_err: - ret = ehci_shutdown_phy(dev, &priv->phy); + ret = generic_shutdown_phy(&priv->phy); if (ret) dev_err(dev, "failed to shutdown usb phy (ret=%d)\n", ret); @@ -141,7 +141,7 @@ static int ehci_usb_remove(struct udevice *dev) if (ret) return ret; - ret = ehci_shutdown_phy(dev, &priv->phy); + ret = generic_shutdown_phy(&priv->phy); if (ret) return ret; diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index d160cf019d3..dd0d153500c 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -56,7 +56,7 @@ static int ehci_usb_probe(struct udevice *dev) hcor = (struct ehci_hcor *)((phys_addr_t)hccr + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase))); - ret = ehci_setup_phy(dev, &p->phy, 0); + ret = generic_setup_phy(dev, &p->phy, 0); if (ret) return ret; @@ -81,7 +81,7 @@ static int ehci_usb_remove(struct udevice *dev) /* Stop controller. */ clrbits_le32(&ehci->usbcmd, CMD_RUN); - ret = ehci_shutdown_phy(dev, &p->phy); + ret = generic_shutdown_phy(&p->phy); if (ret) return ret; diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index e30449b55e4..fa2ca2a1d91 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -726,7 +726,7 @@ static int ehci_usb_probe(struct udevice *dev) mdelay(10); #if defined(CONFIG_PHY) - ret = ehci_setup_phy(dev, &priv->phy, 0); + ret = generic_setup_phy(dev, &priv->phy, 0); if (ret) goto err_regulator; #endif @@ -743,7 +743,7 @@ static int ehci_usb_probe(struct udevice *dev) err_phy: #if defined(CONFIG_PHY) - ehci_shutdown_phy(dev, &priv->phy); + generic_shutdown_phy(&priv->phy); err_regulator: #endif #if CONFIG_IS_ENABLED(DM_REGULATOR) @@ -767,7 +767,7 @@ int ehci_usb_remove(struct udevice *dev) ehci_deregister(dev); #if defined(CONFIG_PHY) - ehci_shutdown_phy(dev, &priv->phy); + generic_shutdown_phy(&priv->phy); #endif #if CONFIG_IS_ENABLED(DM_REGULATOR) diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 1ab306147fa..e98ab312618 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -31,7 +31,7 @@ static int ehci_pci_init(struct udevice *dev, struct ehci_hccr **ret_hccr, int ret; u32 cmd; - ret = ehci_setup_phy(dev, &priv->phy, 0); + ret = generic_setup_phy(dev, &priv->phy, 0); if (ret) return ret; @@ -149,7 +149,7 @@ static int ehci_pci_remove(struct udevice *dev) if (ret) return ret; - return ehci_shutdown_phy(dev, &priv->phy); + return generic_shutdown_phy(&priv->phy); } static const struct udevice_id ehci_pci_ids[] = { From 75341e9c16aa10929a1616060a3b565ecf6e1418 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 6 Sep 2022 08:15:29 +0200 Subject: [PATCH 6/7] usb: ehci: Remove unused ehci_{setup,shutdown}_phy() helpers Remove unused ehci_{setup,shutdown}_phy() helpers now replaced by generic_{setup,shutdown}_phy(). Signed-off-by: Patrice Chotard Cc: Marek Vasut Cc: Simon Glass --- drivers/usb/host/ehci-hcd.c | 66 ------------------------------------- drivers/usb/host/ehci.h | 4 --- 2 files changed, 70 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index d30f2a0d13b..9139d61dd0c 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1767,69 +1767,3 @@ struct dm_usb_ops ehci_usb_ops = { }; #endif - -#ifdef CONFIG_PHY -int ehci_setup_phy(struct udevice *dev, struct phy *phy, int index) -{ - int ret; - - if (!phy) - return 0; - - ret = generic_phy_get_by_index(dev, index, phy); - if (ret) { - if (ret != -ENOENT) { - dev_err(dev, "failed to get usb phy\n"); - return ret; - } - } else { - ret = generic_phy_init(phy); - if (ret) { - dev_dbg(dev, "failed to init usb phy\n"); - return ret; - } - - ret = generic_phy_power_on(phy); - if (ret) { - dev_dbg(dev, "failed to power on usb phy\n"); - return generic_phy_exit(phy); - } - } - - return 0; -} - -int ehci_shutdown_phy(struct udevice *dev, struct phy *phy) -{ - int ret = 0; - - if (!phy) - return 0; - - if (generic_phy_valid(phy)) { - ret = generic_phy_power_off(phy); - if (ret) { - dev_dbg(dev, "failed to power off usb phy\n"); - return ret; - } - - ret = generic_phy_exit(phy); - if (ret) { - dev_dbg(dev, "failed to power off usb phy\n"); - return ret; - } - } - - return 0; -} -#else -int ehci_setup_phy(struct udevice *dev, struct phy *phy, int index) -{ - return 0; -} - -int ehci_shutdown_phy(struct udevice *dev, struct phy *phy) -{ - return 0; -} -#endif diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 5170044a3ae..5770d35b464 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -295,9 +295,5 @@ int ehci_register(struct udevice *dev, struct ehci_hccr *hccr, int ehci_deregister(struct udevice *dev); extern struct dm_usb_ops ehci_usb_ops; -/* EHCI PHY functions */ -int ehci_setup_phy(struct udevice *dev, struct phy *phy, int index); -int ehci_shutdown_phy(struct udevice *dev, struct phy *phy); - #include #endif /* USB_EHCI_H */ From 5f7e01e9d5d8005e9a8fbbdf8a05dfd63a5e5f04 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Fri, 7 Oct 2022 11:38:22 +0200 Subject: [PATCH 7/7] usb: gadget: fastboot: detach usb on reboot commands When host issues "fastboot reboot fastboot", it's expected that the board drops the USB connection before resetting. On some boards, such as Khadas VIM3L and SEI610, this is not the case. We observe the following error: $ fastboot reboot fastboot Rebooting into fastboot OKAY [ 0.004s] fastboot: error: Failed to boot into userspace fastboot; one or more components might be unbootable. This does not happen when we use the RST button on the board. It can be reproduced in linux with: # echo b > /proc/sysrq-trigger In this case, we hit a undefined hardware behavior, where D+ and D- are in an unknown state. Therefore the host can't detect usb disconnection. Make sure we always call usb_gadget_release() when a "fastboot reboot" command is issued. Note: usb_gadget_release() should be called before g_dnl_unregister() because g_dnl_unregister() triggers a complete() call on each endpoint (thus calling do_reset()). Signed-off-by: Mattijs Korpershoek --- cmd/fastboot.c | 2 +- drivers/usb/gadget/f_fastboot.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/fastboot.c b/cmd/fastboot.c index dd223b1554d..b498e4b22bb 100644 --- a/cmd/fastboot.c +++ b/cmd/fastboot.c @@ -83,9 +83,9 @@ static int do_fastboot_usb(int argc, char *const argv[], ret = CMD_RET_SUCCESS; exit: + usb_gadget_release(controller_index); g_dnl_unregister(); g_dnl_clear_detach(); - usb_gadget_release(controller_index); return ret; #else diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index d0e92c7a071..07b1681c8a9 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -544,6 +544,7 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) case FASTBOOT_COMMAND_REBOOT_FASTBOOTD: case FASTBOOT_COMMAND_REBOOT_RECOVERY: fastboot_func->in_req->complete = compl_do_reset; + g_dnl_trigger_detach(); break; #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) case FASTBOOT_COMMAND_ACMD: