Ventana: KBC: Removing the KBC usage on ventana
[linux-2.6.git] / arch / arm / mach-tegra / platsmp.c
index a7b8191..582810c 100644 (file)
@@ -7,7 +7,7 @@
  *  Copyright (C) 2009 Palm
  *  All Rights Reserved
  *
- *  Copyright (C) 2010 NVIDIA Corporation
+ *  Copyright (C) 2010-2011 NVIDIA Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -49,17 +49,12 @@ const struct cpumask *const tegra_cpu_init_mask = to_cpumask(tegra_cpu_init_bits
 #define CPU_CLOCK(cpu) (0x1<<(8+cpu))
 #define CPU_RESET(cpu) (0x1111ul<<(cpu))
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-/* For Tegra2 use the software-written value of the reset register for status.*/
-#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET
-#else
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
 #define CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR \
        (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x34c)
 #define CAR_BOND_OUT_V \
        (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x390)
 #define CAR_BOND_OUT_V_CPU_G   (1<<0)
-#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS \
-       (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x470)
 #endif
 
 static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
@@ -83,9 +78,7 @@ static unsigned int available_cpus(void)
 
 static int is_g_cluster_available(unsigned int cpu)
 {
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-       return -EPERM;
-#else
+#ifdef CONFIG_TEGRA_CLUSTER_CONTROL
        u32 fuse_sku = readl(FUSE_SKU_DIRECT_CONFIG);
        u32 bond_out = readl(CAR_BOND_OUT_V);
 
@@ -101,6 +94,8 @@ static int is_g_cluster_available(unsigned int cpu)
         *        (e.g., low battery, over temperature, etc.). Add checks for
         *        these conditions. */
        return 0;
+#else
+       return -EPERM;
 #endif
 }
 
@@ -130,7 +125,7 @@ static int power_up_cpu(unsigned int cpu)
         * On first boot entry do not wait - go to direct ungate.
         */
        if (cpu_isset(cpu, tegra_cpu_init_map)) {
-               timeout = jiffies + HZ;
+               timeout = jiffies + 5;
                do {
                        if (is_cpu_powered(cpu))
                                goto remove_clamps;
@@ -141,7 +136,7 @@ static int power_up_cpu(unsigned int cpu)
        /* First boot or Flow controller did not work as expected. Try to
           directly toggle power gates. Error if direct power on also fails. */
        if (!is_cpu_powered(cpu)) {
-               ret = tegra_powergate_power_on(TEGRA_CPU_POWERGATE_ID(cpu));
+               ret = tegra_unpowergate_partition(TEGRA_CPU_POWERGATE_ID(cpu));
                if (ret)
                        goto fail;
 
@@ -193,6 +188,11 @@ int boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
        int status;
 
+       /* Avoid timer calibration on slave cpus. Use the value calibrated
+        * on master cpu. This reduces the bringup time for each slave cpu
+        * by around 260ms.
+        */
+       preset_lpj = loops_per_jiffy;
        if (is_lp_cluster()) {
                struct clk *cpu_clk, *cpu_g_clk;
 
@@ -261,6 +261,16 @@ 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();
+               tegra_all_cpus_booted = true;
+       }
+
        set_smp_cross_call(gic_raise_softirq);
 }
 
@@ -273,6 +283,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);
 }