summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/pxamci.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2018-12-02 11:43:24 +0300
committerUlf Hansson <ulf.hansson@linaro.org>2018-12-17 10:26:24 +0300
commitc914a27c92f91fe2206a035a3d1f9ac8f7ea1fe5 (patch)
treea074f4b404a67161cc4b269e1b6f21c584d204aa /drivers/mmc/host/pxamci.c
parent58e2d877e37018b3804ab2601d9c9ad3fbcc74e7 (diff)
downloadlinux-c914a27c92f91fe2206a035a3d1f9ac8f7ea1fe5.tar.xz
mmc: pxamci: Support getting GPIO descs for RO and WP
This implements the code path for the PXAMCI hostso that it can retrieve GPIO descriptors rather than use the global GPIO numberspace for GPIO lines. If the GPIO descriptor is present, it will take precedence and get used in place of the platform data GPIO number. We move the code around a bit so we request the card detect first and the write protect second. We keep the code setting the host flag for the write protect polarity inversion semantics since the slot GPIO core needs to be refactored to deal with this before we can get rid of this. Cc: Daniel Mack <daniel@zonque.org> Cc: Robert Jarzmik <robert.jarzmik@free.fr> Cc: Bartosz Golaszewski <brgl@bgdev.pl> Cc: Andrea Adami <andrea.adami@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/pxamci.c')
-rw-r--r--drivers/mmc/host/pxamci.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index f7ffbf1676b1..5f06c7902306 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -33,7 +33,6 @@
#include <linux/gpio.h>
#include <linux/gfp.h>
#include <linux/of.h>
-#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <asm/sizes.h>
@@ -63,6 +62,7 @@ struct pxamci_host {
unsigned int imask;
unsigned int power_mode;
unsigned long detect_delay_ms;
+ bool use_ro_gpio;
struct pxamci_platform_data *pdata;
struct mmc_request *mrq;
@@ -432,7 +432,7 @@ static int pxamci_get_ro(struct mmc_host *mmc)
{
struct pxamci_host *host = mmc_priv(mmc);
- if (host->pdata && gpio_is_valid(host->pdata->gpio_card_ro))
+ if (host->use_ro_gpio)
return mmc_gpio_get_ro(mmc);
if (host->pdata && host->pdata->get_ro)
return !!host->pdata->get_ro(mmc_dev(mmc));
@@ -749,25 +749,39 @@ static int pxamci_probe(struct platform_device *pdev)
host->pdata->gpio_power_invert);
}
- if (gpio_is_valid(gpio_ro)) {
+ /* FIXME: should we pass detection delay to debounce? */
+ ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL);
+ if (ret && ret != -ENOENT) {
+ dev_err(dev, "Failed requesting gpio_cd\n");
+ goto out;
+ }
+ if (ret == -ENOENT && gpio_is_valid(gpio_cd)) {
+ ret = mmc_gpio_request_cd(mmc, gpio_cd, 0);
+ if (ret) {
+ dev_err(dev, "Failed requesting gpio_cd %d\n",
+ gpio_cd);
+ }
+ }
+
+ ret = mmc_gpiod_request_ro(mmc, "wp", 0, false, 0, NULL);
+ if (ret && ret != -ENOENT) {
+ dev_err(dev, "Failed requesting gpio_ro\n");
+ goto out;
+ }
+ /* Try platform data instead */
+ if (ret == -ENOENT && gpio_is_valid(gpio_ro)) {
ret = mmc_gpio_request_ro(mmc, gpio_ro);
if (ret) {
dev_err(dev,
"Failed requesting gpio_ro %d\n",
gpio_ro);
goto out;
- } else {
- mmc->caps2 |= host->pdata->gpio_card_ro_invert ?
- 0 : MMC_CAP2_RO_ACTIVE_HIGH;
}
}
-
- if (gpio_is_valid(gpio_cd))
- ret = mmc_gpio_request_cd(mmc, gpio_cd, 0);
- if (ret) {
- dev_err(dev, "Failed requesting gpio_cd %d\n",
- gpio_cd);
- goto out;
+ if (!ret) {
+ host->use_ro_gpio = true;
+ mmc->caps2 |= host->pdata->gpio_card_ro_invert ?
+ 0 : MMC_CAP2_RO_ACTIVE_HIGH;
}
if (host->pdata->init)
@@ -775,7 +789,7 @@ static int pxamci_probe(struct platform_device *pdev)
if (gpio_is_valid(gpio_power) && host->pdata->setpower)
dev_warn(dev, "gpio_power and setpower() both defined\n");
- if (gpio_is_valid(gpio_ro) && host->pdata->get_ro)
+ if (host->use_ro_gpio && host->pdata->get_ro)
dev_warn(dev, "gpio_ro and get_ro() both defined\n");
}