aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMing Lei <tom.leiming@gmail.com>2009-02-20 08:23:09 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 19:20:36 -0400
commit1ded7ea47b8829a06068c3bb5e3ebe471076617a (patch)
tree113e3daefadaec5e25c7b4b8a7ce3cff23ba0327
parenta227fd7db74fa05d866790a4b29ba049bb5035cc (diff)
USB: ch341 serial: fix port number changed after resume
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@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/serial/ch341.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index d5ea679e1698..ab4cc277aa65 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)
529 return result; 529 return result;
530} 530}
531 531
532
533static int ch341_reset_resume(struct usb_interface *intf)
534{
535 struct usb_device *dev = interface_to_usbdev(intf);
536 struct usb_serial *serial = NULL;
537 struct ch341_private *priv;
538
539 serial = usb_get_intfdata(intf);
540 priv = usb_get_serial_port_data(serial->port[0]);
541
542 /*reconfigure ch341 serial port after bus-reset*/
543 ch341_configure(dev, priv);
544
545 usb_serial_resume(intf);
546
547 return 0;
548}
549
532static struct usb_driver ch341_driver = { 550static struct usb_driver ch341_driver = {
533 .name = "ch341", 551 .name = "ch341",
534 .probe = usb_serial_probe, 552 .probe = usb_serial_probe,
535 .disconnect = usb_serial_disconnect, 553 .disconnect = usb_serial_disconnect,
554 .suspend = usb_serial_suspend,
555 .resume = usb_serial_resume,
556 .reset_resume = ch341_reset_resume,
536 .id_table = id_table, 557 .id_table = id_table,
537 .no_dynamic_id = 1, 558 .no_dynamic_id = 1,
559 .supports_autosuspend = 1,
538}; 560};
539 561
540static struct usb_serial_driver ch341_device = { 562static struct usb_serial_driver ch341_device = {