This is an attempt to alleviate race conditions in the SAM driver where essential resources like serial device and GPIO pins are not ready at the time ssam_serial_hub_probe() is called. Instead of giving up probing, a better way would be to defer the probing by returning -EPROBE_DEFER, allowing the kernel try again later. However, there is no way of identifying all such cases from other real errors in a few days. So let's take a gradual approach identify and address these cases as they arise. This commit marks the initial step in this process. Suggested-by: Maximilian Luz <luzmaximilian@xxxxxxxxx> Reviewed-by: Maximilian Luz <luzmaximilian@xxxxxxxxx> Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> Acked-by: Hans de Goede <hdegoede@xxxxxxxxxx> Signed-off-by: Weifeng Liu <weifeng.liu.z@xxxxxxxxx> --- drivers/platform/surface/aggregator/core.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/platform/surface/aggregator/core.c b/drivers/platform/surface/aggregator/core.c index ba550eaa06fc..7b1871eb7a6f 100644 --- a/drivers/platform/surface/aggregator/core.c +++ b/drivers/platform/surface/aggregator/core.c @@ -645,9 +645,22 @@ static int ssam_serial_hub_probe(struct serdev_device *serdev) /* Set up serdev device. */ serdev_device_set_drvdata(serdev, ctrl); serdev_device_set_client_ops(serdev, &ssam_serdev_ops); + + /* + * The following step can fail when it's called too early before the + * underlying UART device is ready (in this case -ENXIO is returned). + * Instead of simply giving up and losing everything, we can defer + * the probing by returning -EPROBE_DEFER so that the kernel would be + * able to retry later. + */ status = serdev_device_open(serdev); - if (status) + if (status == -ENXIO) + status = -EPROBE_DEFER; + if (status) { + dev_err_probe(&serdev->dev, status, + "failed to open serdev device\n"); goto err_devopen; + } astatus = ssam_serdev_setup_via_acpi(ssh->handle, serdev); if (ACPI_FAILURE(astatus)) { -- 2.44.0