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); }
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; }
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; }
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; }
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; }