aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorChanghwan Youn <chaos.youn@samsung.com>2011-10-04 04:08:57 -0400
committerKukjin Kim <kgene.kim@samsung.com>2011-10-04 05:35:02 -0400
commit90a454b4c5ef16ec71797b3dcaf454e604c786a3 (patch)
tree11cf8fcec590c912b4cb35a24232337f1f7e1946 /arch
parentb88b1cc72e2bbb55c56f2df55b5ad59a18ad1464 (diff)
ARM: EXYNOS4: Add functions for gic interrupt handling
This patch adds two functions for gic interrupt handling. 1. Add interrupt handling of 4 cores. 2. Dynamically set gic bank offset according to the type of soc. Gic bank offset of EXYNOS4412 is 0x4000 while the offset of EXYNOS4210 and EXYNOS4212 is 0x8000. This patch is necessary because EXYNOS4 socs cannot support GIC register banking as described in commit aab74d3e75364. Signed-off-by: Changhwan Youn <chaos.youn@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-exynos4/cpu.c8
-rw-r--r--arch/arm/mach-exynos4/include/mach/entry-macro.S23
-rw-r--r--arch/arm/mach-exynos4/include/mach/map.h1
-rw-r--r--arch/arm/mach-exynos4/platsmp.c5
4 files changed, 27 insertions, 10 deletions
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index 940bc12f7547..a348434f17b5 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -32,6 +32,8 @@
32#include <mach/regs-irq.h> 32#include <mach/regs-irq.h>
33#include <mach/regs-pmu.h> 33#include <mach/regs-pmu.h>
34 34
35unsigned int gic_bank_offset __read_mostly;
36
35extern int combiner_init(unsigned int combiner_nr, void __iomem *base, 37extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
36 unsigned int irq_start); 38 unsigned int irq_start);
37extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); 39extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
@@ -203,16 +205,18 @@ static void exynos4_gic_irq_fix_base(struct irq_data *d)
203 struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); 205 struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
204 206
205 gic_data->cpu_base = S5P_VA_GIC_CPU + 207 gic_data->cpu_base = S5P_VA_GIC_CPU +
206 (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); 208 (gic_bank_offset * smp_processor_id());
207 209
208 gic_data->dist_base = S5P_VA_GIC_DIST + 210 gic_data->dist_base = S5P_VA_GIC_DIST +
209 (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); 211 (gic_bank_offset * smp_processor_id());
210} 212}
211 213
212void __init exynos4_init_irq(void) 214void __init exynos4_init_irq(void)
213{ 215{
214 int irq; 216 int irq;
215 217
218 gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
219
216 gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); 220 gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
217 gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; 221 gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base;
218 gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; 222 gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base;
diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S
index 61393dcf5559..4c9adbd87eac 100644
--- a/arch/arm/mach-exynos4/include/mach/entry-macro.S
+++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S
@@ -17,12 +17,25 @@
17 .endm 17 .endm
18 18
19 .macro get_irqnr_preamble, base, tmp 19 .macro get_irqnr_preamble, base, tmp
20 ldr \base, =gic_cpu_base_addr 20 mov \tmp, #0
21
22 mrc p15, 0, \base, c0, c0, 5
23 and \base, \base, #3
24 cmp \base, #0
25 beq 1f
26
27 ldr \tmp, =gic_bank_offset
28 ldr \tmp, [\tmp]
29 cmp \base, #1
30 beq 1f
31
32 cmp \base, #2
33 addeq \tmp, \tmp, \tmp
34 addne \tmp, \tmp, \tmp, LSL #1
35
361: ldr \base, =gic_cpu_base_addr
21 ldr \base, [\base] 37 ldr \base, [\base]
22 mrc p15, 0, \tmp, c0, c0, 5 38 add \base, \base, \tmp
23 and \tmp, \tmp, #3
24 cmp \tmp, #1
25 addeq \base, \base, #EXYNOS4_GIC_BANK_OFFSET
26 .endm 39 .endm
27 40
28 .macro arch_ret_to_user, tmp1, tmp2 41 .macro arch_ret_to_user, tmp1, tmp2
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
index 7073ac730855..9f97eb8499ee 100644
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -62,7 +62,6 @@
62 62
63#define EXYNOS4_PA_GIC_CPU 0x10480000 63#define EXYNOS4_PA_GIC_CPU 0x10480000
64#define EXYNOS4_PA_GIC_DIST 0x10490000 64#define EXYNOS4_PA_GIC_DIST 0x10490000
65#define EXYNOS4_GIC_BANK_OFFSET 0x8000
66 65
67#define EXYNOS4_PA_COREPERI 0x10500000 66#define EXYNOS4_PA_COREPERI 0x10500000
68#define EXYNOS4_PA_TWD 0x10500600 67#define EXYNOS4_PA_TWD 0x10500600
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
index a3346e36d0ae..d5f0f299ba0d 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -32,6 +32,7 @@
32 32
33#include <plat/cpu.h> 33#include <plat/cpu.h>
34 34
35extern unsigned int gic_bank_offset;
35extern void exynos4_secondary_startup(void); 36extern void exynos4_secondary_startup(void);
36 37
37#define CPU1_BOOT_REG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ 38#define CPU1_BOOT_REG (samsung_rev() == EXYNOS4210_REV_1_1 ? \
@@ -67,9 +68,9 @@ static DEFINE_SPINLOCK(boot_lock);
67static void __cpuinit exynos4_gic_secondary_init(void) 68static void __cpuinit exynos4_gic_secondary_init(void)
68{ 69{
69 void __iomem *dist_base = S5P_VA_GIC_DIST + 70 void __iomem *dist_base = S5P_VA_GIC_DIST +
70 (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); 71 (gic_bank_offset * smp_processor_id());
71 void __iomem *cpu_base = S5P_VA_GIC_CPU + 72 void __iomem *cpu_base = S5P_VA_GIC_CPU +
72 (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); 73 (gic_bank_offset * smp_processor_id());
73 int i; 74 int i;
74 75
75 /* 76 /*