diff mbox

mmc: mmci: switch the driver to using gpio descriptors

Message ID 1397550786-8146-1-git-send-email-linus.walleij@linaro.org
State New
Headers show

Commit Message

Linus Walleij April 15, 2014, 8:33 a.m. UTC
The next step in modernization of GPIO is to let drivers handle
descriptors rather than integer numbers representing GPIO pins,
akin to how clocks or regulators are already handled today.

This patch makes the MMCI driver use GPIO descriptos in the
core code with fallback code using the platform data if that
is not possible. After all platforms with MMCI have been
migrated to use descriptors, the platform data entries for
GPIO pins can be removed.

Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Hi Russell,Ulf: there is no hurry to do these changes (only used
for my very corner-case MMCI PL181 experiments) but it's the
desired direction to use descriptors for GPIOs going forward.
I can rebase this on top of Ulf's patch stack any time, no
problem.
---
 drivers/mmc/host/mmci.c | 76 ++++++++++++++++++++++++-------------------------
 drivers/mmc/host/mmci.h |  4 +--
 2 files changed, 40 insertions(+), 40 deletions(-)

Comments

Alexander Shiyan April 15, 2014, 8:43 a.m. UTC | #1
Tue, 15 Apr 2014 10:33:06 +0200 от Linus Walleij <linus.walleij@linaro.org>:
> The next step in modernization of GPIO is to let drivers handle
> descriptors rather than integer numbers representing GPIO pins,
> akin to how clocks or regulators are already handled today.
> 
> This patch makes the MMCI driver use GPIO descriptos in the
> core code with fallback code using the platform data if that
> is not possible. After all platforms with MMCI have been
> migrated to use descriptors, the platform data entries for
> GPIO pins can be removed.
> 
> Cc: Alexandre Courbot <gnurou@gmail.com>
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Cc: Russell King <linux@arm.linux.org.uk>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Hi Russell,Ulf: there is no hurry to do these changes (only used
> for my very corner-case MMCI PL181 experiments) but it's the
> desired direction to use descriptors for GPIOs going forward.
> I can rebase this on top of Ulf's patch stack any time, no
> problem.
> ---
...
>  static void mmci_dt_populate_generic_pdata(struct device_node *np,
> -					struct mmci_platform_data *pdata)
> +					   struct mmci_platform_data *pdata)
>  {
>  	int bus_width = 0;
>  
> -	pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0);
> -	pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0);
> -
>  	if (of_get_property(np, "cd-inverted", NULL))
>  		pdata->cd_invert = true;

You could even eliminate "cd-inverted" property for DT case.

---
Alexandre Courbot April 16, 2014, 6:30 a.m. UTC | #2
On Tue, Apr 15, 2014 at 5:33 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> The next step in modernization of GPIO is to let drivers handle
> descriptors rather than integer numbers representing GPIO pins,
> akin to how clocks or regulators are already handled today.
>
> This patch makes the MMCI driver use GPIO descriptos in the

s/descriptos/descriptors

> core code with fallback code using the platform data if that
> is not possible. After all platforms with MMCI have been
> migrated to use descriptors, the platform data entries for
> GPIO pins can be removed.
>
> Cc: Alexandre Courbot <gnurou@gmail.com>
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Cc: Russell King <linux@arm.linux.org.uk>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Hi Russell,Ulf: there is no hurry to do these changes (only used
> for my very corner-case MMCI PL181 experiments) but it's the
> desired direction to use descriptors for GPIOs going forward.
> I can rebase this on top of Ulf's patch stack any time, no
> problem.
> ---
>  drivers/mmc/host/mmci.c | 76 ++++++++++++++++++++++++-------------------------
>  drivers/mmc/host/mmci.h |  4 +--
>  2 files changed, 40 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index 771c60ab4a32..f84e39a5d592 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -26,7 +26,7 @@
>  #include <linux/amba/bus.h>
>  #include <linux/clk.h>
>  #include <linux/scatterlist.h>
> -#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/of_gpio.h>
>  #include <linux/regulator/consumer.h>
>  #include <linux/dmaengine.h>
> @@ -1330,10 +1330,10 @@ static int mmci_get_ro(struct mmc_host *mmc)
>  {
>         struct mmci_host *host = mmc_priv(mmc);
>
> -       if (host->gpio_wp == -ENOSYS)
> +       if (IS_ERR(host->gpio_wp))
>                 return -ENOSYS;
>
> -       return gpio_get_value_cansleep(host->gpio_wp);
> +       return gpiod_get_value_cansleep(host->gpio_wp);
>  }
>
>  static int mmci_get_cd(struct mmc_host *mmc)
> @@ -1342,13 +1342,13 @@ static int mmci_get_cd(struct mmc_host *mmc)
>         struct mmci_platform_data *plat = host->plat;
>         unsigned int status;
>
> -       if (host->gpio_cd == -ENOSYS) {
> +       if (IS_ERR(host->gpio_cd)) {
>                 if (!plat->status)
>                         return 1; /* Assume always present */
>
>                 status = plat->status(mmc_dev(host->mmc));
>         } else
> -               status = !!gpio_get_value_cansleep(host->gpio_cd)
> +               status = !!gpiod_get_value_cansleep(host->gpio_cd)

I think you don't even need that "!!" anymore since gpiolib now clamps
the returned values.

>                         ^ plat->cd_invert;
>
>         /*
> @@ -1412,13 +1412,10 @@ static struct mmc_host_ops mmci_ops = {
>
>  #ifdef CONFIG_OF
>  static void mmci_dt_populate_generic_pdata(struct device_node *np,
> -                                       struct mmci_platform_data *pdata)
> +                                          struct mmci_platform_data *pdata)
>  {
>         int bus_width = 0;
>
> -       pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0);
> -       pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0);
> -
>         if (of_get_property(np, "cd-inverted", NULL))
>                 pdata->cd_invert = true;
>         else
> @@ -1494,9 +1491,20 @@ static int mmci_probe(struct amba_device *dev,
>         host = mmc_priv(mmc);
>         host->mmc = mmc;
>
> -       host->gpio_wp = -ENOSYS;
> -       host->gpio_cd = -ENOSYS;
> +       host->gpio_wp = ERR_PTR(-ENOSYS);
> +       host->gpio_cd = ERR_PTR(-ENOSYS);
>         host->gpio_cd_irq = -1;
> +       /*
> +        * TODO: when we finally get rid of all platform data for all
> +        * platforms deploying the MMCI block, we can delete the
> +        * gpio_to_desc() calls.
> +        */
> +       host->gpio_wp = gpiod_get(&dev->dev, "wp");
> +       if (IS_ERR(host->gpio_wp) && gpio_is_valid(plat->gpio_wp))
> +               host->gpio_wp = gpio_to_desc(plat->gpio_wp);

I think you will probably want to also call gpio_request() before
gpio_to_desc, or you may end up using a non-requested GPIO.

> +       host->gpio_cd = gpiod_get(&dev->dev, "cd");
> +       if (IS_ERR(host->gpio_cd) && gpio_is_valid(plat->gpio_wp))
> +               host->gpio_cd = gpio_to_desc(plat->gpio_cd);

Same here.

Nice patch anyway. Once the fallback integer GPIO code can be removed,
this will result in more removed lines than added ones, which is what
I like about these gpiod conversion patches! :)

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ulf Hansson April 16, 2014, 7:31 a.m. UTC | #3
On 15 April 2014 10:33, Linus Walleij <linus.walleij@linaro.org> wrote:
> The next step in modernization of GPIO is to let drivers handle
> descriptors rather than integer numbers representing GPIO pins,
> akin to how clocks or regulators are already handled today.
>
> This patch makes the MMCI driver use GPIO descriptos in the
> core code with fallback code using the platform data if that
> is not possible. After all platforms with MMCI have been
> migrated to use descriptors, the platform data entries for
> GPIO pins can be removed.
>
> Cc: Alexandre Courbot <gnurou@gmail.com>
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Cc: Russell King <linux@arm.linux.org.uk>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Hi Russell,Ulf: there is no hurry to do these changes (only used
> for my very corner-case MMCI PL181 experiments) but it's the
> desired direction to use descriptors for GPIOs going forward.
> I can rebase this on top of Ulf's patch stack any time, no
> problem.

If you rebase it on top of my patch stack - I can resend the pull
request I sent a few days ago and include this one!?

Kind regards
Ulf Hansson

> ---
>  drivers/mmc/host/mmci.c | 76 ++++++++++++++++++++++++-------------------------
>  drivers/mmc/host/mmci.h |  4 +--
>  2 files changed, 40 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index 771c60ab4a32..f84e39a5d592 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -26,7 +26,7 @@
>  #include <linux/amba/bus.h>
>  #include <linux/clk.h>
>  #include <linux/scatterlist.h>
> -#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/of_gpio.h>
>  #include <linux/regulator/consumer.h>
>  #include <linux/dmaengine.h>
> @@ -1330,10 +1330,10 @@ static int mmci_get_ro(struct mmc_host *mmc)
>  {
>         struct mmci_host *host = mmc_priv(mmc);
>
> -       if (host->gpio_wp == -ENOSYS)
> +       if (IS_ERR(host->gpio_wp))
>                 return -ENOSYS;
>
> -       return gpio_get_value_cansleep(host->gpio_wp);
> +       return gpiod_get_value_cansleep(host->gpio_wp);
>  }
>
>  static int mmci_get_cd(struct mmc_host *mmc)
> @@ -1342,13 +1342,13 @@ static int mmci_get_cd(struct mmc_host *mmc)
>         struct mmci_platform_data *plat = host->plat;
>         unsigned int status;
>
> -       if (host->gpio_cd == -ENOSYS) {
> +       if (IS_ERR(host->gpio_cd)) {
>                 if (!plat->status)
>                         return 1; /* Assume always present */
>
>                 status = plat->status(mmc_dev(host->mmc));
>         } else
> -               status = !!gpio_get_value_cansleep(host->gpio_cd)
> +               status = !!gpiod_get_value_cansleep(host->gpio_cd)
>                         ^ plat->cd_invert;
>
>         /*
> @@ -1412,13 +1412,10 @@ static struct mmc_host_ops mmci_ops = {
>
>  #ifdef CONFIG_OF
>  static void mmci_dt_populate_generic_pdata(struct device_node *np,
> -                                       struct mmci_platform_data *pdata)
> +                                          struct mmci_platform_data *pdata)
>  {
>         int bus_width = 0;
>
> -       pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0);
> -       pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0);
> -
>         if (of_get_property(np, "cd-inverted", NULL))
>                 pdata->cd_invert = true;
>         else
> @@ -1494,9 +1491,20 @@ static int mmci_probe(struct amba_device *dev,
>         host = mmc_priv(mmc);
>         host->mmc = mmc;
>
> -       host->gpio_wp = -ENOSYS;
> -       host->gpio_cd = -ENOSYS;
> +       host->gpio_wp = ERR_PTR(-ENOSYS);
> +       host->gpio_cd = ERR_PTR(-ENOSYS);
>         host->gpio_cd_irq = -1;
> +       /*
> +        * TODO: when we finally get rid of all platform data for all
> +        * platforms deploying the MMCI block, we can delete the
> +        * gpio_to_desc() calls.
> +        */
> +       host->gpio_wp = gpiod_get(&dev->dev, "wp");
> +       if (IS_ERR(host->gpio_wp) && gpio_is_valid(plat->gpio_wp))
> +               host->gpio_wp = gpio_to_desc(plat->gpio_wp);
> +       host->gpio_cd = gpiod_get(&dev->dev, "cd");
> +       if (IS_ERR(host->gpio_cd) && gpio_is_valid(plat->gpio_wp))
> +               host->gpio_cd = gpio_to_desc(plat->gpio_cd);
>
>         host->hw_designer = amba_manf(dev);
>         host->hw_revision = amba_rev(dev);
> @@ -1616,17 +1624,13 @@ static int mmci_probe(struct amba_device *dev,
>         writel(0, host->base + MMCIMASK1);
>         writel(0xfff, host->base + MMCICLEAR);
>
> -       if (plat->gpio_cd == -EPROBE_DEFER) {
> +       if (PTR_ERR(host->gpio_cd) == -EPROBE_DEFER) {
>                 ret = -EPROBE_DEFER;
>                 goto err_gpio_cd;
>         }
> -       if (gpio_is_valid(plat->gpio_cd)) {
> -               ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
> -               if (ret == 0)
> -                       ret = gpio_direction_input(plat->gpio_cd);
> -               if (ret == 0)
> -                       host->gpio_cd = plat->gpio_cd;
> -               else if (ret != -ENOSYS)
> +       if (!IS_ERR(host->gpio_cd)) {
> +               ret = gpiod_direction_input(host->gpio_cd);
> +               if (ret < 0 && ret != -ENOSYS)
>                         goto err_gpio_cd;
>
>                 /*
> @@ -1636,28 +1640,24 @@ static int mmci_probe(struct amba_device *dev,
>                  * for the inverted case) so we request triggers on both
>                  * edges.
>                  */
> -               ret = request_any_context_irq(gpio_to_irq(plat->gpio_cd),
> +               ret = request_any_context_irq(gpiod_to_irq(host->gpio_cd),
>                                 mmci_cd_irq,
>                                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>                                 DRIVER_NAME " (cd)", host);
>                 if (ret >= 0)
> -                       host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd);
> +                       host->gpio_cd_irq = gpiod_to_irq(host->gpio_cd);
>         }
> -       if (plat->gpio_wp == -EPROBE_DEFER) {
> +       if (PTR_ERR(host->gpio_wp) == -EPROBE_DEFER) {
>                 ret = -EPROBE_DEFER;
>                 goto err_gpio_wp;
>         }
> -       if (gpio_is_valid(plat->gpio_wp)) {
> -               ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)");
> -               if (ret == 0)
> -                       ret = gpio_direction_input(plat->gpio_wp);
> -               if (ret == 0)
> -                       host->gpio_wp = plat->gpio_wp;
> -               else if (ret != -ENOSYS)
> +       if (!IS_ERR(host->gpio_wp)) {
> +               ret = gpiod_direction_input(host->gpio_wp);
> +               if (ret < 0 && ret != -ENOSYS)
>                         goto err_gpio_wp;
>         }
>
> -       if ((host->plat->status || host->gpio_cd != -ENOSYS)
> +       if ((host->plat->status || !IS_ERR(host->gpio_cd))
>             && host->gpio_cd_irq < 0)
>                 mmc->caps |= MMC_CAP_NEEDS_POLL;
>
> @@ -1696,13 +1696,13 @@ static int mmci_probe(struct amba_device *dev,
>   irq0_free:
>         free_irq(dev->irq[0], host);
>   unmap:
> -       if (host->gpio_wp != -ENOSYS)
> -               gpio_free(host->gpio_wp);
> +       if (!IS_ERR(host->gpio_wp))
> +               gpiod_put(host->gpio_wp);
>   err_gpio_wp:
>         if (host->gpio_cd_irq >= 0)
>                 free_irq(host->gpio_cd_irq, host);
> -       if (host->gpio_cd != -ENOSYS)
> -               gpio_free(host->gpio_cd);
> +       if (!IS_ERR(host->gpio_cd))
> +               gpiod_put(host->gpio_cd);
>   err_gpio_cd:
>         iounmap(host->base);
>   clk_disable:
> @@ -1741,12 +1741,12 @@ static int mmci_remove(struct amba_device *dev)
>                 if (!host->singleirq)
>                         free_irq(dev->irq[1], host);
>
> -               if (host->gpio_wp != -ENOSYS)
> -                       gpio_free(host->gpio_wp);
> +               if (!IS_ERR(host->gpio_wp))
> +                       gpiod_put(host->gpio_wp);
>                 if (host->gpio_cd_irq >= 0)
>                         free_irq(host->gpio_cd_irq, host);
> -               if (host->gpio_cd != -ENOSYS)
> -                       gpio_free(host->gpio_cd);
> +               if (!IS_ERR(host->gpio_cd))
> +                       gpiod_put(host->gpio_cd);
>
>                 iounmap(host->base);
>                 clk_disable_unprepare(host->clk);
> diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
> index 58b1b8896bf2..b1c1de28201f 100644
> --- a/drivers/mmc/host/mmci.h
> +++ b/drivers/mmc/host/mmci.h
> @@ -176,8 +176,8 @@ struct mmci_host {
>         struct mmc_data         *data;
>         struct mmc_host         *mmc;
>         struct clk              *clk;
> -       int                     gpio_cd;
> -       int                     gpio_wp;
> +       struct gpio_desc        *gpio_cd;
> +       struct gpio_desc        *gpio_wp;
>         int                     gpio_cd_irq;
>         bool                    singleirq;
>
> --
> 1.9.0
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij April 23, 2014, 6:59 a.m. UTC | #4
On Wed, Apr 16, 2014 at 9:31 AM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> On 15 April 2014 10:33, Linus Walleij <linus.walleij@linaro.org> wrote:
>> The next step in modernization of GPIO is to let drivers handle
>> descriptors rather than integer numbers representing GPIO pins,
>> akin to how clocks or regulators are already handled today.
>>
>> This patch makes the MMCI driver use GPIO descriptos in the
>> core code with fallback code using the platform data if that
>> is not possible. After all platforms with MMCI have been
>> migrated to use descriptors, the platform data entries for
>> GPIO pins can be removed.
>>
>> Cc: Alexandre Courbot <gnurou@gmail.com>
>> Cc: Ulf Hansson <ulf.hansson@linaro.org>
>> Cc: Russell King <linux@arm.linux.org.uk>
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
>> ---
>> Hi Russell,Ulf: there is no hurry to do these changes (only used
>> for my very corner-case MMCI PL181 experiments) but it's the
>> desired direction to use descriptors for GPIOs going forward.
>> I can rebase this on top of Ulf's patch stack any time, no
>> problem.
>
> If you rebase it on top of my patch stack - I can resend the pull
> request I sent a few days ago and include this one!?

There is no hurry. I'd let Russell think about your recent patches
first and I will keep this patch on my watchlist until things
settle down.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 771c60ab4a32..f84e39a5d592 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -26,7 +26,7 @@ 
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
 #include <linux/scatterlist.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/of_gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/dmaengine.h>
@@ -1330,10 +1330,10 @@  static int mmci_get_ro(struct mmc_host *mmc)
 {
 	struct mmci_host *host = mmc_priv(mmc);
 
-	if (host->gpio_wp == -ENOSYS)
+	if (IS_ERR(host->gpio_wp))
 		return -ENOSYS;
 
-	return gpio_get_value_cansleep(host->gpio_wp);
+	return gpiod_get_value_cansleep(host->gpio_wp);
 }
 
 static int mmci_get_cd(struct mmc_host *mmc)
@@ -1342,13 +1342,13 @@  static int mmci_get_cd(struct mmc_host *mmc)
 	struct mmci_platform_data *plat = host->plat;
 	unsigned int status;
 
-	if (host->gpio_cd == -ENOSYS) {
+	if (IS_ERR(host->gpio_cd)) {
 		if (!plat->status)
 			return 1; /* Assume always present */
 
 		status = plat->status(mmc_dev(host->mmc));
 	} else
-		status = !!gpio_get_value_cansleep(host->gpio_cd)
+		status = !!gpiod_get_value_cansleep(host->gpio_cd)
 			^ plat->cd_invert;
 
 	/*
@@ -1412,13 +1412,10 @@  static struct mmc_host_ops mmci_ops = {
 
 #ifdef CONFIG_OF
 static void mmci_dt_populate_generic_pdata(struct device_node *np,
-					struct mmci_platform_data *pdata)
+					   struct mmci_platform_data *pdata)
 {
 	int bus_width = 0;
 
-	pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0);
-	pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0);
-
 	if (of_get_property(np, "cd-inverted", NULL))
 		pdata->cd_invert = true;
 	else
@@ -1494,9 +1491,20 @@  static int mmci_probe(struct amba_device *dev,
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
 
-	host->gpio_wp = -ENOSYS;
-	host->gpio_cd = -ENOSYS;
+	host->gpio_wp = ERR_PTR(-ENOSYS);
+	host->gpio_cd = ERR_PTR(-ENOSYS);
 	host->gpio_cd_irq = -1;
+	/*
+	 * TODO: when we finally get rid of all platform data for all
+	 * platforms deploying the MMCI block, we can delete the
+	 * gpio_to_desc() calls.
+	 */
+	host->gpio_wp = gpiod_get(&dev->dev, "wp");
+	if (IS_ERR(host->gpio_wp) && gpio_is_valid(plat->gpio_wp))
+		host->gpio_wp = gpio_to_desc(plat->gpio_wp);
+	host->gpio_cd = gpiod_get(&dev->dev, "cd");
+	if (IS_ERR(host->gpio_cd) && gpio_is_valid(plat->gpio_wp))
+		host->gpio_cd = gpio_to_desc(plat->gpio_cd);
 
 	host->hw_designer = amba_manf(dev);
 	host->hw_revision = amba_rev(dev);
@@ -1616,17 +1624,13 @@  static int mmci_probe(struct amba_device *dev,
 	writel(0, host->base + MMCIMASK1);
 	writel(0xfff, host->base + MMCICLEAR);
 
-	if (plat->gpio_cd == -EPROBE_DEFER) {
+	if (PTR_ERR(host->gpio_cd) == -EPROBE_DEFER) {
 		ret = -EPROBE_DEFER;
 		goto err_gpio_cd;
 	}
-	if (gpio_is_valid(plat->gpio_cd)) {
-		ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
-		if (ret == 0)
-			ret = gpio_direction_input(plat->gpio_cd);
-		if (ret == 0)
-			host->gpio_cd = plat->gpio_cd;
-		else if (ret != -ENOSYS)
+	if (!IS_ERR(host->gpio_cd)) {
+		ret = gpiod_direction_input(host->gpio_cd);
+		if (ret < 0 && ret != -ENOSYS)
 			goto err_gpio_cd;
 
 		/*
@@ -1636,28 +1640,24 @@  static int mmci_probe(struct amba_device *dev,
 		 * for the inverted case) so we request triggers on both
 		 * edges.
 		 */
-		ret = request_any_context_irq(gpio_to_irq(plat->gpio_cd),
+		ret = request_any_context_irq(gpiod_to_irq(host->gpio_cd),
 				mmci_cd_irq,
 				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				DRIVER_NAME " (cd)", host);
 		if (ret >= 0)
-			host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd);
+			host->gpio_cd_irq = gpiod_to_irq(host->gpio_cd);
 	}
-	if (plat->gpio_wp == -EPROBE_DEFER) {
+	if (PTR_ERR(host->gpio_wp) == -EPROBE_DEFER) {
 		ret = -EPROBE_DEFER;
 		goto err_gpio_wp;
 	}
-	if (gpio_is_valid(plat->gpio_wp)) {
-		ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)");
-		if (ret == 0)
-			ret = gpio_direction_input(plat->gpio_wp);
-		if (ret == 0)
-			host->gpio_wp = plat->gpio_wp;
-		else if (ret != -ENOSYS)
+	if (!IS_ERR(host->gpio_wp)) {
+		ret = gpiod_direction_input(host->gpio_wp);
+		if (ret < 0 && ret != -ENOSYS)
 			goto err_gpio_wp;
 	}
 
-	if ((host->plat->status || host->gpio_cd != -ENOSYS)
+	if ((host->plat->status || !IS_ERR(host->gpio_cd))
 	    && host->gpio_cd_irq < 0)
 		mmc->caps |= MMC_CAP_NEEDS_POLL;
 
@@ -1696,13 +1696,13 @@  static int mmci_probe(struct amba_device *dev,
  irq0_free:
 	free_irq(dev->irq[0], host);
  unmap:
-	if (host->gpio_wp != -ENOSYS)
-		gpio_free(host->gpio_wp);
+	if (!IS_ERR(host->gpio_wp))
+		gpiod_put(host->gpio_wp);
  err_gpio_wp:
 	if (host->gpio_cd_irq >= 0)
 		free_irq(host->gpio_cd_irq, host);
-	if (host->gpio_cd != -ENOSYS)
-		gpio_free(host->gpio_cd);
+	if (!IS_ERR(host->gpio_cd))
+		gpiod_put(host->gpio_cd);
  err_gpio_cd:
 	iounmap(host->base);
  clk_disable:
@@ -1741,12 +1741,12 @@  static int mmci_remove(struct amba_device *dev)
 		if (!host->singleirq)
 			free_irq(dev->irq[1], host);
 
-		if (host->gpio_wp != -ENOSYS)
-			gpio_free(host->gpio_wp);
+		if (!IS_ERR(host->gpio_wp))
+			gpiod_put(host->gpio_wp);
 		if (host->gpio_cd_irq >= 0)
 			free_irq(host->gpio_cd_irq, host);
-		if (host->gpio_cd != -ENOSYS)
-			gpio_free(host->gpio_cd);
+		if (!IS_ERR(host->gpio_cd))
+			gpiod_put(host->gpio_cd);
 
 		iounmap(host->base);
 		clk_disable_unprepare(host->clk);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 58b1b8896bf2..b1c1de28201f 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -176,8 +176,8 @@  struct mmci_host {
 	struct mmc_data		*data;
 	struct mmc_host		*mmc;
 	struct clk		*clk;
-	int			gpio_cd;
-	int			gpio_wp;
+	struct gpio_desc	*gpio_cd;
+	struct gpio_desc	*gpio_wp;
 	int			gpio_cd_irq;
 	bool			singleirq;