aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Shiyan <shc_work@mail.ru>2014-06-18 13:05:40 -0400
committerLee Jones <lee.jones@linaro.org>2014-07-09 09:58:10 -0400
commit10f9edaeaa30468194e1dcd0e47e59b012f4cf8b (patch)
tree21cc8d8c703b749e4a116a052817530de6309fee
parent215cd99a1ec70395cd5a20cd9b75d2d7af6bbe7e (diff)
mfd: mc13xxx: Use regmap irq framework for interrupts
This patch convert mc13xxx MFD driver to use regmap irq framework for interrupt registration. Signed-off-by: Alexander Shiyan <shc_work@mail.ru> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/mc13xxx-core.c310
-rw-r--r--drivers/mfd/mc13xxx.h11
-rw-r--r--include/linux/mfd/mc13783.h1
-rw-r--r--include/linux/mfd/mc13xxx.h23
5 files changed, 65 insertions, 281 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 207c433074af..defe58d65940 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -187,6 +187,7 @@ config MFD_MC13XXX
187 tristate 187 tristate
188 depends on (SPI_MASTER || I2C) 188 depends on (SPI_MASTER || I2C)
189 select MFD_CORE 189 select MFD_CORE
190 select REGMAP_IRQ
190 help 191 help
191 Enable support for the Freescale MC13783 and MC13892 PMICs. 192 Enable support for the Freescale MC13783 and MC13892 PMICs.
192 This driver provides common support for accessing the device, 193 This driver provides common support for accessing the device,
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index acf5dd712eb2..2b6bc868cd3d 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -10,106 +10,18 @@
10 * Free Software Foundation. 10 * Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/slab.h>
14#include <linux/module.h> 13#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/mutex.h>
17#include <linux/interrupt.h>
18#include <linux/mfd/core.h>
19#include <linux/mfd/mc13xxx.h>
20#include <linux/of.h> 14#include <linux/of.h>
21#include <linux/of_device.h> 15#include <linux/of_device.h>
22#include <linux/of_gpio.h> 16#include <linux/platform_device.h>
17#include <linux/mfd/core.h>
23 18
24#include "mc13xxx.h" 19#include "mc13xxx.h"
25 20
26#define MC13XXX_IRQSTAT0 0 21#define MC13XXX_IRQSTAT0 0
27#define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0)
28#define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1)
29#define MC13XXX_IRQSTAT0_TSI (1 << 2)
30#define MC13783_IRQSTAT0_WHIGHI (1 << 3)
31#define MC13783_IRQSTAT0_WLOWI (1 << 4)
32#define MC13XXX_IRQSTAT0_CHGDETI (1 << 6)
33#define MC13783_IRQSTAT0_CHGOVI (1 << 7)
34#define MC13XXX_IRQSTAT0_CHGREVI (1 << 8)
35#define MC13XXX_IRQSTAT0_CHGSHORTI (1 << 9)
36#define MC13XXX_IRQSTAT0_CCCVI (1 << 10)
37#define MC13XXX_IRQSTAT0_CHGCURRI (1 << 11)
38#define MC13XXX_IRQSTAT0_BPONI (1 << 12)
39#define MC13XXX_IRQSTAT0_LOBATLI (1 << 13)
40#define MC13XXX_IRQSTAT0_LOBATHI (1 << 14)
41#define MC13783_IRQSTAT0_UDPI (1 << 15)
42#define MC13783_IRQSTAT0_USBI (1 << 16)
43#define MC13783_IRQSTAT0_IDI (1 << 19)
44#define MC13783_IRQSTAT0_SE1I (1 << 21)
45#define MC13783_IRQSTAT0_CKDETI (1 << 22)
46#define MC13783_IRQSTAT0_UDMI (1 << 23)
47
48#define MC13XXX_IRQMASK0 1 22#define MC13XXX_IRQMASK0 1
49#define MC13XXX_IRQMASK0_ADCDONEM MC13XXX_IRQSTAT0_ADCDONEI
50#define MC13XXX_IRQMASK0_ADCBISDONEM MC13XXX_IRQSTAT0_ADCBISDONEI
51#define MC13XXX_IRQMASK0_TSM MC13XXX_IRQSTAT0_TSI
52#define MC13783_IRQMASK0_WHIGHM MC13783_IRQSTAT0_WHIGHI
53#define MC13783_IRQMASK0_WLOWM MC13783_IRQSTAT0_WLOWI
54#define MC13XXX_IRQMASK0_CHGDETM MC13XXX_IRQSTAT0_CHGDETI
55#define MC13783_IRQMASK0_CHGOVM MC13783_IRQSTAT0_CHGOVI
56#define MC13XXX_IRQMASK0_CHGREVM MC13XXX_IRQSTAT0_CHGREVI
57#define MC13XXX_IRQMASK0_CHGSHORTM MC13XXX_IRQSTAT0_CHGSHORTI
58#define MC13XXX_IRQMASK0_CCCVM MC13XXX_IRQSTAT0_CCCVI
59#define MC13XXX_IRQMASK0_CHGCURRM MC13XXX_IRQSTAT0_CHGCURRI
60#define MC13XXX_IRQMASK0_BPONM MC13XXX_IRQSTAT0_BPONI
61#define MC13XXX_IRQMASK0_LOBATLM MC13XXX_IRQSTAT0_LOBATLI
62#define MC13XXX_IRQMASK0_LOBATHM MC13XXX_IRQSTAT0_LOBATHI
63#define MC13783_IRQMASK0_UDPM MC13783_IRQSTAT0_UDPI
64#define MC13783_IRQMASK0_USBM MC13783_IRQSTAT0_USBI
65#define MC13783_IRQMASK0_IDM MC13783_IRQSTAT0_IDI
66#define MC13783_IRQMASK0_SE1M MC13783_IRQSTAT0_SE1I
67#define MC13783_IRQMASK0_CKDETM MC13783_IRQSTAT0_CKDETI
68#define MC13783_IRQMASK0_UDMM MC13783_IRQSTAT0_UDMI
69
70#define MC13XXX_IRQSTAT1 3 23#define MC13XXX_IRQSTAT1 3
71#define MC13XXX_IRQSTAT1_1HZI (1 << 0)
72#define MC13XXX_IRQSTAT1_TODAI (1 << 1)
73#define MC13783_IRQSTAT1_ONOFD1I (1 << 3)
74#define MC13783_IRQSTAT1_ONOFD2I (1 << 4)
75#define MC13783_IRQSTAT1_ONOFD3I (1 << 5)
76#define MC13XXX_IRQSTAT1_SYSRSTI (1 << 6)
77#define MC13XXX_IRQSTAT1_RTCRSTI (1 << 7)
78#define MC13XXX_IRQSTAT1_PCI (1 << 8)
79#define MC13XXX_IRQSTAT1_WARMI (1 << 9)
80#define MC13XXX_IRQSTAT1_MEMHLDI (1 << 10)
81#define MC13783_IRQSTAT1_PWRRDYI (1 << 11)
82#define MC13XXX_IRQSTAT1_THWARNLI (1 << 12)
83#define MC13XXX_IRQSTAT1_THWARNHI (1 << 13)
84#define MC13XXX_IRQSTAT1_CLKI (1 << 14)
85#define MC13783_IRQSTAT1_SEMAFI (1 << 15)
86#define MC13783_IRQSTAT1_MC2BI (1 << 17)
87#define MC13783_IRQSTAT1_HSDETI (1 << 18)
88#define MC13783_IRQSTAT1_HSLI (1 << 19)
89#define MC13783_IRQSTAT1_ALSPTHI (1 << 20)
90#define MC13783_IRQSTAT1_AHSSHORTI (1 << 21)
91
92#define MC13XXX_IRQMASK1 4 24#define MC13XXX_IRQMASK1 4
93#define MC13XXX_IRQMASK1_1HZM MC13XXX_IRQSTAT1_1HZI
94#define MC13XXX_IRQMASK1_TODAM MC13XXX_IRQSTAT1_TODAI
95#define MC13783_IRQMASK1_ONOFD1M MC13783_IRQSTAT1_ONOFD1I
96#define MC13783_IRQMASK1_ONOFD2M MC13783_IRQSTAT1_ONOFD2I
97#define MC13783_IRQMASK1_ONOFD3M MC13783_IRQSTAT1_ONOFD3I
98#define MC13XXX_IRQMASK1_SYSRSTM MC13XXX_IRQSTAT1_SYSRSTI
99#define MC13XXX_IRQMASK1_RTCRSTM MC13XXX_IRQSTAT1_RTCRSTI
100#define MC13XXX_IRQMASK1_PCM MC13XXX_IRQSTAT1_PCI
101#define MC13XXX_IRQMASK1_WARMM MC13XXX_IRQSTAT1_WARMI
102#define MC13XXX_IRQMASK1_MEMHLDM MC13XXX_IRQSTAT1_MEMHLDI
103#define MC13783_IRQMASK1_PWRRDYM MC13783_IRQSTAT1_PWRRDYI
104#define MC13XXX_IRQMASK1_THWARNLM MC13XXX_IRQSTAT1_THWARNLI
105#define MC13XXX_IRQMASK1_THWARNHM MC13XXX_IRQSTAT1_THWARNHI
106#define MC13XXX_IRQMASK1_CLKM MC13XXX_IRQSTAT1_CLKI
107#define MC13783_IRQMASK1_SEMAFM MC13783_IRQSTAT1_SEMAFI
108#define MC13783_IRQMASK1_MC2BM MC13783_IRQSTAT1_MC2BI
109#define MC13783_IRQMASK1_HSDETM MC13783_IRQSTAT1_HSDETI
110#define MC13783_IRQMASK1_HSLM MC13783_IRQSTAT1_HSLI
111#define MC13783_IRQMASK1_ALSPTHM MC13783_IRQSTAT1_ALSPTHI
112#define MC13783_IRQMASK1_AHSSHORTM MC13783_IRQSTAT1_AHSSHORTI
113 25
114#define MC13XXX_REVISION 7 26#define MC13XXX_REVISION 7
115#define MC13XXX_REVISION_REVMETAL (0x07 << 0) 27#define MC13XXX_REVISION_REVMETAL (0x07 << 0)
@@ -189,45 +101,21 @@ EXPORT_SYMBOL(mc13xxx_reg_rmw);
189 101
190int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq) 102int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq)
191{ 103{
192 int ret; 104 int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);
193 unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1;
194 u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
195 u32 mask;
196
197 if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
198 return -EINVAL;
199
200 ret = mc13xxx_reg_read(mc13xxx, offmask, &mask);
201 if (ret)
202 return ret;
203 105
204 if (mask & irqbit) 106 disable_irq_nosync(virq);
205 /* already masked */
206 return 0;
207 107
208 return mc13xxx_reg_write(mc13xxx, offmask, mask | irqbit); 108 return 0;
209} 109}
210EXPORT_SYMBOL(mc13xxx_irq_mask); 110EXPORT_SYMBOL(mc13xxx_irq_mask);
211 111
212int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq) 112int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq)
213{ 113{
214 int ret; 114 int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);
215 unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1;
216 u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
217 u32 mask;
218
219 if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
220 return -EINVAL;
221 115
222 ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); 116 enable_irq(virq);
223 if (ret)
224 return ret;
225 117
226 if (!(mask & irqbit)) 118 return 0;
227 /* already unmasked */
228 return 0;
229
230 return mc13xxx_reg_write(mc13xxx, offmask, mask & ~irqbit);
231} 119}
232EXPORT_SYMBOL(mc13xxx_irq_unmask); 120EXPORT_SYMBOL(mc13xxx_irq_unmask);
233 121
@@ -239,7 +127,7 @@ int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq,
239 unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1; 127 unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1;
240 u32 irqbit = 1 << (irq < 24 ? irq : irq - 24); 128 u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
241 129
242 if (irq < 0 || irq >= MC13XXX_NUM_IRQ) 130 if (irq < 0 || irq >= ARRAY_SIZE(mc13xxx->irqs))
243 return -EINVAL; 131 return -EINVAL;
244 132
245 if (enabled) { 133 if (enabled) {
@@ -266,147 +154,26 @@ int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq,
266} 154}
267EXPORT_SYMBOL(mc13xxx_irq_status); 155EXPORT_SYMBOL(mc13xxx_irq_status);
268 156
269int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq)
270{
271 unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1;
272 unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
273
274 BUG_ON(irq < 0 || irq >= MC13XXX_NUM_IRQ);
275
276 return mc13xxx_reg_write(mc13xxx, offstat, val);
277}
278EXPORT_SYMBOL(mc13xxx_irq_ack);
279
280int mc13xxx_irq_request_nounmask(struct mc13xxx *mc13xxx, int irq,
281 irq_handler_t handler, const char *name, void *dev)
282{
283 BUG_ON(!mutex_is_locked(&mc13xxx->lock));
284 BUG_ON(!handler);
285
286 if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
287 return -EINVAL;
288
289 if (mc13xxx->irqhandler[irq])
290 return -EBUSY;
291
292 mc13xxx->irqhandler[irq] = handler;
293 mc13xxx->irqdata[irq] = dev;
294
295 return 0;
296}
297EXPORT_SYMBOL(mc13xxx_irq_request_nounmask);
298
299int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq, 157int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq,
300 irq_handler_t handler, const char *name, void *dev) 158 irq_handler_t handler, const char *name, void *dev)
301{ 159{
302 int ret; 160 int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);
303 161
304 ret = mc13xxx_irq_request_nounmask(mc13xxx, irq, handler, name, dev); 162 return devm_request_threaded_irq(mc13xxx->dev, virq, NULL, handler,
305 if (ret) 163 0, name, dev);
306 return ret;
307
308 ret = mc13xxx_irq_unmask(mc13xxx, irq);
309 if (ret) {
310 mc13xxx->irqhandler[irq] = NULL;
311 mc13xxx->irqdata[irq] = NULL;
312 return ret;
313 }
314
315 return 0;
316} 164}
317EXPORT_SYMBOL(mc13xxx_irq_request); 165EXPORT_SYMBOL(mc13xxx_irq_request);
318 166
319int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev) 167int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev)
320{ 168{
321 int ret; 169 int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);
322 BUG_ON(!mutex_is_locked(&mc13xxx->lock));
323 170
324 if (irq < 0 || irq >= MC13XXX_NUM_IRQ || !mc13xxx->irqhandler[irq] || 171 devm_free_irq(mc13xxx->dev, virq, dev);
325 mc13xxx->irqdata[irq] != dev)
326 return -EINVAL;
327
328 ret = mc13xxx_irq_mask(mc13xxx, irq);
329 if (ret)
330 return ret;
331
332 mc13xxx->irqhandler[irq] = NULL;
333 mc13xxx->irqdata[irq] = NULL;
334 172
335 return 0; 173 return 0;
336} 174}
337EXPORT_SYMBOL(mc13xxx_irq_free); 175EXPORT_SYMBOL(mc13xxx_irq_free);
338 176
339static inline irqreturn_t mc13xxx_irqhandler(struct mc13xxx *mc13xxx, int irq)
340{
341 return mc13xxx->irqhandler[irq](irq, mc13xxx->irqdata[irq]);
342}
343
344/*
345 * returns: number of handled irqs or negative error
346 * locking: holds mc13xxx->lock
347 */
348static int mc13xxx_irq_handle(struct mc13xxx *mc13xxx,
349 unsigned int offstat, unsigned int offmask, int baseirq)
350{
351 u32 stat, mask;
352 int ret = mc13xxx_reg_read(mc13xxx, offstat, &stat);
353 int num_handled = 0;
354
355 if (ret)
356 return ret;
357
358 ret = mc13xxx_reg_read(mc13xxx, offmask, &mask);
359 if (ret)
360 return ret;
361
362 while (stat & ~mask) {
363 int irq = __ffs(stat & ~mask);
364
365 stat &= ~(1 << irq);
366
367 if (likely(mc13xxx->irqhandler[baseirq + irq])) {
368 irqreturn_t handled;
369
370 handled = mc13xxx_irqhandler(mc13xxx, baseirq + irq);
371 if (handled == IRQ_HANDLED)
372 num_handled++;
373 } else {
374 dev_err(mc13xxx->dev,
375 "BUG: irq %u but no handler\n",
376 baseirq + irq);
377
378 mask |= 1 << irq;
379
380 ret = mc13xxx_reg_write(mc13xxx, offmask, mask);
381 }
382 }
383
384 return num_handled;
385}
386
387static irqreturn_t mc13xxx_irq_thread(int irq, void *data)
388{
389 struct mc13xxx *mc13xxx = data;
390 irqreturn_t ret;
391 int handled = 0;
392
393 mc13xxx_lock(mc13xxx);
394
395 ret = mc13xxx_irq_handle(mc13xxx, MC13XXX_IRQSTAT0,
396 MC13XXX_IRQMASK0, 0);
397 if (ret > 0)
398 handled = 1;
399
400 ret = mc13xxx_irq_handle(mc13xxx, MC13XXX_IRQSTAT1,
401 MC13XXX_IRQMASK1, 24);
402 if (ret > 0)
403 handled = 1;
404
405 mc13xxx_unlock(mc13xxx);
406
407 return IRQ_RETVAL(handled);
408}
409
410#define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask)) 177#define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask))
411static void mc13xxx_print_revision(struct mc13xxx *mc13xxx, u32 revision) 178static void mc13xxx_print_revision(struct mc13xxx *mc13xxx, u32 revision)
412{ 179{
@@ -475,8 +242,6 @@ static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data)
475{ 242{
476 struct mc13xxx_adcdone_data *adcdone_data = data; 243 struct mc13xxx_adcdone_data *adcdone_data = data;
477 244
478 mc13xxx_irq_ack(adcdone_data->mc13xxx, irq);
479
480 complete_all(&adcdone_data->done); 245 complete_all(&adcdone_data->done);
481 246
482 return IRQ_HANDLED; 247 return IRQ_HANDLED;
@@ -544,7 +309,6 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
544 dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__); 309 dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__);
545 mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, 310 mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE,
546 mc13xxx_handler_adcdone, __func__, &adcdone_data); 311 mc13xxx_handler_adcdone, __func__, &adcdone_data);
547 mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE);
548 312
549 mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0); 313 mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0);
550 mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1); 314 mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1);
@@ -599,7 +363,8 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
599 if (!cell.name) 363 if (!cell.name)
600 return -ENOMEM; 364 return -ENOMEM;
601 365
602 return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, NULL); 366 return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0,
367 regmap_irq_get_domain(mc13xxx->irq_data));
603} 368}
604 369
605static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) 370static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format)
@@ -640,8 +405,8 @@ int mc13xxx_common_init(struct device *dev)
640{ 405{
641 struct mc13xxx_platform_data *pdata = dev_get_platdata(dev); 406 struct mc13xxx_platform_data *pdata = dev_get_platdata(dev);
642 struct mc13xxx *mc13xxx = dev_get_drvdata(dev); 407 struct mc13xxx *mc13xxx = dev_get_drvdata(dev);
643 int ret;
644 u32 revision; 408 u32 revision;
409 int i, ret;
645 410
646 mc13xxx->dev = dev; 411 mc13xxx->dev = dev;
647 412
@@ -651,31 +416,32 @@ int mc13xxx_common_init(struct device *dev)
651 416
652 mc13xxx->variant->print_revision(mc13xxx, revision); 417 mc13xxx->variant->print_revision(mc13xxx, revision);
653 418
654 /* mask all irqs */ 419 for (i = 0; i < ARRAY_SIZE(mc13xxx->irqs); i++) {
655 ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK0, 0x00ffffff); 420 mc13xxx->irqs[i].reg_offset = i / MC13XXX_IRQ_PER_REG;
656 if (ret) 421 mc13xxx->irqs[i].mask = BIT(i % MC13XXX_IRQ_PER_REG);
657 return ret; 422 }
658 423
659 ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK1, 0x00ffffff); 424 mc13xxx->irq_chip.name = dev_name(dev);
425 mc13xxx->irq_chip.status_base = MC13XXX_IRQSTAT0;
426 mc13xxx->irq_chip.mask_base = MC13XXX_IRQMASK0;
427 mc13xxx->irq_chip.ack_base = MC13XXX_IRQSTAT0;
428 mc13xxx->irq_chip.irq_reg_stride = MC13XXX_IRQSTAT1 - MC13XXX_IRQSTAT0;
429 mc13xxx->irq_chip.init_ack_masked = true;
430 mc13xxx->irq_chip.use_ack = true;
431 mc13xxx->irq_chip.num_regs = MC13XXX_IRQ_REG_CNT;
432 mc13xxx->irq_chip.irqs = mc13xxx->irqs;
433 mc13xxx->irq_chip.num_irqs = ARRAY_SIZE(mc13xxx->irqs);
434
435 ret = regmap_add_irq_chip(mc13xxx->regmap, mc13xxx->irq, IRQF_ONESHOT,
436 0, &mc13xxx->irq_chip, &mc13xxx->irq_data);
660 if (ret) 437 if (ret)
661 return ret; 438 return ret;
662 439
663 mutex_init(&mc13xxx->lock); 440 mutex_init(&mc13xxx->lock);
664 441
665 ret = request_threaded_irq(mc13xxx->irq, NULL, mc13xxx_irq_thread,
666 IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx);
667 if (ret)
668 return ret;
669
670 if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) 442 if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata)
671 mc13xxx->flags = pdata->flags; 443 mc13xxx->flags = pdata->flags;
672 444
673 if (mc13xxx->flags & MC13XXX_USE_ADC)
674 mc13xxx_add_subdevice(mc13xxx, "%s-adc");
675
676 if (mc13xxx->flags & MC13XXX_USE_RTC)
677 mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
678
679 if (pdata) { 445 if (pdata) {
680 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", 446 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
681 &pdata->regulators, sizeof(pdata->regulators)); 447 &pdata->regulators, sizeof(pdata->regulators));
@@ -699,6 +465,12 @@ int mc13xxx_common_init(struct device *dev)
699 mc13xxx_add_subdevice(mc13xxx, "%s-ts"); 465 mc13xxx_add_subdevice(mc13xxx, "%s-ts");
700 } 466 }
701 467
468 if (mc13xxx->flags & MC13XXX_USE_ADC)
469 mc13xxx_add_subdevice(mc13xxx, "%s-adc");
470
471 if (mc13xxx->flags & MC13XXX_USE_RTC)
472 mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
473
702 return 0; 474 return 0;
703} 475}
704EXPORT_SYMBOL_GPL(mc13xxx_common_init); 476EXPORT_SYMBOL_GPL(mc13xxx_common_init);
@@ -707,8 +479,8 @@ int mc13xxx_common_exit(struct device *dev)
707{ 479{
708 struct mc13xxx *mc13xxx = dev_get_drvdata(dev); 480 struct mc13xxx *mc13xxx = dev_get_drvdata(dev);
709 481
710 free_irq(mc13xxx->irq, mc13xxx);
711 mfd_remove_devices(dev); 482 mfd_remove_devices(dev);
483 regmap_del_irq_chip(mc13xxx->irq, mc13xxx->irq_data);
712 mutex_destroy(&mc13xxx->lock); 484 mutex_destroy(&mc13xxx->lock);
713 485
714 return 0; 486 return 0;
diff --git a/drivers/mfd/mc13xxx.h b/drivers/mfd/mc13xxx.h
index ae7f1659f5d1..33677d1dcf66 100644
--- a/drivers/mfd/mc13xxx.h
+++ b/drivers/mfd/mc13xxx.h
@@ -13,7 +13,9 @@
13#include <linux/regmap.h> 13#include <linux/regmap.h>
14#include <linux/mfd/mc13xxx.h> 14#include <linux/mfd/mc13xxx.h>
15 15
16#define MC13XXX_NUMREGS 0x3f 16#define MC13XXX_NUMREGS 0x3f
17#define MC13XXX_IRQ_REG_CNT 2
18#define MC13XXX_IRQ_PER_REG 24
17 19
18struct mc13xxx; 20struct mc13xxx;
19 21
@@ -33,13 +35,14 @@ struct mc13xxx {
33 struct device *dev; 35 struct device *dev;
34 const struct mc13xxx_variant *variant; 36 const struct mc13xxx_variant *variant;
35 37
38 struct regmap_irq irqs[MC13XXX_IRQ_PER_REG * MC13XXX_IRQ_REG_CNT];
39 struct regmap_irq_chip irq_chip;
40 struct regmap_irq_chip_data *irq_data;
41
36 struct mutex lock; 42 struct mutex lock;
37 int irq; 43 int irq;
38 int flags; 44 int flags;
39 45
40 irq_handler_t irqhandler[MC13XXX_NUM_IRQ];
41 void *irqdata[MC13XXX_NUM_IRQ];
42
43 int adcflags; 46 int adcflags;
44}; 47};
45 48
diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h
index a8eeda773a7b..4ff6137d8d67 100644
--- a/include/linux/mfd/mc13783.h
+++ b/include/linux/mfd/mc13783.h
@@ -86,6 +86,5 @@
86#define MC13783_IRQ_HSL 43 86#define MC13783_IRQ_HSL 43
87#define MC13783_IRQ_ALSPTH 44 87#define MC13783_IRQ_ALSPTH 44
88#define MC13783_IRQ_AHSSHORT 45 88#define MC13783_IRQ_AHSSHORT 45
89#define MC13783_NUM_IRQ MC13XXX_NUM_IRQ
90 89
91#endif /* ifndef __LINUX_MFD_MC13783_H */ 90#endif /* ifndef __LINUX_MFD_MC13783_H */
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h
index d63b1d309106..638222e43e48 100644
--- a/include/linux/mfd/mc13xxx.h
+++ b/include/linux/mfd/mc13xxx.h
@@ -23,15 +23,10 @@ int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset,
23 23
24int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq, 24int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq,
25 irq_handler_t handler, const char *name, void *dev); 25 irq_handler_t handler, const char *name, void *dev);
26int mc13xxx_irq_request_nounmask(struct mc13xxx *mc13xxx, int irq,
27 irq_handler_t handler, const char *name, void *dev);
28int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev); 26int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev);
29 27
30int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq);
31int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq);
32int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq, 28int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq,
33 int *enabled, int *pending); 29 int *enabled, int *pending);
34int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq);
35 30
36int mc13xxx_get_flags(struct mc13xxx *mc13xxx); 31int mc13xxx_get_flags(struct mc13xxx *mc13xxx);
37 32
@@ -39,6 +34,22 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx,
39 unsigned int mode, unsigned int channel, 34 unsigned int mode, unsigned int channel,
40 u8 ato, bool atox, unsigned int *sample); 35 u8 ato, bool atox, unsigned int *sample);
41 36
37/* Deprecated calls */
38static inline int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq)
39{
40 return 0;
41}
42
43static inline int mc13xxx_irq_request_nounmask(struct mc13xxx *mc13xxx, int irq,
44 irq_handler_t handler,
45 const char *name, void *dev)
46{
47 return mc13xxx_irq_request(mc13xxx, irq, handler, name, dev);
48}
49
50int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq);
51int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq);
52
42#define MC13783_AUDIO_RX0 36 53#define MC13783_AUDIO_RX0 36
43#define MC13783_AUDIO_RX1 37 54#define MC13783_AUDIO_RX1 37
44#define MC13783_AUDIO_TX 38 55#define MC13783_AUDIO_TX 38
@@ -68,8 +79,6 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx,
68#define MC13XXX_IRQ_THWARNH 37 79#define MC13XXX_IRQ_THWARNH 37
69#define MC13XXX_IRQ_CLK 38 80#define MC13XXX_IRQ_CLK 38
70 81
71#define MC13XXX_NUM_IRQ 46
72
73struct regulator_init_data; 82struct regulator_init_data;
74 83
75struct mc13xxx_regulator_init_data { 84struct mc13xxx_regulator_init_data {