aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavi Merino <javi.merino@arm.com>2015-09-14 09:23:53 -0400
committerEduardo Valentin <edubezval@gmail.com>2015-09-14 10:43:15 -0400
commitf5cbb182586ea36c6ad0e90e3534d18a5e9af094 (patch)
treee33fc9efce7e776c23fcd685d9a3942d182c5c65
parent8b7b390f805f09ff252351468a79ebabde1ab55a (diff)
thermal: power_allocator: don't require tzp to be present for the thermal zone
Thermal zones created using thermal_zone_device_create() may not have tzp. As the governor gets its parameters from there, allocate it while the governor is bound to the thermal zone so that it can operate in it. In this case, tzp is freed when the thermal zone switches to another governor. Cc: Zhang Rui <rui.zhang@intel.com> Cc: Eduardo Valentin <edubezval@gmail.com> Reviewed-by: Daniel Kurtz <djkurtz@chromium.org> Signed-off-by: Javi Merino <javi.merino@arm.com> Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
-rw-r--r--drivers/thermal/power_allocator.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/drivers/thermal/power_allocator.c b/drivers/thermal/power_allocator.c
index ea57759eb095..718363f5be40 100644
--- a/drivers/thermal/power_allocator.c
+++ b/drivers/thermal/power_allocator.c
@@ -58,6 +58,8 @@ static inline s64 div_frac(s64 x, s64 y)
58 58
59/** 59/**
60 * struct power_allocator_params - parameters for the power allocator governor 60 * struct power_allocator_params - parameters for the power allocator governor
61 * @allocated_tzp: whether we have allocated tzp for this thermal zone and
62 * it needs to be freed on unbind
61 * @err_integral: accumulated error in the PID controller. 63 * @err_integral: accumulated error in the PID controller.
62 * @prev_err: error in the previous iteration of the PID controller. 64 * @prev_err: error in the previous iteration of the PID controller.
63 * Used to calculate the derivative term. 65 * Used to calculate the derivative term.
@@ -70,6 +72,7 @@ static inline s64 div_frac(s64 x, s64 y)
70 * controlling for. 72 * controlling for.
71 */ 73 */
72struct power_allocator_params { 74struct power_allocator_params {
75 bool allocated_tzp;
73 s64 err_integral; 76 s64 err_integral;
74 s32 prev_err; 77 s32 prev_err;
75 int trip_switch_on; 78 int trip_switch_on;
@@ -527,8 +530,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz)
527 * Initialize the PID controller parameters and bind it to the thermal 530 * Initialize the PID controller parameters and bind it to the thermal
528 * zone. 531 * zone.
529 * 532 *
530 * Return: 0 on success, -EINVAL if the thermal zone doesn't have tzp or -ENOMEM 533 * Return: 0 on success, or -ENOMEM if we ran out of memory.
531 * if we ran out of memory.
532 */ 534 */
533static int power_allocator_bind(struct thermal_zone_device *tz) 535static int power_allocator_bind(struct thermal_zone_device *tz)
534{ 536{
@@ -536,13 +538,20 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
536 struct power_allocator_params *params; 538 struct power_allocator_params *params;
537 int control_temp; 539 int control_temp;
538 540
539 if (!tz->tzp)
540 return -EINVAL;
541
542 params = kzalloc(sizeof(*params), GFP_KERNEL); 541 params = kzalloc(sizeof(*params), GFP_KERNEL);
543 if (!params) 542 if (!params)
544 return -ENOMEM; 543 return -ENOMEM;
545 544
545 if (!tz->tzp) {
546 tz->tzp = kzalloc(sizeof(*tz->tzp), GFP_KERNEL);
547 if (!tz->tzp) {
548 ret = -ENOMEM;
549 goto free_params;
550 }
551
552 params->allocated_tzp = true;
553 }
554
546 if (!tz->tzp->sustainable_power) 555 if (!tz->tzp->sustainable_power)
547 dev_warn(&tz->device, "power_allocator: sustainable_power will be estimated\n"); 556 dev_warn(&tz->device, "power_allocator: sustainable_power will be estimated\n");
548 557
@@ -563,11 +572,24 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
563 tz->governor_data = params; 572 tz->governor_data = params;
564 573
565 return 0; 574 return 0;
575
576free_params:
577 kfree(params);
578
579 return ret;
566} 580}
567 581
568static void power_allocator_unbind(struct thermal_zone_device *tz) 582static void power_allocator_unbind(struct thermal_zone_device *tz)
569{ 583{
584 struct power_allocator_params *params = tz->governor_data;
585
570 dev_dbg(&tz->device, "Unbinding from thermal zone %d\n", tz->id); 586 dev_dbg(&tz->device, "Unbinding from thermal zone %d\n", tz->id);
587
588 if (params->allocated_tzp) {
589 kfree(tz->tzp);
590 tz->tzp = NULL;
591 }
592
571 kfree(tz->governor_data); 593 kfree(tz->governor_data);
572 tz->governor_data = NULL; 594 tz->governor_data = NULL;
573} 595}