Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / sec-irq.c
1 /*
2  * sec-irq.c
3  *
4  * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
5  *              http://www.samsung.com
6  *
7  *  This program is free software; you can redistribute  it and/or modify it
8  *  under  the terms of  the GNU General  Public License as published by the
9  *  Free Software Foundation;  either version 2 of the  License, or (at your
10  *  option) any later version.
11  *
12  */
13
14 #include <linux/device.h>
15 #include <linux/interrupt.h>
16 #include <linux/irq.h>
17 #include <linux/regmap.h>
18
19 #include <linux/mfd/samsung/core.h>
20 #include <linux/mfd/samsung/irq.h>
21 #include <linux/mfd/samsung/s2mps11.h>
22 #include <linux/mfd/samsung/s2mps14.h>
23 #include <linux/mfd/samsung/s2mpu02.h>
24 #include <linux/mfd/samsung/s5m8763.h>
25 #include <linux/mfd/samsung/s5m8767.h>
26
27 static const struct regmap_irq s2mps11_irqs[] = {
28         [S2MPS11_IRQ_PWRONF] = {
29                 .reg_offset = 0,
30                 .mask = S2MPS11_IRQ_PWRONF_MASK,
31         },
32         [S2MPS11_IRQ_PWRONR] = {
33                 .reg_offset = 0,
34                 .mask = S2MPS11_IRQ_PWRONR_MASK,
35         },
36         [S2MPS11_IRQ_JIGONBF] = {
37                 .reg_offset = 0,
38                 .mask = S2MPS11_IRQ_JIGONBF_MASK,
39         },
40         [S2MPS11_IRQ_JIGONBR] = {
41                 .reg_offset = 0,
42                 .mask = S2MPS11_IRQ_JIGONBR_MASK,
43         },
44         [S2MPS11_IRQ_ACOKBF] = {
45                 .reg_offset = 0,
46                 .mask = S2MPS11_IRQ_ACOKBF_MASK,
47         },
48         [S2MPS11_IRQ_ACOKBR] = {
49                 .reg_offset = 0,
50                 .mask = S2MPS11_IRQ_ACOKBR_MASK,
51         },
52         [S2MPS11_IRQ_PWRON1S] = {
53                 .reg_offset = 0,
54                 .mask = S2MPS11_IRQ_PWRON1S_MASK,
55         },
56         [S2MPS11_IRQ_MRB] = {
57                 .reg_offset = 0,
58                 .mask = S2MPS11_IRQ_MRB_MASK,
59         },
60         [S2MPS11_IRQ_RTC60S] = {
61                 .reg_offset = 1,
62                 .mask = S2MPS11_IRQ_RTC60S_MASK,
63         },
64         [S2MPS11_IRQ_RTCA1] = {
65                 .reg_offset = 1,
66                 .mask = S2MPS11_IRQ_RTCA1_MASK,
67         },
68         [S2MPS11_IRQ_RTCA0] = {
69                 .reg_offset = 1,
70                 .mask = S2MPS11_IRQ_RTCA0_MASK,
71         },
72         [S2MPS11_IRQ_SMPL] = {
73                 .reg_offset = 1,
74                 .mask = S2MPS11_IRQ_SMPL_MASK,
75         },
76         [S2MPS11_IRQ_RTC1S] = {
77                 .reg_offset = 1,
78                 .mask = S2MPS11_IRQ_RTC1S_MASK,
79         },
80         [S2MPS11_IRQ_WTSR] = {
81                 .reg_offset = 1,
82                 .mask = S2MPS11_IRQ_WTSR_MASK,
83         },
84         [S2MPS11_IRQ_INT120C] = {
85                 .reg_offset = 2,
86                 .mask = S2MPS11_IRQ_INT120C_MASK,
87         },
88         [S2MPS11_IRQ_INT140C] = {
89                 .reg_offset = 2,
90                 .mask = S2MPS11_IRQ_INT140C_MASK,
91         },
92 };
93
94 static const struct regmap_irq s2mps14_irqs[] = {
95         [S2MPS14_IRQ_PWRONF] = {
96                 .reg_offset = 0,
97                 .mask = S2MPS11_IRQ_PWRONF_MASK,
98         },
99         [S2MPS14_IRQ_PWRONR] = {
100                 .reg_offset = 0,
101                 .mask = S2MPS11_IRQ_PWRONR_MASK,
102         },
103         [S2MPS14_IRQ_JIGONBF] = {
104                 .reg_offset = 0,
105                 .mask = S2MPS11_IRQ_JIGONBF_MASK,
106         },
107         [S2MPS14_IRQ_JIGONBR] = {
108                 .reg_offset = 0,
109                 .mask = S2MPS11_IRQ_JIGONBR_MASK,
110         },
111         [S2MPS14_IRQ_ACOKBF] = {
112                 .reg_offset = 0,
113                 .mask = S2MPS11_IRQ_ACOKBF_MASK,
114         },
115         [S2MPS14_IRQ_ACOKBR] = {
116                 .reg_offset = 0,
117                 .mask = S2MPS11_IRQ_ACOKBR_MASK,
118         },
119         [S2MPS14_IRQ_PWRON1S] = {
120                 .reg_offset = 0,
121                 .mask = S2MPS11_IRQ_PWRON1S_MASK,
122         },
123         [S2MPS14_IRQ_MRB] = {
124                 .reg_offset = 0,
125                 .mask = S2MPS11_IRQ_MRB_MASK,
126         },
127         [S2MPS14_IRQ_RTC60S] = {
128                 .reg_offset = 1,
129                 .mask = S2MPS11_IRQ_RTC60S_MASK,
130         },
131         [S2MPS14_IRQ_RTCA1] = {
132                 .reg_offset = 1,
133                 .mask = S2MPS11_IRQ_RTCA1_MASK,
134         },
135         [S2MPS14_IRQ_RTCA0] = {
136                 .reg_offset = 1,
137                 .mask = S2MPS11_IRQ_RTCA0_MASK,
138         },
139         [S2MPS14_IRQ_SMPL] = {
140                 .reg_offset = 1,
141                 .mask = S2MPS11_IRQ_SMPL_MASK,
142         },
143         [S2MPS14_IRQ_RTC1S] = {
144                 .reg_offset = 1,
145                 .mask = S2MPS11_IRQ_RTC1S_MASK,
146         },
147         [S2MPS14_IRQ_WTSR] = {
148                 .reg_offset = 1,
149                 .mask = S2MPS11_IRQ_WTSR_MASK,
150         },
151         [S2MPS14_IRQ_INT120C] = {
152                 .reg_offset = 2,
153                 .mask = S2MPS11_IRQ_INT120C_MASK,
154         },
155         [S2MPS14_IRQ_INT140C] = {
156                 .reg_offset = 2,
157                 .mask = S2MPS11_IRQ_INT140C_MASK,
158         },
159         [S2MPS14_IRQ_TSD] = {
160                 .reg_offset = 2,
161                 .mask = S2MPS14_IRQ_TSD_MASK,
162         },
163 };
164
165 static const struct regmap_irq s2mpu02_irqs[] = {
166         [S2MPU02_IRQ_PWRONF] = {
167                 .reg_offset = 0,
168                 .mask = S2MPS11_IRQ_PWRONF_MASK,
169         },
170         [S2MPU02_IRQ_PWRONR] = {
171                 .reg_offset = 0,
172                 .mask = S2MPS11_IRQ_PWRONR_MASK,
173         },
174         [S2MPU02_IRQ_JIGONBF] = {
175                 .reg_offset = 0,
176                 .mask = S2MPS11_IRQ_JIGONBF_MASK,
177         },
178         [S2MPU02_IRQ_JIGONBR] = {
179                 .reg_offset = 0,
180                 .mask = S2MPS11_IRQ_JIGONBR_MASK,
181         },
182         [S2MPU02_IRQ_ACOKBF] = {
183                 .reg_offset = 0,
184                 .mask = S2MPS11_IRQ_ACOKBF_MASK,
185         },
186         [S2MPU02_IRQ_ACOKBR] = {
187                 .reg_offset = 0,
188                 .mask = S2MPS11_IRQ_ACOKBR_MASK,
189         },
190         [S2MPU02_IRQ_PWRON1S] = {
191                 .reg_offset = 0,
192                 .mask = S2MPS11_IRQ_PWRON1S_MASK,
193         },
194         [S2MPU02_IRQ_MRB] = {
195                 .reg_offset = 0,
196                 .mask = S2MPS11_IRQ_MRB_MASK,
197         },
198         [S2MPU02_IRQ_RTC60S] = {
199                 .reg_offset = 1,
200                 .mask = S2MPS11_IRQ_RTC60S_MASK,
201         },
202         [S2MPU02_IRQ_RTCA1] = {
203                 .reg_offset = 1,
204                 .mask = S2MPS11_IRQ_RTCA1_MASK,
205         },
206         [S2MPU02_IRQ_RTCA0] = {
207                 .reg_offset = 1,
208                 .mask = S2MPS11_IRQ_RTCA0_MASK,
209         },
210         [S2MPU02_IRQ_SMPL] = {
211                 .reg_offset = 1,
212                 .mask = S2MPS11_IRQ_SMPL_MASK,
213         },
214         [S2MPU02_IRQ_RTC1S] = {
215                 .reg_offset = 1,
216                 .mask = S2MPS11_IRQ_RTC1S_MASK,
217         },
218         [S2MPU02_IRQ_WTSR] = {
219                 .reg_offset = 1,
220                 .mask = S2MPS11_IRQ_WTSR_MASK,
221         },
222         [S2MPU02_IRQ_INT120C] = {
223                 .reg_offset = 2,
224                 .mask = S2MPS11_IRQ_INT120C_MASK,
225         },
226         [S2MPU02_IRQ_INT140C] = {
227                 .reg_offset = 2,
228                 .mask = S2MPS11_IRQ_INT140C_MASK,
229         },
230         [S2MPU02_IRQ_TSD] = {
231                 .reg_offset = 2,
232                 .mask = S2MPS14_IRQ_TSD_MASK,
233         },
234 };
235
236 static const struct regmap_irq s5m8767_irqs[] = {
237         [S5M8767_IRQ_PWRR] = {
238                 .reg_offset = 0,
239                 .mask = S5M8767_IRQ_PWRR_MASK,
240         },
241         [S5M8767_IRQ_PWRF] = {
242                 .reg_offset = 0,
243                 .mask = S5M8767_IRQ_PWRF_MASK,
244         },
245         [S5M8767_IRQ_PWR1S] = {
246                 .reg_offset = 0,
247                 .mask = S5M8767_IRQ_PWR1S_MASK,
248         },
249         [S5M8767_IRQ_JIGR] = {
250                 .reg_offset = 0,
251                 .mask = S5M8767_IRQ_JIGR_MASK,
252         },
253         [S5M8767_IRQ_JIGF] = {
254                 .reg_offset = 0,
255                 .mask = S5M8767_IRQ_JIGF_MASK,
256         },
257         [S5M8767_IRQ_LOWBAT2] = {
258                 .reg_offset = 0,
259                 .mask = S5M8767_IRQ_LOWBAT2_MASK,
260         },
261         [S5M8767_IRQ_LOWBAT1] = {
262                 .reg_offset = 0,
263                 .mask = S5M8767_IRQ_LOWBAT1_MASK,
264         },
265         [S5M8767_IRQ_MRB] = {
266                 .reg_offset = 1,
267                 .mask = S5M8767_IRQ_MRB_MASK,
268         },
269         [S5M8767_IRQ_DVSOK2] = {
270                 .reg_offset = 1,
271                 .mask = S5M8767_IRQ_DVSOK2_MASK,
272         },
273         [S5M8767_IRQ_DVSOK3] = {
274                 .reg_offset = 1,
275                 .mask = S5M8767_IRQ_DVSOK3_MASK,
276         },
277         [S5M8767_IRQ_DVSOK4] = {
278                 .reg_offset = 1,
279                 .mask = S5M8767_IRQ_DVSOK4_MASK,
280         },
281         [S5M8767_IRQ_RTC60S] = {
282                 .reg_offset = 2,
283                 .mask = S5M8767_IRQ_RTC60S_MASK,
284         },
285         [S5M8767_IRQ_RTCA1] = {
286                 .reg_offset = 2,
287                 .mask = S5M8767_IRQ_RTCA1_MASK,
288         },
289         [S5M8767_IRQ_RTCA2] = {
290                 .reg_offset = 2,
291                 .mask = S5M8767_IRQ_RTCA2_MASK,
292         },
293         [S5M8767_IRQ_SMPL] = {
294                 .reg_offset = 2,
295                 .mask = S5M8767_IRQ_SMPL_MASK,
296         },
297         [S5M8767_IRQ_RTC1S] = {
298                 .reg_offset = 2,
299                 .mask = S5M8767_IRQ_RTC1S_MASK,
300         },
301         [S5M8767_IRQ_WTSR] = {
302                 .reg_offset = 2,
303                 .mask = S5M8767_IRQ_WTSR_MASK,
304         },
305 };
306
307 static const struct regmap_irq s5m8763_irqs[] = {
308         [S5M8763_IRQ_DCINF] = {
309                 .reg_offset = 0,
310                 .mask = S5M8763_IRQ_DCINF_MASK,
311         },
312         [S5M8763_IRQ_DCINR] = {
313                 .reg_offset = 0,
314                 .mask = S5M8763_IRQ_DCINR_MASK,
315         },
316         [S5M8763_IRQ_JIGF] = {
317                 .reg_offset = 0,
318                 .mask = S5M8763_IRQ_JIGF_MASK,
319         },
320         [S5M8763_IRQ_JIGR] = {
321                 .reg_offset = 0,
322                 .mask = S5M8763_IRQ_JIGR_MASK,
323         },
324         [S5M8763_IRQ_PWRONF] = {
325                 .reg_offset = 0,
326                 .mask = S5M8763_IRQ_PWRONF_MASK,
327         },
328         [S5M8763_IRQ_PWRONR] = {
329                 .reg_offset = 0,
330                 .mask = S5M8763_IRQ_PWRONR_MASK,
331         },
332         [S5M8763_IRQ_WTSREVNT] = {
333                 .reg_offset = 1,
334                 .mask = S5M8763_IRQ_WTSREVNT_MASK,
335         },
336         [S5M8763_IRQ_SMPLEVNT] = {
337                 .reg_offset = 1,
338                 .mask = S5M8763_IRQ_SMPLEVNT_MASK,
339         },
340         [S5M8763_IRQ_ALARM1] = {
341                 .reg_offset = 1,
342                 .mask = S5M8763_IRQ_ALARM1_MASK,
343         },
344         [S5M8763_IRQ_ALARM0] = {
345                 .reg_offset = 1,
346                 .mask = S5M8763_IRQ_ALARM0_MASK,
347         },
348         [S5M8763_IRQ_ONKEY1S] = {
349                 .reg_offset = 2,
350                 .mask = S5M8763_IRQ_ONKEY1S_MASK,
351         },
352         [S5M8763_IRQ_TOPOFFR] = {
353                 .reg_offset = 2,
354                 .mask = S5M8763_IRQ_TOPOFFR_MASK,
355         },
356         [S5M8763_IRQ_DCINOVPR] = {
357                 .reg_offset = 2,
358                 .mask = S5M8763_IRQ_DCINOVPR_MASK,
359         },
360         [S5M8763_IRQ_CHGRSTF] = {
361                 .reg_offset = 2,
362                 .mask = S5M8763_IRQ_CHGRSTF_MASK,
363         },
364         [S5M8763_IRQ_DONER] = {
365                 .reg_offset = 2,
366                 .mask = S5M8763_IRQ_DONER_MASK,
367         },
368         [S5M8763_IRQ_CHGFAULT] = {
369                 .reg_offset = 2,
370                 .mask = S5M8763_IRQ_CHGFAULT_MASK,
371         },
372         [S5M8763_IRQ_LOBAT1] = {
373                 .reg_offset = 3,
374                 .mask = S5M8763_IRQ_LOBAT1_MASK,
375         },
376         [S5M8763_IRQ_LOBAT2] = {
377                 .reg_offset = 3,
378                 .mask = S5M8763_IRQ_LOBAT2_MASK,
379         },
380 };
381
382 static const struct regmap_irq_chip s2mps11_irq_chip = {
383         .name = "s2mps11",
384         .irqs = s2mps11_irqs,
385         .num_irqs = ARRAY_SIZE(s2mps11_irqs),
386         .num_regs = 3,
387         .status_base = S2MPS11_REG_INT1,
388         .mask_base = S2MPS11_REG_INT1M,
389         .ack_base = S2MPS11_REG_INT1,
390 };
391
392 #define S2MPS1X_IRQ_CHIP_COMMON_DATA            \
393         .irqs = s2mps14_irqs,                   \
394         .num_irqs = ARRAY_SIZE(s2mps14_irqs),   \
395         .num_regs = 3,                          \
396         .status_base = S2MPS14_REG_INT1,        \
397         .mask_base = S2MPS14_REG_INT1M,         \
398         .ack_base = S2MPS14_REG_INT1            \
399
400 static const struct regmap_irq_chip s2mps13_irq_chip = {
401         .name = "s2mps13",
402         S2MPS1X_IRQ_CHIP_COMMON_DATA,
403 };
404
405 static const struct regmap_irq_chip s2mps14_irq_chip = {
406         .name = "s2mps14",
407         S2MPS1X_IRQ_CHIP_COMMON_DATA,
408 };
409
410 static const struct regmap_irq_chip s2mpu02_irq_chip = {
411         .name = "s2mpu02",
412         .irqs = s2mpu02_irqs,
413         .num_irqs = ARRAY_SIZE(s2mpu02_irqs),
414         .num_regs = 3,
415         .status_base = S2MPU02_REG_INT1,
416         .mask_base = S2MPU02_REG_INT1M,
417         .ack_base = S2MPU02_REG_INT1,
418 };
419
420 static const struct regmap_irq_chip s5m8767_irq_chip = {
421         .name = "s5m8767",
422         .irqs = s5m8767_irqs,
423         .num_irqs = ARRAY_SIZE(s5m8767_irqs),
424         .num_regs = 3,
425         .status_base = S5M8767_REG_INT1,
426         .mask_base = S5M8767_REG_INT1M,
427         .ack_base = S5M8767_REG_INT1,
428 };
429
430 static const struct regmap_irq_chip s5m8763_irq_chip = {
431         .name = "s5m8763",
432         .irqs = s5m8763_irqs,
433         .num_irqs = ARRAY_SIZE(s5m8763_irqs),
434         .num_regs = 4,
435         .status_base = S5M8763_REG_IRQ1,
436         .mask_base = S5M8763_REG_IRQM1,
437         .ack_base = S5M8763_REG_IRQ1,
438 };
439
440 int sec_irq_init(struct sec_pmic_dev *sec_pmic)
441 {
442         int ret = 0;
443         int type = sec_pmic->device_type;
444         const struct regmap_irq_chip *sec_irq_chip;
445
446         if (!sec_pmic->irq) {
447                 dev_warn(sec_pmic->dev,
448                          "No interrupt specified, no interrupts\n");
449                 sec_pmic->irq_base = 0;
450                 return 0;
451         }
452
453         switch (type) {
454         case S5M8763X:
455                 sec_irq_chip = &s5m8763_irq_chip;
456                 break;
457         case S5M8767X:
458                 sec_irq_chip = &s5m8767_irq_chip;
459                 break;
460         case S2MPS11X:
461                 sec_irq_chip = &s2mps11_irq_chip;
462                 break;
463         case S2MPS13X:
464                 sec_irq_chip = &s2mps13_irq_chip;
465                 break;
466         case S2MPS14X:
467                 sec_irq_chip = &s2mps14_irq_chip;
468                 break;
469         case S2MPU02:
470                 sec_irq_chip = &s2mpu02_irq_chip;
471                 break;
472         default:
473                 dev_err(sec_pmic->dev, "Unknown device type %lu\n",
474                         sec_pmic->device_type);
475                 return -EINVAL;
476         }
477
478         ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
479                           IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
480                           sec_pmic->irq_base, sec_irq_chip,
481                           &sec_pmic->irq_data);
482         if (ret != 0) {
483                 dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
484                 return ret;
485         }
486
487         /*
488          * The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
489          * so the interrupt number must be consistent.
490          */
491         BUILD_BUG_ON(((enum s2mps14_irq)S2MPS11_IRQ_RTCA0) != S2MPS14_IRQ_RTCA0);
492
493         return 0;
494 }
495
496 void sec_irq_exit(struct sec_pmic_dev *sec_pmic)
497 {
498         regmap_del_irq_chip(sec_pmic->irq, sec_pmic->irq_data);
499 }