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

Commit 00f68c3e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cpuidle: lpm-levels: Add Support for PSCI on 32bit"

parents f5a621ea cad2f807
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ struct psci_power_state {
};

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

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

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

struct psci_operations psci_ops;
#define PSCI_POWER_STATE_BIT	BIT(30)

static int (*invoke_psci_fn)(u32, u32, u32, u32);
typedef int (*psci_initcall_t)(const struct device_node *);
@@ -80,15 +82,14 @@ static int psci_get_version(void)
	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)
{
	int err;
	u32 fn, power_state;
	u32 fn;

	fn = psci_function_id[PSCI_FN_CPU_SUSPEND];
	power_state = psci_power_state_pack(state);
	err = invoke_psci_fn(fn, power_state, entry_point, 0);
	err = invoke_psci_fn(fn, state_id, entry_point, 0);
	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);
}

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
 * standard values.
+19 −1
Original line number Diff line number Diff line
@@ -810,10 +810,28 @@ bool psci_enter_sleep(struct lpm_cluster *cluster, int idx, bool from_idle)
		return success;
	}
}
#elif defined(CONFIG_ARM_PSCI)
bool psci_enter_sleep(struct lpm_cluster *cluster, int idx, bool from_idle)
{
	int affinity_level = 0;
	int state_id = get_cluster_id(cluster, &affinity_level);
	int power_state = PSCI_POWER_STATE(cluster->cpu->levels[idx].is_reset);

	affinity_level = PSCI_AFFINITY_LEVEL(affinity_level);
	if (!idx) {
		wfi();
		return 1;
	}

	state_id |= (power_state | affinity_level
				| cluster->cpu->levels[idx].psci_id);

	return !cpu_suspend(state_id);
}
#else
bool psci_enter_sleep(struct lpm_cluster *cluster, int idx, bool from_idle)
{
	WARN_ONCE(true, "PSCI cpu_suspend ops not supported on V7\n");
	WARN_ONCE(true, "PSCI cpu_suspend ops not supported\n");
	return false;
}
#endif