summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-22 23:09:42 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-22 23:09:42 -0700
commit5fa21d821f6972e70942f2c555ec29dde962bdb2 (patch)
treefbe0a083ce7fc7ddb58cd452d5598662acac325b
parent8542e5893c2b10b4f6c80149e7dc3fdd2dc38bc6 (diff)
parent5d9fd169c9fbdaecdc430431e59bf94ff40b93d3 (diff)
downloadlwn-5fa21d821f6972e70942f2c555ec29dde962bdb2.tar.gz
lwn-5fa21d821f6972e70942f2c555ec29dde962bdb2.zip
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: [PATCH] Driver core: fix locking issues with the devices that are attached to classes [PATCH] USB: get USB suspend to work again
-rw-r--r--drivers/base/core.c19
-rw-r--r--drivers/usb/core/usb.c2
2 files changed, 13 insertions, 8 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index d0f84ff78776..27c2176895de 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -356,6 +356,13 @@ int device_add(struct device *dev)
if (parent)
klist_add_tail(&dev->knode_parent, &parent->klist_children);
+ if (dev->class) {
+ /* tie the class to the device */
+ down(&dev->class->sem);
+ list_add_tail(&dev->node, &dev->class->devices);
+ up(&dev->class->sem);
+ }
+
/* notify platform of device entry */
if (platform_notify)
platform_notify(dev);
@@ -455,6 +462,9 @@ void device_del(struct device * dev)
sysfs_remove_link(&dev->kobj, "device");
sysfs_remove_link(&dev->parent->kobj, class_name);
kfree(class_name);
+ down(&dev->class->sem);
+ list_del_init(&dev->node);
+ up(&dev->class->sem);
}
device_remove_file(dev, &dev->uevent_attr);
@@ -601,11 +611,6 @@ struct device *device_create(struct class *class, struct device *parent,
if (retval)
goto error;
- /* tie the class to the device */
- down(&class->sem);
- list_add_tail(&dev->node, &class->devices);
- up(&class->sem);
-
return dev;
error:
@@ -636,9 +641,7 @@ void device_destroy(struct class *class, dev_t devt)
}
up(&class->sem);
- if (dev) {
- list_del_init(&dev->node);
+ if (dev)
device_unregister(dev);
- }
}
EXPORT_SYMBOL_GPL(device_destroy);
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 515310751303..fb488c8a860c 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -991,6 +991,8 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
static int verify_suspended(struct device *dev, void *unused)
{
+ if (dev->driver == NULL)
+ return 0;
return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0;
}