Commit c2802302 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal

Pull thermal SoC updates from Eduardo Valentin:

 - Tegra DT binding documentation for Tegra194

 - Armada now supports ap806 and cp110

 - RCAR thermal now supports R8A774C0 and R8A77990

 - Fixes on thermal_hwmon, IMX, generic-ADC, ST, RCAR, Broadcom,
   Uniphier, QCOM, Tegra, PowerClamp, and Armada thermal drivers.

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal: (22 commits)
  thermal: generic-adc: Fix adc to temp interpolation
  thermal: rcar_thermal: add R8A77990 support
  dt-bindings: thermal: rcar-thermal: add R8A77990 support
  thermal: rcar_thermal: add R8A774C0 support
  dt-bindings: thermal: rcar-thermal: add R8A774C0 support
  dt-bindings: cp110: document the thermal interrupt capabilities
  dt-bindings: ap806: document the thermal interrupt capabilities
  MAINTAINERS: thermal: add entry for Marvell MVEBU thermal driver
  thermal: armada: add overheat interrupt support
  thermal: st: fix Makefile typo
  thermal: uniphier: Convert to SPDX identifier
  thermal/intel_powerclamp: Change to use DEFINE_SHOW_ATTRIBUTE macro
  thermal: tegra: soctherm: Change to use DEFINE_SHOW_ATTRIBUTE macro
  dt-bindings: thermal: tegra-bpmp: Add Tegra194 support
  thermal: imx: save one condition block for normal case of nvmem initialization
  thermal: imx: fix for dependency on cpu-freq
  thermal: tsens: qcom: do not create duplicate regmap debugfs entries
  thermal: armada: Use PTR_ERR_OR_ZERO in armada_thermal_probe_legacy()
  dt-bindings: thermal: rcar-gen3-thermal: All variants use 3 interrupts
  thermal: broadcom: use devm_thermal_zone_of_sensor_register
  ...
parents a6701241 9d216211
......@@ -114,12 +114,17 @@ Documentation/devicetree/bindings/thermal/thermal.txt
The thermal IP can probe the temperature all around the processor. It
may feature several channels, each of them wired to one sensor.
It is possible to setup an overheat interrupt by giving at least one
critical point to any subnode of the thermal-zone node.
Required properties:
- compatible: must be one of:
* marvell,armada-ap806-thermal
- reg: register range associated with the thermal functions.
Optional properties:
- interrupts: overheat interrupt handle. Should point to line 18 of the
SEI irqchip. See interrupt-controller/interrupts.txt
- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
to this IP and represents the channel ID. There is one sensor per
channel. O refers to the thermal IP internal channel, while positive
......@@ -133,6 +138,8 @@ ap_syscon1: system-controller@6f8000 {
ap_thermal: thermal-sensor@80 {
compatible = "marvell,armada-ap806-thermal";
reg = <0x80 0x10>;
interrupt-parent = <&sei>;
interrupts = <18>;
#thermal-sensor-cells = <1>;
};
};
......@@ -199,6 +199,9 @@ Thermal:
The thermal IP can probe the temperature all around the processor. It
may feature several channels, each of them wired to one sensor.
It is possible to setup an overheat interrupt by giving at least one
critical point to any subnode of the thermal-zone node.
For common binding part and usage, refer to
Documentation/devicetree/bindings/thermal/thermal.txt
......@@ -208,6 +211,11 @@ Required properties:
- reg: register range associated with the thermal functions.
Optional properties:
- interrupts-extended: overheat interrupt handle. Should point to
a line of the ICU-SEI irqchip (116 is what is usually used by the
firmware). The ICU-SEI will redirect towards interrupt line #37 of the
AP SEI which is shared across all CPs.
See interrupt-controller/interrupts.txt
- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
to this IP and represents the channel ID. There is one sensor per
channel. O refers to the thermal IP internal channel.
......@@ -220,6 +228,7 @@ CP110_LABEL(syscon1): system-controller@6f8000 {
CP110_LABEL(thermal): thermal-sensor@70 {
compatible = "marvell,armada-cp110-thermal";
reg = <0x70 0x10>;
interrupts-extended = <&CP110_LABEL(icu_sei) 116 IRQ_TYPE_LEVEL_HIGH>;
#thermal-sensor-cells = <1>;
};
};
......@@ -21,8 +21,7 @@ Required properties:
Optional properties:
- interrupts : interrupts routed to the TSC (3 for H3, M3-W, M3-N,
and V3H)
- interrupts : interrupts routed to the TSC (must be 3).
- power-domain : Must contain a reference to the power domain. This
property is mandatory if the thermal sensor instance
is part of a controllable power domain.
......
......@@ -4,17 +4,19 @@ Required properties:
- compatible : "renesas,thermal-<soctype>",
"renesas,rcar-gen2-thermal" (with thermal-zone) or
"renesas,rcar-thermal" (without thermal-zone) as
fallback except R-Car V3M/D3.
fallback except R-Car V3M/E3/D3 and RZ/G2E.
Examples with soctypes are:
- "renesas,thermal-r8a73a4" (R-Mobile APE6)
- "renesas,thermal-r8a7743" (RZ/G1M)
- "renesas,thermal-r8a7744" (RZ/G1N)
- "renesas,thermal-r8a774c0" (RZ/G2E)
- "renesas,thermal-r8a7779" (R-Car H1)
- "renesas,thermal-r8a7790" (R-Car H2)
- "renesas,thermal-r8a7791" (R-Car M2-W)
- "renesas,thermal-r8a7792" (R-Car V2H)
- "renesas,thermal-r8a7793" (R-Car M2-N)
- "renesas,thermal-r8a77970" (R-Car V3M)
- "renesas,thermal-r8a77990" (R-Car E3)
- "renesas,thermal-r8a77995" (R-Car D3)
- reg : Address range of the thermal registers.
The 1st reg will be recognized as common register
......@@ -23,7 +25,7 @@ Required properties:
Option properties:
- interrupts : If present should contain 3 interrupts for
R-Car V3M/D3 or 1 interrupt otherwise.
R-Car V3M/E3/D3 and RZ/G2E or 1 interrupt otherwise.
Example (non interrupt support):
......
......@@ -9109,6 +9109,11 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/phy/marvell10g.c
MARVELL MVEBU THERMAL DRIVER
M: Miquel Raynal <miquel.raynal@bootlin.com>
S: Maintained
F: drivers/thermal/armada_thermal.c
MARVELL MVNETA ETHERNET DRIVER
M: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
L: netdev@vger.kernel.org
......
......@@ -212,7 +212,7 @@ config HISI_THERMAL
config IMX_THERMAL
tristate "Temperature sensor driver for Freescale i.MX SoCs"
depends on (ARCH_MXC && CPU_THERMAL) || COMPILE_TEST
depends on ARCH_MXC || COMPILE_TEST
depends on NVMEM || !NVMEM
depends on MFD_SYSCON
depends on OF
......
This diff is collapsed.
......@@ -18,6 +18,8 @@
#include <linux/platform_device.h>
#include <linux/thermal.h>
#include "../thermal_hwmon.h"
#define BCM2835_TS_TSENSCTL 0x00
#define BCM2835_TS_TSENSSTAT 0x04
......@@ -266,6 +268,15 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, tz);
/*
* Thermal_zone doesn't enable hwmon as default,
* enable it here
*/
tz->tzp->no_hwmon = false;
err = thermal_add_hwmon_sysfs(tz);
if (err)
goto err_tz;
bcm2835_thermal_debugfs(pdev);
return 0;
......
......@@ -329,7 +329,8 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
priv->dev = &pdev->dev;
platform_set_drvdata(pdev, priv);
thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &of_ops);
thermal = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv,
&of_ops);
if (IS_ERR(thermal)) {
ret = PTR_ERR(thermal);
dev_err(&pdev->dev, "could not register sensor: %d\n", ret);
......@@ -341,40 +342,23 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "could not get IRQ\n");
ret = irq;
goto err;
return irq;
}
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
brcmstb_tmon_irq_thread, IRQF_ONESHOT,
DRV_NAME, priv);
if (ret < 0) {
dev_err(&pdev->dev, "could not request IRQ: %d\n", ret);
goto err;
return ret;
}
dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n");
return 0;
err:
thermal_zone_of_sensor_unregister(&pdev->dev, thermal);
return ret;
}
static int brcmstb_thermal_exit(struct platform_device *pdev)
{
struct brcmstb_thermal_priv *priv = platform_get_drvdata(pdev);
struct thermal_zone_device *thermal = priv->thermal;
if (thermal)
thermal_zone_of_sensor_unregister(&pdev->dev, priv->thermal);
return 0;
}
static struct platform_driver brcmstb_thermal_driver = {
.probe = brcmstb_thermal_probe,
.remove = brcmstb_thermal_exit,
.driver = {
.name = DRV_NAME,
.of_match_table = brcmstb_thermal_id_table,
......
......@@ -648,15 +648,24 @@ static const struct of_device_id of_imx_thermal_match[] = {
};
MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
#ifdef CONFIG_CPU_FREQ
/*
* Create cooling device in case no #cooling-cells property is available in
* CPU node
*/
static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
{
struct device_node *np = of_get_cpu_node(data->policy->cpu, NULL);
struct device_node *np;
int ret;
data->policy = cpufreq_cpu_get(0);
if (!data->policy) {
pr_debug("%s: CPUFreq policy not found\n", __func__);
return -EPROBE_DEFER;
}
np = of_get_cpu_node(data->policy->cpu, NULL);
if (!np || !of_find_property(np, "#cooling-cells", NULL)) {
data->cdev = cpufreq_cooling_register(data->policy);
if (IS_ERR(data->cdev)) {
......@@ -669,6 +678,24 @@ static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
return 0;
}
static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data)
{
cpufreq_cooling_unregister(data->cdev);
cpufreq_cpu_put(data->policy);
}
#else
static inline int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
{
return 0;
}
static inline void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data)
{
}
#endif
static int imx_thermal_probe(struct platform_device *pdev)
{
struct imx_thermal_data *data;
......@@ -715,9 +742,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) {
ret = imx_init_from_nvmem_cells(pdev);
if (ret == -EPROBE_DEFER)
return ret;
if (ret) {
if (ret == -EPROBE_DEFER)
return ret;
dev_err(&pdev->dev, "failed to init from nvmem: %d\n",
ret);
return ret;
......@@ -743,14 +771,11 @@ static int imx_thermal_probe(struct platform_device *pdev)
regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
data->socdata->power_down_mask);
data->policy = cpufreq_cpu_get(0);
if (!data->policy) {
pr_debug("%s: CPUFreq policy not found\n", __func__);
return -EPROBE_DEFER;
}
ret = imx_thermal_register_legacy_cooling(data);
if (ret) {
if (ret == -EPROBE_DEFER)
return ret;
dev_err(&pdev->dev,
"failed to register cpufreq cooling device: %d\n", ret);
return ret;
......@@ -762,7 +787,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev,
"failed to get thermal clk: %d\n", ret);
goto cpufreq_put;
goto legacy_cleanup;
}
/*
......@@ -775,7 +800,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
ret = clk_prepare_enable(data->thermal_clk);
if (ret) {
dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
goto cpufreq_put;
goto legacy_cleanup;
}
data->tz = thermal_zone_device_register("imx_thermal_zone",
......@@ -829,9 +854,8 @@ static int imx_thermal_probe(struct platform_device *pdev)
thermal_zone_device_unregister(data->tz);
clk_disable:
clk_disable_unprepare(data->thermal_clk);
cpufreq_put:
cpufreq_cooling_unregister(data->cdev);
cpufreq_cpu_put(data->policy);
legacy_cleanup:
imx_thermal_unregister_legacy_cooling(data);
return ret;
}
......
......@@ -708,19 +708,7 @@ static int powerclamp_debug_show(struct seq_file *m, void *unused)
return 0;
}
static int powerclamp_debug_open(struct inode *inode,
struct file *file)
{
return single_open(file, powerclamp_debug_show, inode->i_private);
}
static const struct file_operations powerclamp_debug_fops = {
.open = powerclamp_debug_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
DEFINE_SHOW_ATTRIBUTE(powerclamp_debug);
static inline void powerclamp_create_debug_files(void)
{
......
......@@ -114,6 +114,14 @@ int get_temp_common(struct tsens_device *tmdev, int id, int *temp)
}
static const struct regmap_config tsens_config = {
.name = "tm",
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
};
static const struct regmap_config tsens_srot_config = {
.name = "srot",
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
......@@ -139,8 +147,8 @@ int __init init_common(struct tsens_device *tmdev)
if (IS_ERR(srot_base))
return PTR_ERR(srot_base);
tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev,
srot_base, &tsens_config);
tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, srot_base,
&tsens_srot_config);
if (IS_ERR(tmdev->srot_map))
return PTR_ERR(tmdev->srot_map);
......
......@@ -112,10 +112,18 @@ static const struct of_device_id rcar_thermal_dt_ids[] = {
.compatible = "renesas,rcar-gen2-thermal",
.data = &rcar_gen2_thermal,
},
{
.compatible = "renesas,thermal-r8a774c0",
.data = &rcar_gen3_thermal,
},
{
.compatible = "renesas,thermal-r8a77970",
.data = &rcar_gen3_thermal,
},
{
.compatible = "renesas,thermal-r8a77990",
.data = &rcar_gen3_thermal,
},
{
.compatible = "renesas,thermal-r8a77995",
.data = &rcar_gen3_thermal,
......
obj-$(CONFIG_ST_THERMAL) := st_thermal.o
obj-$(CONFIG_ST_THERMAL_SYSCFG) += st_thermal_syscfg.o
obj-$(CONFIG_ST_THERMAL_MEMMAP) += st_thermal_memmap.o
obj-$(CONFIG_STM32_THERMAL) := stm_thermal.o
\ No newline at end of file
obj-$(CONFIG_STM32_THERMAL) += stm_thermal.o
......@@ -803,17 +803,7 @@ static int regs_show(struct seq_file *s, void *data)
return 0;
}
static int regs_open(struct inode *inode, struct file *file)
{
return single_open(file, regs_show, inode->i_private);
}
static const struct file_operations regs_fops = {
.open = regs_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
DEFINE_SHOW_ATTRIBUTE(regs);
static void soctherm_debug_init(struct platform_device *pdev)
{
......
......@@ -26,7 +26,7 @@ struct gadc_thermal_info {
static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val)
{
int temp, adc_hi, adc_lo;
int temp, temp_hi, temp_lo, adc_hi, adc_lo;
int i;
for (i = 0; i < gti->nlookup_table; i++) {
......@@ -36,13 +36,17 @@ static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val)
if (i == 0) {
temp = gti->lookup_table[0];
} else if (i >= (gti->nlookup_table - 1)) {
} else if (i >= gti->nlookup_table) {
temp = gti->lookup_table[2 * (gti->nlookup_table - 1)];
} else {
adc_hi = gti->lookup_table[2 * i - 1];
adc_lo = gti->lookup_table[2 * i + 1];
temp = gti->lookup_table[2 * i];
temp -= ((val - adc_lo) * 1000) / (adc_hi - adc_lo);
temp_hi = gti->lookup_table[2 * i - 2];
temp_lo = gti->lookup_table[2 * i];
temp = temp_hi + mult_frac(temp_lo - temp_hi, val - adc_hi,
adc_lo - adc_hi);
}
return temp;
......
......@@ -19,13 +19,13 @@
int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz);
void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz);
#else
static int
static inline int
thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
{
return 0;
}
static void
static inline void
thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
{
}
......
// SPDX-License-Identifier: GPL-2.0
/**
* uniphier_thermal.c - Socionext UniPhier thermal driver
*
* Copyright 2014 Panasonic Corporation
* Copyright 2016-2017 Socionext Inc.
* All rights reserved.
*
* Author:
* Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 of
* the License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/bitops.h>
......
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