On Thu, Nov 1, 2018 at 8:53 AM Niklas Söderlund
<niklas.soderl...@ragnatech.se> wrote:
>
> From: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>
>
> SD / MMC did not operate properly when suspend transition failed.
> Because the SCC was not reset at resume, issue of the command failed.
> Call the host specific reset function and reset the hardware in order to
> add reset of SCC. This change also fixes tuning on some stubborn cards
> on Gen2.
>
> Based on work from Masaharu Hayakawa.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>
>
> ---
> * Changes sine v1
> - Merge tmio_mmc_reset() into tmio_mmc_hw_reset() as it's now the only
>   caller.
>
> * Changes since v2
> - Rebased on mmc/next caused small refactoring of the code.
> ---
>  drivers/mmc/host/tmio_mmc_core.c | 26 +++++++++++++++-----------
>  1 file changed, 15 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/mmc/host/tmio_mmc_core.c 
> b/drivers/mmc/host/tmio_mmc_core.c
> index 953562a12a0d6ebc..662161be03b6d52e 100644
> --- a/drivers/mmc/host/tmio_mmc_core.c
> +++ b/drivers/mmc/host/tmio_mmc_core.c
> @@ -171,6 +171,18 @@ 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,
> @@ -209,7 +221,7 @@ static void tmio_mmc_reset_work(struct work_struct *work)
>
>         spin_unlock_irqrestore(&host->lock, flags);
>
> -       host->reset(host);
> +       tmio_mmc_hw_reset(host->mmc);
>
>         /* Ready for new calls */
>         host->mrq = NULL;



I see tmio_mmc_abort_dma() a few lines below.

If you add tmio_mmc_abort_dma() into tmio_mmc_hw_reset(),
you do not need to abort DMA twice, don't you?




        tmio_mmc_hw_reset(host->mmc);

        /* Ready for new calls */
        host->mrq = NULL;

        tmio_mmc_abort_dma(host);              /* <-- abort DMA again? */
        mmc_request_done(host->mmc, mrq);
}







> @@ -696,14 +708,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);
> @@ -1228,7 +1232,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_hw_reset(mmc);


I think it is weird to call tmio_mmc_abort_dma()
before tmio_mmc_request_dma().





>         _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, 
> CTL_IRQ_MASK);
>         tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
> @@ -1329,7 +1333,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_hw_reset(host->mmc);
>
>         if (host->clk_cache)
>                 host->set_clock(host, host->clk_cache);
> --
> 2.19.1
>


--
Best Regards
Masahiro Yamada

Reply via email to