aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/sd.c11
-rw-r--r--drivers/mmc/host/sdhci.c32
2 files changed, 43 insertions, 0 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index fc65475a26ee..b461b290ce25 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -925,6 +925,13 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
925 925
926 /* Card is an ultra-high-speed card */ 926 /* Card is an ultra-high-speed card */
927 mmc_sd_card_set_uhs(card); 927 mmc_sd_card_set_uhs(card);
928
929 /*
930 * Since initialization is now complete, enable preset
931 * value registers for UHS-I cards.
932 */
933 if (host->ops->enable_preset_value)
934 host->ops->enable_preset_value(host, true);
928 } else { 935 } else {
929 /* 936 /*
930 * Attempt to change to high-speed (if supported) 937 * Attempt to change to high-speed (if supported)
@@ -1095,6 +1102,10 @@ int mmc_attach_sd(struct mmc_host *host)
1095 if (err) 1102 if (err)
1096 return err; 1103 return err;
1097 1104
1105 /* Disable preset value enable if already set since last time */
1106 if (host->ops->enable_preset_value)
1107 host->ops->enable_preset_value(host, false);
1108
1098 err = mmc_send_app_op_cond(host, 0, &ocr); 1109 err = mmc_send_app_op_cond(host, 0, &ocr);
1099 if (err) 1110 if (err)
1100 return err; 1111 return err;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 8a56eacea34d..a1ab22415883 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1649,6 +1649,37 @@ out:
1649 return err; 1649 return err;
1650} 1650}
1651 1651
1652static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable)
1653{
1654 struct sdhci_host *host;
1655 u16 ctrl;
1656 unsigned long flags;
1657
1658 host = mmc_priv(mmc);
1659
1660 /* Host Controller v3.00 defines preset value registers */
1661 if (host->version < SDHCI_SPEC_300)
1662 return;
1663
1664 spin_lock_irqsave(&host->lock, flags);
1665
1666 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
1667
1668 /*
1669 * We only enable or disable Preset Value if they are not already
1670 * enabled or disabled respectively. Otherwise, we bail out.
1671 */
1672 if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
1673 ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
1674 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1675 } else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
1676 ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
1677 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
1678 }
1679
1680 spin_unlock_irqrestore(&host->lock, flags);
1681}
1682
1652static const struct mmc_host_ops sdhci_ops = { 1683static const struct mmc_host_ops sdhci_ops = {
1653 .request = sdhci_request, 1684 .request = sdhci_request,
1654 .set_ios = sdhci_set_ios, 1685 .set_ios = sdhci_set_ios,
@@ -1656,6 +1687,7 @@ static const struct mmc_host_ops sdhci_ops = {
1656 .enable_sdio_irq = sdhci_enable_sdio_irq, 1687 .enable_sdio_irq = sdhci_enable_sdio_irq,
1657 .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, 1688 .start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
1658 .execute_tuning = sdhci_execute_tuning, 1689 .execute_tuning = sdhci_execute_tuning,
1690 .enable_preset_value = sdhci_enable_preset_value,
1659}; 1691};
1660 1692
1661/*****************************************************************************\ 1693/*****************************************************************************\