Home Home > GIT Browse > SLE12-SP4
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Saenz Julienne <nsaenzjulienne@suse.de>2019-08-06 10:27:06 +0200
committerNicolas Saenz Julienne <nsaenzjulienne@suse.de>2019-08-08 11:39:13 +0200
commit7ca0aa7c9e8d525c4327160da7b22bbccb84aea3 (patch)
tree845c1c00665fc6f8e8b5fb566ede82d3790d7d90
parenta84461b1293e47d9854eee199cda852717927e86 (diff)
cpufreq: dt: Try freeing static OPPs only if we have added them
(jsc#SLE-7294).
-rw-r--r--patches.drivers/cpufreq-dt-try-freeing-static-opps-only-if-we-have-added-them.patch111
-rw-r--r--series.conf1
2 files changed, 112 insertions, 0 deletions
diff --git a/patches.drivers/cpufreq-dt-try-freeing-static-opps-only-if-we-have-added-them.patch b/patches.drivers/cpufreq-dt-try-freeing-static-opps-only-if-we-have-added-them.patch
new file mode 100644
index 0000000000..3ef12f58fa
--- /dev/null
+++ b/patches.drivers/cpufreq-dt-try-freeing-static-opps-only-if-we-have-added-them.patch
@@ -0,0 +1,111 @@
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 3 Oct 2018 15:35:21 +0530
+Subject: cpufreq: dt: Try freeing static OPPs only if we have added them
+Git-commit: 51c99dd2c06b234575661fa1e0a1dea6c3ef566f
+Patch-mainline: v4.20-rc1
+References: jsc#SLE-7294
+
+We can not call dev_pm_opp_of_cpumask_remove_table() freely anymore
+since the latest OPP core updates as that uses reference counting to
+free resources. There are cases where no static OPPs are added (using
+DT) for a platform and trying to remove the OPP table may end up
+decrementing refcount which is already zero and hence generating
+warnings.
+
+Lets track if we were able to add static OPPs or not and then only
+remove the table based on that. Some reshuffling of code is also done to
+do that.
+
+Reported-by: Niklas Cassel <niklas.cassel@linaro.org>
+Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+---
+ drivers/cpufreq/cpufreq-dt.c | 34 +++++++++++++++++++---------------
+ 1 file changed, 19 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
+index 0a9ebf00be46..e58bfcb1169e 100644
+--- a/drivers/cpufreq/cpufreq-dt.c
++++ b/drivers/cpufreq/cpufreq-dt.c
+@@ -32,6 +32,7 @@ struct private_data {
+ struct device *cpu_dev;
+ struct thermal_cooling_device *cdev;
+ const char *reg_name;
++ bool have_static_opps;
+ };
+
+ static struct freq_attr *cpufreq_dt_attr[] = {
+@@ -204,6 +205,15 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+ }
+ }
+
++ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++ if (!priv) {
++ ret = -ENOMEM;
++ goto out_put_regulator;
++ }
++
++ priv->reg_name = name;
++ priv->opp_table = opp_table;
++
+ /*
+ * Initialize OPP tables for all policy->cpus. They will be shared by
+ * all CPUs which have marked their CPUs shared with OPP bindings.
+@@ -214,7 +224,8 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+ *
+ * OPPs might be populated at runtime, don't check for error here
+ */
+- dev_pm_opp_of_cpumask_add_table(policy->cpus);
++ if (!dev_pm_opp_of_cpumask_add_table(policy->cpus))
++ priv->have_static_opps = true;
+
+ /*
+ * But we need OPP table to function so if it is not there let's
+@@ -240,19 +251,10 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+ __func__, ret);
+ }
+
+- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+- if (!priv) {
+- ret = -ENOMEM;
+- goto out_free_opp;
+- }
+-
+- 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_free_opp;
+ }
+
+ priv->cpu_dev = cpu_dev;
+@@ -282,10 +284,11 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+
+ out_free_cpufreq_table:
+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
+-out_free_priv:
+- kfree(priv);
+ out_free_opp:
+- dev_pm_opp_of_cpumask_remove_table(policy->cpus);
++ if (priv->have_static_opps)
++ dev_pm_opp_of_cpumask_remove_table(policy->cpus);
++ kfree(priv);
++out_put_regulator:
+ if (name)
+ dev_pm_opp_put_regulators(opp_table);
+ out_put_clk:
+@@ -300,7 +303,8 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
+
+ cpufreq_cooling_unregister(priv->cdev);
+ dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
+- dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
++ if (priv->have_static_opps)
++ dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
+ if (priv->reg_name)
+ dev_pm_opp_put_regulators(priv->opp_table);
+
+
diff --git a/series.conf b/series.conf
index 28e56da31d..64b220e017 100644
--- a/series.conf
+++ b/series.conf
@@ -19631,6 +19631,7 @@
patches.drivers/pcmcia-Implement-CLKRUN-protocol-disabling-for-Ricoh.patch
patches.fixes/cpufreq-conservative-Take-limits-changes-into-accoun.patch
patches.arch/x86-hibernate-fix-nosave_regions-setup-for-hibernation
+ patches.drivers/cpufreq-dt-try-freeing-static-opps-only-if-we-have-added-them.patch
patches.fixes/cpupower-remove-stringop-truncation-waring.patch
patches.fixes/ACPICA-AML-interpreter-add-region-addresses-in-globa.patch
patches.drivers/ACPI-LPSS-Add-alternative-ACPI-HIDs-for-Cherry-Trail.patch