提交 fc6d319b 编写于 作者: J Johan Hovold 提交者: Zheng Zengkai

USB: serial: cp210x: fix CP2105 GPIO registration

stable inclusion
from stable-v5.10.88
commit 5c93584d9a2fd7e9e4238868c754b5eb0acf5452
bugzilla: 186058 https://gitee.com/openeuler/kernel/issues/I4QW6A

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=5c93584d9a2fd7e9e4238868c754b5eb0acf5452

--------------------------------

commit 83b67041 upstream.

When generalising GPIO support and adding support for CP2102N, the GPIO
registration for some CP2105 devices accidentally broke. Specifically,
when all the pins of a port are in "modem" mode, and thus unavailable
for GPIO use, the GPIO chip would now be registered without having
initialised the number of GPIO lines. This would in turn be rejected by
gpiolib and some errors messages would be printed (but importantly probe
would still succeed).

Fix this by initialising the number of GPIO lines before registering the
GPIO chip.

Note that as for the other device types, and as when all CP2105 pins are
muxed for LED function, the GPIO chip is registered also when no pins
are available for GPIO use.
Reported-by: NMaarten Brock <m.brock@vanmierlo.com>
Link: https://lore.kernel.org/r/5eb560c81d2ea1a2b4602a92d9f48a89@vanmierlo.com
Fixes: c8acfe0a ("USB: serial: cp210x: implement GPIO support for CP2102N")
Cc: stable@vger.kernel.org      # 4.19
Cc: Karoly Pados <pados@pados.hu>
Link: https://lore.kernel.org/r/20211126094348.31698-1-johan@kernel.orgReviewed-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tested-by: NMaarten Brock <m.brock@vanmierlo.com>
Signed-off-by: NJohan Hovold <johan@kernel.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 2ff7d8c2
...@@ -1750,6 +1750,8 @@ static int cp2105_gpioconf_init(struct usb_serial *serial) ...@@ -1750,6 +1750,8 @@ static int cp2105_gpioconf_init(struct usb_serial *serial)
/* 2 banks of GPIO - One for the pins taken from each serial port */ /* 2 banks of GPIO - One for the pins taken from each serial port */
if (intf_num == 0) { if (intf_num == 0) {
priv->gc.ngpio = 2;
if (mode.eci == CP210X_PIN_MODE_MODEM) { if (mode.eci == CP210X_PIN_MODE_MODEM) {
/* mark all GPIOs of this interface as reserved */ /* mark all GPIOs of this interface as reserved */
priv->gpio_altfunc = 0xff; priv->gpio_altfunc = 0xff;
...@@ -1760,8 +1762,9 @@ static int cp2105_gpioconf_init(struct usb_serial *serial) ...@@ -1760,8 +1762,9 @@ static int cp2105_gpioconf_init(struct usb_serial *serial)
priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) & priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) &
CP210X_ECI_GPIO_MODE_MASK) >> CP210X_ECI_GPIO_MODE_MASK) >>
CP210X_ECI_GPIO_MODE_OFFSET); CP210X_ECI_GPIO_MODE_OFFSET);
priv->gc.ngpio = 2;
} else if (intf_num == 1) { } else if (intf_num == 1) {
priv->gc.ngpio = 3;
if (mode.sci == CP210X_PIN_MODE_MODEM) { if (mode.sci == CP210X_PIN_MODE_MODEM) {
/* mark all GPIOs of this interface as reserved */ /* mark all GPIOs of this interface as reserved */
priv->gpio_altfunc = 0xff; priv->gpio_altfunc = 0xff;
...@@ -1772,7 +1775,6 @@ static int cp2105_gpioconf_init(struct usb_serial *serial) ...@@ -1772,7 +1775,6 @@ static int cp2105_gpioconf_init(struct usb_serial *serial)
priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) & priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) &
CP210X_SCI_GPIO_MODE_MASK) >> CP210X_SCI_GPIO_MODE_MASK) >>
CP210X_SCI_GPIO_MODE_OFFSET); CP210X_SCI_GPIO_MODE_OFFSET);
priv->gc.ngpio = 3;
} else { } else {
return -ENODEV; return -ENODEV;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册