aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-01-06 20:29:26 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-01-06 20:29:26 -0500
commit5e93c6b4ecd78b1bab49bad1dc2f6ed7ec0115ee (patch)
tree4f4e321a1ca0baf64d8af528080c71f93495a7d7 /drivers/mmc/host
parent98d27b8abf413a310df6676f7d2128ada1cccc08 (diff)
parent3c0cb7c31c206aaedb967e44b98442bbeb17a6c4 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into rmobile-latest
Conflicts: arch/arm/mach-shmobile/Kconfig Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/at91_mci.c13
-rw-r--r--drivers/mmc/host/atmel-mci.c18
-rw-r--r--drivers/mmc/host/mmci.c207
-rw-r--r--drivers/mmc/host/mmci.h9
-rw-r--r--drivers/mmc/host/msm_sdcc.c139
-rw-r--r--drivers/mmc/host/msm_sdcc.h8
6 files changed, 320 insertions, 74 deletions
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 591ab540b407..d3e6a962f423 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -69,6 +69,7 @@
69#include <linux/highmem.h> 69#include <linux/highmem.h>
70 70
71#include <linux/mmc/host.h> 71#include <linux/mmc/host.h>
72#include <linux/mmc/sdio.h>
72 73
73#include <asm/io.h> 74#include <asm/io.h>
74#include <asm/irq.h> 75#include <asm/irq.h>
@@ -493,10 +494,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
493 else if (data->flags & MMC_DATA_WRITE) 494 else if (data->flags & MMC_DATA_WRITE)
494 cmdr |= AT91_MCI_TRCMD_START; 495 cmdr |= AT91_MCI_TRCMD_START;
495 496
496 if (data->flags & MMC_DATA_STREAM) 497 if (cmd->opcode == SD_IO_RW_EXTENDED) {
497 cmdr |= AT91_MCI_TRTYP_STREAM; 498 cmdr |= AT91_MCI_TRTYP_SDIO_BLOCK;
498 if (data->blocks > 1) 499 } else {
499 cmdr |= AT91_MCI_TRTYP_MULTIPLE; 500 if (data->flags & MMC_DATA_STREAM)
501 cmdr |= AT91_MCI_TRTYP_STREAM;
502 if (data->blocks > 1)
503 cmdr |= AT91_MCI_TRTYP_MULTIPLE;
504 }
500 } 505 }
501 else { 506 else {
502 block_length = 0; 507 block_length = 0;
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 301351a5d838..ad2a7a032cdf 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -26,6 +26,7 @@
26#include <linux/stat.h> 26#include <linux/stat.h>
27 27
28#include <linux/mmc/host.h> 28#include <linux/mmc/host.h>
29#include <linux/mmc/sdio.h>
29 30
30#include <mach/atmel-mci.h> 31#include <mach/atmel-mci.h>
31#include <linux/atmel-mci.h> 32#include <linux/atmel-mci.h>
@@ -532,12 +533,17 @@ static u32 atmci_prepare_command(struct mmc_host *mmc,
532 data = cmd->data; 533 data = cmd->data;
533 if (data) { 534 if (data) {
534 cmdr |= MCI_CMDR_START_XFER; 535 cmdr |= MCI_CMDR_START_XFER;
535 if (data->flags & MMC_DATA_STREAM) 536
536 cmdr |= MCI_CMDR_STREAM; 537 if (cmd->opcode == SD_IO_RW_EXTENDED) {
537 else if (data->blocks > 1) 538 cmdr |= MCI_CMDR_SDIO_BLOCK;
538 cmdr |= MCI_CMDR_MULTI_BLOCK; 539 } else {
539 else 540 if (data->flags & MMC_DATA_STREAM)
540 cmdr |= MCI_CMDR_BLOCK; 541 cmdr |= MCI_CMDR_STREAM;
542 else if (data->blocks > 1)
543 cmdr |= MCI_CMDR_MULTI_BLOCK;
544 else
545 cmdr |= MCI_CMDR_BLOCK;
546 }
541 547
542 if (data->flags & MMC_DATA_READ) 548 if (data->flags & MMC_DATA_READ)
543 cmdr |= MCI_CMDR_TRDIR_READ; 549 cmdr |= MCI_CMDR_TRDIR_READ;
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 87b4fc6c98c2..563022825667 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -19,6 +19,7 @@
19#include <linux/highmem.h> 19#include <linux/highmem.h>
20#include <linux/log2.h> 20#include <linux/log2.h>
21#include <linux/mmc/host.h> 21#include <linux/mmc/host.h>
22#include <linux/mmc/card.h>
22#include <linux/amba/bus.h> 23#include <linux/amba/bus.h>
23#include <linux/clk.h> 24#include <linux/clk.h>
24#include <linux/scatterlist.h> 25#include <linux/scatterlist.h>
@@ -45,6 +46,12 @@ static unsigned int fmax = 515633;
45 * is asserted (likewise for RX) 46 * is asserted (likewise for RX)
46 * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY 47 * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
47 * is asserted (likewise for RX) 48 * is asserted (likewise for RX)
49 * @broken_blockend: the MCI_DATABLOCKEND is broken on the hardware
50 * and will not work at all.
51 * @broken_blockend_dma: the MCI_DATABLOCKEND is broken on the hardware when
52 * using DMA.
53 * @sdio: variant supports SDIO
54 * @st_clkdiv: true if using a ST-specific clock divider algorithm
48 */ 55 */
49struct variant_data { 56struct variant_data {
50 unsigned int clkreg; 57 unsigned int clkreg;
@@ -52,6 +59,10 @@ struct variant_data {
52 unsigned int datalength_bits; 59 unsigned int datalength_bits;
53 unsigned int fifosize; 60 unsigned int fifosize;
54 unsigned int fifohalfsize; 61 unsigned int fifohalfsize;
62 bool broken_blockend;
63 bool broken_blockend_dma;
64 bool sdio;
65 bool st_clkdiv;
55}; 66};
56 67
57static struct variant_data variant_arm = { 68static struct variant_data variant_arm = {
@@ -65,6 +76,8 @@ static struct variant_data variant_u300 = {
65 .fifohalfsize = 8 * 4, 76 .fifohalfsize = 8 * 4,
66 .clkreg_enable = 1 << 13, /* HWFCEN */ 77 .clkreg_enable = 1 << 13, /* HWFCEN */
67 .datalength_bits = 16, 78 .datalength_bits = 16,
79 .broken_blockend_dma = true,
80 .sdio = true,
68}; 81};
69 82
70static struct variant_data variant_ux500 = { 83static struct variant_data variant_ux500 = {
@@ -73,7 +86,11 @@ static struct variant_data variant_ux500 = {
73 .clkreg = MCI_CLK_ENABLE, 86 .clkreg = MCI_CLK_ENABLE,
74 .clkreg_enable = 1 << 14, /* HWFCEN */ 87 .clkreg_enable = 1 << 14, /* HWFCEN */
75 .datalength_bits = 24, 88 .datalength_bits = 24,
89 .broken_blockend = true,
90 .sdio = true,
91 .st_clkdiv = true,
76}; 92};
93
77/* 94/*
78 * This must be called with host->lock held 95 * This must be called with host->lock held
79 */ 96 */
@@ -86,7 +103,22 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
86 if (desired >= host->mclk) { 103 if (desired >= host->mclk) {
87 clk = MCI_CLK_BYPASS; 104 clk = MCI_CLK_BYPASS;
88 host->cclk = host->mclk; 105 host->cclk = host->mclk;
106 } else if (variant->st_clkdiv) {
107 /*
108 * DB8500 TRM says f = mclk / (clkdiv + 2)
109 * => clkdiv = (mclk / f) - 2
110 * Round the divider up so we don't exceed the max
111 * frequency
112 */
113 clk = DIV_ROUND_UP(host->mclk, desired) - 2;
114 if (clk >= 256)
115 clk = 255;
116 host->cclk = host->mclk / (clk + 2);
89 } else { 117 } else {
118 /*
119 * PL180 TRM says f = mclk / (2 * (clkdiv + 1))
120 * => clkdiv = mclk / (2 * f) - 1
121 */
90 clk = host->mclk / (2 * desired) - 1; 122 clk = host->mclk / (2 * desired) - 1;
91 if (clk >= 256) 123 if (clk >= 256)
92 clk = 255; 124 clk = 255;
@@ -129,10 +161,26 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
129 spin_lock(&host->lock); 161 spin_lock(&host->lock);
130} 162}
131 163
164static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
165{
166 void __iomem *base = host->base;
167
168 if (host->singleirq) {
169 unsigned int mask0 = readl(base + MMCIMASK0);
170
171 mask0 &= ~MCI_IRQ1MASK;
172 mask0 |= mask;
173
174 writel(mask0, base + MMCIMASK0);
175 }
176
177 writel(mask, base + MMCIMASK1);
178}
179
132static void mmci_stop_data(struct mmci_host *host) 180static void mmci_stop_data(struct mmci_host *host)
133{ 181{
134 writel(0, host->base + MMCIDATACTRL); 182 writel(0, host->base + MMCIDATACTRL);
135 writel(0, host->base + MMCIMASK1); 183 mmci_set_mask1(host, 0);
136 host->data = NULL; 184 host->data = NULL;
137} 185}
138 186
@@ -162,6 +210,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
162 host->data = data; 210 host->data = data;
163 host->size = data->blksz * data->blocks; 211 host->size = data->blksz * data->blocks;
164 host->data_xfered = 0; 212 host->data_xfered = 0;
213 host->blockend = false;
214 host->dataend = false;
165 215
166 mmci_init_sg(host, data); 216 mmci_init_sg(host, data);
167 217
@@ -196,9 +246,14 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
196 irqmask = MCI_TXFIFOHALFEMPTYMASK; 246 irqmask = MCI_TXFIFOHALFEMPTYMASK;
197 } 247 }
198 248
249 /* The ST Micro variants has a special bit to enable SDIO */
250 if (variant->sdio && host->mmc->card)
251 if (mmc_card_sdio(host->mmc->card))
252 datactrl |= MCI_ST_DPSM_SDIOEN;
253
199 writel(datactrl, base + MMCIDATACTRL); 254 writel(datactrl, base + MMCIDATACTRL);
200 writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); 255 writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
201 writel(irqmask, base + MMCIMASK1); 256 mmci_set_mask1(host, irqmask);
202} 257}
203 258
204static void 259static void
@@ -233,20 +288,9 @@ static void
233mmci_data_irq(struct mmci_host *host, struct mmc_data *data, 288mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
234 unsigned int status) 289 unsigned int status)
235{ 290{
236 if (status & MCI_DATABLOCKEND) { 291 struct variant_data *variant = host->variant;
237 host->data_xfered += data->blksz; 292
238#ifdef CONFIG_ARCH_U300 293 /* First check for errors */
239 /*
240 * On the U300 some signal or other is
241 * badly routed so that a data write does
242 * not properly terminate with a MCI_DATAEND
243 * status flag. This quirk will make writes
244 * work again.
245 */
246 if (data->flags & MMC_DATA_WRITE)
247 status |= MCI_DATAEND;
248#endif
249 }
250 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { 294 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
251 dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status); 295 dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status);
252 if (status & MCI_DATACRCFAIL) 296 if (status & MCI_DATACRCFAIL)
@@ -255,7 +299,10 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
255 data->error = -ETIMEDOUT; 299 data->error = -ETIMEDOUT;
256 else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) 300 else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
257 data->error = -EIO; 301 data->error = -EIO;
258 status |= MCI_DATAEND; 302
303 /* Force-complete the transaction */
304 host->blockend = true;
305 host->dataend = true;
259 306
260 /* 307 /*
261 * We hit an error condition. Ensure that any data 308 * We hit an error condition. Ensure that any data
@@ -273,9 +320,64 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
273 local_irq_restore(flags); 320 local_irq_restore(flags);
274 } 321 }
275 } 322 }
276 if (status & MCI_DATAEND) { 323
324 /*
325 * On ARM variants in PIO mode, MCI_DATABLOCKEND
326 * is always sent first, and we increase the
327 * transfered number of bytes for that IRQ. Then
328 * MCI_DATAEND follows and we conclude the transaction.
329 *
330 * On the Ux500 single-IRQ variant MCI_DATABLOCKEND
331 * doesn't seem to immediately clear from the status,
332 * so we can't use it keep count when only one irq is
333 * used because the irq will hit for other reasons, and
334 * then the flag is still up. So we use the MCI_DATAEND
335 * IRQ at the end of the entire transfer because
336 * MCI_DATABLOCKEND is broken.
337 *
338 * In the U300, the IRQs can arrive out-of-order,
339 * e.g. MCI_DATABLOCKEND sometimes arrives after MCI_DATAEND,
340 * so for this case we use the flags "blockend" and
341 * "dataend" to make sure both IRQs have arrived before
342 * concluding the transaction. (This does not apply
343 * to the Ux500 which doesn't fire MCI_DATABLOCKEND
344 * at all.) In DMA mode it suffers from the same problem
345 * as the Ux500.
346 */
347 if (status & MCI_DATABLOCKEND) {
348 /*
349 * Just being a little over-cautious, we do not
350 * use this progressive update if the hardware blockend
351 * flag is unreliable: since it can stay high between
352 * IRQs it will corrupt the transfer counter.
353 */
354 if (!variant->broken_blockend)
355 host->data_xfered += data->blksz;
356 host->blockend = true;
357 }
358
359 if (status & MCI_DATAEND)
360 host->dataend = true;
361
362 /*
363 * On variants with broken blockend we shall only wait for dataend,
364 * on others we must sync with the blockend signal since they can
365 * appear out-of-order.
366 */
367 if (host->dataend && (host->blockend || variant->broken_blockend)) {
277 mmci_stop_data(host); 368 mmci_stop_data(host);
278 369
370 /* Reset these flags */
371 host->blockend = false;
372 host->dataend = false;
373
374 /*
375 * Variants with broken blockend flags need to handle the
376 * end of the entire transfer here.
377 */
378 if (variant->broken_blockend && !data->error)
379 host->data_xfered += data->blksz * data->blocks;
380
279 if (!data->stop) { 381 if (!data->stop) {
280 mmci_request_end(host, data->mrq); 382 mmci_request_end(host, data->mrq);
281 } else { 383 } else {
@@ -356,7 +458,32 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
356 variant->fifosize : variant->fifohalfsize; 458 variant->fifosize : variant->fifohalfsize;
357 count = min(remain, maxcnt); 459 count = min(remain, maxcnt);
358 460
359 writesl(base + MMCIFIFO, ptr, count >> 2); 461 /*
462 * The ST Micro variant for SDIO transfer sizes
463 * less then 8 bytes should have clock H/W flow
464 * control disabled.
465 */
466 if (variant->sdio &&
467 mmc_card_sdio(host->mmc->card)) {
468 if (count < 8)
469 writel(readl(host->base + MMCICLOCK) &
470 ~variant->clkreg_enable,
471 host->base + MMCICLOCK);
472 else
473 writel(readl(host->base + MMCICLOCK) |
474 variant->clkreg_enable,
475 host->base + MMCICLOCK);
476 }
477
478 /*
479 * SDIO especially may want to send something that is
480 * not divisible by 4 (as opposed to card sectors
481 * etc), and the FIFO only accept full 32-bit writes.
482 * So compensate by adding +3 on the count, a single
483 * byte become a 32bit write, 7 bytes will be two
484 * 32bit writes etc.
485 */
486 writesl(base + MMCIFIFO, ptr, (count + 3) >> 2);
360 487
361 ptr += count; 488 ptr += count;
362 remain -= count; 489 remain -= count;
@@ -437,7 +564,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
437 * "any data available" mode. 564 * "any data available" mode.
438 */ 565 */
439 if (status & MCI_RXACTIVE && host->size < variant->fifosize) 566 if (status & MCI_RXACTIVE && host->size < variant->fifosize)
440 writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1); 567 mmci_set_mask1(host, MCI_RXDATAAVLBLMASK);
441 568
442 /* 569 /*
443 * If we run out of data, disable the data IRQs; this 570 * If we run out of data, disable the data IRQs; this
@@ -446,7 +573,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
446 * stops us racing with our data end IRQ. 573 * stops us racing with our data end IRQ.
447 */ 574 */
448 if (host->size == 0) { 575 if (host->size == 0) {
449 writel(0, base + MMCIMASK1); 576 mmci_set_mask1(host, 0);
450 writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0); 577 writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0);
451 } 578 }
452 579
@@ -469,6 +596,14 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
469 struct mmc_data *data; 596 struct mmc_data *data;
470 597
471 status = readl(host->base + MMCISTATUS); 598 status = readl(host->base + MMCISTATUS);
599
600 if (host->singleirq) {
601 if (status & readl(host->base + MMCIMASK1))
602 mmci_pio_irq(irq, dev_id);
603
604 status &= ~MCI_IRQ1MASK;
605 }
606
472 status &= readl(host->base + MMCIMASK0); 607 status &= readl(host->base + MMCIMASK0);
473 writel(status, host->base + MMCICLEAR); 608 writel(status, host->base + MMCICLEAR);
474 609
@@ -635,6 +770,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
635 struct variant_data *variant = id->data; 770 struct variant_data *variant = id->data;
636 struct mmci_host *host; 771 struct mmci_host *host;
637 struct mmc_host *mmc; 772 struct mmc_host *mmc;
773 unsigned int mask;
638 int ret; 774 int ret;
639 775
640 /* must have platform data */ 776 /* must have platform data */
@@ -806,20 +942,30 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
806 if (ret) 942 if (ret)
807 goto unmap; 943 goto unmap;
808 944
809 ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, DRIVER_NAME " (pio)", host); 945 if (dev->irq[1] == NO_IRQ)
810 if (ret) 946 host->singleirq = true;
811 goto irq0_free; 947 else {
948 ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED,
949 DRIVER_NAME " (pio)", host);
950 if (ret)
951 goto irq0_free;
952 }
812 953
813 writel(MCI_IRQENABLE, host->base + MMCIMASK0); 954 mask = MCI_IRQENABLE;
955 /* Don't use the datablockend flag if it's broken */
956 if (variant->broken_blockend)
957 mask &= ~MCI_DATABLOCKEND;
814 958
815 amba_set_drvdata(dev, mmc); 959 writel(mask, host->base + MMCIMASK0);
816 960
817 mmc_add_host(mmc); 961 amba_set_drvdata(dev, mmc);
818 962
819 dev_info(&dev->dev, "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", 963 dev_info(&dev->dev, "%s: PL%03x rev%u at 0x%08llx irq %d,%d\n",
820 mmc_hostname(mmc), amba_rev(dev), amba_config(dev), 964 mmc_hostname(mmc), amba_part(dev), amba_rev(dev),
821 (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); 965 (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]);
822 966
967 mmc_add_host(mmc);
968
823 return 0; 969 return 0;
824 970
825 irq0_free: 971 irq0_free:
@@ -864,7 +1010,8 @@ static int __devexit mmci_remove(struct amba_device *dev)
864 writel(0, host->base + MMCIDATACTRL); 1010 writel(0, host->base + MMCIDATACTRL);
865 1011
866 free_irq(dev->irq[0], host); 1012 free_irq(dev->irq[0], host);
867 free_irq(dev->irq[1], host); 1013 if (!host->singleirq)
1014 free_irq(dev->irq[1], host);
868 1015
869 if (host->gpio_wp != -ENOSYS) 1016 if (host->gpio_wp != -ENOSYS)
870 gpio_free(host->gpio_wp); 1017 gpio_free(host->gpio_wp);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 4ae887fc0189..df06f01aac89 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -139,6 +139,11 @@
139 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ 139 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
140 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK) 140 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK)
141 141
142/* These interrupts are directed to IRQ1 when two IRQ lines are available */
143#define MCI_IRQ1MASK \
144 (MCI_RXFIFOHALFFULLMASK | MCI_RXDATAAVLBLMASK | \
145 MCI_TXFIFOHALFEMPTYMASK)
146
142#define NR_SG 16 147#define NR_SG 16
143 148
144struct clk; 149struct clk;
@@ -154,6 +159,7 @@ struct mmci_host {
154 int gpio_cd; 159 int gpio_cd;
155 int gpio_wp; 160 int gpio_wp;
156 int gpio_cd_irq; 161 int gpio_cd_irq;
162 bool singleirq;
157 163
158 unsigned int data_xfered; 164 unsigned int data_xfered;
159 165
@@ -171,6 +177,9 @@ struct mmci_host {
171 struct timer_list timer; 177 struct timer_list timer;
172 unsigned int oldstat; 178 unsigned int oldstat;
173 179
180 bool blockend;
181 bool dataend;
182
174 /* pio stuff */ 183 /* pio stuff */
175 struct sg_mapping_iter sg_miter; 184 struct sg_mapping_iter sg_miter;
176 unsigned int size; 185 unsigned int size;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 1290d14c5839..5decfd0bd61d 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -44,6 +44,7 @@
44#include <mach/mmc.h> 44#include <mach/mmc.h>
45#include <mach/msm_iomap.h> 45#include <mach/msm_iomap.h>
46#include <mach/dma.h> 46#include <mach/dma.h>
47#include <mach/clk.h>
47 48
48#include "msm_sdcc.h" 49#include "msm_sdcc.h"
49 50
@@ -126,6 +127,40 @@ static void
126msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, 127msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd,
127 u32 c); 128 u32 c);
128 129
130static void msmsdcc_reset_and_restore(struct msmsdcc_host *host)
131{
132 u32 mci_clk = 0;
133 u32 mci_mask0 = 0;
134 int ret = 0;
135
136 /* Save the controller state */
137 mci_clk = readl(host->base + MMCICLOCK);
138 mci_mask0 = readl(host->base + MMCIMASK0);
139
140 /* Reset the controller */
141 ret = clk_reset(host->clk, CLK_RESET_ASSERT);
142 if (ret)
143 pr_err("%s: Clock assert failed at %u Hz with err %d\n",
144 mmc_hostname(host->mmc), host->clk_rate, ret);
145
146 ret = clk_reset(host->clk, CLK_RESET_DEASSERT);
147 if (ret)
148 pr_err("%s: Clock deassert failed at %u Hz with err %d\n",
149 mmc_hostname(host->mmc), host->clk_rate, ret);
150
151 pr_info("%s: Controller has been re-initialiazed\n",
152 mmc_hostname(host->mmc));
153
154 /* Restore the contoller state */
155 writel(host->pwr, host->base + MMCIPOWER);
156 writel(mci_clk, host->base + MMCICLOCK);
157 writel(mci_mask0, host->base + MMCIMASK0);
158 ret = clk_set_rate(host->clk, host->clk_rate);
159 if (ret)
160 pr_err("%s: Failed to set clk rate %u Hz (%d)\n",
161 mmc_hostname(host->mmc), host->clk_rate, ret);
162}
163
129static void 164static void
130msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) 165msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq)
131{ 166{
@@ -155,7 +190,7 @@ static void
155msmsdcc_stop_data(struct msmsdcc_host *host) 190msmsdcc_stop_data(struct msmsdcc_host *host)
156{ 191{
157 host->curr.data = NULL; 192 host->curr.data = NULL;
158 host->curr.got_dataend = host->curr.got_datablkend = 0; 193 host->curr.got_dataend = 0;
159} 194}
160 195
161uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host) 196uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host)
@@ -189,42 +224,42 @@ msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd)
189} 224}
190 225
191static void 226static void
192msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, 227msmsdcc_dma_complete_tlet(unsigned long data)
193 unsigned int result,
194 struct msm_dmov_errdata *err)
195{ 228{
196 struct msmsdcc_dma_data *dma_data = 229 struct msmsdcc_host *host = (struct msmsdcc_host *)data;
197 container_of(cmd, struct msmsdcc_dma_data, hdr);
198 struct msmsdcc_host *host = dma_data->host;
199 unsigned long flags; 230 unsigned long flags;
200 struct mmc_request *mrq; 231 struct mmc_request *mrq;
232 struct msm_dmov_errdata err;
201 233
202 spin_lock_irqsave(&host->lock, flags); 234 spin_lock_irqsave(&host->lock, flags);
203 host->dma.active = 0; 235 host->dma.active = 0;
204 236
237 err = host->dma.err;
205 mrq = host->curr.mrq; 238 mrq = host->curr.mrq;
206 BUG_ON(!mrq); 239 BUG_ON(!mrq);
207 WARN_ON(!mrq->data); 240 WARN_ON(!mrq->data);
208 241
209 if (!(result & DMOV_RSLT_VALID)) { 242 if (!(host->dma.result & DMOV_RSLT_VALID)) {
210 pr_err("msmsdcc: Invalid DataMover result\n"); 243 pr_err("msmsdcc: Invalid DataMover result\n");
211 goto out; 244 goto out;
212 } 245 }
213 246
214 if (result & DMOV_RSLT_DONE) { 247 if (host->dma.result & DMOV_RSLT_DONE) {
215 host->curr.data_xfered = host->curr.xfer_size; 248 host->curr.data_xfered = host->curr.xfer_size;
216 } else { 249 } else {
217 /* Error or flush */ 250 /* Error or flush */
218 if (result & DMOV_RSLT_ERROR) 251 if (host->dma.result & DMOV_RSLT_ERROR)
219 pr_err("%s: DMA error (0x%.8x)\n", 252 pr_err("%s: DMA error (0x%.8x)\n",
220 mmc_hostname(host->mmc), result); 253 mmc_hostname(host->mmc), host->dma.result);
221 if (result & DMOV_RSLT_FLUSH) 254 if (host->dma.result & DMOV_RSLT_FLUSH)
222 pr_err("%s: DMA channel flushed (0x%.8x)\n", 255 pr_err("%s: DMA channel flushed (0x%.8x)\n",
223 mmc_hostname(host->mmc), result); 256 mmc_hostname(host->mmc), host->dma.result);
224 if (err) 257
225 pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n", 258 pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n",
226 err->flush[0], err->flush[1], err->flush[2], 259 err.flush[0], err.flush[1], err.flush[2],
227 err->flush[3], err->flush[4], err->flush[5]); 260 err.flush[3], err.flush[4], err.flush[5]);
261
262 msmsdcc_reset_and_restore(host);
228 if (!mrq->data->error) 263 if (!mrq->data->error)
229 mrq->data->error = -EIO; 264 mrq->data->error = -EIO;
230 } 265 }
@@ -242,8 +277,7 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
242 host->dma.sg = NULL; 277 host->dma.sg = NULL;
243 host->dma.busy = 0; 278 host->dma.busy = 0;
244 279
245 if ((host->curr.got_dataend && host->curr.got_datablkend) 280 if (host->curr.got_dataend || mrq->data->error) {
246 || mrq->data->error) {
247 281
248 /* 282 /*
249 * If we've already gotten our DATAEND / DATABLKEND 283 * If we've already gotten our DATAEND / DATABLKEND
@@ -273,6 +307,22 @@ out:
273 return; 307 return;
274} 308}
275 309
310static void
311msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd,
312 unsigned int result,
313 struct msm_dmov_errdata *err)
314{
315 struct msmsdcc_dma_data *dma_data =
316 container_of(cmd, struct msmsdcc_dma_data, hdr);
317 struct msmsdcc_host *host = dma_data->host;
318
319 dma_data->result = result;
320 if (err)
321 memcpy(&dma_data->err, err, sizeof(struct msm_dmov_errdata));
322
323 tasklet_schedule(&host->dma_tlet);
324}
325
276static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data) 326static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data)
277{ 327{
278 if (host->dma.channel == -1) 328 if (host->dma.channel == -1)
@@ -424,6 +474,11 @@ msmsdcc_start_command_deferred(struct msmsdcc_host *host,
424 (cmd->opcode == 53)) 474 (cmd->opcode == 53))
425 *c |= MCI_CSPM_DATCMD; 475 *c |= MCI_CSPM_DATCMD;
426 476
477 if (host->prog_scan && (cmd->opcode == 12)) {
478 *c |= MCI_CPSM_PROGENA;
479 host->prog_enable = true;
480 }
481
427 if (cmd == cmd->mrq->stop) 482 if (cmd == cmd->mrq->stop)
428 *c |= MCI_CSPM_MCIABORT; 483 *c |= MCI_CSPM_MCIABORT;
429 484
@@ -450,7 +505,6 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
450 host->curr.xfer_remain = host->curr.xfer_size; 505 host->curr.xfer_remain = host->curr.xfer_size;
451 host->curr.data_xfered = 0; 506 host->curr.data_xfered = 0;
452 host->curr.got_dataend = 0; 507 host->curr.got_dataend = 0;
453 host->curr.got_datablkend = 0;
454 508
455 memset(&host->pio, 0, sizeof(host->pio)); 509 memset(&host->pio, 0, sizeof(host->pio));
456 510
@@ -494,6 +548,8 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
494 host->cmd_c = c; 548 host->cmd_c = c;
495 } 549 }
496 msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); 550 msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr);
551 if (data->flags & MMC_DATA_WRITE)
552 host->prog_scan = true;
497 } else { 553 } else {
498 msmsdcc_writel(host, timeout, MMCIDATATIMER); 554 msmsdcc_writel(host, timeout, MMCIDATATIMER);
499 555
@@ -555,6 +611,9 @@ msmsdcc_pio_read(struct msmsdcc_host *host, char *buffer, unsigned int remain)
555 uint32_t *ptr = (uint32_t *) buffer; 611 uint32_t *ptr = (uint32_t *) buffer;
556 int count = 0; 612 int count = 0;
557 613
614 if (remain % 4)
615 remain = ((remain >> 2) + 1) << 2;
616
558 while (msmsdcc_readl(host, MMCISTATUS) & MCI_RXDATAAVLBL) { 617 while (msmsdcc_readl(host, MMCISTATUS) & MCI_RXDATAAVLBL) {
559 *ptr = msmsdcc_readl(host, MMCIFIFO + (count % MCI_FIFOSIZE)); 618 *ptr = msmsdcc_readl(host, MMCIFIFO + (count % MCI_FIFOSIZE));
560 ptr++; 619 ptr++;
@@ -575,13 +634,14 @@ msmsdcc_pio_write(struct msmsdcc_host *host, char *buffer,
575 char *ptr = buffer; 634 char *ptr = buffer;
576 635
577 do { 636 do {
578 unsigned int count, maxcnt; 637 unsigned int count, maxcnt, sz;
579 638
580 maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE : 639 maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE :
581 MCI_FIFOHALFSIZE; 640 MCI_FIFOHALFSIZE;
582 count = min(remain, maxcnt); 641 count = min(remain, maxcnt);
583 642
584 writesl(base + MMCIFIFO, ptr, count >> 2); 643 sz = count % 4 ? (count >> 2) + 1 : (count >> 2);
644 writesl(base + MMCIFIFO, ptr, sz);
585 ptr += count; 645 ptr += count;
586 remain -= count; 646 remain -= count;
587 647
@@ -702,10 +762,26 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
702 msm_dmov_stop_cmd(host->dma.channel, 762 msm_dmov_stop_cmd(host->dma.channel,
703 &host->dma.hdr, 0); 763 &host->dma.hdr, 0);
704 else if (host->curr.data) { /* Non DMA */ 764 else if (host->curr.data) { /* Non DMA */
765 msmsdcc_reset_and_restore(host);
705 msmsdcc_stop_data(host); 766 msmsdcc_stop_data(host);
706 msmsdcc_request_end(host, cmd->mrq); 767 msmsdcc_request_end(host, cmd->mrq);
707 } else /* host->data == NULL */ 768 } else { /* host->data == NULL */
708 msmsdcc_request_end(host, cmd->mrq); 769 if (!cmd->error && host->prog_enable) {
770 if (status & MCI_PROGDONE) {
771 host->prog_scan = false;
772 host->prog_enable = false;
773 msmsdcc_request_end(host, cmd->mrq);
774 } else {
775 host->curr.cmd = cmd;
776 }
777 } else {
778 if (host->prog_enable) {
779 host->prog_scan = false;
780 host->prog_enable = false;
781 }
782 msmsdcc_request_end(host, cmd->mrq);
783 }
784 }
709 } else if (cmd->data) 785 } else if (cmd->data)
710 if (!(cmd->data->flags & MMC_DATA_READ)) 786 if (!(cmd->data->flags & MMC_DATA_READ))
711 msmsdcc_start_data(host, cmd->data, 787 msmsdcc_start_data(host, cmd->data,
@@ -719,7 +795,7 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
719 struct mmc_data *data = host->curr.data; 795 struct mmc_data *data = host->curr.data;
720 796
721 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | 797 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL |
722 MCI_CMDTIMEOUT) && host->curr.cmd) { 798 MCI_CMDTIMEOUT | MCI_PROGDONE) && host->curr.cmd) {
723 msmsdcc_do_cmdirq(host, status); 799 msmsdcc_do_cmdirq(host, status);
724 } 800 }
725 801
@@ -735,6 +811,7 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
735 msm_dmov_stop_cmd(host->dma.channel, 811 msm_dmov_stop_cmd(host->dma.channel,
736 &host->dma.hdr, 0); 812 &host->dma.hdr, 0);
737 else { 813 else {
814 msmsdcc_reset_and_restore(host);
738 if (host->curr.data) 815 if (host->curr.data)
739 msmsdcc_stop_data(host); 816 msmsdcc_stop_data(host);
740 if (!data->stop) 817 if (!data->stop)
@@ -748,14 +825,10 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
748 if (!host->curr.got_dataend && (status & MCI_DATAEND)) 825 if (!host->curr.got_dataend && (status & MCI_DATAEND))
749 host->curr.got_dataend = 1; 826 host->curr.got_dataend = 1;
750 827
751 if (!host->curr.got_datablkend && (status & MCI_DATABLOCKEND))
752 host->curr.got_datablkend = 1;
753
754 /* 828 /*
755 * If DMA is still in progress, we complete via the completion handler 829 * If DMA is still in progress, we complete via the completion handler
756 */ 830 */
757 if (host->curr.got_dataend && host->curr.got_datablkend && 831 if (host->curr.got_dataend && !host->dma.busy) {
758 !host->dma.busy) {
759 /* 832 /*
760 * There appears to be an issue in the controller where 833 * There appears to be an issue in the controller where
761 * if you request a small block transfer (< fifo size), 834 * if you request a small block transfer (< fifo size),
@@ -792,8 +865,7 @@ msmsdcc_irq(int irq, void *dev_id)
792 865
793 do { 866 do {
794 status = msmsdcc_readl(host, MMCISTATUS); 867 status = msmsdcc_readl(host, MMCISTATUS);
795 status &= (msmsdcc_readl(host, MMCIMASK0) | 868 status &= msmsdcc_readl(host, MMCIMASK0);
796 MCI_DATABLOCKENDMASK);
797 msmsdcc_writel(host, status, MMCICLEAR); 869 msmsdcc_writel(host, status, MMCICLEAR);
798 870
799 if (status & MCI_SDIOINTR) 871 if (status & MCI_SDIOINTR)
@@ -1118,6 +1190,9 @@ msmsdcc_probe(struct platform_device *pdev)
1118 host->dmares = dmares; 1190 host->dmares = dmares;
1119 spin_lock_init(&host->lock); 1191 spin_lock_init(&host->lock);
1120 1192
1193 tasklet_init(&host->dma_tlet, msmsdcc_dma_complete_tlet,
1194 (unsigned long)host);
1195
1121 /* 1196 /*
1122 * Setup DMA 1197 * Setup DMA
1123 */ 1198 */
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index ff2b0f74f6f4..939557af266d 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -138,7 +138,7 @@
138#define MCI_IRQENABLE \ 138#define MCI_IRQENABLE \
139 (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ 139 (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
140 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ 140 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
141 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK) 141 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK|MCI_PROGDONEMASK)
142 142
143/* 143/*
144 * The size of the FIFO in bytes. 144 * The size of the FIFO in bytes.
@@ -172,6 +172,8 @@ struct msmsdcc_dma_data {
172 struct msmsdcc_host *host; 172 struct msmsdcc_host *host;
173 int busy; /* Set if DM is busy */ 173 int busy; /* Set if DM is busy */
174 int active; 174 int active;
175 unsigned int result;
176 struct msm_dmov_errdata err;
175}; 177};
176 178
177struct msmsdcc_pio_data { 179struct msmsdcc_pio_data {
@@ -188,7 +190,6 @@ struct msmsdcc_curr_req {
188 unsigned int xfer_remain; /* Bytes remaining to send */ 190 unsigned int xfer_remain; /* Bytes remaining to send */
189 unsigned int data_xfered; /* Bytes acked by BLKEND irq */ 191 unsigned int data_xfered; /* Bytes acked by BLKEND irq */
190 int got_dataend; 192 int got_dataend;
191 int got_datablkend;
192 int user_pages; 193 int user_pages;
193}; 194};
194 195
@@ -235,6 +236,7 @@ struct msmsdcc_host {
235 int cmdpoll; 236 int cmdpoll;
236 struct msmsdcc_stats stats; 237 struct msmsdcc_stats stats;
237 238
239 struct tasklet_struct dma_tlet;
238 /* Command parameters */ 240 /* Command parameters */
239 unsigned int cmd_timeout; 241 unsigned int cmd_timeout;
240 unsigned int cmd_pio_irqmask; 242 unsigned int cmd_pio_irqmask;
@@ -242,6 +244,8 @@ struct msmsdcc_host {
242 struct mmc_command *cmd_cmd; 244 struct mmc_command *cmd_cmd;
243 u32 cmd_c; 245 u32 cmd_c;
244 246
247 bool prog_scan;
248 bool prog_enable;
245}; 249};
246 250
247#endif 251#endif