mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
driver core: Introduce device_{add,remove}_of_node()
An of_node can be set to a device using device_set_node(), which does not prevent any of_node and/or fwnode overwrites. When adding an of_node on an already present device, the following operations need to be done: - Attach the of_node only if no of_node is already attached - Attach the of_node as a fwnode if no fwnode were already attached This is the purpose of device_add_of_node(). device_remove_of_node() reverts the operations done by device_add_of_node(). Link: https://lore.kernel.org/r/20250224141356.36325-2-herve.codina@bootlin.com Signed-off-by: Herve Codina <herve.codina@bootlin.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring (Arm) <robh@kernel.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2014c95afe
commit
3b62449da4
|
|
@ -5170,6 +5170,67 @@ void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(set_secondary_fwnode);
|
||||
|
||||
/**
|
||||
* device_remove_of_node - Remove an of_node from a device
|
||||
* @dev: device whose device tree node is being removed
|
||||
*/
|
||||
void device_remove_of_node(struct device *dev)
|
||||
{
|
||||
dev = get_device(dev);
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
if (!dev->of_node)
|
||||
goto end;
|
||||
|
||||
if (dev->fwnode == of_fwnode_handle(dev->of_node))
|
||||
dev->fwnode = NULL;
|
||||
|
||||
of_node_put(dev->of_node);
|
||||
dev->of_node = NULL;
|
||||
|
||||
end:
|
||||
put_device(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_remove_of_node);
|
||||
|
||||
/**
|
||||
* device_add_of_node - Add an of_node to an existing device
|
||||
* @dev: device whose device tree node is being added
|
||||
* @of_node: of_node to add
|
||||
*
|
||||
* Return: 0 on success or error code on failure.
|
||||
*/
|
||||
int device_add_of_node(struct device *dev, struct device_node *of_node)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!of_node)
|
||||
return -EINVAL;
|
||||
|
||||
dev = get_device(dev);
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
if (dev->of_node) {
|
||||
dev_err(dev, "Cannot replace node %pOF with %pOF\n",
|
||||
dev->of_node, of_node);
|
||||
ret = -EBUSY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
dev->of_node = of_node_get(of_node);
|
||||
|
||||
if (!dev->fwnode)
|
||||
dev->fwnode = of_fwnode_handle(of_node);
|
||||
|
||||
ret = 0;
|
||||
end:
|
||||
put_device(dev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_add_of_node);
|
||||
|
||||
/**
|
||||
* device_set_of_node_from_dev - reuse device-tree node of another device
|
||||
* @dev: device whose device-tree node is being set
|
||||
|
|
|
|||
|
|
@ -1191,6 +1191,8 @@ int device_online(struct device *dev);
|
|||
void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
|
||||
void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
|
||||
void device_set_node(struct device *dev, struct fwnode_handle *fwnode);
|
||||
int device_add_of_node(struct device *dev, struct device_node *of_node);
|
||||
void device_remove_of_node(struct device *dev);
|
||||
void device_set_of_node_from_dev(struct device *dev, const struct device *dev2);
|
||||
|
||||
static inline struct device_node *dev_of_node(struct device *dev)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user