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