diff options
Diffstat (limited to 'drivers/thermal')
-rw-r--r-- | drivers/thermal/samsung/exynos_tmu.c | 64 | ||||
-rw-r--r-- | drivers/thermal/samsung/exynos_tmu.h | 14 | ||||
-rw-r--r-- | drivers/thermal/samsung/exynos_tmu_data.c | 36 |
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 | */ |
60 | struct exynos_tmu_data { | 61 | struct 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 | ||
134 | static 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 | |||
151 | static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) | 136 | static 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); |
263 | out: | 248 | out: |
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 | ||
553 | static 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 | |||
578 | static 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 | |||
568 | static irqreturn_t exynos_tmu_irq(int irq, void *id) | 587 | static 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 | */ | ||
76 | struct 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) |
28 | static const struct exynos_tmu_registers exynos4210_tmu_registers = { | ||
29 | .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, | ||
30 | .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, | ||
31 | }; | ||
32 | |||
33 | struct exynos_tmu_init_data const exynos4210_default_tmu_data = { | 28 | struct 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) |
75 | static 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) |
134 | static 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) |
205 | static 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) |
266 | static 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) |
333 | static 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 | ||