|
9 | 9 |
|
10 | 10 | #include <linux/err.h>
|
11 | 11 | #include <linux/of.h>
|
| 12 | +#include <linux/of_device.h> |
12 | 13 | #include <linux/platform_device.h>
|
13 | 14 |
|
14 | 15 | #include "cpufreq-dt.h"
|
15 | 16 |
|
16 |
| -static const struct of_device_id machines[] __initconst = { |
| 17 | +/* |
| 18 | + * Machines for which the cpufreq device is *always* created, mostly used for |
| 19 | + * platforms using "operating-points" (V1) property. |
| 20 | + */ |
| 21 | +static const struct of_device_id whitelist[] __initconst = { |
17 | 22 | { .compatible = "allwinner,sun4i-a10", },
|
18 | 23 | { .compatible = "allwinner,sun5i-a10s", },
|
19 | 24 | { .compatible = "allwinner,sun5i-a13", },
|
@@ -107,21 +112,51 @@ static const struct of_device_id machines[] __initconst = {
|
107 | 112 | { }
|
108 | 113 | };
|
109 | 114 |
|
| 115 | +/* |
| 116 | + * Machines for which the cpufreq device is *not* created, mostly used for |
| 117 | + * platforms using "operating-points-v2" property. |
| 118 | + */ |
| 119 | +static const struct of_device_id blacklist[] __initconst = { |
| 120 | + { } |
| 121 | +}; |
| 122 | + |
| 123 | +static bool __init cpu0_node_has_opp_v2_prop(void) |
| 124 | +{ |
| 125 | + struct device_node *np = of_cpu_device_node_get(0); |
| 126 | + bool ret = false; |
| 127 | + |
| 128 | + if (of_get_property(np, "operating-points-v2", NULL)) |
| 129 | + ret = true; |
| 130 | + |
| 131 | + of_node_put(np); |
| 132 | + return ret; |
| 133 | +} |
| 134 | + |
110 | 135 | static int __init cpufreq_dt_platdev_init(void)
|
111 | 136 | {
|
112 | 137 | struct device_node *np = of_find_node_by_path("/");
|
113 | 138 | const struct of_device_id *match;
|
| 139 | + const void *data = NULL; |
114 | 140 |
|
115 | 141 | if (!np)
|
116 | 142 | return -ENODEV;
|
117 | 143 |
|
118 |
| - match = of_match_node(machines, np); |
| 144 | + match = of_match_node(whitelist, np); |
| 145 | + if (match) { |
| 146 | + data = match->data; |
| 147 | + goto create_pdev; |
| 148 | + } |
| 149 | + |
| 150 | + if (cpu0_node_has_opp_v2_prop() && !of_match_node(blacklist, np)) |
| 151 | + goto create_pdev; |
| 152 | + |
119 | 153 | of_node_put(np);
|
120 |
| - if (!match) |
121 |
| - return -ENODEV; |
| 154 | + return -ENODEV; |
122 | 155 |
|
| 156 | +create_pdev: |
| 157 | + of_node_put(np); |
123 | 158 | return PTR_ERR_OR_ZERO(platform_device_register_data(NULL, "cpufreq-dt",
|
124 |
| - -1, match->data, |
| 159 | + -1, data, |
125 | 160 | sizeof(struct cpufreq_dt_platform_data)));
|
126 | 161 | }
|
127 | 162 | device_initcall(cpufreq_dt_platdev_init);
|
0 commit comments