Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'cpufreq/arm/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm

Pull cpufreq-arm fixes for 5.10-rc5 from Viresh Kumar:

"- tegra186: Fix ->get() callback.
- arm/scmi: Add dummy clock provider to fix failure."

* 'cpufreq/arm/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm:
cpufreq: scmi: Fix OPP addition failure with a dummy clock provider
cpufreq: tegra186: Fix get frequency callback

+27 -12
+6
drivers/cpufreq/scmi-cpufreq.c
··· 8 8 9 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 10 11 + #include <linux/clk-provider.h> 11 12 #include <linux/cpu.h> 12 13 #include <linux/cpufreq.h> 13 14 #include <linux/cpumask.h> ··· 229 228 static int scmi_cpufreq_probe(struct scmi_device *sdev) 230 229 { 231 230 int ret; 231 + struct device *dev = &sdev->dev; 232 232 233 233 handle = sdev->handle; 234 234 235 235 if (!handle || !handle->perf_ops) 236 236 return -ENODEV; 237 + 238 + /* dummy clock provider as needed by OPP if clocks property is used */ 239 + if (of_find_property(dev->of_node, "#clock-cells", NULL)) 240 + devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); 237 241 238 242 ret = cpufreq_register_driver(&scmi_cpufreq_driver); 239 243 if (ret) {
+21 -12
drivers/cpufreq/tegra186-cpufreq.c
··· 42 42 struct tegra186_cpufreq_cluster { 43 43 const struct tegra186_cpufreq_cluster_info *info; 44 44 struct cpufreq_frequency_table *table; 45 + u32 ref_clk_khz; 46 + u32 div; 45 47 }; 46 48 47 49 struct tegra186_cpufreq_data { ··· 96 94 97 95 static unsigned int tegra186_cpufreq_get(unsigned int cpu) 98 96 { 99 - struct cpufreq_frequency_table *tbl; 97 + struct tegra186_cpufreq_data *data = cpufreq_get_driver_data(); 100 98 struct cpufreq_policy *policy; 101 99 void __iomem *edvd_reg; 102 100 unsigned int i, freq = 0; ··· 106 104 if (!policy) 107 105 return 0; 108 106 109 - tbl = policy->freq_table; 110 107 edvd_reg = policy->driver_data; 111 108 ndiv = readl(edvd_reg) & EDVD_CORE_VOLT_FREQ_F_MASK; 112 109 113 - for (i = 0; tbl[i].frequency != CPUFREQ_TABLE_END; i++) { 114 - if ((tbl[i].driver_data & EDVD_CORE_VOLT_FREQ_F_MASK) == ndiv) { 115 - freq = tbl[i].frequency; 116 - break; 110 + for (i = 0; i < data->num_clusters; i++) { 111 + struct tegra186_cpufreq_cluster *cluster = &data->clusters[i]; 112 + int core; 113 + 114 + for (core = 0; core < ARRAY_SIZE(cluster->info->cpus); core++) { 115 + if (cluster->info->cpus[core] != policy->cpu) 116 + continue; 117 + 118 + freq = (cluster->ref_clk_khz * ndiv) / cluster->div; 119 + goto out; 117 120 } 118 121 } 119 122 123 + out: 120 124 cpufreq_cpu_put(policy); 121 125 122 126 return freq; ··· 141 133 142 134 static struct cpufreq_frequency_table *init_vhint_table( 143 135 struct platform_device *pdev, struct tegra_bpmp *bpmp, 144 - unsigned int cluster_id) 136 + struct tegra186_cpufreq_cluster *cluster) 145 137 { 146 138 struct cpufreq_frequency_table *table; 147 139 struct mrq_cpu_vhint_request req; ··· 160 152 161 153 memset(&req, 0, sizeof(req)); 162 154 req.addr = phys; 163 - req.cluster_id = cluster_id; 155 + req.cluster_id = cluster->info->bpmp_cluster_id; 164 156 165 157 memset(&msg, 0, sizeof(msg)); 166 158 msg.mrq = MRQ_CPU_VHINT; ··· 193 185 goto free; 194 186 } 195 187 188 + cluster->ref_clk_khz = data->ref_clk_hz / 1000; 189 + cluster->div = data->pdiv * data->mdiv; 190 + 196 191 for (i = data->vfloor, j = 0; i <= data->vceil; i++) { 197 192 struct cpufreq_frequency_table *point; 198 193 u16 ndiv = data->ndiv[i]; ··· 213 202 214 203 point = &table[j++]; 215 204 point->driver_data = edvd_val; 216 - point->frequency = data->ref_clk_hz * ndiv / data->pdiv / 217 - data->mdiv / 1000; 205 + point->frequency = (cluster->ref_clk_khz * ndiv) / cluster->div; 218 206 } 219 207 220 208 table[j].frequency = CPUFREQ_TABLE_END; ··· 255 245 struct tegra186_cpufreq_cluster *cluster = &data->clusters[i]; 256 246 257 247 cluster->info = &tegra186_clusters[i]; 258 - cluster->table = init_vhint_table( 259 - pdev, bpmp, cluster->info->bpmp_cluster_id); 248 + cluster->table = init_vhint_table(pdev, bpmp, cluster); 260 249 if (IS_ERR(cluster->table)) { 261 250 err = PTR_ERR(cluster->table); 262 251 goto put_bpmp;