Commit 83dc42271f79202b746bc9614817b41a6911c88f
Committed by
Jaehoon Chung
1 parent
01298da31d
Exists in
smarc_8mq_lf_v2020.04
and in
17 other branches
mmc: Retry some MMC cmds on failure
With certain SD cards like Kingston 8GB/16GB UHS card, it is seen that MMC_CMD_ALL_SEND_CID cmd fails on first attempt, but succeeds subsequently. Therefore, retry MMC_CMD_ALL_SEND_CID cmd a few time as done in Linux kernel. Similarly, it is seen that MMC_CMD_SET_BLOCKLEN may fail on first attempt, therefore retry this cmd a few times as done in kernel. To make it clear that those are optionnal workarounds, a new Kconfig option 'MMC_QUIRKS' is added (enabled by default). Signed-off-by: Vignesh R <vigneshr@ti.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
Showing 3 changed files with 52 additions and 2 deletions Side-by-side Diff
drivers/mmc/Kconfig
... | ... | @@ -42,6 +42,15 @@ |
42 | 42 | If you have an ARM(R) platform with a Multimedia Card slot, |
43 | 43 | say Y or M here. |
44 | 44 | |
45 | +config MMC_QUIRKS | |
46 | + bool "Enable quirks" | |
47 | + default y | |
48 | + help | |
49 | + Some cards and hosts may sometimes behave unexpectedly (quirks). | |
50 | + This option enable workarounds to handle those quirks. Some of them | |
51 | + are enabled by default, other may require additionnal flags or are | |
52 | + enabled by the host driver. | |
53 | + | |
45 | 54 | config MMC_VERBOSE |
46 | 55 | bool "Output more information about the MMC" |
47 | 56 | default y |
drivers/mmc/mmc.c
... | ... | @@ -279,6 +279,7 @@ |
279 | 279 | int mmc_set_blocklen(struct mmc *mmc, int len) |
280 | 280 | { |
281 | 281 | struct mmc_cmd cmd; |
282 | + int err; | |
282 | 283 | |
283 | 284 | if (mmc->ddr_mode) |
284 | 285 | return 0; |
... | ... | @@ -287,7 +288,24 @@ |
287 | 288 | cmd.resp_type = MMC_RSP_R1; |
288 | 289 | cmd.cmdarg = len; |
289 | 290 | |
290 | - return mmc_send_cmd(mmc, &cmd, NULL); | |
291 | + err = mmc_send_cmd(mmc, &cmd, NULL); | |
292 | + | |
293 | +#ifdef CONFIG_MMC_QUIRKS | |
294 | + if (err && (mmc->quirks & MMC_QUIRK_RETRY_SET_BLOCKLEN)) { | |
295 | + int retries = 4; | |
296 | + /* | |
297 | + * It has been seen that SET_BLOCKLEN may fail on the first | |
298 | + * attempt, let's try a few more time | |
299 | + */ | |
300 | + do { | |
301 | + err = mmc_send_cmd(mmc, &cmd, NULL); | |
302 | + if (!err) | |
303 | + break; | |
304 | + } while (retries--); | |
305 | + } | |
306 | +#endif | |
307 | + | |
308 | + return err; | |
291 | 309 | } |
292 | 310 | |
293 | 311 | static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, |
... | ... | @@ -1881,7 +1899,6 @@ |
1881 | 1899 | cmd.resp_type = MMC_RSP_R1; |
1882 | 1900 | cmd.cmdarg = 1; |
1883 | 1901 | err = mmc_send_cmd(mmc, &cmd, NULL); |
1884 | - | |
1885 | 1902 | if (err) |
1886 | 1903 | return err; |
1887 | 1904 | } |
... | ... | @@ -1895,6 +1912,21 @@ |
1895 | 1912 | |
1896 | 1913 | err = mmc_send_cmd(mmc, &cmd, NULL); |
1897 | 1914 | |
1915 | +#ifdef CONFIG_MMC_QUIRKS | |
1916 | + if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) { | |
1917 | + int retries = 4; | |
1918 | + /* | |
1919 | + * It has been seen that SEND_CID may fail on the first | |
1920 | + * attempt, let's try a few more time | |
1921 | + */ | |
1922 | + do { | |
1923 | + err = mmc_send_cmd(mmc, &cmd, NULL); | |
1924 | + if (!err) | |
1925 | + break; | |
1926 | + } while (retries--); | |
1927 | + } | |
1928 | +#endif | |
1929 | + | |
1898 | 1930 | if (err) |
1899 | 1931 | return err; |
1900 | 1932 | |
... | ... | @@ -2238,6 +2270,11 @@ |
2238 | 2270 | err = mmc_power_init(mmc); |
2239 | 2271 | if (err) |
2240 | 2272 | return err; |
2273 | + | |
2274 | +#ifdef CONFIG_MMC_QUIRKS | |
2275 | + mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN | | |
2276 | + MMC_QUIRK_RETRY_SEND_CID; | |
2277 | +#endif | |
2241 | 2278 | |
2242 | 2279 | err = mmc_power_cycle(mmc); |
2243 | 2280 | if (err) { |
include/mmc.h
... | ... | @@ -306,6 +306,9 @@ |
306 | 306 | #define ENHNCD_SUPPORT (0x2) |
307 | 307 | #define PART_ENH_ATTRIB (0x1f) |
308 | 308 | |
309 | +#define MMC_QUIRK_RETRY_SEND_CID BIT(0) | |
310 | +#define MMC_QUIRK_RETRY_SET_BLOCKLEN BIT(1) | |
311 | + | |
309 | 312 | enum mmc_voltage { |
310 | 313 | MMC_SIGNAL_VOLTAGE_000 = 0, |
311 | 314 | MMC_SIGNAL_VOLTAGE_120, |
... | ... | @@ -591,6 +594,7 @@ |
591 | 594 | * operating mode due to limitations when |
592 | 595 | * accessing the boot partitions |
593 | 596 | */ |
597 | + u32 quirks; | |
594 | 598 | }; |
595 | 599 | |
596 | 600 | struct mmc_hwpart_conf { |