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.c65
1 files changed, 57 insertions, 8 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 2683eac30c68..ce6b64c489ad 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -726,11 +726,20 @@ int device_add(struct device *dev)
726{ 726{
727 struct device *parent = NULL; 727 struct device *parent = NULL;
728 struct class_interface *class_intf; 728 struct class_interface *class_intf;
729 int error = -EINVAL; 729 int error;
730
731 error = pm_sleep_lock();
732 if (error) {
733 dev_warn(dev, "Suspicious %s during suspend\n", __FUNCTION__);
734 dump_stack();
735 return error;
736 }
730 737
731 dev = get_device(dev); 738 dev = get_device(dev);
732 if (!dev || !strlen(dev->bus_id)) 739 if (!dev || !strlen(dev->bus_id)) {
740 error = -EINVAL;
733 goto Error; 741 goto Error;
742 }
734 743
735 pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); 744 pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
736 745
@@ -795,6 +804,7 @@ int device_add(struct device *dev)
795 } 804 }
796 Done: 805 Done:
797 put_device(dev); 806 put_device(dev);
807 pm_sleep_unlock();
798 return error; 808 return error;
799 BusError: 809 BusError:
800 device_pm_remove(dev); 810 device_pm_remove(dev);
@@ -905,6 +915,7 @@ void device_del(struct device * dev)
905 struct device * parent = dev->parent; 915 struct device * parent = dev->parent;
906 struct class_interface *class_intf; 916 struct class_interface *class_intf;
907 917
918 device_pm_remove(dev);
908 if (parent) 919 if (parent)
909 klist_del(&dev->knode_parent); 920 klist_del(&dev->knode_parent);
910 if (MAJOR(dev->devt)) 921 if (MAJOR(dev->devt))
@@ -981,7 +992,6 @@ void device_del(struct device * dev)
981 if (dev->bus) 992 if (dev->bus)
982 blocking_notifier_call_chain(&dev->bus->bus_notifier, 993 blocking_notifier_call_chain(&dev->bus->bus_notifier,
983 BUS_NOTIFY_DEL_DEVICE, dev); 994 BUS_NOTIFY_DEL_DEVICE, dev);
984 device_pm_remove(dev);
985 kobject_uevent(&dev->kobj, KOBJ_REMOVE); 995 kobject_uevent(&dev->kobj, KOBJ_REMOVE);
986 kobject_del(&dev->kobj); 996 kobject_del(&dev->kobj);
987 if (parent) 997 if (parent)
@@ -1156,14 +1166,11 @@ error:
1156EXPORT_SYMBOL_GPL(device_create); 1166EXPORT_SYMBOL_GPL(device_create);
1157 1167
1158/** 1168/**
1159 * device_destroy - removes a device that was created with device_create() 1169 * find_device - finds a device that was created with device_create()
1160 * @class: pointer to the struct class that this device was registered with 1170 * @class: pointer to the struct class that this device was registered with
1161 * @devt: the dev_t of the device that was previously registered 1171 * @devt: the dev_t of the device that was previously registered
1162 *
1163 * This call unregisters and cleans up a device that was created with a
1164 * call to device_create().
1165 */ 1172 */
1166void device_destroy(struct class *class, dev_t devt) 1173static struct device *find_device(struct class *class, dev_t devt)
1167{ 1174{
1168 struct device *dev = NULL; 1175 struct device *dev = NULL;
1169 struct device *dev_tmp; 1176 struct device *dev_tmp;
@@ -1176,12 +1183,54 @@ void device_destroy(struct class *class, dev_t devt)
1176 } 1183 }
1177 } 1184 }
1178 up(&class->sem); 1185 up(&class->sem);
1186 return dev;
1187}
1179 1188
1189/**
1190 * device_destroy - removes a device that was created with device_create()
1191 * @class: pointer to the struct class that this device was registered with
1192 * @devt: the dev_t of the device that was previously registered
1193 *
1194 * This call unregisters and cleans up a device that was created with a
1195 * call to device_create().
1196 */
1197void device_destroy(struct class *class, dev_t devt)
1198{
1199 struct device *dev;
1200
1201 dev = find_device(class, devt);
1180 if (dev) 1202 if (dev)
1181 device_unregister(dev); 1203 device_unregister(dev);
1182} 1204}
1183EXPORT_SYMBOL_GPL(device_destroy); 1205EXPORT_SYMBOL_GPL(device_destroy);
1184 1206
1207#ifdef CONFIG_PM_SLEEP
1208/**
1209 * destroy_suspended_device - asks the PM core to remove a suspended device
1210 * @class: pointer to the struct class that this device was registered with
1211 * @devt: the dev_t of the device that was previously registered
1212 *
1213 * This call notifies the PM core of the necessity to unregister a suspended
1214 * device created with a call to device_create() (devices cannot be
1215 * unregistered directly while suspended, since the PM core holds their
1216 * semaphores at that time).
1217 *
1218 * It can only be called within the scope of a system sleep transition. In
1219 * practice this means it has to be directly or indirectly invoked either by
1220 * a suspend or resume method, or by the PM core (e.g. via
1221 * disable_nonboot_cpus() or enable_nonboot_cpus()).
1222 */
1223void destroy_suspended_device(struct class *class, dev_t devt)
1224{
1225 struct device *dev;
1226
1227 dev = find_device(class, devt);
1228 if (dev)
1229 device_pm_schedule_removal(dev);
1230}
1231EXPORT_SYMBOL_GPL(destroy_suspended_device);
1232#endif /* CONFIG_PM_SLEEP */
1233
1185/** 1234/**
1186 * device_rename - renames a device 1235 * device_rename - renames a device
1187 * @dev: the pointer to the struct device to be renamed 1236 * @dev: the pointer to the struct device to be renamed