| From c4ebe3ac348552471d25a8edb1ea0b8df6aaf730 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 18 Oct 2023 10:06:02 +0200 |
| Subject: cpufreq: qcom-nvmem: Simplify driver data allocation |
| |
| From: Stephan Gerhold <stephan.gerhold@kernkonzept.com> |
| |
| [ Upstream commit 2a5d46c3ad6b0e62d2b04356ad999d504fb564e0 ] |
| |
| Simplify the allocation and cleanup of driver data by using devm |
| together with a flexible array. Prepare for adding additional per-CPU |
| data by defining a struct qcom_cpufreq_drv_cpu instead of storing the |
| opp_tokens directly. |
| |
| Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com> |
| Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org> |
| Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> |
| Stable-dep-of: d01c84b97f19 ("cpufreq: qcom-nvmem: fix memory leaks in probe error paths") |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/cpufreq/qcom-cpufreq-nvmem.c | 49 ++++++++++------------------ |
| 1 file changed, 18 insertions(+), 31 deletions(-) |
| |
| diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c |
| index 91634b84baa87..983991c0afd5c 100644 |
| --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c |
| +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c |
| @@ -53,10 +53,14 @@ struct qcom_cpufreq_match_data { |
| const char **genpd_names; |
| }; |
| |
| +struct qcom_cpufreq_drv_cpu { |
| + int opp_token; |
| +}; |
| + |
| struct qcom_cpufreq_drv { |
| - int *opp_tokens; |
| u32 versions; |
| const struct qcom_cpufreq_match_data *data; |
| + struct qcom_cpufreq_drv_cpu cpus[]; |
| }; |
| |
| static struct platform_device *cpufreq_dt_pdev, *cpufreq_pdev; |
| @@ -284,42 +288,32 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) |
| return -ENOENT; |
| } |
| |
| - drv = kzalloc(sizeof(*drv), GFP_KERNEL); |
| + drv = devm_kzalloc(&pdev->dev, struct_size(drv, cpus, num_possible_cpus()), |
| + GFP_KERNEL); |
| if (!drv) |
| return -ENOMEM; |
| |
| match = pdev->dev.platform_data; |
| drv->data = match->data; |
| - if (!drv->data) { |
| - ret = -ENODEV; |
| - goto free_drv; |
| - } |
| + if (!drv->data) |
| + return -ENODEV; |
| |
| if (drv->data->get_version) { |
| speedbin_nvmem = of_nvmem_cell_get(np, NULL); |
| - if (IS_ERR(speedbin_nvmem)) { |
| - ret = dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem), |
| - "Could not get nvmem cell\n"); |
| - goto free_drv; |
| - } |
| + if (IS_ERR(speedbin_nvmem)) |
| + return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem), |
| + "Could not get nvmem cell\n"); |
| |
| ret = drv->data->get_version(cpu_dev, |
| speedbin_nvmem, &pvs_name, drv); |
| if (ret) { |
| nvmem_cell_put(speedbin_nvmem); |
| - goto free_drv; |
| + return ret; |
| } |
| nvmem_cell_put(speedbin_nvmem); |
| } |
| of_node_put(np); |
| |
| - drv->opp_tokens = kcalloc(num_possible_cpus(), sizeof(*drv->opp_tokens), |
| - GFP_KERNEL); |
| - if (!drv->opp_tokens) { |
| - ret = -ENOMEM; |
| - goto free_drv; |
| - } |
| - |
| for_each_possible_cpu(cpu) { |
| struct dev_pm_opp_config config = { |
| .supported_hw = NULL, |
| @@ -345,9 +339,9 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) |
| } |
| |
| if (config.supported_hw || config.genpd_names) { |
| - drv->opp_tokens[cpu] = dev_pm_opp_set_config(cpu_dev, &config); |
| - if (drv->opp_tokens[cpu] < 0) { |
| - ret = drv->opp_tokens[cpu]; |
| + drv->cpus[cpu].opp_token = dev_pm_opp_set_config(cpu_dev, &config); |
| + if (drv->cpus[cpu].opp_token < 0) { |
| + ret = drv->cpus[cpu].opp_token; |
| dev_err(cpu_dev, "Failed to set OPP config\n"); |
| goto free_opp; |
| } |
| @@ -366,11 +360,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) |
| |
| free_opp: |
| for_each_possible_cpu(cpu) |
| - dev_pm_opp_clear_config(drv->opp_tokens[cpu]); |
| - kfree(drv->opp_tokens); |
| -free_drv: |
| - kfree(drv); |
| - |
| + dev_pm_opp_clear_config(drv->cpus[cpu].opp_token); |
| return ret; |
| } |
| |
| @@ -382,10 +372,7 @@ static void qcom_cpufreq_remove(struct platform_device *pdev) |
| platform_device_unregister(cpufreq_dt_pdev); |
| |
| for_each_possible_cpu(cpu) |
| - dev_pm_opp_clear_config(drv->opp_tokens[cpu]); |
| - |
| - kfree(drv->opp_tokens); |
| - kfree(drv); |
| + dev_pm_opp_clear_config(drv->cpus[cpu].opp_token); |
| } |
| |
| static struct platform_driver qcom_cpufreq_driver = { |
| -- |
| 2.43.0 |
| |