aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorChaithrika U S <chaithrika@ti.com>2010-05-26 17:41:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-27 12:12:39 -0400
commitbbce5802afc560c4a487afea3761b85fcb862fb3 (patch)
treea484a542fff37b412276da7be5d6a91d928cf0ad /drivers/mmc/host
parent06de845f72eeb169ea624f17396cd41d03384940 (diff)
davinci: mmc: updates to suspend/resume implementation
Improve the suspend and resume callbacks in DaVinci MMC host controller driver. Modify the reset status of the contorller and clock during suspend and resume. Also migrate the power management callbacks from platform driver to dev_pm_ops structure. Tested on DA850/OMAP-L138 EVM. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Chaithrika U S <chaithrika@ti.com> Acked-by: Kevin Hilman <khilman@deeprootsystems.com> Cc: Vipin Bhandari <vipin.bhandari@ti.com> Cc: Sudhakar Rajashekhara <sudhakar.raj@ti.com> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/davinci_mmc.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 56afe0a00f56..aae39125b8d7 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -171,6 +171,7 @@ struct mmc_davinci_host {
171#define DAVINCI_MMC_DATADIR_READ 1 171#define DAVINCI_MMC_DATADIR_READ 1
172#define DAVINCI_MMC_DATADIR_WRITE 2 172#define DAVINCI_MMC_DATADIR_WRITE 2
173 unsigned char data_dir; 173 unsigned char data_dir;
174 unsigned char suspended;
174 175
175 /* buffer is used during PIO of one scatterlist segment, and 176 /* buffer is used during PIO of one scatterlist segment, and
176 * is updated along with buffer_bytes_left. bytes_left applies 177 * is updated along with buffer_bytes_left. bytes_left applies
@@ -1332,32 +1333,66 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev)
1332} 1333}
1333 1334
1334#ifdef CONFIG_PM 1335#ifdef CONFIG_PM
1335static int davinci_mmcsd_suspend(struct platform_device *pdev, pm_message_t msg) 1336static int davinci_mmcsd_suspend(struct device *dev)
1336{ 1337{
1338 struct platform_device *pdev = to_platform_device(dev);
1337 struct mmc_davinci_host *host = platform_get_drvdata(pdev); 1339 struct mmc_davinci_host *host = platform_get_drvdata(pdev);
1340 struct pm_message msg = { PM_EVENT_SUSPEND };
1341 int ret;
1338 1342
1339 return mmc_suspend_host(host->mmc, msg); 1343 mmc_host_enable(host->mmc);
1344 ret = mmc_suspend_host(host->mmc, msg);
1345 if (!ret) {
1346 writel(0, host->base + DAVINCI_MMCIM);
1347 mmc_davinci_reset_ctrl(host, 1);
1348 mmc_host_disable(host->mmc);
1349 clk_disable(host->clk);
1350 host->suspended = 1;
1351 } else {
1352 host->suspended = 0;
1353 mmc_host_disable(host->mmc);
1354 }
1355
1356 return ret;
1340} 1357}
1341 1358
1342static int davinci_mmcsd_resume(struct platform_device *pdev) 1359static int davinci_mmcsd_resume(struct device *dev)
1343{ 1360{
1361 struct platform_device *pdev = to_platform_device(dev);
1344 struct mmc_davinci_host *host = platform_get_drvdata(pdev); 1362 struct mmc_davinci_host *host = platform_get_drvdata(pdev);
1363 int ret;
1345 1364
1346 return mmc_resume_host(host->mmc); 1365 if (!host->suspended)
1366 return 0;
1367
1368 clk_enable(host->clk);
1369 mmc_host_enable(host->mmc);
1370
1371 mmc_davinci_reset_ctrl(host, 0);
1372 ret = mmc_resume_host(host->mmc);
1373 if (!ret)
1374 host->suspended = 0;
1375
1376 return ret;
1347} 1377}
1378
1379static const struct dev_pm_ops davinci_mmcsd_pm = {
1380 .suspend = davinci_mmcsd_suspend,
1381 .resume = davinci_mmcsd_resume,
1382};
1383
1384#define davinci_mmcsd_pm_ops (&davinci_mmcsd_pm)
1348#else 1385#else
1349#define davinci_mmcsd_suspend NULL 1386#define davinci_mmcsd_pm_ops NULL
1350#define davinci_mmcsd_resume NULL
1351#endif 1387#endif
1352 1388
1353static struct platform_driver davinci_mmcsd_driver = { 1389static struct platform_driver davinci_mmcsd_driver = {
1354 .driver = { 1390 .driver = {
1355 .name = "davinci_mmc", 1391 .name = "davinci_mmc",
1356 .owner = THIS_MODULE, 1392 .owner = THIS_MODULE,
1393 .pm = davinci_mmcsd_pm_ops,
1357 }, 1394 },
1358 .remove = __exit_p(davinci_mmcsd_remove), 1395 .remove = __exit_p(davinci_mmcsd_remove),
1359 .suspend = davinci_mmcsd_suspend,
1360 .resume = davinci_mmcsd_resume,
1361}; 1396};
1362 1397
1363static int __init davinci_mmcsd_init(void) 1398static int __init davinci_mmcsd_init(void)