From: Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>
To: MyungJoo Ham <myungjoo.ham@samsung.com>,
Kyungmin Park <kyungmin.park@samsung.com>,
Chanwoo Choi <cw00.choi@samsung.com>,
"Rob Herring" <robh+dt@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
"Matthias Brugger" <matthias.bgg@gmail.com>,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
Viresh Kumar <viresh.kumar@linaro.org>,
Nishanth Menon <nm@ti.com>, "Stephen Boyd" <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org, srv_heupstream@mediatek.com,
linux-pm@vger.kernel.org, Roger Lu <roger.lu@mediatek.com>,
Stephen Boyd <sboyd@codeaurora.org>,
linux-kernel@vger.kernel.org, fan.chen@mediatek.com,
linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org
Subject: [PATCH 6/8] PM / OPP: Support adjusting OPP voltages at runtime
Date: Thu, 16 May 2019 17:08:43 +0800 [thread overview]
Message-ID: <1557997725-12178-7-git-send-email-andrew-sh.cheng@mediatek.com> (raw)
In-Reply-To: <1557997725-12178-1-git-send-email-andrew-sh.cheng@mediatek.com>
From: Stephen Boyd <sboyd@codeaurora.org>
On some SoCs the Adaptive Voltage Scaling (AVS) technique is
employed to optimize the operating voltage of a device. At a
given frequency, the hardware monitors dynamic factors and either
makes a suggestion for how much to adjust a voltage for the
current frequency, or it automatically adjusts the voltage
without software intervention. Add an API to the OPP library for
the former case, so that AVS type devices can update the voltages
for an OPP when the hardware determines the voltage should
change. The assumption is that drivers like CPUfreq or devfreq
will register for the OPP notifiers and adjust the voltage
according to suggestions that AVS makes.
This patch is devired from [1] submitted by Stephen.
[1] https://lore.kernel.org/patchwork/patch/599279/
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Roger Lu <roger.lu@mediatek.com>
---
drivers/opp/core.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/pm_opp.h | 11 +++++++
2 files changed, 89 insertions(+)
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 0420f7e8ad5b..879ca5f50d1a 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -1946,6 +1946,84 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
return r;
}
+/*
+ * dev_pm_opp_adjust_voltage() - helper to change the voltage of an OPP
+ * @dev: device for which we do this operation
+ * @freq: OPP frequency to adjust voltage of
+ * @u_volt: new OPP voltage
+ *
+ * Change the voltage of an OPP with an RCU operation.
+ *
+ * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the
+ * copy operation, returns 0 if no modifcation was done OR modification was
+ * successful.
+ *
+ * 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 locking or synchronize_rcu() blocking calls cannot be used.
+ */
+int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
+ unsigned long u_volt)
+{
+ struct opp_table *opp_table;
+ struct dev_pm_opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV);
+ int r = 0;
+
+ /* Find the opp_table */
+ opp_table = _find_opp_table(dev);
+ if (IS_ERR(opp_table)) {
+ r = PTR_ERR(opp_table);
+ dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r);
+ return r;
+ }
+
+ /* keep the node allocated */
+ new_opp = kmalloc(sizeof(*new_opp), GFP_KERNEL);
+ if (!new_opp)
+ return -ENOMEM;
+
+ mutex_lock(&opp_table->lock);
+
+ /* Do we have the frequency? */
+ list_for_each_entry(tmp_opp, &opp_table->opp_list, node) {
+ if (tmp_opp->rate == freq) {
+ opp = tmp_opp;
+ break;
+ }
+ }
+
+ if (IS_ERR(opp)) {
+ r = PTR_ERR(opp);
+ goto unlock;
+ }
+
+ /* Is update really needed? */
+ if (opp->supplies->u_volt == u_volt)
+ goto unlock;
+
+ /* copy the old data over */
+ *new_opp = *opp;
+
+ /* plug in new node */
+ new_opp->supplies->u_volt = u_volt;
+
+ list_replace_rcu(&opp->node, &new_opp->node);
+ mutex_unlock(&opp_table->lock);
+
+ /* Notify the change of the OPP */
+ blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ADJUST_VOLTAGE,
+ opp);
+
+ return 0;
+
+unlock:
+ mutex_unlock(&opp_table->lock);
+ kfree(new_opp);
+ return r;
+}
+
/**
* dev_pm_opp_enable() - Enable a specific OPP
* @dev: device for which we do this operation
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 24c757a32a7b..70219fe3ca20 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -25,6 +25,7 @@ struct opp_table;
enum dev_pm_opp_event {
OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
+ OPP_EVENT_ADJUST_VOLTAGE,
};
/**
@@ -112,6 +113,9 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq,
void dev_pm_opp_remove(struct device *dev, unsigned long freq);
void dev_pm_opp_remove_all_dynamic(struct device *dev);
+int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
+ unsigned long u_volt);
+
int dev_pm_opp_enable(struct device *dev, unsigned long freq);
int dev_pm_opp_disable(struct device *dev, unsigned long freq);
@@ -229,6 +233,13 @@ static inline void dev_pm_opp_remove_all_dynamic(struct device *dev)
{
}
+static inline int
+dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
+ unsigned long u_volt)
+{
+ return 0;
+}
+
static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq)
{
return 0;
--
2.12.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-05-16 9:10 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-16 9:08 [PATCH 0/8] Add cpufreq and cci devfreq for mt8183, and SVS support Andrew-sh.Cheng
2019-05-16 9:08 ` [PATCH 1/8] cpufreq: mediatek: change to regulator_get_optional Andrew-sh.Cheng
2019-05-16 9:08 ` [PATCH 2/8] cpufreq: mediatek: add clock enable for intermediate clock Andrew-sh.Cheng
2019-05-16 9:08 ` [PATCH 3/8] cpufreq: mediatek: Add support for mt8183 Andrew-sh.Cheng
2019-05-16 9:08 ` [PATCH 4/8] dt-bindings: devfreq: add compatible for mt8183 cci devfreq Andrew-sh.Cheng
2019-05-20 4:43 ` Viresh Kumar
2019-05-16 9:08 ` [PATCH 5/8] devfreq: add mediatek " Andrew-sh.Cheng
2019-05-16 9:08 ` Andrew-sh.Cheng [this message]
2019-05-20 4:47 ` [PATCH 6/8] PM / OPP: Support adjusting OPP voltages at runtime Viresh Kumar
2019-07-29 3:39 ` Roger Lu
2019-07-29 9:20 ` Viresh Kumar
2019-05-16 9:08 ` [PATCH 7/8] cpufreq: mediatek: add opp notification for SVS support Andrew-sh.Cheng
2019-05-27 7:02 ` Hsin-Yi Wang
2019-05-16 9:08 ` [PATCH 8/8] devfreq: mediatek: cci devfreq register " Andrew-sh.Cheng
2019-05-24 8:04 ` Hsin-Yi Wang
2019-05-16 9:23 ` [PATCH 0/8] Add cpufreq and cci devfreq for mt8183, and " Viresh Kumar
2019-05-16 12:23 ` andrew-sh.cheng
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=1557997725-12178-7-git-send-email-andrew-sh.cheng@mediatek.com \
--to=andrew-sh.cheng@mediatek.com \
--cc=cw00.choi@samsung.com \
--cc=devicetree@vger.kernel.org \
--cc=fan.chen@mediatek.com \
--cc=kyungmin.park@samsung.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-pm@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=matthias.bgg@gmail.com \
--cc=myungjoo.ham@samsung.com \
--cc=nm@ti.com \
--cc=rjw@rjwysocki.net \
--cc=robh+dt@kernel.org \
--cc=roger.lu@mediatek.com \
--cc=sboyd@codeaurora.org \
--cc=sboyd@kernel.org \
--cc=srv_heupstream@mediatek.com \
--cc=viresh.kumar@linaro.org \
/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