Commit 0a5be743 authored by Catalin Marinas's avatar Catalin Marinas
Browse files

Merge tag 'arm64-suspend' of git://linux-arm.org/linux-2.6-lp into upstream

* tag 'arm64-suspend' of git://linux-arm.org/linux-2.6-lp:
  arm64: add CPU power management menu/entries
  arm64: kernel: add PM build infrastructure
  arm64: kernel: add CPU idle call
  arm64: enable generic clockevent broadcast
  arm64: kernel: implement HW breakpoints CPU PM notifier
  arm64: kernel: refactor code to install/uninstall breakpoints
  arm: kvm: implement CPU PM notifier
  arm64: kernel: implement fpsimd CPU PM notifier
  arm64: kernel: cpu_{suspend/resume} implementation
  arm64: kernel: suspend/resume registers save/restore
  arm64: kernel: build MPIDR_EL1 hash function data structure
  arm64: kernel: add MPIDR_EL1 accessors macros

Conflicts:
	arch/arm64/Kconfig
parents 6ac2104d 1307220d
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
 */

#include <linux/cpu.h>
#include <linux/cpu_pm.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/kvm_host.h>
@@ -853,6 +854,33 @@ static struct notifier_block hyp_init_cpu_nb = {
	.notifier_call = hyp_init_cpu_notify,
};

#ifdef CONFIG_CPU_PM
static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
				    unsigned long cmd,
				    void *v)
{
	if (cmd == CPU_PM_EXIT) {
		cpu_init_hyp_mode(NULL);
		return NOTIFY_OK;
	}

	return NOTIFY_DONE;
}

static struct notifier_block hyp_init_cpu_pm_nb = {
	.notifier_call = hyp_init_cpu_pm_notifier,
};

static void __init hyp_cpu_pm_init(void)
{
	cpu_pm_register_notifier(&hyp_init_cpu_pm_nb);
}
#else
static inline void hyp_cpu_pm_init(void)
{
}
#endif

/**
 * Inits Hyp-mode on all online CPUs
 */
@@ -1013,6 +1041,8 @@ int kvm_arch_init(void *opaque)
		goto out_err;
	}

	hyp_cpu_pm_init();

	kvm_coproc_table_init();
	return 0;
out_err:
+21 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ config ARM64
	def_bool y
	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
	select ARCH_USE_CMPXCHG_LOCKREF
	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
	select ARCH_WANT_OPTIONAL_GPIOLIB
	select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
	select ARCH_WANT_FRAME_POINTERS
@@ -11,8 +12,10 @@ config ARM64
	select BUILDTIME_EXTABLE_SORT
	select CLONE_BACKWARDS
	select COMMON_CLK
	select CPU_PM if (SUSPEND || CPU_IDLE)
	select DCACHE_WORD_ACCESS
	select GENERIC_CLOCKEVENTS
	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
	select GENERIC_IOMAP
	select GENERIC_IRQ_PROBE
	select GENERIC_IRQ_SHOW
@@ -280,6 +283,24 @@ config SYSVIPC_COMPAT

endmenu

menu "Power management options"

source "kernel/power/Kconfig"

config ARCH_SUSPEND_POSSIBLE
	def_bool y

config ARM64_CPU_SUSPEND
	def_bool PM_SLEEP

endmenu

menu "CPU Power Management"

source "drivers/cpuidle/Kconfig"

endmenu

source "net/Kconfig"

source "drivers/Kconfig"
+6 −0
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@ struct device_node;
 * 		from the cpu to be killed.
 * @cpu_die:	Makes a cpu leave the kernel. Must not fail. Called from the
 *		cpu being killed.
 * @cpu_suspend: Suspends a cpu and saves the required context. May fail owing
 *               to wrong parameters or error conditions. Called from the
 *               CPU being suspended. Must be called with IRQs disabled.
 */
struct cpu_operations {
	const char	*name;
@@ -50,6 +53,9 @@ struct cpu_operations {
	int		(*cpu_disable)(unsigned int cpu);
	void		(*cpu_die)(unsigned int cpu);
#endif
#ifdef CONFIG_ARM64_CPU_SUSPEND
	int		(*cpu_suspend)(unsigned long);
#endif
};

extern const struct cpu_operations *cpu_ops[NR_CPUS];
+10 −0
Original line number Diff line number Diff line
@@ -20,6 +20,16 @@

#define MPIDR_HWID_BITMASK	0xff00ffffff

#define MPIDR_LEVEL_BITS_SHIFT	3
#define MPIDR_LEVEL_BITS	(1 << MPIDR_LEVEL_BITS_SHIFT)
#define MPIDR_LEVEL_MASK	((1 << MPIDR_LEVEL_BITS) - 1)

#define MPIDR_LEVEL_SHIFT(level) \
	(((1 << level) >> 1) << MPIDR_LEVEL_BITS_SHIFT)

#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
	((mpidr >> MPIDR_LEVEL_SHIFT(level)) & MPIDR_LEVEL_MASK)

#define read_cpuid(reg) ({						\
	u64 __val;							\
	asm("mrs	%0, " #reg : "=r" (__val));			\
+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
#include <linux/threads.h>
#include <asm/irq.h>

#define NR_IPI	4
#define NR_IPI	5

typedef struct {
	unsigned int __softirq_pending;
Loading