mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-01 06:33:07 +00:00
software node: Introduce device_add_software_node()
This helper will register a software node and then assign it to device at the same time. The function will also make sure that the device can't have more than one software node. Acked-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Link: https://lore.kernel.org/r/20210115094914.88401-2-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c86cad04dc
commit
e68d0119e3
2 changed files with 65 additions and 9 deletions
|
@ -48,6 +48,19 @@ EXPORT_SYMBOL_GPL(is_software_node);
|
||||||
struct swnode, fwnode) : NULL; \
|
struct swnode, fwnode) : NULL; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
static inline struct swnode *dev_to_swnode(struct device *dev)
|
||||||
|
{
|
||||||
|
struct fwnode_handle *fwnode = dev_fwnode(dev);
|
||||||
|
|
||||||
|
if (!fwnode)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!is_software_node(fwnode))
|
||||||
|
fwnode = fwnode->secondary;
|
||||||
|
|
||||||
|
return to_swnode(fwnode);
|
||||||
|
}
|
||||||
|
|
||||||
static struct swnode *
|
static struct swnode *
|
||||||
software_node_to_swnode(const struct software_node *node)
|
software_node_to_swnode(const struct software_node *node)
|
||||||
{
|
{
|
||||||
|
@ -843,22 +856,62 @@ void fwnode_remove_software_node(struct fwnode_handle *fwnode)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(fwnode_remove_software_node);
|
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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
int device_add_software_node(struct device *dev, const struct software_node *swnode)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Only one software node per device. */
|
||||||
|
if (dev_to_swnode(dev))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
ret = software_node_register(swnode);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
set_secondary_fwnode(dev, software_node_fwnode(swnode));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(device_add_software_node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* device_remove_software_node - Remove device's software node
|
||||||
|
* @dev: The device with the software node.
|
||||||
|
*
|
||||||
|
* This function will unregister the software node of @dev.
|
||||||
|
*/
|
||||||
|
void device_remove_software_node(struct device *dev)
|
||||||
|
{
|
||||||
|
struct swnode *swnode;
|
||||||
|
|
||||||
|
swnode = dev_to_swnode(dev);
|
||||||
|
if (!swnode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
software_node_notify(dev, KOBJ_REMOVE);
|
||||||
|
set_secondary_fwnode(dev, NULL);
|
||||||
|
kobject_put(&swnode->kobj);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(device_remove_software_node);
|
||||||
|
|
||||||
int software_node_notify(struct device *dev, unsigned long action)
|
int software_node_notify(struct device *dev, unsigned long action)
|
||||||
{
|
{
|
||||||
struct fwnode_handle *fwnode = dev_fwnode(dev);
|
|
||||||
struct swnode *swnode;
|
struct swnode *swnode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!fwnode)
|
swnode = dev_to_swnode(dev);
|
||||||
|
if (!swnode)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!is_software_node(fwnode))
|
|
||||||
fwnode = fwnode->secondary;
|
|
||||||
if (!is_software_node(fwnode))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
swnode = to_swnode(fwnode);
|
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case KOBJ_ADD:
|
case KOBJ_ADD:
|
||||||
ret = sysfs_create_link(&dev->kobj, &swnode->kobj,
|
ret = sysfs_create_link(&dev->kobj, &swnode->kobj,
|
||||||
|
|
|
@ -488,4 +488,7 @@ fwnode_create_software_node(const struct property_entry *properties,
|
||||||
const struct fwnode_handle *parent);
|
const struct fwnode_handle *parent);
|
||||||
void fwnode_remove_software_node(struct fwnode_handle *fwnode);
|
void fwnode_remove_software_node(struct fwnode_handle *fwnode);
|
||||||
|
|
||||||
|
int device_add_software_node(struct device *dev, const struct software_node *swnode);
|
||||||
|
void device_remove_software_node(struct device *dev);
|
||||||
|
|
||||||
#endif /* _LINUX_PROPERTY_H_ */
|
#endif /* _LINUX_PROPERTY_H_ */
|
||||||
|
|
Loading…
Reference in a new issue