diff options
-rw-r--r-- | drivers/mfd/ab8500-core.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 4778bb124efe..3d5da51b6a94 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -368,16 +368,40 @@ static void ab8500_irq_mask(struct irq_data *data) int mask = 1 << (offset % 8); ab8500->mask[index] |= mask; + + /* The AB8500 GPIOs have two interrupts each (rising & falling). */ + if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R) + ab8500->mask[index + 2] |= mask; + if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R) + ab8500->mask[index + 1] |= mask; + if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R) + ab8500->mask[index] |= (mask >> 1); } static void ab8500_irq_unmask(struct irq_data *data) { struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); + unsigned int type = irqd_get_trigger_type(data); int offset = data->hwirq; int index = offset / 8; int mask = 1 << (offset % 8); - ab8500->mask[index] &= ~mask; + if (type & IRQ_TYPE_EDGE_RISING) + ab8500->mask[index] &= ~mask; + + /* The AB8500 GPIOs have two interrupts each (rising & falling). */ + if (type & IRQ_TYPE_EDGE_FALLING) { + if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R) + ab8500->mask[index + 2] &= ~mask; + else if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R) + ab8500->mask[index + 1] &= ~mask; + else if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R) + ab8500->mask[index] &= ~(mask >> 1); + else + ab8500->mask[index] &= ~mask; + } else + /* Satisfies the case where type is not set. */ + ab8500->mask[index] &= ~mask; } static struct irq_chip ab8500_irq_chip = { |