aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorFabio Baltieri <fabio.baltieri@linaro.org>2013-03-21 09:49:44 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-04-09 04:19:45 -0400
commit7a93fb375437225ee89a15652a887547450f3d2a (patch)
treeca68b026ad33434fdac487bcfa0c1ad59f435904 /drivers/mfd
parentd95c785500f60c59e4257385af2cfee7d4044809 (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.c27
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)
458static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, 458static 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}