diff options
author | Fabio Baltieri <fabio.baltieri@linaro.org> | 2013-03-21 09:49:44 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-04-09 04:19:45 -0400 |
commit | 7a93fb375437225ee89a15652a887547450f3d2a (patch) | |
tree | ca68b026ad33434fdac487bcfa0c1ad59f435904 /drivers/mfd | |
parent | d95c785500f60c59e4257385af2cfee7d4044809 (diff) |
mfd: ab8500-core: Ignore masked out interrupts
AB8500 asserts LATCH bits for masked out interrupts. This patch
explicitly masks those out using the cached mask value to prevent
handle_nested_irq() being called for masked IRQ on the same register as
unmasked ones.
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Fabio Baltieri <fabio.baltieri@linaro.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/ab8500-core.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index f276352cc9ef..36751f37dd52 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -458,22 +458,23 @@ static void update_latch_offset(u8 *offset, int i) | |||
458 | static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, | 458 | static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, |
459 | int latch_offset, u8 latch_val) | 459 | int latch_offset, u8 latch_val) |
460 | { | 460 | { |
461 | int int_bit = __ffs(latch_val); | 461 | int int_bit, line, i; |
462 | int line, i; | ||
463 | 462 | ||
464 | do { | 463 | for (i = 0; i < ab8500->mask_size; i++) |
465 | int_bit = __ffs(latch_val); | 464 | if (ab8500->irq_reg_offset[i] == latch_offset) |
465 | break; | ||
466 | 466 | ||
467 | for (i = 0; i < ab8500->mask_size; i++) | 467 | if (i >= ab8500->mask_size) { |
468 | if (ab8500->irq_reg_offset[i] == latch_offset) | 468 | dev_err(ab8500->dev, "Register offset 0x%2x not declared\n", |
469 | break; | 469 | latch_offset); |
470 | return -ENXIO; | ||
471 | } | ||
470 | 472 | ||
471 | if (i >= ab8500->mask_size) { | 473 | /* ignore masked out interrupts */ |
472 | dev_err(ab8500->dev, "Register offset 0x%2x not declared\n", | 474 | latch_val &= ~ab8500->mask[i]; |
473 | latch_offset); | ||
474 | return -ENXIO; | ||
475 | } | ||
476 | 475 | ||
476 | while (latch_val) { | ||
477 | int_bit = __ffs(latch_val); | ||
477 | line = (i << 3) + int_bit; | 478 | line = (i << 3) + int_bit; |
478 | latch_val &= ~(1 << int_bit); | 479 | latch_val &= ~(1 << int_bit); |
479 | 480 | ||
@@ -491,7 +492,7 @@ static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, | |||
491 | line += 1; | 492 | line += 1; |
492 | 493 | ||
493 | handle_nested_irq(ab8500->irq_base + line); | 494 | handle_nested_irq(ab8500->irq_base + line); |
494 | } while (latch_val); | 495 | } |
495 | 496 | ||
496 | return 0; | 497 | return 0; |
497 | } | 498 | } |