2 * Copyright (C) 2013 Spreadtrum Communications Inc.
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.
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.
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>
21 #include <linux/thermal.h>
22 #include <linux/sprd_thm.h>
24 #include "linux/delay.h"
26 #include <linux/slab.h>
27 #include <linux/of_device.h>
28 //#include <linux/of_address.h>
29 #include <linux/of_irq.h>
32 struct thm_handle_ops *sprd_thm_handle_ops[SPRD_MAX_SENSOR] = {NULL};
33 char sprd_thm_name[SPRD_MAX_SENSOR][THERMAL_NAME_LENGTH] = {{0},{0}};
34 extern struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
35 extern int thermal_zone_get_temp(struct thermal_zone_device *tz, unsigned long *temp);
36 int sprd_thermal_temp_get(enum sprd_thm_sensor_id thermal_id,unsigned long *temp)
38 char thermal_name[SPRD_MAX_SENSOR][THERMAL_NAME_LENGTH] = {
43 struct thermal_zone_device * tz = thermal_zone_get_zone_by_name(thermal_name[thermal_id]);
46 return thermal_zone_get_temp(tz, temp);
48 EXPORT_SYMBOL(sprd_thermal_temp_get);
50 static int sprd_thm_ops_init(struct sprd_thermal_zone *pzone)
52 if((!sprd_thm_name[pzone->sensor_id]) ||(!sprd_thm_handle_ops[pzone->sensor_id]) )
54 strcpy(pzone->thermal_zone_name,sprd_thm_name[pzone->sensor_id]);
55 pzone->ops = sprd_thm_handle_ops[pzone->sensor_id];
58 int sprd_thm_add(struct thm_handle_ops* ops, char *p,int id)
60 if( (ops == NULL) ||( p == NULL) ||( id > SPRD_MAX_SENSOR - 1))
62 sprd_thm_handle_ops[id] = ops;
63 strcpy(sprd_thm_name[id],p);
66 void sprd_thm_delete(int id)
68 sprd_thm_handle_ops[id] = NULL;
69 strcpy(sprd_thm_name[id],"");
71 static int sprd_thermal_match_cdev(struct thermal_cooling_device *cdev,
72 struct sprd_trip_point *trip_point)
75 if (!strlen(cdev->type))
77 for (i = 0; i < COOLING_DEV_MAX; i++) {
78 if (!strcmp(trip_point->cdev_name[i], cdev->type))
84 /* Callback to bind cooling device to thermal zone */
85 static int sprd_cdev_bind(struct thermal_zone_device *thermal,
86 struct thermal_cooling_device *cdev)
88 struct sprd_thermal_zone *pzone = thermal->devdata;
89 struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
92 printk(KERN_INFO "sprd_cdev_bind--%d \n", pzone->sensor_id);
93 for (i = 0; i < ptrips->num_trips; i++) {
94 if (sprd_thermal_match_cdev(cdev, &ptrips->trip_points[i]))
96 ret = thermal_zone_bind_cooling_device(thermal, i, cdev, THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
97 dev_info(&cdev->device, "%s bind to %d: %d-%s\n", cdev->type,
98 i, ret, ret ? "fail" : "succeed");
103 /* Callback to unbind cooling device from thermal zone */
104 static int sprd_cdev_unbind(struct thermal_zone_device *thermal,
105 struct thermal_cooling_device *cdev)
107 struct sprd_thermal_zone *pzone = thermal->devdata;
108 struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
109 int i, ret = -EINVAL;
111 for (i = 0; i < ptrips->num_trips; i++) {
112 if (sprd_thermal_match_cdev(cdev, &ptrips->trip_points[i]))
114 ret = thermal_zone_unbind_cooling_device(thermal, i, cdev);
115 dev_info(&cdev->device, "%s unbind from %d: %s\n",
116 cdev->type, i, ret ? "fail" : "succeed");
121 /* Callback to get current temperature */
122 static int sprd_sys_get_temp(struct thermal_zone_device *thermal,
125 struct sprd_thermal_zone *pzone = thermal->devdata;
126 if(!pzone->ops->read_temp)
128 *temp = pzone->ops->read_temp(pzone);
132 /* Callback to get thermal zone mode */
133 static int sprd_sys_get_mode(struct thermal_zone_device *thermal,
134 enum thermal_device_mode *mode)
136 struct sprd_thermal_zone *pzone = thermal->devdata;
137 mutex_lock(&pzone->th_lock);
139 mutex_unlock(&pzone->th_lock);
143 /* Callback to set thermal zone mode */
144 static int sprd_sys_set_mode(struct thermal_zone_device *thermal,
145 enum thermal_device_mode mode)
147 struct sprd_thermal_zone *pzone = thermal->devdata;
148 mutex_lock(&pzone->th_lock);
150 if (mode == THERMAL_DEVICE_ENABLED)
151 schedule_work(&pzone->therm_work);
152 mutex_unlock(&pzone->th_lock);
156 static int sprd_sys_get_regs(struct thermal_zone_device *thermal,
159 struct sprd_thermal_zone *pzone = thermal->devdata;
160 if(!pzone->ops->reg_debug_get)
162 return pzone->ops->reg_debug_get(pzone,regs);
165 static int sprd_sys_set_regs(struct thermal_zone_device *thermal,
168 struct sprd_thermal_zone *pzone = thermal->devdata;
169 if(!pzone->ops->reg_debug_set)
171 return pzone->ops->reg_debug_set(pzone,regs);
174 /* Callback to get thermal zone logtime */
175 static int sprd_sys_get_logtime(struct thermal_zone_device *thermal,
176 unsigned long *logtime)
178 struct sprd_thermal_zone *pzone = thermal->devdata;
179 mutex_lock(&pzone->th_lock);
180 *logtime = pzone->logtime;
181 mutex_unlock(&pzone->th_lock);
185 /* Callback to set thermal zone logtime */
186 static int sprd_sys_set_logtime(struct thermal_zone_device *thermal,
187 unsigned long logtime)
189 struct sprd_thermal_zone *pzone = thermal->devdata;
190 mutex_lock(&pzone->th_lock);
191 pzone->logtime = logtime;
192 mutex_unlock(&pzone->th_lock);
196 /* Callback to get thermal log switch status*/
197 static int sprd_sys_get_logswitch(struct thermal_zone_device *thermal,
198 enum thermal_log_switch *logswitch)
200 struct sprd_thermal_zone *pzone = thermal->devdata;
201 mutex_lock(&pzone->th_lock);
202 *logswitch = pzone->thmlog_switch;
203 mutex_unlock(&pzone->th_lock);
207 /* Callback to set thermal log switch status */
208 static int sprd_sys_set_logswitch(struct thermal_zone_device *thermal,
209 enum thermal_log_switch logswitch)
211 struct sprd_thermal_zone *pzone = thermal->devdata;
212 mutex_lock(&pzone->th_lock);
213 pzone->thmlog_switch = logswitch;
214 if (logswitch == THERMAL_LOG_ENABLED)
215 schedule_delayed_work(&pzone->thm_logtime_work, (HZ * pzone->logtime));
216 mutex_unlock(&pzone->th_lock);
222 debug_reg_show(struct device *dev, struct device_attribute *attr, char *buf)
224 struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
226 sprd_sys_get_regs(tz,regs);
227 return sprintf(buf, "DET_PERI=%08x,MON_CTL=%08x,MON_PERI=%08x,SENSOR_CTL=%08x\n",
228 regs[0],regs[1],regs[2],regs[3]);
232 debug_reg_store(struct device *dev, struct device_attribute *attr,
233 const char *buf, size_t count)
235 struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
236 unsigned int regs[4]={0};
237 if (!sscanf(buf, "%x,%x,%x,%x", ®s[0],®s[1],®s[2],®s[3]))
240 printk("%x,%x,%x,%x\n", regs[0],regs[1],regs[2],regs[3]);
241 sprd_sys_set_regs(tz,regs);
244 static DEVICE_ATTR(debug_reg, 0644,debug_reg_show, debug_reg_store);
246 static int sprd_debug_get_trip_temp(struct thermal_zone_device *thermal,
247 int trip, unsigned long *temp,unsigned long *low_off)
249 struct sprd_thermal_zone *pzone = thermal->devdata;
250 struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
251 if (trip >= ptrips->num_trips)
253 *temp = ptrips->trip_points[trip].temp;
254 *low_off = ptrips->trip_points[trip].lowoff;
258 static int sprd_debug_set_trip_temp(struct thermal_zone_device *thermal,
259 int trip, unsigned long temp,unsigned long low_off)
261 struct sprd_thermal_zone *pzone = thermal->devdata;
262 struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
263 if(!pzone->ops->trip_debug_set)
265 ptrips->trip_points[trip].temp = temp;
266 ptrips->trip_points[trip].lowoff = low_off;
267 return pzone->ops->trip_debug_set(pzone,trip);
270 trip_point_debug_temp_show(struct device *dev, struct device_attribute *attr,
273 struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
275 long temperature,low_off;
276 if (!sscanf(attr->attr.name, "trip_%d_temp", &trip))
278 ret = sprd_debug_get_trip_temp(tz, trip, &temperature,&low_off);
282 return sprintf(buf, "tem = %ld,low_off=%ld\n", temperature,low_off);
285 trip_point_debug_temp_store(struct device *dev, struct device_attribute *attr,
286 const char *buf, size_t count)
288 struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
290 unsigned long temperature,low_off;
291 if (!sscanf(attr->attr.name, "trip_%d_temp", &trip))
293 if(!sscanf(buf,"%ld,%ld",&temperature,&low_off))
295 ret = sprd_debug_set_trip_temp(tz, trip, temperature, low_off);
296 return ret ? ret : count;
300 logtime_show(struct device *dev, struct device_attribute *attr, char *buf)
302 //struct thermal_zone_device *tz = to_thermal_zone(dev);
303 struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
304 unsigned long logtime;
306 result = sprd_sys_get_logtime(tz, &logtime);
310 return sprintf(buf, "%ld\n", logtime);
314 logtime_store(struct device *dev, struct device_attribute *attr,
315 const char *buf, size_t count)
317 //struct thermal_zone_device *tz = to_thermal_zone(dev);
318 struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
320 unsigned long logtime;
321 if (kstrtoul(buf, 10, &logtime))
323 result = sprd_sys_set_logtime(tz, logtime);
330 logswitch_show(struct device *dev, struct device_attribute *attr, char *buf)
332 //struct thermal_zone_device *tz = to_thermal_zone(dev);
333 struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
334 enum thermal_log_switch logswtich;
337 result = sprd_sys_get_logswitch(tz, &logswtich);
341 return sprintf(buf, "%s\n", logswtich == THERMAL_LOG_ENABLED ? "enabled"
345 logswitch_store(struct device *dev, struct device_attribute *attr,
346 const char *buf, size_t count)
348 struct thermal_zone_device *tz = container_of(dev, struct thermal_zone_device, device);
351 if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
352 result = sprd_sys_set_logswitch(tz, THERMAL_LOG_ENABLED);
353 else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
354 result = sprd_sys_set_logswitch(tz, THERMAL_LOG_DISABLED);
364 static DEVICE_ATTR(logtime, 0644, logtime_show, logtime_store);
365 static DEVICE_ATTR(logswitch, 0644, logswitch_show, logswitch_store);
367 static int create_trip_attrs(struct thermal_zone_device *tz)
370 int size = sizeof(struct thermal_attr) * tz->trips;
372 result = device_create_file(&tz->device, &dev_attr_logswitch);
375 result = device_create_file(&tz->device, &dev_attr_logtime);
378 tz->trip_temp_attrs = kzalloc(size, GFP_KERNEL);
379 if (!tz->trip_temp_attrs) {
383 for (indx = 0; indx < tz->trips; indx++) {
384 /* create trip temp attribute */
385 snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
386 "trip_%d_temp", indx);
388 sysfs_attr_init(&tz->trip_temp_attrs[indx].attr.attr);
389 tz->trip_temp_attrs[indx].attr.attr.name =
390 tz->trip_temp_attrs[indx].name;
391 tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO;
392 tz->trip_temp_attrs[indx].attr.show = trip_point_debug_temp_show;
393 tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR;
394 tz->trip_temp_attrs[indx].attr.store =trip_point_debug_temp_store;
395 device_create_file(&tz->device,
396 &tz->trip_temp_attrs[indx].attr);
401 static void remove_trip_attrs(struct thermal_zone_device *tz)
404 device_remove_file(&tz->device, &dev_attr_logswitch);
405 device_remove_file(&tz->device, &dev_attr_logtime);
406 for (indx = 0; indx < tz->trips; indx++) {
407 device_remove_file(&tz->device,
408 &tz->trip_temp_attrs[indx].attr);
410 kfree(tz->trip_temp_attrs);
413 static int sprd_sys_get_trend(struct thermal_zone_device *thermal,
414 int trip, enum thermal_trend * ptrend)
416 struct sprd_thermal_zone *pzone = thermal->devdata;
417 return pzone->ops->get_trend(pzone, trip, ptrend);
420 static int sprd_sys_get_hyst(struct thermal_zone_device *thermal,
421 int trip, unsigned long *physt)
423 struct sprd_thermal_zone *pzone = thermal->devdata;
424 return pzone->ops->get_hyst(pzone, trip, physt);
428 /* Callback to get trip point type */
429 static int sprd_sys_get_trip_type(struct thermal_zone_device *thermal,
430 int trip, enum thermal_trip_type *type)
432 struct sprd_thermal_zone *pzone = thermal->devdata;
433 struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
434 if (trip >= ptrips->num_trips)
436 *type = ptrips->trip_points[trip].type;
440 /* Callback to get trip point temperature */
441 static int sprd_sys_get_trip_temp(struct thermal_zone_device *thermal,
442 int trip, unsigned long *temp)
444 struct sprd_thermal_zone *pzone = thermal->devdata;
445 struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
446 if (trip >= ptrips->num_trips)
448 *temp = ptrips->trip_points[trip].temp;
452 /* Callback to get critical trip point temperature */
453 static int sprd_sys_get_crit_temp(struct thermal_zone_device *thermal,
456 struct sprd_thermal_zone *pzone = thermal->devdata;
457 struct sprd_thm_platform_data *ptrips = pzone->trip_tab;
459 for (i = ptrips->num_trips - 1; i > 0; i--) {
460 if (ptrips->trip_points[i].type == THERMAL_TRIP_CRITICAL) {
461 *temp = ptrips->trip_points[i].temp;
468 static struct thermal_zone_device_ops thdev_ops = {
469 .bind = sprd_cdev_bind,
470 .unbind = sprd_cdev_unbind,
471 .get_temp = sprd_sys_get_temp,
472 .get_mode = sprd_sys_get_mode,
473 .set_mode = sprd_sys_set_mode,
474 .get_trip_type = sprd_sys_get_trip_type,
475 .get_trip_temp = sprd_sys_get_trip_temp,
476 .get_trip_hyst = sprd_sys_get_hyst,
477 .get_crit_temp = sprd_sys_get_crit_temp,
478 .get_trend = sprd_sys_get_trend,
481 static irqreturn_t sprd_thm_irq_handler(int irq, void *irq_data)
483 struct sprd_thermal_zone *pzone = irq_data;
485 dev_dbg(&pzone->therm_dev->device, "sprd_thm_irq_handler\n");
486 if (!pzone->ops->irq_handle(pzone)) {
487 schedule_work(&pzone->therm_work);
492 static void sprd_thermal_work(struct work_struct *work)
494 enum thermal_device_mode cur_mode;
495 struct sprd_thermal_zone *pzone;
497 pzone = container_of(work, struct sprd_thermal_zone, therm_work);
498 mutex_lock(&pzone->th_lock);
499 cur_mode = pzone->mode;
500 mutex_unlock(&pzone->th_lock);
501 if (cur_mode == THERMAL_DEVICE_DISABLED)
503 thermal_zone_device_update(pzone->therm_dev);
504 dev_dbg(&pzone->therm_dev->device, "thermal work finished.\n");
507 static void sprd_thermal_resume_delay_work(struct work_struct *work)
509 struct sprd_thermal_zone *pzone;
511 pzone = container_of(work, struct sprd_thermal_zone, resume_delay_work.work);
512 dev_dbg(&pzone->therm_dev->device, "thermal resume delay work Started.\n");
513 pzone->ops->resume(pzone);
514 dev_dbg(&pzone->therm_dev->device, "thermal resume delay work finished.\n");
518 static struct sprd_thm_platform_data *thermal_detect_parse_dt(
521 struct sprd_thm_platform_data *pdata;
522 struct device_node *np = dev->of_node;
523 const char *cooling_names = "cooling-names";
524 const char *point_arr[16];
526 u32 trip_points_critical,trip_num,cool_num;
527 u32 trip_temp[COOLING_DEV_MAX], trip_lowoff[COOLING_DEV_MAX];
528 int i = 0,j=0,cool=1,k;
530 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
532 dev_err(dev, "could not allocate memory for platform data\n");
535 ret = of_property_read_u32(np, "trip_points_critical", &trip_points_critical);
537 dev_err(dev, "fail to get trip_points_critical\n");
540 ret = of_property_read_u32(np, "trip_num", &trip_num);
542 dev_err(dev, "fail to get trip_num\n");
545 ret = of_property_read_u32(np, "cool_num", &cool_num);
551 for (i = 0; i < trip_num-1; i++) {
552 ret = of_property_read_u32_index(np, "trip_points_active", i,
555 dev_err(dev, "fail to get trip_points_active\n");
558 ret = of_property_read_u32_index(np, "trip_points_lowoff", i,
561 dev_err(dev, "fail to get trip_points_lowoff\n");
566 for (j = 0; j < cool_num*(trip_num-1); ++j){
567 ret = of_property_read_string_index(np, cooling_names, j,
570 printk("cooling_names: %s: missing %s in dt node\n", __func__, cooling_names);
572 printk("cooling_names: %s: %s is %s\n", __func__, cooling_names, point_arr[j]);
576 pdata->num_trips = trip_num;
578 for (i = 0; i < trip_num -1; ++i){
579 pdata->trip_points[i].temp = trip_temp[i];
580 pdata->trip_points[i].lowoff = trip_lowoff[i];
581 pdata->trip_points[i].type = THERMAL_TRIP_ACTIVE;
583 for (k = 0; k < cool_num; ++k){
584 memcpy(pdata->trip_points[i].cdev_name[k],
585 point_arr[i+k*(trip_num-1)], strlen(point_arr[i+k*(trip_num-1)])+1);
586 dev_info(dev,"cdev name: %s \n", pdata->trip_points[i].cdev_name[k]);
589 memcpy(pdata->trip_points[i].cdev_name[0],
590 "thermal-cpufreq-0", sizeof("thermal-cpufreq-0"));
591 dev_info(dev, "def cdev name:is %s\n", pdata->trip_points[i].cdev_name[0]);
593 dev_info(dev, "trip[%d] temp: %d lowoff: %d\n",
594 i, trip_temp[i], trip_lowoff[i]);
597 pdata->trip_points[i].temp = trip_points_critical;
598 pdata->trip_points[i].type = THERMAL_TRIP_CRITICAL;
611 extern int of_address_to_resource(struct device_node *dev, int index,
615 static void thm_logtime_work(struct work_struct *work)
617 struct sprd_thermal_zone *pzone;
619 pzone = container_of(work, struct sprd_thermal_zone, thm_logtime_work.work);
620 temp = pzone->ops->read_temp(pzone);
621 printk(" thm sensor id:%d, logtime:%ld, temp:%d\n", pzone->sensor_id,pzone->logtime,temp);
622 if(pzone->thmlog_switch){
623 schedule_delayed_work(&pzone->thm_logtime_work, (HZ * pzone->logtime));
627 static int sprd_thermal_probe(struct platform_device *pdev)
629 struct sprd_thermal_zone *pzone = NULL;
630 struct sprd_thm_platform_data *ptrips = NULL;
631 struct resource *regs;
632 int thm_irq, ret = 0;
634 struct device_node *np = pdev->dev.of_node;
637 printk(KERN_INFO " sprd_thermal_probe id:%d\n", pdev->id);
640 dev_err(&pdev->dev, "device node not found\n");
643 ptrips = thermal_detect_parse_dt(&pdev->dev);
645 ptrips = dev_get_platdata(&pdev->dev);
649 pzone = devm_kzalloc(&pdev->dev, sizeof(*pzone), GFP_KERNEL);
652 mutex_init(&pzone->th_lock);
653 mutex_lock(&pzone->th_lock);
654 pzone->mode = THERMAL_DEVICE_DISABLED;
655 pzone->trip_tab = ptrips;
656 pzone->trend_val = THERMAL_TREND_STABLE;
658 ret = of_property_read_u32(np, "id", &pdev->id);
660 printk(KERN_INFO "sprd_thermal_probe No sensor ID \n");
663 pzone->sensor_id = pdev->id;
665 pzone->sensor_id = pdev->id;
668 pzone->thmlog_switch= THERMAL_LOG_DISABLED;
669 INIT_DELAYED_WORK(&pzone->thm_logtime_work, thm_logtime_work);
670 ret = sprd_thm_ops_init(pzone);
672 dev_err(&pdev->dev, " pzone->ops =NULL id =%d\n",pzone->sensor_id);
675 INIT_WORK(&pzone->therm_work, sprd_thermal_work);
676 INIT_DELAYED_WORK(&pzone->resume_delay_work,sprd_thermal_resume_delay_work);
678 regs = kzalloc(sizeof(*regs), GFP_KERNEL);
679 ret = of_address_to_resource(np, 0, regs);
681 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
686 ret = pzone->ops->get_reg_base(pzone , regs);
688 dev_err(&pdev->dev, "Failed to get_reg_base.\n");
691 printk(KERN_INFO "sprd_thermal_probe id:%d,base:0x%lx \n", pdev->id,
692 (unsigned long)pzone->reg_base);
694 thm_irq = irq_of_parse_and_map(np, 0);
696 thm_irq = platform_get_irq(pdev, 0);
699 dev_err(&pdev->dev, "Get IRQ_THM_INT failed.\n");
703 devm_request_threaded_irq(&pdev->dev, thm_irq, NULL,
704 sprd_thm_irq_handler,
705 IRQF_NO_SUSPEND | IRQF_ONESHOT | IRQF_SHARED,
706 "sprd_thm_irq", pzone);
708 dev_err(&pdev->dev, "Failed to allocate temp low irq.\n");
713 thermal_zone_device_register(pzone->thermal_zone_name,
714 ptrips->num_trips, 0, pzone,
715 &thdev_ops, 0, 0, 0);
716 if (IS_ERR_OR_NULL(pzone->therm_dev)) {
717 dev_err(&pdev->dev, "Register thermal zone device failed.\n");
718 return PTR_ERR(pzone->therm_dev);
720 dev_info(&pdev->dev, "Thermal zone device registered.\n");
722 pzone->ops->hw_init(pzone);
723 platform_set_drvdata(pdev, pzone);
724 pzone->mode = THERMAL_DEVICE_ENABLED;
725 mutex_unlock(&pzone->th_lock);
728 create_trip_attrs(pzone->therm_dev);
729 ret = device_create_file(&pzone->therm_dev->device, &dev_attr_debug_reg);
731 dev_err(&pdev->dev, "create regs debug fail\n");
736 static int sprd_thermal_remove(struct platform_device *pdev)
738 struct sprd_thermal_zone *pzone = platform_get_drvdata(pdev);
740 remove_trip_attrs(pzone->therm_dev);
741 device_remove_file(&pzone->therm_dev->device, &dev_attr_debug_reg);
743 thermal_zone_device_unregister(pzone->therm_dev);
744 cancel_work_sync(&pzone->therm_work);
745 mutex_destroy(&pzone->th_lock);
749 static int sprd_thermal_suspend(struct platform_device *pdev,
752 struct sprd_thermal_zone *pzone = platform_get_drvdata(pdev);
753 flush_work(&pzone->therm_work);
754 flush_delayed_work(&pzone->resume_delay_work);
755 pzone->ops->suspend(pzone);
759 static int sprd_thermal_resume(struct platform_device *pdev)
761 struct sprd_thermal_zone *pzone = platform_get_drvdata(pdev);
762 schedule_delayed_work(&pzone->resume_delay_work, (HZ * 1));
763 //sprd_thm_hw_resume(pzone);
769 static const struct of_device_id thermal_of_match[] = {
770 { .compatible = "sprd,sprd-thermal", },
775 static struct platform_driver sprd_thermal_driver = {
776 .probe = sprd_thermal_probe,
777 .suspend = sprd_thermal_suspend,
778 .resume = sprd_thermal_resume,
779 .remove = sprd_thermal_remove,
781 .owner = THIS_MODULE,
782 .name = "sprd-thermal",
784 .of_match_table = of_match_ptr(thermal_of_match),
788 static int __init sprd_thermal_init(void)
790 return platform_driver_register(&sprd_thermal_driver);
793 static void __exit sprd_thermal_exit(void)
795 platform_driver_unregister(&sprd_thermal_driver);
798 //module_init(sprd_thermal_init);
799 //module_exit(sprd_thermal_exit);
801 device_initcall_sync(sprd_thermal_init);
802 module_exit(sprd_thermal_exit);
803 // module_platform_driver(sprd_thermal_driver);
804 MODULE_AUTHOR("Mingwei Zhang <mingwei.zhang@spreadtrum.com>");
805 MODULE_DESCRIPTION("sprd thermal driver");
806 MODULE_LICENSE("GPL");