Commit ec22559e authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

USB: suspend support for usb serial

this implements generic support for suspend/resume for usb serial.
Signed-off-by: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent dd172d72
...@@ -69,6 +69,7 @@ struct usb_serial_driver usb_serial_generic_device = { ...@@ -69,6 +69,7 @@ struct usb_serial_driver usb_serial_generic_device = {
.shutdown = usb_serial_generic_shutdown, .shutdown = usb_serial_generic_shutdown,
.throttle = usb_serial_generic_throttle, .throttle = usb_serial_generic_throttle,
.unthrottle = usb_serial_generic_unthrottle, .unthrottle = usb_serial_generic_unthrottle,
.resume = usb_serial_generic_resume,
}; };
static int generic_probe(struct usb_interface *interface, static int generic_probe(struct usb_interface *interface,
...@@ -169,6 +170,23 @@ static void generic_cleanup (struct usb_serial_port *port) ...@@ -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) void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp)
{ {
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
......
...@@ -46,6 +46,8 @@ static struct usb_driver usb_serial_driver = { ...@@ -46,6 +46,8 @@ static struct usb_driver usb_serial_driver = {
.name = "usbserial", .name = "usbserial",
.probe = usb_serial_probe, .probe = usb_serial_probe,
.disconnect = usb_serial_disconnect, .disconnect = usb_serial_disconnect,
.suspend = usb_serial_suspend,
.resume = usb_serial_resume,
.no_dynamic_id = 1, .no_dynamic_id = 1,
}; };
...@@ -1069,6 +1071,35 @@ void usb_serial_disconnect(struct usb_interface *interface) ...@@ -1069,6 +1071,35 @@ void usb_serial_disconnect(struct usb_interface *interface)
dev_info(dev, "device disconnected\n"); 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 = { static const struct tty_operations serial_ops = {
.open = serial_open, .open = serial_open,
.close = serial_close, .close = serial_close,
......
...@@ -221,6 +221,9 @@ struct usb_serial_driver { ...@@ -221,6 +221,9 @@ struct usb_serial_driver {
int (*port_probe) (struct usb_serial_port *port); int (*port_probe) (struct usb_serial_port *port);
int (*port_remove) (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 */ /* serial function calls */
int (*open) (struct usb_serial_port *port, struct file * filp); int (*open) (struct usb_serial_port *port, struct file * filp);
void (*close) (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); ...@@ -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 int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
extern void usb_serial_disconnect(struct usb_interface *iface); 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_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); 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); ...@@ -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_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 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 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_write_room (struct usb_serial_port *port);
extern int usb_serial_generic_chars_in_buffer (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); extern void usb_serial_generic_read_bulk_callback (struct urb *urb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment