Skip to content

Commit

Permalink
Merge tag 'thermal-6.6-rc1-2' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/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
  ...
  • Loading branch information
Linus Torvalds committed Sep 4, 2023
2 parents 2a3a850 + 8289d81 commit 0ca4080
Show file tree
Hide file tree
Showing 28 changed files with 468 additions and 140 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# 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>;
};
8 changes: 8 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -12390,6 +12390,14 @@ S: Maintained
F: Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
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)
M: Sathya Prakash <sathya.prakash@broadcom.com>
M: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Expand Down
41 changes: 18 additions & 23 deletions drivers/acpi/thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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_trip *acpi_trip;
int t, i;
int t;

if (!tz || trip_index < 0)
if (!tz || !trip)
return -EINVAL;

if (tz->trips.critical.valid)
trip_index--;

if (tz->trips.hot.valid)
trip_index--;

if (trip_index < 0)
acpi_trip = trip->priv;
if (!acpi_trip || !acpi_trip->valid)
return -EINVAL;

acpi_trip = &tz->trips.passive.trip;
if (acpi_trip->valid && !trip_index--) {
switch (trip->type) {
case THERMAL_TRIP_PASSIVE:
t = tz->trips.passive.tc1 * (tz->temperature -
tz->last_temperature) +
tz->trips.passive.tc2 * (tz->temperature -
Expand All @@ -524,19 +520,18 @@ static int thermal_get_trend(struct thermal_zone_device *thermal,
*trend = THERMAL_TREND_STABLE;

return 0;
}

t = acpi_thermal_temp(tz, tz->temperature);

for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
acpi_trip = &tz->trips.active[i].trip;
if (acpi_trip->valid && !trip_index--) {
if (t > acpi_thermal_temp(tz, acpi_trip->temperature)) {
*trend = THERMAL_TREND_RAISING;
return 0;
}
case THERMAL_TRIP_ACTIVE:
t = acpi_thermal_temp(tz, tz->temperature);
if (t <= trip->temperature)
break;
}

*trend = THERMAL_TREND_RAISING;

return 0;

default:
break;
}

return -EINVAL;
Expand Down
12 changes: 12 additions & 0 deletions drivers/thermal/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -510,4 +510,16 @@ config KHADAS_MCU_FAN_THERMAL
If you say yes here you get support for the FAN controlled
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
1 change: 1 addition & 0 deletions drivers/thermal/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,4 @@ obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o
obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o
obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) += khadas_mcu_fan.o
obj-$(CONFIG_LOONGSON2_THERMAL) += loongson2_thermal.o
1 change: 0 additions & 1 deletion drivers/thermal/broadcom/brcmstb_thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,6 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
return PTR_ERR(priv->tmon_base);

priv->dev = &pdev->dev;
platform_set_drvdata(pdev, priv);
of_ops = priv->temp_params->of_ops;

thermal = devm_thermal_of_zone_register(&pdev->dev, 0, priv,
Expand Down
1 change: 0 additions & 1 deletion drivers/thermal/broadcom/sr-thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ static int sr_thermal_probe(struct platform_device *pdev)

dev_dbg(dev, "thermal sensor %d registered\n", i);
}
platform_set_drvdata(pdev, sr_thermal);

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/thermal/db8500_thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ MODULE_DEVICE_TABLE(of, db8500_thermal_match);
static struct platform_driver db8500_thermal_driver = {
.driver = {
.name = "db8500-thermal",
.of_match_table = of_match_ptr(db8500_thermal_match),
.of_match_table = db8500_thermal_match,
},
.probe = db8500_thermal_probe,
.suspend = db8500_thermal_suspend,
Expand Down
6 changes: 2 additions & 4 deletions drivers/thermal/imx8mm_thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,8 @@ static int imx8mm_tmu_probe_set_calib_v1(struct platform_device *pdev,
int ret;

ret = nvmem_cell_read_u32(&pdev->dev, "calib", &ana0);
if (ret) {
dev_warn(dev, "Failed to read OCOTP nvmem cell (%d).\n", ret);
return ret;
}
if (ret)
return dev_err_probe(dev, ret, "Failed to read OCOTP nvmem cell\n");

writel(FIELD_PREP(TASR_BUF_VREF_MASK,
FIELD_GET(ANA0_BUF_VREF_MASK, ana0)) |
Expand Down
1 change: 0 additions & 1 deletion drivers/thermal/k3_bandgap.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ static int k3_bandgap_probe(struct platform_device *pdev)
devm_thermal_add_hwmon_sysfs(dev, data[id].tzd);
}

platform_set_drvdata(pdev, bgp);

return 0;

Expand Down
2 changes: 0 additions & 2 deletions drivers/thermal/k3_j72xx_bandgap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 +
K3_VTM_MISC_CTRL_OFFSET);

platform_set_drvdata(pdev, bgp);

print_look_up_table(dev, ref_table);
/*
* Now that the derived_table has the appropriate look up values
Expand Down
169 changes: 169 additions & 0 deletions drivers/thermal/loongson2_thermal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// 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");
2 changes: 0 additions & 2 deletions drivers/thermal/max77620_thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@ static int max77620_thermal_probe(struct platform_device *pdev)
return ret;
}

platform_set_drvdata(pdev, mtherm);

return 0;
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/thermal/mediatek/auxadc_thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1282,8 +1282,6 @@ static int mtk_thermal_probe(struct platform_device *pdev)
mtk_thermal_init_bank(mt, i, apmixed_phys_base,
auxadc_phys_base, ctrl_id);

platform_set_drvdata(pdev, mt);

tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
&mtk_thermal_ops);
if (IS_ERR(tzdev))
Expand Down
Loading

0 comments on commit 0ca4080

Please sign in to comment.