]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/base/core.c
Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linvil...
[mv-sheeva.git] / drivers / base / core.c
index a8ac34ba610716a4fc5c4193920a3d44a4697ccd..cf2a398aaaa1f6c0113bb1b58793e8d14b940129 100644 (file)
 int (*platform_notify)(struct device * dev) = NULL;
 int (*platform_notify_remove)(struct device * dev) = NULL;
 
+/*
+ * Detect the LANANA-assigned LOCAL/EXPERIMENTAL majors
+ */
+bool is_lanana_major(unsigned int major)
+{
+       if (major >= 60 && major <= 63)
+               return 1;
+       if (major >= 120 && major <= 127)
+               return 1;
+       if (major >= 240 && major <= 254)
+               return 1;
+       return 0;
+}
+
 /*
  * sysfs bindings for devices.
  */
@@ -623,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: