@@ -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);
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@boundarydevices.com> --- drivers/mmc/host/sdhci-esdhc-imx.c | 79 ++++++++++++++++------------------- 1 files changed, 36 insertions(+), 43 deletions(-)