mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'thermal-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull thermal control updates from Rafael Wysocki:
"These extend the int340x thermal driver, add thermal DT bindings for
some Qcom platforms, add DT bindings and support for Armada AP807 and
MSM8909, allow selecting the bang-bang thermal governor as the default
one, address issues in several thermal drivers for ARM platforms and
clean up code.
Specifics:
- Add new IOCTLs to the int340x thermal driver to allow user space to
retrieve the Passive v2 thermal table (Srinivas Pandruvada)
- 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)
- Clean up and fix 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-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (39 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:
@@ -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
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
@@ -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>;
|
||||
};
|
||||
@@ -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:
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -203,6 +203,151 @@ end:
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_parse_art);
|
||||
|
||||
/*
|
||||
* acpi_parse_psvt - Passive Table (PSVT) for passive cooling
|
||||
*
|
||||
* @handle: ACPI handle of the device which contains PSVT
|
||||
* @psvt_count: the number of valid entries resulted from parsing PSVT
|
||||
* @psvtp: pointer to array of psvt entries
|
||||
*
|
||||
*/
|
||||
static int acpi_parse_psvt(acpi_handle handle, int *psvt_count, struct psvt **psvtp)
|
||||
{
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
int nr_bad_entries = 0, revision = 0;
|
||||
union acpi_object *p;
|
||||
acpi_status status;
|
||||
int i, result = 0;
|
||||
struct psvt *psvts;
|
||||
|
||||
if (!acpi_has_method(handle, "PSVT"))
|
||||
return -ENODEV;
|
||||
|
||||
status = acpi_evaluate_object(handle, "PSVT", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
p = buffer.pointer;
|
||||
if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
|
||||
result = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* first package is the revision number */
|
||||
if (p->package.count > 0) {
|
||||
union acpi_object *prev = &(p->package.elements[0]);
|
||||
|
||||
if (prev->type == ACPI_TYPE_INTEGER)
|
||||
revision = (int)prev->integer.value;
|
||||
} else {
|
||||
result = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Support only version 2 */
|
||||
if (revision != 2) {
|
||||
result = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
*psvt_count = p->package.count - 1;
|
||||
if (!*psvt_count) {
|
||||
result = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
psvts = kcalloc(*psvt_count, sizeof(*psvts), GFP_KERNEL);
|
||||
if (!psvts) {
|
||||
result = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Start index is 1 because the first package is the revision number */
|
||||
for (i = 1; i < p->package.count; i++) {
|
||||
struct acpi_buffer psvt_int_format = { sizeof("RRNNNNNNNNNN"), "RRNNNNNNNNNN" };
|
||||
struct acpi_buffer psvt_str_format = { sizeof("RRNNNNNSNNNN"), "RRNNNNNSNNNN" };
|
||||
union acpi_object *package = &(p->package.elements[i]);
|
||||
struct psvt *psvt = &psvts[i - 1 - nr_bad_entries];
|
||||
struct acpi_buffer *psvt_format = &psvt_int_format;
|
||||
struct acpi_buffer element = { 0, NULL };
|
||||
union acpi_object *knob;
|
||||
struct acpi_device *res;
|
||||
struct psvt *psvt_ptr;
|
||||
|
||||
element.length = ACPI_ALLOCATE_BUFFER;
|
||||
element.pointer = NULL;
|
||||
|
||||
if (package->package.count >= ACPI_NR_PSVT_ELEMENTS) {
|
||||
knob = &(package->package.elements[ACPI_PSVT_CONTROL_KNOB]);
|
||||
} else {
|
||||
nr_bad_entries++;
|
||||
pr_info("PSVT package %d is invalid, ignored\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (knob->type == ACPI_TYPE_STRING) {
|
||||
psvt_format = &psvt_str_format;
|
||||
if (knob->string.length > ACPI_LIMIT_STR_MAX_LEN - 1) {
|
||||
pr_info("PSVT package %d limit string len exceeds max\n", i);
|
||||
knob->string.length = ACPI_LIMIT_STR_MAX_LEN - 1;
|
||||
}
|
||||
}
|
||||
|
||||
status = acpi_extract_package(&(p->package.elements[i]), psvt_format, &element);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
nr_bad_entries++;
|
||||
pr_info("PSVT package %d is invalid, ignored\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
psvt_ptr = (struct psvt *)element.pointer;
|
||||
|
||||
memcpy(psvt, psvt_ptr, sizeof(*psvt));
|
||||
|
||||
/* The limit element can be string or U64 */
|
||||
psvt->control_knob_type = (u64)knob->type;
|
||||
|
||||
if (knob->type == ACPI_TYPE_STRING) {
|
||||
memset(&psvt->limit, 0, sizeof(u64));
|
||||
strncpy(psvt->limit.string, psvt_ptr->limit.str_ptr, knob->string.length);
|
||||
} else {
|
||||
psvt->limit.integer = psvt_ptr->limit.integer;
|
||||
}
|
||||
|
||||
kfree(element.pointer);
|
||||
|
||||
res = acpi_fetch_acpi_dev(psvt->source);
|
||||
if (!res) {
|
||||
nr_bad_entries++;
|
||||
pr_info("Failed to get source ACPI device\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
res = acpi_fetch_acpi_dev(psvt->target);
|
||||
if (!res) {
|
||||
nr_bad_entries++;
|
||||
pr_info("Failed to get target ACPI device\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* don't count bad entries */
|
||||
*psvt_count -= nr_bad_entries;
|
||||
|
||||
if (!*psvt_count) {
|
||||
result = -EFAULT;
|
||||
kfree(psvts);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*psvtp = psvts;
|
||||
|
||||
return 0;
|
||||
|
||||
end:
|
||||
kfree(buffer.pointer);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* get device name from acpi handle */
|
||||
static void get_single_name(acpi_handle handle, char *name)
|
||||
@@ -289,6 +434,57 @@ free_trt:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fill_psvt(char __user *ubuf)
|
||||
{
|
||||
int i, ret, count, psvt_len;
|
||||
union psvt_object *psvt_user;
|
||||
struct psvt *psvts;
|
||||
|
||||
ret = acpi_parse_psvt(acpi_thermal_rel_handle, &count, &psvts);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
psvt_len = count * sizeof(*psvt_user);
|
||||
|
||||
psvt_user = kzalloc(psvt_len, GFP_KERNEL);
|
||||
if (!psvt_user) {
|
||||
ret = -ENOMEM;
|
||||
goto free_psvt;
|
||||
}
|
||||
|
||||
/* now fill in user psvt data */
|
||||
for (i = 0; i < count; i++) {
|
||||
/* userspace psvt needs device name instead of acpi reference */
|
||||
get_single_name(psvts[i].source, psvt_user[i].source_device);
|
||||
get_single_name(psvts[i].target, psvt_user[i].target_device);
|
||||
|
||||
psvt_user[i].priority = psvts[i].priority;
|
||||
psvt_user[i].sample_period = psvts[i].sample_period;
|
||||
psvt_user[i].passive_temp = psvts[i].passive_temp;
|
||||
psvt_user[i].source_domain = psvts[i].source_domain;
|
||||
psvt_user[i].control_knob = psvts[i].control_knob;
|
||||
psvt_user[i].step_size = psvts[i].step_size;
|
||||
psvt_user[i].limit_coeff = psvts[i].limit_coeff;
|
||||
psvt_user[i].unlimit_coeff = psvts[i].unlimit_coeff;
|
||||
psvt_user[i].control_knob_type = psvts[i].control_knob_type;
|
||||
if (psvt_user[i].control_knob_type == ACPI_TYPE_STRING)
|
||||
strncpy(psvt_user[i].limit.string, psvts[i].limit.string,
|
||||
ACPI_LIMIT_STR_MAX_LEN);
|
||||
else
|
||||
psvt_user[i].limit.integer = psvts[i].limit.integer;
|
||||
|
||||
}
|
||||
|
||||
if (copy_to_user(ubuf, psvt_user, psvt_len))
|
||||
ret = -EFAULT;
|
||||
|
||||
kfree(psvt_user);
|
||||
|
||||
free_psvt:
|
||||
kfree(psvts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd,
|
||||
unsigned long __arg)
|
||||
{
|
||||
@@ -298,6 +494,7 @@ static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd,
|
||||
char __user *arg = (void __user *)__arg;
|
||||
struct trt *trts = NULL;
|
||||
struct art *arts = NULL;
|
||||
struct psvt *psvts;
|
||||
|
||||
switch (cmd) {
|
||||
case ACPI_THERMAL_GET_TRT_COUNT:
|
||||
@@ -336,6 +533,27 @@ static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd,
|
||||
case ACPI_THERMAL_GET_ART:
|
||||
return fill_art(arg);
|
||||
|
||||
case ACPI_THERMAL_GET_PSVT_COUNT:
|
||||
ret = acpi_parse_psvt(acpi_thermal_rel_handle, &count, &psvts);
|
||||
if (!ret) {
|
||||
kfree(psvts);
|
||||
return put_user(count, (unsigned long __user *)__arg);
|
||||
}
|
||||
return ret;
|
||||
|
||||
case ACPI_THERMAL_GET_PSVT_LEN:
|
||||
/* total length of the data retrieved (count * PSVT entry size) */
|
||||
ret = acpi_parse_psvt(acpi_thermal_rel_handle, &count, &psvts);
|
||||
length = count * sizeof(union psvt_object);
|
||||
if (!ret) {
|
||||
kfree(psvts);
|
||||
return put_user(length, (unsigned long __user *)__arg);
|
||||
}
|
||||
return ret;
|
||||
|
||||
case ACPI_THERMAL_GET_PSVT:
|
||||
return fill_psvt(arg);
|
||||
|
||||
default:
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,16 @@
|
||||
#define ACPI_THERMAL_GET_TRT _IOR(ACPI_THERMAL_MAGIC, 5, unsigned long)
|
||||
#define ACPI_THERMAL_GET_ART _IOR(ACPI_THERMAL_MAGIC, 6, unsigned long)
|
||||
|
||||
/*
|
||||
* ACPI_THERMAL_GET_PSVT_COUNT = Number of PSVT entries
|
||||
* ACPI_THERMAL_GET_PSVT_LEN = Total return data size (PSVT count x each
|
||||
* PSVT entry size)
|
||||
* ACPI_THERMAL_GET_PSVT = Get the data as an array of psvt_objects
|
||||
*/
|
||||
#define ACPI_THERMAL_GET_PSVT_LEN _IOR(ACPI_THERMAL_MAGIC, 7, unsigned long)
|
||||
#define ACPI_THERMAL_GET_PSVT_COUNT _IOR(ACPI_THERMAL_MAGIC, 8, unsigned long)
|
||||
#define ACPI_THERMAL_GET_PSVT _IOR(ACPI_THERMAL_MAGIC, 9, unsigned long)
|
||||
|
||||
struct art {
|
||||
acpi_handle source;
|
||||
acpi_handle target;
|
||||
@@ -43,6 +53,32 @@ struct trt {
|
||||
u64 reserved4;
|
||||
} __packed;
|
||||
|
||||
#define ACPI_NR_PSVT_ELEMENTS 12
|
||||
#define ACPI_PSVT_CONTROL_KNOB 7
|
||||
#define ACPI_LIMIT_STR_MAX_LEN 8
|
||||
|
||||
struct psvt {
|
||||
acpi_handle source;
|
||||
acpi_handle target;
|
||||
u64 priority;
|
||||
u64 sample_period;
|
||||
u64 passive_temp;
|
||||
u64 source_domain;
|
||||
u64 control_knob;
|
||||
union {
|
||||
/* For limit_type = ACPI_TYPE_INTEGER */
|
||||
u64 integer;
|
||||
/* For limit_type = ACPI_TYPE_STRING */
|
||||
char string[ACPI_LIMIT_STR_MAX_LEN];
|
||||
char *str_ptr;
|
||||
} limit;
|
||||
u64 step_size;
|
||||
u64 limit_coeff;
|
||||
u64 unlimit_coeff;
|
||||
/* Spec calls this field reserved, so we borrow it for type info */
|
||||
u64 control_knob_type; /* ACPI_TYPE_STRING or ACPI_TYPE_INTEGER */
|
||||
} __packed;
|
||||
|
||||
#define ACPI_NR_ART_ELEMENTS 13
|
||||
/* for usrspace */
|
||||
union art_object {
|
||||
@@ -77,6 +113,27 @@ union trt_object {
|
||||
u64 __data[8];
|
||||
};
|
||||
|
||||
union psvt_object {
|
||||
struct {
|
||||
char source_device[8];
|
||||
char target_device[8];
|
||||
u64 priority;
|
||||
u64 sample_period;
|
||||
u64 passive_temp;
|
||||
u64 source_domain;
|
||||
u64 control_knob;
|
||||
union {
|
||||
u64 integer;
|
||||
char string[ACPI_LIMIT_STR_MAX_LEN];
|
||||
} limit;
|
||||
u64 step_size;
|
||||
u64 limit_coeff;
|
||||
u64 unlimit_coeff;
|
||||
u64 control_knob_type;
|
||||
};
|
||||
u64 __data[ACPI_NR_PSVT_ELEMENTS];
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
int acpi_thermal_rel_misc_device_add(acpi_handle handle);
|
||||
int acpi_thermal_rel_misc_device_remove(acpi_handle handle);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user