PSCI v0.2 support and DT bindings
v3 cover PSCI v0.2 support and DT bindings
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
Signature · 1 line
1.8.3.2
PATCH v3 1/3 PSCI: Add initial support for PSCIv0.2 functions
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.
--- 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
arch/arm/include/asm/psci.h +5 -2
@@ -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
arch/arm/kernel/psci.c +130 -21
205 lines not on this page · raw message
arch/arm64/kernel/psci.c +132 -22
216 lines not on this page · raw message
include/uapi/linux/psci.h new file +40 -0
@@ -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 <[email protected]> +*/ + +#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 */
Signature · 1 line
1.8.3.2
PATCH v3 1/3 PSCI: Add initial support for PSCIv0.2 functions
Quoted 3 lines · Ashwin Chaugule
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]
arch/arm/kernel/psci.c static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1, · line 117
Quoted 10 lines
arch/arm/kernel/psci.c +6
-0@@ -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]
arch/arm/kernel/psci.c void __init psci_init(void) · line 231
Quoted 6 lines
arch/arm/kernel/psci.c +6
-0+ 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).
Quoted 4 lines
arch/arm64/kernel/psci.c +1
-0err = -EINVAL ; +pr_err ("Conflicting PSCI version detected.\n" ); goto out_put_node; }
[snip]
Quoted 8 lines
include/uapi/linux/psci.h new file +2
-0@@ -0,0 +1,40 @@ +/* +* This program is free software; you can redistribute it and/or modify
include/uapi/linux/psci.h line 12
Quoted 10 lines
include/uapi/linux/psci.h new file +10
-0+* 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 <[email protected]>
I believe this should be:
Copyright (C) 2014 Linaro Ltd.
Author: Ashwin Chaugule <[email protected]>
And typically the copyright is placed above the license.
Quoted 16 lines
include/uapi/linux/psci.h new file +16
-0+*/ + +#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
include/uapi/linux/psci.h line 38
Quoted 10 lines
include/uapi/linux/psci.h new file +10
-0+#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.
Quoted 5 lines
include/uapi/linux/psci.h new file +2
-1+ +#endif /* _UAPI_LINUX_PSCI_H */ --1.8.3.2
PATCH v3 1/3 PSCI: Add initial support for PSCIv0.2 functions
Hi Rob,
Quoted 8 lines · Rob Herring
arch/arm/kernel/psci.c static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1, · line 117
Quoted 6 lines
arch/arm/kernel/psci.c +6
-0+#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.
Quoted 13 lines
[snip]
arch/arm/kernel/psci.c void __init psci_init(void) · line 231
Quoted 6 lines
arch/arm/kernel/psci.c +6
-0+ 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.
Quoted 4 lines
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?
Quoted 9 lines
Quoted 2 lines
+ *
+ * Copyright (C) 2014, Ashwin Chaugule <[email protected]>I believe this should be:
Copyright (C) 2014 Linaro Ltd.
Author: Ashwin Chaugule <[email protected]>And typically the copyright is placed above the license.
Ok.
Quoted 8 lines
include/uapi/linux/psci.h line 38
Quoted 5 lines
include/uapi/linux/psci.h new file +5
-0+ +#define PSCI_RET_SUCCESS 0 +#define PSCI_RET_EOPNOTSUPP -1 +#define PSCI_RET_EINVAL -2 +#define PSCI_RET_EPERM -3Please fill out all error codes.
Ok, I see the return codes table. Will add all of it.
Cheers,
Ashwin
PATCH v3 1/3 PSCI: Add initial support for PSCIv0.2 functions
Quoted 8 lines
-----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;
Quoted 2 lines
Christoffer Dall
Subject: Re: [Linaro-acpi] [PATCH v3 1/3] PSCI: Add initial support for
PSCIv0.2
Quoted 15 lines
functions
Hi Rob,
Quoted 8 lines · Rob Herring
arch/arm/kernel/psci.c static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1, · line 117
Quoted 6 lines
arch/arm/kernel/psci.c +6
-0+#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.
Quoted 8 lines
Will do.
Quoted 6 lines
[snip]
Quoted 3 lines
arch/arm/kernel/psci.c +3
-0+ ver =psci_get_version (); + + pr_info("PSCIv%d.%d detected in firmware.\n",
PSCI_VER_MAJOR(ver),
Quoted 11 lines
Quoted 7 lines
arch/arm/kernel/psci.c void __init psci_init(void) · line 231
Quoted 3 lines
arch/arm/kernel/psci.c +3
-0+ 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.
Quoted 1 line
Quoted 8 lines
Quoted 3 lines
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
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
+ *
+ * Copyright (C) 2014, Ashwin Chaugule
Quoted 28 lines
Quoted 7 lines
I believe this should be:
Copyright (C) 2014 Linaro Ltd.
Author: Ashwin Chaugule <[email protected]>And typically the copyright is placed above the license.
Ok.
Quoted 8 lines
include/uapi/linux/psci.h line 38
Quoted 5 lines
include/uapi/linux/psci.h new file +5
-0+ +#define PSCI_RET_SUCCESS 0 +#define PSCI_RET_EOPNOTSUPP -1 +#define PSCI_RET_EINVAL -2 +#define PSCI_RET_EPERM -3Please 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
PATCH v3 2/3 Documentation: devicetree: Add new binding for PSCIv0.2
In reply to Ashwin ChauguleThe 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.
--- Documentation/devicetree/bindings/arm/psci.txt | 35 +++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/arm/psci.txt +34 -1
@@ -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 >; + + ... + };
Signature · 1 line
1.8.3.2
PATCH v3 3/3 ARM: Check if a CPU has gone offline
In reply to Ashwin ChaugulePSCIv0.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.
--- arch/arm/kernel/psci_smp.c | 21 +++++++++++++++++++++ include/uapi/linux/psci.h | 5 +++++ 2 files changed, 26 insertions(+)
arch/arm/kernel/psci_smp.c +21 -0
@@ -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 };
include/uapi/linux/psci.h +5 -0
@@ -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 */
Signature · 1 line
1.8.3.2
PATCH v3 3/3 ARM: Check if a CPU has gone offline
Quoted 6 lines · Ashwin Chaugule
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 viacpu_killensures that a CPU has quiesced after a call tocpu_die.Signed-off-by Ashwin Chaugule <[email protected]>
One minor nit, but otherwise:
Quoted 28 lines
--- arch/arm/kernel/psci_smp.c | 21 +++++++++++++++++++++ include/uapi/linux/psci.h | 5 +++++ 2 files changed, 26 insertions(+)arch/arm/kernel/psci_smp.c +8
-0@@ -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 ;
arch/arm/kernel/psci_smp.c void __ref psci_cpu_die(unsigned int cpu) · line 86
Quoted 10 lines
arch/arm/kernel/psci_smp.c +10
-0+ + 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.
Quoted 29 lines
arch/arm/kernel/psci_smp.c +3
-0+} +#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 };include/uapi/linux/psci.h +5
-1@@ -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