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
6 From: Viresh Kumar <viresh.kumar@linaro.org>
8 commit 0334906c06967142c8805fbe88acf787f65d3d26 upstream.
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
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.
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>
30 drivers/cpufreq/qcom-cpufreq-kryo.c | 20 ++++++++++++++++++--
31 1 file changed, 18 insertions(+), 2 deletions(-)
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
37 static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
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
48 + opp_tables = kcalloc(num_possible_cpus(), sizeof(*opp_tables), GFP_KERNEL);
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
57 cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
59 - if (!IS_ERR(cpufreq_dt_pdev))
60 + if (!IS_ERR(cpufreq_dt_pdev)) {
61 + platform_set_drvdata(pdev, opp_tables);
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:
69 dev_pm_opp_put_supported_hw(opp_tables[cpu]);
76 static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
78 + struct opp_table **opp_tables = platform_get_drvdata(pdev);
81 platform_device_unregister(cpufreq_dt_pdev);
83 + for_each_possible_cpu(cpu)
84 + dev_pm_opp_put_supported_hw(opp_tables[cpu]);