Fishwaldo opened a new pull request, #19879:
URL: https://github.com/apache/nuttx/pull/19879
## Summary
Adds `/proc/regulator`, listing every registered regulator with what it is
putting out and who is holding it.
The regulator framework has no way out to userspace at all. Consumers reach a
rail by name from inside the kernel, which is the right interface for
controlling one, but it leaves a board with regulators offering no way to see
what they are doing, and a newly written regulator driver cannot be looked at
without writing a consumer for it first. This is a quality of life view of
the
same kind as `/proc/pinctrl`, `/proc/reset` and `/proc/gpio`.
```
npu_vdd uv:718750 min:700000 max:1100000 enabled:1 users:0
opens:0 supply:- always_on:1 boot_on:0
```
Every line carries the same `key:value` tokens in the same order, so the file
can be parsed as well as read:
| Token | Meaning |
|---|---|
| `uv` | Present voltage in microvolts, or `-` if unreadable |
| `min`, `max` | The range the regulator will accept |
| `enabled` | Whether the rail is on, or `-` if unreadable |
| `users` | Consumers currently enabling it |
| `opens` | Handles currently held on it |
| `supply` | The regulator feeding this one, or `-` |
| `always_on` | Set if the rail must never be switched off |
| `boot_on` | Set if the rail is expected on at start up |
`always_on` and `boot_on` earn their place beside the counts: the line above
shows `enabled:1 users:0`, which reads as a leaked enable until `always_on:1`
explains it.
The voltage and the enabled state are read back from the hardware rather than
recalled, so a rail the boot loader set and nothing has touched since reads
as
it actually is. Both calls can fail, and a failure reports `-` rather than an
errno formatted as a voltage, or as a rail that looks switched on.
Reading the hardware is also why this takes the list mutex directly rather
than
calling `regulator_list_lock()`, which additionally disables interrupts so
that
callers in interrupt or idle context are safe. Asking a regulator on a bus
what
it is doing means a transfer, and a transfer waits; a task reading a file can
afford to wait and an interrupt handler cannot.
The entry is read only. What voltage a rail may be is knowledge its consumers
hold, and arranging the order between them is what the framework is for, so
moving one from a shell would step around the part that matters.
`Documentation/components/drivers/special/power/` had no regulator page at
all.
It now documents the framework: the consumer interface and what counted
enables
and intersected voltage ranges mean, what a driver supplies, the new entry,
and
the rpmsg variant.
## Impact
New feature, off by default. With `CONFIG_REGULATOR_PROCFS` unset nothing
here
is compiled.
No interface changes: no new method, no change to `struct regulator_dev_s` or
`struct regulator_ops_s`, and no existing driver needs updating. The entry is
built from state the framework already holds plus the two read operations any
regulator may already implement.
Also fixes the option's dependencies. It declared `depends on FS_PROCFS`
while
calling `procfs_register()`, which exists only under `FS_PROCFS_REGISTER`, so
enabling it with `FS_PROCFS=y` and `FS_PROCFS_REGISTER=n` failed to link. And
`procfs_register()` appends without checking for duplicates, so the entry is
now claimed once for the lifetime of the system rather than whenever the list
is empty.
Worth flagging to reviewers: **no in-tree configuration enables
`CONFIG_REGULATOR`**, so CI will not compile this code. A green run says
nothing about it, and the testing below is the only evidence.
## Testing
Host: macOS 26.5.1 (arm64), `riscv-none-elf-gcc` 15.2.0, Sphinx 6.2.1.
**Build**: `sim:nsh` with `REGULATOR` alone, and again with `FS_PROCFS`,
`FS_PROCFS_REGISTER` and `REGULATOR_PROCFS` added, each from a clean tree:
both
compile `drivers/power/supply/regulator.c`. Documentation builds with no new
warnings.
**Hardware**: ESWIN EIC7700 EVB (EIC7700X, 4 x RV64GC), whose NPU rail is an
MPS MPQ8785 on I2C.
```
nsh> cat /proc/regulator
npu_vdd uv:718750 min:700000 max:1100000 enabled:1 users:0
opens:0 supply:- always_on:1 boot_on:0
```
The voltage was cross-checked against a second, independent path to the same
part: that driver also publishes through uORB, and `sensor_voltage0` reports
**0.720312 V** where procfs reports **718750 uV**. Both are right and they
measure different things, which is worth stating because the difference looks
like an error at first glance:
* the regulator path reads `VOUT_COMMAND`, the commanded setpoint, which the
framework reconstructs from the selector as `min_uv + n * uv_step`, here
700000 + 3 * 6250
* the uORB path reads `READ_VOUT`, the measured output
They differ by 1562 uV, 0.22%, which is a switching converter regulating
close
to its command rather than exactly on it.
That comparison also confirms the read-back: `users:0` means nothing in NuttX
has ever set this rail, so 718750 can only have come from reading what the
boot
loader left, not from anything this software remembered.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]