Commit 26141008 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull device properties framework fixes from Rafael Wysocki:
 "Prevent software nodes from being registered before their parents and
  fix a recent mistake causing already registered software nodes to be
  registered again in some cases (Heikki Krogerus)"

* tag 'devprop-5.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  software node: Fix device_add_software_node()
  software node: Fix node registration
parents 3077f027 2a92c90f
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
@@ -938,6 +938,9 @@ int software_node_register(const struct software_node *node)
	if (software_node_to_swnode(node))
		return -EEXIST;

	if (node->parent && !parent)
		return -EINVAL;

	return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0));
}
EXPORT_SYMBOL_GPL(software_node_register);
@@ -1002,25 +1005,33 @@ EXPORT_SYMBOL_GPL(fwnode_remove_software_node);
/**
 * device_add_software_node - Assign software node to a device
 * @dev: The device the software node is meant for.
 * @swnode: The software node.
 * @node: The software node.
 *
 * This function will register @swnode and make it the secondary firmware node
 * pointer of @dev. If @dev has no primary node, then @swnode will become the primary
 * node.
 * This function will make @node the secondary firmware node pointer of @dev. If
 * @dev has no primary node, then @node will become the primary node. The
 * function will register @node automatically if it wasn't already registered.
 */
int device_add_software_node(struct device *dev, const struct software_node *swnode)
int device_add_software_node(struct device *dev, const struct software_node *node)
{
	struct swnode *swnode;
	int ret;

	/* Only one software node per device. */
	if (dev_to_swnode(dev))
		return -EBUSY;

	ret = software_node_register(swnode);
	swnode = software_node_to_swnode(node);
	if (swnode) {
		kobject_get(&swnode->kobj);
	} else {
		ret = software_node_register(node);
		if (ret)
			return ret;

	set_secondary_fwnode(dev, software_node_fwnode(swnode));
		swnode = software_node_to_swnode(node);
	}

	set_secondary_fwnode(dev, &swnode->fwnode);

	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -488,7 +488,7 @@ fwnode_create_software_node(const struct property_entry *properties,
			    const struct fwnode_handle *parent);
void fwnode_remove_software_node(struct fwnode_handle *fwnode);

int device_add_software_node(struct device *dev, const struct software_node *swnode);
int device_add_software_node(struct device *dev, const struct software_node *node);
void device_remove_software_node(struct device *dev);

int device_create_managed_software_node(struct device *dev,