Commit 2a5d46c3 authored by Stephan Gerhold's avatar Stephan Gerhold Committed by Viresh Kumar
Browse files

cpufreq: qcom-nvmem: Simplify driver data allocation



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: default avatarStephan Gerhold <stephan.gerhold@kernkonzept.com>
Reviewed-by: default avatarKonrad Dybcio <konrad.dybcio@linaro.org>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
parent dce13a23
Loading
Loading
Loading
Loading
+18 −31
Original line number Diff line number Diff line
@@ -40,10 +40,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;
@@ -243,42 +247,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),
		if (IS_ERR(speedbin_nvmem))
			return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem),
					     "Could not get nvmem cell\n");
			goto free_drv;
		}

		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,
@@ -304,9 +298,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;
			}
@@ -325,11 +319,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;
}

@@ -341,10 +331,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 = {