[PATCH 1/2] mmc: sdhci-esdhc: simplify cd_gpio, wp_gpio

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.kisky@xxxxxxxxxxxxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux