Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
5d72ed35
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
5d72ed35
编写于
7月 05, 2017
作者:
Z
Zhang Rui
浏览文件
操作
浏览文件
下载
差异文件
Merge branches 'thermal-core', 'thermal-intel' and 'thermal-soc' into next
上级
0d76d6e1
4ca0e75e
467aebee
变更
15
显示空白变更内容
内联
并排
Showing
15 changed file
with
338 addition
and
416 deletion
+338
-416
drivers/cpufreq/arm_big_little.c
drivers/cpufreq/arm_big_little.c
+1
-1
drivers/cpufreq/cpufreq-dt.c
drivers/cpufreq/cpufreq-dt.c
+1
-1
drivers/cpufreq/cpufreq_stats.c
drivers/cpufreq/cpufreq_stats.c
+4
-9
drivers/cpufreq/dbx500-cpufreq.c
drivers/cpufreq/dbx500-cpufreq.c
+1
-1
drivers/cpufreq/mt8173-cpufreq.c
drivers/cpufreq/mt8173-cpufreq.c
+1
-3
drivers/cpufreq/qoriq-cpufreq.c
drivers/cpufreq/qoriq-cpufreq.c
+1
-2
drivers/thermal/broadcom/bcm2835_thermal.c
drivers/thermal/broadcom/bcm2835_thermal.c
+0
-1
drivers/thermal/cpu_cooling.c
drivers/thermal/cpu_cooling.c
+248
-361
drivers/thermal/hisi_thermal.c
drivers/thermal/hisi_thermal.c
+4
-1
drivers/thermal/imx_thermal.c
drivers/thermal/imx_thermal.c
+21
-6
drivers/thermal/int340x_thermal/acpi_thermal_rel.c
drivers/thermal/int340x_thermal/acpi_thermal_rel.c
+3
-3
drivers/thermal/int340x_thermal/int3403_thermal.c
drivers/thermal/int340x_thermal/int3403_thermal.c
+10
-2
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+15
-7
include/linux/cpu_cooling.h
include/linux/cpu_cooling.h
+14
-18
include/linux/cpufreq.h
include/linux/cpufreq.h
+14
-0
未找到文件。
drivers/cpufreq/arm_big_little.c
浏览文件 @
5d72ed35
...
@@ -540,7 +540,7 @@ static void bL_cpufreq_ready(struct cpufreq_policy *policy)
...
@@ -540,7 +540,7 @@ static void bL_cpufreq_ready(struct cpufreq_policy *policy)
&
power_coefficient
);
&
power_coefficient
);
cdev
[
cur_cluster
]
=
of_cpufreq_power_cooling_register
(
np
,
cdev
[
cur_cluster
]
=
of_cpufreq_power_cooling_register
(
np
,
policy
->
related_cpus
,
power_coefficient
,
NULL
);
policy
,
power_coefficient
,
NULL
);
if
(
IS_ERR
(
cdev
[
cur_cluster
]))
{
if
(
IS_ERR
(
cdev
[
cur_cluster
]))
{
dev_err
(
cpu_dev
,
dev_err
(
cpu_dev
,
"running cpufreq without cooling device: %ld
\n
"
,
"running cpufreq without cooling device: %ld
\n
"
,
...
...
drivers/cpufreq/cpufreq-dt.c
浏览文件 @
5d72ed35
...
@@ -326,7 +326,7 @@ static void cpufreq_ready(struct cpufreq_policy *policy)
...
@@ -326,7 +326,7 @@ static void cpufreq_ready(struct cpufreq_policy *policy)
&
power_coefficient
);
&
power_coefficient
);
priv
->
cdev
=
of_cpufreq_power_cooling_register
(
np
,
priv
->
cdev
=
of_cpufreq_power_cooling_register
(
np
,
policy
->
related_cpus
,
power_coefficient
,
NULL
);
policy
,
power_coefficient
,
NULL
);
if
(
IS_ERR
(
priv
->
cdev
))
{
if
(
IS_ERR
(
priv
->
cdev
))
{
dev_err
(
priv
->
cpu_dev
,
dev_err
(
priv
->
cpu_dev
,
"running cpufreq without cooling device: %ld
\n
"
,
"running cpufreq without cooling device: %ld
\n
"
,
...
...
drivers/cpufreq/cpufreq_stats.c
浏览文件 @
5d72ed35
...
@@ -170,11 +170,10 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
...
@@ -170,11 +170,10 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
unsigned
int
i
=
0
,
count
=
0
,
ret
=
-
ENOMEM
;
unsigned
int
i
=
0
,
count
=
0
,
ret
=
-
ENOMEM
;
struct
cpufreq_stats
*
stats
;
struct
cpufreq_stats
*
stats
;
unsigned
int
alloc_size
;
unsigned
int
alloc_size
;
struct
cpufreq_frequency_table
*
pos
,
*
table
;
struct
cpufreq_frequency_table
*
pos
;
/* We need cpufreq table for creating stats table */
count
=
cpufreq_table_count_valid_entries
(
policy
);
table
=
policy
->
freq_table
;
if
(
!
count
)
if
(
unlikely
(
!
table
))
return
;
return
;
/* stats already initialized */
/* stats already initialized */
...
@@ -185,10 +184,6 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
...
@@ -185,10 +184,6 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
if
(
!
stats
)
if
(
!
stats
)
return
;
return
;
/* Find total allocation size */
cpufreq_for_each_valid_entry
(
pos
,
table
)
count
++
;
alloc_size
=
count
*
sizeof
(
int
)
+
count
*
sizeof
(
u64
);
alloc_size
=
count
*
sizeof
(
int
)
+
count
*
sizeof
(
u64
);
alloc_size
+=
count
*
count
*
sizeof
(
int
);
alloc_size
+=
count
*
count
*
sizeof
(
int
);
...
@@ -205,7 +200,7 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
...
@@ -205,7 +200,7 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
stats
->
max_state
=
count
;
stats
->
max_state
=
count
;
/* Find valid-unique entries */
/* Find valid-unique entries */
cpufreq_for_each_valid_entry
(
pos
,
table
)
cpufreq_for_each_valid_entry
(
pos
,
policy
->
freq_
table
)
if
(
freq_table_get_index
(
stats
,
pos
->
frequency
)
==
-
1
)
if
(
freq_table_get_index
(
stats
,
pos
->
frequency
)
==
-
1
)
stats
->
freq_table
[
i
++
]
=
pos
->
frequency
;
stats
->
freq_table
[
i
++
]
=
pos
->
frequency
;
...
...
drivers/cpufreq/dbx500-cpufreq.c
浏览文件 @
5d72ed35
...
@@ -43,7 +43,7 @@ static int dbx500_cpufreq_exit(struct cpufreq_policy *policy)
...
@@ -43,7 +43,7 @@ static int dbx500_cpufreq_exit(struct cpufreq_policy *policy)
static
void
dbx500_cpufreq_ready
(
struct
cpufreq_policy
*
policy
)
static
void
dbx500_cpufreq_ready
(
struct
cpufreq_policy
*
policy
)
{
{
cdev
=
cpufreq_cooling_register
(
policy
->
cpus
);
cdev
=
cpufreq_cooling_register
(
policy
);
if
(
IS_ERR
(
cdev
))
if
(
IS_ERR
(
cdev
))
pr_err
(
"Failed to register cooling device %ld
\n
"
,
PTR_ERR
(
cdev
));
pr_err
(
"Failed to register cooling device %ld
\n
"
,
PTR_ERR
(
cdev
));
else
else
...
...
drivers/cpufreq/mt8173-cpufreq.c
浏览文件 @
5d72ed35
...
@@ -320,9 +320,7 @@ static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
...
@@ -320,9 +320,7 @@ static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
of_property_read_u32
(
np
,
DYNAMIC_POWER
,
&
capacitance
);
of_property_read_u32
(
np
,
DYNAMIC_POWER
,
&
capacitance
);
info
->
cdev
=
of_cpufreq_power_cooling_register
(
np
,
info
->
cdev
=
of_cpufreq_power_cooling_register
(
np
,
policy
->
related_cpus
,
policy
,
capacitance
,
NULL
);
capacitance
,
NULL
);
if
(
IS_ERR
(
info
->
cdev
))
{
if
(
IS_ERR
(
info
->
cdev
))
{
dev_err
(
info
->
cpu_dev
,
dev_err
(
info
->
cpu_dev
,
...
...
drivers/cpufreq/qoriq-cpufreq.c
浏览文件 @
5d72ed35
...
@@ -278,8 +278,7 @@ static void qoriq_cpufreq_ready(struct cpufreq_policy *policy)
...
@@ -278,8 +278,7 @@ static void qoriq_cpufreq_ready(struct cpufreq_policy *policy)
struct
device_node
*
np
=
of_get_cpu_node
(
policy
->
cpu
,
NULL
);
struct
device_node
*
np
=
of_get_cpu_node
(
policy
->
cpu
,
NULL
);
if
(
of_find_property
(
np
,
"#cooling-cells"
,
NULL
))
{
if
(
of_find_property
(
np
,
"#cooling-cells"
,
NULL
))
{
cpud
->
cdev
=
of_cpufreq_cooling_register
(
np
,
cpud
->
cdev
=
of_cpufreq_cooling_register
(
np
,
policy
);
policy
->
related_cpus
);
if
(
IS_ERR
(
cpud
->
cdev
)
&&
PTR_ERR
(
cpud
->
cdev
)
!=
-
ENOSYS
)
{
if
(
IS_ERR
(
cpud
->
cdev
)
&&
PTR_ERR
(
cpud
->
cdev
)
!=
-
ENOSYS
)
{
pr_err
(
"cpu%d is not running as cooling device: %ld
\n
"
,
pr_err
(
"cpu%d is not running as cooling device: %ld
\n
"
,
...
...
drivers/thermal/broadcom/bcm2835_thermal.c
浏览文件 @
5d72ed35
...
@@ -245,7 +245,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
...
@@ -245,7 +245,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
*/
*/
err
=
tz
->
ops
->
get_trip_temp
(
tz
,
0
,
&
trip_temp
);
err
=
tz
->
ops
->
get_trip_temp
(
tz
,
0
,
&
trip_temp
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
err
=
PTR_ERR
(
tz
);
dev_err
(
&
pdev
->
dev
,
dev_err
(
&
pdev
->
dev
,
"Not able to read trip_temp: %d
\n
"
,
"Not able to read trip_temp: %d
\n
"
,
err
);
err
);
...
...
drivers/thermal/cpu_cooling.c
浏览文件 @
5d72ed35
...
@@ -49,40 +49,45 @@
...
@@ -49,40 +49,45 @@
*/
*/
/**
/**
* struct
power_table - frequency to power conversion
* struct
freq_table - frequency table along with power entries
* @frequency: frequency in KHz
* @frequency: frequency in KHz
* @power: power in mW
* @power: power in mW
*
*
* This structure is built when the cooling device registers and helps
* This structure is built when the cooling device registers and helps
* in translating frequency to power and viceversa.
* in translating frequency to power and vice
versa.
*/
*/
struct
power
_table
{
struct
freq
_table
{
u32
frequency
;
u32
frequency
;
u32
power
;
u32
power
;
};
};
/**
* struct time_in_idle - Idle time stats
* @time: previous reading of the absolute time that this cpu was idle
* @timestamp: wall time of the last invocation of get_cpu_idle_time_us()
*/
struct
time_in_idle
{
u64
time
;
u64
timestamp
;
};
/**
/**
* struct cpufreq_cooling_device - data for cooling device with cpufreq
* struct cpufreq_cooling_device - data for cooling device with cpufreq
* @id: unique integer value corresponding to each cpufreq_cooling_device
* @id: unique integer value corresponding to each cpufreq_cooling_device
* registered.
* registered.
* @cool_dev: thermal_cooling_device pointer to keep track of the
* @last_load: load measured by the latest call to cpufreq_get_requested_power()
* registered cooling device.
* @cpufreq_state: integer value representing the current state of cpufreq
* @cpufreq_state: integer value representing the current state of cpufreq
* cooling devices.
* cooling devices.
* @clipped_freq: integer value representing the absolute value of the clipped
* @clipped_freq: integer value representing the absolute value of the clipped
* frequency.
* frequency.
* @max_level: maximum cooling level. One less than total number of valid
* @max_level: maximum cooling level. One less than total number of valid
* cpufreq frequencies.
* cpufreq frequencies.
* @allowed_cpus: all the cpus involved for this cpufreq_cooling_device.
* @freq_table: Freq table in descending order of frequencies
* @cdev: thermal_cooling_device pointer to keep track of the
* registered cooling device.
* @policy: cpufreq policy.
* @node: list_head to link all cpufreq_cooling_device together.
* @node: list_head to link all cpufreq_cooling_device together.
* @last_load: load measured by the latest call to cpufreq_get_requested_power()
* @idle_time: idle time stats
* @time_in_idle: previous reading of the absolute time that this cpu was idle
* @time_in_idle_timestamp: wall time of the last invocation of
* get_cpu_idle_time_us()
* @dyn_power_table: array of struct power_table for frequency to power
* conversion, sorted in ascending order.
* @dyn_power_table_entries: number of entries in the @dyn_power_table array
* @cpu_dev: the first cpu_device from @allowed_cpus that has OPPs registered
* @plat_get_static_power: callback to calculate the static power
* @plat_get_static_power: callback to calculate the static power
*
*
* This structure is required for keeping information of each registered
* This structure is required for keeping information of each registered
...
@@ -90,80 +95,44 @@ struct power_table {
...
@@ -90,80 +95,44 @@ struct power_table {
*/
*/
struct
cpufreq_cooling_device
{
struct
cpufreq_cooling_device
{
int
id
;
int
id
;
struct
thermal_cooling_device
*
cool_dev
;
u32
last_load
;
unsigned
int
cpufreq_state
;
unsigned
int
cpufreq_state
;
unsigned
int
clipped_freq
;
unsigned
int
clipped_freq
;
unsigned
int
max_level
;
unsigned
int
max_level
;
unsigned
int
*
freq_table
;
/* In descending order */
struct
freq_table
*
freq_table
;
/* In descending order */
struct
cpumask
allowed_cpus
;
struct
thermal_cooling_device
*
cdev
;
struct
cpufreq_policy
*
policy
;
struct
list_head
node
;
struct
list_head
node
;
u32
last_load
;
struct
time_in_idle
*
idle_time
;
u64
*
time_in_idle
;
u64
*
time_in_idle_timestamp
;
struct
power_table
*
dyn_power_table
;
int
dyn_power_table_entries
;
struct
device
*
cpu_dev
;
get_static_t
plat_get_static_power
;
get_static_t
plat_get_static_power
;
};
};
static
DEFINE_IDA
(
cpufreq_ida
);
static
DEFINE_IDA
(
cpufreq_ida
);
static
DEFINE_MUTEX
(
cooling_list_lock
);
static
DEFINE_MUTEX
(
cooling_list_lock
);
static
LIST_HEAD
(
cpufreq_dev_list
);
static
LIST_HEAD
(
cpufreq_
c
dev_list
);
/* Below code defines functions to be used for cpufreq as cooling device */
/* Below code defines functions to be used for cpufreq as cooling device */
/**
/**
* get_level: Find the level for a particular frequency
* get_level: Find the level for a particular frequency
* @cpufreq_
dev: cpufreq_
dev for which the property is required
* @cpufreq_
cdev: cpufreq_c
dev for which the property is required
* @freq: Frequency
* @freq: Frequency
*
*
* Return: level
on success, THERMAL_CSTATE_INVALID on error
.
* Return: level
corresponding to the frequency
.
*/
*/
static
unsigned
long
get_level
(
struct
cpufreq_cooling_device
*
cpufreq_dev
,
static
unsigned
long
get_level
(
struct
cpufreq_cooling_device
*
cpufreq_
c
dev
,
unsigned
int
freq
)
unsigned
int
freq
)
{
{
struct
freq_table
*
freq_table
=
cpufreq_cdev
->
freq_table
;
unsigned
long
level
;
unsigned
long
level
;
for
(
level
=
0
;
level
<=
cpufreq_dev
->
max_level
;
level
++
)
{
for
(
level
=
1
;
level
<=
cpufreq_cdev
->
max_level
;
level
++
)
if
(
freq
==
cpufreq_dev
->
freq_table
[
level
])
if
(
freq
>
freq_table
[
level
].
frequency
)
return
level
;
if
(
freq
>
cpufreq_dev
->
freq_table
[
level
])
break
;
break
;
}
return
THERMAL_CSTATE_INVALID
;
return
level
-
1
;
}
}
/**
* cpufreq_cooling_get_level - for a given cpu, return the cooling level.
* @cpu: cpu for which the level is required
* @freq: the frequency of interest
*
* This function will match the cooling level corresponding to the
* requested @freq and return it.
*
* Return: The matched cooling level on success or THERMAL_CSTATE_INVALID
* otherwise.
*/
unsigned
long
cpufreq_cooling_get_level
(
unsigned
int
cpu
,
unsigned
int
freq
)
{
struct
cpufreq_cooling_device
*
cpufreq_dev
;
mutex_lock
(
&
cooling_list_lock
);
list_for_each_entry
(
cpufreq_dev
,
&
cpufreq_dev_list
,
node
)
{
if
(
cpumask_test_cpu
(
cpu
,
&
cpufreq_dev
->
allowed_cpus
))
{
mutex_unlock
(
&
cooling_list_lock
);
return
get_level
(
cpufreq_dev
,
freq
);
}
}
mutex_unlock
(
&
cooling_list_lock
);
pr_err
(
"%s: cpu:%d not part of any cooling device
\n
"
,
__func__
,
cpu
);
return
THERMAL_CSTATE_INVALID
;
}
EXPORT_SYMBOL_GPL
(
cpufreq_cooling_get_level
);
/**
/**
* cpufreq_thermal_notifier - notifier callback for cpufreq policy change.
* cpufreq_thermal_notifier - notifier callback for cpufreq policy change.
* @nb: struct notifier_block * with callback info.
* @nb: struct notifier_block * with callback info.
...
@@ -181,14 +150,18 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
...
@@ -181,14 +150,18 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
{
{
struct
cpufreq_policy
*
policy
=
data
;
struct
cpufreq_policy
*
policy
=
data
;
unsigned
long
clipped_freq
;
unsigned
long
clipped_freq
;
struct
cpufreq_cooling_device
*
cpufreq_dev
;
struct
cpufreq_cooling_device
*
cpufreq_
c
dev
;
if
(
event
!=
CPUFREQ_ADJUST
)
if
(
event
!=
CPUFREQ_ADJUST
)
return
NOTIFY_DONE
;
return
NOTIFY_DONE
;
mutex_lock
(
&
cooling_list_lock
);
mutex_lock
(
&
cooling_list_lock
);
list_for_each_entry
(
cpufreq_dev
,
&
cpufreq_dev_list
,
node
)
{
list_for_each_entry
(
cpufreq_cdev
,
&
cpufreq_cdev_list
,
node
)
{
if
(
!
cpumask_test_cpu
(
policy
->
cpu
,
&
cpufreq_dev
->
allowed_cpus
))
/*
* A new copy of the policy is sent to the notifier and can't
* compare that directly.
*/
if
(
policy
->
cpu
!=
cpufreq_cdev
->
policy
->
cpu
)
continue
;
continue
;
/*
/*
...
@@ -202,7 +175,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
...
@@ -202,7 +175,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
* But, if clipped_freq is greater than policy->max, we don't
* But, if clipped_freq is greater than policy->max, we don't
* need to do anything.
* need to do anything.
*/
*/
clipped_freq
=
cpufreq_dev
->
clipped_freq
;
clipped_freq
=
cpufreq_
c
dev
->
clipped_freq
;
if
(
policy
->
max
>
clipped_freq
)
if
(
policy
->
max
>
clipped_freq
)
cpufreq_verify_within_limits
(
policy
,
0
,
clipped_freq
);
cpufreq_verify_within_limits
(
policy
,
0
,
clipped_freq
);
...
@@ -214,63 +187,63 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
...
@@ -214,63 +187,63 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
}
}
/**
/**
*
build_dyn_power_table() - create a dynamic power to frequency table
*
update_freq_table() - Update the freq table with power numbers
* @cpufreq_
device: the cpufreq cooling device in which to stor
e the table
* @cpufreq_
cdev: the cpufreq cooling device in which to updat
e the table
* @capacitance: dynamic power coefficient for these cpus
* @capacitance: dynamic power coefficient for these cpus
*
*
* Build a dynamic power to frequency table for this cpu and store it
* Update the freq table with power numbers. This table will be used in
* in @cpufreq_device. This table will be used in cpu_power_to_freq() and
* cpu_power_to_freq() and cpu_freq_to_power() to convert between power and
* cpu_freq_to_power() to convert between power and frequency
* frequency efficiently. Power is stored in mW, frequency in KHz. The
* efficiently. Power is stored in mW, frequency in KHz. The
* resulting table is in descending order.
* resulting table is in ascending order.
*
*
* Return: 0 on success, -EINVAL if there are no OPPs for any CPUs,
* Return: 0 on success, -EINVAL if there are no OPPs for any CPUs,
* -ENOMEM if we run out of memory or -EAGAIN if an OPP was
* or -ENOMEM if we run out of memory.
* added/enabled while the function was executing.
*/
*/
static
int
build_dyn_power_table
(
struct
cpufreq_cooling_device
*
cpufreq_device
,
static
int
update_freq_table
(
struct
cpufreq_cooling_device
*
cpufreq_cdev
,
u32
capacitance
)
u32
capacitance
)
{
{
struct
power_table
*
power
_table
;
struct
freq_table
*
freq_table
=
cpufreq_cdev
->
freq
_table
;
struct
dev_pm_opp
*
opp
;
struct
dev_pm_opp
*
opp
;
struct
device
*
dev
=
NULL
;
struct
device
*
dev
=
NULL
;
int
num_opps
=
0
,
cpu
,
i
,
ret
=
0
;
int
num_opps
=
0
,
cpu
=
cpufreq_cdev
->
policy
->
cpu
,
i
;
unsigned
long
freq
;
for_each_cpu
(
cpu
,
&
cpufreq_device
->
allowed_cpus
)
{
dev
=
get_cpu_device
(
cpu
);
dev
=
get_cpu_device
(
cpu
);
if
(
!
dev
)
{
if
(
unlikely
(
!
dev
)
)
{
dev_warn
(
&
cpufreq_device
->
cool_
dev
->
device
,
dev_warn
(
&
cpufreq_cdev
->
c
dev
->
device
,
"No cpu device for cpu %d
\n
"
,
cpu
);
"No cpu device for cpu %d
\n
"
,
cpu
);
continue
;
return
-
ENODEV
;
}
}
num_opps
=
dev_pm_opp_get_opp_count
(
dev
);
num_opps
=
dev_pm_opp_get_opp_count
(
dev
);
if
(
num_opps
>
0
)
if
(
num_opps
<
0
)
break
;
else
if
(
num_opps
<
0
)
return
num_opps
;
return
num_opps
;
}
if
(
num_opps
==
0
)
/*
* The cpufreq table is also built from the OPP table and so the count
* should match.
*/
if
(
num_opps
!=
cpufreq_cdev
->
max_level
+
1
)
{
dev_warn
(
dev
,
"Number of OPPs not matching with max_levels
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
power_table
=
kcalloc
(
num_opps
,
sizeof
(
*
power_table
),
GFP_KERNEL
);
for
(
i
=
0
;
i
<=
cpufreq_cdev
->
max_level
;
i
++
)
{
if
(
!
power_table
)
unsigned
long
freq
=
freq_table
[
i
].
frequency
*
1000
;
return
-
ENOMEM
;
u32
freq_mhz
=
freq_table
[
i
].
frequency
/
1000
;
for
(
freq
=
0
,
i
=
0
;
opp
=
dev_pm_opp_find_freq_ceil
(
dev
,
&
freq
),
!
IS_ERR
(
opp
);
freq
++
,
i
++
)
{
u32
freq_mhz
,
voltage_mv
;
u64
power
;
u64
power
;
u32
voltage_mv
;
if
(
i
>=
num_opps
)
{
/*
ret
=
-
EAGAIN
;
* Find ceil frequency as 'freq' may be slightly lower than OPP
goto
free_power_table
;
* freq due to truncation while converting to kHz.
*/
opp
=
dev_pm_opp_find_freq_ceil
(
dev
,
&
freq
);
if
(
IS_ERR
(
opp
))
{
dev_err
(
dev
,
"failed to get opp for %lu frequency
\n
"
,
freq
);
return
-
EINVAL
;
}
}
freq_mhz
=
freq
/
1000000
;
voltage_mv
=
dev_pm_opp_get_voltage
(
opp
)
/
1000
;
voltage_mv
=
dev_pm_opp_get_voltage
(
opp
)
/
1000
;
dev_pm_opp_put
(
opp
);
dev_pm_opp_put
(
opp
);
...
@@ -281,89 +254,73 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device,
...
@@ -281,89 +254,73 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device,
power
=
(
u64
)
capacitance
*
freq_mhz
*
voltage_mv
*
voltage_mv
;
power
=
(
u64
)
capacitance
*
freq_mhz
*
voltage_mv
*
voltage_mv
;
do_div
(
power
,
1000000000
);
do_div
(
power
,
1000000000
);
/* frequency is stored in power_table in KHz */
power_table
[
i
].
frequency
=
freq
/
1000
;
/* power is stored in mW */
/* power is stored in mW */
power
_table
[
i
].
power
=
power
;
freq
_table
[
i
].
power
=
power
;
}
}
if
(
i
!=
num_opps
)
{
ret
=
PTR_ERR
(
opp
);
goto
free_power_table
;
}
cpufreq_device
->
cpu_dev
=
dev
;
cpufreq_device
->
dyn_power_table
=
power_table
;
cpufreq_device
->
dyn_power_table_entries
=
i
;
return
0
;
return
0
;
free_power_table:
kfree
(
power_table
);
return
ret
;
}
}
static
u32
cpu_freq_to_power
(
struct
cpufreq_cooling_device
*
cpufreq_
device
,
static
u32
cpu_freq_to_power
(
struct
cpufreq_cooling_device
*
cpufreq_
cdev
,
u32
freq
)
u32
freq
)
{
{
int
i
;
int
i
;
struct
power_table
*
pt
=
cpufreq_device
->
dyn_power
_table
;
struct
freq_table
*
freq_table
=
cpufreq_cdev
->
freq
_table
;
for
(
i
=
1
;
i
<
cpufreq_device
->
dyn_power_table_entries
;
i
++
)
for
(
i
=
1
;
i
<
=
cpufreq_cdev
->
max_level
;
i
++
)
if
(
freq
<
pt
[
i
].
frequency
)
if
(
freq
>
freq_table
[
i
].
frequency
)
break
;
break
;
return
pt
[
i
-
1
].
power
;
return
freq_table
[
i
-
1
].
power
;
}
}
static
u32
cpu_power_to_freq
(
struct
cpufreq_cooling_device
*
cpufreq_
device
,
static
u32
cpu_power_to_freq
(
struct
cpufreq_cooling_device
*
cpufreq_
cdev
,
u32
power
)
u32
power
)
{
{
int
i
;
int
i
;
struct
power_table
*
pt
=
cpufreq_device
->
dyn_power
_table
;
struct
freq_table
*
freq_table
=
cpufreq_cdev
->
freq
_table
;
for
(
i
=
1
;
i
<
cpufreq_device
->
dyn_power_table_entries
;
i
++
)
for
(
i
=
1
;
i
<
=
cpufreq_cdev
->
max_level
;
i
++
)
if
(
power
<
pt
[
i
].
power
)
if
(
power
>
freq_table
[
i
].
power
)
break
;
break
;
return
pt
[
i
-
1
].
frequency
;
return
freq_table
[
i
-
1
].
frequency
;
}
}
/**
/**
* get_load() - get load for a cpu since last updated
* get_load() - get load for a cpu since last updated
* @cpufreq_
device
: &struct cpufreq_cooling_device for this cpu
* @cpufreq_
cdev
: &struct cpufreq_cooling_device for this cpu
* @cpu: cpu number
* @cpu: cpu number
* @cpu_idx: index of the cpu in
cpufreq_device->allowed_cpus
* @cpu_idx: index of the cpu in
time_in_idle*
*
*
* Return: The average load of cpu @cpu in percentage since this
* Return: The average load of cpu @cpu in percentage since this
* function was last called.
* function was last called.
*/
*/
static
u32
get_load
(
struct
cpufreq_cooling_device
*
cpufreq_
device
,
int
cpu
,
static
u32
get_load
(
struct
cpufreq_cooling_device
*
cpufreq_
cdev
,
int
cpu
,
int
cpu_idx
)
int
cpu_idx
)
{
{
u32
load
;
u32
load
;
u64
now
,
now_idle
,
delta_time
,
delta_idle
;
u64
now
,
now_idle
,
delta_time
,
delta_idle
;
struct
time_in_idle
*
idle_time
=
&
cpufreq_cdev
->
idle_time
[
cpu_idx
];
now_idle
=
get_cpu_idle_time
(
cpu
,
&
now
,
0
);
now_idle
=
get_cpu_idle_time
(
cpu
,
&
now
,
0
);
delta_idle
=
now_idle
-
cpufreq_device
->
time_in_idle
[
cpu_idx
]
;
delta_idle
=
now_idle
-
idle_time
->
time
;
delta_time
=
now
-
cpufreq_device
->
time_in_idle_timestamp
[
cpu_idx
]
;
delta_time
=
now
-
idle_time
->
timestamp
;
if
(
delta_time
<=
delta_idle
)
if
(
delta_time
<=
delta_idle
)
load
=
0
;
load
=
0
;
else
else
load
=
div64_u64
(
100
*
(
delta_time
-
delta_idle
),
delta_time
);
load
=
div64_u64
(
100
*
(
delta_time
-
delta_idle
),
delta_time
);
cpufreq_device
->
time_in_idle
[
cpu_idx
]
=
now_idle
;
idle_time
->
time
=
now_idle
;
cpufreq_device
->
time_in_idle_timestamp
[
cpu_idx
]
=
now
;
idle_time
->
timestamp
=
now
;
return
load
;
return
load
;
}
}
/**
/**
* get_static_power() - calculate the static power consumed by the cpus
* get_static_power() - calculate the static power consumed by the cpus
* @cpufreq_
device
: struct &cpufreq_cooling_device for this cpu cdev
* @cpufreq_
cdev
: struct &cpufreq_cooling_device for this cpu cdev
* @tz: thermal zone device in which we're operating
* @tz: thermal zone device in which we're operating
* @freq: frequency in KHz
* @freq: frequency in KHz
* @power: pointer in which to store the calculated static power
* @power: pointer in which to store the calculated static power
...
@@ -376,26 +333,28 @@ static u32 get_load(struct cpufreq_cooling_device *cpufreq_device, int cpu,
...
@@ -376,26 +333,28 @@ static u32 get_load(struct cpufreq_cooling_device *cpufreq_device, int cpu,
*
*
* Return: 0 on success, -E* on failure.
* Return: 0 on success, -E* on failure.
*/
*/
static
int
get_static_power
(
struct
cpufreq_cooling_device
*
cpufreq_
device
,
static
int
get_static_power
(
struct
cpufreq_cooling_device
*
cpufreq_
cdev
,
struct
thermal_zone_device
*
tz
,
unsigned
long
freq
,
struct
thermal_zone_device
*
tz
,
unsigned
long
freq
,
u32
*
power
)
u32
*
power
)
{
{
struct
dev_pm_opp
*
opp
;
struct
dev_pm_opp
*
opp
;
unsigned
long
voltage
;
unsigned
long
voltage
;
struct
cpumask
*
cpumask
=
&
cpufreq_device
->
allowed_cpus
;
struct
cpufreq_policy
*
policy
=
cpufreq_cdev
->
policy
;
struct
cpumask
*
cpumask
=
policy
->
related_cpus
;
unsigned
long
freq_hz
=
freq
*
1000
;
unsigned
long
freq_hz
=
freq
*
1000
;
struct
device
*
dev
;
if
(
!
cpufreq_device
->
plat_get_static_power
||
if
(
!
cpufreq_cdev
->
plat_get_static_power
)
{
!
cpufreq_device
->
cpu_dev
)
{
*
power
=
0
;
*
power
=
0
;
return
0
;
return
0
;
}
}
opp
=
dev_pm_opp_find_freq_exact
(
cpufreq_device
->
cpu_dev
,
freq_hz
,
dev
=
get_cpu_device
(
policy
->
cpu
);
true
);
WARN_ON
(
!
dev
);
opp
=
dev_pm_opp_find_freq_exact
(
dev
,
freq_hz
,
true
);
if
(
IS_ERR
(
opp
))
{
if
(
IS_ERR
(
opp
))
{
dev_warn_ratelimited
(
cpufreq_device
->
cpu_dev
,
dev_warn_ratelimited
(
dev
,
"Failed to find OPP for frequency %lu: %ld
\n
"
,
"Failed to find OPP for frequency %lu: %ld
\n
"
,
freq_hz
,
PTR_ERR
(
opp
));
freq_hz
,
PTR_ERR
(
opp
));
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -404,31 +363,30 @@ static int get_static_power(struct cpufreq_cooling_device *cpufreq_device,
...
@@ -404,31 +363,30 @@ static int get_static_power(struct cpufreq_cooling_device *cpufreq_device,
dev_pm_opp_put
(
opp
);
dev_pm_opp_put
(
opp
);
if
(
voltage
==
0
)
{
if
(
voltage
==
0
)
{
dev_err_ratelimited
(
cpufreq_device
->
cpu_dev
,
dev_err_ratelimited
(
dev
,
"Failed to get voltage for frequency %lu
\n
"
,
"Failed to get voltage for frequency %lu
\n
"
,
freq_hz
);
freq_hz
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
return
cpufreq_
device
->
plat_get_static_power
(
cpumask
,
tz
->
passive_delay
,
return
cpufreq_
cdev
->
plat_get_static_power
(
cpumask
,
tz
->
passive_delay
,
voltage
,
power
);
voltage
,
power
);
}
}
/**
/**
* get_dynamic_power() - calculate the dynamic power
* get_dynamic_power() - calculate the dynamic power
* @cpufreq_
device
: &cpufreq_cooling_device for this cdev
* @cpufreq_
cdev
: &cpufreq_cooling_device for this cdev
* @freq: current frequency
* @freq: current frequency
*
*
* Return: the dynamic power consumed by the cpus described by
* Return: the dynamic power consumed by the cpus described by
* @cpufreq_
device
.
* @cpufreq_
cdev
.
*/
*/
static
u32
get_dynamic_power
(
struct
cpufreq_cooling_device
*
cpufreq_
device
,
static
u32
get_dynamic_power
(
struct
cpufreq_cooling_device
*
cpufreq_
cdev
,
unsigned
long
freq
)
unsigned
long
freq
)
{
{
u32
raw_cpu_power
;
u32
raw_cpu_power
;
raw_cpu_power
=
cpu_freq_to_power
(
cpufreq_
device
,
freq
);
raw_cpu_power
=
cpu_freq_to_power
(
cpufreq_
cdev
,
freq
);
return
(
raw_cpu_power
*
cpufreq_
device
->
last_load
)
/
100
;
return
(
raw_cpu_power
*
cpufreq_
cdev
->
last_load
)
/
100
;
}
}
/* cpufreq cooling device callback functions are defined below */
/* cpufreq cooling device callback functions are defined below */
...
@@ -446,9 +404,9 @@ static u32 get_dynamic_power(struct cpufreq_cooling_device *cpufreq_device,
...
@@ -446,9 +404,9 @@ static u32 get_dynamic_power(struct cpufreq_cooling_device *cpufreq_device,
static
int
cpufreq_get_max_state
(
struct
thermal_cooling_device
*
cdev
,
static
int
cpufreq_get_max_state
(
struct
thermal_cooling_device
*
cdev
,
unsigned
long
*
state
)
unsigned
long
*
state
)
{
{
struct
cpufreq_cooling_device
*
cpufreq_
device
=
cdev
->
devdata
;
struct
cpufreq_cooling_device
*
cpufreq_
cdev
=
cdev
->
devdata
;
*
state
=
cpufreq_
device
->
max_level
;
*
state
=
cpufreq_
cdev
->
max_level
;
return
0
;
return
0
;
}
}
...
@@ -465,9 +423,9 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
...
@@ -465,9 +423,9 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
static
int
cpufreq_get_cur_state
(
struct
thermal_cooling_device
*
cdev
,
static
int
cpufreq_get_cur_state
(
struct
thermal_cooling_device
*
cdev
,
unsigned
long
*
state
)
unsigned
long
*
state
)
{
{
struct
cpufreq_cooling_device
*
cpufreq_
device
=
cdev
->
devdata
;
struct
cpufreq_cooling_device
*
cpufreq_
cdev
=
cdev
->
devdata
;
*
state
=
cpufreq_
device
->
cpufreq_state
;
*
state
=
cpufreq_
cdev
->
cpufreq_state
;
return
0
;
return
0
;
}
}
...
@@ -485,23 +443,22 @@ static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
...
@@ -485,23 +443,22 @@ static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
static
int
cpufreq_set_cur_state
(
struct
thermal_cooling_device
*
cdev
,
static
int
cpufreq_set_cur_state
(
struct
thermal_cooling_device
*
cdev
,
unsigned
long
state
)
unsigned
long
state
)
{
{
struct
cpufreq_cooling_device
*
cpufreq_device
=
cdev
->
devdata
;
struct
cpufreq_cooling_device
*
cpufreq_cdev
=
cdev
->
devdata
;
unsigned
int
cpu
=
cpumask_any
(
&
cpufreq_device
->
allowed_cpus
);
unsigned
int
clip_freq
;
unsigned
int
clip_freq
;
/* Request state should be less than max_level */
/* Request state should be less than max_level */
if
(
WARN_ON
(
state
>
cpufreq_
device
->
max_level
))
if
(
WARN_ON
(
state
>
cpufreq_
cdev
->
max_level
))
return
-
EINVAL
;
return
-
EINVAL
;
/* Check if the old cooling action is same as new cooling action */
/* Check if the old cooling action is same as new cooling action */
if
(
cpufreq_
device
->
cpufreq_state
==
state
)
if
(
cpufreq_
cdev
->
cpufreq_state
==
state
)
return
0
;
return
0
;
clip_freq
=
cpufreq_
device
->
freq_table
[
state
]
;
clip_freq
=
cpufreq_
cdev
->
freq_table
[
state
].
frequency
;
cpufreq_
device
->
cpufreq_state
=
state
;
cpufreq_
cdev
->
cpufreq_state
=
state
;
cpufreq_
device
->
clipped_freq
=
clip_freq
;
cpufreq_
cdev
->
clipped_freq
=
clip_freq
;
cpufreq_update_policy
(
cpu
);
cpufreq_update_policy
(
cpu
freq_cdev
->
policy
->
cpu
);
return
0
;
return
0
;
}
}
...
@@ -536,33 +493,23 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
...
@@ -536,33 +493,23 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
unsigned
long
freq
;
unsigned
long
freq
;
int
i
=
0
,
cpu
,
ret
;
int
i
=
0
,
cpu
,
ret
;
u32
static_power
,
dynamic_power
,
total_load
=
0
;
u32
static_power
,
dynamic_power
,
total_load
=
0
;
struct
cpufreq_cooling_device
*
cpufreq_device
=
cdev
->
devdata
;
struct
cpufreq_cooling_device
*
cpufreq_cdev
=
cdev
->
devdata
;
struct
cpufreq_policy
*
policy
=
cpufreq_cdev
->
policy
;
u32
*
load_cpu
=
NULL
;
u32
*
load_cpu
=
NULL
;
cpu
=
cpumask_any_and
(
&
cpufreq_device
->
allowed_cpus
,
cpu_online_mask
);
freq
=
cpufreq_quick_get
(
policy
->
cpu
);
/*
* All the CPUs are offline, thus the requested power by
* the cdev is 0
*/
if
(
cpu
>=
nr_cpu_ids
)
{
*
power
=
0
;
return
0
;
}
freq
=
cpufreq_quick_get
(
cpu
);
if
(
trace_thermal_power_cpu_get_power_enabled
())
{
if
(
trace_thermal_power_cpu_get_power_enabled
())
{
u32
ncpus
=
cpumask_weight
(
&
cpufreq_device
->
allow
ed_cpus
);
u32
ncpus
=
cpumask_weight
(
policy
->
relat
ed_cpus
);
load_cpu
=
kcalloc
(
ncpus
,
sizeof
(
*
load_cpu
),
GFP_KERNEL
);
load_cpu
=
kcalloc
(
ncpus
,
sizeof
(
*
load_cpu
),
GFP_KERNEL
);
}
}
for_each_cpu
(
cpu
,
&
cpufreq_device
->
allow
ed_cpus
)
{
for_each_cpu
(
cpu
,
policy
->
relat
ed_cpus
)
{
u32
load
;
u32
load
;
if
(
cpu_online
(
cpu
))
if
(
cpu_online
(
cpu
))
load
=
get_load
(
cpufreq_
device
,
cpu
,
i
);
load
=
get_load
(
cpufreq_
cdev
,
cpu
,
i
);
else
else
load
=
0
;
load
=
0
;
...
@@ -573,19 +520,19 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
...
@@ -573,19 +520,19 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
i
++
;
i
++
;
}
}
cpufreq_
device
->
last_load
=
total_load
;
cpufreq_
cdev
->
last_load
=
total_load
;
dynamic_power
=
get_dynamic_power
(
cpufreq_
device
,
freq
);
dynamic_power
=
get_dynamic_power
(
cpufreq_
cdev
,
freq
);
ret
=
get_static_power
(
cpufreq_
device
,
tz
,
freq
,
&
static_power
);
ret
=
get_static_power
(
cpufreq_
cdev
,
tz
,
freq
,
&
static_power
);
if
(
ret
)
{
if
(
ret
)
{
kfree
(
load_cpu
);
kfree
(
load_cpu
);
return
ret
;
return
ret
;
}
}
if
(
load_cpu
)
{
if
(
load_cpu
)
{
trace_thermal_power_cpu_get_power
(
trace_thermal_power_cpu_get_power
(
policy
->
related_cpus
,
freq
,
&
cpufreq_device
->
allowed_cpus
,
load_cpu
,
i
,
dynamic_power
,
freq
,
load_cpu
,
i
,
dynamic_power
,
static_power
);
static_power
);
kfree
(
load_cpu
);
kfree
(
load_cpu
);
}
}
...
@@ -614,38 +561,23 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
...
@@ -614,38 +561,23 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
unsigned
long
state
,
u32
*
power
)
unsigned
long
state
,
u32
*
power
)
{
{
unsigned
int
freq
,
num_cpus
;
unsigned
int
freq
,
num_cpus
;
cpumask_var_t
cpumask
;
u32
static_power
,
dynamic_power
;
u32
static_power
,
dynamic_power
;
int
ret
;
int
ret
;
struct
cpufreq_cooling_device
*
cpufreq_
device
=
cdev
->
devdata
;
struct
cpufreq_cooling_device
*
cpufreq_
cdev
=
cdev
->
devdata
;
if
(
!
alloc_cpumask_var
(
&
cpumask
,
GFP_KERNEL
))
/* Request state should be less than max_level */
return
-
ENOMEM
;
if
(
WARN_ON
(
state
>
cpufreq_cdev
->
max_level
))
return
-
EINVAL
;
cpumask_and
(
cpumask
,
&
cpufreq_device
->
allowed_cpus
,
cpu_online_mask
);
num_cpus
=
cpumask_weight
(
cpumask
);
/* None of our cpus are online, so no power */
if
(
num_cpus
==
0
)
{
*
power
=
0
;
ret
=
0
;
goto
out
;
}
freq
=
cpufreq_device
->
freq_table
[
state
];
num_cpus
=
cpumask_weight
(
cpufreq_cdev
->
policy
->
cpus
);
if
(
!
freq
)
{
ret
=
-
EINVAL
;
goto
out
;
}
dynamic_power
=
cpu_freq_to_power
(
cpufreq_device
,
freq
)
*
num_cpus
;
freq
=
cpufreq_cdev
->
freq_table
[
state
].
frequency
;
ret
=
get_static_power
(
cpufreq_device
,
tz
,
freq
,
&
static_power
);
dynamic_power
=
cpu_freq_to_power
(
cpufreq_cdev
,
freq
)
*
num_cpus
;
ret
=
get_static_power
(
cpufreq_cdev
,
tz
,
freq
,
&
static_power
);
if
(
ret
)
if
(
ret
)
goto
ou
t
;
return
re
t
;
*
power
=
static_power
+
dynamic_power
;
*
power
=
static_power
+
dynamic_power
;
out:
free_cpumask_var
(
cpumask
);
return
ret
;
return
ret
;
}
}
...
@@ -673,39 +605,27 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev,
...
@@ -673,39 +605,27 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev,
struct
thermal_zone_device
*
tz
,
u32
power
,
struct
thermal_zone_device
*
tz
,
u32
power
,
unsigned
long
*
state
)
unsigned
long
*
state
)
{
{
unsigned
int
c
pu
,
c
ur_freq
,
target_freq
;
unsigned
int
cur_freq
,
target_freq
;
int
ret
;
int
ret
;
s32
dyn_power
;
s32
dyn_power
;
u32
last_load
,
normalised_power
,
static_power
;
u32
last_load
,
normalised_power
,
static_power
;
struct
cpufreq_cooling_device
*
cpufreq_device
=
cdev
->
devdata
;
struct
cpufreq_cooling_device
*
cpufreq_cdev
=
cdev
->
devdata
;
struct
cpufreq_policy
*
policy
=
cpufreq_cdev
->
policy
;
cpu
=
cpumask_any_and
(
&
cpufreq_device
->
allowed_cpus
,
cpu_online_mask
);
/* None of our cpus are online */
if
(
cpu
>=
nr_cpu_ids
)
return
-
ENODEV
;
cur_freq
=
cpufreq_quick_get
(
cpu
);
cur_freq
=
cpufreq_quick_get
(
policy
->
cpu
);
ret
=
get_static_power
(
cpufreq_
device
,
tz
,
cur_freq
,
&
static_power
);
ret
=
get_static_power
(
cpufreq_
cdev
,
tz
,
cur_freq
,
&
static_power
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
dyn_power
=
power
-
static_power
;
dyn_power
=
power
-
static_power
;
dyn_power
=
dyn_power
>
0
?
dyn_power
:
0
;
dyn_power
=
dyn_power
>
0
?
dyn_power
:
0
;
last_load
=
cpufreq_
device
->
last_load
?:
1
;
last_load
=
cpufreq_
cdev
->
last_load
?:
1
;
normalised_power
=
(
dyn_power
*
100
)
/
last_load
;
normalised_power
=
(
dyn_power
*
100
)
/
last_load
;
target_freq
=
cpu_power_to_freq
(
cpufreq_device
,
normalised_power
);
target_freq
=
cpu_power_to_freq
(
cpufreq_cdev
,
normalised_power
);
*
state
=
cpufreq_cooling_get_level
(
cpu
,
target_freq
);
if
(
*
state
==
THERMAL_CSTATE_INVALID
)
{
dev_err_ratelimited
(
&
cdev
->
device
,
"Failed to convert %dKHz for cpu %d into a cdev state
\n
"
,
target_freq
,
cpu
);
return
-
EINVAL
;
}
trace_thermal_power_cpu_limit
(
&
cpufreq_device
->
allowed_cpus
,
*
state
=
get_level
(
cpufreq_cdev
,
target_freq
);
target_freq
,
*
state
,
power
);
trace_thermal_power_cpu_limit
(
policy
->
related_cpus
,
target_freq
,
*
state
,
power
);
return
0
;
return
0
;
}
}
...
@@ -748,7 +668,7 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table,
...
@@ -748,7 +668,7 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table,
/**
/**
* __cpufreq_cooling_register - helper function to create cpufreq cooling device
* __cpufreq_cooling_register - helper function to create cpufreq cooling device
* @np: a valid struct device_node to the cooling device device tree node
* @np: a valid struct device_node to the cooling device device tree node
* @
clip_cpus: cpumask of cpus where the frequency constraints will happen.
* @
policy: cpufreq policy
* Normally this should be same as cpufreq policy->related_cpus.
* Normally this should be same as cpufreq policy->related_cpus.
* @capacitance: dynamic power coefficient for these cpus
* @capacitance: dynamic power coefficient for these cpus
* @plat_static_func: function to calculate the static power consumed by these
* @plat_static_func: function to calculate the static power consumed by these
...
@@ -764,102 +684,68 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table,
...
@@ -764,102 +684,68 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table,
*/
*/
static
struct
thermal_cooling_device
*
static
struct
thermal_cooling_device
*
__cpufreq_cooling_register
(
struct
device_node
*
np
,
__cpufreq_cooling_register
(
struct
device_node
*
np
,
const
struct
cpumask
*
clip_cpus
,
u32
capacitance
,
struct
cpufreq_policy
*
policy
,
u32
capacitance
,
get_static_t
plat_static_func
)
get_static_t
plat_static_func
)
{
{
struct
cpufreq_policy
*
policy
;
struct
thermal_cooling_device
*
cdev
;
struct
thermal_cooling_device
*
cool_dev
;
struct
cpufreq_cooling_device
*
cpufreq_cdev
;
struct
cpufreq_cooling_device
*
cpufreq_dev
;
char
dev_name
[
THERMAL_NAME_LENGTH
];
char
dev_name
[
THERMAL_NAME_LENGTH
];
struct
cpufreq_frequency_table
*
pos
,
*
table
;
cpumask_var_t
temp_mask
;
unsigned
int
freq
,
i
,
num_cpus
;
unsigned
int
freq
,
i
,
num_cpus
;
int
ret
;
int
ret
;
struct
thermal_cooling_device_ops
*
cooling_ops
;
struct
thermal_cooling_device_ops
*
cooling_ops
;
bool
first
;
bool
first
;
if
(
!
alloc_cpumask_var
(
&
temp_mask
,
GFP_KERNEL
))
if
(
IS_ERR_OR_NULL
(
policy
))
{
return
ERR_PTR
(
-
ENOMEM
);
pr_err
(
"%s: cpufreq policy isn't valid: %p"
,
__func__
,
policy
);
return
ERR_PTR
(
-
EINVAL
);
cpumask_and
(
temp_mask
,
clip_cpus
,
cpu_online_mask
);
policy
=
cpufreq_cpu_get
(
cpumask_first
(
temp_mask
));
if
(
!
policy
)
{
pr_debug
(
"%s: CPUFreq policy not found
\n
"
,
__func__
);
cool_dev
=
ERR_PTR
(
-
EPROBE_DEFER
);
goto
free_cpumask
;
}
}
table
=
policy
->
freq_table
;
i
=
cpufreq_table_count_valid_entries
(
policy
)
;
if
(
!
table
)
{
if
(
!
i
)
{
pr_debug
(
"%s: CPUFreq table not found
\n
"
,
__func__
);
pr_debug
(
"%s: CPUFreq table not found
or has no valid entries
\n
"
,
cool_dev
=
ERR_PTR
(
-
ENODEV
);
__func__
);
goto
put_policy
;
return
ERR_PTR
(
-
ENODEV
)
;
}
}
cpufreq_dev
=
kzalloc
(
sizeof
(
*
cpufreq_dev
),
GFP_KERNEL
);
cpufreq_cdev
=
kzalloc
(
sizeof
(
*
cpufreq_cdev
),
GFP_KERNEL
);
if
(
!
cpufreq_dev
)
{
if
(
!
cpufreq_cdev
)
cool_dev
=
ERR_PTR
(
-
ENOMEM
);
return
ERR_PTR
(
-
ENOMEM
);
goto
put_policy
;
}
num_cpus
=
cpumask_weight
(
clip_cpus
);
cpufreq_cdev
->
policy
=
policy
;
cpufreq_dev
->
time_in_idle
=
kcalloc
(
num_cpus
,
num_cpus
=
cpumask_weight
(
policy
->
related_cpus
);
sizeof
(
*
cpufreq_dev
->
time_in_idle
),
cpufreq_cdev
->
idle_time
=
kcalloc
(
num_cpus
,
sizeof
(
*
cpufreq_cdev
->
idle_time
),
GFP_KERNEL
);
GFP_KERNEL
);
if
(
!
cpufreq_
dev
->
time_in_idl
e
)
{
if
(
!
cpufreq_
cdev
->
idle_tim
e
)
{
c
ool_
dev
=
ERR_PTR
(
-
ENOMEM
);
cdev
=
ERR_PTR
(
-
ENOMEM
);
goto
free_cdev
;
goto
free_cdev
;
}
}
cpufreq_dev
->
time_in_idle_timestamp
=
kcalloc
(
num_cpus
,
sizeof
(
*
cpufreq_dev
->
time_in_idle_timestamp
),
GFP_KERNEL
);
if
(
!
cpufreq_dev
->
time_in_idle_timestamp
)
{
cool_dev
=
ERR_PTR
(
-
ENOMEM
);
goto
free_time_in_idle
;
}
/* Find max levels */
cpufreq_for_each_valid_entry
(
pos
,
table
)
cpufreq_dev
->
max_level
++
;
cpufreq_dev
->
freq_table
=
kmalloc
(
sizeof
(
*
cpufreq_dev
->
freq_table
)
*
cpufreq_dev
->
max_level
,
GFP_KERNEL
);
if
(
!
cpufreq_dev
->
freq_table
)
{
cool_dev
=
ERR_PTR
(
-
ENOMEM
);
goto
free_time_in_idle_timestamp
;
}
/* max_level is an index, not a counter */
/* max_level is an index, not a counter */
cpufreq_dev
->
max_level
--
;
cpufreq_cdev
->
max_level
=
i
-
1
;
cpumask_copy
(
&
cpufreq_dev
->
allowed_cpus
,
clip_cpus
);
if
(
capacitance
)
{
cpufreq_dev
->
plat_get_static_power
=
plat_static_func
;
ret
=
build_dyn_power_table
(
cpufreq_dev
,
capacitance
);
if
(
ret
)
{
cool_dev
=
ERR_PTR
(
ret
);
goto
free_table
;
}
cooling_ops
=
&
cpufreq_power_cooling_ops
;
cpufreq_cdev
->
freq_table
=
kmalloc_array
(
i
,
}
else
{
sizeof
(
*
cpufreq_cdev
->
freq_table
),
cooling_ops
=
&
cpufreq_cooling_ops
;
GFP_KERNEL
);
if
(
!
cpufreq_cdev
->
freq_table
)
{
cdev
=
ERR_PTR
(
-
ENOMEM
);
goto
free_idle_time
;
}
}
ret
=
ida_simple_get
(
&
cpufreq_ida
,
0
,
0
,
GFP_KERNEL
);
ret
=
ida_simple_get
(
&
cpufreq_ida
,
0
,
0
,
GFP_KERNEL
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
c
ool_
dev
=
ERR_PTR
(
ret
);
cdev
=
ERR_PTR
(
ret
);
goto
free_
power_
table
;
goto
free_table
;
}
}
cpufreq_dev
->
id
=
ret
;
cpufreq_cdev
->
id
=
ret
;
snprintf
(
dev_name
,
sizeof
(
dev_name
),
"thermal-cpufreq-%d"
,
cpufreq_cdev
->
id
);
/* Fill freq-table in descending order of frequencies */
/* Fill freq-table in descending order of frequencies */
for
(
i
=
0
,
freq
=
-
1
;
i
<=
cpufreq_dev
->
max_level
;
i
++
)
{
for
(
i
=
0
,
freq
=
-
1
;
i
<=
cpufreq_
c
dev
->
max_level
;
i
++
)
{
freq
=
find_next_max
(
table
,
freq
);
freq
=
find_next_max
(
policy
->
freq_
table
,
freq
);
cpufreq_
dev
->
freq_table
[
i
]
=
freq
;
cpufreq_
cdev
->
freq_table
[
i
].
frequency
=
freq
;
/* Warn for duplicate entries */
/* Warn for duplicate entries */
if
(
!
freq
)
if
(
!
freq
)
...
@@ -868,51 +754,54 @@ __cpufreq_cooling_register(struct device_node *np,
...
@@ -868,51 +754,54 @@ __cpufreq_cooling_register(struct device_node *np,
pr_debug
(
"%s: freq:%u KHz
\n
"
,
__func__
,
freq
);
pr_debug
(
"%s: freq:%u KHz
\n
"
,
__func__
,
freq
);
}
}
snprintf
(
dev_name
,
sizeof
(
dev_name
),
"thermal-cpufreq-%d"
,
if
(
capacitance
)
{
cpufreq_dev
->
id
);
cpufreq_cdev
->
plat_get_static_power
=
plat_static_func
;
ret
=
update_freq_table
(
cpufreq_cdev
,
capacitance
);
if
(
ret
)
{
cdev
=
ERR_PTR
(
ret
);
goto
remove_ida
;
}
cooling_ops
=
&
cpufreq_power_cooling_ops
;
}
else
{
cooling_ops
=
&
cpufreq_cooling_ops
;
}
c
ool_dev
=
thermal_of_cooling_device_register
(
np
,
dev_name
,
cpufreq_
dev
,
c
dev
=
thermal_of_cooling_device_register
(
np
,
dev_name
,
cpufreq_c
dev
,
cooling_ops
);
cooling_ops
);
if
(
IS_ERR
(
c
ool_
dev
))
if
(
IS_ERR
(
cdev
))
goto
remove_ida
;
goto
remove_ida
;
cpufreq_
dev
->
clipped_freq
=
cpufreq_dev
->
freq_table
[
0
]
;
cpufreq_
cdev
->
clipped_freq
=
cpufreq_cdev
->
freq_table
[
0
].
frequency
;
cpufreq_
dev
->
cool_dev
=
cool_
dev
;
cpufreq_
cdev
->
cdev
=
c
dev
;
mutex_lock
(
&
cooling_list_lock
);
mutex_lock
(
&
cooling_list_lock
);
/* Register the notifier for first cpufreq cooling device */
/* Register the notifier for first cpufreq cooling device */
first
=
list_empty
(
&
cpufreq_dev_list
);
first
=
list_empty
(
&
cpufreq_
c
dev_list
);
list_add
(
&
cpufreq_
dev
->
node
,
&
cpufreq_
dev_list
);
list_add
(
&
cpufreq_
cdev
->
node
,
&
cpufreq_c
dev_list
);
mutex_unlock
(
&
cooling_list_lock
);
mutex_unlock
(
&
cooling_list_lock
);
if
(
first
)
if
(
first
)
cpufreq_register_notifier
(
&
thermal_cpufreq_notifier_block
,
cpufreq_register_notifier
(
&
thermal_cpufreq_notifier_block
,
CPUFREQ_POLICY_NOTIFIER
);
CPUFREQ_POLICY_NOTIFIER
);
goto
put_policy
;
return
cdev
;
remove_ida:
remove_ida:
ida_simple_remove
(
&
cpufreq_ida
,
cpufreq_dev
->
id
);
ida_simple_remove
(
&
cpufreq_ida
,
cpufreq_cdev
->
id
);
free_power_table:
kfree
(
cpufreq_dev
->
dyn_power_table
);
free_table:
free_table:
kfree
(
cpufreq_dev
->
freq_table
);
kfree
(
cpufreq_cdev
->
freq_table
);
free_time_in_idle_timestamp:
free_idle_time:
kfree
(
cpufreq_dev
->
time_in_idle_timestamp
);
kfree
(
cpufreq_cdev
->
idle_time
);
free_time_in_idle:
kfree
(
cpufreq_dev
->
time_in_idle
);
free_cdev:
free_cdev:
kfree
(
cpufreq_dev
);
kfree
(
cpufreq_cdev
);
put_policy:
return
cdev
;
cpufreq_cpu_put
(
policy
);
free_cpumask:
free_cpumask_var
(
temp_mask
);
return
cool_dev
;
}
}
/**
/**
* cpufreq_cooling_register - function to create cpufreq cooling device.
* cpufreq_cooling_register - function to create cpufreq cooling device.
* @
clip_cpus: cpumask of cpus where the frequency constraints will happen.
* @
policy: cpufreq policy
*
*
* This interface function registers the cpufreq cooling device with the name
* This interface function registers the cpufreq cooling device with the name
* "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
* "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
...
@@ -922,16 +811,16 @@ __cpufreq_cooling_register(struct device_node *np,
...
@@ -922,16 +811,16 @@ __cpufreq_cooling_register(struct device_node *np,
* on failure, it returns a corresponding ERR_PTR().
* on failure, it returns a corresponding ERR_PTR().
*/
*/
struct
thermal_cooling_device
*
struct
thermal_cooling_device
*
cpufreq_cooling_register
(
const
struct
cpumask
*
clip_cpus
)
cpufreq_cooling_register
(
struct
cpufreq_policy
*
policy
)
{
{
return
__cpufreq_cooling_register
(
NULL
,
clip_cpus
,
0
,
NULL
);
return
__cpufreq_cooling_register
(
NULL
,
policy
,
0
,
NULL
);
}
}
EXPORT_SYMBOL_GPL
(
cpufreq_cooling_register
);
EXPORT_SYMBOL_GPL
(
cpufreq_cooling_register
);
/**
/**
* of_cpufreq_cooling_register - function to create cpufreq cooling device.
* of_cpufreq_cooling_register - function to create cpufreq cooling device.
* @np: a valid struct device_node to the cooling device device tree node
* @np: a valid struct device_node to the cooling device device tree node
* @
clip_cpus: cpumask of cpus where the frequency constraints will happen.
* @
policy: cpufreq policy
*
*
* This interface function registers the cpufreq cooling device with the name
* This interface function registers the cpufreq cooling device with the name
* "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
* "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
...
@@ -943,18 +832,18 @@ EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
...
@@ -943,18 +832,18 @@ EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
*/
*/
struct
thermal_cooling_device
*
struct
thermal_cooling_device
*
of_cpufreq_cooling_register
(
struct
device_node
*
np
,
of_cpufreq_cooling_register
(
struct
device_node
*
np
,
const
struct
cpumask
*
clip_cpus
)
struct
cpufreq_policy
*
policy
)
{
{
if
(
!
np
)
if
(
!
np
)
return
ERR_PTR
(
-
EINVAL
);
return
ERR_PTR
(
-
EINVAL
);
return
__cpufreq_cooling_register
(
np
,
clip_cpus
,
0
,
NULL
);
return
__cpufreq_cooling_register
(
np
,
policy
,
0
,
NULL
);
}
}
EXPORT_SYMBOL_GPL
(
of_cpufreq_cooling_register
);
EXPORT_SYMBOL_GPL
(
of_cpufreq_cooling_register
);
/**
/**
* cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions
* cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions
* @
clip_cpus: cpumask of cpus where the frequency constraints will happen
* @
policy: cpufreq policy
* @capacitance: dynamic power coefficient for these cpus
* @capacitance: dynamic power coefficient for these cpus
* @plat_static_func: function to calculate the static power consumed by these
* @plat_static_func: function to calculate the static power consumed by these
* cpus (optional)
* cpus (optional)
...
@@ -974,10 +863,10 @@ EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register);
...
@@ -974,10 +863,10 @@ EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register);
* on failure, it returns a corresponding ERR_PTR().
* on failure, it returns a corresponding ERR_PTR().
*/
*/
struct
thermal_cooling_device
*
struct
thermal_cooling_device
*
cpufreq_power_cooling_register
(
const
struct
cpumask
*
clip_cpus
,
u32
capacitance
,
cpufreq_power_cooling_register
(
struct
cpufreq_policy
*
policy
,
u32
capacitance
,
get_static_t
plat_static_func
)
get_static_t
plat_static_func
)
{
{
return
__cpufreq_cooling_register
(
NULL
,
clip_cpus
,
capacitance
,
return
__cpufreq_cooling_register
(
NULL
,
policy
,
capacitance
,
plat_static_func
);
plat_static_func
);
}
}
EXPORT_SYMBOL
(
cpufreq_power_cooling_register
);
EXPORT_SYMBOL
(
cpufreq_power_cooling_register
);
...
@@ -985,7 +874,7 @@ EXPORT_SYMBOL(cpufreq_power_cooling_register);
...
@@ -985,7 +874,7 @@ EXPORT_SYMBOL(cpufreq_power_cooling_register);
/**
/**
* of_cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions
* of_cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions
* @np: a valid struct device_node to the cooling device device tree node
* @np: a valid struct device_node to the cooling device device tree node
* @
clip_cpus: cpumask of cpus where the frequency constraints will happen
* @
policy: cpufreq policy
* @capacitance: dynamic power coefficient for these cpus
* @capacitance: dynamic power coefficient for these cpus
* @plat_static_func: function to calculate the static power consumed by these
* @plat_static_func: function to calculate the static power consumed by these
* cpus (optional)
* cpus (optional)
...
@@ -1007,14 +896,14 @@ EXPORT_SYMBOL(cpufreq_power_cooling_register);
...
@@ -1007,14 +896,14 @@ EXPORT_SYMBOL(cpufreq_power_cooling_register);
*/
*/
struct
thermal_cooling_device
*
struct
thermal_cooling_device
*
of_cpufreq_power_cooling_register
(
struct
device_node
*
np
,
of_cpufreq_power_cooling_register
(
struct
device_node
*
np
,
const
struct
cpumask
*
clip_cpus
,
struct
cpufreq_policy
*
policy
,
u32
capacitance
,
u32
capacitance
,
get_static_t
plat_static_func
)
get_static_t
plat_static_func
)
{
{
if
(
!
np
)
if
(
!
np
)
return
ERR_PTR
(
-
EINVAL
);
return
ERR_PTR
(
-
EINVAL
);
return
__cpufreq_cooling_register
(
np
,
clip_cpus
,
capacitance
,
return
__cpufreq_cooling_register
(
np
,
policy
,
capacitance
,
plat_static_func
);
plat_static_func
);
}
}
EXPORT_SYMBOL
(
of_cpufreq_power_cooling_register
);
EXPORT_SYMBOL
(
of_cpufreq_power_cooling_register
);
...
@@ -1027,30 +916,28 @@ EXPORT_SYMBOL(of_cpufreq_power_cooling_register);
...
@@ -1027,30 +916,28 @@ EXPORT_SYMBOL(of_cpufreq_power_cooling_register);
*/
*/
void
cpufreq_cooling_unregister
(
struct
thermal_cooling_device
*
cdev
)
void
cpufreq_cooling_unregister
(
struct
thermal_cooling_device
*
cdev
)
{
{
struct
cpufreq_cooling_device
*
cpufreq_dev
;
struct
cpufreq_cooling_device
*
cpufreq_
c
dev
;
bool
last
;
bool
last
;
if
(
!
cdev
)
if
(
!
cdev
)
return
;
return
;
cpufreq_dev
=
cdev
->
devdata
;
cpufreq_
c
dev
=
cdev
->
devdata
;
mutex_lock
(
&
cooling_list_lock
);
mutex_lock
(
&
cooling_list_lock
);
list_del
(
&
cpufreq_dev
->
node
);
list_del
(
&
cpufreq_
c
dev
->
node
);
/* Unregister the notifier for the last cpufreq cooling device */
/* Unregister the notifier for the last cpufreq cooling device */
last
=
list_empty
(
&
cpufreq_dev_list
);
last
=
list_empty
(
&
cpufreq_
c
dev_list
);
mutex_unlock
(
&
cooling_list_lock
);
mutex_unlock
(
&
cooling_list_lock
);
if
(
last
)
if
(
last
)
cpufreq_unregister_notifier
(
&
thermal_cpufreq_notifier_block
,
cpufreq_unregister_notifier
(
&
thermal_cpufreq_notifier_block
,
CPUFREQ_POLICY_NOTIFIER
);
CPUFREQ_POLICY_NOTIFIER
);
thermal_cooling_device_unregister
(
cpufreq_dev
->
cool_dev
);
thermal_cooling_device_unregister
(
cpufreq_cdev
->
cdev
);
ida_simple_remove
(
&
cpufreq_ida
,
cpufreq_dev
->
id
);
ida_simple_remove
(
&
cpufreq_ida
,
cpufreq_cdev
->
id
);
kfree
(
cpufreq_dev
->
dyn_power_table
);
kfree
(
cpufreq_cdev
->
idle_time
);
kfree
(
cpufreq_dev
->
time_in_idle_timestamp
);
kfree
(
cpufreq_cdev
->
freq_table
);
kfree
(
cpufreq_dev
->
time_in_idle
);
kfree
(
cpufreq_cdev
);
kfree
(
cpufreq_dev
->
freq_table
);
kfree
(
cpufreq_dev
);
}
}
EXPORT_SYMBOL_GPL
(
cpufreq_cooling_unregister
);
EXPORT_SYMBOL_GPL
(
cpufreq_cooling_unregister
);
drivers/thermal/hisi_thermal.c
浏览文件 @
5d72ed35
...
@@ -397,8 +397,11 @@ static int hisi_thermal_suspend(struct device *dev)
...
@@ -397,8 +397,11 @@ static int hisi_thermal_suspend(struct device *dev)
static
int
hisi_thermal_resume
(
struct
device
*
dev
)
static
int
hisi_thermal_resume
(
struct
device
*
dev
)
{
{
struct
hisi_thermal_data
*
data
=
dev_get_drvdata
(
dev
);
struct
hisi_thermal_data
*
data
=
dev_get_drvdata
(
dev
);
int
ret
;
clk_prepare_enable
(
data
->
clk
);
ret
=
clk_prepare_enable
(
data
->
clk
);
if
(
ret
)
return
ret
;
data
->
irq_enabled
=
true
;
data
->
irq_enabled
=
true
;
hisi_thermal_enable_bind_irq_sensor
(
data
);
hisi_thermal_enable_bind_irq_sensor
(
data
);
...
...
drivers/thermal/imx_thermal.c
浏览文件 @
5d72ed35
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
*/
*/
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/cpu_cooling.h>
#include <linux/cpu_cooling.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/device.h>
...
@@ -88,6 +89,7 @@ static struct thermal_soc_data thermal_imx6sx_data = {
...
@@ -88,6 +89,7 @@ static struct thermal_soc_data thermal_imx6sx_data = {
};
};
struct
imx_thermal_data
{
struct
imx_thermal_data
{
struct
cpufreq_policy
*
policy
;
struct
thermal_zone_device
*
tz
;
struct
thermal_zone_device
*
tz
;
struct
thermal_cooling_device
*
cdev
;
struct
thermal_cooling_device
*
cdev
;
enum
thermal_device_mode
mode
;
enum
thermal_device_mode
mode
;
...
@@ -525,13 +527,18 @@ static int imx_thermal_probe(struct platform_device *pdev)
...
@@ -525,13 +527,18 @@ static int imx_thermal_probe(struct platform_device *pdev)
regmap_write
(
map
,
MISC0
+
REG_SET
,
MISC0_REFTOP_SELBIASOFF
);
regmap_write
(
map
,
MISC0
+
REG_SET
,
MISC0_REFTOP_SELBIASOFF
);
regmap_write
(
map
,
TEMPSENSE0
+
REG_SET
,
TEMPSENSE0_POWER_DOWN
);
regmap_write
(
map
,
TEMPSENSE0
+
REG_SET
,
TEMPSENSE0_POWER_DOWN
);
data
->
cdev
=
cpufreq_cooling_register
(
cpu_present_mask
);
data
->
policy
=
cpufreq_cpu_get
(
0
);
if
(
!
data
->
policy
)
{
pr_debug
(
"%s: CPUFreq policy not found
\n
"
,
__func__
);
return
-
EPROBE_DEFER
;
}
data
->
cdev
=
cpufreq_cooling_register
(
data
->
policy
);
if
(
IS_ERR
(
data
->
cdev
))
{
if
(
IS_ERR
(
data
->
cdev
))
{
ret
=
PTR_ERR
(
data
->
cdev
);
ret
=
PTR_ERR
(
data
->
cdev
);
if
(
ret
!=
-
EPROBE_DEFER
)
dev_err
(
&
pdev
->
dev
,
dev_err
(
&
pdev
->
dev
,
"failed to register cpufreq cooling device: %d
\n
"
,
"failed to register cpufreq cooling device: %d
\n
"
,
ret
);
ret
);
cpufreq_cpu_put
(
data
->
policy
);
return
ret
;
return
ret
;
}
}
...
@@ -542,6 +549,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
...
@@ -542,6 +549,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
dev_err
(
&
pdev
->
dev
,
dev_err
(
&
pdev
->
dev
,
"failed to get thermal clk: %d
\n
"
,
ret
);
"failed to get thermal clk: %d
\n
"
,
ret
);
cpufreq_cooling_unregister
(
data
->
cdev
);
cpufreq_cooling_unregister
(
data
->
cdev
);
cpufreq_cpu_put
(
data
->
policy
);
return
ret
;
return
ret
;
}
}
...
@@ -556,6 +564,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
...
@@ -556,6 +564,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to enable thermal clk: %d
\n
"
,
ret
);
dev_err
(
&
pdev
->
dev
,
"failed to enable thermal clk: %d
\n
"
,
ret
);
cpufreq_cooling_unregister
(
data
->
cdev
);
cpufreq_cooling_unregister
(
data
->
cdev
);
cpufreq_cpu_put
(
data
->
policy
);
return
ret
;
return
ret
;
}
}
...
@@ -571,6 +580,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
...
@@ -571,6 +580,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
"failed to register thermal zone device %d
\n
"
,
ret
);
"failed to register thermal zone device %d
\n
"
,
ret
);
clk_disable_unprepare
(
data
->
thermal_clk
);
clk_disable_unprepare
(
data
->
thermal_clk
);
cpufreq_cooling_unregister
(
data
->
cdev
);
cpufreq_cooling_unregister
(
data
->
cdev
);
cpufreq_cpu_put
(
data
->
policy
);
return
ret
;
return
ret
;
}
}
...
@@ -599,6 +609,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
...
@@ -599,6 +609,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
clk_disable_unprepare
(
data
->
thermal_clk
);
clk_disable_unprepare
(
data
->
thermal_clk
);
thermal_zone_device_unregister
(
data
->
tz
);
thermal_zone_device_unregister
(
data
->
tz
);
cpufreq_cooling_unregister
(
data
->
cdev
);
cpufreq_cooling_unregister
(
data
->
cdev
);
cpufreq_cpu_put
(
data
->
policy
);
return
ret
;
return
ret
;
}
}
...
@@ -620,6 +631,7 @@ static int imx_thermal_remove(struct platform_device *pdev)
...
@@ -620,6 +631,7 @@ static int imx_thermal_remove(struct platform_device *pdev)
thermal_zone_device_unregister
(
data
->
tz
);
thermal_zone_device_unregister
(
data
->
tz
);
cpufreq_cooling_unregister
(
data
->
cdev
);
cpufreq_cooling_unregister
(
data
->
cdev
);
cpufreq_cpu_put
(
data
->
policy
);
return
0
;
return
0
;
}
}
...
@@ -648,8 +660,11 @@ static int imx_thermal_resume(struct device *dev)
...
@@ -648,8 +660,11 @@ static int imx_thermal_resume(struct device *dev)
{
{
struct
imx_thermal_data
*
data
=
dev_get_drvdata
(
dev
);
struct
imx_thermal_data
*
data
=
dev_get_drvdata
(
dev
);
struct
regmap
*
map
=
data
->
tempmon
;
struct
regmap
*
map
=
data
->
tempmon
;
int
ret
;
clk_prepare_enable
(
data
->
thermal_clk
);
ret
=
clk_prepare_enable
(
data
->
thermal_clk
);
if
(
ret
)
return
ret
;
/* Enabled thermal sensor after resume */
/* Enabled thermal sensor after resume */
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
);
...
...
drivers/thermal/int340x_thermal/acpi_thermal_rel.c
浏览文件 @
5d72ed35
...
@@ -62,8 +62,8 @@ static int acpi_thermal_rel_release(struct inode *inode, struct file *file)
...
@@ -62,8 +62,8 @@ static int acpi_thermal_rel_release(struct inode *inode, struct file *file)
* acpi_parse_trt - Thermal Relationship Table _TRT for passive cooling
* acpi_parse_trt - Thermal Relationship Table _TRT for passive cooling
*
*
* @handle: ACPI handle of the device contains _TRT
* @handle: ACPI handle of the device contains _TRT
* @
a
rt_count: the number of valid entries resulted from parsing _TRT
* @
t
rt_count: the number of valid entries resulted from parsing _TRT
* @
artp: pointer to pointer of array of art
entries in parsing result
* @
trtp: pointer to pointer of array of _TRT
entries in parsing result
* @create_dev: whether to create platform devices for target and source
* @create_dev: whether to create platform devices for target and source
*
*
*/
*/
...
@@ -208,7 +208,7 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
...
@@ -208,7 +208,7 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
if
(
art
->
target
)
{
if
(
art
->
target
)
{
result
=
acpi_bus_get_device
(
art
->
target
,
&
adev
);
result
=
acpi_bus_get_device
(
art
->
target
,
&
adev
);
if
(
result
)
if
(
result
)
pr_warn
(
"Failed to get
source
ACPI device
\n
"
);
pr_warn
(
"Failed to get
target
ACPI device
\n
"
);
}
}
}
}
...
...
drivers/thermal/int340x_thermal/int3403_thermal.c
浏览文件 @
5d72ed35
...
@@ -237,9 +237,17 @@ static int int3403_add(struct platform_device *pdev)
...
@@ -237,9 +237,17 @@ static int int3403_add(struct platform_device *pdev)
status
=
acpi_evaluate_integer
(
priv
->
adev
->
handle
,
"PTYP"
,
status
=
acpi_evaluate_integer
(
priv
->
adev
->
handle
,
"PTYP"
,
NULL
,
&
priv
->
type
);
NULL
,
&
priv
->
type
);
if
(
ACPI_FAILURE
(
status
))
{
unsigned
long
long
tmp
;
status
=
acpi_evaluate_integer
(
priv
->
adev
->
handle
,
"_TMP"
,
NULL
,
&
tmp
);
if
(
ACPI_FAILURE
(
status
))
{
if
(
ACPI_FAILURE
(
status
))
{
result
=
-
EINVAL
;
result
=
-
EINVAL
;
goto
err
;
goto
err
;
}
else
{
priv
->
type
=
INT3403_TYPE_SENSOR
;
}
}
}
platform_set_drvdata
(
pdev
,
priv
);
platform_set_drvdata
(
pdev
,
priv
);
...
...
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
浏览文件 @
5d72ed35
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>
#include <linux/workqueue.h>
#include <linux/thermal.h>
#include <linux/thermal.h>
#include <linux/cpufreq.h>
#include <linux/cpumask.h>
#include <linux/cpumask.h>
#include <linux/cpu_cooling.h>
#include <linux/cpu_cooling.h>
#include <linux/of.h>
#include <linux/of.h>
...
@@ -37,6 +38,7 @@
...
@@ -37,6 +38,7 @@
/* common data structures */
/* common data structures */
struct
ti_thermal_data
{
struct
ti_thermal_data
{
struct
cpufreq_policy
*
policy
;
struct
thermal_zone_device
*
ti_thermal
;
struct
thermal_zone_device
*
ti_thermal
;
struct
thermal_zone_device
*
pcb_tz
;
struct
thermal_zone_device
*
pcb_tz
;
struct
thermal_cooling_device
*
cool_dev
;
struct
thermal_cooling_device
*
cool_dev
;
...
@@ -247,15 +249,19 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
...
@@ -247,15 +249,19 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
if
(
!
data
)
if
(
!
data
)
return
-
EINVAL
;
return
-
EINVAL
;
data
->
policy
=
cpufreq_cpu_get
(
0
);
if
(
!
data
->
policy
)
{
pr_debug
(
"%s: CPUFreq policy not found
\n
"
,
__func__
);
return
-
EPROBE_DEFER
;
}
/* Register cooling device */
/* Register cooling device */
data
->
cool_dev
=
cpufreq_cooling_register
(
cpu_present_mask
);
data
->
cool_dev
=
cpufreq_cooling_register
(
data
->
policy
);
if
(
IS_ERR
(
data
->
cool_dev
))
{
if
(
IS_ERR
(
data
->
cool_dev
))
{
int
ret
=
PTR_ERR
(
data
->
cool_dev
);
int
ret
=
PTR_ERR
(
data
->
cool_dev
);
dev_err
(
bgp
->
dev
,
"Failed to register cpu cooling device %d
\n
"
,
if
(
ret
!=
-
EPROBE_DEFER
)
dev_err
(
bgp
->
dev
,
"Failed to register cpu cooling device %d
\n
"
,
ret
);
ret
);
cpufreq_cpu_put
(
data
->
policy
);
return
ret
;
return
ret
;
}
}
...
@@ -270,8 +276,10 @@ int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id)
...
@@ -270,8 +276,10 @@ int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id)
data
=
ti_bandgap_get_sensor_data
(
bgp
,
id
);
data
=
ti_bandgap_get_sensor_data
(
bgp
,
id
);
if
(
data
)
if
(
data
)
{
cpufreq_cooling_unregister
(
data
->
cool_dev
);
cpufreq_cooling_unregister
(
data
->
cool_dev
);
cpufreq_cpu_put
(
data
->
policy
);
}
return
0
;
return
0
;
}
}
include/linux/cpu_cooling.h
浏览文件 @
5d72ed35
...
@@ -28,47 +28,49 @@
...
@@ -28,47 +28,49 @@
#include <linux/thermal.h>
#include <linux/thermal.h>
#include <linux/cpumask.h>
#include <linux/cpumask.h>
struct
cpufreq_policy
;
typedef
int
(
*
get_static_t
)(
cpumask_t
*
cpumask
,
int
interval
,
typedef
int
(
*
get_static_t
)(
cpumask_t
*
cpumask
,
int
interval
,
unsigned
long
voltage
,
u32
*
power
);
unsigned
long
voltage
,
u32
*
power
);
#ifdef CONFIG_CPU_THERMAL
#ifdef CONFIG_CPU_THERMAL
/**
/**
* cpufreq_cooling_register - function to create cpufreq cooling device.
* cpufreq_cooling_register - function to create cpufreq cooling device.
* @
clip_cpus: cpumask of cpus where the frequency constraints will happen
* @
policy: cpufreq policy.
*/
*/
struct
thermal_cooling_device
*
struct
thermal_cooling_device
*
cpufreq_cooling_register
(
const
struct
cpumask
*
clip_cpus
);
cpufreq_cooling_register
(
struct
cpufreq_policy
*
policy
);
struct
thermal_cooling_device
*
struct
thermal_cooling_device
*
cpufreq_power_cooling_register
(
const
struct
cpumask
*
clip_cpus
,
cpufreq_power_cooling_register
(
struct
cpufreq_policy
*
policy
,
u32
capacitance
,
get_static_t
plat_static_func
);
u32
capacitance
,
get_static_t
plat_static_func
);
/**
/**
* of_cpufreq_cooling_register - create cpufreq cooling device based on DT.
* of_cpufreq_cooling_register - create cpufreq cooling device based on DT.
* @np: a valid struct device_node to the cooling device device tree node.
* @np: a valid struct device_node to the cooling device device tree node.
* @
clip_cpus: cpumask of cpus where the frequency constraints will happen
* @
policy: cpufreq policy.
*/
*/
#ifdef CONFIG_THERMAL_OF
#ifdef CONFIG_THERMAL_OF
struct
thermal_cooling_device
*
struct
thermal_cooling_device
*
of_cpufreq_cooling_register
(
struct
device_node
*
np
,
of_cpufreq_cooling_register
(
struct
device_node
*
np
,
const
struct
cpumask
*
clip_cpus
);
struct
cpufreq_policy
*
policy
);
struct
thermal_cooling_device
*
struct
thermal_cooling_device
*
of_cpufreq_power_cooling_register
(
struct
device_node
*
np
,
of_cpufreq_power_cooling_register
(
struct
device_node
*
np
,
const
struct
cpumask
*
clip_cpus
,
struct
cpufreq_policy
*
policy
,
u32
capacitance
,
u32
capacitance
,
get_static_t
plat_static_func
);
get_static_t
plat_static_func
);
#else
#else
static
inline
struct
thermal_cooling_device
*
static
inline
struct
thermal_cooling_device
*
of_cpufreq_cooling_register
(
struct
device_node
*
np
,
of_cpufreq_cooling_register
(
struct
device_node
*
np
,
const
struct
cpumask
*
clip_cpus
)
struct
cpufreq_policy
*
policy
)
{
{
return
ERR_PTR
(
-
ENOSYS
);
return
ERR_PTR
(
-
ENOSYS
);
}
}
static
inline
struct
thermal_cooling_device
*
static
inline
struct
thermal_cooling_device
*
of_cpufreq_power_cooling_register
(
struct
device_node
*
np
,
of_cpufreq_power_cooling_register
(
struct
device_node
*
np
,
const
struct
cpumask
*
clip_cpus
,
struct
cpufreq_policy
*
policy
,
u32
capacitance
,
u32
capacitance
,
get_static_t
plat_static_func
)
get_static_t
plat_static_func
)
{
{
...
@@ -82,15 +84,14 @@ of_cpufreq_power_cooling_register(struct device_node *np,
...
@@ -82,15 +84,14 @@ of_cpufreq_power_cooling_register(struct device_node *np,
*/
*/
void
cpufreq_cooling_unregister
(
struct
thermal_cooling_device
*
cdev
);
void
cpufreq_cooling_unregister
(
struct
thermal_cooling_device
*
cdev
);
unsigned
long
cpufreq_cooling_get_level
(
unsigned
int
cpu
,
unsigned
int
freq
);
#else
/* !CONFIG_CPU_THERMAL */
#else
/* !CONFIG_CPU_THERMAL */
static
inline
struct
thermal_cooling_device
*
static
inline
struct
thermal_cooling_device
*
cpufreq_cooling_register
(
const
struct
cpumask
*
clip_cpus
)
cpufreq_cooling_register
(
struct
cpufreq_policy
*
policy
)
{
{
return
ERR_PTR
(
-
ENOSYS
);
return
ERR_PTR
(
-
ENOSYS
);
}
}
static
inline
struct
thermal_cooling_device
*
static
inline
struct
thermal_cooling_device
*
cpufreq_power_cooling_register
(
const
struct
cpumask
*
clip_cpus
,
cpufreq_power_cooling_register
(
struct
cpufreq_policy
*
policy
,
u32
capacitance
,
get_static_t
plat_static_func
)
u32
capacitance
,
get_static_t
plat_static_func
)
{
{
return
NULL
;
return
NULL
;
...
@@ -98,14 +99,14 @@ cpufreq_power_cooling_register(const struct cpumask *clip_cpus,
...
@@ -98,14 +99,14 @@ cpufreq_power_cooling_register(const struct cpumask *clip_cpus,
static
inline
struct
thermal_cooling_device
*
static
inline
struct
thermal_cooling_device
*
of_cpufreq_cooling_register
(
struct
device_node
*
np
,
of_cpufreq_cooling_register
(
struct
device_node
*
np
,
const
struct
cpumask
*
clip_cpus
)
struct
cpufreq_policy
*
policy
)
{
{
return
ERR_PTR
(
-
ENOSYS
);
return
ERR_PTR
(
-
ENOSYS
);
}
}
static
inline
struct
thermal_cooling_device
*
static
inline
struct
thermal_cooling_device
*
of_cpufreq_power_cooling_register
(
struct
device_node
*
np
,
of_cpufreq_power_cooling_register
(
struct
device_node
*
np
,
const
struct
cpumask
*
clip_cpus
,
struct
cpufreq_policy
*
policy
,
u32
capacitance
,
u32
capacitance
,
get_static_t
plat_static_func
)
get_static_t
plat_static_func
)
{
{
...
@@ -117,11 +118,6 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
...
@@ -117,11 +118,6 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
{
{
return
;
return
;
}
}
static
inline
unsigned
long
cpufreq_cooling_get_level
(
unsigned
int
cpu
,
unsigned
int
freq
)
{
return
THERMAL_CSTATE_INVALID
;
}
#endif
/* CONFIG_CPU_THERMAL */
#endif
/* CONFIG_CPU_THERMAL */
#endif
/* __CPU_COOLING_H__ */
#endif
/* __CPU_COOLING_H__ */
include/linux/cpufreq.h
浏览文件 @
5d72ed35
...
@@ -862,6 +862,20 @@ static inline int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
...
@@ -862,6 +862,20 @@ static inline int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
return
-
EINVAL
;
return
-
EINVAL
;
}
}
}
}
static
inline
int
cpufreq_table_count_valid_entries
(
const
struct
cpufreq_policy
*
policy
)
{
struct
cpufreq_frequency_table
*
pos
;
int
count
=
0
;
if
(
unlikely
(
!
policy
->
freq_table
))
return
0
;
cpufreq_for_each_valid_entry
(
pos
,
policy
->
freq_table
)
count
++
;
return
count
;
}
#else
#else
static
inline
int
cpufreq_boost_trigger_state
(
int
state
)
static
inline
int
cpufreq_boost_trigger_state
(
int
state
)
{
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录