mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
Thermal control updates for 7.1-rc1
- Fix thermal core issues related to thermal zone removal and
registration errors that may lead to a use-after-free or a memory
leak in some cases (Rafael Wysocki)
- Drop a redundant check from thermal_zone_device_update(), adjust
thermal workqueue allocation flags, and switch over thermal_class
allocation to static (Rafael Wysocki)
- Relocate the suspend and resume of thermal zones closer to the
suspend and resume of devices, respectively (Rafael Wysocki)
- Remove a pointless variable used in the thermal core when
registering a cooling device (Daniel Lezcano)
- Replace sprintf() in thermal_bind_cdev_to_trip() and use
str_enabled_disabled() helper in mode_show() (Thorsten Blum)
- Replace cpumask_weight() in intel_hfi_offline() with cpumask_empty()
which is generally more efficient (Yury Norov)
- Add support for reading DDR data rate from PCI config space on Nova
Lake platforms to the int340x thermal driver (Srinivas Pandruvada)
- Add an OF node address to output message to make sensor names more
distinguishable (Alexander Stein)
- Add hwmon support for the i.MX97 thermal sensor (Alexander Stein)
- Clamp correctly the results when doing value/temperature conversion
in the Spreadtrum driver (Thorsten Blum)
- Add SDM670 compatible DT bindings for the Tsens and the lMH thermal
drivers (Richard Acayan)
- Add SM8750 compatible DT bindings for the Tsens thermal driver (Manaf
Meethalavalappu Pallikunhi)
- Add Eliza SoC compatible DT bindings for the Tsens driver (Krzysztof
Kozlowski)
- Fix inverted condition check on error in the Spear thermal control
driver (Gopi Krishna Menon)
- Convert DT bindings documentation into DT schema (Gopi Krishna Menon)
- Use max() macro to increase readability in the Broadcom STB thermal
sensor (Thorsten Blum)
- Remove a stale @trim_offset kernel-doc entry (John Madieu)
-----BEGIN PGP SIGNATURE-----
iQFGBAABCAAwFiEEcM8Aw/RY0dgsiRUR7l+9nS/U47UFAmnZBFwSHHJqd0Byand5
c29ja2kubmV0AAoJEO5fvZ0v1OO1CIAH/jT/z4QMvfBCIlTgwTN6ArqmbEPBoufI
yhwyH/9gYEoJ5qvBBYWRu+NbiKIcQGdQ4bIVMbrYREqUAqZtD0ICTyysWKyxN0xC
2Y+a1uyx5Q73Ac4s2+GNhNIykpFLeODSkHX4wHmA8DSjCdSLvqtfewK09XxoFKiP
Gdb1mhihdEQREC2nfqOpWtxeRp90AK3Ak1Obvf4+95i2KYrQgrmaxXIGFH1Q7IQu
4Va4/7ZEdFPmBTS3vpI3wNjFb5SDHtaP8/FUc/vVohs7if4mGT2JI94oE5ic/+bc
RpCHvii51hHIs0VUJAqkzJwNIH1/3F3UDbiJtkV0sW9tYj02I8dLYPM=
=m1xx
-----END PGP SIGNATURE-----
Merge tag 'thermal-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull thermal control updates from Rafael Wysocki:
"These include thermal core fixes and simplifications, driver fixes and
new hardware support (SDM670, Eliza SoC), new driver features (hwmon
support in imx91, DDR data rate on Nova Lake in int340x), and a
handful of cleanups:
- Fix thermal core issues related to thermal zone removal and
registration errors that may lead to a use-after-free or a memory
leak in some cases (Rafael Wysocki)
- Drop a redundant check from thermal_zone_device_update(), adjust
thermal workqueue allocation flags, and switch over thermal_class
allocation to static (Rafael Wysocki)
- Relocate the suspend and resume of thermal zones closer to the
suspend and resume of devices, respectively (Rafael Wysocki)
- Remove a pointless variable used in the thermal core when
registering a cooling device (Daniel Lezcano)
- Replace sprintf() in thermal_bind_cdev_to_trip() and use
str_enabled_disabled() helper in mode_show() (Thorsten Blum)
- Replace cpumask_weight() in intel_hfi_offline() with
cpumask_empty() which is generally more efficient (Yury Norov)
- Add support for reading DDR data rate from PCI config space on Nova
Lake platforms to the int340x thermal driver (Srinivas Pandruvada)
- Add an OF node address to output message to make sensor names more
distinguishable (Alexander Stein)
- Add hwmon support for the i.MX97 thermal sensor (Alexander Stein)
- Clamp correctly the results when doing value/temperature conversion
in the Spreadtrum driver (Thorsten Blum)
- Add SDM670 compatible DT bindings for the Tsens and the lMH thermal
drivers (Richard Acayan)
- Add SM8750 compatible DT bindings for the Tsens thermal driver
(Manaf Meethalavalappu Pallikunhi)
- Add Eliza SoC compatible DT bindings for the Tsens driver
(Krzysztof Kozlowski)
- Fix inverted condition check on error in the Spear thermal control
driver (Gopi Krishna Menon)
- Convert DT bindings documentation into DT schema (Gopi Krishna
Menon)
- Use max() macro to increase readability in the Broadcom STB thermal
sensor (Thorsten Blum)
- Remove a stale @trim_offset kernel-doc entry (John Madieu)"
* tag 'thermal-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (25 commits)
thermal: renesas: rzg3e: Remove stale @trim_offset kernel-doc entry
thermal: core: Suspend thermal zones later and resume them earlier
thermal: core: Allocate thermal_class statically
thermal: core: Adjust thermal_wq allocation flags
thermal: core: Drop redundant check from thermal_zone_device_update()
thermal: core: Free thermal zone ID later during removal
thermal: core: Fix thermal zone governor cleanup issues
thermal/core: Remove pointless variable when registering a cooling device
thermal/drivers/brcmstb_thermal: Use max to simplify brcmstb_get_temp
dt-bindings: thermal: st,thermal-spear1340: convert to dtschema
thermal/drivers/spear: Fix error condition for reading st,thermal-flags
dt-bindings: thermal: qcom-tsens: Add Eliza SoC TSENS
thermal: devfreq_cooling: avoid unnecessary kfree of freq_table
thermal: intel: hfi: use cpumask_empty() in intel_hfi_offline()
thermal: sysfs: Use str_enabled_disabled() helper in mode_show()
dt-bindings: thermal: qcom-tsens: Document the SM8750 Temperature Sensor
thermal/drivers/sprd: Use min instead of clamp in sprd_thm_temp_to_rawdata
dt-bindings: thermal: lmh: Add SDM670 compatible
dt-bindings: thermal: tsens: add SDM670 compatible
thermal/drivers/sprd: Fix raw temperature clamping in sprd_thm_rawdata_to_temp
...
This commit is contained in:
commit
fbfb6bd927
|
|
@ -22,6 +22,9 @@ properties:
|
|||
- qcom,sc8180x-lmh
|
||||
- qcom,sdm845-lmh
|
||||
- qcom,sm8150-lmh
|
||||
- items:
|
||||
- const: qcom,sdm670-lmh
|
||||
- const: qcom,sdm845-lmh
|
||||
- items:
|
||||
- const: qcom,qcm2290-lmh
|
||||
- const: qcom,sm8150-lmh
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ properties:
|
|||
- description: v2 of TSENS
|
||||
items:
|
||||
- enum:
|
||||
- qcom,eliza-tsens
|
||||
- qcom,glymur-tsens
|
||||
- qcom,kaanapali-tsens
|
||||
- qcom,milos-tsens
|
||||
|
|
@ -71,6 +72,7 @@ properties:
|
|||
- qcom,sc8180x-tsens
|
||||
- qcom,sc8280xp-tsens
|
||||
- qcom,sdm630-tsens
|
||||
- qcom,sdm670-tsens
|
||||
- qcom,sdm845-tsens
|
||||
- qcom,sm6115-tsens
|
||||
- qcom,sm6350-tsens
|
||||
|
|
@ -81,6 +83,7 @@ properties:
|
|||
- qcom,sm8450-tsens
|
||||
- qcom,sm8550-tsens
|
||||
- qcom,sm8650-tsens
|
||||
- qcom,sm8750-tsens
|
||||
- qcom,x1e80100-tsens
|
||||
- const: qcom,tsens-v2
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
* SPEAr Thermal
|
||||
|
||||
Required properties:
|
||||
- compatible : "st,thermal-spear1340"
|
||||
- reg : Address range of the thermal registers
|
||||
- st,thermal-flags: flags used to enable thermal sensor
|
||||
|
||||
Example:
|
||||
|
||||
thermal@fc000000 {
|
||||
compatible = "st,thermal-spear1340";
|
||||
reg = <0xfc000000 0x1000>;
|
||||
st,thermal-flags = <0x7000>;
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/thermal/st,thermal-spear1340.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: SPEAr Thermal Sensor
|
||||
|
||||
maintainers:
|
||||
- Viresh Kumar <vireshk@kernel.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,thermal-spear1340
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
st,thermal-flags:
|
||||
description: flags used to enable thermal sensor
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- st,thermal-flags
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
thermal@fc000000 {
|
||||
compatible = "st,thermal-spear1340";
|
||||
reg = <0xfc000000 0x1000>;
|
||||
st,thermal-flags = <0x7000>;
|
||||
};
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
#include <trace/events/power.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/devfreq.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/nmi.h>
|
||||
|
||||
|
|
@ -1282,6 +1283,8 @@ void dpm_complete(pm_message_t state)
|
|||
list_splice(&list, &dpm_list);
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
|
||||
/* Start resuming thermal control */
|
||||
thermal_pm_complete();
|
||||
/* Allow device probing and trigger re-probing of deferred devices */
|
||||
device_unblock_probing();
|
||||
trace_suspend_resume(TPS("dpm_complete"), state.event, false);
|
||||
|
|
@ -2225,6 +2228,8 @@ int dpm_prepare(pm_message_t state)
|
|||
* instead. The normal behavior will be restored in dpm_complete().
|
||||
*/
|
||||
device_block_probing();
|
||||
/* Suspend thermal control. */
|
||||
thermal_pm_prepare();
|
||||
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
while (!list_empty(&dpm_list) && !error) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/irqreturn.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
|
@ -154,7 +155,7 @@ static int brcmstb_get_temp(struct thermal_zone_device *tz, int *temp)
|
|||
{
|
||||
struct brcmstb_thermal_priv *priv = thermal_zone_device_priv(tz);
|
||||
u32 val;
|
||||
long t;
|
||||
int t;
|
||||
|
||||
val = __raw_readl(priv->tmon_base + AVS_TMON_STATUS);
|
||||
|
||||
|
|
@ -164,10 +165,7 @@ static int brcmstb_get_temp(struct thermal_zone_device *tz, int *temp)
|
|||
val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift;
|
||||
|
||||
t = avs_tmon_code_to_temp(priv, val);
|
||||
if (t < 0)
|
||||
*temp = 0;
|
||||
else
|
||||
*temp = t;
|
||||
*temp = max(0, t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -472,7 +472,8 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
|
|||
remove_qos_req:
|
||||
dev_pm_qos_remove_request(&dfc->req_max_freq);
|
||||
free_table:
|
||||
kfree(dfc->freq_table);
|
||||
if (!dfc->em_pd)
|
||||
kfree(dfc->freq_table);
|
||||
free_dfc:
|
||||
kfree(dfc);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
#include <linux/thermal.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include "thermal_hwmon.h"
|
||||
|
||||
#define REG_SET 0x4
|
||||
#define REG_CLR 0x8
|
||||
#define REG_TOG 0xc
|
||||
|
|
@ -318,6 +320,8 @@ static int imx91_tmu_probe(struct platform_device *pdev)
|
|||
return dev_err_probe(dev, PTR_ERR(tmu->tzd),
|
||||
"failed to register thermal zone sensor\n");
|
||||
|
||||
devm_thermal_add_hwmon_sysfs(dev, tmu->tzd);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
|
|
|||
|
|
@ -402,17 +402,31 @@ static ssize_t rfi_restriction_show(struct device *dev,
|
|||
return sysfs_emit(buf, "%llu\n", resp);
|
||||
}
|
||||
|
||||
/* ddr_data_rate */
|
||||
static const struct mmio_reg nvl_ddr_data_rate_reg = { 1, 0xE0, 10, 0x3FF, 2};
|
||||
|
||||
static const struct mmio_reg *ddr_data_rate_reg;
|
||||
|
||||
static ssize_t ddr_data_rate_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
u16 id = 0x0107;
|
||||
u64 resp;
|
||||
int ret;
|
||||
|
||||
ret = processor_thermal_send_mbox_read_cmd(to_pci_dev(dev), id, &resp);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ddr_data_rate_reg) {
|
||||
u16 reg_val;
|
||||
|
||||
pci_read_config_word(to_pci_dev(dev), ddr_data_rate_reg->offset, ®_val);
|
||||
resp = (reg_val >> ddr_data_rate_reg->shift) & ddr_data_rate_reg->mask;
|
||||
resp = (resp * 3333) / 100;
|
||||
} else {
|
||||
const u16 id = 0x0107;
|
||||
int ret;
|
||||
|
||||
ret = processor_thermal_send_mbox_read_cmd(to_pci_dev(dev), id, &resp);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return sysfs_emit(buf, "%llu\n", resp);
|
||||
}
|
||||
|
|
@ -461,6 +475,7 @@ int proc_thermal_rfim_add(struct pci_dev *pdev, struct proc_thermal_device *proc
|
|||
case PCI_DEVICE_ID_INTEL_NVL_H_THERMAL:
|
||||
case PCI_DEVICE_ID_INTEL_NVL_S_THERMAL:
|
||||
dlvr_mmio_regs_table = nvl_dlvr_mmio_regs;
|
||||
ddr_data_rate_reg = &nvl_ddr_data_rate_reg;
|
||||
break;
|
||||
default:
|
||||
dlvr_mmio_regs_table = dlvr_mmio_regs;
|
||||
|
|
|
|||
|
|
@ -526,7 +526,7 @@ void intel_hfi_offline(unsigned int cpu)
|
|||
mutex_lock(&hfi_instance_lock);
|
||||
cpumask_clear_cpu(cpu, hfi_instance->cpus);
|
||||
|
||||
if (!cpumask_weight(hfi_instance->cpus))
|
||||
if (cpumask_empty(hfi_instance->cpus))
|
||||
hfi_disable();
|
||||
|
||||
mutex_unlock(&hfi_instance_lock);
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@ struct rzg3e_thermal_info {
|
|||
* @info: chip type specific information
|
||||
* @trmval0: calibration value 0 (b)
|
||||
* @trmval1: calibration value 1 (c)
|
||||
* @trim_offset: offset for trim registers in syscon
|
||||
* @lock: protects hardware access during conversions
|
||||
*/
|
||||
struct rzg3e_thermal_priv {
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
|
|||
struct device_node *np = pdev->dev.of_node;
|
||||
int ret = 0, val;
|
||||
|
||||
if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
|
||||
if (!np || of_property_read_u32(np, "st,thermal-flags", &val)) {
|
||||
dev_err(&pdev->dev, "Failed: DT Pdata not passed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ static int sprd_thm_sensor_calibration(struct device_node *np,
|
|||
static int sprd_thm_rawdata_to_temp(struct sprd_thermal_sensor *sen,
|
||||
u32 rawdata)
|
||||
{
|
||||
clamp(rawdata, (u32)SPRD_THM_RAW_DATA_LOW, (u32)SPRD_THM_RAW_DATA_HIGH);
|
||||
rawdata = clamp(rawdata, SPRD_THM_RAW_DATA_LOW, SPRD_THM_RAW_DATA_HIGH);
|
||||
|
||||
/*
|
||||
* According to the thermal datasheet, the formula of converting
|
||||
|
|
@ -192,7 +192,7 @@ static int sprd_thm_temp_to_rawdata(int temp, struct sprd_thermal_sensor *sen)
|
|||
{
|
||||
u32 val;
|
||||
|
||||
clamp(temp, (int)SPRD_THM_TEMP_LOW, (int)SPRD_THM_TEMP_HIGH);
|
||||
temp = clamp(temp, SPRD_THM_TEMP_LOW, SPRD_THM_TEMP_HIGH);
|
||||
|
||||
/*
|
||||
* According to the thermal datasheet, the formula of converting
|
||||
|
|
@ -201,7 +201,7 @@ static int sprd_thm_temp_to_rawdata(int temp, struct sprd_thermal_sensor *sen)
|
|||
*/
|
||||
val = (temp + sen->cal_offset) / sen->cal_slope;
|
||||
|
||||
return clamp(val, val, (u32)(SPRD_THM_RAW_DATA_HIGH - 1));
|
||||
return min(val, SPRD_THM_RAW_DATA_HIGH - 1);
|
||||
}
|
||||
|
||||
static int sprd_thm_read_temp(struct thermal_zone_device *tz, int *temp)
|
||||
|
|
|
|||
|
|
@ -695,18 +695,12 @@ int thermal_zone_device_disable(struct thermal_zone_device *tz)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_device_disable);
|
||||
|
||||
static bool thermal_zone_is_present(struct thermal_zone_device *tz)
|
||||
{
|
||||
return !list_empty(&tz->node);
|
||||
}
|
||||
|
||||
void thermal_zone_device_update(struct thermal_zone_device *tz,
|
||||
enum thermal_notify_event event)
|
||||
{
|
||||
guard(thermal_zone)(tz);
|
||||
|
||||
if (thermal_zone_is_present(tz))
|
||||
__thermal_zone_device_update(tz, event);
|
||||
__thermal_zone_device_update(tz, event);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_device_update);
|
||||
|
||||
|
|
@ -863,7 +857,7 @@ static int thermal_bind_cdev_to_trip(struct thermal_zone_device *tz,
|
|||
goto free_mem;
|
||||
|
||||
dev->id = result;
|
||||
sprintf(dev->name, "cdev%d", dev->id);
|
||||
snprintf(dev->name, sizeof(dev->name), "cdev%d", dev->id);
|
||||
result =
|
||||
sysfs_create_link(&tz->device.kobj, &cdev->device.kobj, dev->name);
|
||||
if (result)
|
||||
|
|
@ -964,6 +958,8 @@ static void thermal_release(struct device *dev)
|
|||
sizeof("thermal_zone") - 1)) {
|
||||
tz = to_thermal_zone(dev);
|
||||
thermal_zone_destroy_device_groups(tz);
|
||||
thermal_set_governor(tz, NULL);
|
||||
ida_destroy(&tz->ida);
|
||||
mutex_destroy(&tz->lock);
|
||||
complete(&tz->removal);
|
||||
} else if (!strncmp(dev_name(dev), "cooling_device",
|
||||
|
|
@ -976,7 +972,11 @@ static void thermal_release(struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static struct class *thermal_class;
|
||||
static const struct class thermal_class = {
|
||||
.name = "thermal",
|
||||
.dev_release = thermal_release,
|
||||
};
|
||||
static bool thermal_class_unavailable __ro_after_init = true;
|
||||
|
||||
static inline
|
||||
void print_bind_err_msg(struct thermal_zone_device *tz,
|
||||
|
|
@ -1063,13 +1063,13 @@ __thermal_cooling_device_register(struct device_node *np,
|
|||
{
|
||||
struct thermal_cooling_device *cdev;
|
||||
unsigned long current_state;
|
||||
int id, ret;
|
||||
int ret;
|
||||
|
||||
if (!ops || !ops->get_max_state || !ops->get_cur_state ||
|
||||
!ops->set_cur_state)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (!thermal_class)
|
||||
if (thermal_class_unavailable)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
cdev = kzalloc_obj(*cdev);
|
||||
|
|
@ -1080,7 +1080,6 @@ __thermal_cooling_device_register(struct device_node *np,
|
|||
if (ret < 0)
|
||||
goto out_kfree_cdev;
|
||||
cdev->id = ret;
|
||||
id = ret;
|
||||
|
||||
cdev->type = kstrdup_const(type ? type : "", GFP_KERNEL);
|
||||
if (!cdev->type) {
|
||||
|
|
@ -1093,7 +1092,7 @@ __thermal_cooling_device_register(struct device_node *np,
|
|||
cdev->np = np;
|
||||
cdev->ops = ops;
|
||||
cdev->updated = false;
|
||||
cdev->device.class = thermal_class;
|
||||
cdev->device.class = &thermal_class;
|
||||
cdev->devdata = devdata;
|
||||
|
||||
ret = cdev->ops->get_max_state(cdev, &cdev->max_state);
|
||||
|
|
@ -1137,7 +1136,7 @@ __thermal_cooling_device_register(struct device_node *np,
|
|||
out_cdev_type:
|
||||
kfree_const(cdev->type);
|
||||
out_ida_remove:
|
||||
ida_free(&thermal_cdev_ida, id);
|
||||
ida_free(&thermal_cdev_ida, cdev->id);
|
||||
out_kfree_cdev:
|
||||
kfree(cdev);
|
||||
return ERR_PTR(ret);
|
||||
|
|
@ -1541,7 +1540,7 @@ thermal_zone_device_register_with_trips(const char *type,
|
|||
if (polling_delay && passive_delay > polling_delay)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (!thermal_class)
|
||||
if (thermal_class_unavailable)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
tz = kzalloc_flex(*tz, trips, num_trips);
|
||||
|
|
@ -1577,7 +1576,7 @@ thermal_zone_device_register_with_trips(const char *type,
|
|||
if (!tz->ops.critical)
|
||||
tz->ops.critical = thermal_zone_device_critical;
|
||||
|
||||
tz->device.class = thermal_class;
|
||||
tz->device.class = &thermal_class;
|
||||
tz->devdata = devdata;
|
||||
tz->num_trips = num_trips;
|
||||
for_each_trip_desc(tz, td) {
|
||||
|
|
@ -1611,8 +1610,10 @@ thermal_zone_device_register_with_trips(const char *type,
|
|||
/* sys I/F */
|
||||
/* Add nodes that are always present via .groups */
|
||||
result = thermal_zone_create_device_groups(tz);
|
||||
if (result)
|
||||
if (result) {
|
||||
thermal_set_governor(tz, NULL);
|
||||
goto remove_id;
|
||||
}
|
||||
|
||||
result = device_register(&tz->device);
|
||||
if (result)
|
||||
|
|
@ -1725,12 +1726,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
|
|||
|
||||
cancel_delayed_work_sync(&tz->poll_queue);
|
||||
|
||||
thermal_set_governor(tz, NULL);
|
||||
|
||||
thermal_thresholds_exit(tz);
|
||||
thermal_remove_hwmon_sysfs(tz);
|
||||
ida_free(&thermal_tz_ida, tz->id);
|
||||
ida_destroy(&tz->ida);
|
||||
|
||||
device_del(&tz->device);
|
||||
put_device(&tz->device);
|
||||
|
|
@ -1738,6 +1735,9 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
|
|||
thermal_notify_tz_delete(tz);
|
||||
|
||||
wait_for_completion(&tz->removal);
|
||||
|
||||
ida_free(&thermal_tz_ida, tz->id);
|
||||
|
||||
kfree(tz->tzp);
|
||||
kfree(tz);
|
||||
}
|
||||
|
|
@ -1823,7 +1823,7 @@ static void thermal_zone_pm_prepare(struct thermal_zone_device *tz)
|
|||
cancel_delayed_work(&tz->poll_queue);
|
||||
}
|
||||
|
||||
static void thermal_pm_notify_prepare(void)
|
||||
static void __thermal_pm_prepare(void)
|
||||
{
|
||||
struct thermal_zone_device *tz;
|
||||
|
||||
|
|
@ -1835,6 +1835,19 @@ static void thermal_pm_notify_prepare(void)
|
|||
thermal_zone_pm_prepare(tz);
|
||||
}
|
||||
|
||||
void thermal_pm_prepare(void)
|
||||
{
|
||||
if (thermal_class_unavailable)
|
||||
return;
|
||||
|
||||
__thermal_pm_prepare();
|
||||
/*
|
||||
* Allow any leftover thermal work items already on the worqueue to
|
||||
* complete so they don't get in the way later.
|
||||
*/
|
||||
flush_workqueue(thermal_wq);
|
||||
}
|
||||
|
||||
static void thermal_zone_pm_complete(struct thermal_zone_device *tz)
|
||||
{
|
||||
guard(thermal_zone)(tz);
|
||||
|
|
@ -1851,10 +1864,13 @@ static void thermal_zone_pm_complete(struct thermal_zone_device *tz)
|
|||
mod_delayed_work(thermal_wq, &tz->poll_queue, 0);
|
||||
}
|
||||
|
||||
static void thermal_pm_notify_complete(void)
|
||||
void thermal_pm_complete(void)
|
||||
{
|
||||
struct thermal_zone_device *tz;
|
||||
|
||||
if (thermal_class_unavailable)
|
||||
return;
|
||||
|
||||
guard(mutex)(&thermal_list_lock);
|
||||
|
||||
thermal_pm_suspended = false;
|
||||
|
|
@ -1863,41 +1879,6 @@ static void thermal_pm_notify_complete(void)
|
|||
thermal_zone_pm_complete(tz);
|
||||
}
|
||||
|
||||
static int thermal_pm_notify(struct notifier_block *nb,
|
||||
unsigned long mode, void *_unused)
|
||||
{
|
||||
switch (mode) {
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
case PM_RESTORE_PREPARE:
|
||||
case PM_SUSPEND_PREPARE:
|
||||
thermal_pm_notify_prepare();
|
||||
/*
|
||||
* Allow any leftover thermal work items already on the
|
||||
* worqueue to complete so they don't get in the way later.
|
||||
*/
|
||||
flush_workqueue(thermal_wq);
|
||||
break;
|
||||
case PM_POST_HIBERNATION:
|
||||
case PM_POST_RESTORE:
|
||||
case PM_POST_SUSPEND:
|
||||
thermal_pm_notify_complete();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block thermal_pm_nb = {
|
||||
.notifier_call = thermal_pm_notify,
|
||||
/*
|
||||
* Run at the lowest priority to avoid interference between the thermal
|
||||
* zone resume work items spawned by thermal_pm_notify() and the other
|
||||
* PM notifiers.
|
||||
*/
|
||||
.priority = INT_MIN,
|
||||
};
|
||||
|
||||
static int __init thermal_init(void)
|
||||
{
|
||||
int result;
|
||||
|
|
@ -1908,8 +1889,7 @@ static int __init thermal_init(void)
|
|||
if (result)
|
||||
goto error;
|
||||
|
||||
thermal_wq = alloc_workqueue("thermal_events",
|
||||
WQ_FREEZABLE | WQ_POWER_EFFICIENT | WQ_PERCPU, 0);
|
||||
thermal_wq = alloc_workqueue("thermal_events", WQ_POWER_EFFICIENT, 0);
|
||||
if (!thermal_wq) {
|
||||
result = -ENOMEM;
|
||||
goto unregister_netlink;
|
||||
|
|
@ -1919,26 +1899,11 @@ static int __init thermal_init(void)
|
|||
if (result)
|
||||
goto destroy_workqueue;
|
||||
|
||||
thermal_class = kzalloc_obj(*thermal_class);
|
||||
if (!thermal_class) {
|
||||
result = -ENOMEM;
|
||||
goto unregister_governors;
|
||||
}
|
||||
|
||||
thermal_class->name = "thermal";
|
||||
thermal_class->dev_release = thermal_release;
|
||||
|
||||
result = class_register(thermal_class);
|
||||
if (result) {
|
||||
kfree(thermal_class);
|
||||
thermal_class = NULL;
|
||||
goto unregister_governors;
|
||||
}
|
||||
|
||||
result = register_pm_notifier(&thermal_pm_nb);
|
||||
result = class_register(&thermal_class);
|
||||
if (result)
|
||||
pr_warn("Thermal: Can not register suspend notifier, return %d\n",
|
||||
result);
|
||||
goto unregister_governors;
|
||||
|
||||
thermal_class_unavailable = false;
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int
|
|||
count = of_count_phandle_with_args(child, "thermal-sensors",
|
||||
"#thermal-sensor-cells");
|
||||
if (count <= 0) {
|
||||
pr_err("%pOFn: missing thermal sensor\n", child);
|
||||
pr_err("%pOFP: missing thermal sensor\n", child);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
|
|
@ -156,14 +156,14 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int
|
|||
"#thermal-sensor-cells",
|
||||
i, &sensor_specs);
|
||||
if (ret < 0) {
|
||||
pr_err("%pOFn: Failed to read thermal-sensors cells: %d\n", child, ret);
|
||||
pr_err("%pOFP: Failed to read thermal-sensors cells: %d\n", child, ret);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
of_node_put(sensor_specs.np);
|
||||
if ((sensor == sensor_specs.np) && id == (sensor_specs.args_count ?
|
||||
sensor_specs.args[0] : 0)) {
|
||||
pr_debug("sensor %pOFn id=%d belongs to %pOFn\n", sensor, id, child);
|
||||
pr_debug("sensor %pOFP id=%d belongs to %pOFP\n", sensor, id, child);
|
||||
return no_free_ptr(child);
|
||||
}
|
||||
}
|
||||
|
|
@ -180,7 +180,7 @@ static int thermal_of_monitor_init(struct device_node *np, int *delay, int *pdel
|
|||
if (ret == -EINVAL) {
|
||||
*pdelay = 0;
|
||||
} else if (ret < 0) {
|
||||
pr_err("%pOFn: Couldn't get polling-delay-passive: %d\n", np, ret);
|
||||
pr_err("%pOFP: Couldn't get polling-delay-passive: %d\n", np, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +188,7 @@ static int thermal_of_monitor_init(struct device_node *np, int *delay, int *pdel
|
|||
if (ret == -EINVAL) {
|
||||
*delay = 0;
|
||||
} else if (ret < 0) {
|
||||
pr_err("%pOFn: Couldn't get polling-delay: %d\n", np, ret);
|
||||
pr_err("%pOFP: Couldn't get polling-delay: %d\n", np, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -380,23 +380,23 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *
|
|||
np = of_thermal_zone_find(sensor, id);
|
||||
if (IS_ERR(np)) {
|
||||
if (PTR_ERR(np) != -ENODEV)
|
||||
pr_err("Failed to find thermal zone for %pOFn id=%d\n", sensor, id);
|
||||
pr_err("Failed to find thermal zone for %pOFP id=%d\n", sensor, id);
|
||||
return ERR_CAST(np);
|
||||
}
|
||||
|
||||
trips = thermal_of_trips_init(np, &ntrips);
|
||||
if (IS_ERR(trips)) {
|
||||
pr_err("Failed to parse trip points for %pOFn id=%d\n", sensor, id);
|
||||
pr_err("Failed to parse trip points for %pOFP id=%d\n", sensor, id);
|
||||
ret = PTR_ERR(trips);
|
||||
goto out_of_node_put;
|
||||
}
|
||||
|
||||
if (!trips)
|
||||
pr_info("No trip points found for %pOFn id=%d\n", sensor, id);
|
||||
pr_info("No trip points found for %pOFP id=%d\n", sensor, id);
|
||||
|
||||
ret = thermal_of_monitor_init(np, &delay, &pdelay);
|
||||
if (ret) {
|
||||
pr_err("Failed to initialize monitoring delays from %pOFn\n", np);
|
||||
pr_err("Failed to initialize monitoring delays from %pOFP\n", np);
|
||||
goto out_kfree_trips;
|
||||
}
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *
|
|||
pdelay, delay);
|
||||
if (IS_ERR(tz)) {
|
||||
ret = PTR_ERR(tz);
|
||||
pr_err("Failed to register thermal zone %pOFn: %d\n", np, ret);
|
||||
pr_err("Failed to register thermal zone %pOFP: %d\n", np, ret);
|
||||
goto out_kfree_trips;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#include "thermal_core.h"
|
||||
|
|
@ -56,10 +57,8 @@ mode_show(struct device *dev, struct device_attribute *attr, char *buf)
|
|||
|
||||
guard(thermal_zone)(tz);
|
||||
|
||||
if (tz->mode == THERMAL_DEVICE_ENABLED)
|
||||
return sysfs_emit(buf, "enabled\n");
|
||||
|
||||
return sysfs_emit(buf, "disabled\n");
|
||||
return sysfs_emit(buf, "%s\n",
|
||||
str_enabled_disabled(tz->mode == THERMAL_DEVICE_ENABLED));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
|
|
|
|||
|
|
@ -273,6 +273,9 @@ bool thermal_trip_is_bound_to_cdev(struct thermal_zone_device *tz,
|
|||
int thermal_zone_device_enable(struct thermal_zone_device *tz);
|
||||
int thermal_zone_device_disable(struct thermal_zone_device *tz);
|
||||
void thermal_zone_device_critical(struct thermal_zone_device *tz);
|
||||
|
||||
void thermal_pm_prepare(void);
|
||||
void thermal_pm_complete(void);
|
||||
#else
|
||||
static inline struct thermal_zone_device *thermal_zone_device_register_with_trips(
|
||||
const char *type,
|
||||
|
|
@ -350,6 +353,9 @@ static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)
|
|||
|
||||
static inline int thermal_zone_device_disable(struct thermal_zone_device *tz)
|
||||
{ return -ENODEV; }
|
||||
|
||||
static inline void thermal_pm_prepare(void) {}
|
||||
static inline void thermal_pm_complete(void) {}
|
||||
#endif /* CONFIG_THERMAL */
|
||||
|
||||
#endif /* __THERMAL_H__ */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user