| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Lina Iyer <ilina@codeaurora.org> |
| Date: Fri, 13 Sep 2019 15:59:11 -0600 |
| Subject: FROMLIST: drivers: irqchip: pdc: Do not toggle IRQ_ENABLE during |
| mask/unmask |
| |
| When an interrupt is to be serviced, the convention is to mask the |
| interrupt at the chip and unmask after servicing the interrupt. Enabling |
| and disabling the interrupt at the PDC irqchip causes an interrupt storm |
| due to the way dual edge interrupts are handled in hardware. |
| |
| Skip configuring the PDC when the IRQ is masked and unmasked, instead |
| use the irq_enable/irq_disable callbacks to toggle the IRQ_ENABLE |
| register at the PDC. The PDC's IRQ_ENABLE register is only used during |
| the monitoring mode when the system is asleep and is not needed for |
| active mode detection. |
| |
| Signed-off-by: Lina Iyer <ilina@codeaurora.org> |
| |
| BUG: 141169320 |
| TEST: Build and boot |
| |
| Change-Id: Ia5827a509bfb47aaa18ed0ea8f61c74f643fa91f |
| Signed-off-by: Maulik Shah <mkshah@codeaurora.org> |
| Link: https://patchwork.kernel.org/patch/11145361 |
| --- |
| drivers/irqchip/qcom-pdc.c | 16 ++++++++++++++-- |
| 1 file changed, 14 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c |
| index b230794e38c1..5eef5eab78df 100644 |
| --- a/drivers/irqchip/qcom-pdc.c |
| +++ b/drivers/irqchip/qcom-pdc.c |
| @@ -63,15 +63,25 @@ static void pdc_enable_intr(struct irq_data *d, bool on) |
| raw_spin_unlock(&pdc_lock); |
| } |
| |
| -static void qcom_pdc_gic_mask(struct irq_data *d) |
| +static void qcom_pdc_gic_disable(struct irq_data *d) |
| { |
| pdc_enable_intr(d, false); |
| + irq_chip_disable_parent(d); |
| +} |
| + |
| +static void qcom_pdc_gic_enable(struct irq_data *d) |
| +{ |
| + pdc_enable_intr(d, true); |
| + irq_chip_enable_parent(d); |
| +} |
| + |
| +static void qcom_pdc_gic_mask(struct irq_data *d) |
| +{ |
| irq_chip_mask_parent(d); |
| } |
| |
| static void qcom_pdc_gic_unmask(struct irq_data *d) |
| { |
| - pdc_enable_intr(d, true); |
| irq_chip_unmask_parent(d); |
| } |
| |
| @@ -148,6 +158,8 @@ static struct irq_chip qcom_pdc_gic_chip = { |
| .irq_eoi = irq_chip_eoi_parent, |
| .irq_mask = qcom_pdc_gic_mask, |
| .irq_unmask = qcom_pdc_gic_unmask, |
| + .irq_disable = qcom_pdc_gic_disable, |
| + .irq_enable = qcom_pdc_gic_enable, |
| .irq_retrigger = irq_chip_retrigger_hierarchy, |
| .irq_set_type = qcom_pdc_gic_set_type, |
| .flags = IRQCHIP_MASK_ON_SUSPEND | |