]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
USB: of: fix root-hub device-tree node handling
authorJohan Hovold <johan@kernel.org>
Tue, 6 Jun 2017 15:59:02 +0000 (17:59 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Jun 2017 09:07:32 +0000 (11:07 +0200)
In an attempt to work around a pinmux over-allocation issue in driver
core, commit dc5878abf49c ("usb: core: move root hub's device node
assignment after it is added to bus") moved the device-tree node
assignment until after the root hub had been registered.

This not only makes the device-tree node unavailable to the usb driver
during probe, but also prevents the of_node from being linked to in
sysfs and causes a race with user-space for the (recently added) devspec
attribute.

Use the new device_set_of_node_from_dev() helper to reuse the node of
the sysdev device, something which now prevents driver core from trying
to reclaim any pinctrl pins during probe.

Fixes: dc5878abf49c ("usb: core: move root hub's device node assignment after it is added to bus")
Fixes: 51fa91475e43 ("usb/core: Added devspec sysfs entry for devices behind the usb hub")
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/hcd.c
drivers/usb/core/usb.c

index e72cbc75161919622e517c2d74d9deb04ef43367..ab1bb3b538ac6175dd1fbe5babb686a6a8f4bc49 100644 (file)
@@ -1077,7 +1077,6 @@ static void usb_deregister_bus (struct usb_bus *bus)
 static int register_root_hub(struct usb_hcd *hcd)
 {
        struct device *parent_dev = hcd->self.controller;
-       struct device *sysdev = hcd->self.sysdev;
        struct usb_device *usb_dev = hcd->self.root_hub;
        const int devnum = 1;
        int retval;
@@ -1124,7 +1123,6 @@ static int register_root_hub(struct usb_hcd *hcd)
                /* Did the HC die before the root hub was registered? */
                if (HCD_DEAD(hcd))
                        usb_hc_died (hcd);      /* This time clean up */
-               usb_dev->dev.of_node = sysdev->of_node;
        }
        mutex_unlock(&usb_bus_idr_lock);
 
index 62e1906bb2f31d2e76afc0661c942711fcf44765..17681d5638ac3ff418dbec8eb8254c4b4e6e7727 100644 (file)
@@ -416,8 +416,7 @@ static void usb_release_dev(struct device *dev)
 
        usb_destroy_configuration(udev);
        usb_release_bos_descriptor(udev);
-       if (udev->parent)
-               of_node_put(dev->of_node);
+       of_node_put(dev->of_node);
        usb_put_hcd(hcd);
        kfree(udev->product);
        kfree(udev->manufacturer);
@@ -616,6 +615,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
                dev->route = 0;
 
                dev->dev.parent = bus->controller;
+               device_set_of_node_from_dev(&dev->dev, bus->sysdev);
                dev_set_name(&dev->dev, "usb%d", bus->busnum);
                root_hub = 1;
        } else {