]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/mmc/host/omap_hsmmc.c
omap_hsmmc: Fix response type for busy after response
[linux-2.6-omap-h63xx.git] / drivers / mmc / host / omap_hsmmc.c
index 5ff2ca22beea1908963f5eb259e3cbb4c04add68..1f84bd4a3b2796840dc42e8ab3ff866449cff376 100644 (file)
@@ -150,6 +150,7 @@ struct mmc_omap_host {
        int                     initstr;
        int                     slot_id;
        int                     dbclk_enabled;
+       int                     response_busy;
        struct  omap_mmc_platform_data  *pdata;
 };
 
@@ -244,10 +245,14 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
        OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
        OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
 
+       host->response_busy = 0;
        if (cmd->flags & MMC_RSP_PRESENT) {
                if (cmd->flags & MMC_RSP_136)
                        resptype = 1;
-               else
+               else if (cmd->flags & MMC_RSP_BUSY) {
+                       resptype = 3;
+                       host->response_busy = 1;
+               } else
                        resptype = 2;
        }
 
@@ -282,6 +287,15 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
 static void
 mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
 {
+       if (!data) {
+               struct mmc_request *mrq = host->mrq;
+
+               host->mrq = NULL;
+               mmc_omap_fclk_lazy_disable(host);
+               mmc_request_done(host->mmc, mrq);
+               return;
+       }
+
        host->data = NULL;
 
        if (host->use_dma && host->dma_ch != -1)
@@ -323,7 +337,7 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
                        cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);
                }
        }
-       if (host->data == NULL || cmd->error) {
+       if ((host->data == NULL && !host->response_busy) || cmd->error) {
                host->mrq = NULL;
                mmc_request_done(host->mmc, cmd->mrq);
        }
@@ -413,7 +427,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
        struct mmc_data *data;
        int end_cmd = 0, end_trans = 0, status;
 
-       if (host->cmd == NULL && host->data == NULL) {
+       if (host->mrq == NULL) {
                OMAP_HSMMC_WRITE(host->base, STAT,
                        OMAP_HSMMC_READ(host->base, STAT));
                return IRQ_HANDLED;
@@ -438,18 +452,24 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
                                }
                                end_cmd = 1;
                        }
-                       if (host->data) {
-                               mmc_dma_cleanup(host, -ETIMEDOUT);
+                       if (host->data || host->response_busy) {
+                               if (host->data)
+                                       mmc_dma_cleanup(host, -ETIMEDOUT);
+                               host->response_busy = 0;
                                mmc_omap_reset_controller_fsm(host, SRD);
                        }
                }
                if ((status & DATA_TIMEOUT) ||
                        (status & DATA_CRC)) {
-                       if (host->data) {
-                               if (status & DATA_TIMEOUT)
-                                       mmc_dma_cleanup(host, -ETIMEDOUT);
+                       if (host->data || host->response_busy) {
+                               int err = (status & DATA_TIMEOUT) ?
+                                               -ETIMEDOUT : -EILSEQ;
+
+                               if (host->data)
+                                       mmc_dma_cleanup(host, err);
                                else
-                                       mmc_dma_cleanup(host, -EILSEQ);
+                                       host->mrq->cmd->error = err;
+                               host->response_busy = 0;
                                mmc_omap_reset_controller_fsm(host, SRD);
                                end_trans = 1;
                        }