]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/mmc/host/omap_hsmmc.c
hsmmc: Fix comments from Pierre
[linux-2.6-omap-h63xx.git] / drivers / mmc / host / omap_hsmmc.c
index f4b7c30615311963402c5f7c527b146f121d2731..59c594615da38fed7dcca4146d48d8d3da72ed14 100644 (file)
 #define OMAP_MMC_DATADIR_WRITE 2
 #define MMC_TIMEOUT_MS         20
 #define OMAP_MMC_MASTER_CLOCK  96000000
-#define DRIVER_NAME            "mmci-omap"
+#define DRIVER_NAME            "mmci-omap-hs"
 
 /*
  * One controller can have multiple slots, like on some omap boards using
@@ -192,6 +192,11 @@ static void mmc_omap_idle_timer(unsigned long data)
        mmc_omap_fclk_state(host, OFF);
 }
 
+static void mmc_omap_fclk_lazy_disable(struct mmc_omap_host *host)
+{
+       mod_timer(&host->idle_timer, jiffies + IDLE_TIMEOUT);
+}
+
 /*
  * Stop clock to the card
  */
@@ -289,9 +294,10 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
 
        /*
         * Unlike OMAP1 controller, the cmdtype does not seem to be based on
-        * ac, bc, adtc, bcr. Only CMD12 needs a val of 0x3, rest 0x0.
+        * ac, bc, adtc, bcr. Only commands ending an open ended transfer need
+        * a val of 0x3, rest 0x0.
         */
-       if (cmd->opcode == 12)
+       if (cmd == host->mrq->stop)
                cmdtype = 0x3;
 
        cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22);
@@ -332,7 +338,7 @@ mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
 
        if (!data->stop) {
                host->mrq = NULL;
-               mod_timer(&host->idle_timer, jiffies + IDLE_TIMEOUT);
+               mmc_omap_fclk_lazy_disable(host);
                mmc_request_done(host->mmc, data->mrq);
                return;
        }
@@ -361,7 +367,7 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
        }
        if (host->data == NULL || cmd->error) {
                host->mrq = NULL;
-               mod_timer(&host->idle_timer, jiffies + IDLE_TIMEOUT);
+               mmc_omap_fclk_lazy_disable(host);
                mmc_request_done(host->mmc, cmd->mrq);
        }
 }
@@ -529,10 +535,13 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd)
         * Only MMC1 supports 3.0V.  MMC2 will not function if SDVS30 is
         * set in HCTL.
         */
-       if (host->id == OMAP_MMC1_DEVID && (((1 << vdd) == MMC_VDD_32_33) ||
-                               ((1 << vdd) == MMC_VDD_33_34)))
-               reg_val |= SDVS30;
-       if ((1 << vdd) == MMC_VDD_165_195)
+       if (host->id == OMAP_MMC1_DEVID) {
+               if (((1 << vdd) == MMC_VDD_32_33) ||
+                   ((1 << vdd) == MMC_VDD_33_34))
+                       reg_val |= SDVS30;
+               else if ((1 << vdd) == MMC_VDD_165_195)
+                       reg_val |= SDVS18;
+       } else
                reg_val |= SDVS18;
 
        OMAP_HSMMC_WRITE(host->base, HCTL, reg_val);
@@ -574,7 +583,7 @@ static void mmc_omap_detect(struct work_struct *work)
                while (OMAP_HSMMC_READ(host->base, SYSCTL) & SRD) ;
                mmc_detect_change(host->mmc, (HZ * 50) / 1000);
        }
-       mod_timer(&host->idle_timer, jiffies + IDLE_TIMEOUT);
+       mmc_omap_fclk_lazy_disable(host);
 }
 
 /*
@@ -872,10 +881,7 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                OMAP_HSMMC_WRITE(host->base, CON,
                                OMAP_HSMMC_READ(host->base, CON) | OD);
 
-       if (ios->power_mode == MMC_POWER_OFF)
-               mmc_omap_fclk_state(host, OFF);
-       else
-               mod_timer(&host->idle_timer, jiffies + IDLE_TIMEOUT);
+       mmc_omap_fclk_lazy_disable(host);
 }
 
 static int omap_hsmmc_get_cd(struct mmc_host *mmc)
@@ -998,7 +1004,7 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
         * MMC can still work without debounce clock.
         */
        if (IS_ERR(host->dbclk))
-               dev_dbg(mmc_dev(host->mmc), "Failed to get debounce clock\n");
+               dev_warn(mmc_dev(host->mmc), "Failed to get debounce clock\n");
        else
                if (clk_enable(host->dbclk) != 0)
                        dev_dbg(mmc_dev(host->mmc), "Enabling debounce"
@@ -1090,7 +1096,7 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
                if (ret < 0)
                        goto err_cover_switch;
        }
-       mod_timer(&host->idle_timer, jiffies + IDLE_TIMEOUT);
+       mmc_omap_fclk_lazy_disable(host);
 
        return 0;
 
@@ -1126,26 +1132,7 @@ static int omap_mmc_remove(struct platform_device *pdev)
 {
        struct mmc_omap_host *host = platform_get_drvdata(pdev);
        struct resource *res;
-       u16 vdd = 0;
-
-       if (host) {
-               mmc_omap_fclk_state(host, ON);
-               if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
-                       /*
-                        * Set the vdd back to 3V,
-                        * applicable for dual volt support.
-                        */
-                       vdd = fls(host->mmc->ocr_avail) - 1;
-                       if (omap_mmc_switch_opcond(host, vdd) != 0)
-                               host->mmc->ios.vdd = vdd;
-               }
-       }
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res)
-               release_mem_region(res->start, res->end - res->start + 1);
-
-       platform_set_drvdata(pdev, NULL);
        if (host) {
                mmc_remove_host(host->mmc);
                if (host->pdata->cleanup)
@@ -1168,6 +1155,11 @@ static int omap_mmc_remove(struct platform_device *pdev)
                iounmap(host->base);
        }
 
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res)
+               release_mem_region(res->start, res->end - res->start + 1);
+       platform_set_drvdata(pdev, NULL);
+
        return 0;
 }
 
@@ -1181,12 +1173,11 @@ static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state)
                return 0;
 
        if (host) {
-               mmc_omap_fclk_state(host, ON);
-
                ret = mmc_suspend_host(host->mmc, state);
                if (ret == 0) {
                        host->suspended = 1;
 
+                       mmc_omap_fclk_state(host, ON);
                        OMAP_HSMMC_WRITE(host->base, ISE, 0);
                        OMAP_HSMMC_WRITE(host->base, IE, 0);
 
@@ -1198,19 +1189,8 @@ static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state)
                                                " level suspend\n");
                        }
 
-                       if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
-                               u32 hctl = OMAP_HSMMC_READ(host->base, HCTL) &
-                                       SDVSCLR;
-
-                               if (host->id == OMAP_MMC1_DEVID)
-                                       hctl |= SDVS30;
-                               else
-                                       hctl |= SDVS18;
-
-                               OMAP_HSMMC_WRITE(host->base, HCTL, hctl);
-                               OMAP_HSMMC_WRITE(host->base, HCTL, hctl | SDBP);
-                       }
-
+                       OMAP_HSMMC_WRITE(host->base, HCTL,
+                                        OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
                        mmc_omap_fclk_state(host, OFF);
                        clk_disable(host->iclk);
                        clk_disable(host->dbclk);
@@ -1230,7 +1210,7 @@ static int omap_mmc_resume(struct platform_device *pdev)
                return 0;
 
        if (host) {
-
+               int i;
                if (mmc_omap_fclk_state(host, ON) != 0)
                        goto clk_en_err;
 
@@ -1245,6 +1225,13 @@ static int omap_mmc_resume(struct platform_device *pdev)
                        dev_dbg(mmc_dev(host->mmc),
                                        "Enabling debounce clk failed\n");
 
+               OMAP_HSMMC_WRITE(host->base, HCTL,
+                                OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+
+               for (i = 0; i < 100; i++)
+                       if (OMAP_HSMMC_READ(host->base, HCTL) & SDBP)
+                               break;
+
                if (host->pdata->resume) {
                        ret = host->pdata->resume(&pdev->dev, host->slot_id);
                        if (ret)
@@ -1257,7 +1244,7 @@ static int omap_mmc_resume(struct platform_device *pdev)
                if (ret == 0)
                        host->suspended = 0;
 
-               mod_timer(&host->idle_timer, jiffies + IDLE_TIMEOUT);
+               mmc_omap_fclk_lazy_disable(host);
        }
 
        return ret;