blob: e0c1f2409035e2bb0d610c1992bde65fb0748cd4 [file] [log] [blame]
Kuninori Morimotoc9545792018-07-30 07:56:06 +00001// SPDX-License-Identifier: GPL-2.0
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +10002/*
3 * R-Car THS/TSC thermal sensor driver
4 *
5 * Copyright (C) 2012 Renesas Solutions Corp.
6 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +10007 */
8#include <linux/delay.h>
9#include <linux/err.h>
Kuninori Morimotoe0a51722013-01-31 09:04:48 +000010#include <linux/irq.h>
11#include <linux/interrupt.h>
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +100012#include <linux/io.h>
13#include <linux/module.h>
Kuninori Morimoto8b477ea2016-01-28 02:45:08 +000014#include <linux/of_device.h>
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +100015#include <linux/platform_device.h>
Kuninori Morimoto51d45d22013-03-26 06:08:52 +000016#include <linux/pm_runtime.h>
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -080017#include <linux/reboot.h>
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +100018#include <linux/slab.h>
19#include <linux/spinlock.h>
20#include <linux/thermal.h>
21
Kuninori Morimoto64a411e2016-07-19 10:01:37 +000022#include "thermal_hwmon.h"
23
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -080024#define IDLE_INTERVAL 5000
25
Kuninori Morimotoe0a51722013-01-31 09:04:48 +000026#define COMMON_STR 0x00
27#define COMMON_ENR 0x04
28#define COMMON_INTMSK 0x0c
29
30#define REG_POSNEG 0x20
31#define REG_FILONOFF 0x28
Kuninori Morimotoe9137a52013-01-31 09:03:46 +000032#define REG_THSCR 0x2c
33#define REG_THSSR 0x30
Kuninori Morimotoe0a51722013-01-31 09:04:48 +000034#define REG_INTCTRL 0x34
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +100035
36/* THSCR */
Kuninori Morimotof8f53e12013-01-31 09:03:11 +000037#define CPCTL (1 << 12)
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +100038
39/* THSSR */
40#define CTEMP 0x3f
41
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +000042struct rcar_thermal_common {
43 void __iomem *base;
44 struct device *dev;
45 struct list_head head;
Kuninori Morimotoe0a51722013-01-31 09:04:48 +000046 spinlock_t lock;
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +000047};
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +100048
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +090049struct rcar_thermal_chip {
50 unsigned int use_of_thermal : 1;
51 unsigned int has_filonoff : 1;
52 unsigned int irq_per_ch : 1;
53 unsigned int needs_suspend_resume : 1;
54 unsigned int nirqs;
Yoshihiro Kaneko20386f02019-05-08 13:08:45 +020055 unsigned int ctemp_bands;
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +090056};
57
58static const struct rcar_thermal_chip rcar_thermal = {
59 .use_of_thermal = 0,
60 .has_filonoff = 1,
61 .irq_per_ch = 0,
62 .needs_suspend_resume = 0,
63 .nirqs = 1,
Yoshihiro Kaneko20386f02019-05-08 13:08:45 +020064 .ctemp_bands = 1,
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +090065};
66
67static const struct rcar_thermal_chip rcar_gen2_thermal = {
68 .use_of_thermal = 1,
69 .has_filonoff = 1,
70 .irq_per_ch = 0,
71 .needs_suspend_resume = 0,
72 .nirqs = 1,
Yoshihiro Kaneko20386f02019-05-08 13:08:45 +020073 .ctemp_bands = 1,
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +090074};
75
76static const struct rcar_thermal_chip rcar_gen3_thermal = {
77 .use_of_thermal = 1,
78 .has_filonoff = 0,
79 .irq_per_ch = 1,
80 .needs_suspend_resume = 1,
81 /*
82 * The Gen3 chip has 3 interrupts, but this driver uses only 2
83 * interrupts to detect a temperature change, rise or fall.
84 */
85 .nirqs = 2,
Yoshihiro Kaneko20386f02019-05-08 13:08:45 +020086 .ctemp_bands = 2,
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +090087};
88
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +100089struct rcar_thermal_priv {
90 void __iomem *base;
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +000091 struct rcar_thermal_common *common;
92 struct thermal_zone_device *zone;
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +090093 const struct rcar_thermal_chip *chip;
Kuninori Morimotoe0a51722013-01-31 09:04:48 +000094 struct delayed_work work;
Kuninori Morimotob2bbc6a2013-01-31 09:03:22 +000095 struct mutex lock;
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +000096 struct list_head list;
Kuninori Morimotoe0a51722013-01-31 09:04:48 +000097 int id;
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +100098};
99
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000100#define rcar_thermal_for_each_priv(pos, common) \
101 list_for_each_entry(pos, &common->head, list)
102
Kuninori Morimotoc4997032012-11-26 02:32:06 +0000103#define MCELSIUS(temp) ((temp) * 1000)
Kuninori Morimoto9dde8f82013-01-31 09:02:51 +0000104#define rcar_zone_to_priv(zone) ((zone)->devdata)
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000105#define rcar_priv_to_dev(priv) ((priv)->common->dev)
106#define rcar_has_irq_support(priv) ((priv)->common->base)
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000107#define rcar_id_to_shift(priv) ((priv)->id * 8)
108
Kuninori Morimotoca1e4552015-12-15 01:17:07 +0000109static const struct of_device_id rcar_thermal_dt_ids[] = {
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900110 {
111 .compatible = "renesas,rcar-thermal",
112 .data = &rcar_thermal,
113 },
114 {
115 .compatible = "renesas,rcar-gen2-thermal",
116 .data = &rcar_gen2_thermal,
117 },
118 {
Fabrizio Castrob8d3d112018-12-13 20:23:10 +0000119 .compatible = "renesas,thermal-r8a774c0",
120 .data = &rcar_gen3_thermal,
121 },
122 {
Sergei Shtylyov92ca3662018-10-05 00:03:13 +0300123 .compatible = "renesas,thermal-r8a77970",
124 .data = &rcar_gen3_thermal,
125 },
126 {
Yoshihiro Kanekoe36e1302018-12-17 23:50:21 +0900127 .compatible = "renesas,thermal-r8a77990",
128 .data = &rcar_gen3_thermal,
129 },
130 {
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900131 .compatible = "renesas,thermal-r8a77995",
132 .data = &rcar_gen3_thermal,
133 },
Kuninori Morimotoca1e4552015-12-15 01:17:07 +0000134 {},
135};
136MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids);
137
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000138/*
139 * basic functions
140 */
Kuninori Morimotoe9137a52013-01-31 09:03:46 +0000141#define rcar_thermal_common_read(c, r) \
142 _rcar_thermal_common_read(c, COMMON_ ##r)
143static u32 _rcar_thermal_common_read(struct rcar_thermal_common *common,
144 u32 reg)
145{
146 return ioread32(common->base + reg);
147}
148
149#define rcar_thermal_common_write(c, r, d) \
150 _rcar_thermal_common_write(c, COMMON_ ##r, d)
151static void _rcar_thermal_common_write(struct rcar_thermal_common *common,
152 u32 reg, u32 data)
153{
154 iowrite32(data, common->base + reg);
155}
156
157#define rcar_thermal_common_bset(c, r, m, d) \
158 _rcar_thermal_common_bset(c, COMMON_ ##r, m, d)
159static void _rcar_thermal_common_bset(struct rcar_thermal_common *common,
160 u32 reg, u32 mask, u32 data)
161{
162 u32 val;
163
164 val = ioread32(common->base + reg);
165 val &= ~mask;
166 val |= (data & mask);
167 iowrite32(val, common->base + reg);
168}
Kuninori Morimotoe9137a52013-01-31 09:03:46 +0000169
170#define rcar_thermal_read(p, r) _rcar_thermal_read(p, REG_ ##r)
171static u32 _rcar_thermal_read(struct rcar_thermal_priv *priv, u32 reg)
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000172{
Kuninori Morimotob2bbc6a2013-01-31 09:03:22 +0000173 return ioread32(priv->base + reg);
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000174}
175
Kuninori Morimotoe9137a52013-01-31 09:03:46 +0000176#define rcar_thermal_write(p, r, d) _rcar_thermal_write(p, REG_ ##r, d)
177static void _rcar_thermal_write(struct rcar_thermal_priv *priv,
178 u32 reg, u32 data)
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000179{
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000180 iowrite32(data, priv->base + reg);
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000181}
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000182
Kuninori Morimotoe9137a52013-01-31 09:03:46 +0000183#define rcar_thermal_bset(p, r, m, d) _rcar_thermal_bset(p, REG_ ##r, m, d)
184static void _rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg,
185 u32 mask, u32 data)
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000186{
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000187 u32 val;
188
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000189 val = ioread32(priv->base + reg);
190 val &= ~mask;
191 val |= (data & mask);
192 iowrite32(val, priv->base + reg);
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000193}
194
195/*
196 * zone device functions
197 */
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000198static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000199{
Kuninori Morimotof8f53e12013-01-31 09:03:11 +0000200 struct device *dev = rcar_priv_to_dev(priv);
201 int i;
Yoshihiro Shimoda913015c2015-01-07 10:13:11 +0900202 u32 ctemp, old, new;
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000203
Kuninori Morimotob2bbc6a2013-01-31 09:03:22 +0000204 mutex_lock(&priv->lock);
205
Kuninori Morimotof8f53e12013-01-31 09:03:11 +0000206 /*
207 * TSC decides a value of CPTAP automatically,
208 * and this is the conditions which validate interrupt.
209 */
210 rcar_thermal_bset(priv, THSCR, CPCTL, CPCTL);
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000211
Kuninori Morimotof8f53e12013-01-31 09:03:11 +0000212 ctemp = 0;
213 old = ~0;
214 for (i = 0; i < 128; i++) {
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000215 /*
216 * we need to wait 300us after changing comparator offset
217 * to get stable temperature.
218 * see "Usage Notes" on datasheet
219 */
Geert Uytterhoeven263c8c42020-01-15 13:54:17 +0100220 usleep_range(300, 400);
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000221
Kuninori Morimotof8f53e12013-01-31 09:03:11 +0000222 new = rcar_thermal_read(priv, THSSR) & CTEMP;
223 if (new == old) {
224 ctemp = new;
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000225 break;
226 }
Kuninori Morimotof8f53e12013-01-31 09:03:11 +0000227 old = new;
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000228 }
229
Kuninori Morimotof8f53e12013-01-31 09:03:11 +0000230 if (!ctemp) {
231 dev_err(dev, "thermal sensor was broken\n");
Wei Yongjunf0e68fc2013-02-22 13:22:39 +0000232 goto err_out_unlock;
Kuninori Morimotof8f53e12013-01-31 09:03:11 +0000233 }
234
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000235 /*
236 * enable IRQ
237 */
238 if (rcar_has_irq_support(priv)) {
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900239 if (priv->chip->has_filonoff)
240 rcar_thermal_write(priv, FILONOFF, 0);
Kuninori Morimotof8f53e12013-01-31 09:03:11 +0000241
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000242 /* enable Rising/Falling edge interrupt */
243 rcar_thermal_write(priv, POSNEG, 0x1);
244 rcar_thermal_write(priv, INTCTRL, (((ctemp - 0) << 8) |
245 ((ctemp - 1) << 0)));
246 }
247
Wei Yongjunf0e68fc2013-02-22 13:22:39 +0000248err_out_unlock:
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000249 mutex_unlock(&priv->lock);
Niklas Söderlund57ed7372020-03-10 18:00:28 +0100250
251 return ctemp ? ctemp : -EINVAL;
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000252}
253
Kuninori Morimoto8b477ea2016-01-28 02:45:08 +0000254static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv,
255 int *temp)
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000256{
Niklas Söderlund0fa04202020-03-10 18:00:29 +0100257 int ctemp;
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000258
Niklas Söderlund57ed7372020-03-10 18:00:28 +0100259 ctemp = rcar_thermal_update_temp(priv);
260 if (ctemp < 0)
261 return ctemp;
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000262
Niklas Söderlunddff6d4f2020-01-17 17:05:53 +0100263 /* Guaranteed operating range is -45C to 125C. */
Kuninori Morimoto5440c402015-12-15 01:18:13 +0000264
Niklas Söderlund0fa04202020-03-10 18:00:29 +0100265 if (priv->chip->ctemp_bands == 1)
266 *temp = MCELSIUS((ctemp * 5) - 65);
267 else if (ctemp < 24)
268 *temp = MCELSIUS(((ctemp * 55) - 720) / 10);
269 else
270 *temp = MCELSIUS((ctemp * 5) - 60);
Kuninori Morimoto5440c402015-12-15 01:18:13 +0000271
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000272 return 0;
273}
274
Kuninori Morimoto8b477ea2016-01-28 02:45:08 +0000275static int rcar_thermal_of_get_temp(void *data, int *temp)
276{
277 struct rcar_thermal_priv *priv = data;
278
279 return rcar_thermal_get_current_temp(priv, temp);
280}
281
282static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp)
283{
284 struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
285
286 return rcar_thermal_get_current_temp(priv, temp);
287}
288
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -0800289static int rcar_thermal_get_trip_type(struct thermal_zone_device *zone,
290 int trip, enum thermal_trip_type *type)
291{
292 struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000293 struct device *dev = rcar_priv_to_dev(priv);
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -0800294
295 /* see rcar_thermal_get_temp() */
296 switch (trip) {
297 case 0: /* +90 <= temp */
298 *type = THERMAL_TRIP_CRITICAL;
299 break;
300 default:
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000301 dev_err(dev, "rcar driver trip error\n");
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -0800302 return -EINVAL;
303 }
304
305 return 0;
306}
307
308static int rcar_thermal_get_trip_temp(struct thermal_zone_device *zone,
Sascha Hauer17e83512015-07-24 08:12:54 +0200309 int trip, int *temp)
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -0800310{
311 struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000312 struct device *dev = rcar_priv_to_dev(priv);
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -0800313
314 /* see rcar_thermal_get_temp() */
315 switch (trip) {
316 case 0: /* +90 <= temp */
317 *temp = MCELSIUS(90);
318 break;
319 default:
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000320 dev_err(dev, "rcar driver trip error\n");
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -0800321 return -EINVAL;
322 }
323
324 return 0;
325}
326
327static int rcar_thermal_notify(struct thermal_zone_device *zone,
328 int trip, enum thermal_trip_type type)
329{
330 struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000331 struct device *dev = rcar_priv_to_dev(priv);
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -0800332
333 switch (type) {
334 case THERMAL_TRIP_CRITICAL:
335 /* FIXME */
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000336 dev_warn(dev, "Thermal reached to critical temperature\n");
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -0800337 break;
338 default:
339 break;
340 }
341
342 return 0;
343}
344
Kuninori Morimoto8b477ea2016-01-28 02:45:08 +0000345static const struct thermal_zone_of_device_ops rcar_thermal_zone_of_ops = {
346 .get_temp = rcar_thermal_of_get_temp,
347};
348
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000349static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
kuninori.morimoto.gx@renesas.comd2a73e22012-12-02 18:48:41 -0800350 .get_temp = rcar_thermal_get_temp,
351 .get_trip_type = rcar_thermal_get_trip_type,
352 .get_trip_temp = rcar_thermal_get_trip_temp,
353 .notify = rcar_thermal_notify,
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000354};
355
356/*
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000357 * interrupt
358 */
359#define rcar_thermal_irq_enable(p) _rcar_thermal_irq_ctrl(p, 1)
360#define rcar_thermal_irq_disable(p) _rcar_thermal_irq_ctrl(p, 0)
361static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable)
362{
363 struct rcar_thermal_common *common = priv->common;
364 unsigned long flags;
365 u32 mask = 0x3 << rcar_id_to_shift(priv); /* enable Rising/Falling */
366
Kuninori Morimotoffbcdf82015-12-15 01:17:56 +0000367 if (!rcar_has_irq_support(priv))
368 return;
369
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000370 spin_lock_irqsave(&common->lock, flags);
371
372 rcar_thermal_common_bset(common, INTMSK, mask, enable ? 0 : mask);
373
374 spin_unlock_irqrestore(&common->lock, flags);
375}
376
377static void rcar_thermal_work(struct work_struct *work)
378{
379 struct rcar_thermal_priv *priv;
Kuninori Morimotoa1ade562015-12-15 01:17:40 +0000380 int ret;
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000381
382 priv = container_of(work, struct rcar_thermal_priv, work.work);
383
Kuninori Morimotoa1ade562015-12-15 01:17:40 +0000384 ret = rcar_thermal_update_temp(priv);
385 if (ret < 0)
386 return;
387
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000388 rcar_thermal_irq_enable(priv);
Patrick Titiano94771652014-02-28 14:10:04 +0100389
Niklas Söderlund7617e772020-03-10 18:00:27 +0100390 thermal_zone_device_update(priv->zone, THERMAL_EVENT_UNSPECIFIED);
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000391}
392
393static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status)
394{
395 struct device *dev = rcar_priv_to_dev(priv);
396
397 status = (status >> rcar_id_to_shift(priv)) & 0x3;
398
Patrick Titiano206c0cb2014-02-28 14:10:03 +0100399 if (status) {
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000400 dev_dbg(dev, "thermal%d %s%s\n",
401 priv->id,
402 (status & 0x2) ? "Rising " : "",
403 (status & 0x1) ? "Falling" : "");
404 }
405
406 return status;
407}
408
409static irqreturn_t rcar_thermal_irq(int irq, void *data)
410{
411 struct rcar_thermal_common *common = data;
412 struct rcar_thermal_priv *priv;
413 unsigned long flags;
414 u32 status, mask;
415
416 spin_lock_irqsave(&common->lock, flags);
417
418 mask = rcar_thermal_common_read(common, INTMSK);
419 status = rcar_thermal_common_read(common, STR);
420 rcar_thermal_common_write(common, STR, 0x000F0F0F & mask);
421
422 spin_unlock_irqrestore(&common->lock, flags);
423
424 status = status & ~mask;
425
426 /*
427 * check the status
428 */
429 rcar_thermal_for_each_priv(priv, common) {
430 if (rcar_thermal_had_changed(priv, status)) {
431 rcar_thermal_irq_disable(priv);
Geert Uytterhoeven3a313862018-10-12 09:20:15 +0200432 queue_delayed_work(system_freezable_wq, &priv->work,
433 msecs_to_jiffies(300));
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000434 }
435 }
436
437 return IRQ_HANDLED;
438}
439
440/*
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000441 * platform functions
442 */
Kuninori Morimoto84f0e492015-11-10 02:12:06 +0000443static int rcar_thermal_remove(struct platform_device *pdev)
444{
445 struct rcar_thermal_common *common = platform_get_drvdata(pdev);
446 struct device *dev = &pdev->dev;
447 struct rcar_thermal_priv *priv;
448
449 rcar_thermal_for_each_priv(priv, common) {
Kuninori Morimotoffbcdf82015-12-15 01:17:56 +0000450 rcar_thermal_irq_disable(priv);
Geert Uytterhoeven697ee782018-10-12 09:20:16 +0200451 cancel_delayed_work_sync(&priv->work);
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900452 if (priv->chip->use_of_thermal)
Kuninori Morimoto64a411e2016-07-19 10:01:37 +0000453 thermal_remove_hwmon_sysfs(priv->zone);
Bui Duc Phucd4b23c5c2016-08-22 03:19:49 +0000454 else
455 thermal_zone_device_unregister(priv->zone);
Kuninori Morimoto84f0e492015-11-10 02:12:06 +0000456 }
457
458 pm_runtime_put(dev);
459 pm_runtime_disable(dev);
460
461 return 0;
462}
463
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000464static int rcar_thermal_probe(struct platform_device *pdev)
465{
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000466 struct rcar_thermal_common *common;
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000467 struct rcar_thermal_priv *priv;
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000468 struct device *dev = &pdev->dev;
469 struct resource *res, *irq;
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900470 const struct rcar_thermal_chip *chip = of_device_get_match_data(dev);
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000471 int mres = 0;
472 int i;
Devendra Nagafb84d992013-03-04 16:52:47 +0000473 int ret = -ENODEV;
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000474 int idle = IDLE_INTERVAL;
Yoshihiro Shimoda11313742015-01-07 10:13:10 +0900475 u32 enr_bits = 0;
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000476
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000477 common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
Jingoo Hanb0a60d82014-05-07 15:03:25 +0900478 if (!common)
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000479 return -ENOMEM;
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000480
Kuninori Morimoto84f0e492015-11-10 02:12:06 +0000481 platform_set_drvdata(pdev, common);
482
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000483 INIT_LIST_HEAD(&common->head);
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000484 spin_lock_init(&common->lock);
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000485 common->dev = dev;
486
Kuninori Morimoto51d45d22013-03-26 06:08:52 +0000487 pm_runtime_enable(dev);
488 pm_runtime_get_sync(dev);
489
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900490 for (i = 0; i < chip->nirqs; i++) {
Sergei Shtylyovdf016bb2018-10-03 23:47:34 +0300491 irq = platform_get_resource(pdev, IORESOURCE_IRQ, i);
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900492 if (!irq)
493 continue;
494 if (!common->base) {
495 /*
496 * platform has IRQ support.
497 * Then, driver uses common registers
498 * rcar_has_irq_support() will be enabled
499 */
500 res = platform_get_resource(pdev, IORESOURCE_MEM,
501 mres++);
502 common->base = devm_ioremap_resource(dev, res);
Niklas Söderlund39056e82020-03-10 12:47:09 +0100503 if (IS_ERR(common->base)) {
504 ret = PTR_ERR(common->base);
505 goto error_unregister;
506 }
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000507
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900508 idle = 0; /* polling delay is not needed */
509 }
510
511 ret = devm_request_irq(dev, irq->start, rcar_thermal_irq,
512 IRQF_SHARED, dev_name(dev), common);
513 if (ret) {
514 dev_err(dev, "irq request failed\n ");
515 goto error_unregister;
516 }
517
518 /* update ENR bits */
519 if (chip->irq_per_ch)
520 enr_bits |= 1 << i;
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000521 }
522
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000523 for (i = 0;; i++) {
524 res = platform_get_resource(pdev, IORESOURCE_MEM, mres++);
525 if (!res)
526 break;
527
528 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
529 if (!priv) {
Kuninori Morimoto1dc20822013-03-26 06:08:10 +0000530 ret = -ENOMEM;
531 goto error_unregister;
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000532 }
533
Sachin Kamat50955262013-03-04 06:45:33 +0000534 priv->base = devm_ioremap_resource(dev, res);
Kuninori Morimoto1dc20822013-03-26 06:08:10 +0000535 if (IS_ERR(priv->base)) {
536 ret = PTR_ERR(priv->base);
537 goto error_unregister;
538 }
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000539
540 priv->common = common;
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000541 priv->id = i;
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900542 priv->chip = chip;
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000543 mutex_init(&priv->lock);
544 INIT_LIST_HEAD(&priv->list);
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000545 INIT_DELAYED_WORK(&priv->work, rcar_thermal_work);
Kuninori Morimotoa1ade562015-12-15 01:17:40 +0000546 ret = rcar_thermal_update_temp(priv);
547 if (ret < 0)
548 goto error_unregister;
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000549
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900550 if (chip->use_of_thermal)
Eduardo Valentin5e3258682016-03-09 13:09:43 -0800551 priv->zone = devm_thermal_zone_of_sensor_register(
Kuninori Morimoto8b477ea2016-01-28 02:45:08 +0000552 dev, i, priv,
553 &rcar_thermal_zone_of_ops);
554 else
555 priv->zone = thermal_zone_device_register(
556 "rcar_thermal",
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000557 1, 0, priv,
558 &rcar_thermal_zone_ops, NULL, 0,
Kuninori Morimotoe0a51722013-01-31 09:04:48 +0000559 idle);
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000560 if (IS_ERR(priv->zone)) {
561 dev_err(dev, "can't register thermal zone\n");
Devendra Nagafb84d992013-03-04 16:52:47 +0000562 ret = PTR_ERR(priv->zone);
Dirk Behme87260d32016-04-21 12:24:55 +0200563 priv->zone = NULL;
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000564 goto error_unregister;
565 }
566
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900567 if (chip->use_of_thermal) {
Kuninori Morimoto64a411e2016-07-19 10:01:37 +0000568 /*
569 * thermal_zone doesn't enable hwmon as default,
570 * but, enable it here to keep compatible
571 */
572 priv->zone->tzp->no_hwmon = false;
573 ret = thermal_add_hwmon_sysfs(priv->zone);
574 if (ret)
575 goto error_unregister;
576 }
577
Kuninori Morimotoffbcdf82015-12-15 01:17:56 +0000578 rcar_thermal_irq_enable(priv);
Kuninori Morimoto1dc20822013-03-26 06:08:10 +0000579
580 list_move_tail(&priv->list, &common->head);
Yoshihiro Shimoda11313742015-01-07 10:13:10 +0900581
582 /* update ENR bits */
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900583 if (!chip->irq_per_ch)
584 enr_bits |= 3 << (i * 8);
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000585 }
586
Simon Horman542cdf42018-07-24 13:14:13 +0200587 if (common->base && enr_bits)
Yoshihiro Shimoda11313742015-01-07 10:13:10 +0900588 rcar_thermal_common_write(common, ENR, enr_bits);
589
Laurent Pinchart3db46c92013-05-14 23:00:32 +0000590 dev_info(dev, "%d sensor probed\n", i);
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000591
592 return 0;
Kuninori Morimoto3676d1d2013-01-31 09:03:33 +0000593
594error_unregister:
Kuninori Morimoto84f0e492015-11-10 02:12:06 +0000595 rcar_thermal_remove(pdev);
Kuninori Morimoto51d45d22013-03-26 06:08:52 +0000596
Devendra Nagafb84d992013-03-04 16:52:47 +0000597 return ret;
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000598}
599
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900600#ifdef CONFIG_PM_SLEEP
601static int rcar_thermal_suspend(struct device *dev)
602{
603 struct rcar_thermal_common *common = dev_get_drvdata(dev);
604 struct rcar_thermal_priv *priv = list_first_entry(&common->head,
605 typeof(*priv), list);
606
607 if (priv->chip->needs_suspend_resume) {
608 rcar_thermal_common_write(common, ENR, 0);
609 rcar_thermal_irq_disable(priv);
610 rcar_thermal_bset(priv, THSCR, CPCTL, 0);
611 }
612
613 return 0;
614}
615
616static int rcar_thermal_resume(struct device *dev)
617{
618 struct rcar_thermal_common *common = dev_get_drvdata(dev);
619 struct rcar_thermal_priv *priv = list_first_entry(&common->head,
620 typeof(*priv), list);
621 int ret;
622
623 if (priv->chip->needs_suspend_resume) {
624 ret = rcar_thermal_update_temp(priv);
625 if (ret < 0)
626 return ret;
627 rcar_thermal_irq_enable(priv);
628 rcar_thermal_common_write(common, ENR, 0x03);
629 }
630
631 return 0;
632}
633#endif
634
635static SIMPLE_DEV_PM_OPS(rcar_thermal_pm_ops, rcar_thermal_suspend,
636 rcar_thermal_resume);
637
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000638static struct platform_driver rcar_thermal_driver = {
639 .driver = {
640 .name = "rcar_thermal",
Yoshihiro Kaneko1969d9d2018-05-20 18:26:17 +0900641 .pm = &rcar_thermal_pm_ops,
Kuninori Morimoto76cc1882013-01-31 09:05:26 +0000642 .of_match_table = rcar_thermal_dt_ids,
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000643 },
644 .probe = rcar_thermal_probe,
645 .remove = rcar_thermal_remove,
646};
647module_platform_driver(rcar_thermal_driver);
648
Kuninori Morimotoc9545792018-07-30 07:56:06 +0000649MODULE_LICENSE("GPL v2");
Kuninori Morimoto1e426ff2012-07-21 10:53:48 +1000650MODULE_DESCRIPTION("R-Car THS/TSC thermal sensor driver");
651MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");