cadc4afd00f7501448d557db074b8f01261fbab5
[linux-3.10.git] / drivers / misc / nct1008.c
1 /*
2  * drivers/misc/nct1008.c
3  *
4  * Driver for NCT1008, temperature monitoring device from ON Semiconductors
5  *
6  * Copyright (c) 2010-2014, NVIDIA CORPORATION.  All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23
24 #include <linux/interrupt.h>
25 #include <linux/module.h>
26 #include <linux/i2c.h>
27 #include <linux/slab.h>
28 #include <linux/err.h>
29 #include <linux/gpio.h>
30 #include <linux/device.h>
31 #include <linux/nct1008.h>
32 #include <linux/of_gpio.h>
33 #include <linux/delay.h>
34 #include <linux/thermal.h>
35 #include <linux/regulator/consumer.h>
36
37 /* Register Addresses used in this module. */
38 #define LOC_TEMP_RD                  0x00
39 #define EXT_TEMP_HI_RD               0x01
40 #define STATUS_RD                    0x02
41 #define CONFIG_RD                    0x03
42 #define CONV_RATE_RD                 0x04
43 #define LOC_TEMP_HI_LIMIT_RD         0x05
44 #define LOC_TEMP_LO_LIMIT_RD         0x06
45 #define EXT_TEMP_HI_LIMIT_HI_BYTE_RD 0x07
46 #define EXT_TEMP_LO_LIMIT_HI_BYTE_RD 0x08
47 #define CONFIG_WR                    0x09
48 #define CONV_RATE_WR                 0x0A
49 #define LOC_TEMP_HI_LIMIT_WR         0x0B
50 #define LOC_TEMP_LO_LIMIT_WR         0x0C
51 #define EXT_TEMP_HI_LIMIT_HI_BYTE_WR 0x0D
52 #define EXT_TEMP_LO_LIMIT_HI_BYTE_WR 0x0E
53 #define ONE_SHOT                     0x0F
54 #define EXT_TEMP_LO_RD               0x10
55 #define OFFSET_WR                    0x11
56 #define OFFSET_QUARTER_WR            0x12
57 #define EXT_TEMP_HI_LIMIT_LO_BYTE    0x13
58 #define EXT_TEMP_LO_LIMIT_LO_BYTE    0x14
59 /* NOT USED                          0x15 */
60 /* NOT USED                          0x16 */
61 /* NOT USED                          0x17 */
62 /* NOT USED                          0x18 */
63 #define EXT_THERM_LIMIT_WR           0x19
64 /* NOT USED                          0x1A */
65 /* NOT USED                          0x1B */
66 /* NOT USED                          0x1C */
67 /* NOT USED                          0x1D */
68 /* NOT USED                          0x1E */
69 /* NOT USED                          0x1F */
70 #define LOC_THERM_LIMIT              0x20
71 #define THERM_HYSTERESIS             0x21
72 #define COSECUTIVE_ALERT             0x22
73
74 /* Set of register types that are sensor dependant. */
75 enum nct1008_sensor_reg_types {
76         TEMP_HI_LIMIT, TEMP_LO_LIMIT,
77         TEMP_HI_LIMIT_RD, TEMP_LO_LIMIT_RD,
78         TEMP_HI_LIMIT_WR, TEMP_LO_LIMIT_WR,
79         TEMP_RD_LO, TEMP_RD_HI,
80         TEMP_RD, TEMP_WR,
81         REGS_COUNT /* This has to be the last element! */
82 };
83
84 /* Mapping from register type on a given sensor to hardware specific address. */
85 static int nct1008_sensor_regs[SENSORS_COUNT][REGS_COUNT] = {
86         [LOC] = {
87                 [TEMP_HI_LIMIT_RD] = LOC_TEMP_HI_LIMIT_RD,
88                 [TEMP_HI_LIMIT_WR] = LOC_TEMP_HI_LIMIT_WR,
89                 [TEMP_LO_LIMIT_RD] = LOC_TEMP_LO_LIMIT_RD,
90                 [TEMP_LO_LIMIT_WR] = LOC_TEMP_LO_LIMIT_WR,
91         },
92         [EXT] = {
93                 [TEMP_HI_LIMIT_RD] = EXT_TEMP_HI_LIMIT_HI_BYTE_RD,
94                 [TEMP_HI_LIMIT_WR] = EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
95                 [TEMP_LO_LIMIT_RD] = EXT_TEMP_LO_LIMIT_HI_BYTE_RD,
96                 [TEMP_LO_LIMIT_WR] = EXT_TEMP_LO_LIMIT_HI_BYTE_WR,
97                 [TEMP_RD_LO] = EXT_TEMP_LO_RD,
98                 [TEMP_RD_HI] = EXT_TEMP_HI_RD,
99         },
100 };
101
102 /* Accessor to the sensor specific registers. */
103 #define NCT_REG(x, y) nct1008_sensor_regs[x][y]
104
105 /* Configuration register bits. */
106 #define EXTENDED_RANGE_BIT BIT(2)
107 #define THERM2_BIT         BIT(5)
108 #define STANDBY_BIT        BIT(6)
109 #define ALERT_BIT          BIT(7)
110
111 /* Status register trip point bits. */
112 #define EXT_LO_BIT BIT(3) /* External Sensor has tripped 'temp <= LOW' */
113 #define EXT_HI_BIT BIT(4) /* External Sensor has tripped 'temp > HIGH' */
114 #define LOC_LO_BIT BIT(5) /* Local Sensor has tripped 'temp <= LOW' */
115 #define LOC_HI_BIT BIT(6) /* Local Sensor has tripped 'temp > HIGH' */
116
117 /* Constants.  */
118 #define EXTENDED_RANGE_OFFSET 64U
119 #define STANDARD_RANGE_MAX    127U
120 #define EXTENDED_RANGE_MAX   (150U + EXTENDED_RANGE_OFFSET)
121
122 #define NCT1008_MIN_TEMP       (-64)
123 #define NCT1008_MAX_TEMP         191
124 #define NCT1008_MAX_TEMP_MILLI   191750
125
126 #define MAX_STR_PRINT            50
127 #define MAX_CONV_TIME_ONESHOT_MS 52
128
129 #define CELSIUS_TO_MILLICELSIUS(x) ((x)*1000)
130 #define MILLICELSIUS_TO_CELSIUS(x) ((x)/1000)
131
132 struct nct1008_adjust_offset_table {
133         int temp;
134         int offset;
135 };
136
137 struct nct1008_sensor_data {
138         struct nct1008_adjust_offset_table offset_table[16];
139         struct thermal_zone_device *thz;
140         long current_hi_limit;
141         long current_lo_limit;
142         int temp;
143 };
144
145 struct nct1008_data {
146         struct workqueue_struct *workqueue;
147         struct work_struct work;
148         struct i2c_client *client;
149         struct nct1008_platform_data plat_data;
150         struct mutex mutex;
151         u8 config;
152         enum nct1008_chip chip;
153         struct regulator *nct_reg;
154         int conv_period_ms;
155         int nct_disabled;
156         int stop_workqueue;
157
158         struct nct1008_sensor_data sensors[SENSORS_COUNT];
159 };
160
161 static int conv_period_ms_table[] =
162         {16000, 8000, 4000, 2000, 1000, 500, 250, 125, 63, 32, 16};
163
164 static void nct1008_setup_shutdown_warning(struct nct1008_data *data);
165
166 static inline s16 value_to_temperature(bool extended, u8 value)
167 {
168         return extended ? (s16)(value - EXTENDED_RANGE_OFFSET) : (s16)value;
169 }
170
171 static inline u8 temperature_to_value(bool extended, s16 temp)
172 {
173         return extended ? (u8)(temp + EXTENDED_RANGE_OFFSET) : (u8)temp;
174 }
175
176 static int nct1008_write_reg(struct i2c_client *client, u8 reg, u16 value)
177 {
178         int ret = 0;
179         struct nct1008_data *data = i2c_get_clientdata(client);
180
181         mutex_lock(&data->mutex);
182         if (data && data->nct_disabled) {
183                 mutex_unlock(&data->mutex);
184                 return -ENODEV;
185         }
186
187         ret = i2c_smbus_write_byte_data(client, reg, value);
188         mutex_unlock(&data->mutex);
189
190         if (ret < 0)
191                 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
192
193         return ret;
194 }
195
196 static int nct1008_read_reg(struct i2c_client *client, u8 reg)
197 {
198         int ret = 0;
199         struct nct1008_data *data = i2c_get_clientdata(client);
200         mutex_lock(&data->mutex);
201         if (data && data->nct_disabled) {
202                 mutex_unlock(&data->mutex);
203                 return -ENODEV;
204         }
205
206         ret = i2c_smbus_read_byte_data(client, reg);
207         mutex_unlock(&data->mutex);
208
209         if (ret < 0)
210                 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
211
212         return ret;
213 }
214
215 static int nct1008_get_temp_common(int sensor,
216                                         struct nct1008_data *data,
217                                         long *temp)
218 {
219         struct i2c_client *client = data->client;
220         struct nct1008_platform_data *pdata = client->dev.platform_data;
221         struct nct1008_sensor_data *sensorp;
222         s16 temp_hi;
223         s16 temp_lo;
224         long temp_milli = 0;
225         int i, off = 0;
226         u8 value;
227         int ret;
228
229         if (!((sensor == EXT) || (sensor == LOC)))
230                 return -1;
231
232         /* Read External Temp */
233         if (sensor == EXT) {
234                 ret = nct1008_read_reg(client, NCT_REG(sensor, TEMP_RD_LO));
235                 if (ret < 0)
236                         return -1;
237                 else
238                         value = ret;
239
240                 temp_lo = (value >> 6);
241
242                 ret = nct1008_read_reg(client, EXT_TEMP_HI_RD);
243                 if (ret < 0)
244                         return -1;
245                 else
246                         value = ret;
247
248                 temp_hi = value_to_temperature(pdata->extended_range, value);
249                 temp_milli = CELSIUS_TO_MILLICELSIUS(temp_hi) + temp_lo * 250;
250
251                 sensorp = &data->sensors[sensor];
252                 for (i = 0; i < ARRAY_SIZE(sensorp->offset_table); i++) {
253                         if (temp_milli <
254                                 (sensorp->offset_table[i].temp * 1000)) {
255                                 off = sensorp->offset_table[i].offset * 1000;
256                                 break;
257                         }
258                 }
259
260                 temp_milli += off;
261
262         } else if (sensor == LOC) {
263                 value = nct1008_read_reg(client, LOC_TEMP_RD);
264                 if (value < 0)
265                         return -1;
266                 temp_hi = value_to_temperature(pdata->extended_range, value);
267                 temp_milli = CELSIUS_TO_MILLICELSIUS(temp_hi);
268         }
269
270         if (temp_milli > NCT1008_MAX_TEMP_MILLI)
271                 return -1;
272
273         *temp = temp_milli;
274         data->sensors[sensor].temp = temp_milli;
275
276         return 0;
277 }
278
279 static ssize_t nct1008_show_temp(struct device *dev,
280         struct device_attribute *attr, char *buf)
281 {
282         struct i2c_client *client = to_i2c_client(dev);
283         struct nct1008_platform_data *pdata = client->dev.platform_data;
284         s16 temp1 = 0;
285         s16 temp = 0;
286         u8 temp2 = 0;
287         int value = 0;
288
289         if (!dev || !buf || !attr)
290                 return -EINVAL;
291
292         value = nct1008_read_reg(client, LOC_TEMP_RD);
293         if (value < 0)
294                 goto error;
295         temp1 = value_to_temperature(pdata->extended_range, value);
296
297         value = nct1008_read_reg(client, EXT_TEMP_LO_RD);
298         if (value < 0)
299                 goto error;
300         temp2 = (value >> 6);
301         value = nct1008_read_reg(client, EXT_TEMP_HI_RD);
302         if (value < 0)
303                 goto error;
304         temp = value_to_temperature(pdata->extended_range, value);
305
306         return snprintf(buf, MAX_STR_PRINT, "%d %d.%d\n",
307                 temp1, temp, temp2 * 25);
308
309 error:
310         return snprintf(buf, MAX_STR_PRINT,
311                 "Error read local/ext temperature\n");
312 }
313
314 static ssize_t nct1008_show_temp_overheat(struct device *dev,
315                                 struct device_attribute *attr,
316                                 char *buf)
317 {
318         struct i2c_client *client = to_i2c_client(dev);
319         struct nct1008_platform_data *pdata = client->dev.platform_data;
320         int value;
321         s16 temp, temp2;
322
323         /* Local temperature h/w shutdown limit */
324         value = nct1008_read_reg(client, LOC_THERM_LIMIT);
325         if (value < 0)
326                 goto error;
327         temp = value_to_temperature(pdata->extended_range, value);
328
329         /* External temperature h/w shutdown limit */
330         value = nct1008_read_reg(client, EXT_THERM_LIMIT_WR);
331         if (value < 0)
332                 goto error;
333         temp2 = value_to_temperature(pdata->extended_range, value);
334
335         return snprintf(buf, MAX_STR_PRINT, "%d %d\n", temp, temp2);
336 error:
337         dev_err(dev, "%s: failed to read temperature-overheat "
338                 "\n", __func__);
339         return snprintf(buf, MAX_STR_PRINT, " Rd overheat Error\n");
340 }
341
342 static ssize_t nct1008_set_temp_overheat(struct device *dev,
343                         struct device_attribute *attr,
344                         const char *buf, size_t count)
345 {
346         long int num;
347         int err;
348         u8 temp;
349         long curr_temp;
350         struct i2c_client *client = to_i2c_client(dev);
351         struct nct1008_data *data = i2c_get_clientdata(client);
352         char bufTemp[MAX_STR_PRINT];
353         char bufOverheat[MAX_STR_PRINT];
354         unsigned int ret;
355
356         if (strict_strtol(buf, 0, &num)) {
357                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
358                         __LINE__, __func__);
359                 return -EINVAL;
360         }
361         if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
362                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
363                         __LINE__, __func__);
364                 return -EINVAL;
365         }
366         /* check for system power down */
367         err = nct1008_get_temp_common(EXT, data, &curr_temp);
368         if (err)
369                 goto error;
370
371         curr_temp = MILLICELSIUS_TO_CELSIUS(curr_temp);
372
373         if (curr_temp >= (int)num) {
374                 ret = nct1008_show_temp(dev, attr, bufTemp);
375                 ret = nct1008_show_temp_overheat(dev, attr, bufOverheat);
376                 dev_err(dev, "\nCurrent temp: %s ", bufTemp);
377                 dev_err(dev, "\nOld overheat limit: %s ", bufOverheat);
378                 dev_err(dev, "\nReset from overheat: curr temp=%ld, new overheat temp=%d\n\n",
379                         curr_temp, (int)num);
380         }
381
382         /* External temperature h/w shutdown limit */
383         temp = temperature_to_value(data->plat_data.extended_range, (s16)num);
384         err = nct1008_write_reg(client, EXT_THERM_LIMIT_WR, temp);
385         if (err < 0)
386                 goto error;
387
388         /* Local temperature h/w shutdown limit */
389         temp = temperature_to_value(data->plat_data.extended_range, (s16)num);
390         err = nct1008_write_reg(client, LOC_THERM_LIMIT, temp);
391         if (err < 0)
392                 goto error;
393
394         data->plat_data.sensors[EXT].shutdown_limit = num;
395         if (!client->dev.of_node)
396                 nct1008_setup_shutdown_warning(data);
397
398         return count;
399 error:
400         dev_err(dev, " %s: failed to set temperature-overheat\n", __func__);
401         return err;
402 }
403
404 static ssize_t nct1008_show_temp_alert(struct device *dev,
405                                 struct device_attribute *attr,
406                                 char *buf)
407 {
408         struct i2c_client *client = to_i2c_client(dev);
409         struct nct1008_platform_data *pdata = client->dev.platform_data;
410         int value;
411         s16 temp_hi, temp_lo;
412         /* External Temperature Throttling hi-limit */
413         value = nct1008_read_reg(client, EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
414         if (value < 0)
415                 goto error;
416         temp_hi = value_to_temperature(pdata->extended_range, value);
417
418         /* External Temperature Throttling lo-limit */
419         value = nct1008_read_reg(client, EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
420         if (value < 0)
421                 goto error;
422         temp_lo = value_to_temperature(pdata->extended_range, value);
423
424         return snprintf(buf, MAX_STR_PRINT, "lo:%d hi:%d\n", temp_lo, temp_hi);
425 error:
426         dev_err(dev, "%s: failed to read temperature-alert\n", __func__);
427         return snprintf(buf, MAX_STR_PRINT, " Rd alert Error\n");
428 }
429
430 static ssize_t nct1008_set_temp_alert(struct device *dev,
431                         struct device_attribute *attr,
432                         const char *buf, size_t count)
433 {
434         long int num;
435         int value;
436         int err;
437         struct i2c_client *client = to_i2c_client(dev);
438         struct nct1008_platform_data *pdata = client->dev.platform_data;
439
440         if (strict_strtol(buf, 0, &num)) {
441                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
442                         __LINE__, __func__);
443                 return -EINVAL;
444         }
445         if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
446                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
447                         __LINE__, __func__);
448                 return -EINVAL;
449         }
450
451         /* External Temperature Throttling limit */
452         value = temperature_to_value(pdata->extended_range, (s16)num);
453         err = nct1008_write_reg(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR, value);
454         if (err < 0)
455                 goto error;
456
457         /* Local Temperature Throttling limit */
458         err = nct1008_write_reg(client, LOC_TEMP_HI_LIMIT_WR, value);
459         if (err < 0)
460                 goto error;
461
462         return count;
463 error:
464         dev_err(dev, "%s: failed to set temperature-alert "
465                 "\n", __func__);
466         return err;
467 }
468
469 static ssize_t nct1008_show_sensor_temp(int sensor, struct device *dev,
470         struct device_attribute *attr, char *buf)
471 {
472         struct i2c_client *client = to_i2c_client(dev);
473         struct nct1008_platform_data *pdata = client->dev.platform_data;
474         s16 temp_value;
475         int data = 0;
476         int data_lo;
477
478         if (!dev || !buf || !attr)
479                 return -EINVAL;
480
481         /* When reading the full external temperature value, read the
482          * LSB first. This causes the MSB to be locked (that is, the
483          * ADC does not write to it) until it is read */
484         data_lo = nct1008_read_reg(client, NCT_REG(sensor, TEMP_RD_LO));
485         if (data_lo < 0) {
486                 dev_err(&client->dev, "%s: failed to read "
487                         "ext_temperature, i2c error=%d\n", __func__, data_lo);
488                 goto error;
489         }
490
491         data = nct1008_read_reg(client, NCT_REG(sensor, TEMP_RD_HI));
492         if (data < 0) {
493                 dev_err(&client->dev, "%s: failed to read "
494                         "ext_temperature, i2c error=%d\n", __func__, data);
495                 goto error;
496         }
497
498         temp_value = value_to_temperature(pdata->extended_range, data);
499
500         return snprintf(buf, MAX_STR_PRINT, "%d.%d\n", temp_value,
501                 (25 * (data_lo >> 6)));
502 error:
503         return snprintf(buf, MAX_STR_PRINT, "Error read ext temperature\n");
504 }
505
506 static ssize_t pr_reg(struct nct1008_data *nct, char *buf, int max_s,
507                         const char *reg_name, int offset)
508 {
509         int ret, sz = 0;
510
511         ret = nct1008_read_reg(nct->client, offset);
512         if (ret >= 0)
513                 sz += snprintf(buf + sz, PAGE_SIZE - sz,
514                                 "%20s  0x%02x  0x%02x  0x%02x\n",
515                                 reg_name, nct->client->addr, offset, ret);
516         else
517                 sz += snprintf(buf + sz, PAGE_SIZE - sz,
518                                 "%s: line=%d, i2c ** read error=%d **\n",
519                                 __func__, __LINE__, ret);
520         return sz;
521 }
522
523 static ssize_t nct1008_show_regs(struct device *dev,
524         struct device_attribute *attr, char *buf)
525 {
526         struct i2c_client *client = to_i2c_client(dev);
527         struct nct1008_data *nct = i2c_get_clientdata(client);
528         char *name = nct->chip == NCT72 ? "nct72" : "nct1008";
529         int sz = 0;
530
531         sz += snprintf(buf + sz, PAGE_SIZE - sz,
532                 "%s Registers\n", name);
533         sz += snprintf(buf + sz, PAGE_SIZE - sz,
534                 "---------------------------------------\n");
535         sz += snprintf(buf + sz, PAGE_SIZE - sz, "%20s  %4s  %4s  %s\n",
536                 "Register Name       ", "Addr", "Reg", "Value");
537         sz += snprintf(buf + sz, PAGE_SIZE - sz, "%20s  %4s  %4s  %s\n",
538                 "--------------------", "----", "----", "-----");
539         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
540                 "Status              ", STATUS_RD);
541         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
542                 "Configuration       ", CONFIG_RD);
543         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
544                 "Conversion Rate     ", CONV_RATE_RD);
545         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
546                 "Hysteresis          ", THERM_HYSTERESIS);
547         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
548                 "Consecutive Alert   ", COSECUTIVE_ALERT);
549         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
550                 "Local Temp Value    ", LOC_TEMP_RD);
551         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
552                 "Local Temp Hi Limit ", LOC_TEMP_HI_LIMIT_RD);
553         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
554                 "Local Temp Lo Limit ", LOC_TEMP_LO_LIMIT_RD);
555         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
556                 "Local Therm Limit   ", LOC_THERM_LIMIT);
557         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
558                 "Ext Temp Value Hi   ", EXT_TEMP_HI_RD);
559         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
560                 "Ext Temp Value Lo   ", EXT_TEMP_LO_RD);
561         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
562                 "Ext Temp Hi Limit Hi", EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
563         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
564                 "Ext Temp Hi Limit Lo", EXT_TEMP_HI_LIMIT_LO_BYTE);
565         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
566                 "Ext Temp Lo Limit Hi", EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
567         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
568                 "Ext Temp Lo Limit Lo", EXT_TEMP_LO_LIMIT_LO_BYTE);
569         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
570                 "Ext Temp Offset Hi  ", OFFSET_WR);
571         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
572                 "Ext Temp Offset Lo  ", OFFSET_QUARTER_WR);
573         sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
574                 "Ext Therm Limit     ", EXT_THERM_LIMIT_WR);
575
576         return sz;
577 }
578
579 static ssize_t nct1008_set_offsets(struct device *dev,
580                         struct device_attribute *attr,
581                         const char *buf, size_t count)
582 {
583         struct i2c_client *client = to_i2c_client(dev);
584         struct nct1008_data *nct = i2c_get_clientdata(client);
585         int index, temp, off;
586         int rv = count;
587
588         strim((char *)buf);
589         sscanf(buf, "[%u] %u %d", &index, &temp, &off);
590
591         if (index >= ARRAY_SIZE(nct->sensors[EXT].offset_table)) {
592                 pr_info("%s: invalid index [%d]\n", __func__, index);
593                 rv = -EINVAL;
594         } else {
595                 nct->sensors[EXT].offset_table[index].temp = temp;
596                 nct->sensors[EXT].offset_table[index].offset = off;
597         }
598
599         return rv;
600 }
601
602 static ssize_t nct1008_show_offsets(struct device *dev,
603         struct device_attribute *attr, char *buf)
604 {
605         struct i2c_client *client = to_i2c_client(dev);
606         struct nct1008_data *nct = i2c_get_clientdata(client);
607         char *name = nct->chip == NCT72 ? "nct72" : "nct1008";
608         int i, sz = 0;
609
610         sz += snprintf(buf + sz, PAGE_SIZE - sz,
611                                 "%s offsets table\n", name);
612         sz += snprintf(buf + sz, PAGE_SIZE - sz,
613                                 "%2s  %4s  %s\n", " #", "temp", "offset");
614         sz += snprintf(buf + sz, PAGE_SIZE - sz,
615                                 "%2s  %4s  %s\n", "--", "----", "------");
616
617         for (i = 0; i < ARRAY_SIZE(nct->sensors[EXT].offset_table); i++)
618                 sz += snprintf(buf + sz, PAGE_SIZE - sz,
619                                 "%2d  %4d  %3d\n",
620                                 i, nct->sensors[EXT].offset_table[i].temp,
621                                 nct->sensors[EXT].offset_table[i].offset);
622         return sz;
623 }
624
625
626 /* This function is used by the system to show the temperature. */
627 static ssize_t nct1008_show_ext_temp(struct device *dev,
628                                         struct device_attribute *attr,
629                                         char *buf)
630 {
631         return nct1008_show_sensor_temp(EXT, dev, attr, buf);
632 }
633
634 static DEVICE_ATTR(temperature, S_IRUGO, nct1008_show_temp, NULL);
635 static DEVICE_ATTR(temperature_overheat, (S_IRUGO | (S_IWUSR | S_IWGRP)),
636                 nct1008_show_temp_overheat, nct1008_set_temp_overheat);
637 static DEVICE_ATTR(temperature_alert, (S_IRUGO | (S_IWUSR | S_IWGRP)),
638                 nct1008_show_temp_alert, nct1008_set_temp_alert);
639 static DEVICE_ATTR(ext_temperature, S_IRUGO, nct1008_show_ext_temp, NULL);
640 static DEVICE_ATTR(registers, S_IRUGO, nct1008_show_regs, NULL);
641 static DEVICE_ATTR(offsets, (S_IRUGO | (S_IWUSR | S_IWGRP)),
642                 nct1008_show_offsets, nct1008_set_offsets);
643
644 static struct attribute *nct1008_attributes[] = {
645         &dev_attr_temperature.attr,
646         &dev_attr_temperature_overheat.attr,
647         &dev_attr_temperature_alert.attr,
648         &dev_attr_ext_temperature.attr,
649         &dev_attr_registers.attr,
650         &dev_attr_offsets.attr,
651         NULL
652 };
653
654 static const struct attribute_group nct1008_attr_group = {
655         .attrs = nct1008_attributes,
656 };
657
658 static const unsigned long THERM_WARN_RANGE_HIGH_OFFSET = 3000;
659 static unsigned long nct1008_shutdown_warning_cur_state;
660 static long shutdown_warn_saved_temp;
661
662 static int nct1008_shutdown_warning_get_max_state(
663                                         struct thermal_cooling_device *cdev,
664                                         unsigned long *max_state)
665 {
666         /* A state for every 250mC */
667         *max_state = THERM_WARN_RANGE_HIGH_OFFSET / 250;
668         return 0;
669 }
670
671 static int nct1008_shutdown_warning_get_cur_state(
672                                         struct thermal_cooling_device *cdev,
673                                         unsigned long *cur_state)
674 {
675         struct nct1008_data *data = cdev->devdata;
676         long limit = data->plat_data.sensors[EXT].shutdown_limit * 1000;
677         long temp;
678
679         if (nct1008_get_temp_common(EXT, data, &temp))
680                 return -1;
681
682         if (temp >= (limit - THERM_WARN_RANGE_HIGH_OFFSET))
683                 *cur_state = nct1008_shutdown_warning_cur_state;
684         else
685                 *cur_state = 0;
686
687         return 0;
688 }
689
690 static int nct1008_shutdown_warning_set_cur_state(
691                                         struct thermal_cooling_device *cdev,
692                                         unsigned long cur_state)
693 {
694         struct nct1008_data *data = cdev->devdata;
695         long limit = data->plat_data.sensors[EXT].shutdown_limit * 1000;
696         long temp;
697
698         if (nct1008_get_temp_common(EXT, data, &temp))
699                 return -1;
700         else if (temp < 0)
701                 goto ret;
702
703         if ((temp >= (limit - THERM_WARN_RANGE_HIGH_OFFSET)) &&
704                 (temp != shutdown_warn_saved_temp)) {
705                 pr_warn("NCT%s: Warning: chip temperature (%ld.%02ldC) is %s SHUTDOWN limit (%c%ldC).\n",
706                         (data->chip == NCT72) ? "72" : "1008",
707                         temp / 1000, (temp % 1000) / 10,
708                         temp > limit ? "above" :
709                         temp == limit ? "at" : "near",
710                         temp > limit ? '>' : '<', limit / 1000);
711                 shutdown_warn_saved_temp = temp;
712         }
713
714  ret:
715         nct1008_shutdown_warning_cur_state = cur_state;
716         return 0;
717 }
718
719 static struct thermal_cooling_device_ops nct1008_shutdown_warning_ops = {
720         .get_max_state = nct1008_shutdown_warning_get_max_state,
721         .get_cur_state = nct1008_shutdown_warning_get_cur_state,
722         .set_cur_state = nct1008_shutdown_warning_set_cur_state,
723 };
724
725 static int nct1008_thermal_set_limits(int sensor,
726                                       struct nct1008_data *data,
727                                       long lo_limit_milli,
728                                       long hi_limit_milli)
729 {
730         int err;
731         u8 value;
732         bool extended_range = data->plat_data.extended_range;
733         long lo_limit = MILLICELSIUS_TO_CELSIUS(lo_limit_milli);
734         long hi_limit = MILLICELSIUS_TO_CELSIUS(hi_limit_milli);
735
736         if (lo_limit >= hi_limit)
737                 return -EINVAL;
738
739         if (data->sensors[sensor].current_lo_limit != lo_limit) {
740                 value = temperature_to_value(extended_range, lo_limit);
741                 pr_debug("%s: set lo_limit %ld\n", __func__, lo_limit);
742                 err = nct1008_write_reg(data->client,
743                                 NCT_REG(sensor, TEMP_LO_LIMIT_WR), value);
744                 if (err)
745                         return err;
746
747                 data->sensors[sensor].current_lo_limit = lo_limit;
748         }
749
750         if (data->sensors[sensor].current_hi_limit != hi_limit) {
751                 value = temperature_to_value(extended_range, hi_limit);
752                 pr_debug("%s: set hi_limit %ld\n", __func__, hi_limit);
753                 err = nct1008_write_reg(data->client,
754                                 NCT_REG(sensor, TEMP_HI_LIMIT_WR), value);
755                 if (err)
756                         return err;
757
758                 data->sensors[sensor].current_hi_limit = hi_limit;
759         }
760
761         if (sensor == LOC)
762                 pr_debug("NCT1008: LOC-sensor limits set to %ld - %ld\n",
763                         lo_limit, hi_limit);
764
765         return 0;
766 }
767
768 #ifdef CONFIG_THERMAL
769 static void nct1008_update(int sensor, struct nct1008_data *data)
770 {
771         struct thermal_zone_device *thz;
772         long low_temp, high_temp;
773         struct thermal_trip_info *trip_state;
774         long temp, trip_temp, hysteresis_temp;
775         int count;
776
777         low_temp = 0, high_temp = NCT1008_MAX_TEMP * 1000;
778         thz = data->sensors[sensor].thz;
779
780         if (!thz)
781                 return;
782
783         thermal_zone_device_update(thz);
784
785         temp = thz->temperature;
786
787         for (count = 0; count < thz->trips; count++) {
788                 trip_state = &data->plat_data.sensors[sensor].trips[count];
789                 trip_temp = trip_state->trip_temp;
790                 hysteresis_temp = trip_temp - trip_state->hysteresis;
791                 if ((trip_state->trip_type == THERMAL_TRIP_PASSIVE) &&
792                     !trip_state->tripped)
793                         hysteresis_temp = trip_temp;
794
795                 if ((trip_temp > temp) && (trip_temp < high_temp))
796                         high_temp = trip_temp;
797
798                 if ((hysteresis_temp < temp) && (hysteresis_temp > low_temp))
799                         low_temp = hysteresis_temp;
800         }
801
802         nct1008_thermal_set_limits(sensor, data, low_temp, high_temp);
803 }
804
805 static int nct1008_ext_get_temp(struct thermal_zone_device *thz, long *temp)
806 {
807         struct nct1008_data *data = thz->devdata;
808
809         return nct1008_get_temp_common(EXT, data, temp);
810 }
811
812 static int nct1008_ext_get_temp_as_sensor(void *data, long *temp)
813 {
814         return nct1008_get_temp_common(EXT, (struct nct1008_data *) data, temp);
815 }
816
817 static int nct1008_ext_bind(struct thermal_zone_device *thz,
818                             struct thermal_cooling_device *cdev)
819 {
820         struct nct1008_data *data = thz->devdata;
821         int i;
822         struct nct1008_sensor_platform_data *sensor;
823
824         sensor = &data->plat_data.sensors[EXT];
825
826         for (i = 0; i < sensor->num_trips; i++) {
827                 if (!strcmp(sensor->trips[i].cdev_type, cdev->type))
828                         thermal_zone_bind_cooling_device(thz, i, cdev,
829                                         sensor->trips[i].upper,
830                                         sensor->trips[i].lower);
831         }
832
833         return 0;
834 }
835
836
837 static int nct1008_unbind(int sensor,
838                                 struct thermal_zone_device *thz,
839                                 struct thermal_cooling_device *cdev)
840 {
841         struct nct1008_data *data = thz->devdata;
842         int i;
843
844         struct nct1008_sensor_platform_data *sensor_data;
845
846         sensor_data = &data->plat_data.sensors[sensor];
847
848         for (i = 0; i < sensor_data->num_trips; i++) {
849                 if (!strcmp(sensor_data->trips[i].cdev_type, cdev->type))
850                         thermal_zone_unbind_cooling_device(thz, i, cdev);
851         }
852         return 0;
853 }
854
855 /* Helper function that is called in order to unbind external sensor from the
856    cooling device. */
857 static inline int nct1008_ext_unbind(struct thermal_zone_device *thz,
858                                         struct thermal_cooling_device *cdev)
859 {
860         return nct1008_unbind(EXT, thz, cdev);
861 }
862
863 /* Helper function that is called in order to unbind local sensor from the
864    cooling device. */
865 static inline int nct1008_loc_unbind(struct thermal_zone_device *thz,
866                                         struct thermal_cooling_device *cdev)
867 {
868         return nct1008_unbind(LOC, thz, cdev);
869 }
870
871 /* This function reads the temperature value set for the given trip point. */
872 static int nct1008_get_trip_temp(int sensor,
873                                         struct thermal_zone_device *thz,
874                                         int trip, long *temp)
875 {
876         struct nct1008_data *data = thz->devdata;
877         struct thermal_trip_info *trip_state =
878                 &data->plat_data.sensors[sensor].trips[trip];
879
880         *temp = trip_state->trip_temp;
881
882         if (trip_state->trip_type != THERMAL_TRIP_PASSIVE)
883                 return 0;
884
885         if (thz->temperature >= *temp) {
886                 trip_state->tripped = true;
887         } else if (trip_state->tripped) {
888                 *temp -= trip_state->hysteresis;
889                 if (thz->temperature < *temp)
890                         trip_state->tripped = false;
891         }
892
893         return 0;
894 }
895
896 /* This function reads the temperature value set for the given trip point for
897    the local sensor. */
898 static inline int nct1008_loc_get_trip_temp(struct thermal_zone_device *thz,
899                                                 int trip, long *temp)
900 {
901         return nct1008_get_trip_temp(LOC, thz, trip, temp);
902 }
903
904 /* This function reads the temperature value set for the given trip point for
905         the remote sensor. */
906 static inline int nct1008_ext_get_trip_temp(struct thermal_zone_device *thz,
907                                                 int trip, long *temp)
908 {
909         return nct1008_get_trip_temp(EXT, thz, trip, temp);
910 }
911
912 /* This function allows setting trip point temperature for the sensor
913    specified. */
914 static int nct1008_set_trip_temp(int sensor,
915                                         struct thermal_zone_device *thz,
916                                         int trip, long temp)
917 {
918         struct nct1008_data *data = thz->devdata;
919
920         data->plat_data.sensors[sensor].trips[trip].trip_temp = temp;
921         nct1008_update(sensor, data);
922         return 0;
923 }
924
925 /* This function allows setting trip point temperature for the local sensor. */
926 static inline int nct1008_loc_set_trip_temp(struct thermal_zone_device *thz,
927                                                 int trip, long temp)
928 {
929         return nct1008_set_trip_temp(LOC, thz, trip, temp);
930 }
931
932 /* This function allows setting trip point temperature for the external
933  * sensor. */
934 static inline int nct1008_ext_set_trip_temp(struct thermal_zone_device *thz,
935                                                 int trip, long temp)
936 {
937         return nct1008_set_trip_temp(EXT, thz, trip, temp);
938 }
939
940 /*
941  * Update trip point temperature from the device tree binded thermal zone for
942  * the sensor specified.
943  */
944 static int nct1008_of_trip_update(int sensor, void *of_data, int trip)
945 {
946         int ret;
947         long temp;
948         struct nct1008_data *data = of_data;
949         struct thermal_zone_device *thz = data->sensors[sensor].thz;
950
951         if (thz->ops && thz->ops->get_trip_temp) {
952                 ret = thz->ops->get_trip_temp(thz, trip, &temp);
953                 if (ret)
954                         return ret;
955
956                 data->plat_data.sensors[sensor].trips[trip].trip_temp = temp;
957                 nct1008_update(sensor, data);
958         }
959         return 0;
960 }
961
962 static int nct1008_of_loc_trip_update(void *of_data, int trip)
963 {
964         return nct1008_of_trip_update(LOC, of_data, trip);
965 }
966
967 static int nct1008_of_ext_trip_update(void *of_data, int trip)
968 {
969         return nct1008_of_trip_update(EXT, of_data, trip);
970 }
971
972 /* This function return the trip point type for the sensor specified. */
973 static int nct1008_get_trip_type(int sensor,
974                                         struct thermal_zone_device *thz,
975                                         int trip,
976                                         enum thermal_trip_type *type)
977 {
978         struct nct1008_data *data = thz->devdata;
979
980         *type = data->plat_data.sensors[sensor].trips[trip].trip_type;
981         return 0;
982 }
983
984 /* This function return the trip point type for the local sensor. */
985 static inline int nct1008_loc_get_trip_type(struct thermal_zone_device *thz,
986                                                 int trip,
987                                                 enum thermal_trip_type *type)
988 {
989         return nct1008_get_trip_type(LOC, thz, trip, type);
990 }
991
992 /* This function return the trip point type for the external sensor. */
993 static inline int nct1008_ext_get_trip_type(struct thermal_zone_device *thz,
994                                                 int trip,
995                                                 enum thermal_trip_type *type)
996 {
997         return nct1008_get_trip_type(EXT, thz, trip, type);
998 }
999
1000 /* This function returns value of trend for the temperature change, depending
1001    on the trip point type. */
1002 static int nct1008_get_trend(int sensor,
1003                                 struct thermal_zone_device *thz,
1004                                 int trip,
1005                                 enum thermal_trend *trend)
1006 {
1007         struct nct1008_data *data = thz->devdata;
1008         struct thermal_trip_info *trip_state;
1009
1010         trip_state = &data->plat_data.sensors[sensor].trips[trip];
1011
1012         switch (trip_state->trip_type) {
1013         case THERMAL_TRIP_ACTIVE:
1014                 if (thz->temperature >= trip_state->trip_temp)
1015                         *trend = THERMAL_TREND_RAISING;
1016                 else
1017                         *trend = THERMAL_TREND_DROPPING;
1018                 break;
1019         case THERMAL_TRIP_PASSIVE:
1020                 if (thz->temperature > thz->last_temperature)
1021                         *trend = THERMAL_TREND_RAISING;
1022                 else if (thz->temperature < (thz->last_temperature -
1023                                                 trip_state->hysteresis))
1024                         *trend = THERMAL_TREND_DROPPING;
1025                 else
1026                         *trend = THERMAL_TREND_STABLE;
1027                 break;
1028         default:
1029                 return -EINVAL;
1030         }
1031         return 0;
1032 }
1033
1034 static int nct1008_get_trend_as_sensor(int sensor,
1035                                 struct nct1008_data *data,
1036                                         long *trend)
1037 {
1038          /*FIXME this function will not be used,
1039         bug 200025971 to solve this issue*/
1040         struct thermal_trip_info *trip_state;
1041         int trip = 0;
1042         trip_state = &data->plat_data.sensors[sensor].trips[trip];
1043         *trend = data->sensors[sensor].temp - trip_state->trip_temp;
1044         return 0;
1045 }
1046
1047 /* Helper function to get trend for the local sensor. */
1048 static inline int nct1008_loc_get_trend(struct thermal_zone_device *thz,
1049                                                 int trip,
1050                                                 enum thermal_trend *trend)
1051 {
1052         return nct1008_get_trend(LOC, thz, trip, trend);
1053 }
1054 static inline int nct1008_loc_get_trend_as_sensor(void *data,
1055                                                 long *trend)
1056 {
1057         return nct1008_get_trend_as_sensor(LOC,
1058                 (struct nct1008_data *) data, trend);
1059 }
1060
1061 /* Helper function to get trend for the external sensor. */
1062 static inline int nct1008_ext_get_trend(struct thermal_zone_device *thz,
1063                                                 int trip,
1064                                                 enum thermal_trend *trend)
1065 {
1066         return nct1008_get_trend(EXT, thz, trip, trend);
1067 }
1068 static inline int nct1008_ext_get_trend_as_sensor(void *data,
1069                                                 long *trend)
1070 {
1071         return nct1008_get_trend_as_sensor
1072                 (EXT, (struct nct1008_data *) data, trend);
1073 }
1074
1075
1076 /* Helper function to get temperature of the local sensor. */
1077 static int nct1008_loc_get_temp(struct thermal_zone_device *thz, long *temp)
1078 {
1079         struct nct1008_data *data = thz->devdata;
1080
1081         return nct1008_get_temp_common(LOC, data, temp);
1082 }
1083
1084 static int nct1008_loc_get_temp_as_sensor(void *data, long *temp)
1085 {
1086         return nct1008_get_temp_common(LOC, (struct nct1008_data *) data, temp);
1087 }
1088 /* Helper function to bind local sensor with the cooling device specified. */
1089 static int nct1008_loc_bind(struct thermal_zone_device *thz,
1090                                 struct thermal_cooling_device *cdev)
1091 {
1092         struct nct1008_data *data = thz->devdata;
1093         int i;
1094         struct nct1008_sensor_platform_data *sensor_data;
1095
1096         pr_debug("NCT1008: LOC-sensor bind %s, %s attempt\n",
1097                  thz->type, cdev->type);
1098
1099         sensor_data = &data->plat_data.sensors[LOC];
1100
1101         for (i = 0; i < sensor_data->num_trips; i++) {
1102                 if (!strcmp(sensor_data->trips[i].cdev_type, cdev->type)) {
1103                         thermal_zone_bind_cooling_device(thz, i, cdev,
1104                                 sensor_data->trips[i].upper,
1105                                 sensor_data->trips[i].lower);
1106                         break;
1107                 }
1108         }
1109
1110         return 0;
1111 }
1112
1113 static struct thermal_zone_device_ops nct_loc_ops = {
1114         .get_temp = nct1008_loc_get_temp,
1115         .bind = nct1008_loc_bind,
1116         .unbind = nct1008_loc_unbind,
1117         .get_trip_type = nct1008_loc_get_trip_type,
1118         .get_trip_temp = nct1008_loc_get_trip_temp,
1119         .set_trip_temp = nct1008_loc_set_trip_temp,
1120         .get_trend = nct1008_loc_get_trend,
1121 };
1122
1123 static struct thermal_zone_device_ops nct_ext_ops = {
1124         .get_temp = nct1008_ext_get_temp,
1125         .bind = nct1008_ext_bind,
1126         .unbind = nct1008_ext_unbind,
1127         .get_trip_type = nct1008_ext_get_trip_type,
1128         .get_trip_temp = nct1008_ext_get_trip_temp,
1129         .set_trip_temp = nct1008_ext_set_trip_temp,
1130         .get_trend = nct1008_ext_get_trend,
1131 };
1132 #else
1133 static void nct1008_update(nct1008_sensors sensor, struct nct1008_data *data)
1134 {
1135 }
1136 #endif /* CONFIG_THERMAL */
1137
1138 static int nct1008_enable(struct i2c_client *client)
1139 {
1140         struct nct1008_data *data = i2c_get_clientdata(client);
1141         int err;
1142
1143         err = nct1008_write_reg(client, CONFIG_WR, data->config);
1144         if (err < 0)
1145                 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
1146                 __func__, __LINE__, err);
1147         return err;
1148 }
1149
1150 static int nct1008_disable(struct i2c_client *client)
1151 {
1152         struct nct1008_data *data = i2c_get_clientdata(client);
1153         int err;
1154
1155         err = nct1008_write_reg(client, CONFIG_WR,
1156                                 data->config | STANDBY_BIT);
1157         if (err < 0)
1158                 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
1159                 __func__, __LINE__, err);
1160         return err;
1161 }
1162
1163 static void nct1008_work_func(struct work_struct *work)
1164 {
1165         struct nct1008_data *data = container_of(work, struct nct1008_data,
1166                                                 work);
1167         int err;
1168         struct timespec ts;
1169         int intr_status;
1170
1171         mutex_lock(&data->mutex);
1172         if (data->stop_workqueue) {
1173                 mutex_unlock(&data->mutex);
1174                 return;
1175         }
1176         mutex_unlock(&data->mutex);
1177
1178         err = nct1008_disable(data->client);
1179         if (err == -ENODEV)
1180                 return;
1181
1182         intr_status = nct1008_read_reg(data->client, STATUS_RD);
1183         pr_debug("NCT1008: interruption (0x%08x)\n", intr_status);
1184
1185         if (intr_status & (LOC_LO_BIT | LOC_HI_BIT)) {
1186                 pr_debug("NCT1008: LOC-sensor is not within limits\n");
1187                 nct1008_update(LOC, data);
1188         }
1189
1190         if (intr_status & (EXT_LO_BIT | EXT_HI_BIT))
1191                 nct1008_update(EXT, data);
1192
1193         /* Initiate one-shot conversion */
1194         nct1008_write_reg(data->client, ONE_SHOT, 0x1);
1195
1196         /* Give hardware necessary time to finish conversion */
1197         ts = ns_to_timespec(MAX_CONV_TIME_ONESHOT_MS * 1000 * 1000);
1198         hrtimer_nanosleep(&ts, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
1199
1200         nct1008_read_reg(data->client, STATUS_RD);
1201
1202         nct1008_enable(data->client);
1203
1204         enable_irq(data->client->irq);
1205 }
1206
1207 static irqreturn_t nct1008_irq(int irq, void *dev_id)
1208 {
1209         struct nct1008_data *data = dev_id;
1210
1211         disable_irq_nosync(irq);
1212         queue_work(data->workqueue, &data->work);
1213
1214         return IRQ_HANDLED;
1215 }
1216
1217 static void nct1008_power_control(struct nct1008_data *data, bool is_enable)
1218 {
1219         int ret;
1220
1221         mutex_lock(&data->mutex);
1222         if (!data->nct_reg) {
1223                 data->nct_reg = regulator_get(&data->client->dev, "vdd");
1224                 if (IS_ERR_OR_NULL(data->nct_reg)) {
1225                         if (PTR_ERR(data->nct_reg) == -ENODEV)
1226                                 dev_info(&data->client->dev,
1227                                         "no regulator found for vdd."
1228                                         " Assuming vdd is always powered");
1229                         else
1230                                 dev_warn(&data->client->dev, "Error [%ld] in "
1231                                         "getting the regulator handle for"
1232                                         " vdd\n", PTR_ERR(data->nct_reg));
1233                         data->nct_reg = NULL;
1234                         mutex_unlock(&data->mutex);
1235                         return;
1236                 }
1237         }
1238         if (is_enable)
1239                 ret = regulator_enable(data->nct_reg);
1240         else
1241                 ret = regulator_disable(data->nct_reg);
1242
1243         if (ret < 0)
1244                 dev_err(&data->client->dev, "Error in %s rail vdd_nct%s, "
1245                         "error %d\n", (is_enable) ? "enabling" : "disabling",
1246                         (data->chip == NCT72) ? "72" : "1008",
1247                         ret);
1248         else
1249                 dev_info(&data->client->dev, "success in %s rail vdd_nct%s\n",
1250                         (is_enable) ? "enabling" : "disabling",
1251                         (data->chip == NCT72) ? "72" : "1008");
1252         data->nct_disabled = !is_enable;
1253         mutex_unlock(&data->mutex);
1254 }
1255
1256 static void nct1008_setup_shutdown_warning(struct nct1008_data *data)
1257 {
1258         static struct thermal_cooling_device *cdev;
1259         long limit = data->plat_data.sensors[EXT].shutdown_limit * 1000;
1260         long warn_temp = limit - THERM_WARN_RANGE_HIGH_OFFSET;
1261         int i;
1262         struct nct1008_sensor_platform_data *sensor_data;
1263
1264         if (cdev)
1265                 thermal_cooling_device_unregister(cdev);
1266         cdev = thermal_cooling_device_register("shutdown_warning", data,
1267                                         &nct1008_shutdown_warning_ops);
1268         if (IS_ERR_OR_NULL(cdev)) {
1269                 cdev = NULL;
1270                 return;
1271         }
1272
1273         sensor_data = &data->plat_data.sensors[EXT];
1274
1275         for (i = 0; i < sensor_data->num_trips; i++) {
1276                 if (!strcmp(sensor_data->trips[i].cdev_type,
1277                                                 "shutdown_warning")) {
1278                         sensor_data->trips[i].trip_temp = warn_temp;
1279                         nct1008_update(EXT, data);
1280                         break;
1281                 }
1282         }
1283
1284         pr_info("NCT%s: Enabled overheat logging at %ld.%02ldC\n",
1285                         (data->chip == NCT72) ? "72" : "1008",
1286                         warn_temp / 1000, (warn_temp % 1000) / 10);
1287 }
1288
1289 static int nct1008_configure_sensor(struct nct1008_data *data)
1290 {
1291         struct i2c_client *client = data->client;
1292         struct nct1008_platform_data *pdata = client->dev.platform_data;
1293         u8 value;
1294         s16 temp;
1295         u8 temp2;
1296         int ret;
1297         bool ext_err = false;
1298
1299         if (!pdata || !pdata->supported_hwrev)
1300                 return -ENODEV;
1301
1302         ret = nct1008_read_reg(data->client, STATUS_RD);
1303         if (ret & BIT(2)) {
1304                 pr_info("NCT%s: ERR: remote sensor circuit is open (0x%02x)\n",
1305                         (data->chip == NCT72) ? "72" : "1008", ret);
1306                 ext_err = true; /* flag the error */
1307         }
1308
1309         /* Initially place in Standby */
1310         ret = nct1008_write_reg(client, CONFIG_WR, STANDBY_BIT);
1311         if (ret)
1312                 goto error;
1313
1314         /* Local temperature h/w shutdown limit */
1315         value = temperature_to_value(pdata->extended_range,
1316                                         pdata->sensors[LOC].shutdown_limit);
1317         ret = nct1008_write_reg(client, LOC_THERM_LIMIT, value);
1318         if (ret)
1319                 goto error;
1320
1321         /* set extended range mode if needed */
1322         if (pdata->extended_range)
1323                 data->config |= EXTENDED_RANGE_BIT;
1324         data->config &= ~(THERM2_BIT | ALERT_BIT);
1325
1326         ret = nct1008_write_reg(client, CONFIG_WR, data->config | STANDBY_BIT);
1327         if (ret)
1328                 goto error;
1329
1330         /* Temperature conversion rate */
1331         ret = nct1008_write_reg(client, CONV_RATE_WR, pdata->conv_rate);
1332         if (ret)
1333                 goto error;
1334
1335         data->conv_period_ms = conv_period_ms_table[pdata->conv_rate];
1336
1337         /* Setup local hi and lo limits. */
1338         ret = nct1008_write_reg(client, LOC_TEMP_HI_LIMIT_WR, NCT1008_MAX_TEMP);
1339         if (ret)
1340                 goto error;
1341
1342         ret = nct1008_write_reg(client, LOC_TEMP_LO_LIMIT_WR, 0);
1343         if (ret)
1344                 goto error;
1345
1346         /* read initial temperature */
1347         ret = nct1008_read_reg(client, LOC_TEMP_RD);
1348         if (ret < 0)
1349                 goto error;
1350         else
1351                 value = ret;
1352
1353         temp = value_to_temperature(pdata->extended_range, value);
1354         dev_dbg(&client->dev, "\n initial local temp = %d ", temp);
1355
1356         if (ext_err)
1357                 return ext_err; /* skip configuration of EXT sensor */
1358
1359         /* External temperature h/w shutdown limit. */
1360         value = temperature_to_value(pdata->extended_range,
1361                                         pdata->sensors[EXT].shutdown_limit);
1362         ret = nct1008_write_reg(client, EXT_THERM_LIMIT_WR, value);
1363         if (ret)
1364                 goto error;
1365
1366         /* Setup external hi and lo limits */
1367         ret = nct1008_write_reg(client, EXT_TEMP_LO_LIMIT_HI_BYTE_WR, 0);
1368         if (ret)
1369                 goto error;
1370         ret = nct1008_write_reg(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
1371                         NCT1008_MAX_TEMP);
1372         if (ret)
1373                 goto error;
1374
1375         ret = nct1008_read_reg(client, EXT_TEMP_LO_RD);
1376         if (ret < 0)
1377                 goto error;
1378         else
1379                 value = ret;
1380
1381         temp2 = (value >> 6);
1382         ret = nct1008_read_reg(client, EXT_TEMP_HI_RD);
1383         if (ret < 0)
1384                 goto error;
1385         else
1386                 value = ret;
1387
1388         temp = value_to_temperature(pdata->extended_range, value);
1389
1390         if (temp2 > 0)
1391                 dev_dbg(&client->dev, "\n initial ext temp = %d.%d deg",
1392                                 temp, temp2 * 25);
1393         else
1394                 dev_dbg(&client->dev, "\n initial ext temp = %d.0 deg", temp);
1395
1396         /* Remote channel offset */
1397         ret = nct1008_write_reg(client, OFFSET_WR, pdata->offset / 4);
1398         if (ret < 0)
1399                 goto error;
1400
1401         /* Remote channel offset fraction (quarters) */
1402         ret = nct1008_write_reg(client, OFFSET_QUARTER_WR,
1403                                         (pdata->offset % 4) << 6);
1404         if (ret < 0)
1405                 goto error;
1406
1407         /* Reset current hi/lo limit values with register values */
1408         ret = nct1008_read_reg(data->client, EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
1409         if (ret < 0)
1410                 goto error;
1411         else
1412                 value = ret;
1413         data->sensors[EXT].current_lo_limit =
1414                 value_to_temperature(pdata->extended_range, value);
1415
1416         ret = nct1008_read_reg(data->client, EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
1417         if (ret < 0)
1418                 goto error;
1419         else
1420                 value = ret;
1421
1422         data->sensors[EXT].current_hi_limit =
1423                 value_to_temperature(pdata->extended_range, value);
1424
1425         ret = nct1008_read_reg(data->client, LOC_TEMP_LO_LIMIT_RD);
1426         if (ret < 0)
1427                 goto error;
1428         else
1429                 value = ret;
1430
1431         data->sensors[LOC].current_lo_limit =
1432                 value_to_temperature(pdata->extended_range, value);
1433
1434         value = nct1008_read_reg(data->client, LOC_TEMP_HI_LIMIT_RD);
1435         if (ret < 0)
1436                 goto error;
1437         else
1438                 value = ret;
1439
1440         data->sensors[LOC].current_hi_limit =
1441                 value_to_temperature(pdata->extended_range, value);
1442
1443         if (!client->dev.of_node)
1444                 nct1008_setup_shutdown_warning(data);
1445
1446         return 0;
1447 error:
1448         dev_err(&client->dev, "\n exit %s, err=%d ", __func__, ret);
1449         return ret;
1450 }
1451
1452 static int nct1008_configure_irq(struct nct1008_data *data)
1453 {
1454         data->workqueue = create_singlethread_workqueue((data->chip == NCT72) \
1455                                                         ? "nct72" : "nct1008");
1456
1457         INIT_WORK(&data->work, nct1008_work_func);
1458
1459         if (data->client->irq < 0)
1460                 return 0;
1461         else
1462                 return request_irq(data->client->irq, nct1008_irq,
1463                         IRQF_TRIGGER_LOW,
1464                         (data->chip == NCT72) ? "nct72" : "nct1008",
1465                         data);
1466 }
1467
1468 static struct nct1008_platform_data *nct1008_dt_parse(struct i2c_client *client)
1469 {
1470         struct device_node *np = client->dev.of_node;
1471         struct device_node *child_sensor;
1472         struct nct1008_platform_data *pdata;
1473         int nct72_gpio;
1474         unsigned int proc, index = 0;
1475         if (!np) {
1476                 dev_err(&client->dev,
1477                         "Cannot found the DT node\n");
1478                 goto err_parse_dt;
1479         }
1480
1481         dev_info(&client->dev, "starting parse dt\n");
1482         pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
1483         if (!pdata) {
1484                 dev_err(&client->dev,
1485                         "Parse DT fails at malloc pdata\n");
1486                 goto err_parse_dt;
1487         }
1488
1489         pdata->loc_name = of_get_property(np, "sensor-name", NULL);
1490         if (pdata->loc_name == NULL) {
1491                 dev_err(&client->dev,
1492                         "Cannot found the name\n");
1493                 goto err_parse_dt;
1494         }
1495
1496         if (client->irq == 0)
1497                 client->irq = -1;
1498
1499         if (of_property_read_u32(np, "conv-rate", &proc))
1500                 goto err_parse_dt;
1501         pdata->conv_rate = proc;
1502
1503         if (of_property_read_u32(np, "supported-hwrev", &proc))
1504                 goto err_parse_dt;
1505         pdata->supported_hwrev = (bool) proc;
1506
1507         if (of_property_read_u32(np, "extended-rage", &proc))
1508                 goto err_parse_dt;
1509         pdata->extended_range = (bool) proc;
1510
1511         if (of_property_read_u32(np, "offset", &proc))
1512                 goto err_parse_dt;
1513         pdata->offset =  proc;
1514
1515         if (of_property_read_bool(np, "temp-alert-gpio")) {
1516                 nct72_gpio = of_get_named_gpio(
1517                         np,  "temp-alert-gpio", 0);
1518                 if (gpio_request(nct72_gpio, "temp_alert") < 0)
1519                         dev_err(&client->dev,
1520                                 "%s gpio request error\n", __FILE__);
1521                 if (gpio_direction_input(nct72_gpio) < 0) {
1522                         dev_err(&client->dev,
1523                                 "%s gpio direction_input fail\n", __FILE__);
1524                         gpio_free(nct72_gpio);
1525                 }
1526         }
1527
1528         for_each_child_of_node(np, child_sensor) {
1529                 if (of_property_read_u32(child_sensor, "shutdown-limit", &proc))
1530                         goto err_parse_dt;
1531                 pdata->sensors[index].shutdown_limit = proc;
1532
1533                 proc = 0;
1534                 of_property_read_u32(child_sensor, "suspend_limit_hi", &proc);
1535                 pdata->sensors[index].suspend_limit_hi = proc;
1536                 of_property_read_u32(child_sensor, "suspend_limit_lo", &proc);
1537                 pdata->sensors[index].suspend_limit_lo = proc;
1538                 index++;
1539         }
1540
1541         dev_info(&client->dev, "success parsing dt\n");
1542         client->dev.platform_data = pdata;
1543         return pdata;
1544
1545 err_parse_dt:
1546         dev_err(&client->dev, "Parsing device tree data error.\n");
1547         return NULL;
1548 }
1549
1550 void nct1008_get_trip(int sensor, struct nct1008_data *data)
1551 {
1552         /* TODO: this function assumes that the thermal zone
1553         driver doesn't allow the trip temperature and trip
1554         hysteresis to change at runtime. If they do, the
1555         values in data->plat_data.sensors[sensor].trips[count].trip_temp
1556         and .trip_hyst become stale. */
1557
1558         struct thermal_zone_device *thz;
1559         int count;
1560         long proc;
1561         enum thermal_trip_type trip_type;
1562
1563         thz = data->sensors[sensor].thz;
1564         data->plat_data.sensors[sensor].num_trips = thz->trips;
1565
1566         for (count = 0; count < thz->trips; count++) {
1567                 if (thz->ops && thz->ops->get_trip_temp &&
1568                     (!thz->ops->get_trip_temp(thz, count, &proc)))
1569                         data->plat_data.sensors[sensor].trips[count].trip_temp
1570                                 = proc;
1571                 else
1572                         dev_err(&data->client->dev, "Not found %s trip %d temp",
1573                                 sensor == LOC ? "LOC" : "EXT", count);
1574
1575                 if (thz->ops && thz->ops->get_trip_hyst &&
1576                     (!thz->ops->get_trip_hyst(thz, count, &proc)))
1577                         data->plat_data.sensors[sensor].trips[count].hysteresis
1578                                 = proc;
1579                 else
1580                         dev_err(&data->client->dev, "Not found %s trip %d hyst",
1581                                 sensor == LOC ? "LOC" : "EXT", count);
1582
1583                 if (thz->ops && thz->ops->get_trip_type &&
1584                     (!thz->ops->get_trip_type(thz, count, &trip_type)))
1585                         data->plat_data.sensors[sensor].trips[count].trip_type
1586                                 = trip_type;
1587                 else
1588                         dev_err(&data->client->dev, "Not found %s trip %d type",
1589                                 sensor == LOC ? "LOC" : "EXT", count);
1590         }
1591 }
1592
1593 /*
1594  * Manufacturer(OnSemi) recommended sequence for
1595  * Extended Range mode is as follows
1596  * 1. Place in Standby
1597  * 2. Scale the THERM and ALERT limits
1598  *      appropriately(for Extended Range mode).
1599  * 3. Enable Extended Range mode.
1600  *      ALERT mask/THERM2 mode may be done here
1601  *      as these are not critical
1602  * 4. Set Conversion Rate as required
1603  * 5. Take device out of Standby
1604  */
1605
1606 /*
1607  * function nct1008_probe takes care of initial configuration
1608  */
1609 static int nct1008_probe(struct i2c_client *client,
1610                                 const struct i2c_device_id *id)
1611 {
1612         struct nct1008_data *data;
1613         struct nct1008_platform_data *pdata;
1614         int err;
1615         int i;
1616         u64 mask = 0;
1617         char nct_loc_name[THERMAL_NAME_LENGTH];
1618         char nct_ext_name[THERMAL_NAME_LENGTH];
1619         bool ext_err;
1620         struct nct1008_sensor_platform_data *sensor_data;
1621
1622         if (client->dev.of_node) {
1623                 dev_info(&client->dev, "find device tree node, parsing dt\n");
1624                 pdata = nct1008_dt_parse(client);
1625                 if (IS_ERR(pdata)) {
1626                         err = PTR_ERR(pdata);
1627                         dev_err(&client->dev,
1628                                 "Parsing of node failed, %d\n", err);
1629                         return err;
1630                 }
1631         }
1632
1633         data = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL);
1634         if (!data)
1635                 return -ENOMEM;
1636
1637         data->client = client;
1638         data->chip = id->driver_data;
1639
1640         memcpy(&data->plat_data, client->dev.platform_data,
1641                 sizeof(struct nct1008_platform_data));
1642
1643         i2c_set_clientdata(client, data);
1644         mutex_init(&data->mutex);
1645
1646         nct1008_power_control(data, true);
1647         if (!data->nct_reg) {
1648                 /* power up failure */
1649                 err = -EIO;
1650                 goto cleanup;
1651         }
1652         /* extended range recommended steps 1 through 4 taken care
1653          * in nct1008_configure_sensor function */
1654         err = nct1008_configure_sensor(data);   /* sensor is in standby */
1655         ext_err = err;
1656         if (err < 0) {
1657                 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
1658                         __FILE__, __func__, __LINE__);
1659                 goto error;
1660         }
1661
1662         err = nct1008_configure_irq(data);
1663         if (err < 0) {
1664                 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
1665                         __FILE__, __func__, __LINE__);
1666                 goto error;
1667         }
1668         dev_info(&client->dev, "%s: initialized\n", __func__);
1669
1670         /* extended range recommended step 5 is in nct1008_enable function */
1671         err = nct1008_enable(client);           /* sensor is running */
1672         if (err < 0) {
1673                 dev_err(&client->dev, "Error: %s, line=%d, error=%d\n",
1674                         __func__, __LINE__, err);
1675                 goto error;
1676         }
1677
1678         /* register sysfs hooks */
1679         err = sysfs_create_group(&client->dev.kobj, &nct1008_attr_group);
1680         if (err < 0) {
1681                 dev_err(&client->dev, "\n sysfs create err=%d ", err);
1682                 goto error;
1683         }
1684
1685 #ifdef CONFIG_THERMAL
1686         if (data->plat_data.loc_name) {
1687                 strcpy(nct_loc_name, "Tboard_");
1688                 strcpy(nct_ext_name, "Tdiode_");
1689                 strncat(nct_loc_name, data->plat_data.loc_name,
1690                         (THERMAL_NAME_LENGTH - strlen("Tboard_")) - 1);
1691                 strncat(nct_ext_name, data->plat_data.loc_name,
1692                         (THERMAL_NAME_LENGTH - strlen("Tdiode_")) - 1);
1693         } else {
1694                 strcpy(nct_loc_name, "Tboard");
1695                 strcpy(nct_ext_name, "Tdiode");
1696         }
1697
1698         if (client->dev.of_node) {
1699                 struct thermal_of_sensor_ops loc_sops = {
1700                         .get_temp = nct1008_loc_get_temp_as_sensor,
1701                         .trip_update = nct1008_of_loc_trip_update,
1702                 };
1703
1704                 struct thermal_of_sensor_ops ext_sops = {
1705                         .get_temp = nct1008_ext_get_temp_as_sensor,
1706                         .trip_update = nct1008_of_ext_trip_update,
1707                 };
1708
1709                 /* Config for the Local sensor. */
1710                 data->sensors[LOC].thz =
1711                         thermal_zone_of_sensor_register2(
1712                                 &client->dev, LOC, data, &loc_sops);
1713
1714                 /* register External sensor if connection is good  */
1715                 data->sensors[EXT].thz = ext_err ? NULL :
1716                         thermal_zone_of_sensor_register2(
1717                                 &client->dev, EXT, data, &ext_sops);
1718         } else {
1719                 sensor_data = &data->plat_data.sensors[LOC];
1720
1721                 /* Config for the Local sensor. */
1722                 mask = 0;
1723                 for (i = 0; i < sensor_data->num_trips; i++)
1724                         if (data->plat_data.sensors[LOC].trips[i].mask)
1725                                 mask |= 1ULL << i;
1726
1727                 data->sensors[LOC].thz =
1728                         thermal_zone_device_register(nct_loc_name,
1729                                                 sensor_data->num_trips,
1730                                                 mask,
1731                                                 data,
1732                                                 &nct_loc_ops,
1733                                                 sensor_data->tzp,
1734                                                 2000,
1735                                                 0);
1736
1737                 /* Config for the External sensor. */
1738                 mask = 0;
1739                 for (i = 0; i < data->plat_data.sensors[EXT].num_trips; i++)
1740                         if (data->plat_data.sensors[EXT].trips[i].mask > 0)
1741                                 mask |= 1ULL << i;
1742
1743                 /* register External sensor if connection is good  */
1744                 data->sensors[EXT].thz = ext_err ? NULL :
1745                         thermal_zone_device_register(nct_ext_name,
1746                                 data->plat_data.sensors[EXT].num_trips,
1747                                 mask,
1748                                 data,
1749                                 &nct_ext_ops,
1750                                 data->plat_data.sensors[EXT].tzp,
1751                                 data->plat_data.sensors[EXT].passive_delay,
1752                                 data->plat_data.sensors[EXT].polling_delay);
1753         }
1754
1755         if (!IS_ERR_OR_NULL(data->sensors[LOC].thz)) {
1756                 nct1008_get_trip(LOC, data);
1757                 nct1008_update(LOC, data);
1758         }
1759
1760         if (!IS_ERR_OR_NULL(data->sensors[EXT].thz)) {
1761                 nct1008_get_trip(EXT, data);
1762                 nct1008_update(EXT, data);
1763                 shutdown_warn_saved_temp = data->sensors[EXT].thz->temperature;
1764         }
1765
1766 #endif
1767         return 0;
1768
1769 error:
1770         dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
1771         nct1008_power_control(data, false);
1772 cleanup:
1773         mutex_destroy(&data->mutex);
1774         if (data->nct_reg)
1775                 regulator_put(data->nct_reg);
1776         kfree(data);
1777         return err;
1778 }
1779
1780 static int nct1008_remove(struct i2c_client *client)
1781 {
1782         struct nct1008_data *data = i2c_get_clientdata(client);
1783
1784         mutex_lock(&data->mutex);
1785         data->stop_workqueue = 1;
1786         mutex_unlock(&data->mutex);
1787
1788         cancel_work_sync(&data->work);
1789         free_irq(data->client->irq, data);
1790         sysfs_remove_group(&client->dev.kobj, &nct1008_attr_group);
1791         nct1008_power_control(data, false);
1792
1793         if (data->nct_reg)
1794                 regulator_put(data->nct_reg);
1795
1796         mutex_destroy(&data->mutex);
1797         kfree(data);
1798
1799         return 0;
1800 }
1801
1802 static void nct1008_shutdown(struct i2c_client *client)
1803 {
1804         struct nct1008_data *data = i2c_get_clientdata(client);
1805
1806         mutex_lock(&data->mutex);
1807         data->stop_workqueue = 1;
1808         mutex_unlock(&data->mutex);
1809
1810         if (data->sensors[LOC].thz) {
1811                 if (client->dev.of_node)
1812                         thermal_zone_of_sensor_unregister
1813                                 (&(client->dev), data->sensors[LOC].thz);
1814                 else
1815                         thermal_zone_device_unregister(data->sensors[LOC].thz);
1816                 data->sensors[LOC].thz = NULL;
1817         }
1818         if (data->sensors[EXT].thz) {
1819                 if (client->dev.of_node)
1820                         thermal_zone_of_sensor_unregister
1821                                 (&(client->dev), data->sensors[EXT].thz);
1822                 else
1823                         thermal_zone_device_unregister(data->sensors[EXT].thz);
1824                 data->sensors[EXT].thz = NULL;
1825         }
1826
1827         cancel_work_sync(&data->work);
1828
1829         if (client->irq)
1830                 disable_irq(client->irq);
1831
1832         mutex_lock(&data->mutex);
1833         data->nct_disabled = 1;
1834         mutex_unlock(&data->mutex);
1835 }
1836
1837 #ifdef CONFIG_PM_SLEEP
1838 static int nct1008_suspend_powerdown(struct device *dev)
1839 {
1840         struct i2c_client *client = to_i2c_client(dev);
1841         int err;
1842         struct nct1008_data *data = i2c_get_clientdata(client);
1843
1844         mutex_lock(&data->mutex);
1845         data->stop_workqueue = 1;
1846         mutex_unlock(&data->mutex);
1847         cancel_work_sync(&data->work);
1848         disable_irq(client->irq);
1849         err = nct1008_disable(client);
1850         nct1008_power_control(data, false);
1851         return err;
1852 }
1853
1854 static int nct1008_suspend_wakeup(struct device *dev)
1855 {
1856         struct i2c_client *client = to_i2c_client(dev);
1857         int err;
1858         struct nct1008_data *data = i2c_get_clientdata(client);
1859         long temp;
1860         int sensor_nr;
1861         struct nct1008_sensor_platform_data *sensor_data;
1862
1863         for (sensor_nr = 0; sensor_nr < SENSORS_COUNT; sensor_nr++) {
1864                 sensor_data = &data->plat_data.sensors[sensor_nr];
1865
1866                 err = nct1008_get_temp_common(sensor_nr, data, &temp);
1867
1868                 if (err)
1869                         goto error;
1870
1871                 if (temp > sensor_data->suspend_limit_lo)
1872                         err = nct1008_thermal_set_limits(sensor_nr, data,
1873                                 sensor_data->suspend_limit_lo,
1874                                 NCT1008_MAX_TEMP * 1000);
1875                 else
1876                         err = nct1008_thermal_set_limits(sensor_nr, data,
1877                                 NCT1008_MIN_TEMP * 1000,
1878                                 sensor_data->suspend_limit_hi);
1879
1880                 if (err)
1881                         goto error;
1882         }
1883
1884         /* Enable NCT wake. */
1885         err = enable_irq_wake(client->irq);
1886         if (err)
1887                 dev_err(&client->dev, "Error: %s, error=%d. failed to enable NCT wakeup\n",
1888                         __func__, err);
1889         return err;
1890
1891 error:
1892         dev_err(&client->dev, "\n error in file=: %s %s() line=%d: "
1893                 "error=%d. Can't set correct LP1 alarm limits or set wakeup irq, "
1894                 "shutting down device", __FILE__, __func__, __LINE__, err);
1895
1896         return nct1008_suspend_powerdown(dev);
1897 }
1898
1899 static int nct1008_suspend(struct device *dev)
1900 {
1901         struct i2c_client *client = to_i2c_client(dev);
1902         struct nct1008_data *data = i2c_get_clientdata(client);
1903
1904         if (data->plat_data.suspend_with_wakeup &&
1905                 data->plat_data.suspend_with_wakeup())
1906                 return nct1008_suspend_wakeup(dev);
1907         else
1908                 return nct1008_suspend_powerdown(dev);
1909 }
1910
1911
1912 static int nct1008_resume_wakeup(struct device *dev)
1913 {
1914         int err = 0;
1915         struct i2c_client *client = to_i2c_client(dev);
1916
1917         err = disable_irq_wake(client->irq);
1918         if (err) {
1919                 dev_err(&client->dev, "Error: %s, error=%d. failed to disable NCT "
1920                                 "wakeup\n", __func__, err);
1921                 return err;
1922         }
1923
1924         /* NCT wasn't powered down, so IRQ is still enabled. */
1925         /* Disable it before calling update */
1926         disable_irq(client->irq);
1927
1928         return err;
1929 }
1930
1931 static int nct1008_resume_powerdown(struct device *dev)
1932 {
1933         struct i2c_client *client = to_i2c_client(dev);
1934         int err = 0;
1935         struct nct1008_data *data = i2c_get_clientdata(client);
1936
1937         nct1008_power_control(data, true);
1938         nct1008_configure_sensor(data);
1939         err = nct1008_enable(client);
1940         if (err < 0) {
1941                 dev_err(&client->dev, "Error: %s, error=%d\n",
1942                         __func__, err);
1943                 return err;
1944         }
1945
1946         return err;
1947 }
1948
1949 static int nct1008_resume(struct device *dev)
1950 {
1951         struct i2c_client *client = to_i2c_client(dev);
1952         int err;
1953         struct nct1008_data *data = i2c_get_clientdata(client);
1954
1955         if (data->plat_data.suspend_with_wakeup &&
1956                 data->plat_data.suspend_with_wakeup())
1957                 err = nct1008_resume_wakeup(dev);
1958         else
1959                 err = nct1008_resume_powerdown(dev);
1960
1961         if (err)
1962                 return err;
1963
1964         nct1008_update(LOC, data);
1965         nct1008_update(EXT, data);
1966         mutex_lock(&data->mutex);
1967         data->stop_workqueue = 0;
1968         mutex_unlock(&data->mutex);
1969         enable_irq(client->irq);
1970
1971         return 0;
1972 }
1973
1974 static const struct dev_pm_ops nct1008_pm_ops = {
1975         .suspend        = nct1008_suspend,
1976         .resume         = nct1008_resume,
1977 };
1978
1979 #endif
1980
1981 static const struct i2c_device_id nct1008_id[] = {
1982         { "nct1008", NCT1008 },
1983         { "nct72", NCT72},
1984         {}
1985 };
1986 MODULE_DEVICE_TABLE(i2c, nct1008_id);
1987
1988 static const struct of_device_id nct1008_of_match[] = {
1989         {.compatible = "onsemi,nct72", },
1990         { }
1991 };
1992
1993 static struct i2c_driver nct1008_driver = {
1994         .driver = {
1995                 .name   = "nct1008_nct72",
1996 #ifdef CONFIG_PM_SLEEP
1997                 .pm = &nct1008_pm_ops,
1998 #endif
1999                 .of_match_table = nct1008_of_match,
2000         },
2001         .probe          = nct1008_probe,
2002         .remove         = nct1008_remove,
2003         .id_table       = nct1008_id,
2004         .shutdown       = nct1008_shutdown,
2005 };
2006
2007 static int __init nct1008_init(void)
2008 {
2009         return i2c_add_driver(&nct1008_driver);
2010 }
2011
2012 static void __exit nct1008_exit(void)
2013 {
2014         i2c_del_driver(&nct1008_driver);
2015 }
2016
2017 MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008/NCT72");
2018 MODULE_LICENSE("GPL");
2019
2020 module_init(nct1008_init);
2021 module_exit(nct1008_exit);