Commit 4d09852b authored by Sudeep Holla's avatar Sudeep Holla

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/20200327143438.5382-5-cristian.marussi@arm.comReviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
[Reworked/renamed scmi_handle_xfer_delayed_resp()]
Signed-off-by: default avatarCristian Marussi <cristian.marussi@arm.com>
Signed-off-by: default avatarSudeep Holla <sudeep.holla@arm.com>
parent d5141f37
......@@ -202,29 +202,42 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
spin_unlock_irqrestore(&minfo->xfer_lock, flags);
}
/**
* scmi_rx_callback() - callback for receiving messages
*
* @cinfo: SCMI channel info
* @msg_hdr: Message header
*
* Processes one received message to appropriate transfer information and
* signals completion of the transfer.
*
* NOTE: This function will be invoked in IRQ context, hence should be
* as optimal as possible.
*/
void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
{
struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
struct scmi_xfers_info *minfo = &info->tx_minfo;
u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
struct device *dev = cinfo->dev;
struct scmi_xfer *xfer;
struct device *dev = cinfo->dev;
struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
struct scmi_xfers_info *minfo = &info->rx_minfo;
xfer = scmi_xfer_get(cinfo->handle, minfo);
if (IS_ERR(xfer)) {
dev_err(dev, "failed to get free message slot (%ld)\n",
PTR_ERR(xfer));
info->desc->ops->clear_notification(cinfo);
return;
}
unpack_scmi_header(msg_hdr, &xfer->hdr);
scmi_dump_header_dbg(dev, &xfer->hdr);
info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,
xfer);
trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
xfer->hdr.protocol_id, xfer->hdr.seq,
MSG_TYPE_NOTIFICATION);
if (msg_type == MSG_TYPE_NOTIFICATION)
return; /* Notifications not yet supported */
__scmi_xfer_put(minfo, xfer);
info->desc->ops->clear_notification(cinfo);
}
static void scmi_handle_response(struct scmi_chan_info *cinfo,
u16 xfer_id, u8 msg_type)
{
struct scmi_xfer *xfer;
struct device *dev = cinfo->dev;
struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
struct scmi_xfers_info *minfo = &info->tx_minfo;
/* Are we even expecting this? */
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)
complete(&xfer->done);
}
/**
* scmi_rx_callback() - callback for receiving messages
*
* @cinfo: SCMI channel info
* @msg_hdr: Message header
*
* Processes one received message to appropriate transfer information and
* signals completion of the transfer.
*
* NOTE: This function will be invoked in IRQ context, hence should be
* as optimal as possible.
*/
void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
{
u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
switch (msg_type) {
case MSG_TYPE_NOTIFICATION:
scmi_handle_notification(cinfo, msg_hdr);
break;
case MSG_TYPE_COMMAND:
case MSG_TYPE_DELAYED_RESP:
scmi_handle_response(cinfo, xfer_id, msg_type);
break;
default:
WARN_ONCE(1, "received unknown msg_type:%d\n", msg_type);
break;
}
}
/**
* scmi_xfer_put() - Release a transmit message
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment