summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshay Jaiswal <ashayj@codeaurora.org>2017-02-27 12:33:17 +0530
committerAshay Jaiswal <ashayj@codeaurora.org>2017-05-12 16:24:01 +0530
commit3050aad3ea84567d025d4afb1d98c4dab5b21273 (patch)
tree8bdda3c357037faed55be5492ac65d66a2879b7e
parentae4d972f07f97de9a368a33820a7fe38284498c2 (diff)
spmi-pmic-arb: add support to dispatch interrupt based on IRQ status
Current implementation of SPMI arbiter dispatches interrupt based on the Arbiter's accumulator status, in some cases the accumulator status may remain zero and the interrupt remains un-handled. Add logic to dispatch interrupts based Arbiter's IRQ status if the accumulator status is zero. CRs-Fixed: 2934741 Change-Id: I068f5c7d33758063878721d7cce1308fa803e3bd Signed-off-by: Ashay Jaiswal <ashayj@codeaurora.org>
-rw-r--r--drivers/spmi/spmi-pmic-arb.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index d1802bcba0fb..35d4dea41983 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -577,10 +577,16 @@ static void __pmic_arb_chained_irq(struct spmi_pmic_arb *pa, bool show)
int last = pa->max_apid >> 5;
u32 status, enable;
int i, id, apid;
+ /* status based dispatch */
+ bool acc_valid = false;
+ u32 irq_status = 0;
for (i = first; i <= last; ++i) {
status = readl_relaxed(pa->acc_status +
pa->ver_ops->owner_acc_status(pa->ee, i));
+ if (status)
+ acc_valid = true;
+
while (status) {
id = ffs(status) - 1;
status &= ~BIT(id);
@@ -591,6 +597,28 @@ static void __pmic_arb_chained_irq(struct spmi_pmic_arb *pa, bool show)
periph_interrupt(pa, apid, show);
}
}
+
+ /* ACC_STATUS is empty but IRQ fired check IRQ_STATUS */
+ if (!acc_valid) {
+ for (i = pa->min_apid; i <= pa->max_apid; i++) {
+ /* skip if APPS is not irq owner */
+ if (pa->apid_data[i].irq_owner != pa->ee)
+ continue;
+
+ irq_status = readl_relaxed(pa->intr +
+ pa->ver_ops->irq_status(i));
+ if (irq_status) {
+ enable = readl_relaxed(pa->intr +
+ pa->ver_ops->acc_enable(i));
+ if (enable & SPMI_PIC_ACC_ENABLE_BIT) {
+ dev_dbg(&pa->spmic->dev,
+ "Dispatching IRQ for apid=%d status=%x\n",
+ i, irq_status);
+ periph_interrupt(pa, i, show);
+ }
+ }
+ }
+ }
}
static void pmic_arb_chained_irq(struct irq_desc *desc)