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
diff --git a/drivers/base/core.c b/drivers/base/core.c
index d0f84ff..27c2176 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -356,6 +356,13 @@
 	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 @@
 		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 @@
 	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 @@
 	}
 	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 5153107..fb488c8 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -991,6 +991,8 @@
 
 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;
 }