Commit 0ca4080a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'thermal-6.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more thermal control updates from Rafael Wysocki:
 "These are mostly updates of thermal control drivers for ARM platforms,
  new thermal control support for Loongson-2 and a couple of core
  cleanups made possible by recent changes merged previously.

  Specifics:

   - Check if the Tegra BPMP supports the trip points in order to set
     the .set_trips callback (Mikko Perttunen)

   - Add new Loongson-2 thermal sensor along with the DT bindings (Yinbo
     Zhu)

   - Use IS_ERR_OR_NULL() helper to replace a double test on the TI
     bandgap sensor (Li Zetao)

   - Remove redundant platform_set_drvdata() calls, as there are no
     corresponding calls to platform_get_drvdata(), from a bunch of
     drivers (Andrei Coardos)

   - Switch the Mediatek LVTS mode to filtered in order to enable
     interrupts (Nícolas F. R. A. Prado)

   - Fix Wvoid-pointer-to-enum-cast warning on the Exynos TMU (Krzysztof
     Kozlowski)

   - Remove redundant dev_err_probe(), because the underlying function
     already called it, from the Mediatek sensor (Chen Jiahao)

   - Free calibration nvmem after reading it on sun8i (Mark Brown)

   - Remove useless comment from the sun8i driver (Yangtao Li)

   - Make tsens_xxxx_nvmem static to fix a sparse warning on QCom tsens
     (Min-Hua Chen)

   - Remove error message at probe deferral on imx8mm (Ahmad Fatoum)

   - Fix parameter check in lvts_debugfs_init() with IS_ERR() on
     Mediatek LVTS (Minjie Du)

   - Fix interrupt routine and configuratoin for Mediatek LVTS (Nícolas
     F. R. A. Prado)

   - Drop unused .get_trip_type(), .get_trip_temp() and .get_trip_hyst()
     thermal zone callbacks from the core and rework the .get_trend()
     one to take a trip point pointer as an argument (Rafael Wysocki)"

* tag 'thermal-6.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (29 commits)
  thermal: core: Rework .get_trend() thermal zone callback
  thermal: core: Drop unused .get_trip_*() callbacks
  thermal/drivers/tegra-bpmp: Check if BPMP supports trip points
  thermal: dt-bindings: add loongson-2 thermal
  thermal/drivers/loongson-2: Add thermal management support
  thermal/drivers/ti-soc-thermal: Use helper function IS_ERR_OR_NULL()
  thermal/drivers/generic-adc: Removed unneeded call to platform_set_drvdata()
  thermal/drivers/max77620_thermal: Removed unneeded call to platform_set_drvdata()
  thermal/drivers/mediatek/auxadc_thermal: Removed call to platform_set_drvdata()
  thermal/drivers/sun8i_thermal: Remove unneeded call to platform_set_drvdata()
  thermal/drivers/broadcom/brcstb_thermal: Removed unneeded platform_set_drvdata()
  thermal/drivers/mediatek/lvts_thermal: Make readings valid in filtered mode
  thermal/drivers/k3_bandgap: Remove unneeded call to platform_set_drvdata()
  thermal/drivers/k3_j72xx_bandgap: Removed unneeded call to platform_set_drvdata()
  thermal/drivers/broadcom/sr-thermal: Removed call to platform_set_drvdata()
  thermal/drivers/samsung: Fix Wvoid-pointer-to-enum-cast warning
  thermal/drivers/db8500: Remove redundant of_match_ptr()
  thermal/drivers/mediatek: Clean up redundant dev_err_probe()
  thermal/drivers/sun8i: Free calibration nvmem after reading it
  thermal/drivers/sun8i: Remove unneeded comments
  ...
parents 2a3a850e 8289d810
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/thermal/loongson,ls2k-thermal.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Thermal sensors on Loongson-2 SoCs
maintainers:
- zhanghongchen <zhanghongchen@loongson.cn>
- Yinbo Zhu <zhuyinbo@loongson.cn>
properties:
compatible:
oneOf:
- enum:
- loongson,ls2k1000-thermal
- items:
- enum:
- loongson,ls2k2000-thermal
- const: loongson,ls2k1000-thermal
reg:
maxItems: 1
interrupts:
maxItems: 1
required:
- compatible
- reg
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
thermal: thermal-sensor@1fe01500 {
compatible = "loongson,ls2k1000-thermal";
reg = <0x1fe01500 0x30>;
interrupt-parent = <&liointc0>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
};
...@@ -12390,6 +12390,14 @@ S: Maintained ...@@ -12390,6 +12390,14 @@ S: Maintained
F: Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml F: Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
F: drivers/pinctrl/pinctrl-loongson2.c F: drivers/pinctrl/pinctrl-loongson2.c
LOONGSON-2 SOC SERIES THERMAL DRIVER
M: zhanghongchen <zhanghongchen@loongson.cn>
M: Yinbo Zhu <zhuyinbo@loongson.cn>
L: linux-pm@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml
F: drivers/thermal/loongson2_thermal.c
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
M: Sathya Prakash <sathya.prakash@broadcom.com> M: Sathya Prakash <sathya.prakash@broadcom.com>
M: Sreekanth Reddy <sreekanth.reddy@broadcom.com> M: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
......
...@@ -492,26 +492,22 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) ...@@ -492,26 +492,22 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp)
} }
static int thermal_get_trend(struct thermal_zone_device *thermal, static int thermal_get_trend(struct thermal_zone_device *thermal,
int trip_index, enum thermal_trend *trend) struct thermal_trip *trip,
enum thermal_trend *trend)
{ {
struct acpi_thermal *tz = thermal_zone_device_priv(thermal); struct acpi_thermal *tz = thermal_zone_device_priv(thermal);
struct acpi_thermal_trip *acpi_trip; struct acpi_thermal_trip *acpi_trip;
int t, i; int t;
if (!tz || trip_index < 0) if (!tz || !trip)
return -EINVAL; return -EINVAL;
if (tz->trips.critical.valid) acpi_trip = trip->priv;
trip_index--; if (!acpi_trip || !acpi_trip->valid)
if (tz->trips.hot.valid)
trip_index--;
if (trip_index < 0)
return -EINVAL; return -EINVAL;
acpi_trip = &tz->trips.passive.trip; switch (trip->type) {
if (acpi_trip->valid && !trip_index--) { case THERMAL_TRIP_PASSIVE:
t = tz->trips.passive.tc1 * (tz->temperature - t = tz->trips.passive.tc1 * (tz->temperature -
tz->last_temperature) + tz->last_temperature) +
tz->trips.passive.tc2 * (tz->temperature - tz->trips.passive.tc2 * (tz->temperature -
...@@ -524,19 +520,18 @@ static int thermal_get_trend(struct thermal_zone_device *thermal, ...@@ -524,19 +520,18 @@ static int thermal_get_trend(struct thermal_zone_device *thermal,
*trend = THERMAL_TREND_STABLE; *trend = THERMAL_TREND_STABLE;
return 0; return 0;
}
t = acpi_thermal_temp(tz, tz->temperature);
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { case THERMAL_TRIP_ACTIVE:
acpi_trip = &tz->trips.active[i].trip; t = acpi_thermal_temp(tz, tz->temperature);
if (acpi_trip->valid && !trip_index--) { if (t <= trip->temperature)
if (t > acpi_thermal_temp(tz, acpi_trip->temperature)) {
*trend = THERMAL_TREND_RAISING;
return 0;
}
break; break;
}
*trend = THERMAL_TREND_RAISING;
return 0;
default:
break;
} }
return -EINVAL; return -EINVAL;
......
...@@ -510,4 +510,16 @@ config KHADAS_MCU_FAN_THERMAL ...@@ -510,4 +510,16 @@ config KHADAS_MCU_FAN_THERMAL
If you say yes here you get support for the FAN controlled If you say yes here you get support for the FAN controlled
by the Microcontroller found on the Khadas VIM boards. by the Microcontroller found on the Khadas VIM boards.
config LOONGSON2_THERMAL
tristate "Loongson-2 SoC series thermal driver"
depends on LOONGARCH || COMPILE_TEST
depends on OF
help
Support for Thermal driver found on Loongson-2 SoC series platforms.
The thermal driver realizes get_temp and set_trips function, which
are used to obtain the temperature of the current node and set the
temperature range to trigger the interrupt. When the input temperature
is higher than the high temperature threshold or lower than the low
temperature threshold, the interrupt will occur.
endif endif
...@@ -63,3 +63,4 @@ obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o ...@@ -63,3 +63,4 @@ obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o
obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o
obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) += khadas_mcu_fan.o obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) += khadas_mcu_fan.o
obj-$(CONFIG_LOONGSON2_THERMAL) += loongson2_thermal.o
...@@ -334,7 +334,6 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) ...@@ -334,7 +334,6 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
return PTR_ERR(priv->tmon_base); return PTR_ERR(priv->tmon_base);
priv->dev = &pdev->dev; priv->dev = &pdev->dev;
platform_set_drvdata(pdev, priv);
of_ops = priv->temp_params->of_ops; of_ops = priv->temp_params->of_ops;
thermal = devm_thermal_of_zone_register(&pdev->dev, 0, priv, thermal = devm_thermal_of_zone_register(&pdev->dev, 0, priv,
......
...@@ -91,7 +91,6 @@ static int sr_thermal_probe(struct platform_device *pdev) ...@@ -91,7 +91,6 @@ static int sr_thermal_probe(struct platform_device *pdev)
dev_dbg(dev, "thermal sensor %d registered\n", i); dev_dbg(dev, "thermal sensor %d registered\n", i);
} }
platform_set_drvdata(pdev, sr_thermal);
return 0; return 0;
} }
......
...@@ -229,7 +229,7 @@ MODULE_DEVICE_TABLE(of, db8500_thermal_match); ...@@ -229,7 +229,7 @@ MODULE_DEVICE_TABLE(of, db8500_thermal_match);
static struct platform_driver db8500_thermal_driver = { static struct platform_driver db8500_thermal_driver = {
.driver = { .driver = {
.name = "db8500-thermal", .name = "db8500-thermal",
.of_match_table = of_match_ptr(db8500_thermal_match), .of_match_table = db8500_thermal_match,
}, },
.probe = db8500_thermal_probe, .probe = db8500_thermal_probe,
.suspend = db8500_thermal_suspend, .suspend = db8500_thermal_suspend,
......
...@@ -178,10 +178,8 @@ static int imx8mm_tmu_probe_set_calib_v1(struct platform_device *pdev, ...@@ -178,10 +178,8 @@ static int imx8mm_tmu_probe_set_calib_v1(struct platform_device *pdev,
int ret; int ret;
ret = nvmem_cell_read_u32(&pdev->dev, "calib", &ana0); ret = nvmem_cell_read_u32(&pdev->dev, "calib", &ana0);
if (ret) { if (ret)
dev_warn(dev, "Failed to read OCOTP nvmem cell (%d).\n", ret); return dev_err_probe(dev, ret, "Failed to read OCOTP nvmem cell\n");
return ret;
}
writel(FIELD_PREP(TASR_BUF_VREF_MASK, writel(FIELD_PREP(TASR_BUF_VREF_MASK,
FIELD_GET(ANA0_BUF_VREF_MASK, ana0)) | FIELD_GET(ANA0_BUF_VREF_MASK, ana0)) |
......
...@@ -225,7 +225,6 @@ static int k3_bandgap_probe(struct platform_device *pdev) ...@@ -225,7 +225,6 @@ static int k3_bandgap_probe(struct platform_device *pdev)
devm_thermal_add_hwmon_sysfs(dev, data[id].tzd); devm_thermal_add_hwmon_sysfs(dev, data[id].tzd);
} }
platform_set_drvdata(pdev, bgp);
return 0; return 0;
......
...@@ -502,8 +502,6 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev) ...@@ -502,8 +502,6 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
writel(K3_VTM_ANYMAXT_OUTRG_ALERT_EN, data[0].bgp->cfg2_base + writel(K3_VTM_ANYMAXT_OUTRG_ALERT_EN, data[0].bgp->cfg2_base +
K3_VTM_MISC_CTRL_OFFSET); K3_VTM_MISC_CTRL_OFFSET);
platform_set_drvdata(pdev, bgp);
print_look_up_table(dev, ref_table); print_look_up_table(dev, ref_table);
/* /*
* Now that the derived_table has the appropriate look up values * Now that the derived_table has the appropriate look up values
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Author: zhanghongchen <zhanghongchen@loongson.cn>
* Yinbo Zhu <zhuyinbo@loongson.cn>
* Copyright (C) 2022-2023 Loongson Technology Corporation Limited
*/
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
#include <linux/units.h>
#include "thermal_hwmon.h"
#define LOONGSON2_MAX_SENSOR_SEL_NUM 3
#define LOONGSON2_THSENS_CTRL_HI_REG 0x0
#define LOONGSON2_THSENS_CTRL_LOW_REG 0x8
#define LOONGSON2_THSENS_STATUS_REG 0x10
#define LOONGSON2_THSENS_OUT_REG 0x14
#define LOONGSON2_THSENS_INT_LO BIT(0)
#define LOONGSON2_THSENS_INT_HIGH BIT(1)
#define LOONGSON2_THSENS_OUT_MASK 0xFF
struct loongson2_thermal_chip_data {
unsigned int thermal_sensor_sel;
};
struct loongson2_thermal_data {
void __iomem *regs;
const struct loongson2_thermal_chip_data *chip_data;
};
static int loongson2_thermal_set(struct loongson2_thermal_data *data,
int low, int high, bool enable)
{
u64 reg_ctrl = 0;
int reg_off = data->chip_data->thermal_sensor_sel * 2;
low = clamp(-40, low, high);
high = clamp(125, low, high);
low += HECTO;
high += HECTO;
reg_ctrl = low;
reg_ctrl |= enable ? 0x100 : 0;
writew(reg_ctrl, data->regs + LOONGSON2_THSENS_CTRL_LOW_REG + reg_off);
reg_ctrl = high;
reg_ctrl |= enable ? 0x100 : 0;
writew(reg_ctrl, data->regs + LOONGSON2_THSENS_CTRL_HI_REG + reg_off);
return 0;
}
static int loongson2_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
{
u32 reg_val;
struct loongson2_thermal_data *data = thermal_zone_device_priv(tz);
reg_val = readl(data->regs + LOONGSON2_THSENS_OUT_REG);
*temp = ((reg_val & LOONGSON2_THSENS_OUT_MASK) - HECTO) * KILO;
return 0;
}
static irqreturn_t loongson2_thermal_irq_thread(int irq, void *dev)
{
struct thermal_zone_device *tzd = dev;
struct loongson2_thermal_data *data = thermal_zone_device_priv(tzd);
writeb(LOONGSON2_THSENS_INT_LO | LOONGSON2_THSENS_INT_HIGH, data->regs +
LOONGSON2_THSENS_STATUS_REG);
thermal_zone_device_update(tzd, THERMAL_EVENT_UNSPECIFIED);
return IRQ_HANDLED;
}
static int loongson2_thermal_set_trips(struct thermal_zone_device *tz, int low, int high)
{
struct loongson2_thermal_data *data = thermal_zone_device_priv(tz);
return loongson2_thermal_set(data, low/MILLI, high/MILLI, true);
}
static const struct thermal_zone_device_ops loongson2_of_thermal_ops = {
.get_temp = loongson2_thermal_get_temp,
.set_trips = loongson2_thermal_set_trips,
};
static int loongson2_thermal_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct loongson2_thermal_data *data;
struct thermal_zone_device *tzd;
int ret, irq, i;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->chip_data = device_get_match_data(dev);
data->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->regs))
return PTR_ERR(data->regs);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
writeb(LOONGSON2_THSENS_INT_LO | LOONGSON2_THSENS_INT_HIGH, data->regs +
LOONGSON2_THSENS_STATUS_REG);
loongson2_thermal_set(data, 0, 0, false);
for (i = 0; i <= LOONGSON2_MAX_SENSOR_SEL_NUM; i++) {
tzd = devm_thermal_of_zone_register(dev, i, data,
&loongson2_of_thermal_ops);
if (!IS_ERR(tzd))
break;
if (PTR_ERR(tzd) != ENODEV)
continue;
return dev_err_probe(dev, PTR_ERR(tzd), "failed to register");
}
ret = devm_request_threaded_irq(dev, irq, NULL, loongson2_thermal_irq_thread,
IRQF_ONESHOT, "loongson2_thermal", tzd);
if (ret < 0)
return dev_err_probe(dev, ret, "failed to request alarm irq\n");
devm_thermal_add_hwmon_sysfs(dev, tzd);
return 0;
}
static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k1000_data = {
.thermal_sensor_sel = 0,
};
static const struct of_device_id of_loongson2_thermal_match[] = {
{
.compatible = "loongson,ls2k1000-thermal",
.data = &loongson2_thermal_ls2k1000_data,
},
{ /* end */ }
};
MODULE_DEVICE_TABLE(of, of_loongson2_thermal_match);
static struct platform_driver loongson2_thermal_driver = {
.driver = {
.name = "loongson2_thermal",
.of_match_table = of_loongson2_thermal_match,
},
.probe = loongson2_thermal_probe,
};
module_platform_driver(loongson2_thermal_driver);
MODULE_DESCRIPTION("Loongson2 thermal driver");
MODULE_LICENSE("GPL");
...@@ -139,8 +139,6 @@ static int max77620_thermal_probe(struct platform_device *pdev) ...@@ -139,8 +139,6 @@ static int max77620_thermal_probe(struct platform_device *pdev)
return ret; return ret;
} }
platform_set_drvdata(pdev, mtherm);
return 0; return 0;
} }
......
...@@ -1282,8 +1282,6 @@ static int mtk_thermal_probe(struct platform_device *pdev) ...@@ -1282,8 +1282,6 @@ static int mtk_thermal_probe(struct platform_device *pdev)
mtk_thermal_init_bank(mt, i, apmixed_phys_base, mtk_thermal_init_bank(mt, i, apmixed_phys_base,
auxadc_phys_base, ctrl_id); auxadc_phys_base, ctrl_id);
platform_set_drvdata(pdev, mt);
tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt, tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
&mtk_thermal_ops); &mtk_thermal_ops);
if (IS_ERR(tzdev)) if (IS_ERR(tzdev))
......
...@@ -58,14 +58,19 @@ ...@@ -58,14 +58,19 @@
#define LVTS_PROTTC(__base) (__base + 0x00CC) #define LVTS_PROTTC(__base) (__base + 0x00CC)
#define LVTS_CLKEN(__base) (__base + 0x00E4) #define LVTS_CLKEN(__base) (__base + 0x00E4)
#define LVTS_PERIOD_UNIT ((118 * 1000) / (256 * 38)) #define LVTS_PERIOD_UNIT 0
#define LVTS_GROUP_INTERVAL 1 #define LVTS_GROUP_INTERVAL 0
#define LVTS_FILTER_INTERVAL 1 #define LVTS_FILTER_INTERVAL 0
#define LVTS_SENSOR_INTERVAL 1 #define LVTS_SENSOR_INTERVAL 0
#define LVTS_HW_FILTER 0x2 #define LVTS_HW_FILTER 0x0
#define LVTS_TSSEL_CONF 0x13121110 #define LVTS_TSSEL_CONF 0x13121110
#define LVTS_CALSCALE_CONF 0x300 #define LVTS_CALSCALE_CONF 0x300
#define LVTS_MONINT_CONF 0x9FBF7BDE #define LVTS_MONINT_CONF 0x8300318C
#define LVTS_MONINT_OFFSET_SENSOR0 0xC
#define LVTS_MONINT_OFFSET_SENSOR1 0x180
#define LVTS_MONINT_OFFSET_SENSOR2 0x3000
#define LVTS_MONINT_OFFSET_SENSOR3 0x3000000
#define LVTS_INT_SENSOR0 0x0009001F #define LVTS_INT_SENSOR0 0x0009001F
#define LVTS_INT_SENSOR1 0x001203E0 #define LVTS_INT_SENSOR1 0x001203E0
...@@ -81,8 +86,13 @@ ...@@ -81,8 +86,13 @@
#define LVTS_MSR_IMMEDIATE_MODE 0 #define LVTS_MSR_IMMEDIATE_MODE 0
#define LVTS_MSR_FILTERED_MODE 1 #define LVTS_MSR_FILTERED_MODE 1
#define LVTS_MSR_READ_TIMEOUT_US 400
#define LVTS_MSR_READ_WAIT_US (LVTS_MSR_READ_TIMEOUT_US / 2)
#define LVTS_HW_SHUTDOWN_MT8195 105000 #define LVTS_HW_SHUTDOWN_MT8195 105000
#define LVTS_MINIMUM_THRESHOLD 20000
static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT; static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
static int coeff_b = LVTS_COEFF_B; static int coeff_b = LVTS_COEFF_B;
...@@ -110,6 +120,8 @@ struct lvts_sensor { ...@@ -110,6 +120,8 @@ struct lvts_sensor {
void __iomem *base; void __iomem *base;
int id; int id;
int dt_id; int dt_id;
int low_thresh;
int high_thresh;
}; };
struct lvts_ctrl { struct lvts_ctrl {
...@@ -119,6 +131,8 @@ struct lvts_ctrl { ...@@ -119,6 +131,8 @@ struct lvts_ctrl {
int num_lvts_sensor; int num_lvts_sensor;
int mode; int mode;
void __iomem *base; void __iomem *base;
int low_thresh;
int high_thresh;
}; };
struct lvts_domain { struct lvts_domain {
...@@ -190,7 +204,7 @@ static int lvts_debugfs_init(struct device *dev, struct lvts_domain *lvts_td) ...@@ -190,7 +204,7 @@ static int lvts_debugfs_init(struct device *dev, struct lvts_domain *lvts_td)
int i; int i;
lvts_td->dom_dentry = debugfs_create_dir(dev_name(dev), NULL); lvts_td->dom_dentry = debugfs_create_dir(dev_name(dev), NULL);
if (!lvts_td->dom_dentry) if (IS_ERR(lvts_td->dom_dentry))
return 0; return 0;
for (i = 0; i < lvts_td->num_lvts_ctrl; i++) { for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
...@@ -257,6 +271,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp) ...@@ -257,6 +271,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz); struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
void __iomem *msr = lvts_sensor->msr; void __iomem *msr = lvts_sensor->msr;
u32 value; u32 value;
int rc;
/* /*
* Measurement registers: * Measurement registers:
...@@ -269,7 +284,8 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp) ...@@ -269,7 +284,8 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
* 16 : Valid temperature * 16 : Valid temperature
* 15-0 : Raw temperature * 15-0 : Raw temperature
*/ */
value = readl(msr); rc = readl_poll_timeout(msr, value, value & BIT(16),
LVTS_MSR_READ_WAIT_US, LVTS_MSR_READ_TIMEOUT_US);
/* /*
* As the thermal zone temperature will read before the * As the thermal zone temperature will read before the
...@@ -282,7 +298,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp) ...@@ -282,7 +298,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
* functionning temperature and directly jump to a system * functionning temperature and directly jump to a system
* shutdown. * shutdown.
*/ */
if (!(value & BIT(16))) if (rc)
return -EAGAIN; return -EAGAIN;
*temp = lvts_raw_to_temp(value & 0xFFFF); *temp = lvts_raw_to_temp(value & 0xFFFF);
...@@ -290,32 +306,84 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp) ...@@ -290,32 +306,84 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
return 0; return 0;
} }
static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)
{
u32 masks[] = {
LVTS_MONINT_OFFSET_SENSOR0,
LVTS_MONINT_OFFSET_SENSOR1,
LVTS_MONINT_OFFSET_SENSOR2,
LVTS_MONINT_OFFSET_SENSOR3,
};
u32 value = 0;
int i;
value = readl(LVTS_MONINT(lvts_ctrl->base));
for (i = 0; i < ARRAY_SIZE(masks); i++) {
if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
&& lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
value |= masks[i];
else
value &= ~masks[i];
}
writel(value, LVTS_MONINT(lvts_ctrl->base));
}
static bool lvts_should_update_thresh(struct lvts_ctrl *lvts_ctrl, int high)
{
int i;
if (high > lvts_ctrl->high_thresh)
return true;
for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++)
if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
&& lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
return false;
return true;
}
static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
{ {
struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz); struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl, sensors[lvts_sensor->id]);
void __iomem *base = lvts_sensor->base; void __iomem *base = lvts_sensor->base;
u32 raw_low = lvts_temp_to_raw(low); u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD);
u32 raw_high = lvts_temp_to_raw(high); u32 raw_high = lvts_temp_to_raw(high);
bool should_update_thresh;
lvts_sensor->low_thresh = low;
lvts_sensor->high_thresh = high;
should_update_thresh = lvts_should_update_thresh(lvts_ctrl, high);
if (should_update_thresh) {
lvts_ctrl->high_thresh = high;
lvts_ctrl->low_thresh = low;
}
lvts_update_irq_mask(lvts_ctrl);
if (!should_update_thresh)
return 0;
/* /*
* Hot to normal temperature threshold * Low offset temperature threshold
* *
* LVTS_H2NTHRE * LVTS_OFFSETL
* *
* Bits: * Bits:
* *
* 14-0 : Raw temperature for threshold * 14-0 : Raw temperature for threshold
*/ */
if (low != -INT_MAX) { pr_debug("%s: Setting low limit temperature interrupt: %d\n",
pr_debug("%s: Setting low limit temperature interrupt: %d\n", thermal_zone_device_type(tz), low);
thermal_zone_device_type(tz), low); writel(raw_low, LVTS_OFFSETL(base));
writel(raw_low, LVTS_H2NTHRE(base));
}
/* /*
* Hot temperature threshold * High offset temperature threshold
* *
* LVTS_HTHRE * LVTS_OFFSETH
* *
* Bits: * Bits:
* *
...@@ -323,7 +391,7 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) ...@@ -323,7 +391,7 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
*/ */
pr_debug("%s: Setting high limit temperature interrupt: %d\n", pr_debug("%s: Setting high limit temperature interrupt: %d\n",
thermal_zone_device_type(tz), high); thermal_zone_device_type(tz), high);
writel(raw_high, LVTS_HTHRE(base)); writel(raw_high, LVTS_OFFSETH(base));
return 0; return 0;
} }
...@@ -451,7 +519,7 @@ static irqreturn_t lvts_irq_handler(int irq, void *data) ...@@ -451,7 +519,7 @@ static irqreturn_t lvts_irq_handler(int irq, void *data)
for (i = 0; i < lvts_td->num_lvts_ctrl; i++) { for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl); aux = lvts_ctrl_irq_handler(&lvts_td->lvts_ctrl[i]);
if (aux != IRQ_HANDLED) if (aux != IRQ_HANDLED)
continue; continue;
...@@ -521,6 +589,9 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl, ...@@ -521,6 +589,9 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
*/ */
lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ? lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
imm_regs[i] : msr_regs[i]; imm_regs[i] : msr_regs[i];
lvts_sensor[i].low_thresh = INT_MIN;
lvts_sensor[i].high_thresh = INT_MIN;
}; };
lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor; lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
...@@ -688,6 +759,9 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td, ...@@ -688,6 +759,9 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
*/ */
lvts_ctrl[i].hw_tshut_raw_temp = lvts_ctrl[i].hw_tshut_raw_temp =
lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp); lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp);
lvts_ctrl[i].low_thresh = INT_MIN;
lvts_ctrl[i].high_thresh = INT_MIN;
} }
/* /*
...@@ -896,24 +970,6 @@ static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl) ...@@ -896,24 +970,6 @@ static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl)
LVTS_HW_FILTER << 3 | LVTS_HW_FILTER; LVTS_HW_FILTER << 3 | LVTS_HW_FILTER;
writel(value, LVTS_MSRCTL0(lvts_ctrl->base)); writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
/*
* LVTS_MSRCTL1 : Measurement control
*
* Bits:
*
* 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
* 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
* 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
* 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
*
* That configuration will ignore the filtering and the delays
* introduced below in MONCTL1 and MONCTL2
*/
if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
value = BIT(9) | BIT(6) | BIT(5) | BIT(4);
writel(value, LVTS_MSRCTL1(lvts_ctrl->base));
}
/* /*
* LVTS_MONCTL1 : Period unit and group interval configuration * LVTS_MONCTL1 : Period unit and group interval configuration
* *
...@@ -979,6 +1035,15 @@ static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl) ...@@ -979,6 +1035,15 @@ static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
struct thermal_zone_device *tz; struct thermal_zone_device *tz;
u32 sensor_map = 0; u32 sensor_map = 0;
int i; int i;
/*
* Bitmaps to enable each sensor on immediate and filtered modes, as
* described in MSRCTL1 and MONCTL0 registers below, respectively.
*/
u32 sensor_imm_bitmap[] = { BIT(4), BIT(5), BIT(6), BIT(9) };
u32 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) };
u32 *sensor_bitmap = lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE ?
sensor_imm_bitmap : sensor_filt_bitmap;
for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) { for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
...@@ -1016,20 +1081,38 @@ static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl) ...@@ -1016,20 +1081,38 @@ static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
* map, so we can enable the temperature monitoring in * map, so we can enable the temperature monitoring in
* the hardware thermal controller. * the hardware thermal controller.
*/ */
sensor_map |= BIT(i); sensor_map |= sensor_bitmap[i];
} }
/* /*
* Bits:
* 9: Single point access flow
* 0-3: Enable sensing point 0-3
*
* The initialization of the thermal zones give us * The initialization of the thermal zones give us
* which sensor point to enable. If any thermal zone * which sensor point to enable. If any thermal zone
* was not described in the device tree, it won't be * was not described in the device tree, it won't be
* enabled here in the sensor map. * enabled here in the sensor map.
*/ */
writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base)); if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
/*
* LVTS_MSRCTL1 : Measurement control
*
* Bits:
*
* 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
* 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
* 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
* 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
*
* That configuration will ignore the filtering and the delays
* introduced in MONCTL1 and MONCTL2
*/
writel(sensor_map, LVTS_MSRCTL1(lvts_ctrl->base));
} else {
/*
* Bits:
* 9: Single point access flow
* 0-3: Enable sensing point 0-3
*/
writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
}
return 0; return 0;
} }
...@@ -1138,7 +1221,7 @@ static int lvts_probe(struct platform_device *pdev) ...@@ -1138,7 +1221,7 @@ static int lvts_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) if (irq < 0)
return dev_err_probe(dev, irq, "No irq resource\n"); return irq;
ret = lvts_domain_init(dev, lvts_td, lvts_data); ret = lvts_domain_init(dev, lvts_td, lvts_data);
if (ret) if (ret)
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#define BIT_APPEND 0x3 #define BIT_APPEND 0x3
struct tsens_legacy_calibration_format tsens_8916_nvmem = { static struct tsens_legacy_calibration_format tsens_8916_nvmem = {
.base_len = 7, .base_len = 7,
.base_shift = 3, .base_shift = 3,
.sp_len = 5, .sp_len = 5,
...@@ -39,7 +39,7 @@ struct tsens_legacy_calibration_format tsens_8916_nvmem = { ...@@ -39,7 +39,7 @@ struct tsens_legacy_calibration_format tsens_8916_nvmem = {
}, },
}; };
struct tsens_legacy_calibration_format tsens_8974_nvmem = { static struct tsens_legacy_calibration_format tsens_8974_nvmem = {
.base_len = 8, .base_len = 8,
.base_shift = 2, .base_shift = 2,
.sp_len = 6, .sp_len = 6,
...@@ -61,7 +61,7 @@ struct tsens_legacy_calibration_format tsens_8974_nvmem = { ...@@ -61,7 +61,7 @@ struct tsens_legacy_calibration_format tsens_8974_nvmem = {
}, },
}; };
struct tsens_legacy_calibration_format tsens_8974_backup_nvmem = { static struct tsens_legacy_calibration_format tsens_8974_backup_nvmem = {
.base_len = 8, .base_len = 8,
.base_shift = 2, .base_shift = 2,
.sp_len = 6, .sp_len = 6,
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#define TM_HIGH_LOW_INT_STATUS_OFF 0x0088 #define TM_HIGH_LOW_INT_STATUS_OFF 0x0088
#define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090 #define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090
struct tsens_legacy_calibration_format tsens_qcs404_nvmem = { static struct tsens_legacy_calibration_format tsens_qcs404_nvmem = {
.base_len = 8, .base_len = 8,
.base_shift = 2, .base_shift = 2,
.sp_len = 6, .sp_len = 6,
......
...@@ -887,7 +887,7 @@ static int exynos_map_dt_data(struct platform_device *pdev) ...@@ -887,7 +887,7 @@ static int exynos_map_dt_data(struct platform_device *pdev)
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
} }
data->soc = (enum soc_type)of_device_get_match_data(&pdev->dev); data->soc = (uintptr_t)of_device_get_match_data(&pdev->dev);
switch (data->soc) { switch (data->soc) {
case SOC_ARCH_EXYNOS4210: case SOC_ARCH_EXYNOS4210:
......
...@@ -56,8 +56,6 @@ ...@@ -56,8 +56,6 @@
#define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12) #define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12)
#define SUN50I_H6_THS_DATA_IRQ_STS(x) BIT(x) #define SUN50I_H6_THS_DATA_IRQ_STS(x) BIT(x)
/* millidegree celsius */
struct tsensor { struct tsensor {
struct ths_device *tmdev; struct ths_device *tmdev;
struct thermal_zone_device *tzd; struct thermal_zone_device *tzd;
...@@ -286,7 +284,7 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev) ...@@ -286,7 +284,7 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev)
size_t callen; size_t callen;
int ret = 0; int ret = 0;
calcell = devm_nvmem_cell_get(dev, "calibration"); calcell = nvmem_cell_get(dev, "calibration");
if (IS_ERR(calcell)) { if (IS_ERR(calcell)) {
if (PTR_ERR(calcell) == -EPROBE_DEFER) if (PTR_ERR(calcell) == -EPROBE_DEFER)
return -EPROBE_DEFER; return -EPROBE_DEFER;
...@@ -316,6 +314,8 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev) ...@@ -316,6 +314,8 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev)
kfree(caldata); kfree(caldata);
out: out:
if (!IS_ERR(calcell))
nvmem_cell_put(calcell);
return ret; return ret;
} }
...@@ -489,8 +489,6 @@ static int sun8i_ths_probe(struct platform_device *pdev) ...@@ -489,8 +489,6 @@ static int sun8i_ths_probe(struct platform_device *pdev)
if (!tmdev->chip) if (!tmdev->chip)
return -EINVAL; return -EINVAL;
platform_set_drvdata(pdev, tmdev);
ret = sun8i_ths_resource_init(tmdev); ret = sun8i_ths_resource_init(tmdev);
if (ret) if (ret)
return ret; return ret;
......
...@@ -167,19 +167,69 @@ static int tegra_bpmp_thermal_get_num_zones(struct tegra_bpmp *bpmp, ...@@ -167,19 +167,69 @@ static int tegra_bpmp_thermal_get_num_zones(struct tegra_bpmp *bpmp,
return 0; return 0;
} }
static int tegra_bpmp_thermal_trips_supported(struct tegra_bpmp *bpmp, bool *supported)
{
struct mrq_thermal_host_to_bpmp_request req;
union mrq_thermal_bpmp_to_host_response reply;
struct tegra_bpmp_message msg;
int err;
memset(&req, 0, sizeof(req));
req.type = CMD_THERMAL_QUERY_ABI;
req.query_abi.type = CMD_THERMAL_SET_TRIP;
memset(&msg, 0, sizeof(msg));
msg.mrq = MRQ_THERMAL;
msg.tx.data = &req;
msg.tx.size = sizeof(req);
msg.rx.data = &reply;
msg.rx.size = sizeof(reply);
err = tegra_bpmp_transfer(bpmp, &msg);
if (err)
return err;
if (msg.rx.ret == 0) {
*supported = true;
return 0;
} else if (msg.rx.ret == -BPMP_ENODEV) {
*supported = false;
return 0;
} else {
return -EINVAL;
}
}
static const struct thermal_zone_device_ops tegra_bpmp_of_thermal_ops = { static const struct thermal_zone_device_ops tegra_bpmp_of_thermal_ops = {
.get_temp = tegra_bpmp_thermal_get_temp, .get_temp = tegra_bpmp_thermal_get_temp,
.set_trips = tegra_bpmp_thermal_set_trips, .set_trips = tegra_bpmp_thermal_set_trips,
}; };
static const struct thermal_zone_device_ops tegra_bpmp_of_thermal_ops_notrips = {
.get_temp = tegra_bpmp_thermal_get_temp,
};
static int tegra_bpmp_thermal_probe(struct platform_device *pdev) static int tegra_bpmp_thermal_probe(struct platform_device *pdev)
{ {
struct tegra_bpmp *bpmp = dev_get_drvdata(pdev->dev.parent); struct tegra_bpmp *bpmp = dev_get_drvdata(pdev->dev.parent);
const struct thermal_zone_device_ops *thermal_ops;
struct tegra_bpmp_thermal *tegra; struct tegra_bpmp_thermal *tegra;
struct thermal_zone_device *tzd; struct thermal_zone_device *tzd;
unsigned int i, max_num_zones; unsigned int i, max_num_zones;
bool supported;
int err; int err;
err = tegra_bpmp_thermal_trips_supported(bpmp, &supported);
if (err) {
dev_err(&pdev->dev, "failed to determine if trip points are supported\n");
return err;
}
if (supported)
thermal_ops = &tegra_bpmp_of_thermal_ops;
else
thermal_ops = &tegra_bpmp_of_thermal_ops_notrips;
tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
if (!tegra) if (!tegra)
return -ENOMEM; return -ENOMEM;
...@@ -222,7 +272,7 @@ static int tegra_bpmp_thermal_probe(struct platform_device *pdev) ...@@ -222,7 +272,7 @@ static int tegra_bpmp_thermal_probe(struct platform_device *pdev)
} }
tzd = devm_thermal_of_zone_register( tzd = devm_thermal_of_zone_register(
&pdev->dev, i, zone, &tegra_bpmp_of_thermal_ops); &pdev->dev, i, zone, thermal_ops);
if (IS_ERR(tzd)) { if (IS_ERR(tzd)) {
if (PTR_ERR(tzd) == -EPROBE_DEFER) if (PTR_ERR(tzd) == -EPROBE_DEFER)
return -EPROBE_DEFER; return -EPROBE_DEFER;
......
...@@ -142,7 +142,6 @@ static int gadc_thermal_probe(struct platform_device *pdev) ...@@ -142,7 +142,6 @@ static int gadc_thermal_probe(struct platform_device *pdev)
return ret; return ret;
gti->dev = &pdev->dev; gti->dev = &pdev->dev;
platform_set_drvdata(pdev, gti);
gti->tz_dev = devm_thermal_of_zone_register(&pdev->dev, 0, gti, gti->tz_dev = devm_thermal_of_zone_register(&pdev->dev, 0, gti,
&gadc_thermal_ops); &gadc_thermal_ops);
......
...@@ -1266,7 +1266,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t ...@@ -1266,7 +1266,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp) && !trips) if (num_trips > 0 && !trips)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
if (!thermal_class) if (!thermal_class)
......
...@@ -70,7 +70,7 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) ...@@ -70,7 +70,7 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
void thermal_cdev_update(struct thermal_cooling_device *); void thermal_cdev_update(struct thermal_cooling_device *);
void __thermal_cdev_update(struct thermal_cooling_device *cdev); void __thermal_cdev_update(struct thermal_cooling_device *cdev);
int get_tz_trend(struct thermal_zone_device *tz, int trip); int get_tz_trend(struct thermal_zone_device *tz, int trip_index);
struct thermal_instance * struct thermal_instance *
get_thermal_instance(struct thermal_zone_device *tz, get_thermal_instance(struct thermal_zone_device *tz,
......
...@@ -22,8 +22,9 @@ ...@@ -22,8 +22,9 @@
#include "thermal_core.h" #include "thermal_core.h"
#include "thermal_trace.h" #include "thermal_trace.h"
int get_tz_trend(struct thermal_zone_device *tz, int trip) int get_tz_trend(struct thermal_zone_device *tz, int trip_index)
{ {
struct thermal_trip *trip = tz->trips ? &tz->trips[trip_index] : NULL;
enum thermal_trend trend; enum thermal_trend trend;
if (tz->emul_temperature || !tz->ops->get_trend || if (tz->emul_temperature || !tz->ops->get_trend ||
......
...@@ -101,29 +101,11 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) ...@@ -101,29 +101,11 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz)
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
struct thermal_trip *trip) struct thermal_trip *trip)
{ {
int ret; if (!tz || !tz->trips || trip_id < 0 || trip_id >= tz->num_trips || !trip)
if (!tz || trip_id < 0 || trip_id >= tz->num_trips || !trip)
return -EINVAL; return -EINVAL;
if (tz->trips) { *trip = tz->trips[trip_id];
*trip = tz->trips[trip_id]; return 0;
return 0;
}
if (tz->ops->get_trip_hyst) {
ret = tz->ops->get_trip_hyst(tz, trip_id, &trip->hysteresis);
if (ret)
return ret;
} else {
trip->hysteresis = 0;
}
ret = tz->ops->get_trip_temp(tz, trip_id, &trip->temperature);
if (ret)
return ret;
return tz->ops->get_trip_type(tz, trip_id, &trip->type);
} }
EXPORT_SYMBOL_GPL(__thermal_zone_get_trip); EXPORT_SYMBOL_GPL(__thermal_zone_get_trip);
......
...@@ -314,7 +314,7 @@ int ti_bandgap_adc_to_mcelsius(struct ti_bandgap *bgp, int adc_val, int *t) ...@@ -314,7 +314,7 @@ int ti_bandgap_adc_to_mcelsius(struct ti_bandgap *bgp, int adc_val, int *t)
*/ */
static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id) static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id)
{ {
if (!bgp || IS_ERR(bgp)) { if (IS_ERR_OR_NULL(bgp)) {
pr_err("%s: invalid bandgap pointer\n", __func__); pr_err("%s: invalid bandgap pointer\n", __func__);
return -EINVAL; return -EINVAL;
} }
......
...@@ -109,7 +109,8 @@ static inline int __ti_thermal_get_temp(struct thermal_zone_device *tz, int *tem ...@@ -109,7 +109,8 @@ static inline int __ti_thermal_get_temp(struct thermal_zone_device *tz, int *tem
return ret; return ret;
} }
static int __ti_thermal_get_trend(struct thermal_zone_device *tz, int trip, enum thermal_trend *trend) static int __ti_thermal_get_trend(struct thermal_zone_device *tz,
struct thermal_trip *trip, enum thermal_trend *trend)
{ {
struct ti_thermal_data *data = thermal_zone_device_priv(tz); struct ti_thermal_data *data = thermal_zone_device_priv(tz);
struct ti_bandgap *bgp; struct ti_bandgap *bgp;
......
...@@ -53,6 +53,20 @@ enum thermal_notify_event { ...@@ -53,6 +53,20 @@ enum thermal_notify_event {
THERMAL_EVENT_KEEP_ALIVE, /* Request for user space handler to respond */ THERMAL_EVENT_KEEP_ALIVE, /* Request for user space handler to respond */
}; };
/**
* struct thermal_trip - representation of a point in temperature domain
* @temperature: temperature value in miliCelsius
* @hysteresis: relative hysteresis in miliCelsius
* @type: trip point type
* @priv: pointer to driver data associated with this trip
*/
struct thermal_trip {
int temperature;
int hysteresis;
enum thermal_trip_type type;
void *priv;
};
struct thermal_zone_device_ops { struct thermal_zone_device_ops {
int (*bind) (struct thermal_zone_device *, int (*bind) (struct thermal_zone_device *,
struct thermal_cooling_device *); struct thermal_cooling_device *);
...@@ -62,34 +76,16 @@ struct thermal_zone_device_ops { ...@@ -62,34 +76,16 @@ struct thermal_zone_device_ops {
int (*set_trips) (struct thermal_zone_device *, int, int); int (*set_trips) (struct thermal_zone_device *, int, int);
int (*change_mode) (struct thermal_zone_device *, int (*change_mode) (struct thermal_zone_device *,
enum thermal_device_mode); enum thermal_device_mode);
int (*get_trip_type) (struct thermal_zone_device *, int,
enum thermal_trip_type *);
int (*get_trip_temp) (struct thermal_zone_device *, int, int *);
int (*set_trip_temp) (struct thermal_zone_device *, int, int); int (*set_trip_temp) (struct thermal_zone_device *, int, int);
int (*get_trip_hyst) (struct thermal_zone_device *, int, int *);
int (*set_trip_hyst) (struct thermal_zone_device *, int, int); int (*set_trip_hyst) (struct thermal_zone_device *, int, int);
int (*get_crit_temp) (struct thermal_zone_device *, int *); int (*get_crit_temp) (struct thermal_zone_device *, int *);
int (*set_emul_temp) (struct thermal_zone_device *, int); int (*set_emul_temp) (struct thermal_zone_device *, int);
int (*get_trend) (struct thermal_zone_device *, int, int (*get_trend) (struct thermal_zone_device *, struct thermal_trip *,
enum thermal_trend *); enum thermal_trend *);
void (*hot)(struct thermal_zone_device *); void (*hot)(struct thermal_zone_device *);
void (*critical)(struct thermal_zone_device *); void (*critical)(struct thermal_zone_device *);
}; };
/**
* struct thermal_trip - representation of a point in temperature domain
* @temperature: temperature value in miliCelsius
* @hysteresis: relative hysteresis in miliCelsius
* @type: trip point type
* @priv: pointer to driver data associated with this trip
*/
struct thermal_trip {
int temperature;
int hysteresis;
enum thermal_trip_type type;
void *priv;
};
struct thermal_cooling_device_ops { struct thermal_cooling_device_ops {
int (*get_max_state) (struct thermal_cooling_device *, unsigned long *); int (*get_max_state) (struct thermal_cooling_device *, unsigned long *);
int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *); int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment