diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index a0d284ef3f40a..203bbd3788587 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -96,6 +96,7 @@ struct wdm_device {
 	struct mutex		rlock;
 	wait_queue_head_t	wait;
 	struct work_struct	rxwork;
+	struct work_struct	service_outs_intr;
 	int			werr;
 	int			rerr;
 	int                     resp_count;
@@ -151,9 +152,6 @@ static void wdm_out_callback(struct urb *urb)
 	wake_up(&desc->wait);
 }
 
-/* forward declaration */
-static int service_outstanding_interrupt(struct wdm_device *desc);
-
 static void wdm_in_callback(struct urb *urb)
 {
 	struct wdm_device *desc = urb->context;
@@ -209,8 +207,6 @@ static void wdm_in_callback(struct urb *urb)
 		}
 	}
 skip_error:
-	set_bit(WDM_READ, &desc->flags);
-	wake_up(&desc->wait);
 
 	if (desc->rerr) {
 		/*
@@ -219,9 +215,11 @@ static void wdm_in_callback(struct urb *urb)
 		 * We should respond to further attempts from the device to send
 		 * data, so that we can get unstuck.
 		 */
-		service_outstanding_interrupt(desc);
+		schedule_work(&desc->service_outs_intr);
+	} else {
+		set_bit(WDM_READ, &desc->flags);
+		wake_up(&desc->wait);
 	}
-
 	spin_unlock(&desc->iuspin);
 }
 
@@ -758,6 +756,21 @@ static void wdm_rxwork(struct work_struct *work)
 	}
 }
 
+static void service_interrupt_work(struct work_struct *work)
+{
+	struct wdm_device *desc;
+
+	desc = container_of(work, struct wdm_device, service_outs_intr);
+
+	spin_lock_irq(&desc->iuspin);
+	service_outstanding_interrupt(desc);
+	if (!desc->resp_count) {
+		set_bit(WDM_READ, &desc->flags);
+		wake_up(&desc->wait);
+	}
+	spin_unlock_irq(&desc->iuspin);
+}
+
 /* --- hotplug --- */
 
 static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor *ep,
@@ -779,6 +792,7 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
 	desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
 	desc->intf = intf;
 	INIT_WORK(&desc->rxwork, wdm_rxwork);
+	INIT_WORK(&desc->service_outs_intr, service_interrupt_work);
 
 	rv = -EINVAL;
 	if (!usb_endpoint_is_int_in(ep))
@@ -964,6 +978,7 @@ static void wdm_disconnect(struct usb_interface *intf)
 	mutex_lock(&desc->wlock);
 	kill_urbs(desc);
 	cancel_work_sync(&desc->rxwork);
+	cancel_work_sync(&desc->service_outs_intr);
 	mutex_unlock(&desc->wlock);
 	mutex_unlock(&desc->rlock);
 
@@ -1006,6 +1021,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
 		/* callback submits work - order is essential */
 		kill_urbs(desc);
 		cancel_work_sync(&desc->rxwork);
+		cancel_work_sync(&desc->service_outs_intr);
 	}
 	if (!PMSG_IS_AUTO(message)) {
 		mutex_unlock(&desc->wlock);
@@ -1065,6 +1081,7 @@ static int wdm_pre_reset(struct usb_interface *intf)
 	mutex_lock(&desc->wlock);
 	kill_urbs(desc);
 	cancel_work_sync(&desc->rxwork);
+	cancel_work_sync(&desc->service_outs_intr);
 	return 0;
 }