mirror of
https://github.com/torvalds/linux.git
synced 2024-12-30 14:52:05 +00:00
Thermal control updates for 5.20-rc1
- 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). -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmLoK5ASHHJqd0Byand5 c29ja2kubmV0AAoJEILEb/54YlRxa0cQAJsl3wDxkDbvfEENZ1VSdfeH3qXbUSSE EEo0j4X85JE1F1NwT8R2tb4D/YMJDT3p6I55twrVLvxNUdTnx7ybRfXem24uXkK5 xOybfsuYsSWXxaEfI4260GBzY6ijTR7uWYyDLPN3vvbW3FdMj+nni0D9uTySw7UL ecIe1ISn3nxbbp0FxYh+n88+718HWKo07BaTE4TyKeUgQHw+v7HHtCZq7Rdoogm8 cp6tTkJ8ymrHoEvAWBIcO58zCx7LkSFeU69oMm4CUzVjxWdFfREb079F5cZ92GXr ex70r/gKfFAd5GAAdL0WjeS4RwHKta49WKqAMA7w41nIgDj0IA2gJRowfJvKDkF+ JgcQ7OrJ5eo5jCr4pbycgQ9Lh23zBQe/3LH+yV71KlKiLf6/Tl5rhELfBNbZmraZ HOvD5dAxBLySmANN2VX7DJgtbTcinneL9BDVo6dBTdYaWC4jQxXYm73n66nkZdS7 BDJ0N2P0uZ7NGLawXwrrsMi8xbIApMw4W/o8SN9R4FF1LqIroDg60kLJ9zO+6IhI xF8ZtcMdyPVa71fSZNwD0+mz2sF6XnTucf88CjxzVdAxbvNVPQEvKufThWTreyuU pjBPtf1YFOFz9CusBYAplOIu96RqUgL1t1aqqwsCqXoUu4Lgh/pyksIDeam1l0EP Q5WBUB9bK8q8 =wj9M -----END PGP SIGNATURE----- Merge tag 'thermal-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm 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 ...
This commit is contained in:
commit
c1dbe9a1c8
@ -0,0 +1,85 @@
|
||||
# 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -1,51 +0,0 @@
|
||||
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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -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,23 +58,12 @@ required:
|
||||
- "#thermal-sensor-cells"
|
||||
|
||||
if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- renesas,r8a779a0-thermal
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
items:
|
||||
- description: TSC1 registers
|
||||
- description: TSC2 registers
|
||||
- description: TSC3 registers
|
||||
required:
|
||||
- interrupts
|
||||
else:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- renesas,r8a779a0-thermal
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
@ -82,6 +72,24 @@ else:
|
||||
- description: TSC2 registers
|
||||
- description: TSC3 registers
|
||||
- description: TSC4 registers
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
items:
|
||||
- description: TSC1 registers
|
||||
- description: TSC2 registers
|
||||
- description: TSC3 registers
|
||||
if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- renesas,r8a779f0-thermal
|
||||
then:
|
||||
required:
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
* 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, -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.
|
||||
* 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 @@ free_cdev:
|
||||
* @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)
|
||||
{
|
||||
|
@ -53,7 +53,6 @@ static const unsigned long db8500_thermal_points[] = {
|
||||
|
||||
struct db8500_thermal_zone {
|
||||
struct thermal_zone_device *tz;
|
||||
enum thermal_trend trend;
|
||||
unsigned long interpolated_temp;
|
||||
unsigned int cur_index;
|
||||
};
|
||||
@ -73,24 +72,12 @@ static int db8500_thermal_get_temp(void *data, int *temp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Callback to get temperature changing trend */
|
||||
static int db8500_thermal_get_trend(void *data, int trip, enum thermal_trend *trend)
|
||||
{
|
||||
struct db8500_thermal_zone *th = data;
|
||||
|
||||
*trend = th->trend;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_zone_of_device_ops thdev_ops = {
|
||||
.get_temp = db8500_thermal_get_temp,
|
||||
.get_trend = db8500_thermal_get_trend,
|
||||
};
|
||||
|
||||
static void db8500_thermal_update_config(struct db8500_thermal_zone *th,
|
||||
unsigned int idx,
|
||||
enum thermal_trend trend,
|
||||
unsigned long next_low,
|
||||
unsigned long next_high)
|
||||
{
|
||||
@ -98,7 +85,6 @@ static void db8500_thermal_update_config(struct db8500_thermal_zone *th,
|
||||
|
||||
th->cur_index = idx;
|
||||
th->interpolated_temp = (next_low + next_high)/2;
|
||||
th->trend = trend;
|
||||
|
||||
/*
|
||||
* The PRCMU accept absolute temperatures in celsius so divide
|
||||
@ -127,8 +113,7 @@ static irqreturn_t prcmu_low_irq_handler(int irq, void *irq_data)
|
||||
}
|
||||
idx -= 1;
|
||||
|
||||
db8500_thermal_update_config(th, idx, THERMAL_TREND_DROPPING,
|
||||
next_low, next_high);
|
||||
db8500_thermal_update_config(th, idx, next_low, next_high);
|
||||
dev_dbg(&th->tz->device,
|
||||
"PRCMU set max %ld, min %ld\n", next_high, next_low);
|
||||
|
||||
@ -149,8 +134,7 @@ static irqreturn_t prcmu_high_irq_handler(int irq, void *irq_data)
|
||||
next_low = db8500_thermal_points[idx];
|
||||
idx += 1;
|
||||
|
||||
db8500_thermal_update_config(th, idx, THERMAL_TREND_RAISING,
|
||||
next_low, next_high);
|
||||
db8500_thermal_update_config(th, idx, next_low, next_high);
|
||||
|
||||
dev_dbg(&th->tz->device,
|
||||
"PRCMU set max %ld, min %ld\n", next_high, next_low);
|
||||
@ -174,10 +158,8 @@ static int db8500_thermal_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
low_irq = platform_get_irq_byname(pdev, "IRQ_HOTMON_LOW");
|
||||
if (low_irq < 0) {
|
||||
dev_err(dev, "Get IRQ_HOTMON_LOW failed\n");
|
||||
if (low_irq < 0)
|
||||
return low_irq;
|
||||
}
|
||||
|
||||
ret = devm_request_threaded_irq(dev, low_irq, NULL,
|
||||
prcmu_low_irq_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT,
|
||||
@ -188,10 +170,8 @@ static int db8500_thermal_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
high_irq = platform_get_irq_byname(pdev, "IRQ_HOTMON_HIGH");
|
||||
if (high_irq < 0) {
|
||||
dev_err(dev, "Get IRQ_HOTMON_HIGH failed\n");
|
||||
if (high_irq < 0)
|
||||
return high_irq;
|
||||
}
|
||||
|
||||
ret = devm_request_threaded_irq(dev, high_irq, NULL,
|
||||
prcmu_high_irq_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT,
|
||||
@ -210,8 +190,7 @@ static int db8500_thermal_probe(struct platform_device *pdev)
|
||||
dev_info(dev, "thermal zone sensor registered\n");
|
||||
|
||||
/* Start measuring at the lowest point */
|
||||
db8500_thermal_update_config(th, 0, THERMAL_TREND_STABLE,
|
||||
PRCMU_DEFAULT_LOW_TEMP,
|
||||
db8500_thermal_update_config(th, 0, PRCMU_DEFAULT_LOW_TEMP,
|
||||
db8500_thermal_points[0]);
|
||||
|
||||
platform_set_drvdata(pdev, th);
|
||||
@ -232,8 +211,7 @@ static int db8500_thermal_resume(struct platform_device *pdev)
|
||||
struct db8500_thermal_zone *th = platform_get_drvdata(pdev);
|
||||
|
||||
/* Resume and start measuring at the lowest point */
|
||||
db8500_thermal_update_config(th, 0, THERMAL_TREND_STABLE,
|
||||
PRCMU_DEFAULT_LOW_TEMP,
|
||||
db8500_thermal_update_config(th, 0, PRCMU_DEFAULT_LOW_TEMP,
|
||||
db8500_thermal_points[0]);
|
||||
|
||||
return 0;
|
||||
|
@ -28,6 +28,7 @@
|
||||
* struct devfreq_cooling_device - Devfreq cooling device
|
||||
* devfreq_cooling_device registered.
|
||||
* @cdev: Pointer to associated thermal cooling device.
|
||||
* @cooling_ops: devfreq callbacks to thermal cooling device ops
|
||||
* @devfreq: Pointer to associated devfreq device.
|
||||
* @cooling_state: Current cooling state.
|
||||
* @freq_table: Pointer to a table with the frequencies sorted in descending
|
||||
@ -48,6 +49,7 @@
|
||||
*/
|
||||
struct devfreq_cooling_device {
|
||||
struct thermal_cooling_device *cdev;
|
||||
struct thermal_cooling_device_ops cooling_ops;
|
||||
struct devfreq *devfreq;
|
||||
unsigned long cooling_state;
|
||||
u32 *freq_table;
|
||||
@ -301,12 +303,6 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_cooling_device_ops devfreq_cooling_ops = {
|
||||
.get_max_state = devfreq_cooling_get_max_state,
|
||||
.get_cur_state = devfreq_cooling_get_cur_state,
|
||||
.set_cur_state = devfreq_cooling_set_cur_state,
|
||||
};
|
||||
|
||||
/**
|
||||
* devfreq_cooling_gen_tables() - Generate frequency table.
|
||||
* @dfc: Pointer to devfreq cooling device.
|
||||
@ -374,18 +370,18 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
|
||||
char *name;
|
||||
int err, num_opps;
|
||||
|
||||
ops = kmemdup(&devfreq_cooling_ops, sizeof(*ops), GFP_KERNEL);
|
||||
if (!ops)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
dfc = kzalloc(sizeof(*dfc), GFP_KERNEL);
|
||||
if (!dfc) {
|
||||
err = -ENOMEM;
|
||||
goto free_ops;
|
||||
}
|
||||
if (!dfc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
dfc->devfreq = df;
|
||||
|
||||
ops = &dfc->cooling_ops;
|
||||
ops->get_max_state = devfreq_cooling_get_max_state;
|
||||
ops->get_cur_state = devfreq_cooling_get_cur_state;
|
||||
ops->set_cur_state = devfreq_cooling_set_cur_state;
|
||||
|
||||
em = em_pd_get(dev);
|
||||
if (em && !em_is_artificial(em)) {
|
||||
dfc->em_pd = em;
|
||||
@ -448,8 +444,6 @@ free_table:
|
||||
kfree(dfc->freq_table);
|
||||
free_dfc:
|
||||
kfree(dfc);
|
||||
free_ops:
|
||||
kfree(ops);
|
||||
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
@ -531,13 +525,11 @@ EXPORT_SYMBOL_GPL(devfreq_cooling_em_register);
|
||||
void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
|
||||
{
|
||||
struct devfreq_cooling_device *dfc;
|
||||
const struct thermal_cooling_device_ops *ops;
|
||||
struct device *dev;
|
||||
|
||||
if (IS_ERR_OR_NULL(cdev))
|
||||
return;
|
||||
|
||||
ops = cdev->ops;
|
||||
dfc = cdev->devdata;
|
||||
dev = dfc->devfreq->dev.parent;
|
||||
|
||||
@ -548,6 +540,5 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
|
||||
|
||||
kfree(dfc->freq_table);
|
||||
kfree(dfc);
|
||||
kfree(ops);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devfreq_cooling_unregister);
|
||||
|
@ -25,10 +25,10 @@ static int get_trip_level(struct thermal_zone_device *tz)
|
||||
int trip_temp;
|
||||
enum thermal_trip_type trip_type;
|
||||
|
||||
if (tz->trips == 0 || !tz->ops->get_trip_temp)
|
||||
if (tz->num_trips == 0 || !tz->ops->get_trip_temp)
|
||||
return 0;
|
||||
|
||||
for (count = 0; count < tz->trips; count++) {
|
||||
for (count = 0; count < tz->num_trips; count++) {
|
||||
tz->ops->get_trip_temp(tz, count, &trip_temp);
|
||||
if (tz->temperature < trip_temp)
|
||||
break;
|
||||
@ -53,7 +53,7 @@ static long get_target_state(struct thermal_zone_device *tz,
|
||||
|
||||
cdev->ops->get_max_state(cdev, &max_state);
|
||||
|
||||
return (long)(percentage * level * max_state) / (100 * tz->trips);
|
||||
return (long)(percentage * level * max_state) / (100 * tz->num_trips);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -527,7 +527,7 @@ static void get_governor_trips(struct thermal_zone_device *tz,
|
||||
last_active = INVALID_TRIP;
|
||||
last_passive = INVALID_TRIP;
|
||||
|
||||
for (i = 0; i < tz->trips; i++) {
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
enum thermal_trip_type type;
|
||||
int ret;
|
||||
|
||||
@ -668,7 +668,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
|
||||
|
||||
get_governor_trips(tz, params);
|
||||
|
||||
if (tz->trips > 0) {
|
||||
if (tz->num_trips > 0) {
|
||||
ret = tz->ops->get_trip_temp(tz,
|
||||
params->trip_max_desired_temperature,
|
||||
&control_temp);
|
||||
|
@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <trace/events/thermal.h>
|
||||
|
||||
#include "thermal_core.h"
|
||||
@ -52,10 +53,7 @@ static unsigned long get_target_state(struct thermal_instance *instance,
|
||||
|
||||
if (!instance->initialized) {
|
||||
if (throttle) {
|
||||
next_target = (cur_state + 1) >= instance->upper ?
|
||||
instance->upper :
|
||||
((cur_state + 1) < instance->lower ?
|
||||
instance->lower : (cur_state + 1));
|
||||
next_target = clamp((cur_state + 1), instance->lower, instance->upper);
|
||||
} else {
|
||||
next_target = THERMAL_NO_TARGET;
|
||||
}
|
||||
@ -66,35 +64,19 @@ static unsigned long get_target_state(struct thermal_instance *instance,
|
||||
switch (trend) {
|
||||
case THERMAL_TREND_RAISING:
|
||||
if (throttle) {
|
||||
next_target = cur_state < instance->upper ?
|
||||
(cur_state + 1) : instance->upper;
|
||||
if (next_target < instance->lower)
|
||||
next_target = instance->lower;
|
||||
next_target = clamp((cur_state + 1), instance->lower, instance->upper);
|
||||
}
|
||||
break;
|
||||
case THERMAL_TREND_RAISE_FULL:
|
||||
if (throttle)
|
||||
next_target = instance->upper;
|
||||
break;
|
||||
case THERMAL_TREND_DROPPING:
|
||||
if (cur_state <= instance->lower) {
|
||||
if (!throttle)
|
||||
next_target = THERMAL_NO_TARGET;
|
||||
} else {
|
||||
if (!throttle) {
|
||||
next_target = cur_state - 1;
|
||||
if (next_target > instance->upper)
|
||||
next_target = instance->upper;
|
||||
next_target = clamp((cur_state - 1), instance->lower, instance->upper);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case THERMAL_TREND_DROP_FULL:
|
||||
if (cur_state == instance->lower) {
|
||||
if (!throttle)
|
||||
next_target = THERMAL_NO_TARGET;
|
||||
} else
|
||||
next_target = instance->lower;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -207,14 +207,6 @@ static int pch_wpt_suspend(struct pch_thermal_device *ptd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do not check temperature if it is not a S0ix capable platform */
|
||||
#ifdef CONFIG_ACPI
|
||||
if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
|
||||
return 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* Do not check temperature if it is not s2idle */
|
||||
if (pm_suspend_via_firmware())
|
||||
return 0;
|
||||
|
@ -105,7 +105,7 @@ static struct zone_device *pkg_temp_thermal_get_dev(unsigned int cpu)
|
||||
}
|
||||
|
||||
/*
|
||||
* tj-max is is interesting because threshold is set relative to this
|
||||
* tj-max is interesting because threshold is set relative to this
|
||||
* temperature.
|
||||
*/
|
||||
static int get_tj_max(int cpu, u32 *tj_max)
|
||||
|
@ -151,8 +151,6 @@ static int prep_lookup_table(struct err_values *err_vals, int *ref_table)
|
||||
/* 300 milli celsius steps */
|
||||
while (i--)
|
||||
derived_table[i] = derived_table[i + 1] - 300;
|
||||
/* case 0 */
|
||||
derived_table[i] = derived_table[i + 1] - 300;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -433,7 +431,7 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
|
||||
GFP_KERNEL);
|
||||
if (!derived_table) {
|
||||
ret = -ENOMEM;
|
||||
goto err_alloc;
|
||||
goto err_free_ref_table;
|
||||
}
|
||||
|
||||
/* Workaround not needed if bit30/bit31 is set even for J721e */
|
||||
@ -483,7 +481,7 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(ti_thermal)) {
|
||||
dev_err(bgp->dev, "thermal zone device is NULL\n");
|
||||
ret = PTR_ERR(ti_thermal);
|
||||
goto err_alloc;
|
||||
goto err_free_ref_table;
|
||||
}
|
||||
}
|
||||
|
||||
@ -514,6 +512,9 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_ref_table:
|
||||
kfree(ref_table);
|
||||
|
||||
err_alloc:
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
@ -529,11 +530,11 @@ static int k3_j72xx_bandgap_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct k3_j72xx_bandgap_data k3_j72xx_bandgap_j721e_data = {
|
||||
static const struct k3_j72xx_bandgap_data k3_j72xx_bandgap_j721e_data = {
|
||||
.has_errata_i2128 = 1,
|
||||
};
|
||||
|
||||
const struct k3_j72xx_bandgap_data k3_j72xx_bandgap_j7200_data = {
|
||||
static const struct k3_j72xx_bandgap_data k3_j72xx_bandgap_j7200_data = {
|
||||
.has_errata_i2128 = 0,
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <linux/thermal.h>
|
||||
#include <asm-generic/unaligned.h>
|
||||
|
||||
#include "../thermal_hwmon.h"
|
||||
|
||||
/*
|
||||
* Thermal monitoring block consists of 8 (ADC_TM5_NUM_CHANNELS) channels. Each
|
||||
* channel is programmed to use one of ADC channels for voltage comparison.
|
||||
@ -687,6 +689,9 @@ static int adc_tm5_register_tzd(struct adc_tm5_chip *adc_tm)
|
||||
return PTR_ERR(tzd);
|
||||
}
|
||||
adc_tm->channels[i].tzd = tzd;
|
||||
if (devm_thermal_add_hwmon_sysfs(tzd))
|
||||
dev_warn(adc_tm->dev,
|
||||
"Failed to add hwmon sysfs attributes\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/thermal.h>
|
||||
|
||||
#include "../thermal_core.h"
|
||||
#include "../thermal_hwmon.h"
|
||||
|
||||
#define QPNP_TM_REG_DIG_MAJOR 0x01
|
||||
#define QPNP_TM_REG_TYPE 0x04
|
||||
@ -458,6 +459,10 @@ static int qpnp_tm_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (devm_thermal_add_hwmon_sysfs(chip->tz_dev))
|
||||
dev_warn(&pdev->dev,
|
||||
"Failed to add hwmon sysfs attributes\n");
|
||||
|
||||
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, qpnp_tm_isr,
|
||||
IRQF_ONESHOT, node->name, chip);
|
||||
if (ret < 0)
|
||||
|
@ -933,17 +933,6 @@ static int tsens_get_temp(void *data, int *temp)
|
||||
return priv->ops->get_temp(s, temp);
|
||||
}
|
||||
|
||||
static int tsens_get_trend(void *data, int trip, enum thermal_trend *trend)
|
||||
{
|
||||
struct tsens_sensor *s = data;
|
||||
struct tsens_priv *priv = s->priv;
|
||||
|
||||
if (priv->ops->get_trend)
|
||||
return priv->ops->get_trend(s, trend);
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static int __maybe_unused tsens_suspend(struct device *dev)
|
||||
{
|
||||
struct tsens_priv *priv = dev_get_drvdata(dev);
|
||||
@ -1004,7 +993,6 @@ MODULE_DEVICE_TABLE(of, tsens_table);
|
||||
|
||||
static const struct thermal_zone_of_device_ops tsens_of_ops = {
|
||||
.get_temp = tsens_get_temp,
|
||||
.get_trend = tsens_get_trend,
|
||||
.set_trips = tsens_set_trips,
|
||||
};
|
||||
|
||||
|
@ -65,7 +65,6 @@ struct tsens_sensor {
|
||||
* @disable: Function to disable the tsens device
|
||||
* @suspend: Function to suspend the tsens device
|
||||
* @resume: Function to resume the tsens device
|
||||
* @get_trend: Function to get the thermal/temp trend
|
||||
*/
|
||||
struct tsens_ops {
|
||||
/* mandatory callbacks */
|
||||
@ -77,7 +76,6 @@ struct tsens_ops {
|
||||
void (*disable)(struct tsens_priv *priv);
|
||||
int (*suspend)(struct tsens_priv *priv);
|
||||
int (*resume)(struct tsens_priv *priv);
|
||||
int (*get_trend)(struct tsens_sensor *s, enum thermal_trend *trend);
|
||||
};
|
||||
|
||||
#define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \
|
||||
|
@ -511,7 +511,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
|
||||
zone = devm_thermal_zone_of_sensor_register(dev, i, tsc,
|
||||
&rcar_gen3_tz_of_ops);
|
||||
if (IS_ERR(zone)) {
|
||||
dev_err(dev, "Can't register thermal zone\n");
|
||||
dev_err(dev, "Sensor %u: Can't register thermal zone\n", i);
|
||||
ret = PTR_ERR(zone);
|
||||
goto error_unregister;
|
||||
}
|
||||
@ -533,7 +533,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
goto error_unregister;
|
||||
|
||||
dev_info(dev, "TSC%u: Loaded %d trip points\n", i, ret);
|
||||
dev_info(dev, "Sensor %u: Loaded %d trip points\n", i, ret);
|
||||
}
|
||||
|
||||
if (!priv->num_tscs) {
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
#define TS_CODE_AVE_SCALE(x) ((x) * 1000000)
|
||||
#define MCELSIUS(temp) ((temp) * MILLIDEGREE_PER_DEGREE)
|
||||
#define TS_CODE_CAP_TIMES 8 /* Capture times */
|
||||
#define TS_CODE_CAP_TIMES 8 /* Total number of ADC data samples */
|
||||
|
||||
#define RZG2L_THERMAL_GRAN 500 /* milli Celsius */
|
||||
#define RZG2L_TSU_SS_TIMEOUT_US 1000
|
||||
@ -80,7 +80,8 @@ static int rzg2l_thermal_get_temp(void *devdata, int *temp)
|
||||
int val, i;
|
||||
|
||||
for (i = 0; i < TS_CODE_CAP_TIMES ; i++) {
|
||||
/* TSU repeats measurement at 20 microseconds intervals and
|
||||
/*
|
||||
* TSU repeats measurement at 20 microseconds intervals and
|
||||
* automatically updates the results of measurement. As per
|
||||
* the HW manual for measuring temperature we need to read 8
|
||||
* values consecutively and then take the average.
|
||||
@ -92,16 +93,18 @@ static int rzg2l_thermal_get_temp(void *devdata, int *temp)
|
||||
|
||||
ts_code_ave = result / TS_CODE_CAP_TIMES;
|
||||
|
||||
/* Calculate actual sensor value by applying curvature correction formula
|
||||
/*
|
||||
* Calculate actual sensor value by applying curvature correction formula
|
||||
* dsensor = ts_code_ave / (1 + ts_code_ave * 0.000013). Here we are doing
|
||||
* integer calculation by scaling all the values by 1000000.
|
||||
*/
|
||||
dsensor = TS_CODE_AVE_SCALE(ts_code_ave) /
|
||||
(TS_CODE_AVE_SCALE(1) + (ts_code_ave * CURVATURE_CORRECTION_CONST));
|
||||
|
||||
/* The temperature Tj is calculated by the formula
|
||||
/*
|
||||
* The temperature Tj is calculated by the formula
|
||||
* Tj = (dsensor − calib1) * 165/ (calib0 − calib1) − 40
|
||||
* where calib0 and calib1 are the caliberation values.
|
||||
* where calib0 and calib1 are the calibration values.
|
||||
*/
|
||||
val = ((dsensor - priv->calib1) * (MCELSIUS(165) /
|
||||
(priv->calib0 - priv->calib1))) - MCELSIUS(40);
|
||||
@ -122,7 +125,8 @@ static int rzg2l_thermal_init(struct rzg2l_thermal_priv *priv)
|
||||
rzg2l_thermal_write(priv, TSU_SM, TSU_SM_NORMAL_MODE);
|
||||
rzg2l_thermal_write(priv, TSU_ST, 0);
|
||||
|
||||
/* Before setting the START bit, TSU should be in normal operating
|
||||
/*
|
||||
* Before setting the START bit, TSU should be in normal operating
|
||||
* mode. As per the HW manual, it will take 60 µs to place the TSU
|
||||
* into normal operating mode.
|
||||
*/
|
||||
@ -217,7 +221,7 @@ static int rzg2l_thermal_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
dev_dbg(dev, "TSU probed with %s caliberation values",
|
||||
dev_dbg(dev, "TSU probed with %s calibration values",
|
||||
rzg2l_thermal_read(priv, OTPTSUTRIM_REG(0)) ? "hw" : "sw");
|
||||
|
||||
return 0;
|
||||
|
@ -237,7 +237,7 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
|
||||
* The calibration data on the H6 is the ambient temperature and
|
||||
* sensor values that are filled during the factory test stage.
|
||||
*
|
||||
* The unit of stored FT temperature is 0.1 degreee celusis.
|
||||
* The unit of stored FT temperature is 0.1 degree celsius.
|
||||
*
|
||||
* We need to calculate a delta between measured and caluclated
|
||||
* register values and this will become a calibration offset.
|
||||
|
@ -633,37 +633,6 @@ static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_thermctl_get_trend(void *data, int trip,
|
||||
enum thermal_trend *trend)
|
||||
{
|
||||
struct tegra_thermctl_zone *zone = data;
|
||||
struct thermal_zone_device *tz = zone->tz;
|
||||
int trip_temp, temp, last_temp, ret;
|
||||
|
||||
if (!tz)
|
||||
return -EINVAL;
|
||||
|
||||
ret = tz->ops->get_trip_temp(zone->tz, trip, &trip_temp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
temp = READ_ONCE(tz->temperature);
|
||||
last_temp = READ_ONCE(tz->last_temperature);
|
||||
|
||||
if (temp > trip_temp) {
|
||||
if (temp >= last_temp)
|
||||
*trend = THERMAL_TREND_RAISING;
|
||||
else
|
||||
*trend = THERMAL_TREND_STABLE;
|
||||
} else if (temp < trip_temp) {
|
||||
*trend = THERMAL_TREND_DROPPING;
|
||||
} else {
|
||||
*trend = THERMAL_TREND_STABLE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void thermal_irq_enable(struct tegra_thermctl_zone *zn)
|
||||
{
|
||||
u32 r;
|
||||
@ -716,7 +685,6 @@ static int tegra_thermctl_set_trips(void *data, int lo, int hi)
|
||||
static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
|
||||
.get_temp = tegra_thermctl_get_temp,
|
||||
.set_trip_temp = tegra_thermctl_set_trip_temp,
|
||||
.get_trend = tegra_thermctl_get_trend,
|
||||
.set_trips = tegra_thermctl_set_trips,
|
||||
};
|
||||
|
||||
|
@ -316,7 +316,7 @@ static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd,
|
||||
*hot_trip = 85000;
|
||||
*crit_trip = 90000;
|
||||
|
||||
for (i = 0; i < tzd->trips; i++) {
|
||||
for (i = 0; i < tzd->num_trips; i++) {
|
||||
enum thermal_trip_type type;
|
||||
int trip_temp;
|
||||
|
||||
|
@ -340,12 +340,8 @@ void thermal_zone_device_critical(struct thermal_zone_device *tz)
|
||||
EXPORT_SYMBOL(thermal_zone_device_critical);
|
||||
|
||||
static void handle_critical_trips(struct thermal_zone_device *tz,
|
||||
int trip, enum thermal_trip_type trip_type)
|
||||
int trip, int trip_temp, enum thermal_trip_type trip_type)
|
||||
{
|
||||
int trip_temp;
|
||||
|
||||
tz->ops->get_trip_temp(tz, trip, &trip_temp);
|
||||
|
||||
/* If we have not crossed the trip_temp, we do not care. */
|
||||
if (trip_temp <= 0 || tz->temperature < trip_temp)
|
||||
return;
|
||||
@ -384,7 +380,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
|
||||
}
|
||||
|
||||
if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
|
||||
handle_critical_trips(tz, trip, type);
|
||||
handle_critical_trips(tz, trip, trip_temp, type);
|
||||
else
|
||||
handle_non_critical_trips(tz, trip);
|
||||
/*
|
||||
@ -505,7 +501,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz,
|
||||
|
||||
tz->notify_event = event;
|
||||
|
||||
for (count = 0; count < tz->trips; count++)
|
||||
for (count = 0; count < tz->num_trips; count++)
|
||||
handle_thermal_trip(tz, count);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_device_update);
|
||||
@ -630,7 +626,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
||||
unsigned long max_state;
|
||||
int result, ret;
|
||||
|
||||
if (trip >= tz->trips || trip < 0)
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return -EINVAL;
|
||||
|
||||
list_for_each_entry(pos1, &thermal_tz_list, node) {
|
||||
@ -667,7 +663,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
||||
dev->target = THERMAL_NO_TARGET;
|
||||
dev->weight = weight;
|
||||
|
||||
result = ida_simple_get(&tz->ida, 0, 0, GFP_KERNEL);
|
||||
result = ida_alloc(&tz->ida, GFP_KERNEL);
|
||||
if (result < 0)
|
||||
goto free_mem;
|
||||
|
||||
@ -721,7 +717,7 @@ remove_trip_file:
|
||||
remove_symbol_link:
|
||||
sysfs_remove_link(&tz->device.kobj, dev->name);
|
||||
release_ida:
|
||||
ida_simple_remove(&tz->ida, dev->id);
|
||||
ida_free(&tz->ida, dev->id);
|
||||
free_mem:
|
||||
kfree(dev);
|
||||
return result;
|
||||
@ -768,7 +764,7 @@ unbind:
|
||||
device_remove_file(&tz->device, &pos->weight_attr);
|
||||
device_remove_file(&tz->device, &pos->attr);
|
||||
sysfs_remove_link(&tz->device.kobj, pos->name);
|
||||
ida_simple_remove(&tz->ida, pos->id);
|
||||
ida_free(&tz->ida, pos->id);
|
||||
kfree(pos);
|
||||
return 0;
|
||||
}
|
||||
@ -811,7 +807,7 @@ static void __bind(struct thermal_zone_device *tz, int mask,
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < tz->trips; i++) {
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
if (mask & (1 << i)) {
|
||||
unsigned long upper, lower;
|
||||
|
||||
@ -901,7 +897,7 @@ __thermal_cooling_device_register(struct device_node *np,
|
||||
if (!cdev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
|
||||
ret = ida_alloc(&thermal_cdev_ida, GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
goto out_kfree_cdev;
|
||||
cdev->id = ret;
|
||||
@ -952,7 +948,7 @@ out_kfree_type:
|
||||
put_device(&cdev->device);
|
||||
cdev = NULL;
|
||||
out_ida_remove:
|
||||
ida_simple_remove(&thermal_cdev_ida, id);
|
||||
ida_free(&thermal_cdev_ida, id);
|
||||
out_kfree_cdev:
|
||||
kfree(cdev);
|
||||
return ERR_PTR(ret);
|
||||
@ -1057,7 +1053,7 @@ static void __unbind(struct thermal_zone_device *tz, int mask,
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tz->trips; i++)
|
||||
for (i = 0; i < tz->num_trips; i++)
|
||||
if (mask & (1 << i))
|
||||
thermal_zone_unbind_cooling_device(tz, i, cdev);
|
||||
}
|
||||
@ -1111,7 +1107,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
|
||||
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
|
||||
ida_simple_remove(&thermal_cdev_ida, cdev->id);
|
||||
ida_free(&thermal_cdev_ida, cdev->id);
|
||||
device_del(&cdev->device);
|
||||
thermal_cooling_device_destroy_sysfs(cdev);
|
||||
kfree(cdev->type);
|
||||
@ -1159,10 +1155,18 @@ exit:
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
}
|
||||
|
||||
static void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms)
|
||||
{
|
||||
*delay_jiffies = msecs_to_jiffies(delay_ms);
|
||||
if (delay_ms > 1000)
|
||||
*delay_jiffies = round_jiffies(*delay_jiffies);
|
||||
}
|
||||
|
||||
/**
|
||||
* thermal_zone_device_register() - register a new thermal zone device
|
||||
* thermal_zone_device_register_with_trips() - register a new thermal zone device
|
||||
* @type: the thermal zone device type
|
||||
* @trips: the number of trip points the thermal zone support
|
||||
* @trips: a pointer to an array of thermal trips
|
||||
* @num_trips: the number of trip points the thermal zone support
|
||||
* @mask: a bit string indicating the writeablility of trip points
|
||||
* @devdata: private device data
|
||||
* @ops: standard thermal zone device callbacks
|
||||
@ -1184,10 +1188,10 @@ exit:
|
||||
* IS_ERR*() helpers.
|
||||
*/
|
||||
struct thermal_zone_device *
|
||||
thermal_zone_device_register(const char *type, int trips, int mask,
|
||||
void *devdata, struct thermal_zone_device_ops *ops,
|
||||
struct thermal_zone_params *tzp, int passive_delay,
|
||||
int polling_delay)
|
||||
thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *trips, int num_trips, int mask,
|
||||
void *devdata, struct thermal_zone_device_ops *ops,
|
||||
struct thermal_zone_params *tzp, int passive_delay,
|
||||
int polling_delay)
|
||||
{
|
||||
struct thermal_zone_device *tz;
|
||||
enum thermal_trip_type trip_type;
|
||||
@ -1198,27 +1202,27 @@ thermal_zone_device_register(const char *type, int trips, int mask,
|
||||
struct thermal_governor *governor;
|
||||
|
||||
if (!type || strlen(type) == 0) {
|
||||
pr_err("Error: No thermal zone type defined\n");
|
||||
pr_err("No thermal zone type defined\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
|
||||
pr_err("Error: Thermal zone name (%s) too long, should be under %d chars\n",
|
||||
pr_err("Thermal zone name (%s) too long, should be under %d chars\n",
|
||||
type, THERMAL_NAME_LENGTH);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips) {
|
||||
pr_err("Error: Incorrect number of thermal trips\n");
|
||||
if (num_trips > THERMAL_MAX_TRIPS || num_trips < 0 || mask >> num_trips) {
|
||||
pr_err("Incorrect number of thermal trips\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (!ops) {
|
||||
pr_err("Error: Thermal zone device ops not defined\n");
|
||||
pr_err("Thermal zone device ops not defined\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
|
||||
if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
tz = kzalloc(sizeof(*tz), GFP_KERNEL);
|
||||
@ -1228,7 +1232,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
|
||||
INIT_LIST_HEAD(&tz->thermal_instances);
|
||||
ida_init(&tz->ida);
|
||||
mutex_init(&tz->lock);
|
||||
id = ida_simple_get(&thermal_tz_ida, 0, 0, GFP_KERNEL);
|
||||
id = ida_alloc(&thermal_tz_ida, GFP_KERNEL);
|
||||
if (id < 0) {
|
||||
result = id;
|
||||
goto free_tz;
|
||||
@ -1249,6 +1253,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
|
||||
tz->device.class = &thermal_class;
|
||||
tz->devdata = devdata;
|
||||
tz->trips = trips;
|
||||
tz->num_trips = num_trips;
|
||||
|
||||
thermal_set_delay_jiffies(&tz->passive_delay_jiffies, passive_delay);
|
||||
thermal_set_delay_jiffies(&tz->polling_delay_jiffies, polling_delay);
|
||||
@ -1266,7 +1271,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
|
||||
if (result)
|
||||
goto release_device;
|
||||
|
||||
for (count = 0; count < trips; count++) {
|
||||
for (count = 0; count < num_trips; count++) {
|
||||
if (tz->ops->get_trip_type(tz, count, &trip_type) ||
|
||||
tz->ops->get_trip_temp(tz, count, &trip_temp) ||
|
||||
!trip_temp)
|
||||
@ -1319,11 +1324,21 @@ release_device:
|
||||
put_device(&tz->device);
|
||||
tz = NULL;
|
||||
remove_id:
|
||||
ida_simple_remove(&thermal_tz_ida, id);
|
||||
ida_free(&thermal_tz_ida, id);
|
||||
free_tz:
|
||||
kfree(tz);
|
||||
return ERR_PTR(result);
|
||||
}
|
||||
|
||||
struct thermal_zone_device *thermal_zone_device_register(const char *type, int ntrips, int mask,
|
||||
void *devdata, struct thermal_zone_device_ops *ops,
|
||||
struct thermal_zone_params *tzp, int passive_delay,
|
||||
int polling_delay)
|
||||
{
|
||||
return thermal_zone_device_register_with_trips(type, NULL, ntrips, mask,
|
||||
devdata, ops, tzp,
|
||||
passive_delay, polling_delay);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_device_register);
|
||||
|
||||
/**
|
||||
@ -1379,7 +1394,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
|
||||
thermal_set_governor(tz, NULL);
|
||||
|
||||
thermal_remove_hwmon_sysfs(tz);
|
||||
ida_simple_remove(&thermal_tz_ida, tz->id);
|
||||
ida_free(&thermal_tz_ida, tz->id);
|
||||
ida_destroy(&tz->ida);
|
||||
mutex_destroy(&tz->lock);
|
||||
device_unregister(&tz->device);
|
||||
|
@ -68,20 +68,6 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
|
||||
void thermal_cdev_update(struct thermal_cooling_device *);
|
||||
void __thermal_cdev_update(struct thermal_cooling_device *cdev);
|
||||
|
||||
/**
|
||||
* struct thermal_trip - representation of a point in temperature domain
|
||||
* @np: pointer to struct device_node that this trip point was created from
|
||||
* @temperature: temperature value in miliCelsius
|
||||
* @hysteresis: relative hysteresis in miliCelsius
|
||||
* @type: trip point type
|
||||
*/
|
||||
struct thermal_trip {
|
||||
struct device_node *np;
|
||||
int temperature;
|
||||
int hysteresis;
|
||||
enum thermal_trip_type type;
|
||||
};
|
||||
|
||||
int get_tz_trend(struct thermal_zone_device *tz, int trip);
|
||||
|
||||
struct thermal_instance *
|
||||
@ -126,7 +112,6 @@ int thermal_build_list_of_policies(char *buf);
|
||||
|
||||
/* Helpers */
|
||||
void thermal_zone_set_trips(struct thermal_zone_device *tz);
|
||||
void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms);
|
||||
|
||||
/* sysfs I/F */
|
||||
int thermal_zone_create_device_groups(struct thermal_zone_device *, int);
|
||||
|
@ -39,7 +39,6 @@ int get_tz_trend(struct thermal_zone_device *tz, int trip)
|
||||
|
||||
return trend;
|
||||
}
|
||||
EXPORT_SYMBOL(get_tz_trend);
|
||||
|
||||
struct thermal_instance *
|
||||
get_thermal_instance(struct thermal_zone_device *tz,
|
||||
@ -90,7 +89,7 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
ret = tz->ops->get_temp(tz, temp);
|
||||
|
||||
if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) {
|
||||
for (count = 0; count < tz->trips; count++) {
|
||||
for (count = 0; count < tz->num_trips; count++) {
|
||||
ret = tz->ops->get_trip_type(tz, count, &type);
|
||||
if (!ret && type == THERMAL_TRIP_CRITICAL) {
|
||||
ret = tz->ops->get_trip_temp(tz, count,
|
||||
@ -138,7 +137,7 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
|
||||
if (!tz->ops->set_trips || !tz->ops->get_trip_hyst)
|
||||
goto exit;
|
||||
|
||||
for (i = 0; i < tz->trips; i++) {
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
int trip_low;
|
||||
|
||||
tz->ops->get_trip_temp(tz, i, &trip_temp);
|
||||
@ -175,13 +174,6 @@ exit:
|
||||
mutex_unlock(&tz->lock);
|
||||
}
|
||||
|
||||
void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms)
|
||||
{
|
||||
*delay_jiffies = msecs_to_jiffies(delay_ms);
|
||||
if (delay_ms > 1000)
|
||||
*delay_jiffies = round_jiffies(*delay_jiffies);
|
||||
}
|
||||
|
||||
static void thermal_cdev_set_cur_state(struct thermal_cooling_device *cdev,
|
||||
int target)
|
||||
{
|
||||
@ -228,7 +220,6 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev)
|
||||
}
|
||||
mutex_unlock(&cdev->lock);
|
||||
}
|
||||
EXPORT_SYMBOL(thermal_cdev_update);
|
||||
|
||||
/**
|
||||
* thermal_zone_get_slope - return the slope attribute of the thermal zone
|
||||
|
@ -469,7 +469,7 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
for (i = 0; i < tz->trips; i++) {
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
|
||||
enum thermal_trip_type type;
|
||||
int temp, hyst = 0;
|
||||
|
@ -118,12 +118,7 @@ static int of_thermal_set_trips(struct thermal_zone_device *tz,
|
||||
*/
|
||||
int of_thermal_get_ntrips(struct thermal_zone_device *tz)
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
if (!data || IS_ERR(data))
|
||||
return -ENODEV;
|
||||
|
||||
return data->ntrips;
|
||||
return tz->num_trips;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_thermal_get_ntrips);
|
||||
|
||||
@ -139,9 +134,7 @@ EXPORT_SYMBOL_GPL(of_thermal_get_ntrips);
|
||||
*/
|
||||
bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip)
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
if (!data || trip >= data->ntrips || trip < 0)
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -161,12 +154,7 @@ EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid);
|
||||
const struct thermal_trip *
|
||||
of_thermal_get_trip_points(struct thermal_zone_device *tz)
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
return data->trips;
|
||||
return tz->trips;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_thermal_get_trip_points);
|
||||
|
||||
@ -281,12 +269,10 @@ static int of_thermal_unbind(struct thermal_zone_device *thermal,
|
||||
static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
|
||||
enum thermal_trip_type *type)
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
if (trip >= data->ntrips || trip < 0)
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return -EDOM;
|
||||
|
||||
*type = data->trips[trip].type;
|
||||
*type = tz->trips[trip].type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -294,12 +280,10 @@ static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
|
||||
static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip,
|
||||
int *temp)
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
if (trip >= data->ntrips || trip < 0)
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return -EDOM;
|
||||
|
||||
*temp = data->trips[trip].temperature;
|
||||
*temp = tz->trips[trip].temperature;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -309,7 +293,7 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
if (trip >= data->ntrips || trip < 0)
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return -EDOM;
|
||||
|
||||
if (data->ops && data->ops->set_trip_temp) {
|
||||
@ -321,7 +305,7 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
|
||||
}
|
||||
|
||||
/* thermal framework should take care of data->mask & (1 << trip) */
|
||||
data->trips[trip].temperature = temp;
|
||||
tz->trips[trip].temperature = temp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -329,12 +313,10 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
|
||||
static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip,
|
||||
int *hyst)
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
if (trip >= data->ntrips || trip < 0)
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return -EDOM;
|
||||
|
||||
*hyst = data->trips[trip].hysteresis;
|
||||
*hyst = tz->trips[trip].hysteresis;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -342,13 +324,11 @@ static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip,
|
||||
static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip,
|
||||
int hyst)
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
if (trip >= data->ntrips || trip < 0)
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return -EDOM;
|
||||
|
||||
/* thermal framework should take care of data->mask & (1 << trip) */
|
||||
data->trips[trip].hysteresis = hyst;
|
||||
tz->trips[trip].hysteresis = hyst;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -356,12 +336,11 @@ static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip,
|
||||
static int of_thermal_get_crit_temp(struct thermal_zone_device *tz,
|
||||
int *temp)
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < data->ntrips; i++)
|
||||
if (data->trips[i].type == THERMAL_TRIP_CRITICAL) {
|
||||
*temp = data->trips[i].temperature;
|
||||
for (i = 0; i < tz->num_trips; i++)
|
||||
if (tz->trips[i].type == THERMAL_TRIP_CRITICAL) {
|
||||
*temp = tz->trips[i].temperature;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -671,6 +650,35 @@ EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister);
|
||||
|
||||
/*** functions parsing device tree nodes ***/
|
||||
|
||||
static int of_find_trip_id(struct device_node *np, struct device_node *trip)
|
||||
{
|
||||
struct device_node *trips;
|
||||
struct device_node *t;
|
||||
int i = 0;
|
||||
|
||||
trips = of_get_child_by_name(np, "trips");
|
||||
if (!trips) {
|
||||
pr_err("Failed to find 'trips' node\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the trip id point associated with the cooling device map
|
||||
*/
|
||||
for_each_child_of_node(trips, t) {
|
||||
|
||||
if (t == trip)
|
||||
goto out;
|
||||
i++;
|
||||
}
|
||||
|
||||
i = -ENXIO;
|
||||
out:
|
||||
of_node_put(trips);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* thermal_of_populate_bind_params - parse and fill cooling map data
|
||||
* @np: DT node containing a cooling-map node
|
||||
@ -685,15 +693,15 @@ EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister);
|
||||
*
|
||||
* Return: 0 on success, proper error code otherwise
|
||||
*/
|
||||
static int thermal_of_populate_bind_params(struct device_node *np,
|
||||
struct __thermal_bind_params *__tbp,
|
||||
struct thermal_trip *trips,
|
||||
int ntrips)
|
||||
static int thermal_of_populate_bind_params(struct device_node *tz_np,
|
||||
struct device_node *np,
|
||||
struct __thermal_bind_params *__tbp)
|
||||
{
|
||||
struct of_phandle_args cooling_spec;
|
||||
struct __thermal_cooling_bind_param *__tcbp;
|
||||
struct device_node *trip;
|
||||
int ret, i, count;
|
||||
int trip_id;
|
||||
u32 prop;
|
||||
|
||||
/* Default weight. Usage is optional */
|
||||
@ -708,18 +716,14 @@ static int thermal_of_populate_bind_params(struct device_node *np,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* match using device_node */
|
||||
for (i = 0; i < ntrips; i++)
|
||||
if (trip == trips[i].np) {
|
||||
__tbp->trip_id = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ntrips) {
|
||||
ret = -ENODEV;
|
||||
trip_id = of_find_trip_id(tz_np, trip);
|
||||
if (trip_id < 0) {
|
||||
ret = trip_id;
|
||||
goto end;
|
||||
}
|
||||
|
||||
__tbp->trip_id = trip_id;
|
||||
|
||||
count = of_count_phandle_with_args(np, "cooling-device",
|
||||
"#cooling-cells");
|
||||
if (count <= 0) {
|
||||
@ -843,13 +847,56 @@ static int thermal_of_populate_trip(struct device_node *np,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Required for cooling map matching */
|
||||
trip->np = np;
|
||||
of_node_get(np);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *ntrips)
|
||||
{
|
||||
struct thermal_trip *tt;
|
||||
struct device_node *trips, *trip;
|
||||
int ret, count;
|
||||
|
||||
trips = of_get_child_by_name(np, "trips");
|
||||
if (!trips) {
|
||||
pr_err("Failed to find 'trips' node\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
count = of_get_child_count(trips);
|
||||
if (!count) {
|
||||
pr_err("No trip point defined\n");
|
||||
ret = -EINVAL;
|
||||
goto out_of_node_put;
|
||||
}
|
||||
|
||||
tt = kzalloc(sizeof(*tt) * count, GFP_KERNEL);
|
||||
if (!tt) {
|
||||
ret = -ENOMEM;
|
||||
goto out_of_node_put;
|
||||
}
|
||||
|
||||
*ntrips = count;
|
||||
|
||||
count = 0;
|
||||
for_each_child_of_node(trips, trip) {
|
||||
ret = thermal_of_populate_trip(trip, &tt[count++]);
|
||||
if (ret)
|
||||
goto out_kfree;
|
||||
}
|
||||
|
||||
of_node_put(trips);
|
||||
|
||||
return tt;
|
||||
|
||||
out_kfree:
|
||||
kfree(tt);
|
||||
*ntrips = 0;
|
||||
out_of_node_put:
|
||||
of_node_put(trips);
|
||||
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* thermal_of_build_thermal_zone - parse and fill one thermal zone data
|
||||
* @np: DT node containing a thermal zone node
|
||||
@ -909,32 +956,12 @@ __init *thermal_of_build_thermal_zone(struct device_node *np)
|
||||
tz->offset = 0;
|
||||
}
|
||||
|
||||
/* trips */
|
||||
child = of_get_child_by_name(np, "trips");
|
||||
|
||||
/* No trips provided */
|
||||
if (!child)
|
||||
tz->trips = thermal_of_trips_init(np, &tz->ntrips);
|
||||
if (IS_ERR(tz->trips)) {
|
||||
ret = PTR_ERR(tz->trips);
|
||||
goto finish;
|
||||
|
||||
tz->ntrips = of_get_child_count(child);
|
||||
if (tz->ntrips == 0) /* must have at least one child */
|
||||
goto finish;
|
||||
|
||||
tz->trips = kcalloc(tz->ntrips, sizeof(*tz->trips), GFP_KERNEL);
|
||||
if (!tz->trips) {
|
||||
ret = -ENOMEM;
|
||||
goto free_tz;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for_each_child_of_node(child, gchild) {
|
||||
ret = thermal_of_populate_trip(gchild, &tz->trips[i++]);
|
||||
if (ret)
|
||||
goto free_trips;
|
||||
}
|
||||
|
||||
of_node_put(child);
|
||||
|
||||
/* cooling-maps */
|
||||
child = of_get_child_by_name(np, "cooling-maps");
|
||||
|
||||
@ -954,10 +981,11 @@ __init *thermal_of_build_thermal_zone(struct device_node *np)
|
||||
|
||||
i = 0;
|
||||
for_each_child_of_node(child, gchild) {
|
||||
ret = thermal_of_populate_bind_params(gchild, &tz->tbps[i++],
|
||||
tz->trips, tz->ntrips);
|
||||
if (ret)
|
||||
ret = thermal_of_populate_bind_params(np, gchild, &tz->tbps[i++]);
|
||||
if (ret) {
|
||||
of_node_put(gchild);
|
||||
goto free_tbps;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
@ -978,10 +1006,7 @@ free_tbps:
|
||||
|
||||
kfree(tz->tbps);
|
||||
free_trips:
|
||||
for (i = 0; i < tz->ntrips; i++)
|
||||
of_node_put(tz->trips[i].np);
|
||||
kfree(tz->trips);
|
||||
of_node_put(gchild);
|
||||
free_tz:
|
||||
kfree(tz);
|
||||
of_node_put(child);
|
||||
@ -1004,8 +1029,6 @@ static __init void of_thermal_free_zone(struct __thermal_zone *tz)
|
||||
}
|
||||
|
||||
kfree(tz->tbps);
|
||||
for (i = 0; i < tz->ntrips; i++)
|
||||
of_node_put(tz->trips[i].np);
|
||||
kfree(tz->trips);
|
||||
kfree(tz);
|
||||
}
|
||||
@ -1103,11 +1126,9 @@ int __init of_parse_thermal_zones(void)
|
||||
tzp->slope = tz->slope;
|
||||
tzp->offset = tz->offset;
|
||||
|
||||
zone = thermal_zone_device_register(child->name, tz->ntrips,
|
||||
mask, tz,
|
||||
ops, tzp,
|
||||
tz->passive_delay,
|
||||
tz->polling_delay);
|
||||
zone = thermal_zone_device_register_with_trips(child->name, tz->trips, tz->ntrips,
|
||||
mask, tz, ops, tzp, tz->passive_delay,
|
||||
tz->polling_delay);
|
||||
if (IS_ERR(zone)) {
|
||||
pr_err("Failed to build %pOFn zone %ld\n", child,
|
||||
PTR_ERR(zone));
|
||||
|
@ -416,15 +416,15 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
||||
int indx;
|
||||
|
||||
/* This function works only for zones with at least one trip */
|
||||
if (tz->trips <= 0)
|
||||
if (tz->num_trips <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
tz->trip_type_attrs = kcalloc(tz->trips, sizeof(*tz->trip_type_attrs),
|
||||
tz->trip_type_attrs = kcalloc(tz->num_trips, sizeof(*tz->trip_type_attrs),
|
||||
GFP_KERNEL);
|
||||
if (!tz->trip_type_attrs)
|
||||
return -ENOMEM;
|
||||
|
||||
tz->trip_temp_attrs = kcalloc(tz->trips, sizeof(*tz->trip_temp_attrs),
|
||||
tz->trip_temp_attrs = kcalloc(tz->num_trips, sizeof(*tz->trip_temp_attrs),
|
||||
GFP_KERNEL);
|
||||
if (!tz->trip_temp_attrs) {
|
||||
kfree(tz->trip_type_attrs);
|
||||
@ -432,7 +432,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
||||
}
|
||||
|
||||
if (tz->ops->get_trip_hyst) {
|
||||
tz->trip_hyst_attrs = kcalloc(tz->trips,
|
||||
tz->trip_hyst_attrs = kcalloc(tz->num_trips,
|
||||
sizeof(*tz->trip_hyst_attrs),
|
||||
GFP_KERNEL);
|
||||
if (!tz->trip_hyst_attrs) {
|
||||
@ -442,7 +442,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
||||
}
|
||||
}
|
||||
|
||||
attrs = kcalloc(tz->trips * 3 + 1, sizeof(*attrs), GFP_KERNEL);
|
||||
attrs = kcalloc(tz->num_trips * 3 + 1, sizeof(*attrs), GFP_KERNEL);
|
||||
if (!attrs) {
|
||||
kfree(tz->trip_type_attrs);
|
||||
kfree(tz->trip_temp_attrs);
|
||||
@ -451,7 +451,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (indx = 0; indx < tz->trips; indx++) {
|
||||
for (indx = 0; indx < tz->num_trips; indx++) {
|
||||
/* create trip type attribute */
|
||||
snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH,
|
||||
"trip_point_%d_type", indx);
|
||||
@ -478,7 +478,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
||||
tz->trip_temp_attrs[indx].attr.store =
|
||||
trip_point_temp_store;
|
||||
}
|
||||
attrs[indx + tz->trips] = &tz->trip_temp_attrs[indx].attr.attr;
|
||||
attrs[indx + tz->num_trips] = &tz->trip_temp_attrs[indx].attr.attr;
|
||||
|
||||
/* create Optional trip hyst attribute */
|
||||
if (!tz->ops->get_trip_hyst)
|
||||
@ -496,10 +496,10 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
||||
tz->trip_hyst_attrs[indx].attr.store =
|
||||
trip_point_hyst_store;
|
||||
}
|
||||
attrs[indx + tz->trips * 2] =
|
||||
attrs[indx + tz->num_trips * 2] =
|
||||
&tz->trip_hyst_attrs[indx].attr.attr;
|
||||
}
|
||||
attrs[tz->trips * 3] = NULL;
|
||||
attrs[tz->num_trips * 3] = NULL;
|
||||
|
||||
tz->trips_attribute_group.attrs = attrs;
|
||||
|
||||
@ -540,7 +540,7 @@ int thermal_zone_create_device_groups(struct thermal_zone_device *tz,
|
||||
for (i = 0; i < size - 2; i++)
|
||||
groups[i] = thermal_zone_attribute_groups[i];
|
||||
|
||||
if (tz->trips) {
|
||||
if (tz->num_trips) {
|
||||
result = create_trip_attrs(tz, mask);
|
||||
if (result) {
|
||||
kfree(groups);
|
||||
@ -561,7 +561,7 @@ void thermal_zone_destroy_device_groups(struct thermal_zone_device *tz)
|
||||
if (!tz)
|
||||
return;
|
||||
|
||||
if (tz->trips)
|
||||
if (tz->num_trips)
|
||||
destroy_trip_attrs(tz);
|
||||
|
||||
kfree(tz->device.groups);
|
||||
|
@ -226,7 +226,7 @@ static irqreturn_t ti_bandgap_talert_irq_handler(int irq, void *data)
|
||||
/*
|
||||
* One TALERT interrupt: Two sources
|
||||
* If the interrupt is due to t_hot then mask t_hot and
|
||||
* and unmask t_cold else mask t_cold and unmask t_hot
|
||||
* unmask t_cold else mask t_cold and unmask t_hot
|
||||
*/
|
||||
if (t_hot) {
|
||||
ctrl &= ~tsr->mask_hot_mask;
|
||||
|
@ -40,8 +40,6 @@ enum thermal_trend {
|
||||
THERMAL_TREND_STABLE, /* temperature is stable */
|
||||
THERMAL_TREND_RAISING, /* temperature is raising */
|
||||
THERMAL_TREND_DROPPING, /* temperature is dropping */
|
||||
THERMAL_TREND_RAISE_FULL, /* apply highest cooling action */
|
||||
THERMAL_TREND_DROP_FULL, /* apply lowest cooling action */
|
||||
};
|
||||
|
||||
/* Thermal notification reason */
|
||||
@ -80,6 +78,18 @@ struct thermal_zone_device_ops {
|
||||
void (*critical)(struct thermal_zone_device *);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct thermal_trip - representation of a point in temperature domain
|
||||
* @temperature: temperature value in miliCelsius
|
||||
* @hysteresis: relative hysteresis in miliCelsius
|
||||
* @type: trip point type
|
||||
*/
|
||||
struct thermal_trip {
|
||||
int temperature;
|
||||
int hysteresis;
|
||||
enum thermal_trip_type type;
|
||||
};
|
||||
|
||||
struct thermal_cooling_device_ops {
|
||||
int (*get_max_state) (struct thermal_cooling_device *, unsigned long *);
|
||||
int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *);
|
||||
@ -113,7 +123,8 @@ struct thermal_cooling_device {
|
||||
* @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
|
||||
* @mode: current mode of this thermal zone
|
||||
* @devdata: private pointer for device private data
|
||||
* @trips: number of trip points the thermal zone supports
|
||||
* @trips: an array of struct thermal_trip
|
||||
* @num_trips: number of trip points the thermal zone supports
|
||||
* @trips_disabled; bitmap for disabled trips
|
||||
* @passive_delay_jiffies: number of jiffies to wait between polls when
|
||||
* performing passive cooling.
|
||||
@ -153,7 +164,8 @@ struct thermal_zone_device {
|
||||
struct thermal_attr *trip_hyst_attrs;
|
||||
enum thermal_device_mode mode;
|
||||
void *devdata;
|
||||
int trips;
|
||||
struct thermal_trip *trips;
|
||||
int num_trips;
|
||||
unsigned long trips_disabled; /* bitmap for disabled trips */
|
||||
unsigned long passive_delay_jiffies;
|
||||
unsigned long polling_delay_jiffies;
|
||||
@ -366,8 +378,14 @@ void devm_thermal_zone_of_sensor_unregister(struct device *dev,
|
||||
struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
|
||||
void *, struct thermal_zone_device_ops *,
|
||||
struct thermal_zone_params *, int, int);
|
||||
|
||||
void thermal_zone_device_unregister(struct thermal_zone_device *);
|
||||
|
||||
struct thermal_zone_device *
|
||||
thermal_zone_device_register_with_trips(const char *, struct thermal_trip *, int, int,
|
||||
void *, struct thermal_zone_device_ops *,
|
||||
struct thermal_zone_params *, int, int);
|
||||
|
||||
int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
|
||||
struct thermal_cooling_device *,
|
||||
unsigned long, unsigned long,
|
||||
|
@ -92,34 +92,22 @@ TRACE_EVENT(thermal_zone_trip,
|
||||
);
|
||||
|
||||
#ifdef CONFIG_CPU_THERMAL
|
||||
TRACE_EVENT(thermal_power_cpu_get_power,
|
||||
TP_PROTO(const struct cpumask *cpus, unsigned long freq, u32 *load,
|
||||
size_t load_len, u32 dynamic_power),
|
||||
TRACE_EVENT(thermal_power_cpu_get_power_simple,
|
||||
TP_PROTO(int cpu, u32 power),
|
||||
|
||||
TP_ARGS(cpus, freq, load, load_len, dynamic_power),
|
||||
TP_ARGS(cpu, power),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__bitmask(cpumask, num_possible_cpus())
|
||||
__field(unsigned long, freq )
|
||||
__dynamic_array(u32, load, load_len)
|
||||
__field(size_t, load_len )
|
||||
__field(u32, dynamic_power )
|
||||
__field(int, cpu)
|
||||
__field(u32, power)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_bitmask(cpumask, cpumask_bits(cpus),
|
||||
num_possible_cpus());
|
||||
__entry->freq = freq;
|
||||
memcpy(__get_dynamic_array(load), load,
|
||||
load_len * sizeof(*load));
|
||||
__entry->load_len = load_len;
|
||||
__entry->dynamic_power = dynamic_power;
|
||||
__entry->cpu = cpu;
|
||||
__entry->power = power;
|
||||
),
|
||||
|
||||
TP_printk("cpus=%s freq=%lu load={%s} dynamic_power=%d",
|
||||
__get_bitmask(cpumask), __entry->freq,
|
||||
__print_array(__get_dynamic_array(load), __entry->load_len, 4),
|
||||
__entry->dynamic_power)
|
||||
TP_printk("cpu=%d power=%u", __entry->cpu, __entry->power)
|
||||
);
|
||||
|
||||
TRACE_EVENT(thermal_power_cpu_limit,
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
/**************************************************************************
|
||||
* PID (Proportional-Integral-Derivative) controller is commonly used in
|
||||
* linear control system, consider the the process.
|
||||
* linear control system, consider the process.
|
||||
* G(s) = U(s)/E(s)
|
||||
* kp = proportional gain
|
||||
* ki = integral gain
|
||||
|
@ -27,6 +27,9 @@
|
||||
#define NR_LINES_TZDATA 1
|
||||
#define TMON_LOG_FILE "/var/tmp/tmon.log"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
extern unsigned long ticktime;
|
||||
extern double time_elapsed;
|
||||
extern unsigned long target_temp_user;
|
||||
|
Loading…
Reference in New Issue
Block a user