mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 05:04:02 +02:00
mmc: Merge branch fixes into next
Merge the mmc fixes for v7.2-rc[n] into the next branch, to allow them to get tested together with the mmc changes that are targeted for the next release. Signed-off-by: Ulf Hansson <ulfh@kernel.org>
This commit is contained in:
commit
cf93175e7e
|
|
@ -1326,19 +1326,21 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
|
|||
|
||||
dev_dbg(mmc_dev(host->mmc), "change pinctrl state for uhs %d\n", uhs);
|
||||
|
||||
if (IS_ERR(imx_data->pinctrl) ||
|
||||
IS_ERR(imx_data->pins_100mhz) ||
|
||||
IS_ERR(imx_data->pins_200mhz))
|
||||
if (IS_ERR(imx_data->pinctrl))
|
||||
return -EINVAL;
|
||||
|
||||
switch (uhs) {
|
||||
case MMC_TIMING_UHS_SDR50:
|
||||
case MMC_TIMING_UHS_DDR50:
|
||||
if (IS_ERR(imx_data->pins_100mhz))
|
||||
return -EINVAL;
|
||||
pinctrl = imx_data->pins_100mhz;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR104:
|
||||
case MMC_TIMING_MMC_HS200:
|
||||
case MMC_TIMING_MMC_HS400:
|
||||
if (IS_ERR(imx_data->pins_200mhz))
|
||||
return -EINVAL;
|
||||
pinctrl = imx_data->pins_200mhz;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1349,6 +1351,23 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
|
|||
return pinctrl_select_state(imx_data->pinctrl, pinctrl);
|
||||
}
|
||||
|
||||
static void esdhc_set_dll_override(struct sdhci_host *host)
|
||||
{
|
||||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
|
||||
struct esdhc_platform_data *boarddata = &imx_data->boarddata;
|
||||
u32 v;
|
||||
|
||||
if (!boarddata->delay_line)
|
||||
return;
|
||||
|
||||
v = boarddata->delay_line << ESDHC_DLL_OVERRIDE_VAL_SHIFT |
|
||||
(1 << ESDHC_DLL_OVERRIDE_EN_SHIFT);
|
||||
if (is_imx53_esdhc(imx_data))
|
||||
v <<= 1;
|
||||
writel(v, host->ioaddr + ESDHC_DLL_CTRL);
|
||||
}
|
||||
|
||||
/*
|
||||
* For HS400 eMMC, there is a data_strobe line. This signal is generated
|
||||
* by the device and used for data output and CRC status response output
|
||||
|
|
@ -1404,7 +1423,6 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
|
|||
u32 m;
|
||||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
|
||||
struct esdhc_platform_data *boarddata = &imx_data->boarddata;
|
||||
|
||||
/* disable ddr mode and disable HS400 mode */
|
||||
m = readl(host->ioaddr + ESDHC_MIX_CTRL);
|
||||
|
|
@ -1425,15 +1443,7 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
|
|||
m |= ESDHC_MIX_CTRL_DDREN;
|
||||
writel(m, host->ioaddr + ESDHC_MIX_CTRL);
|
||||
imx_data->is_ddr = 1;
|
||||
if (boarddata->delay_line) {
|
||||
u32 v;
|
||||
v = boarddata->delay_line <<
|
||||
ESDHC_DLL_OVERRIDE_VAL_SHIFT |
|
||||
(1 << ESDHC_DLL_OVERRIDE_EN_SHIFT);
|
||||
if (is_imx53_esdhc(imx_data))
|
||||
v <<= 1;
|
||||
writel(v, host->ioaddr + ESDHC_DLL_CTRL);
|
||||
}
|
||||
esdhc_set_dll_override(host);
|
||||
break;
|
||||
case MMC_TIMING_MMC_HS400:
|
||||
m |= ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN;
|
||||
|
|
@ -2051,7 +2061,9 @@ static int sdhci_esdhc_suspend(struct device *dev)
|
|||
* 2, make sure the pm_runtime_force_resume() in sdhci_esdhc_resume() really
|
||||
* invoke its ->runtime_resume callback (needs_force_resume = 1).
|
||||
*/
|
||||
pm_runtime_get_sync(dev);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((imx_data->socdata->flags & ESDHC_FLAG_STATE_LOST_IN_LPMODE) &&
|
||||
(host->tuning_mode != SDHCI_TUNING_MODE_1)) {
|
||||
|
|
@ -2064,15 +2076,14 @@ static int sdhci_esdhc_suspend(struct device *dev)
|
|||
* to save the tuning delay value just in case the usdhc
|
||||
* lost power during system PM.
|
||||
*/
|
||||
if (mmc_card_keep_power(host->mmc) && mmc_card_wake_sdio_irq(host->mmc) &&
|
||||
esdhc_is_usdhc(imx_data))
|
||||
if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data))
|
||||
sdhc_esdhc_tuning_save(host);
|
||||
|
||||
/* The irqs of imx are not shared. It is safe to disable */
|
||||
disable_irq(host->irq);
|
||||
|
||||
if (device_may_wakeup(dev)) {
|
||||
/* The irqs of imx are not shared. It is safe to disable */
|
||||
disable_irq(host->irq);
|
||||
ret = sdhci_enable_irq_wakeups(host);
|
||||
if (!ret)
|
||||
if (!sdhci_enable_irq_wakeups(host))
|
||||
dev_warn(dev, "Failed to enable irq wakeup\n");
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -2083,12 +2094,12 @@ static int sdhci_esdhc_suspend(struct device *dev)
|
|||
* other function like GPIO function to save power in PM,
|
||||
* which finally block the SDIO wakeup function.
|
||||
*/
|
||||
ret = pinctrl_pm_select_sleep_state(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (pinctrl_pm_select_sleep_state(dev))
|
||||
dev_warn(dev, "Failed to select sleep pinctrl state\n");
|
||||
}
|
||||
|
||||
ret = mmc_gpio_set_cd_wake(host->mmc, true);
|
||||
if (mmc_gpio_set_cd_wake(host->mmc, true))
|
||||
dev_warn(dev, "Failed to enable cd wake\n");
|
||||
|
||||
/*
|
||||
* Make sure invoke runtime_suspend to gate off clock.
|
||||
|
|
@ -2096,7 +2107,7 @@ static int sdhci_esdhc_suspend(struct device *dev)
|
|||
*/
|
||||
pm_runtime_force_suspend(dev);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdhci_esdhc_resume(struct device *dev)
|
||||
|
|
@ -2106,31 +2117,45 @@ static int sdhci_esdhc_resume(struct device *dev)
|
|||
struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
|
||||
int ret;
|
||||
|
||||
pm_runtime_force_resume(dev);
|
||||
if (!device_may_wakeup(dev)) {
|
||||
ret = esdhc_change_pinstate(host, host->timing);
|
||||
if (ret)
|
||||
dev_warn(dev, "Failed to restore pinctrl state\n");
|
||||
}
|
||||
|
||||
ret = mmc_gpio_set_cd_wake(host->mmc, false);
|
||||
ret = pm_runtime_force_resume(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mmc_gpio_set_cd_wake(host->mmc, false);
|
||||
|
||||
/* re-initialize hw state in case it's lost in low power mode */
|
||||
sdhci_esdhc_imx_hwinit(host);
|
||||
|
||||
if (host->irq_wake_enabled) {
|
||||
if (host->irq_wake_enabled)
|
||||
sdhci_disable_irq_wakeups(host);
|
||||
enable_irq(host->irq);
|
||||
}
|
||||
|
||||
enable_irq(host->irq);
|
||||
|
||||
/*
|
||||
* restore the saved tuning delay value for the device which keep
|
||||
* power during system PM.
|
||||
*/
|
||||
if (mmc_card_keep_power(host->mmc) && mmc_card_wake_sdio_irq(host->mmc) &&
|
||||
esdhc_is_usdhc(imx_data))
|
||||
if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data)) {
|
||||
sdhc_esdhc_tuning_restore(host);
|
||||
|
||||
/*
|
||||
* Restore DLL override for DDR modes. hwinit unconditionally
|
||||
* clears ESDHC_DLL_CTRL, but the card is still in DDR mode.
|
||||
*/
|
||||
if (host->timing == MMC_TIMING_UHS_DDR50 ||
|
||||
host->timing == MMC_TIMING_MMC_DDR52)
|
||||
esdhc_set_dll_override(host);
|
||||
}
|
||||
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdhci_esdhc_runtime_suspend(struct device *dev)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user