diff options
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index da890f030fac..d595aa5586a7 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -141,6 +141,14 @@ static void destroy_serial(struct kref *kref) | |||
141 | if (serial->minor != SERIAL_TTY_NO_MINOR) | 141 | if (serial->minor != SERIAL_TTY_NO_MINOR) |
142 | return_serial(serial); | 142 | return_serial(serial); |
143 | 143 | ||
144 | serial->type->release(serial); | ||
145 | |||
146 | for (i = 0; i < serial->num_ports; ++i) { | ||
147 | port = serial->port[i]; | ||
148 | if (port) | ||
149 | put_device(&port->dev); | ||
150 | } | ||
151 | |||
144 | /* If this is a "fake" port, we have to clean it up here, as it will | 152 | /* If this is a "fake" port, we have to clean it up here, as it will |
145 | * not get cleaned up in port_release() as it was never registered with | 153 | * not get cleaned up in port_release() as it was never registered with |
146 | * the driver core */ | 154 | * the driver core */ |
@@ -148,9 +156,8 @@ static void destroy_serial(struct kref *kref) | |||
148 | for (i = serial->num_ports; | 156 | for (i = serial->num_ports; |
149 | i < serial->num_port_pointers; ++i) { | 157 | i < serial->num_port_pointers; ++i) { |
150 | port = serial->port[i]; | 158 | port = serial->port[i]; |
151 | if (!port) | 159 | if (port) |
152 | continue; | 160 | port_free(port); |
153 | port_free(port); | ||
154 | } | 161 | } |
155 | } | 162 | } |
156 | 163 | ||
@@ -1118,10 +1125,6 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1118 | serial->disconnected = 1; | 1125 | serial->disconnected = 1; |
1119 | mutex_unlock(&serial->disc_mutex); | 1126 | mutex_unlock(&serial->disc_mutex); |
1120 | 1127 | ||
1121 | /* Unfortunately, many of the sub-drivers expect the port structures | ||
1122 | * to exist when their shutdown method is called, so we have to go | ||
1123 | * through this awkward two-step unregistration procedure. | ||
1124 | */ | ||
1125 | for (i = 0; i < serial->num_ports; ++i) { | 1128 | for (i = 0; i < serial->num_ports; ++i) { |
1126 | port = serial->port[i]; | 1129 | port = serial->port[i]; |
1127 | if (port) { | 1130 | if (port) { |
@@ -1153,14 +1156,7 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1153 | } | 1156 | } |
1154 | } | 1157 | } |
1155 | } | 1158 | } |
1156 | serial->type->shutdown(serial); | 1159 | serial->type->disconnect(serial); |
1157 | for (i = 0; i < serial->num_ports; ++i) { | ||
1158 | port = serial->port[i]; | ||
1159 | if (port) { | ||
1160 | put_device(&port->dev); | ||
1161 | serial->port[i] = NULL; | ||
1162 | } | ||
1163 | } | ||
1164 | 1160 | ||
1165 | /* let the last holder of this object | 1161 | /* let the last holder of this object |
1166 | * cause it to be cleaned up */ | 1162 | * cause it to be cleaned up */ |
@@ -1338,7 +1334,8 @@ static void fixup_generic(struct usb_serial_driver *device) | |||
1338 | set_to_generic_if_null(device, chars_in_buffer); | 1334 | set_to_generic_if_null(device, chars_in_buffer); |
1339 | set_to_generic_if_null(device, read_bulk_callback); | 1335 | set_to_generic_if_null(device, read_bulk_callback); |
1340 | set_to_generic_if_null(device, write_bulk_callback); | 1336 | set_to_generic_if_null(device, write_bulk_callback); |
1341 | set_to_generic_if_null(device, shutdown); | 1337 | set_to_generic_if_null(device, disconnect); |
1338 | set_to_generic_if_null(device, release); | ||
1342 | } | 1339 | } |
1343 | 1340 | ||
1344 | int usb_serial_register(struct usb_serial_driver *driver) | 1341 | int usb_serial_register(struct usb_serial_driver *driver) |