* Input submission and I/O error handler.
  */
 static DEFINE_MUTEX(hid_open_mut);
-static struct workqueue_struct *resumption_waker;
 
 static void hid_io_error(struct hid_device *hid);
 static int hid_submit_out(struct hid_device *hid);
        struct hid_report *report;
        char *raw_report;
        struct usbhid_device *usbhid = hid->driver_data;
+       int r;
 
        report = usbhid->out[usbhid->outtail].report;
        raw_report = usbhid->out[usbhid->outtail].raw_report;
 
+       r = usb_autopm_get_interface_async(usbhid->intf);
+       if (r < 0)
+               return -1;
+
+       /*
+        * if the device hasn't been woken, we leave the output
+        * to resume()
+        */
        if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
                usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
                usbhid->urbout->dev = hid_to_usb_dev(hid);
 
                if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
                        hid_err(hid, "usb_submit_urb(out) failed\n");
+                       usb_autopm_put_interface_async(usbhid->intf);
                        return -1;
                }
                usbhid->last_out = jiffies;
-       } else {
-               /*
-                * queue work to wake up the device.
-                * as the work queue is freezeable, this is safe
-                * with respect to STD and STR
-                */
-               queue_work(resumption_waker, &usbhid->restart_work);
        }
 
        return 0;
        struct hid_report *report;
        unsigned char dir;
        char *raw_report;
-       int len;
+       int len, r;
        struct usbhid_device *usbhid = hid->driver_data;
 
        report = usbhid->ctrl[usbhid->ctrltail].report;
        raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
        dir = usbhid->ctrl[usbhid->ctrltail].dir;
 
+       r = usb_autopm_get_interface_async(usbhid->intf);
+       if (r < 0)
+               return -1;
        if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
                len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
                if (dir == USB_DIR_OUT) {
                        usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
 
                if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
+                       usb_autopm_put_interface_async(usbhid->intf);
                        hid_err(hid, "usb_submit_urb(ctrl) failed\n");
                        return -1;
                }
                usbhid->last_ctrl = jiffies;
-       } else {
-               /*
-                * queue work to wake up the device.
-                * as the work queue is freezeable, this is safe
-                * with respect to STD and STR
-                */
-               queue_work(resumption_waker, &usbhid->restart_work);
        }
 
        return 0;
 
        clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
        spin_unlock_irqrestore(&usbhid->lock, flags);
+       usb_autopm_put_interface_async(usbhid->intf);
        wake_up(&usbhid->wait);
 }
 
                        wake_up(&usbhid->wait);
                }
                spin_unlock(&usbhid->lock);
+               usb_autopm_put_interface_async(usbhid->intf);
                return;
        }
 
        clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
        spin_unlock(&usbhid->lock);
+       usb_autopm_put_interface_async(usbhid->intf);
        wake_up(&usbhid->wait);
 }
 
        mutex_lock(&hid_open_mut);
        if (!hid->open++) {
                res = usb_autopm_get_interface(usbhid->intf);
-               /* the device must be awake to reliable request remote wakeup */
+               /* the device must be awake to reliably request remote wakeup */
                if (res < 0) {
                        hid->open--;
                        mutex_unlock(&hid_open_mut);
        usbhid_restart_ctrl_queue(usbhid);
 }
 
-static void __usbhid_restart_queues(struct work_struct *work)
-{
-       struct usbhid_device *usbhid =
-               container_of(work, struct usbhid_device, restart_work);
-       int r;
-
-       r = usb_autopm_get_interface(usbhid->intf);
-       if (r < 0)
-               return;
-       usb_autopm_put_interface(usbhid->intf);
-}
-
 static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
 {
        struct usbhid_device *usbhid = hid->driver_data;
 
        init_waitqueue_head(&usbhid->wait);
        INIT_WORK(&usbhid->reset_work, hid_reset);
-       INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
        setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
        spin_lock_init(&usbhid->lock);
 
 static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
 {
        del_timer_sync(&usbhid->io_retry);
-       cancel_work_sync(&usbhid->restart_work);
        cancel_work_sync(&usbhid->reset_work);
 }
 
        spin_lock_irq(&usbhid->lock);
        set_bit(HID_RESET_PENDING, &usbhid->iofl);
        spin_unlock_irq(&usbhid->lock);
-       cancel_work_sync(&usbhid->restart_work);
        hid_cease_io(usbhid);
 
        return 0;
 {
        int retval = -ENOMEM;
 
-       resumption_waker = create_freezeable_workqueue("usbhid_resumer");
-       if (!resumption_waker)
-               goto no_queue;
        retval = hid_register_driver(&hid_usb_driver);
        if (retval)
                goto hid_register_fail;
 usbhid_quirks_init_fail:
        hid_unregister_driver(&hid_usb_driver);
 hid_register_fail:
-       destroy_workqueue(resumption_waker);
-no_queue:
        return retval;
 }
 
        usb_deregister(&hid_driver);
        usbhid_quirks_exit();
        hid_unregister_driver(&hid_usb_driver);
-       destroy_workqueue(resumption_waker);
 }
 
 module_init(hid_init);