diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-01-18 04:42:18 -0500 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-02-11 09:30:37 -0500 |
commit | bacdf4809afade180a8f2171adb4cf7ec715d139 (patch) | |
tree | a2cdf633a0604f3b736d4686b404463243f78a12 | |
parent | 9d42c84f9182da615e7ec0964ce585f23c822349 (diff) |
ARC: Interrupt Handling
This contains:
-bootup arch IRQ init: init_IRQ(), arc_init_IRQ()
-generic IRQ subsystem glue: arch_do_IRQ()
-basic IRQ chip setup for in-core intc
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/arc/include/asm/arcregs.h | 3 | ||||
-rw-r--r-- | arch/arc/include/asm/hw_irq.h | 7 | ||||
-rw-r--r-- | arch/arc/include/asm/irq.h | 22 | ||||
-rw-r--r-- | arch/arc/kernel/irq.c | 107 | ||||
-rw-r--r-- | arch/arc/plat-arcfpga/irq.c | 15 |
5 files changed, 152 insertions, 2 deletions
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 8ca8faf4b80e..3fccb04e6d93 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h | |||
@@ -11,6 +11,9 @@ | |||
11 | 11 | ||
12 | #ifdef __KERNEL__ | 12 | #ifdef __KERNEL__ |
13 | 13 | ||
14 | /* Build Configuration Registers */ | ||
15 | #define ARC_REG_VECBASE_BCR 0x68 | ||
16 | |||
14 | /* status32 Bits Positions */ | 17 | /* status32 Bits Positions */ |
15 | #define STATUS_H_BIT 0 /* CPU Halted */ | 18 | #define STATUS_H_BIT 0 /* CPU Halted */ |
16 | #define STATUS_E1_BIT 1 /* Int 1 enable */ | 19 | #define STATUS_E1_BIT 1 /* Int 1 enable */ |
diff --git a/arch/arc/include/asm/hw_irq.h b/arch/arc/include/asm/hw_irq.h new file mode 100644 index 000000000000..fd565ab89695 --- /dev/null +++ b/arch/arc/include/asm/hw_irq.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | ||
3 | * | ||
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. | ||
7 | */ | ||
diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h new file mode 100644 index 000000000000..ca4aeba1eed3 --- /dev/null +++ b/arch/arc/include/asm/irq.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | ||
3 | * | ||
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. | ||
7 | */ | ||
8 | |||
9 | #ifndef __ASM_ARC_IRQ_H | ||
10 | #define __ASM_ARC_IRQ_H | ||
11 | |||
12 | /* Platform Independent IRQs */ | ||
13 | #define TIMER0_IRQ 3 | ||
14 | #define TIMER1_IRQ 4 | ||
15 | |||
16 | #include <asm-generic/irq.h> | ||
17 | |||
18 | extern void __init arc_init_IRQ(void); | ||
19 | extern void __init plat_init_IRQ(void); | ||
20 | extern int __init get_hw_config_num_irq(void); | ||
21 | |||
22 | #endif | ||
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c index c4e9b25d305f..2f399eb88f9d 100644 --- a/arch/arc/kernel/irq.c +++ b/arch/arc/kernel/irq.c | |||
@@ -9,8 +9,111 @@ | |||
9 | 9 | ||
10 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <asm/irqflags.h> | 12 | #include <asm/sections.h> |
13 | #include <asm/arcregs.h> | 13 | #include <asm/irq.h> |
14 | |||
15 | /* | ||
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) | ||
20 | * | ||
21 | * what it does ? | ||
22 | * -setup Vector Table Base Reg - in case Linux not linked at 0x8000_0000 | ||
23 | * -Disable all IRQs (on CPU side) | ||
24 | */ | ||
25 | void __init arc_init_IRQ(void) | ||
26 | { | ||
27 | int level_mask = level_mask; | ||
28 | |||
29 | write_aux_reg(AUX_INTR_VEC_BASE, _int_vec_base_lds); | ||
30 | |||
31 | /* Disable all IRQs: enable them as devices request */ | ||
32 | write_aux_reg(AUX_IENABLE, 0); | ||
33 | } | ||
34 | |||
35 | /* | ||
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 | ||
40 | * | ||
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 | ||
43 | * below, per IRQ. | ||
44 | */ | ||
45 | |||
46 | static void arc_mask_irq(struct irq_data *data) | ||
47 | { | ||
48 | arch_mask_irq(data->irq); | ||
49 | } | ||
50 | |||
51 | static void arc_unmask_irq(struct irq_data *data) | ||
52 | { | ||
53 | arch_unmask_irq(data->irq); | ||
54 | } | ||
55 | |||
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, | ||
60 | }; | ||
61 | |||
62 | void __init init_onchip_IRQ(void) | ||
63 | { | ||
64 | int i; | ||
65 | |||
66 | for (i = 0; i < NR_IRQS; i++) | ||
67 | irq_set_chip_and_handler(i, &onchip_intc, handle_level_irq); | ||
68 | |||
69 | #ifdef CONFIG_SMP | ||
70 | irq_set_chip_and_handler(TIMER0_IRQ, &onchip_intc, handle_percpu_irq); | ||
71 | #endif | ||
72 | } | ||
73 | |||
74 | /* | ||
75 | * Late Interrupt system init called from start_kernel for Boot CPU only | ||
76 | * | ||
77 | * Since slab must already be initialized, platforms can start doing any | ||
78 | * needed request_irq( )s | ||
79 | */ | ||
80 | void __init init_IRQ(void) | ||
81 | { | ||
82 | init_onchip_IRQ(); | ||
83 | plat_init_IRQ(); | ||
84 | } | ||
85 | |||
86 | /* | ||
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 | ||
89 | */ | ||
90 | void arch_do_IRQ(unsigned int irq, struct pt_regs *regs) | ||
91 | { | ||
92 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
93 | |||
94 | irq_enter(); | ||
95 | generic_handle_irq(irq); | ||
96 | irq_exit(); | ||
97 | set_irq_regs(old_regs); | ||
98 | } | ||
99 | |||
100 | int __init get_hw_config_num_irq(void) | ||
101 | { | ||
102 | uint32_t val = read_aux_reg(ARC_REG_VECBASE_BCR); | ||
103 | |||
104 | switch (val & 0x03) { | ||
105 | case 0: | ||
106 | return 16; | ||
107 | case 1: | ||
108 | return 32; | ||
109 | case 2: | ||
110 | return 8; | ||
111 | default: | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | return 0; | ||
116 | } | ||
14 | 117 | ||
15 | void arch_local_irq_enable(void) | 118 | void arch_local_irq_enable(void) |
16 | { | 119 | { |
diff --git a/arch/arc/plat-arcfpga/irq.c b/arch/arc/plat-arcfpga/irq.c new file mode 100644 index 000000000000..ed726360b9f6 --- /dev/null +++ b/arch/arc/plat-arcfpga/irq.c | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * ARC FPGA Platform IRQ hookups | ||
3 | * | ||
4 | * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/interrupt.h> | ||
12 | |||
13 | void __init plat_init_IRQ(void) | ||
14 | { | ||
15 | } | ||