thermal: sprd: remove build warnings
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / thermal / sprd_board_thm.c
1 /*
2  * Copyright (C) 2013 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <linux/interrupt.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
18 #include <linux/err.h>
19 #include<linux/string.h>
20 #include <asm/io.h>
21 #include <linux/thermal.h>
22 #include <linux/sprd_thm.h>
23 #include "thm.h"
24 #include "linux/delay.h"
25 #ifdef CONFIG_OF
26 #include <linux/slab.h>
27 #include <linux/of_device.h>
28 //#include <linux/of_address.h>
29 #include <linux/of_irq.h>
30 #endif
31
32 struct thm_handle_ops *sprd_boardthm_handle_ops[SPRD_MAX_SENSOR] = {NULL};
33 char sprd_boardthm_name[SPRD_MAX_SENSOR][THERMAL_NAME_LENGTH] = {{0},{0}};
34
35 static int sprd_thm_ops_init(struct sprd_thermal_zone *pzone)
36 {
37         if((!sprd_boardthm_name[pzone->sensor_id]) ||(!sprd_boardthm_handle_ops[pzone->sensor_id])  )
38                 return  -1;
39         strcpy(pzone->thermal_zone_name,sprd_boardthm_name[pzone->sensor_id]);
40         pzone->ops = sprd_boardthm_handle_ops[pzone->sensor_id];
41         return 0;
42 }
43 int sprd_boardthm_add(struct thm_handle_ops* ops, char *p,int id)
44 {
45         if( (ops == NULL) ||( p == NULL) ||( id > (SPRD_MAX_SENSOR - 1)))
46                 return -1;
47         sprd_boardthm_handle_ops[id] = ops;
48         strcpy(sprd_boardthm_name[id],p);
49         return 0;
50 }
51 void sprd_boardthm_delete(int id)
52 {
53         sprd_boardthm_handle_ops[id] = NULL;
54         strcpy(sprd_boardthm_name[id],"");
55 }
56 static int sprd_thermal_match_cdev(struct thermal_cooling_device *cdev,
57                                    struct sprd_trip_point *trip_point)
58 {
59         int i;
60         if (!strlen(cdev->type))
61                 return -EINVAL;
62         for (i = 0; i < COOLING_DEV_MAX; i++) {
63                 if (!strcmp(trip_point->cdev_name[i], cdev->type))
64                         return 0;
65         }
66         return -ENODEV;
67 }
68
69 /* Callback to bind cooling device to thermal zone */
70 static int sprd_cdev_bind(struct thermal_zone_device *thermal,
71                           struct thermal_cooling_device *cdev)
72 {
73         struct sprd_thermal_zone *pzone = thermal->devdata;
74         struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
75         int i, ret = -EINVAL;
76
77         printk(KERN_INFO "sprd_cdev_bind--%d \n", pzone->sensor_id);
78         for (i = 0; i < ptrips->num_trips; i++) {
79                 if (sprd_thermal_match_cdev(cdev, &ptrips->trip_points[i]))
80                         continue;
81                 ret = thermal_zone_bind_cooling_device(thermal, i, cdev, THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
82                 dev_info(&cdev->device, "%s bind to %d: %d-%s\n", cdev->type,
83                          i, ret, ret ? "fail" : "succeed");
84         }
85         return 0;
86 }
87
88 /* Callback to unbind cooling device from thermal zone */
89 static int sprd_cdev_unbind(struct thermal_zone_device *thermal,
90                             struct thermal_cooling_device *cdev)
91 {
92         struct sprd_thermal_zone *pzone = thermal->devdata;
93         struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
94         int i, ret = -EINVAL;
95
96         for (i = 0; i < ptrips->num_trips; i++) {
97                 if (sprd_thermal_match_cdev(cdev, &ptrips->trip_points[i]))
98                         continue;
99                 ret = thermal_zone_unbind_cooling_device(thermal, i, cdev);
100                 dev_info(&cdev->device, "%s unbind from %d: %s\n",
101                          cdev->type, i, ret ? "fail" : "succeed");
102         }
103         return ret;
104 }
105
106 /* Callback to get current temperature */
107 static int sprd_sys_get_temp(struct thermal_zone_device *thermal,
108                              unsigned long *temp)
109 {
110         struct sprd_thermal_zone *pzone = thermal->devdata;
111         if(!pzone->ops->read_temp)
112                 return -1;
113         *temp = pzone->ops->read_temp(pzone);
114         return 0;
115 }
116
117 /* Callback to get thermal zone mode */
118 static int sprd_sys_get_mode(struct thermal_zone_device *thermal,
119                              enum thermal_device_mode *mode)
120 {
121         struct sprd_thermal_zone *pzone = thermal->devdata;
122         mutex_lock(&pzone->th_lock);
123         *mode = pzone->mode;
124         mutex_unlock(&pzone->th_lock);
125         return 0;
126 }
127
128 /* Callback to set thermal zone mode */
129 static int sprd_sys_set_mode(struct thermal_zone_device *thermal,
130                              enum thermal_device_mode mode)
131 {
132         struct sprd_thermal_zone *pzone = thermal->devdata;
133         mutex_lock(&pzone->th_lock);
134         pzone->mode = mode;
135         if (mode == THERMAL_DEVICE_ENABLED)
136                 schedule_work(&pzone->therm_work);
137         mutex_unlock(&pzone->th_lock);
138         return 0;
139 }
140 #ifdef THM_TEST
141 static int sprd_sys_get_regs(struct thermal_zone_device *thermal,
142                             unsigned  int* regs)
143 {
144         struct sprd_thermal_zone *pzone = thermal->devdata;
145         if(!pzone->ops->reg_debug_get)
146                 return -1;
147         return pzone->ops->reg_debug_get(pzone,regs);
148 }
149
150 static int sprd_sys_set_regs(struct thermal_zone_device *thermal,
151                              unsigned int *regs)
152 {
153         struct sprd_thermal_zone *pzone = thermal->devdata;
154         if(!pzone->ops->reg_debug_set)
155                 return -1;
156         return pzone->ops->reg_debug_set(pzone,regs);
157 }
158
159 static ssize_t
160 debug_reg_show(struct device *dev, struct device_attribute *attr, char *buf)
161 {
162         struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
163         u32 regs[4] = {0};
164         sprd_sys_get_regs(tz,regs);
165         return sprintf(buf, "DET_PERI=%08x,MON_CTL=%08x,MON_PERI=%08x,SENSOR_CTL=%08x\n",
166                 regs[0],regs[1],regs[2],regs[3]);
167 }
168
169 static ssize_t
170 debug_reg_store(struct device *dev, struct device_attribute *attr,
171            const char *buf, size_t count)
172 {
173         struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
174         unsigned int regs[4]={0};
175         if (!sscanf(buf, "%x,%x,%x,%x", &regs[0],&regs[1],&regs[2],&regs[3]))
176                 return -EINVAL;
177
178         printk("%x,%x,%x,%x\n", regs[0],regs[1],regs[2],regs[3]);
179         sprd_sys_set_regs(tz,regs);
180         return count;
181 }
182 static DEVICE_ATTR(debug_reg, 0644,debug_reg_show, debug_reg_store);
183
184 static int sprd_debug_get_trip_temp(struct thermal_zone_device *thermal,
185                                   int trip, unsigned long *temp,unsigned long *low_off)
186 {
187         struct sprd_thermal_zone *pzone = thermal->devdata;
188         struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
189         if (trip >= ptrips->num_trips)
190                 return -EINVAL;
191         *temp = ptrips->trip_points[trip].temp;
192         *low_off = ptrips->trip_points[trip].lowoff;
193         return 0;
194 }
195
196 static int sprd_debug_set_trip_temp(struct thermal_zone_device *thermal,
197                                   int trip, unsigned long temp,unsigned long low_off)
198 {
199         struct sprd_thermal_zone *pzone = thermal->devdata;
200         struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
201         if(!pzone->ops->trip_debug_set)
202                 return 0;
203         ptrips->trip_points[trip].temp = temp;
204         ptrips->trip_points[trip].lowoff = low_off;
205         return pzone->ops->trip_debug_set(pzone,trip);
206 }
207 static ssize_t
208 trip_point_debug_temp_show(struct device *dev, struct device_attribute *attr,
209                      char *buf)
210 {
211         struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
212         int trip, ret;
213         long temperature,low_off;
214         if (!sscanf(attr->attr.name, "trip_%d_temp", &trip))
215                 return -EINVAL;
216         ret = sprd_debug_get_trip_temp(tz, trip, &temperature,&low_off);
217
218         if (ret)
219                 return ret;
220         return sprintf(buf, "tem = %ld,low_off=%ld\n", temperature,low_off);
221 }
222 static ssize_t
223 trip_point_debug_temp_store(struct device *dev, struct device_attribute *attr,
224                      const char *buf, size_t count)
225 {
226         struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
227         int trip, ret;
228         unsigned long temperature,low_off;
229         if (!sscanf(attr->attr.name, "trip_%d_temp", &trip))
230                 return -EINVAL;
231         if(!sscanf(buf,"%ld,%ld",&temperature,&low_off))
232                 return -EINVAL;
233         ret = sprd_debug_set_trip_temp(tz, trip, temperature, low_off);
234         return ret ? ret : count;
235 }
236
237 static int create_trip_attrs(struct thermal_zone_device *tz)
238 {
239         int indx;
240         int size = sizeof(struct thermal_attr) * tz->trips;
241
242         tz->trip_temp_attrs = kzalloc(size, GFP_KERNEL);
243         if (!tz->trip_temp_attrs) {
244                 return -ENOMEM;
245         }
246
247         for (indx = 0; indx < tz->trips; indx++) {
248                 /* create trip temp attribute */
249                 snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
250                          "trip_%d_temp", indx);
251
252                 sysfs_attr_init(&tz->trip_temp_attrs[indx].attr.attr);
253                 tz->trip_temp_attrs[indx].attr.attr.name =
254                                                 tz->trip_temp_attrs[indx].name;
255                 tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO;
256                 tz->trip_temp_attrs[indx].attr.show = trip_point_debug_temp_show;
257                 tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR;
258                 tz->trip_temp_attrs[indx].attr.store =trip_point_debug_temp_store;
259                 device_create_file(&tz->device,
260                                    &tz->trip_temp_attrs[indx].attr);
261         }
262         return 0;
263 }
264
265 static void remove_trip_attrs(struct thermal_zone_device *tz)
266 {
267         int indx;
268         for (indx = 0; indx < tz->trips; indx++) {
269                 device_remove_file(&tz->device,
270                                    &tz->trip_temp_attrs[indx].attr);
271         }
272         kfree(tz->trip_temp_attrs);
273 }
274 #endif
275 /* Callback to get trip point type */
276 static int sprd_sys_get_trip_type(struct thermal_zone_device *thermal,
277                                   int trip, enum thermal_trip_type *type)
278 {
279         struct sprd_thermal_zone *pzone = thermal->devdata;
280         struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
281         if (trip >= ptrips->num_trips)
282                 return -EINVAL;
283         *type = ptrips->trip_points[trip].type;
284         return 0;
285 }
286
287 /* Callback to get trip point temperature */
288 static int sprd_sys_get_trip_temp(struct thermal_zone_device *thermal,
289                                   int trip, unsigned long *temp)
290 {
291         struct sprd_thermal_zone *pzone = thermal->devdata;
292         struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
293         if (trip >= ptrips->num_trips)
294                 return -EINVAL;
295         *temp = ptrips->trip_points[trip].temp;
296         return 0;
297 }
298
299 /* Callback to get critical trip point temperature */
300 static int sprd_sys_get_crit_temp(struct thermal_zone_device *thermal,
301                                   unsigned long *temp)
302 {
303         struct sprd_thermal_zone *pzone = thermal->devdata;
304         struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
305         int i;
306         for (i = ptrips->num_trips - 1; i > 0; i--) {
307                 if (ptrips->trip_points[i].type == THERMAL_TRIP_CRITICAL) {
308                         *temp = ptrips->trip_points[i].temp;
309                         return 0;
310                 }
311         }
312         return -EINVAL;
313 }
314
315 static struct thermal_zone_device_ops thdev_ops = {
316         .bind = sprd_cdev_bind,
317         .unbind = sprd_cdev_unbind,
318         .get_temp = sprd_sys_get_temp,
319         .get_mode = sprd_sys_get_mode,
320         .set_mode = sprd_sys_set_mode,
321         .get_trip_type = sprd_sys_get_trip_type,
322         .get_trip_temp = sprd_sys_get_trip_temp,
323         .get_crit_temp = sprd_sys_get_crit_temp,
324 };
325 #if 0
326 static irqreturn_t sprd_thm_irq_handler(int irq, void *irq_data)
327 {
328         struct sprd_thermal_zone *pzone = irq_data;
329
330         dev_dbg(&pzone->therm_dev->device, "sprd_thm_irq_handler\n");
331         if (!pzone->ops->irq_handle(pzone)) {
332                 schedule_work(&pzone->therm_work);
333         }
334         return IRQ_HANDLED;
335 }
336 #endif
337
338 static void sprd_thermal_work(struct work_struct *work)
339 {
340         enum thermal_device_mode cur_mode;
341         struct sprd_thermal_zone *pzone;
342
343         pzone = container_of(work, struct sprd_thermal_zone, therm_work);
344         mutex_lock(&pzone->th_lock);
345         cur_mode = pzone->mode;
346         mutex_unlock(&pzone->th_lock);
347         if (cur_mode == THERMAL_DEVICE_DISABLED)
348                 return;
349         thermal_zone_device_update(pzone->therm_dev);
350         dev_dbg(&pzone->therm_dev->device, "thermal work finished.\n");
351 }
352
353
354 static void thm_read_work(struct work_struct *work)
355 {
356         struct sprd_thermal_zone *pzone;
357         pzone = container_of(work, struct sprd_thermal_zone, thm_read_work.work);
358     thermal_zone_device_update(pzone->therm_dev);
359     printk("thm sensor id:%d, pzone->temp_inteval:%ld, temp:%d\n", pzone->sensor_id,pzone->temp_inteval,pzone->therm_dev->temperature);
360         schedule_delayed_work(&pzone->thm_read_work, (HZ * pzone->temp_inteval));       
361 }
362
363 static void sprd_thermal_resume_delay_work(struct work_struct *work)
364 {
365         struct sprd_thermal_zone *pzone;
366
367         pzone = container_of(work, struct sprd_thermal_zone, resume_delay_work.work);
368         dev_dbg(&pzone->therm_dev->device, "thermal resume delay work Started.\n");
369         pzone->ops->resume(pzone);
370         dev_dbg(&pzone->therm_dev->device, "thermal resume delay work finished.\n");
371 }
372
373 #ifdef CONFIG_OF
374 static struct sprd_thm_platform_data *thermal_detect_parse_dt(
375                          struct device *dev)
376 {
377         struct sprd_thm_platform_data *pdata;
378         const char *cooling_names = "cooling-names";
379         const char *point_arr[5];
380         int ret;
381         u32 trip_points_critical,trip_num,cool_num;
382         u32 trip_temp[COOLING_DEV_MAX], trip_lowoff[COOLING_DEV_MAX];
383         int i = 0;
384         int j = 0;
385         static int cool=1;
386         struct device_node *np = dev->of_node;
387         
388         pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
389         if (!pdata) {
390                 dev_err(dev, "could not allocate memory for platform data\n");
391                 return NULL;
392         }
393         ret = of_property_read_u32(np, "trip_points_critical", &trip_points_critical);
394         if(ret){
395                 dev_err(dev, "fail to get trip_points_critical\n");
396                 goto fail;
397         }
398         ret = of_property_read_u32(np, "trip_num", &trip_num);
399         if(ret){
400                 dev_err(dev, "fail to get trip_num\n");
401                 goto fail;
402         }
403         ret = of_property_read_u32(np, "cool_num", &cool_num);
404         if(ret){
405                 cool=0;
406         }
407         for (i = 0; i < trip_num-1; i++) {
408                 ret = of_property_read_u32_index(np, "trip_points_active", i,
409                                                  &trip_temp[i]);
410                 if(ret){
411                         dev_err(dev, "fail to get trip_points_active\n");
412                         goto fail;
413                 }
414                 ret = of_property_read_u32_index(np, "trip_points_lowoff", i,
415                                                  &trip_lowoff[i]);
416                 if(ret){
417                         dev_err(dev, "fail to get trip_points_lowoff\n");
418                         goto fail;
419                 }
420         }
421         if(cool==1){
422             for (j = 0; j < cool_num; ++j){
423                         ret = of_property_read_string_index(np, cooling_names, j,
424                                                           &point_arr[j]);
425                         if (ret) {
426                                 printk("cooling_names: missing %s in dt node\n", cooling_names);
427                                 } else {
428                                 printk("cooling_names: %s is %s\n", cooling_names, point_arr[j]);
429                         }
430             }
431         }
432         pdata->num_trips = trip_num;
433     
434         for (i = 0; i < trip_num -1; ++i){
435                         pdata->trip_points[i].temp = trip_temp[i];
436                         pdata->trip_points[i].lowoff = trip_lowoff[i];
437                         pdata->trip_points[i].type = THERMAL_TRIP_ACTIVE;
438                         if(cool==1){
439                                         for (j = 0; j < cool_num; ++j){
440                                         memcpy(pdata->trip_points[i].cdev_name[j],
441                                                         point_arr[j], strlen(point_arr[j])+1);
442                                         dev_info(dev,"cdev name: %s is %s\n", pdata->trip_points[i].cdev_name[j], point_arr[j]);
443                                 }
444                         }
445                         else{
446                                 memcpy(pdata->trip_points[i].cdev_name[0],
447                                         "thermal-cpufreq-0", sizeof("thermal-cpufreq-0"));
448                                 dev_info(dev, "def cdev name:is %s\n",  pdata->trip_points[i].cdev_name[0]);
449                                 
450                         }
451                         dev_info(dev, "trip[%d] temp: %d lowoff: %d\n",
452                                         i, trip_temp[i], trip_lowoff[i]);
453                                 
454         }
455         pdata->trip_points[i].temp = trip_points_critical;
456         pdata->trip_points[i].type = THERMAL_TRIP_CRITICAL;
457
458         return pdata;
459
460 fail:
461         kfree(pdata);
462         return NULL;
463
464 }
465
466 static struct sprd_board_sensor_config *sprdboard_thermal_parse_dt(
467                                                            struct device *dev)
468 {
469     struct sprd_board_sensor_config *pconfig;
470         struct device_node *np = dev->of_node;
471         int ret,i;
472         int temp;
473         int temp_adc_ch,temp_adc_scale,temp_adc_sample_cnt;
474         int temp_table_mode,temp_tab_size,temp_support;
475     
476         pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL);
477         if (!pconfig) {
478                 dev_err(dev, "could not allocate memory for platform data\n");
479                 return NULL;
480         }
481         ret =of_property_read_u32(np, "temp-adc-ch",&temp_adc_ch);
482         if(ret){
483                 dev_err(dev, "sprd_thermal_probe No temp-adc-ch\n");
484                 goto fail;
485         }
486         ret =of_property_read_u32(np, "temp-adc-scale",&temp_adc_scale);
487         if(ret){
488                 dev_err(dev, "sprd_thermal_probe No temp_adc_scale\n");
489                 goto fail;
490         }
491         ret =of_property_read_u32(np, "temp-adc-sample-cnt",&temp_adc_sample_cnt);
492         if(ret){
493                 dev_err(dev, "fail to get temp_adc_sample_cnt\n");
494                 goto fail;
495         }
496         ret =of_property_read_u32(np, "temp-table-mode",&temp_table_mode);
497         if(ret){
498                 dev_err(dev, "fail to get temp_table_mode\n");
499                 goto fail;
500         }
501         ret =of_property_read_u32(np, "temp-tab-size",&temp_tab_size);
502         if(ret){
503                 dev_err(dev, "fail to get  temp_tab_size\n");
504                 goto fail;
505         }
506         ret =of_property_read_u32(np, "temp-support",&temp_support);
507         if(ret){
508                 dev_err(dev, "fail to get temp_support\n");
509                 goto fail;
510         }
511         pconfig->temp_adc_ch=temp_adc_ch;
512         pconfig->temp_adc_sample_cnt=temp_adc_sample_cnt;
513         pconfig->temp_adc_scale=temp_adc_scale;
514         pconfig->temp_table_mode=temp_table_mode;
515         pconfig->temp_support=temp_support;
516         pconfig->temp_tab_size=temp_tab_size;
517         pconfig->temp_tab = kzalloc(sizeof(struct sprdboard_table_data) *
518                                   pconfig->temp_tab_size-1, GFP_KERNEL);
519         for (i = 0; i < pconfig->temp_tab_size-1; i++) {
520                 ret = of_property_read_u32_index(np, "temp-tab-val", i,
521                                                  &pconfig->temp_tab[i].x);
522                 if(ret){
523                         dev_err(dev, "fail to get temp-tab-va\n");
524                         goto fail;
525                 }
526                 ret = of_property_read_u32_index(np, "temp-tab-temp", i, &temp);
527                 if(ret){
528                         dev_err(dev, "fail to get temp-tab-temp\n");
529                         goto fail;
530                 }
531                 pconfig->temp_tab[i].y = temp - 1000;
532         }
533         return pconfig;
534 fail:
535         kfree(pconfig);
536         return NULL;
537         
538 }
539
540 #endif
541
542 #ifdef CONFIG_OF
543 extern int of_address_to_resource(struct device_node *dev, int index,
544                                   struct resource *r);
545 #endif
546
547 static int sprd_thermal_probe(struct platform_device *pdev)
548 {
549         struct sprd_thermal_zone *pzone = NULL;
550         struct sprd_thm_platform_data *ptrips = NULL;
551         struct sprd_board_sensor_config *pconfig = NULL;
552         int ret = 0;
553         int temp_inteval;       
554 #ifdef CONFIG_OF
555         struct device_node *np = pdev->dev.of_node;
556 #endif
557
558         pconfig = devm_kzalloc(&pdev->dev,
559                              sizeof(struct sprd_board_sensor_config),
560                              GFP_KERNEL);
561         printk("sprd_thermal_probe---------start\n");
562
563 #ifdef CONFIG_OF
564         if (!np) {
565                 dev_err(&pdev->dev, "device node not found\n");
566                 return -EINVAL;
567         }
568         pconfig = sprdboard_thermal_parse_dt(&pdev->dev);
569         if (!pconfig)
570                 return -EINVAL;
571         ptrips = thermal_detect_parse_dt(&pdev->dev);
572 #else
573         ptrips = dev_get_platdata(&pdev->dev);
574 #endif
575         if (!ptrips){
576                 kfree(pconfig);
577                 return -EINVAL;
578         }
579         pzone = devm_kzalloc(&pdev->dev, sizeof(*pzone), GFP_KERNEL);
580         if (!pzone){
581                 kfree(pconfig);
582                 kfree(ptrips);
583                 return -ENOMEM;
584         }
585         mutex_init(&pzone->th_lock);
586         mutex_lock(&pzone->th_lock);
587         pzone->mode = THERMAL_DEVICE_DISABLED;
588         pzone->trip_tab = ptrips;
589         pzone->sensor_config= pconfig;
590 #ifdef CONFIG_OF
591         ret = of_property_read_u32(np, "id", &pdev->id);
592     printk(KERN_INFO " sprd_thermal_probe id:%d\n", pdev->id);
593         if(ret){
594                 printk(KERN_INFO "sprd_thermal_probe No sensor ID \n");
595                 return -EINVAL;
596         }
597         pzone->sensor_id = pdev->id;
598 #else
599         pzone->sensor_id = pdev->id;
600 #endif
601     
602         ret = of_property_read_u32(np, "temp_inteval", &temp_inteval);
603     if(ret){
604                 printk(KERN_INFO "sprd_thermal_probe No temp_inteval \n");
605                 return -EINVAL;
606         }
607         pzone->temp_inteval=temp_inteval;
608         ret = sprd_thm_ops_init(pzone);
609         if(ret){
610                 dev_err(&pdev->dev, " pzone->ops =NULL id =%d\n",pzone->sensor_id);
611                 return -ENODEV;
612         }
613         ret=pzone->ops->hw_init(pzone);
614         if(ret){
615                 dev_err(&pdev->dev, " pzone->ops->hw_init error id =%d\n",pzone->sensor_id);
616                 return -ENODEV;
617         }
618         INIT_WORK(&pzone->therm_work, sprd_thermal_work);
619         INIT_DELAYED_WORK(&pzone->thm_read_work, thm_read_work);
620         INIT_DELAYED_WORK(&pzone->resume_delay_work,sprd_thermal_resume_delay_work);
621         pzone->therm_dev =
622             thermal_zone_device_register(pzone->thermal_zone_name,
623                                          ptrips->num_trips, 0, pzone,
624                                          &thdev_ops, 0, 0, 0); 
625         if (IS_ERR_OR_NULL(pzone->therm_dev)) {
626                 dev_err(&pdev->dev, "Register thermal zone device failed.\n");
627                 return PTR_ERR(pzone->therm_dev);
628         }
629         dev_info(&pdev->dev, "Thermal zone device registered.\n");
630         platform_set_drvdata(pdev, pzone);
631         pzone->mode = THERMAL_DEVICE_ENABLED;
632         mutex_unlock(&pzone->th_lock);
633         schedule_delayed_work(&pzone->thm_read_work, (HZ * pzone->temp_inteval));
634
635 #ifdef THM_TEST
636         create_trip_attrs(pzone->therm_dev);    
637         ret = device_create_file(&pzone->therm_dev->device, &dev_attr_debug_reg);
638                 if (ret)
639                         dev_err(&pdev->dev, "create regs debug fail\n");
640 #endif
641     printk("sprd_thermal_probe---------end\n");
642         return 0;
643 }
644
645 static int sprd_thermal_remove(struct platform_device *pdev)
646 {
647         struct sprd_thermal_zone *pzone = platform_get_drvdata(pdev);
648 #ifdef THM_TEST
649         remove_trip_attrs(pzone->therm_dev);
650         device_remove_file(&pzone->therm_dev->device, &dev_attr_debug_reg);
651 #endif
652         thermal_zone_device_unregister(pzone->therm_dev);
653         cancel_work_sync(&pzone->therm_work);
654         cancel_delayed_work_sync(&pzone->thm_read_work);
655         mutex_destroy(&pzone->th_lock);
656         return 0;
657 }
658
659 static int sprd_thermal_suspend(struct platform_device *pdev,
660                                 pm_message_t state)
661 {
662         struct sprd_thermal_zone *pzone = platform_get_drvdata(pdev);
663         flush_work(&pzone->therm_work);
664         flush_delayed_work(&pzone->resume_delay_work);
665         flush_delayed_work(&pzone->thm_read_work);
666         pzone->ops->suspend(pzone);
667         return 0;
668 }
669
670 static int sprd_thermal_resume(struct platform_device *pdev)
671 {
672         struct sprd_thermal_zone *pzone = platform_get_drvdata(pdev);
673         schedule_delayed_work(&pzone->resume_delay_work, (HZ * 1));
674         schedule_delayed_work(&pzone->thm_read_work, (HZ * pzone->temp_inteval));
675         
676         //sprd_thm_hw_resume(pzone);
677
678         return 0;
679 }
680
681 #ifdef CONFIG_OF
682 static const struct of_device_id thermal_of_match[] = {
683         { .compatible = "sprd,board-thermal", },
684        {}
685 };
686 #endif
687
688 static struct platform_driver sprd_thermal_driver = {
689         .probe = sprd_thermal_probe,
690         .suspend = sprd_thermal_suspend,
691         .resume = sprd_thermal_resume,
692         .remove = sprd_thermal_remove,
693         .driver = {
694                    .owner = THIS_MODULE,
695                    .name = "board-thermal",
696 #ifdef CONFIG_OF
697                         .of_match_table = of_match_ptr(thermal_of_match),
698 #endif
699                    },
700 };
701 static int __init sprd_thermal_init(void)
702 {
703         return platform_driver_register(&sprd_thermal_driver);
704 }
705
706 static void __exit sprd_thermal_exit(void)
707 {
708         platform_driver_unregister(&sprd_thermal_driver);
709 }
710
711
712
713 device_initcall_sync(sprd_thermal_init);
714 module_exit(sprd_thermal_exit);
715
716 MODULE_AUTHOR("Mingwei Zhang <mingwei.zhang@spreadtrum.com>");
717 MODULE_DESCRIPTION("sprd thermal sensor driver");
718 MODULE_LICENSE("GPL");