diff options
| author | Oliver Neukum <oliver@neukum.org> | 2009-12-16 11:05:57 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-02 17:53:19 -0500 |
| commit | 97d35f95552c9a0ee4777a7f04431a9fd1260478 (patch) | |
| tree | bb5a2c5244b0ae17a2dd07d65e0f1637c7babb1e /drivers/usb/class/cdc-acm.c | |
| parent | 1f141ca2b1f40088203fba061cc7b1f8da7c38ab (diff) | |
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>
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index ef2e6f9c8906..6ae7ccaff07f 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -170,6 +170,7 @@ static void acm_write_done(struct acm *acm, struct acm_wb *wb) | |||
| 170 | { | 170 | { |
| 171 | wb->use = 0; | 171 | wb->use = 0; |
| 172 | acm->transmitting--; | 172 | acm->transmitting--; |
| 173 | usb_autopm_put_interface_async(acm->control); | ||
| 173 | } | 174 | } |
| 174 | 175 | ||
| 175 | /* | 176 | /* |
| @@ -211,9 +212,12 @@ static int acm_write_start(struct acm *acm, int wbn) | |||
| 211 | } | 212 | } |
| 212 | 213 | ||
| 213 | dbg("%s susp_count: %d", __func__, acm->susp_count); | 214 | dbg("%s susp_count: %d", __func__, acm->susp_count); |
| 215 | usb_autopm_get_interface_async(acm->control); | ||
| 214 | if (acm->susp_count) { | 216 | if (acm->susp_count) { |
| 215 | acm->delayed_wb = wb; | 217 | if (!acm->delayed_wb) |
| 216 | schedule_work(&acm->waker); | 218 | acm->delayed_wb = wb; |
| 219 | else | ||
| 220 | usb_autopm_put_interface_async(acm->control); | ||
| 217 | spin_unlock_irqrestore(&acm->write_lock, flags); | 221 | spin_unlock_irqrestore(&acm->write_lock, flags); |
| 218 | return 0; /* A white lie */ | 222 | return 0; /* A white lie */ |
| 219 | } | 223 | } |
| @@ -534,23 +538,6 @@ static void acm_softint(struct work_struct *work) | |||
| 534 | tty_kref_put(tty); | 538 | tty_kref_put(tty); |
| 535 | } | 539 | } |
| 536 | 540 | ||
| 537 | static void acm_waker(struct work_struct *waker) | ||
| 538 | { | ||
| 539 | struct acm *acm = container_of(waker, struct acm, waker); | ||
| 540 | int rv; | ||
| 541 | |||
| 542 | rv = usb_autopm_get_interface(acm->control); | ||
| 543 | if (rv < 0) { | ||
| 544 | dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__); | ||
| 545 | return; | ||
| 546 | } | ||
| 547 | if (acm->delayed_wb) { | ||
| 548 | acm_start_wb(acm, acm->delayed_wb); | ||
| 549 | acm->delayed_wb = NULL; | ||
| 550 | } | ||
| 551 | usb_autopm_put_interface(acm->control); | ||
| 552 | } | ||
| 553 | |||
| 554 | /* | 541 | /* |
| 555 | * TTY handlers | 542 | * TTY handlers |
| 556 | */ | 543 | */ |
| @@ -1178,7 +1165,6 @@ made_compressed_probe: | |||
| 1178 | acm->urb_task.func = acm_rx_tasklet; | 1165 | acm->urb_task.func = acm_rx_tasklet; |
| 1179 | acm->urb_task.data = (unsigned long) acm; | 1166 | acm->urb_task.data = (unsigned long) acm; |
| 1180 | INIT_WORK(&acm->work, acm_softint); | 1167 | INIT_WORK(&acm->work, acm_softint); |
| 1181 | INIT_WORK(&acm->waker, acm_waker); | ||
| 1182 | init_waitqueue_head(&acm->drain_wait); | 1168 | init_waitqueue_head(&acm->drain_wait); |
| 1183 | spin_lock_init(&acm->throttle_lock); | 1169 | spin_lock_init(&acm->throttle_lock); |
| 1184 | spin_lock_init(&acm->write_lock); | 1170 | spin_lock_init(&acm->write_lock); |
| @@ -1343,7 +1329,6 @@ static void stop_data_traffic(struct acm *acm) | |||
| 1343 | tasklet_enable(&acm->urb_task); | 1329 | tasklet_enable(&acm->urb_task); |
| 1344 | 1330 | ||
| 1345 | cancel_work_sync(&acm->work); | 1331 | cancel_work_sync(&acm->work); |
| 1346 | cancel_work_sync(&acm->waker); | ||
| 1347 | } | 1332 | } |
| 1348 | 1333 | ||
| 1349 | static void acm_disconnect(struct usb_interface *intf) | 1334 | 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 | static int acm_resume(struct usb_interface *intf) | 1420 | static int acm_resume(struct usb_interface *intf) |
| 1436 | { | 1421 | { |
| 1437 | struct acm *acm = usb_get_intfdata(intf); | 1422 | struct acm *acm = usb_get_intfdata(intf); |
| 1423 | struct acm_wb *wb; | ||
| 1438 | int rv = 0; | 1424 | int rv = 0; |
| 1439 | int cnt; | 1425 | int cnt; |
| 1440 | 1426 | ||
| @@ -1449,6 +1435,21 @@ static int acm_resume(struct usb_interface *intf) | |||
| 1449 | mutex_lock(&acm->mutex); | 1435 | mutex_lock(&acm->mutex); |
| 1450 | if (acm->port.count) { | 1436 | if (acm->port.count) { |
| 1451 | rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); | 1437 | rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); |
| 1438 | |||
| 1439 | spin_lock_irq(&acm->write_lock); | ||
| 1440 | if (acm->delayed_wb) { | ||
| 1441 | wb = acm->delayed_wb; | ||
| 1442 | acm->delayed_wb = NULL; | ||
| 1443 | spin_unlock_irq(&acm->write_lock); | ||
| 1444 | acm_start_wb(acm, acm->delayed_wb); | ||
| 1445 | } else { | ||
| 1446 | spin_unlock_irq(&acm->write_lock); | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | /* | ||
| 1450 | * delayed error checking because we must | ||
| 1451 | * do the write path at all cost | ||
| 1452 | */ | ||
| 1452 | if (rv < 0) | 1453 | if (rv < 0) |
| 1453 | goto err_out; | 1454 | goto err_out; |
| 1454 | 1455 | ||
