@@ -1218,6 +1218,53 @@ static void pl2303_process_read_urb(struct urb *urb)
tty_flip_buffer_push(&port->port);
}
+static int pl2303_configure(struct usb_serial *serial, struct pl2303_serial_private *priv)
+{
+ struct usb_serial_port *port = serial->port[0];
+
+ if (priv->quirks & PL2303_QUIRK_LEGACY) {
+ usb_clear_halt(serial->dev, port->write_urb->pipe);
+ usb_clear_halt(serial->dev, port->read_urb->pipe);
+ } else {
+ /* reset upstream data pipes */
+ if (priv->type == &pl2303_type_data[TYPE_HXN])
+ pl2303_vendor_write(serial, PL2303_HXN_RESET_REG,
+ PL2303_HXN_RESET_UPSTREAM_PIPE |
+ PL2303_HXN_RESET_DOWNSTREAM_PIPE);
+ else {
+ pl2303_vendor_write(serial, 8, 0);
+ pl2303_vendor_write(serial, 9, 0);
+ }
+ }
+ return 0;
+}
+
+static int pl2303_reset_resume(struct usb_serial *serial)
+{
+ struct usb_serial_port *port = serial->port[0];
+ struct pl2303_serial_private *priv = usb_get_serial_port_data(port);
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ int ret;
+
+ /* reconfigure pl2303 serial port after bus-reset */
+ pl2303_configure(serial, priv);
+
+ /* Setup termios */
+ if (tty)
+ pl2303_set_termios(tty, port, NULL);
+
+ if (tty_port_initialized(&port->port)) {
+ ret = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
+ if (ret) {
+ dev_err(&port->dev, "failed to submit interrupt urb: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return usb_serial_generic_resume(serial);
+}
+
static struct usb_serial_driver pl2303_device = {
.driver = {
.owner = THIS_MODULE,
@@ -1246,6 +1293,7 @@ static struct usb_serial_driver pl2303_device = {
.release = pl2303_release,
.port_probe = pl2303_port_probe,
.port_remove = pl2303_port_remove,
+ .reset_resume = pl2303_reset_resume,
};
static struct usb_serial_driver * const serial_drivers[] = {