Commit 7aff0fe33033fc75b61446ba29d38b1b1354af9f
1 parent
dcd6c92267
Exists in
master
and in
20 other branches
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
drivers/of/base.c
... | ... | @@ -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 | } |
include/linux/of.h
... | ... | @@ -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, |