From 42637fdae833f8c3e8a0270ea7e74152cbd8ef38 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 28 Feb 2018 16:16:58 +0300 Subject: usb: dwc2: Allow selection of data buffer size If we use hardware with very small RAM (let's consider just a couple of hundreds of kB but not megabytes) it is not super convenient to lose 64kB for statically allocated bufer which most probably won't be used as big as it is. Typically we'll have much shorter data packages to excahnge and in the worst case longer packets will be split on separate transactions. For those corner-cases user will be able to set his buffer size of choice via USB_DWC2_BUFFER_SIZE option in menuconfig. By default we'll use 64 kB as it was hard-coeded before so existing users shouldn't be affected at all. Signed-off-by: Alexey Brodkin Cc: Marek Vasut --- drivers/usb/host/Kconfig | 12 ++++++++++++ drivers/usb/host/dwc2.c | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 90b2f78ec7..a7249b7511 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -245,3 +245,15 @@ config USB_DWC2 Hi-Speed (480 Mbps), Full-Speed (12 Mbps), and Low-Speed (1.5 Mbps) operation is compliant to the controller Supplement. If you want to enable this controller in host mode, say Y. + +if USB_DWC2 +config USB_DWC2_BUFFER_SIZE + int "Data buffer size in kB" + default 64 + ---help--- + By default 64 kB buffer is used but if amount of RAM avaialble on + the target is not enough to accommodate allocation of buffer of + that size it is possible to shrink it. Smaller sizes should be fine + because larger transactions could be split in smaller ones. + +endif # USB_DWC2 diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index 0efe645044..e436c711e7 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -25,7 +25,7 @@ DECLARE_GLOBAL_DATA_PTR; #define DWC2_HC_CHANNEL 0 #define DWC2_STATUS_BUF_SIZE 64 -#define DWC2_DATA_BUF_SIZE (64 * 1024) +#define DWC2_DATA_BUF_SIZE (CONFIG_USB_DWC2_BUFFER_SIZE * 1024) #define MAX_DEVICE 16 #define MAX_ENDPOINT 16 -- cgit From 7d4e4d30631ba9350a18ab2243e749d583b402ab Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Wed, 7 Mar 2018 14:50:08 +0530 Subject: usb: xhci-dwc3: Power on USB PHY before using It is wrong that expect .phy_init() to also power on the PHY. Therefore, explicitly, call generic_phy_power_on() after generic_phy_power_init() in order to power on PHY before using it. Signed-off-by: Vignesh R Reviewed-by: Bin Meng --- drivers/usb/host/xhci-dwc3.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index 258d1cd00a..cf1986bebd 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -137,6 +137,12 @@ static int xhci_dwc3_probe(struct udevice *dev) pr_err("Can't init USB PHY for %s\n", dev->name); return ret; } + + ret = generic_phy_power_on(&plat->usb_phy); + if (ret) { + pr_err("Can't power on USB PHY for %s\n", dev->name); + return ret; + } } dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); @@ -159,6 +165,12 @@ static int xhci_dwc3_remove(struct udevice *dev) int ret; if (generic_phy_valid(&plat->usb_phy)) { + ret = generic_phy_power_off(&plat->usb_phy); + if (ret) { + pr_err("Can't poweroff USB PHY for %s\n", dev->name); + return ret; + } + ret = generic_phy_exit(&plat->usb_phy); if (ret) { pr_err("Can't deinit USB PHY for %s\n", dev->name); -- cgit From 3fc2635d3da8f87675629b6058b646b63d684dff Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Wed, 7 Mar 2018 14:50:09 +0530 Subject: usb: xhci-dwc3: Refractor PHY operations into separate function Refractor PHY get/init/poweron and PHY poweroff/exit operations into separate function so that its easy to support multiple PHYs. Signed-off-by: Vignesh R --- drivers/usb/host/xhci-dwc3.c | 75 ++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 27 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index cf1986bebd..e61a04eeb8 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -112,39 +112,69 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val) } #ifdef CONFIG_DM_USB -static int xhci_dwc3_probe(struct udevice *dev) +static int xhci_dwc3_setup_phy(struct udevice *dev, int index, struct phy *phy) { - struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); - struct xhci_hcor *hcor; - struct xhci_hccr *hccr; - struct dwc3 *dwc3_reg; - enum usb_dr_mode dr_mode; - int ret; - - hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev)); - hcor = (struct xhci_hcor *)((uintptr_t)hccr + - HC_LENGTH(xhci_readl(&(hccr)->cr_capbase))); + int ret = 0; - ret = generic_phy_get_by_index(dev, 0, &plat->usb_phy); + ret = generic_phy_get_by_index(dev, index, phy); if (ret) { if (ret != -ENOENT) { pr_err("Failed to get USB PHY for %s\n", dev->name); return ret; } } else { - ret = generic_phy_init(&plat->usb_phy); + ret = generic_phy_init(phy); if (ret) { pr_err("Can't init USB PHY for %s\n", dev->name); return ret; } - - ret = generic_phy_power_on(&plat->usb_phy); + ret = generic_phy_power_on(phy); if (ret) { pr_err("Can't power on USB PHY for %s\n", dev->name); + generic_phy_exit(phy); return ret; } } + return 0; +} + +static int xhci_dwc3_shutdown_phy(struct phy *phy) +{ + int ret = 0; + + if (generic_phy_valid(phy)) { + ret = generic_phy_power_off(phy); + if (ret) + return ret; + + ret = generic_phy_exit(phy); + if (ret) + return ret; + } + + return 0; +} + +static int xhci_dwc3_probe(struct udevice *dev) +{ + struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); + struct xhci_hcor *hcor; + struct xhci_hccr *hccr; + struct dwc3 *dwc3_reg; + enum usb_dr_mode dr_mode; + int ret; + + hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev)); + hcor = (struct xhci_hcor *)((uintptr_t)hccr + + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase))); + + ret = xhci_dwc3_setup_phy(dev, 0, &plat->usb_phy); + if (ret) { + pr_err("Failed to setup USB PHY for %s\n", dev->name); + return ret; + } + dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); dwc3_core_init(dwc3_reg); @@ -164,19 +194,10 @@ static int xhci_dwc3_remove(struct udevice *dev) struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); int ret; - if (generic_phy_valid(&plat->usb_phy)) { - ret = generic_phy_power_off(&plat->usb_phy); - if (ret) { - pr_err("Can't poweroff USB PHY for %s\n", dev->name); - return ret; - } + ret = xhci_dwc3_shutdown_phy(&plat->usb_phy); + if (ret) + pr_err("Can't shutdown USB PHY for %s\n", dev->name); - ret = generic_phy_exit(&plat->usb_phy); - if (ret) { - pr_err("Can't deinit USB PHY for %s\n", dev->name); - return ret; - } - } return xhci_deregister(dev); } -- cgit From 2fd4242cc50e2da6666028e65a10467171e3dab6 Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Wed, 7 Mar 2018 14:50:10 +0530 Subject: ubs: xhci-dwc3: Enable USB3 PHY when available DWC3 USB3 controllers will need USB3 PHY to be enabled, in addition to USB2 PHY, to be functional. Therefore enable USB3 PHY when available. Signed-off-by: Vignesh R --- drivers/usb/host/xhci-dwc3.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index e61a04eeb8..1022dd5512 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -23,6 +23,7 @@ DECLARE_GLOBAL_DATA_PTR; struct xhci_dwc3_platdata { struct phy usb_phy; + struct phy usb3_phy; }; void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode) @@ -175,6 +176,13 @@ static int xhci_dwc3_probe(struct udevice *dev) return ret; } + ret = xhci_dwc3_setup_phy(dev, 1, &plat->usb3_phy); + if (ret) { + pr_err("Failed to setup USB3 PHY for %s\n", dev->name); + xhci_dwc3_shutdown_phy(&plat->usb_phy); + return ret; + } + dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); dwc3_core_init(dwc3_reg); @@ -198,6 +206,9 @@ static int xhci_dwc3_remove(struct udevice *dev) if (ret) pr_err("Can't shutdown USB PHY for %s\n", dev->name); + ret = xhci_dwc3_shutdown_phy(&plat->usb3_phy); + if (ret) + pr_err("Can't shutdown USB3 PHY for %s\n", dev->name); return xhci_deregister(dev); } -- cgit From 2715e32ce117f596053d3a133d465cbb3d16531c Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 13 Mar 2018 08:41:07 +0100 Subject: usb: Remove unused ppc4xx EHCI host driver ppc4xx support was removed some time ago. Lets remove the now unused EHCI driver and all its references for this platform as well. Signed-off-by: Stefan Roese Cc: Heinrich Schuchardt Cc: Marek Vasut --- drivers/usb/host/Makefile | 1 - drivers/usb/host/ehci-ppc4xx.c | 35 ----------------------------------- 2 files changed, 36 deletions(-) delete mode 100644 drivers/usb/host/ehci-ppc4xx.c (limited to 'drivers/usb') diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 7f9ba24cfe..98194893b9 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -35,7 +35,6 @@ obj-$(CONFIG_USB_EHCI_MX5) += ehci-mx5.o obj-$(CONFIG_USB_EHCI_MX6) += ehci-mx6.o obj-$(CONFIG_USB_EHCI_MX7) += ehci-mx6.o obj-$(CONFIG_USB_EHCI_OMAP) += ehci-omap.o -obj-$(CONFIG_USB_EHCI_PPC4XX) += ehci-ppc4xx.o obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o diff --git a/drivers/usb/host/ehci-ppc4xx.c b/drivers/usb/host/ehci-ppc4xx.c deleted file mode 100644 index 9d23577642..0000000000 --- a/drivers/usb/host/ehci-ppc4xx.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * (C) Copyright 2010, Chris Zhang - * - * Author: Chris Zhang - * This code is based on ehci freescale driver - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include -#include - -#include "ehci.h" - -/* - * Create the appropriate control structures to manage - * a new EHCI host controller. - */ -int ehci_hcd_init(int index, enum usb_init_type init, - struct ehci_hccr **hccr, struct ehci_hcor **hcor) -{ - *hccr = (struct ehci_hccr *)(CONFIG_SYS_PPC4XX_USB_ADDR); - *hcor = (struct ehci_hcor *)((uint32_t) *hccr + - HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); - return 0; -} - -/* - * Destroy the appropriate control structures corresponding - * the the EHCI host controller. - */ -int ehci_hcd_stop(int index) -{ - return 0; -} -- cgit From a800a6793f095746173834ead6b3663bc3c0542c Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 14 Mar 2018 17:48:53 +0100 Subject: usb: ehci-generic: handle phy power on/off Add generic_phy_power_on() and generic_phy_power_off() calls to switch ON/OFF phy during probe and remove functions. Signed-off-by: Christophe Kerello Signed-off-by: Patrice Chotard --- drivers/usb/host/ehci-generic.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c index 1cb92c0338..2edd6d7433 100644 --- a/drivers/usb/host/ehci-generic.c +++ b/drivers/usb/host/ehci-generic.c @@ -106,6 +106,12 @@ static int ehci_usb_probe(struct udevice *dev) pr_err("failed to init usb phy\n"); goto reset_err; } + + err = generic_phy_power_on(&priv->phy); + if (err) { + dev_err(dev, "failed to power on usb phy\n"); + goto phy_power_err; + } } hccr = map_physmem(dev_read_addr(dev), 0x100, MAP_NOCACHE); @@ -119,6 +125,13 @@ static int ehci_usb_probe(struct udevice *dev) return 0; phy_err: + if (generic_phy_valid(&priv->phy)) { + ret = generic_phy_power_off(&priv->phy); + if (ret) + dev_err(dev, "failed to power off usb phy\n"); + } + +phy_power_err: if (generic_phy_valid(&priv->phy)) { ret = generic_phy_exit(&priv->phy); if (ret) @@ -147,6 +160,10 @@ static int ehci_usb_remove(struct udevice *dev) return ret; if (generic_phy_valid(&priv->phy)) { + ret = generic_phy_power_off(&priv->phy); + if (ret) + return ret; + ret = generic_phy_exit(&priv->phy); if (ret) return ret; -- cgit From 20f06a48332d8dec255e3e808c3c97bb3222c2fd Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 14 Mar 2018 17:48:54 +0100 Subject: usb: ehci-generic: factorize PHY operation Factorize PHY get/init/poweron and PHY poweroff/exit operations into separate function, it simplify the error path. Signed-off-by: Patrice Chotard --- drivers/usb/host/ehci-generic.c | 99 ++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 40 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c index 2edd6d7433..0926986d27 100644 --- a/drivers/usb/host/ehci-generic.c +++ b/drivers/usb/host/ehci-generic.c @@ -27,6 +27,56 @@ struct generic_ehci { int reset_count; }; +static int ehci_setup_phy(struct udevice *dev, int index) +{ + struct generic_ehci *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_err(dev, "failed to init usb phy\n"); + return ret; + } + + ret = generic_phy_power_on(&priv->phy); + if (ret) { + dev_err(dev, "failed to power on usb phy\n"); + return generic_phy_exit(&priv->phy); + } + } + + return 0; +} + +static int ehci_shutdown_phy(struct udevice *dev) +{ + struct generic_ehci *priv = dev_get_priv(dev); + int ret = 0; + + if (generic_phy_valid(&priv->phy)) { + ret = generic_phy_power_off(&priv->phy); + if (ret) { + dev_err(dev, "failed to power off usb phy\n"); + return ret; + } + + ret = generic_phy_exit(&priv->phy); + if (ret) { + dev_err(dev, "failed to power off usb phy\n"); + return ret; + } + } + + return 0; +} + static int ehci_usb_probe(struct udevice *dev) { struct generic_ehci *priv = dev_get_priv(dev); @@ -93,26 +143,10 @@ static int ehci_usb_probe(struct udevice *dev) } } - err = generic_phy_get_by_index(dev, 0, &priv->phy); - if (err) { - if (err != -ENOENT) { - pr_err("failed to get usb phy\n"); - goto reset_err; - } - } else { - - err = generic_phy_init(&priv->phy); - if (err) { - pr_err("failed to init usb phy\n"); - goto reset_err; - } + err = ehci_setup_phy(dev, 0); + if (err) - err = generic_phy_power_on(&priv->phy); - if (err) { - dev_err(dev, "failed to power on usb phy\n"); - goto phy_power_err; - } - } + goto reset_err; hccr = map_physmem(dev_read_addr(dev), 0x100, MAP_NOCACHE); hcor = (struct ehci_hcor *)((uintptr_t)hccr + @@ -125,18 +159,9 @@ static int ehci_usb_probe(struct udevice *dev) return 0; phy_err: - if (generic_phy_valid(&priv->phy)) { - ret = generic_phy_power_off(&priv->phy); - if (ret) - dev_err(dev, "failed to power off usb phy\n"); - } - -phy_power_err: - if (generic_phy_valid(&priv->phy)) { - ret = generic_phy_exit(&priv->phy); - if (ret) - pr_err("failed to release phy\n"); - } + ret = ehci_shutdown_phy(dev); + if (ret) + dev_err(dev, "failed to shutdown usb phy\n"); reset_err: ret = reset_release_all(priv->resets, priv->reset_count); @@ -159,15 +184,9 @@ static int ehci_usb_remove(struct udevice *dev) if (ret) return ret; - if (generic_phy_valid(&priv->phy)) { - ret = generic_phy_power_off(&priv->phy); - if (ret) - return ret; - - ret = generic_phy_exit(&priv->phy); - if (ret) - return ret; - } + ret = ehci_shutdown_phy(dev); + if (ret) + return ret; ret = reset_release_all(priv->resets, priv->reset_count); if (ret) -- cgit From df7777ab4386a5982d978a558e9b973085654c5e Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 14 Mar 2018 17:48:55 +0100 Subject: usb: ehci-generic: replace pr_err() by dev_err() As we get access to struct udevice, use dev_err() instead of pr_err(). Signed-off-by: Patrice Chotard --- drivers/usb/host/ehci-generic.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c index 0926986d27..b012d8651f 100644 --- a/drivers/usb/host/ehci-generic.c +++ b/drivers/usb/host/ehci-generic.c @@ -101,7 +101,7 @@ static int ehci_usb_probe(struct udevice *dev) break; err = clk_enable(&priv->clocks[i]); if (err) { - pr_err("failed to enable clock %d\n", i); + dev_err(dev, "failed to enable clock %d\n", i); clk_free(&priv->clocks[i]); goto clk_err; } @@ -109,7 +109,8 @@ static int ehci_usb_probe(struct udevice *dev) } } else { if (clock_nb != -ENOENT) { - pr_err("failed to get clock phandle(%d)\n", clock_nb); + dev_err(dev, "failed to get clock phandle(%d)\n", + clock_nb); return clock_nb; } } @@ -130,7 +131,8 @@ static int ehci_usb_probe(struct udevice *dev) break; if (reset_deassert(&priv->resets[i])) { - pr_err("failed to deassert reset %d\n", i); + dev_err(dev, "failed to deassert reset %d\n", + i); reset_free(&priv->resets[i]); goto reset_err; } @@ -138,14 +140,14 @@ static int ehci_usb_probe(struct udevice *dev) } } else { if (reset_nb != -ENOENT) { - pr_err("failed to get reset phandle(%d)\n", reset_nb); + dev_err(dev, "failed to get reset phandle(%d)\n", + reset_nb); goto clk_err; } } err = ehci_setup_phy(dev, 0); if (err) - goto reset_err; hccr = map_physmem(dev_read_addr(dev), 0x100, MAP_NOCACHE); @@ -166,11 +168,11 @@ phy_err: reset_err: ret = reset_release_all(priv->resets, priv->reset_count); if (ret) - pr_err("failed to assert all resets\n"); + dev_err(dev, "failed to assert all resets\n"); clk_err: ret = clk_release_all(priv->clocks, priv->clock_count); if (ret) - pr_err("failed to disable all clocks\n"); + dev_err(dev, "failed to disable all clocks\n"); return err; } -- cgit From 633e1ec6bf7131d3c8fecbb4adcc96e17925a015 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 14 Mar 2018 17:48:56 +0100 Subject: usb: ohci-generic: handle phy power on/off Add generic_phy_power_on() and generic_phy_power_off() calls to switch ON/OFF phy during probe and remove functions. Signed-off-by: Patrice Chotard --- drivers/usb/host/ohci-generic.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c index bf55a71d66..4843b4ac85 100644 --- a/drivers/usb/host/ohci-generic.c +++ b/drivers/usb/host/ohci-generic.c @@ -98,6 +98,12 @@ static int ohci_usb_probe(struct udevice *dev) pr_err("failed to init usb phy\n"); goto reset_err; } + + err = generic_phy_power_on(&priv->phy); + if (err) { + dev_err(dev, "failed to power on usb phy\n"); + goto phy_power_err; + } } err = ohci_register(dev, regs); @@ -107,6 +113,13 @@ static int ohci_usb_probe(struct udevice *dev) return 0; phy_err: + if (generic_phy_valid(&priv->phy)) { + ret = generic_phy_power_off(&priv->phy); + if (ret) + dev_err(dev, "failed to power off usb phy\n"); + } + +phy_power_err: if (generic_phy_valid(&priv->phy)) { ret = generic_phy_exit(&priv->phy); if (ret) @@ -135,6 +148,10 @@ static int ohci_usb_remove(struct udevice *dev) return ret; if (generic_phy_valid(&priv->phy)) { + ret = generic_phy_power_off(&priv->phy); + if (ret) + return ret; + ret = generic_phy_exit(&priv->phy); if (ret) return ret; -- cgit From cab4d48a939537ab10e00429fc774825b743ed10 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 14 Mar 2018 17:48:57 +0100 Subject: usb: ohci-generic: factorize PHY operation Factorize PHY get/init/poweron and PHY poweroff/exit operations into separate function, it simplify the error path. Signed-off-by: Patrice Chotard --- drivers/usb/host/ohci-generic.c | 99 ++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 40 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c index 4843b4ac85..590fe4ca74 100644 --- a/drivers/usb/host/ohci-generic.c +++ b/drivers/usb/host/ohci-generic.c @@ -25,6 +25,56 @@ 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_err(dev, "failed to init usb phy\n"); + return ret; + } + + ret = generic_phy_power_on(&priv->phy); + if (ret) { + dev_err(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_err(dev, "failed to power off usb phy\n"); + return ret; + } + + ret = generic_phy_exit(&priv->phy); + if (ret) { + dev_err(dev, "failed to power off usb phy\n"); + return ret; + } + } + + return 0; +} + static int ohci_usb_probe(struct udevice *dev) { struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev); @@ -85,26 +135,10 @@ static int ohci_usb_probe(struct udevice *dev) goto clk_err; } - err = generic_phy_get_by_index(dev, 0, &priv->phy); - if (err) { - if (err != -ENOENT) { - pr_err("failed to get usb phy\n"); - goto reset_err; - } - } else { - - err = generic_phy_init(&priv->phy); - if (err) { - pr_err("failed to init usb phy\n"); - goto reset_err; - } + err = ohci_setup_phy(dev, 0); + if (err) - err = generic_phy_power_on(&priv->phy); - if (err) { - dev_err(dev, "failed to power on usb phy\n"); - goto phy_power_err; - } - } + goto reset_err; err = ohci_register(dev, regs); if (err) @@ -113,18 +147,9 @@ static int ohci_usb_probe(struct udevice *dev) return 0; phy_err: - if (generic_phy_valid(&priv->phy)) { - ret = generic_phy_power_off(&priv->phy); - if (ret) - dev_err(dev, "failed to power off usb phy\n"); - } - -phy_power_err: - if (generic_phy_valid(&priv->phy)) { - ret = generic_phy_exit(&priv->phy); - if (ret) - pr_err("failed to release phy\n"); - } + ret = ohci_shutdown_phy(dev); + if (ret) + dev_err(dev, "failed to shutdown usb phy\n"); reset_err: ret = reset_release_all(priv->resets, priv->reset_count); @@ -147,15 +172,9 @@ static int ohci_usb_remove(struct udevice *dev) if (ret) return ret; - if (generic_phy_valid(&priv->phy)) { - ret = generic_phy_power_off(&priv->phy); - if (ret) - return ret; - - ret = generic_phy_exit(&priv->phy); - if (ret) - return ret; - } + ret = ohci_shutdown_phy(dev); + if (ret) + return ret; ret = reset_release_all(priv->resets, priv->reset_count); if (ret) -- cgit From 6048d42fa7a2b97913db9a033675bf267fb4e030 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 14 Mar 2018 17:48:58 +0100 Subject: usb: ohci-generic: replace pr_err() by dev_err() As we get access to struct udevice, use dev_err() instead of pr_err(). Signed-off-by: Patrice Chotard --- drivers/usb/host/ohci-generic.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c index 590fe4ca74..5bdd7995b9 100644 --- a/drivers/usb/host/ohci-generic.c +++ b/drivers/usb/host/ohci-generic.c @@ -97,14 +97,14 @@ static int ohci_usb_probe(struct udevice *dev) err = clk_enable(&priv->clocks[i]); if (err) { - pr_err("failed to enable clock %d\n", i); + dev_err(dev, "failed to enable clock %d\n", i); clk_free(&priv->clocks[i]); goto clk_err; } priv->clock_count++; } } else if (clock_nb != -ENOENT) { - pr_err("failed to get clock phandle(%d)\n", clock_nb); + dev_err(dev, "failed to get clock phandle(%d)\n", clock_nb); return clock_nb; } @@ -124,20 +124,19 @@ static int ohci_usb_probe(struct udevice *dev) err = reset_deassert(&priv->resets[i]); if (err) { - pr_err("failed to deassert reset %d\n", i); + dev_err(dev, "failed to deassert reset %d\n", i); reset_free(&priv->resets[i]); goto reset_err; } priv->reset_count++; } } else if (reset_nb != -ENOENT) { - pr_err("failed to get reset phandle(%d)\n", reset_nb); + dev_err(dev, "failed to get reset phandle(%d)\n", reset_nb); goto clk_err; } err = ohci_setup_phy(dev, 0); if (err) - goto reset_err; err = ohci_register(dev, regs); @@ -154,11 +153,11 @@ phy_err: reset_err: ret = reset_release_all(priv->resets, priv->reset_count); if (ret) - pr_err("failed to assert all resets\n"); + dev_err(dev, "failed to assert all resets\n"); clk_err: ret = clk_release_all(priv->clocks, priv->clock_count); if (ret) - pr_err("failed to disable all clocks\n"); + dev_err(dev, "failed to disable all clocks\n"); return err; } -- cgit From 82e7975b85bea1c2acccf30e6fd11e1a48a7e783 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Thu, 15 Mar 2018 18:00:30 +0100 Subject: usb: dwc2: disable external vbus supply when the device is removed This patch adds an interface to disable the power in dwc2 driver. This new interface is called when the device is removed. Signed-off-by: Christophe Kerello Signed-off-by: Patrice Chotard --- drivers/usb/host/dwc2.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index e436c711e7..138646e4c8 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -34,6 +34,9 @@ struct dwc2_priv { #ifdef CONFIG_DM_USB uint8_t aligned_buffer[DWC2_DATA_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN); uint8_t status_buffer[DWC2_STATUS_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN); +#ifdef CONFIG_DM_REGULATOR + struct udevice *vbus_supply; +#endif #else uint8_t *aligned_buffer; uint8_t *status_buffer; @@ -168,16 +171,17 @@ static void dwc_otg_core_reset(struct dwc2_core_regs *regs) #if defined(CONFIG_DM_USB) && defined(CONFIG_DM_REGULATOR) static int dwc_vbus_supply_init(struct udevice *dev) { - struct udevice *vbus_supply; + struct dwc2_priv *priv = dev_get_priv(dev); int ret; - ret = device_get_supply_regulator(dev, "vbus-supply", &vbus_supply); + ret = device_get_supply_regulator(dev, "vbus-supply", + &priv->vbus_supply); if (ret) { debug("%s: No vbus supply\n", dev->name); return 0; } - ret = regulator_set_enable(vbus_supply, true); + ret = regulator_set_enable(priv->vbus_supply, true); if (ret) { pr_err("Error enabling vbus supply\n"); return ret; @@ -185,11 +189,34 @@ static int dwc_vbus_supply_init(struct udevice *dev) return 0; } + +static int dwc_vbus_supply_exit(struct udevice *dev) +{ + struct dwc2_priv *priv = dev_get_priv(dev); + int ret; + + if (priv->vbus_supply) { + ret = regulator_set_enable(priv->vbus_supply, false); + if (ret) { + dev_err(dev, "Error disabling vbus supply\n"); + return ret; + } + } + + return 0; +} #else static int dwc_vbus_supply_init(struct udevice *dev) { return 0; } + +#if defined(CONFIG_DM_USB) +static int dwc_vbus_supply_exit(struct udevice *dev) +{ + return 0; +} +#endif #endif /* @@ -1269,6 +1296,11 @@ static int dwc2_usb_probe(struct udevice *dev) static int dwc2_usb_remove(struct udevice *dev) { struct dwc2_priv *priv = dev_get_priv(dev); + int ret; + + ret = dwc_vbus_supply_exit(dev); + if (ret) + return ret; dwc2_uninit_common(priv->regs); -- cgit From c2e4c8656978302ff2846a655fb87c658220c4e0 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Thu, 15 Mar 2018 18:00:31 +0100 Subject: usb: dwc2: increase timeout in wait_for_chhltd This patch increases timeout to 2s. It was seen on 2 USB devices (Verbatim STORE N GO 070B4AED0FB22358 and USB DISK 2.0 9000729BA41DDF40) that the request sense command takes between 1.3s and and 1.5s. Signed-off-by: Christophe Kerello Signed-off-by: Patrice Chotard --- drivers/usb/host/dwc2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index 138646e4c8..f9e2f2b785 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -811,7 +811,7 @@ int wait_for_chhltd(struct dwc2_hc_regs *hc_regs, uint32_t *sub, u8 *toggle) uint32_t hcint, hctsiz; ret = wait_for_bit_le32(&hc_regs->hcint, DWC2_HCINT_CHHLTD, true, - 1000, false); + 2000, false); if (ret) return ret; -- cgit From ac6c796c3f5c7b7594cf4ecede8cd8fb8d2611ba Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Thu, 15 Mar 2018 18:00:32 +0100 Subject: usb: dwc2: Replace printf, pr_err by dev_info, dev_err Replace printf() call by dev_info() and pr_err() by dev_err() Signed-off-by: Patrice Chotard --- drivers/usb/host/dwc2.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index f9e2f2b785..4862ab0e7d 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -114,7 +114,7 @@ static void dwc_otg_flush_tx_fifo(struct dwc2_core_regs *regs, const int num) ret = wait_for_bit_le32(®s->grstctl, DWC2_GRSTCTL_TXFFLSH, false, 1000, false); if (ret) - printf("%s: Timeout!\n", __func__); + dev_info(dev, "%s: Timeout!\n", __func__); /* Wait for 3 PHY Clocks */ udelay(1); @@ -133,7 +133,7 @@ static void dwc_otg_flush_rx_fifo(struct dwc2_core_regs *regs) ret = wait_for_bit_le32(®s->grstctl, DWC2_GRSTCTL_RXFFLSH, false, 1000, false); if (ret) - printf("%s: Timeout!\n", __func__); + dev_info(dev, "%s: Timeout!\n", __func__); /* Wait for 3 PHY Clocks */ udelay(1); @@ -151,14 +151,14 @@ static void dwc_otg_core_reset(struct dwc2_core_regs *regs) ret = wait_for_bit_le32(®s->grstctl, DWC2_GRSTCTL_AHBIDLE, true, 1000, false); if (ret) - printf("%s: Timeout!\n", __func__); + dev_info(dev, "%s: Timeout!\n", __func__); /* Core Soft Reset */ writel(DWC2_GRSTCTL_CSFTRST, ®s->grstctl); ret = wait_for_bit_le32(®s->grstctl, DWC2_GRSTCTL_CSFTRST, false, 1000, false); if (ret) - printf("%s: Timeout!\n", __func__); + dev_info(dev, "%s: Timeout!\n", __func__); /* * Wait for core to come out of reset. @@ -183,7 +183,7 @@ static int dwc_vbus_supply_init(struct udevice *dev) ret = regulator_set_enable(priv->vbus_supply, true); if (ret) { - pr_err("Error enabling vbus supply\n"); + dev_err(dev, "Error enabling vbus supply\n"); return ret; } @@ -297,7 +297,7 @@ static void dwc_otg_core_host_init(struct udevice *dev, ret = wait_for_bit_le32(®s->hc_regs[i].hcchar, DWC2_HCCHAR_CHEN, false, 1000, false); if (ret) - printf("%s: Timeout!\n", __func__); + dev_info("%s: Timeout!\n", __func__); } /* Turn on the vbus power. */ @@ -1118,7 +1118,7 @@ int _submit_int_msg(struct dwc2_priv *priv, struct usb_device *dev, timeout = get_timer(0) + USB_TIMEOUT_MS(pipe); for (;;) { if (get_timer(0) > timeout) { - printf("Timeout poll on interrupt endpoint\n"); + dev_err(dev, "Timeout poll on interrupt endpoint\n"); return -ETIMEDOUT; } ret = _submit_bulk_msg(priv, dev, pipe, buffer, len); @@ -1134,11 +1134,13 @@ static int dwc2_init_common(struct udevice *dev, struct dwc2_priv *priv) int i, j; snpsid = readl(®s->gsnpsid); - printf("Core Release: %x.%03x\n", snpsid >> 12 & 0xf, snpsid & 0xfff); + dev_info(dev, "Core Release: %x.%03x\n", + snpsid >> 12 & 0xf, snpsid & 0xfff); if ((snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_2xx && (snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_3xx) { - printf("SNPSID invalid (not DWC2 OTG device): %08x\n", snpsid); + dev_info(dev, "SNPSID invalid (not DWC2 OTG device): %08x\n", + snpsid); return -ENODEV; } -- cgit