From: Park Chungwoo Date: Tue, 15 Mar 2016 08:09:10 +0000 (+0900) Subject: thermal : Add throttle hotplug function. X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=967f5408e934de5aafa06b9c50c2b1eaa5451f82;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git thermal : Add throttle hotplug function. Resolved migration conflicts from kernel 4.9 to 4.14. Change-Id: I594d154e791f420a036731ddc3238b7ec6c49947 Signed-off-by: Park Chungwoo --- diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 1fb527a169c3..b5108cf614a9 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -112,6 +112,29 @@ static int of_thermal_set_trips(struct thermal_zone_device *tz, return data->ops->set_trips(data->sensor_data, low, high); } +/** + * of_thermal_throttle_hotplug - function to throttle hotplug cpu core. + * + * @tz: pointer to a thermal zone + * + * This function call throttle_cpu_hotplug function in exynos thermal. + * + * Return: do not exist function callback, -EINVAL when data not available + */ +static int of_thermal_throttle_hotplug(struct thermal_zone_device *tz) +{ + struct __thermal_zone *data = tz->devdata; + int ret = 0; + + if (!data->ops->throttle_cpu_hotplug) + return -EINVAL; + + ret = data->ops->throttle_cpu_hotplug(data->sensor_data, tz->temperature); + + return ret; +} + + /** * of_thermal_get_ntrips - function to export number of available trip * points. @@ -432,6 +455,7 @@ thermal_zone_of_add_sensor(struct device_node *zone, if (ops->set_emul_temp) tzd->ops->set_emul_temp = of_thermal_set_emul_temp; + tzd->ops->throttle_hotplug = of_thermal_throttle_hotplug; mutex_unlock(&tzd->lock); return tzd; diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 03988c90cedd..764a475642f9 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -35,6 +35,10 @@ #include #include #include +#include +#include +#include +#include #include "exynos_tmu.h" #include "../thermal_core.h" @@ -97,6 +101,7 @@ #define MCELSIUS 1000 static bool suspended; +static bool is_cpu_hotplugged_out; static DEFINE_MUTEX (thermal_suspend_lock); /* list of multiple instance for each thermal sensor */ @@ -125,6 +130,10 @@ static LIST_HEAD(dtm_dev_list); */ struct exynos_tmu_data { int id; + /* Throttle hotplug related variables */ + bool hotplug_enable; + int hotplug_in_threshold; + int hotplug_out_threshold; struct exynos_tmu_platform_data *pdata; void __iomem *base; int irq; @@ -653,6 +662,21 @@ static int exynos_map_dt_data(struct platform_device *pdev) return -EADDRNOTAVAIL; } + data->hotplug_enable = of_property_read_bool(pdev->dev.of_node, + "hotplug_enable"); + if (data->hotplug_enable) { + dev_info(&pdev->dev, "thermal zone use hotplug function \n"); + of_property_read_u32(pdev->dev.of_node, "hotplug_in_threshold", + &data->hotplug_in_threshold); + if (!data->hotplug_in_threshold) + dev_err(&pdev->dev, "No input hotplug_in_threshold \n"); + + of_property_read_u32(pdev->dev.of_node, "hotplug_out_threshold", + &data->hotplug_out_threshold); + if (!data->hotplug_out_threshold) + dev_err(&pdev->dev, "No input hotplug_out_threshold \n"); + } + pdata = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_platform_data), GFP_KERNEL); @@ -679,6 +703,48 @@ static int exynos_map_dt_data(struct platform_device *pdev) return 0; } +struct pm_qos_request thermal_cpu_hotplug_request; +static int exynos_throttle_cpu_hotplug(void *p, int temp) +{ + struct exynos_tmu_data *data = p; + struct cpufreq_cooling_device *cpufreq_cdev = (struct cpufreq_cooling_device *)data->cool_dev->devdata; + int ret = 0; + + temp = temp / MCELSIUS; + + if (is_cpu_hotplugged_out) { + if (temp < data->hotplug_in_threshold) { + /* + * If current temperature is lower than low threshold, + * call cluster1_cores_hotplug(false) for hotplugged out cpus. + */ + pm_qos_update_request(&thermal_cpu_hotplug_request, + NR_CPUS); + is_cpu_hotplugged_out = false; + cpufreq_cdev->cpufreq_state = 0; + } + } else { + if (temp >= data->hotplug_out_threshold) { + /* + * If current temperature is higher than high threshold, + * call cluster1_cores_hotplug(true) to hold temperature down. + */ + is_cpu_hotplugged_out = true; + + pm_qos_update_request(&thermal_cpu_hotplug_request, + NR_CLUST1_CPUS); + } + } + + return ret; +} + +static const struct thermal_zone_of_device_ops exynos_hotplug_sensor_ops = { + .get_temp = exynos_get_temp, + .set_emul_temp = exynos_tmu_set_emulation, + .throttle_cpu_hotplug = exynos_throttle_cpu_hotplug, +}; + static const struct thermal_zone_of_device_ops exynos_sensor_ops = { .get_temp = exynos_get_temp, .set_emul_temp = exynos_tmu_set_emulation, @@ -755,7 +821,14 @@ static int exynos_tmu_probe(struct platform_device *pdev) * data->tzd must be registered before calling exynos_tmu_initialize(), * requesting irq and calling exynos_tmu_control(). */ + if(data->hotplug_enable) + pm_qos_add_request(&thermal_cpu_hotplug_request, + PM_QOS_CPU_ONLINE_MAX, + PM_QOS_CPU_ONLINE_MAX_DEFAULT_VALUE); + data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data, + data->hotplug_enable ? + &exynos_hotplug_sensor_ops : &exynos_sensor_ops); if (IS_ERR(data->tzd)) { ret = PTR_ERR(data->tzd); diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 2b1b0ba393a4..c4eca6f9355b 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -483,6 +483,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz, for (count = 0; count < tz->trips; count++) handle_thermal_trip(tz, count); + + if (tz->ops->throttle_hotplug) + tz->ops->throttle_hotplug(tz); } EXPORT_SYMBOL_GPL(thermal_zone_device_update); diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 905af30d4944..a85b78ed4b6c 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -128,6 +128,7 @@ struct thermal_zone_device_ops { enum thermal_trend *); int (*notify) (struct thermal_zone_device *, int, enum thermal_trip_type); + int (*throttle_hotplug) (struct thermal_zone_device *); }; struct thermal_cooling_device_ops { @@ -371,6 +372,7 @@ struct thermal_zone_of_device_ops { int (*set_trips)(void *, int, int); int (*set_emul_temp)(void *, int); int (*set_trip_temp)(void *, int, int); + int (*throttle_cpu_hotplug)(void *, int temp); }; /**