diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-06 18:04:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-06 18:04:58 -0500 |
commit | 3f551e3cefcf119c1d397ed8b5633d9fa73fca0a (patch) | |
tree | 6f9c643122a35bbf5468e07b6fb8766af62af8e6 | |
parent | b46dc8ae17a427c50c00241898832807576fd28a (diff) | |
parent | 134f4010799a30acd969e603985c27b9f3e6f58d (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management updates from Zhang Rui:
- fix a race condition issue in power allocator governor (Yi Zeng).
- add support for AP806 and CP110 in armada thermal driver, together
with several improvements (Baruch Siach, Miquel Raynal)
- add support for r8z7743 in rcar thermal driver (Biju Das)
- convert thermal core to use new hwmon API to avoid warning (Fabio
Estevam)
- small fixes and cleanups in thermal core and x86_pkg_thermal,
int3400_thermal, hisi_thermal, mtk_thermal and imx_thermal drivers
(Pravin Shedge, Geert Uytterhoeven, Alexey Khoroshilov, Brian Bian,
Matthias Brugger, Nicolin Chen, Uwe Kleine-König)
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: (25 commits)
thermal: thermal_hwmon: Convert to hwmon_device_register_with_info()
thermal/x86 pkg temp: Remove debugfs_create_u32() casts
thermal: int3400_thermal: fix error handling in int3400_thermal_probe()
thermal/drivers/hisi: Remove bogus const from function return type
thermal: armada: Give meaningful names to the thermal zones
thermal: armada: Wait sensors validity before exiting the init callback
thermal: armada: Change sensors trim default value
thermal: armada: Update Kconfig and module description
thermal: armada: Add support for Armada CP110
thermal: armada: Add support for Armada AP806
thermal: armada: Use real status register name
thermal: armada: Clarify control registers accesses
thermal: armada: Simplify the check of the validity bit
thermal: armada: Use msleep for long delays
dt-bindings: thermal: Describe Armada AP806 and CP110
dt-bindings: thermal: rcar: Add device tree support for r8a7743
thermal: mtk: Cleanup unused defines
thermal: imx: update to new formula according to NXP AN5215
thermal: imx: use consistent style to write temperatures
thermal: imx: improve comments describing algorithm for temp calculation
...
-rw-r--r-- | Documentation/devicetree/bindings/thermal/armada-thermal.txt | 37 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/thermal/rcar-thermal.txt | 1 | ||||
-rw-r--r-- | drivers/thermal/Kconfig | 4 | ||||
-rw-r--r-- | drivers/thermal/armada_thermal.c | 253 | ||||
-rw-r--r-- | drivers/thermal/hisi_thermal.c | 2 | ||||
-rw-r--r-- | drivers/thermal/imx_thermal.c | 74 | ||||
-rw-r--r-- | drivers/thermal/int340x_thermal/int3400_thermal.c | 12 | ||||
-rw-r--r-- | drivers/thermal/mtk_thermal.c | 9 | ||||
-rw-r--r-- | drivers/thermal/of-thermal.c | 1 | ||||
-rw-r--r-- | drivers/thermal/power_allocator.c | 2 | ||||
-rw-r--r-- | drivers/thermal/tegra/soctherm.c | 103 | ||||
-rw-r--r-- | drivers/thermal/thermal_hwmon.c | 20 | ||||
-rw-r--r-- | drivers/thermal/x86_pkg_temp_thermal.c | 4 |
13 files changed, 312 insertions, 210 deletions
diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt index 24aacf8948c5..e0d013a2e66d 100644 --- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt | |||
@@ -2,22 +2,35 @@ | |||
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | 4 | ||
5 | - compatible: Should be set to one of the following: | 5 | - compatible: Should be set to one of the following: |
6 | marvell,armada370-thermal | 6 | * marvell,armada370-thermal |
7 | marvell,armada375-thermal | 7 | * marvell,armada375-thermal |
8 | marvell,armada380-thermal | 8 | * marvell,armada380-thermal |
9 | marvell,armadaxp-thermal | 9 | * marvell,armadaxp-thermal |
10 | * marvell,armada-ap806-thermal | ||
11 | * marvell,armada-cp110-thermal | ||
10 | 12 | ||
11 | - reg: Device's register space. | 13 | - reg: Device's register space. |
12 | Two entries are expected, see the examples below. | 14 | Two entries are expected, see the examples below. The first one points |
13 | The first one is required for the sensor register; | 15 | to the status register (4B). The second one points to the control |
14 | the second one is required for the control register | 16 | registers (8B). |
15 | to be used for sensor initialization (a.k.a. calibration). | 17 | Note: The compatibles marvell,armada370-thermal, |
18 | marvell,armada380-thermal, and marvell,armadaxp-thermal must point to | ||
19 | "control MSB/control 1", with size of 4 (deprecated binding), or point | ||
20 | to "control LSB/control 0" with size of 8 (current binding). All other | ||
21 | compatibles must point to "control LSB/control 0" with size of 8. | ||
16 | 22 | ||
17 | Example: | 23 | Examples: |
18 | 24 | ||
25 | /* Legacy bindings */ | ||
19 | thermal@d0018300 { | 26 | thermal@d0018300 { |
20 | compatible = "marvell,armada370-thermal"; | 27 | compatible = "marvell,armada370-thermal"; |
21 | reg = <0xd0018300 0x4 | 28 | reg = <0xd0018300 0x4 |
22 | 0xd0018304 0x4>; | 29 | 0xd0018304 0x4>; |
23 | }; | 30 | }; |
31 | |||
32 | ap_thermal: thermal@6f8084 { | ||
33 | compatible = "marvell,armada-ap806-thermal"; | ||
34 | reg = <0x6f808C 0x4>, | ||
35 | <0x6f8084 0x8>; | ||
36 | }; | ||
diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt index a8e52c8ccfcc..349e635f2d87 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt | |||
@@ -6,6 +6,7 @@ Required properties: | |||
6 | "renesas,rcar-thermal" (without thermal-zone) as fallback. | 6 | "renesas,rcar-thermal" (without thermal-zone) as fallback. |
7 | Examples with soctypes are: | 7 | Examples with soctypes are: |
8 | - "renesas,thermal-r8a73a4" (R-Mobile APE6) | 8 | - "renesas,thermal-r8a73a4" (R-Mobile APE6) |
9 | - "renesas,thermal-r8a7743" (RZ/G1M) | ||
9 | - "renesas,thermal-r8a7779" (R-Car H1) | 10 | - "renesas,thermal-r8a7779" (R-Car H1) |
10 | - "renesas,thermal-r8a7790" (R-Car H2) | 11 | - "renesas,thermal-r8a7790" (R-Car H2) |
11 | - "renesas,thermal-r8a7791" (R-Car M2-W) | 12 | - "renesas,thermal-r8a7791" (R-Car M2-W) |
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 315ae2926e20..b6adc54b96f1 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig | |||
@@ -301,13 +301,13 @@ config DB8500_THERMAL | |||
301 | thermal zone if trip points reached. | 301 | thermal zone if trip points reached. |
302 | 302 | ||
303 | config ARMADA_THERMAL | 303 | config ARMADA_THERMAL |
304 | tristate "Armada 370/XP thermal management" | 304 | tristate "Marvell EBU Armada SoCs thermal management" |
305 | depends on ARCH_MVEBU || COMPILE_TEST | 305 | depends on ARCH_MVEBU || COMPILE_TEST |
306 | depends on HAS_IOMEM | 306 | depends on HAS_IOMEM |
307 | depends on OF | 307 | depends on OF |
308 | help | 308 | help |
309 | Enable this option if you want to have support for thermal management | 309 | Enable this option if you want to have support for thermal management |
310 | controller present in Armada 370 and Armada XP SoC. | 310 | controller present in Marvell EBU Armada SoCs (370,375,XP,38x,7K,8K). |
311 | 311 | ||
312 | config DA9062_THERMAL | 312 | config DA9062_THERMAL |
313 | tristate "DA9062/DA9061 Dialog Semiconductor thermal driver" | 313 | tristate "DA9062/DA9061 Dialog Semiconductor thermal driver" |
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index 706d74798cbe..4c275ec10ac5 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Marvell Armada 370/XP thermal sensor driver | 2 | * Marvell EBU Armada SoCs thermal sensor driver |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Marvell | 4 | * Copyright (C) 2013 Marvell |
5 | * | 5 | * |
@@ -23,8 +23,7 @@ | |||
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/of_device.h> | 24 | #include <linux/of_device.h> |
25 | #include <linux/thermal.h> | 25 | #include <linux/thermal.h> |
26 | 26 | #include <linux/iopoll.h> | |
27 | #define THERMAL_VALID_MASK 0x1 | ||
28 | 27 | ||
29 | /* Thermal Manager Control and Status Register */ | 28 | /* Thermal Manager Control and Status Register */ |
30 | #define PMU_TDC0_SW_RST_MASK (0x1 << 1) | 29 | #define PMU_TDC0_SW_RST_MASK (0x1 << 1) |
@@ -39,14 +38,38 @@ | |||
39 | #define A375_UNIT_CONTROL_MASK 0x7 | 38 | #define A375_UNIT_CONTROL_MASK 0x7 |
40 | #define A375_READOUT_INVERT BIT(15) | 39 | #define A375_READOUT_INVERT BIT(15) |
41 | #define A375_HW_RESETn BIT(8) | 40 | #define A375_HW_RESETn BIT(8) |
42 | #define A380_HW_RESET BIT(8) | 41 | |
42 | /* Legacy bindings */ | ||
43 | #define LEGACY_CONTROL_MEM_LEN 0x4 | ||
44 | |||
45 | /* Current bindings with the 2 control registers under the same memory area */ | ||
46 | #define LEGACY_CONTROL1_OFFSET 0x0 | ||
47 | #define CONTROL0_OFFSET 0x0 | ||
48 | #define CONTROL1_OFFSET 0x4 | ||
49 | |||
50 | /* Errata fields */ | ||
51 | #define CONTROL0_TSEN_TC_TRIM_MASK 0x7 | ||
52 | #define CONTROL0_TSEN_TC_TRIM_VAL 0x3 | ||
53 | |||
54 | /* TSEN refers to the temperature sensors within the AP */ | ||
55 | #define CONTROL0_TSEN_START BIT(0) | ||
56 | #define CONTROL0_TSEN_RESET BIT(1) | ||
57 | #define CONTROL0_TSEN_ENABLE BIT(2) | ||
58 | |||
59 | /* EXT_TSEN refers to the external temperature sensors, out of the AP */ | ||
60 | #define CONTROL1_EXT_TSEN_SW_RESET BIT(7) | ||
61 | #define CONTROL1_EXT_TSEN_HW_RESETn BIT(8) | ||
62 | |||
63 | #define STATUS_POLL_PERIOD_US 1000 | ||
64 | #define STATUS_POLL_TIMEOUT_US 100000 | ||
43 | 65 | ||
44 | struct armada_thermal_data; | 66 | struct armada_thermal_data; |
45 | 67 | ||
46 | /* Marvell EBU Thermal Sensor Dev Structure */ | 68 | /* Marvell EBU Thermal Sensor Dev Structure */ |
47 | struct armada_thermal_priv { | 69 | struct armada_thermal_priv { |
48 | void __iomem *sensor; | 70 | void __iomem *status; |
49 | void __iomem *control; | 71 | void __iomem *control0; |
72 | void __iomem *control1; | ||
50 | struct armada_thermal_data *data; | 73 | struct armada_thermal_data *data; |
51 | }; | 74 | }; |
52 | 75 | ||
@@ -59,107 +82,142 @@ struct armada_thermal_data { | |||
59 | bool (*is_valid)(struct armada_thermal_priv *); | 82 | bool (*is_valid)(struct armada_thermal_priv *); |
60 | 83 | ||
61 | /* Formula coeficients: temp = (b - m * reg) / div */ | 84 | /* Formula coeficients: temp = (b - m * reg) / div */ |
62 | unsigned long coef_b; | 85 | s64 coef_b; |
63 | unsigned long coef_m; | 86 | s64 coef_m; |
64 | unsigned long coef_div; | 87 | u32 coef_div; |
65 | bool inverted; | 88 | bool inverted; |
89 | bool signed_sample; | ||
66 | 90 | ||
67 | /* Register shift and mask to access the sensor temperature */ | 91 | /* Register shift and mask to access the sensor temperature */ |
68 | unsigned int temp_shift; | 92 | unsigned int temp_shift; |
69 | unsigned int temp_mask; | 93 | unsigned int temp_mask; |
70 | unsigned int is_valid_shift; | 94 | u32 is_valid_bit; |
95 | bool needs_control0; | ||
71 | }; | 96 | }; |
72 | 97 | ||
73 | static void armadaxp_init_sensor(struct platform_device *pdev, | 98 | static void armadaxp_init_sensor(struct platform_device *pdev, |
74 | struct armada_thermal_priv *priv) | 99 | struct armada_thermal_priv *priv) |
75 | { | 100 | { |
76 | unsigned long reg; | 101 | u32 reg; |
77 | 102 | ||
78 | reg = readl_relaxed(priv->control); | 103 | reg = readl_relaxed(priv->control1); |
79 | reg |= PMU_TDC0_OTF_CAL_MASK; | 104 | reg |= PMU_TDC0_OTF_CAL_MASK; |
80 | writel(reg, priv->control); | 105 | writel(reg, priv->control1); |
81 | 106 | ||
82 | /* Reference calibration value */ | 107 | /* Reference calibration value */ |
83 | reg &= ~PMU_TDC0_REF_CAL_CNT_MASK; | 108 | reg &= ~PMU_TDC0_REF_CAL_CNT_MASK; |
84 | reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS); | 109 | reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS); |
85 | writel(reg, priv->control); | 110 | writel(reg, priv->control1); |
86 | 111 | ||
87 | /* Reset the sensor */ | 112 | /* Reset the sensor */ |
88 | reg = readl_relaxed(priv->control); | 113 | reg = readl_relaxed(priv->control1); |
89 | writel((reg | PMU_TDC0_SW_RST_MASK), priv->control); | 114 | writel((reg | PMU_TDC0_SW_RST_MASK), priv->control1); |
90 | 115 | ||
91 | writel(reg, priv->control); | 116 | writel(reg, priv->control1); |
92 | 117 | ||
93 | /* Enable the sensor */ | 118 | /* Enable the sensor */ |
94 | reg = readl_relaxed(priv->sensor); | 119 | reg = readl_relaxed(priv->status); |
95 | reg &= ~PMU_TM_DISABLE_MASK; | 120 | reg &= ~PMU_TM_DISABLE_MASK; |
96 | writel(reg, priv->sensor); | 121 | writel(reg, priv->status); |
97 | } | 122 | } |
98 | 123 | ||
99 | static void armada370_init_sensor(struct platform_device *pdev, | 124 | static void armada370_init_sensor(struct platform_device *pdev, |
100 | struct armada_thermal_priv *priv) | 125 | struct armada_thermal_priv *priv) |
101 | { | 126 | { |
102 | unsigned long reg; | 127 | u32 reg; |
103 | 128 | ||
104 | reg = readl_relaxed(priv->control); | 129 | reg = readl_relaxed(priv->control1); |
105 | reg |= PMU_TDC0_OTF_CAL_MASK; | 130 | reg |= PMU_TDC0_OTF_CAL_MASK; |
106 | writel(reg, priv->control); | 131 | writel(reg, priv->control1); |
107 | 132 | ||
108 | /* Reference calibration value */ | 133 | /* Reference calibration value */ |
109 | reg &= ~PMU_TDC0_REF_CAL_CNT_MASK; | 134 | reg &= ~PMU_TDC0_REF_CAL_CNT_MASK; |
110 | reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS); | 135 | reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS); |
111 | writel(reg, priv->control); | 136 | writel(reg, priv->control1); |
112 | 137 | ||
113 | reg &= ~PMU_TDC0_START_CAL_MASK; | 138 | reg &= ~PMU_TDC0_START_CAL_MASK; |
114 | writel(reg, priv->control); | 139 | writel(reg, priv->control1); |
115 | 140 | ||
116 | mdelay(10); | 141 | msleep(10); |
117 | } | 142 | } |
118 | 143 | ||
119 | static void armada375_init_sensor(struct platform_device *pdev, | 144 | static void armada375_init_sensor(struct platform_device *pdev, |
120 | struct armada_thermal_priv *priv) | 145 | struct armada_thermal_priv *priv) |
121 | { | 146 | { |
122 | unsigned long reg; | 147 | u32 reg; |
123 | 148 | ||
124 | reg = readl(priv->control + 4); | 149 | reg = readl(priv->control1); |
125 | reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT); | 150 | reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT); |
126 | reg &= ~A375_READOUT_INVERT; | 151 | reg &= ~A375_READOUT_INVERT; |
127 | reg &= ~A375_HW_RESETn; | 152 | reg &= ~A375_HW_RESETn; |
128 | 153 | ||
129 | writel(reg, priv->control + 4); | 154 | writel(reg, priv->control1); |
130 | mdelay(20); | 155 | msleep(20); |
131 | 156 | ||
132 | reg |= A375_HW_RESETn; | 157 | reg |= A375_HW_RESETn; |
133 | writel(reg, priv->control + 4); | 158 | writel(reg, priv->control1); |
134 | mdelay(50); | 159 | msleep(50); |
160 | } | ||
161 | |||
162 | static void armada_wait_sensor_validity(struct armada_thermal_priv *priv) | ||
163 | { | ||
164 | u32 reg; | ||
165 | |||
166 | readl_relaxed_poll_timeout(priv->status, reg, | ||
167 | reg & priv->data->is_valid_bit, | ||
168 | STATUS_POLL_PERIOD_US, | ||
169 | STATUS_POLL_TIMEOUT_US); | ||
135 | } | 170 | } |
136 | 171 | ||
137 | static void armada380_init_sensor(struct platform_device *pdev, | 172 | static void armada380_init_sensor(struct platform_device *pdev, |
138 | struct armada_thermal_priv *priv) | 173 | struct armada_thermal_priv *priv) |
139 | { | 174 | { |
140 | unsigned long reg = readl_relaxed(priv->control); | 175 | u32 reg = readl_relaxed(priv->control1); |
141 | 176 | ||
142 | /* Reset hardware once */ | 177 | /* Disable the HW/SW reset */ |
143 | if (!(reg & A380_HW_RESET)) { | 178 | reg |= CONTROL1_EXT_TSEN_HW_RESETn; |
144 | reg |= A380_HW_RESET; | 179 | reg &= ~CONTROL1_EXT_TSEN_SW_RESET; |
145 | writel(reg, priv->control); | 180 | writel(reg, priv->control1); |
146 | mdelay(10); | 181 | |
182 | /* Set Tsen Tc Trim to correct default value (errata #132698) */ | ||
183 | if (priv->control0) { | ||
184 | reg = readl_relaxed(priv->control0); | ||
185 | reg &= ~CONTROL0_TSEN_TC_TRIM_MASK; | ||
186 | reg |= CONTROL0_TSEN_TC_TRIM_VAL; | ||
187 | writel(reg, priv->control0); | ||
147 | } | 188 | } |
189 | |||
190 | /* Wait the sensors to be valid or the core will warn the user */ | ||
191 | armada_wait_sensor_validity(priv); | ||
192 | } | ||
193 | |||
194 | static void armada_ap806_init_sensor(struct platform_device *pdev, | ||
195 | struct armada_thermal_priv *priv) | ||
196 | { | ||
197 | u32 reg; | ||
198 | |||
199 | reg = readl_relaxed(priv->control0); | ||
200 | reg &= ~CONTROL0_TSEN_RESET; | ||
201 | reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE; | ||
202 | writel(reg, priv->control0); | ||
203 | |||
204 | /* Wait the sensors to be valid or the core will warn the user */ | ||
205 | armada_wait_sensor_validity(priv); | ||
148 | } | 206 | } |
149 | 207 | ||
150 | static bool armada_is_valid(struct armada_thermal_priv *priv) | 208 | static bool armada_is_valid(struct armada_thermal_priv *priv) |
151 | { | 209 | { |
152 | unsigned long reg = readl_relaxed(priv->sensor); | 210 | u32 reg = readl_relaxed(priv->status); |
153 | 211 | ||
154 | return (reg >> priv->data->is_valid_shift) & THERMAL_VALID_MASK; | 212 | return reg & priv->data->is_valid_bit; |
155 | } | 213 | } |
156 | 214 | ||
157 | static int armada_get_temp(struct thermal_zone_device *thermal, | 215 | static int armada_get_temp(struct thermal_zone_device *thermal, |
158 | int *temp) | 216 | int *temp) |
159 | { | 217 | { |
160 | struct armada_thermal_priv *priv = thermal->devdata; | 218 | struct armada_thermal_priv *priv = thermal->devdata; |
161 | unsigned long reg; | 219 | u32 reg, div; |
162 | unsigned long m, b, div; | 220 | s64 sample, b, m; |
163 | 221 | ||
164 | /* Valid check */ | 222 | /* Valid check */ |
165 | if (priv->data->is_valid && !priv->data->is_valid(priv)) { | 223 | if (priv->data->is_valid && !priv->data->is_valid(priv)) { |
@@ -168,8 +226,13 @@ static int armada_get_temp(struct thermal_zone_device *thermal, | |||
168 | return -EIO; | 226 | return -EIO; |
169 | } | 227 | } |
170 | 228 | ||
171 | reg = readl_relaxed(priv->sensor); | 229 | reg = readl_relaxed(priv->status); |
172 | reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask; | 230 | reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask; |
231 | if (priv->data->signed_sample) | ||
232 | /* The most significant bit is the sign bit */ | ||
233 | sample = sign_extend32(reg, fls(priv->data->temp_mask) - 1); | ||
234 | else | ||
235 | sample = reg; | ||
173 | 236 | ||
174 | /* Get formula coeficients */ | 237 | /* Get formula coeficients */ |
175 | b = priv->data->coef_b; | 238 | b = priv->data->coef_b; |
@@ -177,9 +240,10 @@ static int armada_get_temp(struct thermal_zone_device *thermal, | |||
177 | div = priv->data->coef_div; | 240 | div = priv->data->coef_div; |
178 | 241 | ||
179 | if (priv->data->inverted) | 242 | if (priv->data->inverted) |
180 | *temp = ((m * reg) - b) / div; | 243 | *temp = div_s64((m * sample) - b, div); |
181 | else | 244 | else |
182 | *temp = (b - (m * reg)) / div; | 245 | *temp = div_s64(b - (m * sample), div); |
246 | |||
183 | return 0; | 247 | return 0; |
184 | } | 248 | } |
185 | 249 | ||
@@ -191,45 +255,73 @@ static const struct armada_thermal_data armadaxp_data = { | |||
191 | .init_sensor = armadaxp_init_sensor, | 255 | .init_sensor = armadaxp_init_sensor, |
192 | .temp_shift = 10, | 256 | .temp_shift = 10, |
193 | .temp_mask = 0x1ff, | 257 | .temp_mask = 0x1ff, |
194 | .coef_b = 3153000000UL, | 258 | .coef_b = 3153000000ULL, |
195 | .coef_m = 10000000UL, | 259 | .coef_m = 10000000ULL, |
196 | .coef_div = 13825, | 260 | .coef_div = 13825, |
197 | }; | 261 | }; |
198 | 262 | ||
199 | static const struct armada_thermal_data armada370_data = { | 263 | static const struct armada_thermal_data armada370_data = { |
200 | .is_valid = armada_is_valid, | 264 | .is_valid = armada_is_valid, |
201 | .init_sensor = armada370_init_sensor, | 265 | .init_sensor = armada370_init_sensor, |
202 | .is_valid_shift = 9, | 266 | .is_valid_bit = BIT(9), |
203 | .temp_shift = 10, | 267 | .temp_shift = 10, |
204 | .temp_mask = 0x1ff, | 268 | .temp_mask = 0x1ff, |
205 | .coef_b = 3153000000UL, | 269 | .coef_b = 3153000000ULL, |
206 | .coef_m = 10000000UL, | 270 | .coef_m = 10000000ULL, |
207 | .coef_div = 13825, | 271 | .coef_div = 13825, |
208 | }; | 272 | }; |
209 | 273 | ||
210 | static const struct armada_thermal_data armada375_data = { | 274 | static const struct armada_thermal_data armada375_data = { |
211 | .is_valid = armada_is_valid, | 275 | .is_valid = armada_is_valid, |
212 | .init_sensor = armada375_init_sensor, | 276 | .init_sensor = armada375_init_sensor, |
213 | .is_valid_shift = 10, | 277 | .is_valid_bit = BIT(10), |
214 | .temp_shift = 0, | 278 | .temp_shift = 0, |
215 | .temp_mask = 0x1ff, | 279 | .temp_mask = 0x1ff, |
216 | .coef_b = 3171900000UL, | 280 | .coef_b = 3171900000ULL, |
217 | .coef_m = 10000000UL, | 281 | .coef_m = 10000000ULL, |
218 | .coef_div = 13616, | 282 | .coef_div = 13616, |
283 | .needs_control0 = true, | ||
219 | }; | 284 | }; |
220 | 285 | ||
221 | static const struct armada_thermal_data armada380_data = { | 286 | static const struct armada_thermal_data armada380_data = { |
222 | .is_valid = armada_is_valid, | 287 | .is_valid = armada_is_valid, |
223 | .init_sensor = armada380_init_sensor, | 288 | .init_sensor = armada380_init_sensor, |
224 | .is_valid_shift = 10, | 289 | .is_valid_bit = BIT(10), |
225 | .temp_shift = 0, | 290 | .temp_shift = 0, |
226 | .temp_mask = 0x3ff, | 291 | .temp_mask = 0x3ff, |
227 | .coef_b = 1172499100UL, | 292 | .coef_b = 1172499100ULL, |
228 | .coef_m = 2000096UL, | 293 | .coef_m = 2000096ULL, |
229 | .coef_div = 4201, | 294 | .coef_div = 4201, |
230 | .inverted = true, | 295 | .inverted = true, |
231 | }; | 296 | }; |
232 | 297 | ||
298 | static const struct armada_thermal_data armada_ap806_data = { | ||
299 | .is_valid = armada_is_valid, | ||
300 | .init_sensor = armada_ap806_init_sensor, | ||
301 | .is_valid_bit = BIT(16), | ||
302 | .temp_shift = 0, | ||
303 | .temp_mask = 0x3ff, | ||
304 | .coef_b = -150000LL, | ||
305 | .coef_m = 423ULL, | ||
306 | .coef_div = 1, | ||
307 | .inverted = true, | ||
308 | .signed_sample = true, | ||
309 | .needs_control0 = true, | ||
310 | }; | ||
311 | |||
312 | static const struct armada_thermal_data armada_cp110_data = { | ||
313 | .is_valid = armada_is_valid, | ||
314 | .init_sensor = armada380_init_sensor, | ||
315 | .is_valid_bit = BIT(10), | ||
316 | .temp_shift = 0, | ||
317 | .temp_mask = 0x3ff, | ||
318 | .coef_b = 1172499100ULL, | ||
319 | .coef_m = 2000096ULL, | ||
320 | .coef_div = 4201, | ||
321 | .inverted = true, | ||
322 | .needs_control0 = true, | ||
323 | }; | ||
324 | |||
233 | static const struct of_device_id armada_thermal_id_table[] = { | 325 | static const struct of_device_id armada_thermal_id_table[] = { |
234 | { | 326 | { |
235 | .compatible = "marvell,armadaxp-thermal", | 327 | .compatible = "marvell,armadaxp-thermal", |
@@ -248,6 +340,14 @@ static const struct of_device_id armada_thermal_id_table[] = { | |||
248 | .data = &armada380_data, | 340 | .data = &armada380_data, |
249 | }, | 341 | }, |
250 | { | 342 | { |
343 | .compatible = "marvell,armada-ap806-thermal", | ||
344 | .data = &armada_ap806_data, | ||
345 | }, | ||
346 | { | ||
347 | .compatible = "marvell,armada-cp110-thermal", | ||
348 | .data = &armada_cp110_data, | ||
349 | }, | ||
350 | { | ||
251 | /* sentinel */ | 351 | /* sentinel */ |
252 | }, | 352 | }, |
253 | }; | 353 | }; |
@@ -255,6 +355,7 @@ MODULE_DEVICE_TABLE(of, armada_thermal_id_table); | |||
255 | 355 | ||
256 | static int armada_thermal_probe(struct platform_device *pdev) | 356 | static int armada_thermal_probe(struct platform_device *pdev) |
257 | { | 357 | { |
358 | void __iomem *control = NULL; | ||
258 | struct thermal_zone_device *thermal; | 359 | struct thermal_zone_device *thermal; |
259 | const struct of_device_id *match; | 360 | const struct of_device_id *match; |
260 | struct armada_thermal_priv *priv; | 361 | struct armada_thermal_priv *priv; |
@@ -269,20 +370,40 @@ static int armada_thermal_probe(struct platform_device *pdev) | |||
269 | return -ENOMEM; | 370 | return -ENOMEM; |
270 | 371 | ||
271 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 372 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
272 | priv->sensor = devm_ioremap_resource(&pdev->dev, res); | 373 | priv->status = devm_ioremap_resource(&pdev->dev, res); |
273 | if (IS_ERR(priv->sensor)) | 374 | if (IS_ERR(priv->status)) |
274 | return PTR_ERR(priv->sensor); | 375 | return PTR_ERR(priv->status); |
275 | 376 | ||
276 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 377 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
277 | priv->control = devm_ioremap_resource(&pdev->dev, res); | 378 | control = devm_ioremap_resource(&pdev->dev, res); |
278 | if (IS_ERR(priv->control)) | 379 | if (IS_ERR(control)) |
279 | return PTR_ERR(priv->control); | 380 | return PTR_ERR(control); |
280 | 381 | ||
281 | priv->data = (struct armada_thermal_data *)match->data; | 382 | priv->data = (struct armada_thermal_data *)match->data; |
383 | |||
384 | /* | ||
385 | * Legacy DT bindings only described "control1" register (also referred | ||
386 | * as "control MSB" on old documentation). New bindings cover | ||
387 | * "control0/control LSB" and "control1/control MSB" registers within | ||
388 | * the same resource, which is then of size 8 instead of 4. | ||
389 | */ | ||
390 | if (resource_size(res) == LEGACY_CONTROL_MEM_LEN) { | ||
391 | /* ->control0 unavailable in this configuration */ | ||
392 | if (priv->data->needs_control0) { | ||
393 | dev_err(&pdev->dev, "No access to control0 register\n"); | ||
394 | return -EINVAL; | ||
395 | } | ||
396 | |||
397 | priv->control1 = control + LEGACY_CONTROL1_OFFSET; | ||
398 | } else { | ||
399 | priv->control0 = control + CONTROL0_OFFSET; | ||
400 | priv->control1 = control + CONTROL1_OFFSET; | ||
401 | } | ||
402 | |||
282 | priv->data->init_sensor(pdev, priv); | 403 | priv->data->init_sensor(pdev, priv); |
283 | 404 | ||
284 | thermal = thermal_zone_device_register("armada_thermal", 0, 0, | 405 | thermal = thermal_zone_device_register(dev_name(&pdev->dev), 0, 0, priv, |
285 | priv, &ops, NULL, 0, 0); | 406 | &ops, NULL, 0, 0); |
286 | if (IS_ERR(thermal)) { | 407 | if (IS_ERR(thermal)) { |
287 | dev_err(&pdev->dev, | 408 | dev_err(&pdev->dev, |
288 | "Failed to register thermal zone device\n"); | 409 | "Failed to register thermal zone device\n"); |
@@ -316,5 +437,5 @@ static struct platform_driver armada_thermal_driver = { | |||
316 | module_platform_driver(armada_thermal_driver); | 437 | module_platform_driver(armada_thermal_driver); |
317 | 438 | ||
318 | MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>"); | 439 | MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>"); |
319 | MODULE_DESCRIPTION("Armada 370/XP thermal driver"); | 440 | MODULE_DESCRIPTION("Marvell EBU Armada SoCs thermal driver"); |
320 | MODULE_LICENSE("GPL v2"); | 441 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index 2d855a96cdd9..761d0559c268 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c | |||
@@ -527,7 +527,7 @@ static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor, | |||
527 | static int hisi_thermal_probe(struct platform_device *pdev) | 527 | static int hisi_thermal_probe(struct platform_device *pdev) |
528 | { | 528 | { |
529 | struct hisi_thermal_data *data; | 529 | struct hisi_thermal_data *data; |
530 | int const (*platform_probe)(struct hisi_thermal_data *); | 530 | int (*platform_probe)(struct hisi_thermal_data *); |
531 | struct device *dev = &pdev->dev; | 531 | struct device *dev = &pdev->dev; |
532 | int ret; | 532 | int ret; |
533 | 533 | ||
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index e7d4ffc3de7f..a67781b7a0b2 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c | |||
@@ -70,10 +70,6 @@ enum imx_thermal_trip { | |||
70 | #define IMX_POLLING_DELAY 2000 /* millisecond */ | 70 | #define IMX_POLLING_DELAY 2000 /* millisecond */ |
71 | #define IMX_PASSIVE_DELAY 1000 | 71 | #define IMX_PASSIVE_DELAY 1000 |
72 | 72 | ||
73 | #define FACTOR0 10000000 | ||
74 | #define FACTOR1 15976 | ||
75 | #define FACTOR2 4297157 | ||
76 | |||
77 | #define TEMPMON_IMX6Q 1 | 73 | #define TEMPMON_IMX6Q 1 |
78 | #define TEMPMON_IMX6SX 2 | 74 | #define TEMPMON_IMX6SX 2 |
79 | 75 | ||
@@ -347,78 +343,74 @@ static struct thermal_zone_device_ops imx_tz_ops = { | |||
347 | .set_trip_temp = imx_set_trip_temp, | 343 | .set_trip_temp = imx_set_trip_temp, |
348 | }; | 344 | }; |
349 | 345 | ||
350 | static int imx_init_calib(struct platform_device *pdev, u32 val) | 346 | static int imx_init_calib(struct platform_device *pdev, u32 ocotp_ana1) |
351 | { | 347 | { |
352 | struct imx_thermal_data *data = platform_get_drvdata(pdev); | 348 | struct imx_thermal_data *data = platform_get_drvdata(pdev); |
353 | int t1, n1; | 349 | int n1; |
354 | u64 temp64; | 350 | u64 temp64; |
355 | 351 | ||
356 | if (val == 0 || val == ~0) { | 352 | if (ocotp_ana1 == 0 || ocotp_ana1 == ~0) { |
357 | dev_err(&pdev->dev, "invalid sensor calibration data\n"); | 353 | dev_err(&pdev->dev, "invalid sensor calibration data\n"); |
358 | return -EINVAL; | 354 | return -EINVAL; |
359 | } | 355 | } |
360 | 356 | ||
361 | /* | 357 | /* |
362 | * Sensor data layout: | 358 | * The sensor is calibrated at 25 °C (aka T1) and the value measured |
363 | * [31:20] - sensor value @ 25C | 359 | * (aka N1) at this temperature is provided in bits [31:20] in the |
364 | * Use universal formula now and only need sensor value @ 25C | 360 | * i.MX's OCOTP value ANA1. |
365 | * slope = 0.4297157 - (0.0015976 * 25C fuse) | 361 | * To find the actual temperature T, the following formula has to be used |
362 | * when reading value n from the sensor: | ||
363 | * | ||
364 | * T = T1 + (N - N1) / (0.4148468 - 0.0015423 * N1) °C + 3.580661 °C | ||
365 | * = [T1' - N1 / (0.4148468 - 0.0015423 * N1) °C] + N / (0.4148468 - 0.0015423 * N1) °C | ||
366 | * = [T1' + N1 / (0.0015423 * N1 - 0.4148468) °C] - N / (0.0015423 * N1 - 0.4148468) °C | ||
367 | * = c2 - c1 * N | ||
368 | * | ||
369 | * with | ||
370 | * | ||
371 | * T1' = 28.580661 °C | ||
372 | * c1 = 1 / (0.0015423 * N1 - 0.4297157) °C | ||
373 | * c2 = T1' + N1 / (0.0015423 * N1 - 0.4148468) °C | ||
374 | * = T1' + N1 * c1 | ||
366 | */ | 375 | */ |
367 | n1 = val >> 20; | 376 | n1 = ocotp_ana1 >> 20; |
368 | t1 = 25; /* t1 always 25C */ | ||
369 | 377 | ||
370 | /* | 378 | temp64 = 10000000; /* use 10^7 as fixed point constant for values in formula */ |
371 | * Derived from linear interpolation: | 379 | temp64 *= 1000; /* to get result in °mC */ |
372 | * slope = 0.4297157 - (0.0015976 * 25C fuse) | 380 | do_div(temp64, 15423 * n1 - 4148468); |
373 | * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0 | ||
374 | * (Nmeas - n1) / (Tmeas - t1) = slope | ||
375 | * We want to reduce this down to the minimum computation necessary | ||
376 | * for each temperature read. Also, we want Tmeas in millicelsius | ||
377 | * and we don't want to lose precision from integer division. So... | ||
378 | * Tmeas = (Nmeas - n1) / slope + t1 | ||
379 | * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1 | ||
380 | * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1 | ||
381 | * Let constant c1 = (-1000 / slope) | ||
382 | * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1 | ||
383 | * Let constant c2 = n1 *c1 + 1000 * t1 | ||
384 | * milli_Tmeas = c2 - Nmeas * c1 | ||
385 | */ | ||
386 | temp64 = FACTOR0; | ||
387 | temp64 *= 1000; | ||
388 | do_div(temp64, FACTOR1 * n1 - FACTOR2); | ||
389 | data->c1 = temp64; | 381 | data->c1 = temp64; |
390 | data->c2 = n1 * data->c1 + 1000 * t1; | 382 | data->c2 = n1 * data->c1 + 28581; |
391 | 383 | ||
392 | return 0; | 384 | return 0; |
393 | } | 385 | } |
394 | 386 | ||
395 | static void imx_init_temp_grade(struct platform_device *pdev, u32 val) | 387 | static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0) |
396 | { | 388 | { |
397 | struct imx_thermal_data *data = platform_get_drvdata(pdev); | 389 | struct imx_thermal_data *data = platform_get_drvdata(pdev); |
398 | 390 | ||
399 | /* The maximum die temp is specified by the Temperature Grade */ | 391 | /* The maximum die temp is specified by the Temperature Grade */ |
400 | switch ((val >> 6) & 0x3) { | 392 | switch ((ocotp_mem0 >> 6) & 0x3) { |
401 | case 0: /* Commercial (0 to 95C) */ | 393 | case 0: /* Commercial (0 to 95 °C) */ |
402 | data->temp_grade = "Commercial"; | 394 | data->temp_grade = "Commercial"; |
403 | data->temp_max = 95000; | 395 | data->temp_max = 95000; |
404 | break; | 396 | break; |
405 | case 1: /* Extended Commercial (-20 to 105C) */ | 397 | case 1: /* Extended Commercial (-20 °C to 105 °C) */ |
406 | data->temp_grade = "Extended Commercial"; | 398 | data->temp_grade = "Extended Commercial"; |
407 | data->temp_max = 105000; | 399 | data->temp_max = 105000; |
408 | break; | 400 | break; |
409 | case 2: /* Industrial (-40 to 105C) */ | 401 | case 2: /* Industrial (-40 °C to 105 °C) */ |
410 | data->temp_grade = "Industrial"; | 402 | data->temp_grade = "Industrial"; |
411 | data->temp_max = 105000; | 403 | data->temp_max = 105000; |
412 | break; | 404 | break; |
413 | case 3: /* Automotive (-40 to 125C) */ | 405 | case 3: /* Automotive (-40 °C to 125 °C) */ |
414 | data->temp_grade = "Automotive"; | 406 | data->temp_grade = "Automotive"; |
415 | data->temp_max = 125000; | 407 | data->temp_max = 125000; |
416 | break; | 408 | break; |
417 | } | 409 | } |
418 | 410 | ||
419 | /* | 411 | /* |
420 | * Set the critical trip point at 5C under max | 412 | * Set the critical trip point at 5 °C under max |
421 | * Set the passive trip point at 10C under max (can change via sysfs) | 413 | * Set the passive trip point at 10 °C under max (changeable via sysfs) |
422 | */ | 414 | */ |
423 | data->temp_critical = data->temp_max - (1000 * 5); | 415 | data->temp_critical = data->temp_max - (1000 * 5); |
424 | data->temp_passive = data->temp_max - (1000 * 10); | 416 | data->temp_passive = data->temp_max - (1000 * 10); |
diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c index 8ee38f55c7f3..e26b01c05e82 100644 --- a/drivers/thermal/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/int340x_thermal/int3400_thermal.c | |||
@@ -211,7 +211,7 @@ static void int3400_notify(acpi_handle handle, | |||
211 | thermal_prop); | 211 | thermal_prop); |
212 | break; | 212 | break; |
213 | default: | 213 | default: |
214 | dev_err(&priv->adev->dev, "Unsupported event [0x%x]\n", event); | 214 | /* Ignore unknown notification codes sent to INT3400 device */ |
215 | break; | 215 | break; |
216 | } | 216 | } |
217 | } | 217 | } |
@@ -319,17 +319,21 @@ static int int3400_thermal_probe(struct platform_device *pdev) | |||
319 | 319 | ||
320 | result = sysfs_create_group(&pdev->dev.kobj, &uuid_attribute_group); | 320 | result = sysfs_create_group(&pdev->dev.kobj, &uuid_attribute_group); |
321 | if (result) | 321 | if (result) |
322 | goto free_zone; | 322 | goto free_rel_misc; |
323 | 323 | ||
324 | result = acpi_install_notify_handler( | 324 | result = acpi_install_notify_handler( |
325 | priv->adev->handle, ACPI_DEVICE_NOTIFY, int3400_notify, | 325 | priv->adev->handle, ACPI_DEVICE_NOTIFY, int3400_notify, |
326 | (void *)priv); | 326 | (void *)priv); |
327 | if (result) | 327 | if (result) |
328 | goto free_zone; | 328 | goto free_sysfs; |
329 | 329 | ||
330 | return 0; | 330 | return 0; |
331 | 331 | ||
332 | free_zone: | 332 | free_sysfs: |
333 | sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group); | ||
334 | free_rel_misc: | ||
335 | if (!priv->rel_misc_dev_res) | ||
336 | acpi_thermal_rel_misc_device_remove(priv->adev->handle); | ||
333 | thermal_zone_device_unregister(priv->thermal); | 337 | thermal_zone_device_unregister(priv->thermal); |
334 | free_art_trt: | 338 | free_art_trt: |
335 | kfree(priv->trts); | 339 | kfree(priv->trts); |
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 1e61c09153c9..c75661a3801a 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c | |||
@@ -32,15 +32,10 @@ | |||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | 33 | ||
34 | /* AUXADC Registers */ | 34 | /* AUXADC Registers */ |
35 | #define AUXADC_CON0_V 0x000 | ||
36 | #define AUXADC_CON1_V 0x004 | ||
37 | #define AUXADC_CON1_SET_V 0x008 | 35 | #define AUXADC_CON1_SET_V 0x008 |
38 | #define AUXADC_CON1_CLR_V 0x00c | 36 | #define AUXADC_CON1_CLR_V 0x00c |
39 | #define AUXADC_CON2_V 0x010 | 37 | #define AUXADC_CON2_V 0x010 |
40 | #define AUXADC_DATA(channel) (0x14 + (channel) * 4) | 38 | #define AUXADC_DATA(channel) (0x14 + (channel) * 4) |
41 | #define AUXADC_MISC_V 0x094 | ||
42 | |||
43 | #define AUXADC_CON1_CHANNEL(x) BIT(x) | ||
44 | 39 | ||
45 | #define APMIXED_SYS_TS_CON1 0x604 | 40 | #define APMIXED_SYS_TS_CON1 0x604 |
46 | 41 | ||
@@ -158,8 +153,6 @@ | |||
158 | /* The number of sensing points per bank */ | 153 | /* The number of sensing points per bank */ |
159 | #define MT2712_NUM_SENSORS_PER_ZONE 4 | 154 | #define MT2712_NUM_SENSORS_PER_ZONE 4 |
160 | 155 | ||
161 | #define THERMAL_NAME "mtk-thermal" | ||
162 | |||
163 | struct mtk_thermal; | 156 | struct mtk_thermal; |
164 | 157 | ||
165 | struct thermal_bank_cfg { | 158 | struct thermal_bank_cfg { |
@@ -765,7 +758,7 @@ static struct platform_driver mtk_thermal_driver = { | |||
765 | .probe = mtk_thermal_probe, | 758 | .probe = mtk_thermal_probe, |
766 | .remove = mtk_thermal_remove, | 759 | .remove = mtk_thermal_remove, |
767 | .driver = { | 760 | .driver = { |
768 | .name = THERMAL_NAME, | 761 | .name = "mtk-thermal", |
769 | .of_match_table = mtk_thermal_of_match, | 762 | .of_match_table = mtk_thermal_of_match, |
770 | }, | 763 | }, |
771 | }; | 764 | }; |
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index d04ec3b9e5ff..e09f0354a4bc 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/err.h> | 30 | #include <linux/err.h> |
31 | #include <linux/export.h> | 31 | #include <linux/export.h> |
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | #include <linux/thermal.h> | ||
34 | 33 | ||
35 | #include "thermal_core.h" | 34 | #include "thermal_core.h" |
36 | 35 | ||
diff --git a/drivers/thermal/power_allocator.c b/drivers/thermal/power_allocator.c index b4d3116cfdaf..3055f9a12a17 100644 --- a/drivers/thermal/power_allocator.c +++ b/drivers/thermal/power_allocator.c | |||
@@ -523,6 +523,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz) | |||
523 | struct thermal_instance *instance; | 523 | struct thermal_instance *instance; |
524 | struct power_allocator_params *params = tz->governor_data; | 524 | struct power_allocator_params *params = tz->governor_data; |
525 | 525 | ||
526 | mutex_lock(&tz->lock); | ||
526 | list_for_each_entry(instance, &tz->thermal_instances, tz_node) { | 527 | list_for_each_entry(instance, &tz->thermal_instances, tz_node) { |
527 | if ((instance->trip != params->trip_max_desired_temperature) || | 528 | if ((instance->trip != params->trip_max_desired_temperature) || |
528 | (!cdev_is_power_actor(instance->cdev))) | 529 | (!cdev_is_power_actor(instance->cdev))) |
@@ -534,6 +535,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz) | |||
534 | mutex_unlock(&instance->cdev->lock); | 535 | mutex_unlock(&instance->cdev->lock); |
535 | thermal_cdev_update(instance->cdev); | 536 | thermal_cdev_update(instance->cdev); |
536 | } | 537 | } |
538 | mutex_unlock(&tz->lock); | ||
537 | } | 539 | } |
538 | 540 | ||
539 | /** | 541 | /** |
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index 075db1de5e53..455b58ce2652 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c | |||
@@ -341,62 +341,6 @@ static int tegra_thermctl_get_temp(void *data, int *out_temp) | |||
341 | return 0; | 341 | return 0; |
342 | } | 342 | } |
343 | 343 | ||
344 | static int | ||
345 | thermtrip_program(struct device *dev, const struct tegra_tsensor_group *sg, | ||
346 | int trip_temp); | ||
347 | static int | ||
348 | throttrip_program(struct device *dev, const struct tegra_tsensor_group *sg, | ||
349 | struct soctherm_throt_cfg *stc, int trip_temp); | ||
350 | static struct soctherm_throt_cfg * | ||
351 | find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name); | ||
352 | |||
353 | static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp) | ||
354 | { | ||
355 | struct tegra_thermctl_zone *zone = data; | ||
356 | struct thermal_zone_device *tz = zone->tz; | ||
357 | struct tegra_soctherm *ts = zone->ts; | ||
358 | const struct tegra_tsensor_group *sg = zone->sg; | ||
359 | struct device *dev = zone->dev; | ||
360 | enum thermal_trip_type type; | ||
361 | int ret; | ||
362 | |||
363 | if (!tz) | ||
364 | return -EINVAL; | ||
365 | |||
366 | ret = tz->ops->get_trip_type(tz, trip, &type); | ||
367 | if (ret) | ||
368 | return ret; | ||
369 | |||
370 | if (type == THERMAL_TRIP_CRITICAL) { | ||
371 | return thermtrip_program(dev, sg, temp); | ||
372 | } else if (type == THERMAL_TRIP_HOT) { | ||
373 | int i; | ||
374 | |||
375 | for (i = 0; i < THROTTLE_SIZE; i++) { | ||
376 | struct thermal_cooling_device *cdev; | ||
377 | struct soctherm_throt_cfg *stc; | ||
378 | |||
379 | if (!ts->throt_cfgs[i].init) | ||
380 | continue; | ||
381 | |||
382 | cdev = ts->throt_cfgs[i].cdev; | ||
383 | if (get_thermal_instance(tz, cdev, trip)) | ||
384 | stc = find_throttle_cfg_by_name(ts, cdev->type); | ||
385 | else | ||
386 | continue; | ||
387 | |||
388 | return throttrip_program(dev, sg, stc, temp); | ||
389 | } | ||
390 | } | ||
391 | |||
392 | return 0; | ||
393 | } | ||
394 | |||
395 | static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = { | ||
396 | .get_temp = tegra_thermctl_get_temp, | ||
397 | .set_trip_temp = tegra_thermctl_set_trip_temp, | ||
398 | }; | ||
399 | |||
400 | /** | 344 | /** |
401 | * enforce_temp_range() - check and enforce temperature range [min, max] | 345 | * enforce_temp_range() - check and enforce temperature range [min, max] |
402 | * @trip_temp: the trip temperature to check | 346 | * @trip_temp: the trip temperature to check |
@@ -527,6 +471,53 @@ find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name) | |||
527 | return NULL; | 471 | return NULL; |
528 | } | 472 | } |
529 | 473 | ||
474 | static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp) | ||
475 | { | ||
476 | struct tegra_thermctl_zone *zone = data; | ||
477 | struct thermal_zone_device *tz = zone->tz; | ||
478 | struct tegra_soctherm *ts = zone->ts; | ||
479 | const struct tegra_tsensor_group *sg = zone->sg; | ||
480 | struct device *dev = zone->dev; | ||
481 | enum thermal_trip_type type; | ||
482 | int ret; | ||
483 | |||
484 | if (!tz) | ||
485 | return -EINVAL; | ||
486 | |||
487 | ret = tz->ops->get_trip_type(tz, trip, &type); | ||
488 | if (ret) | ||
489 | return ret; | ||
490 | |||
491 | if (type == THERMAL_TRIP_CRITICAL) { | ||
492 | return thermtrip_program(dev, sg, temp); | ||
493 | } else if (type == THERMAL_TRIP_HOT) { | ||
494 | int i; | ||
495 | |||
496 | for (i = 0; i < THROTTLE_SIZE; i++) { | ||
497 | struct thermal_cooling_device *cdev; | ||
498 | struct soctherm_throt_cfg *stc; | ||
499 | |||
500 | if (!ts->throt_cfgs[i].init) | ||
501 | continue; | ||
502 | |||
503 | cdev = ts->throt_cfgs[i].cdev; | ||
504 | if (get_thermal_instance(tz, cdev, trip)) | ||
505 | stc = find_throttle_cfg_by_name(ts, cdev->type); | ||
506 | else | ||
507 | continue; | ||
508 | |||
509 | return throttrip_program(dev, sg, stc, temp); | ||
510 | } | ||
511 | } | ||
512 | |||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = { | ||
517 | .get_temp = tegra_thermctl_get_temp, | ||
518 | .set_trip_temp = tegra_thermctl_set_trip_temp, | ||
519 | }; | ||
520 | |||
530 | static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp) | 521 | static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp) |
531 | { | 522 | { |
532 | int ntrips, i, ret; | 523 | int ntrips, i, ret; |
diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c index 541af5946203..c4a508a124dc 100644 --- a/drivers/thermal/thermal_hwmon.c +++ b/drivers/thermal/thermal_hwmon.c | |||
@@ -59,14 +59,6 @@ static LIST_HEAD(thermal_hwmon_list); | |||
59 | static DEFINE_MUTEX(thermal_hwmon_list_lock); | 59 | static DEFINE_MUTEX(thermal_hwmon_list_lock); |
60 | 60 | ||
61 | static ssize_t | 61 | static ssize_t |
62 | name_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
63 | { | ||
64 | struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev); | ||
65 | return sprintf(buf, "%s\n", hwmon->type); | ||
66 | } | ||
67 | static DEVICE_ATTR_RO(name); | ||
68 | |||
69 | static ssize_t | ||
70 | temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) | 62 | temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) |
71 | { | 63 | { |
72 | int temperature; | 64 | int temperature; |
@@ -165,15 +157,12 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) | |||
165 | 157 | ||
166 | INIT_LIST_HEAD(&hwmon->tz_list); | 158 | INIT_LIST_HEAD(&hwmon->tz_list); |
167 | strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH); | 159 | strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH); |
168 | hwmon->device = hwmon_device_register(NULL); | 160 | hwmon->device = hwmon_device_register_with_info(NULL, hwmon->type, |
161 | hwmon, NULL, NULL); | ||
169 | if (IS_ERR(hwmon->device)) { | 162 | if (IS_ERR(hwmon->device)) { |
170 | result = PTR_ERR(hwmon->device); | 163 | result = PTR_ERR(hwmon->device); |
171 | goto free_mem; | 164 | goto free_mem; |
172 | } | 165 | } |
173 | dev_set_drvdata(hwmon->device, hwmon); | ||
174 | result = device_create_file(hwmon->device, &dev_attr_name); | ||
175 | if (result) | ||
176 | goto free_mem; | ||
177 | 166 | ||
178 | register_sys_interface: | 167 | register_sys_interface: |
179 | temp = kzalloc(sizeof(*temp), GFP_KERNEL); | 168 | temp = kzalloc(sizeof(*temp), GFP_KERNEL); |
@@ -222,10 +211,8 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) | |||
222 | free_temp_mem: | 211 | free_temp_mem: |
223 | kfree(temp); | 212 | kfree(temp); |
224 | unregister_name: | 213 | unregister_name: |
225 | if (new_hwmon_device) { | 214 | if (new_hwmon_device) |
226 | device_remove_file(hwmon->device, &dev_attr_name); | ||
227 | hwmon_device_unregister(hwmon->device); | 215 | hwmon_device_unregister(hwmon->device); |
228 | } | ||
229 | free_mem: | 216 | free_mem: |
230 | if (new_hwmon_device) | 217 | if (new_hwmon_device) |
231 | kfree(hwmon); | 218 | kfree(hwmon); |
@@ -267,7 +254,6 @@ void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) | |||
267 | list_del(&hwmon->node); | 254 | list_del(&hwmon->node); |
268 | mutex_unlock(&thermal_hwmon_list_lock); | 255 | mutex_unlock(&thermal_hwmon_list_lock); |
269 | 256 | ||
270 | device_remove_file(hwmon->device, &dev_attr_name); | ||
271 | hwmon_device_unregister(hwmon->device); | 257 | hwmon_device_unregister(hwmon->device); |
272 | kfree(hwmon); | 258 | kfree(hwmon); |
273 | } | 259 | } |
diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c index d93eee2f101b..1a6c88b10a39 100644 --- a/drivers/thermal/x86_pkg_temp_thermal.c +++ b/drivers/thermal/x86_pkg_temp_thermal.c | |||
@@ -96,12 +96,12 @@ static int pkg_temp_debugfs_init(void) | |||
96 | return -ENOENT; | 96 | return -ENOENT; |
97 | 97 | ||
98 | d = debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs, | 98 | d = debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs, |
99 | (u32 *)&pkg_interrupt_cnt); | 99 | &pkg_interrupt_cnt); |
100 | if (!d) | 100 | if (!d) |
101 | goto err_out; | 101 | goto err_out; |
102 | 102 | ||
103 | d = debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs, | 103 | d = debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs, |
104 | (u32 *)&pkg_work_cnt); | 104 | &pkg_work_cnt); |
105 | if (!d) | 105 | if (!d) |
106 | goto err_out; | 106 | goto err_out; |
107 | 107 | ||