aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2012-12-20 06:23:42 -0500
committerLinus Walleij <linus.walleij@linaro.org>2013-02-08 08:25:30 -0500
commit9c677b9b74d4314ed7f222bf802d6d1e7585eb65 (patch)
tree48962275455bc67551f3bd28585638ada958da02 /drivers/mfd
parent88b62b915b0b7e25870eb0604ed9a92ba4bfc9f7 (diff)
mfd: ab8500: prepare to handle AB8500 GPIO's IRQs correctly
In an upcoming patch, the gpio-ab8500 driver will relinquish all IRQ handling capability and pass it back into the AB8500 core driver. This will aid in reducing massive code duplication within the kernel. Also, most of the functionality is already in the AB8500 core driver, as the GPIO IRQs are actually sandwiched between lots of other IRQs which the core driver already handles. All we're doing here is providing the core driver with knowledge that each GPIO has two IRQs assigned to it; one for rising and a separate one for falling. Cc: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/ab8500-core.c26
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)
368 int mask = 1 << (offset % 8); 368 int mask = 1 << (offset % 8);
369 369
370 ab8500->mask[index] |= mask; 370 ab8500->mask[index] |= mask;
371
372 /* The AB8500 GPIOs have two interrupts each (rising & falling). */
373 if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R)
374 ab8500->mask[index + 2] |= mask;
375 if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R)
376 ab8500->mask[index + 1] |= mask;
377 if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R)
378 ab8500->mask[index] |= (mask >> 1);
371} 379}
372 380
373static void ab8500_irq_unmask(struct irq_data *data) 381static void ab8500_irq_unmask(struct irq_data *data)
374{ 382{
375 struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); 383 struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
384 unsigned int type = irqd_get_trigger_type(data);
376 int offset = data->hwirq; 385 int offset = data->hwirq;
377 int index = offset / 8; 386 int index = offset / 8;
378 int mask = 1 << (offset % 8); 387 int mask = 1 << (offset % 8);
379 388
380 ab8500->mask[index] &= ~mask; 389 if (type & IRQ_TYPE_EDGE_RISING)
390 ab8500->mask[index] &= ~mask;
391
392 /* The AB8500 GPIOs have two interrupts each (rising & falling). */
393 if (type & IRQ_TYPE_EDGE_FALLING) {
394 if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R)
395 ab8500->mask[index + 2] &= ~mask;
396 else if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R)
397 ab8500->mask[index + 1] &= ~mask;
398 else if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R)
399 ab8500->mask[index] &= ~(mask >> 1);
400 else
401 ab8500->mask[index] &= ~mask;
402 } else
403 /* Satisfies the case where type is not set. */
404 ab8500->mask[index] &= ~mask;
381} 405}
382 406
383static struct irq_chip ab8500_irq_chip = { 407static struct irq_chip ab8500_irq_chip = {