aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/qcom/pinctrl-msm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/qcom/pinctrl-msm.c')
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 2155a30c282b..5d72ffad32c2 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -634,6 +634,29 @@ static void msm_gpio_irq_mask(struct irq_data *d)
634 raw_spin_lock_irqsave(&pctrl->lock, flags); 634 raw_spin_lock_irqsave(&pctrl->lock, flags);
635 635
636 val = readl(pctrl->regs + g->intr_cfg_reg); 636 val = readl(pctrl->regs + g->intr_cfg_reg);
637 /*
638 * There are two bits that control interrupt forwarding to the CPU. The
639 * RAW_STATUS_EN bit causes the level or edge sensed on the line to be
640 * latched into the interrupt status register when the hardware detects
641 * an irq that it's configured for (either edge for edge type or level
642 * for level type irq). The 'non-raw' status enable bit causes the
643 * hardware to assert the summary interrupt to the CPU if the latched
644 * status bit is set. There's a bug though, the edge detection logic
645 * seems to have a problem where toggling the RAW_STATUS_EN bit may
646 * cause the status bit to latch spuriously when there isn't any edge
647 * so we can't touch that bit for edge type irqs and we have to keep
648 * the bit set anyway so that edges are latched while the line is masked.
649 *
650 * To make matters more complicated, leaving the RAW_STATUS_EN bit
651 * enabled all the time causes level interrupts to re-latch into the
652 * status register because the level is still present on the line after
653 * we ack it. We clear the raw status enable bit during mask here and
654 * set the bit on unmask so the interrupt can't latch into the hardware
655 * while it's masked.
656 */
657 if (irqd_get_trigger_type(d) & IRQ_TYPE_LEVEL_MASK)
658 val &= ~BIT(g->intr_raw_status_bit);
659
637 val &= ~BIT(g->intr_enable_bit); 660 val &= ~BIT(g->intr_enable_bit);
638 writel(val, pctrl->regs + g->intr_cfg_reg); 661 writel(val, pctrl->regs + g->intr_cfg_reg);
639 662
@@ -655,6 +678,7 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
655 raw_spin_lock_irqsave(&pctrl->lock, flags); 678 raw_spin_lock_irqsave(&pctrl->lock, flags);
656 679
657 val = readl(pctrl->regs + g->intr_cfg_reg); 680 val = readl(pctrl->regs + g->intr_cfg_reg);
681 val |= BIT(g->intr_raw_status_bit);
658 val |= BIT(g->intr_enable_bit); 682 val |= BIT(g->intr_enable_bit);
659 writel(val, pctrl->regs + g->intr_cfg_reg); 683 writel(val, pctrl->regs + g->intr_cfg_reg);
660 684