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
a5c926ac
Commit
a5c926ac
authored
Jan 27, 2023
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back Intel thermal control changes for 6.3.
parents
acd7e9ee
e90eb1df
Changes
50
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
50 changed files
with
1112 additions
and
1351 deletions
+1112
-1351
Documentation/driver-api/thermal/intel_dptf.rst
Documentation/driver-api/thermal/intel_dptf.rst
+3
-0
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+0
-2
drivers/net/ethernet/chelsio/cxgb4/cxgb4_thermal.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_thermal.c
+7
-32
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+48
-161
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+1
-1
drivers/net/wireless/intel/iwlwifi/mvm/tt.c
drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+12
-59
drivers/platform/x86/acerhdf.c
drivers/platform/x86/acerhdf.c
+26
-47
drivers/thermal/Kconfig
drivers/thermal/Kconfig
+4
-0
drivers/thermal/Makefile
drivers/thermal/Makefile
+1
-0
drivers/thermal/armada_thermal.c
drivers/thermal/armada_thermal.c
+20
-20
drivers/thermal/broadcom/bcm2835_thermal.c
drivers/thermal/broadcom/bcm2835_thermal.c
+5
-3
drivers/thermal/da9062-thermal.c
drivers/thermal/da9062-thermal.c
+8
-44
drivers/thermal/gov_bang_bang.c
drivers/thermal/gov_bang_bang.c
+22
-15
drivers/thermal/gov_fair_share.c
drivers/thermal/gov_fair_share.c
+6
-12
drivers/thermal/gov_power_allocator.c
drivers/thermal/gov_power_allocator.c
+23
-28
drivers/thermal/gov_step_wise.c
drivers/thermal/gov_step_wise.c
+10
-12
drivers/thermal/hisi_thermal.c
drivers/thermal/hisi_thermal.c
+6
-5
drivers/thermal/imx_thermal.c
drivers/thermal/imx_thermal.c
+27
-45
drivers/thermal/intel/Kconfig
drivers/thermal/intel/Kconfig
+8
-0
drivers/thermal/intel/Makefile
drivers/thermal/intel/Makefile
+1
-0
drivers/thermal/intel/int340x_thermal/Kconfig
drivers/thermal/intel/int340x_thermal/Kconfig
+1
-0
drivers/thermal/intel/int340x_thermal/int3400_thermal.c
drivers/thermal/intel/int340x_thermal/int3400_thermal.c
+50
-8
drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
+15
-18
drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
+2
-2
drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
.../thermal/intel/int340x_thermal/processor_thermal_device.c
+24
-105
drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
...rmal/intel/int340x_thermal/processor_thermal_device_pci.c
+22
-31
drivers/thermal/intel/intel_menlow.c
drivers/thermal/intel/intel_menlow.c
+6
-6
drivers/thermal/intel/intel_pch_thermal.c
drivers/thermal/intel/intel_pch_thermal.c
+27
-69
drivers/thermal/intel/intel_soc_dts_iosf.c
drivers/thermal/intel/intel_soc_dts_iosf.c
+6
-29
drivers/thermal/intel/intel_tcc.c
drivers/thermal/intel/intel_tcc.c
+139
-0
drivers/thermal/intel/intel_tcc_cooling.c
drivers/thermal/intel/intel_tcc_cooling.c
+8
-29
drivers/thermal/intel/x86_pkg_temp_thermal.c
drivers/thermal/intel/x86_pkg_temp_thermal.c
+88
-88
drivers/thermal/qcom/qcom-spmi-temp-alarm.c
drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+22
-22
drivers/thermal/rcar_gen3_thermal.c
drivers/thermal/rcar_gen3_thermal.c
+1
-1
drivers/thermal/rcar_thermal.c
drivers/thermal/rcar_thermal.c
+6
-47
drivers/thermal/samsung/exynos_tmu.c
drivers/thermal/samsung/exynos_tmu.c
+28
-34
drivers/thermal/st/st_thermal.c
drivers/thermal/st/st_thermal.c
+7
-40
drivers/thermal/tegra/soctherm.c
drivers/thermal/tegra/soctherm.c
+15
-20
drivers/thermal/tegra/tegra30-tsensor.c
drivers/thermal/tegra/tegra30-tsensor.c
+8
-9
drivers/thermal/thermal_acpi.c
drivers/thermal/thermal_acpi.c
+150
-0
drivers/thermal/thermal_core.c
drivers/thermal/thermal_core.c
+131
-23
drivers/thermal/thermal_core.h
drivers/thermal/thermal_core.h
+2
-22
drivers/thermal/thermal_helpers.c
drivers/thermal/thermal_helpers.c
+14
-14
drivers/thermal/thermal_netlink.c
drivers/thermal/thermal_netlink.c
+8
-11
drivers/thermal/thermal_of.c
drivers/thermal/thermal_of.c
+0
-116
drivers/thermal/thermal_sysfs.c
drivers/thermal/thermal_sysfs.c
+44
-91
drivers/thermal/ti-soc-thermal/ti-thermal.h
drivers/thermal/ti-soc-thermal/ti-thermal.h
+0
-15
drivers/thermal/uniphier_thermal.c
drivers/thermal/uniphier_thermal.c
+12
-15
include/linux/intel_tcc.h
include/linux/intel_tcc.h
+18
-0
include/linux/thermal.h
include/linux/thermal.h
+20
-0
No files found.
Documentation/driver-api/thermal/intel_dptf.rst
View file @
a5c926ac
...
...
@@ -84,6 +84,9 @@ DPTF ACPI Drivers interface
https:/github.com/intel/thermal_daemon for decoding
thermal table.
``production_mode`` (RO)
When different from zero, manufacturer locked thermal configuration
from further changes.
ACPI Thermal Relationship table interface
------------------------------------------
...
...
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
View file @
a5c926ac
...
...
@@ -1079,8 +1079,6 @@ struct mbox_list {
#if IS_ENABLED(CONFIG_THERMAL)
struct
ch_thermal
{
struct
thermal_zone_device
*
tzdev
;
int
trip_temp
;
int
trip_type
;
};
#endif
...
...
drivers/net/ethernet/chelsio/cxgb4/cxgb4_thermal.c
View file @
a5c926ac
...
...
@@ -29,36 +29,12 @@ static int cxgb4_thermal_get_temp(struct thermal_zone_device *tzdev,
return
0
;
}
static
int
cxgb4_thermal_get_trip_type
(
struct
thermal_zone_device
*
tzdev
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
struct
adapter
*
adap
=
tzdev
->
devdata
;
if
(
!
adap
->
ch_thermal
.
trip_temp
)
return
-
EINVAL
;
*
type
=
adap
->
ch_thermal
.
trip_type
;
return
0
;
}
static
int
cxgb4_thermal_get_trip_temp
(
struct
thermal_zone_device
*
tzdev
,
int
trip
,
int
*
temp
)
{
struct
adapter
*
adap
=
tzdev
->
devdata
;
if
(
!
adap
->
ch_thermal
.
trip_temp
)
return
-
EINVAL
;
*
temp
=
adap
->
ch_thermal
.
trip_temp
;
return
0
;
}
static
struct
thermal_zone_device_ops
cxgb4_thermal_ops
=
{
.
get_temp
=
cxgb4_thermal_get_temp
,
.
get_trip_type
=
cxgb4_thermal_get_trip_type
,
.
get_trip_temp
=
cxgb4_thermal_get_trip_temp
,
};
static
struct
thermal_trip
trip
=
{
.
type
=
THERMAL_TRIP_CRITICAL
}
;
int
cxgb4_thermal_init
(
struct
adapter
*
adap
)
{
struct
ch_thermal
*
ch_thermal
=
&
adap
->
ch_thermal
;
...
...
@@ -79,15 +55,14 @@ int cxgb4_thermal_init(struct adapter *adap)
if
(
ret
<
0
)
{
num_trip
=
0
;
/* could not get trip temperature */
}
else
{
ch_thermal
->
trip_temp
=
val
*
1000
;
ch_thermal
->
trip_type
=
THERMAL_TRIP_CRITICAL
;
trip
.
temperature
=
val
*
1000
;
}
snprintf
(
ch_tz_name
,
sizeof
(
ch_tz_name
),
"cxgb4_%s"
,
adap
->
name
);
ch_thermal
->
tzdev
=
thermal_zone_device_register
(
ch_tz_name
,
num_trip
,
0
,
adap
,
&
cxgb4_thermal_ops
,
NULL
,
0
,
0
);
ch_thermal
->
tzdev
=
thermal_zone_device_register
_with_trips
(
ch_tz_name
,
&
trip
,
num_trip
,
0
,
adap
,
&
cxgb4_thermal_ops
,
NULL
,
0
,
0
);
if
(
IS_ERR
(
ch_thermal
->
tzdev
))
{
ret
=
PTR_ERR
(
ch_thermal
->
tzdev
);
dev_err
(
adap
->
pdev_dev
,
"Failed to register thermal zone
\n
"
);
...
...
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
View file @
a5c926ac
This diff is collapsed.
Click to expand it.
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
View file @
a5c926ac
...
...
@@ -501,7 +501,7 @@ struct iwl_mvm_tt_mgmt {
* @tzone: thermal zone device data
*/
struct
iwl_mvm_thermal_device
{
s
16
temp_
trips
[
IWL_MAX_DTS_TRIPS
];
s
truct
thermal_trip
trips
[
IWL_MAX_DTS_TRIPS
];
u8
fw_trips_index
[
IWL_MAX_DTS_TRIPS
];
struct
thermal_zone_device
*
tzone
;
};
...
...
drivers/net/wireless/intel/iwlwifi/mvm/tt.c
View file @
a5c926ac
...
...
@@ -573,11 +573,11 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
* and uncompressed, the FW should get it compressed and sorted
*/
/* compress t
emp_t
rips to cmd array, remove uninitialized values*/
/* compress trips to cmd array, remove uninitialized values*/
for
(
i
=
0
;
i
<
IWL_MAX_DTS_TRIPS
;
i
++
)
{
if
(
mvm
->
tz_device
.
t
emp_trips
[
i
]
!=
S16
_MIN
)
{
if
(
mvm
->
tz_device
.
t
rips
[
i
].
temperature
!=
INT
_MIN
)
{
cmd
.
thresholds
[
idx
++
]
=
cpu_to_le16
(
mvm
->
tz_device
.
temp_trips
[
i
]
);
cpu_to_le16
(
(
s16
)(
mvm
->
tz_device
.
trips
[
i
].
temperature
/
1000
)
);
}
}
cmd
.
num_temps
=
cpu_to_le32
(
idx
);
...
...
@@ -593,8 +593,8 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
*/
for
(
i
=
0
;
i
<
idx
;
i
++
)
{
for
(
j
=
0
;
j
<
IWL_MAX_DTS_TRIPS
;
j
++
)
{
if
(
le16_to_cpu
(
cmd
.
thresholds
[
i
]
)
==
mvm
->
tz_device
.
temp_trips
[
j
]
)
if
(
(
int
)(
le16_to_cpu
(
cmd
.
thresholds
[
i
])
*
1000
)
==
mvm
->
tz_device
.
trips
[
j
].
temperature
)
mvm
->
tz_device
.
fw_trips_index
[
i
]
=
j
;
}
}
...
...
@@ -638,37 +638,12 @@ static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device,
return
ret
;
}
static
int
iwl_mvm_tzone_get_trip_temp
(
struct
thermal_zone_device
*
device
,
int
trip
,
int
*
temp
)
{
struct
iwl_mvm
*
mvm
=
(
struct
iwl_mvm
*
)
device
->
devdata
;
if
(
trip
<
0
||
trip
>=
IWL_MAX_DTS_TRIPS
)
return
-
EINVAL
;
*
temp
=
mvm
->
tz_device
.
temp_trips
[
trip
]
*
1000
;
return
0
;
}
static
int
iwl_mvm_tzone_get_trip_type
(
struct
thermal_zone_device
*
device
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
if
(
trip
<
0
||
trip
>=
IWL_MAX_DTS_TRIPS
)
return
-
EINVAL
;
*
type
=
THERMAL_TRIP_PASSIVE
;
return
0
;
}
static
int
iwl_mvm_tzone_set_trip_temp
(
struct
thermal_zone_device
*
device
,
int
trip
,
int
temp
)
{
struct
iwl_mvm
*
mvm
=
(
struct
iwl_mvm
*
)
device
->
devdata
;
struct
iwl_mvm_thermal_device
*
tzone
;
int
i
,
ret
;
s16
temperature
;
int
ret
;
mutex_lock
(
&
mvm
->
mutex
);
...
...
@@ -678,40 +653,17 @@ static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
goto
out
;
}
if
(
trip
<
0
||
trip
>=
IWL_MAX_DTS_TRIPS
)
{
ret
=
-
EINVAL
;
goto
out
;
}
if
((
temp
/
1000
)
>
S16_MAX
)
{
ret
=
-
EINVAL
;
goto
out
;
}
temperature
=
(
s16
)(
temp
/
1000
);
tzone
=
&
mvm
->
tz_device
;
if
(
!
tzone
)
{
ret
=
-
EIO
;
goto
out
;
}
/* no updates*/
if
(
tzone
->
temp_trips
[
trip
]
==
temperature
)
{
ret
=
0
;
goto
out
;
}
/* already existing temperature */
for
(
i
=
0
;
i
<
IWL_MAX_DTS_TRIPS
;
i
++
)
{
if
(
tzone
->
temp_trips
[
i
]
==
temperature
)
{
ret
=
-
EINVAL
;
goto
out
;
}
}
tzone
->
temp_trips
[
trip
]
=
temperature
;
ret
=
iwl_mvm_send_temp_report_ths_cmd
(
mvm
);
out:
mutex_unlock
(
&
mvm
->
mutex
);
...
...
@@ -720,8 +672,6 @@ static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
static
struct
thermal_zone_device_ops
tzone_ops
=
{
.
get_temp
=
iwl_mvm_tzone_get_temp
,
.
get_trip_temp
=
iwl_mvm_tzone_get_trip_temp
,
.
get_trip_type
=
iwl_mvm_tzone_get_trip_type
,
.
set_trip_temp
=
iwl_mvm_tzone_set_trip_temp
,
};
...
...
@@ -743,7 +693,8 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
BUILD_BUG_ON
(
ARRAY_SIZE
(
name
)
>=
THERMAL_NAME_LENGTH
);
sprintf
(
name
,
"iwlwifi_%u"
,
atomic_inc_return
(
&
counter
)
&
0xFF
);
mvm
->
tz_device
.
tzone
=
thermal_zone_device_register
(
name
,
mvm
->
tz_device
.
tzone
=
thermal_zone_device_register_with_trips
(
name
,
mvm
->
tz_device
.
trips
,
IWL_MAX_DTS_TRIPS
,
IWL_WRITABLE_TRIPS_MSK
,
mvm
,
&
tzone_ops
,
...
...
@@ -766,8 +717,10 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
/* 0 is a valid temperature,
* so initialize the array with S16_MIN which invalid temperature
*/
for
(
i
=
0
;
i
<
IWL_MAX_DTS_TRIPS
;
i
++
)
mvm
->
tz_device
.
temp_trips
[
i
]
=
S16_MIN
;
for
(
i
=
0
;
i
<
IWL_MAX_DTS_TRIPS
;
i
++
)
{
mvm
->
tz_device
.
trips
[
i
].
temperature
=
INT_MIN
;
mvm
->
tz_device
.
trips
[
i
].
type
=
THERMAL_TRIP_PASSIVE
;
}
}
static
int
iwl_mvm_tcool_get_max_state
(
struct
thermal_cooling_device
*
cdev
,
...
...
drivers/platform/x86/acerhdf.c
View file @
a5c926ac
...
...
@@ -46,6 +46,8 @@
* measured by the on-die thermal monitor are within 0 <= Tj <= 90. So,
* assume 89°C is critical temperature.
*/
#define ACERHDF_DEFAULT_TEMP_FANON 60000
#define ACERHDF_DEFAULT_TEMP_FANOFF 53000
#define ACERHDF_TEMP_CRIT 89000
#define ACERHDF_FAN_OFF 0
#define ACERHDF_FAN_AUTO 1
...
...
@@ -70,8 +72,8 @@ static int kernelmode;
#endif
static
unsigned
int
interval
=
10
;
static
unsigned
int
fanon
=
60000
;
static
unsigned
int
fanoff
=
53000
;
static
unsigned
int
fanon
=
ACERHDF_DEFAULT_TEMP_FANON
;
static
unsigned
int
fanoff
=
ACERHDF_DEFAULT_TEMP_FANOFF
;
static
unsigned
int
verbose
;
static
unsigned
int
list_supported
;
static
unsigned
int
fanstate
=
ACERHDF_FAN_AUTO
;
...
...
@@ -137,6 +139,15 @@ struct ctrl_settings {
int
mcmd_enable
;
};
static
struct
thermal_trip
trips
[]
=
{
[
0
]
=
{
.
temperature
=
ACERHDF_DEFAULT_TEMP_FANON
,
.
hysteresis
=
ACERHDF_DEFAULT_TEMP_FANON
-
ACERHDF_DEFAULT_TEMP_FANOFF
,
.
type
=
THERMAL_TRIP_ACTIVE
},
[
1
]
=
{
.
temperature
=
ACERHDF_TEMP_CRIT
,
.
type
=
THERMAL_TRIP_CRITICAL
}
};
static
struct
ctrl_settings
ctrl_cfg
__read_mostly
;
/* Register addresses and values for different BIOS versions */
...
...
@@ -326,6 +337,15 @@ static void acerhdf_check_param(struct thermal_zone_device *thermal)
fanon
=
ACERHDF_MAX_FANON
;
}
if
(
fanon
<
fanoff
)
{
pr_err
(
"fanoff temperature (%d) is above fanon temperature (%d), clamping to %d
\n
"
,
fanoff
,
fanon
,
fanon
);
fanoff
=
fanon
;
};
trips
[
0
].
temperature
=
fanon
;
trips
[
0
].
hysteresis
=
fanon
-
fanoff
;
if
(
kernelmode
&&
prev_interval
!=
interval
)
{
if
(
interval
>
ACERHDF_MAX_INTERVAL
)
{
pr_err
(
"interval too high, set to %d
\n
"
,
...
...
@@ -424,43 +444,6 @@ static int acerhdf_change_mode(struct thermal_zone_device *thermal,
return
0
;
}
static
int
acerhdf_get_trip_type
(
struct
thermal_zone_device
*
thermal
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
if
(
trip
==
0
)
*
type
=
THERMAL_TRIP_ACTIVE
;
else
if
(
trip
==
1
)
*
type
=
THERMAL_TRIP_CRITICAL
;
else
return
-
EINVAL
;
return
0
;
}
static
int
acerhdf_get_trip_hyst
(
struct
thermal_zone_device
*
thermal
,
int
trip
,
int
*
temp
)
{
if
(
trip
!=
0
)
return
-
EINVAL
;
*
temp
=
fanon
-
fanoff
;
return
0
;
}
static
int
acerhdf_get_trip_temp
(
struct
thermal_zone_device
*
thermal
,
int
trip
,
int
*
temp
)
{
if
(
trip
==
0
)
*
temp
=
fanon
;
else
if
(
trip
==
1
)
*
temp
=
ACERHDF_TEMP_CRIT
;
else
return
-
EINVAL
;
return
0
;
}
static
int
acerhdf_get_crit_temp
(
struct
thermal_zone_device
*
thermal
,
int
*
temperature
)
{
...
...
@@ -474,13 +457,9 @@ static struct thermal_zone_device_ops acerhdf_dev_ops = {
.
unbind
=
acerhdf_unbind
,
.
get_temp
=
acerhdf_get_ec_temp
,
.
change_mode
=
acerhdf_change_mode
,
.
get_trip_type
=
acerhdf_get_trip_type
,
.
get_trip_hyst
=
acerhdf_get_trip_hyst
,
.
get_trip_temp
=
acerhdf_get_trip_temp
,
.
get_crit_temp
=
acerhdf_get_crit_temp
,
};
/*
* cooling device callback functions
* get maximal fan cooling state
...
...
@@ -710,10 +689,10 @@ static int __init acerhdf_register_thermal(void)
if
(
IS_ERR
(
cl_dev
))
return
-
EINVAL
;
thz_dev
=
thermal_zone_device_register
(
"acerhdf"
,
2
,
0
,
NULL
,
&
acerhdf_dev_ops
,
&
acerhdf_zone_params
,
0
,
(
kernelmode
)
?
interval
*
1000
:
0
);
thz_dev
=
thermal_zone_device_register
_with_trips
(
"acerhdf"
,
trips
,
ARRAY_SIZE
(
trips
)
,
0
,
NULL
,
&
acerhdf_dev_ops
,
&
acerhdf_zone_params
,
0
,
(
kernelmode
)
?
interval
*
1000
:
0
);
if
(
IS_ERR
(
thz_dev
))
return
-
EINVAL
;
...
...
drivers/thermal/Kconfig
View file @
a5c926ac
...
...
@@ -76,6 +76,10 @@ config THERMAL_OF
Say 'Y' here if you need to build thermal infrastructure
based on device tree.
config THERMAL_ACPI
depends on ACPI
bool
config THERMAL_WRITABLE_TRIPS
bool "Enable writable trip points"
help
...
...
drivers/thermal/Makefile
View file @
a5c926ac
...
...
@@ -13,6 +13,7 @@ thermal_sys-$(CONFIG_THERMAL_NETLINK) += thermal_netlink.o
# interface to/from other layers providing sensors
thermal_sys-$(CONFIG_THERMAL_HWMON)
+=
thermal_hwmon.o
thermal_sys-$(CONFIG_THERMAL_OF)
+=
thermal_of.o
thermal_sys-$(CONFIG_THERMAL_ACPI)
+=
thermal_acpi.o
# governors
thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE)
+=
gov_fair_share.o
...
...
drivers/thermal/armada_thermal.c
View file @
a5c926ac
...
...
@@ -761,8 +761,7 @@ static void armada_set_sane_name(struct platform_device *pdev,
}
/* Save the name locally */
strncpy
(
priv
->
zone_name
,
name
,
THERMAL_NAME_LENGTH
-
1
);
priv
->
zone_name
[
THERMAL_NAME_LENGTH
-
1
]
=
'\0'
;
strscpy
(
priv
->
zone_name
,
name
,
THERMAL_NAME_LENGTH
);
/* Then check there are no '-' or hwmon core will complain */
do
{
...
...
@@ -785,33 +784,34 @@ static int armada_configure_overheat_int(struct armada_thermal_priv *priv,
int
sensor_id
)
{
/* Retrieve the critical trip point to enable the overheat interrupt */
const
struct
thermal_trip
*
trips
=
of_thermal_get_trip_points
(
tz
)
;
struct
thermal_trip
trip
;
int
ret
;
int
i
;
if
(
!
trips
)
return
-
EINVAL
;
for
(
i
=
0
;
i
<
thermal_zone_get_num_trips
(
tz
);
i
++
)
{
for
(
i
=
0
;
i
<
of_thermal_get_ntrips
(
tz
);
i
++
)
if
(
trips
[
i
].
type
==
THERMAL_TRIP_CRITICAL
)
break
;
ret
=
thermal_zone_get_trip
(
tz
,
i
,
&
trip
);
if
(
ret
)
return
ret
;
if
(
i
==
of_thermal_get_ntrips
(
tz
)
)
return
-
EINVAL
;
if
(
trip
.
type
!=
THERMAL_TRIP_CRITICAL
)
continue
;
ret
=
armada_select_channel
(
priv
,
sensor_id
);
if
(
ret
)
return
ret
;
ret
=
armada_select_channel
(
priv
,
sensor_id
);
if
(
ret
)
return
ret
;
armada_set_overheat_thresholds
(
priv
,
trips
[
i
].
temperature
,
trips
[
i
].
hysteresis
);
priv
->
overheat_sensor
=
tz
;
priv
->
interrupt_source
=
sensor_id
;
armada_set_overheat_thresholds
(
priv
,
trip
.
temperature
,
trip
.
hysteresis
);
priv
->
overheat_sensor
=
tz
;
priv
->
interrupt_source
=
sensor_id
;
armada_enable_overheat_interrupt
(
priv
);
armada_enable_overheat_interrupt
(
priv
);
return
0
;
return
0
;
}
return
-
EINVAL
;
}
static
int
armada_thermal_probe
(
struct
platform_device
*
pdev
)
...
...
drivers/thermal/broadcom/bcm2835_thermal.c
View file @
a5c926ac
...
...
@@ -18,6 +18,7 @@
#include <linux/platform_device.h>
#include <linux/thermal.h>
#include "../thermal_core.h"
#include "../thermal_hwmon.h"
#define BCM2835_TS_TSENSCTL 0x00
...
...
@@ -224,7 +225,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
*/
val
=
readl
(
data
->
regs
+
BCM2835_TS_TSENSCTL
);
if
(
!
(
val
&
BCM2835_TS_TSENSCTL_RSTB
))
{
int
trip_temp
,
offset
,
slope
;
struct
thermal_trip
trip
;
int
offset
,
slope
;
slope
=
thermal_zone_get_slope
(
tz
);
offset
=
thermal_zone_get_offset
(
tz
);
...
...
@@ -232,7 +234,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
* For now we deal only with critical, otherwise
* would need to iterate
*/
err
=
t
z
->
ops
->
get_trip_temp
(
tz
,
0
,
&
trip_tem
p
);
err
=
t
hermal_zone_get_trip
(
tz
,
0
,
&
tri
p
);
if
(
err
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Not able to read trip_temp: %d
\n
"
,
...
...
@@ -249,7 +251,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
val
|=
(
0xFE
<<
BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT
);
/* trip_adc value from info */
val
|=
bcm2835_thermal_temp2adc
(
trip
_temp
,
val
|=
bcm2835_thermal_temp2adc
(
trip
.
temperature
,
offset
,
slope
)
<<
BCM2835_TS_TSENSCTL_THOLD_SHIFT
;
...
...
drivers/thermal/da9062-thermal.c
View file @
a5c926ac
...
...
@@ -120,44 +120,6 @@ static irqreturn_t da9062_thermal_irq_handler(int irq, void *data)
return
IRQ_HANDLED
;
}
static
int
da9062_thermal_get_trip_type
(
struct
thermal_zone_device
*
z
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
struct
da9062_thermal
*
thermal
=
z
->
devdata
;
switch
(
trip
)
{
case
0
:
*
type
=
THERMAL_TRIP_HOT
;
break
;
default:
dev_err
(
thermal
->
dev
,
"Driver does not support more than 1 trip-wire
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
int
da9062_thermal_get_trip_temp
(
struct
thermal_zone_device
*
z
,
int
trip
,
int
*
temp
)
{
struct
da9062_thermal
*
thermal
=
z
->
devdata
;
switch
(
trip
)
{
case
0
:
*
temp
=
DA9062_MILLI_CELSIUS
(
125
);
break
;
default:
dev_err
(
thermal
->
dev
,
"Driver does not support more than 1 trip-wire
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
int
da9062_thermal_get_temp
(
struct
thermal_zone_device
*
z
,
int
*
temp
)
{
...
...
@@ -172,8 +134,10 @@ static int da9062_thermal_get_temp(struct thermal_zone_device *z,
static
struct
thermal_zone_device_ops
da9062_thermal_ops
=
{
.
get_temp
=
da9062_thermal_get_temp
,
.
get_trip_type
=
da9062_thermal_get_trip_type
,
.
get_trip_temp
=
da9062_thermal_get_trip_temp
,
};
static
struct
thermal_trip
trips
[]
=
{
{
.
temperature
=
DA9062_MILLI_CELSIUS
(
125
),
.
type
=
THERMAL_TRIP_HOT
},
};
static
const
struct
da9062_thermal_config
da9062_config
=
{
...
...
@@ -228,10 +192,10 @@ static int da9062_thermal_probe(struct platform_device *pdev)
INIT_DELAYED_WORK
(
&
thermal
->
work
,
da9062_thermal_poll_on
);
mutex_init
(
&
thermal
->
lock
);
thermal
->
zone
=
thermal_zone_device_register
(
thermal
->
config
->
name
,
1
,
0
,
thermal
,
&
da9062_thermal_ops
,
NULL
,
pp_tmp
,
0
);
thermal
->
zone
=
thermal_zone_device_register
_with_trips
(
thermal
->
config
->
name
,
trips
,
ARRAY_SIZE
(
trips
)
,
0
,
thermal
,
&
da9062_thermal_ops
,
NULL
,
pp_tmp
,
0
);
if
(
IS_ERR
(
thermal
->
zone
))
{
dev_err
(
&
pdev
->
dev
,
"Cannot register thermal zone device
\n
"
);
ret
=
PTR_ERR
(
thermal
->
zone
);
...
...
drivers/thermal/gov_bang_bang.c
View file @
a5c926ac
...
...
@@ -13,26 +13,28 @@
#include "thermal_core.h"
static
void
thermal_zone_trip_update
(
struct
thermal_zone_device
*
tz
,
int
trip
)
static
int
thermal_zone_trip_update
(
struct
thermal_zone_device
*
tz
,
int
trip_id
)
{
int
trip_temp
,
trip_hyst
;
struct
thermal_trip
trip
;
struct
thermal_instance
*
instance
;
int
ret
;
tz
->
ops
->
get_trip_temp
(
tz
,
trip
,
&
trip_temp
);
ret
=
__thermal_zone_get_trip
(
tz
,
trip_id
,
&
trip
);
if
(
ret
)
{
pr_warn_once
(
"Failed to retrieve trip point %d
\n
"
,
trip_id
);
return
ret
;
}
if
(
!
tz
->
ops
->
get_trip_hyst
)
{
pr_warn_once
(
"Undefined get_trip_hyst for thermal zone %s - "
"running with default hysteresis zero
\n
"
,
tz
->
type
);
trip_hyst
=
0
;
}
else
tz
->
ops
->
get_trip_hyst
(
tz
,
trip
,
&
trip_hyst
);
if
(
!
trip
.
hysteresis
)
dev_info_once
(
&
tz
->
device
,
"Zero hysteresis value for thermal zone %s
\n
"
,
tz
->
type
);
dev_dbg
(
&
tz
->
device
,
"Trip%d[temp=%d]:temp=%d:hyst=%d
\n
"
,
trip
,
trip_temp
,
tz
->
temperature
,
trip
_hyst
);
trip
_id
,
trip
.
temperature
,
tz
->
temperature
,
trip
.
hysteresis
);
list_for_each_entry
(
instance
,
&
tz
->
thermal_instances
,
tz_node
)
{
if
(
instance
->
trip
!=
trip
)
if
(
instance
->
trip
!=
trip
_id
)
continue
;
/* in case fan is in initial state, switch the fan off */
...
...
@@ -50,10 +52,10 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
* enable fan when temperature exceeds trip_temp and disable
* the fan in case it falls below trip_temp minus hysteresis
*/
if
(
instance
->
target
==
0
&&
tz
->
temperature
>=
trip
_temp
)
if
(
instance
->
target
==
0
&&
tz
->
temperature
>=
trip
.
temperature
)
instance
->
target
=
1
;
else
if
(
instance
->
target
==
1
&&
tz
->
temperature
<=
trip_temp
-
trip_hyst
)
tz
->
temperature
<=
trip
.
temperature
-
trip
.
hysteresis
)
instance
->
target
=
0
;
dev_dbg
(
&
instance
->
cdev
->
device
,
"target=%d
\n
"
,
...
...
@@ -63,6 +65,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
instance
->
cdev
->
updated
=
false
;
/* cdev needs update */
mutex_unlock
(
&
instance
->
cdev
->
lock
);
}
return
0
;
}
/**
...
...
@@ -95,10 +99,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
static
int
bang_bang_control
(
struct
thermal_zone_device
*
tz
,
int
trip
)
{
struct
thermal_instance
*
instance
;
int
ret
;
lockdep_assert_held
(
&
tz
->
lock
);
thermal_zone_trip_update
(
tz
,
trip
);
ret
=
thermal_zone_trip_update
(
tz
,
trip
);
if
(
ret
)
return
ret
;
list_for_each_entry
(
instance
,
&
tz
->
thermal_instances
,
tz_node
)
thermal_cdev_update
(
instance
->
cdev
);
...
...
drivers/thermal/gov_fair_share.c
View file @
a5c926ac
...
...
@@ -21,16 +21,12 @@
*/
static
int
get_trip_level
(
struct
thermal_zone_device
*
tz
)
{
int
count
=
0
;
int
trip_temp
;
enum
thermal_trip_type
trip_type
;
if
(
tz
->
num_trips
==
0
||
!
tz
->
ops
->
get_trip_temp
)
return
0
;
struct
thermal_trip
trip
;
int
count
;
for
(
count
=
0
;
count
<
tz
->
num_trips
;
count
++
)
{
tz
->
ops
->
get_trip_temp
(
tz
,
count
,
&
trip_tem
p
);
if
(
tz
->
temperature
<
trip
_temp
)
__thermal_zone_get_trip
(
tz
,
count
,
&
tri
p
);
if
(
tz
->
temperature
<
trip
.
temperature
)
break
;
}
...
...
@@ -38,10 +34,8 @@ static int get_trip_level(struct thermal_zone_device *tz)
* count > 0 only if temperature is greater than first trip
* point, in which case, trip_point = count - 1
*/
if
(
count
>
0
)
{
tz
->
ops
->
get_trip_type
(
tz
,
count
-
1
,
&
trip_type
);
trace_thermal_zone_trip
(
tz
,
count
-
1
,
trip_type
);
}
if
(
count
>
0
)
trace_thermal_zone_trip
(
tz
,
count
-
1
,
trip
.
type
);
return
count
;
}
...
...
drivers/thermal/gov_power_allocator.c
View file @
a5c926ac
...
...
@@ -124,16 +124,15 @@ static void estimate_pid_constants(struct thermal_zone_device *tz,
u32
sustainable_power
,
int
trip_switch_on
,
int
control_temp
)
{
struct
thermal_trip
trip
;
u32
temperature_threshold
=
control_temp
;
int
ret
;
int
switch_on_temp
;
u32
temperature_threshold
;
s32
k_i
;
ret
=
tz
->
ops
->
get_trip_temp
(
tz
,
trip_switch_on
,
&
switch_on_tem
p
);
if
(
ret
)
switch_on_temp
=
0
;
ret
=
__thermal_zone_get_trip
(
tz
,
trip_switch_on
,
&
tri
p
);
if
(
!
ret
)
temperature_threshold
-=
trip
.
temperature
;
temperature_threshold
=
control_temp
-
switch_on_temp
;
/*
* estimate_pid_constants() tries to find appropriate default
* values for thermal zones that don't provide them. If a
...
...
@@ -519,10 +518,10 @@ static void get_governor_trips(struct thermal_zone_device *tz,
last_passive
=
INVALID_TRIP
;
for
(
i
=
0
;
i
<
tz
->
num_trips
;
i
++
)
{
enum
thermal_trip_type
type
;
struct
thermal_trip
trip
;
int
ret
;
ret
=
tz
->
ops
->
get_trip_type
(
tz
,
i
,
&
type
);
ret
=
__thermal_zone_get_trip
(
tz
,
i
,
&
trip
);
if
(
ret
)
{
dev_warn
(
&
tz
->
device
,
"Failed to get trip point %d type: %d
\n
"
,
i
,
...
...
@@ -530,14 +529,14 @@ static void get_governor_trips(struct thermal_zone_device *tz,
continue
;
}
if
(
type
==
THERMAL_TRIP_PASSIVE
)
{
if
(
t
rip
.
t
ype
==
THERMAL_TRIP_PASSIVE
)
{
if
(
!
found_first_passive
)
{
params
->
trip_switch_on
=
i
;
found_first_passive
=
true
;
}
else
{
last_passive
=
i
;
}
}
else
if
(
type
==
THERMAL_TRIP_ACTIVE
)
{
}
else
if
(
t
rip
.
t
ype
==
THERMAL_TRIP_ACTIVE
)
{
last_active
=
i
;
}
else
{
break
;
...
...
@@ -632,7 +631,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
{
int
ret
;
struct
power_allocator_params
*
params
;
int
control_tem
p
;
struct
thermal_trip
tri
p
;
ret
=
check_power_actors
(
tz
);
if
(
ret
)
...
...
@@ -658,13 +657,12 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
get_governor_trips
(
tz
,
params
);
if
(
tz
->
num_trips
>
0
)
{
ret
=
tz
->
ops
->
get_trip_temp
(
tz
,
params
->
trip_max_desired_temperature
,
&
control_temp
);
ret
=
__thermal_zone_get_trip
(
tz
,
params
->
trip_max_desired_temperature
,
&
trip
);
if
(
!
ret
)
estimate_pid_constants
(
tz
,
tz
->
tzp
->
sustainable_power
,
params
->
trip_switch_on
,
control_temp
);
trip
.
temperature
);
}
reset_pid_controller
(
params
);
...
...
@@ -694,11 +692,11 @@ static void power_allocator_unbind(struct thermal_zone_device *tz)
tz
->
governor_data
=
NULL
;
}
static
int
power_allocator_throttle
(
struct
thermal_zone_device
*
tz
,
int
trip
)
static
int
power_allocator_throttle
(
struct
thermal_zone_device
*
tz
,
int
trip
_id
)
{
int
ret
;
int
switch_on_temp
,
control_temp
;
struct
power_allocator_params
*
params
=
tz
->
governor_data
;
struct
thermal_trip
trip
;
int
ret
;
bool
update
;
lockdep_assert_held
(
&
tz
->
lock
);
...
...
@@ -707,13 +705,12 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
* We get called for every trip point but we only need to do
* our calculations once
*/
if
(
trip
!=
params
->
trip_max_desired_temperature
)
if
(
trip
_id
!=
params
->
trip_max_desired_temperature
)
return
0
;
ret
=
tz
->
ops
->
get_trip_temp
(
tz
,
params
->
trip_switch_on
,
&
switch_on_temp
);
if
(
!
ret
&&
(
tz
->
temperature
<
switch_on_temp
))
{
update
=
(
tz
->
last_temperature
>=
switch_on_temp
);
ret
=
__thermal_zone_get_trip
(
tz
,
params
->
trip_switch_on
,
&
trip
);
if
(
!
ret
&&
(
tz
->
temperature
<
trip
.
temperature
))
{
update
=
(
tz
->
last_temperature
>=
trip
.
temperature
);
tz
->
passive
=
0
;
reset_pid_controller
(
params
);
allow_maximum_power
(
tz
,
update
);
...
...
@@ -722,16 +719,14 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
tz
->
passive
=
1
;
ret
=
tz
->
ops
->
get_trip_temp
(
tz
,
params
->
trip_max_desired_temperature
,
&
control_temp
);
ret
=
__thermal_zone_get_trip
(
tz
,
params
->
trip_max_desired_temperature
,
&
trip
);
if
(
ret
)
{
dev_warn
(
&
tz
->
device
,
"Failed to get the maximum desired temperature: %d
\n
"
,
dev_warn
(
&
tz
->
device
,
"Failed to get the maximum desired temperature: %d
\n
"
,
ret
);
return
ret
;
}
return
allocate_power
(
tz
,
control_temp
);
return
allocate_power
(
tz
,
trip
.
temperature
);
}
static
struct
thermal_governor
thermal_gov_power_allocator
=
{
...
...
drivers/thermal/gov_step_wise.c
View file @
a5c926ac
...
...
@@ -95,30 +95,28 @@ static void update_passive_instance(struct thermal_zone_device *tz,
tz
->
passive
+=
value
;
}
static
void
thermal_zone_trip_update
(
struct
thermal_zone_device
*
tz
,
int
trip
)
static
void
thermal_zone_trip_update
(
struct
thermal_zone_device
*
tz
,
int
trip
_id
)
{
int
trip_temp
;
enum
thermal_trip_type
trip_type
;
enum
thermal_trend
trend
;
struct
thermal_instance
*
instance
;
struct
thermal_trip
trip
;
bool
throttle
=
false
;
int
old_target
;
tz
->
ops
->
get_trip_temp
(
tz
,
trip
,
&
trip_temp
);
tz
->
ops
->
get_trip_type
(
tz
,
trip
,
&
trip_type
);
__thermal_zone_get_trip
(
tz
,
trip_id
,
&
trip
);
trend
=
get_tz_trend
(
tz
,
trip
);
trend
=
get_tz_trend
(
tz
,
trip
_id
);
if
(
tz
->
temperature
>=
trip
_temp
)
{
if
(
tz
->
temperature
>=
trip
.
temperature
)
{
throttle
=
true
;
trace_thermal_zone_trip
(
tz
,
trip
,
trip_
type
);
trace_thermal_zone_trip
(
tz
,
trip
_id
,
trip
.
type
);
}
dev_dbg
(
&
tz
->
device
,
"Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d
\n
"
,
trip
,
trip_type
,
trip_temp
,
trend
,
throttle
);
trip
_id
,
trip
.
type
,
trip
.
temperature
,
trend
,
throttle
);
list_for_each_entry
(
instance
,
&
tz
->
thermal_instances
,
tz_node
)
{
if
(
instance
->
trip
!=
trip
)
if
(
instance
->
trip
!=
trip
_id
)
continue
;
old_target
=
instance
->
target
;
...
...
@@ -132,11 +130,11 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
/* Activate a passive thermal instance */
if
(
old_target
==
THERMAL_NO_TARGET
&&
instance
->
target
!=
THERMAL_NO_TARGET
)
update_passive_instance
(
tz
,
trip
_
type
,
1
);
update_passive_instance
(
tz
,
trip
.
type
,
1
);
/* Deactivate a passive thermal instance */
else
if
(
old_target
!=
THERMAL_NO_TARGET
&&
instance
->
target
==
THERMAL_NO_TARGET
)
update_passive_instance
(
tz
,
trip
_
type
,
-
1
);
update_passive_instance
(
tz
,
trip
.
type
,
-
1
);
instance
->
initialized
=
true
;
mutex_lock
(
&
instance
->
cdev
->
lock
);
...
...
drivers/thermal/hisi_thermal.c
View file @
a5c926ac
...
...
@@ -482,7 +482,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
struct
hisi_thermal_sensor
*
sensor
)
{
int
ret
,
i
;
const
struct
thermal_trip
*
trip
;
struct
thermal_trip
trip
;
sensor
->
tzd
=
devm_thermal_of_zone_register
(
&
pdev
->
dev
,
sensor
->
id
,
sensor
,
...
...
@@ -495,11 +495,12 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
return
ret
;
}
trip
=
of_thermal_get_trip_points
(
sensor
->
tzd
);
for
(
i
=
0
;
i
<
thermal_zone_get_num_trips
(
sensor
->
tzd
);
i
++
)
{
for
(
i
=
0
;
i
<
of_thermal_get_ntrips
(
sensor
->
tzd
);
i
++
)
{
if
(
trip
[
i
].
type
==
THERMAL_TRIP_PASSIVE
)
{
sensor
->
thres_temp
=
trip
[
i
].
temperature
;
thermal_zone_get_trip
(
sensor
->
tzd
,
i
,
&
trip
);
if
(
trip
.
type
==
THERMAL_TRIP_PASSIVE
)
{
sensor
->
thres_temp
=
trip
.
temperature
;
break
;
}
}
...
...
drivers/thermal/imx_thermal.c
View file @
a5c926ac
...
...
@@ -76,7 +76,6 @@
enum
imx_thermal_trip
{
IMX_TRIP_PASSIVE
,
IMX_TRIP_CRITICAL
,
IMX_TRIP_NUM
,
};
#define IMX_POLLING_DELAY 2000
/* millisecond */
...
...
@@ -115,6 +114,11 @@ struct thermal_soc_data {
u32
low_alarm_shift
;
};
static
struct
thermal_trip
trips
[]
=
{
[
IMX_TRIP_PASSIVE
]
=
{
.
type
=
THERMAL_TRIP_PASSIVE
},
[
IMX_TRIP_CRITICAL
]
=
{
.
type
=
THERMAL_TRIP_CRITICAL
},
};
static
struct
thermal_soc_data
thermal_imx6q_data
=
{
.
version
=
TEMPMON_IMX6Q
,
...
...
@@ -201,8 +205,6 @@ struct imx_thermal_data {
struct
thermal_cooling_device
*
cdev
;
struct
regmap
*
tempmon
;
u32
c1
,
c2
;
/* See formula in imx_init_calib() */
int
temp_passive
;
int
temp_critical
;
int
temp_max
;
int
alarm_temp
;
int
last_temp
;
...
...
@@ -279,12 +281,12 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
/* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
if
(
data
->
socdata
->
version
==
TEMPMON_IMX6Q
)
{
if
(
data
->
alarm_temp
==
data
->
temp_passiv
e
&&
*
temp
>=
data
->
temp_passiv
e
)
imx_set_alarm_temp
(
data
,
data
->
temp_critical
);
if
(
data
->
alarm_temp
==
data
->
temp_critical
&&
*
temp
<
data
->
temp_passiv
e
)
{
imx_set_alarm_temp
(
data
,
data
->
temp_passiv
e
);
if
(
data
->
alarm_temp
==
trips
[
IMX_TRIP_PASSIVE
].
temperatur
e
&&
*
temp
>=
trips
[
IMX_TRIP_PASSIVE
].
temperatur
e
)
imx_set_alarm_temp
(
data
,
trips
[
IMX_TRIP_CRITICAL
].
temperature
);
if
(
data
->
alarm_temp
==
trips
[
IMX_TRIP_CRITICAL
].
temperature
&&
*
temp
<
trips
[
IMX_TRIP_PASSIVE
].
temperatur
e
)
{
imx_set_alarm_temp
(
data
,
trips
[
IMX_TRIP_PASSIVE
].
temperatur
e
);
dev_dbg
(
&
tz
->
device
,
"thermal alarm off: T < %d
\n
"
,
data
->
alarm_temp
/
1000
);
}
...
...
@@ -330,29 +332,10 @@ static int imx_change_mode(struct thermal_zone_device *tz,
return
0
;
}
static
int
imx_get_trip_type
(
struct
thermal_zone_device
*
tz
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
*
type
=
(
trip
==
IMX_TRIP_PASSIVE
)
?
THERMAL_TRIP_PASSIVE
:
THERMAL_TRIP_CRITICAL
;
return
0
;
}
static
int
imx_get_crit_temp
(
struct
thermal_zone_device
*
tz
,
int
*
temp
)
{
struct
imx_thermal_data
*
data
=
tz
->
devdata
;
*
temp
=
data
->
temp_critical
;
return
0
;
}
static
int
imx_get_trip_temp
(
struct
thermal_zone_device
*
tz
,
int
trip
,
int
*
temp
)
{
struct
imx_thermal_data
*
data
=
tz
->
devdata
;
*
temp
=
trips
[
IMX_TRIP_CRITICAL
].
temperature
;
*
temp
=
(
trip
==
IMX_TRIP_PASSIVE
)
?
data
->
temp_passive
:
data
->
temp_critical
;
return
0
;
}
...
...
@@ -371,10 +354,10 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
return
-
EPERM
;
/* do not allow passive to be set higher than critical */
if
(
temp
<
0
||
temp
>
data
->
temp_critical
)
if
(
temp
<
0
||
temp
>
trips
[
IMX_TRIP_CRITICAL
].
temperature
)
return
-
EINVAL
;
data
->
temp_passiv
e
=
temp
;
trips
[
IMX_TRIP_PASSIVE
].
temperatur
e
=
temp
;
imx_set_alarm_temp
(
data
,
temp
);
...
...
@@ -423,8 +406,6 @@ static struct thermal_zone_device_ops imx_tz_ops = {
.
unbind
=
imx_unbind
,
.
get_temp
=
imx_get_temp
,
.
change_mode
=
imx_change_mode
,
.
get_trip_type
=
imx_get_trip_type
,
.
get_trip_temp
=
imx_get_trip_temp
,
.
get_crit_temp
=
imx_get_crit_temp
,
.
set_trip_temp
=
imx_set_trip_temp
,
};
...
...
@@ -507,8 +488,8 @@ static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0)
* Set the critical trip point at 5 °C under max
* Set the passive trip point at 10 °C under max (changeable via sysfs)
*/
data
->
temp_critical
=
data
->
temp_max
-
(
1000
*
5
);
data
->
temp_passive
=
data
->
temp_max
-
(
1000
*
10
);
trips
[
IMX_TRIP_PASSIVE
].
temperature
=
data
->
temp_max
-
(
1000
*
10
);
trips
[
IMX_TRIP_CRITICAL
].
temperature
=
data
->
temp_max
-
(
1000
*
5
);
}
static
int
imx_init_from_tempmon_data
(
struct
platform_device
*
pdev
)
...
...
@@ -743,12 +724,13 @@ static int imx_thermal_probe(struct platform_device *pdev)
goto
legacy_cleanup
;
}
data
->
tz
=
thermal_zone_device_register
(
"imx_thermal_zone"
,
IMX_TRIP_NUM
,
BIT
(
IMX_TRIP_PASSIVE
),
data
,
&
imx_tz_ops
,
NULL
,
IMX_PASSIVE_DELAY
,
IMX_POLLING_DELAY
);
data
->
tz
=
thermal_zone_device_register_with_trips
(
"imx_thermal_zone"
,
trips
,
ARRAY_SIZE
(
trips
),
BIT
(
IMX_TRIP_PASSIVE
),
data
,
&
imx_tz_ops
,
NULL
,
IMX_PASSIVE_DELAY
,
IMX_POLLING_DELAY
);
if
(
IS_ERR
(
data
->
tz
))
{
ret
=
PTR_ERR
(
data
->
tz
);
dev_err
(
&
pdev
->
dev
,
...
...
@@ -758,8 +740,8 @@ static int imx_thermal_probe(struct platform_device *pdev)
dev_info
(
&
pdev
->
dev
,
"%s CPU temperature grade - max:%dC"
" critical:%dC passive:%dC
\n
"
,
data
->
temp_grade
,
data
->
temp_max
/
1000
,
data
->
temp_critical
/
1000
,
data
->
temp_passiv
e
/
1000
);
data
->
temp_max
/
1000
,
trips
[
IMX_TRIP_CRITICAL
].
temperature
/
1000
,
trips
[
IMX_TRIP_PASSIVE
].
temperatur
e
/
1000
);
/* Enable measurements at ~ 10 Hz */
regmap_write
(
map
,
data
->
socdata
->
measure_freq_ctrl
+
REG_CLR
,
...
...
@@ -767,10 +749,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
measure_freq
=
DIV_ROUND_UP
(
32768
,
10
);
/* 10 Hz */
regmap_write
(
map
,
data
->
socdata
->
measure_freq_ctrl
+
REG_SET
,
measure_freq
<<
data
->
socdata
->
measure_freq_shift
);
imx_set_alarm_temp
(
data
,
data
->
temp_passiv
e
);
imx_set_alarm_temp
(
data
,
trips
[
IMX_TRIP_PASSIVE
].
temperatur
e
);
if
(
data
->
socdata
->
version
==
TEMPMON_IMX6SX
)
imx_set_panic_temp
(
data
,
data
->
temp_critical
);
imx_set_panic_temp
(
data
,
trips
[
IMX_TRIP_CRITICAL
].
temperature
);
regmap_write
(
map
,
data
->
socdata
->
sensor_ctrl
+
REG_CLR
,
data
->
socdata
->
power_down_mask
);
...
...
drivers/thermal/intel/Kconfig
View file @
a5c926ac
...
...
@@ -12,11 +12,16 @@ config X86_THERMAL_VECTOR
def_bool y
depends on X86 && CPU_SUP_INTEL && X86_LOCAL_APIC
config INTEL_TCC
bool
depends on X86
config X86_PKG_TEMP_THERMAL
tristate "X86 package temperature thermal driver"
depends on X86_THERMAL_VECTOR
select THERMAL_GOV_USER_SPACE
select THERMAL_WRITABLE_TRIPS
select INTEL_TCC
default m
help
Enable this to register CPU digital sensor for package temperature as
...
...
@@ -28,6 +33,7 @@ config INTEL_SOC_DTS_IOSF_CORE
tristate
depends on X86 && PCI
select IOSF_MBI
select INTEL_TCC
help
This is becoming a common feature for Intel SoCs to expose the additional
digital temperature sensors (DTSs) using side band interface (IOSF). This
...
...
@@ -75,6 +81,7 @@ config INTEL_BXT_PMIC_THERMAL
config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
select THERMAL_ACPI if ACPI
help
Enable this to support thermal reporting on certain intel PCHs.
Thermal reporting device will provide temperature reading,
...
...
@@ -83,6 +90,7 @@ config INTEL_PCH_THERMAL
config INTEL_TCC_COOLING
tristate "Intel TCC offset cooling Driver"
depends on X86
select INTEL_TCC
help
Enable this to support system cooling by adjusting the effective TCC
activation temperature via the TCC Offset register, which is widely
...
...
drivers/thermal/intel/Makefile
View file @
a5c926ac
...
...
@@ -2,6 +2,7 @@
#
# Makefile for various Intel thermal drivers.
obj-$(CONFIG_INTEL_TCC)
+=
intel_tcc.o
obj-$(CONFIG_INTEL_POWERCLAMP)
+=
intel_powerclamp.o
obj-$(CONFIG_X86_PKG_TEMP_THERMAL)
+=
x86_pkg_temp_thermal.o
obj-$(CONFIG_INTEL_SOC_DTS_IOSF_CORE)
+=
intel_soc_dts_iosf.o
...
...
drivers/thermal/intel/int340x_thermal/Kconfig
View file @
a5c926ac
...
...
@@ -10,6 +10,7 @@ config INT340X_THERMAL
select ACPI_THERMAL_REL
select ACPI_FAN
select INTEL_SOC_DTS_IOSF_CORE
select INTEL_TCC
select PROC_THERMAL_MMIO_RAPL if POWERCAP
help
Newer laptops and tablets that use ACPI may have thermal sensors and
...
...
drivers/thermal/intel/int340x_thermal/int3400_thermal.c
View file @
a5c926ac
...
...
@@ -60,6 +60,7 @@ struct int3400_thermal_priv {
int
odvp_count
;
int
*
odvp
;
u32
os_uuid_mask
;
int
production_mode
;
struct
odvp_attr
*
odvp_attrs
;
};
...
...
@@ -130,10 +131,7 @@ static ssize_t available_uuids_show(struct device *dev,
for
(
i
=
0
;
i
<
INT3400_THERMAL_MAXIMUM_UUID
;
i
++
)
{
if
(
priv
->
uuid_bitmap
&
(
1
<<
i
))
length
+=
scnprintf
(
&
buf
[
length
],
PAGE_SIZE
-
length
,
"%s
\n
"
,
int3400_thermal_uuids
[
i
]);
length
+=
sysfs_emit_at
(
buf
,
length
,
int3400_thermal_uuids
[
i
]);
}
return
length
;
...
...
@@ -151,10 +149,7 @@ static ssize_t current_uuid_show(struct device *dev,
for
(
i
=
0
;
i
<=
INT3400_THERMAL_CRITICAL
;
i
++
)
{
if
(
priv
->
os_uuid_mask
&
BIT
(
i
))
length
+=
scnprintf
(
&
buf
[
length
],
PAGE_SIZE
-
length
,
"%s
\n
"
,
int3400_thermal_uuids
[
i
]);
length
+=
sysfs_emit_at
(
buf
,
length
,
int3400_thermal_uuids
[
i
]);
}
if
(
length
)
...
...
@@ -315,6 +310,44 @@ static int int3400_thermal_get_uuids(struct int3400_thermal_priv *priv)
return
result
;
}
static
ssize_t
production_mode_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
int3400_thermal_priv
*
priv
=
dev_get_drvdata
(
dev
);
return
sysfs_emit
(
buf
,
"%d
\n
"
,
priv
->
production_mode
);
}
static
DEVICE_ATTR_RO
(
production_mode
);
static
int
production_mode_init
(
struct
int3400_thermal_priv
*
priv
)
{
unsigned
long
long
mode
;
acpi_status
status
;
int
ret
;
priv
->
production_mode
=
-
1
;
status
=
acpi_evaluate_integer
(
priv
->
adev
->
handle
,
"DCFG"
,
NULL
,
&
mode
);
/* If the method is not present, this is not an error */
if
(
ACPI_FAILURE
(
status
))
return
0
;
ret
=
sysfs_create_file
(
&
priv
->
pdev
->
dev
.
kobj
,
&
dev_attr_production_mode
.
attr
);
if
(
ret
)
return
ret
;
priv
->
production_mode
=
mode
;
return
0
;
}
static
void
production_mode_exit
(
struct
int3400_thermal_priv
*
priv
)
{
if
(
priv
->
production_mode
>=
0
)
sysfs_remove_file
(
&
priv
->
pdev
->
dev
.
kobj
,
&
dev_attr_production_mode
.
attr
);
}
static
ssize_t
odvp_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
...
...
@@ -610,8 +643,15 @@ static int int3400_thermal_probe(struct platform_device *pdev)
if
(
result
)
goto
free_sysfs
;
result
=
production_mode_init
(
priv
);
if
(
result
)
goto
free_notify
;
return
0
;
free_notify:
acpi_remove_notify_handler
(
priv
->
adev
->
handle
,
ACPI_DEVICE_NOTIFY
,
int3400_notify
);
free_sysfs:
cleanup_odvp
(
priv
);
if
(
!
ZERO_OR_NULL_PTR
(
priv
->
data_vault
))
{
...
...
@@ -638,6 +678,8 @@ static int int3400_thermal_remove(struct platform_device *pdev)
{
struct
int3400_thermal_priv
*
priv
=
platform_get_drvdata
(
pdev
);
production_mode_exit
(
priv
);
acpi_remove_notify_handler
(
priv
->
adev
->
handle
,
ACPI_DEVICE_NOTIFY
,
int3400_notify
);
...
...
drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
View file @
a5c926ac
...
...
@@ -18,9 +18,6 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone,
unsigned
long
long
tmp
;
acpi_status
status
;
if
(
d
->
override_ops
&&
d
->
override_ops
->
get_temp
)
return
d
->
override_ops
->
get_temp
(
zone
,
temp
);
status
=
acpi_evaluate_integer
(
d
->
adev
->
handle
,
"_TMP"
,
NULL
,
&
tmp
);
if
(
ACPI_FAILURE
(
status
))
return
-
EIO
;
...
...
@@ -46,9 +43,6 @@ static int int340x_thermal_get_trip_temp(struct thermal_zone_device *zone,
struct
int34x_thermal_zone
*
d
=
zone
->
devdata
;
int
i
,
ret
=
0
;
if
(
d
->
override_ops
&&
d
->
override_ops
->
get_trip_temp
)
return
d
->
override_ops
->
get_trip_temp
(
zone
,
trip
,
temp
);
mutex_lock
(
&
d
->
trip_mutex
);
if
(
trip
<
d
->
aux_trip_nr
)
...
...
@@ -83,9 +77,6 @@ static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone,
struct
int34x_thermal_zone
*
d
=
zone
->
devdata
;
int
i
,
ret
=
0
;
if
(
d
->
override_ops
&&
d
->
override_ops
->
get_trip_type
)
return
d
->
override_ops
->
get_trip_type
(
zone
,
trip
,
type
);
mutex_lock
(
&
d
->
trip_mutex
);
if
(
trip
<
d
->
aux_trip_nr
)
...
...
@@ -120,9 +111,6 @@ static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone,
acpi_status
status
;
char
name
[
10
];
if
(
d
->
override_ops
&&
d
->
override_ops
->
set_trip_temp
)
return
d
->
override_ops
->
set_trip_temp
(
zone
,
trip
,
temp
);
snprintf
(
name
,
sizeof
(
name
),
"PAT%d"
,
trip
);
status
=
acpi_execute_simple_method
(
d
->
adev
->
handle
,
name
,
millicelsius_to_deci_kelvin
(
temp
));
...
...
@@ -142,9 +130,6 @@ static int int340x_thermal_get_trip_hyst(struct thermal_zone_device *zone,
acpi_status
status
;
unsigned
long
long
hyst
;
if
(
d
->
override_ops
&&
d
->
override_ops
->
get_trip_hyst
)
return
d
->
override_ops
->
get_trip_hyst
(
zone
,
trip
,
temp
);
status
=
acpi_evaluate_integer
(
d
->
adev
->
handle
,
"GTSH"
,
NULL
,
&
hyst
);
if
(
ACPI_FAILURE
(
status
))
*
temp
=
0
;
...
...
@@ -229,7 +214,7 @@ static struct thermal_zone_params int340x_thermal_params = {
};
struct
int34x_thermal_zone
*
int340x_thermal_zone_add
(
struct
acpi_device
*
adev
,
struct
thermal_zone_device_ops
*
override_ops
)
int
(
*
get_temp
)
(
struct
thermal_zone_device
*
,
int
*
)
)
{
struct
int34x_thermal_zone
*
int34x_thermal_zone
;
acpi_status
status
;
...
...
@@ -245,7 +230,16 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
mutex_init
(
&
int34x_thermal_zone
->
trip_mutex
);
int34x_thermal_zone
->
adev
=
adev
;
int34x_thermal_zone
->
override_ops
=
override_ops
;
int34x_thermal_zone
->
ops
=
kmemdup
(
&
int340x_thermal_zone_ops
,
sizeof
(
int340x_thermal_zone_ops
),
GFP_KERNEL
);
if
(
!
int34x_thermal_zone
->
ops
)
{
ret
=
-
ENOMEM
;
goto
err_ops_alloc
;
}
if
(
get_temp
)
int34x_thermal_zone
->
ops
->
get_temp
=
get_temp
;
status
=
acpi_evaluate_integer
(
adev
->
handle
,
"PATC"
,
NULL
,
&
trip_cnt
);
if
(
ACPI_FAILURE
(
status
))
...
...
@@ -276,7 +270,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
acpi_device_bid
(
adev
),
trip_cnt
,
trip_mask
,
int34x_thermal_zone
,
&
int340x_thermal_zone_
ops
,
int34x_thermal_zone
->
ops
,
&
int340x_thermal_params
,
0
,
0
);
if
(
IS_ERR
(
int34x_thermal_zone
->
zone
))
{
...
...
@@ -295,6 +289,8 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
acpi_lpat_free_conversion_table
(
int34x_thermal_zone
->
lpat_table
);
kfree
(
int34x_thermal_zone
->
aux_trips
);
err_trip_alloc:
kfree
(
int34x_thermal_zone
->
ops
);
err_ops_alloc:
mutex_destroy
(
&
int34x_thermal_zone
->
trip_mutex
);
kfree
(
int34x_thermal_zone
);
return
ERR_PTR
(
ret
);
...
...
@@ -307,6 +303,7 @@ void int340x_thermal_zone_remove(struct int34x_thermal_zone
thermal_zone_device_unregister
(
int34x_thermal_zone
->
zone
);
acpi_lpat_free_conversion_table
(
int34x_thermal_zone
->
lpat_table
);
kfree
(
int34x_thermal_zone
->
aux_trips
);
kfree
(
int34x_thermal_zone
->
ops
);
mutex_destroy
(
&
int34x_thermal_zone
->
trip_mutex
);
kfree
(
int34x_thermal_zone
);
}
...
...
drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
View file @
a5c926ac
...
...
@@ -29,14 +29,14 @@ struct int34x_thermal_zone {
int
hot_temp
;
int
hot_trip_id
;
struct
thermal_zone_device
*
zone
;
struct
thermal_zone_device_ops
*
o
verride_o
ps
;
struct
thermal_zone_device_ops
*
ops
;
void
*
priv_data
;
struct
acpi_lpat_conversion_table
*
lpat_table
;
struct
mutex
trip_mutex
;
};
struct
int34x_thermal_zone
*
int340x_thermal_zone_add
(
struct
acpi_device
*
,
struct
thermal_zone_device_ops
*
override_ops
);
int
(
*
get_temp
)
(
struct
thermal_zone_device
*
,
int
*
)
);
void
int340x_thermal_zone_remove
(
struct
int34x_thermal_zone
*
);
int
int340x_thermal_read_trips
(
struct
int34x_thermal_zone
*
int34x_zone
);
...
...
drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
View file @
a5c926ac
...
...
@@ -4,6 +4,7 @@
* Copyright (c) 2014, Intel Corporation.
*/
#include <linux/acpi.h>
#include <linux/intel_tcc.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
...
...
@@ -68,54 +69,17 @@ static const struct attribute_group power_limit_attribute_group = {
.
name
=
"power_limits"
};
static
int
tcc_get_offset
(
void
)
{
u64
val
;
int
err
;
err
=
rdmsrl_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
&
val
);
if
(
err
)
return
err
;
return
(
val
>>
24
)
&
0x3f
;
}
static
ssize_t
tcc_offset_degree_celsius_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
int
tcc
;
tcc
=
tcc_get_offset
();
if
(
tcc
<
0
)
return
tcc
;
return
sprintf
(
buf
,
"%d
\n
"
,
tcc
);
}
static
int
tcc_offset_update
(
unsigned
int
tcc
)
{
u64
val
;
int
err
;
int
offset
;
if
(
tcc
>
63
)
return
-
EINVAL
;
err
=
rdmsrl_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
&
val
);
if
(
err
)
return
err
;
offset
=
intel_tcc_get_offset
(
-
1
);
if
(
offset
<
0
)
return
offset
;
if
(
val
&
BIT
(
31
))
return
-
EPERM
;
val
&=
~
GENMASK_ULL
(
29
,
24
);
val
|=
(
tcc
&
0x3f
)
<<
24
;
err
=
wrmsrl_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
val
);
if
(
err
)
return
err
;
return
0
;
return
sprintf
(
buf
,
"%d
\n
"
,
offset
);
}
static
ssize_t
tcc_offset_degree_celsius_store
(
struct
device
*
dev
,
...
...
@@ -136,7 +100,7 @@ static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
if
(
kstrtouint
(
buf
,
0
,
&
tcc
))
return
-
EINVAL
;
err
=
tcc_offset_update
(
tcc
);
err
=
intel_tcc_set_offset
(
-
1
,
tcc
);
if
(
err
)
return
err
;
...
...
@@ -145,72 +109,27 @@ static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
static
DEVICE_ATTR_RW
(
tcc_offset_degree_celsius
);
static
int
stored_tjmax
;
/* since it is fixed, we can have local storage */
static
int
get_tjmax
(
void
)
{
u32
eax
,
edx
;
u32
val
;
int
err
;
err
=
rdmsr_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
&
eax
,
&
edx
);
if
(
err
)
return
err
;
val
=
(
eax
>>
16
)
&
0xff
;
if
(
val
)
return
val
;
return
-
EINVAL
;
}
static
int
read_temp_msr
(
int
*
temp
)
static
int
proc_thermal_get_zone_temp
(
struct
thermal_zone_device
*
zone
,
int
*
temp
)
{
int
cpu
;
u32
eax
,
edx
;
int
err
;
unsigned
long
curr_temp_off
=
0
;
int
curr_temp
;
*
temp
=
0
;
for_each_online_cpu
(
cpu
)
{
err
=
rdmsr_safe_on_cpu
(
cpu
,
MSR_IA32_THERM_STATUS
,
&
eax
,
&
edx
);
if
(
err
)
goto
err_ret
;
else
{
if
(
eax
&
0x80000000
)
{
curr_temp_off
=
(
eax
>>
16
)
&
0x7f
;
if
(
!*
temp
||
curr_temp_off
<
*
temp
)
*
temp
=
curr_temp_off
;
}
else
{
err
=
-
EINVAL
;
goto
err_ret
;
}
}
curr_temp
=
intel_tcc_get_temp
(
cpu
,
false
);
if
(
curr_temp
<
0
)
return
curr_temp
;
if
(
!*
temp
||
curr_temp
>
*
temp
)
*
temp
=
curr_temp
;
}
return
0
;
err_ret:
return
err
;
}
*
temp
*=
1000
;
static
int
proc_thermal_get_zone_temp
(
struct
thermal_zone_device
*
zone
,
int
*
temp
)
{
int
ret
;
ret
=
read_temp_msr
(
temp
);
if
(
!
ret
)
*
temp
=
(
stored_tjmax
-
*
temp
)
*
1000
;
return
ret
;
return
0
;
}
static
struct
thermal_zone_device_ops
proc_thermal_local_ops
=
{
.
get_temp
=
proc_thermal_get_zone_temp
,
};
static
int
proc_thermal_read_ppcc
(
struct
proc_thermal_device
*
proc_priv
)
{
int
i
;
...
...
@@ -285,7 +204,7 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv)
struct
acpi_device
*
adev
;
acpi_status
status
;
unsigned
long
long
tmp
;
struct
thermal_zone_device_ops
*
ops
=
NULL
;
int
(
*
get_temp
)
(
struct
thermal_zone_device
*
,
int
*
)
=
NULL
;
int
ret
;
adev
=
ACPI_COMPANION
(
dev
);
...
...
@@ -302,12 +221,11 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv)
status
=
acpi_evaluate_integer
(
adev
->
handle
,
"_TMP"
,
NULL
,
&
tmp
);
if
(
ACPI_FAILURE
(
status
))
{
/* there is no _TMP method, add local method */
stored_tjmax
=
get_tjmax
();
if
(
stored_tjmax
>
0
)
ops
=
&
proc_thermal_local_ops
;
if
(
intel_tcc_get_tjmax
(
-
1
)
>
0
)
get_temp
=
proc_thermal_get_zone_temp
;
}
proc_priv
->
int340x_zone
=
int340x_thermal_zone_add
(
adev
,
ops
);
proc_priv
->
int340x_zone
=
int340x_thermal_zone_add
(
adev
,
get_temp
);
if
(
IS_ERR
(
proc_priv
->
int340x_zone
))
{
return
PTR_ERR
(
proc_priv
->
int340x_zone
);
}
else
...
...
@@ -356,7 +274,7 @@ static int tcc_offset_save = -1;
int
proc_thermal_suspend
(
struct
device
*
dev
)
{
tcc_offset_save
=
tcc_get_offset
(
);
tcc_offset_save
=
intel_tcc_get_offset
(
-
1
);
if
(
tcc_offset_save
<
0
)
dev_warn
(
dev
,
"failed to save offset (%d)
\n
"
,
tcc_offset_save
);
...
...
@@ -373,7 +291,7 @@ int proc_thermal_resume(struct device *dev)
/* Do not update if saving failed */
if
(
tcc_offset_save
>=
0
)
tcc_offset_update
(
tcc_offset_save
);
intel_tcc_set_offset
(
-
1
,
tcc_offset_save
);
return
0
;
}
...
...
@@ -460,6 +378,7 @@ void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *
}
EXPORT_SYMBOL_GPL
(
proc_thermal_mmio_remove
);
MODULE_IMPORT_NS
(
INTEL_TCC
);
MODULE_AUTHOR
(
"Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"
);
MODULE_DESCRIPTION
(
"Processor Thermal Reporting Device Driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
View file @
a5c926ac
...
...
@@ -144,34 +144,6 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
return
0
;
}
static
int
sys_get_trip_temp
(
struct
thermal_zone_device
*
tzd
,
int
trip
,
int
*
temp
)
{
struct
proc_thermal_pci
*
pci_info
=
tzd
->
devdata
;
u32
_temp
;
proc_thermal_mmio_read
(
pci_info
,
PROC_THERMAL_MMIO_THRES_0
,
&
_temp
);
if
(
!
_temp
)
{
*
temp
=
THERMAL_TEMP_INVALID
;
}
else
{
int
tjmax
;
proc_thermal_mmio_read
(
pci_info
,
PROC_THERMAL_MMIO_TJMAX
,
&
tjmax
);
_temp
=
tjmax
-
_temp
;
*
temp
=
(
unsigned
long
)
_temp
*
1000
;
}
return
0
;
}
static
int
sys_get_trip_type
(
struct
thermal_zone_device
*
tzd
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
*
type
=
THERMAL_TRIP_PASSIVE
;
return
0
;
}
static
int
sys_set_trip_temp
(
struct
thermal_zone_device
*
tzd
,
int
trip
,
int
temp
)
{
struct
proc_thermal_pci
*
pci_info
=
tzd
->
devdata
;
...
...
@@ -200,10 +172,26 @@ static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp
return
0
;
}
static
int
get_trip_temp
(
struct
proc_thermal_pci
*
pci_info
)
{
int
temp
,
tjmax
;
proc_thermal_mmio_read
(
pci_info
,
PROC_THERMAL_MMIO_THRES_0
,
&
temp
);
if
(
!
temp
)
return
THERMAL_TEMP_INVALID
;
proc_thermal_mmio_read
(
pci_info
,
PROC_THERMAL_MMIO_TJMAX
,
&
tjmax
);
temp
=
(
tjmax
-
temp
)
*
1000
;
return
temp
;
}
static
struct
thermal_trip
psv_trip
=
{
.
type
=
THERMAL_TRIP_PASSIVE
,
};
static
struct
thermal_zone_device_ops
tzone_ops
=
{
.
get_temp
=
sys_get_curr_temp
,
.
get_trip_temp
=
sys_get_trip_temp
,
.
get_trip_type
=
sys_get_trip_type
,
.
set_trip_temp
=
sys_set_trip_temp
,
};
...
...
@@ -251,7 +239,10 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
if
(
ret
)
goto
err_ret_thermal
;
pci_info
->
tzone
=
thermal_zone_device_register
(
"TCPU_PCI"
,
1
,
1
,
pci_info
,
psv_trip
.
temperature
=
get_trip_temp
(
pci_info
);
pci_info
->
tzone
=
thermal_zone_device_register_with_trips
(
"TCPU_PCI"
,
&
psv_trip
,
1
,
1
,
pci_info
,
&
tzone_ops
,
&
tzone_params
,
0
,
0
);
if
(
IS_ERR
(
pci_info
->
tzone
))
{
...
...
drivers/thermal/intel/intel_menlow.c
View file @
a5c926ac
...
...
@@ -232,9 +232,9 @@ static DEFINE_MUTEX(intel_menlow_attr_lock);
/*
* sensor_get_auxtrip - get the current auxtrip value from sensor
* @
name: Thermalzone nam
e
* @
auxtype : AUX0/AUX1
* @
buf: syfs buffer
* @
handle: Object handl
e
* @
index : GET_AUX1/GET_AUX0
* @
value : The address will be fill by the value
*/
static
int
sensor_get_auxtrip
(
acpi_handle
handle
,
int
index
,
unsigned
long
long
*
value
)
...
...
@@ -254,9 +254,9 @@ static int sensor_get_auxtrip(acpi_handle handle, int index,
/*
* sensor_set_auxtrip - set the new auxtrip value to sensor
* @
name: Thermalzone nam
e
* @
auxtype : AUX0/AUX1
* @
buf: syfs buffer
* @
handle: Object handl
e
* @
index : GET_AUX1/GET_AUX0
* @
value : The value will be set
*/
static
int
sensor_set_auxtrip
(
acpi_handle
handle
,
int
index
,
int
value
)
{
...
...
drivers/thermal/intel/intel_pch_thermal.c
View file @
a5c926ac
...
...
@@ -29,6 +29,7 @@
#define PCH_THERMAL_DID_CNL_LP 0x02F9
/* CNL-LP PCH */
#define PCH_THERMAL_DID_CML_H 0X06F9
/* CML-H PCH */
#define PCH_THERMAL_DID_LWB 0xA1B1
/* Lewisburg PCH */
#define PCH_THERMAL_DID_WBG 0x8D24
/* Wellsburg PCH */
/* Wildcat Point-LP PCH Thermal registers */
#define WPT_TEMP 0x0000
/* Temperature */
...
...
@@ -65,6 +66,8 @@
#define WPT_TEMP_OFFSET (PCH_TEMP_OFFSET * MILLIDEGREE_PER_DEGREE)
#define GET_PCH_TEMP(x) (((x) / 2) + PCH_TEMP_OFFSET)
#define PCH_MAX_TRIPS 3
/* critical, hot, passive */
/* Amount of time for each cooling delay, 100ms by default for now */
static
unsigned
int
delay_timeout
=
100
;
module_param
(
delay_timeout
,
int
,
0644
);
...
...
@@ -82,12 +85,7 @@ struct pch_thermal_device {
const
struct
pch_dev_ops
*
ops
;
struct
pci_dev
*
pdev
;
struct
thermal_zone_device
*
tzd
;
int
crt_trip_id
;
unsigned
long
crt_temp
;
int
hot_trip_id
;
unsigned
long
hot_temp
;
int
psv_trip_id
;
unsigned
long
psv_temp
;
struct
thermal_trip
trips
[
PCH_MAX_TRIPS
];
bool
bios_enabled
;
};
...
...
@@ -102,33 +100,22 @@ static void pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd,
int
*
nr_trips
)
{
struct
acpi_device
*
adev
;
ptd
->
psv_trip_id
=
-
1
;
int
ret
;
adev
=
ACPI_COMPANION
(
&
ptd
->
pdev
->
dev
);
if
(
adev
)
{
unsigned
long
long
r
;
acpi_status
status
;
status
=
acpi_evaluate_integer
(
adev
->
handle
,
"_PSV"
,
NULL
,
&
r
);
if
(
ACPI_SUCCESS
(
status
))
{
unsigned
long
trip_temp
;
trip_temp
=
deci_kelvin_to_millicelsius
(
r
);
if
(
trip_temp
)
{
ptd
->
psv_temp
=
trip_temp
;
ptd
->
psv_trip_id
=
*
nr_trips
;
++
(
*
nr_trips
);
}
}
}
if
(
!
adev
)
return
;
ret
=
thermal_acpi_trip_passive
(
adev
,
&
ptd
->
trips
[
*
nr_trips
]);
if
(
ret
)
return
;
++
(
*
nr_trips
);
}
#else
static
void
pch_wpt_add_acpi_psv_trip
(
struct
pch_thermal_device
*
ptd
,
int
*
nr_trips
)
{
ptd
->
psv_trip_id
=
-
1
;
}
#endif
...
...
@@ -163,21 +150,19 @@ static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips)
}
read_trips:
ptd
->
crt_trip_id
=
-
1
;
trip_temp
=
readw
(
ptd
->
hw_base
+
WPT_CTT
);
trip_temp
&=
0x1FF
;
if
(
trip_temp
)
{
ptd
->
crt_temp
=
GET_WPT_TEMP
(
trip_temp
);
ptd
->
crt_trip_id
=
0
;
ptd
->
trips
[
*
nr_trips
].
temperature
=
GET_WPT_TEMP
(
trip_temp
);
ptd
->
trips
[
*
nr_trips
].
type
=
THERMAL_TRIP_CRITICAL
;
++
(
*
nr_trips
);
}
ptd
->
hot_trip_id
=
-
1
;
trip_temp
=
readw
(
ptd
->
hw_base
+
WPT_PHL
);
trip_temp
&=
0x1FF
;
if
(
trip_temp
)
{
ptd
->
hot_temp
=
GET_WPT_TEMP
(
trip_temp
);
ptd
->
hot_trip_id
=
*
nr_trips
;
ptd
->
trips
[
*
nr_trips
].
temperature
=
GET_WPT_TEMP
(
trip_temp
);
ptd
->
trips
[
*
nr_trips
].
type
=
THERMAL_TRIP_HOT
;
++
(
*
nr_trips
);
}
...
...
@@ -298,39 +283,6 @@ static int pch_thermal_get_temp(struct thermal_zone_device *tzd, int *temp)
return
ptd
->
ops
->
get_temp
(
ptd
,
temp
);
}
static
int
pch_get_trip_type
(
struct
thermal_zone_device
*
tzd
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
struct
pch_thermal_device
*
ptd
=
tzd
->
devdata
;
if
(
ptd
->
crt_trip_id
==
trip
)
*
type
=
THERMAL_TRIP_CRITICAL
;
else
if
(
ptd
->
hot_trip_id
==
trip
)
*
type
=
THERMAL_TRIP_HOT
;
else
if
(
ptd
->
psv_trip_id
==
trip
)
*
type
=
THERMAL_TRIP_PASSIVE
;
else
return
-
EINVAL
;
return
0
;
}
static
int
pch_get_trip_temp
(
struct
thermal_zone_device
*
tzd
,
int
trip
,
int
*
temp
)
{
struct
pch_thermal_device
*
ptd
=
tzd
->
devdata
;
if
(
ptd
->
crt_trip_id
==
trip
)
*
temp
=
ptd
->
crt_temp
;
else
if
(
ptd
->
hot_trip_id
==
trip
)
*
temp
=
ptd
->
hot_temp
;
else
if
(
ptd
->
psv_trip_id
==
trip
)
*
temp
=
ptd
->
psv_temp
;
else
return
-
EINVAL
;
return
0
;
}
static
void
pch_critical
(
struct
thermal_zone_device
*
tzd
)
{
dev_dbg
(
&
tzd
->
device
,
"%s: critical temperature reached
\n
"
,
tzd
->
type
);
...
...
@@ -338,8 +290,6 @@ static void pch_critical(struct thermal_zone_device *tzd)
static
struct
thermal_zone_device_ops
tzd_ops
=
{
.
get_temp
=
pch_thermal_get_temp
,
.
get_trip_type
=
pch_get_trip_type
,
.
get_trip_temp
=
pch_get_trip_temp
,
.
critical
=
pch_critical
,
};
...
...
@@ -350,6 +300,7 @@ enum board_ids {
board_cnl
,
board_cml
,
board_lwb
,
board_wbg
,
};
static
const
struct
board_info
{
...
...
@@ -380,6 +331,10 @@ static const struct board_info {
.
name
=
"pch_lewisburg"
,
.
ops
=
&
pch_dev_ops_wpt
,
},
[
board_wbg
]
=
{
.
name
=
"pch_wellsburg"
,
.
ops
=
&
pch_dev_ops_wpt
,
},
};
static
int
intel_pch_thermal_probe
(
struct
pci_dev
*
pdev
,
...
...
@@ -423,8 +378,9 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev,
if
(
err
)
goto
error_cleanup
;
ptd
->
tzd
=
thermal_zone_device_register
(
bi
->
name
,
nr_trips
,
0
,
ptd
,
&
tzd_ops
,
NULL
,
0
,
0
);
ptd
->
tzd
=
thermal_zone_device_register_with_trips
(
bi
->
name
,
ptd
->
trips
,
nr_trips
,
0
,
ptd
,
&
tzd_ops
,
NULL
,
0
,
0
);
if
(
IS_ERR
(
ptd
->
tzd
))
{
dev_err
(
&
pdev
->
dev
,
"Failed to register thermal zone %s
\n
"
,
bi
->
name
);
...
...
@@ -495,6 +451,8 @@ static const struct pci_device_id intel_pch_thermal_id[] = {
.
driver_data
=
board_cml
,
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCH_THERMAL_DID_LWB
),
.
driver_data
=
board_lwb
,
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCH_THERMAL_DID_WBG
),
.
driver_data
=
board_wbg
,
},
{
0
,
},
};
MODULE_DEVICE_TABLE
(
pci
,
intel_pch_thermal_id
);
...
...
drivers/thermal/intel/intel_soc_dts_iosf.c
View file @
a5c926ac
...
...
@@ -7,6 +7,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bitops.h>
#include <linux/intel_tcc.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
...
...
@@ -45,32 +46,6 @@
/* DTS0 and DTS 1 */
#define SOC_MAX_DTS_SENSORS 2
static
int
get_tj_max
(
u32
*
tj_max
)
{
u32
eax
,
edx
;
u32
val
;
int
err
;
err
=
rdmsr_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
&
eax
,
&
edx
);
if
(
err
)
goto
err_ret
;
else
{
val
=
(
eax
>>
16
)
&
0xff
;
if
(
val
)
*
tj_max
=
val
*
1000
;
else
{
err
=
-
EINVAL
;
goto
err_ret
;
}
}
return
0
;
err_ret:
*
tj_max
=
0
;
return
err
;
}
static
int
sys_get_trip_temp
(
struct
thermal_zone_device
*
tzd
,
int
trip
,
int
*
temp
)
{
...
...
@@ -405,7 +380,7 @@ struct intel_soc_dts_sensors *intel_soc_dts_iosf_init(
{
struct
intel_soc_dts_sensors
*
sensors
;
bool
notification
;
u32
tj_max
;
int
tj_max
;
int
ret
;
int
i
;
...
...
@@ -415,8 +390,9 @@ struct intel_soc_dts_sensors *intel_soc_dts_iosf_init(
if
(
!
trip_count
||
read_only_trip_count
>
trip_count
)
return
ERR_PTR
(
-
EINVAL
);
if
(
get_tj_max
(
&
tj_max
))
return
ERR_PTR
(
-
EINVAL
);
tj_max
=
intel_tcc_get_tjmax
(
-
1
);
if
(
tj_max
<
0
)
return
ERR_PTR
(
tj_max
);
sensors
=
kzalloc
(
sizeof
(
*
sensors
),
GFP_KERNEL
);
if
(
!
sensors
)
...
...
@@ -475,4 +451,5 @@ void intel_soc_dts_iosf_exit(struct intel_soc_dts_sensors *sensors)
}
EXPORT_SYMBOL_GPL
(
intel_soc_dts_iosf_exit
);
MODULE_IMPORT_NS
(
INTEL_TCC
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/thermal/intel/intel_tcc.c
0 → 100644
View file @
a5c926ac
// SPDX-License-Identifier: GPL-2.0-only
/*
* intel_tcc.c - Library for Intel TCC (thermal control circuitry) MSR access
* Copyright (c) 2022, Intel Corporation.
*/
#include <linux/errno.h>
#include <linux/intel_tcc.h>
#include <asm/msr.h>
/**
* intel_tcc_get_tjmax() - returns the default TCC activation Temperature
* @cpu: cpu that the MSR should be run on, nagative value means any cpu.
*
* Get the TjMax value, which is the default thermal throttling or TCC
* activation temperature in degrees C.
*
* Return: Tjmax value in degrees C on success, negative error code otherwise.
*/
int
intel_tcc_get_tjmax
(
int
cpu
)
{
u32
low
,
high
;
int
val
,
err
;
if
(
cpu
<
0
)
err
=
rdmsr_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
&
low
,
&
high
);
else
err
=
rdmsr_safe_on_cpu
(
cpu
,
MSR_IA32_TEMPERATURE_TARGET
,
&
low
,
&
high
);
if
(
err
)
return
err
;
val
=
(
low
>>
16
)
&
0xff
;
return
val
?
val
:
-
ENODATA
;
}
EXPORT_SYMBOL_NS_GPL
(
intel_tcc_get_tjmax
,
INTEL_TCC
);
/**
* intel_tcc_get_offset() - returns the TCC Offset value to Tjmax
* @cpu: cpu that the MSR should be run on, nagative value means any cpu.
*
* Get the TCC offset value to Tjmax. The effective thermal throttling or TCC
* activation temperature equals "Tjmax" - "TCC Offset", in degrees C.
*
* Return: Tcc offset value in degrees C on success, negative error code otherwise.
*/
int
intel_tcc_get_offset
(
int
cpu
)
{
u32
low
,
high
;
int
err
;
if
(
cpu
<
0
)
err
=
rdmsr_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
&
low
,
&
high
);
else
err
=
rdmsr_safe_on_cpu
(
cpu
,
MSR_IA32_TEMPERATURE_TARGET
,
&
low
,
&
high
);
if
(
err
)
return
err
;
return
(
low
>>
24
)
&
0x3f
;
}
EXPORT_SYMBOL_NS_GPL
(
intel_tcc_get_offset
,
INTEL_TCC
);
/**
* intel_tcc_set_offset() - set the TCC offset value to Tjmax
* @cpu: cpu that the MSR should be run on, nagative value means any cpu.
* @offset: TCC offset value in degree C
*
* Set the TCC Offset value to Tjmax. The effective thermal throttling or TCC
* activation temperature equals "Tjmax" - "TCC Offset", in degree C.
*
* Return: On success returns 0, negative error code otherwise.
*/
int
intel_tcc_set_offset
(
int
cpu
,
int
offset
)
{
u32
low
,
high
;
int
err
;
if
(
offset
<
0
||
offset
>
0x3f
)
return
-
EINVAL
;
if
(
cpu
<
0
)
err
=
rdmsr_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
&
low
,
&
high
);
else
err
=
rdmsr_safe_on_cpu
(
cpu
,
MSR_IA32_TEMPERATURE_TARGET
,
&
low
,
&
high
);
if
(
err
)
return
err
;
/* MSR Locked */
if
(
low
&
BIT
(
31
))
return
-
EPERM
;
low
&=
~
(
0x3f
<<
24
);
low
|=
offset
<<
24
;
if
(
cpu
<
0
)
return
wrmsr_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
low
,
high
);
else
return
wrmsr_safe_on_cpu
(
cpu
,
MSR_IA32_TEMPERATURE_TARGET
,
low
,
high
);
}
EXPORT_SYMBOL_NS_GPL
(
intel_tcc_set_offset
,
INTEL_TCC
);
/**
* intel_tcc_get_temp() - returns the current temperature
* @cpu: cpu that the MSR should be run on, nagative value means any cpu.
* @pkg: true: Package Thermal Sensor. false: Core Thermal Sensor.
*
* Get the current temperature returned by the CPU core/package level
* thermal sensor, in degrees C.
*
* Return: Temperature in degrees C on success, negative error code otherwise.
*/
int
intel_tcc_get_temp
(
int
cpu
,
bool
pkg
)
{
u32
low
,
high
;
u32
msr
=
pkg
?
MSR_IA32_PACKAGE_THERM_STATUS
:
MSR_IA32_THERM_STATUS
;
int
tjmax
,
temp
,
err
;
tjmax
=
intel_tcc_get_tjmax
(
cpu
);
if
(
tjmax
<
0
)
return
tjmax
;
if
(
cpu
<
0
)
err
=
rdmsr_safe
(
msr
,
&
low
,
&
high
);
else
err
=
rdmsr_safe_on_cpu
(
cpu
,
msr
,
&
low
,
&
high
);
if
(
err
)
return
err
;
/* Temperature is beyond the valid thermal sensor range */
if
(
!
(
low
&
BIT
(
31
)))
return
-
ENODATA
;
temp
=
tjmax
-
((
low
>>
16
)
&
0x7f
);
/* Do not allow negative CPU temperature */
return
temp
>=
0
?
temp
:
-
ENODATA
;
}
EXPORT_SYMBOL_NS_GPL
(
intel_tcc_get_temp
,
INTEL_TCC
);
drivers/thermal/intel/intel_tcc_cooling.c
View file @
a5c926ac
...
...
@@ -7,12 +7,11 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/device.h>
#include <linux/intel_tcc.h>
#include <linux/module.h>
#include <linux/thermal.h>
#include <asm/cpu_device_id.h>
#define TCC_SHIFT 24
#define TCC_MASK (0x3fULL<<24)
#define TCC_PROGRAMMABLE BIT(30)
#define TCC_LOCKED BIT(31)
...
...
@@ -21,47 +20,26 @@ static struct thermal_cooling_device *tcc_cdev;
static
int
tcc_get_max_state
(
struct
thermal_cooling_device
*
cdev
,
unsigned
long
*
state
)
{
*
state
=
TCC_MASK
>>
TCC_SHIFT
;
return
0
;
}
static
int
tcc_offset_update
(
int
tcc
)
{
u64
val
;
int
err
;
err
=
rdmsrl_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
&
val
);
if
(
err
)
return
err
;
val
&=
~
TCC_MASK
;
val
|=
tcc
<<
TCC_SHIFT
;
err
=
wrmsrl_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
val
);
if
(
err
)
return
err
;
*
state
=
0x3f
;
return
0
;
}
static
int
tcc_get_cur_state
(
struct
thermal_cooling_device
*
cdev
,
unsigned
long
*
state
)
{
u64
val
;
int
err
;
int
offset
=
intel_tcc_get_offset
(
-
1
);
err
=
rdmsrl_safe
(
MSR_IA32_TEMPERATURE_TARGET
,
&
val
);
if
(
err
)
return
err
;
if
(
offset
<
0
)
return
offset
;
*
state
=
(
val
&
TCC_MASK
)
>>
TCC_SHIFT
;
*
state
=
offset
;
return
0
;
}
static
int
tcc_set_cur_state
(
struct
thermal_cooling_device
*
cdev
,
unsigned
long
state
)
{
return
tcc_offset_update
(
state
);
return
intel_tcc_set_offset
(
-
1
,
(
int
)
state
);
}
static
const
struct
thermal_cooling_device_ops
tcc_cooling_ops
=
{
...
...
@@ -140,6 +118,7 @@ static void __exit tcc_cooling_exit(void)
module_exit
(
tcc_cooling_exit
)
MODULE_IMPORT_NS
(
INTEL_TCC
);
MODULE_DESCRIPTION
(
"TCC offset cooling device Driver"
);
MODULE_AUTHOR
(
"Zhang Rui <rui.zhang@intel.com>"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/thermal/intel/x86_pkg_temp_thermal.c
View file @
a5c926ac
...
...
@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/intel_tcc.h>
#include <linux/err.h>
#include <linux/param.h>
#include <linux/device.h>
...
...
@@ -48,11 +49,11 @@ MODULE_PARM_DESC(notify_delay_ms,
struct
zone_device
{
int
cpu
;
bool
work_scheduled
;
u32
tj_max
;
u32
msr_pkg_therm_low
;
u32
msr_pkg_therm_high
;
struct
delayed_work
work
;
struct
thermal_zone_device
*
tzone
;
struct
thermal_trip
*
trips
;
struct
cpumask
cpumask
;
};
...
...
@@ -104,71 +105,17 @@ static struct zone_device *pkg_temp_thermal_get_dev(unsigned int cpu)
return
NULL
;
}
/*
* tj-max is interesting because threshold is set relative to this
* temperature.
*/
static
int
get_tj_max
(
int
cpu
,
u32
*
tj_max
)
{
u32
eax
,
edx
,
val
;
int
err
;
err
=
rdmsr_safe_on_cpu
(
cpu
,
MSR_IA32_TEMPERATURE_TARGET
,
&
eax
,
&
edx
);
if
(
err
)
return
err
;
val
=
(
eax
>>
16
)
&
0xff
;
*
tj_max
=
val
*
1000
;
return
val
?
0
:
-
EINVAL
;
}
static
int
sys_get_curr_temp
(
struct
thermal_zone_device
*
tzd
,
int
*
temp
)
{
struct
zone_device
*
zonedev
=
tzd
->
devdata
;
u32
eax
,
edx
;
rdmsr_on_cpu
(
zonedev
->
cpu
,
MSR_IA32_PACKAGE_THERM_STATUS
,
&
eax
,
&
edx
);
if
(
eax
&
0x80000000
)
{
*
temp
=
zonedev
->
tj_max
-
((
eax
>>
16
)
&
0x7f
)
*
1000
;
pr_debug
(
"sys_get_curr_temp %d
\n
"
,
*
temp
);
return
0
;
}
return
-
EINVAL
;
}
static
int
sys_get_trip_temp
(
struct
thermal_zone_device
*
tzd
,
int
trip
,
int
*
temp
)
{
struct
zone_device
*
zonedev
=
tzd
->
devdata
;
unsigned
long
thres_reg_value
;
u32
mask
,
shift
,
eax
,
edx
;
int
ret
;
if
(
trip
>=
MAX_NUMBER_OF_TRIPS
)
return
-
EINVAL
;
if
(
trip
)
{
mask
=
THERM_MASK_THRESHOLD1
;
shift
=
THERM_SHIFT_THRESHOLD1
;
}
else
{
mask
=
THERM_MASK_THRESHOLD0
;
shift
=
THERM_SHIFT_THRESHOLD0
;
}
ret
=
rdmsr_on_cpu
(
zonedev
->
cpu
,
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
&
eax
,
&
edx
);
if
(
ret
<
0
)
return
ret
;
int
val
;
thres_reg_value
=
(
eax
&
mask
)
>>
shift
;
if
(
thres_reg_value
)
*
temp
=
zonedev
->
tj_max
-
thres_reg_value
*
1000
;
else
*
temp
=
THERMAL_TEMP_INVALID
;
pr_debug
(
"sys_get_trip_temp %d
\n
"
,
*
temp
);
val
=
intel_tcc_get_temp
(
zonedev
->
cpu
,
true
);
if
(
val
<
0
)
return
val
;
*
temp
=
val
*
1000
;
pr_debug
(
"sys_get_curr_temp %d
\n
"
,
*
temp
);
return
0
;
}
...
...
@@ -177,9 +124,14 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
{
struct
zone_device
*
zonedev
=
tzd
->
devdata
;
u32
l
,
h
,
mask
,
shift
,
intr
;
int
ret
;
int
tj_max
,
ret
;
tj_max
=
intel_tcc_get_tjmax
(
zonedev
->
cpu
);
if
(
tj_max
<
0
)
return
tj_max
;
tj_max
*=
1000
;
if
(
trip
>=
MAX_NUMBER_OF_TRIPS
||
temp
>=
zonedev
->
tj_max
)
if
(
trip
>=
MAX_NUMBER_OF_TRIPS
||
temp
>=
tj_max
)
return
-
EINVAL
;
ret
=
rdmsr_on_cpu
(
zonedev
->
cpu
,
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
...
...
@@ -204,7 +156,7 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
if
(
!
temp
)
{
l
&=
~
intr
;
}
else
{
l
|=
(
zonedev
->
tj_max
-
temp
)
/
1000
<<
shift
;
l
|=
(
tj_max
-
temp
)
/
1000
<<
shift
;
l
|=
intr
;
}
...
...
@@ -212,18 +164,9 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
l
,
h
);
}
static
int
sys_get_trip_type
(
struct
thermal_zone_device
*
thermal
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
*
type
=
THERMAL_TRIP_PASSIVE
;
return
0
;
}
/* Thermal zone callback registry */
static
struct
thermal_zone_device_ops
tzone_ops
=
{
.
get_temp
=
sys_get_curr_temp
,
.
get_trip_temp
=
sys_get_trip_temp
,
.
get_trip_type
=
sys_get_trip_type
,
.
set_trip_temp
=
sys_set_trip_temp
,
};
...
...
@@ -323,12 +266,55 @@ static int pkg_thermal_notify(u64 msr_val)
return
0
;
}
static
struct
thermal_trip
*
pkg_temp_thermal_trips_init
(
int
cpu
,
int
tj_max
,
int
num_trips
)
{
struct
thermal_trip
*
trips
;
unsigned
long
thres_reg_value
;
u32
mask
,
shift
,
eax
,
edx
;
int
ret
,
i
;
trips
=
kzalloc
(
sizeof
(
*
trips
)
*
num_trips
,
GFP_KERNEL
);
if
(
!
trips
)
return
ERR_PTR
(
-
ENOMEM
);
for
(
i
=
0
;
i
<
num_trips
;
i
++
)
{
if
(
i
)
{
mask
=
THERM_MASK_THRESHOLD1
;
shift
=
THERM_SHIFT_THRESHOLD1
;
}
else
{
mask
=
THERM_MASK_THRESHOLD0
;
shift
=
THERM_SHIFT_THRESHOLD0
;
}
ret
=
rdmsr_on_cpu
(
cpu
,
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
&
eax
,
&
edx
);
if
(
ret
<
0
)
{
kfree
(
trips
);
return
ERR_PTR
(
ret
);
}
thres_reg_value
=
(
eax
&
mask
)
>>
shift
;
trips
[
i
].
temperature
=
thres_reg_value
?
tj_max
-
thres_reg_value
*
1000
:
THERMAL_TEMP_INVALID
;
trips
[
i
].
type
=
THERMAL_TRIP_PASSIVE
;
pr_debug
(
"%s: cpu=%d, trip=%d, temp=%d
\n
"
,
__func__
,
cpu
,
i
,
trips
[
i
].
temperature
);
}
return
trips
;
}
static
int
pkg_temp_thermal_device_add
(
unsigned
int
cpu
)
{
int
id
=
topology_logical_die_id
(
cpu
);
u32
tj_max
,
eax
,
ebx
,
ecx
,
edx
;
u32
eax
,
ebx
,
ecx
,
edx
;
struct
zone_device
*
zonedev
;
int
thres_count
,
err
;
int
tj_max
;
if
(
id
>=
max_id
)
return
-
ENOMEM
;
...
...
@@ -340,32 +326,34 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
thres_count
=
clamp_val
(
thres_count
,
0
,
MAX_NUMBER_OF_TRIPS
);
err
=
get_tj_max
(
cpu
,
&
tj_max
);
if
(
err
)
return
err
;
tj_max
=
intel_tcc_get_tjmax
(
cpu
);
if
(
tj_max
<
0
)
return
tj_max
;
zonedev
=
kzalloc
(
sizeof
(
*
zonedev
),
GFP_KERNEL
);
if
(
!
zonedev
)
return
-
ENOMEM
;
zonedev
->
trips
=
pkg_temp_thermal_trips_init
(
cpu
,
tj_max
,
thres_count
);
if
(
IS_ERR
(
zonedev
->
trips
))
{
err
=
PTR_ERR
(
zonedev
->
trips
);
goto
out_kfree_zonedev
;
}
INIT_DELAYED_WORK
(
&
zonedev
->
work
,
pkg_temp_thermal_threshold_work_fn
);
zonedev
->
cpu
=
cpu
;
zonedev
->
tj_max
=
tj_max
;
zonedev
->
tzone
=
thermal_zone_device_register
(
"x86_pkg_temp"
,
thres_count
,
zonedev
->
tzone
=
thermal_zone_device_register_with_trips
(
"x86_pkg_temp"
,
zonedev
->
trips
,
thres_count
,
(
thres_count
==
MAX_NUMBER_OF_TRIPS
)
?
0x03
:
0x01
,
zonedev
,
&
tzone_ops
,
&
pkg_temp_tz_params
,
0
,
0
);
if
(
IS_ERR
(
zonedev
->
tzone
))
{
err
=
PTR_ERR
(
zonedev
->
tzone
);
kfree
(
zonedev
);
return
err
;
goto
out_kfree_trips
;
}
err
=
thermal_zone_device_enable
(
zonedev
->
tzone
);
if
(
err
)
{
thermal_zone_device_unregister
(
zonedev
->
tzone
);
kfree
(
zonedev
);
return
err
;
}
if
(
err
)
goto
out_unregister_tz
;
/* Store MSR value for package thermal interrupt, to restore at exit */
rdmsr
(
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
zonedev
->
msr_pkg_therm_low
,
zonedev
->
msr_pkg_therm_high
);
...
...
@@ -374,7 +362,16 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
raw_spin_lock_irq
(
&
pkg_temp_lock
);
zones
[
id
]
=
zonedev
;
raw_spin_unlock_irq
(
&
pkg_temp_lock
);
return
0
;
out_unregister_tz:
thermal_zone_device_unregister
(
zonedev
->
tzone
);
out_kfree_trips:
kfree
(
zonedev
->
trips
);
out_kfree_zonedev:
kfree
(
zonedev
);
return
err
;
}
static
int
pkg_thermal_cpu_offline
(
unsigned
int
cpu
)
...
...
@@ -458,8 +455,10 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
raw_spin_unlock_irq
(
&
pkg_temp_lock
);
/* Final cleanup if this is the last cpu */
if
(
lastcpu
)
if
(
lastcpu
)
{
kfree
(
zonedev
->
trips
);
kfree
(
zonedev
);
}
return
0
;
}
...
...
@@ -531,6 +530,7 @@ static void __exit pkg_temp_thermal_exit(void)
}
module_exit
(
pkg_temp_thermal_exit
)
MODULE_IMPORT_NS
(
INTEL_TCC
);
MODULE_DESCRIPTION
(
"X86 PKG TEMP Thermal Driver"
);
MODULE_AUTHOR
(
"Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/thermal/qcom/qcom-spmi-temp-alarm.c
View file @
a5c926ac
...
...
@@ -264,17 +264,17 @@ static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
return
qpnp_tm_write
(
chip
,
QPNP_TM_REG_SHUTDOWN_CTRL1
,
reg
);
}
static
int
qpnp_tm_set_trip_temp
(
struct
thermal_zone_device
*
tz
,
int
trip
,
int
temp
)
static
int
qpnp_tm_set_trip_temp
(
struct
thermal_zone_device
*
tz
,
int
trip
_id
,
int
temp
)
{
struct
qpnp_tm_chip
*
chip
=
tz
->
devdata
;
const
struct
thermal_trip
*
trip_points
;
struct
thermal_trip
trip
;
int
ret
;
trip_points
=
of_thermal_get_trip_points
(
chip
->
tz_dev
);
if
(
!
trip_points
)
return
-
EINVAL
;
ret
=
__thermal_zone_get_trip
(
chip
->
tz_dev
,
trip_id
,
&
trip
);
if
(
ret
)
return
ret
;
if
(
trip
_points
[
trip
]
.
type
!=
THERMAL_TRIP_CRITICAL
)
if
(
trip
.
type
!=
THERMAL_TRIP_CRITICAL
)
return
0
;
mutex_lock
(
&
chip
->
lock
);
...
...
@@ -300,22 +300,17 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data)
static
int
qpnp_tm_get_critical_trip_temp
(
struct
qpnp_tm_chip
*
chip
)
{
int
ntrips
;
const
struct
thermal_trip
*
trips
;
int
i
;
ntrips
=
of_thermal_get_ntrips
(
chip
->
tz_dev
);
if
(
ntrips
<=
0
)
return
THERMAL_TEMP_INVALID
;
trips
=
of_thermal_get_trip_points
(
chip
->
tz_dev
);
if
(
!
trips
)
return
THERMAL_TEMP_INVALID
;
for
(
i
=
0
;
i
<
ntrips
;
i
++
)
{
if
(
of_thermal_is_trip_valid
(
chip
->
tz_dev
,
i
)
&&
trips
[
i
].
type
==
THERMAL_TRIP_CRITICAL
)
return
trips
[
i
].
temperature
;
struct
thermal_trip
trip
;
int
i
,
ret
;
for
(
i
=
0
;
i
<
thermal_zone_get_num_trips
(
chip
->
tz_dev
);
i
++
)
{
ret
=
thermal_zone_get_trip
(
chip
->
tz_dev
,
i
,
&
trip
);
if
(
ret
)
continue
;
if
(
trip
.
type
==
THERMAL_TRIP_CRITICAL
)
return
trip
.
temperature
;
}
return
THERMAL_TEMP_INVALID
;
...
...
@@ -353,7 +348,12 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip)
if
(
stage
)
chip
->
temp
=
qpnp_tm_decode_temp
(
chip
,
stage
);
mutex_unlock
(
&
chip
->
lock
);
crit_temp
=
qpnp_tm_get_critical_trip_temp
(
chip
);
mutex_lock
(
&
chip
->
lock
);
ret
=
qpnp_tm_update_critical_trip_temp
(
chip
,
crit_temp
);
if
(
ret
<
0
)
goto
out
;
...
...
drivers/thermal/rcar_gen3_thermal.c
View file @
a5c926ac
...
...
@@ -529,7 +529,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
if
(
ret
)
goto
error_unregister
;
ret
=
of_thermal_get_n
trips
(
tsc
->
zone
);
ret
=
thermal_zone_get_num_
trips
(
tsc
->
zone
);
if
(
ret
<
0
)
goto
error_unregister
;
...
...
drivers/thermal/rcar_thermal.c
View file @
a5c926ac
...
...
@@ -278,52 +278,12 @@ static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp)
return
rcar_thermal_get_current_temp
(
priv
,
temp
);
}
static
int
rcar_thermal_get_trip_type
(
struct
thermal_zone_device
*
zone
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
struct
rcar_thermal_priv
*
priv
=
rcar_zone_to_priv
(
zone
);
struct
device
*
dev
=
rcar_priv_to_dev
(
priv
);
/* see rcar_thermal_get_temp() */
switch
(
trip
)
{
case
0
:
/* +90 <= temp */
*
type
=
THERMAL_TRIP_CRITICAL
;
break
;
default:
dev_err
(
dev
,
"rcar driver trip error
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
int
rcar_thermal_get_trip_temp
(
struct
thermal_zone_device
*
zone
,
int
trip
,
int
*
temp
)
{
struct
rcar_thermal_priv
*
priv
=
rcar_zone_to_priv
(
zone
);
struct
device
*
dev
=
rcar_priv_to_dev
(
priv
);
/* see rcar_thermal_get_temp() */
switch
(
trip
)
{
case
0
:
/* +90 <= temp */
*
temp
=
MCELSIUS
(
90
);
break
;
default:
dev_err
(
dev
,
"rcar driver trip error
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
const
struct
thermal_zone_device_ops
rcar_thermal_zone_of_ops
=
{
static
struct
thermal_zone_device_ops
rcar_thermal_zone_ops
=
{
.
get_temp
=
rcar_thermal_get_temp
,
};
static
struct
thermal_zone_device_ops
rcar_thermal_zone_ops
=
{
.
get_temp
=
rcar_thermal_get_temp
,
.
get_trip_type
=
rcar_thermal_get_trip_type
,
.
get_trip_temp
=
rcar_thermal_get_trip_temp
,
static
struct
thermal_trip
trips
[]
=
{
{
.
type
=
THERMAL_TRIP_CRITICAL
,
.
temperature
=
90000
}
};
/*
...
...
@@ -529,11 +489,10 @@ static int rcar_thermal_probe(struct platform_device *pdev)
if
(
chip
->
use_of_thermal
)
{
priv
->
zone
=
devm_thermal_of_zone_register
(
dev
,
i
,
priv
,
&
rcar_thermal_zone_o
f_o
ps
);
&
rcar_thermal_zone_ops
);
}
else
{
priv
->
zone
=
thermal_zone_device_register
(
"rcar_thermal"
,
1
,
0
,
priv
,
priv
->
zone
=
thermal_zone_device_register_with_trips
(
"rcar_thermal"
,
trips
,
ARRAY_SIZE
(
trips
),
0
,
priv
,
&
rcar_thermal_zone_ops
,
NULL
,
0
,
idle
);
...
...
drivers/thermal/samsung/exynos_tmu.c
View file @
a5c926ac
...
...
@@ -260,31 +260,23 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
{
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
struct
thermal_zone_device
*
tzd
=
data
->
tzd
;
const
struct
thermal_trip
*
const
trips
=
of_thermal_get_trip_points
(
tzd
);
int
num_trips
=
thermal_zone_get_num_trips
(
tzd
);
unsigned
int
status
;
int
ret
=
0
,
temp
,
hyst
;
int
ret
=
0
,
temp
;
if
(
!
trips
)
{
dev_err
(
&
pdev
->
dev
,
"Cannot get trip points from device tree!
\n
"
);
return
-
ENODEV
;
}
if
(
data
->
soc
!=
SOC_ARCH_EXYNOS5433
)
/* FIXME */
ret
=
tzd
->
ops
->
get_crit_temp
(
tzd
,
&
temp
);
if
(
ret
)
{
ret
=
thermal_zone_get_crit_temp
(
tzd
,
&
temp
);
if
(
ret
&&
data
->
soc
!=
SOC_ARCH_EXYNOS5433
)
{
/* FIXME */
dev_err
(
&
pdev
->
dev
,
"No CRITICAL trip point defined in device tree!
\n
"
);
goto
out
;
}
if
(
of_thermal_get_ntrips
(
tzd
)
>
data
->
ntrip
)
{
if
(
num_trips
>
data
->
ntrip
)
{
dev_info
(
&
pdev
->
dev
,
"More trip points than supported by this TMU.
\n
"
);
dev_info
(
&
pdev
->
dev
,
"%d trip points should be configured in polling mode.
\n
"
,
(
of_thermal_get_ntrips
(
tzd
)
-
data
->
ntrip
)
);
num_trips
-
data
->
ntrip
);
}
mutex_lock
(
&
data
->
lock
);
...
...
@@ -297,25 +289,22 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
ret
=
-
EBUSY
;
}
else
{
int
i
,
ntrips
=
min_t
(
int
,
of_thermal_get_ntrips
(
tzd
)
,
data
->
ntrip
);
min_t
(
int
,
num_trips
,
data
->
ntrip
);
data
->
tmu_initialize
(
pdev
);
/* Write temperature code for rising and falling threshold */
for
(
i
=
0
;
i
<
ntrips
;
i
++
)
{
/* Write temperature code for rising threshold */
ret
=
tzd
->
ops
->
get_trip_temp
(
tzd
,
i
,
&
temp
);
if
(
ret
)
goto
err
;
temp
/=
MCELSIUS
;
data
->
tmu_set_trip_temp
(
data
,
i
,
temp
);
/* Write temperature code for falling threshold */
ret
=
tzd
->
ops
->
get_trip_hyst
(
tzd
,
i
,
&
hyst
);
struct
thermal_trip
trip
;
ret
=
thermal_zone_get_trip
(
tzd
,
i
,
&
trip
);
if
(
ret
)
goto
err
;
hyst
/=
MCELSIUS
;
data
->
tmu_set_trip_hyst
(
data
,
i
,
temp
,
hyst
);
data
->
tmu_set_trip_temp
(
data
,
i
,
trip
.
temperature
/
MCELSIUS
);
data
->
tmu_set_trip_hyst
(
data
,
i
,
trip
.
temperature
/
MCELSIUS
,
trip
.
hysteresis
/
MCELSIUS
);
}
data
->
tmu_clear_irqs
(
data
);
...
...
@@ -360,21 +349,23 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
}
static
void
exynos4210_tmu_set_trip_temp
(
struct
exynos_tmu_data
*
data
,
int
trip
,
u8
temp
)
int
trip
_id
,
u8
temp
)
{
const
struct
thermal_trip
*
const
trips
=
of_thermal_get_trip_points
(
data
->
tzd
);
struct
thermal_trip
trip
;
u8
ref
,
th_code
;
ref
=
trips
[
0
].
temperature
/
MCELSIUS
;
if
(
thermal_zone_get_trip
(
data
->
tzd
,
0
,
&
trip
))
return
;
ref
=
trip
.
temperature
/
MCELSIUS
;
if
(
trip
==
0
)
{
if
(
trip
_id
==
0
)
{
th_code
=
temp_to_code
(
data
,
ref
);
writeb
(
th_code
,
data
->
base
+
EXYNOS4210_TMU_REG_THRESHOLD_TEMP
);
}
temp
-=
ref
;
writeb
(
temp
,
data
->
base
+
EXYNOS4210_TMU_REG_TRIG_LEVEL0
+
trip
*
4
);
writeb
(
temp
,
data
->
base
+
EXYNOS4210_TMU_REG_TRIG_LEVEL0
+
trip
_id
*
4
);
}
/* failing thresholds are not supported on Exynos4210 */
...
...
@@ -562,13 +553,14 @@ static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
{
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
struct
thermal_zone_device
*
tz
=
data
->
tzd
;
struct
thermal_trip
trip
;
unsigned
int
con
,
interrupt_en
=
0
,
i
;
con
=
get_con_reg
(
data
,
readl
(
data
->
base
+
EXYNOS_TMU_REG_CONTROL
));
if
(
on
)
{
for
(
i
=
0
;
i
<
data
->
ntrip
;
i
++
)
{
if
(
!
of_thermal_is_trip_valid
(
tz
,
i
))
if
(
thermal_zone_get_trip
(
tz
,
i
,
&
trip
))
continue
;
interrupt_en
|=
...
...
@@ -592,13 +584,14 @@ static void exynos5433_tmu_control(struct platform_device *pdev, bool on)
{
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
struct
thermal_zone_device
*
tz
=
data
->
tzd
;
struct
thermal_trip
trip
;
unsigned
int
con
,
interrupt_en
=
0
,
pd_det_en
,
i
;
con
=
get_con_reg
(
data
,
readl
(
data
->
base
+
EXYNOS_TMU_REG_CONTROL
));
if
(
on
)
{
for
(
i
=
0
;
i
<
data
->
ntrip
;
i
++
)
{
if
(
!
of_thermal_is_trip_valid
(
tz
,
i
))
if
(
thermal_zone_get_trip
(
tz
,
i
,
&
trip
))
continue
;
interrupt_en
|=
...
...
@@ -623,13 +616,14 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on)
{
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
struct
thermal_zone_device
*
tz
=
data
->
tzd
;
struct
thermal_trip
trip
;
unsigned
int
con
,
interrupt_en
=
0
,
i
;
con
=
get_con_reg
(
data
,
readl
(
data
->
base
+
EXYNOS_TMU_REG_CONTROL
));
if
(
on
)
{
for
(
i
=
0
;
i
<
data
->
ntrip
;
i
++
)
{
if
(
!
of_thermal_is_trip_valid
(
tz
,
i
))
if
(
thermal_zone_get_trip
(
tz
,
i
,
&
trip
))
continue
;
interrupt_en
|=
...
...
drivers/thermal/st/st_thermal.c
View file @
a5c926ac
...
...
@@ -134,48 +134,12 @@ static int st_thermal_get_temp(struct thermal_zone_device *th, int *temperature)
return
0
;
}
static
int
st_thermal_get_trip_type
(
struct
thermal_zone_device
*
th
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
struct
st_thermal_sensor
*
sensor
=
th
->
devdata
;
struct
device
*
dev
=
sensor
->
dev
;
switch
(
trip
)
{
case
0
:
*
type
=
THERMAL_TRIP_CRITICAL
;
break
;
default:
dev_err
(
dev
,
"invalid trip point
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
int
st_thermal_get_trip_temp
(
struct
thermal_zone_device
*
th
,
int
trip
,
int
*
temp
)
{
struct
st_thermal_sensor
*
sensor
=
th
->
devdata
;
struct
device
*
dev
=
sensor
->
dev
;
switch
(
trip
)
{
case
0
:
*
temp
=
mcelsius
(
sensor
->
cdata
->
crit_temp
);
break
;
default:
dev_err
(
dev
,
"Invalid trip point
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
struct
thermal_zone_device_ops
st_tz_ops
=
{
.
get_temp
=
st_thermal_get_temp
,
.
get_trip_type
=
st_thermal_get_trip_type
,
.
get_trip_temp
=
st_thermal_get_trip_temp
,
};
static
struct
thermal_trip
trip
;
int
st_thermal_register
(
struct
platform_device
*
pdev
,
const
struct
of_device_id
*
st_thermal_of_match
)
{
...
...
@@ -238,9 +202,12 @@ int st_thermal_register(struct platform_device *pdev,
polling_delay
=
sensor
->
ops
->
register_enable_irq
?
0
:
1000
;
trip
.
temperature
=
sensor
->
cdata
->
crit_temp
;
trip
.
type
=
THERMAL_TRIP_CRITICAL
;
sensor
->
thermal_dev
=
thermal_zone_device_register
(
dev_name
(
dev
)
,
1
,
0
,
sensor
,
&
st_tz_ops
,
NULL
,
0
,
polling_delay
);
thermal_zone_device_register
_with_trips
(
dev_name
(
dev
),
&
trip
,
1
,
0
,
sensor
,
&
st_tz_ops
,
NULL
,
0
,
polling_delay
);
if
(
IS_ERR
(
sensor
->
thermal_dev
))
{
dev_err
(
dev
,
"failed to register thermal zone device
\n
"
);
ret
=
PTR_ERR
(
sensor
->
thermal_dev
);
...
...
drivers/thermal/tegra/soctherm.c
View file @
a5c926ac
...
...
@@ -582,23 +582,23 @@ static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id)
return
temp
;
}
static
int
tegra_thermctl_set_trip_temp
(
struct
thermal_zone_device
*
tz
,
int
trip
,
int
temp
)
static
int
tegra_thermctl_set_trip_temp
(
struct
thermal_zone_device
*
tz
,
int
trip
_id
,
int
temp
)
{
struct
tegra_thermctl_zone
*
zone
=
tz
->
devdata
;
struct
tegra_soctherm
*
ts
=
zone
->
ts
;
struct
thermal_trip
trip
;
const
struct
tegra_tsensor_group
*
sg
=
zone
->
sg
;
struct
device
*
dev
=
zone
->
dev
;
enum
thermal_trip_type
type
;
int
ret
;
if
(
!
tz
)
return
-
EINVAL
;
ret
=
tz
->
ops
->
get_trip_type
(
tz
,
trip
,
&
type
);
ret
=
__thermal_zone_get_trip
(
tz
,
trip_id
,
&
trip
);
if
(
ret
)
return
ret
;
if
(
type
==
THERMAL_TRIP_CRITICAL
)
{
if
(
t
rip
.
t
ype
==
THERMAL_TRIP_CRITICAL
)
{
/*
* If thermtrips property is set in DT,
* doesn't need to program critical type trip to HW,
...
...
@@ -609,7 +609,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip
else
return
0
;
}
else
if
(
type
==
THERMAL_TRIP_HOT
)
{
}
else
if
(
t
rip
.
t
ype
==
THERMAL_TRIP_HOT
)
{
int
i
;
for
(
i
=
0
;
i
<
THROTTLE_SIZE
;
i
++
)
{
...
...
@@ -620,7 +620,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip
continue
;
cdev
=
ts
->
throt_cfgs
[
i
].
cdev
;
if
(
get_thermal_instance
(
tz
,
cdev
,
trip
))
if
(
get_thermal_instance
(
tz
,
cdev
,
trip
_id
))
stc
=
find_throttle_cfg_by_name
(
ts
,
cdev
->
type
);
else
continue
;
...
...
@@ -687,25 +687,20 @@ static const struct thermal_zone_device_ops tegra_of_thermal_ops = {
.
set_trips
=
tegra_thermctl_set_trips
,
};
static
int
get_hot_temp
(
struct
thermal_zone_device
*
tz
,
int
*
trip
,
int
*
temp
)
static
int
get_hot_temp
(
struct
thermal_zone_device
*
tz
,
int
*
trip
_id
,
int
*
temp
)
{
int
ntrips
,
i
,
ret
;
enum
thermal_trip_type
type
;
int
i
,
ret
;
struct
thermal_trip
trip
;
ntrips
=
of_thermal_get_ntrips
(
tz
);
if
(
ntrips
<=
0
)
return
-
EINVAL
;
for
(
i
=
0
;
i
<
thermal_zone_get_num_trips
(
tz
);
i
++
)
{
for
(
i
=
0
;
i
<
ntrips
;
i
++
)
{
ret
=
tz
->
ops
->
get_trip_type
(
tz
,
i
,
&
type
);
ret
=
thermal_zone_get_trip
(
tz
,
i
,
&
trip
);
if
(
ret
)
return
-
EINVAL
;
if
(
type
==
THERMAL_TRIP_HOT
)
{
ret
=
tz
->
ops
->
get_trip_temp
(
tz
,
i
,
temp
);
if
(
!
ret
)
*
trip
=
i
;
return
ret
;
if
(
trip
.
type
==
THERMAL_TRIP_HOT
)
{
*
trip_id
=
i
;
return
0
;
}
}
...
...
@@ -747,7 +742,7 @@ static int tegra_soctherm_set_hwtrips(struct device *dev,
/* Get thermtrips. If missing, try to get critical trips. */
temperature
=
tsensor_group_thermtrip_get
(
ts
,
sg
->
id
);
if
(
min_low_temp
==
temperature
)
if
(
t
z
->
ops
->
get_crit_temp
(
tz
,
&
temperature
))
if
(
t
hermal_zone_
get_crit_temp
(
tz
,
&
temperature
))
temperature
=
max_high_temp
;
ret
=
thermtrip_program
(
dev
,
sg
,
temperature
);
...
...
drivers/thermal/tegra/tegra30-tsensor.c
View file @
a5c926ac
...
...
@@ -316,18 +316,17 @@ static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd,
*
hot_trip
=
85000
;
*
crit_trip
=
90000
;
for
(
i
=
0
;
i
<
tzd
->
num_trips
;
i
++
)
{
enum
thermal_trip_type
type
;
int
trip_temp
;
for
(
i
=
0
;
i
<
thermal_zone_get_num_trips
(
tzd
);
i
++
)
{
tzd
->
ops
->
get_trip_temp
(
tzd
,
i
,
&
trip_temp
);
tzd
->
ops
->
get_trip_type
(
tzd
,
i
,
&
type
);
struct
thermal_trip
trip
;
if
(
type
==
THERMAL_TRIP_HOT
)
*
hot_trip
=
trip_temp
;
thermal_zone_get_trip
(
tzd
,
i
,
&
trip
);
if
(
type
==
THERMAL_TRIP_CRITICAL
)
*
crit_trip
=
trip_temp
;
if
(
trip
.
type
==
THERMAL_TRIP_HOT
)
*
hot_trip
=
trip
.
temperature
;
if
(
trip
.
type
==
THERMAL_TRIP_CRITICAL
)
*
crit_trip
=
trip
.
temperature
;
}
/* clamp hardware trips to the calibration limits */
...
...
drivers/thermal/thermal_acpi.c
0 → 100644
View file @
a5c926ac
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2023 Linaro Limited
* Copyright 2023 Intel Corporation
*
* Library routines for populating a generic thermal trip point structure
* with data obtained by evaluating a specific object in the ACPI Namespace.
*/
#include <linux/acpi.h>
#include <linux/units.h>
#include "thermal_core.h"
/*
* Minimum temperature for full military grade is 218°K (-55°C) and
* max temperature is 448°K (175°C). We can consider those values as
* the boundaries for the [trips] temperature returned by the
* firmware. Any values out of these boundaries may be considered
* bogus and we can assume the firmware has no data to provide.
*/
#define TEMP_MIN_DECIK 2180
#define TEMP_MAX_DECIK 4480
static
int
thermal_acpi_trip_init
(
struct
acpi_device
*
adev
,
enum
thermal_trip_type
type
,
int
id
,
struct
thermal_trip
*
trip
)
{
unsigned
long
long
temp
;
acpi_status
status
;
char
obj_name
[
5
];
switch
(
type
)
{
case
THERMAL_TRIP_ACTIVE
:
if
(
id
<
0
||
id
>
9
)
return
-
EINVAL
;
obj_name
[
1
]
=
'A'
;
obj_name
[
2
]
=
'C'
;
obj_name
[
3
]
=
'0'
+
id
;
break
;
case
THERMAL_TRIP_PASSIVE
:
obj_name
[
1
]
=
'P'
;
obj_name
[
2
]
=
'S'
;
obj_name
[
3
]
=
'V'
;
break
;
case
THERMAL_TRIP_HOT
:
obj_name
[
1
]
=
'H'
;
obj_name
[
2
]
=
'O'
;
obj_name
[
3
]
=
'T'
;
break
;
case
THERMAL_TRIP_CRITICAL
:
obj_name
[
1
]
=
'C'
;
obj_name
[
2
]
=
'R'
;
obj_name
[
3
]
=
'T'
;
break
;
}
obj_name
[
0
]
=
'_'
;
obj_name
[
4
]
=
'\0'
;
status
=
acpi_evaluate_integer
(
adev
->
handle
,
obj_name
,
NULL
,
&
temp
);
if
(
ACPI_FAILURE
(
status
))
{
acpi_handle_debug
(
adev
->
handle
,
"%s evaluation failed
\n
"
,
obj_name
);
return
-
ENODATA
;
}
if
(
temp
<
TEMP_MIN_DECIK
||
temp
>=
TEMP_MAX_DECIK
)
{
acpi_handle_debug
(
adev
->
handle
,
"%s result %llu out of range
\n
"
,
obj_name
,
temp
);
return
-
ENODATA
;
}
trip
->
temperature
=
deci_kelvin_to_millicelsius
(
temp
);
trip
->
hysteresis
=
0
;
trip
->
type
=
type
;
return
0
;
}
/**
* thermal_acpi_trip_active - Get the specified active trip point
* @adev: Thermal zone ACPI device object to get the description from.
* @id: Active cooling level (0 - 9).
* @trip: Trip point structure to be populated on success.
*
* Evaluate the _ACx object for the thermal zone represented by @adev to obtain
* the temperature of the active cooling trip point corresponding to the active
* cooling level given by @id and initialize @trip as an active trip point using
* that temperature value.
*
* Return 0 on success or a negative error value on failure.
*/
int
thermal_acpi_trip_active
(
struct
acpi_device
*
adev
,
int
id
,
struct
thermal_trip
*
trip
)
{
return
thermal_acpi_trip_init
(
adev
,
THERMAL_TRIP_ACTIVE
,
id
,
trip
);
}
EXPORT_SYMBOL_GPL
(
thermal_acpi_trip_active
);
/**
* thermal_acpi_trip_passive - Get the passive trip point
* @adev: Thermal zone ACPI device object to get the description from.
* @trip: Trip point structure to be populated on success.
*
* Evaluate the _PSV object for the thermal zone represented by @adev to obtain
* the temperature of the passive cooling trip point and initialize @trip as a
* passive trip point using that temperature value.
*
* Return 0 on success or -ENODATA on failure.
*/
int
thermal_acpi_trip_passive
(
struct
acpi_device
*
adev
,
struct
thermal_trip
*
trip
)
{
return
thermal_acpi_trip_init
(
adev
,
THERMAL_TRIP_PASSIVE
,
INT_MAX
,
trip
);
}
EXPORT_SYMBOL_GPL
(
thermal_acpi_trip_passive
);
/**
* thermal_acpi_trip_hot - Get the near critical trip point
* @adev: the ACPI device to get the description from.
* @trip: a &struct thermal_trip to be filled if the function succeed.
*
* Evaluate the _HOT object for the thermal zone represented by @adev to obtain
* the temperature of the trip point at which the system is expected to be put
* into the S4 sleep state and initialize @trip as a hot trip point using that
* temperature value.
*
* Return 0 on success or -ENODATA on failure.
*/
int
thermal_acpi_trip_hot
(
struct
acpi_device
*
adev
,
struct
thermal_trip
*
trip
)
{
return
thermal_acpi_trip_init
(
adev
,
THERMAL_TRIP_HOT
,
INT_MAX
,
trip
);
}
EXPORT_SYMBOL_GPL
(
thermal_acpi_trip_hot
);
/**
* thermal_acpi_trip_critical - Get the critical trip point
* @adev: the ACPI device to get the description from.
* @trip: a &struct thermal_trip to be filled if the function succeed.
*
* Evaluate the _CRT object for the thermal zone represented by @adev to obtain
* the temperature of the critical cooling trip point and initialize @trip as a
* critical trip point using that temperature value.
*
* Return 0 on success or -ENODATA on failure.
*/
int
thermal_acpi_trip_critical
(
struct
acpi_device
*
adev
,
struct
thermal_trip
*
trip
)
{
return
thermal_acpi_trip_init
(
adev
,
THERMAL_TRIP_CRITICAL
,
INT_MAX
,
trip
);
}
EXPORT_SYMBOL_GPL
(
thermal_acpi_trip_critical
);
drivers/thermal/thermal_core.c
View file @
a5c926ac
...
...
@@ -344,35 +344,31 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
tz
->
ops
->
critical
(
tz
);
}
static
void
handle_thermal_trip
(
struct
thermal_zone_device
*
tz
,
int
trip
)
static
void
handle_thermal_trip
(
struct
thermal_zone_device
*
tz
,
int
trip
_id
)
{
enum
thermal_trip_type
type
;
int
trip_temp
,
hyst
=
0
;
struct
thermal_trip
trip
;
/* Ignore disabled trip points */
if
(
test_bit
(
trip
,
&
tz
->
trips_disabled
))
if
(
test_bit
(
trip
_id
,
&
tz
->
trips_disabled
))
return
;
tz
->
ops
->
get_trip_temp
(
tz
,
trip
,
&
trip_temp
);
tz
->
ops
->
get_trip_type
(
tz
,
trip
,
&
type
);
if
(
tz
->
ops
->
get_trip_hyst
)
tz
->
ops
->
get_trip_hyst
(
tz
,
trip
,
&
hyst
);
__thermal_zone_get_trip
(
tz
,
trip_id
,
&
trip
);
if
(
tz
->
last_temperature
!=
THERMAL_TEMP_INVALID
)
{
if
(
tz
->
last_temperature
<
trip
_temp
&&
tz
->
temperature
>=
trip
_temp
)
thermal_notify_tz_trip_up
(
tz
->
id
,
trip
,
if
(
tz
->
last_temperature
<
trip
.
temperature
&&
tz
->
temperature
>=
trip
.
temperature
)
thermal_notify_tz_trip_up
(
tz
->
id
,
trip
_id
,
tz
->
temperature
);
if
(
tz
->
last_temperature
>=
trip
_temp
&&
tz
->
temperature
<
(
trip
_temp
-
hyst
))
thermal_notify_tz_trip_down
(
tz
->
id
,
trip
,
if
(
tz
->
last_temperature
>=
trip
.
temperature
&&
tz
->
temperature
<
(
trip
.
temperature
-
trip
.
hysteresis
))
thermal_notify_tz_trip_down
(
tz
->
id
,
trip
_id
,
tz
->
temperature
);
}
if
(
t
ype
==
THERMAL_TRIP_CRITICAL
||
type
==
THERMAL_TRIP_HOT
)
handle_critical_trips
(
tz
,
trip
,
trip_temp
,
type
);
if
(
t
rip
.
type
==
THERMAL_TRIP_CRITICAL
||
trip
.
type
==
THERMAL_TRIP_HOT
)
handle_critical_trips
(
tz
,
trip
_id
,
trip
.
temperature
,
trip
.
type
);
else
handle_non_critical_trips
(
tz
,
trip
);
handle_non_critical_trips
(
tz
,
trip
_id
);
}
static
void
update_temperature
(
struct
thermal_zone_device
*
tz
)
...
...
@@ -1166,6 +1162,119 @@ static void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms
*
delay_jiffies
=
round_jiffies
(
*
delay_jiffies
);
}
int
thermal_zone_get_num_trips
(
struct
thermal_zone_device
*
tz
)
{
return
tz
->
num_trips
;
}
EXPORT_SYMBOL_GPL
(
thermal_zone_get_num_trips
);
int
thermal_zone_get_crit_temp
(
struct
thermal_zone_device
*
tz
,
int
*
temp
)
{
int
i
,
ret
=
-
EINVAL
;
if
(
tz
->
ops
->
get_crit_temp
)
return
tz
->
ops
->
get_crit_temp
(
tz
,
temp
);
if
(
!
tz
->
trips
)
return
-
EINVAL
;
mutex_lock
(
&
tz
->
lock
);
for
(
i
=
0
;
i
<
tz
->
num_trips
;
i
++
)
{
if
(
tz
->
trips
[
i
].
type
==
THERMAL_TRIP_CRITICAL
)
{
*
temp
=
tz
->
trips
[
i
].
temperature
;
ret
=
0
;
break
;
}
}
mutex_unlock
(
&
tz
->
lock
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
thermal_zone_get_crit_temp
);
int
__thermal_zone_get_trip
(
struct
thermal_zone_device
*
tz
,
int
trip_id
,
struct
thermal_trip
*
trip
)
{
int
ret
;
if
(
!
tz
||
trip_id
<
0
||
trip_id
>=
tz
->
num_trips
||
!
trip
)
return
-
EINVAL
;
if
(
tz
->
trips
)
{
*
trip
=
tz
->
trips
[
trip_id
];
return
0
;
}
if
(
tz
->
ops
->
get_trip_hyst
)
{
ret
=
tz
->
ops
->
get_trip_hyst
(
tz
,
trip_id
,
&
trip
->
hysteresis
);
if
(
ret
)
return
ret
;
}
else
{
trip
->
hysteresis
=
0
;
}
ret
=
tz
->
ops
->
get_trip_temp
(
tz
,
trip_id
,
&
trip
->
temperature
);
if
(
ret
)
return
ret
;
return
tz
->
ops
->
get_trip_type
(
tz
,
trip_id
,
&
trip
->
type
);
}
EXPORT_SYMBOL_GPL
(
__thermal_zone_get_trip
);
int
thermal_zone_get_trip
(
struct
thermal_zone_device
*
tz
,
int
trip_id
,
struct
thermal_trip
*
trip
)
{
int
ret
;
mutex_lock
(
&
tz
->
lock
);
ret
=
__thermal_zone_get_trip
(
tz
,
trip_id
,
trip
);
mutex_unlock
(
&
tz
->
lock
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
thermal_zone_get_trip
);
int
thermal_zone_set_trip
(
struct
thermal_zone_device
*
tz
,
int
trip_id
,
const
struct
thermal_trip
*
trip
)
{
struct
thermal_trip
t
;
int
ret
;
if
(
!
tz
->
ops
->
set_trip_temp
&&
!
tz
->
ops
->
set_trip_hyst
&&
!
tz
->
trips
)
return
-
EINVAL
;
ret
=
__thermal_zone_get_trip
(
tz
,
trip_id
,
&
t
);
if
(
ret
)
return
ret
;
if
(
t
.
type
!=
trip
->
type
)
return
-
EINVAL
;
if
(
t
.
temperature
!=
trip
->
temperature
&&
tz
->
ops
->
set_trip_temp
)
{
ret
=
tz
->
ops
->
set_trip_temp
(
tz
,
trip_id
,
trip
->
temperature
);
if
(
ret
)
return
ret
;
}
if
(
t
.
hysteresis
!=
trip
->
hysteresis
&&
tz
->
ops
->
set_trip_hyst
)
{
ret
=
tz
->
ops
->
set_trip_hyst
(
tz
,
trip_id
,
trip
->
hysteresis
);
if
(
ret
)
return
ret
;
}
if
(
tz
->
trips
&&
(
t
.
temperature
!=
trip
->
temperature
||
t
.
hysteresis
!=
trip
->
hysteresis
))
tz
->
trips
[
trip_id
]
=
*
trip
;
thermal_notify_tz_trip_change
(
tz
->
id
,
trip_id
,
trip
->
type
,
trip
->
temperature
,
trip
->
hysteresis
);
__thermal_zone_device_update
(
tz
,
THERMAL_TRIP_CHANGED
);
return
0
;
}
/**
* thermal_zone_device_register_with_trips() - register a new thermal zone device
* @type: the thermal zone device type
...
...
@@ -1198,8 +1307,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
int
polling_delay
)
{
struct
thermal_zone_device
*
tz
;
enum
thermal_trip_type
trip_type
;
int
trip_temp
;
int
id
;
int
result
;
int
count
;
...
...
@@ -1239,7 +1346,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
return
ERR_PTR
(
-
EINVAL
);
}
if
(
num_trips
>
0
&&
(
!
ops
->
get_trip_type
||
!
ops
->
get_trip_temp
))
if
(
num_trips
>
0
&&
(
!
ops
->
get_trip_type
||
!
ops
->
get_trip_temp
)
&&
!
trips
)
return
ERR_PTR
(
-
EINVAL
);
tz
=
kzalloc
(
sizeof
(
*
tz
),
GFP_KERNEL
);
...
...
@@ -1290,9 +1397,10 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
goto
release_device
;
for
(
count
=
0
;
count
<
num_trips
;
count
++
)
{
if
(
tz
->
ops
->
get_trip_type
(
tz
,
count
,
&
trip_type
)
||
tz
->
ops
->
get_trip_temp
(
tz
,
count
,
&
trip_temp
)
||
!
trip_temp
)
struct
thermal_trip
trip
;
result
=
thermal_zone_get_trip
(
tz
,
count
,
&
trip
);
if
(
result
)
set_bit
(
count
,
&
tz
->
trips_disabled
);
}
...
...
drivers/thermal/thermal_core.h
View file @
a5c926ac
...
...
@@ -114,6 +114,8 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
/* Helpers */
void
__thermal_zone_set_trips
(
struct
thermal_zone_device
*
tz
);
int
__thermal_zone_get_trip
(
struct
thermal_zone_device
*
tz
,
int
trip_id
,
struct
thermal_trip
*
trip
);
int
__thermal_zone_get_temp
(
struct
thermal_zone_device
*
tz
,
int
*
temp
);
/* sysfs I/F */
...
...
@@ -137,28 +139,6 @@ thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
#endif
/* CONFIG_THERMAL_STATISTICS */
/* device tree support */
#ifdef CONFIG_THERMAL_OF
int
of_thermal_get_ntrips
(
struct
thermal_zone_device
*
);
bool
of_thermal_is_trip_valid
(
struct
thermal_zone_device
*
,
int
);
const
struct
thermal_trip
*
of_thermal_get_trip_points
(
struct
thermal_zone_device
*
);
#else
static
inline
int
of_thermal_get_ntrips
(
struct
thermal_zone_device
*
tz
)
{
return
0
;
}
static
inline
bool
of_thermal_is_trip_valid
(
struct
thermal_zone_device
*
tz
,
int
trip
)
{
return
false
;
}
static
inline
const
struct
thermal_trip
*
of_thermal_get_trip_points
(
struct
thermal_zone_device
*
tz
)
{
return
NULL
;
}
#endif
int
thermal_zone_device_is_enabled
(
struct
thermal_zone_device
*
tz
);
#endif
/* __THERMAL_CORE_H__ */
drivers/thermal/thermal_helpers.c
View file @
a5c926ac
...
...
@@ -83,7 +83,7 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
int
ret
=
-
EINVAL
;
int
count
;
int
crit_temp
=
INT_MAX
;
enum
thermal_trip_type
type
;
struct
thermal_trip
trip
;
lockdep_assert_held
(
&
tz
->
lock
);
...
...
@@ -91,10 +91,9 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
if
(
IS_ENABLED
(
CONFIG_THERMAL_EMULATION
)
&&
tz
->
emul_temperature
)
{
for
(
count
=
0
;
count
<
tz
->
num_trips
;
count
++
)
{
ret
=
tz
->
ops
->
get_trip_type
(
tz
,
count
,
&
type
);
if
(
!
ret
&&
type
==
THERMAL_TRIP_CRITICAL
)
{
ret
=
tz
->
ops
->
get_trip_temp
(
tz
,
count
,
&
crit_temp
);
ret
=
__thermal_zone_get_trip
(
tz
,
count
,
&
trip
);
if
(
!
ret
&&
trip
.
type
==
THERMAL_TRIP_CRITICAL
)
{
crit_temp
=
trip
.
temperature
;
break
;
}
}
...
...
@@ -164,29 +163,30 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
*/
void
__thermal_zone_set_trips
(
struct
thermal_zone_device
*
tz
)
{
int
low
=
-
INT_MAX
;
int
high
=
INT_MAX
;
int
trip_temp
,
hysteresis
;
struct
thermal_trip
trip
;
int
low
=
-
INT_MAX
,
high
=
INT_MAX
;
int
i
,
ret
;
lockdep_assert_held
(
&
tz
->
lock
);
if
(
!
tz
->
ops
->
set_trips
||
!
tz
->
ops
->
get_trip_hyst
)
if
(
!
tz
->
ops
->
set_trips
)
return
;
for
(
i
=
0
;
i
<
tz
->
num_trips
;
i
++
)
{
int
trip_low
;
tz
->
ops
->
get_trip_temp
(
tz
,
i
,
&
trip_temp
);
tz
->
ops
->
get_trip_hyst
(
tz
,
i
,
&
hysteresis
);
ret
=
__thermal_zone_get_trip
(
tz
,
i
,
&
trip
);
if
(
ret
)
return
;
trip_low
=
trip
_temp
-
hysteresis
;
trip_low
=
trip
.
temperature
-
trip
.
hysteresis
;
if
(
trip_low
<
tz
->
temperature
&&
trip_low
>
low
)
low
=
trip_low
;
if
(
trip_temp
>
tz
->
temperature
&&
trip_temp
<
high
)
high
=
trip_temp
;
if
(
trip
.
temperature
>
tz
->
temperature
&&
trip
.
temperature
<
high
)
high
=
trip
.
temperature
;
}
/* No need to change trip points */
...
...
drivers/thermal/thermal_netlink.c
View file @
a5c926ac
...
...
@@ -452,7 +452,8 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
struct
sk_buff
*
msg
=
p
->
msg
;
struct
thermal_zone_device
*
tz
;
struct
nlattr
*
start_trip
;
int
i
,
id
;
struct
thermal_trip
trip
;
int
ret
,
i
,
id
;
if
(
!
p
->
attrs
[
THERMAL_GENL_ATTR_TZ_ID
])
return
-
EINVAL
;
...
...
@@ -471,18 +472,14 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
for
(
i
=
0
;
i
<
tz
->
num_trips
;
i
++
)
{
enum
thermal_trip_type
type
;
int
temp
,
hyst
=
0
;
tz
->
ops
->
get_trip_type
(
tz
,
i
,
&
type
);
tz
->
ops
->
get_trip_temp
(
tz
,
i
,
&
temp
);
if
(
tz
->
ops
->
get_trip_hyst
)
tz
->
ops
->
get_trip_hyst
(
tz
,
i
,
&
hyst
);
ret
=
__thermal_zone_get_trip
(
tz
,
i
,
&
trip
);
if
(
ret
)
goto
out_cancel_nest
;
if
(
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_ID
,
i
)
||
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_TYPE
,
type
)
||
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_TEMP
,
t
emp
)
||
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_HYST
,
hyst
))
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_TYPE
,
t
rip
.
t
ype
)
||
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_TEMP
,
t
rip
.
temperature
)
||
nla_put_u32
(
msg
,
THERMAL_GENL_ATTR_TZ_TRIP_HYST
,
trip
.
hysteresis
))
goto
out_cancel_nest
;
}
...
...
drivers/thermal/thermal_of.c
View file @
a5c926ac
...
...
@@ -19,117 +19,6 @@
#include "thermal_core.h"
/**
* of_thermal_get_ntrips - function to export number of available trip
* points.
* @tz: pointer to a thermal zone
*
* This function is a globally visible wrapper to get number of trip points
* stored in the local struct __thermal_zone
*
* Return: number of available trip points, -ENODEV when data not available
*/
int
of_thermal_get_ntrips
(
struct
thermal_zone_device
*
tz
)
{
return
tz
->
num_trips
;
}
EXPORT_SYMBOL_GPL
(
of_thermal_get_ntrips
);
/**
* of_thermal_is_trip_valid - function to check if trip point is valid
*
* @tz: pointer to a thermal zone
* @trip: trip point to evaluate
*
* This function is responsible for checking if passed trip point is valid
*
* Return: true if trip point is valid, false otherwise
*/
bool
of_thermal_is_trip_valid
(
struct
thermal_zone_device
*
tz
,
int
trip
)
{
if
(
trip
>=
tz
->
num_trips
||
trip
<
0
)
return
false
;
return
true
;
}
EXPORT_SYMBOL_GPL
(
of_thermal_is_trip_valid
);
/**
* of_thermal_get_trip_points - function to get access to a globally exported
* trip points
*
* @tz: pointer to a thermal zone
*
* This function provides a pointer to trip points table
*
* Return: pointer to trip points table, NULL otherwise
*/
const
struct
thermal_trip
*
of_thermal_get_trip_points
(
struct
thermal_zone_device
*
tz
)
{
return
tz
->
trips
;
}
EXPORT_SYMBOL_GPL
(
of_thermal_get_trip_points
);
static
int
of_thermal_get_trip_type
(
struct
thermal_zone_device
*
tz
,
int
trip
,
enum
thermal_trip_type
*
type
)
{
if
(
trip
>=
tz
->
num_trips
||
trip
<
0
)
return
-
EDOM
;
*
type
=
tz
->
trips
[
trip
].
type
;
return
0
;
}
static
int
of_thermal_get_trip_temp
(
struct
thermal_zone_device
*
tz
,
int
trip
,
int
*
temp
)
{
if
(
trip
>=
tz
->
num_trips
||
trip
<
0
)
return
-
EDOM
;
*
temp
=
tz
->
trips
[
trip
].
temperature
;
return
0
;
}
static
int
of_thermal_get_trip_hyst
(
struct
thermal_zone_device
*
tz
,
int
trip
,
int
*
hyst
)
{
if
(
trip
>=
tz
->
num_trips
||
trip
<
0
)
return
-
EDOM
;
*
hyst
=
tz
->
trips
[
trip
].
hysteresis
;
return
0
;
}
static
int
of_thermal_set_trip_hyst
(
struct
thermal_zone_device
*
tz
,
int
trip
,
int
hyst
)
{
if
(
trip
>=
tz
->
num_trips
||
trip
<
0
)
return
-
EDOM
;
/* thermal framework should take care of data->mask & (1 << trip) */
tz
->
trips
[
trip
].
hysteresis
=
hyst
;
return
0
;
}
static
int
of_thermal_get_crit_temp
(
struct
thermal_zone_device
*
tz
,
int
*
temp
)
{
int
i
;
for
(
i
=
0
;
i
<
tz
->
num_trips
;
i
++
)
if
(
tz
->
trips
[
i
].
type
==
THERMAL_TRIP_CRITICAL
)
{
*
temp
=
tz
->
trips
[
i
].
temperature
;
return
0
;
}
return
-
EINVAL
;
}
/*** functions parsing device tree nodes ***/
static
int
of_find_trip_id
(
struct
device_node
*
np
,
struct
device_node
*
trip
)
...
...
@@ -628,11 +517,6 @@ struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor,
goto
out_kfree_trips
;
}
of_ops
->
get_trip_type
=
of_ops
->
get_trip_type
?
:
of_thermal_get_trip_type
;
of_ops
->
get_trip_temp
=
of_ops
->
get_trip_temp
?
:
of_thermal_get_trip_temp
;
of_ops
->
get_trip_hyst
=
of_ops
->
get_trip_hyst
?
:
of_thermal_get_trip_hyst
;
of_ops
->
set_trip_hyst
=
of_ops
->
set_trip_hyst
?
:
of_thermal_set_trip_hyst
;
of_ops
->
get_crit_temp
=
of_ops
->
get_crit_temp
?
:
of_thermal_get_crit_temp
;
of_ops
->
bind
=
thermal_of_bind
;
of_ops
->
unbind
=
thermal_of_unbind
;
...
...
drivers/thermal/thermal_sysfs.c
View file @
a5c926ac
...
...
@@ -83,27 +83,25 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
char
*
buf
)
{
struct
thermal_zone_device
*
tz
=
to_thermal_zone
(
dev
);
enum
thermal_trip_type
type
;
int
trip
,
result
;
struct
thermal_trip
trip
;
int
trip
_id
,
result
;
if
(
!
tz
->
ops
->
get_trip_type
)
return
-
EPERM
;
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_type"
,
&
trip
)
!=
1
)
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_type"
,
&
trip_id
)
!=
1
)
return
-
EINVAL
;
mutex_lock
(
&
tz
->
lock
);
if
(
device_is_registered
(
dev
))
result
=
tz
->
ops
->
get_trip_type
(
tz
,
trip
,
&
type
);
result
=
__thermal_zone_get_trip
(
tz
,
trip_id
,
&
trip
);
else
result
=
-
ENODEV
;
mutex_unlock
(
&
tz
->
lock
);
if
(
result
)
return
result
;
switch
(
type
)
{
switch
(
t
rip
.
t
ype
)
{
case
THERMAL_TRIP_CRITICAL
:
return
sprintf
(
buf
,
"critical
\n
"
);
case
THERMAL_TRIP_HOT
:
...
...
@@ -122,17 +120,10 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
const
char
*
buf
,
size_t
count
)
{
struct
thermal_zone_device
*
tz
=
to_thermal_zone
(
dev
);
int
trip
,
ret
;
int
temperature
,
hyst
=
0
;
enum
thermal_trip_type
type
;
if
(
!
tz
->
ops
->
set_trip_temp
&&
!
tz
->
trips
)
return
-
EPERM
;
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_temp"
,
&
trip
)
!=
1
)
return
-
EINVAL
;
struct
thermal_trip
trip
;
int
trip_id
,
ret
;
if
(
kstrtoint
(
buf
,
10
,
&
temperature
)
)
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_temp"
,
&
trip_id
)
!=
1
)
return
-
EINVAL
;
mutex_lock
(
&
tz
->
lock
);
...
...
@@ -142,36 +133,19 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
goto
unlock
;
}
if
(
tz
->
ops
->
set_trip_temp
)
{
ret
=
tz
->
ops
->
set_trip_temp
(
tz
,
trip
,
temperature
);
if
(
ret
)
goto
unlock
;
}
if
(
tz
->
trips
)
tz
->
trips
[
trip
].
temperature
=
temperature
;
if
(
tz
->
ops
->
get_trip_hyst
)
{
ret
=
tz
->
ops
->
get_trip_hyst
(
tz
,
trip
,
&
hyst
);
if
(
ret
)
goto
unlock
;
}
ret
=
tz
->
ops
->
get_trip_type
(
tz
,
trip
,
&
type
);
ret
=
__thermal_zone_get_trip
(
tz
,
trip_id
,
&
trip
);
if
(
ret
)
goto
unlock
;
thermal_notify_tz_trip_change
(
tz
->
id
,
trip
,
type
,
temperature
,
hyst
);
__thermal_zone_device_update
(
tz
,
THERMAL_EVENT_UNSPECIFIED
)
;
ret
=
kstrtoint
(
buf
,
10
,
&
trip
.
temperature
);
if
(
ret
)
goto
unlock
;
ret
=
thermal_zone_set_trip
(
tz
,
trip_id
,
&
trip
);
unlock:
mutex_unlock
(
&
tz
->
lock
);
if
(
ret
)
return
ret
;
return
count
;
return
ret
?
ret
:
count
;
}
static
ssize_t
...
...
@@ -179,19 +153,16 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
char
*
buf
)
{
struct
thermal_zone_device
*
tz
=
to_thermal_zone
(
dev
);
int
trip
,
ret
;
int
temperature
;
if
(
!
tz
->
ops
->
get_trip_temp
)
return
-
EPERM
;
struct
thermal_trip
trip
;
int
trip_id
,
ret
;
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_temp"
,
&
trip
)
!=
1
)
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_temp"
,
&
trip
_id
)
!=
1
)
return
-
EINVAL
;
mutex_lock
(
&
tz
->
lock
);
if
(
device_is_registered
(
dev
))
ret
=
tz
->
ops
->
get_trip_temp
(
tz
,
trip
,
&
temperature
);
ret
=
__thermal_zone_get_trip
(
tz
,
trip_id
,
&
trip
);
else
ret
=
-
ENODEV
;
...
...
@@ -200,7 +171,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
if
(
ret
)
return
ret
;
return
sprintf
(
buf
,
"%d
\n
"
,
temperature
);
return
sprintf
(
buf
,
"%d
\n
"
,
t
rip
.
t
emperature
);
}
static
ssize_t
...
...
@@ -208,16 +179,13 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
const
char
*
buf
,
size_t
count
)
{
struct
thermal_zone_device
*
tz
=
to_thermal_zone
(
dev
);
int
trip
,
ret
;
int
temperature
;
if
(
!
tz
->
ops
->
set_trip_hyst
)
return
-
EPERM
;
struct
thermal_trip
trip
;
int
trip_id
,
ret
;
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_hyst"
,
&
trip
)
!=
1
)
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_hyst"
,
&
trip
_id
)
!=
1
)
return
-
EINVAL
;
if
(
kstrtoint
(
buf
,
10
,
&
t
emperature
))
if
(
kstrtoint
(
buf
,
10
,
&
t
rip
.
hysteresis
))
return
-
EINVAL
;
mutex_lock
(
&
tz
->
lock
);
...
...
@@ -227,16 +195,11 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
goto
unlock
;
}
/*
* We are not doing any check on the 'temperature' value
* here. The driver implementing 'set_trip_hyst' has to
* take care of this.
*/
ret
=
tz
->
ops
->
set_trip_hyst
(
tz
,
trip
,
temperature
);
if
(
!
ret
)
__thermal_zone_set_trips
(
tz
);
ret
=
__thermal_zone_get_trip
(
tz
,
trip_id
,
&
trip
);
if
(
ret
)
goto
unlock
;
ret
=
thermal_zone_set_trip
(
tz
,
trip_id
,
&
trip
);
unlock:
mutex_unlock
(
&
tz
->
lock
);
...
...
@@ -248,25 +211,22 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
char
*
buf
)
{
struct
thermal_zone_device
*
tz
=
to_thermal_zone
(
dev
);
int
trip
,
ret
;
int
temperature
;
if
(
!
tz
->
ops
->
get_trip_hyst
)
return
-
EPERM
;
struct
thermal_trip
trip
;
int
trip_id
,
ret
;
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_hyst"
,
&
trip
)
!=
1
)
if
(
sscanf
(
attr
->
attr
.
name
,
"trip_point_%d_hyst"
,
&
trip
_id
)
!=
1
)
return
-
EINVAL
;
mutex_lock
(
&
tz
->
lock
);
if
(
device_is_registered
(
dev
))
ret
=
tz
->
ops
->
get_trip_hyst
(
tz
,
trip
,
&
temperature
);
ret
=
__thermal_zone_get_trip
(
tz
,
trip_id
,
&
trip
);
else
ret
=
-
ENODEV
;
mutex_unlock
(
&
tz
->
lock
);
return
ret
?
ret
:
sprintf
(
buf
,
"%d
\n
"
,
t
emperature
);
return
ret
?
ret
:
sprintf
(
buf
,
"%d
\n
"
,
t
rip
.
hysteresis
);
}
static
ssize_t
...
...
@@ -491,23 +451,20 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
return
-
ENOMEM
;
}
if
(
tz
->
ops
->
get_trip_hyst
)
{
tz
->
trip_hyst_attrs
=
kcalloc
(
tz
->
num_trips
,
sizeof
(
*
tz
->
trip_hyst_attrs
),
GFP_KERNEL
);
if
(
!
tz
->
trip_hyst_attrs
)
{
kfree
(
tz
->
trip_type_attrs
);
kfree
(
tz
->
trip_temp_attrs
);
return
-
ENOMEM
;
}
tz
->
trip_hyst_attrs
=
kcalloc
(
tz
->
num_trips
,
sizeof
(
*
tz
->
trip_hyst_attrs
),
GFP_KERNEL
);
if
(
!
tz
->
trip_hyst_attrs
)
{
kfree
(
tz
->
trip_type_attrs
);
kfree
(
tz
->
trip_temp_attrs
);
return
-
ENOMEM
;
}
attrs
=
kcalloc
(
tz
->
num_trips
*
3
+
1
,
sizeof
(
*
attrs
),
GFP_KERNEL
);
if
(
!
attrs
)
{
kfree
(
tz
->
trip_type_attrs
);
kfree
(
tz
->
trip_temp_attrs
);
if
(
tz
->
ops
->
get_trip_hyst
)
kfree
(
tz
->
trip_hyst_attrs
);
kfree
(
tz
->
trip_hyst_attrs
);
return
-
ENOMEM
;
}
...
...
@@ -540,9 +497,6 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
}
attrs
[
indx
+
tz
->
num_trips
]
=
&
tz
->
trip_temp_attrs
[
indx
].
attr
.
attr
;
/* create Optional trip hyst attribute */
if
(
!
tz
->
ops
->
get_trip_hyst
)
continue
;
snprintf
(
tz
->
trip_hyst_attrs
[
indx
].
name
,
THERMAL_NAME_LENGTH
,
"trip_point_%d_hyst"
,
indx
);
...
...
@@ -579,8 +533,7 @@ static void destroy_trip_attrs(struct thermal_zone_device *tz)
kfree
(
tz
->
trip_type_attrs
);
kfree
(
tz
->
trip_temp_attrs
);
if
(
tz
->
ops
->
get_trip_hyst
)
kfree
(
tz
->
trip_hyst_attrs
);
kfree
(
tz
->
trip_hyst_attrs
);
kfree
(
tz
->
trips_attribute_group
.
attrs
);
}
...
...
drivers/thermal/ti-soc-thermal/ti-thermal.h
View file @
a5c926ac
...
...
@@ -38,21 +38,6 @@
/* Update rates */
#define FAST_TEMP_MONITORING_RATE 250
/* helper macros */
/**
* ti_thermal_get_trip_value - returns trip temperature based on index
* @i: trip index
*/
#define ti_thermal_get_trip_value(i) \
(OMAP_TRIP_HOT + ((i) * OMAP_TRIP_STEP))
/**
* ti_thermal_is_valid_trip - check for trip index
* @i: trip index
*/
#define ti_thermal_is_valid_trip(trip) \
((trip) >= 0 && (trip) < OMAP_TRIP_NUMBER)
#ifdef CONFIG_TI_THERMAL
int
ti_thermal_expose_sensor
(
struct
ti_bandgap
*
bgp
,
int
id
,
char
*
domain
);
int
ti_thermal_remove_sensor
(
struct
ti_bandgap
*
bgp
,
int
id
);
...
...
drivers/thermal/uniphier_thermal.c
View file @
a5c926ac
...
...
@@ -248,8 +248,7 @@ static int uniphier_tm_probe(struct platform_device *pdev)
struct
regmap
*
regmap
;
struct
device_node
*
parent
;
struct
uniphier_tm_dev
*
tdev
;
const
struct
thermal_trip
*
trips
;
int
i
,
ret
,
irq
,
ntrips
,
crit_temp
=
INT_MAX
;
int
i
,
ret
,
irq
,
crit_temp
=
INT_MAX
;
tdev
=
devm_kzalloc
(
dev
,
sizeof
(
*
tdev
),
GFP_KERNEL
);
if
(
!
tdev
)
...
...
@@ -296,20 +295,18 @@ static int uniphier_tm_probe(struct platform_device *pdev)
return
PTR_ERR
(
tdev
->
tz_dev
);
}
/* get trip points */
trips
=
of_thermal_get_trip_points
(
tdev
->
tz_dev
);
ntrips
=
of_thermal_get_ntrips
(
tdev
->
tz_dev
);
if
(
ntrips
>
ALERT_CH_NUM
)
{
dev_err
(
dev
,
"thermal zone has too many trips
\n
"
);
return
-
E2BIG
;
}
/* set alert temperatures */
for
(
i
=
0
;
i
<
ntrips
;
i
++
)
{
if
(
trips
[
i
].
type
==
THERMAL_TRIP_CRITICAL
&&
trips
[
i
].
temperature
<
crit_temp
)
crit_temp
=
trips
[
i
].
temperature
;
uniphier_tm_set_alert
(
tdev
,
i
,
trips
[
i
].
temperature
);
for
(
i
=
0
;
i
<
thermal_zone_get_num_trips
(
tdev
->
tz_dev
);
i
++
)
{
struct
thermal_trip
trip
;
ret
=
thermal_zone_get_trip
(
tdev
->
tz_dev
,
i
,
&
trip
);
if
(
ret
)
return
ret
;
if
(
trip
.
type
==
THERMAL_TRIP_CRITICAL
&&
trip
.
temperature
<
crit_temp
)
crit_temp
=
trip
.
temperature
;
uniphier_tm_set_alert
(
tdev
,
i
,
trip
.
temperature
);
tdev
->
alert_en
[
i
]
=
true
;
}
if
(
crit_temp
>
CRITICAL_TEMP_LIMIT
)
{
...
...
include/linux/intel_tcc.h
0 → 100644
View file @
a5c926ac
/* SPDX-License-Identifier: GPL-2.0 */
/*
* header for Intel TCC (thermal control circuitry) library
*
* Copyright (C) 2022 Intel Corporation.
*/
#ifndef __INTEL_TCC_H__
#define __INTEL_TCC_H__
#include <linux/types.h>
int
intel_tcc_get_tjmax
(
int
cpu
);
int
intel_tcc_get_offset
(
int
cpu
);
int
intel_tcc_set_offset
(
int
cpu
,
int
offset
);
int
intel_tcc_get_temp
(
int
cpu
,
bool
pkg
);
#endif
/* __INTEL_TCC_H__ */
include/linux/thermal.h
View file @
a5c926ac
...
...
@@ -334,6 +334,26 @@ static inline void devm_thermal_of_zone_unregister(struct device *dev,
}
#endif
int
__thermal_zone_get_trip
(
struct
thermal_zone_device
*
tz
,
int
trip_id
,
struct
thermal_trip
*
trip
);
int
thermal_zone_get_trip
(
struct
thermal_zone_device
*
tz
,
int
trip_id
,
struct
thermal_trip
*
trip
);
int
thermal_zone_set_trip
(
struct
thermal_zone_device
*
tz
,
int
trip_id
,
const
struct
thermal_trip
*
trip
);
int
thermal_zone_get_num_trips
(
struct
thermal_zone_device
*
tz
);
int
thermal_zone_get_crit_temp
(
struct
thermal_zone_device
*
tz
,
int
*
temp
);
#ifdef CONFIG_THERMAL_ACPI
int
thermal_acpi_trip_active
(
struct
acpi_device
*
adev
,
int
id
,
struct
thermal_trip
*
trip
);
int
thermal_acpi_trip_passive
(
struct
acpi_device
*
adev
,
struct
thermal_trip
*
trip
);
int
thermal_acpi_trip_hot
(
struct
acpi_device
*
adev
,
struct
thermal_trip
*
trip
);
int
thermal_acpi_trip_critical
(
struct
acpi_device
*
adev
,
struct
thermal_trip
*
trip
);
#endif
#ifdef CONFIG_THERMAL
struct
thermal_zone_device
*
thermal_zone_device_register
(
const
char
*
,
int
,
int
,
void
*
,
struct
thermal_zone_device_ops
*
,
...
...
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