diff options
author | Benoit Cousson <b-cousson@ti.com> | 2012-02-29 13:40:31 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-03-22 08:04:33 -0400 |
commit | 78518ffa08fceee42d61359303c58bdd0a82033f (patch) | |
tree | 3db4458970c145e8b82fa8a31536c700a4479aee /drivers/mfd/twl6030-irq.c | |
parent | 1b8f333ff49f778a1215f65754c31c02408d1d08 (diff) |
mfd: Move twl-core IRQ allocation into twl[4030|6030]-irq files
During DT adaptation, the irq_alloc_desc was added into twl-core, but
due to the rather different and weird IRQ management required by the twl4030,
it is much better to have a different approach for it.
The issue is that twl4030 uses a two level IRQ mechanism but handles all the
PWR interrupts as part of the twl-core interrupt range. It ends up with a
range of 16 interrupts total for CORE and PWR.
The other twl4030 functionalities already have a dedicated driver and thus
their IRQs and irqdomain can and should be defined localy.
twl6030 is using a single level IRQ controller and thus does not require any
trick.
Move the irq_alloc_desc and irq_domain_add_legacy in twl4030-irq and
twl6030-irq.
Allocate together CORE and PWR IRQs for twl4030-irq.
Conflicts:
drivers/mfd/twl-core.c
Signed-off-by: Benoit Cousson <b-cousson@ti.com>
Acked-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/twl6030-irq.c')
-rw-r--r-- | drivers/mfd/twl6030-irq.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index bb3d762280f9..86c4082fa411 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <linux/i2c/twl.h> | 39 | #include <linux/i2c/twl.h> |
40 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
41 | #include <linux/suspend.h> | 41 | #include <linux/suspend.h> |
42 | #include <linux/of.h> | ||
43 | #include <linux/irqdomain.h> | ||
42 | 44 | ||
43 | #include "twl-core.h" | 45 | #include "twl-core.h" |
44 | 46 | ||
@@ -53,6 +55,7 @@ | |||
53 | * specifies mapping between interrupt number and the associated module. | 55 | * specifies mapping between interrupt number and the associated module. |
54 | * | 56 | * |
55 | */ | 57 | */ |
58 | #define TWL6030_NR_IRQS 20 | ||
56 | 59 | ||
57 | static int twl6030_interrupt_mapping[24] = { | 60 | static int twl6030_interrupt_mapping[24] = { |
58 | PWR_INTR_OFFSET, /* Bit 0 PWRON */ | 61 | PWR_INTR_OFFSET, /* Bit 0 PWRON */ |
@@ -246,11 +249,6 @@ static int twl6030_irq_set_wake(struct irq_data *d, unsigned int on) | |||
246 | return 0; | 249 | return 0; |
247 | } | 250 | } |
248 | 251 | ||
249 | /*----------------------------------------------------------------------*/ | ||
250 | |||
251 | static unsigned twl6030_irq_next; | ||
252 | |||
253 | /*----------------------------------------------------------------------*/ | ||
254 | int twl6030_interrupt_unmask(u8 bit_mask, u8 offset) | 252 | int twl6030_interrupt_unmask(u8 bit_mask, u8 offset) |
255 | { | 253 | { |
256 | int ret; | 254 | int ret; |
@@ -350,8 +348,10 @@ int twl6030_mmc_card_detect(struct device *dev, int slot) | |||
350 | } | 348 | } |
351 | EXPORT_SYMBOL(twl6030_mmc_card_detect); | 349 | EXPORT_SYMBOL(twl6030_mmc_card_detect); |
352 | 350 | ||
353 | int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | 351 | int twl6030_init_irq(struct device *dev, int irq_num) |
354 | { | 352 | { |
353 | struct device_node *node = dev->of_node; | ||
354 | int nr_irqs, irq_base, irq_end; | ||
355 | 355 | ||
356 | int status = 0; | 356 | int status = 0; |
357 | int i; | 357 | int i; |
@@ -360,6 +360,20 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
360 | u8 mask[4]; | 360 | u8 mask[4]; |
361 | 361 | ||
362 | static struct irq_chip twl6030_irq_chip; | 362 | static struct irq_chip twl6030_irq_chip; |
363 | |||
364 | nr_irqs = TWL6030_NR_IRQS; | ||
365 | |||
366 | irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); | ||
367 | if (IS_ERR_VALUE(irq_base)) { | ||
368 | dev_err(dev, "Fail to allocate IRQ descs\n"); | ||
369 | return irq_base; | ||
370 | } | ||
371 | |||
372 | irq_domain_add_legacy(node, nr_irqs, irq_base, 0, | ||
373 | &irq_domain_simple_ops, NULL); | ||
374 | |||
375 | irq_end = irq_base + nr_irqs; | ||
376 | |||
363 | mask[1] = 0xFF; | 377 | mask[1] = 0xFF; |
364 | mask[2] = 0xFF; | 378 | mask[2] = 0xFF; |
365 | mask[3] = 0xFF; | 379 | mask[3] = 0xFF; |
@@ -387,9 +401,8 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
387 | activate_irq(i); | 401 | activate_irq(i); |
388 | } | 402 | } |
389 | 403 | ||
390 | twl6030_irq_next = i; | ||
391 | pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH", | 404 | pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH", |
392 | irq_num, irq_base, twl6030_irq_next - 1); | 405 | irq_num, irq_base, irq_end); |
393 | 406 | ||
394 | /* install an irq handler to demultiplex the TWL6030 interrupt */ | 407 | /* install an irq handler to demultiplex the TWL6030 interrupt */ |
395 | init_completion(&irq_event); | 408 | init_completion(&irq_event); |
@@ -410,7 +423,7 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
410 | 423 | ||
411 | twl_irq = irq_num; | 424 | twl_irq = irq_num; |
412 | register_pm_notifier(&twl6030_irq_pm_notifier_block); | 425 | register_pm_notifier(&twl6030_irq_pm_notifier_block); |
413 | return status; | 426 | return irq_base; |
414 | 427 | ||
415 | fail_kthread: | 428 | fail_kthread: |
416 | free_irq(irq_num, &irq_event); | 429 | free_irq(irq_num, &irq_event); |