diff options
Diffstat (limited to 'drivers/mmc/core/pwrseq.c')
-rw-r--r-- | drivers/mmc/core/pwrseq.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c index bd08772..2cea00e 100644 --- a/drivers/mmc/core/pwrseq.c +++ b/drivers/mmc/core/pwrseq.c @@ -7,14 +7,73 @@ * * MMC power sequence management */ +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/of_platform.h> + #include <linux/mmc/host.h> #include "pwrseq.h" +struct mmc_pwrseq_match { + const char *compatible; + int (*alloc)(struct mmc_host *host, struct device *dev); +}; + +static struct mmc_pwrseq_match pwrseq_match[] = { + { + .compatible = "mmc-pwrseq-simple", + .alloc = mmc_pwrseq_simple_alloc, + }, +}; + +static struct mmc_pwrseq_match *mmc_pwrseq_find(struct device_node *np) +{ + struct mmc_pwrseq_match *match = ERR_PTR(-ENODEV); + int i; + + for (i = 0; i < ARRAY_SIZE(pwrseq_match); i++) { + if (of_device_is_compatible(np, pwrseq_match[i].compatible)) { + match = &pwrseq_match[i]; + break; + } + } + + return match; +} int mmc_pwrseq_alloc(struct mmc_host *host) { - return 0; + struct platform_device *pdev; + struct device_node *np; + struct mmc_pwrseq_match *match; + int ret = 0; + + np = of_parse_phandle(host->parent->of_node, "mmc-pwrseq", 0); + if (!np) + return 0; + + pdev = of_find_device_by_node(np); + if (!pdev) { + ret = -ENODEV; + goto err; + } + + match = mmc_pwrseq_find(np); + if (IS_ERR(match)) { + ret = PTR_ERR(match); + goto err; + } + + ret = match->alloc(host, &pdev->dev); + if (!ret) + dev_info(host->parent, "allocated mmc-pwrseq\n"); + +err: + of_node_put(np); + return ret; } void mmc_pwrseq_pre_power_on(struct mmc_host *host) |