USB: cdc-acm: fix possible deadlock with multiple openers

The lock must be dropped before usb_autopm_interface_put() is called

Signed-off-by: Oliver Neukum <oliver@neukum.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

BUG=chrome-os-partner:3143
TEST=run power_Resume test in tight loops on Alex.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>

Review URL: http://codereview.chromium.org/6820034

Change-Id: Ic0e9c134b803393c66dbec7d4a66e2b7af5ceae4
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 5fb3117..fc74de7 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -556,7 +556,7 @@
 
 	acm = acm_table[tty->index];
 	if (!acm || !acm->dev)
-		goto err_out;
+		goto out;
 	else
 		rv = 0;
 
@@ -572,8 +572,9 @@
 
 	mutex_lock(&acm->mutex);
 	if (acm->port.count++) {
+		mutex_unlock(&acm->mutex);
 		usb_autopm_put_interface(acm->control);
-		goto done;
+		goto out;
 	}
 
 	acm->ctrlurb->dev = acm->dev;
@@ -602,18 +603,18 @@
 	set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
 	rv = tty_port_block_til_ready(&acm->port, tty, filp);
 	tasklet_schedule(&acm->urb_task);
-done:
+
 	mutex_unlock(&acm->mutex);
-err_out:
+out:
 	mutex_unlock(&open_mutex);
 	return rv;
 
 full_bailout:
 	usb_kill_urb(acm->ctrlurb);
 bail_out:
-	usb_autopm_put_interface(acm->control);
 	acm->port.count--;
 	mutex_unlock(&acm->mutex);
+	usb_autopm_put_interface(acm->control);
 early_bail:
 	mutex_unlock(&open_mutex);
 	tty_port_tty_set(&acm->port, NULL);