Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e47a3ba2 authored by Ashay Jaiswal's avatar Ashay Jaiswal Committed by David Collins
Browse files

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: default avatarAshay Jaiswal <ashayj@codeaurora.org>
[collinsd: fix merge conflict]
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
parent 1f1661bd
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -525,12 +525,18 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
	u8 ee = pmic_arb->ee;
	u32 status, enable;
	int i, id, apid;
	/* status based dispatch */
	bool acc_valid = false;
	u32 irq_status = 0;

	chained_irq_enter(chip, desc);

	for (i = first; i <= last; ++i) {
		status = readl_relaxed(
				ver_ops->owner_acc_status(pmic_arb, ee, i));
		if (status)
			acc_valid = true;

		while (status) {
			id = ffs(status) - 1;
			status &= ~BIT(id);
@@ -548,6 +554,28 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
		}
	}

	/* ACC_STATUS is empty but IRQ fired check IRQ_STATUS */
	if (!acc_valid) {
		for (i = pmic_arb->min_apid; i <= pmic_arb->max_apid; i++) {
			/* skip if APPS is not irq owner */
			if (pmic_arb->apid_data[i].irq_ee != pmic_arb->ee)
				continue;

			irq_status = readl_relaxed(
					     ver_ops->irq_status(pmic_arb, i));
			if (irq_status) {
				enable = readl_relaxed(
					     ver_ops->acc_enable(pmic_arb, i));
				if (enable & SPMI_PIC_ACC_ENABLE_BIT) {
					dev_dbg(&pmic_arb->spmic->dev,
						"Dispatching IRQ for apid=%d status=%x\n",
						i, irq_status);
					periph_interrupt(pmic_arb, i);
				}
			}
		}
	}

	chained_irq_exit(chip, desc);
}