Re: [RFC PATCH] mmc: cqhci: keep CQE enabled if halt times out

Adrian Hunter <[email protected]>
Newsgroups org.kernel.vger.linux-mmc,org.kernel.vger.linux-kernel
Organization Intel Finland Oy, Registered Address: c/o Alberga Business Park, 6 krs, Bertel Jungin Aukio 5, 02600 Espoo, Business Identity Code: 0357606 - 4, Domiciled in Helsinki
Message-ID <[email protected]>
On 23/06/2026 17:04, Pengpeng Hou wrote:
> cqhci_off() asks the controller to halt before post_disable(), clearing
> mmc->cqe_on and freeing CQE resources. If the halt wait times out, the
> function still continues through that success path even though the
> hardware may still be using the command queue.

CQHCI should be idle when cqhci_off() is used, so it should halt
immediately.  If not, it is a hardware error, but carrying on is
a reasonable option because I/O errors will trigger recovery
later.

> 
> Make cqhci_off() report whether the halt completed and leave the CQE
> state/resources intact when the controller remains stuck on. This keeps
> the existing host-specific ->disable() ordering and is intended as an
> RFC patch because the cqe_disable callback itself has no error return.

Is there a real problem that you are trying to fix?

> 
> Signed-off-by: Pengpeng Hou <[email protected]>
> ---
>  drivers/mmc/host/cqhci-core.c | 17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mmc/host/cqhci-core.c b/drivers/mmc/host/cqhci-core.c
> index 178277d90..84846207c 100644
> --- a/drivers/mmc/host/cqhci-core.c
> +++ b/drivers/mmc/host/cqhci-core.c
> @@ -372,14 +372,14 @@ static u32 cqhci_read_ctl(struct cqhci_host *cq_host)
>  	return cqhci_readl(cq_host, CQHCI_CTL);
>  }
>  
> -static void cqhci_off(struct mmc_host *mmc)
> +static bool cqhci_off(struct mmc_host *mmc)
>  {
>  	struct cqhci_host *cq_host = mmc->cqe_private;
>  	u32 reg;
>  	int err;
>  
>  	if (!cq_host->enabled || !mmc->cqe_on || cq_host->recovery_halt)
> -		return;
> +		return true;
>  
>  	if (cq_host->ops->disable)
>  		cq_host->ops->disable(mmc, false);
> @@ -388,15 +388,19 @@ static void cqhci_off(struct mmc_host *mmc)
>  
>  	err = readx_poll_timeout(cqhci_read_ctl, cq_host, reg,
>  				 reg & CQHCI_HALT, 0, CQHCI_OFF_TIMEOUT);
> -	if (err < 0)
> +	if (err < 0) {
>  		pr_err("%s: cqhci: CQE stuck on\n", mmc_hostname(mmc));
> -	else
> -		pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc));
> +		return false;
> +	}
> +
> +	pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc));
>  
>  	if (cq_host->ops->post_disable)
>  		cq_host->ops->post_disable(mmc);
>  
>  	mmc->cqe_on = false;
> +
> +	return true;
>  }
>  
>  static void cqhci_disable(struct mmc_host *mmc)
> @@ -406,7 +410,8 @@ static void cqhci_disable(struct mmc_host *mmc)
>  	if (!cq_host->enabled)
>  		return;
>  
> -	cqhci_off(mmc);
> +	if (!cqhci_off(mmc))
> +		return;
>  
>  	__cqhci_disable(cq_host);
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.