Thread (69 messages) 69 messages, 12 authors, 2011-09-17
STALE5373d
Revisions (14)
  1. v1 [diff vs current]
  2. v1 [diff vs current]
  3. v1 current
  4. v1 [diff vs current]
  5. v2 [diff vs current]
  6. v3 [diff vs current]
  7. v3 [diff vs current]
  8. v3 [diff vs current]
  9. v3 [diff vs current]
  10. v3 [diff vs current]
  11. v3 [diff vs current]
  12. v3 [diff vs current]
  13. v4 [diff vs current]
  14. v5 [diff vs current]

[PATCH 4/6] arm/imx6q: add smp and cpu hotplug support

From: Shawn Guo <hidden>
Date: 2011-09-07 04:41:45

On Tue, Sep 06, 2011 at 08:53:07PM +0200, Arnd Bergmann wrote:
On Tuesday 06 September 2011 17:58:38 Shawn Guo wrote:
quoted
It adds smp and cpu hotplug support for imx6q.
+static u32 twd_saved_regs[4];
+static int twd_irq;
+
+/*
+ * Resuming from ARM Dormant/Shutdown mode, the boot procedure will
+ * re-setup local timer for secondary cores.  For primary core, it
+ * has to take care of itself with the following pair of functions
+ * during suspend/resume.
+ */
+void imx_local_timer_pre_suspend(void)
+{
+	twd_saved_regs[0] = __raw_readl(twd_base + TWD_TIMER_LOAD);
+	twd_saved_regs[1] = __raw_readl(twd_base + TWD_TIMER_COUNTER);
+	twd_saved_regs[2] = __raw_readl(twd_base + TWD_TIMER_CONTROL);
+	twd_saved_regs[3] = __raw_readl(twd_base + TWD_TIMER_INTSTAT);
+}
+
+void imx_local_timer_post_resume(void)
+{
+	__raw_writel(twd_saved_regs[0], twd_base + TWD_TIMER_LOAD);
+	__raw_writel(twd_saved_regs[1], twd_base + TWD_TIMER_COUNTER);
+	__raw_writel(twd_saved_regs[2], twd_base + TWD_TIMER_CONTROL);
+	__raw_writel(twd_saved_regs[3], twd_base + TWD_TIMER_INTSTAT);
+
+	gic_enable_ppi(twd_irq);
+}
readl_relaxed()?
Ok.  You get the best judgement on this.
quoted
+extern void v7_secondary_startup(void);
+
+#define IMX_SCU_VIRT_BASE	0xf4a00000
+
+static void __iomem *scu_base = ((void __iomem *)(IMX_SCU_VIRT_BASE));
It's a little bit silly to have a variable for the base and then initialize
it statically. Not sure what the best solution is here.
I have to admit that this scu mapping code was cloned from highbank :)
quoted
+static struct map_desc scu_io_desc __initdata = {
+	.virtual	= IMX_SCU_VIRT_BASE,
+	.pfn		= 0, /* run-time */
+	.length		= SZ_4K,
+	.type		= MT_DEVICE,
+};
+
+void __init imx_scu_map_io(void)
+{
+	unsigned long base;
+
+	/* Get SCU base */
+	asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
+
+	scu_io_desc.pfn = __phys_to_pfn(base);
+	iotable_init(&scu_io_desc, 1);
+}
Maybe we can simply define a platform-independent where the SCU gets mapped?
That would get rid of most of the platform specific SCU code, at least for
those platforms that can reliably read the scu base.
Yes, if we can find a virtual base working for all platforms.  The scu
virtual base needs to be available before dynamic mapping gets ready,
so it has to be static mapping.
quoted
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+	int i, ncores;
+
+	ncores = scu_get_core_count(scu_base);
+
+	for (i = 0; i < ncores; i++)
+		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
+}
+
+void imx_smp_prepare(void)
+{
+	scu_enable(scu_base);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+	imx_smp_prepare();
+}
Then these functions could also be moved into the smp_scu file as generic
helpers that can be used by all similar platforms.
-- 
Regards,
Shawn
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help