From patchwork Wed Jul 8 17:16:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Pieralisi X-Patchwork-Id: 6750171 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 89CCFC05AC for ; Wed, 8 Jul 2015 17:19:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 77A5F2060D for ; Wed, 8 Jul 2015 17:19:38 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7A1A02060C for ; Wed, 8 Jul 2015 17:19:37 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZCsy4-0008U1-Bw; Wed, 08 Jul 2015 17:17:08 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZCsxj-000859-AS for linux-arm-kernel@lists.infradead.org; Wed, 08 Jul 2015 17:16:47 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 443DA493; Wed, 8 Jul 2015 10:16:54 -0700 (PDT) Received: from red-moon.cambridge.arm.com (red-moon.cambridge.arm.com [10.1.203.137]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9D8703F317; Wed, 8 Jul 2015 10:16:26 -0700 (PDT) From: Lorenzo Pieralisi To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 4/5] drivers: firmware: psci: add extended stateid power_state support Date: Wed, 8 Jul 2015 18:16:50 +0100 Message-Id: <1436375811-10529-5-git-send-email-lorenzo.pieralisi@arm.com> X-Mailer: git-send-email 2.2.1 In-Reply-To: <1436375811-10529-1-git-send-email-lorenzo.pieralisi@arm.com> References: <1436375811-10529-1-git-send-email-lorenzo.pieralisi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150708_101647_374021_CB3BDBFC X-CRM114-Status: GOOD ( 13.24 ) X-Spam-Score: -7.6 (-------) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Jisheng Zhang , Lorenzo Pieralisi , arm@kernel.org, Catalin Marinas , Will Deacon , Ashwin Chaugule , Sudeep Holla MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP PSCI v1.0 augmented the power_state parameter format specification (extended stateid) and introduced a way to probe it through the PSCI_FEATURES interface. This patch implements code that detects the power_state format at run-time through the PSCI_FEATURES interface, so that the power_state argument can be properly detected and validated in the kernel according to the information provided through firmware. Signed-off-by: Lorenzo Pieralisi Cc: Mark Rutland --- drivers/firmware/psci.c | 34 ++++++++++++++++++++++++++++++++-- include/uapi/linux/psci.h | 12 ++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index 24ef3a8..bd2ba5b 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -75,14 +75,34 @@ static u32 psci_function_id[PSCI_FN_MAX]; PSCI_0_2_POWER_STATE_TYPE_MASK | \ PSCI_0_2_POWER_STATE_AFFL_MASK) +#define PSCI_1_0_EXT_POWER_STATE_MASK \ + (PSCI_1_0_EXT_POWER_STATE_ID_MASK | \ + PSCI_1_0_EXT_POWER_STATE_TYPE_MASK) + +static u32 psci_cpu_suspend_feature; + +static inline bool psci_has_ext_power_state(void) +{ + return psci_cpu_suspend_feature & + PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK; +} + bool psci_power_state_loses_context(u32 state) { - return state & PSCI_0_2_POWER_STATE_TYPE_MASK; + const u32 mask = psci_has_ext_power_state() ? + PSCI_1_0_EXT_POWER_STATE_TYPE_MASK : + PSCI_0_2_POWER_STATE_TYPE_MASK; + + return state & mask; } bool psci_power_state_is_valid(u32 state) { - return !(state & ~PSCI_0_2_POWER_STATE_MASK); + const u32 valid_mask = psci_has_ext_power_state() ? + PSCI_1_0_EXT_POWER_STATE_MASK : + PSCI_0_2_POWER_STATE_MASK; + + return !(state & ~valid_mask); } static int psci_to_linux_errno(int errno) @@ -203,6 +223,14 @@ static int __init psci_features(u32 psci_func_id) psci_func_id, 0, 0); } +static void __init psci_init_cpu_suspend(void) +{ + int feature = psci_features(psci_function_id[PSCI_FN_CPU_SUSPEND]); + + if (feature != PSCI_RET_NOT_SUPPORTED) + psci_cpu_suspend_feature = feature; +} + /* * Detect the presence of a resident Trusted OS which may cause CPU_OFF to * return DENIED (which would be fatal). @@ -287,6 +315,8 @@ static int __init psci_probe(void) psci_init_migrate(); + psci_init_cpu_suspend(); + return 0; } diff --git a/include/uapi/linux/psci.h b/include/uapi/linux/psci.h index 187b828d..0a9485f 100644 --- a/include/uapi/linux/psci.h +++ b/include/uapi/linux/psci.h @@ -58,6 +58,13 @@ #define PSCI_0_2_POWER_STATE_AFFL_MASK \ (0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) +/* PSCI extended power state encoding for CPU_SUSPEND function */ +#define PSCI_1_0_EXT_POWER_STATE_ID_MASK 0xfffffff +#define PSCI_1_0_EXT_POWER_STATE_ID_SHIFT 0 +#define PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT 30 +#define PSCI_1_0_EXT_POWER_STATE_TYPE_MASK \ + (0x1 << PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT) + /* PSCI v0.2 affinity level state returned by AFFINITY_INFO */ #define PSCI_0_2_AFFINITY_LEVEL_ON 0 #define PSCI_0_2_AFFINITY_LEVEL_OFF 1 @@ -78,6 +85,11 @@ #define PSCI_VERSION_MINOR(ver) \ ((ver) & PSCI_VERSION_MINOR_MASK) +/* PSCI features decoding (>=1.0) */ +#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1 +#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK \ + (0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT) + /* PSCI return values (inclusive of all PSCI versions) */ #define PSCI_RET_SUCCESS 0 #define PSCI_RET_NOT_SUPPORTED -1