From: Hyeonseong Gil Date: Wed, 4 May 2016 07:43:48 +0000 (+0900) Subject: [COMMON] thermal: power_allocator: anti-windup for integral term X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=c7e3357cc27c8ba22a077afbaf20c155291ad7c6;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [COMMON] thermal: power_allocator: anti-windup for integral term Change-Id: Id62b77cc74dc69c9d54a43574d732c5bb16b1535 Signed-off-by: Hyeonseong Gil --- diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 548b325e7c48..11617dc4e769 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -1032,6 +1032,9 @@ int __init of_parse_thermal_zones(void) if (!of_property_read_u32(child, "k_i", &prop)) tzp->k_i = prop; + if (!of_property_read_u32(child, "i_max", &prop)) + tzp->integral_max = prop; + for (i = 0; i < tz->ntrips; i++) mask |= 1 << i; diff --git a/drivers/thermal/power_allocator.c b/drivers/thermal/power_allocator.c index 9e0f02427b10..40debd67bf68 100644 --- a/drivers/thermal/power_allocator.c +++ b/drivers/thermal/power_allocator.c @@ -158,13 +158,20 @@ static void estimate_pid_constants(struct thermal_zone_device *tz, if (!tz->tzp->k_po || force) tz->tzp->k_po = int_to_frac(sustainable_power) / temperature_threshold; + else + tz->tzp->k_po = int_to_frac(tz->tzp->k_po); if (!tz->tzp->k_pu || force) tz->tzp->k_pu = int_to_frac(2 * sustainable_power) / temperature_threshold; + else + tz->tzp->k_pu = int_to_frac(tz->tzp->k_pu); if (!tz->tzp->k_i || force) tz->tzp->k_i = int_to_frac(10) / 1000; + else + tz->tzp->k_i = int_to_frac(tz->tzp->k_i); + /* * The default for k_d and integral_cutoff is 0, so we can * leave them as they are. @@ -209,7 +216,7 @@ static u32 pid_controller(struct thermal_zone_device *tz, true); } - err = control_temp - tz->temperature; + err = (control_temp - tz->temperature) / 1000; err = int_to_frac(err); /* Calculate the proportional term */ @@ -225,8 +232,15 @@ static u32 pid_controller(struct thermal_zone_device *tz, if (err < int_to_frac(tz->tzp->integral_cutoff)) { s64 i_next = i + mul_frac(tz->tzp->k_i, err); - - if (abs(i_next) < max_power_frac) { + s64 i_windup = int_to_frac(-1 * (s64)tz->tzp->sustainable_power); + + if (i_next > int_to_frac(tz->tzp->integral_max)) { + i = int_to_frac(tz->tzp->integral_max); + params->err_integral = div_frac(i, tz->tzp->k_i); + } else if (i_next <= i_windup) { + i = i_windup; + params->err_integral = div_frac(i, tz->tzp->k_i); + } else { i = i_next; params->err_integral += err; } diff --git a/include/linux/thermal.h b/include/linux/thermal.h index a85b78ed4b6c..f969b5e790e1 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -333,6 +333,8 @@ struct thermal_zone_params { /* threshold below which the error is no longer accumulated */ s32 integral_cutoff; + s32 integral_max; + /* * @slope: slope of a linear temperature adjustment curve. * Used by thermal zone drivers.