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

From: Tsz Shan Chan

Date: Tue Aug 11 2026 - 03:20:20 EST


Use the IRQ trigger type set by firmware instead, and fall back to
IRQF_TRIGGER_FALLING if no trigger type is specified to maintain current
behaviour.

Support IRQF_TRIGGER_FALLING and IRQF_TRIGGER_LOW, which match the open
drain active low interrupt output. Reject unsupported trigger types.

Request the interrupt with IRQF_SHARED, and return IRQ_NONE in the irq
handler when there is no interrupt pending.

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

diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
index 663e623da833..9fff00ae515e 100644
--- a/drivers/iio/light/vcnl4000.c
+++ b/drivers/iio/light/vcnl4000.c
@@ -1469,8 +1469,8 @@ static irqreturn_t vcnl4040_irq_thread(int irq, void *p)
int ret;

ret = i2c_smbus_read_word_data(data->client, data->chip_spec->int_reg);
- if (ret < 0)
- return IRQ_HANDLED;
+ if (ret <= 0)
+ return IRQ_NONE;

if (ret & VCNL4040_PS_IF_CLOSE) {
iio_push_event(indio_dev,
@@ -1525,8 +1525,8 @@ static irqreturn_t vcnl4010_irq_thread(int irq, void *p)
int ret;

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

isr = ret;

@@ -1558,7 +1558,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;
}

@@ -1979,10 +1978,24 @@ static int vcnl4000_probe(struct i2c_client *client)
}

if (client->irq && data->chip_spec->irq_thread) {
+ u32 irq_type = irq_get_trigger_type(client->irq);
+
+ switch (irq_type) {
+ case IRQF_TRIGGER_FALLING:
+ case IRQF_TRIGGER_LOW:
+ break;
+ case IRQF_TRIGGER_NONE:
+ irq_type = IRQF_TRIGGER_FALLING;
+ break;
+ default:
+ return dev_err_probe(dev, -EINVAL,
+ "unsupported irq trigger type %x\n",
+ irq_type);
+ }
ret = devm_request_threaded_irq(dev, client->irq, NULL,
data->chip_spec->irq_thread,
- IRQF_TRIGGER_FALLING |
- IRQF_ONESHOT,
+ IRQF_ONESHOT | IRQF_SHARED |
+ irq_type,
"vcnl4000_irq",
indio_dev);
if (ret < 0)

--
2.55.0