summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorEvan Green <evgreen@chromium.org>2018-05-25 12:25:23 -0700
committerUlf Hansson <ulf.hansson@linaro.org>2018-05-29 12:24:26 +0200
commit52af318c93e970d26c5522eab23ef84fdcb417e1 (patch)
treef971ff2041bde54c46d870236872cc977acb0722 /drivers/mmc
parentfb8617e1ee4d4057c76730e2f8376ece45663c34 (diff)
downloadlinux-52af318c93e970d26c5522eab23ef84fdcb417e1.tar.bz2
mmc: Allow non-sleeping GPIO cd
This change uses the appropriate _cansleep or non-sleeping API for reading GPIO card detect state. This allows users with GPIOs that never sleep to avoid a warning when certain quirks are present. The sdhci controller has an SDHCI_QUIRK_NO_CARD_NO_RESET, which indicates that a controller will not reset properly if no card is inserted. With this quirk enabled, mmc_get_cd_gpio is called in several places with a spinlock held and interrupts disabled. gpiod_get_raw_value_cansleep is not happy with this situation, and throws out a warning. For boards that a) use controllers that have this quirk, and b) wire card detect up to a GPIO that doesn't sleep, this is a spurious warning. This change silences that warning, at the cost of pushing this problem down to users that have sleeping GPIOs and controllers with this quirk. Signed-off-by: Evan Green <evgreen@chromium.org> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/slot-gpio.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 56559351d2e1..ef05e0039378 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -79,15 +79,22 @@ EXPORT_SYMBOL(mmc_gpio_get_ro);
int mmc_gpio_get_cd(struct mmc_host *host)
{
struct mmc_gpio *ctx = host->slot.handler_priv;
+ int cansleep;
if (!ctx || !ctx->cd_gpio)
return -ENOSYS;
- if (ctx->override_cd_active_level)
- return !gpiod_get_raw_value_cansleep(ctx->cd_gpio) ^
- !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH);
+ cansleep = gpiod_cansleep(ctx->cd_gpio);
+ if (ctx->override_cd_active_level) {
+ int value = cansleep ?
+ gpiod_get_raw_value_cansleep(ctx->cd_gpio) :
+ gpiod_get_raw_value(ctx->cd_gpio);
+ return !value ^ !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH);
+ }
- return gpiod_get_value_cansleep(ctx->cd_gpio);
+ return cansleep ?
+ gpiod_get_value_cansleep(ctx->cd_gpio) :
+ gpiod_get_value(ctx->cd_gpio);
}
EXPORT_SYMBOL(mmc_gpio_get_cd);