From: lorenzo.pieralisi@arm.com (Lorenzo Pieralisi)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 07/12] arm64: psci: kill psci_power_state
Date: Mon, 11 May 2015 16:32:33 +0100 [thread overview]
Message-ID: <20150511153223.GA2942@red-moon> (raw)
In-Reply-To: <1431085004-32743-8-git-send-email-mark.rutland@arm.com>
On Fri, May 08, 2015 at 12:36:39PM +0100, Mark Rutland wrote:
> A PSCI 1.0 implementation may choose to use the new extended StateID
> format, the presence of which may be queried via the PSCI_FEATURES call.
> The layout of this new StateID format is incompatible with the existing
> format, and so to handle both we must abstract attempts to parse the
> fields.
>
> In preparation for PSCI 1.0 support, this patch introduces
> psci_power_state_loses_context and psci_power_state_is_valid functions
> to query information from a PSCI power state, which is no longer
> decomposed (and hence the pack/unpack functions are removed). As it is
> no longer decomposed, it is now passed round as an opaque u32 token.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
> arch/arm64/kernel/psci.c | 89 ++++++++++++++++++++----------------------------
> 1 file changed, 37 insertions(+), 52 deletions(-)
Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
> index 25e2610..185174e 100644
> --- a/arch/arm64/kernel/psci.c
> +++ b/arch/arm64/kernel/psci.c
> @@ -37,11 +37,19 @@
> #define PSCI_POWER_STATE_TYPE_STANDBY 0
> #define PSCI_POWER_STATE_TYPE_POWER_DOWN 1
>
> -struct psci_power_state {
> - u16 id;
> - u8 type;
> - u8 affinity_level;
> -};
> +static bool psci_power_state_loses_context(u32 state)
> +{
> + return !!(state & PSCI_0_2_POWER_STATE_TYPE_MASK);
> +}
> +
> +static bool psci_power_state_is_valid(u32 state)
> +{
> + const u32 valid_mask = PSCI_0_2_POWER_STATE_ID_MASK |
> + PSCI_0_2_POWER_STATE_TYPE_MASK |
> + PSCI_0_2_POWER_STATE_AFFL_MASK;
> +
> + return !(state & ~valid_mask);
> +}
>
> /*
> * The CPU any Trusted OS is resident on. The trusted OS may reject CPU_OFF
> @@ -57,9 +65,8 @@ static bool psci_tos_resident_on(int cpu)
> }
>
> struct psci_operations {
> - int (*cpu_suspend)(struct psci_power_state state,
> - unsigned long entry_point);
> - int (*cpu_off)(struct psci_power_state state);
> + int (*cpu_suspend)(u32 state, unsigned long entry_point);
> + int (*cpu_off)(u32 state);
> int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
> int (*migrate)(unsigned long cpuid);
> int (*affinity_info)(unsigned long target_affinity,
> @@ -84,7 +91,7 @@ enum psci_function {
> PSCI_FN_MAX,
> };
>
> -static DEFINE_PER_CPU_READ_MOSTLY(struct psci_power_state *, psci_power_state);
> +static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
>
> static u32 psci_function_id[PSCI_FN_MAX];
>
> @@ -104,53 +111,28 @@ static int psci_to_linux_errno(int errno)
> return -EINVAL;
> }
>
> -static u32 psci_power_state_pack(struct psci_power_state state)
> -{
> - return ((state.id << PSCI_0_2_POWER_STATE_ID_SHIFT)
> - & PSCI_0_2_POWER_STATE_ID_MASK) |
> - ((state.type << PSCI_0_2_POWER_STATE_TYPE_SHIFT)
> - & PSCI_0_2_POWER_STATE_TYPE_MASK) |
> - ((state.affinity_level << PSCI_0_2_POWER_STATE_AFFL_SHIFT)
> - & PSCI_0_2_POWER_STATE_AFFL_MASK);
> -}
> -
> -static void psci_power_state_unpack(u32 power_state,
> - struct psci_power_state *state)
> -{
> - state->id = (power_state & PSCI_0_2_POWER_STATE_ID_MASK) >>
> - PSCI_0_2_POWER_STATE_ID_SHIFT;
> - state->type = (power_state & PSCI_0_2_POWER_STATE_TYPE_MASK) >>
> - PSCI_0_2_POWER_STATE_TYPE_SHIFT;
> - state->affinity_level =
> - (power_state & PSCI_0_2_POWER_STATE_AFFL_MASK) >>
> - PSCI_0_2_POWER_STATE_AFFL_SHIFT;
> -}
> -
> static u32 psci_get_version(void)
> {
> return invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
> }
>
> -static int psci_cpu_suspend(struct psci_power_state state,
> - unsigned long entry_point)
> +static int psci_cpu_suspend(u32 state, 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, entry_point, 0);
> return psci_to_linux_errno(err);
> }
>
> -static int psci_cpu_off(struct psci_power_state state)
> +static int psci_cpu_off(u32 state)
> {
> int err;
> - u32 fn, power_state;
> + u32 fn;
>
> fn = psci_function_id[PSCI_FN_CPU_OFF];
> - power_state = psci_power_state_pack(state);
> - err = invoke_psci_fn(fn, power_state, 0, 0);
> + err = invoke_psci_fn(fn, state, 0, 0);
> return psci_to_linux_errno(err);
> }
>
> @@ -195,7 +177,7 @@ static int __maybe_unused cpu_psci_cpu_init_idle(struct device_node *cpu_node,
> unsigned int cpu)
> {
> int i, ret, count = 0;
> - struct psci_power_state *psci_states;
> + u32 *psci_states;
> struct device_node *state_node;
>
> /*
> @@ -220,13 +202,13 @@ static int __maybe_unused cpu_psci_cpu_init_idle(struct device_node *cpu_node,
> return -ENOMEM;
>
> for (i = 0; i < count; i++) {
> - u32 psci_power_state;
> + u32 state;
>
> state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
>
> ret = of_property_read_u32(state_node,
> "arm,psci-suspend-param",
> - &psci_power_state);
> + &state);
> if (ret) {
> pr_warn(" * %s missing arm,psci-suspend-param property\n",
> state_node->full_name);
> @@ -235,9 +217,13 @@ static int __maybe_unused cpu_psci_cpu_init_idle(struct device_node *cpu_node,
> }
>
> of_node_put(state_node);
> - pr_debug("psci-power-state %#x index %d\n", psci_power_state,
> - i);
> - psci_power_state_unpack(psci_power_state, &psci_states[i]);
> + pr_debug("psci-power-state %#x index %d\n", state, i);
> + if (!psci_power_state_is_valid(state)) {
> + pr_warn("Invalid PSCI power state %#x\n", state);
> + ret = -EINVAL;
> + goto free_mem;
> + }
> + psci_states[i] = state;
> }
> /* Idle states parsed correctly, initialize per-cpu pointer */
> per_cpu(psci_power_state, cpu) = psci_states;
> @@ -520,9 +506,8 @@ static void cpu_psci_cpu_die(unsigned int cpu)
> * There are no known implementations of PSCI actually using the
> * power state field, pass a sensible default for now.
> */
> - struct psci_power_state state = {
> - .type = PSCI_POWER_STATE_TYPE_POWER_DOWN,
> - };
> + u32 state = PSCI_POWER_STATE_TYPE_POWER_DOWN <<
> + PSCI_0_2_POWER_STATE_TYPE_SHIFT;
>
> ret = psci_ops.cpu_off(state);
>
> @@ -561,7 +546,7 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
>
> static int psci_suspend_finisher(unsigned long index)
> {
> - struct psci_power_state *state = __this_cpu_read(psci_power_state);
> + u32 *state = __this_cpu_read(psci_power_state);
>
> return psci_ops.cpu_suspend(state[index - 1],
> virt_to_phys(cpu_resume));
> @@ -570,7 +555,7 @@ static int psci_suspend_finisher(unsigned long index)
> static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index)
> {
> int ret;
> - struct psci_power_state *state = __this_cpu_read(psci_power_state);
> + u32 *state = __this_cpu_read(psci_power_state);
> /*
> * idle state index 0 corresponds to wfi, should never be called
> * from the cpu_suspend operations
> @@ -578,7 +563,7 @@ static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index)
> if (WARN_ON_ONCE(!index))
> return -EINVAL;
>
> - if (state[index - 1].type == PSCI_POWER_STATE_TYPE_STANDBY)
> + if (!psci_power_state_loses_context(state[index - 1]))
> ret = psci_ops.cpu_suspend(state[index - 1], 0);
> else
> ret = __cpu_suspend(index, psci_suspend_finisher);
> --
> 1.9.1
>
next prev parent reply other threads:[~2015-05-11 15:32 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-08 11:36 [PATCH 00/12] arm/arm64: Unify PSCI client support Mark Rutland
2015-05-08 11:36 ` [PATCH 01/12] arm/arm64: kvm: add missing PSCI include Mark Rutland
2015-05-12 14:07 ` Christoffer Dall
2015-05-08 11:36 ` [PATCH 02/12] arm64: smp_plat: add get_logical_index Mark Rutland
2015-05-08 11:36 ` [PATCH 03/12] arm64: smp: consistently use error codes Mark Rutland
2015-05-08 11:36 ` [PATCH 04/12] arm64: psci: remove unnecessary id indirection Mark Rutland
2015-05-08 11:36 ` [PATCH 05/12] arm64: psci: support unsigned return values Mark Rutland
2015-05-11 12:25 ` Lorenzo Pieralisi
2015-05-11 12:39 ` Mark Rutland
2015-05-08 11:36 ` [PATCH 06/12] arm64: psci: account for Trusted OS instances Mark Rutland
2015-05-13 14:22 ` Lorenzo Pieralisi
2015-05-18 10:04 ` Mark Rutland
2015-05-15 15:06 ` Ashwin Chaugule
2015-05-18 9:24 ` Mark Rutland
2015-05-08 11:36 ` [PATCH 07/12] arm64: psci: kill psci_power_state Mark Rutland
2015-05-11 15:32 ` Lorenzo Pieralisi [this message]
2015-05-08 11:36 ` [PATCH 08/12] arm64: psci: remove ACPI coupling Mark Rutland
2015-05-15 15:10 ` Ashwin Chaugule
2015-05-08 11:36 ` [PATCH 09/12] arm64: psci: factor invocation code to drivers Mark Rutland
2015-05-13 9:40 ` Mark Rutland
2015-05-08 11:36 ` [PATCH 10/12] drivers: psci: support native SMC{32,64} calls Mark Rutland
2015-05-08 11:36 ` [PATCH 11/12] ARM: migrate to common PSCI client code Mark Rutland
2015-05-15 15:41 ` Ashwin Chaugule
2015-05-15 15:43 ` Ashwin Chaugule
2015-05-18 9:46 ` Mark Rutland
2015-05-18 19:14 ` Ashwin Chaugule
2015-05-26 12:59 ` Mark Rutland
2015-05-08 11:36 ` [PATCH 12/12] MAINTAINERS: add PSCI entry Mark Rutland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150511153223.GA2942@red-moon \
--to=lorenzo.pieralisi@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).