Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b06184ac authored by Heikki Krogerus's avatar Heikki Krogerus Committed by Rafael J. Wysocki
Browse files

software node: Add software_node_get_reference_args()



This makes it possible to support drivers that use
fwnode_property_get_reference_args() function.

Signed-off-by: default avatarHeikki Krogerus <heikki.krogerus@linux.intel.com>
Tested-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent c959d0c2
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -560,6 +560,52 @@ software_node_get_named_child_node(const struct fwnode_handle *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_reference *ref;
	const struct property_entry *prop;
	struct fwnode_handle *refnode;
	int i;

	if (!swnode || !swnode->node->references)
		return -ENOENT;

	for (ref = swnode->node->references; ref->name; ref++)
		if (!strcmp(ref->name, propname))
			break;

	if (!ref->name || index > (ref->nrefs - 1))
		return -ENOENT;

	refnode = software_node_fwnode(ref->refs[index].node);
	if (!refnode)
		return -ENOENT;

	if (nargs_prop) {
		prop = property_entry_get(swnode->node->properties, nargs_prop);
		if (!prop)
			return -EINVAL;

		nargs = prop->value.u32_data;
	}

	if (nargs > NR_FWNODE_REFERENCE_ARGS)
		return -EINVAL;

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

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

	return 0;
}

static const struct fwnode_operations software_node_ops = {
	.get = software_node_get,
	.put = software_node_put,
@@ -569,6 +615,7 @@ static const struct fwnode_operations software_node_ops = {
	.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
};

/* -------------------------------------------------------------------------- */
+28 −0
Original line number Diff line number Diff line
@@ -332,16 +332,44 @@ int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
/* -------------------------------------------------------------------------- */
/* Software fwnode support - when HW description is incomplete or missing */

struct software_node;

/**
 * struct software_node_ref_args - Reference with additional arguments
 * @node: Reference to a software node
 * @nargs: Number of elements in @args array
 * @args: Integer arguments
 */
struct software_node_ref_args {
	const struct software_node *node;
	unsigned int nargs;
	u64 args[NR_FWNODE_REFERENCE_ARGS];
};

/**
 * struct software_node_reference - Named software node reference property
 * @name: Name of the property
 * @nrefs: Number of elements in @refs array
 * @refs: Array of references with optional arguments
 */
struct software_node_reference {
	const char *name;
	unsigned int nrefs;
	const struct software_node_ref_args *refs;
};

/**
 * struct software_node - Software node description
 * @name: Name of the software node
 * @parent: Parent of the software node
 * @properties: Array of device properties
 * @references: Array of software node reference properties
 */
struct software_node {
	const char *name;
	const struct software_node *parent;
	const struct property_entry *properties;
	const struct software_node_reference *references;
};

bool is_software_node(const struct fwnode_handle *fwnode);