Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

thermal: exynos: fix IRQ clearing on TMU initialization

* Factor out code for clearing raised IRQs from exynos_tmu_work() to
exynos_tmu_clear_irqs().

* Add a comment about documentation bugs to exynos_tmu_clear_irqs().

[ The documentation for Exynos3250, Exynos4412, Exynos5250 and
Exynos5260 incorrectly states that INTCLEAR register has
a different placing of bits responsible for FALL IRQs than
INTSTAT register. Exynos5420 and Exynos5440 documentation is
correct (Exynos4210 doesn't support FALL IRQs at all). ]

* Use exynos_tmu_clear_irqs() in exynos_tmu_initialize() instead
of open-coded code trying to clear IRQs according to predefined
masks. After this change exynos_tmu_initialize() just clears
IRQs that are raised like it is already done in exynos_tmu_work().

As a nice side-effect the code now uses the correct offset
(16 instead of 12) for bits responsible for clearing FALL IRQs
in INTCLEAR register on Exynos3250, Exynos4412 and Exynos5250.

* Remove no longer needed intclr_rise_[mask,shift] and
intclr_fall_[mask,shift] fields from struct exynos_tmu_registers.

* Remove no longer needed defines.

This patch has been tested on Exynos4412 and Exynos5420 SoCs.

Cc: Amit Daniel Kachhap <amit.daniel@samsung.com>
Cc: Lukasz Majewski <l.majewski@samsung.com>
Cc: Eduardo Valentin <edubezval@gmail.com>
Cc: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Eduardo Valentin <edubezval@gmail.com>

authored by

Bartlomiej Zolnierkiewicz and committed by
Eduardo Valentin
b835ced1 c2aad93c

+21 -52
+21 -8
drivers/thermal/samsung/exynos_tmu.c
··· 122 122 return temp; 123 123 } 124 124 125 + static void exynos_tmu_clear_irqs(struct exynos_tmu_data *data) 126 + { 127 + const struct exynos_tmu_registers *reg = data->pdata->registers; 128 + unsigned int val_irq; 129 + 130 + val_irq = readl(data->base + reg->tmu_intstat); 131 + /* 132 + * Clear the interrupts. Please note that the documentation for 133 + * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly 134 + * states that INTCLEAR register has a different placing of bits 135 + * responsible for FALL IRQs than INTSTAT register. Exynos5420 136 + * and Exynos5440 documentation is correct (Exynos4210 doesn't 137 + * support FALL IRQs at all). 138 + */ 139 + writel(val_irq, data->base + reg->tmu_intclear); 140 + } 141 + 125 142 static int exynos_tmu_initialize(struct platform_device *pdev) 126 143 { 127 144 struct exynos_tmu_data *data = platform_get_drvdata(pdev); ··· 224 207 writeb(pdata->trigger_levels[i], data->base + 225 208 reg->threshold_th0 + i * sizeof(reg->threshold_th0)); 226 209 227 - writel(reg->intclr_rise_mask, data->base + reg->tmu_intclear); 210 + exynos_tmu_clear_irqs(data); 228 211 } else { 229 212 /* Write temperature code for rising and falling threshold */ 230 213 for (i = 0; i < pdata->non_hw_trigger_levels; i++) { ··· 245 228 writel(falling_threshold, 246 229 data->base + reg->threshold_th1); 247 230 248 - writel((reg->intclr_rise_mask << reg->intclr_rise_shift) | 249 - (reg->intclr_fall_mask << reg->intclr_fall_shift), 250 - data->base + reg->tmu_intclear); 231 + exynos_tmu_clear_irqs(data); 251 232 252 233 /* if last threshold limit is also present */ 253 234 i = pdata->max_trigger_level - 1; ··· 411 396 struct exynos_tmu_data, irq_work); 412 397 struct exynos_tmu_platform_data *pdata = data->pdata; 413 398 const struct exynos_tmu_registers *reg = pdata->registers; 414 - unsigned int val_irq, val_type; 399 + unsigned int val_type; 415 400 416 401 if (!IS_ERR(data->clk_sec)) 417 402 clk_enable(data->clk_sec); ··· 429 414 clk_enable(data->clk); 430 415 431 416 /* TODO: take action based on particular interrupt */ 432 - val_irq = readl(data->base + reg->tmu_intstat); 433 - /* clear the interrupts */ 434 - writel(val_irq, data->base + reg->tmu_intclear); 417 + exynos_tmu_clear_irqs(data); 435 418 436 419 clk_disable(data->clk); 437 420 mutex_unlock(&data->lock);
-8
drivers/thermal/samsung/exynos_tmu.h
··· 100 100 * @inten_fall0_shift: shift bits of falling 0 interrupt bits. 101 101 * @tmu_intstat: Register containing the interrupt status values. 102 102 * @tmu_intclear: Register for clearing the raised interrupt status. 103 - * @intclr_fall_shift: shift bits for interrupt clear fall 0 104 - * @intclr_rise_shift: shift bits of all rising interrupt bits. 105 - * @intclr_rise_mask: mask bits of all rising interrupt bits. 106 - * @intclr_fall_mask: mask bits of all rising interrupt bits. 107 103 * @emul_con: TMU emulation controller register. 108 104 * @emul_temp_shift: shift bits of emulation temperature. 109 105 * @emul_time_shift: shift bits of emulation time. ··· 139 143 u32 tmu_intstat; 140 144 141 145 u32 tmu_intclear; 142 - u32 intclr_fall_shift; 143 - u32 intclr_rise_shift; 144 - u32 intclr_fall_mask; 145 - u32 intclr_rise_mask; 146 146 147 147 u32 emul_con; 148 148 u32 emul_temp_shift;
-21
drivers/thermal/samsung/exynos_tmu_data.c
··· 39 39 .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, 40 40 .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, 41 41 .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, 42 - .intclr_rise_mask = EXYNOS4210_TMU_TRIG_LEVEL_MASK, 43 42 }; 44 43 45 44 struct exynos_tmu_init_data const exynos4210_default_tmu_data = { ··· 105 106 .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, 106 107 .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, 107 108 .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, 108 - .intclr_fall_shift = EXYNOS_TMU_CLEAR_FALL_INT_SHIFT, 109 - .intclr_rise_shift = EXYNOS_TMU_RISE_INT_SHIFT, 110 - .intclr_rise_mask = EXYNOS_TMU_RISE_INT_MASK, 111 - .intclr_fall_mask = EXYNOS_TMU_FALL_INT_MASK, 112 109 .emul_con = EXYNOS_EMUL_CON, 113 110 .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, 114 111 .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, ··· 188 193 .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, 189 194 .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, 190 195 .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, 191 - .intclr_fall_shift = EXYNOS_TMU_CLEAR_FALL_INT_SHIFT, 192 - .intclr_rise_shift = EXYNOS_TMU_RISE_INT_SHIFT, 193 - .intclr_rise_mask = EXYNOS_TMU_RISE_INT_MASK, 194 - .intclr_fall_mask = EXYNOS_TMU_FALL_INT_MASK, 195 196 .emul_con = EXYNOS_EMUL_CON, 196 197 .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, 197 198 .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, ··· 280 289 .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, 281 290 .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, 282 291 .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, 283 - .intclr_fall_shift = EXYNOS5420_TMU_CLEAR_FALL_INT_SHIFT, 284 - .intclr_rise_shift = EXYNOS_TMU_RISE_INT_SHIFT, 285 - .intclr_rise_mask = EXYNOS5260_TMU_RISE_INT_MASK, 286 - .intclr_fall_mask = EXYNOS5260_TMU_FALL_INT_MASK, 287 292 .emul_con = EXYNOS5260_EMUL_CON, 288 293 .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, 289 294 .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, ··· 360 373 .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, 361 374 .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, 362 375 .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, 363 - .intclr_fall_shift = EXYNOS5420_TMU_CLEAR_FALL_INT_SHIFT, 364 - .intclr_rise_shift = EXYNOS_TMU_RISE_INT_SHIFT, 365 - .intclr_rise_mask = EXYNOS_TMU_RISE_INT_MASK, 366 - .intclr_fall_mask = EXYNOS_TMU_FALL_INT_MASK, 367 376 .emul_con = EXYNOS_EMUL_CON, 368 377 .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, 369 378 .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, ··· 448 465 .inten_fall0_shift = EXYNOS5440_TMU_INTEN_FALL0_SHIFT, 449 466 .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, 450 467 .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, 451 - .intclr_fall_shift = EXYNOS5440_TMU_CLEAR_FALL_INT_SHIFT, 452 - .intclr_rise_shift = EXYNOS5440_TMU_RISE_INT_SHIFT, 453 - .intclr_rise_mask = EXYNOS5440_TMU_RISE_INT_MASK, 454 - .intclr_fall_mask = EXYNOS5440_TMU_FALL_INT_MASK, 455 468 .tmu_irqstatus = EXYNOS5440_TMU_IRQ_STATUS, 456 469 .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, 457 470 .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT,
-15
drivers/thermal/samsung/exynos_tmu_data.h
··· 46 46 #define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44 47 47 #define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50 48 48 49 - #define EXYNOS4210_TMU_TRIG_LEVEL_MASK 0x1111 50 - 51 49 /* Exynos5250, Exynos4412, Exynos3250 specific registers */ 52 50 #define EXYNOS_TMU_TRIMINFO_CON2 0x14 53 51 #define EXYNOS_THD_TEMP_RISE 0x50 ··· 55 57 #define EXYNOS_TRIMINFO_RELOAD_ENABLE 1 56 58 #define EXYNOS_TRIMINFO_25_SHIFT 0 57 59 #define EXYNOS_TRIMINFO_85_SHIFT 8 58 - #define EXYNOS_TMU_RISE_INT_MASK 0x111 59 - #define EXYNOS_TMU_RISE_INT_SHIFT 0 60 - #define EXYNOS_TMU_FALL_INT_MASK 0x111 61 - #define EXYNOS_TMU_CLEAR_FALL_INT_SHIFT 12 62 - #define EXYNOS5420_TMU_CLEAR_FALL_INT_SHIFT 16 63 - #define EXYNOS5440_TMU_CLEAR_FALL_INT_SHIFT 4 64 60 #define EXYNOS_TMU_TRIP_MODE_SHIFT 13 65 61 #define EXYNOS_TMU_TRIP_MODE_MASK 0x7 66 62 #define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12 ··· 79 87 #define EXYNOS5260_TMU_REG_INTEN 0xC0 80 88 #define EXYNOS5260_TMU_REG_INTSTAT 0xC4 81 89 #define EXYNOS5260_TMU_REG_INTCLEAR 0xC8 82 - #define EXYNOS5260_TMU_CLEAR_RISE_INT 0x1111 83 - #define EXYNOS5260_TMU_CLEAR_FALL_INT (0x1111 << 16) 84 - #define EXYNOS5260_TMU_RISE_INT_MASK 0x1111 85 - #define EXYNOS5260_TMU_FALL_INT_MASK 0x1111 86 90 #define EXYNOS5260_EMUL_CON 0x100 87 91 88 92 /* Exynos4412 specific */ ··· 100 112 #define EXYNOS5440_TMU_IRQ_STATUS 0x000 101 113 #define EXYNOS5440_TMU_PMIN 0x004 102 114 103 - #define EXYNOS5440_TMU_RISE_INT_MASK 0xf 104 - #define EXYNOS5440_TMU_RISE_INT_SHIFT 0 105 - #define EXYNOS5440_TMU_FALL_INT_MASK 0xf 106 115 #define EXYNOS5440_TMU_INTEN_RISE0_SHIFT 0 107 116 #define EXYNOS5440_TMU_INTEN_RISE1_SHIFT 1 108 117 #define EXYNOS5440_TMU_INTEN_RISE2_SHIFT 2