summaryrefslogtreecommitdiff
path: root/drivers/mfd/db5500-prcmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/db5500-prcmu.c')
-rw-r--r--drivers/mfd/db5500-prcmu.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/mfd/db5500-prcmu.c b/drivers/mfd/db5500-prcmu.c
index 2633b728ada..452084f6858 100644
--- a/drivers/mfd/db5500-prcmu.c
+++ b/drivers/mfd/db5500-prcmu.c
@@ -1644,8 +1644,10 @@ static bool read_mailbox_0(void)
ev &= mb0_transfer.req.dbb_irqs;
for (n = 0; n < NUM_DB5500_PRCMU_WAKEUPS; n++) {
- if (ev & prcmu_irq_bit[n])
- generic_handle_irq(IRQ_DB5500_PRCMU_BASE + n);
+ if (ev & prcmu_irq_bit[n]) {
+ if (n != IRQ_INDEX(ABB))
+ generic_handle_irq(IRQ_DB5500_PRCMU_BASE + n);
+ }
}
r = true;
break;
@@ -1837,7 +1839,24 @@ static irqreturn_t prcmu_irq_handler(int irq, void *data)
static irqreturn_t prcmu_irq_thread_fn(int irq, void *data)
{
+ u32 ev;
+
+ /*
+ * ABB needs to be handled before the wakeup because
+ * the ping/pong buffers for ABB events could change
+ * after we acknowledge the wakeup.
+ */
+ if (readb(PRCM_ACK_MB0_READ_POINTER) & 1)
+ ev = readl(PRCM_ACK_MB0_WAKEUP_1_DBB);
+ else
+ ev = readl(PRCM_ACK_MB0_WAKEUP_0_DBB);
+
+ ev &= mb0_transfer.req.dbb_irqs;
+ if (ev & WAKEUP_BIT_ABB)
+ handle_nested_irq(IRQ_DB5500_PRCMU_ABB);
+
ack_dbb_wakeup();
+
return IRQ_HANDLED;
}
@@ -1933,6 +1952,8 @@ void __init db5500_prcmu_early_init(void)
irq = IRQ_DB5500_PRCMU_BASE + i;
irq_set_chip_and_handler(irq, &prcmu_irq_chip,
handle_simple_irq);
+ if (irq == IRQ_DB5500_PRCMU_ABB)
+ irq_set_nested_thread(irq, true);
set_irq_flags(irq, IRQF_VALID);
}
prcmu_ape_clocks_init();