linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/3] PSCI v0.2 support and DT bindings
@ 2014-03-27 21:23 Ashwin Chaugule
  2014-03-27 21:23 ` [PATCH v3 1/3] PSCI: Add initial support for PSCIv0.2 functions Ashwin Chaugule
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Ashwin Chaugule @ 2014-03-27 21:23 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds some new functions introduced by the PSCI v0.2 spec.
It also adds DT bindings to differentiate between PSCI v0.1 and v0.2 and
appropriately selects the Function IDs. The third patch makes use of a
new function, AFFINITY_INFO, added by PSCI v0.2 to ensure that CPU's
killed after CPU_OFF are actually offlined.

Changes in v3:
        -       Roll up common functionality for getting conduit method.
        -       Remove #defines for ARM32 and ARM64 in uapi/linux/psci.h
        -       Remove functions not supported by PSCI v0.1
        -       Misc cleanups.
        -       Add PSCI_AFFINITY_INFO return types in uapi header.
        -       Changed function names for PSCI v0.1 and PSCI v0.2
        -       Added copyright info to uapi header.
        -       Fixed args to affinity_info call.
        -       Fix typo in psci_init definition when PSCI is not defined.

Changes in v2:

        -       Add AFFINITY_INFO and MIGRATE_INFO_TYPE functions.
        -       Add binding Documentation.
        -       Add function to get PSCI version.
        -       Add common #defines in uapi/linux/psci.h
        -       Implement cpu_kill and check if CPU is dead via AFFINITY_INFO.
        -       Misc cleanups.

Changes in v1:

        -       Add new binding "arm, psci-0.2"
        -       Separate conduit and PSCI function assignment methods.


Ashwin Chaugule (3):
  PSCI: Add initial support for PSCIv0.2 functions
  Documentation: devicetree: Add new binding for PSCIv0.2
  ARM: Check if a CPU has gone offline

 Documentation/devicetree/bindings/arm/psci.txt |  35 +++++-
 arch/arm/include/asm/psci.h                    |   7 +-
 arch/arm/kernel/psci.c                         | 151 ++++++++++++++++++++----
 arch/arm/kernel/psci_smp.c                     |  21 ++++
 arch/arm64/kernel/psci.c                       | 154 +++++++++++++++++++++----
 include/uapi/linux/psci.h                      |  45 ++++++++
 6 files changed, 367 insertions(+), 46 deletions(-)
 create mode 100644 include/uapi/linux/psci.h

-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v3 1/3] PSCI: Add initial support for PSCIv0.2 functions
  2014-03-27 21:23 [PATCH v3 0/3] PSCI v0.2 support and DT bindings Ashwin Chaugule
@ 2014-03-27 21:23 ` Ashwin Chaugule
  2014-03-28 13:54   ` Rob Herring
  2014-03-27 21:23 ` [PATCH v3 2/3] Documentation: devicetree: Add new binding for PSCIv0.2 Ashwin Chaugule
  2014-03-27 21:23 ` [PATCH v3 3/3] ARM: Check if a CPU has gone offline Ashwin Chaugule
  2 siblings, 1 reply; 8+ messages in thread
From: Ashwin Chaugule @ 2014-03-27 21:23 UTC (permalink / raw)
  To: linux-arm-kernel

The PSCIv0.2 spec defines standard values of function IDs
and introduces a few new functions. Detect version of PSCI
and appropriately select the right PSCI functions.

Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
---
 arch/arm/include/asm/psci.h |   7 +-
 arch/arm/kernel/psci.c      | 151 +++++++++++++++++++++++++++++++++++++------
 arch/arm64/kernel/psci.c    | 154 +++++++++++++++++++++++++++++++++++++-------
 include/uapi/linux/psci.h   |  40 ++++++++++++
 4 files changed, 307 insertions(+), 45 deletions(-)
 create mode 100644 include/uapi/linux/psci.h

diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
index c4ae171..b93e34a 100644
--- a/arch/arm/include/asm/psci.h
+++ b/arch/arm/include/asm/psci.h
@@ -29,16 +29,19 @@ struct psci_operations {
 	int (*cpu_off)(struct psci_power_state state);
 	int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
 	int (*migrate)(unsigned long cpuid);
+	int (*affinity_info)(unsigned long target_affinity,
+			unsigned long lowest_affinity_level);
+	int (*migrate_info_type)(void);
 };
 
 extern struct psci_operations psci_ops;
 extern struct smp_operations psci_smp_ops;
 
 #ifdef CONFIG_ARM_PSCI
-void psci_init(void);
+int psci_init(void);
 bool psci_smp_available(void);
 #else
-static inline void psci_init(void) { }
+static inline int psci_init(void) { }
 static inline bool psci_smp_available(void) { return false; }
 #endif
 
diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c
index 4693188..e7cc62e 100644
--- a/arch/arm/kernel/psci.c
+++ b/arch/arm/kernel/psci.c
@@ -17,6 +17,7 @@
 
 #include <linux/init.h>
 #include <linux/of.h>
+#include <uapi/linux/psci.h>
 
 #include <asm/compiler.h>
 #include <asm/errno.h>
@@ -27,22 +28,20 @@
 struct psci_operations psci_ops;
 
 static int (*invoke_psci_fn)(u32, u32, u32, u32);
+typedef int (*psci_initcall_t)(const struct device_node *);
 
 enum psci_function {
 	PSCI_FN_CPU_SUSPEND,
 	PSCI_FN_CPU_ON,
 	PSCI_FN_CPU_OFF,
 	PSCI_FN_MIGRATE,
+	PSCI_FN_AFFINITY_INFO,
+	PSCI_FN_MIGRATE_INFO_TYPE,
 	PSCI_FN_MAX,
 };
 
 static u32 psci_function_id[PSCI_FN_MAX];
 
-#define PSCI_RET_SUCCESS		0
-#define PSCI_RET_EOPNOTSUPP		-1
-#define PSCI_RET_EINVAL			-2
-#define PSCI_RET_EPERM			-3
-
 static int psci_to_linux_errno(int errno)
 {
 	switch (errno) {
@@ -110,6 +109,21 @@ static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1,
 	return function_id;
 }
 
+#define PSCI_VER_MAJOR_MASK		0xffff0000
+#define PSCI_VER_MINOR_MASK		0x0000ffff
+#define PSCI_VER_MAJOR_SHIFT	16
+#define PSCI_VER_MAJOR(ver)		\
+	((ver & PSCI_VER_MAJOR_MASK) >> PSCI_VER_MAJOR_SHIFT)
+#define PSCI_VER_MINOR(ver)		(ver & PSCI_VER_MINOR_MASK)
+
+static int psci_get_version(void)
+{
+	int err;
+
+	err = invoke_psci_fn(PSCI_ID_VERSION, 0, 0, 0);
+	return err;
+}
+
 static int psci_cpu_suspend(struct psci_power_state state,
 			    unsigned long entry_point)
 {
@@ -153,26 +167,36 @@ static int psci_migrate(unsigned long cpuid)
 	return psci_to_linux_errno(err);
 }
 
-static const struct of_device_id psci_of_match[] __initconst = {
-	{ .compatible = "arm,psci",	},
-	{},
-};
+static int psci_affinity_info(unsigned long target_affinity,
+		unsigned long lowest_affinity_level)
+{
+	int err;
+	u32 fn;
 
-void __init psci_init(void)
+	fn = psci_function_id[PSCI_FN_AFFINITY_INFO];
+	err = invoke_psci_fn(fn, target_affinity, lowest_affinity_level, 0);
+	return err;
+}
+
+static int psci_migrate_info_type(void)
 {
-	struct device_node *np;
-	const char *method;
-	u32 id;
+	int err;
+	u32 fn;
 
-	np = of_find_matching_node(NULL, psci_of_match);
-	if (!np)
-		return;
+	fn = psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE];
+	err = invoke_psci_fn(fn, 0, 0, 0);
+	return err;
+}
 
-	pr_info("probing function IDs from device-tree\n");
+static int get_set_conduit_method(struct device_node *np)
+{
+	const char *method;
+
+	pr_info("probing for conduit method from DT.\n");
 
 	if (of_property_read_string(np, "method", &method)) {
-		pr_warning("missing \"method\" property\n");
-		goto out_put_node;
+		pr_warn("missing \"method\" property\n");
+		return -ENXIO;
 	}
 
 	if (!strcmp("hvc", method)) {
@@ -180,10 +204,75 @@ void __init psci_init(void)
 	} else if (!strcmp("smc", method)) {
 		invoke_psci_fn = __invoke_psci_fn_smc;
 	} else {
-		pr_warning("invalid \"method\" property: %s\n", method);
+		pr_warn("invalid \"method\" property: %s\n", method);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ * PSCI Function IDs for v0.2+ are well defined so use
+ * standard values.
+ */
+static int psci_0_2_init(struct device_node *np)
+{
+	int err, ver;
+
+	err = get_set_conduit_method(np);
+
+	if (err)
+		goto out_put_node;
+
+	ver = psci_get_version();
+
+	pr_info("PSCIv%d.%d detected in firmware.\n", PSCI_VER_MAJOR(ver),
+			PSCI_VER_MINOR(ver));
+
+	if (PSCI_VER_MAJOR(ver) == 0 && PSCI_VER_MINOR(ver) < 2) {
+		err = -EINVAL;
+		pr_err("Conflicting PSCI version detected.\n");
 		goto out_put_node;
 	}
 
+	pr_info("Using standard PSCI v0.2 function IDs\n");
+	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_ID_CPU_SUSPEND_32;
+	psci_ops.cpu_suspend = psci_cpu_suspend;
+
+	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_ID_CPU_OFF;
+	psci_ops.cpu_off = psci_cpu_off;
+
+	psci_function_id[PSCI_FN_CPU_ON] = PSCI_ID_CPU_ON_32;
+	psci_ops.cpu_on = psci_cpu_on;
+
+	psci_function_id[PSCI_FN_MIGRATE] = PSCI_ID_CPU_MIGRATE_32;
+	psci_ops.migrate = psci_migrate;
+
+	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_ID_AFFINITY_INFO_32;
+	psci_ops.affinity_info = psci_affinity_info;
+
+	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] = PSCI_ID_MIGRATE_INFO_TYPE;
+	psci_ops.migrate_info_type = psci_migrate_info_type;
+
+out_put_node:
+	of_node_put(np);
+	return err;
+}
+
+/*
+ * PSCI < v0.2 get PSCI Function IDs via DT.
+ */
+static int psci_0_1_init(struct device_node *np)
+{
+	u32 id;
+	int err;
+
+	err = get_set_conduit_method(np);
+
+	if (err)
+		goto out_put_node;
+
+	pr_info("Using PSCI v0.1 Function IDs from DT\n");
+
 	if (!of_property_read_u32(np, "cpu_suspend", &id)) {
 		psci_function_id[PSCI_FN_CPU_SUSPEND] = id;
 		psci_ops.cpu_suspend = psci_cpu_suspend;
@@ -206,5 +295,25 @@ void __init psci_init(void)
 
 out_put_node:
 	of_node_put(np);
-	return;
+	return err;
+}
+
+static const struct of_device_id psci_of_match[] __initconst = {
+	{ .compatible = "arm,psci", .data = psci_0_1_init},
+	{ .compatible = "arm,psci-0.2", .data = psci_0_2_init},
+	{},
+};
+
+int __init psci_init(void)
+{
+	struct device_node *np;
+	const struct of_device_id *matched_np;
+	psci_initcall_t init_fn;
+
+	np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
+	if (!np)
+		return -ENODEV;
+
+	init_fn = (psci_initcall_t)matched_np->data;
+	return init_fn(np);
 }
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 4f97db3..6b6590d 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/smp.h>
+#include <uapi/linux/psci.h>
 
 #include <asm/compiler.h>
 #include <asm/cpu_ops.h>
@@ -40,27 +41,28 @@ struct psci_operations {
 	int (*cpu_off)(struct psci_power_state state);
 	int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
 	int (*migrate)(unsigned long cpuid);
+	int (*affinity_info)(unsigned long target_affinity,
+			unsigned long lowest_affinity_level);
+	int (*migrate_info_type)(void);
 };
 
 static struct psci_operations psci_ops;
 
 static int (*invoke_psci_fn)(u64, u64, u64, u64);
+typedef int (*psci_initcall_t)(const struct device_node *);
 
 enum psci_function {
 	PSCI_FN_CPU_SUSPEND,
 	PSCI_FN_CPU_ON,
 	PSCI_FN_CPU_OFF,
 	PSCI_FN_MIGRATE,
+	PSCI_FN_AFFINITY_INFO,
+	PSCI_FN_MIGRATE_INFO_TYPE,
 	PSCI_FN_MAX,
 };
 
 static u32 psci_function_id[PSCI_FN_MAX];
 
-#define PSCI_RET_SUCCESS		0
-#define PSCI_RET_EOPNOTSUPP		-1
-#define PSCI_RET_EINVAL			-2
-#define PSCI_RET_EPERM			-3
-
 static int psci_to_linux_errno(int errno)
 {
 	switch (errno) {
@@ -128,6 +130,21 @@ static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
 	return function_id;
 }
 
+#define PSCI_VER_MAJOR_MASK		0xffff0000
+#define PSCI_VER_MINOR_MASK		0x0000ffff
+#define PSCI_VER_MAJOR_SHIFT	16
+#define PSCI_VER_MAJOR(ver)		\
+	((ver & PSCI_VER_MAJOR_MASK) >> PSCI_VER_MAJOR_SHIFT)
+#define PSCI_VER_MINOR(ver)		(ver & PSCI_VER_MINOR_MASK)
+
+static int psci_get_version(void)
+{
+	int err;
+
+	err = invoke_psci_fn(PSCI_ID_VERSION, 0, 0, 0);
+	return err;
+}
+
 static int psci_cpu_suspend(struct psci_power_state state,
 			    unsigned long entry_point)
 {
@@ -171,28 +188,36 @@ static int psci_migrate(unsigned long cpuid)
 	return psci_to_linux_errno(err);
 }
 
-static const struct of_device_id psci_of_match[] __initconst = {
-	{ .compatible = "arm,psci",	},
-	{},
-};
+static int psci_affinity_info(unsigned long target_affinity,
+		unsigned long lowest_affinity_level)
+{
+	int err;
+	u32 fn;
 
-int __init psci_init(void)
+	fn = psci_function_id[PSCI_FN_AFFINITY_INFO];
+	err = invoke_psci_fn(fn, target_affinity, lowest_affinity_level, 0);
+	return err;
+}
+
+static int psci_migrate_info_type(void)
 {
-	struct device_node *np;
-	const char *method;
-	u32 id;
-	int err = 0;
+	int err;
+	u32 fn;
 
-	np = of_find_matching_node(NULL, psci_of_match);
-	if (!np)
-		return -ENODEV;
+	fn = psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE];
+	err = invoke_psci_fn(fn, 0, 0, 0);
+	return err;
+}
 
-	pr_info("probing function IDs from device-tree\n");
+static int get_set_conduit_method(struct device_node *np)
+{
+	const char *method;
+
+	pr_info("probing for conduit method from DT.\n");
 
 	if (of_property_read_string(np, "method", &method)) {
-		pr_warning("missing \"method\" property\n");
-		err = -ENXIO;
-		goto out_put_node;
+		pr_warn("missing \"method\" property\n");
+		return -ENXIO;
 	}
 
 	if (!strcmp("hvc", method)) {
@@ -200,11 +225,75 @@ int __init psci_init(void)
 	} else if (!strcmp("smc", method)) {
 		invoke_psci_fn = __invoke_psci_fn_smc;
 	} else {
-		pr_warning("invalid \"method\" property: %s\n", method);
+		pr_warn("invalid \"method\" property: %s\n", method);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ * PSCI Function IDs for v0.2+ are well defined so use
+ * standard values.
+ */
+static int psci_0_2_init(struct device_node *np)
+{
+	int err, ver;
+
+	err = get_set_conduit_method(np);
+
+	if (err)
+		goto out_put_node;
+
+	ver = psci_get_version();
+
+	pr_info("PSCIv%d.%d detected in firmware.\n", PSCI_VER_MAJOR(ver),
+			PSCI_VER_MINOR(ver));
+
+	if (PSCI_VER_MAJOR(ver) == 0 && PSCI_VER_MINOR(ver) < 2) {
 		err = -EINVAL;
+		pr_err("Conflicting PSCI version detected.\n");
 		goto out_put_node;
 	}
 
+	pr_info("Using standard PSCI v0.2 function IDs\n");
+	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_ID_CPU_SUSPEND_64;
+	psci_ops.cpu_suspend = psci_cpu_suspend;
+
+	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_ID_CPU_OFF;
+	psci_ops.cpu_off = psci_cpu_off;
+
+	psci_function_id[PSCI_FN_CPU_ON] = PSCI_ID_CPU_ON_64;
+	psci_ops.cpu_on = psci_cpu_on;
+
+	psci_function_id[PSCI_FN_MIGRATE] = PSCI_ID_CPU_MIGRATE_64;
+	psci_ops.migrate = psci_migrate;
+
+	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_ID_AFFINITY_INFO_64;
+	psci_ops.affinity_info = psci_affinity_info;
+
+	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] = PSCI_ID_MIGRATE_INFO_TYPE;
+	psci_ops.migrate_info_type = psci_migrate_info_type;
+
+out_put_node:
+	of_node_put(np);
+	return err;
+}
+
+/*
+ * PSCI < v0.2 get PSCI Function IDs via DT.
+ */
+static int psci_0_1_init(struct device_node *np)
+{
+	u32 id;
+	int err;
+
+	err = get_set_conduit_method(np);
+
+	if (err)
+		goto out_put_node;
+
+	pr_info("Using PSCI v0.1 Function IDs from DT\n");
+
 	if (!of_property_read_u32(np, "cpu_suspend", &id)) {
 		psci_function_id[PSCI_FN_CPU_SUSPEND] = id;
 		psci_ops.cpu_suspend = psci_cpu_suspend;
@@ -230,6 +319,27 @@ out_put_node:
 	return err;
 }
 
+static const struct of_device_id psci_of_match[] __initconst = {
+	{ .compatible = "arm,psci",	.data = psci_0_1_init},
+	{ .compatible = "arm,psci-0.2",	.data = psci_0_2_init},
+	{},
+};
+
+int __init psci_init(void)
+{
+	struct device_node *np;
+	const struct of_device_id *matched_np;
+	psci_initcall_t init_fn;
+
+	np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
+
+	if (!np)
+		return -ENODEV;
+
+	init_fn = (psci_initcall_t)matched_np->data;
+	return init_fn(np);
+}
+
 #ifdef CONFIG_SMP
 
 static int __init cpu_psci_cpu_init(struct device_node *dn, unsigned int cpu)
diff --git a/include/uapi/linux/psci.h b/include/uapi/linux/psci.h
new file mode 100644
index 0000000..c523051
--- /dev/null
+++ b/include/uapi/linux/psci.h
@@ -0,0 +1,40 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *	Copyright (C) 2014, Ashwin Chaugule <ashwin.chaugule@linaro.org>
+ */
+
+#ifndef _UAPI_LINUX_PSCI_H
+#define _UAPI_LINUX_PSCI_H
+
+/* PSCI Function IDs as per PSCI spec v0.2 */
+#define PSCI_ID_VERSION					0x84000000
+#define PSCI_ID_CPU_SUSPEND_32			0x84000001
+#define PSCI_ID_CPU_SUSPEND_64			0xc4000001
+#define PSCI_ID_CPU_OFF					0x84000002
+#define PSCI_ID_CPU_ON_32				0x84000003
+#define PSCI_ID_CPU_ON_64				0xC4000003
+#define PSCI_ID_AFFINITY_INFO_32		0x84000004
+#define PSCI_ID_AFFINITY_INFO_64		0xC4000004
+#define PSCI_ID_CPU_MIGRATE_32			0x84000005
+#define PSCI_ID_CPU_MIGRATE_64			0xc4000005
+#define PSCI_ID_MIGRATE_INFO_TYPE		0x84000006
+#define PSCI_ID_MIGRATE_INFO_UP_CPU_32	0x84000007
+#define PSCI_ID_MIGRATE_INFO_UP_CPU_64	0xc4000007
+#define PSCI_ID_SYSTEM_OFF				0x84000008
+#define PSCI_ID_SYSTEM_RESET			0x84000009
+
+#define PSCI_RET_SUCCESS		0
+#define PSCI_RET_EOPNOTSUPP		-1
+#define PSCI_RET_EINVAL			-2
+#define PSCI_RET_EPERM			-3
+
+#endif /* _UAPI_LINUX_PSCI_H */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 2/3] Documentation: devicetree: Add new binding for PSCIv0.2
  2014-03-27 21:23 [PATCH v3 0/3] PSCI v0.2 support and DT bindings Ashwin Chaugule
  2014-03-27 21:23 ` [PATCH v3 1/3] PSCI: Add initial support for PSCIv0.2 functions Ashwin Chaugule
@ 2014-03-27 21:23 ` Ashwin Chaugule
  2014-03-27 21:23 ` [PATCH v3 3/3] ARM: Check if a CPU has gone offline Ashwin Chaugule
  2 siblings, 0 replies; 8+ messages in thread
From: Ashwin Chaugule @ 2014-03-27 21:23 UTC (permalink / raw)
  To: linux-arm-kernel

The PSCI v0.2+ spec defines standard values for PSCI function IDs.
Add a new binding entry so that pre v0.2 implementations can
use DT entries for function IDs and v0.2+ implementations use
standard entries as defined by the PSCIv0.2 specification.

Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/arm/psci.txt | 35 +++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/psci.txt b/Documentation/devicetree/bindings/arm/psci.txt
index 433afe9..d01a90b 100644
--- a/Documentation/devicetree/bindings/arm/psci.txt
+++ b/Documentation/devicetree/bindings/arm/psci.txt
@@ -21,7 +21,15 @@ to #0.
 
 Main node required properties:
 
- - compatible    : Must be "arm,psci"
+ - compatible    : should contain at least one of:
+
+				 * "arm,psci" : for implementations complying to PSCI versions prior to
+					0.2. For these cases function IDs must be provided.
+
+				 * "arm,psci-0.2" : for implementations complying to PSCI 0.2. Function
+					IDs are not required and should be ignored by an OS with PSCI 0.2
+					support, but are permitted to be present for compatibility with
+					existing software when "arm,psci" is later in the compatible list.
 
  - method        : The method of calling the PSCI firmware. Permitted
                    values are:
@@ -45,6 +53,8 @@ Main node optional properties:
 
 Example:
 
+Case 1: PSCI v0.1 only.
+
 	psci {
 		compatible	= "arm,psci";
 		method		= "smc";
@@ -53,3 +63,26 @@ Example:
 		cpu_on		= <0x95c10002>;
 		migrate		= <0x95c10003>;
 	};
+
+
+Case 2: PSCI v0.2 only
+
+	psci {
+		compatible	= "arm,psci-0.2";
+		method		= "smc";
+	};
+
+Case 3: PSCI v0.2 and PSCI v0.1.
+
+	As described above, for compatibility with existing kernels, the
+	hypervisor will likely want to provide IDs, e.g.
+
+	psci {
+		compatible = "arm,psci-0.2", "arm,psci";
+		method = "hvc";
+
+		cpu_on = < arbitrary value >;
+		cpu_off = < arbitrary value >;
+
+		...
+	};
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 3/3] ARM: Check if a CPU has gone offline
  2014-03-27 21:23 [PATCH v3 0/3] PSCI v0.2 support and DT bindings Ashwin Chaugule
  2014-03-27 21:23 ` [PATCH v3 1/3] PSCI: Add initial support for PSCIv0.2 functions Ashwin Chaugule
  2014-03-27 21:23 ` [PATCH v3 2/3] Documentation: devicetree: Add new binding for PSCIv0.2 Ashwin Chaugule
@ 2014-03-27 21:23 ` Ashwin Chaugule
  2014-03-28 13:31   ` Rob Herring
  2 siblings, 1 reply; 8+ messages in thread
From: Ashwin Chaugule @ 2014-03-27 21:23 UTC (permalink / raw)
  To: linux-arm-kernel

PSCIv0.2 adds a new function called AFFINITY_INFO, which
can be used to query if a specified CPU has actually gone
offline. Calling this function via cpu_kill ensures that
a CPU has quiesced after a call to cpu_die.

Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
---
 arch/arm/kernel/psci_smp.c | 21 +++++++++++++++++++++
 include/uapi/linux/psci.h  |  5 +++++
 2 files changed, 26 insertions(+)

diff --git a/arch/arm/kernel/psci_smp.c b/arch/arm/kernel/psci_smp.c
index 570a48c..4c1adf9 100644
--- a/arch/arm/kernel/psci_smp.c
+++ b/arch/arm/kernel/psci_smp.c
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/of.h>
+#include <uapi/linux/psci.h>
 
 #include <asm/psci.h>
 #include <asm/smp_plat.h>
@@ -66,6 +67,25 @@ void __ref psci_cpu_die(unsigned int cpu)
        /* We should never return */
        panic("psci: cpu %d failed to shutdown\n", cpu);
 }
+
+int __ref psci_cpu_kill(unsigned int cpu)
+{
+	int err;
+
+	if (!psci_ops.affinity_info)
+		return 1;
+
+	err = psci_ops.affinity_info(cpu_logical_map(cpu), 0);
+
+	if (err != PSCI_AFFINITY_INFO_RET_OFF) {
+		pr_err("psci: Cannot kill CPU:%d, psci ret val: %d\n",
+				cpu, err);
+		/* Make platform_cpu_kill() fail. */
+		return 0;
+	}
+	return err;
+}
+
 #endif
 
 bool __init psci_smp_available(void)
@@ -78,5 +98,6 @@ struct smp_operations __initdata psci_smp_ops = {
 	.smp_boot_secondary	= psci_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
 	.cpu_die		= psci_cpu_die,
+	.cpu_kill		= psci_cpu_kill,
 #endif
 };
diff --git a/include/uapi/linux/psci.h b/include/uapi/linux/psci.h
index c523051..2c177f5 100644
--- a/include/uapi/linux/psci.h
+++ b/include/uapi/linux/psci.h
@@ -37,4 +37,9 @@
 #define PSCI_RET_EINVAL			-2
 #define PSCI_RET_EPERM			-3
 
+/* Return values from the PSCI_ID_AFFINITY_INFO Function. */
+#define PSCI_AFFINITY_INFO_RET_ON			0
+#define PSCI_AFFINITY_INFO_RET_OFF			1
+#define PSCI_AFFINITY_INFO_RET_ON_PENDING	2
+
 #endif /* _UAPI_LINUX_PSCI_H */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 3/3] ARM: Check if a CPU has gone offline
  2014-03-27 21:23 ` [PATCH v3 3/3] ARM: Check if a CPU has gone offline Ashwin Chaugule
@ 2014-03-28 13:31   ` Rob Herring
  0 siblings, 0 replies; 8+ messages in thread
From: Rob Herring @ 2014-03-28 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 27, 2014 at 4:23 PM, Ashwin Chaugule
<ashwin.chaugule@linaro.org> wrote:
> PSCIv0.2 adds a new function called AFFINITY_INFO, which
> can be used to query if a specified CPU has actually gone
> offline. Calling this function via cpu_kill ensures that
> a CPU has quiesced after a call to cpu_die.
>
> Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>

One minor nit, but otherwise:

Reviewed-by: Rob Herring <robh@kernel.org>

> ---
>  arch/arm/kernel/psci_smp.c | 21 +++++++++++++++++++++
>  include/uapi/linux/psci.h  |  5 +++++
>  2 files changed, 26 insertions(+)
>
> diff --git a/arch/arm/kernel/psci_smp.c b/arch/arm/kernel/psci_smp.c
> index 570a48c..4c1adf9 100644
> --- a/arch/arm/kernel/psci_smp.c
> +++ b/arch/arm/kernel/psci_smp.c
> @@ -16,6 +16,7 @@
>  #include <linux/init.h>
>  #include <linux/smp.h>
>  #include <linux/of.h>
> +#include <uapi/linux/psci.h>
>
>  #include <asm/psci.h>
>  #include <asm/smp_plat.h>
> @@ -66,6 +67,25 @@ void __ref psci_cpu_die(unsigned int cpu)
>         /* We should never return */
>         panic("psci: cpu %d failed to shutdown\n", cpu);
>  }
> +
> +int __ref psci_cpu_kill(unsigned int cpu)
> +{
> +       int err;
> +
> +       if (!psci_ops.affinity_info)
> +               return 1;
> +
> +       err = psci_ops.affinity_info(cpu_logical_map(cpu), 0);
> +
> +       if (err != PSCI_AFFINITY_INFO_RET_OFF) {
> +               pr_err("psci: Cannot kill CPU:%d, psci ret val: %d\n",
> +                               cpu, err);
> +               /* Make platform_cpu_kill() fail. */
> +               return 0;
> +       }
> +       return err;

I think this should just be "return 1;" PSCI_AFFINITY_INFO_RET_OFF
happens to match, but it's really different meanings.

> +}
> +
>  #endif
>
>  bool __init psci_smp_available(void)
> @@ -78,5 +98,6 @@ struct smp_operations __initdata psci_smp_ops = {
>         .smp_boot_secondary     = psci_boot_secondary,
>  #ifdef CONFIG_HOTPLUG_CPU
>         .cpu_die                = psci_cpu_die,
> +       .cpu_kill               = psci_cpu_kill,
>  #endif
>  };
> diff --git a/include/uapi/linux/psci.h b/include/uapi/linux/psci.h
> index c523051..2c177f5 100644
> --- a/include/uapi/linux/psci.h
> +++ b/include/uapi/linux/psci.h
> @@ -37,4 +37,9 @@
>  #define PSCI_RET_EINVAL                        -2
>  #define PSCI_RET_EPERM                 -3
>
> +/* Return values from the PSCI_ID_AFFINITY_INFO Function. */
> +#define PSCI_AFFINITY_INFO_RET_ON                      0
> +#define PSCI_AFFINITY_INFO_RET_OFF                     1
> +#define PSCI_AFFINITY_INFO_RET_ON_PENDING      2
> +
>  #endif /* _UAPI_LINUX_PSCI_H */
> --
> 1.8.3.2
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v3 1/3] PSCI: Add initial support for PSCIv0.2 functions
  2014-03-27 21:23 ` [PATCH v3 1/3] PSCI: Add initial support for PSCIv0.2 functions Ashwin Chaugule
@ 2014-03-28 13:54   ` Rob Herring
  2014-03-28 15:00     ` Ashwin Chaugule
  0 siblings, 1 reply; 8+ messages in thread
From: Rob Herring @ 2014-03-28 13:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 27, 2014 at 4:23 PM, Ashwin Chaugule
<ashwin.chaugule@linaro.org> wrote:
> The PSCIv0.2 spec defines standard values of function IDs
> and introduces a few new functions. Detect version of PSCI
> and appropriately select the right PSCI functions.

Looks pretty good. A few minor things below.

[snip]

> @@ -110,6 +109,21 @@ static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1,
>         return function_id;
>  }
>
> +#define PSCI_VER_MAJOR_MASK            0xffff0000
> +#define PSCI_VER_MINOR_MASK            0x0000ffff
> +#define PSCI_VER_MAJOR_SHIFT   16
> +#define PSCI_VER_MAJOR(ver)            \
> +       ((ver & PSCI_VER_MAJOR_MASK) >> PSCI_VER_MAJOR_SHIFT)
> +#define PSCI_VER_MINOR(ver)            (ver & PSCI_VER_MINOR_MASK)

This can go in the header.

[snip]

> +       ver = psci_get_version();
> +
> +       pr_info("PSCIv%d.%d detected in firmware.\n", PSCI_VER_MAJOR(ver),
> +                       PSCI_VER_MINOR(ver));
> +
> +       if (PSCI_VER_MAJOR(ver) == 0 && PSCI_VER_MINOR(ver) < 2) {

So we want to allow 0.3, but not 1.x? I think we want to allow any
later version. Later versions either have to be backward's compatible
with 0.2 or have to not have "arm,psci-0.2" compatible string.

Does this work if ver is an error value? We may have implementations
that failed to implement this function (which should not be ignored
for now).

>                 err = -EINVAL;
> +               pr_err("Conflicting PSCI version detected.\n");
>                 goto out_put_node;
>         }

[snip]

> diff --git a/include/uapi/linux/psci.h b/include/uapi/linux/psci.h
> new file mode 100644
> index 0000000..c523051
> --- /dev/null
> +++ b/include/uapi/linux/psci.h
> @@ -0,0 +1,40 @@
> +/*
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *     Copyright (C) 2014, Ashwin Chaugule <ashwin.chaugule@linaro.org>

I believe this should be:

Copyright (C) 2014 Linaro Ltd.
Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>

And typically the copyright is placed above the license.

> + */
> +
> +#ifndef _UAPI_LINUX_PSCI_H
> +#define _UAPI_LINUX_PSCI_H
> +
> +/* PSCI Function IDs as per PSCI spec v0.2 */
> +#define PSCI_ID_VERSION                                        0x84000000
> +#define PSCI_ID_CPU_SUSPEND_32                 0x84000001
> +#define PSCI_ID_CPU_SUSPEND_64                 0xc4000001
> +#define PSCI_ID_CPU_OFF                                        0x84000002
> +#define PSCI_ID_CPU_ON_32                              0x84000003
> +#define PSCI_ID_CPU_ON_64                              0xC4000003
> +#define PSCI_ID_AFFINITY_INFO_32               0x84000004
> +#define PSCI_ID_AFFINITY_INFO_64               0xC4000004
> +#define PSCI_ID_CPU_MIGRATE_32                 0x84000005
> +#define PSCI_ID_CPU_MIGRATE_64                 0xc4000005
> +#define PSCI_ID_MIGRATE_INFO_TYPE              0x84000006
> +#define PSCI_ID_MIGRATE_INFO_UP_CPU_32 0x84000007
> +#define PSCI_ID_MIGRATE_INFO_UP_CPU_64 0xc4000007
> +#define PSCI_ID_SYSTEM_OFF                             0x84000008
> +#define PSCI_ID_SYSTEM_RESET                   0x84000009
> +
> +#define PSCI_RET_SUCCESS               0
> +#define PSCI_RET_EOPNOTSUPP            -1
> +#define PSCI_RET_EINVAL                        -2
> +#define PSCI_RET_EPERM                 -3

Please fill out all error codes.

> +
> +#endif /* _UAPI_LINUX_PSCI_H */
> --
> 1.8.3.2
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v3 1/3] PSCI: Add initial support for PSCIv0.2 functions
  2014-03-28 13:54   ` Rob Herring
@ 2014-03-28 15:00     ` Ashwin Chaugule
  2014-03-28 15:40       ` [Linaro-acpi] " Charles Garcia-Tobin
  0 siblings, 1 reply; 8+ messages in thread
From: Ashwin Chaugule @ 2014-03-28 15:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rob,

On 28 March 2014 09:54, Rob Herring <rob.herring@linaro.org> wrote:

>> +#define PSCI_VER_MAJOR_MASK            0xffff0000
>> +#define PSCI_VER_MINOR_MASK            0x0000ffff
>> +#define PSCI_VER_MAJOR_SHIFT   16
>> +#define PSCI_VER_MAJOR(ver)            \
>> +       ((ver & PSCI_VER_MAJOR_MASK) >> PSCI_VER_MAJOR_SHIFT)
>> +#define PSCI_VER_MINOR(ver)            (ver & PSCI_VER_MINOR_MASK)
>
> This can go in the header.

Will do.

>
> [snip]
>
>> +       ver = psci_get_version();
>> +
>> +       pr_info("PSCIv%d.%d detected in firmware.\n", PSCI_VER_MAJOR(ver),
>> +                       PSCI_VER_MINOR(ver));
>> +
>> +       if (PSCI_VER_MAJOR(ver) == 0 && PSCI_VER_MINOR(ver) < 2) {
>
> So we want to allow 0.3, but not 1.x? I think we want to allow any
> later version. Later versions either have to be backward's compatible
> with 0.2 or have to not have "arm,psci-0.2" compatible string.

If its 1.x, it should still go through? Should only fail for 0.1 or 0.0.

>
> Does this work if ver is an error value? We may have implementations
> that failed to implement this function (which should not be ignored
> for now).

True. What is a good err value to check for? negative values?

One would hope implementations would return (-7) NOT_PRESENT, but it
could also be garbage?

>> + *
>> + *     Copyright (C) 2014, Ashwin Chaugule <ashwin.chaugule@linaro.org>
>
> I believe this should be:
>
> Copyright (C) 2014 Linaro Ltd.
> Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
>
> And typically the copyright is placed above the license.

Ok.

>> +
>> +#define PSCI_RET_SUCCESS               0
>> +#define PSCI_RET_EOPNOTSUPP            -1
>> +#define PSCI_RET_EINVAL                        -2
>> +#define PSCI_RET_EPERM                 -3
>
> Please fill out all error codes.
>

Ok, I see the return codes table. Will add all of it.

Cheers,
Ashwin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Linaro-acpi] [PATCH v3 1/3] PSCI: Add initial support for PSCIv0.2 functions
  2014-03-28 15:00     ` Ashwin Chaugule
@ 2014-03-28 15:40       ` Charles Garcia-Tobin
  0 siblings, 0 replies; 8+ messages in thread
From: Charles Garcia-Tobin @ 2014-03-28 15:40 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: linaro-acpi-bounces at lists.linaro.org [mailto:linaro-acpi-
> bounces at lists.linaro.org] On Behalf Of Ashwin Chaugule
> Sent: 28 March 2014 15:00
> To: rob.herring at linaro.org
> Cc: Anup Patel; Patch Tracking; Marc Zyngier; linaro-acpi;
linux-arm-kernel;
> Christoffer Dall
> Subject: Re: [Linaro-acpi] [PATCH v3 1/3] PSCI: Add initial support for
PSCIv0.2
> functions
> 
> Hi Rob,
> 
> On 28 March 2014 09:54, Rob Herring <rob.herring@linaro.org> wrote:
> 
> >> +#define PSCI_VER_MAJOR_MASK            0xffff0000
> >> +#define PSCI_VER_MINOR_MASK            0x0000ffff
> >> +#define PSCI_VER_MAJOR_SHIFT   16
> >> +#define PSCI_VER_MAJOR(ver)            \
> >> +       ((ver & PSCI_VER_MAJOR_MASK) >> PSCI_VER_MAJOR_SHIFT)
> >> +#define PSCI_VER_MINOR(ver)            (ver & PSCI_VER_MINOR_MASK)
> >
> > This can go in the header.
> 
> Will do.
> 
> >
> > [snip]
> >
> >> +       ver = psci_get_version();
> >> +
> >> +       pr_info("PSCIv%d.%d detected in firmware.\n",
PSCI_VER_MAJOR(ver),
> >> +                       PSCI_VER_MINOR(ver));
> >> +
> >> +       if (PSCI_VER_MAJOR(ver) == 0 && PSCI_VER_MINOR(ver) < 2) {
> >
> > So we want to allow 0.3, but not 1.x? I think we want to allow any
> > later version. Later versions either have to be backward's compatible
> > with 0.2 or have to not have "arm,psci-0.2" compatible string.
> 
> If its 1.x, it should still go through? Should only fail for 0.1 or 0.0.
> 
> >
> > Does this work if ver is an error value? We may have implementations
> > that failed to implement this function (which should not be ignored
> > for now).
> 
> True. What is a good err value to check for? negative values?
> 
> One would hope implementations would return (-7) NOT_PRESENT, but it
> could also be garbage?

So from v0.2 PSCI_VERSION is compulsory. It has to be implemented. If a
function is not implemented it must return NOT_SUPPORTED(-1)

Cheers

Charles

>
> >> + *
> >> + *     Copyright (C) 2014, Ashwin Chaugule
<ashwin.chaugule@linaro.org>
> >
> > I believe this should be:
> >
> > Copyright (C) 2014 Linaro Ltd.
> > Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
> >
> > And typically the copyright is placed above the license.
> 
> Ok.
> 
> >> +
> >> +#define PSCI_RET_SUCCESS               0
> >> +#define PSCI_RET_EOPNOTSUPP            -1
> >> +#define PSCI_RET_EINVAL                        -2
> >> +#define PSCI_RET_EPERM                 -3
> >
> > Please fill out all error codes.
> >
> 
> Ok, I see the return codes table. Will add all of it.
> 
> Cheers,
> Ashwin
> 
> _______________________________________________
> Linaro-acpi mailing list
> Linaro-acpi at lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/linaro-acpi

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-03-28 15:40 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-27 21:23 [PATCH v3 0/3] PSCI v0.2 support and DT bindings Ashwin Chaugule
2014-03-27 21:23 ` [PATCH v3 1/3] PSCI: Add initial support for PSCIv0.2 functions Ashwin Chaugule
2014-03-28 13:54   ` Rob Herring
2014-03-28 15:00     ` Ashwin Chaugule
2014-03-28 15:40       ` [Linaro-acpi] " Charles Garcia-Tobin
2014-03-27 21:23 ` [PATCH v3 2/3] Documentation: devicetree: Add new binding for PSCIv0.2 Ashwin Chaugule
2014-03-27 21:23 ` [PATCH v3 3/3] ARM: Check if a CPU has gone offline Ashwin Chaugule
2014-03-28 13:31   ` Rob Herring

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).