aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal/samsung/exynos_tmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal/samsung/exynos_tmu.c')
-rw-r--r--drivers/thermal/samsung/exynos_tmu.c64
1 files changed, 43 insertions, 21 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;