Use gpio_find_by_chip_name() to find the GPIO pins as they can
be dynamically allocated on various gpio_chips.

Note that we don't want to touch the platform data as it can
now specify the GPIO offset on a named gpio_chip.

This removes the need to use callbacks to set the GPIO pins
in platform data.

Cc: Chris Ball <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Rajendra Nayak <[email protected]>
Signed-off-by: Tony Lindgren <[email protected]>
---
 arch/arm/mach-omap2/hsmmc.c           |    3 +
 arch/arm/mach-omap2/hsmmc.h           |    5 ++
 arch/arm/plat-omap/include/plat/mmc.h |    3 +
 drivers/gpio/gpio-twl4030.c           |    2 +
 drivers/mmc/host/omap_hsmmc.c         |  109 +++++++++++++++++++++------------
 5 files changed, 82 insertions(+), 40 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index a97876d..dda88f7 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -323,7 +323,10 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
 
        mmc->get_context_loss_count = hsmmc_get_context_loss;
 
+       mmc->slots[0].gpiochip_cd = c->gpiochip_cd;
        mmc->slots[0].switch_pin = c->gpio_cd;
+
+       mmc->slots[0].gpiochip_wp = c->gpiochip_wp;
        mmc->slots[0].gpio_wp = c->gpio_wp;
 
        mmc->slots[0].remux = c->remux;
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 07831cc..ffbb78d 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -22,8 +22,13 @@ struct omap2_hsmmc_info {
        bool    no_off_init;    /* no power off when not in MMC sleep state */
        bool    vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
        bool    deferred;       /* mmc needs a deferred probe */
+
+       char    *gpiochip_cd;   /* Optional gpiochip for gpio_cd */
        int     gpio_cd;        /* or -EINVAL */
+
+       char    *gpiochip_wp;   /* Optional gpiochip for gpio_wp */
        int     gpio_wp;        /* or -EINVAL */
+
        char    *name;          /* or NULL for default */
        struct platform_device *pdev;   /* mmc controller instance */
        int     ocr_mask;       /* temporary HACK */
diff --git a/arch/arm/plat-omap/include/plat/mmc.h 
b/arch/arm/plat-omap/include/plat/mmc.h
index f75946c..cbfbdc3 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -130,7 +130,10 @@ struct omap_mmc_platform_data {
 #define HSMMC_HAS_UPDATED_RESET        (1 << 1)
                unsigned features;
 
+               char *gpiochip_cd;              /* optional gpiochip for card 
detect */
                int switch_pin;                 /* gpio (card detect) */
+
+               char *gpiochip_wp;              /* optional gpiochip for write 
protect */
                int gpio_wp;                    /* gpio (write protect) */
 
                int (*set_bus_mode)(struct device *dev, int slot, int bus_mode);
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index b8b4f22..d0f266c 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -391,6 +391,7 @@ static int __devinit gpio_twl4030_debounce(u32 debounce, u8 
mmc_cd)
 }
 
 static int gpio_twl4030_remove(struct platform_device *pdev);
+static struct platform_driver gpio_twl4030_driver;
 
 static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
 {
@@ -430,6 +431,7 @@ no_irqs:
                                pdata->debounce, pdata->mmc_cd,
                                ret);
 
+       twl_gpiochip.label = gpio_twl4030_driver.driver.name;
        twl_gpiochip.base = pdata->gpio_base;
        twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
        twl_gpiochip.dev = &pdev->dev;
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index fd0c661..1aa2420 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -176,6 +176,8 @@ struct omap_hsmmc_host {
        int                     use_dma, dma_ch;
        int                     dma_line_tx, dma_line_rx;
        int                     slot_id;
+       int                     gpio_cd;
+       int                     gpio_wp;
        int                     got_dbclk;
        int                     response_busy;
        int                     context_loss;
@@ -192,26 +194,29 @@ struct omap_hsmmc_host {
 
 static int omap_hsmmc_card_detect(struct device *dev, int slot)
 {
-       struct omap_mmc_platform_data *mmc = dev->platform_data;
+       struct omap_hsmmc_host *host =
+               platform_get_drvdata(to_platform_device(dev));
 
        /* NOTE: assumes card detect signal is active-low */
-       return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
+       return !gpio_get_value_cansleep(host->gpio_cd);
 }
 
 static int omap_hsmmc_get_wp(struct device *dev, int slot)
 {
-       struct omap_mmc_platform_data *mmc = dev->platform_data;
+       struct omap_hsmmc_host *host =
+               platform_get_drvdata(to_platform_device(dev));
 
        /* NOTE: assumes write protect signal is active-high */
-       return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
+       return gpio_get_value_cansleep(host->gpio_wp);
 }
 
 static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
 {
-       struct omap_mmc_platform_data *mmc = dev->platform_data;
+       struct omap_hsmmc_host *host =
+               platform_get_drvdata(to_platform_device(dev));
 
        /* NOTE: assumes card detect signal is active-low */
-       return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
+       return !gpio_get_value_cansleep(host->gpio_cd);
 }
 
 #ifdef CONFIG_PM
@@ -497,55 +502,80 @@ static inline int omap_hsmmc_have_reg(void)
 
 #endif
 
-static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata)
+static int omap_hsmmc_gpio_init(struct omap_hsmmc_host *host)
 {
-       int ret;
-
-       if (gpio_is_valid(pdata->slots[0].switch_pin)) {
-               if (pdata->slots[0].cover)
-                       pdata->slots[0].get_cover_state =
+       struct omap_mmc_platform_data *pdata = host->pdata;
+       struct omap_mmc_slot_data *slot = &pdata->slots[0];
+       int gpio, ret;
+
+       gpio = slot->switch_pin;
+       if (slot->gpiochip_cd)
+               gpio = gpio_find_by_chip_name(slot->gpiochip_cd, gpio);
+       if (gpio_is_valid(gpio)) {
+               if (slot->cover)
+                       slot->get_cover_state =
                                        omap_hsmmc_get_cover_state;
                else
-                       pdata->slots[0].card_detect = omap_hsmmc_card_detect;
-               pdata->slots[0].card_detect_irq =
-                               gpio_to_irq(pdata->slots[0].switch_pin);
-               ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd");
+                       slot->card_detect = omap_hsmmc_card_detect;
+               slot->card_detect_irq =
+                               gpio_to_irq(gpio);
+               ret = gpio_request(gpio, "mmc_cd");
                if (ret)
                        return ret;
-               ret = gpio_direction_input(pdata->slots[0].switch_pin);
+               ret = gpio_direction_input(gpio);
                if (ret)
                        goto err_free_sp;
-       } else
-               pdata->slots[0].switch_pin = -EINVAL;
+               host->gpio_cd = gpio;
+       } else {
+               if (slot->gpiochip_cd) {
+                       pr_warning("MMC %s card detect GPIO chip %s 
unavailable\n",
+                               slot->name, slot->gpiochip_cd);
+                       ret = -ENODEV;
+                       goto err_free_sp;
+               }
+               host->gpio_cd = -EINVAL;
+       }
 
-       if (gpio_is_valid(pdata->slots[0].gpio_wp)) {
-               pdata->slots[0].get_ro = omap_hsmmc_get_wp;
-               ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp");
+       gpio = slot->gpio_wp;
+       if (slot->gpiochip_wp)
+               gpio = gpio_find_by_chip_name(slot->gpiochip_wp, gpio);
+       if (gpio_is_valid(gpio)) {
+               slot->get_ro = omap_hsmmc_get_wp;
+               ret = gpio_request(gpio, "mmc_wp");
                if (ret)
                        goto err_free_cd;
-               ret = gpio_direction_input(pdata->slots[0].gpio_wp);
+               ret = gpio_direction_input(gpio);
                if (ret)
                        goto err_free_wp;
-       } else
-               pdata->slots[0].gpio_wp = -EINVAL;
+               host->gpio_wp = gpio;
+       } else {
+               if (slot->gpiochip_wp) {
+                       pr_warning("MMC %s write protect GPIO chip %s 
unavailable\n",
+                               slot->name, slot->gpiochip_wp);
+                       ret = -ENODEV;
+                       goto err_free_wp;
+               }
+               host->gpio_wp = -EINVAL;
+       }
 
        return 0;
 
 err_free_wp:
-       gpio_free(pdata->slots[0].gpio_wp);
+       if (gpio_is_valid(host->gpio_wp))
+               gpio_free(host->gpio_wp);
 err_free_cd:
-       if (gpio_is_valid(pdata->slots[0].switch_pin))
+       if (gpio_is_valid(host->gpio_cd))
 err_free_sp:
-               gpio_free(pdata->slots[0].switch_pin);
+               gpio_free(host->gpio_cd);
        return ret;
 }
 
-static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata)
+static void omap_hsmmc_gpio_free(struct omap_hsmmc_host *host)
 {
-       if (gpio_is_valid(pdata->slots[0].gpio_wp))
-               gpio_free(pdata->slots[0].gpio_wp);
-       if (gpio_is_valid(pdata->slots[0].switch_pin))
-               gpio_free(pdata->slots[0].switch_pin);
+       if (gpio_is_valid(host->gpio_wp))
+               gpio_free(host->gpio_wp);
+       if (gpio_is_valid(host->gpio_cd))
+               gpio_free(host->gpio_cd);
 }
 
 /*
@@ -1876,10 +1906,6 @@ static int __init omap_hsmmc_probe(struct 
platform_device *pdev)
        if (res == NULL)
                return -EBUSY;
 
-       ret = omap_hsmmc_gpio_init(pdata);
-       if (ret)
-               goto err;
-
        mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev);
        if (!mmc) {
                ret = -ENOMEM;
@@ -1903,6 +1929,10 @@ static int __init omap_hsmmc_probe(struct 
platform_device *pdev)
 
        platform_set_drvdata(pdev, host);
 
+       ret = omap_hsmmc_gpio_init(host);
+       if (ret)
+               goto err1;
+
        mmc->ops        = &omap_hsmmc_ops;
 
        /*
@@ -2093,8 +2123,7 @@ err1:
        platform_set_drvdata(pdev, NULL);
        mmc_free_host(mmc);
 err_alloc:
-       omap_hsmmc_gpio_free(pdata);
-err:
+       omap_hsmmc_gpio_free(host);
        release_mem_region(res->start, resource_size(res));
        return ret;
 }
@@ -2125,7 +2154,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
 
                mmc_free_host(host->mmc);
                iounmap(host->base);
-               omap_hsmmc_gpio_free(pdev->dev.platform_data);
+               omap_hsmmc_gpio_free(host);
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to