aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/core.c51
-rw-r--r--include/linux/device.h3
2 files changed, 53 insertions, 1 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4d59975c24a8..7ecb1938e590 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -162,10 +162,18 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
162 struct device *dev = to_dev(kobj); 162 struct device *dev = to_dev(kobj);
163 int retval = 0; 163 int retval = 0;
164 164
165 /* add the major/minor if present */ 165 /* add device node properties if present */
166 if (MAJOR(dev->devt)) { 166 if (MAJOR(dev->devt)) {
167 const char *tmp;
168 const char *name;
169
167 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 170 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
168 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 }
169 } 177 }
170 178
171 if (dev->type && dev->type->name) 179 if (dev->type && dev->type->name)
@@ -1129,6 +1137,47 @@ static struct device *next_device(struct klist_iter *i)
1129} 1137}
1130 1138
1131/** 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/**
1132 * device_for_each_child - device child iterator. 1181 * device_for_each_child - device child iterator.
1133 * @parent: parent struct device. 1182 * @parent: parent struct device.
1134 * @data: data for the callback. 1183 * @data: data for the callback.
diff --git a/include/linux/device.h b/include/linux/device.h
index 4410464b134a..ed4e39f2c423 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -194,6 +194,7 @@ struct class {
194 struct kobject *dev_kobj; 194 struct kobject *dev_kobj;
195 195
196 int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); 196 int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
197 char *(*nodename)(struct device *dev);
197 198
198 void (*class_release)(struct class *class); 199 void (*class_release)(struct class *class);
199 void (*dev_release)(struct device *dev); 200 void (*dev_release)(struct device *dev);
@@ -289,6 +290,7 @@ struct device_type {
289 const char *name; 290 const char *name;
290 struct attribute_group **groups; 291 struct attribute_group **groups;
291 int (*uevent)(struct device *dev, struct kobj_uevent_env *env); 292 int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
293 char *(*nodename)(struct device *dev);
292 void (*release)(struct device *dev); 294 void (*release)(struct device *dev);
293 295
294 struct dev_pm_ops *pm; 296 struct dev_pm_ops *pm;
@@ -488,6 +490,7 @@ extern struct device *device_find_child(struct device *dev, void *data,
488extern int device_rename(struct device *dev, char *new_name); 490extern int device_rename(struct device *dev, char *new_name);
489extern int device_move(struct device *dev, struct device *new_parent, 491extern int device_move(struct device *dev, struct device *new_parent,
490 enum dpm_order dpm_order); 492 enum dpm_order dpm_order);
493extern const char *device_get_nodename(struct device *dev, const char **tmp);
491 494
492/* 495/*
493 * Root device objects for grouping under /sys/devices 496 * Root device objects for grouping under /sys/devices