mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-11 15:37:23 +00:00
usb: dwc3-generic: Allow different controller DT node pattern
The most of devicetree has the following USB node structure. The controller node is placed as a child node of the glue node. Current dwc3-generic driver works on this premise. glue { /* glue node */ usb { /* controller node */ }; }; However, UniPhier original devicetree has the following USB node structure. The controller node is separately placed from the glue node. usb { /* controller node */ }; glue { /* glue node */ }; In dwc_glue_bind(), this patch provides .glue_get_ctrl_dev() callback to get such a controller node and binds the driver related to the node. If this callback isn't defined, dwc_glue_bind() looks for the controller nodes from the child nodes, as before. Suggested-by: Marek Vasut <marex@denx.de> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com> Reviewed-by: Marek Vasut <marex@denx.de>
This commit is contained in:
parent
c6583354b7
commit
f7b7c72133
1 changed files with 60 additions and 39 deletions
|
@ -276,6 +276,7 @@ U_BOOT_DRIVER(dwc3_generic_host) = {
|
|||
#endif
|
||||
|
||||
struct dwc3_glue_ops {
|
||||
int (*glue_get_ctrl_dev)(struct udevice *parent, ofnode *node);
|
||||
void (*glue_configure)(struct udevice *dev, int index,
|
||||
enum usb_dr_mode mode);
|
||||
};
|
||||
|
@ -415,54 +416,74 @@ struct dwc3_glue_ops ti_ops = {
|
|||
.glue_configure = dwc3_ti_glue_configure,
|
||||
};
|
||||
|
||||
static int dwc3_glue_bind_common(struct udevice *parent, ofnode node)
|
||||
{
|
||||
const char *name = ofnode_get_name(node);
|
||||
const char *driver = NULL;
|
||||
enum usb_dr_mode dr_mode;
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
debug("%s: subnode name: %s\n", __func__, name);
|
||||
|
||||
/* if the parent node doesn't have a mode check the leaf */
|
||||
dr_mode = usb_get_dr_mode(dev_ofnode(parent));
|
||||
if (!dr_mode)
|
||||
dr_mode = usb_get_dr_mode(node);
|
||||
|
||||
switch (dr_mode) {
|
||||
case USB_DR_MODE_PERIPHERAL:
|
||||
case USB_DR_MODE_OTG:
|
||||
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
|
||||
debug("%s: dr_mode: OTG or Peripheral\n", __func__);
|
||||
driver = "dwc3-generic-peripheral";
|
||||
#endif
|
||||
break;
|
||||
#if defined(CONFIG_SPL_USB_HOST) || !defined(CONFIG_SPL_BUILD)
|
||||
case USB_DR_MODE_HOST:
|
||||
debug("%s: dr_mode: HOST\n", __func__);
|
||||
driver = "dwc3-generic-host";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
debug("%s: unsupported dr_mode\n", __func__);
|
||||
return -ENODEV;
|
||||
};
|
||||
|
||||
if (!driver)
|
||||
return -ENXIO;
|
||||
|
||||
ret = device_bind_driver_to_node(parent, driver, name,
|
||||
node, &dev);
|
||||
if (ret) {
|
||||
debug("%s: not able to bind usb device mode\n",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dwc3_glue_bind(struct udevice *parent)
|
||||
{
|
||||
struct dwc3_glue_ops *ops = (struct dwc3_glue_ops *)dev_get_driver_data(parent);
|
||||
ofnode node;
|
||||
int ret;
|
||||
enum usb_dr_mode dr_mode;
|
||||
|
||||
dr_mode = usb_get_dr_mode(dev_ofnode(parent));
|
||||
if (ops && ops->glue_get_ctrl_dev) {
|
||||
ret = ops->glue_get_ctrl_dev(parent, &node);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return dwc3_glue_bind_common(parent, node);
|
||||
}
|
||||
|
||||
ofnode_for_each_subnode(node, dev_ofnode(parent)) {
|
||||
const char *name = ofnode_get_name(node);
|
||||
struct udevice *dev;
|
||||
const char *driver = NULL;
|
||||
|
||||
debug("%s: subnode name: %s\n", __func__, name);
|
||||
|
||||
/* if the parent node doesn't have a mode check the leaf */
|
||||
if (!dr_mode)
|
||||
dr_mode = usb_get_dr_mode(node);
|
||||
|
||||
switch (dr_mode) {
|
||||
case USB_DR_MODE_PERIPHERAL:
|
||||
case USB_DR_MODE_OTG:
|
||||
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
|
||||
debug("%s: dr_mode: OTG or Peripheral\n", __func__);
|
||||
driver = "dwc3-generic-peripheral";
|
||||
#endif
|
||||
break;
|
||||
#if defined(CONFIG_SPL_USB_HOST) || !defined(CONFIG_SPL_BUILD)
|
||||
case USB_DR_MODE_HOST:
|
||||
debug("%s: dr_mode: HOST\n", __func__);
|
||||
driver = "dwc3-generic-host";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
debug("%s: unsupported dr_mode\n", __func__);
|
||||
return -ENODEV;
|
||||
};
|
||||
|
||||
if (!driver)
|
||||
ret = dwc3_glue_bind_common(parent, node);
|
||||
if (ret == -ENXIO)
|
||||
continue;
|
||||
|
||||
ret = device_bind_driver_to_node(parent, driver, name,
|
||||
node, &dev);
|
||||
if (ret) {
|
||||
debug("%s: not able to bind usb device mode\n",
|
||||
__func__);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue