Merge branch 'parisc-4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[cascardo/linux.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 s2mps15_irq_chip = {
411         .name = "s2mps15",
412         S2MPS1X_IRQ_CHIP_COMMON_DATA,
413 };
414
415 static const struct regmap_irq_chip s2mpu02_irq_chip = {
416         .name = "s2mpu02",
417         .irqs = s2mpu02_irqs,
418         .num_irqs = ARRAY_SIZE(s2mpu02_irqs),
419         .num_regs = 3,
420         .status_base = S2MPU02_REG_INT1,
421         .mask_base = S2MPU02_REG_INT1M,
422         .ack_base = S2MPU02_REG_INT1,
423 };
424
425 static const struct regmap_irq_chip s5m8767_irq_chip = {
426         .name = "s5m8767",
427         .irqs = s5m8767_irqs,
428         .num_irqs = ARRAY_SIZE(s5m8767_irqs),
429         .num_regs = 3,
430         .status_base = S5M8767_REG_INT1,
431         .mask_base = S5M8767_REG_INT1M,
432         .ack_base = S5M8767_REG_INT1,
433 };
434
435 static const struct regmap_irq_chip s5m8763_irq_chip = {
436         .name = "s5m8763",
437         .irqs = s5m8763_irqs,
438         .num_irqs = ARRAY_SIZE(s5m8763_irqs),
439         .num_regs = 4,
440         .status_base = S5M8763_REG_IRQ1,
441         .mask_base = S5M8763_REG_IRQM1,
442         .ack_base = S5M8763_REG_IRQ1,
443 };
444
445 int sec_irq_init(struct sec_pmic_dev *sec_pmic)
446 {
447         int ret = 0;
448         int type = sec_pmic->device_type;
449         const struct regmap_irq_chip *sec_irq_chip;
450
451         if (!sec_pmic->irq) {
452                 dev_warn(sec_pmic->dev,
453                          "No interrupt specified, no interrupts\n");
454                 sec_pmic->irq_base = 0;
455                 return 0;
456         }
457
458         switch (type) {
459         case S5M8763X:
460                 sec_irq_chip = &s5m8763_irq_chip;
461                 break;
462         case S5M8767X:
463                 sec_irq_chip = &s5m8767_irq_chip;
464                 break;
465         case S2MPS11X:
466                 sec_irq_chip = &s2mps11_irq_chip;
467                 break;
468         case S2MPS13X:
469                 sec_irq_chip = &s2mps13_irq_chip;
470                 break;
471         case S2MPS14X:
472                 sec_irq_chip = &s2mps14_irq_chip;
473                 break;
474         case S2MPS15X:
475                 sec_irq_chip = &s2mps15_irq_chip;
476                 break;
477         case S2MPU02:
478                 sec_irq_chip = &s2mpu02_irq_chip;
479                 break;
480         default:
481                 dev_err(sec_pmic->dev, "Unknown device type %lu\n",
482                         sec_pmic->device_type);
483                 return -EINVAL;
484         }
485
486         ret = devm_regmap_add_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic,
487                                        sec_pmic->irq,
488                                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
489                                        sec_pmic->irq_base, sec_irq_chip,
490                                        &sec_pmic->irq_data);
491         if (ret != 0) {
492                 dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
493                 return ret;
494         }
495
496         /*
497          * The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
498          * so the interrupt number must be consistent.
499          */
500         BUILD_BUG_ON(((enum s2mps14_irq)S2MPS11_IRQ_RTCA0) != S2MPS14_IRQ_RTCA0);
501
502         return 0;
503 }