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

Commit 22cb42d1 authored by Ashay Jaiswal's avatar Ashay Jaiswal
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: 1008665
Change-Id: I068f5c7d33758063878721d7cce1308fa803e3bd
Signed-off-by: default avatarAshay Jaiswal <ashayj@codeaurora.org>
parent cc957303
Loading
Loading
Loading
Loading
+25 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -928,6 +928,10 @@ __pmic_arb_periph_irq(int irq, void *dev_id, bool show)
	int first = pmic_arb->min_intr_apid >> 5;
	int first = pmic_arb->min_intr_apid >> 5;
	int last = pmic_arb->max_intr_apid >> 5;
	int last = pmic_arb->max_intr_apid >> 5;
	int i, j;
	int i, j;
	/* status based dispatch */
	bool acc_valid = false;
	u32 irq_status = 0;



	dev_dbg(pmic_arb->dev, "Peripheral interrupt detected\n");
	dev_dbg(pmic_arb->dev, "Peripheral interrupt detected\n");


@@ -935,6 +939,8 @@ __pmic_arb_periph_irq(int irq, void *dev_id, bool show)
	for (i = first; i <= last; ++i) {
	for (i = first; i <= last; ++i) {
		status = readl_relaxed(pmic_arb->intr +
		status = readl_relaxed(pmic_arb->intr +
					pmic_arb->ver->owner_acc_status(ee, i));
					pmic_arb->ver->owner_acc_status(ee, i));
		if (status)
			acc_valid = true;


		if ((i == 0) && (status & pmic_arb->irq_acc0_init_val)) {
		if ((i == 0) && (status & pmic_arb->irq_acc0_init_val)) {
			dev_dbg(pmic_arb->dev, "Ignoring IRQ acc[0] mask:0x%x\n",
			dev_dbg(pmic_arb->dev, "Ignoring IRQ acc[0] mask:0x%x\n",
@@ -951,6 +957,24 @@ __pmic_arb_periph_irq(int irq, void *dev_id, bool show)
		}
		}
	}
	}


	/* ACC_STATUS is empty but IRQ fired check IRQ_STATUS */
	if (!acc_valid) {
		for (i = pmic_arb->min_intr_apid; i <= pmic_arb->max_intr_apid;
				i++) {
			if (!is_apid_valid(pmic_arb, i))
				continue;
			irq_status = readl_relaxed(pmic_arb->intr +
					pmic_arb->ver->irq_status(i));
			if (irq_status) {
				dev_dbg(pmic_arb->dev,
					"Dispatching for IRQ_STATUS_REG:0x%lx IRQ_STATUS:0x%x\n",
					(ulong) pmic_arb->ver->irq_status(i),
					irq_status);
				ret |= periph_interrupt(pmic_arb, i, show);
			}
		}
	}

	return ret;
	return ret;
}
}