1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * exynos_tmu.c - Samsung Exynos TMU (Thermal Management Unit) 4 * 5 * Copyright (C) 2014 Samsung Electronics 6 * Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> 7 * Lukasz Majewski <l.majewski@samsung.com> 8 * 9 * Copyright (C) 2011 Samsung Electronics 10 * Donggeun Kim <dg77.kim@samsung.com> 11 * Amit Daniel Kachhap <amit.kachhap@linaro.org> 12 */ 13 14 #include <linux/clk.h> 15 #include <linux/io.h> 16 #include <linux/interrupt.h> 17 #include <linux/module.h> 18 #include <linux/of_device.h> 19 #include <linux/of_address.h> 20 #include <linux/of_irq.h> 21 #include <linux/platform_device.h> 22 #include <linux/regulator/consumer.h> 23 24 #include <dt-bindings/thermal/thermal_exynos.h> 25 26 #include "../thermal_core.h" 27 28 /* Exynos generic registers */ 29 #define EXYNOS_TMU_REG_TRIMINFO 0x0 30 #define EXYNOS_TMU_REG_CONTROL 0x20 31 #define EXYNOS_TMU_REG_STATUS 0x28 32 #define EXYNOS_TMU_REG_CURRENT_TEMP 0x40 33 #define EXYNOS_TMU_REG_INTEN 0x70 34 #define EXYNOS_TMU_REG_INTSTAT 0x74 35 #define EXYNOS_TMU_REG_INTCLEAR 0x78 36 37 #define EXYNOS_TMU_TEMP_MASK 0xff 38 #define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24 39 #define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f 40 #define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf 41 #define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8 42 #define EXYNOS_TMU_CORE_EN_SHIFT 0 43 44 /* Exynos3250 specific registers */ 45 #define EXYNOS_TMU_TRIMINFO_CON1 0x10 46 47 /* Exynos4210 specific registers */ 48 #define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44 49 #define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50 50 51 /* Exynos5250, Exynos4412, Exynos3250 specific registers */ 52 #define EXYNOS_TMU_TRIMINFO_CON2 0x14 53 #define EXYNOS_THD_TEMP_RISE 0x50 54 #define EXYNOS_THD_TEMP_FALL 0x54 55 #define EXYNOS_EMUL_CON 0x80 56 57 #define EXYNOS_TRIMINFO_RELOAD_ENABLE 1 58 #define EXYNOS_TRIMINFO_25_SHIFT 0 59 #define EXYNOS_TRIMINFO_85_SHIFT 8 60 #define EXYNOS_TMU_TRIP_MODE_SHIFT 13 61 #define EXYNOS_TMU_TRIP_MODE_MASK 0x7 62 #define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12 63 64 #define EXYNOS_TMU_INTEN_RISE0_SHIFT 0 65 #define EXYNOS_TMU_INTEN_FALL0_SHIFT 16 66 67 #define EXYNOS_EMUL_TIME 0x57F0 68 #define EXYNOS_EMUL_TIME_MASK 0xffff 69 #define EXYNOS_EMUL_TIME_SHIFT 16 70 #define EXYNOS_EMUL_DATA_SHIFT 8 71 #define EXYNOS_EMUL_DATA_MASK 0xFF 72 #define EXYNOS_EMUL_ENABLE 0x1 73 74 /* Exynos5260 specific */ 75 #define EXYNOS5260_TMU_REG_INTEN 0xC0 76 #define EXYNOS5260_TMU_REG_INTSTAT 0xC4 77 #define EXYNOS5260_TMU_REG_INTCLEAR 0xC8 78 #define EXYNOS5260_EMUL_CON 0x100 79 80 /* Exynos4412 specific */ 81 #define EXYNOS4412_MUX_ADDR_VALUE 6 82 #define EXYNOS4412_MUX_ADDR_SHIFT 20 83 84 /* Exynos5433 specific registers */ 85 #define EXYNOS5433_THD_TEMP_RISE3_0 0x050 86 #define EXYNOS5433_THD_TEMP_RISE7_4 0x054 87 #define EXYNOS5433_THD_TEMP_FALL3_0 0x060 88 #define EXYNOS5433_THD_TEMP_FALL7_4 0x064 89 #define EXYNOS5433_TMU_REG_INTEN 0x0c0 90 #define EXYNOS5433_TMU_REG_INTPEND 0x0c8 91 #define EXYNOS5433_TMU_EMUL_CON 0x110 92 #define EXYNOS5433_TMU_PD_DET_EN 0x130 93 94 #define EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT 16 95 #define EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT 23 96 #define EXYNOS5433_TRIMINFO_SENSOR_ID_MASK \ 97 (0xf << EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT) 98 #define EXYNOS5433_TRIMINFO_CALIB_SEL_MASK BIT(23) 99 100 #define EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING 0 101 #define EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING 1 102 103 #define EXYNOS5433_PD_DET_EN 1 104 105 #define EXYNOS5433_G3D_BASE 0x10070000 106 107 /* Exynos7 specific registers */ 108 #define EXYNOS7_THD_TEMP_RISE7_6 0x50 109 #define EXYNOS7_THD_TEMP_FALL7_6 0x60 110 #define EXYNOS7_TMU_REG_INTEN 0x110 111 #define EXYNOS7_TMU_REG_INTPEND 0x118 112 #define EXYNOS7_TMU_REG_EMUL_CON 0x160 113 114 #define EXYNOS7_TMU_TEMP_MASK 0x1ff 115 #define EXYNOS7_PD_DET_EN_SHIFT 23 116 #define EXYNOS7_TMU_INTEN_RISE0_SHIFT 0 117 #define EXYNOS7_EMUL_DATA_SHIFT 7 118 #define EXYNOS7_EMUL_DATA_MASK 0x1ff 119 120 #define EXYNOS_FIRST_POINT_TRIM 25 121 #define EXYNOS_SECOND_POINT_TRIM 85 122 123 #define EXYNOS_NOISE_CANCEL_MODE 4 124 125 #define MCELSIUS 1000 126 127 enum soc_type { 128 SOC_ARCH_EXYNOS3250 = 1, 129 SOC_ARCH_EXYNOS4210, 130 SOC_ARCH_EXYNOS4412, 131 SOC_ARCH_EXYNOS5250, 132 SOC_ARCH_EXYNOS5260, 133 SOC_ARCH_EXYNOS5420, 134 SOC_ARCH_EXYNOS5420_TRIMINFO, 135 SOC_ARCH_EXYNOS5433, 136 SOC_ARCH_EXYNOS7, 137 }; 138 139 /** 140 * struct exynos_tmu_data : A structure to hold the private data of the TMU 141 * driver 142 * @id: identifier of the one instance of the TMU controller. 143 * @base: base address of the single instance of the TMU controller. 144 * @base_second: base address of the common registers of the TMU controller. 145 * @irq: irq number of the TMU controller. 146 * @soc: id of the SOC type. 147 * @irq_work: pointer to the irq work structure. 148 * @lock: lock to implement synchronization. 149 * @clk: pointer to the clock structure. 150 * @clk_sec: pointer to the clock structure for accessing the base_second. 151 * @sclk: pointer to the clock structure for accessing the tmu special clk. 152 * @cal_type: calibration type for temperature 153 * @efuse_value: SoC defined fuse value 154 * @min_efuse_value: minimum valid trimming data 155 * @max_efuse_value: maximum valid trimming data 156 * @temp_error1: fused value of the first point trim. 157 * @temp_error2: fused value of the second point trim. 158 * @gain: gain of amplifier in the positive-TC generator block 159 * 0 < gain <= 15 160 * @reference_voltage: reference voltage of amplifier 161 * in the positive-TC generator block 162 * 0 < reference_voltage <= 31 163 * @regulator: pointer to the TMU regulator structure. 164 * @reg_conf: pointer to structure to register with core thermal. 165 * @tzd: pointer to thermal_zone_device structure 166 * @ntrip: number of supported trip points. 167 * @enabled: current status of TMU device 168 * @tmu_set_trip_temp: SoC specific method to set trip (rising threshold) 169 * @tmu_set_trip_hyst: SoC specific to set hysteresis (falling threshold) 170 * @tmu_initialize: SoC specific TMU initialization method 171 * @tmu_control: SoC specific TMU control method 172 * @tmu_read: SoC specific TMU temperature read method 173 * @tmu_set_emulation: SoC specific TMU emulation setting method 174 * @tmu_clear_irqs: SoC specific TMU interrupts clearing method 175 */ 176 struct exynos_tmu_data { 177 int id; 178 void __iomem *base; 179 void __iomem *base_second; 180 int irq; 181 enum soc_type soc; 182 struct work_struct irq_work; 183 struct mutex lock; 184 struct clk *clk, *clk_sec, *sclk; 185 u32 cal_type; 186 u32 efuse_value; 187 u32 min_efuse_value; 188 u32 max_efuse_value; 189 u16 temp_error1, temp_error2; 190 u8 gain; 191 u8 reference_voltage; 192 struct regulator *regulator; 193 struct thermal_zone_device *tzd; 194 unsigned int ntrip; 195 bool enabled; 196 197 void (*tmu_set_trip_temp)(struct exynos_tmu_data *data, int trip, 198 u8 temp); 199 void (*tmu_set_trip_hyst)(struct exynos_tmu_data *data, int trip, 200 u8 temp, u8 hyst); 201 void (*tmu_initialize)(struct platform_device *pdev); 202 void (*tmu_control)(struct platform_device *pdev, bool on); 203 int (*tmu_read)(struct exynos_tmu_data *data); 204 void (*tmu_set_emulation)(struct exynos_tmu_data *data, int temp); 205 void (*tmu_clear_irqs)(struct exynos_tmu_data *data); 206 }; 207 208 /* 209 * TMU treats temperature as a mapped temperature code. 210 * The temperature is converted differently depending on the calibration type. 211 */ 212 static int temp_to_code(struct exynos_tmu_data *data, u8 temp) 213 { 214 if (data->cal_type == TYPE_ONE_POINT_TRIMMING) 215 return temp + data->temp_error1 - EXYNOS_FIRST_POINT_TRIM; 216 217 return (temp - EXYNOS_FIRST_POINT_TRIM) * 218 (data->temp_error2 - data->temp_error1) / 219 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) + 220 data->temp_error1; 221 } 222 223 /* 224 * Calculate a temperature value from a temperature code. 225 * The unit of the temperature is degree Celsius. 226 */ 227 static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code) 228 { 229 if (data->cal_type == TYPE_ONE_POINT_TRIMMING) 230 return temp_code - data->temp_error1 + EXYNOS_FIRST_POINT_TRIM; 231 232 return (temp_code - data->temp_error1) * 233 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) / 234 (data->temp_error2 - data->temp_error1) + 235 EXYNOS_FIRST_POINT_TRIM; 236 } 237 238 static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) 239 { 240 u16 tmu_temp_mask = 241 (data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK 242 : EXYNOS_TMU_TEMP_MASK; 243 244 data->temp_error1 = trim_info & tmu_temp_mask; 245 data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & 246 EXYNOS_TMU_TEMP_MASK); 247 248 if (!data->temp_error1 || 249 (data->min_efuse_value > data->temp_error1) || 250 (data->temp_error1 > data->max_efuse_value)) 251 data->temp_error1 = data->efuse_value & EXYNOS_TMU_TEMP_MASK; 252 253 if (!data->temp_error2) 254 data->temp_error2 = 255 (data->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) & 256 EXYNOS_TMU_TEMP_MASK; 257 } 258 259 static int exynos_tmu_initialize(struct platform_device *pdev) 260 { 261 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 262 struct thermal_zone_device *tzd = data->tzd; 263 int num_trips = thermal_zone_get_num_trips(tzd); 264 unsigned int status; 265 int ret = 0, temp; 266 267 ret = thermal_zone_get_crit_temp(tzd, &temp); 268 if (ret && data->soc != SOC_ARCH_EXYNOS5433) { /* FIXME */ 269 dev_err(&pdev->dev, 270 "No CRITICAL trip point defined in device tree!\n"); 271 goto out; 272 } 273 274 if (num_trips > data->ntrip) { 275 dev_info(&pdev->dev, 276 "More trip points than supported by this TMU.\n"); 277 dev_info(&pdev->dev, 278 "%d trip points should be configured in polling mode.\n", 279 num_trips - data->ntrip); 280 } 281 282 mutex_lock(&data->lock); 283 clk_enable(data->clk); 284 if (!IS_ERR(data->clk_sec)) 285 clk_enable(data->clk_sec); 286 287 status = readb(data->base + EXYNOS_TMU_REG_STATUS); 288 if (!status) { 289 ret = -EBUSY; 290 } else { 291 int i, ntrips = 292 min_t(int, num_trips, data->ntrip); 293 294 data->tmu_initialize(pdev); 295 296 /* Write temperature code for rising and falling threshold */ 297 for (i = 0; i < ntrips; i++) { 298 299 struct thermal_trip trip; 300 301 ret = thermal_zone_get_trip(tzd, i, &trip); 302 if (ret) 303 goto err; 304 305 data->tmu_set_trip_temp(data, i, trip.temperature / MCELSIUS); 306 data->tmu_set_trip_hyst(data, i, trip.temperature / MCELSIUS, 307 trip.hysteresis / MCELSIUS); 308 } 309 310 data->tmu_clear_irqs(data); 311 } 312 err: 313 clk_disable(data->clk); 314 mutex_unlock(&data->lock); 315 if (!IS_ERR(data->clk_sec)) 316 clk_disable(data->clk_sec); 317 out: 318 return ret; 319 } 320 321 static u32 get_con_reg(struct exynos_tmu_data *data, u32 con) 322 { 323 if (data->soc == SOC_ARCH_EXYNOS4412 || 324 data->soc == SOC_ARCH_EXYNOS3250) 325 con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT); 326 327 con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT); 328 con |= data->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT; 329 330 con &= ~(EXYNOS_TMU_BUF_SLOPE_SEL_MASK << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT); 331 con |= (data->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT); 332 333 con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT); 334 con |= (EXYNOS_NOISE_CANCEL_MODE << EXYNOS_TMU_TRIP_MODE_SHIFT); 335 336 return con; 337 } 338 339 static void exynos_tmu_control(struct platform_device *pdev, bool on) 340 { 341 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 342 343 mutex_lock(&data->lock); 344 clk_enable(data->clk); 345 data->tmu_control(pdev, on); 346 data->enabled = on; 347 clk_disable(data->clk); 348 mutex_unlock(&data->lock); 349 } 350 351 static void exynos4210_tmu_set_trip_temp(struct exynos_tmu_data *data, 352 int trip_id, u8 temp) 353 { 354 struct thermal_trip trip; 355 u8 ref, th_code; 356 357 if (thermal_zone_get_trip(data->tzd, 0, &trip)) 358 return; 359 360 ref = trip.temperature / MCELSIUS; 361 362 if (trip_id == 0) { 363 th_code = temp_to_code(data, ref); 364 writeb(th_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); 365 } 366 367 temp -= ref; 368 writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip_id * 4); 369 } 370 371 /* failing thresholds are not supported on Exynos4210 */ 372 static void exynos4210_tmu_set_trip_hyst(struct exynos_tmu_data *data, 373 int trip, u8 temp, u8 hyst) 374 { 375 } 376 377 static void exynos4210_tmu_initialize(struct platform_device *pdev) 378 { 379 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 380 381 sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO)); 382 } 383 384 static void exynos4412_tmu_set_trip_temp(struct exynos_tmu_data *data, 385 int trip, u8 temp) 386 { 387 u32 th, con; 388 389 th = readl(data->base + EXYNOS_THD_TEMP_RISE); 390 th &= ~(0xff << 8 * trip); 391 th |= temp_to_code(data, temp) << 8 * trip; 392 writel(th, data->base + EXYNOS_THD_TEMP_RISE); 393 394 if (trip == 3) { 395 con = readl(data->base + EXYNOS_TMU_REG_CONTROL); 396 con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); 397 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); 398 } 399 } 400 401 static void exynos4412_tmu_set_trip_hyst(struct exynos_tmu_data *data, 402 int trip, u8 temp, u8 hyst) 403 { 404 u32 th; 405 406 th = readl(data->base + EXYNOS_THD_TEMP_FALL); 407 th &= ~(0xff << 8 * trip); 408 if (hyst) 409 th |= temp_to_code(data, temp - hyst) << 8 * trip; 410 writel(th, data->base + EXYNOS_THD_TEMP_FALL); 411 } 412 413 static void exynos4412_tmu_initialize(struct platform_device *pdev) 414 { 415 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 416 unsigned int trim_info, ctrl; 417 418 if (data->soc == SOC_ARCH_EXYNOS3250 || 419 data->soc == SOC_ARCH_EXYNOS4412 || 420 data->soc == SOC_ARCH_EXYNOS5250) { 421 if (data->soc == SOC_ARCH_EXYNOS3250) { 422 ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); 423 ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; 424 writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); 425 } 426 ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2); 427 ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; 428 writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2); 429 } 430 431 /* On exynos5420 the triminfo register is in the shared space */ 432 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) 433 trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO); 434 else 435 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); 436 437 sanitize_temp_error(data, trim_info); 438 } 439 440 static void exynos5433_tmu_set_trip_temp(struct exynos_tmu_data *data, 441 int trip, u8 temp) 442 { 443 unsigned int reg_off, j; 444 u32 th; 445 446 if (trip > 3) { 447 reg_off = EXYNOS5433_THD_TEMP_RISE7_4; 448 j = trip - 4; 449 } else { 450 reg_off = EXYNOS5433_THD_TEMP_RISE3_0; 451 j = trip; 452 } 453 454 th = readl(data->base + reg_off); 455 th &= ~(0xff << j * 8); 456 th |= (temp_to_code(data, temp) << j * 8); 457 writel(th, data->base + reg_off); 458 } 459 460 static void exynos5433_tmu_set_trip_hyst(struct exynos_tmu_data *data, 461 int trip, u8 temp, u8 hyst) 462 { 463 unsigned int reg_off, j; 464 u32 th; 465 466 if (trip > 3) { 467 reg_off = EXYNOS5433_THD_TEMP_FALL7_4; 468 j = trip - 4; 469 } else { 470 reg_off = EXYNOS5433_THD_TEMP_FALL3_0; 471 j = trip; 472 } 473 474 th = readl(data->base + reg_off); 475 th &= ~(0xff << j * 8); 476 th |= (temp_to_code(data, temp - hyst) << j * 8); 477 writel(th, data->base + reg_off); 478 } 479 480 static void exynos5433_tmu_initialize(struct platform_device *pdev) 481 { 482 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 483 unsigned int trim_info; 484 int sensor_id, cal_type; 485 486 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); 487 sanitize_temp_error(data, trim_info); 488 489 /* Read the temperature sensor id */ 490 sensor_id = (trim_info & EXYNOS5433_TRIMINFO_SENSOR_ID_MASK) 491 >> EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT; 492 dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id); 493 494 /* Read the calibration mode */ 495 writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO); 496 cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK) 497 >> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT; 498 499 switch (cal_type) { 500 case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING: 501 data->cal_type = TYPE_TWO_POINT_TRIMMING; 502 break; 503 case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING: 504 default: 505 data->cal_type = TYPE_ONE_POINT_TRIMMING; 506 break; 507 } 508 509 dev_info(&pdev->dev, "Calibration type is %d-point calibration\n", 510 cal_type ? 2 : 1); 511 } 512 513 static void exynos7_tmu_set_trip_temp(struct exynos_tmu_data *data, 514 int trip, u8 temp) 515 { 516 unsigned int reg_off, bit_off; 517 u32 th; 518 519 reg_off = ((7 - trip) / 2) * 4; 520 bit_off = ((8 - trip) % 2); 521 522 th = readl(data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off); 523 th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off)); 524 th |= temp_to_code(data, temp) << (16 * bit_off); 525 writel(th, data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off); 526 } 527 528 static void exynos7_tmu_set_trip_hyst(struct exynos_tmu_data *data, 529 int trip, u8 temp, u8 hyst) 530 { 531 unsigned int reg_off, bit_off; 532 u32 th; 533 534 reg_off = ((7 - trip) / 2) * 4; 535 bit_off = ((8 - trip) % 2); 536 537 th = readl(data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off); 538 th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off)); 539 th |= temp_to_code(data, temp - hyst) << (16 * bit_off); 540 writel(th, data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off); 541 } 542 543 static void exynos7_tmu_initialize(struct platform_device *pdev) 544 { 545 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 546 unsigned int trim_info; 547 548 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); 549 sanitize_temp_error(data, trim_info); 550 } 551 552 static void exynos4210_tmu_control(struct platform_device *pdev, bool on) 553 { 554 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 555 struct thermal_zone_device *tz = data->tzd; 556 struct thermal_trip trip; 557 unsigned int con, interrupt_en = 0, i; 558 559 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); 560 561 if (on) { 562 for (i = 0; i < data->ntrip; i++) { 563 if (thermal_zone_get_trip(tz, i, &trip)) 564 continue; 565 566 interrupt_en |= 567 (1 << (EXYNOS_TMU_INTEN_RISE0_SHIFT + i * 4)); 568 } 569 570 if (data->soc != SOC_ARCH_EXYNOS4210) 571 interrupt_en |= 572 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; 573 574 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); 575 } else { 576 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); 577 } 578 579 writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN); 580 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); 581 } 582 583 static void exynos5433_tmu_control(struct platform_device *pdev, bool on) 584 { 585 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 586 struct thermal_zone_device *tz = data->tzd; 587 struct thermal_trip trip; 588 unsigned int con, interrupt_en = 0, pd_det_en, i; 589 590 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); 591 592 if (on) { 593 for (i = 0; i < data->ntrip; i++) { 594 if (thermal_zone_get_trip(tz, i, &trip)) 595 continue; 596 597 interrupt_en |= 598 (1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i)); 599 } 600 601 interrupt_en |= 602 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; 603 604 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); 605 } else 606 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); 607 608 pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0; 609 610 writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN); 611 writel(interrupt_en, data->base + EXYNOS5433_TMU_REG_INTEN); 612 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); 613 } 614 615 static void exynos7_tmu_control(struct platform_device *pdev, bool on) 616 { 617 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 618 struct thermal_zone_device *tz = data->tzd; 619 struct thermal_trip trip; 620 unsigned int con, interrupt_en = 0, i; 621 622 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); 623 624 if (on) { 625 for (i = 0; i < data->ntrip; i++) { 626 if (thermal_zone_get_trip(tz, i, &trip)) 627 continue; 628 629 interrupt_en |= 630 (1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i)); 631 } 632 633 interrupt_en |= 634 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; 635 636 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); 637 con |= (1 << EXYNOS7_PD_DET_EN_SHIFT); 638 } else { 639 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); 640 con &= ~(1 << EXYNOS7_PD_DET_EN_SHIFT); 641 } 642 643 writel(interrupt_en, data->base + EXYNOS7_TMU_REG_INTEN); 644 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); 645 } 646 647 static int exynos_get_temp(struct thermal_zone_device *tz, int *temp) 648 { 649 struct exynos_tmu_data *data = tz->devdata; 650 int value, ret = 0; 651 652 if (!data || !data->tmu_read) 653 return -EINVAL; 654 else if (!data->enabled) 655 /* 656 * Called too early, probably 657 * from thermal_zone_of_sensor_register(). 658 */ 659 return -EAGAIN; 660 661 mutex_lock(&data->lock); 662 clk_enable(data->clk); 663 664 value = data->tmu_read(data); 665 if (value < 0) 666 ret = value; 667 else 668 *temp = code_to_temp(data, value) * MCELSIUS; 669 670 clk_disable(data->clk); 671 mutex_unlock(&data->lock); 672 673 return ret; 674 } 675 676 #ifdef CONFIG_THERMAL_EMULATION 677 static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, 678 int temp) 679 { 680 if (temp) { 681 temp /= MCELSIUS; 682 683 val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); 684 val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); 685 if (data->soc == SOC_ARCH_EXYNOS7) { 686 val &= ~(EXYNOS7_EMUL_DATA_MASK << 687 EXYNOS7_EMUL_DATA_SHIFT); 688 val |= (temp_to_code(data, temp) << 689 EXYNOS7_EMUL_DATA_SHIFT) | 690 EXYNOS_EMUL_ENABLE; 691 } else { 692 val &= ~(EXYNOS_EMUL_DATA_MASK << 693 EXYNOS_EMUL_DATA_SHIFT); 694 val |= (temp_to_code(data, temp) << 695 EXYNOS_EMUL_DATA_SHIFT) | 696 EXYNOS_EMUL_ENABLE; 697 } 698 } else { 699 val &= ~EXYNOS_EMUL_ENABLE; 700 } 701 702 return val; 703 } 704 705 static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data, 706 int temp) 707 { 708 unsigned int val; 709 u32 emul_con; 710 711 if (data->soc == SOC_ARCH_EXYNOS5260) 712 emul_con = EXYNOS5260_EMUL_CON; 713 else if (data->soc == SOC_ARCH_EXYNOS5433) 714 emul_con = EXYNOS5433_TMU_EMUL_CON; 715 else if (data->soc == SOC_ARCH_EXYNOS7) 716 emul_con = EXYNOS7_TMU_REG_EMUL_CON; 717 else 718 emul_con = EXYNOS_EMUL_CON; 719 720 val = readl(data->base + emul_con); 721 val = get_emul_con_reg(data, val, temp); 722 writel(val, data->base + emul_con); 723 } 724 725 static int exynos_tmu_set_emulation(struct thermal_zone_device *tz, int temp) 726 { 727 struct exynos_tmu_data *data = tz->devdata; 728 int ret = -EINVAL; 729 730 if (data->soc == SOC_ARCH_EXYNOS4210) 731 goto out; 732 733 if (temp && temp < MCELSIUS) 734 goto out; 735 736 mutex_lock(&data->lock); 737 clk_enable(data->clk); 738 data->tmu_set_emulation(data, temp); 739 clk_disable(data->clk); 740 mutex_unlock(&data->lock); 741 return 0; 742 out: 743 return ret; 744 } 745 #else 746 #define exynos4412_tmu_set_emulation NULL 747 static int exynos_tmu_set_emulation(struct thermal_zone_device *tz, int temp) 748 { return -EINVAL; } 749 #endif /* CONFIG_THERMAL_EMULATION */ 750 751 static int exynos4210_tmu_read(struct exynos_tmu_data *data) 752 { 753 int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); 754 755 /* "temp_code" should range between 75 and 175 */ 756 return (ret < 75 || ret > 175) ? -ENODATA : ret; 757 } 758 759 static int exynos4412_tmu_read(struct exynos_tmu_data *data) 760 { 761 return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); 762 } 763 764 static int exynos7_tmu_read(struct exynos_tmu_data *data) 765 { 766 return readw(data->base + EXYNOS_TMU_REG_CURRENT_TEMP) & 767 EXYNOS7_TMU_TEMP_MASK; 768 } 769 770 static void exynos_tmu_work(struct work_struct *work) 771 { 772 struct exynos_tmu_data *data = container_of(work, 773 struct exynos_tmu_data, irq_work); 774 775 thermal_zone_device_update(data->tzd, THERMAL_EVENT_UNSPECIFIED); 776 777 mutex_lock(&data->lock); 778 clk_enable(data->clk); 779 780 /* TODO: take action based on particular interrupt */ 781 data->tmu_clear_irqs(data); 782 783 clk_disable(data->clk); 784 mutex_unlock(&data->lock); 785 enable_irq(data->irq); 786 } 787 788 static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data) 789 { 790 unsigned int val_irq; 791 u32 tmu_intstat, tmu_intclear; 792 793 if (data->soc == SOC_ARCH_EXYNOS5260) { 794 tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT; 795 tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR; 796 } else if (data->soc == SOC_ARCH_EXYNOS7) { 797 tmu_intstat = EXYNOS7_TMU_REG_INTPEND; 798 tmu_intclear = EXYNOS7_TMU_REG_INTPEND; 799 } else if (data->soc == SOC_ARCH_EXYNOS5433) { 800 tmu_intstat = EXYNOS5433_TMU_REG_INTPEND; 801 tmu_intclear = EXYNOS5433_TMU_REG_INTPEND; 802 } else { 803 tmu_intstat = EXYNOS_TMU_REG_INTSTAT; 804 tmu_intclear = EXYNOS_TMU_REG_INTCLEAR; 805 } 806 807 val_irq = readl(data->base + tmu_intstat); 808 /* 809 * Clear the interrupts. Please note that the documentation for 810 * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly 811 * states that INTCLEAR register has a different placing of bits 812 * responsible for FALL IRQs than INTSTAT register. Exynos5420 813 * and Exynos5440 documentation is correct (Exynos4210 doesn't 814 * support FALL IRQs at all). 815 */ 816 writel(val_irq, data->base + tmu_intclear); 817 } 818 819 static irqreturn_t exynos_tmu_irq(int irq, void *id) 820 { 821 struct exynos_tmu_data *data = id; 822 823 disable_irq_nosync(irq); 824 schedule_work(&data->irq_work); 825 826 return IRQ_HANDLED; 827 } 828 829 static const struct of_device_id exynos_tmu_match[] = { 830 { 831 .compatible = "samsung,exynos3250-tmu", 832 .data = (const void *)SOC_ARCH_EXYNOS3250, 833 }, { 834 .compatible = "samsung,exynos4210-tmu", 835 .data = (const void *)SOC_ARCH_EXYNOS4210, 836 }, { 837 .compatible = "samsung,exynos4412-tmu", 838 .data = (const void *)SOC_ARCH_EXYNOS4412, 839 }, { 840 .compatible = "samsung,exynos5250-tmu", 841 .data = (const void *)SOC_ARCH_EXYNOS5250, 842 }, { 843 .compatible = "samsung,exynos5260-tmu", 844 .data = (const void *)SOC_ARCH_EXYNOS5260, 845 }, { 846 .compatible = "samsung,exynos5420-tmu", 847 .data = (const void *)SOC_ARCH_EXYNOS5420, 848 }, { 849 .compatible = "samsung,exynos5420-tmu-ext-triminfo", 850 .data = (const void *)SOC_ARCH_EXYNOS5420_TRIMINFO, 851 }, { 852 .compatible = "samsung,exynos5433-tmu", 853 .data = (const void *)SOC_ARCH_EXYNOS5433, 854 }, { 855 .compatible = "samsung,exynos7-tmu", 856 .data = (const void *)SOC_ARCH_EXYNOS7, 857 }, 858 { }, 859 }; 860 MODULE_DEVICE_TABLE(of, exynos_tmu_match); 861 862 static int exynos_map_dt_data(struct platform_device *pdev) 863 { 864 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 865 struct resource res; 866 867 if (!data || !pdev->dev.of_node) 868 return -ENODEV; 869 870 data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl"); 871 if (data->id < 0) 872 data->id = 0; 873 874 data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); 875 if (data->irq <= 0) { 876 dev_err(&pdev->dev, "failed to get IRQ\n"); 877 return -ENODEV; 878 } 879 880 if (of_address_to_resource(pdev->dev.of_node, 0, &res)) { 881 dev_err(&pdev->dev, "failed to get Resource 0\n"); 882 return -ENODEV; 883 } 884 885 data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); 886 if (!data->base) { 887 dev_err(&pdev->dev, "Failed to ioremap memory\n"); 888 return -EADDRNOTAVAIL; 889 } 890 891 data->soc = (enum soc_type)of_device_get_match_data(&pdev->dev); 892 893 switch (data->soc) { 894 case SOC_ARCH_EXYNOS4210: 895 data->tmu_set_trip_temp = exynos4210_tmu_set_trip_temp; 896 data->tmu_set_trip_hyst = exynos4210_tmu_set_trip_hyst; 897 data->tmu_initialize = exynos4210_tmu_initialize; 898 data->tmu_control = exynos4210_tmu_control; 899 data->tmu_read = exynos4210_tmu_read; 900 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 901 data->ntrip = 4; 902 data->gain = 15; 903 data->reference_voltage = 7; 904 data->efuse_value = 55; 905 data->min_efuse_value = 40; 906 data->max_efuse_value = 100; 907 break; 908 case SOC_ARCH_EXYNOS3250: 909 case SOC_ARCH_EXYNOS4412: 910 case SOC_ARCH_EXYNOS5250: 911 case SOC_ARCH_EXYNOS5260: 912 case SOC_ARCH_EXYNOS5420: 913 case SOC_ARCH_EXYNOS5420_TRIMINFO: 914 data->tmu_set_trip_temp = exynos4412_tmu_set_trip_temp; 915 data->tmu_set_trip_hyst = exynos4412_tmu_set_trip_hyst; 916 data->tmu_initialize = exynos4412_tmu_initialize; 917 data->tmu_control = exynos4210_tmu_control; 918 data->tmu_read = exynos4412_tmu_read; 919 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 920 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 921 data->ntrip = 4; 922 data->gain = 8; 923 data->reference_voltage = 16; 924 data->efuse_value = 55; 925 if (data->soc != SOC_ARCH_EXYNOS5420 && 926 data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO) 927 data->min_efuse_value = 40; 928 else 929 data->min_efuse_value = 0; 930 data->max_efuse_value = 100; 931 break; 932 case SOC_ARCH_EXYNOS5433: 933 data->tmu_set_trip_temp = exynos5433_tmu_set_trip_temp; 934 data->tmu_set_trip_hyst = exynos5433_tmu_set_trip_hyst; 935 data->tmu_initialize = exynos5433_tmu_initialize; 936 data->tmu_control = exynos5433_tmu_control; 937 data->tmu_read = exynos4412_tmu_read; 938 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 939 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 940 data->ntrip = 8; 941 data->gain = 8; 942 if (res.start == EXYNOS5433_G3D_BASE) 943 data->reference_voltage = 23; 944 else 945 data->reference_voltage = 16; 946 data->efuse_value = 75; 947 data->min_efuse_value = 40; 948 data->max_efuse_value = 150; 949 break; 950 case SOC_ARCH_EXYNOS7: 951 data->tmu_set_trip_temp = exynos7_tmu_set_trip_temp; 952 data->tmu_set_trip_hyst = exynos7_tmu_set_trip_hyst; 953 data->tmu_initialize = exynos7_tmu_initialize; 954 data->tmu_control = exynos7_tmu_control; 955 data->tmu_read = exynos7_tmu_read; 956 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 957 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 958 data->ntrip = 8; 959 data->gain = 9; 960 data->reference_voltage = 17; 961 data->efuse_value = 75; 962 data->min_efuse_value = 15; 963 data->max_efuse_value = 100; 964 break; 965 default: 966 dev_err(&pdev->dev, "Platform not supported\n"); 967 return -EINVAL; 968 } 969 970 data->cal_type = TYPE_ONE_POINT_TRIMMING; 971 972 /* 973 * Check if the TMU shares some registers and then try to map the 974 * memory of common registers. 975 */ 976 if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO) 977 return 0; 978 979 if (of_address_to_resource(pdev->dev.of_node, 1, &res)) { 980 dev_err(&pdev->dev, "failed to get Resource 1\n"); 981 return -ENODEV; 982 } 983 984 data->base_second = devm_ioremap(&pdev->dev, res.start, 985 resource_size(&res)); 986 if (!data->base_second) { 987 dev_err(&pdev->dev, "Failed to ioremap memory\n"); 988 return -ENOMEM; 989 } 990 991 return 0; 992 } 993 994 static const struct thermal_zone_device_ops exynos_sensor_ops = { 995 .get_temp = exynos_get_temp, 996 .set_emul_temp = exynos_tmu_set_emulation, 997 }; 998 999 static int exynos_tmu_probe(struct platform_device *pdev) 1000 { 1001 struct exynos_tmu_data *data; 1002 int ret; 1003 1004 data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data), 1005 GFP_KERNEL); 1006 if (!data) 1007 return -ENOMEM; 1008 1009 platform_set_drvdata(pdev, data); 1010 mutex_init(&data->lock); 1011 1012 /* 1013 * Try enabling the regulator if found 1014 * TODO: Add regulator as an SOC feature, so that regulator enable 1015 * is a compulsory call. 1016 */ 1017 data->regulator = devm_regulator_get_optional(&pdev->dev, "vtmu"); 1018 if (!IS_ERR(data->regulator)) { 1019 ret = regulator_enable(data->regulator); 1020 if (ret) { 1021 dev_err(&pdev->dev, "failed to enable vtmu\n"); 1022 return ret; 1023 } 1024 } else { 1025 if (PTR_ERR(data->regulator) == -EPROBE_DEFER) 1026 return -EPROBE_DEFER; 1027 dev_info(&pdev->dev, "Regulator node (vtmu) not found\n"); 1028 } 1029 1030 ret = exynos_map_dt_data(pdev); 1031 if (ret) 1032 goto err_sensor; 1033 1034 INIT_WORK(&data->irq_work, exynos_tmu_work); 1035 1036 data->clk = devm_clk_get(&pdev->dev, "tmu_apbif"); 1037 if (IS_ERR(data->clk)) { 1038 dev_err(&pdev->dev, "Failed to get clock\n"); 1039 ret = PTR_ERR(data->clk); 1040 goto err_sensor; 1041 } 1042 1043 data->clk_sec = devm_clk_get(&pdev->dev, "tmu_triminfo_apbif"); 1044 if (IS_ERR(data->clk_sec)) { 1045 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) { 1046 dev_err(&pdev->dev, "Failed to get triminfo clock\n"); 1047 ret = PTR_ERR(data->clk_sec); 1048 goto err_sensor; 1049 } 1050 } else { 1051 ret = clk_prepare(data->clk_sec); 1052 if (ret) { 1053 dev_err(&pdev->dev, "Failed to get clock\n"); 1054 goto err_sensor; 1055 } 1056 } 1057 1058 ret = clk_prepare(data->clk); 1059 if (ret) { 1060 dev_err(&pdev->dev, "Failed to get clock\n"); 1061 goto err_clk_sec; 1062 } 1063 1064 switch (data->soc) { 1065 case SOC_ARCH_EXYNOS5433: 1066 case SOC_ARCH_EXYNOS7: 1067 data->sclk = devm_clk_get(&pdev->dev, "tmu_sclk"); 1068 if (IS_ERR(data->sclk)) { 1069 dev_err(&pdev->dev, "Failed to get sclk\n"); 1070 ret = PTR_ERR(data->sclk); 1071 goto err_clk; 1072 } else { 1073 ret = clk_prepare_enable(data->sclk); 1074 if (ret) { 1075 dev_err(&pdev->dev, "Failed to enable sclk\n"); 1076 goto err_clk; 1077 } 1078 } 1079 break; 1080 default: 1081 break; 1082 } 1083 1084 /* 1085 * data->tzd must be registered before calling exynos_tmu_initialize(), 1086 * requesting irq and calling exynos_tmu_control(). 1087 */ 1088 data->tzd = devm_thermal_of_zone_register(&pdev->dev, 0, data, 1089 &exynos_sensor_ops); 1090 if (IS_ERR(data->tzd)) { 1091 ret = PTR_ERR(data->tzd); 1092 if (ret != -EPROBE_DEFER) 1093 dev_err(&pdev->dev, "Failed to register sensor: %d\n", 1094 ret); 1095 goto err_sclk; 1096 } 1097 1098 ret = exynos_tmu_initialize(pdev); 1099 if (ret) { 1100 dev_err(&pdev->dev, "Failed to initialize TMU\n"); 1101 goto err_sclk; 1102 } 1103 1104 ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq, 1105 IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data); 1106 if (ret) { 1107 dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq); 1108 goto err_sclk; 1109 } 1110 1111 exynos_tmu_control(pdev, true); 1112 return 0; 1113 1114 err_sclk: 1115 clk_disable_unprepare(data->sclk); 1116 err_clk: 1117 clk_unprepare(data->clk); 1118 err_clk_sec: 1119 if (!IS_ERR(data->clk_sec)) 1120 clk_unprepare(data->clk_sec); 1121 err_sensor: 1122 if (!IS_ERR(data->regulator)) 1123 regulator_disable(data->regulator); 1124 1125 return ret; 1126 } 1127 1128 static int exynos_tmu_remove(struct platform_device *pdev) 1129 { 1130 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 1131 1132 exynos_tmu_control(pdev, false); 1133 1134 clk_disable_unprepare(data->sclk); 1135 clk_unprepare(data->clk); 1136 if (!IS_ERR(data->clk_sec)) 1137 clk_unprepare(data->clk_sec); 1138 1139 if (!IS_ERR(data->regulator)) 1140 regulator_disable(data->regulator); 1141 1142 return 0; 1143 } 1144 1145 #ifdef CONFIG_PM_SLEEP 1146 static int exynos_tmu_suspend(struct device *dev) 1147 { 1148 exynos_tmu_control(to_platform_device(dev), false); 1149 1150 return 0; 1151 } 1152 1153 static int exynos_tmu_resume(struct device *dev) 1154 { 1155 struct platform_device *pdev = to_platform_device(dev); 1156 1157 exynos_tmu_initialize(pdev); 1158 exynos_tmu_control(pdev, true); 1159 1160 return 0; 1161 } 1162 1163 static SIMPLE_DEV_PM_OPS(exynos_tmu_pm, 1164 exynos_tmu_suspend, exynos_tmu_resume); 1165 #define EXYNOS_TMU_PM (&exynos_tmu_pm) 1166 #else 1167 #define EXYNOS_TMU_PM NULL 1168 #endif 1169 1170 static struct platform_driver exynos_tmu_driver = { 1171 .driver = { 1172 .name = "exynos-tmu", 1173 .pm = EXYNOS_TMU_PM, 1174 .of_match_table = exynos_tmu_match, 1175 }, 1176 .probe = exynos_tmu_probe, 1177 .remove = exynos_tmu_remove, 1178 }; 1179 1180 module_platform_driver(exynos_tmu_driver); 1181 1182 MODULE_DESCRIPTION("Exynos TMU Driver"); 1183 MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); 1184 MODULE_LICENSE("GPL"); 1185 MODULE_ALIAS("platform:exynos-tmu"); 1186