Skip to content

Commit fbd64f9

Browse files
ahunter6storulf
authored andcommitted
mmc: sdhci: Do not invert write-protect twice
mmc_of_parse() reads device property "wp-inverted" and sets MMC_CAP2_RO_ACTIVE_HIGH if it is true. MMC_CAP2_RO_ACTIVE_HIGH is used to invert a write-protect (AKA read-only) GPIO value. sdhci_get_property() also reads "wp-inverted" and sets SDHCI_QUIRK_INVERTED_WRITE_PROTECT which is used to invert the write-protect value as well but also acts upon a value read out from the SDHCI_PRESENT_STATE register. Many drivers call both mmc_of_parse() and sdhci_get_property(), so that both MMC_CAP2_RO_ACTIVE_HIGH and SDHCI_QUIRK_INVERTED_WRITE_PROTECT will be set if the controller has device property "wp-inverted". Amend the logic in sdhci_check_ro() to allow for that possibility, so that the write-protect value is not inverted twice. Also do not invert the value if it is a negative error value. Note that callers treat an error the same as not-write-protected, so the result is functionally the same in that case. Also do not invert the value if sdhci host operation ->get_ro() is used. None of the users of that callback set SDHCI_QUIRK_INVERTED_WRITE_PROTECT directly or indirectly, but two do call mmc_gpio_get_ro(), so leave it to them to deal with that if they ever set SDHCI_QUIRK_INVERTED_WRITE_PROTECT in the future. Fixes: 6d5cd06 ("mmc: sdhci: use WP GPIO in sdhci_check_ro()") Signed-off-by: Adrian Hunter <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent 84bb8d8 commit fbd64f9

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

drivers/mmc/host/sdhci.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,26 +2515,34 @@ EXPORT_SYMBOL_GPL(sdhci_get_cd_nogpio);
25152515

25162516
static int sdhci_check_ro(struct sdhci_host *host)
25172517
{
2518+
bool allow_invert = false;
25182519
unsigned long flags;
25192520
int is_readonly;
25202521

25212522
spin_lock_irqsave(&host->lock, flags);
25222523

2523-
if (host->flags & SDHCI_DEVICE_DEAD)
2524+
if (host->flags & SDHCI_DEVICE_DEAD) {
25242525
is_readonly = 0;
2525-
else if (host->ops->get_ro)
2526+
} else if (host->ops->get_ro) {
25262527
is_readonly = host->ops->get_ro(host);
2527-
else if (mmc_can_gpio_ro(host->mmc))
2528+
} else if (mmc_can_gpio_ro(host->mmc)) {
25282529
is_readonly = mmc_gpio_get_ro(host->mmc);
2529-
else
2530+
/* Do not invert twice */
2531+
allow_invert = !(host->mmc->caps2 & MMC_CAP2_RO_ACTIVE_HIGH);
2532+
} else {
25302533
is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
25312534
& SDHCI_WRITE_PROTECT);
2535+
allow_invert = true;
2536+
}
25322537

25332538
spin_unlock_irqrestore(&host->lock, flags);
25342539

2535-
/* This quirk needs to be replaced by a callback-function later */
2536-
return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
2537-
!is_readonly : is_readonly;
2540+
if (is_readonly >= 0 &&
2541+
allow_invert &&
2542+
(host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT))
2543+
is_readonly = !is_readonly;
2544+
2545+
return is_readonly;
25382546
}
25392547

25402548
#define SAMPLE_COUNT 5

0 commit comments

Comments
 (0)