|
@@ -637,12 +637,41 @@ int device_add(struct device *dev)
|
|
|
BUS_NOTIFY_DEL_DEVICE, dev);
|
|
|
device_remove_groups(dev);
|
|
|
GroupError:
|
|
|
- device_remove_attrs(dev);
|
|
|
+ device_remove_attrs(dev);
|
|
|
AttrsError:
|
|
|
if (dev->devt_attr) {
|
|
|
device_remove_file(dev, dev->devt_attr);
|
|
|
kfree(dev->devt_attr);
|
|
|
}
|
|
|
+
|
|
|
+ if (dev->class) {
|
|
|
+ sysfs_remove_link(&dev->kobj, "subsystem");
|
|
|
+ /* If this is not a "fake" compatible device, remove the
|
|
|
+ * symlink from the class to the device. */
|
|
|
+ if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
|
|
|
+ sysfs_remove_link(&dev->class->subsys.kset.kobj,
|
|
|
+ dev->bus_id);
|
|
|
+#ifdef CONFIG_SYSFS_DEPRECATED
|
|
|
+ if (parent) {
|
|
|
+ char *class_name = make_class_name(dev->class->name,
|
|
|
+ &dev->kobj);
|
|
|
+ if (class_name)
|
|
|
+ sysfs_remove_link(&dev->parent->kobj,
|
|
|
+ class_name);
|
|
|
+ kfree(class_name);
|
|
|
+ sysfs_remove_link(&dev->kobj, "device");
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ down(&dev->class->sem);
|
|
|
+ /* notify any interfaces that the device is now gone */
|
|
|
+ list_for_each_entry(class_intf, &dev->class->interfaces, node)
|
|
|
+ if (class_intf->remove_dev)
|
|
|
+ class_intf->remove_dev(dev, class_intf);
|
|
|
+ /* remove the device from the class list */
|
|
|
+ list_del_init(&dev->node);
|
|
|
+ up(&dev->class->sem);
|
|
|
+ }
|
|
|
ueventattrError:
|
|
|
device_remove_file(dev, &dev->uevent_attr);
|
|
|
attrError:
|