]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/cpufreq-kryo-release-opp-tables-on-module-removal.patch
f42e1f44b6c8edbc5377067ac7bde75242fccaba
[thirdparty/kernel/stable-queue.git] / queue-4.19 / cpufreq-kryo-release-opp-tables-on-module-removal.patch
1 From 0334906c06967142c8805fbe88acf787f65d3d26 Mon Sep 17 00:00:00 2001
2 From: Viresh Kumar <viresh.kumar@linaro.org>
3 Date: Wed, 20 Feb 2019 16:41:18 +0530
4 Subject: cpufreq: kryo: Release OPP tables on module removal
5
6 From: Viresh Kumar <viresh.kumar@linaro.org>
7
8 commit 0334906c06967142c8805fbe88acf787f65d3d26 upstream.
9
10 Commit 5ad7346b4ae2 ("cpufreq: kryo: Add module remove and exit") made
11 it possible to build the kryo cpufreq driver as a module, but it failed
12 to release all the resources, i.e. OPP tables, when the module is
13 unloaded.
14
15 This patch fixes it by releasing the OPP tables, by calling
16 dev_pm_opp_put_supported_hw() for them, from the
17 qcom_cpufreq_kryo_remove() routine. The array of pointers to the OPP
18 tables is also allocated dynamically now in qcom_cpufreq_kryo_probe(),
19 as the pointers will be required while releasing the resources.
20
21 Compile tested only.
22
23 Cc: 4.18+ <stable@vger.kernel.org> # v4.18+
24 Fixes: 5ad7346b4ae2 ("cpufreq: kryo: Add module remove and exit")
25 Reviewed-by: Georgi Djakov <georgi.djakov@linaro.org>
26 Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
27 Signed-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