summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2019-03-01 16:30:16 +0100
committerSylwester Nawrocki <s.nawrocki@samsung.com>2019-03-27 12:18:53 +0100
commit4625551527e673d59d74a2e0f0483ae85dcdb207 (patch)
tree766fd4d0fea5e10e1841b2187c7f3013befd3949 /drivers
parentbf75262d7163301a838c4d4f9e5c761c4aa2da46 (diff)
downloadlinux-exynos-4625551527e673d59d74a2e0f0483ae85dcdb207.tar.gz
linux-exynos-4625551527e673d59d74a2e0f0483ae85dcdb207.tar.bz2
linux-exynos-4625551527e673d59d74a2e0f0483ae85dcdb207.zip
soc: samsung: asv: Wait until OPP gets released before adding new one
There is currently no check whether an OPP is actually removed before attempting to add an replacement OPP. In situations when and OPP is referenced when we try to remove it and it is not already removed at the time of return from the dev_pm_opp_remove() call subsequent dev_pm_opp_add() invocation will fail. To avoid that add a polling loop with timeout as a barrier before adding new OPP. This patch should also prevent related cpufreq core issues as indicated by logs as follows. exynos_asv_update_cpu_opp cpu4 opp5, freq: 2000 missing exynos5433_asv_opp_get_voltage: arm,cortex-a57: [6] freq: 1900, voltage: 1262500 -> 1187500 cpu cpu4: _opp_add: duplicate OPPs detected. Existing: freq: 1900000000, volt: 1262500, enabled: 1. New: freq: 1900000000, volt: 1187500, enabled: 1 exynos_asv_update_cpu_opp: Failed to add OPP 1900000000 Hz/1187500 uV for cpu4 (-17) cpu cpu4: dev_pm_opp_set_rate: failed to find OPP for freq 1900000000 (-34) exynos5433_asv_opp_get_voltage: arm,cortex-a57: [9] freq: 1600, voltage: 1137500 -> 1062500 cpufreq: __target_index: Failed to change cpu frequency: -34 Change-Id: Ibf6a568cabbd5380952d97f93d27ac59f1db125b Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/soc/samsung/exynos-asv.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
index f416e0fbcfb4..611c3740fb38 100644
--- a/drivers/soc/samsung/exynos-asv.c
+++ b/drivers/soc/samsung/exynos-asv.c
@@ -8,6 +8,7 @@
#include <linux/bitrev.h>
#include <linux/cpu.h>
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/init.h>
@@ -46,6 +47,7 @@ int exynos_asv_update_cpu_opp(struct device *cpu)
for (i = 0; i < subsys->dvfs_nr; i++) {
unsigned int new_voltage;
unsigned int voltage;
+ int timeout = 1000;
int err;
opp_freq = subsys->asv_table[i][0];
@@ -66,6 +68,14 @@ int exynos_asv_update_cpu_opp(struct device *cpu)
opp_freq *= MHZ;
dev_pm_opp_remove(cpu, opp_freq);
+ while (--timeout) {
+ opp = dev_pm_opp_find_freq_exact(cpu, opp_freq, true);
+ if (IS_ERR(opp))
+ break;
+ dev_pm_opp_put(opp);
+ msleep(1);
+ }
+
err = dev_pm_opp_add(cpu, opp_freq, new_voltage);
if (err < 0)
pr_err("%s: Failed to add OPP %u Hz/%u uV for cpu%d\n",