linux/drivers/thermal/exynos_thermal.c
<<
>>
Prefs
   1/*
   2 * exynos_thermal.c - Samsung EXYNOS TMU (Thermal Management Unit)
   3 *
   4 *  Copyright (C) 2011 Samsung Electronics
   5 *  Donggeun Kim <dg77.kim@samsung.com>
   6 *  Amit Daniel Kachhap <amit.kachhap@linaro.org>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 *
  22 */
  23
  24#include <linux/module.h>
  25#include <linux/err.h>
  26#include <linux/kernel.h>
  27#include <linux/slab.h>
  28#include <linux/platform_device.h>
  29#include <linux/interrupt.h>
  30#include <linux/clk.h>
  31#include <linux/workqueue.h>
  32#include <linux/sysfs.h>
  33#include <linux/kobject.h>
  34#include <linux/io.h>
  35#include <linux/mutex.h>
  36#include <linux/platform_data/exynos_thermal.h>
  37#include <linux/thermal.h>
  38#include <linux/cpufreq.h>
  39#include <linux/cpu_cooling.h>
  40#include <linux/of.h>
  41
  42#include <plat/cpu.h>
  43
  44/* Exynos generic registers */
  45#define EXYNOS_TMU_REG_TRIMINFO         0x0
  46#define EXYNOS_TMU_REG_CONTROL          0x20
  47#define EXYNOS_TMU_REG_STATUS           0x28
  48#define EXYNOS_TMU_REG_CURRENT_TEMP     0x40
  49#define EXYNOS_TMU_REG_INTEN            0x70
  50#define EXYNOS_TMU_REG_INTSTAT          0x74
  51#define EXYNOS_TMU_REG_INTCLEAR         0x78
  52
  53#define EXYNOS_TMU_TRIM_TEMP_MASK       0xff
  54#define EXYNOS_TMU_GAIN_SHIFT           8
  55#define EXYNOS_TMU_REF_VOLTAGE_SHIFT    24
  56#define EXYNOS_TMU_CORE_ON              3
  57#define EXYNOS_TMU_CORE_OFF             2
  58#define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET      50
  59
  60/* Exynos4210 specific registers */
  61#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP       0x44
  62#define EXYNOS4210_TMU_REG_TRIG_LEVEL0  0x50
  63#define EXYNOS4210_TMU_REG_TRIG_LEVEL1  0x54
  64#define EXYNOS4210_TMU_REG_TRIG_LEVEL2  0x58
  65#define EXYNOS4210_TMU_REG_TRIG_LEVEL3  0x5C
  66#define EXYNOS4210_TMU_REG_PAST_TEMP0   0x60
  67#define EXYNOS4210_TMU_REG_PAST_TEMP1   0x64
  68#define EXYNOS4210_TMU_REG_PAST_TEMP2   0x68
  69#define EXYNOS4210_TMU_REG_PAST_TEMP3   0x6C
  70
  71#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK 0x1
  72#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK 0x10
  73#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK 0x100
  74#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK 0x1000
  75#define EXYNOS4210_TMU_INTCLEAR_VAL     0x1111
  76
  77/* Exynos5250 and Exynos4412 specific registers */
  78#define EXYNOS_TMU_TRIMINFO_CON 0x14
  79#define EXYNOS_THD_TEMP_RISE            0x50
  80#define EXYNOS_THD_TEMP_FALL            0x54
  81#define EXYNOS_EMUL_CON         0x80
  82
  83#define EXYNOS_TRIMINFO_RELOAD          0x1
  84#define EXYNOS_TMU_CLEAR_RISE_INT       0x111
  85#define EXYNOS_TMU_CLEAR_FALL_INT       (0x111 << 12)
  86#define EXYNOS_MUX_ADDR_VALUE           6
  87#define EXYNOS_MUX_ADDR_SHIFT           20
  88#define EXYNOS_TMU_TRIP_MODE_SHIFT      13
  89
  90#define EFUSE_MIN_VALUE 40
  91#define EFUSE_MAX_VALUE 100
  92
  93/* In-kernel thermal framework related macros & definations */
  94#define SENSOR_NAME_LEN 16
  95#define MAX_TRIP_COUNT  8
  96#define MAX_COOLING_DEVICE 4
  97#define MAX_THRESHOLD_LEVS 4
  98
  99#define ACTIVE_INTERVAL 500
 100#define IDLE_INTERVAL 10000
 101#define MCELSIUS        1000
 102
 103#ifdef CONFIG_EXYNOS_THERMAL_EMUL
 104#define EXYNOS_EMUL_TIME        0x57F0
 105#define EXYNOS_EMUL_TIME_SHIFT  16
 106#define EXYNOS_EMUL_DATA_SHIFT  8
 107#define EXYNOS_EMUL_DATA_MASK   0xFF
 108#define EXYNOS_EMUL_ENABLE      0x1
 109#endif /* CONFIG_EXYNOS_THERMAL_EMUL */
 110
 111/* CPU Zone information */
 112#define PANIC_ZONE      4
 113#define WARN_ZONE       3
 114#define MONITOR_ZONE    2
 115#define SAFE_ZONE       1
 116
 117#define GET_ZONE(trip) (trip + 2)
 118#define GET_TRIP(zone) (zone - 2)
 119
 120#define EXYNOS_ZONE_COUNT       3
 121
 122struct exynos_tmu_data {
 123        struct exynos_tmu_platform_data *pdata;
 124        struct resource *mem;
 125        void __iomem *base;
 126        int irq;
 127        enum soc_type soc;
 128        struct work_struct irq_work;
 129        struct mutex lock;
 130        struct clk *clk;
 131        u8 temp_error1, temp_error2;
 132};
 133
 134struct  thermal_trip_point_conf {
 135        int trip_val[MAX_TRIP_COUNT];
 136        int trip_count;
 137        u8 trigger_falling;
 138};
 139
 140struct  thermal_cooling_conf {
 141        struct freq_clip_table freq_data[MAX_TRIP_COUNT];
 142        int freq_clip_count;
 143};
 144
 145struct thermal_sensor_conf {
 146        char name[SENSOR_NAME_LEN];
 147        int (*read_temperature)(void *data);
 148        struct thermal_trip_point_conf trip_data;
 149        struct thermal_cooling_conf cooling_data;
 150        void *private_data;
 151};
 152
 153struct exynos_thermal_zone {
 154        enum thermal_device_mode mode;
 155        struct thermal_zone_device *therm_dev;
 156        struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
 157        unsigned int cool_dev_size;
 158        struct platform_device *exynos4_dev;
 159        struct thermal_sensor_conf *sensor_conf;
 160        bool bind;
 161};
 162
 163static struct exynos_thermal_zone *th_zone;
 164static void exynos_unregister_thermal(void);
 165static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
 166
 167/* Get mode callback functions for thermal zone */
 168static int exynos_get_mode(struct thermal_zone_device *thermal,
 169                        enum thermal_device_mode *mode)
 170{
 171        if (th_zone)
 172                *mode = th_zone->mode;
 173        return 0;
 174}
 175
 176/* Set mode callback functions for thermal zone */
 177static int exynos_set_mode(struct thermal_zone_device *thermal,
 178                        enum thermal_device_mode mode)
 179{
 180        if (!th_zone->therm_dev) {
 181                pr_notice("thermal zone not registered\n");
 182                return 0;
 183        }
 184
 185        mutex_lock(&th_zone->therm_dev->lock);
 186
 187        if (mode == THERMAL_DEVICE_ENABLED &&
 188                !th_zone->sensor_conf->trip_data.trigger_falling)
 189                th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
 190        else
 191                th_zone->therm_dev->polling_delay = 0;
 192
 193        mutex_unlock(&th_zone->therm_dev->lock);
 194
 195        th_zone->mode = mode;
 196        thermal_zone_device_update(th_zone->therm_dev);
 197        pr_info("thermal polling set for duration=%d msec\n",
 198                                th_zone->therm_dev->polling_delay);
 199        return 0;
 200}
 201
 202
 203/* Get trip type callback functions for thermal zone */
 204static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
 205                                 enum thermal_trip_type *type)
 206{
 207        switch (GET_ZONE(trip)) {
 208        case MONITOR_ZONE:
 209        case WARN_ZONE:
 210                *type = THERMAL_TRIP_ACTIVE;
 211                break;
 212        case PANIC_ZONE:
 213                *type = THERMAL_TRIP_CRITICAL;
 214                break;
 215        default:
 216                return -EINVAL;
 217        }
 218        return 0;
 219}
 220
 221/* Get trip temperature callback functions for thermal zone */
 222static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
 223                                unsigned long *temp)
 224{
 225        if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
 226                return -EINVAL;
 227
 228        *temp = th_zone->sensor_conf->trip_data.trip_val[trip];
 229        /* convert the temperature into millicelsius */
 230        *temp = *temp * MCELSIUS;
 231
 232        return 0;
 233}
 234
 235/* Get critical temperature callback functions for thermal zone */
 236static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
 237                                unsigned long *temp)
 238{
 239        int ret;
 240        /* Panic zone */
 241        ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
 242        return ret;
 243}
 244
 245static int exynos_get_frequency_level(unsigned int cpu, unsigned int freq)
 246{
 247        int i = 0, ret = -EINVAL;
 248        struct cpufreq_frequency_table *table = NULL;
 249#ifdef CONFIG_CPU_FREQ
 250        table = cpufreq_frequency_get_table(cpu);
 251#endif
 252        if (!table)
 253                return ret;
 254
 255        while (table[i].frequency != CPUFREQ_TABLE_END) {
 256                if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
 257                        continue;
 258                if (table[i].frequency == freq)
 259                        return i;
 260                i++;
 261        }
 262        return ret;
 263}
 264
 265/* Bind callback functions for thermal zone */
 266static int exynos_bind(struct thermal_zone_device *thermal,
 267                        struct thermal_cooling_device *cdev)
 268{
 269        int ret = 0, i, tab_size, level;
 270        struct freq_clip_table *tab_ptr, *clip_data;
 271        struct thermal_sensor_conf *data = th_zone->sensor_conf;
 272
 273        tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
 274        tab_size = data->cooling_data.freq_clip_count;
 275
 276        if (tab_ptr == NULL || tab_size == 0)
 277                return -EINVAL;
 278
 279        /* find the cooling device registered*/
 280        for (i = 0; i < th_zone->cool_dev_size; i++)
 281                if (cdev == th_zone->cool_dev[i])
 282                        break;
 283
 284        /* No matching cooling device */
 285        if (i == th_zone->cool_dev_size)
 286                return 0;
 287
 288        /* Bind the thermal zone to the cpufreq cooling device */
 289        for (i = 0; i < tab_size; i++) {
 290                clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
 291                level = exynos_get_frequency_level(0, clip_data->freq_clip_max);
 292                if (level < 0)
 293                        return 0;
 294                switch (GET_ZONE(i)) {
 295                case MONITOR_ZONE:
 296                case WARN_ZONE:
 297                        if (thermal_zone_bind_cooling_device(thermal, i, cdev,
 298                                                                level, 0)) {
 299                                pr_err("error binding cdev inst %d\n", i);
 300                                ret = -EINVAL;
 301                        }
 302                        th_zone->bind = true;
 303                        break;
 304                default:
 305                        ret = -EINVAL;
 306                }
 307        }
 308
 309        return ret;
 310}
 311
 312/* Unbind callback functions for thermal zone */
 313static int exynos_unbind(struct thermal_zone_device *thermal,
 314                        struct thermal_cooling_device *cdev)
 315{
 316        int ret = 0, i, tab_size;
 317        struct thermal_sensor_conf *data = th_zone->sensor_conf;
 318
 319        if (th_zone->bind == false)
 320                return 0;
 321
 322        tab_size = data->cooling_data.freq_clip_count;
 323
 324        if (tab_size == 0)
 325                return -EINVAL;
 326
 327        /* find the cooling device registered*/
 328        for (i = 0; i < th_zone->cool_dev_size; i++)
 329                if (cdev == th_zone->cool_dev[i])
 330                        break;
 331
 332        /* No matching cooling device */
 333        if (i == th_zone->cool_dev_size)
 334                return 0;
 335
 336        /* Bind the thermal zone to the cpufreq cooling device */
 337        for (i = 0; i < tab_size; i++) {
 338                switch (GET_ZONE(i)) {
 339                case MONITOR_ZONE:
 340                case WARN_ZONE:
 341                        if (thermal_zone_unbind_cooling_device(thermal, i,
 342                                                                cdev)) {
 343                                pr_err("error unbinding cdev inst=%d\n", i);
 344                                ret = -EINVAL;
 345                        }
 346                        th_zone->bind = false;
 347                        break;
 348                default:
 349                        ret = -EINVAL;
 350                }
 351        }
 352        return ret;
 353}
 354
 355/* Get temperature callback functions for thermal zone */
 356static int exynos_get_temp(struct thermal_zone_device *thermal,
 357                        unsigned long *temp)
 358{
 359        void *data;
 360
 361        if (!th_zone->sensor_conf) {
 362                pr_info("Temperature sensor not initialised\n");
 363                return -EINVAL;
 364        }
 365        data = th_zone->sensor_conf->private_data;
 366        *temp = th_zone->sensor_conf->read_temperature(data);
 367        /* convert the temperature into millicelsius */
 368        *temp = *temp * MCELSIUS;
 369        return 0;
 370}
 371
 372/* Get the temperature trend */
 373static int exynos_get_trend(struct thermal_zone_device *thermal,
 374                        int trip, enum thermal_trend *trend)
 375{
 376        int ret;
 377        unsigned long trip_temp;
 378
 379        ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
 380        if (ret < 0)
 381                return ret;
 382
 383        if (thermal->temperature >= trip_temp)
 384                *trend = THERMAL_TREND_RAISE_FULL;
 385        else
 386                *trend = THERMAL_TREND_DROP_FULL;
 387
 388        return 0;
 389}
 390/* Operation callback functions for thermal zone */
 391static struct thermal_zone_device_ops const exynos_dev_ops = {
 392        .bind = exynos_bind,
 393        .unbind = exynos_unbind,
 394        .get_temp = exynos_get_temp,
 395        .get_trend = exynos_get_trend,
 396        .get_mode = exynos_get_mode,
 397        .set_mode = exynos_set_mode,
 398        .get_trip_type = exynos_get_trip_type,
 399        .get_trip_temp = exynos_get_trip_temp,
 400        .get_crit_temp = exynos_get_crit_temp,
 401};
 402
 403/*
 404 * This function may be called from interrupt based temperature sensor
 405 * when threshold is changed.
 406 */
 407static void exynos_report_trigger(void)
 408{
 409        unsigned int i;
 410        char data[10];
 411        char *envp[] = { data, NULL };
 412
 413        if (!th_zone || !th_zone->therm_dev)
 414                return;
 415        if (th_zone->bind == false) {
 416                for (i = 0; i < th_zone->cool_dev_size; i++) {
 417                        if (!th_zone->cool_dev[i])
 418                                continue;
 419                        exynos_bind(th_zone->therm_dev,
 420                                        th_zone->cool_dev[i]);
 421                }
 422        }
 423
 424        thermal_zone_device_update(th_zone->therm_dev);
 425
 426        mutex_lock(&th_zone->therm_dev->lock);
 427        /* Find the level for which trip happened */
 428        for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
 429                if (th_zone->therm_dev->last_temperature <
 430                        th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
 431                        break;
 432        }
 433
 434        if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
 435                !th_zone->sensor_conf->trip_data.trigger_falling) {
 436                if (i > 0)
 437                        th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
 438                else
 439                        th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
 440        }
 441
 442        snprintf(data, sizeof(data), "%u", i);
 443        kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
 444        mutex_unlock(&th_zone->therm_dev->lock);
 445}
 446
 447/* Register with the in-kernel thermal management */
 448static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
 449{
 450        int ret;
 451        struct cpumask mask_val;
 452
 453        if (!sensor_conf || !sensor_conf->read_temperature) {
 454                pr_err("Temperature sensor not initialised\n");
 455                return -EINVAL;
 456        }
 457
 458        th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
 459        if (!th_zone)
 460                return -ENOMEM;
 461
 462        th_zone->sensor_conf = sensor_conf;
 463        cpumask_set_cpu(0, &mask_val);
 464        th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
 465        if (IS_ERR(th_zone->cool_dev[0])) {
 466                pr_err("Failed to register cpufreq cooling device\n");
 467                ret = -EINVAL;
 468                goto err_unregister;
 469        }
 470        th_zone->cool_dev_size++;
 471
 472        th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
 473                        EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
 474                        sensor_conf->trip_data.trigger_falling ?
 475                        0 : IDLE_INTERVAL);
 476
 477        if (IS_ERR(th_zone->therm_dev)) {
 478                pr_err("Failed to register thermal zone device\n");
 479                ret = PTR_ERR(th_zone->therm_dev);
 480                goto err_unregister;
 481        }
 482        th_zone->mode = THERMAL_DEVICE_ENABLED;
 483
 484        pr_info("Exynos: Kernel Thermal management registered\n");
 485
 486        return 0;
 487
 488err_unregister:
 489        exynos_unregister_thermal();
 490        return ret;
 491}
 492
 493/* Un-Register with the in-kernel thermal management */
 494static void exynos_unregister_thermal(void)
 495{
 496        int i;
 497
 498        if (!th_zone)
 499                return;
 500
 501        if (th_zone->therm_dev)
 502                thermal_zone_device_unregister(th_zone->therm_dev);
 503
 504        for (i = 0; i < th_zone->cool_dev_size; i++) {
 505                if (th_zone->cool_dev[i])
 506                        cpufreq_cooling_unregister(th_zone->cool_dev[i]);
 507        }
 508
 509        kfree(th_zone);
 510        pr_info("Exynos: Kernel Thermal management unregistered\n");
 511}
 512
 513/*
 514 * TMU treats temperature as a mapped temperature code.
 515 * The temperature is converted differently depending on the calibration type.
 516 */
 517static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
 518{
 519        struct exynos_tmu_platform_data *pdata = data->pdata;
 520        int temp_code;
 521
 522        if (data->soc == SOC_ARCH_EXYNOS4210)
 523                /* temp should range between 25 and 125 */
 524                if (temp < 25 || temp > 125) {
 525                        temp_code = -EINVAL;
 526                        goto out;
 527                }
 528
 529        switch (pdata->cal_type) {
 530        case TYPE_TWO_POINT_TRIMMING:
 531                temp_code = (temp - 25) *
 532                    (data->temp_error2 - data->temp_error1) /
 533                    (85 - 25) + data->temp_error1;
 534                break;
 535        case TYPE_ONE_POINT_TRIMMING:
 536                temp_code = temp + data->temp_error1 - 25;
 537                break;
 538        default:
 539                temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
 540                break;
 541        }
 542out:
 543        return temp_code;
 544}
 545
 546/*
 547 * Calculate a temperature value from a temperature code.
 548 * The unit of the temperature is degree Celsius.
 549 */
 550static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
 551{
 552        struct exynos_tmu_platform_data *pdata = data->pdata;
 553        int temp;
 554
 555        if (data->soc == SOC_ARCH_EXYNOS4210)
 556                /* temp_code should range between 75 and 175 */
 557                if (temp_code < 75 || temp_code > 175) {
 558                        temp = -ENODATA;
 559                        goto out;
 560                }
 561
 562        switch (pdata->cal_type) {
 563        case TYPE_TWO_POINT_TRIMMING:
 564                temp = (temp_code - data->temp_error1) * (85 - 25) /
 565                    (data->temp_error2 - data->temp_error1) + 25;
 566                break;
 567        case TYPE_ONE_POINT_TRIMMING:
 568                temp = temp_code - data->temp_error1 + 25;
 569                break;
 570        default:
 571                temp = temp_code - EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
 572                break;
 573        }
 574out:
 575        return temp;
 576}
 577
 578static int exynos_tmu_initialize(struct platform_device *pdev)
 579{
 580        struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 581        struct exynos_tmu_platform_data *pdata = data->pdata;
 582        unsigned int status, trim_info;
 583        unsigned int rising_threshold = 0, falling_threshold = 0;
 584        int ret = 0, threshold_code, i, trigger_levs = 0;
 585
 586        mutex_lock(&data->lock);
 587        clk_enable(data->clk);
 588
 589        status = readb(data->base + EXYNOS_TMU_REG_STATUS);
 590        if (!status) {
 591                ret = -EBUSY;
 592                goto out;
 593        }
 594
 595        if (data->soc == SOC_ARCH_EXYNOS) {
 596                __raw_writel(EXYNOS_TRIMINFO_RELOAD,
 597                                data->base + EXYNOS_TMU_TRIMINFO_CON);
 598        }
 599        /* Save trimming info in order to perform calibration */
 600        trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
 601        data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
 602        data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
 603
 604        if ((EFUSE_MIN_VALUE > data->temp_error1) ||
 605                        (data->temp_error1 > EFUSE_MAX_VALUE) ||
 606                        (data->temp_error2 != 0))
 607                data->temp_error1 = pdata->efuse_value;
 608
 609        /* Count trigger levels to be enabled */
 610        for (i = 0; i < MAX_THRESHOLD_LEVS; i++)
 611                if (pdata->trigger_levels[i])
 612                        trigger_levs++;
 613
 614        if (data->soc == SOC_ARCH_EXYNOS4210) {
 615                /* Write temperature code for threshold */
 616                threshold_code = temp_to_code(data, pdata->threshold);
 617                if (threshold_code < 0) {
 618                        ret = threshold_code;
 619                        goto out;
 620                }
 621                writeb(threshold_code,
 622                        data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
 623                for (i = 0; i < trigger_levs; i++)
 624                        writeb(pdata->trigger_levels[i],
 625                        data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
 626
 627                writel(EXYNOS4210_TMU_INTCLEAR_VAL,
 628                        data->base + EXYNOS_TMU_REG_INTCLEAR);
 629        } else if (data->soc == SOC_ARCH_EXYNOS) {
 630                /* Write temperature code for rising and falling threshold */
 631                for (i = 0; i < trigger_levs; i++) {
 632                        threshold_code = temp_to_code(data,
 633                                                pdata->trigger_levels[i]);
 634                        if (threshold_code < 0) {
 635                                ret = threshold_code;
 636                                goto out;
 637                        }
 638                        rising_threshold |= threshold_code << 8 * i;
 639                        if (pdata->threshold_falling) {
 640                                threshold_code = temp_to_code(data,
 641                                                pdata->trigger_levels[i] -
 642                                                pdata->threshold_falling);
 643                                if (threshold_code > 0)
 644                                        falling_threshold |=
 645                                                threshold_code << 8 * i;
 646                        }
 647                }
 648
 649                writel(rising_threshold,
 650                                data->base + EXYNOS_THD_TEMP_RISE);
 651                writel(falling_threshold,
 652                                data->base + EXYNOS_THD_TEMP_FALL);
 653
 654                writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT,
 655                                data->base + EXYNOS_TMU_REG_INTCLEAR);
 656        }
 657out:
 658        clk_disable(data->clk);
 659        mutex_unlock(&data->lock);
 660
 661        return ret;
 662}
 663
 664static void exynos_tmu_control(struct platform_device *pdev, bool on)
 665{
 666        struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 667        struct exynos_tmu_platform_data *pdata = data->pdata;
 668        unsigned int con, interrupt_en;
 669
 670        mutex_lock(&data->lock);
 671        clk_enable(data->clk);
 672
 673        con = pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT |
 674                pdata->gain << EXYNOS_TMU_GAIN_SHIFT;
 675
 676        if (data->soc == SOC_ARCH_EXYNOS) {
 677                con |= pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT;
 678                con |= (EXYNOS_MUX_ADDR_VALUE << EXYNOS_MUX_ADDR_SHIFT);
 679        }
 680
 681        if (on) {
 682                con |= EXYNOS_TMU_CORE_ON;
 683                interrupt_en = pdata->trigger_level3_en << 12 |
 684                        pdata->trigger_level2_en << 8 |
 685                        pdata->trigger_level1_en << 4 |
 686                        pdata->trigger_level0_en;
 687                if (pdata->threshold_falling)
 688                        interrupt_en |= interrupt_en << 16;
 689        } else {
 690                con |= EXYNOS_TMU_CORE_OFF;
 691                interrupt_en = 0; /* Disable all interrupts */
 692        }
 693        writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
 694        writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
 695
 696        clk_disable(data->clk);
 697        mutex_unlock(&data->lock);
 698}
 699
 700static int exynos_tmu_read(struct exynos_tmu_data *data)
 701{
 702        u8 temp_code;
 703        int temp;
 704
 705        mutex_lock(&data->lock);
 706        clk_enable(data->clk);
 707
 708        temp_code = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
 709        temp = code_to_temp(data, temp_code);
 710
 711        clk_disable(data->clk);
 712        mutex_unlock(&data->lock);
 713
 714        return temp;
 715}
 716
 717static void exynos_tmu_work(struct work_struct *work)
 718{
 719        struct exynos_tmu_data *data = container_of(work,
 720                        struct exynos_tmu_data, irq_work);
 721
 722        exynos_report_trigger();
 723        mutex_lock(&data->lock);
 724        clk_enable(data->clk);
 725        if (data->soc == SOC_ARCH_EXYNOS)
 726                writel(EXYNOS_TMU_CLEAR_RISE_INT |
 727                                EXYNOS_TMU_CLEAR_FALL_INT,
 728                                data->base + EXYNOS_TMU_REG_INTCLEAR);
 729        else
 730                writel(EXYNOS4210_TMU_INTCLEAR_VAL,
 731                                data->base + EXYNOS_TMU_REG_INTCLEAR);
 732        clk_disable(data->clk);
 733        mutex_unlock(&data->lock);
 734
 735        enable_irq(data->irq);
 736}
 737
 738static irqreturn_t exynos_tmu_irq(int irq, void *id)
 739{
 740        struct exynos_tmu_data *data = id;
 741
 742        disable_irq_nosync(irq);
 743        schedule_work(&data->irq_work);
 744
 745        return IRQ_HANDLED;
 746}
 747static struct thermal_sensor_conf exynos_sensor_conf = {
 748        .name                   = "exynos-therm",
 749        .read_temperature       = (int (*)(void *))exynos_tmu_read,
 750};
 751
 752#if defined(CONFIG_CPU_EXYNOS4210)
 753static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
 754        .threshold = 80,
 755        .trigger_levels[0] = 5,
 756        .trigger_levels[1] = 20,
 757        .trigger_levels[2] = 30,
 758        .trigger_level0_en = 1,
 759        .trigger_level1_en = 1,
 760        .trigger_level2_en = 1,
 761        .trigger_level3_en = 0,
 762        .gain = 15,
 763        .reference_voltage = 7,
 764        .cal_type = TYPE_ONE_POINT_TRIMMING,
 765        .freq_tab[0] = {
 766                .freq_clip_max = 800 * 1000,
 767                .temp_level = 85,
 768        },
 769        .freq_tab[1] = {
 770                .freq_clip_max = 200 * 1000,
 771                .temp_level = 100,
 772        },
 773        .freq_tab_count = 2,
 774        .type = SOC_ARCH_EXYNOS4210,
 775};
 776#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
 777#else
 778#define EXYNOS4210_TMU_DRV_DATA (NULL)
 779#endif
 780
 781#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
 782static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
 783        .threshold_falling = 10,
 784        .trigger_levels[0] = 85,
 785        .trigger_levels[1] = 103,
 786        .trigger_levels[2] = 110,
 787        .trigger_level0_en = 1,
 788        .trigger_level1_en = 1,
 789        .trigger_level2_en = 1,
 790        .trigger_level3_en = 0,
 791        .gain = 8,
 792        .reference_voltage = 16,
 793        .noise_cancel_mode = 4,
 794        .cal_type = TYPE_ONE_POINT_TRIMMING,
 795        .efuse_value = 55,
 796        .freq_tab[0] = {
 797                .freq_clip_max = 800 * 1000,
 798                .temp_level = 85,
 799        },
 800        .freq_tab[1] = {
 801                .freq_clip_max = 200 * 1000,
 802                .temp_level = 103,
 803        },
 804        .freq_tab_count = 2,
 805        .type = SOC_ARCH_EXYNOS,
 806};
 807#define EXYNOS_TMU_DRV_DATA (&exynos_default_tmu_data)
 808#else
 809#define EXYNOS_TMU_DRV_DATA (NULL)
 810#endif
 811
 812#ifdef CONFIG_OF
 813static const struct of_device_id exynos_tmu_match[] = {
 814        {
 815                .compatible = "samsung,exynos4210-tmu",
 816                .data = (void *)EXYNOS4210_TMU_DRV_DATA,
 817        },
 818        {
 819                .compatible = "samsung,exynos5250-tmu",
 820                .data = (void *)EXYNOS_TMU_DRV_DATA,
 821        },
 822        {},
 823};
 824MODULE_DEVICE_TABLE(of, exynos_tmu_match);
 825#endif
 826
 827static struct platform_device_id exynos_tmu_driver_ids[] = {
 828        {
 829                .name           = "exynos4210-tmu",
 830                .driver_data    = (kernel_ulong_t)EXYNOS4210_TMU_DRV_DATA,
 831        },
 832        {
 833                .name           = "exynos5250-tmu",
 834                .driver_data    = (kernel_ulong_t)EXYNOS_TMU_DRV_DATA,
 835        },
 836        { },
 837};
 838MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids);
 839
 840static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
 841                        struct platform_device *pdev)
 842{
 843#ifdef CONFIG_OF
 844        if (pdev->dev.of_node) {
 845                const struct of_device_id *match;
 846                match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
 847                if (!match)
 848                        return NULL;
 849                return (struct exynos_tmu_platform_data *) match->data;
 850        }
 851#endif
 852        return (struct exynos_tmu_platform_data *)
 853                        platform_get_device_id(pdev)->driver_data;
 854}
 855
 856#ifdef CONFIG_EXYNOS_THERMAL_EMUL
 857static ssize_t exynos_tmu_emulation_show(struct device *dev,
 858                                         struct device_attribute *attr,
 859                                         char *buf)
 860{
 861        struct platform_device *pdev = container_of(dev,
 862                                        struct platform_device, dev);
 863        struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 864        unsigned int reg;
 865        u8 temp_code;
 866        int temp = 0;
 867
 868        if (data->soc == SOC_ARCH_EXYNOS4210)
 869                goto out;
 870
 871        mutex_lock(&data->lock);
 872        clk_enable(data->clk);
 873        reg = readl(data->base + EXYNOS_EMUL_CON);
 874        clk_disable(data->clk);
 875        mutex_unlock(&data->lock);
 876
 877        if (reg & EXYNOS_EMUL_ENABLE) {
 878                reg >>= EXYNOS_EMUL_DATA_SHIFT;
 879                temp_code = reg & EXYNOS_EMUL_DATA_MASK;
 880                temp = code_to_temp(data, temp_code);
 881        }
 882out:
 883        return sprintf(buf, "%d\n", temp * MCELSIUS);
 884}
 885
 886static ssize_t exynos_tmu_emulation_store(struct device *dev,
 887                                        struct device_attribute *attr,
 888                                        const char *buf, size_t count)
 889{
 890        struct platform_device *pdev = container_of(dev,
 891                                        struct platform_device, dev);
 892        struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 893        unsigned int reg;
 894        int temp;
 895
 896        if (data->soc == SOC_ARCH_EXYNOS4210)
 897                goto out;
 898
 899        if (!sscanf(buf, "%d\n", &temp) || temp < 0)
 900                return -EINVAL;
 901
 902        mutex_lock(&data->lock);
 903        clk_enable(data->clk);
 904
 905        reg = readl(data->base + EXYNOS_EMUL_CON);
 906
 907        if (temp) {
 908                /* Both CELSIUS and MCELSIUS type are available for input */
 909                if (temp > MCELSIUS)
 910                        temp /= MCELSIUS;
 911
 912                reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
 913                        (temp_to_code(data, (temp / MCELSIUS))
 914                         << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE;
 915        } else {
 916                reg &= ~EXYNOS_EMUL_ENABLE;
 917        }
 918
 919        writel(reg, data->base + EXYNOS_EMUL_CON);
 920
 921        clk_disable(data->clk);
 922        mutex_unlock(&data->lock);
 923
 924out:
 925        return count;
 926}
 927
 928static DEVICE_ATTR(emulation, 0644, exynos_tmu_emulation_show,
 929                                        exynos_tmu_emulation_store);
 930static int create_emulation_sysfs(struct device *dev)
 931{
 932        return device_create_file(dev, &dev_attr_emulation);
 933}
 934static void remove_emulation_sysfs(struct device *dev)
 935{
 936        device_remove_file(dev, &dev_attr_emulation);
 937}
 938#else
 939static inline int create_emulation_sysfs(struct device *dev) { return 0; }
 940static inline void remove_emulation_sysfs(struct device *dev) {}
 941#endif
 942
 943static int exynos_tmu_probe(struct platform_device *pdev)
 944{
 945        struct exynos_tmu_data *data;
 946        struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
 947        int ret, i;
 948
 949        if (!pdata)
 950                pdata = exynos_get_driver_data(pdev);
 951
 952        if (!pdata) {
 953                dev_err(&pdev->dev, "No platform init data supplied.\n");
 954                return -ENODEV;
 955        }
 956        data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
 957                                        GFP_KERNEL);
 958        if (!data) {
 959                dev_err(&pdev->dev, "Failed to allocate driver structure\n");
 960                return -ENOMEM;
 961        }
 962
 963        data->irq = platform_get_irq(pdev, 0);
 964        if (data->irq < 0) {
 965                dev_err(&pdev->dev, "Failed to get platform irq\n");
 966                return data->irq;
 967        }
 968
 969        INIT_WORK(&data->irq_work, exynos_tmu_work);
 970
 971        data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 972        if (!data->mem) {
 973                dev_err(&pdev->dev, "Failed to get platform resource\n");
 974                return -ENOENT;
 975        }
 976
 977        data->base = devm_ioremap_resource(&pdev->dev, data->mem);
 978        if (IS_ERR(data->base))
 979                return PTR_ERR(data->base);
 980
 981        ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
 982                IRQF_TRIGGER_RISING, "exynos-tmu", data);
 983        if (ret) {
 984                dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
 985                return ret;
 986        }
 987
 988        data->clk = clk_get(NULL, "tmu_apbif");
 989        if (IS_ERR(data->clk)) {
 990                dev_err(&pdev->dev, "Failed to get clock\n");
 991                return  PTR_ERR(data->clk);
 992        }
 993
 994        if (pdata->type == SOC_ARCH_EXYNOS ||
 995                                pdata->type == SOC_ARCH_EXYNOS4210)
 996                data->soc = pdata->type;
 997        else {
 998                ret = -EINVAL;
 999                dev_err(&pdev->dev, "Platform not supported\n");
1000                goto err_clk;
1001        }
1002
1003        data->pdata = pdata;
1004        platform_set_drvdata(pdev, data);
1005        mutex_init(&data->lock);
1006
1007        ret = exynos_tmu_initialize(pdev);
1008        if (ret) {
1009                dev_err(&pdev->dev, "Failed to initialize TMU\n");
1010                goto err_clk;
1011        }
1012
1013        exynos_tmu_control(pdev, true);
1014
1015        /* Register the sensor with thermal management interface */
1016        (&exynos_sensor_conf)->private_data = data;
1017        exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
1018                        pdata->trigger_level1_en + pdata->trigger_level2_en +
1019                        pdata->trigger_level3_en;
1020
1021        for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
1022                exynos_sensor_conf.trip_data.trip_val[i] =
1023                        pdata->threshold + pdata->trigger_levels[i];
1024
1025        exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;
1026
1027        exynos_sensor_conf.cooling_data.freq_clip_count =
1028                                                pdata->freq_tab_count;
1029        for (i = 0; i < pdata->freq_tab_count; i++) {
1030                exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
1031                                        pdata->freq_tab[i].freq_clip_max;
1032                exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
1033                                        pdata->freq_tab[i].temp_level;
1034        }
1035
1036        ret = exynos_register_thermal(&exynos_sensor_conf);
1037        if (ret) {
1038                dev_err(&pdev->dev, "Failed to register thermal interface\n");
1039                goto err_clk;
1040        }
1041
1042        ret = create_emulation_sysfs(&pdev->dev);
1043        if (ret)
1044                dev_err(&pdev->dev, "Failed to create emulation mode sysfs node\n");
1045
1046        return 0;
1047err_clk:
1048        platform_set_drvdata(pdev, NULL);
1049        clk_put(data->clk);
1050        return ret;
1051}
1052
1053static int exynos_tmu_remove(struct platform_device *pdev)
1054{
1055        struct exynos_tmu_data *data = platform_get_drvdata(pdev);
1056
1057        remove_emulation_sysfs(&pdev->dev);
1058
1059        exynos_tmu_control(pdev, false);
1060
1061        exynos_unregister_thermal();
1062
1063        clk_put(data->clk);
1064
1065        platform_set_drvdata(pdev, NULL);
1066
1067        return 0;
1068}
1069
1070#ifdef CONFIG_PM_SLEEP
1071static int exynos_tmu_suspend(struct device *dev)
1072{
1073        exynos_tmu_control(to_platform_device(dev), false);
1074
1075        return 0;
1076}
1077
1078static int exynos_tmu_resume(struct device *dev)
1079{
1080        struct platform_device *pdev = to_platform_device(dev);
1081
1082        exynos_tmu_initialize(pdev);
1083        exynos_tmu_control(pdev, true);
1084
1085        return 0;
1086}
1087
1088static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
1089                         exynos_tmu_suspend, exynos_tmu_resume);
1090#define EXYNOS_TMU_PM   (&exynos_tmu_pm)
1091#else
1092#define EXYNOS_TMU_PM   NULL
1093#endif
1094
1095static struct platform_driver exynos_tmu_driver = {
1096        .driver = {
1097                .name   = "exynos-tmu",
1098                .owner  = THIS_MODULE,
1099                .pm     = EXYNOS_TMU_PM,
1100                .of_match_table = of_match_ptr(exynos_tmu_match),
1101        },
1102        .probe = exynos_tmu_probe,
1103        .remove = exynos_tmu_remove,
1104        .id_table = exynos_tmu_driver_ids,
1105};
1106
1107module_platform_driver(exynos_tmu_driver);
1108
1109MODULE_DESCRIPTION("EXYNOS TMU Driver");
1110MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
1111MODULE_LICENSE("GPL");
1112MODULE_ALIAS("platform:exynos-tmu");
1113
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.