summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2011-11-04 16:27:34 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 10:59:16 +0200
commitc0e867edc32988ec4f6baaa3bfa1bf8f0ab286e5 (patch)
tree6c598a47a32f20b3c402ccd9ed5e414df6e7b3ed /drivers/mfd
parent52be3e88958147c29394d5d4c036f65376ba8a41 (diff)
db5500-prcmu: handle AB5500 irq as a nested thread
Handle ABB irq as a nested thread because otherwise the READ_POINTER which indicates which buffer to use for the ABB events could change (after the ack_dbb_wakeup()) before the ABB interrupt handler has a chance to handle it. ST-Ericsson ID: 370101 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I37db4651ddf242500fbc750d8f07893bfb2d4d1b Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/36457 Reviewed-by: QABUILD Reviewed-by: Vijaya Kumar K-1 <vijay.kilari@stericsson.com>
Diffstat (limited to 'drivers/mfd')
-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();