Skip to content

drivers/reset: Add line read-back and a procfs entry - #19876

Open
Fishwaldo wants to merge 1 commit into
apache:masterfrom
Fishwaldo:upstream-reset-procfs
Open

drivers/reset: Add line read-back and a procfs entry#19876
Fishwaldo wants to merge 1 commit into
apache:masterfrom
Fishwaldo:upstream-reset-procfs

Conversation

@Fishwaldo

Copy link
Copy Markdown
Contributor

Summary

Adds /proc/reset, which lists every reset line a board's controllers have and
whether each one is currently asserted or released.

There was no way to see that. status() reads one line at a time, and only for
a caller that already knows its id; nothing else in the interface says how many
lines a controller has or what any of them resets. During bring up that is the
question that matters, since a peripheral that appears dead is often just still
in reset.

The file is rendered from a new optional get_line method, under
CONFIG_RESET_PROCFS. Every line carries the same key:value tokens in the
same order, so the file can be parsed as well as read.

It also fixes an existing hazard in the function it modifies:
procfs_register() appends without checking for duplicates, so registering a
controller after all of them had unregistered would have added /proc/reset a
second time. The entry is now claimed once for the lifetime of the system.

The state deliberately stays with status(), which already reports it — the
framework calls it, so a controller never supplies the same fact twice.
get_line supplies only what the framework cannot derive:

struct reset_lineinfo_s
{
  char name[RESET_NAME_MAX];    /* What this line resets */
  char extra[RESET_EXTRA_MAX];  /* Controller specific key:value text */
};

Everything is optional. A controller without get_line is listed by name
and a note. Both members may be left empty, and a line then reports by id
alone. extra carries whatever the structure has no member for.

Controllers commonly leave gaps in their numbering, so nlines in
struct reset_controller_dev bounds the ids get_line is asked about rather
than counting real lines — for a controller with dense numbering the two are
the same, which is why it is not called maxid. Returning -ENODEV reports an
id that names no line, and the renderer skips those, which is what keeps the
listing dense:

static int mychip_getline(FAR struct reset_controller_dev *rcdev,
                          unsigned int id,
                          FAR struct reset_lineinfo_s *info)
{
  if (id >= nitems(g_mychip_lines) || g_mychip_lines[id].name == NULL)
    {
      return -ENODEV;              /* a gap in the numbering */
    }

  strlcpy(info->name, g_mychip_lines[id].name, sizeof(info->name));
  snprintf(info->extra, sizeof(info->extra), "reg:0x%03x bit:%u",
           MYCHIP_RESET_REG(id), MYCHIP_RESET_BIT(id));
  return OK;
}

This follows the shape of the pinctrl read-back in #19871, so the two procfs
entries agree on how a controller describes itself.

Documentation/components/drivers/special/reset.rst had a title and no
content. It now documents the framework: the consumer interface and what
shared and exclusive handles mean, the controller interface and its call
table, the new method, and /proc/reset.

Impact

New feature, off by default. CONFIG_RESET_PROCFS depends on
FS_PROCFS_REGISTER; with it unset nothing here is compiled.

struct reset_control_ops gains one optional member and
struct reset_controller_dev gains nlines. The only in-tree controller is
drivers/reset/reset_rpmsg.c, which is unaffected: it allocates its controller
with kmm_zalloc(), so the new field is zero and the new method NULL, and it
is listed with its note.

No change to the existing operations or their behaviour.

Worth flagging to reviewers: no in-tree configuration enables CONFIG_RESET,
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, since CI cannot: sim:nsh with RESET, FS_PROCFS,
FS_PROCFS_REGISTER and RESET_PROCFS forced on compiles drivers/reset/core.c
clean; also built with RESET_PROCFS off. Documentation builds with no new
warnings.

Hardware: ESWIN EIC7700 EVB (EIC7700X, 4 x RV64GC). The consumer is the
EIC7700X CRG reset driver, part of a port being upstreamed separately; this
PR is deliberately independent of it and adds no in-tree user.

nsh> cat /proc/reset
eic7700x-crg:
0    noc_nsp                  state:released reg:0x400 bit:0
16   snoc_aon_a               state:released reg:0x400 bit:16
32   gpu_axi                  state:asserted reg:0x404 bit:0
36   gpu_spu                  state:asserted reg:0x404 bit:4
64   dsp_axi                  state:asserted reg:0x408 bit:0
1920 testmux                  state:released reg:0x4f0 bit:0
1921 spi_slv                  state:released reg:0x4f0 bit:1

Note 16 → 32 → 36 → 64: that controller is a good exercise of the sparse case,
1628 of its 1952 ids naming nothing, and the gaps are skipped rather than
printed.

Checked on that output:

  • 324 lines rendered, exactly matching the controller's table — every gap
    skipped, none of the 1628 empty ids printed
  • ids strictly increasing with no duplicate at any read boundary; the file is
    many times one read buffer, so this exercises the pos accounting across
    repeated read() calls
  • the state: column verified against the hardware: 107 of the lines fall
    in registers I read independently over JTAG while the board was running, and
    all 107 agree with the register bits (active low, so a set bit reads
    released) — 0 mismatches
  • the asserted lines are plausible on their own terms: the GPU and DSP blocks
    read state:asserted throughout, and nothing has brought either out of reset

A controller without get_line was checked by removing the method: the
controller is listed with its note and no lines.

@github-actions github-actions Bot added Area: Drivers Drivers issues Size: L The size of the change in this PR is large labels Aug 17, 2026
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

qemu-armv8a

jerpelea
jerpelea previously approved these changes Aug 17, 2026
status() reads one reset line at a time, and only for a caller that
already knows the id.  Nothing else in the interface says how many lines
a controller has or what any of them resets, so the lines a board is
holding cannot be surveyed.

Adds an optional get_line method describing one line as a structure: its
name, and a text member for controller specific fields the structure
does not cover.  The asserted state stays with status(), which already
reports it, so a controller does not supply the same fact twice.
Returning -ENODEV reports an id that names no line, which is how
controllers with gaps in their numbering are handled.
reset_controller_dev gains the line count that bounds the ids.

CONFIG_RESET_PROCFS adds /proc/reset, one key:value line per reset line,
every line the same tokens in the same order so the file is machine
parseable.  A controller without get_line is listed by name and a note.

The controller list already existed for reset_control_get() to search,
so the renderer only walks what was there.  /proc/reset is claimed when
the first controller registers; procfs_register() requires that procfs
is not yet mounted, which holds because controllers register during
board or architecture start up, and it appends without checking for
duplicates, so the entry is claimed once for the lifetime of the system.

Documents the framework, which had a page with nothing on it: the
consumer interface and what shared and exclusive handles mean, the
controller interface, the new method, and /proc/reset.

Off by default and costs nothing when off.  No in-tree configuration
enables RESET, so this builds only when a board turns it on.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
@Fishwaldo
Fishwaldo force-pushed the upstream-reset-procfs branch from b6c445d to 815cc35 Compare August 17, 2026 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Drivers Drivers issues Size: L The size of the change in this PR is large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants