[PATCH] mmc: dw_mmc: fix falling from idmac to PIO mode when dw_mci_reset occurs
Ulf Hansson
ulf.hansson at linaro.org
Thu Mar 15 02:57:32 PDT 2018
On 14 March 2018 at 20:30, Evgeniy Didin <Evgeniy.Didin at synopsys.com> wrote:
> It was found that in IDMAC mode after soft-reset driver switches
> to PIO mode.
>
> That's what happens in case of DTO timeout overflow calculation failure:
> 1. soft-reset is called
> 2. driver restarts dma
> 3. descriptors states are checked, one of descriptor is owned by the IDMAC.
> 4. driver can't use DMA and then switches to PIO mode.
>
> Failure was already fixed in:
> https://www.spinics.net/lists/linux-mmc/msg48125.html.
Evgeniy,
It seems like I should squash this fix into the above commit? Makes sense?
Kind regards
Uffe
>
> Behaviour while soft-reset is not something we except or
> even want to happen. So we switch from dw_mci_idmac_reset
> to dw_mci_idmac_init, so descriptors are cleaned before starting dma.
>
> And while at it explicitly zero des0 which otherwise might
> contain garbage as being allocated by dmam_alloc_coherent().
>
> Signed-off-by: Evgeniy Didin <Evgeniy.Didin at synopsys.com>
> Cc: Jaehoon Chung <jh80.chung at samsung.com>
> Cc: Ulf Hansson <ulf.hansson at linaro.org>
> Cc: Andy Shevchenko <andy.shevchenko at gmail.com>
> Cc: Jisheng Zhang <Jisheng.Zhang at synaptics.com>
> Cc: Shawn Lin <shawn.lin at rock-chips.com>
> Cc: Alexey Brodkin <abrodkin at synopsys.com>
> Cc: Eugeniy Paltsev <Eugeniy.Paltsev at synopsys.com>
> Cc: linux-snps-arc at lists.infradead.org
> ---
> drivers/mmc/host/dw_mmc.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 0aa39975f33b..26f2ac107702 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -558,6 +558,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
> (sizeof(struct idmac_desc_64addr) *
> (i + 1))) >> 32;
> /* Initialize reserved and buffer size fields to "0" */
> + p->des0 = 0;
> p->des1 = 0;
> p->des2 = 0;
> p->des3 = 0;
> @@ -580,6 +581,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
> i++, p++) {
> p->des3 = cpu_to_le32(host->sg_dma +
> (sizeof(struct idmac_desc) * (i + 1)));
> + p->des0 = 0;
> p->des1 = 0;
> }
>
> @@ -1795,8 +1797,8 @@ static bool dw_mci_reset(struct dw_mci *host)
> }
>
> if (host->use_dma == TRANS_MODE_IDMAC)
> - /* It is also recommended that we reset and reprogram idmac */
> - dw_mci_idmac_reset(host);
> + /* It is also required that we reinit idmac */
> + dw_mci_idmac_init(host);
>
> ret = true;
>
> --
> 2.11.0
>
More information about the linux-snps-arc
mailing list