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
1e032393
Commit
1e032393
authored
Nov 02, 2017
by
Zhang Rui
Browse files
Options
Browse Files
Download
Plain Diff
Merge branches 'thermal-core', 'thermal-tool', 'thermal-intel' and 'thermal-soc' into next
parents
023b7b07
501a5c71
6ed5ed14
fe9ba5bc
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
1054 additions
and
326 deletions
+1054
-326
Documentation/devicetree/bindings/thermal/brcm,avs-tmon.txt
Documentation/devicetree/bindings/thermal/brcm,avs-tmon.txt
+20
-0
Documentation/devicetree/bindings/thermal/imx-thermal.txt
Documentation/devicetree/bindings/thermal/imx-thermal.txt
+7
-0
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
...entation/devicetree/bindings/thermal/rockchip-thermal.txt
+1
-0
MAINTAINERS
MAINTAINERS
+8
-0
drivers/thermal/Kconfig
drivers/thermal/Kconfig
+2
-1
drivers/thermal/armada_thermal.c
drivers/thermal/armada_thermal.c
+1
-1
drivers/thermal/broadcom/Kconfig
drivers/thermal/broadcom/Kconfig
+7
-0
drivers/thermal/broadcom/Makefile
drivers/thermal/broadcom/Makefile
+1
-0
drivers/thermal/broadcom/brcmstb_thermal.c
drivers/thermal/broadcom/brcmstb_thermal.c
+387
-0
drivers/thermal/cpu_cooling.c
drivers/thermal/cpu_cooling.c
+1
-1
drivers/thermal/hisi_thermal.c
drivers/thermal/hisi_thermal.c
+404
-208
drivers/thermal/imx_thermal.c
drivers/thermal/imx_thermal.c
+74
-30
drivers/thermal/int340x_thermal/processor_thermal_device.c
drivers/thermal/int340x_thermal/processor_thermal_device.c
+6
-0
drivers/thermal/intel_bxt_pmic_thermal.c
drivers/thermal/intel_bxt_pmic_thermal.c
+1
-2
drivers/thermal/intel_pch_thermal.c
drivers/thermal/intel_pch_thermal.c
+11
-0
drivers/thermal/intel_powerclamp.c
drivers/thermal/intel_powerclamp.c
+2
-2
drivers/thermal/qcom-spmi-temp-alarm.c
drivers/thermal/qcom-spmi-temp-alarm.c
+14
-29
drivers/thermal/rcar_gen3_thermal.c
drivers/thermal/rcar_gen3_thermal.c
+15
-19
drivers/thermal/rockchip_thermal.c
drivers/thermal/rockchip_thermal.c
+67
-0
drivers/thermal/step_wise.c
drivers/thermal/step_wise.c
+6
-5
drivers/thermal/tegra/soctherm.c
drivers/thermal/tegra/soctherm.c
+1
-1
drivers/thermal/thermal-generic-adc.c
drivers/thermal/thermal-generic-adc.c
+4
-20
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+2
-1
tools/thermal/tmon/Makefile
tools/thermal/tmon/Makefile
+12
-6
No files found.
Documentation/devicetree/bindings/thermal/brcm,avs-tmon.txt
0 → 100644
View file @
1e032393
* Broadcom STB thermal management
Thermal management core, provided by the AVS TMON hardware block.
Required properties:
- compatible: must be "brcm,avs-tmon" and/or "brcm,avs-tmon-bcm7445"
- reg: address range for the AVS TMON registers
- interrupts: temperature monitor interrupt, for high/low threshold triggers
- interrupt-names: should be "tmon"
- interrupt-parent: the parent interrupt controller
Example:
thermal@f04d1500 {
compatible = "brcm,avs-tmon-bcm7445", "brcm,avs-tmon";
reg = <0xf04d1500 0x28>;
interrupts = <0x6>;
interrupt-names = "tmon";
interrupt-parent = <&avs_host_l2_intc>;
};
Documentation/devicetree/bindings/thermal/imx-thermal.txt
View file @
1e032393
...
...
@@ -7,10 +7,17 @@ Required properties:
is higher than panic threshold, system will auto reboot by SRC module.
- fsl,tempmon : phandle pointer to system controller that contains TEMPMON
control registers, e.g. ANATOP on imx6q.
- nvmem-cells: A phandle to the calibration cells provided by ocotp.
- nvmem-cell-names: Should be "calib", "temp_grade".
Deprecated properties:
- fsl,tempmon-data : phandle pointer to fuse controller that contains TEMPMON
calibration data, e.g. OCOTP on imx6q. The details about calibration data
can be found in SoC Reference Manual.
Direct access to OCOTP via fsl,tempmon-data is incorrect on some newer chips
because it does not handle OCOTP clock requirements.
Optional properties:
- clocks : thermal sensor's clock source.
...
...
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
View file @
1e032393
...
...
@@ -2,6 +2,7 @@
Required properties:
- compatible : should be "rockchip,<name>-tsadc"
"rockchip,rv1108-tsadc": found on RV1108 SoCs
"rockchip,rk3228-tsadc": found on RK3228 SoCs
"rockchip,rk3288-tsadc": found on RK3288 SoCs
"rockchip,rk3328-tsadc": found on RK3328 SoCs
...
...
MAINTAINERS
View file @
1e032393
...
...
@@ -2955,6 +2955,14 @@ S: Maintained
F: Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt
F: drivers/cpufreq/brcmstb*
BROADCOM STB AVS TMON DRIVER
M: Markus Mayer <mmayer@broadcom.com>
M: bcm-kernel-feedback-list@broadcom.com
L: linux-pm@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/thermal/brcm,avs-tmon.txt
F: drivers/thermal/broadcom/brcmstb*
BROADCOM STB NAND FLASH DRIVER
M: Brian Norris <computersforpeace@gmail.com>
M: Kamal Dasu <kdasu.kdev@gmail.com>
...
...
drivers/thermal/Kconfig
View file @
1e032393
...
...
@@ -206,6 +206,7 @@ config HISI_THERMAL
config IMX_THERMAL
tristate "Temperature sensor driver for Freescale i.MX SoCs"
depends on (ARCH_MXC && CPU_THERMAL) || COMPILE_TEST
depends on NVMEM || !NVMEM
depends on MFD_SYSCON
depends on OF
help
...
...
@@ -408,7 +409,7 @@ config MTK_THERMAL
controller present in Mediatek SoCs
menu "Broadcom thermal drivers"
depends on ARCH_BCM || COMPILE_TEST
depends on ARCH_BCM ||
ARCH_BRCMSTB || ARCH_BCM2835 ||
COMPILE_TEST
source "drivers/thermal/broadcom/Kconfig"
endmenu
...
...
drivers/thermal/armada_thermal.c
View file @
1e032393
...
...
@@ -58,7 +58,7 @@ struct armada_thermal_data {
/* Test for a valid sensor value (optional) */
bool
(
*
is_valid
)(
struct
armada_thermal_priv
*
);
/* Formula coeficients: temp = (b
+
m * reg) / div */
/* Formula coeficients: temp = (b
-
m * reg) / div */
unsigned
long
coef_b
;
unsigned
long
coef_m
;
unsigned
long
coef_div
;
...
...
drivers/thermal/broadcom/Kconfig
View file @
1e032393
...
...
@@ -6,6 +6,13 @@ config BCM2835_THERMAL
help
Support for thermal sensors on Broadcom bcm2835 SoCs.
config BRCMSTB_THERMAL
tristate "Broadcom STB AVS TMON thermal driver"
depends on ARCH_BRCMSTB || COMPILE_TEST
help
Enable this driver if you have a Broadcom STB SoC and would like
thermal framework support.
config BCM_NS_THERMAL
tristate "Northstar thermal driver"
depends on ARCH_BCM_IPROC || COMPILE_TEST
...
...
drivers/thermal/broadcom/Makefile
View file @
1e032393
obj-$(CONFIG_BCM2835_THERMAL)
+=
bcm2835_thermal.o
obj-$(CONFIG_BRCMSTB_THERMAL)
+=
brcmstb_thermal.o
obj-$(CONFIG_BCM_NS_THERMAL)
+=
ns-thermal.o
drivers/thermal/broadcom/brcmstb_thermal.c
0 → 100644
View file @
1e032393
/*
* Broadcom STB AVS TMON thermal sensor driver
*
* Copyright (c) 2015-2017 Broadcom
*
* 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.
*
*/
#define DRV_NAME "brcmstb_thermal"
#define pr_fmt(fmt) DRV_NAME ": " fmt
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/irqreturn.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/thermal.h>
#define AVS_TMON_STATUS 0x00
#define AVS_TMON_STATUS_valid_msk BIT(11)
#define AVS_TMON_STATUS_data_msk GENMASK(10, 1)
#define AVS_TMON_STATUS_data_shift 1
#define AVS_TMON_EN_OVERTEMP_RESET 0x04
#define AVS_TMON_EN_OVERTEMP_RESET_msk BIT(0)
#define AVS_TMON_RESET_THRESH 0x08
#define AVS_TMON_RESET_THRESH_msk GENMASK(10, 1)
#define AVS_TMON_RESET_THRESH_shift 1
#define AVS_TMON_INT_IDLE_TIME 0x10
#define AVS_TMON_EN_TEMP_INT_SRCS 0x14
#define AVS_TMON_EN_TEMP_INT_SRCS_high BIT(1)
#define AVS_TMON_EN_TEMP_INT_SRCS_low BIT(0)
#define AVS_TMON_INT_THRESH 0x18
#define AVS_TMON_INT_THRESH_high_msk GENMASK(26, 17)
#define AVS_TMON_INT_THRESH_high_shift 17
#define AVS_TMON_INT_THRESH_low_msk GENMASK(10, 1)
#define AVS_TMON_INT_THRESH_low_shift 1
#define AVS_TMON_TEMP_INT_CODE 0x1c
#define AVS_TMON_TP_TEST_ENABLE 0x20
/* Default coefficients */
#define AVS_TMON_TEMP_SLOPE -487
#define AVS_TMON_TEMP_OFFSET 410040
/* HW related temperature constants */
#define AVS_TMON_TEMP_MAX 0x3ff
#define AVS_TMON_TEMP_MIN -88161
#define AVS_TMON_TEMP_MASK AVS_TMON_TEMP_MAX
enum
avs_tmon_trip_type
{
TMON_TRIP_TYPE_LOW
=
0
,
TMON_TRIP_TYPE_HIGH
,
TMON_TRIP_TYPE_RESET
,
TMON_TRIP_TYPE_MAX
,
};
struct
avs_tmon_trip
{
/* HW bit to enable the trip */
u32
enable_offs
;
u32
enable_mask
;
/* HW field to read the trip temperature */
u32
reg_offs
;
u32
reg_msk
;
int
reg_shift
;
};
static
struct
avs_tmon_trip
avs_tmon_trips
[]
=
{
/* Trips when temperature is below threshold */
[
TMON_TRIP_TYPE_LOW
]
=
{
.
enable_offs
=
AVS_TMON_EN_TEMP_INT_SRCS
,
.
enable_mask
=
AVS_TMON_EN_TEMP_INT_SRCS_low
,
.
reg_offs
=
AVS_TMON_INT_THRESH
,
.
reg_msk
=
AVS_TMON_INT_THRESH_low_msk
,
.
reg_shift
=
AVS_TMON_INT_THRESH_low_shift
,
},
/* Trips when temperature is above threshold */
[
TMON_TRIP_TYPE_HIGH
]
=
{
.
enable_offs
=
AVS_TMON_EN_TEMP_INT_SRCS
,
.
enable_mask
=
AVS_TMON_EN_TEMP_INT_SRCS_high
,
.
reg_offs
=
AVS_TMON_INT_THRESH
,
.
reg_msk
=
AVS_TMON_INT_THRESH_high_msk
,
.
reg_shift
=
AVS_TMON_INT_THRESH_high_shift
,
},
/* Automatically resets chip when above threshold */
[
TMON_TRIP_TYPE_RESET
]
=
{
.
enable_offs
=
AVS_TMON_EN_OVERTEMP_RESET
,
.
enable_mask
=
AVS_TMON_EN_OVERTEMP_RESET_msk
,
.
reg_offs
=
AVS_TMON_RESET_THRESH
,
.
reg_msk
=
AVS_TMON_RESET_THRESH_msk
,
.
reg_shift
=
AVS_TMON_RESET_THRESH_shift
,
},
};
struct
brcmstb_thermal_priv
{
void
__iomem
*
tmon_base
;
struct
device
*
dev
;
struct
thermal_zone_device
*
thermal
;
};
static
void
avs_tmon_get_coeffs
(
struct
thermal_zone_device
*
tz
,
int
*
slope
,
int
*
offset
)
{
*
slope
=
thermal_zone_get_slope
(
tz
);
*
offset
=
thermal_zone_get_offset
(
tz
);
}
/* Convert a HW code to a temperature reading (millidegree celsius) */
static
inline
int
avs_tmon_code_to_temp
(
struct
thermal_zone_device
*
tz
,
u32
code
)
{
const
int
val
=
code
&
AVS_TMON_TEMP_MASK
;
int
slope
,
offset
;
avs_tmon_get_coeffs
(
tz
,
&
slope
,
&
offset
);
return
slope
*
val
+
offset
;
}
/*
* Convert a temperature value (millidegree celsius) to a HW code
*
* @temp: temperature to convert
* @low: if true, round toward the low side
*/
static
inline
u32
avs_tmon_temp_to_code
(
struct
thermal_zone_device
*
tz
,
int
temp
,
bool
low
)
{
int
slope
,
offset
;
if
(
temp
<
AVS_TMON_TEMP_MIN
)
return
AVS_TMON_TEMP_MAX
;
/* Maximum code value */
avs_tmon_get_coeffs
(
tz
,
&
slope
,
&
offset
);
if
(
temp
>=
offset
)
return
0
;
/* Minimum code value */
if
(
low
)
return
(
u32
)(
DIV_ROUND_UP
(
offset
-
temp
,
abs
(
slope
)));
else
return
(
u32
)((
offset
-
temp
)
/
abs
(
slope
));
}
static
int
brcmstb_get_temp
(
void
*
data
,
int
*
temp
)
{
struct
brcmstb_thermal_priv
*
priv
=
data
;
u32
val
;
long
t
;
val
=
__raw_readl
(
priv
->
tmon_base
+
AVS_TMON_STATUS
);
if
(
!
(
val
&
AVS_TMON_STATUS_valid_msk
))
{
dev_err
(
priv
->
dev
,
"reading not valid
\n
"
);
return
-
EIO
;
}
val
=
(
val
&
AVS_TMON_STATUS_data_msk
)
>>
AVS_TMON_STATUS_data_shift
;
t
=
avs_tmon_code_to_temp
(
priv
->
thermal
,
val
);
if
(
t
<
0
)
*
temp
=
0
;
else
*
temp
=
t
;
return
0
;
}
static
void
avs_tmon_trip_enable
(
struct
brcmstb_thermal_priv
*
priv
,
enum
avs_tmon_trip_type
type
,
int
en
)
{
struct
avs_tmon_trip
*
trip
=
&
avs_tmon_trips
[
type
];
u32
val
=
__raw_readl
(
priv
->
tmon_base
+
trip
->
enable_offs
);
dev_dbg
(
priv
->
dev
,
"%sable trip, type %d
\n
"
,
en
?
"en"
:
"dis"
,
type
);
if
(
en
)
val
|=
trip
->
enable_mask
;
else
val
&=
~
trip
->
enable_mask
;
__raw_writel
(
val
,
priv
->
tmon_base
+
trip
->
enable_offs
);
}
static
int
avs_tmon_get_trip_temp
(
struct
brcmstb_thermal_priv
*
priv
,
enum
avs_tmon_trip_type
type
)
{
struct
avs_tmon_trip
*
trip
=
&
avs_tmon_trips
[
type
];
u32
val
=
__raw_readl
(
priv
->
tmon_base
+
trip
->
reg_offs
);
val
&=
trip
->
reg_msk
;
val
>>=
trip
->
reg_shift
;
return
avs_tmon_code_to_temp
(
priv
->
thermal
,
val
);
}
static
void
avs_tmon_set_trip_temp
(
struct
brcmstb_thermal_priv
*
priv
,
enum
avs_tmon_trip_type
type
,
int
temp
)
{
struct
avs_tmon_trip
*
trip
=
&
avs_tmon_trips
[
type
];
u32
val
,
orig
;
dev_dbg
(
priv
->
dev
,
"set temp %d to %d
\n
"
,
type
,
temp
);
/* round toward low temp for the low interrupt */
val
=
avs_tmon_temp_to_code
(
priv
->
thermal
,
temp
,
type
==
TMON_TRIP_TYPE_LOW
);
val
<<=
trip
->
reg_shift
;
val
&=
trip
->
reg_msk
;
orig
=
__raw_readl
(
priv
->
tmon_base
+
trip
->
reg_offs
);
orig
&=
~
trip
->
reg_msk
;
orig
|=
val
;
__raw_writel
(
orig
,
priv
->
tmon_base
+
trip
->
reg_offs
);
}
static
int
avs_tmon_get_intr_temp
(
struct
brcmstb_thermal_priv
*
priv
)
{
u32
val
;
val
=
__raw_readl
(
priv
->
tmon_base
+
AVS_TMON_TEMP_INT_CODE
);
return
avs_tmon_code_to_temp
(
priv
->
thermal
,
val
);
}
static
irqreturn_t
brcmstb_tmon_irq_thread
(
int
irq
,
void
*
data
)
{
struct
brcmstb_thermal_priv
*
priv
=
data
;
int
low
,
high
,
intr
;
low
=
avs_tmon_get_trip_temp
(
priv
,
TMON_TRIP_TYPE_LOW
);
high
=
avs_tmon_get_trip_temp
(
priv
,
TMON_TRIP_TYPE_HIGH
);
intr
=
avs_tmon_get_intr_temp
(
priv
);
dev_dbg
(
priv
->
dev
,
"low/intr/high: %d/%d/%d
\n
"
,
low
,
intr
,
high
);
/* Disable high-temp until next threshold shift */
if
(
intr
>=
high
)
avs_tmon_trip_enable
(
priv
,
TMON_TRIP_TYPE_HIGH
,
0
);
/* Disable low-temp until next threshold shift */
if
(
intr
<=
low
)
avs_tmon_trip_enable
(
priv
,
TMON_TRIP_TYPE_LOW
,
0
);
/*
* Notify using the interrupt temperature, in case the temperature
* changes before it can next be read out
*/
thermal_zone_device_update
(
priv
->
thermal
,
intr
);
return
IRQ_HANDLED
;
}
static
int
brcmstb_set_trips
(
void
*
data
,
int
low
,
int
high
)
{
struct
brcmstb_thermal_priv
*
priv
=
data
;
dev_dbg
(
priv
->
dev
,
"set trips %d <--> %d
\n
"
,
low
,
high
);
/*
* Disable low-temp if "low" is too small. As per thermal framework
* API, we use -INT_MAX rather than INT_MIN.
*/
if
(
low
<=
-
INT_MAX
)
{
avs_tmon_trip_enable
(
priv
,
TMON_TRIP_TYPE_LOW
,
0
);
}
else
{
avs_tmon_set_trip_temp
(
priv
,
TMON_TRIP_TYPE_LOW
,
low
);
avs_tmon_trip_enable
(
priv
,
TMON_TRIP_TYPE_LOW
,
1
);
}
/* Disable high-temp if "high" is too big. */
if
(
high
==
INT_MAX
)
{
avs_tmon_trip_enable
(
priv
,
TMON_TRIP_TYPE_HIGH
,
0
);
}
else
{
avs_tmon_set_trip_temp
(
priv
,
TMON_TRIP_TYPE_HIGH
,
high
);
avs_tmon_trip_enable
(
priv
,
TMON_TRIP_TYPE_HIGH
,
1
);
}
return
0
;
}
static
struct
thermal_zone_of_device_ops
of_ops
=
{
.
get_temp
=
brcmstb_get_temp
,
.
set_trips
=
brcmstb_set_trips
,
};
static
const
struct
of_device_id
brcmstb_thermal_id_table
[]
=
{
{
.
compatible
=
"brcm,avs-tmon"
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
brcmstb_thermal_id_table
);
static
int
brcmstb_thermal_probe
(
struct
platform_device
*
pdev
)
{
struct
thermal_zone_device
*
thermal
;
struct
brcmstb_thermal_priv
*
priv
;
struct
resource
*
res
;
int
irq
,
ret
;
priv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
priv
),
GFP_KERNEL
);
if
(
!
priv
)
return
-
ENOMEM
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
priv
->
tmon_base
=
devm_ioremap_resource
(
&
pdev
->
dev
,
res
);
if
(
IS_ERR
(
priv
->
tmon_base
))
return
PTR_ERR
(
priv
->
tmon_base
);
priv
->
dev
=
&
pdev
->
dev
;
platform_set_drvdata
(
pdev
,
priv
);
thermal
=
thermal_zone_of_sensor_register
(
&
pdev
->
dev
,
0
,
priv
,
&
of_ops
);
if
(
IS_ERR
(
thermal
))
{
ret
=
PTR_ERR
(
thermal
);
dev_err
(
&
pdev
->
dev
,
"could not register sensor: %d
\n
"
,
ret
);
return
ret
;
}
priv
->
thermal
=
thermal
;
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
irq
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"could not get IRQ
\n
"
);
ret
=
irq
;
goto
err
;
}
ret
=
devm_request_threaded_irq
(
&
pdev
->
dev
,
irq
,
NULL
,
brcmstb_tmon_irq_thread
,
IRQF_ONESHOT
,
DRV_NAME
,
priv
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"could not request IRQ: %d
\n
"
,
ret
);
goto
err
;
}
dev_info
(
&
pdev
->
dev
,
"registered AVS TMON of-sensor driver
\n
"
);
return
0
;
err:
thermal_zone_of_sensor_unregister
(
&
pdev
->
dev
,
thermal
);
return
ret
;
}
static
int
brcmstb_thermal_exit
(
struct
platform_device
*
pdev
)
{
struct
brcmstb_thermal_priv
*
priv
=
platform_get_drvdata
(
pdev
);
struct
thermal_zone_device
*
thermal
=
priv
->
thermal
;
if
(
thermal
)
thermal_zone_of_sensor_unregister
(
&
pdev
->
dev
,
priv
->
thermal
);
return
0
;
}
static
struct
platform_driver
brcmstb_thermal_driver
=
{
.
probe
=
brcmstb_thermal_probe
,
.
remove
=
brcmstb_thermal_exit
,
.
driver
=
{
.
name
=
DRV_NAME
,
.
of_match_table
=
brcmstb_thermal_id_table
,
},
};
module_platform_driver
(
brcmstb_thermal_driver
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_AUTHOR
(
"Brian Norris"
);
MODULE_DESCRIPTION
(
"Broadcom STB AVS TMON thermal driver"
);
drivers/thermal/cpu_cooling.c
View file @
1e032393
...
...
@@ -696,7 +696,7 @@ __cpufreq_cooling_register(struct device_node *np,
bool
first
;
if
(
IS_ERR_OR_NULL
(
policy
))
{
pr_err
(
"%s: cpufreq policy isn't valid: %p"
,
__func__
,
policy
);
pr_err
(
"%s: cpufreq policy isn't valid: %p
\n
"
,
__func__
,
policy
);
return
ERR_PTR
(
-
EINVAL
);
}
...
...
drivers/thermal/hisi_thermal.c
View file @
1e032393
...
...
@@ -23,222 +23,450 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/of_device.h>
#include "thermal_core.h"
#define TEMP0_TH (0x4)
#define TEMP0_RST_TH (0x8)
#define TEMP0_CFG (0xC)
#define TEMP0_EN (0x10)
#define TEMP0_INT_EN (0x14)
#define TEMP0_INT_CLR (0x18)
#define TEMP0_RST_MSK (0x1C)
#define TEMP0_VALUE (0x28)
#define HISI_TEMP_BASE (-60)
#define HISI_TEMP_RESET (100000)
#define HISI_MAX_SENSORS 4
#define HI6220_TEMP0_LAG (0x0)
#define HI6220_TEMP0_TH (0x4)
#define HI6220_TEMP0_RST_TH (0x8)
#define HI6220_TEMP0_CFG (0xC)
#define HI6220_TEMP0_CFG_SS_MSK (0xF000)
#define HI6220_TEMP0_CFG_HDAK_MSK (0x30)
#define HI6220_TEMP0_EN (0x10)
#define HI6220_TEMP0_INT_EN (0x14)
#define HI6220_TEMP0_INT_CLR (0x18)
#define HI6220_TEMP0_RST_MSK (0x1C)
#define HI6220_TEMP0_VALUE (0x28)
#define HI3660_OFFSET(chan) ((chan) * 0x40)
#define HI3660_TEMP(chan) (HI3660_OFFSET(chan) + 0x1C)
#define HI3660_TH(chan) (HI3660_OFFSET(chan) + 0x20)
#define HI3660_LAG(chan) (HI3660_OFFSET(chan) + 0x28)
#define HI3660_INT_EN(chan) (HI3660_OFFSET(chan) + 0x2C)
#define HI3660_INT_CLR(chan) (HI3660_OFFSET(chan) + 0x30)
#define HI6220_TEMP_BASE (-60000)
#define HI6220_TEMP_RESET (100000)
#define HI6220_TEMP_STEP (785)
#define HI6220_TEMP_LAG (3500)
#define HI3660_TEMP_BASE (-63780)
#define HI3660_TEMP_STEP (205)
#define HI3660_TEMP_LAG (4000)
#define HI6220_DEFAULT_SENSOR 2
#define HI3660_DEFAULT_SENSOR 1
struct
hisi_thermal_sensor
{
struct
hisi_thermal_data
*
thermal
;
struct
thermal_zone_device
*
tzd
;
long
sensor_temp
;
uint32_t
id
;
uint32_t
thres_temp
;
};
struct
hisi_thermal_data
{
struct
mutex
thermal_lock
;
/* protects register data */
int
(
*
get_temp
)(
struct
hisi_thermal_data
*
data
);
int
(
*
enable_sensor
)(
struct
hisi_thermal_data
*
data
);
int
(
*
disable_sensor
)(
struct
hisi_thermal_data
*
data
);
int
(
*
irq_handler
)(
struct
hisi_thermal_data
*
data
);
struct
platform_device
*
pdev
;
struct
clk
*
clk
;
struct
hisi_thermal_sensor
sensors
[
HISI_MAX_SENSORS
];
int
irq
,
irq_bind_sensor
;
bool
irq_enabled
;
struct
hisi_thermal_sensor
sensor
;
void
__iomem
*
regs
;
int
irq
;
};
/* in millicelsius */
static
inline
int
_step_to_temp
(
int
step
)
/*
* The temperature computation on the tsensor is as follow:
* Unit: millidegree Celsius
* Step: 200/255 (0.7843)
* Temperature base: -60°C
*
* The register is programmed in temperature steps, every step is 785
* millidegree and begins at -60 000 m°C
*
* The temperature from the steps:
*
* Temp = TempBase + (steps x 785)
*
* and the steps from the temperature:
*
* steps = (Temp - TempBase) / 785
*
*/
static
inline
int
hi6220_thermal_step_to_temp
(
int
step
)
{
/*
* Every step equals (1 * 200) / 255 celsius, and finally
* need convert to millicelsius.
*/
return
(
HISI_TEMP_BASE
*
1000
+
(
step
*
200000
/
255
));
return
HI6220_TEMP_BASE
+
(
step
*
HI6220_TEMP_STEP
);
}
static
inline
long
_temp_to_step
(
long
temp
)
static
inline
int
hi6220_thermal_temp_to_step
(
int
temp
)
{
return
((
temp
-
HISI_TEMP_BASE
*
1000
)
*
255
)
/
200000
;
return
DIV_ROUND_UP
(
temp
-
HI6220_TEMP_BASE
,
HI6220_TEMP_STEP
)
;
}
static
long
hisi_thermal_get_sensor_temp
(
struct
hisi_thermal_data
*
data
,
struct
hisi_thermal_sensor
*
sensor
)
/*
* for Hi3660,
* Step: 189/922 (0.205)
* Temperature base: -63.780°C
*
* The register is programmed in temperature steps, every step is 205
* millidegree and begins at -63 780 m°C
*/
static
inline
int
hi3660_thermal_step_to_temp
(
int
step
)
{
long
val
;
return
HI3660_TEMP_BASE
+
step
*
HI3660_TEMP_STEP
;
}
mutex_lock
(
&
data
->
thermal_lock
);
static
inline
int
hi3660_thermal_temp_to_step
(
int
temp
)
{
return
DIV_ROUND_UP
(
temp
-
HI3660_TEMP_BASE
,
HI3660_TEMP_STEP
);
}
/* disable interrupt */
writel
(
0x0
,
data
->
regs
+
TEMP0_INT_EN
);
writel
(
0x1
,
data
->
regs
+
TEMP0_INT_CLR
);
/*
* The lag register contains 5 bits encoding the temperature in steps.
*
* Each time the temperature crosses the threshold boundary, an
* interrupt is raised. It could be when the temperature is going
* above the threshold or below. However, if the temperature is
* fluctuating around this value due to the load, we can receive
* several interrupts which may not desired.
*
* We can setup a temperature representing the delta between the
* threshold and the current temperature when the temperature is
* decreasing.
*
* For instance: the lag register is 5°C, the threshold is 65°C, when
* the temperature reaches 65°C an interrupt is raised and when the
* temperature decrease to 65°C - 5°C another interrupt is raised.
*
* A very short lag can lead to an interrupt storm, a long lag
* increase the latency to react to the temperature changes. In our
* case, that is not really a problem as we are polling the
* temperature.
*
* [0:4] : lag register
*
* The temperature is coded in steps, cf. HI6220_TEMP_STEP.
*
* Min : 0x00 : 0.0 °C
* Max : 0x1F : 24.3 °C
*
* The 'value' parameter is in milliCelsius.
*/
static
inline
void
hi6220_thermal_set_lag
(
void
__iomem
*
addr
,
int
value
)
{
writel
(
DIV_ROUND_UP
(
value
,
HI6220_TEMP_STEP
)
&
0x1F
,
addr
+
HI6220_TEMP0_LAG
);
}
/* disable module firstly */
writel
(
0x0
,
data
->
regs
+
TEMP0_EN
);
static
inline
void
hi6220_thermal_alarm_clear
(
void
__iomem
*
addr
,
int
value
)
{
writel
(
value
,
addr
+
HI6220_TEMP0_INT_CLR
);
}
/* select sensor id */
writel
((
sensor
->
id
<<
12
),
data
->
regs
+
TEMP0_CFG
);
static
inline
void
hi6220_thermal_alarm_enable
(
void
__iomem
*
addr
,
int
value
)
{
writel
(
value
,
addr
+
HI6220_TEMP0_INT_EN
);
}
/* enable module */
writel
(
0x1
,
data
->
regs
+
TEMP0_EN
);
static
inline
void
hi6220_thermal_alarm_set
(
void
__iomem
*
addr
,
int
temp
)
{
writel
(
hi6220_thermal_temp_to_step
(
temp
)
|
0x0FFFFFF00
,
addr
+
HI6220_TEMP0_TH
);
}
usleep_range
(
3000
,
5000
);
static
inline
void
hi6220_thermal_reset_set
(
void
__iomem
*
addr
,
int
temp
)
{
writel
(
hi6220_thermal_temp_to_step
(
temp
),
addr
+
HI6220_TEMP0_RST_TH
);
}
val
=
readl
(
data
->
regs
+
TEMP0_VALUE
);
val
=
_step_to_temp
(
val
);
static
inline
void
hi6220_thermal_reset_enable
(
void
__iomem
*
addr
,
int
value
)
{
writel
(
value
,
addr
+
HI6220_TEMP0_RST_MSK
);
}
mutex_unlock
(
&
data
->
thermal_lock
);
static
inline
void
hi6220_thermal_enable
(
void
__iomem
*
addr
,
int
value
)
{
writel
(
value
,
addr
+
HI6220_TEMP0_EN
);
}
return
val
;
static
inline
int
hi6220_thermal_get_temperature
(
void
__iomem
*
addr
)
{
return
hi6220_thermal_step_to_temp
(
readl
(
addr
+
HI6220_TEMP0_VALUE
));
}
static
void
hisi_thermal_enable_bind_irq_sensor
(
struct
hisi_thermal_data
*
data
)
/*
* [0:6] lag register
*
* The temperature is coded in steps, cf. HI3660_TEMP_STEP.
*
* Min : 0x00 : 0.0 °C
* Max : 0x7F : 26.0 °C
*
*/
static
inline
void
hi3660_thermal_set_lag
(
void
__iomem
*
addr
,
int
id
,
int
value
)
{
struct
hisi_thermal_sensor
*
sensor
;
writel
(
DIV_ROUND_UP
(
value
,
HI3660_TEMP_STEP
)
&
0x7F
,
addr
+
HI3660_LAG
(
id
));
}
mutex_lock
(
&
data
->
thermal_lock
);
static
inline
void
hi3660_thermal_alarm_clear
(
void
__iomem
*
addr
,
int
id
,
int
value
)
{
writel
(
value
,
addr
+
HI3660_INT_CLR
(
id
));
}
sensor
=
&
data
->
sensors
[
data
->
irq_bind_sensor
];
static
inline
void
hi3660_thermal_alarm_enable
(
void
__iomem
*
addr
,
int
id
,
int
value
)
{
writel
(
value
,
addr
+
HI3660_INT_EN
(
id
));
}
/* setting the hdak time */
writel
(
0x0
,
data
->
regs
+
TEMP0_CFG
);
static
inline
void
hi3660_thermal_alarm_set
(
void
__iomem
*
addr
,
int
id
,
int
value
)
{
writel
(
value
,
addr
+
HI3660_TH
(
id
));
}
static
inline
int
hi3660_thermal_get_temperature
(
void
__iomem
*
addr
,
int
id
)
{
return
hi3660_thermal_step_to_temp
(
readl
(
addr
+
HI3660_TEMP
(
id
)));
}
/*
* Temperature configuration register - Sensor selection
*
* Bits [19:12]
*
* 0x0: local sensor (default)
* 0x1: remote sensor 1 (ACPU cluster 1)
* 0x2: remote sensor 2 (ACPU cluster 0)
* 0x3: remote sensor 3 (G3D)
*/
static
inline
void
hi6220_thermal_sensor_select
(
void
__iomem
*
addr
,
int
sensor
)
{
writel
((
readl
(
addr
+
HI6220_TEMP0_CFG
)
&
~
HI6220_TEMP0_CFG_SS_MSK
)
|
(
sensor
<<
12
),
addr
+
HI6220_TEMP0_CFG
);
}
/*
* Temperature configuration register - Hdak conversion polling interval
*
* Bits [5:4]
*
* 0x0 : 0.768 ms
* 0x1 : 6.144 ms
* 0x2 : 49.152 ms
* 0x3 : 393.216 ms
*/
static
inline
void
hi6220_thermal_hdak_set
(
void
__iomem
*
addr
,
int
value
)
{
writel
((
readl
(
addr
+
HI6220_TEMP0_CFG
)
&
~
HI6220_TEMP0_CFG_HDAK_MSK
)
|
(
value
<<
4
),
addr
+
HI6220_TEMP0_CFG
);
}
static
int
hi6220_thermal_irq_handler
(
struct
hisi_thermal_data
*
data
)
{
hi6220_thermal_alarm_clear
(
data
->
regs
,
1
);
return
0
;
}
static
int
hi3660_thermal_irq_handler
(
struct
hisi_thermal_data
*
data
)
{
hi3660_thermal_alarm_clear
(
data
->
regs
,
data
->
sensor
.
id
,
1
);
return
0
;
}
static
int
hi6220_thermal_get_temp
(
struct
hisi_thermal_data
*
data
)
{
return
hi6220_thermal_get_temperature
(
data
->
regs
);
}
static
int
hi3660_thermal_get_temp
(
struct
hisi_thermal_data
*
data
)
{
return
hi3660_thermal_get_temperature
(
data
->
regs
,
data
->
sensor
.
id
);
}
static
int
hi6220_thermal_disable_sensor
(
struct
hisi_thermal_data
*
data
)
{
/* disable sensor module */
hi6220_thermal_enable
(
data
->
regs
,
0
);
hi6220_thermal_alarm_enable
(
data
->
regs
,
0
);
hi6220_thermal_reset_enable
(
data
->
regs
,
0
);
clk_disable_unprepare
(
data
->
clk
);
return
0
;
}
static
int
hi3660_thermal_disable_sensor
(
struct
hisi_thermal_data
*
data
)
{
/* disable sensor module */
hi3660_thermal_alarm_enable
(
data
->
regs
,
data
->
sensor
.
id
,
0
);
return
0
;
}
static
int
hi6220_thermal_enable_sensor
(
struct
hisi_thermal_data
*
data
)
{
struct
hisi_thermal_sensor
*
sensor
=
&
data
->
sensor
;
int
ret
;
/* enable clock for tsensor */
ret
=
clk_prepare_enable
(
data
->
clk
);
if
(
ret
)
return
ret
;
/* disable module firstly */
writel
(
0x0
,
data
->
regs
+
TEMP0_RST_MSK
);
writel
(
0x0
,
data
->
regs
+
TEMP0_EN
);
hi6220_thermal_reset_enable
(
data
->
regs
,
0
);
hi6220_thermal_enable
(
data
->
regs
,
0
);
/* select sensor id */
writel
((
sensor
->
id
<<
12
),
data
->
regs
+
TEMP0_CFG
);
hi6220_thermal_sensor_select
(
data
->
regs
,
sensor
->
id
);
/* setting the hdak time */
hi6220_thermal_hdak_set
(
data
->
regs
,
0
);
/* setting lag value between current temp and the threshold */
hi6220_thermal_set_lag
(
data
->
regs
,
HI6220_TEMP_LAG
);
/* enable for interrupt */
writel
(
_temp_to_step
(
sensor
->
thres_temp
)
|
0x0FFFFFF00
,
data
->
regs
+
TEMP0_TH
);
hi6220_thermal_alarm_set
(
data
->
regs
,
sensor
->
thres_temp
);
writel
(
_temp_to_step
(
HISI_TEMP_RESET
),
data
->
regs
+
TEMP0_RST_TH
);
hi6220_thermal_reset_set
(
data
->
regs
,
HI6220_TEMP_RESET
);
/* enable module */
writel
(
0x1
,
data
->
regs
+
TEMP0_RST_MSK
);
writel
(
0x1
,
data
->
regs
+
TEMP0_EN
);
writel
(
0x0
,
data
->
regs
+
TEMP0_INT_CLR
);
writel
(
0x1
,
data
->
regs
+
TEMP0_INT_EN
);
hi6220_thermal_reset_enable
(
data
->
regs
,
1
);
hi6220_thermal_enable
(
data
->
regs
,
1
);
usleep_range
(
3000
,
5000
);
hi6220_thermal_alarm_clear
(
data
->
regs
,
0
);
hi6220_thermal_alarm_enable
(
data
->
regs
,
1
);
mutex_unlock
(
&
data
->
thermal_lock
)
;
return
0
;
}
static
void
hisi_thermal_dis
able_sensor
(
struct
hisi_thermal_data
*
data
)
static
int
hi3660_thermal_en
able_sensor
(
struct
hisi_thermal_data
*
data
)
{
mutex_lock
(
&
data
->
thermal_lock
);
unsigned
int
value
;
struct
hisi_thermal_sensor
*
sensor
=
&
data
->
sensor
;
/* disable sensor module */
writel
(
0x0
,
data
->
regs
+
TEMP0_INT_EN
);
writel
(
0x0
,
data
->
regs
+
TEMP0_RST_MSK
);
writel
(
0x0
,
data
->
regs
+
TEMP0_EN
);
/* disable interrupt */
hi3660_thermal_alarm_enable
(
data
->
regs
,
sensor
->
id
,
0
);
mutex_unlock
(
&
data
->
thermal_lock
);
}
/* setting lag value between current temp and the threshold */
hi3660_thermal_set_lag
(
data
->
regs
,
sensor
->
id
,
HI3660_TEMP_LAG
);
static
int
hisi_thermal_get_temp
(
void
*
_sensor
,
int
*
temp
)
{
struct
hisi_thermal_sensor
*
sensor
=
_sensor
;
struct
hisi_thermal_data
*
data
=
sensor
->
thermal
;
/* set interrupt threshold */
value
=
hi3660_thermal_temp_to_step
(
sensor
->
thres_temp
);
hi3660_thermal_alarm_set
(
data
->
regs
,
sensor
->
id
,
value
);
int
sensor_id
=
-
1
,
i
;
long
max_temp
=
0
;
/* enable interrupt */
hi3660_thermal_alarm_clear
(
data
->
regs
,
sensor
->
id
,
1
);
hi3660_thermal_alarm_enable
(
data
->
regs
,
sensor
->
id
,
1
);
*
temp
=
hisi_thermal_get_sensor_temp
(
data
,
sensor
);
return
0
;
}
sensor
->
sensor_temp
=
*
temp
;
static
int
hi6220_thermal_probe
(
struct
hisi_thermal_data
*
data
)
{
struct
platform_device
*
pdev
=
data
->
pdev
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
resource
*
res
;
int
ret
;
for
(
i
=
0
;
i
<
HISI_MAX_SENSORS
;
i
++
)
{
if
(
!
data
->
sensors
[
i
].
tzd
)
continue
;
data
->
get_temp
=
hi6220_thermal_get_temp
;
data
->
enable_sensor
=
hi6220_thermal_enable_sensor
;
data
->
disable_sensor
=
hi6220_thermal_disable_sensor
;
data
->
irq_handler
=
hi6220_thermal_irq_handler
;
if
(
data
->
sensors
[
i
].
sensor_temp
>=
max_temp
)
{
max_temp
=
data
->
sensors
[
i
].
sensor_temp
;
sensor_id
=
i
;
}
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
data
->
regs
=
devm_ioremap_resource
(
dev
,
res
);
if
(
IS_ERR
(
data
->
regs
))
{
dev_err
(
dev
,
"failed to get io address
\n
"
);
return
PTR_ERR
(
data
->
regs
);
}
/* If no sensor has been enabled, then skip to enable irq */
if
(
sensor_id
==
-
1
)
return
0
;
mutex_lock
(
&
data
->
thermal_lock
);
data
->
irq_bind_sensor
=
sensor_id
;
mutex_unlock
(
&
data
->
thermal_lock
);
dev_dbg
(
&
data
->
pdev
->
dev
,
"id=%d, irq=%d, temp=%d, thres=%d
\n
"
,
sensor
->
id
,
data
->
irq_enabled
,
*
temp
,
sensor
->
thres_temp
);
/*
* Bind irq to sensor for two cases:
* Reenable alarm IRQ if temperature below threshold;
* if irq has been enabled, always set it;
*/
if
(
data
->
irq_enabled
)
{
hisi_thermal_enable_bind_irq_sensor
(
data
);
return
0
;
data
->
clk
=
devm_clk_get
(
dev
,
"thermal_clk"
);
if
(
IS_ERR
(
data
->
clk
))
{
ret
=
PTR_ERR
(
data
->
clk
);
if
(
ret
!=
-
EPROBE_DEFER
)
dev_err
(
dev
,
"failed to get thermal clk: %d
\n
"
,
ret
);
return
ret
;
}
if
(
max_temp
<
sensor
->
thres_temp
)
{
data
->
irq_enabled
=
true
;
hisi_thermal_enable_bind_irq_sensor
(
data
)
;
enable_irq
(
data
->
irq
);
}
data
->
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
data
->
irq
<
0
)
return
data
->
irq
;
data
->
sensor
.
id
=
HI6220_DEFAULT_SENSOR
;
return
0
;
}
static
const
struct
thermal_zone_of_device_ops
hisi_of_thermal_ops
=
{
.
get_temp
=
hisi_thermal_get_temp
,
};
static
int
hi3660_thermal_probe
(
struct
hisi_thermal_data
*
data
)
{
struct
platform_device
*
pdev
=
data
->
pdev
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
resource
*
res
;
data
->
get_temp
=
hi3660_thermal_get_temp
;
data
->
enable_sensor
=
hi3660_thermal_enable_sensor
;
data
->
disable_sensor
=
hi3660_thermal_disable_sensor
;
data
->
irq_handler
=
hi3660_thermal_irq_handler
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
data
->
regs
=
devm_ioremap_resource
(
dev
,
res
);
if
(
IS_ERR
(
data
->
regs
))
{
dev_err
(
dev
,
"failed to get io address
\n
"
);
return
PTR_ERR
(
data
->
regs
);
}
static
irqreturn_t
hisi_thermal_alarm_irq
(
int
irq
,
void
*
dev
)
data
->
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
data
->
irq
<
0
)
return
data
->
irq
;
data
->
sensor
.
id
=
HI3660_DEFAULT_SENSOR
;
return
0
;
}
static
int
hisi_thermal_get_temp
(
void
*
__data
,
int
*
temp
)
{
struct
hisi_thermal_data
*
data
=
dev
;
struct
hisi_thermal_data
*
data
=
__data
;
struct
hisi_thermal_sensor
*
sensor
=
&
data
->
sensor
;
disable_irq_nosync
(
irq
);
data
->
irq_enabled
=
false
;
*
temp
=
data
->
get_temp
(
data
);
return
IRQ_WAKE_THREAD
;
dev_dbg
(
&
data
->
pdev
->
dev
,
"id=%d, temp=%d, thres=%d
\n
"
,
sensor
->
id
,
*
temp
,
sensor
->
thres_temp
);
return
0
;
}
static
const
struct
thermal_zone_of_device_ops
hisi_of_thermal_ops
=
{
.
get_temp
=
hisi_thermal_get_temp
,
};
static
irqreturn_t
hisi_thermal_alarm_irq_thread
(
int
irq
,
void
*
dev
)
{
struct
hisi_thermal_data
*
data
=
dev
;
struct
hisi_thermal_sensor
*
sensor
;
int
i
;
struct
hisi_thermal_sensor
*
sensor
=
&
data
->
sensor
;
int
temp
=
0
;
mutex_lock
(
&
data
->
thermal_lock
);
sensor
=
&
data
->
sensors
[
data
->
irq_bind_sensor
];
data
->
irq_handler
(
data
);
dev_crit
(
&
data
->
pdev
->
dev
,
"THERMAL ALARM: T > %d
\n
"
,
sensor
->
thres_temp
/
1000
);
mutex_unlock
(
&
data
->
thermal_lock
);
hisi_thermal_get_temp
(
data
,
&
temp
);
for
(
i
=
0
;
i
<
HISI_MAX_SENSORS
;
i
++
)
{
if
(
!
data
->
sensors
[
i
].
tzd
)
continue
;
if
(
temp
>=
sensor
->
thres_temp
)
{
dev_crit
(
&
data
->
pdev
->
dev
,
"THERMAL ALARM: %d > %d
\n
"
,
temp
,
sensor
->
thres_temp
)
;
thermal_zone_device_update
(
data
->
sensor
s
[
i
]
.
tzd
,
thermal_zone_device_update
(
data
->
sensor
.
tzd
,
THERMAL_EVENT_UNSPECIFIED
);
}
else
{
dev_crit
(
&
data
->
pdev
->
dev
,
"THERMAL ALARM stopped: %d < %d
\n
"
,
temp
,
sensor
->
thres_temp
);
}
return
IRQ_HANDLED
;
...
...
@@ -246,17 +474,14 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev)
static
int
hisi_thermal_register_sensor
(
struct
platform_device
*
pdev
,
struct
hisi_thermal_data
*
data
,
struct
hisi_thermal_sensor
*
sensor
,
int
index
)
struct
hisi_thermal_sensor
*
sensor
)
{
int
ret
,
i
;
const
struct
thermal_trip
*
trip
;
sensor
->
id
=
index
;
sensor
->
thermal
=
data
;
sensor
->
tzd
=
devm_thermal_zone_of_sensor_register
(
&
pdev
->
dev
,
sensor
->
id
,
sensor
,
&
hisi_of_thermal_ops
);
sensor
->
id
,
data
,
&
hisi_of_thermal_ops
);
if
(
IS_ERR
(
sensor
->
tzd
))
{
ret
=
PTR_ERR
(
sensor
->
tzd
);
sensor
->
tzd
=
NULL
;
...
...
@@ -278,7 +503,14 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
}
static
const
struct
of_device_id
of_hisi_thermal_match
[]
=
{
{
.
compatible
=
"hisilicon,tsensor"
},
{
.
compatible
=
"hisilicon,tsensor"
,
.
data
=
hi6220_thermal_probe
},
{
.
compatible
=
"hisilicon,hi3660-tsensor"
,
.
data
=
hi3660_thermal_probe
},
{
/* end */
}
};
MODULE_DEVICE_TABLE
(
of
,
of_hisi_thermal_match
);
...
...
@@ -295,88 +527,63 @@ static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor,
static
int
hisi_thermal_probe
(
struct
platform_device
*
pdev
)
{
struct
hisi_thermal_data
*
data
;
struct
resource
*
res
;
int
i
;
int
const
(
*
platform_probe
)(
struct
hisi_thermal_data
*
)
;
struct
device
*
dev
=
&
pdev
->
dev
;
int
ret
;
data
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
data
),
GFP_KERNEL
);
data
=
devm_kzalloc
(
dev
,
sizeof
(
*
data
),
GFP_KERNEL
);
if
(
!
data
)
return
-
ENOMEM
;
mutex_init
(
&
data
->
thermal_lock
);
data
->
pdev
=
pdev
;
platform_set_drvdata
(
pdev
,
data
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
data
->
regs
=
devm_ioremap_resource
(
&
pdev
->
dev
,
res
);
if
(
IS_ERR
(
data
->
regs
))
{
dev_err
(
&
pdev
->
dev
,
"failed to get io address
\n
"
);
return
PTR_ERR
(
data
->
regs
);
platform_probe
=
of_device_get_match_data
(
dev
);
if
(
!
platform_probe
)
{
dev_err
(
dev
,
"failed to get probe func
\n
"
);
return
-
EINVAL
;
}
data
->
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
data
->
irq
<
0
)
return
data
->
irq
;
ret
=
devm_request_threaded_irq
(
&
pdev
->
dev
,
data
->
irq
,
hisi_thermal_alarm_irq
,
hisi_thermal_alarm_irq_thread
,
0
,
"hisi_thermal"
,
data
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"failed to request alarm irq: %d
\n
"
,
ret
);
ret
=
platform_probe
(
data
);
if
(
ret
)
return
ret
;
}
platform_set_drvdata
(
pdev
,
data
);
data
->
clk
=
devm_clk_get
(
&
pdev
->
dev
,
"thermal_clk"
);
if
(
IS_ERR
(
data
->
clk
))
{
ret
=
PTR_ERR
(
data
->
clk
);
if
(
ret
!=
-
EPROBE_DEFER
)
dev_err
(
&
pdev
->
dev
,
"failed to get thermal clk: %d
\n
"
,
ret
);
ret
=
hisi_thermal_register_sensor
(
pdev
,
data
,
&
data
->
sensor
);
if
(
ret
)
{
dev_err
(
dev
,
"failed to register thermal sensor: %d
\n
"
,
ret
);
return
ret
;
}
/* enable clock for thermal */
ret
=
clk_prepare_enable
(
data
->
clk
);
ret
=
data
->
enable_sensor
(
data
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to enable thermal clk
: %d
\n
"
,
ret
);
dev_err
(
dev
,
"Failed to setup the sensor
: %d
\n
"
,
ret
);
return
ret
;
}
hisi_thermal_enable_bind_irq_sensor
(
data
);
irq_get_irqchip_state
(
data
->
irq
,
IRQCHIP_STATE_MASKED
,
&
data
->
irq_enabled
);
for
(
i
=
0
;
i
<
HISI_MAX_SENSORS
;
++
i
)
{
ret
=
hisi_thermal_register_sensor
(
pdev
,
data
,
&
data
->
sensors
[
i
],
i
);
if
(
ret
)
dev_err
(
&
pdev
->
dev
,
"failed to register thermal sensor: %d
\n
"
,
ret
);
else
hisi_thermal_toggle_sensor
(
&
data
->
sensors
[
i
],
true
);
if
(
data
->
irq
)
{
ret
=
devm_request_threaded_irq
(
dev
,
data
->
irq
,
NULL
,
hisi_thermal_alarm_irq_thread
,
IRQF_ONESHOT
,
"hisi_thermal"
,
data
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"failed to request alarm irq: %d
\n
"
,
ret
);
return
ret
;
}
}
hisi_thermal_toggle_sensor
(
&
data
->
sensor
,
true
);
return
0
;
}
static
int
hisi_thermal_remove
(
struct
platform_device
*
pdev
)
{
struct
hisi_thermal_data
*
data
=
platform_get_drvdata
(
pdev
);
int
i
;
struct
hisi_thermal_sensor
*
sensor
=
&
data
->
sensor
;
for
(
i
=
0
;
i
<
HISI_MAX_SENSORS
;
i
++
)
{
struct
hisi_thermal_sensor
*
sensor
=
&
data
->
sensors
[
i
];
hisi_thermal_toggle_sensor
(
sensor
,
false
);
if
(
!
sensor
->
tzd
)
continue
;
hisi_thermal_toggle_sensor
(
sensor
,
false
);
}
hisi_thermal_disable_sensor
(
data
);
clk_disable_unprepare
(
data
->
clk
);
data
->
disable_sensor
(
data
);
return
0
;
}
...
...
@@ -386,10 +593,7 @@ static int hisi_thermal_suspend(struct device *dev)
{
struct
hisi_thermal_data
*
data
=
dev_get_drvdata
(
dev
);
hisi_thermal_disable_sensor
(
data
);
data
->
irq_enabled
=
false
;
clk_disable_unprepare
(
data
->
clk
);
data
->
disable_sensor
(
data
);
return
0
;
}
...
...
@@ -397,16 +601,8 @@ static int hisi_thermal_suspend(struct device *dev)
static
int
hisi_thermal_resume
(
struct
device
*
dev
)
{
struct
hisi_thermal_data
*
data
=
dev_get_drvdata
(
dev
);
int
ret
;
ret
=
clk_prepare_enable
(
data
->
clk
);
if
(
ret
)
return
ret
;
data
->
irq_enabled
=
true
;
hisi_thermal_enable_bind_irq_sensor
(
data
);
return
0
;
return
data
->
enable_sensor
(
data
);
}
#endif
...
...
drivers/thermal/imx_thermal.c
View file @
1e032393
...
...
@@ -25,6 +25,7 @@
#include <linux/slab.h>
#include <linux/thermal.h>
#include <linux/types.h>
#include <linux/nvmem-consumer.h>
#define REG_SET 0x4
#define REG_CLR 0x8
...
...
@@ -94,7 +95,7 @@ struct imx_thermal_data {
struct
thermal_cooling_device
*
cdev
;
enum
thermal_device_mode
mode
;
struct
regmap
*
tempmon
;
u32
c1
,
c2
;
/* See formula in imx_
get_sensor_data
() */
u32
c1
,
c2
;
/* See formula in imx_
init_calib
() */
int
temp_passive
;
int
temp_critical
;
int
temp_max
;
...
...
@@ -177,7 +178,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
n_meas
=
(
val
&
TEMPSENSE0_TEMP_CNT_MASK
)
>>
TEMPSENSE0_TEMP_CNT_SHIFT
;
/* See imx_
get_sensor_data
() for formula derivation */
/* See imx_
init_calib
() for formula derivation */
*
temp
=
data
->
c2
-
n_meas
*
data
->
c1
;
/* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
...
...
@@ -346,29 +347,12 @@ static struct thermal_zone_device_ops imx_tz_ops = {
.
set_trip_temp
=
imx_set_trip_temp
,
};
static
int
imx_
get_sensor_data
(
struct
platform_device
*
pdev
)
static
int
imx_
init_calib
(
struct
platform_device
*
pdev
,
u32
val
)
{
struct
imx_thermal_data
*
data
=
platform_get_drvdata
(
pdev
);
struct
regmap
*
map
;
int
t1
,
n1
;
int
ret
;
u32
val
;
u64
temp64
;
map
=
syscon_regmap_lookup_by_phandle
(
pdev
->
dev
.
of_node
,
"fsl,tempmon-data"
);
if
(
IS_ERR
(
map
))
{
ret
=
PTR_ERR
(
map
);
dev_err
(
&
pdev
->
dev
,
"failed to get sensor regmap: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
regmap_read
(
map
,
OCOTP_ANA1
,
&
val
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to read sensor data: %d
\n
"
,
ret
);
return
ret
;
}
if
(
val
==
0
||
val
==
~
0
)
{
dev_err
(
&
pdev
->
dev
,
"invalid sensor calibration data
\n
"
);
return
-
EINVAL
;
...
...
@@ -405,12 +389,12 @@ static int imx_get_sensor_data(struct platform_device *pdev)
data
->
c1
=
temp64
;
data
->
c2
=
n1
*
data
->
c1
+
1000
*
t1
;
/* use OTP for thermal grade */
ret
=
regmap_read
(
map
,
OCOTP_MEM0
,
&
val
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to read temp grade: %d
\n
"
,
ret
);
return
ret
;
}
return
0
;
}
static
void
imx_init_temp_grade
(
struct
platform_device
*
pdev
,
u32
val
)
{
struct
imx_thermal_data
*
data
=
platform_get_drvdata
(
pdev
);
/* The maximum die temp is specified by the Temperature Grade */
switch
((
val
>>
6
)
&
0x3
)
{
...
...
@@ -438,6 +422,55 @@ static int imx_get_sensor_data(struct platform_device *pdev)
*/
data
->
temp_critical
=
data
->
temp_max
-
(
1000
*
5
);
data
->
temp_passive
=
data
->
temp_max
-
(
1000
*
10
);
}
static
int
imx_init_from_tempmon_data
(
struct
platform_device
*
pdev
)
{
struct
regmap
*
map
;
int
ret
;
u32
val
;
map
=
syscon_regmap_lookup_by_phandle
(
pdev
->
dev
.
of_node
,
"fsl,tempmon-data"
);
if
(
IS_ERR
(
map
))
{
ret
=
PTR_ERR
(
map
);
dev_err
(
&
pdev
->
dev
,
"failed to get sensor regmap: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
regmap_read
(
map
,
OCOTP_ANA1
,
&
val
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to read sensor data: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
imx_init_calib
(
pdev
,
val
);
if
(
ret
)
return
ret
;
ret
=
regmap_read
(
map
,
OCOTP_MEM0
,
&
val
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to read sensor data: %d
\n
"
,
ret
);
return
ret
;
}
imx_init_temp_grade
(
pdev
,
val
);
return
0
;
}
static
int
imx_init_from_nvmem_cells
(
struct
platform_device
*
pdev
)
{
int
ret
;
u32
val
;
ret
=
nvmem_cell_read_u32
(
&
pdev
->
dev
,
"calib"
,
&
val
);
if
(
ret
)
return
ret
;
imx_init_calib
(
pdev
,
val
);
ret
=
nvmem_cell_read_u32
(
&
pdev
->
dev
,
"temp_grade"
,
&
val
);
if
(
ret
)
return
ret
;
imx_init_temp_grade
(
pdev
,
val
);
return
0
;
}
...
...
@@ -514,10 +547,21 @@ static int imx_thermal_probe(struct platform_device *pdev)
platform_set_drvdata
(
pdev
,
data
);
ret
=
imx_get_sensor_data
(
pdev
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get sensor data
\n
"
);
return
ret
;
if
(
of_find_property
(
pdev
->
dev
.
of_node
,
"nvmem-cells"
,
NULL
))
{
ret
=
imx_init_from_nvmem_cells
(
pdev
);
if
(
ret
==
-
EPROBE_DEFER
)
return
ret
;
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to init from nvmem: %d
\n
"
,
ret
);
return
ret
;
}
}
else
{
ret
=
imx_init_from_tempmon_data
(
pdev
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to init from from fsl,tempmon-data
\n
"
);
return
ret
;
}
}
/* Make sure sensor is in known good state for measurements */
...
...
drivers/thermal/int340x_thermal/processor_thermal_device.c
View file @
1e032393
...
...
@@ -30,6 +30,10 @@
/* Skylake thermal reporting device */
#define PCI_DEVICE_ID_PROC_SKL_THERMAL 0x1903
/* CannonLake thermal reporting device */
#define PCI_DEVICE_ID_PROC_CNL_THERMAL 0x5a03
#define PCI_DEVICE_ID_PROC_CFL_THERMAL 0x3E83
/* Braswell thermal reporting device */
#define PCI_DEVICE_ID_PROC_BSW_THERMAL 0x22DC
...
...
@@ -461,6 +465,8 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_PROC_BXT1_THERMAL
)},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_PROC_BXTX_THERMAL
)},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_PROC_BXTP_THERMAL
)},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_PROC_CNL_THERMAL
)},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_PROC_CFL_THERMAL
)},
{
0
,
},
};
...
...
drivers/thermal/intel_bxt_pmic_thermal.c
View file @
1e032393
...
...
@@ -166,7 +166,7 @@ static irqreturn_t pmic_thermal_irq_handler(int irq, void *data)
struct
pmic_thermal_data
*
td
;
struct
intel_soc_pmic
*
pmic
;
struct
regmap
*
regmap
;
u8
reg_val
,
mask
,
irq_stat
,
trip
;
u8
reg_val
,
mask
,
irq_stat
;
u16
reg
,
evt_stat_reg
;
int
i
,
j
,
ret
;
...
...
@@ -201,7 +201,6 @@ static irqreturn_t pmic_thermal_irq_handler(int irq, void *data)
if
(
regmap_read
(
regmap
,
evt_stat_reg
,
&
ret
))
return
IRQ_HANDLED
;
trip
=
td
->
maps
[
i
].
trip_config
[
j
].
trip_num
;
tzd
=
thermal_zone_get_zone_by_name
(
td
->
maps
[
i
].
handle
);
if
(
!
IS_ERR
(
tzd
))
thermal_zone_device_update
(
tzd
,
...
...
drivers/thermal/intel_pch_thermal.c
View file @
1e032393
...
...
@@ -30,6 +30,8 @@
#define PCH_THERMAL_DID_WPT 0x9CA4
/* Wildcat Point */
#define PCH_THERMAL_DID_SKL 0x9D31
/* Skylake PCH */
#define PCH_THERMAL_DID_SKL_H 0xA131
/* Skylake PCH 100 series */
#define PCH_THERMAL_DID_CNL 0x9Df9
/* CNL PCH */
#define PCH_THERMAL_DID_CNL_H 0xA379
/* CNL-H PCH */
/* Wildcat Point-LP PCH Thermal registers */
#define WPT_TEMP 0x0000
/* Temperature */
...
...
@@ -278,6 +280,7 @@ enum board_ids {
board_hsw
,
board_wpt
,
board_skl
,
board_cnl
,
};
static
const
struct
board_info
{
...
...
@@ -296,6 +299,10 @@ static const struct board_info {
.
name
=
"pch_skylake"
,
.
ops
=
&
pch_dev_ops_wpt
,
},
[
board_cnl
]
=
{
.
name
=
"pch_cannonlake"
,
.
ops
=
&
pch_dev_ops_wpt
,
},
};
static
int
intel_pch_thermal_probe
(
struct
pci_dev
*
pdev
,
...
...
@@ -398,6 +405,10 @@ static const struct pci_device_id intel_pch_thermal_id[] = {
.
driver_data
=
board_skl
,
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCH_THERMAL_DID_SKL_H
),
.
driver_data
=
board_skl
,
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCH_THERMAL_DID_CNL
),
.
driver_data
=
board_cnl
,
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCH_THERMAL_DID_CNL_H
),
.
driver_data
=
board_cnl
,
},
{
0
,
},
};
MODULE_DEVICE_TABLE
(
pci
,
intel_pch_thermal_id
);
...
...
drivers/thermal/intel_powerclamp.c
View file @
1e032393
...
...
@@ -675,13 +675,13 @@ static int __init powerclamp_probe(void)
{
if
(
!
x86_match_cpu
(
intel_powerclamp_ids
))
{
pr_err
(
"CPU does not support MWAIT"
);
pr_err
(
"CPU does not support MWAIT
\n
"
);
return
-
ENODEV
;
}
/* The goal for idle time alignment is to achieve package cstate. */
if
(
!
has_pkg_state_counter
())
{
pr_info
(
"No package C-state available"
);
pr_info
(
"No package C-state available
\n
"
);
return
-
ENODEV
;
}
...
...
drivers/thermal/qcom-spmi-temp-alarm.c
View file @
1e032393
...
...
@@ -125,7 +125,7 @@ static int qpnp_tm_get_temp(void *data, int *temp)
if
(
!
temp
)
return
-
EINVAL
;
if
(
IS_ERR
(
chip
->
adc
)
)
{
if
(
!
chip
->
adc
)
{
ret
=
qpnp_tm_update_temp_no_adc
(
chip
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -224,67 +224,53 @@ static int qpnp_tm_probe(struct platform_device *pdev)
return
irq
;
/* ADC based measurements are optional */
chip
->
adc
=
iio_channel_get
(
&
pdev
->
dev
,
"thermal"
);
if
(
PTR_ERR
(
chip
->
adc
)
==
-
EPROBE_DEFER
)
return
PTR_ERR
(
chip
->
adc
);
chip
->
adc
=
devm_iio_channel_get
(
&
pdev
->
dev
,
"thermal"
);
if
(
IS_ERR
(
chip
->
adc
))
{
ret
=
PTR_ERR
(
chip
->
adc
);
chip
->
adc
=
NULL
;
if
(
ret
==
-
EPROBE_DEFER
)
return
ret
;
}
chip
->
base
=
res
;
ret
=
qpnp_tm_read
(
chip
,
QPNP_TM_REG_TYPE
,
&
type
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"could not read type
\n
"
);
goto
fail
;
return
ret
;
}
ret
=
qpnp_tm_read
(
chip
,
QPNP_TM_REG_SUBTYPE
,
&
subtype
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"could not read subtype
\n
"
);
goto
fail
;
return
ret
;
}
if
(
type
!=
QPNP_TM_TYPE
||
subtype
!=
QPNP_TM_SUBTYPE
)
{
dev_err
(
&
pdev
->
dev
,
"invalid type 0x%02x or subtype 0x%02x
\n
"
,
type
,
subtype
);
ret
=
-
ENODEV
;
goto
fail
;
return
-
ENODEV
;
}
ret
=
qpnp_tm_init
(
chip
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"init failed
\n
"
);
goto
fail
;
return
ret
;
}
ret
=
devm_request_threaded_irq
(
&
pdev
->
dev
,
irq
,
NULL
,
qpnp_tm_isr
,
IRQF_ONESHOT
,
node
->
name
,
chip
);
if
(
ret
<
0
)
goto
fail
;
return
ret
;
chip
->
tz_dev
=
devm_thermal_zone_of_sensor_register
(
&
pdev
->
dev
,
0
,
chip
,
&
qpnp_tm_sensor_ops
);
if
(
IS_ERR
(
chip
->
tz_dev
))
{
dev_err
(
&
pdev
->
dev
,
"failed to register sensor
\n
"
);
ret
=
PTR_ERR
(
chip
->
tz_dev
);
goto
fail
;
return
PTR_ERR
(
chip
->
tz_dev
);
}
return
0
;
fail:
if
(
!
IS_ERR
(
chip
->
adc
))
iio_channel_release
(
chip
->
adc
);
return
ret
;
}
static
int
qpnp_tm_remove
(
struct
platform_device
*
pdev
)
{
struct
qpnp_tm_chip
*
chip
=
dev_get_drvdata
(
&
pdev
->
dev
);
if
(
!
IS_ERR
(
chip
->
adc
))
iio_channel_release
(
chip
->
adc
);
return
0
;
}
static
const
struct
of_device_id
qpnp_tm_match_table
[]
=
{
...
...
@@ -299,7 +285,6 @@ static struct platform_driver qpnp_tm_driver = {
.
of_match_table
=
qpnp_tm_match_table
,
},
.
probe
=
qpnp_tm_probe
,
.
remove
=
qpnp_tm_remove
,
};
module_platform_driver
(
qpnp_tm_driver
);
...
...
drivers/thermal/rcar_gen3_thermal.c
View file @
1e032393
...
...
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock.h>
#include <linux/sys_soc.h>
#include <linux/thermal.h>
#include "thermal_core.h"
...
...
@@ -90,10 +91,6 @@ struct rcar_gen3_thermal_priv {
struct
rcar_gen3_thermal_tsc
*
tscs
[
TSC_MAX_NUM
];
unsigned
int
num_tscs
;
spinlock_t
lock
;
/* Protect interrupts on and off */
const
struct
rcar_gen3_thermal_data
*
data
;
};
struct
rcar_gen3_thermal_data
{
void
(
*
thermal_init
)(
struct
rcar_gen3_thermal_tsc
*
tsc
);
};
...
...
@@ -278,7 +275,12 @@ static irqreturn_t rcar_gen3_thermal_irq_thread(int irq, void *data)
return
IRQ_HANDLED
;
}
static
void
r8a7795_thermal_init
(
struct
rcar_gen3_thermal_tsc
*
tsc
)
static
const
struct
soc_device_attribute
r8a7795es1
[]
=
{
{
.
soc_id
=
"r8a7795"
,
.
revision
=
"ES1.*"
},
{
/* sentinel */
}
};
static
void
rcar_gen3_thermal_init_r8a7795es1
(
struct
rcar_gen3_thermal_tsc
*
tsc
)
{
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_CTSR
,
CTSR_THBGR
);
rcar_gen3_thermal_write
(
tsc
,
REG_GEN3_CTSR
,
0x0
);
...
...
@@ -303,7 +305,7 @@ static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
usleep_range
(
1000
,
2000
);
}
static
void
r
8a7796
_thermal_init
(
struct
rcar_gen3_thermal_tsc
*
tsc
)
static
void
r
car_gen3
_thermal_init
(
struct
rcar_gen3_thermal_tsc
*
tsc
)
{
u32
reg_val
;
...
...
@@ -324,17 +326,9 @@ static void r8a7796_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
usleep_range
(
1000
,
2000
);
}
static
const
struct
rcar_gen3_thermal_data
r8a7795_data
=
{
.
thermal_init
=
r8a7795_thermal_init
,
};
static
const
struct
rcar_gen3_thermal_data
r8a7796_data
=
{
.
thermal_init
=
r8a7796_thermal_init
,
};
static
const
struct
of_device_id
rcar_gen3_thermal_dt_ids
[]
=
{
{
.
compatible
=
"renesas,r8a7795-thermal"
,
.
data
=
&
r8a7795_data
},
{
.
compatible
=
"renesas,r8a7796-thermal"
,
.
data
=
&
r8a7796_data
},
{
.
compatible
=
"renesas,r8a7795-thermal"
,
},
{
.
compatible
=
"renesas,r8a7796-thermal"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
rcar_gen3_thermal_dt_ids
);
...
...
@@ -371,7 +365,9 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
if
(
!
priv
)
return
-
ENOMEM
;
priv
->
data
=
of_device_get_match_data
(
dev
);
priv
->
thermal_init
=
rcar_gen3_thermal_init
;
if
(
soc_device_match
(
r8a7795es1
))
priv
->
thermal_init
=
rcar_gen3_thermal_init_r8a7795es1
;
spin_lock_init
(
&
priv
->
lock
);
...
...
@@ -423,7 +419,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
priv
->
tscs
[
i
]
=
tsc
;
priv
->
data
->
thermal_init
(
tsc
);
priv
->
thermal_init
(
tsc
);
rcar_gen3_thermal_calc_coefs
(
&
tsc
->
coef
,
ptat
,
thcode
[
i
]);
zone
=
devm_thermal_zone_of_sensor_register
(
dev
,
i
,
tsc
,
...
...
@@ -476,7 +472,7 @@ static int __maybe_unused rcar_gen3_thermal_resume(struct device *dev)
for
(
i
=
0
;
i
<
priv
->
num_tscs
;
i
++
)
{
struct
rcar_gen3_thermal_tsc
*
tsc
=
priv
->
tscs
[
i
];
priv
->
data
->
thermal_init
(
tsc
);
priv
->
thermal_init
(
tsc
);
rcar_gen3_thermal_set_trips
(
tsc
,
tsc
->
low
,
tsc
->
high
);
}
...
...
drivers/thermal/rockchip_thermal.c
View file @
1e032393
...
...
@@ -242,6 +242,45 @@ struct tsadc_table {
int
temp
;
};
static
const
struct
tsadc_table
rv1108_table
[]
=
{
{
0
,
-
40000
},
{
374
,
-
40000
},
{
382
,
-
35000
},
{
389
,
-
30000
},
{
397
,
-
25000
},
{
405
,
-
20000
},
{
413
,
-
15000
},
{
421
,
-
10000
},
{
429
,
-
5000
},
{
436
,
0
},
{
444
,
5000
},
{
452
,
10000
},
{
460
,
15000
},
{
468
,
20000
},
{
476
,
25000
},
{
483
,
30000
},
{
491
,
35000
},
{
499
,
40000
},
{
507
,
45000
},
{
515
,
50000
},
{
523
,
55000
},
{
531
,
60000
},
{
539
,
65000
},
{
547
,
70000
},
{
555
,
75000
},
{
562
,
80000
},
{
570
,
85000
},
{
578
,
90000
},
{
586
,
95000
},
{
594
,
100000
},
{
602
,
105000
},
{
610
,
110000
},
{
618
,
115000
},
{
626
,
120000
},
{
634
,
125000
},
{
TSADCV2_DATA_MASK
,
125000
},
};
static
const
struct
tsadc_table
rk3228_code_table
[]
=
{
{
0
,
-
40000
},
{
588
,
-
40000
},
...
...
@@ -779,6 +818,30 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
writel_relaxed
(
val
,
regs
+
TSADCV2_INT_EN
);
}
static
const
struct
rockchip_tsadc_chip
rv1108_tsadc_data
=
{
.
chn_id
[
SENSOR_CPU
]
=
0
,
/* cpu sensor is channel 0 */
.
chn_num
=
1
,
/* one channel for tsadc */
.
tshut_mode
=
TSHUT_MODE_GPIO
,
/* default TSHUT via GPIO give PMIC */
.
tshut_polarity
=
TSHUT_LOW_ACTIVE
,
/* default TSHUT LOW ACTIVE */
.
tshut_temp
=
95000
,
.
initialize
=
rk_tsadcv2_initialize
,
.
irq_ack
=
rk_tsadcv3_irq_ack
,
.
control
=
rk_tsadcv3_control
,
.
get_temp
=
rk_tsadcv2_get_temp
,
.
set_alarm_temp
=
rk_tsadcv2_alarm_temp
,
.
set_tshut_temp
=
rk_tsadcv2_tshut_temp
,
.
set_tshut_mode
=
rk_tsadcv2_tshut_mode
,
.
table
=
{
.
id
=
rv1108_table
,
.
length
=
ARRAY_SIZE
(
rv1108_table
),
.
data_mask
=
TSADCV2_DATA_MASK
,
.
mode
=
ADC_INCREMENT
,
},
};
static
const
struct
rockchip_tsadc_chip
rk3228_tsadc_data
=
{
.
chn_id
[
SENSOR_CPU
]
=
0
,
/* cpu sensor is channel 0 */
.
chn_num
=
1
,
/* one channel for tsadc */
...
...
@@ -927,6 +990,10 @@ static const struct rockchip_tsadc_chip rk3399_tsadc_data = {
};
static
const
struct
of_device_id
of_rockchip_thermal_match
[]
=
{
{
.
compatible
=
"rockchip,rv1108-tsadc"
,
.
data
=
(
void
*
)
&
rv1108_tsadc_data
,
},
{
.
compatible
=
"rockchip,rk3228-tsadc"
,
.
data
=
(
void
*
)
&
rk3228_tsadc_data
,
...
...
drivers/thermal/step_wise.c
View file @
1e032393
...
...
@@ -31,8 +31,7 @@
* If the temperature is higher than a trip point,
* a. if the trend is THERMAL_TREND_RAISING, use higher cooling
* state for this trip point
* b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
* state for this trip point
* b. if the trend is THERMAL_TREND_DROPPING, do nothing
* c. if the trend is THERMAL_TREND_RAISE_FULL, use upper limit
* for this trip point
* d. if the trend is THERMAL_TREND_DROP_FULL, use lower limit
...
...
@@ -94,9 +93,11 @@ static unsigned long get_target_state(struct thermal_instance *instance,
if
(
!
throttle
)
next_target
=
THERMAL_NO_TARGET
;
}
else
{
next_target
=
cur_state
-
1
;
if
(
next_target
>
instance
->
upper
)
next_target
=
instance
->
upper
;
if
(
!
throttle
)
{
next_target
=
cur_state
-
1
;
if
(
next_target
>
instance
->
upper
)
next_target
=
instance
->
upper
;
}
}
break
;
case
THERMAL_TREND_DROP_FULL
:
...
...
drivers/thermal/tegra/soctherm.c
View file @
1e032393
...
...
@@ -483,7 +483,7 @@ static int throttrip_program(struct device *dev,
unsigned
int
throt
;
u32
r
,
reg_off
;
if
(
!
dev
||
!
sg
||
!
stc
||
!
stc
->
init
)
if
(
!
sg
||
!
stc
||
!
stc
->
init
)
return
-
EINVAL
;
temp
=
enforce_temp_range
(
dev
,
trip_temp
)
/
ts
->
soc
->
thresh_grain
;
...
...
drivers/thermal/thermal-generic-adc.c
View file @
1e032393
...
...
@@ -126,37 +126,22 @@ static int gadc_thermal_probe(struct platform_device *pdev)
gti
->
dev
=
&
pdev
->
dev
;
platform_set_drvdata
(
pdev
,
gti
);
gti
->
channel
=
iio_channel_get
(
&
pdev
->
dev
,
"sensor-channel"
);
gti
->
channel
=
devm_
iio_channel_get
(
&
pdev
->
dev
,
"sensor-channel"
);
if
(
IS_ERR
(
gti
->
channel
))
{
ret
=
PTR_ERR
(
gti
->
channel
);
dev_err
(
&
pdev
->
dev
,
"IIO channel not found: %d
\n
"
,
ret
);
return
ret
;
}
gti
->
tz_dev
=
thermal_zone_of_sensor_register
(
&
pdev
->
dev
,
0
,
gti
,
&
gadc_thermal_ops
);
gti
->
tz_dev
=
devm_thermal_zone_of_sensor_register
(
&
pdev
->
dev
,
0
,
gti
,
&
gadc_thermal_ops
);
if
(
IS_ERR
(
gti
->
tz_dev
))
{
ret
=
PTR_ERR
(
gti
->
tz_dev
);
dev_err
(
&
pdev
->
dev
,
"Thermal zone sensor register failed: %d
\n
"
,
ret
);
goto
sensor_fail
;
return
ret
;
}
return
0
;
sensor_fail:
iio_channel_release
(
gti
->
channel
);
return
ret
;
}
static
int
gadc_thermal_remove
(
struct
platform_device
*
pdev
)
{
struct
gadc_thermal_info
*
gti
=
platform_get_drvdata
(
pdev
);
thermal_zone_of_sensor_unregister
(
&
pdev
->
dev
,
gti
->
tz_dev
);
iio_channel_release
(
gti
->
channel
);
return
0
;
}
...
...
@@ -172,7 +157,6 @@ static struct platform_driver gadc_thermal_driver = {
.
of_match_table
=
of_adc_thermal_match
,
},
.
probe
=
gadc_thermal_probe
,
.
remove
=
gadc_thermal_remove
,
};
module_platform_driver
(
gadc_thermal_driver
);
...
...
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
View file @
1e032393
...
...
@@ -278,7 +278,8 @@ int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id)
if
(
data
)
{
cpufreq_cooling_unregister
(
data
->
cool_dev
);
cpufreq_cpu_put
(
data
->
policy
);
if
(
data
->
policy
)
cpufreq_cpu_put
(
data
->
policy
);
}
return
0
;
...
...
tools/thermal/tmon/Makefile
View file @
1e032393
# We need this for the "cc-option" macro.
include
../../../scripts/Kbuild.include
VERSION
=
1.0
BINDIR
=
usr/bin
WARNFLAGS
=
-Wall
-Wshadow
-W
-Wformat
-Wimplicit-function-declaration
-Wimplicit-int
CFLAGS
+=
-O1
${WARNFLAGS}
-fstack-protector
CC
=
$(CROSS_COMPILE)
gcc
CFLAGS
+=
-O1
${WARNFLAGS}
# Add "-fstack-protector" only if toolchain supports it.
CFLAGS
+=
$(
call
cc-option,-fstack-protector
)
CC
?=
$(CROSS_COMPILE)
gcc
PKG_CONFIG
?=
pkg-config
CFLAGS
+=
-D
VERSION
=
\"
$(VERSION)
\"
LDFLAGS
+=
...
...
@@ -18,12 +24,12 @@ STATIC := --static
endif
TMON_LIBS
=
-lm
-lpthread
TMON_LIBS
+=
$(
shell
pkg-config
--libs
$(STATIC)
panelw ncursesw 2> /dev/null
||
\
pkg-config
--libs
$(STATIC)
panel ncurses 2> /dev/null
||
\
TMON_LIBS
+=
$(
shell
$(PKG_CONFIG)
--libs
$(STATIC)
panelw ncursesw 2> /dev/null
||
\
$(PKG_CONFIG)
--libs
$(STATIC)
panel ncurses 2> /dev/null
||
\
echo
-lpanel
-lncurses
)
CFLAGS
+=
$(
shell
pkg-config
--cflags
$(STATIC)
panelw ncursesw 2> /dev/null
||
\
pkg-config
--cflags
$(STATIC)
panel ncurses 2> /dev/null
)
CFLAGS
+=
$(
shell
$(PKG_CONFIG)
--cflags
$(STATIC)
panelw ncursesw 2> /dev/null
||
\
$(PKG_CONFIG)
--cflags
$(STATIC)
panel ncurses 2> /dev/null
)
OBJS
=
tmon.o tui.o sysfs.o pid.o
OBJS
+=
...
...
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