usb: dwc3: rockchip: fix possible circular deadlock
[firefly-linux-kernel-4.4.55.git] / drivers / hwmon / rockchip_tsadc.c
1 /*
2  * Copyright (C) ST-Ericsson 2010 - 2013
3  * Author: Martin Persson <martin.persson@stericsson.com>
4  *         Hongbo Zhang <hongbo.zhang@linaro.org>
5  * License Terms: GNU General Public License v2
6  *
7  * When the AB8500 thermal warning temperature is reached (threshold cannot
8  * be changed by SW), an interrupt is set, and if no further action is taken
9  * within a certain time frame, pm_power off will be called.
10  *
11  * When AB8500 thermal shutdown temperature is reached a hardware shutdown of
12  * the AB8500 will occur.
13  */
14
15  #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/device.h>
19 #include <linux/platform_device.h>
20 #include <linux/err.h>
21 #include <linux/clk.h>
22 #include <linux/interrupt.h>
23 #include <linux/irq.h>
24 #include <linux/io.h>
25 #include <linux/delay.h>
26 #include <linux/slab.h>
27 #include <linux/workqueue.h>
28 #include <linux/ioport.h>
29
30 #include <linux/err.h>
31 #include <linux/hwmon.h>
32 #include <linux/hwmon-sysfs.h>
33 #include <linux/module.h>
34 #include <linux/slab.h>
35 #include <linux/sysfs.h>
36
37 #include <linux/timer.h>
38 #include <linux/completion.h>
39 #include <linux/of_irq.h>
40 #include <linux/regulator/consumer.h>
41 #include <linux/of_platform.h>
42 #include <linux/of.h>
43 #include <linux/of_device.h>
44 #include <linux/rockchip/common.h>
45 #include "hwmon-rockchip.h"
46
47
48 #define DEFAULT_POWER_OFF_DELAY (HZ * 10)
49 /* Number of monitored sensors should not greater than NUM_SENSORS */
50 #define NUM_MONITORED_SENSORS   4
51
52 #define TSADC_USER_CON  0x00
53 #define TSADC_AUTO_CON  0x04
54
55 #define TSADC_CTRL_CH(ch)       ((ch) << 0)
56 #define TSADC_CTRL_POWER_UP     (1 << 3)
57 #define TSADC_CTRL_START        (1 << 4)
58
59 #define TSADC_STAS_BUSY         (1 << 12)
60 #define TSADC_STAS_BUSY_MASK    (1 << 12)
61 #define TSADC_AUTO_STAS_BUSY            (1 << 16)
62 #define TSADC_AUTO_STAS_BUSY_MASK       (1 << 16)
63 #define TSADC_SAMPLE_DLY_SEL  (1 << 17)
64 #define TSADC_SAMPLE_DLY_SEL_MASK  (1 << 17)
65
66 #define TSADC_INT_EN  0x08
67 #define TSADC_INT_PD  0x0c
68
69 #define TSADC_DATA0  0x20
70 #define TSADC_DATA1  0x24
71 #define TSADC_DATA2  0x28
72 #define TSADC_DATA3  0x2c
73 #define TSADC_DATA_MASK         0xfff
74
75 #define TSADC_COMP0_INT  0x30
76 #define TSADC_COMP1_INT  0x34
77 #define TSADC_COMP2_INT  0x38
78 #define TSADC_COMP3_INT  0x3c
79
80 #define TSADC_COMP0_SHUT  0x40
81 #define TSADC_COMP1_SHUT  0x44
82 #define TSADC_COMP2_SHUT  0x48
83 #define TSADC_COMP3_SHUT  0x4c
84
85 #define TSADC_HIGHT_INT_DEBOUNCE  0x60
86 #define TSADC_HIGHT_TSHUT_DEBOUNCE  0x64
87 #define TSADC_HIGHT_INT_DEBOUNCE_TIME 0x0a
88 #define TSADC_HIGHT_TSHUT_DEBOUNCE_TIME 0x0a
89
90 #define TSADC_AUTO_PERIOD  0x68
91 #define TSADC_AUTO_PERIOD_HT  0x6c
92 #define TSADC_AUTO_PERIOD_TIME  0x03e8
93 #define TSADC_AUTO_PERIOD_HT_TIME  0x64
94
95 #define TSADC_AUTO_EVENT_NAME           "tsadc"
96
97 #define TSADC_COMP_INT_DATA             80
98 #define TSADC_COMP_INT_DATA_MASK                0xfff
99 #define TSADC_COMP_SHUT_DATA_MASK               0xfff
100 #define TSADC_TEMP_INT_EN 0
101 #define TSADC_TEMP_SHUT_EN 1
102 static int tsadc_ht_temp;
103 static int tsadc_ht_reset_cru;
104 static int tsadc_ht_pull_gpio;
105
106 struct tsadc_port {
107         struct pinctrl          *pctl;
108         struct pinctrl_state    *pins_default;
109         struct pinctrl_state    *pins_tsadc_int;
110 };
111
112 struct rockchip_tsadc_temp {
113         struct delayed_work power_off_work;
114         struct rockchip_temp *rockchip_data;
115         void __iomem            *regs;
116         struct clk              *clk;
117         struct clk              *pclk;
118         int irq;
119         struct resource         *ioarea;
120         struct tsadc_host               *tsadc;
121         struct work_struct      auto_ht_irq_work;
122         struct workqueue_struct  *workqueue;
123         struct workqueue_struct  *tsadc_workqueue;
124 };
125 struct tsadc_table
126 {
127         int code;
128         int temp;
129 };
130
131 static const struct tsadc_table table[] =
132 {
133         {TSADC_DATA_MASK, -40},
134
135         {3800, -40},
136         {3792, -35},
137         {3783, -30},
138         {3774, -25},
139         {3765, -20},
140         {3756, -15},
141         {3747, -10},
142         {3737, -5},
143         {3728, 0},
144         {3718, 5},
145
146         {3708, 10},
147         {3698, 15},
148         {3688, 20},
149         {3678, 25},
150         {3667, 30},
151         {3656, 35},
152         {3645, 40},
153         {3634, 45},
154         {3623, 50},
155         {3611, 55},
156
157         {3600, 60},
158         {3588, 65},
159         {3575, 70},
160         {3563, 75},
161         {3550, 80},
162         {3537, 85},
163         {3524, 90},
164         {3510, 95},
165         {3496, 100},
166         {3482, 105},
167
168         {3467, 110},
169         {3452, 115},
170         {3437, 120},
171         {3421, 125},
172
173         {0, 125},
174 };
175
176 static struct rockchip_tsadc_temp *g_dev;
177
178 static DEFINE_MUTEX(tsadc_mutex);
179
180 static u32 tsadc_readl(u32 offset)
181 {
182         return readl_relaxed(g_dev->regs + offset);
183 }
184
185 static void tsadc_writel(u32 val, u32 offset)
186 {
187         writel_relaxed(val, g_dev->regs + offset);
188 }
189
190 void rockchip_tsadc_auto_ht_work(struct work_struct *work)
191 {
192         int ret,val;
193
194 //      printk("%s,line=%d\n", __func__,__LINE__);
195
196         mutex_lock(&tsadc_mutex);
197
198         val = tsadc_readl(TSADC_INT_PD);
199         tsadc_writel(val &(~ (1 <<8) ), TSADC_INT_PD);
200         ret = tsadc_readl(TSADC_INT_PD);
201         tsadc_writel(ret | 0xff, TSADC_INT_PD);       //clr irq status
202         if ((val & 0x0f) != 0){
203                 printk("rockchip tsadc is over temp . %s,line=%d\n", __func__,__LINE__);
204                 pm_power_off();                                 //power_off
205         }
206         mutex_unlock(&tsadc_mutex);
207 }
208
209 static irqreturn_t rockchip_tsadc_auto_ht_interrupt(int irq, void *data)
210 {
211         struct rockchip_tsadc_temp *dev = data;
212
213         printk("%s,line=%d\n", __func__,__LINE__);
214         
215         queue_work(dev->workqueue, &dev->auto_ht_irq_work);
216         
217         return IRQ_HANDLED;
218 }
219
220 static void rockchip_tsadc_set_cmpn_int_vale( int chn, int temp)
221 {
222         u32 code = 0;
223         int i;
224
225         for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
226                 if (temp <= table[i].temp && temp > table[i -1].temp) {
227                         code = table[i].code;
228                 }
229         }
230         tsadc_writel((code & TSADC_COMP_INT_DATA_MASK), (TSADC_COMP0_INT + chn*4));
231
232 }
233
234 static void rockchip_tsadc_set_cmpn_shut_vale( int chn, int temp)
235 {
236         u32 code=0;
237         int i;
238
239         for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
240                 if (temp <= table[i].temp && temp > table[i -1].temp) {
241                         code = table[i].code;
242                 }
243         }
244
245         tsadc_writel((code & TSADC_COMP_SHUT_DATA_MASK), (TSADC_COMP0_SHUT + chn*4));
246 }
247
248 static void rockchip_tsadc_set_auto_int_en( int chn, int ht_int_en,int tshut_en)
249 {
250         u32 ret;
251         tsadc_writel(0, TSADC_INT_EN);
252         if (ht_int_en){
253                 ret = tsadc_readl(TSADC_INT_EN);
254                 tsadc_writel( ret | (1 << chn), TSADC_INT_EN);
255         }
256         if (tshut_en){
257                 ret = tsadc_readl(TSADC_INT_EN);
258                 if (tsadc_ht_pull_gpio)
259                         tsadc_writel(ret | (0xf << (chn + 4)), TSADC_INT_EN);
260                 else if (tsadc_ht_reset_cru)
261                         tsadc_writel(ret | (0xf << (chn + 8)), TSADC_INT_EN);
262         }       
263
264 }
265 static void rockchip_tsadc_auto_mode_set(int chn, int int_temp,
266         int shut_temp, int int_en, int shut_en)
267 {
268         u32 ret;
269         
270         if (!g_dev || chn > 4)
271                 return;
272         
273         mutex_lock(&tsadc_mutex);
274         
275         clk_enable(g_dev->pclk);
276         clk_enable(g_dev->clk);
277         
278         msleep(10);
279         tsadc_writel(0, TSADC_AUTO_CON);
280         tsadc_writel(3 << (4+chn), TSADC_AUTO_CON);
281         msleep(10);
282         if ((tsadc_readl(TSADC_AUTO_CON) & TSADC_AUTO_STAS_BUSY_MASK) != TSADC_AUTO_STAS_BUSY) {
283                 rockchip_tsadc_set_cmpn_int_vale(chn,int_temp);
284                 rockchip_tsadc_set_cmpn_shut_vale(chn,shut_temp),
285
286                 tsadc_writel(TSADC_AUTO_PERIOD_TIME, TSADC_AUTO_PERIOD);
287                 tsadc_writel(TSADC_AUTO_PERIOD_HT_TIME, TSADC_AUTO_PERIOD_HT);
288
289                 tsadc_writel(TSADC_HIGHT_INT_DEBOUNCE_TIME,
290                         TSADC_HIGHT_INT_DEBOUNCE);
291                 tsadc_writel(TSADC_HIGHT_TSHUT_DEBOUNCE_TIME,
292                         TSADC_HIGHT_TSHUT_DEBOUNCE);
293                 
294                 rockchip_tsadc_set_auto_int_en(chn,int_en,shut_en);     
295         }
296
297         msleep(10);
298
299         ret = tsadc_readl(TSADC_AUTO_CON);
300         tsadc_writel(ret | (1 <<0) , TSADC_AUTO_CON);
301         
302         mutex_unlock(&tsadc_mutex);
303                 
304 }
305
306 int rockchip_tsadc_set_auto_temp(int chn)
307 {
308         rockchip_tsadc_auto_mode_set(chn, TSADC_COMP_INT_DATA,
309                 tsadc_ht_temp, TSADC_TEMP_INT_EN, TSADC_TEMP_SHUT_EN);
310         return 0;
311 }
312 EXPORT_SYMBOL(rockchip_tsadc_set_auto_temp);
313
314 static void rockchip_tsadc_get(int chn, int *temp, int *code)
315 {
316         int i;
317         *temp = 0;
318         *code = 0;
319
320         if (!g_dev || chn > 4){
321                 *temp = INVALID_TEMP;
322                 return ;
323         }
324 #if 0
325         mutex_lock(&tsadc_mutex);
326
327         clk_enable(g_dev->pclk);
328         clk_enable(g_dev->clk);
329
330         msleep(10);
331         tsadc_writel(0, TSADC_USER_CON);
332         tsadc_writel(TSADC_CTRL_POWER_UP | TSADC_CTRL_CH(chn), TSADC_USER_CON);
333         msleep(20);
334         if ((tsadc_readl(TSADC_USER_CON) & TSADC_STAS_BUSY_MASK) != TSADC_STAS_BUSY) {
335                 *code = tsadc_readl((TSADC_DATA0 + chn*4)) & TSADC_DATA_MASK;
336                 for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
337                         if ((*code) <= table[i].code && (*code) > table[i + 1].code) {
338                                 *temp = table[i].temp + (table[i + 1].temp - table[i].temp) * (table[i].code - (*code)) / (table[i].code - table[i + 1].code);
339                         }
340                 }
341         }
342         
343         tsadc_writel(0, TSADC_USER_CON);
344
345         clk_disable(g_dev->clk);
346         clk_disable(g_dev->pclk);
347
348         mutex_unlock(&tsadc_mutex);
349 #else
350         *code = tsadc_readl((TSADC_DATA0 + chn*4)) & TSADC_DATA_MASK;
351         for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
352                 if ((*code) <= table[i].code && (*code) > table[i + 1].code)
353                         *temp = table[i].temp + (table[i + 1].temp
354                         - table[i].temp) * (table[i].code - (*code))
355                         / (table[i].code - table[i + 1].code);
356         }
357 #endif
358 }
359
360  int rockchip_tsadc_get_temp(int chn)
361 {
362         int temp, code;
363         
364         rockchip_tsadc_get(chn, &temp, &code);
365
366         return temp;
367 }
368 EXPORT_SYMBOL(rockchip_tsadc_get_temp);
369
370 static ssize_t rockchip_show_name(struct device *dev,
371                 struct device_attribute *devattr, char *buf)
372 {
373         return sprintf(buf, "rockchip-tsadc\n");
374 }
375
376 static ssize_t rockchip_show_label(struct device *dev,
377                 struct device_attribute *devattr, char *buf)
378 {
379         char *label;
380         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
381         int index = attr->index;
382
383         switch (index) {
384         case 0:
385                 label = "tsadc0";
386                 break;
387         case 1:
388                 label = "tsadc1";
389                 break;
390         case 2:
391                 label = "tsadc2";
392                 break;
393         case 3:
394                 label = "tsadc3";
395                 break;
396         default:
397                 return -EINVAL;
398         }
399
400         return sprintf(buf, "%s\n", label);
401 }
402
403 int rockchip_hwmon_init(struct rockchip_temp *data)
404 {
405         struct rockchip_tsadc_temp *rockchip_tsadc_data;
406         struct resource *res;
407         struct device_node *np = data->pdev->dev.of_node;
408         int ret,irq;
409         u32 rate;
410         struct tsadc_port *uap;
411         
412         rockchip_tsadc_data = devm_kzalloc(&data->pdev->dev, sizeof(*rockchip_tsadc_data),
413                 GFP_KERNEL);
414         if (!rockchip_tsadc_data)
415                 return -ENOMEM;
416
417         res = platform_get_resource(data->pdev, IORESOURCE_MEM, 0);
418         rockchip_tsadc_data->regs = devm_request_and_ioremap(&data->pdev->dev, res);
419         if (!rockchip_tsadc_data->regs) {
420                 dev_err(&data->pdev->dev, "cannot map IO\n");
421                 return -ENXIO;
422         } 
423
424         //irq request   
425         irq = platform_get_irq(data->pdev, 0);
426         if (irq < 0) {
427                 dev_err(&data->pdev->dev, "no irq resource?\n");
428                 return -EPERM;
429         }
430         rockchip_tsadc_data->irq = irq;
431         ret = request_threaded_irq(rockchip_tsadc_data->irq, NULL, rockchip_tsadc_auto_ht_interrupt, IRQF_ONESHOT, TSADC_AUTO_EVENT_NAME, rockchip_tsadc_data);
432         if (ret < 0) {
433                 dev_err(&data->pdev->dev, "failed to attach tsadc irq\n");
434                 return -EPERM;
435         }       
436
437         rockchip_tsadc_data->workqueue = create_singlethread_workqueue("rockchip_tsadc");
438         INIT_WORK(&rockchip_tsadc_data->auto_ht_irq_work, rockchip_tsadc_auto_ht_work);
439         
440         //clk enable
441         rockchip_tsadc_data->clk = devm_clk_get(&data->pdev->dev, "tsadc");
442         if (IS_ERR(rockchip_tsadc_data->clk)) {
443             dev_err(&data->pdev->dev, "failed to get tsadc clock\n");
444             ret = PTR_ERR(rockchip_tsadc_data->clk);
445             return -EPERM;
446         }
447
448         if(of_property_read_u32(np, "clock-frequency", &rate)) {
449           dev_err(&data->pdev->dev, "Missing clock-frequency property in the DT.\n");
450           return -EPERM;
451         }
452
453         ret = clk_set_rate(rockchip_tsadc_data->clk, rate);
454             if(ret < 0) {
455             dev_err(&data->pdev->dev, "failed to set adc clk\n");
456             return -EPERM;
457         }
458         clk_prepare_enable(rockchip_tsadc_data->clk);
459
460         rockchip_tsadc_data->pclk = devm_clk_get(&data->pdev->dev, "pclk_tsadc");
461         if (IS_ERR(rockchip_tsadc_data->pclk)) {
462             dev_err(&data->pdev->dev, "failed to get tsadc pclk\n");
463             ret = PTR_ERR(rockchip_tsadc_data->pclk);
464             return -EPERM;
465         }
466         clk_prepare_enable(rockchip_tsadc_data->pclk);
467
468         platform_set_drvdata(data->pdev, rockchip_tsadc_data);
469         g_dev = rockchip_tsadc_data;
470         data->plat_data = rockchip_tsadc_data;
471
472         if (of_property_read_u32(np, "tsadc-ht-temp",
473                 &tsadc_ht_temp)) {
474                 dev_err(&data->pdev->dev, "Missing  tsadc_ht_temp in the DT.\n");
475                 return -EPERM;
476         }
477         if (of_property_read_u32(np, "tsadc-ht-reset-cru",
478                 &tsadc_ht_reset_cru)) {
479                 dev_err(&data->pdev->dev, "Missing tsadc_ht_reset_cru in the DT.\n");
480                 return -EPERM;
481         }
482         if (of_property_read_u32(np, "tsadc-ht-pull-gpio",
483                 &tsadc_ht_pull_gpio)) {
484                 dev_err(&data->pdev->dev, "Missing tsadc_ht_pull_gpio in the DT.\n");
485                 return -EPERM;
486         }
487
488         if (tsadc_ht_pull_gpio){
489                 /*bit8=1 gpio0_b2 = 1 shutdown else gpio0_b2 =1 shutdown*/
490                 /*
491                 ret = tsadc_readl(TSADC_AUTO_CON);
492                 tsadc_writel(ret | (1 << 8) , TSADC_AUTO_CON);
493                 */
494                 uap = devm_kzalloc(&data->pdev->dev, sizeof(struct tsadc_port),
495                 GFP_KERNEL);
496                 if (uap == NULL)
497                         dev_err(&data->pdev->dev,
498                         "uap is not set %s,line=%d\n", __func__, __LINE__);
499                 uap->pctl = devm_pinctrl_get(&data->pdev->dev);
500                 uap->pins_default = pinctrl_lookup_state(uap->pctl, "default");
501                 uap->pins_tsadc_int = pinctrl_lookup_state(uap->pctl, "tsadc_int");
502                 pinctrl_select_state(uap->pctl, uap->pins_tsadc_int);
503         }
504
505         rockchip_tsadc_set_auto_temp(1);
506
507         data->monitored_sensors = NUM_MONITORED_SENSORS;
508         data->ops.read_sensor = rockchip_tsadc_get_temp;
509         data->ops.show_name = rockchip_show_name;
510         data->ops.show_label = rockchip_show_label;
511         data->ops.is_visible = NULL;
512
513         dev_info(&data->pdev->dev, "initialized\n");
514         return 0;
515 }
516 EXPORT_SYMBOL(rockchip_hwmon_init);
517
518 MODULE_LICENSE("GPL");
519 MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
520 MODULE_DESCRIPTION("Driver for TSADC");