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/export.h>
0016 #include <linux/module.h>
0017 #include <linux/of_platform.h>
0018 #include <linux/pm_opp.h>
0019 #include <linux/scpi_protocol.h>
0020 #include <linux/slab.h>
0021 #include <linux/types.h>
0022
0023 struct scpi_data {
0024 struct clk *clk;
0025 struct device *cpu_dev;
0026 };
0027
0028 static struct scpi_ops *scpi_ops;
0029
0030 static unsigned int scpi_cpufreq_get_rate(unsigned int cpu)
0031 {
0032 struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
0033 struct scpi_data *priv = policy->driver_data;
0034 unsigned long rate = clk_get_rate(priv->clk);
0035
0036 return rate / 1000;
0037 }
0038
0039 static int
0040 scpi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
0041 {
0042 u64 rate = policy->freq_table[index].frequency * 1000;
0043 struct scpi_data *priv = policy->driver_data;
0044 int ret;
0045
0046 ret = clk_set_rate(priv->clk, rate);
0047
0048 if (ret)
0049 return ret;
0050
0051 if (clk_get_rate(priv->clk) != rate)
0052 return -EIO;
0053
0054 return 0;
0055 }
0056
0057 static int
0058 scpi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
0059 {
0060 int cpu, domain, tdomain;
0061 struct device *tcpu_dev;
0062
0063 domain = scpi_ops->device_domain_id(cpu_dev);
0064 if (domain < 0)
0065 return domain;
0066
0067 for_each_possible_cpu(cpu) {
0068 if (cpu == cpu_dev->id)
0069 continue;
0070
0071 tcpu_dev = get_cpu_device(cpu);
0072 if (!tcpu_dev)
0073 continue;
0074
0075 tdomain = scpi_ops->device_domain_id(tcpu_dev);
0076 if (tdomain == domain)
0077 cpumask_set_cpu(cpu, cpumask);
0078 }
0079
0080 return 0;
0081 }
0082
0083 static int scpi_cpufreq_init(struct cpufreq_policy *policy)
0084 {
0085 int ret;
0086 unsigned int latency;
0087 struct device *cpu_dev;
0088 struct scpi_data *priv;
0089 struct cpufreq_frequency_table *freq_table;
0090
0091 cpu_dev = get_cpu_device(policy->cpu);
0092 if (!cpu_dev) {
0093 pr_err("failed to get cpu%d device\n", policy->cpu);
0094 return -ENODEV;
0095 }
0096
0097 ret = scpi_ops->add_opps_to_device(cpu_dev);
0098 if (ret) {
0099 dev_warn(cpu_dev, "failed to add opps to the device\n");
0100 return ret;
0101 }
0102
0103 ret = scpi_get_sharing_cpus(cpu_dev, policy->cpus);
0104 if (ret) {
0105 dev_warn(cpu_dev, "failed to get sharing cpumask\n");
0106 return ret;
0107 }
0108
0109 ret = dev_pm_opp_set_sharing_cpus(cpu_dev, policy->cpus);
0110 if (ret) {
0111 dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
0112 __func__, ret);
0113 return ret;
0114 }
0115
0116 ret = dev_pm_opp_get_opp_count(cpu_dev);
0117 if (ret <= 0) {
0118 dev_dbg(cpu_dev, "OPP table is not ready, deferring probe\n");
0119 ret = -EPROBE_DEFER;
0120 goto out_free_opp;
0121 }
0122
0123 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0124 if (!priv) {
0125 ret = -ENOMEM;
0126 goto out_free_opp;
0127 }
0128
0129 ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
0130 if (ret) {
0131 dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
0132 goto out_free_priv;
0133 }
0134
0135 priv->cpu_dev = cpu_dev;
0136 priv->clk = clk_get(cpu_dev, NULL);
0137 if (IS_ERR(priv->clk)) {
0138 dev_err(cpu_dev, "%s: Failed to get clk for cpu: %d\n",
0139 __func__, cpu_dev->id);
0140 ret = PTR_ERR(priv->clk);
0141 goto out_free_cpufreq_table;
0142 }
0143
0144 policy->driver_data = priv;
0145 policy->freq_table = freq_table;
0146
0147
0148 policy->dvfs_possible_from_any_cpu = true;
0149
0150 latency = scpi_ops->get_transition_latency(cpu_dev);
0151 if (!latency)
0152 latency = CPUFREQ_ETERNAL;
0153
0154 policy->cpuinfo.transition_latency = latency;
0155
0156 policy->fast_switch_possible = false;
0157
0158 return 0;
0159
0160 out_free_cpufreq_table:
0161 dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
0162 out_free_priv:
0163 kfree(priv);
0164 out_free_opp:
0165 dev_pm_opp_remove_all_dynamic(cpu_dev);
0166
0167 return ret;
0168 }
0169
0170 static int scpi_cpufreq_exit(struct cpufreq_policy *policy)
0171 {
0172 struct scpi_data *priv = policy->driver_data;
0173
0174 clk_put(priv->clk);
0175 dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
0176 dev_pm_opp_remove_all_dynamic(priv->cpu_dev);
0177 kfree(priv);
0178
0179 return 0;
0180 }
0181
0182 static struct cpufreq_driver scpi_cpufreq_driver = {
0183 .name = "scpi-cpufreq",
0184 .flags = CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
0185 CPUFREQ_NEED_INITIAL_FREQ_CHECK |
0186 CPUFREQ_IS_COOLING_DEV,
0187 .verify = cpufreq_generic_frequency_table_verify,
0188 .attr = cpufreq_generic_attr,
0189 .get = scpi_cpufreq_get_rate,
0190 .init = scpi_cpufreq_init,
0191 .exit = scpi_cpufreq_exit,
0192 .target_index = scpi_cpufreq_set_target,
0193 .register_em = cpufreq_register_em_with_opp,
0194 };
0195
0196 static int scpi_cpufreq_probe(struct platform_device *pdev)
0197 {
0198 int ret;
0199
0200 scpi_ops = get_scpi_ops();
0201 if (!scpi_ops)
0202 return -EIO;
0203
0204 ret = cpufreq_register_driver(&scpi_cpufreq_driver);
0205 if (ret)
0206 dev_err(&pdev->dev, "%s: registering cpufreq failed, err: %d\n",
0207 __func__, ret);
0208 return ret;
0209 }
0210
0211 static int scpi_cpufreq_remove(struct platform_device *pdev)
0212 {
0213 cpufreq_unregister_driver(&scpi_cpufreq_driver);
0214 scpi_ops = NULL;
0215 return 0;
0216 }
0217
0218 static struct platform_driver scpi_cpufreq_platdrv = {
0219 .driver = {
0220 .name = "scpi-cpufreq",
0221 },
0222 .probe = scpi_cpufreq_probe,
0223 .remove = scpi_cpufreq_remove,
0224 };
0225 module_platform_driver(scpi_cpufreq_platdrv);
0226
0227 MODULE_ALIAS("platform:scpi-cpufreq");
0228 MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
0229 MODULE_DESCRIPTION("ARM SCPI CPUFreq interface driver");
0230 MODULE_LICENSE("GPL v2");