aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Baldyga <r.baldyga@samsung.com>2014-05-21 02:52:48 -0400
committerLee Jones <lee.jones@linaro.org>2014-06-17 10:17:00 -0400
commit342d669c1ee421323f552a62729d3a3d0065093c (patch)
tree2b19ea7f3df22d56cdab3bba96266e0ca6bd12cd
parentd0540f91cf74fab90e1143d8d40da8a5b5fabc8a (diff)
mfd: max77693: Handle IRQs using regmap
This patch modifies mfd driver to use regmap for handling interrupts. It allows to simplify irq handling process. This modifications needed to make small changes in function drivers, which use interrupts. Signed-off-by: Robert Baldyga <r.baldyga@samsung.com> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/extcon/extcon-max77693.c3
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/Makefile2
-rw-r--r--drivers/mfd/max77693-irq.c346
-rw-r--r--drivers/mfd/max77693.c158
-rw-r--r--include/linux/mfd/max77693-private.h46
6 files changed, 195 insertions, 361 deletions
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
index ba84a6e77e03..c7278b1649da 100644
--- a/drivers/extcon/extcon-max77693.c
+++ b/drivers/extcon/extcon-max77693.c
@@ -1154,7 +1154,8 @@ static int max77693_muic_probe(struct platform_device *pdev)
1154 struct max77693_muic_irq *muic_irq = &muic_irqs[i]; 1154 struct max77693_muic_irq *muic_irq = &muic_irqs[i];
1155 unsigned int virq = 0; 1155 unsigned int virq = 0;
1156 1156
1157 virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq); 1157 virq = regmap_irq_get_virq(max77693->irq_data_muic,
1158 muic_irq->irq);
1158 if (!virq) { 1159 if (!virq) {
1159 ret = -EINVAL; 1160 ret = -EINVAL;
1160 goto err_irq; 1161 goto err_irq;
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ee8204cc31e9..2feac14d1085 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -384,6 +384,7 @@ config MFD_MAX77693
384 depends on I2C=y 384 depends on I2C=y
385 select MFD_CORE 385 select MFD_CORE
386 select REGMAP_I2C 386 select REGMAP_I2C
387 select REGMAP_IRQ
387 help 388 help
388 Say yes here to add support for Maxim Semiconductor MAX77693. 389 Say yes here to add support for Maxim Semiconductor MAX77693.
389 This is a companion Power Management IC with Flash, Haptic, Charger, 390 This is a companion Power Management IC with Flash, Haptic, Charger,
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8afedba535c7..8c6e7bba4660 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -116,7 +116,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o
116 116
117obj-$(CONFIG_MFD_MAX14577) += max14577.o 117obj-$(CONFIG_MFD_MAX14577) += max14577.o
118obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o 118obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o
119obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o 119obj-$(CONFIG_MFD_MAX77693) += max77693.o
120obj-$(CONFIG_MFD_MAX8907) += max8907.o 120obj-$(CONFIG_MFD_MAX8907) += max8907.o
121max8925-objs := max8925-core.o max8925-i2c.o 121max8925-objs := max8925-core.o max8925-i2c.o
122obj-$(CONFIG_MFD_MAX8925) += max8925.o 122obj-$(CONFIG_MFD_MAX8925) += max8925.o
diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c
deleted file mode 100644
index 7d8f99f94f27..000000000000
--- a/drivers/mfd/max77693-irq.c
+++ /dev/null
@@ -1,346 +0,0 @@
1/*
2 * max77693-irq.c - Interrupt controller support for MAX77693
3 *
4 * Copyright (C) 2012 Samsung Electronics Co.Ltd
5 * SangYoung Son <hello.son@samsung.com>
6 *
7 * This program is not provided / owned by Maxim Integrated Products.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 * This driver is based on max8997-irq.c
24 */
25
26#include <linux/err.h>
27#include <linux/irq.h>
28#include <linux/interrupt.h>
29#include <linux/module.h>
30#include <linux/irqdomain.h>
31#include <linux/mfd/max77693.h>
32#include <linux/mfd/max77693-private.h>
33#include <linux/regmap.h>
34
35static const unsigned int max77693_mask_reg[] = {
36 [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK,
37 [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
38 [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK,
39 [MUIC_INT1] = MAX77693_MUIC_REG_INTMASK1,
40 [MUIC_INT2] = MAX77693_MUIC_REG_INTMASK2,
41 [MUIC_INT3] = MAX77693_MUIC_REG_INTMASK3,
42};
43
44static struct regmap *max77693_get_regmap(struct max77693_dev *max77693,
45 enum max77693_irq_source src)
46{
47 switch (src) {
48 case LED_INT ... CHG_INT:
49 return max77693->regmap;
50 case MUIC_INT1 ... MUIC_INT3:
51 return max77693->regmap_muic;
52 default:
53 return ERR_PTR(-EINVAL);
54 }
55}
56
57struct max77693_irq_data {
58 int mask;
59 enum max77693_irq_source group;
60};
61
62#define DECLARE_IRQ(idx, _group, _mask) \
63 [(idx)] = { .group = (_group), .mask = (_mask) }
64static const struct max77693_irq_data max77693_irqs[] = {
65 DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_OPEN, LED_INT, 1 << 0),
66 DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_SHORT, LED_INT, 1 << 1),
67 DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_OPEN, LED_INT, 1 << 2),
68 DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_SHORT, LED_INT, 1 << 3),
69 DECLARE_IRQ(MAX77693_LED_IRQ_MAX_FLASH, LED_INT, 1 << 4),
70
71 DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T120C_INT, TOPSYS_INT, 1 << 0),
72 DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T140C_INT, TOPSYS_INT, 1 << 1),
73 DECLARE_IRQ(MAX77693_TOPSYS_IRQ_LOWSYS_INT, TOPSYS_INT, 1 << 3),
74
75 DECLARE_IRQ(MAX77693_CHG_IRQ_BYP_I, CHG_INT, 1 << 0),
76 DECLARE_IRQ(MAX77693_CHG_IRQ_THM_I, CHG_INT, 1 << 2),
77 DECLARE_IRQ(MAX77693_CHG_IRQ_BAT_I, CHG_INT, 1 << 3),
78 DECLARE_IRQ(MAX77693_CHG_IRQ_CHG_I, CHG_INT, 1 << 4),
79 DECLARE_IRQ(MAX77693_CHG_IRQ_CHGIN_I, CHG_INT, 1 << 6),
80
81 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC, MUIC_INT1, 1 << 0),
82 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_LOW, MUIC_INT1, 1 << 1),
83 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_ERR, MUIC_INT1, 1 << 2),
84 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC1K, MUIC_INT1, 1 << 3),
85
86 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGTYP, MUIC_INT2, 1 << 0),
87 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGDETREUN, MUIC_INT2, 1 << 1),
88 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DCDTMR, MUIC_INT2, 1 << 2),
89 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DXOVP, MUIC_INT2, 1 << 3),
90 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VBVOLT, MUIC_INT2, 1 << 4),
91 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VIDRM, MUIC_INT2, 1 << 5),
92
93 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_EOC, MUIC_INT3, 1 << 0),
94 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CGMBC, MUIC_INT3, 1 << 1),
95 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_OVP, MUIC_INT3, 1 << 2),
96 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR, MUIC_INT3, 1 << 3),
97 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, MUIC_INT3, 1 << 4),
98 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_BAT_DET, MUIC_INT3, 1 << 5),
99};
100
101static void max77693_irq_lock(struct irq_data *data)
102{
103 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
104
105 mutex_lock(&max77693->irqlock);
106}
107
108static void max77693_irq_sync_unlock(struct irq_data *data)
109{
110 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
111 int i;
112
113 for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
114 u8 mask_reg = max77693_mask_reg[i];
115 struct regmap *map = max77693_get_regmap(max77693, i);
116
117 if (mask_reg == MAX77693_REG_INVALID ||
118 IS_ERR_OR_NULL(map))
119 continue;
120 max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i];
121
122 regmap_write(map, max77693_mask_reg[i],
123 max77693->irq_masks_cur[i]);
124 }
125
126 mutex_unlock(&max77693->irqlock);
127}
128
129static const inline struct max77693_irq_data *
130irq_to_max77693_irq(struct max77693_dev *max77693, int irq)
131{
132 struct irq_data *data = irq_get_irq_data(irq);
133 return &max77693_irqs[data->hwirq];
134}
135
136static void max77693_irq_mask(struct irq_data *data)
137{
138 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
139 const struct max77693_irq_data *irq_data =
140 irq_to_max77693_irq(max77693, data->irq);
141
142 if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
143 return;
144
145 if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
146 max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
147 else
148 max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
149}
150
151static void max77693_irq_unmask(struct irq_data *data)
152{
153 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
154 const struct max77693_irq_data *irq_data =
155 irq_to_max77693_irq(max77693, data->irq);
156
157 if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
158 return;
159
160 if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
161 max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
162 else
163 max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
164}
165
166static struct irq_chip max77693_irq_chip = {
167 .name = "max77693",
168 .irq_bus_lock = max77693_irq_lock,
169 .irq_bus_sync_unlock = max77693_irq_sync_unlock,
170 .irq_mask = max77693_irq_mask,
171 .irq_unmask = max77693_irq_unmask,
172};
173
174#define MAX77693_IRQSRC_CHG (1 << 0)
175#define MAX77693_IRQSRC_TOP (1 << 1)
176#define MAX77693_IRQSRC_FLASH (1 << 2)
177#define MAX77693_IRQSRC_MUIC (1 << 3)
178static irqreturn_t max77693_irq_thread(int irq, void *data)
179{
180 struct max77693_dev *max77693 = data;
181 u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {};
182 unsigned int irq_src;
183 int ret;
184 int i, cur_irq;
185
186 ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_INTSRC,
187 &irq_src);
188 if (ret < 0) {
189 dev_err(max77693->dev, "Failed to read interrupt source: %d\n",
190 ret);
191 return IRQ_NONE;
192 }
193
194 if (irq_src & MAX77693_IRQSRC_CHG) {
195 /* CHG_INT */
196 unsigned int data;
197 ret = regmap_read(max77693->regmap,
198 MAX77693_CHG_REG_CHG_INT, &data);
199 irq_reg[CHG_INT] = data;
200 }
201
202 if (irq_src & MAX77693_IRQSRC_TOP) {
203 /* TOPSYS_INT */
204 unsigned int data;
205 ret = regmap_read(max77693->regmap,
206 MAX77693_PMIC_REG_TOPSYS_INT, &data);
207 irq_reg[TOPSYS_INT] = data;
208 }
209
210 if (irq_src & MAX77693_IRQSRC_FLASH) {
211 /* LED_INT */
212 unsigned int data;
213 ret = regmap_read(max77693->regmap,
214 MAX77693_LED_REG_FLASH_INT, &data);
215 irq_reg[LED_INT] = data;
216 }
217
218 if (irq_src & MAX77693_IRQSRC_MUIC)
219 /* MUIC INT1 ~ INT3 */
220 regmap_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1,
221 &irq_reg[MUIC_INT1], MAX77693_NUM_IRQ_MUIC_REGS);
222
223 /* Apply masking */
224 for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
225 if (i >= MUIC_INT1 && i <= MUIC_INT3)
226 irq_reg[i] &= max77693->irq_masks_cur[i];
227 else
228 irq_reg[i] &= ~max77693->irq_masks_cur[i];
229 }
230
231 /* Report */
232 for (i = 0; i < MAX77693_IRQ_NR; i++) {
233 if (irq_reg[max77693_irqs[i].group] & max77693_irqs[i].mask) {
234 cur_irq = irq_find_mapping(max77693->irq_domain, i);
235 if (cur_irq)
236 handle_nested_irq(cur_irq);
237 }
238 }
239
240 return IRQ_HANDLED;
241}
242
243int max77693_irq_resume(struct max77693_dev *max77693)
244{
245 if (max77693->irq)
246 max77693_irq_thread(0, max77693);
247
248 return 0;
249}
250
251static int max77693_irq_domain_map(struct irq_domain *d, unsigned int irq,
252 irq_hw_number_t hw)
253{
254 struct max77693_dev *max77693 = d->host_data;
255
256 irq_set_chip_data(irq, max77693);
257 irq_set_chip_and_handler(irq, &max77693_irq_chip, handle_edge_irq);
258 irq_set_nested_thread(irq, 1);
259#ifdef CONFIG_ARM
260 set_irq_flags(irq, IRQF_VALID);
261#else
262 irq_set_noprobe(irq);
263#endif
264 return 0;
265}
266
267static struct irq_domain_ops max77693_irq_domain_ops = {
268 .map = max77693_irq_domain_map,
269};
270
271int max77693_irq_init(struct max77693_dev *max77693)
272{
273 struct irq_domain *domain;
274 int i;
275 int ret = 0;
276 unsigned int intsrc_mask;
277
278 mutex_init(&max77693->irqlock);
279
280 /* Mask individual interrupt sources */
281 for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
282 struct regmap *map;
283 /* MUIC IRQ 0:MASK 1:NOT MASK */
284 /* Other IRQ 1:MASK 0:NOT MASK */
285 if (i >= MUIC_INT1 && i <= MUIC_INT3) {
286 max77693->irq_masks_cur[i] = 0x00;
287 max77693->irq_masks_cache[i] = 0x00;
288 } else {
289 max77693->irq_masks_cur[i] = 0xff;
290 max77693->irq_masks_cache[i] = 0xff;
291 }
292 map = max77693_get_regmap(max77693, i);
293
294 if (IS_ERR_OR_NULL(map))
295 continue;
296 if (max77693_mask_reg[i] == MAX77693_REG_INVALID)
297 continue;
298 if (i >= MUIC_INT1 && i <= MUIC_INT3)
299 regmap_write(map, max77693_mask_reg[i], 0x00);
300 else
301 regmap_write(map, max77693_mask_reg[i], 0xff);
302 }
303
304 domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR,
305 &max77693_irq_domain_ops, max77693);
306 if (!domain) {
307 dev_err(max77693->dev, "could not create irq domain\n");
308 ret = -ENODEV;
309 goto err_irq;
310 }
311 max77693->irq_domain = domain;
312
313 /* Unmask max77693 interrupt */
314 ret = regmap_read(max77693->regmap,
315 MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask);
316 if (ret < 0) {
317 dev_err(max77693->dev, "fail to read PMIC register\n");
318 goto err_irq;
319 }
320
321 intsrc_mask &= ~(MAX77693_IRQSRC_CHG);
322 intsrc_mask &= ~(MAX77693_IRQSRC_FLASH);
323 intsrc_mask &= ~(MAX77693_IRQSRC_MUIC);
324 ret = regmap_write(max77693->regmap,
325 MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask);
326 if (ret < 0) {
327 dev_err(max77693->dev, "fail to write PMIC register\n");
328 goto err_irq;
329 }
330
331 ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread,
332 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
333 "max77693-irq", max77693);
334 if (ret)
335 dev_err(max77693->dev, "Failed to request IRQ %d: %d\n",
336 max77693->irq, ret);
337
338err_irq:
339 return ret;
340}
341
342void max77693_irq_exit(struct max77693_dev *max77693)
343{
344 if (max77693->irq)
345 free_irq(max77693->irq, max77693);
346}
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
index a0308336adaf..249c139ef04a 100644
--- a/drivers/mfd/max77693.c
+++ b/drivers/mfd/max77693.c
@@ -55,12 +55,95 @@ static const struct regmap_config max77693_regmap_config = {
55 .max_register = MAX77693_PMIC_REG_END, 55 .max_register = MAX77693_PMIC_REG_END,
56}; 56};
57 57
58static const struct regmap_irq max77693_led_irqs[] = {
59 { .mask = LED_IRQ_FLED2_OPEN, },
60 { .mask = LED_IRQ_FLED2_SHORT, },
61 { .mask = LED_IRQ_FLED1_OPEN, },
62 { .mask = LED_IRQ_FLED1_SHORT, },
63 { .mask = LED_IRQ_MAX_FLASH, },
64};
65
66static const struct regmap_irq_chip max77693_led_irq_chip = {
67 .name = "max77693-led",
68 .status_base = MAX77693_LED_REG_FLASH_INT,
69 .mask_base = MAX77693_LED_REG_FLASH_INT_MASK,
70 .mask_invert = false,
71 .num_regs = 1,
72 .irqs = max77693_led_irqs,
73 .num_irqs = ARRAY_SIZE(max77693_led_irqs),
74};
75
76static const struct regmap_irq max77693_topsys_irqs[] = {
77 { .mask = TOPSYS_IRQ_T120C_INT, },
78 { .mask = TOPSYS_IRQ_T140C_INT, },
79 { .mask = TOPSYS_IRQ_LOWSYS_INT, },
80};
81
82static const struct regmap_irq_chip max77693_topsys_irq_chip = {
83 .name = "max77693-topsys",
84 .status_base = MAX77693_PMIC_REG_TOPSYS_INT,
85 .mask_base = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
86 .mask_invert = false,
87 .num_regs = 1,
88 .irqs = max77693_topsys_irqs,
89 .num_irqs = ARRAY_SIZE(max77693_topsys_irqs),
90};
91
92static const struct regmap_irq max77693_charger_irqs[] = {
93 { .mask = CHG_IRQ_BYP_I, },
94 { .mask = CHG_IRQ_THM_I, },
95 { .mask = CHG_IRQ_BAT_I, },
96 { .mask = CHG_IRQ_CHG_I, },
97 { .mask = CHG_IRQ_CHGIN_I, },
98};
99
100static const struct regmap_irq_chip max77693_charger_irq_chip = {
101 .name = "max77693-charger",
102 .status_base = MAX77693_CHG_REG_CHG_INT,
103 .mask_base = MAX77693_CHG_REG_CHG_INT_MASK,
104 .mask_invert = false,
105 .num_regs = 1,
106 .irqs = max77693_charger_irqs,
107 .num_irqs = ARRAY_SIZE(max77693_charger_irqs),
108};
109
58static const struct regmap_config max77693_regmap_muic_config = { 110static const struct regmap_config max77693_regmap_muic_config = {
59 .reg_bits = 8, 111 .reg_bits = 8,
60 .val_bits = 8, 112 .val_bits = 8,
61 .max_register = MAX77693_MUIC_REG_END, 113 .max_register = MAX77693_MUIC_REG_END,
62}; 114};
63 115
116static const struct regmap_irq max77693_muic_irqs[] = {
117 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC, },
118 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_LOW, },
119 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_ERR, },
120 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC1K, },
121
122 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGTYP, },
123 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGDETREUN, },
124 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DCDTMR, },
125 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DXOVP, },
126 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VBVOLT, },
127 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VIDRM, },
128
129 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_EOC, },
130 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CGMBC, },
131 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_OVP, },
132 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_MBCCHG_ERR, },
133 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CHG_ENABLED, },
134 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_BAT_DET, },
135};
136
137static const struct regmap_irq_chip max77693_muic_irq_chip = {
138 .name = "max77693-muic",
139 .status_base = MAX77693_MUIC_REG_INT1,
140 .mask_base = MAX77693_MUIC_REG_INTMASK1,
141 .mask_invert = true,
142 .num_regs = 3,
143 .irqs = max77693_muic_irqs,
144 .num_irqs = ARRAY_SIZE(max77693_muic_irqs),
145};
146
64static int max77693_i2c_probe(struct i2c_client *i2c, 147static int max77693_i2c_probe(struct i2c_client *i2c,
65 const struct i2c_device_id *id) 148 const struct i2c_device_id *id)
66{ 149{
@@ -124,9 +207,45 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
124 goto err_regmap_muic; 207 goto err_regmap_muic;
125 } 208 }
126 209
127 ret = max77693_irq_init(max77693); 210 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
128 if (ret < 0) 211 IRQF_ONESHOT | IRQF_SHARED |
129 goto err_irq; 212 IRQF_TRIGGER_FALLING, 0,
213 &max77693_led_irq_chip,
214 &max77693->irq_data_led);
215 if (ret) {
216 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
217 goto err_regmap_muic;
218 }
219
220 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
221 IRQF_ONESHOT | IRQF_SHARED |
222 IRQF_TRIGGER_FALLING, 0,
223 &max77693_topsys_irq_chip,
224 &max77693->irq_data_topsys);
225 if (ret) {
226 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
227 goto err_irq_topsys;
228 }
229
230 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
231 IRQF_ONESHOT | IRQF_SHARED |
232 IRQF_TRIGGER_FALLING, 0,
233 &max77693_charger_irq_chip,
234 &max77693->irq_data_charger);
235 if (ret) {
236 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
237 goto err_irq_charger;
238 }
239
240 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
241 IRQF_ONESHOT | IRQF_SHARED |
242 IRQF_TRIGGER_FALLING, 0,
243 &max77693_muic_irq_chip,
244 &max77693->irq_data_muic);
245 if (ret) {
246 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
247 goto err_irq_muic;
248 }
130 249
131 pm_runtime_set_active(max77693->dev); 250 pm_runtime_set_active(max77693->dev);
132 251
@@ -138,8 +257,14 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
138 return ret; 257 return ret;
139 258
140err_mfd: 259err_mfd:
141 max77693_irq_exit(max77693); 260 mfd_remove_devices(max77693->dev);
142err_irq: 261 regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
262err_irq_muic:
263 regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
264err_irq_charger:
265 regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
266err_irq_topsys:
267 regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
143err_regmap_muic: 268err_regmap_muic:
144 i2c_unregister_device(max77693->haptic); 269 i2c_unregister_device(max77693->haptic);
145err_i2c_haptic: 270err_i2c_haptic:
@@ -152,7 +277,12 @@ static int max77693_i2c_remove(struct i2c_client *i2c)
152 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 277 struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
153 278
154 mfd_remove_devices(max77693->dev); 279 mfd_remove_devices(max77693->dev);
155 max77693_irq_exit(max77693); 280
281 regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
282 regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
283 regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
284 regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
285
156 i2c_unregister_device(max77693->muic); 286 i2c_unregister_device(max77693->muic);
157 i2c_unregister_device(max77693->haptic); 287 i2c_unregister_device(max77693->haptic);
158 288
@@ -170,8 +300,11 @@ static int max77693_suspend(struct device *dev)
170 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); 300 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
171 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 301 struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
172 302
173 if (device_may_wakeup(dev)) 303 if (device_may_wakeup(dev)) {
174 irq_set_irq_wake(max77693->irq, 1); 304 enable_irq_wake(max77693->irq);
305 disable_irq(max77693->irq);
306 }
307
175 return 0; 308 return 0;
176} 309}
177 310
@@ -180,9 +313,12 @@ static int max77693_resume(struct device *dev)
180 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); 313 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
181 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 314 struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
182 315
183 if (device_may_wakeup(dev)) 316 if (device_may_wakeup(dev)) {
184 irq_set_irq_wake(max77693->irq, 0); 317 disable_irq_wake(max77693->irq);
185 return max77693_irq_resume(max77693); 318 enable_irq(max77693->irq);
319 }
320
321 return 0;
186} 322}
187 323
188static const struct dev_pm_ops max77693_pm = { 324static const struct dev_pm_ops max77693_pm = {
diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index 80ec31d561c4..c466ff3e16b8 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -262,6 +262,41 @@ enum max77693_irq_source {
262 MAX77693_IRQ_GROUP_NR, 262 MAX77693_IRQ_GROUP_NR,
263}; 263};
264 264
265#define LED_IRQ_FLED2_OPEN BIT(0)
266#define LED_IRQ_FLED2_SHORT BIT(1)
267#define LED_IRQ_FLED1_OPEN BIT(2)
268#define LED_IRQ_FLED1_SHORT BIT(3)
269#define LED_IRQ_MAX_FLASH BIT(4)
270
271#define TOPSYS_IRQ_T120C_INT BIT(0)
272#define TOPSYS_IRQ_T140C_INT BIT(1)
273#define TOPSYS_IRQ_LOWSYS_INT BIT(3)
274
275#define CHG_IRQ_BYP_I BIT(0)
276#define CHG_IRQ_THM_I BIT(2)
277#define CHG_IRQ_BAT_I BIT(3)
278#define CHG_IRQ_CHG_I BIT(4)
279#define CHG_IRQ_CHGIN_I BIT(6)
280
281#define MUIC_IRQ_INT1_ADC BIT(0)
282#define MUIC_IRQ_INT1_ADC_LOW BIT(1)
283#define MUIC_IRQ_INT1_ADC_ERR BIT(2)
284#define MUIC_IRQ_INT1_ADC1K BIT(3)
285
286#define MUIC_IRQ_INT2_CHGTYP BIT(0)
287#define MUIC_IRQ_INT2_CHGDETREUN BIT(1)
288#define MUIC_IRQ_INT2_DCDTMR BIT(2)
289#define MUIC_IRQ_INT2_DXOVP BIT(3)
290#define MUIC_IRQ_INT2_VBVOLT BIT(4)
291#define MUIC_IRQ_INT2_VIDRM BIT(5)
292
293#define MUIC_IRQ_INT3_EOC BIT(0)
294#define MUIC_IRQ_INT3_CGMBC BIT(1)
295#define MUIC_IRQ_INT3_OVP BIT(2)
296#define MUIC_IRQ_INT3_MBCCHG_ERR BIT(3)
297#define MUIC_IRQ_INT3_CHG_ENABLED BIT(4)
298#define MUIC_IRQ_INT3_BAT_DET BIT(5)
299
265enum max77693_irq { 300enum max77693_irq {
266 /* PMIC - FLASH */ 301 /* PMIC - FLASH */
267 MAX77693_LED_IRQ_FLED2_OPEN, 302 MAX77693_LED_IRQ_FLED2_OPEN,
@@ -282,6 +317,10 @@ enum max77693_irq {
282 MAX77693_CHG_IRQ_CHG_I, 317 MAX77693_CHG_IRQ_CHG_I,
283 MAX77693_CHG_IRQ_CHGIN_I, 318 MAX77693_CHG_IRQ_CHGIN_I,
284 319
320 MAX77693_IRQ_NR,
321};
322
323enum max77693_irq_muic {
285 /* MUIC INT1 */ 324 /* MUIC INT1 */
286 MAX77693_MUIC_IRQ_INT1_ADC, 325 MAX77693_MUIC_IRQ_INT1_ADC,
287 MAX77693_MUIC_IRQ_INT1_ADC_LOW, 326 MAX77693_MUIC_IRQ_INT1_ADC_LOW,
@@ -304,7 +343,7 @@ enum max77693_irq {
304 MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, 343 MAX77693_MUIC_IRQ_INT3_CHG_ENABLED,
305 MAX77693_MUIC_IRQ_INT3_BAT_DET, 344 MAX77693_MUIC_IRQ_INT3_BAT_DET,
306 345
307 MAX77693_IRQ_NR, 346 MAX77693_MUIC_IRQ_NR,
308}; 347};
309 348
310struct max77693_dev { 349struct max77693_dev {
@@ -319,7 +358,10 @@ struct max77693_dev {
319 struct regmap *regmap_muic; 358 struct regmap *regmap_muic;
320 struct regmap *regmap_haptic; 359 struct regmap *regmap_haptic;
321 360
322 struct irq_domain *irq_domain; 361 struct regmap_irq_chip_data *irq_data_led;
362 struct regmap_irq_chip_data *irq_data_topsys;
363 struct regmap_irq_chip_data *irq_data_charger;
364 struct regmap_irq_chip_data *irq_data_muic;
323 365
324 int irq; 366 int irq;
325 int irq_gpio; 367 int irq_gpio;