[patch]autosuspend for usb serial
Oliver Neukum <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Organization | Novell |
| Message-ID | <[email protected]> |
Hi, this implements the standard open/close autosuspend support for usb serial devices. Regards Oliver Signed-off-by: Oliver Neukum <[email protected]> -- --- a/drivers/usb/serial/usb-serial.c 2007-04-27 11:19:41.000000000 +0200 +++ b/drivers/usb/serial/usb-serial.c 2007-04-27 17:52:26.000000000 +0200 @@ -50,6 +50,7 @@ static struct usb_driver usb_serial_driv .suspend = usb_serial_suspend, .resume = usb_serial_resume, .no_dynamic_id = 1, + .supports_autosuspend = 1, }; /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead @@ -226,16 +227,21 @@ static int serial_open (struct tty_struc goto bailout_mutex_unlock; } + retval = usb_autopm_get_interface(serial->interface); + if (retval) + goto bailout_module_put; + /* only call the device specific open if this * is the first time the port is opened */ retval = serial->type->open(port, filp); if (retval) - goto bailout_module_put; + goto bailout_module_put_autopm; } mutex_unlock(&port->mutex); return 0; - +bailout_module_put_autopm: + usb_autopm_put_interface(serial->interface); bailout_module_put: module_put(serial->type->driver.owner); bailout_mutex_unlock: @@ -276,6 +282,8 @@ static void serial_close(struct tty_stru port->tty = NULL; } + if (!port->disconnected) + usb_autopm_put_interface(port->serial->interface); module_put(port->serial->type->driver.owner); } @@ -1059,6 +1067,9 @@ void usb_serial_disconnect(struct usb_in if (serial) { for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; + mutex_lock(&port->mutex); + port->disconnected = 1; + mutex_unlock(&port->mutex); if (port) { if (port->tty) tty_hangup(port->tty); @@ -1078,6 +1089,7 @@ int usb_serial_suspend(struct usb_interf struct usb_serial_port *port; int i, r = 0; + dev_info(&intf->dev, "suspending device\n"); if (serial) { for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; @@ -1098,6 +1110,7 @@ int usb_serial_resume(struct usb_interfa { struct usb_serial *serial = usb_get_intfdata(intf); + dev_info(&intf->dev,"resuming device\n"); return serial->type->resume(serial); } --- a/include/linux/usb/serial.h 2007-04-27 11:21:06.000000000 +0200 +++ b/include/linux/usb/serial.h 2007-04-27 11:21:56.000000000 +0200 @@ -64,8 +64,9 @@ struct usb_serial_port { struct usb_serial * serial; struct tty_struct * tty; spinlock_t lock; - struct mutex mutex; + struct mutex mutex; unsigned char number; + unsigned char disconnected; unsigned char * interrupt_in_buffer; struct urb * interrupt_in_urb; ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ [email protected] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel