All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lina Iyer <lina.iyer@linaro.org>
To: ulf.hansson@linaro.org, khilman@kernel.org, rjw@rjwysocki.net,
	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org
Cc: geert@linux-m68k.org, k.kozlowski@samsung.com,
	msivasub@codeaurora.org, agross@codeaurora.org,
	sboyd@codeaurora.org, linux-arm-msm@vger.kernel.org,
	lorenzo.pieralisi@arm.com, ahaslam@baylibre.com,
	mtitinger@baylibre.com, Lina Iyer <lina.iyer@linaro.org>,
	Mark Rutland <mark.rutland@arm.com>
Subject: [RFC v2 09/12] drivers: firmware: psci: Allow OS Initiated suspend mode
Date: Fri, 12 Feb 2016 13:50:35 -0700	[thread overview]
Message-ID: <1455310238-8963-10-git-send-email-lina.iyer@linaro.org> (raw)
In-Reply-To: <1455310238-8963-1-git-send-email-lina.iyer@linaro.org>

PSCI firmware v1.0 onwards may support 2 different modes for
CPU_SUSPEND. Platform coordinated mode is the default and every firmware
should support it. The firmware shall also be the default mode.

With the kernel capable of deciding the state for CPU cluster and
coherency domains, the OS Initiated mode may now be used by the kernel,
provided the firmware supports it. SET_SUSPEND_MODE is a PSCI function
available on v1.0 onwards and can be used to set the mode in the
firmware.

Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 drivers/firmware/psci.c   | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/psci.h      |  2 ++
 include/uapi/linux/psci.h |  5 +++++
 3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index f25cd79..03c084e 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -49,12 +49,19 @@
  * require cooperation with a Trusted OS driver.
  */
 static int resident_cpu = -1;
+static bool has_osi_pd;
+static bool psci_suspend_mode_is_osi;
 
 bool psci_tos_resident_on(int cpu)
 {
 	return cpu == resident_cpu;
 }
 
+bool psci_has_osi_pd_support(void)
+{
+	return has_osi_pd;
+}
+
 struct psci_operations psci_ops;
 
 typedef unsigned long (psci_fn)(unsigned long, unsigned long,
@@ -250,6 +257,26 @@ static int psci_system_suspend(unsigned long unused)
 			      virt_to_phys(cpu_resume), 0, 0);
 }
 
+int psci_set_suspend_mode_osi(bool enable)
+{
+	int ret;
+	int mode;
+
+	if (enable && !psci_has_osi_pd_support())
+		return -ENODEV;
+
+	if (enable == psci_suspend_mode_is_osi)
+		return 0;
+
+	mode = enable ? PSCI_1_0_SUSPEND_MODE_OSI : PSCI_1_0_SUSPEND_MODE_PC;
+	ret = invoke_psci_fn(PSCI_FN_NATIVE(1_0, SET_SUSPEND_MODE),
+			     mode, 0, 0);
+	if (!ret)
+		psci_suspend_mode_is_osi = enable;
+
+	return psci_to_linux_errno(ret);
+}
+
 static int psci_system_suspend_enter(suspend_state_t state)
 {
 	return cpu_suspend(0, psci_system_suspend);
@@ -443,10 +470,26 @@ out_put_node:
 	return err;
 }
 
+static int __init psci_1_0_init(struct device_node *np)
+{
+	int ret;
+
+	ret = psci_0_2_init(np);
+	if (ret)
+		return ret;
+
+	/* Check if PSCI OSI mode is available */
+	ret = psci_features(PSCI_FN_NATIVE(0_2, CPU_SUSPEND));
+	if (ret & PSCI_1_0_OS_INITIATED)
+		has_osi_pd = true;
+
+	return 0;
+}
+
 static const struct of_device_id const psci_of_match[] __initconst = {
 	{ .compatible = "arm,psci",	.data = psci_0_1_init},
 	{ .compatible = "arm,psci-0.2",	.data = psci_0_2_init},
-	{ .compatible = "arm,psci-1.0",	.data = psci_0_2_init},
+	{ .compatible = "arm,psci-1.0",	.data = psci_1_0_init},
 	{},
 };
 
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 12c4865..deae633 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -23,6 +23,8 @@
 bool psci_tos_resident_on(int cpu);
 bool psci_power_state_loses_context(u32 state);
 bool psci_power_state_is_valid(u32 state);
+bool psci_has_osi_pd_support(void);
+int psci_set_suspend_mode_osi(bool enable);
 
 struct psci_operations {
 	int (*cpu_suspend)(u32 state, unsigned long entry_point);
diff --git a/include/uapi/linux/psci.h b/include/uapi/linux/psci.h
index 3d7a0fc..eaab6e3 100644
--- a/include/uapi/linux/psci.h
+++ b/include/uapi/linux/psci.h
@@ -50,6 +50,7 @@
 #define PSCI_1_0_FN_SYSTEM_SUSPEND		PSCI_0_2_FN(14)
 
 #define PSCI_1_0_FN64_SYSTEM_SUSPEND		PSCI_0_2_FN64(14)
+#define PSCI_1_0_FN64_SET_SUSPEND_MODE		PSCI_0_2_FN64(15)
 
 /* PSCI v0.2 power state encoding for CPU_SUSPEND function */
 #define PSCI_0_2_POWER_STATE_ID_MASK		0xffff
@@ -93,6 +94,10 @@
 #define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK	\
 			(0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT)
 
+#define PSCI_1_0_OS_INITIATED			BIT(0)
+#define PSCI_1_0_SUSPEND_MODE_PC		0
+#define PSCI_1_0_SUSPEND_MODE_OSI		1
+
 /* PSCI return values (inclusive of all PSCI versions) */
 #define PSCI_RET_SUCCESS			0
 #define PSCI_RET_NOT_SUPPORTED			-1
-- 
2.1.4

WARNING: multiple messages have this Message-ID (diff)
From: lina.iyer@linaro.org (Lina Iyer)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC v2 09/12] drivers: firmware: psci: Allow OS Initiated suspend mode
Date: Fri, 12 Feb 2016 13:50:35 -0700	[thread overview]
Message-ID: <1455310238-8963-10-git-send-email-lina.iyer@linaro.org> (raw)
In-Reply-To: <1455310238-8963-1-git-send-email-lina.iyer@linaro.org>

PSCI firmware v1.0 onwards may support 2 different modes for
CPU_SUSPEND. Platform coordinated mode is the default and every firmware
should support it. The firmware shall also be the default mode.

With the kernel capable of deciding the state for CPU cluster and
coherency domains, the OS Initiated mode may now be used by the kernel,
provided the firmware supports it. SET_SUSPEND_MODE is a PSCI function
available on v1.0 onwards and can be used to set the mode in the
firmware.

Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 drivers/firmware/psci.c   | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/psci.h      |  2 ++
 include/uapi/linux/psci.h |  5 +++++
 3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index f25cd79..03c084e 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -49,12 +49,19 @@
  * require cooperation with a Trusted OS driver.
  */
 static int resident_cpu = -1;
+static bool has_osi_pd;
+static bool psci_suspend_mode_is_osi;
 
 bool psci_tos_resident_on(int cpu)
 {
 	return cpu == resident_cpu;
 }
 
+bool psci_has_osi_pd_support(void)
+{
+	return has_osi_pd;
+}
+
 struct psci_operations psci_ops;
 
 typedef unsigned long (psci_fn)(unsigned long, unsigned long,
@@ -250,6 +257,26 @@ static int psci_system_suspend(unsigned long unused)
 			      virt_to_phys(cpu_resume), 0, 0);
 }
 
+int psci_set_suspend_mode_osi(bool enable)
+{
+	int ret;
+	int mode;
+
+	if (enable && !psci_has_osi_pd_support())
+		return -ENODEV;
+
+	if (enable == psci_suspend_mode_is_osi)
+		return 0;
+
+	mode = enable ? PSCI_1_0_SUSPEND_MODE_OSI : PSCI_1_0_SUSPEND_MODE_PC;
+	ret = invoke_psci_fn(PSCI_FN_NATIVE(1_0, SET_SUSPEND_MODE),
+			     mode, 0, 0);
+	if (!ret)
+		psci_suspend_mode_is_osi = enable;
+
+	return psci_to_linux_errno(ret);
+}
+
 static int psci_system_suspend_enter(suspend_state_t state)
 {
 	return cpu_suspend(0, psci_system_suspend);
@@ -443,10 +470,26 @@ out_put_node:
 	return err;
 }
 
+static int __init psci_1_0_init(struct device_node *np)
+{
+	int ret;
+
+	ret = psci_0_2_init(np);
+	if (ret)
+		return ret;
+
+	/* Check if PSCI OSI mode is available */
+	ret = psci_features(PSCI_FN_NATIVE(0_2, CPU_SUSPEND));
+	if (ret & PSCI_1_0_OS_INITIATED)
+		has_osi_pd = true;
+
+	return 0;
+}
+
 static const struct of_device_id const psci_of_match[] __initconst = {
 	{ .compatible = "arm,psci",	.data = psci_0_1_init},
 	{ .compatible = "arm,psci-0.2",	.data = psci_0_2_init},
-	{ .compatible = "arm,psci-1.0",	.data = psci_0_2_init},
+	{ .compatible = "arm,psci-1.0",	.data = psci_1_0_init},
 	{},
 };
 
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 12c4865..deae633 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -23,6 +23,8 @@
 bool psci_tos_resident_on(int cpu);
 bool psci_power_state_loses_context(u32 state);
 bool psci_power_state_is_valid(u32 state);
+bool psci_has_osi_pd_support(void);
+int psci_set_suspend_mode_osi(bool enable);
 
 struct psci_operations {
 	int (*cpu_suspend)(u32 state, unsigned long entry_point);
diff --git a/include/uapi/linux/psci.h b/include/uapi/linux/psci.h
index 3d7a0fc..eaab6e3 100644
--- a/include/uapi/linux/psci.h
+++ b/include/uapi/linux/psci.h
@@ -50,6 +50,7 @@
 #define PSCI_1_0_FN_SYSTEM_SUSPEND		PSCI_0_2_FN(14)
 
 #define PSCI_1_0_FN64_SYSTEM_SUSPEND		PSCI_0_2_FN64(14)
+#define PSCI_1_0_FN64_SET_SUSPEND_MODE		PSCI_0_2_FN64(15)
 
 /* PSCI v0.2 power state encoding for CPU_SUSPEND function */
 #define PSCI_0_2_POWER_STATE_ID_MASK		0xffff
@@ -93,6 +94,10 @@
 #define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK	\
 			(0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT)
 
+#define PSCI_1_0_OS_INITIATED			BIT(0)
+#define PSCI_1_0_SUSPEND_MODE_PC		0
+#define PSCI_1_0_SUSPEND_MODE_OSI		1
+
 /* PSCI return values (inclusive of all PSCI versions) */
 #define PSCI_RET_SUCCESS			0
 #define PSCI_RET_NOT_SUPPORTED			-1
-- 
2.1.4

  parent reply	other threads:[~2016-02-12 20:51 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-12 20:50 [RFC v2 00/12] PM: SoC idle support using PM domains Lina Iyer
2016-02-12 20:50 ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 01/12] PM / Domains: Abstract genpd locking Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 18:08   ` Stephen Boyd
2016-02-26 18:08     ` Stephen Boyd
2016-03-01 16:55     ` Lina Iyer
2016-03-01 16:55       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 02/12] PM / Domains: Support IRQ safe PM domains Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 18:17   ` Stephen Boyd
2016-02-26 18:17     ` Stephen Boyd
2016-03-01 17:44     ` Lina Iyer
2016-03-01 17:44       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 03/12] PM / cpu_domains: Setup PM domains for CPUs/clusters Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-17 23:38   ` Lina Iyer
2016-02-17 23:38     ` Lina Iyer
2016-02-18 17:29   ` [BUG FIX] PM / cpu_domains: Check for NULL callbacks Lina Iyer
2016-02-18 17:29     ` Lina Iyer
2016-02-18 17:46     ` Rafael J. Wysocki
2016-02-18 17:46       ` Rafael J. Wysocki
2016-02-18 22:51       ` Lina Iyer
2016-02-18 22:51         ` Lina Iyer
2016-02-26 19:10   ` [RFC v2 03/12] PM / cpu_domains: Setup PM domains for CPUs/clusters Stephen Boyd
2016-02-26 19:10     ` Stephen Boyd
2016-03-01 18:00     ` Lina Iyer
2016-03-01 18:00       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 04/12] ARM: cpuidle: Add runtime PM support for CPUs Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 18:24   ` Stephen Boyd
2016-02-26 18:24     ` Stephen Boyd
2016-03-01 18:36     ` Lina Iyer
2016-03-01 18:36       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 05/12] timer: Export next wake up of a CPU Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 06/12] PM / cpu_domains: Record CPUs that are part of the domain Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 19:20   ` Stephen Boyd
2016-02-26 19:20     ` Stephen Boyd
2016-03-01 19:24     ` Lina Iyer
2016-03-01 19:24       ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 07/12] PM / cpu_domains: Add PM Domain governor for CPUs Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 19:33   ` Stephen Boyd
2016-02-26 19:33     ` Stephen Boyd
2016-03-01 19:32     ` Lina Iyer
2016-03-01 19:32       ` Lina Iyer
2016-03-01 19:35       ` Stephen Boyd
2016-03-01 19:35         ` Stephen Boyd
2016-02-12 20:50 ` [RFC v2 08/12] Documentation / cpu_domains: Describe CPU PM domains setup and governor Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 19:43   ` Stephen Boyd
2016-02-26 19:43     ` Stephen Boyd
2016-03-01 19:36     ` Lina Iyer
2016-03-01 19:36       ` Lina Iyer
2016-02-12 20:50 ` Lina Iyer [this message]
2016-02-12 20:50   ` [RFC v2 09/12] drivers: firmware: psci: Allow OS Initiated suspend mode Lina Iyer
2016-02-12 20:50 ` [RFC v2 10/12] ARM64: psci: Support cluster idle states for OS-Initiated Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 11/12] ARM64: dts: Add PSCI cpuidle support for MSM8916 Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-12 20:50 ` [RFC v2 12/12] ARM64: dts: Define CPU power domain " Lina Iyer
2016-02-12 20:50   ` Lina Iyer
2016-02-26 19:50   ` Stephen Boyd
2016-02-26 19:50     ` Stephen Boyd
2016-03-01 19:41     ` Lina Iyer
2016-03-01 19:41       ` Lina Iyer

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=1455310238-8963-10-git-send-email-lina.iyer@linaro.org \
    --to=lina.iyer@linaro.org \
    --cc=agross@codeaurora.org \
    --cc=ahaslam@baylibre.com \
    --cc=geert@linux-m68k.org \
    --cc=k.kozlowski@samsung.com \
    --cc=khilman@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=msivasub@codeaurora.org \
    --cc=mtitinger@baylibre.com \
    --cc=rjw@rjwysocki.net \
    --cc=sboyd@codeaurora.org \
    --cc=ulf.hansson@linaro.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.