/* * Copyright 2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ #include #include "mailbox.h" LOG_MODULE_REGISTER(scmi_mbox); static void scmi_mbox_cb(const struct device *mbox, mbox_channel_id_t channel_id, void *user_data, struct mbox_msg *data) { struct scmi_channel *scmi_chan = user_data; if (scmi_chan->cb) { scmi_chan->cb(scmi_chan); } } static int scmi_mbox_send_message(const struct device *transport, struct scmi_channel *chan, struct scmi_message *msg) { struct scmi_mbox_channel *mbox_chan; int ret; mbox_chan = chan->data; ret = scmi_shmem_write_message(mbox_chan->shmem, msg); if (ret < 0) { LOG_ERR("failed to write message to shmem: %d", ret); return ret; } ret = mbox_send_dt(&mbox_chan->tx, NULL); if (ret < 0) { LOG_ERR("failed to ring doorbell: %d", ret); return ret; } return 0; } static int scmi_mbox_read_message(const struct device *transport, struct scmi_channel *chan, struct scmi_message *msg) { struct scmi_mbox_channel *mbox_chan; mbox_chan = chan->data; return scmi_shmem_read_message(mbox_chan->shmem, msg); } static bool scmi_mbox_channel_is_free(const struct device *transport, struct scmi_channel *chan) { struct scmi_mbox_channel *mbox_chan = chan->data; return scmi_shmem_channel_status(mbox_chan->shmem) & SCMI_SHMEM_CHAN_STATUS_BUSY_BIT; } static int scmi_mbox_setup_chan(const struct device *transport, struct scmi_channel *chan, bool tx) { int ret; struct scmi_mbox_channel *mbox_chan; struct mbox_dt_spec *tx_reply; mbox_chan = chan->data; if (!tx) { return -ENOTSUP; } if (mbox_chan->tx_reply.dev) { tx_reply = &mbox_chan->tx_reply; } else { tx_reply = &mbox_chan->tx; } ret = mbox_register_callback_dt(tx_reply, scmi_mbox_cb, chan); if (ret < 0) { LOG_ERR("failed to register tx reply cb"); return ret; } ret = mbox_set_enabled_dt(tx_reply, true); if (ret < 0) { LOG_ERR("failed to enable tx reply dbell"); } /* enable interrupt-based communication */ scmi_shmem_update_flags(mbox_chan->shmem, SCMI_SHMEM_CHAN_FLAG_IRQ_BIT, SCMI_SHMEM_CHAN_FLAG_IRQ_BIT); return 0; } static struct scmi_transport_api scmi_mbox_api = { .setup_chan = scmi_mbox_setup_chan, .send_message = scmi_mbox_send_message, .read_message = scmi_mbox_read_message, .channel_is_free = scmi_mbox_channel_is_free, }; DT_INST_SCMI_MAILBOX_DEFINE(0, PRE_KERNEL_1, CONFIG_ARM_SCMI_TRANSPORT_INIT_PRIORITY, &scmi_mbox_api);