diff options
Diffstat (limited to 'arch/arm/common')
-rw-r--r-- | arch/arm/common/bL_switcher.c | 16 | ||||
-rw-r--r-- | arch/arm/common/mcpm_entry.c | 52 | ||||
-rw-r--r-- | arch/arm/common/timer-sp.c | 4 |
3 files changed, 57 insertions, 15 deletions
diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c index 490f3dced749..6eaddc47c43d 100644 --- a/arch/arm/common/bL_switcher.c +++ b/arch/arm/common/bL_switcher.c @@ -58,16 +58,6 @@ static int read_mpidr(void) } /* - * Get a global nanosecond time stamp for tracing. - */ -static s64 get_ns(void) -{ - struct timespec ts; - getnstimeofday(&ts); - return timespec_to_ns(&ts); -} - -/* * bL switcher core code. */ @@ -224,7 +214,7 @@ static int bL_switch_to(unsigned int new_cluster_id) */ local_irq_disable(); local_fiq_disable(); - trace_cpu_migrate_begin(get_ns(), ob_mpidr); + trace_cpu_migrate_begin(ktime_get_real_ns(), ob_mpidr); /* redirect GIC's SGIs to our counterpart */ gic_migrate_target(bL_gic_id[ib_cpu][ib_cluster]); @@ -267,7 +257,7 @@ static int bL_switch_to(unsigned int new_cluster_id) tdev->evtdev->next_event, 1); } - trace_cpu_migrate_finish(get_ns(), ib_mpidr); + trace_cpu_migrate_finish(ktime_get_real_ns(), ib_mpidr); local_fiq_enable(); local_irq_enable(); @@ -558,7 +548,7 @@ int bL_switcher_get_logical_index(u32 mpidr) static void bL_switcher_trace_trigger_cpu(void *__always_unused info) { - trace_cpu_migrate_current(get_ns(), read_mpidr()); + trace_cpu_migrate_current(ktime_get_real_ns(), read_mpidr()); } int bL_switcher_trace_trigger(void) diff --git a/arch/arm/common/mcpm_entry.c b/arch/arm/common/mcpm_entry.c index f91136ab447e..3c165fc2dce2 100644 --- a/arch/arm/common/mcpm_entry.c +++ b/arch/arm/common/mcpm_entry.c @@ -12,11 +12,13 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/irqflags.h> +#include <linux/cpu_pm.h> #include <asm/mcpm.h> #include <asm/cacheflush.h> #include <asm/idmap.h> #include <asm/cputype.h> +#include <asm/suspend.h> extern unsigned long mcpm_entry_vectors[MAX_NR_CLUSTERS][MAX_CPUS_PER_CLUSTER]; @@ -146,6 +148,56 @@ int mcpm_cpu_powered_up(void) return 0; } +#ifdef CONFIG_ARM_CPU_SUSPEND + +static int __init nocache_trampoline(unsigned long _arg) +{ + void (*cache_disable)(void) = (void *)_arg; + unsigned int mpidr = read_cpuid_mpidr(); + unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + phys_reset_t phys_reset; + + mcpm_set_entry_vector(cpu, cluster, cpu_resume); + setup_mm_for_reboot(); + + __mcpm_cpu_going_down(cpu, cluster); + BUG_ON(!__mcpm_outbound_enter_critical(cpu, cluster)); + cache_disable(); + __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN); + __mcpm_cpu_down(cpu, cluster); + + phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset); + phys_reset(virt_to_phys(mcpm_entry_point)); + BUG(); +} + +int __init mcpm_loopback(void (*cache_disable)(void)) +{ + int ret; + + /* + * We're going to soft-restart the current CPU through the + * low-level MCPM code by leveraging the suspend/resume + * infrastructure. Let's play it safe by using cpu_pm_enter() + * in case the CPU init code path resets the VFP or similar. + */ + local_irq_disable(); + local_fiq_disable(); + ret = cpu_pm_enter(); + if (!ret) { + ret = cpu_suspend((unsigned long)cache_disable, nocache_trampoline); + cpu_pm_exit(); + } + local_fiq_enable(); + local_irq_enable(); + if (ret) + pr_err("%s returned %d\n", __func__, ret); + return ret; +} + +#endif + struct sync_struct mcpm_sync; /* diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c index fd6bff0c5b96..19211324772f 100644 --- a/arch/arm/common/timer-sp.c +++ b/arch/arm/common/timer-sp.c @@ -233,13 +233,13 @@ static void __init sp804_of_init(struct device_node *np) if (IS_ERR(clk1)) clk1 = NULL; - /* Get the 2nd clock if the timer has 2 timer clocks */ + /* Get the 2nd clock if the timer has 3 timer clocks */ if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) { clk2 = of_clk_get(np, 1); if (IS_ERR(clk2)) { pr_err("sp804: %s clock not found: %d\n", np->name, (int)PTR_ERR(clk2)); - goto err; + clk2 = NULL; } } else clk2 = clk1; |