Merge git://git.denx.de/u-boot-usb
This commit is contained in:
commit
da773532cd
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -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;
|
||||
@ -111,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);
|
||||
@ -130,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);
|
||||
@ -148,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.
|
||||
@ -168,28 +171,52 @@ 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");
|
||||
dev_err(dev, "Error enabling vbus supply\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
/*
|
||||
@ -270,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. */
|
||||
@ -784,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;
|
||||
|
||||
@ -1091,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);
|
||||
@ -1107,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;
|
||||
}
|
||||
|
||||
@ -1269,6 +1298,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);
|
||||
|
||||
|
@ -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);
|
||||
@ -51,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;
|
||||
}
|
||||
@ -59,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;
|
||||
}
|
||||
}
|
||||
@ -80,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;
|
||||
}
|
||||
@ -88,25 +140,15 @@ 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 = 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)
|
||||
goto reset_err;
|
||||
|
||||
hccr = map_physmem(dev_read_addr(dev), 0x100, MAP_NOCACHE);
|
||||
hcor = (struct ehci_hcor *)((uintptr_t)hccr +
|
||||
@ -119,20 +161,18 @@ static int ehci_usb_probe(struct udevice *dev)
|
||||
return 0;
|
||||
|
||||
phy_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);
|
||||
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;
|
||||
}
|
||||
@ -146,11 +186,9 @@ static int ehci_usb_remove(struct udevice *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (generic_phy_valid(&priv->phy)) {
|
||||
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)
|
||||
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright 2010, Chris Zhang <chris@seamicro.com>
|
||||
*
|
||||
* Author: Chris Zhang <chris@seamicro.com>
|
||||
* This code is based on ehci freescale driver
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <usb.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#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;
|
||||
}
|
@ -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);
|
||||
@ -47,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;
|
||||
}
|
||||
|
||||
@ -74,31 +124,20 @@ 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 = 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)
|
||||
goto reset_err;
|
||||
|
||||
err = ohci_register(dev, regs);
|
||||
if (err)
|
||||
@ -107,20 +146,18 @@ static int ohci_usb_probe(struct udevice *dev)
|
||||
return 0;
|
||||
|
||||
phy_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);
|
||||
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;
|
||||
}
|
||||
@ -134,11 +171,9 @@ static int ohci_usb_remove(struct udevice *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (generic_phy_valid(&priv->phy)) {
|
||||
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)
|
||||
|
@ -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)
|
||||
@ -112,6 +113,50 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_USB
|
||||
static int xhci_dwc3_setup_phy(struct udevice *dev, int index, struct phy *phy)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
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(phy);
|
||||
if (ret) {
|
||||
pr_err("Can't init USB PHY for %s\n", dev->name);
|
||||
return ret;
|
||||
}
|
||||
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);
|
||||
@ -125,18 +170,17 @@ static int xhci_dwc3_probe(struct udevice *dev)
|
||||
hcor = (struct xhci_hcor *)((uintptr_t)hccr +
|
||||
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
|
||||
|
||||
ret = generic_phy_get_by_index(dev, 0, &plat->usb_phy);
|
||||
ret = xhci_dwc3_setup_phy(dev, 0, &plat->usb_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);
|
||||
if (ret) {
|
||||
pr_err("Can't init USB PHY for %s\n", dev->name);
|
||||
return ret;
|
||||
}
|
||||
pr_err("Failed to setup USB PHY for %s\n", dev->name);
|
||||
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);
|
||||
@ -158,13 +202,13 @@ 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_exit(&plat->usb_phy);
|
||||
if (ret) {
|
||||
pr_err("Can't deinit 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 = 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user