aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartosz Golaszewski <brgl@bgdev.pl>2017-07-03 05:12:03 -0400
committerLinus Walleij <linus.walleij@linaro.org>2017-08-01 08:07:35 -0400
commitdf1e76f28ffe87d1b065eecab2d0fbb89e6bdee5 (patch)
tree726b2e39ad615a59bbbf7b64d9e0a199a9faa518
parenta589e211bd74715a63f507dade294ba618259ff7 (diff)
gpiolib: skip unwanted events, don't convert them to opposite edge
The previous fix for filtering out of unwatched events was not entirely correct. Instead of skipping the events we don't want, they are now interpreted as events with opposing edge. In order to fix it: always read the GPIO line value on interrupt and only emit the event if it corresponds with the event type we requested. Cc: stable@vger.kernel.org Fixes: ad537b822577 ("gpiolib: fix filtering out unwanted events") Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/gpio/gpiolib.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 9568708a550b..cd003b74512f 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -704,24 +704,23 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p)
704{ 704{
705 struct lineevent_state *le = p; 705 struct lineevent_state *le = p;
706 struct gpioevent_data ge; 706 struct gpioevent_data ge;
707 int ret; 707 int ret, level;
708 708
709 ge.timestamp = ktime_get_real_ns(); 709 ge.timestamp = ktime_get_real_ns();
710 level = gpiod_get_value_cansleep(le->desc);
710 711
711 if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE 712 if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
712 && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) { 713 && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
713 int level = gpiod_get_value_cansleep(le->desc);
714
715 if (level) 714 if (level)
716 /* Emit low-to-high event */ 715 /* Emit low-to-high event */
717 ge.id = GPIOEVENT_EVENT_RISING_EDGE; 716 ge.id = GPIOEVENT_EVENT_RISING_EDGE;
718 else 717 else
719 /* Emit high-to-low event */ 718 /* Emit high-to-low event */
720 ge.id = GPIOEVENT_EVENT_FALLING_EDGE; 719 ge.id = GPIOEVENT_EVENT_FALLING_EDGE;
721 } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE) { 720 } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE && level) {
722 /* Emit low-to-high event */ 721 /* Emit low-to-high event */
723 ge.id = GPIOEVENT_EVENT_RISING_EDGE; 722 ge.id = GPIOEVENT_EVENT_RISING_EDGE;
724 } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) { 723 } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE && !level) {
725 /* Emit high-to-low event */ 724 /* Emit high-to-low event */
726 ge.id = GPIOEVENT_EVENT_FALLING_EDGE; 725 ge.id = GPIOEVENT_EVENT_FALLING_EDGE;
727 } else { 726 } else {