Skip to content

Commit

Permalink
software node: Add software_node_get_reference_args()
Browse files Browse the repository at this point in the history
This makes it possible to support drivers that use
fwnode_property_get_reference_args() function.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Heikki Krogerus authored and Rafael J. Wysocki committed Jun 3, 2019
1 parent c959d0c commit b06184a
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
47 changes: 47 additions & 0 deletions drivers/base/swnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
};

/* -------------------------------------------------------------------------- */
Expand Down
28 changes: 28 additions & 0 deletions include/linux/property.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit b06184a

Please sign in to comment.