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

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

Pull ARM cpufreq updates for 5.17-rc1 from Viresh Kumar:

"- Qcom cpufreq driver updates improve irq support (Ard Biesheuvel, Stephen Boyd,
and Vladimir Zapolskiy).

- Fixes double devm_remap for mediatek driver (Hector Yuan).

- Introduces thermal pressure helpers (Lukasz Luba)."

* 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm:
cpufreq: mediatek-hw: Fix double devm_remap in hotplug case
cpufreq: qcom-hw: Use optional irq API
cpufreq: qcom-hw: Set CPU affinity of dcvsh interrupts
cpufreq: qcom-hw: Fix probable nested interrupt handling
cpufreq: qcom-cpufreq-hw: Avoid stack buffer for IRQ name
arch_topology: Remove unused topology_set_thermal_pressure() and related
cpufreq: qcom-cpufreq-hw: Use new thermal pressure update function
cpufreq: qcom-cpufreq-hw: Update offline CPUs per-cpu thermal pressure
thermal: cpufreq_cooling: Use new thermal pressure update function
arch_topology: Introduce thermal pressure update function

+96 -40
+1 -1
arch/arm/include/asm/topology.h
··· 23 23 24 24 /* Replace task scheduler's default thermal pressure API */ 25 25 #define arch_scale_thermal_pressure topology_get_thermal_pressure 26 - #define arch_set_thermal_pressure topology_set_thermal_pressure 26 + #define arch_update_thermal_pressure topology_update_thermal_pressure 27 27 28 28 #else 29 29
+1 -1
arch/arm64/include/asm/topology.h
··· 32 32 33 33 /* Replace task scheduler's default thermal pressure API */ 34 34 #define arch_scale_thermal_pressure topology_get_thermal_pressure 35 - #define arch_set_thermal_pressure topology_set_thermal_pressure 35 + #define arch_update_thermal_pressure topology_update_thermal_pressure 36 36 37 37 #include <asm-generic/topology.h> 38 38
+38 -4
drivers/base/arch_topology.c
··· 22 22 static DEFINE_PER_CPU(struct scale_freq_data __rcu *, sft_data); 23 23 static struct cpumask scale_freq_counters_mask; 24 24 static bool scale_freq_invariant; 25 + static DEFINE_PER_CPU(u32, freq_factor) = 1; 25 26 26 27 static bool supports_scale_freq_counters(const struct cpumask *cpus) 27 28 { ··· 156 155 157 156 DEFINE_PER_CPU(unsigned long, thermal_pressure); 158 157 159 - void topology_set_thermal_pressure(const struct cpumask *cpus, 160 - unsigned long th_pressure) 158 + /** 159 + * topology_update_thermal_pressure() - Update thermal pressure for CPUs 160 + * @cpus : The related CPUs for which capacity has been reduced 161 + * @capped_freq : The maximum allowed frequency that CPUs can run at 162 + * 163 + * Update the value of thermal pressure for all @cpus in the mask. The 164 + * cpumask should include all (online+offline) affected CPUs, to avoid 165 + * operating on stale data when hot-plug is used for some CPUs. The 166 + * @capped_freq reflects the currently allowed max CPUs frequency due to 167 + * thermal capping. It might be also a boost frequency value, which is bigger 168 + * than the internal 'freq_factor' max frequency. In such case the pressure 169 + * value should simply be removed, since this is an indication that there is 170 + * no thermal throttling. The @capped_freq must be provided in kHz. 171 + */ 172 + void topology_update_thermal_pressure(const struct cpumask *cpus, 173 + unsigned long capped_freq) 161 174 { 175 + unsigned long max_capacity, capacity, th_pressure; 176 + u32 max_freq; 162 177 int cpu; 178 + 179 + cpu = cpumask_first(cpus); 180 + max_capacity = arch_scale_cpu_capacity(cpu); 181 + max_freq = per_cpu(freq_factor, cpu); 182 + 183 + /* Convert to MHz scale which is used in 'freq_factor' */ 184 + capped_freq /= 1000; 185 + 186 + /* 187 + * Handle properly the boost frequencies, which should simply clean 188 + * the thermal pressure value. 189 + */ 190 + if (max_freq <= capped_freq) 191 + capacity = max_capacity; 192 + else 193 + capacity = mult_frac(max_capacity, capped_freq, max_freq); 194 + 195 + th_pressure = max_capacity - capacity; 163 196 164 197 for_each_cpu(cpu, cpus) 165 198 WRITE_ONCE(per_cpu(thermal_pressure, cpu), th_pressure); 166 199 } 167 - EXPORT_SYMBOL_GPL(topology_set_thermal_pressure); 200 + EXPORT_SYMBOL_GPL(topology_update_thermal_pressure); 168 201 169 202 static ssize_t cpu_capacity_show(struct device *dev, 170 203 struct device_attribute *attr, ··· 252 217 update_topology = 0; 253 218 } 254 219 255 - static DEFINE_PER_CPU(u32, freq_factor) = 1; 256 220 static u32 *raw_capacity; 257 221 258 222 static int free_raw_capacity(void)
+30 -3
drivers/cpufreq/mediatek-cpufreq-hw.c
··· 36 36 struct mtk_cpufreq_data { 37 37 struct cpufreq_frequency_table *table; 38 38 void __iomem *reg_bases[REG_ARRAY_SIZE]; 39 + struct resource *res; 40 + void __iomem *base; 39 41 int nr_opp; 40 42 }; 41 43 ··· 158 156 { 159 157 struct mtk_cpufreq_data *data; 160 158 struct device *dev = &pdev->dev; 159 + struct resource *res; 161 160 void __iomem *base; 162 161 int ret, i; 163 162 int index; ··· 173 170 if (index < 0) 174 171 return index; 175 172 176 - base = devm_platform_ioremap_resource(pdev, index); 177 - if (IS_ERR(base)) 178 - return PTR_ERR(base); 173 + res = platform_get_resource(pdev, IORESOURCE_MEM, index); 174 + if (!res) { 175 + dev_err(dev, "failed to get mem resource %d\n", index); 176 + return -ENODEV; 177 + } 178 + 179 + if (!request_mem_region(res->start, resource_size(res), res->name)) { 180 + dev_err(dev, "failed to request resource %pR\n", res); 181 + return -EBUSY; 182 + } 183 + 184 + base = ioremap(res->start, resource_size(res)); 185 + if (!base) { 186 + dev_err(dev, "failed to map resource %pR\n", res); 187 + ret = -ENOMEM; 188 + goto release_region; 189 + } 190 + 191 + data->base = base; 192 + data->res = res; 179 193 180 194 for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++) 181 195 data->reg_bases[i] = base + offsets[i]; ··· 207 187 policy->driver_data = data; 208 188 209 189 return 0; 190 + release_region: 191 + release_mem_region(res->start, resource_size(res)); 192 + return ret; 210 193 } 211 194 212 195 static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) ··· 256 233 static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy) 257 234 { 258 235 struct mtk_cpufreq_data *data = policy->driver_data; 236 + struct resource *res = data->res; 237 + void __iomem *base = data->base; 259 238 260 239 /* HW should be in paused state now */ 261 240 writel_relaxed(0x0, data->reg_bases[REG_FREQ_ENABLE]); 241 + iounmap(base); 242 + release_mem_region(res->start, resource_size(res)); 262 243 263 244 return 0; 264 245 }
+19 -20
drivers/cpufreq/qcom-cpufreq-hw.c
··· 46 46 */ 47 47 struct mutex throttle_lock; 48 48 int throttle_irq; 49 + char irq_name[15]; 49 50 bool cancel_throttle; 50 51 struct delayed_work throttle_work; 51 52 struct cpufreq_policy *policy; ··· 276 275 277 276 static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) 278 277 { 279 - unsigned long max_capacity, capacity, freq_hz, throttled_freq; 280 278 struct cpufreq_policy *policy = data->policy; 281 279 int cpu = cpumask_first(policy->cpus); 282 280 struct device *dev = get_cpu_device(cpu); 281 + unsigned long freq_hz, throttled_freq; 283 282 struct dev_pm_opp *opp; 284 283 unsigned int freq; 285 284 ··· 296 295 297 296 throttled_freq = freq_hz / HZ_PER_KHZ; 298 297 299 - /* Update thermal pressure */ 300 - 301 - max_capacity = arch_scale_cpu_capacity(cpu); 302 - capacity = mult_frac(max_capacity, throttled_freq, policy->cpuinfo.max_freq); 303 - 304 - /* Don't pass boost capacity to scheduler */ 305 - if (capacity > max_capacity) 306 - capacity = max_capacity; 307 - 308 - arch_set_thermal_pressure(policy->cpus, max_capacity - capacity); 298 + /* Update thermal pressure (the boost frequencies are accepted) */ 299 + arch_update_thermal_pressure(policy->related_cpus, throttled_freq); 309 300 310 301 /* 311 302 * In the unlikely case policy is unregistered do not enable ··· 335 342 336 343 /* Disable interrupt and enable polling */ 337 344 disable_irq_nosync(c_data->throttle_irq); 338 - qcom_lmh_dcvs_notify(c_data); 345 + schedule_delayed_work(&c_data->throttle_work, 0); 339 346 340 - return 0; 347 + return IRQ_HANDLED; 341 348 } 342 349 343 350 static const struct qcom_cpufreq_soc_data qcom_soc_data = { ··· 368 375 { 369 376 struct qcom_cpufreq_data *data = policy->driver_data; 370 377 struct platform_device *pdev = cpufreq_get_driver_data(); 371 - char irq_name[15]; 372 378 int ret; 373 379 374 380 /* 375 381 * Look for LMh interrupt. If no interrupt line is specified / 376 382 * if there is an error, allow cpufreq to be enabled as usual. 377 383 */ 378 - data->throttle_irq = platform_get_irq(pdev, index); 379 - if (data->throttle_irq <= 0) 380 - return data->throttle_irq == -EPROBE_DEFER ? -EPROBE_DEFER : 0; 384 + data->throttle_irq = platform_get_irq_optional(pdev, index); 385 + if (data->throttle_irq == -ENXIO) 386 + return 0; 387 + if (data->throttle_irq < 0) 388 + return data->throttle_irq; 381 389 382 390 data->cancel_throttle = false; 383 391 data->policy = policy; ··· 386 392 mutex_init(&data->throttle_lock); 387 393 INIT_DEFERRABLE_WORK(&data->throttle_work, qcom_lmh_dcvs_poll); 388 394 389 - snprintf(irq_name, sizeof(irq_name), "dcvsh-irq-%u", policy->cpu); 395 + snprintf(data->irq_name, sizeof(data->irq_name), "dcvsh-irq-%u", policy->cpu); 390 396 ret = request_threaded_irq(data->throttle_irq, NULL, qcom_lmh_dcvs_handle_irq, 391 - IRQF_ONESHOT, irq_name, data); 397 + IRQF_ONESHOT, data->irq_name, data); 392 398 if (ret) { 393 - dev_err(&pdev->dev, "Error registering %s: %d\n", irq_name, ret); 399 + dev_err(&pdev->dev, "Error registering %s: %d\n", data->irq_name, ret); 394 400 return 0; 395 401 } 402 + 403 + ret = irq_set_affinity_hint(data->throttle_irq, policy->cpus); 404 + if (ret) 405 + dev_err(&pdev->dev, "Failed to set CPU affinity of %s[%d]\n", 406 + data->irq_name, data->throttle_irq); 396 407 397 408 return 0; 398 409 }
+1 -5
drivers/thermal/cpufreq_cooling.c
··· 462 462 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; 463 463 struct cpumask *cpus; 464 464 unsigned int frequency; 465 - unsigned long max_capacity, capacity; 466 465 int ret; 467 466 468 467 /* Request state should be less than max_level */ ··· 478 479 if (ret >= 0) { 479 480 cpufreq_cdev->cpufreq_state = state; 480 481 cpus = cpufreq_cdev->policy->related_cpus; 481 - max_capacity = arch_scale_cpu_capacity(cpumask_first(cpus)); 482 - capacity = frequency * max_capacity; 483 - capacity /= cpufreq_cdev->policy->cpuinfo.max_freq; 484 - arch_set_thermal_pressure(cpus, max_capacity - capacity); 482 + arch_update_thermal_pressure(cpus, frequency); 485 483 ret = 0; 486 484 } 487 485
+2 -2
include/linux/arch_topology.h
··· 56 56 return per_cpu(thermal_pressure, cpu); 57 57 } 58 58 59 - void topology_set_thermal_pressure(const struct cpumask *cpus, 60 - unsigned long th_pressure); 59 + void topology_update_thermal_pressure(const struct cpumask *cpus, 60 + unsigned long capped_freq); 61 61 62 62 struct cpu_topology { 63 63 int thread_id;
+3 -3
include/linux/sched/topology.h
··· 266 266 } 267 267 #endif 268 268 269 - #ifndef arch_set_thermal_pressure 269 + #ifndef arch_update_thermal_pressure 270 270 static __always_inline 271 - void arch_set_thermal_pressure(const struct cpumask *cpus, 272 - unsigned long th_pressure) 271 + void arch_update_thermal_pressure(const struct cpumask *cpus, 272 + unsigned long capped_frequency) 273 273 { } 274 274 #endif 275 275
+1 -1
init/Kconfig
··· 550 550 i.e. put less load on throttled CPUs than on non/less throttled ones. 551 551 552 552 This requires the architecture to implement 553 - arch_set_thermal_pressure() and arch_scale_thermal_pressure(). 553 + arch_update_thermal_pressure() and arch_scale_thermal_pressure(). 554 554 555 555 config BSD_PROCESS_ACCT 556 556 bool "BSD Process Accounting"