software node: Add software_node_get_reference_args()
authorHeikki Krogerus <heikki.krogerus@linux.intel.com>
Fri, 31 May 2019 14:15:36 +0000 (17:15 +0300)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 3 Jun 2019 08:55:38 +0000 (10:55 +0200)
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>
drivers/base/swnode.c
include/linux/property.h

index 2d925fc2255fa2f8a08555e03be51a1d3b6a5a26..e7b3aa3bd55addce693e796f8c8c289f3ee1dfff 100644 (file)
@@ -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
 };
 
 /* -------------------------------------------------------------------------- */
index a3813ded52ea5daf38f187377dc6aeb2dc4eb036..abcde2f236a06d336e7c1edafdc9d7305307a829 100644 (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 */
 
+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);