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