ti-bandgap.c 42.5 KB
Newer Older
1
/*
2
 * TI Bandgap temperature sensor driver
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
 *
 * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
 * Author: J Keerthy <j-keerthy@ti.com>
 * Author: Moiz Sonasath <m-sonasath@ti.com>
 * Couple of fixes, DT and MFD adaptation:
 *   Eduardo Valentin <eduardo.valentin@ti.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <linux/module.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/types.h>
36
#include <linux/spinlock.h>
37 38 39 40
#include <linux/reboot.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
41
#include <linux/of_gpio.h>
42
#include <linux/io.h>
43

44
#include "ti-bandgap.h"
45

46 47
static int ti_bandgap_force_single_read(struct ti_bandgap *bgp, int id);

48 49
/***   Helper functions to access registers and their bitfields   ***/

50
/**
51 52
 * ti_bandgap_readl() - simple read helper function
 * @bgp: pointer to ti_bandgap structure
53 54 55
 * @reg: desired register (offset) to be read
 *
 * Helper function to read bandgap registers. It uses the io remapped area.
56
 * Return: the register value.
57
 */
58
static u32 ti_bandgap_readl(struct ti_bandgap *bgp, u32 reg)
59
{
60
	return readl(bgp->base + reg);
61 62
}

63
/**
64 65
 * ti_bandgap_writel() - simple write helper function
 * @bgp: pointer to ti_bandgap structure
66 67 68 69 70
 * @val: desired register value to be written
 * @reg: desired register (offset) to be written
 *
 * Helper function to write bandgap registers. It uses the io remapped area.
 */
71
static void ti_bandgap_writel(struct ti_bandgap *bgp, u32 val, u32 reg)
72
{
73
	writel(val, bgp->base + reg);
74 75
}

76 77 78 79 80 81
/**
 * DOC: macro to update bits.
 *
 * RMW_BITS() - used to read, modify and update bandgap bitfields.
 *            The value passed will be shifted.
 */
82
#define RMW_BITS(bgp, id, reg, mask, val)			\
83 84 85 86
do {								\
	struct temp_sensor_registers *t;			\
	u32 r;							\
								\
87
	t = bgp->conf->sensors[(id)].registers;		\
88
	r = ti_bandgap_readl(bgp, t->reg);			\
89 90
	r &= ~t->mask;						\
	r |= (val) << __ffs(t->mask);				\
91
	ti_bandgap_writel(bgp, r, t->reg);			\
92 93
} while (0)

94 95
/***   Basic helper functions   ***/

96
/**
97 98
 * ti_bandgap_power() - controls the power state of a bandgap device
 * @bgp: pointer to ti_bandgap structure
99 100 101 102
 * @on: desired power state (1 - on, 0 - off)
 *
 * Used to power on/off a bandgap device instance. Only used on those
 * that features tempsoff bit.
103 104
 *
 * Return: 0 on success, -ENOTSUPP if tempsoff is not supported.
105
 */
106
static int ti_bandgap_power(struct ti_bandgap *bgp, bool on)
107
{
P
Pavel Machek 已提交
108
	int i;
109

P
Pavel Machek 已提交
110 111
	if (!TI_BANDGAP_HAS(bgp, POWER_SWITCH))
		return -ENOTSUPP;
112

113
	for (i = 0; i < bgp->conf->sensor_count; i++)
114
		/* active on 0 */
115
		RMW_BITS(bgp, i, temp_sensor_ctrl, bgap_tempsoff_mask, !on);
P
Pavel Machek 已提交
116
	return 0;
117 118
}

119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
/**
 * ti_errata814_bandgap_read_temp() - helper function to read dra7 sensor temperature
 * @bgp: pointer to ti_bandgap structure
 * @reg: desired register (offset) to be read
 *
 * Function to read dra7 bandgap sensor temperature. This is done separately
 * so as to workaround the errata "Bandgap Temperature read Dtemp can be
 * corrupted" - Errata ID: i814".
 * Read accesses to registers listed below can be corrupted due to incorrect
 * resynchronization between clock domains.
 * Read access to registers below can be corrupted :
 * CTRL_CORE_DTEMP_MPU/GPU/CORE/DSPEVE/IVA_n (n = 0 to 4)
 * CTRL_CORE_TEMP_SENSOR_MPU/GPU/CORE/DSPEVE/IVA_n
 *
 * Return: the register value.
 */
static u32 ti_errata814_bandgap_read_temp(struct ti_bandgap *bgp,  u32 reg)
{
	u32 val1, val2;

	val1 = ti_bandgap_readl(bgp, reg);
	val2 = ti_bandgap_readl(bgp, reg);

	/* If both times we read the same value then that is right */
	if (val1 == val2)
		return val1;

	/* if val1 and val2 are different read it third time */
	return ti_bandgap_readl(bgp, reg);
}

150
/**
151 152
 * ti_bandgap_read_temp() - helper function to read sensor temperature
 * @bgp: pointer to ti_bandgap structure
153 154 155 156 157 158
 * @id: bandgap sensor id
 *
 * Function to concentrate the steps to read sensor temperature register.
 * This function is desired because, depending on bandgap device version,
 * it might be needed to freeze the bandgap state machine, before fetching
 * the register value.
159 160
 *
 * Return: temperature in ADC values.
161
 */
162
static u32 ti_bandgap_read_temp(struct ti_bandgap *bgp, int id)
163 164
{
	struct temp_sensor_registers *tsr;
165
	u32 temp, reg;
166

167
	tsr = bgp->conf->sensors[id].registers;
168 169
	reg = tsr->temp_sensor_ctrl;

170
	if (TI_BANDGAP_HAS(bgp, FREEZE_BIT)) {
171
		RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 1);
172 173 174 175 176 177 178 179
		/*
		 * In case we cannot read from cur_dtemp / dtemp_0,
		 * then we read from the last valid temp read
		 */
		reg = tsr->ctrl_dtemp_1;
	}

	/* read temperature */
180 181 182 183 184
	if (TI_BANDGAP_HAS(bgp, ERRATA_814))
		temp = ti_errata814_bandgap_read_temp(bgp, reg);
	else
		temp = ti_bandgap_readl(bgp, reg);

185 186
	temp &= tsr->bgap_dtemp_mask;

187
	if (TI_BANDGAP_HAS(bgp, FREEZE_BIT))
188
		RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 0);
189 190 191 192

	return temp;
}

193 194
/***   IRQ handlers   ***/

195
/**
196
 * ti_bandgap_talert_irq_handler() - handles Temperature alert IRQs
197
 * @irq: IRQ number
198
 * @data: private data (struct ti_bandgap *)
199 200 201 202 203 204
 *
 * This is the Talert handler. Use it only if bandgap device features
 * HAS(TALERT). This handler goes over all sensors and checks their
 * conditions and acts accordingly. In case there are events pending,
 * it will reset the event mask to wait for the opposite event (next event).
 * Every time there is a new event, it will be reported to thermal layer.
205 206
 *
 * Return: IRQ_HANDLED
207
 */
208
static irqreturn_t ti_bandgap_talert_irq_handler(int irq, void *data)
209
{
210
	struct ti_bandgap *bgp = data;
211
	struct temp_sensor_registers *tsr;
212
	u32 t_hot = 0, t_cold = 0, ctrl;
213 214
	int i;

215 216 217
	spin_lock(&bgp->lock);
	for (i = 0; i < bgp->conf->sensor_count; i++) {
		tsr = bgp->conf->sensors[i].registers;
218
		ctrl = ti_bandgap_readl(bgp, tsr->bgap_status);
219 220 221

		/* Read the status of t_hot */
		t_hot = ctrl & tsr->status_hot_mask;
222 223

		/* Read the status of t_cold */
224
		t_cold = ctrl & tsr->status_cold_mask;
225 226 227 228

		if (!t_cold && !t_hot)
			continue;

229
		ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
230 231 232 233 234 235 236 237 238 239 240 241 242
		/*
		 * One TALERT interrupt: Two sources
		 * If the interrupt is due to t_hot then mask t_hot and
		 * and unmask t_cold else mask t_cold and unmask t_hot
		 */
		if (t_hot) {
			ctrl &= ~tsr->mask_hot_mask;
			ctrl |= tsr->mask_cold_mask;
		} else if (t_cold) {
			ctrl &= ~tsr->mask_cold_mask;
			ctrl |= tsr->mask_hot_mask;
		}

243
		ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
244

245
		dev_dbg(bgp->dev,
246
			"%s: IRQ from %s sensor: hotevent %d coldevent %d\n",
247
			__func__, bgp->conf->sensors[i].domain,
248 249
			t_hot, t_cold);

250
		/* report temperature to whom may concern */
251 252
		if (bgp->conf->report_temperature)
			bgp->conf->report_temperature(bgp, i);
253
	}
254
	spin_unlock(&bgp->lock);
255 256 257 258

	return IRQ_HANDLED;
}

259
/**
260
 * ti_bandgap_tshut_irq_handler() - handles Temperature shutdown signal
261 262 263 264 265 266
 * @irq: IRQ number
 * @data: private data (unused)
 *
 * This is the Tshut handler. Use it only if bandgap device features
 * HAS(TSHUT). If any sensor fires the Tshut signal, we simply shutdown
 * the system.
267 268
 *
 * Return: IRQ_HANDLED
269
 */
270
static irqreturn_t ti_bandgap_tshut_irq_handler(int irq, void *data)
271
{
272 273 274
	pr_emerg("%s: TSHUT temperature reached. Needs shut down...\n",
		 __func__);

275 276 277 278 279
	orderly_poweroff(true);

	return IRQ_HANDLED;
}

280 281
/***   Helper functions which manipulate conversion ADC <-> mi Celsius   ***/

282
/**
283 284
 * ti_bandgap_adc_to_mcelsius() - converts an ADC value to mCelsius scale
 * @bgp: struct ti_bandgap pointer
285 286 287 288 289 290
 * @adc_val: value in ADC representation
 * @t: address where to write the resulting temperature in mCelsius
 *
 * Simple conversion from ADC representation to mCelsius. In case the ADC value
 * is out of the ADC conv table range, it returns -ERANGE, 0 on success.
 * The conversion table is indexed by the ADC values.
291 292 293
 *
 * Return: 0 if conversion was successful, else -ERANGE in case the @adc_val
 * argument is out of the ADC conv table range.
294
 */
295
static
296
int ti_bandgap_adc_to_mcelsius(struct ti_bandgap *bgp, int adc_val, int *t)
297
{
298
	const struct ti_bandgap_data *conf = bgp->conf;
299 300

	/* look up for temperature in the table and return the temperature */
P
Pavel Machek 已提交
301 302
	if (adc_val < conf->adc_start_val || adc_val > conf->adc_end_val)
		return -ERANGE;
303

304
	*t = bgp->conf->conv_table[adc_val - conf->adc_start_val];
P
Pavel Machek 已提交
305
	return 0;
306 307
}

308
/**
309 310
 * ti_bandgap_mcelsius_to_adc() - converts a mCelsius value to ADC scale
 * @bgp: struct ti_bandgap pointer
311 312 313 314 315 316
 * @temp: value in mCelsius
 * @adc: address where to write the resulting temperature in ADC representation
 *
 * Simple conversion from mCelsius to ADC values. In case the temp value
 * is out of the ADC conv table range, it returns -ERANGE, 0 on success.
 * The conversion table is indexed by the ADC values.
317 318 319
 *
 * Return: 0 if conversion was successful, else -ERANGE in case the @temp
 * argument is out of the ADC conv table range.
320
 */
321
static
322
int ti_bandgap_mcelsius_to_adc(struct ti_bandgap *bgp, long temp, int *adc)
323
{
324
	const struct ti_bandgap_data *conf = bgp->conf;
325
	const int *conv_table = bgp->conf->conv_table;
P
Pavel Machek 已提交
326
	int high, low, mid;
327 328

	low = 0;
329
	high = conf->adc_end_val - conf->adc_start_val;
330 331
	mid = (high + low) / 2;

P
Pavel Machek 已提交
332 333
	if (temp < conv_table[low] || temp > conv_table[high])
		return -ERANGE;
334 335

	while (low < high) {
336
		if (temp < conv_table[mid])
337 338 339 340 341 342
			high = mid - 1;
		else
			low = mid + 1;
		mid = (low + high) / 2;
	}

343
	*adc = conf->adc_start_val + low;
P
Pavel Machek 已提交
344
	return 0;
345 346
}

347
/**
348 349
 * ti_bandgap_add_hyst() - add hysteresis (in mCelsius) to an ADC value
 * @bgp: struct ti_bandgap pointer
350 351 352 353 354
 * @adc_val: temperature value in ADC representation
 * @hyst_val: hysteresis value in mCelsius
 * @sum: address where to write the resulting temperature (in ADC scale)
 *
 * Adds an hysteresis value (in mCelsius) to a ADC temperature value.
355 356
 *
 * Return: 0 on success, -ERANGE otherwise.
357
 */
358
static
359 360
int ti_bandgap_add_hyst(struct ti_bandgap *bgp, int adc_val, int hyst_val,
			u32 *sum)
361 362 363 364 365 366 367
{
	int temp, ret;

	/*
	 * Need to add in the mcelsius domain, so we have a temperature
	 * the conv_table range
	 */
368
	ret = ti_bandgap_adc_to_mcelsius(bgp, adc_val, &temp);
369
	if (ret < 0)
P
Pavel Machek 已提交
370
		return ret;
371 372 373

	temp += hyst_val;

374
	ret = ti_bandgap_mcelsius_to_adc(bgp, temp, sum);
375 376 377
	return ret;
}

378 379
/***   Helper functions handling device Alert/Shutdown signals   ***/

380
/**
381 382
 * ti_bandgap_unmask_interrupts() - unmasks the events of thot & tcold
 * @bgp: struct ti_bandgap pointer
383
 * @id: bandgap sensor id
384 385 386 387 388 389
 * @t_hot: hot temperature value to trigger alert signal
 * @t_cold: cold temperature value to trigger alert signal
 *
 * Checks the requested t_hot and t_cold values and configures the IRQ event
 * masks accordingly. Call this function only if bandgap features HAS(TALERT).
 */
390 391
static void ti_bandgap_unmask_interrupts(struct ti_bandgap *bgp, int id,
					 u32 t_hot, u32 t_cold)
392 393 394 395 396
{
	struct temp_sensor_registers *tsr;
	u32 temp, reg_val;

	/* Read the current on die temperature */
397
	temp = ti_bandgap_read_temp(bgp, id);
398

399
	tsr = bgp->conf->sensors[id].registers;
400
	reg_val = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
401

402 403 404 405 406 407 408 409 410
	if (temp < t_hot)
		reg_val |= tsr->mask_hot_mask;
	else
		reg_val &= ~tsr->mask_hot_mask;

	if (t_cold < temp)
		reg_val |= tsr->mask_cold_mask;
	else
		reg_val &= ~tsr->mask_cold_mask;
411
	ti_bandgap_writel(bgp, reg_val, tsr->bgap_mask_ctrl);
412 413
}

414
/**
415 416
 * ti_bandgap_update_alert_threshold() - sequence to update thresholds
 * @bgp: struct ti_bandgap pointer
417 418 419 420 421 422 423 424 425 426
 * @id: bandgap sensor id
 * @val: value (ADC) of a new threshold
 * @hot: desired threshold to be updated. true if threshold hot, false if
 *       threshold cold
 *
 * It will program the required thresholds (hot and cold) for TALERT signal.
 * This function can be used to update t_hot or t_cold, depending on @hot value.
 * It checks the resulting t_hot and t_cold values, based on the new passed @val
 * and configures the thresholds so that t_hot is always greater than t_cold.
 * Call this function only if bandgap features HAS(TALERT).
427 428
 *
 * Return: 0 if no error, else corresponding error
429
 */
430 431
static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id,
					     int val, bool hot)
432
{
433
	struct temp_sensor_data *ts_data = bgp->conf->sensors[id].ts_data;
434
	struct temp_sensor_registers *tsr;
435
	u32 thresh_val, reg_val, t_hot, t_cold, ctrl;
436
	int err = 0;
437

438
	tsr = bgp->conf->sensors[id].registers;
439

440
	/* obtain the current value */
441
	thresh_val = ti_bandgap_readl(bgp, tsr->bgap_threshold);
442 443 444 445 446 447 448 449 450
	t_cold = (thresh_val & tsr->threshold_tcold_mask) >>
		__ffs(tsr->threshold_tcold_mask);
	t_hot = (thresh_val & tsr->threshold_thot_mask) >>
		__ffs(tsr->threshold_thot_mask);
	if (hot)
		t_hot = val;
	else
		t_cold = val;

451
	if (t_cold > t_hot) {
452
		if (hot)
453 454 455
			err = ti_bandgap_add_hyst(bgp, t_hot,
						  -ts_data->hyst_val,
						  &t_cold);
456
		else
457 458 459
			err = ti_bandgap_add_hyst(bgp, t_cold,
						  ts_data->hyst_val,
						  &t_hot);
460 461
	}

462
	/* write the new threshold values */
463 464 465 466
	reg_val = thresh_val &
		  ~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask);
	reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) |
		   (t_cold << __ffs(tsr->threshold_tcold_mask));
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494

	/**
	 * Errata i813:
	 * Spurious Thermal Alert: Talert can happen randomly while the device
	 * remains under the temperature limit defined for this event to trig.
	 * This spurious event is caused by a incorrect re-synchronization
	 * between clock domains. The comparison between configured threshold
	 * and current temperature value can happen while the value is
	 * transitioning (metastable), thus causing inappropriate event
	 * generation. No spurious event occurs as long as the threshold value
	 * stays unchanged. Spurious event can be generated while a thermal
	 * alert threshold is modified in
	 * CONTROL_BANDGAP_THRESHOLD_MPU/GPU/CORE/DSPEVE/IVA_n.
	 */

	if (TI_BANDGAP_HAS(bgp, ERRATA_813)) {
		/* Mask t_hot and t_cold events at the IP Level */
		ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);

		if (hot)
			ctrl &= ~tsr->mask_hot_mask;
		else
			ctrl &= ~tsr->mask_cold_mask;

		ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
	}

	/* Write the threshold value */
495
	ti_bandgap_writel(bgp, reg_val, tsr->bgap_threshold);
496

497 498 499 500 501 502 503 504 505 506 507
	if (TI_BANDGAP_HAS(bgp, ERRATA_813)) {
		/* Unmask t_hot and t_cold events at the IP Level */
		ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
		if (hot)
			ctrl |= tsr->mask_hot_mask;
		else
			ctrl |= tsr->mask_cold_mask;

		ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
	}

508
	if (err) {
509
		dev_err(bgp->dev, "failed to reprogram thot threshold\n");
510 511
		err = -EIO;
		goto exit;
512 513
	}

514
	ti_bandgap_unmask_interrupts(bgp, id, t_hot, t_cold);
515 516
exit:
	return err;
517 518
}

519
/**
520 521
 * ti_bandgap_validate() - helper to check the sanity of a struct ti_bandgap
 * @bgp: struct ti_bandgap pointer
522 523 524 525
 * @id: bandgap sensor id
 *
 * Checks if the bandgap pointer is valid and if the sensor id is also
 * applicable.
526 527 528
 *
 * Return: 0 if no errors, -EINVAL for invalid @bgp pointer or -ERANGE if
 * @id cannot index @bgp sensors.
529
 */
530
static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id)
531
{
532
	if (!bgp || IS_ERR(bgp)) {
533
		pr_err("%s: invalid bandgap pointer\n", __func__);
P
Pavel Machek 已提交
534
		return -EINVAL;
535 536
	}

537 538
	if ((id < 0) || (id >= bgp->conf->sensor_count)) {
		dev_err(bgp->dev, "%s: sensor id out of range (%d)\n",
539
			__func__, id);
P
Pavel Machek 已提交
540
		return -ERANGE;
541 542
	}

P
Pavel Machek 已提交
543
	return 0;
544 545
}

546
/**
547 548
 * _ti_bandgap_write_threshold() - helper to update TALERT t_cold or t_hot
 * @bgp: struct ti_bandgap pointer
549 550 551 552 553 554 555 556 557
 * @id: bandgap sensor id
 * @val: value (mCelsius) of a new threshold
 * @hot: desired threshold to be updated. true if threshold hot, false if
 *       threshold cold
 *
 * It will update the required thresholds (hot and cold) for TALERT signal.
 * This function can be used to update t_hot or t_cold, depending on @hot value.
 * Validates the mCelsius range and update the requested threshold.
 * Call this function only if bandgap features HAS(TALERT).
558 559
 *
 * Return: 0 if no error, else corresponding error value.
560
 */
561 562
static int _ti_bandgap_write_threshold(struct ti_bandgap *bgp, int id, int val,
				       bool hot)
563
{
564 565 566 567 568
	struct temp_sensor_data *ts_data;
	struct temp_sensor_registers *tsr;
	u32 adc_val;
	int ret;

569
	ret = ti_bandgap_validate(bgp, id);
570
	if (ret)
P
Pavel Machek 已提交
571
		return ret;
572

P
Pavel Machek 已提交
573 574
	if (!TI_BANDGAP_HAS(bgp, TALERT))
		return -ENOTSUPP;
575

576 577
	ts_data = bgp->conf->sensors[id].ts_data;
	tsr = bgp->conf->sensors[id].registers;
578 579 580 581 582 583
	if (hot) {
		if (val < ts_data->min_temp + ts_data->hyst_val)
			ret = -EINVAL;
	} else {
		if (val > ts_data->max_temp + ts_data->hyst_val)
			ret = -EINVAL;
584 585
	}

586
	if (ret)
P
Pavel Machek 已提交
587
		return ret;
588

589
	ret = ti_bandgap_mcelsius_to_adc(bgp, val, &adc_val);
590
	if (ret < 0)
P
Pavel Machek 已提交
591
		return ret;
592

593
	spin_lock(&bgp->lock);
594
	ret = ti_bandgap_update_alert_threshold(bgp, id, adc_val, hot);
595
	spin_unlock(&bgp->lock);
596
	return ret;
597 598
}

599
/**
600 601
 * _ti_bandgap_read_threshold() - helper to read TALERT t_cold or t_hot
 * @bgp: struct ti_bandgap pointer
602 603 604 605 606 607 608 609
 * @id: bandgap sensor id
 * @val: value (mCelsius) of a threshold
 * @hot: desired threshold to be read. true if threshold hot, false if
 *       threshold cold
 *
 * It will fetch the required thresholds (hot and cold) for TALERT signal.
 * This function can be used to read t_hot or t_cold, depending on @hot value.
 * Call this function only if bandgap features HAS(TALERT).
610 611 612
 *
 * Return: 0 if no error, -ENOTSUPP if it has no TALERT support, or the
 * corresponding error value if some operation fails.
613
 */
614 615
static int _ti_bandgap_read_threshold(struct ti_bandgap *bgp, int id,
				      int *val, bool hot)
616 617
{
	struct temp_sensor_registers *tsr;
618 619
	u32 temp, mask;
	int ret = 0;
620

621
	ret = ti_bandgap_validate(bgp, id);
622
	if (ret)
623
		goto exit;
624

625
	if (!TI_BANDGAP_HAS(bgp, TALERT)) {
626 627 628
		ret = -ENOTSUPP;
		goto exit;
	}
629

630
	tsr = bgp->conf->sensors[id].registers;
631 632 633 634 635
	if (hot)
		mask = tsr->threshold_thot_mask;
	else
		mask = tsr->threshold_tcold_mask;

636
	temp = ti_bandgap_readl(bgp, tsr->bgap_threshold);
637
	temp = (temp & mask) >> __ffs(mask);
P
Pavel Machek 已提交
638
	ret = ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
639
	if (ret) {
640
		dev_err(bgp->dev, "failed to read thot\n");
641 642
		ret = -EIO;
		goto exit;
643 644
	}

645
	*val = temp;
646

647
exit:
648
	return ret;
649 650
}

651 652 653
/***   Exposed APIs   ***/

/**
654
 * ti_bandgap_read_thot() - reads sensor current thot
655 656 657
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @thot: resulting current thot value
658
 *
659
 * Return: 0 on success or the proper error code
660
 */
661
int ti_bandgap_read_thot(struct ti_bandgap *bgp, int id, int *thot)
662
{
663
	return _ti_bandgap_read_threshold(bgp, id, thot, true);
664 665
}

666
/**
667
 * ti_bandgap_write_thot() - sets sensor current thot
668 669 670
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @val: desired thot value
671
 *
672
 * Return: 0 on success or the proper error code
673
 */
674
int ti_bandgap_write_thot(struct ti_bandgap *bgp, int id, int val)
675
{
676
	return _ti_bandgap_write_threshold(bgp, id, val, true);
677 678 679
}

/**
680
 * ti_bandgap_read_tcold() - reads sensor current tcold
681 682 683
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @tcold: resulting current tcold value
684
 *
685
 * Return: 0 on success or the proper error code
686
 */
687
int ti_bandgap_read_tcold(struct ti_bandgap *bgp, int id, int *tcold)
688
{
689
	return _ti_bandgap_read_threshold(bgp, id, tcold, false);
690 691 692
}

/**
693
 * ti_bandgap_write_tcold() - sets the sensor tcold
694 695 696
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @val: desired tcold value
697
 *
698
 * Return: 0 on success or the proper error code
699
 */
700
int ti_bandgap_write_tcold(struct ti_bandgap *bgp, int id, int val)
701
{
702
	return _ti_bandgap_write_threshold(bgp, id, val, false);
703 704
}

705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
/**
 * ti_bandgap_read_counter() - read the sensor counter
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: resulting update interval in miliseconds
 */
static void ti_bandgap_read_counter(struct ti_bandgap *bgp, int id,
				    int *interval)
{
	struct temp_sensor_registers *tsr;
	int time;

	tsr = bgp->conf->sensors[id].registers;
	time = ti_bandgap_readl(bgp, tsr->bgap_counter);
	time = (time & tsr->counter_mask) >>
					__ffs(tsr->counter_mask);
	time = time * 1000 / bgp->clk_rate;
	*interval = time;
}

/**
 * ti_bandgap_read_counter_delay() - read the sensor counter delay
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: resulting update interval in miliseconds
 */
static void ti_bandgap_read_counter_delay(struct ti_bandgap *bgp, int id,
					  int *interval)
{
	struct temp_sensor_registers *tsr;
	int reg_val;

	tsr = bgp->conf->sensors[id].registers;

	reg_val = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
	reg_val = (reg_val & tsr->mask_counter_delay_mask) >>
				__ffs(tsr->mask_counter_delay_mask);
	switch (reg_val) {
	case 0:
		*interval = 0;
		break;
	case 1:
		*interval = 1;
		break;
	case 2:
		*interval = 10;
		break;
	case 3:
		*interval = 100;
		break;
	case 4:
		*interval = 250;
		break;
	case 5:
		*interval = 500;
		break;
	default:
		dev_warn(bgp->dev, "Wrong counter delay value read from register %X",
			 reg_val);
	}
}

767
/**
768
 * ti_bandgap_read_update_interval() - read the sensor update interval
769 770 771
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: resulting update interval in miliseconds
772
 *
773
 * Return: 0 on success or the proper error code
774
 */
775 776
int ti_bandgap_read_update_interval(struct ti_bandgap *bgp, int id,
				    int *interval)
777
{
778
	int ret = 0;
779

780
	ret = ti_bandgap_validate(bgp, id);
781
	if (ret)
782
		goto exit;
783

784 785 786 787 788
	if (!TI_BANDGAP_HAS(bgp, COUNTER) &&
	    !TI_BANDGAP_HAS(bgp, COUNTER_DELAY)) {
		ret = -ENOTSUPP;
		goto exit;
	}
789

790 791 792 793
	if (TI_BANDGAP_HAS(bgp, COUNTER)) {
		ti_bandgap_read_counter(bgp, id, interval);
		goto exit;
	}
794

795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
	ti_bandgap_read_counter_delay(bgp, id, interval);
exit:
	return ret;
}

/**
 * ti_bandgap_write_counter_delay() - set the counter_delay
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: desired update interval in miliseconds
 *
 * Return: 0 on success or the proper error code
 */
static int ti_bandgap_write_counter_delay(struct ti_bandgap *bgp, int id,
					  u32 interval)
{
	int rval;

	switch (interval) {
	case 0: /* Immediate conversion */
		rval = 0x0;
		break;
	case 1: /* Conversion after ever 1ms */
		rval = 0x1;
		break;
	case 10: /* Conversion after ever 10ms */
		rval = 0x2;
		break;
	case 100: /* Conversion after ever 100ms */
		rval = 0x3;
		break;
	case 250: /* Conversion after ever 250ms */
		rval = 0x4;
		break;
	case 500: /* Conversion after ever 500ms */
		rval = 0x5;
		break;
	default:
		dev_warn(bgp->dev, "Delay %d ms is not supported\n", interval);
		return -EINVAL;
	}

	spin_lock(&bgp->lock);
	RMW_BITS(bgp, id, bgap_mask_ctrl, mask_counter_delay_mask, rval);
	spin_unlock(&bgp->lock);
840 841 842 843

	return 0;
}

844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
/**
 * ti_bandgap_write_counter() - set the bandgap sensor counter
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: desired update interval in miliseconds
 */
static void ti_bandgap_write_counter(struct ti_bandgap *bgp, int id,
				     u32 interval)
{
	interval = interval * bgp->clk_rate / 1000;
	spin_lock(&bgp->lock);
	RMW_BITS(bgp, id, bgap_counter, counter_mask, interval);
	spin_unlock(&bgp->lock);
}

859
/**
860
 * ti_bandgap_write_update_interval() - set the update interval
861 862 863
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @interval: desired update interval in miliseconds
864
 *
865
 * Return: 0 on success or the proper error code
866
 */
867 868
int ti_bandgap_write_update_interval(struct ti_bandgap *bgp,
				     int id, u32 interval)
869
{
870
	int ret = ti_bandgap_validate(bgp, id);
871
	if (ret)
872
		goto exit;
873

874 875 876 877 878
	if (!TI_BANDGAP_HAS(bgp, COUNTER) &&
	    !TI_BANDGAP_HAS(bgp, COUNTER_DELAY)) {
		ret = -ENOTSUPP;
		goto exit;
	}
879

880 881 882 883
	if (TI_BANDGAP_HAS(bgp, COUNTER)) {
		ti_bandgap_write_counter(bgp, id, interval);
		goto exit;
	}
884

885 886 887
	ret = ti_bandgap_write_counter_delay(bgp, id, interval);
exit:
	return ret;
888 889 890
}

/**
891
 * ti_bandgap_read_temperature() - report current temperature
892 893 894
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @temperature: resulting temperature
895
 *
896
 * Return: 0 on success or the proper error code
897
 */
898 899
int ti_bandgap_read_temperature(struct ti_bandgap *bgp, int id,
				int *temperature)
900 901 902 903
{
	u32 temp;
	int ret;

904
	ret = ti_bandgap_validate(bgp, id);
905 906 907
	if (ret)
		return ret;

908 909 910 911 912 913
	if (!TI_BANDGAP_HAS(bgp, MODE_CONFIG)) {
		ret = ti_bandgap_force_single_read(bgp, id);
		if (ret)
			return ret;
	}

914
	spin_lock(&bgp->lock);
915
	temp = ti_bandgap_read_temp(bgp, id);
916
	spin_unlock(&bgp->lock);
917

P
Pavel Machek 已提交
918
	ret = ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
919 920 921 922 923 924 925 926 927
	if (ret)
		return -EIO;

	*temperature = temp;

	return 0;
}

/**
928
 * ti_bandgap_set_sensor_data() - helper function to store thermal
929
 * framework related data.
930 931 932
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @data: thermal framework related data to be stored
933
 *
934
 * Return: 0 on success or the proper error code
935
 */
936
int ti_bandgap_set_sensor_data(struct ti_bandgap *bgp, int id, void *data)
937
{
938
	int ret = ti_bandgap_validate(bgp, id);
939 940 941
	if (ret)
		return ret;

942
	bgp->regval[id].data = data;
943 944 945 946 947

	return 0;
}

/**
948
 * ti_bandgap_get_sensor_data() - helper function to get thermal
949
 * framework related data.
950 951
 * @bgp: pointer to bandgap instance
 * @id: sensor id
952
 *
953
 * Return: data stored by set function with sensor id on success or NULL
954
 */
955
void *ti_bandgap_get_sensor_data(struct ti_bandgap *bgp, int id)
956
{
957
	int ret = ti_bandgap_validate(bgp, id);
958 959 960
	if (ret)
		return ERR_PTR(ret);

961
	return bgp->regval[id].data;
962 963
}

964 965
/***   Helper functions used during device initialization   ***/

966
/**
967 968
 * ti_bandgap_force_single_read() - executes 1 single ADC conversion
 * @bgp: pointer to struct ti_bandgap
969 970 971 972
 * @id: sensor id which it is desired to read 1 temperature
 *
 * Used to initialize the conversion state machine and set it to a valid
 * state. Called during device initialization and context restore events.
973 974
 *
 * Return: 0
975
 */
976
static int
977
ti_bandgap_force_single_read(struct ti_bandgap *bgp, int id)
978
{
979 980
	u32 counter = 1000;
	struct temp_sensor_registers *tsr;
981 982

	/* Select single conversion mode */
983
	if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
984
		RMW_BITS(bgp, id, bgap_mode_ctrl, mode_ctrl_mask, 0);
985 986

	/* Start of Conversion = 1 */
987
	RMW_BITS(bgp, id, temp_sensor_ctrl, bgap_soc_mask, 1);
988

989 990 991 992 993 994 995 996
	/* Wait for EOCZ going up */
	tsr = bgp->conf->sensors[id].registers;

	while (--counter) {
		if (ti_bandgap_readl(bgp, tsr->temp_sensor_ctrl) &
		    tsr->bgap_eocz_mask)
			break;
	}
997

998
	/* Start of Conversion = 0 */
999
	RMW_BITS(bgp, id, temp_sensor_ctrl, bgap_soc_mask, 0);
1000

1001 1002 1003 1004 1005 1006 1007 1008
	/* Wait for EOCZ going down */
	counter = 1000;
	while (--counter) {
		if (!(ti_bandgap_readl(bgp, tsr->temp_sensor_ctrl) &
		      tsr->bgap_eocz_mask))
			break;
	}

1009 1010 1011 1012
	return 0;
}

/**
1013 1014
 * ti_bandgap_set_continous_mode() - One time enabling of continuous mode
 * @bgp: pointer to struct ti_bandgap
1015
 *
1016 1017 1018 1019
 * Call this function only if HAS(MODE_CONFIG) is set. As this driver may
 * be used for junction temperature monitoring, it is desirable that the
 * sensors are operational all the time, so that alerts are generated
 * properly.
1020 1021
 *
 * Return: 0
1022
 */
1023
static int ti_bandgap_set_continuous_mode(struct ti_bandgap *bgp)
1024 1025 1026
{
	int i;

1027
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1028
		/* Perform a single read just before enabling continuous */
1029
		ti_bandgap_force_single_read(bgp, i);
1030
		RMW_BITS(bgp, i, bgap_mode_ctrl, mode_ctrl_mask, 1);
1031 1032 1033 1034 1035
	}

	return 0;
}

1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
/**
 * ti_bandgap_get_trend() - To fetch the temperature trend of a sensor
 * @bgp: pointer to struct ti_bandgap
 * @id: id of the individual sensor
 * @trend: Pointer to trend.
 *
 * This function needs to be called to fetch the temperature trend of a
 * Particular sensor. The function computes the difference in temperature
 * w.r.t time. For the bandgaps with built in history buffer the temperatures
 * are read from the buffer and for those without the Buffer -ENOTSUPP is
 * returned.
 *
 * Return: 0 if no error, else return corresponding error. If no
 *		error then the trend value is passed on to trend parameter
 */
int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend)
{
	struct temp_sensor_registers *tsr;
	u32 temp1, temp2, reg1, reg2;
	int t1, t2, interval, ret = 0;

	ret = ti_bandgap_validate(bgp, id);
	if (ret)
		goto exit;

	if (!TI_BANDGAP_HAS(bgp, HISTORY_BUFFER) ||
	    !TI_BANDGAP_HAS(bgp, FREEZE_BIT)) {
		ret = -ENOTSUPP;
		goto exit;
	}

1067 1068
	spin_lock(&bgp->lock);

1069 1070 1071
	tsr = bgp->conf->sensors[id].registers;

	/* Freeze and read the last 2 valid readings */
1072
	RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 1);
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
	reg1 = tsr->ctrl_dtemp_1;
	reg2 = tsr->ctrl_dtemp_2;

	/* read temperature from history buffer */
	temp1 = ti_bandgap_readl(bgp, reg1);
	temp1 &= tsr->bgap_dtemp_mask;

	temp2 = ti_bandgap_readl(bgp, reg2);
	temp2 &= tsr->bgap_dtemp_mask;

	/* Convert from adc values to mCelsius temperature */
	ret = ti_bandgap_adc_to_mcelsius(bgp, temp1, &t1);
	if (ret)
1086
		goto unfreeze;
1087 1088 1089

	ret = ti_bandgap_adc_to_mcelsius(bgp, temp2, &t2);
	if (ret)
1090
		goto unfreeze;
1091 1092 1093

	/* Fetch the update interval */
	ret = ti_bandgap_read_update_interval(bgp, id, &interval);
1094
	if (ret)
1095
		goto unfreeze;
1096

1097 1098 1099 1100
	/* Set the interval to 1 ms if bandgap counter delay is not set */
	if (interval == 0)
		interval = 1;

1101 1102 1103 1104 1105
	*trend = (t1 - t2) / interval;

	dev_dbg(bgp->dev, "The temperatures are t1 = %d and t2 = %d and trend =%d\n",
		t1, t2, *trend);

1106 1107 1108
unfreeze:
	RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 0);
	spin_unlock(&bgp->lock);
1109 1110 1111 1112
exit:
	return ret;
}

1113
/**
1114 1115
 * ti_bandgap_tshut_init() - setup and initialize tshut handling
 * @bgp: pointer to struct ti_bandgap
1116 1117 1118 1119 1120 1121 1122 1123
 * @pdev: pointer to device struct platform_device
 *
 * Call this function only in case the bandgap features HAS(TSHUT).
 * In this case, the driver needs to handle the TSHUT signal as an IRQ.
 * The IRQ is wired as a GPIO, and for this purpose, it is required
 * to specify which GPIO line is used. TSHUT IRQ is fired anytime
 * one of the bandgap sensors violates the TSHUT high/hot threshold.
 * And in that case, the system must go off.
1124 1125
 *
 * Return: 0 if no error, else error status
1126
 */
1127 1128
static int ti_bandgap_tshut_init(struct ti_bandgap *bgp,
				 struct platform_device *pdev)
1129
{
1130
	int gpio_nr = bgp->tshut_gpio;
1131 1132 1133 1134 1135
	int status;

	/* Request for gpio_86 line */
	status = gpio_request(gpio_nr, "tshut");
	if (status < 0) {
1136
		dev_err(bgp->dev, "Could not request for TSHUT GPIO:%i\n", 86);
1137 1138 1139 1140
		return status;
	}
	status = gpio_direction_input(gpio_nr);
	if (status) {
1141
		dev_err(bgp->dev, "Cannot set input TSHUT GPIO %d\n", gpio_nr);
1142 1143 1144
		return status;
	}

1145 1146
	status = request_irq(gpio_to_irq(gpio_nr), ti_bandgap_tshut_irq_handler,
			     IRQF_TRIGGER_RISING, "tshut", NULL);
1147 1148
	if (status) {
		gpio_free(gpio_nr);
1149
		dev_err(bgp->dev, "request irq failed for TSHUT");
1150 1151 1152 1153 1154
	}

	return 0;
}

1155
/**
1156 1157
 * ti_bandgap_alert_init() - setup and initialize talert handling
 * @bgp: pointer to struct ti_bandgap
1158 1159 1160 1161 1162 1163 1164
 * @pdev: pointer to device struct platform_device
 *
 * Call this function only in case the bandgap features HAS(TALERT).
 * In this case, the driver needs to handle the TALERT signals as an IRQs.
 * TALERT is a normal IRQ and it is fired any time thresholds (hot or cold)
 * are violated. In these situation, the driver must reprogram the thresholds,
 * accordingly to specified policy.
1165 1166
 *
 * Return: 0 if no error, else return corresponding error.
1167
 */
1168 1169
static int ti_bandgap_talert_init(struct ti_bandgap *bgp,
				  struct platform_device *pdev)
1170 1171 1172
{
	int ret;

1173 1174
	bgp->irq = platform_get_irq(pdev, 0);
	if (bgp->irq < 0) {
1175
		dev_err(&pdev->dev, "get_irq failed\n");
1176
		return bgp->irq;
1177
	}
1178
	ret = request_threaded_irq(bgp->irq, NULL,
1179
				   ti_bandgap_talert_irq_handler,
1180
				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
1181
				   "talert", bgp);
1182 1183 1184 1185 1186 1187 1188 1189
	if (ret) {
		dev_err(&pdev->dev, "Request threaded irq failed.\n");
		return ret;
	}

	return 0;
}

1190
static const struct of_device_id of_ti_bandgap_match[];
1191
/**
1192
 * ti_bandgap_build() - parse DT and setup a struct ti_bandgap
1193 1194 1195 1196
 * @pdev: pointer to device struct platform_device
 *
 * Used to read the device tree properties accordingly to the bandgap
 * matching version. Based on bandgap version and its capabilities it
1197
 * will build a struct ti_bandgap out of the required DT entries.
1198 1199 1200
 *
 * Return: valid bandgap structure if successful, else returns ERR_PTR
 * return value must be verified with IS_ERR.
1201
 */
1202
static struct ti_bandgap *ti_bandgap_build(struct platform_device *pdev)
1203 1204 1205
{
	struct device_node *node = pdev->dev.of_node;
	const struct of_device_id *of_id;
1206
	struct ti_bandgap *bgp;
1207 1208 1209 1210 1211 1212 1213 1214 1215
	struct resource *res;
	int i;

	/* just for the sake */
	if (!node) {
		dev_err(&pdev->dev, "no platform information available\n");
		return ERR_PTR(-EINVAL);
	}

1216
	bgp = devm_kzalloc(&pdev->dev, sizeof(*bgp), GFP_KERNEL);
1217
	if (!bgp) {
1218 1219 1220 1221
		dev_err(&pdev->dev, "Unable to allocate mem for driver ref\n");
		return ERR_PTR(-ENOMEM);
	}

1222
	of_id = of_match_device(of_ti_bandgap_match, &pdev->dev);
1223
	if (of_id)
1224
		bgp->conf = of_id->data;
1225

1226 1227 1228
	/* register shadow for context save and restore */
	bgp->regval = devm_kzalloc(&pdev->dev, sizeof(*bgp->regval) *
				   bgp->conf->sensor_count, GFP_KERNEL);
1229
	if (!bgp->regval) {
1230 1231 1232 1233
		dev_err(&pdev->dev, "Unable to allocate mem for driver ref\n");
		return ERR_PTR(-ENOMEM);
	}

1234 1235 1236 1237 1238 1239 1240
	i = 0;
	do {
		void __iomem *chunk;

		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
		if (!res)
			break;
1241
		chunk = devm_ioremap_resource(&pdev->dev, res);
1242
		if (i == 0)
1243
			bgp->base = chunk;
1244 1245
		if (IS_ERR(chunk))
			return ERR_CAST(chunk);
1246

1247 1248 1249
		i++;
	} while (res);

1250
	if (TI_BANDGAP_HAS(bgp, TSHUT)) {
1251
		bgp->tshut_gpio = of_get_gpio(node, 0);
1252
		if (!gpio_is_valid(bgp->tshut_gpio)) {
1253
			dev_err(&pdev->dev, "invalid gpio for tshut (%d)\n",
1254
				bgp->tshut_gpio);
1255 1256 1257 1258
			return ERR_PTR(-EINVAL);
		}
	}

1259
	return bgp;
1260 1261
}

1262 1263
/***   Device driver call backs   ***/

1264
static
1265
int ti_bandgap_probe(struct platform_device *pdev)
1266
{
1267
	struct ti_bandgap *bgp;
1268
	int clk_rate, ret, i;
1269

1270
	bgp = ti_bandgap_build(pdev);
1271
	if (IS_ERR(bgp)) {
1272
		dev_err(&pdev->dev, "failed to fetch platform data\n");
1273
		return PTR_ERR(bgp);
1274
	}
1275
	bgp->dev = &pdev->dev;
1276

1277 1278 1279 1280
	if (TI_BANDGAP_HAS(bgp, UNRELIABLE))
		dev_warn(&pdev->dev,
			 "This OMAP thermal sensor is unreliable. You've been warned\n");

1281 1282
	if (TI_BANDGAP_HAS(bgp, TSHUT)) {
		ret = ti_bandgap_tshut_init(bgp, pdev);
1283 1284 1285 1286 1287 1288 1289
		if (ret) {
			dev_err(&pdev->dev,
				"failed to initialize system tshut IRQ\n");
			return ret;
		}
	}

1290
	bgp->fclock = clk_get(NULL, bgp->conf->fclock_name);
1291
	if (IS_ERR(bgp->fclock)) {
1292
		dev_err(&pdev->dev, "failed to request fclock reference\n");
1293
		ret = PTR_ERR(bgp->fclock);
1294 1295 1296
		goto free_irqs;
	}

P
Pavel Machek 已提交
1297
	bgp->div_clk = clk_get(NULL, bgp->conf->div_ck_name);
1298
	if (IS_ERR(bgp->div_clk)) {
P
Pavel Machek 已提交
1299
		dev_err(&pdev->dev, "failed to request div_ts_ck clock ref\n");
1300
		ret = PTR_ERR(bgp->div_clk);
1301
		goto put_fclock;
1302 1303
	}

1304
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1305 1306 1307
		struct temp_sensor_registers *tsr;
		u32 val;

1308
		tsr = bgp->conf->sensors[i].registers;
1309 1310 1311 1312 1313
		/*
		 * check if the efuse has a non-zero value if not
		 * it is an untrimmed sample and the temperatures
		 * may not be accurate
		 */
1314
		val = ti_bandgap_readl(bgp, tsr->bgap_efuse);
1315
		if (!val)
1316 1317 1318 1319
			dev_info(&pdev->dev,
				 "Non-trimmed BGAP, Temp not accurate\n");
	}

1320 1321 1322
	clk_rate = clk_round_rate(bgp->div_clk,
				  bgp->conf->sensors[0].ts_data->max_freq);
	if (clk_rate < bgp->conf->sensors[0].ts_data->min_freq ||
1323
	    clk_rate <= 0) {
1324 1325 1326 1327 1328
		ret = -ENODEV;
		dev_err(&pdev->dev, "wrong clock rate (%d)\n", clk_rate);
		goto put_clks;
	}

1329
	ret = clk_set_rate(bgp->div_clk, clk_rate);
1330 1331 1332
	if (ret)
		dev_err(&pdev->dev, "Cannot re-set clock rate. Continuing\n");

1333
	bgp->clk_rate = clk_rate;
1334
	if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
1335
		clk_prepare_enable(bgp->fclock);
1336

1337

1338 1339 1340
	spin_lock_init(&bgp->lock);
	bgp->dev = &pdev->dev;
	platform_set_drvdata(pdev, bgp);
1341

1342
	ti_bandgap_power(bgp, true);
1343 1344

	/* Set default counter to 1 for now */
1345
	if (TI_BANDGAP_HAS(bgp, COUNTER))
1346 1347
		for (i = 0; i < bgp->conf->sensor_count; i++)
			RMW_BITS(bgp, i, bgap_counter, counter_mask, 1);
1348

1349
	/* Set default thresholds for alert and shutdown */
1350
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1351 1352
		struct temp_sensor_data *ts_data;

1353
		ts_data = bgp->conf->sensors[i].ts_data;
1354

1355
		if (TI_BANDGAP_HAS(bgp, TALERT)) {
1356
			/* Set initial Talert thresholds */
1357
			RMW_BITS(bgp, i, bgap_threshold,
1358
				 threshold_tcold_mask, ts_data->t_cold);
1359
			RMW_BITS(bgp, i, bgap_threshold,
1360 1361
				 threshold_thot_mask, ts_data->t_hot);
			/* Enable the alert events */
1362 1363
			RMW_BITS(bgp, i, bgap_mask_ctrl, mask_hot_mask, 1);
			RMW_BITS(bgp, i, bgap_mask_ctrl, mask_cold_mask, 1);
1364 1365
		}

1366
		if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG)) {
1367
			/* Set initial Tshut thresholds */
1368
			RMW_BITS(bgp, i, tshut_threshold,
1369
				 tshut_hot_mask, ts_data->tshut_hot);
1370
			RMW_BITS(bgp, i, tshut_threshold,
1371
				 tshut_cold_mask, ts_data->tshut_cold);
1372 1373 1374
		}
	}

1375 1376
	if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
		ti_bandgap_set_continuous_mode(bgp);
1377 1378

	/* Set .250 seconds time as default counter */
1379
	if (TI_BANDGAP_HAS(bgp, COUNTER))
1380 1381 1382
		for (i = 0; i < bgp->conf->sensor_count; i++)
			RMW_BITS(bgp, i, bgap_counter, counter_mask,
				 bgp->clk_rate / 4);
1383 1384

	/* Every thing is good? Then expose the sensors */
1385
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1386 1387
		char *domain;

1388 1389 1390 1391 1392
		if (bgp->conf->sensors[i].register_cooling) {
			ret = bgp->conf->sensors[i].register_cooling(bgp, i);
			if (ret)
				goto remove_sensors;
		}
1393

1394 1395 1396 1397 1398 1399
		if (bgp->conf->expose_sensor) {
			domain = bgp->conf->sensors[i].domain;
			ret = bgp->conf->expose_sensor(bgp, i, domain);
			if (ret)
				goto remove_last_cooling;
		}
1400 1401 1402 1403 1404 1405 1406
	}

	/*
	 * Enable the Interrupts once everything is set. Otherwise irq handler
	 * might be called as soon as it is enabled where as rest of framework
	 * is still getting initialised.
	 */
1407 1408
	if (TI_BANDGAP_HAS(bgp, TALERT)) {
		ret = ti_bandgap_talert_init(bgp, pdev);
1409 1410
		if (ret) {
			dev_err(&pdev->dev, "failed to initialize Talert IRQ\n");
1411
			i = bgp->conf->sensor_count;
1412 1413 1414 1415 1416 1417
			goto disable_clk;
		}
	}

	return 0;

1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428
remove_last_cooling:
	if (bgp->conf->sensors[i].unregister_cooling)
		bgp->conf->sensors[i].unregister_cooling(bgp, i);
remove_sensors:
	for (i--; i >= 0; i--) {
		if (bgp->conf->sensors[i].unregister_cooling)
			bgp->conf->sensors[i].unregister_cooling(bgp, i);
		if (bgp->conf->remove_sensor)
			bgp->conf->remove_sensor(bgp, i);
	}
	ti_bandgap_power(bgp, false);
1429
disable_clk:
1430
	if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
1431
		clk_disable_unprepare(bgp->fclock);
1432
put_clks:
1433
	clk_put(bgp->div_clk);
1434 1435
put_fclock:
	clk_put(bgp->fclock);
1436
free_irqs:
1437
	if (TI_BANDGAP_HAS(bgp, TSHUT)) {
1438 1439
		free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
		gpio_free(bgp->tshut_gpio);
1440 1441 1442 1443 1444 1445
	}

	return ret;
}

static
1446
int ti_bandgap_remove(struct platform_device *pdev)
1447
{
1448
	struct ti_bandgap *bgp = platform_get_drvdata(pdev);
1449 1450 1451
	int i;

	/* First thing is to remove sensor interfaces */
1452
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1453
		if (bgp->conf->sensors[i].unregister_cooling)
1454
			bgp->conf->sensors[i].unregister_cooling(bgp, i);
1455

1456 1457
		if (bgp->conf->remove_sensor)
			bgp->conf->remove_sensor(bgp, i);
1458 1459
	}

1460
	ti_bandgap_power(bgp, false);
1461

1462
	if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
1463 1464 1465
		clk_disable_unprepare(bgp->fclock);
	clk_put(bgp->fclock);
	clk_put(bgp->div_clk);
1466

1467
	if (TI_BANDGAP_HAS(bgp, TALERT))
1468
		free_irq(bgp->irq, bgp);
1469

1470
	if (TI_BANDGAP_HAS(bgp, TSHUT)) {
1471 1472
		free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
		gpio_free(bgp->tshut_gpio);
1473 1474 1475 1476 1477
	}

	return 0;
}

1478
#ifdef CONFIG_PM_SLEEP
1479
static int ti_bandgap_save_ctxt(struct ti_bandgap *bgp)
1480 1481 1482
{
	int i;

1483
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1484 1485 1486
		struct temp_sensor_registers *tsr;
		struct temp_sensor_regval *rval;

1487
		rval = &bgp->regval[i];
1488
		tsr = bgp->conf->sensors[i].registers;
1489

1490 1491
		if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
			rval->bg_mode_ctrl = ti_bandgap_readl(bgp,
1492
							tsr->bgap_mode_ctrl);
1493 1494
		if (TI_BANDGAP_HAS(bgp, COUNTER))
			rval->bg_counter = ti_bandgap_readl(bgp,
1495
							tsr->bgap_counter);
1496 1497
		if (TI_BANDGAP_HAS(bgp, TALERT)) {
			rval->bg_threshold = ti_bandgap_readl(bgp,
1498
							tsr->bgap_threshold);
1499
			rval->bg_ctrl = ti_bandgap_readl(bgp,
1500
						   tsr->bgap_mask_ctrl);
1501 1502
		}

1503 1504
		if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG))
			rval->tshut_threshold = ti_bandgap_readl(bgp,
1505
						   tsr->tshut_threshold);
1506 1507 1508 1509 1510
	}

	return 0;
}

1511
static int ti_bandgap_restore_ctxt(struct ti_bandgap *bgp)
1512 1513 1514
{
	int i;

1515
	for (i = 0; i < bgp->conf->sensor_count; i++) {
1516 1517 1518 1519
		struct temp_sensor_registers *tsr;
		struct temp_sensor_regval *rval;
		u32 val = 0;

1520
		rval = &bgp->regval[i];
1521
		tsr = bgp->conf->sensors[i].registers;
1522

1523 1524
		if (TI_BANDGAP_HAS(bgp, COUNTER))
			val = ti_bandgap_readl(bgp, tsr->bgap_counter);
1525

1526 1527 1528
		if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG))
			ti_bandgap_writel(bgp, rval->tshut_threshold,
					  tsr->tshut_threshold);
1529 1530 1531
		/* Force immediate temperature measurement and update
		 * of the DTEMP field
		 */
1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544
		ti_bandgap_force_single_read(bgp, i);

		if (TI_BANDGAP_HAS(bgp, COUNTER))
			ti_bandgap_writel(bgp, rval->bg_counter,
					  tsr->bgap_counter);
		if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
			ti_bandgap_writel(bgp, rval->bg_mode_ctrl,
					  tsr->bgap_mode_ctrl);
		if (TI_BANDGAP_HAS(bgp, TALERT)) {
			ti_bandgap_writel(bgp, rval->bg_threshold,
					  tsr->bgap_threshold);
			ti_bandgap_writel(bgp, rval->bg_ctrl,
					  tsr->bgap_mask_ctrl);
1545 1546 1547 1548 1549 1550
		}
	}

	return 0;
}

1551
static int ti_bandgap_suspend(struct device *dev)
1552
{
1553
	struct ti_bandgap *bgp = dev_get_drvdata(dev);
1554 1555
	int err;

1556 1557
	err = ti_bandgap_save_ctxt(bgp);
	ti_bandgap_power(bgp, false);
1558

1559
	if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
1560
		clk_disable_unprepare(bgp->fclock);
1561 1562 1563 1564

	return err;
}

1565
static int ti_bandgap_resume(struct device *dev)
1566
{
1567
	struct ti_bandgap *bgp = dev_get_drvdata(dev);
1568

1569
	if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
1570
		clk_prepare_enable(bgp->fclock);
1571

1572
	ti_bandgap_power(bgp, true);
1573

1574
	return ti_bandgap_restore_ctxt(bgp);
1575
}
1576 1577
static SIMPLE_DEV_PM_OPS(ti_bandgap_dev_pm_ops, ti_bandgap_suspend,
			 ti_bandgap_resume);
1578

1579
#define DEV_PM_OPS	(&ti_bandgap_dev_pm_ops)
1580 1581 1582 1583
#else
#define DEV_PM_OPS	NULL
#endif

1584
static const struct of_device_id of_ti_bandgap_match[] = {
1585 1586 1587 1588 1589
#ifdef CONFIG_OMAP3_THERMAL
	{
		.compatible = "ti,omap34xx-bandgap",
		.data = (void *)&omap34xx_data,
	},
1590 1591 1592 1593
	{
		.compatible = "ti,omap36xx-bandgap",
		.data = (void *)&omap36xx_data,
	},
1594
#endif
1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607
#ifdef CONFIG_OMAP4_THERMAL
	{
		.compatible = "ti,omap4430-bandgap",
		.data = (void *)&omap4430_data,
	},
	{
		.compatible = "ti,omap4460-bandgap",
		.data = (void *)&omap4460_data,
	},
	{
		.compatible = "ti,omap4470-bandgap",
		.data = (void *)&omap4470_data,
	},
1608 1609 1610 1611 1612 1613
#endif
#ifdef CONFIG_OMAP5_THERMAL
	{
		.compatible = "ti,omap5430-bandgap",
		.data = (void *)&omap5430_data,
	},
1614 1615 1616 1617 1618 1619
#endif
#ifdef CONFIG_DRA752_THERMAL
	{
		.compatible = "ti,dra752-bandgap",
		.data = (void *)&dra752_data,
	},
1620
#endif
1621 1622 1623
	/* Sentinel */
	{ },
};
1624
MODULE_DEVICE_TABLE(of, of_ti_bandgap_match);
1625

1626 1627 1628
static struct platform_driver ti_bandgap_sensor_driver = {
	.probe = ti_bandgap_probe,
	.remove = ti_bandgap_remove,
1629
	.driver = {
1630
			.name = "ti-soc-thermal",
1631
			.pm = DEV_PM_OPS,
1632
			.of_match_table	= of_ti_bandgap_match,
1633 1634 1635
	},
};

1636
module_platform_driver(ti_bandgap_sensor_driver);
1637 1638 1639

MODULE_DESCRIPTION("OMAP4+ bandgap temperature sensor driver");
MODULE_LICENSE("GPL v2");
1640
MODULE_ALIAS("platform:ti-soc-thermal");
1641
MODULE_AUTHOR("Texas Instrument Inc.");