[U-Boot] [PATCH 0/3] Extend xhci-dwc3

From: Patrice Chotard patrice.chotard@st.com
Convert xhci-dwc3 to Driver Model Add dual role mode selection from DT Add generic PHY support
Patrice Chotard (3): usb: host: xhci-dwc3: Convert driver to DM usb: host: xhci-dwc3: Add dual role mode support from DT usb: host: xhci-dwc3: Add generic PHY support
drivers/usb/host/xhci-dwc3.c | 109 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+)

From: Patrice Chotard patrice.chotard@st.com
Add Driver Model support with use of generic DT compatible string "snps,dwc3"
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- drivers/usb/host/xhci-dwc3.c | 71 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index 33961cd..b0b9076 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -9,9 +9,23 @@ */
#include <common.h> +#include <dm.h> +#include <usb.h> + +#include "xhci.h" #include <asm/io.h> #include <linux/usb/dwc3.h>
+DECLARE_GLOBAL_DATA_PTR; + +struct xhci_dwc3_platdata { + phys_addr_t dwc3_regs; +}; + +struct xhci_dwc3_priv { + struct xhci_ctrl ctrl; +}; + void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode) { clrsetbits_le32(&dwc3_reg->g_ctl, @@ -97,3 +111,60 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val) setbits_le32(&dwc3_reg->g_fladj, GFLADJ_30MHZ_REG_SEL | GFLADJ_30MHZ(val)); } + +static int xhci_dwc3_ofdata_to_platdata(struct udevice *dev) +{ + struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); + u32 reg[2]; + + /* get the dwc3 register space base address */ + if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), "reg", reg, + ARRAY_SIZE(reg))) { + debug("dwc3 node has bad/missing 'reg' property\n"); + return -FDT_ERR_NOTFOUND; + } + plat->dwc3_regs = reg[0]; + + 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; + + hccr = (struct xhci_hccr *)plat->dwc3_regs; + hcor = (struct xhci_hcor *)((phys_addr_t)hccr + + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase))); + + dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); + + dwc3_core_init(dwc3_reg); + + return xhci_register(dev, hccr, hcor); +} + +static int xhci_dwc3_remove(struct udevice *dev) +{ + return xhci_deregister(dev); +} + +static const struct udevice_id xhci_dwc3_ids[] = { + { .compatible = "snps,dwc3" }, + { } +}; + +U_BOOT_DRIVER(xhci_dwc3) = { + .name = "xhci-dwc3", + .id = UCLASS_USB, + .of_match = xhci_dwc3_ids, + .ofdata_to_platdata = xhci_dwc3_ofdata_to_platdata, + .probe = xhci_dwc3_probe, + .remove = xhci_dwc3_remove, + .ops = &xhci_usb_ops, + .priv_auto_alloc_size = sizeof(struct xhci_dwc3_priv), + .platdata_auto_alloc_size = sizeof(struct xhci_dwc3_platdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +};

On 05/19/2017 09:15 AM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add Driver Model support with use of generic DT compatible string "snps,dwc3"
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/xhci-dwc3.c | 71 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index 33961cd..b0b9076 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -9,9 +9,23 @@ */
#include <common.h> +#include <dm.h> +#include <usb.h>
+#include "xhci.h" #include <asm/io.h> #include <linux/usb/dwc3.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct xhci_dwc3_platdata {
- phys_addr_t dwc3_regs;
+};
Since you have DM, do you need this ?
+struct xhci_dwc3_priv {
- struct xhci_ctrl ctrl;
+};
void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode) { clrsetbits_le32(&dwc3_reg->g_ctl, @@ -97,3 +111,60 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val) setbits_le32(&dwc3_reg->g_fladj, GFLADJ_30MHZ_REG_SEL | GFLADJ_30MHZ(val)); }
+static int xhci_dwc3_ofdata_to_platdata(struct udevice *dev) +{
- struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
- u32 reg[2];
- /* get the dwc3 register space base address */
- if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), "reg", reg,
ARRAY_SIZE(reg))) {
dev_get_addr() ?
debug("dwc3 node has bad/missing 'reg' property\n");
return -FDT_ERR_NOTFOUND;
- }
- plat->dwc3_regs = reg[0];
- 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;
- hccr = (struct xhci_hccr *)plat->dwc3_regs;
- hcor = (struct xhci_hcor *)((phys_addr_t)hccr +
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
- dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
- dwc3_core_init(dwc3_reg);
- return xhci_register(dev, hccr, hcor);
+}
+static int xhci_dwc3_remove(struct udevice *dev) +{
- return xhci_deregister(dev);
+}
+static const struct udevice_id xhci_dwc3_ids[] = {
- { .compatible = "snps,dwc3" },
- { }
+};
+U_BOOT_DRIVER(xhci_dwc3) = {
- .name = "xhci-dwc3",
- .id = UCLASS_USB,
- .of_match = xhci_dwc3_ids,
- .ofdata_to_platdata = xhci_dwc3_ofdata_to_platdata,
- .probe = xhci_dwc3_probe,
- .remove = xhci_dwc3_remove,
- .ops = &xhci_usb_ops,
- .priv_auto_alloc_size = sizeof(struct xhci_dwc3_priv),
- .platdata_auto_alloc_size = sizeof(struct xhci_dwc3_platdata),
- .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};

Hi Marek
On 05/19/2017 12:06 PM, Marek Vasut wrote:
On 05/19/2017 09:15 AM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add Driver Model support with use of generic DT compatible string "snps,dwc3"
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/xhci-dwc3.c | 71 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index 33961cd..b0b9076 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -9,9 +9,23 @@ */
#include <common.h> +#include <dm.h> +#include <usb.h>
+#include "xhci.h" #include <asm/io.h> #include <linux/usb/dwc3.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct xhci_dwc3_platdata {
- phys_addr_t dwc3_regs;
+};
Since you have DM, do you need this ?
Ah yes, effectively, i can remove that
+struct xhci_dwc3_priv {
- struct xhci_ctrl ctrl;
+};
- void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode) { clrsetbits_le32(&dwc3_reg->g_ctl,
@@ -97,3 +111,60 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val) setbits_le32(&dwc3_reg->g_fladj, GFLADJ_30MHZ_REG_SEL | GFLADJ_30MHZ(val)); }
+static int xhci_dwc3_ofdata_to_platdata(struct udevice *dev) +{
- struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
- u32 reg[2];
- /* get the dwc3 register space base address */
- if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), "reg", reg,
ARRAY_SIZE(reg))) {
dev_get_addr() ?
Agree, i will fix it
Thanks
Patrice
debug("dwc3 node has bad/missing 'reg' property\n");
return -FDT_ERR_NOTFOUND;
- }
- plat->dwc3_regs = reg[0];
- 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;
- hccr = (struct xhci_hccr *)plat->dwc3_regs;
- hcor = (struct xhci_hcor *)((phys_addr_t)hccr +
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
- dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
- dwc3_core_init(dwc3_reg);
- return xhci_register(dev, hccr, hcor);
+}
+static int xhci_dwc3_remove(struct udevice *dev) +{
- return xhci_deregister(dev);
+}
+static const struct udevice_id xhci_dwc3_ids[] = {
- { .compatible = "snps,dwc3" },
- { }
+};
+U_BOOT_DRIVER(xhci_dwc3) = {
- .name = "xhci-dwc3",
- .id = UCLASS_USB,
- .of_match = xhci_dwc3_ids,
- .ofdata_to_platdata = xhci_dwc3_ofdata_to_platdata,
- .probe = xhci_dwc3_probe,
- .remove = xhci_dwc3_remove,
- .ops = &xhci_usb_ops,
- .priv_auto_alloc_size = sizeof(struct xhci_dwc3_priv),
- .platdata_auto_alloc_size = sizeof(struct xhci_dwc3_platdata),
- .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};

From: Patrice Chotard patrice.chotard@st.com
DWC3 dual role mode is selected using DT "dr_mode" property. If not found, DWC3 controller is configured in HOST mode by default
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- drivers/usb/host/xhci-dwc3.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index b0b9076..ea85834 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -15,6 +15,7 @@ #include "xhci.h" #include <asm/io.h> #include <linux/usb/dwc3.h> +#include <linux/usb/otg.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -134,6 +135,7 @@ static int xhci_dwc3_probe(struct udevice *dev) struct xhci_hcor *hcor; struct xhci_hccr *hccr; struct dwc3 *dwc3_reg; + enum usb_dr_mode dr_mode;
hccr = (struct xhci_hccr *)plat->dwc3_regs; hcor = (struct xhci_hcor *)((phys_addr_t)hccr + @@ -143,6 +145,13 @@ static int xhci_dwc3_probe(struct udevice *dev)
dwc3_core_init(dwc3_reg);
+ dr_mode = usb_get_dr_mode(dev_of_offset(dev)); + if (dr_mode == USB_DR_MODE_UNKNOWN) + /* by default set dual role mode to HOST */ + dr_mode = USB_DR_MODE_HOST; + + dwc3_set_mode(dwc3_reg, dr_mode); + return xhci_register(dev, hccr, hcor); }

On 19 May 2017 at 01:15, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
DWC3 dual role mode is selected using DT "dr_mode" property. If not found, DWC3 controller is configured in HOST mode by default
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/xhci-dwc3.c | 9 +++++++++ 1 file changed, 9 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

From: Patrice Chotard patrice.chotard@st.com
Add support of generic PHY framework support
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- drivers/usb/host/xhci-dwc3.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index ea85834..70d3946 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -10,6 +10,8 @@
#include <common.h> #include <dm.h> +#include <fdtdec.h> +#include <generic-phy.h> #include <usb.h>
#include "xhci.h" @@ -20,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
struct xhci_dwc3_platdata { + struct phy usb_phy; phys_addr_t dwc3_regs; };
@@ -136,11 +139,26 @@ static int xhci_dwc3_probe(struct udevice *dev) struct xhci_hccr *hccr; struct dwc3 *dwc3_reg; enum usb_dr_mode dr_mode; + int ret;
hccr = (struct xhci_hccr *)plat->dwc3_regs; hcor = (struct xhci_hcor *)((phys_addr_t)hccr + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
+ ret = generic_phy_get_by_index(dev, 0, &plat->usb_phy); + if (ret) { + if (ret != -ENOENT) { + error("Failed to get USB PHY for %s\n", dev->name); + return ret; + } + } else { + ret = generic_phy_init(&plat->usb_phy); + if (ret) { + error("Can't init USB PHY for %s\n", dev->name); + return ret; + } + } + dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
dwc3_core_init(dwc3_reg); @@ -157,6 +175,17 @@ static int xhci_dwc3_probe(struct udevice *dev)
static int xhci_dwc3_remove(struct udevice *dev) { + struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); + int ret; + + if (plat->usb_phy.dev) { + ret = generic_phy_exit(&plat->usb_phy); + if (ret) { + error("Can't deinit USB PHY for %s\n", dev->name); + return ret; + } + } + return xhci_deregister(dev); }

On 05/19/2017 09:15 AM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support of generic PHY framework support
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/xhci-dwc3.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index ea85834..70d3946 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -10,6 +10,8 @@
#include <common.h> #include <dm.h> +#include <fdtdec.h> +#include <generic-phy.h> #include <usb.h>
#include "xhci.h" @@ -20,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
struct xhci_dwc3_platdata {
- struct phy usb_phy; phys_addr_t dwc3_regs;
};
@@ -136,11 +139,26 @@ static int xhci_dwc3_probe(struct udevice *dev) struct xhci_hccr *hccr; struct dwc3 *dwc3_reg; enum usb_dr_mode dr_mode;
int ret;
hccr = (struct xhci_hccr *)plat->dwc3_regs; hcor = (struct xhci_hcor *)((phys_addr_t)hccr + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
ret = generic_phy_get_by_index(dev, 0, &plat->usb_phy);
if (ret) {
if (ret != -ENOENT) {
error("Failed to get USB PHY for %s\n", dev->name);
return ret;
}
} else {
You can drop the else and indent here by reordering the condition.
Otherwise OK.
ret = generic_phy_init(&plat->usb_phy);
if (ret) {
error("Can't init USB PHY for %s\n", dev->name);
return ret;
}
}
dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
dwc3_core_init(dwc3_reg);
@@ -157,6 +175,17 @@ static int xhci_dwc3_probe(struct udevice *dev)
static int xhci_dwc3_remove(struct udevice *dev) {
- struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
- int ret;
- if (plat->usb_phy.dev) {
ret = generic_phy_exit(&plat->usb_phy);
if (ret) {
error("Can't deinit USB PHY for %s\n", dev->name);
return ret;
}
- }
- return xhci_deregister(dev);
}

Hi Marek
On 05/19/2017 12:07 PM, Marek Vasut wrote:
On 05/19/2017 09:15 AM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support of generic PHY framework support
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/xhci-dwc3.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index ea85834..70d3946 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -10,6 +10,8 @@
#include <common.h> #include <dm.h> +#include <fdtdec.h> +#include <generic-phy.h> #include <usb.h>
#include "xhci.h" @@ -20,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
struct xhci_dwc3_platdata {
- struct phy usb_phy; phys_addr_t dwc3_regs; };
@@ -136,11 +139,26 @@ static int xhci_dwc3_probe(struct udevice *dev) struct xhci_hccr *hccr; struct dwc3 *dwc3_reg; enum usb_dr_mode dr_mode;
int ret;
hccr = (struct xhci_hccr *)plat->dwc3_regs; hcor = (struct xhci_hcor *)((phys_addr_t)hccr + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
ret = generic_phy_get_by_index(dev, 0, &plat->usb_phy);
if (ret) {
if (ret != -ENOENT) {
error("Failed to get USB PHY for %s\n", dev->name);
return ret;
}
} else {
You can drop the else and indent here by reordering the condition.
I can't drop the "else", otherwise, in case there is no "phys" property in DT (by example for arch/arm/dts/zynqmp.dtsi), generic_phy_get_by_index() returns -ENOENT, we must continue without calling generic_phy_init().
Patrice
Otherwise OK.
ret = generic_phy_init(&plat->usb_phy);
if (ret) {
error("Can't init USB PHY for %s\n", dev->name);
return ret;
}
}
dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
dwc3_core_init(dwc3_reg);
@@ -157,6 +175,17 @@ static int xhci_dwc3_probe(struct udevice *dev)
static int xhci_dwc3_remove(struct udevice *dev) {
- struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
- int ret;
- if (plat->usb_phy.dev) {
ret = generic_phy_exit(&plat->usb_phy);
if (ret) {
error("Can't deinit USB PHY for %s\n", dev->name);
return ret;
}
- }
- return xhci_deregister(dev); }

On 19 May 2017 at 01:15, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support of generic PHY framework support
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/xhci-dwc3.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
Please see below.
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index ea85834..70d3946 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -10,6 +10,8 @@
#include <common.h> #include <dm.h> +#include <fdtdec.h> +#include <generic-phy.h> #include <usb.h>
#include "xhci.h" @@ -20,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
struct xhci_dwc3_platdata {
struct phy usb_phy; phys_addr_t dwc3_regs;
};
@@ -136,11 +139,26 @@ static int xhci_dwc3_probe(struct udevice *dev) struct xhci_hccr *hccr; struct dwc3 *dwc3_reg; enum usb_dr_mode dr_mode;
int ret; hccr = (struct xhci_hccr *)plat->dwc3_regs; hcor = (struct xhci_hcor *)((phys_addr_t)hccr + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
ret = generic_phy_get_by_index(dev, 0, &plat->usb_phy);
if (ret) {
if (ret != -ENOENT) {
error("Failed to get USB PHY for %s\n", dev->name);
return ret;
}
} else {
ret = generic_phy_init(&plat->usb_phy);
if (ret) {
error("Can't init USB PHY for %s\n", dev->name);
return ret;
}
}
dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); dwc3_core_init(dwc3_reg);
@@ -157,6 +175,17 @@ static int xhci_dwc3_probe(struct udevice *dev)
static int xhci_dwc3_remove(struct udevice *dev) {
struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
int ret;
if (plat->usb_phy.dev) {
I'd like to have something like generic_phy_valid() to avoid poking inside this data structure. Could you send a patch to add this please?
ret = generic_phy_exit(&plat->usb_phy);
if (ret) {
error("Can't deinit USB PHY for %s\n", dev->name);
return ret;
}
}
return xhci_deregister(dev);
}
-- 1.9.1
Regards, Simon

Hi Simon
On 05/22/2017 10:26 PM, Simon Glass wrote:
On 19 May 2017 at 01:15, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support of generic PHY framework support
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/xhci-dwc3.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
Please see below.
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index ea85834..70d3946 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -10,6 +10,8 @@
#include <common.h> #include <dm.h> +#include <fdtdec.h> +#include <generic-phy.h> #include <usb.h>
#include "xhci.h" @@ -20,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
struct xhci_dwc3_platdata {
};struct phy usb_phy; phys_addr_t dwc3_regs;
@@ -136,11 +139,26 @@ static int xhci_dwc3_probe(struct udevice *dev) struct xhci_hccr *hccr; struct dwc3 *dwc3_reg; enum usb_dr_mode dr_mode;
int ret; hccr = (struct xhci_hccr *)plat->dwc3_regs; hcor = (struct xhci_hcor *)((phys_addr_t)hccr + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
ret = generic_phy_get_by_index(dev, 0, &plat->usb_phy);
if (ret) {
if (ret != -ENOENT) {
error("Failed to get USB PHY for %s\n", dev->name);
return ret;
}
} else {
ret = generic_phy_init(&plat->usb_phy);
if (ret) {
error("Can't init USB PHY for %s\n", dev->name);
return ret;
}
}
dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); dwc3_core_init(dwc3_reg);
@@ -157,6 +175,17 @@ static int xhci_dwc3_probe(struct udevice *dev)
static int xhci_dwc3_remove(struct udevice *dev) {
struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
int ret;
if (plat->usb_phy.dev) {
I'd like to have something like generic_phy_valid() to avoid poking inside this data structure. Could you send a patch to add this please?
Sure, i will add the generic_phy_valid() method.
As the v2 of this series has already been send and reviewed by Marek. I will send the v3 including a patch with generic_phy_valid() and make usage of it.
Thanks
Patrice
ret = generic_phy_exit(&plat->usb_phy);
if (ret) {
error("Can't deinit USB PHY for %s\n", dev->name);
return ret;
}
}
}return xhci_deregister(dev);
-- 1.9.1
Regards, Simon
participants (4)
-
Marek Vasut
-
Patrice CHOTARD
-
patrice.chotard@st.com
-
Simon Glass