mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
UPSTREAM: mmc: core: fix __mmc_switch timeout caused by preempt
there is a time window between __mmc_send_status() and time_afer(),
on some eMMC chip, the timeout_ms is only 10ms, if this thread was
scheduled out during this period, then, even card has already changes
to transfer state by the result of CMD13, this part of code also treat
it to timeout error.
So, need calculate timeout first, then call __mmc_send_status(), if
already timeout and card still in programing state, then treat it to
the real timeout error.
Change-Id: I7499d3d41711ea5abe6baec780d2988dc60dfc5b
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 3bbb0deea6)
This commit is contained in:
committed by
Gerrit Code Review
parent
354189f074
commit
2f98f55d98
@@ -489,6 +489,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
|
||||
unsigned long timeout;
|
||||
u32 status = 0;
|
||||
bool use_r1b_resp = use_busy_signal;
|
||||
bool expired = false;
|
||||
|
||||
mmc_retune_hold(host);
|
||||
|
||||
@@ -545,6 +546,12 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
|
||||
timeout = jiffies + msecs_to_jiffies(timeout_ms);
|
||||
do {
|
||||
if (send_status) {
|
||||
/*
|
||||
* Due to the possibility of being preempted after
|
||||
* sending the status command, check the expiration
|
||||
* time first.
|
||||
*/
|
||||
expired = time_after(jiffies, timeout);
|
||||
err = __mmc_send_status(card, &status, ignore_crc);
|
||||
if (err)
|
||||
goto out;
|
||||
@@ -565,7 +572,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
|
||||
}
|
||||
|
||||
/* Timeout if the device never leaves the program state. */
|
||||
if (time_after(jiffies, timeout)) {
|
||||
if (expired && R1_CURRENT_STATE(status) == R1_STATE_PRG) {
|
||||
pr_err("%s: Card stuck in programming state! %s\n",
|
||||
mmc_hostname(host), __func__);
|
||||
err = -ETIMEDOUT;
|
||||
|
||||
Reference in New Issue
Block a user