diff options
author | Oliver Neukum <oneukum@suse.de> | 2007-04-27 14:54:57 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-12 19:29:44 -0400 |
commit | ec22559e0b7a05283a3413bda5d177e42c950e23 (patch) | |
tree | 5f7a9ae8907cdf910532381111ce4b8aae877e05 | |
parent | dd172d72addefd89795e819cc2cc3eb1b9d12a7f (diff) |
USB: suspend support for usb serial
this implements generic support for suspend/resume for usb serial.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/serial/generic.c | 18 | ||||
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 31 | ||||
-rw-r--r-- | 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 4f8282ad7720..b90ef3f70f4c 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 = { | |||
69 | .shutdown = usb_serial_generic_shutdown, | 69 | .shutdown = usb_serial_generic_shutdown, |
70 | .throttle = usb_serial_generic_throttle, | 70 | .throttle = usb_serial_generic_throttle, |
71 | .unthrottle = usb_serial_generic_unthrottle, | 71 | .unthrottle = usb_serial_generic_unthrottle, |
72 | .resume = usb_serial_generic_resume, | ||
72 | }; | 73 | }; |
73 | 74 | ||
74 | static int generic_probe(struct usb_interface *interface, | 75 | static int generic_probe(struct usb_interface *interface, |
@@ -169,6 +170,23 @@ static void generic_cleanup (struct usb_serial_port *port) | |||
169 | } | 170 | } |
170 | } | 171 | } |
171 | 172 | ||
173 | int usb_serial_generic_resume(struct usb_serial *serial) | ||
174 | { | ||
175 | struct usb_serial_port *port; | ||
176 | int i, c = 0, r; | ||
177 | |||
178 | for (i = 0; i < serial->num_ports; i++) { | ||
179 | port = serial->port[i]; | ||
180 | if (port->open_count && port->read_urb) { | ||
181 | r = usb_submit_urb(port->read_urb, GFP_NOIO); | ||
182 | if (r < 0) | ||
183 | c++; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | return c ? -EIO : 0; | ||
188 | } | ||
189 | |||
172 | void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp) | 190 | void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp) |
173 | { | 191 | { |
174 | dbg("%s - port %d", __FUNCTION__, port->number); | 192 | dbg("%s - port %d", __FUNCTION__, port->number); |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 87f378806db6..e3e3728e16e3 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 = { | |||
46 | .name = "usbserial", | 46 | .name = "usbserial", |
47 | .probe = usb_serial_probe, | 47 | .probe = usb_serial_probe, |
48 | .disconnect = usb_serial_disconnect, | 48 | .disconnect = usb_serial_disconnect, |
49 | .suspend = usb_serial_suspend, | ||
50 | .resume = usb_serial_resume, | ||
49 | .no_dynamic_id = 1, | 51 | .no_dynamic_id = 1, |
50 | }; | 52 | }; |
51 | 53 | ||
@@ -1069,6 +1071,35 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1069 | dev_info(dev, "device disconnected\n"); | 1071 | dev_info(dev, "device disconnected\n"); |
1070 | } | 1072 | } |
1071 | 1073 | ||
1074 | int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) | ||
1075 | { | ||
1076 | struct usb_serial *serial = usb_get_intfdata(intf); | ||
1077 | struct usb_serial_port *port; | ||
1078 | int i, r = 0; | ||
1079 | |||
1080 | if (serial) { | ||
1081 | for (i = 0; i < serial->num_ports; ++i) { | ||
1082 | port = serial->port[i]; | ||
1083 | if (port) | ||
1084 | kill_traffic(port); | ||
1085 | } | ||
1086 | } | ||
1087 | |||
1088 | if (serial->type->suspend) | ||
1089 | serial->type->suspend(serial, message); | ||
1090 | |||
1091 | return r; | ||
1092 | } | ||
1093 | EXPORT_SYMBOL(usb_serial_suspend); | ||
1094 | |||
1095 | int usb_serial_resume(struct usb_interface *intf) | ||
1096 | { | ||
1097 | struct usb_serial *serial = usb_get_intfdata(intf); | ||
1098 | |||
1099 | return serial->type->resume(serial); | ||
1100 | } | ||
1101 | EXPORT_SYMBOL(usb_serial_resume); | ||
1102 | |||
1072 | static const struct tty_operations serial_ops = { | 1103 | static const struct tty_operations serial_ops = { |
1073 | .open = serial_open, | 1104 | .open = serial_open, |
1074 | .close = serial_close, | 1105 | .close = serial_close, |
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 32acbae28d24..e8b8928232c8 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h | |||
@@ -221,6 +221,9 @@ struct usb_serial_driver { | |||
221 | int (*port_probe) (struct usb_serial_port *port); | 221 | int (*port_probe) (struct usb_serial_port *port); |
222 | int (*port_remove) (struct usb_serial_port *port); | 222 | int (*port_remove) (struct usb_serial_port *port); |
223 | 223 | ||
224 | int (*suspend) (struct usb_serial *serial, pm_message_t message); | ||
225 | int (*resume) (struct usb_serial *serial); | ||
226 | |||
224 | /* serial function calls */ | 227 | /* serial function calls */ |
225 | int (*open) (struct usb_serial_port *port, struct file * filp); | 228 | int (*open) (struct usb_serial_port *port, struct file * filp); |
226 | void (*close) (struct usb_serial_port *port, struct file * filp); | 229 | 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 | extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id); | 252 | extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id); |
250 | extern void usb_serial_disconnect(struct usb_interface *iface); | 253 | extern void usb_serial_disconnect(struct usb_interface *iface); |
251 | 254 | ||
255 | extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t message); | ||
256 | extern int usb_serial_resume(struct usb_interface *intf); | ||
257 | |||
252 | extern int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest); | 258 | extern int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest); |
253 | extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit); | 259 | extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit); |
254 | 260 | ||
@@ -269,6 +275,7 @@ extern void usb_serial_put(struct usb_serial *serial); | |||
269 | extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp); | 275 | extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp); |
270 | extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigned char *buf, int count); | 276 | extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigned char *buf, int count); |
271 | extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp); | 277 | extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp); |
278 | extern int usb_serial_generic_resume (struct usb_serial *serial); | ||
272 | extern int usb_serial_generic_write_room (struct usb_serial_port *port); | 279 | extern int usb_serial_generic_write_room (struct usb_serial_port *port); |
273 | extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port); | 280 | extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port); |
274 | extern void usb_serial_generic_read_bulk_callback (struct urb *urb); | 281 | extern void usb_serial_generic_read_bulk_callback (struct urb *urb); |