Commit 054a3ef6 authored by Manivannan Sadhasivam's avatar Manivannan Sadhasivam Committed by Viresh Kumar

cpufreq: qcom-hw: Allocate qcom_cpufreq_data during probe

qcom_cpufreq_data is allocated based on the number of frequency domains
defined in DT which is static and won't change during runtime. There is
no real reason to allocate it during the CPU init() callback and deallocate
it during exit(). Hence, move the allocation to probe() and use the
allocated memory during init().

This also allows us to use devm_platform_get_and_ioremap_resource() helper
for acquiring the freq-domain resources from DT.
Signed-off-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
parent 68069b0d
...@@ -61,6 +61,10 @@ struct qcom_cpufreq_data { ...@@ -61,6 +61,10 @@ struct qcom_cpufreq_data {
struct freq_qos_request throttle_freq_req; struct freq_qos_request throttle_freq_req;
}; };
static struct {
struct qcom_cpufreq_data *data;
} qcom_cpufreq;
static unsigned long cpu_hw_rate, xo_rate; static unsigned long cpu_hw_rate, xo_rate;
static bool icc_scaling_enabled; static bool icc_scaling_enabled;
...@@ -503,8 +507,6 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) ...@@ -503,8 +507,6 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
struct of_phandle_args args; struct of_phandle_args args;
struct device_node *cpu_np; struct device_node *cpu_np;
struct device *cpu_dev; struct device *cpu_dev;
struct resource *res;
void __iomem *base;
struct qcom_cpufreq_data *data; struct qcom_cpufreq_data *data;
int ret, index; int ret, index;
...@@ -526,43 +528,16 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) ...@@ -526,43 +528,16 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
return ret; return ret;
index = args.args[0]; index = args.args[0];
res = platform_get_resource(pdev, IORESOURCE_MEM, index);
if (!res) {
dev_err(dev, "failed to get mem resource %d\n", index);
return -ENODEV;
}
if (!request_mem_region(res->start, resource_size(res), res->name)) {
dev_err(dev, "failed to request resource %pR\n", res);
return -EBUSY;
}
base = ioremap(res->start, resource_size(res));
if (!base) {
dev_err(dev, "failed to map resource %pR\n", res);
ret = -ENOMEM;
goto release_region;
}
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto unmap_base;
}
data->soc_data = of_device_get_match_data(&pdev->dev); data->soc_data = of_device_get_match_data(&pdev->dev);
data->base = base; data = &qcom_cpufreq.data[index];
data->res = res;
/* HW should be in enabled state to proceed */ /* HW should be in enabled state to proceed */
if (!(readl_relaxed(base + data->soc_data->reg_enable) & 0x1)) { if (!(readl_relaxed(data->base + data->soc_data->reg_enable) & 0x1)) {
dev_err(dev, "Domain-%d cpufreq hardware not enabled\n", index); dev_err(dev, "Domain-%d cpufreq hardware not enabled\n", index);
ret = -ENODEV; return -ENODEV;
goto error;
} }
if (readl_relaxed(base + data->soc_data->reg_dcvs_ctrl) & 0x1) if (readl_relaxed(data->base + data->soc_data->reg_dcvs_ctrl) & 0x1)
data->per_core_dcvs = true; data->per_core_dcvs = true;
qcom_get_related_cpus(index, policy->cpus); qcom_get_related_cpus(index, policy->cpus);
...@@ -573,14 +548,13 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) ...@@ -573,14 +548,13 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
ret = qcom_cpufreq_hw_read_lut(cpu_dev, policy); ret = qcom_cpufreq_hw_read_lut(cpu_dev, policy);
if (ret) { if (ret) {
dev_err(dev, "Domain-%d failed to read LUT\n", index); dev_err(dev, "Domain-%d failed to read LUT\n", index);
goto error; return ret;
} }
ret = dev_pm_opp_get_opp_count(cpu_dev); ret = dev_pm_opp_get_opp_count(cpu_dev);
if (ret <= 0) { if (ret <= 0) {
dev_err(cpu_dev, "Failed to add OPPs\n"); dev_err(cpu_dev, "Failed to add OPPs\n");
ret = -ENODEV; return -ENODEV;
goto error;
} }
if (policy_has_boost_freq(policy)) { if (policy_has_boost_freq(policy)) {
...@@ -589,18 +563,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) ...@@ -589,18 +563,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
dev_warn(cpu_dev, "failed to enable boost: %d\n", ret); dev_warn(cpu_dev, "failed to enable boost: %d\n", ret);
} }
ret = qcom_cpufreq_hw_lmh_init(policy, index); return qcom_cpufreq_hw_lmh_init(policy, index);
if (ret)
goto error;
return 0;
error:
kfree(data);
unmap_base:
iounmap(base);
release_region:
release_mem_region(res->start, resource_size(res));
return ret;
} }
static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy) static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
...@@ -657,7 +620,7 @@ static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev) ...@@ -657,7 +620,7 @@ static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
{ {
struct device *cpu_dev; struct device *cpu_dev;
struct clk *clk; struct clk *clk;
int ret; int ret, i, num_domains;
clk = clk_get(&pdev->dev, "xo"); clk = clk_get(&pdev->dev, "xo");
if (IS_ERR(clk)) if (IS_ERR(clk))
...@@ -684,6 +647,31 @@ static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev) ...@@ -684,6 +647,31 @@ static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
if (ret) if (ret)
return ret; return ret;
/* Allocate qcom_cpufreq_data based on the available frequency domains in DT */
num_domains = of_property_count_elems_of_size(pdev->dev.of_node, "reg", sizeof(u32) * 4);
if (num_domains <= 0)
return num_domains;
qcom_cpufreq.data = devm_kzalloc(&pdev->dev, sizeof(struct qcom_cpufreq_data) * num_domains,
GFP_KERNEL);
if (!qcom_cpufreq.data)
return -ENOMEM;
for (i = 0; i < num_domains; i++) {
struct qcom_cpufreq_data *data = &qcom_cpufreq.data[i];
struct resource *res;
void __iomem *base;
base = devm_platform_get_and_ioremap_resource(pdev, i, &res);
if (IS_ERR(base)) {
dev_err(&pdev->dev, "Failed to map resource %pR\n", res);
return PTR_ERR(base);
}
data->base = base;
data->res = res;
}
ret = cpufreq_register_driver(&cpufreq_qcom_hw_driver); ret = cpufreq_register_driver(&cpufreq_qcom_hw_driver);
if (ret) if (ret)
dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n"); dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment