aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 1977d4beb89e..7ecb1938e590 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -22,6 +22,7 @@
22#include <linux/kallsyms.h> 22#include <linux/kallsyms.h>
23#include <linux/semaphore.h> 23#include <linux/semaphore.h>
24#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/async.h>
25 26
26#include "base.h" 27#include "base.h"
27#include "power/power.h" 28#include "power/power.h"
@@ -161,10 +162,18 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
161 struct device *dev = to_dev(kobj); 162 struct device *dev = to_dev(kobj);
162 int retval = 0; 163 int retval = 0;
163 164
164 /* add the major/minor if present */ 165 /* add device node properties if present */
165 if (MAJOR(dev->devt)) { 166 if (MAJOR(dev->devt)) {
167 const char *tmp;
168 const char *name;
169
166 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 170 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
167 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); 171 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
172 name = device_get_nodename(dev, &tmp);
173 if (name) {
174 add_uevent_var(env, "DEVNAME=%s", name);
175 kfree(tmp);
176 }
168 } 177 }
169 178
170 if (dev->type && dev->type->name) 179 if (dev->type && dev->type->name)
@@ -874,7 +883,7 @@ int device_add(struct device *dev)
874 * the name, and force the use of dev_name() 883 * the name, and force the use of dev_name()
875 */ 884 */
876 if (dev->init_name) { 885 if (dev->init_name) {
877 dev_set_name(dev, dev->init_name); 886 dev_set_name(dev, "%s", dev->init_name);
878 dev->init_name = NULL; 887 dev->init_name = NULL;
879 } 888 }
880 889
@@ -1128,6 +1137,47 @@ static struct device *next_device(struct klist_iter *i)
1128} 1137}
1129 1138
1130/** 1139/**
1140 * device_get_nodename - path of device node file
1141 * @dev: device
1142 * @tmp: possibly allocated string
1143 *
1144 * Return the relative path of a possible device node.
1145 * Non-default names may need to allocate a memory to compose
1146 * a name. This memory is returned in tmp and needs to be
1147 * freed by the caller.
1148 */
1149const char *device_get_nodename(struct device *dev, const char **tmp)
1150{
1151 char *s;
1152
1153 *tmp = NULL;
1154
1155 /* the device type may provide a specific name */
1156 if (dev->type && dev->type->nodename)
1157 *tmp = dev->type->nodename(dev);
1158 if (*tmp)
1159 return *tmp;
1160
1161 /* the class may provide a specific name */
1162 if (dev->class && dev->class->nodename)
1163 *tmp = dev->class->nodename(dev);
1164 if (*tmp)
1165 return *tmp;
1166
1167 /* return name without allocation, tmp == NULL */
1168 if (strchr(dev_name(dev), '!') == NULL)
1169 return dev_name(dev);
1170
1171 /* replace '!' in the name with '/' */
1172 *tmp = kstrdup(dev_name(dev), GFP_KERNEL);
1173 if (!*tmp)
1174 return NULL;
1175 while ((s = strchr(*tmp, '!')))
1176 s[0] = '/';
1177 return *tmp;
1178}
1179
1180/**
1131 * device_for_each_child - device child iterator. 1181 * device_for_each_child - device child iterator.
1132 * @parent: parent struct device. 1182 * @parent: parent struct device.
1133 * @data: data for the callback. 1183 * @data: data for the callback.
@@ -1271,7 +1321,7 @@ struct device *__root_device_register(const char *name, struct module *owner)
1271 if (!root) 1321 if (!root)
1272 return ERR_PTR(err); 1322 return ERR_PTR(err);
1273 1323
1274 err = dev_set_name(&root->dev, name); 1324 err = dev_set_name(&root->dev, "%s", name);
1275 if (err) { 1325 if (err) {
1276 kfree(root); 1326 kfree(root);
1277 return ERR_PTR(err); 1327 return ERR_PTR(err);
@@ -1665,4 +1715,5 @@ void device_shutdown(void)
1665 kobject_put(sysfs_dev_char_kobj); 1715 kobject_put(sysfs_dev_char_kobj);
1666 kobject_put(sysfs_dev_block_kobj); 1716 kobject_put(sysfs_dev_block_kobj);
1667 kobject_put(dev_kobj); 1717 kobject_put(dev_kobj);
1718 async_synchronize_full();
1668} 1719}