Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 986fde17 authored by Lina Iyer's avatar Lina Iyer Committed by Ram Chandrasekar
Browse files

drivers: cpu_cooling: allow platform freq mitigation



Allow platform drivers to register with CPU cooling with their frequency
mitigation functions. This allows the platform drivers to provide the
callbacks to get the current ceil limit and to set the floor and ceil
limits for the cpu.

Change-Id: I47960b002bf1bce1cd588de2892de46793a95562
Signed-off-by: default avatarLina Iyer <ilina@codeaurora.org>
parent 97a13edc
Loading
Loading
Loading
Loading
+47 −6
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/cpu.h>
#include <linux/cpu_cooling.h>
#include <linux/sched.h>
#include <linux/of_device.h>

#include <trace/events/thermal.h>

@@ -105,6 +106,7 @@ struct cpufreq_cooling_device {
	int dyn_power_table_entries;
	struct device *cpu_dev;
	get_static_t plat_get_static_power;
	struct cpu_cooling_ops *plat_ops;
};
static DEFINE_IDR(cpufreq_idr);
static DEFINE_MUTEX(cooling_cpufreq_lock);
@@ -547,7 +549,17 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
	cpufreq_device->cpufreq_state = state;
	cpufreq_device->clipped_freq = clip_freq;

	/* Check if the device has a platform mitigation function that
	 * can handle the CPU freq mitigation, if not, notify cpufreq
	 * framework.
	 */
	if (cpufreq_device->plat_ops) {
		if (cpufreq_device->plat_ops->ceil_limit)
			cpufreq_device->plat_ops->ceil_limit(cpu,
						clip_freq);
	} else {
		cpufreq_update_policy(cpu);
	}

	return 0;
}
@@ -791,6 +803,9 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table,
 * @capacitance: dynamic power coefficient for these cpus
 * @plat_static_func: function to calculate the static power consumed by these
 *                    cpus (optional)
 * @plat_mitig_func: function that does the mitigation by changing the
 *                   frequencies (Optional). By default, cpufreq framweork will
 *                   be notified of the new limits.
 *
 * This interface function registers the cpufreq cooling device with the name
 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
@@ -803,7 +818,8 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table,
static struct thermal_cooling_device *
__cpufreq_cooling_register(struct device_node *np,
			const struct cpumask *clip_cpus, u32 capacitance,
			get_static_t plat_static_func)
			get_static_t plat_static_func,
			struct cpu_cooling_ops *plat_ops)
{
	struct cpufreq_policy *policy;
	struct thermal_cooling_device *cool_dev;
@@ -884,6 +900,8 @@ __cpufreq_cooling_register(struct device_node *np,
		cooling_ops = &cpufreq_cooling_ops;
	}

	cpufreq_dev->plat_ops = plat_ops;

	ret = get_idr(&cpufreq_idr, &cpufreq_dev->id);
	if (ret) {
		cool_dev = ERR_PTR(ret);
@@ -959,7 +977,7 @@ __cpufreq_cooling_register(struct device_node *np,
struct thermal_cooling_device *
cpufreq_cooling_register(const struct cpumask *clip_cpus)
{
	return __cpufreq_cooling_register(NULL, clip_cpus, 0, NULL);
	return __cpufreq_cooling_register(NULL, clip_cpus, 0, NULL, NULL);
}
EXPORT_SYMBOL_GPL(cpufreq_cooling_register);

@@ -983,7 +1001,7 @@ of_cpufreq_cooling_register(struct device_node *np,
	if (!np)
		return ERR_PTR(-EINVAL);

	return __cpufreq_cooling_register(np, clip_cpus, 0, NULL);
	return __cpufreq_cooling_register(np, clip_cpus, 0, NULL, NULL);
}
EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register);

@@ -1013,10 +1031,33 @@ cpufreq_power_cooling_register(const struct cpumask *clip_cpus, u32 capacitance,
			       get_static_t plat_static_func)
{
	return __cpufreq_cooling_register(NULL, clip_cpus, capacitance,
				plat_static_func);
				plat_static_func, NULL);
}
EXPORT_SYMBOL(cpufreq_power_cooling_register);

/**
 * cpufreq_platform_cooling_register() - create cpufreq cooling device with
 * additional platform specific mitigation function.
 *
 * @clip_cpus: cpumask of cpus where the frequency constraints will happen
 * @plat_ops: the platform mitigation functions that will be called insted of
 * cpufreq, if provided.
 *
 * Return: a valid struct thermal_cooling_device pointer on success,
 * on failure, it returns a corresponding ERR_PTR().
 */
struct thermal_cooling_device *
cpufreq_platform_cooling_register(const struct cpumask *clip_cpus,
				struct cpu_cooling_ops *plat_ops)
{
	struct device_node *cpu_node;

	cpu_node = of_cpu_device_node_get(cpumask_first(clip_cpus));
	return __cpufreq_cooling_register(cpu_node, clip_cpus, 0, NULL,
						plat_ops);
}
EXPORT_SYMBOL(cpufreq_platform_cooling_register);

/**
 * of_cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions
 * @np:	a valid struct device_node to the cooling device device tree node
@@ -1050,7 +1091,7 @@ of_cpufreq_power_cooling_register(struct device_node *np,
		return ERR_PTR(-EINVAL);

	return __cpufreq_cooling_register(np, clip_cpus, capacitance,
				plat_static_func);
				plat_static_func, NULL);
}
EXPORT_SYMBOL(of_cpufreq_power_cooling_register);

+16 −0
Original line number Diff line number Diff line
@@ -30,6 +30,11 @@

typedef int (*get_static_t)(cpumask_t *cpumask, int interval,
			    unsigned long voltage, u32 *power);
typedef int (*plat_mitig_t)(int cpu, u32 clip_freq);

struct cpu_cooling_ops {
	plat_mitig_t ceil_limit, floor_limit;
};

#ifdef CONFIG_CPU_THERMAL
/**
@@ -43,6 +48,10 @@ struct thermal_cooling_device *
cpufreq_power_cooling_register(const struct cpumask *clip_cpus,
			       u32 capacitance, get_static_t plat_static_func);

struct thermal_cooling_device *
cpufreq_platform_cooling_register(const struct cpumask *clip_cpus,
					struct cpu_cooling_ops *ops);

/**
 * of_cpufreq_cooling_register - create cpufreq cooling device based on DT.
 * @np: a valid struct device_node to the cooling device device tree node.
@@ -112,6 +121,13 @@ of_cpufreq_power_cooling_register(struct device_node *np,
	return NULL;
}

static inline struct thermal_cooling_device *
cpufreq_platform_cooling_register(const struct cpumask *clip_cpus,
					struct cpu_cooling_ops *ops)
{
	return NULL;
}

static inline
void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
{