// SPDX-License-Identifier: GPL-2.0
/*
 * Software nodes for the firmware node framework.
 *
 * Copyright (C) 2018, Intel Corporation
 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
 */

#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/property.h>
#include <linux/slab.h>

#include "base.h"

struct swnode {
	struct kobject kobj;
	struct fwnode_handle fwnode;
	const struct software_node *node;
	int id;

	/* hierarchy */
	struct ida child_ids;
	struct list_head entry;
	struct list_head children;
	struct swnode *parent;

	unsigned int allocated:1;
	unsigned int managed:1;
};

static DEFINE_IDA(swnode_root_ids);
static struct kset *swnode_kset;

#define kobj_to_swnode(_kobj_) container_of(_kobj_, struct swnode, kobj)

static const struct fwnode_operations software_node_ops;

bool is_software_node(const struct fwnode_handle *fwnode)
{
	return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &software_node_ops;
}
EXPORT_SYMBOL_GPL(is_software_node);

#define to_swnode(__fwnode)						\
	({								\
		typeof(__fwnode) __to_swnode_fwnode = __fwnode;		\
									\
		is_software_node(__to_swnode_fwnode) ?			\
			container_of(__to_swnode_fwnode,		\
				     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 *
software_node_to_swnode(const struct software_node *node)
{
	struct swnode *swnode = NULL;
	struct kobject *k;

	if (!node)
		return NULL;

	spin_lock(&swnode_kset->list_lock);

	list_for_each_entry(k, &swnode_kset->list, entry) {
		swnode = kobj_to_swnode(k);
		if (swnode->node == node)
			break;
		swnode = NULL;
	}

	spin_unlock(&swnode_kset->list_lock);

	return swnode;
}

const struct software_node *to_software_node(const struct fwnode_handle *fwnode)
{
	const struct swnode *swnode = to_swnode(fwnode);

	return swnode ? swnode->node : NULL;
}
EXPORT_SYMBOL_GPL(to_software_node);

struct fwnode_handle *software_node_fwnode(const struct software_node *node)
{
	struct swnode *swnode = software_node_to_swnode(node);

	return swnode ? &swnode->fwnode : NULL;
}
EXPORT_SYMBOL_GPL(software_node_fwnode);

/* -------------------------------------------------------------------------- */
/* property_entry processing */

static const struct property_entry *
property_entry_get(const struct property_entry *prop, const char *name)
{
	if (!prop)
		return NULL;

	for (; prop->name; prop++)
		if (!strcmp(name, prop->name))
			return prop;

	return NULL;
}

static const void *property_get_pointer(const struct property_entry *prop)
{
	if (!prop->length)
		return NULL;

	return prop->is_inline ? &prop->value : prop->pointer;
}

static const void *property_entry_find(const struct property_entry *props,
				       const char *propname, size_t length)
{
	const struct property_entry *prop;
	const void *pointer;

	prop = property_entry_get(props, propname);
	if (!prop)
		return ERR_PTR(-EINVAL);
	pointer = property_get_pointer(prop);
	if (!pointer)
		return ERR_PTR(-ENODATA);
	if (length > prop->length)
		return ERR_PTR(-EOVERFLOW);
	return pointer;
}

static int
property_entry_count_elems_of_size(const struct property_entry *props,
				   const char *propname, size_t length)
{
	const struct property_entry *prop;

	prop = property_entry_get(props, propname);
	if (!prop)
		return -EINVAL;

	return prop->length / length;
}

static int property_entry_read_int_array(const struct property_entry *props,
					 const char *name,
					 unsigned int elem_size, void *val,
					 size_t nval)
{
	const void *pointer;
	size_t length;

	if (!val)
		return property_entry_count_elems_of_size(props, name,
							  elem_size);

	if (!is_power_of_2(elem_size) || elem_size > sizeof(u64))
		return -ENXIO;

	length = nval * elem_size;

	pointer = property_entry_find(props, name, length);
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);

	memcpy(val, pointer, length);
	return 0;
}

static int property_entry_read_string_array(const struct property_entry *props,
					    const char *propname,
					    const char **strings, size_t nval)
{
	const void *pointer;
	size_t length;
	int array_len;

	/* Find out the array length. */
	array_len = property_entry_count_elems_of_size(props, propname,
						       sizeof(const char *));
	if (array_len < 0)
		return array_len;

	/* Return how many there are if strings is NULL. */
	if (!strings)
		return array_len;

	array_len = min_t(size_t, nval, array_len);
	length = array_len * sizeof(*strings);

	pointer = property_entry_find(props, propname, length);
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);

	memcpy(strings, pointer, length);

	return array_len;
}

static void property_entry_free_data(const struct property_entry *p)
{
	const char * const *src_str;
	size_t i, nval;

	if (p->type == DEV_PROP_STRING) {
		src_str = property_get_pointer(p);
		nval = p->length / sizeof(*src_str);
		for (i = 0; i < nval; i++)
			kfree(src_str[i]);
	}

	if (!p->is_inline)
		kfree(p->pointer);

	kfree(p->name);
}

static bool property_copy_string_array(const char **dst_ptr,
				       const char * const *src_ptr,
				       size_t nval)
{
	int i;

	for (i = 0; i < nval; i++) {
		dst_ptr[i] = kstrdup(src_ptr[i], GFP_KERNEL);
		if (!dst_ptr[i] && src_ptr[i]) {
			while (--i >= 0)
				kfree(dst_ptr[i]);
			return false;
		}
	}

	return true;
}

static int property_entry_copy_data(struct property_entry *dst,
				    const struct property_entry *src)
{
	const void *pointer = property_get_pointer(src);
	void *dst_ptr;
	size_t nval;

	/*
	 * Properties with no data should not be marked as stored
	 * out of line.
	 */
	if (!src->is_inline && !src->length)
		return -ENODATA;

	/*
	 * Reference properties are never stored inline as
	 * they are too big.
	 */
	if (src->type == DEV_PROP_REF && src->is_inline)
		return -EINVAL;

	if (src->length <= sizeof(dst->value)) {
		dst_ptr = &dst->value;
		dst->is_inline = true;
	} else {
		dst_ptr = kmalloc(src->length, GFP_KERNEL);
		if (!dst_ptr)
			return -ENOMEM;
		dst->pointer = dst_ptr;
	}

	if (src->type == DEV_PROP_STRING) {
		nval = src->length / sizeof(const char *);
		if (!property_copy_string_array(dst_ptr, pointer, nval)) {
			if (!dst->is_inline)
				kfree(dst->pointer);
			return -ENOMEM;
		}
	} else {
		memcpy(dst_ptr, pointer, src->length);
	}

	dst->length = src->length;
	dst->type = src->type;
	dst->name = kstrdup(src->name, GFP_KERNEL);
	if (!dst->name) {
		property_entry_free_data(dst);
		return -ENOMEM;
	}

	return 0;
}

/**
 * property_entries_dup - duplicate array of properties
 * @properties: array of properties to copy
 *
 * This function creates a deep copy of the given NULL-terminated array
 * of property entries.
 */
struct property_entry *
property_entries_dup(const struct property_entry *properties)
{
	struct property_entry *p;
	int i, n = 0;
	int ret;

	if (!properties)
		return NULL;

	while (properties[n].name)
		n++;

	p = kcalloc(n + 1, sizeof(*p), GFP_KERNEL);
	if (!p)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < n; i++) {
		ret = property_entry_copy_data(&p[i], &properties[i]);
		if (ret) {
			while (--i >= 0)
				property_entry_free_data(&p[i]);
			kfree(p);
			return ERR_PTR(ret);
		}
	}

	return p;
}
EXPORT_SYMBOL_GPL(property_entries_dup);

/**
 * property_entries_free - free previously allocated array of properties
 * @properties: array of properties to destroy
 *
 * This function frees given NULL-terminated array of property entries,
 * along with their data.
 */
void property_entries_free(const struct property_entry *properties)
{
	const struct property_entry *p;

	if (!properties)
		return;

	for (p = properties; p->name; p++)
		property_entry_free_data(p);

	kfree(properties);
}
EXPORT_SYMBOL_GPL(property_entries_free);

/* -------------------------------------------------------------------------- */
/* fwnode operations */

static struct fwnode_handle *software_node_get(struct fwnode_handle *fwnode)
{
	struct swnode *swnode = to_swnode(fwnode);

	kobject_get(&swnode->kobj);

	return &swnode->fwnode;
}

static void software_node_put(struct fwnode_handle *fwnode)
{
	struct swnode *swnode = to_swnode(fwnode);

	kobject_put(&swnode->kobj);
}

static bool software_node_property_present(const struct fwnode_handle *fwnode,
					   const char *propname)
{
	struct swnode *swnode = to_swnode(fwnode);

	return !!property_entry_get(swnode->node->properties, propname);
}

static int software_node_read_int_array(const struct fwnode_handle *fwnode,
					const char *propname,
					unsigned int elem_size, void *val,
					size_t nval)
{
	struct swnode *swnode = to_swnode(fwnode);

	return property_entry_read_int_array(swnode->node->properties, propname,
					     elem_size, val, nval);
}

static int software_node_read_string_array(const struct fwnode_handle *fwnode,
					   const char *propname,
					   const char **val, size_t nval)
{
	struct swnode *swnode = to_swnode(fwnode);

	return property_entry_read_string_array(swnode->node->properties,
						propname, val, nval);
}

static const char *
software_node_get_name(const struct fwnode_handle *fwnode)
{
	const struct swnode *swnode = to_swnode(fwnode);

	return kobject_name(&swnode->kobj);
}

static const char *
software_node_get_name_prefix(const struct fwnode_handle *fwnode)
{
	struct fwnode_handle *parent;
	const char *prefix;

	parent = fwnode_get_parent(fwnode);
	if (!parent)
		return "";

	/* Figure out the prefix from the parents. */
	while (is_software_node(parent))
		parent = fwnode_get_next_parent(parent);

	prefix = fwnode_get_name_prefix(parent);
	fwnode_handle_put(parent);

	/* Guess something if prefix was NULL. */
	return prefix ?: "/";
}

static struct fwnode_handle *
software_node_get_parent(const struct fwnode_handle *fwnode)
{
	struct swnode *swnode = to_swnode(fwnode);

	if (!swnode || !swnode->parent)
		return NULL;

	return fwnode_handle_get(&swnode->parent->fwnode);
}

static struct fwnode_handle *
software_node_get_next_child(const struct fwnode_handle *fwnode,
			     struct fwnode_handle *child)
{
	struct swnode *p = to_swnode(fwnode);
	struct swnode *c = to_swnode(child);

	if (!p || list_empty(&p->children) ||
	    (c && list_is_last(&c->entry, &p->children))) {
		fwnode_handle_put(child);
		return NULL;
	}

	if (c)
		c = list_next_entry(c, entry);
	else
		c = list_first_entry(&p->children, struct swnode, entry);

	fwnode_handle_put(child);
	return fwnode_handle_get(&c->fwnode);
}

static struct fwnode_handle *
software_node_get_named_child_node(const struct fwnode_handle *fwnode,
				   const char *childname)
{
	struct swnode *swnode = to_swnode(fwnode);
	struct swnode *child;

	if (!swnode || list_empty(&swnode->children))
		return NULL;

	list_for_each_entry(child, &swnode->children, entry) {
		if (!strcmp(childname, kobject_name(&child->kobj))) {
			kobject_get(&child->kobj);
			return &child->fwnode;
		}
	}
	return NULL;
}

static int
software_node_get_reference_args(const struct fwnode_handle *fwnode,
				 const char *propname, const char *nargs_prop,
				 unsigned int nargs, unsigned int index,
				 struct fwnode_reference_args *args)
{
	struct swnode *swnode = to_swnode(fwnode);
	const struct software_node_ref_args *ref_array;
	const struct software_node_ref_args *ref;
	const struct property_entry *prop;
	struct fwnode_handle *refnode;
	u32 nargs_prop_val;
	int error;
	int i;

	prop = property_entry_get(swnode->node->properties, propname);
	if (!prop)
		return -ENOENT;

	if (prop->type != DEV_PROP_REF)
		return -EINVAL;

	/*
	 * We expect that references are never stored inline, even
	 * single ones, as they are too big.
	 */
	if (prop->is_inline)
		return -EINVAL;

	if (index * sizeof(*ref) >= prop->length)
		return -ENOENT;

	ref_array = prop->pointer;
	ref = &ref_array[index];

	refnode = software_node_fwnode(ref->node);
	if (!refnode)
		return -ENOENT;

	if (nargs_prop) {
		error = property_entry_read_int_array(ref->node->properties,
						      nargs_prop, sizeof(u32),
						      &nargs_prop_val, 1);
		if (error)
			return error;

		nargs = nargs_prop_val;
	}

	if (nargs > NR_FWNODE_REFERENCE_ARGS)
		return -EINVAL;

	if (!args)
		return 0;

	args->fwnode = software_node_get(refnode);
	args->nargs = nargs;

	for (i = 0; i < nargs; i++)
		args->args[i] = ref->args[i];

	return 0;
}

static struct fwnode_handle *
swnode_graph_find_next_port(const struct fwnode_handle *parent,
			    struct fwnode_handle *port)
{
	struct fwnode_handle *old = port;

	while ((port = software_node_get_next_child(parent, old))) {
		/*
		 * fwnode ports have naming style "port@", so we search for any
		 * children that follow that convention.
		 */
		if (!strncmp(to_swnode(port)->node->name, "port@",
			     strlen("port@")))
			return port;
		old = port;
	}

	return NULL;
}

static struct fwnode_handle *
software_node_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
				      struct fwnode_handle *endpoint)
{
	struct swnode *swnode = to_swnode(fwnode);
	struct fwnode_handle *parent;
	struct fwnode_handle *port;

	if (!swnode)
		return NULL;

	if (endpoint) {
		port = software_node_get_parent(endpoint);
		parent = software_node_get_parent(port);
	} else {
		parent = software_node_get_named_child_node(fwnode, "ports");
		if (!parent)
			parent = software_node_get(&swnode->fwnode);

		port = swnode_graph_find_next_port(parent, NULL);
	}

	for (; port; port = swnode_graph_find_next_port(parent, port)) {
		endpoint = software_node_get_next_child(port, endpoint);
		if (endpoint) {
			fwnode_handle_put(port);
			break;
		}
	}

	fwnode_handle_put(parent);

	return endpoint;
}

static struct fwnode_handle *
software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
{
	struct swnode *swnode = to_swnode(fwnode);
	const struct software_node_ref_args *ref;
	const struct property_entry *prop;

	if (!swnode)
		return NULL;

	prop = property_entry_get(swnode->node->properties, "remote-endpoint");
	if (!prop || prop->type != DEV_PROP_REF || prop->is_inline)
		return NULL;

	ref = prop->pointer;

	return software_node_get(software_node_fwnode(ref[0].node));
}

static struct fwnode_handle *
software_node_graph_get_port_parent(struct fwnode_handle *fwnode)
{
	struct swnode *swnode = to_swnode(fwnode);

	swnode = swnode->parent;
	if (swnode && !strcmp(swnode->node->name, "ports"))
		swnode = swnode->parent;

	return swnode ? software_node_get(&swnode->fwnode) : NULL;
}

static int
software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode,
				   struct fwnode_endpoint *endpoint)
{
	struct swnode *swnode = to_swnode(fwnode);
	const char *parent_name = swnode->parent->node->name;
	int ret;

	if (strlen("port@") >= strlen(parent_name) ||
	    strncmp(parent_name, "port@", strlen("port@")))
		return -EINVAL;

	/* Ports have naming style "port@n", we need to select the n */
	ret = kstrtou32(parent_name + strlen("port@"), 10, &endpoint->port);
	if (ret)
		return ret;

	endpoint->id = swnode->id;
	endpoint->local_fwnode = fwnode;

	return 0;
}

static const struct fwnode_operations software_node_ops = {
	.get = software_node_get,
	.put = software_node_put,
	.property_present = software_node_property_present,
	.property_read_int_array = software_node_read_int_array,
	.property_read_string_array = software_node_read_string_array,
	.get_name = software_node_get_name,
	.get_name_prefix = software_node_get_name_prefix,
	.get_parent = software_node_get_parent,
	.get_next_child_node = software_node_get_next_child,
	.get_named_child_node = software_node_get_named_child_node,
	.get_reference_args = software_node_get_reference_args,
	.graph_get_next_endpoint = software_node_graph_get_next_endpoint,
	.graph_get_remote_endpoint = software_node_graph_get_remote_endpoint,
	.graph_get_port_parent = software_node_graph_get_port_parent,
	.graph_parse_endpoint = software_node_graph_parse_endpoint,
};

/* -------------------------------------------------------------------------- */

/**
 * software_node_find_by_name - Find software node by name
 * @parent: Parent of the software node
 * @name: Name of the software node
 *
 * The function will find a node that is child of @parent and that is named
 * @name. If no node is found, the function returns NULL.
 *
 * NOTE: you will need to drop the reference with fwnode_handle_put() after use.
 */
const struct software_node *
software_node_find_by_name(const struct software_node *parent, const char *name)
{
	struct swnode *swnode = NULL;
	struct kobject *k;

	if (!name)
		return NULL;

	spin_lock(&swnode_kset->list_lock);

	list_for_each_entry(k, &swnode_kset->list, entry) {
		swnode = kobj_to_swnode(k);
		if (parent == swnode->node->parent && swnode->node->name &&
		    !strcmp(name, swnode->node->name)) {
			kobject_get(&swnode->kobj);
			break;
		}
		swnode = NULL;
	}

	spin_unlock(&swnode_kset->list_lock);

	return swnode ? swnode->node : NULL;
}
EXPORT_SYMBOL_GPL(software_node_find_by_name);

static struct software_node *software_node_alloc(const struct property_entry *properties)
{
	struct property_entry *props;
	struct software_node *node;

	props = property_entries_dup(properties);
	if (IS_ERR(props))
		return ERR_CAST(props);

	node = kzalloc(sizeof(*node), GFP_KERNEL);
	if (!node) {
		property_entries_free(props);
		return ERR_PTR(-ENOMEM);
	}

	node->properties = props;

	return node;
}

static void software_node_free(const struct software_node *node)
{
	property_entries_free(node->properties);
	kfree(node);
}

static void software_node_release(struct kobject *kobj)
{
	struct swnode *swnode = kobj_to_swnode(kobj);

	if (swnode->parent) {
		ida_simple_remove(&swnode->parent->child_ids, swnode->id);
		list_del(&swnode->entry);
	} else {
		ida_simple_remove(&swnode_root_ids, swnode->id);
	}

	if (swnode->allocated)
		software_node_free(swnode->node);

	ida_destroy(&swnode->child_ids);
	kfree(swnode);
}

static const struct kobj_type software_node_type = {
	.release = software_node_release,
	.sysfs_ops = &kobj_sysfs_ops,
};

static struct fwnode_handle *
swnode_register(const struct software_node *node, struct swnode *parent,
		unsigned int allocated)
{
	struct swnode *swnode;
	int ret;

	swnode = kzalloc(sizeof(*swnode), GFP_KERNEL);
	if (!swnode)
		return ERR_PTR(-ENOMEM);

	ret = ida_simple_get(parent ? &parent->child_ids : &swnode_root_ids,
			     0, 0, GFP_KERNEL);
	if (ret < 0) {
		kfree(swnode);
		return ERR_PTR(ret);
	}

	swnode->id = ret;
	swnode->node = node;
	swnode->parent = parent;
	swnode->kobj.kset = swnode_kset;
	fwnode_init(&swnode->fwnode, &software_node_ops);

	ida_init(&swnode->child_ids);
	INIT_LIST_HEAD(&swnode->entry);
	INIT_LIST_HEAD(&swnode->children);

	if (node->name)
		ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
					   parent ? &parent->kobj : NULL,
					   "%s", node->name);
	else
		ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
					   parent ? &parent->kobj : NULL,
					   "node%d", swnode->id);
	if (ret) {
		kobject_put(&swnode->kobj);
		return ERR_PTR(ret);
	}

	/*
	 * Assign the flag only in the successful case, so
	 * the above kobject_put() won't mess up with properties.
	 */
	swnode->allocated = allocated;

	if (parent)
		list_add_tail(&swnode->entry, &parent->children);

	kobject_uevent(&swnode->kobj, KOBJ_ADD);
	return &swnode->fwnode;
}

/**
 * software_node_register_node_group - Register a group of software nodes
 * @node_group: NULL terminated array of software node pointers to be registered
 *
 * Register multiple software nodes at once. If any node in the array
 * has its .parent pointer set (which can only be to another software_node),
 * then its parent **must** have been registered before it is; either outside
 * of this function or by ordering the array such that parent comes before
 * child.
 */
int software_node_register_node_group(const struct software_node **node_group)
{
	unsigned int i;
	int ret;

	if (!node_group)
		return 0;

	for (i = 0; node_group[i]; i++) {
		ret = software_node_register(node_group[i]);
		if (ret) {
			software_node_unregister_node_group(node_group);
			return ret;
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(software_node_register_node_group);

/**
 * software_node_unregister_node_group - Unregister a group of software nodes
 * @node_group: NULL terminated array of software node pointers to be unregistered
 *
 * Unregister multiple software nodes at once. If parent pointers are set up
 * in any of the software nodes then the array **must** be ordered such that
 * parents come before their children.
 *
 * NOTE: If you are uncertain whether the array is ordered such that
 * parents will be unregistered before their children, it is wiser to
 * remove the nodes individually, in the correct order (child before
 * parent).
 */
void software_node_unregister_node_group(
		const struct software_node **node_group)
{
	unsigned int i = 0;

	if (!node_group)
		return;

	while (node_group[i])
		i++;

	while (i--)
		software_node_unregister(node_group[i]);
}
EXPORT_SYMBOL_GPL(software_node_unregister_node_group);

/**
 * software_node_register - Register static software node
 * @node: The software node to be registered
 */
int software_node_register(const struct software_node *node)
{
	struct swnode *parent = software_node_to_swnode(node->parent);

	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);

/**
 * software_node_unregister - Unregister static software node
 * @node: The software node to be unregistered
 */
void software_node_unregister(const struct software_node *node)
{
	struct swnode *swnode;

	swnode = software_node_to_swnode(node);
	if (swnode)
		fwnode_remove_software_node(&swnode->fwnode);
}
EXPORT_SYMBOL_GPL(software_node_unregister);

struct fwnode_handle *
fwnode_create_software_node(const struct property_entry *properties,
			    const struct fwnode_handle *parent)
{
	struct fwnode_handle *fwnode;
	struct software_node *node;
	struct swnode *p;

	if (IS_ERR(parent))
		return ERR_CAST(parent);

	p = to_swnode(parent);
	if (parent && !p)
		return ERR_PTR(-EINVAL);

	node = software_node_alloc(properties);
	if (IS_ERR(node))
		return ERR_CAST(node);

	node->parent = p ? p->node : NULL;

	fwnode = swnode_register(node, p, 1);
	if (IS_ERR(fwnode))
		software_node_free(node);

	return fwnode;
}
EXPORT_SYMBOL_GPL(fwnode_create_software_node);

void fwnode_remove_software_node(struct fwnode_handle *fwnode)
{
	struct swnode *swnode = to_swnode(fwnode);

	if (!swnode)
		return;

	kobject_put(&swnode->kobj);
}
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.
 * @node: The software 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 *node)
{
	struct swnode *swnode;
	int ret;

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

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

		swnode = software_node_to_swnode(node);
	}

	set_secondary_fwnode(dev, &swnode->fwnode);

	/*
	 * If the device has been fully registered by the time this function is
	 * called, software_node_notify() must be called separately so that the
	 * symlinks get created and the reference count of the node is kept in
	 * balance.
	 */
	if (device_is_registered(dev))
		software_node_notify(dev);

	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;

	if (device_is_registered(dev))
		software_node_notify_remove(dev);

	set_secondary_fwnode(dev, NULL);
	kobject_put(&swnode->kobj);
}
EXPORT_SYMBOL_GPL(device_remove_software_node);

/**
 * device_create_managed_software_node - Create a software node for a device
 * @dev: The device the software node is assigned to.
 * @properties: Device properties for the software node.
 * @parent: Parent of the software node.
 *
 * Creates a software node as a managed resource for @dev, which means the
 * lifetime of the newly created software node is tied to the lifetime of @dev.
 * Software nodes created with this function should not be reused or shared
 * because of that. The function takes a deep copy of @properties for the
 * software node.
 *
 * Since the new software node is assigned directly to @dev, and since it should
 * not be shared, it is not returned to the caller. The function returns 0 on
 * success, and errno in case of an error.
 */
int device_create_managed_software_node(struct device *dev,
					const struct property_entry *properties,
					const struct software_node *parent)
{
	struct fwnode_handle *p = software_node_fwnode(parent);
	struct fwnode_handle *fwnode;

	if (parent && !p)
		return -EINVAL;

	fwnode = fwnode_create_software_node(properties, p);
	if (IS_ERR(fwnode))
		return PTR_ERR(fwnode);

	to_swnode(fwnode)->managed = true;
	set_secondary_fwnode(dev, fwnode);

	if (device_is_registered(dev))
		software_node_notify(dev);

	return 0;
}
EXPORT_SYMBOL_GPL(device_create_managed_software_node);

void software_node_notify(struct device *dev)
{
	struct swnode *swnode;
	int ret;

	swnode = dev_to_swnode(dev);
	if (!swnode)
		return;

	ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node");
	if (ret)
		return;

	ret = sysfs_create_link(&swnode->kobj, &dev->kobj, dev_name(dev));
	if (ret) {
		sysfs_remove_link(&dev->kobj, "software_node");
		return;
	}

	kobject_get(&swnode->kobj);
}

void software_node_notify_remove(struct device *dev)
{
	struct swnode *swnode;

	swnode = dev_to_swnode(dev);
	if (!swnode)
		return;

	sysfs_remove_link(&swnode->kobj, dev_name(dev));
	sysfs_remove_link(&dev->kobj, "software_node");
	kobject_put(&swnode->kobj);

	if (swnode->managed) {
		set_secondary_fwnode(dev, NULL);
		kobject_put(&swnode->kobj);
	}
}

static int __init software_node_init(void)
{
	swnode_kset = kset_create_and_add("software_nodes", NULL, kernel_kobj);
	if (!swnode_kset)
		return -ENOMEM;
	return 0;
}
postcore_initcall(software_node_init);

static void __exit software_node_exit(void)
{
	ida_destroy(&swnode_root_ids);
	kset_unregister(swnode_kset);
}
__exitcall(software_node_exit);
