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
7429b1e0
Commit
7429b1e0
authored
Dec 24, 2014
by
Zhang Rui
Browse files
Options
Browse Files
Download
Plain Diff
Merge branches 'thermal-core', 'thermal-soc' and 'thermal-int340x' of .git into next
parents
fc4de356
0733d138
f8061d38
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
496 additions
and
276 deletions
+496
-276
drivers/thermal/cpu_cooling.c
drivers/thermal/cpu_cooling.c
+135
-224
drivers/thermal/db8500_cpufreq_cooling.c
drivers/thermal/db8500_cpufreq_cooling.c
+9
-11
drivers/thermal/imx_thermal.c
drivers/thermal/imx_thermal.c
+5
-10
drivers/thermal/int340x_thermal/Makefile
drivers/thermal/int340x_thermal/Makefile
+1
-0
drivers/thermal/int340x_thermal/acpi_thermal_rel.c
drivers/thermal/int340x_thermal/acpi_thermal_rel.c
+4
-4
drivers/thermal/int340x_thermal/int3400_thermal.c
drivers/thermal/int340x_thermal/int3400_thermal.c
+0
-1
drivers/thermal/int340x_thermal/int3402_thermal.c
drivers/thermal/int340x_thermal/int3402_thermal.c
+0
-1
drivers/thermal/int340x_thermal/int3403_thermal.c
drivers/thermal/int340x_thermal/int3403_thermal.c
+4
-0
drivers/thermal/int340x_thermal/processor_thermal_device.c
drivers/thermal/int340x_thermal/processor_thermal_device.c
+309
-0
drivers/thermal/intel_powerclamp.c
drivers/thermal/intel_powerclamp.c
+1
-0
drivers/thermal/rockchip_thermal.c
drivers/thermal/rockchip_thermal.c
+0
-1
drivers/thermal/samsung/Kconfig
drivers/thermal/samsung/Kconfig
+1
-1
drivers/thermal/samsung/exynos_thermal_common.c
drivers/thermal/samsung/exynos_thermal_common.c
+6
-6
drivers/thermal/samsung/exynos_tmu.c
drivers/thermal/samsung/exynos_tmu.c
+4
-1
drivers/thermal/thermal_core.c
drivers/thermal/thermal_core.c
+4
-2
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+8
-9
include/dt-bindings/thermal/thermal.h
include/dt-bindings/thermal/thermal.h
+1
-1
include/linux/cpu_cooling.h
include/linux/cpu_cooling.h
+3
-3
include/linux/thermal.h
include/linux/thermal.h
+1
-1
No files found.
drivers/thermal/cpu_cooling.c
View file @
7429b1e0
...
@@ -4,6 +4,8 @@
...
@@ -4,6 +4,8 @@
* Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
* Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
* Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
* Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
*
*
* Copyright (C) 2014 Viresh Kumar <viresh.kumar@linaro.org>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
...
@@ -28,6 +30,20 @@
...
@@ -28,6 +30,20 @@
#include <linux/cpu.h>
#include <linux/cpu.h>
#include <linux/cpu_cooling.h>
#include <linux/cpu_cooling.h>
/*
* Cooling state <-> CPUFreq frequency
*
* Cooling states are translated to frequencies throughout this driver and this
* is the relation between them.
*
* Highest cooling state corresponds to lowest possible frequency.
*
* i.e.
* level 0 --> 1st Max Freq
* level 1 --> 2nd Max Freq
* ...
*/
/**
/**
* 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
...
@@ -38,26 +54,27 @@
...
@@ -38,26 +54,27 @@
* cooling devices.
* cooling devices.
* @cpufreq_val: integer value representing the absolute value of the clipped
* @cpufreq_val: integer value representing the absolute value of the clipped
* frequency.
* frequency.
* @max_level: maximum cooling level. One less than total number of valid
* cpufreq frequencies.
* @allowed_cpus: all the cpus involved for this cpufreq_cooling_device.
* @allowed_cpus: all the cpus involved for this cpufreq_cooling_device.
* @node: list_head to link all cpufreq_cooling_device together.
* @node: list_head to link all cpufreq_cooling_device together.
*
*
* This structure is required for keeping information of each
* This structure is required for keeping information of each registered
* cpufreq_cooling_device registered. In order to prevent corruption of this a
* cpufreq_cooling_device.
* mutex lock cooling_cpufreq_lock is used.
*/
*/
struct
cpufreq_cooling_device
{
struct
cpufreq_cooling_device
{
int
id
;
int
id
;
struct
thermal_cooling_device
*
cool_dev
;
struct
thermal_cooling_device
*
cool_dev
;
unsigned
int
cpufreq_state
;
unsigned
int
cpufreq_state
;
unsigned
int
cpufreq_val
;
unsigned
int
cpufreq_val
;
unsigned
int
max_level
;
unsigned
int
*
freq_table
;
/* In descending order */
struct
cpumask
allowed_cpus
;
struct
cpumask
allowed_cpus
;
struct
list_head
node
;
struct
list_head
node
;
};
};
static
DEFINE_IDR
(
cpufreq_idr
);
static
DEFINE_IDR
(
cpufreq_idr
);
static
DEFINE_MUTEX
(
cooling_cpufreq_lock
);
static
DEFINE_MUTEX
(
cooling_cpufreq_lock
);
static
unsigned
int
cpufreq_dev_count
;
static
LIST_HEAD
(
cpufreq_dev_list
);
static
LIST_HEAD
(
cpufreq_dev_list
);
/**
/**
...
@@ -99,120 +116,30 @@ static void release_idr(struct idr *idr, int id)
...
@@ -99,120 +116,30 @@ static void release_idr(struct idr *idr, int id)
/* Below code defines functions to be used for cpufreq as cooling device */
/* Below code defines functions to be used for cpufreq as cooling device */
/**
/**
* is_cpufreq_valid - function to check frequency transitioning capability.
* get_level: Find the level for a particular frequency
* @cpu: cpu for which check is needed.
* @cpufreq_dev: cpufreq_dev for which the property is required
*
* @freq: Frequency
* This function will check the current state of the system if
* it is capable of changing the frequency for a given @cpu.
*
*
* Return: 0 if the system is not currently capable of changing
* Return: level on success, THERMAL_CSTATE_INVALID on error.
* the frequency of given cpu. !0 in case the frequency is changeable.
*/
*/
static
int
is_cpufreq_valid
(
int
cpu
)
static
unsigned
long
get_level
(
struct
cpufreq_cooling_device
*
cpufreq_dev
,
unsigned
int
freq
)
{
{
struct
cpufreq_policy
policy
;
unsigned
long
level
;
return
!
cpufreq_get_policy
(
&
policy
,
cpu
);
for
(
level
=
0
;
level
<=
cpufreq_dev
->
max_level
;
level
++
)
{
}
if
(
freq
==
cpufreq_dev
->
freq_table
[
level
])
return
level
;
enum
cpufreq_cooling_property
{
GET_LEVEL
,
GET_FREQ
,
GET_MAXL
,
};
/**
if
(
freq
>
cpufreq_dev
->
freq_table
[
level
])
* get_property - fetch a property of interest for a give cpu.
break
;
* @cpu: cpu for which the property is required
* @input: query parameter
* @output: query return
* @property: type of query (frequency, level, max level)
*
* This is the common function to
* 1. get maximum cpu cooling states
* 2. translate frequency to cooling state
* 3. translate cooling state to frequency
* Note that the code may be not in good shape
* but it is written in this way in order to:
* a) reduce duplicate code as most of the code can be shared.
* b) make sure the logic is consistent when translating between
* cooling states and frequencies.
*
* Return: 0 on success, -EINVAL when invalid parameters are passed.
*/
static
int
get_property
(
unsigned
int
cpu
,
unsigned
long
input
,
unsigned
int
*
output
,
enum
cpufreq_cooling_property
property
)
{
int
i
;
unsigned
long
max_level
=
0
,
level
=
0
;
unsigned
int
freq
=
CPUFREQ_ENTRY_INVALID
;
int
descend
=
-
1
;
struct
cpufreq_frequency_table
*
pos
,
*
table
=
cpufreq_frequency_get_table
(
cpu
);
if
(
!
output
)
return
-
EINVAL
;
if
(
!
table
)
return
-
EINVAL
;
cpufreq_for_each_valid_entry
(
pos
,
table
)
{
/* ignore duplicate entry */
if
(
freq
==
pos
->
frequency
)
continue
;
/* get the frequency order */
if
(
freq
!=
CPUFREQ_ENTRY_INVALID
&&
descend
==
-
1
)
descend
=
freq
>
pos
->
frequency
;
freq
=
pos
->
frequency
;
max_level
++
;
}
}
/* No valid cpu frequency entry */
return
THERMAL_CSTATE_INVALID
;
if
(
max_level
==
0
)
return
-
EINVAL
;
/* max_level is an index, not a counter */
max_level
--
;
/* get max level */
if
(
property
==
GET_MAXL
)
{
*
output
=
(
unsigned
int
)
max_level
;
return
0
;
}
if
(
property
==
GET_FREQ
)
level
=
descend
?
input
:
(
max_level
-
input
);
i
=
0
;
cpufreq_for_each_valid_entry
(
pos
,
table
)
{
/* ignore duplicate entry */
if
(
freq
==
pos
->
frequency
)
continue
;
/* now we have a valid frequency entry */
freq
=
pos
->
frequency
;
if
(
property
==
GET_LEVEL
&&
(
unsigned
int
)
input
==
freq
)
{
/* get level by frequency */
*
output
=
descend
?
i
:
(
max_level
-
i
);
return
0
;
}
if
(
property
==
GET_FREQ
&&
level
==
i
)
{
/* get frequency by level */
*
output
=
freq
;
return
0
;
}
i
++
;
}
return
-
EINVAL
;
}
}
/**
/**
* cpufreq_cooling_get_level - for a give cpu, return the cooling level.
* cpufreq_cooling_get_level - for a give
n
cpu, return the cooling level.
* @cpu: cpu for which the level is required
* @cpu: cpu for which the level is required
* @freq: the frequency of interest
* @freq: the frequency of interest
*
*
...
@@ -224,77 +151,21 @@ static int get_property(unsigned int cpu, unsigned long input,
...
@@ -224,77 +151,21 @@ static int get_property(unsigned int cpu, unsigned long input,
*/
*/
unsigned
long
cpufreq_cooling_get_level
(
unsigned
int
cpu
,
unsigned
int
freq
)
unsigned
long
cpufreq_cooling_get_level
(
unsigned
int
cpu
,
unsigned
int
freq
)
{
{
unsigned
int
val
;
struct
cpufreq_cooling_device
*
cpufreq_dev
;
if
(
get_property
(
cpu
,
(
unsigned
long
)
freq
,
&
val
,
GET_LEVEL
))
return
THERMAL_CSTATE_INVALID
;
return
(
unsigned
long
)
val
;
}
EXPORT_SYMBOL_GPL
(
cpufreq_cooling_get_level
);
/**
* get_cpu_frequency - get the absolute value of frequency from level.
* @cpu: cpu for which frequency is fetched.
* @level: cooling level
*
* This function matches cooling level with frequency. Based on a cooling level
* of frequency, equals cooling state of cpu cooling device, it will return
* the corresponding frequency.
* e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc
*
* Return: 0 on error, the corresponding frequency otherwise.
*/
static
unsigned
int
get_cpu_frequency
(
unsigned
int
cpu
,
unsigned
long
level
)
{
int
ret
=
0
;
unsigned
int
freq
;
ret
=
get_property
(
cpu
,
level
,
&
freq
,
GET_FREQ
);
if
(
ret
)
return
0
;
return
freq
;
}
/**
* cpufreq_apply_cooling - function to apply frequency clipping.
* @cpufreq_device: cpufreq_cooling_device pointer containing frequency
* clipping data.
* @cooling_state: value of the cooling state.
*
* Function used to make sure the cpufreq layer is aware of current thermal
* limits. The limits are applied by updating the cpufreq policy.
*
* Return: 0 on success, an error code otherwise (-EINVAL in case wrong
* cooling state).
*/
static
int
cpufreq_apply_cooling
(
struct
cpufreq_cooling_device
*
cpufreq_device
,
unsigned
long
cooling_state
)
{
unsigned
int
cpuid
,
clip_freq
;
struct
cpumask
*
mask
=
&
cpufreq_device
->
allowed_cpus
;
unsigned
int
cpu
=
cpumask_any
(
mask
);
/* Check if the old cooling action is same as new cooling action */
if
(
cpufreq_device
->
cpufreq_state
==
cooling_state
)
return
0
;
clip_freq
=
get_cpu_frequency
(
cpu
,
cooling_state
);
if
(
!
clip_freq
)
return
-
EINVAL
;
cpufreq_device
->
cpufreq_state
=
cooling_state
;
cpufreq_device
->
cpufreq_val
=
clip_freq
;
for_each_cpu
(
cpuid
,
mask
)
{
mutex_lock
(
&
cooling_cpufreq_lock
);
if
(
is_cpufreq_valid
(
cpuid
))
list_for_each_entry
(
cpufreq_dev
,
&
cpufreq_dev_list
,
node
)
{
cpufreq_update_policy
(
cpuid
);
if
(
cpumask_test_cpu
(
cpu
,
&
cpufreq_dev
->
allowed_cpus
))
{
mutex_unlock
(
&
cooling_cpufreq_lock
);
return
get_level
(
cpufreq_dev
,
freq
);
}
}
}
mutex_unlock
(
&
cooling_cpufreq_lock
);
return
0
;
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.
...
@@ -324,11 +195,6 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
...
@@ -324,11 +195,6 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
&
cpufreq_dev
->
allowed_cpus
))
&
cpufreq_dev
->
allowed_cpus
))
continue
;
continue
;
if
(
!
cpufreq_dev
->
cpufreq_val
)
cpufreq_dev
->
cpufreq_val
=
get_cpu_frequency
(
cpumask_any
(
&
cpufreq_dev
->
allowed_cpus
),
cpufreq_dev
->
cpufreq_state
);
max_freq
=
cpufreq_dev
->
cpufreq_val
;
max_freq
=
cpufreq_dev
->
cpufreq_val
;
if
(
policy
->
max
!=
max_freq
)
if
(
policy
->
max
!=
max_freq
)
...
@@ -355,19 +221,9 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
...
@@ -355,19 +221,9 @@ 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_device
=
cdev
->
devdata
;
struct
cpumask
*
mask
=
&
cpufreq_device
->
allowed_cpus
;
unsigned
int
cpu
;
unsigned
int
count
=
0
;
int
ret
;
cpu
=
cpumask_any
(
mask
);
*
state
=
cpufreq_device
->
max_level
;
return
0
;
ret
=
get_property
(
cpu
,
0
,
&
count
,
GET_MAXL
);
if
(
count
>
0
)
*
state
=
count
;
return
ret
;
}
}
/**
/**
...
@@ -404,8 +260,24 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
...
@@ -404,8 +260,24 @@ 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_device
=
cdev
->
devdata
;
unsigned
int
cpu
=
cpumask_any
(
&
cpufreq_device
->
allowed_cpus
);
unsigned
int
clip_freq
;
/* Request state should be less than max_level */
if
(
WARN_ON
(
state
>
cpufreq_device
->
max_level
))
return
-
EINVAL
;
/* Check if the old cooling action is same as new cooling action */
if
(
cpufreq_device
->
cpufreq_state
==
state
)
return
0
;
clip_freq
=
cpufreq_device
->
freq_table
[
state
];
cpufreq_device
->
cpufreq_state
=
state
;
cpufreq_device
->
cpufreq_val
=
clip_freq
;
return
cpufreq_apply_cooling
(
cpufreq_device
,
state
);
cpufreq_update_policy
(
cpu
);
return
0
;
}
}
/* Bind cpufreq callbacks to thermal cooling device ops */
/* Bind cpufreq callbacks to thermal cooling device ops */
...
@@ -420,10 +292,25 @@ static struct notifier_block thermal_cpufreq_notifier_block = {
...
@@ -420,10 +292,25 @@ static struct notifier_block thermal_cpufreq_notifier_block = {
.
notifier_call
=
cpufreq_thermal_notifier
,
.
notifier_call
=
cpufreq_thermal_notifier
,
};
};
static
unsigned
int
find_next_max
(
struct
cpufreq_frequency_table
*
table
,
unsigned
int
prev_max
)
{
struct
cpufreq_frequency_table
*
pos
;
unsigned
int
max
=
0
;
cpufreq_for_each_valid_entry
(
pos
,
table
)
{
if
(
pos
->
frequency
>
max
&&
pos
->
frequency
<
prev_max
)
max
=
pos
->
frequency
;
}
return
max
;
}
/**
/**
* __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.
* @clip_cpus: cpumask of cpus where the frequency constraints will happen.
* Normally this should be same as cpufreq policy->related_cpus.
*
*
* 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
...
@@ -438,37 +325,42 @@ __cpufreq_cooling_register(struct device_node *np,
...
@@ -438,37 +325,42 @@ __cpufreq_cooling_register(struct device_node *np,
const
struct
cpumask
*
clip_cpus
)
const
struct
cpumask
*
clip_cpus
)
{
{
struct
thermal_cooling_device
*
cool_dev
;
struct
thermal_cooling_device
*
cool_dev
;
struct
cpufreq_cooling_device
*
cpufreq_dev
=
NULL
;
struct
cpufreq_cooling_device
*
cpufreq_dev
;
unsigned
int
min
=
0
,
max
=
0
;
char
dev_name
[
THERMAL_NAME_LENGTH
];
char
dev_name
[
THERMAL_NAME_LENGTH
];
int
ret
=
0
,
i
;
struct
cpufreq_frequency_table
*
pos
,
*
table
;
struct
cpufreq_policy
policy
;
unsigned
int
freq
,
i
;
int
ret
;
/* Verify that all the clip cpus have same freq_min, freq_max limit */
table
=
cpufreq_frequency_get_table
(
cpumask_first
(
clip_cpus
));
for_each_cpu
(
i
,
clip_cpus
)
{
if
(
!
table
)
{
/* continue if cpufreq policy not found and not return error */
pr_debug
(
"%s: CPUFreq table not found
\n
"
,
__func__
);
if
(
!
cpufreq_get_policy
(
&
policy
,
i
))
return
ERR_PTR
(
-
EPROBE_DEFER
);
continue
;
if
(
min
==
0
&&
max
==
0
)
{
min
=
policy
.
cpuinfo
.
min_freq
;
max
=
policy
.
cpuinfo
.
max_freq
;
}
else
{
if
(
min
!=
policy
.
cpuinfo
.
min_freq
||
max
!=
policy
.
cpuinfo
.
max_freq
)
return
ERR_PTR
(
-
EINVAL
);
}
}
}
cpufreq_dev
=
kzalloc
(
sizeof
(
struct
cpufreq_cooling_device
),
GFP_KERNEL
);
cpufreq_dev
=
kzalloc
(
sizeof
(
*
cpufreq_dev
),
GFP_KERNEL
);
if
(
!
cpufreq_dev
)
if
(
!
cpufreq_dev
)
return
ERR_PTR
(
-
ENOMEM
);
return
ERR_PTR
(
-
ENOMEM
);
/* 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_cdev
;
}
/* max_level is an index, not a counter */
cpufreq_dev
->
max_level
--
;
cpumask_copy
(
&
cpufreq_dev
->
allowed_cpus
,
clip_cpus
);
cpumask_copy
(
&
cpufreq_dev
->
allowed_cpus
,
clip_cpus
);
ret
=
get_idr
(
&
cpufreq_idr
,
&
cpufreq_dev
->
id
);
ret
=
get_idr
(
&
cpufreq_idr
,
&
cpufreq_dev
->
id
);
if
(
ret
)
{
if
(
ret
)
{
kfree
(
cpufreq_dev
);
cool_dev
=
ERR_PTR
(
ret
);
return
ERR_PTR
(
-
EINVAL
)
;
goto
free_table
;
}
}
snprintf
(
dev_name
,
sizeof
(
dev_name
),
"thermal-cpufreq-%d"
,
snprintf
(
dev_name
,
sizeof
(
dev_name
),
"thermal-cpufreq-%d"
,
...
@@ -476,24 +368,43 @@ __cpufreq_cooling_register(struct device_node *np,
...
@@ -476,24 +368,43 @@ __cpufreq_cooling_register(struct device_node *np,
cool_dev
=
thermal_of_cooling_device_register
(
np
,
dev_name
,
cpufreq_dev
,
cool_dev
=
thermal_of_cooling_device_register
(
np
,
dev_name
,
cpufreq_dev
,
&
cpufreq_cooling_ops
);
&
cpufreq_cooling_ops
);
if
(
IS_ERR
(
cool_dev
))
{
if
(
IS_ERR
(
cool_dev
))
release_idr
(
&
cpufreq_idr
,
cpufreq_dev
->
id
);
goto
remove_idr
;
kfree
(
cpufreq_dev
);
return
cool_dev
;
/* Fill freq-table in descending order of frequencies */
for
(
i
=
0
,
freq
=
-
1
;
i
<=
cpufreq_dev
->
max_level
;
i
++
)
{
freq
=
find_next_max
(
table
,
freq
);
cpufreq_dev
->
freq_table
[
i
]
=
freq
;
/* Warn for duplicate entries */
if
(
!
freq
)
pr_warn
(
"%s: table has duplicate entries
\n
"
,
__func__
);
else
pr_debug
(
"%s: freq:%u KHz
\n
"
,
__func__
,
freq
);
}
}
cpufreq_dev
->
cpufreq_val
=
cpufreq_dev
->
freq_table
[
0
];
cpufreq_dev
->
cool_dev
=
cool_dev
;
cpufreq_dev
->
cool_dev
=
cool_dev
;
cpufreq_dev
->
cpufreq_state
=
0
;
mutex_lock
(
&
cooling_cpufreq_lock
);
mutex_lock
(
&
cooling_cpufreq_lock
);
/* Register the notifier for first cpufreq cooling device */
/* Register the notifier for first cpufreq cooling device */
if
(
cpufreq_dev_count
==
0
)
if
(
list_empty
(
&
cpufreq_dev_list
)
)
cpufreq_register_notifier
(
&
thermal_cpufreq_notifier_block
,
cpufreq_register_notifier
(
&
thermal_cpufreq_notifier_block
,
CPUFREQ_POLICY_NOTIFIER
);
CPUFREQ_POLICY_NOTIFIER
);
cpufreq_dev_count
++
;
list_add
(
&
cpufreq_dev
->
node
,
&
cpufreq_dev_list
);
list_add
(
&
cpufreq_dev
->
node
,
&
cpufreq_dev_list
);
mutex_unlock
(
&
cooling_cpufreq_lock
);
mutex_unlock
(
&
cooling_cpufreq_lock
);
return
cool_dev
;
remove_idr:
release_idr
(
&
cpufreq_idr
,
cpufreq_dev
->
id
);
free_table:
kfree
(
cpufreq_dev
->
freq_table
);
free_cdev:
kfree
(
cpufreq_dev
);
return
cool_dev
;
return
cool_dev
;
}
}
...
@@ -555,16 +466,16 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
...
@@ -555,16 +466,16 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
cpufreq_dev
=
cdev
->
devdata
;
cpufreq_dev
=
cdev
->
devdata
;
mutex_lock
(
&
cooling_cpufreq_lock
);
mutex_lock
(
&
cooling_cpufreq_lock
);
list_del
(
&
cpufreq_dev
->
node
);
list_del
(
&
cpufreq_dev
->
node
);
cpufreq_dev_count
--
;
/* Unregister the notifier for the last cpufreq cooling device */
/* Unregister the notifier for the last cpufreq cooling device */
if
(
cpufreq_dev_count
==
0
)
if
(
list_empty
(
&
cpufreq_dev_list
)
)
cpufreq_unregister_notifier
(
&
thermal_cpufreq_notifier_block
,
cpufreq_unregister_notifier
(
&
thermal_cpufreq_notifier_block
,
CPUFREQ_POLICY_NOTIFIER
);
CPUFREQ_POLICY_NOTIFIER
);
mutex_unlock
(
&
cooling_cpufreq_lock
);
mutex_unlock
(
&
cooling_cpufreq_lock
);
thermal_cooling_device_unregister
(
cpufreq_dev
->
cool_dev
);
thermal_cooling_device_unregister
(
cpufreq_dev
->
cool_dev
);
release_idr
(
&
cpufreq_idr
,
cpufreq_dev
->
id
);
release_idr
(
&
cpufreq_idr
,
cpufreq_dev
->
id
);
kfree
(
cpufreq_dev
->
freq_table
);
kfree
(
cpufreq_dev
);
kfree
(
cpufreq_dev
);
}
}
EXPORT_SYMBOL_GPL
(
cpufreq_cooling_unregister
);
EXPORT_SYMBOL_GPL
(
cpufreq_cooling_unregister
);
drivers/thermal/db8500_cpufreq_cooling.c
View file @
7429b1e0
...
@@ -18,7 +18,6 @@
...
@@ -18,7 +18,6 @@
*/
*/
#include <linux/cpu_cooling.h>
#include <linux/cpu_cooling.h>
#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of.h>
...
@@ -28,18 +27,17 @@
...
@@ -28,18 +27,17 @@
static
int
db8500_cpufreq_cooling_probe
(
struct
platform_device
*
pdev
)
static
int
db8500_cpufreq_cooling_probe
(
struct
platform_device
*
pdev
)
{
{
struct
thermal_cooling_device
*
cdev
;
struct
thermal_cooling_device
*
cdev
;
struct
cpumask
mask_val
;
/* make sure cpufreq driver has been initialized */
cdev
=
cpufreq_cooling_register
(
cpu_present_mask
);
if
(
!
cpufreq_frequency_get_table
(
0
))
if
(
IS_ERR
(
cdev
))
{
return
-
EPROBE_DEFER
;
int
ret
=
PTR_ERR
(
cdev
)
;
cpumask_set_cpu
(
0
,
&
mask_val
);
if
(
ret
!=
-
EPROBE_DEFER
)
cdev
=
cpufreq_cooling_register
(
&
mask_val
);
dev_err
(
&
pdev
->
dev
,
"Failed to register cooling device %d
\n
"
,
ret
);
if
(
IS_ERR
(
cdev
))
{
return
ret
;
dev_err
(
&
pdev
->
dev
,
"Failed to register cooling device
\n
"
);
return
PTR_ERR
(
cdev
);
}
}
platform_set_drvdata
(
pdev
,
cdev
);
platform_set_drvdata
(
pdev
,
cdev
);
...
...
drivers/thermal/imx_thermal.c
View file @
7429b1e0
...
@@ -9,7 +9,6 @@
...
@@ -9,7 +9,6 @@
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/cpu_cooling.h>
#include <linux/cpu_cooling.h>
#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/init.h>
...
@@ -454,15 +453,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
...
@@ -454,15 +453,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
const
struct
of_device_id
*
of_id
=
const
struct
of_device_id
*
of_id
=
of_match_device
(
of_imx_thermal_match
,
&
pdev
->
dev
);
of_match_device
(
of_imx_thermal_match
,
&
pdev
->
dev
);
struct
imx_thermal_data
*
data
;
struct
imx_thermal_data
*
data
;
struct
cpumask
clip_cpus
;
struct
regmap
*
map
;
struct
regmap
*
map
;
int
measure_freq
;
int
measure_freq
;
int
ret
;
int
ret
;
if
(
!
cpufreq_get_current_driver
())
{
dev_dbg
(
&
pdev
->
dev
,
"no cpufreq driver!"
);
return
-
EPROBE_DEFER
;
}
data
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
data
),
GFP_KERNEL
);
data
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
data
),
GFP_KERNEL
);
if
(
!
data
)
if
(
!
data
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -516,12 +510,13 @@ static int imx_thermal_probe(struct platform_device *pdev)
...
@@ -516,12 +510,13 @@ 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
);
cpumask_set_cpu
(
0
,
&
clip_cpus
);
data
->
cdev
=
cpufreq_cooling_register
(
cpu_present_mask
);
data
->
cdev
=
cpufreq_cooling_register
(
&
clip_cpus
);
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
"
,
ret
);
"failed to register cpufreq cooling device: %d
\n
"
,
ret
);
return
ret
;
return
ret
;
}
}
...
...
drivers/thermal/int340x_thermal/Makefile
View file @
7429b1e0
obj-$(CONFIG_INT340X_THERMAL)
+=
int3400_thermal.o
obj-$(CONFIG_INT340X_THERMAL)
+=
int3400_thermal.o
obj-$(CONFIG_INT340X_THERMAL)
+=
int3402_thermal.o
obj-$(CONFIG_INT340X_THERMAL)
+=
int3402_thermal.o
obj-$(CONFIG_INT340X_THERMAL)
+=
int3403_thermal.o
obj-$(CONFIG_INT340X_THERMAL)
+=
int3403_thermal.o
obj-$(CONFIG_INT340X_THERMAL)
+=
processor_thermal_device.o
obj-$(CONFIG_ACPI_THERMAL_REL)
+=
acpi_thermal_rel.o
obj-$(CONFIG_ACPI_THERMAL_REL)
+=
acpi_thermal_rel.o
drivers/thermal/int340x_thermal/acpi_thermal_rel.c
View file @
7429b1e0
...
@@ -82,7 +82,7 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp,
...
@@ -82,7 +82,7 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp,
struct
acpi_buffer
trt_format
=
{
sizeof
(
"RRNNNNNN"
),
"RRNNNNNN"
};
struct
acpi_buffer
trt_format
=
{
sizeof
(
"RRNNNNNN"
),
"RRNNNNNN"
};
if
(
!
acpi_has_method
(
handle
,
"_TRT"
))
if
(
!
acpi_has_method
(
handle
,
"_TRT"
))
return
0
;
return
-
ENODEV
;
status
=
acpi_evaluate_object
(
handle
,
"_TRT"
,
NULL
,
&
buffer
);
status
=
acpi_evaluate_object
(
handle
,
"_TRT"
,
NULL
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
if
(
ACPI_FAILURE
(
status
))
...
@@ -167,7 +167,7 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
...
@@ -167,7 +167,7 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
sizeof
(
"RRNNNNNNNNNNN"
),
"RRNNNNNNNNNNN"
};
sizeof
(
"RRNNNNNNNNNNN"
),
"RRNNNNNNNNNNN"
};
if
(
!
acpi_has_method
(
handle
,
"_ART"
))
if
(
!
acpi_has_method
(
handle
,
"_ART"
))
return
0
;
return
-
ENODEV
;
status
=
acpi_evaluate_object
(
handle
,
"_ART"
,
NULL
,
&
buffer
);
status
=
acpi_evaluate_object
(
handle
,
"_ART"
,
NULL
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
if
(
ACPI_FAILURE
(
status
))
...
@@ -321,8 +321,8 @@ static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd,
...
@@ -321,8 +321,8 @@ static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd,
unsigned
long
length
=
0
;
unsigned
long
length
=
0
;
int
count
=
0
;
int
count
=
0
;
char
__user
*
arg
=
(
void
__user
*
)
__arg
;
char
__user
*
arg
=
(
void
__user
*
)
__arg
;
struct
trt
*
trts
;
struct
trt
*
trts
=
NULL
;
struct
art
*
arts
;
struct
art
*
arts
=
NULL
;
switch
(
cmd
)
{
switch
(
cmd
)
{
case
ACPI_THERMAL_GET_TRT_COUNT
:
case
ACPI_THERMAL_GET_TRT_COUNT
:
...
...
drivers/thermal/int340x_thermal/int3400_thermal.c
View file @
7429b1e0
...
@@ -335,7 +335,6 @@ static struct platform_driver int3400_thermal_driver = {
...
@@ -335,7 +335,6 @@ static struct platform_driver int3400_thermal_driver = {
.
remove
=
int3400_thermal_remove
,
.
remove
=
int3400_thermal_remove
,
.
driver
=
{
.
driver
=
{
.
name
=
"int3400 thermal"
,
.
name
=
"int3400 thermal"
,
.
owner
=
THIS_MODULE
,
.
acpi_match_table
=
ACPI_PTR
(
int3400_thermal_match
),
.
acpi_match_table
=
ACPI_PTR
(
int3400_thermal_match
),
},
},
};
};
...
...
drivers/thermal/int340x_thermal/int3402_thermal.c
View file @
7429b1e0
...
@@ -231,7 +231,6 @@ static struct platform_driver int3402_thermal_driver = {
...
@@ -231,7 +231,6 @@ static struct platform_driver int3402_thermal_driver = {
.
remove
=
int3402_thermal_remove
,
.
remove
=
int3402_thermal_remove
,
.
driver
=
{
.
driver
=
{
.
name
=
"int3402 thermal"
,
.
name
=
"int3402 thermal"
,
.
owner
=
THIS_MODULE
,
.
acpi_match_table
=
int3402_thermal_match
,
.
acpi_match_table
=
int3402_thermal_match
,
},
},
};
};
...
...
drivers/thermal/int340x_thermal/int3403_thermal.c
View file @
7429b1e0
...
@@ -301,6 +301,8 @@ static int int3403_sensor_remove(struct int3403_priv *priv)
...
@@ -301,6 +301,8 @@ static int int3403_sensor_remove(struct int3403_priv *priv)
{
{
struct
int3403_sensor
*
obj
=
priv
->
priv
;
struct
int3403_sensor
*
obj
=
priv
->
priv
;
acpi_remove_notify_handler
(
priv
->
adev
->
handle
,
ACPI_DEVICE_NOTIFY
,
int3403_notify
);
thermal_zone_device_unregister
(
obj
->
tzone
);
thermal_zone_device_unregister
(
obj
->
tzone
);
return
0
;
return
0
;
}
}
...
@@ -369,6 +371,7 @@ static int int3403_cdev_add(struct int3403_priv *priv)
...
@@ -369,6 +371,7 @@ static int int3403_cdev_add(struct int3403_priv *priv)
p
=
buf
.
pointer
;
p
=
buf
.
pointer
;
if
(
!
p
||
(
p
->
type
!=
ACPI_TYPE_PACKAGE
))
{
if
(
!
p
||
(
p
->
type
!=
ACPI_TYPE_PACKAGE
))
{
printk
(
KERN_WARNING
"Invalid PPSS data
\n
"
);
printk
(
KERN_WARNING
"Invalid PPSS data
\n
"
);
kfree
(
buf
.
pointer
);
return
-
EFAULT
;
return
-
EFAULT
;
}
}
...
@@ -381,6 +384,7 @@ static int int3403_cdev_add(struct int3403_priv *priv)
...
@@ -381,6 +384,7 @@ static int int3403_cdev_add(struct int3403_priv *priv)
priv
->
priv
=
obj
;
priv
->
priv
=
obj
;
kfree
(
buf
.
pointer
);
/* TODO: add ACPI notification support */
/* TODO: add ACPI notification support */
return
result
;
return
result
;
...
...
drivers/thermal/int340x_thermal/processor_thermal_device.c
0 → 100644
View file @
7429b1e0
/*
* processor_thermal_device.c
* Copyright (c) 2014, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
/* Broadwell-U/HSB thermal reporting device */
#define PCI_DEVICE_ID_PROC_BDW_THERMAL 0x1603
#define PCI_DEVICE_ID_PROC_HSB_THERMAL 0x0A03
/* Braswell thermal reporting device */
#define PCI_DEVICE_ID_PROC_BSW_THERMAL 0x22DC
struct
power_config
{
u32
index
;
u32
min_uw
;
u32
max_uw
;
u32
tmin_us
;
u32
tmax_us
;
u32
step_uw
;
};
struct
proc_thermal_device
{
struct
device
*
dev
;
struct
acpi_device
*
adev
;
struct
power_config
power_limits
[
2
];
};
enum
proc_thermal_emum_mode_type
{
PROC_THERMAL_NONE
,
PROC_THERMAL_PCI
,
PROC_THERMAL_PLATFORM_DEV
};
/*
* We can have only one type of enumeration, PCI or Platform,
* not both. So we don't need instance specific data.
*/
static
enum
proc_thermal_emum_mode_type
proc_thermal_emum_mode
=
PROC_THERMAL_NONE
;
#define POWER_LIMIT_SHOW(index, suffix) \
static ssize_t power_limit_##index##_##suffix##_show(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
struct pci_dev *pci_dev; \
struct platform_device *pdev; \
struct proc_thermal_device *proc_dev; \
\
if (proc_thermal_emum_mode == PROC_THERMAL_PLATFORM_DEV) { \
pdev = to_platform_device(dev); \
proc_dev = platform_get_drvdata(pdev); \
} else { \
pci_dev = to_pci_dev(dev); \
proc_dev = pci_get_drvdata(pci_dev); \
} \
return sprintf(buf, "%lu\n",\
(unsigned long)proc_dev->power_limits[index].suffix * 1000); \
}
POWER_LIMIT_SHOW
(
0
,
min_uw
)
POWER_LIMIT_SHOW
(
0
,
max_uw
)
POWER_LIMIT_SHOW
(
0
,
step_uw
)
POWER_LIMIT_SHOW
(
0
,
tmin_us
)
POWER_LIMIT_SHOW
(
0
,
tmax_us
)
POWER_LIMIT_SHOW
(
1
,
min_uw
)
POWER_LIMIT_SHOW
(
1
,
max_uw
)
POWER_LIMIT_SHOW
(
1
,
step_uw
)
POWER_LIMIT_SHOW
(
1
,
tmin_us
)
POWER_LIMIT_SHOW
(
1
,
tmax_us
)
static
DEVICE_ATTR_RO
(
power_limit_0_min_uw
);
static
DEVICE_ATTR_RO
(
power_limit_0_max_uw
);
static
DEVICE_ATTR_RO
(
power_limit_0_step_uw
);
static
DEVICE_ATTR_RO
(
power_limit_0_tmin_us
);
static
DEVICE_ATTR_RO
(
power_limit_0_tmax_us
);
static
DEVICE_ATTR_RO
(
power_limit_1_min_uw
);
static
DEVICE_ATTR_RO
(
power_limit_1_max_uw
);
static
DEVICE_ATTR_RO
(
power_limit_1_step_uw
);
static
DEVICE_ATTR_RO
(
power_limit_1_tmin_us
);
static
DEVICE_ATTR_RO
(
power_limit_1_tmax_us
);
static
struct
attribute
*
power_limit_attrs
[]
=
{
&
dev_attr_power_limit_0_min_uw
.
attr
,
&
dev_attr_power_limit_1_min_uw
.
attr
,
&
dev_attr_power_limit_0_max_uw
.
attr
,
&
dev_attr_power_limit_1_max_uw
.
attr
,
&
dev_attr_power_limit_0_step_uw
.
attr
,
&
dev_attr_power_limit_1_step_uw
.
attr
,
&
dev_attr_power_limit_0_tmin_us
.
attr
,
&
dev_attr_power_limit_1_tmin_us
.
attr
,
&
dev_attr_power_limit_0_tmax_us
.
attr
,
&
dev_attr_power_limit_1_tmax_us
.
attr
,
NULL
};
static
struct
attribute_group
power_limit_attribute_group
=
{
.
attrs
=
power_limit_attrs
,
.
name
=
"power_limits"
};
static
int
proc_thermal_add
(
struct
device
*
dev
,
struct
proc_thermal_device
**
priv
)
{
struct
proc_thermal_device
*
proc_priv
;
struct
acpi_device
*
adev
;
acpi_status
status
;
struct
acpi_buffer
buf
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
union
acpi_object
*
elements
,
*
ppcc
;
union
acpi_object
*
p
;
int
i
;
int
ret
;
adev
=
ACPI_COMPANION
(
dev
);
status
=
acpi_evaluate_object
(
adev
->
handle
,
"PPCC"
,
NULL
,
&
buf
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
p
=
buf
.
pointer
;
if
(
!
p
||
(
p
->
type
!=
ACPI_TYPE_PACKAGE
))
{
dev_err
(
dev
,
"Invalid PPCC data
\n
"
);
ret
=
-
EFAULT
;
goto
free_buffer
;
}
if
(
!
p
->
package
.
count
)
{
dev_err
(
dev
,
"Invalid PPCC package size
\n
"
);
ret
=
-
EFAULT
;
goto
free_buffer
;
}
proc_priv
=
devm_kzalloc
(
dev
,
sizeof
(
*
proc_priv
),
GFP_KERNEL
);
if
(
!
proc_priv
)
{
ret
=
-
ENOMEM
;
goto
free_buffer
;
}
proc_priv
->
dev
=
dev
;
proc_priv
->
adev
=
adev
;
for
(
i
=
0
;
i
<
min
((
int
)
p
->
package
.
count
-
1
,
2
);
++
i
)
{
elements
=
&
(
p
->
package
.
elements
[
i
+
1
]);
if
(
elements
->
type
!=
ACPI_TYPE_PACKAGE
||
elements
->
package
.
count
!=
6
)
{
ret
=
-
EFAULT
;
goto
free_buffer
;
}
ppcc
=
elements
->
package
.
elements
;
proc_priv
->
power_limits
[
i
].
index
=
ppcc
[
0
].
integer
.
value
;
proc_priv
->
power_limits
[
i
].
min_uw
=
ppcc
[
1
].
integer
.
value
;
proc_priv
->
power_limits
[
i
].
max_uw
=
ppcc
[
2
].
integer
.
value
;
proc_priv
->
power_limits
[
i
].
tmin_us
=
ppcc
[
3
].
integer
.
value
;
proc_priv
->
power_limits
[
i
].
tmax_us
=
ppcc
[
4
].
integer
.
value
;
proc_priv
->
power_limits
[
i
].
step_uw
=
ppcc
[
5
].
integer
.
value
;
}
*
priv
=
proc_priv
;
ret
=
sysfs_create_group
(
&
dev
->
kobj
,
&
power_limit_attribute_group
);
free_buffer:
kfree
(
buf
.
pointer
);
return
ret
;
}
void
proc_thermal_remove
(
struct
proc_thermal_device
*
proc_priv
)
{
sysfs_remove_group
(
&
proc_priv
->
dev
->
kobj
,
&
power_limit_attribute_group
);
}
static
int
int3401_add
(
struct
platform_device
*
pdev
)
{
struct
proc_thermal_device
*
proc_priv
;
int
ret
;
if
(
proc_thermal_emum_mode
==
PROC_THERMAL_PCI
)
{
dev_err
(
&
pdev
->
dev
,
"error: enumerated as PCI dev
\n
"
);
return
-
ENODEV
;
}
ret
=
proc_thermal_add
(
&
pdev
->
dev
,
&
proc_priv
);
if
(
ret
)
return
ret
;
platform_set_drvdata
(
pdev
,
proc_priv
);
proc_thermal_emum_mode
=
PROC_THERMAL_PLATFORM_DEV
;
return
0
;
}
static
int
int3401_remove
(
struct
platform_device
*
pdev
)
{
proc_thermal_remove
(
platform_get_drvdata
(
pdev
));
return
0
;
}
static
int
proc_thermal_pci_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
unused
)
{
struct
proc_thermal_device
*
proc_priv
;
int
ret
;
if
(
proc_thermal_emum_mode
==
PROC_THERMAL_PLATFORM_DEV
)
{
dev_err
(
&
pdev
->
dev
,
"error: enumerated as platform dev
\n
"
);
return
-
ENODEV
;
}
ret
=
pci_enable_device
(
pdev
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"error: could not enable device
\n
"
);
return
ret
;
}
ret
=
proc_thermal_add
(
&
pdev
->
dev
,
&
proc_priv
);
if
(
ret
)
{
pci_disable_device
(
pdev
);
return
ret
;
}
pci_set_drvdata
(
pdev
,
proc_priv
);
proc_thermal_emum_mode
=
PROC_THERMAL_PCI
;
return
0
;
}
static
void
proc_thermal_pci_remove
(
struct
pci_dev
*
pdev
)
{
proc_thermal_remove
(
pci_get_drvdata
(
pdev
));
pci_disable_device
(
pdev
);
}
static
const
struct
pci_device_id
proc_thermal_pci_ids
[]
=
{
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_PROC_BDW_THERMAL
)},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_PROC_HSB_THERMAL
)},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_PROC_BSW_THERMAL
)},
{
0
,
},
};
MODULE_DEVICE_TABLE
(
pci
,
proc_thermal_pci_ids
);
static
struct
pci_driver
proc_thermal_pci_driver
=
{
.
name
=
"proc_thermal"
,
.
probe
=
proc_thermal_pci_probe
,
.
remove
=
proc_thermal_pci_remove
,
.
id_table
=
proc_thermal_pci_ids
,
};
static
const
struct
acpi_device_id
int3401_device_ids
[]
=
{
{
"INT3401"
,
0
},
{
""
,
0
},
};
MODULE_DEVICE_TABLE
(
acpi
,
int3401_device_ids
);
static
struct
platform_driver
int3401_driver
=
{
.
probe
=
int3401_add
,
.
remove
=
int3401_remove
,
.
driver
=
{
.
name
=
"int3401 thermal"
,
.
acpi_match_table
=
int3401_device_ids
,
},
};
static
int
__init
proc_thermal_init
(
void
)
{
int
ret
;
ret
=
platform_driver_register
(
&
int3401_driver
);
if
(
ret
)
return
ret
;
ret
=
pci_register_driver
(
&
proc_thermal_pci_driver
);
return
ret
;
}
static
void
__exit
proc_thermal_exit
(
void
)
{
platform_driver_unregister
(
&
int3401_driver
);
pci_unregister_driver
(
&
proc_thermal_pci_driver
);
}
module_init
(
proc_thermal_init
);
module_exit
(
proc_thermal_exit
);
MODULE_AUTHOR
(
"Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"
);
MODULE_DESCRIPTION
(
"Processor Thermal Reporting Device Driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/thermal/intel_powerclamp.c
View file @
7429b1e0
...
@@ -688,6 +688,7 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = {
...
@@ -688,6 +688,7 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = {
{
X86_VENDOR_INTEL
,
6
,
0x45
},
{
X86_VENDOR_INTEL
,
6
,
0x45
},
{
X86_VENDOR_INTEL
,
6
,
0x46
},
{
X86_VENDOR_INTEL
,
6
,
0x46
},
{
X86_VENDOR_INTEL
,
6
,
0x4c
},
{
X86_VENDOR_INTEL
,
6
,
0x4c
},
{
X86_VENDOR_INTEL
,
6
,
0x56
},
{}
{}
};
};
MODULE_DEVICE_TABLE
(
x86cpu
,
intel_powerclamp_ids
);
MODULE_DEVICE_TABLE
(
x86cpu
,
intel_powerclamp_ids
);
...
...
drivers/thermal/rockchip_thermal.c
View file @
7429b1e0
...
@@ -677,7 +677,6 @@ static SIMPLE_DEV_PM_OPS(rockchip_thermal_pm_ops,
...
@@ -677,7 +677,6 @@ static SIMPLE_DEV_PM_OPS(rockchip_thermal_pm_ops,
static
struct
platform_driver
rockchip_thermal_driver
=
{
static
struct
platform_driver
rockchip_thermal_driver
=
{
.
driver
=
{
.
driver
=
{
.
name
=
"rockchip-thermal"
,
.
name
=
"rockchip-thermal"
,
.
owner
=
THIS_MODULE
,
.
pm
=
&
rockchip_thermal_pm_ops
,
.
pm
=
&
rockchip_thermal_pm_ops
,
.
of_match_table
=
of_rockchip_thermal_match
,
.
of_match_table
=
of_rockchip_thermal_match
,
},
},
...
...
drivers/thermal/samsung/Kconfig
View file @
7429b1e0
config EXYNOS_THERMAL
config EXYNOS_THERMAL
tristate "Exynos thermal management unit driver"
tristate "Exynos thermal management unit driver"
depends on
ARCH_HAS_BANDGAP &&
OF
depends on OF
help
help
If you say yes here you get support for the TMU (Thermal Management
If you say yes here you get support for the TMU (Thermal Management
Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises
Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises
...
...
drivers/thermal/samsung/exynos_thermal_common.c
View file @
7429b1e0
...
@@ -347,7 +347,6 @@ void exynos_report_trigger(struct thermal_sensor_conf *conf)
...
@@ -347,7 +347,6 @@ void exynos_report_trigger(struct thermal_sensor_conf *conf)
int
exynos_register_thermal
(
struct
thermal_sensor_conf
*
sensor_conf
)
int
exynos_register_thermal
(
struct
thermal_sensor_conf
*
sensor_conf
)
{
{
int
ret
;
int
ret
;
struct
cpumask
mask_val
;
struct
exynos_thermal_zone
*
th_zone
;
struct
exynos_thermal_zone
*
th_zone
;
if
(
!
sensor_conf
||
!
sensor_conf
->
read_temperature
)
{
if
(
!
sensor_conf
||
!
sensor_conf
->
read_temperature
)
{
...
@@ -367,13 +366,14 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
...
@@ -367,13 +366,14 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
* sensor
* sensor
*/
*/
if
(
sensor_conf
->
cooling_data
.
freq_clip_count
>
0
)
{
if
(
sensor_conf
->
cooling_data
.
freq_clip_count
>
0
)
{
cpumask_set_cpu
(
0
,
&
mask_val
);
th_zone
->
cool_dev
[
th_zone
->
cool_dev_size
]
=
th_zone
->
cool_dev
[
th_zone
->
cool_dev_size
]
=
cpufreq_cooling_register
(
&
mask_val
);
cpufreq_cooling_register
(
cpu_present_mask
);
if
(
IS_ERR
(
th_zone
->
cool_dev
[
th_zone
->
cool_dev_size
]))
{
if
(
IS_ERR
(
th_zone
->
cool_dev
[
th_zone
->
cool_dev_size
]))
{
ret
=
PTR_ERR
(
th_zone
->
cool_dev
[
th_zone
->
cool_dev_size
]);
if
(
ret
!=
-
EPROBE_DEFER
)
dev_err
(
sensor_conf
->
dev
,
dev_err
(
sensor_conf
->
dev
,
"Failed to register cpufreq cooling device
\n
"
);
"Failed to register cpufreq cooling device: %d
\n
"
,
ret
=
-
EINVAL
;
ret
)
;
goto
err_unregister
;
goto
err_unregister
;
}
}
th_zone
->
cool_dev_size
++
;
th_zone
->
cool_dev_size
++
;
...
...
drivers/thermal/samsung/exynos_tmu.c
View file @
7429b1e0
...
@@ -927,7 +927,10 @@ static int exynos_tmu_probe(struct platform_device *pdev)
...
@@ -927,7 +927,10 @@ static int exynos_tmu_probe(struct platform_device *pdev)
/* Register the sensor with thermal management interface */
/* Register the sensor with thermal management interface */
ret
=
exynos_register_thermal
(
sensor_conf
);
ret
=
exynos_register_thermal
(
sensor_conf
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to register thermal interface
\n
"
);
if
(
ret
!=
-
EPROBE_DEFER
)
dev_err
(
&
pdev
->
dev
,
"Failed to register thermal interface: %d
\n
"
,
ret
);
goto
err_clk
;
goto
err_clk
;
}
}
data
->
reg_conf
=
sensor_conf
;
data
->
reg_conf
=
sensor_conf
;
...
...
drivers/thermal/thermal_core.c
View file @
7429b1e0
...
@@ -930,7 +930,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
...
@@ -930,7 +930,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
struct
thermal_zone_device
*
pos1
;
struct
thermal_zone_device
*
pos1
;
struct
thermal_cooling_device
*
pos2
;
struct
thermal_cooling_device
*
pos2
;
unsigned
long
max_state
;
unsigned
long
max_state
;
int
result
;
int
result
,
ret
;
if
(
trip
>=
tz
->
trips
||
(
trip
<
0
&&
trip
!=
THERMAL_TRIPS_NONE
))
if
(
trip
>=
tz
->
trips
||
(
trip
<
0
&&
trip
!=
THERMAL_TRIPS_NONE
))
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -947,7 +947,9 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
...
@@ -947,7 +947,9 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
if
(
tz
!=
pos1
||
cdev
!=
pos2
)
if
(
tz
!=
pos1
||
cdev
!=
pos2
)
return
-
EINVAL
;
return
-
EINVAL
;
cdev
->
ops
->
get_max_state
(
cdev
,
&
max_state
);
ret
=
cdev
->
ops
->
get_max_state
(
cdev
,
&
max_state
);
if
(
ret
)
return
ret
;
/* lower default 0, upper default max_state */
/* lower default 0, upper default max_state */
lower
=
lower
==
THERMAL_NO_LIMIT
?
0
:
lower
;
lower
=
lower
==
THERMAL_NO_LIMIT
?
0
:
lower
;
...
...
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
View file @
7429b1e0
...
@@ -28,7 +28,6 @@
...
@@ -28,7 +28,6 @@
#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>
...
@@ -407,17 +406,17 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
...
@@ -407,17 +406,17 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
if
(
!
data
)
if
(
!
data
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
!
cpufreq_get_current_driver
())
{
dev_dbg
(
bgp
->
dev
,
"no cpufreq driver yet
\n
"
);
return
-
EPROBE_DEFER
;
}
/* Register cooling device */
/* Register cooling device */
data
->
cool_dev
=
cpufreq_cooling_register
(
cpu_present_mask
);
data
->
cool_dev
=
cpufreq_cooling_register
(
cpu_present_mask
);
if
(
IS_ERR
(
data
->
cool_dev
))
{
if
(
IS_ERR
(
data
->
cool_dev
))
{
int
ret
=
PTR_ERR
(
data
->
cool_dev
);
if
(
ret
!=
-
EPROBE_DEFER
)
dev_err
(
bgp
->
dev
,
dev_err
(
bgp
->
dev
,
"Failed to register cpufreq cooling device
\n
"
);
"Failed to register cpu cooling device %d
\n
"
,
return
PTR_ERR
(
data
->
cool_dev
);
ret
);
return
ret
;
}
}
ti_bandgap_set_sensor_data
(
bgp
,
id
,
data
);
ti_bandgap_set_sensor_data
(
bgp
,
id
,
data
);
...
...
include/dt-bindings/thermal/thermal.h
View file @
7429b1e0
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
#define _DT_BINDINGS_THERMAL_THERMAL_H
#define _DT_BINDINGS_THERMAL_THERMAL_H
/* On cooling devices upper and lower limits */
/* On cooling devices upper and lower limits */
#define THERMAL_NO_LIMIT (
-1UL
)
#define THERMAL_NO_LIMIT (
~0
)
#endif
#endif
include/linux/cpu_cooling.h
View file @
7429b1e0
...
@@ -50,7 +50,7 @@ static inline struct thermal_cooling_device *
...
@@ -50,7 +50,7 @@ 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
)
const
struct
cpumask
*
clip_cpus
)
{
{
return
NULL
;
return
ERR_PTR
(
-
ENOSYS
)
;
}
}
#endif
#endif
...
@@ -65,13 +65,13 @@ unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq);
...
@@ -65,13 +65,13 @@ unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq);
static
inline
struct
thermal_cooling_device
*
static
inline
struct
thermal_cooling_device
*
cpufreq_cooling_register
(
const
struct
cpumask
*
clip_cpus
)
cpufreq_cooling_register
(
const
struct
cpumask
*
clip_cpus
)
{
{
return
NULL
;
return
ERR_PTR
(
-
ENOSYS
)
;
}
}
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
)
const
struct
cpumask
*
clip_cpus
)
{
{
return
NULL
;
return
ERR_PTR
(
-
ENOSYS
)
;
}
}
static
inline
static
inline
void
cpufreq_cooling_unregister
(
struct
thermal_cooling_device
*
cdev
)
void
cpufreq_cooling_unregister
(
struct
thermal_cooling_device
*
cdev
)
...
...
include/linux/thermal.h
View file @
7429b1e0
...
@@ -38,7 +38,7 @@
...
@@ -38,7 +38,7 @@
#define THERMAL_CSTATE_INVALID -1UL
#define THERMAL_CSTATE_INVALID -1UL
/* No upper/lower limit requirement */
/* No upper/lower limit requirement */
#define THERMAL_NO_LIMIT
THERMAL_CSTATE_INVALID
#define THERMAL_NO_LIMIT
((u32)~0)
/* Unit conversion macros */
/* Unit conversion macros */
#define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \
#define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \
...
...
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