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
efde8bfd
Commit
efde8bfd
authored
Jun 27, 2024
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back thermal control material for v6.11.
parents
52903814
06d55c42
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
112 additions
and
80 deletions
+112
-80
drivers/thermal/gov_bang_bang.c
drivers/thermal/gov_bang_bang.c
+3
-11
drivers/thermal/thermal_core.c
drivers/thermal/thermal_core.c
+6
-2
drivers/thermal/thermal_core.h
drivers/thermal/thermal_core.h
+3
-1
drivers/thermal/thermal_debugfs.c
drivers/thermal/thermal_debugfs.c
+72
-38
drivers/thermal/thermal_debugfs.h
drivers/thermal/thermal_debugfs.h
+2
-0
drivers/thermal/thermal_sysfs.c
drivers/thermal/thermal_sysfs.c
+4
-15
drivers/thermal/thermal_trip.c
drivers/thermal/thermal_trip.c
+22
-13
No files found.
drivers/thermal/gov_bang_bang.c
View file @
efde8bfd
...
...
@@ -57,24 +57,16 @@ static void bang_bang_control(struct thermal_zone_device *tz,
if
(
instance
->
trip
!=
trip
)
continue
;
if
(
instance
->
target
==
THERMAL_NO_TARGET
)
instance
->
target
=
0
;
if
(
instance
->
target
!=
0
&&
instance
->
target
!=
1
)
{
if
(
instance
->
target
!=
0
&&
instance
->
target
!=
1
&&
instance
->
target
!=
THERMAL_NO_TARGET
)
pr_debug
(
"Unexpected state %ld of thermal instance %s in bang-bang
\n
"
,
instance
->
target
,
instance
->
name
);
instance
->
target
=
1
;
}
/*
* Enable the fan when the trip is crossed on the way up and
* disable it when the trip is crossed on the way down.
*/
if
(
instance
->
target
==
0
&&
crossed_up
)
instance
->
target
=
1
;
else
if
(
instance
->
target
==
1
&&
!
crossed_up
)
instance
->
target
=
0
;
instance
->
target
=
crossed_up
;
dev_dbg
(
&
instance
->
cdev
->
device
,
"target=%ld
\n
"
,
instance
->
target
);
...
...
drivers/thermal/thermal_core.c
View file @
efde8bfd
...
...
@@ -463,6 +463,9 @@ static void thermal_governor_trip_crossed(struct thermal_governor *governor,
const
struct
thermal_trip
*
trip
,
bool
crossed_up
)
{
if
(
trip
->
type
==
THERMAL_TRIP_HOT
||
trip
->
type
==
THERMAL_TRIP_CRITICAL
)
return
;
if
(
governor
->
trip_crossed
)
governor
->
trip_crossed
(
tz
,
trip
,
crossed_up
);
}
...
...
@@ -513,13 +516,13 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
if
(
tz
->
temperature
==
THERMAL_TEMP_INVALID
)
return
;
__thermal_zone_set_trips
(
tz
);
tz
->
notify_event
=
event
;
for_each_trip_desc
(
tz
,
td
)
handle_thermal_trip
(
tz
,
td
,
&
way_up_list
,
&
way_down_list
);
thermal_zone_set_trips
(
tz
);
list_sort
(
&
way_up_list
,
&
way_up_list
,
thermal_trip_notify_cmp
);
list_for_each_entry
(
td
,
&
way_up_list
,
notify_list_node
)
thermal_trip_crossed
(
tz
,
&
td
->
trip
,
governor
,
true
);
...
...
@@ -1649,6 +1652,7 @@ static void thermal_zone_device_resume(struct work_struct *work)
tz
->
suspended
=
false
;
thermal_debug_tz_resume
(
tz
);
thermal_zone_device_init
(
tz
);
__thermal_zone_device_update
(
tz
,
THERMAL_EVENT_UNSPECIFIED
);
...
...
drivers/thermal/thermal_core.h
View file @
efde8bfd
...
...
@@ -244,7 +244,9 @@ void thermal_governor_update_tz(struct thermal_zone_device *tz,
#define trip_to_trip_desc(__trip) \
container_of(__trip, struct thermal_trip_desc, trip)
void
__thermal_zone_set_trips
(
struct
thermal_zone_device
*
tz
);
const
char
*
thermal_trip_type_name
(
enum
thermal_trip_type
trip_type
);
void
thermal_zone_set_trips
(
struct
thermal_zone_device
*
tz
);
int
thermal_zone_trip_id
(
const
struct
thermal_zone_device
*
tz
,
const
struct
thermal_trip
*
trip
);
void
thermal_zone_trip_updated
(
struct
thermal_zone_device
*
tz
,
...
...
drivers/thermal/thermal_debugfs.c
View file @
efde8bfd
...
...
@@ -94,7 +94,6 @@ struct cdev_record {
* @trip_temp: trip temperature at mitigation start
* @trip_hyst: trip hysteresis at mitigation start
* @count: the number of times the zone temperature was above the trip point
* @max: maximum recorded temperature above the trip point
* @min: minimum recorded temperature above the trip point
* @avg: average temperature above the trip point
*/
...
...
@@ -104,7 +103,6 @@ struct trip_stats {
int
trip_temp
;
int
trip_hyst
;
int
count
;
int
max
;
int
min
;
int
avg
;
};
...
...
@@ -122,12 +120,14 @@ struct trip_stats {
* @timestamp: first trip point crossed the way up
* @duration: total duration of the mitigation episode
* @node: a list element to be added to the list of tz events
* @max_temp: maximum zone temperature during this episode
* @trip_stats: per trip point statistics, flexible array
*/
struct
tz_episode
{
ktime_t
timestamp
;
ktime_t
duration
;
struct
list_head
node
;
int
max_temp
;
struct
trip_stats
trip_stats
[];
};
...
...
@@ -561,10 +561,11 @@ static struct tz_episode *thermal_debugfs_tz_event_alloc(struct thermal_zone_dev
INIT_LIST_HEAD
(
&
tze
->
node
);
tze
->
timestamp
=
now
;
tze
->
duration
=
KTIME_MIN
;
tze
->
max_temp
=
INT_MIN
;
for
(
i
=
0
;
i
<
tz
->
num_trips
;
i
++
)
{
tze
->
trip_stats
[
i
].
trip_temp
=
THERMAL_TEMP_INVALID
;
tze
->
trip_stats
[
i
].
min
=
INT_MAX
;
tze
->
trip_stats
[
i
].
max
=
INT_MIN
;
}
return
tze
;
...
...
@@ -573,20 +574,20 @@ static struct tz_episode *thermal_debugfs_tz_event_alloc(struct thermal_zone_dev
void
thermal_debug_tz_trip_up
(
struct
thermal_zone_device
*
tz
,
const
struct
thermal_trip
*
trip
)
{
struct
tz_episode
*
tze
;
struct
tz_debugfs
*
tz_dbg
;
struct
thermal_debugfs
*
thermal_dbg
=
tz
->
debugfs
;
int
trip_id
=
thermal_zone_trip_id
(
tz
,
trip
);
ktime_t
now
=
ktime_get
();
struct
trip_stats
*
trip_stats
;
struct
tz_debugfs
*
tz_dbg
;
struct
tz_episode
*
tze
;
if
(
!
thermal_dbg
)
return
;
mutex_lock
(
&
thermal_dbg
->
lock
);
tz_dbg
=
&
thermal_dbg
->
tz_dbg
;
mutex_lock
(
&
thermal_dbg
->
lock
);
/*
* The mitigation is starting. A mitigation can contain
* several episodes where each of them is related to a
...
...
@@ -653,23 +654,33 @@ void thermal_debug_tz_trip_up(struct thermal_zone_device *tz,
mutex_unlock
(
&
thermal_dbg
->
lock
);
}
static
void
tz_episode_close_trip
(
struct
tz_episode
*
tze
,
int
trip_id
,
ktime_t
now
)
{
struct
trip_stats
*
trip_stats
=
&
tze
->
trip_stats
[
trip_id
];
ktime_t
delta
=
ktime_sub
(
now
,
trip_stats
->
timestamp
);
trip_stats
->
duration
=
ktime_add
(
delta
,
trip_stats
->
duration
);
/* Mark the end of mitigation for this trip point. */
trip_stats
->
timestamp
=
KTIME_MAX
;
}
void
thermal_debug_tz_trip_down
(
struct
thermal_zone_device
*
tz
,
const
struct
thermal_trip
*
trip
)
{
struct
thermal_debugfs
*
thermal_dbg
=
tz
->
debugfs
;
int
trip_id
=
thermal_zone_trip_id
(
tz
,
trip
);
ktime_t
now
=
ktime_get
();
struct
tz_episode
*
tze
;
struct
tz_debugfs
*
tz_dbg
;
ktime_t
delta
,
now
=
ktime_get
();
int
trip_id
=
thermal_zone_trip_id
(
tz
,
trip
);
int
i
;
if
(
!
thermal_dbg
)
return
;
mutex_lock
(
&
thermal_dbg
->
lock
);
tz_dbg
=
&
thermal_dbg
->
tz_dbg
;
mutex_lock
(
&
thermal_dbg
->
lock
);
/*
* The temperature crosses the way down but there was not
* mitigation detected before. That may happen when the
...
...
@@ -695,13 +706,7 @@ void thermal_debug_tz_trip_down(struct thermal_zone_device *tz,
tze
=
list_first_entry
(
&
tz_dbg
->
tz_episodes
,
struct
tz_episode
,
node
);
delta
=
ktime_sub
(
now
,
tze
->
trip_stats
[
trip_id
].
timestamp
);
tze
->
trip_stats
[
trip_id
].
duration
=
ktime_add
(
delta
,
tze
->
trip_stats
[
trip_id
].
duration
);
/* Mark the end of mitigation for this trip point. */
tze
->
trip_stats
[
trip_id
].
timestamp
=
KTIME_MAX
;
tz_episode_close_trip
(
tze
,
trip_id
,
now
);
/*
* This event closes the mitigation as we are crossing the
...
...
@@ -724,20 +729,22 @@ void thermal_debug_update_trip_stats(struct thermal_zone_device *tz)
if
(
!
thermal_dbg
)
return
;
mutex_lock
(
&
thermal_dbg
->
lock
);
tz_dbg
=
&
thermal_dbg
->
tz_dbg
;
mutex_lock
(
&
thermal_dbg
->
lock
);
if
(
!
tz_dbg
->
nr_trips
)
goto
out
;
tze
=
list_first_entry
(
&
tz_dbg
->
tz_episodes
,
struct
tz_episode
,
node
);
if
(
tz
->
temperature
>
tze
->
max_temp
)
tze
->
max_temp
=
tz
->
temperature
;
for
(
i
=
0
;
i
<
tz_dbg
->
nr_trips
;
i
++
)
{
int
trip_id
=
tz_dbg
->
trips_crossed
[
i
];
struct
trip_stats
*
trip_stats
=
&
tze
->
trip_stats
[
trip_id
];
trip_stats
->
max
=
max
(
trip_stats
->
max
,
tz
->
temperature
);
trip_stats
->
min
=
min
(
trip_stats
->
min
,
tz
->
temperature
);
trip_stats
->
avg
+=
(
tz
->
temperature
-
trip_stats
->
avg
)
/
++
trip_stats
->
count
;
...
...
@@ -777,7 +784,6 @@ static int tze_seq_show(struct seq_file *s, void *v)
struct
thermal_zone_device
*
tz
=
thermal_dbg
->
tz_dbg
.
tz
;
struct
thermal_trip_desc
*
td
;
struct
tz_episode
*
tze
;
const
char
*
type
;
u64
duration_ms
;
int
trip_id
;
char
c
;
...
...
@@ -793,10 +799,10 @@ static int tze_seq_show(struct seq_file *s, void *v)
c
=
'='
;
}
seq_printf
(
s
,
",-Mitigation at %llu
us, duration%c%llums
\n
"
,
ktime_to_
us
(
tze
->
timestamp
),
c
,
duration_ms
);
seq_printf
(
s
,
",-Mitigation at %llu
ms, duration%c%llums, max. temp=%dm°C
\n
"
,
ktime_to_
ms
(
tze
->
timestamp
),
c
,
duration_ms
,
tze
->
max_temp
);
seq_printf
(
s
,
"| trip | type | temp(
°mC) | hyst(°mC) | duration | avg(°mC) | min(°mC) | max(°m
C) |
\n
"
);
seq_printf
(
s
,
"| trip | type | temp(
m°C) | hyst(m°C) | duration(ms) | avg(m°C) | min(m°
C) |
\n
"
);
for_each_trip_desc
(
tz
,
td
)
{
const
struct
thermal_trip
*
trip
=
&
td
->
trip
;
...
...
@@ -814,16 +820,9 @@ static int tze_seq_show(struct seq_file *s, void *v)
trip_stats
=
&
tze
->
trip_stats
[
trip_id
];
/* Skip trips without any stats. */
if
(
trip_stats
->
min
>
trip_stats
->
max
)
if
(
trip_stats
->
trip_temp
==
THERMAL_TEMP_INVALID
)
continue
;
if
(
trip
->
type
==
THERMAL_TRIP_PASSIVE
)
type
=
"passive"
;
else
if
(
trip
->
type
==
THERMAL_TRIP_ACTIVE
)
type
=
"active"
;
else
type
=
"hot"
;
if
(
trip_stats
->
timestamp
!=
KTIME_MAX
)
{
/* Mitigation in progress. */
ktime_t
delta
=
ktime_sub
(
ktime_get
(),
...
...
@@ -837,15 +836,14 @@ static int tze_seq_show(struct seq_file *s, void *v)
c
=
' '
;
}
seq_printf
(
s
,
"| %*d | %*s | %*d | %*d | %c%*lld | %*d | %*d |
%*d |
\n
"
,
seq_printf
(
s
,
"| %*d | %*s | %*d | %*d | %c%*lld | %*d | %*d |
\n
"
,
4
,
trip_id
,
8
,
t
ype
,
8
,
t
hermal_trip_type_name
(
trip
->
type
)
,
9
,
trip_stats
->
trip_temp
,
9
,
trip_stats
->
trip_hyst
,
c
,
1
0
,
duration_ms
,
c
,
1
1
,
duration_ms
,
9
,
trip_stats
->
avg
,
9
,
trip_stats
->
min
,
9
,
trip_stats
->
max
);
9
,
trip_stats
->
min
);
}
return
0
;
...
...
@@ -922,3 +920,39 @@ void thermal_debug_tz_remove(struct thermal_zone_device *tz)
thermal_debugfs_remove_id
(
thermal_dbg
);
kfree
(
trips_crossed
);
}
void
thermal_debug_tz_resume
(
struct
thermal_zone_device
*
tz
)
{
struct
thermal_debugfs
*
thermal_dbg
=
tz
->
debugfs
;
ktime_t
now
=
ktime_get
();
struct
tz_debugfs
*
tz_dbg
;
struct
tz_episode
*
tze
;
int
i
;
if
(
!
thermal_dbg
)
return
;
mutex_lock
(
&
thermal_dbg
->
lock
);
tz_dbg
=
&
thermal_dbg
->
tz_dbg
;
if
(
!
tz_dbg
->
nr_trips
)
goto
out
;
/*
* A mitigation episode was in progress before the preceding system
* suspend transition, so close it because the zone handling is starting
* over from scratch.
*/
tze
=
list_first_entry
(
&
tz_dbg
->
tz_episodes
,
struct
tz_episode
,
node
);
for
(
i
=
0
;
i
<
tz_dbg
->
nr_trips
;
i
++
)
tz_episode_close_trip
(
tze
,
tz_dbg
->
trips_crossed
[
i
],
now
);
tze
->
duration
=
ktime_sub
(
now
,
tze
->
timestamp
);
tz_dbg
->
nr_trips
=
0
;
out:
mutex_unlock
(
&
thermal_dbg
->
lock
);
}
drivers/thermal/thermal_debugfs.h
View file @
efde8bfd
...
...
@@ -7,6 +7,7 @@ void thermal_debug_cdev_remove(struct thermal_cooling_device *cdev);
void
thermal_debug_cdev_state_update
(
const
struct
thermal_cooling_device
*
cdev
,
int
state
);
void
thermal_debug_tz_add
(
struct
thermal_zone_device
*
tz
);
void
thermal_debug_tz_remove
(
struct
thermal_zone_device
*
tz
);
void
thermal_debug_tz_resume
(
struct
thermal_zone_device
*
tz
);
void
thermal_debug_tz_trip_up
(
struct
thermal_zone_device
*
tz
,
const
struct
thermal_trip
*
trip
);
void
thermal_debug_tz_trip_down
(
struct
thermal_zone_device
*
tz
,
...
...
@@ -20,6 +21,7 @@ static inline void thermal_debug_cdev_state_update(const struct thermal_cooling_
int
state
)
{}
static
inline
void
thermal_debug_tz_add
(
struct
thermal_zone_device
*
tz
)
{}
static
inline
void
thermal_debug_tz_remove
(
struct
thermal_zone_device
*
tz
)
{}
static
inline
void
thermal_debug_tz_resume
(
struct
thermal_zone_device
*
tz
)
{}
static
inline
void
thermal_debug_tz_trip_up
(
struct
thermal_zone_device
*
tz
,
const
struct
thermal_trip
*
trip
)
{};
static
inline
void
thermal_debug_tz_trip_down
(
struct
thermal_zone_device
*
tz
,
...
...
drivers/thermal/thermal_sysfs.c
View file @
efde8bfd
...
...
@@ -88,18 +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
)
return
-
EINVAL
;
switch
(
tz
->
trips
[
trip_id
].
trip
.
type
)
{
case
THERMAL_TRIP_CRITICAL
:
return
sprintf
(
buf
,
"critical
\n
"
);
case
THERMAL_TRIP_HOT
:
return
sprintf
(
buf
,
"hot
\n
"
);
case
THERMAL_TRIP_PASSIVE
:
return
sprintf
(
buf
,
"passive
\n
"
);
case
THERMAL_TRIP_ACTIVE
:
return
sprintf
(
buf
,
"active
\n
"
);
default:
return
sprintf
(
buf
,
"unknown
\n
"
);
}
return
sprintf
(
buf
,
"%s
\n
"
,
thermal_trip_type_name
(
tz
->
trips
[
trip_id
].
trip
.
type
));
}
static
ssize_t
...
...
@@ -150,7 +139,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_temp"
,
&
trip_id
)
!=
1
)
return
-
EINVAL
;
return
sprintf
(
buf
,
"%d
\n
"
,
tz
->
trips
[
trip_id
].
trip
.
temperature
);
return
sprintf
(
buf
,
"%d
\n
"
,
READ_ONCE
(
tz
->
trips
[
trip_id
].
trip
.
temperature
)
);
}
static
ssize_t
...
...
@@ -174,7 +163,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
trip
=
&
tz
->
trips
[
trip_id
].
trip
;
if
(
hyst
!=
trip
->
hysteresis
)
{
trip
->
hysteresis
=
hyst
;
WRITE_ONCE
(
trip
->
hysteresis
,
hyst
)
;
thermal_zone_trip_updated
(
tz
,
trip
);
}
...
...
@@ -194,7 +183,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_hyst"
,
&
trip_id
)
!=
1
)
return
-
EINVAL
;
return
sprintf
(
buf
,
"%d
\n
"
,
tz
->
trips
[
trip_id
].
trip
.
hysteresis
);
return
sprintf
(
buf
,
"%d
\n
"
,
READ_ONCE
(
tz
->
trips
[
trip_id
].
trip
.
hysteresis
)
);
}
static
ssize_t
...
...
drivers/thermal/thermal_trip.c
View file @
efde8bfd
...
...
@@ -9,6 +9,21 @@
*/
#include "thermal_core.h"
static
const
char
*
trip_type_names
[]
=
{
[
THERMAL_TRIP_ACTIVE
]
=
"active"
,
[
THERMAL_TRIP_PASSIVE
]
=
"passive"
,
[
THERMAL_TRIP_HOT
]
=
"hot"
,
[
THERMAL_TRIP_CRITICAL
]
=
"critical"
,
};
const
char
*
thermal_trip_type_name
(
enum
thermal_trip_type
trip_type
)
{
if
(
trip_type
<
THERMAL_TRIP_ACTIVE
||
trip_type
>
THERMAL_TRIP_CRITICAL
)
return
"unknown"
;
return
trip_type_names
[
trip_type
];
}
int
for_each_thermal_trip
(
struct
thermal_zone_device
*
tz
,
int
(
*
cb
)(
struct
thermal_trip
*
,
void
*
),
void
*
data
)
...
...
@@ -47,7 +62,7 @@ int thermal_zone_get_num_trips(struct thermal_zone_device *tz)
EXPORT_SYMBOL_GPL
(
thermal_zone_get_num_trips
);
/**
*
__
thermal_zone_set_trips - Computes the next trip points for the driver
* thermal_zone_set_trips - Computes the next trip points for the driver
* @tz: a pointer to a thermal zone device structure
*
* The function computes the next temperature boundaries by browsing
...
...
@@ -61,7 +76,7 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_num_trips);
*
* It does not return a value
*/
void
__
thermal_zone_set_trips
(
struct
thermal_zone_device
*
tz
)
void
thermal_zone_set_trips
(
struct
thermal_zone_device
*
tz
)
{
const
struct
thermal_trip_desc
*
td
;
int
low
=
-
INT_MAX
,
high
=
INT_MAX
;
...
...
@@ -73,17 +88,11 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz)
return
;
for_each_trip_desc
(
tz
,
td
)
{
const
struct
thermal_trip
*
trip
=
&
td
->
trip
;
int
trip_low
;
trip_low
=
trip
->
temperature
-
trip
->
hysteresis
;
if
(
trip_low
<
tz
->
temperature
&&
trip_low
>
low
)
low
=
trip_low
;
if
(
td
->
threshold
<
tz
->
temperature
&&
td
->
threshold
>
low
)
low
=
td
->
threshold
;
if
(
trip
->
temperature
>
tz
->
temperature
&&
trip
->
temperature
<
high
)
high
=
trip
->
temperature
;
if
(
td
->
threshold
>
tz
->
temperature
&&
td
->
threshold
<
high
)
high
=
td
->
threshold
;
}
/* No need to change trip points */
...
...
@@ -152,7 +161,7 @@ void thermal_zone_set_trip_temp(struct thermal_zone_device *tz,
if
(
trip
->
temperature
==
temp
)
return
;
trip
->
temperature
=
temp
;
WRITE_ONCE
(
trip
->
temperature
,
temp
)
;
thermal_notify_tz_trip_change
(
tz
,
trip
);
if
(
temp
==
THERMAL_TEMP_INVALID
)
{
...
...
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