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