Commit 97d35f95 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

USB: cdc-acm: Update to new autopm API

Update cdc-acm to the async methods eliminating the workqueue
Signed-off-by: default avatarOliver Neukum <oliver@neukum.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 1f141ca2
...@@ -170,6 +170,7 @@ static void acm_write_done(struct acm *acm, struct acm_wb *wb) ...@@ -170,6 +170,7 @@ static void acm_write_done(struct acm *acm, struct acm_wb *wb)
{ {
wb->use = 0; wb->use = 0;
acm->transmitting--; acm->transmitting--;
usb_autopm_put_interface_async(acm->control);
} }
/* /*
...@@ -211,9 +212,12 @@ static int acm_write_start(struct acm *acm, int wbn) ...@@ -211,9 +212,12 @@ static int acm_write_start(struct acm *acm, int wbn)
} }
dbg("%s susp_count: %d", __func__, acm->susp_count); dbg("%s susp_count: %d", __func__, acm->susp_count);
usb_autopm_get_interface_async(acm->control);
if (acm->susp_count) { if (acm->susp_count) {
acm->delayed_wb = wb; if (!acm->delayed_wb)
schedule_work(&acm->waker); acm->delayed_wb = wb;
else
usb_autopm_put_interface_async(acm->control);
spin_unlock_irqrestore(&acm->write_lock, flags); spin_unlock_irqrestore(&acm->write_lock, flags);
return 0; /* A white lie */ return 0; /* A white lie */
} }
...@@ -534,23 +538,6 @@ static void acm_softint(struct work_struct *work) ...@@ -534,23 +538,6 @@ static void acm_softint(struct work_struct *work)
tty_kref_put(tty); tty_kref_put(tty);
} }
static void acm_waker(struct work_struct *waker)
{
struct acm *acm = container_of(waker, struct acm, waker);
int rv;
rv = usb_autopm_get_interface(acm->control);
if (rv < 0) {
dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__);
return;
}
if (acm->delayed_wb) {
acm_start_wb(acm, acm->delayed_wb);
acm->delayed_wb = NULL;
}
usb_autopm_put_interface(acm->control);
}
/* /*
* TTY handlers * TTY handlers
*/ */
...@@ -1178,7 +1165,6 @@ static int acm_probe(struct usb_interface *intf, ...@@ -1178,7 +1165,6 @@ static int acm_probe(struct usb_interface *intf,
acm->urb_task.func = acm_rx_tasklet; acm->urb_task.func = acm_rx_tasklet;
acm->urb_task.data = (unsigned long) acm; acm->urb_task.data = (unsigned long) acm;
INIT_WORK(&acm->work, acm_softint); INIT_WORK(&acm->work, acm_softint);
INIT_WORK(&acm->waker, acm_waker);
init_waitqueue_head(&acm->drain_wait); init_waitqueue_head(&acm->drain_wait);
spin_lock_init(&acm->throttle_lock); spin_lock_init(&acm->throttle_lock);
spin_lock_init(&acm->write_lock); spin_lock_init(&acm->write_lock);
...@@ -1343,7 +1329,6 @@ static void stop_data_traffic(struct acm *acm) ...@@ -1343,7 +1329,6 @@ static void stop_data_traffic(struct acm *acm)
tasklet_enable(&acm->urb_task); tasklet_enable(&acm->urb_task);
cancel_work_sync(&acm->work); cancel_work_sync(&acm->work);
cancel_work_sync(&acm->waker);
} }
static void acm_disconnect(struct usb_interface *intf) static void acm_disconnect(struct usb_interface *intf)
...@@ -1435,6 +1420,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) ...@@ -1435,6 +1420,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
static int acm_resume(struct usb_interface *intf) static int acm_resume(struct usb_interface *intf)
{ {
struct acm *acm = usb_get_intfdata(intf); struct acm *acm = usb_get_intfdata(intf);
struct acm_wb *wb;
int rv = 0; int rv = 0;
int cnt; int cnt;
...@@ -1449,6 +1435,21 @@ static int acm_resume(struct usb_interface *intf) ...@@ -1449,6 +1435,21 @@ static int acm_resume(struct usb_interface *intf)
mutex_lock(&acm->mutex); mutex_lock(&acm->mutex);
if (acm->port.count) { if (acm->port.count) {
rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
spin_lock_irq(&acm->write_lock);
if (acm->delayed_wb) {
wb = acm->delayed_wb;
acm->delayed_wb = NULL;
spin_unlock_irq(&acm->write_lock);
acm_start_wb(acm, acm->delayed_wb);
} else {
spin_unlock_irq(&acm->write_lock);
}
/*
* delayed error checking because we must
* do the write path at all cost
*/
if (rv < 0) if (rv < 0)
goto err_out; goto err_out;
......
...@@ -112,7 +112,6 @@ struct acm { ...@@ -112,7 +112,6 @@ struct acm {
struct mutex mutex; struct mutex mutex;
struct usb_cdc_line_coding line; /* bits, stop, parity */ struct usb_cdc_line_coding line; /* bits, stop, parity */
struct work_struct work; /* work queue entry for line discipline waking up */ struct work_struct work; /* work queue entry for line discipline waking up */
struct work_struct waker;
wait_queue_head_t drain_wait; /* close processing */ wait_queue_head_t drain_wait; /* close processing */
struct tasklet_struct urb_task; /* rx processing */ struct tasklet_struct urb_task; /* rx processing */
spinlock_t throttle_lock; /* synchronize throtteling and read callback */ spinlock_t throttle_lock; /* synchronize throtteling and read callback */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment