aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/wm831x-irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/wm831x-irq.c')
-rw-r--r--drivers/mfd/wm831x-irq.c24
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
531out: 545out: