summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci-of-arasan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sdhci-of-arasan.c')
-rw-r--r--drivers/mmc/host/sdhci-of-arasan.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 5edd024347bd..8c29676ab662 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -76,6 +76,8 @@
#define FREQSEL_225M_200M 0x7
#define PHY_DLL_TIMEOUT_MS 100
+#define SDHCI_HW_RST_EN BIT(4)
+
/* Default settings for ZynqMP Clock Phases */
#define ZYNQMP_ICLK_PHASE {0, 63, 63, 0, 63, 0, 0, 183, 54, 0, 0}
#define ZYNQMP_OCLK_PHASE {0, 72, 60, 0, 60, 72, 135, 48, 72, 135, 0}
@@ -475,6 +477,21 @@ static void sdhci_arasan_reset(struct sdhci_host *host, u8 mask)
}
}
+static void sdhci_arasan_hw_reset(struct sdhci_host *host)
+{
+ u8 reg;
+
+ reg = sdhci_readb(host, SDHCI_POWER_CONTROL);
+ reg |= SDHCI_HW_RST_EN;
+ sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
+ /* As per eMMC spec, minimum 1us is required but give it 2us for good measure */
+ usleep_range(2, 5);
+ reg &= ~SDHCI_HW_RST_EN;
+ sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
+ /* As per eMMC spec, minimum 200us is required but give it 300us for good measure */
+ usleep_range(300, 500);
+}
+
static int sdhci_arasan_voltage_switch(struct mmc_host *mmc,
struct mmc_ios *ios)
{
@@ -505,6 +522,7 @@ static const struct sdhci_ops sdhci_arasan_ops = {
.reset = sdhci_arasan_reset,
.set_uhs_signaling = sdhci_set_uhs_signaling,
.set_power = sdhci_set_power_and_bus_voltage,
+ .hw_reset = sdhci_arasan_hw_reset,
};
static u32 sdhci_arasan_cqhci_irq(struct sdhci_host *host, u32 intmask)
@@ -2046,7 +2064,7 @@ static struct platform_driver sdhci_arasan_driver = {
.pm = &sdhci_arasan_dev_pm_ops,
},
.probe = sdhci_arasan_probe,
- .remove_new = sdhci_arasan_remove,
+ .remove = sdhci_arasan_remove,
};
module_platform_driver(sdhci_arasan_driver);