Commit 07d57a32fb6eb2da017796e038682f817a4f685e

Authored by Grant Likely
1 parent 7aff0fe330

drivercore: Output common devicetree information in uevent

When userspace needs to find a specific device, it currently isn't easy to
resolve a /sys/devices/ path from a specific device tree node.  Nor is it
easy to obtain the compatible list for devices.

This patch generalizes the code that inserts OF_* values into the uevent
device attribute so that any device that is attached to an OF node will
have that information exported to userspace.  Without this patch only
platform devices and some powerpc-specific busses have access to this
data.

The original function also creates a MODALIAS property for the compatible
list, but that code has not been generalized into the common case because
it has the potential to break module loading on a lot of bus types.  Bus
types are still responsible for their own MODALIAS properties.

Boot tested on ARM and compile tested on PowerPC and SPARC.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Tobias Klauser <tklauser@distanz.ch>
Cc: Frederic Lambert <frdrc66@gmail.com>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Mark Brown <broonie@sirena.org.uk>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Showing 6 changed files with 30 additions and 19 deletions Side-by-side Diff

arch/powerpc/kernel/ibmebus.c
... ... @@ -713,7 +713,7 @@
713 713  
714 714 struct bus_type ibmebus_bus_type = {
715 715 .name = "ibmebus",
716   - .uevent = of_device_uevent,
  716 + .uevent = of_device_uevent_modalias,
717 717 .bus_attrs = ibmebus_bus_attrs,
718 718 .match = ibmebus_bus_bus_match,
719 719 .probe = ibmebus_bus_device_probe,
... ... @@ -18,6 +18,8 @@
18 18 #include <linux/string.h>
19 19 #include <linux/kdev_t.h>
20 20 #include <linux/notifier.h>
  21 +#include <linux/of.h>
  22 +#include <linux/of_device.h>
21 23 #include <linux/genhd.h>
22 24 #include <linux/kallsyms.h>
23 25 #include <linux/mutex.h>
... ... @@ -266,6 +268,9 @@
266 268  
267 269 if (dev->driver)
268 270 add_uevent_var(env, "DRIVER=%s", dev->driver->name);
  271 +
  272 + /* Add common DT information about the device */
  273 + of_device_uevent(dev, env);
269 274  
270 275 /* have the bus specific function add its stuff */
271 276 if (dev->bus && dev->bus->uevent) {
drivers/base/platform.c
... ... @@ -621,7 +621,7 @@
621 621 int rc;
622 622  
623 623 /* Some devices have extra OF data and an OF-style MODALIAS */
624   - rc = of_device_uevent(dev,env);
  624 + rc = of_device_uevent_modalias(dev,env);
625 625 if (rc != -ENODEV)
626 626 return rc;
627 627  
drivers/macintosh/macio_asic.c
... ... @@ -137,7 +137,7 @@
137 137 struct bus_type macio_bus_type = {
138 138 .name = "macio",
139 139 .match = macio_bus_match,
140   - .uevent = of_device_uevent,
  140 + .uevent = of_device_uevent_modalias,
141 141 .probe = macio_device_probe,
142 142 .remove = macio_device_remove,
143 143 .shutdown = macio_device_shutdown,
... ... @@ -128,39 +128,41 @@
128 128 /**
129 129 * of_device_uevent - Display OF related uevent information
130 130 */
131   -int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
  131 +void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
132 132 {
133 133 const char *compat;
134 134 int seen = 0, cplen, sl;
135 135  
136 136 if ((!dev) || (!dev->of_node))
137   - return -ENODEV;
  137 + return;
138 138  
139   - if (add_uevent_var(env, "OF_NAME=%s", dev->of_node->name))
140   - return -ENOMEM;
  139 + add_uevent_var(env, "OF_NAME=%s", dev->of_node->name);
  140 + add_uevent_var(env, "OF_FULLNAME=%s", dev->of_node->full_name);
  141 + if (dev->of_node->type && strcmp("<NULL>", dev->of_node->type) != 0)
  142 + add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type);
141 143  
142   - if (add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type))
143   - return -ENOMEM;
144   -
145 144 /* Since the compatible field can contain pretty much anything
146 145 * it's not really legal to split it out with commas. We split it
147 146 * up using a number of environment variables instead. */
148   -
149 147 compat = of_get_property(dev->of_node, "compatible", &cplen);
150 148 while (compat && *compat && cplen > 0) {
151   - if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
152   - return -ENOMEM;
153   -
  149 + add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
154 150 sl = strlen(compat) + 1;
155 151 compat += sl;
156 152 cplen -= sl;
157 153 seen++;
158 154 }
  155 + add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
  156 +}
159 157  
160   - if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
161   - return -ENOMEM;
  158 +int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
  159 +{
  160 + int sl;
162 161  
163   - /* modalias is trickier, we add it in 2 steps */
  162 + if ((!dev) || (!dev->of_node))
  163 + return -ENODEV;
  164 +
  165 + /* Devicetree modalias is tricky, we add it in 2 steps */
164 166 if (add_uevent_var(env, "MODALIAS="))
165 167 return -ENOMEM;
166 168  
include/linux/of_device.h
... ... @@ -34,7 +34,8 @@
34 34 extern ssize_t of_device_get_modalias(struct device *dev,
35 35 char *str, ssize_t len);
36 36  
37   -extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
  37 +extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
  38 +extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
38 39  
39 40 static inline void of_device_node_put(struct device *dev)
40 41 {
... ... @@ -49,7 +50,10 @@
49 50 return 0;
50 51 }
51 52  
52   -static inline int of_device_uevent(struct device *dev,
  53 +static inline void of_device_uevent(struct device *dev,
  54 + struct kobj_uevent_env *env) { }
  55 +
  56 +static inline int of_device_uevent_modalias(struct device *dev,
53 57 struct kobj_uevent_env *env)
54 58 {
55 59 return -ENODEV;