Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
cb15c81a
K
Kernel
项目概览
openeuler
/
Kernel
大约 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
cb15c81a
编写于
5月 06, 2017
作者:
Z
Zhang Rui
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'thermal-soc' into next
上级
bb4d5e38
e4cb5bb2
变更
19
显示空白变更内容
内联
并排
Showing
19 changed file
with
1061 addition
and
217 deletion
+1061
-217
Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
...tion/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
+28
-4
Documentation/devicetree/bindings/thermal/brcm,ns-thermal
Documentation/devicetree/bindings/thermal/brcm,ns-thermal
+37
-0
Documentation/devicetree/bindings/thermal/da9062-thermal.txt
Documentation/devicetree/bindings/thermal/da9062-thermal.txt
+36
-0
drivers/thermal/Kconfig
drivers/thermal/Kconfig
+15
-0
drivers/thermal/Makefile
drivers/thermal/Makefile
+2
-0
drivers/thermal/broadcom/Kconfig
drivers/thermal/broadcom/Kconfig
+16
-0
drivers/thermal/broadcom/Makefile
drivers/thermal/broadcom/Makefile
+2
-0
drivers/thermal/broadcom/bcm2835_thermal.c
drivers/thermal/broadcom/bcm2835_thermal.c
+314
-0
drivers/thermal/broadcom/ns-thermal.c
drivers/thermal/broadcom/ns-thermal.c
+106
-0
drivers/thermal/da9062-thermal.c
drivers/thermal/da9062-thermal.c
+315
-0
drivers/thermal/mtk_thermal.c
drivers/thermal/mtk_thermal.c
+1
-1
drivers/thermal/rcar_gen3_thermal.c
drivers/thermal/rcar_gen3_thermal.c
+184
-15
drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
+0
-10
drivers/thermal/ti-soc-thermal/omap3-thermal-data.c
drivers/thermal/ti-soc-thermal/omap3-thermal-data.c
+0
-4
drivers/thermal/ti-soc-thermal/omap4-thermal-data.c
drivers/thermal/ti-soc-thermal/omap4-thermal-data.c
+0
-6
drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
+0
-4
drivers/thermal/ti-soc-thermal/ti-bandgap.h
drivers/thermal/ti-soc-thermal/ti-bandgap.h
+0
-4
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+5
-153
drivers/thermal/ti-soc-thermal/ti-thermal.h
drivers/thermal/ti-soc-thermal/ti-thermal.h
+0
-16
未找到文件。
Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
浏览文件 @
cb15c81a
...
...
@@ -7,11 +7,35 @@ compatible: should be one of: "brcm,bcm2835-thermal",
"brcm,bcm2836-thermal" or "brcm,bcm2837-thermal"
reg: Address range of the thermal registers.
clocks: Phandle of the clock used by the thermal sensor.
#thermal-sensor-cells: should be 0 (see thermal.txt)
Example:
thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <0>;
polling-delay = <1000>;
thermal-sensors = <&thermal>;
trips {
cpu-crit {
temperature = <80000>;
hysteresis = <0>;
type = "critical";
};
};
coefficients = <(-538) 407000>;
cooling-maps {
};
};
};
thermal: thermal@7e212000 {
compatible = "brcm,bcm2835-thermal";
reg = <0x7e212000 0x8>;
clocks = <&clocks BCM2835_CLOCK_TSENS>;
#thermal-sensor-cells = <0>;
};
Documentation/devicetree/bindings/thermal/brcm,ns-thermal
0 → 100644
浏览文件 @
cb15c81a
* Broadcom Northstar Thermal
This binding describes thermal sensor that is part of Northstar's DMU (Device
Management Unit).
Required properties:
- compatible : Must be "brcm,ns-thermal"
- reg : iomem address range of PVTMON registers
- #thermal-sensor-cells : Should be <0>
Example:
thermal: thermal@1800c2c0 {
compatible = "brcm,ns-thermal";
reg = <0x1800c2c0 0x10>;
#thermal-sensor-cells = <0>;
};
thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <0>;
polling-delay = <1000>;
coefficients = <(-556) 418000>;
thermal-sensors = <&thermal>;
trips {
cpu-crit {
temperature = <125000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
};
};
};
Documentation/devicetree/bindings/thermal/da9062-thermal.txt
0 → 100644
浏览文件 @
cb15c81a
* Dialog DA9062/61 TJUNC Thermal Module
This module is part of the DA9061/DA9062. For more details about entire
DA9062 and DA9061 chips see Documentation/devicetree/bindings/mfd/da9062.txt
Junction temperature thermal module uses an interrupt signal to identify
high THERMAL_TRIP_HOT temperatures for the PMIC device.
Required properties:
- compatible: should be one of the following valid compatible string lines:
"dlg,da9061-thermal", "dlg,da9062-thermal"
"dlg,da9062-thermal"
Optional properties:
- polling-delay-passive : Specify the polling period, measured in
milliseconds, between thermal zone device update checks.
Example: DA9062
pmic0: da9062@58 {
thermal {
compatible = "dlg,da9062-thermal";
polling-delay-passive = <3000>;
};
};
Example: DA9061 using a fall-back compatible for the DA9062 onkey driver
pmic0: da9061@58 {
thermal {
compatible = "dlg,da9061-thermal", "dlg,da9062-thermal";
polling-delay-passive = <3000>;
};
};
drivers/thermal/Kconfig
浏览文件 @
cb15c81a
...
...
@@ -320,6 +320,16 @@ config DB8500_CPUFREQ_COOLING
bound cpufreq cooling device turns active to set CPU frequency low to
cool down the CPU.
config DA9062_THERMAL
tristate "DA9062/DA9061 Dialog Semiconductor thermal driver"
depends on MFD_DA9062 || COMPILE_TEST
depends on OF
help
Enable this for the Dialog Semiconductor thermal sensor driver.
This will report PMIC junction over-temperature for one thermal trip
zone.
Compatible with the DA9062 and DA9061 PMICs.
config INTEL_POWERCLAMP
tristate "Intel PowerClamp idle injection driver"
depends on THERMAL
...
...
@@ -409,6 +419,11 @@ config MTK_THERMAL
Enable this option if you want to have support for thermal management
controller present in Mediatek SoCs
menu "Broadcom thermal drivers"
depends on ARCH_BCM || COMPILE_TEST
source "drivers/thermal/broadcom/Kconfig"
endmenu
menu "Texas Instruments thermal drivers"
depends on ARCH_HAS_BANDGAP || COMPILE_TEST
depends on HAS_IOMEM
...
...
drivers/thermal/Makefile
浏览文件 @
cb15c81a
...
...
@@ -27,6 +27,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o
thermal_sys-$(CONFIG_DEVFREQ_THERMAL)
+=
devfreq_cooling.o
# platform thermal drivers
obj-y
+=
broadcom/
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM)
+=
qcom-spmi-temp-alarm.o
obj-$(CONFIG_SPEAR_THERMAL)
+=
spear_thermal.o
obj-$(CONFIG_ROCKCHIP_THERMAL)
+=
rockchip_thermal.o
...
...
@@ -42,6 +43,7 @@ obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
obj-$(CONFIG_MAX77620_THERMAL)
+=
max77620_thermal.o
obj-$(CONFIG_QORIQ_THERMAL)
+=
qoriq_thermal.o
obj-$(CONFIG_DB8500_CPUFREQ_COOLING)
+=
db8500_cpufreq_cooling.o
obj-$(CONFIG_DA9062_THERMAL)
+=
da9062-thermal.o
obj-$(CONFIG_INTEL_POWERCLAMP)
+=
intel_powerclamp.o
obj-$(CONFIG_X86_PKG_TEMP_THERMAL)
+=
x86_pkg_temp_thermal.o
obj-$(CONFIG_INTEL_SOC_DTS_IOSF_CORE)
+=
intel_soc_dts_iosf.o
...
...
drivers/thermal/broadcom/Kconfig
0 → 100644
浏览文件 @
cb15c81a
config BCM2835_THERMAL
tristate "Thermal sensors on bcm2835 SoC"
depends on ARCH_BCM2835 || COMPILE_TEST
depends on HAS_IOMEM
depends on THERMAL_OF
help
Support for thermal sensors on Broadcom bcm2835 SoCs.
config BCM_NS_THERMAL
tristate "Northstar thermal driver"
depends on ARCH_BCM_IPROC || COMPILE_TEST
help
Northstar is a family of SoCs that includes e.g. BCM4708, BCM47081,
BCM4709 and BCM47094. It contains DMU (Device Management Unit) block
with a thermal sensor that allows checking CPU temperature. This
driver provides support for it.
drivers/thermal/broadcom/Makefile
0 → 100644
浏览文件 @
cb15c81a
obj-$(CONFIG_BCM2835_THERMAL)
+=
bcm2835_thermal.o
obj-$(CONFIG_BCM_NS_THERMAL)
+=
ns-thermal.o
drivers/thermal/broadcom/bcm2835_thermal.c
0 → 100644
浏览文件 @
cb15c81a
/*
* Driver for Broadcom BCM2835 SoC temperature sensor
*
* Copyright (C) 2016 Martin Sperl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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/clk.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
#define BCM2835_TS_TSENSCTL 0x00
#define BCM2835_TS_TSENSSTAT 0x04
#define BCM2835_TS_TSENSCTL_PRWDW BIT(0)
#define BCM2835_TS_TSENSCTL_RSTB BIT(1)
/*
* bandgap reference voltage in 6 mV increments
* 000b = 1178 mV, 001b = 1184 mV, ... 111b = 1220 mV
*/
#define BCM2835_TS_TSENSCTL_CTRL_BITS 3
#define BCM2835_TS_TSENSCTL_CTRL_SHIFT 2
#define BCM2835_TS_TSENSCTL_CTRL_MASK \
GENMASK(BCM2835_TS_TSENSCTL_CTRL_BITS + \
BCM2835_TS_TSENSCTL_CTRL_SHIFT - 1, \
BCM2835_TS_TSENSCTL_CTRL_SHIFT)
#define BCM2835_TS_TSENSCTL_CTRL_DEFAULT 1
#define BCM2835_TS_TSENSCTL_EN_INT BIT(5)
#define BCM2835_TS_TSENSCTL_DIRECT BIT(6)
#define BCM2835_TS_TSENSCTL_CLR_INT BIT(7)
#define BCM2835_TS_TSENSCTL_THOLD_SHIFT 8
#define BCM2835_TS_TSENSCTL_THOLD_BITS 10
#define BCM2835_TS_TSENSCTL_THOLD_MASK \
GENMASK(BCM2835_TS_TSENSCTL_THOLD_BITS + \
BCM2835_TS_TSENSCTL_THOLD_SHIFT - 1, \
BCM2835_TS_TSENSCTL_THOLD_SHIFT)
/*
* time how long the block to be asserted in reset
* which based on a clock counter (TSENS clock assumed)
*/
#define BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT 18
#define BCM2835_TS_TSENSCTL_RSTDELAY_BITS 8
#define BCM2835_TS_TSENSCTL_REGULEN BIT(26)
#define BCM2835_TS_TSENSSTAT_DATA_BITS 10
#define BCM2835_TS_TSENSSTAT_DATA_SHIFT 0
#define BCM2835_TS_TSENSSTAT_DATA_MASK \
GENMASK(BCM2835_TS_TSENSSTAT_DATA_BITS + \
BCM2835_TS_TSENSSTAT_DATA_SHIFT - 1, \
BCM2835_TS_TSENSSTAT_DATA_SHIFT)
#define BCM2835_TS_TSENSSTAT_VALID BIT(10)
#define BCM2835_TS_TSENSSTAT_INTERRUPT BIT(11)
struct
bcm2835_thermal_data
{
struct
thermal_zone_device
*
tz
;
void
__iomem
*
regs
;
struct
clk
*
clk
;
struct
dentry
*
debugfsdir
;
};
static
int
bcm2835_thermal_adc2temp
(
u32
adc
,
int
offset
,
int
slope
)
{
return
offset
+
slope
*
adc
;
}
static
int
bcm2835_thermal_temp2adc
(
int
temp
,
int
offset
,
int
slope
)
{
temp
-=
offset
;
temp
/=
slope
;
if
(
temp
<
0
)
temp
=
0
;
if
(
temp
>=
BIT
(
BCM2835_TS_TSENSSTAT_DATA_BITS
))
temp
=
BIT
(
BCM2835_TS_TSENSSTAT_DATA_BITS
)
-
1
;
return
temp
;
}
static
int
bcm2835_thermal_get_temp
(
void
*
d
,
int
*
temp
)
{
struct
bcm2835_thermal_data
*
data
=
d
;
u32
val
=
readl
(
data
->
regs
+
BCM2835_TS_TSENSSTAT
);
if
(
!
(
val
&
BCM2835_TS_TSENSSTAT_VALID
))
return
-
EIO
;
val
&=
BCM2835_TS_TSENSSTAT_DATA_MASK
;
*
temp
=
bcm2835_thermal_adc2temp
(
val
,
thermal_zone_get_offset
(
data
->
tz
),
thermal_zone_get_slope
(
data
->
tz
));
return
0
;
}
static
const
struct
debugfs_reg32
bcm2835_thermal_regs
[]
=
{
{
.
name
=
"ctl"
,
.
offset
=
0
},
{
.
name
=
"stat"
,
.
offset
=
4
}
};
static
void
bcm2835_thermal_debugfs
(
struct
platform_device
*
pdev
)
{
struct
thermal_zone_device
*
tz
=
platform_get_drvdata
(
pdev
);
struct
bcm2835_thermal_data
*
data
=
tz
->
devdata
;
struct
debugfs_regset32
*
regset
;
data
->
debugfsdir
=
debugfs_create_dir
(
"bcm2835_thermal"
,
NULL
);
if
(
!
data
->
debugfsdir
)
return
;
regset
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
regset
),
GFP_KERNEL
);
if
(
!
regset
)
return
;
regset
->
regs
=
bcm2835_thermal_regs
;
regset
->
nregs
=
ARRAY_SIZE
(
bcm2835_thermal_regs
);
regset
->
base
=
data
->
regs
;
debugfs_create_regset32
(
"regset"
,
0444
,
data
->
debugfsdir
,
regset
);
}
static
struct
thermal_zone_of_device_ops
bcm2835_thermal_ops
=
{
.
get_temp
=
bcm2835_thermal_get_temp
,
};
/*
* Note: as per Raspberry Foundation FAQ
* (https://www.raspberrypi.org/help/faqs/#performanceOperatingTemperature)
* the recommended temperature range for the SoC -40C to +85C
* so the trip limit is set to 80C.
* this applies to all the BCM283X SoC
*/
static
const
struct
of_device_id
bcm2835_thermal_of_match_table
[]
=
{
{
.
compatible
=
"brcm,bcm2835-thermal"
,
},
{
.
compatible
=
"brcm,bcm2836-thermal"
,
},
{
.
compatible
=
"brcm,bcm2837-thermal"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
bcm2835_thermal_of_match_table
);
static
int
bcm2835_thermal_probe
(
struct
platform_device
*
pdev
)
{
const
struct
of_device_id
*
match
;
struct
thermal_zone_device
*
tz
;
struct
bcm2835_thermal_data
*
data
;
struct
resource
*
res
;
int
err
=
0
;
u32
val
;
unsigned
long
rate
;
data
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
data
),
GFP_KERNEL
);
if
(
!
data
)
return
-
ENOMEM
;
match
=
of_match_device
(
bcm2835_thermal_of_match_table
,
&
pdev
->
dev
);
if
(
!
match
)
return
-
EINVAL
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
data
->
regs
=
devm_ioremap_resource
(
&
pdev
->
dev
,
res
);
if
(
IS_ERR
(
data
->
regs
))
{
err
=
PTR_ERR
(
data
->
regs
);
dev_err
(
&
pdev
->
dev
,
"Could not get registers: %d
\n
"
,
err
);
return
err
;
}
data
->
clk
=
devm_clk_get
(
&
pdev
->
dev
,
NULL
);
if
(
IS_ERR
(
data
->
clk
))
{
err
=
PTR_ERR
(
data
->
clk
);
if
(
err
!=
-
EPROBE_DEFER
)
dev_err
(
&
pdev
->
dev
,
"Could not get clk: %d
\n
"
,
err
);
return
err
;
}
err
=
clk_prepare_enable
(
data
->
clk
);
if
(
err
)
return
err
;
rate
=
clk_get_rate
(
data
->
clk
);
if
((
rate
<
1920000
)
||
(
rate
>
5000000
))
dev_warn
(
&
pdev
->
dev
,
"Clock %pCn running at %pCr Hz is outside of the recommended range: 1.92 to 5MHz
\n
"
,
data
->
clk
,
data
->
clk
);
/* register of thermal sensor and get info from DT */
tz
=
thermal_zone_of_sensor_register
(
&
pdev
->
dev
,
0
,
data
,
&
bcm2835_thermal_ops
);
if
(
IS_ERR
(
tz
))
{
err
=
PTR_ERR
(
tz
);
dev_err
(
&
pdev
->
dev
,
"Failed to register the thermal device: %d
\n
"
,
err
);
goto
err_clk
;
}
/*
* right now the FW does set up the HW-block, so we are not
* touching the configuration registers.
* But if the HW is not enabled, then set it up
* using "sane" values used by the firmware right now.
*/
val
=
readl
(
data
->
regs
+
BCM2835_TS_TSENSCTL
);
if
(
!
(
val
&
BCM2835_TS_TSENSCTL_RSTB
))
{
int
trip_temp
,
offset
,
slope
;
slope
=
thermal_zone_get_slope
(
tz
);
offset
=
thermal_zone_get_offset
(
tz
);
/*
* For now we deal only with critical, otherwise
* would need to iterate
*/
err
=
tz
->
ops
->
get_trip_temp
(
tz
,
0
,
&
trip_temp
);
if
(
err
<
0
)
{
err
=
PTR_ERR
(
tz
);
dev_err
(
&
pdev
->
dev
,
"Not able to read trip_temp: %d
\n
"
,
err
);
goto
err_tz
;
}
/* set bandgap reference voltage and enable voltage regulator */
val
=
(
BCM2835_TS_TSENSCTL_CTRL_DEFAULT
<<
BCM2835_TS_TSENSCTL_CTRL_SHIFT
)
|
BCM2835_TS_TSENSCTL_REGULEN
;
/* use the recommended reset duration */
val
|=
(
0xFE
<<
BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT
);
/* trip_adc value from info */
val
|=
bcm2835_thermal_temp2adc
(
trip_temp
,
offset
,
slope
)
<<
BCM2835_TS_TSENSCTL_THOLD_SHIFT
;
/* write the value back to the register as 2 steps */
writel
(
val
,
data
->
regs
+
BCM2835_TS_TSENSCTL
);
val
|=
BCM2835_TS_TSENSCTL_RSTB
;
writel
(
val
,
data
->
regs
+
BCM2835_TS_TSENSCTL
);
}
data
->
tz
=
tz
;
platform_set_drvdata
(
pdev
,
tz
);
bcm2835_thermal_debugfs
(
pdev
);
return
0
;
err_tz:
thermal_zone_of_sensor_unregister
(
&
pdev
->
dev
,
tz
);
err_clk:
clk_disable_unprepare
(
data
->
clk
);
return
err
;
}
static
int
bcm2835_thermal_remove
(
struct
platform_device
*
pdev
)
{
struct
thermal_zone_device
*
tz
=
platform_get_drvdata
(
pdev
);
struct
bcm2835_thermal_data
*
data
=
tz
->
devdata
;
debugfs_remove_recursive
(
data
->
debugfsdir
);
thermal_zone_of_sensor_unregister
(
&
pdev
->
dev
,
tz
);
clk_disable_unprepare
(
data
->
clk
);
return
0
;
}
static
struct
platform_driver
bcm2835_thermal_driver
=
{
.
probe
=
bcm2835_thermal_probe
,
.
remove
=
bcm2835_thermal_remove
,
.
driver
=
{
.
name
=
"bcm2835_thermal"
,
.
of_match_table
=
bcm2835_thermal_of_match_table
,
},
};
module_platform_driver
(
bcm2835_thermal_driver
);
MODULE_AUTHOR
(
"Martin Sperl"
);
MODULE_DESCRIPTION
(
"Thermal driver for bcm2835 chip"
);
MODULE_LICENSE
(
"GPL"
);
drivers/thermal/broadcom/ns-thermal.c
0 → 100644
浏览文件 @
cb15c81a
/*
* Copyright (C) 2017 Rafał Miłecki <rafal@milecki.pl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
#define PVTMON_CONTROL0 0x00
#define PVTMON_CONTROL0_SEL_MASK 0x0000000e
#define PVTMON_CONTROL0_SEL_TEMP_MONITOR 0x00000000
#define PVTMON_CONTROL0_SEL_TEST_MODE 0x0000000e
#define PVTMON_STATUS 0x08
struct
ns_thermal
{
struct
thermal_zone_device
*
tz
;
void
__iomem
*
pvtmon
;
};
static
int
ns_thermal_get_temp
(
void
*
data
,
int
*
temp
)
{
struct
ns_thermal
*
ns_thermal
=
data
;
int
offset
=
thermal_zone_get_offset
(
ns_thermal
->
tz
);
int
slope
=
thermal_zone_get_slope
(
ns_thermal
->
tz
);
u32
val
;
val
=
readl
(
ns_thermal
->
pvtmon
+
PVTMON_CONTROL0
);
if
((
val
&
PVTMON_CONTROL0_SEL_MASK
)
!=
PVTMON_CONTROL0_SEL_TEMP_MONITOR
)
{
/* Clear current mode selection */
val
&=
~
PVTMON_CONTROL0_SEL_MASK
;
/* Set temp monitor mode (it's the default actually) */
val
|=
PVTMON_CONTROL0_SEL_TEMP_MONITOR
;
writel
(
val
,
ns_thermal
->
pvtmon
+
PVTMON_CONTROL0
);
}
val
=
readl
(
ns_thermal
->
pvtmon
+
PVTMON_STATUS
);
*
temp
=
slope
*
val
+
offset
;
return
0
;
}
static
const
struct
thermal_zone_of_device_ops
ns_thermal_ops
=
{
.
get_temp
=
ns_thermal_get_temp
,
};
static
int
ns_thermal_probe
(
struct
platform_device
*
pdev
)
{
struct
device
*
dev
=
&
pdev
->
dev
;
struct
ns_thermal
*
ns_thermal
;
ns_thermal
=
devm_kzalloc
(
dev
,
sizeof
(
*
ns_thermal
),
GFP_KERNEL
);
if
(
!
ns_thermal
)
return
-
ENOMEM
;
ns_thermal
->
pvtmon
=
of_iomap
(
dev_of_node
(
dev
),
0
);
if
(
WARN_ON
(
!
ns_thermal
->
pvtmon
))
return
-
ENOENT
;
ns_thermal
->
tz
=
devm_thermal_zone_of_sensor_register
(
dev
,
0
,
ns_thermal
,
&
ns_thermal_ops
);
if
(
IS_ERR
(
ns_thermal
->
tz
))
{
iounmap
(
ns_thermal
->
pvtmon
);
return
PTR_ERR
(
ns_thermal
->
tz
);
}
platform_set_drvdata
(
pdev
,
ns_thermal
);
return
0
;
}
static
int
ns_thermal_remove
(
struct
platform_device
*
pdev
)
{
struct
ns_thermal
*
ns_thermal
=
platform_get_drvdata
(
pdev
);
iounmap
(
ns_thermal
->
pvtmon
);
return
0
;
}
static
const
struct
of_device_id
ns_thermal_of_match
[]
=
{
{
.
compatible
=
"brcm,ns-thermal"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
ns_thermal_of_match
);
static
struct
platform_driver
ns_thermal_driver
=
{
.
probe
=
ns_thermal_probe
,
.
remove
=
ns_thermal_remove
,
.
driver
=
{
.
name
=
"ns-thermal"
,
.
of_match_table
=
ns_thermal_of_match
,
},
};
module_platform_driver
(
ns_thermal_driver
);
MODULE_AUTHOR
(
"Rafał Miłecki <rafal@milecki.pl>"
);
MODULE_DESCRIPTION
(
"Northstar thermal driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/thermal/da9062-thermal.c
0 → 100644
浏览文件 @
cb15c81a
/*
* Thermal device driver for DA9062 and DA9061
* Copyright (C) 2017 Dialog Semiconductor
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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.
*/
/* When over-temperature is reached, an interrupt from the device will be
* triggered. Following this event the interrupt will be disabled and
* periodic transmission of uevents (HOT trip point) should define the
* first level of temperature supervision. It is expected that any final
* implementation of the thermal driver will include a .notify() function
* to implement these uevents to userspace.
*
* These uevents are intended to indicate non-invasive temperature control
* of the system, where the necessary measures for cooling are the
* responsibility of the host software. Once the temperature falls again,
* the IRQ is re-enabled so the start of a new over-temperature event can
* be detected without constant software monitoring.
*/
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/thermal.h>
#include <linux/workqueue.h>
#include <linux/mfd/da9062/core.h>
#include <linux/mfd/da9062/registers.h>
/* Minimum, maximum and default polling millisecond periods are provided
* here as an example. It is expected that any final implementation to also
* include a modification of these settings to match the required
* application.
*/
#define DA9062_DEFAULT_POLLING_MS_PERIOD 3000
#define DA9062_MAX_POLLING_MS_PERIOD 10000
#define DA9062_MIN_POLLING_MS_PERIOD 1000
#define DA9062_MILLI_CELSIUS(t) ((t) * 1000)
struct
da9062_thermal_config
{
const
char
*
name
;
};
struct
da9062_thermal
{
struct
da9062
*
hw
;
struct
delayed_work
work
;
struct
thermal_zone_device
*
zone
;
enum
thermal_device_mode
mode
;
struct
mutex
lock
;
/* protection for da9062_thermal temperature */
int
temperature
;
int
irq
;
const
struct
da9062_thermal_config
*
config
;
struct
device
*
dev
;
};
static
void
da9062_thermal_poll_on
(
struct
work_struct
*
work
)
{
struct
da9062_thermal
*
thermal
=
container_of
(
work
,
struct
da9062_thermal
,
work
.
work
);
unsigned
long
delay
;
unsigned
int
val
;
int
ret
;
/* clear E_TEMP */
ret
=
regmap_write
(
thermal
->
hw
->
regmap
,
DA9062AA_EVENT_B
,
DA9062AA_E_TEMP_MASK
);
if
(
ret
<
0
)
{
dev_err
(
thermal
->
dev
,
"Cannot clear the TJUNC temperature status
\n
"
);
goto
err_enable_irq
;
}
/* Now read E_TEMP again: it is acting like a status bit.
* If over-temperature, then this status will be true.
* If not over-temperature, this status will be false.
*/
ret
=
regmap_read
(
thermal
->
hw
->
regmap
,
DA9062AA_EVENT_B
,
&
val
);
if
(
ret
<
0
)
{
dev_err
(
thermal
->
dev
,
"Cannot check the TJUNC temperature status
\n
"
);
goto
err_enable_irq
;
}
if
(
val
&
DA9062AA_E_TEMP_MASK
)
{
mutex_lock
(
&
thermal
->
lock
);
thermal
->
temperature
=
DA9062_MILLI_CELSIUS
(
125
);
mutex_unlock
(
&
thermal
->
lock
);
thermal_zone_device_update
(
thermal
->
zone
,
THERMAL_EVENT_UNSPECIFIED
);
delay
=
msecs_to_jiffies
(
thermal
->
zone
->
passive_delay
);
schedule_delayed_work
(
&
thermal
->
work
,
delay
);
return
;
}
mutex_lock
(
&
thermal
->
lock
);
thermal
->
temperature
=
DA9062_MILLI_CELSIUS
(
0
);
mutex_unlock
(
&
thermal
->
lock
);
thermal_zone_device_update
(
thermal
->
zone
,
THERMAL_EVENT_UNSPECIFIED
);
err_enable_irq:
enable_irq
(
thermal
->
irq
);
}
static
irqreturn_t
da9062_thermal_irq_handler
(
int
irq
,
void
*
data
)
{
struct
da9062_thermal
*
thermal
=
data
;
disable_irq_nosync
(
thermal
->
irq
);
schedule_delayed_work
(
&
thermal
->
work
,
0
);
return
IRQ_HANDLED
;
}
static
int
da9062_thermal_get_mode
(
struct
thermal_zone_device
*
z
,
enum
thermal_device_mode
*
mode
)
{
struct
da9062_thermal
*
thermal
=
z
->
devdata
;
*
mode
=
thermal
->
mode
;
return
0
;
}
static
int
da9062_thermal_get_trip_type
(
struct
thermal_zone_device
*
z
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
struct
da9062_thermal
*
thermal
=
z
->
devdata
;
switch
(
trip
)
{
case
0
:
*
type
=
THERMAL_TRIP_HOT
;
break
;
default:
dev_err
(
thermal
->
dev
,
"Driver does not support more than 1 trip-wire
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
int
da9062_thermal_get_trip_temp
(
struct
thermal_zone_device
*
z
,
int
trip
,
int
*
temp
)
{
struct
da9062_thermal
*
thermal
=
z
->
devdata
;
switch
(
trip
)
{
case
0
:
*
temp
=
DA9062_MILLI_CELSIUS
(
125
);
break
;
default:
dev_err
(
thermal
->
dev
,
"Driver does not support more than 1 trip-wire
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
int
da9062_thermal_get_temp
(
struct
thermal_zone_device
*
z
,
int
*
temp
)
{
struct
da9062_thermal
*
thermal
=
z
->
devdata
;
mutex_lock
(
&
thermal
->
lock
);
*
temp
=
thermal
->
temperature
;
mutex_unlock
(
&
thermal
->
lock
);
return
0
;
}
static
struct
thermal_zone_device_ops
da9062_thermal_ops
=
{
.
get_temp
=
da9062_thermal_get_temp
,
.
get_mode
=
da9062_thermal_get_mode
,
.
get_trip_type
=
da9062_thermal_get_trip_type
,
.
get_trip_temp
=
da9062_thermal_get_trip_temp
,
};
static
const
struct
da9062_thermal_config
da9062_config
=
{
.
name
=
"da9062-thermal"
,
};
static
const
struct
of_device_id
da9062_compatible_reg_id_table
[]
=
{
{
.
compatible
=
"dlg,da9062-thermal"
,
.
data
=
&
da9062_config
},
{
},
};
MODULE_DEVICE_TABLE
(
of
,
da9062_compatible_reg_id_table
);
static
int
da9062_thermal_probe
(
struct
platform_device
*
pdev
)
{
struct
da9062
*
chip
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
da9062_thermal
*
thermal
;
unsigned
int
pp_tmp
=
DA9062_DEFAULT_POLLING_MS_PERIOD
;
const
struct
of_device_id
*
match
;
int
ret
=
0
;
match
=
of_match_node
(
da9062_compatible_reg_id_table
,
pdev
->
dev
.
of_node
);
if
(
!
match
)
return
-
ENXIO
;
if
(
pdev
->
dev
.
of_node
)
{
if
(
!
of_property_read_u32
(
pdev
->
dev
.
of_node
,
"polling-delay-passive"
,
&
pp_tmp
))
{
if
(
pp_tmp
<
DA9062_MIN_POLLING_MS_PERIOD
||
pp_tmp
>
DA9062_MAX_POLLING_MS_PERIOD
)
{
dev_warn
(
&
pdev
->
dev
,
"Out-of-range polling period %d ms
\n
"
,
pp_tmp
);
pp_tmp
=
DA9062_DEFAULT_POLLING_MS_PERIOD
;
}
}
}
thermal
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
da9062_thermal
),
GFP_KERNEL
);
if
(
!
thermal
)
{
ret
=
-
ENOMEM
;
goto
err
;
}
thermal
->
config
=
match
->
data
;
thermal
->
hw
=
chip
;
thermal
->
mode
=
THERMAL_DEVICE_ENABLED
;
thermal
->
dev
=
&
pdev
->
dev
;
INIT_DELAYED_WORK
(
&
thermal
->
work
,
da9062_thermal_poll_on
);
mutex_init
(
&
thermal
->
lock
);
thermal
->
zone
=
thermal_zone_device_register
(
thermal
->
config
->
name
,
1
,
0
,
thermal
,
&
da9062_thermal_ops
,
NULL
,
pp_tmp
,
0
);
if
(
IS_ERR
(
thermal
->
zone
))
{
dev_err
(
&
pdev
->
dev
,
"Cannot register thermal zone device
\n
"
);
ret
=
PTR_ERR
(
thermal
->
zone
);
goto
err
;
}
dev_dbg
(
&
pdev
->
dev
,
"TJUNC temperature polling period set at %d ms
\n
"
,
thermal
->
zone
->
passive_delay
);
ret
=
platform_get_irq_byname
(
pdev
,
"THERMAL"
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to get platform IRQ.
\n
"
);
goto
err_zone
;
}
thermal
->
irq
=
ret
;
ret
=
request_threaded_irq
(
thermal
->
irq
,
NULL
,
da9062_thermal_irq_handler
,
IRQF_TRIGGER_LOW
|
IRQF_ONESHOT
,
"THERMAL"
,
thermal
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to request thermal device IRQ.
\n
"
);
goto
err_zone
;
}
platform_set_drvdata
(
pdev
,
thermal
);
return
0
;
err_zone:
thermal_zone_device_unregister
(
thermal
->
zone
);
err:
return
ret
;
}
static
int
da9062_thermal_remove
(
struct
platform_device
*
pdev
)
{
struct
da9062_thermal
*
thermal
=
platform_get_drvdata
(
pdev
);
free_irq
(
thermal
->
irq
,
thermal
);
cancel_delayed_work_sync
(
&
thermal
->
work
);
thermal_zone_device_unregister
(
thermal
->
zone
);
return
0
;
}
static
struct
platform_driver
da9062_thermal_driver
=
{
.
probe
=
da9062_thermal_probe
,
.
remove
=
da9062_thermal_remove
,
.
driver
=
{
.
name
=
"da9062-thermal"
,
.
of_match_table
=
da9062_compatible_reg_id_table
,
},
};
module_platform_driver
(
da9062_thermal_driver
);
MODULE_AUTHOR
(
"Steve Twiss"
);
MODULE_DESCRIPTION
(
"Thermal TJUNC device driver for Dialog DA9062 and DA9061"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_ALIAS
(
"platform:da9062-thermal"
);
drivers/thermal/mtk_thermal.c
浏览文件 @
cb15c81a
...
...
@@ -191,7 +191,7 @@ static const int mt8173_bank_data[MT8173_NUM_ZONES][3] = {
};
static
const
int
mt8173_msr
[
MT8173_NUM_SENSORS_PER_ZONE
]
=
{
TEMP_MSR0
,
TEMP_MSR1
,
TEMP_MSR2
,
TEMP_MSR
2
TEMP_MSR0
,
TEMP_MSR1
,
TEMP_MSR2
,
TEMP_MSR
3
};
static
const
int
mt8173_adcpnp
[
MT8173_NUM_SENSORS_PER_ZONE
]
=
{
...
...
drivers/thermal/rcar_gen3_thermal.c
浏览文件 @
cb15c81a
...
...
@@ -20,12 +20,14 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock.h>
#include <linux/thermal.h>
#include "thermal_core.h"
/* Register offsets */
#define REG_GEN3_IRQSTR 0x04
#define REG_GEN3_IRQMSK 0x08
...
...
@@ -41,6 +43,14 @@
#define REG_GEN3_THCODE2 0x54
#define REG_GEN3_THCODE3 0x58
/* IRQ{STR,MSK,EN} bits */
#define IRQ_TEMP1 BIT(0)
#define IRQ_TEMP2 BIT(1)
#define IRQ_TEMP3 BIT(2)
#define IRQ_TEMPD1 BIT(3)
#define IRQ_TEMPD2 BIT(4)
#define IRQ_TEMPD3 BIT(5)
/* CTSR bits */
#define CTSR_PONM BIT(8)
#define CTSR_AOUT BIT(7)
...
...
@@ -72,11 +82,15 @@ struct rcar_gen3_thermal_tsc {
void
__iomem
*
base
;
struct
thermal_zone_device
*
zone
;
struct
equation_coefs
coef
;
struct
mutex
lock
;
int
low
;
int
high
;
};
struct
rcar_gen3_thermal_priv
{
struct
rcar_gen3_thermal_tsc
*
tscs
[
TSC_MAX_NUM
];
unsigned
int
num_tscs
;
spinlock_t
lock
;
/* Protect interrupts on and off */
const
struct
rcar_gen3_thermal_data
*
data
;
};
struct
rcar_gen3_thermal_data
{
...
...
@@ -114,6 +128,7 @@ static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc,
#define FIXPT_SHIFT 7
#define FIXPT_INT(_x) ((_x) << FIXPT_SHIFT)
#define INT_FIXPT(_x) ((_x) >> FIXPT_SHIFT)
#define FIXPT_DIV(_a, _b) DIV_ROUND_CLOSEST(((_a) << FIXPT_SHIFT), (_b))
#define FIXPT_TO_MCELSIUS(_x) ((_x) * 1000 >> FIXPT_SHIFT)
...
...
@@ -163,16 +178,12 @@ static int rcar_gen3_thermal_get_temp(void *devdata, int *temp)
u32
reg
;
/* Read register and convert to mili Celsius */
mutex_lock
(
&
tsc
->
lock
);
reg
=
rcar_gen3_thermal_read
(
tsc
,
REG_GEN3_TEMP
)
&
CTEMP_MASK
;
val1
=
FIXPT_DIV
(
FIXPT_INT
(
reg
)
-
tsc
->
coef
.
b1
,
tsc
->
coef
.
a1
);
val2
=
FIXPT_DIV
(
FIXPT_INT
(
reg
)
-
tsc
->
coef
.
b2
,
tsc
->
coef
.
a2
);
mcelsius
=
FIXPT_TO_MCELSIUS
((
val1
+
val2
)
/
2
);
mutex_unlock
(
&
tsc
->
lock
);
/* Make sure we are inside specifications */
if
((
mcelsius
<
MCELSIUS
(
-
40
))
||
(
mcelsius
>
MCELSIUS
(
125
)))
return
-
EIO
;
...
...
@@ -183,10 +194,90 @@ static int rcar_gen3_thermal_get_temp(void *devdata, int *temp)
return
0
;
}
static
int
rcar_gen3_thermal_mcelsius_to_temp
(
struct
rcar_gen3_thermal_tsc
*
tsc
,
int
mcelsius
)
{
int
celsius
,
val1
,
val2
;
celsius
=
DIV_ROUND_CLOSEST
(
mcelsius
,
1000
);
val1
=
celsius
*
tsc
->
coef
.
a1
+
tsc
->
coef
.
b1
;
val2
=
celsius
*
tsc
->
coef
.
a2
+
tsc
->
coef
.
b2
;
return
INT_FIXPT
((
val1
+
val2
)
/
2
);
}
static
int
rcar_gen3_thermal_set_trips
(
void
*
devdata
,
int
low
,
int
high
)
{
struct
rcar_gen3_thermal_tsc
*
tsc
=
devdata
;
low
=
clamp_val
(
low
,
-
40000
,
125000
);
high
=
clamp_val
(
high
,
-
40000
,
125000
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_IRQTEMP1
,
rcar_gen3_thermal_mcelsius_to_temp
(
tsc
,
low
));
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_IRQTEMP2
,
rcar_gen3_thermal_mcelsius_to_temp
(
tsc
,
high
));
tsc
->
low
=
low
;
tsc
->
high
=
high
;
return
0
;
}
static
struct
thermal_zone_of_device_ops
rcar_gen3_tz_of_ops
=
{
.
get_temp
=
rcar_gen3_thermal_get_temp
,
.
set_trips
=
rcar_gen3_thermal_set_trips
,
};
static
void
rcar_thermal_irq_set
(
struct
rcar_gen3_thermal_priv
*
priv
,
bool
on
)
{
unsigned
int
i
;
u32
val
=
on
?
IRQ_TEMPD1
|
IRQ_TEMP2
:
0
;
for
(
i
=
0
;
i
<
priv
->
num_tscs
;
i
++
)
rcar_gen3_thermal_write
(
priv
->
tscs
[
i
],
REG_GEN3_IRQMSK
,
val
);
}
static
irqreturn_t
rcar_gen3_thermal_irq
(
int
irq
,
void
*
data
)
{
struct
rcar_gen3_thermal_priv
*
priv
=
data
;
u32
status
;
int
i
,
ret
=
IRQ_HANDLED
;
spin_lock
(
&
priv
->
lock
);
for
(
i
=
0
;
i
<
priv
->
num_tscs
;
i
++
)
{
status
=
rcar_gen3_thermal_read
(
priv
->
tscs
[
i
],
REG_GEN3_IRQSTR
);
rcar_gen3_thermal_write
(
priv
->
tscs
[
i
],
REG_GEN3_IRQSTR
,
0
);
if
(
status
)
ret
=
IRQ_WAKE_THREAD
;
}
if
(
ret
==
IRQ_WAKE_THREAD
)
rcar_thermal_irq_set
(
priv
,
false
);
spin_unlock
(
&
priv
->
lock
);
return
ret
;
}
static
irqreturn_t
rcar_gen3_thermal_irq_thread
(
int
irq
,
void
*
data
)
{
struct
rcar_gen3_thermal_priv
*
priv
=
data
;
unsigned
long
flags
;
int
i
;
for
(
i
=
0
;
i
<
priv
->
num_tscs
;
i
++
)
thermal_zone_device_update
(
priv
->
tscs
[
i
]
->
zone
,
THERMAL_EVENT_UNSPECIFIED
);
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
rcar_thermal_irq_set
(
priv
,
true
);
spin_unlock_irqrestore
(
&
priv
->
lock
,
flags
);
return
IRQ_HANDLED
;
}
static
void
r8a7795_thermal_init
(
struct
rcar_gen3_thermal_tsc
*
tsc
)
{
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_CTSR
,
CTSR_THBGR
);
...
...
@@ -195,7 +286,11 @@ static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
usleep_range
(
1000
,
2000
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_CTSR
,
CTSR_PONM
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_IRQCTL
,
0x3F
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_IRQMSK
,
0
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_IRQEN
,
IRQ_TEMPD1
|
IRQ_TEMP2
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_CTSR
,
CTSR_PONM
|
CTSR_AOUT
|
CTSR_THBGR
|
CTSR_VMEN
);
...
...
@@ -219,9 +314,14 @@ static void r8a7796_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
usleep_range
(
1000
,
2000
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_IRQCTL
,
0x3F
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_IRQMSK
,
0
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_IRQEN
,
IRQ_TEMPD1
|
IRQ_TEMP2
);
reg_val
=
rcar_gen3_thermal_read
(
tsc
,
REG_GEN3_THCTR
);
reg_val
|=
THCTR_THSST
;
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_THCTR
,
reg_val
);
usleep_range
(
1000
,
2000
);
}
static
const
struct
rcar_gen3_thermal_data
r8a7795_data
=
{
...
...
@@ -255,9 +355,8 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
struct
device
*
dev
=
&
pdev
->
dev
;
struct
resource
*
res
;
struct
thermal_zone_device
*
zone
;
int
ret
,
i
;
const
struct
rcar_gen3_thermal_data
*
match_data
=
of_device_get_match_data
(
dev
);
int
ret
,
irq
,
i
;
char
*
irqname
;
/* default values if FUSEs are missing */
/* TODO: Read values from hardware on supported platforms */
...
...
@@ -272,24 +371,50 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
if
(
!
priv
)
return
-
ENOMEM
;
priv
->
data
=
of_device_get_match_data
(
dev
);
spin_lock_init
(
&
priv
->
lock
);
platform_set_drvdata
(
pdev
,
priv
);
/*
* Request 2 (of the 3 possible) IRQs, the driver only needs to
* to trigger on the low and high trip points of the current
* temp window at this point.
*/
for
(
i
=
0
;
i
<
2
;
i
++
)
{
irq
=
platform_get_irq
(
pdev
,
i
);
if
(
irq
<
0
)
return
irq
;
irqname
=
devm_kasprintf
(
dev
,
GFP_KERNEL
,
"%s:ch%d"
,
dev_name
(
dev
),
i
);
if
(
!
irqname
)
return
-
ENOMEM
;
ret
=
devm_request_threaded_irq
(
dev
,
irq
,
rcar_gen3_thermal_irq
,
rcar_gen3_thermal_irq_thread
,
IRQF_SHARED
,
irqname
,
priv
);
if
(
ret
)
return
ret
;
}
pm_runtime_enable
(
dev
);
pm_runtime_get_sync
(
dev
);
for
(
i
=
0
;
i
<
TSC_MAX_NUM
;
i
++
)
{
struct
rcar_gen3_thermal_tsc
*
tsc
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
i
);
if
(
!
res
)
break
;
tsc
=
devm_kzalloc
(
dev
,
sizeof
(
*
tsc
),
GFP_KERNEL
);
if
(
!
tsc
)
{
ret
=
-
ENOMEM
;
goto
error_unregister
;
}
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
i
);
if
(
!
res
)
break
;
tsc
->
base
=
devm_ioremap_resource
(
dev
,
res
);
if
(
IS_ERR
(
tsc
->
base
))
{
ret
=
PTR_ERR
(
tsc
->
base
);
...
...
@@ -297,9 +422,8 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
}
priv
->
tscs
[
i
]
=
tsc
;
mutex_init
(
&
tsc
->
lock
);
match_
data
->
thermal_init
(
tsc
);
priv
->
data
->
thermal_init
(
tsc
);
rcar_gen3_thermal_calc_coefs
(
&
tsc
->
coef
,
ptat
,
thcode
[
i
]);
zone
=
devm_thermal_zone_of_sensor_register
(
dev
,
i
,
tsc
,
...
...
@@ -310,8 +434,23 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
goto
error_unregister
;
}
tsc
->
zone
=
zone
;
ret
=
of_thermal_get_ntrips
(
tsc
->
zone
);
if
(
ret
<
0
)
goto
error_unregister
;
dev_info
(
dev
,
"TSC%d: Loaded %d trip points
\n
"
,
i
,
ret
);
}
priv
->
num_tscs
=
i
;
if
(
!
priv
->
num_tscs
)
{
ret
=
-
ENODEV
;
goto
error_unregister
;
}
rcar_thermal_irq_set
(
priv
,
true
);
return
0
;
error_unregister:
...
...
@@ -320,9 +459,39 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
return
ret
;
}
static
int
__maybe_unused
rcar_gen3_thermal_suspend
(
struct
device
*
dev
)
{
struct
rcar_gen3_thermal_priv
*
priv
=
dev_get_drvdata
(
dev
);
rcar_thermal_irq_set
(
priv
,
false
);
return
0
;
}
static
int
__maybe_unused
rcar_gen3_thermal_resume
(
struct
device
*
dev
)
{
struct
rcar_gen3_thermal_priv
*
priv
=
dev_get_drvdata
(
dev
);
unsigned
int
i
;
for
(
i
=
0
;
i
<
priv
->
num_tscs
;
i
++
)
{
struct
rcar_gen3_thermal_tsc
*
tsc
=
priv
->
tscs
[
i
];
priv
->
data
->
thermal_init
(
tsc
);
rcar_gen3_thermal_set_trips
(
tsc
,
tsc
->
low
,
tsc
->
high
);
}
rcar_thermal_irq_set
(
priv
,
true
);
return
0
;
}
static
SIMPLE_DEV_PM_OPS
(
rcar_gen3_thermal_pm_ops
,
rcar_gen3_thermal_suspend
,
rcar_gen3_thermal_resume
);
static
struct
platform_driver
rcar_gen3_thermal_driver
=
{
.
driver
=
{
.
name
=
"rcar_gen3_thermal"
,
.
pm
=
&
rcar_gen3_thermal_pm_ops
,
.
of_match_table
=
rcar_gen3_thermal_dt_ids
,
},
.
probe
=
rcar_gen3_thermal_probe
,
...
...
drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
浏览文件 @
cb15c81a
...
...
@@ -410,8 +410,6 @@ const struct ti_bandgap_data dra752_data = {
.
domain
=
"cpu"
,
.
register_cooling
=
ti_thermal_register_cpu_cooling
,
.
unregister_cooling
=
ti_thermal_unregister_cpu_cooling
,
.
slope
=
DRA752_GRADIENT_SLOPE
,
.
constant
=
DRA752_GRADIENT_CONST
,
.
slope_pcb
=
DRA752_GRADIENT_SLOPE_W_PCB
,
.
constant_pcb
=
DRA752_GRADIENT_CONST_W_PCB
,
},
...
...
@@ -419,8 +417,6 @@ const struct ti_bandgap_data dra752_data = {
.
registers
=
&
dra752_gpu_temp_sensor_registers
,
.
ts_data
=
&
dra752_gpu_temp_sensor_data
,
.
domain
=
"gpu"
,
.
slope
=
DRA752_GRADIENT_SLOPE
,
.
constant
=
DRA752_GRADIENT_CONST
,
.
slope_pcb
=
DRA752_GRADIENT_SLOPE_W_PCB
,
.
constant_pcb
=
DRA752_GRADIENT_CONST_W_PCB
,
},
...
...
@@ -428,8 +424,6 @@ const struct ti_bandgap_data dra752_data = {
.
registers
=
&
dra752_core_temp_sensor_registers
,
.
ts_data
=
&
dra752_core_temp_sensor_data
,
.
domain
=
"core"
,
.
slope
=
DRA752_GRADIENT_SLOPE
,
.
constant
=
DRA752_GRADIENT_CONST
,
.
slope_pcb
=
DRA752_GRADIENT_SLOPE_W_PCB
,
.
constant_pcb
=
DRA752_GRADIENT_CONST_W_PCB
,
},
...
...
@@ -437,8 +431,6 @@ const struct ti_bandgap_data dra752_data = {
.
registers
=
&
dra752_dspeve_temp_sensor_registers
,
.
ts_data
=
&
dra752_dspeve_temp_sensor_data
,
.
domain
=
"dspeve"
,
.
slope
=
DRA752_GRADIENT_SLOPE
,
.
constant
=
DRA752_GRADIENT_CONST
,
.
slope_pcb
=
DRA752_GRADIENT_SLOPE_W_PCB
,
.
constant_pcb
=
DRA752_GRADIENT_CONST_W_PCB
,
},
...
...
@@ -446,8 +438,6 @@ const struct ti_bandgap_data dra752_data = {
.
registers
=
&
dra752_iva_temp_sensor_registers
,
.
ts_data
=
&
dra752_iva_temp_sensor_data
,
.
domain
=
"iva"
,
.
slope
=
DRA752_GRADIENT_SLOPE
,
.
constant
=
DRA752_GRADIENT_CONST
,
.
slope_pcb
=
DRA752_GRADIENT_SLOPE_W_PCB
,
.
constant_pcb
=
DRA752_GRADIENT_CONST_W_PCB
,
},
...
...
drivers/thermal/ti-soc-thermal/omap3-thermal-data.c
浏览文件 @
cb15c81a
...
...
@@ -91,8 +91,6 @@ const struct ti_bandgap_data omap34xx_data = {
.
registers
=
&
omap34xx_mpu_temp_sensor_registers
,
.
ts_data
=
&
omap34xx_mpu_temp_sensor_data
,
.
domain
=
"cpu"
,
.
slope
=
0
,
.
constant
=
20000
,
.
slope_pcb
=
0
,
.
constant_pcb
=
20000
,
.
register_cooling
=
NULL
,
...
...
@@ -164,8 +162,6 @@ const struct ti_bandgap_data omap36xx_data = {
.
registers
=
&
omap36xx_mpu_temp_sensor_registers
,
.
ts_data
=
&
omap36xx_mpu_temp_sensor_data
,
.
domain
=
"cpu"
,
.
slope
=
0
,
.
constant
=
20000
,
.
slope_pcb
=
0
,
.
constant_pcb
=
20000
,
.
register_cooling
=
NULL
,
...
...
drivers/thermal/ti-soc-thermal/omap4-thermal-data.c
浏览文件 @
cb15c81a
...
...
@@ -82,8 +82,6 @@ const struct ti_bandgap_data omap4430_data = {
.
registers
=
&
omap4430_mpu_temp_sensor_registers
,
.
ts_data
=
&
omap4430_mpu_temp_sensor_data
,
.
domain
=
"cpu"
,
.
slope
=
OMAP_GRADIENT_SLOPE_4430
,
.
constant
=
OMAP_GRADIENT_CONST_4430
,
.
slope_pcb
=
OMAP_GRADIENT_SLOPE_W_PCB_4430
,
.
constant_pcb
=
OMAP_GRADIENT_CONST_W_PCB_4430
,
.
register_cooling
=
ti_thermal_register_cpu_cooling
,
...
...
@@ -222,8 +220,6 @@ const struct ti_bandgap_data omap4460_data = {
.
registers
=
&
omap4460_mpu_temp_sensor_registers
,
.
ts_data
=
&
omap4460_mpu_temp_sensor_data
,
.
domain
=
"cpu"
,
.
slope
=
OMAP_GRADIENT_SLOPE_4460
,
.
constant
=
OMAP_GRADIENT_CONST_4460
,
.
slope_pcb
=
OMAP_GRADIENT_SLOPE_W_PCB_4460
,
.
constant_pcb
=
OMAP_GRADIENT_CONST_W_PCB_4460
,
.
register_cooling
=
ti_thermal_register_cpu_cooling
,
...
...
@@ -255,8 +251,6 @@ const struct ti_bandgap_data omap4470_data = {
.
registers
=
&
omap4460_mpu_temp_sensor_registers
,
.
ts_data
=
&
omap4460_mpu_temp_sensor_data
,
.
domain
=
"cpu"
,
.
slope
=
OMAP_GRADIENT_SLOPE_4470
,
.
constant
=
OMAP_GRADIENT_CONST_4470
,
.
slope_pcb
=
OMAP_GRADIENT_SLOPE_W_PCB_4470
,
.
constant_pcb
=
OMAP_GRADIENT_CONST_W_PCB_4470
,
.
register_cooling
=
ti_thermal_register_cpu_cooling
,
...
...
drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
浏览文件 @
cb15c81a
...
...
@@ -336,8 +336,6 @@ const struct ti_bandgap_data omap5430_data = {
.
domain
=
"cpu"
,
.
register_cooling
=
ti_thermal_register_cpu_cooling
,
.
unregister_cooling
=
ti_thermal_unregister_cpu_cooling
,
.
slope
=
OMAP_GRADIENT_SLOPE_5430_CPU
,
.
constant
=
OMAP_GRADIENT_CONST_5430_CPU
,
.
slope_pcb
=
OMAP_GRADIENT_SLOPE_W_PCB_5430_CPU
,
.
constant_pcb
=
OMAP_GRADIENT_CONST_W_PCB_5430_CPU
,
},
...
...
@@ -345,8 +343,6 @@ const struct ti_bandgap_data omap5430_data = {
.
registers
=
&
omap5430_gpu_temp_sensor_registers
,
.
ts_data
=
&
omap5430_gpu_temp_sensor_data
,
.
domain
=
"gpu"
,
.
slope
=
OMAP_GRADIENT_SLOPE_5430_GPU
,
.
constant
=
OMAP_GRADIENT_CONST_5430_GPU
,
.
slope_pcb
=
OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU
,
.
constant_pcb
=
OMAP_GRADIENT_CONST_W_PCB_5430_GPU
,
},
...
...
drivers/thermal/ti-soc-thermal/ti-bandgap.h
浏览文件 @
cb15c81a
...
...
@@ -254,8 +254,6 @@ struct ti_bandgap {
* @ts_data: pointer to struct with thresholds, limits of temperature sensor
* @registers: pointer to the list of register offsets and bitfields
* @domain: the name of the domain where the sensor is located
* @slope: sensor gradient slope info for hotspot extrapolation equation
* @constant: sensor gradient const info for hotspot extrapolation equation
* @slope_pcb: sensor gradient slope info for hotspot extrapolation equation
* with no external influence
* @constant_pcb: sensor gradient const info for hotspot extrapolation equation
...
...
@@ -274,8 +272,6 @@ struct ti_temp_sensor {
struct
temp_sensor_registers
*
registers
;
char
*
domain
;
/* for hotspot extrapolation */
const
int
slope
;
const
int
constant
;
const
int
slope_pcb
;
const
int
constant_pcb
;
int
(
*
register_cooling
)(
struct
ti_bandgap
*
bgp
,
int
id
);
...
...
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
浏览文件 @
cb15c81a
...
...
@@ -96,8 +96,8 @@ static inline int __ti_thermal_get_temp(void *devdata, int *temp)
return
ret
;
/* Default constants */
slope
=
s
->
slope
;
constant
=
s
->
constant
;
slope
=
thermal_zone_get_slope
(
data
->
ti_thermal
)
;
constant
=
thermal_zone_get_offset
(
data
->
ti_thermal
)
;
pcb_tz
=
data
->
pcb_tz
;
/* In case pcb zone is available, use the extrapolation rule with it */
...
...
@@ -126,119 +126,6 @@ static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
return
__ti_thermal_get_temp
(
data
,
temp
);
}
/* Bind callback functions for thermal zone */
static
int
ti_thermal_bind
(
struct
thermal_zone_device
*
thermal
,
struct
thermal_cooling_device
*
cdev
)
{
struct
ti_thermal_data
*
data
=
thermal
->
devdata
;
int
id
;
if
(
!
data
||
IS_ERR
(
data
))
return
-
ENODEV
;
/* check if this is the cooling device we registered */
if
(
data
->
cool_dev
!=
cdev
)
return
0
;
id
=
data
->
sensor_id
;
/* Simple thing, two trips, one passive another critical */
return
thermal_zone_bind_cooling_device
(
thermal
,
0
,
cdev
,
/* bind with min and max states defined by cpu_cooling */
THERMAL_NO_LIMIT
,
THERMAL_NO_LIMIT
,
THERMAL_WEIGHT_DEFAULT
);
}
/* Unbind callback functions for thermal zone */
static
int
ti_thermal_unbind
(
struct
thermal_zone_device
*
thermal
,
struct
thermal_cooling_device
*
cdev
)
{
struct
ti_thermal_data
*
data
=
thermal
->
devdata
;
if
(
!
data
||
IS_ERR
(
data
))
return
-
ENODEV
;
/* check if this is the cooling device we registered */
if
(
data
->
cool_dev
!=
cdev
)
return
0
;
/* Simple thing, two trips, one passive another critical */
return
thermal_zone_unbind_cooling_device
(
thermal
,
0
,
cdev
);
}
/* Get mode callback functions for thermal zone */
static
int
ti_thermal_get_mode
(
struct
thermal_zone_device
*
thermal
,
enum
thermal_device_mode
*
mode
)
{
struct
ti_thermal_data
*
data
=
thermal
->
devdata
;
if
(
data
)
*
mode
=
data
->
mode
;
return
0
;
}
/* Set mode callback functions for thermal zone */
static
int
ti_thermal_set_mode
(
struct
thermal_zone_device
*
thermal
,
enum
thermal_device_mode
mode
)
{
struct
ti_thermal_data
*
data
=
thermal
->
devdata
;
struct
ti_bandgap
*
bgp
;
bgp
=
data
->
bgp
;
if
(
!
data
->
ti_thermal
)
{
dev_notice
(
&
thermal
->
device
,
"thermal zone not registered
\n
"
);
return
0
;
}
mutex_lock
(
&
data
->
ti_thermal
->
lock
);
if
(
mode
==
THERMAL_DEVICE_ENABLED
)
data
->
ti_thermal
->
polling_delay
=
FAST_TEMP_MONITORING_RATE
;
else
data
->
ti_thermal
->
polling_delay
=
0
;
mutex_unlock
(
&
data
->
ti_thermal
->
lock
);
data
->
mode
=
mode
;
ti_bandgap_write_update_interval
(
bgp
,
data
->
sensor_id
,
data
->
ti_thermal
->
polling_delay
);
thermal_zone_device_update
(
data
->
ti_thermal
,
THERMAL_EVENT_UNSPECIFIED
);
dev_dbg
(
&
thermal
->
device
,
"thermal polling set for duration=%d msec
\n
"
,
data
->
ti_thermal
->
polling_delay
);
return
0
;
}
/* Get trip type callback functions for thermal zone */
static
int
ti_thermal_get_trip_type
(
struct
thermal_zone_device
*
thermal
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
if
(
!
ti_thermal_is_valid_trip
(
trip
))
return
-
EINVAL
;
if
(
trip
+
1
==
OMAP_TRIP_NUMBER
)
*
type
=
THERMAL_TRIP_CRITICAL
;
else
*
type
=
THERMAL_TRIP_PASSIVE
;
return
0
;
}
/* Get trip temperature callback functions for thermal zone */
static
int
ti_thermal_get_trip_temp
(
struct
thermal_zone_device
*
thermal
,
int
trip
,
int
*
temp
)
{
if
(
!
ti_thermal_is_valid_trip
(
trip
))
return
-
EINVAL
;
*
temp
=
ti_thermal_get_trip_value
(
trip
);
return
0
;
}
static
int
__ti_thermal_get_trend
(
void
*
p
,
int
trip
,
enum
thermal_trend
*
trend
)
{
struct
ti_thermal_data
*
data
=
p
;
...
...
@@ -262,38 +149,11 @@ static int __ti_thermal_get_trend(void *p, int trip, enum thermal_trend *trend)
return
0
;
}
/* Get the temperature trend callback functions for thermal zone */
static
int
ti_thermal_get_trend
(
struct
thermal_zone_device
*
thermal
,
int
trip
,
enum
thermal_trend
*
trend
)
{
return
__ti_thermal_get_trend
(
thermal
->
devdata
,
trip
,
trend
);
}
/* Get critical temperature callback functions for thermal zone */
static
int
ti_thermal_get_crit_temp
(
struct
thermal_zone_device
*
thermal
,
int
*
temp
)
{
/* shutdown zone */
return
ti_thermal_get_trip_temp
(
thermal
,
OMAP_TRIP_NUMBER
-
1
,
temp
);
}
static
const
struct
thermal_zone_of_device_ops
ti_of_thermal_ops
=
{
.
get_temp
=
__ti_thermal_get_temp
,
.
get_trend
=
__ti_thermal_get_trend
,
};
static
struct
thermal_zone_device_ops
ti_thermal_ops
=
{
.
get_temp
=
ti_thermal_get_temp
,
.
get_trend
=
ti_thermal_get_trend
,
.
bind
=
ti_thermal_bind
,
.
unbind
=
ti_thermal_unbind
,
.
get_mode
=
ti_thermal_get_mode
,
.
set_mode
=
ti_thermal_set_mode
,
.
get_trip_type
=
ti_thermal_get_trip_type
,
.
get_trip_temp
=
ti_thermal_get_trip_temp
,
.
get_crit_temp
=
ti_thermal_get_crit_temp
,
};
static
struct
ti_thermal_data
*
ti_thermal_build_data
(
struct
ti_bandgap
*
bgp
,
int
id
)
{
...
...
@@ -330,19 +190,11 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
/* in case this is specified by DT */
data
->
ti_thermal
=
devm_thermal_zone_of_sensor_register
(
bgp
->
dev
,
id
,
data
,
&
ti_of_thermal_ops
);
if
(
IS_ERR
(
data
->
ti_thermal
))
{
/* Create thermal zone */
data
->
ti_thermal
=
thermal_zone_device_register
(
domain
,
OMAP_TRIP_NUMBER
,
0
,
data
,
&
ti_thermal_ops
,
NULL
,
FAST_TEMP_MONITORING_RATE
,
FAST_TEMP_MONITORING_RATE
);
if
(
IS_ERR
(
data
->
ti_thermal
))
{
dev_err
(
bgp
->
dev
,
"thermal zone device is NULL
\n
"
);
return
PTR_ERR
(
data
->
ti_thermal
);
}
data
->
ti_thermal
->
polling_delay
=
FAST_TEMP_MONITORING_RATE
;
data
->
our_zone
=
true
;
}
ti_bandgap_set_sensor_data
(
bgp
,
id
,
data
);
ti_bandgap_write_update_interval
(
bgp
,
data
->
sensor_id
,
data
->
ti_thermal
->
polling_delay
);
...
...
drivers/thermal/ti-soc-thermal/ti-thermal.h
浏览文件 @
cb15c81a
...
...
@@ -25,22 +25,6 @@
#include "ti-bandgap.h"
/* sensors gradient and offsets */
#define OMAP_GRADIENT_SLOPE_4430 0
#define OMAP_GRADIENT_CONST_4430 20000
#define OMAP_GRADIENT_SLOPE_4460 348
#define OMAP_GRADIENT_CONST_4460 -9301
#define OMAP_GRADIENT_SLOPE_4470 308
#define OMAP_GRADIENT_CONST_4470 -7896
#define OMAP_GRADIENT_SLOPE_5430_CPU 65
#define OMAP_GRADIENT_CONST_5430_CPU -1791
#define OMAP_GRADIENT_SLOPE_5430_GPU 117
#define OMAP_GRADIENT_CONST_5430_GPU -2992
#define DRA752_GRADIENT_SLOPE 0
#define DRA752_GRADIENT_CONST 2000
/* PCB sensor calculation constants */
#define OMAP_GRADIENT_SLOPE_W_PCB_4430 0
#define OMAP_GRADIENT_CONST_W_PCB_4430 20000
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录