diff options
Diffstat (limited to 'drivers/mfd/wm831x-irq.c')
-rw-r--r-- | drivers/mfd/wm831x-irq.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index ecc9d6d62fad..804e56ec99eb 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
@@ -413,22 +413,25 @@ static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) | |||
413 | * do the update here as we can be called with the bus lock | 413 | * do the update here as we can be called with the bus lock |
414 | * held. | 414 | * held. |
415 | */ | 415 | */ |
416 | wm831x->gpio_level_low[irq] = false; | ||
417 | wm831x->gpio_level_high[irq] = false; | ||
416 | switch (type) { | 418 | switch (type) { |
417 | case IRQ_TYPE_EDGE_BOTH: | 419 | case IRQ_TYPE_EDGE_BOTH: |
418 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE; | 420 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE; |
419 | wm831x->gpio_level[irq] = false; | ||
420 | break; | 421 | break; |
421 | case IRQ_TYPE_EDGE_RISING: | 422 | case IRQ_TYPE_EDGE_RISING: |
422 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; | 423 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; |
423 | wm831x->gpio_level[irq] = false; | ||
424 | break; | 424 | break; |
425 | case IRQ_TYPE_EDGE_FALLING: | 425 | case IRQ_TYPE_EDGE_FALLING: |
426 | wm831x->gpio_update[irq] = 0x10000; | 426 | wm831x->gpio_update[irq] = 0x10000; |
427 | wm831x->gpio_level[irq] = false; | ||
428 | break; | 427 | break; |
429 | case IRQ_TYPE_LEVEL_HIGH: | 428 | case IRQ_TYPE_LEVEL_HIGH: |
430 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; | 429 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; |
431 | wm831x->gpio_level[irq] = true; | 430 | wm831x->gpio_level_high[irq] = true; |
431 | break; | ||
432 | case IRQ_TYPE_LEVEL_LOW: | ||
433 | wm831x->gpio_update[irq] = 0x10000; | ||
434 | wm831x->gpio_level_low[irq] = true; | ||
432 | break; | 435 | break; |
433 | default: | 436 | default: |
434 | return -EINVAL; | 437 | return -EINVAL; |
@@ -517,7 +520,7 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data) | |||
517 | * status. This is sucky but improves interoperability. | 520 | * status. This is sucky but improves interoperability. |
518 | */ | 521 | */ |
519 | if (primary == WM831X_GP_INT && | 522 | if (primary == WM831X_GP_INT && |
520 | wm831x->gpio_level[i - WM831X_IRQ_GPIO_1]) { | 523 | wm831x->gpio_level_high[i - WM831X_IRQ_GPIO_1]) { |
521 | ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL); | 524 | ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL); |
522 | while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) { | 525 | while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) { |
523 | handle_nested_irq(irq_find_mapping(wm831x->irq_domain, | 526 | handle_nested_irq(irq_find_mapping(wm831x->irq_domain, |
@@ -526,6 +529,17 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data) | |||
526 | WM831X_GPIO_LEVEL); | 529 | WM831X_GPIO_LEVEL); |
527 | } | 530 | } |
528 | } | 531 | } |
532 | |||
533 | if (primary == WM831X_GP_INT && | ||
534 | wm831x->gpio_level_low[i - WM831X_IRQ_GPIO_1]) { | ||
535 | ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL); | ||
536 | while (!(ret & 1 << (i - WM831X_IRQ_GPIO_1))) { | ||
537 | handle_nested_irq(irq_find_mapping(wm831x->irq_domain, | ||
538 | i)); | ||
539 | ret = wm831x_reg_read(wm831x, | ||
540 | WM831X_GPIO_LEVEL); | ||
541 | } | ||
542 | } | ||
529 | } | 543 | } |
530 | 544 | ||
531 | out: | 545 | out: |