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
fe9ba5bc
Commit
fe9ba5bc
authored
7 years ago
by
Zhang Rui
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'imx-nvmem' into thermal-soc
parents
b2fd708f
531fcdeb
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
82 additions
and
30 deletions
+82
-30
Documentation/devicetree/bindings/thermal/imx-thermal.txt
Documentation/devicetree/bindings/thermal/imx-thermal.txt
+7
-0
drivers/thermal/Kconfig
drivers/thermal/Kconfig
+1
-0
drivers/thermal/imx_thermal.c
drivers/thermal/imx_thermal.c
+74
-30
No files found.
Documentation/devicetree/bindings/thermal/imx-thermal.txt
View file @
fe9ba5bc
...
...
@@ -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.
...
...
This diff is collapsed.
Click to expand it.
drivers/thermal/Kconfig
View file @
fe9ba5bc
...
...
@@ -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
...
...
This diff is collapsed.
Click to expand it.
drivers/thermal/imx_thermal.c
View file @
fe9ba5bc
...
...
@@ -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 */
...
...
This diff is collapsed.
Click to expand it.
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