aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/irq.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-04-01 12:30:01 -0700
committerTejun Heo <tj@kernel.org>2012-04-01 12:55:00 -0700
commit959d851caa48829eb85cb85aa949fd6b4c5d5bc6 (patch)
tree3ba9c94ec346275fb44c4f0d1cd2537cdff8d811 /arch/arm/mach-omap2/irq.c
parentblkcg: change a spin_lock() to spin_lock_irq() (diff)
parentcgroup: make css->refcnt clearing on cgroup removal optional (diff)
downloadlinux-dev-959d851caa48829eb85cb85aa949fd6b4c5d5bc6.tar.xz
linux-dev-959d851caa48829eb85cb85aa949fd6b4c5d5bc6.zip
Merge branch 'for-3.5' of ../cgroup into block/for-3.5/core-merged
cgroup/for-3.5 contains the following changes which blk-cgroup needs to proceed with the on-going cleanup. * Dynamic addition and removal of cftypes to make config/stat file handling modular for policies. * cgroup removal update to not wait for css references to drain to fix blkcg removal hang caused by cfq caching cfqgs. Pull in cgroup/for-3.5 into block/for-3.5/core. This causes the following conflicts in block/blk-cgroup.c. * 761b3ef50e "cgroup: remove cgroup_subsys argument from callbacks" conflicts with blkiocg_pre_destroy() addition and blkiocg_attach() removal. Resolved by removing @subsys from all subsys methods. * 676f7c8f84 "cgroup: relocate cftype and cgroup_subsys definitions in controllers" conflicts with ->pre_destroy() and ->attach() updates and removal of modular config. Resolved by dropping forward declarations of the methods and applying updates to the relocated blkio_subsys. * 4baf6e3325 "cgroup: convert all non-memcg controllers to the new cftype interface" builds upon the previous item. Resolved by adding ->base_cftypes to the relocated blkio_subsys. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'arch/arm/mach-omap2/irq.c')
-rw-r--r--arch/arm/mach-omap2/irq.c65
1 files changed, 54 insertions, 11 deletions
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 1fef061f7927..65f0d2571c9a 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -11,13 +11,20 @@
* for more details.
*/
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
-#include <mach/hardware.h>
+
#include <asm/exception.h>
#include <asm/mach/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <mach/hardware.h>
+
+#include "iomap.h"
/* selected INTC register offsets */
@@ -57,6 +64,8 @@ static struct omap_irq_bank {
},
};
+static struct irq_domain *domain;
+
/* Structure to save interrupt controller context */
struct omap3_intc_regs {
u32 sysconfig;
@@ -147,17 +156,27 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
}
-static void __init omap_init_irq(u32 base, int nr_irqs)
+static void __init omap_init_irq(u32 base, int nr_irqs,
+ struct device_node *node)
{
void __iomem *omap_irq_base;
unsigned long nr_of_irqs = 0;
unsigned int nr_banks = 0;
- int i, j;
+ int i, j, irq_base;
omap_irq_base = ioremap(base, SZ_4K);
if (WARN_ON(!omap_irq_base))
return;
+ irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
+ if (irq_base < 0) {
+ pr_warn("Couldn't allocate IRQ numbers\n");
+ irq_base = 0;
+ }
+
+ domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
+ &irq_domain_simple_ops, NULL);
+
for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
struct omap_irq_bank *bank = irq_banks + i;
@@ -166,36 +185,36 @@ static void __init omap_init_irq(u32 base, int nr_irqs)
/* Static mapping, never released */
bank->base_reg = ioremap(base, SZ_4K);
if (!bank->base_reg) {
- printk(KERN_ERR "Could not ioremap irq bank%i\n", i);
+ pr_err("Could not ioremap irq bank%i\n", i);
continue;
}
omap_irq_bank_init_one(bank);
for (j = 0; j < bank->nr_irqs; j += 32)
- omap_alloc_gc(bank->base_reg + j, j, 32);
+ omap_alloc_gc(bank->base_reg + j, j + irq_base, 32);
nr_of_irqs += bank->nr_irqs;
nr_banks++;
}
- printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
- nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
+ pr_info("Total of %ld interrupts on %d active controller%s\n",
+ nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
}
void __init omap2_init_irq(void)
{
- omap_init_irq(OMAP24XX_IC_BASE, 96);
+ omap_init_irq(OMAP24XX_IC_BASE, 96, NULL);
}
void __init omap3_init_irq(void)
{
- omap_init_irq(OMAP34XX_IC_BASE, 96);
+ omap_init_irq(OMAP34XX_IC_BASE, 96, NULL);
}
void __init ti81xx_init_irq(void)
{
- omap_init_irq(OMAP34XX_IC_BASE, 128);
+ omap_init_irq(OMAP34XX_IC_BASE, 128, NULL);
}
static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs)
@@ -225,8 +244,10 @@ out:
irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET);
irqnr &= ACTIVEIRQ_MASK;
- if (irqnr)
+ if (irqnr) {
+ irqnr = irq_find_mapping(domain, irqnr);
handle_IRQ(irqnr, regs);
+ }
} while (irqnr);
}
@@ -236,6 +257,28 @@ asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs
omap_intc_handle_irq(base_addr, regs);
}
+int __init omap_intc_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct resource res;
+ u32 nr_irqs = 96;
+
+ if (WARN_ON(!node))
+ return -ENODEV;
+
+ if (of_address_to_resource(node, 0, &res)) {
+ WARN(1, "unable to get intc registers\n");
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(node, "ti,intc-size", &nr_irqs))
+ pr_warn("unable to get intc-size, default to %d\n", nr_irqs);
+
+ omap_init_irq(res.start, nr_irqs, of_node_get(node));
+
+ return 0;
+}
+
#ifdef CONFIG_ARCH_OMAP3
static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];