aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/ab8500-core.c
diff options
context:
space:
mode:
authorDariusz Szymczak <dariusz.xd.szymczak@stericsson.com>2012-11-26 07:31:26 -0500
committerLee Jones <lee.jones@linaro.org>2013-03-06 23:29:31 -0500
commitf348fefd2a227122eb2d723e255c60cf491d0557 (patch)
tree20a7597a5183c09ed3eb48444416b97ea02f59d1 /drivers/mfd/ab8500-core.c
parent7b830ae4e538cf04d3b57432bb08f58b828dbafa (diff)
mfd: ab8500-core: Hierarchical interrupt registers
Make use of the hierarchical interrupt rergister called ITLatchHier1 - 3 also for the 8500 platform (currently the hierarchical interrupt registers are used only for the 8540 and 9540 platforms). This will make the interrupt routing go faster since fewer i2c reads need to made in the most common cases. Signed-off-by: Dariusz Szymczak <dariusz.xd.szymczak@stericsson.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Reviewed-by: Mian Yousaf KAUKAB <mian.yousaf.kaukab@stericsson.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/ab8500-core.c')
-rw-r--r--drivers/mfd/ab8500-core.c82
1 files changed, 6 insertions, 76 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index caab1fd3a03f..c7ff55753a8f 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -549,66 +549,6 @@ static irqreturn_t ab8500_hierarchical_irq(int irq, void *dev)
549 return IRQ_HANDLED; 549 return IRQ_HANDLED;
550} 550}
551 551
552/**
553 * ab8500_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ
554 *
555 * @ab8500: ab8500_irq controller to operate on.
556 * @irq: index of the interrupt requested in the chip IRQs
557 *
558 * Useful for drivers to request their own IRQs.
559 */
560static int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq)
561{
562 if (!ab8500)
563 return -EINVAL;
564
565 return irq_create_mapping(ab8500->domain, irq);
566}
567
568static irqreturn_t ab8500_irq(int irq, void *dev)
569{
570 struct ab8500 *ab8500 = dev;
571 int i;
572
573 dev_vdbg(ab8500->dev, "interrupt\n");
574
575 atomic_inc(&ab8500->transfer_ongoing);
576
577 for (i = 0; i < ab8500->mask_size; i++) {
578 int regoffset = ab8500->irq_reg_offset[i];
579 int status;
580 u8 value;
581
582 /*
583 * Interrupt register 12 doesn't exist prior to AB8500 version
584 * 2.0
585 */
586 if (regoffset == 11 && is_ab8500_1p1_or_earlier(ab8500))
587 continue;
588
589 if (regoffset < 0)
590 continue;
591
592 status = get_register_interruptible(ab8500, AB8500_INTERRUPT,
593 AB8500_IT_LATCH1_REG + regoffset, &value);
594 if (status < 0 || value == 0)
595 continue;
596
597 do {
598 int bit = __ffs(value);
599 int line = i * 8 + bit;
600 int virq = ab8500_irq_get_virq(ab8500, line);
601
602 handle_nested_irq(virq);
603 ab8500_debug_register_interrupt(line);
604 value &= ~(1 << bit);
605
606 } while (value);
607 }
608 atomic_dec(&ab8500->transfer_ongoing);
609 return IRQ_HANDLED;
610}
611
612static int ab8500_irq_map(struct irq_domain *d, unsigned int virq, 552static int ab8500_irq_map(struct irq_domain *d, unsigned int virq,
613 irq_hw_number_t hwirq) 553 irq_hw_number_t hwirq)
614{ 554{
@@ -1737,22 +1677,12 @@ static int ab8500_probe(struct platform_device *pdev)
1737 if (ret) 1677 if (ret)
1738 return ret; 1678 return ret;
1739 1679
1740 /* Activate this feature only in ab9540 */ 1680 ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL,
1741 /* till tests are done on ab8500 1p2 or later*/ 1681 ab8500_hierarchical_irq,
1742 if (is_ab9540(ab8500) || is_ab8540(ab8500)) 1682 IRQF_ONESHOT | IRQF_NO_SUSPEND,
1743 ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL, 1683 "ab8500", ab8500);
1744 ab8500_hierarchical_irq, 1684 if (ret)
1745 IRQF_ONESHOT | IRQF_NO_SUSPEND, 1685 return ret;
1746 "ab8500", ab8500);
1747 }
1748 else {
1749 ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL,
1750 ab8500_irq,
1751 IRQF_ONESHOT | IRQF_NO_SUSPEND,
1752 "ab8500", ab8500);
1753 if (ret)
1754 return ret;
1755 }
1756 1686
1757 if (is_ab9540(ab8500)) 1687 if (is_ab9540(ab8500))
1758 ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, 1688 ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,