[PATCH v2 6/9] interconnect: qcom: let platforms declare their bugginess

Dmitry Baryshkov
2026-03-24T00:11:17Z

On MSM8974 programming some of the RPM resources results in the
"resource does not exist" messages from the firmware. This occurs even
with the downstream bus driver, which happily ignores the errors. My
assumption is that these resources existed in the earlier firmware
revisions but were later switched to be programmed differently (for the
later platforms corresponding nodes use qos.ap_owned, which prevents
those resources from being programmed.

In preparation for conversion of the MSM8974 driver (which doesn't have
QoS code yet) to the main icc-rpm set of helpers, let the driver declare
that those -ENXIO errors must be ignored (for now). Later, when the QoS
programming is sorted out (and more interconnects are added to the DT),
this quirk might be removed.

Reviewed-by: Brian Masney <bmasney@redhat.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/interconnect/qcom/icc-rpm.c | 17 ++++++++++-------
drivers/interconnect/qcom/icc-rpm.h | 3 +++
2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c
index aec2f84cd56f..23a1d116e79a 100644
--- a/drivers/interconnect/qcom/icc-rpm.c
+++ b/drivers/interconnect/qcom/icc-rpm.c
@@ -204,7 +204,7 @@ static int qcom_icc_qos_set(struct icc_node *node)
}
}

-static int qcom_icc_rpm_set(struct qcom_icc_node *qn, u64 *bw)
+static int qcom_icc_rpm_set(struct qcom_icc_node *qn, u64 *bw, bool ignore_enxio)
{
int ret, rpm_ctx = 0;
u64 bw_bps;
@@ -222,8 +222,9 @@ static int qcom_icc_rpm_set(struct qcom_icc_node *qn, u64 *bw)
bw_bps);
if (ret) {
pr_err("qcom_icc_rpm_smd_send mas %d error %d\n",
- qn->mas_rpm_id, ret);
- return ret;
+ qn->mas_rpm_id, ret);
+ if (ret != -ENXIO || !ignore_enxio)
+ return ret;
}
}

@@ -234,8 +235,9 @@ static int qcom_icc_rpm_set(struct qcom_icc_node *qn, u64 *bw)
bw_bps);
if (ret) {
pr_err("qcom_icc_rpm_smd_send slv %d error %d\n",
- qn->slv_rpm_id, ret);
- return ret;
+ qn->slv_rpm_id, ret);
+ if (ret != -ENXIO || !ignore_enxio)
+ return ret;
}
}
}
@@ -361,12 +363,12 @@ static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
active_rate = agg_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE];
sleep_rate = agg_clk_rate[QCOM_SMD_RPM_SLEEP_STATE];

- ret = qcom_icc_rpm_set(src_qn, src_qn->sum_avg);
+ ret = qcom_icc_rpm_set(src_qn, src_qn->sum_avg, qp->ignore_enxio);
if (ret)
return ret;

if (dst_qn) {
- ret = qcom_icc_rpm_set(dst_qn, dst_qn->sum_avg);
+ ret = qcom_icc_rpm_set(dst_qn, dst_qn->sum_avg, qp->ignore_enxio);
if (ret)
return ret;
}
@@ -509,6 +511,7 @@ int qnoc_probe(struct platform_device *pdev)
for (i = 0; i < cd_num; i++)
qp->intf_clks[i].id = cds[i];

+ qp->ignore_enxio = desc->ignore_enxio;
qp->keep_alive = desc->keep_alive;
qp->type = desc->type;
qp->qos_offset = desc->qos_offset;
diff --git a/drivers/interconnect/qcom/icc-rpm.h b/drivers/interconnect/qcom/icc-rpm.h
index ad554c63967b..7d1cb2efa9ee 100644
--- a/drivers/interconnect/qcom/icc-rpm.h
+++ b/drivers/interconnect/qcom/icc-rpm.h
@@ -51,6 +51,7 @@ struct rpm_clk_resource {
* @bus_clk: a pointer to a HLOS-owned bus clock
* @intf_clks: a clk_bulk_data array of interface clocks
* @keep_alive: whether to always keep a minimum vote on the bus clocks
+ * @ignore_enxio: whether to ignore ENXIO errors (for MSM8974)
*/
struct qcom_icc_provider {
struct icc_provider provider;
@@ -65,6 +66,7 @@ struct qcom_icc_provider {
struct clk *bus_clk;
struct clk_bulk_data *intf_clks;
bool keep_alive;
+ bool ignore_enxio;
};

/**
@@ -136,6 +138,7 @@ struct qcom_icc_desc {
u16 ab_coeff;
u16 ib_coeff;
int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);
+ bool ignore_enxio;
};

/* Valid for all bus types */

--
2.47.3