diff options
Diffstat (limited to 'arch/arm/common/gic.c')
-rw-r--r-- | arch/arm/common/gic.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 36ae03a3f5d1..788658cca960 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
@@ -617,6 +617,27 @@ static void __init gic_pm_init(struct gic_chip_data *gic) | |||
617 | } | 617 | } |
618 | #endif | 618 | #endif |
619 | 619 | ||
620 | #ifdef CONFIG_SMP | ||
621 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | ||
622 | { | ||
623 | int cpu; | ||
624 | unsigned long map = 0; | ||
625 | |||
626 | /* Convert our logical CPU mask into a physical one. */ | ||
627 | for_each_cpu(cpu, mask) | ||
628 | map |= 1 << cpu_logical_map(cpu); | ||
629 | |||
630 | /* | ||
631 | * Ensure that stores to Normal memory are visible to the | ||
632 | * other CPUs before issuing the IPI. | ||
633 | */ | ||
634 | dsb(); | ||
635 | |||
636 | /* this always happens on GIC0 */ | ||
637 | writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); | ||
638 | } | ||
639 | #endif | ||
640 | |||
620 | static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, | 641 | static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, |
621 | irq_hw_number_t hw) | 642 | irq_hw_number_t hw) |
622 | { | 643 | { |
@@ -743,6 +764,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
743 | if (WARN_ON(!gic->domain)) | 764 | if (WARN_ON(!gic->domain)) |
744 | return; | 765 | return; |
745 | 766 | ||
767 | #ifdef CONFIG_SMP | ||
768 | set_smp_cross_call(gic_raise_softirq); | ||
769 | #endif | ||
746 | gic_chip.flags |= gic_arch_extn.flags; | 770 | gic_chip.flags |= gic_arch_extn.flags; |
747 | gic_dist_init(gic); | 771 | gic_dist_init(gic); |
748 | gic_cpu_init(gic); | 772 | gic_cpu_init(gic); |
@@ -756,27 +780,6 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr) | |||
756 | gic_cpu_init(&gic_data[gic_nr]); | 780 | gic_cpu_init(&gic_data[gic_nr]); |
757 | } | 781 | } |
758 | 782 | ||
759 | #ifdef CONFIG_SMP | ||
760 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | ||
761 | { | ||
762 | int cpu; | ||
763 | unsigned long map = 0; | ||
764 | |||
765 | /* Convert our logical CPU mask into a physical one. */ | ||
766 | for_each_cpu(cpu, mask) | ||
767 | map |= gic_cpu_map[cpu]; | ||
768 | |||
769 | /* | ||
770 | * Ensure that stores to Normal memory are visible to the | ||
771 | * other CPUs before issuing the IPI. | ||
772 | */ | ||
773 | dsb(); | ||
774 | |||
775 | /* this always happens on GIC0 */ | ||
776 | writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); | ||
777 | } | ||
778 | #endif | ||
779 | |||
780 | #ifdef CONFIG_OF | 783 | #ifdef CONFIG_OF |
781 | static int gic_cnt __initdata = 0; | 784 | static int gic_cnt __initdata = 0; |
782 | 785 | ||