.. | .. |
---|
52 | 52 | unsigned int irq_per_ch : 1; |
---|
53 | 53 | unsigned int needs_suspend_resume : 1; |
---|
54 | 54 | unsigned int nirqs; |
---|
| 55 | + unsigned int ctemp_bands; |
---|
55 | 56 | }; |
---|
56 | 57 | |
---|
57 | 58 | static const struct rcar_thermal_chip rcar_thermal = { |
---|
.. | .. |
---|
60 | 61 | .irq_per_ch = 0, |
---|
61 | 62 | .needs_suspend_resume = 0, |
---|
62 | 63 | .nirqs = 1, |
---|
| 64 | + .ctemp_bands = 1, |
---|
63 | 65 | }; |
---|
64 | 66 | |
---|
65 | 67 | static const struct rcar_thermal_chip rcar_gen2_thermal = { |
---|
.. | .. |
---|
68 | 70 | .irq_per_ch = 0, |
---|
69 | 71 | .needs_suspend_resume = 0, |
---|
70 | 72 | .nirqs = 1, |
---|
| 73 | + .ctemp_bands = 1, |
---|
71 | 74 | }; |
---|
72 | 75 | |
---|
73 | 76 | static const struct rcar_thermal_chip rcar_gen3_thermal = { |
---|
.. | .. |
---|
80 | 83 | * interrupts to detect a temperature change, rise or fall. |
---|
81 | 84 | */ |
---|
82 | 85 | .nirqs = 2, |
---|
| 86 | + .ctemp_bands = 2, |
---|
83 | 87 | }; |
---|
84 | 88 | |
---|
85 | 89 | struct rcar_thermal_priv { |
---|
.. | .. |
---|
91 | 95 | struct mutex lock; |
---|
92 | 96 | struct list_head list; |
---|
93 | 97 | int id; |
---|
94 | | - u32 ctemp; |
---|
95 | 98 | }; |
---|
96 | 99 | |
---|
97 | 100 | #define rcar_thermal_for_each_priv(pos, common) \ |
---|
.. | .. |
---|
111 | 114 | { |
---|
112 | 115 | .compatible = "renesas,rcar-gen2-thermal", |
---|
113 | 116 | .data = &rcar_gen2_thermal, |
---|
| 117 | + }, |
---|
| 118 | + { |
---|
| 119 | + .compatible = "renesas,thermal-r8a774c0", |
---|
| 120 | + .data = &rcar_gen3_thermal, |
---|
| 121 | + }, |
---|
| 122 | + { |
---|
| 123 | + .compatible = "renesas,thermal-r8a77970", |
---|
| 124 | + .data = &rcar_gen3_thermal, |
---|
| 125 | + }, |
---|
| 126 | + { |
---|
| 127 | + .compatible = "renesas,thermal-r8a77990", |
---|
| 128 | + .data = &rcar_gen3_thermal, |
---|
114 | 129 | }, |
---|
115 | 130 | { |
---|
116 | 131 | .compatible = "renesas,thermal-r8a77995", |
---|
.. | .. |
---|
183 | 198 | static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) |
---|
184 | 199 | { |
---|
185 | 200 | struct device *dev = rcar_priv_to_dev(priv); |
---|
186 | | - int i; |
---|
187 | | - u32 ctemp, old, new; |
---|
188 | | - int ret = -EINVAL; |
---|
| 201 | + int old, new, ctemp = -EINVAL; |
---|
| 202 | + unsigned int i; |
---|
189 | 203 | |
---|
190 | 204 | mutex_lock(&priv->lock); |
---|
191 | 205 | |
---|
.. | .. |
---|
195 | 209 | */ |
---|
196 | 210 | rcar_thermal_bset(priv, THSCR, CPCTL, CPCTL); |
---|
197 | 211 | |
---|
198 | | - ctemp = 0; |
---|
199 | 212 | old = ~0; |
---|
200 | 213 | for (i = 0; i < 128; i++) { |
---|
201 | 214 | /* |
---|
.. | .. |
---|
203 | 216 | * to get stable temperature. |
---|
204 | 217 | * see "Usage Notes" on datasheet |
---|
205 | 218 | */ |
---|
206 | | - udelay(300); |
---|
| 219 | + usleep_range(300, 400); |
---|
207 | 220 | |
---|
208 | 221 | new = rcar_thermal_read(priv, THSSR) & CTEMP; |
---|
209 | 222 | if (new == old) { |
---|
.. | .. |
---|
213 | 226 | old = new; |
---|
214 | 227 | } |
---|
215 | 228 | |
---|
216 | | - if (!ctemp) { |
---|
| 229 | + if (ctemp < 0) { |
---|
217 | 230 | dev_err(dev, "thermal sensor was broken\n"); |
---|
218 | 231 | goto err_out_unlock; |
---|
219 | 232 | } |
---|
.. | .. |
---|
231 | 244 | ((ctemp - 1) << 0))); |
---|
232 | 245 | } |
---|
233 | 246 | |
---|
234 | | - dev_dbg(dev, "thermal%d %d -> %d\n", priv->id, priv->ctemp, ctemp); |
---|
235 | | - |
---|
236 | | - priv->ctemp = ctemp; |
---|
237 | | - ret = 0; |
---|
238 | 247 | err_out_unlock: |
---|
239 | 248 | mutex_unlock(&priv->lock); |
---|
240 | | - return ret; |
---|
| 249 | + |
---|
| 250 | + return ctemp; |
---|
241 | 251 | } |
---|
242 | 252 | |
---|
243 | 253 | static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv, |
---|
244 | 254 | int *temp) |
---|
245 | 255 | { |
---|
246 | | - int tmp; |
---|
247 | | - int ret; |
---|
| 256 | + int ctemp; |
---|
248 | 257 | |
---|
249 | | - ret = rcar_thermal_update_temp(priv); |
---|
250 | | - if (ret < 0) |
---|
251 | | - return ret; |
---|
| 258 | + ctemp = rcar_thermal_update_temp(priv); |
---|
| 259 | + if (ctemp < 0) |
---|
| 260 | + return ctemp; |
---|
252 | 261 | |
---|
253 | | - mutex_lock(&priv->lock); |
---|
254 | | - tmp = MCELSIUS((priv->ctemp * 5) - 65); |
---|
255 | | - mutex_unlock(&priv->lock); |
---|
| 262 | + /* Guaranteed operating range is -45C to 125C. */ |
---|
256 | 263 | |
---|
257 | | - if ((tmp < MCELSIUS(-45)) || (tmp > MCELSIUS(125))) { |
---|
258 | | - struct device *dev = rcar_priv_to_dev(priv); |
---|
259 | | - |
---|
260 | | - dev_err(dev, "it couldn't measure temperature correctly\n"); |
---|
261 | | - return -EIO; |
---|
262 | | - } |
---|
263 | | - |
---|
264 | | - *temp = tmp; |
---|
| 264 | + if (priv->chip->ctemp_bands == 1) |
---|
| 265 | + *temp = MCELSIUS((ctemp * 5) - 65); |
---|
| 266 | + else if (ctemp < 24) |
---|
| 267 | + *temp = MCELSIUS(((ctemp * 55) - 720) / 10); |
---|
| 268 | + else |
---|
| 269 | + *temp = MCELSIUS((ctemp * 5) - 60); |
---|
265 | 270 | |
---|
266 | 271 | return 0; |
---|
267 | 272 | } |
---|
.. | .. |
---|
371 | 376 | static void rcar_thermal_work(struct work_struct *work) |
---|
372 | 377 | { |
---|
373 | 378 | struct rcar_thermal_priv *priv; |
---|
374 | | - int cctemp, nctemp; |
---|
375 | 379 | int ret; |
---|
376 | 380 | |
---|
377 | 381 | priv = container_of(work, struct rcar_thermal_priv, work.work); |
---|
378 | | - |
---|
379 | | - ret = rcar_thermal_get_current_temp(priv, &cctemp); |
---|
380 | | - if (ret < 0) |
---|
381 | | - return; |
---|
382 | 382 | |
---|
383 | 383 | ret = rcar_thermal_update_temp(priv); |
---|
384 | 384 | if (ret < 0) |
---|
.. | .. |
---|
386 | 386 | |
---|
387 | 387 | rcar_thermal_irq_enable(priv); |
---|
388 | 388 | |
---|
389 | | - ret = rcar_thermal_get_current_temp(priv, &nctemp); |
---|
390 | | - if (ret < 0) |
---|
391 | | - return; |
---|
392 | | - |
---|
393 | | - if (nctemp != cctemp) |
---|
394 | | - thermal_zone_device_update(priv->zone, |
---|
395 | | - THERMAL_EVENT_UNSPECIFIED); |
---|
| 389 | + thermal_zone_device_update(priv->zone, THERMAL_EVENT_UNSPECIFIED); |
---|
396 | 390 | } |
---|
397 | 391 | |
---|
398 | 392 | static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status) |
---|
.. | .. |
---|
552 | 546 | if (ret < 0) |
---|
553 | 547 | goto error_unregister; |
---|
554 | 548 | |
---|
555 | | - if (chip->use_of_thermal) |
---|
| 549 | + if (chip->use_of_thermal) { |
---|
556 | 550 | priv->zone = devm_thermal_zone_of_sensor_register( |
---|
557 | 551 | dev, i, priv, |
---|
558 | 552 | &rcar_thermal_zone_of_ops); |
---|
559 | | - else |
---|
| 553 | + } else { |
---|
560 | 554 | priv->zone = thermal_zone_device_register( |
---|
561 | 555 | "rcar_thermal", |
---|
562 | 556 | 1, 0, priv, |
---|
563 | 557 | &rcar_thermal_zone_ops, NULL, 0, |
---|
564 | 558 | idle); |
---|
| 559 | + |
---|
| 560 | + ret = thermal_zone_device_enable(priv->zone); |
---|
| 561 | + if (ret) { |
---|
| 562 | + thermal_zone_device_unregister(priv->zone); |
---|
| 563 | + priv->zone = ERR_PTR(ret); |
---|
| 564 | + } |
---|
| 565 | + } |
---|
565 | 566 | if (IS_ERR(priv->zone)) { |
---|
566 | 567 | dev_err(dev, "can't register thermal zone\n"); |
---|
567 | 568 | ret = PTR_ERR(priv->zone); |
---|