13 #include <linux/kernel.h>
14 #include <linux/module.h>
19 #include <asm/exception.h>
32 #define INTC_REVISION 0x0000
33 #define INTC_SYSCONFIG 0x0010
34 #define INTC_SYSSTATUS 0x0014
35 #define INTC_SIR 0x0040
36 #define INTC_CONTROL 0x0048
37 #define INTC_PROTECTION 0x004C
38 #define INTC_IDLE 0x0050
39 #define INTC_THRESHOLD 0x0068
40 #define INTC_MIR0 0x0084
41 #define INTC_MIR_CLEAR0 0x0088
42 #define INTC_MIR_SET0 0x008c
43 #define INTC_PENDING_IRQ0 0x0098
45 #define IRQ_BITS_PER_REG 32
47 #define OMAP2_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE)
48 #define OMAP3_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE)
49 #define INTCPS_SIR_IRQ_OFFSET 0x0040
50 #define ACTIVEIRQ_MASK 0x7f
51 #define INTCPS_NR_MIR_REGS 3
52 #define INTCPS_NR_IRQS 96
95 static void omap_ack_irq(
struct irq_data *
d)
100 static void omap_mask_ack_irq(
struct irq_data *
d)
111 pr_info(
"IRQ: Found an INTC at 0x%p (revision %ld.%ld) with %d interrupts\n",
133 for (irq = 0; irq < bank->
nr_irqs; irq += 32)
142 omap_alloc_gc(
void __iomem *base,
unsigned int irq_start,
unsigned int num)
144 struct irq_chip_generic *
gc;
145 struct irq_chip_type *
ct;
150 ct->chip.irq_ack = omap_mask_ack_irq;
165 unsigned long nr_of_irqs = 0;
166 unsigned int nr_banks = 0;
173 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
175 pr_warn(
"Couldn't allocate IRQ numbers\n");
190 pr_err(
"Could not ioremap irq bank%i\n", i);
194 omap_irq_bank_init_one(bank);
196 for (j = 0; j < bank->
nr_irqs; j += 32)
197 omap_alloc_gc(bank->
base_reg + j, j + irq_base, 32);
203 pr_info(
"Total of %ld interrupts on %d active controller%s\n",
204 nr_of_irqs, nr_banks, nr_banks > 1 ?
"s" :
"");
222 static inline void omap_intc_handle_irq(
void __iomem *base_addr,
struct pt_regs *
regs)
236 #ifdef CONFIG_SOC_TI81XX
259 omap_intc_handle_irq(base_addr, regs);
272 WARN(1,
"unable to get intc registers\n");
276 if (of_property_read_u32(node,
"ti,intc-size", &nr_irq))
277 pr_warn(
"unable to get intc-size, default to %d\n", nr_irq);
279 omap_init_irq(res.
start, nr_irq, of_node_get(node));
285 { .compatible =
"ti,omap2-intc", .data =
intc_of_init, },
294 #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
297 void omap_intc_save_context(
void)
300 for (ind = 0; ind <
ARRAY_SIZE(irq_banks); ind++) {
302 intc_context[
ind].sysconfig =
304 intc_context[
ind].protection =
306 intc_context[
ind].idle =
308 intc_context[
ind].threshold =
311 intc_context[ind].ilr[i] =
312 intc_bank_read_reg(bank, (0x100 + 0x4*i));
314 intc_context[ind].mir[i] =
315 intc_bank_read_reg(&irq_banks[0],
INTC_MIR0 +
320 void omap_intc_restore_context(
void)
324 for (ind = 0; ind <
ARRAY_SIZE(irq_banks); ind++) {
326 intc_bank_write_reg(intc_context[ind].sysconfig,
328 intc_bank_write_reg(intc_context[ind].sysconfig,
330 intc_bank_write_reg(intc_context[ind].protection,
332 intc_bank_write_reg(intc_context[ind].
idle,
334 intc_bank_write_reg(intc_context[ind].
threshold,
337 intc_bank_write_reg(intc_context[ind].ilr[i],
338 bank, (0x100 + 0x4*i));
340 intc_bank_write_reg(intc_context[ind].mir[i],
346 void omap3_intc_suspend(
void)
352 void omap3_intc_prepare_idle(
void)
361 void omap3_intc_resume_idle(
void)
370 omap_intc_handle_irq(base_addr, regs);