rcar_thermal.c 14.8 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2 3 4 5 6 7 8 9
/*
 *  R-Car THS/TSC thermal sensor driver
 *
 * Copyright (C) 2012 Renesas Solutions Corp.
 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 */
#include <linux/delay.h>
#include <linux/err.h>
10 11
#include <linux/irq.h>
#include <linux/interrupt.h>
12 13
#include <linux/io.h>
#include <linux/module.h>
14
#include <linux/of_device.h>
15
#include <linux/platform_device.h>
16
#include <linux/pm_runtime.h>
17
#include <linux/reboot.h>
18 19 20 21
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/thermal.h>

22 23
#include "thermal_hwmon.h"

24 25
#define IDLE_INTERVAL	5000

26 27 28 29 30 31
#define COMMON_STR	0x00
#define COMMON_ENR	0x04
#define COMMON_INTMSK	0x0c

#define REG_POSNEG	0x20
#define REG_FILONOFF	0x28
32 33
#define REG_THSCR	0x2c
#define REG_THSSR	0x30
34
#define REG_INTCTRL	0x34
35 36

/* THSCR */
37
#define CPCTL	(1 << 12)
38 39 40 41

/* THSSR */
#define CTEMP	0x3f

42 43 44 45
struct rcar_thermal_common {
	void __iomem *base;
	struct device *dev;
	struct list_head head;
46
	spinlock_t lock;
47
};
48

49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
struct rcar_thermal_chip {
	unsigned int use_of_thermal : 1;
	unsigned int has_filonoff : 1;
	unsigned int irq_per_ch : 1;
	unsigned int needs_suspend_resume : 1;
	unsigned int nirqs;
};

static const struct rcar_thermal_chip rcar_thermal = {
	.use_of_thermal = 0,
	.has_filonoff = 1,
	.irq_per_ch = 0,
	.needs_suspend_resume = 0,
	.nirqs = 1,
};

static const struct rcar_thermal_chip rcar_gen2_thermal = {
	.use_of_thermal = 1,
	.has_filonoff = 1,
	.irq_per_ch = 0,
	.needs_suspend_resume = 0,
	.nirqs = 1,
};

static const struct rcar_thermal_chip rcar_gen3_thermal = {
	.use_of_thermal = 1,
	.has_filonoff = 0,
	.irq_per_ch = 1,
	.needs_suspend_resume = 1,
	/*
	 * The Gen3 chip has 3 interrupts, but this driver uses only 2
	 * interrupts to detect a temperature change, rise or fall.
	 */
	.nirqs = 2,
};

85 86
struct rcar_thermal_priv {
	void __iomem *base;
87 88
	struct rcar_thermal_common *common;
	struct thermal_zone_device *zone;
89
	const struct rcar_thermal_chip *chip;
90
	struct delayed_work work;
91
	struct mutex lock;
92
	struct list_head list;
93
	int id;
94
	u32 ctemp;
95 96
};

97 98 99
#define rcar_thermal_for_each_priv(pos, common)	\
	list_for_each_entry(pos, &common->head, list)

100
#define MCELSIUS(temp)			((temp) * 1000)
101
#define rcar_zone_to_priv(zone)		((zone)->devdata)
102 103
#define rcar_priv_to_dev(priv)		((priv)->common->dev)
#define rcar_has_irq_support(priv)	((priv)->common->base)
104 105
#define rcar_id_to_shift(priv)		((priv)->id * 8)

106
static const struct of_device_id rcar_thermal_dt_ids[] = {
107 108 109 110 111 112 113 114 115 116 117 118
	{
		.compatible = "renesas,rcar-thermal",
		.data = &rcar_thermal,
	},
	{
		.compatible = "renesas,rcar-gen2-thermal",
		 .data = &rcar_gen2_thermal,
	},
	{
		.compatible = "renesas,thermal-r8a77995",
		.data = &rcar_gen3_thermal,
	},
119 120 121 122
	{},
};
MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids);

123 124 125
/*
 *		basic functions
 */
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
#define rcar_thermal_common_read(c, r) \
	_rcar_thermal_common_read(c, COMMON_ ##r)
static u32 _rcar_thermal_common_read(struct rcar_thermal_common *common,
				     u32 reg)
{
	return ioread32(common->base + reg);
}

#define rcar_thermal_common_write(c, r, d) \
	_rcar_thermal_common_write(c, COMMON_ ##r, d)
static void _rcar_thermal_common_write(struct rcar_thermal_common *common,
				       u32 reg, u32 data)
{
	iowrite32(data, common->base + reg);
}

#define rcar_thermal_common_bset(c, r, m, d) \
	_rcar_thermal_common_bset(c, COMMON_ ##r, m, d)
static void _rcar_thermal_common_bset(struct rcar_thermal_common *common,
				      u32 reg, u32 mask, u32 data)
{
	u32 val;

	val = ioread32(common->base + reg);
	val &= ~mask;
	val |= (data & mask);
	iowrite32(val, common->base + reg);
}

#define rcar_thermal_read(p, r) _rcar_thermal_read(p, REG_ ##r)
static u32 _rcar_thermal_read(struct rcar_thermal_priv *priv, u32 reg)
157
{
158
	return ioread32(priv->base + reg);
159 160
}

161 162 163
#define rcar_thermal_write(p, r, d) _rcar_thermal_write(p, REG_ ##r, d)
static void _rcar_thermal_write(struct rcar_thermal_priv *priv,
				u32 reg, u32 data)
164 165 166 167
{
	iowrite32(data, priv->base + reg);
}

168 169 170
#define rcar_thermal_bset(p, r, m, d) _rcar_thermal_bset(p, REG_ ##r, m, d)
static void _rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg,
			       u32 mask, u32 data)
171 172 173 174 175 176 177 178 179 180 181 182
{
	u32 val;

	val = ioread32(priv->base + reg);
	val &= ~mask;
	val |= (data & mask);
	iowrite32(val, priv->base + reg);
}

/*
 *		zone device functions
 */
183
static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
184
{
185 186
	struct device *dev = rcar_priv_to_dev(priv);
	int i;
187
	u32 ctemp, old, new;
188
	int ret = -EINVAL;
189

190 191
	mutex_lock(&priv->lock);

192 193 194 195 196 197 198 199 200
	/*
	 * TSC decides a value of CPTAP automatically,
	 * and this is the conditions which validate interrupt.
	 */
	rcar_thermal_bset(priv, THSCR, CPCTL, CPCTL);

	ctemp = 0;
	old = ~0;
	for (i = 0; i < 128; i++) {
201 202 203 204 205 206 207
		/*
		 * we need to wait 300us after changing comparator offset
		 * to get stable temperature.
		 * see "Usage Notes" on datasheet
		 */
		udelay(300);

208 209 210
		new = rcar_thermal_read(priv, THSSR) & CTEMP;
		if (new == old) {
			ctemp = new;
211 212
			break;
		}
213
		old = new;
214 215
	}

216 217
	if (!ctemp) {
		dev_err(dev, "thermal sensor was broken\n");
218
		goto err_out_unlock;
219 220
	}

221 222 223 224
	/*
	 * enable IRQ
	 */
	if (rcar_has_irq_support(priv)) {
225 226
		if (priv->chip->has_filonoff)
			rcar_thermal_write(priv, FILONOFF, 0);
227 228 229 230 231 232 233 234 235 236

		/* enable Rising/Falling edge interrupt */
		rcar_thermal_write(priv, POSNEG,  0x1);
		rcar_thermal_write(priv, INTCTRL, (((ctemp - 0) << 8) |
						   ((ctemp - 1) << 0)));
	}

	dev_dbg(dev, "thermal%d  %d -> %d\n", priv->id, priv->ctemp, ctemp);

	priv->ctemp = ctemp;
237 238
	ret = 0;
err_out_unlock:
239
	mutex_unlock(&priv->lock);
240
	return ret;
241 242
}

243 244
static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv,
					 int *temp)
245
{
246
	int tmp;
247
	int ret;
248

249 250 251
	ret = rcar_thermal_update_temp(priv);
	if (ret < 0)
		return ret;
252 253

	mutex_lock(&priv->lock);
254
	tmp =  MCELSIUS((priv->ctemp * 5) - 65);
255 256
	mutex_unlock(&priv->lock);

257 258 259 260 261 262 263 264 265
	if ((tmp < MCELSIUS(-45)) || (tmp > MCELSIUS(125))) {
		struct device *dev = rcar_priv_to_dev(priv);

		dev_err(dev, "it couldn't measure temperature correctly\n");
		return -EIO;
	}

	*temp = tmp;

266 267 268
	return 0;
}

269 270 271 272 273 274 275 276 277 278 279 280 281 282
static int rcar_thermal_of_get_temp(void *data, int *temp)
{
	struct rcar_thermal_priv *priv = data;

	return rcar_thermal_get_current_temp(priv, temp);
}

static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp)
{
	struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);

	return rcar_thermal_get_current_temp(priv, temp);
}

283 284 285 286
static int rcar_thermal_get_trip_type(struct thermal_zone_device *zone,
				      int trip, enum thermal_trip_type *type)
{
	struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
287
	struct device *dev = rcar_priv_to_dev(priv);
288 289 290 291 292 293 294

	/* see rcar_thermal_get_temp() */
	switch (trip) {
	case 0: /* +90 <= temp */
		*type = THERMAL_TRIP_CRITICAL;
		break;
	default:
295
		dev_err(dev, "rcar driver trip error\n");
296 297 298 299 300 301 302
		return -EINVAL;
	}

	return 0;
}

static int rcar_thermal_get_trip_temp(struct thermal_zone_device *zone,
303
				      int trip, int *temp)
304 305
{
	struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
306
	struct device *dev = rcar_priv_to_dev(priv);
307 308 309 310 311 312 313

	/* see rcar_thermal_get_temp() */
	switch (trip) {
	case 0: /* +90 <= temp */
		*temp = MCELSIUS(90);
		break;
	default:
314
		dev_err(dev, "rcar driver trip error\n");
315 316 317 318 319 320 321 322 323 324
		return -EINVAL;
	}

	return 0;
}

static int rcar_thermal_notify(struct thermal_zone_device *zone,
			       int trip, enum thermal_trip_type type)
{
	struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
325
	struct device *dev = rcar_priv_to_dev(priv);
326 327 328 329

	switch (type) {
	case THERMAL_TRIP_CRITICAL:
		/* FIXME */
330
		dev_warn(dev, "Thermal reached to critical temperature\n");
331 332 333 334 335 336 337 338
		break;
	default:
		break;
	}

	return 0;
}

339 340 341 342
static const struct thermal_zone_of_device_ops rcar_thermal_zone_of_ops = {
	.get_temp	= rcar_thermal_of_get_temp,
};

343
static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
344 345 346 347
	.get_temp	= rcar_thermal_get_temp,
	.get_trip_type	= rcar_thermal_get_trip_type,
	.get_trip_temp	= rcar_thermal_get_trip_temp,
	.notify		= rcar_thermal_notify,
348 349
};

350 351 352 353 354 355 356 357 358 359 360
/*
 *		interrupt
 */
#define rcar_thermal_irq_enable(p)	_rcar_thermal_irq_ctrl(p, 1)
#define rcar_thermal_irq_disable(p)	_rcar_thermal_irq_ctrl(p, 0)
static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable)
{
	struct rcar_thermal_common *common = priv->common;
	unsigned long flags;
	u32 mask = 0x3 << rcar_id_to_shift(priv); /* enable Rising/Falling */

361 362 363
	if (!rcar_has_irq_support(priv))
		return;

364 365 366 367 368 369 370 371 372 373
	spin_lock_irqsave(&common->lock, flags);

	rcar_thermal_common_bset(common, INTMSK, mask, enable ? 0 : mask);

	spin_unlock_irqrestore(&common->lock, flags);
}

static void rcar_thermal_work(struct work_struct *work)
{
	struct rcar_thermal_priv *priv;
374
	int cctemp, nctemp;
375
	int ret;
376 377 378

	priv = container_of(work, struct rcar_thermal_priv, work.work);

379 380 381 382
	ret = rcar_thermal_get_current_temp(priv, &cctemp);
	if (ret < 0)
		return;

383 384 385 386
	ret = rcar_thermal_update_temp(priv);
	if (ret < 0)
		return;

387
	rcar_thermal_irq_enable(priv);
388

389 390 391 392
	ret = rcar_thermal_get_current_temp(priv, &nctemp);
	if (ret < 0)
		return;

393
	if (nctemp != cctemp)
394 395
		thermal_zone_device_update(priv->zone,
					   THERMAL_EVENT_UNSPECIFIED);
396 397 398 399 400 401 402 403
}

static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status)
{
	struct device *dev = rcar_priv_to_dev(priv);

	status = (status >> rcar_id_to_shift(priv)) & 0x3;

404
	if (status) {
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
		dev_dbg(dev, "thermal%d %s%s\n",
			priv->id,
			(status & 0x2) ? "Rising " : "",
			(status & 0x1) ? "Falling" : "");
	}

	return status;
}

static irqreturn_t rcar_thermal_irq(int irq, void *data)
{
	struct rcar_thermal_common *common = data;
	struct rcar_thermal_priv *priv;
	unsigned long flags;
	u32 status, mask;

	spin_lock_irqsave(&common->lock, flags);

	mask	= rcar_thermal_common_read(common, INTMSK);
	status	= rcar_thermal_common_read(common, STR);
	rcar_thermal_common_write(common, STR, 0x000F0F0F & mask);

	spin_unlock_irqrestore(&common->lock, flags);

	status = status & ~mask;

	/*
	 * check the status
	 */
	rcar_thermal_for_each_priv(priv, common) {
		if (rcar_thermal_had_changed(priv, status)) {
			rcar_thermal_irq_disable(priv);
			schedule_delayed_work(&priv->work,
					      msecs_to_jiffies(300));
		}
	}

	return IRQ_HANDLED;
}

445 446 447
/*
 *		platform functions
 */
448 449 450 451 452 453 454
static int rcar_thermal_remove(struct platform_device *pdev)
{
	struct rcar_thermal_common *common = platform_get_drvdata(pdev);
	struct device *dev = &pdev->dev;
	struct rcar_thermal_priv *priv;

	rcar_thermal_for_each_priv(priv, common) {
455
		rcar_thermal_irq_disable(priv);
456
		if (priv->chip->use_of_thermal)
457
			thermal_remove_hwmon_sysfs(priv->zone);
458 459
		else
			thermal_zone_device_unregister(priv->zone);
460 461 462 463 464 465 466 467
	}

	pm_runtime_put(dev);
	pm_runtime_disable(dev);

	return 0;
}

468 469
static int rcar_thermal_probe(struct platform_device *pdev)
{
470
	struct rcar_thermal_common *common;
471
	struct rcar_thermal_priv *priv;
472 473
	struct device *dev = &pdev->dev;
	struct resource *res, *irq;
474
	const struct rcar_thermal_chip *chip = of_device_get_match_data(dev);
475 476
	int mres = 0;
	int i;
477
	int ret = -ENODEV;
478
	int idle = IDLE_INTERVAL;
479
	u32 enr_bits = 0;
480

481
	common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
482
	if (!common)
483 484
		return -ENOMEM;

485 486
	platform_set_drvdata(pdev, common);

487
	INIT_LIST_HEAD(&common->head);
488
	spin_lock_init(&common->lock);
489 490
	common->dev = dev;

491 492 493
	pm_runtime_enable(dev);
	pm_runtime_get_sync(dev);

494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
	for (i = 0; i < chip->nirqs; i++) {
		irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
		if (!irq)
			continue;
		if (!common->base) {
			/*
			 * platform has IRQ support.
			 * Then, driver uses common registers
			 * rcar_has_irq_support() will be enabled
			 */
			res = platform_get_resource(pdev, IORESOURCE_MEM,
						    mres++);
			common->base = devm_ioremap_resource(dev, res);
			if (IS_ERR(common->base))
				return PTR_ERR(common->base);

			idle = 0; /* polling delay is not needed */
		}
512

513 514 515 516 517 518 519 520 521 522
		ret = devm_request_irq(dev, irq->start, rcar_thermal_irq,
				       IRQF_SHARED, dev_name(dev), common);
		if (ret) {
			dev_err(dev, "irq request failed\n ");
			goto error_unregister;
		}

		/* update ENR bits */
		if (chip->irq_per_ch)
			enr_bits |= 1 << i;
523 524
	}

525 526 527 528 529 530 531
	for (i = 0;; i++) {
		res = platform_get_resource(pdev, IORESOURCE_MEM, mres++);
		if (!res)
			break;

		priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
		if (!priv) {
532 533
			ret = -ENOMEM;
			goto error_unregister;
534 535
		}

536
		priv->base = devm_ioremap_resource(dev, res);
537 538 539 540
		if (IS_ERR(priv->base)) {
			ret = PTR_ERR(priv->base);
			goto error_unregister;
		}
541 542

		priv->common = common;
543
		priv->id = i;
544
		priv->chip = chip;
545 546
		mutex_init(&priv->lock);
		INIT_LIST_HEAD(&priv->list);
547
		INIT_DELAYED_WORK(&priv->work, rcar_thermal_work);
548 549 550
		ret = rcar_thermal_update_temp(priv);
		if (ret < 0)
			goto error_unregister;
551

552
		if (chip->use_of_thermal)
553
			priv->zone = devm_thermal_zone_of_sensor_register(
554 555 556 557 558
						dev, i, priv,
						&rcar_thermal_zone_of_ops);
		else
			priv->zone = thermal_zone_device_register(
						"rcar_thermal",
559 560
						1, 0, priv,
						&rcar_thermal_zone_ops, NULL, 0,
561
						idle);
562 563
		if (IS_ERR(priv->zone)) {
			dev_err(dev, "can't register thermal zone\n");
564
			ret = PTR_ERR(priv->zone);
565
			priv->zone = NULL;
566 567 568
			goto error_unregister;
		}

569
		if (chip->use_of_thermal) {
570 571 572 573 574 575 576 577 578 579
			/*
			 * thermal_zone doesn't enable hwmon as default,
			 * but, enable it here to keep compatible
			 */
			priv->zone->tzp->no_hwmon = false;
			ret = thermal_add_hwmon_sysfs(priv->zone);
			if (ret)
				goto error_unregister;
		}

580
		rcar_thermal_irq_enable(priv);
581 582

		list_move_tail(&priv->list, &common->head);
583 584

		/* update ENR bits */
585 586
		if (!chip->irq_per_ch)
			enr_bits |= 3 << (i * 8);
587 588
	}

589
	if (common->base && enr_bits)
590 591
		rcar_thermal_common_write(common, ENR, enr_bits);

592
	dev_info(dev, "%d sensor probed\n", i);
593 594

	return 0;
595 596

error_unregister:
597
	rcar_thermal_remove(pdev);
598

599
	return ret;
600 601
}

602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
#ifdef CONFIG_PM_SLEEP
static int rcar_thermal_suspend(struct device *dev)
{
	struct rcar_thermal_common *common = dev_get_drvdata(dev);
	struct rcar_thermal_priv *priv = list_first_entry(&common->head,
							  typeof(*priv), list);

	if (priv->chip->needs_suspend_resume) {
		rcar_thermal_common_write(common, ENR, 0);
		rcar_thermal_irq_disable(priv);
		rcar_thermal_bset(priv, THSCR, CPCTL, 0);
	}

	return 0;
}

static int rcar_thermal_resume(struct device *dev)
{
	struct rcar_thermal_common *common = dev_get_drvdata(dev);
	struct rcar_thermal_priv *priv = list_first_entry(&common->head,
							  typeof(*priv), list);
	int ret;

	if (priv->chip->needs_suspend_resume) {
		ret = rcar_thermal_update_temp(priv);
		if (ret < 0)
			return ret;
		rcar_thermal_irq_enable(priv);
		rcar_thermal_common_write(common, ENR, 0x03);
	}

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(rcar_thermal_pm_ops, rcar_thermal_suspend,
			 rcar_thermal_resume);

640 641 642
static struct platform_driver rcar_thermal_driver = {
	.driver	= {
		.name	= "rcar_thermal",
643
		.pm = &rcar_thermal_pm_ops,
644
		.of_match_table = rcar_thermal_dt_ids,
645 646 647 648 649 650
	},
	.probe		= rcar_thermal_probe,
	.remove		= rcar_thermal_remove,
};
module_platform_driver(rcar_thermal_driver);

651
MODULE_LICENSE("GPL v2");
652 653
MODULE_DESCRIPTION("R-Car THS/TSC thermal sensor driver");
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");