]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.31/cpufreq-kryo-release-opp-tables-on-module-removal.patch
Linux 4.19.31
[thirdparty/kernel/stable-queue.git] / releases / 4.19.31 / cpufreq-kryo-release-opp-tables-on-module-removal.patch
CommitLineData
ec71c73b
GKH
1From 0334906c06967142c8805fbe88acf787f65d3d26 Mon Sep 17 00:00:00 2001
2From: Viresh Kumar <viresh.kumar@linaro.org>
3Date: Wed, 20 Feb 2019 16:41:18 +0530
4Subject: cpufreq: kryo: Release OPP tables on module removal
5
6From: Viresh Kumar <viresh.kumar@linaro.org>
7
8commit 0334906c06967142c8805fbe88acf787f65d3d26 upstream.
9
10Commit 5ad7346b4ae2 ("cpufreq: kryo: Add module remove and exit") made
11it possible to build the kryo cpufreq driver as a module, but it failed
12to release all the resources, i.e. OPP tables, when the module is
13unloaded.
14
15This patch fixes it by releasing the OPP tables, by calling
16dev_pm_opp_put_supported_hw() for them, from the
17qcom_cpufreq_kryo_remove() routine. The array of pointers to the OPP
18tables is also allocated dynamically now in qcom_cpufreq_kryo_probe(),
19as the pointers will be required while releasing the resources.
20
21Compile tested only.
22
23Cc: 4.18+ <stable@vger.kernel.org> # v4.18+
24Fixes: 5ad7346b4ae2 ("cpufreq: kryo: Add module remove and exit")
25Reviewed-by: Georgi Djakov <georgi.djakov@linaro.org>
26Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
27Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28
29---
30 drivers/cpufreq/qcom-cpufreq-kryo.c | 20 ++++++++++++++++++--
31 1 file changed, 18 insertions(+), 2 deletions(-)
32
33--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
34+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
35@@ -75,7 +75,7 @@ static enum _msm8996_version qcom_cpufre
36
37 static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
38 {
39- struct opp_table *opp_tables[NR_CPUS] = {0};
40+ struct opp_table **opp_tables;
41 enum _msm8996_version msm8996_version;
42 struct nvmem_cell *speedbin_nvmem;
43 struct device_node *np;
44@@ -133,6 +133,10 @@ static int qcom_cpufreq_kryo_probe(struc
45 }
46 kfree(speedbin);
47
48+ opp_tables = kcalloc(num_possible_cpus(), sizeof(*opp_tables), GFP_KERNEL);
49+ if (!opp_tables)
50+ return -ENOMEM;
51+
52 for_each_possible_cpu(cpu) {
53 cpu_dev = get_cpu_device(cpu);
54 if (NULL == cpu_dev) {
55@@ -151,8 +155,10 @@ static int qcom_cpufreq_kryo_probe(struc
56
57 cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
58 NULL, 0);
59- if (!IS_ERR(cpufreq_dt_pdev))
60+ if (!IS_ERR(cpufreq_dt_pdev)) {
61+ platform_set_drvdata(pdev, opp_tables);
62 return 0;
63+ }
64
65 ret = PTR_ERR(cpufreq_dt_pdev);
66 dev_err(cpu_dev, "Failed to register platform device\n");
67@@ -163,13 +169,23 @@ free_opp:
68 break;
69 dev_pm_opp_put_supported_hw(opp_tables[cpu]);
70 }
71+ kfree(opp_tables);
72
73 return ret;
74 }
75
76 static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
77 {
78+ struct opp_table **opp_tables = platform_get_drvdata(pdev);
79+ unsigned int cpu;
80+
81 platform_device_unregister(cpufreq_dt_pdev);
82+
83+ for_each_possible_cpu(cpu)
84+ dev_pm_opp_put_supported_hw(opp_tables[cpu]);
85+
86+ kfree(opp_tables);
87+
88 return 0;
89 }
90