RE: [v2, 1/2] mmc: sdhci-of-esdhc: poll ESDHC_FLUSH_ASYNC_FIFO bit until completion

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Adrian,

> -----Original Message-----
> From: Adrian Hunter <adrian.hunter@xxxxxxxxx>
> Sent: Tuesday, October 8, 2019 6:49 PM
> To: Y.b. Lu <yangbo.lu@xxxxxxx>; linux-mmc@xxxxxxxxxxxxxxx; Ulf Hansson
> <ulf.hansson@xxxxxxxxxx>
> Subject: Re: [v2, 1/2] mmc: sdhci-of-esdhc: poll ESDHC_FLUSH_ASYNC_FIFO
> bit until completion
> 
> On 24/09/19 12:31 PM, Yangbo Lu wrote:
> > The ESDHC_FLUSH_ASYNC_FIFO bit which is set to flush asynchronous FIFO
> > should be polled until it's auto cleared by hardware.
> >
> > Signed-off-by: Yangbo Lu <yangbo.lu@xxxxxxx>
> > ---
> > Changes for v2:
> > 	- None.
> > ---
> >  drivers/mmc/host/sdhci-of-esdhc.c | 32
> > ++++++++++++++++++++++++++++++++
> >  1 file changed, 32 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c
> > b/drivers/mmc/host/sdhci-of-esdhc.c
> > index 1d1953d..be0ba6b 100644
> > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > @@ -655,6 +655,21 @@ static void esdhc_of_set_clock(struct sdhci_host
> *host, unsigned int clock)
> >  		temp = sdhci_readl(host, ESDHC_DMA_SYSCTL);
> >  		temp |= ESDHC_FLUSH_ASYNC_FIFO;
> >  		sdhci_writel(host, temp, ESDHC_DMA_SYSCTL);
> > +		/* Wait max 20 ms */
> > +		timeout = ktime_add_ms(ktime_get(), 20);
> > +		while (1) {
> > +			bool timedout = ktime_after(ktime_get(), timeout);
> > +
> > +			if (!(sdhci_readl(host, ESDHC_DMA_SYSCTL) &
> > +			      ESDHC_FLUSH_ASYNC_FIFO))
> > +				break;
> > +			if (timedout) {
> > +				pr_err("%s: tuning block polling FLUSH_ASYNC_FIFO
> timeout.\n",
> > +					mmc_hostname(host->mmc));
> > +				break;
> > +			}
> > +			udelay(10);
> > +		}
> >  	}
> >
> >  	/* Wait max 20 ms */
> > @@ -811,6 +826,7 @@ static struct soc_device_attribute
> > soc_fixup_tuning[] = {
> >
> >  static void esdhc_tuning_block_enable(struct sdhci_host *host, bool
> > enable)  {
> > +	ktime_t timeout;
> >  	u32 val;
> >
> >  	esdhc_clock_enable(host, false);
> > @@ -819,6 +835,22 @@ static void esdhc_tuning_block_enable(struct
> sdhci_host *host, bool enable)
> >  	val |= ESDHC_FLUSH_ASYNC_FIFO;
> >  	sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
> >
> > +	/* Wait max 20 ms */
> > +	timeout = ktime_add_ms(ktime_get(), 20);
> > +	while (1) {
> > +		bool timedout = ktime_after(ktime_get(), timeout);
> > +
> > +		if (!(sdhci_readl(host, ESDHC_DMA_SYSCTL) &
> > +		      ESDHC_FLUSH_ASYNC_FIFO))
> > +			break;
> > +		if (timedout) {
> > +			pr_err("%s: tuning block polling FLUSH_ASYNC_FIFO
> timeout.\n",
> > +				mmc_hostname(host->mmc));
> > +			break;
> > +		}
> > +		udelay(10);
> > +	}
> 
> That code is the same as the block above, so it could be a separate function.
> Also you don't use SDHCI_QUIRK_CLOCK_BEFORE_RESET so using
> usleep_range would be ok instead of udelay.

[Y.b. Lu] Sent out v3. Converted to use esdhc_flush_async_fifo(), and used usleep_range() instead of udelay().
Thanks!

> 
> > +
> >  	val = sdhci_readl(host, ESDHC_TBCTL);
> >  	if (enable)
> >  		val |= ESDHC_TB_EN;
> >





[Index of Archives]     [Linux Memonry Technology]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux