[v3,0/3] mmc: Introduce support for WP GPIO in the core SDHCI
mbox series

Message ID 20190212140737.8668-1-thomas.petazzoni@bootlin.com
Headers show
  • mmc: Introduce support for WP GPIO in the core SDHCI
Related show


Thomas Petazzoni Feb. 12, 2019, 2:07 p.m. UTC

While doing the bring up of a Zynq 7000 platform where the WP signal
of a SD slot is connected to a regular GPIO rather than through the
SDHCI WP pin, I realized that the GPIO described by wp-gpios was
properly requested, but it was in fact not used at all.

Indeed, the SDHCI core implements sdhci_check_ro() by:

 - Calling a controller-specific ->get_ro() callback if it exists. A
   few controller-specific drivers implement this, but not
   sdhci-of-arasan, which is used on Zynq 7000.

 - Using the SDHCI_PRESENT_STATE register, which reports the state of
   the SDHCI interface WP pin, and obvisouly not the state of a
   separate WP GPIO.

This patch series therefore changes sdhci_check_ro() to behave like
sdhci_get_cd(): use a GPIO first if available, and if not, fallback to
using the SDHCI_PRESENT_STATE register. Indeed, if there's a wp-gpios
described in the DT, it quite certainly indicates that the SDHCI WP
signal is not used, and the WP GPIO should be used instead.

As part of this series, two SDHCI drivers are modified to no longer
implement their custom ->get_ro() hook, since the core SDHCI now does
the right thing with the WP GPIO.

Changes since v2:
- Don't change the argument passed to sdhci_check_ro(), as requested
  by Adrian Hunter.
- Collect Acked-by from Adrian Hunter on PATCH 2 and PATCH 3.

Changes since v1:
- Call the ->get_ro() callback before using the WP GPIO in the core,
  as suggested by Adrian Hunter.
- Fix typoes in commit logs.
- Collect Reviewed-by/Tested-by/Acked-by tags.

Best regards,


Thomas Petazzoni (3):
  mmc: sdhci: use WP GPIO in sdhci_check_ro()
  mmc: sdhci-omap: drop ->get_ro() implementation
  mmc: sdhci-tegra: drop ->get_ro() implementation

 drivers/mmc/host/sdhci-omap.c  | 1 -
 drivers/mmc/host/sdhci-tegra.c | 9 ---------
 drivers/mmc/host/sdhci.c       | 2 ++
 3 files changed, 2 insertions(+), 10 deletions(-)


Adrian Hunter Feb. 12, 2019, 2:09 p.m. UTC | #1
On 12/02/19 4:07 PM, Thomas Petazzoni wrote:
> Even though SDHCI controllers may have a dedicated WP pin that can be
> queried using the SDHCI_PRESENT_STATE register, some platforms may
> chose to use a separate regular GPIO to route the WP signal. Such a
> GPIO is typically represented using the wp-gpios property in the
> Device Tree.
> Unfortunately, the current sdhci_check_ro() function does not make use
> of such GPIO when available: it either uses a host controller specific
> ->get_ro() operation, or uses the SDHCI_PRESENT_STATE. Several host
> controller specific ->get_ro() functions are implemented just to check
> a WP GPIO state.
> Instead of pushing this to more controller-specific implementations,
> let's handle this in the core SDHCI code, just like it is already done
> for the CD GPIO in sdhci_get_cd().
> The below patch simply changes sdhci_check_ro() to use the value of
> the WP GPIO if available.
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>

Acked-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
> Changes since v2:
>  - As suggested by Adrian Hunter, keep the argument of
>    sdhci_check_ro() as it is: a "struct sdhci_host*"
> Changes since v1:
>  - As suggested by Adrian Hunter, call the ->get_ro() if it exists
>    before falling back to using mmc_gpio_get_ro(). Indeed, if the
>    controller-specific code has implemented a ->get_ro() callback, it
>    should take precedence over what the SDHCI core does.
>    Due to this change, I have not added Thierry Redding Reviewed-by.
>  - Fix typo in the commit log noticed by Thierry Redding.
> ---
>  drivers/mmc/host/sdhci.c | 2 ++
>  1 file changed, 2 insertions(+)
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index df05352b6a4a..b3444d12c8c8 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -2033,6 +2033,8 @@ static int sdhci_check_ro(struct sdhci_host *host)
>  		is_readonly = 0;
>  	else if (host->ops->get_ro)
>  		is_readonly = host->ops->get_ro(host);
> +	else if (mmc_can_gpio_ro(host->mmc))
> +		is_readonly = mmc_gpio_get_ro(host->mmc);
>  	else
>  		is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)