aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/samsung/exynos_tmu.c64
-rw-r--r--drivers/thermal/samsung/exynos_tmu.h14
-rw-r--r--drivers/thermal/samsung/exynos_tmu_data.c36
3 files changed, 43 insertions, 71 deletions
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 01aa5481c13e..1b3c2f4a846b 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -56,6 +56,7 @@
56 * @tmu_control: SoC specific TMU control method 56 * @tmu_control: SoC specific TMU control method
57 * @tmu_read: SoC specific TMU temperature read method 57 * @tmu_read: SoC specific TMU temperature read method
58 * @tmu_set_emulation: SoC specific TMU emulation setting method 58 * @tmu_set_emulation: SoC specific TMU emulation setting method
59 * @tmu_clear_irqs: SoC specific TMU interrupts clearing method
59 */ 60 */
60struct exynos_tmu_data { 61struct exynos_tmu_data {
61 int id; 62 int id;
@@ -75,6 +76,7 @@ struct exynos_tmu_data {
75 int (*tmu_read)(struct exynos_tmu_data *data); 76 int (*tmu_read)(struct exynos_tmu_data *data);
76 void (*tmu_set_emulation)(struct exynos_tmu_data *data, 77 void (*tmu_set_emulation)(struct exynos_tmu_data *data,
77 unsigned long temp); 78 unsigned long temp);
79 void (*tmu_clear_irqs)(struct exynos_tmu_data *data);
78}; 80};
79 81
80/* 82/*
@@ -131,23 +133,6 @@ static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
131 return temp; 133 return temp;
132} 134}
133 135
134static void exynos_tmu_clear_irqs(struct exynos_tmu_data *data)
135{
136 const struct exynos_tmu_registers *reg = data->pdata->registers;
137 unsigned int val_irq;
138
139 val_irq = readl(data->base + reg->tmu_intstat);
140 /*
141 * Clear the interrupts. Please note that the documentation for
142 * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
143 * states that INTCLEAR register has a different placing of bits
144 * responsible for FALL IRQs than INTSTAT register. Exynos5420
145 * and Exynos5440 documentation is correct (Exynos4210 doesn't
146 * support FALL IRQs at all).
147 */
148 writel(val_irq, data->base + reg->tmu_intclear);
149}
150
151static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) 136static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
152{ 137{
153 struct exynos_tmu_platform_data *pdata = data->pdata; 138 struct exynos_tmu_platform_data *pdata = data->pdata;
@@ -259,7 +244,7 @@ static int exynos4210_tmu_initialize(struct platform_device *pdev)
259 writeb(pdata->trigger_levels[i], data->base + 244 writeb(pdata->trigger_levels[i], data->base +
260 EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4); 245 EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
261 246
262 exynos_tmu_clear_irqs(data); 247 data->tmu_clear_irqs(data);
263out: 248out:
264 return ret; 249 return ret;
265} 250}
@@ -304,7 +289,7 @@ static int exynos4412_tmu_initialize(struct platform_device *pdev)
304 writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); 289 writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE);
305 writel(get_th_reg(data, 0, true), data->base + EXYNOS_THD_TEMP_FALL); 290 writel(get_th_reg(data, 0, true), data->base + EXYNOS_THD_TEMP_FALL);
306 291
307 exynos_tmu_clear_irqs(data); 292 data->tmu_clear_irqs(data);
308 293
309 /* if last threshold limit is also present */ 294 /* if last threshold limit is also present */
310 i = pdata->max_trigger_level - 1; 295 i = pdata->max_trigger_level - 1;
@@ -353,7 +338,7 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev)
353 writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH0); 338 writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH0);
354 writel(0, data->base + EXYNOS5440_TMU_S0_7_TH1); 339 writel(0, data->base + EXYNOS5440_TMU_S0_7_TH1);
355 340
356 exynos_tmu_clear_irqs(data); 341 data->tmu_clear_irqs(data);
357 342
358 /* if last threshold limit is also present */ 343 /* if last threshold limit is also present */
359 i = pdata->max_trigger_level - 1; 344 i = pdata->max_trigger_level - 1;
@@ -557,7 +542,7 @@ static void exynos_tmu_work(struct work_struct *work)
557 clk_enable(data->clk); 542 clk_enable(data->clk);
558 543
559 /* TODO: take action based on particular interrupt */ 544 /* TODO: take action based on particular interrupt */
560 exynos_tmu_clear_irqs(data); 545 data->tmu_clear_irqs(data);
561 546
562 clk_disable(data->clk); 547 clk_disable(data->clk);
563 mutex_unlock(&data->lock); 548 mutex_unlock(&data->lock);
@@ -565,6 +550,40 @@ out:
565 enable_irq(data->irq); 550 enable_irq(data->irq);
566} 551}
567 552
553static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
554{
555 unsigned int val_irq;
556 u32 tmu_intstat, tmu_intclear;
557
558 if (data->soc == SOC_ARCH_EXYNOS5260) {
559 tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
560 tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
561 } else {
562 tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
563 tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
564 }
565
566 val_irq = readl(data->base + tmu_intstat);
567 /*
568 * Clear the interrupts. Please note that the documentation for
569 * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
570 * states that INTCLEAR register has a different placing of bits
571 * responsible for FALL IRQs than INTSTAT register. Exynos5420
572 * and Exynos5440 documentation is correct (Exynos4210 doesn't
573 * support FALL IRQs at all).
574 */
575 writel(val_irq, data->base + tmu_intclear);
576}
577
578static void exynos5440_tmu_clear_irqs(struct exynos_tmu_data *data)
579{
580 unsigned int val_irq;
581
582 val_irq = readl(data->base + EXYNOS5440_TMU_S0_7_IRQ);
583 /* clear the interrupts */
584 writel(val_irq, data->base + EXYNOS5440_TMU_S0_7_IRQ);
585}
586
568static irqreturn_t exynos_tmu_irq(int irq, void *id) 587static irqreturn_t exynos_tmu_irq(int irq, void *id)
569{ 588{
570 struct exynos_tmu_data *data = id; 589 struct exynos_tmu_data *data = id;
@@ -760,6 +779,7 @@ static int exynos_tmu_probe(struct platform_device *pdev)
760 data->tmu_initialize = exynos4210_tmu_initialize; 779 data->tmu_initialize = exynos4210_tmu_initialize;
761 data->tmu_control = exynos4210_tmu_control; 780 data->tmu_control = exynos4210_tmu_control;
762 data->tmu_read = exynos4210_tmu_read; 781 data->tmu_read = exynos4210_tmu_read;
782 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
763 break; 783 break;
764 case SOC_ARCH_EXYNOS3250: 784 case SOC_ARCH_EXYNOS3250:
765 case SOC_ARCH_EXYNOS4412: 785 case SOC_ARCH_EXYNOS4412:
@@ -771,12 +791,14 @@ static int exynos_tmu_probe(struct platform_device *pdev)
771 data->tmu_control = exynos4210_tmu_control; 791 data->tmu_control = exynos4210_tmu_control;
772 data->tmu_read = exynos4412_tmu_read; 792 data->tmu_read = exynos4412_tmu_read;
773 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 793 data->tmu_set_emulation = exynos4412_tmu_set_emulation;
794 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
774 break; 795 break;
775 case SOC_ARCH_EXYNOS5440: 796 case SOC_ARCH_EXYNOS5440:
776 data->tmu_initialize = exynos5440_tmu_initialize; 797 data->tmu_initialize = exynos5440_tmu_initialize;
777 data->tmu_control = exynos5440_tmu_control; 798 data->tmu_control = exynos5440_tmu_control;
778 data->tmu_read = exynos5440_tmu_read; 799 data->tmu_read = exynos5440_tmu_read;
779 data->tmu_set_emulation = exynos5440_tmu_set_emulation; 800 data->tmu_set_emulation = exynos5440_tmu_set_emulation;
801 data->tmu_clear_irqs = exynos5440_tmu_clear_irqs;
780 break; 802 break;
781 default: 803 default:
782 ret = -EINVAL; 804 ret = -EINVAL;
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
index 785eccf22c19..c4c0aa58f3a1 100644
--- a/drivers/thermal/samsung/exynos_tmu.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -68,17 +68,6 @@ enum soc_type {
68#define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) 68#define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b)
69 69
70/** 70/**
71 * struct exynos_tmu_register - register descriptors to access registers.
72 * The register validity may vary slightly across different exynos SOC's.
73 * @tmu_intstat: Register containing the interrupt status values.
74 * @tmu_intclear: Register for clearing the raised interrupt status.
75 */
76struct exynos_tmu_registers {
77 u32 tmu_intstat;
78 u32 tmu_intclear;
79};
80
81/**
82 * struct exynos_tmu_platform_data 71 * struct exynos_tmu_platform_data
83 * @threshold: basic temperature for generating interrupt 72 * @threshold: basic temperature for generating interrupt
84 * 25 <= threshold <= 125 [unit: degree Celsius] 73 * 25 <= threshold <= 125 [unit: degree Celsius]
@@ -127,8 +116,6 @@ struct exynos_tmu_registers {
127 * @freq_clip_table: Table representing frequency reduction percentage. 116 * @freq_clip_table: Table representing frequency reduction percentage.
128 * @freq_tab_count: Count of the above table as frequency reduction may 117 * @freq_tab_count: Count of the above table as frequency reduction may
129 * applicable to only some of the trigger levels. 118 * applicable to only some of the trigger levels.
130 * @registers: Pointer to structure containing all the TMU controller registers
131 * and bitfields shifts and masks.
132 * @features: a bitfield value indicating the features supported in SOC like 119 * @features: a bitfield value indicating the features supported in SOC like
133 * emulation, multi instance etc 120 * emulation, multi instance etc
134 * 121 *
@@ -158,7 +145,6 @@ struct exynos_tmu_platform_data {
158 enum soc_type type; 145 enum soc_type type;
159 struct freq_clip_table freq_tab[4]; 146 struct freq_clip_table freq_tab[4];
160 unsigned int freq_tab_count; 147 unsigned int freq_tab_count;
161 const struct exynos_tmu_registers *registers;
162 unsigned int features; 148 unsigned int features;
163}; 149};
164 150
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
index d0bb4b35d0b9..d35ec1545a2d 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.c
+++ b/drivers/thermal/samsung/exynos_tmu_data.c
@@ -25,11 +25,6 @@
25#include "exynos_tmu_data.h" 25#include "exynos_tmu_data.h"
26 26
27#if defined(CONFIG_CPU_EXYNOS4210) 27#if defined(CONFIG_CPU_EXYNOS4210)
28static const struct exynos_tmu_registers exynos4210_tmu_registers = {
29 .tmu_intstat = EXYNOS_TMU_REG_INTSTAT,
30 .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
31};
32
33struct exynos_tmu_init_data const exynos4210_default_tmu_data = { 28struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
34 .tmu_data = { 29 .tmu_data = {
35 { 30 {
@@ -64,7 +59,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
64 }, 59 },
65 .freq_tab_count = 2, 60 .freq_tab_count = 2,
66 .type = SOC_ARCH_EXYNOS4210, 61 .type = SOC_ARCH_EXYNOS4210,
67 .registers = &exynos4210_tmu_registers,
68 }, 62 },
69 }, 63 },
70 .tmu_count = 1, 64 .tmu_count = 1,
@@ -72,11 +66,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
72#endif 66#endif
73 67
74#if defined(CONFIG_SOC_EXYNOS3250) 68#if defined(CONFIG_SOC_EXYNOS3250)
75static const struct exynos_tmu_registers exynos3250_tmu_registers = {
76 .tmu_intstat = EXYNOS_TMU_REG_INTSTAT,
77 .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
78};
79
80#define EXYNOS3250_TMU_DATA \ 69#define EXYNOS3250_TMU_DATA \
81 .threshold_falling = 10, \ 70 .threshold_falling = 10, \
82 .trigger_levels[0] = 70, \ 71 .trigger_levels[0] = 70, \
@@ -112,7 +101,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = {
112 .temp_level = 95, \ 101 .temp_level = 95, \
113 }, \ 102 }, \
114 .freq_tab_count = 2, \ 103 .freq_tab_count = 2, \
115 .registers = &exynos3250_tmu_registers, \
116 .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ 104 .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \
117 TMU_SUPPORT_EMUL_TIME) 105 TMU_SUPPORT_EMUL_TIME)
118#endif 106#endif
@@ -131,11 +119,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = {
131#endif 119#endif
132 120
133#if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) 121#if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250)
134static const struct exynos_tmu_registers exynos4412_tmu_registers = {
135 .tmu_intstat = EXYNOS_TMU_REG_INTSTAT,
136 .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
137};
138
139#define EXYNOS4412_TMU_DATA \ 122#define EXYNOS4412_TMU_DATA \
140 .threshold_falling = 10, \ 123 .threshold_falling = 10, \
141 .trigger_levels[0] = 70, \ 124 .trigger_levels[0] = 70, \
@@ -171,7 +154,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = {
171 .temp_level = 95, \ 154 .temp_level = 95, \
172 }, \ 155 }, \
173 .freq_tab_count = 2, \ 156 .freq_tab_count = 2, \
174 .registers = &exynos4412_tmu_registers, \
175 .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ 157 .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \
176 TMU_SUPPORT_EMUL_TIME) 158 TMU_SUPPORT_EMUL_TIME)
177#endif 159#endif
@@ -202,11 +184,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = {
202#endif 184#endif
203 185
204#if defined(CONFIG_SOC_EXYNOS5260) 186#if defined(CONFIG_SOC_EXYNOS5260)
205static const struct exynos_tmu_registers exynos5260_tmu_registers = {
206 .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT,
207 .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR,
208};
209
210#define __EXYNOS5260_TMU_DATA \ 187#define __EXYNOS5260_TMU_DATA \
211 .threshold_falling = 10, \ 188 .threshold_falling = 10, \
212 .trigger_levels[0] = 85, \ 189 .trigger_levels[0] = 85, \
@@ -242,7 +219,6 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = {
242 .temp_level = 103, \ 219 .temp_level = 103, \
243 }, \ 220 }, \
244 .freq_tab_count = 2, \ 221 .freq_tab_count = 2, \
245 .registers = &exynos5260_tmu_registers, \
246 222
247#define EXYNOS5260_TMU_DATA \ 223#define EXYNOS5260_TMU_DATA \
248 __EXYNOS5260_TMU_DATA \ 224 __EXYNOS5260_TMU_DATA \
@@ -263,11 +239,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = {
263#endif 239#endif
264 240
265#if defined(CONFIG_SOC_EXYNOS5420) 241#if defined(CONFIG_SOC_EXYNOS5420)
266static const struct exynos_tmu_registers exynos5420_tmu_registers = {
267 .tmu_intstat = EXYNOS_TMU_REG_INTSTAT,
268 .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
269};
270
271#define __EXYNOS5420_TMU_DATA \ 242#define __EXYNOS5420_TMU_DATA \
272 .threshold_falling = 10, \ 243 .threshold_falling = 10, \
273 .trigger_levels[0] = 85, \ 244 .trigger_levels[0] = 85, \
@@ -303,7 +274,6 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = {
303 .temp_level = 103, \ 274 .temp_level = 103, \
304 }, \ 275 }, \
305 .freq_tab_count = 2, \ 276 .freq_tab_count = 2, \
306 .registers = &exynos5420_tmu_registers, \
307 277
308#define EXYNOS5420_TMU_DATA \ 278#define EXYNOS5420_TMU_DATA \
309 __EXYNOS5420_TMU_DATA \ 279 __EXYNOS5420_TMU_DATA \
@@ -330,11 +300,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = {
330#endif 300#endif
331 301
332#if defined(CONFIG_SOC_EXYNOS5440) 302#if defined(CONFIG_SOC_EXYNOS5440)
333static const struct exynos_tmu_registers exynos5440_tmu_registers = {
334 .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ,
335 .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ,
336};
337
338#define EXYNOS5440_TMU_DATA \ 303#define EXYNOS5440_TMU_DATA \
339 .trigger_levels[0] = 100, \ 304 .trigger_levels[0] = 100, \
340 .trigger_levels[4] = 105, \ 305 .trigger_levels[4] = 105, \
@@ -354,7 +319,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = {
354 .second_point_trim = 70, \ 319 .second_point_trim = 70, \
355 .default_temp_offset = 25, \ 320 .default_temp_offset = 25, \
356 .type = SOC_ARCH_EXYNOS5440, \ 321 .type = SOC_ARCH_EXYNOS5440, \
357 .registers = &exynos5440_tmu_registers, \
358 .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ 322 .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \
359 TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE), 323 TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE),
360 324