usb: cdc-acm: fix cooldown mechanism
[platform/kernel/linux-starfive.git] / drivers / usb / class / cdc-acm.c
index 30ef946..1e75688 100644 (file)
@@ -508,6 +508,7 @@ static void acm_read_bulk_callback(struct urb *urb)
                        "%s - cooling babbling device\n", __func__);
                usb_mark_last_busy(acm->dev);
                set_bit(rb->index, &acm->urbs_in_error_delay);
+               set_bit(ACM_ERROR_DELAY, &acm->flags);
                cooldown = true;
                break;
        default:
@@ -533,7 +534,7 @@ static void acm_read_bulk_callback(struct urb *urb)
 
        if (stopped || stalled || cooldown) {
                if (stalled)
-                       schedule_work(&acm->work);
+                       schedule_delayed_work(&acm->dwork, 0);
                else if (cooldown)
                        schedule_delayed_work(&acm->dwork, HZ / 2);
                return;
@@ -563,13 +564,13 @@ static void acm_write_bulk(struct urb *urb)
        acm_write_done(acm, wb);
        spin_unlock_irqrestore(&acm->write_lock, flags);
        set_bit(EVENT_TTY_WAKEUP, &acm->flags);
-       schedule_work(&acm->work);
+       schedule_delayed_work(&acm->dwork, 0);
 }
 
 static void acm_softint(struct work_struct *work)
 {
        int i;
-       struct acm *acm = container_of(work, struct acm, work);
+       struct acm *acm = container_of(work, struct acm, dwork.work);
 
        if (test_bit(EVENT_RX_STALL, &acm->flags)) {
                smp_mb(); /* against acm_suspend() */
@@ -585,7 +586,7 @@ static void acm_softint(struct work_struct *work)
        if (test_and_clear_bit(ACM_ERROR_DELAY, &acm->flags)) {
                for (i = 0; i < acm->rx_buflimit; i++)
                        if (test_and_clear_bit(i, &acm->urbs_in_error_delay))
-                                       acm_submit_read_urb(acm, i, GFP_NOIO);
+                               acm_submit_read_urb(acm, i, GFP_KERNEL);
        }
 
        if (test_and_clear_bit(EVENT_TTY_WAKEUP, &acm->flags))
@@ -1351,7 +1352,6 @@ made_compressed_probe:
        acm->ctrlsize = ctrlsize;
        acm->readsize = readsize;
        acm->rx_buflimit = num_rx_buf;
-       INIT_WORK(&acm->work, acm_softint);
        INIT_DELAYED_WORK(&acm->dwork, acm_softint);
        init_waitqueue_head(&acm->wioctl);
        spin_lock_init(&acm->write_lock);
@@ -1561,7 +1561,6 @@ static void acm_disconnect(struct usb_interface *intf)
        }
 
        acm_kill_urbs(acm);
-       cancel_work_sync(&acm->work);
        cancel_delayed_work_sync(&acm->dwork);
 
        tty_unregister_device(acm_tty_driver, acm->minor);
@@ -1604,7 +1603,6 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
                return 0;
 
        acm_kill_urbs(acm);
-       cancel_work_sync(&acm->work);
        cancel_delayed_work_sync(&acm->dwork);
        acm->urbs_in_error_delay = 0;