@@ -1007,6 +1007,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
mod_timer(&host->timer, jiffies + 10 * HZ);
host->cmd = cmd;
+ host->busy_handle = 0;
sdhci_prepare_data(host, cmd);
@@ -2282,11 +2283,21 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
if (host->cmd->data)
DBG("Cannot wait for busy signal when also "
"doing a data transfer");
- else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ))
+ else if (host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) {
+ /*
+ * The controller does not support the end-of-busy IRQ,
+ * fall through and take the SDHCI_INT_RESPONSE
+ */
+ } else if (host->busy_handle == 0) {
+ /* Mark that command complete before busy is ended */
+ host->busy_handle = 1;
return;
-
- /* The controller does not support the end-of-busy IRQ,
- * fall through and take the SDHCI_INT_RESPONSE */
+ } else {
+ /*
+ * We already received end-of-busy IRQ,
+ * process commnad now.
+ */
+ }
}
if (intmask & SDHCI_INT_RESPONSE)
@@ -2346,7 +2357,15 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
*/
if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
if (intmask & SDHCI_INT_DATA_END) {
- sdhci_finish_command(host);
+ /*
+ * Some cards handle busy-end interrupt
+ * before the command completed, so make
+ * sure we do things in the proper order.
+ */
+ if (host->busy_handle)
+ sdhci_finish_command(host);
+ else
+ host->busy_handle = 1;
return;
}
}
@@ -150,6 +150,7 @@ struct sdhci_host {
struct mmc_command *cmd; /* Current command */
struct mmc_data *data; /* Current data request */
unsigned int data_early:1; /* Data finished before cmd */
+ unsigned int busy_handle:1; /* Handling the order of Busy-end */
struct sg_mapping_iter sg_miter; /* SG state for PIO */
unsigned int blocks; /* remaining PIO blocks */