diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index eefc98584eac92e86be28c55836f532a60e9065a..92ecc4eb1e88ce44b499f2acda20675e90ac73f7 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -755,48 +755,57 @@ EXPORT_SYMBOL_GPL_FUTURE(usb_deregister);
 static int suspend_device(struct usb_device *udev, pm_message_t msg)
 {
 	struct usb_device_driver	*udriver;
+	int				status = 0;
 
 	if (udev->dev.driver == NULL)
-		return 0;
+		goto done;
 	udriver = to_usb_device_driver(udev->dev.driver);
 	if (udev->dev.power.power_state.event == msg.event)
-		return 0;
-	return udriver->suspend(udev, msg);
+		goto done;
+	status = udriver->suspend(udev, msg);
+
+done:
+	if (status == 0)
+		udev->dev.power.power_state.event = msg.event;
+	return status;
 }
 
 /* Caller has locked udev */
 static int resume_device(struct usb_device *udev)
 {
 	struct usb_device_driver	*udriver;
+	int				status = 0;
 
 	if (udev->dev.power.power_state.event == PM_EVENT_ON)
-		return 0;
-
-	/* mark things as "on" immediately, no matter what errors crop up */
-	udev->dev.power.power_state.event = PM_EVENT_ON;
+		goto done;
 
 	if (udev->dev.driver == NULL)
-		return 0;
+		goto done;
 	udriver = to_usb_device_driver(udev->dev.driver);
 	if (udev->state == USB_STATE_NOTATTACHED)
-		return 0;
-	return udriver->resume(udev);
+		goto done;
+	status = udriver->resume(udev);
+
+done:
+	if (status == 0)
+		udev->dev.power.power_state.event = PM_EVENT_ON;
+	return status;
 }
 
 /* Caller has locked intf's usb_device */
 static int suspend_interface(struct usb_interface *intf, pm_message_t msg)
 {
 	struct usb_driver	*driver;
-	int			status;
+	int			status = 0;
 
 	if (intf->dev.driver == NULL)
-		return 0;
+		goto done;
 
 	driver = to_usb_driver(intf->dev.driver);
 
 	/* with no hardware, USB interfaces only use FREEZE and ON states */
 	if (!is_active(intf))
-		return 0;
+		goto done;
 
 	if (driver->suspend && driver->resume) {
 		status = driver->suspend(intf, msg);
@@ -810,8 +819,11 @@ static int suspend_interface(struct usb_interface *intf, pm_message_t msg)
 		dev_warn(&intf->dev, "no suspend for driver %s?\n",
 				driver->name);
 		mark_quiesced(intf);
-		status = 0;
 	}
+
+done:
+	if (status == 0)
+		intf->dev.power.power_state.event = msg.event;
 	return status;
 }
 
@@ -820,24 +832,19 @@ static int resume_interface(struct usb_interface *intf)
 {
 	struct usb_driver	*driver;
 	struct usb_device	*udev;
-	int			status;
+	int			status = 0;
 
 	if (intf->dev.power.power_state.event == PM_EVENT_ON)
-		return 0;
-
-	/* mark things as "on" immediately, no matter what errors crop up */
-	intf->dev.power.power_state.event = PM_EVENT_ON;
+		goto done;
 
-	if (intf->dev.driver == NULL) {
-		intf->dev.power.power_state.event = PM_EVENT_FREEZE;
-		return 0;
-	}
+	if (intf->dev.driver == NULL)
+		goto done;
 
 	driver = to_usb_driver(intf->dev.driver);
 
 	udev = interface_to_usbdev(intf);
 	if (udev->state == USB_STATE_NOTATTACHED)
-		return 0;
+		goto done;
 
 	/* if driver was suspended, it has a resume method;
 	 * however, sysfs can wrongly mark things as suspended
@@ -845,15 +852,21 @@ static int resume_interface(struct usb_interface *intf)
 	 */
 	if (driver->resume) {
 		status = driver->resume(intf);
-		if (status) {
+		if (status)
 			dev_err(&intf->dev, "%s error %d\n",
 					"resume", status);
-			mark_quiesced(intf);
-		}
-	} else
+		else
+			mark_active(intf);
+	} else {
 		dev_warn(&intf->dev, "no resume for driver %s?\n",
 				driver->name);
-	return 0;
+		mark_active(intf);
+	}
+
+done:
+	if (status == 0)
+		intf->dev.power.power_state.event = PM_EVENT_ON;
+	return status;
 }
 
 /* Caller has locked udev */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a39112041e6932131fc12db5e6042eb4527c2f66..7af53db4d76ff6e827bb93e60e9aaa593fee9e22 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1582,9 +1582,10 @@ static int __usb_port_suspend (struct usb_device *udev, int port1)
 	if (udev->parent)
 		status = hub_port_suspend(hdev_to_hub(udev->parent), port1,
 				udev);
-
-	if (status == 0)
-		udev->dev.power.power_state = PMSG_SUSPEND;
+	else {
+		dev_dbg(&udev->dev, "usb suspend\n");
+		usb_set_device_state(udev, USB_STATE_SUSPENDED);
+	}
 	return status;
 }
 
@@ -1617,8 +1618,6 @@ int usb_port_suspend(struct usb_device *udev)
 		return -ENODEV;
 	return __usb_port_suspend(udev, udev->portnum);
 #else
-	/* NOTE:  udev->state unchanged, it's not lying ... */
-	udev->dev.power.power_state = PMSG_SUSPEND;
 	return 0;
 #endif
 }
@@ -1647,7 +1646,6 @@ static int finish_port_resume(struct usb_device *udev)
 	usb_set_device_state(udev, udev->actconfig
 			? USB_STATE_CONFIGURED
 			: USB_STATE_ADDRESS);
-	udev->dev.power.power_state = PMSG_ON;
 
  	/* 10.5.4.5 says be sure devices in the tree are still there.
  	 * For now let's assume the device didn't go crazy on resume,