* [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling
@ 2019-12-11 2:40 Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 1/4] gpio: add gpiod_toggle_active_low() Michał Mirosław
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Michał Mirosław @ 2019-12-11 2:40 UTC (permalink / raw)
To: linux-mmc
Cc: Ulf Hansson, Adrian Hunter, Bartosz Golaszewski, Linus Walleij,
linux-gpio, linux-kernel
This series removes convoluted handling of inverted CD and WP lines in
SD/MMC host drivers when using GPIOs.
First patch adds an API: gpiod_toggle_active_low() that switches line
inversion flag in the gpiod structure. Next two patches modify MMC
host's WP and CD initialization to apply all the inversions onto
gpiod's active-low flag. Final patch removes now-unused argument from
init functions.
x86 allyesconfig build-tested.
v2: move argument removal in sdhci-esdhc-imx.c to last patch
Michał Mirosław (4):
gpio: add gpiod_toggle_active_low()
mmc: rework wp-gpio handling
mmc: rework cd-gpio handling
mmc: remove mmc_gpiod_request_*(invert_gpio)
drivers/gpio/gpiolib-of.c | 21 -------------------
drivers/gpio/gpiolib.c | 11 ++++++++++
drivers/mmc/core/host.c | 33 ++++++++----------------------
drivers/mmc/core/slot-gpio.c | 31 ++++++++++------------------
drivers/mmc/host/davinci_mmc.c | 4 ++--
drivers/mmc/host/mmc_spi.c | 4 ++--
drivers/mmc/host/mmci.c | 4 ++--
drivers/mmc/host/pxamci.c | 12 +++++------
drivers/mmc/host/s3cmci.c | 4 ++--
drivers/mmc/host/sdhci-acpi.c | 2 +-
drivers/mmc/host/sdhci-esdhc-imx.c | 15 +++++++-------
drivers/mmc/host/sdhci-pci-core.c | 4 ++--
drivers/mmc/host/sdhci-sirf.c | 2 +-
drivers/mmc/host/sdhci-spear.c | 2 +-
drivers/mmc/host/tmio_mmc_core.c | 2 +-
include/linux/gpio/consumer.h | 7 +++++++
include/linux/mmc/slot-gpio.h | 5 ++---
17 files changed, 67 insertions(+), 96 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/4] mmc: rework wp-gpio handling
2019-12-11 2:40 [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 1/4] gpio: add gpiod_toggle_active_low() Michał Mirosław
@ 2019-12-11 2:40 ` Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 3/4] mmc: rework cd-gpio handling Michał Mirosław
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Michał Mirosław @ 2019-12-11 2:40 UTC (permalink / raw)
To: linux-mmc
Cc: Ulf Hansson, Linus Walleij, Bartosz Golaszewski, Adrian Hunter,
linux-gpio, linux-kernel
Use MMC_CAP2_RO_ACTIVE_HIGH flag as indicator if GPIO line is to be
inverted compared to DT/platform-specified polarity. The flag is not
used after init in GPIO mode anyway. No functional changes intended.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
v2: moved argument removal in sdhci-esdhc-imx to the right patch
---
drivers/gpio/gpiolib-of.c | 4 ----
drivers/mmc/core/host.c | 11 ++++-------
drivers/mmc/core/slot-gpio.c | 3 +++
drivers/mmc/host/pxamci.c | 8 ++++----
drivers/mmc/host/sdhci-esdhc-imx.c | 3 ++-
5 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index dc27b1a88e93..b0b77e52e261 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -120,10 +120,6 @@ static void of_gpio_flags_quirks(struct device_node *np,
if (of_property_read_bool(np, "cd-inverted"))
*flags ^= OF_GPIO_ACTIVE_LOW;
}
- if (!strcmp(propname, "wp-gpios")) {
- if (of_property_read_bool(np, "wp-inverted"))
- *flags ^= OF_GPIO_ACTIVE_LOW;
- }
}
/*
* Some GPIO fixed regulator quirks.
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 105b7a7c0251..b3484def0a8b 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -176,7 +176,6 @@ int mmc_of_parse(struct mmc_host *host)
u32 bus_width, drv_type, cd_debounce_delay_ms;
int ret;
bool cd_cap_invert, cd_gpio_invert = false;
- bool ro_cap_invert, ro_gpio_invert = false;
if (!dev || !dev_fwnode(dev))
return 0;
@@ -255,9 +254,11 @@ int mmc_of_parse(struct mmc_host *host)
}
/* Parse Write Protection */
- ro_cap_invert = device_property_read_bool(dev, "wp-inverted");
- ret = mmc_gpiod_request_ro(host, "wp", 0, 0, &ro_gpio_invert);
+ if (device_property_read_bool(dev, "wp-inverted"))
+ host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+
+ ret = mmc_gpiod_request_ro(host, "wp", 0, 0, NULL);
if (!ret)
dev_info(host->parent, "Got WP GPIO\n");
else if (ret != -ENOENT && ret != -ENOSYS)
@@ -266,10 +267,6 @@ int mmc_of_parse(struct mmc_host *host)
if (device_property_read_bool(dev, "disable-wp"))
host->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
- /* See the comment on CD inversion above */
- if (ro_cap_invert ^ ro_gpio_invert)
- host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
-
if (device_property_read_bool(dev, "cap-sd-highspeed"))
host->caps |= MMC_CAP_SD_HIGHSPEED;
if (device_property_read_bool(dev, "cap-mmc-highspeed"))
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index da2596c5fa28..582ec3d720f6 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -241,6 +241,9 @@ int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id,
return ret;
}
+ if (host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH)
+ gpiod_toggle_active_low(desc);
+
if (gpio_invert)
*gpio_invert = !gpiod_is_active_low(desc);
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 024acc1b0a2e..b2bbcb09a49e 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -740,16 +740,16 @@ static int pxamci_probe(struct platform_device *pdev)
goto out;
}
+ if (!host->pdata->gpio_card_ro_invert)
+ mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+
ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL);
if (ret && ret != -ENOENT) {
dev_err(dev, "Failed requesting gpio_ro\n");
goto out;
}
- if (!ret) {
+ 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)
host->pdata->init(dev, pxamci_detect_irq, mmc);
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 1c988d6a2433..dccb4df46512 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1381,13 +1381,14 @@ static int sdhci_esdhc_imx_probe_nondt(struct platform_device *pdev,
host->mmc->parent->platform_data);
/* write_protect */
if (boarddata->wp_type == ESDHC_WP_GPIO) {
+ host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+
err = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0, NULL);
if (err) {
dev_err(mmc_dev(host->mmc),
"failed to request write-protect gpio!\n");
return err;
}
- host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
}
/* card_detect */
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 1/4] gpio: add gpiod_toggle_active_low()
2019-12-11 2:40 [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling Michał Mirosław
@ 2019-12-11 2:40 ` Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 2/4] mmc: rework wp-gpio handling Michał Mirosław
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Michał Mirosław @ 2019-12-11 2:40 UTC (permalink / raw)
To: linux-mmc
Cc: Ulf Hansson, Linus Walleij, Bartosz Golaszewski, linux-gpio,
linux-kernel, Adrian Hunter
Add possibility to toggle active-low flag of a gpio descriptor. This is
useful for compatibility code, where defaults are inverted vs DT gpio
flags or the active-low flag is taken from elsewhere.
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/gpio/gpiolib.c | 11 +++++++++++
include/linux/gpio/consumer.h | 7 +++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 9913886ede90..6130691e2047 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -3363,6 +3363,17 @@ int gpiod_is_active_low(const struct gpio_desc *desc)
}
EXPORT_SYMBOL_GPL(gpiod_is_active_low);
+/**
+ * gpiod_toggle_active_low - toggle whether a GPIO is active-low or not
+ * @desc: the gpio descriptor to change
+ */
+void gpiod_toggle_active_low(struct gpio_desc *desc)
+{
+ VALIDATE_DESC_VOID(desc);
+ change_bit(FLAG_ACTIVE_LOW, &desc->flags);
+}
+EXPORT_SYMBOL_GPL(gpiod_toggle_active_low);
+
/* I/O calls are only valid after configuration completed; the relevant
* "is this a valid GPIO" error checks should already have been done.
*
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index 5215fdba6b9a..bf2d017dd7b7 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -158,6 +158,7 @@ int gpiod_set_raw_array_value_cansleep(unsigned int array_size,
int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
int gpiod_set_transitory(struct gpio_desc *desc, bool transitory);
+void gpiod_toggle_active_low(struct gpio_desc *desc);
int gpiod_is_active_low(const struct gpio_desc *desc);
int gpiod_cansleep(const struct gpio_desc *desc);
@@ -483,6 +484,12 @@ static inline int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
return -ENOSYS;
}
+static inline void gpiod_toggle_active_low(struct gpio_desc *desc)
+{
+ /* GPIO can never have been requested */
+ WARN_ON(desc);
+}
+
static inline int gpiod_is_active_low(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 4/4] mmc: remove mmc_gpiod_request_*(invert_gpio)
2019-12-11 2:40 [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling Michał Mirosław
` (2 preceding siblings ...)
2019-12-11 2:40 ` [PATCH v2 3/4] mmc: rework cd-gpio handling Michał Mirosław
@ 2019-12-11 2:40 ` Michał Mirosław
2019-12-18 14:01 ` [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling Ulf Hansson
4 siblings, 0 replies; 6+ messages in thread
From: Michał Mirosław @ 2019-12-11 2:40 UTC (permalink / raw)
To: linux-mmc
Cc: Adrian Hunter, Bartosz Golaszewski, Linus Walleij, linux-gpio,
linux-kernel, Ulf Hansson
Now, that invert_gpio arguments are unused, remove them.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/mmc/core/host.c | 5 ++---
drivers/mmc/core/slot-gpio.c | 15 ++-------------
drivers/mmc/host/davinci_mmc.c | 4 ++--
drivers/mmc/host/mmc_spi.c | 4 ++--
drivers/mmc/host/mmci.c | 4 ++--
drivers/mmc/host/pxamci.c | 4 ++--
drivers/mmc/host/s3cmci.c | 4 ++--
drivers/mmc/host/sdhci-acpi.c | 2 +-
drivers/mmc/host/sdhci-esdhc-imx.c | 4 ++--
drivers/mmc/host/sdhci-pci-core.c | 4 ++--
drivers/mmc/host/sdhci-sirf.c | 2 +-
drivers/mmc/host/sdhci-spear.c | 2 +-
drivers/mmc/host/tmio_mmc_core.c | 2 +-
include/linux/mmc/slot-gpio.h | 5 ++---
14 files changed, 24 insertions(+), 37 deletions(-)
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index e655dc1b5b85..c8768726d925 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -232,8 +232,7 @@ int mmc_of_parse(struct mmc_host *host)
host->caps |= MMC_CAP_NEEDS_POLL;
ret = mmc_gpiod_request_cd(host, "cd", 0, false,
- cd_debounce_delay_ms * 1000,
- NULL);
+ cd_debounce_delay_ms * 1000);
if (!ret)
dev_info(host->parent, "Got CD GPIO\n");
else if (ret != -ENOENT && ret != -ENOSYS)
@@ -245,7 +244,7 @@ int mmc_of_parse(struct mmc_host *host)
if (device_property_read_bool(dev, "wp-inverted"))
host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
- ret = mmc_gpiod_request_ro(host, "wp", 0, 0, NULL);
+ ret = mmc_gpiod_request_ro(host, "wp", 0, 0);
if (!ret)
dev_info(host->parent, "Got WP GPIO\n");
else if (ret != -ENOENT && ret != -ENOSYS)
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 303e825ecfd8..05e907451df9 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -160,8 +160,6 @@ EXPORT_SYMBOL(mmc_gpio_set_cd_isr);
* @idx: index of the GPIO to obtain in the consumer
* @override_active_level: ignore %GPIO_ACTIVE_LOW flag
* @debounce: debounce time in microseconds
- * @gpio_invert: will return whether the GPIO line is inverted or not, set
- * to NULL to ignore
*
* Note that this must be called prior to mmc_add_host()
* otherwise the caller must also call mmc_gpiod_request_cd_irq().
@@ -170,7 +168,7 @@ EXPORT_SYMBOL(mmc_gpio_set_cd_isr);
*/
int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id,
unsigned int idx, bool override_active_level,
- unsigned int debounce, bool *gpio_invert)
+ unsigned int debounce)
{
struct mmc_gpio *ctx = host->slot.handler_priv;
struct gpio_desc *desc;
@@ -194,9 +192,6 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id,
if (host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH)
gpiod_toggle_active_low(desc);
- if (gpio_invert)
- *gpio_invert = !gpiod_is_active_low(desc);
-
ctx->cd_gpio = desc;
return 0;
@@ -217,14 +212,11 @@ EXPORT_SYMBOL(mmc_can_gpio_cd);
* @con_id: function within the GPIO consumer
* @idx: index of the GPIO to obtain in the consumer
* @debounce: debounce time in microseconds
- * @gpio_invert: will return whether the GPIO line is inverted or not,
- * set to NULL to ignore
*
* Returns zero on success, else an error.
*/
int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id,
- unsigned int idx,
- unsigned int debounce, bool *gpio_invert)
+ unsigned int idx, unsigned int debounce)
{
struct mmc_gpio *ctx = host->slot.handler_priv;
struct gpio_desc *desc;
@@ -243,9 +235,6 @@ int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id,
if (host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH)
gpiod_toggle_active_low(desc);
- if (gpio_invert)
- *gpio_invert = !gpiod_is_active_low(desc);
-
ctx->ro_gpio = desc;
return 0;
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index ebfaeb33bc8c..f01fecd75833 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -1174,13 +1174,13 @@ static int mmc_davinci_parse_pdata(struct mmc_host *mmc)
mmc->caps |= pdata->caps;
/* Register a cd gpio, if there is not one, enable polling */
- ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL);
+ ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0);
if (ret == -EPROBE_DEFER)
return ret;
else if (ret)
mmc->caps |= MMC_CAP_NEEDS_POLL;
- ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL);
+ ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0);
if (ret == -EPROBE_DEFER)
return ret;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 74c6cfbf9172..76a67a292b16 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1421,7 +1421,7 @@ static int mmc_spi_probe(struct spi_device *spi)
* Index 0 is card detect
* Old boardfiles were specifying 1 ms as debounce
*/
- status = mmc_gpiod_request_cd(mmc, NULL, 0, false, 1000, NULL);
+ status = mmc_gpiod_request_cd(mmc, NULL, 0, false, 1000);
if (status == -EPROBE_DEFER)
goto fail_add_host;
if (!status) {
@@ -1436,7 +1436,7 @@ static int mmc_spi_probe(struct spi_device *spi)
mmc_detect_change(mmc, 0);
/* Index 1 is write protect/read only */
- status = mmc_gpiod_request_ro(mmc, NULL, 1, 0, NULL);
+ status = mmc_gpiod_request_ro(mmc, NULL, 1, 0);
if (status == -EPROBE_DEFER)
goto fail_add_host;
if (!status)
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 40e72c30ea84..7c5c24f9f8fe 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -2062,11 +2062,11 @@ static int mmci_probe(struct amba_device *dev,
* silently of these do not exist
*/
if (!np) {
- ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL);
+ ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0);
if (ret == -EPROBE_DEFER)
goto clk_disable;
- ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL);
+ ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0);
if (ret == -EPROBE_DEFER)
goto clk_disable;
}
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index b2bbcb09a49e..d38982abd26d 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -734,7 +734,7 @@ static int pxamci_probe(struct platform_device *pdev)
}
/* FIXME: should we pass detection delay to debounce? */
- ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL);
+ ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0);
if (ret && ret != -ENOENT) {
dev_err(dev, "Failed requesting gpio_cd\n");
goto out;
@@ -743,7 +743,7 @@ static int pxamci_probe(struct platform_device *pdev)
if (!host->pdata->gpio_card_ro_invert)
mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
- ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL);
+ ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0);
if (ret && ret != -ENOENT) {
dev_err(dev, "Failed requesting gpio_ro\n");
goto out;
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index bce9c33bc4b5..1e616ae56b13 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1505,14 +1505,14 @@ static int s3cmci_probe_pdata(struct s3cmci_host *host)
mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
/* If we get -ENOENT we have no card detect GPIO line */
- ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL);
+ ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0);
if (ret != -ENOENT) {
dev_err(&pdev->dev, "error requesting GPIO for CD %d\n",
ret);
return ret;
}
- ret = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0, NULL);
+ ret = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0);
if (ret != -ENOENT) {
dev_err(&pdev->dev, "error requesting GPIO for WP %d\n",
ret);
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 105e73d4a3b9..dd908577a9dc 100644
--- a/drivers/mmc/host/sdhci-acpi.c
+++ b/drivers/mmc/host/sdhci-acpi.c
@@ -752,7 +752,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) {
bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL);
- err = mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL);
+ err = mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0);
if (err) {
if (err == -EPROBE_DEFER)
goto err_free;
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index dccb4df46512..e9d408870f4f 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1383,7 +1383,7 @@ static int sdhci_esdhc_imx_probe_nondt(struct platform_device *pdev,
if (boarddata->wp_type == ESDHC_WP_GPIO) {
host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
- err = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0, NULL);
+ err = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0);
if (err) {
dev_err(mmc_dev(host->mmc),
"failed to request write-protect gpio!\n");
@@ -1394,7 +1394,7 @@ static int sdhci_esdhc_imx_probe_nondt(struct platform_device *pdev,
/* card_detect */
switch (boarddata->cd_type) {
case ESDHC_CD_GPIO:
- err = mmc_gpiod_request_cd(host->mmc, "cd", 0, false, 0, NULL);
+ err = mmc_gpiod_request_cd(host->mmc, "cd", 0, false, 0);
if (err) {
dev_err(mmc_dev(host->mmc),
"failed to request card-detect gpio!\n");
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
index acefb76b4e15..53496111883d 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -1983,12 +1983,12 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
if (slot->cd_idx >= 0) {
ret = mmc_gpiod_request_cd(host->mmc, "cd", slot->cd_idx,
- slot->cd_override_level, 0, NULL);
+ slot->cd_override_level, 0);
if (ret && ret != -EPROBE_DEFER)
ret = mmc_gpiod_request_cd(host->mmc, NULL,
slot->cd_idx,
slot->cd_override_level,
- 0, NULL);
+ 0);
if (ret == -EPROBE_DEFER)
goto remove;
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index e43143223320..f4b05dd6c20a 100644
--- a/drivers/mmc/host/sdhci-sirf.c
+++ b/drivers/mmc/host/sdhci-sirf.c
@@ -194,7 +194,7 @@ static int sdhci_sirf_probe(struct platform_device *pdev)
* We must request the IRQ after sdhci_add_host(), as the tasklet only
* gets setup in sdhci_add_host() and we oops.
*/
- ret = mmc_gpiod_request_cd(host->mmc, "cd", 0, false, 0, NULL);
+ ret = mmc_gpiod_request_cd(host->mmc, "cd", 0, false, 0);
if (ret == -EPROBE_DEFER)
goto err_request_cd;
if (!ret)
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 916b5b09c3d1..141dd3847411 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -98,7 +98,7 @@ static int sdhci_probe(struct platform_device *pdev)
* It is optional to use GPIOs for sdhci card detection. If we
* find a descriptor using slot GPIO, we use it.
*/
- ret = mmc_gpiod_request_cd(host->mmc, "cd", 0, false, 0, NULL);
+ ret = mmc_gpiod_request_cd(host->mmc, "cd", 0, false, 0);
if (ret == -EPROBE_DEFER)
goto disable_clk;
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index c4a1d49fbea4..d68bc4e3891d 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -1181,7 +1181,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
* Look for a card detect GPIO, if it fails with anything
* else than a probe deferral, just live without it.
*/
- ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL);
+ ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0);
if (ret == -EPROBE_DEFER)
return ret;
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
index 0de3d7c016cd..4ae2f2908f99 100644
--- a/include/linux/mmc/slot-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -17,10 +17,9 @@ int mmc_gpio_get_ro(struct mmc_host *host);
int mmc_gpio_get_cd(struct mmc_host *host);
int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id,
unsigned int idx, bool override_active_level,
- unsigned int debounce, bool *gpio_invert);
+ unsigned int debounce);
int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id,
- unsigned int idx,
- unsigned int debounce, bool *gpio_invert);
+ unsigned int idx, unsigned int debounce);
void mmc_gpio_set_cd_isr(struct mmc_host *host,
irqreturn_t (*isr)(int irq, void *dev_id));
int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on);
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 3/4] mmc: rework cd-gpio handling
2019-12-11 2:40 [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 1/4] gpio: add gpiod_toggle_active_low() Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 2/4] mmc: rework wp-gpio handling Michał Mirosław
@ 2019-12-11 2:40 ` Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 4/4] mmc: remove mmc_gpiod_request_*(invert_gpio) Michał Mirosław
2019-12-18 14:01 ` [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling Ulf Hansson
4 siblings, 0 replies; 6+ messages in thread
From: Michał Mirosław @ 2019-12-11 2:40 UTC (permalink / raw)
To: linux-mmc
Cc: Adrian Hunter, Bartosz Golaszewski, Linus Walleij, linux-gpio,
linux-kernel, Ulf Hansson
There are a few places around the code that invert inverted and possibly
inverted CD line. That's really confusing. Squash them all into one
place in mmc_gpiod_request_cd(). MMC_CAP2_CD_ACTIVE_HIGH is used
analogously to WP line: in GPIO mode it is used only at probe time to
switch polarity, for native mode it is left as is.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/gpio/gpiolib-of.c | 17 -----------------
drivers/mmc/core/host.c | 21 ++++-----------------
drivers/mmc/core/slot-gpio.c | 17 ++++++++---------
3 files changed, 12 insertions(+), 43 deletions(-)
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index b0b77e52e261..8310da48ba01 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -104,23 +104,6 @@ static void of_gpio_flags_quirks(struct device_node *np,
enum of_gpio_flags *flags,
int index)
{
- /*
- * Handle MMC "cd-inverted" and "wp-inverted" semantics.
- */
- if (IS_ENABLED(CONFIG_MMC)) {
- /*
- * Active low is the default according to the
- * SDHCI specification and the device tree
- * bindings. However the code in the current
- * kernel was written such that the phandle
- * flags were always respected, and "cd-inverted"
- * would invert the flag from the device phandle.
- */
- if (!strcmp(propname, "cd-gpios")) {
- if (of_property_read_bool(np, "cd-inverted"))
- *flags ^= OF_GPIO_ACTIVE_LOW;
- }
- }
/*
* Some GPIO fixed regulator quirks.
* Note that active low is the default.
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index b3484def0a8b..e655dc1b5b85 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -175,7 +175,6 @@ int mmc_of_parse(struct mmc_host *host)
struct device *dev = host->parent;
u32 bus_width, drv_type, cd_debounce_delay_ms;
int ret;
- bool cd_cap_invert, cd_gpio_invert = false;
if (!dev || !dev_fwnode(dev))
return 0;
@@ -218,10 +217,12 @@ int mmc_of_parse(struct mmc_host *host)
*/
/* Parse Card Detection */
+
if (device_property_read_bool(dev, "non-removable")) {
host->caps |= MMC_CAP_NONREMOVABLE;
} else {
- cd_cap_invert = device_property_read_bool(dev, "cd-inverted");
+ if (device_property_read_bool(dev, "cd-inverted"))
+ host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
if (device_property_read_u32(dev, "cd-debounce-delay-ms",
&cd_debounce_delay_ms))
@@ -232,25 +233,11 @@ int mmc_of_parse(struct mmc_host *host)
ret = mmc_gpiod_request_cd(host, "cd", 0, false,
cd_debounce_delay_ms * 1000,
- &cd_gpio_invert);
+ NULL);
if (!ret)
dev_info(host->parent, "Got CD GPIO\n");
else if (ret != -ENOENT && ret != -ENOSYS)
return ret;
-
- /*
- * There are two ways to flag that the CD line is inverted:
- * through the cd-inverted flag and by the GPIO line itself
- * being inverted from the GPIO subsystem. This is a leftover
- * from the times when the GPIO subsystem did not make it
- * possible to flag a line as inverted.
- *
- * If the capability on the host AND the GPIO line are
- * both inverted, the end result is that the CD line is
- * not inverted.
- */
- if (cd_cap_invert ^ cd_gpio_invert)
- host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
}
/* Parse Write Protection */
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 582ec3d720f6..303e825ecfd8 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -19,7 +19,6 @@
struct mmc_gpio {
struct gpio_desc *ro_gpio;
struct gpio_desc *cd_gpio;
- bool override_cd_active_level;
irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id);
char *ro_label;
char *cd_label;
@@ -80,13 +79,6 @@ int mmc_gpio_get_cd(struct mmc_host *host)
return -ENOSYS;
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 cansleep ?
gpiod_get_value_cansleep(ctx->cd_gpio) :
gpiod_get_value(ctx->cd_gpio);
@@ -194,10 +186,17 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id,
ctx->cd_debounce_delay_ms = debounce / 1000;
}
+ /* override forces default (active-low) polarity ... */
+ if (override_active_level && !gpiod_is_active_low(desc))
+ gpiod_toggle_active_low(desc);
+
+ /* ... or active-high */
+ if (host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH)
+ gpiod_toggle_active_low(desc);
+
if (gpio_invert)
*gpio_invert = !gpiod_is_active_low(desc);
- ctx->override_cd_active_level = override_active_level;
ctx->cd_gpio = desc;
return 0;
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling
2019-12-11 2:40 [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling Michał Mirosław
` (3 preceding siblings ...)
2019-12-11 2:40 ` [PATCH v2 4/4] mmc: remove mmc_gpiod_request_*(invert_gpio) Michał Mirosław
@ 2019-12-18 14:01 ` Ulf Hansson
4 siblings, 0 replies; 6+ messages in thread
From: Ulf Hansson @ 2019-12-18 14:01 UTC (permalink / raw)
To: Michał Mirosław
Cc: linux-mmc, Adrian Hunter, Bartosz Golaszewski, Linus Walleij,
open list:GPIO SUBSYSTEM, Linux Kernel Mailing List
On Wed, 11 Dec 2019 at 03:40, Michał Mirosław <mirq-linux@rere.qmqm.pl> wrote:
>
> This series removes convoluted handling of inverted CD and WP lines in
> SD/MMC host drivers when using GPIOs.
>
> First patch adds an API: gpiod_toggle_active_low() that switches line
> inversion flag in the gpiod structure. Next two patches modify MMC
> host's WP and CD initialization to apply all the inversions onto
> gpiod's active-low flag. Final patch removes now-unused argument from
> init functions.
>
> x86 allyesconfig build-tested.
>
> v2: move argument removal in sdhci-esdhc-imx.c to last patch
>
> Michał Mirosław (4):
> gpio: add gpiod_toggle_active_low()
> mmc: rework wp-gpio handling
> mmc: rework cd-gpio handling
> mmc: remove mmc_gpiod_request_*(invert_gpio)
>
> drivers/gpio/gpiolib-of.c | 21 -------------------
> drivers/gpio/gpiolib.c | 11 ++++++++++
> drivers/mmc/core/host.c | 33 ++++++++----------------------
> drivers/mmc/core/slot-gpio.c | 31 ++++++++++------------------
> drivers/mmc/host/davinci_mmc.c | 4 ++--
> drivers/mmc/host/mmc_spi.c | 4 ++--
> drivers/mmc/host/mmci.c | 4 ++--
> drivers/mmc/host/pxamci.c | 12 +++++------
> drivers/mmc/host/s3cmci.c | 4 ++--
> drivers/mmc/host/sdhci-acpi.c | 2 +-
> drivers/mmc/host/sdhci-esdhc-imx.c | 15 +++++++-------
> drivers/mmc/host/sdhci-pci-core.c | 4 ++--
> drivers/mmc/host/sdhci-sirf.c | 2 +-
> drivers/mmc/host/sdhci-spear.c | 2 +-
> drivers/mmc/host/tmio_mmc_core.c | 2 +-
> include/linux/gpio/consumer.h | 7 +++++++
> include/linux/mmc/slot-gpio.h | 5 ++---
> 17 files changed, 67 insertions(+), 96 deletions(-)
>
Applied for next, thanks!
Kind regards
Uffe
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-12-18 14:01 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-11 2:40 [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 1/4] gpio: add gpiod_toggle_active_low() Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 2/4] mmc: rework wp-gpio handling Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 3/4] mmc: rework cd-gpio handling Michał Mirosław
2019-12-11 2:40 ` [PATCH v2 4/4] mmc: remove mmc_gpiod_request_*(invert_gpio) Michał Mirosław
2019-12-18 14:01 ` [PATCH v2 0/4] mmc: simplify WP/CD GPIO handling Ulf Hansson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).