X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fof%2Fdevice.c;fp=drivers%2Fof%2Fdevice.c;h=8a1d93a2bb815c380bb18710369912834c2d2f06;hb=09e67ca2c523544e6b38aa570a5f62a0cf20b87b;hp=8fbfeee53c1e30841e9558c61fb04202bbf1688b;hpb=7bc228b1ef71f395aeb89bdf81bf95556b08b374;p=linux-2.6 diff --git a/drivers/of/device.c b/drivers/of/device.c index 8fbfeee53c..8a1d93a2bb 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -104,3 +104,51 @@ void of_device_unregister(struct of_device *ofdev) device_unregister(&ofdev->dev); } EXPORT_SYMBOL(of_device_unregister); + +ssize_t of_device_get_modalias(struct of_device *ofdev, + char *str, ssize_t len) +{ + const char *compat; + int cplen, i; + ssize_t tsize, csize, repend; + + /* Name & Type */ + csize = snprintf(str, len, "of:N%sT%s", + ofdev->node->name, ofdev->node->type); + + /* Get compatible property if any */ + compat = of_get_property(ofdev->node, "compatible", &cplen); + if (!compat) + return csize; + + /* Find true end (we tolerate multiple \0 at the end */ + for (i = (cplen - 1); i >= 0 && !compat[i]; i--) + cplen--; + if (!cplen) + return csize; + cplen++; + + /* Check space (need cplen+1 chars including final \0) */ + tsize = csize + cplen; + 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 tsize; +}