diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-07 14:43:33 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-07 14:43:33 -0700 |
commit | 74fee4e88fd196c712abfdae89acfa272abf10f8 (patch) | |
tree | 942a2668830b36f5cf9bc9f2c77948f8b04c2742 /drivers/of/device.c | |
parent | 7d955656121f547ff9a708ed7ee4c86a08bf628a (diff) | |
parent | 84024468cf1612783e6ab317da5b72fa41487ac6 (diff) |
Merge tag 'devicetree-for-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull DeviceTree updates from Rob Herring:
"There's a few orphans in the conversion to %pOF printf specifiers
included here that no one else picked up.
Summary:
- Convert more DT code to use of_property_read_* API.
- Improve DT overlay support when adding multiple overlays
- Convert printk's to %pOF format specifiers. Most went via subsystem
trees, but picked up the remaining orphans
- Correct unittests to use preferred "okay" for "status" property
value
- Add a KASLR seed property
- Vendor prefixes for Mellanox, Theobroma System, Adaptrum, Moxa
- Fix modalias buffer handling
- Clean-up of include paths for building dtbs
- Add bindings for amc6821, isl1208, tsl2x7x, srf02, and srf10
devices
- Add nvmem bindings for MediaTek MT7623 and MT7622 SoC
- Add compatible string for Allwinner H5 Mali-450 GPU
- Fix links to old OpenFirmware docs with new mirror on
devicetree.org
- Remove status property from binding doc examples"
* tag 'devicetree-for-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (45 commits)
devicetree: Adjust status "ok" -> "okay" under drivers/of/
dt-bindings: Remove "status" from examples
dt-bindings: pinctrl: sh-pfc: Use generic node name
dt-bindings: Add vendor Mellanox
dt-binding: net/phy: fix interrupts description
virt: Convert to using %pOF instead of full_name
macintosh: Convert to using %pOF instead of full_name
ide: pmac: Convert to using %pOF instead of full_name
microblaze: Convert to using %pOF instead of full_name
dt-bindings: usb: musb: Grammar s/the/to/, s/is/are/
of: Use PLATFORM_DEVID_NONE definition
of/device: Fix of_device_get_modalias() buffer handling
of/device: Prevent buffer overflow in of_device_modalias()
dt-bindings: add amc6821, isl1208 trivial bindings
dt-bindings: add vendor prefix for Theobroma Systems
of: search scripts/dtc/include-prefixes path for both CPP and DTC
of: remove arch/$(SRCARCH)/boot/dts from include search path for CPP
of: remove drivers/of/testcase-data from include search path for CPP
of: return of_get_cpu_node from of_cpu_device_node_get if CPUs are not registered
iio: srf08: add device tree binding for srf02 and srf10
...
Diffstat (limited to 'drivers/of/device.c')
-rw-r--r-- | drivers/of/device.c | 75 |
1 files changed, 31 insertions, 44 deletions
diff --git a/drivers/of/device.c b/drivers/of/device.c index e0a28ea341fe..17b66e9715d2 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -58,7 +58,7 @@ int of_device_add(struct platform_device *ofdev) /* name and id have to be set so that the platform bus doesn't get * confused on matching */ ofdev->name = dev_name(&ofdev->dev); - ofdev->id = -1; + ofdev->id = PLATFORM_DEVID_NONE; /* * If this device has not binding numa node in devicetree, that is @@ -196,8 +196,10 @@ EXPORT_SYMBOL(of_device_get_match_data); static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) { const char *compat; - int cplen, i; - ssize_t tsize, csize, repend; + char *c; + struct property *p; + ssize_t csize; + ssize_t tsize; if ((!dev) || (!dev->of_node)) return -ENODEV; @@ -205,42 +207,28 @@ static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len /* Name & Type */ csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name, dev->of_node->type); - - /* Get compatible property if any */ - compat = of_get_property(dev->of_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] = '_'; + tsize = csize; + len -= csize; + if (str) + str += csize; + + of_property_for_each_string(dev->of_node, "compatible", p, compat) { + csize = strlen(compat) + 1; + tsize += csize; + if (csize > len) + continue; + + csize = snprintf(str, len, "C%s", compat); + for (c = str; c; ) { + c = strchr(c, ' '); + if (c) + *c++ = '_'; + } + len -= csize; + str += csize; } - return repend; + return tsize; } int of_device_request_module(struct device *dev) @@ -274,6 +262,8 @@ ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len) ssize_t sl = of_device_get_modalias(dev, str, len - 2); if (sl < 0) return sl; + if (sl > len - 2) + return -ENOMEM; str[sl++] = '\n'; str[sl] = 0; @@ -288,25 +278,22 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) { const char *compat; struct alias_prop *app; - int seen = 0, cplen, sl; + struct property *p; + int seen = 0; if ((!dev) || (!dev->of_node)) return; add_uevent_var(env, "OF_NAME=%s", dev->of_node->name); - add_uevent_var(env, "OF_FULLNAME=%s", dev->of_node->full_name); + add_uevent_var(env, "OF_FULLNAME=%pOF", dev->of_node); if (dev->of_node->type && strcmp("<NULL>", dev->of_node->type) != 0) add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type); /* Since the compatible field can contain pretty much anything * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(dev->of_node, "compatible", &cplen); - while (compat && *compat && cplen > 0) { + of_property_for_each_string(dev->of_node, "compatible", p, compat) { add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); - sl = strlen(compat) + 1; - compat += sl; - cplen -= sl; seen++; } add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen); |