For some sdio cards, clock need to alwasys on during working. So pm_runtime need to be disabled for this case. Signed-off-by: Kevin Liu <kliu5@xxxxxxxxxxx> --- drivers/mmc/host/sdhci-pxav3.c | 58 ++++++++++++++++++++++++++-------------- include/linux/mmc/sdhci.h | 1 + 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index a0cdbc5..24fc327 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -300,18 +300,23 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) sdhci_get_of_property(pdev); - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS); - pm_runtime_use_autosuspend(&pdev->dev); - pm_suspend_ignore_children(&pdev->dev, 1); - pm_runtime_get_noresume(&pdev->dev); + if (!(host->quirks2 & SDHCI_QUIRK2_PM_RUNTIME_BROKEN)) { + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, + PXAV3_RPM_DELAY_MS); + pm_runtime_use_autosuspend(&pdev->dev); + pm_suspend_ignore_children(&pdev->dev, 1); + pm_runtime_get_noresume(&pdev->dev); + } ret = sdhci_add_host(host); if (ret) { dev_err(&pdev->dev, "failed to add host\n"); - pm_runtime_forbid(&pdev->dev); - pm_runtime_disable(&pdev->dev); + if (!(host->quirks2 & SDHCI_QUIRK2_PM_RUNTIME_BROKEN)) { + pm_runtime_forbid(&pdev->dev); + pm_runtime_disable(&pdev->dev); + } goto err_add_host; } @@ -324,7 +329,8 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); } - pm_runtime_put_autosuspend(&pdev->dev); + if (!(host->quirks2 & SDHCI_QUIRK2_PM_RUNTIME_BROKEN)) + pm_runtime_put_autosuspend(&pdev->dev); return 0; @@ -344,9 +350,13 @@ static int sdhci_pxav3_remove(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pxa *pxa = pltfm_host->priv; - pm_runtime_get_sync(&pdev->dev); - sdhci_remove_host(host, 1); - pm_runtime_disable(&pdev->dev); + if (!(host->quirks2 & SDHCI_QUIRK2_PM_RUNTIME_BROKEN)) { + pm_runtime_get_sync(&pdev->dev); + sdhci_remove_host(host, 1); + pm_runtime_disable(&pdev->dev); + } else { + sdhci_remove_host(host, 1); + } clk_disable_unprepare(pltfm_host->clk); clk_put(pltfm_host->clk); @@ -365,10 +375,14 @@ static int sdhci_pxav3_suspend(struct device *dev) int ret; struct sdhci_host *host = dev_get_drvdata(dev); - pm_runtime_get_sync(dev); - ret = sdhci_suspend_host(host); - pm_runtime_mark_last_busy(dev); - pm_runtime_put_autosuspend(dev); + if (!(host->quirks2 & SDHCI_QUIRK2_PM_RUNTIME_BROKEN)) { + pm_runtime_get_sync(dev); + ret = sdhci_suspend_host(host); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + } else { + ret = sdhci_suspend_host(host); + } return ret; } @@ -378,10 +392,14 @@ static int sdhci_pxav3_resume(struct device *dev) int ret; struct sdhci_host *host = dev_get_drvdata(dev); - pm_runtime_get_sync(dev); - ret = sdhci_resume_host(host); - pm_runtime_mark_last_busy(dev); - pm_runtime_put_autosuspend(dev); + if (!(host->quirks2 & SDHCI_QUIRK2_PM_RUNTIME_BROKEN)) { + pm_runtime_get_sync(dev); + ret = sdhci_resume_host(host); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + } else { + ret = sdhci_resume_host(host); + } return ret; } diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index b838ffc..3fd6c8c 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -95,6 +95,7 @@ struct sdhci_host { /* The system physically doesn't support 1.8v, even if the host does */ #define SDHCI_QUIRK2_NO_1_8_V (1<<2) #define SDHCI_QUIRK2_PRESET_VALUE_BROKEN (1<<3) +#define SDHCI_QUIRK2_PM_RUNTIME_BROKEN (1<<4) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html