Re: [PATCH] gpio: OF: Parse MMC-specific CD and WP properties

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Nov 26, 2018 at 03:17:14PM +0100, Linus Walleij wrote:
> When retrieveing CD (card detect) and WP (write protect)
> GPIO handles from the device tree, make sure to assign
> them active low by default unless the "cd-inverted" or
> "wp-inverted" properties are set. These properties mean
> that respective signal is active HIGH since the SDHCI
> specification stipulates that this kind of signals
> should be treated as active LOW.
> 
> If the twocell GPIO flag is also specified as active
> low, well that's nice and we will silently ignore the
> tautological specification.
> 
> If however the GPIO line is specified as active low
> in the GPIO flasg cell and "cd-inverted" or "wp-inverted"
> is also specified, the latter takes precedence and we
> print a warning.
> 
> The current effect on the MMC slot-gpio core are as
> follows:
> 
> For CD GPIOs: no effect. The current code in
> mmc/core/host.c calls mmc_gpiod_request_cd() with
> the "override_active_level" argument set to true,
> which means that whatever the GPIO descriptor
> thinks about active low/high will be ignored, the
> core will use the MMC_CAP2_CD_ACTIVE_HIGH to keep
> track of this and reads the raw value from the
> GPIO descriptor, totally bypassing gpiolibs inversion
> semantics. I plan to clean this up at a later point
> passing the handling of inversion semantics over
> to gpiolib, so this patch prepares the ground for
> that.
> 
> Fow WP GPIOs: this is probably fixing a bug, because
> the code in mmc/core/host.c calls mmc_gpiod_request_ro()
> with the "override_active_level" argument set to false,
> which means it will respect the inversion semantics of
> the gpiolib and ignore the MMC_CAP2_RO_ACTIVE_HIGH
> flag for everyone using this through device tree.
> However the code in host.c confusingly goes to great
> lengths setting up the MMC_CAP2_RO_ACTIVE_HIGH flag
> from the GPIO descriptor and by reading the "wp-inverted"
> property of the node. As far as I can tell this is all
> in vain and the inversion is broken: device trees that
> use "wp-inverted" do not work as intended, instead the
> only way to actually get inversion on a line is by
> setting the second cell flag to GPIO_ACTIVE_HIGH (which
> will be the default) or GPIO_ACTIVE_LOW if they want
> the proper MMC semantics. Presumably all device trees do
> this right but we need to parse and handle this properly.
> 
> Cc: linux-mmc@xxxxxxxxxxxxxxx
> Cc: linux-gpio@xxxxxxxxxxxxxxx
> Cc: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx>
> Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx>

At least for qemu this doeesn't work: It causes boots from mmc to
fail for vexpress-a9 and vexpress-a15 machine types. Reason is that
OF_GPIO_ACTIVE_LOW was so far not set for those machine types, but
it is now set by the code below. This may also affect other machines -
hard to say, since there are lots of boot failures in -next right now,
and the symptoms are often similar.

Since the lack of {cd,wp}-inverted now always sets OF_GPIO_ACTIVE_LOW,
I suspect that all active-high configurations which do not also explicitly
specify {cd,wp}-inverted in their devicetree files are now broken.

Guenter

> ---
>  drivers/gpio/gpiolib-of.c | 39 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
> index 7f1260c78270..50a390251410 100644
> --- a/drivers/gpio/gpiolib-of.c
> +++ b/drivers/gpio/gpiolib-of.c
> @@ -57,6 +57,45 @@ 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)) {
> +		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;
> +			}
> +		}
> +		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;
> +			}
> +		}
> +	}
>  	/*
>  	 * Some GPIO fixed regulator quirks.
>  	 * Note that active low is the default.



[Index of Archives]     [Linux Memonry Technology]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux