aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorVille Syrjala <syrjala@sci.fi>2008-06-14 13:27:20 -0400
committerPierre Ossman <drzeus@drzeus.cx>2008-07-15 08:14:42 -0400
commit5385edc50063a2175383ef5e90aa67fb6ab1beae (patch)
treef697344c2f4d9bad7a66b9b5661301004113b586 /drivers/mmc
parentfa1fe010c126ee69f2f75e3a4efc2f6252281ff8 (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')
-rw-r--r--drivers/mmc/host/at91_mci.c21
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);