static int tegra_sdhci_suspend(struct platform_device *pdev, pm_message_t state) { struct tegra_sdhci_host *host = platform_get_drvdata(pdev); int ret = 0; printk(KERN_INFO "%s (%s) ++ \n", __func__, mmc_hostname(host->sdhci->mmc)); if (time_before(jiffies, host->card_detection_time + msecs_to_jiffies(SD_TIME_GAP_FOR_SUSPEND))) { printk(KERN_INFO "%s: Prevent from going to suspend mode too soon \n", __func__); return -1; } if (host->irq_cd != -1) disable_irq(host->irq_cd); if (host->card_always_on && is_card_sdio(host->sdhci->mmc->card)) { int div = 0; u16 clk; unsigned int clock = 100000; if (device_may_wakeup(&pdev->dev)) { enable_irq_wake(host->sdhci->irq); } /* save interrupt status before suspending */ host->sdhci_ints = sdhci_readl(host->sdhci, SDHCI_INT_ENABLE); /* reduce host controller clk and card clk to 100 KHz */ tegra_sdhci_set_clock(host->sdhci, clock); sdhci_writew(host->sdhci, 0, SDHCI_CLOCK_CONTROL); if (host->sdhci->max_clk > clock) { div = 1 << (fls(host->sdhci->max_clk / clock) - 2); if (div > 128) div = 128; } clk = div << SDHCI_DIVIDER_SHIFT; clk |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_CARD_EN; sdhci_writew(host->sdhci, clk, SDHCI_CLOCK_CONTROL); return ret; } /* * Set disable_delay to zero * to disable mmc_schedule_delay_work * before suspend */ mmc_set_disable_delay(host->sdhci->mmc, 0); ret = sdhci_suspend_host(host->sdhci, state); if (ret) pr_err("%s: failed, error = %d\n", __func__, ret); tegra_sdhci_enable_clock(host, 0); printk(KERN_INFO "%s (%s) -- \n", __func__, mmc_hostname(host->sdhci->mmc)); return ret; }
static int tegra_sdhci_suspend(struct platform_device *pdev, pm_message_t state) { struct tegra_sdhci_host *host = platform_get_drvdata(pdev); int ret = 0; MMC_printk("%s:+", mmc_hostname(host->sdhci->mmc)); if ((host->card_always_on && is_card_sdio(host->sdhci->mmc->card)) || is_card_mmc(host->sdhci->mmc->card)){ int div = 0; u16 clk; unsigned int clock = 100000; if (device_may_wakeup(&pdev->dev)) { enable_irq_wake(host->sdhci->irq); } /* save interrupt status before suspending */ host->sdhci_ints = sdhci_readl(host->sdhci, SDHCI_INT_ENABLE); /* reduce host controller clk and card clk to 100 KHz */ tegra_sdhci_set_clock(host->sdhci, clock); sdhci_writew(host->sdhci, 0, SDHCI_CLOCK_CONTROL); if (host->sdhci->max_clk > clock) { div = 1 << (fls(host->sdhci->max_clk / clock) - 2); if (div > 128) div = 128; } clk = div << SDHCI_DIVIDER_SHIFT; clk |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_CARD_EN; sdhci_writew(host->sdhci, clk, SDHCI_CLOCK_CONTROL); printk("tegra_sdhci_suspend: skip %s suspend(always on)!\n",is_card_mmc(host->sdhci->mmc->card)?"eMMC":"SDIO"); return ret; } ret = sdhci_suspend_host(host->sdhci, state); if (ret) pr_err("%s: failed, error = %d\n", __func__, ret); tegra_sdhci_enable_clock(host, 0); MMC_printk("%s:-", mmc_hostname(host->sdhci->mmc)); return ret; }