From: Oliver Neukum <[EMAIL PROTECTED]>
this implements generic support for suspend/resume for usb serial.
Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
drivers/usb/serial/generic.c | 18 ++++++++++++++++++
drivers/usb/serial/usb-serial.c | 31 +++++++++++++++++++++++++++++++
include/linux/usb/serial.h | 7 +++++++
3 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 4f8282a..b90ef3f 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -69,6 +69,7 @@ struct usb_serial_driver usb_serial_generic_device = {
.shutdown = usb_serial_generic_shutdown,
.throttle = usb_serial_generic_throttle,
.unthrottle = usb_serial_generic_unthrottle,
+ .resume = usb_serial_generic_resume,
};
static int generic_probe(struct usb_interface *interface,
@@ -169,6 +170,23 @@ static void generic_cleanup (struct usb_serial_port *port)
}
}
+int usb_serial_generic_resume(struct usb_serial *serial)
+{
+ struct usb_serial_port *port;
+ int i, c = 0, r;
+
+ for (i = 0; i < serial->num_ports; i++) {
+ port = serial->port[i];
+ if (port->open_count && port->read_urb) {
+ r = usb_submit_urb(port->read_urb, GFP_NOIO);
+ if (r < 0)
+ c++;
+ }
+ }
+
+ return c ? -EIO : 0;
+}
+
void usb_serial_generic_close (struct usb_serial_port *port, struct file *
filp)
{
dbg("%s - port %d", __FUNCTION__, port->number);
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 87f3788..e3e3728 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -46,6 +46,8 @@ static struct usb_driver usb_serial_driver = {
.name = "usbserial",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
+ .suspend = usb_serial_suspend,
+ .resume = usb_serial_resume,
.no_dynamic_id = 1,
};
@@ -1069,6 +1071,35 @@ void usb_serial_disconnect(struct usb_interface
*interface)
dev_info(dev, "device disconnected\n");
}
+int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct usb_serial *serial = usb_get_intfdata(intf);
+ struct usb_serial_port *port;
+ int i, r = 0;
+
+ if (serial) {
+ for (i = 0; i < serial->num_ports; ++i) {
+ port = serial->port[i];
+ if (port)
+ kill_traffic(port);
+ }
+ }
+
+ if (serial->type->suspend)
+ serial->type->suspend(serial, message);
+
+ return r;
+}
+EXPORT_SYMBOL(usb_serial_suspend);
+
+int usb_serial_resume(struct usb_interface *intf)
+{
+ struct usb_serial *serial = usb_get_intfdata(intf);
+
+ return serial->type->resume(serial);
+}
+EXPORT_SYMBOL(usb_serial_resume);
+
static const struct tty_operations serial_ops = {
.open = serial_open,
.close = serial_close,
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 32acbae..e8b8928 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -221,6 +221,9 @@ struct usb_serial_driver {
int (*port_probe) (struct usb_serial_port *port);
int (*port_remove) (struct usb_serial_port *port);
+ int (*suspend) (struct usb_serial *serial, pm_message_t message);
+ int (*resume) (struct usb_serial *serial);
+
/* serial function calls */
int (*open) (struct usb_serial_port *port, struct file *
filp);
void (*close) (struct usb_serial_port *port, struct file *
filp);
@@ -249,6 +252,9 @@ extern void usb_serial_port_softint(struct usb_serial_port
*port);
extern int usb_serial_probe(struct usb_interface *iface, const struct
usb_device_id *id);
extern void usb_serial_disconnect(struct usb_interface *iface);
+extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t
message);
+extern int usb_serial_resume(struct usb_interface *intf);
+
extern int ezusb_writememory (struct usb_serial *serial, int address, unsigned
char *data, int length, __u8 bRequest);
extern int ezusb_set_reset (struct usb_serial *serial, unsigned char
reset_bit);
@@ -269,6 +275,7 @@ extern void usb_serial_put(struct usb_serial *serial);
extern int usb_serial_generic_open (struct usb_serial_port *port, struct file
*filp);
extern int usb_serial_generic_write (struct usb_serial_port *port, const
unsigned char *buf, int count);
extern void usb_serial_generic_close (struct usb_serial_port *port, struct
file *filp);
+extern int usb_serial_generic_resume (struct usb_serial *serial);
extern int usb_serial_generic_write_room (struct usb_serial_port *port);
extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
extern void usb_serial_generic_read_bulk_callback (struct urb *urb);
--
1.5.2.2
-------------------------------------------------------------------------
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