ARM: tegra: Fix uniprocessor reset handler initialization
Scott Williams [Thu, 28 Jul 2011 03:10:06 +0000 (20:10 -0700)]
- For CONFIG_SMP kernels on systems that only report one CPU available,
  there is never a call to platform_smp_prepare_cpus() which means
  the reset handler would not get initialized. Invoke the reset handler
  initialization from smp_init_cpus() if there is only one CPU.
- For non-CONFIG_SMP kernels, the call to initialize the reset handler
  got accidentally dropped in the port to Linux 2.6.39. Invoke the
  reset handler initiazation from tegra_init_early() in this case.

Change-Id: I782faf84c89d4285aac26bfccb829f27878029de
Signed-off-by: Scott Williams <scwilliams@nvidia.com>
Signed-off-by: Dan Willemsen <dwillemsen@nvidia.com>

Rebase-Id: R9b35221571885a1620e0d7e19880b05a18c97233

arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/platsmp.c

index 5e3e993..00fd120 100644 (file)
@@ -324,6 +324,12 @@ void __init tegra_init_early(void)
 {
        arm_pm_restart = tegra_pm_restart;
        register_reboot_notifier(&tegra_reboot_notifier);
+#ifndef CONFIG_SMP
+       /* For SMP system, initializing the reset handler here is too
+          late. For non-SMP systems, the function that calls the reset
+          handler initializer is not called, so do it here for non-SMP. */
+       tegra_cpu_reset_handler_init();
+#endif
        tegra_init_fuse();
        tegra_gpio_resume_init();
        tegra_init_clock();
index 6cd9c61..ac33ef5 100644 (file)
@@ -256,6 +256,14 @@ void __init smp_init_cpus(void)
        for (i = 0; i < ncores; i++)
                set_cpu_possible(i, true);
 
+       /* If only one CPU is possible, platform_smp_prepare_cpus() will
+          never get called. We must therefore initialize the reset handler
+          here. If there is more than one CPU, we must wait until after
+          the cpu_present_mask has been updated with all present CPUs in
+          platform_smp_prepare_cpus() before initializing the reset handler. */
+       if (ncores == 1)
+               tegra_cpu_reset_handler_init();
+
        set_smp_cross_call(gic_raise_softirq);
 }
 
@@ -268,6 +276,9 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
        if (max_cpus == 1)
                tegra_all_cpus_booted = true;
 
+       /* If we're here, it means that more than one CPU was found by
+          smp_init_cpus() which also means that it did not initialize the
+          reset handler. Do it now before the secondary CPUs are started. */
        tegra_cpu_reset_handler_init();
        scu_enable(scu_base);
 }