diff options
| author | Amit Daniel Kachhap <amit.daniel@samsung.com> | 2013-06-24 06:50:25 -0400 |
|---|---|---|
| committer | Eduardo Valentin <eduardo.valentin@ti.com> | 2013-08-13 09:51:59 -0400 |
| commit | 1b678641c24f035f020bcecf8a92cde145a49724 (patch) | |
| tree | 25fb1eea7998bf4daadd525690f7fec7a0eaa55c | |
| parent | 44328fcc4964d04a8e70e14fd443a8389e98a1de (diff) | |
thermal: exynos: Bifurcate exynos thermal common and tmu controller code
This code bifurcates exynos thermal implementation into common and sensor
specific parts. The common thermal code interacts with core thermal layer and
core cpufreq cooling parts and is independent of SOC specific driver. This
change is needed to cleanly add support for new TMU sensors.
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
| -rw-r--r-- | drivers/thermal/samsung/Kconfig | 19 | ||||
| -rw-r--r-- | drivers/thermal/samsung/Makefile | 4 | ||||
| -rw-r--r-- | drivers/thermal/samsung/exynos_thermal.c | 419 | ||||
| -rw-r--r-- | drivers/thermal/samsung/exynos_thermal_common.c | 385 | ||||
| -rw-r--r-- | drivers/thermal/samsung/exynos_thermal_common.h | 83 |
5 files changed, 491 insertions, 419 deletions
diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig index 2cf31ad90fa9..f8100b1b953a 100644 --- a/drivers/thermal/samsung/Kconfig +++ b/drivers/thermal/samsung/Kconfig | |||
| @@ -1,8 +1,17 @@ | |||
| 1 | config EXYNOS_THERMAL | 1 | config EXYNOS_THERMAL |
| 2 | tristate "Temperature sensor on Samsung EXYNOS" | 2 | tristate "Exynos thermal management unit driver" |
| 3 | depends on ARCH_HAS_BANDGAP | 3 | depends on ARCH_HAS_BANDGAP |
| 4 | help | 4 | help |
| 5 | If you say yes here you get support for TMU (Thermal Management | 5 | If you say yes here you get support for the TMU (Thermal Management |
| 6 | Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering | 6 | Unit) driver for SAMSUNG EXYNOS series of soc. This driver initialises |
| 7 | the exynos thermal driver with the core thermal layer and cpu | 7 | the TMU, reports temperature and handles cooling action if defined. |
| 8 | cooling API's. | 8 | This driver uses the exynos core thermal API's. |
| 9 | |||
| 10 | config EXYNOS_THERMAL_CORE | ||
| 11 | bool "Core thermal framework support for EXYNOS SOC's" | ||
| 12 | depends on EXYNOS_THERMAL | ||
| 13 | help | ||
| 14 | If you say yes here you get support for EXYNOS TMU | ||
| 15 | (Thermal Management Unit) common registration/unregistration | ||
| 16 | functions to the core thermal layer and also to use the generic | ||
| 17 | cpu cooling API's. | ||
diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile index 1fe6d939e8f1..6227d4fbec08 100644 --- a/drivers/thermal/samsung/Makefile +++ b/drivers/thermal/samsung/Makefile | |||
| @@ -1,4 +1,6 @@ | |||
| 1 | # | 1 | # |
| 2 | # Samsung thermal specific Makefile | 2 | # Samsung thermal specific Makefile |
| 3 | # | 3 | # |
| 4 | obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o | 4 | obj-$(CONFIG_EXYNOS_THERMAL) += exynos_soc_thermal.o |
| 5 | exynos_soc_thermal-y := exynos_thermal.o | ||
| 6 | exynos_soc_thermal-$(CONFIG_EXYNOS_THERMAL_CORE) += exynos_thermal_common.o | ||
diff --git a/drivers/thermal/samsung/exynos_thermal.c b/drivers/thermal/samsung/exynos_thermal.c index 9af4b93c9f86..f3500ab6615d 100644 --- a/drivers/thermal/samsung/exynos_thermal.c +++ b/drivers/thermal/samsung/exynos_thermal.c | |||
| @@ -21,23 +21,15 @@ | |||
| 21 | * | 21 | * |
| 22 | */ | 22 | */ |
| 23 | 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> | 24 | #include <linux/clk.h> |
| 31 | #include <linux/workqueue.h> | ||
| 32 | #include <linux/sysfs.h> | ||
| 33 | #include <linux/kobject.h> | ||
| 34 | #include <linux/io.h> | 25 | #include <linux/io.h> |
| 35 | #include <linux/mutex.h> | 26 | #include <linux/interrupt.h> |
| 36 | #include <linux/platform_data/exynos_thermal.h> | 27 | #include <linux/module.h> |
| 37 | #include <linux/thermal.h> | ||
| 38 | #include <linux/cpufreq.h> | ||
| 39 | #include <linux/cpu_cooling.h> | ||
| 40 | #include <linux/of.h> | 28 | #include <linux/of.h> |
| 29 | #include <linux/platform_device.h> | ||
| 30 | #include <linux/platform_data/exynos_thermal.h> | ||
| 31 | |||
| 32 | #include "exynos_thermal_common.h" | ||
| 41 | 33 | ||
| 42 | /* Exynos generic registers */ | 34 | /* Exynos generic registers */ |
| 43 | #define EXYNOS_TMU_REG_TRIMINFO 0x0 | 35 | #define EXYNOS_TMU_REG_TRIMINFO 0x0 |
| @@ -88,16 +80,6 @@ | |||
| 88 | #define EFUSE_MIN_VALUE 40 | 80 | #define EFUSE_MIN_VALUE 40 |
| 89 | #define EFUSE_MAX_VALUE 100 | 81 | #define EFUSE_MAX_VALUE 100 |
| 90 | 82 | ||
| 91 | /* In-kernel thermal framework related macros & definations */ | ||
| 92 | #define SENSOR_NAME_LEN 16 | ||
| 93 | #define MAX_TRIP_COUNT 8 | ||
| 94 | #define MAX_COOLING_DEVICE 4 | ||
| 95 | #define MAX_THRESHOLD_LEVS 4 | ||
| 96 | |||
| 97 | #define ACTIVE_INTERVAL 500 | ||
| 98 | #define IDLE_INTERVAL 10000 | ||
| 99 | #define MCELSIUS 1000 | ||
| 100 | |||
| 101 | #ifdef CONFIG_THERMAL_EMULATION | 83 | #ifdef CONFIG_THERMAL_EMULATION |
| 102 | #define EXYNOS_EMUL_TIME 0x57F0 | 84 | #define EXYNOS_EMUL_TIME 0x57F0 |
| 103 | #define EXYNOS_EMUL_TIME_SHIFT 16 | 85 | #define EXYNOS_EMUL_TIME_SHIFT 16 |
| @@ -106,17 +88,6 @@ | |||
| 106 | #define EXYNOS_EMUL_ENABLE 0x1 | 88 | #define EXYNOS_EMUL_ENABLE 0x1 |
| 107 | #endif /* CONFIG_THERMAL_EMULATION */ | 89 | #endif /* CONFIG_THERMAL_EMULATION */ |
| 108 | 90 | ||
| 109 | /* CPU Zone information */ | ||
| 110 | #define PANIC_ZONE 4 | ||
| 111 | #define WARN_ZONE 3 | ||
| 112 | #define MONITOR_ZONE 2 | ||
| 113 | #define SAFE_ZONE 1 | ||
| 114 | |||
| 115 | #define GET_ZONE(trip) (trip + 2) | ||
| 116 | #define GET_TRIP(zone) (zone - 2) | ||
| 117 | |||
| 118 | #define EXYNOS_ZONE_COUNT 3 | ||
| 119 | |||
| 120 | struct exynos_tmu_data { | 91 | struct exynos_tmu_data { |
| 121 | struct exynos_tmu_platform_data *pdata; | 92 | struct exynos_tmu_platform_data *pdata; |
| 122 | struct resource *mem; | 93 | struct resource *mem; |
| @@ -129,384 +100,6 @@ struct exynos_tmu_data { | |||
| 129 | u8 temp_error1, temp_error2; | 100 | u8 temp_error1, temp_error2; |
| 130 | }; | 101 | }; |
| 131 | 102 | ||
| 132 | struct thermal_trip_point_conf { | ||
| 133 | int trip_val[MAX_TRIP_COUNT]; | ||
| 134 | int trip_count; | ||
| 135 | u8 trigger_falling; | ||
| 136 | }; | ||
| 137 | |||
| 138 | struct thermal_cooling_conf { | ||
| 139 | struct freq_clip_table freq_data[MAX_TRIP_COUNT]; | ||
| 140 | int freq_clip_count; | ||
| 141 | }; | ||
| 142 | |||
| 143 | struct thermal_sensor_conf { | ||
| 144 | char name[SENSOR_NAME_LEN]; | ||
| 145 | int (*read_temperature)(void *data); | ||
| 146 | int (*write_emul_temp)(void *drv_data, unsigned long temp); | ||
| 147 | struct thermal_trip_point_conf trip_data; | ||
| 148 | struct thermal_cooling_conf cooling_data; | ||
| 149 | void *private_data; | ||
| 150 | }; | ||
| 151 | |||
| 152 | struct exynos_thermal_zone { | ||
| 153 | enum thermal_device_mode mode; | ||
| 154 | struct thermal_zone_device *therm_dev; | ||
| 155 | struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE]; | ||
| 156 | unsigned int cool_dev_size; | ||
| 157 | struct platform_device *exynos4_dev; | ||
| 158 | struct thermal_sensor_conf *sensor_conf; | ||
| 159 | bool bind; | ||
| 160 | }; | ||
| 161 | |||
| 162 | static struct exynos_thermal_zone *th_zone; | ||
| 163 | static void exynos_unregister_thermal(void); | ||
| 164 | static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf); | ||
| 165 | |||
| 166 | /* Get mode callback functions for thermal zone */ | ||
| 167 | static int exynos_get_mode(struct thermal_zone_device *thermal, | ||
| 168 | enum thermal_device_mode *mode) | ||
| 169 | { | ||
| 170 | if (th_zone) | ||
| 171 | *mode = th_zone->mode; | ||
| 172 | return 0; | ||
| 173 | } | ||
| 174 | |||
| 175 | /* Set mode callback functions for thermal zone */ | ||
| 176 | static int exynos_set_mode(struct thermal_zone_device *thermal, | ||
| 177 | enum thermal_device_mode mode) | ||
| 178 | { | ||
| 179 | if (!th_zone->therm_dev) { | ||
| 180 | pr_notice("thermal zone not registered\n"); | ||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | |||
| 184 | mutex_lock(&th_zone->therm_dev->lock); | ||
| 185 | |||
| 186 | if (mode == THERMAL_DEVICE_ENABLED && | ||
| 187 | !th_zone->sensor_conf->trip_data.trigger_falling) | ||
| 188 | th_zone->therm_dev->polling_delay = IDLE_INTERVAL; | ||
| 189 | else | ||
| 190 | th_zone->therm_dev->polling_delay = 0; | ||
| 191 | |||
| 192 | mutex_unlock(&th_zone->therm_dev->lock); | ||
| 193 | |||
| 194 | th_zone->mode = mode; | ||
| 195 | thermal_zone_device_update(th_zone->therm_dev); | ||
| 196 | pr_info("thermal polling set for duration=%d msec\n", | ||
