* [PATCH v3 0/3] power: reset: Add NVMEM recorder provider for PSCRR
@ 2026-09-14 4:38 Faruque Ansari
2026-09-14 4:38 ` [PATCH v3 1/3] dt-bindings: nvmem: layouts: Add PSCRR NVMEM layout Faruque Ansari
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Faruque Ansari @ 2026-09-14 4:38 UTC (permalink / raw)
To: Oleksij Rempel, Pengutronix Kernel Team, Sebastian Reichel,
Rob Herring, Krzysztof Kozlowski, Wim Van Sebroeck,
Guenter Roeck, Benson Leung, Tzung-Bi Shih, Srinivas Kandagatla,
Daniel Lezcano
Cc: linux-arm-msm, linux-kernel, linux-pm, devicetree,
linux-watchdog, kernel, Liam Girdwood, Mark Brown,
Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Søren Andersen,
Guenter Roeck, Matti Vaittinen, Ahmad Fatoum, Andrew Morton,
avaneesh.dwivedi, Umang Chheda, Faruque Ansari
The PSCRR framework[1] currently does not provide a recorder provider
capable of persisting power state change reasons across power cycles.
This series extends the PSCRR framework[1] with support for an
NVMEM-cell recorder provider, integrating PSCRR-recorded power state
change reasons with the NVMEM subsystem.
The recorder writes the power state change reason into a small NVMEM cell
(e.g. a PMIC SDAM byte or RTC scratch register) before shutdown or reset,
so the cause survives a power cycle and is available via
/sys/kernel/pscrr/ on the next boot.
Only the NVMEM-cell provider is included here. The PMIC hardware-register
provider will be submitted as a separate series.
[1] https://lore.kernel.org/lkml/20260731095959.296056-1-o.rempel@pengutronix.de/
---
Changes in v3:
- Drop unnecessary nvmem_cell_get_size() and core compatibility
detection changes because the layout now owns the compatible.
- Patch 1/3 (dt-bindings): Move compatible from the cell to the
nvmem-layout node, relocate binding to nvmem/layouts/, and
simplify the cell to a plain reg/bits child.
- Drop the trailing "binding" from the subject, as suggested by
Krzysztof.
- Patch 2/3 (driver): Convert pscrr-nvmem from a consumer-based
platform driver to an nvmem_layout_driver that directly manages
its cell.
- Patch 3/3 (dts): Update DTS to place compatible on the layout
node, add bits to reboot_reason_persist, and remove the separate
reboot-reason consumer node.
- Link to v2: https://patch.msgid.link/20260819-pscrr-provider-v2-0-9072383e0f4d@oss.qualcomm.com
Changes in v2:
- Add reviewers to To/Cc list.
- Update patch 1/4:
* Rename DT node from pscr-reason to reboot-reason.
* Update DT binding example to use fixed-layout NVMEM layout.
* Add reboot_reason_persist NVMEM cell under fixed-layout.
* Update Qualcomm DTS example accordingly.
- Update patch 2/4 based on Uwe Kleine-König feedback:
* Remove unnecessary #include <linux/mod_devicetable.h>
- Link to v1: https://lore.kernel.org/all/20260817-pscrr-provider-v1-0-88a318c13d41@oss.qualcomm.com/
---
Faruque Ansari (3):
dt-bindings: nvmem: layouts: Add PSCRR NVMEM layout
power: reset: Add PSCRR NVMEM recorder
arm64: dts: qcom: lemans: Add PSCRR NVMEM recorder node
.../bindings/nvmem/layouts/nvmem-layout.yaml | 1 +
.../bindings/nvmem/layouts/pscrr-nvmem.yaml | 87 +++++++
MAINTAINERS | 1 +
arch/arm64/boot/dts/qcom/lemans-pmics.dtsi | 11 +
drivers/power/reset/pscrr/Kconfig | 14 ++
drivers/power/reset/pscrr/Makefile | 1 +
drivers/power/reset/pscrr/pscrr-nvmem.c | 269 +++++++++++++++++++++
7 files changed, 384 insertions(+)
---
base-commit: be461b2185ea3ff6d9c92deedcee0a62a57e1332
change-id: 20260806-pscrr-provider-b9f8f451701e
Best regards,
--
Faruque Ansari <faruque.ansari@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/3] dt-bindings: nvmem: layouts: Add PSCRR NVMEM layout
2026-09-14 4:38 [PATCH v3 0/3] power: reset: Add NVMEM recorder provider for PSCRR Faruque Ansari
@ 2026-09-14 4:38 ` Faruque Ansari
2026-09-24 15:19 ` Rob Herring (Arm)
2026-09-14 4:38 ` [PATCH v3 2/3] power: reset: Add PSCRR NVMEM recorder Faruque Ansari
2026-09-14 4:38 ` [PATCH v3 3/3] arm64: dts: qcom: lemans: Add PSCRR NVMEM recorder node Faruque Ansari
2 siblings, 1 reply; 5+ messages in thread
From: Faruque Ansari @ 2026-09-14 4:38 UTC (permalink / raw)
To: Oleksij Rempel, Pengutronix Kernel Team, Sebastian Reichel,
Rob Herring, Krzysztof Kozlowski, Wim Van Sebroeck,
Guenter Roeck, Benson Leung, Tzung-Bi Shih, Srinivas Kandagatla,
Daniel Lezcano
Cc: linux-arm-msm, linux-kernel, linux-pm, devicetree,
linux-watchdog, kernel, Liam Girdwood, Mark Brown,
Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Søren Andersen,
Guenter Roeck, Matti Vaittinen, Ahmad Fatoum, Andrew Morton,
avaneesh.dwivedi, Umang Chheda, Faruque Ansari
Add a schema for the PSCRR NVMEM layout, which persists the power
state change reason in a single NVMEM cell so it survives a power
cycle and can be read back on the next boot.
Signed-off-by: Faruque Ansari <faruque.ansari@oss.qualcomm.com>
---
.../bindings/nvmem/layouts/nvmem-layout.yaml | 1 +
.../bindings/nvmem/layouts/pscrr-nvmem.yaml | 87 ++++++++++++++++++++++
MAINTAINERS | 1 +
3 files changed, 89 insertions(+)
diff --git a/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml b/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml
index 382507060651..24545db61416 100644
--- a/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml
+++ b/Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml
@@ -21,6 +21,7 @@ oneOf:
- $ref: fixed-layout.yaml
- $ref: kontron,sl28-vpd.yaml
- $ref: onie,tlv-layout.yaml
+ - $ref: pscrr-nvmem.yaml
- $ref: u-boot,env.yaml
properties:
diff --git a/Documentation/devicetree/bindings/nvmem/layouts/pscrr-nvmem.yaml b/Documentation/devicetree/bindings/nvmem/layouts/pscrr-nvmem.yaml
new file mode 100644
index 000000000000..118669d33f5c
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/layouts/pscrr-nvmem.yaml
@@ -0,0 +1,87 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/layouts/pscrr-nvmem.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVMEM layout for the Power State Change Reason recorder (PSCRR)
+
+maintainers:
+ - Faruque Ansari <faruque.ansari@oss.qualcomm.com>
+ - Oleksij Rempel <o.rempel@pengutronix.de>
+
+description:
+ An NVMEM layout for a Power State Change Reason (PSCRR) recorder. The
+ reboot or shutdown cause is persisted into a single small NVMEM cell,
+ such as an RTC scratch register, a PMIC SDAM (Scratch Data Access Memory)
+ byte, or an EEPROM byte, so the reason survives a power cycle and can be
+ read back on the next boot.
+
+select: false
+
+properties:
+ compatible:
+ const: pscrr-nvmem
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+patternProperties:
+ "^.*@[0-9a-f]+$":
+ type: object
+ description:
+ The single NVMEM cell used to persist the power state change reason.
+
+ properties:
+ reg:
+ items:
+ - items:
+ - description: Offset, in bytes, of the cell within the
+ parent NVMEM device.
+ - const: 1
+ description:
+ Offset and size, in bytes, of the cell within the parent NVMEM
+ device. The reason value occupies a single byte, so the size
+ must be 1.
+
+ bits:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ items:
+ - minimum: 0
+ maximum: 7
+ description:
+ Bit offset within the byte addressed by reg.
+ - minimum: 1
+ maximum: 8
+ description:
+ Number of bits used to store the reason. Must be wide enough
+ to hold every value of enum psc_reason (currently 4 bits or
+ more).
+ description:
+ Optional. When absent, the whole byte addressed by reg is used.
+
+ required:
+ - reg
+
+ additionalProperties: false
+
+required:
+ - compatible
+
+additionalProperties: false
+
+examples:
+ - |
+ nvmem-layout {
+ compatible = "pscrr-nvmem";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ reboot-reason-persist@49 {
+ reg = <0x49 0x1>;
+ bits = <0 4>;
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 19b9f6605d98..51f31e95f4ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21693,6 +21693,7 @@ R: Pengutronix Kernel Team <kernel@pengutronix.de>
L: linux-pm@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/sysfs-kernel-pscrr
+F: Documentation/devicetree/bindings/nvmem/layouts/pscrr-nvmem.yaml
F: drivers/power/reset/pscrr/
F: include/linux/pscrr.h
F: tools/testing/selftests/pscrr/
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 2/3] power: reset: Add PSCRR NVMEM recorder
2026-09-14 4:38 [PATCH v3 0/3] power: reset: Add NVMEM recorder provider for PSCRR Faruque Ansari
2026-09-14 4:38 ` [PATCH v3 1/3] dt-bindings: nvmem: layouts: Add PSCRR NVMEM layout Faruque Ansari
@ 2026-09-14 4:38 ` Faruque Ansari
2026-09-14 4:38 ` [PATCH v3 3/3] arm64: dts: qcom: lemans: Add PSCRR NVMEM recorder node Faruque Ansari
2 siblings, 0 replies; 5+ messages in thread
From: Faruque Ansari @ 2026-09-14 4:38 UTC (permalink / raw)
To: Oleksij Rempel, Pengutronix Kernel Team, Sebastian Reichel,
Rob Herring, Krzysztof Kozlowski, Wim Van Sebroeck,
Guenter Roeck, Benson Leung, Tzung-Bi Shih, Srinivas Kandagatla,
Daniel Lezcano
Cc: linux-arm-msm, linux-kernel, linux-pm, devicetree,
linux-watchdog, kernel, Liam Girdwood, Mark Brown,
Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Søren Andersen,
Guenter Roeck, Matti Vaittinen, Ahmad Fatoum, Andrew Morton,
avaneesh.dwivedi, Umang Chheda, Faruque Ansari
Record the power state change reason into a NVMEM cell (a PMIC
SDAM byte, RTC scratch register, or EEPROM) and read it back on the
next boot, so the cause survives a power cycle.
The recorder is implemented as an NVMEM layout driver: it owns the
single cell described by its layout binding and adds it to the
parent NVMEM device, rather than acting as a standalone consumer of
someone else's cell.
Co-developed-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Faruque Ansari <faruque.ansari@oss.qualcomm.com>
---
drivers/power/reset/pscrr/Kconfig | 14 ++
drivers/power/reset/pscrr/Makefile | 1 +
drivers/power/reset/pscrr/pscrr-nvmem.c | 269 ++++++++++++++++++++++++++++++++
3 files changed, 284 insertions(+)
diff --git a/drivers/power/reset/pscrr/Kconfig b/drivers/power/reset/pscrr/Kconfig
index 72de82731b53..459b05ba32d3 100644
--- a/drivers/power/reset/pscrr/Kconfig
+++ b/drivers/power/reset/pscrr/Kconfig
@@ -31,3 +31,17 @@ menuconfig PSCRR
unless hardware provides the reset cause.
If unsure, say N.
+
+if PSCRR
+
+config PSCRR_NVMEM
+ tristate "PSCRR NVMEM recorder provider"
+ depends on NVMEM_LAYOUTS
+ help
+ PSCRR recorder that stores the power state change reason in a
+ small NVMEM cell (such as an RTC scratch register) and reads it
+ back on the next boot, so the cause survives a power cycle.
+
+ If unsure, say N.
+
+endif # PSCRR
diff --git a/drivers/power/reset/pscrr/Makefile b/drivers/power/reset/pscrr/Makefile
index e5530a858971..95c80c80c7da 100644
--- a/drivers/power/reset/pscrr/Makefile
+++ b/drivers/power/reset/pscrr/Makefile
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PSCRR) += pscrr.o
+obj-$(CONFIG_PSCRR_NVMEM) += pscrr-nvmem.o
diff --git a/drivers/power/reset/pscrr/pscrr-nvmem.c b/drivers/power/reset/pscrr/pscrr-nvmem.c
new file mode 100644
index 000000000000..64f67f0521e0
--- /dev/null
+++ b/drivers/power/reset/pscrr/pscrr-nvmem.c
@@ -0,0 +1,269 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pscrr-nvmem.c - NVMEM layout driver for PSCRR
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * Copyright (C) 2025 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
+ */
+
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/pscrr.h>
+#include <linux/slab.h>
+
+struct pscrr_nvmem {
+ struct nvmem_device *nvmem;
+ u32 offset; /* byte offset of the cell, from reg[0] */
+ u32 bit_offset; /* 0 when the cell has no "bits" property */
+ u32 nbits; /* BITS_PER_BYTE when the cell has no "bits" property */
+ enum psc_reason reason;
+};
+
+static inline u8 pscrr_nvmem_mask(struct pscrr_nvmem *priv)
+{
+ return (u8)GENMASK(priv->bit_offset + priv->nbits - 1, priv->bit_offset);
+}
+
+static int pscrr_nvmem_raw_read(struct pscrr_nvmem *priv, u8 *raw)
+{
+ int ret;
+
+ ret = nvmem_device_read(priv->nvmem, priv->offset, sizeof(*raw), raw);
+
+ return ret < 0 ? ret : 0;
+}
+
+static int pscrr_nvmem_raw_write(struct pscrr_nvmem *priv, u8 raw)
+{
+ int ret;
+
+ ret = nvmem_device_write(priv->nvmem, priv->offset, sizeof(raw), &raw);
+
+ return ret < 0 ? ret : 0;
+}
+
+static int pscrr_nvmem_cell_read(struct pscrr_nvmem *priv, u8 *out)
+{
+ u8 raw, mask = pscrr_nvmem_mask(priv);
+ int ret;
+
+ ret = pscrr_nvmem_raw_read(priv, &raw);
+ if (ret)
+ return ret;
+
+ *out = (raw & mask) >> priv->bit_offset;
+
+ return 0;
+}
+
+static int pscrr_nvmem_cell_write(struct pscrr_nvmem *priv, u8 val)
+{
+ u8 raw, mask = pscrr_nvmem_mask(priv);
+ int ret;
+
+ /* Sub-byte cell: preserve the neighbouring bits, read-modify-write. */
+ if (priv->nbits < BITS_PER_BYTE) {
+ ret = pscrr_nvmem_raw_read(priv, &raw);
+ if (ret)
+ return ret;
+ } else {
+ raw = 0;
+ }
+
+ raw = (raw & ~mask) | ((val << priv->bit_offset) & mask);
+
+ return pscrr_nvmem_raw_write(priv, raw);
+}
+
+static int pscrr_nvmem_read_reasons(struct pscrr_provider *p,
+ unsigned long *reasons)
+{
+ struct pscrr_nvmem *priv = p->priv;
+
+ /*
+ * Report the reason latched at probe (or overwritten by a later
+ * record); the cell itself was cleared at probe, so it is not read
+ * live here.
+ */
+ set_bit(READ_ONCE(priv->reason), reasons);
+
+ return 0;
+}
+
+static int pscrr_nvmem_write_reason(struct pscrr_provider *p,
+ enum psc_reason reason)
+{
+ struct pscrr_nvmem *priv = p->priv;
+ int ret;
+
+ if (reason >= PSCR_REASON_COUNT)
+ return -EINVAL;
+
+ ret = pscrr_nvmem_cell_write(priv, reason);
+ if (ret)
+ return ret;
+
+ WRITE_ONCE(priv->reason, reason);
+
+ return 0;
+}
+
+static const struct pscrr_provider_ops pscrr_nvmem_ops = {
+ .read_reasons = pscrr_nvmem_read_reasons,
+ .write_reason = pscrr_nvmem_write_reason,
+};
+
+static struct device_node *pscrr_nvmem_get_cell(struct device *dev,
+ struct nvmem_device *nvmem,
+ u32 reg[2])
+{
+ struct device_node *layout_np, *cell_np = NULL;
+
+ layout_np = of_nvmem_layout_get_container(nvmem);
+ if (!layout_np)
+ return ERR_PTR(-ENOENT);
+
+ for_each_child_of_node_scoped(layout_np, child) {
+ if (of_property_read_u32_array(child, "reg", reg, 2))
+ continue;
+
+ cell_np = of_node_get(child);
+ break;
+ }
+ of_node_put(layout_np);
+
+ return cell_np ?: ERR_PTR(dev_err_probe(dev, -ENOENT,
+ "missing pscr nvmem cell\n"));
+}
+
+static int pscrr_nvmem_add_cells(struct nvmem_layout *layout)
+{
+ struct device *dev = &layout->dev;
+ struct pscrr_nvmem *priv;
+ struct device_node *cell_np;
+ struct nvmem_cell_info info = { };
+ u32 reg[2], bits[2];
+ u8 val;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->nvmem = layout->nvmem;
+
+ cell_np = pscrr_nvmem_get_cell(dev, priv->nvmem, reg);
+ if (IS_ERR(cell_np))
+ return PTR_ERR(cell_np);
+
+ /* The reason is a single byte; a bit cell still occupies one. */
+ if (reg[1] != sizeof(val)) {
+ of_node_put(cell_np);
+ return dev_err_probe(dev, -EINVAL,
+ "unsupported pscr nvmem cell size\n");
+ }
+ priv->offset = reg[0];
+
+ if (!of_property_read_u32_array(cell_np, "bits", bits, ARRAY_SIZE(bits))) {
+ priv->bit_offset = bits[0];
+ priv->nbits = bits[1];
+ } else {
+ priv->bit_offset = 0;
+ priv->nbits = BITS_PER_BYTE;
+ }
+
+ if (priv->bit_offset + priv->nbits > BITS_PER_BYTE * reg[1]) {
+ of_node_put(cell_np);
+ return dev_err_probe(dev, -EINVAL, "bits exceed cell size\n");
+ }
+
+ /* PSCR_REASON_COUNT must fit in the allotted bits. */
+ if (PSCR_REASON_COUNT > (1U << priv->nbits)) {
+ of_node_put(cell_np);
+ return dev_err_probe(dev, -EINVAL,
+ "too few bits for the reason range\n");
+ }
+
+ /*
+ * The cell survives resets, so at boot it still holds whatever the
+ * previous session recorded before it went down. Latch that as this
+ * boot's reason, then clear the cell back to PSCR_UNKNOWN: if this
+ * session is later cut short by an abrupt reset that never runs the
+ * recorder (watchdog power-cycle, sudden power loss), the next boot
+ * reads "unknown" instead of a stale reason left over from an earlier
+ * cycle.
+ */
+ ret = pscrr_nvmem_cell_read(priv, &val);
+ if (ret) {
+ of_node_put(cell_np);
+ return dev_err_probe(dev, ret,
+ "failed to read the pscr nvmem cell\n");
+ }
+
+ priv->reason = val < PSCR_REASON_COUNT ? val : PSCR_UNKNOWN;
+
+ ret = pscrr_nvmem_cell_write(priv, PSCR_UNKNOWN);
+ if (ret) {
+ of_node_put(cell_np);
+ return dev_err_probe(dev, ret,
+ "failed to clear the pscr nvmem cell\n");
+ }
+
+ info.name = kasprintf(GFP_KERNEL, "%pOFn", cell_np);
+ if (!info.name) {
+ of_node_put(cell_np);
+ return -ENOMEM;
+ }
+ info.offset = reg[0];
+ info.bytes = reg[1];
+ info.bit_offset = priv->bit_offset;
+ info.nbits = priv->nbits;
+ info.np = cell_np;
+
+ ret = nvmem_add_one_cell(priv->nvmem, &info);
+ kfree(info.name);
+ if (ret) {
+ of_node_put(cell_np);
+ return ret;
+ }
+
+ return PTR_ERR_OR_ZERO(devm_pscrr_provider_register(dev, "nvmem",
+ &pscrr_nvmem_ops, NULL,
+ priv));
+}
+
+static int pscrr_nvmem_probe(struct nvmem_layout *layout)
+{
+ layout->add_cells = pscrr_nvmem_add_cells;
+
+ return nvmem_layout_register(layout);
+}
+
+static void pscrr_nvmem_remove(struct nvmem_layout *layout)
+{
+ nvmem_layout_unregister(layout);
+}
+
+static const struct of_device_id pscrr_nvmem_of_match[] = {
+ { .compatible = "pscrr-nvmem" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, pscrr_nvmem_of_match);
+
+static struct nvmem_layout_driver pscrr_nvmem_layout = {
+ .driver = {
+ .name = "pscrr-nvmem",
+ .of_match_table = pscrr_nvmem_of_match,
+ },
+ .probe = pscrr_nvmem_probe,
+ .remove = pscrr_nvmem_remove,
+};
+module_nvmem_layout_driver(pscrr_nvmem_layout);
+
+MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
+MODULE_AUTHOR("Faruque Ansari <faruque.ansari@oss.qualcomm.com>");
+MODULE_DESCRIPTION("NVMEM recorder provider for PSCRR");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 3/3] arm64: dts: qcom: lemans: Add PSCRR NVMEM recorder node
2026-09-14 4:38 [PATCH v3 0/3] power: reset: Add NVMEM recorder provider for PSCRR Faruque Ansari
2026-09-14 4:38 ` [PATCH v3 1/3] dt-bindings: nvmem: layouts: Add PSCRR NVMEM layout Faruque Ansari
2026-09-14 4:38 ` [PATCH v3 2/3] power: reset: Add PSCRR NVMEM recorder Faruque Ansari
@ 2026-09-14 4:38 ` Faruque Ansari
2 siblings, 0 replies; 5+ messages in thread
From: Faruque Ansari @ 2026-09-14 4:38 UTC (permalink / raw)
To: Oleksij Rempel, Pengutronix Kernel Team, Sebastian Reichel,
Rob Herring, Krzysztof Kozlowski, Wim Van Sebroeck,
Guenter Roeck, Benson Leung, Tzung-Bi Shih, Srinivas Kandagatla,
Daniel Lezcano
Cc: linux-arm-msm, linux-kernel, linux-pm, devicetree,
linux-watchdog, kernel, Liam Girdwood, Mark Brown,
Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Søren Andersen,
Guenter Roeck, Matti Vaittinen, Ahmad Fatoum, Andrew Morton,
avaneesh.dwivedi, Umang Chheda, Faruque Ansari
The PSCRR NVMEM recorder needs a persistent storage cell to save the
power state change reason before shutdown or reset. Without a described
NVMEM cell, the recorder has no platform storage where it can preserve
that reason for the next boot.
Add a pscrr-nvmem layout under the PMIC SDAM and describe a one-byte
cell at offset 0x49. The recorder uses the lower four bits of this cell
to persist the power state change reason across resets.
---
arch/arm64/boot/dts/qcom/lemans-pmics.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi b/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi
index 500f715931aa..180d180be3c6 100644
--- a/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi
+++ b/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi
@@ -186,6 +186,17 @@ reboot_reason: reboot-reason@48 {
reg = <0x48 0x1>;
bits = <1 7>;
};
+
+ nvmem-layout {
+ compatible = "pscrr-nvmem";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ reboot_reason_persist: reboot-reason-persist@49 {
+ reg = <0x49 0x1>;
+ bits = <0 4>;
+ };
+ };
};
};
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/3] dt-bindings: nvmem: layouts: Add PSCRR NVMEM layout
2026-09-14 4:38 ` [PATCH v3 1/3] dt-bindings: nvmem: layouts: Add PSCRR NVMEM layout Faruque Ansari
@ 2026-09-24 15:19 ` Rob Herring (Arm)
0 siblings, 0 replies; 5+ messages in thread
From: Rob Herring (Arm) @ 2026-09-24 15:19 UTC (permalink / raw)
To: Faruque Ansari
Cc: Andrew Morton, Benson Leung, Mark Brown, linux-arm-msm,
Oleksij Rempel, Søren Andersen, linux-pm, Sebastian Reichel,
Guenter Roeck, Guenter Roeck, Zhang Rui, Pengutronix Kernel Team,
Lukasz Luba, Daniel Lezcano, Rafael J. Wysocki, Matti Vaittinen,
Tzung-Bi Shih, Ahmad Fatoum, avaneesh.dwivedi, Umang Chheda,
linux-kernel, kernel, Srinivas Kandagatla, devicetree,
Liam Girdwood, Wim Van Sebroeck, Krzysztof Kozlowski,
linux-watchdog
On Mon, 14 Sep 2026 10:08:45 +0530, Faruque Ansari wrote:
> Add a schema for the PSCRR NVMEM layout, which persists the power
> state change reason in a single NVMEM cell so it survives a power
> cycle and can be read back on the next boot.
>
> Signed-off-by: Faruque Ansari <faruque.ansari@oss.qualcomm.com>
> ---
> .../bindings/nvmem/layouts/nvmem-layout.yaml | 1 +
> .../bindings/nvmem/layouts/pscrr-nvmem.yaml | 87 ++++++++++++++++++++++
> MAINTAINERS | 1 +
> 3 files changed, 89 insertions(+)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-24 15:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-14 4:38 [PATCH v3 0/3] power: reset: Add NVMEM recorder provider for PSCRR Faruque Ansari
2026-09-14 4:38 ` [PATCH v3 1/3] dt-bindings: nvmem: layouts: Add PSCRR NVMEM layout Faruque Ansari
2026-09-24 15:19 ` Rob Herring (Arm)
2026-09-14 4:38 ` [PATCH v3 2/3] power: reset: Add PSCRR NVMEM recorder Faruque Ansari
2026-09-14 4:38 ` [PATCH v3 3/3] arm64: dts: qcom: lemans: Add PSCRR NVMEM recorder node Faruque Ansari
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®