From: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
To: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>,
Bjorn Andersson <andersson@kernel.org>,
Sebastian Reichel <sre@kernel.org>, Rob Herring <robh@kernel.org>,
Sudeep Holla <sudeep.holla@arm.com>,
Souvik Chakravarty <Souvik.Chakravarty@arm.com>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Andy Yan <andy.yan@rock-chips.com>,
Mark Rutland <mark.rutland@arm.com>,
Lorenzo Pieralisi <lpieralisi@kernel.org>,
Arnd Bergmann <arnd@arndb.de>,
Konrad Dybcio <konradybcio@kernel.org>,
cros-qcom-dts-watchers@chromium.org,
Vinod Koul <vkoul@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Florian Fainelli <florian.fainelli@broadcom.com>
Cc: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>,
Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>,
Stephen Boyd <swboyd@chromium.org>,
Andre Draszik <andre.draszik@linaro.org>,
linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-arm-msm@vger.kernel.org,
Elliot Berman <quic_eberman@quicinc.com>,
Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>,
Srinivas Kandagatla <srini@kernel.org>
Subject: [PATCH v11 8/8] power: reset: reboot-mode: Expose sysfs for registered reboot_modes
Date: Thu, 17 Jul 2025 18:16:54 +0530 [thread overview]
Message-ID: <20250717-arm-psci-system_reset2-vendor-reboots-v11-8-df3e2b2183c3@oss.qualcomm.com> (raw)
In-Reply-To: <20250717-arm-psci-system_reset2-vendor-reboots-v11-0-df3e2b2183c3@oss.qualcomm.com>
Currently, there is no standardized mechanism for userspace to
discover which reboot-modes are supported on a given platform.
This limitation forces tools and scripts to rely on hardcoded
assumptions about the supported reboot-modes.
Create a class 'reboot-mode' and a device under it to expose a
sysfs interface to show the available reboot mode arguments to
userspace.
Create the device using the node name of the driver that
registers with reboot mode driver.
This results in the creation of:
/sys/class/reboot-mode/<driver>/reboot_modes
This read-only sysfs file will exposes the list of supported
reboot modes arguments provided by the driver, enabling userspace
to query the list of arguments.
Align the clean up path to maintain backward compatibility for
existing reboot-mode based drivers.
Add ABI documentation for /sys/class/reboot-mode/*/reboot_modes.
Signed-off-by: Shivendra Pratap <shivendra.pratap@oss.qualcomm.com>
---
.../testing/sysfs-class-reboot-mode-reboot_modes | 38 +++++++++
drivers/power/reset/reboot-mode.c | 96 +++++++++++++++++++---
include/linux/reboot-mode.h | 1 +
3 files changed, 123 insertions(+), 12 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes b/Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes
new file mode 100644
index 0000000000000000000000000000000000000000..63b3ef1ecc66c73744fc831fa9864592c514bd56
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes
@@ -0,0 +1,38 @@
+What: /sys/class/reboot-mode/<driver>/reboot_modes
+Date: July 2025
+KernelVersion: 6.16
+Contact: linux-pm@vger.kernel.org
+ Description:
+ This interface exposes the reboot-mode arguments
+ registered with the reboot-mode framework. It is
+ a read-only interface and provides a comma
+ separated list of reboot-mode arguments supported
+ on the current platform.
+ Example:
+ normal,recovery,fastboot,bootloader
+
+ The exact sysfs path may vary depending on the
+ driver that registers the arguments.
+ Example:
+ /sys/class/reboot-mode/reboot-mode/reboot_modes
+ /sys/class/reboot-mode/pon/reboot_modes
+
+ The supported arguments can be used by userspace
+ to invoke device reset using the reboot() system
+ call, with the "argument" as string to "*arg"
+ parameter along with LINUX_REBOOT_CMD_RESTART2.
+ Example:
+ reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_RESTART2, "bootloader");
+
+ A driver can expose the supported arguments by
+ registering them with the reboot-mode framework
+ using the property names that follow the
+ mode-<argument> format.
+ Example:
+ mode-bootloader, mode-recovery.
+
+ This attribute is useful for scripts or initramfs
+ logic that need to programmatically determine
+ which reboot-mode arguments are valid before
+ triggering a reboot.
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
index 1196627fbf98d87eec57a3d4ee544e403e6eb946..af3551fe2f625aacd31699604b7cbdd66c318c00 100644
--- a/drivers/power/reset/reboot-mode.c
+++ b/drivers/power/reset/reboot-mode.c
@@ -6,6 +6,7 @@
#define pr_fmt(fmt) "reboot-mode: " fmt
#include <linux/device.h>
+#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
@@ -23,6 +24,8 @@ struct mode_info {
struct list_head list;
};
+static struct class *rb_class;
+
static struct mode_info *get_reboot_mode_info(struct reboot_mode_driver *reboot, const char *cmd)
{
const char *normal = "normal";
@@ -65,6 +68,79 @@ static int reboot_mode_notify(struct notifier_block *this,
return NOTIFY_DONE;
}
+static void release_reboot_mode_device(struct device *dev, void *res);
+
+static ssize_t reboot_modes_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct reboot_mode_driver **devres_reboot;
+ struct reboot_mode_driver *reboot;
+ struct mode_info *info;
+ ssize_t size = 0;
+
+ devres_reboot = devres_find(dev, release_reboot_mode_device, NULL, 0);
+ reboot = *devres_reboot;
+ list_for_each_entry(info, &reboot->head, list) {
+ size += sprintf(buf + size, "%s,", info->mode);
+ }
+
+ if (size) {
+ size += sprintf(buf + size - 1, "\n");
+ return size;
+ }
+
+ return -ENODATA;
+}
+static DEVICE_ATTR_RO(reboot_modes);
+
+static void release_reboot_mode_device(struct device *dev, void *res)
+{
+ struct reboot_mode_driver *reboot = *(struct reboot_mode_driver **)res;
+ struct mode_info *info;
+ struct mode_info *next;
+
+ unregister_reboot_notifier(&reboot->reboot_notifier);
+
+ list_for_each_entry_safe(info, next, &reboot->head, list) {
+ kfree_const(info->mode);
+ list_del(&info->list);
+ kfree(info);
+ }
+
+ device_remove_file(reboot->dev, &dev_attr_reboot_modes);
+}
+
+static int create_reboot_mode_device(struct reboot_mode_driver *reboot,
+ const char *dev_name)
+{
+ struct reboot_mode_driver **dr;
+ int ret = 0;
+
+ if (!rb_class) {
+ rb_class = class_create("reboot-mode");
+ if (IS_ERR(rb_class))
+ return PTR_ERR(rb_class);
+ }
+
+ reboot->reboot_dev = device_create(rb_class, NULL, 0, NULL, dev_name);
+ if (IS_ERR(reboot->reboot_dev))
+ return PTR_ERR(reboot->reboot_dev);
+
+ ret = device_create_file(reboot->reboot_dev, &dev_attr_reboot_modes);
+ if (ret)
+ return ret;
+
+ dr = devres_alloc(release_reboot_mode_device, sizeof(*dr), GFP_KERNEL);
+ if (!dr) {
+ device_remove_file(reboot->reboot_dev, &dev_attr_reboot_modes);
+ return -ENOMEM;
+ }
+
+ *dr = reboot;
+ devres_add(reboot->reboot_dev, dr);
+
+ return ret;
+}
+
/**
* reboot_mode_register - register a reboot mode driver
* @reboot: reboot mode driver
@@ -83,6 +159,10 @@ int reboot_mode_register(struct reboot_mode_driver *reboot, struct device_node *
if (!np)
return -EINVAL;
+ ret = create_reboot_mode_device(reboot, np->name ? np->name : "reboot-mode-dev");
+ if (ret)
+ return ret;
+
INIT_LIST_HEAD(&reboot->head);
for_each_property_of_node(np, prop) {
@@ -137,24 +217,16 @@ EXPORT_SYMBOL_GPL(reboot_mode_register);
*/
int reboot_mode_unregister(struct reboot_mode_driver *reboot)
{
- struct mode_info *info;
- struct mode_info *next;
-
- unregister_reboot_notifier(&reboot->reboot_notifier);
-
- list_for_each_entry_safe(info, next, &reboot->head, list) {
- kfree_const(info->mode);
- list_del(&info->list);
- kfree(info);
- }
-
+ device_unregister(reboot->reboot_dev);
return 0;
}
EXPORT_SYMBOL_GPL(reboot_mode_unregister);
static void devm_reboot_mode_release(struct device *dev, void *res)
{
- reboot_mode_unregister(*(struct reboot_mode_driver **)res);
+ struct reboot_mode_driver *reboot = *(struct reboot_mode_driver **)res;
+
+ device_unregister(reboot->reboot_dev);
}
/**
diff --git a/include/linux/reboot-mode.h b/include/linux/reboot-mode.h
index d9d9165a8635e5d55d92197a69c7fae179ac2045..8fb35ef1c00749500a99d088b5f7010d57547844 100644
--- a/include/linux/reboot-mode.h
+++ b/include/linux/reboot-mode.h
@@ -6,6 +6,7 @@
struct reboot_mode_driver {
struct device *dev;
+ struct device *reboot_dev;
struct list_head head;
int (*write)(struct reboot_mode_driver *reboot, u64 magic);
struct notifier_block reboot_notifier;
--
2.34.1
next prev parent reply other threads:[~2025-07-17 12:48 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-17 12:46 [PATCH v11 0/8] Implement vendor resets for PSCI SYSTEM_RESET2 Shivendra Pratap
2025-07-17 12:46 ` [PATCH v11 1/8] power: reset: reboot-mode: Add device tree node-based registration Shivendra Pratap
2025-07-18 18:37 ` Dmitry Baryshkov
2025-07-19 15:35 ` Shivendra Pratap
2025-07-20 18:43 ` Dmitry Baryshkov
2025-07-17 12:46 ` [PATCH v11 2/8] power: reset: reboot-mode: Add support for 64 bit magic Shivendra Pratap
2025-07-18 18:40 ` Dmitry Baryshkov
2025-07-19 15:13 ` Shivendra Pratap
2025-07-19 16:57 ` Andrew Lunn
2025-07-19 17:37 ` Shivendra Pratap
2025-07-20 15:16 ` Andrew Lunn
2025-07-20 15:24 ` Shivendra Pratap
2025-07-17 12:46 ` [PATCH v11 3/8] dt-bindings: arm: Document reboot mode magic Shivendra Pratap
2025-07-17 12:46 ` [PATCH v11 4/8] firmware: psci: Implement vendor-specific resets as reboot-mode Shivendra Pratap
2025-07-17 12:46 ` [PATCH v11 5/8] arm64: dts: qcom: qcm6490-idp: Add PSCI SYSTEM_RESET2 types Shivendra Pratap
2025-07-17 12:46 ` [PATCH v11 6/8] arm64: dts: qcom: qcs6490-rb3gen2: " Shivendra Pratap
2025-07-17 12:46 ` [PATCH v11 7/8] arm64: dts: qcom: sa8775p-ride: " Shivendra Pratap
2025-07-17 12:46 ` Shivendra Pratap [this message]
2025-07-18 21:29 ` [PATCH v11 0/8] Implement vendor resets for PSCI SYSTEM_RESET2 Florian Fainelli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250717-arm-psci-system_reset2-vendor-reboots-v11-8-df3e2b2183c3@oss.qualcomm.com \
--to=shivendra.pratap@oss.qualcomm.com \
--cc=Souvik.Chakravarty@arm.com \
--cc=andersson@kernel.org \
--cc=andre.draszik@linaro.org \
--cc=andy.yan@rock-chips.com \
--cc=arnd@arndb.de \
--cc=bartosz.golaszewski@linaro.org \
--cc=catalin.marinas@arm.com \
--cc=conor+dt@kernel.org \
--cc=cros-qcom-dts-watchers@chromium.org \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=florian.fainelli@broadcom.com \
--cc=konradybcio@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=mark.rutland@arm.com \
--cc=mukesh.ojha@oss.qualcomm.com \
--cc=quic_eberman@quicinc.com \
--cc=robh@kernel.org \
--cc=sre@kernel.org \
--cc=srini@kernel.org \
--cc=sudeep.holla@arm.com \
--cc=swboyd@chromium.org \
--cc=vkoul@kernel.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).