]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/base/core.c
PM: Remove destroy_suspended_device()
[linux-2.6-omap-h63xx.git] / drivers / base / core.c
index edf3bbeb8d6a0af7438119b915aafb3f0111617d..0262fc7c45fcbc2673d3a3d687973228aa9ee538 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kdev_t.h>
 #include <linux/notifier.h>
 #include <linux/genhd.h>
+#include <linux/kallsyms.h>
 #include <asm/semaphore.h>
 
 #include "base.h"
 int (*platform_notify)(struct device *dev) = NULL;
 int (*platform_notify_remove)(struct device *dev) = NULL;
 
-/*
- * sysfs bindings for devices.
- */
+#ifdef CONFIG_BLOCK
+static inline int device_is_not_partition(struct device *dev)
+{
+       return !(dev->type == &part_type);
+}
+#else
+static inline int device_is_not_partition(struct device *dev)
+{
+       return 1;
+}
+#endif
 
 /**
  * dev_driver_string - Return a device's driver name, if at all possible
@@ -60,6 +69,10 @@ static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
 
        if (dev_attr->show)
                ret = dev_attr->show(dev, dev_attr, buf);
+       if (ret >= (ssize_t)PAGE_SIZE) {
+               print_symbol("dev_attr_show: %s returned bad count\n",
+                               (unsigned long)dev_attr->show);
+       }
        return ret;
 }
 
@@ -415,10 +428,8 @@ struct kset *devices_kset;
 int device_create_file(struct device *dev, struct device_attribute *attr)
 {
        int error = 0;
-       if (get_device(dev)) {
+       if (dev)
                error = sysfs_create_file(&dev->kobj, &attr->attr);
-               put_device(dev);
-       }
        return error;
 }
 
@@ -429,10 +440,8 @@ int device_create_file(struct device *dev, struct device_attribute *attr)
  */
 void device_remove_file(struct device *dev, struct device_attribute *attr)
 {
-       if (get_device(dev)) {
+       if (dev)
                sysfs_remove_file(&dev->kobj, &attr->attr);
-               put_device(dev);
-       }
 }
 
 /**
@@ -617,7 +626,8 @@ static struct kobject *get_device_parent(struct device *dev,
 static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
 {
        /* see if we live in a "glue" directory */
-       if (!dev->class || glue_dir->kset != &dev->class->class_dirs)
+       if (!glue_dir || !dev->class ||
+           glue_dir->kset != &dev->class->class_dirs)
                return;
 
        kobject_put(glue_dir);
@@ -652,14 +662,14 @@ static int device_add_class_symlinks(struct device *dev)
 #ifdef CONFIG_SYSFS_DEPRECATED
        /* stacked class devices need a symlink in the class directory */
        if (dev->kobj.parent != &dev->class->subsys.kobj &&
-           dev->type != &part_type) {
+           device_is_not_partition(dev)) {
                error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
                                          dev->bus_id);
                if (error)
                        goto out_subsys;
        }
 
-       if (dev->parent && dev->type != &part_type) {
+       if (dev->parent && device_is_not_partition(dev)) {
                struct device *parent = dev->parent;
                char *class_name;
 
@@ -688,11 +698,11 @@ static int device_add_class_symlinks(struct device *dev)
        return 0;
 
 out_device:
-       if (dev->parent && dev->type != &part_type)
+       if (dev->parent && device_is_not_partition(dev))
                sysfs_remove_link(&dev->kobj, "device");
 out_busid:
        if (dev->kobj.parent != &dev->class->subsys.kobj &&
-           dev->type != &part_type)
+           device_is_not_partition(dev))
                sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
 #else
        /* link in the class directory pointing to the device */
@@ -701,7 +711,7 @@ out_busid:
        if (error)
                goto out_subsys;
 
-       if (dev->parent && dev->type != &part_type) {
+       if (dev->parent && device_is_not_partition(dev)) {
                error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
                                          "device");
                if (error)
@@ -725,7 +735,7 @@ static void device_remove_class_symlinks(struct device *dev)
                return;
 
 #ifdef CONFIG_SYSFS_DEPRECATED
-       if (dev->parent && dev->type != &part_type) {
+       if (dev->parent && device_is_not_partition(dev)) {
                char *class_name;
 
                class_name = make_class_name(dev->class->name, &dev->kobj);
@@ -737,10 +747,10 @@ static void device_remove_class_symlinks(struct device *dev)
        }
 
        if (dev->kobj.parent != &dev->class->subsys.kobj &&
-           dev->type != &part_type)
+           device_is_not_partition(dev))
                sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
 #else
-       if (dev->parent && dev->type != &part_type)
+       if (dev->parent && device_is_not_partition(dev))
                sysfs_remove_link(&dev->kobj, "device");
 
        sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
@@ -766,17 +776,10 @@ int device_add(struct device *dev)
        struct class_interface *class_intf;
        int error;
 
-       error = pm_sleep_lock();
-       if (error) {
-               dev_warn(dev, "Suspicious %s during suspend\n", __FUNCTION__);
-               dump_stack();
-               return error;
-       }
-
        dev = get_device(dev);
        if (!dev || !strlen(dev->bus_id)) {
                error = -EINVAL;
-               goto Error;
+               goto Done;
        }
 
        pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__);
@@ -814,13 +817,12 @@ int device_add(struct device *dev)
        error = device_add_attrs(dev);
        if (error)
                goto AttrsError;
-       error = dpm_sysfs_add(dev);
-       if (error)
-               goto PMError;
-       device_pm_add(dev);
        error = bus_add_device(dev);
        if (error)
                goto BusError;
+       error = device_pm_add(dev);
+       if (error)
+               goto PMError;
        kobject_uevent(&dev->kobj, KOBJ_ADD);
        bus_attach_device(dev);
        if (parent)
@@ -839,12 +841,10 @@ int device_add(struct device *dev)
        }
  Done:
        put_device(dev);
-       pm_sleep_unlock();
        return error;
- BusError:
-       device_pm_remove(dev);
-       dpm_sysfs_remove(dev);
  PMError:
+       bus_remove_device(dev);
+ BusError:
        if (dev->bus)
                blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                             BUS_NOTIFY_DEL_DEVICE, dev);
@@ -1136,25 +1136,11 @@ error:
 }
 EXPORT_SYMBOL_GPL(device_create);
 
-/**
- * find_device - finds a device that was created with device_create()
- * @class: pointer to the struct class that this device was registered with
- * @devt: the dev_t of the device that was previously registered
- */
-static struct device *find_device(struct class *class, dev_t devt)
+static int __match_devt(struct device *dev, void *data)
 {
-       struct device *dev = NULL;
-       struct device *dev_tmp;
+       dev_t *devt = data;
 
-       down(&class->sem);
-       list_for_each_entry(dev_tmp, &class->devices, node) {
-               if (dev_tmp->devt == devt) {
-                       dev = dev_tmp;
-                       break;
-               }
-       }
-       up(&class->sem);
-       return dev;
+       return dev->devt == *devt;
 }
 
 /**
@@ -1169,39 +1155,14 @@ void device_destroy(struct class *class, dev_t devt)
 {
        struct device *dev;
 
-       dev = find_device(class, devt);
-       if (dev)
+       dev = class_find_device(class, &devt, __match_devt);
+       if (dev) {
+               put_device(dev);
                device_unregister(dev);
+       }
 }
 EXPORT_SYMBOL_GPL(device_destroy);
 
-#ifdef CONFIG_PM_SLEEP
-/**
- * destroy_suspended_device - asks the PM core to remove a suspended device
- * @class: pointer to the struct class that this device was registered with
- * @devt: the dev_t of the device that was previously registered
- *
- * This call notifies the PM core of the necessity to unregister a suspended
- * device created with a call to device_create() (devices cannot be
- * unregistered directly while suspended, since the PM core holds their
- * semaphores at that time).
- *
- * It can only be called within the scope of a system sleep transition.  In
- * practice this means it has to be directly or indirectly invoked either by
- * a suspend or resume method, or by the PM core (e.g. via
- * disable_nonboot_cpus() or enable_nonboot_cpus()).
- */
-void destroy_suspended_device(struct class *class, dev_t devt)
-{
-       struct device *dev;
-
-       dev = find_device(class, devt);
-       if (dev)
-               device_pm_schedule_removal(dev);
-}
-EXPORT_SYMBOL_GPL(destroy_suspended_device);
-#endif /* CONFIG_PM_SLEEP */
-
 /**
  * device_rename - renames a device
  * @dev: the pointer to the struct device to be renamed