| From 1c447116d017a98c90f8f71c8c5a611e0aa42178 Mon Sep 17 00:00:00 2001 |
| From: Adrian Hunter <adrian.hunter@intel.com> |
| Date: Thu, 5 May 2016 08:12:28 +0300 |
| Subject: mmc: mmc: Fix partition switch timeout for some eMMCs |
| |
| From: Adrian Hunter <adrian.hunter@intel.com> |
| |
| commit 1c447116d017a98c90f8f71c8c5a611e0aa42178 upstream. |
| |
| Some eMMCs set the partition switch timeout too low. |
| |
| Now typically eMMCs are considered a critical component (e.g. because |
| they store the root file system) and consequently are expected to be |
| reliable. Thus we can neglect the use case where eMMCs can't switch |
| reliably and we might want a lower timeout to facilitate speedy |
| recovery. |
| |
| Although we could employ a quirk for the cards that are affected (if |
| we could identify them all), as described above, there is little |
| benefit to having a low timeout, so instead simply set a minimum |
| timeout. |
| |
| The minimum is set to 300ms somewhat arbitrarily - the examples that |
| have been seen had a timeout of 10ms but were sometimes taking 60-70ms. |
| |
| Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> |
| Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/mmc/core/mmc.c | 7 +++++++ |
| 1 file changed, 7 insertions(+) |
| |
| --- a/drivers/mmc/core/mmc.c |
| +++ b/drivers/mmc/core/mmc.c |
| @@ -333,6 +333,9 @@ static void mmc_manage_gp_partitions(str |
| } |
| } |
| |
| +/* Minimum partition switch timeout in milliseconds */ |
| +#define MMC_MIN_PART_SWITCH_TIME 300 |
| + |
| /* |
| * Decode extended CSD. |
| */ |
| @@ -397,6 +400,10 @@ static int mmc_decode_ext_csd(struct mmc |
| |
| /* EXT_CSD value is in units of 10ms, but we store in ms */ |
| card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; |
| + /* Some eMMC set the value too low so set a minimum */ |
| + if (card->ext_csd.part_time && |
| + card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME) |
| + card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME; |
| |
| /* Sleep / awake timeout in 100ns units */ |
| if (sa_shift > 0 && sa_shift <= 0x17) |