Commit a31b0c6c authored by Kristina Martsenko's avatar Kristina Martsenko Committed by Ulf Hansson

mmc: core: fix card detection regression

Since commit 89168b48 ("mmc: core: restore detect line inversion
semantics"), the SD card on i.MX28 (and possibly other) devices isn't
detected and booting stops at:

[    4.120617] Waiting for root device /dev/mmcblk0p3...

This is caused by the MMC_CAP2_CD_ACTIVE_HIGH flag being set incorrectly
when the host controller doesn't use a GPIO for card detection (but
instead uses a dedicated pin). In this case mmc_gpiod_request_cd() will
return before assigning to the gpio_invert variable, leaving the
variable uninitialized. The variable then gets used to set the flag.
This patch fixes the issue by making sure gpio_invert is set to false
when a GPIO isn't used. After this patch, i.MX28 boots fine.

The MMC_CAP2_RO_ACTIVE_HIGH (write protect) flag is also set incorrectly
for the exact same reason (it uses the same uninitialized variable), so
this patch fixes that too.

Fixes: 89168b48 ("mmc: core: restore detect line inversion semantics")
Reported-by: default avatarStefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: default avatarKristina Martšenko <kristina.martsenko@gmail.com>
Tested-by: default avatarFabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 0df1f248
......@@ -311,7 +311,8 @@ int mmc_of_parse(struct mmc_host *host)
struct device_node *np;
u32 bus_width;
int len, ret;
bool cap_invert, gpio_invert;
bool cd_cap_invert, cd_gpio_invert = false;
bool ro_cap_invert, ro_gpio_invert = false;
if (!host->parent || !host->parent->of_node)
return 0;
......@@ -359,16 +360,13 @@ int mmc_of_parse(struct mmc_host *host)
if (of_find_property(np, "non-removable", &len)) {
host->caps |= MMC_CAP_NONREMOVABLE;
} else {
if (of_property_read_bool(np, "cd-inverted"))
cap_invert = true;
else
cap_invert = false;
cd_cap_invert = of_property_read_bool(np, "cd-inverted");
if (of_find_property(np, "broken-cd", &len))
host->caps |= MMC_CAP_NEEDS_POLL;
ret = mmc_gpiod_request_cd(host, "cd", 0, true,
0, &gpio_invert);
0, &cd_gpio_invert);
if (ret) {
if (ret == -EPROBE_DEFER)
return ret;
......@@ -391,17 +389,14 @@ int mmc_of_parse(struct mmc_host *host)
* both inverted, the end result is that the CD line is
* not inverted.
*/
if (cap_invert ^ gpio_invert)
if (cd_cap_invert ^ cd_gpio_invert)
host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
}
/* Parse Write Protection */
if (of_property_read_bool(np, "wp-inverted"))
cap_invert = true;
else
cap_invert = false;
ro_cap_invert = of_property_read_bool(np, "wp-inverted");
ret = mmc_gpiod_request_ro(host, "wp", 0, false, 0, &gpio_invert);
ret = mmc_gpiod_request_ro(host, "wp", 0, false, 0, &ro_gpio_invert);
if (ret) {
if (ret == -EPROBE_DEFER)
goto out;
......@@ -414,7 +409,7 @@ int mmc_of_parse(struct mmc_host *host)
dev_info(host->parent, "Got WP GPIO\n");
/* See the comment on CD inversion above */
if (cap_invert ^ gpio_invert)
if (ro_cap_invert ^ ro_gpio_invert)
host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
if (of_find_property(np, "cap-sd-highspeed", &len))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment