mfd: ab8500-core: Ignore masked out interrupts
authorFabio Baltieri <fabio.baltieri@linaro.org>
Thu, 21 Mar 2013 13:49:44 +0000 (14:49 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Tue, 9 Apr 2013 08:19:45 +0000 (10:19 +0200)
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>
drivers/mfd/ab8500-core.c

index f276352cc9ef3d2d5493f983f01d8257c6f42726..36751f37dd5236dc9cd169b2ffb5f6c6272e12ce 100644 (file)
@@ -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;
 }