mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
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:
@@ -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.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user