0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define pr_fmt(fmt) "mvebu-pmsu: " fmt
0013
0014 #include <linux/clk.h>
0015 #include <linux/cpu.h>
0016 #include <linux/init.h>
0017 #include <linux/kernel.h>
0018 #include <linux/of_address.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/pm_opp.h>
0021 #include <linux/resource.h>
0022
0023 static int __init armada_xp_pmsu_cpufreq_init(void)
0024 {
0025 struct device_node *np;
0026 struct resource res;
0027 int ret, cpu;
0028
0029 if (!of_machine_is_compatible("marvell,armadaxp"))
0030 return 0;
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 np = of_find_compatible_node(NULL, NULL, "marvell,armada-xp-cpu-clock");
0041 if (!np)
0042 return 0;
0043
0044 ret = of_address_to_resource(np, 1, &res);
0045 if (ret) {
0046 pr_warn(FW_WARN "not enabling cpufreq, deprecated armada-xp-cpu-clock binding\n");
0047 of_node_put(np);
0048 return 0;
0049 }
0050
0051 of_node_put(np);
0052
0053
0054
0055
0056
0057
0058
0059 for_each_possible_cpu(cpu) {
0060 struct device *cpu_dev;
0061 struct clk *clk;
0062 int ret;
0063
0064 cpu_dev = get_cpu_device(cpu);
0065 if (!cpu_dev) {
0066 pr_err("Cannot get CPU %d\n", cpu);
0067 continue;
0068 }
0069
0070 clk = clk_get(cpu_dev, NULL);
0071 if (IS_ERR(clk)) {
0072 pr_err("Cannot get clock for CPU %d\n", cpu);
0073 return PTR_ERR(clk);
0074 }
0075
0076 ret = dev_pm_opp_add(cpu_dev, clk_get_rate(clk), 0);
0077 if (ret) {
0078 clk_put(clk);
0079 return ret;
0080 }
0081
0082 ret = dev_pm_opp_add(cpu_dev, clk_get_rate(clk) / 2, 0);
0083 if (ret) {
0084 dev_pm_opp_remove(cpu_dev, clk_get_rate(clk));
0085 clk_put(clk);
0086 dev_err(cpu_dev, "Failed to register OPPs\n");
0087 return ret;
0088 }
0089
0090 ret = dev_pm_opp_set_sharing_cpus(cpu_dev,
0091 cpumask_of(cpu_dev->id));
0092 if (ret)
0093 dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
0094 __func__, ret);
0095 clk_put(clk);
0096 }
0097
0098 platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
0099 return 0;
0100 }
0101 device_initcall(armada_xp_pmsu_cpufreq_init);