git: e887179d4bc0 - main - scmi: Add helper to manipulate scmi_msg descriptors
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 23 Jan 2025 17:27:35 UTC
The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=e887179d4bc032e79d0334371d613c5841989a41 commit e887179d4bc032e79d0334371d613c5841989a41 Author: Cristian Marussi <cristian.marussi@arm.com> AuthorDate: 2025-01-23 13:23:28 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2025-01-23 17:26:26 +0000 scmi: Add helper to manipulate scmi_msg descriptors Refactor allocation logic for scmi_req and introduce new helpers to be able to obtain an scmi_msg reference to a freshly allocated request. Tested on: Arm Morello Board Reviewed by: andrew Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D47423 Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> --- sys/dev/firmware/arm/scmi.c | 77 +++++++++++++++++++++++++++++++++++---------- sys/dev/firmware/arm/scmi.h | 2 ++ 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/sys/dev/firmware/arm/scmi.c b/sys/dev/firmware/arm/scmi.c index cf5a678370fd..8104f4e10429 100644 --- a/sys/dev/firmware/arm/scmi.c +++ b/sys/dev/firmware/arm/scmi.c @@ -132,9 +132,10 @@ static int scmi_transport_init(struct scmi_softc *, phandle_t); static void scmi_transport_cleanup(struct scmi_softc *); static struct scmi_reqs_pool *scmi_reqs_pool_allocate(const int, const int); static void scmi_reqs_pool_free(struct scmi_reqs_pool *); -static struct scmi_req *scmi_req_alloc(struct scmi_softc *, enum scmi_chan); +static struct scmi_req *scmi_req_alloc(struct scmi_softc *, enum scmi_chan); +static struct scmi_req *scmi_req_initialized_alloc(device_t, int, int); static void scmi_req_free_unlocked(struct scmi_softc *, - enum scmi_chan, struct scmi_req *); + enum scmi_chan, struct scmi_req *); static void scmi_req_get(struct scmi_softc *, struct scmi_req *); static void scmi_req_put(struct scmi_softc *, struct scmi_req *); static int scmi_token_pick(struct scmi_softc *); @@ -319,6 +320,32 @@ scmi_transport_cleanup(struct scmi_softc *sc) free(sc->trs, M_DEVBUF); } +static struct scmi_req * +scmi_req_initialized_alloc(device_t dev, int tx_payld_sz, int rx_payld_sz) +{ + struct scmi_softc *sc; + struct scmi_req *req; + + sc = device_get_softc(dev); + + if (tx_payld_sz > SCMI_MAX_MSG_PAYLD_SIZE(sc) || + rx_payld_sz > SCMI_MAX_MSG_REPLY_SIZE(sc)) { + device_printf(dev, "Unsupported payload size. Drop.\n"); + return (NULL); + } + + /* Pick one from free list */ + req = scmi_req_alloc(sc, SCMI_CHAN_A2P); + if (req == NULL) + return (NULL); + + req->msg.tx_len = sizeof(req->msg.hdr) + tx_payld_sz; + req->msg.rx_len = rx_payld_sz ? + rx_payld_sz + 2 * sizeof(uint32_t) : SCMI_MAX_MSG_SIZE(sc); + + return (req); +} + static struct scmi_req * scmi_req_alloc(struct scmi_softc *sc, enum scmi_chan ch_idx) { @@ -374,6 +401,10 @@ scmi_req_put(struct scmi_softc *sc, struct scmi_req *req) { mtx_lock_spin(&req->mtx); if (!refcount_release_if_not_last(&req->cnt)) { + req->protocol_id = 0; + req->message_id = 0; + req->token = 0; + req->header = 0; bzero(&req->msg, sizeof(req->msg) + SCMI_MAX_MSG_PAYLD_SIZE(sc)); scmi_req_free_unlocked(sc, SCMI_CHAN_A2P, req); } @@ -604,27 +635,15 @@ void * scmi_buf_get(device_t dev, uint8_t protocol_id, uint8_t message_id, int tx_payld_sz, int rx_payld_sz) { - struct scmi_softc *sc; struct scmi_req *req; - sc = device_get_softc(dev); - - if (tx_payld_sz > SCMI_MAX_MSG_PAYLD_SIZE(sc) || - rx_payld_sz > SCMI_MAX_MSG_REPLY_SIZE(sc)) { - device_printf(dev, "Unsupported payload size. Drop.\n"); - return (NULL); - } - - /* Pick one from free list */ - req = scmi_req_alloc(sc, SCMI_CHAN_A2P); + /* Pick a pre-built req */ + req = scmi_req_initialized_alloc(dev, tx_payld_sz, rx_payld_sz); if (req == NULL) return (NULL); req->protocol_id = protocol_id & SCMI_HDR_PROTOCOL_ID_BF; req->message_id = message_id & SCMI_HDR_MESSAGE_ID_BF; - req->msg.tx_len = sizeof(req->msg.hdr) + tx_payld_sz; - req->msg.rx_len = rx_payld_sz ? - rx_payld_sz + 2 * sizeof(uint32_t) : SCMI_MAX_MSG_SIZE(sc); return (&req->msg.payld[0]); } @@ -641,6 +660,32 @@ scmi_buf_put(device_t dev, void *buf) scmi_req_put(sc, req); } +struct scmi_msg * +scmi_msg_get(device_t dev, int tx_payld_sz, int rx_payld_sz) +{ + struct scmi_req *req; + + /* Pick a pre-built req */ + req = scmi_req_initialized_alloc(dev, tx_payld_sz, rx_payld_sz); + if (req == NULL) + return (NULL); + + return (&req->msg); +} + +void +scmi_msg_put(device_t dev, struct scmi_msg *msg) +{ + struct scmi_softc *sc; + struct scmi_req *req; + + sc = device_get_softc(dev); + + req = msg_to_req(msg); + + scmi_req_put(sc, req); +} + int scmi_request(device_t dev, void *in, void **out) { diff --git a/sys/dev/firmware/arm/scmi.h b/sys/dev/firmware/arm/scmi.h index 135b49c3b05b..f6aa072caeca 100644 --- a/sys/dev/firmware/arm/scmi.h +++ b/sys/dev/firmware/arm/scmi.h @@ -80,6 +80,8 @@ struct scmi_msg { void *scmi_buf_get(device_t dev, uint8_t protocol_id, uint8_t message_id, int tx_payd_sz, int rx_payld_sz); void scmi_buf_put(device_t dev, void *buf); +struct scmi_msg *scmi_msg_get(device_t dev, int tx_payld_sz, int rx_payld_sz); +void scmi_msg_put(device_t dev, struct scmi_msg *msg); int scmi_request(device_t dev, void *in, void **); void scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr, uint32_t rx_len);