Skip to contentSkip to conversation

Patch "mmc: sdhci-of-arasan: fix incorrect timeout clock" has been added to the 4.10-stable tree

PATCH [email protected] 1 participant 1 message Mar 28, 2017

Subsystems (4)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

mmc: sdhci-of-arasan: fix incorrect timeout clock

to the 4.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
mmc-sdhci-of-arasan-fix-incorrect-timeout-clock.patch
and it can be found in the queue-4.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 16681037e75ce08f2980ac5dbb03414429c7a55d Mon Sep 17 00:00:00 2001

From: Anssi Hannula <[email protected]>
Date: Mon, 13 Feb 2017 14:06:10 +0200
Subject: mmc: sdhci-of-arasan: fix incorrect timeout clock

From: Anssi Hannula <[email protected]>

commit 16681037e75ce08f2980ac5dbb03414429c7a55d upstream.

sdhci_arasan_get_timeout_clock() divides the frequency it has with (1 << (13 + divisor)).

However, the divisor is not some Arasan-specific value, but instead is just the Data Timeout Counter Value from the SDHCI Timeout Control Register.

Applying it here like this is wrong as the sdhci driver already takes that value into account when calculating timeouts, and in fact it *sets* that register value based on how long a timeout is wanted.

Additionally, sdhci core interprets the .get_timeout_clock callback return value as if it were read from hardware registers, i.e. the unit should be kHz or MHz depending on SDHCI_TIMEOUT_CLK_UNIT capability bit. This bit is set at least on the tested Zynq-7000 SoC.

With the tested hardware (SDHCI_TIMEOUT_CLK_UNIT set) this results in too high a timeout clock rate being reported, causing the core to use longer-than-needed timeouts. Additionally, on a partitioned MMC (therefore having erase_group_def bit set) mmc_calc_max_discard() disables discard support as it looks like controller does not support the long timeouts needed for that.

Do not apply the extra divisor and return the timeout clock in the expected unit.

Tested with a Zynq-7000 SoC and a partitioned Toshiba THGBMAG5A1JBAWR eMMC card.

Fixes e3ec3a3d11ad ("mmc: arasan: Add driver for Arasan SDHCI")
---
 drivers/mmc/host/sdhci-of-arasan.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)
drivers/mmc/host/sdhci-of-arasan.c +5 -9
@@ -28,13 +28,9 @@
 #include "sdhci-pltfm.h"
 #include <linux/of.h>
 
-#define SDHCI_ARASAN_CLK_CTRL_OFFSET	0x2c
 #define SDHCI_ARASAN_VENDOR_REGISTER	0x78
 
 #define VENDOR_ENHANCED_STROBE		BIT(0)
-#define CLK_CTRL_TIMEOUT_SHIFT		16
-#define CLK_CTRL_TIMEOUT_MASK		(0xf << CLK_CTRL_TIMEOUT_SHIFT)
-#define CLK_CTRL_TIMEOUT_MIN_EXP	13
 
 #define PHY_CLK_TOO_SLOW_HZ		400000
 
@@ -163,15 +159,15 @@ static int sdhci_arasan_syscon_write(str
 
 static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
 {
-	u32 div;
 	unsigned long freq;
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 
-	div = readl(host->ioaddr + SDHCI_ARASAN_CLK_CTRL_OFFSET);
-	div = (div & CLK_CTRL_TIMEOUT_MASK) >> CLK_CTRL_TIMEOUT_SHIFT;
+	/* SDHCI timeout clock is in kHz */
+	freq = DIV_ROUND_UP(clk_get_rate(pltfm_host->clk), 1000);
 
-	freq = clk_get_rate(pltfm_host->clk);
-	freq /= 1 << (CLK_CTRL_TIMEOUT_MIN_EXP + div);
+	/* or in MHz */
+	if (host->caps & SDHCI_TIMEOUT_CLK_UNIT)
+		freq = DIV_ROUND_UP(freq, 1000);
 
 	return freq;
 }

Patches currently in stable-queue which might be from [email protected] are

queue-4.10/mmc-core-fix-access-to-hs400-es-devices.patch queue-4.10/mmc-sdhci-of-arasan-fix-incorrect-timeout-clock.patch