Commit be7b5622 authored by Ido Yariv's avatar Ido Yariv Committed by Chris Ball

mmc: davinci: Eliminate spurious interrupts

The davinci mmc interrupt handler fills the fifo, as long as the DXRDY
or DRRDY bits are set in the status register.

If interrupts fire during this loop, they will be handled by the
handler, but the interrupt controller will still buffer these. As a
result, the handler will be called again to serve these needlessly. In
order to avoid these spurious interrupts, keep interrupts masked while
filling the fifo.
Signed-off-by: default avatarIdo Yariv <ido@wizery.com>
Tested-by: default avatarRajashekhara, Sudhakar <sudhakar.raj@ti.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 1f84b71b
...@@ -1009,12 +1009,33 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id) ...@@ -1009,12 +1009,33 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
* by read. So, it is not unbouned loop even in the case of * by read. So, it is not unbouned loop even in the case of
* non-dma. * non-dma.
*/ */
while (host->bytes_left && (status & (MMCST0_DXRDY | MMCST0_DRRDY))) { if (host->bytes_left && (status & (MMCST0_DXRDY | MMCST0_DRRDY))) {
davinci_fifo_data_trans(host, rw_threshold); unsigned long im_val;
status = readl(host->base + DAVINCI_MMCST0);
if (!status) /*
break; * If interrupts fire during the following loop, they will be
qstatus |= status; * handled by the handler, but the PIC will still buffer these.
* As a result, the handler will be called again to serve these
* needlessly. In order to avoid these spurious interrupts,
* keep interrupts masked during the loop.
*/
im_val = readl(host->base + DAVINCI_MMCIM);
writel(0, host->base + DAVINCI_MMCIM);
do {
davinci_fifo_data_trans(host, rw_threshold);
status = readl(host->base + DAVINCI_MMCST0);
qstatus |= status;
} while (host->bytes_left &&
(status & (MMCST0_DXRDY | MMCST0_DRRDY)));
/*
* If an interrupt is pending, it is assumed it will fire when
* it is unmasked. This assumption is also taken when the MMCIM
* is first set. Otherwise, writing to MMCIM after reading the
* status is race-prone.
*/
writel(im_val, host->base + DAVINCI_MMCIM);
} }
if (qstatus & MMCST0_DATDNE) { if (qstatus & MMCST0_DATDNE) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment