|
@@ -1785,7 +1785,7 @@ static inline struct omap_mmc_platform_data
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-static int __init omap_hsmmc_probe(struct platform_device *pdev)
|
|
|
+static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
|
|
|
struct mmc_host *mmc;
|
|
@@ -1818,8 +1818,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
|
|
|
if (res == NULL || irq < 0)
|
|
|
return -ENXIO;
|
|
|
|
|
|
- res->start += pdata->reg_offset;
|
|
|
- res->end += pdata->reg_offset;
|
|
|
res = request_mem_region(res->start, resource_size(res), pdev->name);
|
|
|
if (res == NULL)
|
|
|
return -EBUSY;
|
|
@@ -1843,7 +1841,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
|
|
|
host->dma_ch = -1;
|
|
|
host->irq = irq;
|
|
|
host->slot_id = 0;
|
|
|
- host->mapbase = res->start;
|
|
|
+ host->mapbase = res->start + pdata->reg_offset;
|
|
|
host->base = ioremap(host->mapbase, SZ_4K);
|
|
|
host->power_mode = MMC_POWER_OFF;
|
|
|
host->next_data.cookie = 1;
|
|
@@ -1875,8 +1873,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
|
|
|
goto err1;
|
|
|
}
|
|
|
|
|
|
- omap_hsmmc_context_save(host);
|
|
|
-
|
|
|
if (host->pdata->controller_flags & OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) {
|
|
|
dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n");
|
|
|
mmc->caps2 |= MMC_CAP2_NO_MULTI_READ;
|
|
@@ -1887,6 +1883,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
|
|
|
pm_runtime_set_autosuspend_delay(host->dev, MMC_AUTOSUSPEND_DELAY);
|
|
|
pm_runtime_use_autosuspend(host->dev);
|
|
|
|
|
|
+ omap_hsmmc_context_save(host);
|
|
|
+
|
|
|
if (cpu_is_omap2430()) {
|
|
|
host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
|
|
|
/*
|
|
@@ -2018,8 +2016,7 @@ err_reg:
|
|
|
err_irq_cd_init:
|
|
|
free_irq(host->irq, host);
|
|
|
err_irq:
|
|
|
- pm_runtime_mark_last_busy(host->dev);
|
|
|
- pm_runtime_put_autosuspend(host->dev);
|
|
|
+ pm_runtime_put_sync(host->dev);
|
|
|
pm_runtime_disable(host->dev);
|
|
|
clk_put(host->fclk);
|
|
|
if (host->got_dbclk) {
|
|
@@ -2037,35 +2034,33 @@ err:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int omap_hsmmc_remove(struct platform_device *pdev)
|
|
|
+static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
|
|
|
{
|
|
|
struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
|
|
|
struct resource *res;
|
|
|
|
|
|
- if (host) {
|
|
|
- pm_runtime_get_sync(host->dev);
|
|
|
- mmc_remove_host(host->mmc);
|
|
|
- if (host->use_reg)
|
|
|
- omap_hsmmc_reg_put(host);
|
|
|
- if (host->pdata->cleanup)
|
|
|
- host->pdata->cleanup(&pdev->dev);
|
|
|
- free_irq(host->irq, host);
|
|
|
- if (mmc_slot(host).card_detect_irq)
|
|
|
- free_irq(mmc_slot(host).card_detect_irq, host);
|
|
|
-
|
|
|
- pm_runtime_put_sync(host->dev);
|
|
|
- pm_runtime_disable(host->dev);
|
|
|
- clk_put(host->fclk);
|
|
|
- if (host->got_dbclk) {
|
|
|
- clk_disable(host->dbclk);
|
|
|
- clk_put(host->dbclk);
|
|
|
- }
|
|
|
+ pm_runtime_get_sync(host->dev);
|
|
|
+ mmc_remove_host(host->mmc);
|
|
|
+ if (host->use_reg)
|
|
|
+ omap_hsmmc_reg_put(host);
|
|
|
+ if (host->pdata->cleanup)
|
|
|
+ host->pdata->cleanup(&pdev->dev);
|
|
|
+ free_irq(host->irq, host);
|
|
|
+ if (mmc_slot(host).card_detect_irq)
|
|
|
+ free_irq(mmc_slot(host).card_detect_irq, host);
|
|
|
|
|
|
- mmc_free_host(host->mmc);
|
|
|
- iounmap(host->base);
|
|
|
- omap_hsmmc_gpio_free(pdev->dev.platform_data);
|
|
|
+ pm_runtime_put_sync(host->dev);
|
|
|
+ pm_runtime_disable(host->dev);
|
|
|
+ clk_put(host->fclk);
|
|
|
+ if (host->got_dbclk) {
|
|
|
+ clk_disable(host->dbclk);
|
|
|
+ clk_put(host->dbclk);
|
|
|
}
|
|
|
|
|
|
+ mmc_free_host(host->mmc);
|
|
|
+ iounmap(host->base);
|
|
|
+ omap_hsmmc_gpio_free(pdev->dev.platform_data);
|
|
|
+
|
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
if (res)
|
|
|
release_mem_region(res->start, resource_size(res));
|
|
@@ -2078,49 +2073,45 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
|
|
|
static int omap_hsmmc_suspend(struct device *dev)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
- struct platform_device *pdev = to_platform_device(dev);
|
|
|
- struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
|
|
|
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
|
|
|
|
|
|
- if (host && host->suspended)
|
|
|
+ if (!host)
|
|
|
return 0;
|
|
|
|
|
|
- if (host) {
|
|
|
- pm_runtime_get_sync(host->dev);
|
|
|
- host->suspended = 1;
|
|
|
- if (host->pdata->suspend) {
|
|
|
- ret = host->pdata->suspend(&pdev->dev,
|
|
|
- host->slot_id);
|
|
|
- if (ret) {
|
|
|
- dev_dbg(mmc_dev(host->mmc),
|
|
|
- "Unable to handle MMC board"
|
|
|
- " level suspend\n");
|
|
|
- host->suspended = 0;
|
|
|
- return ret;
|
|
|
- }
|
|
|
- }
|
|
|
- ret = mmc_suspend_host(host->mmc);
|
|
|
+ if (host && host->suspended)
|
|
|
+ return 0;
|
|
|
|
|
|
+ pm_runtime_get_sync(host->dev);
|
|
|
+ host->suspended = 1;
|
|
|
+ if (host->pdata->suspend) {
|
|
|
+ ret = host->pdata->suspend(dev, host->slot_id);
|
|
|
if (ret) {
|
|
|
+ dev_dbg(dev, "Unable to handle MMC board"
|
|
|
+ " level suspend\n");
|
|
|
host->suspended = 0;
|
|
|
- if (host->pdata->resume) {
|
|
|
- ret = host->pdata->resume(&pdev->dev,
|
|
|
- host->slot_id);
|
|
|
- if (ret)
|
|
|
- dev_dbg(mmc_dev(host->mmc),
|
|
|
- "Unmask interrupt failed\n");
|
|
|
- }
|
|
|
- goto err;
|
|
|
+ return ret;
|
|
|
}
|
|
|
+ }
|
|
|
+ ret = mmc_suspend_host(host->mmc);
|
|
|
|
|
|
- if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) {
|
|
|
- omap_hsmmc_disable_irq(host);
|
|
|
- OMAP_HSMMC_WRITE(host->base, HCTL,
|
|
|
- OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
|
|
|
+ if (ret) {
|
|
|
+ host->suspended = 0;
|
|
|
+ if (host->pdata->resume) {
|
|
|
+ ret = host->pdata->resume(dev, host->slot_id);
|
|
|
+ if (ret)
|
|
|
+ dev_dbg(dev, "Unmask interrupt failed\n");
|
|
|
}
|
|
|
- if (host->got_dbclk)
|
|
|
- clk_disable(host->dbclk);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
|
|
|
+ if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) {
|
|
|
+ omap_hsmmc_disable_irq(host);
|
|
|
+ OMAP_HSMMC_WRITE(host->base, HCTL,
|
|
|
+ OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
|
|
|
}
|
|
|
+
|
|
|
+ if (host->got_dbclk)
|
|
|
+ clk_disable(host->dbclk);
|
|
|
err:
|
|
|
pm_runtime_put_sync(host->dev);
|
|
|
return ret;
|
|
@@ -2130,38 +2121,37 @@ err:
|
|
|
static int omap_hsmmc_resume(struct device *dev)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
- struct platform_device *pdev = to_platform_device(dev);
|
|
|
- struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
|
|
|
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
|
|
|
+
|
|
|
+ if (!host)
|
|
|
+ return 0;
|
|
|
|
|
|
if (host && !host->suspended)
|
|
|
return 0;
|
|
|
|
|
|
- if (host) {
|
|
|
- pm_runtime_get_sync(host->dev);
|
|
|
+ pm_runtime_get_sync(host->dev);
|
|
|
|
|
|
- if (host->got_dbclk)
|
|
|
- clk_enable(host->dbclk);
|
|
|
+ if (host->got_dbclk)
|
|
|
+ clk_enable(host->dbclk);
|
|
|
|
|
|
- if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
|
|
|
- omap_hsmmc_conf_bus_power(host);
|
|
|
+ if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
|
|
|
+ omap_hsmmc_conf_bus_power(host);
|
|
|
|
|
|
- if (host->pdata->resume) {
|
|
|
- ret = host->pdata->resume(&pdev->dev, host->slot_id);
|
|
|
- if (ret)
|
|
|
- dev_dbg(mmc_dev(host->mmc),
|
|
|
- "Unmask interrupt failed\n");
|
|
|
- }
|
|
|
+ if (host->pdata->resume) {
|
|
|
+ ret = host->pdata->resume(dev, host->slot_id);
|
|
|
+ if (ret)
|
|
|
+ dev_dbg(dev, "Unmask interrupt failed\n");
|
|
|
+ }
|
|
|
|
|
|
- omap_hsmmc_protect_card(host);
|
|
|
+ omap_hsmmc_protect_card(host);
|
|
|
|
|
|
- /* Notify the core to resume the host */
|
|
|
- ret = mmc_resume_host(host->mmc);
|
|
|
- if (ret == 0)
|
|
|
- host->suspended = 0;
|
|
|
+ /* Notify the core to resume the host */
|
|
|
+ ret = mmc_resume_host(host->mmc);
|
|
|
+ if (ret == 0)
|
|
|
+ host->suspended = 0;
|
|
|
|
|
|
- pm_runtime_mark_last_busy(host->dev);
|
|
|
- pm_runtime_put_autosuspend(host->dev);
|
|
|
- }
|
|
|
+ pm_runtime_mark_last_busy(host->dev);
|
|
|
+ pm_runtime_put_autosuspend(host->dev);
|
|
|
|
|
|
return ret;
|
|
|
|
|
@@ -2178,7 +2168,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev)
|
|
|
|
|
|
host = platform_get_drvdata(to_platform_device(dev));
|
|
|
omap_hsmmc_context_save(host);
|
|
|
- dev_dbg(mmc_dev(host->mmc), "disabled\n");
|
|
|
+ dev_dbg(dev, "disabled\n");
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -2189,7 +2179,7 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
|
|
|
|
|
|
host = platform_get_drvdata(to_platform_device(dev));
|
|
|
omap_hsmmc_context_restore(host);
|
|
|
- dev_dbg(mmc_dev(host->mmc), "enabled\n");
|
|
|
+ dev_dbg(dev, "enabled\n");
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -2202,7 +2192,8 @@ static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
|
|
|
};
|
|
|
|
|
|
static struct platform_driver omap_hsmmc_driver = {
|
|
|
- .remove = omap_hsmmc_remove,
|
|
|
+ .probe = omap_hsmmc_probe,
|
|
|
+ .remove = __devexit_p(omap_hsmmc_remove),
|
|
|
.driver = {
|
|
|
.name = DRIVER_NAME,
|
|
|
.owner = THIS_MODULE,
|
|
@@ -2211,21 +2202,7 @@ static struct platform_driver omap_hsmmc_driver = {
|
|
|
},
|
|
|
};
|
|
|
|
|
|
-static int __init omap_hsmmc_init(void)
|
|
|
-{
|
|
|
- /* Register the MMC driver */
|
|
|
- return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe);
|
|
|
-}
|
|
|
-
|
|
|
-static void __exit omap_hsmmc_cleanup(void)
|
|
|
-{
|
|
|
- /* Unregister MMC driver */
|
|
|
- platform_driver_unregister(&omap_hsmmc_driver);
|
|
|
-}
|
|
|
-
|
|
|
-module_init(omap_hsmmc_init);
|
|
|
-module_exit(omap_hsmmc_cleanup);
|
|
|
-
|
|
|
+module_platform_driver(omap_hsmmc_driver);
|
|
|
MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver");
|
|
|
MODULE_LICENSE("GPL");
|
|
|
MODULE_ALIAS("platform:" DRIVER_NAME);
|