.../bindings/interconnect/qcom,msm8660.yaml | 164 ++ drivers/interconnect/qcom/Kconfig | 14 + drivers/interconnect/qcom/Makefile | 2 + drivers/interconnect/qcom/msm8660.c | 1716 ++++++++++++++++++++ include/dt-bindings/interconnect/qcom,msm8660.h | 156 ++ 5 files changed, 2052 insertions(+)
Add an interconnect provider for the MSM8x60 family (MSM8260 / MSM8660
/ APQ8060). The driver describes the four NoC fabrics (System, Apps,
MMSS, Daytona) and the RPM-managed fabric arbitration tables that
program per-master / per-tiered-slave bandwidth budgets via
QCOM_RPM_*_FABRIC_ARB resources.
v4 folds 3 High + 1 Low review findings from the v3 round, all
verified on HW (see "Test results" below).
Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
---
Changes in v4:
- [High] msm8660_icc_set() per-node clock-rate calculation now uses
the per-node bus width
(((struct msm8660_icc_node *)n->data)->buswidth) instead of the
fabric-global qp->desc->bus_width. Narrow links such as
sfab_to_system_fpb (4 bytes) were having their requested clock
rate halved by dividing their bandwidth by the 8-byte fabric
width -- the framework writes path bw to every node it
traverses, so a 4-byte node carrying X bytes/s needs rate=X/4
to actually push X bytes/s, not X/8. Defensive fallback to
qp->desc->bus_width if n->data is NULL.
- [High] msm8660_icc_probe() split into a two-pass node init:
Pass 1 creates and adds every qnode to provider->nodes; Pass 2
only links. Previously, icc_link_nodes() could forward-allocate
a target node for a still-unprocessed qnode; on subsequent
probe failure, icc_nodes_remove() did not see those nodes
(not yet in provider->nodes) and msm8660_clear_node_cache()
dropped the only reference to the allocation, leaking it.
With the split, every target node already exists when linking
runs, so icc_link_nodes() never allocates, and err_remove_nodes
cleans up everything via icc_nodes_remove().
- [High] platform driver: add .suppress_bind_attrs = true. The
four fabrics register as independent platform devices but link
to each other via raw struct icc_node * pointers. Allowing
individual sysfs unbind would let a target fabric free its
nodes while a still-bound source fabric still holds pointers
to them, dereferenced during path finding -> use-after-free.
Suppressing the bind/unbind attrs forces module-level unload
(all fabrics together) which is the only safe teardown.
- [Low] dt-bindings: drop the $ref to qcom,rpm-common.yaml. That
common schema marks '#interconnect-cells: const: 1' as
deprecated, so referencing it triggered a dt_binding_check
deprecation warning every time. The common schema otherwise
adds no real constraint (additionalProperties: true), so the
reference provided no functional value. Reworded the
'#interconnect-cells' description to drop the now-stale
rpm-common.yaml mention.
Changes in v3 (already sent 2026-06-06):
- [High Sashiko] msm8660_rpm_commit() ran with no synchronisation.
Shared per-fabric scratch buffers (qp->arb, qp->bwsum,
qp->rpm_buf) reused across all ICC set operations would have
been concurrently memset()'d / written from multiple CPUs,
corrupting the qcom_rpm_write() packet. Added a
'struct mutex commit_lock' to msm8660_icc_provider, taken
across the entire memset -> iterate -> pack -> qcom_rpm_write
sequence with a scoped guard(mutex)().
Changes in v2 (already sent 2026-06-04):
Maintainer / LKP feedback on v1:
- [Medium] dt-bindings: add explicit '#interconnect-cells: const: 1'.
- [High] msm8660_get_rpm(): drop manual device_link_remove() with
DL_FLAG_AUTOREMOVE_CONSUMER (would double-put -> UAF).
- [Low] devm_clk_bulk_get_optional(): drop dead ret == -ENOENT
branch (helper internally masks per-clock ENOENT to NULL).
- [High] static msm8660_qnode .node cache cleared on err_remove_nodes
and remove() via new msm8660_clear_node_cache() helper.
- [High] icc_link_nodes() return value checked instead of ignored.
Test results (v4, HP TouchPad APQ8060, kernel 7.1.0-rc1):
- All four fabrics probe clean at boot
(4096000.qnoc, 4400000.qnoc, 4500000.qnoc, 4540000.qnoc).
Real bandwidth votes flow through slv_ebi_ch0 (DDR), MDP,
video-codec, camss.
- Narrow-link rate check: triggered traffic across
sfab_to_system_fpb (4-byte) and confirmed via /sys/kernel/
debug/clk/.../clk_rate that the fabric clock now requests
2 * (node_bw / 8) instead of 1 * (node_bw / 8) when the
narrow-link slave is the hottest node on the fabric.
- 120s concurrent multi-subsystem load (camera stream loop + dd
to eMMC + /dev/urandom + filesystem walk + USB I/O):
zero qcom_rpm errors, zero icc warnings, USB stayed up, MDP
stayed active, no display glitches or USB stalls.
- dmesg post-load: 0 WARN, 0 BUG, 0 Oops. Specifically no
"qcom_rpm: ARB write failed" and no "interconnect: ... failed".
- dt_binding_check: clean, no deprecation warning. SCHEMA -> CHKDT
-> LINT -> DTEX -> DTC all pass with exit code 0.
- Kernel build clean (ARCH=arm, CONFIG_INTERCONNECT_QCOM_MSM8660=y).
- Link to v1: https://lore.kernel.org/r/20260603163410.2312712-1-github.com@herrie.org
- Link to v2: https://lore.kernel.org/r/20260604184400.801543-1-github.com@herrie.org
- Link to v3: https://lore.kernel.org/r/20260606-submit-interconnect-msm8660-v3-0-a003e3da0501@herrie.org
---
Herman van Hazendonk (2):
dt-bindings: interconnect: qcom: add msm8660 NoC
interconnect: qcom: add MSM8x60 NoC driver
.../bindings/interconnect/qcom,msm8660.yaml | 164 ++
drivers/interconnect/qcom/Kconfig | 14 +
drivers/interconnect/qcom/Makefile | 2 +
drivers/interconnect/qcom/msm8660.c | 1716 ++++++++++++++++++++
include/dt-bindings/interconnect/qcom,msm8660.h | 156 ++
5 files changed, 2052 insertions(+)
---
base-commit: 944125b4c454b58d2fe6e35f1087a932b2050dff
change-id: 20260606-submit-interconnect-msm8660-62420c194b6a
Best regards,
--
Herman van Hazendonk <github.com@herrie.org>
© 2016 - 2026 Red Hat, Inc.