Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
6fefe19f
Commit
6fefe19f
authored
Feb 22, 2017
by
Zhang Rui
Browse files
Options
Browse Files
Download
Plain Diff
Merge branches 'thermal-core', 'thermal-soc', 'thermal-intel' and 'ida-conversion' into next
parents
d9cc34a6
ee73bcdb
da8c1c46
2f96c035
Changes
22
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
864 additions
and
254 deletions
+864
-254
Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
+7
-0
Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
...ntation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
+56
-0
Documentation/devicetree/bindings/thermal/zx2967-thermal.txt
Documentation/devicetree/bindings/thermal/zx2967-thermal.txt
+116
-0
arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
+2
-2
arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+2
-2
drivers/thermal/Kconfig
drivers/thermal/Kconfig
+17
-0
drivers/thermal/Makefile
drivers/thermal/Makefile
+2
-0
drivers/thermal/clock_cooling.c
drivers/thermal/clock_cooling.c
+8
-42
drivers/thermal/cpu_cooling.c
drivers/thermal/cpu_cooling.c
+11
-52
drivers/thermal/devfreq_cooling.c
drivers/thermal/devfreq_cooling.c
+9
-44
drivers/thermal/imx_thermal.c
drivers/thermal/imx_thermal.c
+4
-0
drivers/thermal/intel_powerclamp.c
drivers/thermal/intel_powerclamp.c
+0
-4
drivers/thermal/mtk_thermal.c
drivers/thermal/mtk_thermal.c
+8
-8
drivers/thermal/rcar_gen3_thermal.c
drivers/thermal/rcar_gen3_thermal.c
+335
-0
drivers/thermal/samsung/exynos_tmu.c
drivers/thermal/samsung/exynos_tmu.c
+0
-1
drivers/thermal/samsung/exynos_tmu.h
drivers/thermal/samsung/exynos_tmu.h
+0
-1
drivers/thermal/thermal_core.c
drivers/thermal/thermal_core.c
+26
-49
drivers/thermal/ti-soc-thermal/Kconfig
drivers/thermal/ti-soc-thermal/Kconfig
+0
-1
drivers/thermal/ti-soc-thermal/dra752-bandgap.h
drivers/thermal/ti-soc-thermal/dra752-bandgap.h
+0
-19
drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
+1
-27
drivers/thermal/zx2967_thermal.c
drivers/thermal/zx2967_thermal.c
+258
-0
include/linux/thermal.h
include/linux/thermal.h
+2
-2
No files found.
Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
View file @
6fefe19f
...
...
@@ -17,6 +17,12 @@ Required properties:
calibration data, as specified by the SoC reference manual.
The first cell of each pair is the value to be written to TTCFGR,
and the second is the value to be written to TSCFGR.
- #thermal-sensor-cells : Must be 1. The sensor specifier is the monitoring
site ID, and represents the "n" in TRITSRn and TRATSRn.
Optional property:
- little-endian : If present, the TMU registers are little endian. If absent,
the default is big endian.
Example:
...
...
@@ -60,4 +66,5 @@ tmu@f0000 {
0x00030000 0x00000012
0x00030001 0x0000001d>;
#thermal-sensor-cells = <1>;
};
Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
0 → 100644
View file @
6fefe19f
* DT bindings for Renesas R-Car Gen3 Thermal Sensor driver
On R-Car Gen3 SoCs, the thermal sensor controllers (TSC) control the thermal
sensors (THS) which are the analog circuits for measuring temperature (Tj)
inside the LSI.
Required properties:
- compatible : "renesas,<soctype>-thermal",
Examples with soctypes are:
- "renesas,r8a7795-thermal" (R-Car H3)
- "renesas,r8a7796-thermal" (R-Car M3-W)
- reg : Address ranges of the thermal registers. Each sensor
needs one address range. Sorting must be done in
increasing order according to datasheet, i.e.
TSC1, TSC2, ...
- clocks : Must contain a reference to the functional clock.
- #thermal-sensor-cells : must be <1>.
Optional properties:
- interrupts : interrupts routed to the TSC (3 for H3 and M3-W)
- 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.
Example:
tsc: thermal@e6198000 {
compatible = "renesas,r8a7795-thermal";
reg = <0 0xe6198000 0 0x68>,
<0 0xe61a0000 0 0x5c>,
<0 0xe61a8000 0 0x5c>;
interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 522>;
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
#thermal-sensor-cells = <1>;
status = "okay";
};
thermal-zones {
sensor_thermal1: sensor-thermal1 {
polling-delay-passive = <250>;
polling-delay = <1000>;
thermal-sensors = <&tsc 0>;
trips {
sensor1_crit: sensor1-crit {
temperature = <90000>;
hysteresis = <2000>;
type = "critical";
};
};
};
};
Documentation/devicetree/bindings/thermal/zx2967-thermal.txt
0 → 100644
View file @
6fefe19f
* ZTE zx2967 family Thermal
Required Properties:
- compatible: should be one of the following.
* zte,zx296718-thermal
- reg: physical base address of the controller and length of memory mapped
region.
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
- clock-names: "topcrm" for the topcrm clock.
"apb" for the apb clock.
- #thermal-sensor-cells: must be 0.
Please note: slope coefficient defined in thermal-zones section need to be
multiplied by 1000.
Example for tempsensor:
tempsensor: tempsensor@148a000 {
compatible = "zte,zx296718-thermal";
reg = <0x0148a000 0x20>;
clocks = <&topcrm TEMPSENSOR_GATE>, <&audiocrm AUDIO_TS_PCLK>;
clock-names = "topcrm", "apb";
#thermal-sensor-cells = <0>;
};
Example for cooling device:
cooling_dev: cooling_dev {
cluster0_cooling_dev: cluster0-cooling-dev {
#cooling-cells = <2>;
cpumask = <0xf>;
capacitance = <1500>;
};
cluster1_cooling_dev: cluster1-cooling-dev {
#cooling-cells = <2>;
cpumask = <0x30>;
capacitance = <2000>;
};
};
Example for thermal zones:
thermal-zones {
zx296718_thermal: zx296718_thermal {
polling-delay-passive = <500>;
polling-delay = <1000>;
sustainable-power = <6500>;
thermal-sensors = <&tempsensor 0>;
/*
* slope need to be multiplied by 1000.
*/
coefficients = <1951 (-922)>;
trips {
trip0: switch_on_temperature {
temperature = <90000>;
hysteresis = <2000>;
type = "passive";
};
trip1: desired_temperature {
temperature = <100000>;
hysteresis = <2000>;
type = "passive";
};
crit: critical_temperature {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
};
};
cooling-maps {
map0 {
trip = <&trip0>;
cooling-device = <&gpu 2 5>;
};
map1 {
trip = <&trip0>;
cooling-device = <&cluster0_cooling_dev 1 2>;
};
map2 {
trip = <&trip1>;
cooling-device = <&cluster0_cooling_dev 1 2>;
};
map3 {
trip = <&crit>;
cooling-device = <&cluster0_cooling_dev 1 2>;
};
map4 {
trip = <&trip0>;
cooling-device = <&cluster1_cooling_dev 1 2>;
contribution = <9000>;
};
map5 {
trip = <&trip1>;
cooling-device = <&cluster1_cooling_dev 1 2>;
contribution = <4096>;
};
map6 {
trip = <&crit>;
cooling-device = <&cluster1_cooling_dev 1 2>;
contribution = <4096>;
};
};
};
};
arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
View file @
6fefe19f
...
...
@@ -422,7 +422,7 @@ tmu: tmu@f0000 {
0x00030001 0x0000000d
0x00030002 0x00000019
0x00030003 0x00000024>;
#thermal-sensor-cells = <
0
>;
#thermal-sensor-cells = <
1
>;
};
thermal-zones {
...
...
@@ -430,7 +430,7 @@ cpu_thermal: cpu-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu>;
thermal-sensors = <&tmu
0
>;
trips {
cpu_alert: cpu-alert {
...
...
arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
View file @
6fefe19f
...
...
@@ -526,7 +526,7 @@ tmu: tmu@f0000 {
0x00030000 0x00000012
0x00030001 0x0000001d>;
#thermal-sensor-cells = <
0
>;
#thermal-sensor-cells = <
1
>;
};
thermal-zones {
...
...
@@ -534,7 +534,7 @@ cpu_thermal: cpu-thermal {
polling-delay-passive = <1000>;
polling-delay = <5000>;
thermal-sensors = <&tmu>;
thermal-sensors = <&tmu
2
>;
trips {
cpu_alert: cpu-alert {
...
...
drivers/thermal/Kconfig
View file @
6fefe19f
...
...
@@ -245,6 +245,15 @@ config RCAR_THERMAL
Enable this to plug the R-Car thermal sensor driver into the Linux
thermal framework.
config RCAR_GEN3_THERMAL
tristate "Renesas R-Car Gen3 thermal driver"
depends on ARCH_RENESAS || COMPILE_TEST
depends on HAS_IOMEM
depends on OF
help
Enable this to plug the R-Car Gen3 thermal sensor driver into the Linux
thermal framework.
config KIRKWOOD_THERMAL
tristate "Temperature sensor on Marvell Kirkwood SoCs"
depends on MACH_KIRKWOOD || COMPILE_TEST
...
...
@@ -436,4 +445,12 @@ depends on (ARCH_QCOM && OF) || COMPILE_TEST
source "drivers/thermal/qcom/Kconfig"
endmenu
config ZX2967_THERMAL
tristate "Thermal sensors on zx2967 SoC"
depends on ARCH_ZX || COMPILE_TEST
help
Enable the zx2967 thermal sensors driver, which supports
the primitive temperature sensor embedded in zx2967 SoCs.
This sensor generates the real time die temperature.
endif
drivers/thermal/Makefile
View file @
6fefe19f
...
...
@@ -31,6 +31,7 @@ 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
obj-$(CONFIG_RCAR_THERMAL)
+=
rcar_thermal.o
obj-$(CONFIG_RCAR_GEN3_THERMAL)
+=
rcar_gen3_thermal.o
obj-$(CONFIG_KIRKWOOD_THERMAL)
+=
kirkwood_thermal.o
obj-y
+=
samsung/
obj-$(CONFIG_DOVE_THERMAL)
+=
dove_thermal.o
...
...
@@ -56,3 +57,4 @@ obj-$(CONFIG_TEGRA_SOCTHERM) += tegra/
obj-$(CONFIG_HISI_THERMAL)
+=
hisi_thermal.o
obj-$(CONFIG_MTK_THERMAL)
+=
mtk_thermal.o
obj-$(CONFIG_GENERIC_ADC_THERMAL)
+=
thermal-generic-adc.o
obj-$(CONFIG_ZX2967_THERMAL)
+=
zx2967_thermal.o
drivers/thermal/clock_cooling.c
View file @
6fefe19f
...
...
@@ -65,42 +65,7 @@ struct clock_cooling_device {
};
#define to_clock_cooling_device(x) \
container_of(x, struct clock_cooling_device, clk_rate_change_nb)
static
DEFINE_IDR
(
clock_idr
);
static
DEFINE_MUTEX
(
cooling_clock_lock
);
/**
* clock_cooling_get_idr - function to get an unique id.
* @id: int * value generated by this function.
*
* This function will populate @id with an unique
* id, using the idr API.
*
* Return: 0 on success, an error code on failure.
*/
static
int
clock_cooling_get_idr
(
int
*
id
)
{
int
ret
;
mutex_lock
(
&
cooling_clock_lock
);
ret
=
idr_alloc
(
&
clock_idr
,
NULL
,
0
,
0
,
GFP_KERNEL
);
mutex_unlock
(
&
cooling_clock_lock
);
if
(
unlikely
(
ret
<
0
))
return
ret
;
*
id
=
ret
;
return
0
;
}
/**
* release_idr - function to free the unique id.
* @id: int value representing the unique id.
*/
static
void
release_idr
(
int
id
)
{
mutex_lock
(
&
cooling_clock_lock
);
idr_remove
(
&
clock_idr
,
id
);
mutex_unlock
(
&
cooling_clock_lock
);
}
static
DEFINE_IDA
(
clock_ida
);
/* Below code defines functions to be used for clock as cooling device */
...
...
@@ -432,16 +397,17 @@ clock_cooling_register(struct device *dev, const char *clock_name)
if
(
IS_ERR
(
ccdev
->
clk
))
return
ERR_CAST
(
ccdev
->
clk
);
ret
=
clock_cooling_get_idr
(
&
ccdev
->
id
);
if
(
ret
)
return
ERR_PTR
(
-
EINVAL
);
ret
=
ida_simple_get
(
&
clock_ida
,
0
,
0
,
GFP_KERNEL
);
if
(
ret
<
0
)
return
ERR_PTR
(
ret
);
ccdev
->
id
=
ret
;
snprintf
(
dev_name
,
sizeof
(
dev_name
),
"thermal-clock-%d"
,
ccdev
->
id
);
cdev
=
thermal_cooling_device_register
(
dev_name
,
ccdev
,
&
clock_cooling_ops
);
if
(
IS_ERR
(
cdev
))
{
release_idr
(
ccdev
->
id
);
ida_simple_remove
(
&
clock_ida
,
ccdev
->
id
);
return
ERR_PTR
(
-
EINVAL
);
}
ccdev
->
cdev
=
cdev
;
...
...
@@ -450,7 +416,7 @@ clock_cooling_register(struct device *dev, const char *clock_name)
/* Assuming someone has already filled the opp table for this device */
ret
=
dev_pm_opp_init_cpufreq_table
(
dev
,
&
ccdev
->
freq_table
);
if
(
ret
)
{
release_idr
(
ccdev
->
id
);
ida_simple_remove
(
&
clock_ida
,
ccdev
->
id
);
return
ERR_PTR
(
ret
);
}
ccdev
->
clock_state
=
0
;
...
...
@@ -481,6 +447,6 @@ void clock_cooling_unregister(struct thermal_cooling_device *cdev)
dev_pm_opp_free_cpufreq_table
(
ccdev
->
dev
,
&
ccdev
->
freq_table
);
thermal_cooling_device_unregister
(
ccdev
->
cdev
);
release_idr
(
ccdev
->
id
);
ida_simple_remove
(
&
clock_ida
,
ccdev
->
id
);
}
EXPORT_SYMBOL_GPL
(
clock_cooling_unregister
);
drivers/thermal/cpu_cooling.c
View file @
6fefe19f
...
...
@@ -26,6 +26,7 @@
#include <linux/thermal.h>
#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/idr.h>
#include <linux/pm_opp.h>
#include <linux/slab.h>
#include <linux/cpu.h>
...
...
@@ -104,50 +105,13 @@ struct cpufreq_cooling_device {
struct
device
*
cpu_dev
;
get_static_t
plat_get_static_power
;
};
static
DEFINE_IDR
(
cpufreq_idr
);
static
DEFINE_MUTEX
(
cooling_cpufreq_lock
);
static
DEFINE_IDA
(
cpufreq_ida
);
static
unsigned
int
cpufreq_dev_count
;
static
DEFINE_MUTEX
(
cooling_list_lock
);
static
LIST_HEAD
(
cpufreq_dev_list
);
/**
* get_idr - function to get a unique id.
* @idr: struct idr * handle used to create a id.
* @id: int * value generated by this function.
*
* This function will populate @id with an unique
* id, using the idr API.
*
* Return: 0 on success, an error code on failure.
*/
static
int
get_idr
(
struct
idr
*
idr
,
int
*
id
)
{
int
ret
;
mutex_lock
(
&
cooling_cpufreq_lock
);
ret
=
idr_alloc
(
idr
,
NULL
,
0
,
0
,
GFP_KERNEL
);
mutex_unlock
(
&
cooling_cpufreq_lock
);
if
(
unlikely
(
ret
<
0
))
return
ret
;
*
id
=
ret
;
return
0
;
}
/**
* release_idr - function to free the unique id.
* @idr: struct idr * handle used for creating the id.
* @id: int value representing the unique id.
*/
static
void
release_idr
(
struct
idr
*
idr
,
int
id
)
{
mutex_lock
(
&
cooling_cpufreq_lock
);
idr_remove
(
idr
,
id
);
mutex_unlock
(
&
cooling_cpufreq_lock
);
}
/* Below code defines functions to be used for cpufreq as cooling device */
/**
...
...
@@ -886,11 +850,12 @@ __cpufreq_cooling_register(struct device_node *np,
cooling_ops
=
&
cpufreq_cooling_ops
;
}
ret
=
get_idr
(
&
cpufreq_idr
,
&
cpufreq_dev
->
id
);
if
(
ret
)
{
ret
=
ida_simple_get
(
&
cpufreq_ida
,
0
,
0
,
GFP_KERNEL
);
if
(
ret
<
0
)
{
cool_dev
=
ERR_PTR
(
ret
);
goto
free_power_table
;
}
cpufreq_dev
->
id
=
ret
;
/* Fill freq-table in descending order of frequencies */
for
(
i
=
0
,
freq
=
-
1
;
i
<=
cpufreq_dev
->
max_level
;
i
++
)
{
...
...
@@ -910,27 +875,24 @@ __cpufreq_cooling_register(struct device_node *np,
cool_dev
=
thermal_of_cooling_device_register
(
np
,
dev_name
,
cpufreq_dev
,
cooling_ops
);
if
(
IS_ERR
(
cool_dev
))
goto
remove_id
r
;
goto
remove_id
a
;
cpufreq_dev
->
clipped_freq
=
cpufreq_dev
->
freq_table
[
0
];
cpufreq_dev
->
cool_dev
=
cool_dev
;
mutex_lock
(
&
cooling_cpufreq_lock
);
mutex_lock
(
&
cooling_list_lock
);
list_add
(
&
cpufreq_dev
->
node
,
&
cpufreq_dev_list
);
mutex_unlock
(
&
cooling_list_lock
);
/* Register the notifier for first cpufreq cooling device */
if
(
!
cpufreq_dev_count
++
)
cpufreq_register_notifier
(
&
thermal_cpufreq_notifier_block
,
CPUFREQ_POLICY_NOTIFIER
);
mutex_unlock
(
&
cooling_
cpufreq
_lock
);
mutex_unlock
(
&
cooling_
list
_lock
);
goto
put_policy
;
remove_id
r
:
release_idr
(
&
cpufreq_idr
,
cpufreq_dev
->
id
);
remove_id
a
:
ida_simple_remove
(
&
cpufreq_ida
,
cpufreq_dev
->
id
);
free_power_table:
kfree
(
cpufreq_dev
->
dyn_power_table
);
free_table:
...
...
@@ -1072,20 +1034,17 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
cpufreq_dev
=
cdev
->
devdata
;
mutex_lock
(
&
cooling_list_lock
);
/* Unregister the notifier for the last cpufreq cooling device */
mutex_lock
(
&
cooling_cpufreq_lock
);
if
(
!--
cpufreq_dev_count
)
cpufreq_unregister_notifier
(
&
thermal_cpufreq_notifier_block
,
CPUFREQ_POLICY_NOTIFIER
);
mutex_lock
(
&
cooling_list_lock
);
list_del
(
&
cpufreq_dev
->
node
);
mutex_unlock
(
&
cooling_list_lock
);
mutex_unlock
(
&
cooling_cpufreq_lock
);
thermal_cooling_device_unregister
(
cpufreq_dev
->
cool_dev
);
release_idr
(
&
cpufreq_idr
,
cpufreq_dev
->
id
);
ida_simple_remove
(
&
cpufreq_ida
,
cpufreq_dev
->
id
);
kfree
(
cpufreq_dev
->
dyn_power_table
);
kfree
(
cpufreq_dev
->
time_in_idle_timestamp
);
kfree
(
cpufreq_dev
->
time_in_idle
);
...
...
drivers/thermal/devfreq_cooling.c
View file @
6fefe19f
...
...
@@ -21,14 +21,14 @@
#include <linux/devfreq.h>
#include <linux/devfreq_cooling.h>
#include <linux/export.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/pm_opp.h>
#include <linux/thermal.h>
#include <trace/events/thermal.h>
static
DEFINE_MUTEX
(
devfreq_lock
);
static
DEFINE_IDR
(
devfreq_idr
);
static
DEFINE_IDA
(
devfreq_ida
);
/**
* struct devfreq_cooling_device - Devfreq cooling device
...
...
@@ -57,42 +57,6 @@ struct devfreq_cooling_device {
struct
devfreq_cooling_power
*
power_ops
;
};
/**
* get_idr - function to get a unique id.
* @idr: struct idr * handle used to create a id.
* @id: int * value generated by this function.
*
* This function will populate @id with an unique
* id, using the idr API.
*
* Return: 0 on success, an error code on failure.
*/
static
int
get_idr
(
struct
idr
*
idr
,
int
*
id
)
{
int
ret
;
mutex_lock
(
&
devfreq_lock
);
ret
=
idr_alloc
(
idr
,
NULL
,
0
,
0
,
GFP_KERNEL
);
mutex_unlock
(
&
devfreq_lock
);
if
(
unlikely
(
ret
<
0
))
return
ret
;
*
id
=
ret
;
return
0
;
}
/**
* release_idr - function to free the unique id.
* @idr: struct idr * handle used for creating the id.
* @id: int value representing the unique id.
*/
static
void
release_idr
(
struct
idr
*
idr
,
int
id
)
{
mutex_lock
(
&
devfreq_lock
);
idr_remove
(
idr
,
id
);
mutex_unlock
(
&
devfreq_lock
);
}
/**
* partition_enable_opps() - disable all opps above a given state
* @dfc: Pointer to devfreq we are operating on
...
...
@@ -496,9 +460,10 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
if
(
err
)
goto
free_dfc
;
err
=
get_idr
(
&
devfreq_idr
,
&
dfc
->
id
);
if
(
err
)
err
=
ida_simple_get
(
&
devfreq_ida
,
0
,
0
,
GFP_KERNEL
);
if
(
err
<
0
)
goto
free_tables
;
dfc
->
id
=
err
;
snprintf
(
dev_name
,
sizeof
(
dev_name
),
"thermal-devfreq-%d"
,
dfc
->
id
);
...
...
@@ -509,15 +474,15 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
dev_err
(
df
->
dev
.
parent
,
"Failed to register devfreq cooling device (%d)
\n
"
,
err
);
goto
release_id
r
;
goto
release_id
a
;
}
dfc
->
cdev
=
cdev
;
return
cdev
;
release_id
r
:
release_idr
(
&
devfreq_idr
,
dfc
->
id
);
release_id
a
:
ida_simple_remove
(
&
devfreq_ida
,
dfc
->
id
);
free_tables:
kfree
(
dfc
->
power_table
);
kfree
(
dfc
->
freq_table
);
...
...
@@ -565,7 +530,7 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
dfc
=
cdev
->
devdata
;
thermal_cooling_device_unregister
(
dfc
->
cdev
);
release_idr
(
&
devfreq_idr
,
dfc
->
id
);
ida_simple_remove
(
&
devfreq_ida
,
dfc
->
id
);
kfree
(
dfc
->
power_table
);
kfree
(
dfc
->
freq_table
);
...
...
drivers/thermal/imx_thermal.c
View file @
6fefe19f
...
...
@@ -489,6 +489,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
data
->
tempmon
=
map
;
data
->
socdata
=
of_device_get_match_data
(
&
pdev
->
dev
);
if
(
!
data
->
socdata
)
{
dev_err
(
&
pdev
->
dev
,
"no device match found
\n
"
);
return
-
ENODEV
;
}
/* make sure the IRQ flag is clear before enabling irq on i.MX6SX */
if
(
data
->
socdata
->
version
==
TEMPMON_IMX6SX
)
{
...
...
drivers/thermal/intel_powerclamp.c
View file @
6fefe19f
...
...
@@ -461,16 +461,13 @@ static void poll_pkg_cstate(struct work_struct *dummy)
{
static
u64
msr_last
;
static
u64
tsc_last
;
static
unsigned
long
jiffies_last
;
u64
msr_now
;
unsigned
long
jiffies_now
;
u64
tsc_now
;
u64
val64
;
msr_now
=
pkg_state_counter
();
tsc_now
=
rdtsc
();
jiffies_now
=
jiffies
;
/* calculate pkg cstate vs tsc ratio */
if
(
!
msr_last
||
!
tsc_last
)
...
...
@@ -485,7 +482,6 @@ static void poll_pkg_cstate(struct work_struct *dummy)
/* update record */
msr_last
=
msr_now
;
jiffies_last
=
jiffies_now
;
tsc_last
=
tsc_now
;
if
(
true
==
clamping
)
...
...
drivers/thermal/mtk_thermal.c
View file @
6fefe19f
...
...
@@ -183,37 +183,37 @@ struct mtk_thermal {
};
/* MT8173 thermal sensor data */
const
int
mt8173_bank_data
[
MT8173_NUM_ZONES
][
3
]
=
{
static
const
int
mt8173_bank_data
[
MT8173_NUM_ZONES
][
3
]
=
{
{
MT8173_TS2
,
MT8173_TS3
},
{
MT8173_TS2
,
MT8173_TS4
},
{
MT8173_TS1
,
MT8173_TS2
,
MT8173_TSABB
},
{
MT8173_TS2
},
};
const
int
mt8173_msr
[
MT8173_NUM_SENSORS_PER_ZONE
]
=
{
static
const
int
mt8173_msr
[
MT8173_NUM_SENSORS_PER_ZONE
]
=
{
TEMP_MSR0
,
TEMP_MSR1
,
TEMP_MSR2
,
TEMP_MSR2
};
const
int
mt8173_adcpnp
[
MT8173_NUM_SENSORS_PER_ZONE
]
=
{
static
const
int
mt8173_adcpnp
[
MT8173_NUM_SENSORS_PER_ZONE
]
=
{
TEMP_ADCPNP0
,
TEMP_ADCPNP1
,
TEMP_ADCPNP2
,
TEMP_ADCPNP3
};
const
int
mt8173_mux_values
[
MT8173_NUM_SENSORS
]
=
{
0
,
1
,
2
,
3
,
16
};
static
const
int
mt8173_mux_values
[
MT8173_NUM_SENSORS
]
=
{
0
,
1
,
2
,
3
,
16
};
/* MT2701 thermal sensor data */
const
int
mt2701_bank_data
[
MT2701_NUM_SENSORS
]
=
{
static
const
int
mt2701_bank_data
[
MT2701_NUM_SENSORS
]
=
{
MT2701_TS1
,
MT2701_TS2
,
MT2701_TSABB
};
const
int
mt2701_msr
[
MT2701_NUM_SENSORS_PER_ZONE
]
=
{
static
const
int
mt2701_msr
[
MT2701_NUM_SENSORS_PER_ZONE
]
=
{
TEMP_MSR0
,
TEMP_MSR1
,
TEMP_MSR2
};
const
int
mt2701_adcpnp
[
MT2701_NUM_SENSORS_PER_ZONE
]
=
{
static
const
int
mt2701_adcpnp
[
MT2701_NUM_SENSORS_PER_ZONE
]
=
{
TEMP_ADCPNP0
,
TEMP_ADCPNP1
,
TEMP_ADCPNP2
};
const
int
mt2701_mux_values
[
MT2701_NUM_SENSORS
]
=
{
0
,
1
,
16
};
static
const
int
mt2701_mux_values
[
MT2701_NUM_SENSORS
]
=
{
0
,
1
,
16
};
/**
* The MT8173 thermal controller has four banks. Each bank can read up to
...
...
drivers/thermal/rcar_gen3_thermal.c
0 → 100644
View file @
6fefe19f
/*
* R-Car Gen3 THS thermal sensor driver
* Based on rcar_thermal.c and work from Hien Dang and Khiem Nguyen.
*
* Copyright (C) 2016 Renesas Electronics Corporation.
* Copyright (C) 2016 Sang Engineering
*
* 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; version 2 of the License.
*
* 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/delay.h>
#include <linux/err.h>
#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/thermal.h>
/* Register offsets */
#define REG_GEN3_IRQSTR 0x04
#define REG_GEN3_IRQMSK 0x08
#define REG_GEN3_IRQCTL 0x0C
#define REG_GEN3_IRQEN 0x10
#define REG_GEN3_IRQTEMP1 0x14
#define REG_GEN3_IRQTEMP2 0x18
#define REG_GEN3_IRQTEMP3 0x1C
#define REG_GEN3_CTSR 0x20
#define REG_GEN3_THCTR 0x20
#define REG_GEN3_TEMP 0x28
#define REG_GEN3_THCODE1 0x50
#define REG_GEN3_THCODE2 0x54
#define REG_GEN3_THCODE3 0x58
/* CTSR bits */
#define CTSR_PONM BIT(8)
#define CTSR_AOUT BIT(7)
#define CTSR_THBGR BIT(5)
#define CTSR_VMEN BIT(4)
#define CTSR_VMST BIT(1)
#define CTSR_THSST BIT(0)
/* THCTR bits */
#define THCTR_PONM BIT(6)
#define THCTR_THSST BIT(0)
#define CTEMP_MASK 0xFFF
#define MCELSIUS(temp) ((temp) * 1000)
#define GEN3_FUSE_MASK 0xFFF
#define TSC_MAX_NUM 3
/* Structure for thermal temperature calculation */
struct
equation_coefs
{
int
a1
;
int
b1
;
int
a2
;
int
b2
;
};
struct
rcar_gen3_thermal_tsc
{
void
__iomem
*
base
;
struct
thermal_zone_device
*
zone
;
struct
equation_coefs
coef
;
struct
mutex
lock
;
};
struct
rcar_gen3_thermal_priv
{
struct
rcar_gen3_thermal_tsc
*
tscs
[
TSC_MAX_NUM
];
};
struct
rcar_gen3_thermal_data
{
void
(
*
thermal_init
)(
struct
rcar_gen3_thermal_tsc
*
tsc
);
};
static
inline
u32
rcar_gen3_thermal_read
(
struct
rcar_gen3_thermal_tsc
*
tsc
,
u32
reg
)
{
return
ioread32
(
tsc
->
base
+
reg
);
}
static
inline
void
rcar_gen3_thermal_write
(
struct
rcar_gen3_thermal_tsc
*
tsc
,
u32
reg
,
u32
data
)
{
iowrite32
(
data
,
tsc
->
base
+
reg
);
}
/*
* Linear approximation for temperature
*
* [reg] = [temp] * a + b => [temp] = ([reg] - b) / a
*
* The constants a and b are calculated using two triplets of int values PTAT
* and THCODE. PTAT and THCODE can either be read from hardware or use hard
* coded values from driver. The formula to calculate a and b are taken from
* BSP and sparsely documented and understood.
*
* Examining the linear formula and the formula used to calculate constants a
* and b while knowing that the span for PTAT and THCODE values are between
* 0x000 and 0xfff the largest integer possible is 0xfff * 0xfff == 0xffe001.
* Integer also needs to be signed so that leaves 7 bits for binary
* fixed point scaling.
*/
#define FIXPT_SHIFT 7
#define FIXPT_INT(_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)
#define RCAR3_THERMAL_GRAN 500
/* mili Celsius */
/* no idea where these constants come from */
#define TJ_1 96
#define TJ_3 -41
static
void
rcar_gen3_thermal_calc_coefs
(
struct
equation_coefs
*
coef
,
int
*
ptat
,
int
*
thcode
)
{
int
tj_2
;
/* TODO: Find documentation and document constant calculation formula */
/*
* Division is not scaled in BSP and if scaled it might overflow
* the dividend (4095 * 4095 << 14 > INT_MAX) so keep it unscaled
*/
tj_2
=
(
FIXPT_INT
((
ptat
[
1
]
-
ptat
[
2
])
*
137
)
/
(
ptat
[
0
]
-
ptat
[
2
]))
-
FIXPT_INT
(
41
);
coef
->
a1
=
FIXPT_DIV
(
FIXPT_INT
(
thcode
[
1
]
-
thcode
[
2
]),
tj_2
-
FIXPT_INT
(
TJ_3
));
coef
->
b1
=
FIXPT_INT
(
thcode
[
2
])
-
coef
->
a1
*
TJ_3
;
coef
->
a2
=
FIXPT_DIV
(
FIXPT_INT
(
thcode
[
1
]
-
thcode
[
0
]),
tj_2
-
FIXPT_INT
(
TJ_1
));
coef
->
b2
=
FIXPT_INT
(
thcode
[
0
])
-
coef
->
a2
*
TJ_1
;
}
static
int
rcar_gen3_thermal_round
(
int
temp
)
{
int
result
,
round_offs
;
round_offs
=
temp
>=
0
?
RCAR3_THERMAL_GRAN
/
2
:
-
RCAR3_THERMAL_GRAN
/
2
;
result
=
(
temp
+
round_offs
)
/
RCAR3_THERMAL_GRAN
;
return
result
*
RCAR3_THERMAL_GRAN
;
}
static
int
rcar_gen3_thermal_get_temp
(
void
*
devdata
,
int
*
temp
)
{
struct
rcar_gen3_thermal_tsc
*
tsc
=
devdata
;
int
mcelsius
,
val1
,
val2
;
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
;
/* Round value to device granularity setting */
*
temp
=
rcar_gen3_thermal_round
(
mcelsius
);
return
0
;
}
static
struct
thermal_zone_of_device_ops
rcar_gen3_tz_of_ops
=
{
.
get_temp
=
rcar_gen3_thermal_get_temp
,
};
static
void
r8a7795_thermal_init
(
struct
rcar_gen3_thermal_tsc
*
tsc
)
{
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_CTSR
,
CTSR_THBGR
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_CTSR
,
0x0
);
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_CTSR
,
CTSR_PONM
|
CTSR_AOUT
|
CTSR_THBGR
|
CTSR_VMEN
);
usleep_range
(
100
,
200
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_CTSR
,
CTSR_PONM
|
CTSR_AOUT
|
CTSR_THBGR
|
CTSR_VMEN
|
CTSR_VMST
|
CTSR_THSST
);
usleep_range
(
1000
,
2000
);
}
static
void
r8a7796_thermal_init
(
struct
rcar_gen3_thermal_tsc
*
tsc
)
{
u32
reg_val
;
reg_val
=
rcar_gen3_thermal_read
(
tsc
,
REG_GEN3_THCTR
);
reg_val
&=
~
THCTR_PONM
;
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_THCTR
,
reg_val
);
usleep_range
(
1000
,
2000
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_IRQCTL
,
0x3F
);
reg_val
=
rcar_gen3_thermal_read
(
tsc
,
REG_GEN3_THCTR
);
reg_val
|=
THCTR_THSST
;
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_THCTR
,
reg_val
);
}
static
const
struct
rcar_gen3_thermal_data
r8a7795_data
=
{
.
thermal_init
=
r8a7795_thermal_init
,
};
static
const
struct
rcar_gen3_thermal_data
r8a7796_data
=
{
.
thermal_init
=
r8a7796_thermal_init
,
};
static
const
struct
of_device_id
rcar_gen3_thermal_dt_ids
[]
=
{
{
.
compatible
=
"renesas,r8a7795-thermal"
,
.
data
=
&
r8a7795_data
},
{
.
compatible
=
"renesas,r8a7796-thermal"
,
.
data
=
&
r8a7796_data
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
rcar_gen3_thermal_dt_ids
);
static
int
rcar_gen3_thermal_remove
(
struct
platform_device
*
pdev
)
{
struct
device
*
dev
=
&
pdev
->
dev
;
pm_runtime_put
(
dev
);
pm_runtime_disable
(
dev
);
return
0
;
}
static
int
rcar_gen3_thermal_probe
(
struct
platform_device
*
pdev
)
{
struct
rcar_gen3_thermal_priv
*
priv
;
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
);
/* default values if FUSEs are missing */
/* TODO: Read values from hardware on supported platforms */
int
ptat
[
3
]
=
{
2351
,
1509
,
435
};
int
thcode
[
TSC_MAX_NUM
][
3
]
=
{
{
3248
,
2800
,
2221
},
{
3245
,
2795
,
2216
},
{
3250
,
2805
,
2237
},
};
priv
=
devm_kzalloc
(
dev
,
sizeof
(
*
priv
),
GFP_KERNEL
);
if
(
!
priv
)
return
-
ENOMEM
;
platform_set_drvdata
(
pdev
,
priv
);
pm_runtime_enable
(
dev
);
pm_runtime_get_sync
(
dev
);
for
(
i
=
0
;
i
<
TSC_MAX_NUM
;
i
++
)
{
struct
rcar_gen3_thermal_tsc
*
tsc
;
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
);
goto
error_unregister
;
}
priv
->
tscs
[
i
]
=
tsc
;
mutex_init
(
&
tsc
->
lock
);
match_data
->
thermal_init
(
tsc
);
rcar_gen3_thermal_calc_coefs
(
&
tsc
->
coef
,
ptat
,
thcode
[
i
]);
zone
=
devm_thermal_zone_of_sensor_register
(
dev
,
i
,
tsc
,
&
rcar_gen3_tz_of_ops
);
if
(
IS_ERR
(
zone
))
{
dev_err
(
dev
,
"Can't register thermal zone
\n
"
);
ret
=
PTR_ERR
(
zone
);
goto
error_unregister
;
}
tsc
->
zone
=
zone
;
}
return
0
;
error_unregister:
rcar_gen3_thermal_remove
(
pdev
);
return
ret
;
}
static
struct
platform_driver
rcar_gen3_thermal_driver
=
{
.
driver
=
{
.
name
=
"rcar_gen3_thermal"
,
.
of_match_table
=
rcar_gen3_thermal_dt_ids
,
},
.
probe
=
rcar_gen3_thermal_probe
,
.
remove
=
rcar_gen3_thermal_remove
,
};
module_platform_driver
(
rcar_gen3_thermal_driver
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_DESCRIPTION
(
"R-Car Gen3 THS thermal sensor driver"
);
MODULE_AUTHOR
(
"Wolfram Sang <wsa+renesas@sang-engineering.com>"
);
drivers/thermal/samsung/exynos_tmu.c
View file @
6fefe19f
...
...
@@ -1168,7 +1168,6 @@ static int exynos_of_sensor_conf(struct device_node *np,
pdata
->
default_temp_offset
=
(
u8
)
value
;
of_property_read_u32
(
np
,
"samsung,tmu_cal_type"
,
&
pdata
->
cal_type
);
of_property_read_u32
(
np
,
"samsung,tmu_cal_mode"
,
&
pdata
->
cal_mode
);
of_node_put
(
np
);
return
0
;
...
...
drivers/thermal/samsung/exynos_tmu.h
View file @
6fefe19f
...
...
@@ -70,7 +70,6 @@ struct exynos_tmu_platform_data {
enum
soc_type
type
;
u32
cal_type
;
u32
cal_mode
;
};
#endif
/* _EXYNOS_TMU_H */
drivers/thermal/thermal_core.c
View file @
6fefe19f
...
...
@@ -36,9 +36,8 @@ MODULE_AUTHOR("Zhang Rui");
MODULE_DESCRIPTION
(
"Generic thermal management sysfs support"
);
MODULE_LICENSE
(
"GPL v2"
);
static
DEFINE_IDR
(
thermal_tz_idr
);
static
DEFINE_IDR
(
thermal_cdev_idr
);
static
DEFINE_MUTEX
(
thermal_idr_lock
);
static
DEFINE_IDA
(
thermal_tz_ida
);
static
DEFINE_IDA
(
thermal_cdev_ida
);
static
LIST_HEAD
(
thermal_tz_list
);
static
LIST_HEAD
(
thermal_cdev_list
);
...
...
@@ -589,29 +588,6 @@ void thermal_zone_device_unbind_exception(struct thermal_zone_device *tz,
* - thermal zone devices lifecycle: registration, unregistration,
* binding, and unbinding.
*/
static
int
get_idr
(
struct
idr
*
idr
,
struct
mutex
*
lock
,
int
*
id
)
{
int
ret
;
if
(
lock
)
mutex_lock
(
lock
);
ret
=
idr_alloc
(
idr
,
NULL
,
0
,
0
,
GFP_KERNEL
);
if
(
lock
)
mutex_unlock
(
lock
);
if
(
unlikely
(
ret
<
0
))
return
ret
;
*
id
=
ret
;
return
0
;
}
static
void
release_idr
(
struct
idr
*
idr
,
struct
mutex
*
lock
,
int
id
)
{
if
(
lock
)
mutex_lock
(
lock
);
idr_remove
(
idr
,
id
);
if
(
lock
)
mutex_unlock
(
lock
);
}
/**
* thermal_zone_bind_cooling_device() - bind a cooling device to a thermal zone
...
...
@@ -685,15 +661,16 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
dev
->
target
=
THERMAL_NO_TARGET
;
dev
->
weight
=
weight
;
result
=
get_idr
(
&
tz
->
idr
,
&
tz
->
lock
,
&
dev
->
id
);
if
(
result
)
result
=
ida_simple_get
(
&
tz
->
ida
,
0
,
0
,
GFP_KERNEL
);
if
(
result
<
0
)
goto
free_mem
;
dev
->
id
=
result
;
sprintf
(
dev
->
name
,
"cdev%d"
,
dev
->
id
);
result
=
sysfs_create_link
(
&
tz
->
device
.
kobj
,
&
cdev
->
device
.
kobj
,
dev
->
name
);
if
(
result
)
goto
release_id
r
;
goto
release_id
a
;
sprintf
(
dev
->
attr_name
,
"cdev%d_trip_point"
,
dev
->
id
);
sysfs_attr_init
(
&
dev
->
attr
.
attr
);
...
...
@@ -737,8 +714,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
device_remove_file
(
&
tz
->
device
,
&
dev
->
attr
);
remove_symbol_link:
sysfs_remove_link
(
&
tz
->
device
.
kobj
,
dev
->
name
);
release_id
r
:
release_idr
(
&
tz
->
idr
,
&
tz
->
lock
,
dev
->
id
);
release_id
a
:
ida_simple_remove
(
&
tz
->
ida
,
dev
->
id
);
free_mem:
kfree
(
dev
);
return
result
;
...
...
@@ -785,7 +762,7 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
device_remove_file
(
&
tz
->
device
,
&
pos
->
weight_attr
);
device_remove_file
(
&
tz
->
device
,
&
pos
->
attr
);
sysfs_remove_link
(
&
tz
->
device
.
kobj
,
pos
->
name
);
release_idr
(
&
tz
->
idr
,
&
tz
->
lock
,
pos
->
id
);
ida_simple_remove
(
&
tz
->
ida
,
pos
->
id
);
kfree
(
pos
);
return
0
;
}
...
...
@@ -925,12 +902,13 @@ __thermal_cooling_device_register(struct device_node *np,
if
(
!
cdev
)
return
ERR_PTR
(
-
ENOMEM
);
result
=
get_idr
(
&
thermal_cdev_idr
,
&
thermal_idr_lock
,
&
cdev
->
id
);
if
(
result
)
{
result
=
ida_simple_get
(
&
thermal_cdev_ida
,
0
,
0
,
GFP_KERNEL
);
if
(
result
<
0
)
{
kfree
(
cdev
);
return
ERR_PTR
(
result
);
}
cdev
->
id
=
result
;
strlcpy
(
cdev
->
type
,
type
?
:
""
,
sizeof
(
cdev
->
type
));
mutex_init
(
&
cdev
->
lock
);
INIT_LIST_HEAD
(
&
cdev
->
thermal_instances
);
...
...
@@ -943,7 +921,7 @@ __thermal_cooling_device_register(struct device_node *np,
dev_set_name
(
&
cdev
->
device
,
"cooling_device%d"
,
cdev
->
id
);
result
=
device_register
(
&
cdev
->
device
);
if
(
result
)
{
release_idr
(
&
thermal_cdev_idr
,
&
thermal_idr_lock
,
cdev
->
id
);
ida_simple_remove
(
&
thermal_cdev_ida
,
cdev
->
id
);
kfree
(
cdev
);
return
ERR_PTR
(
result
);
}
...
...
@@ -1070,7 +1048,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
mutex_unlock
(
&
thermal_list_lock
);
release_idr
(
&
thermal_cdev_idr
,
&
thermal_idr_lock
,
cdev
->
id
);
ida_simple_remove
(
&
thermal_cdev_ida
,
cdev
->
id
);
device_unregister
(
&
cdev
->
device
);
}
EXPORT_SYMBOL_GPL
(
thermal_cooling_device_unregister
);
...
...
@@ -1172,14 +1150,15 @@ thermal_zone_device_register(const char *type, int trips, int mask,
return
ERR_PTR
(
-
ENOMEM
);
INIT_LIST_HEAD
(
&
tz
->
thermal_instances
);
id
r_init
(
&
tz
->
idr
);
id
a_init
(
&
tz
->
ida
);
mutex_init
(
&
tz
->
lock
);
result
=
get_idr
(
&
thermal_tz_idr
,
&
thermal_idr_lock
,
&
tz
->
id
);
if
(
result
)
{
result
=
ida_simple_get
(
&
thermal_tz_ida
,
0
,
0
,
GFP_KERNEL
);
if
(
result
<
0
)
{
kfree
(
tz
);
return
ERR_PTR
(
result
);
}
tz
->
id
=
result
;
strlcpy
(
tz
->
type
,
type
,
sizeof
(
tz
->
type
));
tz
->
ops
=
ops
;
tz
->
tzp
=
tzp
;
...
...
@@ -1201,7 +1180,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
dev_set_name
(
&
tz
->
device
,
"thermal_zone%d"
,
tz
->
id
);
result
=
device_register
(
&
tz
->
device
);
if
(
result
)
{
release_idr
(
&
thermal_tz_idr
,
&
thermal_idr_lock
,
tz
->
id
);
ida_simple_remove
(
&
thermal_tz_ida
,
tz
->
id
);
kfree
(
tz
);
return
ERR_PTR
(
result
);
}
...
...
@@ -1255,7 +1234,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
return
tz
;
unregister:
release_idr
(
&
thermal_tz_idr
,
&
thermal_idr_lock
,
tz
->
id
);
ida_simple_remove
(
&
thermal_tz_ida
,
tz
->
id
);
device_unregister
(
&
tz
->
device
);
return
ERR_PTR
(
result
);
}
...
...
@@ -1313,8 +1292,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
thermal_set_governor
(
tz
,
NULL
);
thermal_remove_hwmon_sysfs
(
tz
);
release_idr
(
&
thermal_tz_idr
,
&
thermal_idr_lock
,
tz
->
id
);
id
r_destroy
(
&
tz
->
idr
);
ida_simple_remove
(
&
thermal_tz_ida
,
tz
->
id
);
id
a_destroy
(
&
tz
->
ida
);
mutex_destroy
(
&
tz
->
lock
);
device_unregister
(
&
tz
->
device
);
}
...
...
@@ -1514,9 +1493,8 @@ static int __init thermal_init(void)
unregister_governors:
thermal_unregister_governors
();
error:
idr_destroy
(
&
thermal_tz_idr
);
idr_destroy
(
&
thermal_cdev_idr
);
mutex_destroy
(
&
thermal_idr_lock
);
ida_destroy
(
&
thermal_tz_ida
);
ida_destroy
(
&
thermal_cdev_ida
);
mutex_destroy
(
&
thermal_list_lock
);
mutex_destroy
(
&
thermal_governor_lock
);
return
result
;
...
...
@@ -1529,9 +1507,8 @@ static void __exit thermal_exit(void)
genetlink_exit
();
class_unregister
(
&
thermal_class
);
thermal_unregister_governors
();
idr_destroy
(
&
thermal_tz_idr
);
idr_destroy
(
&
thermal_cdev_idr
);
mutex_destroy
(
&
thermal_idr_lock
);
ida_destroy
(
&
thermal_tz_ida
);
ida_destroy
(
&
thermal_cdev_ida
);
mutex_destroy
(
&
thermal_list_lock
);
mutex_destroy
(
&
thermal_governor_lock
);
}
...
...
drivers/thermal/ti-soc-thermal/Kconfig
View file @
6fefe19f
...
...
@@ -11,7 +11,6 @@ config TI_SOC_THERMAL
config TI_THERMAL
bool "Texas Instruments SoCs thermal framework support"
depends on TI_SOC_THERMAL
depends on CPU_THERMAL
help
If you say yes here you want to get support for generic thermal
framework for the Texas Instruments on die bandgap temperature sensor.
...
...
drivers/thermal/ti-soc-thermal/dra752-bandgap.h
View file @
6fefe19f
...
...
@@ -54,7 +54,6 @@
#define DRA752_STD_FUSE_OPP_BGAP_CORE_OFFSET 0x8
#define DRA752_TEMP_SENSOR_CORE_OFFSET 0x154
#define DRA752_BANDGAP_THRESHOLD_CORE_OFFSET 0x1ac
#define DRA752_BANDGAP_TSHUT_CORE_OFFSET 0x1b8
#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_OFFSET 0x1c4
#define DRA752_DTEMP_CORE_0_OFFSET 0x208
#define DRA752_DTEMP_CORE_1_OFFSET 0x20c
...
...
@@ -66,7 +65,6 @@
#define DRA752_STD_FUSE_OPP_BGAP_IVA_OFFSET 0x388
#define DRA752_TEMP_SENSOR_IVA_OFFSET 0x398
#define DRA752_BANDGAP_THRESHOLD_IVA_OFFSET 0x3a4
#define DRA752_BANDGAP_TSHUT_IVA_OFFSET 0x3ac
#define DRA752_BANDGAP_CUMUL_DTEMP_IVA_OFFSET 0x3b4
#define DRA752_DTEMP_IVA_0_OFFSET 0x3d0
#define DRA752_DTEMP_IVA_1_OFFSET 0x3d4
...
...
@@ -78,7 +76,6 @@
#define DRA752_STD_FUSE_OPP_BGAP_MPU_OFFSET 0x4
#define DRA752_TEMP_SENSOR_MPU_OFFSET 0x14c
#define DRA752_BANDGAP_THRESHOLD_MPU_OFFSET 0x1a4
#define DRA752_BANDGAP_TSHUT_MPU_OFFSET 0x1b0
#define DRA752_BANDGAP_CUMUL_DTEMP_MPU_OFFSET 0x1bc
#define DRA752_DTEMP_MPU_0_OFFSET 0x1e0
#define DRA752_DTEMP_MPU_1_OFFSET 0x1e4
...
...
@@ -90,7 +87,6 @@
#define DRA752_STD_FUSE_OPP_BGAP_DSPEVE_OFFSET 0x384
#define DRA752_TEMP_SENSOR_DSPEVE_OFFSET 0x394
#define DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET 0x3a0
#define DRA752_BANDGAP_TSHUT_DSPEVE_OFFSET 0x3a8
#define DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_OFFSET 0x3b0
#define DRA752_DTEMP_DSPEVE_0_OFFSET 0x3bc
#define DRA752_DTEMP_DSPEVE_1_OFFSET 0x3c0
...
...
@@ -102,7 +98,6 @@
#define DRA752_STD_FUSE_OPP_BGAP_GPU_OFFSET 0x0
#define DRA752_TEMP_SENSOR_GPU_OFFSET 0x150
#define DRA752_BANDGAP_THRESHOLD_GPU_OFFSET 0x1a8
#define DRA752_BANDGAP_TSHUT_GPU_OFFSET 0x1b4
#define DRA752_BANDGAP_CUMUL_DTEMP_GPU_OFFSET 0x1c0
#define DRA752_DTEMP_GPU_0_OFFSET 0x1f4
#define DRA752_DTEMP_GPU_1_OFFSET 0x1f8
...
...
@@ -173,10 +168,6 @@
#define DRA752_BANDGAP_THRESHOLD_HOT_MASK (0x3ff << 16)
#define DRA752_BANDGAP_THRESHOLD_COLD_MASK (0x3ff << 0)
/* DRA752.TSHUT_THRESHOLD */
#define DRA752_TSHUT_THRESHOLD_MUXCTRL_MASK BIT(31)
#define DRA752_TSHUT_THRESHOLD_HOT_MASK (0x3ff << 16)
#define DRA752_TSHUT_THRESHOLD_COLD_MASK (0x3ff << 0)
/* DRA752.BANDGAP_CUMUL_DTEMP_CORE */
#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_MASK (0xffffffff << 0)
...
...
@@ -216,8 +207,6 @@
#define DRA752_GPU_MAX_TEMP 125000
#define DRA752_GPU_HYST_VAL 5000
/* interrupts thresholds */
#define DRA752_GPU_TSHUT_HOT 915
#define DRA752_GPU_TSHUT_COLD 900
#define DRA752_GPU_T_HOT 800
#define DRA752_GPU_T_COLD 795
...
...
@@ -230,8 +219,6 @@
#define DRA752_MPU_MAX_TEMP 125000
#define DRA752_MPU_HYST_VAL 5000
/* interrupts thresholds */
#define DRA752_MPU_TSHUT_HOT 915
#define DRA752_MPU_TSHUT_COLD 900
#define DRA752_MPU_T_HOT 800
#define DRA752_MPU_T_COLD 795
...
...
@@ -244,8 +231,6 @@
#define DRA752_CORE_MAX_TEMP 125000
#define DRA752_CORE_HYST_VAL 5000
/* interrupts thresholds */
#define DRA752_CORE_TSHUT_HOT 915
#define DRA752_CORE_TSHUT_COLD 900
#define DRA752_CORE_T_HOT 800
#define DRA752_CORE_T_COLD 795
...
...
@@ -258,8 +243,6 @@
#define DRA752_DSPEVE_MAX_TEMP 125000
#define DRA752_DSPEVE_HYST_VAL 5000
/* interrupts thresholds */
#define DRA752_DSPEVE_TSHUT_HOT 915
#define DRA752_DSPEVE_TSHUT_COLD 900
#define DRA752_DSPEVE_T_HOT 800
#define DRA752_DSPEVE_T_COLD 795
...
...
@@ -272,8 +255,6 @@
#define DRA752_IVA_MAX_TEMP 125000
#define DRA752_IVA_HYST_VAL 5000
/* interrupts thresholds */
#define DRA752_IVA_TSHUT_HOT 915
#define DRA752_IVA_TSHUT_COLD 900
#define DRA752_IVA_T_HOT 800
#define DRA752_IVA_T_COLD 795
...
...
drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
View file @
6fefe19f
...
...
@@ -49,9 +49,6 @@ dra752_core_temp_sensor_registers = {
.
bgap_threshold
=
DRA752_BANDGAP_THRESHOLD_CORE_OFFSET
,
.
threshold_thot_mask
=
DRA752_BANDGAP_THRESHOLD_HOT_MASK
,
.
threshold_tcold_mask
=
DRA752_BANDGAP_THRESHOLD_COLD_MASK
,
.
tshut_threshold
=
DRA752_BANDGAP_TSHUT_CORE_OFFSET
,
.
tshut_hot_mask
=
DRA752_TSHUT_THRESHOLD_HOT_MASK
,
.
tshut_cold_mask
=
DRA752_TSHUT_THRESHOLD_COLD_MASK
,
.
bgap_status
=
DRA752_BANDGAP_STATUS_1_OFFSET
,
.
status_bgap_alert_mask
=
DRA752_BANDGAP_STATUS_1_ALERT_MASK
,
.
status_hot_mask
=
DRA752_BANDGAP_STATUS_1_HOT_CORE_MASK
,
...
...
@@ -85,9 +82,6 @@ dra752_iva_temp_sensor_registers = {
.
bgap_threshold
=
DRA752_BANDGAP_THRESHOLD_IVA_OFFSET
,
.
threshold_thot_mask
=
DRA752_BANDGAP_THRESHOLD_HOT_MASK
,
.
threshold_tcold_mask
=
DRA752_BANDGAP_THRESHOLD_COLD_MASK
,
.
tshut_threshold
=
DRA752_BANDGAP_TSHUT_IVA_OFFSET
,
.
tshut_hot_mask
=
DRA752_TSHUT_THRESHOLD_HOT_MASK
,
.
tshut_cold_mask
=
DRA752_TSHUT_THRESHOLD_COLD_MASK
,
.
bgap_status
=
DRA752_BANDGAP_STATUS_2_OFFSET
,
.
status_bgap_alert_mask
=
DRA752_BANDGAP_STATUS_1_ALERT_MASK
,
.
status_hot_mask
=
DRA752_BANDGAP_STATUS_2_HOT_IVA_MASK
,
...
...
@@ -121,9 +115,6 @@ dra752_mpu_temp_sensor_registers = {
.
bgap_threshold
=
DRA752_BANDGAP_THRESHOLD_MPU_OFFSET
,
.
threshold_thot_mask
=
DRA752_BANDGAP_THRESHOLD_HOT_MASK
,
.
threshold_tcold_mask
=
DRA752_BANDGAP_THRESHOLD_COLD_MASK
,
.
tshut_threshold
=
DRA752_BANDGAP_TSHUT_MPU_OFFSET
,
.
tshut_hot_mask
=
DRA752_TSHUT_THRESHOLD_HOT_MASK
,
.
tshut_cold_mask
=
DRA752_TSHUT_THRESHOLD_COLD_MASK
,
.
bgap_status
=
DRA752_BANDGAP_STATUS_1_OFFSET
,
.
status_bgap_alert_mask
=
DRA752_BANDGAP_STATUS_1_ALERT_MASK
,
.
status_hot_mask
=
DRA752_BANDGAP_STATUS_1_HOT_MPU_MASK
,
...
...
@@ -157,9 +148,6 @@ dra752_dspeve_temp_sensor_registers = {
.
bgap_threshold
=
DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET
,
.
threshold_thot_mask
=
DRA752_BANDGAP_THRESHOLD_HOT_MASK
,
.
threshold_tcold_mask
=
DRA752_BANDGAP_THRESHOLD_COLD_MASK
,
.
tshut_threshold
=
DRA752_BANDGAP_TSHUT_DSPEVE_OFFSET
,
.
tshut_hot_mask
=
DRA752_TSHUT_THRESHOLD_HOT_MASK
,
.
tshut_cold_mask
=
DRA752_TSHUT_THRESHOLD_COLD_MASK
,
.
bgap_status
=
DRA752_BANDGAP_STATUS_2_OFFSET
,
.
status_bgap_alert_mask
=
DRA752_BANDGAP_STATUS_1_ALERT_MASK
,
.
status_hot_mask
=
DRA752_BANDGAP_STATUS_2_HOT_DSPEVE_MASK
,
...
...
@@ -193,9 +181,6 @@ dra752_gpu_temp_sensor_registers = {
.
bgap_threshold
=
DRA752_BANDGAP_THRESHOLD_GPU_OFFSET
,
.
threshold_thot_mask
=
DRA752_BANDGAP_THRESHOLD_HOT_MASK
,
.
threshold_tcold_mask
=
DRA752_BANDGAP_THRESHOLD_COLD_MASK
,
.
tshut_threshold
=
DRA752_BANDGAP_TSHUT_GPU_OFFSET
,
.
tshut_hot_mask
=
DRA752_TSHUT_THRESHOLD_HOT_MASK
,
.
tshut_cold_mask
=
DRA752_TSHUT_THRESHOLD_COLD_MASK
,
.
bgap_status
=
DRA752_BANDGAP_STATUS_1_OFFSET
,
.
status_bgap_alert_mask
=
DRA752_BANDGAP_STATUS_1_ALERT_MASK
,
.
status_hot_mask
=
DRA752_BANDGAP_STATUS_1_HOT_GPU_MASK
,
...
...
@@ -211,8 +196,6 @@ dra752_gpu_temp_sensor_registers = {
/* Thresholds and limits for DRA752 MPU temperature sensor */
static
struct
temp_sensor_data
dra752_mpu_temp_sensor_data
=
{
.
tshut_hot
=
DRA752_MPU_TSHUT_HOT
,
.
tshut_cold
=
DRA752_MPU_TSHUT_COLD
,
.
t_hot
=
DRA752_MPU_T_HOT
,
.
t_cold
=
DRA752_MPU_T_COLD
,
.
min_freq
=
DRA752_MPU_MIN_FREQ
,
...
...
@@ -226,8 +209,6 @@ static struct temp_sensor_data dra752_mpu_temp_sensor_data = {
/* Thresholds and limits for DRA752 GPU temperature sensor */
static
struct
temp_sensor_data
dra752_gpu_temp_sensor_data
=
{
.
tshut_hot
=
DRA752_GPU_TSHUT_HOT
,
.
tshut_cold
=
DRA752_GPU_TSHUT_COLD
,
.
t_hot
=
DRA752_GPU_T_HOT
,
.
t_cold
=
DRA752_GPU_T_COLD
,
.
min_freq
=
DRA752_GPU_MIN_FREQ
,
...
...
@@ -241,8 +222,6 @@ static struct temp_sensor_data dra752_gpu_temp_sensor_data = {
/* Thresholds and limits for DRA752 CORE temperature sensor */
static
struct
temp_sensor_data
dra752_core_temp_sensor_data
=
{
.
tshut_hot
=
DRA752_CORE_TSHUT_HOT
,
.
tshut_cold
=
DRA752_CORE_TSHUT_COLD
,
.
t_hot
=
DRA752_CORE_T_HOT
,
.
t_cold
=
DRA752_CORE_T_COLD
,
.
min_freq
=
DRA752_CORE_MIN_FREQ
,
...
...
@@ -256,8 +235,6 @@ static struct temp_sensor_data dra752_core_temp_sensor_data = {
/* Thresholds and limits for DRA752 DSPEVE temperature sensor */
static
struct
temp_sensor_data
dra752_dspeve_temp_sensor_data
=
{
.
tshut_hot
=
DRA752_DSPEVE_TSHUT_HOT
,
.
tshut_cold
=
DRA752_DSPEVE_TSHUT_COLD
,
.
t_hot
=
DRA752_DSPEVE_T_HOT
,
.
t_cold
=
DRA752_DSPEVE_T_COLD
,
.
min_freq
=
DRA752_DSPEVE_MIN_FREQ
,
...
...
@@ -271,8 +248,6 @@ static struct temp_sensor_data dra752_dspeve_temp_sensor_data = {
/* Thresholds and limits for DRA752 IVA temperature sensor */
static
struct
temp_sensor_data
dra752_iva_temp_sensor_data
=
{
.
tshut_hot
=
DRA752_IVA_TSHUT_HOT
,
.
tshut_cold
=
DRA752_IVA_TSHUT_COLD
,
.
t_hot
=
DRA752_IVA_T_HOT
,
.
t_cold
=
DRA752_IVA_T_COLD
,
.
min_freq
=
DRA752_IVA_MIN_FREQ
,
...
...
@@ -416,8 +391,7 @@ int dra752_adc_to_temp[DRA752_ADC_END_VALUE - DRA752_ADC_START_VALUE + 1] = {
/* DRA752 data */
const
struct
ti_bandgap_data
dra752_data
=
{
.
features
=
TI_BANDGAP_FEATURE_TSHUT_CONFIG
|
TI_BANDGAP_FEATURE_FREEZE_BIT
|
.
features
=
TI_BANDGAP_FEATURE_FREEZE_BIT
|
TI_BANDGAP_FEATURE_TALERT
|
TI_BANDGAP_FEATURE_COUNTER_DELAY
|
TI_BANDGAP_FEATURE_HISTORY_BUFFER
|
...
...
drivers/thermal/zx2967_thermal.c
0 → 100644
View file @
6fefe19f
/*
* ZTE's zx2967 family thermal sensor driver
*
* Copyright (C) 2017 ZTE Ltd.
*
* Author: Baoyou Xie <baoyou.xie@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
/* Power Mode: 0->low 1->high */
#define ZX2967_THERMAL_POWER_MODE 0
#define ZX2967_POWER_MODE_LOW 0
#define ZX2967_POWER_MODE_HIGH 1
/* DCF Control Register */
#define ZX2967_THERMAL_DCF 0x4
#define ZX2967_DCF_EN BIT(1)
#define ZX2967_DCF_FREEZE BIT(0)
/* Selection Register */
#define ZX2967_THERMAL_SEL 0x8
/* Control Register */
#define ZX2967_THERMAL_CTRL 0x10
#define ZX2967_THERMAL_READY BIT(12)
#define ZX2967_THERMAL_TEMP_MASK GENMASK(11, 0)
#define ZX2967_THERMAL_ID_MASK 0x18
#define ZX2967_THERMAL_ID 0x10
#define ZX2967_GET_TEMP_TIMEOUT_US (100 * 1024)
/**
* struct zx2967_thermal_priv - zx2967 thermal sensor private structure
* @tzd: struct thermal_zone_device where the sensor is registered
* @lock: prevents read sensor in parallel
* @clk_topcrm: topcrm clk structure
* @clk_apb: apb clk structure
* @regs: pointer to base address of the thermal sensor
*/
struct
zx2967_thermal_priv
{
struct
thermal_zone_device
*
tzd
;
struct
mutex
lock
;
struct
clk
*
clk_topcrm
;
struct
clk
*
clk_apb
;
void
__iomem
*
regs
;
struct
device
*
dev
;
};
static
int
zx2967_thermal_get_temp
(
void
*
data
,
int
*
temp
)
{
void
__iomem
*
regs
;
struct
zx2967_thermal_priv
*
priv
=
data
;
u32
val
;
int
ret
;
if
(
!
priv
->
tzd
)
return
-
EAGAIN
;
regs
=
priv
->
regs
;
mutex_lock
(
&
priv
->
lock
);
writel_relaxed
(
ZX2967_POWER_MODE_LOW
,
regs
+
ZX2967_THERMAL_POWER_MODE
);
writel_relaxed
(
ZX2967_DCF_EN
,
regs
+
ZX2967_THERMAL_DCF
);
val
=
readl_relaxed
(
regs
+
ZX2967_THERMAL_SEL
);
val
&=
~
ZX2967_THERMAL_ID_MASK
;
val
|=
ZX2967_THERMAL_ID
;
writel_relaxed
(
val
,
regs
+
ZX2967_THERMAL_SEL
);
/*
* Must wait for a while, surely it's a bit odd.
* otherwise temperature value we got has a few deviation, even if
* the THERMAL_READY bit is set.
*/
usleep_range
(
100
,
300
);
ret
=
readx_poll_timeout
(
readl
,
regs
+
ZX2967_THERMAL_CTRL
,
val
,
val
&
ZX2967_THERMAL_READY
,
300
,
ZX2967_GET_TEMP_TIMEOUT_US
);
if
(
ret
)
{
dev_err
(
priv
->
dev
,
"Thermal sensor data timeout
\n
"
);
goto
unlock
;
}
writel_relaxed
(
ZX2967_DCF_FREEZE
|
ZX2967_DCF_EN
,
regs
+
ZX2967_THERMAL_DCF
);
val
=
readl_relaxed
(
regs
+
ZX2967_THERMAL_CTRL
)
&
ZX2967_THERMAL_TEMP_MASK
;
writel_relaxed
(
ZX2967_POWER_MODE_HIGH
,
regs
+
ZX2967_THERMAL_POWER_MODE
);
/*
* Calculate temperature
* In dts, slope is multiplied by 1000.
*/
*
temp
=
DIV_ROUND_CLOSEST
(((
s32
)
val
+
priv
->
tzd
->
tzp
->
offset
)
*
1000
,
priv
->
tzd
->
tzp
->
slope
);
unlock:
mutex_unlock
(
&
priv
->
lock
);
return
ret
;
}
static
struct
thermal_zone_of_device_ops
zx2967_of_thermal_ops
=
{
.
get_temp
=
zx2967_thermal_get_temp
,
};
static
int
zx2967_thermal_probe
(
struct
platform_device
*
pdev
)
{
struct
zx2967_thermal_priv
*
priv
;
struct
resource
*
res
;
int
ret
;
priv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
priv
),
GFP_KERNEL
);
if
(
!
priv
)
return
-
ENOMEM
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
priv
->
regs
=
devm_ioremap_resource
(
&
pdev
->
dev
,
res
);
if
(
IS_ERR
(
priv
->
regs
))
return
PTR_ERR
(
priv
->
regs
);
priv
->
clk_topcrm
=
devm_clk_get
(
&
pdev
->
dev
,
"topcrm"
);
if
(
IS_ERR
(
priv
->
clk_topcrm
))
{
ret
=
PTR_ERR
(
priv
->
clk_topcrm
);
dev_err
(
&
pdev
->
dev
,
"failed to get topcrm clock: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
clk_prepare_enable
(
priv
->
clk_topcrm
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to enable topcrm clock: %d
\n
"
,
ret
);
return
ret
;
}
priv
->
clk_apb
=
devm_clk_get
(
&
pdev
->
dev
,
"apb"
);
if
(
IS_ERR
(
priv
->
clk_apb
))
{
ret
=
PTR_ERR
(
priv
->
clk_apb
);
dev_err
(
&
pdev
->
dev
,
"failed to get apb clock: %d
\n
"
,
ret
);
goto
disable_clk_topcrm
;
}
ret
=
clk_prepare_enable
(
priv
->
clk_apb
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to enable apb clock: %d
\n
"
,
ret
);
goto
disable_clk_topcrm
;
}
mutex_init
(
&
priv
->
lock
);
priv
->
tzd
=
thermal_zone_of_sensor_register
(
&
pdev
->
dev
,
0
,
priv
,
&
zx2967_of_thermal_ops
);
if
(
IS_ERR
(
priv
->
tzd
))
{
ret
=
PTR_ERR
(
priv
->
tzd
);
dev_err
(
&
pdev
->
dev
,
"failed to register sensor: %d
\n
"
,
ret
);
goto
disable_clk_all
;
}
if
(
priv
->
tzd
->
tzp
->
slope
==
0
)
{
thermal_zone_of_sensor_unregister
(
&
pdev
->
dev
,
priv
->
tzd
);
dev_err
(
&
pdev
->
dev
,
"coefficients of sensor is invalid
\n
"
);
ret
=
-
EINVAL
;
goto
disable_clk_all
;
}
priv
->
dev
=
&
pdev
->
dev
;
platform_set_drvdata
(
pdev
,
priv
);
return
0
;
disable_clk_all:
clk_disable_unprepare
(
priv
->
clk_apb
);
disable_clk_topcrm:
clk_disable_unprepare
(
priv
->
clk_topcrm
);
return
ret
;
}
static
int
zx2967_thermal_exit
(
struct
platform_device
*
pdev
)
{
struct
zx2967_thermal_priv
*
priv
=
platform_get_drvdata
(
pdev
);
thermal_zone_of_sensor_unregister
(
&
pdev
->
dev
,
priv
->
tzd
);
clk_disable_unprepare
(
priv
->
clk_topcrm
);
clk_disable_unprepare
(
priv
->
clk_apb
);
return
0
;
}
static
const
struct
of_device_id
zx2967_thermal_id_table
[]
=
{
{
.
compatible
=
"zte,zx296718-thermal"
},
{}
};
MODULE_DEVICE_TABLE
(
of
,
zx2967_thermal_id_table
);
#ifdef CONFIG_PM_SLEEP
static
int
zx2967_thermal_suspend
(
struct
device
*
dev
)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
zx2967_thermal_priv
*
priv
=
platform_get_drvdata
(
pdev
);
if
(
priv
&&
priv
->
clk_topcrm
)
clk_disable_unprepare
(
priv
->
clk_topcrm
);
if
(
priv
&&
priv
->
clk_apb
)
clk_disable_unprepare
(
priv
->
clk_apb
);
return
0
;
}
static
int
zx2967_thermal_resume
(
struct
device
*
dev
)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
zx2967_thermal_priv
*
priv
=
platform_get_drvdata
(
pdev
);
int
error
;
error
=
clk_prepare_enable
(
priv
->
clk_topcrm
);
if
(
error
)
return
error
;
error
=
clk_prepare_enable
(
priv
->
clk_apb
);
if
(
error
)
{
clk_disable_unprepare
(
priv
->
clk_topcrm
);
return
error
;
}
return
0
;
}
#endif
static
SIMPLE_DEV_PM_OPS
(
zx2967_thermal_pm_ops
,
zx2967_thermal_suspend
,
zx2967_thermal_resume
);
static
struct
platform_driver
zx2967_thermal_driver
=
{
.
probe
=
zx2967_thermal_probe
,
.
remove
=
zx2967_thermal_exit
,
.
driver
=
{
.
name
=
"zx2967_thermal"
,
.
of_match_table
=
zx2967_thermal_id_table
,
.
pm
=
&
zx2967_thermal_pm_ops
,
},
};
module_platform_driver
(
zx2967_thermal_driver
);
MODULE_AUTHOR
(
"Baoyou Xie <baoyou.xie@linaro.org>"
);
MODULE_DESCRIPTION
(
"ZTE zx2967 thermal driver"
);
MODULE_LICENSE
(
"GPL v2"
);
include/linux/thermal.h
View file @
6fefe19f
...
...
@@ -194,7 +194,7 @@ struct thermal_attr {
* @governor: pointer to the governor for this thermal zone
* @governor_data: private pointer for governor data
* @thermal_instances: list of &struct thermal_instance of this thermal zone
* @id
r: &struct idr
to generate unique id for this zone's cooling
* @id
a: &struct ida
to generate unique id for this zone's cooling
* devices
* @lock: lock to protect thermal_instances list
* @node: node in thermal_tz_list (in thermal_core.c)
...
...
@@ -227,7 +227,7 @@ struct thermal_zone_device {
struct
thermal_governor
*
governor
;
void
*
governor_data
;
struct
list_head
thermal_instances
;
struct
id
r
idr
;
struct
id
a
ida
;
struct
mutex
lock
;
struct
list_head
node
;
struct
delayed_work
poll_queue
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment