* [PATCH master 1/4] ARM: psci: of: fixup only version if node already exists
2022-11-01 6:26 [PATCH master 0/4] ARM: psci: client: unbreak hypervisor boot Ahmad Fatoum
@ 2022-11-01 6:26 ` Ahmad Fatoum
2022-11-01 6:26 ` [PATCH master 2/4] ARM: psci: client: match most specific compatible first Ahmad Fatoum
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Ahmad Fatoum @ 2022-11-01 6:26 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
When barebox is booted as QEMU -kernel, PSCI will have method = "hvc",
because QEMU will act as Hypervisor. barebox handles this correctly and
will use hvc instead of smc, but of_psci_fixup() always fixes up
method = "smc" thereby breaking kernel boot.
Fix this by only updating version if the node already exists and
omitting everything else.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/cpu/psci-of.c | 39 +++++++++++++++++++++++----------------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/psci-of.c b/arch/arm/cpu/psci-of.c
index ef83b0edee69..e08a04b36d05 100644
--- a/arch/arm/cpu/psci-of.c
+++ b/arch/arm/cpu/psci-of.c
@@ -7,16 +7,10 @@
#include <asm/psci.h>
#include <linux/arm-smccc.h>
-int of_psci_fixup(struct device_node *root, unsigned long psci_version)
+static int of_psci_version_fixup(struct device_node *psci,
+ unsigned long psci_version)
{
- struct device_node *psci;
- int ret;
const char *compat;
- struct device_node *cpus, *cpu;
-
- psci = of_create_node(root, "/psci");
- if (!psci)
- return -EINVAL;
if (psci_version >= ARM_PSCI_VER_1_0) {
compat = "arm,psci-1.0";
@@ -27,6 +21,27 @@ int of_psci_fixup(struct device_node *root, unsigned long psci_version)
return -EINVAL;
}
+ return of_property_write_string(psci, "compatible", compat);
+}
+
+int of_psci_fixup(struct device_node *root, unsigned long psci_version)
+{
+ struct device_node *psci;
+ int ret;
+ struct device_node *cpus, *cpu;
+
+ psci = of_find_node_by_path_from(root, "/psci");
+ if (psci)
+ return of_psci_version_fixup(psci, psci_version);
+
+ psci = of_create_node(root, "/psci");
+ if (!psci)
+ return -EINVAL;
+
+ ret = of_property_write_string(psci, "method", "smc");
+ if (ret)
+ return ret;
+
cpus = of_find_node_by_path_from(root, "/cpus");
if (!cpus) {
pr_err("Cannot find /cpus node, PSCI fixup aborting\n");
@@ -42,13 +57,5 @@ int of_psci_fixup(struct device_node *root, unsigned long psci_version)
pr_debug("Fixed %s\n", cpu->full_name);
}
- ret = of_property_write_string(psci, "compatible", compat);
- if (ret)
- return ret;
-
- ret = of_property_write_string(psci, "method", "smc");
- if (ret)
- return ret;
-
return 0;
}
--
2.30.2
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH master 2/4] ARM: psci: client: match most specific compatible first
2022-11-01 6:26 [PATCH master 0/4] ARM: psci: client: unbreak hypervisor boot Ahmad Fatoum
2022-11-01 6:26 ` [PATCH master 1/4] ARM: psci: of: fixup only version if node already exists Ahmad Fatoum
@ 2022-11-01 6:26 ` Ahmad Fatoum
2022-11-01 6:26 ` [PATCH master 3/4] ARM: psci: client: always register OF fixup Ahmad Fatoum
2022-11-01 6:26 ` [PATCH master 4/4] ARM: psci: keep older PSCI versions in compatible fixup Ahmad Fatoum
3 siblings, 0 replies; 5+ messages in thread
From: Ahmad Fatoum @ 2022-11-01 6:26 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The PSCI client driver will use the barebox compatible to determine
whether it's safe to use the ARM_PSCI_0_2_FN_PSCI_VERSION command.
For this reason, we need to match against the newer PSCI compatibles
first, because otherwise
compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
would have us end up with PSCI v0.1 instead.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/cpu/psci-client.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/psci-client.c b/arch/arm/cpu/psci-client.c
index 7d5b3768b59e..8e151177c2d7 100644
--- a/arch/arm/cpu/psci-client.c
+++ b/arch/arm/cpu/psci-client.c
@@ -176,9 +176,9 @@ static int __init psci_probe(struct device_d *dev)
}
static __maybe_unused struct of_device_id psci_dt_ids[] = {
- { .compatible = "arm,psci", .data = (void*)ARM_PSCI_VER(0,1) },
- { .compatible = "arm,psci-0.2", .data = (void*)ARM_PSCI_VER(0,2) },
{ .compatible = "arm,psci-1.0", .data = (void*)ARM_PSCI_VER(1,0) },
+ { .compatible = "arm,psci-0.2", .data = (void*)ARM_PSCI_VER(0,2) },
+ { .compatible = "arm,psci", .data = (void*)ARM_PSCI_VER(0,1) },
{ /* sentinel */ },
};
--
2.30.2
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH master 3/4] ARM: psci: client: always register OF fixup
2022-11-01 6:26 [PATCH master 0/4] ARM: psci: client: unbreak hypervisor boot Ahmad Fatoum
2022-11-01 6:26 ` [PATCH master 1/4] ARM: psci: of: fixup only version if node already exists Ahmad Fatoum
2022-11-01 6:26 ` [PATCH master 2/4] ARM: psci: client: match most specific compatible first Ahmad Fatoum
@ 2022-11-01 6:26 ` Ahmad Fatoum
2022-11-01 6:26 ` [PATCH master 4/4] ARM: psci: keep older PSCI versions in compatible fixup Ahmad Fatoum
3 siblings, 0 replies; 5+ messages in thread
From: Ahmad Fatoum @ 2022-11-01 6:26 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
We currently only register the device tree fixup if PSCI version in
device tree disagrees with version read from firmware. The barebox
PSCI DT version may differ from the kernel version though, so we
should rather run the fixup always. If the kernel has already an
up-to-date compatible, it won't change. But for cases where firmware is
expected to fill out the correct PSCI version, barebox will do what's
expected.
While at it, move the of_version logic together to make it easier
to follow.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/cpu/psci-client.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/arch/arm/cpu/psci-client.c b/arch/arm/cpu/psci-client.c
index 8e151177c2d7..218170dfa4ba 100644
--- a/arch/arm/cpu/psci-client.c
+++ b/arch/arm/cpu/psci-client.c
@@ -119,10 +119,6 @@ static int __init psci_probe(struct device_d *dev)
ulong of_version, actual_version;
int ret;
- ret = dev_get_drvdata(dev, (const void **)&of_version);
- if (ret)
- return -ENODEV;
-
ret = of_property_read_string(dev->device_node, "method", &method);
if (ret) {
dev_warn(dev, "missing \"method\" property\n");
@@ -139,6 +135,7 @@ static int __init psci_probe(struct device_d *dev)
}
+ of_version = (ulong)device_get_match_data(dev);
if (of_version < ARM_PSCI_VER(0,2)) {
version = of_version;
@@ -155,8 +152,7 @@ static int __init psci_probe(struct device_d *dev)
dev_info(dev, "detected version %u.%u\n",
version >> 16, version & 0xffff);
- if (actual_version != of_version)
- of_register_fixup(of_psci_do_fixup, &version);
+ of_register_fixup(of_psci_do_fixup, &version);
ret = poweroff_handler_register_fn(psci_poweroff);
if (ret)
--
2.30.2
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH master 4/4] ARM: psci: keep older PSCI versions in compatible fixup
2022-11-01 6:26 [PATCH master 0/4] ARM: psci: client: unbreak hypervisor boot Ahmad Fatoum
` (2 preceding siblings ...)
2022-11-01 6:26 ` [PATCH master 3/4] ARM: psci: client: always register OF fixup Ahmad Fatoum
@ 2022-11-01 6:26 ` Ahmad Fatoum
3 siblings, 0 replies; 5+ messages in thread
From: Ahmad Fatoum @ 2022-11-01 6:26 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The psci device tree binding mandates keeping older ARM PSCI compatibles
as less-specific compatible entries. Have the barebox fixup comply
with this.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/cpu/psci-of.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/arch/arm/cpu/psci-of.c b/arch/arm/cpu/psci-of.c
index e08a04b36d05..0d25e8b2fdb2 100644
--- a/arch/arm/cpu/psci-of.c
+++ b/arch/arm/cpu/psci-of.c
@@ -10,18 +10,16 @@
static int of_psci_version_fixup(struct device_node *psci,
unsigned long psci_version)
{
- const char *compat;
-
- if (psci_version >= ARM_PSCI_VER_1_0) {
- compat = "arm,psci-1.0";
- } else if (psci_version >= ARM_PSCI_VER_0_2) {
- compat = "arm,psci-0.2";
- } else {
- pr_err("Unsupported PSCI version %ld\n", psci_version);
- return -EINVAL;
- }
+ if (psci_version >= ARM_PSCI_VER_1_0)
+ return of_property_write_strings(psci, "compatible",
+ "arm,psci-1.0", "arm,psci-0.2", "arm,psci", NULL);
+
+ if (psci_version >= ARM_PSCI_VER_0_2)
+ return of_property_write_strings(psci, "compatible",
+ "arm,psci-0.2", "arm,psci", NULL);
- return of_property_write_string(psci, "compatible", compat);
+ pr_err("Unsupported PSCI version %ld\n", psci_version);
+ return -EINVAL;
}
int of_psci_fixup(struct device_node *root, unsigned long psci_version)
--
2.30.2
^ permalink raw reply [flat|nested] 5+ messages in thread