Discussion:
[PATCH 00/21] thermal: exynos: Thermal code rework to use device tree
Lukasz Majewski
2014-10-09 16:38:36 UTC
Permalink
1. Introduction

Following patches aim to clean up the current implementation of the thermal
framework on Exynos devices.

The main goal was to use a generic code for reading thermal configuration
(of-thermal.c). Due to that redundant exynos_thermal_common.[h|c] files
were removed.

Around 400 lines of code (LOC) were removed directly by this patch, which
is around 20% of the Exynos thermal code base.

This work should NOT bring any functional changes to Exynos thermal
subsystem.

2. Patch-set structure

This series starts with extending current of-thermal.c implementation with
exporting information about trip points and support for setting emulated
temperature. Those changes were necessary to reuse this code in Exynos.

Then the cpu_cooling functionality has been preserved to allow cooling
devices by reducing operating frequency. Definition of trip points and
cpufreq's cooling properties were moved to device tree.

Then the rework of the way in which configuration data is provided to
the Exynos thermal subsystem was performed. Now device tree is used for
configuration.

Patch series end with removing exynos5250/exynos3250 TMU compatibles.
Both SoCs have thermal management unit (TMU) compatible with the one first
introduced at Exynos4412.

3. Dead code removal

Thermal support for some SoCs, previously available in the exynos_tmu_data.c
file, was removed since, as of 3.17-rc6, they didn't have TMU bindings.

Moreover, support for cpu_cooling devices was preserved only on those
SoCs which had available and working cpufreq driver.

4. Testing

Test devices:
- Exynos4210 - Trats (TMU zone + cpu_cooling)
- Exynos4412 - Trats2/Odroid U3 (TMU zone + cpu_cooling)
- Exynos5250 - Arndale (TMU zone + cpu_cooling)
- Exynos5420 - Arndale-octa (only TMU zones)

Unfortunately, I don't posses Exynos5440 for testing. Its functionality
has been preserved in the code, but not tested on the hardware. I would
be grateful for help in testing.

5. Prerequisites:

This work requires following patches developed by Bartlomiej Zolnierkiewicz:

5.1. [PATCH v3] ARM: dts: add CPU nodes for Exynos4 SoCs
http://article.gmane.org/gmane.linux.kernel.samsung-soc/37946/match=patch+v3+arm+dts+add+cpu+nodes+exynos4+socs

5.2. First thermal clean up patch set (from patch 1 to 33):

[PATCH 00/33] thermal: exynos: convert the driver to use per-SoC type operations
http://article.gmane.org/gmane.linux.kernel.samsung-soc/37642/match=patch+00+33+thermal+exynos+convert+driver+use+per+soc+type+operations


Lukasz Majewski (21):
thermal: of: Extend of-thermal.c to provide number of trip points
thermal: of: Extend of-thermal.c to provide check if trip point is
enabled
thermal: of: Extend of-thermal.c to provide number of non critical
trip points
thermal: of: Extend current of-thermal.c code to allow setting
emulated temp
thermal: exynos: cosmetic: Correct comment format
thermal: exynos: Provide thermal_exynos.h file to be included in
device tree files
thermal: dts: trats: Enable TMU on the Exynos4210 trats device
thermal: dts: exynos: Adding LD010 regulator node necessary for TMU on
Odroid U3 board
thermal: dts: Provide bindings and enable TMU at Exynos4x12 devices
thermal: cpu_cooling: dts: Define device tree bindings for Exynos cpu
cooling functionality
thermal: cpu_cooling: Modify exynos thermal code to use device tree
for cpu cooling configuration
thermal: exynos: dts: Add default definition for the TMU sensor
thermal: dts: Default trip points definition for Exynos5420 SoCs
thermal: exynos: dts: Define default thermal-zones for Exynos4
thermal: dts: exynos: Trip points and sensor configuration data for
Exynos5440
thermal: exynos: dts: Provide device tree bindings identical to one in
exynos_tmu_data.c
thermal: samsung: core: Exynos TMU rework to use device tree for
configuration
thermal: exynos: Remove exynos_thermal_common.[c|h] files
thermal: exynos: Remove exynos_tmu_data.c file
thermal: exynos: Make Exynos5250 TMU compatible with Exynos4412
thermal: exynos: Make Exynos3250 TMU compatible with Exynos4412

arch/arm/boot/dts/exynos4-cpu-thermal.dtsi | 52 +++
arch/arm/boot/dts/exynos4.dtsi | 5 +
arch/arm/boot/dts/exynos4210-trats.dts | 19 +
arch/arm/boot/dts/exynos4210.dtsi | 28 +-
arch/arm/boot/dts/exynos4212.dtsi | 5 +-
arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 27 ++
arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi | 24 ++
arch/arm/boot/dts/exynos4412.dtsi | 5 +-
arch/arm/boot/dts/exynos4x12.dtsi | 13 +
arch/arm/boot/dts/exynos5250.dtsi | 29 +-
arch/arm/boot/dts/exynos5420-trip-points.dtsi | 35 ++
arch/arm/boot/dts/exynos5420.dtsi | 33 ++
arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi | 25 ++
arch/arm/boot/dts/exynos5440-trip-points.dtsi | 25 ++
arch/arm/boot/dts/exynos5440.dtsi | 18 +
drivers/cpufreq/exynos-cpufreq.c | 23 +-
drivers/thermal/of-thermal.c | 52 ++-
drivers/thermal/samsung/Makefile | 2 -
drivers/thermal/samsung/exynos_thermal_common.c | 430 ----------------------
drivers/thermal/samsung/exynos_thermal_common.h | 106 ------
drivers/thermal/samsung/exynos_tmu.c | 283 +++++++-------
drivers/thermal/samsung/exynos_tmu.h | 79 +---
drivers/thermal/samsung/exynos_tmu_data.c | 264 -------------
drivers/thermal/thermal_core.h | 15 +
include/dt-bindings/thermal/thermal_exynos.h | 40 ++
include/linux/thermal.h | 6 +-
26 files changed, 623 insertions(+), 1020 deletions(-)
create mode 100644 arch/arm/boot/dts/exynos4-cpu-thermal.dtsi
create mode 100644 arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
create mode 100644 arch/arm/boot/dts/exynos5420-trip-points.dtsi
create mode 100644 arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi
create mode 100644 arch/arm/boot/dts/exynos5440-trip-points.dtsi
delete mode 100644 drivers/thermal/samsung/exynos_thermal_common.c
delete mode 100644 drivers/thermal/samsung/exynos_thermal_common.h
delete mode 100644 drivers/thermal/samsung/exynos_tmu_data.c
create mode 100644 include/dt-bindings/thermal/thermal_exynos.h
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:37 UTC
Permalink
This patch extends the of-thermal.c to provide information about number of
available trip points.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/thermal/of-thermal.c | 6 ++++++
drivers/thermal/thermal_core.h | 5 +++++
2 files changed, 11 insertions(+)

diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index f8eb625..b2390d9 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -113,6 +113,12 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz,
return data->get_temp(data->sensor_data, temp);
}

+int of_thermal_get_ntrips(struct thermal_zone_device *tz)
+{
+ struct __thermal_zone *data = tz->devdata;
+ return data->ntrips;
+}
+
static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
enum thermal_trend *trend)
{
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index 3db339f..587ca5c 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -81,9 +81,14 @@ static inline void thermal_gov_user_space_unregister(void) {}
#ifdef CONFIG_THERMAL_OF
int of_parse_thermal_zones(void);
void of_thermal_destroy_zones(void);
+int of_thermal_get_ntrips(struct thermal_zone_device *);
#else
static inline int of_parse_thermal_zones(void) { return 0; }
static inline void of_thermal_destroy_zones(void) { }
+static inline int of_thermal_get_ntrips(struct thermal_zone_device *)
+{
+ return 0;
+}
#endif

#endif /* __THERMAL_CORE_H__ */
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:38 UTC
Permalink
This patch extends the of-thermal.c to provide check if trip point is
enabled.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/thermal/of-thermal.c | 9 +++++++++
drivers/thermal/thermal_core.h | 5 +++++
2 files changed, 14 insertions(+)

diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index b2390d9..23c8d6c 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -119,6 +119,15 @@ int of_thermal_get_ntrips(struct thermal_zone_device *tz)
return data->ntrips;
}

+int of_thermal_is_trip_en(struct thermal_zone_device *tz, int trip)
+{
+ struct __thermal_zone *data = tz->devdata;
+
+ if (trip >= data->ntrips || trip < 0)
+ return 0;
+ return 1;
+}
+
static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
enum thermal_trend *trend)
{
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index 587ca5c..ed8ff05 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -82,6 +82,7 @@ static inline void thermal_gov_user_space_unregister(void) {}
int of_parse_thermal_zones(void);
void of_thermal_destroy_zones(void);
int of_thermal_get_ntrips(struct thermal_zone_device *);
+int of_thermal_is_trip_en(struct thermal_zone_device *, int);
#else
static inline int of_parse_thermal_zones(void) { return 0; }
static inline void of_thermal_destroy_zones(void) { }
@@ -89,6 +90,10 @@ static inline int of_thermal_get_ntrips(struct thermal_zone_device *)
{
return 0;
}
+int of_thermal_is_trip_en(struct thermal_zone_device *, int)
+{
+ return 0;
+}
#endif

#endif /* __THERMAL_CORE_H__ */
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:40 UTC
Permalink
Before this change it was only possible to set get_temp() and get_trend()
methods to be used in the common code handling passing parameters via
device tree to "cpu-thermal" CPU thermal zone device.

Now it is possible to also set emulated value of temperature for debug
purposes.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/thermal/of-thermal.c | 25 ++++++++++++++++++++++---
include/linux/thermal.h | 6 ++++--
2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index cd74e64..f206375 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -98,10 +98,22 @@ struct __thermal_zone {
void *sensor_data;
int (*get_temp)(void *, long *);
int (*get_trend)(void *, long *);
+ int (*set_emul_temp)(void *, unsigned long);
};

/*** DT thermal zone device callbacks ***/

+static int of_thermal_set_emul_temp(struct thermal_zone_device *tz,
+ unsigned long temp)
+{
+ struct __thermal_zone *data = tz->devdata;
+
+ if (!data->set_emul_temp)
+ return -EINVAL;
+
+ return data->set_emul_temp(data->sensor_data, temp);
+}
+
static int of_thermal_get_temp(struct thermal_zone_device *tz,
unsigned long *temp)
{
@@ -352,7 +364,8 @@ static struct thermal_zone_device *
thermal_zone_of_add_sensor(struct device_node *zone,
struct device_node *sensor, void *data,
int (*get_temp)(void *, long *),
- int (*get_trend)(void *, long *))
+ int (*get_trend)(void *, long *),
+ int (*set_emul_temp)(void *, unsigned long))
{
struct thermal_zone_device *tzd;
struct __thermal_zone *tz;
@@ -366,10 +379,12 @@ thermal_zone_of_add_sensor(struct device_node *zone,
mutex_lock(&tzd->lock);
tz->get_temp = get_temp;
tz->get_trend = get_trend;
+ tz->set_emul_temp = set_emul_temp;
tz->sensor_data = data;

tzd->ops->get_temp = of_thermal_get_temp;
tzd->ops->get_trend = of_thermal_get_trend;
+ tzd->ops->set_emul_temp = of_thermal_set_emul_temp;
mutex_unlock(&tzd->lock);

return tzd;
@@ -411,7 +426,8 @@ thermal_zone_of_add_sensor(struct device_node *zone,
struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int sensor_id,
void *data, int (*get_temp)(void *, long *),
- int (*get_trend)(void *, long *))
+ int (*get_trend)(void *, long *),
+ int (*set_emul_temp)(void *, unsigned long))
{
struct device_node *np, *child, *sensor_np;

@@ -453,7 +469,8 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id,
return thermal_zone_of_add_sensor(child, sensor_np,
data,
get_temp,
- get_trend);
+ get_trend,
+ set_emul_temp);
}
}
of_node_put(np);
@@ -494,9 +511,11 @@ void thermal_zone_of_sensor_unregister(struct device *dev,
mutex_lock(&tzd->lock);
tzd->ops->get_temp = NULL;
tzd->ops->get_trend = NULL;
+ tzd->ops->set_emul_temp = NULL;

tz->get_temp = NULL;
tz->get_trend = NULL;
+ tz->set_emul_temp = NULL;
tz->sensor_data = NULL;
mutex_unlock(&tzd->lock);
}
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 0305cde..36010e9 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -290,14 +290,16 @@ struct thermal_genl_event {
struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int id,
void *data, int (*get_temp)(void *, long *),
- int (*get_trend)(void *, long *));
+ int (*get_trend)(void *, long *),
+ int (*set_emul_temp)(void *, unsigned long));
void thermal_zone_of_sensor_unregister(struct device *dev,
struct thermal_zone_device *tz);
#else
static inline struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int id,
void *data, int (*get_temp)(void *, long *),
- int (*get_trend)(void *, long *))
+ int (*get_trend)(void *, long *),
+ int (*set_emul_temp)(void *, unsigned long))
{
return NULL;
}
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:39 UTC
Permalink
This patch extends the of-thermal.c to provide information about number of
available non critical (i.e. non HW) trip points in the system.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/thermal/of-thermal.c | 12 ++++++++++++
drivers/thermal/thermal_core.h | 5 +++++
2 files changed, 17 insertions(+)

diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index 23c8d6c..cd74e64 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -128,6 +128,18 @@ int of_thermal_is_trip_en(struct thermal_zone_device *tz, int trip)
return 1;
}

+int of_thermal_get_non_crit_ntrips(struct thermal_zone_device *tz)
+{
+ struct __thermal_zone *data = tz->devdata;
+ int i;
+
+ for (i = 0; i < data->ntrips; i++)
+ if (data->trips[i].type != THERMAL_TRIP_CRITICAL)
+ continue;
+
+ return --i;
+}
+
static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
enum thermal_trend *trend)
{
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index ed8ff05..334a7be 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -83,6 +83,7 @@ int of_parse_thermal_zones(void);
void of_thermal_destroy_zones(void);
int of_thermal_get_ntrips(struct thermal_zone_device *);
int of_thermal_is_trip_en(struct thermal_zone_device *, int);
+int of_thermal_get_non_crit_ntrips(struct thermal_zone_device *);
#else
static inline int of_parse_thermal_zones(void) { return 0; }
static inline void of_thermal_destroy_zones(void) { }
@@ -94,6 +95,10 @@ int of_thermal_is_trip_en(struct thermal_zone_device *, int)
{
return 0;
}
+int of_thermal_get_non_crit_ntrips(struct thermal_zone_device *)
+{
+ return 0;
+}
#endif

#endif /* __THERMAL_CORE_H__ */
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:41 UTC
Permalink
Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/thermal/samsung/exynos_tmu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 9e7f720..fa29b95 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -606,7 +606,7 @@ out:
#define exynos5440_tmu_set_emulation NULL
static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
{ return -EINVAL; }
-#endif/*CONFIG_THERMAL_EMULATION*/
+#endif /* CONFIG_THERMAL_EMULATION */

static int exynos4210_tmu_read(struct exynos_tmu_data *data)
{
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:42 UTC
Permalink
This patch is a preparatory patch for being able to read Exynos thermal
configuration from the device tree.

The DTC is not able to interpret enums properly and hence it is necessary
to #define those values explicitly.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/thermal/samsung/exynos_tmu.c | 2 +-
drivers/thermal/samsung/exynos_tmu.h | 23 +++-------------
include/dt-bindings/thermal/thermal_exynos.h | 40 ++++++++++++++++++++++++++++
3 files changed, 44 insertions(+), 21 deletions(-)
create mode 100644 include/dt-bindings/thermal/thermal_exynos.h

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index fa29b95..2f55daa 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -159,7 +159,7 @@ struct exynos_tmu_data {
void __iomem *base;
void __iomem *base_second;
int irq;
- enum soc_type soc;
+ int soc;
struct work_struct irq_work;
struct mutex lock;
struct clk *clk, *clk_sec;
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
index da3009b..a089391 100644
--- a/drivers/thermal/samsung/exynos_tmu.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -26,24 +26,7 @@

#include "exynos_thermal_common.h"

-enum calibration_type {
- TYPE_ONE_POINT_TRIMMING,
- TYPE_ONE_POINT_TRIMMING_25,
- TYPE_ONE_POINT_TRIMMING_85,
- TYPE_TWO_POINT_TRIMMING,
- TYPE_NONE,
-};
-
-enum soc_type {
- SOC_ARCH_EXYNOS3250 = 1,
- SOC_ARCH_EXYNOS4210,
- SOC_ARCH_EXYNOS4412,
- SOC_ARCH_EXYNOS5250,
- SOC_ARCH_EXYNOS5260,
- SOC_ARCH_EXYNOS5420,
- SOC_ARCH_EXYNOS5420_TRIMINFO,
- SOC_ARCH_EXYNOS5440,
-};
+#include <dt-bindings/thermal/thermal_exynos.h>

/**
* struct exynos_tmu_platform_data
@@ -115,8 +98,8 @@ struct exynos_tmu_platform_data {
u8 second_point_trim;
u8 default_temp_offset;

- enum calibration_type cal_type;
- enum soc_type type;
+ u32 cal_type;
+ u32 type;
struct freq_clip_table freq_tab[4];
unsigned int freq_tab_count;
};
diff --git a/include/dt-bindings/thermal/thermal_exynos.h b/include/dt-bindings/thermal/thermal_exynos.h
new file mode 100644
index 0000000..5d91d64
--- /dev/null
+++ b/include/dt-bindings/thermal/thermal_exynos.h
@@ -0,0 +1,40 @@
+/*
+ * thermal_exynos.h - Samsung EXYNOS TMU device tree definitions
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ * Lukasz Majewski <***@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 _EXYNOS_THERMAL_TMU_DT_H
+#define _EXYNOS_THERMAL_TMU_DT_H
+
+#define TYPE_ONE_POINT_TRIMMING 0
+#define TYPE_ONE_POINT_TRIMMING_25 1
+#define TYPE_ONE_POINT_TRIMMING_85 2
+#define TYPE_TWO_POINT_TRIMMING 3
+#define TYPE_NONE 4
+
+#define SOC_ARCH_EXYNOS3250 1
+#define SOC_ARCH_EXYNOS4210 2
+#define SOC_ARCH_EXYNOS4412 3
+#define SOC_ARCH_EXYNOS5250 4
+#define SOC_ARCH_EXYNOS5260 5
+#define SOC_ARCH_EXYNOS5420_TRIMINFO 6
+#define SOC_ARCH_EXYNOS5420 7
+#define SOC_ARCH_EXYNOS5440 8
+
+#endif /* _EXYNOS_THERMAL_TMU_DT_H */
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:43 UTC
Permalink
The thermal IP block (Thermal Management Unit) called TMU has been enabled
in this device.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
arch/arm/boot/dts/exynos4210-trats.dts | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index f516da9..b59019c 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -424,6 +424,10 @@
status = "okay";
};

+ ***@100C0000 {
+ status = "okay";
+ };
+
camera {
pinctrl-names = "default";
pinctrl-0 = <>;
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:44 UTC
Permalink
Signed-off-by: Lukasz Majewski <***@samsung.com>
---
arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index adadaf9..5364f1a 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -209,6 +209,13 @@
regulator-always-on;
};

+ ldo10_reg: LDO10 {
+ regulator-name = "VDD18_MIPIHSI_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
ldo11_reg: LDO11 {
regulator-name = "VDD18_ABB1_1.8V";
regulator-min-microvolt = <1800000>;
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:45 UTC
Permalink
This commit adds necessary bindings for enabling TMU IP block on the
Exynos4412 Odroid U3 device.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 5 +++++
arch/arm/boot/dts/exynos4x12.dtsi | 10 ++++++++++
2 files changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 5364f1a..5d4ecc3 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -374,6 +374,11 @@
ehci: ***@12580000 {
status = "okay";
};
+
+ ***@100C0000 {
+ vtmu-supply = <&ldo10_reg>;
+ status = "okay";
+ };
};

&pinctrl_1 {
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 861bb91..c12890c 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -271,4 +271,14 @@
compatible = "samsung,exynos4x12-usb2-phy";
samsung,sysreg-phandle = <&sys_reg>;
};
+
+ ***@100C0000 {
+ compatible = "samsung,exynos4412-tmu";
+ interrupt-parent = <&combiner>;
+ reg = <0x100C0000 0x100>;
+ interrupts = <2 4>;
+ clocks = <&clock 383>;
+ clock-names = "tmu_apbif";
+ status = "disabled";
+ };
};
--
2.0.0.rc2
Lukasz Majewski
2014-10-09 16:38:46 UTC
Permalink
Presented patch aims to move data necessary for correct CPU cooling device
configuration from exynos_tmu_data.c to device tree.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
arch/arm/boot/dts/exynos4210-trats.dts | 15 +++++++++++++++
arch/arm/boot/dts/exynos4210.dtsi | 5 ++++-
arch/arm/boot/dts/exynos4212.dtsi | 5 ++++-
arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 15 +++++++++++++++
arch/arm/boot/dts/exynos4412.dtsi | 5 ++++-
arch/arm/boot/dts/exynos5250.dtsi | 20 +++++++++++++++++++-
6 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index b59019c..d9dd9a7 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -428,6 +428,21 @@
status = "okay";
};

+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ cooling-maps {
+ map0 {
+ /* Corresponds to 800MHz at freq_table */
+ cooling-device = <&cpu0 2 2>;
+ };
+ map1 {
+ /* Corresponds to 200MHz at freq_table */
+ cooling-device = <&cpu0 4 4>;
+ };
+ };
+ };
+ };
+
camera {
pinctrl-names = "default";
pinctrl-0 = <>;
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 477d455..10e8915 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -45,10 +45,13 @@
#address-cells = <1>;
#size-cells = <0>;

- ***@0 {
+ cpu0: ***@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0x900>;
+ cooling-min-level = <4>;
+ cooling-max-level = <2>;
+ #cooling-cells = <2>; /* min followed by max */
};

***@1 {
diff --git a/arch/arm/boot/dts/exynos4212.dtsi b/arch/arm/boot/dts/exynos4212.dtsi
index 484a2da..6405954 100644
--- a/arch/arm/boot/dts/exynos4212.dtsi
+++ b/arch/arm/boot/dts/exynos4212.dtsi
@@ -26,10 +26,13 @@
#address-cells = <1>;
#size-cells = <0>;

- ***@0 {
+ cpu0: ***@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0xA00>;
+ cooling-min-level = <13>;
+ cooling-max-level = <7>;
+ #cooling-cells = <2>; /* min followed by max */
};

***@1 {
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 5d4ecc3..28e7a4c 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -379,6 +379,21 @@
vtmu-supply = <&ldo10_reg>;
status = "okay";
};
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ cooling-maps {
+ map0 {
+ /* Corresponds to 800MHz at freq_table */
+ cooling-device = <&cpu0 7 7>;
+ };
+ map1 {
+ /* Corresponds to 200MHz at freq_table */
+ cooling-device = <&cpu0 13 13>;
+ };
+ };
+ };
+ };
};

&pinctrl_1 {
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index 529fd13..9ed8925 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -26,10 +26,13 @@
#address-cells = <1>;
#size-cells = <0>;

- ***@0 {
+ cpu0: ***@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0xA00>;
+ cooling-min-level = <13>;
+ cooling-max-level = <7>;
+ #cooling-cells = <2>; /* min followed by max */
};

***@1 {
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 492e1ef..c322fb9 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -58,11 +58,14 @@
#address-cells = <1>;
#size-cells = <0>;

- ***@0 {
+ cpu0: ***@0 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0>;
clock-frequency = <1700000000>;
+ cooling-min-level = <15>;
+ cooling-max-level = <9>;
+ #cooling-cells = <2>; /* min followed by max */
};
***@1 {
device_type = "cpu";
@@ -241,6 +244,21 @@
clock-names = "tmu_apbif";
};

+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ cooling-maps {
+ map0 {
+ /* Corresponds to 800MHz at freq_table */
+ cooling-device = <&cpu0 9 9>;
+ };
+ map1 {
+ /* Corresponds to 200MHz at freq_table */
+ cooling-device = <&cpu0 15 15>;
+ };
+ };
+ };
+ };
+
***@12C00000 {
clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
clock-names = "uart", "clk_uart_baud0";
--
2.0.0.rc2
Lukasz Majewski
2014-10-09 16:38:47 UTC
Permalink
Up till now exynos_tmu_data.c was used for storing CPU cooling configuration
data. Now the Exynos thermal core code uses device tree to get this data.
For this purpose generic thermal code for configuring CPU cooling was
used.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/cpufreq/exynos-cpufreq.c | 23 ++++-
drivers/thermal/samsung/exynos_thermal_common.c | 122 ++++++++++++++----------
drivers/thermal/samsung/exynos_tmu.c | 7 --
drivers/thermal/samsung/exynos_tmu.h | 5 -
drivers/thermal/samsung/exynos_tmu_data.c | 42 +-------
5 files changed, 94 insertions(+), 105 deletions(-)

diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
index 1e0ec57..fdedb8d 100644
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -18,10 +18,13 @@
#include <linux/cpufreq.h>
#include <linux/platform_device.h>
#include <linux/of.h>
+#include <linux/cpu_cooling.h>
+#include <linux/cpu.h>

#include "exynos-cpufreq.h"

static struct exynos_dvfs_info *exynos_info;
+static struct thermal_cooling_device *cdev;
static struct regulator *arm_regulator;
static unsigned int locking_frequency;

@@ -156,6 +159,7 @@ static struct cpufreq_driver exynos_driver = {

static int exynos_cpufreq_probe(struct platform_device *pdev)
{
+ struct device_node *np;
int ret = -EINVAL;

exynos_info = kzalloc(sizeof(*exynos_info), GFP_KERNEL);
@@ -198,9 +202,24 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
/* Done here as we want to capture boot frequency */
locking_frequency = clk_get_rate(exynos_info->cpu_clk) / 1000;

- if (!cpufreq_register_driver(&exynos_driver))
- return 0;
+ if (cpufreq_register_driver(&exynos_driver))
+ goto err;

+ np = of_find_node_by_path("/cpus/***@0");
+ if (!np) {
+ pr_err("failed to find cpu0 node\n");
+ return -ENOENT;
+ }
+ if (of_find_property(np, "#cooling-cells", NULL)) {
+ cdev = of_cpufreq_cooling_register(np, cpu_present_mask);
+ if (IS_ERR(cdev))
+ pr_err("running cpufreq without cooling device: %ld\n",
+ PTR_ERR(cdev));
+ }
+ of_node_put(np);
+
+ return 0;
+ err:
dev_err(&pdev->dev, "failed to register cpufreq driver\n");
regulator_put(arm_regulator);
err_vdd_arm:
diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
index 3f5ad25..c306de5 100644
--- a/drivers/thermal/samsung/exynos_thermal_common.c
+++ b/drivers/thermal/samsung/exynos_thermal_common.c
@@ -133,47 +133,62 @@ static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
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 exynos_thermal_zone *th_zone = thermal->devdata;
struct thermal_sensor_conf *data = th_zone->sensor_conf;
+ struct device_node *child, *gchild, *np;
+ struct of_phandle_args cooling_spec;
+ unsigned long max, state = 0;
+ int ret = 0, i = 0;

- 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)
+ /*
+ * Below code is necessary to skip binding when cpufreq's
+ * frequency table is not yet initialized.
+ */
+ cdev->ops->get_max_state(cdev, &state);
+ if (!state && !th_zone->cool_dev_size) {
+ th_zone->cool_dev_size = 1;
+ th_zone->cool_dev[0] = cdev;
+ th_zone->bind = false;
return 0;
+ }

- /* find the cooling device registered*/
- for (i = 0; i < th_zone->cool_dev_size; i++)
- if (cdev == th_zone->cool_dev[i])
- break;
+ np = of_find_node_by_path("/thermal-zones/cpu-thermal");
+ if (!np) {
+ pr_err("failed to find thmerla-zones/cpu-thermal node\n");
+ return -ENOENT;
+ }

- /* No matching cooling device */
- if (i == th_zone->cool_dev_size)
- return 0;
+ child = of_get_child_by_name(np, "cooling-maps");

- /* 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)) {
- dev_err(data->dev,
- "error unbinding cdev inst=%d\n", i);
- ret = -EINVAL;
- }
- th_zone->bind = true;
- break;
- default:
+ for_each_child_of_node(child, gchild) {
+ ret = of_parse_phandle_with_args(gchild, "cooling-device",
+ "#cooling-cells",
+ 0, &cooling_spec);
+ if (ret < 0) {
+ pr_err("missing cooling_device property\n");
+ goto end;
+ }
+
+ if (cooling_spec.args_count < 2) {
ret = -EINVAL;
+ goto end;
}
+
+ max = cooling_spec.args[0];
+ if (thermal_zone_bind_cooling_device(thermal, i, cdev,
+ max, 0)) {
+ dev_err(data->dev,
+ "thermal error unbinding cdev inst=%d\n", i);
+
+ ret = -EINVAL;
+ goto end;
+ }
+ i++;
}
+ th_zone->bind = true;
+end:
+ of_node_put(child);
+ of_node_put(np);

return ret;
}
@@ -182,16 +197,12 @@ static int exynos_bind(struct thermal_zone_device *thermal,
static int exynos_unbind(struct thermal_zone_device *thermal,
struct thermal_cooling_device *cdev)
{
- int ret = 0, i, tab_size;
+ int ret = 0, i;
struct exynos_thermal_zone *th_zone = thermal->devdata;
struct thermal_sensor_conf *data = th_zone->sensor_conf;
+ struct device_node *child, *gchild, *np;

- if (th_zone->bind == false)
- return 0;
-
- tab_size = data->cooling_data.freq_clip_count;
-
- if (tab_size == 0)
+ if (th_zone->bind == false || !th_zone->cool_dev_size)
return 0;

/* find the cooling device registered*/
@@ -203,23 +214,30 @@ static int exynos_unbind(struct thermal_zone_device *thermal,
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)) {
- dev_err(data->dev,
- "error unbinding cdev inst=%d\n", i);
- ret = -EINVAL;
- }
- th_zone->bind = false;
- break;
- default:
+ np = of_find_node_by_path("/thermal-zones/cpu-thermal");
+ if (!np) {
+ pr_err("failed to find thmerla-zones/cpu-thermal node\n");
+ return -ENOENT;
+ }
+
+ child = of_get_child_by_name(np, "cooling-maps");
+
+ i = 0;
+ for_each_child_of_node(child, gchild) {
+ if (thermal_zone_unbind_cooling_device(thermal, i,
+ cdev)) {
+ dev_err(data->dev,
+ "error unbinding cdev inst=%d\n", i);
ret = -EINVAL;
+ goto end;
}
+ i++;
}
+ th_zone->bind = false;
+end:
+ of_node_put(child);
+ of_node_put(np);
+
return ret;
}

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 2f55daa..1d6b1cb 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -937,13 +937,6 @@ static int exynos_tmu_probe(struct platform_device *pdev)

sensor_conf->trip_data.trigger_falling = pdata->threshold_falling;

- sensor_conf->cooling_data.freq_clip_count = pdata->freq_tab_count;
- for (i = 0; i < pdata->freq_tab_count; i++) {
- sensor_conf->cooling_data.freq_data[i].freq_clip_max =
- pdata->freq_tab[i].freq_clip_max;
- sensor_conf->cooling_data.freq_data[i].temp_level =
- pdata->freq_tab[i].temp_level;
- }
sensor_conf->dev = &pdev->dev;
/* Register the sensor with thermal management interface */
ret = exynos_register_thermal(sensor_conf);
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
index a089391..1e87f0f 100644
--- a/drivers/thermal/samsung/exynos_tmu.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -73,9 +73,6 @@
* @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
- * @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.
*
* This structure is required for configuration of exynos_tmu driver.
*/
@@ -100,8 +97,6 @@ struct exynos_tmu_platform_data {

u32 cal_type;
u32 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 b239100..a993f3d 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.c
+++ b/drivers/thermal/samsung/exynos_tmu_data.c
@@ -47,15 +47,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
.first_point_trim = 25,
.second_point_trim = 85,
.default_temp_offset = 50,
- .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,
},
},
@@ -87,16 +78,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
.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 = 70, \
- }, \
- .freq_tab[1] = { \
- .freq_clip_max = 400 * 1000, \
- .temp_level = 95, \
- }, \
- .freq_tab_count = 2
+ .default_temp_offset = 50

struct exynos_tmu_init_data const exynos3250_default_tmu_data = {
.tmu_data = {
@@ -133,16 +115,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = {
.max_efuse_value = 100, \
.first_point_trim = 25, \
.second_point_trim = 85, \
- .default_temp_offset = 50, \
- .freq_tab[0] = { \
- .freq_clip_max = 1400 * 1000, \
- .temp_level = 70, \
- }, \
- .freq_tab[1] = { \
- .freq_clip_max = 400 * 1000, \
- .temp_level = 95, \
- }, \
- .freq_tab_count = 2
+ .default_temp_offset = 50

struct exynos_tmu_init_data const exynos4412_default_tmu_data = {
.tmu_data = {
@@ -189,16 +162,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = {
.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, \
- }, \
- .freq_tab[1] = { \
- .freq_clip_max = 200 * 1000, \
- .temp_level = 103, \
- }, \
- .freq_tab_count = 2, \
+ .default_temp_offset = 50,

#define EXYNOS5260_TMU_DATA \
__EXYNOS5260_TMU_DATA \
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:49 UTC
Permalink
This code groups in one place default settings of trip points. It is used
in SoCs with multiple instances of TMU sensor.

Separate device tree file prevents from multiple copying of the same data.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
arch/arm/boot/dts/exynos5420-trip-points.dtsi | 35 +++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 arch/arm/boot/dts/exynos5420-trip-points.dtsi

diff --git a/arch/arm/boot/dts/exynos5420-trip-points.dtsi b/arch/arm/boot/dts/exynos5420-trip-points.dtsi
new file mode 100644
index 0000000..09d6c56
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-trip-points.dtsi
@@ -0,0 +1,35 @@
+/*
+ * Device tree sources for default Exynos 5420 thermal zone definition
+ *
+ * Copyright (c) 2014 Lukasz Majewski <***@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+polling-delay-passive = <0>;
+polling-delay = <0>;
+trips {
+ cpu-alert-0 {
+ temperature = <85000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu-alert-1 {
+ temperature = <103000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu-alert-2 {
+ temperature = <110000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu-crit-0 {
+ temperature = <1200000>; /* millicelsius */
+ hysteresis = <0>; /* millicelsius */
+ type = "critical";
+ };
+};
--
2.0.0.rc2
Lukasz Majewski
2014-10-09 16:38:52 UTC
Permalink
Presented device tree bindings provide data already hardcoded in the
exynos_tmu_data.c file.
After this commit, it should be possible to reuse common thermal core
framework in Exynos SoCs.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
arch/arm/boot/dts/exynos4.dtsi | 5 +++++
arch/arm/boot/dts/exynos4210.dtsi | 23 ++++++++++++++++++++++-
arch/arm/boot/dts/exynos4x12.dtsi | 3 +++
arch/arm/boot/dts/exynos5250.dtsi | 7 +++++--
arch/arm/boot/dts/exynos5420.dtsi | 33 +++++++++++++++++++++++++++++++++
arch/arm/boot/dts/exynos5440.dtsi | 18 ++++++++++++++++++
6 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index e0278ec..1735bb3 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -21,6 +21,7 @@

#include <dt-bindings/clock/exynos4.h>
#include <dt-bindings/clock/exynos-audss-clk.h>
+#include <dt-bindings/thermal/thermal_exynos.h>
#include "skeleton.dtsi"

/ {
@@ -645,4 +646,8 @@
samsung,sysreg = <&sys_reg>;
status = "disabled";
};
+
+ tmu: ***@100C0000 {
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ };
};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 10e8915..1c52681 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -21,6 +21,8 @@

#include "exynos4.dtsi"
#include "exynos4210-pinctrl.dtsi"
+#include "exynos4-cpu-thermal.dtsi"
+#include <dt-bindings/thermal/thermal_exynos.h>

/ {
compatible = "samsung,exynos4210", "samsung,exynos4";
@@ -146,16 +148,35 @@
reg = <0x03860000 0x1000>;
};

- ***@100C0000 {
+ tmu: ***@100C0000 {
compatible = "samsung,exynos4210-tmu";
interrupt-parent = <&combiner>;
reg = <0x100C0000 0x100>;
interrupts = <2 4>;
clocks = <&clock CLK_TMU_APBIF>;
clock-names = "tmu_apbif";
+ gain = <15>;
+ reference_voltage = <7>;
+ type = <SOC_ARCH_EXYNOS4210>;
status = "disabled";
};

+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ trips {
+ cpu_alert0: cpu-alert-0 {
+ temperature = <85000>; /* millicelsius */
+ };
+ cpu_alert1: cpu-alert-1 {
+ temperature = <100000>; /* millicelsius */
+ };
+ cpu_alert2: cpu-alert-2 {
+ temperature = <110000>; /* millicelsius */
+ };
+ };
+ };
+ };
+
***@12800000 {
compatible = "samsung,s5pv210-g2d";
reg = <0x12800000 0x1000>;
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index c12890c..a7dda7e 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -19,6 +19,8 @@

#include "exynos4.dtsi"
#include "exynos4x12-pinctrl.dtsi"
+#include "exynos4-cpu-thermal.dtsi"
+#include <dt-bindings/thermal/thermal_exynos.h>

/ {
aliases {
@@ -279,6 +281,7 @@
interrupts = <2 4>;
clocks = <&clock 383>;
clock-names = "tmu_apbif";
+ type = <SOC_ARCH_EXYNOS4412>;
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index c322fb9..e71ec78 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -20,8 +20,9 @@
#include <dt-bindings/clock/exynos5250.h>
#include "exynos5.dtsi"
#include "exynos5250-pinctrl.dtsi"
-
+#include "exynos4-cpu-thermal.dtsi"
#include <dt-bindings/clock/exynos-audss-clk.h>
+#include <dt-bindings/thermal/thermal_exynos.h>

/ {
compatible = "samsung,exynos5250", "samsung,exynos5";
@@ -236,12 +237,14 @@
status = "disabled";
};

- ***@10060000 {
+ tmu: ***@10060000 {
compatible = "samsung,exynos5250-tmu";
reg = <0x10060000 0x100>;
interrupts = <0 65 0>;
clocks = <&clock CLK_TMU>;
clock-names = "tmu_apbif";
+ type = <SOC_ARCH_EXYNOS5250>;
+ #include "exynos4412-tmu-sensor-conf.dtsi"
};

thermal-zones {
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index bfe056d..4bebc6f 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -756,6 +756,8 @@
interrupts = <0 65 0>;
clocks = <&clock CLK_TMU>;
clock-names = "tmu_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ type = <SOC_ARCH_EXYNOS5420>;
};

tmu_cpu1: ***@10064000 {
@@ -764,6 +766,8 @@
interrupts = <0 183 0>;
clocks = <&clock CLK_TMU>;
clock-names = "tmu_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ type = <SOC_ARCH_EXYNOS5420>;
};

tmu_cpu2: ***@10068000 {
@@ -772,6 +776,8 @@
interrupts = <0 184 0>;
clocks = <&clock CLK_TMU>, <&clock CLK_TMU>;
clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ type = <SOC_ARCH_EXYNOS5420_TRIMINFO>;
};

tmu_cpu3: ***@1006c000 {
@@ -780,6 +786,8 @@
interrupts = <0 185 0>;
clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>;
clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ type = <SOC_ARCH_EXYNOS5420_TRIMINFO>;
};

tmu_gpu: ***@100a0000 {
@@ -788,6 +796,31 @@
interrupts = <0 215 0>;
clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>;
clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+ #include "exynos4412-tmu-sensor-conf.dtsi"
+ type = <SOC_ARCH_EXYNOS5420_TRIMINFO>;
+ };
+
+ thermal-zones {
+ cpu0_thermal: cpu0-thermal {
+ thermal-sensors = <&tmu_cpu0>;
+ #include "exynos5420-trip-points.dtsi"
+ };
+ cpu1_thermal: cpu1-thermal {
+ thermal-sensors = <&tmu_cpu1>;
+ #include "exynos5420-trip-points.dtsi"
+ };
+ cpu2_thermal: cpu2-thermal {
+ thermal-sensors = <&tmu_cpu2>;
+ #include "exynos5420-trip-points.dtsi"
+ };
+ cpu3_thermal: cpu3-thermal {
+ thermal-sensors = <&tmu_cpu3>;
+ #include "exynos5420-trip-points.dtsi"
+ };
+ gpu_thermal: gpu-thermal {
+ thermal-sensors = <&tmu_gpu>;
+ #include "exynos5420-trip-points.dtsi"
+ };
};

watchdog: ***@101D0000 {
diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi
index 8f3373c..59d9416 100644
--- a/arch/arm/boot/dts/exynos5440.dtsi
+++ b/arch/arm/boot/dts/exynos5440.dtsi
@@ -219,6 +219,7 @@
interrupts = <0 58 0>;
clocks = <&clock CLK_B_125>;
clock-names = "tmu_apbif";
+ #include "exynos5440-tmu-sensor-conf.dtsi"
};

tmuctrl_1: ***@16011C {
@@ -227,6 +228,7 @@
interrupts = <0 58 0>;
clocks = <&clock CLK_B_125>;
clock-names = "tmu_apbif";
+ #include "exynos5440-tmu-sensor-conf.dtsi"
};

tmuctrl_2: ***@160120 {
@@ -235,6 +237,22 @@
interrupts = <0 58 0>;
clocks = <&clock CLK_B_125>;
clock-names = "tmu_apbif";
+ #include "exynos5440-tmu-sensor-conf.dtsi"
+ };
+
+ thermal-zones {
+ cpu0_thermal: cpu0-thermal {
+ thermal-sensors = <&tmuctrl_0>;
+ #include "exynos5440-trip-points.dtsi"
+ };
+ cpu1_thermal: cpu1-thermal {
+ thermal-sensors = <&tmuctrl_1>;
+ #include "exynos5440-trip-points.dtsi"
+ };
+ cpu2_thermal: cpu2-thermal {
+ thermal-sensors = <&tmuctrl_2>;
+ #include "exynos5440-trip-points.dtsi"
+ };
};

***@210000 {
--
2.0.0.rc2
Lukasz Majewski
2014-10-09 16:38:48 UTC
Permalink
Exynos 4 and 5 family of SoCs uses almost identical TMU sensor to measure the
on chip temperature. Hence it is possible to group TMU configuration parameters
in one dts include file.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi | 24 +++++++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi

diff --git a/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
new file mode 100644
index 0000000..ee6d8bb
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
@@ -0,0 +1,24 @@
+/*
+ * Device tree sources for Exynos4412 TMU sensor configuration
+ *
+ * Copyright (c) 2014 Lukasz Majewski <***@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/thermal/thermal_exynos.h>
+
+#thermal-sensor-cells = <0>;
+gain = <8>;
+reference_voltage = <16>;
+noise_cancel_mode = <4>;
+efuse_value = <55>;
+min_efuse_value = <40>;
+max_efuse_value = <100>;
+first_point_trim = <25>;
+second_point_trim = <85>;
+default_temp_offset = <50>;
+cal_type = <TYPE_ONE_POINT_TRIMMING>;
--
2.0.0.rc2
Lukasz Majewski
2014-10-09 16:38:50 UTC
Permalink
Trip points corresponding to the one defined in the exynos_tmu_data.c
for Exynos4 have been included.
This thermal-zones attribute is afterwards reused for Exynos4210, Exynos4412
and Exynos5250.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
arch/arm/boot/dts/exynos4-cpu-thermal.dtsi | 52 ++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 arch/arm/boot/dts/exynos4-cpu-thermal.dtsi

diff --git a/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi b/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi
new file mode 100644
index 0000000..506600a
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi
@@ -0,0 +1,52 @@
+/*
+ * Device tree sources for Exynos4 thermal zone
+ *
+ * Copyright (c) 2014 Lukasz Majewski <***@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ thermal-sensors = <&tmu 0>;
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ trips {
+ cpu_alert0: cpu-alert-0 {
+ temperature = <70000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu_alert1: cpu-alert-1 {
+ temperature = <95000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu_alert2: cpu-alert-2 {
+ temperature = <110000>; /* millicelsius */
+ hysteresis = <10000>; /* millicelsius */
+ type = "active";
+ };
+ cpu_crit0: cpu-crit-0 {
+ temperature = <120000>; /* millicelsius */
+ hysteresis = <0>; /* millicelsius */
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ };
+ map1 {
+ trip = <&cpu_alert1>;
+ };
+ };
+ };
+ };
+};
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:51 UTC
Permalink
This commit provides information about Exynos5440 device configuration.
Previously this information was available in exynos_tmu_data.c file.
Now it is available in the device tree.
Such approach allows reusing some common code for thermal.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi | 25 +++++++++++++++++++++++
arch/arm/boot/dts/exynos5440-trip-points.dtsi | 25 +++++++++++++++++++++++
2 files changed, 50 insertions(+)
create mode 100644 arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi
create mode 100644 arch/arm/boot/dts/exynos5440-trip-points.dtsi

diff --git a/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi
new file mode 100644
index 0000000..336cb12
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi
@@ -0,0 +1,25 @@
+/*
+ * Device tree sources for Exynos5440 TMU sensor configuration
+ *
+ * Copyright (c) 2014 Lukasz Majewski <***@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/thermal/thermal_exynos.h>
+
+#thermal-sensor-cells = <0>;
+gain = <5>;
+reference_voltage = <16>;
+noise_cancel_mode = <4>;
+efuse_value = <0x5d2d>;
+min_efuse_value = <16>;
+max_efuse_value = <76>;
+first_point_trim = <25>;
+second_point_trim = <70>;
+default_temp_offset = <25>;
+cal_type = <TYPE_ONE_POINT_TRIMMING>;
+type = <SOC_ARCH_EXYNOS5440>;
diff --git a/arch/arm/boot/dts/exynos5440-trip-points.dtsi b/arch/arm/boot/dts/exynos5440-trip-points.dtsi
new file mode 100644
index 0000000..48adfa8
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5440-trip-points.dtsi
@@ -0,0 +1,25 @@
+/*
+ * Device tree sources for default Exynos5440 thermal zone definition
+ *
+ * Copyright (c) 2014 Lukasz Majewski <***@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+polling-delay-passive = <0>;
+polling-delay = <0>;
+trips {
+ cpu-alert-0 {
+ temperature = <100000>; /* millicelsius */
+ hysteresis = <0>; /* millicelsius */
+ type = "active";
+ };
+ cpu-crit-0 {
+ temperature = <1050000>; /* millicelsius */
+ hysteresis = <0>; /* millicelsius */
+ type = "critical";
+ };
+};
--
2.0.0.rc2
Lukasz Majewski
2014-10-09 16:38:53 UTC
Permalink
This patch brings support for providing configuration via device tree.
Previously, data hardcoded in the exynos_tmu_data.c file was used, which is
not scalable and error prone.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/thermal/samsung/Makefile | 2 -
drivers/thermal/samsung/exynos_tmu.c | 266 ++++++++++++++++++++---------------
drivers/thermal/samsung/exynos_tmu.h | 51 -------
3 files changed, 154 insertions(+), 165 deletions(-)

diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
index c09d830..1e47d0d 100644
--- a/drivers/thermal/samsung/Makefile
+++ b/drivers/thermal/samsung/Makefile
@@ -3,5 +3,3 @@
#
obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o
exynos_thermal-y := exynos_tmu.o
-exynos_thermal-y += exynos_tmu_data.o
-exynos_thermal-$(CONFIG_EXYNOS_THERMAL_CORE) += exynos_thermal_common.o
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 1d6b1cb..e26042a 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -1,6 +1,10 @@
/*
* exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit)
*
+ * Copyright (C) 2014 Samsung Electronics
+ * Bartlomiej Zolnierkiewicz <***@samsung.com>
+ * Lukasz Majewski <***@samsung.com>
+ *
* Copyright (C) 2011 Samsung Electronics
* Donggeun Kim <***@samsung.com>
* Amit Daniel Kachhap <***@linaro.org>
@@ -31,8 +35,8 @@
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>

-#include "exynos_thermal_common.h"
#include "exynos_tmu.h"
+#include "../thermal_core.h"

/* Exynos generic registers */
#define EXYNOS_TMU_REG_TRIMINFO 0x0
@@ -130,6 +134,7 @@
#define EXYNOS5440_TMU_TH_RISE4_SHIFT 24
#define EXYNOS5440_EFUSE_SWAP_OFFSET 8

+#define MCELSIUS 1000
/**
* struct exynos_tmu_data : A structure to hold the private data of the TMU
driver
@@ -165,7 +170,8 @@ struct exynos_tmu_data {
struct clk *clk, *clk_sec;
u8 temp_error1, temp_error2;
struct regulator *regulator;
- struct thermal_sensor_conf *reg_conf;
+ struct thermal_zone_device *tzd;
+
int (*tmu_initialize)(struct platform_device *pdev);
void (*tmu_control)(struct platform_device *pdev, bool on);
int (*tmu_read)(struct exynos_tmu_data *data);
@@ -174,6 +180,33 @@ struct exynos_tmu_data {
void (*tmu_clear_irqs)(struct exynos_tmu_data *data);
};

+static void exynos_report_trigger(struct exynos_tmu_data *p)
+{
+ char data[10], *envp[] = { data, NULL };
+ struct thermal_zone_device *tz = p->tzd;
+ unsigned long temp;
+ unsigned int i;
+
+ if (!p) {
+ pr_err("Wrong temperature configuration data\n");
+ return;
+ }
+
+ thermal_zone_device_update(tz);
+
+ mutex_lock(&tz->lock);
+ /* Find the level for which trip happened */
+ for (i = 0; i < of_thermal_get_ntrips(tz); i++) {
+ tz->ops->get_trip_temp(tz, i, &temp);
+ if (tz->last_temperature < temp)
+ break;
+ }
+
+ snprintf(data, sizeof(data), "%u", i);
+ kobject_uevent_env(&tz->device.kobj, KOBJ_CHANGE, envp);
+ mutex_unlock(&tz->lock);
+}
+
/*
* TMU treats temperature as a mapped temperature code.
* The temperature is converted differently depending on the calibration type.
@@ -249,16 +282,22 @@ static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)

static u32 get_th_reg(struct exynos_tmu_data *data, u32 threshold, bool falling)
{
- struct exynos_tmu_platform_data *pdata = data->pdata;
- int i;
+ struct thermal_zone_device *tz = data->tzd;
+ unsigned long temp, temp_hist;
+ int i, ret;

- for (i = 0; i < pdata->non_hw_trigger_levels; i++) {
- u8 temp = pdata->trigger_levels[i];
+ for (i = 0; i < of_thermal_get_non_crit_ntrips(tz); i++) {
+ ret = tz->ops->get_trip_temp(tz, i, &temp);
+ if (ret)
+ return 0;

- if (falling)
- temp -= pdata->threshold_falling;
- else
+ temp /= MCELSIUS;
+ if (falling) {
+ tz->ops->get_trip_hyst(tz, i, &temp_hist);
+ temp -= (temp_hist / MCELSIUS);
+ } else {
threshold &= ~(0xff << 8 * i);
+ }

threshold |= temp_to_code(data, temp) << 8 * i;
}
@@ -320,9 +359,10 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
static int exynos4210_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;
+ struct thermal_zone_device *tz = data->tzd;
int ret = 0, threshold_code, i;
+ unsigned long reference, temp;
+ unsigned int status;

status = readb(data->base + EXYNOS_TMU_REG_STATUS);
if (!status) {
@@ -333,12 +373,21 @@ static int exynos4210_tmu_initialize(struct platform_device *pdev)
sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO));

/* Write temperature code for threshold */
- threshold_code = temp_to_code(data, pdata->threshold);
+ tz->ops->get_trip_temp(tz, 0, &reference);
+ reference /= MCELSIUS;
+ threshold_code = temp_to_code(data, reference);
+ if (threshold_code < 0) {
+ ret = threshold_code;
+ goto out;
+ }
writeb(threshold_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);

- for (i = 0; i < pdata->non_hw_trigger_levels; i++)
- writeb(pdata->trigger_levels[i], data->base +
+ for (i = 0; i < of_thermal_get_non_crit_ntrips(tz); i++) {
+ tz->ops->get_trip_temp(tz, i, &temp);
+ temp /= MCELSIUS;
+ writeb(temp - reference, data->base +
EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
+ }

writel(EXYNOS4210_TMU_TRIG_LEVEL_MASK,
data->base + EXYNOS_TMU_REG_INTCLEAR);
@@ -349,9 +398,9 @@ out:
static int exynos4412_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, con, ctrl, rising_threshold;
int ret = 0, threshold_code, i;
+ unsigned long crit_temp = 0;

status = readb(data->base + EXYNOS_TMU_REG_STATUS);
if (!status) {
@@ -401,9 +450,9 @@ static int exynos4412_tmu_initialize(struct platform_device *pdev)
data->base + EXYNOS_TMU_REG_INTCLEAR);

/* if last threshold limit is also present */
- i = pdata->max_trigger_level - 1;
- if (pdata->trigger_levels[i] && pdata->trigger_type[i] == HW_TRIP) {
- threshold_code = temp_to_code(data, pdata->trigger_levels[i]);
+ i = of_thermal_get_non_crit_ntrips(data->tzd);
+ if (!data->tzd->ops->get_crit_temp(data->tzd, &crit_temp)) {
+ threshold_code = temp_to_code(data, crit_temp / MCELSIUS);
/* 1-4 level to be assigned in th0 reg */
rising_threshold &= ~(0xff << 8 * i);
rising_threshold |= threshold_code << 8 * i;
@@ -419,9 +468,9 @@ out:
static int exynos5440_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 trim_info = 0, con, rising_threshold;
- int ret = 0, threshold_code, i;
+ int ret = 0, threshold_code;
+ unsigned long crit_temp = 0;

/*
* For exynos5440 soc triminfo value is swapped between TMU0 and
@@ -452,9 +501,8 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev)
data->base + EXYNOS5440_TMU_S0_7_IRQ);

/* if last threshold limit is also present */
- i = pdata->max_trigger_level - 1;
- if (pdata->trigger_levels[i] && pdata->trigger_type[i] == HW_TRIP) {
- threshold_code = temp_to_code(data, pdata->trigger_levels[i]);
+ if (!data->tzd->ops->get_crit_temp(data->tzd, &crit_temp)) {
+ threshold_code = temp_to_code(data, crit_temp / MCELSIUS);
/* 5th level to be assigned in th2 reg */
rising_threshold =
threshold_code << EXYNOS5440_TMU_TH_RISE4_SHIFT;
@@ -472,7 +520,7 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev)
static void exynos4210_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 thermal_zone_device *tz = data->tzd;
unsigned int con, interrupt_en;

con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
@@ -480,10 +528,11 @@ static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
if (on) {
con |= (1 << EXYNOS_TMU_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;
+ of_thermal_is_trip_en(tz, 3) << EXYNOS_TMU_INTEN_RISE3_SHIFT |
+ of_thermal_is_trip_en(tz, 2) << EXYNOS_TMU_INTEN_RISE2_SHIFT |
+ of_thermal_is_trip_en(tz, 1) << EXYNOS_TMU_INTEN_RISE1_SHIFT |
+ of_thermal_is_trip_en(tz, 0) << EXYNOS_TMU_INTEN_RISE0_SHIFT;
+
if (data->soc != SOC_ARCH_EXYNOS4210)
interrupt_en |=
interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
@@ -498,7 +547,7 @@ static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
static void exynos5440_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 thermal_zone_device *tz = data->tzd;
unsigned int con, interrupt_en;

con = get_con_reg(data, readl(data->base + EXYNOS5440_TMU_S0_7_CTRL));
@@ -506,10 +555,10 @@ static void exynos5440_tmu_control(struct platform_device *pdev, bool on)
if (on) {
con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
interrupt_en =
- pdata->trigger_enable[3] << EXYNOS5440_TMU_INTEN_RISE3_SHIFT |
- pdata->trigger_enable[2] << EXYNOS5440_TMU_INTEN_RISE2_SHIFT |
- pdata->trigger_enable[1] << EXYNOS5440_TMU_INTEN_RISE1_SHIFT |
- pdata->trigger_enable[0] << EXYNOS5440_TMU_INTEN_RISE0_SHIFT;
+ of_thermal_is_trip_en(tz, 3) << EXYNOS5440_TMU_INTEN_RISE3_SHIFT |
+ of_thermal_is_trip_en(tz, 2) << EXYNOS5440_TMU_INTEN_RISE2_SHIFT |
+ of_thermal_is_trip_en(tz, 1) << EXYNOS5440_TMU_INTEN_RISE1_SHIFT |
+ of_thermal_is_trip_en(tz, 0) << EXYNOS5440_TMU_INTEN_RISE0_SHIFT;
interrupt_en |= interrupt_en << EXYNOS5440_TMU_INTEN_FALL0_SHIFT;
} else {
con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
@@ -519,19 +568,21 @@ static void exynos5440_tmu_control(struct platform_device *pdev, bool on)
writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL);
}

-static int exynos_tmu_read(struct exynos_tmu_data *data)
+int exynos_get_temp(void *p, long *temp)
{
- int ret;
+ struct exynos_tmu_data *data = p;
+ if (!data)
+ return -EINVAL;

mutex_lock(&data->lock);
clk_enable(data->clk);
- ret = data->tmu_read(data);
- if (ret >= 0)
- ret = code_to_temp(data, ret);
+
+ *temp = code_to_temp(data, data->tmu_read(data)) * MCELSIUS;
+
clk_disable(data->clk);
mutex_unlock(&data->lock);

- return ret;
+ return 0;
}

#ifdef CONFIG_THERMAL_EMULATION
@@ -643,7 +694,7 @@ static void exynos_tmu_work(struct work_struct *work)
if (!IS_ERR(data->clk_sec))
clk_disable(data->clk_sec);

- exynos_report_trigger(data->reg_conf);
+ exynos_report_trigger(data);
mutex_lock(&data->lock);
clk_enable(data->clk);
/* TODO: take action based on particular interrupt */
@@ -694,55 +745,63 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id)
static const struct of_device_id exynos_tmu_match[] = {
{
.compatible = "samsung,exynos3250-tmu",
- .data = &exynos3250_default_tmu_data,
},
{
.compatible = "samsung,exynos4210-tmu",
- .data = &exynos4210_default_tmu_data,
},
{
.compatible = "samsung,exynos4412-tmu",
- .data = &exynos4412_default_tmu_data,
},
{
.compatible = "samsung,exynos5250-tmu",
- .data = &exynos5250_default_tmu_data,
},
{
.compatible = "samsung,exynos5260-tmu",
- .data = &exynos5260_default_tmu_data,
},
{
.compatible = "samsung,exynos5420-tmu",
- .data = &exynos5420_default_tmu_data,
},
{
.compatible = "samsung,exynos5420-tmu-ext-triminfo",
- .data = &exynos5420_default_tmu_data,
},
{
.compatible = "samsung,exynos5440-tmu",
- .data = &exynos5440_default_tmu_data,
},
{},
};
MODULE_DEVICE_TABLE(of, exynos_tmu_match);

-static inline struct exynos_tmu_platform_data *exynos_get_driver_data(
- struct platform_device *pdev, int id)
+static int exynos_of_sensor_conf(struct device_node *np,
+ struct exynos_tmu_platform_data *pdata)
{
- struct exynos_tmu_init_data *data_table;
- struct exynos_tmu_platform_data *tmu_data;
- const struct of_device_id *match;
-
- match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
- if (!match)
- return NULL;
- data_table = (struct exynos_tmu_init_data *) match->data;
- if (!data_table || id >= data_table->tmu_count)
- return NULL;
- tmu_data = data_table->tmu_data;
- return (struct exynos_tmu_platform_data *) (tmu_data + id);
+ u32 value;
+ int ret;
+
+ of_node_get(np);
+
+ ret = of_property_read_u32(np, "gain", &value);
+ pdata->gain = (u8) value;
+ of_property_read_u32(np, "reference_voltage", &value);
+ pdata->reference_voltage = (u8) value;
+ of_property_read_u32(np, "noise_cancel_mode", &value);
+ pdata->noise_cancel_mode = (u8) value;;
+
+ of_property_read_u32(np, "efuse_value", &pdata->efuse_value);
+ of_property_read_u32(np, "min_efuse_value", &pdata->min_efuse_value);
+ of_property_read_u32(np, "max_efuse_value", &pdata->max_efuse_value);
+
+ of_property_read_u32(np, "first_point_trim", &value);
+ pdata->first_point_trim = (u8) value;
+ of_property_read_u32(np, "second_point_trim", &value);
+ pdata->second_point_trim = (u8) value;
+ of_property_read_u32(np, "default_temp_offset", &value);
+ pdata->default_temp_offset = (u8) value;
+
+ of_property_read_u32(np, "cal_type", &pdata->cal_type);
+ of_property_read_u32(np, "type", &pdata->type);
+
+ of_node_put(np);
+ return 0;
}

static int exynos_map_dt_data(struct platform_device *pdev)
@@ -792,12 +851,13 @@ static int exynos_map_dt_data(struct platform_device *pdev)
return -EADDRNOTAVAIL;
}

- pdata = exynos_get_driver_data(pdev, data->id);
- if (!pdata) {
- dev_err(&pdev->dev, "No platform init data supplied.\n");
- return -ENODEV;
- }
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct exynos_tmu_platform_data),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;

+ exynos_of_sensor_conf(pdev->dev.of_node, pdata);
data->pdata = pdata;
data->soc = pdata->type;

@@ -857,10 +917,9 @@ static int exynos_map_dt_data(struct platform_device *pdev)

static int exynos_tmu_probe(struct platform_device *pdev)
{
- struct exynos_tmu_data *data;
struct exynos_tmu_platform_data *pdata;
- struct thermal_sensor_conf *sensor_conf;
- int ret, i;
+ struct exynos_tmu_data *data;
+ int ret;

data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
GFP_KERNEL);
@@ -870,9 +929,16 @@ static int exynos_tmu_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
mutex_init(&data->lock);

+ data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
+ exynos_get_temp, NULL,
+ exynos_tmu_set_emulation);
+ if (IS_ERR(data->tzd)) {
+ pr_err("thermal: tz: %p ERROR\n", data->tzd);
+ return PTR_ERR(data->tzd);
+ }
ret = exynos_map_dt_data(pdev);
if (ret)
- return ret;
+ goto err_sensor;

pdata = data->pdata;

@@ -881,20 +947,22 @@ static int exynos_tmu_probe(struct platform_device *pdev)
data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
if (IS_ERR(data->clk)) {
dev_err(&pdev->dev, "Failed to get clock\n");
- return PTR_ERR(data->clk);
+ ret = PTR_ERR(data->clk);
+ goto err_sensor;
}

data->clk_sec = devm_clk_get(&pdev->dev, "tmu_triminfo_apbif");
if (IS_ERR(data->clk_sec)) {
if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
dev_err(&pdev->dev, "Failed to get triminfo clock\n");
- return PTR_ERR(data->clk_sec);
+ ret = PTR_ERR(data->clk_sec);
+ goto err_sensor;
}
} else {
ret = clk_prepare(data->clk_sec);
if (ret) {
dev_err(&pdev->dev, "Failed to get clock\n");
- return ret;
+ goto err_sensor;
}
}

@@ -910,42 +978,6 @@ static int exynos_tmu_probe(struct platform_device *pdev)
goto err_clk;
}

- exynos_tmu_control(pdev, true);
-
- /* 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) {
- ret = -ENOMEM;
- goto err_clk;
- }
- 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 < sensor_conf->trip_data.trip_count; i++) {
- sensor_conf->trip_data.trip_val[i] =
- pdata->threshold + pdata->trigger_levels[i];
- sensor_conf->trip_data.trip_type[i] =
- pdata->trigger_type[i];
- }
-
- sensor_conf->trip_data.trigger_falling = pdata->threshold_falling;
-
- sensor_conf->dev = &pdev->dev;
- /* 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;
- }
- data->reg_conf = sensor_conf;
-
ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data);
if (ret) {
@@ -953,21 +985,31 @@ static int exynos_tmu_probe(struct platform_device *pdev)
goto err_clk;
}

+ ret = exynos_tmu_initialize(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to initialize TMU\n");
+ goto err_clk;
+ }
+ exynos_tmu_control(pdev, true);
return 0;
+
err_clk:
clk_unprepare(data->clk);
err_clk_sec:
if (!IS_ERR(data->clk_sec))
clk_unprepare(data->clk_sec);
+err_sensor:
+ thermal_zone_of_sensor_unregister(&pdev->dev, data->tzd);
+
return ret;
}

static int exynos_tmu_remove(struct platform_device *pdev)
{
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+ struct thermal_zone_device *tzd = data->tzd;

- exynos_unregister_thermal(data->reg_conf);
-
+ thermal_zone_of_sensor_unregister(&pdev->dev, tzd);
exynos_tmu_control(pdev, false);

clk_unprepare(data->clk);
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
index 1e87f0f..6f176ef 100644
--- a/drivers/thermal/samsung/exynos_tmu.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -24,40 +24,10 @@
#define _EXYNOS_TMU_H
#include <linux/cpu_cooling.h>

-#include "exynos_thermal_common.h"
-
#include <dt-bindings/thermal/thermal_exynos.h>

/**
* struct exynos_tmu_platform_data
- * @threshold: basic temperature for generating interrupt
- * 25 <= threshold <= 125 [unit: degree Celsius]
- * @threshold_falling: differntial value for setting threshold
- * of temperature falling interrupt.
- * @trigger_levels: array for each interrupt levels
- * [unit: degree Celsius]
- * 0: temperature for trigger_level0 interrupt
- * condition for trigger_level0 interrupt:
- * current temperature > threshold + trigger_levels[0]
- * 1: temperature for trigger_level1 interrupt
- * condition for trigger_level1 interrupt:
- * current temperature > threshold + trigger_levels[1]
- * 2: temperature for trigger_level2 interrupt
- * condition for trigger_level2 interrupt:
- * current temperature > threshold + trigger_levels[2]
- * 3: temperature for trigger_level3 interrupt
- * condition for trigger_level3 interrupt:
- * current temperature > threshold + trigger_levels[3]
- * @trigger_type: defines the type of trigger. Possible values are,
- * THROTTLE_ACTIVE trigger type
- * THROTTLE_PASSIVE trigger type
- * SW_TRIP trigger type
- * HW_TRIP
- * @trigger_enable[]: array to denote which trigger levels are enabled.
- * 1 = enable trigger_level[] interrupt,
- * 0 = disable trigger_level[] interrupt
- * @max_trigger_level: max trigger level supported by the TMU
- * @non_hw_trigger_levels: number of defined non-hardware trigger levels
* @gain: gain of amplifier in the positive-TC generator block
* 0 < gain <= 15
* @reference_voltage: reference voltage of amplifier
@@ -69,21 +39,12 @@
* @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
*
* This structure is required for configuration of exynos_tmu driver.
*/
struct exynos_tmu_platform_data {
- u8 threshold;
- u8 threshold_falling;
- u8 trigger_levels[MAX_TRIP_COUNT];
- enum trigger_type trigger_type[MAX_TRIP_COUNT];
- bool trigger_enable[MAX_TRIP_COUNT];
- u8 max_trigger_level;
- u8 non_hw_trigger_levels;
u8 gain;
u8 reference_voltage;
u8 noise_cancel_mode;
@@ -99,18 +60,6 @@ struct exynos_tmu_platform_data {
u32 type;
};

-/**
- * struct exynos_tmu_init_data
- * @tmu_count: number of TMU instances.
- * @tmu_data: platform data of all TMU instances.
- * This structure is required to store data for multi-instance exynos tmu
- * driver.
- */
-struct exynos_tmu_init_data {
- int tmu_count;
- struct exynos_tmu_platform_data tmu_data[];
-};
-
extern struct exynos_tmu_init_data const exynos3250_default_tmu_data;
extern struct exynos_tmu_init_data const exynos4210_default_tmu_data;
extern struct exynos_tmu_init_data const exynos4412_default_tmu_data;
--
2.0.0.rc2
Lukasz Majewski
2014-10-09 16:38:54 UTC
Permalink
After defining all necessary Exynos data in the device tree
those files can be removed.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/thermal/samsung/exynos_thermal_common.c | 448 ------------------------
drivers/thermal/samsung/exynos_thermal_common.h | 106 ------
2 files changed, 554 deletions(-)
delete mode 100644 drivers/thermal/samsung/exynos_thermal_common.c
delete mode 100644 drivers/thermal/samsung/exynos_thermal_common.h

diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
deleted file mode 100644
index c306de5..0000000
--- a/drivers/thermal/samsung/exynos_thermal_common.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * exynos_thermal_common.c - Samsung EXYNOS common thermal file
- *
- * Copyright (C) 2013 Samsung Electronics
- * Amit Daniel Kachhap <***@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/cpu_cooling.h>
-#include <linux/err.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;
-};
-
-/* 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;
-}
-
-/* Set mode callback functions for thermal zone */
-static int exynos_set_mode(struct thermal_zone_device *thermal,
- enum thermal_device_mode mode)
-{
- struct exynos_thermal_zone *th_zone = thermal->devdata;
- if (!th_zone) {
- dev_err(&thermal->device,
- "thermal zone not registered\n");
- return 0;
- }
-
- mutex_lock(&thermal->lock);
-
- if (mode == THERMAL_DEVICE_ENABLED &&
- !th_zone->sensor_conf->trip_data.trigger_falling)
- thermal->polling_delay = IDLE_INTERVAL;
- else
- thermal->polling_delay = 0;
-
- mutex_unlock(&thermal->lock);
-
- th_zone->mode = mode;
- thermal_zone_device_update(thermal);
- dev_dbg(th_zone->sensor_conf->dev,
- "thermal polling set for duration=%d msec\n",
- thermal->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)
-{
- struct exynos_thermal_zone *th_zone = thermal->devdata;
- int max_trip = th_zone->sensor_conf->trip_data.trip_count;
- int trip_type;
-
- if (trip < 0 || trip >= max_trip)
- return -EINVAL;
-
- trip_type = th_zone->sensor_conf->trip_data.trip_type[trip];
-
- if (trip_type == SW_TRIP)
- *type = THERMAL_TRIP_CRITICAL;
- else if (trip_type == THROTTLE_ACTIVE)
- *type = THERMAL_TRIP_ACTIVE;
- else if (trip_type == THROTTLE_PASSIVE)
- *type = THERMAL_TRIP_PASSIVE;
- else
- 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)
-{
- 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;
-
- *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)
-{
- 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 */
-static int exynos_bind(struct thermal_zone_device *thermal,
- struct thermal_cooling_device *cdev)
-{
- struct exynos_thermal_zone *th_zone = thermal->devdata;
- struct thermal_sensor_conf *data = th_zone->sensor_conf;
- struct device_node *child, *gchild, *np;
- struct of_phandle_args cooling_spec;
- unsigned long max, state = 0;
- int ret = 0, i = 0;
-
- /*
- * Below code is necessary to skip binding when cpufreq's
- * frequency table is not yet initialized.
- */
- cdev->ops->get_max_state(cdev, &state);
- if (!state && !th_zone->cool_dev_size) {
- th_zone->cool_dev_size = 1;
- th_zone->cool_dev[0] = cdev;
- th_zone->bind = false;
- return 0;
- }
-
- np = of_find_node_by_path("/thermal-zones/cpu-thermal");
- if (!np) {
- pr_err("failed to find thmerla-zones/cpu-thermal node\n");
- return -ENOENT;
- }
-
- child = of_get_child_by_name(np, "cooling-maps");
-
- for_each_child_of_node(child, gchild) {
- ret = of_parse_phandle_with_args(gchild, "cooling-device",
- "#cooling-cells",
- 0, &cooling_spec);
- if (ret < 0) {
- pr_err("missing cooling_device property\n");
- goto end;
- }
-
- if (cooling_spec.args_count < 2) {
- ret = -EINVAL;
- goto end;
- }
-
- max = cooling_spec.args[0];
- if (thermal_zone_bind_cooling_device(thermal, i, cdev,
- max, 0)) {
- dev_err(data->dev,
- "thermal error unbinding cdev inst=%d\n", i);
-
- ret = -EINVAL;
- goto end;
- }
- i++;
- }
- th_zone->bind = true;
-end:
- of_node_put(child);
- of_node_put(np);
-
- 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;
- struct exynos_thermal_zone *th_zone = thermal->devdata;
- struct thermal_sensor_conf *data = th_zone->sensor_conf;
- struct device_node *child, *gchild, *np;
-
- if (th_zone->bind == false || !th_zone->cool_dev_size)
- return 0;
-
- /* 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;
-
- np = of_find_node_by_path("/thermal-zones/cpu-thermal");
- if (!np) {
- pr_err("failed to find thmerla-zones/cpu-thermal node\n");
- return -ENOENT;
- }
-
- child = of_get_child_by_name(np, "cooling-maps");
-
- i = 0;
- for_each_child_of_node(child, gchild) {
- if (thermal_zone_unbind_cooling_device(thermal, i,
- cdev)) {
- dev_err(data->dev,
- "error unbinding cdev inst=%d\n", i);
- ret = -EINVAL;
- goto end;
- }
- i++;
- }
- th_zone->bind = false;
-end:
- of_node_put(child);
- of_node_put(np);
-
- return ret;
-}
-
-/* Get temperature callback functions for thermal zone */
-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) {
- dev_err(&thermal->device,
- "Temperature sensor not initialised\n");
- return -EINVAL;
- }
- data = th_zone->sensor_conf->driver_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;
- struct exynos_thermal_zone *th_zone = thermal->devdata;
-
- if (!th_zone->sensor_conf) {
- dev_err(&thermal->device,
- "Temperature sensor not initialised\n");
- return -EINVAL;
- }
- 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;
-}
-
-/* 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 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(struct thermal_sensor_conf *conf)
-{
- unsigned int i;
- char data[10];
- char *envp[] = { data, NULL };
- struct exynos_thermal_zone *th_zone;
-
- if (!conf || !conf->pzone_data) {
- pr_err("Invalid temperature sensor configuration data\n");
- return;
- }
-
- th_zone = conf->pzone_data;
-
- 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;
- struct exynos_thermal_zone *th_zone;
-
- if (!sensor_conf || !sensor_conf->read_temperature) {
- pr_err("Temperature sensor not initialised\n");
- return -EINVAL;
- }
-
- th_zone = devm_kzalloc(sensor_conf->dev,
- sizeof(struct exynos_thermal_zone), GFP_KERNEL);
- if (!th_zone)
- return -ENOMEM;
-
- th_zone->sensor_conf = sensor_conf;
- /*
- * TODO: 1) Handle multiple cooling devices in a thermal zone
- * 2) Add a flag/name in cooling info to map to specific
- * sensor
- */
- if (sensor_conf->cooling_data.freq_clip_count > 0) {
- cpumask_set_cpu(0, &mask_val);
- th_zone->cool_dev[th_zone->cool_dev_size] =
- cpufreq_cooling_register(&mask_val);
- if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) {
- dev_err(sensor_conf->dev,
- "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, 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)) {
- dev_err(sensor_conf->dev,
- "Failed to register thermal zone device\n");
- ret = PTR_ERR(th_zone->therm_dev);
- goto err_unregister;
- }
- th_zone->mode = THERMAL_DEVICE_ENABLED;
- sensor_conf->pzone_data = th_zone;
-
- dev_info(sensor_conf->dev,
- "Exynos: Thermal zone(%s) registered\n", sensor_conf->name);
-
- return 0;
-
-err_unregister:
- exynos_unregister_thermal(sensor_conf);
- return ret;
-}
-
-/* Un-Register with the in-kernel thermal management */
-void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf)
-{
- int i;
- struct exynos_thermal_zone *th_zone;
-
- if (!sensor_conf || !sensor_conf->pzone_data) {
- pr_err("Invalid temperature sensor configuration data\n");
- return;
- }
-
- th_zone = sensor_conf->pzone_data;
-
- 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]);
- }
-
- dev_info(sensor_conf->dev,
- "Exynos: Kernel Thermal management unregistered\n");
-}
diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
deleted file mode 100644
index cd44719..0000000
--- a/drivers/thermal/samsung/exynos_thermal_common.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * exynos_thermal_common.h - Samsung EXYNOS common header file
- *
- * Copyright (C) 2013 Samsung Electronics
- * Amit Daniel Kachhap <***@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 _EXYNOS_THERMAL_COMMON_H
-#define _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 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)
-
-enum trigger_type {
- THROTTLE_ACTIVE = 1,
- THROTTLE_PASSIVE,
- SW_TRIP,
- HW_TRIP,
-};
-
-/**
- * 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_type[MAX_TRIP_COUNT];
- int trip_count;
- unsigned char 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 *driver_data;
- void *pzone_data;
- struct device *dev;
-};
-
-/*Functions used exynos based thermal sensor driver*/
-#ifdef CONFIG_EXYNOS_THERMAL_CORE
-void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf);
-int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
-void exynos_report_trigger(struct thermal_sensor_conf *sensor_conf);
-#else
-static inline void
-exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf) { return; }
-
-static inline int
-exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) { return 0; }
-
-static inline void
-exynos_report_trigger(struct thermal_sensor_conf *sensor_conf) { return; }
-
-#endif /* CONFIG_EXYNOS_THERMAL_CORE */
-#endif /* _EXYNOS_THERMAL_COMMON_H */
--
2.0.0.rc2
Lukasz Majewski
2014-10-09 16:38:56 UTC
Permalink
Since both SoCs have the same TMU IP block embedded on them, it is
not necessary to maintain separate compatible entry.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
arch/arm/boot/dts/exynos5250.dtsi | 2 +-
drivers/thermal/samsung/exynos_tmu.c | 3 ---
2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index e71ec78..3426bab 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -238,7 +238,7 @@
};

tmu: ***@10060000 {
- compatible = "samsung,exynos5250-tmu";
+ compatible = "samsung,exynos4412-tmu";
reg = <0x10060000 0x100>;
interrupts = <0 65 0>;
clocks = <&clock CLK_TMU>;
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index e26042a..f1e8c9b 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -753,9 +753,6 @@ static const struct of_device_id exynos_tmu_match[] = {
.compatible = "samsung,exynos4412-tmu",
},
{
- .compatible = "samsung,exynos5250-tmu",
- },
- {
.compatible = "samsung,exynos5260-tmu",
},
{
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:55 UTC
Permalink
Data already present in the exynos_tmu_data.c file has been moved to the
appropriate device tree files.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/thermal/samsung/exynos_tmu_data.c | 228 ------------------------------
1 file changed, 228 deletions(-)
delete mode 100644 drivers/thermal/samsung/exynos_tmu_data.c

diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
deleted file mode 100644
index a993f3d..0000000
--- a/drivers/thermal/samsung/exynos_tmu_data.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * exynos_tmu_data.c - Samsung EXYNOS tmu data file
- *
- * Copyright (C) 2013 Samsung Electronics
- * Amit Daniel Kachhap <***@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"
-
-struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
- .tmu_data = {
- {
- .threshold = 80,
- .trigger_levels[0] = 5,
- .trigger_levels[1] = 20,
- .trigger_levels[2] = 30,
- .trigger_enable[0] = true,
- .trigger_enable[1] = true,
- .trigger_enable[2] = true,
- .trigger_enable[3] = false,
- .trigger_type[0] = THROTTLE_ACTIVE,
- .trigger_type[1] = THROTTLE_ACTIVE,
- .trigger_type[2] = SW_TRIP,
- .max_trigger_level = 4,
- .non_hw_trigger_levels = 3,
- .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,
- .type = SOC_ARCH_EXYNOS4210,
- },
- },
- .tmu_count = 1,
-};
-
-#define EXYNOS3250_TMU_DATA \
- .threshold_falling = 10, \
- .trigger_levels[0] = 70, \
- .trigger_levels[1] = 95, \
- .trigger_levels[2] = 110, \
- .trigger_levels[3] = 120, \
- .trigger_enable[0] = true, \
- .trigger_enable[1] = true, \
- .trigger_enable[2] = true, \
- .trigger_enable[3] = false, \
- .trigger_type[0] = THROTTLE_ACTIVE, \
- .trigger_type[1] = THROTTLE_ACTIVE, \
- .trigger_type[2] = SW_TRIP, \
- .trigger_type[3] = HW_TRIP, \
- .max_trigger_level = 4, \
- .non_hw_trigger_levels = 3, \
- .gain = 8, \
- .reference_voltage = 16, \
- .noise_cancel_mode = 4, \
- .cal_type = TYPE_TWO_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
-
-struct exynos_tmu_init_data const exynos3250_default_tmu_data = {
- .tmu_data = {
- {
- EXYNOS3250_TMU_DATA,
- .type = SOC_ARCH_EXYNOS3250,
- },
- },
- .tmu_count = 1,
-};
-
-#define EXYNOS4412_TMU_DATA \
- .threshold_falling = 10, \
- .trigger_levels[0] = 70, \
- .trigger_levels[1] = 95, \
- .trigger_levels[2] = 110, \
- .trigger_levels[3] = 120, \
- .trigger_enable[0] = true, \
- .trigger_enable[1] = true, \
- .trigger_enable[2] = true, \
- .trigger_enable[3] = false, \
- .trigger_type[0] = THROTTLE_ACTIVE, \
- .trigger_type[1] = THROTTLE_ACTIVE, \
- .trigger_type[2] = SW_TRIP, \
- .trigger_type[3] = HW_TRIP, \
- .max_trigger_level = 4, \
- .non_hw_trigger_levels = 3, \
- .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
-
-struct exynos_tmu_init_data const exynos4412_default_tmu_data = {
- .tmu_data = {
- {
- EXYNOS4412_TMU_DATA,
- .type = SOC_ARCH_EXYNOS4412,
- },
- },
- .tmu_count = 1,
-};
-
-struct exynos_tmu_init_data const exynos5250_default_tmu_data = {
- .tmu_data = {
- {
- EXYNOS4412_TMU_DATA,
- .type = SOC_ARCH_EXYNOS5250,
- },
- },
- .tmu_count = 1,
-};
-
-#define __EXYNOS5260_TMU_DATA \
- .threshold_falling = 10, \
- .trigger_levels[0] = 85, \
- .trigger_levels[1] = 103, \
- .trigger_levels[2] = 110, \
- .trigger_levels[3] = 120, \
- .trigger_enable[0] = true, \
- .trigger_enable[1] = true, \
- .trigger_enable[2] = true, \
- .trigger_enable[3] = false, \
- .trigger_type[0] = THROTTLE_ACTIVE, \
- .trigger_type[1] = THROTTLE_ACTIVE, \
- .trigger_type[2] = SW_TRIP, \
- .trigger_type[3] = HW_TRIP, \
- .max_trigger_level = 4, \
- .non_hw_trigger_levels = 3, \
- .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,
-
-#define EXYNOS5260_TMU_DATA \
- __EXYNOS5260_TMU_DATA \
- .type = SOC_ARCH_EXYNOS5260
-
-struct exynos_tmu_init_data const exynos5260_default_tmu_data = {
- .tmu_data = {
- { EXYNOS5260_TMU_DATA },
- { EXYNOS5260_TMU_DATA },
- { EXYNOS5260_TMU_DATA },
- { EXYNOS5260_TMU_DATA },
- { EXYNOS5260_TMU_DATA },
- },
- .tmu_count = 5,
-};
-
-#define EXYNOS5420_TMU_DATA \
- __EXYNOS5260_TMU_DATA \
- .type = SOC_ARCH_EXYNOS5420
-
-#define EXYNOS5420_TMU_DATA_SHARED \
- __EXYNOS5260_TMU_DATA \
- .type = SOC_ARCH_EXYNOS5420_TRIMINFO
-
-struct exynos_tmu_init_data const exynos5420_default_tmu_data = {
- .tmu_data = {
- { EXYNOS5420_TMU_DATA },
- { EXYNOS5420_TMU_DATA },
- { EXYNOS5420_TMU_DATA_SHARED },
- { EXYNOS5420_TMU_DATA_SHARED },
- { EXYNOS5420_TMU_DATA_SHARED },
- },
- .tmu_count = 5,
-};
-
-#define EXYNOS5440_TMU_DATA \
- .trigger_levels[0] = 100, \
- .trigger_levels[4] = 105, \
- .trigger_enable[0] = 1, \
- .trigger_type[0] = SW_TRIP, \
- .trigger_type[4] = HW_TRIP, \
- .max_trigger_level = 5, \
- .non_hw_trigger_levels = 1, \
- .gain = 5, \
- .reference_voltage = 16, \
- .noise_cancel_mode = 4, \
- .cal_type = TYPE_ONE_POINT_TRIMMING, \
- .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
-
-struct exynos_tmu_init_data const exynos5440_default_tmu_data = {
- .tmu_data = {
- { EXYNOS5440_TMU_DATA } ,
- { EXYNOS5440_TMU_DATA } ,
- { EXYNOS5440_TMU_DATA } ,
- },
- .tmu_count = 3,
-};
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-09 16:38:57 UTC
Permalink
Since both SoCs have the same TMU IP block embedded on them, it is
not necessary to maintain separate compatible entry.

Signed-off-by: Lukasz Majewski <***@samsung.com>
---
drivers/thermal/samsung/exynos_tmu.c | 3 ---
1 file changed, 3 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index f1e8c9b..7818e2f 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -744,9 +744,6 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id)

static const struct of_device_id exynos_tmu_match[] = {
{
- .compatible = "samsung,exynos3250-tmu",
- },
- {
.compatible = "samsung,exynos4210-tmu",
},
{
--
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Chanwoo Choi
2014-10-09 23:34:22 UTC
Permalink
Post by Lukasz Majewski
Since both SoCs have the same TMU IP block embedded on them, it is
not necessary to maintain separate compatible entry.
---
drivers/thermal/samsung/exynos_tmu.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index f1e8c9b..7818e2f 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -744,9 +744,6 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id)
static const struct of_device_id exynos_tmu_match[] = {
{
- .compatible = "samsung,exynos3250-tmu",
- },
- {
If you want to remove compatible string for Exynos3250,
you have to modify it on exynos3250.dtsi.

Thanks,
Chanwoo Choi
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-10 08:51:18 UTC
Permalink
Hi Chanwoo,
Post by Chanwoo Choi
Post by Lukasz Majewski
Since both SoCs have the same TMU IP block embedded on them, it is
not necessary to maintain separate compatible entry.
---
drivers/thermal/samsung/exynos_tmu.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/thermal/samsung/exynos_tmu.c
b/drivers/thermal/samsung/exynos_tmu.c index f1e8c9b..7818e2f 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -744,9 +744,6 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id)
static const struct of_device_id exynos_tmu_match[] = {
{
- .compatible = "samsung,exynos3250-tmu",
- },
- {
If you want to remove compatible string for Exynos3250,
you have to modify it on exynos3250.dtsi.
Thanks for pointing this out. I've overlooked this dtsi file.
Post by Chanwoo Choi
Thanks,
Chanwoo Choi
--
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Lukasz Majewski
2014-10-23 08:50:04 UTC
Permalink
Hi Lukasz,
Post by Lukasz Majewski
1. Introduction
Following patches aim to clean up the current implementation of the
thermal framework on Exynos devices.
The main goal was to use a generic code for reading thermal
configuration (of-thermal.c). Due to that redundant
exynos_thermal_common.[h|c] files were removed.
Around 400 lines of code (LOC) were removed directly by this patch,
which is around 20% of the Exynos thermal code base.
This work should NOT bring any functional changes to Exynos thermal
subsystem.
2. Patch-set structure
This series starts with extending current of-thermal.c implementation
with exporting information about trip points and support for setting
emulated temperature. Those changes were necessary to reuse this code
in Exynos.
Then the cpu_cooling functionality has been preserved to allow cooling
devices by reducing operating frequency. Definition of trip points and
cpufreq's cooling properties were moved to device tree.
Then the rework of the way in which configuration data is provided to
the Exynos thermal subsystem was performed. Now device tree is used
for configuration.
Patch series end with removing exynos5250/exynos3250 TMU compatibles.
Both SoCs have thermal management unit (TMU) compatible with the one
first introduced at Exynos4412.
3. Dead code removal
Thermal support for some SoCs, previously available in the
exynos_tmu_data.c file, was removed since, as of 3.17-rc6, they
didn't have TMU bindings.
Moreover, support for cpu_cooling devices was preserved only on those
SoCs which had available and working cpufreq driver.
4. Testing
- Exynos4210 - Trats (TMU zone + cpu_cooling)
- Exynos4412 - Trats2/Odroid U3 (TMU zone + cpu_cooling)
- Exynos5250 - Arndale (TMU zone + cpu_cooling)
- Exynos5420 - Arndale-octa (only TMU zones)
Unfortunately, I don't posses Exynos5440 for testing. Its
functionality has been preserved in the code, but not tested on the
hardware. I would be grateful for help in testing.
This work requires following patches developed by Bartlomiej
5.1. [PATCH v3] ARM: dts: add CPU nodes for Exynos4 SoCs
http://article.gmane.org/gmane.linux.kernel.samsung-soc/37946/match=patch+v3+arm+dts+add+cpu+nodes+exynos4+socs
[PATCH 00/33] thermal: exynos: convert the driver to use per-SoC type operations
http://article.gmane.org/gmane.linux.kernel.samsung-soc/37642/match=patch+00+33+thermal+exynos+convert+driver+use+per+soc+type+operations
Any comments on this patch set (despite the ones from Chanwoo)?

I'm especially wondering if changes introduced to of-thermal.c file are
appropriate for mainline.
Post by Lukasz Majewski
thermal: of: Extend of-thermal.c to provide number of trip points
thermal: of: Extend of-thermal.c to provide check if trip point is
enabled
thermal: of: Extend of-thermal.c to provide number of non critical
trip points
thermal: of: Extend current of-thermal.c code to allow setting
emulated temp
thermal: exynos: cosmetic: Correct comment format
thermal: exynos: Provide thermal_exynos.h file to be included in
device tree files
thermal: dts: trats: Enable TMU on the Exynos4210 trats device
thermal: dts: exynos: Adding LD010 regulator node necessary for TMU
on Odroid U3 board
thermal: dts: Provide bindings and enable TMU at Exynos4x12 devices
thermal: cpu_cooling: dts: Define device tree bindings for Exynos
cpu cooling functionality
thermal: cpu_cooling: Modify exynos thermal code to use device tree
for cpu cooling configuration
thermal: exynos: dts: Add default definition for the TMU sensor
thermal: dts: Default trip points definition for Exynos5420 SoCs
thermal: exynos: dts: Define default thermal-zones for Exynos4
thermal: dts: exynos: Trip points and sensor configuration data for
Exynos5440
thermal: exynos: dts: Provide device tree bindings identical to one
in exynos_tmu_data.c
thermal: samsung: core: Exynos TMU rework to use device tree for
configuration
thermal: exynos: Remove exynos_thermal_common.[c|h] files
thermal: exynos: Remove exynos_tmu_data.c file
thermal: exynos: Make Exynos5250 TMU compatible with Exynos4412
thermal: exynos: Make Exynos3250 TMU compatible with Exynos4412
arch/arm/boot/dts/exynos4-cpu-thermal.dtsi | 52 +++
arch/arm/boot/dts/exynos4.dtsi | 5 +
arch/arm/boot/dts/exynos4210-trats.dts | 19 +
arch/arm/boot/dts/exynos4210.dtsi | 28 +-
arch/arm/boot/dts/exynos4212.dtsi | 5 +-
arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 27 ++
arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi | 24 ++
arch/arm/boot/dts/exynos4412.dtsi | 5 +-
arch/arm/boot/dts/exynos4x12.dtsi | 13 +
arch/arm/boot/dts/exynos5250.dtsi | 29 +-
arch/arm/boot/dts/exynos5420-trip-points.dtsi | 35 ++
arch/arm/boot/dts/exynos5420.dtsi | 33 ++
arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi | 25 ++
arch/arm/boot/dts/exynos5440-trip-points.dtsi | 25 ++
arch/arm/boot/dts/exynos5440.dtsi | 18 +
drivers/cpufreq/exynos-cpufreq.c | 23 +-
drivers/thermal/of-thermal.c | 52 ++-
drivers/thermal/samsung/Makefile | 2 -
drivers/thermal/samsung/exynos_thermal_common.c | 430
----------------------
drivers/thermal/samsung/exynos_thermal_common.h | 106 ------
drivers/thermal/samsung/exynos_tmu.c | 283
+++++++------- drivers/thermal/samsung/exynos_tmu.h |
79 +--- drivers/thermal/samsung/exynos_tmu_data.c | 264
------------- drivers/thermal/thermal_core.h | 15
+ include/dt-bindings/thermal/thermal_exynos.h | 40 ++
include/linux/thermal.h | 6 +- 26 files
changed, 623 insertions(+), 1020 deletions(-) create mode 100644
arch/arm/boot/dts/exynos4-cpu-thermal.dtsi create mode 100644
arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi create mode 100644
arch/arm/boot/dts/exynos5420-trip-points.dtsi create mode 100644
arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi create mode 100644
arch/arm/boot/dts/exynos5440-trip-points.dtsi delete mode 100644
drivers/thermal/samsung/exynos_thermal_common.c delete mode 100644
drivers/thermal/samsung/exynos_thermal_common.h delete mode 100644
drivers/thermal/samsung/exynos_tmu_data.c create mode 100644
include/dt-bindings/thermal/thermal_exynos.h
--
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...