Commit c1dbe9a1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull thermal control updates from Rafael Wysocki:
 "These start a rework of the handling of trip points in the thermal
  core, improve the cpufreq/devfreq cooling device handling, update some
  thermal control drivers and the tmon utility and clean up code.

  Specifics:

   - Consolidate the thermal core code by beginning to move the thermal
     trip structure from the thermal OF code as a generic structure to
     be used by the different sensors when registering a thermal zone
     (Daniel Lezcano).

   - Make per cpufreq / devfreq cooling device ops instead of using a
     global variable, fix comments and rework the trace information
     (Lukasz Luba).

   - Add the include/dt-bindings/thermal.h under the area covered by the
     thermal maintainer in the MAINTAINERS file (Lukas Bulwahn).

   - Improve the error output by giving the sensor identification when a
     thermal zone failed to initialize, the DT bindings by changing the
     positive logic and adding the r8a779f0 support on the rcar3
     (Wolfram Sang).

   - Convert the QCom tsens DT binding to the dtsformat format
     (Krzysztof Kozlowski).

   - Remove the pointless get_trend() function in the QCom, Ux500 and
     tegra thermal drivers, along with the unused DROP_FULL and
     RAISE_FULL trends definitions. Simplify the code by using clamp()
     macros (Daniel Lezcano).

   - Fix ref_table memory leak at probe time on the k3_j72xx bandgap
     (Bryan Brattlof).

   - Fix array underflow in prep_lookup_table (Dan Carpenter).

   - Add static annotation to the k3_j72xx_bandgap_j7* data structure
     (Jin Xiaoyun).

   - Fix typos in comments detected on sun8i by Coccinelle (Julia
     Lawall).

   - Fix typos in comments on rzg2l (Biju Das).

   - Remove as unnecessary call to dev_err() as the error is already
     printed by the failing function on u8500 (Yang Li).

   - Register the thermal zones as hwmon sensors for the Qcom thermal
     sensors (Dmitry Baryshkov).

   - Fix 'tmon' tool compilation issue by adding phtread.h include
     (Markus Mayer).

   - Fix typo in the comments for the 'tmon' tool (Slark Xiao).

   - Make the thermal core use ida_alloc()/free() directly instead of
     ida_simple_get()/ida_simple_remove() that have been deprecated
     (keliu).

   - Drop ACPI_FADT_LOW_POWER_S0 check from the Intel PCH thermal
     control driver (Rafael Wysocki)"

* tag 'thermal-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (39 commits)
  thermal/of: Initialize trip points separately
  thermal/of: Use thermal trips stored in the thermal zone
  thermal/core: Add thermal_trip in thermal_zone
  thermal/core: Rename 'trips' to 'num_trips'
  thermal/core: Move thermal_set_delay_jiffies to static
  thermal/core: Remove unneeded EXPORT_SYMBOLS
  thermal/of: Move thermal_trip structure to thermal.h
  thermal/of: Remove the device node pointer for thermal_trip
  thermal/of: Replace device node match with device node search
  thermal/core: Remove duplicate information when an error occurs
  thermal/core: Avoid calling ->get_trip_temp() unnecessarily
  thermal/tools/tmon: Fix typo 'the the' in comment
  thermal/tools/tmon: Include pthread and time headers in tmon.h
  thermal/ti-soc-thermal: Fix comment typo
  thermal/drivers/qcom/spmi-adc-tm5: Register thermal zones as hwmon sensors
  thermal/drivers/qcom/temp-alarm: Register thermal zones as hwmon sensors
  thermal/drivers/u8500: Remove unnecessary print function dev_err()
  thermal/drivers/rzg2l: Fix comments
  thermal/drivers/sun8i: Fix typo in comment
  thermal/drivers/k3_j72xx_bandgap: Make k3_j72xx_bandgap_j721e_data and k3_j72xx_bandgap_j7200_data static
  ...
parents a771ea64 da9d0179
Loading
Loading
Loading
Loading
+85 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/thermal/qcom,spmi-temp-alarm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Qualcomm QPNP PMIC Temperature Alarm

maintainers:
  - Bjorn Andersson <bjorn.andersson@linaro.org>

description:
  QPNP temperature alarm peripherals are found inside of Qualcomm PMIC chips
  that utilize the Qualcomm SPMI implementation. These peripherals provide an
  interrupt signal and status register to identify high PMIC die temperature.

allOf:
  - $ref: thermal-sensor.yaml#

properties:
  compatible:
    const: qcom,spmi-temp-alarm

  reg:
    maxItems: 1

  interrupts:
    maxItems: 1

  io-channels:
    items:
      - description: ADC channel, which reports chip die temperature

  io-channel-names:
    items:
      - const: thermal

  '#thermal-sensor-cells':
    const: 0

required:
  - compatible
  - reg
  - interrupts
  - '#thermal-sensor-cells'

additionalProperties: false

examples:
  - |
    #include <dt-bindings/interrupt-controller/arm-gic.h>

    pmic {
        #address-cells = <1>;
        #size-cells = <0>;

        pm8350_temp_alarm: temperature-sensor@a00 {
            compatible = "qcom,spmi-temp-alarm";
            reg = <0xa00>;
            interrupts = <0x1 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
            #thermal-sensor-cells = <0>;
        };
    };

    thermal-zones {
        pm8350_thermal: pm8350c-thermal {
            polling-delay-passive = <100>;
            polling-delay = <0>;
            thermal-sensors = <&pm8350_temp_alarm>;

            trips {
                pm8350_trip0: trip0 {
                    temperature = <95000>;
                    hysteresis = <0>;
                    type = "passive";
                };

                pm8350_crit: pm8350c-crit {
                    temperature = <115000>;
                    hysteresis = <0>;
                    type = "critical";
                };
            };
        };
    };
+0 −51
Original line number Diff line number Diff line
Qualcomm QPNP PMIC Temperature Alarm

QPNP temperature alarm peripherals are found inside of Qualcomm PMIC chips
that utilize the Qualcomm SPMI implementation. These peripherals provide an
interrupt signal and status register to identify high PMIC die temperature.

Required properties:
- compatible:      Should contain "qcom,spmi-temp-alarm".
- reg:             Specifies the SPMI address.
- interrupts:      PMIC temperature alarm interrupt.
- #thermal-sensor-cells: Should be 0. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.

Optional properties:
- io-channels:     Should contain IIO channel specifier for the ADC channel,
                   which report chip die temperature.
- io-channel-names: Should contain "thermal".

Example:

	pm8941_temp: thermal-alarm@2400 {
		compatible = "qcom,spmi-temp-alarm";
		reg = <0x2400>;
		interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>;
		#thermal-sensor-cells = <0>;

		io-channels = <&pm8941_vadc VADC_DIE_TEMP>;
		io-channel-names = "thermal";
	};

	thermal-zones {
		pm8941 {
			polling-delay-passive = <250>;
			polling-delay = <1000>;

			thermal-sensors = <&pm8941_temp>;

			trips {
				stage1 {
					temperature = <105000>;
					hysteresis = <2000>;
					type = "passive";
				};
				stage2 {
					temperature = <125000>;
					hysteresis = <2000>;
					type = "critical";
				};
			};
		};
	};
+22 −14
Original line number Diff line number Diff line
@@ -8,9 +8,9 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas R-Car Gen3 Thermal Sensor

description:
  On R-Car Gen3 SoCs, the thermal sensor controllers (TSC) control the thermal
  sensors (THS) which are the analog circuits for measuring temperature (Tj)
  inside the LSI.
  On most R-Car Gen3 and later SoCs, the thermal sensor controllers (TSC)
  control the thermal sensors (THS) which are the analog circuits for
  measuring temperature (Tj) inside the LSI.

maintainers:
  - Niklas Söderlund <niklas.soderlund@ragnatech.se>
@@ -27,6 +27,7 @@ properties:
      - renesas,r8a77965-thermal # R-Car M3-N
      - renesas,r8a77980-thermal # R-Car V3H
      - renesas,r8a779a0-thermal # R-Car V3U
      - renesas,r8a779f0-thermal # R-Car S4-8

  reg: true

@@ -57,7 +58,6 @@ required:
  - "#thermal-sensor-cells"

if:
  not:
  properties:
    compatible:
      contains:
@@ -66,22 +66,30 @@ if:
then:
  properties:
    reg:
      minItems: 2
      items:
        - description: TSC0 registers
        - description: TSC1 registers
        - description: TSC2 registers
        - description: TSC3 registers
  required:
    - interrupts
        - description: TSC4 registers
else:
  properties:
    reg:
      minItems: 2
      items:
        - description: TSC0 registers
        - description: TSC1 registers
        - description: TSC2 registers
        - description: TSC3 registers
        - description: TSC4 registers
  if:
    not:
      properties:
        compatible:
          contains:
            enum:
              - renesas,r8a779f0-thermal
  then:
    required:
      - interrupts

additionalProperties: false

+1 −0
Original line number Diff line number Diff line
@@ -19949,6 +19949,7 @@ F: Documentation/ABI/testing/sysfs-class-thermal
F:	Documentation/devicetree/bindings/thermal/
F:	Documentation/driver-api/thermal/
F:	drivers/thermal/
F:	include/dt-bindings/thermal/
F:	include/linux/cpu_cooling.h
F:	include/linux/thermal.h
F:	include/uapi/linux/thermal.h
+25 −52
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ struct time_in_idle {
 * @cdev: thermal_cooling_device pointer to keep track of the
 *	registered cooling device.
 * @policy: cpufreq policy.
 * @cooling_ops: cpufreq callbacks to thermal cooling device ops
 * @idle_time: idle time stats
 * @qos_req: PM QoS contraint to apply
 *
@@ -72,6 +73,7 @@ struct cpufreq_cooling_device {
	unsigned int max_level;
	struct em_perf_domain *em;
	struct cpufreq_policy *policy;
	struct thermal_cooling_device_ops cooling_ops;
#ifndef CONFIG_SMP
	struct time_in_idle *idle_time;
#endif
@@ -211,7 +213,7 @@ static u32 get_dynamic_power(struct cpufreq_cooling_device *cpufreq_cdev,
 * complex code may be needed if experiments show that it's not
 * accurate enough.
 *
 * Return: 0 on success, -E* if getting the static power failed.
 * Return: 0 on success, this function doesn't fail.
 */
static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
				       u32 *power)
@@ -221,16 +223,9 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
	u32 total_load = 0;
	struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
	struct cpufreq_policy *policy = cpufreq_cdev->policy;
	u32 *load_cpu = NULL;

	freq = cpufreq_quick_get(policy->cpu);

	if (trace_thermal_power_cpu_get_power_enabled()) {
		u32 ncpus = cpumask_weight(policy->related_cpus);

		load_cpu = kcalloc(ncpus, sizeof(*load_cpu), GFP_KERNEL);
	}

	for_each_cpu(cpu, policy->related_cpus) {
		u32 load;

@@ -240,22 +235,13 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
			load = 0;

		total_load += load;
		if (load_cpu)
			load_cpu[i] = load;

		i++;
	}

	cpufreq_cdev->last_load = total_load;

	*power = get_dynamic_power(cpufreq_cdev, freq);

	if (load_cpu) {
		trace_thermal_power_cpu_get_power(policy->related_cpus, freq,
						  load_cpu, i, *power);

		kfree(load_cpu);
	}
	trace_thermal_power_cpu_get_power_simple(policy->cpu, *power);

	return 0;
}
@@ -270,9 +256,8 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
 * milliwatts assuming 100% load.  Store the calculated power in
 * @power.
 *
 * Return: 0 on success, -EINVAL if the cooling device state could not
 * be converted into a frequency or other -E* if there was an error
 * when calculating the static power.
 * Return: 0 on success, -EINVAL if the cooling device state is bigger
 * than maximum allowed.
 */
static int cpufreq_state2power(struct thermal_cooling_device *cdev,
			       unsigned long state, u32 *power)
@@ -302,15 +287,11 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
 * Calculate a cooling device state for the cpus described by @cdev
 * that would allow them to consume at most @power mW and store it in
 * @state.  Note that this calculation depends on external factors
 * such as the cpu load or the current static power.  Calling this
 * function with the same power as input can yield different cooling
 * device states depending on those external factors.
 *
 * Return: 0 on success, -ENODEV if no cpus are online or -EINVAL if
 * the calculated frequency could not be converted to a valid state.
 * The latter should not happen unless the frequencies available to
 * cpufreq have changed since the initialization of the cpu cooling
 * device.
 * such as the CPUs load.  Calling this function with the same power
 * as input can yield different cooling device states depending on those
 * external factors.
 *
 * Return: 0 on success, this function doesn't fail.
 */
static int cpufreq_power2state(struct thermal_cooling_device *cdev,
			       u32 power, unsigned long *state)
@@ -422,7 +403,7 @@ static unsigned int get_state_freq(struct cpufreq_cooling_device *cpufreq_cdev,
 * Callback for the thermal cooling device to return the cpufreq
 * max cooling state.
 *
 * Return: 0 on success, an error code otherwise.
 * Return: 0 on success, this function doesn't fail.
 */
static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
				 unsigned long *state)
@@ -441,7 +422,7 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
 * Callback for the thermal cooling device to return the cpufreq
 * current cooling state.
 *
 * Return: 0 on success, an error code otherwise.
 * Return: 0 on success, this function doesn't fail.
 */
static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
				 unsigned long *state)
@@ -492,14 +473,6 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
	return ret;
}

/* Bind cpufreq callbacks to thermal cooling device ops */

static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
	.get_max_state		= cpufreq_get_max_state,
	.get_cur_state		= cpufreq_get_cur_state,
	.set_cur_state		= cpufreq_set_cur_state,
};

/**
 * __cpufreq_cooling_register - helper function to create cpufreq cooling device
 * @np: a valid struct device_node to the cooling device device tree node
@@ -508,7 +481,7 @@ static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
 * @em: Energy Model of the cpufreq policy
 *
 * This interface function registers the cpufreq cooling device with the name
 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
 * "cpufreq-%s". This API can support multiple instances of cpufreq
 * cooling devices. It also gives the opportunity to link the cooling device
 * with a device tree node, in order to bind it via the thermal DT code.
 *
@@ -561,7 +534,10 @@ __cpufreq_cooling_register(struct device_node *np,
	/* max_level is an index, not a counter */
	cpufreq_cdev->max_level = i - 1;

	cooling_ops = &cpufreq_cooling_ops;
	cooling_ops = &cpufreq_cdev->cooling_ops;
	cooling_ops->get_max_state = cpufreq_get_max_state;
	cooling_ops->get_cur_state = cpufreq_get_cur_state;
	cooling_ops->set_cur_state = cpufreq_set_cur_state;

#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
	if (em_is_sane(cpufreq_cdev, em)) {
@@ -616,8 +592,8 @@ __cpufreq_cooling_register(struct device_node *np,
 * @policy: cpufreq policy
 *
 * This interface function registers the cpufreq cooling device with the name
 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
 * cooling devices.
 * "cpufreq-%s". This API can support multiple instances of cpufreq cooling
 * devices.
 *
 * Return: a valid struct thermal_cooling_device pointer on success,
 * on failure, it returns a corresponding ERR_PTR().
@@ -634,17 +610,14 @@ EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
 * @policy: cpufreq policy
 *
 * This interface function registers the cpufreq cooling device with the name
 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
 * cooling devices. Using this API, the cpufreq cooling device will be
 * linked to the device tree node provided.
 * "cpufreq-%s". This API can support multiple instances of cpufreq cooling
 * devices. Using this API, the cpufreq cooling device will be linked to the
 * device tree node provided.
 *
 * Using this function, the cooling device will implement the power
 * extensions by using a simple cpu power model.  The cpus must have
 * extensions by using the Energy Model (if present).  The cpus must have
 * registered their OPPs using the OPP library.
 *
 * It also takes into account, if property present in policy CPU node, the
 * static power consumed by the cpu.
 *
 * Return: a valid struct thermal_cooling_device pointer on success,
 * and NULL on failure.
 */
@@ -680,7 +653,7 @@ EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register);
 * cpufreq_cooling_unregister - function to remove cpufreq cooling device.
 * @cdev: thermal cooling device pointer.
 *
 * This interface function unregisters the "thermal-cpufreq-%x" cooling device.
 * This interface function unregisters the "cpufreq-%x" cooling device.
 */
void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
{
Loading