Skip to content

Commit f433e8a

Browse files
tmlindstorulf
authored andcommitted
mmc: sdhci-omap: Implement PM runtime functions
Implement PM runtime functions and enable autosuspend. Note that we save context in probe to avoid restoring invalid context on the first resume. For system suspend, we have the new PM runtime functions do most of the work. Signed-off-by: Tony Lindgren <tony@atomide.com> Link: https://lore.kernel.org/r/20211015104720.52240-5-tony@atomide.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 42b380b commit f433e8a

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

drivers/mmc/host/sdhci-omap.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,8 @@ static const struct soc_device_attribute sdhci_omap_soc_devices[] = {
12071207
}
12081208
};
12091209

1210+
static void sdhci_omap_context_save(struct sdhci_omap_host *omap_host);
1211+
12101212
static int sdhci_omap_probe(struct platform_device *pdev)
12111213
{
12121214
int ret;
@@ -1252,6 +1254,7 @@ static int sdhci_omap_probe(struct platform_device *pdev)
12521254
omap_host->timing = MMC_TIMING_LEGACY;
12531255
omap_host->flags = data->flags;
12541256
omap_host->omap_offset = data->omap_offset;
1257+
omap_host->con = -EINVAL; /* Prevent invalid restore on first resume */
12551258
host->ioaddr += offset;
12561259
host->mapbase = regs->start + offset;
12571260

@@ -1302,6 +1305,8 @@ static int sdhci_omap_probe(struct platform_device *pdev)
13021305
* SYSCONFIG register of omap devices. The callback will be invoked
13031306
* as part of pm_runtime_get_sync.
13041307
*/
1308+
pm_runtime_use_autosuspend(dev);
1309+
pm_runtime_set_autosuspend_delay(dev, 50);
13051310
pm_runtime_enable(dev);
13061311
ret = pm_runtime_resume_and_get(dev);
13071312
if (ret) {
@@ -1312,7 +1317,7 @@ static int sdhci_omap_probe(struct platform_device *pdev)
13121317
ret = sdhci_omap_set_capabilities(host);
13131318
if (ret) {
13141319
dev_err(dev, "failed to set system capabilities\n");
1315-
goto err_put_sync;
1320+
goto err_rpm_put;
13161321
}
13171322

13181323
host->mmc_host_ops.start_signal_voltage_switch =
@@ -1340,7 +1345,7 @@ static int sdhci_omap_probe(struct platform_device *pdev)
13401345

13411346
ret = sdhci_setup_host(host);
13421347
if (ret)
1343-
goto err_put_sync;
1348+
goto err_rpm_put;
13441349

13451350
ret = sdhci_omap_config_iodelay_pinctrl_state(omap_host);
13461351
if (ret)
@@ -1350,15 +1355,19 @@ static int sdhci_omap_probe(struct platform_device *pdev)
13501355
if (ret)
13511356
goto err_cleanup_host;
13521357

1358+
pm_runtime_mark_last_busy(dev);
1359+
pm_runtime_put_autosuspend(dev);
1360+
13531361
return 0;
13541362

13551363
err_cleanup_host:
13561364
sdhci_cleanup_host(host);
13571365

1358-
err_put_sync:
1359-
pm_runtime_put_sync(dev);
1360-
1366+
err_rpm_put:
1367+
pm_runtime_mark_last_busy(dev);
1368+
pm_runtime_put_autosuspend(dev);
13611369
err_rpm_disable:
1370+
pm_runtime_dont_use_autosuspend(dev);
13621371
pm_runtime_disable(dev);
13631372

13641373
err_pltfm_free:
@@ -1371,9 +1380,12 @@ static int sdhci_omap_remove(struct platform_device *pdev)
13711380
struct device *dev = &pdev->dev;
13721381
struct sdhci_host *host = platform_get_drvdata(pdev);
13731382

1383+
pm_runtime_get_sync(dev);
13741384
sdhci_remove_host(host, true);
1385+
pm_runtime_dont_use_autosuspend(dev);
13751386
pm_runtime_put_sync(dev);
1376-
pm_runtime_disable(dev);
1387+
/* Ensure device gets disabled despite userspace sysfs config */
1388+
pm_runtime_force_suspend(dev);
13771389
sdhci_pltfm_free(pdev);
13781390

13791391
return 0;
@@ -1402,42 +1414,44 @@ static void sdhci_omap_context_restore(struct sdhci_omap_host *omap_host)
14021414
sdhci_omap_writel(omap_host, SDHCI_OMAP_ISE, omap_host->ise);
14031415
}
14041416

1405-
static int __maybe_unused sdhci_omap_suspend(struct device *dev)
1417+
static int __maybe_unused sdhci_omap_runtime_suspend(struct device *dev)
14061418
{
14071419
struct sdhci_host *host = dev_get_drvdata(dev);
14081420
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
14091421
struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
14101422

1411-
sdhci_suspend_host(host);
1423+
sdhci_runtime_suspend_host(host);
14121424

14131425
sdhci_omap_context_save(omap_host);
14141426

14151427
pinctrl_pm_select_idle_state(dev);
14161428

1417-
pm_runtime_force_suspend(dev);
1418-
14191429
return 0;
14201430
}
14211431

1422-
static int __maybe_unused sdhci_omap_resume(struct device *dev)
1432+
static int __maybe_unused sdhci_omap_runtime_resume(struct device *dev)
14231433
{
14241434
struct sdhci_host *host = dev_get_drvdata(dev);
14251435
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
14261436
struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
14271437

1428-
pm_runtime_force_resume(dev);
1429-
14301438
pinctrl_pm_select_default_state(dev);
14311439

1432-
sdhci_omap_context_restore(omap_host);
1440+
if (omap_host->con != -EINVAL)
1441+
sdhci_omap_context_restore(omap_host);
14331442

1434-
sdhci_resume_host(host);
1443+
sdhci_runtime_resume_host(host, 0);
14351444

14361445
return 0;
14371446
}
14381447
#endif
1439-
static SIMPLE_DEV_PM_OPS(sdhci_omap_dev_pm_ops, sdhci_omap_suspend,
1440-
sdhci_omap_resume);
1448+
1449+
static const struct dev_pm_ops sdhci_omap_dev_pm_ops = {
1450+
SET_RUNTIME_PM_OPS(sdhci_omap_runtime_suspend,
1451+
sdhci_omap_runtime_resume, NULL)
1452+
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1453+
pm_runtime_force_resume)
1454+
};
14411455

14421456
static struct platform_driver sdhci_omap_driver = {
14431457
.probe = sdhci_omap_probe,

0 commit comments

Comments
 (0)