Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2bf69867 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

USB: of: fix root-hub device-tree node handling



In an attempt to work around a pinmux over-allocation issue in driver
core, commit dc5878ab ("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: dc5878ab ("usb: core: move root hub's device node assignment after it is added to bus")
Fixes: 51fa9147 ("usb/core: Added devspec sysfs entry for devices behind the usb hub")
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ed032c1b
Loading
Loading
Loading
Loading
+0 −2
Original line number Original line Diff line number Diff line
@@ -1077,7 +1077,6 @@ static void usb_deregister_bus (struct usb_bus *bus)
static int register_root_hub(struct usb_hcd *hcd)
static int register_root_hub(struct usb_hcd *hcd)
{
{
	struct device *parent_dev = hcd->self.controller;
	struct device *parent_dev = hcd->self.controller;
	struct device *sysdev = hcd->self.sysdev;
	struct usb_device *usb_dev = hcd->self.root_hub;
	struct usb_device *usb_dev = hcd->self.root_hub;
	const int devnum = 1;
	const int devnum = 1;
	int retval;
	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? */
		/* Did the HC die before the root hub was registered? */
		if (HCD_DEAD(hcd))
		if (HCD_DEAD(hcd))
			usb_hc_died (hcd);	/* This time clean up */
			usb_hc_died (hcd);	/* This time clean up */
		usb_dev->dev.of_node = sysdev->of_node;
	}
	}
	mutex_unlock(&usb_bus_idr_lock);
	mutex_unlock(&usb_bus_idr_lock);


+2 −2
Original line number Original line Diff line number Diff line
@@ -416,7 +416,6 @@ static void usb_release_dev(struct device *dev)


	usb_destroy_configuration(udev);
	usb_destroy_configuration(udev);
	usb_release_bos_descriptor(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);
	usb_put_hcd(hcd);
	kfree(udev->product);
	kfree(udev->product);
@@ -616,6 +615,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
		dev->route = 0;
		dev->route = 0;


		dev->dev.parent = bus->controller;
		dev->dev.parent = bus->controller;
		device_set_of_node_from_dev(&dev->dev, bus->sysdev);
		dev_set_name(&dev->dev, "usb%d", bus->busnum);
		dev_set_name(&dev->dev, "usb%d", bus->busnum);
		root_hub = 1;
		root_hub = 1;
	} else {
	} else {