thermal: exynos: Rename exynos_thermal.c to exynos_tmu.c
[firefly-linux-kernel-4.4.55.git] / drivers / thermal / samsung / exynos_tmu.c
1 /*
2  * exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit)
3  *
4  *  Copyright (C) 2011 Samsung Electronics
5  *  Donggeun Kim <dg77.kim@samsung.com>
6  *  Amit Daniel Kachhap <amit.kachhap@linaro.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include <linux/clk.h>
25 #include <linux/io.h>
26 #include <linux/interrupt.h>
27 #include <linux/module.h>
28 #include <linux/of.h>
29 #include <linux/platform_device.h>
30 #include <linux/platform_data/exynos_thermal.h>
31
32 #include "exynos_thermal_common.h"
33
34 /* Exynos generic registers */
35 #define EXYNOS_TMU_REG_TRIMINFO         0x0
36 #define EXYNOS_TMU_REG_CONTROL          0x20
37 #define EXYNOS_TMU_REG_STATUS           0x28
38 #define EXYNOS_TMU_REG_CURRENT_TEMP     0x40
39 #define EXYNOS_TMU_REG_INTEN            0x70
40 #define EXYNOS_TMU_REG_INTSTAT          0x74
41 #define EXYNOS_TMU_REG_INTCLEAR         0x78
42
43 #define EXYNOS_TMU_TRIM_TEMP_MASK       0xff
44 #define EXYNOS_TMU_GAIN_SHIFT           8
45 #define EXYNOS_TMU_REF_VOLTAGE_SHIFT    24
46 #define EXYNOS_TMU_CORE_ON              3
47 #define EXYNOS_TMU_CORE_OFF             2
48 #define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET      50
49
50 /* Exynos4210 specific registers */
51 #define EXYNOS4210_TMU_REG_THRESHOLD_TEMP       0x44
52 #define EXYNOS4210_TMU_REG_TRIG_LEVEL0  0x50
53 #define EXYNOS4210_TMU_REG_TRIG_LEVEL1  0x54
54 #define EXYNOS4210_TMU_REG_TRIG_LEVEL2  0x58
55 #define EXYNOS4210_TMU_REG_TRIG_LEVEL3  0x5C
56 #define EXYNOS4210_TMU_REG_PAST_TEMP0   0x60
57 #define EXYNOS4210_TMU_REG_PAST_TEMP1   0x64
58 #define EXYNOS4210_TMU_REG_PAST_TEMP2   0x68
59 #define EXYNOS4210_TMU_REG_PAST_TEMP3   0x6C
60
61 #define EXYNOS4210_TMU_TRIG_LEVEL0_MASK 0x1
62 #define EXYNOS4210_TMU_TRIG_LEVEL1_MASK 0x10
63 #define EXYNOS4210_TMU_TRIG_LEVEL2_MASK 0x100
64 #define EXYNOS4210_TMU_TRIG_LEVEL3_MASK 0x1000
65 #define EXYNOS4210_TMU_INTCLEAR_VAL     0x1111
66
67 /* Exynos5250 and Exynos4412 specific registers */
68 #define EXYNOS_TMU_TRIMINFO_CON 0x14
69 #define EXYNOS_THD_TEMP_RISE            0x50
70 #define EXYNOS_THD_TEMP_FALL            0x54
71 #define EXYNOS_EMUL_CON         0x80
72
73 #define EXYNOS_TRIMINFO_RELOAD          0x1
74 #define EXYNOS_TMU_CLEAR_RISE_INT       0x111
75 #define EXYNOS_TMU_CLEAR_FALL_INT       (0x111 << 12)
76 #define EXYNOS_MUX_ADDR_VALUE           6
77 #define EXYNOS_MUX_ADDR_SHIFT           20
78 #define EXYNOS_TMU_TRIP_MODE_SHIFT      13
79
80 #define EFUSE_MIN_VALUE 40
81 #define EFUSE_MAX_VALUE 100
82
83 #ifdef CONFIG_THERMAL_EMULATION
84 #define EXYNOS_EMUL_TIME        0x57F0
85 #define EXYNOS_EMUL_TIME_SHIFT  16
86 #define EXYNOS_EMUL_DATA_SHIFT  8
87 #define EXYNOS_EMUL_DATA_MASK   0xFF
88 #define EXYNOS_EMUL_ENABLE      0x1
89 #endif /* CONFIG_THERMAL_EMULATION */
90
91 struct exynos_tmu_data {
92         struct exynos_tmu_platform_data *pdata;
93         struct resource *mem;
94         void __iomem *base;
95         int irq;
96         enum soc_type soc;
97         struct work_struct irq_work;
98         struct mutex lock;
99         struct clk *clk;
100         u8 temp_error1, temp_error2;
101 };
102
103 /*
104  * TMU treats temperature as a mapped temperature code.
105  * The temperature is converted differently depending on the calibration type.
106  */
107 static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
108 {
109         struct exynos_tmu_platform_data *pdata = data->pdata;
110         int temp_code;
111
112         if (data->soc == SOC_ARCH_EXYNOS4210)
113                 /* temp should range between 25 and 125 */
114                 if (temp < 25 || temp > 125) {
115                         temp_code = -EINVAL;
116                         goto out;
117                 }
118
119         switch (pdata->cal_type) {
120         case TYPE_TWO_POINT_TRIMMING:
121                 temp_code = (temp - 25) *
122                     (data->temp_error2 - data->temp_error1) /
123                     (85 - 25) + data->temp_error1;
124                 break;
125         case TYPE_ONE_POINT_TRIMMING:
126                 temp_code = temp + data->temp_error1 - 25;
127                 break;
128         default:
129                 temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
130                 break;
131         }
132 out:
133         return temp_code;
134 }
135
136 /*
137  * Calculate a temperature value from a temperature code.
138  * The unit of the temperature is degree Celsius.
139  */
140 static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
141 {
142         struct exynos_tmu_platform_data *pdata = data->pdata;
143         int temp;
144
145         if (data->soc == SOC_ARCH_EXYNOS4210)
146                 /* temp_code should range between 75 and 175 */
147                 if (temp_code < 75 || temp_code > 175) {
148                         temp = -ENODATA;
149                         goto out;
150                 }
151
152         switch (pdata->cal_type) {
153         case TYPE_TWO_POINT_TRIMMING:
154                 temp = (temp_code - data->temp_error1) * (85 - 25) /
155                     (data->temp_error2 - data->temp_error1) + 25;
156                 break;
157         case TYPE_ONE_POINT_TRIMMING:
158                 temp = temp_code - data->temp_error1 + 25;
159                 break;
160         default:
161                 temp = temp_code - EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
162                 break;
163         }
164 out:
165         return temp;
166 }
167
168 static int exynos_tmu_initialize(struct platform_device *pdev)
169 {
170         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
171         struct exynos_tmu_platform_data *pdata = data->pdata;
172         unsigned int status, trim_info;
173         unsigned int rising_threshold = 0, falling_threshold = 0;
174         int ret = 0, threshold_code, i, trigger_levs = 0;
175
176         mutex_lock(&data->lock);
177         clk_enable(data->clk);
178
179         status = readb(data->base + EXYNOS_TMU_REG_STATUS);
180         if (!status) {
181                 ret = -EBUSY;
182                 goto out;
183         }
184
185         if (data->soc == SOC_ARCH_EXYNOS) {
186                 __raw_writel(EXYNOS_TRIMINFO_RELOAD,
187                                 data->base + EXYNOS_TMU_TRIMINFO_CON);
188         }
189         /* Save trimming info in order to perform calibration */
190         trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
191         data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
192         data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
193
194         if ((EFUSE_MIN_VALUE > data->temp_error1) ||
195                         (data->temp_error1 > EFUSE_MAX_VALUE) ||
196                         (data->temp_error2 != 0))
197                 data->temp_error1 = pdata->efuse_value;
198
199         /* Count trigger levels to be enabled */
200         for (i = 0; i < MAX_THRESHOLD_LEVS; i++)
201                 if (pdata->trigger_levels[i])
202                         trigger_levs++;
203
204         if (data->soc == SOC_ARCH_EXYNOS4210) {
205                 /* Write temperature code for threshold */
206                 threshold_code = temp_to_code(data, pdata->threshold);
207                 if (threshold_code < 0) {
208                         ret = threshold_code;
209                         goto out;
210                 }
211                 writeb(threshold_code,
212                         data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
213                 for (i = 0; i < trigger_levs; i++)
214                         writeb(pdata->trigger_levels[i],
215                         data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
216
217                 writel(EXYNOS4210_TMU_INTCLEAR_VAL,
218                         data->base + EXYNOS_TMU_REG_INTCLEAR);
219         } else if (data->soc == SOC_ARCH_EXYNOS) {
220                 /* Write temperature code for rising and falling threshold */
221                 for (i = 0; i < trigger_levs; i++) {
222                         threshold_code = temp_to_code(data,
223                                                 pdata->trigger_levels[i]);
224                         if (threshold_code < 0) {
225                                 ret = threshold_code;
226                                 goto out;
227                         }
228                         rising_threshold |= threshold_code << 8 * i;
229                         if (pdata->threshold_falling) {
230                                 threshold_code = temp_to_code(data,
231                                                 pdata->trigger_levels[i] -
232                                                 pdata->threshold_falling);
233                                 if (threshold_code > 0)
234                                         falling_threshold |=
235                                                 threshold_code << 8 * i;
236                         }
237                 }
238
239                 writel(rising_threshold,
240                                 data->base + EXYNOS_THD_TEMP_RISE);
241                 writel(falling_threshold,
242                                 data->base + EXYNOS_THD_TEMP_FALL);
243
244                 writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT,
245                                 data->base + EXYNOS_TMU_REG_INTCLEAR);
246         }
247 out:
248         clk_disable(data->clk);
249         mutex_unlock(&data->lock);
250
251         return ret;
252 }
253
254 static void exynos_tmu_control(struct platform_device *pdev, bool on)
255 {
256         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
257         struct exynos_tmu_platform_data *pdata = data->pdata;
258         unsigned int con, interrupt_en;
259
260         mutex_lock(&data->lock);
261         clk_enable(data->clk);
262
263         con = pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT |
264                 pdata->gain << EXYNOS_TMU_GAIN_SHIFT;
265
266         if (data->soc == SOC_ARCH_EXYNOS) {
267                 con |= pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT;
268                 con |= (EXYNOS_MUX_ADDR_VALUE << EXYNOS_MUX_ADDR_SHIFT);
269         }
270
271         if (on) {
272                 con |= EXYNOS_TMU_CORE_ON;
273                 interrupt_en = pdata->trigger_level3_en << 12 |
274                         pdata->trigger_level2_en << 8 |
275                         pdata->trigger_level1_en << 4 |
276                         pdata->trigger_level0_en;
277                 if (pdata->threshold_falling)
278                         interrupt_en |= interrupt_en << 16;
279         } else {
280                 con |= EXYNOS_TMU_CORE_OFF;
281                 interrupt_en = 0; /* Disable all interrupts */
282         }
283         writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
284         writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
285
286         clk_disable(data->clk);
287         mutex_unlock(&data->lock);
288 }
289
290 static int exynos_tmu_read(struct exynos_tmu_data *data)
291 {
292         u8 temp_code;
293         int temp;
294
295         mutex_lock(&data->lock);
296         clk_enable(data->clk);
297
298         temp_code = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
299         temp = code_to_temp(data, temp_code);
300
301         clk_disable(data->clk);
302         mutex_unlock(&data->lock);
303
304         return temp;
305 }
306
307 #ifdef CONFIG_THERMAL_EMULATION
308 static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
309 {
310         struct exynos_tmu_data *data = drv_data;
311         unsigned int reg;
312         int ret = -EINVAL;
313
314         if (data->soc == SOC_ARCH_EXYNOS4210)
315                 goto out;
316
317         if (temp && temp < MCELSIUS)
318                 goto out;
319
320         mutex_lock(&data->lock);
321         clk_enable(data->clk);
322
323         reg = readl(data->base + EXYNOS_EMUL_CON);
324
325         if (temp) {
326                 temp /= MCELSIUS;
327
328                 reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
329                         (temp_to_code(data, temp)
330                          << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE;
331         } else {
332                 reg &= ~EXYNOS_EMUL_ENABLE;
333         }
334
335         writel(reg, data->base + EXYNOS_EMUL_CON);
336
337         clk_disable(data->clk);
338         mutex_unlock(&data->lock);
339         return 0;
340 out:
341         return ret;
342 }
343 #else
344 static int exynos_tmu_set_emulation(void *drv_data,     unsigned long temp)
345         { return -EINVAL; }
346 #endif/*CONFIG_THERMAL_EMULATION*/
347
348 static void exynos_tmu_work(struct work_struct *work)
349 {
350         struct exynos_tmu_data *data = container_of(work,
351                         struct exynos_tmu_data, irq_work);
352
353         exynos_report_trigger();
354         mutex_lock(&data->lock);
355         clk_enable(data->clk);
356         if (data->soc == SOC_ARCH_EXYNOS)
357                 writel(EXYNOS_TMU_CLEAR_RISE_INT |
358                                 EXYNOS_TMU_CLEAR_FALL_INT,
359                                 data->base + EXYNOS_TMU_REG_INTCLEAR);
360         else
361                 writel(EXYNOS4210_TMU_INTCLEAR_VAL,
362                                 data->base + EXYNOS_TMU_REG_INTCLEAR);
363         clk_disable(data->clk);
364         mutex_unlock(&data->lock);
365
366         enable_irq(data->irq);
367 }
368
369 static irqreturn_t exynos_tmu_irq(int irq, void *id)
370 {
371         struct exynos_tmu_data *data = id;
372
373         disable_irq_nosync(irq);
374         schedule_work(&data->irq_work);
375
376         return IRQ_HANDLED;
377 }
378 static struct thermal_sensor_conf exynos_sensor_conf = {
379         .name                   = "exynos-therm",
380         .read_temperature       = (int (*)(void *))exynos_tmu_read,
381         .write_emul_temp        = exynos_tmu_set_emulation,
382 };
383
384 #if defined(CONFIG_CPU_EXYNOS4210)
385 static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
386         .threshold = 80,
387         .trigger_levels[0] = 5,
388         .trigger_levels[1] = 20,
389         .trigger_levels[2] = 30,
390         .trigger_level0_en = 1,
391         .trigger_level1_en = 1,
392         .trigger_level2_en = 1,
393         .trigger_level3_en = 0,
394         .gain = 15,
395         .reference_voltage = 7,
396         .cal_type = TYPE_ONE_POINT_TRIMMING,
397         .freq_tab[0] = {
398                 .freq_clip_max = 800 * 1000,
399                 .temp_level = 85,
400         },
401         .freq_tab[1] = {
402                 .freq_clip_max = 200 * 1000,
403                 .temp_level = 100,
404         },
405         .freq_tab_count = 2,
406         .type = SOC_ARCH_EXYNOS4210,
407 };
408 #define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
409 #else
410 #define EXYNOS4210_TMU_DRV_DATA (NULL)
411 #endif
412
413 #if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412) || \
414         defined(CONFIG_SOC_EXYNOS4212)
415 static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
416         .threshold_falling = 10,
417         .trigger_levels[0] = 85,
418         .trigger_levels[1] = 103,
419         .trigger_levels[2] = 110,
420         .trigger_level0_en = 1,
421         .trigger_level1_en = 1,
422         .trigger_level2_en = 1,
423         .trigger_level3_en = 0,
424         .gain = 8,
425         .reference_voltage = 16,
426         .noise_cancel_mode = 4,
427         .cal_type = TYPE_ONE_POINT_TRIMMING,
428         .efuse_value = 55,
429         .freq_tab[0] = {
430                 .freq_clip_max = 800 * 1000,
431                 .temp_level = 85,
432         },
433         .freq_tab[1] = {
434                 .freq_clip_max = 200 * 1000,
435                 .temp_level = 103,
436         },
437         .freq_tab_count = 2,
438         .type = SOC_ARCH_EXYNOS,
439 };
440 #define EXYNOS_TMU_DRV_DATA (&exynos_default_tmu_data)
441 #else
442 #define EXYNOS_TMU_DRV_DATA (NULL)
443 #endif
444
445 #ifdef CONFIG_OF
446 static const struct of_device_id exynos_tmu_match[] = {
447         {
448                 .compatible = "samsung,exynos4210-tmu",
449                 .data = (void *)EXYNOS4210_TMU_DRV_DATA,
450         },
451         {
452                 .compatible = "samsung,exynos4412-tmu",
453                 .data = (void *)EXYNOS_TMU_DRV_DATA,
454         },
455         {
456                 .compatible = "samsung,exynos5250-tmu",
457                 .data = (void *)EXYNOS_TMU_DRV_DATA,
458         },
459         {},
460 };
461 MODULE_DEVICE_TABLE(of, exynos_tmu_match);
462 #endif
463
464 static struct platform_device_id exynos_tmu_driver_ids[] = {
465         {
466                 .name           = "exynos4210-tmu",
467                 .driver_data    = (kernel_ulong_t)EXYNOS4210_TMU_DRV_DATA,
468         },
469         {
470                 .name           = "exynos5250-tmu",
471                 .driver_data    = (kernel_ulong_t)EXYNOS_TMU_DRV_DATA,
472         },
473         { },
474 };
475 MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids);
476
477 static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
478                         struct platform_device *pdev)
479 {
480 #ifdef CONFIG_OF
481         if (pdev->dev.of_node) {
482                 const struct of_device_id *match;
483                 match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
484                 if (!match)
485                         return NULL;
486                 return (struct exynos_tmu_platform_data *) match->data;
487         }
488 #endif
489         return (struct exynos_tmu_platform_data *)
490                         platform_get_device_id(pdev)->driver_data;
491 }
492
493 static int exynos_tmu_probe(struct platform_device *pdev)
494 {
495         struct exynos_tmu_data *data;
496         struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
497         int ret, i;
498
499         if (!pdata)
500                 pdata = exynos_get_driver_data(pdev);
501
502         if (!pdata) {
503                 dev_err(&pdev->dev, "No platform init data supplied.\n");
504                 return -ENODEV;
505         }
506         data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
507                                         GFP_KERNEL);
508         if (!data) {
509                 dev_err(&pdev->dev, "Failed to allocate driver structure\n");
510                 return -ENOMEM;
511         }
512
513         data->irq = platform_get_irq(pdev, 0);
514         if (data->irq < 0) {
515                 dev_err(&pdev->dev, "Failed to get platform irq\n");
516                 return data->irq;
517         }
518
519         INIT_WORK(&data->irq_work, exynos_tmu_work);
520
521         data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
522         data->base = devm_ioremap_resource(&pdev->dev, data->mem);
523         if (IS_ERR(data->base))
524                 return PTR_ERR(data->base);
525
526         ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
527                 IRQF_TRIGGER_RISING, "exynos-tmu", data);
528         if (ret) {
529                 dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
530                 return ret;
531         }
532
533         data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
534         if (IS_ERR(data->clk)) {
535                 dev_err(&pdev->dev, "Failed to get clock\n");
536                 return  PTR_ERR(data->clk);
537         }
538
539         ret = clk_prepare(data->clk);
540         if (ret)
541                 return ret;
542
543         if (pdata->type == SOC_ARCH_EXYNOS ||
544                                 pdata->type == SOC_ARCH_EXYNOS4210)
545                 data->soc = pdata->type;
546         else {
547                 ret = -EINVAL;
548                 dev_err(&pdev->dev, "Platform not supported\n");
549                 goto err_clk;
550         }
551
552         data->pdata = pdata;
553         platform_set_drvdata(pdev, data);
554         mutex_init(&data->lock);
555
556         ret = exynos_tmu_initialize(pdev);
557         if (ret) {
558                 dev_err(&pdev->dev, "Failed to initialize TMU\n");
559                 goto err_clk;
560         }
561
562         exynos_tmu_control(pdev, true);
563
564         /* Register the sensor with thermal management interface */
565         (&exynos_sensor_conf)->private_data = data;
566         exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
567                         pdata->trigger_level1_en + pdata->trigger_level2_en +
568                         pdata->trigger_level3_en;
569
570         for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
571                 exynos_sensor_conf.trip_data.trip_val[i] =
572                         pdata->threshold + pdata->trigger_levels[i];
573
574         exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;
575
576         exynos_sensor_conf.cooling_data.freq_clip_count =
577                                                 pdata->freq_tab_count;
578         for (i = 0; i < pdata->freq_tab_count; i++) {
579                 exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
580                                         pdata->freq_tab[i].freq_clip_max;
581                 exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
582                                         pdata->freq_tab[i].temp_level;
583         }
584
585         ret = exynos_register_thermal(&exynos_sensor_conf);
586         if (ret) {
587                 dev_err(&pdev->dev, "Failed to register thermal interface\n");
588                 goto err_clk;
589         }
590
591         return 0;
592 err_clk:
593         clk_unprepare(data->clk);
594         return ret;
595 }
596
597 static int exynos_tmu_remove(struct platform_device *pdev)
598 {
599         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
600
601         exynos_tmu_control(pdev, false);
602
603         exynos_unregister_thermal();
604
605         clk_unprepare(data->clk);
606
607         return 0;
608 }
609
610 #ifdef CONFIG_PM_SLEEP
611 static int exynos_tmu_suspend(struct device *dev)
612 {
613         exynos_tmu_control(to_platform_device(dev), false);
614
615         return 0;
616 }
617
618 static int exynos_tmu_resume(struct device *dev)
619 {
620         struct platform_device *pdev = to_platform_device(dev);
621
622         exynos_tmu_initialize(pdev);
623         exynos_tmu_control(pdev, true);
624
625         return 0;
626 }
627
628 static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
629                          exynos_tmu_suspend, exynos_tmu_resume);
630 #define EXYNOS_TMU_PM   (&exynos_tmu_pm)
631 #else
632 #define EXYNOS_TMU_PM   NULL
633 #endif
634
635 static struct platform_driver exynos_tmu_driver = {
636         .driver = {
637                 .name   = "exynos-tmu",
638                 .owner  = THIS_MODULE,
639                 .pm     = EXYNOS_TMU_PM,
640                 .of_match_table = of_match_ptr(exynos_tmu_match),
641         },
642         .probe = exynos_tmu_probe,
643         .remove = exynos_tmu_remove,
644         .id_table = exynos_tmu_driver_ids,
645 };
646
647 module_platform_driver(exynos_tmu_driver);
648
649 MODULE_DESCRIPTION("EXYNOS TMU Driver");
650 MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
651 MODULE_LICENSE("GPL");
652 MODULE_ALIAS("platform:exynos-tmu");