On Thu, May 21, 2020 at 12:40 AM Michael Walle <mich...@walle.cc> wrote: > > It is possible to specify a device tree node for an USB device. This is > useful if you have a static USB setup and want to use aliases which > point to these nodes, like on the Raspberry Pi. > The nodes are matched against their hub port number, the compatible > strings are not matched for now. > > Signed-off-by: Michael Walle <mich...@walle.cc> > --- > This is a new patch in v5: > Fixes the ethernet0 alias on Raspberry Pis. This has never been > working, but wasn't a problem until recently. Patch 2/2 changes > the allocation of the numbers and reserves possible aliases. > > drivers/usb/host/usb-uclass.c | 41 ++++++++++++++++++++++++++++++----- > 1 file changed, 36 insertions(+), 5 deletions(-) > > diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c > index cb79dfbbd5..f42c0625cb 100644 > --- a/drivers/usb/host/usb-uclass.c > +++ b/drivers/usb/host/usb-uclass.c > @@ -494,6 +494,35 @@ static int usb_match_one_id(struct usb_device_descriptor > *desc, > return usb_match_one_id_intf(desc, int_desc, id); > } > > +static ofnode usb_get_ofnode(struct udevice *hub, int port) > +{ > + ofnode node; > + u32 reg; > + > + if (!dev_has_of_node(hub)) > + return ofnode_null(); > + > + /* > + * The USB controller and its USB hub are two different udevices, > + * but the device tree has only one node for both. Thus we are > + * assigning this node to both udevices. > + * If port is zero, the controller scans its root hub, thus we > + * are using the same ofnode as the controller here. > + */ > + if (!port) > + return dev_ofnode(hub); > + > + ofnode_for_each_subnode(node, dev_ofnode(hub)) { > + if (ofnode_read_u32(node, "reg", ®)) > + continue; > + > + if (reg == port) > + return node; > + } > + > + return ofnode_null(); > +} > + > /** > * usb_find_and_bind_driver() - Find and bind the right USB driver > * > @@ -502,13 +531,14 @@ static int usb_match_one_id(struct > usb_device_descriptor *desc, > static int usb_find_and_bind_driver(struct udevice *parent, > struct usb_device_descriptor *desc, > struct usb_interface_descriptor *iface, > - int bus_seq, int devnum, > + int bus_seq, int devnum, int port, > struct udevice **devp) > { > struct usb_driver_entry *start, *entry; > int n_ents; > int ret; > char name[30], *str; > + ofnode node = usb_get_ofnode(parent, port); > > *devp = NULL; > debug("%s: Searching for driver\n", __func__); > @@ -533,8 +563,8 @@ static int usb_find_and_bind_driver(struct udevice > *parent, > * find another driver. For now this doesn't seem > * necesssary, so just bind the first match. > */ > - ret = device_bind(parent, drv, drv->name, NULL, -1, > - &dev); > + ret = device_bind_ofnode(parent, drv, drv->name, NULL, > + node, &dev); > if (ret) > goto error; > debug("%s: Match found: %s\n", __func__, drv->name); > @@ -651,9 +681,10 @@ int usb_scan_device(struct udevice *parent, int port, > if (ret) { > if (ret != -ENOENT) > return ret; > - ret = usb_find_and_bind_driver(parent, &udev->descriptor, > iface, > + ret = usb_find_and_bind_driver(parent, &udev->descriptor, > + iface, > udev->controller_dev->seq, > - udev->devnum, &dev); > + udev->devnum, port, &dev); > if (ret) > return ret; > created = true; > --
Do we have tests added ? Regards, Bin