aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-4.14/0054-cpufreq-dt-Handle-OPP-voltage-adjust-events.patch
diff options
context:
space:
mode:
authorRam Chandra Jangir <rjangir@codeaurora.org>2018-05-04 21:57:33 +0530
committerJohn Crispin <john@phrozen.org>2018-05-22 20:34:14 +0200
commit93dd2f7211db6607184adadb488582e01fd5c29b (patch)
treefe982ceb4c20d2e1ecbe9ecfc386addaccae2e92 /target/linux/ipq806x/patches-4.14/0054-cpufreq-dt-Handle-OPP-voltage-adjust-events.patch
parent70e6ea319d3bfdfdb34be540dc7d89aa175b5587 (diff)
downloadupstream-93dd2f7211db6607184adadb488582e01fd5c29b.tar.gz
upstream-93dd2f7211db6607184adadb488582e01fd5c29b.tar.bz2
upstream-93dd2f7211db6607184adadb488582e01fd5c29b.zip
ipq806x: add kernel 4.14 support
- Rebased the patches for 4.14 - Dropped spi-qup and 0027, 0028, 0029 clk patches since it's already included in upstream. Tested on IPQ AP148 Board: 1) NOR boot and NAND boot 2) Tested USB and PCIe interfaces 3) WDOG test 4) cpu frequency scaling 5) ethernet, 2G and 5G WiFi 6) ubi sysupgrade Signed-off-by: Ram Chandra Jangir <rjangir@codeaurora.org> Tested-by: Stefan Lippers-Hollmann <s.l-h@gmx.de>
Diffstat (limited to 'target/linux/ipq806x/patches-4.14/0054-cpufreq-dt-Handle-OPP-voltage-adjust-events.patch')
-rw-r--r--target/linux/ipq806x/patches-4.14/0054-cpufreq-dt-Handle-OPP-voltage-adjust-events.patch131
1 files changed, 131 insertions, 0 deletions
diff --git a/target/linux/ipq806x/patches-4.14/0054-cpufreq-dt-Handle-OPP-voltage-adjust-events.patch b/target/linux/ipq806x/patches-4.14/0054-cpufreq-dt-Handle-OPP-voltage-adjust-events.patch
new file mode 100644
index 0000000000..47c64eca82
--- /dev/null
+++ b/target/linux/ipq806x/patches-4.14/0054-cpufreq-dt-Handle-OPP-voltage-adjust-events.patch
@@ -0,0 +1,131 @@
+From 10577f74c35bd395951d1b2382c8d821089b5745 Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <sboyd@codeaurora.org>
+Date: Fri, 18 Sep 2015 17:52:08 -0700
+Subject: [PATCH 54/69] cpufreq-dt: Handle OPP voltage adjust events
+
+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.
+
+In the former case, an AVS driver will call
+dev_pm_opp_modify_voltage() and update the voltage for the
+particular OPP the CPUs are using. Add an OPP notifier to
+cpufreq-dt so that we can adjust the voltage of the CPU when AVS
+updates the OPP.
+
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
+---
+ drivers/cpufreq/cpufreq-dt.c | 68 ++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 65 insertions(+), 3 deletions(-)
+
+--- a/drivers/cpufreq/cpufreq-dt.c
++++ b/drivers/cpufreq/cpufreq-dt.c
+@@ -32,6 +32,9 @@ struct private_data {
+ struct device *cpu_dev;
+ struct thermal_cooling_device *cdev;
+ const char *reg_name;
++ struct notifier_block opp_nb;
++ struct mutex lock;
++ unsigned long opp_freq;
+ };
+
+ static struct freq_attr *cpufreq_dt_attr[] = {
+@@ -43,9 +46,16 @@ static struct freq_attr *cpufreq_dt_attr
+ static int set_target(struct cpufreq_policy *policy, unsigned int index)
+ {
+ struct private_data *priv = policy->driver_data;
++ int ret;
++ unsigned long target_freq = policy->freq_table[index].frequency * 1000;
++
++ mutex_lock(&priv->lock);
++ ret = dev_pm_opp_set_rate(priv->cpu_dev, target_freq);
++ if (!ret)
++ priv->opp_freq = target_freq;
++ mutex_unlock(&priv->lock);
+
+- return dev_pm_opp_set_rate(priv->cpu_dev,
+- policy->freq_table[index].frequency * 1000);
++ return ret;
+ }
+
+ /*
+@@ -86,6 +96,39 @@ node_put:
+ return name;
+ }
+
++static int opp_notifier(struct notifier_block *nb, unsigned long event,
++ void *data)
++{
++ struct dev_pm_opp *opp = data;
++ struct private_data *priv = container_of(nb, struct private_data,
++ opp_nb);
++ struct device *cpu_dev = priv->cpu_dev;
++ struct regulator *cpu_reg;
++ unsigned long volt, freq;
++ int ret = 0;
++
++ if (event == OPP_EVENT_ADJUST_VOLTAGE) {
++ cpu_reg = dev_pm_opp_get_regulator(cpu_dev);
++ if (IS_ERR(cpu_reg)) {
++ ret = PTR_ERR(cpu_reg);
++ goto out;
++ }
++ volt = dev_pm_opp_get_voltage(opp);
++ freq = dev_pm_opp_get_freq(opp);
++
++ mutex_lock(&priv->lock);
++ if (freq == priv->opp_freq) {
++ ret = regulator_set_voltage_triplet(cpu_reg, volt, volt, volt);
++ }
++ mutex_unlock(&priv->lock);
++ if (ret)
++ dev_err(cpu_dev, "failed to scale voltage: %d\n", ret);
++ }
++
++out:
++ return notifier_from_errno(ret);
++}
++
+ static int resources_available(void)
+ {
+ struct device *cpu_dev;
+@@ -152,6 +195,7 @@ static int cpufreq_init(struct cpufreq_p
+ bool fallback = false;
+ const char *name;
+ int ret;
++ struct srcu_notifier_head *opp_srcu_head;
+
+ cpu_dev = get_cpu_device(policy->cpu);
+ if (!cpu_dev) {
+@@ -241,13 +285,16 @@ static int cpufreq_init(struct cpufreq_p
+ goto out_free_opp;
+ }
+
++ mutex_init(&priv->lock);
++ dev_pm_opp_register_notifier(cpu_dev, &priv->opp_nb);
++
+ priv->reg_name = name;
+ priv->opp_table = opp_table;
+
+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
+ if (ret) {
+ dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
+- goto out_free_priv;
++ goto out_unregister_nb;
+ }
+
+ priv->cpu_dev = cpu_dev;
+@@ -283,6 +343,8 @@ static int cpufreq_init(struct cpufreq_p
+
+ out_free_cpufreq_table:
+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
++out_unregister_nb:
++ dev_pm_opp_unregister_notifier(cpu_dev, &priv->opp_nb);
+ out_free_priv:
+ kfree(priv);
+ out_free_opp: