diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a2114fb47edd..fde49464a637 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1507,6 +1507,9 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) switch (ios->power_mode) { case MMC_POWER_UP: + if (!IS_ERR_OR_NULL(slot->host->pinctrl)) + pinctrl_select_state(slot->host->pinctrl, slot->host->idle_state); + if (!IS_ERR(mmc->supply.vmmc)) { ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); @@ -1523,6 +1526,9 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) mci_writel(slot->host, PWREN, regs); break; case MMC_POWER_ON: + if (!IS_ERR_OR_NULL(slot->host->pinctrl)) + pinctrl_select_state(slot->host->pinctrl, slot->host->normal_state); + if (!slot->host->vqmmc_enabled) { if (!IS_ERR(mmc->supply.vqmmc)) { ret = regulator_enable(mmc->supply.vqmmc); @@ -1547,6 +1553,9 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) break; case MMC_POWER_OFF: + if (!IS_ERR_OR_NULL(slot->host->pinctrl)) + pinctrl_select_state(slot->host->pinctrl, slot->host->idle_state); + /* Turn clock off before power goes down */ dw_mci_setup_bus(slot, false); @@ -3262,6 +3271,22 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) return ERR_PTR(ret); } + host->pinctrl = devm_pinctrl_get(host->dev); + if (!IS_ERR(host->pinctrl)) { + host->normal_state = pinctrl_lookup_state(host->pinctrl, "normal"); + if (IS_ERR(host->normal_state)) + dev_warn(dev, "No normal pinctrl state\n"); + + host->idle_state = pinctrl_lookup_state(host->pinctrl, "idle"); + if (IS_ERR(host->idle_state)) + dev_warn(dev, "No idle pinctrl state\n"); + + if (!IS_ERR(host->normal_state) && !IS_ERR(host->idle_state)) + pinctrl_select_state(host->pinctrl, host->idle_state); + else + host->pinctrl = NULL; + } + return pdata; } diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 0160a1769f62..6ffa2fd6db38 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -233,6 +233,9 @@ struct dw_mci { bool need_xfer_timer; struct timer_list xfer_timer; bool is_rv1106_sd; + struct pinctrl *pinctrl; + struct pinctrl_state *normal_state; + struct pinctrl_state *idle_state; }; /* DMA ops for Internal/External DMAC interface */