[PATCH 2/2] [RFC] pl2303 autosuspend

Sarah Sharp <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <20071025175845.GA8987@localdomain>
Addition of autosuspend to pl2303 usb-serial converter.

Signed-off-by: Sarah Sharp <[email protected]>
---

As Alan Stern suggested, I tried to add most of the autosuspend support to
usb-serial.c (which seems to be the glue layer between the tty and the driver
for the specific usb-serial chip).  I added the claim and release interface
calls to the tty open and close functions in the usb-serial.c layer.

To enable the device to be autosuspended, the driver for the USB to serial
device would then only need to add pointers to the usb-serial.c's suspend and
resume functions and the .supports_autosuspend to their usb_driver structure.
They would also need to add a suspend/resume pointer to their usb_serial_driver
structure if they wanted the serial core to call them in its suspend/resume
functions.  It's kind of convoluted; the alternative would be to just add
suspend and resume functions to each driver.

For now, I didn't add a suspend and resume function to the usb_serial_driver
structure in pl2303.c.  (Hence the need for the first patch to avoid the NULL
pointer dereference.)  I did add the .supports_autosuspend flag to the
usb_driver structure with pointers to usb-serial.c's suspend and resume
functions.  AFAIK, this works with autosuspend in many cases.

However, I think it will break with kernel swsuspend (and writing "suspend" to
the level sysfs file) if the tty is open.  I'm looking for suggestions on how to
make it work, along with any other comments.  I was looking at taking some of
the code out of the pl2303's close function and putting into a separate kill
traffic function, but I think it would require some work to be able to be called
in interrupt context (as I think would be the case with a swsuspend?).

The other gotcha is that the pl2303 claims to support remote wakeup.  I haven't
found a good explanation on any datasheet I've seen about *when* remote wakeup
is triggered.  One datasheet for the pl2303-HX [1] lists a register RW_MODE that
if set to 0 "When engages remote wakeup, the device issues disconnect signal" or
if set to 1 "When engages remote wakeup, the device issues resume signal".  If
anyone can help me decode this, it would be appreciated.

[1]
http://www.prolific.com.tw/support/files/%5CIO%20Cable%5CPL-2303%5CDoc%5CData%20Sheet%5Cds_pl2303H_v16B.pdf

 drivers/usb/serial/pl2303.c     |    3 +++
 drivers/usb/serial/usb-serial.c |    9 +++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 1da57fd..1021f31 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -95,7 +95,10 @@ static struct usb_driver pl2303_driver = {
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.suspend =	usb_serial_suspend,
+	.resume =	usb_serial_resume,
 	.no_dynamic_id = 	1,
+	.supports_autosuspend =	1,
 };
 
 #define SET_LINE_REQUEST_TYPE		0x21
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 9af1c12..af8002e 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -225,16 +225,21 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
 			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_interface_put;
 	}
 
 	mutex_unlock(&port->mutex);
 	return 0;
 
+bailout_interface_put:
+	usb_autopm_put_interface(serial->interface);
 bailout_module_put:
 	module_put(serial->type->driver.owner);
 bailout_mutex_unlock:
@@ -274,7 +279,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
 				port->tty->driver_data = NULL;
 			port->tty = NULL;
 		}
-
+		usb_autopm_put_interface(port->serial->interface);
 		module_put(port->serial->type->driver.owner);
 	}
 
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.