Re: [PATCH v1 5/6] mmc: sdhci: add quirk to ignore command inhibit for data

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

 



On 18/02/19 5:16 AM, Yinbo Zhu wrote:
> From: Yangbo Lu <yangbo.lu@xxxxxxx>
> 
> For some controllers, in Present State Register, Data Line
> Active bit is not reliable for commands (such as CMD6, CMD7,
> CMD12, CMD28, CMD29, or CMD38) with busy signal. DLA affects
> Command with Data Inhibit bit. Therefore, software driver
> may not know the busy status in DLA/CDIHB.
> 
> Futunately MMC core driver has already polled card status
> with CMD13 after sending any command with busy signal. So
> we can just ignore CDIHB never released issue for such
> controllers. This patch is to add a quirk to handle this.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@xxxxxxx>
> Signed-off-by: Yinbo Zhu <yinbo.zhu@xxxxxxx>
> ---
>  drivers/mmc/host/sdhci.c |   13 +++++++++++++
>  drivers/mmc/host/sdhci.h |    2 +-
>  2 files changed, 14 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 8f72889..1cd28c1 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1340,6 +1340,7 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
>  {
>  	int flags;
>  	u32 mask;
> +	u32 val;
>  	unsigned long timeout;
>  
>  	WARN_ON(host->cmd);
> @@ -1365,6 +1366,18 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
>  
>  	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
>  		if (timeout == 0) {
> +			val = sdhci_readl(host, SDHCI_PRESENT_STATE);
> +			/*
> +			 * Some controllers have unreliable Data Line Active
> +			 * bit for commands with busy signal. This affects
> +			 * Command Inhibit (data) bit. Just ignore it since
> +			 * MMC core driver has already polled card status
> +			 * with CMD13 after any command with busy siganl.
> +			 */
> +			if (((val & mask) == SDHCI_DATA_INHIBIT) &&
> +			(host->quirks2 & SDHCI_QUIRK2_IGNORE_DATA_INHIBIT))
> +				break;

What about instead masking the bit in esdhc_readl_fixup()?

> +
>  			pr_err("%s: Controller never released inhibit bit(s).\n",
>  			       mmc_hostname(host->mmc));
>  			sdhci_dumpregs(host);
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 01002cb..65075b8 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -485,7 +485,7 @@ struct sdhci_host {
>   * block count.
>   */
>  #define SDHCI_QUIRK2_USE_32BIT_BLK_CNT			(1<<18)
> -
> +#define SDHCI_QUIRK2_IGNORE_DATA_INHIBIT		(1<<19)
>  	int irq;		/* Device IRQ */
>  	void __iomem *ioaddr;	/* Mapped address */
>  	char *bounce_buffer;	/* For packing SDMA reads/writes */
> 




[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