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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux

Pull thermal management fixes from Zhang Rui:

- Power allocator governor changes to allow binding on thermal zones
with missing power estimates information. From Javi Merino.

- Add compile test flags on thermal drivers that allow it without
producing compilation errors. From Eduardo Valentin.

- Fixes around memory allocation on cpu_cooling. From Javi Merino.

- Fix on db8500 cpufreq code to allow autoload. From Luis de
Bethencourt.

- Maintainer entries for cpu cooling device

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux:
thermal: power_allocator: exit early if there are no cooling devices
thermal: power_allocator: don't require tzp to be present for the thermal zone
thermal: power_allocator: relax the requirement of two passive trip points
thermal: power_allocator: relax the requirement of a sustainable_power in tzp
thermal: Add a function to get the minimum power
thermal: cpu_cooling: free power table on error or when unregistering
thermal: cpu_cooling: don't call kcalloc() under rcu_read_lock
thermal: db8500_cpufreq_cooling: Fix module autoload for OF platform driver
thermal: cpu_cooling: Add MAINTAINERS entry
thermal: ti-soc: Kconfig fix to avoid menu showing wrongly
thermal: ti-soc: allow compile test
thermal: qcom_spmi: allow compile test
thermal: exynos: allow compile test
thermal: armada: allow compile test
thermal: dove: allow compile test
thermal: kirkwood: allow compile test
thermal: rockchip: allow compile test
thermal: spear: allow compile test
thermal: hisi: allow compile test
thermal: Fix thermal_zone_of_sensor_register to match documentation

+269 -100
+1 -1
Documentation/thermal/power_allocator.txt
··· 4 4 Trip points 5 5 ----------- 6 6 7 - The governor requires the following two passive trip points: 7 + The governor works optimally with the following two passive trip points: 8 8 9 9 1. "switch on" trip point: temperature above which the governor 10 10 control loop starts operating. This is the first passive trip
+10
MAINTAINERS
··· 10338 10338 F: include/linux/cpu_cooling.h 10339 10339 F: Documentation/devicetree/bindings/thermal/ 10340 10340 10341 + THERMAL/CPU_COOLING 10342 + M: Amit Daniel Kachhap <amit.kachhap@gmail.com> 10343 + M: Viresh Kumar <viresh.kumar@linaro.org> 10344 + M: Javi Merino <javi.merino@arm.com> 10345 + L: linux-pm@vger.kernel.org 10346 + S: Supported 10347 + F: Documentation/thermal/cpu-cooling-api.txt 10348 + F: drivers/thermal/cpu_cooling.c 10349 + F: include/linux/cpu_cooling.h 10350 + 10341 10351 THINGM BLINK(1) USB RGB LED DRIVER 10342 10352 M: Vivien Didelot <vivien.didelot@savoirfairelinux.com> 10343 10353 S: Maintained
+9 -8
drivers/thermal/Kconfig
··· 163 163 164 164 config HISI_THERMAL 165 165 tristate "Hisilicon thermal driver" 166 - depends on ARCH_HISI && CPU_THERMAL && OF 166 + depends on (ARCH_HISI && CPU_THERMAL && OF) || COMPILE_TEST 167 167 help 168 168 Enable this to plug hisilicon's thermal sensor driver into the Linux 169 169 thermal framework. cpufreq is used as the cooling device to throttle ··· 182 182 183 183 config SPEAR_THERMAL 184 184 bool "SPEAr thermal sensor driver" 185 - depends on PLAT_SPEAR 185 + depends on PLAT_SPEAR || COMPILE_TEST 186 186 depends on OF 187 187 help 188 188 Enable this to plug the SPEAr thermal sensor driver into the Linux ··· 190 190 191 191 config ROCKCHIP_THERMAL 192 192 tristate "Rockchip thermal driver" 193 - depends on ARCH_ROCKCHIP 193 + depends on ARCH_ROCKCHIP || COMPILE_TEST 194 194 depends on RESET_CONTROLLER 195 195 help 196 196 Rockchip thermal driver provides support for Temperature sensor ··· 208 208 209 209 config KIRKWOOD_THERMAL 210 210 tristate "Temperature sensor on Marvell Kirkwood SoCs" 211 - depends on MACH_KIRKWOOD 211 + depends on MACH_KIRKWOOD || COMPILE_TEST 212 212 depends on OF 213 213 help 214 214 Support for the Kirkwood thermal sensor driver into the Linux thermal ··· 216 216 217 217 config DOVE_THERMAL 218 218 tristate "Temperature sensor on Marvell Dove SoCs" 219 - depends on ARCH_DOVE || MACH_DOVE 219 + depends on ARCH_DOVE || MACH_DOVE || COMPILE_TEST 220 220 depends on OF 221 221 help 222 222 Support for the Dove thermal sensor driver in the Linux thermal ··· 234 234 235 235 config ARMADA_THERMAL 236 236 tristate "Armada 370/XP thermal management" 237 - depends on ARCH_MVEBU 237 + depends on ARCH_MVEBU || COMPILE_TEST 238 238 depends on OF 239 239 help 240 240 Enable this option if you want to have support for thermal management ··· 349 349 programmable trip points and other information. 350 350 351 351 menu "Texas Instruments thermal drivers" 352 + depends on ARCH_HAS_BANDGAP || COMPILE_TEST 352 353 source "drivers/thermal/ti-soc-thermal/Kconfig" 353 354 endmenu 354 355 355 356 menu "Samsung thermal drivers" 356 - depends on ARCH_EXYNOS 357 + depends on ARCH_EXYNOS || COMPILE_TEST 357 358 source "drivers/thermal/samsung/Kconfig" 358 359 endmenu 359 360 ··· 365 364 366 365 config QCOM_SPMI_TEMP_ALARM 367 366 tristate "Qualcomm SPMI PMIC Temperature Alarm" 368 - depends on OF && SPMI && IIO 367 + depends on OF && (SPMI || COMPILE_TEST) && IIO 369 368 select REGMAP_SPMI 370 369 help 371 370 This enables a thermal sysfs driver for Qualcomm plug-and-play (QPNP)
+31 -21
drivers/thermal/cpu_cooling.c
··· 262 262 * efficiently. Power is stored in mW, frequency in KHz. The 263 263 * resulting table is in ascending order. 264 264 * 265 - * Return: 0 on success, -E* on error. 265 + * Return: 0 on success, -EINVAL if there are no OPPs for any CPUs, 266 + * -ENOMEM if we run out of memory or -EAGAIN if an OPP was 267 + * added/enabled while the function was executing. 266 268 */ 267 269 static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, 268 270 u32 capacitance) ··· 275 273 int num_opps = 0, cpu, i, ret = 0; 276 274 unsigned long freq; 277 275 278 - rcu_read_lock(); 279 - 280 276 for_each_cpu(cpu, &cpufreq_device->allowed_cpus) { 281 277 dev = get_cpu_device(cpu); 282 278 if (!dev) { ··· 284 284 } 285 285 286 286 num_opps = dev_pm_opp_get_opp_count(dev); 287 - if (num_opps > 0) { 287 + if (num_opps > 0) 288 288 break; 289 - } else if (num_opps < 0) { 290 - ret = num_opps; 291 - goto unlock; 292 - } 289 + else if (num_opps < 0) 290 + return num_opps; 293 291 } 294 292 295 - if (num_opps == 0) { 296 - ret = -EINVAL; 297 - goto unlock; 298 - } 293 + if (num_opps == 0) 294 + return -EINVAL; 299 295 300 296 power_table = kcalloc(num_opps, sizeof(*power_table), GFP_KERNEL); 301 - if (!power_table) { 302 - ret = -ENOMEM; 303 - goto unlock; 304 - } 297 + if (!power_table) 298 + return -ENOMEM; 299 + 300 + rcu_read_lock(); 305 301 306 302 for (freq = 0, i = 0; 307 303 opp = dev_pm_opp_find_freq_ceil(dev, &freq), !IS_ERR(opp); 308 304 freq++, i++) { 309 305 u32 freq_mhz, voltage_mv; 310 306 u64 power; 307 + 308 + if (i >= num_opps) { 309 + rcu_read_unlock(); 310 + ret = -EAGAIN; 311 + goto free_power_table; 312 + } 311 313 312 314 freq_mhz = freq / 1000000; 313 315 voltage_mv = dev_pm_opp_get_voltage(opp) / 1000; ··· 328 326 power_table[i].power = power; 329 327 } 330 328 331 - if (i == 0) { 329 + rcu_read_unlock(); 330 + 331 + if (i != num_opps) { 332 332 ret = PTR_ERR(opp); 333 - goto unlock; 333 + goto free_power_table; 334 334 } 335 335 336 336 cpufreq_device->cpu_dev = dev; 337 337 cpufreq_device->dyn_power_table = power_table; 338 338 cpufreq_device->dyn_power_table_entries = i; 339 339 340 - unlock: 341 - rcu_read_unlock(); 340 + return 0; 341 + 342 + free_power_table: 343 + kfree(power_table); 344 + 342 345 return ret; 343 346 } 344 347 ··· 854 847 ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); 855 848 if (ret) { 856 849 cool_dev = ERR_PTR(ret); 857 - goto free_table; 850 + goto free_power_table; 858 851 } 859 852 860 853 snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", ··· 896 889 897 890 remove_idr: 898 891 release_idr(&cpufreq_idr, cpufreq_dev->id); 892 + free_power_table: 893 + kfree(cpufreq_dev->dyn_power_table); 899 894 free_table: 900 895 kfree(cpufreq_dev->freq_table); 901 896 free_time_in_idle_timestamp: ··· 1048 1039 1049 1040 thermal_cooling_device_unregister(cpufreq_dev->cool_dev); 1050 1041 release_idr(&cpufreq_idr, cpufreq_dev->id); 1042 + kfree(cpufreq_dev->dyn_power_table); 1051 1043 kfree(cpufreq_dev->time_in_idle_timestamp); 1052 1044 kfree(cpufreq_dev->time_in_idle); 1053 1045 kfree(cpufreq_dev->freq_table);
+1
drivers/thermal/db8500_cpufreq_cooling.c
··· 72 72 { .compatible = "stericsson,db8500-cpufreq-cooling" }, 73 73 {}, 74 74 }; 75 + MODULE_DEVICE_TABLE(of, db8500_cpufreq_cooling_match); 75 76 #endif 76 77 77 78 static struct platform_driver db8500_cpufreq_cooling_driver = {
+179 -64
drivers/thermal/power_allocator.c
··· 24 24 25 25 #include "thermal_core.h" 26 26 27 + #define INVALID_TRIP -1 28 + 27 29 #define FRAC_BITS 10 28 30 #define int_to_frac(x) ((x) << FRAC_BITS) 29 31 #define frac_to_int(x) ((x) >> FRAC_BITS) ··· 58 56 59 57 /** 60 58 * struct power_allocator_params - parameters for the power allocator governor 59 + * @allocated_tzp: whether we have allocated tzp for this thermal zone and 60 + * it needs to be freed on unbind 61 61 * @err_integral: accumulated error in the PID controller. 62 62 * @prev_err: error in the previous iteration of the PID controller. 63 63 * Used to calculate the derivative term. 64 64 * @trip_switch_on: first passive trip point of the thermal zone. The 65 65 * governor switches on when this trip point is crossed. 66 + * If the thermal zone only has one passive trip point, 67 + * @trip_switch_on should be INVALID_TRIP. 66 68 * @trip_max_desired_temperature: last passive trip point of the thermal 67 69 * zone. The temperature we are 68 70 * controlling for. 69 71 */ 70 72 struct power_allocator_params { 73 + bool allocated_tzp; 71 74 s64 err_integral; 72 75 s32 prev_err; 73 76 int trip_switch_on; 74 77 int trip_max_desired_temperature; 75 78 }; 79 + 80 + /** 81 + * estimate_sustainable_power() - Estimate the sustainable power of a thermal zone 82 + * @tz: thermal zone we are operating in 83 + * 84 + * For thermal zones that don't provide a sustainable_power in their 85 + * thermal_zone_params, estimate one. Calculate it using the minimum 86 + * power of all the cooling devices as that gives a valid value that 87 + * can give some degree of functionality. For optimal performance of 88 + * this governor, provide a sustainable_power in the thermal zone's 89 + * thermal_zone_params. 90 + */ 91 + static u32 estimate_sustainable_power(struct thermal_zone_device *tz) 92 + { 93 + u32 sustainable_power = 0; 94 + struct thermal_instance *instance; 95 + struct power_allocator_params *params = tz->governor_data; 96 + 97 + list_for_each_entry(instance, &tz->thermal_instances, tz_node) { 98 + struct thermal_cooling_device *cdev = instance->cdev; 99 + u32 min_power; 100 + 101 + if (instance->trip != params->trip_max_desired_temperature) 102 + continue; 103 + 104 + if (power_actor_get_min_power(cdev, tz, &min_power)) 105 + continue; 106 + 107 + sustainable_power += min_power; 108 + } 109 + 110 + return sustainable_power; 111 + } 112 + 113 + /** 114 + * estimate_pid_constants() - Estimate the constants for the PID controller 115 + * @tz: thermal zone for which to estimate the constants 116 + * @sustainable_power: sustainable power for the thermal zone 117 + * @trip_switch_on: trip point number for the switch on temperature 118 + * @control_temp: target temperature for the power allocator governor 119 + * @force: whether to force the update of the constants 120 + * 121 + * This function is used to update the estimation of the PID 122 + * controller constants in struct thermal_zone_parameters. 123 + * Sustainable power is provided in case it was estimated. The 124 + * estimated sustainable_power should not be stored in the 125 + * thermal_zone_parameters so it has to be passed explicitly to this 126 + * function. 127 + * 128 + * If @force is not set, the values in the thermal zone's parameters 129 + * are preserved if they are not zero. If @force is set, the values 130 + * in thermal zone's parameters are overwritten. 131 + */ 132 + static void estimate_pid_constants(struct thermal_zone_device *tz, 133 + u32 sustainable_power, int trip_switch_on, 134 + int control_temp, bool force) 135 + { 136 + int ret; 137 + int switch_on_temp; 138 + u32 temperature_threshold; 139 + 140 + ret = tz->ops->get_trip_temp(tz, trip_switch_on, &switch_on_temp); 141 + if (ret) 142 + switch_on_temp = 0; 143 + 144 + temperature_threshold = control_temp - switch_on_temp; 145 + 146 + if (!tz->tzp->k_po || force) 147 + tz->tzp->k_po = int_to_frac(sustainable_power) / 148 + temperature_threshold; 149 + 150 + if (!tz->tzp->k_pu || force) 151 + tz->tzp->k_pu = int_to_frac(2 * sustainable_power) / 152 + temperature_threshold; 153 + 154 + if (!tz->tzp->k_i || force) 155 + tz->tzp->k_i = int_to_frac(10) / 1000; 156 + /* 157 + * The default for k_d and integral_cutoff is 0, so we can 158 + * leave them as they are. 159 + */ 160 + } 76 161 77 162 /** 78 163 * pid_controller() - PID controller ··· 187 98 { 188 99 s64 p, i, d, power_range; 189 100 s32 err, max_power_frac; 101 + u32 sustainable_power; 190 102 struct power_allocator_params *params = tz->governor_data; 191 103 192 104 max_power_frac = int_to_frac(max_allocatable_power); 105 + 106 + if (tz->tzp->sustainable_power) { 107 + sustainable_power = tz->tzp->sustainable_power; 108 + } else { 109 + sustainable_power = estimate_sustainable_power(tz); 110 + estimate_pid_constants(tz, sustainable_power, 111 + params->trip_switch_on, control_temp, 112 + true); 113 + } 193 114 194 115 err = control_temp - current_temp; 195 116 err = int_to_frac(err); ··· 238 139 power_range = p + i + d; 239 140 240 141 /* feed-forward the known sustainable dissipatable power */ 241 - power_range = tz->tzp->sustainable_power + frac_to_int(power_range); 142 + power_range = sustainable_power + frac_to_int(power_range); 242 143 243 144 power_range = clamp(power_range, (s64)0, (s64)max_allocatable_power); 244 145 ··· 346 247 } 347 248 } 348 249 250 + if (!num_actors) { 251 + ret = -ENODEV; 252 + goto unlock; 253 + } 254 + 349 255 /* 350 256 * We need to allocate five arrays of the same size: 351 257 * req_power, max_power, granted_power, extra_actor_power and ··· 444 340 return ret; 445 341 } 446 342 447 - static int get_governor_trips(struct thermal_zone_device *tz, 448 - struct power_allocator_params *params) 343 + /** 344 + * get_governor_trips() - get the number of the two trip points that are key for this governor 345 + * @tz: thermal zone to operate on 346 + * @params: pointer to private data for this governor 347 + * 348 + * The power allocator governor works optimally with two trips points: 349 + * a "switch on" trip point and a "maximum desired temperature". These 350 + * are defined as the first and last passive trip points. 351 + * 352 + * If there is only one trip point, then that's considered to be the 353 + * "maximum desired temperature" trip point and the governor is always 354 + * on. If there are no passive or active trip points, then the 355 + * governor won't do anything. In fact, its throttle function 356 + * won't be called at all. 357 + */ 358 + static void get_governor_trips(struct thermal_zone_device *tz, 359 + struct power_allocator_params *params) 449 360 { 450 - int i, ret, last_passive; 361 + int i, last_active, last_passive; 451 362 bool found_first_passive; 452 363 453 364 found_first_passive = false; 454 - last_passive = -1; 455 - ret = -EINVAL; 365 + last_active = INVALID_TRIP; 366 + last_passive = INVALID_TRIP; 456 367 457 368 for (i = 0; i < tz->trips; i++) { 458 369 enum thermal_trip_type type; 370 + int ret; 459 371 460 372 ret = tz->ops->get_trip_type(tz, i, &type); 461 - if (ret) 462 - return ret; 373 + if (ret) { 374 + dev_warn(&tz->device, 375 + "Failed to get trip point %d type: %d\n", i, 376 + ret); 377 + continue; 378 + } 463 379 464 - if (!found_first_passive) { 465 - if (type == THERMAL_TRIP_PASSIVE) { 380 + if (type == THERMAL_TRIP_PASSIVE) { 381 + if (!found_first_passive) { 466 382 params->trip_switch_on = i; 467 383 found_first_passive = true; 384 + } else { 385 + last_passive = i; 468 386 } 469 - } else if (type == THERMAL_TRIP_PASSIVE) { 470 - last_passive = i; 387 + } else if (type == THERMAL_TRIP_ACTIVE) { 388 + last_active = i; 471 389 } else { 472 390 break; 473 391 } 474 392 } 475 393 476 - if (last_passive != -1) { 394 + if (last_passive != INVALID_TRIP) { 477 395 params->trip_max_desired_temperature = last_passive; 478 - ret = 0; 396 + } else if (found_first_passive) { 397 + params->trip_max_desired_temperature = params->trip_switch_on; 398 + params->trip_switch_on = INVALID_TRIP; 479 399 } else { 480 - ret = -EINVAL; 400 + params->trip_switch_on = INVALID_TRIP; 401 + params->trip_max_desired_temperature = last_active; 481 402 } 482 - 483 - return ret; 484 403 } 485 404 486 405 static void reset_pid_controller(struct power_allocator_params *params) ··· 532 405 * power_allocator_bind() - bind the power_allocator governor to a thermal zone 533 406 * @tz: thermal zone to bind it to 534 407 * 535 - * Check that the thermal zone is valid for this governor, that is, it 536 - * has two thermal trips. If so, initialize the PID controller 537 - * parameters and bind it to the thermal zone. 408 + * Initialize the PID controller parameters and bind it to the thermal 409 + * zone. 538 410 * 539 - * Return: 0 on success, -EINVAL if the trips were invalid or -ENOMEM 540 - * if we ran out of memory. 411 + * Return: 0 on success, or -ENOMEM if we ran out of memory. 541 412 */ 542 413 static int power_allocator_bind(struct thermal_zone_device *tz) 543 414 { 544 415 int ret; 545 416 struct power_allocator_params *params; 546 - int switch_on_temp, control_temp; 547 - u32 temperature_threshold; 548 - 549 - if (!tz->tzp || !tz->tzp->sustainable_power) { 550 - dev_err(&tz->device, 551 - "power_allocator: missing sustainable_power\n"); 552 - return -EINVAL; 553 - } 417 + int control_temp; 554 418 555 419 params = kzalloc(sizeof(*params), GFP_KERNEL); 556 420 if (!params) 557 421 return -ENOMEM; 558 422 559 - ret = get_governor_trips(tz, params); 560 - if (ret) { 561 - dev_err(&tz->device, 562 - "thermal zone %s has wrong trip setup for power allocator\n", 563 - tz->type); 564 - goto free; 423 + if (!tz->tzp) { 424 + tz->tzp = kzalloc(sizeof(*tz->tzp), GFP_KERNEL); 425 + if (!tz->tzp) { 426 + ret = -ENOMEM; 427 + goto free_params; 428 + } 429 + 430 + params->allocated_tzp = true; 565 431 } 566 432 567 - ret = tz->ops->get_trip_temp(tz, params->trip_switch_on, 568 - &switch_on_temp); 569 - if (ret) 570 - goto free; 433 + if (!tz->tzp->sustainable_power) 434 + dev_warn(&tz->device, "power_allocator: sustainable_power will be estimated\n"); 571 435 572 - ret = tz->ops->get_trip_temp(tz, params->trip_max_desired_temperature, 573 - &control_temp); 574 - if (ret) 575 - goto free; 436 + get_governor_trips(tz, params); 576 437 577 - temperature_threshold = control_temp - switch_on_temp; 578 - 579 - tz->tzp->k_po = tz->tzp->k_po ?: 580 - int_to_frac(tz->tzp->sustainable_power) / temperature_threshold; 581 - tz->tzp->k_pu = tz->tzp->k_pu ?: 582 - int_to_frac(2 * tz->tzp->sustainable_power) / 583 - temperature_threshold; 584 - tz->tzp->k_i = tz->tzp->k_i ?: int_to_frac(10) / 1000; 585 - /* 586 - * The default for k_d and integral_cutoff is 0, so we can 587 - * leave them as they are. 588 - */ 438 + if (tz->trips > 0) { 439 + ret = tz->ops->get_trip_temp(tz, 440 + params->trip_max_desired_temperature, 441 + &control_temp); 442 + if (!ret) 443 + estimate_pid_constants(tz, tz->tzp->sustainable_power, 444 + params->trip_switch_on, 445 + control_temp, false); 446 + } 589 447 590 448 reset_pid_controller(params); 591 449 ··· 578 466 579 467 return 0; 580 468 581 - free: 469 + free_params: 582 470 kfree(params); 471 + 583 472 return ret; 584 473 } 585 474 586 475 static void power_allocator_unbind(struct thermal_zone_device *tz) 587 476 { 477 + struct power_allocator_params *params = tz->governor_data; 478 + 588 479 dev_dbg(&tz->device, "Unbinding from thermal zone %d\n", tz->id); 480 + 481 + if (params->allocated_tzp) { 482 + kfree(tz->tzp); 483 + tz->tzp = NULL; 484 + } 485 + 589 486 kfree(tz->governor_data); 590 487 tz->governor_data = NULL; 591 488 } ··· 620 499 621 500 ret = tz->ops->get_trip_temp(tz, params->trip_switch_on, 622 501 &switch_on_temp); 623 - if (ret) { 624 - dev_warn(&tz->device, 625 - "Failed to get switch on temperature: %d\n", ret); 626 - return ret; 627 - } 628 - 629 - if (current_temp < switch_on_temp) { 502 + if (!ret && (current_temp < switch_on_temp)) { 630 503 tz->passive = 0; 631 504 reset_pid_controller(params); 632 505 allow_maximum_power(tz);
+28
drivers/thermal/thermal_core.c
··· 1013 1013 } 1014 1014 1015 1015 /** 1016 + * power_actor_get_min_power() - get the mainimum power that a cdev can consume 1017 + * @cdev: pointer to &thermal_cooling_device 1018 + * @tz: a valid thermal zone device pointer 1019 + * @min_power: pointer in which to store the minimum power 1020 + * 1021 + * Calculate the minimum power consumption in milliwatts that the 1022 + * cooling device can currently consume and store it in @min_power. 1023 + * 1024 + * Return: 0 on success, -EINVAL if @cdev doesn't support the 1025 + * power_actor API or -E* on other error. 1026 + */ 1027 + int power_actor_get_min_power(struct thermal_cooling_device *cdev, 1028 + struct thermal_zone_device *tz, u32 *min_power) 1029 + { 1030 + unsigned long max_state; 1031 + int ret; 1032 + 1033 + if (!cdev_is_power_actor(cdev)) 1034 + return -EINVAL; 1035 + 1036 + ret = cdev->ops->get_max_state(cdev, &max_state); 1037 + if (ret) 1038 + return ret; 1039 + 1040 + return cdev->ops->state2power(cdev, tz, max_state, min_power); 1041 + } 1042 + 1043 + /** 1016 1044 * power_actor_set_power() - limit the maximum power that a cooling device can consume 1017 1045 * @cdev: pointer to &thermal_cooling_device 1018 1046 * @instance: thermal instance to update
+3 -5
drivers/thermal/ti-soc-thermal/Kconfig
··· 1 1 config TI_SOC_THERMAL 2 2 tristate "Texas Instruments SoCs temperature sensor driver" 3 - depends on THERMAL 4 - depends on ARCH_HAS_BANDGAP 5 3 help 6 4 If you say yes here you get support for the Texas Instruments 7 5 OMAP4460+ on die bandgap temperature sensor support. The register ··· 22 24 config OMAP4_THERMAL 23 25 bool "Texas Instruments OMAP4 thermal support" 24 26 depends on TI_SOC_THERMAL 25 - depends on ARCH_OMAP4 27 + depends on ARCH_OMAP4 || COMPILE_TEST 26 28 help 27 29 If you say yes here you get thermal support for the Texas Instruments 28 30 OMAP4 SoC family. The current chip supported are: ··· 36 38 config OMAP5_THERMAL 37 39 bool "Texas Instruments OMAP5 thermal support" 38 40 depends on TI_SOC_THERMAL 39 - depends on SOC_OMAP5 41 + depends on SOC_OMAP5 || COMPILE_TEST 40 42 help 41 43 If you say yes here you get thermal support for the Texas Instruments 42 44 OMAP5 SoC family. The current chip supported are: ··· 48 50 config DRA752_THERMAL 49 51 bool "Texas Instruments DRA752 thermal support" 50 52 depends on TI_SOC_THERMAL 51 - depends on SOC_DRA7XX 53 + depends on SOC_DRA7XX || COMPILE_TEST 52 54 help 53 55 If you say yes here you get thermal support for the Texas Instruments 54 56 DRA752 SoC family. The current chip supported are:
+7 -1
include/linux/thermal.h
··· 360 360 thermal_zone_of_sensor_register(struct device *dev, int id, void *data, 361 361 const struct thermal_zone_of_device_ops *ops) 362 362 { 363 - return NULL; 363 + return ERR_PTR(-ENODEV); 364 364 } 365 365 366 366 static inline ··· 380 380 381 381 int power_actor_get_max_power(struct thermal_cooling_device *, 382 382 struct thermal_zone_device *tz, u32 *max_power); 383 + int power_actor_get_min_power(struct thermal_cooling_device *, 384 + struct thermal_zone_device *tz, u32 *min_power); 383 385 int power_actor_set_power(struct thermal_cooling_device *, 384 386 struct thermal_instance *, u32); 385 387 struct thermal_zone_device *thermal_zone_device_register(const char *, int, int, ··· 417 415 static inline int power_actor_get_max_power(struct thermal_cooling_device *cdev, 418 416 struct thermal_zone_device *tz, u32 *max_power) 419 417 { return 0; } 418 + static inline int power_actor_get_min_power(struct thermal_cooling_device *cdev, 419 + struct thermal_zone_device *tz, 420 + u32 *min_power) 421 + { return -ENODEV; } 420 422 static inline int power_actor_set_power(struct thermal_cooling_device *cdev, 421 423 struct thermal_instance *tz, u32 power) 422 424 { return 0; }