Commit 443d1129 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'driver-core-5.11-rc5' of...

Merge tag 'driver-core-5.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core fixes from Greg KH:
 "Here are some small driver core fixes for 5.11-rc5 that resolve some
  reported problems:

   - revert of a -rc1 patch that was causing problems with some machines

   - device link device name collision problem fix (busses only have to
     name devices unique to their bus, not unique to all busses)

   - kernfs splice bugfixes to resolve firmware loading problems for
     Qualcomm systems.

   - other tiny driver core fixes for minor issues reported.

  All of these have been in linux-next with no reported problems"

* tag 'driver-core-5.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
  driver core: Fix device link device name collision
  driver core: Extend device_is_dependent()
  kernfs: wire up ->splice_read and ->splice_write
  kernfs: implement ->write_iter
  kernfs: implement ->read_iter
  Revert "driver core: Reorder devices on successful probe"
  Driver core: platform: Add extra error check in devm_platform_get_irqs_affinity()
  drivers core: Free dma_range_map when driver probe failed
parents 832bceef e020ff61
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -5,8 +5,8 @@ Description:
		Provide a place in sysfs for the device link objects in the
		kernel at any given time.  The name of a device link directory,
		denoted as ... above, is of the form <supplier>--<consumer>
		where <supplier> is the supplier device name and <consumer> is
		the consumer device name.
		where <supplier> is the supplier bus:device name and <consumer>
		is the consumer bus:device name.

What:		/sys/class/devlink/.../auto_remove_on
Date:		May 2020
+3 −2
Original line number Diff line number Diff line
@@ -4,5 +4,6 @@ Contact: Saravana Kannan <saravanak@google.com>
Description:
		The /sys/devices/.../consumer:<consumer> are symlinks to device
		links where this device is the supplier. <consumer> denotes the
		name of the consumer in that device link. There can be zero or
		more of these symlinks for a given device.
		name of the consumer in that device link and is of the form
		bus:device name. There can be zero or more of these symlinks
		for a given device.
+3 −2
Original line number Diff line number Diff line
@@ -4,5 +4,6 @@ Contact: Saravana Kannan <saravanak@google.com>
Description:
		The /sys/devices/.../supplier:<supplier> are symlinks to device
		links where this device is the consumer. <supplier> denotes the
		name of the supplier in that device link. There can be zero or
		more of these symlinks for a given device.
		name of the supplier in that device link and is of the form
		bus:device name. There can be zero or more of these symlinks
		for a given device.
+31 −13
Original line number Diff line number Diff line
@@ -208,6 +208,16 @@ int device_links_read_lock_held(void)
#endif
#endif /* !CONFIG_SRCU */

static bool device_is_ancestor(struct device *dev, struct device *target)
{
	while (target->parent) {
		target = target->parent;
		if (dev == target)
			return true;
	}
	return false;
}

/**
 * device_is_dependent - Check if one device depends on another one
 * @dev: Device to check dependencies for.
@@ -221,7 +231,12 @@ int device_is_dependent(struct device *dev, void *target)
	struct device_link *link;
	int ret;

	if (dev == target)
	/*
	 * The "ancestors" check is needed to catch the case when the target
	 * device has not been completely initialized yet and it is still
	 * missing from the list of children of its parent device.
	 */
	if (dev == target || device_is_ancestor(dev, target))
		return 1;

	ret = device_for_each_child(dev, target, device_is_dependent);
@@ -456,7 +471,9 @@ static int devlink_add_symlinks(struct device *dev,
	struct device *con = link->consumer;
	char *buf;

	len = max(strlen(dev_name(sup)), strlen(dev_name(con)));
	len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)),
		  strlen(dev_bus_name(con)) + strlen(dev_name(con)));
	len += strlen(":");
	len += strlen("supplier:") + 1;
	buf = kzalloc(len, GFP_KERNEL);
	if (!buf)
@@ -470,12 +487,12 @@ static int devlink_add_symlinks(struct device *dev,
	if (ret)
		goto err_con;

	snprintf(buf, len, "consumer:%s", dev_name(con));
	snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con));
	ret = sysfs_create_link(&sup->kobj, &link->link_dev.kobj, buf);
	if (ret)
		goto err_con_dev;

	snprintf(buf, len, "supplier:%s", dev_name(sup));
	snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup));
	ret = sysfs_create_link(&con->kobj, &link->link_dev.kobj, buf);
	if (ret)
		goto err_sup_dev;
@@ -483,7 +500,7 @@ static int devlink_add_symlinks(struct device *dev,
	goto out;

err_sup_dev:
	snprintf(buf, len, "consumer:%s", dev_name(con));
	snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con));
	sysfs_remove_link(&sup->kobj, buf);
err_con_dev:
	sysfs_remove_link(&link->link_dev.kobj, "consumer");
@@ -506,7 +523,9 @@ static void devlink_remove_symlinks(struct device *dev,
	sysfs_remove_link(&link->link_dev.kobj, "consumer");
	sysfs_remove_link(&link->link_dev.kobj, "supplier");

	len = max(strlen(dev_name(sup)), strlen(dev_name(con)));
	len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)),
		  strlen(dev_bus_name(con)) + strlen(dev_name(con)));
	len += strlen(":");
	len += strlen("supplier:") + 1;
	buf = kzalloc(len, GFP_KERNEL);
	if (!buf) {
@@ -514,9 +533,9 @@ static void devlink_remove_symlinks(struct device *dev,
		return;
	}

	snprintf(buf, len, "supplier:%s", dev_name(sup));
	snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup));
	sysfs_remove_link(&con->kobj, buf);
	snprintf(buf, len, "consumer:%s", dev_name(con));
	snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con));
	sysfs_remove_link(&sup->kobj, buf);
	kfree(buf);
}
@@ -737,8 +756,9 @@ struct device_link *device_link_add(struct device *consumer,

	link->link_dev.class = &devlink_class;
	device_set_pm_not_required(&link->link_dev);
	dev_set_name(&link->link_dev, "%s--%s",
		     dev_name(supplier), dev_name(consumer));
	dev_set_name(&link->link_dev, "%s:%s--%s:%s",
		     dev_bus_name(supplier), dev_name(supplier),
		     dev_bus_name(consumer), dev_name(consumer));
	if (device_register(&link->link_dev)) {
		put_device(consumer);
		put_device(supplier);
@@ -1808,9 +1828,7 @@ const char *dev_driver_string(const struct device *dev)
	 * never change once they are set, so they don't need special care.
	 */
	drv = READ_ONCE(dev->driver);
	return drv ? drv->name :
			(dev->bus ? dev->bus->name :
			(dev->class ? dev->class->name : ""));
	return drv ? drv->name : dev_bus_name(dev);
}
EXPORT_SYMBOL(dev_driver_string);

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

	device_pm_check_callbacks(dev);

	/*
	 * Reorder successfully probed devices to the end of the device list.
	 * This ensures that suspend/resume order matches probe order, which
	 * is usually what drivers rely on.
	 */
	device_pm_move_to_tail(dev);

	/*
	 * Make sure the device is no longer in one of the deferred lists and
	 * kick off retrying all pending devices
@@ -619,6 +612,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
	else if (drv->remove)
		drv->remove(dev);
probe_failed:
	kfree(dev->dma_range_map);
	dev->dma_range_map = NULL;
	if (dev->bus)
		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
Loading