mmc: core: fix card detection regression
Since commit89168b4899
("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:89168b4899
("mmc: core: restore detect line inversion semantics") Reported-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Kristina Martšenko <kristina.martsenko@gmail.com> Tested-by: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
parent
0df1f2487d
commit
a31b0c6c19
@ -311,7 +311,8 @@ int mmc_of_parse(struct mmc_host *host)
|
|||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
u32 bus_width;
|
u32 bus_width;
|
||||||
int len, ret;
|
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)
|
if (!host->parent || !host->parent->of_node)
|
||||||
return 0;
|
return 0;
|
||||||
@ -359,16 +360,13 @@ int mmc_of_parse(struct mmc_host *host)
|
|||||||
if (of_find_property(np, "non-removable", &len)) {
|
if (of_find_property(np, "non-removable", &len)) {
|
||||||
host->caps |= MMC_CAP_NONREMOVABLE;
|
host->caps |= MMC_CAP_NONREMOVABLE;
|
||||||
} else {
|
} else {
|
||||||
if (of_property_read_bool(np, "cd-inverted"))
|
cd_cap_invert = of_property_read_bool(np, "cd-inverted");
|
||||||
cap_invert = true;
|
|
||||||
else
|
|
||||||
cap_invert = false;
|
|
||||||
|
|
||||||
if (of_find_property(np, "broken-cd", &len))
|
if (of_find_property(np, "broken-cd", &len))
|
||||||
host->caps |= MMC_CAP_NEEDS_POLL;
|
host->caps |= MMC_CAP_NEEDS_POLL;
|
||||||
|
|
||||||
ret = mmc_gpiod_request_cd(host, "cd", 0, true,
|
ret = mmc_gpiod_request_cd(host, "cd", 0, true,
|
||||||
0, &gpio_invert);
|
0, &cd_gpio_invert);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret == -EPROBE_DEFER)
|
if (ret == -EPROBE_DEFER)
|
||||||
return ret;
|
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
|
* both inverted, the end result is that the CD line is
|
||||||
* not inverted.
|
* not inverted.
|
||||||
*/
|
*/
|
||||||
if (cap_invert ^ gpio_invert)
|
if (cd_cap_invert ^ cd_gpio_invert)
|
||||||
host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
|
host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse Write Protection */
|
/* Parse Write Protection */
|
||||||
if (of_property_read_bool(np, "wp-inverted"))
|
ro_cap_invert = of_property_read_bool(np, "wp-inverted");
|
||||||
cap_invert = true;
|
|
||||||
else
|
|
||||||
cap_invert = false;
|
|
||||||
|
|
||||||
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) {
|
||||||
if (ret == -EPROBE_DEFER)
|
if (ret == -EPROBE_DEFER)
|
||||||
goto out;
|
goto out;
|
||||||
@ -414,7 +409,7 @@ int mmc_of_parse(struct mmc_host *host)
|
|||||||
dev_info(host->parent, "Got WP GPIO\n");
|
dev_info(host->parent, "Got WP GPIO\n");
|
||||||
|
|
||||||
/* See the comment on CD inversion above */
|
/* 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;
|
host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
|
||||||
|
|
||||||
if (of_find_property(np, "cap-sd-highspeed", &len))
|
if (of_find_property(np, "cap-sd-highspeed", &len))
|
||||||
|
Loading…
Reference in New Issue
Block a user