Re: [PATCH v2 1/4] soc: qcom: rpmh: Allow non-child devices to issue write commands

From: Fenglin Wu

Date: Tue Jun 30 2026 - 22:43:24 EST




On 6/30/2026 10:37 PM, Mark Brown wrote:
> On Tue, Jun 30, 2026 at 04:28:54PM +0200, Konrad Dybcio wrote:
>
>> +Mark, would you accept not-quite-a-regulator driver?
>
> Probably not, but I'm having a hard time telling what the problem is -
> the quoting level is rather deep and multiple levels of it don't use any
> word wrapping within paragraphs so it's all excessively hard to read.
> Frankly I very nearly just deleted the mail unread. Could someone
> summarise what's going on here please?

Hi Mark,

Please see a short summary below:

Qcom PMH0101 includes bi-directional level-shifter (BIDIR_LVL_SHIFTER)
modules that act as open-drain voltage translators, mainly to support
1.2 to 1.8V voltage translation on the I2C bus between the SoC with 1.2V
IOs and other I2C clients with 1.8V IOs. Each module shares two physical
pins with two GPIO modules, and control of the BIDIR_LVL_SHIFTER module
is centralized on the AOP side with 'XOB' resources so it can be shared
between different subsystems.

When a BIDIR_LVL_SHIFTER is enabled, it needs to send RPMh commands to
enable it and SPMI commands to disable the related two GPIO modules, to
make sure their circuitry does not interfere with it. For now, the
suggestion is to write a new driver for BIDIR_LVL_SHIFTER and place it
as a child of the rpmh_rsc device, and refer to pinstate nodes to
disable these two GPIO modules. However, we are now facing a difficulty
in deciding which subsystem the new driver should belong to. We expected
that the new driver should provide following capabilities:

1. Enable and disable the level-shifter at runtime. Consumers, likely
I2C client devices, will enable it when active and disable it when not,
mainly to save power.
2. Allow sharing the level-shifter between multiple consumers, even
across different subsystems (currently managed by AOP).

Following are the approaches that we are considered, and it seems only a
regulator device could satisfy the requirement the best but we want to
check with you if you are fine to put it in the regulator framework.

A. Using the mux subsystem: The level-shifter acts as a switch, so it
fits the mux subsystem physically. It can be enabled/disabled via
‘mux_control_select()’ and ‘mux_control_deselect()’. However, with
multiple consumers, a second call to ‘mux_control_select()’ is blocked
until ‘mux_control_deselect()’ is called, so votes from multiple
consumers are not allowed and can’t be aggregated.

B. Using the GPIO/pinctrl subsystem: After moving to a new driver, the
level-shifter doesn’t fit the GPIO controller or pinctrl device concept.
It has only one pinmux, and each level-shifter works with two pins.
Also, both GPIO and pinctrl frameworks require exclusive control, and
couldn't shared between consumers.

C. Using the regulator framework: The level-shifter is controlled via
the RPMh XOB resource at the AOP side, which was adopted from the idea
of power rails sharing between subsystems. The regulator framework’s
APIs and reference counting fit the requirements for sharing between
multiple consumers. The problem is, the level-shifter isn’t a power rail
so it is conceptually not a regulator.

Thanks
Fenglin Wu