diff options
-rw-r--r-- | Documentation/devicetree/bindings/arm/gic.txt | 4 | ||||
-rw-r--r-- | arch/arm/common/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/common/gic.c | 133 | ||||
-rw-r--r-- | arch/arm/include/asm/hardware/gic.h | 24 | ||||
-rw-r--r-- | arch/arm/mach-exynos/cpu.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-exynos/platsmp.c | 28 | ||||
-rw-r--r-- | arch/arm/plat-s5p/Kconfig | 1 |
7 files changed, 132 insertions, 77 deletions
diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt index 52916b4aa1fe..9b4b82a721b6 100644 --- a/Documentation/devicetree/bindings/arm/gic.txt +++ b/Documentation/devicetree/bindings/arm/gic.txt | |||
@@ -42,6 +42,10 @@ Optional | |||
42 | - interrupts : Interrupt source of the parent interrupt controller. Only | 42 | - interrupts : Interrupt source of the parent interrupt controller. Only |
43 | present on secondary GICs. | 43 | present on secondary GICs. |
44 | 44 | ||
45 | - cpu-offset : per-cpu offset within the distributor and cpu interface | ||
46 | regions, used when the GIC doesn't have banked registers. The offset is | ||
47 | cpu-offset * cpu-nr. | ||
48 | |||
45 | Example: | 49 | Example: |
46 | 50 | ||
47 | intc: interrupt-controller@fff11000 { | 51 | intc: interrupt-controller@fff11000 { |
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 74df9ca2be31..a3beda1213da 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig | |||
@@ -2,6 +2,9 @@ config ARM_GIC | |||
2 | select IRQ_DOMAIN | 2 | select IRQ_DOMAIN |
3 | bool | 3 | bool |
4 | 4 | ||
5 | config GIC_NON_BANKED | ||
6 | bool | ||
7 | |||
5 | config ARM_VIC | 8 | config ARM_VIC |
6 | bool | 9 | bool |
7 | 10 | ||
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 0e6ae470c94f..43cb6f1a7cf2 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
@@ -43,6 +43,31 @@ | |||
43 | #include <asm/mach/irq.h> | 43 | #include <asm/mach/irq.h> |
44 | #include <asm/hardware/gic.h> | 44 | #include <asm/hardware/gic.h> |
45 | 45 | ||
46 | union gic_base { | ||
47 | void __iomem *common_base; | ||
48 | void __percpu __iomem **percpu_base; | ||
49 | }; | ||
50 | |||
51 | struct gic_chip_data { | ||
52 | unsigned int irq_offset; | ||
53 | union gic_base dist_base; | ||
54 | union gic_base cpu_base; | ||
55 | #ifdef CONFIG_CPU_PM | ||
56 | u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; | ||
57 | u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; | ||
58 | u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; | ||
59 | u32 __percpu *saved_ppi_enable; | ||
60 | u32 __percpu *saved_ppi_conf; | ||
61 | #endif | ||
62 | #ifdef CONFIG_IRQ_DOMAIN | ||
63 | struct irq_domain domain; | ||
64 | #endif | ||
65 | unsigned int gic_irqs; | ||
66 | #ifdef CONFIG_GIC_NON_BANKED | ||
67 | void __iomem *(*get_base)(union gic_base *); | ||
68 | #endif | ||
69 | }; | ||
70 | |||
46 | static DEFINE_RAW_SPINLOCK(irq_controller_lock); | 71 | static DEFINE_RAW_SPINLOCK(irq_controller_lock); |
47 | 72 | ||
48 | /* Address of GIC 0 CPU interface */ | 73 | /* Address of GIC 0 CPU interface */ |
@@ -67,16 +92,48 @@ struct irq_chip gic_arch_extn = { | |||
67 | 92 | ||
68 | static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly; | 93 | static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly; |
69 | 94 | ||
95 | #ifdef CONFIG_GIC_NON_BANKED | ||
96 | static void __iomem *gic_get_percpu_base(union gic_base *base) | ||
97 | { | ||
98 | return *__this_cpu_ptr(base->percpu_base); | ||
99 | } | ||
100 | |||
101 | static void __iomem *gic_get_common_base(union gic_base *base) | ||
102 | { | ||
103 | return base->common_base; | ||
104 | } | ||
105 | |||
106 | static inline void __iomem *gic_data_dist_base(struct gic_chip_data *data) | ||
107 | { | ||
108 | return data->get_base(&data->dist_base); | ||
109 | } | ||
110 | |||
111 | static inline void __iomem *gic_data_cpu_base(struct gic_chip_data *data) | ||
112 | { | ||
113 | return data->get_base(&data->cpu_base); | ||
114 | } | ||
115 | |||
116 | static inline void gic_set_base_accessor(struct gic_chip_data *data, | ||
117 | void __iomem *(*f)(union gic_base *)) | ||
118 | { | ||
119 | data->get_base = f; | ||
120 | } | ||
121 | #else | ||
122 | #define gic_data_dist_base(d) ((d)->dist_base.common_base) | ||
123 | #define gic_data_cpu_base(d) ((d)->cpu_base.common_base) | ||
124 | #define gic_set_base_accessor(d,f) | ||
125 | #endif | ||
126 | |||
70 | static inline void __iomem *gic_dist_base(struct irq_data *d) | 127 | static inline void __iomem *gic_dist_base(struct irq_data *d) |
71 | { | 128 | { |
72 | struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); | 129 | struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); |
73 | return gic_data->dist_base; | 130 | return gic_data_dist_base(gic_data); |
74 | } | 131 | } |
75 | 132 | ||
76 | static inline void __iomem *gic_cpu_base(struct irq_data *d) | 133 | static inline void __iomem *gic_cpu_base(struct irq_data *d) |
77 | { | 134 | { |
78 | struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); | 135 | struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); |
79 | return gic_data->cpu_base; | 136 | return gic_data_cpu_base(gic_data); |
80 | } | 137 | } |
81 | 138 | ||
82 | static inline unsigned int gic_irq(struct irq_data *d) | 139 | static inline unsigned int gic_irq(struct irq_data *d) |
@@ -225,7 +282,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | |||
225 | chained_irq_enter(chip, desc); | 282 | chained_irq_enter(chip, desc); |
226 | 283 | ||
227 | raw_spin_lock(&irq_controller_lock); | 284 | raw_spin_lock(&irq_controller_lock); |
228 | status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK); | 285 | status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK); |
229 | raw_spin_unlock(&irq_controller_lock); | 286 | raw_spin_unlock(&irq_controller_lock); |
230 | 287 | ||
231 | gic_irq = (status & 0x3ff); | 288 | gic_irq = (status & 0x3ff); |
@@ -270,7 +327,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic) | |||
270 | u32 cpumask; | 327 | u32 cpumask; |
271 | unsigned int gic_irqs = gic->gic_irqs; | 328 | unsigned int gic_irqs = gic->gic_irqs; |
272 | struct irq_domain *domain = &gic->domain; | 329 | struct irq_domain *domain = &gic->domain; |
273 | void __iomem *base = gic->dist_base; | 330 | void __iomem *base = gic_data_dist_base(gic); |
274 | u32 cpu = 0; | 331 | u32 cpu = 0; |
275 | 332 | ||
276 | #ifdef CONFIG_SMP | 333 | #ifdef CONFIG_SMP |
@@ -330,8 +387,8 @@ static void __init gic_dist_init(struct gic_chip_data *gic) | |||
330 | 387 | ||
331 | static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) | 388 | static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) |
332 | { | 389 | { |
333 | void __iomem *dist_base = gic->dist_base; | 390 | void __iomem *dist_base = gic_data_dist_base(gic); |
334 | void __iomem *base = gic->cpu_base; | 391 | void __iomem *base = gic_data_cpu_base(gic); |
335 | int i; | 392 | int i; |
336 | 393 | ||
337 | /* | 394 | /* |
@@ -368,7 +425,7 @@ static void gic_dist_save(unsigned int gic_nr) | |||
368 | BUG(); | 425 | BUG(); |
369 | 426 | ||
370 | gic_irqs = gic_data[gic_nr].gic_irqs; | 427 | gic_irqs = gic_data[gic_nr].gic_irqs; |
371 | dist_base = gic_data[gic_nr].dist_base; | 428 | dist_base = gic_data_dist_base(&gic_data[gic_nr]); |
372 | 429 | ||
373 | if (!dist_base) | 430 | if (!dist_base) |
374 | return; | 431 | return; |
@@ -403,7 +460,7 @@ static void gic_dist_restore(unsigned int gic_nr) | |||
403 | BUG(); | 460 | BUG(); |
404 | 461 | ||
405 | gic_irqs = gic_data[gic_nr].gic_irqs; | 462 | gic_irqs = gic_data[gic_nr].gic_irqs; |
406 | dist_base = gic_data[gic_nr].dist_base; | 463 | dist_base = gic_data_dist_base(&gic_data[gic_nr]); |
407 | 464 | ||
408 | if (!dist_base) | 465 | if (!dist_base) |
409 | return; | 466 | return; |
@@ -439,8 +496,8 @@ static void gic_cpu_save(unsigned int gic_nr) | |||
439 | if (gic_nr >= MAX_GIC_NR) | 496 | if (gic_nr >= MAX_GIC_NR) |
440 | BUG(); | 497 | BUG(); |
441 | 498 | ||
442 | dist_base = gic_data[gic_nr].dist_base; | 499 | dist_base = gic_data_dist_base(&gic_data[gic_nr]); |
443 | cpu_base = gic_data[gic_nr].cpu_base; | 500 | cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); |
444 | 501 | ||
445 | if (!dist_base || !cpu_base) | 502 | if (!dist_base || !cpu_base) |
446 | return; | 503 | return; |
@@ -465,8 +522,8 @@ static void gic_cpu_restore(unsigned int gic_nr) | |||
465 | if (gic_nr >= MAX_GIC_NR) | 522 | if (gic_nr >= MAX_GIC_NR) |
466 | BUG(); | 523 | BUG(); |
467 | 524 | ||
468 | dist_base = gic_data[gic_nr].dist_base; | 525 | dist_base = gic_data_dist_base(&gic_data[gic_nr]); |
469 | cpu_base = gic_data[gic_nr].cpu_base; | 526 | cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); |
470 | 527 | ||
471 | if (!dist_base || !cpu_base) | 528 | if (!dist_base || !cpu_base) |
472 | return; | 529 | return; |
@@ -491,6 +548,11 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) | |||
491 | int i; | 548 | int i; |
492 | 549 | ||
493 | for (i = 0; i < MAX_GIC_NR; i++) { | 550 | for (i = 0; i < MAX_GIC_NR; i++) { |
551 | #ifdef CONFIG_GIC_NON_BANKED | ||
552 | /* Skip over unused GICs */ | ||
553 | if (!gic_data[i].get_base) | ||
554 | continue; | ||
555 | #endif | ||
494 | switch (cmd) { | 556 | switch (cmd) { |
495 | case CPU_PM_ENTER: | 557 | case CPU_PM_ENTER: |
496 | gic_cpu_save(i); | 558 | gic_cpu_save(i); |
@@ -563,8 +625,9 @@ const struct irq_domain_ops gic_irq_domain_ops = { | |||
563 | #endif | 625 | #endif |
564 | }; | 626 | }; |
565 | 627 | ||
566 | void __init gic_init(unsigned int gic_nr, int irq_start, | 628 | void __init gic_init_bases(unsigned int gic_nr, int irq_start, |
567 | void __iomem *dist_base, void __iomem *cpu_base) | 629 | void __iomem *dist_base, void __iomem *cpu_base, |
630 | u32 percpu_offset) | ||
568 | { | 631 | { |
569 | struct gic_chip_data *gic; | 632 | struct gic_chip_data *gic; |
570 | struct irq_domain *domain; | 633 | struct irq_domain *domain; |
@@ -574,8 +637,36 @@ void __init gic_init(unsigned int gic_nr, int irq_start, | |||
574 | 637 | ||
575 | gic = &gic_data[gic_nr]; | 638 | gic = &gic_data[gic_nr]; |
576 | domain = &gic->domain; | 639 | domain = &gic->domain; |
577 | gic->dist_base = dist_base; | 640 | #ifdef CONFIG_GIC_NON_BANKED |
578 | gic->cpu_base = cpu_base; | 641 | if (percpu_offset) { /* Frankein-GIC without banked registers... */ |
642 | unsigned int cpu; | ||
643 | |||
644 | gic->dist_base.percpu_base = alloc_percpu(void __iomem *); | ||
645 | gic->cpu_base.percpu_base = alloc_percpu(void __iomem *); | ||
646 | if (WARN_ON(!gic->dist_base.percpu_base || | ||
647 | !gic->cpu_base.percpu_base)) { | ||
648 | free_percpu(gic->dist_base.percpu_base); | ||
649 | free_percpu(gic->cpu_base.percpu_base); | ||
650 | return; | ||
651 | } | ||
652 | |||
653 | for_each_possible_cpu(cpu) { | ||
654 | unsigned long offset = percpu_offset * cpu_logical_map(cpu); | ||
655 | *per_cpu_ptr(gic->dist_base.percpu_base, cpu) = dist_base + offset; | ||
656 | *per_cpu_ptr(gic->cpu_base.percpu_base, cpu) = cpu_base + offset; | ||
657 | } | ||
658 | |||
659 | gic_set_base_accessor(gic, gic_get_percpu_base); | ||
660 | } else | ||
661 | #endif | ||
662 | { /* Normal, sane GIC... */ | ||
663 | WARN(percpu_offset, | ||
664 | "GIC_NON_BANKED not enabled, ignoring %08x offset!", | ||
665 | percpu_offset); | ||
666 | gic->dist_base.common_base = dist_base; | ||
667 | gic->cpu_base.common_base = cpu_base; | ||
668 | gic_set_base_accessor(gic, gic_get_common_base); | ||
669 | } | ||
579 | 670 | ||
580 | /* | 671 | /* |
581 | * For primary GICs, skip over SGIs. | 672 | * For primary GICs, skip over SGIs. |
@@ -593,7 +684,7 @@ void __init gic_init(unsigned int gic_nr, int irq_start, | |||
593 | * Find out how many interrupts are supported. | 684 | * Find out how many interrupts are supported. |
594 | * The GIC only supports up to 1020 interrupt sources. | 685 | * The GIC only supports up to 1020 interrupt sources. |
595 | */ | 686 | */ |
596 | gic_irqs = readl_relaxed(dist_base + GIC_DIST_CTR) & 0x1f; | 687 | gic_irqs = readl_relaxed(gic_data_dist_base(gic) + GIC_DIST_CTR) & 0x1f; |
597 | gic_irqs = (gic_irqs + 1) * 32; | 688 | gic_irqs = (gic_irqs + 1) * 32; |
598 | if (gic_irqs > 1020) | 689 | if (gic_irqs > 1020) |
599 | gic_irqs = 1020; | 690 | gic_irqs = 1020; |
@@ -641,7 +732,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | |||
641 | dsb(); | 732 | dsb(); |
642 | 733 | ||
643 | /* this always happens on GIC0 */ | 734 | /* this always happens on GIC0 */ |
644 | writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); | 735 | writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); |
645 | } | 736 | } |
646 | #endif | 737 | #endif |
647 | 738 | ||
@@ -652,6 +743,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) | |||
652 | { | 743 | { |
653 | void __iomem *cpu_base; | 744 | void __iomem *cpu_base; |
654 | void __iomem *dist_base; | 745 | void __iomem *dist_base; |
746 | u32 percpu_offset; | ||
655 | int irq; | 747 | int irq; |
656 | struct irq_domain *domain = &gic_data[gic_cnt].domain; | 748 | struct irq_domain *domain = &gic_data[gic_cnt].domain; |
657 | 749 | ||
@@ -664,9 +756,12 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) | |||
664 | cpu_base = of_iomap(node, 1); | 756 | cpu_base = of_iomap(node, 1); |
665 | WARN(!cpu_base, "unable to map gic cpu registers\n"); | 757 | WARN(!cpu_base, "unable to map gic cpu registers\n"); |
666 | 758 | ||
759 | if (of_property_read_u32(node, "cpu-offset", &percpu_offset)) | ||
760 | percpu_offset = 0; | ||
761 | |||
667 | domain->of_node = of_node_get(node); | 762 | domain->of_node = of_node_get(node); |
668 | 763 | ||
669 | gic_init(gic_cnt, -1, dist_base, cpu_base); | 764 | gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset); |
670 | 765 | ||
671 | if (parent) { | 766 | if (parent) { |
672 | irq = irq_of_parse_and_map(node, 0); | 767 | irq = irq_of_parse_and_map(node, 0); |
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 3e91f22046f5..2721d90625e5 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h | |||
@@ -39,27 +39,19 @@ struct device_node; | |||
39 | extern void __iomem *gic_cpu_base_addr; | 39 | extern void __iomem *gic_cpu_base_addr; |
40 | extern struct irq_chip gic_arch_extn; | 40 | extern struct irq_chip gic_arch_extn; |
41 | 41 | ||
42 | void gic_init(unsigned int, int, void __iomem *, void __iomem *); | 42 | void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, |
43 | u32 offset); | ||
43 | int gic_of_init(struct device_node *node, struct device_node *parent); | 44 | int gic_of_init(struct device_node *node, struct device_node *parent); |
44 | void gic_secondary_init(unsigned int); | 45 | void gic_secondary_init(unsigned int); |
45 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); | 46 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); |
46 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); | 47 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); |
47 | 48 | ||
48 | struct gic_chip_data { | 49 | static inline void gic_init(unsigned int nr, int start, |
49 | void __iomem *dist_base; | 50 | void __iomem *dist , void __iomem *cpu) |
50 | void __iomem *cpu_base; | 51 | { |
51 | #ifdef CONFIG_CPU_PM | 52 | gic_init_bases(nr, start, dist, cpu, 0); |
52 | u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; | 53 | } |
53 | u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; | 54 | |
54 | u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; | ||
55 | u32 __percpu *saved_ppi_enable; | ||
56 | u32 __percpu *saved_ppi_conf; | ||
57 | #endif | ||
58 | #ifdef CONFIG_IRQ_DOMAIN | ||
59 | struct irq_domain domain; | ||
60 | #endif | ||
61 | unsigned int gic_irqs; | ||
62 | }; | ||
63 | #endif | 55 | #endif |
64 | 56 | ||
65 | #endif | 57 | #endif |
diff --git a/arch/arm/mach-exynos/cpu.c b/arch/arm/mach-exynos/cpu.c index 90ec247f3b37..e92e464bdbba 100644 --- a/arch/arm/mach-exynos/cpu.c +++ b/arch/arm/mach-exynos/cpu.c | |||
@@ -207,27 +207,13 @@ void __init exynos4_init_clocks(int xtal) | |||
207 | exynos4_setup_clocks(); | 207 | exynos4_setup_clocks(); |
208 | } | 208 | } |
209 | 209 | ||
210 | static void exynos4_gic_irq_fix_base(struct irq_data *d) | ||
211 | { | ||
212 | struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); | ||
213 | |||
214 | gic_data->cpu_base = S5P_VA_GIC_CPU + | ||
215 | (gic_bank_offset * smp_processor_id()); | ||
216 | |||
217 | gic_data->dist_base = S5P_VA_GIC_DIST + | ||
218 | (gic_bank_offset * smp_processor_id()); | ||
219 | } | ||
220 | |||
221 | void __init exynos4_init_irq(void) | 210 | void __init exynos4_init_irq(void) |
222 | { | 211 | { |
223 | int irq; | 212 | int irq; |
224 | 213 | ||
225 | gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; | 214 | gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; |
226 | 215 | ||
227 | gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); | 216 | gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset); |
228 | gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; | ||
229 | gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; | ||
230 | gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base; | ||
231 | 217 | ||
232 | for (irq = 0; irq < MAX_COMBINER_NR; irq++) { | 218 | for (irq = 0; irq < MAX_COMBINER_NR; irq++) { |
233 | 219 | ||
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 69ffb2fb3875..60bc45e3e709 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | #include <plat/cpu.h> | 33 | #include <plat/cpu.h> |
34 | 34 | ||
35 | extern unsigned int gic_bank_offset; | ||
36 | extern void exynos4_secondary_startup(void); | 35 | extern void exynos4_secondary_startup(void); |
37 | 36 | ||
38 | #define CPU1_BOOT_REG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ | 37 | #define CPU1_BOOT_REG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ |
@@ -65,31 +64,6 @@ static void __iomem *scu_base_addr(void) | |||
65 | 64 | ||
66 | static DEFINE_SPINLOCK(boot_lock); | 65 | static DEFINE_SPINLOCK(boot_lock); |
67 | 66 | ||
68 | static void __cpuinit exynos4_gic_secondary_init(void) | ||
69 | { | ||
70 | void __iomem *dist_base = S5P_VA_GIC_DIST + | ||
71 | (gic_bank_offset * smp_processor_id()); | ||
72 | void __iomem *cpu_base = S5P_VA_GIC_CPU + | ||
73 | (gic_bank_offset * smp_processor_id()); | ||
74 | int i; | ||
75 | |||
76 | /* | ||
77 | * Deal with the banked PPI and SGI interrupts - disable all | ||
78 | * PPI interrupts, ensure all SGI interrupts are enabled. | ||
79 | */ | ||
80 | __raw_writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); | ||
81 | __raw_writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); | ||
82 | |||
83 | /* | ||
84 | * Set priority on PPI and SGI interrupts | ||
85 | */ | ||
86 | for (i = 0; i < 32; i += 4) | ||
87 | __raw_writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); | ||
88 | |||
89 | __raw_writel(0xf0, cpu_base + GIC_CPU_PRIMASK); | ||
90 | __raw_writel(1, cpu_base + GIC_CPU_CTRL); | ||
91 | } | ||
92 | |||
93 | void __cpuinit platform_secondary_init(unsigned int cpu) | 67 | void __cpuinit platform_secondary_init(unsigned int cpu) |
94 | { | 68 | { |
95 | /* | 69 | /* |
@@ -97,7 +71,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) | |||
97 | * core (e.g. timer irq), then they will not have been enabled | 71 | * core (e.g. timer irq), then they will not have been enabled |
98 | * for us: do so | 72 | * for us: do so |
99 | */ | 73 | */ |
100 | exynos4_gic_secondary_init(); | 74 | gic_secondary_init(0); |
101 | 75 | ||
102 | /* | 76 | /* |
103 | * let the primary processor know we're out of the | 77 | * let the primary processor know we're out of the |
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 9b9968fa8695..8167ce66188c 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig | |||
@@ -11,6 +11,7 @@ config PLAT_S5P | |||
11 | default y | 11 | default y |
12 | select ARM_VIC if !ARCH_EXYNOS4 | 12 | select ARM_VIC if !ARCH_EXYNOS4 |
13 | select ARM_GIC if ARCH_EXYNOS4 | 13 | select ARM_GIC if ARCH_EXYNOS4 |
14 | select GIC_NON_BANKED if ARCH_EXYNOS4 | ||
14 | select NO_IOPORT | 15 | select NO_IOPORT |
15 | select ARCH_REQUIRE_GPIOLIB | 16 | select ARCH_REQUIRE_GPIOLIB |
16 | select S3C_GPIO_TRACK | 17 | select S3C_GPIO_TRACK |