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

Reply via email to