diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3924dd080bea23d2e33d417ee72f86e1cc5133dc..bdf5be0996506802e0b3fa5d91a044c9656e4182 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1658,6 +1658,8 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
 
 	// dev_dbg(hub->intfdev, "resume port %d\n", port1);
 
+	set_bit(port1, hub->busy_bits);
+
 	/* see 7.1.7.7; affects power usage, but not budgeting */
 	status = clear_port_feature(hub->hdev,
 			port1, USB_PORT_FEAT_SUSPEND);
@@ -1707,6 +1709,10 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
 	if (status < 0)
 		hub_port_logical_disconnect(hub, port1);
 
+	clear_bit(port1, hub->busy_bits);
+	if (!hub->hdev->parent && !hub->busy_bits[0])
+		usb_enable_root_hub_irq(hub->hdev->bus);
+
 	return status;
 }
 
@@ -2690,7 +2696,7 @@ static void hub_events(void)
 
 		/* If this is a root hub, tell the HCD it's okay to
 		 * re-enable port-change interrupts now. */
-		if (!hdev->parent)
+		if (!hdev->parent && !hub->busy_bits[0])
 			usb_enable_root_hub_irq(hdev->bus);
 
 loop:
@@ -2865,6 +2871,9 @@ int usb_reset_device(struct usb_device *udev)
 			break;
 	}
 	clear_bit(port1, parent_hub->busy_bits);
+	if (!parent_hdev->parent && !parent_hub->busy_bits[0])
+		usb_enable_root_hub_irq(parent_hdev->bus);
+
 	if (ret < 0)
 		goto re_enumerate;
  
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 29d5f45a8456369f39dd1ed79d8853b40a5cefa7..0f8e82a4d48067da7d547344e41e30b28c123b55 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -212,7 +212,8 @@ struct usb_hub {
 	unsigned long		event_bits[1];	/* status change bitmask */
 	unsigned long		change_bits[1];	/* ports with logical connect
 							status change */
-	unsigned long		busy_bits[1];	/* ports being reset */
+	unsigned long		busy_bits[1];	/* ports being reset or
+							resumed */
 #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
 #error event_bits[] is too short!
 #endif