Skip to content

Commit bc57506

Browse files
committed
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: Rob Herring <robh@kernel.org>
1 parent 7c6ffa0 commit bc57506

File tree

1 file changed

+23
-43
lines changed

1 file changed

+23
-43
lines changed

drivers/of/device.c

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -195,52 +195,35 @@ EXPORT_SYMBOL(of_device_get_match_data);
195195

196196
static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
197197
{
198-
const char *compat;
199-
int cplen, i;
200-
ssize_t tsize, csize, repend;
198+
const char *compat, *start = str;
199+
char *c;
200+
struct property *p;
201+
ssize_t csize;
201202

202203
if ((!dev) || (!dev->of_node))
203204
return -ENODEV;
204205

205206
/* Name & Type */
206207
csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name,
207208
dev->of_node->type);
208-
209-
/* Get compatible property if any */
210-
compat = of_get_property(dev->of_node, "compatible", &cplen);
211-
if (!compat)
212-
return csize;
213-
214-
/* Find true end (we tolerate multiple \0 at the end */
215-
for (i = (cplen - 1); i >= 0 && !compat[i]; i--)
216-
cplen--;
217-
if (!cplen)
218-
return csize;
219-
cplen++;
220-
221-
/* Check space (need cplen+1 chars including final \0) */
222-
tsize = csize + cplen;
223-
repend = tsize;
224-
225-
if (csize >= len) /* @ the limit, all is already filled */
226-
return tsize;
227-
228-
if (tsize >= len) { /* limit compat list */
229-
cplen = len - csize - 1;
230-
repend = len;
231-
}
232-
233-
/* Copy and do char replacement */
234-
memcpy(&str[csize + 1], compat, cplen);
235-
for (i = csize; i < repend; i++) {
236-
char c = str[i];
237-
if (c == '\0')
238-
str[i] = 'C';
239-
else if (c == ' ')
240-
str[i] = '_';
209+
len -= csize;
210+
str += csize;
211+
212+
of_property_for_each_string(dev->of_node, "compatible", p, compat) {
213+
if (strlen(compat) + 2 > len)
214+
break;
215+
216+
csize = snprintf(str, len, "C%s", compat);
217+
for (c = str; c; ) {
218+
c = strchr(c, ' ');
219+
if (c)
220+
*c++ = '_';
221+
}
222+
len -= csize;
223+
str += csize;
241224
}
242225

243-
return repend;
226+
return str - start;
244227
}
245228

246229
int of_device_request_module(struct device *dev)
@@ -288,7 +271,8 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
288271
{
289272
const char *compat;
290273
struct alias_prop *app;
291-
int seen = 0, cplen, sl;
274+
struct property *p;
275+
int seen = 0;
292276

293277
if ((!dev) || (!dev->of_node))
294278
return;
@@ -301,12 +285,8 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
301285
/* Since the compatible field can contain pretty much anything
302286
* it's not really legal to split it out with commas. We split it
303287
* up using a number of environment variables instead. */
304-
compat = of_get_property(dev->of_node, "compatible", &cplen);
305-
while (compat && *compat && cplen > 0) {
288+
of_property_for_each_string(dev->of_node, "compatible", p, compat) {
306289
add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
307-
sl = strlen(compat) + 1;
308-
compat += sl;
309-
cplen -= sl;
310290
seen++;
311291
}
312292
add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);

0 commit comments

Comments
 (0)