diff options
-rw-r--r-- | drivers/mfd/ab8500-core.c | 82 |
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 | */ | ||
560 | static 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 | |||
568 | static 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 | |||
612 | static int ab8500_irq_map(struct irq_domain *d, unsigned int virq, | 552 | static 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, |