Hi Peter,

I'm trying to create device tree nodes for USB devices (use case a USB device providing GPIO and I2C controllers)

Your patch (now merged)
    69bec725  "USB: core: let USB device know device node"

looks just like what I need but I have a couple of problems.

First it doesn't work at all on an i.MX53 because the actual struct device for the USB host controller is a "ci_hdrc" which is a child of the device having the DT node (ci_hdrc_imx)

I can fix that by accepting parent devices too like this:


--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -466,12 +466,23 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
         * cardbus or pci hotplugging, and so on.
         */
        if (unlikely(!parent)) {
+               struct device *cdev = bus->controller;
+
                dev->devpath[0] = '0';
                dev->route = 0;

                dev->dev.parent = bus->controller;
-               dev->dev.of_node = bus->controller->of_node;
+
+               do {
+                       dev->dev.of_node = cdev->of_node;
+                       cdev = cdev->parent;
+               } while(!dev->dev.of_node && cdev);
+
                dev_set_name(&dev->dev, "usb%d", bus->busnum);


(I can submit this properly if we agree it's the right way - I'm not sure if this should be fixed in the core or if ci_hdrc should set its DT node to be the same as its parent)

However my larger question is that I don't see how to associate a DT node with a USB *interface* rather than a USB *device*.

For instance in my use case I will have a single USB device providing several USB interfaces (a composite device), including a GPIO controller and a I2C controller. So I need 2 DT nodes...

There may be something in the the URL referenced in the binding doc (http://www.firmware.org/1275/bindings/usb/usb-1_0.ps)
but that seems to be down (at least has been for the last few days).
I also don't see any code that actually uses the compatible property anyway (even the VID/PID compatible)

Is this something missing, still in progress, or is each driver supposed to handle it on its own?

That would be *possible* something like:

static int usb_gpio_probe(struct usb_interface *interface,
                  const struct usb_device_id *id)
{
    struct device *dev = &interface->dev;
    struct device_node *usb_dev_np = dev->parent->of_node;

struct device_node *usb_itf_np = of_get_child_by_name(usb_dev_np, "gpio");

    ...
}

With
&usbotg {
    #address-cells = <1>;
    #size-cells = <0>;

    hub_board {
        #address-cells = <1>;
        #size-cells = <0>;
        compatible = "pid,vid";
        reg = <1>;

        ext_usb {
            compatible = "pid2,vid2";
            reg = <2>;

            usb_gpio: gpio {
            }
        };
    };
};


But this doesn't seem like a very good idea since we're then likely to grow lots of different driver specific ways of doing the same thing. Eg above I used a child node named "gpio" but it would probably have been better to use the interface number in the node name in case there are several. And what about matching by interface class...

I think a "struct device_node *" should be added to struct usb_interface and the matching be done in the usb core code. Which means expressing in the DT as well all the different ways we can match a USB interface.

Regards,

Martin



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to