linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440
@ 2013-04-26 10:37 Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory Amit Daniel Kachhap
                   ` (19 more replies)
  0 siblings, 20 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

Changes in V2:
* Separated SOC data from TMU driver. This is as per suggestion from Eduardo.
* Merged the new file created for exynos5440 TMU controller with the existing
 TMU controller code.
* Removed the DT parsing code as now the SOC specific data are cleanly put
 inside the data specific file.
* Even the register definations/bitfields are treated as data as there is
 some variation across SOC's.

This patchset adds TMU(Thermal management Unit) driver support for
exynos5440 platform. There are 3 instances of the TMU controllers so
necessary cleanup is done to handle multiple thermal zone.

1 patch (exynos4: Add documentation for Exynos SoC thermal bindings) from
Lukasz Majewski is already posted to mainline. Adding it here for completeness.
(http://www.mail-archive.com/linux-samsung-soc@vger.kernel.org/msg17817.html)

1 patch (thermal: exynos: Support thermal tripping ) from Jonghwan Choi is
added here with some changes.
(https://patchwork.kernel.org/patch/1668371/)

All these patches are based on thermal maintainers git tree,
git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git next.

Amit Daniel Kachhap (19):
  thermal: exynos: Moving exynos thermal files into samsung directory
  thermal: exynos: Bifurcate exynos thermal common and tmu controller
    code
  thermal: exynos: Rename exynos_thermal.c to exynos_tmu.c
  thermal: exynos: Move exynos_thermal.h from include/* to driver/*
    folder
  thermal: exynos: Bifurcate exynos tmu driver and configuration data
  thermal: exynos: Add missing definations and code cleanup
  thermal: exynos: Add extra entries in the tmu platform data
  thermal: exynos: Support thermal tripping
  thermal: exynos: Move register definitions from driver file to data
    file
  thermal: exynos: Fix to clear only the generated interrupts
  thermal: exynos: Add support for instance based register/unregister
  thermal: exynos: Modify private_data to appropriate name driver_data
  thermal: exynos: Return success even if no cooling data supplied
  thermal: exynos: Make the zone handling dependent on trip count
  thermal: exynos: Add support to handle many instances of TMU
  thermal: exynos: Add features to check instead of SOC type
  thermal: exynos: Add support for exynos5440 TMU sensor.
  Documentation: thermal: Explain the exynos thermal driver model
  ARM: dts: Add device tree node for exynos5440 TMU controller

Lukasz Majewski (1):
  ARM: dts: thermal: exynos4: Add documentation for Exynos SoC thermal
    bindings

 .../devicetree/bindings/thermal/exynos-thermal.txt |   49 +
 Documentation/thermal/exynos_thermal               |   43 +-
 arch/arm/boot/dts/exynos5440.dtsi                  |   30 +
 drivers/thermal/Kconfig                            |   13 +-
 drivers/thermal/Makefile                           |    2 +-
 drivers/thermal/exynos_thermal.c                   | 1066 --------------------
 drivers/thermal/samsung/Kconfig                    |   21 +
 drivers/thermal/samsung/Makefile                   |    7 +
 drivers/thermal/samsung/exynos_thermal_common.c    |  401 ++++++++
 drivers/thermal/samsung/exynos_thermal_common.h    |   85 ++
 drivers/thermal/samsung/exynos_tmu.c               |  719 +++++++++++++
 drivers/thermal/samsung/exynos_tmu.h               |  223 ++++
 drivers/thermal/samsung/exynos_tmu_data.c          |  224 ++++
 drivers/thermal/samsung/exynos_tmu_data.h          |  150 +++
 include/linux/platform_data/exynos_thermal.h       |  119 ---
 15 files changed, 1949 insertions(+), 1203 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/thermal/exynos-thermal.txt
 delete mode 100644 drivers/thermal/exynos_thermal.c
 create mode 100644 drivers/thermal/samsung/Kconfig
 create mode 100644 drivers/thermal/samsung/Makefile
 create mode 100644 drivers/thermal/samsung/exynos_thermal_common.c
 create mode 100644 drivers/thermal/samsung/exynos_thermal_common.h
 create mode 100644 drivers/thermal/samsung/exynos_tmu.c
 create mode 100644 drivers/thermal/samsung/exynos_tmu.h
 create mode 100644 drivers/thermal/samsung/exynos_tmu_data.c
 create mode 100644 drivers/thermal/samsung/exynos_tmu_data.h
 delete mode 100644 include/linux/platform_data/exynos_thermal.h


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-05-06 15:05   ` Zhang Rui
  2013-04-26 10:37 ` [PATCH V2 02/20] thermal: exynos: Bifurcate exynos thermal common and tmu controller code Amit Daniel Kachhap
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This movement of files is done for easy maintenance and adding more
new sensor's support for exynos platform easily . This will also help in
bifurcating exynos common, sensor driver and sensor data related parts.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/Kconfig                        |   13 +++++--------
 drivers/thermal/Makefile                       |    2 +-
 drivers/thermal/samsung/Kconfig                |    9 +++++++++
 drivers/thermal/samsung/Makefile               |    4 ++++
 drivers/thermal/{ => samsung}/exynos_thermal.c |    0
 5 files changed, 19 insertions(+), 9 deletions(-)
 create mode 100644 drivers/thermal/samsung/Kconfig
 create mode 100644 drivers/thermal/samsung/Makefile
 rename drivers/thermal/{ => samsung}/exynos_thermal.c (100%)

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 5e3c025..081ddc5 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -114,14 +114,6 @@ config KIRKWOOD_THERMAL
 	  Support for the Kirkwood thermal sensor driver into the Linux thermal
 	  framework. Only kirkwood 88F6282 and 88F6283 have this sensor.
 
-config EXYNOS_THERMAL
-	tristate "Temperature sensor on Samsung EXYNOS"
-	depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
-	depends on CPU_THERMAL
-	help
-	  If you say yes here you get support for TMU (Thermal Management
-	  Unit) on SAMSUNG EXYNOS series of SoC.
-
 config DOVE_THERMAL
 	tristate "Temperature sensor on Marvell Dove SoCs"
 	depends on ARCH_DOVE
@@ -169,4 +161,9 @@ config INTEL_POWERCLAMP
 	  enforce idle time which results in more package C-state residency. The
 	  user interface is exposed via generic thermal framework.
 
+menu "Exynos thermal drivers"
+depends on PLAT_SAMSUNG
+source "drivers/thermal/samsung/Kconfig"
+endmenu
+
 endif
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index c054d41..b3063a9 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -17,7 +17,7 @@ thermal_sys-$(CONFIG_CPU_THERMAL)	+= cpu_cooling.o
 obj-$(CONFIG_SPEAR_THERMAL)	+= spear_thermal.o
 obj-$(CONFIG_RCAR_THERMAL)	+= rcar_thermal.o
 obj-$(CONFIG_KIRKWOOD_THERMAL)  += kirkwood_thermal.o
-obj-$(CONFIG_EXYNOS_THERMAL)	+= exynos_thermal.o
+obj-y				+= samsung/
 obj-$(CONFIG_DOVE_THERMAL)  	+= dove_thermal.o
 obj-$(CONFIG_DB8500_THERMAL)	+= db8500_thermal.o
 obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
new file mode 100644
index 0000000..2d3d9dc
--- /dev/null
+++ b/drivers/thermal/samsung/Kconfig
@@ -0,0 +1,9 @@
+config EXYNOS_THERMAL
+	tristate "Temperature sensor on Samsung EXYNOS"
+	depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
+	depends on CPU_THERMAL
+	help
+	  If you say yes here you get support for TMU (Thermal Management
+	  Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
+	  the exynos thermal driver with the core thermal layer and cpu
+	  cooling API's.
diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
new file mode 100644
index 0000000..1fe6d93
--- /dev/null
+++ b/drivers/thermal/samsung/Makefile
@@ -0,0 +1,4 @@
+#
+# Samsung thermal specific Makefile
+#
+obj-$(CONFIG_EXYNOS_THERMAL)	+= exynos_thermal.o
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/samsung/exynos_thermal.c
similarity index 100%
rename from drivers/thermal/exynos_thermal.c
rename to drivers/thermal/samsung/exynos_thermal.c
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 02/20] thermal: exynos: Bifurcate exynos thermal common and tmu controller code
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-05-06 15:16   ` Zhang Rui
  2013-04-26 10:37 ` [PATCH V2 03/20] thermal: exynos: Rename exynos_thermal.c to exynos_tmu.c Amit Daniel Kachhap
                   ` (17 subsequent siblings)
  19 siblings, 1 reply; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

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>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/Kconfig                 |   26 +-
 drivers/thermal/samsung/Makefile                |    4 +-
 drivers/thermal/samsung/exynos_thermal.c        |  421 +----------------------
 drivers/thermal/samsung/exynos_thermal_common.c |  389 +++++++++++++++++++++
 drivers/thermal/samsung/exynos_thermal_common.h |   71 ++++
 5 files changed, 491 insertions(+), 420 deletions(-)
 create mode 100644 drivers/thermal/samsung/exynos_thermal_common.c
 create mode 100644 drivers/thermal/samsung/exynos_thermal_common.h

diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
index 2d3d9dc..1e3ba31 100644
--- a/drivers/thermal/samsung/Kconfig
+++ b/drivers/thermal/samsung/Kconfig
@@ -1,9 +1,21 @@
-config EXYNOS_THERMAL
-	tristate "Temperature sensor on Samsung EXYNOS"
+config EXYNOS_COMMON
+	bool "Common thermal support for EXYNOS SOC's"
 	depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
-	depends on CPU_THERMAL
 	help
-	  If you say yes here you get support for TMU (Thermal Management
-	  Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
-	  the exynos thermal driver with the core thermal layer and cpu
-	  cooling API's.
+	  If you say yes here you get support for EXYNOS TMU
+	  (Thermal Management Unit) common registration/unregistration
+	  functions to the core thermal layer and also to use the generic
+	  cpu cooling API's.
+
+if EXYNOS_COMMON
+
+config EXYNOS_SOC_THERMAL
+	tristate "Temperature sensor on Samsung EXYNOS series SOC"
+	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250)
+ 	help
+	  If you say yes here you can enable TMU (Thermal Management Unit) on
+	  SAMSUNG EXYNOS 4210, 4412, 4414 and 5250 series of SoC. This option
+	  initialises the TMU controller and registers/unregisters with exynos
+	  common thermal layer.
+
+endif
diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
index 1fe6d93..fcda5b4 100644
--- a/drivers/thermal/samsung/Makefile
+++ b/drivers/thermal/samsung/Makefile
@@ -1,4 +1,6 @@
 #
 # Samsung thermal specific Makefile
 #
-obj-$(CONFIG_EXYNOS_THERMAL)	+= exynos_thermal.o
+obj-$(CONFIG_EXYNOS_SOC_THERMAL)		+= exynos_soc_thermal.o
+exynos_soc_thermal-y				:= exynos_thermal.o
+exynos_soc_thermal-$(CONFIG_EXYNOS_COMMON)	+= exynos_thermal_common.o
diff --git a/drivers/thermal/samsung/exynos_thermal.c b/drivers/thermal/samsung/exynos_thermal.c
index d20ce9e..4c85945 100644
--- a/drivers/thermal/samsung/exynos_thermal.c
+++ b/drivers/thermal/samsung/exynos_thermal.c
@@ -21,23 +21,19 @@
  *
  */
 
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
 #include <linux/clk.h>
-#include <linux/workqueue.h>
-#include <linux/sysfs.h>
-#include <linux/kobject.h>
 #include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
-#include <linux/platform_data/exynos_thermal.h>
-#include <linux/thermal.h>
-#include <linux/cpufreq.h>
-#include <linux/cpu_cooling.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/exynos_thermal.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include "exynos_thermal_common.h"
 
 /* Exynos generic registers */
 #define EXYNOS_TMU_REG_TRIMINFO		0x0
@@ -88,16 +84,6 @@
 #define EFUSE_MIN_VALUE 40
 #define EFUSE_MAX_VALUE 100
 
-/* In-kernel thermal framework related macros & definations */
-#define SENSOR_NAME_LEN	16
-#define MAX_TRIP_COUNT	8
-#define MAX_COOLING_DEVICE 4
-#define MAX_THRESHOLD_LEVS 4
-
-#define ACTIVE_INTERVAL 500
-#define IDLE_INTERVAL 10000
-#define MCELSIUS	1000
-
 #ifdef CONFIG_THERMAL_EMULATION
 #define EXYNOS_EMUL_TIME	0x57F0
 #define EXYNOS_EMUL_TIME_SHIFT	16
@@ -106,17 +92,6 @@
 #define EXYNOS_EMUL_ENABLE	0x1
 #endif /* CONFIG_THERMAL_EMULATION */
 
-/* CPU Zone information */
-#define PANIC_ZONE      4
-#define WARN_ZONE       3
-#define MONITOR_ZONE    2
-#define SAFE_ZONE       1
-
-#define GET_ZONE(trip) (trip + 2)
-#define GET_TRIP(zone) (zone - 2)
-
-#define EXYNOS_ZONE_COUNT	3
-
 struct exynos_tmu_data {
 	struct exynos_tmu_platform_data *pdata;
 	struct resource *mem;
@@ -129,384 +104,6 @@ struct exynos_tmu_data {
 	u8 temp_error1, temp_error2;
 };
 
-struct	thermal_trip_point_conf {
-	int trip_val[MAX_TRIP_COUNT];
-	int trip_count;
-	u8 trigger_falling;
-};
-
-struct	thermal_cooling_conf {
-	struct freq_clip_table freq_data[MAX_TRIP_COUNT];
-	int freq_clip_count;
-};
-
-struct thermal_sensor_conf {
-	char name[SENSOR_NAME_LEN];
-	int (*read_temperature)(void *data);
-	int (*write_emul_temp)(void *drv_data, unsigned long temp);
-	struct thermal_trip_point_conf trip_data;
-	struct thermal_cooling_conf cooling_data;
-	void *private_data;
-};
-
-struct exynos_thermal_zone {
-	enum thermal_device_mode mode;
-	struct thermal_zone_device *therm_dev;
-	struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
-	unsigned int cool_dev_size;
-	struct platform_device *exynos4_dev;
-	struct thermal_sensor_conf *sensor_conf;
-	bool bind;
-};
-
-static struct exynos_thermal_zone *th_zone;
-static void exynos_unregister_thermal(void);
-static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
-
-/* Get mode callback functions for thermal zone */
-static int exynos_get_mode(struct thermal_zone_device *thermal,
-			enum thermal_device_mode *mode)
-{
-	if (th_zone)
-		*mode = th_zone->mode;
-	return 0;
-}
-
-/* Set mode callback functions for thermal zone */
-static int exynos_set_mode(struct thermal_zone_device *thermal,
-			enum thermal_device_mode mode)
-{
-	if (!th_zone->therm_dev) {
-		pr_notice("thermal zone not registered\n");
-		return 0;
-	}
-
-	mutex_lock(&th_zone->therm_dev->lock);
-
-	if (mode == THERMAL_DEVICE_ENABLED &&
-		!th_zone->sensor_conf->trip_data.trigger_falling)
-		th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
-	else
-		th_zone->therm_dev->polling_delay = 0;
-
-	mutex_unlock(&th_zone->therm_dev->lock);
-
-	th_zone->mode = mode;
-	thermal_zone_device_update(th_zone->therm_dev);
-	pr_info("thermal polling set for duration=%d msec\n",
-				th_zone->therm_dev->polling_delay);
-	return 0;
-}
-
-
-/* Get trip type callback functions for thermal zone */
-static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
-				 enum thermal_trip_type *type)
-{
-	switch (GET_ZONE(trip)) {
-	case MONITOR_ZONE:
-	case WARN_ZONE:
-		*type = THERMAL_TRIP_ACTIVE;
-		break;
-	case PANIC_ZONE:
-		*type = THERMAL_TRIP_CRITICAL;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/* Get trip temperature callback functions for thermal zone */
-static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
-				unsigned long *temp)
-{
-	if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
-		return -EINVAL;
-
-	*temp = th_zone->sensor_conf->trip_data.trip_val[trip];
-	/* convert the temperature into millicelsius */
-	*temp = *temp * MCELSIUS;
-
-	return 0;
-}
-
-/* Get critical temperature callback functions for thermal zone */
-static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
-				unsigned long *temp)
-{
-	int ret;
-	/* Panic zone */
-	ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
-	return ret;
-}
-
-/* Bind callback functions for thermal zone */
-static int exynos_bind(struct thermal_zone_device *thermal,
-			struct thermal_cooling_device *cdev)
-{
-	int ret = 0, i, tab_size, level;
-	struct freq_clip_table *tab_ptr, *clip_data;
-	struct thermal_sensor_conf *data = th_zone->sensor_conf;
-
-	tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
-	tab_size = data->cooling_data.freq_clip_count;
-
-	if (tab_ptr == NULL || tab_size == 0)
-		return -EINVAL;
-
-	/* find the cooling device registered*/
-	for (i = 0; i < th_zone->cool_dev_size; i++)
-		if (cdev == th_zone->cool_dev[i])
-			break;
-
-	/* No matching cooling device */
-	if (i == th_zone->cool_dev_size)
-		return 0;
-
-	/* Bind the thermal zone to the cpufreq cooling device */
-	for (i = 0; i < tab_size; i++) {
-		clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
-		level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max);
-		if (level == THERMAL_CSTATE_INVALID)
-			return 0;
-		switch (GET_ZONE(i)) {
-		case MONITOR_ZONE:
-		case WARN_ZONE:
-			if (thermal_zone_bind_cooling_device(thermal, i, cdev,
-								level, 0)) {
-				pr_err("error binding cdev inst %d\n", i);
-				ret = -EINVAL;
-			}
-			th_zone->bind = true;
-			break;
-		default:
-			ret = -EINVAL;
-		}
-	}
-
-	return ret;
-}
-
-/* Unbind callback functions for thermal zone */
-static int exynos_unbind(struct thermal_zone_device *thermal,
-			struct thermal_cooling_device *cdev)
-{
-	int ret = 0, i, tab_size;
-	struct thermal_sensor_conf *data = th_zone->sensor_conf;
-
-	if (th_zone->bind == false)
-		return 0;
-
-	tab_size = data->cooling_data.freq_clip_count;
-
-	if (tab_size == 0)
-		return -EINVAL;
-
-	/* find the cooling device registered*/
-	for (i = 0; i < th_zone->cool_dev_size; i++)
-		if (cdev == th_zone->cool_dev[i])
-			break;
-
-	/* No matching cooling device */
-	if (i == th_zone->cool_dev_size)
-		return 0;
-
-	/* Bind the thermal zone to the cpufreq cooling device */
-	for (i = 0; i < tab_size; i++) {
-		switch (GET_ZONE(i)) {
-		case MONITOR_ZONE:
-		case WARN_ZONE:
-			if (thermal_zone_unbind_cooling_device(thermal, i,
-								cdev)) {
-				pr_err("error unbinding cdev inst=%d\n", i);
-				ret = -EINVAL;
-			}
-			th_zone->bind = false;
-			break;
-		default:
-			ret = -EINVAL;
-		}
-	}
-	return ret;
-}
-
-/* Get temperature callback functions for thermal zone */
-static int exynos_get_temp(struct thermal_zone_device *thermal,
-			unsigned long *temp)
-{
-	void *data;
-
-	if (!th_zone->sensor_conf) {
-		pr_info("Temperature sensor not initialised\n");
-		return -EINVAL;
-	}
-	data = th_zone->sensor_conf->private_data;
-	*temp = th_zone->sensor_conf->read_temperature(data);
-	/* convert the temperature into millicelsius */
-	*temp = *temp * MCELSIUS;
-	return 0;
-}
-
-/* Get temperature callback functions for thermal zone */
-static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
-						unsigned long temp)
-{
-	void *data;
-	int ret = -EINVAL;
-
-	if (!th_zone->sensor_conf) {
-		pr_info("Temperature sensor not initialised\n");
-		return -EINVAL;
-	}
-	data = th_zone->sensor_conf->private_data;
-	if (th_zone->sensor_conf->write_emul_temp)
-		ret = th_zone->sensor_conf->write_emul_temp(data, temp);
-	return ret;
-}
-
-/* Get the temperature trend */
-static int exynos_get_trend(struct thermal_zone_device *thermal,
-			int trip, enum thermal_trend *trend)
-{
-	int ret;
-	unsigned long trip_temp;
-
-	ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
-	if (ret < 0)
-		return ret;
-
-	if (thermal->temperature >= trip_temp)
-		*trend = THERMAL_TREND_RAISE_FULL;
-	else
-		*trend = THERMAL_TREND_DROP_FULL;
-
-	return 0;
-}
-/* Operation callback functions for thermal zone */
-static struct thermal_zone_device_ops const exynos_dev_ops = {
-	.bind = exynos_bind,
-	.unbind = exynos_unbind,
-	.get_temp = exynos_get_temp,
-	.set_emul_temp = exynos_set_emul_temp,
-	.get_trend = exynos_get_trend,
-	.get_mode = exynos_get_mode,
-	.set_mode = exynos_set_mode,
-	.get_trip_type = exynos_get_trip_type,
-	.get_trip_temp = exynos_get_trip_temp,
-	.get_crit_temp = exynos_get_crit_temp,
-};
-
-/*
- * This function may be called from interrupt based temperature sensor
- * when threshold is changed.
- */
-static void exynos_report_trigger(void)
-{
-	unsigned int i;
-	char data[10];
-	char *envp[] = { data, NULL };
-
-	if (!th_zone || !th_zone->therm_dev)
-		return;
-	if (th_zone->bind == false) {
-		for (i = 0; i < th_zone->cool_dev_size; i++) {
-			if (!th_zone->cool_dev[i])
-				continue;
-			exynos_bind(th_zone->therm_dev,
-					th_zone->cool_dev[i]);
-		}
-	}
-
-	thermal_zone_device_update(th_zone->therm_dev);
-
-	mutex_lock(&th_zone->therm_dev->lock);
-	/* Find the level for which trip happened */
-	for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
-		if (th_zone->therm_dev->last_temperature <
-			th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
-			break;
-	}
-
-	if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
-		!th_zone->sensor_conf->trip_data.trigger_falling) {
-		if (i > 0)
-			th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
-		else
-			th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
-	}
-
-	snprintf(data, sizeof(data), "%u", i);
-	kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
-	mutex_unlock(&th_zone->therm_dev->lock);
-}
-
-/* Register with the in-kernel thermal management */
-static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
-{
-	int ret;
-	struct cpumask mask_val;
-
-	if (!sensor_conf || !sensor_conf->read_temperature) {
-		pr_err("Temperature sensor not initialised\n");
-		return -EINVAL;
-	}
-
-	th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
-	if (!th_zone)
-		return -ENOMEM;
-
-	th_zone->sensor_conf = sensor_conf;
-	cpumask_set_cpu(0, &mask_val);
-	th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
-	if (IS_ERR(th_zone->cool_dev[0])) {
-		pr_err("Failed to register cpufreq cooling device\n");
-		ret = -EINVAL;
-		goto err_unregister;
-	}
-	th_zone->cool_dev_size++;
-
-	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
-			EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
-			sensor_conf->trip_data.trigger_falling ?
-			0 : IDLE_INTERVAL);
-
-	if (IS_ERR(th_zone->therm_dev)) {
-		pr_err("Failed to register thermal zone device\n");
-		ret = PTR_ERR(th_zone->therm_dev);
-		goto err_unregister;
-	}
-	th_zone->mode = THERMAL_DEVICE_ENABLED;
-
-	pr_info("Exynos: Kernel Thermal management registered\n");
-
-	return 0;
-
-err_unregister:
-	exynos_unregister_thermal();
-	return ret;
-}
-
-/* Un-Register with the in-kernel thermal management */
-static void exynos_unregister_thermal(void)
-{
-	int i;
-
-	if (!th_zone)
-		return;
-
-	if (th_zone->therm_dev)
-		thermal_zone_device_unregister(th_zone->therm_dev);
-
-	for (i = 0; i < th_zone->cool_dev_size; i++) {
-		if (th_zone->cool_dev[i])
-			cpufreq_cooling_unregister(th_zone->cool_dev[i]);
-	}
-
-	kfree(th_zone);
-	pr_info("Exynos: Kernel Thermal management unregistered\n");
-}
-
 /*
  * TMU treats temperature as a mapped temperature code.
  * The temperature is converted differently depending on the calibration type.
diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
new file mode 100644
index 0000000..9a57606
--- /dev/null
+++ b/drivers/thermal/samsung/exynos_thermal_common.c
@@ -0,0 +1,389 @@
+/*
+ * exynos_thermal_common.c - Samsung EXYNOS common thermal file
+ *
+ *  Copyright (C) 2013 Samsung Electronics
+ *  Amit Daniel Kachhap <amit.daniel@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/cpufreq.h>
+#include <linux/cpu_cooling.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/kobject.h>
+#include <linux/mutex.h>
+#include <linux/platform_data/exynos_thermal.h>
+#include <linux/slab.h>
+#include <linux/thermal.h>
+#include "exynos_thermal_common.h"
+
+struct exynos_thermal_zone {
+	enum thermal_device_mode mode;
+	struct thermal_zone_device *therm_dev;
+	struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
+	unsigned int cool_dev_size;
+	struct platform_device *exynos4_dev;
+	struct thermal_sensor_conf *sensor_conf;
+	bool bind;
+};
+
+static struct exynos_thermal_zone *th_zone;
+
+/* Get mode callback functions for thermal zone */
+static int exynos_get_mode(struct thermal_zone_device *thermal,
+			enum thermal_device_mode *mode)
+{
+	if (th_zone)
+		*mode = th_zone->mode;
+	return 0;
+}
+
+/* Set mode callback functions for thermal zone */
+static int exynos_set_mode(struct thermal_zone_device *thermal,
+			enum thermal_device_mode mode)
+{
+	if (!th_zone->therm_dev) {
+		pr_notice("thermal zone not registered\n");
+		return 0;
+	}
+
+	mutex_lock(&th_zone->therm_dev->lock);
+
+	if (mode == THERMAL_DEVICE_ENABLED &&
+		!th_zone->sensor_conf->trip_data.trigger_falling)
+		th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+	else
+		th_zone->therm_dev->polling_delay = 0;
+
+	mutex_unlock(&th_zone->therm_dev->lock);
+
+	th_zone->mode = mode;
+	thermal_zone_device_update(th_zone->therm_dev);
+	pr_info("thermal polling set for duration=%d msec\n",
+				th_zone->therm_dev->polling_delay);
+	return 0;
+}
+
+
+/* Get trip type callback functions for thermal zone */
+static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
+				 enum thermal_trip_type *type)
+{
+	switch (GET_ZONE(trip)) {
+	case MONITOR_ZONE:
+	case WARN_ZONE:
+		*type = THERMAL_TRIP_ACTIVE;
+		break;
+	case PANIC_ZONE:
+		*type = THERMAL_TRIP_CRITICAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* Get trip temperature callback functions for thermal zone */
+static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
+				unsigned long *temp)
+{
+	if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
+		return -EINVAL;
+
+	*temp = th_zone->sensor_conf->trip_data.trip_val[trip];
+	/* convert the temperature into millicelsius */
+	*temp = *temp * MCELSIUS;
+
+	return 0;
+}
+
+/* Get critical temperature callback functions for thermal zone */
+static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
+				unsigned long *temp)
+{
+	int ret;
+	/* Panic zone */
+	ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
+	return ret;
+}
+
+/* Bind callback functions for thermal zone */
+static int exynos_bind(struct thermal_zone_device *thermal,
+			struct thermal_cooling_device *cdev)
+{
+	int ret = 0, i, tab_size, level;
+	struct freq_clip_table *tab_ptr, *clip_data;
+	struct thermal_sensor_conf *data = th_zone->sensor_conf;
+
+	tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
+	tab_size = data->cooling_data.freq_clip_count;
+
+	if (tab_ptr == NULL || tab_size == 0)
+		return -EINVAL;
+
+	/* find the cooling device registered*/
+	for (i = 0; i < th_zone->cool_dev_size; i++)
+		if (cdev == th_zone->cool_dev[i])
+			break;
+
+	/* No matching cooling device */
+	if (i == th_zone->cool_dev_size)
+		return 0;
+
+	/* Bind the thermal zone to the cpufreq cooling device */
+	for (i = 0; i < tab_size; i++) {
+		clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
+		level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max);
+		if (level == THERMAL_CSTATE_INVALID)
+			return 0;
+		switch (GET_ZONE(i)) {
+		case MONITOR_ZONE:
+		case WARN_ZONE:
+			if (thermal_zone_bind_cooling_device(thermal, i, cdev,
+								level, 0)) {
+				pr_err("error binding cdev inst %d\n", i);
+				ret = -EINVAL;
+			}
+			th_zone->bind = true;
+			break;
+		default:
+			ret = -EINVAL;
+		}
+	}
+
+	return ret;
+}
+
+/* Unbind callback functions for thermal zone */
+static int exynos_unbind(struct thermal_zone_device *thermal,
+			struct thermal_cooling_device *cdev)
+{
+	int ret = 0, i, tab_size;
+	struct thermal_sensor_conf *data = th_zone->sensor_conf;
+
+	if (th_zone->bind == false)
+		return 0;
+
+	tab_size = data->cooling_data.freq_clip_count;
+
+	if (tab_size == 0)
+		return -EINVAL;
+
+	/* find the cooling device registered*/
+	for (i = 0; i < th_zone->cool_dev_size; i++)
+		if (cdev == th_zone->cool_dev[i])
+			break;
+
+	/* No matching cooling device */
+	if (i == th_zone->cool_dev_size)
+		return 0;
+
+	/* Bind the thermal zone to the cpufreq cooling device */
+	for (i = 0; i < tab_size; i++) {
+		switch (GET_ZONE(i)) {
+		case MONITOR_ZONE:
+		case WARN_ZONE:
+			if (thermal_zone_unbind_cooling_device(thermal, i,
+								cdev)) {
+				pr_err("error unbinding cdev inst=%d\n", i);
+				ret = -EINVAL;
+			}
+			th_zone->bind = false;
+			break;
+		default:
+			ret = -EINVAL;
+		}
+	}
+	return ret;
+}
+
+/* Get temperature callback functions for thermal zone */
+static int exynos_get_temp(struct thermal_zone_device *thermal,
+			unsigned long *temp)
+{
+	void *data;
+
+	if (!th_zone->sensor_conf) {
+		pr_info("Temperature sensor not initialised\n");
+		return -EINVAL;
+	}
+	data = th_zone->sensor_conf->private_data;
+	*temp = th_zone->sensor_conf->read_temperature(data);
+	/* convert the temperature into millicelsius */
+	*temp = *temp * MCELSIUS;
+	return 0;
+}
+
+/* Get temperature callback functions for thermal zone */
+static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
+						unsigned long temp)
+{
+	void *data;
+	int ret = -EINVAL;
+
+	if (!th_zone->sensor_conf) {
+		pr_info("Temperature sensor not initialised\n");
+		return -EINVAL;
+	}
+	data = th_zone->sensor_conf->private_data;
+	if (th_zone->sensor_conf->write_emul_temp)
+		ret = th_zone->sensor_conf->write_emul_temp(data, temp);
+	return ret;
+}
+
+/* Get the temperature trend */
+static int exynos_get_trend(struct thermal_zone_device *thermal,
+			int trip, enum thermal_trend *trend)
+{
+	int ret;
+	unsigned long trip_temp;
+
+	ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
+	if (ret < 0)
+		return ret;
+
+	if (thermal->temperature >= trip_temp)
+		*trend = THERMAL_TREND_RAISE_FULL;
+	else
+		*trend = THERMAL_TREND_DROP_FULL;
+
+	return 0;
+}
+/* Operation callback functions for thermal zone */
+static struct thermal_zone_device_ops const exynos_dev_ops = {
+	.bind = exynos_bind,
+	.unbind = exynos_unbind,
+	.get_temp = exynos_get_temp,
+	.set_emul_temp = exynos_set_emul_temp,
+	.get_trend = exynos_get_trend,
+	.get_mode = exynos_get_mode,
+	.set_mode = exynos_set_mode,
+	.get_trip_type = exynos_get_trip_type,
+	.get_trip_temp = exynos_get_trip_temp,
+	.get_crit_temp = exynos_get_crit_temp,
+};
+
+/*
+ * This function may be called from interrupt based temperature sensor
+ * when threshold is changed.
+ */
+void exynos_report_trigger(void)
+{
+	unsigned int i;
+	char data[10];
+	char *envp[] = { data, NULL };
+
+	if (!th_zone || !th_zone->therm_dev)
+		return;
+	if (th_zone->bind == false) {
+		for (i = 0; i < th_zone->cool_dev_size; i++) {
+			if (!th_zone->cool_dev[i])
+				continue;
+			exynos_bind(th_zone->therm_dev,
+					th_zone->cool_dev[i]);
+		}
+	}
+
+	thermal_zone_device_update(th_zone->therm_dev);
+
+	mutex_lock(&th_zone->therm_dev->lock);
+	/* Find the level for which trip happened */
+	for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
+		if (th_zone->therm_dev->last_temperature <
+			th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
+			break;
+	}
+
+	if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
+		!th_zone->sensor_conf->trip_data.trigger_falling) {
+		if (i > 0)
+			th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
+		else
+			th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+	}
+
+	snprintf(data, sizeof(data), "%u", i);
+	kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
+	mutex_unlock(&th_zone->therm_dev->lock);
+}
+
+/* Register with the in-kernel thermal management */
+int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+{
+	int ret;
+	struct cpumask mask_val;
+
+	if (!sensor_conf || !sensor_conf->read_temperature) {
+		pr_err("Temperature sensor not initialised\n");
+		return -EINVAL;
+	}
+
+	th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
+	if (!th_zone)
+		return -ENOMEM;
+
+	th_zone->sensor_conf = sensor_conf;
+	cpumask_set_cpu(0, &mask_val);
+	th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
+	if (IS_ERR(th_zone->cool_dev[0])) {
+		pr_err("Failed to register cpufreq cooling device\n");
+		ret = -EINVAL;
+		goto err_unregister;
+	}
+	th_zone->cool_dev_size++;
+
+	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
+			EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
+			sensor_conf->trip_data.trigger_falling ?
+			0 : IDLE_INTERVAL);
+
+	if (IS_ERR(th_zone->therm_dev)) {
+		pr_err("Failed to register thermal zone device\n");
+		ret = PTR_ERR(th_zone->therm_dev);
+		goto err_unregister;
+	}
+	th_zone->mode = THERMAL_DEVICE_ENABLED;
+
+	pr_info("Exynos: Kernel Thermal management registered\n");
+
+	return 0;
+
+err_unregister:
+	exynos_unregister_thermal();
+	return ret;
+}
+
+/* Un-Register with the in-kernel thermal management */
+void exynos_unregister_thermal(void)
+{
+	int i;
+
+	if (!th_zone)
+		return;
+
+	if (th_zone->therm_dev)
+		thermal_zone_device_unregister(th_zone->therm_dev);
+
+	for (i = 0; i < th_zone->cool_dev_size; i++) {
+		if (th_zone->cool_dev[i])
+			cpufreq_cooling_unregister(th_zone->cool_dev[i]);
+	}
+
+	kfree(th_zone);
+	pr_info("Exynos: Kernel Thermal management unregistered\n");
+}
diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
new file mode 100644
index 0000000..165401f
--- /dev/null
+++ b/drivers/thermal/samsung/exynos_thermal_common.h
@@ -0,0 +1,71 @@
+/*
+ * exynos_thermal_common.h - Samsung EXYNOS common header file
+ *
+ *  Copyright (C) 2013 Samsung Electronics
+ *  Amit Daniel Kachhap <amit.daniel@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _LINUX_EXYNOS_THERMAL_COMMON_H
+#define _LINUX_EXYNOS_THERMAL_COMMON_H
+
+/* In-kernel thermal framework related macros & definations */
+#define SENSOR_NAME_LEN	16
+#define MAX_TRIP_COUNT	8
+#define MAX_COOLING_DEVICE 4
+#define MAX_THRESHOLD_LEVS 4
+
+#define ACTIVE_INTERVAL 500
+#define IDLE_INTERVAL 10000
+#define MCELSIUS	1000
+
+/* CPU Zone information */
+#define PANIC_ZONE      4
+#define WARN_ZONE       3
+#define MONITOR_ZONE    2
+#define SAFE_ZONE       1
+
+#define GET_ZONE(trip) (trip + 2)
+#define GET_TRIP(zone) (zone - 2)
+
+#define EXYNOS_ZONE_COUNT	3
+
+struct	thermal_trip_point_conf {
+	int trip_val[MAX_TRIP_COUNT];
+	int trip_count;
+	u8 trigger_falling;
+};
+
+struct	thermal_cooling_conf {
+	struct freq_clip_table freq_data[MAX_TRIP_COUNT];
+	int freq_clip_count;
+};
+
+struct thermal_sensor_conf {
+	char name[SENSOR_NAME_LEN];
+	int (*read_temperature)(void *data);
+	int (*write_emul_temp)(void *drv_data, unsigned long temp);
+	struct thermal_trip_point_conf trip_data;
+	struct thermal_cooling_conf cooling_data;
+	void *private_data;
+};
+
+/*Functions used exynos based thermal sensor driver*/
+void exynos_unregister_thermal(void);
+int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
+void exynos_report_trigger(void);
+#endif /* _LINUX_EXYNOS_THERMAL_COMMON_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 03/20] thermal: exynos: Rename exynos_thermal.c to exynos_tmu.c
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 02/20] thermal: exynos: Bifurcate exynos thermal common and tmu controller code Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-05-06 15:18   ` Zhang Rui
  2013-04-26 10:37 ` [PATCH V2 04/20] thermal: exynos: Move exynos_thermal.h from include/* to driver/* folder Amit Daniel Kachhap
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch renames exynos_thermal.c to exynos_tmu.c. This change is needed as
this file now just contains exynos tmu driver related codes and thermal zone
or cpufreq cooling registration related changes are not there anymore.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/Makefile                   |    2 +-
 .../samsung/{exynos_thermal.c => exynos_tmu.c}     |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
 rename drivers/thermal/samsung/{exynos_thermal.c => exynos_tmu.c} (99%)

diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
index fcda5b4..75e1f97 100644
--- a/drivers/thermal/samsung/Makefile
+++ b/drivers/thermal/samsung/Makefile
@@ -2,5 +2,5 @@
 # Samsung thermal specific Makefile
 #
 obj-$(CONFIG_EXYNOS_SOC_THERMAL)		+= exynos_soc_thermal.o
-exynos_soc_thermal-y				:= exynos_thermal.o
+exynos_soc_thermal-y				:= exynos_tmu.o
 exynos_soc_thermal-$(CONFIG_EXYNOS_COMMON)	+= exynos_thermal_common.o
diff --git a/drivers/thermal/samsung/exynos_thermal.c b/drivers/thermal/samsung/exynos_tmu.c
similarity index 99%
rename from drivers/thermal/samsung/exynos_thermal.c
rename to drivers/thermal/samsung/exynos_tmu.c
index 4c85945..3de3e61 100644
--- a/drivers/thermal/samsung/exynos_thermal.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -1,5 +1,5 @@
 /*
- * exynos_thermal.c - Samsung EXYNOS TMU (Thermal Management Unit)
+ * exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit)
  *
  *  Copyright (C) 2011 Samsung Electronics
  *  Donggeun Kim <dg77.kim@samsung.com>
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 04/20] thermal: exynos: Move exynos_thermal.h from include/* to driver/* folder
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (2 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 03/20] thermal: exynos: Rename exynos_thermal.c to exynos_tmu.c Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-05-06 15:19   ` Zhang Rui
  2013-04-26 10:37 ` [PATCH V2 05/20] thermal: exynos: Bifurcate exynos tmu driver and configuration data Amit Daniel Kachhap
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch renames and moves  include/linux/platform_data/exynos_thermal.h to
drivers/thermal/samsung/exynos_tmu.h. This file movement is needed as exynos
SOC's are not supporting non-DT based platforms. Also the rename is needed as this
file now just contains exynos tmu driver related definations.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_thermal_common.c    |    1 -
 drivers/thermal/samsung/exynos_thermal_common.h    |   15 +++++++++++++++
 drivers/thermal/samsung/exynos_tmu.c               |    2 +-
 .../thermal/samsung/exynos_tmu.h                   |   15 ---------------
 4 files changed, 16 insertions(+), 17 deletions(-)
 rename include/linux/platform_data/exynos_thermal.h => drivers/thermal/samsung/exynos_tmu.h (88%)

diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
index 9a57606..dae5476 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.c
+++ b/drivers/thermal/samsung/exynos_thermal_common.c
@@ -27,7 +27,6 @@
 #include <linux/kernel.h>
 #include <linux/kobject.h>
 #include <linux/mutex.h>
-#include <linux/platform_data/exynos_thermal.h>
 #include <linux/slab.h>
 #include <linux/thermal.h>
 #include "exynos_thermal_common.h"
diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
index 165401f..985b848 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.h
+++ b/drivers/thermal/samsung/exynos_thermal_common.h
@@ -44,6 +44,21 @@
 
 #define EXYNOS_ZONE_COUNT	3
 
+/**
+ * struct freq_clip_table
+ * @freq_clip_max: maximum frequency allowed for this cooling state.
+ * @temp_level: Temperature level at which the temperature clipping will
+ *	happen.
+ * @mask_val: cpumask of the allowed cpu's where the clipping will take place.
+ *
+ * This structure is required to be filled and passed to the
+ * cpufreq_cooling_unregister function.
+ */
+struct freq_clip_table {
+	unsigned int freq_clip_max;
+	unsigned int temp_level;
+	const struct cpumask *mask_val;
+};
 struct	thermal_trip_point_conf {
 	int trip_val[MAX_TRIP_COUNT];
 	int trip_count;
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 3de3e61..a02f2c9 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -30,10 +30,10 @@
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <linux/platform_data/exynos_thermal.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include "exynos_thermal_common.h"
+#include "exynos_tmu.h"
 
 /* Exynos generic registers */
 #define EXYNOS_TMU_REG_TRIMINFO		0x0
diff --git a/include/linux/platform_data/exynos_thermal.h b/drivers/thermal/samsung/exynos_tmu.h
similarity index 88%
rename from include/linux/platform_data/exynos_thermal.h
rename to drivers/thermal/samsung/exynos_tmu.h
index da7e627..342fb1f 100644
--- a/include/linux/platform_data/exynos_thermal.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -33,21 +33,6 @@ enum soc_type {
 	SOC_ARCH_EXYNOS4210 = 1,
 	SOC_ARCH_EXYNOS,
 };
-/**
- * struct freq_clip_table
- * @freq_clip_max: maximum frequency allowed for this cooling state.
- * @temp_level: Temperature level at which the temperature clipping will
- *	happen.
- * @mask_val: cpumask of the allowed cpu's where the clipping will take place.
- *
- * This structure is required to be filled and passed to the
- * cpufreq_cooling_unregister function.
- */
-struct freq_clip_table {
-	unsigned int freq_clip_max;
-	unsigned int temp_level;
-	const struct cpumask *mask_val;
-};
 
 /**
  * struct exynos_tmu_platform_data
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 05/20] thermal: exynos: Bifurcate exynos tmu driver and configuration data
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (3 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 04/20] thermal: exynos: Move exynos_thermal.h from include/* to driver/* folder Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-05-06 15:28   ` Zhang Rui
  2013-04-26 10:37 ` [PATCH V2 06/20] thermal: exynos: Add missing definations and code cleanup Amit Daniel Kachhap
                   ` (14 subsequent siblings)
  19 siblings, 1 reply; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This code splits the exynos tmu driver code into SOC specific data parts.
This will simplify adding new SOC specific data to the same TMU controller.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/Makefile                |    1 +
 drivers/thermal/samsung/exynos_thermal_common.h |    2 +-
 drivers/thermal/samsung/exynos_tmu.c            |   67 +------------------
 drivers/thermal/samsung/exynos_tmu_data.c       |   78 +++++++++++++++++++++++
 drivers/thermal/samsung/exynos_tmu_data.h       |   40 ++++++++++++
 5 files changed, 124 insertions(+), 64 deletions(-)
 create mode 100644 drivers/thermal/samsung/exynos_tmu_data.c
 create mode 100644 drivers/thermal/samsung/exynos_tmu_data.h

diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
index 75e1f97..b133255 100644
--- a/drivers/thermal/samsung/Makefile
+++ b/drivers/thermal/samsung/Makefile
@@ -3,4 +3,5 @@
 #
 obj-$(CONFIG_EXYNOS_SOC_THERMAL)		+= exynos_soc_thermal.o
 exynos_soc_thermal-y				:= exynos_tmu.o
+exynos_soc_thermal-y				+= exynos_tmu_data.o
 exynos_soc_thermal-$(CONFIG_EXYNOS_COMMON)	+= exynos_thermal_common.o
diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
index 985b848..6ed9bd9 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.h
+++ b/drivers/thermal/samsung/exynos_thermal_common.h
@@ -62,7 +62,7 @@ struct freq_clip_table {
 struct	thermal_trip_point_conf {
 	int trip_val[MAX_TRIP_COUNT];
 	int trip_count;
-	u8 trigger_falling;
+	unsigned char trigger_falling;
 };
 
 struct	thermal_cooling_conf {
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index a02f2c9..05b5068 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -34,6 +34,7 @@
 #include <linux/workqueue.h>
 #include "exynos_thermal_common.h"
 #include "exynos_tmu.h"
+#include "exynos_tmu_data.h"
 
 /* Exynos generic registers */
 #define EXYNOS_TMU_REG_TRIMINFO		0x0
@@ -385,66 +386,6 @@ static struct thermal_sensor_conf exynos_sensor_conf = {
 	.write_emul_temp	= exynos_tmu_set_emulation,
 };
 
-#if defined(CONFIG_CPU_EXYNOS4210)
-static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
-	.threshold = 80,
-	.trigger_levels[0] = 5,
-	.trigger_levels[1] = 20,
-	.trigger_levels[2] = 30,
-	.trigger_level0_en = 1,
-	.trigger_level1_en = 1,
-	.trigger_level2_en = 1,
-	.trigger_level3_en = 0,
-	.gain = 15,
-	.reference_voltage = 7,
-	.cal_type = TYPE_ONE_POINT_TRIMMING,
-	.freq_tab[0] = {
-		.freq_clip_max = 800 * 1000,
-		.temp_level = 85,
-	},
-	.freq_tab[1] = {
-		.freq_clip_max = 200 * 1000,
-		.temp_level = 100,
-	},
-	.freq_tab_count = 2,
-	.type = SOC_ARCH_EXYNOS4210,
-};
-#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
-#else
-#define EXYNOS4210_TMU_DRV_DATA (NULL)
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
-static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
-	.threshold_falling = 10,
-	.trigger_levels[0] = 85,
-	.trigger_levels[1] = 103,
-	.trigger_levels[2] = 110,
-	.trigger_level0_en = 1,
-	.trigger_level1_en = 1,
-	.trigger_level2_en = 1,
-	.trigger_level3_en = 0,
-	.gain = 8,
-	.reference_voltage = 16,
-	.noise_cancel_mode = 4,
-	.cal_type = TYPE_ONE_POINT_TRIMMING,
-	.efuse_value = 55,
-	.freq_tab[0] = {
-		.freq_clip_max = 800 * 1000,
-		.temp_level = 85,
-	},
-	.freq_tab[1] = {
-		.freq_clip_max = 200 * 1000,
-		.temp_level = 103,
-	},
-	.freq_tab_count = 2,
-	.type = SOC_ARCH_EXYNOS,
-};
-#define EXYNOS_TMU_DRV_DATA (&exynos_default_tmu_data)
-#else
-#define EXYNOS_TMU_DRV_DATA (NULL)
-#endif
-
 #ifdef CONFIG_OF
 static const struct of_device_id exynos_tmu_match[] = {
 	{
@@ -453,11 +394,11 @@ static const struct of_device_id exynos_tmu_match[] = {
 	},
 	{
 		.compatible = "samsung,exynos4412-tmu",
-		.data = (void *)EXYNOS_TMU_DRV_DATA,
+		.data = (void *)EXYNOS5250_TMU_DRV_DATA,
 	},
 	{
 		.compatible = "samsung,exynos5250-tmu",
-		.data = (void *)EXYNOS_TMU_DRV_DATA,
+		.data = (void *)EXYNOS5250_TMU_DRV_DATA,
 	},
 	{},
 };
@@ -471,7 +412,7 @@ static struct platform_device_id exynos_tmu_driver_ids[] = {
 	},
 	{
 		.name		= "exynos5250-tmu",
-		.driver_data    = (kernel_ulong_t)EXYNOS_TMU_DRV_DATA,
+		.driver_data    = (kernel_ulong_t)EXYNOS5250_TMU_DRV_DATA,
 	},
 	{ },
 };
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
new file mode 100644
index 0000000..13a60ca
--- /dev/null
+++ b/drivers/thermal/samsung/exynos_tmu_data.c
@@ -0,0 +1,78 @@
+/*
+ * exynos_tmu_data.c - Samsung EXYNOS tmu data file
+ *
+ *  Copyright (C) 2013 Samsung Electronics
+ *  Amit Daniel Kachhap <amit.daniel@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "exynos_thermal_common.h"
+#include "exynos_tmu.h"
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+	.threshold = 80,
+	.trigger_levels[0] = 5,
+	.trigger_levels[1] = 20,
+	.trigger_levels[2] = 30,
+	.trigger_level0_en = 1,
+	.trigger_level1_en = 1,
+	.trigger_level2_en = 1,
+	.trigger_level3_en = 0,
+	.gain = 15,
+	.reference_voltage = 7,
+	.cal_type = TYPE_ONE_POINT_TRIMMING,
+	.freq_tab[0] = {
+		.freq_clip_max = 800 * 1000,
+		.temp_level = 85,
+	},
+	.freq_tab[1] = {
+		.freq_clip_max = 200 * 1000,
+		.temp_level = 100,
+	},
+	.freq_tab_count = 2,
+	.type = SOC_ARCH_EXYNOS4210,
+};
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
+struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
+	.threshold_falling = 10,
+	.trigger_levels[0] = 85,
+	.trigger_levels[1] = 103,
+	.trigger_levels[2] = 110,
+	.trigger_level0_en = 1,
+	.trigger_level1_en = 1,
+	.trigger_level2_en = 1,
+	.trigger_level3_en = 0,
+	.gain = 8,
+	.reference_voltage = 16,
+	.noise_cancel_mode = 4,
+	.cal_type = TYPE_ONE_POINT_TRIMMING,
+	.efuse_value = 55,
+	.freq_tab[0] = {
+		.freq_clip_max = 800 * 1000,
+		.temp_level = 85,
+	},
+	.freq_tab[1] = {
+		.freq_clip_max = 200 * 1000,
+		.temp_level = 103,
+	},
+	.freq_tab_count = 2,
+	.type = SOC_ARCH_EXYNOS,
+};
+#endif
diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
new file mode 100644
index 0000000..c8b0501
--- /dev/null
+++ b/drivers/thermal/samsung/exynos_tmu_data.h
@@ -0,0 +1,40 @@
+/*
+ * exynos_tmu_data.h - Samsung EXYNOS tmu data header file
+ *
+ *  Copyright (C) 2013 Samsung Electronics
+ *  Amit Daniel Kachhap <amit.daniel@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _LINUX_EXYNOS_TMU_DATA_H
+#define _LINUX_EXYNOS_TMU_DATA_H
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+extern struct exynos_tmu_platform_data const exynos4210_default_tmu_data;
+#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
+#else
+#define EXYNOS4210_TMU_DRV_DATA (NULL)
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
+extern struct exynos_tmu_platform_data const exynos5250_default_tmu_data;
+#define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data)
+#else
+#define EXYNOS5250_TMU_DRV_DATA (NULL)
+#endif
+
+#endif /*_LINUX_EXYNOS_TMU_DATA_H*/
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 06/20] thermal: exynos: Add missing definations and code cleanup
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (4 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 05/20] thermal: exynos: Bifurcate exynos tmu driver and configuration data Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 07/20] thermal: exynos: Add extra entries in the tmu platform data Amit Daniel Kachhap
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch adds some extra register bitfield definations and cleans
up the code to prepare for moving register macros and definations inside
the TMU data section.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_tmu.c |   62 +++++++++++++++++++++++++---------
 1 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 05b5068..a43afc4 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -47,9 +47,12 @@
 
 #define EXYNOS_TMU_TRIM_TEMP_MASK	0xff
 #define EXYNOS_TMU_GAIN_SHIFT		8
+#define EXYNOS_TMU_GAIN_MASK		0xf
 #define EXYNOS_TMU_REF_VOLTAGE_SHIFT	24
-#define EXYNOS_TMU_CORE_ON		3
-#define EXYNOS_TMU_CORE_OFF		2
+#define EXYNOS_TMU_REF_VOLTAGE_MASK	0x1f
+#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK	0xf
+#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT	8
+#define EXYNOS_TMU_CORE_EN_SHIFT	0
 #define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET	50
 
 /* Exynos4210 specific registers */
@@ -67,6 +70,7 @@
 #define EXYNOS4210_TMU_TRIG_LEVEL1_MASK	0x10
 #define EXYNOS4210_TMU_TRIG_LEVEL2_MASK	0x100
 #define EXYNOS4210_TMU_TRIG_LEVEL3_MASK	0x1000
+#define EXYNOS4210_TMU_TRIG_LEVEL_MASK	0x1111
 #define EXYNOS4210_TMU_INTCLEAR_VAL	0x1111
 
 /* Exynos5250 and Exynos4412 specific registers */
@@ -76,17 +80,30 @@
 #define EXYNOS_EMUL_CON		0x80
 
 #define EXYNOS_TRIMINFO_RELOAD		0x1
+#define EXYNOS_TRIMINFO_SHIFT		0x0
+#define EXYNOS_TMU_RISE_INT_MASK	0x111
+#define EXYNOS_TMU_RISE_INT_SHIFT	0
+#define EXYNOS_TMU_FALL_INT_MASK	0x111
+#define EXYNOS_TMU_FALL_INT_SHIFT	12
 #define EXYNOS_TMU_CLEAR_RISE_INT	0x111
 #define EXYNOS_TMU_CLEAR_FALL_INT	(0x111 << 12)
-#define EXYNOS_MUX_ADDR_VALUE		6
-#define EXYNOS_MUX_ADDR_SHIFT		20
 #define EXYNOS_TMU_TRIP_MODE_SHIFT	13
+#define EXYNOS_TMU_TRIP_MODE_MASK	0x7
+
+#define EXYNOS_TMU_INTEN_RISE0_SHIFT	0
+#define EXYNOS_TMU_INTEN_RISE1_SHIFT	4
+#define EXYNOS_TMU_INTEN_RISE2_SHIFT	8
+#define EXYNOS_TMU_INTEN_RISE3_SHIFT	12
+#define EXYNOS_TMU_INTEN_FALL0_SHIFT	16
+#define EXYNOS_TMU_INTEN_FALL1_SHIFT	20
+#define EXYNOS_TMU_INTEN_FALL2_SHIFT	24
 
 #define EFUSE_MIN_VALUE 40
 #define EFUSE_MAX_VALUE 100
 
 #ifdef CONFIG_THERMAL_EMULATION
 #define EXYNOS_EMUL_TIME	0x57F0
+#define EXYNOS_EMUL_TIME_MASK	0xffff
 #define EXYNOS_EMUL_TIME_SHIFT	16
 #define EXYNOS_EMUL_DATA_SHIFT	8
 #define EXYNOS_EMUL_DATA_MASK	0xFF
@@ -265,24 +282,37 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
-	con = pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT |
-		pdata->gain << EXYNOS_TMU_GAIN_SHIFT;
+	con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
 
-	if (data->soc == SOC_ARCH_EXYNOS) {
-		con |= pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT;
-		con |= (EXYNOS_MUX_ADDR_VALUE << EXYNOS_MUX_ADDR_SHIFT);
+	if (pdata->reference_voltage) {
+		con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK <<
+				EXYNOS_TMU_REF_VOLTAGE_SHIFT);
+		con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
+	}
+
+	if (pdata->gain) {
+		con &= ~(EXYNOS_TMU_GAIN_MASK << EXYNOS_TMU_GAIN_SHIFT);
+		con |= (pdata->gain << EXYNOS_TMU_GAIN_SHIFT);
+	}
+
+	if (pdata->noise_cancel_mode) {
+		con &= ~(EXYNOS_TMU_TRIP_MODE_MASK <<
+					EXYNOS_TMU_TRIP_MODE_SHIFT);
+		con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT);
 	}
 
 	if (on) {
-		con |= EXYNOS_TMU_CORE_ON;
-		interrupt_en = pdata->trigger_level3_en << 12 |
-			pdata->trigger_level2_en << 8 |
-			pdata->trigger_level1_en << 4 |
-			pdata->trigger_level0_en;
+		con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
+		interrupt_en =
+		pdata->trigger_level3_en << EXYNOS_TMU_INTEN_RISE3_SHIFT |
+		pdata->trigger_level2_en << EXYNOS_TMU_INTEN_RISE2_SHIFT |
+		pdata->trigger_level1_en << EXYNOS_TMU_INTEN_RISE1_SHIFT |
+		pdata->trigger_level0_en << EXYNOS_TMU_INTEN_RISE0_SHIFT;
 		if (pdata->threshold_falling)
-			interrupt_en |= interrupt_en << 16;
+			interrupt_en |=
+				interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
 	} else {
-		con |= EXYNOS_TMU_CORE_OFF;
+		con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
 		interrupt_en = 0; /* Disable all interrupts */
 	}
 	writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 07/20] thermal: exynos: Add extra entries in the tmu platform data
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (5 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 06/20] thermal: exynos: Add missing definations and code cleanup Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 08/20] thermal: exynos: Support thermal tripping Amit Daniel Kachhap
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch adds entries min_efuse_value, max_efuse_value, default_temp_offset,
trigger_type, cal_type, trim_first_point, trim_second_point and
trigger_enable in the TMU platform data structure. Also the driver is modified
to use the data passed by these new platform memebers instead of the constant
macros. All these changes helps in separating the SOC specific data part from
the TMU driver.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_tmu.c      |   43 +++++++++++------------
 drivers/thermal/samsung/exynos_tmu.h      |   52 +++++++++++++++++++----------
 drivers/thermal/samsung/exynos_tmu_data.c |   33 ++++++++++++++----
 3 files changed, 80 insertions(+), 48 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index a43afc4..77b6a37 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -53,7 +53,6 @@
 #define EXYNOS_TMU_BUF_SLOPE_SEL_MASK	0xf
 #define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT	8
 #define EXYNOS_TMU_CORE_EN_SHIFT	0
-#define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET	50
 
 /* Exynos4210 specific registers */
 #define EXYNOS4210_TMU_REG_THRESHOLD_TEMP	0x44
@@ -98,9 +97,6 @@
 #define EXYNOS_TMU_INTEN_FALL1_SHIFT	20
 #define EXYNOS_TMU_INTEN_FALL2_SHIFT	24
 
-#define EFUSE_MIN_VALUE 40
-#define EFUSE_MAX_VALUE 100
-
 #ifdef CONFIG_THERMAL_EMULATION
 #define EXYNOS_EMUL_TIME	0x57F0
 #define EXYNOS_EMUL_TIME_MASK	0xffff
@@ -140,15 +136,16 @@ static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
 
 	switch (pdata->cal_type) {
 	case TYPE_TWO_POINT_TRIMMING:
-		temp_code = (temp - 25) *
-		    (data->temp_error2 - data->temp_error1) /
-		    (85 - 25) + data->temp_error1;
+		temp_code = (temp - pdata->first_point_trim) *
+			(data->temp_error2 - data->temp_error1) /
+			(pdata->second_point_trim - pdata->first_point_trim) +
+			data->temp_error1;
 		break;
 	case TYPE_ONE_POINT_TRIMMING:
-		temp_code = temp + data->temp_error1 - 25;
+		temp_code = temp + data->temp_error1 - pdata->first_point_trim;
 		break;
 	default:
-		temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
+		temp_code = temp + pdata->default_temp_offset;
 		break;
 	}
 out:
@@ -173,14 +170,16 @@ static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
 
 	switch (pdata->cal_type) {
 	case TYPE_TWO_POINT_TRIMMING:
-		temp = (temp_code - data->temp_error1) * (85 - 25) /
-		    (data->temp_error2 - data->temp_error1) + 25;
+		temp = (temp_code - data->temp_error1) *
+			(pdata->second_point_trim - pdata->first_point_trim) /
+			(data->temp_error2 - data->temp_error1) +
+			pdata->first_point_trim;
 		break;
 	case TYPE_ONE_POINT_TRIMMING:
-		temp = temp_code - data->temp_error1 + 25;
+		temp = temp_code - data->temp_error1 + pdata->first_point_trim;
 		break;
 	default:
-		temp = temp_code - EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
+		temp = temp_code - pdata->default_temp_offset;
 		break;
 	}
 out:
@@ -213,8 +212,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 	data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
 	data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
 
-	if ((EFUSE_MIN_VALUE > data->temp_error1) ||
-			(data->temp_error1 > EFUSE_MAX_VALUE) ||
+	if ((pdata->min_efuse_value > data->temp_error1) ||
+			(data->temp_error1 > pdata->max_efuse_value) ||
 			(data->temp_error2 != 0))
 		data->temp_error1 = pdata->efuse_value;
 
@@ -304,10 +303,10 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
 	if (on) {
 		con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
 		interrupt_en =
-		pdata->trigger_level3_en << EXYNOS_TMU_INTEN_RISE3_SHIFT |
-		pdata->trigger_level2_en << EXYNOS_TMU_INTEN_RISE2_SHIFT |
-		pdata->trigger_level1_en << EXYNOS_TMU_INTEN_RISE1_SHIFT |
-		pdata->trigger_level0_en << EXYNOS_TMU_INTEN_RISE0_SHIFT;
+		pdata->trigger_enable[3] << EXYNOS_TMU_INTEN_RISE3_SHIFT |
+		pdata->trigger_enable[2] << EXYNOS_TMU_INTEN_RISE2_SHIFT |
+		pdata->trigger_enable[1] << EXYNOS_TMU_INTEN_RISE1_SHIFT |
+		pdata->trigger_enable[0] << EXYNOS_TMU_INTEN_RISE0_SHIFT;
 		if (pdata->threshold_falling)
 			interrupt_en |=
 				interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
@@ -542,9 +541,9 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 
 	/* Register the sensor with thermal management interface */
 	(&exynos_sensor_conf)->private_data = data;
-	exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
-			pdata->trigger_level1_en + pdata->trigger_level2_en +
-			pdata->trigger_level3_en;
+	exynos_sensor_conf.trip_data.trip_count = pdata->trigger_enable[0] +
+			pdata->trigger_enable[1] + pdata->trigger_enable[2]+
+			pdata->trigger_enable[3];
 
 	for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
 		exynos_sensor_conf.trip_data.trip_val[i] =
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
index 342fb1f..70cc518 100644
--- a/drivers/thermal/samsung/exynos_tmu.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -29,6 +29,17 @@ enum calibration_type {
 	TYPE_NONE,
 };
 
+enum calibration_mode {
+	SW_MODE,
+	HW_MODE,
+};
+
+enum trigger_type {
+	THROTTLE,
+	SW_TRIP,
+	HW_TRIP,
+};
+
 enum soc_type {
 	SOC_ARCH_EXYNOS4210 = 1,
 	SOC_ARCH_EXYNOS,
@@ -54,18 +65,13 @@ enum soc_type {
  *	3: temperature for trigger_level3 interrupt
  *	   condition for trigger_level3 interrupt:
  *		current temperature > threshold + trigger_levels[3]
- * @trigger_level0_en:
- *	1 = enable trigger_level0 interrupt,
- *	0 = disable trigger_level0 interrupt
- * @trigger_level1_en:
- *	1 = enable trigger_level1 interrupt,
- *	0 = disable trigger_level1 interrupt
- * @trigger_level2_en:
- *	1 = enable trigger_level2 interrupt,
- *	0 = disable trigger_level2 interrupt
- * @trigger_level3_en:
- *	1 = enable trigger_level3 interrupt,
- *	0 = disable trigger_level3 interrupt
+ * @trigger_type: defines the type of trigger. Possible values are,
+ *	0: THROTTLE trigger type
+ *	1: SW_TRIP trigger type
+ *	2: HW_TRIP
+ * @trigger_enable[]: array to denote which trigger levels are enabled.
+ *	1 = enable trigger_level[] interrupt,
+ *	0 = disable trigger_level[] interrupt
  * @gain: gain of amplifier in the positive-TC generator block
  *	0 <= gain <= 15
  * @reference_voltage: reference voltage of amplifier
@@ -75,7 +81,13 @@ enum soc_type {
  *	000, 100, 101, 110 and 111 can be different modes
  * @type: determines the type of SOC
  * @efuse_value: platform defined fuse value
+ * @min_efuse_value: minimum valid trimming data
+ * @max_efuse_value: maximum valid trimming data
+ * @first_point_trim: temp value of the first point trimming
+ * @second_point_trim: temp value of the second point trimming
+ * @default_temp_offset: default temperature offset in case of no trimming
  * @cal_type: calibration type for temperature
+ * @cal_mode: calibration mode for temperature
  * @freq_clip_table: Table representing frequency reduction percentage.
  * @freq_tab_count: Count of the above table as frequency reduction may
  *	applicable to only some of the trigger levels.
@@ -85,18 +97,22 @@ enum soc_type {
 struct exynos_tmu_platform_data {
 	u8 threshold;
 	u8 threshold_falling;
-	u8 trigger_levels[4];
-	bool trigger_level0_en;
-	bool trigger_level1_en;
-	bool trigger_level2_en;
-	bool trigger_level3_en;
-
+	u8 trigger_levels[MAX_TRIP_COUNT];
+	enum trigger_type trigger_type[MAX_TRIP_COUNT];
+	bool trigger_enable[MAX_TRIP_COUNT];
 	u8 gain;
 	u8 reference_voltage;
 	u8 noise_cancel_mode;
+
 	u32 efuse_value;
+	u32 min_efuse_value;
+	u32 max_efuse_value;
+	u8 first_point_trim;
+	u8 second_point_trim;
+	u8 default_temp_offset;
 
 	enum calibration_type cal_type;
+	enum calibration_mode cal_mode;
 	enum soc_type type;
 	struct freq_clip_table freq_tab[4];
 	unsigned int freq_tab_count;
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
index 13a60ca..ee6a3c9 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.c
+++ b/drivers/thermal/samsung/exynos_tmu_data.c
@@ -22,6 +22,7 @@
 
 #include "exynos_thermal_common.h"
 #include "exynos_tmu.h"
+#include "exynos_tmu_data.h"
 
 #if defined(CONFIG_CPU_EXYNOS4210)
 struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
@@ -29,13 +30,21 @@ struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
 	.trigger_levels[0] = 5,
 	.trigger_levels[1] = 20,
 	.trigger_levels[2] = 30,
-	.trigger_level0_en = 1,
-	.trigger_level1_en = 1,
-	.trigger_level2_en = 1,
-	.trigger_level3_en = 0,
+	.trigger_enable[0] = 1,
+	.trigger_enable[1] = 1,
+	.trigger_enable[2] = 1,
+	.trigger_enable[3] = 0,
+	.trigger_type[0] = 0,
+	.trigger_type[1] = 0,
+	.trigger_type[2] = 1,
 	.gain = 15,
 	.reference_voltage = 7,
 	.cal_type = TYPE_ONE_POINT_TRIMMING,
+	.min_efuse_value = 40,
+	.max_efuse_value = 100,
+	.first_point_trim = 25,
+	.second_point_trim = 85,
+	.default_temp_offset = 50,
 	.freq_tab[0] = {
 		.freq_clip_max = 800 * 1000,
 		.temp_level = 85,
@@ -55,15 +64,23 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
 	.trigger_levels[0] = 85,
 	.trigger_levels[1] = 103,
 	.trigger_levels[2] = 110,
-	.trigger_level0_en = 1,
-	.trigger_level1_en = 1,
-	.trigger_level2_en = 1,
-	.trigger_level3_en = 0,
+	.trigger_enable[0] = 1,
+	.trigger_enable[1] = 1,
+	.trigger_enable[2] = 1,
+	.trigger_enable[3] = 0,
+	.trigger_type[0] = 0,
+	.trigger_type[1] = 0,
+	.trigger_type[2] = 1,
 	.gain = 8,
 	.reference_voltage = 16,
 	.noise_cancel_mode = 4,
 	.cal_type = TYPE_ONE_POINT_TRIMMING,
 	.efuse_value = 55,
+	.min_efuse_value = 40,
+	.max_efuse_value = 100,
+	.first_point_trim = 25,
+	.second_point_trim = 85,
+	.default_temp_offset = 50,
 	.freq_tab[0] = {
 		.freq_clip_max = 800 * 1000,
 		.temp_level = 85,
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 08/20] thermal: exynos: Support thermal tripping
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (6 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 07/20] thermal: exynos: Add extra entries in the tmu platform data Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 09/20] thermal: exynos: Move register definitions from driver file to data file Amit Daniel Kachhap
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

TMU urgently sends active-high signal (thermal trip) to PMU, and thermal
tripping by hardware logic. Thermal tripping means that PMU cuts off the
whole power of SoC by controlling external voltage regulator.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Jonghwan Choi <jhbird.choi@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_tmu.c      |    8 +++++++-
 drivers/thermal/samsung/exynos_tmu_data.c |    2 ++
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 77b6a37..23baeeb 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -88,6 +88,7 @@
 #define EXYNOS_TMU_CLEAR_FALL_INT	(0x111 << 12)
 #define EXYNOS_TMU_TRIP_MODE_SHIFT	13
 #define EXYNOS_TMU_TRIP_MODE_MASK	0x7
+#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT	12
 
 #define EXYNOS_TMU_INTEN_RISE0_SHIFT	0
 #define EXYNOS_TMU_INTEN_RISE1_SHIFT	4
@@ -190,7 +191,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 {
 	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 	struct exynos_tmu_platform_data *pdata = data->pdata;
-	unsigned int status, trim_info;
+	unsigned int status, trim_info, con;
 	unsigned int rising_threshold = 0, falling_threshold = 0;
 	int ret = 0, threshold_code, i, trigger_levs = 0;
 
@@ -255,6 +256,11 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 					falling_threshold |=
 						threshold_code << 8 * i;
 			}
+			if (pdata->trigger_type[i] != HW_TRIP)
+				continue;
+			con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
+			con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT);
+			writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
 		}
 
 		writel(rising_threshold,
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
index ee6a3c9..6b937f5 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.c
+++ b/drivers/thermal/samsung/exynos_tmu_data.c
@@ -64,6 +64,7 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
 	.trigger_levels[0] = 85,
 	.trigger_levels[1] = 103,
 	.trigger_levels[2] = 110,
+	.trigger_levels[3] = 120,
 	.trigger_enable[0] = 1,
 	.trigger_enable[1] = 1,
 	.trigger_enable[2] = 1,
@@ -71,6 +72,7 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
 	.trigger_type[0] = 0,
 	.trigger_type[1] = 0,
 	.trigger_type[2] = 1,
+	.trigger_type[3] = 2,
 	.gain = 8,
 	.reference_voltage = 16,
 	.noise_cancel_mode = 4,
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 09/20] thermal: exynos: Move register definitions from driver file to data file
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (7 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 08/20] thermal: exynos: Support thermal tripping Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 10/20] thermal: exynos: Fix to clear only the generated interrupts Amit Daniel Kachhap
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch migrates the TMU register definition/bitfields to data file. This
is needed to support SoC's which use the same TMU controller but register
validity, offsets or bitfield may slightly vary across SOC's.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_tmu.c      |  177 +++++++++-------------------
 drivers/thermal/samsung/exynos_tmu.h      |   76 ++++++++++++
 drivers/thermal/samsung/exynos_tmu_data.c |   59 ++++++++++
 drivers/thermal/samsung/exynos_tmu_data.h |   70 +++++++++++
 4 files changed, 262 insertions(+), 120 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 23baeeb..97b87aa 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -36,77 +36,6 @@
 #include "exynos_tmu.h"
 #include "exynos_tmu_data.h"
 
-/* Exynos generic registers */
-#define EXYNOS_TMU_REG_TRIMINFO		0x0
-#define EXYNOS_TMU_REG_CONTROL		0x20
-#define EXYNOS_TMU_REG_STATUS		0x28
-#define EXYNOS_TMU_REG_CURRENT_TEMP	0x40
-#define EXYNOS_TMU_REG_INTEN		0x70
-#define EXYNOS_TMU_REG_INTSTAT		0x74
-#define EXYNOS_TMU_REG_INTCLEAR		0x78
-
-#define EXYNOS_TMU_TRIM_TEMP_MASK	0xff
-#define EXYNOS_TMU_GAIN_SHIFT		8
-#define EXYNOS_TMU_GAIN_MASK		0xf
-#define EXYNOS_TMU_REF_VOLTAGE_SHIFT	24
-#define EXYNOS_TMU_REF_VOLTAGE_MASK	0x1f
-#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK	0xf
-#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT	8
-#define EXYNOS_TMU_CORE_EN_SHIFT	0
-
-/* Exynos4210 specific registers */
-#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP	0x44
-#define EXYNOS4210_TMU_REG_TRIG_LEVEL0	0x50
-#define EXYNOS4210_TMU_REG_TRIG_LEVEL1	0x54
-#define EXYNOS4210_TMU_REG_TRIG_LEVEL2	0x58
-#define EXYNOS4210_TMU_REG_TRIG_LEVEL3	0x5C
-#define EXYNOS4210_TMU_REG_PAST_TEMP0	0x60
-#define EXYNOS4210_TMU_REG_PAST_TEMP1	0x64
-#define EXYNOS4210_TMU_REG_PAST_TEMP2	0x68
-#define EXYNOS4210_TMU_REG_PAST_TEMP3	0x6C
-
-#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK	0x1
-#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK	0x10
-#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK	0x100
-#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK	0x1000
-#define EXYNOS4210_TMU_TRIG_LEVEL_MASK	0x1111
-#define EXYNOS4210_TMU_INTCLEAR_VAL	0x1111
-
-/* Exynos5250 and Exynos4412 specific registers */
-#define EXYNOS_TMU_TRIMINFO_CON	0x14
-#define EXYNOS_THD_TEMP_RISE		0x50
-#define EXYNOS_THD_TEMP_FALL		0x54
-#define EXYNOS_EMUL_CON		0x80
-
-#define EXYNOS_TRIMINFO_RELOAD		0x1
-#define EXYNOS_TRIMINFO_SHIFT		0x0
-#define EXYNOS_TMU_RISE_INT_MASK	0x111
-#define EXYNOS_TMU_RISE_INT_SHIFT	0
-#define EXYNOS_TMU_FALL_INT_MASK	0x111
-#define EXYNOS_TMU_FALL_INT_SHIFT	12
-#define EXYNOS_TMU_CLEAR_RISE_INT	0x111
-#define EXYNOS_TMU_CLEAR_FALL_INT	(0x111 << 12)
-#define EXYNOS_TMU_TRIP_MODE_SHIFT	13
-#define EXYNOS_TMU_TRIP_MODE_MASK	0x7
-#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT	12
-
-#define EXYNOS_TMU_INTEN_RISE0_SHIFT	0
-#define EXYNOS_TMU_INTEN_RISE1_SHIFT	4
-#define EXYNOS_TMU_INTEN_RISE2_SHIFT	8
-#define EXYNOS_TMU_INTEN_RISE3_SHIFT	12
-#define EXYNOS_TMU_INTEN_FALL0_SHIFT	16
-#define EXYNOS_TMU_INTEN_FALL1_SHIFT	20
-#define EXYNOS_TMU_INTEN_FALL2_SHIFT	24
-
-#ifdef CONFIG_THERMAL_EMULATION
-#define EXYNOS_EMUL_TIME	0x57F0
-#define EXYNOS_EMUL_TIME_MASK	0xffff
-#define EXYNOS_EMUL_TIME_SHIFT	16
-#define EXYNOS_EMUL_DATA_SHIFT	8
-#define EXYNOS_EMUL_DATA_MASK	0xFF
-#define EXYNOS_EMUL_ENABLE	0x1
-#endif /* CONFIG_THERMAL_EMULATION */
-
 struct exynos_tmu_data {
 	struct exynos_tmu_platform_data *pdata;
 	struct resource *mem;
@@ -191,6 +120,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 {
 	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 	struct exynos_tmu_platform_data *pdata = data->pdata;
+	struct exynos_tmu_registers *reg = pdata->registers;
 	unsigned int status, trim_info, con;
 	unsigned int rising_threshold = 0, falling_threshold = 0;
 	int ret = 0, threshold_code, i, trigger_levs = 0;
@@ -198,20 +128,20 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
-	status = readb(data->base + EXYNOS_TMU_REG_STATUS);
+	status = readb(data->base + reg->tmu_status);
 	if (!status) {
 		ret = -EBUSY;
 		goto out;
 	}
 
-	if (data->soc == SOC_ARCH_EXYNOS) {
-		__raw_writel(EXYNOS_TRIMINFO_RELOAD,
-				data->base + EXYNOS_TMU_TRIMINFO_CON);
-	}
+	if (data->soc == SOC_ARCH_EXYNOS)
+		__raw_writel(1, data->base + reg->triminfo_ctrl);
+
 	/* Save trimming info in order to perform calibration */
-	trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
-	data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
-	data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
+	trim_info = readl(data->base + reg->triminfo_data);
+	data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK;
+	data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) &
+				EXYNOS_TMU_TEMP_MASK);
 
 	if ((pdata->min_efuse_value > data->temp_error1) ||
 			(data->temp_error1 > pdata->max_efuse_value) ||
@@ -231,13 +161,12 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 			goto out;
 		}
 		writeb(threshold_code,
-			data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
+			data->base + reg->threshold_temp);
 		for (i = 0; i < trigger_levs; i++)
 			writeb(pdata->trigger_levels[i],
-			data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
+			data->base + reg->threshold_th0 + i * 4);
 
-		writel(EXYNOS4210_TMU_INTCLEAR_VAL,
-			data->base + EXYNOS_TMU_REG_INTCLEAR);
+		writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
 	} else if (data->soc == SOC_ARCH_EXYNOS) {
 		/* Write temperature code for rising and falling threshold */
 		for (i = 0; i < trigger_levs; i++) {
@@ -258,18 +187,19 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 			}
 			if (pdata->trigger_type[i] != HW_TRIP)
 				continue;
-			con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
-			con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT);
-			writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
+			con = readl(data->base + reg->tmu_ctrl);
+			con |= (1 << reg->therm_trip_en_shift);
+			writel(con, data->base + reg->tmu_ctrl);
 		}
 
 		writel(rising_threshold,
-				data->base + EXYNOS_THD_TEMP_RISE);
+				data->base + reg->threshold_th0);
 		writel(falling_threshold,
-				data->base + EXYNOS_THD_TEMP_FALL);
+				data->base + reg->threshold_th1);
 
-		writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT,
-				data->base + EXYNOS_TMU_REG_INTCLEAR);
+		writel((reg->inten_rise_mask << reg->inten_rise_shift) |
+			(reg->inten_fall_mask << reg->inten_fall_shift),
+				data->base + reg->tmu_intclear);
 	}
 out:
 	clk_disable(data->clk);
@@ -282,46 +212,46 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
 {
 	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 	struct exynos_tmu_platform_data *pdata = data->pdata;
+	struct exynos_tmu_registers *reg = pdata->registers;
 	unsigned int con, interrupt_en;
 
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
-	con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
+	con = readl(data->base + reg->tmu_ctrl);
 
 	if (pdata->reference_voltage) {
-		con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK <<
-				EXYNOS_TMU_REF_VOLTAGE_SHIFT);
-		con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
+		con &= ~(reg->buf_vref_sel_mask << reg->buf_vref_sel_shift);
+		con |= pdata->reference_voltage << reg->buf_vref_sel_shift;
 	}
 
 	if (pdata->gain) {
-		con &= ~(EXYNOS_TMU_GAIN_MASK << EXYNOS_TMU_GAIN_SHIFT);
-		con |= (pdata->gain << EXYNOS_TMU_GAIN_SHIFT);
+		con &= ~(reg->buf_slope_sel_mask << reg->buf_slope_sel_shift);
+		con |= (pdata->gain << reg->buf_slope_sel_shift);
 	}
 
 	if (pdata->noise_cancel_mode) {
-		con &= ~(EXYNOS_TMU_TRIP_MODE_MASK <<
-					EXYNOS_TMU_TRIP_MODE_SHIFT);
-		con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT);
+		con &= ~(reg->therm_trip_mode_mask <<
+					reg->therm_trip_mode_shift);
+		con |= (pdata->noise_cancel_mode << reg->therm_trip_mode_shift);
 	}
 
 	if (on) {
-		con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
+		con |= (1 << reg->core_en_shift);
 		interrupt_en =
-		pdata->trigger_enable[3] << EXYNOS_TMU_INTEN_RISE3_SHIFT |
-		pdata->trigger_enable[2] << EXYNOS_TMU_INTEN_RISE2_SHIFT |
-		pdata->trigger_enable[1] << EXYNOS_TMU_INTEN_RISE1_SHIFT |
-		pdata->trigger_enable[0] << EXYNOS_TMU_INTEN_RISE0_SHIFT;
+			pdata->trigger_enable[3] << reg->inten_rise3_shift |
+			pdata->trigger_enable[2] << reg->inten_rise2_shift |
+			pdata->trigger_enable[1] << reg->inten_rise1_shift |
+			pdata->trigger_enable[0] << reg->inten_rise0_shift;
 		if (pdata->threshold_falling)
 			interrupt_en |=
-				interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
+				interrupt_en << reg->inten_fall0_shift;
 	} else {
-		con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
+		con &= ~(1 << reg->core_en_shift);
 		interrupt_en = 0; /* Disable all interrupts */
 	}
-	writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
-	writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
+	writel(interrupt_en, data->base + reg->tmu_inten);
+	writel(con, data->base + reg->tmu_ctrl);
 
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
@@ -329,13 +259,15 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
 
 static int exynos_tmu_read(struct exynos_tmu_data *data)
 {
+	struct exynos_tmu_platform_data *pdata = data->pdata;
+	struct exynos_tmu_registers *reg = pdata->registers;
 	u8 temp_code;
 	int temp;
 
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
-	temp_code = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
+	temp_code = readb(data->base + reg->tmu_cur_temp);
 	temp = code_to_temp(data, temp_code);
 
 	clk_disable(data->clk);
@@ -348,7 +280,9 @@ static int exynos_tmu_read(struct exynos_tmu_data *data)
 static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
 {
 	struct exynos_tmu_data *data = drv_data;
-	unsigned int reg;
+	struct exynos_tmu_platform_data *pdata = data->pdata;
+	struct exynos_tmu_registers *reg = pdata->registers;
+	unsigned int val;
 	int ret = -EINVAL;
 
 	if (data->soc == SOC_ARCH_EXYNOS4210)
@@ -360,19 +294,19 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
-	reg = readl(data->base + EXYNOS_EMUL_CON);
+	val = readl(data->base + reg->emul_con);
 
 	if (temp) {
 		temp /= MCELSIUS;
 
-		reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
+		val = (EXYNOS_EMUL_TIME << reg->emul_time_shift) |
 			(temp_to_code(data, temp)
-			 << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE;
+			 << reg->emul_temp_shift) | EXYNOS_EMUL_ENABLE;
 	} else {
-		reg &= ~EXYNOS_EMUL_ENABLE;
+		val &= ~EXYNOS_EMUL_ENABLE;
 	}
 
-	writel(reg, data->base + EXYNOS_EMUL_CON);
+	writel(val, data->base + reg->emul_con);
 
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
@@ -389,17 +323,20 @@ static void exynos_tmu_work(struct work_struct *work)
 {
 	struct exynos_tmu_data *data = container_of(work,
 			struct exynos_tmu_data, irq_work);
+	struct exynos_tmu_platform_data *pdata = data->pdata;
+	struct exynos_tmu_registers *reg = pdata->registers;
 
 	exynos_report_trigger();
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
+
 	if (data->soc == SOC_ARCH_EXYNOS)
-		writel(EXYNOS_TMU_CLEAR_RISE_INT |
-				EXYNOS_TMU_CLEAR_FALL_INT,
-				data->base + EXYNOS_TMU_REG_INTCLEAR);
+		writel((reg->inten_rise_mask << reg->inten_rise_shift) |
+			(reg->inten_fall_mask << reg->inten_fall_shift),
+				data->base + reg->tmu_intclear);
 	else
-		writel(EXYNOS4210_TMU_INTCLEAR_VAL,
-				data->base + EXYNOS_TMU_REG_INTCLEAR);
+		writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
+
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
 
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
index 70cc518..1e5e492 100644
--- a/drivers/thermal/samsung/exynos_tmu.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -46,6 +46,81 @@ enum soc_type {
 };
 
 /**
+ * struct exynos_tmu_register - register descriptors to access registers and
+ * bitfields. The register validity, offsets and bitfield values may vary
+ * slightly across different exynos SOC's.
+ */
+struct exynos_tmu_registers {
+	u32	triminfo_data;
+	u32	triminfo_25_shift;
+	u32	triminfo_85_shift;
+
+	u32	triminfo_ctrl;
+	u32	triminfo_reload_shift;
+
+	u32	tmu_ctrl;
+	u32	buf_vref_sel_shift;
+	u32	buf_vref_sel_mask;
+	u32	therm_trip_mode_shift;
+	u32	therm_trip_mode_mask;
+	u32	therm_trip_en_shift;
+	u32	buf_slope_sel_shift;
+	u32	buf_slope_sel_mask;
+	u32	therm_trip_tq_en_shift;
+	u32	core_en_shift;
+
+	u32	tmu_status;
+
+	u32	tmu_cur_temp;
+	u32	tmu_cur_temp_shift;
+
+	u32	threshold_temp;
+
+	u32	threshold_th0;
+	u32	threshold_th0_l0_shift;
+	u32	threshold_th0_l1_shift;
+	u32	threshold_th0_l2_shift;
+	u32	threshold_th0_l3_shift;
+
+	u32	threshold_th1;
+	u32	threshold_th1_l0_shift;
+	u32	threshold_th1_l1_shift;
+	u32	threshold_th1_l2_shift;
+	u32	threshold_th1_l3_shift;
+
+	u32	threshold_th2;
+	u32	threshold_th2_l0_shift;
+
+	u32	threshold_th3;
+	u32	threshold_th3_l0_shift;
+
+	u32	tmu_inten;
+	u32	inten_rise_shift;
+	u32	inten_rise_mask;
+	u32	inten_fall_shift;
+	u32	inten_fall_mask;
+	u32	inten_rise0_shift;
+	u32	inten_rise1_shift;
+	u32	inten_rise2_shift;
+	u32	inten_rise3_shift;
+	u32	inten_fall0_shift;
+	u32	inten_fall1_shift;
+	u32	inten_fall2_shift;
+	u32	inten_fall3_shift;
+
+	u32	tmu_intstat;
+
+	u32	tmu_intclear;
+
+	u32	tmu_evten;
+
+	u32	emul_con;
+	u32	emul_temp_shift;
+	u32	emul_time_shift;
+	u32	emul_time_mask;
+};
+
+/**
  * struct exynos_tmu_platform_data
  * @threshold: basic temperature for generating interrupt
  *	       25 <= threshold <= 125 [unit: degree Celsius]
@@ -116,5 +191,6 @@ struct exynos_tmu_platform_data {
 	enum soc_type type;
 	struct freq_clip_table freq_tab[4];
 	unsigned int freq_tab_count;
+	struct exynos_tmu_registers *registers;
 };
 #endif /* _LINUX_EXYNOS_THERMAL_H */
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
index 6b937f5..3a1ded1 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.c
+++ b/drivers/thermal/samsung/exynos_tmu_data.c
@@ -25,6 +25,28 @@
 #include "exynos_tmu_data.h"
 
 #if defined(CONFIG_CPU_EXYNOS4210)
+static struct exynos_tmu_registers exynos4210_tmu_registers = {
+	.triminfo_data = EXYNOS_TMU_REG_TRIMINFO,
+	.triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
+	.triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
+	.tmu_ctrl = EXYNOS_TMU_REG_CONTROL,
+	.buf_vref_sel_shift = EXYNOS_TMU_REF_VOLTAGE_SHIFT,
+	.buf_vref_sel_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
+	.buf_slope_sel_shift = EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT,
+	.buf_slope_sel_mask = EXYNOS_TMU_BUF_SLOPE_SEL_MASK,
+	.core_en_shift = EXYNOS_TMU_CORE_EN_SHIFT,
+	.tmu_status = EXYNOS_TMU_REG_STATUS,
+	.tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP,
+	.threshold_temp = EXYNOS4210_TMU_REG_THRESHOLD_TEMP,
+	.threshold_th0 = EXYNOS4210_TMU_REG_TRIG_LEVEL0,
+	.tmu_inten = EXYNOS_TMU_REG_INTEN,
+	.inten_rise_mask = EXYNOS4210_TMU_TRIG_LEVEL_MASK,
+	.inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT,
+	.inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT,
+	.inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT,
+	.inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT,
+	.tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
+};
 struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
 	.threshold = 80,
 	.trigger_levels[0] = 5,
@@ -55,10 +77,46 @@ struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
 	},
 	.freq_tab_count = 2,
 	.type = SOC_ARCH_EXYNOS4210,
+	.registers = &exynos4210_tmu_registers,
 };
 #endif
 
 #if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
+static struct exynos_tmu_registers exynos5250_tmu_registers = {
+	.triminfo_data = EXYNOS_TMU_REG_TRIMINFO,
+	.triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
+	.triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
+	.triminfo_ctrl = EXYNOS_TMU_TRIMINFO_CON,
+	.triminfo_reload_shift = EXYNOS_TRIMINFO_RELOAD_SHIFT,
+	.tmu_ctrl = EXYNOS_TMU_REG_CONTROL,
+	.buf_vref_sel_shift = EXYNOS_TMU_REF_VOLTAGE_SHIFT,
+	.buf_vref_sel_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
+	.therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT,
+	.therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK,
+	.therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT,
+	.buf_slope_sel_shift = EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT,
+	.buf_slope_sel_mask = EXYNOS_TMU_BUF_SLOPE_SEL_MASK,
+	.core_en_shift = EXYNOS_TMU_CORE_EN_SHIFT,
+	.tmu_status = EXYNOS_TMU_REG_STATUS,
+	.tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP,
+	.threshold_th0 = EXYNOS_THD_TEMP_RISE,
+	.threshold_th1 = EXYNOS_THD_TEMP_FALL,
+	.tmu_inten = EXYNOS_TMU_REG_INTEN,
+	.inten_rise_mask = EXYNOS_TMU_RISE_INT_MASK,
+	.inten_rise_shift = EXYNOS_TMU_RISE_INT_SHIFT,
+	.inten_fall_mask = EXYNOS_TMU_FALL_INT_MASK,
+	.inten_fall_shift = EXYNOS_TMU_FALL_INT_SHIFT,
+	.inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT,
+	.inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT,
+	.inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT,
+	.inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT,
+	.inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT,
+	.tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
+	.emul_con = EXYNOS_EMUL_CON,
+	.emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT,
+	.emul_time_shift = EXYNOS_EMUL_TIME_SHIFT,
+	.emul_time_mask = EXYNOS_EMUL_TIME_MASK,
+};
 struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
 	.threshold_falling = 10,
 	.trigger_levels[0] = 85,
@@ -93,5 +151,6 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
 	},
 	.freq_tab_count = 2,
 	.type = SOC_ARCH_EXYNOS,
+	.registers = &exynos5250_tmu_registers,
 };
 #endif
diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
index c8b0501..c11acb3 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.h
+++ b/drivers/thermal/samsung/exynos_tmu_data.h
@@ -23,6 +23,76 @@
 #ifndef _LINUX_EXYNOS_TMU_DATA_H
 #define _LINUX_EXYNOS_TMU_DATA_H
 
+/* Exynos generic registers */
+#define EXYNOS_TMU_REG_TRIMINFO		0x0
+#define EXYNOS_TMU_REG_CONTROL		0x20
+#define EXYNOS_TMU_REG_STATUS		0x28
+#define EXYNOS_TMU_REG_CURRENT_TEMP	0x40
+#define EXYNOS_TMU_REG_INTEN		0x70
+#define EXYNOS_TMU_REG_INTSTAT		0x74
+#define EXYNOS_TMU_REG_INTCLEAR		0x78
+
+#define EXYNOS_TMU_TEMP_MASK		0xff
+#define EXYNOS_TMU_REF_VOLTAGE_SHIFT	24
+#define EXYNOS_TMU_REF_VOLTAGE_MASK	0x1f
+#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK	0xf
+#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT	8
+#define EXYNOS_TMU_CORE_EN_SHIFT	0
+
+/* Exynos4210 specific registers */
+#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP	0x44
+#define EXYNOS4210_TMU_REG_TRIG_LEVEL0	0x50
+#define EXYNOS4210_TMU_REG_TRIG_LEVEL1	0x54
+#define EXYNOS4210_TMU_REG_TRIG_LEVEL2	0x58
+#define EXYNOS4210_TMU_REG_TRIG_LEVEL3	0x5C
+#define EXYNOS4210_TMU_REG_PAST_TEMP0	0x60
+#define EXYNOS4210_TMU_REG_PAST_TEMP1	0x64
+#define EXYNOS4210_TMU_REG_PAST_TEMP2	0x68
+#define EXYNOS4210_TMU_REG_PAST_TEMP3	0x6C
+
+#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK	0x1
+#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK	0x10
+#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK	0x100
+#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK	0x1000
+#define EXYNOS4210_TMU_TRIG_LEVEL_MASK	0x1111
+#define EXYNOS4210_TMU_INTCLEAR_VAL	0x1111
+
+/* Exynos5250 and Exynos4412 specific registers */
+#define EXYNOS_TMU_TRIMINFO_CON	0x14
+#define EXYNOS_THD_TEMP_RISE		0x50
+#define EXYNOS_THD_TEMP_FALL		0x54
+#define EXYNOS_EMUL_CON		0x80
+
+#define EXYNOS_TRIMINFO_RELOAD_SHIFT	1
+#define EXYNOS_TRIMINFO_25_SHIFT	0
+#define EXYNOS_TRIMINFO_85_SHIFT	8
+#define EXYNOS_TMU_RISE_INT_MASK	0x111
+#define EXYNOS_TMU_RISE_INT_SHIFT	0
+#define EXYNOS_TMU_FALL_INT_MASK	0x111
+#define EXYNOS_TMU_FALL_INT_SHIFT	12
+#define EXYNOS_TMU_CLEAR_RISE_INT	0x111
+#define EXYNOS_TMU_CLEAR_FALL_INT	(0x111 << 12)
+#define EXYNOS_TMU_TRIP_MODE_SHIFT	13
+#define EXYNOS_TMU_TRIP_MODE_MASK	0x7
+#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT	12
+
+#define EXYNOS_TMU_INTEN_RISE0_SHIFT	0
+#define EXYNOS_TMU_INTEN_RISE1_SHIFT	4
+#define EXYNOS_TMU_INTEN_RISE2_SHIFT	8
+#define EXYNOS_TMU_INTEN_RISE3_SHIFT	12
+#define EXYNOS_TMU_INTEN_FALL0_SHIFT	16
+#define EXYNOS_TMU_INTEN_FALL1_SHIFT	20
+#define EXYNOS_TMU_INTEN_FALL2_SHIFT	24
+
+#ifdef CONFIG_THERMAL_EMULATION
+#define EXYNOS_EMUL_TIME	0x57F0
+#define EXYNOS_EMUL_TIME_MASK	0xffff
+#define EXYNOS_EMUL_TIME_SHIFT	16
+#define EXYNOS_EMUL_DATA_SHIFT	8
+#define EXYNOS_EMUL_DATA_MASK	0xFF
+#define EXYNOS_EMUL_ENABLE	0x1
+#endif /* CONFIG_THERMAL_EMULATION */
+
 #if defined(CONFIG_CPU_EXYNOS4210)
 extern struct exynos_tmu_platform_data const exynos4210_default_tmu_data;
 #define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 10/20] thermal: exynos: Fix to clear only the generated interrupts
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (8 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 09/20] thermal: exynos: Move register definitions from driver file to data file Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 11/20] thermal: exynos: Add support for instance based register/unregister Amit Daniel Kachhap
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch uses the TMU status register to know the generated interrupts
and only clear them in the interrupt handler.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_tmu.c      |   10 ++++------
 drivers/thermal/samsung/exynos_tmu_data.c |    2 ++
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 97b87aa..082d5a2 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -325,17 +325,15 @@ static void exynos_tmu_work(struct work_struct *work)
 			struct exynos_tmu_data, irq_work);
 	struct exynos_tmu_platform_data *pdata = data->pdata;
 	struct exynos_tmu_registers *reg = pdata->registers;
+	unsigned int val_irq;
 
 	exynos_report_trigger();
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
-	if (data->soc == SOC_ARCH_EXYNOS)
-		writel((reg->inten_rise_mask << reg->inten_rise_shift) |
-			(reg->inten_fall_mask << reg->inten_fall_shift),
-				data->base + reg->tmu_intclear);
-	else
-		writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
+	val_irq = readl(data->base + reg->tmu_intstat);
+	/* clear the interrupts */
+	writel(val_irq, data->base + reg->tmu_intclear);
 
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
index 3a1ded1..7322597 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.c
+++ b/drivers/thermal/samsung/exynos_tmu_data.c
@@ -45,6 +45,7 @@ static struct exynos_tmu_registers exynos4210_tmu_registers = {
 	.inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT,
 	.inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT,
 	.inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT,
+	.tmu_intstat = EXYNOS_TMU_REG_INTSTAT,
 	.tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
 };
 struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
@@ -111,6 +112,7 @@ static struct exynos_tmu_registers exynos5250_tmu_registers = {
 	.inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT,
 	.inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT,
 	.inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT,
+	.tmu_intstat = EXYNOS_TMU_REG_INTSTAT,
 	.tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
 	.emul_con = EXYNOS_EMUL_CON,
 	.emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT,
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 11/20] thermal: exynos: Add support for instance based register/unregister
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (9 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 10/20] thermal: exynos: Fix to clear only the generated interrupts Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 12/20] thermal: exynos: Modify private_data to appropriate name driver_data Amit Daniel Kachhap
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This code modifies the thermal driver to have multiple thermal zone
support by replacing the global thermal zone variable with device data
member of thermal_zone_device.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_thermal_common.c |   36 ++++++++++++++--------
 drivers/thermal/samsung/exynos_thermal_common.h |    5 ++-
 drivers/thermal/samsung/exynos_tmu.c            |   15 +++++----
 3 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
index dae5476..d4cd5ec 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.c
+++ b/drivers/thermal/samsung/exynos_thermal_common.c
@@ -41,12 +41,11 @@ struct exynos_thermal_zone {
 	bool bind;
 };
 
-static struct exynos_thermal_zone *th_zone;
-
 /* Get mode callback functions for thermal zone */
 static int exynos_get_mode(struct thermal_zone_device *thermal,
 			enum thermal_device_mode *mode)
 {
+	struct exynos_thermal_zone *th_zone = thermal->devdata;
 	if (th_zone)
 		*mode = th_zone->mode;
 	return 0;
@@ -56,25 +55,26 @@ static int exynos_get_mode(struct thermal_zone_device *thermal,
 static int exynos_set_mode(struct thermal_zone_device *thermal,
 			enum thermal_device_mode mode)
 {
-	if (!th_zone->therm_dev) {
+	struct exynos_thermal_zone *th_zone = thermal->devdata;
+	if (!th_zone) {
 		pr_notice("thermal zone not registered\n");
 		return 0;
 	}
 
-	mutex_lock(&th_zone->therm_dev->lock);
+	mutex_lock(&thermal->lock);
 
 	if (mode == THERMAL_DEVICE_ENABLED &&
 		!th_zone->sensor_conf->trip_data.trigger_falling)
-		th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+		thermal->polling_delay = IDLE_INTERVAL;
 	else
-		th_zone->therm_dev->polling_delay = 0;
+		thermal->polling_delay = 0;
 
-	mutex_unlock(&th_zone->therm_dev->lock);
+	mutex_unlock(&thermal->lock);
 
 	th_zone->mode = mode;
-	thermal_zone_device_update(th_zone->therm_dev);
+	thermal_zone_device_update(thermal);
 	pr_info("thermal polling set for duration=%d msec\n",
-				th_zone->therm_dev->polling_delay);
+				thermal->polling_delay);
 	return 0;
 }
 
@@ -101,6 +101,8 @@ static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
 static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
 				unsigned long *temp)
 {
+	struct exynos_thermal_zone *th_zone = thermal->devdata;
+
 	if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
 		return -EINVAL;
 
@@ -127,6 +129,7 @@ static int exynos_bind(struct thermal_zone_device *thermal,
 {
 	int ret = 0, i, tab_size, level;
 	struct freq_clip_table *tab_ptr, *clip_data;
+	struct exynos_thermal_zone *th_zone = thermal->devdata;
 	struct thermal_sensor_conf *data = th_zone->sensor_conf;
 
 	tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
@@ -173,6 +176,7 @@ static int exynos_unbind(struct thermal_zone_device *thermal,
 			struct thermal_cooling_device *cdev)
 {
 	int ret = 0, i, tab_size;
+	struct exynos_thermal_zone *th_zone = thermal->devdata;
 	struct thermal_sensor_conf *data = th_zone->sensor_conf;
 
 	if (th_zone->bind == false)
@@ -215,6 +219,7 @@ static int exynos_unbind(struct thermal_zone_device *thermal,
 static int exynos_get_temp(struct thermal_zone_device *thermal,
 			unsigned long *temp)
 {
+	struct exynos_thermal_zone *th_zone = thermal->devdata;
 	void *data;
 
 	if (!th_zone->sensor_conf) {
@@ -234,6 +239,7 @@ static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
 {
 	void *data;
 	int ret = -EINVAL;
+	struct exynos_thermal_zone *th_zone = thermal->devdata;
 
 	if (!th_zone->sensor_conf) {
 		pr_info("Temperature sensor not initialised\n");
@@ -281,11 +287,12 @@ static struct thermal_zone_device_ops const exynos_dev_ops = {
  * This function may be called from interrupt based temperature sensor
  * when threshold is changed.
  */
-void exynos_report_trigger(void)
+void exynos_report_trigger(struct thermal_sensor_conf *conf)
 {
 	unsigned int i;
 	char data[10];
 	char *envp[] = { data, NULL };
+	struct exynos_thermal_zone *th_zone = conf->pzone_data;
 
 	if (!th_zone || !th_zone->therm_dev)
 		return;
@@ -326,6 +333,7 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
 {
 	int ret;
 	struct cpumask mask_val;
+	struct exynos_thermal_zone *th_zone;
 
 	if (!sensor_conf || !sensor_conf->read_temperature) {
 		pr_err("Temperature sensor not initialised\n");
@@ -347,7 +355,7 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
 	th_zone->cool_dev_size++;
 
 	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
-			EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
+			EXYNOS_ZONE_COUNT, 0, th_zone, &exynos_dev_ops, NULL, 0,
 			sensor_conf->trip_data.trigger_falling ?
 			0 : IDLE_INTERVAL);
 
@@ -357,20 +365,22 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
 		goto err_unregister;
 	}
 	th_zone->mode = THERMAL_DEVICE_ENABLED;
+	sensor_conf->pzone_data = th_zone;
 
 	pr_info("Exynos: Kernel Thermal management registered\n");
 
 	return 0;
 
 err_unregister:
-	exynos_unregister_thermal();
+	exynos_unregister_thermal(sensor_conf);
 	return ret;
 }
 
 /* Un-Register with the in-kernel thermal management */
-void exynos_unregister_thermal(void)
+void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf)
 {
 	int i;
+	struct exynos_thermal_zone *th_zone = sensor_conf->pzone_data;
 
 	if (!th_zone)
 		return;
diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
index 6ed9bd9..26fdf8d 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.h
+++ b/drivers/thermal/samsung/exynos_thermal_common.h
@@ -77,10 +77,11 @@ struct thermal_sensor_conf {
 	struct thermal_trip_point_conf trip_data;
 	struct thermal_cooling_conf cooling_data;
 	void *private_data;
+	void *pzone_data;
 };
 
 /*Functions used exynos based thermal sensor driver*/
-void exynos_unregister_thermal(void);
+void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf);
 int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
-void exynos_report_trigger(void);
+void exynos_report_trigger(struct thermal_sensor_conf *sensor_conf);
 #endif /* _LINUX_EXYNOS_THERMAL_COMMON_H */
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 082d5a2..133d3f5 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -319,6 +319,12 @@ static int exynos_tmu_set_emulation(void *drv_data,	unsigned long temp)
 	{ return -EINVAL; }
 #endif/*CONFIG_THERMAL_EMULATION*/
 
+static struct thermal_sensor_conf exynos_sensor_conf = {
+	.name			= "exynos-therm",
+	.read_temperature	= (int (*)(void *))exynos_tmu_read,
+	.write_emul_temp	= exynos_tmu_set_emulation,
+};
+
 static void exynos_tmu_work(struct work_struct *work)
 {
 	struct exynos_tmu_data *data = container_of(work,
@@ -327,7 +333,7 @@ static void exynos_tmu_work(struct work_struct *work)
 	struct exynos_tmu_registers *reg = pdata->registers;
 	unsigned int val_irq;
 
-	exynos_report_trigger();
+	exynos_report_trigger(&exynos_sensor_conf);
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
@@ -350,11 +356,6 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id)
 
 	return IRQ_HANDLED;
 }
-static struct thermal_sensor_conf exynos_sensor_conf = {
-	.name			= "exynos-therm",
-	.read_temperature	= (int (*)(void *))exynos_tmu_read,
-	.write_emul_temp	= exynos_tmu_set_emulation,
-};
 
 #ifdef CONFIG_OF
 static const struct of_device_id exynos_tmu_match[] = {
@@ -520,7 +521,7 @@ static int exynos_tmu_remove(struct platform_device *pdev)
 
 	exynos_tmu_control(pdev, false);
 
-	exynos_unregister_thermal();
+	exynos_unregister_thermal(&exynos_sensor_conf);
 
 	clk_unprepare(data->clk);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 12/20] thermal: exynos: Modify private_data to appropriate name driver_data
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (10 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 11/20] thermal: exynos: Add support for instance based register/unregister Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 13/20] thermal: exynos: Return success even if no cooling data supplied Amit Daniel Kachhap
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch renames member private_data to driver_data of the thermal
zone registration structure as this item stores the driver related
data and uses it to call the driver related callbacks.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_thermal_common.c |    4 ++--
 drivers/thermal/samsung/exynos_thermal_common.h |    2 +-
 drivers/thermal/samsung/exynos_tmu.c            |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
index d4cd5ec..c0e4bdb 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.c
+++ b/drivers/thermal/samsung/exynos_thermal_common.c
@@ -226,7 +226,7 @@ static int exynos_get_temp(struct thermal_zone_device *thermal,
 		pr_info("Temperature sensor not initialised\n");
 		return -EINVAL;
 	}
-	data = th_zone->sensor_conf->private_data;
+	data = th_zone->sensor_conf->driver_data;
 	*temp = th_zone->sensor_conf->read_temperature(data);
 	/* convert the temperature into millicelsius */
 	*temp = *temp * MCELSIUS;
@@ -245,7 +245,7 @@ static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
 		pr_info("Temperature sensor not initialised\n");
 		return -EINVAL;
 	}
-	data = th_zone->sensor_conf->private_data;
+	data = th_zone->sensor_conf->driver_data;
 	if (th_zone->sensor_conf->write_emul_temp)
 		ret = th_zone->sensor_conf->write_emul_temp(data, temp);
 	return ret;
diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
index 26fdf8d..878120b 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.h
+++ b/drivers/thermal/samsung/exynos_thermal_common.h
@@ -76,7 +76,7 @@ struct thermal_sensor_conf {
 	int (*write_emul_temp)(void *drv_data, unsigned long temp);
 	struct thermal_trip_point_conf trip_data;
 	struct thermal_cooling_conf cooling_data;
-	void *private_data;
+	void *driver_data;
 	void *pzone_data;
 };
 
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 133d3f5..bdf40ef 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -482,7 +482,7 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 	exynos_tmu_control(pdev, true);
 
 	/* Register the sensor with thermal management interface */
-	(&exynos_sensor_conf)->private_data = data;
+	(&exynos_sensor_conf)->driver_data = data;
 	exynos_sensor_conf.trip_data.trip_count = pdata->trigger_enable[0] +
 			pdata->trigger_enable[1] + pdata->trigger_enable[2]+
 			pdata->trigger_enable[3];
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 13/20] thermal: exynos: Return success even if no cooling data supplied
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (11 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 12/20] thermal: exynos: Modify private_data to appropriate name driver_data Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 14/20] thermal: exynos: Make the zone handling dependent on trip count Amit Daniel Kachhap
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch removes the error return in the bind/unbind routine
as the platform may not register any cpufreq cooling data.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_thermal_common.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
index c0e4bdb..b7ca8a4 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.c
+++ b/drivers/thermal/samsung/exynos_thermal_common.c
@@ -136,7 +136,7 @@ static int exynos_bind(struct thermal_zone_device *thermal,
 	tab_size = data->cooling_data.freq_clip_count;
 
 	if (tab_ptr == NULL || tab_size == 0)
-		return -EINVAL;
+		return 0;
 
 	/* find the cooling device registered*/
 	for (i = 0; i < th_zone->cool_dev_size; i++)
@@ -185,7 +185,7 @@ static int exynos_unbind(struct thermal_zone_device *thermal,
 	tab_size = data->cooling_data.freq_clip_count;
 
 	if (tab_size == 0)
-		return -EINVAL;
+		return 0;
 
 	/* find the cooling device registered*/
 	for (i = 0; i < th_zone->cool_dev_size; i++)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 14/20] thermal: exynos: Make the zone handling dependent on trip count
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (12 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 13/20] thermal: exynos: Return success even if no cooling data supplied Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 15/20] thermal: exynos: Add support to handle many instances of TMU Amit Daniel Kachhap
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This code simplifies the zone handling to use the trip count passed
by the TMU driver. This also helps in adding more zone support.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_thermal_common.c |   55 ++++++++++++-----------
 drivers/thermal/samsung/exynos_thermal_common.h |    2 -
 2 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
index b7ca8a4..b0dc63e 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.c
+++ b/drivers/thermal/samsung/exynos_thermal_common.c
@@ -83,17 +83,16 @@ static int exynos_set_mode(struct thermal_zone_device *thermal,
 static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
 				 enum thermal_trip_type *type)
 {
-	switch (GET_ZONE(trip)) {
-	case MONITOR_ZONE:
-	case WARN_ZONE:
-		*type = THERMAL_TRIP_ACTIVE;
-		break;
-	case PANIC_ZONE:
-		*type = THERMAL_TRIP_CRITICAL;
-		break;
-	default:
+	struct exynos_thermal_zone *th_zone = thermal->devdata;
+	int max_trip = th_zone->sensor_conf->trip_data.trip_count;
+
+	if (trip < 0 || trip >= max_trip)
 		return -EINVAL;
-	}
+	else if (trip == (max_trip - 1))
+		*type = THERMAL_TRIP_CRITICAL;
+	else
+		*type = THERMAL_TRIP_ACTIVE;
+
 	return 0;
 }
 
@@ -102,8 +101,9 @@ static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
 				unsigned long *temp)
 {
 	struct exynos_thermal_zone *th_zone = thermal->devdata;
+	int max_trip = th_zone->sensor_conf->trip_data.trip_count;
 
-	if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
+	if (trip < 0 || trip >= max_trip)
 		return -EINVAL;
 
 	*temp = th_zone->sensor_conf->trip_data.trip_val[trip];
@@ -117,10 +117,10 @@ static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
 static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
 				unsigned long *temp)
 {
-	int ret;
-	/* Panic zone */
-	ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
-	return ret;
+	struct exynos_thermal_zone *th_zone = thermal->devdata;
+	int max_trip = th_zone->sensor_conf->trip_data.trip_count;
+	/* Get the temp of highest trip*/
+	return exynos_get_trip_temp(thermal, max_trip - 1, temp);
 }
 
 /* Bind callback functions for thermal zone */
@@ -345,19 +345,22 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
 		return -ENOMEM;
 
 	th_zone->sensor_conf = sensor_conf;
-	cpumask_set_cpu(0, &mask_val);
-	th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
-	if (IS_ERR(th_zone->cool_dev[0])) {
-		pr_err("Failed to register cpufreq cooling device\n");
-		ret = -EINVAL;
-		goto err_unregister;
+	if (sensor_conf->cooling_data.freq_clip_count > 0) {
+		cpumask_set_cpu(0, &mask_val);
+		th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
+		if (IS_ERR(th_zone->cool_dev[0])) {
+			pr_err("Failed to register cpufreq cooling device\n");
+			ret = -EINVAL;
+			goto err_unregister;
+		}
+		th_zone->cool_dev_size++;
 	}
-	th_zone->cool_dev_size++;
 
-	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
-			EXYNOS_ZONE_COUNT, 0, th_zone, &exynos_dev_ops, NULL, 0,
-			sensor_conf->trip_data.trigger_falling ?
-			0 : IDLE_INTERVAL);
+	th_zone->therm_dev = thermal_zone_device_register(
+			sensor_conf->name, sensor_conf->trip_data.trip_count,
+			0, th_zone, &exynos_dev_ops, NULL, 0,
+			sensor_conf->trip_data.trigger_falling ? 0 :
+			IDLE_INTERVAL);
 
 	if (IS_ERR(th_zone->therm_dev)) {
 		pr_err("Failed to register thermal zone device\n");
diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
index 878120b..58c3a88 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.h
+++ b/drivers/thermal/samsung/exynos_thermal_common.h
@@ -42,8 +42,6 @@
 #define GET_ZONE(trip) (trip + 2)
 #define GET_TRIP(zone) (zone - 2)
 
-#define EXYNOS_ZONE_COUNT	3
-
 /**
  * struct freq_clip_table
  * @freq_clip_max: maximum frequency allowed for this cooling state.
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 15/20] thermal: exynos: Add support to handle many instances of TMU
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (13 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 14/20] thermal: exynos: Make the zone handling dependent on trip count Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 16/20] thermal: exynos: Add features to check instead of SOC type Amit Daniel Kachhap
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch adds support to handle multiple instances of the TMU controllers.
This is done by removing the static structure to register with the core thermal
and creating it dynamically for each instance of the TMU controller. The
interrupt is made shared type to handle interrupts for all the TMU. Also
the identifier of the TMU controller is extracted from device tree alias.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_tmu.c |  125 +++++++++++++++++++++++-----------
 1 files changed, 84 insertions(+), 41 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index bdf40ef..94d6e8e 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -29,6 +29,8 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
@@ -36,9 +38,24 @@
 #include "exynos_tmu.h"
 #include "exynos_tmu_data.h"
 
+/**
+ * struct exynos_tmu_data : A structure to hold the private data of the TMU
+	driver
+ * @id: identifier of the one instance of the TMU controller.
+ * @pdata: pointer to the tmu platform/configuration data
+ * @base: base address of the single instance of the TMU controller.
+ * @irq: irq number of the TMU controller.
+ * @soc: id of the SOC type.
+ * @irq_work: pointer to the irq work structure.
+ * @lock: lock to implement synchronization.
+ * @clk: pointer to the clock structure.
+ * @temp_error1: fused value of the first point trim.
+ * @temp_error2: fused value of the second point trim.
+ * @reg_conf: pointer to structure to register with core thermal.
+ */
 struct exynos_tmu_data {
+	int id;
 	struct exynos_tmu_platform_data *pdata;
-	struct resource *mem;
 	void __iomem *base;
 	int irq;
 	enum soc_type soc;
@@ -46,6 +63,7 @@ struct exynos_tmu_data {
 	struct mutex lock;
 	struct clk *clk;
 	u8 temp_error1, temp_error2;
+	struct thermal_sensor_conf *reg_conf;
 };
 
 /*
@@ -319,12 +337,6 @@ static int exynos_tmu_set_emulation(void *drv_data,	unsigned long temp)
 	{ return -EINVAL; }
 #endif/*CONFIG_THERMAL_EMULATION*/
 
-static struct thermal_sensor_conf exynos_sensor_conf = {
-	.name			= "exynos-therm",
-	.read_temperature	= (int (*)(void *))exynos_tmu_read,
-	.write_emul_temp	= exynos_tmu_set_emulation,
-};
-
 static void exynos_tmu_work(struct work_struct *work)
 {
 	struct exynos_tmu_data *data = container_of(work,
@@ -333,7 +345,7 @@ static void exynos_tmu_work(struct work_struct *work)
 	struct exynos_tmu_registers *reg = pdata->registers;
 	unsigned int val_irq;
 
-	exynos_report_trigger(&exynos_sensor_conf);
+	exynos_report_trigger(data->reg_conf);
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
@@ -405,10 +417,42 @@ static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
 			platform_get_device_id(pdev)->driver_data;
 }
 
+static int exynos_map_dt_data(struct platform_device *pdev)
+{
+	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+	struct resource res;
+
+	if (!data)
+		return -ENODEV;
+
+	data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl");
+	if (data->id < 0)
+		data->id = 0;
+
+	data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+	if (data->irq <= 0) {
+		dev_err(&pdev->dev, "failed to get IRQ\n");
+		return -ENODEV;
+	}
+
+	if (of_address_to_resource(pdev->dev.of_node, 0, &res)) {
+		dev_err(&pdev->dev, "failed to get Resource\n");
+		return -ENODEV;
+	}
+
+	data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
+	if (!data->base) {
+		dev_err(&pdev->dev, "Failed to ioremap memory\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
 static int exynos_tmu_probe(struct platform_device *pdev)
 {
 	struct exynos_tmu_data *data;
 	struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
+	struct thermal_sensor_conf *sensor_conf;
 	int ret, i;
 
 	if (!pdata)
@@ -425,26 +469,17 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	data->irq = platform_get_irq(pdev, 0);
-	if (data->irq < 0) {
-		dev_err(&pdev->dev, "Failed to get platform irq\n");
-		return data->irq;
-	}
-
-	INIT_WORK(&data->irq_work, exynos_tmu_work);
-
-	data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!data->mem) {
-		dev_err(&pdev->dev, "Failed to get platform resource\n");
-		return -ENOENT;
-	}
+	data->pdata = pdata;
+	platform_set_drvdata(pdev, data);
+	mutex_init(&data->lock);
 
-	data->base = devm_ioremap_resource(&pdev->dev, data->mem);
-	if (IS_ERR(data->base))
-		return PTR_ERR(data->base);
+	ret = exynos_map_dt_data(pdev);
+	if (ret)
+		return ret;
 
+	INIT_WORK(&data->irq_work, exynos_tmu_work);
 	ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
-		IRQF_TRIGGER_RISING, "exynos-tmu", data);
+		IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
 		return ret;
@@ -469,10 +504,6 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 		goto err_clk;
 	}
 
-	data->pdata = pdata;
-	platform_set_drvdata(pdev, data);
-	mutex_init(&data->lock);
-
 	ret = exynos_tmu_initialize(pdev);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to initialize TMU\n");
@@ -481,28 +512,40 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 
 	exynos_tmu_control(pdev, true);
 
-	/* Register the sensor with thermal management interface */
-	(&exynos_sensor_conf)->driver_data = data;
-	exynos_sensor_conf.trip_data.trip_count = pdata->trigger_enable[0] +
+	/* Allocate a structure to register with the exynos core thermal */
+	sensor_conf = devm_kzalloc(&pdev->dev,
+				sizeof(struct thermal_sensor_conf), GFP_KERNEL);
+	if (!sensor_conf) {
+		dev_err(&pdev->dev, "Failed to allocate registration struct\n");
+		ret = -ENOMEM;
+		goto err_clk;
+	}
+	data->reg_conf = sensor_conf;
+	sprintf(sensor_conf->name, "therm_zone%d", data->id);
+	sensor_conf->read_temperature = (int (*)(void *))exynos_tmu_read;
+	sensor_conf->write_emul_temp =
+		(int (*)(void *, unsigned long))exynos_tmu_set_emulation;
+	sensor_conf->driver_data = data;
+	sensor_conf->trip_data.trip_count = pdata->trigger_enable[0] +
 			pdata->trigger_enable[1] + pdata->trigger_enable[2]+
 			pdata->trigger_enable[3];
 
-	for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
-		exynos_sensor_conf.trip_data.trip_val[i] =
+	for (i = 0; i < sensor_conf->trip_data.trip_count; i++)
+		sensor_conf->trip_data.trip_val[i] =
 			pdata->threshold + pdata->trigger_levels[i];
 
-	exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;
+	sensor_conf->trip_data.trigger_falling = pdata->threshold_falling;
 
-	exynos_sensor_conf.cooling_data.freq_clip_count =
-						pdata->freq_tab_count;
+	sensor_conf->cooling_data.freq_clip_count = pdata->freq_tab_count;
 	for (i = 0; i < pdata->freq_tab_count; i++) {
-		exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
+		sensor_conf->cooling_data.freq_data[i].freq_clip_max =
 					pdata->freq_tab[i].freq_clip_max;
-		exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
+		sensor_conf->cooling_data.freq_data[i].temp_level =
 					pdata->freq_tab[i].temp_level;
 	}
 
-	ret = exynos_register_thermal(&exynos_sensor_conf);
+	/* Register the sensor with thermal management interface */
+	ret = exynos_register_thermal(sensor_conf);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register thermal interface\n");
 		goto err_clk;
@@ -521,7 +564,7 @@ static int exynos_tmu_remove(struct platform_device *pdev)
 
 	exynos_tmu_control(pdev, false);
 
-	exynos_unregister_thermal(&exynos_sensor_conf);
+	exynos_unregister_thermal(data->reg_conf);
 
 	clk_unprepare(data->clk);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 16/20] thermal: exynos: Add features to check instead of SOC type
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (14 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 15/20] thermal: exynos: Add support to handle many instances of TMU Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 17/20] ARM: dts: thermal: exynos4: Add documentation for Exynos SoC thermal bindings Amit Daniel Kachhap
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch adds several features supported by TMU as bitfields.
This features varies across different SOC type and comparing
the features present in the TMU is more logical than comparing
the soc itself.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 drivers/thermal/samsung/exynos_tmu.c      |    6 +++---
 drivers/thermal/samsung/exynos_tmu.h      |   20 ++++++++++++++++++++
 drivers/thermal/samsung/exynos_tmu_data.c |    2 ++
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 94d6e8e..c1a8c5f 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -152,7 +152,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 		goto out;
 	}
 
-	if (data->soc == SOC_ARCH_EXYNOS)
+	if (TMU_SUPPORTS(pdata, TRIM_RELOAD))
 		__raw_writel(1, data->base + reg->triminfo_ctrl);
 
 	/* Save trimming info in order to perform calibration */
@@ -261,7 +261,7 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
 			pdata->trigger_enable[2] << reg->inten_rise2_shift |
 			pdata->trigger_enable[1] << reg->inten_rise1_shift |
 			pdata->trigger_enable[0] << reg->inten_rise0_shift;
-		if (pdata->threshold_falling)
+		if (TMU_SUPPORTS(pdata, FALLING_TRIP))
 			interrupt_en |=
 				interrupt_en << reg->inten_fall0_shift;
 	} else {
@@ -303,7 +303,7 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
 	unsigned int val;
 	int ret = -EINVAL;
 
-	if (data->soc == SOC_ARCH_EXYNOS4210)
+	if (!TMU_SUPPORTS(pdata, EMULATION))
 		goto out;
 
 	if (temp && temp < MCELSIUS)
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
index 1e5e492..4dd843d 100644
--- a/drivers/thermal/samsung/exynos_tmu.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -46,6 +46,25 @@ enum soc_type {
 };
 
 /**
+ * EXYNOS TMU supported features.
+ * TMU_SUPPORT_EMULATION - This features is used to set user defined
+ *			temperature to the TMU controller.
+ * TMU_SUPPORT_MULTI_INST - This features denotes that the soc
+ *			has many instances of TMU.
+ * TMU_SUPPORT_TRIM_RELOAD - This features shows that trimming can
+ *			be reloaded.
+ * TMU_SUPPORT_FALLING_TRIP - This features shows that interrupt can
+ *			be registered for falling trips also.
+ * TMU_SUPPORT - macro to compare the above features with the supplied.
+ */
+#define TMU_SUPPORT_EMULATION			BIT(0)
+#define TMU_SUPPORT_MULTI_INST			BIT(1)
+#define TMU_SUPPORT_TRIM_RELOAD			BIT(2)
+#define TMU_SUPPORT_FALLING_TRIP		BIT(3)
+
+#define TMU_SUPPORTS(a, b)	(a->features & TMU_SUPPORT_ ## b)
+
+/**
  * struct exynos_tmu_register - register descriptors to access registers and
  * bitfields. The register validity, offsets and bitfield values may vary
  * slightly across different exynos SOC's.
@@ -192,5 +211,6 @@ struct exynos_tmu_platform_data {
 	struct freq_clip_table freq_tab[4];
 	unsigned int freq_tab_count;
 	struct exynos_tmu_registers *registers;
+	unsigned int features;
 };
 #endif /* _LINUX_EXYNOS_THERMAL_H */
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
index 7322597..8a587d4 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.c
+++ b/drivers/thermal/samsung/exynos_tmu_data.c
@@ -154,5 +154,7 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
 	.freq_tab_count = 2,
 	.type = SOC_ARCH_EXYNOS,
 	.registers = &exynos5250_tmu_registers,
+	.features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD |
+			TMU_SUPPORT_FALLING_TRIP),
 };
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 17/20] ARM: dts: thermal: exynos4: Add documentation for Exynos SoC thermal bindings
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (15 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 16/20] thermal: exynos: Add features to check instead of SOC type Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 18/20] thermal: exynos: Add support for exynos5440 TMU sensor Amit Daniel Kachhap
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin, Lukasz Majewski

From: Lukasz Majewski <l.majewski@samsung.com>

Proper description for Exynos4 bindings added to Documentation/devicetree/
bindings

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 .../devicetree/bindings/thermal/exynos-thermal.txt |   25 ++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/thermal/exynos-thermal.txt

diff --git a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
new file mode 100644
index 0000000..535fd0e
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
@@ -0,0 +1,25 @@
+* Exynos Thermal Management Unit (TMU)
+
+** Required properties:
+
+- compatible : One of the following:
+	       "samsung,exynos4412-tmu"
+	       "samsung,exynos4210-tmu"
+	       "samsung,exynos5250-tmu"
+- interrupt-parent : The phandle for the interrupt controller
+- reg : Address range of the thermal registers
+- interrupts : Should contain interrupt for thermal system
+- clocks : The main clock for TMU device
+- clock-names : Thermal system clock name
+
+Example:
+
+	tmu@100C0000 {
+		compatible = "samsung,exynos4412-tmu";
+		interrupt-parent = <&combiner>;
+		reg = <0x100C0000 0x100>;
+		interrupts = <2 4>;
+		clocks = <&clock 383>;
+		clock-names = "tmu_apbif";
+		status = "disabled";
+	};
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 18/20] thermal: exynos: Add support for exynos5440 TMU sensor.
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (16 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 17/20] ARM: dts: thermal: exynos4: Add documentation for Exynos SoC thermal bindings Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 19/20] Documentation: thermal: Explain the exynos thermal driver model Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 20/20] ARM: dts: Add device tree node for exynos5440 TMU controller Amit Daniel Kachhap
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch modifies TMU controller to add changes needed to work with
exynos5440 platform. Also register definitions and required configuration data
are added. This sensor registers 3 instance of the tmu controller with the
thermal zone and hence reports 3 temperature output. This controller supports
upto five trip points. For critical threshold the driver uses the core driver
thermal framework for shutdown.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 .../devicetree/bindings/thermal/exynos-thermal.txt |   28 ++++-
 drivers/thermal/samsung/Kconfig                    |    4 +-
 drivers/thermal/samsung/exynos_thermal_common.c    |    2 +-
 drivers/thermal/samsung/exynos_tmu.c               |  139 +++++++++++++++++---
 drivers/thermal/samsung/exynos_tmu.h               |    7 +
 drivers/thermal/samsung/exynos_tmu_data.c          |   66 +++++++++-
 drivers/thermal/samsung/exynos_tmu_data.h          |   40 ++++++
 7 files changed, 261 insertions(+), 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
index 535fd0e..970eeba 100644
--- a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
@@ -6,13 +6,16 @@
 	       "samsung,exynos4412-tmu"
 	       "samsung,exynos4210-tmu"
 	       "samsung,exynos5250-tmu"
+	       "samsung,exynos5440-tmu"
 - interrupt-parent : The phandle for the interrupt controller
-- reg : Address range of the thermal registers
+- reg : Address range of the thermal registers. For exynos5440-tmu which has 3
+	instances of TMU, 2 set of register has to supplied. First set belongs
+	to each instance of TMU and second set belongs to common TMU registers.
 - interrupts : Should contain interrupt for thermal system
 - clocks : The main clock for TMU device
 - clock-names : Thermal system clock name
 
-Example:
+Example 1):
 
 	tmu@100C0000 {
 		compatible = "samsung,exynos4412-tmu";
@@ -23,3 +26,24 @@ Example:
 		clock-names = "tmu_apbif";
 		status = "disabled";
 	};
+
+Example 2):
+
+	tmuctrl_0: tmuctrl@160118 {
+		compatible = "samsung,exynos5440-tmu";
+		reg = <0x160118 0x230>, <0x160368 0x10>;
+		interrupts = <0 58 0>;
+		clocks = <&clock 21>;
+		clock-names = "tmu_apbif";
+	};
+
+Note: For multi-instance tmu each instance should have an alias correctly
+numbered in "aliases" node.
+
+Example:
+
+aliases {
+	tmuctrl0 = &tmuctrl_0;
+	tmuctrl1 = &tmuctrl_1;
+	tmuctrl2 = &tmuctrl_2;
+};
diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
index 1e3ba31..83454cd 100644
--- a/drivers/thermal/samsung/Kconfig
+++ b/drivers/thermal/samsung/Kconfig
@@ -11,10 +11,10 @@ if EXYNOS_COMMON
 
 config EXYNOS_SOC_THERMAL
 	tristate "Temperature sensor on Samsung EXYNOS series SOC"
-	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250)
+	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250 || SOC_EXYNOS5440)
  	help
 	  If you say yes here you can enable TMU (Thermal Management Unit) on
-	  SAMSUNG EXYNOS 4210, 4412, 4414 and 5250 series of SoC. This option
+	  SAMSUNG EXYNOS 4210, 4412, 4414, 5250 and 5440 series of SoC. This option
 	  initialises the TMU controller and registers/unregisters with exynos
 	  common thermal layer.
 
diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
index b0dc63e..de43e18 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.c
+++ b/drivers/thermal/samsung/exynos_thermal_common.c
@@ -370,7 +370,7 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
 	th_zone->mode = THERMAL_DEVICE_ENABLED;
 	sensor_conf->pzone_data = th_zone;
 
-	pr_info("Exynos: Kernel Thermal management registered\n");
+	pr_info("Exynos: Thermal zone(%s) registered\n", sensor_conf->name);
 
 	return 0;
 
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index c1a8c5f..72446c9 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -44,6 +44,7 @@
  * @id: identifier of the one instance of the TMU controller.
  * @pdata: pointer to the tmu platform/configuration data
  * @base: base address of the single instance of the TMU controller.
+ * @base_common: base address of the common registers of the TMU controller.
  * @irq: irq number of the TMU controller.
  * @soc: id of the SOC type.
  * @irq_work: pointer to the irq work structure.
@@ -57,6 +58,7 @@ struct exynos_tmu_data {
 	int id;
 	struct exynos_tmu_platform_data *pdata;
 	void __iomem *base;
+	void __iomem *base_common;
 	int irq;
 	enum soc_type soc;
 	struct work_struct irq_work;
@@ -75,6 +77,9 @@ static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
 	struct exynos_tmu_platform_data *pdata = data->pdata;
 	int temp_code;
 
+	if (pdata->cal_mode == HW_MODE)
+		return temp;
+
 	if (data->soc == SOC_ARCH_EXYNOS4210)
 		/* temp should range between 25 and 125 */
 		if (temp < 25 || temp > 125) {
@@ -109,6 +114,9 @@ static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
 	struct exynos_tmu_platform_data *pdata = data->pdata;
 	int temp;
 
+	if (pdata->cal_mode == HW_MODE)
+		return temp_code;
+
 	if (data->soc == SOC_ARCH_EXYNOS4210)
 		/* temp_code should range between 75 and 175 */
 		if (temp_code < 75 || temp_code > 175) {
@@ -139,33 +147,63 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 	struct exynos_tmu_platform_data *pdata = data->pdata;
 	struct exynos_tmu_registers *reg = pdata->registers;
-	unsigned int status, trim_info, con;
+	unsigned int status, trim_info = 0, con;
 	unsigned int rising_threshold = 0, falling_threshold = 0;
 	int ret = 0, threshold_code, i, trigger_levs = 0;
 
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
-	status = readb(data->base + reg->tmu_status);
-	if (!status) {
-		ret = -EBUSY;
-		goto out;
+	if (TMU_SUPPORTS(pdata, READY_STATUS)) {
+		status = readb(data->base + reg->tmu_status);
+		if (!status) {
+			ret = -EBUSY;
+			goto out;
+		}
 	}
 
 	if (TMU_SUPPORTS(pdata, TRIM_RELOAD))
 		__raw_writel(1, data->base + reg->triminfo_ctrl);
 
+	if (pdata->cal_mode == HW_MODE)
+		goto skip_calib_data;
+
 	/* Save trimming info in order to perform calibration */
-	trim_info = readl(data->base + reg->triminfo_data);
+	if (data->soc == SOC_ARCH_EXYNOS5440) {
+		/*
+		 * For exynos5440 soc triminfo value is swapped between TMU0 and
+		 * TMU2, so the below logic is needed.
+		 */
+		switch (data->id) {
+		case 0:
+			trim_info = readl(data->base +
+			EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data);
+			break;
+		case 1:
+			trim_info = readl(data->base + reg->triminfo_data);
+			break;
+		case 2:
+			trim_info = readl(data->base -
+			EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data);
+		}
+	} else {
+		trim_info = readl(data->base + reg->triminfo_data);
+	}
 	data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK;
 	data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) &
 				EXYNOS_TMU_TEMP_MASK);
 
-	if ((pdata->min_efuse_value > data->temp_error1) ||
-			(data->temp_error1 > pdata->max_efuse_value) ||
-			(data->temp_error2 != 0))
-		data->temp_error1 = pdata->efuse_value;
+	if (!data->temp_error1 ||
+		(pdata->min_efuse_value > data->temp_error1) ||
+		(data->temp_error1 > pdata->max_efuse_value))
+		data->temp_error1 = pdata->efuse_value & EXYNOS_TMU_TEMP_MASK;
+
+	if (!data->temp_error2)
+		data->temp_error2 =
+			(pdata->efuse_value >> reg->triminfo_85_shift) &
+			EXYNOS_TMU_TEMP_MASK;
 
+skip_calib_data:
 	/* Count trigger levels to be enabled */
 	for (i = 0; i < MAX_THRESHOLD_LEVS; i++)
 		if (pdata->trigger_levels[i])
@@ -185,9 +223,10 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 			data->base + reg->threshold_th0 + i * 4);
 
 		writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
-	} else if (data->soc == SOC_ARCH_EXYNOS) {
+	} else if (data->soc == SOC_ARCH_EXYNOS ||
+			data->soc == SOC_ARCH_EXYNOS5440) {
 		/* Write temperature code for rising and falling threshold */
-		for (i = 0; i < trigger_levs; i++) {
+		for (i = 0; i < trigger_levs && i < 4 ; i++) {
 			threshold_code = temp_to_code(data,
 						pdata->trigger_levels[i]);
 			if (threshold_code < 0) {
@@ -218,7 +257,29 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 		writel((reg->inten_rise_mask << reg->inten_rise_shift) |
 			(reg->inten_fall_mask << reg->inten_fall_shift),
 				data->base + reg->tmu_intclear);
+
+		/* if 5th threshold limit is also present, use TH2 register */
+		i = 4;
+		if (pdata->trigger_levels[i]) {
+			threshold_code = temp_to_code(data,
+						pdata->trigger_levels[i]);
+			if (threshold_code < 0) {
+				ret = threshold_code;
+				goto out;
+			}
+			rising_threshold = threshold_code << 24;
+			writel(rising_threshold,
+				data->base + reg->threshold_th2);
+			if (pdata->trigger_type[i] == HW_TRIP) {
+				con = readl(data->base + reg->tmu_ctrl);
+				con |= (1 << reg->therm_trip_en_shift);
+				writel(con, data->base + reg->tmu_ctrl);
+			}
+		}
 	}
+	/*Clear the PMIN in the common TMU register*/
+	if (reg->tmu_pmin && !data->id)
+		writel(0, data->base_common + reg->tmu_pmin);
 out:
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
@@ -254,6 +315,11 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
 		con |= (pdata->noise_cancel_mode << reg->therm_trip_mode_shift);
 	}
 
+	if (pdata->cal_mode == HW_MODE) {
+		con &= ~(reg->calib_mode_mask << reg->calib_mode_shift);
+		con |= pdata->cal_type << reg->calib_mode_shift;
+	}
+
 	if (on) {
 		con |= (1 << reg->core_en_shift);
 		interrupt_en =
@@ -317,9 +383,11 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
 	if (temp) {
 		temp /= MCELSIUS;
 
-		val = (EXYNOS_EMUL_TIME << reg->emul_time_shift) |
-			(temp_to_code(data, temp)
-			 << reg->emul_temp_shift) | EXYNOS_EMUL_ENABLE;
+		if (data->soc == SOC_ARCH_EXYNOS && reg->emul_time_shift)
+			val |= (EXYNOS_EMUL_TIME << reg->emul_time_shift);
+
+		val |= (temp_to_code(data, temp) << reg->emul_temp_shift) |
+			EXYNOS_EMUL_ENABLE;
 	} else {
 		val &= ~EXYNOS_EMUL_ENABLE;
 	}
@@ -343,7 +411,14 @@ static void exynos_tmu_work(struct work_struct *work)
 			struct exynos_tmu_data, irq_work);
 	struct exynos_tmu_platform_data *pdata = data->pdata;
 	struct exynos_tmu_registers *reg = pdata->registers;
-	unsigned int val_irq;
+	unsigned int val_irq, val_type;
+
+	/* Find which sensor generated this interrupt */
+	if (reg->tmu_irqstatus) {
+		val_type = readl(data->base_common + reg->tmu_irqstatus);
+		if (!((val_type >> data->id) & 0x1))
+			goto out;
+	}
 
 	exynos_report_trigger(data->reg_conf);
 	mutex_lock(&data->lock);
@@ -355,7 +430,7 @@ static void exynos_tmu_work(struct work_struct *work)
 
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
-
+out:
 	enable_irq(data->irq);
 }
 
@@ -383,6 +458,10 @@ static const struct of_device_id exynos_tmu_match[] = {
 		.compatible = "samsung,exynos5250-tmu",
 		.data = (void *)EXYNOS5250_TMU_DRV_DATA,
 	},
+	{
+		.compatible = "samsung,exynos5440-tmu",
+		.data = (void *)EXYNOS5440_TMU_DRV_DATA,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, exynos_tmu_match);
@@ -420,6 +499,7 @@ static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
 static int exynos_map_dt_data(struct platform_device *pdev)
 {
 	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+	struct exynos_tmu_platform_data *pdata = data->pdata;
 	struct resource res;
 
 	if (!data)
@@ -436,7 +516,7 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 	}
 
 	if (of_address_to_resource(pdev->dev.of_node, 0, &res)) {
-		dev_err(&pdev->dev, "failed to get Resource\n");
+		dev_err(&pdev->dev, "failed to get Resource 0\n");
 		return -ENODEV;
 	}
 
@@ -445,6 +525,26 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Failed to ioremap memory\n");
 		return -ENOMEM;
 	}
+
+	/*
+	 * Check if the TMU is multi instance type and then try to map the
+	 * memory of common registers.
+	 */
+	if (!TMU_SUPPORTS(pdata, MULTI_INST))
+		return 0;
+
+	if (of_address_to_resource(pdev->dev.of_node, 1, &res)) {
+		dev_err(&pdev->dev, "failed to get Resource 1\n");
+		return -ENODEV;
+	}
+
+	data->base_common = devm_ioremap(&pdev->dev, res.start,
+					resource_size(&res));
+	if (!data->base) {
+		dev_err(&pdev->dev, "Failed to ioremap memory\n");
+		return -ENOMEM;
+	}
+
 	return 0;
 }
 
@@ -496,7 +596,8 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 		return ret;
 
 	if (pdata->type == SOC_ARCH_EXYNOS ||
-				pdata->type == SOC_ARCH_EXYNOS4210)
+		pdata->type == SOC_ARCH_EXYNOS4210 ||
+		pdata->type == SOC_ARCH_EXYNOS5440)
 		data->soc = pdata->type;
 	else {
 		ret = -EINVAL;
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
index 4dd843d..2af2567 100644
--- a/drivers/thermal/samsung/exynos_tmu.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -43,6 +43,7 @@ enum trigger_type {
 enum soc_type {
 	SOC_ARCH_EXYNOS4210 = 1,
 	SOC_ARCH_EXYNOS,
+	SOC_ARCH_EXYNOS5440,
 };
 
 /**
@@ -61,6 +62,7 @@ enum soc_type {
 #define TMU_SUPPORT_MULTI_INST			BIT(1)
 #define TMU_SUPPORT_TRIM_RELOAD			BIT(2)
 #define TMU_SUPPORT_FALLING_TRIP		BIT(3)
+#define TMU_SUPPORT_READY_STATUS		BIT(4)
 
 #define TMU_SUPPORTS(a, b)	(a->features & TMU_SUPPORT_ ## b)
 
@@ -85,6 +87,8 @@ struct exynos_tmu_registers {
 	u32	therm_trip_en_shift;
 	u32	buf_slope_sel_shift;
 	u32	buf_slope_sel_mask;
+	u32	calib_mode_shift;
+	u32	calib_mode_mask;
 	u32	therm_trip_tq_en_shift;
 	u32	core_en_shift;
 
@@ -137,6 +141,9 @@ struct exynos_tmu_registers {
 	u32	emul_temp_shift;
 	u32	emul_time_shift;
 	u32	emul_time_mask;
+
+	u32	tmu_irqstatus;
+	u32	tmu_pmin;
 };
 
 /**
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
index 8a587d4..25629e6 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.c
+++ b/drivers/thermal/samsung/exynos_tmu_data.c
@@ -79,6 +79,7 @@ struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
 	.freq_tab_count = 2,
 	.type = SOC_ARCH_EXYNOS4210,
 	.registers = &exynos4210_tmu_registers,
+	.features = (TMU_SUPPORT_READY_STATUS),
 };
 #endif
 
@@ -155,6 +156,69 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
 	.type = SOC_ARCH_EXYNOS,
 	.registers = &exynos5250_tmu_registers,
 	.features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD |
-			TMU_SUPPORT_FALLING_TRIP),
+			TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS),
+};
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS5440)
+static struct exynos_tmu_registers exynos5440_tmu_registers = {
+	.triminfo_data = EXYNOS5440_TMU_S0_7_TRIM,
+	.triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
+	.triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
+	.tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL,
+	.buf_vref_sel_shift = EXYNOS_TMU_REF_VOLTAGE_SHIFT,
+	.buf_vref_sel_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
+	.therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT,
+	.therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK,
+	.therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT,
+	.buf_slope_sel_shift = EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT,
+	.buf_slope_sel_mask = EXYNOS_TMU_BUF_SLOPE_SEL_MASK,
+	.calib_mode_shift = EXYNOS_TMU_CALIB_MODE_SHIFT,
+	.calib_mode_mask = EXYNOS_TMU_CALIB_MODE_MASK,
+	.core_en_shift = EXYNOS_TMU_CORE_EN_SHIFT,
+	.tmu_status = EXYNOS5440_TMU_S0_7_STATUS,
+	.tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP,
+	.threshold_th0 = EXYNOS5440_TMU_S0_7_TH0,
+	.threshold_th1 = EXYNOS5440_TMU_S0_7_TH1,
+	.threshold_th2 = EXYNOS5440_TMU_S0_7_TH2,
+	.tmu_inten = EXYNOS5440_TMU_S0_7_IRQEN,
+	.inten_rise_mask = EXYNOS5440_TMU_RISE_INT_MASK,
+	.inten_rise_shift = EXYNOS5440_TMU_RISE_INT_SHIFT,
+	.inten_fall_mask = EXYNOS5440_TMU_FALL_INT_MASK,
+	.inten_fall_shift = EXYNOS5440_TMU_FALL_INT_SHIFT,
+	.inten_rise0_shift = EXYNOS5440_TMU_INTEN_RISE0_SHIFT,
+	.inten_rise1_shift = EXYNOS5440_TMU_INTEN_RISE1_SHIFT,
+	.inten_rise2_shift = EXYNOS5440_TMU_INTEN_RISE2_SHIFT,
+	.inten_rise3_shift = EXYNOS5440_TMU_INTEN_RISE3_SHIFT,
+	.inten_fall0_shift = EXYNOS5440_TMU_INTEN_FALL0_SHIFT,
+	.tmu_evten = EXYNOS5440_TMU_S0_7_EVTEN,
+	.tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ,
+	.tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ,
+	.tmu_irqstatus = EXYNOS5440_TMU_IRQ_STATUS,
+	.emul_con = EXYNOS5440_TMU_S0_7_DEBUG,
+	.emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT,
+	.tmu_pmin = EXYNOS5440_TMU_PMIN,
+};
+struct exynos_tmu_platform_data const exynos5440_default_tmu_data = {
+	.trigger_levels[0] = 100,
+	.trigger_levels[4] = 105,
+	.trigger_enable[0] = 1,
+	.trigger_type[0] = 1,
+	.trigger_type[4] = 2,
+	.gain = 5,
+	.reference_voltage = 16,
+	.noise_cancel_mode = 4,
+	.cal_type = TYPE_TWO_POINT_TRIMMING,
+	.cal_mode = 0,
+	.efuse_value = 0x5b2d,
+	.min_efuse_value = 16,
+	.max_efuse_value = 76,
+	.first_point_trim = 25,
+	.second_point_trim = 70,
+	.default_temp_offset = 25,
+	.type = SOC_ARCH_EXYNOS5440,
+	.registers = &exynos5440_tmu_registers,
+	.features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP |
+			TMU_SUPPORT_MULTI_INST),
 };
 #endif
diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
index c11acb3..c1b442a 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.h
+++ b/drivers/thermal/samsung/exynos_tmu_data.h
@@ -75,6 +75,8 @@
 #define EXYNOS_TMU_TRIP_MODE_SHIFT	13
 #define EXYNOS_TMU_TRIP_MODE_MASK	0x7
 #define EXYNOS_TMU_THERM_TRIP_EN_SHIFT	12
+#define EXYNOS_TMU_CALIB_MODE_SHIFT	4
+#define EXYNOS_TMU_CALIB_MODE_MASK	0x3
 
 #define EXYNOS_TMU_INTEN_RISE0_SHIFT	0
 #define EXYNOS_TMU_INTEN_RISE1_SHIFT	4
@@ -93,6 +95,37 @@
 #define EXYNOS_EMUL_ENABLE	0x1
 #endif /* CONFIG_THERMAL_EMULATION */
 
+/*exynos5440 specific registers*/
+#define EXYNOS5440_TMU_S0_7_TRIM		0x000
+#define EXYNOS5440_TMU_S0_7_CTRL		0x020
+#define EXYNOS5440_TMU_S0_7_DEBUG		0x040
+#define EXYNOS5440_TMU_S0_7_STATUS		0x060
+#define EXYNOS5440_TMU_S0_7_TEMP		0x0f0
+#define EXYNOS5440_TMU_S0_7_TH0			0x110
+#define EXYNOS5440_TMU_S0_7_TH1			0x130
+#define EXYNOS5440_TMU_S0_7_TH2			0x150
+#define EXYNOS5440_TMU_S0_7_EVTEN		0x1F0
+#define EXYNOS5440_TMU_S0_7_IRQEN		0x210
+#define EXYNOS5440_TMU_S0_7_IRQ			0x230
+/* exynos5440 common registers */
+#define EXYNOS5440_TMU_IRQ_STATUS		0x000
+#define EXYNOS5440_TMU_PMIN			0x004
+#define EXYNOS5440_TMU_TEMP			0x008
+
+#define EXYNOS5440_EFUSE_SWAP_OFFSET		8
+#define EXYNOS5440_TMU_RISE_INT_MASK		0xf
+#define EXYNOS5440_TMU_RISE_INT_SHIFT		0
+#define EXYNOS5440_TMU_FALL_INT_MASK		0xf
+#define EXYNOS5440_TMU_FALL_INT_SHIFT		4
+#define EXYNOS5440_TMU_INTEN_RISE0_SHIFT	0
+#define EXYNOS5440_TMU_INTEN_RISE1_SHIFT	1
+#define EXYNOS5440_TMU_INTEN_RISE2_SHIFT	2
+#define EXYNOS5440_TMU_INTEN_RISE3_SHIFT	3
+#define EXYNOS5440_TMU_INTEN_FALL0_SHIFT	4
+#define EXYNOS5440_TMU_INTEN_FALL1_SHIFT	5
+#define EXYNOS5440_TMU_INTEN_FALL2_SHIFT	6
+#define EXYNOS5440_TMU_INTEN_FALL3_SHIFT	7
+
 #if defined(CONFIG_CPU_EXYNOS4210)
 extern struct exynos_tmu_platform_data const exynos4210_default_tmu_data;
 #define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
@@ -107,4 +140,11 @@ extern struct exynos_tmu_platform_data const exynos5250_default_tmu_data;
 #define EXYNOS5250_TMU_DRV_DATA (NULL)
 #endif
 
+#if defined(CONFIG_SOC_EXYNOS5440)
+extern struct exynos_tmu_platform_data const exynos5440_default_tmu_data;
+#define EXYNOS5440_TMU_DRV_DATA (&exynos5440_default_tmu_data)
+#else
+#define EXYNOS5440_TMU_DRV_DATA (NULL)
+#endif
+
 #endif /*_LINUX_EXYNOS_TMU_DATA_H*/
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 19/20] Documentation: thermal: Explain the exynos thermal driver model
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (17 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 18/20] thermal: exynos: Add support for exynos5440 TMU sensor Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  2013-04-26 10:37 ` [PATCH V2 20/20] ARM: dts: Add device tree node for exynos5440 TMU controller Amit Daniel Kachhap
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch updates the documentation to explain the driver model
and file layout.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 Documentation/thermal/exynos_thermal |   43 ++++++++++++++++++++++++++-------
 1 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/Documentation/thermal/exynos_thermal b/Documentation/thermal/exynos_thermal
index 2b46f67..9010c44 100644
--- a/Documentation/thermal/exynos_thermal
+++ b/Documentation/thermal/exynos_thermal
@@ -1,17 +1,17 @@
-Kernel driver exynos4_tmu
+Kernel driver exynos_tmu
 =================
 
 Supported chips:
-* ARM SAMSUNG EXYNOS4 series of SoC
-  Prefix: 'exynos4-tmu'
+* ARM SAMSUNG EXYNOS4, EXYNOS5 series of SoC
   Datasheet: Not publicly available
 
 Authors: Donggeun Kim <dg77.kim@samsung.com>
+Authors: Amit Daniel <amit.daniel@samsung.com>
 
-Description
------------
+TMU controller Description:
+---------------------------
 
-This driver allows to read temperature inside SAMSUNG EXYNOS4 series of SoC.
+This driver allows to read temperature inside SAMSUNG EXYNOS4/5 series of SoC.
 
 The chip only exposes the measured 8-bit temperature code value
 through a register.
@@ -34,9 +34,9 @@ The three equations are:
   TI2: Trimming info for 85 degree Celsius (stored at TRIMINFO register)
        Temperature code measured at 85 degree Celsius which is unchanged
 
-TMU(Thermal Management Unit) in EXYNOS4 generates interrupt
+TMU(Thermal Management Unit) in EXYNOS4/5 generates interrupt
 when temperature exceeds pre-defined levels.
-The maximum number of configurable threshold is four.
+The maximum number of configurable threshold is five.
 The threshold levels are defined as follows:
   Level_0: current temperature > trigger_level_0 + threshold
   Level_1: current temperature > trigger_level_1 + threshold
@@ -47,6 +47,31 @@ The threshold levels are defined as follows:
   through the corresponding registers.
 
 When an interrupt occurs, this driver notify kernel thermal framework
-with the function exynos4_report_trigger.
+with the function exynos_report_trigger.
 Although an interrupt condition for level_0 can be set,
 it can be used to synchronize the cooling action.
+
+TMU driver description:
+-----------------------
+
+The exynos thermal driver is structured as,
+
+					Kernel Core thermal framework
+				(thermal_core.c, step_wise.c, cpu_cooling.c)
+								^
+								|
+								|
+TMU configuration data -------> TMU Driver  <------> Exynos Core thermal wrapper
+(exynos_tmu_data.c)	      (exynos_tmu.c)	   (exynos_thermal_common.c)
+(exynos_tmu_data.h)	      (exynos_tmu.h)	   (exynos_thermal_common.h)
+
+a) TMU configuration data: This consist of TMU register offsets/bitfields
+		described through structure exynos_tmu_registers. Also several
+		other platform data (struct exynos_tmu_platform_data) members
+		are used to configure the TMU.
+b) TMU driver: This component initialises the TMU controller and sets different
+		thresholds. It invokes core thermal implementation with the call
+		exynos_report_trigger.
+c) Exynos Core thermal wrapper: This provides 3 wrapper function to use the
+		Kernel core thermal framework. They are exynos_unregister_thermal,
+		exynos_register_thermal and exynos_report_trigger.
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH V2 20/20] ARM: dts: Add device tree node for exynos5440 TMU controller
  2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
                   ` (18 preceding siblings ...)
  2013-04-26 10:37 ` [PATCH V2 19/20] Documentation: thermal: Explain the exynos thermal driver model Amit Daniel Kachhap
@ 2013-04-26 10:37 ` Amit Daniel Kachhap
  19 siblings, 0 replies; 31+ messages in thread
From: Amit Daniel Kachhap @ 2013-04-26 10:37 UTC (permalink / raw)
  To: linux-pm
  Cc: Zhang Rui, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

This patch adds device node for TMU controller. There are 3
instances of the controllers so 3 nodes are created.

Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
---
 arch/arm/boot/dts/exynos5440.dtsi |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi
index 9a99755..7842f5f 100644
--- a/arch/arm/boot/dts/exynos5440.dtsi
+++ b/arch/arm/boot/dts/exynos5440.dtsi
@@ -16,6 +16,12 @@
 
 	interrupt-parent = <&gic>;
 
+ 	aliases {
+		tmuctrl0 = &tmuctrl_0;
+		tmuctrl1 = &tmuctrl_1;
+		tmuctrl2 = &tmuctrl_2;
+ 	};
+
 	gic:interrupt-controller@2E0000 {
 		compatible = "arm,cortex-a15-gic";
 		#interrupt-cells = <3>;
@@ -162,4 +168,28 @@
 		reg = <0x130000 0x1000>;
 		interrupts = <0 17 0>, <0 16 0>;
 	};
+
+	tmuctrl_0: tmuctrl@160118 {
+		compatible = "samsung,exynos5440-tmu";
+		reg = <0x160118 0x230>, <0x160368 0x10>;
+		interrupts = <0 58 0>;
+		clocks = <&clock 21>;
+		clock-names = "tmu_apbif";
+	};
+
+	tmuctrl_1: tmuctrl@16011C {
+		compatible = "samsung,exynos5440-tmu";
+		reg = <0x16011C 0x230>, <0x160368 0x10>;
+		interrupts = <0 58 0>;
+		clocks = <&clock 21>;
+		clock-names = "tmu_apbif";
+	};
+
+	tmuctrl_2: tmuctrl@160120 {
+		compatible = "samsung,exynos5440-tmu";
+		reg = <0x160120 0x230>, <0x160368 0x10>;
+		interrupts = <0 58 0>;
+		clocks = <&clock 21>;
+		clock-names = "tmu_apbif";
+	};
 };
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory
  2013-04-26 10:37 ` [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory Amit Daniel Kachhap
@ 2013-05-06 15:05   ` Zhang Rui
  2013-05-07 10:21     ` Tomasz Figa
  2013-05-07 13:12     ` amit daniel kachhap
  0 siblings, 2 replies; 31+ messages in thread
From: Zhang Rui @ 2013-05-06 15:05 UTC (permalink / raw)
  To: Amit Daniel Kachhap
  Cc: linux-pm, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

On Fri, 2013-04-26 at 16:07 +0530, Amit Daniel Kachhap wrote:
> This movement of files is done for easy maintenance and adding more
> new sensor's support for exynos platform easily . This will also help in
> bifurcating exynos common, sensor driver and sensor data related parts.
> 
> Acked-by: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
> ---
>  drivers/thermal/Kconfig                        |   13 +++++--------
>  drivers/thermal/Makefile                       |    2 +-
>  drivers/thermal/samsung/Kconfig                |    9 +++++++++
>  drivers/thermal/samsung/Makefile               |    4 ++++
>  drivers/thermal/{ => samsung}/exynos_thermal.c |    0
>  5 files changed, 19 insertions(+), 9 deletions(-)
>  create mode 100644 drivers/thermal/samsung/Kconfig
>  create mode 100644 drivers/thermal/samsung/Makefile
>  rename drivers/thermal/{ => samsung}/exynos_thermal.c (100%)
> 
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index 5e3c025..081ddc5 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -114,14 +114,6 @@ config KIRKWOOD_THERMAL
>  	  Support for the Kirkwood thermal sensor driver into the Linux thermal
>  	  framework. Only kirkwood 88F6282 and 88F6283 have this sensor.
>  
> -config EXYNOS_THERMAL
> -	tristate "Temperature sensor on Samsung EXYNOS"
> -	depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
> -	depends on CPU_THERMAL
> -	help
> -	  If you say yes here you get support for TMU (Thermal Management
> -	  Unit) on SAMSUNG EXYNOS series of SoC.
> -
>  config DOVE_THERMAL
>  	tristate "Temperature sensor on Marvell Dove SoCs"
>  	depends on ARCH_DOVE
> @@ -169,4 +161,9 @@ config INTEL_POWERCLAMP
>  	  enforce idle time which results in more package C-state residency. The
>  	  user interface is exposed via generic thermal framework.
>  
> +menu "Exynos thermal drivers"

would it be more proper to use "Samsung thermal drivers" or "Samsung
Exynos thermal drivers" instead?

> +depends on PLAT_SAMSUNG
> +source "drivers/thermal/samsung/Kconfig"
> +endmenu
> +
sorry I know few about arm,
could you tell me the difference between
CONFIG_ARCH_EXYNOS4/CONFIG_ARCH_EXYNOS5 and CONFIG_PLAT_SAMSUNG please,
I do not see the dependency between these in Kconfig file?

thanks,
rui
>  endif
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index c054d41..b3063a9 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -17,7 +17,7 @@ thermal_sys-$(CONFIG_CPU_THERMAL)	+= cpu_cooling.o
>  obj-$(CONFIG_SPEAR_THERMAL)	+= spear_thermal.o
>  obj-$(CONFIG_RCAR_THERMAL)	+= rcar_thermal.o
>  obj-$(CONFIG_KIRKWOOD_THERMAL)  += kirkwood_thermal.o
> -obj-$(CONFIG_EXYNOS_THERMAL)	+= exynos_thermal.o
> +obj-y				+= samsung/
>  obj-$(CONFIG_DOVE_THERMAL)  	+= dove_thermal.o
>  obj-$(CONFIG_DB8500_THERMAL)	+= db8500_thermal.o
>  obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
> diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
> new file mode 100644
> index 0000000..2d3d9dc
> --- /dev/null
> +++ b/drivers/thermal/samsung/Kconfig
> @@ -0,0 +1,9 @@
> +config EXYNOS_THERMAL
> +	tristate "Temperature sensor on Samsung EXYNOS"
> +	depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
> +	depends on CPU_THERMAL
> +	help
> +	  If you say yes here you get support for TMU (Thermal Management
> +	  Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
> +	  the exynos thermal driver with the core thermal layer and cpu
> +	  cooling API's.
> diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
> new file mode 100644
> index 0000000..1fe6d93
> --- /dev/null
> +++ b/drivers/thermal/samsung/Makefile
> @@ -0,0 +1,4 @@
> +#
> +# Samsung thermal specific Makefile
> +#
> +obj-$(CONFIG_EXYNOS_THERMAL)	+= exynos_thermal.o
> diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/samsung/exynos_thermal.c
> similarity index 100%
> rename from drivers/thermal/exynos_thermal.c
> rename to drivers/thermal/samsung/exynos_thermal.c



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH V2 02/20] thermal: exynos: Bifurcate exynos thermal common and tmu controller code
  2013-04-26 10:37 ` [PATCH V2 02/20] thermal: exynos: Bifurcate exynos thermal common and tmu controller code Amit Daniel Kachhap
@ 2013-05-06 15:16   ` Zhang Rui
  2013-05-07 13:32     ` amit daniel kachhap
  0 siblings, 1 reply; 31+ messages in thread
From: Zhang Rui @ 2013-05-06 15:16 UTC (permalink / raw)
  To: Amit Daniel Kachhap
  Cc: linux-pm, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

On Fri, 2013-04-26 at 16:07 +0530, Amit Daniel Kachhap wrote:
> 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>
> Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
> ---
>  drivers/thermal/samsung/Kconfig                 |   26 +-
>  drivers/thermal/samsung/Makefile                |    4 +-
>  drivers/thermal/samsung/exynos_thermal.c        |  421 +----------------------
>  drivers/thermal/samsung/exynos_thermal_common.c |  389 +++++++++++++++++++++
>  drivers/thermal/samsung/exynos_thermal_common.h |   71 ++++
>  5 files changed, 491 insertions(+), 420 deletions(-)
>  create mode 100644 drivers/thermal/samsung/exynos_thermal_common.c
>  create mode 100644 drivers/thermal/samsung/exynos_thermal_common.h
> 
> diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
> index 2d3d9dc..1e3ba31 100644
> --- a/drivers/thermal/samsung/Kconfig
> +++ b/drivers/thermal/samsung/Kconfig
> @@ -1,9 +1,21 @@
> -config EXYNOS_THERMAL
> -	tristate "Temperature sensor on Samsung EXYNOS"
> +config EXYNOS_COMMON

EXYNOS_COMMON is misleading here, better use EXYNOS_THERMAL_COMMON?

> +	bool "Common thermal support for EXYNOS SOC's"
>  	depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
> -	depends on CPU_THERMAL
>  	help
> -	  If you say yes here you get support for TMU (Thermal Management
> -	  Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
> -	  the exynos thermal driver with the core thermal layer and cpu
> -	  cooling API's.
> +	  If you say yes here you get support for EXYNOS TMU
> +	  (Thermal Management Unit) common registration/unregistration
> +	  functions to the core thermal layer and also to use the generic
> +	  cpu cooling API's.
> +
> +if EXYNOS_COMMON
> +
> +config EXYNOS_SOC_THERMAL
> +	tristate "Temperature sensor on Samsung EXYNOS series SOC"
> +	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250)
> + 	help
> +	  If you say yes here you can enable TMU (Thermal Management Unit) on
> +	  SAMSUNG EXYNOS 4210, 4412, 4414 and 5250 series of SoC. This option
> +	  initialises the TMU controller and registers/unregisters with exynos
> +	  common thermal layer.
> +
> +endif
> diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
> index 1fe6d93..fcda5b4 100644
> --- a/drivers/thermal/samsung/Makefile
> +++ b/drivers/thermal/samsung/Makefile
> @@ -1,4 +1,6 @@
>  #
>  # Samsung thermal specific Makefile
>  #
> -obj-$(CONFIG_EXYNOS_THERMAL)	+= exynos_thermal.o
> +obj-$(CONFIG_EXYNOS_SOC_THERMAL)		+= exynos_soc_thermal.o
> +exynos_soc_thermal-y				:= exynos_thermal.o
> +exynos_soc_thermal-$(CONFIG_EXYNOS_COMMON)	+= exynos_thermal_common.o

the Makefile suggests that exynos_soc_thermal driver could be built
without CONFIG_EXYNOS_COMMON.
But the Kconfig file shows that exynos_soc_thermal depends on
CONFIG_EXYNOS_COMMON.
If exynos_thermal_common.c contains the code to interact with the
generic thermal layer and you do not want a soc driver without thermal
support, just remove CONFIG_EXYNOS_COMMON and always build it into
exynos_soc_thermal.o.
what do you think?
 
thanks,
rui
> diff --git a/drivers/thermal/samsung/exynos_thermal.c b/drivers/thermal/samsung/exynos_thermal.c
> index d20ce9e..4c85945 100644
> --- a/drivers/thermal/samsung/exynos_thermal.c
> +++ b/drivers/thermal/samsung/exynos_thermal.c
> @@ -21,23 +21,19 @@
>   *
>   */
>  
> -#include <linux/module.h>
> -#include <linux/err.h>
> -#include <linux/kernel.h>
> -#include <linux/slab.h>
> -#include <linux/platform_device.h>
> -#include <linux/interrupt.h>
>  #include <linux/clk.h>
> -#include <linux/workqueue.h>
> -#include <linux/sysfs.h>
> -#include <linux/kobject.h>
>  #include <linux/io.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/kobject.h>
> +#include <linux/module.h>
>  #include <linux/mutex.h>
> -#include <linux/platform_data/exynos_thermal.h>
> -#include <linux/thermal.h>
> -#include <linux/cpufreq.h>
> -#include <linux/cpu_cooling.h>
>  #include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/platform_data/exynos_thermal.h>
> +#include <linux/slab.h>
> +#include <linux/workqueue.h>
> +#include "exynos_thermal_common.h"
>  
>  /* Exynos generic registers */
>  #define EXYNOS_TMU_REG_TRIMINFO		0x0
> @@ -88,16 +84,6 @@
>  #define EFUSE_MIN_VALUE 40
>  #define EFUSE_MAX_VALUE 100
>  
> -/* In-kernel thermal framework related macros & definations */
> -#define SENSOR_NAME_LEN	16
> -#define MAX_TRIP_COUNT	8
> -#define MAX_COOLING_DEVICE 4
> -#define MAX_THRESHOLD_LEVS 4
> -
> -#define ACTIVE_INTERVAL 500
> -#define IDLE_INTERVAL 10000
> -#define MCELSIUS	1000
> -
>  #ifdef CONFIG_THERMAL_EMULATION
>  #define EXYNOS_EMUL_TIME	0x57F0
>  #define EXYNOS_EMUL_TIME_SHIFT	16
> @@ -106,17 +92,6 @@
>  #define EXYNOS_EMUL_ENABLE	0x1
>  #endif /* CONFIG_THERMAL_EMULATION */
>  
> -/* CPU Zone information */
> -#define PANIC_ZONE      4
> -#define WARN_ZONE       3
> -#define MONITOR_ZONE    2
> -#define SAFE_ZONE       1
> -
> -#define GET_ZONE(trip) (trip + 2)
> -#define GET_TRIP(zone) (zone - 2)
> -
> -#define EXYNOS_ZONE_COUNT	3
> -
>  struct exynos_tmu_data {
>  	struct exynos_tmu_platform_data *pdata;
>  	struct resource *mem;
> @@ -129,384 +104,6 @@ struct exynos_tmu_data {
>  	u8 temp_error1, temp_error2;
>  };
>  
> -struct	thermal_trip_point_conf {
> -	int trip_val[MAX_TRIP_COUNT];
> -	int trip_count;
> -	u8 trigger_falling;
> -};
> -
> -struct	thermal_cooling_conf {
> -	struct freq_clip_table freq_data[MAX_TRIP_COUNT];
> -	int freq_clip_count;
> -};
> -
> -struct thermal_sensor_conf {
> -	char name[SENSOR_NAME_LEN];
> -	int (*read_temperature)(void *data);
> -	int (*write_emul_temp)(void *drv_data, unsigned long temp);
> -	struct thermal_trip_point_conf trip_data;
> -	struct thermal_cooling_conf cooling_data;
> -	void *private_data;
> -};
> -
> -struct exynos_thermal_zone {
> -	enum thermal_device_mode mode;
> -	struct thermal_zone_device *therm_dev;
> -	struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
> -	unsigned int cool_dev_size;
> -	struct platform_device *exynos4_dev;
> -	struct thermal_sensor_conf *sensor_conf;
> -	bool bind;
> -};
> -
> -static struct exynos_thermal_zone *th_zone;
> -static void exynos_unregister_thermal(void);
> -static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
> -
> -/* Get mode callback functions for thermal zone */
> -static int exynos_get_mode(struct thermal_zone_device *thermal,
> -			enum thermal_device_mode *mode)
> -{
> -	if (th_zone)
> -		*mode = th_zone->mode;
> -	return 0;
> -}
> -
> -/* Set mode callback functions for thermal zone */
> -static int exynos_set_mode(struct thermal_zone_device *thermal,
> -			enum thermal_device_mode mode)
> -{
> -	if (!th_zone->therm_dev) {
> -		pr_notice("thermal zone not registered\n");
> -		return 0;
> -	}
> -
> -	mutex_lock(&th_zone->therm_dev->lock);
> -
> -	if (mode == THERMAL_DEVICE_ENABLED &&
> -		!th_zone->sensor_conf->trip_data.trigger_falling)
> -		th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
> -	else
> -		th_zone->therm_dev->polling_delay = 0;
> -
> -	mutex_unlock(&th_zone->therm_dev->lock);
> -
> -	th_zone->mode = mode;
> -	thermal_zone_device_update(th_zone->therm_dev);
> -	pr_info("thermal polling set for duration=%d msec\n",
> -				th_zone->therm_dev->polling_delay);
> -	return 0;
> -}
> -
> -
> -/* Get trip type callback functions for thermal zone */
> -static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
> -				 enum thermal_trip_type *type)
> -{
> -	switch (GET_ZONE(trip)) {
> -	case MONITOR_ZONE:
> -	case WARN_ZONE:
> -		*type = THERMAL_TRIP_ACTIVE;
> -		break;
> -	case PANIC_ZONE:
> -		*type = THERMAL_TRIP_CRITICAL;
> -		break;
> -	default:
> -		return -EINVAL;
> -	}
> -	return 0;
> -}
> -
> -/* Get trip temperature callback functions for thermal zone */
> -static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
> -				unsigned long *temp)
> -{
> -	if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
> -		return -EINVAL;
> -
> -	*temp = th_zone->sensor_conf->trip_data.trip_val[trip];
> -	/* convert the temperature into millicelsius */
> -	*temp = *temp * MCELSIUS;
> -
> -	return 0;
> -}
> -
> -/* Get critical temperature callback functions for thermal zone */
> -static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
> -				unsigned long *temp)
> -{
> -	int ret;
> -	/* Panic zone */
> -	ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
> -	return ret;
> -}
> -
> -/* Bind callback functions for thermal zone */
> -static int exynos_bind(struct thermal_zone_device *thermal,
> -			struct thermal_cooling_device *cdev)
> -{
> -	int ret = 0, i, tab_size, level;
> -	struct freq_clip_table *tab_ptr, *clip_data;
> -	struct thermal_sensor_conf *data = th_zone->sensor_conf;
> -
> -	tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
> -	tab_size = data->cooling_data.freq_clip_count;
> -
> -	if (tab_ptr == NULL || tab_size == 0)
> -		return -EINVAL;
> -
> -	/* find the cooling device registered*/
> -	for (i = 0; i < th_zone->cool_dev_size; i++)
> -		if (cdev == th_zone->cool_dev[i])
> -			break;
> -
> -	/* No matching cooling device */
> -	if (i == th_zone->cool_dev_size)
> -		return 0;
> -
> -	/* Bind the thermal zone to the cpufreq cooling device */
> -	for (i = 0; i < tab_size; i++) {
> -		clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
> -		level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max);
> -		if (level == THERMAL_CSTATE_INVALID)
> -			return 0;
> -		switch (GET_ZONE(i)) {
> -		case MONITOR_ZONE:
> -		case WARN_ZONE:
> -			if (thermal_zone_bind_cooling_device(thermal, i, cdev,
> -								level, 0)) {
> -				pr_err("error binding cdev inst %d\n", i);
> -				ret = -EINVAL;
> -			}
> -			th_zone->bind = true;
> -			break;
> -		default:
> -			ret = -EINVAL;
> -		}
> -	}
> -
> -	return ret;
> -}
> -
> -/* Unbind callback functions for thermal zone */
> -static int exynos_unbind(struct thermal_zone_device *thermal,
> -			struct thermal_cooling_device *cdev)
> -{
> -	int ret = 0, i, tab_size;
> -	struct thermal_sensor_conf *data = th_zone->sensor_conf;
> -
> -	if (th_zone->bind == false)
> -		return 0;
> -
> -	tab_size = data->cooling_data.freq_clip_count;
> -
> -	if (tab_size == 0)
> -		return -EINVAL;
> -
> -	/* find the cooling device registered*/
> -	for (i = 0; i < th_zone->cool_dev_size; i++)
> -		if (cdev == th_zone->cool_dev[i])
> -			break;
> -
> -	/* No matching cooling device */
> -	if (i == th_zone->cool_dev_size)
> -		return 0;
> -
> -	/* Bind the thermal zone to the cpufreq cooling device */
> -	for (i = 0; i < tab_size; i++) {
> -		switch (GET_ZONE(i)) {
> -		case MONITOR_ZONE:
> -		case WARN_ZONE:
> -			if (thermal_zone_unbind_cooling_device(thermal, i,
> -								cdev)) {
> -				pr_err("error unbinding cdev inst=%d\n", i);
> -				ret = -EINVAL;
> -			}
> -			th_zone->bind = false;
> -			break;
> -		default:
> -			ret = -EINVAL;
> -		}
> -	}
> -	return ret;
> -}
> -
> -/* Get temperature callback functions for thermal zone */
> -static int exynos_get_temp(struct thermal_zone_device *thermal,
> -			unsigned long *temp)
> -{
> -	void *data;
> -
> -	if (!th_zone->sensor_conf) {
> -		pr_info("Temperature sensor not initialised\n");
> -		return -EINVAL;
> -	}
> -	data = th_zone->sensor_conf->private_data;
> -	*temp = th_zone->sensor_conf->read_temperature(data);
> -	/* convert the temperature into millicelsius */
> -	*temp = *temp * MCELSIUS;
> -	return 0;
> -}
> -
> -/* Get temperature callback functions for thermal zone */
> -static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
> -						unsigned long temp)
> -{
> -	void *data;
> -	int ret = -EINVAL;
> -
> -	if (!th_zone->sensor_conf) {
> -		pr_info("Temperature sensor not initialised\n");
> -		return -EINVAL;
> -	}
> -	data = th_zone->sensor_conf->private_data;
> -	if (th_zone->sensor_conf->write_emul_temp)
> -		ret = th_zone->sensor_conf->write_emul_temp(data, temp);
> -	return ret;
> -}
> -
> -/* Get the temperature trend */
> -static int exynos_get_trend(struct thermal_zone_device *thermal,
> -			int trip, enum thermal_trend *trend)
> -{
> -	int ret;
> -	unsigned long trip_temp;
> -
> -	ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
> -	if (ret < 0)
> -		return ret;
> -
> -	if (thermal->temperature >= trip_temp)
> -		*trend = THERMAL_TREND_RAISE_FULL;
> -	else
> -		*trend = THERMAL_TREND_DROP_FULL;
> -
> -	return 0;
> -}
> -/* Operation callback functions for thermal zone */
> -static struct thermal_zone_device_ops const exynos_dev_ops = {
> -	.bind = exynos_bind,
> -	.unbind = exynos_unbind,
> -	.get_temp = exynos_get_temp,
> -	.set_emul_temp = exynos_set_emul_temp,
> -	.get_trend = exynos_get_trend,
> -	.get_mode = exynos_get_mode,
> -	.set_mode = exynos_set_mode,
> -	.get_trip_type = exynos_get_trip_type,
> -	.get_trip_temp = exynos_get_trip_temp,
> -	.get_crit_temp = exynos_get_crit_temp,
> -};
> -
> -/*
> - * This function may be called from interrupt based temperature sensor
> - * when threshold is changed.
> - */
> -static void exynos_report_trigger(void)
> -{
> -	unsigned int i;
> -	char data[10];
> -	char *envp[] = { data, NULL };
> -
> -	if (!th_zone || !th_zone->therm_dev)
> -		return;
> -	if (th_zone->bind == false) {
> -		for (i = 0; i < th_zone->cool_dev_size; i++) {
> -			if (!th_zone->cool_dev[i])
> -				continue;
> -			exynos_bind(th_zone->therm_dev,
> -					th_zone->cool_dev[i]);
> -		}
> -	}
> -
> -	thermal_zone_device_update(th_zone->therm_dev);
> -
> -	mutex_lock(&th_zone->therm_dev->lock);
> -	/* Find the level for which trip happened */
> -	for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
> -		if (th_zone->therm_dev->last_temperature <
> -			th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
> -			break;
> -	}
> -
> -	if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
> -		!th_zone->sensor_conf->trip_data.trigger_falling) {
> -		if (i > 0)
> -			th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
> -		else
> -			th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
> -	}
> -
> -	snprintf(data, sizeof(data), "%u", i);
> -	kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
> -	mutex_unlock(&th_zone->therm_dev->lock);
> -}
> -
> -/* Register with the in-kernel thermal management */
> -static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
> -{
> -	int ret;
> -	struct cpumask mask_val;
> -
> -	if (!sensor_conf || !sensor_conf->read_temperature) {
> -		pr_err("Temperature sensor not initialised\n");
> -		return -EINVAL;
> -	}
> -
> -	th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
> -	if (!th_zone)
> -		return -ENOMEM;
> -
> -	th_zone->sensor_conf = sensor_conf;
> -	cpumask_set_cpu(0, &mask_val);
> -	th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
> -	if (IS_ERR(th_zone->cool_dev[0])) {
> -		pr_err("Failed to register cpufreq cooling device\n");
> -		ret = -EINVAL;
> -		goto err_unregister;
> -	}
> -	th_zone->cool_dev_size++;
> -
> -	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
> -			EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
> -			sensor_conf->trip_data.trigger_falling ?
> -			0 : IDLE_INTERVAL);
> -
> -	if (IS_ERR(th_zone->therm_dev)) {
> -		pr_err("Failed to register thermal zone device\n");
> -		ret = PTR_ERR(th_zone->therm_dev);
> -		goto err_unregister;
> -	}
> -	th_zone->mode = THERMAL_DEVICE_ENABLED;
> -
> -	pr_info("Exynos: Kernel Thermal management registered\n");
> -
> -	return 0;
> -
> -err_unregister:
> -	exynos_unregister_thermal();
> -	return ret;
> -}
> -
> -/* Un-Register with the in-kernel thermal management */
> -static void exynos_unregister_thermal(void)
> -{
> -	int i;
> -
> -	if (!th_zone)
> -		return;
> -
> -	if (th_zone->therm_dev)
> -		thermal_zone_device_unregister(th_zone->therm_dev);
> -
> -	for (i = 0; i < th_zone->cool_dev_size; i++) {
> -		if (th_zone->cool_dev[i])
> -			cpufreq_cooling_unregister(th_zone->cool_dev[i]);
> -	}
> -
> -	kfree(th_zone);
> -	pr_info("Exynos: Kernel Thermal management unregistered\n");
> -}
> -
>  /*
>   * TMU treats temperature as a mapped temperature code.
>   * The temperature is converted differently depending on the calibration type.
> diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
> new file mode 100644
> index 0000000..9a57606
> --- /dev/null
> +++ b/drivers/thermal/samsung/exynos_thermal_common.c
> @@ -0,0 +1,389 @@
> +/*
> + * exynos_thermal_common.c - Samsung EXYNOS common thermal file
> + *
> + *  Copyright (C) 2013 Samsung Electronics
> + *  Amit Daniel Kachhap <amit.daniel@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#include <linux/cpufreq.h>
> +#include <linux/cpu_cooling.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/kobject.h>
> +#include <linux/mutex.h>
> +#include <linux/platform_data/exynos_thermal.h>
> +#include <linux/slab.h>
> +#include <linux/thermal.h>
> +#include "exynos_thermal_common.h"
> +
> +struct exynos_thermal_zone {
> +	enum thermal_device_mode mode;
> +	struct thermal_zone_device *therm_dev;
> +	struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
> +	unsigned int cool_dev_size;
> +	struct platform_device *exynos4_dev;
> +	struct thermal_sensor_conf *sensor_conf;
> +	bool bind;
> +};
> +
> +static struct exynos_thermal_zone *th_zone;
> +
> +/* Get mode callback functions for thermal zone */
> +static int exynos_get_mode(struct thermal_zone_device *thermal,
> +			enum thermal_device_mode *mode)
> +{
> +	if (th_zone)
> +		*mode = th_zone->mode;
> +	return 0;
> +}
> +
> +/* Set mode callback functions for thermal zone */
> +static int exynos_set_mode(struct thermal_zone_device *thermal,
> +			enum thermal_device_mode mode)
> +{
> +	if (!th_zone->therm_dev) {
> +		pr_notice("thermal zone not registered\n");
> +		return 0;
> +	}
> +
> +	mutex_lock(&th_zone->therm_dev->lock);
> +
> +	if (mode == THERMAL_DEVICE_ENABLED &&
> +		!th_zone->sensor_conf->trip_data.trigger_falling)
> +		th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
> +	else
> +		th_zone->therm_dev->polling_delay = 0;
> +
> +	mutex_unlock(&th_zone->therm_dev->lock);
> +
> +	th_zone->mode = mode;
> +	thermal_zone_device_update(th_zone->therm_dev);
> +	pr_info("thermal polling set for duration=%d msec\n",
> +				th_zone->therm_dev->polling_delay);
> +	return 0;
> +}
> +
> +
> +/* Get trip type callback functions for thermal zone */
> +static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
> +				 enum thermal_trip_type *type)
> +{
> +	switch (GET_ZONE(trip)) {
> +	case MONITOR_ZONE:
> +	case WARN_ZONE:
> +		*type = THERMAL_TRIP_ACTIVE;
> +		break;
> +	case PANIC_ZONE:
> +		*type = THERMAL_TRIP_CRITICAL;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +	return 0;
> +}
> +
> +/* Get trip temperature callback functions for thermal zone */
> +static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
> +				unsigned long *temp)
> +{
> +	if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
> +		return -EINVAL;
> +
> +	*temp = th_zone->sensor_conf->trip_data.trip_val[trip];
> +	/* convert the temperature into millicelsius */
> +	*temp = *temp * MCELSIUS;
> +
> +	return 0;
> +}
> +
> +/* Get critical temperature callback functions for thermal zone */
> +static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
> +				unsigned long *temp)
> +{
> +	int ret;
> +	/* Panic zone */
> +	ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
> +	return ret;
> +}
> +
> +/* Bind callback functions for thermal zone */
> +static int exynos_bind(struct thermal_zone_device *thermal,
> +			struct thermal_cooling_device *cdev)
> +{
> +	int ret = 0, i, tab_size, level;
> +	struct freq_clip_table *tab_ptr, *clip_data;
> +	struct thermal_sensor_conf *data = th_zone->sensor_conf;
> +
> +	tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
> +	tab_size = data->cooling_data.freq_clip_count;
> +
> +	if (tab_ptr == NULL || tab_size == 0)
> +		return -EINVAL;
> +
> +	/* find the cooling device registered*/
> +	for (i = 0; i < th_zone->cool_dev_size; i++)
> +		if (cdev == th_zone->cool_dev[i])
> +			break;
> +
> +	/* No matching cooling device */
> +	if (i == th_zone->cool_dev_size)
> +		return 0;
> +
> +	/* Bind the thermal zone to the cpufreq cooling device */
> +	for (i = 0; i < tab_size; i++) {
> +		clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
> +		level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max);
> +		if (level == THERMAL_CSTATE_INVALID)
> +			return 0;
> +		switch (GET_ZONE(i)) {
> +		case MONITOR_ZONE:
> +		case WARN_ZONE:
> +			if (thermal_zone_bind_cooling_device(thermal, i, cdev,
> +								level, 0)) {
> +				pr_err("error binding cdev inst %d\n", i);
> +				ret = -EINVAL;
> +			}
> +			th_zone->bind = true;
> +			break;
> +		default:
> +			ret = -EINVAL;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +/* Unbind callback functions for thermal zone */
> +static int exynos_unbind(struct thermal_zone_device *thermal,
> +			struct thermal_cooling_device *cdev)
> +{
> +	int ret = 0, i, tab_size;
> +	struct thermal_sensor_conf *data = th_zone->sensor_conf;
> +
> +	if (th_zone->bind == false)
> +		return 0;
> +
> +	tab_size = data->cooling_data.freq_clip_count;
> +
> +	if (tab_size == 0)
> +		return -EINVAL;
> +
> +	/* find the cooling device registered*/
> +	for (i = 0; i < th_zone->cool_dev_size; i++)
> +		if (cdev == th_zone->cool_dev[i])
> +			break;
> +
> +	/* No matching cooling device */
> +	if (i == th_zone->cool_dev_size)
> +		return 0;
> +
> +	/* Bind the thermal zone to the cpufreq cooling device */
> +	for (i = 0; i < tab_size; i++) {
> +		switch (GET_ZONE(i)) {
> +		case MONITOR_ZONE:
> +		case WARN_ZONE:
> +			if (thermal_zone_unbind_cooling_device(thermal, i,
> +								cdev)) {
> +				pr_err("error unbinding cdev inst=%d\n", i);
> +				ret = -EINVAL;
> +			}
> +			th_zone->bind = false;
> +			break;
> +		default:
> +			ret = -EINVAL;
> +		}
> +	}
> +	return ret;
> +}
> +
> +/* Get temperature callback functions for thermal zone */
> +static int exynos_get_temp(struct thermal_zone_device *thermal,
> +			unsigned long *temp)
> +{
> +	void *data;
> +
> +	if (!th_zone->sensor_conf) {
> +		pr_info("Temperature sensor not initialised\n");
> +		return -EINVAL;
> +	}
> +	data = th_zone->sensor_conf->private_data;
> +	*temp = th_zone->sensor_conf->read_temperature(data);
> +	/* convert the temperature into millicelsius */
> +	*temp = *temp * MCELSIUS;
> +	return 0;
> +}
> +
> +/* Get temperature callback functions for thermal zone */
> +static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
> +						unsigned long temp)
> +{
> +	void *data;
> +	int ret = -EINVAL;
> +
> +	if (!th_zone->sensor_conf) {
> +		pr_info("Temperature sensor not initialised\n");
> +		return -EINVAL;
> +	}
> +	data = th_zone->sensor_conf->private_data;
> +	if (th_zone->sensor_conf->write_emul_temp)
> +		ret = th_zone->sensor_conf->write_emul_temp(data, temp);
> +	return ret;
> +}
> +
> +/* Get the temperature trend */
> +static int exynos_get_trend(struct thermal_zone_device *thermal,
> +			int trip, enum thermal_trend *trend)
> +{
> +	int ret;
> +	unsigned long trip_temp;
> +
> +	ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (thermal->temperature >= trip_temp)
> +		*trend = THERMAL_TREND_RAISE_FULL;
> +	else
> +		*trend = THERMAL_TREND_DROP_FULL;
> +
> +	return 0;
> +}
> +/* Operation callback functions for thermal zone */
> +static struct thermal_zone_device_ops const exynos_dev_ops = {
> +	.bind = exynos_bind,
> +	.unbind = exynos_unbind,
> +	.get_temp = exynos_get_temp,
> +	.set_emul_temp = exynos_set_emul_temp,
> +	.get_trend = exynos_get_trend,
> +	.get_mode = exynos_get_mode,
> +	.set_mode = exynos_set_mode,
> +	.get_trip_type = exynos_get_trip_type,
> +	.get_trip_temp = exynos_get_trip_temp,
> +	.get_crit_temp = exynos_get_crit_temp,
> +};
> +
> +/*
> + * This function may be called from interrupt based temperature sensor
> + * when threshold is changed.
> + */
> +void exynos_report_trigger(void)
> +{
> +	unsigned int i;
> +	char data[10];
> +	char *envp[] = { data, NULL };
> +
> +	if (!th_zone || !th_zone->therm_dev)
> +		return;
> +	if (th_zone->bind == false) {
> +		for (i = 0; i < th_zone->cool_dev_size; i++) {
> +			if (!th_zone->cool_dev[i])
> +				continue;
> +			exynos_bind(th_zone->therm_dev,
> +					th_zone->cool_dev[i]);
> +		}
> +	}
> +
> +	thermal_zone_device_update(th_zone->therm_dev);
> +
> +	mutex_lock(&th_zone->therm_dev->lock);
> +	/* Find the level for which trip happened */
> +	for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
> +		if (th_zone->therm_dev->last_temperature <
> +			th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
> +			break;
> +	}
> +
> +	if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
> +		!th_zone->sensor_conf->trip_data.trigger_falling) {
> +		if (i > 0)
> +			th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
> +		else
> +			th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
> +	}
> +
> +	snprintf(data, sizeof(data), "%u", i);
> +	kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
> +	mutex_unlock(&th_zone->therm_dev->lock);
> +}
> +
> +/* Register with the in-kernel thermal management */
> +int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
> +{
> +	int ret;
> +	struct cpumask mask_val;
> +
> +	if (!sensor_conf || !sensor_conf->read_temperature) {
> +		pr_err("Temperature sensor not initialised\n");
> +		return -EINVAL;
> +	}
> +
> +	th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
> +	if (!th_zone)
> +		return -ENOMEM;
> +
> +	th_zone->sensor_conf = sensor_conf;
> +	cpumask_set_cpu(0, &mask_val);
> +	th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
> +	if (IS_ERR(th_zone->cool_dev[0])) {
> +		pr_err("Failed to register cpufreq cooling device\n");
> +		ret = -EINVAL;
> +		goto err_unregister;
> +	}
> +	th_zone->cool_dev_size++;
> +
> +	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
> +			EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
> +			sensor_conf->trip_data.trigger_falling ?
> +			0 : IDLE_INTERVAL);
> +
> +	if (IS_ERR(th_zone->therm_dev)) {
> +		pr_err("Failed to register thermal zone device\n");
> +		ret = PTR_ERR(th_zone->therm_dev);
> +		goto err_unregister;
> +	}
> +	th_zone->mode = THERMAL_DEVICE_ENABLED;
> +
> +	pr_info("Exynos: Kernel Thermal management registered\n");
> +
> +	return 0;
> +
> +err_unregister:
> +	exynos_unregister_thermal();
> +	return ret;
> +}
> +
> +/* Un-Register with the in-kernel thermal management */
> +void exynos_unregister_thermal(void)
> +{
> +	int i;
> +
> +	if (!th_zone)
> +		return;
> +
> +	if (th_zone->therm_dev)
> +		thermal_zone_device_unregister(th_zone->therm_dev);
> +
> +	for (i = 0; i < th_zone->cool_dev_size; i++) {
> +		if (th_zone->cool_dev[i])
> +			cpufreq_cooling_unregister(th_zone->cool_dev[i]);
> +	}
> +
> +	kfree(th_zone);
> +	pr_info("Exynos: Kernel Thermal management unregistered\n");
> +}
> diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
> new file mode 100644
> index 0000000..165401f
> --- /dev/null
> +++ b/drivers/thermal/samsung/exynos_thermal_common.h
> @@ -0,0 +1,71 @@
> +/*
> + * exynos_thermal_common.h - Samsung EXYNOS common header file
> + *
> + *  Copyright (C) 2013 Samsung Electronics
> + *  Amit Daniel Kachhap <amit.daniel@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#ifndef _LINUX_EXYNOS_THERMAL_COMMON_H
> +#define _LINUX_EXYNOS_THERMAL_COMMON_H
> +
> +/* In-kernel thermal framework related macros & definations */
> +#define SENSOR_NAME_LEN	16
> +#define MAX_TRIP_COUNT	8
> +#define MAX_COOLING_DEVICE 4
> +#define MAX_THRESHOLD_LEVS 4
> +
> +#define ACTIVE_INTERVAL 500
> +#define IDLE_INTERVAL 10000
> +#define MCELSIUS	1000
> +
> +/* CPU Zone information */
> +#define PANIC_ZONE      4
> +#define WARN_ZONE       3
> +#define MONITOR_ZONE    2
> +#define SAFE_ZONE       1
> +
> +#define GET_ZONE(trip) (trip + 2)
> +#define GET_TRIP(zone) (zone - 2)
> +
> +#define EXYNOS_ZONE_COUNT	3
> +
> +struct	thermal_trip_point_conf {
> +	int trip_val[MAX_TRIP_COUNT];
> +	int trip_count;
> +	u8 trigger_falling;
> +};
> +
> +struct	thermal_cooling_conf {
> +	struct freq_clip_table freq_data[MAX_TRIP_COUNT];
> +	int freq_clip_count;
> +};
> +
> +struct thermal_sensor_conf {
> +	char name[SENSOR_NAME_LEN];
> +	int (*read_temperature)(void *data);
> +	int (*write_emul_temp)(void *drv_data, unsigned long temp);
> +	struct thermal_trip_point_conf trip_data;
> +	struct thermal_cooling_conf cooling_data;
> +	void *private_data;
> +};
> +
> +/*Functions used exynos based thermal sensor driver*/
> +void exynos_unregister_thermal(void);
> +int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
> +void exynos_report_trigger(void);
> +#endif /* _LINUX_EXYNOS_THERMAL_COMMON_H */

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH V2 03/20] thermal: exynos: Rename exynos_thermal.c to exynos_tmu.c
  2013-04-26 10:37 ` [PATCH V2 03/20] thermal: exynos: Rename exynos_thermal.c to exynos_tmu.c Amit Daniel Kachhap
@ 2013-05-06 15:18   ` Zhang Rui
  0 siblings, 0 replies; 31+ messages in thread
From: Zhang Rui @ 2013-05-06 15:18 UTC (permalink / raw)
  To: Amit Daniel Kachhap
  Cc: linux-pm, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

On Fri, 2013-04-26 at 16:07 +0530, Amit Daniel Kachhap wrote:
> This patch renames exynos_thermal.c to exynos_tmu.c. This change is needed as
> this file now just contains exynos tmu driver related codes and thermal zone
> or cpufreq cooling registration related changes are not there anymore.
> 
> Acked-by: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>

This one looks okay to me.

thanks,
rui
> ---
>  drivers/thermal/samsung/Makefile                   |    2 +-
>  .../samsung/{exynos_thermal.c => exynos_tmu.c}     |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>  rename drivers/thermal/samsung/{exynos_thermal.c => exynos_tmu.c} (99%)
> 
> diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
> index fcda5b4..75e1f97 100644
> --- a/drivers/thermal/samsung/Makefile
> +++ b/drivers/thermal/samsung/Makefile
> @@ -2,5 +2,5 @@
>  # Samsung thermal specific Makefile
>  #
>  obj-$(CONFIG_EXYNOS_SOC_THERMAL)		+= exynos_soc_thermal.o
> -exynos_soc_thermal-y				:= exynos_thermal.o
> +exynos_soc_thermal-y				:= exynos_tmu.o
>  exynos_soc_thermal-$(CONFIG_EXYNOS_COMMON)	+= exynos_thermal_common.o
> diff --git a/drivers/thermal/samsung/exynos_thermal.c b/drivers/thermal/samsung/exynos_tmu.c
> similarity index 99%
> rename from drivers/thermal/samsung/exynos_thermal.c
> rename to drivers/thermal/samsung/exynos_tmu.c
> index 4c85945..3de3e61 100644
> --- a/drivers/thermal/samsung/exynos_thermal.c
> +++ b/drivers/thermal/samsung/exynos_tmu.c
> @@ -1,5 +1,5 @@
>  /*
> - * exynos_thermal.c - Samsung EXYNOS TMU (Thermal Management Unit)
> + * exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit)
>   *
>   *  Copyright (C) 2011 Samsung Electronics
>   *  Donggeun Kim <dg77.kim@samsung.com>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH V2 04/20] thermal: exynos: Move exynos_thermal.h from include/* to driver/* folder
  2013-04-26 10:37 ` [PATCH V2 04/20] thermal: exynos: Move exynos_thermal.h from include/* to driver/* folder Amit Daniel Kachhap
@ 2013-05-06 15:19   ` Zhang Rui
  0 siblings, 0 replies; 31+ messages in thread
From: Zhang Rui @ 2013-05-06 15:19 UTC (permalink / raw)
  To: Amit Daniel Kachhap
  Cc: linux-pm, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

On Fri, 2013-04-26 at 16:07 +0530, Amit Daniel Kachhap wrote:
> This patch renames and moves  include/linux/platform_data/exynos_thermal.h to
> drivers/thermal/samsung/exynos_tmu.h. This file movement is needed as exynos
> SOC's are not supporting non-DT based platforms. Also the rename is needed as this
> file now just contains exynos tmu driver related definations.
> 
> Acked-by: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>

this one looks okay to me.

thanks,
rui
> ---
>  drivers/thermal/samsung/exynos_thermal_common.c    |    1 -
>  drivers/thermal/samsung/exynos_thermal_common.h    |   15 +++++++++++++++
>  drivers/thermal/samsung/exynos_tmu.c               |    2 +-
>  .../thermal/samsung/exynos_tmu.h                   |   15 ---------------
>  4 files changed, 16 insertions(+), 17 deletions(-)
>  rename include/linux/platform_data/exynos_thermal.h => drivers/thermal/samsung/exynos_tmu.h (88%)
> 
> diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
> index 9a57606..dae5476 100644
> --- a/drivers/thermal/samsung/exynos_thermal_common.c
> +++ b/drivers/thermal/samsung/exynos_thermal_common.c
> @@ -27,7 +27,6 @@
>  #include <linux/kernel.h>
>  #include <linux/kobject.h>
>  #include <linux/mutex.h>
> -#include <linux/platform_data/exynos_thermal.h>
>  #include <linux/slab.h>
>  #include <linux/thermal.h>
>  #include "exynos_thermal_common.h"
> diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
> index 165401f..985b848 100644
> --- a/drivers/thermal/samsung/exynos_thermal_common.h
> +++ b/drivers/thermal/samsung/exynos_thermal_common.h
> @@ -44,6 +44,21 @@
>  
>  #define EXYNOS_ZONE_COUNT	3
>  
> +/**
> + * struct freq_clip_table
> + * @freq_clip_max: maximum frequency allowed for this cooling state.
> + * @temp_level: Temperature level at which the temperature clipping will
> + *	happen.
> + * @mask_val: cpumask of the allowed cpu's where the clipping will take place.
> + *
> + * This structure is required to be filled and passed to the
> + * cpufreq_cooling_unregister function.
> + */
> +struct freq_clip_table {
> +	unsigned int freq_clip_max;
> +	unsigned int temp_level;
> +	const struct cpumask *mask_val;
> +};
>  struct	thermal_trip_point_conf {
>  	int trip_val[MAX_TRIP_COUNT];
>  	int trip_count;
> diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
> index 3de3e61..a02f2c9 100644
> --- a/drivers/thermal/samsung/exynos_tmu.c
> +++ b/drivers/thermal/samsung/exynos_tmu.c
> @@ -30,10 +30,10 @@
>  #include <linux/mutex.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> -#include <linux/platform_data/exynos_thermal.h>
>  #include <linux/slab.h>
>  #include <linux/workqueue.h>
>  #include "exynos_thermal_common.h"
> +#include "exynos_tmu.h"
>  
>  /* Exynos generic registers */
>  #define EXYNOS_TMU_REG_TRIMINFO		0x0
> diff --git a/include/linux/platform_data/exynos_thermal.h b/drivers/thermal/samsung/exynos_tmu.h
> similarity index 88%
> rename from include/linux/platform_data/exynos_thermal.h
> rename to drivers/thermal/samsung/exynos_tmu.h
> index da7e627..342fb1f 100644
> --- a/include/linux/platform_data/exynos_thermal.h
> +++ b/drivers/thermal/samsung/exynos_tmu.h
> @@ -33,21 +33,6 @@ enum soc_type {
>  	SOC_ARCH_EXYNOS4210 = 1,
>  	SOC_ARCH_EXYNOS,
>  };
> -/**
> - * struct freq_clip_table
> - * @freq_clip_max: maximum frequency allowed for this cooling state.
> - * @temp_level: Temperature level at which the temperature clipping will
> - *	happen.
> - * @mask_val: cpumask of the allowed cpu's where the clipping will take place.
> - *
> - * This structure is required to be filled and passed to the
> - * cpufreq_cooling_unregister function.
> - */
> -struct freq_clip_table {
> -	unsigned int freq_clip_max;
> -	unsigned int temp_level;
> -	const struct cpumask *mask_val;
> -};
>  
>  /**
>   * struct exynos_tmu_platform_data



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH V2 05/20] thermal: exynos: Bifurcate exynos tmu driver and configuration data
  2013-04-26 10:37 ` [PATCH V2 05/20] thermal: exynos: Bifurcate exynos tmu driver and configuration data Amit Daniel Kachhap
@ 2013-05-06 15:28   ` Zhang Rui
  0 siblings, 0 replies; 31+ messages in thread
From: Zhang Rui @ 2013-05-06 15:28 UTC (permalink / raw)
  To: Amit Daniel Kachhap
  Cc: linux-pm, linux-samsung-soc, linux-kernel, amit.kachhap,
	Kukjin Kim, Eduardo Valentin

On Fri, 2013-04-26 at 16:07 +0530, Amit Daniel Kachhap wrote:
> This code splits the exynos tmu driver code into SOC specific data parts.
> This will simplify adding new SOC specific data to the same TMU controller.
> 
> Acked-by: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>

I'm okay with all the rest patches in this patch series.

thanks,
rui
> ---
>  drivers/thermal/samsung/Makefile                |    1 +
>  drivers/thermal/samsung/exynos_thermal_common.h |    2 +-
>  drivers/thermal/samsung/exynos_tmu.c            |   67 +------------------
>  drivers/thermal/samsung/exynos_tmu_data.c       |   78 +++++++++++++++++++++++
>  drivers/thermal/samsung/exynos_tmu_data.h       |   40 ++++++++++++
>  5 files changed, 124 insertions(+), 64 deletions(-)
>  create mode 100644 drivers/thermal/samsung/exynos_tmu_data.c
>  create mode 100644 drivers/thermal/samsung/exynos_tmu_data.h
> 
> diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
> index 75e1f97..b133255 100644
> --- a/drivers/thermal/samsung/Makefile
> +++ b/drivers/thermal/samsung/Makefile
> @@ -3,4 +3,5 @@
>  #
>  obj-$(CONFIG_EXYNOS_SOC_THERMAL)		+= exynos_soc_thermal.o
>  exynos_soc_thermal-y				:= exynos_tmu.o
> +exynos_soc_thermal-y				+= exynos_tmu_data.o
>  exynos_soc_thermal-$(CONFIG_EXYNOS_COMMON)	+= exynos_thermal_common.o
> diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
> index 985b848..6ed9bd9 100644
> --- a/drivers/thermal/samsung/exynos_thermal_common.h
> +++ b/drivers/thermal/samsung/exynos_thermal_common.h
> @@ -62,7 +62,7 @@ struct freq_clip_table {
>  struct	thermal_trip_point_conf {
>  	int trip_val[MAX_TRIP_COUNT];
>  	int trip_count;
> -	u8 trigger_falling;
> +	unsigned char trigger_falling;
>  };
>  
>  struct	thermal_cooling_conf {
> diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
> index a02f2c9..05b5068 100644
> --- a/drivers/thermal/samsung/exynos_tmu.c
> +++ b/drivers/thermal/samsung/exynos_tmu.c
> @@ -34,6 +34,7 @@
>  #include <linux/workqueue.h>
>  #include "exynos_thermal_common.h"
>  #include "exynos_tmu.h"
> +#include "exynos_tmu_data.h"
>  
>  /* Exynos generic registers */
>  #define EXYNOS_TMU_REG_TRIMINFO		0x0
> @@ -385,66 +386,6 @@ static struct thermal_sensor_conf exynos_sensor_conf = {
>  	.write_emul_temp	= exynos_tmu_set_emulation,
>  };
>  
> -#if defined(CONFIG_CPU_EXYNOS4210)
> -static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
> -	.threshold = 80,
> -	.trigger_levels[0] = 5,
> -	.trigger_levels[1] = 20,
> -	.trigger_levels[2] = 30,
> -	.trigger_level0_en = 1,
> -	.trigger_level1_en = 1,
> -	.trigger_level2_en = 1,
> -	.trigger_level3_en = 0,
> -	.gain = 15,
> -	.reference_voltage = 7,
> -	.cal_type = TYPE_ONE_POINT_TRIMMING,
> -	.freq_tab[0] = {
> -		.freq_clip_max = 800 * 1000,
> -		.temp_level = 85,
> -	},
> -	.freq_tab[1] = {
> -		.freq_clip_max = 200 * 1000,
> -		.temp_level = 100,
> -	},
> -	.freq_tab_count = 2,
> -	.type = SOC_ARCH_EXYNOS4210,
> -};
> -#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
> -#else
> -#define EXYNOS4210_TMU_DRV_DATA (NULL)
> -#endif
> -
> -#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
> -static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
> -	.threshold_falling = 10,
> -	.trigger_levels[0] = 85,
> -	.trigger_levels[1] = 103,
> -	.trigger_levels[2] = 110,
> -	.trigger_level0_en = 1,
> -	.trigger_level1_en = 1,
> -	.trigger_level2_en = 1,
> -	.trigger_level3_en = 0,
> -	.gain = 8,
> -	.reference_voltage = 16,
> -	.noise_cancel_mode = 4,
> -	.cal_type = TYPE_ONE_POINT_TRIMMING,
> -	.efuse_value = 55,
> -	.freq_tab[0] = {
> -		.freq_clip_max = 800 * 1000,
> -		.temp_level = 85,
> -	},
> -	.freq_tab[1] = {
> -		.freq_clip_max = 200 * 1000,
> -		.temp_level = 103,
> -	},
> -	.freq_tab_count = 2,
> -	.type = SOC_ARCH_EXYNOS,
> -};
> -#define EXYNOS_TMU_DRV_DATA (&exynos_default_tmu_data)
> -#else
> -#define EXYNOS_TMU_DRV_DATA (NULL)
> -#endif
> -
>  #ifdef CONFIG_OF
>  static const struct of_device_id exynos_tmu_match[] = {
>  	{
> @@ -453,11 +394,11 @@ static const struct of_device_id exynos_tmu_match[] = {
>  	},
>  	{
>  		.compatible = "samsung,exynos4412-tmu",
> -		.data = (void *)EXYNOS_TMU_DRV_DATA,
> +		.data = (void *)EXYNOS5250_TMU_DRV_DATA,
>  	},
>  	{
>  		.compatible = "samsung,exynos5250-tmu",
> -		.data = (void *)EXYNOS_TMU_DRV_DATA,
> +		.data = (void *)EXYNOS5250_TMU_DRV_DATA,
>  	},
>  	{},
>  };
> @@ -471,7 +412,7 @@ static struct platform_device_id exynos_tmu_driver_ids[] = {
>  	},
>  	{
>  		.name		= "exynos5250-tmu",
> -		.driver_data    = (kernel_ulong_t)EXYNOS_TMU_DRV_DATA,
> +		.driver_data    = (kernel_ulong_t)EXYNOS5250_TMU_DRV_DATA,
>  	},
>  	{ },
>  };
> diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
> new file mode 100644
> index 0000000..13a60ca
> --- /dev/null
> +++ b/drivers/thermal/samsung/exynos_tmu_data.c
> @@ -0,0 +1,78 @@
> +/*
> + * exynos_tmu_data.c - Samsung EXYNOS tmu data file
> + *
> + *  Copyright (C) 2013 Samsung Electronics
> + *  Amit Daniel Kachhap <amit.daniel@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#include "exynos_thermal_common.h"
> +#include "exynos_tmu.h"
> +
> +#if defined(CONFIG_CPU_EXYNOS4210)
> +struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
> +	.threshold = 80,
> +	.trigger_levels[0] = 5,
> +	.trigger_levels[1] = 20,
> +	.trigger_levels[2] = 30,
> +	.trigger_level0_en = 1,
> +	.trigger_level1_en = 1,
> +	.trigger_level2_en = 1,
> +	.trigger_level3_en = 0,
> +	.gain = 15,
> +	.reference_voltage = 7,
> +	.cal_type = TYPE_ONE_POINT_TRIMMING,
> +	.freq_tab[0] = {
> +		.freq_clip_max = 800 * 1000,
> +		.temp_level = 85,
> +	},
> +	.freq_tab[1] = {
> +		.freq_clip_max = 200 * 1000,
> +		.temp_level = 100,
> +	},
> +	.freq_tab_count = 2,
> +	.type = SOC_ARCH_EXYNOS4210,
> +};
> +#endif
> +
> +#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
> +struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
> +	.threshold_falling = 10,
> +	.trigger_levels[0] = 85,
> +	.trigger_levels[1] = 103,
> +	.trigger_levels[2] = 110,
> +	.trigger_level0_en = 1,
> +	.trigger_level1_en = 1,
> +	.trigger_level2_en = 1,
> +	.trigger_level3_en = 0,
> +	.gain = 8,
> +	.reference_voltage = 16,
> +	.noise_cancel_mode = 4,
> +	.cal_type = TYPE_ONE_POINT_TRIMMING,
> +	.efuse_value = 55,
> +	.freq_tab[0] = {
> +		.freq_clip_max = 800 * 1000,
> +		.temp_level = 85,
> +	},
> +	.freq_tab[1] = {
> +		.freq_clip_max = 200 * 1000,
> +		.temp_level = 103,
> +	},
> +	.freq_tab_count = 2,
> +	.type = SOC_ARCH_EXYNOS,
> +};
> +#endif
> diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
> new file mode 100644
> index 0000000..c8b0501
> --- /dev/null
> +++ b/drivers/thermal/samsung/exynos_tmu_data.h
> @@ -0,0 +1,40 @@
> +/*
> + * exynos_tmu_data.h - Samsung EXYNOS tmu data header file
> + *
> + *  Copyright (C) 2013 Samsung Electronics
> + *  Amit Daniel Kachhap <amit.daniel@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#ifndef _LINUX_EXYNOS_TMU_DATA_H
> +#define _LINUX_EXYNOS_TMU_DATA_H
> +
> +#if defined(CONFIG_CPU_EXYNOS4210)
> +extern struct exynos_tmu_platform_data const exynos4210_default_tmu_data;
> +#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
> +#else
> +#define EXYNOS4210_TMU_DRV_DATA (NULL)
> +#endif
> +
> +#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
> +extern struct exynos_tmu_platform_data const exynos5250_default_tmu_data;
> +#define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data)
> +#else
> +#define EXYNOS5250_TMU_DRV_DATA (NULL)
> +#endif
> +
> +#endif /*_LINUX_EXYNOS_TMU_DATA_H*/

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory
  2013-05-06 15:05   ` Zhang Rui
@ 2013-05-07 10:21     ` Tomasz Figa
  2013-05-07 13:18       ` amit daniel kachhap
  2013-05-07 13:12     ` amit daniel kachhap
  1 sibling, 1 reply; 31+ messages in thread
From: Tomasz Figa @ 2013-05-07 10:21 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Amit Daniel Kachhap, linux-pm, linux-samsung-soc, linux-kernel,
	amit.kachhap, Kukjin Kim, Eduardo Valentin

On Monday 06 of May 2013 23:05:06 Zhang Rui wrote:
> On Fri, 2013-04-26 at 16:07 +0530, Amit Daniel Kachhap wrote:
> > This movement of files is done for easy maintenance and adding more
> > new sensor's support for exynos platform easily . This will also help in
> > bifurcating exynos common, sensor driver and sensor data related parts.
> > 
> > Acked-by: Kukjin Kim <kgene.kim@samsung.com>
> > Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
> > ---
> > 
> >  drivers/thermal/Kconfig                        |   13 +++++--------
> >  drivers/thermal/Makefile                       |    2 +-
> >  drivers/thermal/samsung/Kconfig                |    9 +++++++++
> >  drivers/thermal/samsung/Makefile               |    4 ++++
> >  drivers/thermal/{ => samsung}/exynos_thermal.c |    0
> >  5 files changed, 19 insertions(+), 9 deletions(-)
> >  create mode 100644 drivers/thermal/samsung/Kconfig
> >  create mode 100644 drivers/thermal/samsung/Makefile
> >  rename drivers/thermal/{ => samsung}/exynos_thermal.c (100%)
> > 
> > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> > index 5e3c025..081ddc5 100644
> > --- a/drivers/thermal/Kconfig
> > +++ b/drivers/thermal/Kconfig
> > @@ -114,14 +114,6 @@ config KIRKWOOD_THERMAL
> > 
> >  	  Support for the Kirkwood thermal sensor driver into the Linux thermal
> >  	  framework. Only kirkwood 88F6282 and 88F6283 have this sensor.
> > 
> > -config EXYNOS_THERMAL
> > -	tristate "Temperature sensor on Samsung EXYNOS"
> > -	depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
> > -	depends on CPU_THERMAL
> > -	help
> > -	  If you say yes here you get support for TMU (Thermal Management
> > -	  Unit) on SAMSUNG EXYNOS series of SoC.
> > -
> > 
> >  config DOVE_THERMAL
> >  
> >  	tristate "Temperature sensor on Marvell Dove SoCs"
> >  	depends on ARCH_DOVE
> > 
> > @@ -169,4 +161,9 @@ config INTEL_POWERCLAMP
> > 
> >  	  enforce idle time which results in more package C-state residency. The
> >  	  user interface is exposed via generic thermal framework.
> > 
> > +menu "Exynos thermal drivers"
> 
> would it be more proper to use "Samsung thermal drivers" or "Samsung
> Exynos thermal drivers" instead?

+1

Still, I wonder if it really makes sense to create a separate directory and 
submenu for this.

> > +depends on PLAT_SAMSUNG
> > +source "drivers/thermal/samsung/Kconfig"
> > +endmenu
> > +
> 
> sorry I know few about arm,
> could you tell me the difference between
> CONFIG_ARCH_EXYNOS4/CONFIG_ARCH_EXYNOS5 and CONFIG_PLAT_SAMSUNG please,
> I do not see the dependency between these in Kconfig file?

If those files were kept at thermal/, there would be no need for this check. 
Just particular drivers would depend on platform they are for.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Kernel and System Framework
> 
> >  endif
> > 
> > diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> > index c054d41..b3063a9 100644
> > --- a/drivers/thermal/Makefile
> > +++ b/drivers/thermal/Makefile
> > @@ -17,7 +17,7 @@ thermal_sys-$(CONFIG_CPU_THERMAL)	+= cpu_cooling.o
> > 
> >  obj-$(CONFIG_SPEAR_THERMAL)	+= spear_thermal.o
> >  obj-$(CONFIG_RCAR_THERMAL)	+= rcar_thermal.o
> >  obj-$(CONFIG_KIRKWOOD_THERMAL)  += kirkwood_thermal.o
> > 
> > -obj-$(CONFIG_EXYNOS_THERMAL)	+= exynos_thermal.o
> > +obj-y				+= samsung/
> > 
> >  obj-$(CONFIG_DOVE_THERMAL)  	+= dove_thermal.o
> >  obj-$(CONFIG_DB8500_THERMAL)	+= db8500_thermal.o
> >  obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
> > 
> > diff --git a/drivers/thermal/samsung/Kconfig
> > b/drivers/thermal/samsung/Kconfig new file mode 100644
> > index 0000000..2d3d9dc
> > --- /dev/null
> > +++ b/drivers/thermal/samsung/Kconfig
> > @@ -0,0 +1,9 @@
> > +config EXYNOS_THERMAL
> > +	tristate "Temperature sensor on Samsung EXYNOS"
> > +	depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
> > +	depends on CPU_THERMAL
> > +	help
> > +	  If you say yes here you get support for TMU (Thermal Management
> > +	  Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
> > +	  the exynos thermal driver with the core thermal layer and cpu
> > +	  cooling API's.
> > diff --git a/drivers/thermal/samsung/Makefile
> > b/drivers/thermal/samsung/Makefile new file mode 100644
> > index 0000000..1fe6d93
> > --- /dev/null
> > +++ b/drivers/thermal/samsung/Makefile
> > @@ -0,0 +1,4 @@
> > +#
> > +# Samsung thermal specific Makefile
> > +#
> > +obj-$(CONFIG_EXYNOS_THERMAL)	+= exynos_thermal.o
> > diff --git a/drivers/thermal/exynos_thermal.c
> > b/drivers/thermal/samsung/exynos_thermal.c similarity index 100%
> > rename from drivers/thermal/exynos_thermal.c
> > rename to drivers/thermal/samsung/exynos_thermal.c
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc"
> in the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory
  2013-05-06 15:05   ` Zhang Rui
  2013-05-07 10:21     ` Tomasz Figa
@ 2013-05-07 13:12     ` amit daniel kachhap
  1 sibling, 0 replies; 31+ messages in thread
From: amit daniel kachhap @ 2013-05-07 13:12 UTC (permalink / raw)
  To: Zhang Rui
  Cc: linux-pm, linux-samsung-soc, linux-kernel, Kukjin Kim,
	Eduardo Valentin

Hi Rui,

On Mon, May 6, 2013 at 8:35 PM, Zhang Rui <rui.zhang@intel.com> wrote:
> On Fri, 2013-04-26 at 16:07 +0530, Amit Daniel Kachhap wrote:
>> This movement of files is done for easy maintenance and adding more
>> new sensor's support for exynos platform easily . This will also help in
>> bifurcating exynos common, sensor driver and sensor data related parts.
>>
>> Acked-by: Kukjin Kim <kgene.kim@samsung.com>
>> Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
>> ---
>>  drivers/thermal/Kconfig                        |   13 +++++--------
>>  drivers/thermal/Makefile                       |    2 +-
>>  drivers/thermal/samsung/Kconfig                |    9 +++++++++
>>  drivers/thermal/samsung/Makefile               |    4 ++++
>>  drivers/thermal/{ => samsung}/exynos_thermal.c |    0
>>  5 files changed, 19 insertions(+), 9 deletions(-)
>>  create mode 100644 drivers/thermal/samsung/Kconfig
>>  create mode 100644 drivers/thermal/samsung/Makefile
>>  rename drivers/thermal/{ => samsung}/exynos_thermal.c (100%)
>>
>> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
>> index 5e3c025..081ddc5 100644
>> --- a/drivers/thermal/Kconfig
>> +++ b/drivers/thermal/Kconfig
>> @@ -114,14 +114,6 @@ config KIRKWOOD_THERMAL
>>         Support for the Kirkwood thermal sensor driver into the Linux thermal
>>         framework. Only kirkwood 88F6282 and 88F6283 have this sensor.
>>
>> -config EXYNOS_THERMAL
>> -     tristate "Temperature sensor on Samsung EXYNOS"
>> -     depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
>> -     depends on CPU_THERMAL
>> -     help
>> -       If you say yes here you get support for TMU (Thermal Management
>> -       Unit) on SAMSUNG EXYNOS series of SoC.
>> -
>>  config DOVE_THERMAL
>>       tristate "Temperature sensor on Marvell Dove SoCs"
>>       depends on ARCH_DOVE
>> @@ -169,4 +161,9 @@ config INTEL_POWERCLAMP
>>         enforce idle time which results in more package C-state residency. The
>>         user interface is exposed via generic thermal framework.
>>
>> +menu "Exynos thermal drivers"
>
> would it be more proper to use "Samsung thermal drivers" or "Samsung
> Exynos thermal drivers" instead?
Yes "Samsung thermal drivers" will look fine. Submitted with this change.
>
>> +depends on PLAT_SAMSUNG
>> +source "drivers/thermal/samsung/Kconfig"
>> +endmenu
>> +
> sorry I know few about arm,
> could you tell me the difference between
> CONFIG_ARCH_EXYNOS4/CONFIG_ARCH_EXYNOS5 and CONFIG_PLAT_SAMSUNG please,
> I do not see the dependency between these in Kconfig file?
PLAT_SAMSUNG is the superset of ARCH_EXYNOS4/5 so I used this
dependency but currently only exynos based soc's have TMU driver. Also
it matches with the folder name.

Thanks,
Amit Daniel
>
> thanks,
> rui
>>  endif
>> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
>> index c054d41..b3063a9 100644
>> --- a/drivers/thermal/Makefile
>> +++ b/drivers/thermal/Makefile
>> @@ -17,7 +17,7 @@ thermal_sys-$(CONFIG_CPU_THERMAL)   += cpu_cooling.o
>>  obj-$(CONFIG_SPEAR_THERMAL)  += spear_thermal.o
>>  obj-$(CONFIG_RCAR_THERMAL)   += rcar_thermal.o
>>  obj-$(CONFIG_KIRKWOOD_THERMAL)  += kirkwood_thermal.o
>> -obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o
>> +obj-y                                += samsung/
>>  obj-$(CONFIG_DOVE_THERMAL)   += dove_thermal.o
>>  obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
>>  obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
>> diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
>> new file mode 100644
>> index 0000000..2d3d9dc
>> --- /dev/null
>> +++ b/drivers/thermal/samsung/Kconfig
>> @@ -0,0 +1,9 @@
>> +config EXYNOS_THERMAL
>> +     tristate "Temperature sensor on Samsung EXYNOS"
>> +     depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
>> +     depends on CPU_THERMAL
>> +     help
>> +       If you say yes here you get support for TMU (Thermal Management
>> +       Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
>> +       the exynos thermal driver with the core thermal layer and cpu
>> +       cooling API's.
>> diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
>> new file mode 100644
>> index 0000000..1fe6d93
>> --- /dev/null
>> +++ b/drivers/thermal/samsung/Makefile
>> @@ -0,0 +1,4 @@
>> +#
>> +# Samsung thermal specific Makefile
>> +#
>> +obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o
>> diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/samsung/exynos_thermal.c
>> similarity index 100%
>> rename from drivers/thermal/exynos_thermal.c
>> rename to drivers/thermal/samsung/exynos_thermal.c
>
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory
  2013-05-07 10:21     ` Tomasz Figa
@ 2013-05-07 13:18       ` amit daniel kachhap
  2013-05-07 13:36         ` Tomasz Figa
  0 siblings, 1 reply; 31+ messages in thread
From: amit daniel kachhap @ 2013-05-07 13:18 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Zhang Rui, linux-pm, linux-samsung-soc, linux-kernel, Kukjin Kim,
	Eduardo Valentin

Hi Tomasz Figa,

On Tue, May 7, 2013 at 3:51 PM, Tomasz Figa <t.figa@samsung.com> wrote:
> On Monday 06 of May 2013 23:05:06 Zhang Rui wrote:
>> On Fri, 2013-04-26 at 16:07 +0530, Amit Daniel Kachhap wrote:
>> > This movement of files is done for easy maintenance and adding more
>> > new sensor's support for exynos platform easily . This will also help in
>> > bifurcating exynos common, sensor driver and sensor data related parts.
>> >
>> > Acked-by: Kukjin Kim <kgene.kim@samsung.com>
>> > Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
>> > ---
>> >
>> >  drivers/thermal/Kconfig                        |   13 +++++--------
>> >  drivers/thermal/Makefile                       |    2 +-
>> >  drivers/thermal/samsung/Kconfig                |    9 +++++++++
>> >  drivers/thermal/samsung/Makefile               |    4 ++++
>> >  drivers/thermal/{ => samsung}/exynos_thermal.c |    0
>> >  5 files changed, 19 insertions(+), 9 deletions(-)
>> >  create mode 100644 drivers/thermal/samsung/Kconfig
>> >  create mode 100644 drivers/thermal/samsung/Makefile
>> >  rename drivers/thermal/{ => samsung}/exynos_thermal.c (100%)
>> >
>> > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
>> > index 5e3c025..081ddc5 100644
>> > --- a/drivers/thermal/Kconfig
>> > +++ b/drivers/thermal/Kconfig
>> > @@ -114,14 +114,6 @@ config KIRKWOOD_THERMAL
>> >
>> >       Support for the Kirkwood thermal sensor driver into the Linux thermal
>> >       framework. Only kirkwood 88F6282 and 88F6283 have this sensor.
>> >
>> > -config EXYNOS_THERMAL
>> > -   tristate "Temperature sensor on Samsung EXYNOS"
>> > -   depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
>> > -   depends on CPU_THERMAL
>> > -   help
>> > -     If you say yes here you get support for TMU (Thermal Management
>> > -     Unit) on SAMSUNG EXYNOS series of SoC.
>> > -
>> >
>> >  config DOVE_THERMAL
>> >
>> >     tristate "Temperature sensor on Marvell Dove SoCs"
>> >     depends on ARCH_DOVE
>> >
>> > @@ -169,4 +161,9 @@ config INTEL_POWERCLAMP
>> >
>> >       enforce idle time which results in more package C-state residency. The
>> >       user interface is exposed via generic thermal framework.
>> >
>> > +menu "Exynos thermal drivers"
>>
>> would it be more proper to use "Samsung thermal drivers" or "Samsung
>> Exynos thermal drivers" instead?
>
> +1
>
> Still, I wonder if it really makes sense to create a separate directory and
> submenu for this.

Yes separate directory was needed as the current TMU drivers supports
many exynos SOC's with some differences in the controller itself. This
has made it unmanageable and unclean and configuration data need to be
separated from driver. With all these re-structuring, tmu support for
exynos5440 is added very cleanly. Also many changes in this patchset
are for making the driver multi-stance which is needed for 5440.

Thanks,
Amit Daniel
>
>> > +depends on PLAT_SAMSUNG
>> > +source "drivers/thermal/samsung/Kconfig"
>> > +endmenu
>> > +
>>
>> sorry I know few about arm,
>> could you tell me the difference between
>> CONFIG_ARCH_EXYNOS4/CONFIG_ARCH_EXYNOS5 and CONFIG_PLAT_SAMSUNG please,
>> I do not see the dependency between these in Kconfig file?
>
> If those files were kept at thermal/, there would be no need for this check.
> Just particular drivers would depend on platform they are for.
>
> Best regards,
> --
> Tomasz Figa
> Samsung Poland R&D Center
> SW Solution Development, Kernel and System Framework
>>
>> >  endif
>> >
>> > diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
>> > index c054d41..b3063a9 100644
>> > --- a/drivers/thermal/Makefile
>> > +++ b/drivers/thermal/Makefile
>> > @@ -17,7 +17,7 @@ thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o
>> >
>> >  obj-$(CONFIG_SPEAR_THERMAL)        += spear_thermal.o
>> >  obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o
>> >  obj-$(CONFIG_KIRKWOOD_THERMAL)  += kirkwood_thermal.o
>> >
>> > -obj-$(CONFIG_EXYNOS_THERMAL)       += exynos_thermal.o
>> > +obj-y                              += samsung/
>> >
>> >  obj-$(CONFIG_DOVE_THERMAL)         += dove_thermal.o
>> >  obj-$(CONFIG_DB8500_THERMAL)       += db8500_thermal.o
>> >  obj-$(CONFIG_ARMADA_THERMAL)       += armada_thermal.o
>> >
>> > diff --git a/drivers/thermal/samsung/Kconfig
>> > b/drivers/thermal/samsung/Kconfig new file mode 100644
>> > index 0000000..2d3d9dc
>> > --- /dev/null
>> > +++ b/drivers/thermal/samsung/Kconfig
>> > @@ -0,0 +1,9 @@
>> > +config EXYNOS_THERMAL
>> > +   tristate "Temperature sensor on Samsung EXYNOS"
>> > +   depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
>> > +   depends on CPU_THERMAL
>> > +   help
>> > +     If you say yes here you get support for TMU (Thermal Management
>> > +     Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
>> > +     the exynos thermal driver with the core thermal layer and cpu
>> > +     cooling API's.
>> > diff --git a/drivers/thermal/samsung/Makefile
>> > b/drivers/thermal/samsung/Makefile new file mode 100644
>> > index 0000000..1fe6d93
>> > --- /dev/null
>> > +++ b/drivers/thermal/samsung/Makefile
>> > @@ -0,0 +1,4 @@
>> > +#
>> > +# Samsung thermal specific Makefile
>> > +#
>> > +obj-$(CONFIG_EXYNOS_THERMAL)       += exynos_thermal.o
>> > diff --git a/drivers/thermal/exynos_thermal.c
>> > b/drivers/thermal/samsung/exynos_thermal.c similarity index 100%
>> > rename from drivers/thermal/exynos_thermal.c
>> > rename to drivers/thermal/samsung/exynos_thermal.c
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc"
>> in the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH V2 02/20] thermal: exynos: Bifurcate exynos thermal common and tmu controller code
  2013-05-06 15:16   ` Zhang Rui
@ 2013-05-07 13:32     ` amit daniel kachhap
  0 siblings, 0 replies; 31+ messages in thread
From: amit daniel kachhap @ 2013-05-07 13:32 UTC (permalink / raw)
  To: Zhang Rui
  Cc: linux-pm, linux-samsung-soc, linux-kernel, Kukjin Kim,
	Eduardo Valentin

Hi Rui,

On Mon, May 6, 2013 at 8:46 PM, Zhang Rui <rui.zhang@intel.com> wrote:
> On Fri, 2013-04-26 at 16:07 +0530, Amit Daniel Kachhap wrote:
>> 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>
>> Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
>> ---
>>  drivers/thermal/samsung/Kconfig                 |   26 +-
>>  drivers/thermal/samsung/Makefile                |    4 +-
>>  drivers/thermal/samsung/exynos_thermal.c        |  421 +----------------------
>>  drivers/thermal/samsung/exynos_thermal_common.c |  389 +++++++++++++++++++++
>>  drivers/thermal/samsung/exynos_thermal_common.h |   71 ++++
>>  5 files changed, 491 insertions(+), 420 deletions(-)
>>  create mode 100644 drivers/thermal/samsung/exynos_thermal_common.c
>>  create mode 100644 drivers/thermal/samsung/exynos_thermal_common.h
>>
>> diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
>> index 2d3d9dc..1e3ba31 100644
>> --- a/drivers/thermal/samsung/Kconfig
>> +++ b/drivers/thermal/samsung/Kconfig
>> @@ -1,9 +1,21 @@
>> -config EXYNOS_THERMAL
>> -     tristate "Temperature sensor on Samsung EXYNOS"
>> +config EXYNOS_COMMON
>
> EXYNOS_COMMON is misleading here, better use EXYNOS_THERMAL_COMMON?
Yes  submitted V3 version with this change.
>
>> +     bool "Common thermal support for EXYNOS SOC's"
>>       depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
>> -     depends on CPU_THERMAL
>>       help
>> -       If you say yes here you get support for TMU (Thermal Management
>> -       Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
>> -       the exynos thermal driver with the core thermal layer and cpu
>> -       cooling API's.
>> +       If you say yes here you get support for EXYNOS TMU
>> +       (Thermal Management Unit) common registration/unregistration
>> +       functions to the core thermal layer and also to use the generic
>> +       cpu cooling API's.
>> +
>> +if EXYNOS_COMMON
>> +
>> +config EXYNOS_SOC_THERMAL
>> +     tristate "Temperature sensor on Samsung EXYNOS series SOC"
>> +     depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250)
>> +     help
>> +       If you say yes here you can enable TMU (Thermal Management Unit) on
>> +       SAMSUNG EXYNOS 4210, 4412, 4414 and 5250 series of SoC. This option
>> +       initialises the TMU controller and registers/unregisters with exynos
>> +       common thermal layer.
>> +
>> +endif
>> diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
>> index 1fe6d93..fcda5b4 100644
>> --- a/drivers/thermal/samsung/Makefile
>> +++ b/drivers/thermal/samsung/Makefile
>> @@ -1,4 +1,6 @@
>>  #
>>  # Samsung thermal specific Makefile
>>  #
>> -obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o
>> +obj-$(CONFIG_EXYNOS_SOC_THERMAL)             += exynos_soc_thermal.o
>> +exynos_soc_thermal-y                         := exynos_thermal.o
>> +exynos_soc_thermal-$(CONFIG_EXYNOS_COMMON)   += exynos_thermal_common.o
>
> the Makefile suggests that exynos_soc_thermal driver could be built
> without CONFIG_EXYNOS_COMMON.
> But the Kconfig file shows that exynos_soc_thermal depends on
> CONFIG_EXYNOS_COMMON.
> If exynos_thermal_common.c contains the code to interact with the
> generic thermal layer and you do not want a soc driver without thermal
> support, just remove CONFIG_EXYNOS_COMMON and always build it into
> exynos_soc_thermal.o.
> what do you think?

This is a good catch. I somehow missed this. I just submitted a patch
fixing this issue. Actually CONFIG_EXYNOS_COMMON is independent of
CONFIG_EXYNOS_SOC_THERMAL. Now I have added 3
 Kconfig symbol that maps to tmu driver. exynos common part and exynos
configuration data.
In the makefile TMU driver is selected when CONFIG_EXYNOS_SOC_THERMAL
is enabled. To have extra support for common part and configuration
data, those configs need to be enabled

Thanks,
Amit Daniel
>
> thanks,
> rui
>> diff --git a/drivers/thermal/samsung/exynos_thermal.c b/drivers/thermal/samsung/exynos_thermal.c
>> index d20ce9e..4c85945 100644
>> --- a/drivers/thermal/samsung/exynos_thermal.c
>> +++ b/drivers/thermal/samsung/exynos_thermal.c
>> @@ -21,23 +21,19 @@
>>   *
>>   */
>>
>> -#include <linux/module.h>
>> -#include <linux/err.h>
>> -#include <linux/kernel.h>
>> -#include <linux/slab.h>
>> -#include <linux/platform_device.h>
>> -#include <linux/interrupt.h>
>>  #include <linux/clk.h>
>> -#include <linux/workqueue.h>
>> -#include <linux/sysfs.h>
>> -#include <linux/kobject.h>
>>  #include <linux/io.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/kernel.h>
>> +#include <linux/kobject.h>
>> +#include <linux/module.h>
>>  #include <linux/mutex.h>
>> -#include <linux/platform_data/exynos_thermal.h>
>> -#include <linux/thermal.h>
>> -#include <linux/cpufreq.h>
>> -#include <linux/cpu_cooling.h>
>>  #include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/platform_data/exynos_thermal.h>
>> +#include <linux/slab.h>
>> +#include <linux/workqueue.h>
>> +#include "exynos_thermal_common.h"
>>
>>  /* Exynos generic registers */
>>  #define EXYNOS_TMU_REG_TRIMINFO              0x0
>> @@ -88,16 +84,6 @@
>>  #define EFUSE_MIN_VALUE 40
>>  #define EFUSE_MAX_VALUE 100
>>
>> -/* In-kernel thermal framework related macros & definations */
>> -#define SENSOR_NAME_LEN      16
>> -#define MAX_TRIP_COUNT       8
>> -#define MAX_COOLING_DEVICE 4
>> -#define MAX_THRESHOLD_LEVS 4
>> -
>> -#define ACTIVE_INTERVAL 500
>> -#define IDLE_INTERVAL 10000
>> -#define MCELSIUS     1000
>> -
>>  #ifdef CONFIG_THERMAL_EMULATION
>>  #define EXYNOS_EMUL_TIME     0x57F0
>>  #define EXYNOS_EMUL_TIME_SHIFT       16
>> @@ -106,17 +92,6 @@
>>  #define EXYNOS_EMUL_ENABLE   0x1
>>  #endif /* CONFIG_THERMAL_EMULATION */
>>
>> -/* CPU Zone information */
>> -#define PANIC_ZONE      4
>> -#define WARN_ZONE       3
>> -#define MONITOR_ZONE    2
>> -#define SAFE_ZONE       1
>> -
>> -#define GET_ZONE(trip) (trip + 2)
>> -#define GET_TRIP(zone) (zone - 2)
>> -
>> -#define EXYNOS_ZONE_COUNT    3
>> -
>>  struct exynos_tmu_data {
>>       struct exynos_tmu_platform_data *pdata;
>>       struct resource *mem;
>> @@ -129,384 +104,6 @@ struct exynos_tmu_data {
>>       u8 temp_error1, temp_error2;
>>  };
>>
>> -struct       thermal_trip_point_conf {
>> -     int trip_val[MAX_TRIP_COUNT];
>> -     int trip_count;
>> -     u8 trigger_falling;
>> -};
>> -
>> -struct       thermal_cooling_conf {
>> -     struct freq_clip_table freq_data[MAX_TRIP_COUNT];
>> -     int freq_clip_count;
>> -};
>> -
>> -struct thermal_sensor_conf {
>> -     char name[SENSOR_NAME_LEN];
>> -     int (*read_temperature)(void *data);
>> -     int (*write_emul_temp)(void *drv_data, unsigned long temp);
>> -     struct thermal_trip_point_conf trip_data;
>> -     struct thermal_cooling_conf cooling_data;
>> -     void *private_data;
>> -};
>> -
>> -struct exynos_thermal_zone {
>> -     enum thermal_device_mode mode;
>> -     struct thermal_zone_device *therm_dev;
>> -     struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
>> -     unsigned int cool_dev_size;
>> -     struct platform_device *exynos4_dev;
>> -     struct thermal_sensor_conf *sensor_conf;
>> -     bool bind;
>> -};
>> -
>> -static struct exynos_thermal_zone *th_zone;
>> -static void exynos_unregister_thermal(void);
>> -static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
>> -
>> -/* Get mode callback functions for thermal zone */
>> -static int exynos_get_mode(struct thermal_zone_device *thermal,
>> -                     enum thermal_device_mode *mode)
>> -{
>> -     if (th_zone)
>> -             *mode = th_zone->mode;
>> -     return 0;
>> -}
>> -
>> -/* Set mode callback functions for thermal zone */
>> -static int exynos_set_mode(struct thermal_zone_device *thermal,
>> -                     enum thermal_device_mode mode)
>> -{
>> -     if (!th_zone->therm_dev) {
>> -             pr_notice("thermal zone not registered\n");
>> -             return 0;
>> -     }
>> -
>> -     mutex_lock(&th_zone->therm_dev->lock);
>> -
>> -     if (mode == THERMAL_DEVICE_ENABLED &&
>> -             !th_zone->sensor_conf->trip_data.trigger_falling)
>> -             th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
>> -     else
>> -             th_zone->therm_dev->polling_delay = 0;
>> -
>> -     mutex_unlock(&th_zone->therm_dev->lock);
>> -
>> -     th_zone->mode = mode;
>> -     thermal_zone_device_update(th_zone->therm_dev);
>> -     pr_info("thermal polling set for duration=%d msec\n",
>> -                             th_zone->therm_dev->polling_delay);
>> -     return 0;
>> -}
>> -
>> -
>> -/* Get trip type callback functions for thermal zone */
>> -static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
>> -                              enum thermal_trip_type *type)
>> -{
>> -     switch (GET_ZONE(trip)) {
>> -     case MONITOR_ZONE:
>> -     case WARN_ZONE:
>> -             *type = THERMAL_TRIP_ACTIVE;
>> -             break;
>> -     case PANIC_ZONE:
>> -             *type = THERMAL_TRIP_CRITICAL;
>> -             break;
>> -     default:
>> -             return -EINVAL;
>> -     }
>> -     return 0;
>> -}
>> -
>> -/* Get trip temperature callback functions for thermal zone */
>> -static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
>> -                             unsigned long *temp)
>> -{
>> -     if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
>> -             return -EINVAL;
>> -
>> -     *temp = th_zone->sensor_conf->trip_data.trip_val[trip];
>> -     /* convert the temperature into millicelsius */
>> -     *temp = *temp * MCELSIUS;
>> -
>> -     return 0;
>> -}
>> -
>> -/* Get critical temperature callback functions for thermal zone */
>> -static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
>> -                             unsigned long *temp)
>> -{
>> -     int ret;
>> -     /* Panic zone */
>> -     ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
>> -     return ret;
>> -}
>> -
>> -/* Bind callback functions for thermal zone */
>> -static int exynos_bind(struct thermal_zone_device *thermal,
>> -                     struct thermal_cooling_device *cdev)
>> -{
>> -     int ret = 0, i, tab_size, level;
>> -     struct freq_clip_table *tab_ptr, *clip_data;
>> -     struct thermal_sensor_conf *data = th_zone->sensor_conf;
>> -
>> -     tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
>> -     tab_size = data->cooling_data.freq_clip_count;
>> -
>> -     if (tab_ptr == NULL || tab_size == 0)
>> -             return -EINVAL;
>> -
>> -     /* find the cooling device registered*/
>> -     for (i = 0; i < th_zone->cool_dev_size; i++)
>> -             if (cdev == th_zone->cool_dev[i])
>> -                     break;
>> -
>> -     /* No matching cooling device */
>> -     if (i == th_zone->cool_dev_size)
>> -             return 0;
>> -
>> -     /* Bind the thermal zone to the cpufreq cooling device */
>> -     for (i = 0; i < tab_size; i++) {
>> -             clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
>> -             level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max);
>> -             if (level == THERMAL_CSTATE_INVALID)
>> -                     return 0;
>> -             switch (GET_ZONE(i)) {
>> -             case MONITOR_ZONE:
>> -             case WARN_ZONE:
>> -                     if (thermal_zone_bind_cooling_device(thermal, i, cdev,
>> -                                                             level, 0)) {
>> -                             pr_err("error binding cdev inst %d\n", i);
>> -                             ret = -EINVAL;
>> -                     }
>> -                     th_zone->bind = true;
>> -                     break;
>> -             default:
>> -                     ret = -EINVAL;
>> -             }
>> -     }
>> -
>> -     return ret;
>> -}
>> -
>> -/* Unbind callback functions for thermal zone */
>> -static int exynos_unbind(struct thermal_zone_device *thermal,
>> -                     struct thermal_cooling_device *cdev)
>> -{
>> -     int ret = 0, i, tab_size;
>> -     struct thermal_sensor_conf *data = th_zone->sensor_conf;
>> -
>> -     if (th_zone->bind == false)
>> -             return 0;
>> -
>> -     tab_size = data->cooling_data.freq_clip_count;
>> -
>> -     if (tab_size == 0)
>> -             return -EINVAL;
>> -
>> -     /* find the cooling device registered*/
>> -     for (i = 0; i < th_zone->cool_dev_size; i++)
>> -             if (cdev == th_zone->cool_dev[i])
>> -                     break;
>> -
>> -     /* No matching cooling device */
>> -     if (i == th_zone->cool_dev_size)
>> -             return 0;
>> -
>> -     /* Bind the thermal zone to the cpufreq cooling device */
>> -     for (i = 0; i < tab_size; i++) {
>> -             switch (GET_ZONE(i)) {
>> -             case MONITOR_ZONE:
>> -             case WARN_ZONE:
>> -                     if (thermal_zone_unbind_cooling_device(thermal, i,
>> -                                                             cdev)) {
>> -                             pr_err("error unbinding cdev inst=%d\n", i);
>> -                             ret = -EINVAL;
>> -                     }
>> -                     th_zone->bind = false;
>> -                     break;
>> -             default:
>> -                     ret = -EINVAL;
>> -             }
>> -     }
>> -     return ret;
>> -}
>> -
>> -/* Get temperature callback functions for thermal zone */
>> -static int exynos_get_temp(struct thermal_zone_device *thermal,
>> -                     unsigned long *temp)
>> -{
>> -     void *data;
>> -
>> -     if (!th_zone->sensor_conf) {
>> -             pr_info("Temperature sensor not initialised\n");
>> -             return -EINVAL;
>> -     }
>> -     data = th_zone->sensor_conf->private_data;
>> -     *temp = th_zone->sensor_conf->read_temperature(data);
>> -     /* convert the temperature into millicelsius */
>> -     *temp = *temp * MCELSIUS;
>> -     return 0;
>> -}
>> -
>> -/* Get temperature callback functions for thermal zone */
>> -static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
>> -                                             unsigned long temp)
>> -{
>> -     void *data;
>> -     int ret = -EINVAL;
>> -
>> -     if (!th_zone->sensor_conf) {
>> -             pr_info("Temperature sensor not initialised\n");
>> -             return -EINVAL;
>> -     }
>> -     data = th_zone->sensor_conf->private_data;
>> -     if (th_zone->sensor_conf->write_emul_temp)
>> -             ret = th_zone->sensor_conf->write_emul_temp(data, temp);
>> -     return ret;
>> -}
>> -
>> -/* Get the temperature trend */
>> -static int exynos_get_trend(struct thermal_zone_device *thermal,
>> -                     int trip, enum thermal_trend *trend)
>> -{
>> -     int ret;
>> -     unsigned long trip_temp;
>> -
>> -     ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
>> -     if (ret < 0)
>> -             return ret;
>> -
>> -     if (thermal->temperature >= trip_temp)
>> -             *trend = THERMAL_TREND_RAISE_FULL;
>> -     else
>> -             *trend = THERMAL_TREND_DROP_FULL;
>> -
>> -     return 0;
>> -}
>> -/* Operation callback functions for thermal zone */
>> -static struct thermal_zone_device_ops const exynos_dev_ops = {
>> -     .bind = exynos_bind,
>> -     .unbind = exynos_unbind,
>> -     .get_temp = exynos_get_temp,
>> -     .set_emul_temp = exynos_set_emul_temp,
>> -     .get_trend = exynos_get_trend,
>> -     .get_mode = exynos_get_mode,
>> -     .set_mode = exynos_set_mode,
>> -     .get_trip_type = exynos_get_trip_type,
>> -     .get_trip_temp = exynos_get_trip_temp,
>> -     .get_crit_temp = exynos_get_crit_temp,
>> -};
>> -
>> -/*
>> - * This function may be called from interrupt based temperature sensor
>> - * when threshold is changed.
>> - */
>> -static void exynos_report_trigger(void)
>> -{
>> -     unsigned int i;
>> -     char data[10];
>> -     char *envp[] = { data, NULL };
>> -
>> -     if (!th_zone || !th_zone->therm_dev)
>> -             return;
>> -     if (th_zone->bind == false) {
>> -             for (i = 0; i < th_zone->cool_dev_size; i++) {
>> -                     if (!th_zone->cool_dev[i])
>> -                             continue;
>> -                     exynos_bind(th_zone->therm_dev,
>> -                                     th_zone->cool_dev[i]);
>> -             }
>> -     }
>> -
>> -     thermal_zone_device_update(th_zone->therm_dev);
>> -
>> -     mutex_lock(&th_zone->therm_dev->lock);
>> -     /* Find the level for which trip happened */
>> -     for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
>> -             if (th_zone->therm_dev->last_temperature <
>> -                     th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
>> -                     break;
>> -     }
>> -
>> -     if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
>> -             !th_zone->sensor_conf->trip_data.trigger_falling) {
>> -             if (i > 0)
>> -                     th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
>> -             else
>> -                     th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
>> -     }
>> -
>> -     snprintf(data, sizeof(data), "%u", i);
>> -     kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
>> -     mutex_unlock(&th_zone->therm_dev->lock);
>> -}
>> -
>> -/* Register with the in-kernel thermal management */
>> -static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
>> -{
>> -     int ret;
>> -     struct cpumask mask_val;
>> -
>> -     if (!sensor_conf || !sensor_conf->read_temperature) {
>> -             pr_err("Temperature sensor not initialised\n");
>> -             return -EINVAL;
>> -     }
>> -
>> -     th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
>> -     if (!th_zone)
>> -             return -ENOMEM;
>> -
>> -     th_zone->sensor_conf = sensor_conf;
>> -     cpumask_set_cpu(0, &mask_val);
>> -     th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
>> -     if (IS_ERR(th_zone->cool_dev[0])) {
>> -             pr_err("Failed to register cpufreq cooling device\n");
>> -             ret = -EINVAL;
>> -             goto err_unregister;
>> -     }
>> -     th_zone->cool_dev_size++;
>> -
>> -     th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
>> -                     EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
>> -                     sensor_conf->trip_data.trigger_falling ?
>> -                     0 : IDLE_INTERVAL);
>> -
>> -     if (IS_ERR(th_zone->therm_dev)) {
>> -             pr_err("Failed to register thermal zone device\n");
>> -             ret = PTR_ERR(th_zone->therm_dev);
>> -             goto err_unregister;
>> -     }
>> -     th_zone->mode = THERMAL_DEVICE_ENABLED;
>> -
>> -     pr_info("Exynos: Kernel Thermal management registered\n");
>> -
>> -     return 0;
>> -
>> -err_unregister:
>> -     exynos_unregister_thermal();
>> -     return ret;
>> -}
>> -
>> -/* Un-Register with the in-kernel thermal management */
>> -static void exynos_unregister_thermal(void)
>> -{
>> -     int i;
>> -
>> -     if (!th_zone)
>> -             return;
>> -
>> -     if (th_zone->therm_dev)
>> -             thermal_zone_device_unregister(th_zone->therm_dev);
>> -
>> -     for (i = 0; i < th_zone->cool_dev_size; i++) {
>> -             if (th_zone->cool_dev[i])
>> -                     cpufreq_cooling_unregister(th_zone->cool_dev[i]);
>> -     }
>> -
>> -     kfree(th_zone);
>> -     pr_info("Exynos: Kernel Thermal management unregistered\n");
>> -}
>> -
>>  /*
>>   * TMU treats temperature as a mapped temperature code.
>>   * The temperature is converted differently depending on the calibration type.
>> diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
>> new file mode 100644
>> index 0000000..9a57606
>> --- /dev/null
>> +++ b/drivers/thermal/samsung/exynos_thermal_common.c
>> @@ -0,0 +1,389 @@
>> +/*
>> + * exynos_thermal_common.c - Samsung EXYNOS common thermal file
>> + *
>> + *  Copyright (C) 2013 Samsung Electronics
>> + *  Amit Daniel Kachhap <amit.daniel@samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>> + *
>> + */
>> +
>> +#include <linux/cpufreq.h>
>> +#include <linux/cpu_cooling.h>
>> +#include <linux/err.h>
>> +#include <linux/io.h>
>> +#include <linux/kernel.h>
>> +#include <linux/kobject.h>
>> +#include <linux/mutex.h>
>> +#include <linux/platform_data/exynos_thermal.h>
>> +#include <linux/slab.h>
>> +#include <linux/thermal.h>
>> +#include "exynos_thermal_common.h"
>> +
>> +struct exynos_thermal_zone {
>> +     enum thermal_device_mode mode;
>> +     struct thermal_zone_device *therm_dev;
>> +     struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
>> +     unsigned int cool_dev_size;
>> +     struct platform_device *exynos4_dev;
>> +     struct thermal_sensor_conf *sensor_conf;
>> +     bool bind;
>> +};
>> +
>> +static struct exynos_thermal_zone *th_zone;
>> +
>> +/* Get mode callback functions for thermal zone */
>> +static int exynos_get_mode(struct thermal_zone_device *thermal,
>> +                     enum thermal_device_mode *mode)
>> +{
>> +     if (th_zone)
>> +             *mode = th_zone->mode;
>> +     return 0;
>> +}
>> +
>> +/* Set mode callback functions for thermal zone */
>> +static int exynos_set_mode(struct thermal_zone_device *thermal,
>> +                     enum thermal_device_mode mode)
>> +{
>> +     if (!th_zone->therm_dev) {
>> +             pr_notice("thermal zone not registered\n");
>> +             return 0;
>> +     }
>> +
>> +     mutex_lock(&th_zone->therm_dev->lock);
>> +
>> +     if (mode == THERMAL_DEVICE_ENABLED &&
>> +             !th_zone->sensor_conf->trip_data.trigger_falling)
>> +             th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
>> +     else
>> +             th_zone->therm_dev->polling_delay = 0;
>> +
>> +     mutex_unlock(&th_zone->therm_dev->lock);
>> +
>> +     th_zone->mode = mode;
>> +     thermal_zone_device_update(th_zone->therm_dev);
>> +     pr_info("thermal polling set for duration=%d msec\n",
>> +                             th_zone->therm_dev->polling_delay);
>> +     return 0;
>> +}
>> +
>> +
>> +/* Get trip type callback functions for thermal zone */
>> +static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
>> +                              enum thermal_trip_type *type)
>> +{
>> +     switch (GET_ZONE(trip)) {
>> +     case MONITOR_ZONE:
>> +     case WARN_ZONE:
>> +             *type = THERMAL_TRIP_ACTIVE;
>> +             break;
>> +     case PANIC_ZONE:
>> +             *type = THERMAL_TRIP_CRITICAL;
>> +             break;
>> +     default:
>> +             return -EINVAL;
>> +     }
>> +     return 0;
>> +}
>> +
>> +/* Get trip temperature callback functions for thermal zone */
>> +static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
>> +                             unsigned long *temp)
>> +{
>> +     if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
>> +             return -EINVAL;
>> +
>> +     *temp = th_zone->sensor_conf->trip_data.trip_val[trip];
>> +     /* convert the temperature into millicelsius */
>> +     *temp = *temp * MCELSIUS;
>> +
>> +     return 0;
>> +}
>> +
>> +/* Get critical temperature callback functions for thermal zone */
>> +static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
>> +                             unsigned long *temp)
>> +{
>> +     int ret;
>> +     /* Panic zone */
>> +     ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
>> +     return ret;
>> +}
>> +
>> +/* Bind callback functions for thermal zone */
>> +static int exynos_bind(struct thermal_zone_device *thermal,
>> +                     struct thermal_cooling_device *cdev)
>> +{
>> +     int ret = 0, i, tab_size, level;
>> +     struct freq_clip_table *tab_ptr, *clip_data;
>> +     struct thermal_sensor_conf *data = th_zone->sensor_conf;
>> +
>> +     tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
>> +     tab_size = data->cooling_data.freq_clip_count;
>> +
>> +     if (tab_ptr == NULL || tab_size == 0)
>> +             return -EINVAL;
>> +
>> +     /* find the cooling device registered*/
>> +     for (i = 0; i < th_zone->cool_dev_size; i++)
>> +             if (cdev == th_zone->cool_dev[i])
>> +                     break;
>> +
>> +     /* No matching cooling device */
>> +     if (i == th_zone->cool_dev_size)
>> +             return 0;
>> +
>> +     /* Bind the thermal zone to the cpufreq cooling device */
>> +     for (i = 0; i < tab_size; i++) {
>> +             clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
>> +             level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max);
>> +             if (level == THERMAL_CSTATE_INVALID)
>> +                     return 0;
>> +             switch (GET_ZONE(i)) {
>> +             case MONITOR_ZONE:
>> +             case WARN_ZONE:
>> +                     if (thermal_zone_bind_cooling_device(thermal, i, cdev,
>> +                                                             level, 0)) {
>> +                             pr_err("error binding cdev inst %d\n", i);
>> +                             ret = -EINVAL;
>> +                     }
>> +                     th_zone->bind = true;
>> +                     break;
>> +             default:
>> +                     ret = -EINVAL;
>> +             }
>> +     }
>> +
>> +     return ret;
>> +}
>> +
>> +/* Unbind callback functions for thermal zone */
>> +static int exynos_unbind(struct thermal_zone_device *thermal,
>> +                     struct thermal_cooling_device *cdev)
>> +{
>> +     int ret = 0, i, tab_size;
>> +     struct thermal_sensor_conf *data = th_zone->sensor_conf;
>> +
>> +     if (th_zone->bind == false)
>> +             return 0;
>> +
>> +     tab_size = data->cooling_data.freq_clip_count;
>> +
>> +     if (tab_size == 0)
>> +             return -EINVAL;
>> +
>> +     /* find the cooling device registered*/
>> +     for (i = 0; i < th_zone->cool_dev_size; i++)
>> +             if (cdev == th_zone->cool_dev[i])
>> +                     break;
>> +
>> +     /* No matching cooling device */
>> +     if (i == th_zone->cool_dev_size)
>> +             return 0;
>> +
>> +     /* Bind the thermal zone to the cpufreq cooling device */
>> +     for (i = 0; i < tab_size; i++) {
>> +             switch (GET_ZONE(i)) {
>> +             case MONITOR_ZONE:
>> +             case WARN_ZONE:
>> +                     if (thermal_zone_unbind_cooling_device(thermal, i,
>> +                                                             cdev)) {
>> +                             pr_err("error unbinding cdev inst=%d\n", i);
>> +                             ret = -EINVAL;
>> +                     }
>> +                     th_zone->bind = false;
>> +                     break;
>> +             default:
>> +                     ret = -EINVAL;
>> +             }
>> +     }
>> +     return ret;
>> +}
>> +
>> +/* Get temperature callback functions for thermal zone */
>> +static int exynos_get_temp(struct thermal_zone_device *thermal,
>> +                     unsigned long *temp)
>> +{
>> +     void *data;
>> +
>> +     if (!th_zone->sensor_conf) {
>> +             pr_info("Temperature sensor not initialised\n");
>> +             return -EINVAL;
>> +     }
>> +     data = th_zone->sensor_conf->private_data;
>> +     *temp = th_zone->sensor_conf->read_temperature(data);
>> +     /* convert the temperature into millicelsius */
>> +     *temp = *temp * MCELSIUS;
>> +     return 0;
>> +}
>> +
>> +/* Get temperature callback functions for thermal zone */
>> +static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
>> +                                             unsigned long temp)
>> +{
>> +     void *data;
>> +     int ret = -EINVAL;
>> +
>> +     if (!th_zone->sensor_conf) {
>> +             pr_info("Temperature sensor not initialised\n");
>> +             return -EINVAL;
>> +     }
>> +     data = th_zone->sensor_conf->private_data;
>> +     if (th_zone->sensor_conf->write_emul_temp)
>> +             ret = th_zone->sensor_conf->write_emul_temp(data, temp);
>> +     return ret;
>> +}
>> +
>> +/* Get the temperature trend */
>> +static int exynos_get_trend(struct thermal_zone_device *thermal,
>> +                     int trip, enum thermal_trend *trend)
>> +{
>> +     int ret;
>> +     unsigned long trip_temp;
>> +
>> +     ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
>> +     if (ret < 0)
>> +             return ret;
>> +
>> +     if (thermal->temperature >= trip_temp)
>> +             *trend = THERMAL_TREND_RAISE_FULL;
>> +     else
>> +             *trend = THERMAL_TREND_DROP_FULL;
>> +
>> +     return 0;
>> +}
>> +/* Operation callback functions for thermal zone */
>> +static struct thermal_zone_device_ops const exynos_dev_ops = {
>> +     .bind = exynos_bind,
>> +     .unbind = exynos_unbind,
>> +     .get_temp = exynos_get_temp,
>> +     .set_emul_temp = exynos_set_emul_temp,
>> +     .get_trend = exynos_get_trend,
>> +     .get_mode = exynos_get_mode,
>> +     .set_mode = exynos_set_mode,
>> +     .get_trip_type = exynos_get_trip_type,
>> +     .get_trip_temp = exynos_get_trip_temp,
>> +     .get_crit_temp = exynos_get_crit_temp,
>> +};
>> +
>> +/*
>> + * This function may be called from interrupt based temperature sensor
>> + * when threshold is changed.
>> + */
>> +void exynos_report_trigger(void)
>> +{
>> +     unsigned int i;
>> +     char data[10];
>> +     char *envp[] = { data, NULL };
>> +
>> +     if (!th_zone || !th_zone->therm_dev)
>> +             return;
>> +     if (th_zone->bind == false) {
>> +             for (i = 0; i < th_zone->cool_dev_size; i++) {
>> +                     if (!th_zone->cool_dev[i])
>> +                             continue;
>> +                     exynos_bind(th_zone->therm_dev,
>> +                                     th_zone->cool_dev[i]);
>> +             }
>> +     }
>> +
>> +     thermal_zone_device_update(th_zone->therm_dev);
>> +
>> +     mutex_lock(&th_zone->therm_dev->lock);
>> +     /* Find the level for which trip happened */
>> +     for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
>> +             if (th_zone->therm_dev->last_temperature <
>> +                     th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
>> +                     break;
>> +     }
>> +
>> +     if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
>> +             !th_zone->sensor_conf->trip_data.trigger_falling) {
>> +             if (i > 0)
>> +                     th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
>> +             else
>> +                     th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
>> +     }
>> +
>> +     snprintf(data, sizeof(data), "%u", i);
>> +     kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
>> +     mutex_unlock(&th_zone->therm_dev->lock);
>> +}
>> +
>> +/* Register with the in-kernel thermal management */
>> +int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
>> +{
>> +     int ret;
>> +     struct cpumask mask_val;
>> +
>> +     if (!sensor_conf || !sensor_conf->read_temperature) {
>> +             pr_err("Temperature sensor not initialised\n");
>> +             return -EINVAL;
>> +     }
>> +
>> +     th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
>> +     if (!th_zone)
>> +             return -ENOMEM;
>> +
>> +     th_zone->sensor_conf = sensor_conf;
>> +     cpumask_set_cpu(0, &mask_val);
>> +     th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
>> +     if (IS_ERR(th_zone->cool_dev[0])) {
>> +             pr_err("Failed to register cpufreq cooling device\n");
>> +             ret = -EINVAL;
>> +             goto err_unregister;
>> +     }
>> +     th_zone->cool_dev_size++;
>> +
>> +     th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
>> +                     EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
>> +                     sensor_conf->trip_data.trigger_falling ?
>> +                     0 : IDLE_INTERVAL);
>> +
>> +     if (IS_ERR(th_zone->therm_dev)) {
>> +             pr_err("Failed to register thermal zone device\n");
>> +             ret = PTR_ERR(th_zone->therm_dev);
>> +             goto err_unregister;
>> +     }
>> +     th_zone->mode = THERMAL_DEVICE_ENABLED;
>> +
>> +     pr_info("Exynos: Kernel Thermal management registered\n");
>> +
>> +     return 0;
>> +
>> +err_unregister:
>> +     exynos_unregister_thermal();
>> +     return ret;
>> +}
>> +
>> +/* Un-Register with the in-kernel thermal management */
>> +void exynos_unregister_thermal(void)
>> +{
>> +     int i;
>> +
>> +     if (!th_zone)
>> +             return;
>> +
>> +     if (th_zone->therm_dev)
>> +             thermal_zone_device_unregister(th_zone->therm_dev);
>> +
>> +     for (i = 0; i < th_zone->cool_dev_size; i++) {
>> +             if (th_zone->cool_dev[i])
>> +                     cpufreq_cooling_unregister(th_zone->cool_dev[i]);
>> +     }
>> +
>> +     kfree(th_zone);
>> +     pr_info("Exynos: Kernel Thermal management unregistered\n");
>> +}
>> diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
>> new file mode 100644
>> index 0000000..165401f
>> --- /dev/null
>> +++ b/drivers/thermal/samsung/exynos_thermal_common.h
>> @@ -0,0 +1,71 @@
>> +/*
>> + * exynos_thermal_common.h - Samsung EXYNOS common header file
>> + *
>> + *  Copyright (C) 2013 Samsung Electronics
>> + *  Amit Daniel Kachhap <amit.daniel@samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>> + *
>> + */
>> +
>> +#ifndef _LINUX_EXYNOS_THERMAL_COMMON_H
>> +#define _LINUX_EXYNOS_THERMAL_COMMON_H
>> +
>> +/* In-kernel thermal framework related macros & definations */
>> +#define SENSOR_NAME_LEN      16
>> +#define MAX_TRIP_COUNT       8
>> +#define MAX_COOLING_DEVICE 4
>> +#define MAX_THRESHOLD_LEVS 4
>> +
>> +#define ACTIVE_INTERVAL 500
>> +#define IDLE_INTERVAL 10000
>> +#define MCELSIUS     1000
>> +
>> +/* CPU Zone information */
>> +#define PANIC_ZONE      4
>> +#define WARN_ZONE       3
>> +#define MONITOR_ZONE    2
>> +#define SAFE_ZONE       1
>> +
>> +#define GET_ZONE(trip) (trip + 2)
>> +#define GET_TRIP(zone) (zone - 2)
>> +
>> +#define EXYNOS_ZONE_COUNT    3
>> +
>> +struct       thermal_trip_point_conf {
>> +     int trip_val[MAX_TRIP_COUNT];
>> +     int trip_count;
>> +     u8 trigger_falling;
>> +};
>> +
>> +struct       thermal_cooling_conf {
>> +     struct freq_clip_table freq_data[MAX_TRIP_COUNT];
>> +     int freq_clip_count;
>> +};
>> +
>> +struct thermal_sensor_conf {
>> +     char name[SENSOR_NAME_LEN];
>> +     int (*read_temperature)(void *data);
>> +     int (*write_emul_temp)(void *drv_data, unsigned long temp);
>> +     struct thermal_trip_point_conf trip_data;
>> +     struct thermal_cooling_conf cooling_data;
>> +     void *private_data;
>> +};
>> +
>> +/*Functions used exynos based thermal sensor driver*/
>> +void exynos_unregister_thermal(void);
>> +int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
>> +void exynos_report_trigger(void);
>> +#endif /* _LINUX_EXYNOS_THERMAL_COMMON_H */
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory
  2013-05-07 13:18       ` amit daniel kachhap
@ 2013-05-07 13:36         ` Tomasz Figa
  0 siblings, 0 replies; 31+ messages in thread
From: Tomasz Figa @ 2013-05-07 13:36 UTC (permalink / raw)
  To: amit daniel kachhap
  Cc: Zhang Rui, linux-pm, linux-samsung-soc, linux-kernel, Kukjin Kim,
	Eduardo Valentin

On Tuesday 07 of May 2013 18:48:46 amit daniel kachhap wrote:
> Hi Tomasz Figa,
> 
> On Tue, May 7, 2013 at 3:51 PM, Tomasz Figa <t.figa@samsung.com> wrote:
> > On Monday 06 of May 2013 23:05:06 Zhang Rui wrote:
> >> On Fri, 2013-04-26 at 16:07 +0530, Amit Daniel Kachhap wrote:
> >> > This movement of files is done for easy maintenance and adding more
> >> > new sensor's support for exynos platform easily . This will also help
> >> > in
> >> > bifurcating exynos common, sensor driver and sensor data related parts.
> >> > 
> >> > Acked-by: Kukjin Kim <kgene.kim@samsung.com>
> >> > Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
> >> > ---
> >> > 
> >> >  drivers/thermal/Kconfig                        |   13 +++++--------
> >> >  drivers/thermal/Makefile                       |    2 +-
> >> >  drivers/thermal/samsung/Kconfig                |    9 +++++++++
> >> >  drivers/thermal/samsung/Makefile               |    4 ++++
> >> >  drivers/thermal/{ => samsung}/exynos_thermal.c |    0
> >> >  5 files changed, 19 insertions(+), 9 deletions(-)
> >> >  create mode 100644 drivers/thermal/samsung/Kconfig
> >> >  create mode 100644 drivers/thermal/samsung/Makefile
> >> >  rename drivers/thermal/{ => samsung}/exynos_thermal.c (100%)
> >> > 
> >> > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> >> > index 5e3c025..081ddc5 100644
> >> > --- a/drivers/thermal/Kconfig
> >> > +++ b/drivers/thermal/Kconfig
> >> > @@ -114,14 +114,6 @@ config KIRKWOOD_THERMAL
> >> > 
> >> >       Support for the Kirkwood thermal sensor driver into the Linux
> >> >       thermal
> >> >       framework. Only kirkwood 88F6282 and 88F6283 have this sensor.
> >> > 
> >> > -config EXYNOS_THERMAL
> >> > -   tristate "Temperature sensor on Samsung EXYNOS"
> >> > -   depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
> >> > -   depends on CPU_THERMAL
> >> > -   help
> >> > -     If you say yes here you get support for TMU (Thermal Management
> >> > -     Unit) on SAMSUNG EXYNOS series of SoC.
> >> > -
> >> > 
> >> >  config DOVE_THERMAL
> >> >  
> >> >     tristate "Temperature sensor on Marvell Dove SoCs"
> >> >     depends on ARCH_DOVE
> >> > 
> >> > @@ -169,4 +161,9 @@ config INTEL_POWERCLAMP
> >> > 
> >> >       enforce idle time which results in more package C-state
> >> >       residency. The
> >> >       user interface is exposed via generic thermal framework.
> >> > 
> >> > +menu "Exynos thermal drivers"
> >> 
> >> would it be more proper to use "Samsung thermal drivers" or "Samsung
> >> Exynos thermal drivers" instead?
> > 
> > +1
> > 
> > Still, I wonder if it really makes sense to create a separate directory
> > and
> > submenu for this.
> 
> Yes separate directory was needed as the current TMU drivers supports
> many exynos SOC's with some differences in the controller itself. This
> has made it unmanageable and unclean and configuration data need to be
> separated from driver. With all these re-structuring, tmu support for
> exynos5440 is added very cleanly. Also many changes in this patchset
> are for making the driver multi-stance which is needed for 5440.

I fully understand the need to restructure this driver. I'm just thinking if 
there is really a reason to have a separate directory with its own Makefile and 
Kconfig just for six source files, which could be placed in drivers/thermal/ 
directly as well. I guess it's just a matter of preference, though.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Kernel and System Framework

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2013-05-07 13:36 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-26 10:37 [PATCH V2 0/20] thermal: exynos: Add thermal driver for exynos5440 Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 01/20] thermal: exynos: Moving exynos thermal files into samsung directory Amit Daniel Kachhap
2013-05-06 15:05   ` Zhang Rui
2013-05-07 10:21     ` Tomasz Figa
2013-05-07 13:18       ` amit daniel kachhap
2013-05-07 13:36         ` Tomasz Figa
2013-05-07 13:12     ` amit daniel kachhap
2013-04-26 10:37 ` [PATCH V2 02/20] thermal: exynos: Bifurcate exynos thermal common and tmu controller code Amit Daniel Kachhap
2013-05-06 15:16   ` Zhang Rui
2013-05-07 13:32     ` amit daniel kachhap
2013-04-26 10:37 ` [PATCH V2 03/20] thermal: exynos: Rename exynos_thermal.c to exynos_tmu.c Amit Daniel Kachhap
2013-05-06 15:18   ` Zhang Rui
2013-04-26 10:37 ` [PATCH V2 04/20] thermal: exynos: Move exynos_thermal.h from include/* to driver/* folder Amit Daniel Kachhap
2013-05-06 15:19   ` Zhang Rui
2013-04-26 10:37 ` [PATCH V2 05/20] thermal: exynos: Bifurcate exynos tmu driver and configuration data Amit Daniel Kachhap
2013-05-06 15:28   ` Zhang Rui
2013-04-26 10:37 ` [PATCH V2 06/20] thermal: exynos: Add missing definations and code cleanup Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 07/20] thermal: exynos: Add extra entries in the tmu platform data Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 08/20] thermal: exynos: Support thermal tripping Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 09/20] thermal: exynos: Move register definitions from driver file to data file Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 10/20] thermal: exynos: Fix to clear only the generated interrupts Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 11/20] thermal: exynos: Add support for instance based register/unregister Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 12/20] thermal: exynos: Modify private_data to appropriate name driver_data Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 13/20] thermal: exynos: Return success even if no cooling data supplied Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 14/20] thermal: exynos: Make the zone handling dependent on trip count Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 15/20] thermal: exynos: Add support to handle many instances of TMU Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 16/20] thermal: exynos: Add features to check instead of SOC type Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 17/20] ARM: dts: thermal: exynos4: Add documentation for Exynos SoC thermal bindings Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 18/20] thermal: exynos: Add support for exynos5440 TMU sensor Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 19/20] Documentation: thermal: Explain the exynos thermal driver model Amit Daniel Kachhap
2013-04-26 10:37 ` [PATCH V2 20/20] ARM: dts: Add device tree node for exynos5440 TMU controller Amit Daniel Kachhap

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).