summaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorLeo Yan <leo.yan@linaro.org>2016-03-29 07:27:12 -0400
committerEduardo Valentin <edubezval@gmail.com>2016-05-17 10:28:30 -0400
commit439dc96811739ad5440143140fe92df5140daf11 (patch)
treeb667a15530a31336df60443bd39ae609b5c2b83e /drivers/thermal
parent13849883475408272aaddcea00052bd9f4d9b4ca (diff)
thermal: hisilicon: support to use any sensor
In current code sensor driver registers all 4 sensors together and if any of them has not bound to thermal zone successfully then driver will return failure for driver's initialization. As a result, if DT binds thermal zone with only one sensor, then the thermal driver will not work well anymore. So this patch is to fix this issue. It allows the thermal sensor driver can register any number sensors at initialization phase, and fix up code for other related code to skip related sensor's accessing if the sensor has not been enabled in initialization phase. Signed-off-by: Leo Yan <leo.yan@linaro.org> Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/hisi_thermal.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index aee88bd3a5b6..d3bdbaf0bf13 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -160,7 +160,7 @@ static int hisi_thermal_get_temp(void *_sensor, int *temp)
160 struct hisi_thermal_sensor *sensor = _sensor; 160 struct hisi_thermal_sensor *sensor = _sensor;
161 struct hisi_thermal_data *data = sensor->thermal; 161 struct hisi_thermal_data *data = sensor->thermal;
162 162
163 int sensor_id = 0, i; 163 int sensor_id = -1, i;
164 long max_temp = 0; 164 long max_temp = 0;
165 165
166 *temp = hisi_thermal_get_sensor_temp(data, sensor); 166 *temp = hisi_thermal_get_sensor_temp(data, sensor);
@@ -168,12 +168,19 @@ static int hisi_thermal_get_temp(void *_sensor, int *temp)
168 sensor->sensor_temp = *temp; 168 sensor->sensor_temp = *temp;
169 169
170 for (i = 0; i < HISI_MAX_SENSORS; i++) { 170 for (i = 0; i < HISI_MAX_SENSORS; i++) {
171 if (!data->sensors[i].tzd)
172 continue;
173
171 if (data->sensors[i].sensor_temp >= max_temp) { 174 if (data->sensors[i].sensor_temp >= max_temp) {
172 max_temp = data->sensors[i].sensor_temp; 175 max_temp = data->sensors[i].sensor_temp;
173 sensor_id = i; 176 sensor_id = i;
174 } 177 }
175 } 178 }
176 179
180 /* If no sensor has been enabled, then skip to enable irq */
181 if (sensor_id == -1)
182 return 0;
183
177 mutex_lock(&data->thermal_lock); 184 mutex_lock(&data->thermal_lock);
178 data->irq_bind_sensor = sensor_id; 185 data->irq_bind_sensor = sensor_id;
179 mutex_unlock(&data->thermal_lock); 186 mutex_unlock(&data->thermal_lock);
@@ -226,8 +233,12 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev)
226 sensor->thres_temp / 1000); 233 sensor->thres_temp / 1000);
227 mutex_unlock(&data->thermal_lock); 234 mutex_unlock(&data->thermal_lock);
228 235
229 for (i = 0; i < HISI_MAX_SENSORS; i++) 236 for (i = 0; i < HISI_MAX_SENSORS; i++) {
237 if (!data->sensors[i].tzd)
238 continue;
239
230 thermal_zone_device_update(data->sensors[i].tzd); 240 thermal_zone_device_update(data->sensors[i].tzd);
241 }
231 242
232 return IRQ_HANDLED; 243 return IRQ_HANDLED;
233} 244}
@@ -247,6 +258,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
247 sensor->id, sensor, &hisi_of_thermal_ops); 258 sensor->id, sensor, &hisi_of_thermal_ops);
248 if (IS_ERR(sensor->tzd)) { 259 if (IS_ERR(sensor->tzd)) {
249 ret = PTR_ERR(sensor->tzd); 260 ret = PTR_ERR(sensor->tzd);
261 sensor->tzd = NULL;
250 dev_err(&pdev->dev, "failed to register sensor id %d: %d\n", 262 dev_err(&pdev->dev, "failed to register sensor id %d: %d\n",
251 sensor->id, ret); 263 sensor->id, ret);
252 return ret; 264 return ret;
@@ -334,25 +346,17 @@ static int hisi_thermal_probe(struct platform_device *pdev)
334 for (i = 0; i < HISI_MAX_SENSORS; ++i) { 346 for (i = 0; i < HISI_MAX_SENSORS; ++i) {
335 ret = hisi_thermal_register_sensor(pdev, data, 347 ret = hisi_thermal_register_sensor(pdev, data,
336 &data->sensors[i], i); 348 &data->sensors[i], i);
337 if (ret) { 349 if (ret)
338 dev_err(&pdev->dev, 350 dev_err(&pdev->dev,
339 "failed to register thermal sensor: %d\n", ret); 351 "failed to register thermal sensor: %d\n", ret);
340 goto err_get_sensor_data; 352 else
341 } 353 hisi_thermal_toggle_sensor(&data->sensors[i], true);
342 } 354 }
343 355
344 hisi_thermal_enable_bind_irq_sensor(data); 356 hisi_thermal_enable_bind_irq_sensor(data);
345 data->irq_enabled = true; 357 data->irq_enabled = true;
346 358
347 for (i = 0; i < HISI_MAX_SENSORS; i++)
348 hisi_thermal_toggle_sensor(&data->sensors[i], true);
349
350 return 0; 359 return 0;
351
352err_get_sensor_data:
353 clk_disable_unprepare(data->clk);
354
355 return ret;
356} 360}
357 361
358static int hisi_thermal_remove(struct platform_device *pdev) 362static int hisi_thermal_remove(struct platform_device *pdev)
@@ -363,6 +367,9 @@ static int hisi_thermal_remove(struct platform_device *pdev)
363 for (i = 0; i < HISI_MAX_SENSORS; i++) { 367 for (i = 0; i < HISI_MAX_SENSORS; i++) {
364 struct hisi_thermal_sensor *sensor = &data->sensors[i]; 368 struct hisi_thermal_sensor *sensor = &data->sensors[i];
365 369
370 if (!sensor->tzd)
371 continue;
372
366 hisi_thermal_toggle_sensor(sensor, false); 373 hisi_thermal_toggle_sensor(sensor, false);
367 } 374 }
368 375