Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31653389 authored by Maulik Shah's avatar Maulik Shah
Browse files

arm: psci: Support for OS initiated scheme



Existing PSCI implementation supports platform coordinated means of low
power modes where cluster low power modes are aggregated at the platform
level. Adding support for OS initiated scheme, where OS is responsible
for selecting cluster low power modes based on last man determination. With
OS initiated scheme, the OS can make better cluster decisions based on
wakeup times of CPUs within a cluster.

To this effect, in OS initiated schemes, the composite state ID is computed
by the idle driver before calling into the cpu_suspend API. The PSCI driver
is modified to use the composite ID to distinguish between retention and
non-retention states.

Change-Id: I7a5e6f047c5e72d89ff7d4e5f8201bdcbfefa54d
Signed-off-by: default avatarMaulik Shah <mkshah@codeaurora.org>
parent 79ef7b34
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -24,7 +24,7 @@ struct psci_power_state {
};
};


struct psci_operations {
struct psci_operations {
	int (*cpu_suspend)(struct psci_power_state state,
	int (*cpu_suspend)(unsigned long state,
			   unsigned long entry_point);
			   unsigned long entry_point);
	int (*cpu_off)(struct psci_power_state state);
	int (*cpu_off)(struct psci_power_state state);
	int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
	int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
@@ -33,7 +33,7 @@ struct psci_operations {
			unsigned long lowest_affinity_level);
			unsigned long lowest_affinity_level);
	int (*migrate_info_type)(void);
	int (*migrate_info_type)(void);
};
};

int cpu_psci_cpu_suspend(unsigned long state_id);
extern struct psci_operations psci_ops;
extern struct psci_operations psci_ops;
extern struct smp_operations psci_smp_ops;
extern struct smp_operations psci_smp_ops;


+28 −4
Original line number Original line Diff line number Diff line
@@ -25,8 +25,10 @@
#include <asm/errno.h>
#include <asm/errno.h>
#include <asm/psci.h>
#include <asm/psci.h>
#include <asm/system_misc.h>
#include <asm/system_misc.h>
#include <asm/suspend.h>


struct psci_operations psci_ops;
struct psci_operations psci_ops;
#define PSCI_POWER_STATE_BIT	BIT(30)


static int (*invoke_psci_fn)(u32, u32, u32, u32);
static int (*invoke_psci_fn)(u32, u32, u32, u32);
typedef int (*psci_initcall_t)(const struct device_node *);
typedef int (*psci_initcall_t)(const struct device_node *);
@@ -80,15 +82,14 @@ static int psci_get_version(void)
	return err;
	return err;
}
}


static int psci_cpu_suspend(struct psci_power_state state,
static int psci_cpu_suspend(unsigned long  state_id,
			    unsigned long entry_point)
			    unsigned long entry_point)
{
{
	int err;
	int err;
	u32 fn, power_state;
	u32 fn;


	fn = psci_function_id[PSCI_FN_CPU_SUSPEND];
	fn = psci_function_id[PSCI_FN_CPU_SUSPEND];
	power_state = psci_power_state_pack(state);
	err = invoke_psci_fn(fn, state_id, entry_point, 0);
	err = invoke_psci_fn(fn, power_state, entry_point, 0);
	return psci_to_linux_errno(err);
	return psci_to_linux_errno(err);
}
}


@@ -176,6 +177,29 @@ static void psci_sys_poweroff(void)
	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
}
}


static int psci_suspend_finisher(unsigned long state_id)
{
	return psci_ops.cpu_suspend(state_id, virt_to_phys(cpu_resume));
}

/*
 * The PSCI changes are to support OS initiated low power mode where the
 * cluster mode aggregation happens in HLOS. In this case, the cpuidle
 * driver aggregating the cluster low power mode will provide the
 * composite stateID to be passed down to the PSCI layer.
 */
int cpu_psci_cpu_suspend(unsigned long state_id)
{
	if (WARN_ON_ONCE(!state_id))
		return -EINVAL;

	if (state_id & PSCI_POWER_STATE_BIT)
		return __cpu_suspend(state_id, psci_suspend_finisher);
	else
		return  psci_ops.cpu_suspend(state_id, 0);
}
EXPORT_SYMBOL(cpu_psci_cpu_suspend);

/*
/*
 * PSCI Function IDs for v0.2+ are well defined so use
 * PSCI Function IDs for v0.2+ are well defined so use
 * standard values.
 * standard values.