Commit 7aff0fe33033fc75b61446ba29d38b1b1354af9f

Authored by Grant Likely
1 parent dcd6c92267

of: Add of_property_match_string() to find index into a string list

Add a helper function for finding the index of a string in a string
list property.  This helper is useful for bindings that use a separate
*-name property for attaching names to tuples in another property such
as 'reg' or 'gpios'.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

Showing 4 changed files with 70 additions and 0 deletions Side-by-side Diff

arch/arm/boot/dts/testcases/tests-phandle.dtsi
... ... @@ -31,6 +31,8 @@
31 31 phandle-list-bad-phandle = <12345678 0 0>;
32 32 phandle-list-bad-args = <&provider2 1 0>,
33 33 <&provider3 0>;
  34 + empty-property;
  35 + unterminated-string = [40 41 42 43];
34 36 };
35 37 };
36 38 };
... ... @@ -761,6 +761,42 @@
761 761 }
762 762 EXPORT_SYMBOL_GPL(of_property_read_string_index);
763 763  
  764 +/**
  765 + * of_property_match_string() - Find string in a list and return index
  766 + * @np: pointer to node containing string list property
  767 + * @propname: string list property name
  768 + * @string: pointer to string to search for in string list
  769 + *
  770 + * This function searches a string list property and returns the index
  771 + * of a specific string value.
  772 + */
  773 +int of_property_match_string(struct device_node *np, const char *propname,
  774 + const char *string)
  775 +{
  776 + struct property *prop = of_find_property(np, propname, NULL);
  777 + size_t l;
  778 + int i;
  779 + const char *p, *end;
  780 +
  781 + if (!prop)
  782 + return -EINVAL;
  783 + if (!prop->value)
  784 + return -ENODATA;
  785 +
  786 + p = prop->value;
  787 + end = p + prop->length;
  788 +
  789 + for (i = 0; p < end; i++, p += l) {
  790 + l = strlen(p) + 1;
  791 + if (p + l > end)
  792 + return -EILSEQ;
  793 + pr_debug("comparing %s with %s\n", string, p);
  794 + if (strcmp(string, p) == 0)
  795 + return i; /* Found it; return index */
  796 + }
  797 + return -ENODATA;
  798 +}
  799 +EXPORT_SYMBOL_GPL(of_property_match_string);
764 800  
765 801 /**
766 802 * of_property_count_strings - Find and return the number of strings from a
drivers/of/selftest.c
... ... @@ -120,6 +120,34 @@
120 120 pr_info("end - %s\n", passed_all ? "PASS" : "FAIL");
121 121 }
122 122  
  123 +static void __init of_selftest_property_match_string(void)
  124 +{
  125 + struct device_node *np;
  126 + int rc;
  127 +
  128 + pr_info("start\n");
  129 + np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
  130 + if (!np) {
  131 + pr_err("No testcase data in device tree\n");
  132 + return;
  133 + }
  134 +
  135 + rc = of_property_match_string(np, "phandle-list-names", "first");
  136 + selftest(rc == 0, "first expected:0 got:%i\n", rc);
  137 + rc = of_property_match_string(np, "phandle-list-names", "second");
  138 + selftest(rc == 1, "second expected:0 got:%i\n", rc);
  139 + rc = of_property_match_string(np, "phandle-list-names", "third");
  140 + selftest(rc == 2, "third expected:0 got:%i\n", rc);
  141 + rc = of_property_match_string(np, "phandle-list-names", "fourth");
  142 + selftest(rc == -ENODATA, "unmatched string; rc=%i", rc);
  143 + rc = of_property_match_string(np, "missing-property", "blah");
  144 + selftest(rc == -EINVAL, "missing property; rc=%i", rc);
  145 + rc = of_property_match_string(np, "empty-property", "blah");
  146 + selftest(rc == -ENODATA, "empty property; rc=%i", rc);
  147 + rc = of_property_match_string(np, "unterminated-string", "blah");
  148 + selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc);
  149 +}
  150 +
123 151 static int __init of_selftest(void)
124 152 {
125 153 struct device_node *np;
... ... @@ -133,6 +161,7 @@
133 161  
134 162 pr_info("start of selftest - you will see error messages\n");
135 163 of_selftest_parse_phandle_with_args();
  164 + of_selftest_property_match_string();
136 165 pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL");
137 166 return 0;
138 167 }
... ... @@ -217,6 +217,9 @@
217 217 extern int of_property_read_string_index(struct device_node *np,
218 218 const char *propname,
219 219 int index, const char **output);
  220 +extern int of_property_match_string(struct device_node *np,
  221 + const char *propname,
  222 + const char *string);
220 223 extern int of_property_count_strings(struct device_node *np,
221 224 const char *propname);
222 225 extern int of_device_is_compatible(const struct device_node *device,