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
d13cb03a
Commit
d13cb03a
authored
Apr 15, 2013
by
Zhang Rui
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'thermal' of
git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
into next
Conflicts: drivers/thermal/cpu_cooling.c
parents
2fd1db88
bbf7fc88
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
578 additions
and
261 deletions
+578
-261
Documentation/devicetree/bindings/thermal/armada-thermal.txt
Documentation/devicetree/bindings/thermal/armada-thermal.txt
+22
-0
Documentation/thermal/exynos_thermal_emulation
Documentation/thermal/exynos_thermal_emulation
+4
-4
Documentation/thermal/sysfs-api.txt
Documentation/thermal/sysfs-api.txt
+4
-8
drivers/thermal/Kconfig
drivers/thermal/Kconfig
+13
-10
drivers/thermal/Makefile
drivers/thermal/Makefile
+6
-4
drivers/thermal/armada_thermal.c
drivers/thermal/armada_thermal.c
+232
-0
drivers/thermal/cpu_cooling.c
drivers/thermal/cpu_cooling.c
+104
-50
drivers/thermal/exynos_thermal.c
drivers/thermal/exynos_thermal.c
+65
-119
drivers/thermal/fair_share.c
drivers/thermal/fair_share.c
+2
-13
drivers/thermal/rcar_thermal.c
drivers/thermal/rcar_thermal.c
+27
-7
drivers/thermal/step_wise.c
drivers/thermal/step_wise.c
+10
-16
drivers/thermal/thermal_core.c
drivers/thermal/thermal_core.c
+48
-11
drivers/thermal/thermal_core.h
drivers/thermal/thermal_core.h
+27
-0
drivers/thermal/user_space.c
drivers/thermal/user_space.c
+2
-13
include/linux/cpu_cooling.h
include/linux/cpu_cooling.h
+8
-1
include/linux/thermal.h
include/linux/thermal.h
+4
-5
No files found.
Documentation/devicetree/bindings/thermal/armada-thermal.txt
0 → 100644
View file @
d13cb03a
* Marvell Armada 370/XP thermal management
Required properties:
- compatible: Should be set to one of the following:
marvell,armada370-thermal
marvell,armadaxp-thermal
- reg: Device's register space.
Two entries are expected, see the examples below.
The first one is required for the sensor register;
the second one is required for the control register
to be used for sensor initialization (a.k.a. calibration).
Example:
thermal@d0018300 {
compatible = "marvell,armada370-thermal";
reg = <0xd0018300 0x4
0xd0018304 0x4>;
status = "okay";
};
Documentation/thermal/exynos_thermal_emulation
View file @
d13cb03a
...
...
@@ -13,11 +13,11 @@ Thermal emulation mode supports software debug for TMU's operation. User can set
manually with software code and TMU will read current temperature from user value not from
sensor's value.
Enabling CONFIG_
EXYNOS_THERMAL_EMUL option will make this support in
available.
When it's enabled, sysfs node will be created
under
/sys/
bus/platform/devices/'exynos device name'/ with name of 'emulation'
.
Enabling CONFIG_
THERMAL_EMULATION option will make this support
available.
When it's enabled, sysfs node will be created
as
/sys/
devices/virtual/thermal/thermal_zone'zone id'/emul_temp
.
The sysfs node, 'emul
ation
', will contain value 0 for the initial state. When you input any
The sysfs node, 'emul
_node
', will contain value 0 for the initial state. When you input any
temperature you want to update to sysfs node, it automatically enable emulation mode and
current temperature will be changed into it.
(Exynos also supports user changable delay time which would be used to delay of
...
...
Documentation/thermal/sysfs-api.txt
View file @
d13cb03a
...
...
@@ -265,6 +265,10 @@ emul_temp
Unit: millidegree Celsius
WO, Optional
WARNING: Be careful while enabling this option on production systems,
because userland can easily disable the thermal policy by simply
flooding this sysfs node with low temperature values.
*****************************
* Cooling device attributes *
*****************************
...
...
@@ -375,11 +379,3 @@ platform data is provided, this uses the step_wise throttling policy.
This function serves as an arbitrator to set the state of a cooling
device. It sets the cooling device to the deepest cooling state if
possible.
5.5:thermal_register_governor:
This function lets the various thermal governors to register themselves
with the Thermal framework. At run time, depending on a zone's platform
data, a particular governor is used for throttling.
5.6:thermal_unregister_governor:
This function unregisters a governor from the thermal framework.
drivers/thermal/Kconfig
View file @
d13cb03a
...
...
@@ -67,7 +67,7 @@ config THERMAL_GOV_USER_SPACE
Enable this to let the user space manage the platform thermals.
config CPU_THERMAL
tristate
"generic cpu cooling support"
bool
"generic cpu cooling support"
depends on CPU_FREQ
select CPU_FREQ_TABLE
help
...
...
@@ -86,6 +86,10 @@ config THERMAL_EMULATION
user can manually input temperature and test the different trip
threshold behaviour for simulation purpose.
WARNING: Be careful while enabling this option on production systems,
because userland can easily disable the thermal policy by simply
flooding this sysfs node with low temperature values.
config SPEAR_THERMAL
bool "SPEAr thermal sensor driver"
depends on PLAT_SPEAR
...
...
@@ -117,15 +121,6 @@ config EXYNOS_THERMAL
If you say yes here you get support for TMU (Thermal Management
Unit) on SAMSUNG EXYNOS series of SoC.
config EXYNOS_THERMAL_EMUL
bool "EXYNOS TMU emulation mode support"
depends on EXYNOS_THERMAL
help
Exynos 4412 and 4414 and 5 series has emulation mode on TMU.
Enable this option will be make sysfs node in exynos thermal platform
device directory to support emulation mode. With emulation mode sysfs
node, you can manually input temperature to TMU for simulation purpose.
config DOVE_THERMAL
tristate "Temperature sensor on Marvell Dove SoCs"
depends on ARCH_DOVE
...
...
@@ -144,6 +139,14 @@ config DB8500_THERMAL
created. Cooling devices can be bound to the trip points to cool this
thermal zone if trip points reached.
config ARMADA_THERMAL
tristate "Armada 370/XP thermal management"
depends on ARCH_MVEBU
depends on OF
help
Enable this option if you want to have support for thermal management
controller present in Armada 370 and Armada XP SoC.
config DB8500_CPUFREQ_COOLING
tristate "DB8500 cpufreq cooling"
depends on ARCH_U8500
...
...
drivers/thermal/Makefile
View file @
d13cb03a
...
...
@@ -3,14 +3,15 @@
#
obj-$(CONFIG_THERMAL)
+=
thermal_sys.o
thermal_sys-y
+=
thermal_core.o
# governors
obj
-$(CONFIG_THERMAL_GOV_FAIR_SHARE)
+=
fair_share.o
obj
-$(CONFIG_THERMAL_GOV_STEP_WISE)
+=
step_wise.o
obj
-$(CONFIG_THERMAL_GOV_USER_SPACE)
+=
user_space.o
thermal_sys
-$(CONFIG_THERMAL_GOV_FAIR_SHARE)
+=
fair_share.o
thermal_sys
-$(CONFIG_THERMAL_GOV_STEP_WISE)
+=
step_wise.o
thermal_sys
-$(CONFIG_THERMAL_GOV_USER_SPACE)
+=
user_space.o
# cpufreq cooling
obj
-$(CONFIG_CPU_THERMAL)
+=
cpu_cooling.o
thermal_sys
-$(CONFIG_CPU_THERMAL)
+=
cpu_cooling.o
# platform thermal drivers
obj-$(CONFIG_SPEAR_THERMAL)
+=
spear_thermal.o
...
...
@@ -19,6 +20,7 @@ obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o
obj-$(CONFIG_EXYNOS_THERMAL)
+=
exynos_thermal.o
obj-$(CONFIG_DOVE_THERMAL)
+=
dove_thermal.o
obj-$(CONFIG_DB8500_THERMAL)
+=
db8500_thermal.o
obj-$(CONFIG_ARMADA_THERMAL)
+=
armada_thermal.o
obj-$(CONFIG_DB8500_CPUFREQ_COOLING)
+=
db8500_cpufreq_cooling.o
obj-$(CONFIG_INTEL_POWERCLAMP)
+=
intel_powerclamp.o
drivers/thermal/armada_thermal.c
0 → 100644
View file @
d13cb03a
/*
* Marvell Armada 370/XP thermal sensor driver
*
* Copyright (C) 2013 Marvell
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/device.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/thermal.h>
#define THERMAL_VALID_OFFSET 9
#define THERMAL_VALID_MASK 0x1
#define THERMAL_TEMP_OFFSET 10
#define THERMAL_TEMP_MASK 0x1ff
/* Thermal Manager Control and Status Register */
#define PMU_TDC0_SW_RST_MASK (0x1 << 1)
#define PMU_TM_DISABLE_OFFS 0
#define PMU_TM_DISABLE_MASK (0x1 << PMU_TM_DISABLE_OFFS)
#define PMU_TDC0_REF_CAL_CNT_OFFS 11
#define PMU_TDC0_REF_CAL_CNT_MASK (0x1ff << PMU_TDC0_REF_CAL_CNT_OFFS)
#define PMU_TDC0_OTF_CAL_MASK (0x1 << 30)
#define PMU_TDC0_START_CAL_MASK (0x1 << 25)
struct
armada_thermal_ops
;
/* Marvell EBU Thermal Sensor Dev Structure */
struct
armada_thermal_priv
{
void
__iomem
*
sensor
;
void
__iomem
*
control
;
struct
armada_thermal_ops
*
ops
;
};
struct
armada_thermal_ops
{
/* Initialize the sensor */
void
(
*
init_sensor
)(
struct
armada_thermal_priv
*
);
/* Test for a valid sensor value (optional) */
bool
(
*
is_valid
)(
struct
armada_thermal_priv
*
);
};
static
void
armadaxp_init_sensor
(
struct
armada_thermal_priv
*
priv
)
{
unsigned
long
reg
;
reg
=
readl_relaxed
(
priv
->
control
);
reg
|=
PMU_TDC0_OTF_CAL_MASK
;
writel
(
reg
,
priv
->
control
);
/* Reference calibration value */
reg
&=
~
PMU_TDC0_REF_CAL_CNT_MASK
;
reg
|=
(
0xf1
<<
PMU_TDC0_REF_CAL_CNT_OFFS
);
writel
(
reg
,
priv
->
control
);
/* Reset the sensor */
reg
=
readl_relaxed
(
priv
->
control
);
writel
((
reg
|
PMU_TDC0_SW_RST_MASK
),
priv
->
control
);
writel
(
reg
,
priv
->
control
);
/* Enable the sensor */
reg
=
readl_relaxed
(
priv
->
sensor
);
reg
&=
~
PMU_TM_DISABLE_MASK
;
writel
(
reg
,
priv
->
sensor
);
}
static
void
armada370_init_sensor
(
struct
armada_thermal_priv
*
priv
)
{
unsigned
long
reg
;
reg
=
readl_relaxed
(
priv
->
control
);
reg
|=
PMU_TDC0_OTF_CAL_MASK
;
writel
(
reg
,
priv
->
control
);
/* Reference calibration value */
reg
&=
~
PMU_TDC0_REF_CAL_CNT_MASK
;
reg
|=
(
0xf1
<<
PMU_TDC0_REF_CAL_CNT_OFFS
);
writel
(
reg
,
priv
->
control
);
reg
&=
~
PMU_TDC0_START_CAL_MASK
;
writel
(
reg
,
priv
->
control
);
mdelay
(
10
);
}
static
bool
armada_is_valid
(
struct
armada_thermal_priv
*
priv
)
{
unsigned
long
reg
=
readl_relaxed
(
priv
->
sensor
);
return
(
reg
>>
THERMAL_VALID_OFFSET
)
&
THERMAL_VALID_MASK
;
}
static
int
armada_get_temp
(
struct
thermal_zone_device
*
thermal
,
unsigned
long
*
temp
)
{
struct
armada_thermal_priv
*
priv
=
thermal
->
devdata
;
unsigned
long
reg
;
/* Valid check */
if
(
priv
->
ops
->
is_valid
&&
!
priv
->
ops
->
is_valid
(
priv
))
{
dev_err
(
&
thermal
->
device
,
"Temperature sensor reading not valid
\n
"
);
return
-
EIO
;
}
reg
=
readl_relaxed
(
priv
->
sensor
);
reg
=
(
reg
>>
THERMAL_TEMP_OFFSET
)
&
THERMAL_TEMP_MASK
;
*
temp
=
(
3153000000UL
-
(
10000000UL
*
reg
))
/
13825
;
return
0
;
}
static
struct
thermal_zone_device_ops
ops
=
{
.
get_temp
=
armada_get_temp
,
};
static
const
struct
armada_thermal_ops
armadaxp_ops
=
{
.
init_sensor
=
armadaxp_init_sensor
,
};
static
const
struct
armada_thermal_ops
armada370_ops
=
{
.
is_valid
=
armada_is_valid
,
.
init_sensor
=
armada370_init_sensor
,
};
static
const
struct
of_device_id
armada_thermal_id_table
[]
=
{
{
.
compatible
=
"marvell,armadaxp-thermal"
,
.
data
=
&
armadaxp_ops
,
},
{
.
compatible
=
"marvell,armada370-thermal"
,
.
data
=
&
armada370_ops
,
},
{
/* sentinel */
},
};
MODULE_DEVICE_TABLE
(
of
,
armada_thermal_id_table
);
static
int
armada_thermal_probe
(
struct
platform_device
*
pdev
)
{
struct
thermal_zone_device
*
thermal
;
const
struct
of_device_id
*
match
;
struct
armada_thermal_priv
*
priv
;
struct
resource
*
res
;
match
=
of_match_device
(
armada_thermal_id_table
,
&
pdev
->
dev
);
if
(
!
match
)
return
-
ENODEV
;
priv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
priv
),
GFP_KERNEL
);
if
(
!
priv
)
return
-
ENOMEM
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
res
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to get platform resource
\n
"
);
return
-
ENODEV
;
}
priv
->
sensor
=
devm_ioremap_resource
(
&
pdev
->
dev
,
res
);
if
(
IS_ERR
(
priv
->
sensor
))
return
PTR_ERR
(
priv
->
sensor
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
1
);
if
(
!
res
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to get platform resource
\n
"
);
return
-
ENODEV
;
}
priv
->
control
=
devm_ioremap_resource
(
&
pdev
->
dev
,
res
);
if
(
IS_ERR
(
priv
->
control
))
return
PTR_ERR
(
priv
->
control
);
priv
->
ops
=
(
struct
armada_thermal_ops
*
)
match
->
data
;
priv
->
ops
->
init_sensor
(
priv
);
thermal
=
thermal_zone_device_register
(
"armada_thermal"
,
0
,
0
,
priv
,
&
ops
,
NULL
,
0
,
0
);
if
(
IS_ERR
(
thermal
))
{
dev_err
(
&
pdev
->
dev
,
"Failed to register thermal zone device
\n
"
);
return
PTR_ERR
(
thermal
);
}
platform_set_drvdata
(
pdev
,
thermal
);
return
0
;
}
static
int
armada_thermal_exit
(
struct
platform_device
*
pdev
)
{
struct
thermal_zone_device
*
armada_thermal
=
platform_get_drvdata
(
pdev
);
thermal_zone_device_unregister
(
armada_thermal
);
platform_set_drvdata
(
pdev
,
NULL
);
return
0
;
}
static
struct
platform_driver
armada_thermal_driver
=
{
.
probe
=
armada_thermal_probe
,
.
remove
=
armada_thermal_exit
,
.
driver
=
{
.
name
=
"armada_thermal"
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
of_match_ptr
(
armada_thermal_id_table
),
},
};
module_platform_driver
(
armada_thermal_driver
);
MODULE_AUTHOR
(
"Ezequiel Garcia <ezequiel.garcia@free-electrons.com>"
);
MODULE_DESCRIPTION
(
"Armada 370/XP thermal driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/thermal/cpu_cooling.c
View file @
d13cb03a
...
...
@@ -108,54 +108,120 @@ static int is_cpufreq_valid(int cpu)
return
!
cpufreq_get_policy
(
&
policy
,
cpu
);
}
/**
* get_cpu_frequency - get the absolute value of frequency from level.
* @cpu: cpu for which frequency is fetched.
* @level: level of frequency, equals cooling state of cpu cooling device
* e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc
*/
static
unsigned
int
get_cpu_frequency
(
unsigned
int
cpu
,
unsigned
long
level
)
enum
cpufreq_cooling_property
{
GET_LEVEL
,
GET_FREQ
,
GET_MAXL
,
};
/*
* this is the common function to
* 1. get maximum cpu cooling states
* 2. translate frequency to cooling state
* 3. translate cooling state to frequency
* Note that the code may be not in good shape
* but it is written in this way in order to:
* a) reduce duplicate code as most of the code can be shared.
* b) make sure the logic is consistent when translating between
* cooling states and frequencies.
*/
static
int
get_property
(
unsigned
int
cpu
,
unsigned
long
input
,
unsigned
int
*
output
,
enum
cpufreq_cooling_property
property
)
{
int
ret
=
0
,
i
=
0
;
unsigned
long
level_index
;
bool
descend
=
false
;
int
i
,
j
;
unsigned
long
max_level
=
0
,
level
;
unsigned
int
freq
=
CPUFREQ_ENTRY_INVALID
;
int
descend
=
-
1
;
struct
cpufreq_frequency_table
*
table
=
cpufreq_frequency_get_table
(
cpu
);
if
(
!
output
)
return
-
EINVAL
;
if
(
!
table
)
return
ret
;
return
-
EINVAL
;
while
(
table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
)
{
for
(
i
=
0
;
table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
;
i
++
)
{
/* ignore invalid entries */
if
(
table
[
i
].
frequency
==
CPUFREQ_ENTRY_INVALID
)
continue
;
/*check if table in ascending or descending order*/
if
((
table
[
i
+
1
].
frequency
!=
CPUFREQ_TABLE_END
)
&&
(
table
[
i
+
1
].
frequency
<
table
[
i
].
frequency
)
&&
!
descend
)
{
descend
=
true
;
}
/* ignore duplicate entry */
if
(
freq
==
table
[
i
].
frequency
)
continue
;
/* get the frequency order */
if
(
freq
!=
CPUFREQ_ENTRY_INVALID
&&
descend
!=
-
1
)
descend
=
!!
(
freq
>
table
[
i
].
frequency
);
/*return if level matched and table in descending order*/
if
(
descend
&&
i
==
level
)
return
table
[
i
].
frequency
;
i
++
;
freq
=
table
[
i
].
frequency
;
max_level
++
;
}
i
--
;
if
(
level
>
i
||
descend
)
return
ret
;
level_index
=
i
-
level
;
/* get max level */
if
(
property
==
GET_MAXL
)
{
*
output
=
(
unsigned
int
)
max_level
;
return
0
;
}
if
(
property
==
GET_FREQ
)
level
=
descend
?
input
:
(
max_level
-
input
-
1
);
/*Scan the table in reverse order and match the level*/
while
(
i
>=
0
)
{
for
(
i
=
0
,
j
=
0
;
table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
;
i
++
)
{
/* ignore invalid entry */
if
(
table
[
i
].
frequency
==
CPUFREQ_ENTRY_INVALID
)
continue
;
/*return if level matched*/
if
(
i
==
level_index
)
return
table
[
i
].
frequency
;
i
--
;
/* ignore duplicate entry */
if
(
freq
==
table
[
i
].
frequency
)
continue
;
/* now we have a valid frequency entry */
freq
=
table
[
i
].
frequency
;
if
(
property
==
GET_LEVEL
&&
(
unsigned
int
)
input
==
freq
)
{
/* get level by frequency */
*
output
=
descend
?
j
:
(
max_level
-
j
-
1
);
return
0
;
}
if
(
property
==
GET_FREQ
&&
level
==
j
)
{
/* get frequency by level */
*
output
=
freq
;
return
0
;
}
j
++
;
}
return
ret
;
return
-
EINVAL
;
}
unsigned
long
cpufreq_cooling_get_level
(
unsigned
int
cpu
,
unsigned
int
freq
)
{
unsigned
int
val
;
if
(
get_property
(
cpu
,
(
unsigned
long
)
freq
,
&
val
,
GET_LEVEL
))
return
THERMAL_CSTATE_INVALID
;
return
(
unsigned
long
)
val
;
}
EXPORT_SYMBOL
(
cpufreq_cooling_get_level
);
/**
* get_cpu_frequency - get the absolute value of frequency from level.
* @cpu: cpu for which frequency is fetched.
* @level: level of frequency, equals cooling state of cpu cooling device
* e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc
*/
static
unsigned
int
get_cpu_frequency
(
unsigned
int
cpu
,
unsigned
long
level
)
{
int
ret
=
0
;
unsigned
int
freq
;
ret
=
get_property
(
cpu
,
level
,
&
freq
,
GET_FREQ
);
if
(
ret
)
return
0
;
return
freq
;
}
/**
...
...
@@ -237,29 +303,17 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
struct
cpufreq_cooling_device
*
cpufreq_device
=
cdev
->
devdata
;
struct
cpumask
*
mask
=
&
cpufreq_device
->
allowed_cpus
;
unsigned
int
cpu
;
struct
cpufreq_frequency_table
*
table
;
unsigned
long
count
=
0
;
int
i
=
0
;
int
ret
;
cpu
=
cpumask_any
(
mask
);
table
=
cpufreq_frequency_get_table
(
cpu
);
if
(
!
table
)
{
*
state
=
0
;
return
0
;
}
for
(
i
=
0
;
(
table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
);
i
++
)
{
if
(
table
[
i
].
frequency
==
CPUFREQ_ENTRY_INVALID
)
continue
;
count
++
;
}
ret
=
get_property
(
cpu
,
0
,
(
unsigned
int
*
)
&
count
,
GET_MAXL
);
if
(
count
>
0
)
{
*
state
=
--
count
;
return
0
;
}
if
(
count
>
0
)
*
state
=
count
;
return
-
EINVAL
;
return
ret
;
}
/**
...
...
drivers/thermal/exynos_thermal.c
View file @
d13cb03a
...
...
@@ -39,8 +39,6 @@
#include <linux/cpu_cooling.h>
#include <linux/of.h>
#include <plat/cpu.h>
/* Exynos generic registers */
#define EXYNOS_TMU_REG_TRIMINFO 0x0
#define EXYNOS_TMU_REG_CONTROL 0x20
...
...
@@ -100,13 +98,13 @@
#define IDLE_INTERVAL 10000
#define MCELSIUS 1000
#ifdef CONFIG_
EXYNOS_THERMAL_EMUL
#ifdef CONFIG_
THERMAL_EMULATION
#define EXYNOS_EMUL_TIME 0x57F0
#define EXYNOS_EMUL_TIME_SHIFT 16
#define EXYNOS_EMUL_DATA_SHIFT 8
#define EXYNOS_EMUL_DATA_MASK 0xFF
#define EXYNOS_EMUL_ENABLE 0x1
#endif
/* CONFIG_
EXYNOS_THERMAL_EMUL
*/
#endif
/* CONFIG_
THERMAL_EMULATION
*/
/* CPU Zone information */
#define PANIC_ZONE 4
...
...
@@ -145,6 +143,7 @@ struct thermal_cooling_conf {
struct
thermal_sensor_conf
{
char
name
[
SENSOR_NAME_LEN
];
int
(
*
read_temperature
)(
void
*
data
);
int
(
*
write_emul_temp
)(
void
*
drv_data
,
unsigned
long
temp
);
struct
thermal_trip_point_conf
trip_data
;
struct
thermal_cooling_conf
cooling_data
;
void
*
private_data
;
...
...
@@ -242,26 +241,6 @@ static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
return
ret
;
}
static
int
exynos_get_frequency_level
(
unsigned
int
cpu
,
unsigned
int
freq
)
{
int
i
=
0
,
ret
=
-
EINVAL
;
struct
cpufreq_frequency_table
*
table
=
NULL
;
#ifdef CONFIG_CPU_FREQ
table
=
cpufreq_frequency_get_table
(
cpu
);
#endif
if
(
!
table
)
return
ret
;
while
(
table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
)
{
if
(
table
[
i
].
frequency
==
CPUFREQ_ENTRY_INVALID
)
continue
;
if
(
table
[
i
].
frequency
==
freq
)
return
i
;
i
++
;
}
return
ret
;
}
/* Bind callback functions for thermal zone */
static
int
exynos_bind
(
struct
thermal_zone_device
*
thermal
,
struct
thermal_cooling_device
*
cdev
)
...
...
@@ -288,8 +267,8 @@ static int exynos_bind(struct thermal_zone_device *thermal,
/* Bind the thermal zone to the cpufreq cooling device */
for
(
i
=
0
;
i
<
tab_size
;
i
++
)
{
clip_data
=
(
struct
freq_clip_table
*
)
&
(
tab_ptr
[
i
]);
level
=
exynos_get_frequency
_level
(
0
,
clip_data
->
freq_clip_max
);
if
(
level
<
0
)
level
=
cpufreq_cooling_get
_level
(
0
,
clip_data
->
freq_clip_max
);
if
(
level
==
THERMAL_CSTATE_INVALID
)
return
0
;
switch
(
GET_ZONE
(
i
))
{
case
MONITOR_ZONE
:
...
...
@@ -369,6 +348,23 @@ static int exynos_get_temp(struct thermal_zone_device *thermal,
return
0
;
}
/* Get temperature callback functions for thermal zone */
static
int
exynos_set_emul_temp
(
struct
thermal_zone_device
*
thermal
,
unsigned
long
temp
)
{
void
*
data
;
int
ret
=
-
EINVAL
;
if
(
!
th_zone
->
sensor_conf
)
{
pr_info
(
"Temperature sensor not initialised
\n
"
);
return
-
EINVAL
;
}
data
=
th_zone
->
sensor_conf
->
private_data
;
if
(
th_zone
->
sensor_conf
->
write_emul_temp
)
ret
=
th_zone
->
sensor_conf
->
write_emul_temp
(
data
,
temp
);
return
ret
;
}
/* Get the temperature trend */
static
int
exynos_get_trend
(
struct
thermal_zone_device
*
thermal
,
int
trip
,
enum
thermal_trend
*
trend
)
...
...
@@ -392,6 +388,7 @@ static struct thermal_zone_device_ops const exynos_dev_ops = {
.
bind
=
exynos_bind
,
.
unbind
=
exynos_unbind
,
.
get_temp
=
exynos_get_temp
,
.
set_emul_temp
=
exynos_set_emul_temp
,
.
get_trend
=
exynos_get_trend
,
.
get_mode
=
exynos_get_mode
,
.
set_mode
=
exynos_set_mode
,
...
...
@@ -714,6 +711,47 @@ static int exynos_tmu_read(struct exynos_tmu_data *data)
return
temp
;
}
#ifdef CONFIG_THERMAL_EMULATION
static
int
exynos_tmu_set_emulation
(
void
*
drv_data
,
unsigned
long
temp
)
{
struct
exynos_tmu_data
*
data
=
drv_data
;
unsigned
int
reg
;
int
ret
=
-
EINVAL
;
if
(
data
->
soc
==
SOC_ARCH_EXYNOS4210
)
goto
out
;
if
(
temp
&&
temp
<
MCELSIUS
)
goto
out
;
mutex_lock
(
&
data
->
lock
);
clk_enable
(
data
->
clk
);
reg
=
readl
(
data
->
base
+
EXYNOS_EMUL_CON
);
if
(
temp
)
{
temp
/=
MCELSIUS
;
reg
=
(
EXYNOS_EMUL_TIME
<<
EXYNOS_EMUL_TIME_SHIFT
)
|
(
temp_to_code
(
data
,
temp
)
<<
EXYNOS_EMUL_DATA_SHIFT
)
|
EXYNOS_EMUL_ENABLE
;
}
else
{
reg
&=
~
EXYNOS_EMUL_ENABLE
;
}
writel
(
reg
,
data
->
base
+
EXYNOS_EMUL_CON
);
clk_disable
(
data
->
clk
);
mutex_unlock
(
&
data
->
lock
);
return
0
;
out:
return
ret
;
}
#else
static
int
exynos_tmu_set_emulation
(
void
*
drv_data
,
unsigned
long
temp
)
{
return
-
EINVAL
;
}
#endif
/*CONFIG_THERMAL_EMULATION*/
static
void
exynos_tmu_work
(
struct
work_struct
*
work
)
{
struct
exynos_tmu_data
*
data
=
container_of
(
work
,
...
...
@@ -747,6 +785,7 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id)
static
struct
thermal_sensor_conf
exynos_sensor_conf
=
{
.
name
=
"exynos-therm"
,
.
read_temperature
=
(
int
(
*
)(
void
*
))
exynos_tmu_read
,
.
write_emul_temp
=
exynos_tmu_set_emulation
,
};
#if defined(CONFIG_CPU_EXYNOS4210)
...
...
@@ -853,93 +892,6 @@ static inline struct exynos_tmu_platform_data *exynos_get_driver_data(
platform_get_device_id
(
pdev
)
->
driver_data
;
}
#ifdef CONFIG_EXYNOS_THERMAL_EMUL
static
ssize_t
exynos_tmu_emulation_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
platform_device
*
pdev
=
container_of
(
dev
,
struct
platform_device
,
dev
);
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
unsigned
int
reg
;
u8
temp_code
;
int
temp
=
0
;
if
(
data
->
soc
==
SOC_ARCH_EXYNOS4210
)
goto
out
;
mutex_lock
(
&
data
->
lock
);
clk_enable
(
data
->
clk
);
reg
=
readl
(
data
->
base
+
EXYNOS_EMUL_CON
);
clk_disable
(
data
->
clk
);
mutex_unlock
(
&
data
->
lock
);
if
(
reg
&
EXYNOS_EMUL_ENABLE
)
{
reg
>>=
EXYNOS_EMUL_DATA_SHIFT
;
temp_code
=
reg
&
EXYNOS_EMUL_DATA_MASK
;
temp
=
code_to_temp
(
data
,
temp_code
);
}
out:
return
sprintf
(
buf
,
"%d
\n
"
,
temp
*
MCELSIUS
);
}
static
ssize_t
exynos_tmu_emulation_store
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
platform_device
*
pdev
=
container_of
(
dev
,
struct
platform_device
,
dev
);
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
unsigned
int
reg
;
int
temp
;
if
(
data
->
soc
==
SOC_ARCH_EXYNOS4210
)
goto
out
;
if
(
!
sscanf
(
buf
,
"%d
\n
"
,
&
temp
)
||
temp
<
0
)
return
-
EINVAL
;
mutex_lock
(
&
data
->
lock
);
clk_enable
(
data
->
clk
);
reg
=
readl
(
data
->
base
+
EXYNOS_EMUL_CON
);
if
(
temp
)
{
/* Both CELSIUS and MCELSIUS type are available for input */
if
(
temp
>
MCELSIUS
)
temp
/=
MCELSIUS
;
reg
=
(
EXYNOS_EMUL_TIME
<<
EXYNOS_EMUL_TIME_SHIFT
)
|
(
temp_to_code
(
data
,
(
temp
/
MCELSIUS
))
<<
EXYNOS_EMUL_DATA_SHIFT
)
|
EXYNOS_EMUL_ENABLE
;
}
else
{
reg
&=
~
EXYNOS_EMUL_ENABLE
;
}
writel
(
reg
,
data
->
base
+
EXYNOS_EMUL_CON
);
clk_disable
(
data
->
clk
);
mutex_unlock
(
&
data
->
lock
);
out:
return
count
;
}
static
DEVICE_ATTR
(
emulation
,
0644
,
exynos_tmu_emulation_show
,
exynos_tmu_emulation_store
);
static
int
create_emulation_sysfs
(
struct
device
*
dev
)
{
return
device_create_file
(
dev
,
&
dev_attr_emulation
);
}
static
void
remove_emulation_sysfs
(
struct
device
*
dev
)
{
device_remove_file
(
dev
,
&
dev_attr_emulation
);
}
#else
static
inline
int
create_emulation_sysfs
(
struct
device
*
dev
)
{
return
0
;
}
static
inline
void
remove_emulation_sysfs
(
struct
device
*
dev
)
{}
#endif
static
int
exynos_tmu_probe
(
struct
platform_device
*
pdev
)
{
struct
exynos_tmu_data
*
data
;
...
...
@@ -1039,10 +991,6 @@ static int exynos_tmu_probe(struct platform_device *pdev)
goto
err_clk
;
}
ret
=
create_emulation_sysfs
(
&
pdev
->
dev
);
if
(
ret
)
dev_err
(
&
pdev
->
dev
,
"Failed to create emulation mode sysfs node
\n
"
);
return
0
;
err_clk:
platform_set_drvdata
(
pdev
,
NULL
);
...
...
@@ -1054,8 +1002,6 @@ static int exynos_tmu_remove(struct platform_device *pdev)
{
struct
exynos_tmu_data
*
data
=
platform_get_drvdata
(
pdev
);
remove_emulation_sysfs
(
&
pdev
->
dev
);
exynos_tmu_control
(
pdev
,
false
);
exynos_unregister_thermal
();
...
...
drivers/thermal/fair_share.c
View file @
d13cb03a
...
...
@@ -22,9 +22,6 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/thermal.h>
#include "thermal_core.h"
...
...
@@ -111,23 +108,15 @@ static int fair_share_throttle(struct thermal_zone_device *tz, int trip)
static
struct
thermal_governor
thermal_gov_fair_share
=
{
.
name
=
"fair_share"
,
.
throttle
=
fair_share_throttle
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
thermal_gov_fair_share_init
(
void
)
int
thermal_gov_fair_share_register
(
void
)
{
return
thermal_register_governor
(
&
thermal_gov_fair_share
);
}
static
void
__exit
thermal_gov_fair_share_exit
(
void
)
void
thermal_gov_fair_share_unregister
(
void
)
{
thermal_unregister_governor
(
&
thermal_gov_fair_share
);
}
/* This should load after thermal framework */
fs_initcall
(
thermal_gov_fair_share_init
);
module_exit
(
thermal_gov_fair_share_exit
);
MODULE_AUTHOR
(
"Durgadoss R"
);
MODULE_DESCRIPTION
(
"A simple weight based thermal throttling governor"
);
MODULE_LICENSE
(
"GPL"
);
drivers/thermal/rcar_thermal.c
View file @
d13cb03a
...
...
@@ -24,6 +24,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
...
...
@@ -377,6 +378,9 @@ static int rcar_thermal_probe(struct platform_device *pdev)
spin_lock_init
(
&
common
->
lock
);
common
->
dev
=
dev
;
pm_runtime_enable
(
dev
);
pm_runtime_get_sync
(
dev
);
irq
=
platform_get_resource
(
pdev
,
IORESOURCE_IRQ
,
0
);
if
(
irq
)
{
int
ret
;
...
...
@@ -419,12 +423,15 @@ static int rcar_thermal_probe(struct platform_device *pdev)
priv
=
devm_kzalloc
(
dev
,
sizeof
(
*
priv
),
GFP_KERNEL
);
if
(
!
priv
)
{
dev_err
(
dev
,
"Could not allocate priv
\n
"
);
return
-
ENOMEM
;
ret
=
-
ENOMEM
;
goto
error_unregister
;
}
priv
->
base
=
devm_ioremap_resource
(
dev
,
res
);
if
(
IS_ERR
(
priv
->
base
))
return
PTR_ERR
(
priv
->
base
);
if
(
IS_ERR
(
priv
->
base
))
{
ret
=
PTR_ERR
(
priv
->
base
);
goto
error_unregister
;
}
priv
->
common
=
common
;
priv
->
id
=
i
;
...
...
@@ -443,10 +450,10 @@ static int rcar_thermal_probe(struct platform_device *pdev)
goto
error_unregister
;
}
list_move_tail
(
&
priv
->
list
,
&
common
->
head
);
if
(
rcar_has_irq_support
(
priv
))
rcar_thermal_irq_enable
(
priv
);
list_move_tail
(
&
priv
->
list
,
&
common
->
head
);
}
platform_set_drvdata
(
pdev
,
common
);
...
...
@@ -456,8 +463,14 @@ static int rcar_thermal_probe(struct platform_device *pdev)
return
0
;
error_unregister:
rcar_thermal_for_each_priv
(
priv
,
common
)
rcar_thermal_for_each_priv
(
priv
,
common
)
{
thermal_zone_device_unregister
(
priv
->
zone
);
if
(
rcar_has_irq_support
(
priv
))
rcar_thermal_irq_disable
(
priv
);
}
pm_runtime_put_sync
(
dev
);
pm_runtime_disable
(
dev
);
return
ret
;
}
...
...
@@ -465,13 +478,20 @@ static int rcar_thermal_probe(struct platform_device *pdev)
static
int
rcar_thermal_remove
(
struct
platform_device
*
pdev
)
{
struct
rcar_thermal_common
*
common
=
platform_get_drvdata
(
pdev
);
struct
device
*
dev
=
&
pdev
->
dev
;
struct
rcar_thermal_priv
*
priv
;
rcar_thermal_for_each_priv
(
priv
,
common
)
rcar_thermal_for_each_priv
(
priv
,
common
)
{
thermal_zone_device_unregister
(
priv
->
zone
);
if
(
rcar_has_irq_support
(
priv
))
rcar_thermal_irq_disable
(
priv
);
}
platform_set_drvdata
(
pdev
,
NULL
);
pm_runtime_put_sync
(
dev
);
pm_runtime_disable
(
dev
);
return
0
;
}
...
...
drivers/thermal/step_wise.c
View file @
d13cb03a
...
...
@@ -22,9 +22,6 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/thermal.h>
#include "thermal_core.h"
...
...
@@ -59,9 +56,12 @@ static unsigned long get_target_state(struct thermal_instance *instance,
switch
(
trend
)
{
case
THERMAL_TREND_RAISING
:
if
(
throttle
)
if
(
throttle
)
{
cur_state
=
cur_state
<
instance
->
upper
?
(
cur_state
+
1
)
:
instance
->
upper
;
if
(
cur_state
<
instance
->
lower
)
cur_state
=
instance
->
lower
;
}
break
;
case
THERMAL_TREND_RAISE_FULL
:
if
(
throttle
)
...
...
@@ -71,8 +71,11 @@ static unsigned long get_target_state(struct thermal_instance *instance,
if
(
cur_state
==
instance
->
lower
)
{
if
(
!
throttle
)
cur_state
=
-
1
;
}
else
}
else
{
cur_state
-=
1
;
if
(
cur_state
>
instance
->
upper
)
cur_state
=
instance
->
upper
;
}
break
;
case
THERMAL_TREND_DROP_FULL
:
if
(
cur_state
==
instance
->
lower
)
{
...
...
@@ -180,23 +183,14 @@ static int step_wise_throttle(struct thermal_zone_device *tz, int trip)
static
struct
thermal_governor
thermal_gov_step_wise
=
{
.
name
=
"step_wise"
,
.
throttle
=
step_wise_throttle
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
thermal_gov_step_wise_init
(
void
)
int
thermal_gov_step_wise_register
(
void
)
{
return
thermal_register_governor
(
&
thermal_gov_step_wise
);
}
static
void
__exit
thermal_gov_step_wise_exit
(
void
)
void
thermal_gov_step_wise_unregister
(
void
)
{
thermal_unregister_governor
(
&
thermal_gov_step_wise
);
}
/* This should load after thermal framework */
fs_initcall
(
thermal_gov_step_wise_init
);
module_exit
(
thermal_gov_step_wise_exit
);
MODULE_AUTHOR
(
"Durgadoss R"
);
MODULE_DESCRIPTION
(
"A step-by-step thermal throttling governor"
);
MODULE_LICENSE
(
"GPL"
);
drivers/thermal/thermal_
sys
.c
→
drivers/thermal/thermal_
core
.c
View file @
d13cb03a
...
...
@@ -99,7 +99,6 @@ int thermal_register_governor(struct thermal_governor *governor)
return
err
;
}
EXPORT_SYMBOL_GPL
(
thermal_register_governor
);
void
thermal_unregister_governor
(
struct
thermal_governor
*
governor
)
{
...
...
@@ -127,7 +126,6 @@ void thermal_unregister_governor(struct thermal_governor *governor)
mutex_unlock
(
&
thermal_governor_lock
);
return
;
}
EXPORT_SYMBOL_GPL
(
thermal_unregister_governor
);
static
int
get_idr
(
struct
idr
*
idr
,
struct
mutex
*
lock
,
int
*
id
)
{
...
...
@@ -1858,30 +1856,69 @@ static inline int genetlink_init(void) { return 0; }
static
inline
void
genetlink_exit
(
void
)
{}
#endif
/* !CONFIG_NET */
static
int
__init
thermal_register_governors
(
void
)
{
int
result
;
result
=
thermal_gov_step_wise_register
();
if
(
result
)
return
result
;
result
=
thermal_gov_fair_share_register
();
if
(
result
)
return
result
;
return
thermal_gov_user_space_register
();
}
static
void
thermal_unregister_governors
(
void
)
{
thermal_gov_step_wise_unregister
();
thermal_gov_fair_share_unregister
();
thermal_gov_user_space_unregister
();
}
static
int
__init
thermal_init
(
void
)
{
int
result
=
0
;
int
result
;
result
=
thermal_register_governors
();
if
(
result
)
goto
error
;
result
=
class_register
(
&
thermal_class
);
if
(
result
)
{
idr_destroy
(
&
thermal_tz_idr
);
idr_destroy
(
&
thermal_cdev_idr
);
mutex_destroy
(
&
thermal_idr_lock
);
mutex_destroy
(
&
thermal_list_lock
);
return
result
;
}
if
(
result
)
goto
unregister_governors
;
result
=
genetlink_init
();
if
(
result
)
goto
unregister_class
;
return
0
;
unregister_governors:
thermal_unregister_governors
();
unregister_class:
class_unregister
(
&
thermal_class
);
error:
idr_destroy
(
&
thermal_tz_idr
);
idr_destroy
(
&
thermal_cdev_idr
);
mutex_destroy
(
&
thermal_idr_lock
);
mutex_destroy
(
&
thermal_list_lock
);
mutex_destroy
(
&
thermal_governor_lock
);
return
result
;
}
static
void
__exit
thermal_exit
(
void
)
{
genetlink_exit
();
class_unregister
(
&
thermal_class
);
thermal_unregister_governors
();
idr_destroy
(
&
thermal_tz_idr
);
idr_destroy
(
&
thermal_cdev_idr
);
mutex_destroy
(
&
thermal_idr_lock
);
mutex_destroy
(
&
thermal_list_lock
);
genetlink_exit
(
);
mutex_destroy
(
&
thermal_governor_lock
);
}
fs_initcall
(
thermal_init
);
...
...
drivers/thermal/thermal_core.h
View file @
d13cb03a
...
...
@@ -50,4 +50,31 @@ struct thermal_instance {
struct
list_head
cdev_node
;
/* node in cdev->thermal_instances */
};
int
thermal_register_governor
(
struct
thermal_governor
*
);
void
thermal_unregister_governor
(
struct
thermal_governor
*
);
#ifdef CONFIG_THERMAL_GOV_STEP_WISE
int
thermal_gov_step_wise_register
(
void
);
void
thermal_gov_step_wise_unregister
(
void
);
#else
static
inline
int
thermal_gov_step_wise_register
(
void
)
{
return
0
;
}
static
inline
void
thermal_gov_step_wise_unregister
(
void
)
{}
#endif
/* CONFIG_THERMAL_GOV_STEP_WISE */
#ifdef CONFIG_THERMAL_GOV_FAIR_SHARE
int
thermal_gov_fair_share_register
(
void
);
void
thermal_gov_fair_share_unregister
(
void
);
#else
static
inline
int
thermal_gov_fair_share_register
(
void
)
{
return
0
;
}
static
inline
void
thermal_gov_fair_share_unregister
(
void
)
{}
#endif
/* CONFIG_THERMAL_GOV_FAIR_SHARE */
#ifdef CONFIG_THERMAL_GOV_USER_SPACE
int
thermal_gov_user_space_register
(
void
);
void
thermal_gov_user_space_unregister
(
void
);
#else
static
inline
int
thermal_gov_user_space_register
(
void
)
{
return
0
;
}
static
inline
void
thermal_gov_user_space_unregister
(
void
)
{}
#endif
/* CONFIG_THERMAL_GOV_USER_SPACE */
#endif
/* __THERMAL_CORE_H__ */
drivers/thermal/user_space.c
View file @
d13cb03a
...
...
@@ -22,9 +22,6 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/thermal.h>
#include "thermal_core.h"
...
...
@@ -46,23 +43,15 @@ static int notify_user_space(struct thermal_zone_device *tz, int trip)
static
struct
thermal_governor
thermal_gov_user_space
=
{
.
name
=
"user_space"
,
.
throttle
=
notify_user_space
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
thermal_gov_user_space_init
(
void
)
int
thermal_gov_user_space_register
(
void
)
{
return
thermal_register_governor
(
&
thermal_gov_user_space
);
}
static
void
__exit
thermal_gov_user_space_exit
(
void
)
void
thermal_gov_user_space_unregister
(
void
)
{
thermal_unregister_governor
(
&
thermal_gov_user_space
);
}
/* This should load after thermal framework */
fs_initcall
(
thermal_gov_user_space_init
);
module_exit
(
thermal_gov_user_space_exit
);
MODULE_AUTHOR
(
"Durgadoss R"
);
MODULE_DESCRIPTION
(
"A user space Thermal notifier"
);
MODULE_LICENSE
(
"GPL"
);
include/linux/cpu_cooling.h
View file @
d13cb03a
...
...
@@ -29,7 +29,7 @@
#define CPUFREQ_COOLING_START 0
#define CPUFREQ_COOLING_STOP 1
#if
defined(CONFIG_CPU_THERMAL) || defined(CONFIG_CPU_THERMAL_MODULE)
#if
def CONFIG_CPU_THERMAL
/**
* cpufreq_cooling_register - function to create cpufreq cooling device.
* @clip_cpus: cpumask of cpus where the frequency constraints will happen
...
...
@@ -42,6 +42,8 @@ struct thermal_cooling_device *cpufreq_cooling_register(
* @cdev: thermal cooling device pointer.
*/
void
cpufreq_cooling_unregister
(
struct
thermal_cooling_device
*
cdev
);
unsigned
long
cpufreq_cooling_get_level
(
unsigned
int
,
unsigned
int
);
#else
/* !CONFIG_CPU_THERMAL */
static
inline
struct
thermal_cooling_device
*
cpufreq_cooling_register
(
const
struct
cpumask
*
clip_cpus
)
...
...
@@ -53,6 +55,11 @@ static inline void cpufreq_cooling_unregister(
{
return
;
}
static
inline
unsigned
long
cpufreq_cooling_get_level
(
unsigned
int
,
unsigned
int
)
{
return
THERMAL_CSTATE_INVALID
;
}
#endif
/* CONFIG_CPU_THERMAL */
#endif
/* __CPU_COOLING_H__ */
include/linux/thermal.h
View file @
d13cb03a
...
...
@@ -33,8 +33,11 @@
#define THERMAL_MAX_TRIPS 12
#define THERMAL_NAME_LENGTH 20
/* invalid cooling state */
#define THERMAL_CSTATE_INVALID -1UL
/* No upper/lower limit requirement */
#define THERMAL_NO_LIMIT
-1UL
#define THERMAL_NO_LIMIT
THERMAL_CSTATE_INVALID
/* Unit conversion macros */
#define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \
...
...
@@ -184,7 +187,6 @@ struct thermal_governor {
char
name
[
THERMAL_NAME_LENGTH
];
int
(
*
throttle
)(
struct
thermal_zone_device
*
tz
,
int
trip
);
struct
list_head
governor_list
;
struct
module
*
owner
;
};
/* Structure that holds binding parameters for a zone */
...
...
@@ -244,9 +246,6 @@ struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
void
thermal_cdev_update
(
struct
thermal_cooling_device
*
);
void
notify_thermal_framework
(
struct
thermal_zone_device
*
,
int
);
int
thermal_register_governor
(
struct
thermal_governor
*
);
void
thermal_unregister_governor
(
struct
thermal_governor
*
);
#ifdef CONFIG_NET
extern
int
thermal_generate_netlink_event
(
struct
thermal_zone_device
*
tz
,
enum
events
event
);
...
...
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