Re: [PATCH v2] spmi: core: Add generic DebugFS interface for bus inspection
From: Abel Vesa
Date: Mon Oct 19 2026 - 06:42:51 EST
On 26-10-16 22:00:58, vamshi gajjela wrote:
> Introduce a generic, controller-agnostic DebugFS interface in the SPMI
> core under /sys/kernel/debug/spmi/spmi-<nr>/:
> - name: Displays the controller parent device name and OF node.
> - detect: Probes the bus for active slave IDs (0x0 to 0xF).
> - xfer: Transactional interface supporting register reads, writes,
> and directed command opcodes with automatic opcode selection.
>
> Write and command operations restrict access to root (mode 0600) and
> mark the kernel tainted with TAINT_USER. Runtime PM is managed
> automatically across transactions.
>
> Detailed interface syntax and parameters are documented in
> Documentation/ABI/testing/debugfs-spmi.
>
> Co-developed-by: Jim Wylder <jwylder@xxxxxxxxxx>
> Signed-off-by: Jim Wylder <jwylder@xxxxxxxxxx>
> Signed-off-by: vamshi gajjela <vamshigajjela@xxxxxxxxxx>
> ---
> Changes in v2:
> - Rename spmi.c to spmi-core.c and link spmi-debugfs.o into the composite
> spmi.o module so CONFIG_SPMI=m builds cleanly with CONFIG_DEBUG_FS=y.
> - Route DebugFS bus operations through spmi_read_cmd(), spmi_write_cmd(),
> and spmi_cmd() instead of calling controller callbacks directly,
> preserving SPMI tracepoints and core validation.
> - Allocate a per-open-file struct spmi_xfer_ctx in open() instead of
> sharing a controller-wide buffer, avoiding races across concurrent file
> descriptors, and store struct dentry *debugfs directly on
> struct spmi_controller.
> - Reset *ppos = 0 on register read commands so repeated transactions on
> the same open file descriptor work without manual seeking.
> - Restrict SPMI_CMD_ZERO_WRITE at address 0x00 to 7-bit payloads
> (data[0] <= 0x7f) per the MIPI SPMI specification, falling back to
> SPMI_CMD_WRITE for 8-bit values.
> - Parse register addresses with kstrtou16() so values above 0xffff are
> rejected instead of silently truncated.
> - Update Documentation/ABI/testing/debugfs-spmi to document per-fd xfer
> buffers and 7-bit Zero Write opcode selection.
>
> Documentation/ABI/testing/debugfs-spmi | 77 +++++
> MAINTAINERS | 1 +
> drivers/spmi/Makefile | 2 +
> drivers/spmi/{spmi.c => spmi-core.c} | 18 +-
> drivers/spmi/spmi-debugfs.c | 380 +++++++++++++++++++++++++
> include/linux/spmi.h | 24 ++
> 6 files changed, 496 insertions(+), 6 deletions(-)
> create mode 100644 Documentation/ABI/testing/debugfs-spmi
> rename drivers/spmi/{spmi.c => spmi-core.c} (97%)
> create mode 100644 drivers/spmi/spmi-debugfs.c
>
[...]
> diff --git a/include/linux/spmi.h b/include/linux/spmi.h
> index 28e8c8bd3944..237b0b9d4377 100644
> --- a/include/linux/spmi.h
> +++ b/include/linux/spmi.h
> @@ -69,6 +69,8 @@ int spmi_device_add(struct spmi_device *sdev);
>
> void spmi_device_remove(struct spmi_device *sdev);
>
> +struct dentry;
> +
> /**
> * struct spmi_controller - interface to the SPMI master controller
> * @dev: Driver model representation of the device.
> @@ -76,6 +78,7 @@ void spmi_device_remove(struct spmi_device *sdev);
> * @cmd: sends a non-data command sequence on the SPMI bus.
> * @read_cmd: sends a register read command sequence on the SPMI bus.
> * @write_cmd: sends a register write command sequence on the SPMI bus.
> + * @debugfs: debugfs dentry for this controller.
> */
> struct spmi_controller {
> struct device dev;
> @@ -85,6 +88,9 @@ struct spmi_controller {
> u8 sid, u16 addr, u8 *buf, size_t len);
> int (*write_cmd)(struct spmi_controller *ctrl, u8 opcode,
> u8 sid, u16 addr, const u8 *buf, size_t len);
> +#if IS_ENABLED(CONFIG_DEBUG_FS)
> + struct dentry *debugfs;
> +#endif
> };
>
> static inline struct spmi_controller *to_spmi_controller(struct device *d)
> @@ -186,4 +192,22 @@ int spmi_command_sleep(struct spmi_device *sdev);
> int spmi_command_wakeup(struct spmi_device *sdev);
> int spmi_command_shutdown(struct spmi_device *sdev);
>
> +int spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid);
> +int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode,
> + u8 sid, u16 addr, u8 *buf, size_t len);
> +int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode,
> + u8 sid, u16 addr, const u8 *buf, size_t len);
These are not exported, so they can only be used from within spmi.o.
Please move them (together with the debugfs prototypes below) to a
local header in drivers/spmi/ instead of the public include/linux/spmi.h.