#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
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
*/
/*
* 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);
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;
}
}
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);
}
}
* 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);
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);
}
/*
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)
* 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"
if (ret < 0)
goto err_cover_switch;
}
- mod_timer(&host->idle_timer, jiffies + IDLE_TIMEOUT);
+ mmc_omap_fclk_lazy_disable(host);
return 0;
{
struct mmc_omap_host *host = platform_get_drvdata(pdev);
struct resource *res;
- u16 vdd = 0;
-
- 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)
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;
}
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);
" level suspend\n");
}
- if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- & SDVSCLR);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- | SDVS30);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, 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);
return 0;
if (host) {
-
+ int i;
if (mmc_omap_fclk_state(host, ON) != 0)
goto clk_en_err;
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)
if (ret == 0)
host->suspended = 0;
- mod_timer(&host->idle_timer, jiffies + IDLE_TIMEOUT);
+ mmc_omap_fclk_lazy_disable(host);
}
return ret;