diff options
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 57 |
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 | */ | ||
1149 | const 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 | } |