[PATCH v2 2/2] iio: light: vcnl4000: add shared IRQ support

From: Tsz Shan Chan

Date: Fri Aug 14 2026 - 00:31:49 EST


The INT output of vcnl4010/4020 and vcnl4040/4200 is open drain active
low which can be shared with other devices.
Add IRQF_SHARED and switch the trigger type from IRQF_TRIGGER_FALLING to
IRQF_TRIGGER_LOW. Edge triggering can miss interrupts on a shared line.

Return IRQ_NONE from the irq handler when read fails or when none of the
interrupt source bits handled by the driver are set. This prevents
claiming interrupts from other devices on a shared line.

Signed-off-by: Tsz Shan Chan <tchan@xxxxxxxxxxxxxx>
---
drivers/iio/light/vcnl4000.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
index 663e623da833..8a723eaadbb6 100644
--- a/drivers/iio/light/vcnl4000.c
+++ b/drivers/iio/light/vcnl4000.c
@@ -1470,7 +1470,11 @@ static irqreturn_t vcnl4040_irq_thread(int irq, void *p)

ret = i2c_smbus_read_word_data(data->client, data->chip_spec->int_reg);
if (ret < 0)
- return IRQ_HANDLED;
+ return IRQ_NONE;
+
+ if (!(ret & (VCNL4040_PS_IF_CLOSE | VCNL4040_PS_IF_AWAY |
+ VCNL4040_ALS_FALLING | VCNL4040_ALS_RISING)))
+ return IRQ_NONE;

if (ret & VCNL4040_PS_IF_CLOSE) {
iio_push_event(indio_dev,
@@ -1526,7 +1530,10 @@ static irqreturn_t vcnl4010_irq_thread(int irq, void *p)

ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR);
if (ret < 0)
- goto end;
+ return IRQ_NONE;
+
+ if (!(ret & (VCNL4010_INT_THR | VCNL4010_INT_DRDY)))
+ return IRQ_NONE;

isr = ret;

@@ -1558,7 +1565,6 @@ static irqreturn_t vcnl4010_irq_thread(int irq, void *p)
if (isr & VCNL4010_INT_DRDY && iio_buffer_enabled(indio_dev))
iio_trigger_poll_nested(indio_dev->trig);

-end:
return IRQ_HANDLED;
}

@@ -1981,8 +1987,8 @@ static int vcnl4000_probe(struct i2c_client *client)
if (client->irq && data->chip_spec->irq_thread) {
ret = devm_request_threaded_irq(dev, client->irq, NULL,
data->chip_spec->irq_thread,
- IRQF_TRIGGER_FALLING |
- IRQF_ONESHOT,
+ IRQF_TRIGGER_LOW |
+ IRQF_ONESHOT | IRQF_SHARED,
"vcnl4000_irq",
indio_dev);
if (ret < 0)

--
2.55.0