[PATCH] mmc: mmci: switch the driver to using gpio descriptors
Ulf Hansson
ulf.hansson at linaro.org
Wed Apr 16 00:31:12 PDT 2014
On 15 April 2014 10:33, Linus Walleij <linus.walleij at 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 at gmail.com>
> Cc: Ulf Hansson <ulf.hansson at linaro.org>
> Cc: Russell King <linux at arm.linux.org.uk>
> Signed-off-by: Linus Walleij <linus.walleij at 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
>
More information about the linux-arm-kernel
mailing list