Skip to contentSkip to conversation

CP2105 gives kernel error -22 when in modem mode

DISCUSSION Maarten Brock 2 participants 3 messages Nov 25, 2021 – Nov 26, 2021 USB

lore
Share & tools
lore
#0 lore raw

Hello all,

When a uart of the CP2105 USB-serial chip is programmed to be in modem mode, all its gpio pins are in alternate use and none are available for gpio. Still the cp210x driver tries to add a gpiochip unconditionally, which results in an error.

Quoted 8 lines

cp210x 1-1.4.4:1.0: cp210x converter detected
usb 1-1.4.4: cp210x converter now attached to ttyUSB0 cp210x 1-1.4.4:1.1: cp210x converter detected
gpio gpiochip2: (cp210x): tried to insert a GPIO chip with zero lines gpiochip_add_data_with_key: GPIOs 0..-1 (cp210x) failed to register, -22
cp210x 1-1.4.4:1.1: GPIO initialisation failed: -22
usb 1-1.4.4: cp210x converter now attached to ttyUSB1

I propose to add something like the following to cp210x_gpio_init

+ unsigned long valid_mask, altfunc_mask;
...
+ altfunc_mask = priv->gpio_altfunc;
+ bitmap_complement(&valid_mask, &altfunc_mask, priv->gc.ngpio);
+ if (bitmap_empty(&valid_mask, priv->gc.ngpio))
+ return 0;
+
priv->gc.label = "cp210x"; priv->gc.request = cp210x_gpio_request; priv->gc.get_direction = cp210x_gpio_direction_get;

I can write a proper patch, but am unsure if and what the Fixes tag should be.

Maarten

#1 lore raw
Quoted 15 lines · Maarten Brock

Hello all,

When a uart of the CP2105 USB-serial chip is programmed to be in modem mode, all its gpio pins are in alternate use and none are available for gpio. Still the cp210x driver tries to add a gpiochip unconditionally, which results in an error.

Quoted 8 lines

cp210x 1-1.4.4:1.0: cp210x converter detected
usb 1-1.4.4: cp210x converter now attached to ttyUSB0 cp210x 1-1.4.4:1.1: cp210x converter detected
gpio gpiochip2: (cp210x): tried to insert a GPIO chip with zero lines gpiochip_add_data_with_key: GPIOs 0..-1 (cp210x) failed to register, -22
cp210x 1-1.4.4:1.1: GPIO initialisation failed: -22
usb 1-1.4.4: cp210x converter now attached to ttyUSB1

Thanks for reporting this.

Quoted 13 lines

I propose to add something like the following to cp210x_gpio_init

(quoted diff) +6 -0
+	unsigned long valid_mask, altfunc_mask;
...
+	altfunc_mask = priv->gpio_altfunc;
+	bitmap_complement(&valid_mask, &altfunc_mask, priv->gc.ngpio);
+	if (bitmap_empty(&valid_mask, priv->gc.ngpio))
+		return 0;
+
  	priv->gc.label = "cp210x";
  	priv->gc.request = cp210x_gpio_request;
  	priv->gc.get_direction = cp210x_gpio_direction_get;
Quoted 2 lines

I can write a proper patch, but am unsure if and what the Fixes tag should be.

This was introduced by commit c8acfe0aadbe ("USB: serial: cp210x:
implement GPIO support for CP2102N") when generalising GPIO support and adding support for CP2102N. Before that commit, the GPIO chip would indeed never have been registered in this case.

The right fix however is to continue to always register the gpiochip but to make sure that the number of lines is initialised before doing so. This is how we deal with with the other device types and is also how CP2105 is handled when both pins of the CP2105 ECI port are muxed for LED function.

I've just posted a fix here:

	https://lore.kernel.org/r/[email protected]

Johan

#2 lore raw
Quoted 46 lines · Johan Hovold
Quoted 15 lines · Maarten Brock

Hello all,

When a uart of the CP2105 USB-serial chip is programmed to be in modem mode, all its gpio pins are in alternate use and none are available for gpio. Still the cp210x driver tries to add a gpiochip unconditionally, which results in an error.

Quoted 8 lines

cp210x 1-1.4.4:1.0: cp210x converter detected
usb 1-1.4.4: cp210x converter now attached to ttyUSB0 cp210x 1-1.4.4:1.1: cp210x converter detected
gpio gpiochip2: (cp210x): tried to insert a GPIO chip with zero lines gpiochip_add_data_with_key: GPIOs 0..-1 (cp210x) failed to register, -22
cp210x 1-1.4.4:1.1: GPIO initialisation failed: -22
usb 1-1.4.4: cp210x converter now attached to ttyUSB1

Thanks for reporting this.

Quoted 13 lines

I propose to add something like the following to cp210x_gpio_init

(quoted diff) +6 -0
+	unsigned long valid_mask, altfunc_mask;
...
+	altfunc_mask = priv->gpio_altfunc;
+	bitmap_complement(&valid_mask, &altfunc_mask, priv->gc.ngpio);
+	if (bitmap_empty(&valid_mask, priv->gc.ngpio))
+		return 0;
+
  	priv->gc.label = "cp210x";
  	priv->gc.request = cp210x_gpio_request;
  	priv->gc.get_direction = cp210x_gpio_direction_get;
Quoted 2 lines

I can write a proper patch, but am unsure if and what the Fixes tag should be.

This was introduced by commit c8acfe0aadbe ("USB: serial: cp210x:
implement GPIO support for CP2102N") when generalising GPIO support and adding support for CP2102N. Before that commit, the GPIO chip would indeed never have been registered in this case.

The right fix however is to continue to always register the gpiochip but to make sure that the number of lines is initialised before doing so. This is how we deal with with the other device types and is also how CP2105 is handled when both pins of the CP2105 ECI port are muxed for LED function.

Quoted 5 lines

I've just posted a fix here:

	https://lore.kernel.org/r/[email protected]

Johan

Thanks for the quick solution. That patch seems to be a better fix for this bug and I have acknowledged it with a Tested-by.

I do however wonder if it is desirable to register a GPIO controller that has no lines. It's not like those lines can become available at any later time. The CP2105 is OTP, but also the other CP210x devices need to be reprogrammed and reenumerated for those lines to become available again. So I would still vote to apply my proposal though not as a bug fix.

Thanks again,
Maarten