File Index
Files and directories
Sign in
FILE

exynos_tmu.c

File preview with syntax highlighting.

linux-6.19.14/drivers/thermal/samsung/exynos_tmu.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * exynos_tmu.c - Samsung Exynos TMU (Thermal Management Unit)
   4 *
   5 *  Copyright (C) 2014 Samsung Electronics
   6 *  Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
   7 *  Lukasz Majewski <l.majewski@samsung.com>
   8 *
   9 *  Copyright (C) 2011 Samsung Electronics
  10 *  Donggeun Kim <dg77.kim@samsung.com>
  11 *  Amit Daniel Kachhap <amit.kachhap@linaro.org>
  12 */
  13
  14#include <linux/clk.h>
  15#include <linux/io.h>
  16#include <linux/interrupt.h>
  17#include <linux/module.h>
  18#include <linux/of.h>
  19#include <linux/of_address.h>
  20#include <linux/of_irq.h>
  21#include <linux/platform_device.h>
  22#include <linux/regulator/consumer.h>
  23#include <linux/thermal.h>
  24
  25#include <dt-bindings/thermal/thermal_exynos.h>
  26
  27/* Exynos generic registers */
  28#define EXYNOS_TMU_REG_TRIMINFO		0x0
  29#define EXYNOS_TMU_REG_CONTROL		0x20
  30#define EXYNOS_TMU_REG_STATUS		0x28
  31#define EXYNOS_TMU_REG_CURRENT_TEMP	0x40
  32#define EXYNOS_TMU_REG_INTEN		0x70
  33#define EXYNOS_TMU_REG_INTSTAT		0x74
  34#define EXYNOS_TMU_REG_INTCLEAR		0x78
  35
  36#define EXYNOS_TMU_TEMP_MASK		0xff
  37#define EXYNOS_TMU_REF_VOLTAGE_SHIFT	24
  38#define EXYNOS_TMU_REF_VOLTAGE_MASK	0x1f
  39#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK	0xf
  40#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT	8
  41#define EXYNOS_TMU_CORE_EN_SHIFT	0
  42
  43/* Exynos3250 specific registers */
  44#define EXYNOS_TMU_TRIMINFO_CON1	0x10
  45
  46/* Exynos4210 specific registers */
  47#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP	0x44
  48#define EXYNOS4210_TMU_REG_TRIG_LEVEL0	0x50
  49
  50/* Exynos5250, Exynos4412, Exynos3250 specific registers */
  51#define EXYNOS_TMU_TRIMINFO_CON2	0x14
  52#define EXYNOS_THD_TEMP_RISE		0x50
  53#define EXYNOS_THD_TEMP_FALL		0x54
  54#define EXYNOS_EMUL_CON		0x80
  55
  56#define EXYNOS_TRIMINFO_RELOAD_ENABLE	1
  57#define EXYNOS_TRIMINFO_25_SHIFT	0
  58#define EXYNOS_TRIMINFO_85_SHIFT	8
  59#define EXYNOS_TMU_TRIP_MODE_SHIFT	13
  60#define EXYNOS_TMU_TRIP_MODE_MASK	0x7
  61#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT	12
  62
  63#define EXYNOS_TMU_INTEN_RISE0_SHIFT	0
  64#define EXYNOS_TMU_INTEN_FALL0_SHIFT	16
  65
  66#define EXYNOS_EMUL_TIME	0x57F0
  67#define EXYNOS_EMUL_TIME_MASK	0xffff
  68#define EXYNOS_EMUL_TIME_SHIFT	16
  69#define EXYNOS_EMUL_DATA_SHIFT	8
  70#define EXYNOS_EMUL_DATA_MASK	0xFF
  71#define EXYNOS_EMUL_ENABLE	0x1
  72
  73/* Exynos5260 specific */
  74#define EXYNOS5260_TMU_REG_INTEN		0xC0
  75#define EXYNOS5260_TMU_REG_INTSTAT		0xC4
  76#define EXYNOS5260_TMU_REG_INTCLEAR		0xC8
  77#define EXYNOS5260_EMUL_CON			0x100
  78
  79/* Exynos4412 specific */
  80#define EXYNOS4412_MUX_ADDR_VALUE          6
  81#define EXYNOS4412_MUX_ADDR_SHIFT          20
  82
  83/* Exynos5433 specific registers */
  84#define EXYNOS5433_THD_TEMP_RISE3_0		0x050
  85#define EXYNOS5433_THD_TEMP_RISE7_4		0x054
  86#define EXYNOS5433_THD_TEMP_FALL3_0		0x060
  87#define EXYNOS5433_THD_TEMP_FALL7_4		0x064
  88#define EXYNOS5433_TMU_REG_INTEN		0x0c0
  89#define EXYNOS5433_TMU_REG_INTPEND		0x0c8
  90#define EXYNOS5433_TMU_EMUL_CON			0x110
  91#define EXYNOS5433_TMU_PD_DET_EN		0x130
  92
  93#define EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT	16
  94#define EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT	23
  95#define EXYNOS5433_TRIMINFO_SENSOR_ID_MASK	\
  96			(0xf << EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT)
  97#define EXYNOS5433_TRIMINFO_CALIB_SEL_MASK	BIT(23)
  98
  99#define EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING	0
 100#define EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING	1
 101
 102#define EXYNOS5433_PD_DET_EN			1
 103
 104#define EXYNOS5433_G3D_BASE			0x10070000
 105
 106/* Exynos7 specific registers */
 107#define EXYNOS7_THD_TEMP_RISE7_6		0x50
 108#define EXYNOS7_THD_TEMP_FALL7_6		0x60
 109#define EXYNOS7_TMU_REG_INTEN			0x110
 110#define EXYNOS7_TMU_REG_INTPEND			0x118
 111#define EXYNOS7_TMU_REG_EMUL_CON		0x160
 112
 113#define EXYNOS7_TMU_TEMP_MASK			0x1ff
 114#define EXYNOS7_PD_DET_EN_SHIFT			23
 115#define EXYNOS7_TMU_INTEN_RISE0_SHIFT		0
 116#define EXYNOS7_EMUL_DATA_SHIFT			7
 117#define EXYNOS7_EMUL_DATA_MASK			0x1ff
 118
 119#define EXYNOS_FIRST_POINT_TRIM			25
 120#define EXYNOS_SECOND_POINT_TRIM		85
 121
 122#define EXYNOS_NOISE_CANCEL_MODE		4
 123
 124#define MCELSIUS	1000
 125
 126enum soc_type {
 127	SOC_ARCH_EXYNOS3250 = 1,
 128	SOC_ARCH_EXYNOS4210,
 129	SOC_ARCH_EXYNOS4412,
 130	SOC_ARCH_EXYNOS5250,
 131	SOC_ARCH_EXYNOS5260,
 132	SOC_ARCH_EXYNOS5420,
 133	SOC_ARCH_EXYNOS5420_TRIMINFO,
 134	SOC_ARCH_EXYNOS5433,
 135	SOC_ARCH_EXYNOS7,
 136};
 137
 138/**
 139 * struct exynos_tmu_data : A structure to hold the private data of the TMU
 140 *			    driver
 141 * @base: base address of the single instance of the TMU controller.
 142 * @base_second: base address of the common registers of the TMU controller.
 143 * @irq: irq number of the TMU controller.
 144 * @soc: id of the SOC type.
 145 * @lock: lock to implement synchronization.
 146 * @clk: pointer to the clock structure.
 147 * @clk_sec: pointer to the clock structure for accessing the base_second.
 148 * @sclk: pointer to the clock structure for accessing the tmu special clk.
 149 * @cal_type: calibration type for temperature
 150 * @efuse_value: SoC defined fuse value
 151 * @min_efuse_value: minimum valid trimming data
 152 * @max_efuse_value: maximum valid trimming data
 153 * @temp_error1: fused value of the first point trim.
 154 * @temp_error2: fused value of the second point trim.
 155 * @gain: gain of amplifier in the positive-TC generator block
 156 *	0 < gain <= 15
 157 * @reference_voltage: reference voltage of amplifier
 158 *	in the positive-TC generator block
 159 *	0 < reference_voltage <= 31
 160 * @tzd: pointer to thermal_zone_device structure
 161 * @enabled: current status of TMU device
 162 * @tmu_set_low_temp: SoC specific method to set trip (falling threshold)
 163 * @tmu_set_high_temp: SoC specific method to set trip (rising threshold)
 164 * @tmu_set_crit_temp: SoC specific method to set critical temperature
 165 * @tmu_disable_low: SoC specific method to disable an interrupt (falling threshold)
 166 * @tmu_disable_high: SoC specific method to disable an interrupt (rising threshold)
 167 * @tmu_initialize: SoC specific TMU initialization method
 168 * @tmu_control: SoC specific TMU control method
 169 * @tmu_read: SoC specific TMU temperature read method
 170 * @tmu_set_emulation: SoC specific TMU emulation setting method
 171 * @tmu_clear_irqs: SoC specific TMU interrupts clearing method
 172 */
 173struct exynos_tmu_data {
 174	void __iomem *base;
 175	void __iomem *base_second;
 176	int irq;
 177	enum soc_type soc;
 178	struct mutex lock;
 179	struct clk *clk, *clk_sec, *sclk;
 180	u32 cal_type;
 181	u32 efuse_value;
 182	u32 min_efuse_value;
 183	u32 max_efuse_value;
 184	u16 temp_error1, temp_error2;
 185	u8 gain;
 186	u8 reference_voltage;
 187	struct thermal_zone_device *tzd;
 188	bool enabled;
 189
 190	void (*tmu_set_low_temp)(struct exynos_tmu_data *data, u8 temp);
 191	void (*tmu_set_high_temp)(struct exynos_tmu_data *data, u8 temp);
 192	void (*tmu_set_crit_temp)(struct exynos_tmu_data *data, u8 temp);
 193	void (*tmu_disable_low)(struct exynos_tmu_data *data);
 194	void (*tmu_disable_high)(struct exynos_tmu_data *data);
 195	void (*tmu_initialize)(struct platform_device *pdev);
 196	void (*tmu_control)(struct platform_device *pdev, bool on);
 197	int (*tmu_read)(struct exynos_tmu_data *data);
 198	void (*tmu_set_emulation)(struct exynos_tmu_data *data, int temp);
 199	void (*tmu_clear_irqs)(struct exynos_tmu_data *data);
 200};
 201
 202/*
 203 * TMU treats temperature as a mapped temperature code.
 204 * The temperature is converted differently depending on the calibration type.
 205 */
 206static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
 207{
 208	if (data->cal_type == TYPE_ONE_POINT_TRIMMING)
 209		return temp + data->temp_error1 - EXYNOS_FIRST_POINT_TRIM;
 210
 211	return (temp - EXYNOS_FIRST_POINT_TRIM) *
 212		(data->temp_error2 - data->temp_error1) /
 213		(EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) +
 214		data->temp_error1;
 215}
 216
 217/*
 218 * Calculate a temperature value from a temperature code.
 219 * The unit of the temperature is degree Celsius.
 220 */
 221static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code)
 222{
 223	if (data->cal_type == TYPE_ONE_POINT_TRIMMING)
 224		return temp_code - data->temp_error1 + EXYNOS_FIRST_POINT_TRIM;
 225
 226	return (temp_code - data->temp_error1) *
 227		(EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) /
 228		(data->temp_error2 - data->temp_error1) +
 229		EXYNOS_FIRST_POINT_TRIM;
 230}
 231
 232static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
 233{
 234	u16 tmu_temp_mask =
 235		(data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
 236						: EXYNOS_TMU_TEMP_MASK;
 237
 238	data->temp_error1 = trim_info & tmu_temp_mask;
 239	data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) &
 240				EXYNOS_TMU_TEMP_MASK);
 241
 242	if (!data->temp_error1 ||
 243	    (data->min_efuse_value > data->temp_error1) ||
 244	    (data->temp_error1 > data->max_efuse_value))
 245		data->temp_error1 = data->efuse_value & EXYNOS_TMU_TEMP_MASK;
 246
 247	if (!data->temp_error2)
 248		data->temp_error2 =
 249			(data->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) &
 250			EXYNOS_TMU_TEMP_MASK;
 251}
 252
 253static int exynos_tmu_initialize(struct platform_device *pdev)
 254{
 255	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 256	unsigned int status;
 257	int ret = 0;
 258
 259	mutex_lock(&data->lock);
 260	clk_enable(data->clk);
 261	if (!IS_ERR(data->clk_sec))
 262		clk_enable(data->clk_sec);
 263
 264	status = readb(data->base + EXYNOS_TMU_REG_STATUS);
 265	if (!status) {
 266		ret = -EBUSY;
 267	} else {
 268		data->tmu_initialize(pdev);
 269		data->tmu_clear_irqs(data);
 270	}
 271
 272	if (!IS_ERR(data->clk_sec))
 273		clk_disable(data->clk_sec);
 274	clk_disable(data->clk);
 275	mutex_unlock(&data->lock);
 276
 277	return ret;
 278}
 279
 280static int exynos_thermal_zone_configure(struct platform_device *pdev)
 281{
 282	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 283	struct thermal_zone_device *tzd = data->tzd;
 284	int ret, temp;
 285
 286	ret = thermal_zone_get_crit_temp(tzd, &temp);
 287	if (ret) {
 288		/* FIXME: Remove this special case */
 289		if (data->soc == SOC_ARCH_EXYNOS5433)
 290			return 0;
 291
 292		dev_err(&pdev->dev,
 293			"No CRITICAL trip point defined in device tree!\n");
 294		return ret;
 295	}
 296
 297	mutex_lock(&data->lock);
 298	clk_enable(data->clk);
 299
 300	data->tmu_set_crit_temp(data, temp / MCELSIUS);
 301
 302	clk_disable(data->clk);
 303	mutex_unlock(&data->lock);
 304
 305	return 0;
 306}
 307
 308static u32 get_con_reg(struct exynos_tmu_data *data, u32 con)
 309{
 310	if (data->soc == SOC_ARCH_EXYNOS4412 ||
 311	    data->soc == SOC_ARCH_EXYNOS3250)
 312		con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT);
 313
 314	con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT);
 315	con |= data->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
 316
 317	con &= ~(EXYNOS_TMU_BUF_SLOPE_SEL_MASK << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
 318	con |= (data->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
 319
 320	con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT);
 321	con |= (EXYNOS_NOISE_CANCEL_MODE << EXYNOS_TMU_TRIP_MODE_SHIFT);
 322
 323	return con;
 324}
 325
 326static void exynos_tmu_control(struct platform_device *pdev, bool on)
 327{
 328	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 329
 330	mutex_lock(&data->lock);
 331	clk_enable(data->clk);
 332	data->tmu_control(pdev, on);
 333	data->enabled = on;
 334	clk_disable(data->clk);
 335	mutex_unlock(&data->lock);
 336}
 337
 338static void exynos_tmu_update_bit(struct exynos_tmu_data *data, int reg_off,
 339				  int bit_off, bool enable)
 340{
 341	u32 interrupt_en;
 342
 343	interrupt_en = readl(data->base + reg_off);
 344	if (enable)
 345		interrupt_en |= BIT(bit_off);
 346	else
 347		interrupt_en &= ~BIT(bit_off);
 348	writel(interrupt_en, data->base + reg_off);
 349}
 350
 351static void exynos_tmu_update_temp(struct exynos_tmu_data *data, int reg_off,
 352				   int bit_off, u8 temp)
 353{
 354	u16 tmu_temp_mask;
 355	u32 th;
 356
 357	tmu_temp_mask =
 358		(data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
 359						: EXYNOS_TMU_TEMP_MASK;
 360
 361	th = readl(data->base + reg_off);
 362	th &= ~(tmu_temp_mask << bit_off);
 363	th |= temp_to_code(data, temp) << bit_off;
 364	writel(th, data->base + reg_off);
 365}
 366
 367static void exynos4210_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
 368{
 369	/*
 370	 * Failing thresholds are not supported on Exynos 4210.
 371	 * We use polling instead.
 372	 */
 373}
 374
 375static void exynos4210_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
 376{
 377	temp = temp_to_code(data, temp);
 378	writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + 4);
 379	exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
 380			      EXYNOS_TMU_INTEN_RISE0_SHIFT + 4, true);
 381}
 382
 383static void exynos4210_tmu_disable_low(struct exynos_tmu_data *data)
 384{
 385	/* Again, this is handled by polling. */
 386}
 387
 388static void exynos4210_tmu_disable_high(struct exynos_tmu_data *data)
 389{
 390	exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
 391			      EXYNOS_TMU_INTEN_RISE0_SHIFT + 4, false);
 392}
 393
 394static void exynos4210_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
 395{
 396	/*
 397	 * Hardware critical temperature handling is not supported on Exynos 4210.
 398	 * We still set the critical temperature threshold, but this is only to
 399	 * make sure it is handled as soon as possible. It is just a normal interrupt.
 400	 */
 401
 402	temp = temp_to_code(data, temp);
 403	writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + 12);
 404	exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
 405			      EXYNOS_TMU_INTEN_RISE0_SHIFT + 12, true);
 406}
 407
 408static void exynos4210_tmu_initialize(struct platform_device *pdev)
 409{
 410	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 411
 412	sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO));
 413
 414	writeb(0, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
 415}
 416
 417static void exynos4412_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
 418{
 419	exynos_tmu_update_temp(data, EXYNOS_THD_TEMP_FALL, 0, temp);
 420	exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
 421			      EXYNOS_TMU_INTEN_FALL0_SHIFT, true);
 422}
 423
 424static void exynos4412_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
 425{
 426	exynos_tmu_update_temp(data, EXYNOS_THD_TEMP_RISE, 8, temp);
 427	exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
 428			      EXYNOS_TMU_INTEN_RISE0_SHIFT + 4, true);
 429}
 430
 431static void exynos4412_tmu_disable_low(struct exynos_tmu_data *data)
 432{
 433	exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
 434			      EXYNOS_TMU_INTEN_FALL0_SHIFT, false);
 435}
 436
 437static void exynos4412_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
 438{
 439	exynos_tmu_update_temp(data, EXYNOS_THD_TEMP_RISE, 24, temp);
 440	exynos_tmu_update_bit(data, EXYNOS_TMU_REG_CONTROL,
 441			      EXYNOS_TMU_THERM_TRIP_EN_SHIFT, true);
 442}
 443
 444static void exynos4412_tmu_initialize(struct platform_device *pdev)
 445{
 446	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 447	unsigned int trim_info, ctrl;
 448
 449	if (data->soc == SOC_ARCH_EXYNOS3250 ||
 450	    data->soc == SOC_ARCH_EXYNOS4412 ||
 451	    data->soc == SOC_ARCH_EXYNOS5250) {
 452		if (data->soc == SOC_ARCH_EXYNOS3250) {
 453			ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1);
 454			ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
 455			writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1);
 456		}
 457		ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
 458		ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
 459		writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
 460	}
 461
 462	/* On exynos5420 the triminfo register is in the shared space */
 463	if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
 464		trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO);
 465	else
 466		trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
 467
 468	sanitize_temp_error(data, trim_info);
 469}
 470
 471static void exynos5433_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
 472{
 473	exynos_tmu_update_temp(data, EXYNOS5433_THD_TEMP_FALL3_0, 0, temp);
 474	exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
 475			      EXYNOS_TMU_INTEN_FALL0_SHIFT, true);
 476}
 477
 478static void exynos5433_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
 479{
 480	exynos_tmu_update_temp(data, EXYNOS5433_THD_TEMP_RISE3_0, 8, temp);
 481	exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
 482			      EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, true);
 483}
 484
 485static void exynos5433_tmu_disable_low(struct exynos_tmu_data *data)
 486{
 487	exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
 488			      EXYNOS_TMU_INTEN_FALL0_SHIFT, false);
 489}
 490
 491static void exynos5433_tmu_disable_high(struct exynos_tmu_data *data)
 492{
 493	exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
 494			      EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, false);
 495}
 496
 497static void exynos5433_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
 498{
 499	exynos_tmu_update_temp(data, EXYNOS5433_THD_TEMP_RISE7_4, 24, temp);
 500	exynos_tmu_update_bit(data, EXYNOS_TMU_REG_CONTROL,
 501			      EXYNOS_TMU_THERM_TRIP_EN_SHIFT, true);
 502	exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
 503			      EXYNOS7_TMU_INTEN_RISE0_SHIFT + 7, true);
 504}
 505
 506static void exynos5433_tmu_initialize(struct platform_device *pdev)
 507{
 508	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 509	unsigned int trim_info;
 510	int sensor_id, cal_type;
 511
 512	trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
 513	sanitize_temp_error(data, trim_info);
 514
 515	/* Read the temperature sensor id */
 516	sensor_id = (trim_info & EXYNOS5433_TRIMINFO_SENSOR_ID_MASK)
 517				>> EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT;
 518	dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id);
 519
 520	/* Read the calibration mode */
 521	writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO);
 522	cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK)
 523				>> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT;
 524
 525	switch (cal_type) {
 526	case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING:
 527		data->cal_type = TYPE_TWO_POINT_TRIMMING;
 528		break;
 529	case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING:
 530	default:
 531		data->cal_type = TYPE_ONE_POINT_TRIMMING;
 532		break;
 533	}
 534
 535	dev_info(&pdev->dev, "Calibration type is %d-point calibration\n",
 536			cal_type ?  2 : 1);
 537}
 538
 539static void exynos7_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
 540{
 541	exynos_tmu_update_temp(data, EXYNOS7_THD_TEMP_FALL7_6 + 12, 0, temp);
 542	exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
 543			      EXYNOS_TMU_INTEN_FALL0_SHIFT + 0, true);
 544}
 545
 546static void exynos7_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
 547{
 548	exynos_tmu_update_temp(data, EXYNOS7_THD_TEMP_RISE7_6 + 12, 16, temp);
 549	exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
 550			      EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, true);
 551}
 552
 553static void exynos7_tmu_disable_low(struct exynos_tmu_data *data)
 554{
 555	exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
 556			      EXYNOS_TMU_INTEN_FALL0_SHIFT + 0, false);
 557}
 558
 559static void exynos7_tmu_disable_high(struct exynos_tmu_data *data)
 560{
 561	exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
 562			      EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, false);
 563}
 564
 565static void exynos7_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
 566{
 567	/*
 568	 * Like Exynos 4210, Exynos 7 does not seem to support critical temperature
 569	 * handling in hardware. Again, we still set a separate interrupt for it.
 570	 */
 571	exynos_tmu_update_temp(data, EXYNOS7_THD_TEMP_RISE7_6 + 0, 16, temp);
 572	exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
 573			      EXYNOS7_TMU_INTEN_RISE0_SHIFT + 7, true);
 574}
 575
 576static void exynos7_tmu_initialize(struct platform_device *pdev)
 577{
 578	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 579	unsigned int trim_info;
 580
 581	trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
 582	sanitize_temp_error(data, trim_info);
 583}
 584
 585static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
 586{
 587	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 588	unsigned int con;
 589
 590	con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
 591
 592	if (on)
 593		con |= BIT(EXYNOS_TMU_CORE_EN_SHIFT);
 594	else
 595		con &= ~BIT(EXYNOS_TMU_CORE_EN_SHIFT);
 596
 597	writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
 598}
 599
 600static void exynos5433_tmu_control(struct platform_device *pdev, bool on)
 601{
 602	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 603	unsigned int con, pd_det_en;
 604
 605	con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
 606
 607	if (on)
 608		con |= BIT(EXYNOS_TMU_CORE_EN_SHIFT);
 609	else
 610		con &= ~BIT(EXYNOS_TMU_CORE_EN_SHIFT);
 611
 612	pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0;
 613
 614	writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN);
 615	writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
 616}
 617
 618static void exynos7_tmu_control(struct platform_device *pdev, bool on)
 619{
 620	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 621	unsigned int con;
 622
 623	con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
 624
 625	if (on) {
 626		con |= BIT(EXYNOS_TMU_CORE_EN_SHIFT);
 627		con |= BIT(EXYNOS7_PD_DET_EN_SHIFT);
 628	} else {
 629		con &= ~BIT(EXYNOS_TMU_CORE_EN_SHIFT);
 630		con &= ~BIT(EXYNOS7_PD_DET_EN_SHIFT);
 631	}
 632
 633	writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
 634}
 635
 636static int exynos_get_temp(struct thermal_zone_device *tz, int *temp)
 637{
 638	struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
 639	int value, ret = 0;
 640
 641	if (!data || !data->tmu_read)
 642		return -EINVAL;
 643	else if (!data->enabled)
 644		/*
 645		 * Called too early, probably
 646		 * from thermal_zone_of_sensor_register().
 647		 */
 648		return -EAGAIN;
 649
 650	mutex_lock(&data->lock);
 651	clk_enable(data->clk);
 652
 653	value = data->tmu_read(data);
 654	if (value < 0)
 655		ret = value;
 656	else
 657		*temp = code_to_temp(data, value) * MCELSIUS;
 658
 659	clk_disable(data->clk);
 660	mutex_unlock(&data->lock);
 661
 662	return ret;
 663}
 664
 665#ifdef CONFIG_THERMAL_EMULATION
 666static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val,
 667			    int temp)
 668{
 669	if (temp) {
 670		temp /= MCELSIUS;
 671
 672		val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT);
 673		val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT);
 674		if (data->soc == SOC_ARCH_EXYNOS7) {
 675			val &= ~(EXYNOS7_EMUL_DATA_MASK <<
 676				EXYNOS7_EMUL_DATA_SHIFT);
 677			val |= (temp_to_code(data, temp) <<
 678				EXYNOS7_EMUL_DATA_SHIFT) |
 679				EXYNOS_EMUL_ENABLE;
 680		} else {
 681			val &= ~(EXYNOS_EMUL_DATA_MASK <<
 682				EXYNOS_EMUL_DATA_SHIFT);
 683			val |= (temp_to_code(data, temp) <<
 684				EXYNOS_EMUL_DATA_SHIFT) |
 685				EXYNOS_EMUL_ENABLE;
 686		}
 687	} else {
 688		val &= ~EXYNOS_EMUL_ENABLE;
 689	}
 690
 691	return val;
 692}
 693
 694static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
 695					 int temp)
 696{
 697	unsigned int val;
 698	u32 emul_con;
 699
 700	if (data->soc == SOC_ARCH_EXYNOS5260)
 701		emul_con = EXYNOS5260_EMUL_CON;
 702	else if (data->soc == SOC_ARCH_EXYNOS5433)
 703		emul_con = EXYNOS5433_TMU_EMUL_CON;
 704	else if (data->soc == SOC_ARCH_EXYNOS7)
 705		emul_con = EXYNOS7_TMU_REG_EMUL_CON;
 706	else
 707		emul_con = EXYNOS_EMUL_CON;
 708
 709	val = readl(data->base + emul_con);
 710	val = get_emul_con_reg(data, val, temp);
 711	writel(val, data->base + emul_con);
 712}
 713
 714static int exynos_tmu_set_emulation(struct thermal_zone_device *tz, int temp)
 715{
 716	struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
 717	int ret = -EINVAL;
 718
 719	if (data->soc == SOC_ARCH_EXYNOS4210)
 720		goto out;
 721
 722	if (temp && temp < MCELSIUS)
 723		goto out;
 724
 725	mutex_lock(&data->lock);
 726	clk_enable(data->clk);
 727	data->tmu_set_emulation(data, temp);
 728	clk_disable(data->clk);
 729	mutex_unlock(&data->lock);
 730	return 0;
 731out:
 732	return ret;
 733}
 734#else
 735#define exynos4412_tmu_set_emulation NULL
 736static int exynos_tmu_set_emulation(struct thermal_zone_device *tz, int temp)
 737	{ return -EINVAL; }
 738#endif /* CONFIG_THERMAL_EMULATION */
 739
 740static int exynos4210_tmu_read(struct exynos_tmu_data *data)
 741{
 742	int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
 743
 744	/* "temp_code" should range between 75 and 175 */
 745	return (ret < 75 || ret > 175) ? -ENODATA : ret;
 746}
 747
 748static int exynos4412_tmu_read(struct exynos_tmu_data *data)
 749{
 750	return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
 751}
 752
 753static int exynos7_tmu_read(struct exynos_tmu_data *data)
 754{
 755	return readw(data->base + EXYNOS_TMU_REG_CURRENT_TEMP) &
 756		EXYNOS7_TMU_TEMP_MASK;
 757}
 758
 759static irqreturn_t exynos_tmu_threaded_irq(int irq, void *id)
 760{
 761	struct exynos_tmu_data *data = id;
 762
 763	thermal_zone_device_update(data->tzd, THERMAL_EVENT_UNSPECIFIED);
 764
 765	mutex_lock(&data->lock);
 766	clk_enable(data->clk);
 767
 768	/* TODO: take action based on particular interrupt */
 769	data->tmu_clear_irqs(data);
 770
 771	clk_disable(data->clk);
 772	mutex_unlock(&data->lock);
 773
 774	return IRQ_HANDLED;
 775}
 776
 777static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
 778{
 779	unsigned int val_irq;
 780	u32 tmu_intstat, tmu_intclear;
 781
 782	if (data->soc == SOC_ARCH_EXYNOS5260) {
 783		tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
 784		tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
 785	} else if (data->soc == SOC_ARCH_EXYNOS7) {
 786		tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
 787		tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
 788	} else if (data->soc == SOC_ARCH_EXYNOS5433) {
 789		tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
 790		tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
 791	} else {
 792		tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
 793		tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
 794	}
 795
 796	val_irq = readl(data->base + tmu_intstat);
 797	/*
 798	 * Clear the interrupts.  Please note that the documentation for
 799	 * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
 800	 * states that INTCLEAR register has a different placing of bits
 801	 * responsible for FALL IRQs than INTSTAT register.  Exynos5420
 802	 * and Exynos5440 documentation is correct (Exynos4210 doesn't
 803	 * support FALL IRQs at all).
 804	 */
 805	writel(val_irq, data->base + tmu_intclear);
 806}
 807
 808static const struct of_device_id exynos_tmu_match[] = {
 809	{
 810		.compatible = "samsung,exynos3250-tmu",
 811		.data = (const void *)SOC_ARCH_EXYNOS3250,
 812	}, {
 813		.compatible = "samsung,exynos4210-tmu",
 814		.data = (const void *)SOC_ARCH_EXYNOS4210,
 815	}, {
 816		.compatible = "samsung,exynos4412-tmu",
 817		.data = (const void *)SOC_ARCH_EXYNOS4412,
 818	}, {
 819		.compatible = "samsung,exynos5250-tmu",
 820		.data = (const void *)SOC_ARCH_EXYNOS5250,
 821	}, {
 822		.compatible = "samsung,exynos5260-tmu",
 823		.data = (const void *)SOC_ARCH_EXYNOS5260,
 824	}, {
 825		.compatible = "samsung,exynos5420-tmu",
 826		.data = (const void *)SOC_ARCH_EXYNOS5420,
 827	}, {
 828		.compatible = "samsung,exynos5420-tmu-ext-triminfo",
 829		.data = (const void *)SOC_ARCH_EXYNOS5420_TRIMINFO,
 830	}, {
 831		.compatible = "samsung,exynos5433-tmu",
 832		.data = (const void *)SOC_ARCH_EXYNOS5433,
 833	}, {
 834		.compatible = "samsung,exynos7-tmu",
 835		.data = (const void *)SOC_ARCH_EXYNOS7,
 836	},
 837	{ },
 838};
 839MODULE_DEVICE_TABLE(of, exynos_tmu_match);
 840
 841static int exynos_map_dt_data(struct platform_device *pdev)
 842{
 843	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 844	struct resource res;
 845
 846	if (!data || !pdev->dev.of_node)
 847		return -ENODEV;
 848
 849	data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
 850	if (data->irq <= 0) {
 851		dev_err(&pdev->dev, "failed to get IRQ\n");
 852		return -ENODEV;
 853	}
 854
 855	if (of_address_to_resource(pdev->dev.of_node, 0, &res)) {
 856		dev_err(&pdev->dev, "failed to get Resource 0\n");
 857		return -ENODEV;
 858	}
 859
 860	data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
 861	if (!data->base) {
 862		dev_err(&pdev->dev, "Failed to ioremap memory\n");
 863		return -EADDRNOTAVAIL;
 864	}
 865
 866	data->soc = (uintptr_t)of_device_get_match_data(&pdev->dev);
 867
 868	switch (data->soc) {
 869	case SOC_ARCH_EXYNOS4210:
 870		data->tmu_set_low_temp = exynos4210_tmu_set_low_temp;
 871		data->tmu_set_high_temp = exynos4210_tmu_set_high_temp;
 872		data->tmu_disable_low = exynos4210_tmu_disable_low;
 873		data->tmu_disable_high = exynos4210_tmu_disable_high;
 874		data->tmu_set_crit_temp = exynos4210_tmu_set_crit_temp;
 875		data->tmu_initialize = exynos4210_tmu_initialize;
 876		data->tmu_control = exynos4210_tmu_control;
 877		data->tmu_read = exynos4210_tmu_read;
 878		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
 879		data->gain = 15;
 880		data->reference_voltage = 7;
 881		data->efuse_value = 55;
 882		data->min_efuse_value = 40;
 883		data->max_efuse_value = 100;
 884		break;
 885	case SOC_ARCH_EXYNOS3250:
 886	case SOC_ARCH_EXYNOS4412:
 887	case SOC_ARCH_EXYNOS5250:
 888	case SOC_ARCH_EXYNOS5260:
 889	case SOC_ARCH_EXYNOS5420:
 890	case SOC_ARCH_EXYNOS5420_TRIMINFO:
 891		data->tmu_set_low_temp = exynos4412_tmu_set_low_temp;
 892		data->tmu_set_high_temp = exynos4412_tmu_set_high_temp;
 893		data->tmu_disable_low = exynos4412_tmu_disable_low;
 894		data->tmu_disable_high = exynos4210_tmu_disable_high;
 895		data->tmu_set_crit_temp = exynos4412_tmu_set_crit_temp;
 896		data->tmu_initialize = exynos4412_tmu_initialize;
 897		data->tmu_control = exynos4210_tmu_control;
 898		data->tmu_read = exynos4412_tmu_read;
 899		data->tmu_set_emulation = exynos4412_tmu_set_emulation;
 900		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
 901		data->gain = 8;
 902		data->reference_voltage = 16;
 903		data->efuse_value = 55;
 904		if (data->soc != SOC_ARCH_EXYNOS5420 &&
 905		    data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
 906			data->min_efuse_value = 40;
 907		else
 908			data->min_efuse_value = 0;
 909		data->max_efuse_value = 100;
 910		break;
 911	case SOC_ARCH_EXYNOS5433:
 912		data->tmu_set_low_temp = exynos5433_tmu_set_low_temp;
 913		data->tmu_set_high_temp = exynos5433_tmu_set_high_temp;
 914		data->tmu_disable_low = exynos5433_tmu_disable_low;
 915		data->tmu_disable_high = exynos5433_tmu_disable_high;
 916		data->tmu_set_crit_temp = exynos5433_tmu_set_crit_temp;
 917		data->tmu_initialize = exynos5433_tmu_initialize;
 918		data->tmu_control = exynos5433_tmu_control;
 919		data->tmu_read = exynos4412_tmu_read;
 920		data->tmu_set_emulation = exynos4412_tmu_set_emulation;
 921		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
 922		data->gain = 8;
 923		if (res.start == EXYNOS5433_G3D_BASE)
 924			data->reference_voltage = 23;
 925		else
 926			data->reference_voltage = 16;
 927		data->efuse_value = 75;
 928		data->min_efuse_value = 40;
 929		data->max_efuse_value = 150;
 930		break;
 931	case SOC_ARCH_EXYNOS7:
 932		data->tmu_set_low_temp = exynos7_tmu_set_low_temp;
 933		data->tmu_set_high_temp = exynos7_tmu_set_high_temp;
 934		data->tmu_disable_low = exynos7_tmu_disable_low;
 935		data->tmu_disable_high = exynos7_tmu_disable_high;
 936		data->tmu_set_crit_temp = exynos7_tmu_set_crit_temp;
 937		data->tmu_initialize = exynos7_tmu_initialize;
 938		data->tmu_control = exynos7_tmu_control;
 939		data->tmu_read = exynos7_tmu_read;
 940		data->tmu_set_emulation = exynos4412_tmu_set_emulation;
 941		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
 942		data->gain = 9;
 943		data->reference_voltage = 17;
 944		data->efuse_value = 75;
 945		data->min_efuse_value = 15;
 946		data->max_efuse_value = 100;
 947		break;
 948	default:
 949		dev_err(&pdev->dev, "Platform not supported\n");
 950		return -EINVAL;
 951	}
 952
 953	data->cal_type = TYPE_ONE_POINT_TRIMMING;
 954
 955	/*
 956	 * Check if the TMU shares some registers and then try to map the
 957	 * memory of common registers.
 958	 */
 959	if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
 960		return 0;
 961
 962	if (of_address_to_resource(pdev->dev.of_node, 1, &res)) {
 963		dev_err(&pdev->dev, "failed to get Resource 1\n");
 964		return -ENODEV;
 965	}
 966
 967	data->base_second = devm_ioremap(&pdev->dev, res.start,
 968					resource_size(&res));
 969	if (!data->base_second) {
 970		dev_err(&pdev->dev, "Failed to ioremap memory\n");
 971		return -ENOMEM;
 972	}
 973
 974	return 0;
 975}
 976
 977static int exynos_set_trips(struct thermal_zone_device *tz, int low, int high)
 978{
 979	struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
 980
 981	mutex_lock(&data->lock);
 982	clk_enable(data->clk);
 983
 984	if (low > INT_MIN)
 985		data->tmu_set_low_temp(data, low / MCELSIUS);
 986	else
 987		data->tmu_disable_low(data);
 988	if (high < INT_MAX)
 989		data->tmu_set_high_temp(data, high / MCELSIUS);
 990	else
 991		data->tmu_disable_high(data);
 992
 993	clk_disable(data->clk);
 994	mutex_unlock(&data->lock);
 995
 996	return 0;
 997}
 998
 999static const struct thermal_zone_device_ops exynos_sensor_ops = {
1000	.get_temp = exynos_get_temp,
1001	.set_emul_temp = exynos_tmu_set_emulation,
1002	.set_trips = exynos_set_trips,
1003};
1004
1005static int exynos_tmu_probe(struct platform_device *pdev)
1006{
1007	struct device *dev = &pdev->dev;
1008	struct exynos_tmu_data *data;
1009	int ret;
1010
1011	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
1012	if (!data)
1013		return -ENOMEM;
1014
1015	platform_set_drvdata(pdev, data);
1016	mutex_init(&data->lock);
1017
1018	/*
1019	 * Try enabling the regulator if found
1020	 * TODO: Add regulator as an SOC feature, so that regulator enable
1021	 * is a compulsory call.
1022	 */
1023	ret = devm_regulator_get_enable_optional(dev, "vtmu");
1024	switch (ret) {
1025	case 0:
1026	case -ENODEV:
1027		break;
1028	case -EPROBE_DEFER:
1029		return -EPROBE_DEFER;
1030	default:
1031		dev_err(dev, "Failed to get enabled regulator: %d\n", ret);
1032		return ret;
1033	}
1034
1035	ret = exynos_map_dt_data(pdev);
1036	if (ret)
1037		return ret;
1038
1039	data->clk = devm_clk_get(dev, "tmu_apbif");
1040	if (IS_ERR(data->clk))
1041		return dev_err_probe(dev, PTR_ERR(data->clk), "Failed to get clock\n");
1042
1043	data->clk_sec = devm_clk_get(dev, "tmu_triminfo_apbif");
1044	if (IS_ERR(data->clk_sec)) {
1045		if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
1046			return dev_err_probe(dev, PTR_ERR(data->clk_sec),
1047					     "Failed to get triminfo clock\n");
1048	} else {
1049		ret = clk_prepare(data->clk_sec);
1050		if (ret) {
1051			dev_err(dev, "Failed to get clock\n");
1052			return ret;
1053		}
1054	}
1055
1056	ret = clk_prepare(data->clk);
1057	if (ret) {
1058		dev_err(dev, "Failed to get clock\n");
1059		goto err_clk_sec;
1060	}
1061
1062	switch (data->soc) {
1063	case SOC_ARCH_EXYNOS5433:
1064	case SOC_ARCH_EXYNOS7:
1065		data->sclk = devm_clk_get(dev, "tmu_sclk");
1066		if (IS_ERR(data->sclk)) {
1067			ret = dev_err_probe(dev, PTR_ERR(data->sclk), "Failed to get sclk\n");
1068			goto err_clk;
1069		} else {
1070			ret = clk_prepare_enable(data->sclk);
1071			if (ret) {
1072				dev_err(dev, "Failed to enable sclk\n");
1073				goto err_clk;
1074			}
1075		}
1076		break;
1077	default:
1078		break;
1079	}
1080
1081	ret = exynos_tmu_initialize(pdev);
1082	if (ret) {
1083		dev_err(dev, "Failed to initialize TMU\n");
1084		goto err_sclk;
1085	}
1086
1087	data->tzd = devm_thermal_of_zone_register(dev, 0, data,
1088						  &exynos_sensor_ops);
1089	if (IS_ERR(data->tzd)) {
1090		ret = dev_err_probe(dev, PTR_ERR(data->tzd), "Failed to register sensor\n");
1091		goto err_sclk;
1092	}
1093
1094	ret = exynos_thermal_zone_configure(pdev);
1095	if (ret) {
1096		dev_err(dev, "Failed to configure the thermal zone\n");
1097		goto err_sclk;
1098	}
1099
1100	ret = devm_request_threaded_irq(dev, data->irq, NULL,
1101					exynos_tmu_threaded_irq,
1102					IRQF_TRIGGER_RISING
1103						| IRQF_SHARED | IRQF_ONESHOT,
1104					dev_name(dev), data);
1105	if (ret) {
1106		dev_err(dev, "Failed to request irq: %d\n", data->irq);
1107		goto err_sclk;
1108	}
1109
1110	exynos_tmu_control(pdev, true);
1111	return 0;
1112
1113err_sclk:
1114	clk_disable_unprepare(data->sclk);
1115err_clk:
1116	clk_unprepare(data->clk);
1117err_clk_sec:
1118	if (!IS_ERR(data->clk_sec))
1119		clk_unprepare(data->clk_sec);
1120	return ret;
1121}
1122
1123static void exynos_tmu_remove(struct platform_device *pdev)
1124{
1125	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
1126
1127	exynos_tmu_control(pdev, false);
1128
1129	clk_disable_unprepare(data->sclk);
1130	clk_unprepare(data->clk);
1131	if (!IS_ERR(data->clk_sec))
1132		clk_unprepare(data->clk_sec);
1133}
1134
1135#ifdef CONFIG_PM_SLEEP
1136static int exynos_tmu_suspend(struct device *dev)
1137{
1138	exynos_tmu_control(to_platform_device(dev), false);
1139
1140	return 0;
1141}
1142
1143static int exynos_tmu_resume(struct device *dev)
1144{
1145	struct platform_device *pdev = to_platform_device(dev);
1146
1147	exynos_tmu_initialize(pdev);
1148	exynos_tmu_control(pdev, true);
1149
1150	return 0;
1151}
1152
1153static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
1154			 exynos_tmu_suspend, exynos_tmu_resume);
1155#define EXYNOS_TMU_PM	(&exynos_tmu_pm)
1156#else
1157#define EXYNOS_TMU_PM	NULL
1158#endif
1159
1160static struct platform_driver exynos_tmu_driver = {
1161	.driver = {
1162		.name   = "exynos-tmu",
1163		.pm     = EXYNOS_TMU_PM,
1164		.of_match_table = exynos_tmu_match,
1165	},
1166	.probe = exynos_tmu_probe,
1167	.remove = exynos_tmu_remove,
1168};
1169
1170module_platform_driver(exynos_tmu_driver);
1171
1172MODULE_DESCRIPTION("Exynos TMU Driver");
1173MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
1174MODULE_LICENSE("GPL");
1175MODULE_ALIAS("platform:exynos-tmu");
~/ Read-only file preview.