Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f7c1983 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mmc: sdhci: Add new host->op and quirk to apply reset workaround"

parents 9fffca4f 43d6be80
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -235,6 +235,7 @@ void sdhci_reset(struct sdhci_host *host, u8 mask)
{
	unsigned long timeout;

retry_reset:
	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);

	if (mask & SDHCI_RESET_ALL) {
@@ -260,12 +261,43 @@ void sdhci_reset(struct sdhci_host *host, u8 mask)
		if (timeout == 0) {
			pr_err("%s: Reset 0x%x never completed.\n",
				mmc_hostname(host->mmc), (int)mask);
			if ((host->quirks2 & SDHCI_QUIRK2_USE_RESET_WORKAROUND)
				&& host->ops->reset_workaround) {
				if (!host->reset_wa_applied) {
					/*
					 * apply the workaround and issue
					 * reset again.
					 */
					host->ops->reset_workaround(host, 1);
					host->reset_wa_applied = 1;
					host->reset_wa_cnt++;
					goto retry_reset;
				} else {
					pr_err("%s: Reset 0x%x failed with workaround\n",
						mmc_hostname(host->mmc),
						(int)mask);
					/* clear the workaround */
					host->ops->reset_workaround(host, 0);
					host->reset_wa_applied = 0;
				}
			}

			sdhci_dumpregs(host);
			return;
		}
		timeout--;
		mdelay(1);
	}

	if ((host->quirks2 & SDHCI_QUIRK2_USE_RESET_WORKAROUND) &&
			host->ops->reset_workaround && host->reset_wa_applied) {
		pr_info("%s: Reset 0x%x successful with workaround\n",
				mmc_hostname(host->mmc), (int)mask);
		/* clear the workaround */
		host->ops->reset_workaround(host, 0);
		host->reset_wa_applied = 0;
	}

}
EXPORT_SYMBOL_GPL(sdhci_reset);

+1 −0
Original line number Diff line number Diff line
@@ -331,6 +331,7 @@ struct sdhci_ops {
	void	(*enhanced_strobe_mask)(struct sdhci_host *host, bool set);
	void	(*detect)(struct sdhci_host *host, bool detected);
	int	(*notify_load)(struct sdhci_host *host, enum mmc_load state);
	void	(*reset_workaround)(struct sdhci_host *host, u32 enable);
};

#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+5 −1
Original line number Diff line number Diff line
@@ -167,7 +167,6 @@ struct sdhci_host {
 * calculated based on the base clock.
 */
#define SDHCI_QUIRK2_DIVIDE_TOUT_BY_4			(1<<16)

/*
 * Some SDHC controllers are unable to handle data-end bit error in
 * 1-bit mode of SDIO.
@@ -184,6 +183,8 @@ struct sdhci_host {
#define SDHCI_QUIRK_NONSTANDARD_CLOCK			(1<<19)
/* Capability register bit-63 indicates HS400 support */
#define SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400		(1<<20)
/* Use reset workaround in case sdhci reset timeouts */
#define SDHCI_QUIRK2_USE_RESET_WORKAROUND		(1<<21)

	int irq;		/* Device IRQ */
	void __iomem *ioaddr;	/* Mapped address */
@@ -295,6 +296,9 @@ struct sdhci_host {
	u32 auto_cmd_err_sts;
	struct ratelimit_state dbg_dump_rs;
	struct cmdq_host *cq_host;
	int reset_wa_applied; /* reset workaround status */
	ktime_t reset_wa_t; /* time when the reset workaround is applied */
	int reset_wa_cnt; /* total number of times workaround is used */

	unsigned long private[0] ____cacheline_aligned;
};