mmc: core: Rework cd-gpio handling
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>
Wed, 11 Dec 2019 02:40:56 +0000 (03:40 +0100)
committerUlf Hansson <ulf.hansson@linaro.org>
Wed, 18 Dec 2019 12:36:53 +0000 (13:36 +0100)
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>
Link: https://lore.kernel.org/r/db189b715596d63caf8c6a088bddc71dd69a879b.1576031637.git.mirq-linux@rere.qmqm.pl
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/gpio/gpiolib-of.c
drivers/mmc/core/host.c
drivers/mmc/core/slot-gpio.c

index b0b77e5..8310da4 100644 (file)
@@ -105,23 +105,6 @@ static void of_gpio_flags_quirks(struct device_node *np,
                                 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.
         */
index b3484de..e655dc1 100644 (file)
@@ -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 */
index 582ec3d..303e825 100644 (file)
@@ -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;