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 ...@@ -114,12 +114,17 @@ Documentation/devicetree/bindings/thermal/thermal.txt
The thermal IP can probe the temperature all around the processor. It The thermal IP can probe the temperature all around the processor. It
may feature several channels, each of them wired to one sensor. 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: Required properties:
- compatible: must be one of: - compatible: must be one of:
* marvell,armada-ap806-thermal * marvell,armada-ap806-thermal
- reg: register range associated with the thermal functions. - reg: register range associated with the thermal functions.
Optional properties: 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 - #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
to this IP and represents the channel ID. There is one sensor per to this IP and represents the channel ID. There is one sensor per
channel. O refers to the thermal IP internal channel, while positive channel. O refers to the thermal IP internal channel, while positive
...@@ -133,6 +138,8 @@ ap_syscon1: system-controller@6f8000 { ...@@ -133,6 +138,8 @@ ap_syscon1: system-controller@6f8000 {
ap_thermal: thermal-sensor@80 { ap_thermal: thermal-sensor@80 {
compatible = "marvell,armada-ap806-thermal"; compatible = "marvell,armada-ap806-thermal";
reg = <0x80 0x10>; reg = <0x80 0x10>;
interrupt-parent = <&sei>;
interrupts = <18>;
#thermal-sensor-cells = <1>; #thermal-sensor-cells = <1>;
}; };
}; };
...@@ -199,6 +199,9 @@ Thermal: ...@@ -199,6 +199,9 @@ Thermal:
The thermal IP can probe the temperature all around the processor. It The thermal IP can probe the temperature all around the processor. It
may feature several channels, each of them wired to one sensor. 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 For common binding part and usage, refer to
Documentation/devicetree/bindings/thermal/thermal.txt Documentation/devicetree/bindings/thermal/thermal.txt
...@@ -208,6 +211,11 @@ Required properties: ...@@ -208,6 +211,11 @@ Required properties:
- reg: register range associated with the thermal functions. - reg: register range associated with the thermal functions.
Optional properties: 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 - #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
to this IP and represents the channel ID. There is one sensor per to this IP and represents the channel ID. There is one sensor per
channel. O refers to the thermal IP internal channel. channel. O refers to the thermal IP internal channel.
...@@ -220,6 +228,7 @@ CP110_LABEL(syscon1): system-controller@6f8000 { ...@@ -220,6 +228,7 @@ CP110_LABEL(syscon1): system-controller@6f8000 {
CP110_LABEL(thermal): thermal-sensor@70 { CP110_LABEL(thermal): thermal-sensor@70 {
compatible = "marvell,armada-cp110-thermal"; compatible = "marvell,armada-cp110-thermal";
reg = <0x70 0x10>; reg = <0x70 0x10>;
interrupts-extended = <&CP110_LABEL(icu_sei) 116 IRQ_TYPE_LEVEL_HIGH>;
#thermal-sensor-cells = <1>; #thermal-sensor-cells = <1>;
}; };
}; };
...@@ -21,8 +21,7 @@ Required properties: ...@@ -21,8 +21,7 @@ Required properties:
Optional properties: Optional properties:
- interrupts : interrupts routed to the TSC (3 for H3, M3-W, M3-N, - interrupts : interrupts routed to the TSC (must be 3).
and V3H)
- power-domain : Must contain a reference to the power domain. This - power-domain : Must contain a reference to the power domain. This
property is mandatory if the thermal sensor instance property is mandatory if the thermal sensor instance
is part of a controllable power domain. is part of a controllable power domain.
......
...@@ -4,17 +4,19 @@ Required properties: ...@@ -4,17 +4,19 @@ Required properties:
- compatible : "renesas,thermal-<soctype>", - compatible : "renesas,thermal-<soctype>",
"renesas,rcar-gen2-thermal" (with thermal-zone) or "renesas,rcar-gen2-thermal" (with thermal-zone) or
"renesas,rcar-thermal" (without thermal-zone) as "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: Examples with soctypes are:
- "renesas,thermal-r8a73a4" (R-Mobile APE6) - "renesas,thermal-r8a73a4" (R-Mobile APE6)
- "renesas,thermal-r8a7743" (RZ/G1M) - "renesas,thermal-r8a7743" (RZ/G1M)
- "renesas,thermal-r8a7744" (RZ/G1N) - "renesas,thermal-r8a7744" (RZ/G1N)
- "renesas,thermal-r8a774c0" (RZ/G2E)
- "renesas,thermal-r8a7779" (R-Car H1) - "renesas,thermal-r8a7779" (R-Car H1)
- "renesas,thermal-r8a7790" (R-Car H2) - "renesas,thermal-r8a7790" (R-Car H2)
- "renesas,thermal-r8a7791" (R-Car M2-W) - "renesas,thermal-r8a7791" (R-Car M2-W)
- "renesas,thermal-r8a7792" (R-Car V2H) - "renesas,thermal-r8a7792" (R-Car V2H)
- "renesas,thermal-r8a7793" (R-Car M2-N) - "renesas,thermal-r8a7793" (R-Car M2-N)
- "renesas,thermal-r8a77970" (R-Car V3M) - "renesas,thermal-r8a77970" (R-Car V3M)
- "renesas,thermal-r8a77990" (R-Car E3)
- "renesas,thermal-r8a77995" (R-Car D3) - "renesas,thermal-r8a77995" (R-Car D3)
- reg : Address range of the thermal registers. - reg : Address range of the thermal registers.
The 1st reg will be recognized as common register The 1st reg will be recognized as common register
...@@ -23,7 +25,7 @@ Required properties: ...@@ -23,7 +25,7 @@ Required properties:
Option properties: Option properties:
- interrupts : If present should contain 3 interrupts for - 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): Example (non interrupt support):
......
...@@ -9109,6 +9109,11 @@ L: netdev@vger.kernel.org ...@@ -9109,6 +9109,11 @@ L: netdev@vger.kernel.org
S: Maintained S: Maintained
F: drivers/net/phy/marvell10g.c 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 MARVELL MVNETA ETHERNET DRIVER
M: Thomas Petazzoni <thomas.petazzoni@bootlin.com> M: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
......
...@@ -212,7 +212,7 @@ config HISI_THERMAL ...@@ -212,7 +212,7 @@ config HISI_THERMAL
config IMX_THERMAL config IMX_THERMAL
tristate "Temperature sensor driver for Freescale i.MX SoCs" 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 NVMEM || !NVMEM
depends on MFD_SYSCON depends on MFD_SYSCON
depends on OF depends on OF
......
This diff is collapsed.
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/thermal.h> #include <linux/thermal.h>
#include "../thermal_hwmon.h"
#define BCM2835_TS_TSENSCTL 0x00 #define BCM2835_TS_TSENSCTL 0x00
#define BCM2835_TS_TSENSSTAT 0x04 #define BCM2835_TS_TSENSSTAT 0x04
...@@ -266,6 +268,15 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) ...@@ -266,6 +268,15 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, tz); 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); bcm2835_thermal_debugfs(pdev);
return 0; return 0;
......
...@@ -329,7 +329,8 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) ...@@ -329,7 +329,8 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
priv->dev = &pdev->dev; priv->dev = &pdev->dev;
platform_set_drvdata(pdev, priv); 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)) { if (IS_ERR(thermal)) {
ret = PTR_ERR(thermal); ret = PTR_ERR(thermal);
dev_err(&pdev->dev, "could not register sensor: %d\n", ret); dev_err(&pdev->dev, "could not register sensor: %d\n", ret);
...@@ -341,40 +342,23 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) ...@@ -341,40 +342,23 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
dev_err(&pdev->dev, "could not get IRQ\n"); dev_err(&pdev->dev, "could not get IRQ\n");
ret = irq; return irq;
goto err;
} }
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
brcmstb_tmon_irq_thread, IRQF_ONESHOT, brcmstb_tmon_irq_thread, IRQF_ONESHOT,
DRV_NAME, priv); DRV_NAME, priv);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "could not request IRQ: %d\n", ret); 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"); dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n");
return 0; 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 = { static struct platform_driver brcmstb_thermal_driver = {
.probe = brcmstb_thermal_probe, .probe = brcmstb_thermal_probe,
.remove = brcmstb_thermal_exit,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = brcmstb_thermal_id_table, .of_match_table = brcmstb_thermal_id_table,
......
...@@ -648,15 +648,24 @@ static const struct of_device_id of_imx_thermal_match[] = { ...@@ -648,15 +648,24 @@ static const struct of_device_id of_imx_thermal_match[] = {
}; };
MODULE_DEVICE_TABLE(of, 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 * Create cooling device in case no #cooling-cells property is available in
* CPU node * CPU node
*/ */
static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) 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; 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)) { if (!np || !of_find_property(np, "#cooling-cells", NULL)) {
data->cdev = cpufreq_cooling_register(data->policy); data->cdev = cpufreq_cooling_register(data->policy);
if (IS_ERR(data->cdev)) { if (IS_ERR(data->cdev)) {
...@@ -669,6 +678,24 @@ static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) ...@@ -669,6 +678,24 @@ static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
return 0; 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) static int imx_thermal_probe(struct platform_device *pdev)
{ {
struct imx_thermal_data *data; struct imx_thermal_data *data;
...@@ -715,9 +742,10 @@ static int imx_thermal_probe(struct platform_device *pdev) ...@@ -715,9 +742,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) { if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) {
ret = imx_init_from_nvmem_cells(pdev); ret = imx_init_from_nvmem_cells(pdev);
if (ret == -EPROBE_DEFER)
return ret;
if (ret) { if (ret) {
if (ret == -EPROBE_DEFER)
return ret;
dev_err(&pdev->dev, "failed to init from nvmem: %d\n", dev_err(&pdev->dev, "failed to init from nvmem: %d\n",
ret); ret);
return ret; return ret;
...@@ -743,14 +771,11 @@ static int imx_thermal_probe(struct platform_device *pdev) ...@@ -743,14 +771,11 @@ static int imx_thermal_probe(struct platform_device *pdev)
regmap_write(map, data->socdata->sensor_ctrl + REG_SET, regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
data->socdata->power_down_mask); 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); ret = imx_thermal_register_legacy_cooling(data);
if (ret) { if (ret) {
if (ret == -EPROBE_DEFER)
return ret;
dev_err(&pdev->dev, dev_err(&pdev->dev,
"failed to register cpufreq cooling device: %d\n", ret); "failed to register cpufreq cooling device: %d\n", ret);
return ret; return ret;
...@@ -762,7 +787,7 @@ static int imx_thermal_probe(struct platform_device *pdev) ...@@ -762,7 +787,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
if (ret != -EPROBE_DEFER) if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, dev_err(&pdev->dev,
"failed to get thermal clk: %d\n", ret); "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) ...@@ -775,7 +800,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
ret = clk_prepare_enable(data->thermal_clk); ret = clk_prepare_enable(data->thermal_clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", 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", data->tz = thermal_zone_device_register("imx_thermal_zone",
...@@ -829,9 +854,8 @@ static int imx_thermal_probe(struct platform_device *pdev) ...@@ -829,9 +854,8 @@ static int imx_thermal_probe(struct platform_device *pdev)
thermal_zone_device_unregister(data->tz); thermal_zone_device_unregister(data->tz);
clk_disable: clk_disable:
clk_disable_unprepare(data->thermal_clk); clk_disable_unprepare(data->thermal_clk);
cpufreq_put: legacy_cleanup:
cpufreq_cooling_unregister(data->cdev); imx_thermal_unregister_legacy_cooling(data);
cpufreq_cpu_put(data->policy);
return ret; return ret;
} }
......
...@@ -708,19 +708,7 @@ static int powerclamp_debug_show(struct seq_file *m, void *unused) ...@@ -708,19 +708,7 @@ static int powerclamp_debug_show(struct seq_file *m, void *unused)
return 0; return 0;
} }
static int powerclamp_debug_open(struct inode *inode, DEFINE_SHOW_ATTRIBUTE(powerclamp_debug);
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,
};
static inline void powerclamp_create_debug_files(void) static inline void powerclamp_create_debug_files(void)
{ {
......
...@@ -114,6 +114,14 @@ int get_temp_common(struct tsens_device *tmdev, int id, int *temp) ...@@ -114,6 +114,14 @@ int get_temp_common(struct tsens_device *tmdev, int id, int *temp)
} }
static const struct regmap_config tsens_config = { 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, .reg_bits = 32,
.val_bits = 32, .val_bits = 32,
.reg_stride = 4, .reg_stride = 4,
...@@ -139,8 +147,8 @@ int __init init_common(struct tsens_device *tmdev) ...@@ -139,8 +147,8 @@ int __init init_common(struct tsens_device *tmdev)
if (IS_ERR(srot_base)) if (IS_ERR(srot_base))
return PTR_ERR(srot_base); return PTR_ERR(srot_base);
tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, srot_base,
srot_base, &tsens_config); &tsens_srot_config);
if (IS_ERR(tmdev->srot_map)) if (IS_ERR(tmdev->srot_map))
return PTR_ERR(tmdev->srot_map); return PTR_ERR(tmdev->srot_map);
......
...@@ -112,10 +112,18 @@ static const struct of_device_id rcar_thermal_dt_ids[] = { ...@@ -112,10 +112,18 @@ static const struct of_device_id rcar_thermal_dt_ids[] = {
.compatible = "renesas,rcar-gen2-thermal", .compatible = "renesas,rcar-gen2-thermal",
.data = &rcar_gen2_thermal, .data = &rcar_gen2_thermal,
}, },
{
.compatible = "renesas,thermal-r8a774c0",
.data = &rcar_gen3_thermal,
},
{ {
.compatible = "renesas,thermal-r8a77970", .compatible = "renesas,thermal-r8a77970",
.data = &rcar_gen3_thermal, .data = &rcar_gen3_thermal,
}, },
{
.compatible = "renesas,thermal-r8a77990",
.data = &rcar_gen3_thermal,
},
{ {
.compatible = "renesas,thermal-r8a77995", .compatible = "renesas,thermal-r8a77995",
.data = &rcar_gen3_thermal, .data = &rcar_gen3_thermal,
......
obj-$(CONFIG_ST_THERMAL) := st_thermal.o obj-$(CONFIG_ST_THERMAL) := st_thermal.o
obj-$(CONFIG_ST_THERMAL_SYSCFG) += st_thermal_syscfg.o obj-$(CONFIG_ST_THERMAL_SYSCFG) += st_thermal_syscfg.o
obj-$(CONFIG_ST_THERMAL_MEMMAP) += st_thermal_memmap.o obj-$(CONFIG_ST_THERMAL_MEMMAP) += st_thermal_memmap.o
obj-$(CONFIG_STM32_THERMAL) := stm_thermal.o obj-$(CONFIG_STM32_THERMAL) += stm_thermal.o
\ No newline at end of file
...@@ -803,17 +803,7 @@ static int regs_show(struct seq_file *s, void *data) ...@@ -803,17 +803,7 @@ static int regs_show(struct seq_file *s, void *data)
return 0; return 0;
} }
static int regs_open(struct inode *inode, struct file *file) DEFINE_SHOW_ATTRIBUTE(regs);
{
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,
};
static void soctherm_debug_init(struct platform_device *pdev) static void soctherm_debug_init(struct platform_device *pdev)
{ {
......
...@@ -26,7 +26,7 @@ struct gadc_thermal_info { ...@@ -26,7 +26,7 @@ struct gadc_thermal_info {
static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val) 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; int i;
for (i = 0; i < gti->nlookup_table; 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) ...@@ -36,13 +36,17 @@ static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val)
if (i == 0) { if (i == 0) {
temp = gti->lookup_table[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)]; temp = gti->lookup_table[2 * (gti->nlookup_table - 1)];
} else { } else {
adc_hi = gti->lookup_table[2 * i - 1]; adc_hi = gti->lookup_table[2 * i - 1];
adc_lo = 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; return temp;
......
...@@ -19,13 +19,13 @@ ...@@ -19,13 +19,13 @@
int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz); int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz);
void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz); void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz);
#else #else
static int static inline int
thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
{ {
return 0; return 0;
} }
static void static inline void
thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
{ {
} }
......
// SPDX-License-Identifier: GPL-2.0
/** /**
* uniphier_thermal.c - Socionext UniPhier thermal driver * uniphier_thermal.c - Socionext UniPhier thermal driver
*
* Copyright 2014 Panasonic Corporation * Copyright 2014 Panasonic Corporation
* Copyright 2016-2017 Socionext Inc. * Copyright 2016-2017 Socionext Inc.
* All rights reserved.
*
* Author: * Author:
* Kunihiko Hayashi <hayashi.kunihiko@socionext.com> * 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> #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