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

Commit 4617c220 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull thermal management fixes from Eduardo Valentin:
 "Specifics in this pull request:

   - Compilation fixes on SPEAR, and U8500 thermal drivers.
   - RCAR thermal driver now recognizes OF-thermal based thermal zones.
   - Small code rework on OF-thermal.
   - These change have been CI tested using KernelCI bot [1,2].  \o/

  I am taking over on Rui's behalf while he is out.  Happy New Chinese
  Year!

  [1] - https://kernelci.org/build/evalenti/kernel/v4.5-rc3-16-ga53b8394ec3c/
  [2] - https://kernelci.org/boot/all/job/evalenti/kernel/v4.5-rc3-16-ga53b8394ec3c/"

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal:
  thermal: cpu_cooling: fix out of bounds access in time_in_idle
  thermal: allow u8500-thermal driver to be a module
  thermal: allow spear-thermal driver to be a module
  thermal: spear: use __maybe_unused for PM functions
  thermal: rcar: enable to use thermal-zone on DT
  thermal: of: use for_each_available_child_of_node for child iterator
parents b4e4334d a53b8394
Loading
Loading
Loading
Loading
+35 −2
Original line number Diff line number Diff line
* Renesas R-Car Thermal

Required properties:
- compatible		: "renesas,thermal-<soctype>", "renesas,rcar-thermal"
			  as fallback.
- compatible		: "renesas,thermal-<soctype>",
			   "renesas,rcar-gen2-thermal" (with thermal-zone) or
			   "renesas,rcar-thermal" (without thermal-zone) as fallback.
			  Examples with soctypes are:
			    - "renesas,thermal-r8a73a4" (R-Mobile APE6)
			    - "renesas,thermal-r8a7779" (R-Car H1)
@@ -36,3 +37,35 @@ thermal@e61f0000 {
		0xe61f0300 0x38>;
	interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
};

Example (with thermal-zone):

thermal-zones {
	cpu_thermal: cpu-thermal {
		polling-delay-passive	= <1000>;
		polling-delay		= <5000>;

		thermal-sensors = <&thermal>;

		trips {
			cpu-crit {
				temperature	= <115000>;
				hysteresis	= <0>;
				type		= "critical";
			};
		};
		cooling-maps {
		};
	};
};

thermal: thermal@e61f0000 {
	compatible =	"renesas,thermal-r8a7790",
			"renesas,rcar-gen2-thermal",
			"renesas,rcar-thermal";
	reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
	interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
	clocks = <&mstp5_clks R8A7790_CLK_THERMAL>;
	power-domains = <&cpg_clocks>;
	#thermal-sensor-cells = <0>;
};
+3 −0
Original line number Diff line number Diff line
@@ -2048,6 +2048,7 @@ int db8500_prcmu_config_hotmon(u8 low, u8 high)

	return 0;
}
EXPORT_SYMBOL_GPL(db8500_prcmu_config_hotmon);

static int config_hot_period(u16 val)
{
@@ -2074,11 +2075,13 @@ int db8500_prcmu_start_temp_sense(u16 cycles32k)

	return config_hot_period(cycles32k);
}
EXPORT_SYMBOL_GPL(db8500_prcmu_start_temp_sense);

int db8500_prcmu_stop_temp_sense(void)
{
	return config_hot_period(0xFFFF);
}
EXPORT_SYMBOL_GPL(db8500_prcmu_stop_temp_sense);

static int prcmu_a9wdog(u8 cmd, u8 d0, u8 d1, u8 d2, u8 d3)
{
+3 −3
Original line number Diff line number Diff line
@@ -195,7 +195,7 @@ config IMX_THERMAL
	  passive trip is crossed.

config SPEAR_THERMAL
	bool "SPEAr thermal sensor driver"
	tristate "SPEAr thermal sensor driver"
	depends on PLAT_SPEAR || COMPILE_TEST
	depends on OF
	help
@@ -237,8 +237,8 @@ config DOVE_THERMAL
	  framework.

config DB8500_THERMAL
	bool "DB8500 thermal management"
	depends on ARCH_U8500
	tristate "DB8500 thermal management"
	depends on MFD_DB8500_PRCMU
	default y
	help
	  Adds DB8500 thermal management implementation according to the thermal
+8 −6
Original line number Diff line number Diff line
@@ -377,26 +377,28 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_device,
 * get_load() - get load for a cpu since last updated
 * @cpufreq_device:	&struct cpufreq_cooling_device for this cpu
 * @cpu:	cpu number
 * @cpu_idx:	index of the cpu in cpufreq_device->allowed_cpus
 *
 * Return: The average load of cpu @cpu in percentage since this
 * function was last called.
 */
static u32 get_load(struct cpufreq_cooling_device *cpufreq_device, int cpu)
static u32 get_load(struct cpufreq_cooling_device *cpufreq_device, int cpu,
		    int cpu_idx)
{
	u32 load;
	u64 now, now_idle, delta_time, delta_idle;

	now_idle = get_cpu_idle_time(cpu, &now, 0);
	delta_idle = now_idle - cpufreq_device->time_in_idle[cpu];
	delta_time = now - cpufreq_device->time_in_idle_timestamp[cpu];
	delta_idle = now_idle - cpufreq_device->time_in_idle[cpu_idx];
	delta_time = now - cpufreq_device->time_in_idle_timestamp[cpu_idx];

	if (delta_time <= delta_idle)
		load = 0;
	else
		load = div64_u64(100 * (delta_time - delta_idle), delta_time);

	cpufreq_device->time_in_idle[cpu] = now_idle;
	cpufreq_device->time_in_idle_timestamp[cpu] = now;
	cpufreq_device->time_in_idle[cpu_idx] = now_idle;
	cpufreq_device->time_in_idle_timestamp[cpu_idx] = now;

	return load;
}
@@ -598,7 +600,7 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
		u32 load;

		if (cpu_online(cpu))
			load = get_load(cpufreq_device, cpu);
			load = get_load(cpufreq_device, cpu, i);
		else
			load = 0;

+3 −15
Original line number Diff line number Diff line
@@ -475,14 +475,10 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,

	sensor_np = of_node_get(dev->of_node);

	for_each_child_of_node(np, child) {
	for_each_available_child_of_node(np, child) {
		struct of_phandle_args sensor_specs;
		int ret, id;

		/* Check whether child is enabled or not */
		if (!of_device_is_available(child))
			continue;

		/* For now, thermal framework supports only 1 sensor per zone */
		ret = of_parse_phandle_with_args(child, "thermal-sensors",
						 "#thermal-sensor-cells",
@@ -881,16 +877,12 @@ int __init of_parse_thermal_zones(void)
		return 0; /* Run successfully on systems without thermal DT */
	}

	for_each_child_of_node(np, child) {
	for_each_available_child_of_node(np, child) {
		struct thermal_zone_device *zone;
		struct thermal_zone_params *tzp;
		int i, mask = 0;
		u32 prop;

		/* Check whether child is enabled or not */
		if (!of_device_is_available(child))
			continue;

		tz = thermal_of_build_thermal_zone(child);
		if (IS_ERR(tz)) {
			pr_err("failed to build thermal zone %s: %ld\n",
@@ -968,13 +960,9 @@ void of_thermal_destroy_zones(void)
		return;
	}

	for_each_child_of_node(np, child) {
	for_each_available_child_of_node(np, child) {
		struct thermal_zone_device *zone;

		/* Check whether child is enabled or not */
		if (!of_device_is_available(child))
			continue;

		zone = thermal_zone_get_zone_by_name(child->name);
		if (IS_ERR(zone))
			continue;
Loading