Repository navigation
drivers: realtek: support PM device on all Bee SoCs - #316
Closed
YuzhuoLiuRTK wants to merge 18 commits into
Closed
YuzhuoLiuRTK wants to merge 18 commits into
YuzhuoLiuRTK wants to merge 18 commits into
Conversation
YuzhuoLiuRTK
force-pushed
the
downstream/v4.4/drivers/add-pm-device
branch
from
October 9, 2026 01:53
87d075e to
b4c8edf
Compare
YuzhuoLiuRTK
marked this pull request as ready for review
October 9, 2026 01:54
YuzhuoLiuRTK
force-pushed
the
downstream/v4.4/drivers/add-pm-device
branch
2 times, most recently
from
October 14, 2026 02:41
2015176 to
7ae6462
Compare
Where the HAL drives the Arm PCK-600 power control kit, a peripheral keeps its own power and clock domain across a low power state and switches its pads in hardware. Where it does not, the platform power manager takes the whole SoC down and a driver has to save, restore and switch pads itself. Add REALTEK_BEE_HAS_PCK600 so that a driver can key on that capability instead of on the SoC series. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
The sleep hardware state and the wakeup polarity of a pin were only described for RTL87X2J, the only series whose drivers configured a pad for a low power state. Every series needs them now. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Without the PCK-600 power control a timer loses its registers in a low power state, so the shared timer layer gains a store and a restore operation per instance and a pair for the registers the instances share. The shared registers are only stored once per suspend. The HAL does not declare its DLPS entry points in a header, so declare them there. The counter and the PWM driver then suspend by saving the registers and resume by putting them back, the PWM along with its clock and pinctrl state. A suspended PWM still has to hold its output, so drive the pad by hand at the level the last duty cycle left it at when no sleep pinctrl state describes one. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
GPIO_GET_TRIGGER_MODE() and GPIO_GET_TRIGGER_POLARITY() cast the port after selecting the register instead of before, so on RTL8752H they dereference the port as the register and read a register that is not theirs. A both edge interrupt is emulated with a level interrupt whose polarity is flipped from the handler. The level stays asserted while the handler runs and the debounce filter keeps the old verdict, so the flip can raise the very interrupt it just handled. Take the interrupt away around the flip and clear what the flip raised. An edge that arrives before the debounce filter validated the level the interrupt was armed on leaves the pin on the other level, and nothing has been detected in that case, so drop the pin from the callback set and leave the polarity alone. The hardware both edge trigger mode is never selected either way, so BEE_GPIO_TRIGGER_BOTH_EDGE goes. Every interrupt enabled on a pin also armed the pad as a system wakeup source, which woke the SoC on pins the application never marked as a wakeup and made a plain input interrupt cost standby current. Honour GPIO_INT_TRIG_WAKE instead: remember the flag per pin, strip it before decoding the trigger, and arm the pad only for the pins that carry it. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Without the PCK-600 power control the GPIO port loses its registers in a low power state, so add a PM device that saves and restores them. While the port is down each connected pin holds its own state: an output keeps its level from the pad, an input with an interrupt enabled arms the pad as the system wakeup source at the polarity it triggers on, and the pad goes to software mode. On resume an edge that arrived while the port was gone is replayed from the level the pin was left at, because it left no pending bit behind. A debounced pin is left out, its debounce logic raises the interrupt once the pin settles. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Pick the low power flow from REALTEK_BEE_HAS_PCK600 instead of the SoC series. With the PCK-600 power control the controller keeps its context and only drops its always on power request, which the driver already did. Without it the registers are gone over a low power state, so add a PM device that gates the clock and the pads on suspend and restores the registers on resume. The HAL save buffer is filled at init and the few registers written at runtime are mirrored into it, which avoids reading the whole controller back on every suspend. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Pick the low power flow from REALTEK_BEE_HAS_PCK600 instead of the SoC series, and drop the lookup that guarded the sleep state, applying it already reports -ENOENT when it is missing. Without the PCK-600 power control the registers are gone over a low power state, so add a PM device that gates the clock and the pads on suspend and restores the registers on resume. The HAL save buffer is filled when the bus is configured and the interrupt mask and the enable register are mirrored into it as they are written. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Pick the low power flow from REALTEK_BEE_HAS_PCK600 instead of the SoC series: the sleep pinctrl state that drops the power request is applied at init where the PCK-600 power control is there. Without it the registers are gone over a low power state, so add a PM device that gates the clock and the pads on suspend and restores the registers on resume. The HAL save buffer is filled whenever the controller is set up, and resume configures the pin for the direction last selected. Drop the two comments on which HAL header a SoC series resolves <rtl_ir.h> to while touching them, the aliases right below already show it. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Pick the low power flow from REALTEK_BEE_HAS_PCK600 instead of the SoC series, and drop the lookup that guarded the sleep state, applying it already reports -ENOENT when it is missing. Without the PCK-600 power control the registers are gone over a low power state, so add a PM device that gates the clock and the pads on suspend. The controller has no HAL save buffer, so resume replays the configuration the bus was last configured with. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Without the PCK-600 power control the registers of the non always on decoder are gone over a low power state, so add a PM device that gates the clock and the pads on suspend and restores the registers on resume. The HAL save buffer is filled at init and the interrupt mask is mirrored into it whenever a trigger is set. The counter restarts from zero, so suspend folds the count it reached into a per axis accumulator that a sample adds back, which keeps the reported rotation continuous. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Pick the low power flow from REALTEK_BEE_HAS_PCK600 instead of the SoC series, and drop the lookup that guarded the sleep state, applying it already reports -ENOENT when it is missing. Without the PCK-600 power control the registers are gone over a low power state, so add a PM device that gates the clock and the pads on suspend. The controller has no HAL save buffer, so resume replays the retained init_struct and re-enables the interrupts, and a work item waits for the bus to come back on before restoring the receive message buffers, because that wait cannot run in the resume path. can_bee_start() re-initializes the controller on every SoC now rather than only where deep sleep power gates it. A stopped controller is left behind by can_bee_stop() everywhere, and re-initializing from the retained init_struct is what makes a restart pick the configuration back up instead of report a bus off. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Without the PCK-600 power control the registers are gone over a low power state, so add a PM device that gates the clock and the pads on suspend. The controller has no HAL save buffer, so resume replays the stored i2s_config of every stream that reached I2S_STATE_READY. A running stream cannot survive the platform taking the SoC down, and a device runtime reference does not hold off DLPS on its own, so register a platform PM check callback that fails while any instance has a stream running. Streams are refcounted because transmit and receive can run at the same time. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
The driver reached for the RCC HAL directly, which spells the codec clock differently on every SoC series and bypasses the clock controller the rest of the Bee drivers go through. Take the clock from the devicetree and enable it with the clock control API. The clocks property becomes required, so describe it on the codec node of the three boards the i2s_bee sample supports. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Without the PCK-600 power control the codec is gone over a low power state, so add a PM device that gates the clock and applies the sleep pads on suspend and, when output was running, sets the codec up again on resume. Stopping the output no longer applies the sleep pads itself. Output cannot survive the platform taking the SoC down, and a device runtime reference does not hold off DLPS on its own, so register a platform PM check callback that fails while any instance is running output. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
Pick the low power flow from REALTEK_BEE_HAS_PCK600 instead of the SoC series, which also lets both flows share the wakeup pad bookkeeping. Without the PCK-600 power control the registers are gone over a low power state, so add a PM device that gates the clock and the pads on suspend and restores the registers on resume. The HAL save buffer is filled when the controller is set up and the enable and the interrupt mask are mirrored into it as they are written. Suspend arms the sleep state row pads as wakeup sources and resume reports which pad woke the system, so a key pressed while the scanner was down starts a manual scan. A row already holding a key down cannot wake on another press, so BEE_INPUT_KEYSCAN_PM_RELEASE_WAKEUP chooses between waking on the release, which leaks through the pull resistor while the key is held, and waiting for the next timer wakeup. A scan in progress cannot survive the platform taking the SoC down, so register a platform PM check callback that fails while a scan is pending. The input_dump sample moves its rows on the rtl87x2j evb while at it, P2_4 and P2_5 are not brought out as keys on that board. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
UART_INTConfig() read-modify-writes the interrupt enable register, and so does the interrupt service routine when it re-arms the RX idle interrupt, so one can lose the bit the other has just written. Wrap the call in a helper that holds the interrupt lock and route every call site through it. dma_start() only rejects a channel the preceding dma_config() has already accepted, and returning early from there left the UART DMA requests enabled and the timeout timer running, which is a worse state than letting the transfer report its own failure. The async path goes through the DMA driver API and names no DMA HAL identifier of its own, so drop the per SoC series DMA HAL headers. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
The driver kept the UART clock forced on for as long as a transfer was in flight, which only works where the PCK-600 power control is there and keeps the device out of the Zephyr power management. Implement the PM device actions instead. Without a PCK-600 suspend saves the registers through the HAL low power store hook and resume restores them. A device runtime reference is taken for as long as the transmitter or the receiver is enabled, so a UART nobody uses can be suspended while the rest of the system runs. A UART marked as a wakeup source arms its RX pad before suspending and, once it has woken the system up, holds a reference for UART_BEE_KEEP_ACTIVE_TIMEOUT_MSEC so that the incoming frame is received. Holding off the platform low power state needs a check callback on top of the device reference, because the platform takes the SoC down without asking the devices. Drop the always-clock-force-on devicetree property, which has no user left now that the device runtime power management decides when the UART may be powered down. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
The test picked its power management code by SoC series, which no longer says anything now that every Bee SoC supports the PM device actions. What differs is the PCK-600: with one the kernel idle enters the low power state on its own, without one the platform power manager takes the whole SoC down once every check callback agrees. Key the platform callbacks on that, and wrap the wakeup counter, which only a PCK-600 keeps, in a macro. Ask for a wakeup capable interrupt through the GPIO_INT_WAKEUP flag rather than a Bee specific flag, and turn on the device runtime power management on the boards that have a PCK-600. Add a shell command that hands back the device runtime reference the serial shell backend holds on its UART, which is what keeps the whole system out of a low power state. The driver takes its own reference around every transfer and arms a pad wakeup in between, so the first incoming frame resumes the UART and the shell stays usable. Drop the RTC RAP GPIO toggle test, which drives the RTC and the RAP (Realtek Action Peripheral) through the HAL behind the back of the RTC driver, so it only runs when the counter node is disabled and has to undefine GPIO_INT_MASK to include the HAL headers at all. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yuzhuo Liu <[email protected]>
YuzhuoLiuRTK
force-pushed
the
downstream/v4.4/drivers/add-pm-device
branch
from
October 14, 2026 06:04
7ae6462 to
b695811
Compare
YuzhuoLiuRTK
marked this pull request as draft
October 16, 2026 03:00
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Support the Zephyr PM device actions on every Realtek Bee driver, instead of only on the SoC series whose HAL drives an Arm PCK-600 power control kit.
A new hidden Kconfig symbol,
REALTEK_BEE_HAS_PCK600, lets each driver key on that capability instead of on the SoC series.Drivers covered: counter, pwm, gpio, adc, i2c, ir, spi, qdec, can, i2s, codec, keyscan, uart. Where the HAL provides a save buffer the registers are restored from it, otherwise resume replays the configuration the driver last applied.
uart, i2s, codec and keyscan also register a platform PM check callback: a device runtime reference alone cannot hold off the platform low power state, because the platform takes the SoC down without asking the devices.
Dependency
This series does not build on its own. It has to go in together with the companion hal_realtek pull request: rtkconnectivity/hal_realtek#22