diff options
author | Fabio Baltieri <fabio.baltieri@linaro.org> | 2013-03-21 14:49:44 +0100 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-04-09 10:19:45 +0200 |
commit | 7a93fb375437225ee89a15652a887547450f3d2a (patch) | |
tree | ca68b026ad33434fdac487bcfa0c1ad59f435904 /drivers | |
parent | d95c785500f60c59e4257385af2cfee7d4044809 (diff) | |
download | linux-3.10-7a93fb375437225ee89a15652a887547450f3d2a.tar.gz linux-3.10-7a93fb375437225ee89a15652a887547450f3d2a.tar.bz2 linux-3.10-7a93fb375437225ee89a15652a887547450f3d2a.zip |
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')
-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 f276352cc9e..36751f37dd5 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) static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, int latch_offset, u8 latch_val) { - int int_bit = __ffs(latch_val); - int line, i; + int int_bit, line, i; - do { - int_bit = __ffs(latch_val); + for (i = 0; i < ab8500->mask_size; i++) + if (ab8500->irq_reg_offset[i] == latch_offset) + break; - for (i = 0; i < ab8500->mask_size; i++) - if (ab8500->irq_reg_offset[i] == latch_offset) - break; + if (i >= ab8500->mask_size) { + dev_err(ab8500->dev, "Register offset 0x%2x not declared\n", + latch_offset); + return -ENXIO; + } - if (i >= ab8500->mask_size) { - dev_err(ab8500->dev, "Register offset 0x%2x not declared\n", - latch_offset); - return -ENXIO; - } + /* ignore masked out interrupts */ + latch_val &= ~ab8500->mask[i]; + while (latch_val) { + int_bit = __ffs(latch_val); line = (i << 3) + int_bit; latch_val &= ~(1 << int_bit); @@ -491,7 +492,7 @@ static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, line += 1; handle_nested_irq(ab8500->irq_base + line); - } while (latch_val); + } return 0; } |