From: "Chen-Yu Tsai (Moxa)" <wens@csie.org>
To: nobuhiro1.iwamatsu@toshiba.co.jp, pavel@denx.de
Cc: cip-dev@lists.cip-project.org, JohnsonCH.Chen@moxa.com
Subject: [cip-dev] [PATCH 4.4.y-cip 01/23] PM / OPP: get/put regulators from OPP core
Date: Wed, 8 Jul 2020 23:45:32 +0800 [thread overview]
Message-ID: <20200708154554.26450-2-wens@csie.org> (raw)
In-Reply-To: <20200708154554.26450-1-wens@csie.org>
[-- Attachment #1: Type: text/plain, Size: 7062 bytes --]
From: Viresh Kumar <viresh.kumar@linaro.org>
commit 9f8ea969d5cfdd4353d2adb004e8e2286b984369 upstream.
This allows the OPP core to request/free the regulator resource,
attached to a device OPP. The regulator device is fetched using the name
provided by the driver, while calling: dev_pm_opp_set_regulator().
This will work for both OPP-v1 and v2 bindings.
This is a preliminary step for moving the OPP switching logic into the
OPP core.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Chen-Yu Tsai (Moxa) <wens@csie.org>
---
drivers/base/power/opp/core.c | 111 ++++++++++++++++++++++++++++++++++
drivers/base/power/opp/opp.h | 4 ++
include/linux/pm_opp.h | 9 +++
3 files changed, 124 insertions(+)
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
index 1e0a2ddf73323..efdfcee48cac7 100644
--- a/drivers/base/power/opp/core.c
+++ b/drivers/base/power/opp/core.c
@@ -19,6 +19,7 @@
#include <linux/device.h>
#include <linux/of.h>
#include <linux/export.h>
+#include <linux/regulator/consumer.h>
#include "opp.h"
@@ -565,6 +566,9 @@ static void _remove_device_opp(struct device_opp *dev_opp)
if (dev_opp->prop_name)
return;
+ if (!IS_ERR_OR_NULL(dev_opp->regulator))
+ return;
+
list_dev = list_first_entry(&dev_opp->dev_list, struct device_list_opp,
node);
@@ -1091,6 +1095,113 @@ unlock:
}
EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name);
+/**
+ * dev_pm_opp_set_regulator() - Set regulator name for the device
+ * @dev: Device for which regulator name is being set.
+ * @name: Name of the regulator.
+ *
+ * In order to support OPP switching, OPP layer needs to know the name of the
+ * device's regulator, as the core would be required to switch voltages as well.
+ *
+ * This must be called before any OPPs are initialized for the device.
+ *
+ * Locking: The internal device_opp and opp structures are RCU protected.
+ * Hence this function internally uses RCU updater strategy with mutex locks
+ * to keep the integrity of the internal data structures. Callers should ensure
+ * that this function is *NOT* called under RCU protection or in contexts where
+ * mutex cannot be locked.
+ */
+int dev_pm_opp_set_regulator(struct device *dev, const char *name)
+{
+ struct device_opp *dev_opp;
+ struct regulator *reg;
+ int ret;
+
+ mutex_lock(&dev_opp_list_lock);
+
+ dev_opp = _add_device_opp(dev);
+ if (!dev_opp) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+
+ /* This should be called before OPPs are initialized */
+ if (WARN_ON(!list_empty(&dev_opp->opp_list))) {
+ ret = -EBUSY;
+ goto err;
+ }
+
+ /* Already have a regulator set */
+ if (WARN_ON(!IS_ERR_OR_NULL(dev_opp->regulator))) {
+ ret = -EBUSY;
+ goto err;
+ }
+ /* Allocate the regulator */
+ reg = regulator_get_optional(dev, name);
+ if (IS_ERR(reg)) {
+ ret = PTR_ERR(reg);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "%s: no regulator (%s) found: %d\n",
+ __func__, name, ret);
+ goto err;
+ }
+
+ dev_opp->regulator = reg;
+
+ mutex_unlock(&dev_opp_list_lock);
+ return 0;
+
+err:
+ _remove_device_opp(dev_opp);
+unlock:
+ mutex_unlock(&dev_opp_list_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulator);
+
+/**
+ * dev_pm_opp_put_regulator() - Releases resources blocked for regulator
+ * @dev: Device for which regulator was set.
+ *
+ * Locking: The internal device_opp and opp structures are RCU protected.
+ * Hence this function internally uses RCU updater strategy with mutex locks
+ * to keep the integrity of the internal data structures. Callers should ensure
+ * that this function is *NOT* called under RCU protection or in contexts where
+ * mutex cannot be locked.
+ */
+void dev_pm_opp_put_regulator(struct device *dev)
+{
+ struct device_opp *dev_opp;
+
+ mutex_lock(&dev_opp_list_lock);
+
+ /* Check for existing list for 'dev' first */
+ dev_opp = _find_device_opp(dev);
+ if (IS_ERR(dev_opp)) {
+ dev_err(dev, "Failed to find dev_opp: %ld\n", PTR_ERR(dev_opp));
+ goto unlock;
+ }
+
+ if (IS_ERR_OR_NULL(dev_opp->regulator)) {
+ dev_err(dev, "%s: Doesn't have regulator set\n", __func__);
+ goto unlock;
+ }
+
+ /* Make sure there are no concurrent readers while updating dev_opp */
+ WARN_ON(!list_empty(&dev_opp->opp_list));
+
+ regulator_put(dev_opp->regulator);
+ dev_opp->regulator = ERR_PTR(-EINVAL);
+
+ /* Try freeing device_opp if this was the last blocking resource */
+ _remove_device_opp(dev_opp);
+
+unlock:
+ mutex_unlock(&dev_opp_list_lock);
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulator);
+
static bool _opp_is_supported(struct device *dev, struct device_opp *dev_opp,
struct device_node *np)
{
diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h
index 690638ef36ee5..416293b7da237 100644
--- a/drivers/base/power/opp/opp.h
+++ b/drivers/base/power/opp/opp.h
@@ -22,6 +22,8 @@
#include <linux/rculist.h>
#include <linux/rcupdate.h>
+struct regulator;
+
/* Lock to allow exclusive modification to the device and opp lists */
extern struct mutex dev_opp_list_lock;
@@ -132,6 +134,7 @@ struct device_list_opp {
* @supported_hw: Array of version number to support.
* @supported_hw_count: Number of elements in supported_hw array.
* @prop_name: A name to postfix to many DT properties, while parsing them.
+ * @regulator: Supply regulator
* @dentry: debugfs dentry pointer of the real device directory (not links).
* @dentry_name: Name of the real dentry.
*
@@ -159,6 +162,7 @@ struct device_opp {
unsigned int *supported_hw;
unsigned int supported_hw_count;
const char *prop_name;
+ struct regulator *regulator;
#ifdef CONFIG_DEBUG_FS
struct dentry *dentry;
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 95403d2ccaf56..c70a18ac9c8a7 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -60,6 +60,8 @@ int dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions,
void dev_pm_opp_put_supported_hw(struct device *dev);
int dev_pm_opp_set_prop_name(struct device *dev, const char *name);
void dev_pm_opp_put_prop_name(struct device *dev);
+int dev_pm_opp_set_regulator(struct device *dev, const char *name);
+void dev_pm_opp_put_regulator(struct device *dev);
#else
static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
{
@@ -151,6 +153,13 @@ static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name)
static inline void dev_pm_opp_put_prop_name(struct device *dev) {}
+static inline int dev_pm_opp_set_regulator(struct device *dev, const char *name)
+{
+ return -EINVAL;
+}
+
+static inline void dev_pm_opp_put_regulator(struct device *dev) {}
+
#endif /* CONFIG_PM_OPP */
#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
--
2.27.0
[-- Attachment #2: Type: text/plain, Size: 419 bytes --]
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#4887): https://lists.cip-project.org/g/cip-dev/message/4887
Mute This Topic: https://lists.cip-project.org/mt/75379079/4520388
Group Owner: cip-dev+owner@lists.cip-project.org
Unsubscribe: https://lists.cip-project.org/g/cip-dev/leave/8129055/727948398/xyzzy [cip-dev@archiver.kernel.org]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2020-07-08 15:46 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-08 15:45 [cip-dev] [PATCH 4.4.y-cip 00/23] PM / OPP v2 & cpufreq backports part 2 Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` Chen-Yu Tsai (Moxa) [this message]
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 02/23] PM / OPP: Disable OPPs that aren't supported by the regulator Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 03/23] PM / OPP: Introduce dev_pm_opp_get_max_volt_latency() Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 04/23] PM / OPP: Introduce dev_pm_opp_get_max_transition_latency() Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 05/23] PM / OPP: Parse clock-latency and voltage-tolerance for v1 bindings Chen-Yu Tsai (Moxa)
2020-07-09 4:38 ` Nobuhiro Iwamatsu
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 06/23] PM / OPP: Manage device clk Chen-Yu Tsai (Moxa)
2020-07-14 17:44 ` Pavel Machek
2020-07-14 17:57 ` Pavel Machek
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 07/23] PM / OPP: Add dev_pm_opp_set_rate() Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 08/23] cpufreq: dt: Convert few pr_debug/err() calls to dev_dbg/err() Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 09/23] cpufreq: dt: Rename 'need_update' to 'opp_v1' Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 10/23] cpufreq: dt: OPP layers handles clock-latency for V1 bindings as well Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 11/23] cpufreq: dt: Pass regulator name to the OPP core Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 12/23] cpufreq: dt: Unsupported OPPs are already disabled Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 13/23] cpufreq: dt: Reuse dev_pm_opp_get_max_transition_latency() Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 14/23] cpufreq: dt: Use dev_pm_opp_set_rate() to switch frequency Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 15/23] cpufreq: dt: No need to fetch voltage-tolerance Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 16/23] cpufreq: dt: No need to allocate resources anymore Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 17/23] PM / OPP: Fix NULL pointer dereference crash when disabling OPPs Chen-Yu Tsai (Moxa)
2020-07-14 17:37 ` Pavel Machek
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 18/23] PM / OPP: Initialize regulator pointer to an error value Chen-Yu Tsai (Moxa)
2020-07-14 17:38 ` Pavel Machek
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 19/23] PM / OPP: Fix incorrect comments Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 20/23] PM / OPP: Rename structures for clarity Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 21/23] cpufreq: dt: Drop stale comment Chen-Yu Tsai (Moxa)
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 22/23] PM / OPP: Remove useless check Chen-Yu Tsai (Moxa)
2020-07-14 17:41 ` Pavel Machek
2020-07-08 15:45 ` [cip-dev] [PATCH 4.4.y-cip 23/23] PM / OPP: Update voltage in case freq == old_freq Chen-Yu Tsai (Moxa)
2020-07-09 4:48 ` [cip-dev] [PATCH 4.4.y-cip 00/23] PM / OPP v2 & cpufreq backports part 2 Nobuhiro Iwamatsu
2020-07-14 17:33 ` Pavel Machek
2020-08-31 3:41 ` Chen-Yu Tsai (Moxa)
2020-09-02 21:50 ` Pavel Machek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200708154554.26450-2-wens@csie.org \
--to=wens@csie.org \
--cc=JohnsonCH.Chen@moxa.com \
--cc=cip-dev@lists.cip-project.org \
--cc=nobuhiro1.iwamatsu@toshiba.co.jp \
--cc=pavel@denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox