blob: 356beeef7cb9ee57aa0691adeb9a59fd40d91941 [file] [log] [blame]
From b44ec118a86a032b43da0b0142486522f6157ea6 Mon Sep 17 00:00:00 2001
From: Simon Baatz <gmbnomis@gmail.com>
Date: Sun, 9 Jun 2013 22:14:11 +0200
Subject: mmc: return mmc_of_parse() errors to caller
In addition to just logging errors encountered during DT parsing or
allocating GPIO slots for CD/WP, mmc_of_parse() now returns with an error.
In particular, this is needed if the GPIO allocation may return
EPROBE_DEFER.
Signed-off-by: Simon Baatz <gmbnomis@gmail.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
(cherry picked from commit ec0a7517dc25b4cca8a694fd61e09771bffba022)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
drivers/mmc/core/host.c | 30 +++++++++++++++++++++++++-----
include/linux/mmc/host.h | 2 +-
2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 2a3593d9..89f58498 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -306,7 +306,7 @@ static inline void mmc_host_clk_sysfs_init(struct mmc_host *host)
* parse the properties and set respective generic mmc-host flags and
* parameters.
*/
-void mmc_of_parse(struct mmc_host *host)
+int mmc_of_parse(struct mmc_host *host)
{
struct device_node *np;
u32 bus_width;
@@ -315,7 +315,7 @@ void mmc_of_parse(struct mmc_host *host)
int len, ret, gpio;
if (!host->parent || !host->parent->of_node)
- return;
+ return 0;
np = host->parent->of_node;
@@ -338,6 +338,7 @@ void mmc_of_parse(struct mmc_host *host)
default:
dev_err(host->parent,
"Invalid \"bus-width\" value %ud!\n", bus_width);
+ return -EINVAL;
}
/* f_max is obtained from the optional "max-frequency" property */
@@ -367,18 +368,22 @@ void mmc_of_parse(struct mmc_host *host)
host->caps |= MMC_CAP_NEEDS_POLL;
gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags);
+ if (gpio == -EPROBE_DEFER)
+ return gpio;
if (gpio_is_valid(gpio)) {
if (!(flags & OF_GPIO_ACTIVE_LOW))
gpio_inv_cd = true;
ret = mmc_gpio_request_cd(host, gpio);
- if (ret < 0)
+ if (ret < 0) {
dev_err(host->parent,
"Failed to request CD GPIO #%d: %d!\n",
gpio, ret);
- else
+ return ret;
+ } else {
dev_info(host->parent, "Got CD GPIO #%d.\n",
gpio);
+ }
}
if (explicit_inv_cd ^ gpio_inv_cd)
@@ -389,14 +394,23 @@ void mmc_of_parse(struct mmc_host *host)
explicit_inv_wp = of_property_read_bool(np, "wp-inverted");
gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags);
+ if (gpio == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto out;
+ }
if (gpio_is_valid(gpio)) {
if (!(flags & OF_GPIO_ACTIVE_LOW))
gpio_inv_wp = true;
ret = mmc_gpio_request_ro(host, gpio);
- if (ret < 0)
+ if (ret < 0) {
dev_err(host->parent,
"Failed to request WP GPIO: %d!\n", ret);
+ goto out;
+ } else {
+ dev_info(host->parent, "Got WP GPIO #%d.\n",
+ gpio);
+ }
}
if (explicit_inv_wp ^ gpio_inv_wp)
host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
@@ -413,6 +427,12 @@ void mmc_of_parse(struct mmc_host *host)
host->pm_caps |= MMC_PM_KEEP_POWER;
if (of_find_property(np, "enable-sdio-wakeup", &len))
host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
+
+ return 0;
+
+out:
+ mmc_gpio_free_cd(host);
+ return ret;
}
EXPORT_SYMBOL(mmc_of_parse);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index e326ae28..c8c4fbc6 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -369,7 +369,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *);
int mmc_add_host(struct mmc_host *);
void mmc_remove_host(struct mmc_host *);
void mmc_free_host(struct mmc_host *);
-void mmc_of_parse(struct mmc_host *host);
+int mmc_of_parse(struct mmc_host *host);
static inline void *mmc_priv(struct mmc_host *host)
{
--
1.8.4.3.gca3854a