mmc: omap_hsmmc: consolidate error report handling of HSMMC IRQ
[deliverable/linux.git] / drivers / mmc / host / omap_hsmmc.c
index da4f5a73a3247715a5b28c42739f2c8976885482..9afdd202b8735bf5e36509c1952f9f0e8a86d7be 100644 (file)
@@ -44,7 +44,6 @@
 #include <plat/cpu.h>
 
 /* OMAP HSMMC Host Controller Registers */
-#define OMAP_HSMMC_SYSCONFIG   0x0010
 #define OMAP_HSMMC_SYSSTATUS   0x0014
 #define OMAP_HSMMC_CON         0x002C
 #define OMAP_HSMMC_BLK         0x0104
@@ -576,21 +575,8 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
        if (host->context_loss == context_loss)
                return 1;
 
-       /* Wait for hardware reset */
-       timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
-       while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
-               && time_before(jiffies, timeout))
-               ;
-
-       /* Do software reset */
-       OMAP_HSMMC_WRITE(host->base, SYSCONFIG, SOFTRESET);
-       timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
-       while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
-               && time_before(jiffies, timeout))
-               ;
-
-       OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
-                       OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+       if (!OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE)
+               return 1;
 
        if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
                if (host->power_mode != MMC_POWER_OFF &&
@@ -978,72 +964,40 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
                        __func__);
 }
 
+static void hsmmc_command_incomplete(struct omap_hsmmc_host *host, int err)
+{
+       omap_hsmmc_reset_controller_fsm(host, SRC);
+       host->cmd->error = err;
+
+       if (host->data) {
+               omap_hsmmc_reset_controller_fsm(host, SRD);
+               omap_hsmmc_dma_cleanup(host, err);
+       }
+
+}
+
 static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
 {
        struct mmc_data *data;
        int end_cmd = 0, end_trans = 0;
 
-       if (!host->req_in_progress) {
-               do {
-                       OMAP_HSMMC_WRITE(host->base, STAT, status);
-                       /* Flush posted write */
-                       status = OMAP_HSMMC_READ(host->base, STAT);
-               } while (status & INT_EN_MASK);
-               return;
-       }
-
        data = host->data;
        dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
 
        if (status & ERR) {
                omap_hsmmc_dbg_report_irq(host, status);
-               if ((status & CMD_TIMEOUT) ||
-                       (status & CMD_CRC)) {
-                       if (host->cmd) {
-                               if (status & CMD_TIMEOUT) {
-                                       omap_hsmmc_reset_controller_fsm(host,
-                                                                       SRC);
-                                       host->cmd->error = -ETIMEDOUT;
-                               } else {
-                                       host->cmd->error = -EILSEQ;
-                               }
-                               end_cmd = 1;
-                       }
-                       if (host->data || host->response_busy) {
-                               if (host->data)
-                                       omap_hsmmc_dma_cleanup(host,
-                                                               -ETIMEDOUT);
-                               host->response_busy = 0;
-                               omap_hsmmc_reset_controller_fsm(host, SRD);
-                       }
-               }
-               if ((status & DATA_TIMEOUT) ||
-                       (status & DATA_CRC)) {
-                       if (host->data || host->response_busy) {
-                               int err = (status & DATA_TIMEOUT) ?
-                                               -ETIMEDOUT : -EILSEQ;
-
-                               if (host->data)
-                                       omap_hsmmc_dma_cleanup(host, err);
-                               else
-                                       host->mrq->cmd->error = err;
-                               host->response_busy = 0;
-                               omap_hsmmc_reset_controller_fsm(host, SRD);
-                               end_trans = 1;
-                       }
-               }
-               if (status & CARD_ERR) {
-                       dev_dbg(mmc_dev(host->mmc),
-                               "Ignoring card err CMD%d\n", host->cmd->opcode);
-                       if (host->cmd)
-                               end_cmd = 1;
-                       if (host->data)
-                               end_trans = 1;
+               if (status & (CMD_TIMEOUT | DATA_TIMEOUT))
+                       hsmmc_command_incomplete(host, -ETIMEDOUT);
+               else if (status & (CMD_CRC | DATA_CRC))
+                       hsmmc_command_incomplete(host, -EILSEQ);
+
+               end_cmd = 1;
+               if (host->data || host->response_busy) {
+                       end_trans = 1;
+                       host->response_busy = 0;
                }
        }
 
-       OMAP_HSMMC_WRITE(host->base, STAT, status);
-
        if (end_cmd || ((status & CC) && host->cmd))
                omap_hsmmc_cmd_done(host, host->cmd);
        if ((end_trans || (status & TC)) && host->mrq)
@@ -1059,11 +1013,13 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
        int status;
 
        status = OMAP_HSMMC_READ(host->base, STAT);
-       do {
+       while (status & INT_EN_MASK && host->req_in_progress) {
                omap_hsmmc_do_irq(host, status);
+
                /* Flush posted write */
+               OMAP_HSMMC_WRITE(host->base, STAT, status);
                status = OMAP_HSMMC_READ(host->base, STAT);
-       } while (status & INT_EN_MASK);
+       }
 
        return IRQ_HANDLED;
 }
@@ -1593,10 +1549,6 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host)
        value = OMAP_HSMMC_READ(host->base, CAPA);
        OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
 
-       /* Set the controller to AUTO IDLE mode */
-       value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
-       OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
-
        /* Set SD bus power bit */
        set_sd_bus_power(host);
 }
@@ -1654,8 +1606,6 @@ static int omap_hsmmc_regs_show(struct seq_file *s, void *data)
 
        pm_runtime_get_sync(host->dev);
 
-       seq_printf(s, "SYSCONFIG:\t0x%08x\n",
-                       OMAP_HSMMC_READ(host->base, SYSCONFIG));
        seq_printf(s, "CON:\t\t0x%08x\n",
                        OMAP_HSMMC_READ(host->base, CON));
        seq_printf(s, "HCTL:\t\t0x%08x\n",
This page took 0.037684 seconds and 5 git commands to generate.