rk30: fix fiq support when smp

This commit is contained in:
黄涛
2012-03-15 16:14:46 +08:00
parent 5d1bee9d76
commit 3a63866fdd
2 changed files with 46 additions and 17 deletions

View File

@@ -92,29 +92,17 @@ void rk_irq_clearpending(int irq)
void rk30_fiq_init(void)
{
void __iomem *base = RK30_GICD_BASE;
unsigned int gic_irqs, i;
// read gic info to know how many irqs in our chip
gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f;
//set all the interrupt to non-secure state
gic_irqs = readl_relaxed(RK30_GICD_BASE + GIC_DIST_CTR) & 0x1f;
// set all the interrupt to non-secure state
for (i = 0; i < (gic_irqs + 1); i++) {
/*
* In any system that implements the ARM Security Extensions,
* to support a consistent model for message passing between
* processors, ARM strongly recommends that all processors reserve:
* ID0-ID7 for Non-secure interrupts
* ID8-ID15 for Secure interrupts.
*/
if (i == 0) {
writel_relaxed(0xffff00ff, base + GIC_DIST_SECURITY + (i<<2));
} else {
writel_relaxed(0xffffffff, base + GIC_DIST_SECURITY + (i<<2));
}
writel_relaxed(0xffffffff, RK30_GICD_BASE + GIC_DIST_SECURITY + (i<<2));
}
dsb();
writel_relaxed(0x3, base + GIC_DIST_CTRL);
writel_relaxed(0x1f, RK30_GICC_BASE + GIC_CPU_CTRL);
writel_relaxed(0x3, RK30_GICD_BASE + GIC_DIST_CTRL);
writel_relaxed(0xf, RK30_GICC_BASE + GIC_CPU_CTRL);
dsb();
}

View File

@@ -17,6 +17,39 @@
#include <mach/pmu.h>
#ifdef CONFIG_FIQ
static void gic_raise_softirq_non_secure(const struct cpumask *mask, unsigned int irq)
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
unsigned long map = *cpus_addr(*mask);
#else
int cpu;
unsigned long map = 0;
/* Convert our logical CPU mask into a physical one. */
for_each_cpu(cpu, mask)
map |= 1 << cpu_logical_map(cpu);
#endif
/*
* Ensure that stores to Normal memory are visible to the
* other CPUs before issuing the IPI.
*/
dsb();
/* this always happens on GIC0 */
writel_relaxed(map << 16 | irq | 0x8000, RK30_GICD_BASE + GIC_DIST_SOFTINT);
}
static void gic_secondary_init_non_secure(void)
{
#define GIC_DIST_SECURITY 0x080
writel_relaxed(0xffffffff, RK30_GICD_BASE + GIC_DIST_SECURITY);
writel_relaxed(0xf, RK30_GICC_BASE + GIC_CPU_CTRL);
dsb();
}
#endif
void __cpuinit platform_secondary_init(unsigned int cpu)
{
/*
@@ -25,6 +58,10 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
* for us: do so
*/
gic_secondary_init(0);
#ifdef CONFIG_FIQ
gic_secondary_init_non_secure();
#endif
}
extern void rk30_sram_secondary_startup(void);
@@ -66,7 +103,11 @@ void __init smp_init_cpus(void)
for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
#ifdef CONFIG_FIQ
set_smp_cross_call(gic_raise_softirq_non_secure);
#else
set_smp_cross_call(gic_raise_softirq);
#endif
}
void __init platform_smp_prepare_cpus(unsigned int max_cpus)