ARM: tegra: thermal: Edp into cooling device
Joshua Primero [Fri, 10 Aug 2012 00:05:14 +0000 (17:05 -0700)]
Removed EDP specific code from tegra thermal layer. It is
now implemented as a cooling device.

Change-Id: Ica9602569367e07deb04cf3cb8064a1c4101a7a4
Signed-off-by: Joshua Primero <jprimero@nvidia.com>
Reviewed-on: http://git-master/r/124501
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

Rebase-Id: Ra187adf6c66ac57ecd0049fde57a4c6617076206

arch/arm/mach-tegra/cpu-tegra.c
arch/arm/mach-tegra/include/mach/edp.h
arch/arm/mach-tegra/tegra3_thermal.c

index 8fdfa4b..7906fed 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/cpu.h>
 
 #include <mach/edp.h>
+#include <mach/thermal.h>
 
 #include "clock.h"
 #include "cpu-tegra.h"
@@ -210,32 +211,60 @@ static unsigned int edp_governor_speed(unsigned int requested_speed)
                return edp_limit;
 }
 
-int tegra_edp_update_thermal_zone(int temperature)
+int tegra_edp_get_trip_temp(void *data, long trip)
 {
-       int i;
-       int ret = 0;
-       int nlimits = cpu_edp_limits_size;
-       int index;
+       tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
+       return cpu_edp_limits[trip].temperature * 1000;
+}
+
+int tegra_edp_get_trip_size(void)
+{
+       tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
+       return cpu_edp_limits_size-1;
+}
+
+int tegra_edp_get_max_state(struct thermal_cooling_device *cdev,
+                               unsigned long *max_state)
+{
+       *max_state = 1;
+       return 0;
+}
+
+/* Bitmask for which edp trip points have been breached */
+static int edp_state_mask;
+
+int tegra_edp_get_cur_state(struct thermal_cooling_device *cdev,
+                               unsigned long *cur_state)
+{
+       struct tegra_cooling_device *tegra_cdev = cdev->devdata;
+       int index = tegra_cdev->id && 0xffff;
+       *cur_state = !!((1 << index) & edp_state_mask);
+       return 0;
+}
+
+int tegra_edp_set_cur_state(struct thermal_cooling_device *cdev,
+                               unsigned long cur_state)
+{
+       struct tegra_cooling_device *tegra_cdev = cdev->devdata;
+       int index, i;
+
 
        if (!cpu_edp_limits)
                return -EINVAL;
 
-       index = nlimits - 1;
+       mutex_lock(&tegra_cpu_lock);
+       index = tegra_cdev->id & 0xffff;
 
-       if (temperature < cpu_edp_limits[0].temperature) {
-               index = 0;
-       } else {
-               for (i = 0; i < (nlimits - 1); i++) {
-                       if (temperature >= cpu_edp_limits[i].temperature &&
-                          temperature < cpu_edp_limits[i + 1].temperature) {
-                               index = i + 1;
-                               break;
-                       }
-               }
-       }
+       if (cur_state)
+               edp_state_mask |= 1 << index;
+       else
+               edp_state_mask &= ~(1 << index);
 
-       mutex_lock(&tegra_cpu_lock);
-       edp_thermal_index = index;
+       for (i=31; i>=0; i--)
+               if (edp_state_mask & (1 << i))
+                       break;
+
+       edp_thermal_index = i + 1;
 
        /* Update cpu rate if cpufreq (at least on cpu0) is already started;
           alter cpu dvfs table for this thermal zone if necessary */
@@ -247,9 +276,14 @@ int tegra_edp_update_thermal_zone(int temperature)
        tegra_cpu_dvfs_alter(edp_thermal_index, &edp_cpumask, false, 0);
        mutex_unlock(&tegra_cpu_lock);
 
-       return ret;
+       return 0;
 }
-EXPORT_SYMBOL_GPL(tegra_edp_update_thermal_zone);
+
+static struct thermal_cooling_device_ops tegra_edp_cooling_ops = {
+       .get_max_state = tegra_edp_get_max_state,
+       .get_cur_state = tegra_edp_get_cur_state,
+       .set_cur_state = tegra_edp_set_cur_state,
+};
 
 int tegra_system_edp_alarm(bool alarm)
 {
@@ -353,6 +387,16 @@ static struct notifier_block tegra_cpu_edp_notifier = {
        .notifier_call = tegra_cpu_edp_notify,
 };
 
+static struct thermal_cooling_device *edp_cdev;
+static struct tegra_cooling_device edp_cooling_devices[] = {
+       { .id = CDEV_EDPTABLE_ID_EDP_0 },
+       { .id = CDEV_EDPTABLE_ID_EDP_1 },
+       { .id = CDEV_EDPTABLE_ID_EDP_2 },
+       { .id = CDEV_EDPTABLE_ID_EDP_3 },
+       { .id = CDEV_EDPTABLE_ID_EDP_4 },
+};
+
+
 static void tegra_cpu_edp_init(bool resume)
 {
        tegra_get_system_edp_limits(&system_edp_limits);
@@ -376,6 +420,17 @@ static void tegra_cpu_edp_init(bool resume)
                register_hotcpu_notifier(&tegra_cpu_edp_notifier);
                pr_info("cpu-tegra: init EDP limit: %u MHz\n", edp_limit/1000);
        }
+
+       if (!edp_cdev) {
+               int i;
+               for (i=0; i<cpu_edp_limits_size-1; i++) {
+                       edp_cdev = thermal_cooling_device_register(
+                               "edp",
+                               &edp_cooling_devices[i],
+                               &tegra_edp_cooling_ops);
+               }
+       }
+
 }
 
 static void tegra_cpu_edp_exit(void)
index 48321ca..cb1e213 100644 (file)
@@ -42,9 +42,8 @@ struct system_edp_entry {
 };
 
 #ifdef CONFIG_TEGRA_EDP_LIMITS
-
-
-int tegra_edp_update_thermal_zone(int temperature);
+int tegra_edp_get_trip_temp(void *, long trip);
+int tegra_edp_get_trip_size(void);
 void tegra_init_cpu_edp_limits(unsigned int regulator_mA);
 void tegra_init_system_edp_limits(unsigned int power_limit_mW);
 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size);
@@ -57,8 +56,10 @@ static inline void tegra_init_cpu_edp_limits(int regulator_mA)
 {}
 static inline void tegra_init_system_edp_limits(int power_limit_mW)
 {}
-static inline int tegra_edp_update_thermal_zone(int temperature)
-{ return -1; }
+static inline int tegra_edp_get_trip_temp(void *data, long trip)
+{ return 0; }
+static inline int tegra_edp_get_trip_size(void)
+{ return 0; }
 static inline void tegra_get_cpu_edp_limits(struct tegra_edp_limits **limits,
                                            int *size)
 {}
index 56be98e..32c817c 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/thermal.h>
 #include <linux/module.h>
 #include <mach/thermal.h>
-#include <mach/edp.h>
 #include <linux/slab.h>
 #include <linux/suspend.h>
 
@@ -45,10 +44,6 @@ static int throttle_list_size;
 
 #define MAX_TEMP (120000)
 
-#ifdef CONFIG_TEGRA_EDP_LIMITS
-static long edp_thermal_zone_val;
-#endif
-
 #ifdef CONFIG_TEGRA_SKIN_THROTTLE
 static int skin_devs_bitmap;
 static struct therm_est_subdevice *skin_devs[THERMAL_DEVICE_MAX];
@@ -258,11 +253,8 @@ static void tegra_thermal_alert(void *data)
        }
 
 #ifdef CONFIG_TEGRA_EDP_LIMITS
-       tegra_get_cpu_edp_limits(&z, &zones_sz);
-
-/* edp table based off of tdiode measurements */
 #define EDP_TEMP_TJ(_index) (z[_index].temperature * 1000 + therm->edp_offset)
-
+       tegra_get_cpu_edp_limits(&z, &zones_sz);
        if (temp_tj < EDP_TEMP_TJ(0)) {
                lo_limit_edp_tj = temp_low_tj;
                hi_limit_edp_tj = EDP_TEMP_TJ(0);
@@ -294,15 +286,6 @@ static void tegra_thermal_alert(void *data)
        device->set_limits(device->data,
                                tj2dev(device, lo_limit_tj),
                                tj2dev(device, hi_limit_tj));
-
-#ifdef CONFIG_TEGRA_EDP_LIMITS
-       /* inform edp governor */
-       if (edp_thermal_zone_val != temp_tj) {
-               long temp_edp = (temp_tj - therm->edp_offset) / 1000;
-               tegra_edp_update_thermal_zone(temp_edp);
-               edp_thermal_zone_val = temp_tj;
-       }
-#endif
 }
 
 done: