diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2011-11-04 16:27:34 +0530 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 10:59:16 +0200 |
commit | c0e867edc32988ec4f6baaa3bfa1bf8f0ab286e5 (patch) | |
tree | 6c598a47a32f20b3c402ccd9ed5e414df6e7b3ed | |
parent | 52be3e88958147c29394d5d4c036f65376ba8a41 (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>
-rw-r--r-- | drivers/mfd/db5500-prcmu.c | 25 |
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(); |