Skip to contentSkip to conversation

Enabling PSCI based idle on ARM 32-bit platforms

PATCH Superseded Lorenzo Pieralisi 6 participants 15 messages Oct 12, 2015 – Oct 14, 2015

Subsystems (5)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover Enabling PSCI based idle on ARM 32-bit platforms

This patch series is v2 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373756.html

v1->v2:

- Refactored patch 1 to remove cpu parameter from cpuidle_ops suspend hook
- Refactored psci_cpu_init_idle to stub out dt parsing function and make it usable on both ARM/ARM64 with no additional changes
- Updated ARM cpuidle_ops to new interfaces
- Fixed PSCI enable method string in ARM cpuidle_ops struct

PSCI firmware provides a kernel API that, through a standard interface, allows to manage power states transitions in a seamless manner for ARM and ARM64 systems.

Current PSCI code that initializes CPUidle states on PSCI based systems lives in arch/arm64 directory but it is not ARM64 specific and can be shared with ARM 32-bit systems so that the generic ARM CPUidle driver can leverage the common PSCI interface.

This patch series moves PSCI CPUidle management code to drivers/firmware directory so that ARM and ARM64 architecture can actually share the code.

It is made up of two patches:

Patch 1 refactors ARM 32-bit generic idle implementation to remove the cpu parameter from the cpuidle_ops suspend hook, in preparation for a common PSCI implementation for ARM/ARM64 PSCI idle.

Patch 2 moves ARM64 PSCI CPUidle functions implementation to drivers/firmware so that it can be shared with ARM 32-bit platforms code. This patch also adds a PSCI entry section on ARM 32-bit systems so that the PSCI CPUidle back-end can be enabled when the enable-method corresponds to PSCI.

Patches apply on top of current patch stack to enable PSCI 1.0:

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git tags/firmware/psci-1.0

Tested on Juno board (ARM64), compile tested only on ARM 32-bit systems.

Lorenzo Pieralisi (2):
ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook
ARM64: kernel: PSCI: move PSCI idle management code to
drivers/firmware

 arch/arm/include/asm/cpuidle.h |   2 +-
 arch/arm/kernel/cpuidle.c      |   2 +-
 arch/arm64/kernel/psci.c       |  99 +-----------------------------
 drivers/firmware/Makefile      |   2 +-
 drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++
 drivers/soc/qcom/spm.c         |  10 ++--
 include/linux/psci.h           |   3 +
 7 files changed, 146 insertions(+), 105 deletions(-)
 create mode 100644 drivers/firmware/psci_cpuops.c
Signature · 1 line
2.5.1
#1 lore raw

PATCH v2 1/2 ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook

The suspend() hook in the cpuidle_ops struct is always called on the cpu entering idle, which means that the cpu parameter passed to the suspend hook always corresponds to the local cpu, making it somewhat redundant.

This patch removes the logical cpu parameter from the ARM cpuidle_ops.suspend hook and updates all the existing kernel implementations to reflect this change.

Cc Lina Iyer <[email protected]>
Cc Russell King <[email protected]>
Cc Daniel Lezcano <[email protected]>
---
 arch/arm/include/asm/cpuidle.h |  2 +-
 arch/arm/kernel/cpuidle.c      |  2 +-
 drivers/soc/qcom/spm.c         | 10 +++++-----
 3 files changed, 7 insertions(+), 7 deletions(-)
arch/arm/include/asm/cpuidle.h +1 -1
index 0f84249..3848259 100644
@@ -30,7 +30,7 @@ static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
 struct device_node;
 
 struct cpuidle_ops {
-	int (*suspend)(int cpu, unsigned long arg);
+	int (*suspend)(unsigned long arg);
 	int (*init)(struct device_node *, int cpu);
 };
 
arch/arm/kernel/cpuidle.c +1 -1
index 318da33..703926e 100644
@@ -56,7 +56,7 @@ int arm_cpuidle_suspend(int index)
 	int cpu = smp_processor_id();
 
 	if (cpuidle_ops[cpu].suspend)
-		ret = cpuidle_ops[cpu].suspend(cpu, index);
+		ret = cpuidle_ops[cpu].suspend(index);
 
 	return ret;
 }
drivers/soc/qcom/spm.c +5 -5
index b04b05a..0ad66fa 100644
@@ -116,7 +116,7 @@ static const struct spm_reg_data spm_reg_8064_cpu = {
 
 static DEFINE_PER_CPU(struct spm_driver_data *, cpu_spm_drv);
 
-typedef int (*idle_fn)(int);
+typedef int (*idle_fn)(void);
 static DEFINE_PER_CPU(idle_fn*, qcom_idle_ops);
 
 static inline void spm_register_write(struct spm_driver_data *drv,
@@ -179,10 +179,10 @@ static int qcom_pm_collapse(unsigned long int unused)
 	return -1;
 }
 
-static int qcom_cpu_spc(int cpu)
+static int qcom_cpu_spc(void)
 {
 	int ret;
-	struct spm_driver_data *drv = per_cpu(cpu_spm_drv, cpu);
+	struct spm_driver_data *drv = __this_cpu_read(cpu_spm_drv);
 
 	spm_set_low_power_mode(drv, PM_SLEEP_MODE_SPC);
 	ret = cpu_suspend(0, qcom_pm_collapse);
@@ -197,9 +197,9 @@ static int qcom_cpu_spc(int cpu)
 	return ret;
 }
 
-static int qcom_idle_enter(int cpu, unsigned long index)
+static int qcom_idle_enter(unsigned long index)
 {
-	return per_cpu(qcom_idle_ops, cpu)[index](cpu);
+	return __this_cpu_read(qcom_idle_ops)[index]();
 }
 
 static const struct of_device_id qcom_idle_state_match[] __initconst = {
Signature · 1 line
2.5.1
#2 lore raw

PATCH v2 1/2 ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook

Quoted 5 lines · Lorenzo Pieralisi

The suspend() hook in the cpuidle_ops struct is always called on the cpu entering idle, which means that the cpu parameter passed to the suspend hook always corresponds to the local cpu, making it somewhat redundant.

Quoted 8 lines

This patch removes the logical cpu parameter from the ARM cpuidle_ops.suspend hook and updates all the existing kernel implementations to reflect this change.

Cc Lina Iyer <[email protected]>
Cc Russell King <[email protected]>
Cc Daniel Lezcano <[email protected]>
Quoted 73 lines

---

arch/arm/include/asm/cpuidle.h |  2 +-
arch/arm/kernel/cpuidle.c      |  2 +-
drivers/soc/qcom/spm.c         | 10 +++++-----
3 files changed, 7 insertions(+), 7 deletions(-)
arch/arm/include/asm/cpuidle.h +1 -1
index 0f84249..3848259 100644
@@ -30,7 +30,7 @@ static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
 struct device_node;
 
 struct cpuidle_ops {
-	int (*suspend)(int cpu, unsigned long arg);
+	int (*suspend)(unsigned long arg);
 	int (*init)(struct device_node *, int cpu);
 };
 
arch/arm/kernel/cpuidle.c +1 -1
index 318da33..703926e 100644
@@ -56,7 +56,7 @@ int arm_cpuidle_suspend(int index)
 	int cpu = smp_processor_id();
 
 	if (cpuidle_ops[cpu].suspend)
-		ret = cpuidle_ops[cpu].suspend(cpu, index);
+		ret = cpuidle_ops[cpu].suspend(index);
 
 	return ret;
 }
drivers/soc/qcom/spm.c +5 -5
index b04b05a..0ad66fa 100644
@@ -116,7 +116,7 @@ static const struct spm_reg_data spm_reg_8064_cpu = {
 
 static DEFINE_PER_CPU(struct spm_driver_data *, cpu_spm_drv);
 
-typedef int (*idle_fn)(int);
+typedef int (*idle_fn)(void);
 static DEFINE_PER_CPU(idle_fn*, qcom_idle_ops);
 
 static inline void spm_register_write(struct spm_driver_data *drv,
@@ -179,10 +179,10 @@ static int qcom_pm_collapse(unsigned long int unused)
 	return -1;
 }
 
-static int qcom_cpu_spc(int cpu)
+static int qcom_cpu_spc(void)
 {
 	int ret;
-	struct spm_driver_data *drv = per_cpu(cpu_spm_drv, cpu);
+	struct spm_driver_data *drv = __this_cpu_read(cpu_spm_drv);
 
 	spm_set_low_power_mode(drv, PM_SLEEP_MODE_SPC);
 	ret = cpu_suspend(0, qcom_pm_collapse);
@@ -197,9 +197,9 @@ static int qcom_cpu_spc(int cpu)
 	return ret;
 }
 
-static int qcom_idle_enter(int cpu, unsigned long index)
+static int qcom_idle_enter(unsigned long index)
 {
-	return per_cpu(qcom_idle_ops, cpu)[index](cpu);
+	return __this_cpu_read(qcom_idle_ops)[index]();
 }
 
 static const struct of_device_id qcom_idle_state_match[] __initconst = {
Signature · 1 line
2.5.1
#3 lore raw

PATCH v2 1/2 ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook

Hi Lina,

Quoted 10 lines · Lina Iyer
Quoted 9 lines · Lorenzo Pieralisi

The suspend() hook in the cpuidle_ops struct is always called on the cpu entering idle, which means that the cpu parameter passed to the suspend hook always corresponds to the local cpu, making it somewhat redundant.

This patch removes the logical cpu parameter from the ARM cpuidle_ops.suspend hook and updates all the existing kernel implementations to reflect this change.

Quoted 6 lines
Quoted 4 lines
Cc Lina Iyer <[email protected]>
Cc Russell King <[email protected]>
Cc Daniel Lezcano <[email protected]>

Thank you very much. May I also ask you to test it please, a Tested-by is needed since it affects QCOM platforms I can't test on at present.

Thank you,
Lorenzo

#4 lore raw

PATCH v2 1/2 ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook

Quoted 18 lines · Lorenzo Pieralisi

Hi Lina,

Quoted 15 lines · Lina Iyer
Quoted 13 lines · Lorenzo Pieralisi

The suspend() hook in the cpuidle_ops struct is always called on the cpu entering idle, which means that the cpu parameter passed to the suspend hook always corresponds to the local cpu, making it somewhat redundant.

This patch removes the logical cpu parameter from the ARM cpuidle_ops.suspend hook and updates all the existing kernel implementations to reflect this change.

Cc Lina Iyer <[email protected]>
Cc Russell King <[email protected]>
Cc Daniel Lezcano <[email protected]>
Quoted 5 lines
Quoted 1 line

Thank you very much. May I also ask you to test it please, a Tested-by is needed since it affects QCOM platforms I can't test on at present.

Thanks,
Lina

#5 lore raw

PATCH v2 2/2 ARM64: kernel: PSCI: move PSCI idle management code to drivers/firmware

In reply to Lorenzo Pieralisi

ARM64 PSCI kernel interfaces that initialize idle states and implement the suspend API to enter them are generic and can be shared with the ARM architecture.

To achieve that goal, this patch moves ARM64 PSCI idle management code to drivers/firmware by creating a file that contains PSCI helper functions implementing the common kernel interface required by ARM and ARM64 to share the PSCI idle management code.

The ARM generic CPUidle implementation also requires the definition of a cpuidle_ops section entry for the kernel to initialize the CPUidle operations at boot based on the enable-method (ie ARM64 has the statically initialized cpu_ops counterparts for that purpose); therefore this patch also adds the required section entry on CONFIG_ARM for PSCI so that the kernel can initialize the PSCI CPUidle back-end when PSCI is the probed enable-method.

On ARM64 this patch provides no functional change.

Cc Will Deacon <[email protected]>
Cc Sudeep Holla <[email protected]>
Cc Russell King <[email protected]>
Cc Daniel Lezcano <[email protected]>
Cc Catalin Marinas <[email protected]>
Cc Mark Rutland <[email protected]>
Cc Jisheng Zhang <[email protected]>
---
 arch/arm64/kernel/psci.c       |  99 +-----------------------------
 drivers/firmware/Makefile      |   2 +-
 drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++
 include/linux/psci.h           |   3 +
 4 files changed, 139 insertions(+), 98 deletions(-)
 create mode 100644 drivers/firmware/psci_cpuops.c
arch/arm64/kernel/psci.c +2 -97
index f67f35b..42816be 100644
@@ -20,7 +20,6 @@
 #include <linux/smp.h>
 #include <linux/delay.h>
 #include <linux/psci.h>
-#include <linux/slab.h>
 
 #include <uapi/linux/psci.h>
 
@@ -28,73 +27,6 @@
 #include <asm/cpu_ops.h>
 #include <asm/errno.h>
 #include <asm/smp_plat.h>
-#include <asm/suspend.h>
-
-static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
-
-static int __maybe_unused cpu_psci_cpu_init_idle(unsigned int cpu)
-{
-	int i, ret, count = 0;
-	u32 *psci_states;
-	struct device_node *state_node, *cpu_node;
-
-	cpu_node = of_get_cpu_node(cpu, NULL);
-	if (!cpu_node)
-		return -ENODEV;
-
-	/*
-	 * If the PSCI cpu_suspend function hook has not been initialized
-	 * idle states must not be enabled, so bail out
-	 */
-	if (!psci_ops.cpu_suspend)
-		return -EOPNOTSUPP;
-
-	/* Count idle states */
-	while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
-					      count))) {
-		count++;
-		of_node_put(state_node);
-	}
-
-	if (!count)
-		return -ENODEV;
-
-	psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
-	if (!psci_states)
-		return -ENOMEM;
-
-	for (i = 0; i < count; i++) {
-		u32 state;
-
-		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
-
-		ret = of_property_read_u32(state_node,
-					   "arm,psci-suspend-param",
-					   &state);
-		if (ret) {
-			pr_warn(" * %s missing arm,psci-suspend-param property\n",
-				state_node->full_name);
-			of_node_put(state_node);
-			goto free_mem;
-		}
-
-		of_node_put(state_node);
-		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;
-	return 0;
-
-free_mem:
-	kfree(psci_states);
-	return ret;
-}
 
 static int __init cpu_psci_cpu_init(unsigned int cpu)
 {
@@ -178,38 +110,11 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
 }
 #endif
 
-static int psci_suspend_finisher(unsigned long index)
-{
-	u32 *state = __this_cpu_read(psci_power_state);
-
-	return psci_ops.cpu_suspend(state[index - 1],
-				    virt_to_phys(cpu_resume));
-}
-
-static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index)
-{
-	int ret;
-	u32 *state = __this_cpu_read(psci_power_state);
-	/*
-	 * idle state index 0 corresponds to wfi, should never be called
-	 * from the cpu_suspend operations
-	 */
-	if (WARN_ON_ONCE(!index))
-		return -EINVAL;
-
-	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);
-
-	return ret;
-}
-
 const struct cpu_operations cpu_psci_ops = {
 	.name		= "psci",
 #ifdef CONFIG_CPU_IDLE
-	.cpu_init_idle	= cpu_psci_cpu_init_idle,
-	.cpu_suspend	= cpu_psci_cpu_suspend,
+	.cpu_init_idle	= psci_cpu_init_idle,
+	.cpu_suspend	= psci_cpu_suspend_enter,
 #endif
 	.cpu_init	= cpu_psci_cpu_init,
 	.cpu_prepare	= cpu_psci_cpu_prepare,
drivers/firmware/Makefile +1 -1
index 000830f..77553ab 100644
@@ -1,7 +1,7 @@
 #
 # Makefile for the linux kernel.
 #
-obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o
+obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o psci_cpuops.o
 obj-$(CONFIG_DMI)		+= dmi_scan.o
 obj-$(CONFIG_DMI_SYSFS)		+= dmi-sysfs.o
 obj-$(CONFIG_EDD)		+= edd.o
drivers/firmware/psci_cpuops.c new file +133 -0

133 lines not on this page · raw message

include/linux/psci.h +3 -0
index 12c4865..393efe2 100644
@@ -24,6 +24,9 @@ bool psci_tos_resident_on(int cpu);
 bool psci_power_state_loses_context(u32 state);
 bool psci_power_state_is_valid(u32 state);
 
+int psci_cpu_init_idle(unsigned int cpu);
+int psci_cpu_suspend_enter(unsigned long index);
+
 struct psci_operations {
 	int (*cpu_suspend)(u32 state, unsigned long entry_point);
 	int (*cpu_off)(u32 state);
Signature · 1 line
2.5.1
maintainer
#6 lore raw

PATCH v2 2/2 ARM64: kernel: PSCI: move PSCI idle management code to drivers/firmware

Hi Lorenzo,

Quoted 27 lines · Lorenzo Pieralisi

ARM64 PSCI kernel interfaces that initialize idle states and implement the suspend API to enter them are generic and can be shared with the ARM architecture.

To achieve that goal, this patch moves ARM64 PSCI idle management code to drivers/firmware by creating a file that contains PSCI helper functions implementing the common kernel interface required by ARM and ARM64 to share the PSCI idle management code.

The ARM generic CPUidle implementation also requires the definition of a cpuidle_ops section entry for the kernel to initialize the CPUidle operations at boot based on the enable-method (ie ARM64 has the statically initialized cpu_ops counterparts for that purpose); therefore this patch also adds the required section entry on CONFIG_ARM for PSCI so that the kernel can initialize the PSCI CPUidle back-end when PSCI is the probed enable-method.

On ARM64 this patch provides no functional change.

Cc Will Deacon <[email protected]>
Cc Sudeep Holla <[email protected]>
Cc Russell King <[email protected]>
Cc Daniel Lezcano <[email protected]>
Cc Catalin Marinas <[email protected]>
Cc Mark Rutland <[email protected]>
Cc Jisheng Zhang <[email protected]>
Quoted 4 lines
---
 arch/arm64/kernel/psci.c       |  99 +-----------------------------
 drivers/firmware/Makefile      |   2 +-
 drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++

Do we really need the new file, given most of this lived happily in psci.c previously?

drivers/firmware/psci_cpuops.c line 133

Quoted 8 lines
drivers/firmware/psci_cpuops.c new file +8 -0
+#ifdef CONFIG_ARM
+struct cpuidle_ops psci_cpuidle_ops __initdata = {
+	.suspend = psci_cpu_suspend_enter,
+	.init = psci_dt_cpu_init_idle,
+};
+
+CPUIDLE_METHOD_OF_DECLARE(psci, "arm,psci", &psci_cpuidle_ops);
+#endif

Don't these also need to be guarded for CONFIG_CPU_IDLE?

The definitions of cpuidle_ops and CPUIDLE_METHOD_OF_DECLARE in arch/arm/include/asm/cpuidle.h depend on it.

Otherwise this looks fine to me.

Thanks,
Mark.

#7 lore raw

PATCH v2 2/2 ARM64: kernel: PSCI: move PSCI idle management code to drivers/firmware

Hi Mark,

Quoted 35 lines · Mark Rutland

Hi Lorenzo,

Quoted 27 lines · Lorenzo Pieralisi

ARM64 PSCI kernel interfaces that initialize idle states and implement the suspend API to enter them are generic and can be shared with the ARM architecture.

To achieve that goal, this patch moves ARM64 PSCI idle management code to drivers/firmware by creating a file that contains PSCI helper functions implementing the common kernel interface required by ARM and ARM64 to share the PSCI idle management code.

The ARM generic CPUidle implementation also requires the definition of a cpuidle_ops section entry for the kernel to initialize the CPUidle operations at boot based on the enable-method (ie ARM64 has the statically initialized cpu_ops counterparts for that purpose); therefore this patch also adds the required section entry on CONFIG_ARM for PSCI so that the kernel can initialize the PSCI CPUidle back-end when PSCI is the probed enable-method.

On ARM64 this patch provides no functional change.

Cc Will Deacon <[email protected]>
Cc Sudeep Holla <[email protected]>
Cc Russell King <[email protected]>
Cc Daniel Lezcano <[email protected]>
Cc Catalin Marinas <[email protected]>
Cc Mark Rutland <[email protected]>
Cc Jisheng Zhang <[email protected]>
Quoted 4 lines
---
 arch/arm64/kernel/psci.c       |  99 +-----------------------------
 drivers/firmware/Makefile      |   2 +-
 drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++
Quoted 2 lines

Do we really need the new file, given most of this lived happily in psci.c previously?

No, I thought we could separate the PSCI FW API (eg psci_cpu_suspend()) from helper functions that are basically a kernel glue layer (but we have already helper functions in psci.c like psci_tos_resident_on() so..), if we think it is fine to keep them in the same file I can move the functions to psci.c.

Quoted 11 lines

drivers/firmware/psci_cpuops.c line 133

Quoted 8 lines
drivers/firmware/psci_cpuops.c new file +8 -0
+#ifdef CONFIG_ARM
+struct cpuidle_ops psci_cpuidle_ops __initdata = {
+	.suspend = psci_cpu_suspend_enter,
+	.init = psci_dt_cpu_init_idle,
+};
+
+CPUIDLE_METHOD_OF_DECLARE(psci, "arm,psci", &psci_cpuidle_ops);
+#endif

Don't these also need to be guarded for CONFIG_CPU_IDLE?

Quoted 2 lines

The definitions of cpuidle_ops and CPUIDLE_METHOD_OF_DECLARE in arch/arm/include/asm/cpuidle.h depend on it.

Not really, they are not guarded, the side effect of not having a CONFIG_CPU_IDLE guard is just a struct that is compiled in and freed after boot, I thought about that but I am tempted to leave it as is to avoid further ifdeffery, I am not fussed either way.

Quoted 1 line

Otherwise this looks fine to me.

Great, I will prepare a v3 shortly.

Thanks !
Lorenzo

maintainer
#8 lore raw

PATCH v2 2/2 ARM64: kernel: PSCI: move PSCI idle management code to drivers/firmware

Quoted 38 lines · Lorenzo Pieralisi

Hi Mark,

Quoted 35 lines · Mark Rutland

Hi Lorenzo,

Quoted 31 lines · Lorenzo Pieralisi

ARM64 PSCI kernel interfaces that initialize idle states and implement the suspend API to enter them are generic and can be shared with the ARM architecture.

To achieve that goal, this patch moves ARM64 PSCI idle management code to drivers/firmware by creating a file that contains PSCI helper functions implementing the common kernel interface required by ARM and ARM64 to share the PSCI idle management code.

The ARM generic CPUidle implementation also requires the definition of a cpuidle_ops section entry for the kernel to initialize the CPUidle operations at boot based on the enable-method (ie ARM64 has the statically initialized cpu_ops counterparts for that purpose); therefore this patch also adds the required section entry on CONFIG_ARM for PSCI so that the kernel can initialize the PSCI CPUidle back-end when PSCI is the probed enable-method.

On ARM64 this patch provides no functional change.

Cc Will Deacon <[email protected]>
Cc Sudeep Holla <[email protected]>
Cc Russell King <[email protected]>
Cc Daniel Lezcano <[email protected]>
Cc Catalin Marinas <[email protected]>
Cc Mark Rutland <[email protected]>
Cc Jisheng Zhang <[email protected]>
---
 arch/arm64/kernel/psci.c       |  99 +-----------------------------
 drivers/firmware/Makefile      |   2 +-
 drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++
Quoted 8 lines
Quoted 2 lines

Do we really need the new file, given most of this lived happily in psci.c previously?

No, I thought we could separate the PSCI FW API (eg psci_cpu_suspend()) from helper functions that are basically a kernel glue layer (but we have already helper functions in psci.c like psci_tos_resident_on() so..), if we think it is fine to keep them in the same file I can move the functions to psci.c.

Ok. I guess I don't have strong feelings either way, but it seemed simpler to keep them in the same file for now.

I understand your rationale, so either way I'm happy.

Quoted 11 lines
Quoted 11 lines

drivers/firmware/psci_cpuops.c line 133

Quoted 8 lines
drivers/firmware/psci_cpuops.c new file +8 -0
+#ifdef CONFIG_ARM
+struct cpuidle_ops psci_cpuidle_ops __initdata = {
+	.suspend = psci_cpu_suspend_enter,
+	.init = psci_dt_cpu_init_idle,
+};
+
+CPUIDLE_METHOD_OF_DECLARE(psci, "arm,psci", &psci_cpuidle_ops);
+#endif

Don't these also need to be guarded for CONFIG_CPU_IDLE?

Quoted 7 lines
Quoted 2 lines

The definitions of cpuidle_ops and CPUIDLE_METHOD_OF_DECLARE in arch/arm/include/asm/cpuidle.h depend on it.

Not really, they are not guarded, the side effect of not having a CONFIG_CPU_IDLE guard is just a struct that is compiled in and freed after boot, I thought about that but I am tempted to leave it as is to avoid further ifdeffery, I am not fussed either way.

Whoops, I misread the gurards in arch/arm/include/asm/cpuidle.h. Sorry for the noise!

Given the above, for this or a version with just psci.c:

Thanks,
Mark.

maintainer
#9 lore raw

PATCH v2 2/2 ARM64: kernel: PSCI: move PSCI idle management code to drivers/firmware

In reply to Lorenzo Pieralisi
Quoted 27 lines · Lorenzo Pieralisi

ARM64 PSCI kernel interfaces that initialize idle states and implement the suspend API to enter them are generic and can be shared with the ARM architecture.

To achieve that goal, this patch moves ARM64 PSCI idle management code to drivers/firmware by creating a file that contains PSCI helper functions implementing the common kernel interface required by ARM and ARM64 to share the PSCI idle management code.

The ARM generic CPUidle implementation also requires the definition of a cpuidle_ops section entry for the kernel to initialize the CPUidle operations at boot based on the enable-method (ie ARM64 has the statically initialized cpu_ops counterparts for that purpose); therefore this patch also adds the required section entry on CONFIG_ARM for PSCI so that the kernel can initialize the PSCI CPUidle back-end when PSCI is the probed enable-method.

On ARM64 this patch provides no functional change.

Cc Will Deacon <[email protected]>
Cc Sudeep Holla <[email protected]>
Cc Russell King <[email protected]>
Cc Daniel Lezcano <[email protected]>
Cc Catalin Marinas <[email protected]>
Cc Mark Rutland <[email protected]>
Cc Jisheng Zhang <[email protected]>
Quoted 5 lines
---
 arch/arm64/kernel/psci.c       |  99 +-----------------------------
 drivers/firmware/Makefile      |   2 +-
 drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++
 include/linux/psci.h           |   3 +

For the arch/arm64 part:

#10 lore raw

v2 cover Enabling PSCI based idle on ARM 32-bit platforms

In reply to Lorenzo Pieralisi

Hi Lorenzo,

I would like to take this patch through my tree but it does not apply.

Mind to refresh it against linux-pm or v4.3-rc5 ?

-- Daniel

Quoted 59 lines · Lorenzo Pieralisi

This patch series is v2 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373756.html

v1->v2:

- Refactored patch 1 to remove cpu parameter from cpuidle_ops suspend hook
- Refactored psci_cpu_init_idle to stub out dt parsing function and make it usable on both ARM/ARM64 with no additional changes
- Updated ARM cpuidle_ops to new interfaces
- Fixed PSCI enable method string in ARM cpuidle_ops struct

PSCI firmware provides a kernel API that, through a standard interface, allows to manage power states transitions in a seamless manner for ARM and ARM64 systems.

Current PSCI code that initializes CPUidle states on PSCI based systems lives in arch/arm64 directory but it is not ARM64 specific and can be shared with ARM 32-bit systems so that the generic ARM CPUidle driver can leverage the common PSCI interface.

This patch series moves PSCI CPUidle management code to drivers/firmware directory so that ARM and ARM64 architecture can actually share the code.

It is made up of two patches:

Patch 1 refactors ARM 32-bit generic idle implementation to remove the cpu parameter from the cpuidle_ops suspend hook, in preparation for a common PSCI implementation for ARM/ARM64 PSCI idle.

Patch 2 moves ARM64 PSCI CPUidle functions implementation to drivers/firmware so that it can be shared with ARM 32-bit platforms code. This patch also adds a PSCI entry section on ARM 32-bit systems so that the PSCI CPUidle back-end can be enabled when the enable-method corresponds to PSCI.

Patches apply on top of current patch stack to enable PSCI 1.0:

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git tags/firmware/psci-1.0

Tested on Juno board (ARM64), compile tested only on ARM 32-bit systems.

Lorenzo Pieralisi (2):
ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook
ARM64: kernel: PSCI: move PSCI idle management code to
drivers/firmware

  arch/arm/include/asm/cpuidle.h |   2 +-
  arch/arm/kernel/cpuidle.c      |   2 +-
  arch/arm64/kernel/psci.c       |  99 +-----------------------------
  drivers/firmware/Makefile      |   2 +-
  drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++
  drivers/soc/qcom/spm.c         |  10 ++--
  include/linux/psci.h           |   3 +
  7 files changed, 146 insertions(+), 105 deletions(-)

create mode 100644 drivers/firmware/psci_cpuops.c

Signature · 5 lines
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#11 lore raw

v2 cover Enabling PSCI based idle on ARM 32-bit platforms

Hi Daniel,

Quoted 4 lines · Daniel Lezcano

Hi Lorenzo,

I would like to take this patch through my tree but it does not apply.

That's because as I mentioned in the cover letter the series is built on top of:

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git tags/firmware/psci-1.0

Hopefully this tag will soon get pulled in arm-soc, I will respin a v3 anyway to add tags and fold psci_cpuops.c in psci.c, how do you want to merge this then ?

Thanks,
Lorenzo

Quoted 75 lines

Mind to refresh it against linux-pm or v4.3-rc5 ?

-- Daniel

Quoted 59 lines · Lorenzo Pieralisi

This patch series is v2 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373756.html

v1->v2:

- Refactored patch 1 to remove cpu parameter from cpuidle_ops suspend hook
- Refactored psci_cpu_init_idle to stub out dt parsing function and make it usable on both ARM/ARM64 with no additional changes
- Updated ARM cpuidle_ops to new interfaces
- Fixed PSCI enable method string in ARM cpuidle_ops struct

PSCI firmware provides a kernel API that, through a standard interface, allows to manage power states transitions in a seamless manner for ARM and ARM64 systems.

Current PSCI code that initializes CPUidle states on PSCI based systems lives in arch/arm64 directory but it is not ARM64 specific and can be shared with ARM 32-bit systems so that the generic ARM CPUidle driver can leverage the common PSCI interface.

This patch series moves PSCI CPUidle management code to drivers/firmware directory so that ARM and ARM64 architecture can actually share the code.

It is made up of two patches:

Patch 1 refactors ARM 32-bit generic idle implementation to remove the cpu parameter from the cpuidle_ops suspend hook, in preparation for a common PSCI implementation for ARM/ARM64 PSCI idle.

Patch 2 moves ARM64 PSCI CPUidle functions implementation to drivers/firmware so that it can be shared with ARM 32-bit platforms code. This patch also adds a PSCI entry section on ARM 32-bit systems so that the PSCI CPUidle back-end can be enabled when the enable-method corresponds to PSCI.

Patches apply on top of current patch stack to enable PSCI 1.0:

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git tags/firmware/psci-1.0

Tested on Juno board (ARM64), compile tested only on ARM 32-bit systems.

Lorenzo Pieralisi (2):
ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook
ARM64: kernel: PSCI: move PSCI idle management code to
drivers/firmware

 arch/arm/include/asm/cpuidle.h |   2 +-
 arch/arm/kernel/cpuidle.c      |   2 +-
 arch/arm64/kernel/psci.c       |  99 +-----------------------------
 drivers/firmware/Makefile      |   2 +-
 drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++
 drivers/soc/qcom/spm.c         |  10 ++--
 include/linux/psci.h           |   3 +
 7 files changed, 146 insertions(+), 105 deletions(-)
 create mode 100644 drivers/firmware/psci_cpuops.c
Signature · 5 lines
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#12 lore raw

v2 cover Enabling PSCI based idle on ARM 32-bit platforms

Quoted 8 lines · Lorenzo Pieralisi

Hi Daniel,

Quoted 4 lines · Daniel Lezcano

Hi Lorenzo,

I would like to take this patch through my tree but it does not apply.

Quoted 8 lines

That's because as I mentioned in the cover letter the series is built on top of:

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git tags/firmware/psci-1.0

Hopefully this tag will soon get pulled in arm-soc, I will respin a v3 anyway to add tags and fold psci_cpuops.c in psci.c, how do you want to merge this then ?

May be you can create a branch with your modifications to be shared with arm-soc and me ?

Quoted 74 lines
Quoted 74 lines

Mind to refresh it against linux-pm or v4.3-rc5 ?

-- Daniel

Quoted 57 lines · Lorenzo Pieralisi

This patch series is v2 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373756.html

v1->v2:

- Refactored patch 1 to remove cpu parameter from cpuidle_ops suspend hook
- Refactored psci_cpu_init_idle to stub out dt parsing function and make it usable on both ARM/ARM64 with no additional changes
- Updated ARM cpuidle_ops to new interfaces
- Fixed PSCI enable method string in ARM cpuidle_ops struct

PSCI firmware provides a kernel API that, through a standard interface, allows to manage power states transitions in a seamless manner for ARM and ARM64 systems.

Current PSCI code that initializes CPUidle states on PSCI based systems lives in arch/arm64 directory but it is not ARM64 specific and can be shared with ARM 32-bit systems so that the generic ARM CPUidle driver can leverage the common PSCI interface.

This patch series moves PSCI CPUidle management code to drivers/firmware directory so that ARM and ARM64 architecture can actually share the code.

It is made up of two patches:

Patch 1 refactors ARM 32-bit generic idle implementation to remove the cpu parameter from the cpuidle_ops suspend hook, in preparation for a common PSCI implementation for ARM/ARM64 PSCI idle.

Patch 2 moves ARM64 PSCI CPUidle functions implementation to drivers/firmware so that it can be shared with ARM 32-bit platforms code. This patch also adds a PSCI entry section on ARM 32-bit systems so that the PSCI CPUidle back-end can be enabled when the enable-method corresponds to PSCI.

Patches apply on top of current patch stack to enable PSCI 1.0:

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git tags/firmware/psci-1.0

Tested on Juno board (ARM64), compile tested only on ARM 32-bit systems.

Lorenzo Pieralisi (2):
ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook
ARM64: kernel: PSCI: move PSCI idle management code to
drivers/firmware

  arch/arm/include/asm/cpuidle.h |   2 +-
  arch/arm/kernel/cpuidle.c      |   2 +-
  arch/arm64/kernel/psci.c       |  99 +-----------------------------
  drivers/firmware/Makefile      |   2 +-
  drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++
  drivers/soc/qcom/spm.c         |  10 ++--
  include/linux/psci.h           |   3 +
  7 files changed, 146 insertions(+), 105 deletions(-)
Quoted 2 lines

create mode 100644 drivers/firmware/psci_cpuops.c

--
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

Signature · 5 lines
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#13 lore raw

v2 cover Enabling PSCI based idle on ARM 32-bit platforms

Hi Daniel, Arnd,

Quoted 12 lines · Daniel Lezcano
Quoted 11 lines · Lorenzo Pieralisi

Hi Daniel,

Quoted 4 lines · Daniel Lezcano

Hi Lorenzo,

I would like to take this patch through my tree but it does not apply.

That's because as I mentioned in the cover letter the series is built on top of:

Quoted 8 lines
Quoted 5 lines

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git tags/firmware/psci-1.0

Hopefully this tag will soon get pulled in arm-soc, I will respin a v3 anyway to add tags and fold psci_cpuops.c in psci.c, how do you want to merge this then ?

May be you can create a branch with your modifications to be shared with arm-soc and me ?

I asked Arnd to create an immutable branch containing the patches in my pull request below in arm-soc:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/374547.html

I can then resend v3 of this series on top of it, or if you prefer I will send you a pull request (to a branch based on the arm-soc one with my patches on top) just let me know.

Thanks !
Lorenzo

Quoted 83 lines
Quoted 74 lines
Quoted 74 lines

Mind to refresh it against linux-pm or v4.3-rc5 ?

-- Daniel

Quoted 49 lines · Lorenzo Pieralisi

This patch series is v2 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373756.html

v1->v2:

- Refactored patch 1 to remove cpu parameter from cpuidle_ops suspend hook
- Refactored psci_cpu_init_idle to stub out dt parsing function and make it usable on both ARM/ARM64 with no additional changes
- Updated ARM cpuidle_ops to new interfaces
- Fixed PSCI enable method string in ARM cpuidle_ops struct

PSCI firmware provides a kernel API that, through a standard interface, allows to manage power states transitions in a seamless manner for ARM and ARM64 systems.

Current PSCI code that initializes CPUidle states on PSCI based systems lives in arch/arm64 directory but it is not ARM64 specific and can be shared with ARM 32-bit systems so that the generic ARM CPUidle driver can leverage the common PSCI interface.

This patch series moves PSCI CPUidle management code to drivers/firmware directory so that ARM and ARM64 architecture can actually share the code.

It is made up of two patches:

Patch 1 refactors ARM 32-bit generic idle implementation to remove the cpu parameter from the cpuidle_ops suspend hook, in preparation for a common PSCI implementation for ARM/ARM64 PSCI idle.

Patch 2 moves ARM64 PSCI CPUidle functions implementation to drivers/firmware so that it can be shared with ARM 32-bit platforms code. This patch also adds a PSCI entry section on ARM 32-bit systems so that the PSCI CPUidle back-end can be enabled when the enable-method corresponds to PSCI.

Patches apply on top of current patch stack to enable PSCI 1.0:

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git tags/firmware/psci-1.0

Tested on Juno board (ARM64), compile tested only on ARM 32-bit systems.

Lorenzo Pieralisi (2):
ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook
ARM64: kernel: PSCI: move PSCI idle management code to
drivers/firmware

Quoted 10 lines
 arch/arm/include/asm/cpuidle.h |   2 +-
 arch/arm/kernel/cpuidle.c      |   2 +-
 arch/arm64/kernel/psci.c       |  99 +-----------------------------
 drivers/firmware/Makefile      |   2 +-
 drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++
 drivers/soc/qcom/spm.c         |  10 ++--
 include/linux/psci.h           |   3 +
 7 files changed, 146 insertions(+), 105 deletions(-)
 create mode 100644 drivers/firmware/psci_cpuops.c

--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

Signature · 5 lines
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#14 lore raw

v2 cover Enabling PSCI based idle on ARM 32-bit platforms

In reply to Lorenzo Pieralisi

Dear Lorenzo,

Quoted 40 lines · On Mon, 12 Oct 2015 12:17:06 +0100 Lorenzo Pieralisi…

This patch series is v2 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373756.html

v1->v2:

- Refactored patch 1 to remove cpu parameter from cpuidle_ops suspend hook
- Refactored psci_cpu_init_idle to stub out dt parsing function and make it usable on both ARM/ARM64 with no additional changes
- Updated ARM cpuidle_ops to new interfaces
- Fixed PSCI enable method string in ARM cpuidle_ops struct

PSCI firmware provides a kernel API that, through a standard interface, allows to manage power states transitions in a seamless manner for ARM and ARM64 systems.

Current PSCI code that initializes CPUidle states on PSCI based systems lives in arch/arm64 directory but it is not ARM64 specific and can be shared with ARM 32-bit systems so that the generic ARM CPUidle driver can leverage the common PSCI interface.

This patch series moves PSCI CPUidle management code to drivers/firmware directory so that ARM and ARM64 architecture can actually share the code.

It is made up of two patches:

Patch 1 refactors ARM 32-bit generic idle implementation to remove the cpu parameter from the cpuidle_ops suspend hook, in preparation for a common PSCI implementation for ARM/ARM64 PSCI idle.

Patch 2 moves ARM64 PSCI CPUidle functions implementation to drivers/firmware so that it can be shared with ARM 32-bit platforms code. This patch also adds a PSCI entry section on ARM 32-bit systems so that the PSCI CPUidle back-end can be enabled when the enable-method corresponds to PSCI.

Patches apply on top of current patch stack to enable PSCI 1.0:

Quoted 8 lines

git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git tags/firmware/psci-1.0

Tested on Juno board (ARM64), compile tested only on ARM 32-bit systems.

Lorenzo Pieralisi (2):
ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook
ARM64: kernel: PSCI: move PSCI idle management code to
drivers/firmware

I did a simple test, it works ARM 32 PSCI system

So for this series except the qcom changes (I have no qcom platform), feel free to add

I also could simple test v3 when it is out.

thanks a lot for these patches!

Quoted 11 lines
 arch/arm/include/asm/cpuidle.h |   2 +-
 arch/arm/kernel/cpuidle.c      |   2 +-
 arch/arm64/kernel/psci.c       |  99 +-----------------------------
 drivers/firmware/Makefile      |   2 +-
 drivers/firmware/psci_cpuops.c | 133 +++++++++++++++++++++++++++++++++++++++++
 drivers/soc/qcom/spm.c         |  10 ++--
 include/linux/psci.h           |   3 +
 7 files changed, 146 insertions(+), 105 deletions(-)
 create mode 100644 drivers/firmware/psci_cpuops.c