]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
arm: tegra: soctherm: fix pointer misuse in zoneid
authorDiwakar Tundlam <dtundlam@nvidia.com>
Mon, 24 Mar 2014 21:49:35 +0000 (14:49 -0700)
committerDiwakar Tundlam <dtundlam@nvidia.com>
Tue, 25 Mar 2014 00:20:32 +0000 (17:20 -0700)
Storing the integer local thermal array index in tz->devdata pointer
is a misuse of pointers and gives rise to compilation warnings in
64bit builds.

Fix this by storing the pointer to the local therm structure and
retrieving it in the called routines. Since we can no longer have a
thermal zone for each tsensor, we don't support it anymore.

When handling soctherm HW interrupt, we know the exact trip_point
triggered. There's no need to update the entire zone. Hence we switch
to using the thermal_notify_framework API that takes the
specific trip_point.

Bug 1478989

Change-Id: I2211114602d54a4b0ca9d9780ce9a0b68e1ccecc
Signed-off-by: Diwakar Tundlam <dtundlam@nvidia.com>
Reviewed-on: http://git-master/r/385817

arch/arm/mach-tegra/tegra11_soctherm.c
arch/arm/mach-tegra/tegra11_soctherm.h

index 6bd0dc1ec2efdfd01feec2dd67db351c9f82aa1d..01b533460773baec37dda36d76f5298b410fe8df 100644 (file)
@@ -1152,21 +1152,19 @@ static struct thermal_cooling_device_ops soctherm_suspend_ops = {
 static int soctherm_bind(struct thermal_zone_device *thz,
                                struct thermal_cooling_device *cdev)
 {
-       int i, index = ((int)thz->devdata) - TSENSE_SIZE;
+       int i;
+       struct soctherm_therm *therm = thz->devdata;
        struct thermal_trip_info *trip_state;
        u32 base_cp, base_ft;
        s32 shft_cp, shft_ft;
 
-       if (index < 0)
-               return 0;
-
        /* skip binding cooling devices on improperly fused soctherm */
        if (tegra_fuse_calib_base_get_cp(&base_cp, &shft_cp) < 0 ||
            tegra_fuse_calib_base_get_ft(&base_ft, &shft_ft) < 0)
                return 0;
 
-       for (i = 0; i < plat_data.therm[index].num_trips; i++) {
-               trip_state = &plat_data.therm[index].trips[i];
+       for (i = 0; i < therm->num_trips; i++) {
+               trip_state = &therm->trips[i];
                if (trip_state->cdev_type &&
                    !strncmp(trip_state->cdev_type, cdev->type,
                                                THERMAL_NAME_LENGTH)) {
@@ -1194,14 +1192,12 @@ static int soctherm_bind(struct thermal_zone_device *thz,
 static int soctherm_unbind(struct thermal_zone_device *thz,
                                struct thermal_cooling_device *cdev)
 {
-       int i, index = ((int)thz->devdata) - TSENSE_SIZE;
+       int i;
+       struct soctherm_therm *therm = thz->devdata;
        struct thermal_trip_info *trip_state;
 
-       if (index < 0)
-               return 0;
-
-       for (i = 0; i < plat_data.therm[index].num_trips; i++) {
-               trip_state = &plat_data.therm[index].trips[i];
+       for (i = 0; i < therm->num_trips; i++) {
+               trip_state = &therm->trips[i];
                if (!trip_state->bound)
                        continue;
                if (trip_state->cdev_type &&
@@ -1230,56 +1226,45 @@ static int soctherm_unbind(struct thermal_zone_device *thz,
 static int soctherm_get_temp(struct thermal_zone_device *thz,
                                        unsigned long *temp)
 {
-       int index = (int)thz->devdata;
+       struct soctherm_therm *therm = thz->devdata;
+       ptrdiff_t index = therm - plat_data.therm;
        u32 r, regv, shft, mask;
        enum soctherm_sense i, j;
        int tt, ti;
 
-       if (index < TSENSE_SIZE) { /* 'TSENSE_XXX' thermal zone */
-               regv = TS_CPU0_STATUS1;
-               shft = TS_CPU0_STATUS1_TEMP_SHIFT;
-               mask = TS_CPU0_STATUS1_TEMP_MASK;
-               i = index;
-               j = index;
-       } else {
-               index -= TSENSE_SIZE; /* 'THERM_XXX' thermal zone */
-
-               switch (index) {
-               case THERM_CPU:
-                       regv = TS_TEMP1;
-                       shft = TS_TEMP1_CPU_TEMP_SHIFT;
-                       mask = TS_TEMP1_CPU_TEMP_MASK;
-                       i = TSENSE_CPU0;
-                       j = TSENSE_CPU3;
-                       break;
-
-               case THERM_GPU:
-                       regv = TS_TEMP1;
-                       shft = TS_TEMP1_GPU_TEMP_SHIFT;
-                       mask = TS_TEMP1_GPU_TEMP_MASK;
-                       i = TSENSE_GPU;
-                       j = TSENSE_GPU;
-                       break;
-
-               case THERM_PLL:
-                       regv = TS_TEMP2;
-                       shft = TS_TEMP2_PLLX_TEMP_SHIFT;
-                       mask = TS_TEMP2_PLLX_TEMP_MASK;
-                       i = TSENSE_PLLX;
-                       j = TSENSE_PLLX;
-                       break;
-
-               case THERM_MEM:
-                       regv = TS_TEMP2;
-                       shft = TS_TEMP2_MEM_TEMP_SHIFT;
-                       mask = TS_TEMP2_MEM_TEMP_MASK;
-                       i = TSENSE_MEM0;
-                       j = TSENSE_MEM1;
-                       break;
-
-               default:
-                       return 0; /* error really */
-               }
+       switch (index) {
+       case THERM_CPU:
+               regv = TS_TEMP1;
+               shft = TS_TEMP1_CPU_TEMP_SHIFT;
+               mask = TS_TEMP1_CPU_TEMP_MASK;
+               i = TSENSE_CPU0;
+               j = TSENSE_CPU3;
+               break;
+
+       case THERM_GPU:
+               regv = TS_TEMP1;
+               shft = TS_TEMP1_GPU_TEMP_SHIFT;
+               mask = TS_TEMP1_GPU_TEMP_MASK;
+               i = TSENSE_GPU;
+               j = TSENSE_GPU;
+               break;
+
+       case THERM_MEM:
+               regv = TS_TEMP2;
+               shft = TS_TEMP2_MEM_TEMP_SHIFT;
+               mask = TS_TEMP2_MEM_TEMP_MASK;
+               i = TSENSE_MEM0;
+               j = TSENSE_MEM1;
+               break;
+
+       case THERM_PLL:
+       default: /* if devdata has error, return PLL temp to be safe */
+               regv = TS_TEMP2;
+               shft = TS_TEMP2_PLLX_TEMP_SHIFT;
+               mask = TS_TEMP2_PLLX_TEMP_MASK;
+               i = TSENSE_PLLX;
+               j = TSENSE_PLLX;
+               break;
        }
 
        if (read_hw_temp) {
@@ -1317,14 +1302,9 @@ static int soctherm_get_temp(struct thermal_zone_device *thz,
 static int soctherm_get_trip_type(struct thermal_zone_device *thz,
                                int trip, enum thermal_trip_type *type)
 {
-       int index = ((int)thz->devdata) - TSENSE_SIZE;
-       struct thermal_trip_info *trip_state;
+       struct soctherm_therm *therm = thz->devdata;
 
-       if (index < 0)
-               return -EINVAL;
-
-       trip_state = &plat_data.therm[index].trips[trip];
-       *type = trip_state->trip_type;
+       *type = therm->trips[trip].trip_type;
        return 0;
 }
 
@@ -1345,14 +1325,11 @@ static int soctherm_get_trip_type(struct thermal_zone_device *thz,
 static int soctherm_get_trip_temp(struct thermal_zone_device *thz,
                                int trip, unsigned long *temp)
 {
-       int index = ((int)thz->devdata) - TSENSE_SIZE;
+       struct soctherm_therm *therm = thz->devdata;
        struct thermal_trip_info *trip_state;
        unsigned long trip_temp, zone_temp;
 
-       if (index < 0)
-               return -EINVAL;
-
-       trip_state = &plat_data.therm[index].trips[trip];
+       trip_state = &therm->trips[trip];
        trip_temp = trip_state->trip_temp;
        zone_temp = thz->temperature;
 
@@ -1366,7 +1343,6 @@ static int soctherm_get_trip_temp(struct thermal_zone_device *thz,
        }
 
        *temp = trip_temp;
-
        return 0;
 }
 
@@ -1386,39 +1362,35 @@ static int soctherm_get_trip_temp(struct thermal_zone_device *thz,
 static int soctherm_set_trip_temp(struct thermal_zone_device *thz,
                                int trip, unsigned long temp)
 {
-       int index = ((int)thz->devdata) - TSENSE_SIZE;
+       struct soctherm_therm *therm = thz->devdata;
        struct thermal_trip_info *trip_state;
        long rem;
 
-       if (index < 0)
-               return -EINVAL;
-
-       trip_state = &plat_data.therm[index].trips[trip];
-
+       trip_state = &therm->trips[trip];
        trip_state->trip_temp = enforce_temp_range(temp);
 
        rem = trip_state->trip_temp % LOWER_PRECISION_FOR_CONV(1000);
        if (rem) {
                pr_warn("soctherm: zone%d/trip_point%d %ld mC rounded down\n",
-                       index, trip, trip_state->trip_temp);
+                       thz->id, trip, trip_state->trip_temp);
                trip_state->trip_temp -= rem;
        }
 
        if (trip_state->trip_type == THERMAL_TRIP_HOT) {
                if (strnstr(trip_state->cdev_type,
                            "heavy", THERMAL_NAME_LENGTH))
-                       prog_hw_threshold(trip_state, index, THROTTLE_HEAVY);
+                       prog_hw_threshold(trip_state, thz->id, THROTTLE_HEAVY);
                else if (strnstr(trip_state->cdev_type,
                                 "light", THERMAL_NAME_LENGTH))
-                       prog_hw_threshold(trip_state, index, THROTTLE_LIGHT);
+                       prog_hw_threshold(trip_state, thz->id, THROTTLE_LIGHT);
        }
 
        /* Allow SW to shutdown at 'Critical temperature reached' */
-       soctherm_update_zone(index);
+       thermal_notify_framework(&thz[thz->id], trip);
 
        /* Reprogram HW thermtrip */
        if (trip_state->trip_type == THERMAL_TRIP_CRITICAL)
-               prog_hw_shutdown(trip_state, index);
+               prog_hw_shutdown(trip_state, thz->id);
 
        return 0;
 }
@@ -1437,14 +1409,12 @@ static int soctherm_set_trip_temp(struct thermal_zone_device *thz,
 static int soctherm_get_crit_temp(struct thermal_zone_device *thz,
                                  unsigned long *temp)
 {
-       int i, index = ((int)thz->devdata) - TSENSE_SIZE;
+       int i;
+       struct soctherm_therm *therm = thz->devdata;
        struct thermal_trip_info *trip_state;
 
-       if (index < 0)
-               return -EINVAL;
-
-       for (i = 0; i < plat_data.therm[index].num_trips; i++) {
-               trip_state = &plat_data.therm[index].trips[i];
+       for (i = 0; i < therm->num_trips; i++) {
+               trip_state = &therm->trips[i];
                if (trip_state->trip_type != THERMAL_TRIP_CRITICAL)
                        continue;
                *temp = trip_state->trip_temp;
@@ -1485,14 +1455,11 @@ static int soctherm_get_trend(struct thermal_zone_device *thz,
                                int trip,
                                enum thermal_trend *trend)
 {
-       int index = ((int)thz->devdata) - TSENSE_SIZE;
+       struct soctherm_therm *therm = thz->devdata;
        struct thermal_trip_info *trip_state;
        long trip_temp;
 
-       if (index < 0)
-               return -EINVAL;
-
-       trip_state = &plat_data.therm[index].trips[trip];
+       trip_state = &therm->trips[trip];
        thz->ops->get_trip_temp(thz, trip, &trip_temp);
 
        switch (trip_state->trip_type) {
@@ -1620,23 +1587,6 @@ static int __init soctherm_thermal_sys_init(void)
        if (!soctherm_init_platform_done)
                return 0;
 
-       for (i = 0; i < TSENSE_SIZE; i++) {
-               if (plat_data.sensor_data[i].zone_enable) {
-                       snprintf(name, THERMAL_NAME_LENGTH,
-                                "%s-tsensor", sensor_names[i]);
-                       /* Create a thermal zone device for each sensor */
-                       thermal_zone_device_register(
-                                       name,
-                                       0,
-                                       0,
-                                       (void *)i,
-                                       &soctherm_ops,
-                                       NULL,
-                                       0,
-                                       0);
-               }
-       }
-
        for (i = 0; i < THERM_SIZE; i++) {
                therm = &plat_data.therm[i];
                if (!therm->zone_enable)
@@ -1664,13 +1614,12 @@ static int __init soctherm_thermal_sys_init(void)
                        }
                }
 
-               snprintf(name, THERMAL_NAME_LENGTH,
-                        "%s-therm", therm_names[i]);
+               snprintf(name, THERMAL_NAME_LENGTH, "%s-therm", therm_names[i]);
                thz[i] = thermal_zone_device_register(
                                        name,
                                        therm->num_trips,
                                        (1ULL << therm->num_trips) - 1,
-                                       (void *)TSENSE_SIZE + i,
+                                       therm,
                                        &soctherm_ops,
                                        therm->tzp,
                                        therm->passive_delay,
@@ -2680,7 +2629,6 @@ static int soctherm_init_platform_data(void)
        for (i = 0; i < TSENSE_SIZE; i++) {
                therm = &plat_data.therm[tsensor2therm_map[i]];
                s = &plat_data.sensor_data[i];
-               s->sensor_enable = s->zone_enable;
                s->sensor_enable = s->sensor_enable ?: therm->zone_enable;
                s->tall      = s->tall      ?: sensor_defaults.tall;
                s->tiddq     = s->tiddq     ?: sensor_defaults.tiddq;
index 17bac5b9c0ebf3f08cabd3bfd30a40891957ac98..336d18abdd9e047ae435818bfbe1d511f0135e31 100644 (file)
@@ -75,7 +75,6 @@ enum soctherm_polarity_id {
 
 struct soctherm_sensor {
        bool sensor_enable;
-       bool zone_enable;
        int tall;
        int tiddq;
        int ten_count;