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();
}
#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)
{
/*
* for us: do so
*/
gic_secondary_init(0);
+
+#ifdef CONFIG_FIQ
+ gic_secondary_init_non_secure();
+#endif
}
extern void rk30_sram_secondary_startup(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)