[PATCH 13/15] iio: proximity: sx9500: hand on probe deferral of GPIOs

From: Greg Kroah-Hartman

Date: Tue Oct 27 2026 - 12:52:40 EST


From: Josef Bacik <josef@xxxxxxxxxxxxxx>

sx9500_gpio_probe() treats every failure of devm_gpiod_get() as "the
line does not exist". If the GPIO controller has not been probed yet,
the lookup fails with -EPROBE_DEFER, and the driver binds for good
without the line:

- without the "interrupt" GPIO client->irq stays 0, so no interrupt is
requested and no trigger is registered: the device has no events and
no data-ready trigger until it is unbound and bound again;
- without the "reset" GPIO the chip is not reset in
sx9500_init_device().

Which of the two happens depends only on the order in which the drivers
are probed. Return -EPROBE_DEFER so that the probe is repeated once the
controller is there. All other errors are handled as before. The i2c
core sets client->irq again at the start of every probe, so a deferral
on the second line leaves nothing behind.

A system that describes one of the lines but never gets a driver for its
GPIO controller now keeps the sensor in the deferred list instead of
binding it without the line.

Fixes: 45fd5f8e10d3 ("iio: sx9500: add GPIO reset pin")
Fixes: e53111ad5dea ("iio: proximity: sx9500: Assign interrupt from GpioIo()")
Cc: stable <stable@xxxxxxxxxx>
Cc: David Lechner <dlechner@xxxxxxxxxxxx>
Cc: "Nuno Sá" <nuno.sa@xxxxxxxxxx>
Cc: Andy Shevchenko <andy@xxxxxxxxxx>
Cc: Josef Bacik <josef@xxxxxxxxxxxxxx>
Cc: "Uwe Kleine-König (The Capable Hub)" <u.kleine-koenig@xxxxxxxxxxxx>
Cc: Siratul Islam <email@xxxxxxxx>
Cc: Vlad Dogaru <ddvlad@xxxxxxxxx>
Cc: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx>
Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
drivers/iio/proximity/sx9500.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c
index dadce9b44227..94cc577f4404 100644
--- a/drivers/iio/proximity/sx9500.c
+++ b/drivers/iio/proximity/sx9500.c
@@ -853,15 +853,15 @@ static const struct acpi_gpio_mapping acpi_sx9500_gpios[] = {
{ }
};

-static void sx9500_gpio_probe(struct i2c_client *client,
- struct sx9500_data *data)
+static int sx9500_gpio_probe(struct i2c_client *client,
+ struct sx9500_data *data)
{
struct gpio_desc *gpiod_int;
struct device *dev;
int ret;

if (!client)
- return;
+ return 0;

dev = &client->dev;

@@ -871,6 +871,8 @@ static void sx9500_gpio_probe(struct i2c_client *client,

if (client->irq <= 0) {
gpiod_int = devm_gpiod_get(dev, "interrupt", GPIOD_IN);
+ if (PTR_ERR(gpiod_int) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
if (IS_ERR(gpiod_int))
dev_err(dev, "gpio get irq failed\n");
else
@@ -878,10 +880,14 @@ static void sx9500_gpio_probe(struct i2c_client *client,
}

data->gpiod_rst = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (PTR_ERR(data->gpiod_rst) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
if (IS_ERR(data->gpiod_rst)) {
dev_warn(dev, "gpio get reset pin failed\n");
data->gpiod_rst = NULL;
}
+
+ return 0;
}

static int sx9500_probe(struct i2c_client *client)
@@ -911,7 +917,9 @@ static int sx9500_probe(struct i2c_client *client)
indio_dev->modes = INDIO_DIRECT_MODE;
i2c_set_clientdata(client, indio_dev);

- sx9500_gpio_probe(client, data);
+ ret = sx9500_gpio_probe(client, data);
+ if (ret)
+ return ret;

ret = sx9500_init_device(indio_dev);
if (ret < 0)

--
2.56.0