USB: cdc-acm: Update to new autopm API
Update cdc-acm to the async methods eliminating the workqueue Signed-off-by: Oliver Neukum <oliver@neukum.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
1f141ca2b1
commit
97d35f9555
@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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 @@ made_compressed_probe:
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user