[rft]autosuspend for option driver (resend)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

this works for me, but I am looking for testers.
This patch in conjunction with the patch I sent earlier today,
implements autosuspend for the option driver.

	Regards
		Oliver

----

commit 30860299d437a691d21eef6d3b0c92b5d6a40495
Author: Oliver Neukum <oneukum@xxxxxxx>
Date:   Fri Jan 23 18:30:35 2009 +0100

    autosuspend for option

diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index da582f8..955ba1c 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -493,6 +493,7 @@ static struct usb_driver option_driver = {
 	.resume     = usb_serial_resume,
 	.id_table   = option_ids,
 	.no_dynamic_id = 	1,
+	.supports_autosuspend =	1,
 };
 
 /* The card has three separate interfaces, which the serial driver
@@ -860,6 +861,10 @@ static int option_open(struct tty_struct *tty,
 	portdata->rts_state = 1;
 	portdata->dtr_state = 1;
 
+	err = usb_autopm_get_interface(serial->interface);
+	if (err < 0)
+		return err;
+
 	/* Reset low level data toggle and start reading from endpoints */
 	for (i = 0; i < N_IN_URB; i++) {
 		urb = portdata->in_urbs[i];
@@ -927,6 +932,10 @@ static void option_close(struct tty_struct *tty,
 			usb_kill_urb(portdata->in_urbs[i]);
 		for (i = 0; i < N_OUT_URB; i++)
 			usb_kill_urb(portdata->out_urbs[i]);
+		mutex_lock(&serial->disc_mutex);
+		if (!serial->disconnected)
+			usb_autopm_put_interface(serial->interface);
+		mutex_unlock(&serial->disc_mutex);
 	}
 	tty_port_tty_set(&port->port, NULL);
 }
@@ -1167,25 +1176,20 @@ static int option_resume(struct usb_serial *serial)
 		/* walk all ports */
 		port = serial->port[i];
 		portdata = usb_get_serial_port_data(port);
-		mutex_lock(&port->mutex);
 
 		/* skip closed ports */
-		if (!port->port.count) {
-			mutex_unlock(&port->mutex);
+		if (!port->port.count)
 			continue;
-		}
 
 		for (j = 0; j < N_IN_URB; j++) {
 			urb = portdata->in_urbs[j];
 			err = usb_submit_urb(urb, GFP_NOIO);
 			if (err < 0) {
-				mutex_unlock(&port->mutex);
 				err("%s: Error %d for bulk URB %d",
 					 __func__, err, i);
 				return err;
 			}
 		}
-		mutex_unlock(&port->mutex);
 	}
 	return 0;
 }
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index cfcfd5a..6b020f8 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -209,14 +209,12 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
 		goto bailout_kref_put;
 	}
 
-	++port->port.count;
-
 	/* set up our port structure making the tty driver
 	 * remember our port object, and us it */
 	tty->driver_data = port;
 	tty_port_tty_set(&port->port, tty);
 
-	if (port->port.count == 1) {
+	if (!port->port.count) {
 
 		/* lock this module before we call it
 		 * this may fail, which means we must bail out,
@@ -236,6 +234,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
 			goto bailout_interface_put;
 	}
 
+	port->port.count++;
+
 	mutex_unlock(&port->mutex);
 	return 0;
 
@@ -244,7 +244,6 @@ bailout_interface_put:
 bailout_module_put:
 	module_put(serial->type->driver.owner);
 bailout_mutex_unlock:
-	port->port.count = 0;
 	tty->driver_data = NULL;
 	tty_port_tty_set(&port->port, NULL);
 	mutex_unlock(&port->mutex);
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux