diff options
Diffstat (limited to 'drivers/base/core.c')
| -rw-r--r-- | drivers/base/core.c | 44 | 
1 files changed, 31 insertions, 13 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 14f165816742..6eb4c7a904c5 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -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);  | 
