*/
volatile int __cpuinitdata pen_release = -1;
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
+static void write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
static void __iomem *scu_base_addr(void)
{
return MMIO_P2V(A9_MPCORE_SCU);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
- trace_hardirqs_off();
-
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
- gic_cpu_init(0, gic_cpu_base_addr);
+ gic_secondary_init(0);
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
- pen_release = -1;
- smp_wmb();
+ write_pen_release(-1);
/*
* Synchronise with the boot thread.
* since we haven't sent them a soft interrupt, they shouldn't
* be there.
*/
- pen_release = cpu;
- __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
- outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+ write_pen_release(cpu);
/*
* Send the secondary CPU a soft interrupt, thereby causing