[PATCH/RFC 02/14] firmware: arm_scmi: quirk: Handle bad clocks on R-Car X5H

Geert Uytterhoeven
2026-04-21T18:12:08Z

Renesas R-Car X5H SCP FW SDKv4.28.0, v4.31.0, and v4.32.0 expose a few
clocks that do not support the CLOCK_ATTRIBUTES or CLOCK_DESCRIBE_RATES
command. Since commit 0d8b0c8068a8ff5f ("firmware: arm_scmi: Harden
clock protocol initialization") in scmi/for-linux-next (next-20260319
and later), scmi_clock_attributes_get() or
scmi_clock_describe_rates_get() failures are no longer ignored, but
prevent the SCMI clock driver from initializing.

Hence add a quirk to ignore such failures, like before. As the quirk
handling is harmless for unaffected systems, make it generic for all
R-Car X5H systems using SCP FW SDKv4.28.0 or later.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/firmware/arm_scmi/clock.c | 14 ++++++++++++++
drivers/firmware/arm_scmi/quirks.c | 3 +++
drivers/firmware/arm_scmi/quirks.h | 1 +
3 files changed, 18 insertions(+)

diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index ce6f968925af38c0..d530882a0bac88c3 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -1232,6 +1232,18 @@ static const struct scmi_protocol_events clk_protocol_events = {
.num_events = ARRAY_SIZE(clk_events),
};

+#define QUIRK_RCAR_X5H_NO_ATTRIBUTES \
+ ({ \
+ if (ret == -EREMOTEIO || ret == -EOPNOTSUPP) \
+ continue; \
+ })
+
+#define QUIRK_RCAR_X5H_NO_RATES \
+ ({ \
+ if (ret == -EOPNOTSUPP) \
+ ret = 0; \
+ })
+
static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
{
int clkid, ret;
@@ -1256,10 +1268,12 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
for (clkid = 0; clkid < cinfo->num_clocks; clkid++) {
cinfo->clkds[clkid].id = clkid;
ret = scmi_clock_attributes_get(ph, clkid, cinfo);
+ SCMI_QUIRK(clock_rcar_x5h_no_attributes, QUIRK_RCAR_X5H_NO_ATTRIBUTES);
if (ret)
return ret;

ret = scmi_clock_describe_rates_get(ph, clkid, cinfo);
+ SCMI_QUIRK(clock_rcar_x5h_no_attributes, QUIRK_RCAR_X5H_NO_RATES);
if (ret)
return ret;
}
diff --git a/drivers/firmware/arm_scmi/quirks.c b/drivers/firmware/arm_scmi/quirks.c
index c1a2f58505c1a757..e27c21b14220ab5f 100644
--- a/drivers/firmware/arm_scmi/quirks.c
+++ b/drivers/firmware/arm_scmi/quirks.c
@@ -171,6 +171,8 @@ struct scmi_quirk {

/* Global Quirks Definitions */
DEFINE_SCMI_QUIRK(clock_rates_triplet_out_of_spec, NULL, NULL, NULL);
+DEFINE_SCMI_QUIRK(clock_rcar_x5h_no_attributes, "Renesas", NULL, "0x10a0000-",
+ "renesas,r8a78000");
DEFINE_SCMI_QUIRK(perf_level_get_fc_force, "Qualcomm", NULL, "0x20000-");
DEFINE_SCMI_QUIRK(power_rcar_x5h_4_28_bad_domains, "Renesas", NULL,
"0x10a0000-0x10e0000", "renesas,r8a78000");
@@ -183,6 +185,7 @@ DEFINE_SCMI_QUIRK(power_rcar_x5h_4_28_bad_domains, "Renesas", NULL,
*/
static struct scmi_quirk *scmi_quirks_table[] = {
__DECLARE_SCMI_QUIRK_ENTRY(clock_rates_triplet_out_of_spec),
+ __DECLARE_SCMI_QUIRK_ENTRY(clock_rcar_x5h_no_attributes),
__DECLARE_SCMI_QUIRK_ENTRY(perf_level_get_fc_force),
__DECLARE_SCMI_QUIRK_ENTRY(power_rcar_x5h_4_28_bad_domains),
NULL
diff --git a/drivers/firmware/arm_scmi/quirks.h b/drivers/firmware/arm_scmi/quirks.h
index 108c8d11f6043a61..67818b6cf0909f8e 100644
--- a/drivers/firmware/arm_scmi/quirks.h
+++ b/drivers/firmware/arm_scmi/quirks.h
@@ -47,6 +47,7 @@ static inline void scmi_quirks_enable(struct device *dev, const char *vend,

/* Quirk delarations */
DECLARE_SCMI_QUIRK(clock_rates_triplet_out_of_spec);
+DECLARE_SCMI_QUIRK(clock_rcar_x5h_no_attributes);
DECLARE_SCMI_QUIRK(perf_level_get_fc_force);
DECLARE_SCMI_QUIRK(power_rcar_x5h_4_28_bad_domains);

--
2.43.0