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.c203
1 files changed, 133 insertions, 70 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 67b79a7592a9..e13614241c9e 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -95,6 +95,8 @@ static void device_release(struct kobject * kobj)
95 95
96 if (dev->release) 96 if (dev->release)
97 dev->release(dev); 97 dev->release(dev);
98 else if (dev->type && dev->type->release)
99 dev->type->release(dev);
98 else if (dev->class && dev->class->dev_release) 100 else if (dev->class && dev->class->dev_release)
99 dev->class->dev_release(dev); 101 dev->class->dev_release(dev);
100 else { 102 else {
@@ -154,25 +156,47 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
154 "MINOR=%u", MINOR(dev->devt)); 156 "MINOR=%u", MINOR(dev->devt));
155 } 157 }
156 158
157#ifdef CONFIG_SYSFS_DEPRECATED 159 if (dev->driver)
158 /* add bus name (same as SUBSYSTEM, deprecated) */
159 if (dev->bus)
160 add_uevent_var(envp, num_envp, &i,
161 buffer, buffer_size, &length,
162 "PHYSDEVBUS=%s", dev->bus->name);
163#endif
164
165 /* add driver name (PHYSDEV* values are deprecated)*/
166 if (dev->driver) {
167 add_uevent_var(envp, num_envp, &i, 160 add_uevent_var(envp, num_envp, &i,
168 buffer, buffer_size, &length, 161 buffer, buffer_size, &length,
169 "DRIVER=%s", dev->driver->name); 162 "DRIVER=%s", dev->driver->name);
163
170#ifdef CONFIG_SYSFS_DEPRECATED 164#ifdef CONFIG_SYSFS_DEPRECATED
165 if (dev->class) {
166 struct device *parent = dev->parent;
167
168 /* find first bus device in parent chain */
169 while (parent && !parent->bus)
170 parent = parent->parent;
171 if (parent && parent->bus) {
172 const char *path;
173
174 path = kobject_get_path(&parent->kobj, GFP_KERNEL);
175 add_uevent_var(envp, num_envp, &i,
176 buffer, buffer_size, &length,
177 "PHYSDEVPATH=%s", path);
178 kfree(path);
179
180 add_uevent_var(envp, num_envp, &i,
181 buffer, buffer_size, &length,
182 "PHYSDEVBUS=%s", parent->bus->name);
183
184 if (parent->driver)
185 add_uevent_var(envp, num_envp, &i,
186 buffer, buffer_size, &length,
187 "PHYSDEVDRIVER=%s", parent->driver->name);
188 }
189 } else if (dev->bus) {
171 add_uevent_var(envp, num_envp, &i, 190 add_uevent_var(envp, num_envp, &i,
172 buffer, buffer_size, &length, 191 buffer, buffer_size, &length,
173 "PHYSDEVDRIVER=%s", dev->driver->name); 192 "PHYSDEVBUS=%s", dev->bus->name);
174#endif 193
194 if (dev->driver)
195 add_uevent_var(envp, num_envp, &i,
196 buffer, buffer_size, &length,
197 "PHYSDEVDRIVER=%s", dev->driver->name);
175 } 198 }
199#endif
176 200
177 /* terminate, set to next free slot, shrink available space */ 201 /* terminate, set to next free slot, shrink available space */
178 envp[i] = NULL; 202 envp[i] = NULL;
@@ -184,19 +208,25 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
184 if (dev->bus && dev->bus->uevent) { 208 if (dev->bus && dev->bus->uevent) {
185 /* have the bus specific function add its stuff */ 209 /* have the bus specific function add its stuff */
186 retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size); 210 retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
187 if (retval) { 211 if (retval)
188 pr_debug ("%s - uevent() returned %d\n", 212 pr_debug ("%s: bus uevent() returned %d\n",
189 __FUNCTION__, retval); 213 __FUNCTION__, retval);
190 }
191 } 214 }
192 215
193 if (dev->class && dev->class->dev_uevent) { 216 if (dev->class && dev->class->dev_uevent) {
194 /* have the class specific function add its stuff */ 217 /* have the class specific function add its stuff */
195 retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size); 218 retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
196 if (retval) { 219 if (retval)
197 pr_debug("%s - dev_uevent() returned %d\n", 220 pr_debug("%s: class uevent() returned %d\n",
198 __FUNCTION__, retval); 221 __FUNCTION__, retval);
199 } 222 }
223
224 if (dev->type && dev->type->uevent) {
225 /* have the device type specific fuction add its stuff */
226 retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size);
227 if (retval)
228 pr_debug("%s: dev_type uevent() returned %d\n",
229 __FUNCTION__, retval);
200 } 230 }
201 231
202 return retval; 232 return retval;
@@ -247,37 +277,50 @@ static void device_remove_groups(struct device *dev)
247static int device_add_attrs(struct device *dev) 277static int device_add_attrs(struct device *dev)
248{ 278{
249 struct class *class = dev->class; 279 struct class *class = dev->class;
280 struct device_type *type = dev->type;
250 int error = 0; 281 int error = 0;
251 int i; 282 int i;
252 283
253 if (!class) 284 if (class && class->dev_attrs) {
254 return 0;
255
256 if (class->dev_attrs) {
257 for (i = 0; attr_name(class->dev_attrs[i]); i++) { 285 for (i = 0; attr_name(class->dev_attrs[i]); i++) {
258 error = device_create_file(dev, &class->dev_attrs[i]); 286 error = device_create_file(dev, &class->dev_attrs[i]);
259 if (error) 287 if (error)
260 break; 288 break;
261 } 289 }
290 if (error)
291 while (--i >= 0)
292 device_remove_file(dev, &class->dev_attrs[i]);
262 } 293 }
263 if (error) 294
264 while (--i >= 0) 295 if (type && type->attrs) {
265 device_remove_file(dev, &class->dev_attrs[i]); 296 for (i = 0; attr_name(type->attrs[i]); i++) {
297 error = device_create_file(dev, &type->attrs[i]);
298 if (error)
299 break;
300 }
301 if (error)
302 while (--i >= 0)
303 device_remove_file(dev, &type->attrs[i]);
304 }
305
266 return error; 306 return error;
267} 307}
268 308
269static void device_remove_attrs(struct device *dev) 309static void device_remove_attrs(struct device *dev)
270{ 310{
271 struct class *class = dev->class; 311 struct class *class = dev->class;
312 struct device_type *type = dev->type;
272 int i; 313 int i;
273 314
274 if (!class) 315 if (class && class->dev_attrs) {
275 return;
276
277 if (class->dev_attrs) {
278 for (i = 0; attr_name(class->dev_attrs[i]); i++) 316 for (i = 0; attr_name(class->dev_attrs[i]); i++)
279 device_remove_file(dev, &class->dev_attrs[i]); 317 device_remove_file(dev, &class->dev_attrs[i]);
280 } 318 }
319
320 if (type && type->attrs) {
321 for (i = 0; attr_name(type->attrs[i]); i++)
322 device_remove_file(dev, &type->attrs[i]);
323 }
281} 324}
282 325
283 326
@@ -390,22 +433,23 @@ void device_initialize(struct device *dev)
390} 433}
391 434
392#ifdef CONFIG_SYSFS_DEPRECATED 435#ifdef CONFIG_SYSFS_DEPRECATED
393static int setup_parent(struct device *dev, struct device *parent) 436static struct kobject * get_device_parent(struct device *dev,
437 struct device *parent)
394{ 438{
395 /* Set the parent to the class, not the parent device */ 439 /* Set the parent to the class, not the parent device */
396 /* this keeps sysfs from having a symlink to make old udevs happy */ 440 /* this keeps sysfs from having a symlink to make old udevs happy */
397 if (dev->class) 441 if (dev->class)
398 dev->kobj.parent = &dev->class->subsys.kset.kobj; 442 return &dev->class->subsys.kset.kobj;
399 else if (parent) 443 else if (parent)
400 dev->kobj.parent = &parent->kobj; 444 return &parent->kobj;
401 445
402 return 0; 446 return NULL;
403} 447}
404#else 448#else
405static int virtual_device_parent(struct device *dev) 449static struct kobject * virtual_device_parent(struct device *dev)
406{ 450{
407 if (!dev->class) 451 if (!dev->class)
408 return -ENODEV; 452 return ERR_PTR(-ENODEV);
409 453
410 if (!dev->class->virtual_dir) { 454 if (!dev->class->virtual_dir) {
411 static struct kobject *virtual_dir = NULL; 455 static struct kobject *virtual_dir = NULL;
@@ -415,25 +459,31 @@ static int virtual_device_parent(struct device *dev)
415 dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name); 459 dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name);
416 } 460 }
417 461
418 dev->kobj.parent = dev->class->virtual_dir; 462 return dev->class->virtual_dir;
419 return 0;
420} 463}
421 464
422static int setup_parent(struct device *dev, struct device *parent) 465static struct kobject * get_device_parent(struct device *dev,
466 struct device *parent)
423{ 467{
424 int error;
425
426 /* if this is a class device, and has no parent, create one */ 468 /* if this is a class device, and has no parent, create one */
427 if ((dev->class) && (parent == NULL)) { 469 if ((dev->class) && (parent == NULL)) {
428 error = virtual_device_parent(dev); 470 return virtual_device_parent(dev);
429 if (error)
430 return error;
431 } else if (parent) 471 } else if (parent)
432 dev->kobj.parent = &parent->kobj; 472 return &parent->kobj;
473 return NULL;
474}
433 475
476#endif
477static int setup_parent(struct device *dev, struct device *parent)
478{
479 struct kobject *kobj;
480 kobj = get_device_parent(dev, parent);
481 if (IS_ERR(kobj))
482 return PTR_ERR(kobj);
483 if (kobj)
484 dev->kobj.parent = kobj;
434 return 0; 485 return 0;
435} 486}
436#endif
437 487
438/** 488/**
439 * device_add - add device to device hierarchy. 489 * device_add - add device to device hierarchy.
@@ -520,9 +570,13 @@ int device_add(struct device *dev)
520 &dev->kobj, dev->bus_id); 570 &dev->kobj, dev->bus_id);
521#ifdef CONFIG_SYSFS_DEPRECATED 571#ifdef CONFIG_SYSFS_DEPRECATED
522 if (parent) { 572 if (parent) {
523 sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); 573 sysfs_create_link(&dev->kobj, &dev->parent->kobj,
524 class_name = make_class_name(dev->class->name, &dev->kobj); 574 "device");
525 sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name); 575 class_name = make_class_name(dev->class->name,
576 &dev->kobj);
577 if (class_name)
578 sysfs_create_link(&dev->parent->kobj,
579 &dev->kobj, class_name);
526 } 580 }
527#endif 581#endif
528 } 582 }
@@ -535,7 +589,8 @@ int device_add(struct device *dev)
535 goto PMError; 589 goto PMError;
536 if ((error = bus_add_device(dev))) 590 if ((error = bus_add_device(dev)))
537 goto BusError; 591 goto BusError;
538 kobject_uevent(&dev->kobj, KOBJ_ADD); 592 if (!dev->uevent_suppress)
593 kobject_uevent(&dev->kobj, KOBJ_ADD);
539 if ((error = bus_attach_device(dev))) 594 if ((error = bus_attach_device(dev)))
540 goto AttachError; 595 goto AttachError;
541 if (parent) 596 if (parent)
@@ -665,7 +720,9 @@ void device_del(struct device * dev)
665 if (parent) { 720 if (parent) {
666 char *class_name = make_class_name(dev->class->name, 721 char *class_name = make_class_name(dev->class->name,
667 &dev->kobj); 722 &dev->kobj);
668 sysfs_remove_link(&dev->parent->kobj, class_name); 723 if (class_name)
724 sysfs_remove_link(&dev->parent->kobj,
725 class_name);
669 kfree(class_name); 726 kfree(class_name);
670 sysfs_remove_link(&dev->kobj, "device"); 727 sysfs_remove_link(&dev->kobj, "device");
671 } 728 }
@@ -968,20 +1025,25 @@ static int device_move_class_links(struct device *dev,
968 1025
969 class_name = make_class_name(dev->class->name, &dev->kobj); 1026 class_name = make_class_name(dev->class->name, &dev->kobj);
970 if (!class_name) { 1027 if (!class_name) {
971 error = PTR_ERR(class_name); 1028 error = -ENOMEM;
972 class_name = NULL;
973 goto out; 1029 goto out;
974 } 1030 }
975 if (old_parent) { 1031 if (old_parent) {
976 sysfs_remove_link(&dev->kobj, "device"); 1032 sysfs_remove_link(&dev->kobj, "device");
977 sysfs_remove_link(&old_parent->kobj, class_name); 1033 sysfs_remove_link(&old_parent->kobj, class_name);
978 } 1034 }
979 error = sysfs_create_link(&dev->kobj, &new_parent->kobj, "device"); 1035 if (new_parent) {
980 if (error) 1036 error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
981 goto out; 1037 "device");
982 error = sysfs_create_link(&new_parent->kobj, &dev->kobj, class_name); 1038 if (error)
983 if (error) 1039 goto out;
984 sysfs_remove_link(&dev->kobj, "device"); 1040 error = sysfs_create_link(&new_parent->kobj, &dev->kobj,
1041 class_name);
1042 if (error)
1043 sysfs_remove_link(&dev->kobj, "device");
1044 }
1045 else
1046 error = 0;
985out: 1047out:
986 kfree(class_name); 1048 kfree(class_name);
987 return error; 1049 return error;
@@ -993,29 +1055,28 @@ out:
993/** 1055/**
994 * device_move - moves a device to a new parent 1056 * device_move - moves a device to a new parent
995 * @dev: the pointer to the struct device to be moved 1057 * @dev: the pointer to the struct device to be moved
996 * @new_parent: the new parent of the device 1058 * @new_parent: the new parent of the device (can by NULL)
997 */ 1059 */
998int device_move(struct device *dev, struct device *new_parent) 1060int device_move(struct device *dev, struct device *new_parent)
999{ 1061{
1000 int error; 1062 int error;
1001 struct device *old_parent; 1063 struct device *old_parent;
1064 struct kobject *new_parent_kobj;
1002 1065
1003 dev = get_device(dev); 1066 dev = get_device(dev);
1004 if (!dev) 1067 if (!dev)
1005 return -EINVAL; 1068 return -EINVAL;
1006 1069
1007 if (!device_is_registered(dev)) {
1008 error = -EINVAL;
1009 goto out;
1010 }
1011 new_parent = get_device(new_parent); 1070 new_parent = get_device(new_parent);
1012 if (!new_parent) { 1071 new_parent_kobj = get_device_parent (dev, new_parent);
1013 error = -EINVAL; 1072 if (IS_ERR(new_parent_kobj)) {
1073 error = PTR_ERR(new_parent_kobj);
1074 put_device(new_parent);
1014 goto out; 1075 goto out;
1015 } 1076 }
1016 pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id, 1077 pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id,
1017 new_parent->bus_id); 1078 new_parent ? new_parent->bus_id : "<NULL>");
1018 error = kobject_move(&dev->kobj, &new_parent->kobj); 1079 error = kobject_move(&dev->kobj, new_parent_kobj);
1019 if (error) { 1080 if (error) {
1020 put_device(new_parent); 1081 put_device(new_parent);
1021 goto out; 1082 goto out;
@@ -1024,7 +1085,8 @@ int device_move(struct device *dev, struct device *new_parent)
1024 dev->parent = new_parent; 1085 dev->parent = new_parent;
1025 if (old_parent) 1086 if (old_parent)
1026 klist_remove(&dev->knode_parent); 1087 klist_remove(&dev->knode_parent);
1027 klist_add_tail(&dev->knode_parent, &new_parent->klist_children); 1088 if (new_parent)
1089 klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
1028 if (!dev->class) 1090 if (!dev->class)
1029 goto out_put; 1091 goto out_put;
1030 error = device_move_class_links(dev, old_parent, new_parent); 1092 error = device_move_class_links(dev, old_parent, new_parent);
@@ -1032,7 +1094,8 @@ int device_move(struct device *dev, struct device *new_parent)
1032 /* We ignore errors on cleanup since we're hosed anyway... */ 1094 /* We ignore errors on cleanup since we're hosed anyway... */
1033 device_move_class_links(dev, new_parent, old_parent); 1095 device_move_class_links(dev, new_parent, old_parent);
1034 if (!kobject_move(&dev->kobj, &old_parent->kobj)) { 1096 if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
1035 klist_remove(&dev->knode_parent); 1097 if (new_parent)
1098 klist_remove(&dev->knode_parent);
1036 if (old_parent) 1099 if (old_parent)
1037 klist_add_tail(&dev->knode_parent, 1100 klist_add_tail(&dev->knode_parent,
1038 &old_parent->klist_children); 1101 &old_parent->klist_children);