* [PATCH v23 01/13] power: reset: reboot-mode: Remove devres based allocations
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:29 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 02/13] power: reset: reboot-mode: Support up to 3 magic values per mode Shivendra Pratap
` (11 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla, Sebastian Reichel, Bartosz Golaszewski
Devres APIs are intended for use in drivers, where the managed lifetime
of resources is tied directly to the driver attach/detach cycle. In
shared subsystem code, there is no guarantee that the subsystem
functions will only be called after a driver has been attached, nor that
they will not be referenced after the managed resources have been
released during driver detach.
To ensure correct lifetime handling, avoid using devres-based
allocations in the reboot-mode and explicitly handle allocation and
cleanup of resources.
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
drivers/power/reset/reboot-mode.c | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
index d20e44db0532..7a74f72a8313 100644
--- a/drivers/power/reset/reboot-mode.c
+++ b/drivers/power/reset/reboot-mode.c
@@ -3,6 +3,8 @@
* Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
*/
+#define pr_fmt(fmt) "reboot-mode: " fmt
+
#include <linux/device.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -10,6 +12,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/property.h>
#include <linux/reboot.h>
#include <linux/reboot-mode.h>
#include <linux/slab.h>
@@ -168,10 +171,11 @@ static int reboot_mode_create_device(struct reboot_mode_driver *reboot)
*/
int reboot_mode_register(struct reboot_mode_driver *reboot)
{
- struct mode_info *info;
+ struct mode_info *info = NULL;
struct property *prop;
struct device_node *np = reboot->dev->of_node;
size_t len = strlen(PREFIX);
+ u32 magic;
int ret;
INIT_LIST_HEAD(&reboot->head);
@@ -180,19 +184,18 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
if (strncmp(prop->name, PREFIX, len))
continue;
- info = devm_kzalloc(reboot->dev, sizeof(*info), GFP_KERNEL);
+ if (device_property_read_u32(reboot->dev, prop->name, &magic)) {
+ pr_debug("reboot mode %s without magic number\n", prop->name);
+ continue;
+ }
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
ret = -ENOMEM;
goto error;
}
- if (of_property_read_u32(np, prop->name, &info->magic)) {
- dev_err(reboot->dev, "reboot mode %s without magic number\n",
- info->mode);
- devm_kfree(reboot->dev, info);
- continue;
- }
-
+ info->magic = magic;
info->mode = kstrdup_const(prop->name + len, GFP_KERNEL);
if (!info->mode) {
ret = -ENOMEM;
@@ -200,12 +203,12 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
} else if (info->mode[0] == '\0') {
kfree_const(info->mode);
ret = -EINVAL;
- dev_err(reboot->dev, "invalid mode name(%s): too short!\n",
- prop->name);
+ pr_err("invalid mode name(%s): too short!\n", prop->name);
goto error;
}
list_add_tail(&info->list, &reboot->head);
+ info = NULL;
}
reboot->reboot_notifier.notifier_call = reboot_mode_notify;
@@ -218,6 +221,7 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
return 0;
error:
+ kfree(info);
reboot_mode_unregister(reboot);
return ret;
}
@@ -261,12 +265,16 @@ static inline void reboot_mode_unregister_device(struct reboot_mode_driver *rebo
int reboot_mode_unregister(struct reboot_mode_driver *reboot)
{
struct mode_info *info;
+ struct mode_info *next;
unregister_reboot_notifier(&reboot->reboot_notifier);
reboot_mode_unregister_device(reboot);
- list_for_each_entry(info, &reboot->head, list)
+ list_for_each_entry_safe(info, next, &reboot->head, list) {
+ list_del(&info->list);
kfree_const(info->mode);
+ kfree(info);
+ }
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v23 02/13] power: reset: reboot-mode: Support up to 3 magic values per mode
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
2026-07-14 17:16 ` [PATCH v23 01/13] power: reset: reboot-mode: Remove devres based allocations Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:30 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 03/13] power: reset: reboot-mode: Add support for predefined reboot modes Shivendra Pratap
` (10 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla
ARM PSCI vendor-specific resets, require a 32-bit reset_type and a 64-bit
cookie as arguments. This cannot be implemented via the reboot-mode
framework, which supports a single 32-bit argument as magic value.
Extend the reboot-mode framework to support up to three 32-bit arguments
as magic, per reboot-mode.
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
drivers/power/reset/nvmem-reboot-mode.c | 10 ++++----
drivers/power/reset/qcom-pon.c | 8 ++++---
drivers/power/reset/reboot-mode.c | 41 +++++++++++++++++++++-----------
drivers/power/reset/syscon-reboot-mode.c | 8 ++++---
include/linux/reboot-mode.h | 4 +++-
5 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/drivers/power/reset/nvmem-reboot-mode.c b/drivers/power/reset/nvmem-reboot-mode.c
index d260715fccf6..ac69b5f39fb4 100644
--- a/drivers/power/reset/nvmem-reboot-mode.c
+++ b/drivers/power/reset/nvmem-reboot-mode.c
@@ -17,14 +17,16 @@ struct nvmem_reboot_mode {
struct nvmem_cell *cell;
};
-static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot,
- unsigned int magic)
+static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot, u32 *magic, int count)
{
struct nvmem_reboot_mode *nvmem_rbm;
size_t buf_len;
void *buf;
int ret;
+ if (count != 1)
+ return -EINVAL;
+
nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot);
buf = nvmem_cell_read(nvmem_rbm->cell, &buf_len);
@@ -32,10 +34,10 @@ static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot,
return PTR_ERR(buf);
kfree(buf);
- if (buf_len > sizeof(magic))
+ if (buf_len > sizeof(magic[0]))
return -EINVAL;
- ret = nvmem_cell_write(nvmem_rbm->cell, &magic, buf_len);
+ ret = nvmem_cell_write(nvmem_rbm->cell, &magic[0], buf_len);
if (ret < 0)
dev_err(reboot->dev, "update reboot mode bits failed\n");
diff --git a/drivers/power/reset/qcom-pon.c b/drivers/power/reset/qcom-pon.c
index 7e108982a582..a508ab26d03f 100644
--- a/drivers/power/reset/qcom-pon.c
+++ b/drivers/power/reset/qcom-pon.c
@@ -27,17 +27,19 @@ struct qcom_pon {
long reason_shift;
};
-static int qcom_pon_reboot_mode_write(struct reboot_mode_driver *reboot,
- unsigned int magic)
+static int qcom_pon_reboot_mode_write(struct reboot_mode_driver *reboot, u32 *magic, int count)
{
struct qcom_pon *pon = container_of
(reboot, struct qcom_pon, reboot_mode);
int ret;
+ if (count != 1)
+ return -EINVAL;
+
ret = regmap_update_bits(pon->regmap,
pon->baseaddr + PON_SOFT_RB_SPARE,
GENMASK(7, pon->reason_shift),
- magic << pon->reason_shift);
+ magic[0] << pon->reason_shift);
if (ret < 0)
dev_err(pon->dev, "update reboot mode bits failed\n");
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
index 7a74f72a8313..db2129c72341 100644
--- a/drivers/power/reset/reboot-mode.c
+++ b/drivers/power/reset/reboot-mode.c
@@ -22,7 +22,8 @@
struct mode_info {
const char *mode;
- u32 magic;
+ u32 magic[3];
+ int count;
struct list_head list;
};
@@ -74,8 +75,7 @@ static const struct class reboot_mode_class = {
.dev_groups = reboot_mode_groups,
};
-static unsigned int get_reboot_mode_magic(struct reboot_mode_driver *reboot,
- const char *cmd)
+static struct mode_info *get_reboot_mode_info(struct reboot_mode_driver *reboot, const char *cmd)
{
const char *normal = "normal";
struct mode_info *info;
@@ -86,11 +86,11 @@ static unsigned int get_reboot_mode_magic(struct reboot_mode_driver *reboot,
list_for_each_entry(info, &reboot->head, list)
if (!strcmp(info->mode, cmd))
- return info->magic;
+ return info;
/* try to match again, replacing characters impossible in DT */
if (strscpy(cmd_, cmd, sizeof(cmd_)) == -E2BIG)
- return 0;
+ return NULL;
strreplace(cmd_, ' ', '-');
strreplace(cmd_, ',', '-');
@@ -98,21 +98,21 @@ static unsigned int get_reboot_mode_magic(struct reboot_mode_driver *reboot,
list_for_each_entry(info, &reboot->head, list)
if (!strcmp(info->mode, cmd_))
- return info->magic;
+ return info;
- return 0;
+ return NULL;
}
static int reboot_mode_notify(struct notifier_block *this,
unsigned long mode, void *cmd)
{
struct reboot_mode_driver *reboot;
- unsigned int magic;
+ struct mode_info *info;
reboot = container_of(this, struct reboot_mode_driver, reboot_notifier);
- magic = get_reboot_mode_magic(reboot, cmd);
- if (magic)
- reboot->write(reboot, magic);
+ info = get_reboot_mode_info(reboot, cmd);
+ if (info && info->count > 0)
+ reboot->write(reboot, info->magic, info->count);
return NOTIFY_DONE;
}
@@ -175,16 +175,22 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
struct property *prop;
struct device_node *np = reboot->dev->of_node;
size_t len = strlen(PREFIX);
- u32 magic;
+ u32 magic[3];
+ int count;
int ret;
INIT_LIST_HEAD(&reboot->head);
for_each_property_of_node(np, prop) {
+ memset(magic, 0, sizeof(magic));
+
if (strncmp(prop->name, PREFIX, len))
continue;
- if (device_property_read_u32(reboot->dev, prop->name, &magic)) {
+ count = device_property_count_u32(reboot->dev, prop->name);
+
+ if (count <= 0 || count > ARRAY_SIZE(magic) ||
+ device_property_read_u32_array(reboot->dev, prop->name, magic, count)) {
pr_debug("reboot mode %s without magic number\n", prop->name);
continue;
}
@@ -195,7 +201,14 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
goto error;
}
- info->magic = magic;
+ if (!memchr_inv(magic, 0, count * sizeof(u32))) {
+ pr_debug("reboot mode %s with zero magic values\n", prop->name);
+ info->count = -1;
+ } else {
+ memcpy(info->magic, magic, count * sizeof(u32));
+ info->count = count;
+ }
+
info->mode = kstrdup_const(prop->name + len, GFP_KERNEL);
if (!info->mode) {
ret = -ENOMEM;
diff --git a/drivers/power/reset/syscon-reboot-mode.c b/drivers/power/reset/syscon-reboot-mode.c
index e0772c9f70f7..983b1fbf614a 100644
--- a/drivers/power/reset/syscon-reboot-mode.c
+++ b/drivers/power/reset/syscon-reboot-mode.c
@@ -20,16 +20,18 @@ struct syscon_reboot_mode {
u32 mask;
};
-static int syscon_reboot_mode_write(struct reboot_mode_driver *reboot,
- unsigned int magic)
+static int syscon_reboot_mode_write(struct reboot_mode_driver *reboot, u32 *magic, int count)
{
struct syscon_reboot_mode *syscon_rbm;
int ret;
+ if (count != 1)
+ return -EINVAL;
+
syscon_rbm = container_of(reboot, struct syscon_reboot_mode, reboot);
ret = regmap_update_bits(syscon_rbm->map, syscon_rbm->offset,
- syscon_rbm->mask, magic);
+ syscon_rbm->mask, magic[0]);
if (ret < 0)
dev_err(reboot->dev, "update reboot mode bits failed\n");
diff --git a/include/linux/reboot-mode.h b/include/linux/reboot-mode.h
index 4a2abb38d1d6..34a81e4b4f95 100644
--- a/include/linux/reboot-mode.h
+++ b/include/linux/reboot-mode.h
@@ -2,10 +2,12 @@
#ifndef __REBOOT_MODE_H__
#define __REBOOT_MODE_H__
+#include <linux/types.h>
+
struct reboot_mode_driver {
struct device *dev;
struct list_head head;
- int (*write)(struct reboot_mode_driver *reboot, unsigned int magic);
+ int (*write)(struct reboot_mode_driver *reboot, u32 *magic, int count);
struct notifier_block reboot_notifier;
};
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v23 03/13] power: reset: reboot-mode: Add support for predefined reboot modes
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
2026-07-14 17:16 ` [PATCH v23 01/13] power: reset: reboot-mode: Remove devres based allocations Shivendra Pratap
2026-07-14 17:16 ` [PATCH v23 02/13] power: reset: reboot-mode: Support up to 3 magic values per mode Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:27 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 04/13] firmware: psci: Introduce command-based resets Shivendra Pratap
` (9 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla
reboot-mode based drivers can define a reboot-mode by adding it under
the reboot-mode node in device tree. This limits such drivers, to define
any predefined reboot-modes statically within the driver and creates a
dependency on device-tree.
Extend the reboot-mode framework to handle predefined modes alongside
those defined in device tree. Drivers can now define their own
reboot-modes and register them via the framework. A centralized init
call has been added to the reboot-mode framework and adopted by
existing drivers. This ensures driver state is initialized together
with predefined modes.
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
drivers/power/reset/nvmem-reboot-mode.c | 4 +-
drivers/power/reset/qcom-pon.c | 4 +-
drivers/power/reset/reboot-mode.c | 192 ++++++++++++++++++++++++-------
drivers/power/reset/syscon-reboot-mode.c | 4 +-
include/linux/reboot-mode.h | 16 +++
5 files changed, 175 insertions(+), 45 deletions(-)
diff --git a/drivers/power/reset/nvmem-reboot-mode.c b/drivers/power/reset/nvmem-reboot-mode.c
index ac69b5f39fb4..4909c65ca02d 100644
--- a/drivers/power/reset/nvmem-reboot-mode.c
+++ b/drivers/power/reset/nvmem-reboot-mode.c
@@ -53,8 +53,8 @@ static int nvmem_reboot_mode_probe(struct platform_device *pdev)
if (!nvmem_rbm)
return -ENOMEM;
- nvmem_rbm->reboot.dev = &pdev->dev;
- nvmem_rbm->reboot.write = nvmem_reboot_mode_write;
+ reboot_mode_driver_init(&nvmem_rbm->reboot, &pdev->dev,
+ nvmem_reboot_mode_write);
nvmem_rbm->cell = devm_nvmem_cell_get(&pdev->dev, "reboot-mode");
if (IS_ERR(nvmem_rbm->cell)) {
diff --git a/drivers/power/reset/qcom-pon.c b/drivers/power/reset/qcom-pon.c
index a508ab26d03f..5f3c6002ef8a 100644
--- a/drivers/power/reset/qcom-pon.c
+++ b/drivers/power/reset/qcom-pon.c
@@ -72,9 +72,9 @@ static int qcom_pon_probe(struct platform_device *pdev)
reason_shift = (long)of_device_get_match_data(&pdev->dev);
if (reason_shift != NO_REASON_SHIFT) {
- pon->reboot_mode.dev = &pdev->dev;
+ reboot_mode_driver_init(&pon->reboot_mode, &pdev->dev,
+ qcom_pon_reboot_mode_write);
pon->reason_shift = reason_shift;
- pon->reboot_mode.write = qcom_pon_reboot_mode_write;
error = devm_reboot_mode_register(&pdev->dev, &pon->reboot_mode);
if (error) {
dev_err(&pdev->dev, "can't register reboot mode\n");
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
index db2129c72341..08d5b58fce71 100644
--- a/drivers/power/reset/reboot-mode.c
+++ b/drivers/power/reset/reboot-mode.c
@@ -32,18 +32,30 @@ struct reboot_mode_sysfs_data {
struct list_head head;
};
-static inline void reboot_mode_release_list(struct reboot_mode_sysfs_data *priv)
+static inline void reboot_mode_release_list(struct list_head *head)
{
struct mode_info *info;
struct mode_info *next;
- list_for_each_entry_safe(info, next, &priv->head, list) {
+ list_for_each_entry_safe(info, next, head, list) {
list_del(&info->list);
kfree_const(info->mode);
kfree(info);
}
}
+/**
+ * reboot_mode_reset_predefined_modes - Remove all predefined reboot modes
+ * @reboot: reboot mode driver
+ *
+ * Reset predefined reboot modes added via reboot_mode_add_predefined_modes().
+ */
+void reboot_mode_reset_predefined_modes(struct reboot_mode_driver *reboot)
+{
+ reboot_mode_release_list(&reboot->predefined_modes);
+}
+EXPORT_SYMBOL_GPL(reboot_mode_reset_predefined_modes);
+
static ssize_t reboot_modes_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct reboot_mode_sysfs_data *priv;
@@ -117,6 +129,58 @@ static int reboot_mode_notify(struct notifier_block *this,
return NOTIFY_DONE;
}
+/**
+ * reboot_mode_driver_init - Initialize reboot-mode state
+ * @reboot: reboot mode driver object to initialize
+ * @dev: backing device
+ * @write: write callback for programming magic
+ *
+ * This function must be called with a valid @dev and @write before calling
+ * reboot_mode_register(), reboot_mode_add_predefined_modes(), or any other
+ * reboot-mode framework API.
+ */
+void reboot_mode_driver_init(struct reboot_mode_driver *reboot,
+ struct device *dev,
+ int (*write)(struct reboot_mode_driver *reboot, u32 *magic, int count))
+{
+ memset(reboot, 0, sizeof(*reboot));
+ reboot->dev = dev;
+ reboot->write = write;
+ INIT_LIST_HEAD(&reboot->head);
+ INIT_LIST_HEAD(&reboot->predefined_modes);
+}
+EXPORT_SYMBOL_GPL(reboot_mode_driver_init);
+
+static struct mode_info *reboot_mode_create_info(const char *mode, const u32 *magic, int count)
+{
+ struct mode_info *info;
+
+ if (!mode || mode[0] == '\0') {
+ pr_err("invalid mode name\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ info = kzalloc_obj(*info, GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ info->mode = kstrdup_const(mode, GFP_KERNEL);
+ if (!info->mode) {
+ kfree(info);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ if (!memchr_inv(magic, 0, count * sizeof(u32))) {
+ pr_debug("reboot mode %s with zero magic values\n", mode);
+ info->count = -1;
+ } else {
+ memcpy(info->magic, magic, count * sizeof(u32));
+ info->count = count;
+ }
+
+ return info;
+}
+
static int reboot_mode_create_device(struct reboot_mode_driver *reboot)
{
struct reboot_mode_sysfs_data *priv;
@@ -158,7 +222,7 @@ static int reboot_mode_create_device(struct reboot_mode_driver *reboot)
return 0;
error:
- reboot_mode_release_list(priv);
+ reboot_mode_release_list(&priv->head);
kfree(priv);
return ret;
}
@@ -171,7 +235,7 @@ static int reboot_mode_create_device(struct reboot_mode_driver *reboot)
*/
int reboot_mode_register(struct reboot_mode_driver *reboot)
{
- struct mode_info *info = NULL;
+ struct mode_info *info;
struct property *prop;
struct device_node *np = reboot->dev->of_node;
size_t len = strlen(PREFIX);
@@ -179,11 +243,16 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
int count;
int ret;
+ if (reboot->reboot_notifier.notifier_call == reboot_mode_notify)
+ return -EBUSY;
+
INIT_LIST_HEAD(&reboot->head);
+ if (!np)
+ goto predefined_modes;
+
for_each_property_of_node(np, prop) {
memset(magic, 0, sizeof(magic));
-
if (strncmp(prop->name, PREFIX, len))
continue;
@@ -195,35 +264,17 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
continue;
}
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info) {
- ret = -ENOMEM;
- goto error;
- }
-
- if (!memchr_inv(magic, 0, count * sizeof(u32))) {
- pr_debug("reboot mode %s with zero magic values\n", prop->name);
- info->count = -1;
- } else {
- memcpy(info->magic, magic, count * sizeof(u32));
- info->count = count;
- }
-
- info->mode = kstrdup_const(prop->name + len, GFP_KERNEL);
- if (!info->mode) {
- ret = -ENOMEM;
- goto error;
- } else if (info->mode[0] == '\0') {
- kfree_const(info->mode);
- ret = -EINVAL;
- pr_err("invalid mode name(%s): too short!\n", prop->name);
+ info = reboot_mode_create_info(prop->name + len, magic, count);
+ if (IS_ERR(info)) {
+ ret = PTR_ERR(info);
goto error;
}
list_add_tail(&info->list, &reboot->head);
- info = NULL;
}
+predefined_modes:
+ list_splice_tail_init(&reboot->predefined_modes, &reboot->head);
reboot->reboot_notifier.notifier_call = reboot_mode_notify;
register_reboot_notifier(&reboot->reboot_notifier);
@@ -234,7 +285,6 @@ int reboot_mode_register(struct reboot_mode_driver *reboot)
return 0;
error:
- kfree(info);
reboot_mode_unregister(reboot);
return ret;
}
@@ -267,7 +317,7 @@ static inline void reboot_mode_unregister_device(struct reboot_mode_driver *rebo
if (!priv)
return;
- reboot_mode_release_list(priv);
+ reboot_mode_release_list(&priv->head);
kfree(priv);
}
@@ -277,17 +327,12 @@ static inline void reboot_mode_unregister_device(struct reboot_mode_driver *rebo
*/
int reboot_mode_unregister(struct reboot_mode_driver *reboot)
{
- struct mode_info *info;
- struct mode_info *next;
-
unregister_reboot_notifier(&reboot->reboot_notifier);
+ reboot->reboot_notifier.notifier_call = NULL;
reboot_mode_unregister_device(reboot);
- list_for_each_entry_safe(info, next, &reboot->head, list) {
- list_del(&info->list);
- kfree_const(info->mode);
- kfree(info);
- }
+ reboot_mode_release_list(&reboot->head);
+ reboot_mode_release_list(&reboot->predefined_modes);
return 0;
}
@@ -312,8 +357,10 @@ int devm_reboot_mode_register(struct device *dev,
int rc;
dr = devres_alloc(devm_reboot_mode_release, sizeof(*dr), GFP_KERNEL);
- if (!dr)
+ if (!dr) {
+ reboot_mode_reset_predefined_modes(reboot);
return -ENOMEM;
+ }
rc = reboot_mode_register(reboot);
if (rc) {
@@ -352,6 +399,73 @@ void devm_reboot_mode_unregister(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_reboot_mode_unregister);
+/**
+ * reboot_mode_add_predefined_modes - Add predefined reboot modes
+ * @reboot: reboot mode driver
+ * @modes: array of predefined reboot mode entries
+ * @count: number of entries in @modes
+ *
+ * Add predefined reboot modes before registration.
+ *
+ * The entire list is discarded if any mode entry is invalid. An entry
+ * with a zero or negative magic count, a NULL mode string, or a mode
+ * string containing spaces or "\n" is considered invalid.
+ *
+ * Predefined modes are cleared if registration fails.
+ * Call reboot_mode_reset_predefined_modes() if registration is not
+ * performed after adding predefined modes.
+ *
+ * @reboot must be initialized with reboot_mode_driver_init() before calling
+ * this function.
+ *
+ * Returns: 0 on success,
+ * -EINVAL if invalid entry is found in list,
+ * -EBUSY if called after reboot_mode_register() or if predefined modes
+ * are already set, and, -ENOMEM on allocation failures.
+ */
+int reboot_mode_add_predefined_modes(struct reboot_mode_driver *reboot,
+ const struct reboot_mode_entry *modes,
+ size_t count)
+{
+ struct mode_info *info;
+ int ret;
+ size_t i;
+
+ if (reboot->reboot_notifier.notifier_call == reboot_mode_notify ||
+ !list_empty(&reboot->predefined_modes))
+ return -EBUSY;
+
+ if (!modes || !count)
+ return -EINVAL;
+
+ for (i = 0; i < count; i++) {
+ if (modes[i].name && strpbrk(modes[i].name, "\n ")) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (modes[i].count <= 0 || modes[i].count > ARRAY_SIZE(modes[i].magic)) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ info = reboot_mode_create_info(modes[i].name, modes[i].magic, modes[i].count);
+ if (IS_ERR(info)) {
+ ret = PTR_ERR(info);
+ goto error;
+ }
+
+ list_add_tail(&info->list, &reboot->predefined_modes);
+ }
+
+ return 0;
+
+error:
+ reboot_mode_release_list(&reboot->predefined_modes);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(reboot_mode_add_predefined_modes);
+
static int __init reboot_mode_init(void)
{
return class_register(&reboot_mode_class);
diff --git a/drivers/power/reset/syscon-reboot-mode.c b/drivers/power/reset/syscon-reboot-mode.c
index 983b1fbf614a..0c7e11276e6f 100644
--- a/drivers/power/reset/syscon-reboot-mode.c
+++ b/drivers/power/reset/syscon-reboot-mode.c
@@ -47,8 +47,8 @@ static int syscon_reboot_mode_probe(struct platform_device *pdev)
if (!syscon_rbm)
return -ENOMEM;
- syscon_rbm->reboot.dev = &pdev->dev;
- syscon_rbm->reboot.write = syscon_reboot_mode_write;
+ reboot_mode_driver_init(&syscon_rbm->reboot, &pdev->dev,
+ syscon_reboot_mode_write);
syscon_rbm->mask = 0xffffffff;
syscon_rbm->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
diff --git a/include/linux/reboot-mode.h b/include/linux/reboot-mode.h
index 34a81e4b4f95..b216c7595f7e 100644
--- a/include/linux/reboot-mode.h
+++ b/include/linux/reboot-mode.h
@@ -4,18 +4,34 @@
#include <linux/types.h>
+struct reboot_mode_entry {
+ const char *name;
+ u32 magic[3];
+ int count;
+};
+
struct reboot_mode_driver {
struct device *dev;
struct list_head head;
+ /* List of predefined reboot-modes, populated via reboot_mode_add_predefined_modes(). */
+ struct list_head predefined_modes;
int (*write)(struct reboot_mode_driver *reboot, u32 *magic, int count);
struct notifier_block reboot_notifier;
};
+void reboot_mode_driver_init(struct reboot_mode_driver *reboot,
+ struct device *dev,
+ int (*write)(struct reboot_mode_driver *reboot, u32 *magic,
+ int count));
int reboot_mode_register(struct reboot_mode_driver *reboot);
int reboot_mode_unregister(struct reboot_mode_driver *reboot);
int devm_reboot_mode_register(struct device *dev,
struct reboot_mode_driver *reboot);
void devm_reboot_mode_unregister(struct device *dev,
struct reboot_mode_driver *reboot);
+int reboot_mode_add_predefined_modes(struct reboot_mode_driver *reboot,
+ const struct reboot_mode_entry *modes,
+ size_t count);
+void reboot_mode_reset_predefined_modes(struct reboot_mode_driver *reboot);
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v23 03/13] power: reset: reboot-mode: Add support for predefined reboot modes
2026-07-14 17:16 ` [PATCH v23 03/13] power: reset: reboot-mode: Add support for predefined reboot modes Shivendra Pratap
@ 2026-07-14 17:27 ` sashiko-bot
0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-07-14 17:27 UTC (permalink / raw)
To: Shivendra Pratap; +Cc: mfd, devicetree, lee, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Hardcoded non-unique device naming causes cross-instance destruction of sysfs state on probe failure.
--
--- Patch [3]: [PATCH v23 03/13] power: reset: reboot-mode: Add support for predefined reboot modes ---
commit 7f64e78c4dace557cca8c3399655be137b5cc95f
Author: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
power: reset: reboot-mode: Add support for predefined reboot modes
Extend the reboot-mode framework to handle predefined modes alongside
those defined in device tree. Drivers can now define their own
reboot-modes and register them via the framework. A centralized init
call has been added to the reboot-mode framework and adopted by
existing drivers.
> diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
> --- a/drivers/power/reset/reboot-mode.c
> +++ b/drivers/power/reset/reboot-mode.c
[ ... ]
> @@ -267,7 +317,7 @@ static inline void reboot_mode_unregister_device(struct reboot_mode_driver *rebo
> if (!priv)
> return;
>
> - reboot_mode_release_list(priv);
> + reboot_mode_release_list(&priv->head);
> kfree(priv);
> }
[Severity: High]
This is a pre-existing issue, but does the hardcoded use of the generic
driver name for the sysfs device cause cross-instance destruction if
multiple instances of a reboot-mode driver are probed?
If the device tree defines multiple instances (e.g. syscon-reboot-mode),
the first instance successfully creates a sysfs device using
reboot->dev->driver->name:
reboot_mode_create_device() {
...
priv->reboot_mode_device = device_create(&reboot_mode_class, NULL, 0,
(void *)priv, "%s",
reboot->dev->driver->name);
}
The second instance would fail device_create() with -EEXIST due to the
name collision. During its error path cleanup,
reboot_mode_unregister_device() searches for the device by the same
generic driver name:
reboot_mode_unregister_device() {
...
reboot_mode_device = class_find_device(&reboot_mode_class, NULL,
reboot->dev->driver->name,
reboot_mode_match_by_name);
...
device_unregister(reboot_mode_device);
if (!priv)
return;
...
kfree(priv);
}
Could this erroneously find the first successfully probed instance's sysfs
device, unregister it, and free its priv data, leaving the first instance
silently corrupted? Would it be safer to use a unique instance name like
dev_name(reboot->dev) for device_create() instead?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-arm-psci-system_reset2-vendor-reboots-v23-0-e7453c548c21@oss.qualcomm.com?part=3
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v23 04/13] firmware: psci: Introduce command-based resets
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
` (2 preceding siblings ...)
2026-07-14 17:16 ` [PATCH v23 03/13] power: reset: reboot-mode: Add support for predefined reboot modes Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:28 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 05/13] mfd: psci-mfd: Add PSCI MFD driver for cpuidle-psci-domain cell Shivendra Pratap
` (8 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla
PSCI currently supports only two resets - SYSTEM_RESET and SYSTEM_RESET2
ARCH WARM reset. The reset patch is selected based on the Linux
reboot_mode variable. The PSCI specification now includes SYSTEM_RESET2
for vendor-specific resets but there's no mechanism to issue these
through psci_sys_reset().
Add a command-based reset mechanism that allows external drivers to set
the PSCI reset command by passing a reset_type and a cookie.
Add support for the following reset commands:
- SYSTEM_RESET2 vendor-specific resets.
- SYSTEM_RESET2 ARCH WARM reset and SYSTEM_RESET (reset_type = 0 and
cookie maps to psci_standard_resets).
Unsupported commands fall back to the regular PSCI reset path.
Default to the existing reboot_mode-based reset flow unless a reset
command is configured. If a kernel panic occurs after a reset command is
set but before the final PSCI reset is issued, ignore the reset command
and follow the normal reboot_mode-based reset path.
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
drivers/firmware/psci/psci.c | 106 ++++++++++++++++++++++++++++++++++++++++++-
include/linux/psci.h | 36 +++++++++++++++
2 files changed, 140 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index e73bae6cb23a..881819d09911 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -12,7 +12,9 @@
#include <linux/debugfs.h>
#include <linux/errno.h>
#include <linux/linkage.h>
+#include <linux/mutex.h>
#include <linux/of.h>
+#include <linux/panic.h>
#include <linux/pm.h>
#include <linux/printk.h>
#include <linux/psci.h>
@@ -51,6 +53,14 @@ static int resident_cpu = -1;
struct psci_operations psci_ops;
static enum arm_smccc_conduit psci_conduit = SMCCC_CONDUIT_NONE;
+struct psci_system_reset_cmd {
+ u32 reset_type;
+ u64 cookie;
+};
+
+static struct psci_system_reset_cmd reset_cmd;
+static DEFINE_MUTEX(reset_cmd_mutex);
+
bool psci_tos_resident_on(int cpu)
{
return cpu == resident_cpu;
@@ -80,6 +90,62 @@ static u32 psci_cpu_suspend_feature;
static bool psci_system_reset2_supported;
static bool psci_system_off2_hibernate_supported;
+static u32 psci_get_sys_reset_fn(void)
+{
+ switch (reset_cmd.cookie) {
+ case PSCI_SYSTEM_RESET2_ARCH_WARM_RESET:
+ if (psci_system_reset2_supported)
+ return PSCI_FN_NATIVE(1_1, SYSTEM_RESET2);
+ return 0;
+ case PSCI_SYSTEM_RESET_COLD_RESET:
+ return PSCI_0_2_FN_SYSTEM_RESET;
+ default:
+ return 0;
+ }
+}
+
+/** psci_set_reset_cmd() - Configure PSCI reset command
+ * @reset_type: SYSTEM_RESET2 vendor-specific reset_type as defined by
+ * firmware, or 0 for standard resets
+ * @cookie: SYSTEM_RESET2 vendor-specific cookie as defined by firmware or one
+ * of enum psci_standard_resets when @reset_type is set to 0
+ *
+ * Supported commands:
+ * - PSCI SYSTEM_RESET2 vendor-specific reset:
+ * - @reset_type and @cookie must follow platform-specific SYSTEM_RESET2
+ * vendor-specific resets.
+ * - Standard reset selector:
+ * - @reset_type must be 0.
+ * - @cookie must be one of enum psci_standard_resets.
+ *
+ * This is an in-kernel helper intended for built-in reboot flow callers.
+ * reset command can be set only one time per boot cycle.
+ *
+ * Return: 0 on success, -EINVAL if both inputs are zero, -EBUSY if reset
+ * command is already set.
+ */
+int psci_set_reset_cmd(u32 reset_type, u64 cookie)
+{
+ if (!reset_type && !cookie)
+ return -EINVAL;
+
+ scoped_guard(mutex, &reset_cmd_mutex) {
+ if (reset_cmd.reset_type || reset_cmd.cookie)
+ return -EBUSY;
+
+ reset_cmd.reset_type = reset_type;
+ reset_cmd.cookie = cookie;
+ }
+
+ return 0;
+}
+
+bool psci_has_system_reset2_support(void)
+{
+ return psci_system_reset2_supported;
+}
+EXPORT_SYMBOL_GPL(psci_has_system_reset2_support);
+
static inline bool psci_has_ext_power_state(void)
{
return psci_cpu_suspend_feature &
@@ -306,8 +372,24 @@ static int get_set_conduit_method(const struct device_node *np)
return 0;
}
-static int psci_sys_reset(struct notifier_block *nb, unsigned long action,
- void *data)
+static void psci_handle_reset_cmd(void)
+{
+ u32 psci_sys_reset_fn;
+
+ if ((reset_cmd.reset_type & PSCI_1_1_RESET_TYPE_VENDOR_START) &&
+ psci_system_reset2_supported) {
+ /* PSCI SYSTEM_RESET2 Vendor-specific reset */
+ invoke_psci_fn(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2),
+ reset_cmd.reset_type, reset_cmd.cookie, 0);
+ } else {
+ /* Retrieve the psci reset function from reset_cmd */
+ psci_sys_reset_fn = psci_get_sys_reset_fn();
+ if (!reset_cmd.reset_type && psci_sys_reset_fn)
+ invoke_psci_fn(psci_sys_reset_fn, 0, 0, 0);
+ }
+}
+
+static void psci_handle_reboot_mode(void)
{
if ((reboot_mode == REBOOT_WARM || reboot_mode == REBOOT_SOFT) &&
psci_system_reset2_supported) {
@@ -320,6 +402,26 @@ static int psci_sys_reset(struct notifier_block *nb, unsigned long action,
} else {
invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
}
+}
+
+static int psci_sys_reset(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ /* The function psci_handle_reboot_mode follows reboot_mode based
+ * reset flow and psci_handle_reset_cmd uses reset_cmd based reset flow.
+ *
+ * The reset_cmd is configured at the reboot_notifier phase. If a kernel
+ * panic occurs between the reboot_notifier and this final reset, skip the
+ * command-based reset and let reboot_mode drive the reset flow.
+ *
+ * The function psci_handle_reset_cmd invokes non-returning PSCI SYSTEM_RESET
+ * calls to reset the device. If it returns, either the reset failed, or the
+ * command was unsupported. Fallback to reboot_mode based reset flow.
+ */
+ if ((reset_cmd.reset_type || reset_cmd.cookie) && !panic_in_progress())
+ psci_handle_reset_cmd();
+
+ psci_handle_reboot_mode();
return NOTIFY_DONE;
}
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 4ca0060a3fc4..39fe0edec651 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -8,6 +8,7 @@
#define __LINUX_PSCI_H
#include <linux/arm-smccc.h>
+#include <linux/errno.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -21,6 +22,16 @@ bool psci_power_state_is_valid(u32 state);
int psci_set_osi_mode(bool enable);
bool psci_has_osi_support(void);
+/**
+ * enum psci_standard_resets - Standard reset selectors for PSCI reset
+ * @PSCI_SYSTEM_RESET_COLD_RESET: Standard SYSTEM_RESET command.
+ * @PSCI_SYSTEM_RESET2_ARCH_WARM_RESET: SYSTEM_RESET2 architectural warm reset.
+ */
+enum psci_standard_resets {
+ PSCI_SYSTEM_RESET_COLD_RESET = 1,
+ PSCI_SYSTEM_RESET2_ARCH_WARM_RESET,
+};
+
struct psci_operations {
u32 (*get_version)(void);
int (*cpu_suspend)(u32 state, unsigned long entry_point);
@@ -45,8 +56,33 @@ struct psci_0_1_function_ids get_psci_0_1_function_ids(void);
#if defined(CONFIG_ARM_PSCI_FW)
int __init psci_dt_init(void);
+/**
+ * psci_set_reset_cmd() - Configure PSCI reset command
+ * @reset_type: SYSTEM_RESET2 vendor-specific reset_type as defined by
+ * firmware, or 0 for standard resets
+ * @cookie: SYSTEM_RESET2 vendor-specific cookie as defined by firmware or one
+ * of enum psci_standard_resets when @reset_type is set to 0
+ *
+ * Supported commands:
+ * - PSCI SYSTEM_RESET2 vendor-specific reset:
+ * - @reset_type and @cookie must follow platform-specific SYSTEM_RESET2
+ * vendor-reset encoding.
+ * - Standard reset selector:
+ * - @reset_type must be 0.
+ * - @cookie must be one of enum psci_standard_resets.
+ *
+ * This is an in-kernel helper intended for built-in reboot flow callers.
+ * reset command can be set only one time per boot cycle.
+ *
+ * Return: 0 on success, -EINVAL if both inputs are zero, -EBUSY if reset
+ * command is already set.
+ */
+int psci_set_reset_cmd(u32 reset_type, u64 cookie);
+bool psci_has_system_reset2_support(void);
#else
static inline int psci_dt_init(void) { return 0; }
+static inline int psci_set_reset_cmd(u32 reset_type, u64 cookie) { return 0; }
+static inline bool psci_has_system_reset2_support(void) { return false; }
#endif
#if defined(CONFIG_ARM_PSCI_FW) && defined(CONFIG_ACPI)
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v23 04/13] firmware: psci: Introduce command-based resets
2026-07-14 17:16 ` [PATCH v23 04/13] firmware: psci: Introduce command-based resets Shivendra Pratap
@ 2026-07-14 17:28 ` sashiko-bot
0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-07-14 17:28 UTC (permalink / raw)
To: Shivendra Pratap; +Cc: conor+dt, devicetree, robh, lee, mfd
> PSCI currently supports only two resets - SYSTEM_RESET and SYSTEM_RESET2
> ARCH WARM reset. The reset patch is selected based on the Linux
> reboot_mode variable. The PSCI specification now includes SYSTEM_RESET2
> for vendor-specific resets but there's no mechanism to issue these
> through psci_sys_reset().
>
> Add a command-based reset mechanism that allows external drivers to set
> the PSCI reset command by passing a reset_type and a cookie.
>
> Add support for the following reset commands:
> - SYSTEM_RESET2 vendor-specific resets.
> - SYSTEM_RESET2 ARCH WARM reset and SYSTEM_RESET (reset_type = 0 and
> cookie maps to psci_standard_resets).
> Unsupported commands fall back to the regular PSCI reset path.
>
> Default to the existing reboot_mode-based reset flow unless a reset
> command is configured. If a kernel panic occurs after a reset command is
> set but before the final PSCI reset is issued, ignore the reset command
> and follow the normal reboot_mode-based reset path.
>
> Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-arm-psci-system_reset2-vendor-reboots-v23-0-e7453c548c21@oss.qualcomm.com?part=4
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v23 05/13] mfd: psci-mfd: Add PSCI MFD driver for cpuidle-psci-domain cell
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
` (3 preceding siblings ...)
2026-07-14 17:16 ` [PATCH v23 04/13] firmware: psci: Introduce command-based resets Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:27 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 06/13] dt-bindings: arm: Document reboot mode magic Shivendra Pratap
` (7 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla, Bartosz Golaszewski
PSCI has multiple kernel consumers, such as cpuidle-psci-domain.
Currently, both the PSCI core driver and cpuidle-psci-domain bind
directly to the same PSCI node "arm,psci-1.0". Additional consumers, if
introduced, would also need to bind in the same way, leading to several
drivers attached to a single device node.
Introduce a PSCI MFD driver that binds to "arm,psci-1.0" and registers
PSCI child cells. As the first user, register cpuidle-psci-domain as a
child cell.
Update cpuidle-psci-domain to probe as an MFD child and use the parent
PSCI node for power-domain traversal.
Suggested-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
MAINTAINERS | 1 +
drivers/cpuidle/Kconfig.arm | 1 +
drivers/cpuidle/cpuidle-psci-domain.c | 9 +-------
drivers/mfd/Kconfig | 12 ++++++++++
drivers/mfd/Makefile | 2 ++
drivers/mfd/psci-mfd.c | 43 +++++++++++++++++++++++++++++++++++
6 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index dcffe9fc54f6..e1ed6abef62a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21575,6 +21575,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/arm/psci.yaml
F: drivers/firmware/psci/
+F: drivers/mfd/psci-mfd.c
F: include/linux/psci.h
F: include/uapi/linux/psci.h
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index b88b01aa5829..c5ecca0d7397 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -36,6 +36,7 @@ config ARM_PSCI_CPUIDLE_DOMAIN
bool "PSCI CPU idle Domain"
depends on ARM_PSCI_CPUIDLE
depends on PM_GENERIC_DOMAINS_OF
+ depends on MFD_PSCI
select DT_IDLE_GENPD
default y
help
diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
index b9e4ad7d43a3..a2d01810f295 100644
--- a/drivers/cpuidle/cpuidle-psci-domain.c
+++ b/drivers/cpuidle/cpuidle-psci-domain.c
@@ -17,7 +17,6 @@
#include <linux/pm_runtime.h>
#include <linux/psci.h>
#include <linux/slab.h>
-#include <linux/string.h>
#include "cpuidle-psci.h"
#include "dt_idle_genpd.h"
@@ -122,14 +121,9 @@ static void psci_pd_remove(void)
}
}
-static const struct of_device_id psci_of_match[] = {
- { .compatible = "arm,psci-1.0" },
- {}
-};
-
static int psci_cpuidle_domain_probe(struct platform_device *pdev)
{
- struct device_node *np = pdev->dev.of_node;
+ struct device_node *np = pdev->dev.parent->of_node;
bool use_osi = psci_has_osi_support();
int ret = 0, pd_count = 0;
@@ -181,7 +175,6 @@ static struct platform_driver psci_cpuidle_domain_driver = {
.probe = psci_cpuidle_domain_probe,
.driver = {
.name = "psci-cpuidle-domain",
- .of_match_table = psci_of_match,
},
};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 35f6e9b76d05..8b7fae5d3f5c 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2368,6 +2368,18 @@ config MFD_KHADAS_MCU
additional drivers must be enabled in order to use the functionality
of the device.
+config MFD_PSCI
+ bool "PSCI MFD for psci child cells"
+ depends on ARM_PSCI_FW
+ depends on OF
+ select MFD_CORE
+ default y
+ help
+ PSCI MFD registers PSCI child cells and exposes them as
+ platform devices. Child drivers are probed only if enabled in the
+ kernel configuration. Select this option whenever a supported PSCI
+ child driver is selected.
+
config MFD_ACER_A500_EC
tristate "Support for Acer Iconia Tab A500 Embedded Controller"
depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index dd4bb7e77c33..7fa0112ec309 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -24,6 +24,8 @@ obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
obj-$(CONFIG_MFD_GATEWORKS_GSC) += gateworks-gsc.o
obj-$(CONFIG_MFD_MACSMC) += macsmc.o
+obj-$(CONFIG_MFD_PSCI) += psci-mfd.o
+
obj-$(CONFIG_MFD_TI_LP873X) += lp873x.o
obj-$(CONFIG_MFD_TI_LP87565) += lp87565.o
obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o
diff --git a/drivers/mfd/psci-mfd.c b/drivers/mfd/psci-mfd.c
new file mode 100644
index 000000000000..7affd6bb09dd
--- /dev/null
+++ b/drivers/mfd/psci-mfd.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+static const struct mfd_cell psci_cells[] = {
+ {
+ .name = "psci-cpuidle-domain",
+ },
+};
+
+static int psci_mfd_probe(struct platform_device *pdev)
+{
+ return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, psci_cells,
+ ARRAY_SIZE(psci_cells), NULL, 0, NULL);
+}
+
+static const struct of_device_id psci_mfd_of_match[] = {
+ { .compatible = "arm,psci-1.0" },
+ { }
+};
+
+static struct platform_driver psci_mfd_driver = {
+ .probe = psci_mfd_probe,
+ .driver = {
+ .name = "psci-mfd",
+ .of_match_table = psci_mfd_of_match,
+ },
+};
+
+static int __init psci_mfd_init(void)
+{
+ return platform_driver_register(&psci_mfd_driver);
+}
+
+core_initcall(psci_mfd_init);
+
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v23 05/13] mfd: psci-mfd: Add PSCI MFD driver for cpuidle-psci-domain cell
2026-07-14 17:16 ` [PATCH v23 05/13] mfd: psci-mfd: Add PSCI MFD driver for cpuidle-psci-domain cell Shivendra Pratap
@ 2026-07-14 17:27 ` sashiko-bot
0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-07-14 17:27 UTC (permalink / raw)
To: Shivendra Pratap; +Cc: devicetree, conor+dt, robh, mfd, lee
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] MFD Naming Convention Violation: Driver and file names hard-code the implementation detail 'mfd'.
--
--- Patch [5]: [PATCH v23 05/13] mfd: psci-mfd: Add PSCI MFD driver for cpuidle-psci-domain cell ---
commit de3054149d7eea49e51e1d55bb38215b4d3e238f
Author: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
mfd: psci-mfd: Add PSCI MFD driver for cpuidle-psci-domain cell
This commit introduces a PSCI MFD driver that binds to the "arm,psci-1.0"
node and registers PSCI child cells. It migrates cpuidle-psci-domain to
probe as an MFD child rather than binding directly to the parent PSCI node.
> diff --git a/drivers/mfd/psci-mfd.c b/drivers/mfd/psci-mfd.c
> new file mode 100644
> index 0000000000000..7affd6bb09dd8
> --- /dev/null
> +++ b/drivers/mfd/psci-mfd.c
[ ... ]
> +static struct platform_driver psci_mfd_driver = {
> + .probe = psci_mfd_probe,
> + .driver = {
> + .name = "psci-mfd",
[Severity: Low]
This isn't a bug, but does this name violate the MFD subsystem naming
conventions?
The subsystem guidelines recommend avoiding the string "mfd" in driver,
struct, or device names to prevent embedding implementation details into
the driver structure.
Could a more descriptive name be used here that omits the "mfd" string?
> + .of_match_table = psci_mfd_of_match,
> + },
> +};
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-arm-psci-system_reset2-vendor-reboots-v23-0-e7453c548c21@oss.qualcomm.com?part=5
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v23 06/13] dt-bindings: arm: Document reboot mode magic
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
` (4 preceding siblings ...)
2026-07-14 17:16 ` [PATCH v23 05/13] mfd: psci-mfd: Add PSCI MFD driver for cpuidle-psci-domain cell Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:33 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 07/13] power: reset: Add psci-reboot-mode driver Shivendra Pratap
` (6 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla
Add bindings to describe vendor-specific reboot modes. Values here
correspond to valid parameters to vendor-specific reset types in PSCI
SYSTEM_RESET2 call.
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
Documentation/devicetree/bindings/arm/psci.yaml | 54 +++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml
index 6e2e0c551841..11b90e8affb3 100644
--- a/Documentation/devicetree/bindings/arm/psci.yaml
+++ b/Documentation/devicetree/bindings/arm/psci.yaml
@@ -98,6 +98,37 @@ properties:
[1] Kernel documentation - ARM idle states bindings
Documentation/devicetree/bindings/cpu/idle-states.yaml
+ reboot-mode:
+ type: object
+ $ref: /schemas/power/reset/reboot-mode.yaml#
+ additionalProperties: false
+ properties:
+ # "mode-normal" is just SYSTEM_RESET
+ mode-normal: false
+ patternProperties:
+ "^mode-.*$":
+ minItems: 1
+ maxItems: 3
+ items:
+ - description: arg1 (vendor-specific SYSTEM_RESET2 reset_type)
+ minimum: 0x80000000
+ - description: arg2 (cookie_lo in 2-cell form, cookie_hi in 3-cell form)
+ - description: arg3 (cookie_lo in 3-cell form)
+ description: |
+ Describes a PSCI SYSTEM_RESET2 vendor-specific reset type. The string
+ after "mode-" maps a reboot mode to a vendor-specific reset.
+ A vendor-specific reset takes two arguments, a 32-bit reset_type and a
+ 64-bit cookie. The arguments are encoded as up to three 32-bit cells.
+ Each mode property is encoded as mode-xxx = <arg1[, arg2[, arg3]]>,
+ where:
+ - arg1 is reset_type and must be >= 0x80000000.
+ - In 2-cell form, arg2 is lower 32 bits of cookie.
+ - In 3-cell form, arg2 is high 32 bits of cookie
+ and arg3 is low 32 bits of cookie.
+
+ All values should be provided as per the PSCI SYSTEM_RESET2
+ specification.
+
patternProperties:
"^power-domain-":
$ref: /schemas/power/power-domain.yaml#
@@ -137,6 +168,15 @@ allOf:
required:
- cpu_off
- cpu_on
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ const: arm,psci-1.0
+ then:
+ properties:
+ reboot-mode: false
additionalProperties: false
@@ -260,4 +300,18 @@ examples:
domain-idle-states = <&cluster_ret>, <&cluster_pwrdn>;
};
};
+
+ - |+
+
+ // Case 5: SYSTEM_RESET2 vendor resets
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+
+ reboot-mode {
+ mode-edl = <0x80000000 0x00000001>;
+ mode-bootloader = <0x80010001 0x00000002>;
+ mode-needscookie_64 = <0x80000000 0x00000001 0x00000002>;
+ };
+ };
...
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v23 06/13] dt-bindings: arm: Document reboot mode magic
2026-07-14 17:16 ` [PATCH v23 06/13] dt-bindings: arm: Document reboot mode magic Shivendra Pratap
@ 2026-07-14 17:33 ` sashiko-bot
0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-07-14 17:33 UTC (permalink / raw)
To: Shivendra Pratap; +Cc: conor+dt, lee, devicetree, mfd, robh
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] The dt-schema constraints for the reboot mode cells are applied to the outer tuple array rather than the individual 32-bit cells within the tuple, silently bypassing the 0x80000000 minimum value check.
- [Medium] Incorrect use of `additionalProperties: false` alongside `$ref` inside the `reboot-mode` node definition.
--
--- Patch [6]: [PATCH v23 06/13] dt-bindings: arm: Document reboot mode magic ---
commit a9e970af5fba06441f5c9bf2192c866e245aed96
Author: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
dt-bindings: arm: Document reboot mode magic
Add bindings to describe vendor-specific reboot modes. Values here
correspond to valid parameters to vendor-specific reset types in PSCI
SYSTEM_RESET2 call.
> diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml
> index 6e2e0c5518411..11b90e8affb32 100644
> --- a/Documentation/devicetree/bindings/arm/psci.yaml
> +++ b/Documentation/devicetree/bindings/arm/psci.yaml
> @@ -98,6 +98,37 @@ properties:
> [1] Kernel documentation - ARM idle states bindings
> Documentation/devicetree/bindings/cpu/idle-states.yaml
>
> + reboot-mode:
> + type: object
> + $ref: /schemas/power/reset/reboot-mode.yaml#
> + additionalProperties: false
[Severity: Medium]
Should this use unevaluatedProperties: false instead?
Using additionalProperties: false alongside a $ref does not consider
properties defined by the inherited schema (reboot-mode.yaml) or standard
properties injected by the dt-schema core (such as status or phandle).
This can cause dt_binding_check to incorrectly fail on valid device trees
that include standard properties.
> + properties:
> + # "mode-normal" is just SYSTEM_RESET
> + mode-normal: false
> + patternProperties:
> + "^mode-.*$":
> + minItems: 1
> + maxItems: 3
> + items:
> + - description: arg1 (vendor-specific SYSTEM_RESET2 reset_type)
> + minimum: 0x80000000
[Severity: Medium]
Does this correctly apply the minimum constraint to the 32-bit cell?
In dt-schema, uint32-array properties are parsed as a 2D array (an array
of tuples). Because items is placed directly under the property definition
here, it applies the minimum: 0x80000000 constraint to the first tuple
(which is an array) instead of the first cell (which is an integer).
Since JSON schema ignores numeric constraints on arrays, this silently
bypasses the check and allows invalid vendor-specific reset types.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-arm-psci-system_reset2-vendor-reboots-v23-0-e7453c548c21@oss.qualcomm.com?part=6
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v23 07/13] power: reset: Add psci-reboot-mode driver
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
` (5 preceding siblings ...)
2026-07-14 17:16 ` [PATCH v23 06/13] dt-bindings: arm: Document reboot mode magic Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:30 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 08/13] mfd: core: Add firmware-node support to MFD cells Shivendra Pratap
` (5 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla
PSCI supports different types of resets like SYSTEM_RESET, SYSTEM_RESET2
ARCH WARM reset and SYSTEM_RESET2 vendor-specific resets. Currently
there is no common driver that handles all supported psci resets at one
place. Additionally, there is no common mechanism to issue the supported
psci resets from userspace.
Add a psci-reboot-mode driver, and define two types of PSCI resets,
predefined-resets and vendor-specific resets. Predefined-resets are
defined by psci driver and vendor-specific resets are defined by SoC
vendors, under the psci:reboot-mode node of SoC device tree.
Register the driver with the reboot-mode framework to interface these
resets to userspace. When userspace initiates a supported command, pass
the reset arguments to the PSCI driver to enable command-based reset.
This change allows userspace to issue supported PSCI reset commands
using the standard reboot system calls while enabling SoC vendors to
define their specific resets for PSCI.
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
MAINTAINERS | 1 +
drivers/power/reset/Kconfig | 10 +++++
drivers/power/reset/Makefile | 1 +
drivers/power/reset/psci-reboot-mode.c | 78 ++++++++++++++++++++++++++++++++++
4 files changed, 90 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index e1ed6abef62a..4910abafa170 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21576,6 +21576,7 @@ S: Maintained
F: Documentation/devicetree/bindings/arm/psci.yaml
F: drivers/firmware/psci/
F: drivers/mfd/psci-mfd.c
+F: drivers/power/reset/psci-reboot-mode.c
F: include/linux/psci.h
F: include/uapi/linux/psci.h
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 124afb99febe..93e4029d9506 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -348,6 +348,16 @@ config NVMEM_REBOOT_MODE
then the bootloader can read it and take different
action according to the mode.
+config PSCI_REBOOT_MODE
+ bool "PSCI reboot mode driver"
+ depends on OF && (ARM_PSCI_FW || COMPILE_TEST)
+ select REBOOT_MODE
+ help
+ Say y here will enable PSCI reboot mode driver. This gets
+ the PSCI reboot mode arguments and passes them to psci
+ driver. psci driver uses these arguments for issuing
+ device reset into different boot states.
+
config POWER_MLXBF
tristate "Mellanox BlueField power handling driver"
depends on (GPIO_MLXBF2 || GPIO_MLXBF3) && ACPI
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index d7ae97241a83..02948622fe3d 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -40,5 +40,6 @@ obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o
obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o
obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o
+obj-$(CONFIG_PSCI_REBOOT_MODE) += psci-reboot-mode.o
obj-$(CONFIG_POWER_MLXBF) += pwr-mlxbf.o
obj-$(CONFIG_POWER_RESET_QEMU_VIRT_CTRL) += qemu-virt-ctrl.o
diff --git a/drivers/power/reset/psci-reboot-mode.c b/drivers/power/reset/psci-reboot-mode.c
new file mode 100644
index 000000000000..955ed68f1402
--- /dev/null
+++ b/drivers/power/reset/psci-reboot-mode.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/array_size.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/psci.h>
+#include <linux/reboot-mode.h>
+#include <linux/types.h>
+
+static const struct reboot_mode_entry psci_resets[] = {
+ {
+ .name = "psci-system-reset",
+ .magic = { 0, PSCI_SYSTEM_RESET_COLD_RESET },
+ .count = 2,
+ },
+ {
+ .name = "psci-system-reset2-arch-warm-reset",
+ .magic = { 0, PSCI_SYSTEM_RESET2_ARCH_WARM_RESET },
+ .count = 2,
+ },
+};
+
+static u64 psci_reboot_mode_get_cookie(const u32 *magic, int count)
+{
+ u64 cookie = 0;
+ int i;
+
+ /* Build cookie from arg2/arg3 cells in order: cookie_hi then cookie_lo. */
+ for (i = 1; i < count; i++)
+ cookie = (cookie << 32) | magic[i];
+
+ return cookie;
+}
+
+static int psci_reboot_mode_write(struct reboot_mode_driver *reboot,
+ u32 *magic, int count)
+{
+ if (count < 1 || count > 3)
+ return -EINVAL;
+
+ return psci_set_reset_cmd(magic[0], psci_reboot_mode_get_cookie(magic, count));
+}
+
+static int psci_reboot_mode_probe(struct platform_device *pdev)
+{
+ struct reboot_mode_driver *reboot;
+ size_t count;
+ int ret;
+
+ reboot = devm_kzalloc(&pdev->dev, sizeof(*reboot), GFP_KERNEL);
+ if (!reboot)
+ return -ENOMEM;
+
+ reboot_mode_driver_init(reboot, &pdev->dev, psci_reboot_mode_write);
+
+ /* Skip PSCI SYSTEM_RESET2 modes if unsupported */
+ count = psci_has_system_reset2_support() ? ARRAY_SIZE(psci_resets) : 1;
+ ret = reboot_mode_add_predefined_modes(reboot, psci_resets, count);
+ if (ret)
+ return ret;
+
+ return devm_reboot_mode_register(&pdev->dev, reboot);
+}
+
+static struct platform_driver psci_reboot_mode_driver = {
+ .probe = psci_reboot_mode_probe,
+ .driver = {
+ .name = "psci-reboot-mode",
+ },
+};
+module_platform_driver(psci_reboot_mode_driver);
+
+MODULE_DESCRIPTION("PSCI reboot mode driver");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v23 07/13] power: reset: Add psci-reboot-mode driver
2026-07-14 17:16 ` [PATCH v23 07/13] power: reset: Add psci-reboot-mode driver Shivendra Pratap
@ 2026-07-14 17:30 ` sashiko-bot
0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-07-14 17:30 UTC (permalink / raw)
To: Shivendra Pratap; +Cc: mfd, devicetree, robh, conor+dt, lee
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] The `psci-reboot-mode` platform driver is completely unreachable dead code because it lacks an `of_match_table` and is never instantiated as a child device by the parent PSCI or MFD driver.
- [High] Lockless read of `reset_cmd` in `psci_sys_reset()` can race with concurrent updates via `psci_set_reset_cmd()`.
- [Medium] The `PSCI_REBOOT_MODE` config is set to `bool`, which forces the `REBOOT_MODE` framework to be built-in.
--
--- Patch [7]: [PATCH v23 07/13] power: reset: Add psci-reboot-mode driver ---
commit 05cd2956034a357b1e7d5eab96bdce4575604285
Author: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
power: reset: Add psci-reboot-mode driver
Add a psci-reboot-mode driver to handle different types of PSCI resets,
including predefined and vendor-specific resets, at one place. It registers
with the reboot-mode framework to interface these resets to userspace and
passes arguments to the PSCI driver for command-based reset.
> diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
> index 124afb99febe9..93e4029d95060 100644
> --- a/drivers/power/reset/Kconfig
> +++ b/drivers/power/reset/Kconfig
> @@ -348,6 +348,16 @@ config NVMEM_REBOOT_MODE
> then the bootloader can read it and take different
> action according to the mode.
>
> +config PSCI_REBOOT_MODE
> + bool "PSCI reboot mode driver"
> + depends on OF && (ARM_PSCI_FW || COMPILE_TEST)
> + select REBOOT_MODE
[Severity: Medium]
Will this force the REBOOT_MODE framework to always be built-in?
Since PSCI_REBOOT_MODE is defined as a bool, selecting the REBOOT_MODE
tristate will forcefully upgrade the entire reboot-mode framework to built-in
(=y), which overrides user configurations that might prefer it as a module.
Also, since the driver source uses module_platform_driver and MODULE_LICENSE,
it appears designed to be built as a module. Should this be a tristate instead?
> + help
> + Say y here will enable PSCI reboot mode driver. This gets
> + the PSCI reboot mode arguments and passes them to psci
> + driver. psci driver uses these arguments for issuing
> + device reset into different boot states.
> +
> config POWER_MLXBF
> tristate "Mellanox BlueField power handling driver"
> depends on (GPIO_MLXBF2 || GPIO_MLXBF3) && ACPI
[ ... ]
> diff --git a/drivers/power/reset/psci-reboot-mode.c b/drivers/power/reset/psci-reboot-mode.c
> new file mode 100644
> index 0000000000000..955ed68f14026
> --- /dev/null
> +++ b/drivers/power/reset/psci-reboot-mode.c
[ ... ]
> +static int psci_reboot_mode_write(struct reboot_mode_driver *reboot,
> + u32 *magic, int count)
> +{
> + if (count < 1 || count > 3)
> + return -EINVAL;
> +
> + return psci_set_reset_cmd(magic[0], psci_reboot_mode_get_cookie(magic, count));
[Severity: High]
Can this call to psci_set_reset_cmd() race with the atomic restart handler?
Looking at drivers/firmware/psci/psci.c, psci_sys_reset() evaluates reset_cmd
locklessly:
if ((reset_cmd.reset_type || reset_cmd.cookie) && !panic_in_progress())
psci_handle_reset_cmd();
And psci_set_reset_cmd() protects writes using a mutex:
reset_cmd.reset_type = reset_type;
reset_cmd.cookie = cookie;
If an atomic restart handler like psci_sys_reset() executes during a SysRq-B
emergency restart and interrupts a CPU executing psci_set_reset_cmd(), it could
observe a partially updated state.
Since the 64-bit cookie may be written via multiple instructions on 32-bit ARM,
could this lead to torn reads and mismatched reset types, causing the system to
hang during emergency restarts?
> +}
[ ... ]
> +static struct platform_driver psci_reboot_mode_driver = {
> + .probe = psci_reboot_mode_probe,
> + .driver = {
> + .name = "psci-reboot-mode",
> + },
> +};
[Severity: High]
Is this platform driver able to probe?
The driver lacks an of_match_table and is not instantiated as a child device
by any parent PSCI or MFD driver.
A platform driver without an of_match_table must be manually instantiated
(e.g., via mfd_add_devices in an MFD parent like psci-mfd.c). However,
psci_reboot_mode is not listed in psci_cells in drivers/mfd/psci-mfd.c, nor
does any code call of_platform_populate() on the PSCI node.
Does this make the newly introduced psci-reboot-mode functionality unreachable
dead code?
> +module_platform_driver(psci_reboot_mode_driver);
> +
> +MODULE_DESCRIPTION("PSCI reboot mode driver");
> +MODULE_LICENSE("GPL");
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-arm-psci-system_reset2-vendor-reboots-v23-0-e7453c548c21@oss.qualcomm.com?part=7
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v23 08/13] mfd: core: Add firmware-node support to MFD cells
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
` (6 preceding siblings ...)
2026-07-14 17:16 ` [PATCH v23 07/13] power: reset: Add psci-reboot-mode driver Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:30 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 09/13] mfd: psci-mfd: Add psci-reboot-mode child cell Shivendra Pratap
` (4 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla, Bartosz Golaszewski
MFD core has no way to register a child device using an explicit firmware
node. This prevents drivers from registering child nodes when those nodes
do not define a compatible string. One such example is the PSCI
"reboot-mode" node, which omits a compatible string as it describes
boot-states provided by the underlying firmware.
Extend struct mfd_cell with a named firmware-node field to identify a
child node under the MFD parent. The node is added to the MFD child
device during registration when none is assigned by device tree, ACPI,
or software matching.
Suggested-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
drivers/mfd/mfd-core.c | 142 ++++++++++++++++++++++++++++++++++++++++-------
include/linux/mfd/core.h | 10 ++++
2 files changed, 131 insertions(+), 21 deletions(-)
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 7aa32b90cf1e..ba9682ead2ca 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
+#include <linux/fwnode.h>
#include <linux/list.h>
#include <linux/property.h>
#include <linux/mfd/core.h>
@@ -22,6 +23,7 @@
#include <linux/regulator/consumer.h>
static LIST_HEAD(mfd_of_node_list);
+static LIST_HEAD(mfd_named_fwnode_list);
static DEFINE_MUTEX(mfd_of_node_mutex);
struct mfd_of_node_entry {
@@ -30,10 +32,91 @@ struct mfd_of_node_entry {
struct device_node *np;
};
+struct mfd_named_fwnode_entry {
+ struct list_head list;
+ struct device *dev;
+ struct fwnode_handle *fwnode;
+};
+
static const struct device_type mfd_dev_type = {
.name = "mfd_device",
};
+static int mfd_claim_named_fwnode(struct platform_device *pdev,
+ struct fwnode_handle *fwnode)
+{
+ struct mfd_named_fwnode_entry *entry, *iter;
+
+ entry = kzalloc_obj(*entry, GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
+ entry->dev = &pdev->dev;
+ entry->fwnode = fwnode_handle_get(fwnode);
+
+ scoped_guard(mutex, &mfd_of_node_mutex) {
+ list_for_each_entry(iter, &mfd_named_fwnode_list, list)
+ if (iter->fwnode == fwnode) {
+ fwnode_handle_put(entry->fwnode);
+ kfree(entry);
+ return -EAGAIN;
+ }
+
+ list_add_tail(&entry->list, &mfd_named_fwnode_list);
+ }
+
+ return 0;
+}
+
+/*
+ * Temporary MFD-local cleanup for named non-OF child fwnodes.
+ * Remove/rework this when platform core starts owning and dropping
+ * dev->fwnode references for these devices.
+ */
+static void mfd_release_named_fwnode(struct platform_device *pdev)
+{
+ struct mfd_named_fwnode_entry *entry, *tmp;
+
+ scoped_guard(mutex, &mfd_of_node_mutex) {
+ list_for_each_entry_safe(entry, tmp, &mfd_named_fwnode_list, list)
+ if (entry->dev == &pdev->dev) {
+ if (dev_fwnode(&pdev->dev) == entry->fwnode)
+ device_set_node(&pdev->dev, NULL);
+ fwnode_handle_put(entry->fwnode);
+ list_del(&entry->list);
+ kfree(entry);
+ }
+ }
+}
+
+static int mfd_claim_of_node_to_dev(struct platform_device *pdev,
+ struct device_node *np)
+{
+ struct mfd_of_node_entry *of_entry, *iter;
+
+ of_entry = kzalloc_obj(*of_entry, GFP_KERNEL);
+ if (!of_entry)
+ return -ENOMEM;
+
+ of_entry->dev = &pdev->dev;
+ of_entry->np = of_node_get(np);
+
+ /* Skip if OF node has previously been allocated to a device */
+ scoped_guard(mutex, &mfd_of_node_mutex) {
+ list_for_each_entry(iter, &mfd_of_node_list, list)
+ if (iter->np == np) {
+ of_node_put(of_entry->np);
+ kfree(of_entry);
+ return -EAGAIN;
+ }
+
+ list_add_tail(&of_entry->list, &mfd_of_node_list);
+ }
+
+ device_set_node(&pdev->dev, of_fwnode_handle(np));
+ return 0;
+}
+
#if IS_ENABLED(CONFIG_ACPI)
struct match_ids_walk_data {
struct acpi_device_id *ids;
@@ -111,19 +194,11 @@ static int mfd_match_of_node_to_dev(struct platform_device *pdev,
struct device_node *np,
const struct mfd_cell *cell)
{
- struct mfd_of_node_entry *of_entry;
u64 of_node_addr;
- /* Skip if OF node has previously been allocated to a device */
- scoped_guard(mutex, &mfd_of_node_mutex) {
- list_for_each_entry(of_entry, &mfd_of_node_list, list)
- if (of_entry->np == np)
- return -EAGAIN;
- }
-
if (!cell->use_of_reg)
/* No of_reg defined - allocate first free compatible match */
- goto allocate_of_node;
+ return mfd_claim_of_node_to_dev(pdev, np);
/* We only care about each node's first defined address */
if (of_property_read_reg(np, 0, &of_node_addr, NULL))
@@ -134,18 +209,7 @@ static int mfd_match_of_node_to_dev(struct platform_device *pdev,
/* No match */
return -EAGAIN;
-allocate_of_node:
- of_entry = kzalloc(sizeof(*of_entry), GFP_KERNEL);
- if (!of_entry)
- return -ENOMEM;
-
- of_entry->dev = &pdev->dev;
- of_entry->np = of_node_get(np);
- scoped_guard(mutex, &mfd_of_node_mutex)
- list_add_tail(&of_entry->list, &mfd_of_node_list);
-
- device_set_node(&pdev->dev, of_fwnode_handle(np));
- return 0;
+ return mfd_claim_of_node_to_dev(pdev, np);
}
static int mfd_add_device(struct device *parent, int id,
@@ -156,6 +220,7 @@ static int mfd_add_device(struct device *parent, int id,
struct resource *res;
struct platform_device *pdev;
struct mfd_of_node_entry *of_entry, *tmp;
+ struct fwnode_handle *fwnode;
bool disabled = false;
int ret = -ENOMEM;
int platform_id;
@@ -224,6 +289,37 @@ static int mfd_add_device(struct device *parent, int id,
mfd_acpi_add_device(cell, pdev);
+ /* named_fwnode is a fallback only when no OF/ACPI match and no swnode */
+ if (!pdev->dev.fwnode && !cell->swnode && cell->named_fwnode) {
+ struct device_node *named_np;
+
+ fwnode = device_get_named_child_node(parent, cell->named_fwnode);
+ if (!fwnode) {
+ ret = -ENODEV;
+ goto fail_alias;
+ }
+
+ named_np = to_of_node(fwnode);
+ if (named_np) {
+ ret = mfd_claim_of_node_to_dev(pdev, named_np);
+ fwnode_handle_put(fwnode);
+ if (ret == -EAGAIN)
+ ret = -EBUSY;
+ if (ret)
+ goto fail_alias;
+ } else {
+ ret = mfd_claim_named_fwnode(pdev, fwnode);
+ if (ret) {
+ fwnode_handle_put(fwnode);
+ if (ret == -EAGAIN)
+ ret = -EBUSY;
+ goto fail_alias;
+ }
+ device_set_node(&pdev->dev, fwnode);
+ fwnode_handle_put(fwnode);
+ }
+ }
+
if (cell->pdata_size) {
ret = platform_device_add_data(pdev,
cell->platform_data, cell->pdata_size);
@@ -295,6 +391,7 @@ static int mfd_add_device(struct device *parent, int id,
if (cell->swnode)
device_remove_software_node(&pdev->dev);
fail_of_entry:
+ mfd_release_named_fwnode(pdev);
scoped_guard(mutex, &mfd_of_node_mutex) {
list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list)
if (of_entry->dev == &pdev->dev) {
@@ -382,7 +479,10 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
cell->num_parent_supplies);
+ get_device(&pdev->dev);
platform_device_unregister(pdev);
+ mfd_release_named_fwnode(pdev);
+ put_device(&pdev->dev);
return 0;
}
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index faeea7abd688..8daa83dd31ea 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -80,6 +80,16 @@ struct mfd_cell {
/* Software node for the device. */
const struct software_node *swnode;
+ /*
+ * Name of a child firmware node under the MFD parent device.
+ *
+ * Used only as a fallback when no firmware node is assigned to MFD
+ * child and no software node is provided.
+ *
+ * For Device Tree parents, lookup is by base node name only
+ * (the part before '@'). Unit-addresses are not matched.
+ */
+ const char *named_fwnode;
/*
* Device Tree compatible string
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v23 08/13] mfd: core: Add firmware-node support to MFD cells
2026-07-14 17:16 ` [PATCH v23 08/13] mfd: core: Add firmware-node support to MFD cells Shivendra Pratap
@ 2026-07-14 17:30 ` sashiko-bot
0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-07-14 17:30 UTC (permalink / raw)
To: Shivendra Pratap; +Cc: lee, mfd, robh, conor+dt, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Strict enforcement of `named_fwnode` aborts the entire MFD probe if the node is missing.
--
--- Patch [8]: [PATCH v23 08/13] mfd: core: Add firmware-node support to MFD cells ---
commit c957d9fd3d002c62018221b0f97f57bad5c0b519
Author: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
mfd: core: Add firmware-node support to MFD cells
This commit extends struct mfd_cell with a named firmware-node field to allow
registering a child device using an explicit firmware node. It uses this as a
fallback when no firmware node is assigned by device tree, ACPI, or software
matching.
> diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
> index 7aa32b90cf1eb..ba9682ead2cad 100644
> --- a/drivers/mfd/mfd-core.c
> +++ b/drivers/mfd/mfd-core.c
[ ... ]
> @@ -224,6 +289,37 @@ static int mfd_add_device(struct device *parent, int id,
>
> mfd_acpi_add_device(cell, pdev);
>
> + /* named_fwnode is a fallback only when no OF/ACPI match and no swnode */
> + if (!pdev->dev.fwnode && !cell->swnode && cell->named_fwnode) {
> + struct device_node *named_np;
> +
> + fwnode = device_get_named_child_node(parent, cell->named_fwnode);
> + if (!fwnode) {
> + ret = -ENODEV;
> + goto fail_alias;
> + }
[Severity: High]
Will this strict enforcement cause the entire MFD parent probe to fail if an
optional child node is missing?
Unlike the permissive of_compatible match that merely warns and bypasses
missing nodes, returning -ENODEV here cascades up to mfd_add_devices(). This
causes a failure that unwinds all active child devices and blocks the parent
driver's probe.
Should a missing named firmware node be treated less strictly so it doesn't
disable unrelated MFD functions?
> +
> + named_np = to_of_node(fwnode);
> + if (named_np) {
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-arm-psci-system_reset2-vendor-reboots-v23-0-e7453c548c21@oss.qualcomm.com?part=8
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v23 09/13] mfd: psci-mfd: Add psci-reboot-mode child cell
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
` (7 preceding siblings ...)
2026-07-14 17:16 ` [PATCH v23 08/13] mfd: core: Add firmware-node support to MFD cells Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:24 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 10/13] arm64: dts: qcom: Add psci reboot-modes for kodiak boards Shivendra Pratap
` (3 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla, Bartosz Golaszewski
The PSCI "reboot-mode" node does not define a compatible because it is a
configuration of boot-states provided by the underlying firmware. With
the new firmware-node based cells in mfd-core, this node can now be
exposed as a proper child cell.
Add the psci-reboot-mode child cell to the psci-mfd driver with a
named_fwnode. Add psci-cpuidle-domain cell first to isolate it from
reboot-mode failures.
Suggested-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
drivers/mfd/psci-mfd.c | 30 +++++++++++++++++++++++++++++-
drivers/power/reset/Kconfig | 2 +-
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/drivers/mfd/psci-mfd.c b/drivers/mfd/psci-mfd.c
index 7affd6bb09dd..8c6b78ac471b 100644
--- a/drivers/mfd/psci-mfd.c
+++ b/drivers/mfd/psci-mfd.c
@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
static const struct mfd_cell psci_cells[] = {
{
@@ -14,10 +15,37 @@ static const struct mfd_cell psci_cells[] = {
},
};
+static const struct mfd_cell psci_reboot_mode_cell[] = {
+ {
+ .name = "psci-reboot-mode",
+ .named_fwnode = "reboot-mode",
+ },
+};
+
static int psci_mfd_probe(struct platform_device *pdev)
{
- return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, psci_cells,
+ struct fwnode_handle *fwnode;
+ int ret;
+
+ ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, psci_cells,
ARRAY_SIZE(psci_cells), NULL, 0, NULL);
+ if (ret)
+ return ret;
+
+ fwnode = device_get_named_child_node(&pdev->dev, "reboot-mode");
+ if (!fwnode)
+ return 0;
+
+ fwnode_handle_put(fwnode);
+
+ ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
+ psci_reboot_mode_cell,
+ ARRAY_SIZE(psci_reboot_mode_cell),
+ NULL, 0, NULL);
+ if (ret)
+ dev_warn(&pdev->dev, "reboot-mode child cell failed to add: %d\n", ret);
+
+ return 0;
}
static const struct of_device_id psci_mfd_of_match[] = {
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 93e4029d9506..b736a80eda00 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -350,7 +350,7 @@ config NVMEM_REBOOT_MODE
config PSCI_REBOOT_MODE
bool "PSCI reboot mode driver"
- depends on OF && (ARM_PSCI_FW || COMPILE_TEST)
+ depends on OF && ((ARM_PSCI_FW && MFD_PSCI) || COMPILE_TEST)
select REBOOT_MODE
help
Say y here will enable PSCI reboot mode driver. This gets
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v23 09/13] mfd: psci-mfd: Add psci-reboot-mode child cell
2026-07-14 17:16 ` [PATCH v23 09/13] mfd: psci-mfd: Add psci-reboot-mode child cell Shivendra Pratap
@ 2026-07-14 17:24 ` sashiko-bot
0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-07-14 17:24 UTC (permalink / raw)
To: Shivendra Pratap; +Cc: mfd, lee, robh, conor+dt, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The probe function `psci_mfd_probe` ignores the return value of `devm_mfd_add_devices()` for the `psci_reboot_mode_cell` child device, violating the MFD subsystem guideline requiring probe failures to be propagated and unwound.
--
--- Patch [9]: [PATCH v23 09/13] mfd: psci-mfd: Add psci-reboot-mode child cell ---
commit 73724460c58fad980d9dd8ef39b9485acffad30e
Author: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
mfd: psci-mfd: Add psci-reboot-mode child cell
This commit adds the psci-reboot-mode child cell to the psci-mfd driver.
It retrieves the reboot-mode firmware node and registers the new cell
using devm_mfd_add_devices if the node is present.
> diff --git a/drivers/mfd/psci-mfd.c b/drivers/mfd/psci-mfd.c
> index 7affd6bb09dd8..8c6b78ac471bf 100644
> --- a/drivers/mfd/psci-mfd.c
> +++ b/drivers/mfd/psci-mfd.c
[ ... ]
> @@ -14,10 +15,37 @@ static const struct mfd_cell psci_cells[] = {
> },
> };
>
> +static const struct mfd_cell psci_reboot_mode_cell[] = {
> + {
> + .name = "psci-reboot-mode",
> + .named_fwnode = "reboot-mode",
> + },
> +};
> +
> static int psci_mfd_probe(struct platform_device *pdev)
> {
> - return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, psci_cells,
> + struct fwnode_handle *fwnode;
> + int ret;
> +
> + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, psci_cells,
> ARRAY_SIZE(psci_cells), NULL, 0, NULL);
> + if (ret)
> + return ret;
> +
> + fwnode = device_get_named_child_node(&pdev->dev, "reboot-mode");
> + if (!fwnode)
> + return 0;
> +
> + fwnode_handle_put(fwnode);
> +
> + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
> + psci_reboot_mode_cell,
> + ARRAY_SIZE(psci_reboot_mode_cell),
> + NULL, 0, NULL);
> + if (ret)
> + dev_warn(&pdev->dev, "reboot-mode child cell failed to add: %d\n", ret);
> +
> + return 0;
[Severity: High]
Should this propagate the error code instead of returning 0?
The MFD subsystem guidelines specify that if a child device fails to register
during probe, the entire probe must fail and unwind previously registered
children. By returning 0 here, the MFD device is left in a partially
initialized state if the psci-reboot-mode cell fails to register.
> }
>
> static const struct of_device_id psci_mfd_of_match[] = {
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-arm-psci-system_reset2-vendor-reboots-v23-0-e7453c548c21@oss.qualcomm.com?part=9
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v23 10/13] arm64: dts: qcom: Add psci reboot-modes for kodiak boards
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
` (8 preceding siblings ...)
2026-07-14 17:16 ` [PATCH v23 09/13] mfd: psci-mfd: Add psci-reboot-mode child cell Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:32 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 11/13] arm64: dts: qcom: Add psci reboot-modes for lemans boards Shivendra Pratap
` (2 subsequent siblings)
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla, Bartosz Golaszewski
Add PSCI SYSTEM_RESET2 reboot-modes for qcm6490-idp and qcs6490-rb3gen2
for use by the psci-reboot-mode driver.
The following modes are defined:
- bootloader: reboot into fastboot mode for fastboot flashing.
- edl: reboot into emergency download mode for image loading via
the Firehose protocol.
Support for these modes is firmware dependent and not available across
all kodiak based boards.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/kodiak.dtsi | 2 +-
arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 7 +++++++
arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 7 +++++++
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
index 7e73348fe0d0..82713f49ba63 100644
--- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
+++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
@@ -866,7 +866,7 @@ pmu-a78 {
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
};
- psci {
+ psci: psci {
compatible = "arm,psci-1.0";
method = "smc";
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
index bdc02260f902..b7a0b5347639 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
+++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
@@ -786,6 +786,13 @@ &qup_uart7_tx {
bias-disable;
};
+&psci {
+ reboot-mode {
+ mode-bootloader = <0x80010001 0x2>;
+ mode-edl = <0x80000000 0x1>;
+ };
+};
+
&qupv3_id_0 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
index e9a932c90d14..0dd67cae41ff 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -1105,6 +1105,13 @@ &pon_resin {
status = "okay";
};
+&psci {
+ reboot-mode {
+ mode-bootloader = <0x80010001 0x2>;
+ mode-edl = <0x80000000 0x1>;
+ };
+};
+
&qup_uart7_cts {
/*
* Configure a bias-bus-hold on CTS to lower power
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v23 11/13] arm64: dts: qcom: Add psci reboot-modes for lemans boards
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
` (9 preceding siblings ...)
2026-07-14 17:16 ` [PATCH v23 10/13] arm64: dts: qcom: Add psci reboot-modes for kodiak boards Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:32 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 12/13] arm64: dts: qcom: Add psci reboot-modes for monaco boards Shivendra Pratap
2026-07-14 17:16 ` [PATCH v23 13/13] arm64: dts: qcom: Add psci reboot-modes for talos boards Shivendra Pratap
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla, Bartosz Golaszewski
Add PSCI SYSTEM_RESET2 reboot-modes for lemans-evk and
lemans-ride-common(sa8775p-ride, sa8775p-ride-r3, qcs9100-ride,
qcs9100-ride-r3) for use by the psci-reboot-mode driver.
The following modes are defined:
- bootloader: reboot into fastboot mode for fastboot flashing.
- edl: reboot into emergency download mode for image loading via
the Firehose protocol.
Support for these modes is firmware dependent.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/lemans-evk.dts | 7 +++++++
arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi | 7 +++++++
arch/arm64/boot/dts/qcom/lemans.dtsi | 2 +-
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts
index 0c53640c42a6..3baad102270d 100644
--- a/arch/arm64/boot/dts/qcom/lemans-evk.dts
+++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts
@@ -911,6 +911,13 @@ usb2_id: usb2-id-state {
};
};
+&psci {
+ reboot-mode {
+ mode-bootloader = <0x80010001 0x2>;
+ mode-edl = <0x80000000 0x1>;
+ };
+};
+
&qup_i2c19_default {
drive-strength = <2>;
bias-pull-up;
diff --git a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi
index cefb8ff00806..cc96442403e8 100644
--- a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi
@@ -800,6 +800,13 @@ &pmm8654au_3_gpios {
"GNSS_BOOT_MODE";
};
+&psci {
+ reboot-mode {
+ mode-bootloader = <0x80010001 0x2>;
+ mode-edl = <0x80000000 0x1>;
+ };
+};
+
&qupv3_id_1 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
index 3b0539e27b51..55a3fac0c4c6 100644
--- a/arch/arm64/boot/dts/qcom/lemans.dtsi
+++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
@@ -549,7 +549,7 @@ pmu {
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
};
- psci {
+ psci: psci {
compatible = "arm,psci-1.0";
method = "smc";
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v23 12/13] arm64: dts: qcom: Add psci reboot-modes for monaco boards
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
` (10 preceding siblings ...)
2026-07-14 17:16 ` [PATCH v23 11/13] arm64: dts: qcom: Add psci reboot-modes for lemans boards Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:31 ` sashiko-bot
2026-07-14 17:16 ` [PATCH v23 13/13] arm64: dts: qcom: Add psci reboot-modes for talos boards Shivendra Pratap
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla, Bartosz Golaszewski
Add PSCI SYSTEM_RESET2 reboot-modes for monaco-evk and
qcs8300-ride for use by the psci-reboot-mode driver.
The following modes are defined:
- bootloader: reboot into fastboot mode for fastboot flashing.
- edl: reboot into emergency download mode for image loading via
the Firehose protocol.
Support for these modes is firmware dependent.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/monaco-evk.dts | 7 +++++++
arch/arm64/boot/dts/qcom/monaco.dtsi | 2 +-
arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 7 +++++++
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts
index 9d17ef7d2caf..df668dbf2bc6 100644
--- a/arch/arm64/boot/dts/qcom/monaco-evk.dts
+++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts
@@ -661,6 +661,13 @@ usb2_id: usb2-id-state {
};
};
+&psci {
+ reboot-mode {
+ mode-bootloader = <0x80010001 0x2>;
+ mode-edl = <0x80000000 0x1>;
+ };
+};
+
&qup_i2c0_data_clk {
drive-strength = <2>;
bias-pull-up;
diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi
index 64fc0d592282..824ec3838c75 100644
--- a/arch/arm64/boot/dts/qcom/monaco.dtsi
+++ b/arch/arm64/boot/dts/qcom/monaco.dtsi
@@ -654,7 +654,7 @@ pmu-a78 {
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
};
- psci {
+ psci: psci {
compatible = "arm,psci-1.0";
method = "smc";
diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
index e9a8553a8d82..3ab5ae3124ed 100644
--- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
+++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
@@ -678,6 +678,13 @@ &mdss_dsi0_out {
remote-endpoint = <&dsi2dp_bridge_in>;
};
+&psci {
+ reboot-mode {
+ mode-bootloader = <0x80010001 0x2>;
+ mode-edl = <0x80000000 0x1>;
+ };
+};
+
&qupv3_id_0 {
status = "okay";
};
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v23 13/13] arm64: dts: qcom: Add psci reboot-modes for talos boards
2026-07-14 17:16 [PATCH v23 00/13] Implement PSCI reboot mode driver for PSCI resets Shivendra Pratap
` (11 preceding siblings ...)
2026-07-14 17:16 ` [PATCH v23 12/13] arm64: dts: qcom: Add psci reboot-modes for monaco boards Shivendra Pratap
@ 2026-07-14 17:16 ` Shivendra Pratap
2026-07-14 17:32 ` sashiko-bot
12 siblings, 1 reply; 27+ messages in thread
From: Shivendra Pratap @ 2026-07-14 17:16 UTC (permalink / raw)
To: Sebastian Reichel, Mark Rutland, Lorenzo Pieralisi,
Rafael J. Wysocki, Daniel Lezcano, Christian Loehle, Ulf Hansson,
Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Arnd Bergmann, Souvik Chakravarty,
Andy Yan, Matthias Brugger, John Stultz, Moritz Fischer,
Bartosz Golaszewski, Sudeep Holla, Ulf Hansson
Cc: linux-pm, linux-kernel, linux-arm-msm, linux-arm-kernel,
devicetree, Shivendra Pratap, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, mfd,
Srinivas Kandagatla, Bartosz Golaszewski, Song Xue
Add PSCI SYSTEM_RESET2 reboot-modes for qcs615-ride, for use by the
psci-reboot-mode driver.
The following modes are defined:
- bootloader: reboot into fastboot mode for fastboot flashing.
- edl: reboot into emergency download mode for image loading via the
Firehose protocol.
Support for these modes is firmware dependent.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Song Xue <quic_songxue@quicinc.com>
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/qcs615-ride.dts | 7 +++++++
arch/arm64/boot/dts/qcom/talos.dtsi | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/qcs615-ride.dts b/arch/arm64/boot/dts/qcom/qcs615-ride.dts
index 047b4efb04b9..48d3519f50ff 100644
--- a/arch/arm64/boot/dts/qcom/qcs615-ride.dts
+++ b/arch/arm64/boot/dts/qcom/qcs615-ride.dts
@@ -498,6 +498,13 @@ &pon_resin {
status = "okay";
};
+&psci {
+ reboot-mode {
+ mode-bootloader = <0x80010001 0x2>;
+ mode-edl = <0x80000000 0x1>;
+ };
+};
+
&qspi {
status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi
index bdfb70ca9740..6a7ce5a2963a 100644
--- a/arch/arm64/boot/dts/qcom/talos.dtsi
+++ b/arch/arm64/boot/dts/qcom/talos.dtsi
@@ -581,7 +581,7 @@ pmu-a76 {
interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH &ppi_cluster1>;
};
- psci {
+ psci: psci {
compatible = "arm,psci-1.0";
method = "smc";
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread