@@ -711,6 +711,7 @@ config MMC_SDHI
tristate "Renesas SDHI SD/SDIO controller support"
depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
select MMC_TMIO_CORE
+ select RESET_CONTROLLER if ARCH_RENESAS
help
This provides support for the SDHI SD/SDIO controller found in
Renesas SuperH, ARM and ARM64 based SoCs
@@ -70,6 +70,8 @@ struct renesas_sdhi {
DECLARE_BITMAP(smpcmp, BITS_PER_LONG);
unsigned int tap_num;
unsigned int tap_set;
+
+ struct reset_control *rstc;
};
#define host_to_priv(host) \
@@ -20,6 +20,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
@@ -32,6 +33,7 @@
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
#include <linux/sh_dma.h>
#include <linux/slab.h>
#include <linux/sys_soc.h>
@@ -572,10 +574,19 @@ static void renesas_sdhi_scc_reset(struct tmio_mmc_host *host, struct renesas_sd
static void renesas_sdhi_reset(struct tmio_mmc_host *host)
{
struct renesas_sdhi *priv = host_to_priv(host);
+ int ret;
u16 val;
- if (priv->scc_ctl)
+ if (priv->rstc) {
+ reset_control_reset(priv->rstc);
+ /* Unknown why but without polling reset status, it will hang */
+ read_poll_timeout(reset_control_status, ret, ret == 0, 1, 100,
+ false, priv->rstc);
+ priv->needs_adjust_hs400 = false;
+ renesas_sdhi_set_clock(host, host->clk_cache);
+ } else if (priv->scc_ctl) {
renesas_sdhi_scc_reset(host, priv);
+ }
sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, TMIO_MASK_ALL_RCAR2);
@@ -1086,6 +1097,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
if (ret)
goto efree;
+ priv->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
+ if (IS_ERR(priv->rstc))
+ return PTR_ERR(priv->rstc);
+
ver = sd_ctrl_read16(host, CTL_VERSION);
/* GEN2_SDR104 is first known SDHI to use 32bit block count */
if (ver < SDHI_VER_GEN2_SDR104 && mmc_data->max_blk_count > U16_MAX)