aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mmci.c
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2014-01-13 10:49:31 -0500
committerChris Ball <chris@printf.net>2014-02-23 10:41:21 -0500
commit8d94b54d99ea968a9d188ca0e68793ebed601220 (patch)
treefa21c1ab39f0955a29f50ca429e2ac43dad5534b /drivers/mmc/host/mmci.c
parente7f3d22289e4307b3071cc18b1d8ecc6598c0be4 (diff)
mmc: mmci: Enable support for busy detection for ux500 variant
The ux500 variants have HW busy detection support, which is indicated by the busy_detect flag. For these variants let's enable the MMC_CAP_WAIT_WHILE_BUSY flag and add the support for it. The mmc core will provide the RSP_BUSY command flag for those requests we should care about busy detection. Regarding the max_busy_timeout, the HW don't support busy detection timeouts so at this initial step let's make it simple and set it to zero to indicate we are able to support any timeout. Cc: Russell King <linux@arm.linux.org.uk> Cc: Johan Rudholm <jrudholm@gmail.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r--drivers/mmc/host/mmci.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8324e3ec21c2..771c60ab4a32 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -921,6 +921,29 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
921{ 921{
922 void __iomem *base = host->base; 922 void __iomem *base = host->base;
923 bool sbc = (cmd == host->mrq->sbc); 923 bool sbc = (cmd == host->mrq->sbc);
924 bool busy_resp = host->variant->busy_detect &&
925 (cmd->flags & MMC_RSP_BUSY);
926
927 /* Check if we need to wait for busy completion. */
928 if (host->busy_status && (status & MCI_ST_CARDBUSY))
929 return;
930
931 /* Enable busy completion if needed and supported. */
932 if (!host->busy_status && busy_resp &&
933 !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) &&
934 (readl(base + MMCISTATUS) & MCI_ST_CARDBUSY)) {
935 writel(readl(base + MMCIMASK0) | MCI_ST_BUSYEND,
936 base + MMCIMASK0);
937 host->busy_status = status & (MCI_CMDSENT|MCI_CMDRESPEND);
938 return;
939 }
940
941 /* At busy completion, mask the IRQ and complete the request. */
942 if (host->busy_status) {
943 writel(readl(base + MMCIMASK0) & ~MCI_ST_BUSYEND,
944 base + MMCIMASK0);
945 host->busy_status = 0;
946 }
924 947
925 host->cmd = NULL; 948 host->cmd = NULL;
926 949
@@ -1139,14 +1162,19 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
1139 status &= ~MCI_IRQ1MASK; 1162 status &= ~MCI_IRQ1MASK;
1140 } 1163 }
1141 1164
1165 /*
1166 * We intentionally clear the MCI_ST_CARDBUSY IRQ here (if it's
1167 * enabled) since the HW seems to be triggering the IRQ on both
1168 * edges while monitoring DAT0 for busy completion.
1169 */
1142 status &= readl(host->base + MMCIMASK0); 1170 status &= readl(host->base + MMCIMASK0);
1143 writel(status, host->base + MMCICLEAR); 1171 writel(status, host->base + MMCICLEAR);
1144 1172
1145 dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); 1173 dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
1146 1174
1147 cmd = host->cmd; 1175 cmd = host->cmd;
1148 if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT| 1176 if ((status|host->busy_status) & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|
1149 MCI_CMDRESPEND) && cmd) 1177 MCI_CMDSENT|MCI_CMDRESPEND) && cmd)
1150 mmci_cmd_irq(host, cmd, status); 1178 mmci_cmd_irq(host, cmd, status);
1151 1179
1152 data = host->data; 1180 data = host->data;
@@ -1155,6 +1183,10 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
1155 MCI_DATABLOCKEND) && data) 1183 MCI_DATABLOCKEND) && data)
1156 mmci_data_irq(host, data, status); 1184 mmci_data_irq(host, data, status);
1157 1185
1186 /* Don't poll for busy completion in irq context. */
1187 if (host->busy_status)
1188 status &= ~MCI_ST_CARDBUSY;
1189
1158 ret = 1; 1190 ret = 1;
1159 } while (status); 1191 } while (status);
1160 1192
@@ -1504,12 +1536,6 @@ static int mmci_probe(struct amba_device *dev,
1504 goto clk_disable; 1536 goto clk_disable;
1505 } 1537 }
1506 1538
1507 if (variant->busy_detect) {
1508 mmci_ops.card_busy = mmci_card_busy;
1509 mmci_write_datactrlreg(host, MCI_ST_DPSM_BUSYMODE);
1510 }
1511
1512 mmc->ops = &mmci_ops;
1513 /* 1539 /*
1514 * The ARM and ST versions of the block have slightly different 1540 * The ARM and ST versions of the block have slightly different
1515 * clock divider equations which means that the minimum divider 1541 * clock divider equations which means that the minimum divider
@@ -1543,6 +1569,15 @@ static int mmci_probe(struct amba_device *dev,
1543 mmc->caps = plat->capabilities; 1569 mmc->caps = plat->capabilities;
1544 mmc->caps2 = plat->capabilities2; 1570 mmc->caps2 = plat->capabilities2;
1545 1571
1572 if (variant->busy_detect) {
1573 mmci_ops.card_busy = mmci_card_busy;
1574 mmci_write_datactrlreg(host, MCI_ST_DPSM_BUSYMODE);
1575 mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
1576 mmc->max_busy_timeout = 0;
1577 }
1578
1579 mmc->ops = &mmci_ops;
1580
1546 /* We support these PM capabilities. */ 1581 /* We support these PM capabilities. */
1547 mmc->pm_caps = MMC_PM_KEEP_POWER; 1582 mmc->pm_caps = MMC_PM_KEEP_POWER;
1548 1583