Lines Matching +full:p2a +full:- +full:control

1 // SPDX-License-Identifier: GPL-2.0
3 * System Control and Management Interface (SCMI) Message Mailbox Transport
6 * Copyright (C) 2019-2024 ARM Ltd.
20 * struct scmi_mailbox - Structure representing a SCMI mailbox transport
23 * @chan: Transmit/Receive mailbox uni/bi-directional channel
48 core->shmem->tx_prepare(smbox->shmem, m, smbox->cinfo); in tx_prepare()
61 * a previous timed-out reply which arrived late could be wrongly in rx_callback()
64 if (cl->knows_txdone && in rx_callback()
65 !core->shmem->channel_free(smbox->shmem)) { in rx_callback()
66 dev_warn(smbox->cinfo->dev, "Ignoring spurious A2P IRQ !\n"); in rx_callback()
67 core->bad_message_trace(smbox->cinfo, in rx_callback()
68 core->shmem->read_header(smbox->shmem), in rx_callback()
73 core->rx_callback(smbox->cinfo, in rx_callback()
74 core->shmem->read_header(smbox->shmem), NULL); in rx_callback()
86 num_mb = of_count_phandle_with_args(of_node, "mboxes", "#mbox-cells"); in mailbox_chan_available()
91 "#mbox-cells", idx, NULL); in mailbox_chan_available()
95 * mailbox_chan_validate - Validate transport configuration and map channels
101 * @p2a_chan: A reference to the optional p2a channel.
103 * @p2a_rx_chan: A reference to the optional p2a completion channel.
116 struct device_node *np = cdev->of_node; in mailbox_chan_validate()
118 num_mb = of_count_phandle_with_args(np, "mboxes", "#mbox-cells"); in mailbox_chan_validate()
127 "Invalid channel descriptor for '%s' - mbs:%d shm:%d\n", in mailbox_chan_validate()
129 return -EINVAL; in mailbox_chan_validate()
142 ret = -EINVAL; in mailbox_chan_validate()
184 struct device *cdev = cinfo->dev; in mailbox_chan_setup()
194 return -ENODEV; in mailbox_chan_setup()
198 return -ENOMEM; in mailbox_chan_setup()
200 smbox->shmem = core->shmem->setup_iomap(cinfo, dev, tx, NULL); in mailbox_chan_setup()
201 if (IS_ERR(smbox->shmem)) in mailbox_chan_setup()
202 return PTR_ERR(smbox->shmem); in mailbox_chan_setup()
204 cl = &smbox->cl; in mailbox_chan_setup()
205 cl->dev = cdev; in mailbox_chan_setup()
206 cl->tx_prepare = tx ? tx_prepare : NULL; in mailbox_chan_setup()
207 cl->rx_callback = rx_callback; in mailbox_chan_setup()
208 cl->tx_block = false; in mailbox_chan_setup()
209 cl->knows_txdone = tx; in mailbox_chan_setup()
211 smbox->chan = mbox_request_channel(cl, tx ? 0 : p2a_chan); in mailbox_chan_setup()
212 if (IS_ERR(smbox->chan)) { in mailbox_chan_setup()
213 ret = PTR_ERR(smbox->chan); in mailbox_chan_setup()
214 if (ret != -EPROBE_DEFER) in mailbox_chan_setup()
222 smbox->chan_receiver = mbox_request_channel(cl, a2p_rx_chan); in mailbox_chan_setup()
223 if (IS_ERR(smbox->chan_receiver)) { in mailbox_chan_setup()
224 ret = PTR_ERR(smbox->chan_receiver); in mailbox_chan_setup()
225 if (ret != -EPROBE_DEFER) in mailbox_chan_setup()
232 smbox->chan_platform_receiver = mbox_request_channel(cl, p2a_rx_chan); in mailbox_chan_setup()
233 if (IS_ERR(smbox->chan_platform_receiver)) { in mailbox_chan_setup()
234 ret = PTR_ERR(smbox->chan_platform_receiver); in mailbox_chan_setup()
235 if (ret != -EPROBE_DEFER) in mailbox_chan_setup()
236 dev_err(cdev, "failed to request SCMI P2A Receiver mailbox\n"); in mailbox_chan_setup()
241 cinfo->transport_info = smbox; in mailbox_chan_setup()
242 smbox->cinfo = cinfo; in mailbox_chan_setup()
243 mutex_init(&smbox->chan_lock); in mailbox_chan_setup()
251 struct scmi_mailbox *smbox = cinfo->transport_info; in mailbox_chan_free()
253 if (smbox && !IS_ERR(smbox->chan)) { in mailbox_chan_free()
254 mbox_free_channel(smbox->chan); in mailbox_chan_free()
255 mbox_free_channel(smbox->chan_receiver); in mailbox_chan_free()
256 mbox_free_channel(smbox->chan_platform_receiver); in mailbox_chan_free()
257 cinfo->transport_info = NULL; in mailbox_chan_free()
258 smbox->chan = NULL; in mailbox_chan_free()
259 smbox->chan_receiver = NULL; in mailbox_chan_free()
260 smbox->chan_platform_receiver = NULL; in mailbox_chan_free()
261 smbox->cinfo = NULL; in mailbox_chan_free()
270 struct scmi_mailbox *smbox = cinfo->transport_info; in mailbox_send_message()
280 mutex_lock(&smbox->chan_lock); in mailbox_send_message()
282 ret = mbox_send_message(smbox->chan, xfer); in mailbox_send_message()
283 /* mbox_send_message returns non-negative value on success */ in mailbox_send_message()
285 mutex_unlock(&smbox->chan_lock); in mailbox_send_message()
295 struct scmi_mailbox *smbox = cinfo->transport_info; in mailbox_mark_txdone()
297 mbox_client_txdone(smbox->chan, ret); in mailbox_mark_txdone()
300 mutex_unlock(&smbox->chan_lock); in mailbox_mark_txdone()
306 struct scmi_mailbox *smbox = cinfo->transport_info; in mailbox_fetch_response()
308 core->shmem->fetch_response(smbox->shmem, xfer); in mailbox_fetch_response()
314 struct scmi_mailbox *smbox = cinfo->transport_info; in mailbox_fetch_notification()
316 core->shmem->fetch_notification(smbox->shmem, max_len, xfer); in mailbox_fetch_notification()
321 struct scmi_mailbox *smbox = cinfo->transport_info; in mailbox_clear_channel()
325 core->shmem->clear_channel(smbox->shmem); in mailbox_clear_channel()
327 if (!core->shmem->channel_intr_enabled(smbox->shmem)) in mailbox_clear_channel()
330 if (smbox->chan_platform_receiver) in mailbox_clear_channel()
331 intr_chan = smbox->chan_platform_receiver; in mailbox_clear_channel()
332 else if (smbox->chan) in mailbox_clear_channel()
333 intr_chan = smbox->chan; in mailbox_clear_channel()
338 /* mbox_send_message returns non-negative value on success, so reset */ in mailbox_clear_channel()
348 struct scmi_mailbox *smbox = cinfo->transport_info; in mailbox_poll_done()
350 return core->shmem->poll_done(smbox->shmem, xfer); in mailbox_poll_done()