diff options
author | Jean-Jacques Hiblot <jjhiblot@ti.com> | 2018-11-29 10:52:45 +0100 |
---|---|---|
committer | Marek Vasut <marex@denx.de> | 2018-12-07 16:31:45 +0100 |
commit | d648a50c0a27452a5439e7982b23b97c64820430 (patch) | |
tree | 5b32bcb24a3c0cb98de3bf12307097b3db024aaa /drivers/usb/dwc3/core.c | |
parent | 20bebd866690bb09dd1c1cb8ac674c3b17b63c6d (diff) |
dwc3: move phy operation to core.c
Those operations can be used for peripheral operation as well as host
operation.
Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
# Conflicts:
# drivers/usb/dwc3/core.c
# drivers/usb/host/xhci-dwc3.c
Diffstat (limited to 'drivers/usb/dwc3/core.c')
-rw-r--r-- | drivers/usb/dwc3/core.c | 88 |
1 files changed, 86 insertions, 2 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index f9d84657c87..56e2a046bf0 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -19,7 +19,7 @@ #include <asm/dma-mapping.h> #include <linux/ioport.h> #include <dm.h> - +#include <generic-phy.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> @@ -789,6 +789,91 @@ MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver"); +#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB) +int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys) +{ + int i, ret, count; + struct phy *usb_phys; + + /* Return if no phy declared */ + if (!dev_read_prop(dev, "phys", NULL)) + return 0; + count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); + if (count <= 0) + return count; + + usb_phys = devm_kcalloc(dev, count, sizeof(struct phy), + GFP_KERNEL); + if (!usb_phys) + return -ENOMEM; + + for (i = 0; i < count; i++) { + ret = generic_phy_get_by_index(dev, i, &usb_phys[i]); + if (ret && ret != -ENOENT) { + pr_err("Failed to get USB PHY%d for %s\n", + i, dev->name); + return ret; + } + } + + for (i = 0; i < count; i++) { + ret = generic_phy_init(&usb_phys[i]); + if (ret) { + pr_err("Can't init USB PHY%d for %s\n", + i, dev->name); + goto phys_init_err; + } + } + + for (i = 0; i < count; i++) { + ret = generic_phy_power_on(&usb_phys[i]); + if (ret) { + pr_err("Can't power USB PHY%d for %s\n", + i, dev->name); + goto phys_poweron_err; + } + } + + *array = usb_phys; + *num_phys = count; + return 0; + +phys_poweron_err: + for (i = count - 1; i >= 0; i--) + generic_phy_power_off(&usb_phys[i]); + + for (i = 0; i < count; i++) + generic_phy_exit(&usb_phys[i]); + + return ret; + +phys_init_err: + for (; i >= 0; i--) + generic_phy_exit(&usb_phys[i]); + + return ret; +} + +int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys) +{ + int i, ret; + + for (i = 0; i < num_phys; i++) { + if (!generic_phy_valid(&usb_phys[i])) + continue; + + ret = generic_phy_power_off(&usb_phys[i]); + ret |= generic_phy_exit(&usb_phys[i]); + if (ret) { + pr_err("Can't shutdown USB PHY%d for %s\n", + i, dev->name); + } + } + + return 0; +} +#endif + #if CONFIG_IS_ENABLED(DM_USB_GADGET) int dwc3_init(struct dwc3 *dwc) { @@ -840,5 +925,4 @@ void dwc3_remove(struct dwc3 *dwc) dwc3_core_exit(dwc); kfree(dwc->mem); } - #endif |