aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorMarc Pignat <marc.pignat@hevs.ch>2008-05-30 08:05:24 -0400
committerPierre Ossman <drzeus@drzeus.cx>2008-07-15 08:14:41 -0400
commit80f9254668c63ae73c1359d8de50ad94aa1aa94a (patch)
treed80330908a3ed0ea65df5c343184a5ee1d63efd5 /drivers/mmc
parent8769392b1918ec70ab62eebc82e06c47c12f8304 (diff)
mmc: at91_mci: support for block size not modulo 4
Implement transfer with size not modulo 4 for at91sam9*. Please note that the at91rm9200 simply can't handle this. Signed-off-by: Marc Pignat <marc.pignat@hevs.ch> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/at91_mci.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index b9d4ed6b29b1..e40340f32e35 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -233,11 +233,11 @@ static void at91_mci_pre_dma_read(struct at91mci_host *host)
233 233
234 if (i == 0) { 234 if (i == 0) {
235 at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address); 235 at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address);
236 at91_mci_write(host, ATMEL_PDC_RCR, sg->length / 4); 236 at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
237 } 237 }
238 else { 238 else {
239 at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address); 239 at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address);
240 at91_mci_write(host, ATMEL_PDC_RNCR, sg->length / 4); 240 at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
241 } 241 }
242 } 242 }
243 243
@@ -430,7 +430,7 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
430 430
431 if (data) { 431 if (data) {
432 432
433 if ( data->blksz & 0x3 ) { 433 if ( cpu_is_at91rm9200() && (data->blksz & 0x3) ) {
434 pr_debug("Unsupported block size\n"); 434 pr_debug("Unsupported block size\n");
435 cmd->error = -EINVAL; 435 cmd->error = -EINVAL;
436 mmc_request_done(host->mmc, host->request); 436 mmc_request_done(host->mmc, host->request);
@@ -482,7 +482,10 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
482 } else { 482 } else {
483 /* zero block length and PDC mode */ 483 /* zero block length and PDC mode */
484 mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; 484 mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;
485 at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE); 485 mr |= (data->blksz & 0x3) ? AT91_MCI_PDCFBYTE : 0;
486 mr |= (block_length << 16);
487 mr |= AT91_MCI_PDCMODE;
488 at91_mci_write(host, AT91_MCI_MR, mr);
486 489
487 /* 490 /*
488 * Disable the PDC controller 491 * Disable the PDC controller
@@ -517,7 +520,9 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
517 pr_debug("Transmitting %d bytes\n", host->total_length); 520 pr_debug("Transmitting %d bytes\n", host->total_length);
518 521
519 at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); 522 at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
520 at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4); 523 at91_mci_write(host, ATMEL_PDC_TCR, (data->blksz & 0x3) ?
524 host->total_length : host->total_length / 4);
525
521 ier = AT91_MCI_CMDRDY; 526 ier = AT91_MCI_CMDRDY;
522 } 527 }
523 } 528 }