memcpy_fromio(xfer->rx.buf, mem->msg_payload + 4, xfer->rx.len);
}
-/**
- * scmi_rx_callback() - mailbox client callback for receive messages
- *
- * @cl: client pointer
- * @m: mailbox message
- *
- * 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.
- */
-static void scmi_rx_callback(struct mbox_client *cl, void *m)
-{
- u16 xfer_id;
- struct scmi_xfer *xfer;
- struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
- struct device *dev = cinfo->dev;
- struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
- struct scmi_xfers_info *minfo = &info->minfo;
- struct scmi_shared_mem __iomem *mem = cinfo->payload;
-
- xfer_id = MSG_XTRACT_TOKEN(ioread32(&mem->msg_header));
-
- /* Are we even expecting this? */
- if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
- dev_err(dev, "message for %d is not expected!\n", xfer_id);
- return;
- }
-
- xfer = &minfo->xfer_block[xfer_id];
-
- scmi_dump_header_dbg(dev, &xfer->hdr);
-
- scmi_fetch_response(xfer, mem);
- complete(&xfer->done);
-}
-
/**
* pack_scmi_header() - packs and returns 32-bit header
*
spin_unlock_irqrestore(&minfo->xfer_lock, flags);
}
+/**
+ * scmi_rx_callback() - mailbox client callback for receive messages
+ *
+ * @cl: client pointer
+ * @m: mailbox message
+ *
+ * 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.
+ */
+static void scmi_rx_callback(struct mbox_client *cl, void *m)
+{
+ u16 xfer_id;
+ struct scmi_xfer *xfer;
+ struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
+ struct device *dev = cinfo->dev;
+ struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
+ struct scmi_xfers_info *minfo = &info->minfo;
+ struct scmi_shared_mem __iomem *mem = cinfo->payload;
+
+ xfer_id = MSG_XTRACT_TOKEN(ioread32(&mem->msg_header));
+
+ /* Are we even expecting this? */
+ if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
+ dev_err(dev, "message for %d is not expected!\n", xfer_id);
+ return;
+ }
+
+ xfer = &minfo->xfer_block[xfer_id];
+
+ scmi_dump_header_dbg(dev, &xfer->hdr);
+
+ scmi_fetch_response(xfer, mem);
+ complete(&xfer->done);
+}
+
static bool
scmi_xfer_poll_done(const struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
{
return 0;
}
-static const struct scmi_desc scmi_generic_desc = {
- .max_rx_timeout_ms = 30, /* We may increase this if required */
- .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */
- .max_msg_size = 128,
-};
-
-/* Each compatible listed below must have descriptor associated with it */
-static const struct of_device_id scmi_of_match[] = {
- { .compatible = "arm,scmi", .data = &scmi_generic_desc },
- { /* Sentinel */ },
-};
-
-MODULE_DEVICE_TABLE(of, scmi_of_match);
-
static int scmi_xfer_info_init(struct scmi_info *sinfo)
{
int i;
return of_parse_phandle_with_args(np, "mboxes", "#mbox-cells", 0, NULL);
}
-static int scmi_mbox_free_channel(int id, void *p, void *data)
-{
- struct scmi_chan_info *cinfo = p;
- struct idr *idr = data;
-
- if (!IS_ERR_OR_NULL(cinfo->chan)) {
- mbox_free_channel(cinfo->chan);
- cinfo->chan = NULL;
- }
-
- idr_remove(idr, id);
-
- return 0;
-}
-
-static int scmi_remove(struct platform_device *pdev)
-{
- int ret = 0;
- struct scmi_info *info = platform_get_drvdata(pdev);
- struct idr *idr = &info->tx_idr;
-
- mutex_lock(&scmi_list_mutex);
- if (info->users)
- ret = -EBUSY;
- else
- list_del(&info->node);
- mutex_unlock(&scmi_list_mutex);
-
- if (ret)
- return ret;
-
- /* Safe to free channels since no more users */
- ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
- idr_destroy(&info->tx_idr);
-
- return ret;
-}
-
static inline int
scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, int prot_id)
{
return 0;
}
+static int scmi_mbox_free_channel(int id, void *p, void *data)
+{
+ struct scmi_chan_info *cinfo = p;
+ struct idr *idr = data;
+
+ if (!IS_ERR_OR_NULL(cinfo->chan)) {
+ mbox_free_channel(cinfo->chan);
+ cinfo->chan = NULL;
+ }
+
+ idr_remove(idr, id);
+
+ return 0;
+}
+
+static int scmi_remove(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct scmi_info *info = platform_get_drvdata(pdev);
+ struct idr *idr = &info->tx_idr;
+
+ mutex_lock(&scmi_list_mutex);
+ if (info->users)
+ ret = -EBUSY;
+ else
+ list_del(&info->node);
+ mutex_unlock(&scmi_list_mutex);
+
+ if (ret)
+ return ret;
+
+ /* Safe to free channels since no more users */
+ ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
+ idr_destroy(&info->tx_idr);
+
+ return ret;
+}
+
+static const struct scmi_desc scmi_generic_desc = {
+ .max_rx_timeout_ms = 30, /* We may increase this if required */
+ .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */
+ .max_msg_size = 128,
+};
+
+/* Each compatible listed below must have descriptor associated with it */
+static const struct of_device_id scmi_of_match[] = {
+ { .compatible = "arm,scmi", .data = &scmi_generic_desc },
+ { /* Sentinel */ },
+};
+
+MODULE_DEVICE_TABLE(of, scmi_of_match);
+
static struct platform_driver scmi_driver = {
.driver = {
.name = "arm-scmi",