linux-renesas-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFT 0/6] mmc: refactor reset callbacks
@ 2020-08-20 13:25 Wolfram Sang
  2020-08-20 13:25 ` [RFT 1/6] mmc: renesas_sdhi: move wrong 'hw_reset' to 'reset' Wolfram Sang
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Wolfram Sang @ 2020-08-20 13:25 UTC (permalink / raw)
  To: linux-mmc
  Cc: linux-renesas-soc, Yoshihiro Shimoda, Niklas Söderlund,
	Masahiro Yamada, Wolfram Sang

While debugging something else, I noticed that the SDHI driver
doesn't use the 'hw_reset' callback as intended. It was used to reset
the tuning block but not the remote card via RSTn.

So, this patch series fixes it by moving stuff to the reset callback. In
addition, calls within the TMIO core are converted to 'reset' and the
'hw_reset' callback is only used by the MMC core now.

This allow for further cleanups which make the code a tad smaller and
much more readable.

I did some testing here, and tuning etc... still works, no regressions,
both with eMMC and SDXC. I send this out as RFT because I want to give
our BSP team also a chance to test more advanced cases. Also, I will be
thinking of more ways to verify this all is correct. A branch for
testing can be found here:

git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/sdhi/refactor_hw_reset

The branch is based on top of v5.9-rc1.

Looking forward to comments!

Happy hacking,

   Wolfram


Wolfram Sang (6):
  mmc: renesas_sdhi: move wrong 'hw_reset' to 'reset'
  Revert "mmc: tmio: fix reset operation"
  mmc: tmio: remove indirection of 'hw_reset' callback
  mmc: tmio: factor out common parts of the reset routine
  mmc: tmio: don't reset whole IP core when tuning fails
  mmc: tmio: remove indirection of 'execute_tuning' callback

 drivers/mmc/host/renesas_sdhi_core.c | 58 ++++++++++++++--------------
 drivers/mmc/host/tmio_mmc.c          |  8 ----
 drivers/mmc/host/tmio_mmc.h          |  7 ----
 drivers/mmc/host/tmio_mmc_core.c     | 45 ++++-----------------
 drivers/mmc/host/uniphier-sd.c       |  5 ++-
 5 files changed, 39 insertions(+), 84 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFT 1/6] mmc: renesas_sdhi: move wrong 'hw_reset' to 'reset'
  2020-08-20 13:25 [RFT 0/6] mmc: refactor reset callbacks Wolfram Sang
@ 2020-08-20 13:25 ` Wolfram Sang
  2020-08-28  4:31   ` Yoshihiro Shimoda
  2020-08-20 13:25 ` [RFT 2/6] Revert "mmc: tmio: fix reset operation" Wolfram Sang
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Wolfram Sang @ 2020-08-20 13:25 UTC (permalink / raw)
  To: linux-mmc
  Cc: linux-renesas-soc, Yoshihiro Shimoda, Niklas Söderlund,
	Masahiro Yamada, Wolfram Sang

This driver got the usage of 'hw_reset' wrong and missed that it is used
to reset the remote HW (card) only, not the local one (controller). Move
everything to the proper 'reset' callback. Also, add the generic reset
code from TMIO, so we will ensure the same behaviour (it will get
refactored away in a later patch). This also means we need to drop
MMC_CAP_HW_RESET because this is currently not supported by our
hardware.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/renesas_sdhi_core.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 15e21894bd44..73807c8cfa98 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -631,11 +631,20 @@ static bool renesas_sdhi_check_scc_error(struct tmio_mmc_host *host)
 	return renesas_sdhi_manual_correction(host, use_4tap);
 }
 
-static void renesas_sdhi_hw_reset(struct tmio_mmc_host *host)
+static void renesas_sdhi_reset(struct tmio_mmc_host *host)
 {
-	struct renesas_sdhi *priv;
+	struct renesas_sdhi *priv = host_to_priv(host);
 
-	priv = host_to_priv(host);
+	/* FIXME - should we set stop clock reg here */
+	sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
+	usleep_range(10000, 11000);
+	sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
+	usleep_range(10000, 11000);
+
+	if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) {
+		sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
+		sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
+	}
 
 	renesas_sdhi_reset_scc(host, priv);
 	renesas_sdhi_reset_hs400_mode(host, priv);
@@ -862,11 +871,9 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 			renesas_sdhi_start_signal_voltage_switch;
 		host->sdcard_irq_setbit_mask = TMIO_STAT_ALWAYS_SET_27;
 
-		/* SDR and HS200/400 registers requires HW reset */
 		if (of_data && of_data->scc_offset) {
 			priv->scc_ctl = host->ctl + of_data->scc_offset;
-			host->mmc->caps |= MMC_CAP_HW_RESET;
-			host->hw_reset = renesas_sdhi_hw_reset;
+			host->reset = renesas_sdhi_reset;
 		}
 	}
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFT 2/6] Revert "mmc: tmio: fix reset operation"
  2020-08-20 13:25 [RFT 0/6] mmc: refactor reset callbacks Wolfram Sang
  2020-08-20 13:25 ` [RFT 1/6] mmc: renesas_sdhi: move wrong 'hw_reset' to 'reset' Wolfram Sang
@ 2020-08-20 13:25 ` Wolfram Sang
  2020-08-28  4:31   ` Yoshihiro Shimoda
  2020-08-20 13:25 ` [RFT 3/6] mmc: tmio: remove indirection of 'hw_reset' callback Wolfram Sang
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Wolfram Sang @ 2020-08-20 13:25 UTC (permalink / raw)
  To: linux-mmc
  Cc: linux-renesas-soc, Yoshihiro Shimoda, Niklas Söderlund,
	Masahiro Yamada, Wolfram Sang

This reverts commit a87852c6b8827b7fece78ae57d871d56e4348e30. It did fix
the issue, but was building on top of already wrong assumptions. The
driver missed that 'hw_reset' was only for resetting remote HW (card)
and not for the IP core. Since we fixed that in a previous patch, we can
now remove this patch to make it clear that 'reset' is for resetting the
IP core only. Also, cancelling DMA will only be called when actually
needed again. It will also allow for further cleanups and better
readability. Note that in addition to the revert, the call in
'tmio_mmc_execute_tuning' will be converted, too, to maintain the
current behaviour.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/tmio_mmc_core.c | 29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index 946fb013c610..125530e7bd17 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -178,18 +178,6 @@ static void tmio_mmc_reset(struct tmio_mmc_host *host)
 	}
 }
 
-static void tmio_mmc_hw_reset(struct mmc_host *mmc)
-{
-	struct tmio_mmc_host *host = mmc_priv(mmc);
-
-	host->reset(host);
-
-	tmio_mmc_abort_dma(host);
-
-	if (host->hw_reset)
-		host->hw_reset(host);
-}
-
 static void tmio_mmc_reset_work(struct work_struct *work)
 {
 	struct tmio_mmc_host *host = container_of(work, struct tmio_mmc_host,
@@ -228,11 +216,12 @@ static void tmio_mmc_reset_work(struct work_struct *work)
 
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	tmio_mmc_hw_reset(host->mmc);
+	host->reset(host);
 
 	/* Ready for new calls */
 	host->mrq = NULL;
 
+	tmio_mmc_abort_dma(host);
 	mmc_request_done(host->mmc, mrq);
 }
 
@@ -720,6 +709,14 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host,
 	return 0;
 }
 
+static void tmio_mmc_hw_reset(struct mmc_host *mmc)
+{
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+
+	if (host->hw_reset)
+		host->hw_reset(host);
+}
+
 static int tmio_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
@@ -732,7 +729,7 @@ static int tmio_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 
 	if (ret < 0) {
 		dev_warn(&host->pdev->dev, "Tuning procedure failed\n");
-		tmio_mmc_hw_reset(mmc);
+		host->reset(host);
 	}
 
 	return ret;
@@ -1180,7 +1177,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
 		_host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
 
 	_host->set_clock(_host, 0);
-	tmio_mmc_hw_reset(mmc);
+	_host->reset(_host);
 
 	_host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK);
 	tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
@@ -1283,7 +1280,7 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
 	struct tmio_mmc_host *host = dev_get_drvdata(dev);
 
 	tmio_mmc_clk_enable(host);
-	tmio_mmc_hw_reset(host->mmc);
+	host->reset(host);
 
 	if (host->clk_cache)
 		host->set_clock(host, host->clk_cache);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFT 3/6] mmc: tmio: remove indirection of 'hw_reset' callback
  2020-08-20 13:25 [RFT 0/6] mmc: refactor reset callbacks Wolfram Sang
  2020-08-20 13:25 ` [RFT 1/6] mmc: renesas_sdhi: move wrong 'hw_reset' to 'reset' Wolfram Sang
  2020-08-20 13:25 ` [RFT 2/6] Revert "mmc: tmio: fix reset operation" Wolfram Sang
@ 2020-08-20 13:25 ` Wolfram Sang
  2020-08-28  4:31   ` Yoshihiro Shimoda
  2020-08-20 13:25 ` [RFT 4/6] mmc: tmio: factor out common parts of the reset routine Wolfram Sang
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Wolfram Sang @ 2020-08-20 13:25 UTC (permalink / raw)
  To: linux-mmc
  Cc: linux-renesas-soc, Yoshihiro Shimoda, Niklas Söderlund,
	Masahiro Yamada, Wolfram Sang

After Yamada-san's refactorization introducing 'tmio_mmc_host_alloc', we
can populate mmc_ops directly and don't need a layer inbetween.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/tmio_mmc.h      | 1 -
 drivers/mmc/host/tmio_mmc_core.c | 9 ---------
 drivers/mmc/host/uniphier-sd.c   | 5 +++--
 3 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 0a4f36500add..dac717041c2d 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -178,7 +178,6 @@ struct tmio_mmc_host {
 			      unsigned int direction, int blk_size);
 	int (*write16_hook)(struct tmio_mmc_host *host, int addr);
 	void (*reset)(struct tmio_mmc_host *host);
-	void (*hw_reset)(struct tmio_mmc_host *host);
 	bool (*check_retune)(struct tmio_mmc_host *host);
 
 	/*
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index 125530e7bd17..a4bd0a0a305c 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -709,14 +709,6 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host,
 	return 0;
 }
 
-static void tmio_mmc_hw_reset(struct mmc_host *mmc)
-{
-	struct tmio_mmc_host *host = mmc_priv(mmc);
-
-	if (host->hw_reset)
-		host->hw_reset(host);
-}
-
 static int tmio_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
@@ -1008,7 +1000,6 @@ static struct mmc_host_ops tmio_mmc_ops = {
 	.get_cd		= tmio_mmc_get_cd,
 	.enable_sdio_irq = tmio_mmc_enable_sdio_irq,
 	.multi_io_quirk	= tmio_multi_io_quirk,
-	.hw_reset	= tmio_mmc_hw_reset,
 	.execute_tuning = tmio_mmc_execute_tuning,
 };
 
diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c
index f82baf99fd69..55efd5c53249 100644
--- a/drivers/mmc/host/uniphier-sd.c
+++ b/drivers/mmc/host/uniphier-sd.c
@@ -409,8 +409,9 @@ static void uniphier_sd_clk_disable(struct tmio_mmc_host *host)
 	clk_disable_unprepare(priv->clk);
 }
 
-static void uniphier_sd_hw_reset(struct tmio_mmc_host *host)
+static void uniphier_sd_hw_reset(struct mmc_host *mmc)
 {
+	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
 
 	reset_control_assert(priv->rst_hw);
@@ -597,7 +598,7 @@ static int uniphier_sd_probe(struct platform_device *pdev)
 			ret = PTR_ERR(priv->rst_hw);
 			goto free_host;
 		}
-		host->hw_reset = uniphier_sd_hw_reset;
+		host->ops.hw_reset = uniphier_sd_hw_reset;
 	}
 
 	if (host->mmc->caps & MMC_CAP_UHS) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFT 4/6] mmc: tmio: factor out common parts of the reset routine
  2020-08-20 13:25 [RFT 0/6] mmc: refactor reset callbacks Wolfram Sang
                   ` (2 preceding siblings ...)
  2020-08-20 13:25 ` [RFT 3/6] mmc: tmio: remove indirection of 'hw_reset' callback Wolfram Sang
@ 2020-08-20 13:25 ` Wolfram Sang
  2020-08-28  4:31   ` Yoshihiro Shimoda
  2020-08-20 13:25 ` [RFT 5/6] mmc: tmio: don't reset whole IP core when tuning fails Wolfram Sang
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Wolfram Sang @ 2020-08-20 13:25 UTC (permalink / raw)
  To: linux-mmc
  Cc: linux-renesas-soc, Yoshihiro Shimoda, Niklas Söderlund,
	Masahiro Yamada, Wolfram Sang

Some TMIO variants need specific actions in their reset routine, but
they are all based on a generic reset routine. So, the optional 'reset'
callback will now only take care of the additional stuff and we will
have a generic function around it. Less code, easier to maintain, and
much more readable. Code in tmio_mmc.c is untested but in my TC6387XB
datasheet the SDIO part is reset independently from the SD part, too.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/renesas_sdhi_core.c | 11 -----------
 drivers/mmc/host/tmio_mmc.c          |  8 --------
 drivers/mmc/host/tmio_mmc_core.c     | 14 +++++++-------
 3 files changed, 7 insertions(+), 26 deletions(-)

diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 73807c8cfa98..73ddd3e6eebb 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -635,17 +635,6 @@ static void renesas_sdhi_reset(struct tmio_mmc_host *host)
 {
 	struct renesas_sdhi *priv = host_to_priv(host);
 
-	/* FIXME - should we set stop clock reg here */
-	sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
-	usleep_range(10000, 11000);
-	sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
-	usleep_range(10000, 11000);
-
-	if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) {
-		sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
-		sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
-	}
-
 	renesas_sdhi_reset_scc(host, priv);
 	renesas_sdhi_reset_hs400_mode(host, priv);
 
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index 93e83ad25976..757c90160ae4 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -77,18 +77,10 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
 
 static void tmio_mmc_reset(struct tmio_mmc_host *host)
 {
-	/* FIXME - should we set stop clock reg here */
-	sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
 	sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
 	usleep_range(10000, 11000);
-	sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
 	sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001);
 	usleep_range(10000, 11000);
-
-	if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) {
-		sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
-		sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
-	}
 }
 
 #ifdef CONFIG_PM_SLEEP
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index a4bd0a0a305c..f68c10b8ed61 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -172,6 +172,9 @@ static void tmio_mmc_reset(struct tmio_mmc_host *host)
 	sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
 	usleep_range(10000, 11000);
 
+	if (host->reset)
+		host->reset(host);
+
 	if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) {
 		sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
 		sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
@@ -216,7 +219,7 @@ static void tmio_mmc_reset_work(struct work_struct *work)
 
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	host->reset(host);
+	tmio_mmc_reset(host);
 
 	/* Ready for new calls */
 	host->mrq = NULL;
@@ -721,7 +724,7 @@ static int tmio_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 
 	if (ret < 0) {
 		dev_warn(&host->pdev->dev, "Tuning procedure failed\n");
-		host->reset(host);
+		tmio_mmc_reset(host);
 	}
 
 	return ret;
@@ -1144,9 +1147,6 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
 				  mmc->caps & MMC_CAP_NEEDS_POLL ||
 				  !mmc_card_is_removable(mmc));
 
-	if (!_host->reset)
-		_host->reset = tmio_mmc_reset;
-
 	/*
 	 * On Gen2+, eMMC with NONREMOVABLE currently fails because native
 	 * hotplug gets disabled. It seems RuntimePM related yet we need further
@@ -1168,7 +1168,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
 		_host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
 
 	_host->set_clock(_host, 0);
-	_host->reset(_host);
+	tmio_mmc_reset(_host);
 
 	_host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK);
 	tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
@@ -1271,7 +1271,7 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
 	struct tmio_mmc_host *host = dev_get_drvdata(dev);
 
 	tmio_mmc_clk_enable(host);
-	host->reset(host);
+	tmio_mmc_reset(host);
 
 	if (host->clk_cache)
 		host->set_clock(host, host->clk_cache);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFT 5/6] mmc: tmio: don't reset whole IP core when tuning fails
  2020-08-20 13:25 [RFT 0/6] mmc: refactor reset callbacks Wolfram Sang
                   ` (3 preceding siblings ...)
  2020-08-20 13:25 ` [RFT 4/6] mmc: tmio: factor out common parts of the reset routine Wolfram Sang
@ 2020-08-20 13:25 ` Wolfram Sang
  2020-08-28  4:31   ` Yoshihiro Shimoda
  2020-08-20 13:25 ` [RFT 6/6] mmc: tmio: remove indirection of 'execute_tuning' callback Wolfram Sang
  2020-08-28  8:44 ` [RFT 0/6] mmc: refactor reset callbacks Ulf Hansson
  6 siblings, 1 reply; 14+ messages in thread
From: Wolfram Sang @ 2020-08-20 13:25 UTC (permalink / raw)
  To: linux-mmc
  Cc: linux-renesas-soc, Yoshihiro Shimoda, Niklas Söderlund,
	Masahiro Yamada, Wolfram Sang

SDHI needs to reset the SCC only, not the whole IP core. So, if tuning
fails, don't handle specifics in the generic TMIO core, but in the
specific drivers. For SDHI, we need to move around the reset routine a
bit. It is not modified.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/renesas_sdhi_core.c | 45 +++++++++++++++-------------
 drivers/mmc/host/tmio_mmc_core.c     |  4 +--
 2 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 73ddd3e6eebb..872f36a43753 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -432,6 +432,25 @@ static int renesas_sdhi_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_io
 	return 0;
 }
 
+static void renesas_sdhi_reset(struct tmio_mmc_host *host)
+{
+	struct renesas_sdhi *priv = host_to_priv(host);
+
+	renesas_sdhi_reset_scc(host, priv);
+	renesas_sdhi_reset_hs400_mode(host, priv);
+
+	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+			sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+
+	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL,
+		       ~SH_MOBILE_SDHI_SCC_RVSCNTL_RVSEN &
+		       sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL));
+
+	if (host->pdata->flags & TMIO_MMC_MIN_RCAR2)
+		sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK,
+					     TMIO_MASK_INIT_RCAR2);
+}
+
 #define SH_MOBILE_SDHI_MIN_TAP_ROW 3
 
 static int renesas_sdhi_select_tuning(struct tmio_mmc_host *host)
@@ -503,7 +522,7 @@ static int renesas_sdhi_select_tuning(struct tmio_mmc_host *host)
 static int renesas_sdhi_execute_tuning(struct tmio_mmc_host *host, u32 opcode)
 {
 	struct renesas_sdhi *priv = host_to_priv(host);
-	int i;
+	int i, ret;
 
 	priv->tap_num = renesas_sdhi_init_tuning(host);
 	if (!priv->tap_num)
@@ -531,7 +550,10 @@ static int renesas_sdhi_execute_tuning(struct tmio_mmc_host *host, u32 opcode)
 			set_bit(i, priv->smpcmp);
 	}
 
-	return renesas_sdhi_select_tuning(host);
+	ret = renesas_sdhi_select_tuning(host);
+	if (ret < 0)
+		renesas_sdhi_reset(host);
+	return ret;
 }
 
 static bool renesas_sdhi_manual_correction(struct tmio_mmc_host *host, bool use_4tap)
@@ -631,25 +653,6 @@ static bool renesas_sdhi_check_scc_error(struct tmio_mmc_host *host)
 	return renesas_sdhi_manual_correction(host, use_4tap);
 }
 
-static void renesas_sdhi_reset(struct tmio_mmc_host *host)
-{
-	struct renesas_sdhi *priv = host_to_priv(host);
-
-	renesas_sdhi_reset_scc(host, priv);
-	renesas_sdhi_reset_hs400_mode(host, priv);
-
-	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
-			sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
-
-	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL,
-		       ~SH_MOBILE_SDHI_SCC_RVSCNTL_RVSEN &
-		       sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL));
-
-	if (host->pdata->flags & TMIO_MMC_MIN_RCAR2)
-		sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK,
-					     TMIO_MASK_INIT_RCAR2);
-}
-
 static int renesas_sdhi_wait_idle(struct tmio_mmc_host *host, u32 bit)
 {
 	int timeout = 1000;
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index f68c10b8ed61..e7bad761c714 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -722,10 +722,8 @@ static int tmio_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 
 	ret = host->execute_tuning(host, opcode);
 
-	if (ret < 0) {
+	if (ret < 0)
 		dev_warn(&host->pdev->dev, "Tuning procedure failed\n");
-		tmio_mmc_reset(host);
-	}
 
 	return ret;
 }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFT 6/6] mmc: tmio: remove indirection of 'execute_tuning' callback
  2020-08-20 13:25 [RFT 0/6] mmc: refactor reset callbacks Wolfram Sang
                   ` (4 preceding siblings ...)
  2020-08-20 13:25 ` [RFT 5/6] mmc: tmio: don't reset whole IP core when tuning fails Wolfram Sang
@ 2020-08-20 13:25 ` Wolfram Sang
  2020-08-28  4:31   ` Yoshihiro Shimoda
  2020-08-28  8:44 ` [RFT 0/6] mmc: refactor reset callbacks Ulf Hansson
  6 siblings, 1 reply; 14+ messages in thread
From: Wolfram Sang @ 2020-08-20 13:25 UTC (permalink / raw)
  To: linux-mmc
  Cc: linux-renesas-soc, Yoshihiro Shimoda, Niklas Söderlund,
	Masahiro Yamada, Wolfram Sang

After all the previous refactorization, we can now populate mmc_ops
directly and don't need a layer inbetween. The NULL-pointer check and
the error printout are already done by the MMC core.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/mmc/host/renesas_sdhi_core.c |  7 ++++---
 drivers/mmc/host/tmio_mmc.h          |  6 ------
 drivers/mmc/host/tmio_mmc_core.c     | 17 -----------------
 3 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index 872f36a43753..29148fa25d82 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -519,8 +519,9 @@ static int renesas_sdhi_select_tuning(struct tmio_mmc_host *host)
 	return 0;
 }
 
-static int renesas_sdhi_execute_tuning(struct tmio_mmc_host *host, u32 opcode)
+static int renesas_sdhi_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
+	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct renesas_sdhi *priv = host_to_priv(host);
 	int i, ret;
 
@@ -543,7 +544,7 @@ static int renesas_sdhi_execute_tuning(struct tmio_mmc_host *host, u32 opcode)
 		/* Set sampling clock position */
 		sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, i % priv->tap_num);
 
-		if (mmc_send_tuning(host->mmc, opcode, NULL) == 0)
+		if (mmc_send_tuning(mmc, opcode, NULL) == 0)
 			set_bit(i, priv->taps);
 
 		if (sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_SMPCMP) == 0)
@@ -942,8 +943,8 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 		if (!hit)
 			dev_warn(&host->pdev->dev, "Unknown clock rate for tuning\n");
 
-		host->execute_tuning = renesas_sdhi_execute_tuning;
 		host->check_retune = renesas_sdhi_check_scc_error;
+		host->ops.execute_tuning = renesas_sdhi_execute_tuning;
 		host->ops.prepare_hs400_tuning = renesas_sdhi_prepare_hs400_tuning;
 		host->ops.hs400_downgrade = renesas_sdhi_disable_scc;
 		host->ops.hs400_complete = renesas_sdhi_hs400_complete;
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index dac717041c2d..51b5f388f6d8 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -180,12 +180,6 @@ struct tmio_mmc_host {
 	void (*reset)(struct tmio_mmc_host *host);
 	bool (*check_retune)(struct tmio_mmc_host *host);
 
-	/*
-	 * Mandatory callback for tuning to occur which is optional for SDR50
-	 * and mandatory for SDR104.
-	 */
-	int (*execute_tuning)(struct tmio_mmc_host *host, u32 opcode);
-
 	void (*prepare_hs400_tuning)(struct tmio_mmc_host *host);
 	void (*hs400_downgrade)(struct tmio_mmc_host *host);
 	void (*hs400_complete)(struct tmio_mmc_host *host);
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index e7bad761c714..0f266cbf82b8 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -712,22 +712,6 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host,
 	return 0;
 }
 
-static int tmio_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
-{
-	struct tmio_mmc_host *host = mmc_priv(mmc);
-	int ret;
-
-	if (!host->execute_tuning)
-		return 0;
-
-	ret = host->execute_tuning(host, opcode);
-
-	if (ret < 0)
-		dev_warn(&host->pdev->dev, "Tuning procedure failed\n");
-
-	return ret;
-}
-
 static void tmio_process_mrq(struct tmio_mmc_host *host,
 			     struct mmc_request *mrq)
 {
@@ -1001,7 +985,6 @@ static struct mmc_host_ops tmio_mmc_ops = {
 	.get_cd		= tmio_mmc_get_cd,
 	.enable_sdio_irq = tmio_mmc_enable_sdio_irq,
 	.multi_io_quirk	= tmio_multi_io_quirk,
-	.execute_tuning = tmio_mmc_execute_tuning,
 };
 
 static int tmio_mmc_init_ocr(struct tmio_mmc_host *host)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* RE: [RFT 1/6] mmc: renesas_sdhi: move wrong 'hw_reset' to 'reset'
  2020-08-20 13:25 ` [RFT 1/6] mmc: renesas_sdhi: move wrong 'hw_reset' to 'reset' Wolfram Sang
@ 2020-08-28  4:31   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 14+ messages in thread
From: Yoshihiro Shimoda @ 2020-08-28  4:31 UTC (permalink / raw)
  To: Wolfram Sang, linux-mmc
  Cc: linux-renesas-soc, Niklas Söderlund, Masahiro Yamada

Hi Wolfram-san,

> From: Wolfram Sang, Sent: Thursday, August 20, 2020 10:26 PM
> 
> This driver got the usage of 'hw_reset' wrong and missed that it is used
> to reset the remote HW (card) only, not the local one (controller). Move
> everything to the proper 'reset' callback. Also, add the generic reset
> code from TMIO, so we will ensure the same behaviour (it will get
> refactored away in a later patch). This also means we need to drop
> MMC_CAP_HW_RESET because this is currently not supported by our
> hardware.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Best regards,
Yoshihiro Shimoda


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [RFT 2/6] Revert "mmc: tmio: fix reset operation"
  2020-08-20 13:25 ` [RFT 2/6] Revert "mmc: tmio: fix reset operation" Wolfram Sang
@ 2020-08-28  4:31   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 14+ messages in thread
From: Yoshihiro Shimoda @ 2020-08-28  4:31 UTC (permalink / raw)
  To: Wolfram Sang, linux-mmc
  Cc: linux-renesas-soc, Niklas Söderlund, Masahiro Yamada

Hi Wolfram-san,

> From: Wolfram Sang, Sent: Thursday, August 20, 2020 10:26 PM
> 
> This reverts commit a87852c6b8827b7fece78ae57d871d56e4348e30. It did fix
> the issue, but was building on top of already wrong assumptions. The
> driver missed that 'hw_reset' was only for resetting remote HW (card)
> and not for the IP core. Since we fixed that in a previous patch, we can
> now remove this patch to make it clear that 'reset' is for resetting the
> IP core only. Also, cancelling DMA will only be called when actually
> needed again. It will also allow for further cleanups and better
> readability. Note that in addition to the revert, the call in
> 'tmio_mmc_execute_tuning' will be converted, too, to maintain the
> current behaviour.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Best regards,
Yoshihiro Shimoda


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [RFT 3/6] mmc: tmio: remove indirection of 'hw_reset' callback
  2020-08-20 13:25 ` [RFT 3/6] mmc: tmio: remove indirection of 'hw_reset' callback Wolfram Sang
@ 2020-08-28  4:31   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 14+ messages in thread
From: Yoshihiro Shimoda @ 2020-08-28  4:31 UTC (permalink / raw)
  To: Wolfram Sang, linux-mmc
  Cc: linux-renesas-soc, Niklas Söderlund, Masahiro Yamada

Hi Wolfram-san,

> From: Wolfram Sang, Sent: Thursday, August 20, 2020 10:26 PM
> 
> After Yamada-san's refactorization introducing 'tmio_mmc_host_alloc', we
> can populate mmc_ops directly and don't need a layer inbetween.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Best regards,
Yoshihiro Shimoda


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [RFT 4/6] mmc: tmio: factor out common parts of the reset routine
  2020-08-20 13:25 ` [RFT 4/6] mmc: tmio: factor out common parts of the reset routine Wolfram Sang
@ 2020-08-28  4:31   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 14+ messages in thread
From: Yoshihiro Shimoda @ 2020-08-28  4:31 UTC (permalink / raw)
  To: Wolfram Sang, linux-mmc
  Cc: linux-renesas-soc, Niklas Söderlund, Masahiro Yamada

Hi Wolfram-san,

> From: Wolfram Sang, Sent: Thursday, August 20, 2020 10:26 PM
> 
> Some TMIO variants need specific actions in their reset routine, but
> they are all based on a generic reset routine. So, the optional 'reset'
> callback will now only take care of the additional stuff and we will
> have a generic function around it. Less code, easier to maintain, and
> much more readable. Code in tmio_mmc.c is untested but in my TC6387XB
> datasheet the SDIO part is reset independently from the SD part, too.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Best regards,
Yoshihiro Shimoda


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [RFT 5/6] mmc: tmio: don't reset whole IP core when tuning fails
  2020-08-20 13:25 ` [RFT 5/6] mmc: tmio: don't reset whole IP core when tuning fails Wolfram Sang
@ 2020-08-28  4:31   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 14+ messages in thread
From: Yoshihiro Shimoda @ 2020-08-28  4:31 UTC (permalink / raw)
  To: Wolfram Sang, linux-mmc
  Cc: linux-renesas-soc, Niklas Söderlund, Masahiro Yamada

Hi Wolfram-san,

> From: Wolfram Sang, Sent: Thursday, August 20, 2020 10:26 PM
> 
> SDHI needs to reset the SCC only, not the whole IP core. So, if tuning
> fails, don't handle specifics in the generic TMIO core, but in the
> specific drivers. For SDHI, we need to move around the reset routine a
> bit. It is not modified.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Best regards,
Yoshihiro Shimoda


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [RFT 6/6] mmc: tmio: remove indirection of 'execute_tuning' callback
  2020-08-20 13:25 ` [RFT 6/6] mmc: tmio: remove indirection of 'execute_tuning' callback Wolfram Sang
@ 2020-08-28  4:31   ` Yoshihiro Shimoda
  0 siblings, 0 replies; 14+ messages in thread
From: Yoshihiro Shimoda @ 2020-08-28  4:31 UTC (permalink / raw)
  To: Wolfram Sang, linux-mmc
  Cc: linux-renesas-soc, Niklas Söderlund, Masahiro Yamada

Hi Wolfram-san,

> From: Wolfram Sang, Sent: Thursday, August 20, 2020 10:26 PM
> 
> After all the previous refactorization, we can now populate mmc_ops
> directly and don't need a layer inbetween. The NULL-pointer check and
> the error printout are already done by the MMC core.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

And, I tested on R-Car H3 ES3.0 Salvator-XS and it doesn't seem
any regression. So,

Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Best regards,
Yoshihiro Shimoda


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFT 0/6] mmc: refactor reset callbacks
  2020-08-20 13:25 [RFT 0/6] mmc: refactor reset callbacks Wolfram Sang
                   ` (5 preceding siblings ...)
  2020-08-20 13:25 ` [RFT 6/6] mmc: tmio: remove indirection of 'execute_tuning' callback Wolfram Sang
@ 2020-08-28  8:44 ` Ulf Hansson
  6 siblings, 0 replies; 14+ messages in thread
From: Ulf Hansson @ 2020-08-28  8:44 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: linux-mmc, Linux-Renesas, Yoshihiro Shimoda,
	Niklas Söderlund, Masahiro Yamada

On Thu, 20 Aug 2020 at 15:26, Wolfram Sang
<wsa+renesas@sang-engineering.com> wrote:
>
> While debugging something else, I noticed that the SDHI driver
> doesn't use the 'hw_reset' callback as intended. It was used to reset
> the tuning block but not the remote card via RSTn.
>
> So, this patch series fixes it by moving stuff to the reset callback. In
> addition, calls within the TMIO core are converted to 'reset' and the
> 'hw_reset' callback is only used by the MMC core now.
>
> This allow for further cleanups which make the code a tad smaller and
> much more readable.
>
> I did some testing here, and tuning etc... still works, no regressions,
> both with eMMC and SDXC. I send this out as RFT because I want to give
> our BSP team also a chance to test more advanced cases. Also, I will be
> thinking of more ways to verify this all is correct. A branch for
> testing can be found here:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/sdhi/refactor_hw_reset
>
> The branch is based on top of v5.9-rc1.
>
> Looking forward to comments!
>
> Happy hacking,
>
>    Wolfram
>
>
> Wolfram Sang (6):
>   mmc: renesas_sdhi: move wrong 'hw_reset' to 'reset'
>   Revert "mmc: tmio: fix reset operation"
>   mmc: tmio: remove indirection of 'hw_reset' callback
>   mmc: tmio: factor out common parts of the reset routine
>   mmc: tmio: don't reset whole IP core when tuning fails
>   mmc: tmio: remove indirection of 'execute_tuning' callback
>
>  drivers/mmc/host/renesas_sdhi_core.c | 58 ++++++++++++++--------------
>  drivers/mmc/host/tmio_mmc.c          |  8 ----
>  drivers/mmc/host/tmio_mmc.h          |  7 ----
>  drivers/mmc/host/tmio_mmc_core.c     | 45 ++++-----------------
>  drivers/mmc/host/uniphier-sd.c       |  5 ++-
>  5 files changed, 39 insertions(+), 84 deletions(-)
>
> --
> 2.20.1
>

Applied for next, also adding the tested-by tag from Shimoda-san to
all the patches, thanks!

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-08-28  8:45 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-20 13:25 [RFT 0/6] mmc: refactor reset callbacks Wolfram Sang
2020-08-20 13:25 ` [RFT 1/6] mmc: renesas_sdhi: move wrong 'hw_reset' to 'reset' Wolfram Sang
2020-08-28  4:31   ` Yoshihiro Shimoda
2020-08-20 13:25 ` [RFT 2/6] Revert "mmc: tmio: fix reset operation" Wolfram Sang
2020-08-28  4:31   ` Yoshihiro Shimoda
2020-08-20 13:25 ` [RFT 3/6] mmc: tmio: remove indirection of 'hw_reset' callback Wolfram Sang
2020-08-28  4:31   ` Yoshihiro Shimoda
2020-08-20 13:25 ` [RFT 4/6] mmc: tmio: factor out common parts of the reset routine Wolfram Sang
2020-08-28  4:31   ` Yoshihiro Shimoda
2020-08-20 13:25 ` [RFT 5/6] mmc: tmio: don't reset whole IP core when tuning fails Wolfram Sang
2020-08-28  4:31   ` Yoshihiro Shimoda
2020-08-20 13:25 ` [RFT 6/6] mmc: tmio: remove indirection of 'execute_tuning' callback Wolfram Sang
2020-08-28  4:31   ` Yoshihiro Shimoda
2020-08-28  8:44 ` [RFT 0/6] mmc: refactor reset callbacks Ulf Hansson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).