Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+22 −21
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ static void acm_write_done(struct acm *acm, struct acm_wb *wb)
{
	wb->use = 0;
	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);
	usb_autopm_get_interface_async(acm->control);
	if (acm->susp_count) {
		if (!acm->delayed_wb)
			acm->delayed_wb = wb;
		schedule_work(&acm->waker);
		else
			usb_autopm_put_interface_async(acm->control);
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return 0;	/* A white lie */
	}
@@ -534,23 +538,6 @@ static void acm_softint(struct work_struct *work)
	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
 */
@@ -1178,7 +1165,6 @@ made_compressed_probe:
	acm->urb_task.func = acm_rx_tasklet;
	acm->urb_task.data = (unsigned long) acm;
	INIT_WORK(&acm->work, acm_softint);
	INIT_WORK(&acm->waker, acm_waker);
	init_waitqueue_head(&acm->drain_wait);
	spin_lock_init(&acm->throttle_lock);
	spin_lock_init(&acm->write_lock);
@@ -1343,7 +1329,6 @@ static void stop_data_traffic(struct acm *acm)
	tasklet_enable(&acm->urb_task);

	cancel_work_sync(&acm->work);
	cancel_work_sync(&acm->waker);
}

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)
{
	struct acm *acm = usb_get_intfdata(intf);
	struct acm_wb *wb;
	int rv = 0;
	int cnt;

@@ -1449,6 +1435,21 @@ static int acm_resume(struct usb_interface *intf)
	mutex_lock(&acm->mutex);
	if (acm->port.count) {
		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)
			goto err_out;

+0 −1
Original line number Diff line number Diff line
@@ -112,7 +112,6 @@ struct acm {
	struct mutex mutex;
	struct usb_cdc_line_coding line;		/* bits, stop, parity */
	struct work_struct work;			/* work queue entry for line discipline waking up */
	struct work_struct waker;
	wait_queue_head_t drain_wait;			/* close processing */
	struct tasklet_struct urb_task;                 /* rx processing */
	spinlock_t throttle_lock;			/* synchronize throtteling and read callback */