* [PATCH v6 0/3] Fix poweroff restarting the board on Firefly-RK3399
@ 2026-11-01 15:40 Yaozhong Li
2026-11-01 15:40 ` [PATCH v6 1/3] dt-bindings: mfd: rk8xx: add board level power hold GPIOs Yaozhong Li
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Yaozhong Li @ 2026-11-01 15:40 UTC (permalink / raw)
To: Lee Jones
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Chris Zhong, Zhang Qing, Joseph Chen, Sebastian Reichel,
Yaozhong Li, mfd, devicetree, linux-rockchip, linux-arm-kernel,
linux-kernel
On the Firefly-RK3399, "poweroff" drops the rails and immediately brings
them back up, so the board reboots instead of staying off. This series
describes the SoC line that has to be released before the RK808 shutdown
write, and lets the rk8xx driver release it.
v5: https://lore.kernel.org/all/20261027084511.1992-1-yaozhonguwl@gmail.com/
v4: https://lore.kernel.org/all/20261020140127.720-1-yaozhonguwl@gmail.com/
v3: https://lore.kernel.org/all/20260929140649.55-1-yaozhonguwl@gmail.com/
v2: https://lore.kernel.org/all/20260919122930.1418-1-yaozhonguwl@gmail.com/
v1: https://lore.kernel.org/all/20260909092728.1859-1-yaozhonguwl@gmail.com/
Changes since v5
----------------
* 1/3 no longer repeats the two properties in all seven RK8xx schemas
(Lee). They are defined once, in a new rockchip,rk8xx-power-hold.yaml
that also carries the dependentRequired rules, and each RK8xx schema
references it. rk801, rk805, rk808, rk816 and rk818 switch to
unevaluatedProperties: false so that the shared properties are
allowed; rk806 already used it. rk817 keeps additionalProperties:
false and lists the two properties, because it also references
dai-common and only allows a subset of that. The property text and
the rules are the same as in v5.
2/3 and 3/3 are unchanged.
Sashiko repeated its v4 question on v5 1/3, whether the lines should be
board-level nodes rather than PMIC properties; see open question 1.
Changes since v4
----------------
* 1/3, following Rob's review: the description is a folded block with
the two paragraphs separated by a blank line, the dependencies use
dependentRequired, and power-hold-gpios now requires the generic
system-power-controller property in all seven schemas. A board that
adds the lines is expected to switch from the deprecated
rockchip,system-power-controller at the same time; the Firefly-RK3399
already uses the generic spelling, so 3/3 is unchanged.
The driver still honours either spelling, as before this series.
Changes since v3
----------------
* No longer an RFC (Lee). v3 was one because the patched kernel had never
been booted; the driver had only been exercised through an out-of-tree
module doing the same calls. It now has: the board's own kernel was
rebuilt with 2/3 applied, with one unrelated RK3588-only patch left out
as described below, and the power-off was tested with it, including the
GPIO claim at probe that the module could not cover. See Testing.
* 1/3 adds the properties to all seven RK8xx schemas, not just rk808
(Sashiko). rk8xx_probe() reads them for every variant that is the system
power controller. Each schema gets the dependency on whichever spellings
of system-power-controller it allows: rk805, rk808, rk817 and rk818 also
accept the deprecated rockchip,system-power-controller, rk801, rk806 and
rk816 do not. The subject prefix is now "rk8xx". (v5 accepts only the
generic spelling, see above.)
* 1/3 also documents that the lines are released in the order listed,
with one settle delay after the last of them.
* 3/3: the commit message now also says what happens when pwm-backlight
is not bound (Sashiko): nothing claims GPIO1_B5 then, and on this board
it reads low, which was tested, but that is not guaranteed in general.
The Sashiko replies are in the v3 thread. 2/3 is unchanged.
The problem
-----------
U-Boot reports the restart as a power-on reset.
Firefly's BSP drives two SoC pins low during shutdown, before writing the
RK808's shutdown bit: GPIO1_D0 and GPIO1_B5. Mainline does not describe
GPIO1_D0 at all, so nothing ever drives it.
What was established on the board is the sequence, not what happens inside
the PMIC. In the cases tested, the shutdown stuck when GPIO1_D0 went from
high to low during power-off prepare, with GPIO1_B5 low, and the shutdown
bit was written after a settle delay. It did not stick when GPIO1_D0 was
never driven, or when GPIO1_B5 was held high. With the backlight bound,
pwm-backlight's shutdown callback drives GPIO1_B5 low in device_shutdown(),
before the PMIC's handler runs, so only GPIO1_D0 needs to be described.
Prior art
---------
The vendor behaviour comes from Firefly's own change to the rk808 driver
in their BSP; it is not in Rockchip's develop-4.4 or develop-4.19 trees.
It reads two single GPIOs from the PMIC node, pmic,hold-gpio and
pmic,stby-gpio, drives both high at probe, and at power-off drives stby
low, then hold low, waits 200 ms and writes the shutdown bit. On this
board stby is GPIO1_D0 and hold is GPIO1_B5.
Its board files use one or both: both on the Firefly-RK3399 and the
RK818-based Firefly-RK3128 FirePrime, hold only on the ROC-RK3399-PC
family, stby only on a few others. That is where minItems 1 and maxItems 2
come from. None of those boards other than this one uses the new property
in mainline.
On the ROC-RK3399-PC, the vendor describes GPIO2_A6 as pmic,hold-gpio,
while mainline's rk3399-roc-pc.dtsi describes the same pin as the enable
GPIO of the vcc_sys fixed regulator. I have not checked whether that board
powers off correctly on mainline.
The vendor device tree marks stby as GPIO_ACTIVE_LOW, but the vendor driver
uses the legacy integer GPIO API, which ignores the flag, and drives the
line high at runtime. That matches the physical level measured here, so
this series describes the line as active high.
Why not gpio-poweroff
---------------------
gpio-poweroff drives the line active, back to inactive, then active again,
waits timeout-ms and then WARN()s on the assumption that it is itself
performing the power off, and it registers at SYS_OFF_MODE_POWER_OFF. Here
the RK808 performs the power off from its own POWER_OFF_PREPARE handler,
and the line only has to be released and left released before that.
Open questions
--------------
These are still open; I would change the series if a reviewer prefers
otherwise.
1. Should such a line be modelled in the PMIC driver at all, rather than
as a separate driver at POWER_OFF_PREPARE, or as a regulator enable as
mainline does for the ROC-RK3399-PC? On this board the line was tested
going low from power-off prepare, 200 ms before the PMIC write; I do not
know whether a regulator description would achieve that.
2. Would two named properties for the vendor's two roles, hold and
standby, be preferred over an array whose order sets the release order?
3. The vendor calls GPIO1_B5 pmic-hold and its backlight node has no enable
GPIO, so mainline's backlight enable-gpios on that pin may be wrong.
Without a schematic I have left it alone; the series does not depend on
the answer on this board.
Testing
-------
Hardware: Firefly-RK3399 (4 GB, RK808).
The hardware runs below were done with v4. v5 and v6 only change the
binding schemas, so the driver and the device tree tested are the same.
Kernel: the board's Armbian 6.18.45 kernel, rebuilt from the same tag
and configuration and Armbian's current patch set, with 2/3 applied on
top. One Armbian patch that adds an RK3588-only IOMMU driver had to be
left out because its current version no longer builds on 6.18.45;
nothing on the RK3399 uses it. The resulting kernel package, modules
included, was installed in place of the original one. No out-of-tree
module was loaded during these runs, and the board's local power-off
workaround was disabled.
Device tree: the board's own device tree with the properties of 3/3 added,
power-hold-gpios for GPIO1_D0 and a 200 ms delay, and the backlight's
enable-gpios unchanged. pwm-backlight was bound and set to full
brightness, so it drove GPIO1_B5 high while the system ran.
Before each run a script checked, from /sys/kernel/debug/gpio, that
GPIO1_B5 was owned by the backlight and driven high, and that GPIO1_D0 was
claimed by the rk808 driver with the consumer name "power-hold" and driven
high when the property was present, and unclaimed when it was not:
same kernel, power-hold-gpios absent: restarted after 41 s
same kernel, GPIO1_D0 described: 3 of 3 stayed off
"Stayed off" means the board did not come back on the network within
5 minutes and its fan and LEDs were seen off; this caught the control
run's restart. The serial console was not available. In addition, on
each following power-up the RK808 RTC had been reset (this board has no
RTC backup cell), which corroborates that the PMIC had lost power.
Build and schema, against a clean mainline tree (28924df2a):
drivers/mfd/rk8xx-core.o builds with W=1 and no warnings, and
dt_binding_check is clean for all seven schemas and the shared one.
dtbs_check for rk3399-firefly reports no PMIC diagnostics. For each
schema, a device tree with power-hold-gpios but no
system-power-controller is rejected: using an in-tree board for rk805,
rk806, rk808, rk817 and rk818, and the schema's own example for rk801
and rk816, which have no in-tree users. For rk805, rk808, rk817 and
rk818, which still accept the deprecated spelling, power-hold-gpios
together with rockchip,system-power-controller is rejected too, and the
same board with system-power-controller passes. checkpatch reports two
warnings: on 1/3, whether MAINTAINERS needs updating for the new file,
which the MFD entry already covers through
Documentation/devicetree/bindings/mfd/; and on 3/3, an unknown commit
id in the Fixes: tag, caused by the shallow clone; the commit exists
upstream.
The 200 ms is the value the vendor uses; the threshold was not
characterised.
This series was prepared with the help of LLM-based assistants (Claude
Code, cross-reviewed with OpenAI Codex): the analysis, the code and the
text were drafted with them. The measurements were taken on my board, and
I have reviewed the result.
Yaozhong Li (3):
dt-bindings: mfd: rk8xx: add board level power hold GPIOs
mfd: rk8xx: Release the power hold GPIOs before powering off
arm64: dts: rockchip: fix power-off on Firefly-RK3399
.../bindings/mfd/rockchip,rk801.yaml | 5 +-
.../bindings/mfd/rockchip,rk805.yaml | 3 +-
.../bindings/mfd/rockchip,rk806.yaml | 1 +
.../bindings/mfd/rockchip,rk808.yaml | 5 +-
.../bindings/mfd/rockchip,rk816.yaml | 5 +-
.../bindings/mfd/rockchip,rk817.yaml | 4 ++
.../bindings/mfd/rockchip,rk818.yaml | 5 +-
.../mfd/rockchip,rk8xx-power-hold.yaml | 42 ++++++++++++++++
.../boot/dts/rockchip/rk3399-firefly.dts | 2 +
drivers/mfd/rk8xx-core.c | 49 ++++++++++++++++++-
include/linux/mfd/rk808.h | 3 ++
11 files changed, 117 insertions(+), 7 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/rockchip,rk8xx-power-hold.yaml
base-commit: 940de590b839f71d6dc846160534bf202401b8b7
--
2.55.0.windows.3
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v6 1/3] dt-bindings: mfd: rk8xx: add board level power hold GPIOs
2026-11-01 15:40 [PATCH v6 0/3] Fix poweroff restarting the board on Firefly-RK3399 Yaozhong Li
@ 2026-11-01 15:40 ` Yaozhong Li
2026-11-01 15:47 ` sashiko-bot
2026-11-01 15:40 ` [PATCH v6 2/3] mfd: rk8xx: Release the power hold GPIOs before powering off Yaozhong Li
2026-11-01 15:40 ` [PATCH v6 3/3] arm64: dts: rockchip: fix power-off on Firefly-RK3399 Yaozhong Li
2 siblings, 1 reply; 5+ messages in thread
From: Yaozhong Li @ 2026-11-01 15:40 UTC (permalink / raw)
To: Lee Jones
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Chris Zhong, Zhang Qing, Joseph Chen, Sebastian Reichel,
Yaozhong Li, mfd, devicetree, linux-rockchip, linux-arm-kernel,
linux-kernel
Some boards route "power hold" lines from the SoC into the board's power
circuitry. Those lines have to be held asserted while the system is
running and released before the PMIC shutdown request is written,
otherwise the rails can drop and come back up instead of staying off.
Add power-hold-gpios to describe those lines and power-hold-delay-ms for
the settle time. The driver reads them for every RK8xx variant that is
the system power controller, so define them once, in a schema shared by
the seven RK8xx bindings, and reference it from each. The bindings
switch to unevaluatedProperties: false so that the shared properties are
allowed, except rk817, which keeps additionalProperties: false and lists
the two properties: it also references dai-common, of which it only
allows a subset.
The array is bounded at two entries. Firefly's vendor kernel handles
exactly two such lines, pmic,hold-gpio and pmic,stby-gpio, and its board
files use one or both of them, with an RK808 and with an RK818.
The lines are released from the PMIC's power-off path, so they are only
meaningful when the PMIC is the system power controller. Require that.
A board adding these lines is expected to switch to the generic
system-power-controller property at the same time, so the deprecated
rockchip,system-power-controller spelling is not accepted here.
Assisted-by: LLM
Signed-off-by: Yaozhong Li <yaozhonguwl@gmail.com>
---
.../bindings/mfd/rockchip,rk801.yaml | 5 ++-
.../bindings/mfd/rockchip,rk805.yaml | 3 +-
.../bindings/mfd/rockchip,rk806.yaml | 1 +
.../bindings/mfd/rockchip,rk808.yaml | 5 ++-
.../bindings/mfd/rockchip,rk816.yaml | 5 ++-
.../bindings/mfd/rockchip,rk817.yaml | 4 ++
.../bindings/mfd/rockchip,rk818.yaml | 5 ++-
.../mfd/rockchip,rk8xx-power-hold.yaml | 42 +++++++++++++++++++
8 files changed, 65 insertions(+), 5 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/rockchip,rk8xx-power-hold.yaml
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk801.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk801.yaml
index 7c71447..38108fe 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk801.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk801.yaml
@@ -76,7 +76,10 @@ required:
- reg
- interrupts
-additionalProperties: false
+allOf:
+ - $ref: rockchip,rk8xx-power-hold.yaml#
+
+unevaluatedProperties: false
examples:
- |
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml
index da23915..ddf2b2f 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml
@@ -87,6 +87,7 @@ properties:
unevaluatedProperties: false
allOf:
+ - $ref: rockchip,rk8xx-power-hold.yaml#
- if:
properties:
'#clock-cells':
@@ -108,7 +109,7 @@ required:
- interrupts
- "#clock-cells"
-additionalProperties: false
+unevaluatedProperties: false
examples:
- |
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
index eb5bca3..5ca76dd 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
@@ -136,6 +136,7 @@ patternProperties:
enum: [gpio_pwrctrl1, gpio_pwrctrl2, gpio_pwrctrl3]
allOf:
+ - $ref: rockchip,rk8xx-power-hold.yaml#
- $ref: /schemas/spi/spi-peripheral-props.yaml
required:
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml
index 50dfffa..d51f815 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml
@@ -119,7 +119,10 @@ required:
- interrupts
- "#clock-cells"
-additionalProperties: false
+allOf:
+ - $ref: rockchip,rk8xx-power-hold.yaml#
+
+unevaluatedProperties: false
examples:
- |
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk816.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk816.yaml
index a58d945..c0c8dec 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk816.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk816.yaml
@@ -107,7 +107,10 @@ required:
- interrupts
- '#clock-cells'
-additionalProperties: false
+allOf:
+ - $ref: rockchip,rk8xx-power-hold.yaml#
+
+unevaluatedProperties: false
examples:
- |
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk817.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk817.yaml
index 2cb6d17..6207c42 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk817.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk817.yaml
@@ -55,6 +55,9 @@ properties:
system-power-controller: true
+ power-hold-gpios: true
+ power-hold-delay-ms: true
+
wakeup-source:
type: boolean
description:
@@ -157,6 +160,7 @@ properties:
additionalProperties: false
allOf:
+ - $ref: rockchip,rk8xx-power-hold.yaml#
- $ref: /schemas/sound/dai-common.yaml#
- if:
properties:
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk818.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk818.yaml
index 90d944c..c9b863a 100644
--- a/Documentation/devicetree/bindings/mfd/rockchip,rk818.yaml
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk818.yaml
@@ -111,7 +111,10 @@ required:
- interrupts
- "#clock-cells"
-additionalProperties: false
+allOf:
+ - $ref: rockchip,rk8xx-power-hold.yaml#
+
+unevaluatedProperties: false
examples:
- |
diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk8xx-power-hold.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk8xx-power-hold.yaml
new file mode 100644
index 0000000..6be3e1e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk8xx-power-hold.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/rockchip,rk8xx-power-hold.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK8xx PMIC board level power hold GPIOs
+
+maintainers:
+ - Yaozhong Li <yaozhonguwl@gmail.com>
+
+description:
+ Properties shared by the RK8xx PMIC bindings for boards that route power
+ hold lines from the SoC into the board's power circuitry, which have to
+ be released before the PMIC is asked to power the system off.
+
+properties:
+ power-hold-gpios:
+ minItems: 1
+ maxItems: 2
+ description: >
+ Board level power hold lines driven by the SoC. They have to be held
+ asserted while the system is running and released before the PMIC
+ shutdown request is written, otherwise the rails can drop and come
+ back up instead of staying off. Only meaningful when this PMIC is the
+ system power controller, as the lines are released as part of its
+ power-off path.
+
+ The lines are released in the order listed, and power-hold-delay-ms
+ elapses once, after the last of them.
+
+ power-hold-delay-ms:
+ default: 0
+ description:
+ Time to wait after releasing power-hold-gpios before the shutdown
+ request is written, to let the lines settle.
+
+dependentRequired:
+ power-hold-gpios: [ system-power-controller ]
+ power-hold-delay-ms: [ power-hold-gpios ]
+
+additionalProperties: true
--
2.55.0.windows.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v6 1/3] dt-bindings: mfd: rk8xx: add board level power hold GPIOs
2026-11-01 15:40 ` [PATCH v6 1/3] dt-bindings: mfd: rk8xx: add board level power hold GPIOs Yaozhong Li
@ 2026-11-01 15:47 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-11-01 15:47 UTC (permalink / raw)
To: Yaozhong Li; +Cc: mfd, devicetree, robh, conor+dt, lee
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] dt-bindings: mfd: rk8xx: board power-hold GPIOs modeled as PMIC properties
--
commit 675c9ae7bda27dce85ec9548a8ac2ba6bdf5bf40
Author: Yaozhong Li <yaozhonguwl@gmail.com>
dt-bindings: mfd: rk8xx: add board level power hold GPIOs
This commit adds a shared schema rockchip,rk8xx-power-hold.yaml defining
power-hold-gpios and power-hold-delay-ms properties for board-level power
hold lines, and references it across all seven Rockchip RK8xx PMIC MFD
bindings.
> diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk8xx-power-hold.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk8xx-power-hold.yaml
> new file mode 100644
> index 0000000000000..6be3e1e119f0b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/rockchip,rk8xx-power-hold.yaml
> @@ -0,0 +1,42 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/rockchip,rk8xx-power-hold.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip RK8xx PMIC board level power hold GPIOs
> +
> +maintainers:
> + - Yaozhong Li <yaozhonguwl@gmail.com>
> +
> +description:
> + Properties shared by the RK8xx PMIC bindings for boards that route power
> + hold lines from the SoC into the board's power circuitry, which have to
> + be released before the PMIC is asked to power the system off.
> +
> +properties:
> + power-hold-gpios:
> + minItems: 1
> + maxItems: 2
> + description: >
> + Board level power hold lines driven by the SoC. They have to be held
> + asserted while the system is running and released before the PMIC
> + shutdown request is written, otherwise the rails can drop and come
> + back up instead of staying off. Only meaningful when this PMIC is the
> + system power controller, as the lines are released as part of its
> + power-off path.
> +
> + The lines are released in the order listed, and power-hold-delay-ms
> + elapses once, after the last of them.
> +
> + power-hold-delay-ms:
> + default: 0
> + description:
> + Time to wait after releasing power-hold-gpios before the shutdown
> + request is written, to let the lines settle.
[Severity: Medium]
As reported by Sashiko on v5 [1], should board-level SoC power circuitry
GPIOs and OS shutdown sequencing delays be modeled as properties on the
RK8xx PMIC nodes across rockchip,rk801.yaml, rockchip,rk805.yaml,
rockchip,rk806.yaml, rockchip,rk808.yaml, rockchip,rk816.yaml,
rockchip,rk817.yaml, and rockchip,rk818.yaml?
None of the Rockchip RK8xx PMIC variants have SoC-driven power-hold input
pins; as noted in the description, these lines are routed from the SoC into
board circuitry outside the PMIC.
Adding power-hold-gpios (bounded at maxItems: 2 after Firefly's vendor
kernel pmic,hold-gpio and pmic,stby-gpio properties, which on boards like
rk3399-firefly.dts and rk3399-roc-pc.dtsi correspond to the pwm-backlight
enable GPIO or the vcc_sys fixed regulator enable GPIO) and
power-hold-delay-ms to all seven PMIC bindings encodes driver-specific OS
shutdown sequencing on the PMIC node rather than describing the board's
actual power switches or regulators in Devicetree.
[1] https://lore.kernel.org/r/20261027084511.1992-2-yaozhonguwl@gmail.com
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261101154053.3874-1-yaozhonguwl@gmail.com?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v6 2/3] mfd: rk8xx: Release the power hold GPIOs before powering off
2026-11-01 15:40 [PATCH v6 0/3] Fix poweroff restarting the board on Firefly-RK3399 Yaozhong Li
2026-11-01 15:40 ` [PATCH v6 1/3] dt-bindings: mfd: rk8xx: add board level power hold GPIOs Yaozhong Li
@ 2026-11-01 15:40 ` Yaozhong Li
2026-11-01 15:40 ` [PATCH v6 3/3] arm64: dts: rockchip: fix power-off on Firefly-RK3399 Yaozhong Li
2 siblings, 0 replies; 5+ messages in thread
From: Yaozhong Li @ 2026-11-01 15:40 UTC (permalink / raw)
To: Lee Jones
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Chris Zhong, Zhang Qing, Joseph Chen, Sebastian Reichel,
Yaozhong Li, mfd, devicetree, linux-rockchip, linux-arm-kernel,
linux-kernel
rk808_power_off() writes the PMIC's shutdown bit directly. On boards where
lines driven by the SoC gate the PMIC's power-off path, a shutdown
performed this way does not stick: the rails drop and immediately come
back up, so the board restarts instead of staying off. U-Boot reports the
result as a power-on reset.
Take those lines as an optional GPIO array, hold them asserted while the
system runs and release them - waiting power-hold-delay-ms - before
writing the shutdown bit. Device trees without the property retain the
existing behaviour.
The array is claimed before any child device is registered, so that a
-EPROBE_DEFER from the GPIO provider does not tear down the regulators,
RTC and clocks that devm_mfd_add_devices() has already registered.
On a Firefly-RK3399 the shutdown stuck when such a line went from high to
low before the shutdown bit was written, and did not when the line was
never driven.
Assisted-by: LLM
Signed-off-by: Yaozhong Li <yaozhonguwl@gmail.com>
---
drivers/mfd/rk8xx-core.c | 49 +++++++++++++++++++++++++++++++++++++--
include/linux/mfd/rk808.h | 3 +++
2 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
index 3dcf6ab..137ab20 100644
--- a/drivers/mfd/rk8xx-core.c
+++ b/drivers/mfd/rk8xx-core.c
@@ -11,6 +11,8 @@
*/
#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/mfd/rk808.h>
#include <linux/mfd/core.h>
@@ -703,6 +705,22 @@ static int rk808_power_off(struct sys_off_data *data)
default:
return NOTIFY_DONE;
}
+
+ /*
+ * Some boards route "power hold" lines from the SoC into the board's
+ * power circuitry. They have to be held asserted while the system is
+ * running and released before the PMIC shutdown request is written,
+ * otherwise the rails can drop and come back up instead of staying
+ * off. Releasing them here rather than from a separate handler keeps
+ * the ordering against the I2C write explicit.
+ */
+ if (rk808->power_hold_gpios) {
+ for (unsigned int line = 0; line < rk808->power_hold_gpios->ndescs; line++)
+ gpiod_set_value_cansleep(rk808->power_hold_gpios->desc[line], 0);
+
+ msleep(rk808->power_hold_delay_ms);
+ }
+
ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
if (ret)
dev_err(rk808->dev, "Failed to shutdown device!\n");
@@ -766,6 +784,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
struct rk808 *rk808;
const struct rk808_reg_data *pre_init_reg;
const struct mfd_cell *cells;
+ bool system_power_controller;
int dual_support = 0;
int nr_pre_init_regs;
u32 rst_fun = 0;
@@ -851,6 +870,33 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
if (!irq)
return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
+ system_power_controller =
+ device_property_read_bool(dev, "system-power-controller") ||
+ device_property_read_bool(dev, "rockchip,system-power-controller");
+
+ /*
+ * Claim the optional power hold GPIOs before any child device is
+ * registered. A -EPROBE_DEFER from the GPIO provider at this point
+ * costs nothing, whereas deferring after devm_mfd_add_devices()
+ * would tear the freshly registered children down again on every
+ * retry.
+ */
+ if (system_power_controller) {
+ rk808->power_hold_gpios = devm_gpiod_get_array_optional(dev, "power-hold",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(rk808->power_hold_gpios))
+ return dev_err_probe(dev, PTR_ERR(rk808->power_hold_gpios),
+ "Failed to get power hold GPIOs\n");
+
+ /*
+ * The settle time is optional. rk808 is zero initialised and
+ * the binding documents 0 as the default, so an absent property
+ * means the shutdown request follows the release with no wait.
+ */
+ device_property_read_u32(dev, "power-hold-delay-ms",
+ &rk808->power_hold_delay_ms);
+ }
+
ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
IRQF_ONESHOT | dual_support, -1,
rk808->regmap_irq_chip, &rk808->irq_data);
@@ -872,8 +918,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
if (ret)
return dev_err_probe(dev, ret, "failed to add MFD devices\n");
- if (device_property_read_bool(dev, "system-power-controller") ||
- device_property_read_bool(dev, "rockchip,system-power-controller")) {
+ if (system_power_controller) {
ret = devm_register_sys_off_handler(dev,
SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
&rk808_power_off, rk808);
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index 7ffc904..e56d595 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -15,6 +15,7 @@
#ifndef __LINUX_REGULATOR_RK808_H
#define __LINUX_REGULATOR_RK808_H
+#include <linux/gpio/consumer.h>
#include <linux/regulator/machine.h>
#include <linux/regmap.h>
@@ -1466,6 +1467,8 @@ struct rk808 {
long variant;
const struct regmap_config *regmap_cfg;
const struct regmap_irq_chip *regmap_irq_chip;
+ struct gpio_descs *power_hold_gpios;
+ u32 power_hold_delay_ms;
};
void rk8xx_shutdown(struct device *dev);
--
2.55.0.windows.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v6 3/3] arm64: dts: rockchip: fix power-off on Firefly-RK3399
2026-11-01 15:40 [PATCH v6 0/3] Fix poweroff restarting the board on Firefly-RK3399 Yaozhong Li
2026-11-01 15:40 ` [PATCH v6 1/3] dt-bindings: mfd: rk8xx: add board level power hold GPIOs Yaozhong Li
2026-11-01 15:40 ` [PATCH v6 2/3] mfd: rk8xx: Release the power hold GPIOs before powering off Yaozhong Li
@ 2026-11-01 15:40 ` Yaozhong Li
2 siblings, 0 replies; 5+ messages in thread
From: Yaozhong Li @ 2026-11-01 15:40 UTC (permalink / raw)
To: Lee Jones
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Chris Zhong, Zhang Qing, Joseph Chen, Sebastian Reichel,
Yaozhong Li, mfd, devicetree, linux-rockchip, linux-arm-kernel,
linux-kernel
poweroff on this board drops the rails and immediately brings them back
up, so it reboots instead of staying off and U-Boot reports a power-on
reset.
Firefly's BSP drives GPIO1_D0 high while the system runs and low during
shutdown, before writing the RK808's shutdown bit. Mainline does not
describe GPIO1_D0 at all, so nothing drives it and the shutdown does not
stick. Describe it in the PMIC node, with the settle time the vendor
uses.
The BSP releases GPIO1_B5 in the same sequence, and in testing the board
came back up when that pin was still high as the shutdown bit was
written. Mainline describes GPIO1_B5 as the backlight enable GPIO.
pwm-backlight drives its enable GPIO low whenever it turns the backlight
off, including from its shutdown callback in device_shutdown(), which
runs before the PMIC's power-off prepare handler. When pwm-backlight is
not bound, nothing claims the pin; on this board it is then an input
reading low, which also lets the shutdown stick, although that is not
guaranteed on every board. The pin is therefore left to the backlight.
Fixes: 171582e00db1 ("arm64: dts: rockchip: add support for firefly-rk3399 board")
Assisted-by: LLM
Signed-off-by: Yaozhong Li <yaozhonguwl@gmail.com>
---
arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
index 0568dfa..210e4cb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
@@ -327,6 +327,8 @@ rk808: pmic@1b {
pinctrl-names = "default";
pinctrl-0 = <&pmic_int_l>;
system-power-controller;
+ power-hold-gpios = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>;
+ power-hold-delay-ms = <200>;
wakeup-source;
vcc1-supply = <&vcc_sys>;
--
2.55.0.windows.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-01 15:47 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-01 15:40 [PATCH v6 0/3] Fix poweroff restarting the board on Firefly-RK3399 Yaozhong Li
2026-11-01 15:40 ` [PATCH v6 1/3] dt-bindings: mfd: rk8xx: add board level power hold GPIOs Yaozhong Li
2026-11-01 15:47 ` sashiko-bot
2026-11-01 15:40 ` [PATCH v6 2/3] mfd: rk8xx: Release the power hold GPIOs before powering off Yaozhong Li
2026-11-01 15:40 ` [PATCH v6 3/3] arm64: dts: rockchip: fix power-off on Firefly-RK3399 Yaozhong Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox