diff options
author | Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | 2023-03-23 20:40:26 +0300 |
---|---|---|
committer | Viresh Kumar <viresh.kumar@linaro.org> | 2023-03-30 06:51:00 +0300 |
commit | ba5e770c9698782bc203bbf5cf3b36a77720bdbe (patch) | |
tree | 0838f355b324ea98fe82e0ef10260ec887a67a06 /drivers/cpufreq/qcom-cpufreq-hw.c | |
parent | 0883426fd07e39355362e3f2eb9aee1a154dcaf6 (diff) | |
download | linux-ba5e770c9698782bc203bbf5cf3b36a77720bdbe.tar.xz |
cpufreq: qcom-cpufreq-hw: fix double IO unmap and resource release on exit
Commit 054a3ef683a1 ("cpufreq: qcom-hw: Allocate qcom_cpufreq_data
during probe") moved getting memory resource and iomap from
qcom_cpufreq_hw_cpu_init() to the probe function, however it left
untouched cleanup in qcom_cpufreq_hw_cpu_exit().
During device unbind this will lead to doule release of resource and
double iounmap(), first by qcom_cpufreq_hw_cpu_exit() and second via
managed resources:
resource: Trying to free nonexistent resource <0x0000000018593000-0x0000000018593fff>
Trying to vunmap() nonexistent vm area (0000000088a7d4dc)
...
vunmap (mm/vmalloc.c:2771 (discriminator 1))
iounmap (mm/ioremap.c:60)
devm_ioremap_release (lib/devres.c:19)
devres_release_all (drivers/base/devres.c:506 drivers/base/devres.c:535)
device_unbind_cleanup (drivers/base/dd.c:523)
device_release_driver_internal (drivers/base/dd.c:1248 drivers/base/dd.c:1263)
device_driver_detach (drivers/base/dd.c:1300)
unbind_store (drivers/base/bus.c:243)
drv_attr_store (drivers/base/bus.c:127)
sysfs_kf_write (fs/sysfs/file.c:137)
kernfs_fop_write_iter (fs/kernfs/file.c:334)
vfs_write (include/linux/fs.h:1851 fs/read_write.c:491 fs/read_write.c:584)
ksys_write (fs/read_write.c:637)
__arm64_sys_write (fs/read_write.c:646)
invoke_syscall (arch/arm64/include/asm/current.h:19 arch/arm64/kernel/syscall.c:57)
el0_svc_common.constprop.0 (arch/arm64/include/asm/daifflags.h:28 arch/arm64/kernel/syscall.c:150)
do_el0_svc (arch/arm64/kernel/syscall.c:194)
el0_svc (arch/arm64/include/asm/daifflags.h:28 arch/arm64/kernel/entry-common.c:133 arch/arm64/kernel/entry-common.c:142 arch/arm64/kernel/entry-common.c:638)
el0t_64_sync_handler (arch/arm64/kernel/entry-common.c:656)
el0t_64_sync (arch/arm64/kernel/entry.S:591)
Fixes: 054a3ef683a1 ("cpufreq: qcom-hw: Allocate qcom_cpufreq_data during probe")
Cc: <stable@vger.kernel.org>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Diffstat (limited to 'drivers/cpufreq/qcom-cpufreq-hw.c')
-rw-r--r-- | drivers/cpufreq/qcom-cpufreq-hw.c | 11 |
1 files changed, 2 insertions, 9 deletions
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index 575a4461c25a..b75e6157dc81 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -45,7 +45,6 @@ struct qcom_cpufreq_soc_data { struct qcom_cpufreq_data { void __iomem *base; - struct resource *res; /* * Mutex to synchronize between de-init sequence and re-starting LMh @@ -592,16 +591,12 @@ static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy) { struct device *cpu_dev = get_cpu_device(policy->cpu); struct qcom_cpufreq_data *data = policy->driver_data; - struct resource *res = data->res; - void __iomem *base = data->base; dev_pm_opp_remove_all_dynamic(cpu_dev); dev_pm_opp_of_cpumask_remove_table(policy->related_cpus); qcom_cpufreq_hw_lmh_exit(data); kfree(policy->freq_table); kfree(data); - iounmap(base); - release_mem_region(res->start, resource_size(res)); return 0; } @@ -704,17 +699,15 @@ static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev) for (i = 0; i < num_domains; i++) { struct qcom_cpufreq_data *data = &qcom_cpufreq.data[i]; struct clk_init_data clk_init = {}; - struct resource *res; void __iomem *base; - base = devm_platform_get_and_ioremap_resource(pdev, i, &res); + base = devm_platform_ioremap_resource(pdev, i); if (IS_ERR(base)) { - dev_err(dev, "Failed to map resource %pR\n", res); + dev_err(dev, "Failed to map resource index %d\n", i); return PTR_ERR(base); } data->base = base; - data->res = res; /* Register CPU clock for each frequency domain */ clk_init.name = kasprintf(GFP_KERNEL, "qcom_cpufreq%d", i); |