Blame view

drivers/thermal/ti-soc-thermal/ti-thermal-common.c 10.6 KB
445eaf871   Eduardo Valentin   staging: omap-the...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  /*
   * OMAP thermal driver interface
   *
   * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
   * Contact:
   *   Eduardo Valentin <eduardo.valentin@ti.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.
   *
   * 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., 51 Franklin St, Fifth Floor, Boston, MA
   * 02110-1301 USA
   *
   */
  
  #include <linux/device.h>
  #include <linux/err.h>
  #include <linux/mutex.h>
  #include <linux/gfp.h>
  #include <linux/kernel.h>
  #include <linux/workqueue.h>
  #include <linux/thermal.h>
5035d48dd   Eduardo Valentin   staging: omap-the...
31
  #include <linux/cpumask.h>
445eaf871   Eduardo Valentin   staging: omap-the...
32
  #include <linux/cpu_cooling.h>
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
33
  #include <linux/of.h>
445eaf871   Eduardo Valentin   staging: omap-the...
34

7372add4a   Eduardo Valentin   staging: rename o...
35
36
  #include "ti-thermal.h"
  #include "ti-bandgap.h"
445eaf871   Eduardo Valentin   staging: omap-the...
37
38
  
  /* common data structures */
03e859d34   Eduardo Valentin   staging: ti-soc-t...
39
40
  struct ti_thermal_data {
  	struct thermal_zone_device *ti_thermal;
359836e1d   Eduardo Valentin   thermal: ti-soc-t...
41
  	struct thermal_zone_device *pcb_tz;
445eaf871   Eduardo Valentin   staging: omap-the...
42
  	struct thermal_cooling_device *cool_dev;
03e859d34   Eduardo Valentin   staging: ti-soc-t...
43
  	struct ti_bandgap *bgp;
445eaf871   Eduardo Valentin   staging: omap-the...
44
45
46
  	enum thermal_device_mode mode;
  	struct work_struct thermal_wq;
  	int sensor_id;
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
47
  	bool our_zone;
445eaf871   Eduardo Valentin   staging: omap-the...
48
  };
03e859d34   Eduardo Valentin   staging: ti-soc-t...
49
  static void ti_thermal_work(struct work_struct *work)
445eaf871   Eduardo Valentin   staging: omap-the...
50
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
51
52
  	struct ti_thermal_data *data = container_of(work,
  					struct ti_thermal_data, thermal_wq);
445eaf871   Eduardo Valentin   staging: omap-the...
53

0e70f466f   Srinivas Pandruvada   thermal: Enhance ...
54
  	thermal_zone_device_update(data->ti_thermal, THERMAL_EVENT_UNSPECIFIED);
445eaf871   Eduardo Valentin   staging: omap-the...
55

03e859d34   Eduardo Valentin   staging: ti-soc-t...
56
57
58
  	dev_dbg(&data->ti_thermal->device, "updated thermal zone %s
  ",
  		data->ti_thermal->type);
445eaf871   Eduardo Valentin   staging: omap-the...
59
60
61
  }
  
  /**
03e859d34   Eduardo Valentin   staging: ti-soc-t...
62
   * ti_thermal_hotspot_temperature - returns sensor extrapolated temperature
445eaf871   Eduardo Valentin   staging: omap-the...
63
64
65
66
   * @t:	omap sensor temperature
   * @s:	omap sensor slope value
   * @c:	omap sensor const value
   */
03e859d34   Eduardo Valentin   staging: ti-soc-t...
67
  static inline int ti_thermal_hotspot_temperature(int t, int s, int c)
445eaf871   Eduardo Valentin   staging: omap-the...
68
69
70
71
72
73
74
75
76
77
  {
  	int delta = t * s / 1000 + c;
  
  	if (delta < 0)
  		delta = 0;
  
  	return t + delta;
  }
  
  /* thermal zone ops */
e34238bf9   Pavel Machek   cleanup ti-soc-th...
78
  /* Get temperature callback function for thermal zone */
17e8351a7   Sascha Hauer   thermal: consiste...
79
  static inline int __ti_thermal_get_temp(void *devdata, int *temp)
445eaf871   Eduardo Valentin   staging: omap-the...
80
  {
359836e1d   Eduardo Valentin   thermal: ti-soc-t...
81
  	struct thermal_zone_device *pcb_tz = NULL;
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
82
  	struct ti_thermal_data *data = devdata;
03e859d34   Eduardo Valentin   staging: ti-soc-t...
83
  	struct ti_bandgap *bgp;
9879b2c46   Eduardo Valentin   staging: ti-soc-t...
84
  	const struct ti_temp_sensor *s;
359836e1d   Eduardo Valentin   thermal: ti-soc-t...
85
  	int ret, tmp, slope, constant;
17e8351a7   Sascha Hauer   thermal: consiste...
86
  	int pcb_temp;
445eaf871   Eduardo Valentin   staging: omap-the...
87

04a4d10d0   Eduardo Valentin   staging: omap-the...
88
89
  	if (!data)
  		return 0;
d7f080e62   Eduardo Valentin   staging: omap-the...
90
91
  	bgp = data->bgp;
  	s = &bgp->conf->sensors[data->sensor_id];
04a4d10d0   Eduardo Valentin   staging: omap-the...
92

03e859d34   Eduardo Valentin   staging: ti-soc-t...
93
  	ret = ti_bandgap_read_temperature(bgp, data->sensor_id, &tmp);
445eaf871   Eduardo Valentin   staging: omap-the...
94
95
  	if (ret)
  		return ret;
359836e1d   Eduardo Valentin   thermal: ti-soc-t...
96
97
98
99
100
  	/* Default constants */
  	slope = s->slope;
  	constant = s->constant;
  
  	pcb_tz = data->pcb_tz;
445eaf871   Eduardo Valentin   staging: omap-the...
101
  	/* In case pcb zone is available, use the extrapolation rule with it */
0c12b5ac8   Eduardo Valentin   thermal: ti-soc-t...
102
  	if (!IS_ERR(pcb_tz)) {
359836e1d   Eduardo Valentin   thermal: ti-soc-t...
103
104
105
106
107
108
109
110
111
  		ret = thermal_zone_get_temp(pcb_tz, &pcb_temp);
  		if (!ret) {
  			tmp -= pcb_temp; /* got a valid PCB temp */
  			slope = s->slope_pcb;
  			constant = s->constant_pcb;
  		} else {
  			dev_err(bgp->dev,
  				"Failed to read PCB state. Using defaults
  ");
df8f13476   Eduardo Valentin   drivers: thermal:...
112
  			ret = 0;
359836e1d   Eduardo Valentin   thermal: ti-soc-t...
113
  		}
445eaf871   Eduardo Valentin   staging: omap-the...
114
  	}
03e859d34   Eduardo Valentin   staging: ti-soc-t...
115
  	*temp = ti_thermal_hotspot_temperature(tmp, slope, constant);
445eaf871   Eduardo Valentin   staging: omap-the...
116
117
118
  
  	return ret;
  }
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
119
  static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
17e8351a7   Sascha Hauer   thermal: consiste...
120
  				      int *temp)
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
121
122
123
124
125
  {
  	struct ti_thermal_data *data = thermal->devdata;
  
  	return __ti_thermal_get_temp(data, temp);
  }
445eaf871   Eduardo Valentin   staging: omap-the...
126
  /* Bind callback functions for thermal zone */
03e859d34   Eduardo Valentin   staging: ti-soc-t...
127
128
  static int ti_thermal_bind(struct thermal_zone_device *thermal,
  			   struct thermal_cooling_device *cdev)
445eaf871   Eduardo Valentin   staging: omap-the...
129
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
130
  	struct ti_thermal_data *data = thermal->devdata;
5035d48dd   Eduardo Valentin   staging: omap-the...
131
  	int id;
445eaf871   Eduardo Valentin   staging: omap-the...
132

0c12b5ac8   Eduardo Valentin   thermal: ti-soc-t...
133
  	if (!data || IS_ERR(data))
445eaf871   Eduardo Valentin   staging: omap-the...
134
135
136
137
138
139
140
  		return -ENODEV;
  
  	/* check if this is the cooling device we registered */
  	if (data->cool_dev != cdev)
  		return 0;
  
  	id = data->sensor_id;
445eaf871   Eduardo Valentin   staging: omap-the...
141

445eaf871   Eduardo Valentin   staging: omap-the...
142
  	/* Simple thing, two trips, one passive another critical */
a7a3b8c86   Eduardo Valentin   Fix a build error.
143
  	return thermal_zone_bind_cooling_device(thermal, 0, cdev,
67b4c4742   Eduardo Valentin   staging: ti-soc-t...
144
  	/* bind with min and max states defined by cpu_cooling */
a7a3b8c86   Eduardo Valentin   Fix a build error.
145
  						THERMAL_NO_LIMIT,
6cd9e9f62   Kapileshwar Singh   thermal: of: fix ...
146
147
  						THERMAL_NO_LIMIT,
  						THERMAL_WEIGHT_DEFAULT);
445eaf871   Eduardo Valentin   staging: omap-the...
148
149
150
  }
  
  /* Unbind callback functions for thermal zone */
03e859d34   Eduardo Valentin   staging: ti-soc-t...
151
152
  static int ti_thermal_unbind(struct thermal_zone_device *thermal,
  			     struct thermal_cooling_device *cdev)
445eaf871   Eduardo Valentin   staging: omap-the...
153
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
154
  	struct ti_thermal_data *data = thermal->devdata;
445eaf871   Eduardo Valentin   staging: omap-the...
155

0c12b5ac8   Eduardo Valentin   thermal: ti-soc-t...
156
  	if (!data || IS_ERR(data))
445eaf871   Eduardo Valentin   staging: omap-the...
157
158
159
160
161
162
163
164
165
166
167
  		return -ENODEV;
  
  	/* check if this is the cooling device we registered */
  	if (data->cool_dev != cdev)
  		return 0;
  
  	/* Simple thing, two trips, one passive another critical */
  	return thermal_zone_unbind_cooling_device(thermal, 0, cdev);
  }
  
  /* Get mode callback functions for thermal zone */
03e859d34   Eduardo Valentin   staging: ti-soc-t...
168
169
  static int ti_thermal_get_mode(struct thermal_zone_device *thermal,
  			       enum thermal_device_mode *mode)
445eaf871   Eduardo Valentin   staging: omap-the...
170
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
171
  	struct ti_thermal_data *data = thermal->devdata;
445eaf871   Eduardo Valentin   staging: omap-the...
172
173
174
175
176
177
178
179
  
  	if (data)
  		*mode = data->mode;
  
  	return 0;
  }
  
  /* Set mode callback functions for thermal zone */
03e859d34   Eduardo Valentin   staging: ti-soc-t...
180
181
  static int ti_thermal_set_mode(struct thermal_zone_device *thermal,
  			       enum thermal_device_mode mode)
445eaf871   Eduardo Valentin   staging: omap-the...
182
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
183
  	struct ti_thermal_data *data = thermal->devdata;
10ccff1b5   Ranganath Krishnan   thermal: ti-soc-t...
184
185
186
  	struct ti_bandgap *bgp;
  
  	bgp = data->bgp;
445eaf871   Eduardo Valentin   staging: omap-the...
187

03e859d34   Eduardo Valentin   staging: ti-soc-t...
188
  	if (!data->ti_thermal) {
445eaf871   Eduardo Valentin   staging: omap-the...
189
190
191
192
  		dev_notice(&thermal->device, "thermal zone not registered
  ");
  		return 0;
  	}
03e859d34   Eduardo Valentin   staging: ti-soc-t...
193
  	mutex_lock(&data->ti_thermal->lock);
445eaf871   Eduardo Valentin   staging: omap-the...
194
195
  
  	if (mode == THERMAL_DEVICE_ENABLED)
03e859d34   Eduardo Valentin   staging: ti-soc-t...
196
  		data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
445eaf871   Eduardo Valentin   staging: omap-the...
197
  	else
03e859d34   Eduardo Valentin   staging: ti-soc-t...
198
  		data->ti_thermal->polling_delay = 0;
445eaf871   Eduardo Valentin   staging: omap-the...
199

03e859d34   Eduardo Valentin   staging: ti-soc-t...
200
  	mutex_unlock(&data->ti_thermal->lock);
445eaf871   Eduardo Valentin   staging: omap-the...
201
202
  
  	data->mode = mode;
10ccff1b5   Ranganath Krishnan   thermal: ti-soc-t...
203
204
  	ti_bandgap_write_update_interval(bgp, data->sensor_id,
  					data->ti_thermal->polling_delay);
0e70f466f   Srinivas Pandruvada   thermal: Enhance ...
205
  	thermal_zone_device_update(data->ti_thermal, THERMAL_EVENT_UNSPECIFIED);
445eaf871   Eduardo Valentin   staging: omap-the...
206
207
  	dev_dbg(&thermal->device, "thermal polling set for duration=%d msec
  ",
03e859d34   Eduardo Valentin   staging: ti-soc-t...
208
  		data->ti_thermal->polling_delay);
445eaf871   Eduardo Valentin   staging: omap-the...
209
210
211
212
213
  
  	return 0;
  }
  
  /* Get trip type callback functions for thermal zone */
03e859d34   Eduardo Valentin   staging: ti-soc-t...
214
215
  static int ti_thermal_get_trip_type(struct thermal_zone_device *thermal,
  				    int trip, enum thermal_trip_type *type)
445eaf871   Eduardo Valentin   staging: omap-the...
216
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
217
  	if (!ti_thermal_is_valid_trip(trip))
445eaf871   Eduardo Valentin   staging: omap-the...
218
219
220
221
222
223
224
225
226
227
228
  		return -EINVAL;
  
  	if (trip + 1 == OMAP_TRIP_NUMBER)
  		*type = THERMAL_TRIP_CRITICAL;
  	else
  		*type = THERMAL_TRIP_PASSIVE;
  
  	return 0;
  }
  
  /* Get trip temperature callback functions for thermal zone */
03e859d34   Eduardo Valentin   staging: ti-soc-t...
229
  static int ti_thermal_get_trip_temp(struct thermal_zone_device *thermal,
17e8351a7   Sascha Hauer   thermal: consiste...
230
  				    int trip, int *temp)
445eaf871   Eduardo Valentin   staging: omap-the...
231
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
232
  	if (!ti_thermal_is_valid_trip(trip))
445eaf871   Eduardo Valentin   staging: omap-the...
233
  		return -EINVAL;
03e859d34   Eduardo Valentin   staging: ti-soc-t...
234
  	*temp = ti_thermal_get_trip_value(trip);
445eaf871   Eduardo Valentin   staging: omap-the...
235
236
237
  
  	return 0;
  }
e78eaf459   Sascha Hauer   thermal: streamli...
238
  static int __ti_thermal_get_trend(void *p, int trip, enum thermal_trend *trend)
03b7f67bd   J Keerthy   staging: ti-soc-t...
239
  {
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
240
  	struct ti_thermal_data *data = p;
03b7f67bd   J Keerthy   staging: ti-soc-t...
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  	struct ti_bandgap *bgp;
  	int id, tr, ret = 0;
  
  	bgp = data->bgp;
  	id = data->sensor_id;
  
  	ret = ti_bandgap_get_trend(bgp, id, &tr);
  	if (ret)
  		return ret;
  
  	if (tr > 0)
  		*trend = THERMAL_TREND_RAISING;
  	else if (tr < 0)
  		*trend = THERMAL_TREND_DROPPING;
  	else
  		*trend = THERMAL_TREND_STABLE;
  
  	return 0;
  }
e78eaf459   Sascha Hauer   thermal: streamli...
260
261
262
263
264
265
  /* Get the temperature trend callback functions for thermal zone */
  static int ti_thermal_get_trend(struct thermal_zone_device *thermal,
  				int trip, enum thermal_trend *trend)
  {
  	return __ti_thermal_get_trend(thermal->devdata, trip, trend);
  }
445eaf871   Eduardo Valentin   staging: omap-the...
266
  /* Get critical temperature callback functions for thermal zone */
03e859d34   Eduardo Valentin   staging: ti-soc-t...
267
  static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal,
17e8351a7   Sascha Hauer   thermal: consiste...
268
  				    int *temp)
445eaf871   Eduardo Valentin   staging: omap-the...
269
270
  {
  	/* shutdown zone */
03e859d34   Eduardo Valentin   staging: ti-soc-t...
271
  	return ti_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp);
445eaf871   Eduardo Valentin   staging: omap-the...
272
  }
2251aef64   Eduardo Valentin   thermal: of: impr...
273
274
275
276
  static const struct thermal_zone_of_device_ops ti_of_thermal_ops = {
  	.get_temp = __ti_thermal_get_temp,
  	.get_trend = __ti_thermal_get_trend,
  };
03e859d34   Eduardo Valentin   staging: ti-soc-t...
277
278
  static struct thermal_zone_device_ops ti_thermal_ops = {
  	.get_temp = ti_thermal_get_temp,
03b7f67bd   J Keerthy   staging: ti-soc-t...
279
  	.get_trend = ti_thermal_get_trend,
03e859d34   Eduardo Valentin   staging: ti-soc-t...
280
281
282
283
284
285
286
  	.bind = ti_thermal_bind,
  	.unbind = ti_thermal_unbind,
  	.get_mode = ti_thermal_get_mode,
  	.set_mode = ti_thermal_set_mode,
  	.get_trip_type = ti_thermal_get_trip_type,
  	.get_trip_temp = ti_thermal_get_trip_temp,
  	.get_crit_temp = ti_thermal_get_crit_temp,
445eaf871   Eduardo Valentin   staging: omap-the...
287
  };
03e859d34   Eduardo Valentin   staging: ti-soc-t...
288
289
  static struct ti_thermal_data
  *ti_thermal_build_data(struct ti_bandgap *bgp, int id)
445eaf871   Eduardo Valentin   staging: omap-the...
290
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
291
  	struct ti_thermal_data *data;
445eaf871   Eduardo Valentin   staging: omap-the...
292

d7f080e62   Eduardo Valentin   staging: omap-the...
293
  	data = devm_kzalloc(bgp->dev, sizeof(*data), GFP_KERNEL);
445eaf871   Eduardo Valentin   staging: omap-the...
294
  	if (!data) {
d7f080e62   Eduardo Valentin   staging: omap-the...
295
296
  		dev_err(bgp->dev, "kzalloc fail
  ");
04a4d10d0   Eduardo Valentin   staging: omap-the...
297
  		return NULL;
445eaf871   Eduardo Valentin   staging: omap-the...
298
299
  	}
  	data->sensor_id = id;
d7f080e62   Eduardo Valentin   staging: omap-the...
300
  	data->bgp = bgp;
445eaf871   Eduardo Valentin   staging: omap-the...
301
  	data->mode = THERMAL_DEVICE_ENABLED;
0c12b5ac8   Eduardo Valentin   thermal: ti-soc-t...
302
  	/* pcb_tz will be either valid or PTR_ERR() */
359836e1d   Eduardo Valentin   thermal: ti-soc-t...
303
  	data->pcb_tz = thermal_zone_get_zone_by_name("pcb");
03e859d34   Eduardo Valentin   staging: ti-soc-t...
304
  	INIT_WORK(&data->thermal_wq, ti_thermal_work);
445eaf871   Eduardo Valentin   staging: omap-the...
305

04a4d10d0   Eduardo Valentin   staging: omap-the...
306
307
  	return data;
  }
03e859d34   Eduardo Valentin   staging: ti-soc-t...
308
309
  int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
  			     char *domain)
04a4d10d0   Eduardo Valentin   staging: omap-the...
310
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
311
  	struct ti_thermal_data *data;
04a4d10d0   Eduardo Valentin   staging: omap-the...
312

03e859d34   Eduardo Valentin   staging: ti-soc-t...
313
  	data = ti_bandgap_get_sensor_data(bgp, id);
04a4d10d0   Eduardo Valentin   staging: omap-the...
314

0c12b5ac8   Eduardo Valentin   thermal: ti-soc-t...
315
  	if (!data || IS_ERR(data))
03e859d34   Eduardo Valentin   staging: ti-soc-t...
316
  		data = ti_thermal_build_data(bgp, id);
04a4d10d0   Eduardo Valentin   staging: omap-the...
317
318
319
  
  	if (!data)
  		return -EINVAL;
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
320
  	/* in case this is specified by DT */
3982204cc   Eduardo Valentin   thermal: convert ...
321
  	data->ti_thermal = devm_thermal_zone_of_sensor_register(bgp->dev, id,
2251aef64   Eduardo Valentin   thermal: of: impr...
322
  					data, &ti_of_thermal_ops);
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
323
324
325
  	if (IS_ERR(data->ti_thermal)) {
  		/* Create thermal zone */
  		data->ti_thermal = thermal_zone_device_register(domain,
03e859d34   Eduardo Valentin   staging: ti-soc-t...
326
  				OMAP_TRIP_NUMBER, 0, data, &ti_thermal_ops,
50125a9b2   Durgadoss R   Thermal: Pass zon...
327
  				NULL, FAST_TEMP_MONITORING_RATE,
765a1939a   Eduardo Valentin   staging: omap-the...
328
  				FAST_TEMP_MONITORING_RATE);
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
329
330
331
332
333
334
335
  		if (IS_ERR(data->ti_thermal)) {
  			dev_err(bgp->dev, "thermal zone device is NULL
  ");
  			return PTR_ERR(data->ti_thermal);
  		}
  		data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
  		data->our_zone = true;
445eaf871   Eduardo Valentin   staging: omap-the...
336
  	}
03e859d34   Eduardo Valentin   staging: ti-soc-t...
337
  	ti_bandgap_set_sensor_data(bgp, id, data);
10ccff1b5   Ranganath Krishnan   thermal: ti-soc-t...
338
339
  	ti_bandgap_write_update_interval(bgp, data->sensor_id,
  					data->ti_thermal->polling_delay);
445eaf871   Eduardo Valentin   staging: omap-the...
340
341
342
  
  	return 0;
  }
03e859d34   Eduardo Valentin   staging: ti-soc-t...
343
  int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id)
445eaf871   Eduardo Valentin   staging: omap-the...
344
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
345
  	struct ti_thermal_data *data;
445eaf871   Eduardo Valentin   staging: omap-the...
346

03e859d34   Eduardo Valentin   staging: ti-soc-t...
347
  	data = ti_bandgap_get_sensor_data(bgp, id);
445eaf871   Eduardo Valentin   staging: omap-the...
348

26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
349
350
351
  	if (data && data->ti_thermal) {
  		if (data->our_zone)
  			thermal_zone_device_unregister(data->ti_thermal);
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
352
  	}
445eaf871   Eduardo Valentin   staging: omap-the...
353
354
355
  
  	return 0;
  }
03e859d34   Eduardo Valentin   staging: ti-soc-t...
356
  int ti_thermal_report_sensor_temperature(struct ti_bandgap *bgp, int id)
445eaf871   Eduardo Valentin   staging: omap-the...
357
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
358
  	struct ti_thermal_data *data;
445eaf871   Eduardo Valentin   staging: omap-the...
359

03e859d34   Eduardo Valentin   staging: ti-soc-t...
360
  	data = ti_bandgap_get_sensor_data(bgp, id);
445eaf871   Eduardo Valentin   staging: omap-the...
361
362
363
364
365
  
  	schedule_work(&data->thermal_wq);
  
  	return 0;
  }
03e859d34   Eduardo Valentin   staging: ti-soc-t...
366
  int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
445eaf871   Eduardo Valentin   staging: omap-the...
367
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
368
  	struct ti_thermal_data *data;
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
369
370
371
372
373
374
375
376
377
  	struct device_node *np = bgp->dev->of_node;
  
  	/*
  	 * We are assuming here that if one deploys the zone
  	 * using DT, then it must be aware that the cooling device
  	 * loading has to happen via cpufreq driver.
  	 */
  	if (of_find_property(np, "#thermal-sensor-cells", NULL))
  		return 0;
445eaf871   Eduardo Valentin   staging: omap-the...
378

03e859d34   Eduardo Valentin   staging: ti-soc-t...
379
  	data = ti_bandgap_get_sensor_data(bgp, id);
0c12b5ac8   Eduardo Valentin   thermal: ti-soc-t...
380
  	if (!data || IS_ERR(data))
03e859d34   Eduardo Valentin   staging: ti-soc-t...
381
  		data = ti_thermal_build_data(bgp, id);
04a4d10d0   Eduardo Valentin   staging: omap-the...
382
383
384
  
  	if (!data)
  		return -EINVAL;
445eaf871   Eduardo Valentin   staging: omap-the...
385

445eaf871   Eduardo Valentin   staging: omap-the...
386
  	/* Register cooling device */
5035d48dd   Eduardo Valentin   staging: omap-the...
387
  	data->cool_dev = cpufreq_cooling_register(cpu_present_mask);
0c12b5ac8   Eduardo Valentin   thermal: ti-soc-t...
388
  	if (IS_ERR(data->cool_dev)) {
cffafc324   Eduardo Valentin   thermal: ti-soc-t...
389
390
391
392
393
394
395
396
397
  		int ret = PTR_ERR(data->cool_dev);
  
  		if (ret != -EPROBE_DEFER)
  			dev_err(bgp->dev,
  				"Failed to register cpu cooling device %d
  ",
  				ret);
  
  		return ret;
445eaf871   Eduardo Valentin   staging: omap-the...
398
  	}
03e859d34   Eduardo Valentin   staging: ti-soc-t...
399
  	ti_bandgap_set_sensor_data(bgp, id, data);
445eaf871   Eduardo Valentin   staging: omap-the...
400
401
402
  
  	return 0;
  }
03e859d34   Eduardo Valentin   staging: ti-soc-t...
403
  int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id)
445eaf871   Eduardo Valentin   staging: omap-the...
404
  {
03e859d34   Eduardo Valentin   staging: ti-soc-t...
405
  	struct ti_thermal_data *data;
445eaf871   Eduardo Valentin   staging: omap-the...
406

03e859d34   Eduardo Valentin   staging: ti-soc-t...
407
  	data = ti_bandgap_get_sensor_data(bgp, id);
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
408

9ca9be2b0   Markus Elfring   ti-soc-thermal: D...
409
  	if (data)
26d9cc65f   Eduardo Valentin   thermal: ti-soc-t...
410
  		cpufreq_cooling_unregister(data->cool_dev);
445eaf871   Eduardo Valentin   staging: omap-the...
411
412
413
  
  	return 0;
  }