aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/mmci.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2006-01-27 17:18:29 -0500
committerLen Brown <len.brown@intel.com>2006-01-27 17:18:29 -0500
commit292dd876ee765c478b27c93cc51e93a558ed58bf (patch)
tree5b740e93253295baee2a9c414a6c66d03d44a9ef /drivers/mmc/mmci.c
parentd4ec6c7cc9a15a7a529719bc3b84f46812f9842e (diff)
parent9fdb62af92c741addbea15545f214a6e89460865 (diff)
Pull release into acpica branch
Diffstat (limited to 'drivers/mmc/mmci.c')
-rw-r--r--drivers/mmc/mmci.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 166c9b0ad04e..634ef53e85a5 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -19,13 +19,14 @@
19#include <linux/highmem.h> 19#include <linux/highmem.h>
20#include <linux/mmc/host.h> 20#include <linux/mmc/host.h>
21#include <linux/mmc/protocol.h> 21#include <linux/mmc/protocol.h>
22#include <linux/amba/bus.h>
23#include <linux/clk.h>
22 24
25#include <asm/cacheflush.h>
23#include <asm/div64.h> 26#include <asm/div64.h>
24#include <asm/io.h> 27#include <asm/io.h>
25#include <asm/scatterlist.h> 28#include <asm/scatterlist.h>
26#include <asm/sizes.h> 29#include <asm/sizes.h>
27#include <asm/hardware/amba.h>
28#include <asm/hardware/clock.h>
29#include <asm/mach/mmc.h> 30#include <asm/mach/mmc.h>
30 31
31#include "mmci.h" 32#include "mmci.h"
@@ -157,6 +158,13 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
157 else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) 158 else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
158 data->error = MMC_ERR_FIFO; 159 data->error = MMC_ERR_FIFO;
159 status |= MCI_DATAEND; 160 status |= MCI_DATAEND;
161
162 /*
163 * We hit an error condition. Ensure that any data
164 * partially written to a page is properly coherent.
165 */
166 if (host->sg_len && data->flags & MMC_DATA_READ)
167 flush_dcache_page(host->sg_ptr->page);
160 } 168 }
161 if (status & MCI_DATAEND) { 169 if (status & MCI_DATAEND) {
162 mmci_stop_data(host); 170 mmci_stop_data(host);
@@ -292,7 +300,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs)
292 /* 300 /*
293 * Unmap the buffer. 301 * Unmap the buffer.
294 */ 302 */
295 mmci_kunmap_atomic(host, &flags); 303 mmci_kunmap_atomic(host, buffer, &flags);
296 304
297 host->sg_off += len; 305 host->sg_off += len;
298 host->size -= len; 306 host->size -= len;
@@ -301,6 +309,13 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs)
301 if (remain) 309 if (remain)
302 break; 310 break;
303 311
312 /*
313 * If we were reading, and we have completed this
314 * page, ensure that the data cache is coherent.
315 */
316 if (status & MCI_RXACTIVE)
317 flush_dcache_page(host->sg_ptr->page);
318
304 if (!mmci_next_sg(host)) 319 if (!mmci_next_sg(host))
305 break; 320 break;
306 321
@@ -479,13 +494,9 @@ static int mmci_probe(struct amba_device *dev, void *id)
479 goto host_free; 494 goto host_free;
480 } 495 }
481 496
482 ret = clk_use(host->clk);
483 if (ret)
484 goto clk_free;
485
486 ret = clk_enable(host->clk); 497 ret = clk_enable(host->clk);
487 if (ret) 498 if (ret)
488 goto clk_unuse; 499 goto clk_free;
489 500
490 host->plat = plat; 501 host->plat = plat;
491 host->mclk = clk_get_rate(host->clk); 502 host->mclk = clk_get_rate(host->clk);
@@ -558,8 +569,6 @@ static int mmci_probe(struct amba_device *dev, void *id)
558 iounmap(host->base); 569 iounmap(host->base);
559 clk_disable: 570 clk_disable:
560 clk_disable(host->clk); 571 clk_disable(host->clk);
561 clk_unuse:
562 clk_unuse(host->clk);
563 clk_free: 572 clk_free:
564 clk_put(host->clk); 573 clk_put(host->clk);
565 host_free: 574 host_free:
@@ -594,7 +603,6 @@ static int mmci_remove(struct amba_device *dev)
594 603
595 iounmap(host->base); 604 iounmap(host->base);
596 clk_disable(host->clk); 605 clk_disable(host->clk);
597 clk_unuse(host->clk);
598 clk_put(host->clk); 606 clk_put(host->clk);
599 607
600 mmc_free_host(mmc); 608 mmc_free_host(mmc);