diff options
author | Marc Pignat <marc.pignat@hevs.ch> | 2008-05-30 08:05:24 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-07-15 08:14:41 -0400 |
commit | 80f9254668c63ae73c1359d8de50ad94aa1aa94a (patch) | |
tree | d80330908a3ed0ea65df5c343184a5ee1d63efd5 /drivers/mmc | |
parent | 8769392b1918ec70ab62eebc82e06c47c12f8304 (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.c | 15 |
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 | } |