[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-id: <1465465471-28740-10-git-send-email-k.kozlowski@samsung.com>
Date: Thu, 09 Jun 2016 11:44:26 +0200
From: Krzysztof Kozlowski <k.kozlowski@...sung.com>
To: Ulf Hansson <ulf.hansson@...aro.org>,
Rob Herring <robh+dt@...nel.org>,
Pawel Moll <pawel.moll@....com>,
Mark Rutland <mark.rutland@....com>,
Ian Campbell <ijc+devicetree@...lion.org.uk>,
Kumar Gala <galak@...eaurora.org>,
Krzysztof Kozlowski <k.kozlowski@...sung.com>,
Sebastian Reichel <sre@...nel.org>,
Dmitry Eremin-Solenikov <dbaryshkov@...il.com>,
David Woodhouse <dwmw2@...radead.org>,
Liam Girdwood <lgirdwood@...il.com>,
Mark Brown <broonie@...nel.org>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Hans de Goede <hdegoede@...hat.com>,
Jean-Christophe Plagniol-Villard <plagnioj@...osoft.com>,
Tomi Valkeinen <tomi.valkeinen@...com>,
Heiko Stuebner <heiko@...ech.de>, linux-mmc@...r.kernel.org,
devicetree@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org,
linux-samsung-soc@...r.kernel.org, linux-pm@...r.kernel.org,
linux-usb@...r.kernel.org, linux-fbdev@...r.kernel.org,
hzpeterchen@...il.com
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@...sung.com>
Subject: [RFC v4 09/14] power: pwrseq: Add support for USB hubs with external
power
Some USB devices on embedded boards have external power supply which has
to be reset in certain conditions. Add pwrseq interface for this.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@...sung.com>
---
drivers/power/pwrseq/pwrseq.c | 47 ++++++++++++++++++++++++++++++++++++++++++-
include/linux/pwrseq.h | 11 ++++++++++
2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/drivers/power/pwrseq/pwrseq.c b/drivers/power/pwrseq/pwrseq.c
index 495a19d3c30b..722aff4f740f 100644
--- a/drivers/power/pwrseq/pwrseq.c
+++ b/drivers/power/pwrseq/pwrseq.c
@@ -1,7 +1,9 @@
/*
- * Copyright (C) 2014 Linaro Ltd
+ * Copyright (C) 2014 Linaro Ltd
+ * Copyright (C) 2016 Samsung Electronics
*
* Author: Ulf Hansson <ulf.hansson@...aro.org>
+ * Krzysztof Kozlowski <k.kozlowski@...sung.com>
*
* License terms: GNU General Public License (GPL) version 2
*
@@ -52,6 +54,42 @@ int mmc_pwrseq_alloc(struct mmc_host *host)
}
EXPORT_SYMBOL_GPL(mmc_pwrseq_alloc);
+struct pwrseq *pwrseq_alloc(struct device *dev, const char *phandle_name)
+{
+ struct device_node *np;
+ struct pwrseq *p, *ret = NULL;
+
+ np = of_parse_phandle(dev->of_node, phandle_name, 0);
+ if (!np)
+ return NULL;
+
+ mutex_lock(&pwrseq_list_mutex);
+ list_for_each_entry(p, &pwrseq_list, pwrseq_node) {
+ if (p->dev->of_node == np) {
+ if (!try_module_get(p->owner))
+ dev_err(dev,
+ "increasing module refcount failed\n");
+ else
+ ret = p;
+
+ break;
+ }
+ }
+
+ of_node_put(np);
+ mutex_unlock(&pwrseq_list_mutex);
+
+ if (!ret) {
+ dev_dbg(dev, "%s defer probe\n", phandle_name);
+ return ERR_PTR(-EPROBE_DEFER);
+ }
+
+ dev_info(dev, "allocated usb-pwrseq\n");
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pwrseq_alloc);
+
void pwrseq_pre_power_on(struct pwrseq *pwrseq)
{
if (pwrseq && pwrseq->ops->pre_power_on)
@@ -84,6 +122,13 @@ void mmc_pwrseq_free(struct mmc_host *host)
}
EXPORT_SYMBOL_GPL(mmc_pwrseq_free);
+void pwrseq_free(const struct pwrseq *pwrseq)
+{
+ if (pwrseq)
+ module_put(pwrseq->owner);
+}
+EXPORT_SYMBOL_GPL(pwrseq_free);
+
int pwrseq_register(struct pwrseq *pwrseq)
{
if (!pwrseq || !pwrseq->ops || !pwrseq->dev)
diff --git a/include/linux/pwrseq.h b/include/linux/pwrseq.h
index fcc8fd855d4c..6215b3d6350d 100644
--- a/include/linux/pwrseq.h
+++ b/include/linux/pwrseq.h
@@ -31,9 +31,13 @@ void pwrseq_unregister(struct pwrseq *pwrseq);
void pwrseq_pre_power_on(struct pwrseq *pwrseq);
void pwrseq_post_power_on(struct pwrseq *pwrseq);
void pwrseq_power_off(struct pwrseq *pwrseq);
+
int mmc_pwrseq_alloc(struct mmc_host *host);
void mmc_pwrseq_free(struct mmc_host *host);
+struct pwrseq *pwrseq_alloc(struct device *dev, const char *phandle_name);
+void pwrseq_free(const struct pwrseq *pwrseq);
+
#else /* CONFIG_POWER_SEQ */
static inline int pwrseq_register(struct pwrseq *pwrseq)
@@ -44,9 +48,16 @@ static inline void pwrseq_unregister(struct pwrseq *pwrseq) {}
static inline void pwrseq_pre_power_on(struct pwrseq *pwrseq) {}
static inline void pwrseq_post_power_on(struct pwrseq *pwrseq) {}
static inline void pwrseq_power_off(struct pwrseq *pwrseq) {}
+
static inline int mmc_pwrseq_alloc(struct mmc_host *host) { return 0; }
static inline void mmc_pwrseq_free(struct mmc_host *host) {}
+static inline struct pwrseq *pwrseq_alloc(struct device *dev, const char *phandle_name)
+{
+ return NULL;
+}
+static inline void pwrseq_free(const struct pwrseq *pwrseq) {}
+
#endif /* CONFIG_POWER_SEQ */
#endif /* _LINUX_PWRSEQ_H */
--
1.9.1
Powered by blists - more mailing lists