diff options
author | Ville Syrjala <syrjala@sci.fi> | 2008-06-14 13:27:20 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-07-15 08:14:42 -0400 |
commit | 5385edc50063a2175383ef5e90aa67fb6ab1beae (patch) | |
tree | f697344c2f4d9bad7a66b9b5661301004113b586 /drivers/mmc/host/at91_mci.c | |
parent | fa1fe010c126ee69f2f75e3a4efc2f6252281ff8 (diff) |
at91_mci: AT91SAM9260/9263 12 byte write erratum (v2)
AT91SAM926[0/3] PDC must write at least 12 bytes. The code compiles and runs
but the actual condition for this erratum did not trigger in my tests so it's
unclear if it actually works as intended.
Signed-off-by: Ville Syrjala <syrjala@sci.fi>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/host/at91_mci.c')
-rw-r--r-- | drivers/mmc/host/at91_mci.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index e4d018b2fe9f..d3e96ff41428 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -198,9 +198,14 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
198 | unsigned int len, i, size; | 198 | unsigned int len, i, size; |
199 | unsigned *dmabuf = host->buffer; | 199 | unsigned *dmabuf = host->buffer; |
200 | 200 | ||
201 | size = host->total_length; | 201 | size = data->blksz * data->blocks; |
202 | len = data->sg_len; | 202 | len = data->sg_len; |
203 | 203 | ||
204 | /* AT91SAM926[0/3] Data Write Operation and number of bytes erratum */ | ||
205 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | ||
206 | if (host->total_length == 12) | ||
207 | memset(dmabuf, 0, 12); | ||
208 | |||
204 | /* | 209 | /* |
205 | * Just loop through all entries. Size might not | 210 | * Just loop through all entries. Size might not |
206 | * be the entire list though so make sure that | 211 | * be the entire list though so make sure that |
@@ -222,9 +227,10 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
222 | 227 | ||
223 | for (index = 0; index < (amount / 4); index++) | 228 | for (index = 0; index < (amount / 4); index++) |
224 | *dmabuf++ = swab32(sgbuffer[index]); | 229 | *dmabuf++ = swab32(sgbuffer[index]); |
225 | } | 230 | } else { |
226 | else | ||
227 | memcpy(dmabuf, sgbuffer, amount); | 231 | memcpy(dmabuf, sgbuffer, amount); |
232 | dmabuf += amount; | ||
233 | } | ||
228 | 234 | ||
229 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | 235 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); |
230 | 236 | ||
@@ -417,7 +423,7 @@ static void at91_mci_update_bytes_xfered(struct at91mci_host *host) | |||
417 | /* card is in IDLE mode now */ | 423 | /* card is in IDLE mode now */ |
418 | pr_debug("-> bytes_xfered %d, total_length = %d\n", | 424 | pr_debug("-> bytes_xfered %d, total_length = %d\n", |
419 | data->bytes_xfered, host->total_length); | 425 | data->bytes_xfered, host->total_length); |
420 | data->bytes_xfered = host->total_length; | 426 | data->bytes_xfered = data->blksz * data->blocks; |
421 | } | 427 | } |
422 | } | 428 | } |
423 | } | 429 | } |
@@ -600,6 +606,13 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command | |||
600 | * Handle a write | 606 | * Handle a write |
601 | */ | 607 | */ |
602 | host->total_length = block_length * blocks; | 608 | host->total_length = block_length * blocks; |
609 | /* | ||
610 | * AT91SAM926[0/3] Data Write Operation and | ||
611 | * number of bytes erratum | ||
612 | */ | ||
613 | if (cpu_is_at91sam9260 () || cpu_is_at91sam9263()) | ||
614 | if (host->total_length < 12) | ||
615 | host->total_length = 12; | ||
603 | host->buffer = dma_alloc_coherent(NULL, | 616 | host->buffer = dma_alloc_coherent(NULL, |
604 | host->total_length, | 617 | host->total_length, |
605 | &host->physical_address, GFP_KERNEL); | 618 | &host->physical_address, GFP_KERNEL); |