| From a0bf852cd11adbdd92230ace7fdd591a27257d91 Mon Sep 17 00:00:00 2001 |
| From: Yusuke Goda <yusuke.goda.sx@renesas.com> |
| Date: Thu, 9 Sep 2010 16:37:39 -0700 |
| Subject: [PATCH] tmio_mmc: don't clear unhandled pending interrupts |
| |
| commit b78d6c5f51935ba89df8db33a57bacb547aa7325 upstream. |
| |
| Previously, it was possible for ack_mmc_irqs() to clear pending interrupt |
| bits in the CTL_STATUS register, even though the interrupt handler had not |
| been called. This was because of a race that existed when doing a |
| read-modify-write sequence on CTL_STATUS. After the read step in this |
| sequence, if an interrupt occurred (causing one of the bits in CTL_STATUS |
| to be set) the write step would inadvertently clear it. |
| |
| Observed with the TMIO_STAT_RXRDY bit together with CMD53 on AR6002 and |
| BCM4318 SDIO cards in polled mode. |
| |
| This patch eliminates this race by only writing to CTL_STATUS and clearing |
| the interrupts that were passed as an argument to ack_mmc_irqs()." |
| |
| [matt@console-pimps.org: rewrote changelog] |
| Signed-off-by: Yusuke Goda <yusuke.goda.sx@renesas.com> |
| Acked-by: Magnus Damm <damm@opensource.se>" |
| Tested-by: Arnd Hannemann <arnd@arndnet.de>" |
| Acked-by: Ian Molton <ian@mnementh.co.uk> |
| Cc: Matt Fleming <matt@console-pimps.org> |
| Cc: Samuel Ortiz <sameo@linux.intel.com> |
| Cc: Paul Mundt <lethal@linux-sh.org> |
| Cc: <linux-mmc@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| drivers/mmc/host/tmio_mmc.h | 5 +---- |
| 1 files changed, 1 insertions(+), 4 deletions(-) |
| |
| diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h |
| index dafecfb..1836ed9 100644 |
| --- a/drivers/mmc/host/tmio_mmc.h |
| +++ b/drivers/mmc/host/tmio_mmc.h |
| @@ -80,10 +80,7 @@ |
| |
| #define ack_mmc_irqs(host, i) \ |
| do { \ |
| - u32 mask;\ |
| - mask = sd_ctrl_read32((host), CTL_STATUS); \ |
| - mask &= ~((i) & TMIO_MASK_IRQ); \ |
| - sd_ctrl_write32((host), CTL_STATUS, mask); \ |
| + sd_ctrl_write32((host), CTL_STATUS, ~(i)); \ |
| } while (0) |
| |
| |
| -- |
| 1.7.0.4 |
| |