- Add DT bindings for SM6375, MSM8226 and QCM2290 Qcom platforms (Konrad

Dybcio)
 
 - Add DT bindings and support for QCom MSM8226 (Matti Lehtimäki)
 
 - Add DT bindings for QCom ipq9574 (Praveenkumar I)
 
 - Convert bcm2835 DT bindings to the yaml schema (Stefan Wahren)
 
 - Allow selecting the bang-bang governor as default (Thierry Reding)
 
 - Refactor and prepare the code to set the scene for RCar Gen4
   (Wolfram Sang)
 
 - Cleanup and fixes for the QCom tsens drivers. Add DT bindings and
   calibration for the MSM8909 platform (Stephan Gerhold)
 
 - Revert a patch introducing a wrong usage of devm_of_iomap() on the
   Mediatek platform (Ricardo Cañuelo)
 
 - Fix the clock vs reset ordering in order to conform to the
   documentation on the sun8i (Christophe JAILLET)
 
 - Prevent setting up undocumented registers, enable the only described
   sensors and add the version 2.1 on the Qoriq sensor (Peng Fan)
 
 - Add DT bindings and support for the Armada AP807 (Alex Leibovich)
 
 - Update the mlx5 driver with the recent thermal changes (Daniel
   Lezcano)
 
 - Convert to platform remove callback returning void on STM32 (Uwe
   Kleine-König)
 
 - Add an error information printing for devm_thermal_add_hwmon_sysfs()
   and remove the error from the Sun8i, Amlogic, i.MX, TI, K3, Tegra,
   Qoriq, Mediateka and QCom (Yangtao Li)
 
 - Register as hwmon sensor for the Generic ADC (Chen-Yu Tsai)
 
 - Use the dev_err_probe() function in the QCom tsens alarm driver
   (Luca Weiss)
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEEGn3N4YVz0WNVyHskqDIjiipP6E8FAmSZrHQACgkQqDIjiipP
 6E9yrAf+KD4AO8piKP8RoFAwM5TDHz7lQFsf9kcIHA4OjDG9HYG7nV9Y3zlVRb5S
 q4M/e69OCmQBWkntAuNwf3szl5ear7tutJjZb8pCKqQEp83gjyHnK3CrhGYTTFq4
 CWafhhsXhZX9a0twtPoXCO4xD1jxay1Viv0I4uWB8QcNuQbDHYJP9eQtGkppn4ql
 RRYZiYrlsjQ1uyylZ3fEbwcRGT6OGws5xSAhvya+MaU/czEWbjUFpJu37RGobvZ9
 AI8GL4RD46IMsIvrb9xULJu3Fh5j+0Paj7hi6YGQqWPrKvhSFJ8cwc5M0oazslB3
 P02n345laVmGvSskpT64nGZ2ArKr/Q==
 =ZMIC
 -----END PGP SIGNATURE-----

Merge tag 'thermal-v6.5-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/thermal/linux into thermal

Pull thermal control updates for 6.5-rc1 from Daniel Lezcano:

"- Add DT bindings for SM6375, MSM8226 and QCM2290 Qcom platforms (Konrad
   Dybcio)

 - Add DT bindings and support for QCom MSM8226 (Matti Lehtimäki)

 - Add DT bindings for QCom ipq9574 (Praveenkumar I)

 - Convert bcm2835 DT bindings to the yaml schema (Stefan Wahren)

 - Allow selecting the bang-bang governor as default (Thierry Reding)

 - Refactor and prepare the code to set the scene for RCar Gen4
   (Wolfram Sang)

 - Cleanup and fixes for the QCom tsens drivers. Add DT bindings and
   calibration for the MSM8909 platform (Stephan Gerhold)

 - Revert a patch introducing a wrong usage of devm_of_iomap() on the
   Mediatek platform (Ricardo Cañuelo)

 - Fix the clock vs reset ordering in order to conform to the
   documentation on the sun8i (Christophe JAILLET)

 - Prevent setting up undocumented registers, enable the only described
   sensors and add the version 2.1 on the Qoriq sensor (Peng Fan)

 - Add DT bindings and support for the Armada AP807 (Alex Leibovich)

 - Update the mlx5 driver with the recent thermal changes (Daniel
   Lezcano)

 - Convert to platform remove callback returning void on STM32 (Uwe
   Kleine-König)

 - Add an error information printing for devm_thermal_add_hwmon_sysfs()
   and remove the error from the Sun8i, Amlogic, i.MX, TI, K3, Tegra,
   Qoriq, Mediateka and QCom (Yangtao Li)

 - Register as hwmon sensor for the Generic ADC (Chen-Yu Tsai)

 - Use the dev_err_probe() function in the QCom tsens alarm driver
   (Luca Weiss)"

* tag 'thermal-v6.5-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/thermal/linux: (38 commits)
  thermal/drivers/qcom/temp-alarm: Use dev_err_probe
  thermal/drivers/generic-adc: Register thermal zones as hwmon sensors
  thermal/drivers/mediatek/lvts_thermal: Remove redundant msg in lvts_ctrl_start()
  thermal/drivers/qcom: Remove redundant msg at probe time
  thermal/drivers/ti-soc: Remove redundant msg in ti_thermal_expose_sensor()
  thermal/drivers/qoriq: Remove redundant msg in qoriq_tmu_register_tmu_zone()
  thermal/drivers/tegra: Remove redundant msg in tegra_tsensor_register_channel()
  drivers/thermal/k3: Remove redundant msg in k3_bandgap_probe()
  thermal/drivers/imx: Remove redundant msg in imx8mm_tmu_probe() and imx_sc_thermal_probe()
  thermal/drivers/amlogic: Remove redundant msg in amlogic_thermal_probe()
  thermal/drivers/sun8i: Remove redundant msg in sun8i_ths_register()
  thermal/hwmon: Add error information printing for devm_thermal_add_hwmon_sysfs()
  thermal/drivers/stm32: Convert to platform remove callback returning void
  net/mlx5: Update the driver with the recent thermal changes
  thermal/drivers/armada: Add support for AP807 thermal data
  dt-bindings: armada-thermal: Add armada-ap807-thermal compatible
  thermal/drivers/qoriq: Support version 2.1
  thermal/drivers/qoriq: Only enable supported sensors
  thermal/drivers/qoriq: No need to program site adjustment register
  thermal/drivers/mediatek/lvts_thermal: Register thermal zones as hwmon sensors
  ...
This commit is contained in:
Rafael J. Wysocki 2023-06-26 18:56:58 +02:00
commit a8460ba594
30 changed files with 415 additions and 295 deletions

View File

@ -8,6 +8,7 @@ Required properties:
* marvell,armada380-thermal
* marvell,armadaxp-thermal
* marvell,armada-ap806-thermal
* marvell,armada-ap807-thermal
* marvell,armada-cp110-thermal
Note: these bindings are deprecated for AP806/CP110 and should instead

View File

@ -1,41 +0,0 @@
Binding for Thermal Sensor driver for BCM2835 SoCs.
Required parameters:
-------------------
compatible: should be one of: "brcm,bcm2835-thermal",
"brcm,bcm2836-thermal" or "brcm,bcm2837-thermal"
reg: Address range of the thermal registers.
clocks: Phandle of the clock used by the thermal sensor.
#thermal-sensor-cells: should be 0 (see Documentation/devicetree/bindings/thermal/thermal-sensor.yaml)
Example:
thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <0>;
polling-delay = <1000>;
thermal-sensors = <&thermal>;
trips {
cpu-crit {
temperature = <80000>;
hysteresis = <0>;
type = "critical";
};
};
coefficients = <(-538) 407000>;
cooling-maps {
};
};
};
thermal: thermal@7e212000 {
compatible = "brcm,bcm2835-thermal";
reg = <0x7e212000 0x8>;
clocks = <&clocks BCM2835_CLOCK_TSENS>;
#thermal-sensor-cells = <0>;
};

View File

@ -0,0 +1,48 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/thermal/brcm,bcm2835-thermal.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Broadcom BCM2835 thermal sensor
maintainers:
- Stefan Wahren <stefan.wahren@i2se.com>
allOf:
- $ref: thermal-sensor.yaml#
properties:
compatible:
enum:
- brcm,bcm2835-thermal
- brcm,bcm2836-thermal
- brcm,bcm2837-thermal
reg:
maxItems: 1
clocks:
maxItems: 1
"#thermal-sensor-cells":
const: 0
unevaluatedProperties: false
required:
- compatible
- reg
- clocks
- '#thermal-sensor-cells'
examples:
- |
#include <dt-bindings/clock/bcm2835.h>
thermal@7e212000 {
compatible = "brcm,bcm2835-thermal";
reg = <0x7e212000 0x8>;
clocks = <&clocks BCM2835_CLOCK_TSENS>;
#thermal-sensor-cells = <0>;
};

View File

@ -29,6 +29,8 @@ properties:
items:
- enum:
- qcom,mdm9607-tsens
- qcom,msm8226-tsens
- qcom,msm8909-tsens
- qcom,msm8916-tsens
- qcom,msm8939-tsens
- qcom,msm8974-tsens
@ -48,6 +50,7 @@ properties:
- qcom,msm8953-tsens
- qcom,msm8996-tsens
- qcom,msm8998-tsens
- qcom,qcm2290-tsens
- qcom,sc7180-tsens
- qcom,sc7280-tsens
- qcom,sc8180x-tsens
@ -56,6 +59,7 @@ properties:
- qcom,sdm845-tsens
- qcom,sm6115-tsens
- qcom,sm6350-tsens
- qcom,sm6375-tsens
- qcom,sm8150-tsens
- qcom,sm8250-tsens
- qcom,sm8350-tsens
@ -67,6 +71,12 @@ properties:
enum:
- qcom,ipq8074-tsens
- description: v2 of TSENS with combined interrupt
items:
- enum:
- qcom,ipq9574-tsens
- const: qcom,ipq8074-tsens
reg:
items:
- description: TM registers
@ -223,12 +233,7 @@ allOf:
contains:
enum:
- qcom,ipq8064-tsens
- qcom,mdm9607-tsens
- qcom,msm8916-tsens
- qcom,msm8960-tsens
- qcom,msm8974-tsens
- qcom,msm8976-tsens
- qcom,qcs404-tsens
- qcom,tsens-v0_1
- qcom,tsens-v1
then:
@ -244,22 +249,7 @@ allOf:
properties:
compatible:
contains:
enum:
- qcom,msm8953-tsens
- qcom,msm8996-tsens
- qcom,msm8998-tsens
- qcom,sc7180-tsens
- qcom,sc7280-tsens
- qcom,sc8180x-tsens
- qcom,sc8280xp-tsens
- qcom,sdm630-tsens
- qcom,sdm845-tsens
- qcom,sm6350-tsens
- qcom,sm8150-tsens
- qcom,sm8250-tsens
- qcom,sm8350-tsens
- qcom,sm8450-tsens
- qcom,tsens-v2
const: qcom,tsens-v2
then:
properties:
interrupts:

View File

@ -45,7 +45,7 @@ static int mlx5_thermal_get_mtmp_temp(struct mlx5_core_dev *mdev, u32 id, int *p
static int mlx5_thermal_get_temp(struct thermal_zone_device *tzdev,
int *p_temp)
{
struct mlx5_thermal *thermal = tzdev->devdata;
struct mlx5_thermal *thermal = thermal_zone_device_priv(tzdev);
struct mlx5_core_dev *mdev = thermal->mdev;
int err;
@ -81,12 +81,13 @@ int mlx5_thermal_init(struct mlx5_core_dev *mdev)
return -ENOMEM;
thermal->mdev = mdev;
thermal->tzdev = thermal_zone_device_register(data,
MLX5_THERMAL_NUM_TRIPS,
MLX5_THERMAL_TRIP_MASK,
thermal,
&mlx5_thermal_ops,
NULL, 0, MLX5_THERMAL_POLL_INT_MSEC);
thermal->tzdev = thermal_zone_device_register_with_trips(data,
NULL,
MLX5_THERMAL_NUM_TRIPS,
MLX5_THERMAL_TRIP_MASK,
thermal,
&mlx5_thermal_ops,
NULL, 0, MLX5_THERMAL_POLL_INT_MSEC);
if (IS_ERR(thermal->tzdev)) {
dev_err(mdev->device, "Failed to register thermal zone device (%s) %ld\n",
data, PTR_ERR(thermal->tzdev));

View File

@ -130,6 +130,14 @@ config THERMAL_DEFAULT_GOV_POWER_ALLOCATOR
system and device power allocation. This governor can only
operate on cooling devices that implement the power API.
config THERMAL_DEFAULT_GOV_BANG_BANG
bool "bang_bang"
depends on THERMAL_GOV_BANG_BANG
help
Use the bang_bang governor as default. This throttles the
devices one step at the time, taking into account the trip
point hysteresis.
endchoice
config THERMAL_GOV_FAIR_SHARE

View File

@ -282,8 +282,7 @@ static int amlogic_thermal_probe(struct platform_device *pdev)
return ret;
}
if (devm_thermal_add_hwmon_sysfs(&pdev->dev, pdata->tzd))
dev_warn(&pdev->dev, "Failed to add hwmon sysfs attributes\n");
devm_thermal_add_hwmon_sysfs(&pdev->dev, pdata->tzd);
ret = amlogic_thermal_initialize(pdata);
if (ret)

View File

@ -231,7 +231,7 @@ static void armada380_init(struct platform_device *pdev,
regmap_write(priv->syscon, data->syscon_control0_off, reg);
}
static void armada_ap806_init(struct platform_device *pdev,
static void armada_ap80x_init(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
struct armada_thermal_data *data = priv->data;
@ -614,7 +614,7 @@ static const struct armada_thermal_data armada380_data = {
};
static const struct armada_thermal_data armada_ap806_data = {
.init = armada_ap806_init,
.init = armada_ap80x_init,
.is_valid_bit = BIT(16),
.temp_shift = 0,
.temp_mask = 0x3ff,
@ -637,6 +637,30 @@ static const struct armada_thermal_data armada_ap806_data = {
.cpu_nr = 4,
};
static const struct armada_thermal_data armada_ap807_data = {
.init = armada_ap80x_init,
.is_valid_bit = BIT(16),
.temp_shift = 0,
.temp_mask = 0x3ff,
.thresh_shift = 3,
.hyst_shift = 19,
.hyst_mask = 0x3,
.coef_b = -128900LL,
.coef_m = 394ULL,
.coef_div = 1,
.inverted = true,
.signed_sample = true,
.syscon_control0_off = 0x84,
.syscon_control1_off = 0x88,
.syscon_status_off = 0x8C,
.dfx_irq_cause_off = 0x108,
.dfx_irq_mask_off = 0x10C,
.dfx_overheat_irq = BIT(22),
.dfx_server_irq_mask_off = 0x104,
.dfx_server_irq_en = BIT(1),
.cpu_nr = 4,
};
static const struct armada_thermal_data armada_cp110_data = {
.init = armada_cp110_init,
.is_valid_bit = BIT(10),
@ -680,6 +704,10 @@ static const struct of_device_id armada_thermal_id_table[] = {
.compatible = "marvell,armada-ap806-thermal",
.data = &armada_ap806_data,
},
{
.compatible = "marvell,armada-ap807-thermal",
.data = &armada_ap807_data,
},
{
.compatible = "marvell,armada-cp110-thermal",
.data = &armada_cp110_data,

View File

@ -343,8 +343,7 @@ static int imx8mm_tmu_probe(struct platform_device *pdev)
}
tmu->sensors[i].hw_id = i;
if (devm_thermal_add_hwmon_sysfs(&pdev->dev, tmu->sensors[i].tzd))
dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n");
devm_thermal_add_hwmon_sysfs(&pdev->dev, tmu->sensors[i].tzd);
}
platform_set_drvdata(pdev, tmu);

View File

@ -116,8 +116,7 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)
return ret;
}
if (devm_thermal_add_hwmon_sysfs(&pdev->dev, sensor->tzd))
dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n");
devm_thermal_add_hwmon_sysfs(&pdev->dev, sensor->tzd);
}
return 0;

View File

@ -222,8 +222,7 @@ static int k3_bandgap_probe(struct platform_device *pdev)
goto err_alloc;
}
if (devm_thermal_add_hwmon_sysfs(dev, data[id].tzd))
dev_warn(dev, "Failed to add hwmon sysfs attributes\n");
devm_thermal_add_hwmon_sysfs(dev, data[id].tzd);
}
platform_set_drvdata(pdev, bgp);

View File

@ -1222,12 +1222,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
return -ENODEV;
}
auxadc_base = devm_of_iomap(&pdev->dev, auxadc, 0, NULL);
if (IS_ERR(auxadc_base)) {
of_node_put(auxadc);
return PTR_ERR(auxadc_base);
}
auxadc_base = of_iomap(auxadc, 0);
auxadc_phys_base = of_get_phys_base(auxadc);
of_node_put(auxadc);
@ -1243,12 +1238,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
return -ENODEV;
}
apmixed_base = devm_of_iomap(&pdev->dev, apmixedsys, 0, NULL);
if (IS_ERR(apmixed_base)) {
of_node_put(apmixedsys);
return PTR_ERR(apmixed_base);
}
apmixed_base = of_iomap(apmixedsys, 0);
apmixed_phys_base = of_get_phys_base(apmixedsys);
of_node_put(apmixedsys);

View File

@ -19,6 +19,8 @@
#include <linux/thermal.h>
#include <dt-bindings/thermal/mediatek,lvts-thermal.h>
#include "../thermal_hwmon.h"
#define LVTS_MONCTL0(__base) (__base + 0x0000)
#define LVTS_MONCTL1(__base) (__base + 0x0004)
#define LVTS_MONCTL2(__base) (__base + 0x0008)
@ -996,6 +998,8 @@ static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
return PTR_ERR(tz);
}
devm_thermal_add_hwmon_sysfs(dev, tz);
/*
* The thermal zone pointer will be needed in the
* interrupt handler, we store it in the sensor

View File

@ -689,9 +689,7 @@ 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(adc_tm->dev, tzd))
dev_warn(adc_tm->dev,
"Failed to add hwmon sysfs attributes\n");
devm_thermal_add_hwmon_sysfs(adc_tm->dev, tzd);
}
return 0;

View File

@ -411,22 +411,19 @@ static int qpnp_tm_probe(struct platform_device *pdev)
chip->base = res;
ret = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, &type);
if (ret < 0) {
dev_err(&pdev->dev, "could not read type\n");
return ret;
}
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"could not read type\n");
ret = qpnp_tm_read(chip, QPNP_TM_REG_SUBTYPE, &subtype);
if (ret < 0) {
dev_err(&pdev->dev, "could not read subtype\n");
return ret;
}
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"could not read subtype\n");
ret = qpnp_tm_read(chip, QPNP_TM_REG_DIG_MAJOR, &dig_major);
if (ret < 0) {
dev_err(&pdev->dev, "could not read dig_major\n");
return ret;
}
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"could not read dig_major\n");
if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1
&& subtype != QPNP_TM_SUBTYPE_GEN2)) {
@ -448,20 +445,15 @@ static int qpnp_tm_probe(struct platform_device *pdev)
*/
chip->tz_dev = devm_thermal_of_zone_register(
&pdev->dev, 0, chip, &qpnp_tm_sensor_ops);
if (IS_ERR(chip->tz_dev)) {
dev_err(&pdev->dev, "failed to register sensor\n");
return PTR_ERR(chip->tz_dev);
}
if (IS_ERR(chip->tz_dev))
return dev_err_probe(&pdev->dev, PTR_ERR(chip->tz_dev),
"failed to register sensor\n");
ret = qpnp_tm_init(chip);
if (ret < 0) {
dev_err(&pdev->dev, "init failed\n");
return ret;
}
if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "init failed\n");
if (devm_thermal_add_hwmon_sysfs(&pdev->dev, chip->tz_dev))
dev_warn(&pdev->dev,
"Failed to add hwmon sysfs attributes\n");
devm_thermal_add_hwmon_sysfs(&pdev->dev, chip->tz_dev);
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, qpnp_tm_isr,
IRQF_ONESHOT, node->name, chip);

View File

@ -39,26 +39,6 @@ struct tsens_legacy_calibration_format tsens_8916_nvmem = {
},
};
struct tsens_legacy_calibration_format tsens_8939_nvmem = {
.base_len = 8,
.base_shift = 2,
.sp_len = 6,
.mode = { 12, 0 },
.invalid = { 12, 2 },
.base = { { 0, 0 }, { 1, 24 } },
.sp = {
{ { 12, 3 }, { 12, 9 } },
{ { 12, 15 }, { 12, 21 } },
{ { 12, 27 }, { 13, 1 } },
{ { 13, 7 }, { 13, 13 } },
{ { 13, 19 }, { 13, 25 } },
{ { 0, 8 }, { 0, 14 } },
{ { 0, 20 }, { 0, 26 } },
{ { 1, 0 }, { 1, 6 } },
{ { 1, 12 }, { 1, 18 } },
},
};
struct tsens_legacy_calibration_format tsens_8974_nvmem = {
.base_len = 8,
.base_shift = 2,
@ -103,22 +83,6 @@ struct tsens_legacy_calibration_format tsens_8974_backup_nvmem = {
},
};
struct tsens_legacy_calibration_format tsens_9607_nvmem = {
.base_len = 8,
.base_shift = 2,
.sp_len = 6,
.mode = { 2, 20 },
.invalid = { 2, 22 },
.base = { { 0, 0 }, { 2, 12 } },
.sp = {
{ { 0, 8 }, { 0, 14 } },
{ { 0, 20 }, { 0, 26 } },
{ { 1, 0 }, { 1, 6 } },
{ { 1, 12 }, { 1, 18 } },
{ { 2, 0 }, { 2, 6 } },
},
};
static int calibrate_8916(struct tsens_priv *priv)
{
u32 p1[5], p2[5];
@ -243,6 +207,39 @@ static int calibrate_8974(struct tsens_priv *priv)
return 0;
}
static int __init init_8226(struct tsens_priv *priv)
{
priv->sensor[0].slope = 2901;
priv->sensor[1].slope = 2846;
priv->sensor[2].slope = 3038;
priv->sensor[3].slope = 2955;
priv->sensor[4].slope = 2901;
priv->sensor[5].slope = 2846;
return init_common(priv);
}
static int __init init_8909(struct tsens_priv *priv)
{
int i;
for (i = 0; i < priv->num_sensors; ++i)
priv->sensor[i].slope = 3000;
priv->sensor[0].p1_calib_offset = 0;
priv->sensor[0].p2_calib_offset = 0;
priv->sensor[1].p1_calib_offset = -10;
priv->sensor[1].p2_calib_offset = -6;
priv->sensor[2].p1_calib_offset = 0;
priv->sensor[2].p2_calib_offset = 0;
priv->sensor[3].p1_calib_offset = -9;
priv->sensor[3].p2_calib_offset = -9;
priv->sensor[4].p1_calib_offset = -8;
priv->sensor[4].p2_calib_offset = -10;
return init_common(priv);
}
static int __init init_8939(struct tsens_priv *priv) {
priv->sensor[0].slope = 2911;
priv->sensor[1].slope = 2789;
@ -258,7 +255,28 @@ static int __init init_8939(struct tsens_priv *priv) {
return init_common(priv);
}
/* v0.1: 8916, 8939, 8974, 9607 */
static int __init init_9607(struct tsens_priv *priv)
{
int i;
for (i = 0; i < priv->num_sensors; ++i)
priv->sensor[i].slope = 3000;
priv->sensor[0].p1_calib_offset = 1;
priv->sensor[0].p2_calib_offset = 1;
priv->sensor[1].p1_calib_offset = -4;
priv->sensor[1].p2_calib_offset = -2;
priv->sensor[2].p1_calib_offset = 4;
priv->sensor[2].p2_calib_offset = 8;
priv->sensor[3].p1_calib_offset = -3;
priv->sensor[3].p2_calib_offset = -5;
priv->sensor[4].p1_calib_offset = -4;
priv->sensor[4].p2_calib_offset = -4;
return init_common(priv);
}
/* v0.1: 8226, 8909, 8916, 8939, 8974, 9607 */
static struct tsens_features tsens_v0_1_feat = {
.ver_major = VER_0_1,
@ -313,6 +331,32 @@ static const struct tsens_ops ops_v0_1 = {
.get_temp = get_temp_common,
};
static const struct tsens_ops ops_8226 = {
.init = init_8226,
.calibrate = tsens_calibrate_common,
.get_temp = get_temp_common,
};
struct tsens_plat_data data_8226 = {
.num_sensors = 6,
.ops = &ops_8226,
.feat = &tsens_v0_1_feat,
.fields = tsens_v0_1_regfields,
};
static const struct tsens_ops ops_8909 = {
.init = init_8909,
.calibrate = tsens_calibrate_common,
.get_temp = get_temp_common,
};
struct tsens_plat_data data_8909 = {
.num_sensors = 5,
.ops = &ops_8909,
.feat = &tsens_v0_1_feat,
.fields = tsens_v0_1_regfields,
};
static const struct tsens_ops ops_8916 = {
.init = init_common,
.calibrate = calibrate_8916,
@ -356,9 +400,15 @@ struct tsens_plat_data data_8974 = {
.fields = tsens_v0_1_regfields,
};
static const struct tsens_ops ops_9607 = {
.init = init_9607,
.calibrate = tsens_calibrate_common,
.get_temp = get_temp_common,
};
struct tsens_plat_data data_9607 = {
.num_sensors = 5,
.ops = &ops_v0_1,
.ops = &ops_9607,
.feat = &tsens_v0_1_feat,
.fields = tsens_v0_1_regfields,
};

View File

@ -42,28 +42,6 @@ struct tsens_legacy_calibration_format tsens_qcs404_nvmem = {
},
};
struct tsens_legacy_calibration_format tsens_8976_nvmem = {
.base_len = 8,
.base_shift = 2,
.sp_len = 6,
.mode = { 4, 0 },
.invalid = { 4, 2 },
.base = { { 0, 0 }, { 2, 8 } },
.sp = {
{ { 0, 8 }, { 0, 14 } },
{ { 0, 20 }, { 0, 26 } },
{ { 1, 0 }, { 1, 6 } },
{ { 1, 12 }, { 1, 18 } },
{ { 2, 8 }, { 2, 14 } },
{ { 2, 20 }, { 2, 26 } },
{ { 3, 0 }, { 3, 6 } },
{ { 3, 12 }, { 3, 18 } },
{ { 4, 2 }, { 4, 9 } },
{ { 4, 14 }, { 4, 21 } },
{ { 4, 26 }, { 5, 1 } },
},
};
static int calibrate_v1(struct tsens_priv *priv)
{
u32 p1[10], p2[10];

View File

@ -134,10 +134,12 @@ int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2,
p1[i] = p1[i] + (base1 << shift);
break;
case TWO_PT_CALIB:
case TWO_PT_CALIB_NO_OFFSET:
for (i = 0; i < priv->num_sensors; i++)
p2[i] = (p2[i] + base2) << shift;
fallthrough;
case ONE_PT_CALIB2:
case ONE_PT_CALIB2_NO_OFFSET:
for (i = 0; i < priv->num_sensors; i++)
p1[i] = (p1[i] + base1) << shift;
break;
@ -149,6 +151,18 @@ int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2,
}
}
/* Apply calibration offset workaround except for _NO_OFFSET modes */
switch (mode) {
case TWO_PT_CALIB:
for (i = 0; i < priv->num_sensors; i++)
p2[i] += priv->sensor[i].p2_calib_offset;
fallthrough;
case ONE_PT_CALIB2:
for (i = 0; i < priv->num_sensors; i++)
p1[i] += priv->sensor[i].p1_calib_offset;
break;
}
return mode;
}
@ -254,7 +268,7 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
if (!priv->sensor[i].slope)
priv->sensor[i].slope = SLOPE_DEFAULT;
if (mode == TWO_PT_CALIB) {
if (mode == TWO_PT_CALIB || mode == TWO_PT_CALIB_NO_OFFSET) {
/*
* slope (m) = adc_code2 - adc_code1 (y2 - y1)/
* temp_120_degc - temp_30_degc (x2 - x1)
@ -1095,6 +1109,12 @@ static const struct of_device_id tsens_table[] = {
}, {
.compatible = "qcom,mdm9607-tsens",
.data = &data_9607,
}, {
.compatible = "qcom,msm8226-tsens",
.data = &data_8226,
}, {
.compatible = "qcom,msm8909-tsens",
.data = &data_8909,
}, {
.compatible = "qcom,msm8916-tsens",
.data = &data_8916,
@ -1189,9 +1209,7 @@ static int tsens_register(struct tsens_priv *priv)
if (priv->ops->enable)
priv->ops->enable(priv, i);
if (devm_thermal_add_hwmon_sysfs(priv->dev, tzd))
dev_warn(priv->dev,
"Failed to add hwmon sysfs attributes\n");
devm_thermal_add_hwmon_sysfs(priv->dev, tzd);
}
/* VER_0 require to set MIN and MAX THRESH

View File

@ -10,6 +10,8 @@
#define ONE_PT_CALIB 0x1
#define ONE_PT_CALIB2 0x2
#define TWO_PT_CALIB 0x3
#define ONE_PT_CALIB2_NO_OFFSET 0x6
#define TWO_PT_CALIB_NO_OFFSET 0x7
#define CAL_DEGC_PT1 30
#define CAL_DEGC_PT2 120
#define SLOPE_FACTOR 1000
@ -57,6 +59,8 @@ struct tsens_sensor {
unsigned int hw_id;
int slope;
u32 status;
int p1_calib_offset;
int p2_calib_offset;
};
/**
@ -635,7 +639,7 @@ int get_temp_common(const struct tsens_sensor *s, int *temp);
extern struct tsens_plat_data data_8960;
/* TSENS v0.1 targets */
extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607;
extern struct tsens_plat_data data_8226, data_8909, data_8916, data_8939, data_8974, data_9607;
/* TSENS v1 targets */
extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956;

View File

@ -31,7 +31,6 @@
#define TMR_DISABLE 0x0
#define TMR_ME 0x80000000
#define TMR_ALPF 0x0c000000
#define TMR_MSITE_ALL GENMASK(15, 0)
#define REGS_TMTMIR 0x008 /* Temperature measurement interval Register */
#define TMTMIR_DEFAULT 0x0000000f
@ -51,6 +50,7 @@
* Site Register
*/
#define TRITSR_V BIT(31)
#define TRITSR_TP5 BIT(9)
#define REGS_V2_TMSAR(n) (0x304 + 16 * (n)) /* TMU monitoring
* site adjustment register
*/
@ -105,6 +105,11 @@ static int tmu_get_temp(struct thermal_zone_device *tz, int *temp)
* within sensor range. TEMP is an 9 bit value representing
* temperature in KelVin.
*/
regmap_read(qdata->regmap, REGS_TMR, &val);
if (!(val & TMR_ME))
return -EAGAIN;
if (regmap_read_poll_timeout(qdata->regmap,
REGS_TRITSR(qsensor->id),
val,
@ -113,10 +118,15 @@ static int tmu_get_temp(struct thermal_zone_device *tz, int *temp)
10 * USEC_PER_MSEC))
return -ENODATA;
if (qdata->ver == TMU_VER1)
if (qdata->ver == TMU_VER1) {
*temp = (val & GENMASK(7, 0)) * MILLIDEGREE_PER_DEGREE;
else
*temp = kelvin_to_millicelsius(val & GENMASK(8, 0));
} else {
if (val & TRITSR_TP5)
*temp = milli_kelvin_to_millicelsius((val & GENMASK(8, 0)) *
MILLIDEGREE_PER_DEGREE + 500);
else
*temp = kelvin_to_millicelsius(val & GENMASK(8, 0));
}
return 0;
}
@ -128,15 +138,7 @@ static const struct thermal_zone_device_ops tmu_tz_ops = {
static int qoriq_tmu_register_tmu_zone(struct device *dev,
struct qoriq_tmu_data *qdata)
{
int id;
if (qdata->ver == TMU_VER1) {
regmap_write(qdata->regmap, REGS_TMR,
TMR_MSITE_ALL | TMR_ME | TMR_ALPF);
} else {
regmap_write(qdata->regmap, REGS_V2_TMSR, TMR_MSITE_ALL);
regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF_V2);
}
int id, sites = 0;
for (id = 0; id < SITES_MAX; id++) {
struct thermal_zone_device *tzd;
@ -153,14 +155,24 @@ static int qoriq_tmu_register_tmu_zone(struct device *dev,
if (ret == -ENODEV)
continue;
regmap_write(qdata->regmap, REGS_TMR, TMR_DISABLE);
return ret;
}
if (devm_thermal_add_hwmon_sysfs(dev, tzd))
dev_warn(dev,
"Failed to add hwmon sysfs attributes\n");
if (qdata->ver == TMU_VER1)
sites |= 0x1 << (15 - id);
else
sites |= 0x1 << id;
devm_thermal_add_hwmon_sysfs(dev, tzd);
}
if (sites) {
if (qdata->ver == TMU_VER1) {
regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF | sites);
} else {
regmap_write(qdata->regmap, REGS_V2_TMSR, sites);
regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF_V2);
}
}
return 0;
@ -208,8 +220,6 @@ static int qoriq_tmu_calibration(struct device *dev,
static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
{
int i;
/* Disable interrupt, using polling instead */
regmap_write(data->regmap, REGS_TIER, TIER_DISABLE);
@ -220,8 +230,6 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
} else {
regmap_write(data->regmap, REGS_V2_TMTMIR, TMTMIR_DEFAULT);
regmap_write(data->regmap, REGS_V2_TEUMR(0), TEUMR0_V2);
for (i = 0; i < SITES_MAX; i++)
regmap_write(data->regmap, REGS_V2_TMSAR(i), TMSARA_V2);
}
/* Disable monitoring */
@ -230,7 +238,7 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
static const struct regmap_range qoriq_yes_ranges[] = {
regmap_reg_range(REGS_TMR, REGS_TSCFGR),
regmap_reg_range(REGS_TTRnCR(0), REGS_TTRnCR(3)),
regmap_reg_range(REGS_TTRnCR(0), REGS_TTRnCR(15)),
regmap_reg_range(REGS_V2_TEUMR(0), REGS_V2_TEUMR(2)),
regmap_reg_range(REGS_V2_TMSAR(0), REGS_V2_TMSAR(15)),
regmap_reg_range(REGS_IPBRR(0), REGS_IPBRR(1)),

View File

@ -35,6 +35,12 @@
#define REG_GEN3_PTAT2 0x60
#define REG_GEN3_PTAT3 0x64
#define REG_GEN3_THSCP 0x68
#define REG_GEN4_THSFMON00 0x180
#define REG_GEN4_THSFMON01 0x184
#define REG_GEN4_THSFMON02 0x188
#define REG_GEN4_THSFMON15 0x1BC
#define REG_GEN4_THSFMON16 0x1C0
#define REG_GEN4_THSFMON17 0x1C4
/* IRQ{STR,MSK,EN} bits */
#define IRQ_TEMP1 BIT(0)
@ -55,6 +61,7 @@
#define MCELSIUS(temp) ((temp) * 1000)
#define GEN3_FUSE_MASK 0xFFF
#define GEN4_FUSE_MASK 0xFFF
#define TSC_MAX_NUM 5
@ -66,6 +73,13 @@ struct equation_coefs {
int b2;
};
struct rcar_gen3_thermal_priv;
struct rcar_thermal_info {
int ths_tj_1;
void (*read_fuses)(struct rcar_gen3_thermal_priv *priv);
};
struct rcar_gen3_thermal_tsc {
void __iomem *base;
struct thermal_zone_device *zone;
@ -79,6 +93,7 @@ struct rcar_gen3_thermal_priv {
struct thermal_zone_device_ops ops;
unsigned int num_tscs;
int ptat[3];
const struct rcar_thermal_info *info;
};
static inline u32 rcar_gen3_thermal_read(struct rcar_gen3_thermal_tsc *tsc,
@ -236,6 +251,62 @@ static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data)
return IRQ_HANDLED;
}
static void rcar_gen3_thermal_read_fuses_gen3(struct rcar_gen3_thermal_priv *priv)
{
unsigned int i;
/*
* Set the pseudo calibration points with fused values.
* PTAT is shared between all TSCs but only fused for the first
* TSC while THCODEs are fused for each TSC.
*/
priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT1) &
GEN3_FUSE_MASK;
priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT2) &
GEN3_FUSE_MASK;
priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT3) &
GEN3_FUSE_MASK;
for (i = 0; i < priv->num_tscs; i++) {
struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE1) &
GEN3_FUSE_MASK;
tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE2) &
GEN3_FUSE_MASK;
tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE3) &
GEN3_FUSE_MASK;
}
}
static void rcar_gen3_thermal_read_fuses_gen4(struct rcar_gen3_thermal_priv *priv)
{
unsigned int i;
/*
* Set the pseudo calibration points with fused values.
* PTAT is shared between all TSCs but only fused for the first
* TSC while THCODEs are fused for each TSC.
*/
priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON16) &
GEN4_FUSE_MASK;
priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON17) &
GEN4_FUSE_MASK;
priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON15) &
GEN4_FUSE_MASK;
for (i = 0; i < priv->num_tscs; i++) {
struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON01) &
GEN4_FUSE_MASK;
tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON02) &
GEN4_FUSE_MASK;
tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON00) &
GEN4_FUSE_MASK;
}
}
static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv)
{
unsigned int i;
@ -243,7 +314,8 @@ static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv)
/* If fuses are not set, fallback to pseudo values. */
thscp = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_THSCP);
if ((thscp & THSCP_COR_PARA_VLD) != THSCP_COR_PARA_VLD) {
if (!priv->info->read_fuses ||
(thscp & THSCP_COR_PARA_VLD) != THSCP_COR_PARA_VLD) {
/* Default THCODE values in case FUSEs are not set. */
static const int thcodes[TSC_MAX_NUM][3] = {
{ 3397, 2800, 2221 },
@ -268,29 +340,7 @@ static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv)
return false;
}
/*
* Set the pseudo calibration points with fused values.
* PTAT is shared between all TSCs but only fused for the first
* TSC while THCODEs are fused for each TSC.
*/
priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT1) &
GEN3_FUSE_MASK;
priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT2) &
GEN3_FUSE_MASK;
priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT3) &
GEN3_FUSE_MASK;
for (i = 0; i < priv->num_tscs; i++) {
struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE1) &
GEN3_FUSE_MASK;
tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE2) &
GEN3_FUSE_MASK;
tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE3) &
GEN3_FUSE_MASK;
}
priv->info->read_fuses(priv);
return true;
}
@ -318,52 +368,65 @@ static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_priv *priv,
usleep_range(1000, 2000);
}
static const int rcar_gen3_ths_tj_1 = 126;
static const int rcar_gen3_ths_tj_1_m3_w = 116;
static const struct rcar_thermal_info rcar_m3w_thermal_info = {
.ths_tj_1 = 116,
.read_fuses = rcar_gen3_thermal_read_fuses_gen3,
};
static const struct rcar_thermal_info rcar_gen3_thermal_info = {
.ths_tj_1 = 126,
.read_fuses = rcar_gen3_thermal_read_fuses_gen3,
};
static const struct rcar_thermal_info rcar_gen4_thermal_info = {
.ths_tj_1 = 126,
.read_fuses = rcar_gen3_thermal_read_fuses_gen4,
};
static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
{
.compatible = "renesas,r8a774a1-thermal",
.data = &rcar_gen3_ths_tj_1_m3_w,
.data = &rcar_m3w_thermal_info,
},
{
.compatible = "renesas,r8a774b1-thermal",
.data = &rcar_gen3_ths_tj_1,
.data = &rcar_gen3_thermal_info,
},
{
.compatible = "renesas,r8a774e1-thermal",
.data = &rcar_gen3_ths_tj_1,
.data = &rcar_gen3_thermal_info,
},
{
.compatible = "renesas,r8a7795-thermal",
.data = &rcar_gen3_ths_tj_1,
.data = &rcar_gen3_thermal_info,
},
{
.compatible = "renesas,r8a7796-thermal",
.data = &rcar_gen3_ths_tj_1_m3_w,
.data = &rcar_m3w_thermal_info,
},
{
.compatible = "renesas,r8a77961-thermal",
.data = &rcar_gen3_ths_tj_1_m3_w,
.data = &rcar_m3w_thermal_info,
},
{
.compatible = "renesas,r8a77965-thermal",
.data = &rcar_gen3_ths_tj_1,
.data = &rcar_gen3_thermal_info,
},
{
.compatible = "renesas,r8a77980-thermal",
.data = &rcar_gen3_ths_tj_1,
.data = &rcar_gen3_thermal_info,
},
{
.compatible = "renesas,r8a779a0-thermal",
.data = &rcar_gen3_ths_tj_1,
.data = &rcar_gen3_thermal_info,
},
{
.compatible = "renesas,r8a779f0-thermal",
.data = &rcar_gen3_ths_tj_1,
.data = &rcar_gen4_thermal_info,
},
{
.compatible = "renesas,r8a779g0-thermal",
.data = &rcar_gen3_ths_tj_1,
.data = &rcar_gen4_thermal_info,
},
{},
};
@ -418,7 +481,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
{
struct rcar_gen3_thermal_priv *priv;
struct device *dev = &pdev->dev;
const int *ths_tj_1 = of_device_get_match_data(dev);
struct resource *res;
struct thermal_zone_device *zone;
unsigned int i;
@ -430,6 +492,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
priv->ops = rcar_gen3_tz_of_ops;
priv->info = of_device_get_match_data(dev);
platform_set_drvdata(pdev, priv);
if (rcar_gen3_thermal_request_irqs(priv, pdev))
@ -469,7 +532,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
rcar_gen3_thermal_init(priv, tsc);
rcar_gen3_thermal_calc_coefs(priv, tsc, *ths_tj_1);
rcar_gen3_thermal_calc_coefs(priv, tsc, priv->info->ths_tj_1);
zone = devm_thermal_of_zone_register(dev, i, tsc, &priv->ops);
if (IS_ERR(zone)) {

View File

@ -227,14 +227,12 @@ sensor_off:
}
EXPORT_SYMBOL_GPL(st_thermal_register);
int st_thermal_unregister(struct platform_device *pdev)
void st_thermal_unregister(struct platform_device *pdev)
{
struct st_thermal_sensor *sensor = platform_get_drvdata(pdev);
st_thermal_sensor_off(sensor);
thermal_zone_device_unregister(sensor->thermal_dev);
return 0;
}
EXPORT_SYMBOL_GPL(st_thermal_unregister);

View File

@ -94,7 +94,7 @@ struct st_thermal_sensor {
extern int st_thermal_register(struct platform_device *pdev,
const struct of_device_id *st_thermal_of_match);
extern int st_thermal_unregister(struct platform_device *pdev);
extern void st_thermal_unregister(struct platform_device *pdev);
extern const struct dev_pm_ops st_thermal_pm_ops;
#endif /* __STI_RESET_SYSCFG_H */

View File

@ -172,9 +172,9 @@ static int st_mmap_probe(struct platform_device *pdev)
return st_thermal_register(pdev, st_mmap_thermal_of_match);
}
static int st_mmap_remove(struct platform_device *pdev)
static void st_mmap_remove(struct platform_device *pdev)
{
return st_thermal_unregister(pdev);
st_thermal_unregister(pdev);
}
static struct platform_driver st_mmap_thermal_driver = {
@ -184,7 +184,7 @@ static struct platform_driver st_mmap_thermal_driver = {
.of_match_table = st_mmap_thermal_of_match,
},
.probe = st_mmap_probe,
.remove = st_mmap_remove,
.remove_new = st_mmap_remove,
};
module_platform_driver(st_mmap_thermal_driver);

View File

@ -319,6 +319,11 @@ out:
return ret;
}
static void sun8i_ths_reset_control_assert(void *data)
{
reset_control_assert(data);
}
static int sun8i_ths_resource_init(struct ths_device *tmdev)
{
struct device *dev = tmdev->dev;
@ -339,47 +344,35 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev)
if (IS_ERR(tmdev->reset))
return PTR_ERR(tmdev->reset);
tmdev->bus_clk = devm_clk_get(&pdev->dev, "bus");
ret = reset_control_deassert(tmdev->reset);
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, sun8i_ths_reset_control_assert,
tmdev->reset);
if (ret)
return ret;
tmdev->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus");
if (IS_ERR(tmdev->bus_clk))
return PTR_ERR(tmdev->bus_clk);
}
if (tmdev->chip->has_mod_clk) {
tmdev->mod_clk = devm_clk_get(&pdev->dev, "mod");
tmdev->mod_clk = devm_clk_get_enabled(&pdev->dev, "mod");
if (IS_ERR(tmdev->mod_clk))
return PTR_ERR(tmdev->mod_clk);
}
ret = reset_control_deassert(tmdev->reset);
ret = clk_set_rate(tmdev->mod_clk, 24000000);
if (ret)
return ret;
ret = clk_prepare_enable(tmdev->bus_clk);
if (ret)
goto assert_reset;
ret = clk_set_rate(tmdev->mod_clk, 24000000);
if (ret)
goto bus_disable;
ret = clk_prepare_enable(tmdev->mod_clk);
if (ret)
goto bus_disable;
ret = sun8i_ths_calibrate(tmdev);
if (ret)
goto mod_disable;
return ret;
return 0;
mod_disable:
clk_disable_unprepare(tmdev->mod_clk);
bus_disable:
clk_disable_unprepare(tmdev->bus_clk);
assert_reset:
reset_control_assert(tmdev->reset);
return ret;
}
static int sun8i_h3_thermal_init(struct ths_device *tmdev)
@ -475,9 +468,7 @@ static int sun8i_ths_register(struct ths_device *tmdev)
if (IS_ERR(tmdev->sensor[i].tzd))
return PTR_ERR(tmdev->sensor[i].tzd);
if (devm_thermal_add_hwmon_sysfs(tmdev->dev, tmdev->sensor[i].tzd))
dev_warn(tmdev->dev,
"Failed to add hwmon sysfs attributes\n");
devm_thermal_add_hwmon_sysfs(tmdev->dev, tmdev->sensor[i].tzd);
}
return 0;
@ -530,17 +521,6 @@ static int sun8i_ths_probe(struct platform_device *pdev)
return 0;
}
static int sun8i_ths_remove(struct platform_device *pdev)
{
struct ths_device *tmdev = platform_get_drvdata(pdev);
clk_disable_unprepare(tmdev->mod_clk);
clk_disable_unprepare(tmdev->bus_clk);
reset_control_assert(tmdev->reset);
return 0;
}
static const struct ths_thermal_chip sun8i_a83t_ths = {
.sensor_num = 3,
.scale = 705,
@ -642,7 +622,6 @@ MODULE_DEVICE_TABLE(of, of_ths_match);
static struct platform_driver ths_driver = {
.probe = sun8i_ths_probe,
.remove = sun8i_ths_remove,
.driver = {
.name = "sun8i-thermal",
.of_match_table = of_ths_match,

View File

@ -523,8 +523,7 @@ static int tegra_tsensor_register_channel(struct tegra_tsensor *ts,
return 0;
}
if (devm_thermal_add_hwmon_sysfs(ts->dev, tsc->tzd))
dev_warn(ts->dev, "failed to add hwmon sysfs attributes\n");
devm_thermal_add_hwmon_sysfs(ts->dev, tsc->tzd);
return 0;
}

View File

@ -13,6 +13,8 @@
#include <linux/slab.h>
#include <linux/thermal.h>
#include "thermal_hwmon.h"
struct gadc_thermal_info {
struct device *dev;
struct thermal_zone_device *tz_dev;
@ -153,6 +155,8 @@ static int gadc_thermal_probe(struct platform_device *pdev)
return ret;
}
devm_thermal_add_hwmon_sysfs(&pdev->dev, gti->tz_dev);
return 0;
}

View File

@ -23,6 +23,8 @@
#define DEFAULT_THERMAL_GOVERNOR "user_space"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR)
#define DEFAULT_THERMAL_GOVERNOR "power_allocator"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_BANG_BANG)
#define DEFAULT_THERMAL_GOVERNOR "bang_bang"
#endif
/* Initial state of a cooling device during binding */

View File

@ -271,11 +271,14 @@ int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device
ptr = devres_alloc(devm_thermal_hwmon_release, sizeof(*ptr),
GFP_KERNEL);
if (!ptr)
if (!ptr) {
dev_warn(dev, "Failed to allocate device resource data\n");
return -ENOMEM;
}
ret = thermal_add_hwmon_sysfs(tz);
if (ret) {
dev_warn(dev, "Failed to add hwmon sysfs attributes\n");
devres_free(ptr);
return ret;
}

View File

@ -182,8 +182,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
ti_bandgap_write_update_interval(bgp, data->sensor_id,
TI_BANDGAP_UPDATE_INTERVAL_MS);
if (devm_thermal_add_hwmon_sysfs(bgp->dev, data->ti_thermal))
dev_warn(bgp->dev, "failed to add hwmon sysfs attributes\n");
devm_thermal_add_hwmon_sysfs(bgp->dev, data->ti_thermal);
return 0;
}