aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLudovic Desroches <ludovic.desroches@atmel.com>2012-07-24 05:42:04 -0400
committerChris Ball <cjb@laptop.org>2012-09-04 13:58:07 -0400
commit077d40731edc90ee9dedf63249034c8cd5f694ce (patch)
treede469044a1580e9d163b9821fc8fc5c9e2ea5ba7
parent74f330bceaa7b88d06062e1cac3d519a3dfc041e (diff)
mmc: atmel-mci: not busy flag has also to be used for read operations
Even if the datasheet says that the not busy flag has to be used only for write operations, it's false except for version lesser than v2xx. Not waiting on the not busy flag for read operations can cause the controller to hang-up during the initialization of some SD cards with DMA after the first CMD6 -- the next command is sent too early. Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com> Cc: stable <stable@vger.kernel.org> [3.5, 3.6] Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/host/atmel-mci.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 322412cec4ee..a53c7c478e05 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -81,6 +81,7 @@ struct atmel_mci_caps {
81 bool has_bad_data_ordering; 81 bool has_bad_data_ordering;
82 bool need_reset_after_xfer; 82 bool need_reset_after_xfer;
83 bool need_blksz_mul_4; 83 bool need_blksz_mul_4;
84 bool need_notbusy_for_read_ops;
84}; 85};
85 86
86struct atmel_mci_dma { 87struct atmel_mci_dma {
@@ -1625,7 +1626,8 @@ static void atmci_tasklet_func(unsigned long priv)
1625 __func__); 1626 __func__);
1626 atmci_set_completed(host, EVENT_XFER_COMPLETE); 1627 atmci_set_completed(host, EVENT_XFER_COMPLETE);
1627 1628
1628 if (host->data->flags & MMC_DATA_WRITE) { 1629 if (host->caps.need_notbusy_for_read_ops ||
1630 (host->data->flags & MMC_DATA_WRITE)) {
1629 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY); 1631 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
1630 state = STATE_WAITING_NOTBUSY; 1632 state = STATE_WAITING_NOTBUSY;
1631 } else if (host->mrq->stop) { 1633 } else if (host->mrq->stop) {
@@ -2218,6 +2220,7 @@ static void __init atmci_get_cap(struct atmel_mci *host)
2218 host->caps.has_bad_data_ordering = 1; 2220 host->caps.has_bad_data_ordering = 1;
2219 host->caps.need_reset_after_xfer = 1; 2221 host->caps.need_reset_after_xfer = 1;
2220 host->caps.need_blksz_mul_4 = 1; 2222 host->caps.need_blksz_mul_4 = 1;
2223 host->caps.need_notbusy_for_read_ops = 0;
2221 2224
2222 /* keep only major version number */ 2225 /* keep only major version number */
2223 switch (version & 0xf00) { 2226 switch (version & 0xf00) {
@@ -2238,6 +2241,7 @@ static void __init atmci_get_cap(struct atmel_mci *host)
2238 case 0x200: 2241 case 0x200:
2239 host->caps.has_rwproof = 1; 2242 host->caps.has_rwproof = 1;
2240 host->caps.need_blksz_mul_4 = 0; 2243 host->caps.need_blksz_mul_4 = 0;
2244 host->caps.need_notbusy_for_read_ops = 1;
2241 case 0x100: 2245 case 0x100:
2242 host->caps.has_bad_data_ordering = 0; 2246 host->caps.has_bad_data_ordering = 0;
2243 host->caps.need_reset_after_xfer = 0; 2247 host->caps.need_reset_after_xfer = 0;