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
Kirill Smelkov
linux
Commits
7c5b2759
Commit
7c5b2759
authored
Nov 06, 2015
by
Zhang Rui
Browse files
Options
Browse Files
Download
Plain Diff
Merge branches 'thermal-core', 'thermal-intel' and 'thermal-soc' into next
parents
809b6ecb
98cadf25
c422a8ed
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
1043 additions
and
67 deletions
+1043
-67
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
...entation/devicetree/bindings/thermal/rockchip-thermal.txt
+9
-2
Documentation/devicetree/bindings/thermal/ti_soc_thermal.txt
Documentation/devicetree/bindings/thermal/ti_soc_thermal.txt
+14
-0
drivers/base/power/opp.c
drivers/base/power/opp.c
+2
-2
drivers/thermal/Kconfig
drivers/thermal/Kconfig
+17
-0
drivers/thermal/Makefile
drivers/thermal/Makefile
+3
-0
drivers/thermal/armada_thermal.c
drivers/thermal/armada_thermal.c
+3
-3
drivers/thermal/devfreq_cooling.c
drivers/thermal/devfreq_cooling.c
+573
-0
drivers/thermal/imx_thermal.c
drivers/thermal/imx_thermal.c
+12
-9
drivers/thermal/rockchip_thermal.c
drivers/thermal/rockchip_thermal.c
+21
-21
drivers/thermal/samsung/exynos_tmu.c
drivers/thermal/samsung/exynos_tmu.c
+38
-30
drivers/thermal/ti-soc-thermal/Kconfig
drivers/thermal/ti-soc-thermal/Kconfig
+15
-0
drivers/thermal/ti-soc-thermal/Makefile
drivers/thermal/ti-soc-thermal/Makefile
+1
-0
drivers/thermal/ti-soc-thermal/omap3-thermal-data.c
drivers/thermal/ti-soc-thermal/omap3-thermal-data.c
+176
-0
drivers/thermal/ti-soc-thermal/ti-bandgap.c
drivers/thermal/ti-soc-thermal/ti-bandgap.c
+14
-0
drivers/thermal/ti-soc-thermal/ti-bandgap.h
drivers/thermal/ti-soc-thermal/ti-bandgap.h
+11
-0
include/linux/devfreq_cooling.h
include/linux/devfreq_cooling.h
+81
-0
include/trace/events/thermal.h
include/trace/events/thermal.h
+53
-0
No files found.
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
View file @
7c5b2759
...
@@ -12,6 +12,11 @@ Required properties:
...
@@ -12,6 +12,11 @@ Required properties:
- resets : Must contain an entry for each entry in reset-names.
- resets : Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
See ../reset/reset.txt for details.
- reset-names : Must include the name "tsadc-apb".
- reset-names : Must include the name "tsadc-apb".
- pinctrl-names : The pin control state names;
- pinctrl-0 : The "init" pinctrl state, it will be set before device probe.
- pinctrl-1 : The "default" pinctrl state, it will be set after reset the
TSADC controller.
- pinctrl-2 : The "sleep" pinctrl state, it will be in for suspend.
- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
- rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value.
- rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value.
- rockchip,hw-tshut-mode : The hardware-controlled shutdown mode 0:CRU 1:GPIO.
- rockchip,hw-tshut-mode : The hardware-controlled shutdown mode 0:CRU 1:GPIO.
...
@@ -27,8 +32,10 @@ tsadc: tsadc@ff280000 {
...
@@ -27,8 +32,10 @@ tsadc: tsadc@ff280000 {
clock-names = "tsadc", "apb_pclk";
clock-names = "tsadc", "apb_pclk";
resets = <&cru SRST_TSADC>;
resets = <&cru SRST_TSADC>;
reset-names = "tsadc-apb";
reset-names = "tsadc-apb";
pinctrl-names = "default";
pinctrl-names = "init", "default", "sleep";
pinctrl-0 = <&otp_out>;
pinctrl-0 = <&otp_gpio>;
pinctrl-1 = <&otp_out>;
pinctrl-2 = <&otp_gpio>;
#thermal-sensor-cells = <1>;
#thermal-sensor-cells = <1>;
rockchip,hw-tshut-temp = <95000>;
rockchip,hw-tshut-temp = <95000>;
rockchip,hw-tshut-mode = <0>;
rockchip,hw-tshut-mode = <0>;
...
...
Documentation/devicetree/bindings/thermal/ti_soc_thermal.txt
View file @
7c5b2759
...
@@ -10,6 +10,8 @@ to the silicon temperature.
...
@@ -10,6 +10,8 @@ to the silicon temperature.
Required properties:
Required properties:
- compatible : Should be:
- compatible : Should be:
- "ti,omap34xx-bandgap" : for OMAP34xx bandgap
- "ti,omap36xx-bandgap" : for OMAP36xx bandgap
- "ti,omap4430-bandgap" : for OMAP4430 bandgap
- "ti,omap4430-bandgap" : for OMAP4430 bandgap
- "ti,omap4460-bandgap" : for OMAP4460 bandgap
- "ti,omap4460-bandgap" : for OMAP4460 bandgap
- "ti,omap4470-bandgap" : for OMAP4470 bandgap
- "ti,omap4470-bandgap" : for OMAP4470 bandgap
...
@@ -25,6 +27,18 @@ to each bandgap version, because the mapping may change from
...
@@ -25,6 +27,18 @@ to each bandgap version, because the mapping may change from
soc to soc, apart of depending on available features.
soc to soc, apart of depending on available features.
Example:
Example:
OMAP34xx:
bandgap {
reg = <0x48002524 0x4>;
compatible = "ti,omap34xx-bandgap";
};
OMAP36xx:
bandgap {
reg = <0x48002524 0x4>;
compatible = "ti,omap36xx-bandgap";
};
OMAP4430:
OMAP4430:
bandgap {
bandgap {
reg = <0x4a002260 0x4 0x4a00232C 0x4>;
reg = <0x4a002260 0x4 0x4a00232C 0x4>;
...
...
drivers/base/power/opp.c
View file @
7c5b2759
...
@@ -217,7 +217,7 @@ static struct device_opp *_find_device_opp(struct device *dev)
...
@@ -217,7 +217,7 @@ static struct device_opp *_find_device_opp(struct device *dev)
}
}
/**
/**
* dev_pm_opp_get_voltage() - Gets the voltage corresponding to an
available
opp
* dev_pm_opp_get_voltage() - Gets the voltage corresponding to an opp
* @opp: opp for which voltage has to be returned for
* @opp: opp for which voltage has to be returned for
*
*
* Return: voltage in micro volt corresponding to the opp, else
* Return: voltage in micro volt corresponding to the opp, else
...
@@ -239,7 +239,7 @@ unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
...
@@ -239,7 +239,7 @@ unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
opp_rcu_lockdep_assert
();
opp_rcu_lockdep_assert
();
tmp_opp
=
rcu_dereference
(
opp
);
tmp_opp
=
rcu_dereference
(
opp
);
if
(
IS_ERR_OR_NULL
(
tmp_opp
)
||
!
tmp_opp
->
available
)
if
(
IS_ERR_OR_NULL
(
tmp_opp
))
pr_err
(
"%s: Invalid parameters
\n
"
,
__func__
);
pr_err
(
"%s: Invalid parameters
\n
"
,
__func__
);
else
else
v
=
tmp_opp
->
u_volt
;
v
=
tmp_opp
->
u_volt
;
...
...
drivers/thermal/Kconfig
View file @
7c5b2759
...
@@ -147,6 +147,20 @@ config CLOCK_THERMAL
...
@@ -147,6 +147,20 @@ config CLOCK_THERMAL
device that is configured to use this cooling mechanism will be
device that is configured to use this cooling mechanism will be
controlled to reduce clock frequency whenever temperature is high.
controlled to reduce clock frequency whenever temperature is high.
config DEVFREQ_THERMAL
bool "Generic device cooling support"
depends on PM_DEVFREQ
depends on PM_OPP
help
This implements the generic devfreq cooling mechanism through
frequency reduction for devices using devfreq.
This will throttle the device by limiting the maximum allowed DVFS
frequency corresponding to the cooling level.
In order to use the power extensions of the cooling device,
devfreq should use the simple_ondemand governor.
If you want this support, you should say Y here.
If you want this support, you should say Y here.
config THERMAL_EMULATION
config THERMAL_EMULATION
...
@@ -275,6 +289,7 @@ config X86_PKG_TEMP_THERMAL
...
@@ -275,6 +289,7 @@ config X86_PKG_TEMP_THERMAL
tristate "X86 package temperature thermal driver"
tristate "X86 package temperature thermal driver"
depends on X86_THERMAL_VECTOR
depends on X86_THERMAL_VECTOR
select THERMAL_GOV_USER_SPACE
select THERMAL_GOV_USER_SPACE
select THERMAL_WRITABLE_TRIPS
default m
default m
help
help
Enable this to register CPU digital sensor for package temperature as
Enable this to register CPU digital sensor for package temperature as
...
@@ -296,6 +311,7 @@ config INTEL_SOC_DTS_THERMAL
...
@@ -296,6 +311,7 @@ config INTEL_SOC_DTS_THERMAL
tristate "Intel SoCs DTS thermal driver"
tristate "Intel SoCs DTS thermal driver"
depends on X86
depends on X86
select INTEL_SOC_DTS_IOSF_CORE
select INTEL_SOC_DTS_IOSF_CORE
select THERMAL_WRITABLE_TRIPS
help
help
Enable this to register Intel SoCs (e.g. Bay Trail) platform digital
Enable this to register Intel SoCs (e.g. Bay Trail) platform digital
temperature sensor (DTS). These SoCs have two additional DTSs in
temperature sensor (DTS). These SoCs have two additional DTSs in
...
@@ -322,6 +338,7 @@ config INT340X_THERMAL
...
@@ -322,6 +338,7 @@ config INT340X_THERMAL
select ACPI_THERMAL_REL
select ACPI_THERMAL_REL
select ACPI_FAN
select ACPI_FAN
select INTEL_SOC_DTS_IOSF_CORE
select INTEL_SOC_DTS_IOSF_CORE
select THERMAL_WRITABLE_TRIPS
help
help
Newer laptops and tablets that use ACPI may have thermal sensors and
Newer laptops and tablets that use ACPI may have thermal sensors and
other devices with thermal control capabilities outside the core
other devices with thermal control capabilities outside the core
...
...
drivers/thermal/Makefile
View file @
7c5b2759
...
@@ -22,6 +22,9 @@ thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o
...
@@ -22,6 +22,9 @@ thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o
# clock cooling
# clock cooling
thermal_sys-$(CONFIG_CLOCK_THERMAL)
+=
clock_cooling.o
thermal_sys-$(CONFIG_CLOCK_THERMAL)
+=
clock_cooling.o
# devfreq cooling
thermal_sys-$(CONFIG_DEVFREQ_THERMAL)
+=
devfreq_cooling.o
# platform thermal drivers
# platform thermal drivers
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM)
+=
qcom-spmi-temp-alarm.o
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM)
+=
qcom-spmi-temp-alarm.o
obj-$(CONFIG_SPEAR_THERMAL)
+=
spear_thermal.o
obj-$(CONFIG_SPEAR_THERMAL)
+=
spear_thermal.o
...
...
drivers/thermal/armada_thermal.c
View file @
7c5b2759
...
@@ -224,9 +224,9 @@ static const struct armada_thermal_data armada380_data = {
...
@@ -224,9 +224,9 @@ static const struct armada_thermal_data armada380_data = {
.
is_valid_shift
=
10
,
.
is_valid_shift
=
10
,
.
temp_shift
=
0
,
.
temp_shift
=
0
,
.
temp_mask
=
0x3ff
,
.
temp_mask
=
0x3ff
,
.
coef_b
=
29311082
00UL
,
.
coef_b
=
11724991
00UL
,
.
coef_m
=
5000000
UL
,
.
coef_m
=
2000096
UL
,
.
coef_div
=
10502
,
.
coef_div
=
4201
,
.
inverted
=
true
,
.
inverted
=
true
,
};
};
...
...
drivers/thermal/devfreq_cooling.c
0 → 100644
View file @
7c5b2759
/*
* devfreq_cooling: Thermal cooling device implementation for devices using
* devfreq
*
* Copyright (C) 2014-2015 ARM Limited
*
* 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.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* TODO:
* - If OPPs are added or removed after devfreq cooling has
* registered, the devfreq cooling won't react to it.
*/
#include <linux/devfreq.h>
#include <linux/devfreq_cooling.h>
#include <linux/export.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
);
/**
* struct devfreq_cooling_device - Devfreq cooling device
* @id: unique integer value corresponding to each
* devfreq_cooling_device registered.
* @cdev: Pointer to associated thermal cooling device.
* @devfreq: Pointer to associated devfreq device.
* @cooling_state: Current cooling state.
* @power_table: Pointer to table with maximum power draw for each
* cooling state. State is the index into the table, and
* the power is in mW.
* @freq_table: Pointer to a table with the frequencies sorted in descending
* order. You can index the table by cooling device state
* @freq_table_size: Size of the @freq_table and @power_table
* @power_ops: Pointer to devfreq_cooling_power, used to generate the
* @power_table.
*/
struct
devfreq_cooling_device
{
int
id
;
struct
thermal_cooling_device
*
cdev
;
struct
devfreq
*
devfreq
;
unsigned
long
cooling_state
;
u32
*
power_table
;
u32
*
freq_table
;
size_t
freq_table_size
;
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
* @cdev_state: cooling device state we're setting
*
* Go through the OPPs of the device, enabling all OPPs until
* @cdev_state and disabling those frequencies above it.
*/
static
int
partition_enable_opps
(
struct
devfreq_cooling_device
*
dfc
,
unsigned
long
cdev_state
)
{
int
i
;
struct
device
*
dev
=
dfc
->
devfreq
->
dev
.
parent
;
for
(
i
=
0
;
i
<
dfc
->
freq_table_size
;
i
++
)
{
struct
dev_pm_opp
*
opp
;
int
ret
=
0
;
unsigned
int
freq
=
dfc
->
freq_table
[
i
];
bool
want_enable
=
i
>=
cdev_state
?
true
:
false
;
rcu_read_lock
();
opp
=
dev_pm_opp_find_freq_exact
(
dev
,
freq
,
!
want_enable
);
rcu_read_unlock
();
if
(
PTR_ERR
(
opp
)
==
-
ERANGE
)
continue
;
else
if
(
IS_ERR
(
opp
))
return
PTR_ERR
(
opp
);
if
(
want_enable
)
ret
=
dev_pm_opp_enable
(
dev
,
freq
);
else
ret
=
dev_pm_opp_disable
(
dev
,
freq
);
if
(
ret
)
return
ret
;
}
return
0
;
}
static
int
devfreq_cooling_get_max_state
(
struct
thermal_cooling_device
*
cdev
,
unsigned
long
*
state
)
{
struct
devfreq_cooling_device
*
dfc
=
cdev
->
devdata
;
*
state
=
dfc
->
freq_table_size
-
1
;
return
0
;
}
static
int
devfreq_cooling_get_cur_state
(
struct
thermal_cooling_device
*
cdev
,
unsigned
long
*
state
)
{
struct
devfreq_cooling_device
*
dfc
=
cdev
->
devdata
;
*
state
=
dfc
->
cooling_state
;
return
0
;
}
static
int
devfreq_cooling_set_cur_state
(
struct
thermal_cooling_device
*
cdev
,
unsigned
long
state
)
{
struct
devfreq_cooling_device
*
dfc
=
cdev
->
devdata
;
struct
devfreq
*
df
=
dfc
->
devfreq
;
struct
device
*
dev
=
df
->
dev
.
parent
;
int
ret
;
if
(
state
==
dfc
->
cooling_state
)
return
0
;
dev_dbg
(
dev
,
"Setting cooling state %lu
\n
"
,
state
);
if
(
state
>=
dfc
->
freq_table_size
)
return
-
EINVAL
;
ret
=
partition_enable_opps
(
dfc
,
state
);
if
(
ret
)
return
ret
;
dfc
->
cooling_state
=
state
;
return
0
;
}
/**
* freq_get_state() - get the cooling state corresponding to a frequency
* @dfc: Pointer to devfreq cooling device
* @freq: frequency in Hz
*
* Return: the cooling state associated with the @freq, or
* THERMAL_CSTATE_INVALID if it wasn't found.
*/
static
unsigned
long
freq_get_state
(
struct
devfreq_cooling_device
*
dfc
,
unsigned
long
freq
)
{
int
i
;
for
(
i
=
0
;
i
<
dfc
->
freq_table_size
;
i
++
)
{
if
(
dfc
->
freq_table
[
i
]
==
freq
)
return
i
;
}
return
THERMAL_CSTATE_INVALID
;
}
/**
* get_static_power() - calculate the static power
* @dfc: Pointer to devfreq cooling device
* @freq: Frequency in Hz
*
* Calculate the static power in milliwatts using the supplied
* get_static_power(). The current voltage is calculated using the
* OPP library. If no get_static_power() was supplied, assume the
* static power is negligible.
*/
static
unsigned
long
get_static_power
(
struct
devfreq_cooling_device
*
dfc
,
unsigned
long
freq
)
{
struct
devfreq
*
df
=
dfc
->
devfreq
;
struct
device
*
dev
=
df
->
dev
.
parent
;
unsigned
long
voltage
;
struct
dev_pm_opp
*
opp
;
if
(
!
dfc
->
power_ops
->
get_static_power
)
return
0
;
rcu_read_lock
();
opp
=
dev_pm_opp_find_freq_exact
(
dev
,
freq
,
true
);
if
(
IS_ERR
(
opp
)
&&
(
PTR_ERR
(
opp
)
==
-
ERANGE
))
opp
=
dev_pm_opp_find_freq_exact
(
dev
,
freq
,
false
);
voltage
=
dev_pm_opp_get_voltage
(
opp
)
/
1000
;
/* mV */
rcu_read_unlock
();
if
(
voltage
==
0
)
{
dev_warn_ratelimited
(
dev
,
"Failed to get voltage for frequency %lu: %ld
\n
"
,
freq
,
IS_ERR
(
opp
)
?
PTR_ERR
(
opp
)
:
0
);
return
0
;
}
return
dfc
->
power_ops
->
get_static_power
(
voltage
);
}
/**
* get_dynamic_power - calculate the dynamic power
* @dfc: Pointer to devfreq cooling device
* @freq: Frequency in Hz
* @voltage: Voltage in millivolts
*
* Calculate the dynamic power in milliwatts consumed by the device at
* frequency @freq and voltage @voltage. If the get_dynamic_power()
* was supplied as part of the devfreq_cooling_power struct, then that
* function is used. Otherwise, a simple power model (Pdyn = Coeff *
* Voltage^2 * Frequency) is used.
*/
static
unsigned
long
get_dynamic_power
(
struct
devfreq_cooling_device
*
dfc
,
unsigned
long
freq
,
unsigned
long
voltage
)
{
u64
power
;
u32
freq_mhz
;
struct
devfreq_cooling_power
*
dfc_power
=
dfc
->
power_ops
;
if
(
dfc_power
->
get_dynamic_power
)
return
dfc_power
->
get_dynamic_power
(
freq
,
voltage
);
freq_mhz
=
freq
/
1000000
;
power
=
(
u64
)
dfc_power
->
dyn_power_coeff
*
freq_mhz
*
voltage
*
voltage
;
do_div
(
power
,
1000000000
);
return
power
;
}
static
int
devfreq_cooling_get_requested_power
(
struct
thermal_cooling_device
*
cdev
,
struct
thermal_zone_device
*
tz
,
u32
*
power
)
{
struct
devfreq_cooling_device
*
dfc
=
cdev
->
devdata
;
struct
devfreq
*
df
=
dfc
->
devfreq
;
struct
devfreq_dev_status
*
status
=
&
df
->
last_status
;
unsigned
long
state
;
unsigned
long
freq
=
status
->
current_frequency
;
u32
dyn_power
,
static_power
;
/* Get dynamic power for state */
state
=
freq_get_state
(
dfc
,
freq
);
if
(
state
==
THERMAL_CSTATE_INVALID
)
return
-
EAGAIN
;
dyn_power
=
dfc
->
power_table
[
state
];
/* Scale dynamic power for utilization */
dyn_power
=
(
dyn_power
*
status
->
busy_time
)
/
status
->
total_time
;
/* Get static power */
static_power
=
get_static_power
(
dfc
,
freq
);
trace_thermal_power_devfreq_get_power
(
cdev
,
status
,
freq
,
dyn_power
,
static_power
);
*
power
=
dyn_power
+
static_power
;
return
0
;
}
static
int
devfreq_cooling_state2power
(
struct
thermal_cooling_device
*
cdev
,
struct
thermal_zone_device
*
tz
,
unsigned
long
state
,
u32
*
power
)
{
struct
devfreq_cooling_device
*
dfc
=
cdev
->
devdata
;
unsigned
long
freq
;
u32
static_power
;
if
(
state
<
0
||
state
>=
dfc
->
freq_table_size
)
return
-
EINVAL
;
freq
=
dfc
->
freq_table
[
state
];
static_power
=
get_static_power
(
dfc
,
freq
);
*
power
=
dfc
->
power_table
[
state
]
+
static_power
;
return
0
;
}
static
int
devfreq_cooling_power2state
(
struct
thermal_cooling_device
*
cdev
,
struct
thermal_zone_device
*
tz
,
u32
power
,
unsigned
long
*
state
)
{
struct
devfreq_cooling_device
*
dfc
=
cdev
->
devdata
;
struct
devfreq
*
df
=
dfc
->
devfreq
;
struct
devfreq_dev_status
*
status
=
&
df
->
last_status
;
unsigned
long
freq
=
status
->
current_frequency
;
unsigned
long
busy_time
;
s32
dyn_power
;
u32
static_power
;
int
i
;
static_power
=
get_static_power
(
dfc
,
freq
);
dyn_power
=
power
-
static_power
;
dyn_power
=
dyn_power
>
0
?
dyn_power
:
0
;
/* Scale dynamic power for utilization */
busy_time
=
status
->
busy_time
?:
1
;
dyn_power
=
(
dyn_power
*
status
->
total_time
)
/
busy_time
;
/*
* Find the first cooling state that is within the power
* budget for dynamic power.
*/
for
(
i
=
0
;
i
<
dfc
->
freq_table_size
-
1
;
i
++
)
if
(
dyn_power
>=
dfc
->
power_table
[
i
])
break
;
*
state
=
i
;
trace_thermal_power_devfreq_limit
(
cdev
,
freq
,
*
state
,
power
);
return
0
;
}
static
struct
thermal_cooling_device_ops
devfreq_cooling_ops
=
{
.
get_max_state
=
devfreq_cooling_get_max_state
,
.
get_cur_state
=
devfreq_cooling_get_cur_state
,
.
set_cur_state
=
devfreq_cooling_set_cur_state
,
};
/**
* devfreq_cooling_gen_tables() - Generate power and freq tables.
* @dfc: Pointer to devfreq cooling device.
*
* Generate power and frequency tables: the power table hold the
* device's maximum power usage at each cooling state (OPP). The
* static and dynamic power using the appropriate voltage and
* frequency for the state, is acquired from the struct
* devfreq_cooling_power, and summed to make the maximum power draw.
*
* The frequency table holds the frequencies in descending order.
* That way its indexed by cooling device state.
*
* The tables are malloced, and pointers put in dfc. They must be
* freed when unregistering the devfreq cooling device.
*
* Return: 0 on success, negative error code on failure.
*/
static
int
devfreq_cooling_gen_tables
(
struct
devfreq_cooling_device
*
dfc
)
{
struct
devfreq
*
df
=
dfc
->
devfreq
;
struct
device
*
dev
=
df
->
dev
.
parent
;
int
ret
,
num_opps
;
unsigned
long
freq
;
u32
*
power_table
=
NULL
;
u32
*
freq_table
;
int
i
;
num_opps
=
dev_pm_opp_get_opp_count
(
dev
);
if
(
dfc
->
power_ops
)
{
power_table
=
kcalloc
(
num_opps
,
sizeof
(
*
power_table
),
GFP_KERNEL
);
if
(
!
power_table
)
return
-
ENOMEM
;
}
freq_table
=
kcalloc
(
num_opps
,
sizeof
(
*
freq_table
),
GFP_KERNEL
);
if
(
!
freq_table
)
{
ret
=
-
ENOMEM
;
goto
free_power_table
;
}
for
(
i
=
0
,
freq
=
ULONG_MAX
;
i
<
num_opps
;
i
++
,
freq
--
)
{
unsigned
long
power_dyn
,
voltage
;
struct
dev_pm_opp
*
opp
;
rcu_read_lock
();
opp
=
dev_pm_opp_find_freq_floor
(
dev
,
&
freq
);
if
(
IS_ERR
(
opp
))
{
rcu_read_unlock
();
ret
=
PTR_ERR
(
opp
);
goto
free_tables
;
}
voltage
=
dev_pm_opp_get_voltage
(
opp
)
/
1000
;
/* mV */
rcu_read_unlock
();
if
(
dfc
->
power_ops
)
{
power_dyn
=
get_dynamic_power
(
dfc
,
freq
,
voltage
);
dev_dbg
(
dev
,
"Dynamic power table: %lu MHz @ %lu mV: %lu = %lu mW
\n
"
,
freq
/
1000000
,
voltage
,
power_dyn
,
power_dyn
);
power_table
[
i
]
=
power_dyn
;
}
freq_table
[
i
]
=
freq
;
}
if
(
dfc
->
power_ops
)
dfc
->
power_table
=
power_table
;
dfc
->
freq_table
=
freq_table
;
dfc
->
freq_table_size
=
num_opps
;
return
0
;
free_tables:
kfree
(
freq_table
);
free_power_table:
kfree
(
power_table
);
return
ret
;
}
/**
* of_devfreq_cooling_register_power() - Register devfreq cooling device,
* with OF and power information.
* @np: Pointer to OF device_node.
* @df: Pointer to devfreq device.
* @dfc_power: Pointer to devfreq_cooling_power.
*
* Register a devfreq cooling device. The available OPPs must be
* registered on the device.
*
* If @dfc_power is provided, the cooling device is registered with the
* power extensions. For the power extensions to work correctly,
* devfreq should use the simple_ondemand governor, other governors
* are not currently supported.
*/
struct
thermal_cooling_device
*
of_devfreq_cooling_register_power
(
struct
device_node
*
np
,
struct
devfreq
*
df
,
struct
devfreq_cooling_power
*
dfc_power
)
{
struct
thermal_cooling_device
*
cdev
;
struct
devfreq_cooling_device
*
dfc
;
char
dev_name
[
THERMAL_NAME_LENGTH
];
int
err
;
dfc
=
kzalloc
(
sizeof
(
*
dfc
),
GFP_KERNEL
);
if
(
!
dfc
)
return
ERR_PTR
(
-
ENOMEM
);
dfc
->
devfreq
=
df
;
if
(
dfc_power
)
{
dfc
->
power_ops
=
dfc_power
;
devfreq_cooling_ops
.
get_requested_power
=
devfreq_cooling_get_requested_power
;
devfreq_cooling_ops
.
state2power
=
devfreq_cooling_state2power
;
devfreq_cooling_ops
.
power2state
=
devfreq_cooling_power2state
;
}
err
=
devfreq_cooling_gen_tables
(
dfc
);
if
(
err
)
goto
free_dfc
;
err
=
get_idr
(
&
devfreq_idr
,
&
dfc
->
id
);
if
(
err
)
goto
free_tables
;
snprintf
(
dev_name
,
sizeof
(
dev_name
),
"thermal-devfreq-%d"
,
dfc
->
id
);
cdev
=
thermal_of_cooling_device_register
(
np
,
dev_name
,
dfc
,
&
devfreq_cooling_ops
);
if
(
IS_ERR
(
cdev
))
{
err
=
PTR_ERR
(
cdev
);
dev_err
(
df
->
dev
.
parent
,
"Failed to register devfreq cooling device (%d)
\n
"
,
err
);
goto
release_idr
;
}
dfc
->
cdev
=
cdev
;
return
cdev
;
release_idr:
release_idr
(
&
devfreq_idr
,
dfc
->
id
);
free_tables:
kfree
(
dfc
->
power_table
);
kfree
(
dfc
->
freq_table
);
free_dfc:
kfree
(
dfc
);
return
ERR_PTR
(
err
);
}
EXPORT_SYMBOL_GPL
(
of_devfreq_cooling_register_power
);
/**
* of_devfreq_cooling_register() - Register devfreq cooling device,
* with OF information.
* @np: Pointer to OF device_node.
* @df: Pointer to devfreq device.
*/
struct
thermal_cooling_device
*
of_devfreq_cooling_register
(
struct
device_node
*
np
,
struct
devfreq
*
df
)
{
return
of_devfreq_cooling_register_power
(
np
,
df
,
NULL
);
}
EXPORT_SYMBOL_GPL
(
of_devfreq_cooling_register
);
/**
* devfreq_cooling_register() - Register devfreq cooling device.
* @df: Pointer to devfreq device.
*/
struct
thermal_cooling_device
*
devfreq_cooling_register
(
struct
devfreq
*
df
)
{
return
of_devfreq_cooling_register
(
NULL
,
df
);
}
EXPORT_SYMBOL_GPL
(
devfreq_cooling_register
);
/**
* devfreq_cooling_unregister() - Unregister devfreq cooling device.
* @dfc: Pointer to devfreq cooling device to unregister.
*/
void
devfreq_cooling_unregister
(
struct
thermal_cooling_device
*
cdev
)
{
struct
devfreq_cooling_device
*
dfc
;
if
(
!
cdev
)
return
;
dfc
=
cdev
->
devdata
;
thermal_cooling_device_unregister
(
dfc
->
cdev
);
release_idr
(
&
devfreq_idr
,
dfc
->
id
);
kfree
(
dfc
->
power_table
);
kfree
(
dfc
->
freq_table
);
kfree
(
dfc
);
}
EXPORT_SYMBOL_GPL
(
devfreq_cooling_unregister
);
drivers/thermal/imx_thermal.c
View file @
7c5b2759
...
@@ -288,7 +288,7 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
...
@@ -288,7 +288,7 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
if
(
trip
==
IMX_TRIP_CRITICAL
)
if
(
trip
==
IMX_TRIP_CRITICAL
)
return
-
EPERM
;
return
-
EPERM
;
if
(
temp
>
IMX_TEMP_PASSIVE
)
if
(
temp
<
0
||
temp
>
IMX_TEMP_PASSIVE
)
return
-
EINVAL
;
return
-
EINVAL
;
data
->
temp_passive
=
temp
;
data
->
temp_passive
=
temp
;
...
@@ -487,14 +487,6 @@ static int imx_thermal_probe(struct platform_device *pdev)
...
@@ -487,14 +487,6 @@ static int imx_thermal_probe(struct platform_device *pdev)
if
(
data
->
irq
<
0
)
if
(
data
->
irq
<
0
)
return
data
->
irq
;
return
data
->
irq
;
ret
=
devm_request_threaded_irq
(
&
pdev
->
dev
,
data
->
irq
,
imx_thermal_alarm_irq
,
imx_thermal_alarm_irq_thread
,
0
,
"imx_thermal"
,
data
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"failed to request alarm irq: %d
\n
"
,
ret
);
return
ret
;
}
platform_set_drvdata
(
pdev
,
data
);
platform_set_drvdata
(
pdev
,
data
);
ret
=
imx_get_sensor_data
(
pdev
);
ret
=
imx_get_sensor_data
(
pdev
);
...
@@ -571,6 +563,17 @@ static int imx_thermal_probe(struct platform_device *pdev)
...
@@ -571,6 +563,17 @@ static int imx_thermal_probe(struct platform_device *pdev)
regmap_write
(
map
,
TEMPSENSE0
+
REG_CLR
,
TEMPSENSE0_POWER_DOWN
);
regmap_write
(
map
,
TEMPSENSE0
+
REG_CLR
,
TEMPSENSE0_POWER_DOWN
);
regmap_write
(
map
,
TEMPSENSE0
+
REG_SET
,
TEMPSENSE0_MEASURE_TEMP
);
regmap_write
(
map
,
TEMPSENSE0
+
REG_SET
,
TEMPSENSE0_MEASURE_TEMP
);
ret
=
devm_request_threaded_irq
(
&
pdev
->
dev
,
data
->
irq
,
imx_thermal_alarm_irq
,
imx_thermal_alarm_irq_thread
,
0
,
"imx_thermal"
,
data
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"failed to request alarm irq: %d
\n
"
,
ret
);
clk_disable_unprepare
(
data
->
thermal_clk
);
thermal_zone_device_unregister
(
data
->
tz
);
cpufreq_cooling_unregister
(
data
->
cdev
);
return
ret
;
}
data
->
irq_enabled
=
true
;
data
->
irq_enabled
=
true
;
data
->
mode
=
THERMAL_DEVICE_ENABLED
;
data
->
mode
=
THERMAL_DEVICE_ENABLED
;
...
...
drivers/thermal/rockchip_thermal.c
View file @
7c5b2759
...
@@ -106,16 +106,14 @@ struct rockchip_thermal_data {
...
@@ -106,16 +106,14 @@ struct rockchip_thermal_data {
#define TSADCV2_AUTO_PERIOD_HT 0x6c
#define TSADCV2_AUTO_PERIOD_HT 0x6c
#define TSADCV2_AUTO_EN BIT(0)
#define TSADCV2_AUTO_EN BIT(0)
#define TSADCV2_AUTO_DISABLE ~BIT(0)
#define TSADCV2_AUTO_SRC_EN(chn) BIT(4 + (chn))
#define TSADCV2_AUTO_SRC_EN(chn) BIT(4 + (chn))
#define TSADCV2_AUTO_TSHUT_POLARITY_HIGH BIT(8)
#define TSADCV2_AUTO_TSHUT_POLARITY_HIGH BIT(8)
#define TSADCV2_AUTO_TSHUT_POLARITY_LOW ~BIT(8)
#define TSADCV2_INT_SRC_EN(chn) BIT(chn)
#define TSADCV2_INT_SRC_EN(chn) BIT(chn)
#define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn))
#define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn))
#define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn))
#define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn))
#define TSADCV2_INT_PD_CLEAR
~BIT(8)
#define TSADCV2_INT_PD_CLEAR
_MASK
~BIT(8)
#define TSADCV2_DATA_MASK 0xfff
#define TSADCV2_DATA_MASK 0xfff
#define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4
#define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4
...
@@ -124,7 +122,7 @@ struct rockchip_thermal_data {
...
@@ -124,7 +122,7 @@ struct rockchip_thermal_data {
#define TSADCV2_AUTO_PERIOD_HT_TIME 50
/* msec */
#define TSADCV2_AUTO_PERIOD_HT_TIME 50
/* msec */
struct
tsadc_table
{
struct
tsadc_table
{
u
nsigned
long
code
;
u
32
code
;
long
temp
;
long
temp
;
};
};
...
@@ -164,7 +162,6 @@ static const struct tsadc_table v2_code_table[] = {
...
@@ -164,7 +162,6 @@ static const struct tsadc_table v2_code_table[] = {
{
3452
,
115000
},
{
3452
,
115000
},
{
3437
,
120000
},
{
3437
,
120000
},
{
3421
,
125000
},
{
3421
,
125000
},
{
0
,
125000
},
};
};
static
u32
rk_tsadcv2_temp_to_code
(
long
temp
)
static
u32
rk_tsadcv2_temp_to_code
(
long
temp
)
...
@@ -191,19 +188,21 @@ static u32 rk_tsadcv2_temp_to_code(long temp)
...
@@ -191,19 +188,21 @@ static u32 rk_tsadcv2_temp_to_code(long temp)
return
0
;
return
0
;
}
}
static
int
rk_tsadcv2_code_to_temp
(
u32
code
)
static
int
rk_tsadcv2_code_to_temp
(
u32
code
,
int
*
temp
)
{
{
unsigned
int
low
=
0
;
unsigned
int
low
=
1
;
unsigned
int
high
=
ARRAY_SIZE
(
v2_code_table
)
-
1
;
unsigned
int
high
=
ARRAY_SIZE
(
v2_code_table
)
-
1
;
unsigned
int
mid
=
(
low
+
high
)
/
2
;
unsigned
int
mid
=
(
low
+
high
)
/
2
;
unsigned
int
num
;
unsigned
int
num
;
unsigned
long
denom
;
unsigned
long
denom
;
/* Invalid code, return -EAGAIN */
BUILD_BUG_ON
(
ARRAY_SIZE
(
v2_code_table
)
<
2
);
if
(
code
>
TSADCV2_DATA_MASK
)
return
-
EAGAIN
;
while
(
low
<=
high
&&
mid
)
{
code
&=
TSADCV2_DATA_MASK
;
if
(
code
<
v2_code_table
[
high
].
code
)
return
-
EAGAIN
;
/* Incorrect reading */
while
(
low
<=
high
)
{
if
(
code
>=
v2_code_table
[
mid
].
code
&&
if
(
code
>=
v2_code_table
[
mid
].
code
&&
code
<
v2_code_table
[
mid
-
1
].
code
)
code
<
v2_code_table
[
mid
-
1
].
code
)
break
;
break
;
...
@@ -223,7 +222,9 @@ static int rk_tsadcv2_code_to_temp(u32 code)
...
@@ -223,7 +222,9 @@ static int rk_tsadcv2_code_to_temp(u32 code)
num
=
v2_code_table
[
mid
].
temp
-
v2_code_table
[
mid
-
1
].
temp
;
num
=
v2_code_table
[
mid
].
temp
-
v2_code_table
[
mid
-
1
].
temp
;
num
*=
v2_code_table
[
mid
-
1
].
code
-
code
;
num
*=
v2_code_table
[
mid
-
1
].
code
-
code
;
denom
=
v2_code_table
[
mid
-
1
].
code
-
v2_code_table
[
mid
].
code
;
denom
=
v2_code_table
[
mid
-
1
].
code
-
v2_code_table
[
mid
].
code
;
return
v2_code_table
[
mid
-
1
].
temp
+
(
num
/
denom
);
*
temp
=
v2_code_table
[
mid
-
1
].
temp
+
(
num
/
denom
);
return
0
;
}
}
/**
/**
...
@@ -241,10 +242,10 @@ static void rk_tsadcv2_initialize(void __iomem *regs,
...
@@ -241,10 +242,10 @@ static void rk_tsadcv2_initialize(void __iomem *regs,
enum
tshut_polarity
tshut_polarity
)
enum
tshut_polarity
tshut_polarity
)
{
{
if
(
tshut_polarity
==
TSHUT_HIGH_ACTIVE
)
if
(
tshut_polarity
==
TSHUT_HIGH_ACTIVE
)
writel_relaxed
(
0
|
(
TSADCV2_AUTO_TSHUT_POLARITY_HIGH
)
,
writel_relaxed
(
0
U
|
TSADCV2_AUTO_TSHUT_POLARITY_HIGH
,
regs
+
TSADCV2_AUTO_CON
);
regs
+
TSADCV2_AUTO_CON
);
else
else
writel_relaxed
(
0
|
(
TSADCV2_AUTO_TSHUT_POLARITY_LOW
)
,
writel_relaxed
(
0
U
&
~
TSADCV2_AUTO_TSHUT_POLARITY_HIGH
,
regs
+
TSADCV2_AUTO_CON
);
regs
+
TSADCV2_AUTO_CON
);
writel_relaxed
(
TSADCV2_AUTO_PERIOD_TIME
,
regs
+
TSADCV2_AUTO_PERIOD
);
writel_relaxed
(
TSADCV2_AUTO_PERIOD_TIME
,
regs
+
TSADCV2_AUTO_PERIOD
);
...
@@ -261,7 +262,7 @@ static void rk_tsadcv2_irq_ack(void __iomem *regs)
...
@@ -261,7 +262,7 @@ static void rk_tsadcv2_irq_ack(void __iomem *regs)
u32
val
;
u32
val
;
val
=
readl_relaxed
(
regs
+
TSADCV2_INT_PD
);
val
=
readl_relaxed
(
regs
+
TSADCV2_INT_PD
);
writel_relaxed
(
val
&
TSADCV2_INT_PD_CLEAR
,
regs
+
TSADCV2_INT_PD
);
writel_relaxed
(
val
&
TSADCV2_INT_PD_CLEAR
_MASK
,
regs
+
TSADCV2_INT_PD
);
}
}
static
void
rk_tsadcv2_control
(
void
__iomem
*
regs
,
bool
enable
)
static
void
rk_tsadcv2_control
(
void
__iomem
*
regs
,
bool
enable
)
...
@@ -281,14 +282,9 @@ static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, int *temp)
...
@@ -281,14 +282,9 @@ static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, int *temp)
{
{
u32
val
;
u32
val
;
/* the A/D value of the channel last conversion need some time */
val
=
readl_relaxed
(
regs
+
TSADCV2_DATA
(
chn
));
val
=
readl_relaxed
(
regs
+
TSADCV2_DATA
(
chn
));
if
(
val
==
0
)
return
-
EAGAIN
;
*
temp
=
rk_tsadcv2_code_to_temp
(
val
);
return
rk_tsadcv2_code_to_temp
(
val
,
temp
);
return
0
;
}
}
static
void
rk_tsadcv2_tshut_temp
(
int
chn
,
void
__iomem
*
regs
,
long
temp
)
static
void
rk_tsadcv2_tshut_temp
(
int
chn
,
void
__iomem
*
regs
,
long
temp
)
...
@@ -642,6 +638,8 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
...
@@ -642,6 +638,8 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
clk_disable
(
thermal
->
pclk
);
clk_disable
(
thermal
->
pclk
);
clk_disable
(
thermal
->
clk
);
clk_disable
(
thermal
->
clk
);
pinctrl_pm_select_sleep_state
(
dev
);
return
0
;
return
0
;
}
}
...
@@ -678,6 +676,8 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
...
@@ -678,6 +676,8 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
thermal
->
sensors
);
i
++
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
thermal
->
sensors
);
i
++
)
rockchip_thermal_toggle_sensor
(
&
thermal
->
sensors
[
i
],
true
);
rockchip_thermal_toggle_sensor
(
&
thermal
->
sensors
[
i
],
true
);
pinctrl_pm_select_default_state
(
dev
);
return
0
;
return
0
;
}
}
...
...
drivers/thermal/samsung/exynos_tmu.c
View file @
7c5b2759
...
@@ -548,7 +548,7 @@ static int exynos5433_tmu_initialize(struct platform_device *pdev)
...
@@ -548,7 +548,7 @@ static int exynos5433_tmu_initialize(struct platform_device *pdev)
default:
default:
pdata
->
cal_type
=
TYPE_ONE_POINT_TRIMMING
;
pdata
->
cal_type
=
TYPE_ONE_POINT_TRIMMING
;
break
;
break
;
}
;
}
dev_info
(
&
pdev
->
dev
,
"Calibration type is %d-point calibration
\n
"
,
dev_info
(
&
pdev
->
dev
,
"Calibration type is %d-point calibration
\n
"
,
cal_type
?
2
:
1
);
cal_type
?
2
:
1
);
...
@@ -608,7 +608,7 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev)
...
@@ -608,7 +608,7 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev)
{
{
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
unsigned
int
trim_info
=
0
,
con
,
rising_threshold
;
unsigned
int
trim_info
=
0
,
con
,
rising_threshold
;
int
ret
=
0
,
threshold_code
;
int
threshold_code
;
int
crit_temp
=
0
;
int
crit_temp
=
0
;
/*
/*
...
@@ -651,7 +651,8 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev)
...
@@ -651,7 +651,8 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev)
/* Clear the PMIN in the common TMU register */
/* Clear the PMIN in the common TMU register */
if
(
!
data
->
id
)
if
(
!
data
->
id
)
writel
(
0
,
data
->
base_second
+
EXYNOS5440_TMU_PMIN
);
writel
(
0
,
data
->
base_second
+
EXYNOS5440_TMU_PMIN
);
return
ret
;
return
0
;
}
}
static
int
exynos7_tmu_initialize
(
struct
platform_device
*
pdev
)
static
int
exynos7_tmu_initialize
(
struct
platform_device
*
pdev
)
...
@@ -1168,27 +1169,10 @@ static int exynos_map_dt_data(struct platform_device *pdev)
...
@@ -1168,27 +1169,10 @@ static int exynos_map_dt_data(struct platform_device *pdev)
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
struct
exynos_tmu_platform_data
*
pdata
;
struct
exynos_tmu_platform_data
*
pdata
;
struct
resource
res
;
struct
resource
res
;
int
ret
;
if
(
!
data
||
!
pdev
->
dev
.
of_node
)
if
(
!
data
||
!
pdev
->
dev
.
of_node
)
return
-
ENODEV
;
return
-
ENODEV
;
/*
* Try enabling the regulator if found
* TODO: Add regulator as an SOC feature, so that regulator enable
* is a compulsory call.
*/
data
->
regulator
=
devm_regulator_get
(
&
pdev
->
dev
,
"vtmu"
);
if
(
!
IS_ERR
(
data
->
regulator
))
{
ret
=
regulator_enable
(
data
->
regulator
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to enable vtmu
\n
"
);
return
ret
;
}
}
else
{
dev_info
(
&
pdev
->
dev
,
"Regulator node (vtmu) not found
\n
"
);
}
data
->
id
=
of_alias_get_id
(
pdev
->
dev
.
of_node
,
"tmuctrl"
);
data
->
id
=
of_alias_get_id
(
pdev
->
dev
.
of_node
,
"tmuctrl"
);
if
(
data
->
id
<
0
)
if
(
data
->
id
<
0
)
data
->
id
=
0
;
data
->
id
=
0
;
...
@@ -1306,12 +1290,22 @@ static int exynos_tmu_probe(struct platform_device *pdev)
...
@@ -1306,12 +1290,22 @@ static int exynos_tmu_probe(struct platform_device *pdev)
platform_set_drvdata
(
pdev
,
data
);
platform_set_drvdata
(
pdev
,
data
);
mutex_init
(
&
data
->
lock
);
mutex_init
(
&
data
->
lock
);
data
->
tzd
=
thermal_zone_of_sensor_register
(
&
pdev
->
dev
,
0
,
data
,
/*
&
exynos_sensor_ops
);
* Try enabling the regulator if found
if
(
IS_ERR
(
data
->
tzd
))
{
* TODO: Add regulator as an SOC feature, so that regulator enable
pr_err
(
"thermal: tz: %p ERROR
\n
"
,
data
->
tzd
);
* is a compulsory call.
return
PTR_ERR
(
data
->
tzd
);
*/
data
->
regulator
=
devm_regulator_get
(
&
pdev
->
dev
,
"vtmu"
);
if
(
!
IS_ERR
(
data
->
regulator
))
{
ret
=
regulator_enable
(
data
->
regulator
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to enable vtmu
\n
"
);
return
ret
;
}
}
else
{
dev_info
(
&
pdev
->
dev
,
"Regulator node (vtmu) not found
\n
"
);
}
}
ret
=
exynos_map_dt_data
(
pdev
);
ret
=
exynos_map_dt_data
(
pdev
);
if
(
ret
)
if
(
ret
)
goto
err_sensor
;
goto
err_sensor
;
...
@@ -1363,23 +1357,38 @@ static int exynos_tmu_probe(struct platform_device *pdev)
...
@@ -1363,23 +1357,38 @@ static int exynos_tmu_probe(struct platform_device *pdev)
break
;
break
;
default:
default:
break
;
break
;
};
}
/*
* data->tzd must be registered before calling exynos_tmu_initialize(),
* requesting irq and calling exynos_tmu_control().
*/
data
->
tzd
=
thermal_zone_of_sensor_register
(
&
pdev
->
dev
,
0
,
data
,
&
exynos_sensor_ops
);
if
(
IS_ERR
(
data
->
tzd
))
{
ret
=
PTR_ERR
(
data
->
tzd
);
dev_err
(
&
pdev
->
dev
,
"Failed to register sensor: %d
\n
"
,
ret
);
goto
err_sclk
;
}
ret
=
exynos_tmu_initialize
(
pdev
);
ret
=
exynos_tmu_initialize
(
pdev
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to initialize TMU
\n
"
);
dev_err
(
&
pdev
->
dev
,
"Failed to initialize TMU
\n
"
);
goto
err_
sclk
;
goto
err_
thermal
;
}
}
ret
=
devm_request_irq
(
&
pdev
->
dev
,
data
->
irq
,
exynos_tmu_irq
,
ret
=
devm_request_irq
(
&
pdev
->
dev
,
data
->
irq
,
exynos_tmu_irq
,
IRQF_TRIGGER_RISING
|
IRQF_SHARED
,
dev_name
(
&
pdev
->
dev
),
data
);
IRQF_TRIGGER_RISING
|
IRQF_SHARED
,
dev_name
(
&
pdev
->
dev
),
data
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to request irq: %d
\n
"
,
data
->
irq
);
dev_err
(
&
pdev
->
dev
,
"Failed to request irq: %d
\n
"
,
data
->
irq
);
goto
err_
sclk
;
goto
err_
thermal
;
}
}
exynos_tmu_control
(
pdev
,
true
);
exynos_tmu_control
(
pdev
,
true
);
return
0
;
return
0
;
err_thermal:
thermal_zone_of_sensor_unregister
(
&
pdev
->
dev
,
data
->
tzd
);
err_sclk:
err_sclk:
clk_disable_unprepare
(
data
->
sclk
);
clk_disable_unprepare
(
data
->
sclk
);
err_clk:
err_clk:
...
@@ -1388,9 +1397,8 @@ static int exynos_tmu_probe(struct platform_device *pdev)
...
@@ -1388,9 +1397,8 @@ static int exynos_tmu_probe(struct platform_device *pdev)
if
(
!
IS_ERR
(
data
->
clk_sec
))
if
(
!
IS_ERR
(
data
->
clk_sec
))
clk_unprepare
(
data
->
clk_sec
);
clk_unprepare
(
data
->
clk_sec
);
err_sensor:
err_sensor:
if
(
!
IS_ERR
_OR_NULL
(
data
->
regulator
))
if
(
!
IS_ERR
(
data
->
regulator
))
regulator_disable
(
data
->
regulator
);
regulator_disable
(
data
->
regulator
);
thermal_zone_of_sensor_unregister
(
&
pdev
->
dev
,
data
->
tzd
);
return
ret
;
return
ret
;
}
}
...
...
drivers/thermal/ti-soc-thermal/Kconfig
View file @
7c5b2759
...
@@ -19,6 +19,21 @@ config TI_THERMAL
...
@@ -19,6 +19,21 @@ config TI_THERMAL
This includes trip points definitions, extrapolation rules and
This includes trip points definitions, extrapolation rules and
CPU cooling device bindings.
CPU cooling device bindings.
config OMAP3_THERMAL
bool "Texas Instruments OMAP3 thermal support"
depends on TI_SOC_THERMAL
depends on ARCH_OMAP3 || COMPILE_TEST
help
If you say yes here you get thermal support for the Texas Instruments
OMAP3 SoC family. The current chips supported are:
- OMAP3430
OMAP3 chips normally don't need thermal management, and sensors in
this generation are not accurate, nor they are very close to
the important hotspots.
Say 'N' here.
config OMAP4_THERMAL
config OMAP4_THERMAL
bool "Texas Instruments OMAP4 thermal support"
bool "Texas Instruments OMAP4 thermal support"
depends on TI_SOC_THERMAL
depends on TI_SOC_THERMAL
...
...
drivers/thermal/ti-soc-thermal/Makefile
View file @
7c5b2759
...
@@ -2,5 +2,6 @@ obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal.o
...
@@ -2,5 +2,6 @@ obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal.o
ti-soc-thermal-y
:=
ti-bandgap.o
ti-soc-thermal-y
:=
ti-bandgap.o
ti-soc-thermal-$(CONFIG_TI_THERMAL)
+=
ti-thermal-common.o
ti-soc-thermal-$(CONFIG_TI_THERMAL)
+=
ti-thermal-common.o
ti-soc-thermal-$(CONFIG_DRA752_THERMAL)
+=
dra752-thermal-data.o
ti-soc-thermal-$(CONFIG_DRA752_THERMAL)
+=
dra752-thermal-data.o
ti-soc-thermal-$(CONFIG_OMAP3_THERMAL)
+=
omap3-thermal-data.o
ti-soc-thermal-$(CONFIG_OMAP4_THERMAL)
+=
omap4-thermal-data.o
ti-soc-thermal-$(CONFIG_OMAP4_THERMAL)
+=
omap4-thermal-data.o
ti-soc-thermal-$(CONFIG_OMAP5_THERMAL)
+=
omap5-thermal-data.o
ti-soc-thermal-$(CONFIG_OMAP5_THERMAL)
+=
omap5-thermal-data.o
drivers/thermal/ti-soc-thermal/omap3-thermal-data.c
0 → 100644
View file @
7c5b2759
/*
* OMAP3 thermal driver.
*
* Copyright (C) 2011-2012 Texas Instruments Inc.
* Copyright (C) 2014 Pavel Machek <pavel@ucw.cz>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
* Note
* http://www.ti.com/lit/er/sprz278f/sprz278f.pdf "Advisory
* 3.1.1.186 MMC OCP Clock Not Gated When Thermal Sensor Is Used"
*
* Also TI says:
* Just be careful when you try to make thermal policy like decisions
* based on this sensor. Placement of the sensor w.r.t the actual logic
* generating heat has to be a factor as well. If you are just looking
* for an approximation temperature (thermometerish kind), you might be
* ok with this. I am not sure we'd find any TI data around this.. just a
* heads up.
*/
#include "ti-thermal.h"
#include "ti-bandgap.h"
/*
* OMAP34XX has one instance of thermal sensor for MPU
* need to describe the individual bit fields
*/
static
struct
temp_sensor_registers
omap34xx_mpu_temp_sensor_registers
=
{
.
temp_sensor_ctrl
=
0
,
.
bgap_soc_mask
=
BIT
(
8
),
.
bgap_eocz_mask
=
BIT
(
7
),
.
bgap_dtemp_mask
=
0x7f
,
.
bgap_mode_ctrl
=
0
,
.
mode_ctrl_mask
=
BIT
(
9
),
};
/* Thresholds and limits for OMAP34XX MPU temperature sensor */
static
struct
temp_sensor_data
omap34xx_mpu_temp_sensor_data
=
{
.
min_freq
=
32768
,
.
max_freq
=
32768
,
.
max_temp
=
125000
,
.
min_temp
=
-
40000
,
.
hyst_val
=
5000
,
};
/*
* Temperature values in milli degree celsius
*/
static
const
int
omap34xx_adc_to_temp
[
128
]
=
{
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
39000
,
-
38000
,
-
36000
,
-
34000
,
-
32000
,
-
31000
,
-
29000
,
-
28000
,
-
26000
,
-
25000
,
-
24000
,
-
22000
,
-
21000
,
-
19000
,
-
18000
,
-
17000
,
-
15000
,
-
14000
,
-
12000
,
-
11000
,
-
9000
,
-
8000
,
-
7000
,
-
5000
,
-
4000
,
-
2000
,
-
1000
,
0000
,
1000
,
3000
,
4000
,
5000
,
7000
,
8000
,
10000
,
11000
,
13000
,
14000
,
15000
,
17000
,
18000
,
20000
,
21000
,
22000
,
24000
,
25000
,
27000
,
28000
,
30000
,
31000
,
32000
,
34000
,
35000
,
37000
,
38000
,
39000
,
41000
,
42000
,
44000
,
45000
,
47000
,
48000
,
49000
,
51000
,
52000
,
53000
,
55000
,
56000
,
58000
,
59000
,
60000
,
62000
,
63000
,
65000
,
66000
,
67000
,
69000
,
70000
,
72000
,
73000
,
74000
,
76000
,
77000
,
79000
,
80000
,
81000
,
83000
,
84000
,
85000
,
87000
,
88000
,
89000
,
91000
,
92000
,
94000
,
95000
,
96000
,
98000
,
99000
,
100000
,
102000
,
103000
,
105000
,
106000
,
107000
,
109000
,
110000
,
111000
,
113000
,
114000
,
116000
,
117000
,
118000
,
120000
,
121000
,
122000
,
124000
,
124000
,
125000
,
125000
,
125000
,
125000
,
125000
};
/* OMAP34XX data */
const
struct
ti_bandgap_data
omap34xx_data
=
{
.
features
=
TI_BANDGAP_FEATURE_CLK_CTRL
|
TI_BANDGAP_FEATURE_UNRELIABLE
,
.
fclock_name
=
"ts_fck"
,
.
div_ck_name
=
"ts_fck"
,
.
conv_table
=
omap34xx_adc_to_temp
,
.
adc_start_val
=
0
,
.
adc_end_val
=
127
,
.
expose_sensor
=
ti_thermal_expose_sensor
,
.
remove_sensor
=
ti_thermal_remove_sensor
,
.
sensors
=
{
{
.
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
,
.
unregister_cooling
=
NULL
,
},
},
.
sensor_count
=
1
,
};
/*
* OMAP36XX has one instance of thermal sensor for MPU
* need to describe the individual bit fields
*/
static
struct
temp_sensor_registers
omap36xx_mpu_temp_sensor_registers
=
{
.
temp_sensor_ctrl
=
0
,
.
bgap_soc_mask
=
BIT
(
9
),
.
bgap_eocz_mask
=
BIT
(
8
),
.
bgap_dtemp_mask
=
0xFF
,
.
bgap_mode_ctrl
=
0
,
.
mode_ctrl_mask
=
BIT
(
10
),
};
/* Thresholds and limits for OMAP36XX MPU temperature sensor */
static
struct
temp_sensor_data
omap36xx_mpu_temp_sensor_data
=
{
.
min_freq
=
32768
,
.
max_freq
=
32768
,
.
max_temp
=
125000
,
.
min_temp
=
-
40000
,
.
hyst_val
=
5000
,
};
/*
* Temperature values in milli degree celsius
*/
static
const
int
omap36xx_adc_to_temp
[
128
]
=
{
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
40000
,
-
38000
,
-
35000
,
-
34000
,
-
32000
,
-
30000
,
-
28000
,
-
26000
,
-
24000
,
-
22000
,
-
20000
,
-
18500
,
-
17000
,
-
15000
,
-
13500
,
-
12000
,
-
10000
,
-
8000
,
-
6500
,
-
5000
,
-
3500
,
-
1500
,
0
,
2000
,
3500
,
5000
,
6500
,
8500
,
10000
,
12000
,
13500
,
15000
,
17000
,
19000
,
21000
,
23000
,
25000
,
27000
,
28500
,
30000
,
32000
,
33500
,
35000
,
37000
,
38500
,
40000
,
42000
,
43500
,
45000
,
47000
,
48500
,
50000
,
52000
,
53500
,
55000
,
57000
,
58500
,
60000
,
62000
,
64000
,
66000
,
68000
,
70000
,
71500
,
73500
,
75000
,
77000
,
78500
,
80000
,
82000
,
83500
,
85000
,
87000
,
88500
,
90000
,
92000
,
93500
,
95000
,
97000
,
98500
,
100000
,
102000
,
103500
,
105000
,
107000
,
109000
,
111000
,
113000
,
115000
,
117000
,
118500
,
120000
,
122000
,
123500
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
,
125000
};
/* OMAP36XX data */
const
struct
ti_bandgap_data
omap36xx_data
=
{
.
features
=
TI_BANDGAP_FEATURE_CLK_CTRL
|
TI_BANDGAP_FEATURE_UNRELIABLE
,
.
fclock_name
=
"ts_fck"
,
.
div_ck_name
=
"ts_fck"
,
.
conv_table
=
omap36xx_adc_to_temp
,
.
adc_start_val
=
0
,
.
adc_end_val
=
127
,
.
expose_sensor
=
ti_thermal_expose_sensor
,
.
remove_sensor
=
ti_thermal_remove_sensor
,
.
sensors
=
{
{
.
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
,
.
unregister_cooling
=
NULL
,
},
},
.
sensor_count
=
1
,
};
drivers/thermal/ti-soc-thermal/ti-bandgap.c
View file @
7c5b2759
...
@@ -1274,6 +1274,10 @@ int ti_bandgap_probe(struct platform_device *pdev)
...
@@ -1274,6 +1274,10 @@ int ti_bandgap_probe(struct platform_device *pdev)
}
}
bgp
->
dev
=
&
pdev
->
dev
;
bgp
->
dev
=
&
pdev
->
dev
;
if
(
TI_BANDGAP_HAS
(
bgp
,
UNRELIABLE
))
dev_warn
(
&
pdev
->
dev
,
"This OMAP thermal sensor is unreliable. You've been warned
\n
"
);
if
(
TI_BANDGAP_HAS
(
bgp
,
TSHUT
))
{
if
(
TI_BANDGAP_HAS
(
bgp
,
TSHUT
))
{
ret
=
ti_bandgap_tshut_init
(
bgp
,
pdev
);
ret
=
ti_bandgap_tshut_init
(
bgp
,
pdev
);
if
(
ret
)
{
if
(
ret
)
{
...
@@ -1579,6 +1583,16 @@ static SIMPLE_DEV_PM_OPS(ti_bandgap_dev_pm_ops, ti_bandgap_suspend,
...
@@ -1579,6 +1583,16 @@ static SIMPLE_DEV_PM_OPS(ti_bandgap_dev_pm_ops, ti_bandgap_suspend,
#endif
#endif
static
const
struct
of_device_id
of_ti_bandgap_match
[]
=
{
static
const
struct
of_device_id
of_ti_bandgap_match
[]
=
{
#ifdef CONFIG_OMAP3_THERMAL
{
.
compatible
=
"ti,omap34xx-bandgap"
,
.
data
=
(
void
*
)
&
omap34xx_data
,
},
{
.
compatible
=
"ti,omap36xx-bandgap"
,
.
data
=
(
void
*
)
&
omap36xx_data
,
},
#endif
#ifdef CONFIG_OMAP4_THERMAL
#ifdef CONFIG_OMAP4_THERMAL
{
{
.
compatible
=
"ti,omap4430-bandgap"
,
.
compatible
=
"ti,omap4430-bandgap"
,
...
...
drivers/thermal/ti-soc-thermal/ti-bandgap.h
View file @
7c5b2759
...
@@ -322,6 +322,8 @@ struct ti_temp_sensor {
...
@@ -322,6 +322,8 @@ struct ti_temp_sensor {
* has Errata 814
* has Errata 814
* TI_BANDGAP_FEATURE_ERRATA_813 - used to workaorund when the bandgap device
* TI_BANDGAP_FEATURE_ERRATA_813 - used to workaorund when the bandgap device
* has Errata 813
* has Errata 813
* TI_BANDGAP_FEATURE_UNRELIABLE - used when the sensor readings are too
* inaccurate.
* TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a
* TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a
* specific feature (above) or not. Return non-zero, if yes.
* specific feature (above) or not. Return non-zero, if yes.
*/
*/
...
@@ -337,6 +339,7 @@ struct ti_temp_sensor {
...
@@ -337,6 +339,7 @@ struct ti_temp_sensor {
#define TI_BANDGAP_FEATURE_HISTORY_BUFFER BIT(9)
#define TI_BANDGAP_FEATURE_HISTORY_BUFFER BIT(9)
#define TI_BANDGAP_FEATURE_ERRATA_814 BIT(10)
#define TI_BANDGAP_FEATURE_ERRATA_814 BIT(10)
#define TI_BANDGAP_FEATURE_ERRATA_813 BIT(11)
#define TI_BANDGAP_FEATURE_ERRATA_813 BIT(11)
#define TI_BANDGAP_FEATURE_UNRELIABLE BIT(12)
#define TI_BANDGAP_HAS(b, f) \
#define TI_BANDGAP_HAS(b, f) \
((b)->conf->features & TI_BANDGAP_FEATURE_ ## f)
((b)->conf->features & TI_BANDGAP_FEATURE_ ## f)
...
@@ -390,6 +393,14 @@ int ti_bandgap_set_sensor_data(struct ti_bandgap *bgp, int id, void *data);
...
@@ -390,6 +393,14 @@ int ti_bandgap_set_sensor_data(struct ti_bandgap *bgp, int id, void *data);
void
*
ti_bandgap_get_sensor_data
(
struct
ti_bandgap
*
bgp
,
int
id
);
void
*
ti_bandgap_get_sensor_data
(
struct
ti_bandgap
*
bgp
,
int
id
);
int
ti_bandgap_get_trend
(
struct
ti_bandgap
*
bgp
,
int
id
,
int
*
trend
);
int
ti_bandgap_get_trend
(
struct
ti_bandgap
*
bgp
,
int
id
,
int
*
trend
);
#ifdef CONFIG_OMAP3_THERMAL
extern
const
struct
ti_bandgap_data
omap34xx_data
;
extern
const
struct
ti_bandgap_data
omap36xx_data
;
#else
#define omap34xx_data NULL
#define omap36xx_data NULL
#endif
#ifdef CONFIG_OMAP4_THERMAL
#ifdef CONFIG_OMAP4_THERMAL
extern
const
struct
ti_bandgap_data
omap4430_data
;
extern
const
struct
ti_bandgap_data
omap4430_data
;
extern
const
struct
ti_bandgap_data
omap4460_data
;
extern
const
struct
ti_bandgap_data
omap4460_data
;
...
...
include/linux/devfreq_cooling.h
0 → 100644
View file @
7c5b2759
/*
* devfreq_cooling: Thermal cooling device implementation for devices using
* devfreq
*
* Copyright (C) 2014-2015 ARM Limited
*
* 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.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __DEVFREQ_COOLING_H__
#define __DEVFREQ_COOLING_H__
#include <linux/devfreq.h>
#include <linux/thermal.h>
#ifdef CONFIG_DEVFREQ_THERMAL
/**
* struct devfreq_cooling_power - Devfreq cooling power ops
* @get_static_power: Take voltage, in mV, and return the static power
* in mW. If NULL, the static power is assumed
* to be 0.
* @get_dynamic_power: Take voltage, in mV, and frequency, in HZ, and
* return the dynamic power draw in mW. If NULL,
* a simple power model is used.
* @dyn_power_coeff: Coefficient for the simple dynamic power model in
* mW/(MHz mV mV).
* If get_dynamic_power() is NULL, then the
* dynamic power is calculated as
* @dyn_power_coeff * frequency * voltage^2
*/
struct
devfreq_cooling_power
{
unsigned
long
(
*
get_static_power
)(
unsigned
long
voltage
);
unsigned
long
(
*
get_dynamic_power
)(
unsigned
long
freq
,
unsigned
long
voltage
);
unsigned
long
dyn_power_coeff
;
};
struct
thermal_cooling_device
*
of_devfreq_cooling_register_power
(
struct
device_node
*
np
,
struct
devfreq
*
df
,
struct
devfreq_cooling_power
*
dfc_power
);
struct
thermal_cooling_device
*
of_devfreq_cooling_register
(
struct
device_node
*
np
,
struct
devfreq
*
df
);
struct
thermal_cooling_device
*
devfreq_cooling_register
(
struct
devfreq
*
df
);
void
devfreq_cooling_unregister
(
struct
thermal_cooling_device
*
dfc
);
#else
/* !CONFIG_DEVFREQ_THERMAL */
struct
thermal_cooling_device
*
of_devfreq_cooling_register_power
(
struct
device_node
*
np
,
struct
devfreq
*
df
,
struct
devfreq_cooling_power
*
dfc_power
)
{
return
ERR_PTR
(
-
EINVAL
);
}
static
inline
struct
thermal_cooling_device
*
of_devfreq_cooling_register
(
struct
device_node
*
np
,
struct
devfreq
*
df
)
{
return
ERR_PTR
(
-
EINVAL
);
}
static
inline
struct
thermal_cooling_device
*
devfreq_cooling_register
(
struct
devfreq
*
df
)
{
return
ERR_PTR
(
-
EINVAL
);
}
static
inline
void
devfreq_cooling_unregister
(
struct
thermal_cooling_device
*
dfc
)
{
}
#endif
/* CONFIG_DEVFREQ_THERMAL */
#endif
/* __DEVFREQ_COOLING_H__ */
include/trace/events/thermal.h
View file @
7c5b2759
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
#if !defined(_TRACE_THERMAL_H) || defined(TRACE_HEADER_MULTI_READ)
#if !defined(_TRACE_THERMAL_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_THERMAL_H
#define _TRACE_THERMAL_H
#include <linux/devfreq.h>
#include <linux/thermal.h>
#include <linux/thermal.h>
#include <linux/tracepoint.h>
#include <linux/tracepoint.h>
...
@@ -135,6 +136,58 @@ TRACE_EVENT(thermal_power_cpu_limit,
...
@@ -135,6 +136,58 @@ TRACE_EVENT(thermal_power_cpu_limit,
__entry
->
power
)
__entry
->
power
)
);
);
TRACE_EVENT
(
thermal_power_devfreq_get_power
,
TP_PROTO
(
struct
thermal_cooling_device
*
cdev
,
struct
devfreq_dev_status
*
status
,
unsigned
long
freq
,
u32
dynamic_power
,
u32
static_power
),
TP_ARGS
(
cdev
,
status
,
freq
,
dynamic_power
,
static_power
),
TP_STRUCT__entry
(
__string
(
type
,
cdev
->
type
)
__field
(
unsigned
long
,
freq
)
__field
(
u32
,
load
)
__field
(
u32
,
dynamic_power
)
__field
(
u32
,
static_power
)
),
TP_fast_assign
(
__assign_str
(
type
,
cdev
->
type
);
__entry
->
freq
=
freq
;
__entry
->
load
=
(
100
*
status
->
busy_time
)
/
status
->
total_time
;
__entry
->
dynamic_power
=
dynamic_power
;
__entry
->
static_power
=
static_power
;
),
TP_printk
(
"type=%s freq=%lu load=%u dynamic_power=%u static_power=%u"
,
__get_str
(
type
),
__entry
->
freq
,
__entry
->
load
,
__entry
->
dynamic_power
,
__entry
->
static_power
)
);
TRACE_EVENT
(
thermal_power_devfreq_limit
,
TP_PROTO
(
struct
thermal_cooling_device
*
cdev
,
unsigned
long
freq
,
unsigned
long
cdev_state
,
u32
power
),
TP_ARGS
(
cdev
,
freq
,
cdev_state
,
power
),
TP_STRUCT__entry
(
__string
(
type
,
cdev
->
type
)
__field
(
unsigned
int
,
freq
)
__field
(
unsigned
long
,
cdev_state
)
__field
(
u32
,
power
)
),
TP_fast_assign
(
__assign_str
(
type
,
cdev
->
type
);
__entry
->
freq
=
freq
;
__entry
->
cdev_state
=
cdev_state
;
__entry
->
power
=
power
;
),
TP_printk
(
"type=%s freq=%u cdev_state=%lu power=%u"
,
__get_str
(
type
),
__entry
->
freq
,
__entry
->
cdev_state
,
__entry
->
power
)
);
#endif
/* _TRACE_THERMAL_H */
#endif
/* _TRACE_THERMAL_H */
/* This part must be outside protection */
/* This part must be outside protection */
...
...
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