aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2008-07-24 19:09:08 -0400
committerPierre Ossman <drzeus@drzeus.cx>2008-10-12 05:04:27 -0400
commite809517f6fa5803a5a1cd56026f0e2190fc13d5c (patch)
treec53f47a5e3704e7a4012e7dd26c6ce34333bc923 /drivers/mmc/host/sdhci.c
parent3fa8749e584b55f1180411ab1b51117190bac1e5 (diff)
sdhci: let the controller wait for busy state to end
The sdhci controllers can interrupt us when the busy state from the card has ended, saving CPU cycles and power. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index e3a8133560a2..ef461274397b 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1266,9 +1266,31 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
1266 SDHCI_INT_INDEX)) 1266 SDHCI_INT_INDEX))
1267 host->cmd->error = -EILSEQ; 1267 host->cmd->error = -EILSEQ;
1268 1268
1269 if (host->cmd->error) 1269 if (host->cmd->error) {
1270 tasklet_schedule(&host->finish_tasklet); 1270 tasklet_schedule(&host->finish_tasklet);
1271 else if (intmask & SDHCI_INT_RESPONSE) 1271 return;
1272 }
1273
1274 /*
1275 * The host can send and interrupt when the busy state has
1276 * ended, allowing us to wait without wasting CPU cycles.
1277 * Unfortunately this is overloaded on the "data complete"
1278 * interrupt, so we need to take some care when handling
1279 * it.
1280 *
1281 * Note: The 1.0 specification is a bit ambiguous about this
1282 * feature so there might be some problems with older
1283 * controllers.
1284 */
1285 if (host->cmd->flags & MMC_RSP_BUSY) {
1286 if (host->cmd->data)
1287 DBG("Cannot wait for busy signal when also "
1288 "doing a data transfer");
1289 else
1290 return;
1291 }
1292
1293 if (intmask & SDHCI_INT_RESPONSE)
1272 sdhci_finish_command(host); 1294 sdhci_finish_command(host);
1273} 1295}
1274 1296
@@ -1278,11 +1300,16 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
1278 1300
1279 if (!host->data) { 1301 if (!host->data) {
1280 /* 1302 /*
1281 * A data end interrupt is sent together with the response 1303 * The "data complete" interrupt is also used to
1282 * for the stop command. 1304 * indicate that a busy state has ended. See comment
1305 * above in sdhci_cmd_irq().
1283 */ 1306 */
1284 if (intmask & SDHCI_INT_DATA_END) 1307 if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
1285 return; 1308 if (intmask & SDHCI_INT_DATA_END) {
1309 sdhci_finish_command(host);
1310 return;
1311 }
1312 }
1286 1313
1287 printk(KERN_ERR "%s: Got data interrupt 0x%08x even " 1314 printk(KERN_ERR "%s: Got data interrupt 0x%08x even "
1288 "though no data operation was in progress.\n", 1315 "though no data operation was in progress.\n",