aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@linux.intel.com>2017-07-21 08:11:49 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-07-21 18:04:51 -0400
commit3e3119d3088f41106f3581d39e7694a50ca3fc02 (patch)
treeb7215757dd95eda454860929de50319ca5f5d432
parent37ba983cfb47cc7b353146422c437468fcb29c61 (diff)
device property: Introduce fwnode_property_get_reference_args
The new fwnode_property_get_reference_args() interface amends the fwnode property API with the functionality of both of_parse_phandle_with_args() and __acpi_node_get_property_reference(). The semantics is slightly different: the cells property is ignored on ACPI as the number of arguments can be explicitly obtained from the firmware interface. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/property.c27
-rw-r--r--drivers/base/property.c28
-rw-r--r--drivers/of/property.c31
-rw-r--r--include/linux/fwnode.h19
-rw-r--r--include/linux/property.h4
5 files changed, 109 insertions, 0 deletions
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index f8d60051efb8..681a84312dee 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -1195,6 +1195,32 @@ acpi_fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
1195 return NULL; 1195 return NULL;
1196} 1196}
1197 1197
1198static int
1199acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
1200 const char *prop, const char *nargs_prop,
1201 unsigned int args_count, unsigned int index,
1202 struct fwnode_reference_args *args)
1203{
1204 struct acpi_reference_args acpi_args;
1205 unsigned int i;
1206 int ret;
1207
1208 ret = __acpi_node_get_property_reference(fwnode, prop, index,
1209 args_count, &acpi_args);
1210 if (ret < 0)
1211 return ret;
1212 if (!args)
1213 return 0;
1214
1215 args->nargs = acpi_args.nargs;
1216 args->fwnode = acpi_fwnode_handle(acpi_args.adev);
1217
1218 for (i = 0; i < NR_FWNODE_REFERENCE_ARGS; i++)
1219 args->args[i] = i < acpi_args.nargs ? acpi_args.args[i] : 0;
1220
1221 return 0;
1222}
1223
1198static struct fwnode_handle * 1224static struct fwnode_handle *
1199acpi_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, 1225acpi_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
1200 struct fwnode_handle *prev) 1226 struct fwnode_handle *prev)
@@ -1248,6 +1274,7 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
1248 .get_parent = acpi_node_get_parent, \ 1274 .get_parent = acpi_node_get_parent, \
1249 .get_next_child_node = acpi_get_next_subnode, \ 1275 .get_next_child_node = acpi_get_next_subnode, \
1250 .get_named_child_node = acpi_fwnode_get_named_child_node, \ 1276 .get_named_child_node = acpi_fwnode_get_named_child_node, \
1277 .get_reference_args = acpi_fwnode_get_reference_args, \
1251 .graph_get_next_endpoint = \ 1278 .graph_get_next_endpoint = \
1252 acpi_fwnode_graph_get_next_endpoint, \ 1279 acpi_fwnode_graph_get_next_endpoint, \
1253 .graph_get_remote_endpoint = \ 1280 .graph_get_remote_endpoint = \
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 673e2353a2fb..d0b65bbe7e15 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -665,6 +665,34 @@ out:
665} 665}
666EXPORT_SYMBOL_GPL(fwnode_property_match_string); 666EXPORT_SYMBOL_GPL(fwnode_property_match_string);
667 667
668/**
669 * fwnode_property_get_reference_args() - Find a reference with arguments
670 * @fwnode: Firmware node where to look for the reference
671 * @prop: The name of the property
672 * @nargs_prop: The name of the property telling the number of
673 * arguments in the referred node. NULL if @nargs is known,
674 * otherwise @nargs is ignored. Only relevant on OF.
675 * @nargs: Number of arguments. Ignored if @nargs_prop is non-NULL.
676 * @index: Index of the reference, from zero onwards.
677 * @args: Result structure with reference and integer arguments.
678 *
679 * Obtain a reference based on a named property in an fwnode, with
680 * integer arguments.
681 *
682 * Caller is responsible to call fwnode_handle_put() on the returned
683 * args->fwnode pointer.
684 *
685 */
686int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
687 const char *prop, const char *nargs_prop,
688 unsigned int nargs, unsigned int index,
689 struct fwnode_reference_args *args)
690{
691 return fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop,
692 nargs, index, args);
693}
694EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
695
668static int property_copy_string_array(struct property_entry *dst, 696static int property_copy_string_array(struct property_entry *dst,
669 const struct property_entry *src) 697 const struct property_entry *src)
670{ 698{
diff --git a/drivers/of/property.c b/drivers/of/property.c
index ae46a6f0ea36..3868400972b8 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -891,6 +891,36 @@ of_fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
891 return NULL; 891 return NULL;
892} 892}
893 893
894static int
895of_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
896 const char *prop, const char *nargs_prop,
897 unsigned int nargs, unsigned int index,
898 struct fwnode_reference_args *args)
899{
900 struct of_phandle_args of_args;
901 unsigned int i;
902 int ret;
903
904 if (nargs_prop)
905 ret = of_parse_phandle_with_args(to_of_node(fwnode), prop,
906 nargs_prop, index, &of_args);
907 else
908 ret = of_parse_phandle_with_fixed_args(to_of_node(fwnode), prop,
909 nargs, index, &of_args);
910 if (ret < 0)
911 return ret;
912 if (!args)
913 return 0;
914
915 args->nargs = of_args.args_count;
916 args->fwnode = of_fwnode_handle(of_args.np);
917
918 for (i = 0; i < NR_FWNODE_REFERENCE_ARGS; i++)
919 args->args[i] = i < of_args.args_count ? of_args.args[i] : 0;
920
921 return 0;
922}
923
894static struct fwnode_handle * 924static struct fwnode_handle *
895of_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, 925of_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
896 struct fwnode_handle *prev) 926 struct fwnode_handle *prev)
@@ -949,6 +979,7 @@ const struct fwnode_operations of_fwnode_ops = {
949 .get_parent = of_fwnode_get_parent, 979 .get_parent = of_fwnode_get_parent,
950 .get_next_child_node = of_fwnode_get_next_child_node, 980 .get_next_child_node = of_fwnode_get_next_child_node,
951 .get_named_child_node = of_fwnode_get_named_child_node, 981 .get_named_child_node = of_fwnode_get_named_child_node,
982 .get_reference_args = of_fwnode_get_reference_args,
952 .graph_get_next_endpoint = of_fwnode_graph_get_next_endpoint, 983 .graph_get_next_endpoint = of_fwnode_graph_get_next_endpoint,
953 .graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint, 984 .graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint,
954 .graph_get_port_parent = of_fwnode_graph_get_port_parent, 985 .graph_get_port_parent = of_fwnode_graph_get_port_parent,
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 7b50ee4edcfc..0c35b6caf0f6 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -33,6 +33,20 @@ struct fwnode_endpoint {
33 const struct fwnode_handle *local_fwnode; 33 const struct fwnode_handle *local_fwnode;
34}; 34};
35 35
36#define NR_FWNODE_REFERENCE_ARGS 8
37
38/**
39 * struct fwnode_reference_args - Fwnode reference with additional arguments
40 * @fwnode:- A reference to the base fwnode
41 * @nargs: Number of elements in @args array
42 * @args: Integer arguments on the fwnode
43 */
44struct fwnode_reference_args {
45 struct fwnode_handle *fwnode;
46 unsigned int nargs;
47 unsigned int args[NR_FWNODE_REFERENCE_ARGS];
48};
49
36/** 50/**
37 * struct fwnode_operations - Operations for fwnode interface 51 * struct fwnode_operations - Operations for fwnode interface
38 * @get: Get a reference to an fwnode. 52 * @get: Get a reference to an fwnode.
@@ -46,6 +60,7 @@ struct fwnode_endpoint {
46 * @get_parent: Return the parent of an fwnode. 60 * @get_parent: Return the parent of an fwnode.
47 * @get_next_child_node: Return the next child node in an iteration. 61 * @get_next_child_node: Return the next child node in an iteration.
48 * @get_named_child_node: Return a child node with a given name. 62 * @get_named_child_node: Return a child node with a given name.
63 * @get_reference_args: Return a reference pointed to by a property, with args
49 * @graph_get_next_endpoint: Return an endpoint node in an iteration. 64 * @graph_get_next_endpoint: Return an endpoint node in an iteration.
50 * @graph_get_remote_endpoint: Return the remote endpoint node of a local 65 * @graph_get_remote_endpoint: Return the remote endpoint node of a local
51 * endpoint node. 66 * endpoint node.
@@ -73,6 +88,10 @@ struct fwnode_operations {
73 struct fwnode_handle * 88 struct fwnode_handle *
74 (*get_named_child_node)(const struct fwnode_handle *fwnode, 89 (*get_named_child_node)(const struct fwnode_handle *fwnode,
75 const char *name); 90 const char *name);
91 int (*get_reference_args)(const struct fwnode_handle *fwnode,
92 const char *prop, const char *nargs_prop,
93 unsigned int nargs, unsigned int index,
94 struct fwnode_reference_args *args);
76 struct fwnode_handle * 95 struct fwnode_handle *
77 (*graph_get_next_endpoint)(const struct fwnode_handle *fwnode, 96 (*graph_get_next_endpoint)(const struct fwnode_handle *fwnode,
78 struct fwnode_handle *prev); 97 struct fwnode_handle *prev);
diff --git a/include/linux/property.h b/include/linux/property.h
index edff3f89e755..6bebee13c5e0 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -73,6 +73,10 @@ int fwnode_property_read_string(const struct fwnode_handle *fwnode,
73 const char *propname, const char **val); 73 const char *propname, const char **val);
74int fwnode_property_match_string(const struct fwnode_handle *fwnode, 74int fwnode_property_match_string(const struct fwnode_handle *fwnode,
75 const char *propname, const char *string); 75 const char *propname, const char *string);
76int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
77 const char *prop, const char *nargs_prop,
78 unsigned int nargs, unsigned int index,
79 struct fwnode_reference_args *args);
76 80
77struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode); 81struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode);
78struct fwnode_handle *fwnode_get_next_parent( 82struct fwnode_handle *fwnode_get_next_parent(