You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management updates from Zhang Rui: - Introduce generic ADC thermal driver, based on OF thermal (Laxman Dewangan) - Introduce new thermal driver for Tango chips (Marc Gonzalez) - Rockchip driver support for RK3399, RK3366, and some fixes (Caesar Wang, Elaine Zhang and Shawn Lin) - Add CPU power cooling model to Mediatek thermal driver (Dawei Chien) - Wider usage of dev_thermal_zone_of_sensor_register (Eduardo Valentin) - TI thermal driver gained a new maintainer (Keerthy). - Enabled powerclamp driver by checking CPU feature and package cstate counter instead of CPU whitelist (Jacob Pan) - Various fixes on thermal governor, OF thermal, Tegra, and RCAR * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: (50 commits) thermal: tango: initialize TEMPSI_CFG thermal: rockchip: use the usleep_range instead of udelay thermal: rockchip: add the notes for better reading thermal: rockchip: Support RK3366 SoCs in the thermal driver thermal: rockchip: handle the power sequence for tsadc controller thermal: rockchip: update the tsadc table for rk3399 thermal: rockchip: fixes the code_to_temp for tsadc driver thermal: rockchip: disable thermal->clk in err case thermal: tegra: add Tegra132 specific SOC_THERM driver thermal: fix ptr_ret.cocci warnings thermal: mediatek: Add cpu dynamic power cooling model. thermal: generic-adc: Add ADC based thermal sensor driver thermal: generic-adc: Add DT binding for ADC based thermal sensor thermal: tegra: fix static checker warning thermal: tegra: mark PM functions __maybe_unused thermal: add temperature sensor support for tango SoC thermal: hisilicon: fix IRQ imbalance enabling thermal: hisilicon: support to use any sensor thermal: rcar: Remove binding docs for r8a7794 thermal: tegra: add PM support ...
This commit is contained in:
@@ -26,6 +26,10 @@ Required properties :
|
|||||||
of this property. See <dt-bindings/thermal/tegra124-soctherm.h> for a
|
of this property. See <dt-bindings/thermal/tegra124-soctherm.h> for a
|
||||||
list of valid values when referring to thermal sensors.
|
list of valid values when referring to thermal sensors.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
- the "critical" type trip points will be set to SOC_THERM hardware as the
|
||||||
|
shut down temperature. Once the temperature of this thermal zone is higher
|
||||||
|
than it, the system will be shutdown or reset by hardware.
|
||||||
|
|
||||||
Example :
|
Example :
|
||||||
|
|
||||||
@@ -51,5 +55,13 @@ Example: referring to thermal sensors :
|
|||||||
|
|
||||||
thermal-sensors =
|
thermal-sensors =
|
||||||
<&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>;
|
<&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>;
|
||||||
|
|
||||||
|
trips {
|
||||||
|
cpu_shutdown_trip: shutdown-trip {
|
||||||
|
temperature = <102500>;
|
||||||
|
hysteresis = <1000>;
|
||||||
|
type = "critical";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ Required properties:
|
|||||||
- "renesas,thermal-r8a7791" (R-Car M2-W)
|
- "renesas,thermal-r8a7791" (R-Car M2-W)
|
||||||
- "renesas,thermal-r8a7792" (R-Car V2H)
|
- "renesas,thermal-r8a7792" (R-Car V2H)
|
||||||
- "renesas,thermal-r8a7793" (R-Car M2-N)
|
- "renesas,thermal-r8a7793" (R-Car M2-N)
|
||||||
- "renesas,thermal-r8a7794" (R-Car E2)
|
|
||||||
- reg : Address range of the thermal registers.
|
- reg : Address range of the thermal registers.
|
||||||
The 1st reg will be recognized as common register
|
The 1st reg will be recognized as common register
|
||||||
if it has "interrupts".
|
if it has "interrupts".
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
* Tango Thermal
|
||||||
|
|
||||||
|
The SMP8758 SoC includes 3 instances of this temperature sensor
|
||||||
|
(in the CPU, video decoder, and PCIe controller).
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- #thermal-sensor-cells: Should be 0 (see thermal.txt)
|
||||||
|
- compatible: "sigma,smp8758-thermal"
|
||||||
|
- reg: Address range of the thermal registers
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
cpu_temp: thermal@920100 {
|
||||||
|
#thermal-sensor-cells = <0>;
|
||||||
|
compatible = "sigma,smp8758-thermal";
|
||||||
|
reg = <0x920100 12>;
|
||||||
|
};
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
General Purpose Analog To Digital Converter (ADC) based thermal sensor.
|
||||||
|
|
||||||
|
On some of platforms, thermal sensor like thermistors are connected to
|
||||||
|
one of ADC channel and sensor resistance is read via voltage across the
|
||||||
|
sensor resistor. The voltage read across the sensor is mapped to
|
||||||
|
temperature using voltage-temperature lookup table.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
===================
|
||||||
|
- compatible: Must be "generic-adc-thermal".
|
||||||
|
- temperature-lookup-table: Two dimensional array of Integer; lookup table
|
||||||
|
to map the relation between ADC value and
|
||||||
|
temperature. When ADC is read, the value is
|
||||||
|
looked up on the table to get the equivalent
|
||||||
|
temperature.
|
||||||
|
The first value of the each row of array is the
|
||||||
|
temperature in milliCelsius and second value of
|
||||||
|
the each row of array is the ADC read value.
|
||||||
|
- #thermal-sensor-cells: Should be 1. See ./thermal.txt for a description
|
||||||
|
of this property.
|
||||||
|
|
||||||
|
Example :
|
||||||
|
#include <dt-bindings/thermal/thermal.h>
|
||||||
|
|
||||||
|
i2c@7000c400 {
|
||||||
|
ads1015: ads1015@4a {
|
||||||
|
reg = <0x4a>;
|
||||||
|
compatible = "ads1015";
|
||||||
|
sampling-frequency = <3300>;
|
||||||
|
#io-channel-cells = <1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
tboard_thermistor: thermal-sensor {
|
||||||
|
compatible = "generic-adc-thermal";
|
||||||
|
#thermal-sensor-cells = <0>;
|
||||||
|
io-channels = <&ads1015 1>;
|
||||||
|
io-channel-names = "sensor-channel";
|
||||||
|
temperature-lookup-table = < (-40000) 2578
|
||||||
|
(-39000) 2577
|
||||||
|
(-38000) 2576
|
||||||
|
(-37000) 2575
|
||||||
|
(-36000) 2574
|
||||||
|
(-35000) 2573
|
||||||
|
(-34000) 2572
|
||||||
|
(-33000) 2571
|
||||||
|
(-32000) 2569
|
||||||
|
(-31000) 2568
|
||||||
|
(-30000) 2567
|
||||||
|
::::::::::
|
||||||
|
118000 254
|
||||||
|
119000 247
|
||||||
|
120000 240
|
||||||
|
121000 233
|
||||||
|
122000 226
|
||||||
|
123000 220
|
||||||
|
124000 214
|
||||||
|
125000 208>;
|
||||||
|
};
|
||||||
|
|
||||||
|
dummy_cool_dev: dummy-cool-dev {
|
||||||
|
compatible = "dummy-cooling-dev";
|
||||||
|
#cooling-cells = <2>; /* min followed by max */
|
||||||
|
};
|
||||||
|
|
||||||
|
thermal-zones {
|
||||||
|
Tboard {
|
||||||
|
polling-delay = <15000>; /* milliseconds */
|
||||||
|
polling-delay-passive = <0>; /* milliseconds */
|
||||||
|
thermal-sensors = <&tboard_thermistor>;
|
||||||
|
|
||||||
|
trips {
|
||||||
|
therm_est_trip: therm_est_trip {
|
||||||
|
temperature = <40000>;
|
||||||
|
type = "active";
|
||||||
|
hysteresis = <1000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
cooling-maps {
|
||||||
|
map0 {
|
||||||
|
trip = <&therm_est_trip>;
|
||||||
|
cooling-device = <&dummy_cool_dev THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||||
|
contribution = <100>;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -69,8 +69,8 @@ temperature) and throttle appropriate devices.
|
|||||||
1.1.2 void thermal_zone_device_unregister(struct thermal_zone_device *tz)
|
1.1.2 void thermal_zone_device_unregister(struct thermal_zone_device *tz)
|
||||||
|
|
||||||
This interface function removes the thermal zone device.
|
This interface function removes the thermal zone device.
|
||||||
It deletes the corresponding entry form /sys/class/thermal folder and
|
It deletes the corresponding entry from /sys/class/thermal folder and
|
||||||
unbind all the thermal cooling devices it uses.
|
unbinds all the thermal cooling devices it uses.
|
||||||
|
|
||||||
1.1.3 struct thermal_zone_device *thermal_zone_of_sensor_register(
|
1.1.3 struct thermal_zone_device *thermal_zone_of_sensor_register(
|
||||||
struct device *dev, int sensor_id, void *data,
|
struct device *dev, int sensor_id, void *data,
|
||||||
@@ -146,32 +146,32 @@ temperature) and throttle appropriate devices.
|
|||||||
|
|
||||||
This interface function adds a new thermal cooling device (fan/processor/...)
|
This interface function adds a new thermal cooling device (fan/processor/...)
|
||||||
to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
|
to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
|
||||||
to all the thermal zone devices register at the same time.
|
to all the thermal zone devices registered at the same time.
|
||||||
name: the cooling device name.
|
name: the cooling device name.
|
||||||
devdata: device private data.
|
devdata: device private data.
|
||||||
ops: thermal cooling devices call-backs.
|
ops: thermal cooling devices call-backs.
|
||||||
.get_max_state: get the Maximum throttle state of the cooling device.
|
.get_max_state: get the Maximum throttle state of the cooling device.
|
||||||
.get_cur_state: get the Current throttle state of the cooling device.
|
.get_cur_state: get the Currently requested throttle state of the cooling device.
|
||||||
.set_cur_state: set the Current throttle state of the cooling device.
|
.set_cur_state: set the Current throttle state of the cooling device.
|
||||||
|
|
||||||
1.2.2 void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
|
1.2.2 void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
|
||||||
|
|
||||||
This interface function remove the thermal cooling device.
|
This interface function removes the thermal cooling device.
|
||||||
It deletes the corresponding entry form /sys/class/thermal folder and
|
It deletes the corresponding entry from /sys/class/thermal folder and
|
||||||
unbind itself from all the thermal zone devices using it.
|
unbinds itself from all the thermal zone devices using it.
|
||||||
|
|
||||||
1.3 interface for binding a thermal zone device with a thermal cooling device
|
1.3 interface for binding a thermal zone device with a thermal cooling device
|
||||||
1.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
1.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
||||||
int trip, struct thermal_cooling_device *cdev,
|
int trip, struct thermal_cooling_device *cdev,
|
||||||
unsigned long upper, unsigned long lower, unsigned int weight);
|
unsigned long upper, unsigned long lower, unsigned int weight);
|
||||||
|
|
||||||
This interface function bind a thermal cooling device to the certain trip
|
This interface function binds a thermal cooling device to a particular trip
|
||||||
point of a thermal zone device.
|
point of a thermal zone device.
|
||||||
This function is usually called in the thermal zone device .bind callback.
|
This function is usually called in the thermal zone device .bind callback.
|
||||||
tz: the thermal zone device
|
tz: the thermal zone device
|
||||||
cdev: thermal cooling device
|
cdev: thermal cooling device
|
||||||
trip: indicates which trip point the cooling devices is associated with
|
trip: indicates which trip point in this thermal zone the cooling device
|
||||||
in this thermal zone.
|
is associated with.
|
||||||
upper:the Maximum cooling state for this trip point.
|
upper:the Maximum cooling state for this trip point.
|
||||||
THERMAL_NO_LIMIT means no upper limit,
|
THERMAL_NO_LIMIT means no upper limit,
|
||||||
and the cooling device can be in max_state.
|
and the cooling device can be in max_state.
|
||||||
@@ -184,13 +184,13 @@ temperature) and throttle appropriate devices.
|
|||||||
1.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
|
1.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
|
||||||
int trip, struct thermal_cooling_device *cdev);
|
int trip, struct thermal_cooling_device *cdev);
|
||||||
|
|
||||||
This interface function unbind a thermal cooling device from the certain
|
This interface function unbinds a thermal cooling device from a particular
|
||||||
trip point of a thermal zone device. This function is usually called in
|
trip point of a thermal zone device. This function is usually called in
|
||||||
the thermal zone device .unbind callback.
|
the thermal zone device .unbind callback.
|
||||||
tz: the thermal zone device
|
tz: the thermal zone device
|
||||||
cdev: thermal cooling device
|
cdev: thermal cooling device
|
||||||
trip: indicates which trip point the cooling devices is associated with
|
trip: indicates which trip point in this thermal zone the cooling device
|
||||||
in this thermal zone.
|
is associated with.
|
||||||
|
|
||||||
1.4 Thermal Zone Parameters
|
1.4 Thermal Zone Parameters
|
||||||
1.4.1 struct thermal_bind_params
|
1.4.1 struct thermal_bind_params
|
||||||
@@ -210,13 +210,13 @@ temperature) and throttle appropriate devices.
|
|||||||
this thermal zone and cdev, for a particular trip point.
|
this thermal zone and cdev, for a particular trip point.
|
||||||
If nth bit is set, then the cdev and thermal zone are bound
|
If nth bit is set, then the cdev and thermal zone are bound
|
||||||
for trip point n.
|
for trip point n.
|
||||||
.limits: This is an array of cooling state limits. Must have exactly
|
.binding_limits: This is an array of cooling state limits. Must have
|
||||||
2 * thermal_zone.number_of_trip_points. It is an array consisting
|
exactly 2 * thermal_zone.number_of_trip_points. It is an
|
||||||
of tuples <lower-state upper-state> of state limits. Each trip
|
array consisting of tuples <lower-state upper-state> of
|
||||||
will be associated with one state limit tuple when binding.
|
state limits. Each trip will be associated with one state
|
||||||
A NULL pointer means <THERMAL_NO_LIMITS THERMAL_NO_LIMITS>
|
limit tuple when binding. A NULL pointer means
|
||||||
on all trips. These limits are used when binding a cdev to a
|
<THERMAL_NO_LIMITS THERMAL_NO_LIMITS> on all trips.
|
||||||
trip point.
|
These limits are used when binding a cdev to a trip point.
|
||||||
.match: This call back returns success(0) if the 'tz and cdev' need to
|
.match: This call back returns success(0) if the 'tz and cdev' need to
|
||||||
be bound, as per platform data.
|
be bound, as per platform data.
|
||||||
1.4.2 struct thermal_zone_params
|
1.4.2 struct thermal_zone_params
|
||||||
@@ -351,8 +351,8 @@ cdev[0-*]
|
|||||||
RO, Optional
|
RO, Optional
|
||||||
|
|
||||||
cdev[0-*]_trip_point
|
cdev[0-*]_trip_point
|
||||||
The trip point with which cdev[0-*] is associated in this thermal
|
The trip point in this thermal zone which cdev[0-*] is associated
|
||||||
zone; -1 means the cooling device is not associated with any trip
|
with; -1 means the cooling device is not associated with any trip
|
||||||
point.
|
point.
|
||||||
RO, Optional
|
RO, Optional
|
||||||
|
|
||||||
|
|||||||
@@ -11296,6 +11296,7 @@ F: drivers/platform/x86/thinkpad_acpi.c
|
|||||||
|
|
||||||
TI BANDGAP AND THERMAL DRIVER
|
TI BANDGAP AND THERMAL DRIVER
|
||||||
M: Eduardo Valentin <edubezval@gmail.com>
|
M: Eduardo Valentin <edubezval@gmail.com>
|
||||||
|
M: Keerthy <j-keerthy@ti.com>
|
||||||
L: linux-pm@vger.kernel.org
|
L: linux-pm@vger.kernel.org
|
||||||
L: linux-omap@vger.kernel.org
|
L: linux-omap@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|||||||
@@ -307,17 +307,24 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DYNAMIC_POWER "dynamic-power-coefficient"
|
||||||
|
|
||||||
static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
|
static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
|
||||||
{
|
{
|
||||||
struct mtk_cpu_dvfs_info *info = policy->driver_data;
|
struct mtk_cpu_dvfs_info *info = policy->driver_data;
|
||||||
struct device_node *np = of_node_get(info->cpu_dev->of_node);
|
struct device_node *np = of_node_get(info->cpu_dev->of_node);
|
||||||
|
u32 capacitance = 0;
|
||||||
|
|
||||||
if (WARN_ON(!np))
|
if (WARN_ON(!np))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (of_find_property(np, "#cooling-cells", NULL)) {
|
if (of_find_property(np, "#cooling-cells", NULL)) {
|
||||||
info->cdev = of_cpufreq_cooling_register(np,
|
of_property_read_u32(np, DYNAMIC_POWER, &capacitance);
|
||||||
policy->related_cpus);
|
|
||||||
|
info->cdev = of_cpufreq_power_cooling_register(np,
|
||||||
|
policy->related_cpus,
|
||||||
|
capacitance,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (IS_ERR(info->cdev)) {
|
if (IS_ERR(info->cdev)) {
|
||||||
dev_err(info->cpu_dev,
|
dev_err(info->cpu_dev,
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ static const u8 LM75_REG_TEMP[3] = {
|
|||||||
struct lm75_data {
|
struct lm75_data {
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct device *hwmon_dev;
|
struct device *hwmon_dev;
|
||||||
struct thermal_zone_device *tz;
|
|
||||||
struct mutex update_lock;
|
struct mutex update_lock;
|
||||||
u8 orig_conf;
|
u8 orig_conf;
|
||||||
u8 resolution; /* In bits, between 9 and 12 */
|
u8 resolution; /* In bits, between 9 and 12 */
|
||||||
@@ -306,11 +305,9 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||||||
if (IS_ERR(data->hwmon_dev))
|
if (IS_ERR(data->hwmon_dev))
|
||||||
return PTR_ERR(data->hwmon_dev);
|
return PTR_ERR(data->hwmon_dev);
|
||||||
|
|
||||||
data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, 0,
|
devm_thermal_zone_of_sensor_register(data->hwmon_dev, 0,
|
||||||
data->hwmon_dev,
|
data->hwmon_dev,
|
||||||
&lm75_of_thermal_ops);
|
&lm75_of_thermal_ops);
|
||||||
if (IS_ERR(data->tz))
|
|
||||||
data->tz = NULL;
|
|
||||||
|
|
||||||
dev_info(dev, "%s: sensor '%s'\n",
|
dev_info(dev, "%s: sensor '%s'\n",
|
||||||
dev_name(data->hwmon_dev), client->name);
|
dev_name(data->hwmon_dev), client->name);
|
||||||
@@ -322,7 +319,6 @@ static int lm75_remove(struct i2c_client *client)
|
|||||||
{
|
{
|
||||||
struct lm75_data *data = i2c_get_clientdata(client);
|
struct lm75_data *data = i2c_get_clientdata(client);
|
||||||
|
|
||||||
thermal_zone_of_sensor_unregister(data->hwmon_dev, data->tz);
|
|
||||||
hwmon_device_unregister(data->hwmon_dev);
|
hwmon_device_unregister(data->hwmon_dev);
|
||||||
lm75_write_value(client, LM75_REG_CONF, data->orig_conf);
|
lm75_write_value(client, LM75_REG_CONF, data->orig_conf);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -259,7 +259,6 @@ struct ntc_data {
|
|||||||
struct device *dev;
|
struct device *dev;
|
||||||
int n_comp;
|
int n_comp;
|
||||||
char name[PLATFORM_NAME_SIZE];
|
char name[PLATFORM_NAME_SIZE];
|
||||||
struct thermal_zone_device *tz;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_OF) && IS_ENABLED(CONFIG_IIO)
|
#if defined(CONFIG_OF) && IS_ENABLED(CONFIG_IIO)
|
||||||
@@ -579,6 +578,7 @@ static const struct thermal_zone_of_device_ops ntc_of_thermal_ops = {
|
|||||||
|
|
||||||
static int ntc_thermistor_probe(struct platform_device *pdev)
|
static int ntc_thermistor_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
struct thermal_zone_device *tz;
|
||||||
const struct of_device_id *of_id =
|
const struct of_device_id *of_id =
|
||||||
of_match_device(of_match_ptr(ntc_match), &pdev->dev);
|
of_match_device(of_match_ptr(ntc_match), &pdev->dev);
|
||||||
const struct platform_device_id *pdev_id;
|
const struct platform_device_id *pdev_id;
|
||||||
@@ -677,12 +677,10 @@ static int ntc_thermistor_probe(struct platform_device *pdev)
|
|||||||
dev_info(&pdev->dev, "Thermistor type: %s successfully probed.\n",
|
dev_info(&pdev->dev, "Thermistor type: %s successfully probed.\n",
|
||||||
pdev_id->name);
|
pdev_id->name);
|
||||||
|
|
||||||
data->tz = thermal_zone_of_sensor_register(data->dev, 0, data->dev,
|
tz = devm_thermal_zone_of_sensor_register(data->dev, 0, data->dev,
|
||||||
&ntc_of_thermal_ops);
|
&ntc_of_thermal_ops);
|
||||||
if (IS_ERR(data->tz)) {
|
if (IS_ERR(tz))
|
||||||
dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n");
|
dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n");
|
||||||
data->tz = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err_after_sysfs:
|
err_after_sysfs:
|
||||||
@@ -700,8 +698,6 @@ static int ntc_thermistor_remove(struct platform_device *pdev)
|
|||||||
sysfs_remove_group(&data->dev->kobj, &ntc_attr_group);
|
sysfs_remove_group(&data->dev->kobj, &ntc_attr_group);
|
||||||
ntc_iio_channel_release(pdata);
|
ntc_iio_channel_release(pdata);
|
||||||
|
|
||||||
thermal_zone_of_sensor_unregister(data->dev, data->tz);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,8 @@ struct sensor_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct scpi_thermal_zone {
|
struct scpi_thermal_zone {
|
||||||
struct list_head list;
|
|
||||||
int sensor_id;
|
int sensor_id;
|
||||||
struct scpi_sensors *scpi_sensors;
|
struct scpi_sensors *scpi_sensors;
|
||||||
struct thermal_zone_device *tzd;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct scpi_sensors {
|
struct scpi_sensors {
|
||||||
@@ -92,20 +90,6 @@ scpi_show_label(struct device *dev, struct device_attribute *attr, char *buf)
|
|||||||
return sprintf(buf, "%s\n", sensor->info.name);
|
return sprintf(buf, "%s\n", sensor->info.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
unregister_thermal_zones(struct platform_device *pdev,
|
|
||||||
struct scpi_sensors *scpi_sensors)
|
|
||||||
{
|
|
||||||
struct list_head *pos;
|
|
||||||
|
|
||||||
list_for_each(pos, &scpi_sensors->thermal_zones) {
|
|
||||||
struct scpi_thermal_zone *zone;
|
|
||||||
|
|
||||||
zone = list_entry(pos, struct scpi_thermal_zone, list);
|
|
||||||
thermal_zone_of_sensor_unregister(&pdev->dev, zone->tzd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct thermal_zone_of_device_ops scpi_sensor_ops = {
|
static struct thermal_zone_of_device_ops scpi_sensor_ops = {
|
||||||
.get_temp = scpi_read_temp,
|
.get_temp = scpi_read_temp,
|
||||||
};
|
};
|
||||||
@@ -118,7 +102,7 @@ static int scpi_hwmon_probe(struct platform_device *pdev)
|
|||||||
struct scpi_ops *scpi_ops;
|
struct scpi_ops *scpi_ops;
|
||||||
struct device *hwdev, *dev = &pdev->dev;
|
struct device *hwdev, *dev = &pdev->dev;
|
||||||
struct scpi_sensors *scpi_sensors;
|
struct scpi_sensors *scpi_sensors;
|
||||||
int ret, idx;
|
int idx, ret;
|
||||||
|
|
||||||
scpi_ops = get_scpi_ops();
|
scpi_ops = get_scpi_ops();
|
||||||
if (!scpi_ops)
|
if (!scpi_ops)
|
||||||
@@ -232,47 +216,34 @@ static int scpi_hwmon_probe(struct platform_device *pdev)
|
|||||||
INIT_LIST_HEAD(&scpi_sensors->thermal_zones);
|
INIT_LIST_HEAD(&scpi_sensors->thermal_zones);
|
||||||
for (i = 0; i < nr_sensors; i++) {
|
for (i = 0; i < nr_sensors; i++) {
|
||||||
struct sensor_data *sensor = &scpi_sensors->data[i];
|
struct sensor_data *sensor = &scpi_sensors->data[i];
|
||||||
|
struct thermal_zone_device *z;
|
||||||
struct scpi_thermal_zone *zone;
|
struct scpi_thermal_zone *zone;
|
||||||
|
|
||||||
if (sensor->info.class != TEMPERATURE)
|
if (sensor->info.class != TEMPERATURE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
zone = devm_kzalloc(dev, sizeof(*zone), GFP_KERNEL);
|
zone = devm_kzalloc(dev, sizeof(*zone), GFP_KERNEL);
|
||||||
if (!zone) {
|
if (!zone)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto unregister_tzd;
|
|
||||||
}
|
|
||||||
|
|
||||||
zone->sensor_id = i;
|
zone->sensor_id = i;
|
||||||
zone->scpi_sensors = scpi_sensors;
|
zone->scpi_sensors = scpi_sensors;
|
||||||
zone->tzd = thermal_zone_of_sensor_register(dev,
|
z = devm_thermal_zone_of_sensor_register(dev,
|
||||||
sensor->info.sensor_id, zone, &scpi_sensor_ops);
|
sensor->info.sensor_id,
|
||||||
|
zone,
|
||||||
|
&scpi_sensor_ops);
|
||||||
/*
|
/*
|
||||||
* The call to thermal_zone_of_sensor_register returns
|
* The call to thermal_zone_of_sensor_register returns
|
||||||
* an error for sensors that are not associated with
|
* an error for sensors that are not associated with
|
||||||
* any thermal zones or if the thermal subsystem is
|
* any thermal zones or if the thermal subsystem is
|
||||||
* not configured.
|
* not configured.
|
||||||
*/
|
*/
|
||||||
if (IS_ERR(zone->tzd)) {
|
if (IS_ERR(z)) {
|
||||||
devm_kfree(dev, zone);
|
devm_kfree(dev, zone);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
list_add(&zone->list, &scpi_sensors->thermal_zones);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
unregister_tzd:
|
|
||||||
unregister_thermal_zones(pdev, scpi_sensors);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int scpi_hwmon_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct scpi_sensors *scpi_sensors = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
unregister_thermal_zones(pdev, scpi_sensors);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +259,6 @@ static struct platform_driver scpi_hwmon_platdrv = {
|
|||||||
.of_match_table = scpi_of_match,
|
.of_match_table = scpi_of_match,
|
||||||
},
|
},
|
||||||
.probe = scpi_hwmon_probe,
|
.probe = scpi_hwmon_probe,
|
||||||
.remove = scpi_hwmon_remove,
|
|
||||||
};
|
};
|
||||||
module_platform_driver(scpi_hwmon_platdrv);
|
module_platform_driver(scpi_hwmon_platdrv);
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,6 @@
|
|||||||
struct tmp102 {
|
struct tmp102 {
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct device *hwmon_dev;
|
struct device *hwmon_dev;
|
||||||
struct thermal_zone_device *tz;
|
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
u16 config_orig;
|
u16 config_orig;
|
||||||
unsigned long last_update;
|
unsigned long last_update;
|
||||||
@@ -232,10 +231,8 @@ static int tmp102_probe(struct i2c_client *client,
|
|||||||
goto fail_restore_config;
|
goto fail_restore_config;
|
||||||
}
|
}
|
||||||
tmp102->hwmon_dev = hwmon_dev;
|
tmp102->hwmon_dev = hwmon_dev;
|
||||||
tmp102->tz = thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev,
|
devm_thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev,
|
||||||
&tmp102_of_thermal_ops);
|
&tmp102_of_thermal_ops);
|
||||||
if (IS_ERR(tmp102->tz))
|
|
||||||
tmp102->tz = NULL;
|
|
||||||
|
|
||||||
dev_info(dev, "initialized\n");
|
dev_info(dev, "initialized\n");
|
||||||
|
|
||||||
@@ -251,7 +248,6 @@ static int tmp102_remove(struct i2c_client *client)
|
|||||||
{
|
{
|
||||||
struct tmp102 *tmp102 = i2c_get_clientdata(client);
|
struct tmp102 *tmp102 = i2c_get_clientdata(client);
|
||||||
|
|
||||||
thermal_zone_of_sensor_unregister(tmp102->hwmon_dev, tmp102->tz);
|
|
||||||
hwmon_device_unregister(tmp102->hwmon_dev);
|
hwmon_device_unregister(tmp102->hwmon_dev);
|
||||||
|
|
||||||
/* Stop monitoring if device was stopped originally */
|
/* Stop monitoring if device was stopped originally */
|
||||||
|
|||||||
@@ -115,7 +115,6 @@
|
|||||||
struct sun4i_ts_data {
|
struct sun4i_ts_data {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
struct thermal_zone_device *tz;
|
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
bool ignore_fifo_data;
|
bool ignore_fifo_data;
|
||||||
@@ -366,10 +365,7 @@ static int sun4i_ts_probe(struct platform_device *pdev)
|
|||||||
if (IS_ERR(hwmon))
|
if (IS_ERR(hwmon))
|
||||||
return PTR_ERR(hwmon);
|
return PTR_ERR(hwmon);
|
||||||
|
|
||||||
ts->tz = thermal_zone_of_sensor_register(ts->dev, 0, ts,
|
devm_thermal_zone_of_sensor_register(ts->dev, 0, ts, &sun4i_ts_tz_ops);
|
||||||
&sun4i_ts_tz_ops);
|
|
||||||
if (IS_ERR(ts->tz))
|
|
||||||
ts->tz = NULL;
|
|
||||||
|
|
||||||
writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC);
|
writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC);
|
||||||
|
|
||||||
@@ -377,7 +373,6 @@ static int sun4i_ts_probe(struct platform_device *pdev)
|
|||||||
error = input_register_device(ts->input);
|
error = input_register_device(ts->input);
|
||||||
if (error) {
|
if (error) {
|
||||||
writel(0, ts->base + TP_INT_FIFOC);
|
writel(0, ts->base + TP_INT_FIFOC);
|
||||||
thermal_zone_of_sensor_unregister(ts->dev, ts->tz);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,8 +389,6 @@ static int sun4i_ts_remove(struct platform_device *pdev)
|
|||||||
if (ts->input)
|
if (ts->input)
|
||||||
input_unregister_device(ts->input);
|
input_unregister_device(ts->input);
|
||||||
|
|
||||||
thermal_zone_of_sensor_unregister(ts->dev, ts->tz);
|
|
||||||
|
|
||||||
/* Deactivate all IRQs */
|
/* Deactivate all IRQs */
|
||||||
writel(0, ts->base + TP_INT_FIFOC);
|
writel(0, ts->base + TP_INT_FIFOC);
|
||||||
|
|
||||||
|
|||||||
+21
-10
@@ -260,16 +260,6 @@ config ARMADA_THERMAL
|
|||||||
Enable this option if you want to have support for thermal management
|
Enable this option if you want to have support for thermal management
|
||||||
controller present in Armada 370 and Armada XP SoC.
|
controller present in Armada 370 and Armada XP SoC.
|
||||||
|
|
||||||
config TEGRA_SOCTHERM
|
|
||||||
tristate "Tegra SOCTHERM thermal management"
|
|
||||||
depends on ARCH_TEGRA
|
|
||||||
help
|
|
||||||
Enable this option for integrated thermal management support on NVIDIA
|
|
||||||
Tegra124 systems-on-chip. The driver supports four thermal zones
|
|
||||||
(CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal
|
|
||||||
zones to manage temperatures. This option is also required for the
|
|
||||||
emergency thermal reset (thermtrip) feature to function.
|
|
||||||
|
|
||||||
config DB8500_CPUFREQ_COOLING
|
config DB8500_CPUFREQ_COOLING
|
||||||
tristate "DB8500 cpufreq cooling"
|
tristate "DB8500 cpufreq cooling"
|
||||||
depends on ARCH_U8500 || COMPILE_TEST
|
depends on ARCH_U8500 || COMPILE_TEST
|
||||||
@@ -377,6 +367,17 @@ depends on ARCH_STI && OF
|
|||||||
source "drivers/thermal/st/Kconfig"
|
source "drivers/thermal/st/Kconfig"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
config TANGO_THERMAL
|
||||||
|
tristate "Tango thermal management"
|
||||||
|
depends on ARCH_TANGO || COMPILE_TEST
|
||||||
|
help
|
||||||
|
Enable the Tango thermal driver, which supports the primitive
|
||||||
|
temperature sensor embedded in Tango chips since the SMP8758.
|
||||||
|
This sensor only generates a 1-bit signal to indicate whether
|
||||||
|
the die temperature exceeds a programmable threshold.
|
||||||
|
|
||||||
|
source "drivers/thermal/tegra/Kconfig"
|
||||||
|
|
||||||
config QCOM_SPMI_TEMP_ALARM
|
config QCOM_SPMI_TEMP_ALARM
|
||||||
tristate "Qualcomm SPMI PMIC Temperature Alarm"
|
tristate "Qualcomm SPMI PMIC Temperature Alarm"
|
||||||
depends on OF && SPMI && IIO
|
depends on OF && SPMI && IIO
|
||||||
@@ -388,4 +389,14 @@ config QCOM_SPMI_TEMP_ALARM
|
|||||||
real time die temperature if an ADC is present or an estimate of the
|
real time die temperature if an ADC is present or an estimate of the
|
||||||
temperature based upon the over temperature stage value.
|
temperature based upon the over temperature stage value.
|
||||||
|
|
||||||
|
config GENERIC_ADC_THERMAL
|
||||||
|
tristate "Generic ADC based thermal sensor"
|
||||||
|
depends on IIO
|
||||||
|
help
|
||||||
|
This enabled a thermal sysfs driver for the temperature sensor
|
||||||
|
which is connected to the General Purpose ADC. The ADC channel
|
||||||
|
is read via IIO framework and the channel information is provided
|
||||||
|
to this driver. This driver reports the temperature by reading ADC
|
||||||
|
channel and converts it to temperature based on lookup table.
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ obj-y += samsung/
|
|||||||
obj-$(CONFIG_DOVE_THERMAL) += dove_thermal.o
|
obj-$(CONFIG_DOVE_THERMAL) += dove_thermal.o
|
||||||
obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
|
obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
|
||||||
obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
|
obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
|
||||||
|
obj-$(CONFIG_TANGO_THERMAL) += tango_thermal.o
|
||||||
obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
|
obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
|
||||||
obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
|
obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
|
||||||
obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
|
obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
|
||||||
@@ -46,6 +47,7 @@ obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/
|
|||||||
obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/
|
obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/
|
||||||
obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o
|
obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o
|
||||||
obj-$(CONFIG_ST_THERMAL) += st/
|
obj-$(CONFIG_ST_THERMAL) += st/
|
||||||
obj-$(CONFIG_TEGRA_SOCTHERM) += tegra_soctherm.o
|
obj-$(CONFIG_TEGRA_SOCTHERM) += tegra/
|
||||||
obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
|
obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
|
||||||
obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
|
obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
|
||||||
|
obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
|
||||||
|
|||||||
@@ -29,7 +29,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
|||||||
struct thermal_instance *instance;
|
struct thermal_instance *instance;
|
||||||
|
|
||||||
tz->ops->get_trip_temp(tz, trip, &trip_temp);
|
tz->ops->get_trip_temp(tz, trip, &trip_temp);
|
||||||
tz->ops->get_trip_hyst(tz, trip, &trip_hyst);
|
|
||||||
|
if (!tz->ops->get_trip_hyst) {
|
||||||
|
pr_warn_once("Undefined get_trip_hyst for thermal zone %s - "
|
||||||
|
"running with default hysteresis zero\n", tz->type);
|
||||||
|
trip_hyst = 0;
|
||||||
|
} else
|
||||||
|
tz->ops->get_trip_hyst(tz, trip, &trip_hyst);
|
||||||
|
|
||||||
dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d\n",
|
dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d\n",
|
||||||
trip, trip_temp, tz->temperature,
|
trip, trip_temp, tz->temperature,
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ static int hisi_thermal_get_temp(void *_sensor, int *temp)
|
|||||||
struct hisi_thermal_sensor *sensor = _sensor;
|
struct hisi_thermal_sensor *sensor = _sensor;
|
||||||
struct hisi_thermal_data *data = sensor->thermal;
|
struct hisi_thermal_data *data = sensor->thermal;
|
||||||
|
|
||||||
int sensor_id = 0, i;
|
int sensor_id = -1, i;
|
||||||
long max_temp = 0;
|
long max_temp = 0;
|
||||||
|
|
||||||
*temp = hisi_thermal_get_sensor_temp(data, sensor);
|
*temp = hisi_thermal_get_sensor_temp(data, sensor);
|
||||||
@@ -168,12 +168,19 @@ static int hisi_thermal_get_temp(void *_sensor, int *temp)
|
|||||||
sensor->sensor_temp = *temp;
|
sensor->sensor_temp = *temp;
|
||||||
|
|
||||||
for (i = 0; i < HISI_MAX_SENSORS; i++) {
|
for (i = 0; i < HISI_MAX_SENSORS; i++) {
|
||||||
|
if (!data->sensors[i].tzd)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (data->sensors[i].sensor_temp >= max_temp) {
|
if (data->sensors[i].sensor_temp >= max_temp) {
|
||||||
max_temp = data->sensors[i].sensor_temp;
|
max_temp = data->sensors[i].sensor_temp;
|
||||||
sensor_id = i;
|
sensor_id = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If no sensor has been enabled, then skip to enable irq */
|
||||||
|
if (sensor_id == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
mutex_lock(&data->thermal_lock);
|
mutex_lock(&data->thermal_lock);
|
||||||
data->irq_bind_sensor = sensor_id;
|
data->irq_bind_sensor = sensor_id;
|
||||||
mutex_unlock(&data->thermal_lock);
|
mutex_unlock(&data->thermal_lock);
|
||||||
@@ -226,8 +233,12 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev)
|
|||||||
sensor->thres_temp / 1000);
|
sensor->thres_temp / 1000);
|
||||||
mutex_unlock(&data->thermal_lock);
|
mutex_unlock(&data->thermal_lock);
|
||||||
|
|
||||||
for (i = 0; i < HISI_MAX_SENSORS; i++)
|
for (i = 0; i < HISI_MAX_SENSORS; i++) {
|
||||||
|
if (!data->sensors[i].tzd)
|
||||||
|
continue;
|
||||||
|
|
||||||
thermal_zone_device_update(data->sensors[i].tzd);
|
thermal_zone_device_update(data->sensors[i].tzd);
|
||||||
|
}
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
@@ -243,10 +254,11 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
|
|||||||
sensor->id = index;
|
sensor->id = index;
|
||||||
sensor->thermal = data;
|
sensor->thermal = data;
|
||||||
|
|
||||||
sensor->tzd = thermal_zone_of_sensor_register(&pdev->dev, sensor->id,
|
sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev,
|
||||||
sensor, &hisi_of_thermal_ops);
|
sensor->id, sensor, &hisi_of_thermal_ops);
|
||||||
if (IS_ERR(sensor->tzd)) {
|
if (IS_ERR(sensor->tzd)) {
|
||||||
ret = PTR_ERR(sensor->tzd);
|
ret = PTR_ERR(sensor->tzd);
|
||||||
|
sensor->tzd = NULL;
|
||||||
dev_err(&pdev->dev, "failed to register sensor id %d: %d\n",
|
dev_err(&pdev->dev, "failed to register sensor id %d: %d\n",
|
||||||
sensor->id, ret);
|
sensor->id, ret);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -331,28 +343,21 @@ static int hisi_thermal_probe(struct platform_device *pdev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hisi_thermal_enable_bind_irq_sensor(data);
|
||||||
|
irq_get_irqchip_state(data->irq, IRQCHIP_STATE_MASKED,
|
||||||
|
&data->irq_enabled);
|
||||||
|
|
||||||
for (i = 0; i < HISI_MAX_SENSORS; ++i) {
|
for (i = 0; i < HISI_MAX_SENSORS; ++i) {
|
||||||
ret = hisi_thermal_register_sensor(pdev, data,
|
ret = hisi_thermal_register_sensor(pdev, data,
|
||||||
&data->sensors[i], i);
|
&data->sensors[i], i);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"failed to register thermal sensor: %d\n", ret);
|
"failed to register thermal sensor: %d\n", ret);
|
||||||
goto err_get_sensor_data;
|
else
|
||||||
}
|
hisi_thermal_toggle_sensor(&data->sensors[i], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hisi_thermal_enable_bind_irq_sensor(data);
|
|
||||||
data->irq_enabled = true;
|
|
||||||
|
|
||||||
for (i = 0; i < HISI_MAX_SENSORS; i++)
|
|
||||||
hisi_thermal_toggle_sensor(&data->sensors[i], true);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_get_sensor_data:
|
|
||||||
clk_disable_unprepare(data->clk);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hisi_thermal_remove(struct platform_device *pdev)
|
static int hisi_thermal_remove(struct platform_device *pdev)
|
||||||
@@ -363,8 +368,10 @@ static int hisi_thermal_remove(struct platform_device *pdev)
|
|||||||
for (i = 0; i < HISI_MAX_SENSORS; i++) {
|
for (i = 0; i < HISI_MAX_SENSORS; i++) {
|
||||||
struct hisi_thermal_sensor *sensor = &data->sensors[i];
|
struct hisi_thermal_sensor *sensor = &data->sensors[i];
|
||||||
|
|
||||||
|
if (!sensor->tzd)
|
||||||
|
continue;
|
||||||
|
|
||||||
hisi_thermal_toggle_sensor(sensor, false);
|
hisi_thermal_toggle_sensor(sensor, false);
|
||||||
thermal_zone_of_sensor_unregister(&pdev->dev, sensor->tzd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hisi_thermal_disable_sensor(data);
|
hisi_thermal_disable_sensor(data);
|
||||||
|
|||||||
@@ -198,49 +198,33 @@ static struct thermal_zone_device_ops proc_thermal_local_ops = {
|
|||||||
.get_temp = proc_thermal_get_zone_temp,
|
.get_temp = proc_thermal_get_zone_temp,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int proc_thermal_add(struct device *dev,
|
static int proc_thermal_read_ppcc(struct proc_thermal_device *proc_priv)
|
||||||
struct proc_thermal_device **priv)
|
|
||||||
{
|
{
|
||||||
struct proc_thermal_device *proc_priv;
|
int i;
|
||||||
struct acpi_device *adev;
|
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
|
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||||
union acpi_object *elements, *ppcc;
|
union acpi_object *elements, *ppcc;
|
||||||
union acpi_object *p;
|
union acpi_object *p;
|
||||||
unsigned long long tmp;
|
int ret = 0;
|
||||||
struct thermal_zone_device_ops *ops = NULL;
|
|
||||||
int i;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
adev = ACPI_COMPANION(dev);
|
status = acpi_evaluate_object(proc_priv->adev->handle, "PPCC",
|
||||||
if (!adev)
|
NULL, &buf);
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
status = acpi_evaluate_object(adev->handle, "PPCC", NULL, &buf);
|
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
p = buf.pointer;
|
p = buf.pointer;
|
||||||
if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
|
if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
|
||||||
dev_err(dev, "Invalid PPCC data\n");
|
dev_err(proc_priv->dev, "Invalid PPCC data\n");
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto free_buffer;
|
goto free_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p->package.count) {
|
if (!p->package.count) {
|
||||||
dev_err(dev, "Invalid PPCC package size\n");
|
dev_err(proc_priv->dev, "Invalid PPCC package size\n");
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto free_buffer;
|
goto free_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc_priv = devm_kzalloc(dev, sizeof(*proc_priv), GFP_KERNEL);
|
|
||||||
if (!proc_priv) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto free_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
proc_priv->dev = dev;
|
|
||||||
proc_priv->adev = adev;
|
|
||||||
|
|
||||||
for (i = 0; i < min((int)p->package.count - 1, 2); ++i) {
|
for (i = 0; i < min((int)p->package.count - 1, 2); ++i) {
|
||||||
elements = &(p->package.elements[i+1]);
|
elements = &(p->package.elements[i+1]);
|
||||||
if (elements->type != ACPI_TYPE_PACKAGE ||
|
if (elements->type != ACPI_TYPE_PACKAGE ||
|
||||||
@@ -257,12 +241,62 @@ static int proc_thermal_add(struct device *dev,
|
|||||||
proc_priv->power_limits[i].step_uw = ppcc[5].integer.value;
|
proc_priv->power_limits[i].step_uw = ppcc[5].integer.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_buffer:
|
||||||
|
kfree(buf.pointer);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PROC_POWER_CAPABILITY_CHANGED 0x83
|
||||||
|
static void proc_thermal_notify(acpi_handle handle, u32 event, void *data)
|
||||||
|
{
|
||||||
|
struct proc_thermal_device *proc_priv = data;
|
||||||
|
|
||||||
|
if (!proc_priv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case PROC_POWER_CAPABILITY_CHANGED:
|
||||||
|
proc_thermal_read_ppcc(proc_priv);
|
||||||
|
int340x_thermal_zone_device_update(proc_priv->int340x_zone);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(proc_priv->dev, "Unsupported event [0x%x]\n", event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int proc_thermal_add(struct device *dev,
|
||||||
|
struct proc_thermal_device **priv)
|
||||||
|
{
|
||||||
|
struct proc_thermal_device *proc_priv;
|
||||||
|
struct acpi_device *adev;
|
||||||
|
acpi_status status;
|
||||||
|
unsigned long long tmp;
|
||||||
|
struct thermal_zone_device_ops *ops = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
adev = ACPI_COMPANION(dev);
|
||||||
|
if (!adev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
proc_priv = devm_kzalloc(dev, sizeof(*proc_priv), GFP_KERNEL);
|
||||||
|
if (!proc_priv)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
proc_priv->dev = dev;
|
||||||
|
proc_priv->adev = adev;
|
||||||
*priv = proc_priv;
|
*priv = proc_priv;
|
||||||
|
|
||||||
ret = sysfs_create_group(&dev->kobj,
|
ret = proc_thermal_read_ppcc(proc_priv);
|
||||||
&power_limit_attribute_group);
|
if (!ret) {
|
||||||
|
ret = sysfs_create_group(&dev->kobj,
|
||||||
|
&power_limit_attribute_group);
|
||||||
|
|
||||||
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
goto free_buffer;
|
return ret;
|
||||||
|
|
||||||
status = acpi_evaluate_integer(adev->handle, "_TMP", NULL, &tmp);
|
status = acpi_evaluate_integer(adev->handle, "_TMP", NULL, &tmp);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
@@ -274,20 +308,32 @@ static int proc_thermal_add(struct device *dev,
|
|||||||
|
|
||||||
proc_priv->int340x_zone = int340x_thermal_zone_add(adev, ops);
|
proc_priv->int340x_zone = int340x_thermal_zone_add(adev, ops);
|
||||||
if (IS_ERR(proc_priv->int340x_zone)) {
|
if (IS_ERR(proc_priv->int340x_zone)) {
|
||||||
sysfs_remove_group(&proc_priv->dev->kobj,
|
|
||||||
&power_limit_attribute_group);
|
|
||||||
ret = PTR_ERR(proc_priv->int340x_zone);
|
ret = PTR_ERR(proc_priv->int340x_zone);
|
||||||
|
goto remove_group;
|
||||||
} else
|
} else
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
free_buffer:
|
ret = acpi_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY,
|
||||||
kfree(buf.pointer);
|
proc_thermal_notify,
|
||||||
|
(void *)proc_priv);
|
||||||
|
if (ret)
|
||||||
|
goto remove_zone;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
remove_zone:
|
||||||
|
int340x_thermal_zone_remove(proc_priv->int340x_zone);
|
||||||
|
remove_group:
|
||||||
|
sysfs_remove_group(&proc_priv->dev->kobj,
|
||||||
|
&power_limit_attribute_group);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void proc_thermal_remove(struct proc_thermal_device *proc_priv)
|
static void proc_thermal_remove(struct proc_thermal_device *proc_priv)
|
||||||
{
|
{
|
||||||
|
acpi_remove_notify_handler(proc_priv->adev->handle,
|
||||||
|
ACPI_DEVICE_NOTIFY, proc_thermal_notify);
|
||||||
int340x_thermal_zone_remove(proc_priv->int340x_zone);
|
int340x_thermal_zone_remove(proc_priv->int340x_zone);
|
||||||
sysfs_remove_group(&proc_priv->dev->kobj,
|
sysfs_remove_group(&proc_priv->dev->kobj,
|
||||||
&power_limit_attribute_group);
|
&power_limit_attribute_group);
|
||||||
|
|||||||
@@ -510,12 +510,6 @@ static int start_power_clamp(void)
|
|||||||
unsigned long cpu;
|
unsigned long cpu;
|
||||||
struct task_struct *thread;
|
struct task_struct *thread;
|
||||||
|
|
||||||
/* check if pkg cstate counter is completely 0, abort in this case */
|
|
||||||
if (!has_pkg_state_counter()) {
|
|
||||||
pr_err("pkg cstate counter not functional, abort\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_target_ratio = clamp(set_target_ratio, 0U, MAX_TARGET_RATIO - 1);
|
set_target_ratio = clamp(set_target_ratio, 0U, MAX_TARGET_RATIO - 1);
|
||||||
/* prevent cpu hotplug */
|
/* prevent cpu hotplug */
|
||||||
get_online_cpus();
|
get_online_cpus();
|
||||||
@@ -672,35 +666,11 @@ static struct thermal_cooling_device_ops powerclamp_cooling_ops = {
|
|||||||
.set_cur_state = powerclamp_set_cur_state,
|
.set_cur_state = powerclamp_set_cur_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* runs on Nehalem and later */
|
|
||||||
static const struct x86_cpu_id intel_powerclamp_ids[] __initconst = {
|
static const struct x86_cpu_id intel_powerclamp_ids[] __initconst = {
|
||||||
{ X86_VENDOR_INTEL, 6, 0x1a},
|
{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_MWAIT },
|
||||||
{ X86_VENDOR_INTEL, 6, 0x1c},
|
{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ARAT },
|
||||||
{ X86_VENDOR_INTEL, 6, 0x1e},
|
{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_NONSTOP_TSC },
|
||||||
{ X86_VENDOR_INTEL, 6, 0x1f},
|
{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_CONSTANT_TSC},
|
||||||
{ X86_VENDOR_INTEL, 6, 0x25},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x26},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x2a},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x2c},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x2d},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x2e},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x2f},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x37},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x3a},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x3c},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x3d},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x3e},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x3f},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x45},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x46},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x47},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x4c},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x4d},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x4e},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x4f},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x56},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x57},
|
|
||||||
{ X86_VENDOR_INTEL, 6, 0x5e},
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);
|
MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);
|
||||||
@@ -712,11 +682,12 @@ static int __init powerclamp_probe(void)
|
|||||||
boot_cpu_data.x86, boot_cpu_data.x86_model);
|
boot_cpu_data.x86, boot_cpu_data.x86_model);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC) ||
|
|
||||||
!boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ||
|
/* The goal for idle time alignment is to achieve package cstate. */
|
||||||
!boot_cpu_has(X86_FEATURE_MWAIT) ||
|
if (!has_pkg_state_counter()) {
|
||||||
!boot_cpu_has(X86_FEATURE_ARAT))
|
pr_info("No package C-state available");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
/* find the deepest mwait value */
|
/* find the deepest mwait value */
|
||||||
find_target_mwait();
|
find_target_mwait();
|
||||||
|
|||||||
@@ -144,7 +144,6 @@ struct mtk_thermal {
|
|||||||
s32 o_slope;
|
s32 o_slope;
|
||||||
s32 vts[MT8173_NUM_SENSORS];
|
s32 vts[MT8173_NUM_SENSORS];
|
||||||
|
|
||||||
struct thermal_zone_device *tzd;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mtk_thermal_bank_cfg {
|
struct mtk_thermal_bank_cfg {
|
||||||
@@ -572,16 +571,11 @@ static int mtk_thermal_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
platform_set_drvdata(pdev, mt);
|
platform_set_drvdata(pdev, mt);
|
||||||
|
|
||||||
mt->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, mt,
|
devm_thermal_zone_of_sensor_register(&pdev->dev, 0, mt,
|
||||||
&mtk_thermal_ops);
|
&mtk_thermal_ops);
|
||||||
if (IS_ERR(mt->tzd))
|
|
||||||
goto err_register;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_register:
|
|
||||||
clk_disable_unprepare(mt->clk_peri_therm);
|
|
||||||
|
|
||||||
err_disable_clk_auxadc:
|
err_disable_clk_auxadc:
|
||||||
clk_disable_unprepare(mt->clk_auxadc);
|
clk_disable_unprepare(mt->clk_auxadc);
|
||||||
|
|
||||||
@@ -592,8 +586,6 @@ static int mtk_thermal_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct mtk_thermal *mt = platform_get_drvdata(pdev);
|
struct mtk_thermal *mt = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
thermal_zone_of_sensor_unregister(&pdev->dev, mt->tzd);
|
|
||||||
|
|
||||||
clk_disable_unprepare(mt->clk_peri_therm);
|
clk_disable_unprepare(mt->clk_peri_therm);
|
||||||
clk_disable_unprepare(mt->clk_auxadc);
|
clk_disable_unprepare(mt->clk_auxadc);
|
||||||
|
|
||||||
|
|||||||
@@ -331,6 +331,14 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
|
|||||||
if (trip >= data->ntrips || trip < 0)
|
if (trip >= data->ntrips || trip < 0)
|
||||||
return -EDOM;
|
return -EDOM;
|
||||||
|
|
||||||
|
if (data->ops->set_trip_temp) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = data->ops->set_trip_temp(data->sensor_data, trip, temp);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* thermal framework should take care of data->mask & (1 << trip) */
|
/* thermal framework should take care of data->mask & (1 << trip) */
|
||||||
data->trips[trip].temperature = temp;
|
data->trips[trip].temperature = temp;
|
||||||
|
|
||||||
@@ -906,7 +914,7 @@ finish:
|
|||||||
return tz;
|
return tz;
|
||||||
|
|
||||||
free_tbps:
|
free_tbps:
|
||||||
for (i = 0; i < tz->num_tbps; i++)
|
for (i = i - 1; i >= 0; i--)
|
||||||
of_node_put(tz->tbps[i].cooling_device);
|
of_node_put(tz->tbps[i].cooling_device);
|
||||||
kfree(tz->tbps);
|
kfree(tz->tbps);
|
||||||
free_trips:
|
free_trips:
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user