Current GPIO code in cp210x fails to take USB autosuspend into account, making it practically impossible to use GPIOs with autosuspend enabled without user configuration. Fix this like for ftdi_sio in a previous patch. Tested on a CP2102N. Signed-off-by: Karoly Pados <pados@xxxxxxxx> --- Changelog: - v2: Restrict new autopm calls to GPIO paths. Always check result of usb_autopm_get. Rebased to current usb_serial upstream. drivers/usb/serial/cp210x.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index fac7a4547523..f7aaecad6e21 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -1370,8 +1370,13 @@ static int cp210x_gpio_get(struct gpio_chip *gc, unsigned int gpio) if (priv->partnum == CP210X_PARTNUM_CP2105) req_type = REQTYPE_INTERFACE_TO_HOST; + result = usb_autopm_get_interface(serial->interface); + if (result) + return result; + result = cp210x_read_vendor_block(serial, req_type, CP210X_READ_LATCH, &buf, sizeof(buf)); + usb_autopm_put_interface(serial->interface); if (result < 0) return result; @@ -1392,6 +1397,10 @@ static void cp210x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value) buf.mask = BIT(gpio); + result = usb_autopm_get_interface(serial->interface); + if (result) + goto out; + if (priv->partnum == CP210X_PARTNUM_CP2105) { result = cp210x_write_vendor_block(serial, REQTYPE_HOST_TO_INTERFACE, @@ -1399,7 +1408,6 @@ static void cp210x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value) sizeof(buf)); } else { u16 wIndex = buf.state << 8 | buf.mask; - result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), CP210X_VENDOR_SPECIFIC, @@ -1409,6 +1417,9 @@ static void cp210x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value) NULL, 0, USB_CTRL_SET_TIMEOUT); } + usb_autopm_put_interface(serial->interface); + +out: if (result < 0) { dev_err(&serial->interface->dev, "failed to set GPIO value: %d\n", result); -- 2.20.1