0001
0002
0003
0004
0005
0006
0007
0008
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010
0011 #include <linux/clk.h>
0012 #include <linux/cpu.h>
0013 #include <linux/cpufreq.h>
0014 #include <linux/cpumask.h>
0015 #include <linux/err.h>
0016 #include <linux/list.h>
0017 #include <linux/module.h>
0018 #include <linux/of.h>
0019 #include <linux/pm_opp.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/regulator/consumer.h>
0022 #include <linux/slab.h>
0023 #include <linux/thermal.h>
0024
0025 #include "cpufreq-dt.h"
0026
0027 struct private_data {
0028 struct list_head node;
0029
0030 cpumask_var_t cpus;
0031 struct device *cpu_dev;
0032 struct cpufreq_frequency_table *freq_table;
0033 bool have_static_opps;
0034 int opp_token;
0035 };
0036
0037 static LIST_HEAD(priv_list);
0038
0039 static struct freq_attr *cpufreq_dt_attr[] = {
0040 &cpufreq_freq_attr_scaling_available_freqs,
0041 NULL,
0042 NULL,
0043 };
0044
0045 static struct private_data *cpufreq_dt_find_data(int cpu)
0046 {
0047 struct private_data *priv;
0048
0049 list_for_each_entry(priv, &priv_list, node) {
0050 if (cpumask_test_cpu(cpu, priv->cpus))
0051 return priv;
0052 }
0053
0054 return NULL;
0055 }
0056
0057 static int set_target(struct cpufreq_policy *policy, unsigned int index)
0058 {
0059 struct private_data *priv = policy->driver_data;
0060 unsigned long freq = policy->freq_table[index].frequency;
0061
0062 return dev_pm_opp_set_rate(priv->cpu_dev, freq * 1000);
0063 }
0064
0065
0066
0067
0068
0069 static const char *find_supply_name(struct device *dev)
0070 {
0071 struct device_node *np;
0072 struct property *pp;
0073 int cpu = dev->id;
0074 const char *name = NULL;
0075
0076 np = of_node_get(dev->of_node);
0077
0078
0079 if (WARN_ON(!np))
0080 return NULL;
0081
0082
0083 if (!cpu) {
0084 pp = of_find_property(np, "cpu0-supply", NULL);
0085 if (pp) {
0086 name = "cpu0";
0087 goto node_put;
0088 }
0089 }
0090
0091 pp = of_find_property(np, "cpu-supply", NULL);
0092 if (pp) {
0093 name = "cpu";
0094 goto node_put;
0095 }
0096
0097 dev_dbg(dev, "no regulator for cpu%d\n", cpu);
0098 node_put:
0099 of_node_put(np);
0100 return name;
0101 }
0102
0103 static int cpufreq_init(struct cpufreq_policy *policy)
0104 {
0105 struct private_data *priv;
0106 struct device *cpu_dev;
0107 struct clk *cpu_clk;
0108 unsigned int transition_latency;
0109 int ret;
0110
0111 priv = cpufreq_dt_find_data(policy->cpu);
0112 if (!priv) {
0113 pr_err("failed to find data for cpu%d\n", policy->cpu);
0114 return -ENODEV;
0115 }
0116 cpu_dev = priv->cpu_dev;
0117
0118 cpu_clk = clk_get(cpu_dev, NULL);
0119 if (IS_ERR(cpu_clk)) {
0120 ret = PTR_ERR(cpu_clk);
0121 dev_err(cpu_dev, "%s: failed to get clk: %d\n", __func__, ret);
0122 return ret;
0123 }
0124
0125 transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
0126 if (!transition_latency)
0127 transition_latency = CPUFREQ_ETERNAL;
0128
0129 cpumask_copy(policy->cpus, priv->cpus);
0130 policy->driver_data = priv;
0131 policy->clk = cpu_clk;
0132 policy->freq_table = priv->freq_table;
0133 policy->suspend_freq = dev_pm_opp_get_suspend_opp_freq(cpu_dev) / 1000;
0134 policy->cpuinfo.transition_latency = transition_latency;
0135 policy->dvfs_possible_from_any_cpu = true;
0136
0137
0138 if (policy_has_boost_freq(policy)) {
0139
0140 ret = cpufreq_enable_boost_support();
0141 if (ret)
0142 goto out_clk_put;
0143 cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;
0144 }
0145
0146 return 0;
0147
0148 out_clk_put:
0149 clk_put(cpu_clk);
0150
0151 return ret;
0152 }
0153
0154 static int cpufreq_online(struct cpufreq_policy *policy)
0155 {
0156
0157 return 0;
0158 }
0159
0160 static int cpufreq_offline(struct cpufreq_policy *policy)
0161 {
0162
0163
0164
0165
0166 return 0;
0167 }
0168
0169 static int cpufreq_exit(struct cpufreq_policy *policy)
0170 {
0171 clk_put(policy->clk);
0172 return 0;
0173 }
0174
0175 static struct cpufreq_driver dt_cpufreq_driver = {
0176 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |
0177 CPUFREQ_IS_COOLING_DEV,
0178 .verify = cpufreq_generic_frequency_table_verify,
0179 .target_index = set_target,
0180 .get = cpufreq_generic_get,
0181 .init = cpufreq_init,
0182 .exit = cpufreq_exit,
0183 .online = cpufreq_online,
0184 .offline = cpufreq_offline,
0185 .register_em = cpufreq_register_em_with_opp,
0186 .name = "cpufreq-dt",
0187 .attr = cpufreq_dt_attr,
0188 .suspend = cpufreq_generic_suspend,
0189 };
0190
0191 static int dt_cpufreq_early_init(struct device *dev, int cpu)
0192 {
0193 struct private_data *priv;
0194 struct device *cpu_dev;
0195 bool fallback = false;
0196 const char *reg_name[] = { NULL, NULL };
0197 int ret;
0198
0199
0200 if (cpufreq_dt_find_data(cpu))
0201 return 0;
0202
0203 cpu_dev = get_cpu_device(cpu);
0204 if (!cpu_dev)
0205 return -EPROBE_DEFER;
0206
0207 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0208 if (!priv)
0209 return -ENOMEM;
0210
0211 if (!alloc_cpumask_var(&priv->cpus, GFP_KERNEL))
0212 return -ENOMEM;
0213
0214 cpumask_set_cpu(cpu, priv->cpus);
0215 priv->cpu_dev = cpu_dev;
0216
0217
0218
0219
0220
0221 reg_name[0] = find_supply_name(cpu_dev);
0222 if (reg_name[0]) {
0223 priv->opp_token = dev_pm_opp_set_regulators(cpu_dev, reg_name);
0224 if (priv->opp_token < 0) {
0225 ret = priv->opp_token;
0226 if (ret != -EPROBE_DEFER)
0227 dev_err(cpu_dev, "failed to set regulators: %d\n",
0228 ret);
0229 goto free_cpumask;
0230 }
0231 }
0232
0233
0234 ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, priv->cpus);
0235 if (ret) {
0236 if (ret != -ENOENT)
0237 goto out;
0238
0239
0240
0241
0242
0243
0244 if (dev_pm_opp_get_sharing_cpus(cpu_dev, priv->cpus))
0245 fallback = true;
0246 }
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 ret = dev_pm_opp_of_cpumask_add_table(priv->cpus);
0260 if (!ret) {
0261 priv->have_static_opps = true;
0262 } else if (ret == -EPROBE_DEFER) {
0263 goto out;
0264 }
0265
0266
0267
0268
0269
0270 ret = dev_pm_opp_get_opp_count(cpu_dev);
0271 if (ret <= 0) {
0272 dev_err(cpu_dev, "OPP table can't be empty\n");
0273 ret = -ENODEV;
0274 goto out;
0275 }
0276
0277 if (fallback) {
0278 cpumask_setall(priv->cpus);
0279 ret = dev_pm_opp_set_sharing_cpus(cpu_dev, priv->cpus);
0280 if (ret)
0281 dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
0282 __func__, ret);
0283 }
0284
0285 ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &priv->freq_table);
0286 if (ret) {
0287 dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
0288 goto out;
0289 }
0290
0291 list_add(&priv->node, &priv_list);
0292 return 0;
0293
0294 out:
0295 if (priv->have_static_opps)
0296 dev_pm_opp_of_cpumask_remove_table(priv->cpus);
0297 dev_pm_opp_put_regulators(priv->opp_token);
0298 free_cpumask:
0299 free_cpumask_var(priv->cpus);
0300 return ret;
0301 }
0302
0303 static void dt_cpufreq_release(void)
0304 {
0305 struct private_data *priv, *tmp;
0306
0307 list_for_each_entry_safe(priv, tmp, &priv_list, node) {
0308 dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &priv->freq_table);
0309 if (priv->have_static_opps)
0310 dev_pm_opp_of_cpumask_remove_table(priv->cpus);
0311 dev_pm_opp_put_regulators(priv->opp_token);
0312 free_cpumask_var(priv->cpus);
0313 list_del(&priv->node);
0314 }
0315 }
0316
0317 static int dt_cpufreq_probe(struct platform_device *pdev)
0318 {
0319 struct cpufreq_dt_platform_data *data = dev_get_platdata(&pdev->dev);
0320 int ret, cpu;
0321
0322
0323 for_each_possible_cpu(cpu) {
0324 ret = dt_cpufreq_early_init(&pdev->dev, cpu);
0325 if (ret)
0326 goto err;
0327 }
0328
0329 if (data) {
0330 if (data->have_governor_per_policy)
0331 dt_cpufreq_driver.flags |= CPUFREQ_HAVE_GOVERNOR_PER_POLICY;
0332
0333 dt_cpufreq_driver.resume = data->resume;
0334 if (data->suspend)
0335 dt_cpufreq_driver.suspend = data->suspend;
0336 if (data->get_intermediate) {
0337 dt_cpufreq_driver.target_intermediate = data->target_intermediate;
0338 dt_cpufreq_driver.get_intermediate = data->get_intermediate;
0339 }
0340 }
0341
0342 ret = cpufreq_register_driver(&dt_cpufreq_driver);
0343 if (ret) {
0344 dev_err(&pdev->dev, "failed register driver: %d\n", ret);
0345 goto err;
0346 }
0347
0348 return 0;
0349 err:
0350 dt_cpufreq_release();
0351 return ret;
0352 }
0353
0354 static int dt_cpufreq_remove(struct platform_device *pdev)
0355 {
0356 cpufreq_unregister_driver(&dt_cpufreq_driver);
0357 dt_cpufreq_release();
0358 return 0;
0359 }
0360
0361 static struct platform_driver dt_cpufreq_platdrv = {
0362 .driver = {
0363 .name = "cpufreq-dt",
0364 },
0365 .probe = dt_cpufreq_probe,
0366 .remove = dt_cpufreq_remove,
0367 };
0368 module_platform_driver(dt_cpufreq_platdrv);
0369
0370 MODULE_ALIAS("platform:cpufreq-dt");
0371 MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
0372 MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
0373 MODULE_DESCRIPTION("Generic cpufreq driver");
0374 MODULE_LICENSE("GPL");