summaryrefslogtreecommitdiffstats
path: root/drivers/mfd/twl4030-irq.c
diff options
context:
space:
mode:
authorBenoit Cousson <b-cousson@ti.com>2012-02-29 19:40:31 +0100
committerSamuel Ortiz <sameo@linux.intel.com>2012-03-22 13:04:33 +0100
commit78518ffa08fceee42d61359303c58bdd0a82033f (patch)
tree3db4458970c145e8b82fa8a31536c700a4479aee /drivers/mfd/twl4030-irq.c
parentmfd: Remove references already defineid in header file from twl-core (diff)
downloadlinux-78518ffa08fceee42d61359303c58bdd0a82033f.tar.xz
linux-78518ffa08fceee42d61359303c58bdd0a82033f.zip
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/twl4030-irq.c')
-rw-r--r--drivers/mfd/twl4030-irq.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index b31f920feb51..a3dc1d929070 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -28,10 +28,13 @@
*/
#include <linux/init.h>
+#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
#include <linux/i2c/twl.h>
#include "twl-core.h"
@@ -53,6 +56,8 @@
* base + 8 .. base + 15 SIH for PWR_INT
* base + 16 .. base + 33 SIH for GPIO
*/
+#define TWL4030_CORE_NR_IRQS 8
+#define TWL4030_PWR_NR_IRQS 8
/* PIH register offsets */
#define REG_PIH_ISR_P1 0x01
@@ -695,14 +700,34 @@ int twl4030_sih_setup(int module)
/* FIXME pass in which interrupt line we'll use ... */
#define twl_irq_line 0
-int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
+int twl4030_init_irq(struct device *dev, int irq_num)
{
static struct irq_chip twl4030_irq_chip;
+ int irq_base, irq_end, nr_irqs;
+ struct device_node *node = dev->of_node;
int status;
int i;
/*
+ * TWL core and pwr interrupts must be contiguous because
+ * the hwirqs numbers are defined contiguously from 1 to 15.
+ * Create only one domain for both.
+ */
+ nr_irqs = TWL4030_PWR_NR_IRQS + TWL4030_CORE_NR_IRQS;
+
+ irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
+ if (IS_ERR_VALUE(irq_base)) {
+ dev_err(dev, "Fail to allocate IRQ descs\n");
+ return irq_base;
+ }
+
+ irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
+ &irq_domain_simple_ops, NULL);
+
+ irq_end = irq_base + TWL4030_CORE_NR_IRQS;
+
+ /*
* Mask and clear all TWL4030 interrupts since initially we do
* not have any TWL4030 module interrupt handlers present
*/
@@ -747,7 +772,7 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
goto fail_rqirq;
}
- return status;
+ return irq_base;
fail_rqirq:
/* clean up twl4030_sih_setup */
fail: