2 * Copyright (C) 2011-12 Synopsys, Inc. (www.synopsys.com)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
10 #include <linux/interrupt.h>
11 #include <linux/module.h>
12 #include <asm/sections.h>
16 * Early Hardware specific Interrupt setup
17 * -Called very early (start_kernel -> setup_arch -> setup_processor)
18 * -Platform Independent (must for any ARC700)
19 * -Needed for each CPU (hence not foldable into init_IRQ)
22 * -setup Vector Table Base Reg - in case Linux not linked at 0x8000_0000
23 * -Disable all IRQs (on CPU side)
25 void __init arc_init_IRQ(void)
27 int level_mask = level_mask;
29 write_aux_reg(AUX_INTR_VEC_BASE, _int_vec_base_lds);
31 /* Disable all IRQs: enable them as devices request */
32 write_aux_reg(AUX_IENABLE, 0);
36 * ARC700 core includes a simple on-chip intc supporting
37 * -per IRQ enable/disable
38 * -2 levels of interrupts (high/low)
39 * -all interrupts being level triggered
41 * To reduce platform code, we assume all IRQs directly hooked-up into intc.
42 * Platforms with external intc, hence cascaded IRQs, are free to over-ride
46 static void arc_mask_irq(struct irq_data *data)
48 arch_mask_irq(data->irq);
51 static void arc_unmask_irq(struct irq_data *data)
53 arch_unmask_irq(data->irq);
56 static struct irq_chip onchip_intc = {
57 .name = "ARC In-core Intc",
58 .irq_mask = arc_mask_irq,
59 .irq_unmask = arc_unmask_irq,
62 void __init init_onchip_IRQ(void)
66 for (i = 0; i < NR_IRQS; i++)
67 irq_set_chip_and_handler(i, &onchip_intc, handle_level_irq);
70 irq_set_chip_and_handler(TIMER0_IRQ, &onchip_intc, handle_percpu_irq);
75 * Late Interrupt system init called from start_kernel for Boot CPU only
77 * Since slab must already be initialized, platforms can start doing any
78 * needed request_irq( )s
80 void __init init_IRQ(void)
87 * "C" Entry point for any ARC ISR, called from low level vector handler
88 * @irq is the vector number read from ICAUSE reg of on-chip intc
90 void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
92 struct pt_regs *old_regs = set_irq_regs(regs);
95 generic_handle_irq(irq);
97 set_irq_regs(old_regs);
100 int __init get_hw_config_num_irq(void)
102 uint32_t val = read_aux_reg(ARC_REG_VECBASE_BCR);
104 switch (val & 0x03) {
118 void arch_local_irq_enable(void)
123 * ARC IDE Drivers tries to re-enable interrupts from hard-isr
124 * context which is simply wrong
127 WARN_ONCE(1, "IRQ enabled from hard-isr");
131 flags = arch_local_save_flags();
132 flags |= (STATUS_E1_MASK | STATUS_E2_MASK);
133 arch_local_irq_restore(flags);
135 EXPORT_SYMBOL(arch_local_irq_enable);