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]

 



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.

> +
>  	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