diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index fa8044228f0e..a6e1891217e2 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -54,6 +54,7 @@ static struct gpio_desc *of_xlate_and_get_gpiod_flags(struct gpio_chip *chip, } static void of_gpio_flags_quirks(struct device_node *np, + const char *propname, enum of_gpio_flags *flags, int index) { @@ -61,39 +62,21 @@ static void of_gpio_flags_quirks(struct device_node *np, * Handle MMC "cd-inverted" and "wp-inverted" semantics. */ if (IS_ENABLED(CONFIG_MMC)) { - if (of_property_read_bool(np, "cd-gpios")) { - if (of_property_read_bool(np, "cd-inverted")) { - if (*flags & OF_GPIO_ACTIVE_LOW) { - /* "cd-inverted" takes precedence */ - *flags &= ~OF_GPIO_ACTIVE_LOW; - pr_warn("%s GPIO handle specifies CD active low - ignored\n", - of_node_full_name(np)); - } - } else { - /* - * Active low is the default according to the - * SDHCI specification. If the GPIO handle - * specifies the same thing - good. - */ - *flags |= OF_GPIO_ACTIVE_LOW; - } + /* + * 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; } - if (of_property_read_bool(np, "wp-gpios")) { - if (of_property_read_bool(np, "wp-inverted")) { - /* "wp-inverted" takes precedence */ - if (*flags & OF_GPIO_ACTIVE_LOW) { - *flags &= ~OF_GPIO_ACTIVE_LOW; - pr_warn("%s GPIO handle specifies WP active low - ignored\n", - of_node_full_name(np)); - } - } else { - /* - * Active low is the default according to the - * SDHCI specification. If the GPIO handle - * specifies the same thing - good. - */ - *flags |= OF_GPIO_ACTIVE_LOW; - } + if (!strcmp(propname, "wp-gpios")) { + if (of_property_read_bool(np, "wp-inverted")) + *flags ^= OF_GPIO_ACTIVE_LOW; } } /* @@ -213,7 +196,7 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, goto out; if (flags) - of_gpio_flags_quirks(np, flags, index); + of_gpio_flags_quirks(np, propname, flags, index); pr_debug("%s: parsed '%s' property of node '%pOF[%d]' - status (%d)\n", __func__, propname, np, index,