ARM: EXYNOS4: Add functions for gic interrupt handling
authorChanghwan Youn <chaos.youn@samsung.com>
Tue, 4 Oct 2011 08:08:57 +0000 (17:08 +0900)
committerKukjin Kim <kgene.kim@samsung.com>
Tue, 4 Oct 2011 09:35:02 +0000 (18:35 +0900)
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>
arch/arm/mach-exynos4/cpu.c
arch/arm/mach-exynos4/include/mach/entry-macro.S
arch/arm/mach-exynos4/include/mach/map.h
arch/arm/mach-exynos4/platsmp.c

index 940bc12f754733e9225030fc47e73ab8d68d888a..a348434f17b5016fe69034bc1b3300742dbb9d06 100644 (file)
@@ -32,6 +32,8 @@
 #include <mach/regs-irq.h>
 #include <mach/regs-pmu.h>
 
+unsigned int gic_bank_offset __read_mostly;
+
 extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
                         unsigned int irq_start);
 extern 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)
        struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
 
        gic_data->cpu_base = S5P_VA_GIC_CPU +
-                           (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id());
+                           (gic_bank_offset * smp_processor_id());
 
        gic_data->dist_base = S5P_VA_GIC_DIST +
-                           (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id());
+                           (gic_bank_offset * smp_processor_id());
 }
 
 void __init exynos4_init_irq(void)
 {
        int irq;
 
+       gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
+
        gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
        gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base;
        gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base;
index 61393dcf55597371173e7447dcd908759d0d5330..4c9adbd87eac864e16fd77b72f9c3b4a9f9c5c45 100644 (file)
                .endm
 
                .macro  get_irqnr_preamble, base, tmp
-               ldr     \base, =gic_cpu_base_addr
+               mov     \tmp, #0
+
+               mrc     p15, 0, \base, c0, c0, 5
+               and     \base, \base, #3
+               cmp     \base, #0
+               beq     1f
+
+               ldr     \tmp, =gic_bank_offset
+               ldr     \tmp, [\tmp]
+               cmp     \base, #1
+               beq     1f
+
+               cmp     \base, #2
+               addeq   \tmp, \tmp, \tmp
+               addne   \tmp, \tmp, \tmp, LSL #1
+
+1:             ldr     \base, =gic_cpu_base_addr
                ldr     \base, [\base]
-               mrc     p15, 0, \tmp, c0, c0, 5
-               and     \tmp, \tmp, #3
-               cmp     \tmp, #1
-               addeq   \base, \base, #EXYNOS4_GIC_BANK_OFFSET
+               add     \base, \base, \tmp
                .endm
 
                .macro  arch_ret_to_user, tmp1, tmp2
index 7073ac7308554fe77672898468b690cd356c71a4..9f97eb8499ee9899af46bbea81903c2f8021e300 100644 (file)
@@ -62,7 +62,6 @@
 
 #define EXYNOS4_PA_GIC_CPU             0x10480000
 #define EXYNOS4_PA_GIC_DIST            0x10490000
-#define EXYNOS4_GIC_BANK_OFFSET                0x8000
 
 #define EXYNOS4_PA_COREPERI            0x10500000
 #define EXYNOS4_PA_TWD                 0x10500600
index a3346e36d0aeb84061ff3a41f596e51dfb93bf14..d5f0f299ba0d6ae608c9d4ee87082c8fa50b7688 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <plat/cpu.h>
 
+extern unsigned int gic_bank_offset;
 extern void exynos4_secondary_startup(void);
 
 #define CPU1_BOOT_REG          (samsung_rev() == EXYNOS4210_REV_1_1 ? \
@@ -67,9 +68,9 @@ static DEFINE_SPINLOCK(boot_lock);
 static void __cpuinit exynos4_gic_secondary_init(void)
 {
        void __iomem *dist_base = S5P_VA_GIC_DIST +
-                                (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id());
+                               (gic_bank_offset * smp_processor_id());
        void __iomem *cpu_base = S5P_VA_GIC_CPU +
-                               (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id());
+                               (gic_bank_offset * smp_processor_id());
        int i;
 
        /*
This page took 0.047842 seconds and 5 git commands to generate.