From: Ming Lei <tom.leiming@xxxxxxxxx> This patch fixes the following bug: .plug ch341 usb serial port into a hub port; .ch341 driver bound to the device and /dev/ttyUSB0 comes .open /dev/ttyUSB0 by minicom and we can use the serial successfully .suspend the ch341 usb serial device(such as: echo suspend > power/level) .resume the ch341 usb serial device (such as: echo on > power/level) .new port /dev/ttyUSB1 comes ,and the original /dev/ttyUSB0 still exists, but is no longer usable by minicom The patch adds suspend and resume callback to ch341 usb driver to prevent it from unbinding during suspend. The /dev/ttyUSB0 is not released until being closed, so /dev/ttyUSB1 comes after resume, and the original /dev/ttyUSB0 is no longer usable by minicom. It is really a mess for a minicom user. This patch also adds the reset_resume callback to make it usable after resuming from STR or hibernation, for generally STR or hibernation will make the vbus of root-hub lost. Finally enable the driver's supports_autosuspend, for the device is in working order with it. Signed-off-by: Ming Lei <tom.leiming@xxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx> --- drivers/usb/serial/ch341.c | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index d5ea679..ab4cc27 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -529,12 +529,34 @@ static int ch341_tiocmget(struct tty_struct *tty, struct file *file) return result; } + +static int ch341_reset_resume(struct usb_interface *intf) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_serial *serial = NULL; + struct ch341_private *priv; + + serial = usb_get_intfdata(intf); + priv = usb_get_serial_port_data(serial->port[0]); + + /*reconfigure ch341 serial port after bus-reset*/ + ch341_configure(dev, priv); + + usb_serial_resume(intf); + + return 0; +} + static struct usb_driver ch341_driver = { .name = "ch341", .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, + .suspend = usb_serial_suspend, + .resume = usb_serial_resume, + .reset_resume = ch341_reset_resume, .id_table = id_table, .no_dynamic_id = 1, + .supports_autosuspend = 1, }; static struct usb_serial_driver ch341_device = { -- 1.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html