summaryrefslogtreecommitdiff
path: root/drivers/mmc/core/pwrseq.c
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2014-12-05 14:36:58 +0100
committerUlf Hansson <ulf.hansson@linaro.org>2015-01-28 12:32:07 +0100
commit8c96f89c62ecc8334d06820bff62ecf81be97c2b (patch)
tree8feac978c3df53147199f59b5fa7976de5218a0e /drivers/mmc/core/pwrseq.c
parent0e6d633274db7b4db14a1194163b4d31d37b261f (diff)
mmc: pwrseq: Initial support for the simple MMC power sequence provider
To add the core part for the MMC power sequence, let's start by adding initial support for the simple MMC power sequence provider. In this initial step, the MMC power sequence node are fetched and the compatible string for the simple MMC power sequence provider are verified. At this point we don't parse the node for any properties, but instead that will be handled from following patches. Since there are no properties supported yet, let's just implement the ->alloc() and the ->free() callbacks. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Tested-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Reviewed-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Diffstat (limited to 'drivers/mmc/core/pwrseq.c')
-rw-r--r--drivers/mmc/core/pwrseq.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c
index bd087723929f..2cea00ed4e65 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)