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

Jonathan Cameron <[email protected]>
Newsgroups org.kernel.vger.linux-iio,org.kernel.vger.linux-kernel
Message-ID <20260822032550.31a0fa9e@jic23-huawei>
On Fri, 14 Aug 2026 14:30:43 +1000
Tsz Shan Chan <[email protected]> wrote:

> 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.
Fairly low risk change but I guess we'll see.

It used to be annoyingly common for interrupt controllers to support
only edge based interrupts, but hopefully that silliness is a thing
of the past.

So crossed fingers, I'll apply this and see if we get anyone shouting.
I think we'll get away with it

Thanks,

Jonathan

> 
> 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 <[email protected]>
> ---
>  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)
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.