From nobody Wed Apr 8 04:41:10 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A29A23DCDA7; Tue, 10 Mar 2026 18:41:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168091; cv=none; b=tgfVnvxe/aXcojkuzQR4Fzqz/Sa4yI1oMfIj+XhY4h3HQ7mfOqbghCq86q3r3e1PbFI/Wzr3WWpSIn0p5XFVO+oFPWDYimtB1yNUxzQxRZZ7ZHe9wc92qOjqziJ7Odmbr/MDnRvbG1WYNWnTAHQ9+0OfBZjbEYK/i2VzjF9m4sM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168091; c=relaxed/simple; bh=4PsJYF0qEC5bYPzqJY/2oi7M+0Ulx0rXVTlWOgy9JOo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BYb7yhqicfvkUXlSaV2ZEYftdyrmuk4+IDkolj3lbwB6U/W5fVhZO8mqa5LkNZ9V8rB5Qj7qyUloZuJ8nohKxEfurm//3FThi0xab5T6oWO8m8gzijPBiFIOW2tLpBxyBZXJAynMWIcD3MthtwqqW+Yaz9cj48ehS5aZ9ZZf3Ec= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 996D014BF; Tue, 10 Mar 2026 11:41:19 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9C2903F7BD; Tue, 10 Mar 2026 11:41:22 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi Subject: [PATCH v2 11/13] firmware: arm_scmi: Add bound iterators support Date: Tue, 10 Mar 2026 18:40:28 +0000 Message-ID: <20260310184030.3669330-12-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" SCMI core stack provides some common helpers to handle in a unified way multipart message replies: such iterator-helpers, when run, currently process by default the whole set of discovered resources. Introduce an alternative way to run the initialized iterator on a limited range of resources. Note that the subset of resources that can be chosen is anyway limited by the SCMI protocol specification, since you are only allowed to choose the startindex on a multi-part enumeration NOT the end index, so that the effective number of returned items by a bound iterators depends really on platform side decisions. Suggested-by: Etienne Carriere Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/clock.c | 3 +- drivers/firmware/arm_scmi/driver.c | 58 +++++++++++++++++++-------- drivers/firmware/arm_scmi/protocols.h | 13 +++++- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/= clock.c index 5f6b25c7b523..a7dbb0c4f31c 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -511,8 +511,7 @@ iter_clk_describe_process_response(const struct scmi_pr= otocol_handle *ph, struct scmi_clk_ipriv *p =3D priv; const struct scmi_msg_resp_clock_describe_rates *r =3D response; =20 - p->clkd->rates[st->desc_index + st->loop_idx] =3D - RATE_TO_U64(r->rate[st->loop_idx]); + p->clkd->rates[p->clkd->num_rates] =3D RATE_TO_U64(r->rate[st->loop_idx]); =20 /* Count only effectively discovered rates */ p->clkd->num_rates++; diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi= /driver.c index 4bd069da879e..3c393a071750 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1813,48 +1813,50 @@ static void *scmi_iterator_init(const struct scmi_p= rotocol_handle *ph, return no_free_ptr(i); } =20 -static int scmi_iterator_run(void *iter) +static int __scmi_iterator_run(void *iter, unsigned int *start, unsigned i= nt *end) { int ret; struct scmi_iterator_ops *iops; const struct scmi_protocol_handle *ph; struct scmi_iterator_state *st; + struct scmi_iterator *i; =20 if (!iter) return -EINVAL; =20 - /* Take ownership of the iterator */ - struct scmi_iterator *i __free(kfree) =3D iter; - + i =3D iter; iops =3D i->ops; ph =3D i->ph; st =3D &i->state; =20 + /* Reinitialize state for next run */ + st->num_returned =3D 0; + st->num_remaining =3D 0; + st->desc_index =3D start ? *start : 0; + do { iops->prepare_message(i->msg, st->desc_index, i->priv); ret =3D ph->xops->do_xfer(ph, i->t); if (ret) - break; + return ret; =20 st->rx_len =3D i->t->rx.len; ret =3D iops->update_state(st, i->resp, i->priv); if (ret) - break; + return ret; =20 if (st->num_returned > st->max_resources - st->desc_index) { dev_err(ph->dev, "No. of resources can't exceed %d\n", st->max_resources); - ret =3D -EINVAL; - break; + return -EINVAL; } =20 - for (st->loop_idx =3D 0; !ret && st->loop_idx < st->num_returned; - st->loop_idx++) + for (st->loop_idx =3D 0; st->loop_idx < st->num_returned; st->loop_idx++= ) { ret =3D iops->process_response(ph, i->resp, st, i->priv); - - if (ret) - break; + if (ret) + return ret; + } =20 st->desc_index +=3D st->num_returned; ph->xops->reset_rx_to_maxsz(ph, i->t); @@ -1862,14 +1864,36 @@ static int scmi_iterator_run(void *iter) * check for both returned and remaining to avoid infinite * loop due to buggy firmware */ - } while (st->num_returned && st->num_remaining); + } while (st->num_returned && st->num_remaining && + (!end || (st->desc_index <=3D min(*end, st->max_resources - 1)))); =20 - /* Finalize and destroy iterator */ - ph->xops->xfer_put(ph, i->t); + return 0; +} + +static void scmi_iterator_cleanup(void *iter) +{ + struct scmi_iterator *i =3D iter; + + i->ph->xops->xfer_put(i->ph, i->t); + kfree(i); +} + +static int scmi_iterator_run(void *iter) +{ + int ret; + + ret =3D __scmi_iterator_run(iter, NULL, NULL); + scmi_iterator_cleanup(iter); =20 return ret; } =20 +static int scmi_iterator_run_bound(void *iter, unsigned int *start, + unsigned int *end) +{ + return __scmi_iterator_run(iter, start, end); +} + struct scmi_msg_get_fc_info { __le32 domain; __le32 message_id; @@ -2048,6 +2072,8 @@ static const struct scmi_proto_helpers_ops helpers_op= s =3D { .get_max_msg_size =3D scmi_common_get_max_msg_size, .iter_response_init =3D scmi_iterator_init, .iter_response_run =3D scmi_iterator_run, + .iter_response_run_bound =3D scmi_iterator_run_bound, + .iter_response_cleanup =3D scmi_iterator_cleanup, .protocol_msg_check =3D scmi_protocol_msg_check, .fastchannel_init =3D scmi_common_fastchannel_init, .fastchannel_db_ring =3D scmi_common_fastchannel_db_ring, diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_s= cmi/protocols.h index 4c75970326e6..487f84239385 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -259,7 +259,15 @@ struct scmi_fc_info { * multi-part responses using the custom operations * provided in @ops. * @iter_response_run: A common helper to trigger the run of a previously - * initialized iterator. + * initialized iterator. Note that unbound iterators are + * automatically cleaned up. + * @iter_response_run_bound: A common helper to trigger the run of a previ= ously + * initialized iterator, but only within the + * specified, optional, @start and @end resource + * indexes. Note that these bound-iterators need + * explicit cleanup via @iter_response_bound_cleanup. + * @iter_response_bound_cleanup: A common helper to finally release the it= erator + * for bound iterators. * @protocol_msg_check: A common helper to check is a specific protocol me= ssage * is supported. * @fastchannel_init: A common helper used to initialize FC descriptors by @@ -276,6 +284,9 @@ struct scmi_proto_helpers_ops { unsigned int max_resources, u8 msg_id, size_t tx_size, void *priv); int (*iter_response_run)(void *iter); + int (*iter_response_run_bound)(void *iter, + unsigned int *start, unsigned int *end); + void (*iter_response_cleanup)(void *iter); int (*protocol_msg_check)(const struct scmi_protocol_handle *ph, u32 message_id, u32 *attributes); void (*fastchannel_init)(const struct scmi_protocol_handle *ph, --=20 2.53.0