exynos_tmu.c (37f9034f99c3c1ba9087357fbbc2b79fc1a30e72) exynos_tmu.c (b79985ca74b25926cb2d88b60805092c5456bf43)
1/*
2 * exynos_tmu.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

--- 40 unchanged lines hidden (view full) ---

49 * @clk: pointer to the clock structure.
50 * @clk_sec: pointer to the clock structure for accessing the base_second.
51 * @temp_error1: fused value of the first point trim.
52 * @temp_error2: fused value of the second point trim.
53 * @regulator: pointer to the TMU regulator structure.
54 * @reg_conf: pointer to structure to register with core thermal.
55 * @tmu_initialize: SoC specific TMU initialization method
56 * @tmu_control: SoC specific TMU control method
1/*
2 * exynos_tmu.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

--- 40 unchanged lines hidden (view full) ---

49 * @clk: pointer to the clock structure.
50 * @clk_sec: pointer to the clock structure for accessing the base_second.
51 * @temp_error1: fused value of the first point trim.
52 * @temp_error2: fused value of the second point trim.
53 * @regulator: pointer to the TMU regulator structure.
54 * @reg_conf: pointer to structure to register with core thermal.
55 * @tmu_initialize: SoC specific TMU initialization method
56 * @tmu_control: SoC specific TMU control method
57 * @tmu_read: SoC specific TMU temperature read method
57 */
58struct exynos_tmu_data {
59 int id;
60 struct exynos_tmu_platform_data *pdata;
61 void __iomem *base;
62 void __iomem *base_second;
63 int irq;
64 enum soc_type soc;
65 struct work_struct irq_work;
66 struct mutex lock;
67 struct clk *clk, *clk_sec;
68 u8 temp_error1, temp_error2;
69 struct regulator *regulator;
70 struct thermal_sensor_conf *reg_conf;
71 int (*tmu_initialize)(struct platform_device *pdev);
72 void (*tmu_control)(struct platform_device *pdev, bool on);
58 */
59struct exynos_tmu_data {
60 int id;
61 struct exynos_tmu_platform_data *pdata;
62 void __iomem *base;
63 void __iomem *base_second;
64 int irq;
65 enum soc_type soc;
66 struct work_struct irq_work;
67 struct mutex lock;
68 struct clk *clk, *clk_sec;
69 u8 temp_error1, temp_error2;
70 struct regulator *regulator;
71 struct thermal_sensor_conf *reg_conf;
72 int (*tmu_initialize)(struct platform_device *pdev);
73 void (*tmu_control)(struct platform_device *pdev, bool on);
74 int (*tmu_read)(struct exynos_tmu_data *data);
73};
74
75/*
76 * TMU treats temperature as a mapped temperature code.
77 * The temperature is converted differently depending on the calibration type.
78 */
79static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
80{

--- 336 unchanged lines hidden (view full) ---

417 interrupt_en = 0; /* Disable all interrupts */
418 }
419 writel(interrupt_en, data->base + EXYNOS5440_TMU_S0_7_IRQEN);
420 writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL);
421}
422
423static int exynos_tmu_read(struct exynos_tmu_data *data)
424{
75};
76
77/*
78 * TMU treats temperature as a mapped temperature code.
79 * The temperature is converted differently depending on the calibration type.
80 */
81static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
82{

--- 336 unchanged lines hidden (view full) ---

419 interrupt_en = 0; /* Disable all interrupts */
420 }
421 writel(interrupt_en, data->base + EXYNOS5440_TMU_S0_7_IRQEN);
422 writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL);
423}
424
425static int exynos_tmu_read(struct exynos_tmu_data *data)
426{
425 struct exynos_tmu_platform_data *pdata = data->pdata;
426 const struct exynos_tmu_registers *reg = pdata->registers;
427 u8 temp_code;
428 int temp;
427 int ret;
429
430 mutex_lock(&data->lock);
431 clk_enable(data->clk);
428
429 mutex_lock(&data->lock);
430 clk_enable(data->clk);
432
433 temp_code = readb(data->base + reg->tmu_cur_temp);
434
435 if (data->soc == SOC_ARCH_EXYNOS4210)
436 /* temp_code should range between 75 and 175 */
437 if (temp_code < 75 || temp_code > 175) {
438 temp = -ENODATA;
439 goto out;
440 }
441
442 temp = code_to_temp(data, temp_code);
443out:
431 ret = data->tmu_read(data);
432 if (ret >= 0)
433 ret = code_to_temp(data, ret);
444 clk_disable(data->clk);
445 mutex_unlock(&data->lock);
446
434 clk_disable(data->clk);
435 mutex_unlock(&data->lock);
436
447 return temp;
437 return ret;
448}
449
450#ifdef CONFIG_THERMAL_EMULATION
451static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
452{
453 struct exynos_tmu_data *data = drv_data;
454 struct exynos_tmu_platform_data *pdata = data->pdata;
455 const struct exynos_tmu_registers *reg = pdata->registers;

--- 33 unchanged lines hidden (view full) ---

489out:
490 return ret;
491}
492#else
493static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
494 { return -EINVAL; }
495#endif/*CONFIG_THERMAL_EMULATION*/
496
438}
439
440#ifdef CONFIG_THERMAL_EMULATION
441static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
442{
443 struct exynos_tmu_data *data = drv_data;
444 struct exynos_tmu_platform_data *pdata = data->pdata;
445 const struct exynos_tmu_registers *reg = pdata->registers;

--- 33 unchanged lines hidden (view full) ---

479out:
480 return ret;
481}
482#else
483static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
484 { return -EINVAL; }
485#endif/*CONFIG_THERMAL_EMULATION*/
486
487static int exynos4210_tmu_read(struct exynos_tmu_data *data)
488{
489 int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
490
491 /* "temp_code" should range between 75 and 175 */
492 return (ret < 75 || ret > 175) ? -ENODATA : ret;
493}
494
495static int exynos4412_tmu_read(struct exynos_tmu_data *data)
496{
497 return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
498}
499
500static int exynos5440_tmu_read(struct exynos_tmu_data *data)
501{
502 return readb(data->base + EXYNOS5440_TMU_S0_7_TEMP);
503}
504
497static void exynos_tmu_work(struct work_struct *work)
498{
499 struct exynos_tmu_data *data = container_of(work,
500 struct exynos_tmu_data, irq_work);
501 unsigned int val_type;
502
503 if (!IS_ERR(data->clk_sec))
504 clk_enable(data->clk_sec);

--- 208 unchanged lines hidden (view full) ---

713 }
714
715 data->soc = pdata->type;
716
717 switch (data->soc) {
718 case SOC_ARCH_EXYNOS4210:
719 data->tmu_initialize = exynos4210_tmu_initialize;
720 data->tmu_control = exynos4210_tmu_control;
505static void exynos_tmu_work(struct work_struct *work)
506{
507 struct exynos_tmu_data *data = container_of(work,
508 struct exynos_tmu_data, irq_work);
509 unsigned int val_type;
510
511 if (!IS_ERR(data->clk_sec))
512 clk_enable(data->clk_sec);

--- 208 unchanged lines hidden (view full) ---

721 }
722
723 data->soc = pdata->type;
724
725 switch (data->soc) {
726 case SOC_ARCH_EXYNOS4210:
727 data->tmu_initialize = exynos4210_tmu_initialize;
728 data->tmu_control = exynos4210_tmu_control;
729 data->tmu_read = exynos4210_tmu_read;
721 break;
722 case SOC_ARCH_EXYNOS3250:
723 case SOC_ARCH_EXYNOS4412:
724 case SOC_ARCH_EXYNOS5250:
725 case SOC_ARCH_EXYNOS5260:
726 case SOC_ARCH_EXYNOS5420:
727 case SOC_ARCH_EXYNOS5420_TRIMINFO:
728 data->tmu_initialize = exynos4412_tmu_initialize;
729 data->tmu_control = exynos4210_tmu_control;
730 break;
731 case SOC_ARCH_EXYNOS3250:
732 case SOC_ARCH_EXYNOS4412:
733 case SOC_ARCH_EXYNOS5250:
734 case SOC_ARCH_EXYNOS5260:
735 case SOC_ARCH_EXYNOS5420:
736 case SOC_ARCH_EXYNOS5420_TRIMINFO:
737 data->tmu_initialize = exynos4412_tmu_initialize;
738 data->tmu_control = exynos4210_tmu_control;
739 data->tmu_read = exynos4412_tmu_read;
730 break;
731 case SOC_ARCH_EXYNOS5440:
732 data->tmu_initialize = exynos5440_tmu_initialize;
733 data->tmu_control = exynos5440_tmu_control;
740 break;
741 case SOC_ARCH_EXYNOS5440:
742 data->tmu_initialize = exynos5440_tmu_initialize;
743 data->tmu_control = exynos5440_tmu_control;
744 data->tmu_read = exynos5440_tmu_read;
734 break;
735 default:
736 ret = -EINVAL;
737 dev_err(&pdev->dev, "Platform not supported\n");
738 goto err_clk;
739 }
740
741 ret = exynos_tmu_initialize(pdev);

--- 124 unchanged lines hidden ---
745 break;
746 default:
747 ret = -EINVAL;
748 dev_err(&pdev->dev, "Platform not supported\n");
749 goto err_clk;
750 }
751
752 ret = exynos_tmu_initialize(pdev);

--- 124 unchanged lines hidden ---