| 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 |
| |