Skip to content

Commit 4d09852

Browse files
committed
firmware: arm_scmi: Add support for notifications message processing
Add the mechanisms to distinguish notifications from delayed responses and command responses. Also add support to properly fetch notification messages upon reception. Notifications processing does not continue any further after the fetch phase. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Jonathan Cameron <[email protected]> [Reworked/renamed scmi_handle_xfer_delayed_resp()] Signed-off-by: Cristian Marussi <[email protected]> Signed-off-by: Sudeep Holla <[email protected]>
1 parent d5141f3 commit 4d09852

File tree

1 file changed

+64
-20
lines changed

1 file changed

+64
-20
lines changed

drivers/firmware/arm_scmi/driver.c

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -202,29 +202,42 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
202202
spin_unlock_irqrestore(&minfo->xfer_lock, flags);
203203
}
204204

205-
/**
206-
* scmi_rx_callback() - callback for receiving messages
207-
*
208-
* @cinfo: SCMI channel info
209-
* @msg_hdr: Message header
210-
*
211-
* Processes one received message to appropriate transfer information and
212-
* signals completion of the transfer.
213-
*
214-
* NOTE: This function will be invoked in IRQ context, hence should be
215-
* as optimal as possible.
216-
*/
217-
void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
205+
static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
218206
{
219-
struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
220-
struct scmi_xfers_info *minfo = &info->tx_minfo;
221-
u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
222-
u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
223-
struct device *dev = cinfo->dev;
224207
struct scmi_xfer *xfer;
208+
struct device *dev = cinfo->dev;
209+
struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
210+
struct scmi_xfers_info *minfo = &info->rx_minfo;
211+
212+
xfer = scmi_xfer_get(cinfo->handle, minfo);
213+
if (IS_ERR(xfer)) {
214+
dev_err(dev, "failed to get free message slot (%ld)\n",
215+
PTR_ERR(xfer));
216+
info->desc->ops->clear_notification(cinfo);
217+
return;
218+
}
219+
220+
unpack_scmi_header(msg_hdr, &xfer->hdr);
221+
scmi_dump_header_dbg(dev, &xfer->hdr);
222+
info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,
223+
xfer);
224+
225+
trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
226+
xfer->hdr.protocol_id, xfer->hdr.seq,
227+
MSG_TYPE_NOTIFICATION);
225228

226-
if (msg_type == MSG_TYPE_NOTIFICATION)
227-
return; /* Notifications not yet supported */
229+
__scmi_xfer_put(minfo, xfer);
230+
231+
info->desc->ops->clear_notification(cinfo);
232+
}
233+
234+
static void scmi_handle_response(struct scmi_chan_info *cinfo,
235+
u16 xfer_id, u8 msg_type)
236+
{
237+
struct scmi_xfer *xfer;
238+
struct device *dev = cinfo->dev;
239+
struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
240+
struct scmi_xfers_info *minfo = &info->tx_minfo;
228241

229242
/* Are we even expecting this? */
230243
if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
@@ -248,6 +261,37 @@ void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
248261
complete(&xfer->done);
249262
}
250263

264+
/**
265+
* scmi_rx_callback() - callback for receiving messages
266+
*
267+
* @cinfo: SCMI channel info
268+
* @msg_hdr: Message header
269+
*
270+
* Processes one received message to appropriate transfer information and
271+
* signals completion of the transfer.
272+
*
273+
* NOTE: This function will be invoked in IRQ context, hence should be
274+
* as optimal as possible.
275+
*/
276+
void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
277+
{
278+
u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
279+
u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
280+
281+
switch (msg_type) {
282+
case MSG_TYPE_NOTIFICATION:
283+
scmi_handle_notification(cinfo, msg_hdr);
284+
break;
285+
case MSG_TYPE_COMMAND:
286+
case MSG_TYPE_DELAYED_RESP:
287+
scmi_handle_response(cinfo, xfer_id, msg_type);
288+
break;
289+
default:
290+
WARN_ONCE(1, "received unknown msg_type:%d\n", msg_type);
291+
break;
292+
}
293+
}
294+
251295
/**
252296
* scmi_xfer_put() - Release a transmit message
253297
*

0 commit comments

Comments
 (0)