Commit b4d86f37 authored by Wolfram Sang's avatar Wolfram Sang Committed by Ulf Hansson
Browse files

mmc: renesas_sdhi: do hard reset if possible



All recent SDHI instances can be reset via the reset controller. If one
is found, use it instead of the open coded reset. This is to get a
future-proof sane reset state.

Reviewed-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Link: https://lore.kernel.org/r/20210317091622.31890-4-wsa+renesas@sang-engineering.com


Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 0e587014
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -708,6 +708,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
+2 −0
Original line number Diff line number Diff line
@@ -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) \
+16 −1
Original line number Diff line number Diff line
@@ -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);

@@ -1081,6 +1092,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)