]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
usb: typec: ps883x: fix registration race
authorJohan Hovold <johan+linaro@kernel.org>
Tue, 18 Feb 2025 15:29:31 +0000 (16:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Feb 2025 14:16:08 +0000 (15:16 +0100)
Make sure that the retimer is fully setup before registering it to avoid
having consumers try to access it while it is being reset.

Fixes: 257a087c8b52 ("usb: typec: Add support for Parade PS8830 Type-C Retimer")
Cc: Abel Vesa <abel.vesa@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20250218152933.22992-2-johan+linaro@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/typec/mux/ps883x.c

index ef086989231f6c60abd3a4f36ead5017903981db..274de7abe5855dcc39017a5df4e9b6e9d8f190dd 100644 (file)
@@ -346,6 +346,22 @@ static int ps883x_retimer_probe(struct i2c_client *client)
                goto err_vregs_disable;
        }
 
+       /* skip resetting if already configured */
+       if (regmap_test_bits(retimer->regmap, REG_USB_PORT_CONN_STATUS_0,
+                            CONN_STATUS_0_CONNECTION_PRESENT) == 1) {
+               gpiod_direction_output(retimer->reset_gpio, 0);
+       } else {
+               gpiod_direction_output(retimer->reset_gpio, 1);
+
+               /* VDD IO supply enable to reset release delay */
+               usleep_range(4000, 14000);
+
+               gpiod_set_value(retimer->reset_gpio, 0);
+
+               /* firmware initialization delay */
+               msleep(60);
+       }
+
        sw_desc.drvdata = retimer;
        sw_desc.fwnode = dev_fwnode(dev);
        sw_desc.set = ps883x_sw_set;
@@ -368,21 +384,6 @@ static int ps883x_retimer_probe(struct i2c_client *client)
                goto err_switch_unregister;
        }
 
-       /* skip resetting if already configured */
-       if (regmap_test_bits(retimer->regmap, REG_USB_PORT_CONN_STATUS_0,
-                            CONN_STATUS_0_CONNECTION_PRESENT) == 1)
-               return gpiod_direction_output(retimer->reset_gpio, 0);
-
-       gpiod_direction_output(retimer->reset_gpio, 1);
-
-       /* VDD IO supply enable to reset release delay */
-       usleep_range(4000, 14000);
-
-       gpiod_set_value(retimer->reset_gpio, 0);
-
-       /* firmware initialization delay */
-       msleep(60);
-
        return 0;
 
 err_switch_unregister: