[PATCH 2/2] iio: light: vcnl4000: add shared IRQ support
Tsz Shan Chan <[email protected]>
| Newsgroups | org.kernel.vger.linux-iio,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- 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