summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra11_soctherm.c
diff options
context:
space:
mode:
authorDiwakar Tundlam <dtundlam@nvidia.com>2014-03-24 14:49:35 -0700
committerDiwakar Tundlam <dtundlam@nvidia.com>2014-03-24 17:20:32 -0700
commite014eff738f9598812e3105958bdc6e173db9285 (patch)
treec9835a61b6fcccdf7cbaa6672281084b9c10278e /arch/arm/mach-tegra/tegra11_soctherm.c
parentd9c42e5bc506d92c0417b61fb906289398afeda4 (diff)
arm: tegra: soctherm: fix pointer misuse in zoneid
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
Diffstat (limited to 'arch/arm/mach-tegra/tegra11_soctherm.c')
-rw-r--r--arch/arm/mach-tegra/tegra11_soctherm.c176
1 files changed, 62 insertions, 114 deletions
diff --git a/arch/arm/mach-tegra/tegra11_soctherm.c b/arch/arm/mach-tegra/tegra11_soctherm.c
index 6bd0dc1ec2ef..01b533460773 100644
--- a/arch/arm/mach-tegra/tegra11_soctherm.c
+++ b/arch/arm/mach-tegra/tegra11_soctherm.c
@@ -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;