aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartosz Golaszewski <[email protected]>2017-07-03 09:12:03 +0000
committerLinus Walleij <[email protected]>2017-08-01 12:07:35 +0000
commitdf1e76f28ffe87d1b065eecab2d0fbb89e6bdee5 (patch)
tree726b2e39ad615a59bbbf7b64d9e0a199a9faa518
parentgpio: exar: Use correct property prefix and document bindings (diff)
downloadkernel-df1e76f28ffe87d1b065eecab2d0fbb89e6bdee5.tar.gz
kernel-df1e76f28ffe87d1b065eecab2d0fbb89e6bdee5.zip
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: [email protected] Fixes: ad537b822577 ("gpiolib: fix filtering out unwanted events") Signed-off-by: Bartosz Golaszewski <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
-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)
{
struct lineevent_state *le = p;
struct gpioevent_data ge;
- int ret;
+ int ret, level;
ge.timestamp = ktime_get_real_ns();
+ level = gpiod_get_value_cansleep(le->desc);
if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
&& le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
- int level = gpiod_get_value_cansleep(le->desc);
-
if (level)
/* Emit low-to-high event */
ge.id = GPIOEVENT_EVENT_RISING_EDGE;
else
/* Emit high-to-low event */
ge.id = GPIOEVENT_EVENT_FALLING_EDGE;
- } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE) {
+ } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE && level) {
/* Emit low-to-high event */
ge.id = GPIOEVENT_EVENT_RISING_EDGE;
- } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
+ } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE && !level) {
/* Emit high-to-low event */
ge.id = GPIOEVENT_EVENT_FALLING_EDGE;
} else {