Commit bc575064 authored by Rob Herring's avatar Rob Herring

of/device: use of_property_for_each_string to parse compatible strings

Instead of directly parsing the compatible property, use the
of_property_for_each_string() helper to iterate over each compatible
string. This reduces the LoC and makes the functions easier to
understand.
Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent 7c6ffa0b
...@@ -195,9 +195,10 @@ EXPORT_SYMBOL(of_device_get_match_data); ...@@ -195,9 +195,10 @@ EXPORT_SYMBOL(of_device_get_match_data);
static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
{ {
const char *compat; const char *compat, *start = str;
int cplen, i; char *c;
ssize_t tsize, csize, repend; struct property *p;
ssize_t csize;
if ((!dev) || (!dev->of_node)) if ((!dev) || (!dev->of_node))
return -ENODEV; return -ENODEV;
...@@ -205,42 +206,24 @@ static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len ...@@ -205,42 +206,24 @@ static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len
/* Name & Type */ /* Name & Type */
csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name, csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name,
dev->of_node->type); dev->of_node->type);
len -= csize;
/* Get compatible property if any */ str += csize;
compat = of_get_property(dev->of_node, "compatible", &cplen);
if (!compat) of_property_for_each_string(dev->of_node, "compatible", p, compat) {
return csize; if (strlen(compat) + 2 > len)
break;
/* Find true end (we tolerate multiple \0 at the end */
for (i = (cplen - 1); i >= 0 && !compat[i]; i--) csize = snprintf(str, len, "C%s", compat);
cplen--; for (c = str; c; ) {
if (!cplen) c = strchr(c, ' ');
return csize; if (c)
cplen++; *c++ = '_';
}
/* Check space (need cplen+1 chars including final \0) */ len -= csize;
tsize = csize + cplen; str += csize;
repend = tsize;
if (csize >= len) /* @ the limit, all is already filled */
return tsize;
if (tsize >= len) { /* limit compat list */
cplen = len - csize - 1;
repend = len;
}
/* Copy and do char replacement */
memcpy(&str[csize + 1], compat, cplen);
for (i = csize; i < repend; i++) {
char c = str[i];
if (c == '\0')
str[i] = 'C';
else if (c == ' ')
str[i] = '_';
} }
return repend; return str - start;
} }
int of_device_request_module(struct device *dev) int of_device_request_module(struct device *dev)
...@@ -288,7 +271,8 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -288,7 +271,8 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
{ {
const char *compat; const char *compat;
struct alias_prop *app; struct alias_prop *app;
int seen = 0, cplen, sl; struct property *p;
int seen = 0;
if ((!dev) || (!dev->of_node)) if ((!dev) || (!dev->of_node))
return; return;
...@@ -301,12 +285,8 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -301,12 +285,8 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
/* Since the compatible field can contain pretty much anything /* Since the compatible field can contain pretty much anything
* it's not really legal to split it out with commas. We split it * it's not really legal to split it out with commas. We split it
* up using a number of environment variables instead. */ * up using a number of environment variables instead. */
compat = of_get_property(dev->of_node, "compatible", &cplen); of_property_for_each_string(dev->of_node, "compatible", p, compat) {
while (compat && *compat && cplen > 0) {
add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
sl = strlen(compat) + 1;
compat += sl;
cplen -= sl;
seen++; seen++;
} }
add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen); add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment