コード例 #1
0
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;
}
コード例 #2
0
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;
}