static void tegra_sdhci_set_clock(struct sdhci_host *sdhci, unsigned int clock)
{
	struct tegra_sdhci_host *host = sdhci_priv(sdhci);
	pr_debug("tegra sdhci clock %s %u enabled=%d\n",
		mmc_hostname(sdhci->mmc), clock, host->clk_enabled);

	tegra_sdhci_enable_clock(host, clock);
}
Example #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;

	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_resume(struct platform_device *pdev)
{
	struct tegra_sdhci_host *host = platform_get_drvdata(pdev);
	int ret;

	tegra_sdhci_enable_clock(host, 1);
	ret = sdhci_resume_host(host->sdhci);
	if (ret)
		pr_err("%s: failed, error = %d\n", __func__, ret);

	return ret;
}
static int tegra_sdhci_resume(struct platform_device *pdev)
{
	struct tegra_sdhci_host *host = platform_get_drvdata(pdev);
	int ret;
#ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA	
	int i, present;
#endif
	u8 pwr;
	if (host->card_always_on && is_card_sdio(host->sdhci->mmc->card)) {
		int ret = 0;

		if (device_may_wakeup(&pdev->dev)) {
		        disable_irq_wake(host->sdhci->irq);
		}

		/* soft reset SD host controller and enable interrupts */
		ret = tegra_sdhci_restore(host->sdhci);
		if (ret) {
			pr_err("%s: failed, error = %d\n", __func__, ret);
			return ret;
		}

		mmiowb();
#ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA
		for(i=0;i<20;i++){
			present = sdhci_readl(host->sdhci, SDHCI_PRESENT_STATE);
			if((present & SDHCI_CARD_PRESENT) == SDHCI_CARD_PRESENT)
				break;
			mdelay(5);
//			printk(KERN_ERR "MMC : %s : 6(Card Presnet %x) : %d \n",mmc_hostname(host->sdhci->mmc),present,i);
		}
#endif
		host->sdhci->mmc->ops->set_ios(host->sdhci->mmc,
			&host->sdhci->mmc->ios);
		return 0;
	}

	tegra_sdhci_enable_clock(host, 1);

	pwr = SDHCI_POWER_ON;
	sdhci_writeb(host->sdhci, pwr, SDHCI_POWER_CONTROL);
	host->sdhci->pwr = 0;

	ret = sdhci_resume_host(host->sdhci);
	if (ret)
		pr_err("%s: failed, error = %d\n", __func__, ret);

	return ret;
}
static int tegra_sdhci_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct tegra_sdhci_host *host = platform_get_drvdata(pdev);
	struct mmc_host *mmc = host->sdhci->mmc;
	int ret;

	if (host->plat->mmc_data.built_in)
	        mmc->pm_flags |= MMC_PM_KEEP_POWER;

	ret = sdhci_suspend_host(host->sdhci, state);
	if (ret)
		pr_err("%s: failed, error = %d\n", __func__, ret);

	tegra_sdhci_enable_clock(host, 0);
	return ret;
}
Example #6
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;
}
Example #7
0
static int tegra_sdhci_resume(struct platform_device *pdev)
{
	struct tegra_sdhci_host *host = platform_get_drvdata(pdev);
	int ret;
	u8 pwr;

	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 ret = 0;

		if (device_may_wakeup(&pdev->dev)) {
		        disable_irq_wake(host->sdhci->irq);
		}

		/* soft reset SD host controller and enable interrupts */
		ret = tegra_sdhci_restore(host->sdhci);
		if (ret) {
			pr_err("%s: failed, error = %d\n", __func__, ret);
			return ret;
		}

		mmiowb();
		host->sdhci->mmc->ops->set_ios(host->sdhci->mmc,
			&host->sdhci->mmc->ios);
		 printk("tegra_sdhci_suspend: skip %s resume(always on)!\n",is_card_mmc(host->sdhci->mmc->card)?"eMMC":"SDIO");
		return 0;
	}

	tegra_sdhci_enable_clock(host, 1);

	pwr = SDHCI_POWER_ON;
	sdhci_writeb(host->sdhci, pwr, SDHCI_POWER_CONTROL);
	host->sdhci->pwr = 0;

	ret = sdhci_resume_host(host->sdhci);
	if (ret)
		pr_err("%s: failed, error = %d\n", __func__, ret);

	MMC_printk("%s:-", mmc_hostname(host->sdhci->mmc));
	return ret;
}
Example #8
0
static int tegra_sdhci_resume(struct platform_device *pdev)
{
	struct tegra_sdhci_host *host = platform_get_drvdata(pdev);
	int ret;
	u8 pwr;

	if (host->card_always_on && is_card_sdio(host->sdhci->mmc->card)) {
		int ret = 0;

		if (device_may_wakeup(&pdev->dev)) {
		        disable_irq_wake(host->sdhci->irq);
		}

		/* soft reset SD host controller and enable interrupts */
		ret = tegra_sdhci_restore(host->sdhci);
		if (ret) {
			pr_err("%s: failed, error = %d\n", __func__, ret);
			return ret;
		}

		mmiowb();
		host->sdhci->mmc->ops->set_ios(host->sdhci->mmc,
			&host->sdhci->mmc->ios);
		return 0;
	}

	if (host->cd_gpio != -1) {
		bool card_status_before_suspend =  host->card_present;

		if (host->cd_gpio != -1) {
			host->card_present = host->card_present_old = (gpio_get_value(host->cd_gpio) == host->cd_gpio_polarity);
		}
		pr_info("%s: card_status_before_suspend=%d, card_present=%d \n", __func__, card_status_before_suspend, host->card_present);
		if (card_status_before_suspend != host->card_present) {
			if (!host->card_present) {
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
				mmc_set_bus_resume_policy(host->sdhci->mmc, 0);
#endif
			}
		}
	}

	tegra_sdhci_enable_clock(host, 1);

	pwr = SDHCI_POWER_ON;
	sdhci_writeb(host->sdhci, pwr, SDHCI_POWER_CONTROL);
	host->sdhci->pwr = 0;
	/*
	* Set disable_delay
	* to enable mmc_schedule_delay_work
	*/
	mmc_set_disable_delay(host->sdhci->mmc, 5);
	ret = sdhci_resume_host(host->sdhci);
	if (ret)
		pr_err("%s: failed, error = %d\n", __func__, ret);

	if (host->irq_cd != -1)
		enable_irq(host->irq_cd);

	return ret;
}