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
5c897a9a
Commit
5c897a9a
authored
Apr 19, 2024
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back earlier thermal control material for v6.10.
parents
b552f63c
0dbf6087
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
417 additions
and
231 deletions
+417
-231
drivers/thermal/gov_fair_share.c
drivers/thermal/gov_fair_share.c
+5
-2
drivers/thermal/gov_power_allocator.c
drivers/thermal/gov_power_allocator.c
+4
-2
drivers/thermal/gov_step_wise.c
drivers/thermal/gov_step_wise.c
+16
-25
drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c
drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c
+2
-2
drivers/thermal/intel/intel_hfi.c
drivers/thermal/intel/intel_hfi.c
+89
-8
drivers/thermal/thermal_core.c
drivers/thermal/thermal_core.c
+75
-43
drivers/thermal/thermal_core.h
drivers/thermal/thermal_core.h
+117
-2
drivers/thermal/thermal_debugfs.c
drivers/thermal/thermal_debugfs.c
+4
-2
drivers/thermal/thermal_helpers.c
drivers/thermal/thermal_helpers.c
+5
-3
drivers/thermal/thermal_netlink.c
drivers/thermal/thermal_netlink.c
+50
-18
drivers/thermal/thermal_netlink.h
drivers/thermal/thermal_netlink.h
+26
-0
drivers/thermal/thermal_sysfs.c
drivers/thermal/thermal_sysfs.c
+10
-10
drivers/thermal/thermal_trace.h
drivers/thermal/thermal_trace.h
+2
-0
drivers/thermal/thermal_trace_ipa.h
drivers/thermal/thermal_trace_ipa.h
+2
-0
drivers/thermal/thermal_trip.c
drivers/thermal/thermal_trip.c
+8
-7
include/linux/thermal.h
include/linux/thermal.h
+2
-107
No files found.
drivers/thermal/gov_fair_share.c
View file @
5c897a9a
...
@@ -17,10 +17,13 @@
...
@@ -17,10 +17,13 @@
static
int
get_trip_level
(
struct
thermal_zone_device
*
tz
)
static
int
get_trip_level
(
struct
thermal_zone_device
*
tz
)
{
{
const
struct
thermal_trip
*
trip
,
*
level_trip
=
NULL
;
const
struct
thermal_trip
*
level_trip
=
NULL
;
const
struct
thermal_trip_desc
*
td
;
int
trip_level
=
-
1
;
int
trip_level
=
-
1
;
for_each_trip
(
tz
,
trip
)
{
for_each_trip_desc
(
tz
,
td
)
{
const
struct
thermal_trip
*
trip
=
&
td
->
trip
;
if
(
trip
->
temperature
>=
tz
->
temperature
)
if
(
trip
->
temperature
>=
tz
->
temperature
)
continue
;
continue
;
...
...
drivers/thermal/gov_power_allocator.c
View file @
5c897a9a
...
@@ -496,9 +496,11 @@ static void get_governor_trips(struct thermal_zone_device *tz,
...
@@ -496,9 +496,11 @@ static void get_governor_trips(struct thermal_zone_device *tz,
const
struct
thermal_trip
*
first_passive
=
NULL
;
const
struct
thermal_trip
*
first_passive
=
NULL
;
const
struct
thermal_trip
*
last_passive
=
NULL
;
const
struct
thermal_trip
*
last_passive
=
NULL
;
const
struct
thermal_trip
*
last_active
=
NULL
;
const
struct
thermal_trip
*
last_active
=
NULL
;
const
struct
thermal_trip
*
trip
;
const
struct
thermal_trip_desc
*
td
;
for_each_trip_desc
(
tz
,
td
)
{
const
struct
thermal_trip
*
trip
=
&
td
->
trip
;
for_each_trip
(
tz
,
trip
)
{
switch
(
trip
->
type
)
{
switch
(
trip
->
type
)
{
case
THERMAL_TRIP_PASSIVE
:
case
THERMAL_TRIP_PASSIVE
:
if
(
!
first_passive
)
{
if
(
!
first_passive
)
{
...
...
drivers/thermal/gov_step_wise.c
View file @
5c897a9a
...
@@ -32,7 +32,6 @@ static unsigned long get_target_state(struct thermal_instance *instance,
...
@@ -32,7 +32,6 @@ static unsigned long get_target_state(struct thermal_instance *instance,
{
{
struct
thermal_cooling_device
*
cdev
=
instance
->
cdev
;
struct
thermal_cooling_device
*
cdev
=
instance
->
cdev
;
unsigned
long
cur_state
;
unsigned
long
cur_state
;
unsigned
long
next_target
;
/*
/*
* We keep this instance the way it is by default.
* We keep this instance the way it is by default.
...
@@ -40,32 +39,26 @@ static unsigned long get_target_state(struct thermal_instance *instance,
...
@@ -40,32 +39,26 @@ static unsigned long get_target_state(struct thermal_instance *instance,
* cdev in use to determine the next_target.
* cdev in use to determine the next_target.
*/
*/
cdev
->
ops
->
get_cur_state
(
cdev
,
&
cur_state
);
cdev
->
ops
->
get_cur_state
(
cdev
,
&
cur_state
);
next_target
=
instance
->
target
;
dev_dbg
(
&
cdev
->
device
,
"cur_state=%ld
\n
"
,
cur_state
);
dev_dbg
(
&
cdev
->
device
,
"cur_state=%ld
\n
"
,
cur_state
);
if
(
!
instance
->
initialized
)
{
if
(
!
instance
->
initialized
)
{
if
(
throttle
)
{
if
(
throttle
)
next_target
=
clamp
((
cur_state
+
1
),
instance
->
lower
,
instance
->
upper
);
return
clamp
(
cur_state
+
1
,
instance
->
lower
,
instance
->
upper
);
}
else
{
next_target
=
THERMAL_NO_TARGET
;
}
return
next_target
;
return
THERMAL_NO_TARGET
;
}
}
if
(
throttle
)
{
if
(
throttle
)
{
if
(
trend
==
THERMAL_TREND_RAISING
)
if
(
trend
==
THERMAL_TREND_RAISING
)
next_target
=
clamp
((
cur_state
+
1
),
instance
->
lower
,
instance
->
upper
);
return
clamp
(
cur_state
+
1
,
instance
->
lower
,
instance
->
upper
);
}
else
{
}
else
if
(
trend
==
THERMAL_TREND_DROPPING
)
{
if
(
trend
==
THERMAL_TREND_DROPPING
)
{
if
(
cur_state
<=
instance
->
lower
)
if
(
cur_state
<=
instance
->
lower
)
return
THERMAL_NO_TARGET
;
next_target
=
THERMAL_NO_TARGET
;
else
return
clamp
(
cur_state
-
1
,
instance
->
lower
,
instance
->
upper
);
next_target
=
clamp
((
cur_state
-
1
),
instance
->
lower
,
instance
->
upper
);
}
}
}
return
next_
target
;
return
instance
->
target
;
}
}
static
void
thermal_zone_trip_update
(
struct
thermal_zone_device
*
tz
,
static
void
thermal_zone_trip_update
(
struct
thermal_zone_device
*
tz
,
...
@@ -99,15 +92,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
...
@@ -99,15 +92,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
if
(
instance
->
initialized
&&
old_target
==
instance
->
target
)
if
(
instance
->
initialized
&&
old_target
==
instance
->
target
)
continue
;
continue
;
if
(
old_target
==
THERMAL_NO_TARGET
&&
if
(
trip
->
type
==
THERMAL_TRIP_PASSIVE
)
{
instance
->
target
!=
THERMAL_NO_TARGET
)
{
/* If needed, update the status of passive polling. */
/* Activate a passive thermal instance */
if
(
old_target
==
THERMAL_NO_TARGET
&&
if
(
trip
->
type
==
THERMAL_TRIP_PASSIVE
)
instance
->
target
!=
THERMAL_NO_TARGET
)
tz
->
passive
++
;
tz
->
passive
++
;
}
else
if
(
old_target
!=
THERMAL_NO_TARGET
&&
else
if
(
old_target
!=
THERMAL_NO_TARGET
&&
instance
->
target
==
THERMAL_NO_TARGET
)
{
instance
->
target
==
THERMAL_NO_TARGET
)
/* Deactivate a passive thermal instance */
if
(
trip
->
type
==
THERMAL_TRIP_PASSIVE
)
tz
->
passive
--
;
tz
->
passive
--
;
}
}
...
...
drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c
View file @
5c897a9a
...
@@ -309,7 +309,7 @@ static int acpi_parse_psvt(acpi_handle handle, int *psvt_count, struct psvt **ps
...
@@ -309,7 +309,7 @@ static int acpi_parse_psvt(acpi_handle handle, int *psvt_count, struct psvt **ps
if
(
knob
->
type
==
ACPI_TYPE_STRING
)
{
if
(
knob
->
type
==
ACPI_TYPE_STRING
)
{
memset
(
&
psvt
->
limit
,
0
,
sizeof
(
u64
));
memset
(
&
psvt
->
limit
,
0
,
sizeof
(
u64
));
str
ncpy
(
psvt
->
limit
.
string
,
psvt_ptr
->
limit
.
str_ptr
,
knob
->
string
.
length
);
str
scpy
(
psvt
->
limit
.
string
,
psvt_ptr
->
limit
.
str_ptr
,
ACPI_LIMIT_STR_MAX_LEN
);
}
else
{
}
else
{
psvt
->
limit
.
integer
=
psvt_ptr
->
limit
.
integer
;
psvt
->
limit
.
integer
=
psvt_ptr
->
limit
.
integer
;
}
}
...
@@ -468,7 +468,7 @@ static int fill_psvt(char __user *ubuf)
...
@@ -468,7 +468,7 @@ static int fill_psvt(char __user *ubuf)
psvt_user
[
i
].
unlimit_coeff
=
psvts
[
i
].
unlimit_coeff
;
psvt_user
[
i
].
unlimit_coeff
=
psvts
[
i
].
unlimit_coeff
;
psvt_user
[
i
].
control_knob_type
=
psvts
[
i
].
control_knob_type
;
psvt_user
[
i
].
control_knob_type
=
psvts
[
i
].
control_knob_type
;
if
(
psvt_user
[
i
].
control_knob_type
==
ACPI_TYPE_STRING
)
if
(
psvt_user
[
i
].
control_knob_type
==
ACPI_TYPE_STRING
)
str
n
cpy
(
psvt_user
[
i
].
limit
.
string
,
psvts
[
i
].
limit
.
string
,
str
s
cpy
(
psvt_user
[
i
].
limit
.
string
,
psvts
[
i
].
limit
.
string
,
ACPI_LIMIT_STR_MAX_LEN
);
ACPI_LIMIT_STR_MAX_LEN
);
else
else
psvt_user
[
i
].
limit
.
integer
=
psvts
[
i
].
limit
.
integer
;
psvt_user
[
i
].
limit
.
integer
=
psvts
[
i
].
limit
.
integer
;
...
...
drivers/thermal/intel/intel_hfi.c
View file @
5c897a9a
...
@@ -159,6 +159,7 @@ struct hfi_cpu_info {
...
@@ -159,6 +159,7 @@ struct hfi_cpu_info {
static
DEFINE_PER_CPU
(
struct
hfi_cpu_info
,
hfi_cpu_info
)
=
{
.
index
=
-
1
};
static
DEFINE_PER_CPU
(
struct
hfi_cpu_info
,
hfi_cpu_info
)
=
{
.
index
=
-
1
};
static
int
max_hfi_instances
;
static
int
max_hfi_instances
;
static
int
hfi_clients_nr
;
static
struct
hfi_instance
*
hfi_instances
;
static
struct
hfi_instance
*
hfi_instances
;
static
struct
hfi_features
hfi_features
;
static
struct
hfi_features
hfi_features
;
...
@@ -477,8 +478,11 @@ void intel_hfi_online(unsigned int cpu)
...
@@ -477,8 +478,11 @@ void intel_hfi_online(unsigned int cpu)
enable:
enable:
cpumask_set_cpu
(
cpu
,
hfi_instance
->
cpus
);
cpumask_set_cpu
(
cpu
,
hfi_instance
->
cpus
);
/* Enable this HFI instance if this is its first online CPU. */
/*
if
(
cpumask_weight
(
hfi_instance
->
cpus
)
==
1
)
{
* Enable this HFI instance if this is its first online CPU and
* there are user-space clients of thermal events.
*/
if
(
cpumask_weight
(
hfi_instance
->
cpus
)
==
1
&&
hfi_clients_nr
>
0
)
{
hfi_set_hw_table
(
hfi_instance
);
hfi_set_hw_table
(
hfi_instance
);
hfi_enable
();
hfi_enable
();
}
}
...
@@ -573,18 +577,33 @@ static __init int hfi_parse_features(void)
...
@@ -573,18 +577,33 @@ static __init int hfi_parse_features(void)
return
0
;
return
0
;
}
}
static
void
hfi_do_enable
(
void
)
/*
* If concurrency is not prevented by other means, the HFI enable/disable
* routines must be called under hfi_instance_lock."
*/
static
void
hfi_enable_instance
(
void
*
ptr
)
{
hfi_set_hw_table
(
ptr
);
hfi_enable
();
}
static
void
hfi_disable_instance
(
void
*
ptr
)
{
hfi_disable
();
}
static
void
hfi_syscore_resume
(
void
)
{
{
/* This code runs only on the boot CPU. */
/* This code runs only on the boot CPU. */
struct
hfi_cpu_info
*
info
=
&
per_cpu
(
hfi_cpu_info
,
0
);
struct
hfi_cpu_info
*
info
=
&
per_cpu
(
hfi_cpu_info
,
0
);
struct
hfi_instance
*
hfi_instance
=
info
->
hfi_instance
;
struct
hfi_instance
*
hfi_instance
=
info
->
hfi_instance
;
/* No locking needed. There is no concurrency with CPU online. */
/* No locking needed. There is no concurrency with CPU online. */
hfi_set_hw_table
(
hfi_instance
);
if
(
hfi_clients_nr
>
0
)
hfi_enable
(
);
hfi_enable_instance
(
hfi_instance
);
}
}
static
int
hfi_
do_disable
(
void
)
static
int
hfi_
syscore_suspend
(
void
)
{
{
/* No locking needed. There is no concurrency with CPU offline. */
/* No locking needed. There is no concurrency with CPU offline. */
hfi_disable
();
hfi_disable
();
...
@@ -593,8 +612,58 @@ static int hfi_do_disable(void)
...
@@ -593,8 +612,58 @@ static int hfi_do_disable(void)
}
}
static
struct
syscore_ops
hfi_pm_ops
=
{
static
struct
syscore_ops
hfi_pm_ops
=
{
.
resume
=
hfi_do_enable
,
.
resume
=
hfi_syscore_resume
,
.
suspend
=
hfi_do_disable
,
.
suspend
=
hfi_syscore_suspend
,
};
static
int
hfi_thermal_notify
(
struct
notifier_block
*
nb
,
unsigned
long
state
,
void
*
_notify
)
{
struct
thermal_genl_notify
*
notify
=
_notify
;
struct
hfi_instance
*
hfi_instance
;
smp_call_func_t
func
=
NULL
;
unsigned
int
cpu
;
int
i
;
if
(
notify
->
mcgrp
!=
THERMAL_GENL_EVENT_GROUP
)
return
NOTIFY_DONE
;
if
(
state
!=
THERMAL_NOTIFY_BIND
&&
state
!=
THERMAL_NOTIFY_UNBIND
)
return
NOTIFY_DONE
;
mutex_lock
(
&
hfi_instance_lock
);
switch
(
state
)
{
case
THERMAL_NOTIFY_BIND
:
if
(
++
hfi_clients_nr
==
1
)
func
=
hfi_enable_instance
;
break
;
case
THERMAL_NOTIFY_UNBIND
:
if
(
--
hfi_clients_nr
==
0
)
func
=
hfi_disable_instance
;
break
;
}
if
(
!
func
)
goto
out
;
for
(
i
=
0
;
i
<
max_hfi_instances
;
i
++
)
{
hfi_instance
=
&
hfi_instances
[
i
];
if
(
cpumask_empty
(
hfi_instance
->
cpus
))
continue
;
cpu
=
cpumask_any
(
hfi_instance
->
cpus
);
smp_call_function_single
(
cpu
,
func
,
hfi_instance
,
true
);
}
out:
mutex_unlock
(
&
hfi_instance_lock
);
return
NOTIFY_OK
;
}
static
struct
notifier_block
hfi_thermal_nb
=
{
.
notifier_call
=
hfi_thermal_notify
,
};
};
void
__init
intel_hfi_init
(
void
)
void
__init
intel_hfi_init
(
void
)
...
@@ -628,10 +697,22 @@ void __init intel_hfi_init(void)
...
@@ -628,10 +697,22 @@ void __init intel_hfi_init(void)
if
(
!
hfi_updates_wq
)
if
(
!
hfi_updates_wq
)
goto
err_nomem
;
goto
err_nomem
;
/*
* Both thermal core and Intel HFI can not be build as modules.
* As kernel build-in drivers they are initialized before user-space
* starts, hence we can not miss BIND/UNBIND events when applications
* add/remove thermal multicast group to/from a netlink socket.
*/
if
(
thermal_genl_register_notifier
(
&
hfi_thermal_nb
))
goto
err_nl_notif
;
register_syscore_ops
(
&
hfi_pm_ops
);
register_syscore_ops
(
&
hfi_pm_ops
);
return
;
return
;
err_nl_notif:
destroy_workqueue
(
hfi_updates_wq
);
err_nomem:
err_nomem:
for
(
j
=
0
;
j
<
i
;
++
j
)
{
for
(
j
=
0
;
j
<
i
;
++
j
)
{
hfi_instance
=
&
hfi_instances
[
j
];
hfi_instance
=
&
hfi_instances
[
j
];
...
...
drivers/thermal/thermal_core.c
View file @
5c897a9a
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/kdev_t.h>
#include <linux/kdev_t.h>
#include <linux/idr.h>
#include <linux/idr.h>
#include <linux/list_sort.h>
#include <linux/thermal.h>
#include <linux/thermal.h>
#include <linux/reboot.h>
#include <linux/reboot.h>
#include <linux/string.h>
#include <linux/string.h>
...
@@ -361,49 +362,48 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
...
@@ -361,49 +362,48 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
}
}
static
void
handle_thermal_trip
(
struct
thermal_zone_device
*
tz
,
static
void
handle_thermal_trip
(
struct
thermal_zone_device
*
tz
,
struct
thermal_trip
*
trip
)
struct
thermal_trip_desc
*
td
,
struct
list_head
*
way_up_list
,
struct
list_head
*
way_down_list
)
{
{
const
struct
thermal_trip
*
trip
=
&
td
->
trip
;
int
old_threshold
;
if
(
trip
->
temperature
==
THERMAL_TEMP_INVALID
)
if
(
trip
->
temperature
==
THERMAL_TEMP_INVALID
)
return
;
return
;
if
(
tz
->
last_temperature
==
THERMAL_TEMP_INVALID
)
{
/*
/* Initialization. */
* If the trip temperature or hysteresis has been updated recently,
trip
->
threshold
=
trip
->
temperature
;
* the threshold needs to be computed again using the new values.
if
(
tz
->
temperature
>=
trip
->
threshold
)
* However, its initial value still reflects the old ones and that
trip
->
threshold
-=
trip
->
hysteresis
;
* is what needs to be compared with the previous zone temperature
}
else
if
(
tz
->
last_temperature
<
trip
->
threshold
)
{
* to decide which action to take.
*/
old_threshold
=
td
->
threshold
;
td
->
threshold
=
trip
->
temperature
;
if
(
tz
->
last_temperature
>=
old_threshold
&&
tz
->
last_temperature
!=
THERMAL_TEMP_INVALID
)
{
/*
/*
* The trip threshold is equal to the trip temperature, unless
* Mitigation is under way, so it needs to stop if the zone
* the latter has changed in the meantime. In either case,
* temperature falls below the low temperature of the trip.
* the trip is crossed if the current zone temperature is at
* In that case, the trip temperature becomes the new threshold.
* least equal to its temperature, but otherwise ensure that
* the threshold and the trip temperature will be equal.
*/
*/
if
(
tz
->
temperature
>=
trip
->
temperature
)
{
if
(
tz
->
temperature
<
trip
->
temperature
-
trip
->
hysteresis
)
{
thermal_notify_tz_trip_up
(
tz
,
trip
);
list_add
(
&
td
->
notify_list_node
,
way_down_list
);
thermal_debug_tz_trip_up
(
tz
,
trip
);
td
->
notify_temp
=
trip
->
temperature
-
trip
->
hysteresis
;
trip
->
threshold
=
trip
->
temperature
-
trip
->
hysteresis
;
}
else
{
}
else
{
t
rip
->
threshold
=
trip
->
temperature
;
t
d
->
threshold
-=
trip
->
hysteresis
;
}
}
}
else
{
}
else
if
(
tz
->
temperature
>=
trip
->
temperature
)
{
/*
/*
* The previous zone temperature was above or equal to the trip
* There is no mitigation under way, so it needs to be started
* threshold, which would be equal to the "low temperature" of
* if the zone temperature exceeds the trip one. The new
* the trip (its temperature minus its hysteresis), unless the
* threshold is then set to the low temperature of the trip.
* trip temperature or hysteresis had changed. In either case,
* the trip is crossed if the current zone temperature is below
* the low temperature of the trip, but otherwise ensure that
* the trip threshold will be equal to the low temperature of
* the trip.
*/
*/
if
(
tz
->
temperature
<
trip
->
temperature
-
trip
->
hysteresis
)
{
list_add_tail
(
&
td
->
notify_list_node
,
way_up_list
);
thermal_notify_tz_trip_down
(
tz
,
trip
);
td
->
notify_temp
=
trip
->
temperature
;
thermal_debug_tz_trip_down
(
tz
,
trip
);
td
->
threshold
-=
trip
->
hysteresis
;
trip
->
threshold
=
trip
->
temperature
;
}
else
{
trip
->
threshold
=
trip
->
temperature
-
trip
->
hysteresis
;
}
}
}
if
(
trip
->
type
==
THERMAL_TRIP_CRITICAL
||
trip
->
type
==
THERMAL_TRIP_HOT
)
if
(
trip
->
type
==
THERMAL_TRIP_CRITICAL
||
trip
->
type
==
THERMAL_TRIP_HOT
)
...
@@ -455,10 +455,24 @@ static void thermal_zone_device_init(struct thermal_zone_device *tz)
...
@@ -455,10 +455,24 @@ static void thermal_zone_device_init(struct thermal_zone_device *tz)
pos
->
initialized
=
false
;
pos
->
initialized
=
false
;
}
}
static
int
thermal_trip_notify_cmp
(
void
*
ascending
,
const
struct
list_head
*
a
,
const
struct
list_head
*
b
)
{
struct
thermal_trip_desc
*
tda
=
container_of
(
a
,
struct
thermal_trip_desc
,
notify_list_node
);
struct
thermal_trip_desc
*
tdb
=
container_of
(
b
,
struct
thermal_trip_desc
,
notify_list_node
);
int
ret
=
tdb
->
notify_temp
-
tda
->
notify_temp
;
return
ascending
?
ret
:
-
ret
;
}
void
__thermal_zone_device_update
(
struct
thermal_zone_device
*
tz
,
void
__thermal_zone_device_update
(
struct
thermal_zone_device
*
tz
,
enum
thermal_notify_event
event
)
enum
thermal_notify_event
event
)
{
{
struct
thermal_trip
*
trip
;
struct
thermal_trip_desc
*
td
;
LIST_HEAD
(
way_down_list
);
LIST_HEAD
(
way_up_list
);
if
(
tz
->
suspended
)
if
(
tz
->
suspended
)
return
;
return
;
...
@@ -472,8 +486,20 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
...
@@ -472,8 +486,20 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
tz
->
notify_event
=
event
;
tz
->
notify_event
=
event
;
for_each_trip
(
tz
,
trip
)
for_each_trip_desc
(
tz
,
td
)
handle_thermal_trip
(
tz
,
trip
);
handle_thermal_trip
(
tz
,
td
,
&
way_up_list
,
&
way_down_list
);
list_sort
(
&
way_up_list
,
&
way_up_list
,
thermal_trip_notify_cmp
);
list_for_each_entry
(
td
,
&
way_up_list
,
notify_list_node
)
{
thermal_notify_tz_trip_up
(
tz
,
&
td
->
trip
);
thermal_debug_tz_trip_up
(
tz
,
&
td
->
trip
);
}
list_sort
(
NULL
,
&
way_down_list
,
thermal_trip_notify_cmp
);
list_for_each_entry
(
td
,
&
way_down_list
,
notify_list_node
)
{
thermal_notify_tz_trip_down
(
tz
,
&
td
->
trip
);
thermal_debug_tz_trip_down
(
tz
,
&
td
->
trip
);
}
monitor_thermal_zone
(
tz
);
monitor_thermal_zone
(
tz
);
}
}
...
@@ -766,7 +792,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
...
@@ -766,7 +792,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
if
(
trip_index
<
0
||
trip_index
>=
tz
->
num_trips
)
if
(
trip_index
<
0
||
trip_index
>=
tz
->
num_trips
)
return
-
EINVAL
;
return
-
EINVAL
;
return
thermal_bind_cdev_to_trip
(
tz
,
&
tz
->
trips
[
trip_index
],
cdev
,
return
thermal_bind_cdev_to_trip
(
tz
,
&
tz
->
trips
[
trip_index
]
.
trip
,
cdev
,
upper
,
lower
,
weight
);
upper
,
lower
,
weight
);
}
}
EXPORT_SYMBOL_GPL
(
thermal_zone_bind_cooling_device
);
EXPORT_SYMBOL_GPL
(
thermal_zone_bind_cooling_device
);
...
@@ -825,7 +851,7 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
...
@@ -825,7 +851,7 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
if
(
trip_index
<
0
||
trip_index
>=
tz
->
num_trips
)
if
(
trip_index
<
0
||
trip_index
>=
tz
->
num_trips
)
return
-
EINVAL
;
return
-
EINVAL
;
return
thermal_unbind_cdev_from_trip
(
tz
,
&
tz
->
trips
[
trip_index
],
cdev
);
return
thermal_unbind_cdev_from_trip
(
tz
,
&
tz
->
trips
[
trip_index
]
.
trip
,
cdev
);
}
}
EXPORT_SYMBOL_GPL
(
thermal_zone_unbind_cooling_device
);
EXPORT_SYMBOL_GPL
(
thermal_zone_unbind_cooling_device
);
...
@@ -1221,16 +1247,19 @@ static void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms
...
@@ -1221,16 +1247,19 @@ static void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms
int
thermal_zone_get_crit_temp
(
struct
thermal_zone_device
*
tz
,
int
*
temp
)
int
thermal_zone_get_crit_temp
(
struct
thermal_zone_device
*
tz
,
int
*
temp
)
{
{
int
i
,
ret
=
-
EINVAL
;
const
struct
thermal_trip_desc
*
td
;
int
ret
=
-
EINVAL
;
if
(
tz
->
ops
.
get_crit_temp
)
if
(
tz
->
ops
.
get_crit_temp
)
return
tz
->
ops
.
get_crit_temp
(
tz
,
temp
);
return
tz
->
ops
.
get_crit_temp
(
tz
,
temp
);
mutex_lock
(
&
tz
->
lock
);
mutex_lock
(
&
tz
->
lock
);
for
(
i
=
0
;
i
<
tz
->
num_trips
;
i
++
)
{
for_each_trip_desc
(
tz
,
td
)
{
if
(
tz
->
trips
[
i
].
type
==
THERMAL_TRIP_CRITICAL
)
{
const
struct
thermal_trip
*
trip
=
&
td
->
trip
;
*
temp
=
tz
->
trips
[
i
].
temperature
;
if
(
trip
->
type
==
THERMAL_TRIP_CRITICAL
)
{
*
temp
=
trip
->
temperature
;
ret
=
0
;
ret
=
0
;
break
;
break
;
}
}
...
@@ -1274,7 +1303,9 @@ thermal_zone_device_register_with_trips(const char *type,
...
@@ -1274,7 +1303,9 @@ thermal_zone_device_register_with_trips(const char *type,
const
struct
thermal_zone_params
*
tzp
,
const
struct
thermal_zone_params
*
tzp
,
int
passive_delay
,
int
polling_delay
)
int
passive_delay
,
int
polling_delay
)
{
{
const
struct
thermal_trip
*
trip
=
trips
;
struct
thermal_zone_device
*
tz
;
struct
thermal_zone_device
*
tz
;
struct
thermal_trip_desc
*
td
;
int
id
;
int
id
;
int
result
;
int
result
;
struct
thermal_governor
*
governor
;
struct
thermal_governor
*
governor
;
...
@@ -1339,7 +1370,8 @@ thermal_zone_device_register_with_trips(const char *type,
...
@@ -1339,7 +1370,8 @@ thermal_zone_device_register_with_trips(const char *type,
tz
->
device
.
class
=
thermal_class
;
tz
->
device
.
class
=
thermal_class
;
tz
->
devdata
=
devdata
;
tz
->
devdata
=
devdata
;
tz
->
num_trips
=
num_trips
;
tz
->
num_trips
=
num_trips
;
memcpy
(
tz
->
trips
,
trips
,
num_trips
*
sizeof
(
*
trips
));
for_each_trip_desc
(
tz
,
td
)
td
->
trip
=
*
trip
++
;
thermal_set_delay_jiffies
(
&
tz
->
passive_delay_jiffies
,
passive_delay
);
thermal_set_delay_jiffies
(
&
tz
->
passive_delay_jiffies
,
passive_delay
);
thermal_set_delay_jiffies
(
&
tz
->
polling_delay_jiffies
,
polling_delay
);
thermal_set_delay_jiffies
(
&
tz
->
polling_delay_jiffies
,
polling_delay
);
...
...
drivers/thermal/thermal_core.h
View file @
5c897a9a
...
@@ -15,6 +15,118 @@
...
@@ -15,6 +15,118 @@
#include "thermal_netlink.h"
#include "thermal_netlink.h"
#include "thermal_debugfs.h"
#include "thermal_debugfs.h"
struct
thermal_trip_desc
{
struct
thermal_trip
trip
;
struct
list_head
notify_list_node
;
int
notify_temp
;
int
threshold
;
};
/**
* struct thermal_governor - structure that holds thermal governor information
* @name: name of the governor
* @bind_to_tz: callback called when binding to a thermal zone. If it
* returns 0, the governor is bound to the thermal zone,
* otherwise it fails.
* @unbind_from_tz: callback called when a governor is unbound from a
* thermal zone.
* @throttle: callback called for every trip point even if temperature is
* below the trip point temperature
* @update_tz: callback called when thermal zone internals have changed, e.g.
* thermal cooling instance was added/removed
* @governor_list: node in thermal_governor_list (in thermal_core.c)
*/
struct
thermal_governor
{
const
char
*
name
;
int
(
*
bind_to_tz
)(
struct
thermal_zone_device
*
tz
);
void
(
*
unbind_from_tz
)(
struct
thermal_zone_device
*
tz
);
int
(
*
throttle
)(
struct
thermal_zone_device
*
tz
,
const
struct
thermal_trip
*
trip
);
void
(
*
update_tz
)(
struct
thermal_zone_device
*
tz
,
enum
thermal_notify_event
reason
);
struct
list_head
governor_list
;
};
/**
* struct thermal_zone_device - structure for a thermal zone
* @id: unique id number for each thermal zone
* @type: the thermal zone device type
* @device: &struct device for this thermal zone
* @removal: removal completion
* @trip_temp_attrs: attributes for trip points for sysfs: trip temperature
* @trip_type_attrs: attributes for trip points for sysfs: trip type
* @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
* @mode: current mode of this thermal zone
* @devdata: private pointer for device private data
* @num_trips: number of trip points the thermal zone supports
* @passive_delay_jiffies: number of jiffies to wait between polls when
* performing passive cooling.
* @polling_delay_jiffies: number of jiffies to wait between polls when
* checking whether trip points have been crossed (0 for
* interrupt driven systems)
* @temperature: current temperature. This is only for core code,
* drivers should use thermal_zone_get_temp() to get the
* current temperature
* @last_temperature: previous temperature read
* @emul_temperature: emulated temperature when using CONFIG_THERMAL_EMULATION
* @passive: 1 if you've crossed a passive trip point, 0 otherwise.
* @prev_low_trip: the low current temperature if you've crossed a passive
trip point.
* @prev_high_trip: the above current temperature if you've crossed a
passive trip point.
* @need_update: if equals 1, thermal_zone_device_update needs to be invoked.
* @ops: operations this &thermal_zone_device supports
* @tzp: thermal zone parameters
* @governor: pointer to the governor for this thermal zone
* @governor_data: private pointer for governor data
* @thermal_instances: list of &struct thermal_instance of this thermal zone
* @ida: &struct ida to generate unique id for this zone's cooling
* devices
* @lock: lock to protect thermal_instances list
* @node: node in thermal_tz_list (in thermal_core.c)
* @poll_queue: delayed work for polling
* @notify_event: Last notification event
* @suspended: thermal zone suspend indicator
* @trips: array of struct thermal_trip objects
*/
struct
thermal_zone_device
{
int
id
;
char
type
[
THERMAL_NAME_LENGTH
];
struct
device
device
;
struct
completion
removal
;
struct
attribute_group
trips_attribute_group
;
struct
thermal_attr
*
trip_temp_attrs
;
struct
thermal_attr
*
trip_type_attrs
;
struct
thermal_attr
*
trip_hyst_attrs
;
enum
thermal_device_mode
mode
;
void
*
devdata
;
int
num_trips
;
unsigned
long
passive_delay_jiffies
;
unsigned
long
polling_delay_jiffies
;
int
temperature
;
int
last_temperature
;
int
emul_temperature
;
int
passive
;
int
prev_low_trip
;
int
prev_high_trip
;
atomic_t
need_update
;
struct
thermal_zone_device_ops
ops
;
struct
thermal_zone_params
*
tzp
;
struct
thermal_governor
*
governor
;
void
*
governor_data
;
struct
list_head
thermal_instances
;
struct
ida
ida
;
struct
mutex
lock
;
struct
list_head
node
;
struct
delayed_work
poll_queue
;
enum
thermal_notify_event
notify_event
;
bool
suspended
;
#ifdef CONFIG_THERMAL_DEBUGFS
struct
thermal_debugfs
*
debugfs
;
#endif
struct
thermal_trip_desc
trips
[]
__counted_by
(
num_trips
);
};
/* Default Thermal Governor */
/* Default Thermal Governor */
#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
#define DEFAULT_THERMAL_GOVERNOR "step_wise"
#define DEFAULT_THERMAL_GOVERNOR "step_wise"
...
@@ -120,8 +232,11 @@ void thermal_governor_update_tz(struct thermal_zone_device *tz,
...
@@ -120,8 +232,11 @@ void thermal_governor_update_tz(struct thermal_zone_device *tz,
enum
thermal_notify_event
reason
);
enum
thermal_notify_event
reason
);
/* Helpers */
/* Helpers */
#define for_each_trip(__tz, __trip) \
#define for_each_trip_desc(__tz, __td) \
for (__trip = __tz->trips; __trip - __tz->trips < __tz->num_trips; __trip++)
for (__td = __tz->trips; __td - __tz->trips < __tz->num_trips; __td++)
#define trip_to_trip_desc(__trip) \
container_of(__trip, struct thermal_trip_desc, trip)
void
__thermal_zone_set_trips
(
struct
thermal_zone_device
*
tz
);
void
__thermal_zone_set_trips
(
struct
thermal_zone_device
*
tz
);
int
thermal_zone_trip_id
(
const
struct
thermal_zone_device
*
tz
,
int
thermal_zone_trip_id
(
const
struct
thermal_zone_device
*
tz
,
...
...
drivers/thermal/thermal_debugfs.c
View file @
5c897a9a
...
@@ -745,7 +745,7 @@ static void tze_seq_stop(struct seq_file *s, void *v)
...
@@ -745,7 +745,7 @@ static void tze_seq_stop(struct seq_file *s, void *v)
static
int
tze_seq_show
(
struct
seq_file
*
s
,
void
*
v
)
static
int
tze_seq_show
(
struct
seq_file
*
s
,
void
*
v
)
{
{
struct
thermal_zone_device
*
tz
=
s
->
private
;
struct
thermal_zone_device
*
tz
=
s
->
private
;
struct
thermal_trip
*
trip
;
struct
thermal_trip
_desc
*
td
;
struct
tz_episode
*
tze
;
struct
tz_episode
*
tze
;
const
char
*
type
;
const
char
*
type
;
int
trip_id
;
int
trip_id
;
...
@@ -758,7 +758,9 @@ static int tze_seq_show(struct seq_file *s, void *v)
...
@@ -758,7 +758,9 @@ static int tze_seq_show(struct seq_file *s, void *v)
seq_printf
(
s
,
"| trip | type | temp(°mC) | hyst(°mC) | duration | avg(°mC) | min(°mC) | max(°mC) |
\n
"
);
seq_printf
(
s
,
"| trip | type | temp(°mC) | hyst(°mC) | duration | avg(°mC) | min(°mC) | max(°mC) |
\n
"
);
for_each_trip
(
tz
,
trip
)
{
for_each_trip_desc
(
tz
,
td
)
{
const
struct
thermal_trip
*
trip
=
&
td
->
trip
;
/*
/*
* There is no possible mitigation happening at the
* There is no possible mitigation happening at the
* critical trip point, so the stats will be always
* critical trip point, so the stats will be always
...
...
drivers/thermal/thermal_helpers.c
View file @
5c897a9a
...
@@ -50,7 +50,7 @@ get_thermal_instance(struct thermal_zone_device *tz,
...
@@ -50,7 +50,7 @@ get_thermal_instance(struct thermal_zone_device *tz,
mutex_lock
(
&
tz
->
lock
);
mutex_lock
(
&
tz
->
lock
);
mutex_lock
(
&
cdev
->
lock
);
mutex_lock
(
&
cdev
->
lock
);
trip
=
&
tz
->
trips
[
trip_index
];
trip
=
&
tz
->
trips
[
trip_index
]
.
trip
;
list_for_each_entry
(
pos
,
&
tz
->
thermal_instances
,
tz_node
)
{
list_for_each_entry
(
pos
,
&
tz
->
thermal_instances
,
tz_node
)
{
if
(
pos
->
tz
==
tz
&&
pos
->
trip
==
trip
&&
pos
->
cdev
==
cdev
)
{
if
(
pos
->
tz
==
tz
&&
pos
->
trip
==
trip
&&
pos
->
cdev
==
cdev
)
{
...
@@ -82,7 +82,7 @@ EXPORT_SYMBOL(get_thermal_instance);
...
@@ -82,7 +82,7 @@ EXPORT_SYMBOL(get_thermal_instance);
*/
*/
int
__thermal_zone_get_temp
(
struct
thermal_zone_device
*
tz
,
int
*
temp
)
int
__thermal_zone_get_temp
(
struct
thermal_zone_device
*
tz
,
int
*
temp
)
{
{
const
struct
thermal_trip
*
trip
;
const
struct
thermal_trip
_desc
*
td
;
int
crit_temp
=
INT_MAX
;
int
crit_temp
=
INT_MAX
;
int
ret
=
-
EINVAL
;
int
ret
=
-
EINVAL
;
...
@@ -91,7 +91,9 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
...
@@ -91,7 +91,9 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
ret
=
tz
->
ops
.
get_temp
(
tz
,
temp
);
ret
=
tz
->
ops
.
get_temp
(
tz
,
temp
);
if
(
IS_ENABLED
(
CONFIG_THERMAL_EMULATION
)
&&
tz
->
emul_temperature
)
{
if
(
IS_ENABLED
(
CONFIG_THERMAL_EMULATION
)
&&
tz
->
emul_temperature
)
{
for_each_trip
(
tz
,
trip
)
{
for_each_trip_desc
(
tz
,
td
)
{
const
struct
thermal_trip
*
trip
=
&
td
->
trip
;
if
(
trip
->
type
==
THERMAL_TRIP_CRITICAL
)
{
if
(
trip
->
type
==
THERMAL_TRIP_CRITICAL
)
{
crit_temp
=
trip
->
temperature
;
crit_temp
=
trip
->
temperature
;
break
;
break
;
...
...
drivers/thermal/thermal_netlink.c
View file @
5c897a9a
...
@@ -7,17 +7,13 @@
...
@@ -7,17 +7,13 @@
* Generic netlink for thermal management framework
* Generic netlink for thermal management framework
*/
*/
#include <linux/module.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <net/genetlink.h>
#include <net/genetlink.h>
#include <uapi/linux/thermal.h>
#include <uapi/linux/thermal.h>
#include "thermal_core.h"
#include "thermal_core.h"
enum
thermal_genl_multicast_groups
{
THERMAL_GENL_SAMPLING_GROUP
=
0
,
THERMAL_GENL_EVENT_GROUP
=
1
,
};
static
const
struct
genl_multicast_group
thermal_genl_mcgrps
[]
=
{
static
const
struct
genl_multicast_group
thermal_genl_mcgrps
[]
=
{
[
THERMAL_GENL_SAMPLING_GROUP
]
=
{
.
name
=
THERMAL_GENL_SAMPLING_GROUP_NAME
,
},
[
THERMAL_GENL_SAMPLING_GROUP
]
=
{
.
name
=
THERMAL_GENL_SAMPLING_GROUP_NAME
,
},
[
THERMAL_GENL_EVENT_GROUP
]
=
{
.
name
=
THERMAL_GENL_EVENT_GROUP_NAME
,
},
[
THERMAL_GENL_EVENT_GROUP
]
=
{
.
name
=
THERMAL_GENL_EVENT_GROUP_NAME
,
},
...
@@ -74,11 +70,12 @@ struct param {
...
@@ -74,11 +70,12 @@ struct param {
typedef
int
(
*
cb_t
)(
struct
param
*
);
typedef
int
(
*
cb_t
)(
struct
param
*
);
static
struct
genl_family
thermal_gnl_family
;
static
struct
genl_family
thermal_genl_family
;
static
BLOCKING_NOTIFIER_HEAD
(
thermal_genl_chain
);
static
int
thermal_group_has_listeners
(
enum
thermal_genl_multicast_groups
group
)
static
int
thermal_group_has_listeners
(
enum
thermal_genl_multicast_groups
group
)
{
{
return
genl_has_listeners
(
&
thermal_gnl_family
,
&
init_net
,
group
);
return
genl_has_listeners
(
&
thermal_g
e
nl_family
,
&
init_net
,
group
);
}
}
/************************** Sampling encoding *******************************/
/************************** Sampling encoding *******************************/
...
@@ -95,7 +92,7 @@ int thermal_genl_sampling_temp(int id, int temp)
...
@@ -95,7 +92,7 @@ int thermal_genl_sampling_temp(int id, int temp)
if
(
!
skb
)
if
(
!
skb
)
return
-
ENOMEM
;
return
-
ENOMEM
;
hdr
=
genlmsg_put
(
skb
,
0
,
0
,
&
thermal_gnl_family
,
0
,
hdr
=
genlmsg_put
(
skb
,
0
,
0
,
&
thermal_g
e
nl_family
,
0
,
THERMAL_GENL_SAMPLING_TEMP
);
THERMAL_GENL_SAMPLING_TEMP
);
if
(
!
hdr
)
if
(
!
hdr
)
goto
out_free
;
goto
out_free
;
...
@@ -108,7 +105,7 @@ int thermal_genl_sampling_temp(int id, int temp)
...
@@ -108,7 +105,7 @@ int thermal_genl_sampling_temp(int id, int temp)
genlmsg_end
(
skb
,
hdr
);
genlmsg_end
(
skb
,
hdr
);
genlmsg_multicast
(
&
thermal_gnl_family
,
skb
,
0
,
THERMAL_GENL_SAMPLING_GROUP
,
GFP_KERNEL
);
genlmsg_multicast
(
&
thermal_g
e
nl_family
,
skb
,
0
,
THERMAL_GENL_SAMPLING_GROUP
,
GFP_KERNEL
);
return
0
;
return
0
;
out_cancel:
out_cancel:
...
@@ -282,7 +279,7 @@ static int thermal_genl_send_event(enum thermal_genl_event event,
...
@@ -282,7 +279,7 @@ static int thermal_genl_send_event(enum thermal_genl_event event,
return
-
ENOMEM
;
return
-
ENOMEM
;
p
->
msg
=
msg
;
p
->
msg
=
msg
;
hdr
=
genlmsg_put
(
msg
,
0
,
0
,
&
thermal_gnl_family
,
0
,
event
);
hdr
=
genlmsg_put
(
msg
,
0
,
0
,
&
thermal_g
e
nl_family
,
0
,
event
);
if
(
!
hdr
)
if
(
!
hdr
)
goto
out_free_msg
;
goto
out_free_msg
;
...
@@ -292,7 +289,7 @@ static int thermal_genl_send_event(enum thermal_genl_event event,
...
@@ -292,7 +289,7 @@ static int thermal_genl_send_event(enum thermal_genl_event event,
genlmsg_end
(
msg
,
hdr
);
genlmsg_end
(
msg
,
hdr
);
genlmsg_multicast
(
&
thermal_gnl_family
,
msg
,
0
,
THERMAL_GENL_EVENT_GROUP
,
GFP_KERNEL
);
genlmsg_multicast
(
&
thermal_g
e
nl_family
,
msg
,
0
,
THERMAL_GENL_EVENT_GROUP
,
GFP_KERNEL
);
return
0
;
return
0
;
...
@@ -445,7 +442,7 @@ static int thermal_genl_cmd_tz_get_id(struct param *p)
...
@@ -445,7 +442,7 @@ static int thermal_genl_cmd_tz_get_id(struct param *p)
static
int
thermal_genl_cmd_tz_get_trip
(
struct
param
*
p
)
static
int
thermal_genl_cmd_tz_get_trip
(
struct
param
*
p
)
{
{
struct
sk_buff
*
msg
=
p
->
msg
;
struct
sk_buff
*
msg
=
p
->
msg
;
const
struct
thermal_trip
*
trip
;
const
struct
thermal_trip
_desc
*
td
;
struct
thermal_zone_device
*
tz
;
struct
thermal_zone_device
*
tz
;
struct
nlattr
*
start_trip
;
struct
nlattr
*
start_trip
;
int
id
;
int
id
;
...
@@ -465,7 +462,9 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
...
@@ -465,7 +462,9 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
mutex_lock
(
&
tz
->
lock
);
mutex_lock
(
&
tz
->
lock
);
for_each_trip
(
tz
,
trip
)
{
for_each_trip_desc
(
tz
,
td
)
{
const
struct
thermal_trip
*
trip
=
&
td
->
trip
;
if
(
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_ID
,
if
(
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_ID
,
thermal_zone_trip_id
(
tz
,
trip
))
||
thermal_zone_trip_id
(
tz
,
trip
))
||
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_TYPE
,
trip
->
type
)
||
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_TYPE
,
trip
->
type
)
||
...
@@ -593,7 +592,7 @@ static int thermal_genl_cmd_dumpit(struct sk_buff *skb,
...
@@ -593,7 +592,7 @@ static int thermal_genl_cmd_dumpit(struct sk_buff *skb,
int
ret
;
int
ret
;
void
*
hdr
;
void
*
hdr
;
hdr
=
genlmsg_put
(
skb
,
0
,
0
,
&
thermal_gnl_family
,
0
,
cmd
);
hdr
=
genlmsg_put
(
skb
,
0
,
0
,
&
thermal_g
e
nl_family
,
0
,
cmd
);
if
(
!
hdr
)
if
(
!
hdr
)
return
-
EMSGSIZE
;
return
-
EMSGSIZE
;
...
@@ -625,7 +624,7 @@ static int thermal_genl_cmd_doit(struct sk_buff *skb,
...
@@ -625,7 +624,7 @@ static int thermal_genl_cmd_doit(struct sk_buff *skb,
return
-
ENOMEM
;
return
-
ENOMEM
;
p
.
msg
=
msg
;
p
.
msg
=
msg
;
hdr
=
genlmsg_put_reply
(
msg
,
info
,
&
thermal_gnl_family
,
0
,
cmd
);
hdr
=
genlmsg_put_reply
(
msg
,
info
,
&
thermal_g
e
nl_family
,
0
,
cmd
);
if
(
!
hdr
)
if
(
!
hdr
)
goto
out_free_msg
;
goto
out_free_msg
;
...
@@ -645,6 +644,27 @@ static int thermal_genl_cmd_doit(struct sk_buff *skb,
...
@@ -645,6 +644,27 @@ static int thermal_genl_cmd_doit(struct sk_buff *skb,
return
ret
;
return
ret
;
}
}
static
int
thermal_genl_bind
(
int
mcgrp
)
{
struct
thermal_genl_notify
n
=
{
.
mcgrp
=
mcgrp
};
if
(
WARN_ON_ONCE
(
mcgrp
>
THERMAL_GENL_MAX_GROUP
))
return
-
EINVAL
;
blocking_notifier_call_chain
(
&
thermal_genl_chain
,
THERMAL_NOTIFY_BIND
,
&
n
);
return
0
;
}
static
void
thermal_genl_unbind
(
int
mcgrp
)
{
struct
thermal_genl_notify
n
=
{
.
mcgrp
=
mcgrp
};
if
(
WARN_ON_ONCE
(
mcgrp
>
THERMAL_GENL_MAX_GROUP
))
return
;
blocking_notifier_call_chain
(
&
thermal_genl_chain
,
THERMAL_NOTIFY_UNBIND
,
&
n
);
}
static
const
struct
genl_small_ops
thermal_genl_ops
[]
=
{
static
const
struct
genl_small_ops
thermal_genl_ops
[]
=
{
{
{
.
cmd
=
THERMAL_GENL_CMD_TZ_GET_ID
,
.
cmd
=
THERMAL_GENL_CMD_TZ_GET_ID
,
...
@@ -673,12 +693,14 @@ static const struct genl_small_ops thermal_genl_ops[] = {
...
@@ -673,12 +693,14 @@ static const struct genl_small_ops thermal_genl_ops[] = {
},
},
};
};
static
struct
genl_family
thermal_gnl_family
__ro_after_init
=
{
static
struct
genl_family
thermal_g
e
nl_family
__ro_after_init
=
{
.
hdrsize
=
0
,
.
hdrsize
=
0
,
.
name
=
THERMAL_GENL_FAMILY_NAME
,
.
name
=
THERMAL_GENL_FAMILY_NAME
,
.
version
=
THERMAL_GENL_VERSION
,
.
version
=
THERMAL_GENL_VERSION
,
.
maxattr
=
THERMAL_GENL_ATTR_MAX
,
.
maxattr
=
THERMAL_GENL_ATTR_MAX
,
.
policy
=
thermal_genl_policy
,
.
policy
=
thermal_genl_policy
,
.
bind
=
thermal_genl_bind
,
.
unbind
=
thermal_genl_unbind
,
.
small_ops
=
thermal_genl_ops
,
.
small_ops
=
thermal_genl_ops
,
.
n_small_ops
=
ARRAY_SIZE
(
thermal_genl_ops
),
.
n_small_ops
=
ARRAY_SIZE
(
thermal_genl_ops
),
.
resv_start_op
=
THERMAL_GENL_CMD_CDEV_GET
+
1
,
.
resv_start_op
=
THERMAL_GENL_CMD_CDEV_GET
+
1
,
...
@@ -686,12 +708,22 @@ static struct genl_family thermal_gnl_family __ro_after_init = {
...
@@ -686,12 +708,22 @@ static struct genl_family thermal_gnl_family __ro_after_init = {
.
n_mcgrps
=
ARRAY_SIZE
(
thermal_genl_mcgrps
),
.
n_mcgrps
=
ARRAY_SIZE
(
thermal_genl_mcgrps
),
};
};
int
thermal_genl_register_notifier
(
struct
notifier_block
*
nb
)
{
return
blocking_notifier_chain_register
(
&
thermal_genl_chain
,
nb
);
}
int
thermal_genl_unregister_notifier
(
struct
notifier_block
*
nb
)
{
return
blocking_notifier_chain_unregister
(
&
thermal_genl_chain
,
nb
);
}
int
__init
thermal_netlink_init
(
void
)
int
__init
thermal_netlink_init
(
void
)
{
{
return
genl_register_family
(
&
thermal_gnl_family
);
return
genl_register_family
(
&
thermal_g
e
nl_family
);
}
}
void
__init
thermal_netlink_exit
(
void
)
void
__init
thermal_netlink_exit
(
void
)
{
{
genl_unregister_family
(
&
thermal_gnl_family
);
genl_unregister_family
(
&
thermal_g
e
nl_family
);
}
}
drivers/thermal/thermal_netlink.h
View file @
5c897a9a
...
@@ -10,6 +10,19 @@ struct thermal_genl_cpu_caps {
...
@@ -10,6 +10,19 @@ struct thermal_genl_cpu_caps {
int
efficiency
;
int
efficiency
;
};
};
enum
thermal_genl_multicast_groups
{
THERMAL_GENL_SAMPLING_GROUP
=
0
,
THERMAL_GENL_EVENT_GROUP
=
1
,
THERMAL_GENL_MAX_GROUP
=
THERMAL_GENL_EVENT_GROUP
,
};
#define THERMAL_NOTIFY_BIND 0
#define THERMAL_NOTIFY_UNBIND 1
struct
thermal_genl_notify
{
int
mcgrp
;
};
struct
thermal_zone_device
;
struct
thermal_zone_device
;
struct
thermal_trip
;
struct
thermal_trip
;
struct
thermal_cooling_device
;
struct
thermal_cooling_device
;
...
@@ -18,6 +31,9 @@ struct thermal_cooling_device;
...
@@ -18,6 +31,9 @@ struct thermal_cooling_device;
#ifdef CONFIG_THERMAL_NETLINK
#ifdef CONFIG_THERMAL_NETLINK
int
__init
thermal_netlink_init
(
void
);
int
__init
thermal_netlink_init
(
void
);
void
__init
thermal_netlink_exit
(
void
);
void
__init
thermal_netlink_exit
(
void
);
int
thermal_genl_register_notifier
(
struct
notifier_block
*
nb
);
int
thermal_genl_unregister_notifier
(
struct
notifier_block
*
nb
);
int
thermal_notify_tz_create
(
const
struct
thermal_zone_device
*
tz
);
int
thermal_notify_tz_create
(
const
struct
thermal_zone_device
*
tz
);
int
thermal_notify_tz_delete
(
const
struct
thermal_zone_device
*
tz
);
int
thermal_notify_tz_delete
(
const
struct
thermal_zone_device
*
tz
);
int
thermal_notify_tz_enable
(
const
struct
thermal_zone_device
*
tz
);
int
thermal_notify_tz_enable
(
const
struct
thermal_zone_device
*
tz
);
...
@@ -48,6 +64,16 @@ static inline int thermal_notify_tz_create(const struct thermal_zone_device *tz)
...
@@ -48,6 +64,16 @@ static inline int thermal_notify_tz_create(const struct thermal_zone_device *tz)
return
0
;
return
0
;
}
}
static
inline
int
thermal_genl_register_notifier
(
struct
notifier_block
*
nb
)
{
return
0
;
}
static
inline
int
thermal_genl_unregister_notifier
(
struct
notifier_block
*
nb
)
{
return
0
;
}
static
inline
int
thermal_notify_tz_delete
(
const
struct
thermal_zone_device
*
tz
)
static
inline
int
thermal_notify_tz_delete
(
const
struct
thermal_zone_device
*
tz
)
{
{
return
0
;
return
0
;
...
...
drivers/thermal/thermal_sysfs.c
View file @
5c897a9a
...
@@ -88,7 +88,7 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
...
@@ -88,7 +88,7 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_type"
,
&
trip_id
)
!=
1
)
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_type"
,
&
trip_id
)
!=
1
)
return
-
EINVAL
;
return
-
EINVAL
;
switch
(
tz
->
trips
[
trip_id
].
type
)
{
switch
(
tz
->
trips
[
trip_id
].
t
rip
.
t
ype
)
{
case
THERMAL_TRIP_CRITICAL
:
case
THERMAL_TRIP_CRITICAL
:
return
sprintf
(
buf
,
"critical
\n
"
);
return
sprintf
(
buf
,
"critical
\n
"
);
case
THERMAL_TRIP_HOT
:
case
THERMAL_TRIP_HOT
:
...
@@ -120,7 +120,7 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
...
@@ -120,7 +120,7 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
mutex_lock
(
&
tz
->
lock
);
mutex_lock
(
&
tz
->
lock
);
trip
=
&
tz
->
trips
[
trip_id
];
trip
=
&
tz
->
trips
[
trip_id
]
.
trip
;
if
(
temp
!=
trip
->
temperature
)
{
if
(
temp
!=
trip
->
temperature
)
{
if
(
tz
->
ops
.
set_trip_temp
)
{
if
(
tz
->
ops
.
set_trip_temp
)
{
...
@@ -150,7 +150,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
...
@@ -150,7 +150,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_temp"
,
&
trip_id
)
!=
1
)
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_temp"
,
&
trip_id
)
!=
1
)
return
-
EINVAL
;
return
-
EINVAL
;
return
sprintf
(
buf
,
"%d
\n
"
,
tz
->
trips
[
trip_id
].
temperature
);
return
sprintf
(
buf
,
"%d
\n
"
,
tz
->
trips
[
trip_id
].
t
rip
.
t
emperature
);
}
}
static
ssize_t
static
ssize_t
...
@@ -171,7 +171,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
...
@@ -171,7 +171,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
mutex_lock
(
&
tz
->
lock
);
mutex_lock
(
&
tz
->
lock
);
trip
=
&
tz
->
trips
[
trip_id
];
trip
=
&
tz
->
trips
[
trip_id
]
.
trip
;
if
(
hyst
!=
trip
->
hysteresis
)
{
if
(
hyst
!=
trip
->
hysteresis
)
{
trip
->
hysteresis
=
hyst
;
trip
->
hysteresis
=
hyst
;
...
@@ -194,7 +194,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
...
@@ -194,7 +194,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_hyst"
,
&
trip_id
)
!=
1
)
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_hyst"
,
&
trip_id
)
!=
1
)
return
-
EINVAL
;
return
-
EINVAL
;
return
sprintf
(
buf
,
"%d
\n
"
,
tz
->
trips
[
trip_id
].
hysteresis
);
return
sprintf
(
buf
,
"%d
\n
"
,
tz
->
trips
[
trip_id
].
trip
.
hysteresis
);
}
}
static
ssize_t
static
ssize_t
...
@@ -393,7 +393,7 @@ static const struct attribute_group *thermal_zone_attribute_groups[] = {
...
@@ -393,7 +393,7 @@ static const struct attribute_group *thermal_zone_attribute_groups[] = {
*/
*/
static
int
create_trip_attrs
(
struct
thermal_zone_device
*
tz
)
static
int
create_trip_attrs
(
struct
thermal_zone_device
*
tz
)
{
{
const
struct
thermal_trip
*
trip
;
const
struct
thermal_trip
_desc
*
td
;
struct
attribute
**
attrs
;
struct
attribute
**
attrs
;
/* This function works only for zones with at least one trip */
/* This function works only for zones with at least one trip */
...
@@ -429,8 +429,8 @@ static int create_trip_attrs(struct thermal_zone_device *tz)
...
@@ -429,8 +429,8 @@ static int create_trip_attrs(struct thermal_zone_device *tz)
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
for_each_trip
(
tz
,
trip
)
{
for_each_trip
_desc
(
tz
,
td
)
{
int
indx
=
thermal_zone_trip_id
(
tz
,
trip
);
int
indx
=
thermal_zone_trip_id
(
tz
,
&
td
->
trip
);
/* create trip type attribute */
/* create trip type attribute */
snprintf
(
tz
->
trip_type_attrs
[
indx
].
name
,
THERMAL_NAME_LENGTH
,
snprintf
(
tz
->
trip_type_attrs
[
indx
].
name
,
THERMAL_NAME_LENGTH
,
...
@@ -452,7 +452,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz)
...
@@ -452,7 +452,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz)
tz
->
trip_temp_attrs
[
indx
].
name
;
tz
->
trip_temp_attrs
[
indx
].
name
;
tz
->
trip_temp_attrs
[
indx
].
attr
.
attr
.
mode
=
S_IRUGO
;
tz
->
trip_temp_attrs
[
indx
].
attr
.
attr
.
mode
=
S_IRUGO
;
tz
->
trip_temp_attrs
[
indx
].
attr
.
show
=
trip_point_temp_show
;
tz
->
trip_temp_attrs
[
indx
].
attr
.
show
=
trip_point_temp_show
;
if
(
t
rip
->
flags
&
THERMAL_TRIP_FLAG_RW_TEMP
)
{
if
(
t
d
->
trip
.
flags
&
THERMAL_TRIP_FLAG_RW_TEMP
)
{
tz
->
trip_temp_attrs
[
indx
].
attr
.
attr
.
mode
|=
S_IWUSR
;
tz
->
trip_temp_attrs
[
indx
].
attr
.
attr
.
mode
|=
S_IWUSR
;
tz
->
trip_temp_attrs
[
indx
].
attr
.
store
=
tz
->
trip_temp_attrs
[
indx
].
attr
.
store
=
trip_point_temp_store
;
trip_point_temp_store
;
...
@@ -467,7 +467,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz)
...
@@ -467,7 +467,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz)
tz
->
trip_hyst_attrs
[
indx
].
name
;
tz
->
trip_hyst_attrs
[
indx
].
name
;
tz
->
trip_hyst_attrs
[
indx
].
attr
.
attr
.
mode
=
S_IRUGO
;
tz
->
trip_hyst_attrs
[
indx
].
attr
.
attr
.
mode
=
S_IRUGO
;
tz
->
trip_hyst_attrs
[
indx
].
attr
.
show
=
trip_point_hyst_show
;
tz
->
trip_hyst_attrs
[
indx
].
attr
.
show
=
trip_point_hyst_show
;
if
(
t
rip
->
flags
&
THERMAL_TRIP_FLAG_RW_HYST
)
{
if
(
t
d
->
trip
.
flags
&
THERMAL_TRIP_FLAG_RW_HYST
)
{
tz
->
trip_hyst_attrs
[
indx
].
attr
.
attr
.
mode
|=
S_IWUSR
;
tz
->
trip_hyst_attrs
[
indx
].
attr
.
attr
.
mode
|=
S_IWUSR
;
tz
->
trip_hyst_attrs
[
indx
].
attr
.
store
=
tz
->
trip_hyst_attrs
[
indx
].
attr
.
store
=
trip_point_hyst_store
;
trip_point_hyst_store
;
...
...
drivers/thermal/thermal_trace.h
View file @
5c897a9a
...
@@ -9,6 +9,8 @@
...
@@ -9,6 +9,8 @@
#include <linux/thermal.h>
#include <linux/thermal.h>
#include <linux/tracepoint.h>
#include <linux/tracepoint.h>
#include "thermal_core.h"
TRACE_DEFINE_ENUM
(
THERMAL_TRIP_CRITICAL
);
TRACE_DEFINE_ENUM
(
THERMAL_TRIP_CRITICAL
);
TRACE_DEFINE_ENUM
(
THERMAL_TRIP_HOT
);
TRACE_DEFINE_ENUM
(
THERMAL_TRIP_HOT
);
TRACE_DEFINE_ENUM
(
THERMAL_TRIP_PASSIVE
);
TRACE_DEFINE_ENUM
(
THERMAL_TRIP_PASSIVE
);
...
...
drivers/thermal/thermal_trace_ipa.h
View file @
5c897a9a
...
@@ -7,6 +7,8 @@
...
@@ -7,6 +7,8 @@
#include <linux/tracepoint.h>
#include <linux/tracepoint.h>
#include "thermal_core.h"
TRACE_EVENT
(
thermal_power_allocator
,
TRACE_EVENT
(
thermal_power_allocator
,
TP_PROTO
(
struct
thermal_zone_device
*
tz
,
u32
total_req_power
,
TP_PROTO
(
struct
thermal_zone_device
*
tz
,
u32
total_req_power
,
u32
total_granted_power
,
int
num_actors
,
u32
power_range
,
u32
total_granted_power
,
int
num_actors
,
u32
power_range
,
...
...
drivers/thermal/thermal_trip.c
View file @
5c897a9a
...
@@ -13,11 +13,11 @@ int for_each_thermal_trip(struct thermal_zone_device *tz,
...
@@ -13,11 +13,11 @@ int for_each_thermal_trip(struct thermal_zone_device *tz,
int
(
*
cb
)(
struct
thermal_trip
*
,
void
*
),
int
(
*
cb
)(
struct
thermal_trip
*
,
void
*
),
void
*
data
)
void
*
data
)
{
{
struct
thermal_trip
*
trip
;
struct
thermal_trip
_desc
*
td
;
int
ret
;
int
ret
;
for_each_trip
(
tz
,
trip
)
{
for_each_trip
_desc
(
tz
,
td
)
{
ret
=
cb
(
trip
,
data
);
ret
=
cb
(
&
td
->
trip
,
data
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
}
}
...
@@ -63,7 +63,7 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_num_trips);
...
@@ -63,7 +63,7 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_num_trips);
*/
*/
void
__thermal_zone_set_trips
(
struct
thermal_zone_device
*
tz
)
void
__thermal_zone_set_trips
(
struct
thermal_zone_device
*
tz
)
{
{
const
struct
thermal_trip
*
trip
;
const
struct
thermal_trip
_desc
*
td
;
int
low
=
-
INT_MAX
,
high
=
INT_MAX
;
int
low
=
-
INT_MAX
,
high
=
INT_MAX
;
int
ret
;
int
ret
;
...
@@ -72,7 +72,8 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz)
...
@@ -72,7 +72,8 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz)
if
(
!
tz
->
ops
.
set_trips
)
if
(
!
tz
->
ops
.
set_trips
)
return
;
return
;
for_each_trip
(
tz
,
trip
)
{
for_each_trip_desc
(
tz
,
td
)
{
const
struct
thermal_trip
*
trip
=
&
td
->
trip
;
int
trip_low
;
int
trip_low
;
trip_low
=
trip
->
temperature
-
trip
->
hysteresis
;
trip_low
=
trip
->
temperature
-
trip
->
hysteresis
;
...
@@ -110,7 +111,7 @@ int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
...
@@ -110,7 +111,7 @@ int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
if
(
!
tz
||
trip_id
<
0
||
trip_id
>=
tz
->
num_trips
||
!
trip
)
if
(
!
tz
||
trip_id
<
0
||
trip_id
>=
tz
->
num_trips
||
!
trip
)
return
-
EINVAL
;
return
-
EINVAL
;
*
trip
=
tz
->
trips
[
trip_id
];
*
trip
=
tz
->
trips
[
trip_id
]
.
trip
;
return
0
;
return
0
;
}
}
EXPORT_SYMBOL_GPL
(
__thermal_zone_get_trip
);
EXPORT_SYMBOL_GPL
(
__thermal_zone_get_trip
);
...
@@ -135,7 +136,7 @@ int thermal_zone_trip_id(const struct thermal_zone_device *tz,
...
@@ -135,7 +136,7 @@ int thermal_zone_trip_id(const struct thermal_zone_device *tz,
* Assume the trip to be located within the bounds of the thermal
* Assume the trip to be located within the bounds of the thermal
* zone's trips[] table.
* zone's trips[] table.
*/
*/
return
trip
-
tz
->
trips
;
return
trip
_to_trip_desc
(
trip
)
-
tz
->
trips
;
}
}
void
thermal_zone_trip_updated
(
struct
thermal_zone_device
*
tz
,
void
thermal_zone_trip_updated
(
struct
thermal_zone_device
*
tz
,
const
struct
thermal_trip
*
trip
)
const
struct
thermal_trip
*
trip
)
...
...
include/linux/thermal.h
View file @
5c897a9a
...
@@ -61,7 +61,6 @@ enum thermal_notify_event {
...
@@ -61,7 +61,6 @@ enum thermal_notify_event {
* struct thermal_trip - representation of a point in temperature domain
* struct thermal_trip - representation of a point in temperature domain
* @temperature: temperature value in miliCelsius
* @temperature: temperature value in miliCelsius
* @hysteresis: relative hysteresis in miliCelsius
* @hysteresis: relative hysteresis in miliCelsius
* @threshold: trip crossing notification threshold miliCelsius
* @type: trip point type
* @type: trip point type
* @priv: pointer to driver data associated with this trip
* @priv: pointer to driver data associated with this trip
* @flags: flags representing binary properties of the trip
* @flags: flags representing binary properties of the trip
...
@@ -69,7 +68,6 @@ enum thermal_notify_event {
...
@@ -69,7 +68,6 @@ enum thermal_notify_event {
struct
thermal_trip
{
struct
thermal_trip
{
int
temperature
;
int
temperature
;
int
hysteresis
;
int
hysteresis
;
int
threshold
;
enum
thermal_trip_type
type
;
enum
thermal_trip_type
type
;
u8
flags
;
u8
flags
;
void
*
priv
;
void
*
priv
;
...
@@ -81,6 +79,8 @@ struct thermal_trip {
...
@@ -81,6 +79,8 @@ struct thermal_trip {
#define THERMAL_TRIP_FLAG_RW (THERMAL_TRIP_FLAG_RW_TEMP | \
#define THERMAL_TRIP_FLAG_RW (THERMAL_TRIP_FLAG_RW_TEMP | \
THERMAL_TRIP_FLAG_RW_HYST)
THERMAL_TRIP_FLAG_RW_HYST)
struct
thermal_zone_device
;
struct
thermal_zone_device_ops
{
struct
thermal_zone_device_ops
{
int
(
*
bind
)
(
struct
thermal_zone_device
*
,
int
(
*
bind
)
(
struct
thermal_zone_device
*
,
struct
thermal_cooling_device
*
);
struct
thermal_cooling_device
*
);
...
@@ -126,111 +126,6 @@ struct thermal_cooling_device {
...
@@ -126,111 +126,6 @@ struct thermal_cooling_device {
#endif
#endif
};
};
/**
* struct thermal_zone_device - structure for a thermal zone
* @id: unique id number for each thermal zone
* @type: the thermal zone device type
* @device: &struct device for this thermal zone
* @removal: removal completion
* @trip_temp_attrs: attributes for trip points for sysfs: trip temperature
* @trip_type_attrs: attributes for trip points for sysfs: trip type
* @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
* @mode: current mode of this thermal zone
* @devdata: private pointer for device private data
* @num_trips: number of trip points the thermal zone supports
* @passive_delay_jiffies: number of jiffies to wait between polls when
* performing passive cooling.
* @polling_delay_jiffies: number of jiffies to wait between polls when
* checking whether trip points have been crossed (0 for
* interrupt driven systems)
* @temperature: current temperature. This is only for core code,
* drivers should use thermal_zone_get_temp() to get the
* current temperature
* @last_temperature: previous temperature read
* @emul_temperature: emulated temperature when using CONFIG_THERMAL_EMULATION
* @passive: 1 if you've crossed a passive trip point, 0 otherwise.
* @prev_low_trip: the low current temperature if you've crossed a passive
trip point.
* @prev_high_trip: the above current temperature if you've crossed a
passive trip point.
* @need_update: if equals 1, thermal_zone_device_update needs to be invoked.
* @ops: operations this &thermal_zone_device supports
* @tzp: thermal zone parameters
* @governor: pointer to the governor for this thermal zone
* @governor_data: private pointer for governor data
* @thermal_instances: list of &struct thermal_instance of this thermal zone
* @ida: &struct ida to generate unique id for this zone's cooling
* devices
* @lock: lock to protect thermal_instances list
* @node: node in thermal_tz_list (in thermal_core.c)
* @poll_queue: delayed work for polling
* @notify_event: Last notification event
* @suspended: thermal zone suspend indicator
* @trips: array of struct thermal_trip objects
*/
struct
thermal_zone_device
{
int
id
;
char
type
[
THERMAL_NAME_LENGTH
];
struct
device
device
;
struct
completion
removal
;
struct
attribute_group
trips_attribute_group
;
struct
thermal_attr
*
trip_temp_attrs
;
struct
thermal_attr
*
trip_type_attrs
;
struct
thermal_attr
*
trip_hyst_attrs
;
enum
thermal_device_mode
mode
;
void
*
devdata
;
int
num_trips
;
unsigned
long
passive_delay_jiffies
;
unsigned
long
polling_delay_jiffies
;
int
temperature
;
int
last_temperature
;
int
emul_temperature
;
int
passive
;
int
prev_low_trip
;
int
prev_high_trip
;
atomic_t
need_update
;
struct
thermal_zone_device_ops
ops
;
struct
thermal_zone_params
*
tzp
;
struct
thermal_governor
*
governor
;
void
*
governor_data
;
struct
list_head
thermal_instances
;
struct
ida
ida
;
struct
mutex
lock
;
struct
list_head
node
;
struct
delayed_work
poll_queue
;
enum
thermal_notify_event
notify_event
;
bool
suspended
;
#ifdef CONFIG_THERMAL_DEBUGFS
struct
thermal_debugfs
*
debugfs
;
#endif
struct
thermal_trip
trips
[]
__counted_by
(
num_trips
);
};
/**
* struct thermal_governor - structure that holds thermal governor information
* @name: name of the governor
* @bind_to_tz: callback called when binding to a thermal zone. If it
* returns 0, the governor is bound to the thermal zone,
* otherwise it fails.
* @unbind_from_tz: callback called when a governor is unbound from a
* thermal zone.
* @throttle: callback called for every trip point even if temperature is
* below the trip point temperature
* @update_tz: callback called when thermal zone internals have changed, e.g.
* thermal cooling instance was added/removed
* @governor_list: node in thermal_governor_list (in thermal_core.c)
*/
struct
thermal_governor
{
const
char
*
name
;
int
(
*
bind_to_tz
)(
struct
thermal_zone_device
*
tz
);
void
(
*
unbind_from_tz
)(
struct
thermal_zone_device
*
tz
);
int
(
*
throttle
)(
struct
thermal_zone_device
*
tz
,
const
struct
thermal_trip
*
trip
);
void
(
*
update_tz
)(
struct
thermal_zone_device
*
tz
,
enum
thermal_notify_event
reason
);
struct
list_head
governor_list
;
};
/* Structure to define Thermal Zone parameters */
/* Structure to define Thermal Zone parameters */
struct
thermal_zone_params
{
struct
thermal_zone_params
{
const
char
*
governor_name
;
const
char
*
governor_name
;
...
...
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