mmc: core: make hw_reset power cycle SD-cards
PATCH 1/1 mmc: core: make hw_reset power cycle SD-cards
SD-cards cannot be reset, but they can be power cycled. Power cycling a buggy SD-card sometimes helps it get back on track.
--- drivers/mmc/core/core.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-)
drivers/mmc/core/core.c +11 -5
@@ -2250,19 +2250,25 @@ static int mmc_do_hw_reset(struct mmc_host *host, int check) {struct mmc_card *card = host->card; -if (!(host->caps &MMC_CAP_HW_RESET ) || !host->ops->hw_reset) -return -EOPNOTSUPP ; -if (!card)return -EINVAL ; -if (!mmc_can_reset (card)) +if (!mmc_card_sd (card) && !((host->caps &MMC_CAP_HW_RESET ) && + host->ops->hw_reset)) +return -EOPNOTSUPP ; + +if (!mmc_card_sd (card) && !mmc_can_reset (card))return -EOPNOTSUPP ;mmc_host_clk_hold (host);mmc_set_clock (host, host->f_init); - host->ops->hw_reset (host); +if (mmc_card_sd (card)) +mmc_power_cycle (host, card->ocr); +else + host->ops->hw_reset (host); + +pr_warning ("%s: reset device\n" ,mmc_hostname (host));/* If the reset has happened, then a status command will fail */ if (check) {
Signature · 1 line
1.7.2.5
Quoted 2 lines · Johan Rudholm
SD-cards cannot be reset, but they can be power cycled. Power cycling a buggy SD-card sometimes helps it get back on track.
Hi Johan,
This feature has been missing for too long - really great that you are working on this!
Quoted 42 lines
Signed-off-by Johan Rudholm <[email protected]>--- drivers/mmc/core/core.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-)drivers/mmc/core/core.c +11
-6@@ -2250,19 +2250,25 @@ static int mmc_do_hw_reset(struct mmc_host *host, int check) {struct mmc_card *card = host->card; -if (!(host->caps &MMC_CAP_HW_RESET ) || !host->ops->hw_reset) -return -EOPNOTSUPP ; -if (!card)return -EINVAL ; -if (!mmc_can_reset (card)) +if (!mmc_card_sd (card) && !((host->caps &MMC_CAP_HW_RESET ) && + host->ops->hw_reset)) +return -EOPNOTSUPP ; + +if (!mmc_card_sd (card) && !mmc_can_reset (card))return -EOPNOTSUPP ;mmc_host_clk_hold (host);mmc_set_clock (host, host->f_init); - host->ops->hw_reset (host); +if (mmc_card_sd (card)) +mmc_power_cycle (host, card->ocr); +else + host->ops->hw_reset (host); + +pr_warning ("%s: reset device\n" ,mmc_hostname (host));/* If the reset has happened, then a status command will fail */ if (check) { --
Quoted 2 lines
1.7.2.5
Before we decide to go ahead an continue to hack on the current reset code as your patch does, could you possibly consider to do some more extensive rework this code?
Here are some of the ideas that I had in mind.
1) Invent a new bus_ops callback for reset. Or maybe we should re-use the ->power_save|restore ones, since those already exist!?
2) Since those bus_ops are specific for sd/mmc/sdio we shall handle those related parts in there.
3) Then let's mmc_do_hw_reset invoke the above bus_ops.
4) Remove the mmc_hw_reset_check() API. Currently only used by mmc_test.
What do you think?
Kind regards
Uffe
Hi Ulf,
2014-09-11 13:03 GMT+02:00 Ulf Hansson <[email protected]>:
Quoted 48 lines · Johan Rudholm
Quoted 2 lines
SD-cards cannot be reset, but they can be power cycled. Power cycling a buggy SD-card sometimes helps it get back on track.
Hi Johan,
This feature has been missing for too long - really great that you are working on this!
Quoted 39 lines
Signed-off-by Johan Rudholm <[email protected]>--- drivers/mmc/core/core.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-)drivers/mmc/core/core.c +11
-5@@ -2250,19 +2250,25 @@ static int mmc_do_hw_reset(struct mmc_host *host, int check) {struct mmc_card *card = host->card; -if (!(host->caps &MMC_CAP_HW_RESET ) || !host->ops->hw_reset) -return -EOPNOTSUPP ; -if (!card)return -EINVAL ; -if (!mmc_can_reset (card)) +if (!mmc_card_sd (card) && !((host->caps &MMC_CAP_HW_RESET ) && + host->ops->hw_reset)) +return -EOPNOTSUPP ; + +if (!mmc_card_sd (card) && !mmc_can_reset (card))return -EOPNOTSUPP ;mmc_host_clk_hold (host);mmc_set_clock (host, host->f_init); - host->ops->hw_reset (host); +if (mmc_card_sd (card)) +mmc_power_cycle (host, card->ocr); +else + host->ops->hw_reset (host); + +pr_warning ("%s: reset device\n" ,mmc_hostname (host));
Quoted 9 lines
Quoted 5 lines
drivers/mmc/core/core.c +0
-1/* If the reset has happened, then a status command will fail */ if (check) { --1.7.2.5
Before we decide to go ahead an continue to hack on the current reset code as your patch does, could you possibly consider to do some more extensive rework this code?
Sure, challenge accepted!
Quoted 8 lines
Here are some of the ideas that I had in mind.
1) Invent a new
bus_opscallback for reset. Or maybe we should re-use the ->power_save|restore ones, since those already exist!?
2) Since thosebus_opsare specific for sd/mmc/sdio we shall handle those related parts in there.
3) Then let'smmc_do_hw_resetinvoke the abovebus_ops.
4) Remove themmc_hw_reset_check()API. Currently only used bymmc_test.
Reuse makes some sense, since bus_ops->power_restore is already a part of the current hw_reset reset sequence. But do you mean like letting bus_ops->power_save call host_ops->hw_reset? Won't this interfere with the other use case of power_save?
What's the current status of mmc_power_save_host and bus_ops->power_save anyway? As far as I can see, they are no longer used by the MMC framework. Maybe we can throw away mmc_power_save_host and bus_ops->power_save, and instead add the reset bus_ops? The naming of the bus_ops will be more fitting this way.
//Johan