diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-02 09:03:55 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-02 09:03:55 -0700 |
commit | a7726350e06401929eac0aa0677a5467106565fc (patch) | |
tree | e189513e5014bdfccd73a3af731a6b57733743fa /arch/arm/mach-tegra/platsmp.c | |
parent | 4d26aa305414dbb33b3c32fb205b68004cda8ffc (diff) | |
parent | afcf7924ecab726dab0227188783c4a40d9f0eec (diff) | |
download | blackbird-op-linux-a7726350e06401929eac0aa0677a5467106565fc.tar.gz blackbird-op-linux-a7726350e06401929eac0aa0677a5467106565fc.zip |
Merge tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC cleanup from Olof Johansson:
"Here is a collection of cleanup patches. Among the pieces that stand
out are:
- The deletion of h720x platforms
- Split of at91 non-dt platforms to their own Kconfig file to keep
them separate
- General cleanups and refactoring of i.MX and MXS platforms
- Some restructuring of clock tables for OMAP
- Convertion of PMC driver for Tegra to dt-only
- Some renames of sunxi -> sun4i (Allwinner A10)
- ... plus a bunch of other stuff that I haven't mentioned"
* tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (119 commits)
ARM: i.MX: remove unused ARCH_* configs
ARM i.MX53: remove platform ahci support
ARM: sunxi: Rework the restart code
irqchip: sunxi: Rename sunxi to sun4i
irqchip: sunxi: Make use of the IRQCHIP_DECLARE macro
clocksource: sunxi: Rename sunxi to sun4i
clocksource: sunxi: make use of CLKSRC_OF
clocksource: sunxi: Cleanup the timer code
ARM: at91: remove trailing semicolon from macros
ARM: at91/setup: fix trivial typos
ARM: EXYNOS: remove "config EXYNOS_DEV_DRM"
ARM: EXYNOS: change the name of USB ohci header
ARM: SAMSUNG: Remove unnecessary code for dma
ARM: S3C24XX: Remove unused GPIO drive strength register definitions
ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method
ARM: S3C24XX: Removed unneeded dependency on CPU_S3C2412
ARM: S3C24XX: Removed unneeded dependency on CPU_S3C2410
ARM: S3C24XX: Removed unneeded dependency on ARCH_S3C24XX for boards
ARM: SAMSUNG: Fix typo "CONFIG_SAMSUNG_DEV_RTC"
ARM: S5P64X0: Fix typo "CONFIG_S5P64X0_SETUP_SDHCI"
...
Diffstat (limited to 'arch/arm/mach-tegra/platsmp.c')
-rw-r--r-- | arch/arm/mach-tegra/platsmp.c | 118 |
1 files changed, 44 insertions, 74 deletions
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index e78d52d83acd..c31db797e199 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -18,7 +18,6 @@ #include <linux/jiffies.h> #include <linux/smp.h> #include <linux/io.h> -#include <linux/irqchip/arm-gic.h> #include <linux/clk/tegra.h> #include <asm/cacheflush.h> @@ -26,53 +25,58 @@ #include <asm/smp_scu.h> #include <asm/smp_plat.h> -#include <mach/powergate.h> - #include "fuse.h" #include "flowctrl.h" #include "reset.h" +#include "pmc.h" #include "common.h" #include "iomap.h" -extern void tegra_secondary_startup(void); - static cpumask_t tegra_cpu_init_mask; -#define EVP_CPU_RESET_VECTOR \ - (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) - static void __cpuinit tegra_secondary_init(unsigned int cpu) { - /* - * 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_secondary_init(0); - cpumask_set_cpu(cpu, &tegra_cpu_init_mask); } -static int tegra20_power_up_cpu(unsigned int cpu) + +static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle) { - /* Enable the CPU clock. */ - tegra_enable_cpu_clock(cpu); + cpu = cpu_logical_map(cpu); - /* Clear flow controller CSR. */ - flowctrl_write_cpu_csr(cpu, 0); + /* + * Force the CPU into reset. The CPU must remain in reset when + * the flow controller state is cleared (which will cause the + * flow controller to stop driving reset if the CPU has been + * power-gated via the flow controller). This will have no + * effect on first boot of the CPU since it should already be + * in reset. + */ + tegra_put_cpu_in_reset(cpu); + /* + * Unhalt the CPU. If the flow controller was used to + * power-gate the CPU this will cause the flow controller to + * stop driving reset. The CPU will remain in reset because the + * clock and reset block is now driving reset. + */ + flowctrl_write_cpu_halt(cpu, 0); + + tegra_enable_cpu_clock(cpu); + flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */ + tegra_cpu_out_of_reset(cpu); return 0; } -static int tegra30_power_up_cpu(unsigned int cpu) +static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle) { - int ret, pwrgateid; + int ret; unsigned long timeout; - pwrgateid = tegra_cpu_powergate_id(cpu); - if (pwrgateid < 0) - return pwrgateid; + cpu = cpu_logical_map(cpu); + tegra_put_cpu_in_reset(cpu); + flowctrl_write_cpu_halt(cpu, 0); /* * The power up sequence of cold boot CPU and warm boot CPU @@ -85,13 +89,13 @@ static int tegra30_power_up_cpu(unsigned int cpu) * the IO clamps. * For cold boot CPU, do not wait. After the cold boot CPU be * booted, it will run to tegra_secondary_init() and set - * tegra_cpu_init_mask which influences what tegra30_power_up_cpu() + * tegra_cpu_init_mask which influences what tegra30_boot_secondary() * next time around. */ if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { timeout = jiffies + msecs_to_jiffies(50); do { - if (tegra_powergate_is_powered(pwrgateid)) + if (tegra_pmc_cpu_is_powered(cpu)) goto remove_clamps; udelay(10); } while (time_before(jiffies, timeout)); @@ -103,14 +107,14 @@ static int tegra30_power_up_cpu(unsigned int cpu) * be un-gated by un-toggling the power gate register * manually. */ - if (!tegra_powergate_is_powered(pwrgateid)) { - ret = tegra_powergate_power_on(pwrgateid); + if (!tegra_pmc_cpu_is_powered(cpu)) { + ret = tegra_pmc_cpu_power_on(cpu); if (ret) return ret; /* Wait for the power to come up. */ timeout = jiffies + msecs_to_jiffies(100); - while (tegra_powergate_is_powered(pwrgateid)) { + while (tegra_pmc_cpu_is_powered(cpu)) { if (time_after(jiffies, timeout)) return -ETIMEDOUT; udelay(10); @@ -123,60 +127,26 @@ remove_clamps: udelay(10); /* Remove I/O clamps. */ - ret = tegra_powergate_remove_clamping(pwrgateid); + ret = tegra_pmc_cpu_remove_clamping(cpu); if (ret) return ret; udelay(10); - /* Clear flow controller CSR. */ - flowctrl_write_cpu_csr(cpu, 0); - + flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */ + tegra_cpu_out_of_reset(cpu); return 0; } -static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle) +static int __cpuinit tegra_boot_secondary(unsigned int cpu, + struct task_struct *idle) { - int status; - - cpu = cpu_logical_map(cpu); - - /* - * Force the CPU into reset. The CPU must remain in reset when the - * flow controller state is cleared (which will cause the flow - * controller to stop driving reset if the CPU has been power-gated - * via the flow controller). This will have no effect on first boot - * of the CPU since it should already be in reset. - */ - tegra_put_cpu_in_reset(cpu); - - /* - * Unhalt the CPU. If the flow controller was used to power-gate the - * CPU this will cause the flow controller to stop driving reset. - * The CPU will remain in reset because the clock and reset block - * is now driving reset. - */ - flowctrl_write_cpu_halt(cpu, 0); + if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) + return tegra20_boot_secondary(cpu, idle); + if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) + return tegra30_boot_secondary(cpu, idle); - switch (tegra_chip_id) { - case TEGRA20: - status = tegra20_power_up_cpu(cpu); - break; - case TEGRA30: - status = tegra30_power_up_cpu(cpu); - break; - default: - status = -EINVAL; - break; - } - - if (status) - goto done; - - /* Take the CPU out of reset. */ - tegra_cpu_out_of_reset(cpu); -done: - return status; + return -EINVAL; } static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) |