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: 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>
This commit is contained in:
Heikki Krogerus 2019-05-31 17:15:36 +03:00 committed by Rafael J. Wysocki
parent c959d0c231
commit b06184acf7
2 changed files with 75 additions and 0 deletions

View File

@ -560,6 +560,52 @@ software_node_get_named_child_node(const struct fwnode_handle *fwnode,
return NULL; 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 = { static const struct fwnode_operations software_node_ops = {
.get = software_node_get, .get = software_node_get,
.put = software_node_put, .put = software_node_put,
@ -569,6 +615,7 @@ static const struct fwnode_operations software_node_ops = {
.get_parent = software_node_get_parent, .get_parent = software_node_get_parent,
.get_next_child_node = software_node_get_next_child, .get_next_child_node = software_node_get_next_child,
.get_named_child_node = software_node_get_named_child_node, .get_named_child_node = software_node_get_named_child_node,
.get_reference_args = software_node_get_reference_args
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View File

@ -332,16 +332,44 @@ int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Software fwnode support - when HW description is incomplete or missing */ /* 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 * struct software_node - Software node description
* @name: Name of the software node * @name: Name of the software node
* @parent: Parent of the software node * @parent: Parent of the software node
* @properties: Array of device properties * @properties: Array of device properties
* @references: Array of software node reference properties
*/ */
struct software_node { struct software_node {
const char *name; const char *name;
const struct software_node *parent; const struct software_node *parent;
const struct property_entry *properties; const struct property_entry *properties;
const struct software_node_reference *references;
}; };
bool is_software_node(const struct fwnode_handle *fwnode); bool is_software_node(const struct fwnode_handle *fwnode);