From 08145a76a9c188662179f5e34425f97be6c0a8c1 Mon Sep 17 00:00:00 2001 From: Tomasz Kazimierz Motyl Date: Fri, 3 May 2019 05:51:32 -0700 Subject: [PATCH] When ones changes the state of any input pins of a PCA9555 chip before setting up the IRQ mask through i.e. SysFS e.g. echo "both" > /sys/class/gpio/gpioXYZ/edge the epoll_wait shall not exit on the subsequent change of the GPIO state. The reason behind it is that the IRQ status is not being saved when the IRQ is masked. --- drivers/gpio/gpio-pca953x.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 7e76830b33682a..088bef902156d3 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -716,13 +716,16 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending) trigger[i] = (cur_stat[i] ^ old_stat[i]) & chip->irq_mask[i]; if (trigger[i]) trigger_seen = true; + + /* We want the current status recorded in the chip->irq stat regardless the + * chip->irq_mask setting in order to have a change detected when the interrupt + * mask gets changed i.e. echo "both" > /sys/class/gpioXYZ/edge */ + chip->irq_stat[i] = cur_stat[i]; } if (!trigger_seen) return false; - memcpy(chip->irq_stat, cur_stat, NBANK(chip)); - for (i = 0; i < NBANK(chip); i++) { pending[i] = (old_stat[i] & chip->irq_trig_fall[i]) | (cur_stat[i] & chip->irq_trig_raise[i]);