Currently, platform data is referenced by non init functions.
Copy these fields into locally defined struct pltfm_imx_data.

The code also currently frees imx_data on troubles with
cd_gpio, but returns 0 anyway. Now the code ignores cd_gpio
and wp_gpio if the values cause an error.

Also, allow mx51/mx53 to use platform data.

Signed-off-by: Troy Kisky <troy.ki...@boundarydevices.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c |   79 ++++++++++++++++-------------------
 1 files changed, 36 insertions(+), 43 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c 
b/drivers/mmc/host/sdhci-esdhc-imx.c
index a19967d..ad53041 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -31,7 +31,6 @@
 #define SDHCI_VENDOR_SPEC              0xC0
 #define  SDHCI_VENDOR_SPEC_SDIO_QUIRK  0x00000002
 
-#define ESDHC_FLAG_GPIO_FOR_CD_WP      (1 << 0)
 /*
  * The CMDTYPE of the CMD register (offset 0xE) should be set to
  * "11" when the STOP CMD12 is issued on imx53 to abort one
@@ -48,6 +47,8 @@
 struct pltfm_imx_data {
        int flags;
        u32 scratchpad;
+       unsigned int wp_gpio;
+       unsigned int cd_gpio;
 };
 
 static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, 
int reg)
@@ -67,12 +68,8 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
        u32 val = readl(host->ioaddr + reg);
 
        if (unlikely((reg == SDHCI_PRESENT_STATE)
-                       && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP))) {
-               struct esdhc_platform_data *boarddata =
-                               host->mmc->parent->platform_data;
-
-               if (boarddata && gpio_is_valid(boarddata->cd_gpio)
-                               && gpio_get_value(boarddata->cd_gpio))
+                       && (imx_data->cd_gpio != -EINVAL))) {
+               if (gpio_get_value(imx_data->cd_gpio))
                        /* no card, if a valid gpio says so... */
                        val &= SDHCI_CARD_PRESENT;
                else
@@ -89,10 +86,9 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 
val, int reg)
        struct pltfm_imx_data *imx_data = pltfm_host->priv;
 
        if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
-                       && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP)))
+                       && (imx_data->cd_gpio != -EINVAL)))
                /*
                 * these interrupts won't work with a custom card_detect gpio
-                * (only applied to mx25/35)
                 */
                val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
 
@@ -193,10 +189,11 @@ static unsigned int esdhc_pltfm_get_min_clock(struct 
sdhci_host *host)
 
 static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
 {
-       struct esdhc_platform_data *boarddata = 
host->mmc->parent->platform_data;
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct pltfm_imx_data *imx_data = pltfm_host->priv;
 
-       if (boarddata && gpio_is_valid(boarddata->wp_gpio))
-               return gpio_get_value(boarddata->wp_gpio);
+       if (imx_data->wp_gpio != -EINVAL)
+               return gpio_get_value(imx_data->wp_gpio);
        else
                return -ENOSYS;
 }
@@ -242,6 +239,8 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct 
sdhci_pltfm_data *pd
                clk_put(pltfm_host->clk);
                return -ENOMEM;
        }
+       imx_data->cd_gpio = -EINVAL;
+       imx_data->wp_gpio = -EINVAL;
        pltfm_host->priv = imx_data;
 
        if (!cpu_is_mx25())
@@ -258,62 +257,56 @@ static int esdhc_pltfm_init(struct sdhci_host *host, 
struct sdhci_pltfm_data *pd
                imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
 
        if (boarddata) {
-               err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, 
"ESDHC_WP");
+               if (gpio_is_valid(boarddata->cd_gpio))
+                       imx_data->cd_gpio = boarddata->cd_gpio;
+               if (gpio_is_valid(boarddata->wp_gpio))
+                       imx_data->wp_gpio = boarddata->wp_gpio;
+       }
+       if (imx_data->wp_gpio != -EINVAL) {
+               err = gpio_request_one(imx_data->wp_gpio, GPIOF_IN, "ESDHC_WP");
                if (err) {
                        dev_warn(mmc_dev(host->mmc),
                                "no write-protect pin available!\n");
-                       boarddata->wp_gpio = err;
+                       imx_data->wp_gpio = -EINVAL;
+                       /* success, just don't use wp_gpio */
                }
-
-               err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, 
"ESDHC_CD");
+       }
+       if (imx_data->cd_gpio != -EINVAL) {
+               err = gpio_request_one(imx_data->cd_gpio, GPIOF_IN, "ESDHC_CD");
                if (err) {
                        dev_warn(mmc_dev(host->mmc),
                                "no card-detect pin available!\n");
-                       goto no_card_detect_pin;
+                       imx_data->cd_gpio = -EINVAL;
+                       /* success, just don't use cd_gpio */
+                       return 0;
                }
-
-               /* i.MX5x has issues to be researched */
-               if (!cpu_is_mx25() && !cpu_is_mx35())
-                       goto not_supported;
-
-               err = request_irq(gpio_to_irq(boarddata->cd_gpio), cd_irq,
+               err = request_irq(gpio_to_irq(imx_data->cd_gpio), cd_irq,
                                 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
                                 mmc_hostname(host->mmc), host);
                if (err) {
                        dev_warn(mmc_dev(host->mmc), "request irq error\n");
-                       goto no_card_detect_irq;
+                       gpio_free(imx_data->cd_gpio);
+                       imx_data->cd_gpio = -EINVAL;
+                       /* success, just don't use cd_gpio */
+                       return 0;
                }
-
-               imx_data->flags |= ESDHC_FLAG_GPIO_FOR_CD_WP;
                /* Now we have a working card_detect again */
                host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
        }
-
-       return 0;
-
- no_card_detect_irq:
-       gpio_free(boarddata->cd_gpio);
- no_card_detect_pin:
-       boarddata->cd_gpio = err;
- not_supported:
-       kfree(imx_data);
        return 0;
 }
 
 static void esdhc_pltfm_exit(struct sdhci_host *host)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-       struct esdhc_platform_data *boarddata = 
host->mmc->parent->platform_data;
        struct pltfm_imx_data *imx_data = pltfm_host->priv;
 
-       if (boarddata && gpio_is_valid(boarddata->wp_gpio))
-               gpio_free(boarddata->wp_gpio);
-
-       if (boarddata && gpio_is_valid(boarddata->cd_gpio)) {
-               gpio_free(boarddata->cd_gpio);
+       if (imx_data->wp_gpio != -EINVAL)
+               gpio_free(imx_data->wp_gpio);
 
-               if (!(host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION))
-                       free_irq(gpio_to_irq(boarddata->cd_gpio), host);
+       if (imx_data->cd_gpio != -EINVAL) {
+               free_irq(gpio_to_irq(imx_data->cd_gpio), host);
+               gpio_free(imx_data->cd_gpio);
        }
 
        clk_disable(pltfm_host->clk);
-- 
1.7.0.4

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

Reply via email to