aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2006-01-04 16:24:05 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-01-04 16:24:05 +0000
commite9c091b47409255cefa1672041479d850b7b991a (patch)
tree4a88257e054c186dc878a26ffa66f370b287195e /drivers/mmc
parentce11a161c11868f268964274edc7a26a3e063e08 (diff)
downloadkernel_samsung_smdk4412-e9c091b47409255cefa1672041479d850b7b991a.tar.gz
kernel_samsung_smdk4412-e9c091b47409255cefa1672041479d850b7b991a.tar.bz2
kernel_samsung_smdk4412-e9c091b47409255cefa1672041479d850b7b991a.zip
[MMC] mmci: add data cache coherency
Since MMCI currently uses PIO to read data, we have to take steps to ensure data cache coherency on aliasing CPU caches. Add the necessary flush_dcache_page() calls. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/mmci.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 166c9b0ad04..6d161c70014 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -20,6 +20,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/protocol.h>
+#include <asm/cacheflush.h>
#include <asm/div64.h>
#include <asm/io.h>
#include <asm/scatterlist.h>
@@ -157,6 +158,13 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
data->error = MMC_ERR_FIFO;
status |= MCI_DATAEND;
+
+ /*
+ * We hit an error condition. Ensure that any data
+ * partially written to a page is properly coherent.
+ */
+ if (host->sg_len && data->flags & MMC_DATA_READ)
+ flush_dcache_page(host->sg_ptr->page);
}
if (status & MCI_DATAEND) {
mmci_stop_data(host);
@@ -301,6 +309,13 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs)
if (remain)
break;
+ /*
+ * If we were reading, and we have completed this
+ * page, ensure that the data cache is coherent.
+ */
+ if (status & MCI_RXACTIVE)
+ flush_dcache_page(host->sg_ptr->page);
+
if (!mmci_next_sg(host))
break;