Commit 855d388d authored by Wenbin Mei's avatar Wenbin Mei Committed by Ulf Hansson
Browse files

mmc: mediatek: add optional module reset property



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@vger.kernel.org> # v5.4+
Fixes: 966580ad ("mmc: mediatek: add support for MT7622 SoC")
Signed-off-by: default avatarWenbin Mei <wenbin.mei@mediatek.com>
Reviewed-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Tested-by: default avatarFrank Wunderlich <frank-w@public-files.de>
Link: https://lore.kernel.org/r/20200814014346.6496-4-wenbin.mei@mediatek.com


Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 65557383
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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>
@@ -419,6 +420,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 */
@@ -1592,6 +1594,12 @@ static void msdc_init_hw(struct msdc_host *host)
	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);

@@ -2390,6 +2398,11 @@ static int msdc_drv_probe(struct platform_device *pdev)
	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;