[PATCH 5.8 146/186] mmc: mediatek: add optional module reset property

From: Greg Kroah-Hartman
Date: Tue Sep 08 2020 - 14:22:33 EST


From: Wenbin Mei <wenbin.mei@xxxxxxxxxxxx>

commit 855d388df217989fbf1f18c781ae6490dbb48e86 upstream.

This patch fixs eMMC-Access on mt7622/Bpi-64.
Before we got these Errors on mounting eMMC ion R64:
[ 48.664925] blk_update_request: I/O error, dev mmcblk0, sector 204800 op 0x1:(WRITE)
flags 0x800 phys_seg 1 prio class 0
[ 48.676019] Buffer I/O error on dev mmcblk0p1, logical block 0, lost sync page write

This patch adds a optional reset management for msdc.
Sometimes the bootloader does not bring msdc register
to default state, so need reset the msdc controller.

Cc: <stable@xxxxxxxxxxxxxxx> # v5.4+
Fixes: 966580ad236e ("mmc: mediatek: add support for MT7622 SoC")
Signed-off-by: Wenbin Mei <wenbin.mei@xxxxxxxxxxxx>
Reviewed-by: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx>
Tested-by: Frank Wunderlich <frank-w@xxxxxxxxxxxxxxx>
Link: https://lore.kernel.org/r/20200814014346.6496-4-wenbin.mei@xxxxxxxxxxxx
Signed-off-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/mmc/host/mtk-sd.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
+#include <linux/reset.h>

#include <linux/mmc/card.h>
#include <linux/mmc/core.h>
@@ -414,6 +415,7 @@ struct msdc_host {
struct pinctrl_state *pins_uhs;
struct delayed_work req_timeout;
int irq; /* host interrupt */
+ struct reset_control *reset;

struct clk *src_clk; /* msdc source clock */
struct clk *h_clk; /* msdc h_clk */
@@ -1516,6 +1518,12 @@ static void msdc_init_hw(struct msdc_hos
u32 val;
u32 tune_reg = host->dev_comp->pad_tune_reg;

+ if (host->reset) {
+ reset_control_assert(host->reset);
+ usleep_range(10, 50);
+ reset_control_deassert(host->reset);
+ }
+
/* Configure to MMC/SD mode, clock free running */
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN);

@@ -2273,6 +2281,11 @@ static int msdc_drv_probe(struct platfor
if (IS_ERR(host->src_clk_cg))
host->src_clk_cg = NULL;

+ host->reset = devm_reset_control_get_optional_exclusive(&pdev->dev,
+ "hrst");
+ if (IS_ERR(host->reset))
+ return PTR_ERR(host->reset);
+
host->irq = platform_get_irq(pdev, 0);
if (host->irq < 0) {
ret = -EINVAL;