diff options
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 87f378806db6..a3665659d13b 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 | ||
@@ -120,11 +122,9 @@ static void return_serial(struct usb_serial *serial) | |||
120 | if (serial == NULL) | 122 | if (serial == NULL) |
121 | return; | 123 | return; |
122 | 124 | ||
123 | spin_lock(&table_lock); | ||
124 | for (i = 0; i < serial->num_ports; ++i) { | 125 | for (i = 0; i < serial->num_ports; ++i) { |
125 | serial_table[serial->minor + i] = NULL; | 126 | serial_table[serial->minor + i] = NULL; |
126 | } | 127 | } |
127 | spin_unlock(&table_lock); | ||
128 | } | 128 | } |
129 | 129 | ||
130 | static void destroy_serial(struct kref *kref) | 130 | static void destroy_serial(struct kref *kref) |
@@ -172,7 +172,9 @@ static void destroy_serial(struct kref *kref) | |||
172 | 172 | ||
173 | void usb_serial_put(struct usb_serial *serial) | 173 | void usb_serial_put(struct usb_serial *serial) |
174 | { | 174 | { |
175 | spin_lock(&table_lock); | ||
175 | kref_put(&serial->kref, destroy_serial); | 176 | kref_put(&serial->kref, destroy_serial); |
177 | spin_unlock(&table_lock); | ||
176 | } | 178 | } |
177 | 179 | ||
178 | /***************************************************************************** | 180 | /***************************************************************************** |
@@ -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, |