diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 22756db..eff2dfd 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -330,6 +330,12 @@ next_desc: if (status < 0 && info->control != info->data) { usb_set_intfdata(info->data, NULL); usb_driver_release_interface(driver, info->data); + } else { + /* Clearing an endpoint halt brings some Sierra devices (MC7355) + * out of low-power mode. + */ + printk(KERN_INFO "%s: clearing halt\n", __func__); + usb_clear_halt(dev->udev, dev->out); } /* Never use the same address on both ends of the link, even diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index b2aa003..127f192 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -330,6 +331,23 @@ static void qc_release(struct usb_serial *serial) kfree(priv); } +int qc_port_probe(struct usb_serial_port *port) +{ + int retval; + + retval = usb_wwan_port_probe(port); + if (retval == 0) { + printk(KERN_INFO "%s: clearing halt\n", __func__); + /* Clearing an endpoint halt brings some Sierra devices (MC7355) + * out of low-power mode. + */ + usb_clear_halt(port->serial->dev, + usb_sndbulkpipe(port->serial->dev, + port->bulk_out_endpointAddress)); + } + return retval; +} + static struct usb_serial_driver qcdevice = { .driver = { .owner = THIS_MODULE, @@ -346,7 +364,7 @@ static struct usb_serial_driver qcdevice = { .chars_in_buffer = usb_wwan_chars_in_buffer, .attach = qc_attach, .release = qc_release, - .port_probe = usb_wwan_port_probe, + .port_probe = qc_port_probe, .port_remove = usb_wwan_port_remove, #ifdef CONFIG_PM .suspend = usb_wwan_suspend,