1 // SPDX-License-Identifier: GPL-2.0
3 * System Control and Management Interface (SCMI) Message Mailbox Transport
6 * Copyright (C) 2019 ARM Ltd.
10 #include <linux/device.h>
11 #include <linux/mailbox_client.h>
13 #include <linux/of_address.h>
14 #include <linux/slab.h>
19 * struct scmi_mailbox - Structure representing a SCMI mailbox transport
22 * @chan: Transmit/Receive mailbox channel
23 * @cinfo: SCMI channel info
24 * @shmem: Transmit/Receive shared memory area
27 struct mbox_client cl
;
28 struct mbox_chan
*chan
;
29 struct scmi_chan_info
*cinfo
;
30 struct scmi_shared_mem __iomem
*shmem
;
33 #define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)
35 static void tx_prepare(struct mbox_client
*cl
, void *m
)
37 struct scmi_mailbox
*smbox
= client_to_scmi_mailbox(cl
);
39 shmem_tx_prepare(smbox
->shmem
, m
);
42 static void rx_callback(struct mbox_client
*cl
, void *m
)
44 struct scmi_mailbox
*smbox
= client_to_scmi_mailbox(cl
);
46 scmi_rx_callback(smbox
->cinfo
, shmem_read_header(smbox
->shmem
));
49 static bool mailbox_chan_available(struct device
*dev
, int idx
)
51 return !of_parse_phandle_with_args(dev
->of_node
, "mboxes",
52 "#mbox-cells", idx
, NULL
);
55 static int mailbox_chan_setup(struct scmi_chan_info
*cinfo
, struct device
*dev
,
58 const char *desc
= tx
? "Tx" : "Rx";
59 struct device
*cdev
= cinfo
->dev
;
60 struct scmi_mailbox
*smbox
;
61 struct device_node
*shmem
;
62 int ret
, idx
= tx
? 0 : 1;
63 struct mbox_client
*cl
;
67 smbox
= devm_kzalloc(dev
, sizeof(*smbox
), GFP_KERNEL
);
71 shmem
= of_parse_phandle(cdev
->of_node
, "shmem", idx
);
72 ret
= of_address_to_resource(shmem
, 0, &res
);
75 dev_err(cdev
, "failed to get SCMI %s shared memory\n", desc
);
79 size
= resource_size(&res
);
80 smbox
->shmem
= devm_ioremap(dev
, res
.start
, size
);
82 dev_err(dev
, "failed to ioremap SCMI %s shared memory\n", desc
);
83 return -EADDRNOTAVAIL
;
88 cl
->tx_prepare
= tx
? tx_prepare
: NULL
;
89 cl
->rx_callback
= rx_callback
;
91 cl
->knows_txdone
= tx
;
93 smbox
->chan
= mbox_request_channel(cl
, tx
? 0 : 1);
94 if (IS_ERR(smbox
->chan
)) {
95 ret
= PTR_ERR(smbox
->chan
);
96 if (ret
!= -EPROBE_DEFER
)
97 dev_err(cdev
, "failed to request SCMI %s mailbox\n",
102 cinfo
->transport_info
= smbox
;
103 smbox
->cinfo
= cinfo
;
108 static int mailbox_chan_free(int id
, void *p
, void *data
)
110 struct scmi_chan_info
*cinfo
= p
;
111 struct scmi_mailbox
*smbox
= cinfo
->transport_info
;
113 if (smbox
&& !IS_ERR(smbox
->chan
)) {
114 mbox_free_channel(smbox
->chan
);
115 cinfo
->transport_info
= NULL
;
120 scmi_free_channel(cinfo
, data
, id
);
125 static int mailbox_send_message(struct scmi_chan_info
*cinfo
,
126 struct scmi_xfer
*xfer
)
128 struct scmi_mailbox
*smbox
= cinfo
->transport_info
;
131 ret
= mbox_send_message(smbox
->chan
, xfer
);
133 /* mbox_send_message returns non-negative value on success, so reset */
140 static void mailbox_mark_txdone(struct scmi_chan_info
*cinfo
, int ret
)
142 struct scmi_mailbox
*smbox
= cinfo
->transport_info
;
145 * NOTE: we might prefer not to need the mailbox ticker to manage the
146 * transfer queueing since the protocol layer queues things by itself.
147 * Unfortunately, we have to kick the mailbox framework after we have
148 * received our message.
150 mbox_client_txdone(smbox
->chan
, ret
);
153 static void mailbox_fetch_response(struct scmi_chan_info
*cinfo
,
154 struct scmi_xfer
*xfer
)
156 struct scmi_mailbox
*smbox
= cinfo
->transport_info
;
158 shmem_fetch_response(smbox
->shmem
, xfer
);
161 static void mailbox_fetch_notification(struct scmi_chan_info
*cinfo
,
162 size_t max_len
, struct scmi_xfer
*xfer
)
164 struct scmi_mailbox
*smbox
= cinfo
->transport_info
;
166 shmem_fetch_notification(smbox
->shmem
, max_len
, xfer
);
169 static void mailbox_clear_channel(struct scmi_chan_info
*cinfo
)
171 struct scmi_mailbox
*smbox
= cinfo
->transport_info
;
173 shmem_clear_channel(smbox
->shmem
);
177 mailbox_poll_done(struct scmi_chan_info
*cinfo
, struct scmi_xfer
*xfer
)
179 struct scmi_mailbox
*smbox
= cinfo
->transport_info
;
181 return shmem_poll_done(smbox
->shmem
, xfer
);
184 static const struct scmi_transport_ops scmi_mailbox_ops
= {
185 .chan_available
= mailbox_chan_available
,
186 .chan_setup
= mailbox_chan_setup
,
187 .chan_free
= mailbox_chan_free
,
188 .send_message
= mailbox_send_message
,
189 .mark_txdone
= mailbox_mark_txdone
,
190 .fetch_response
= mailbox_fetch_response
,
191 .fetch_notification
= mailbox_fetch_notification
,
192 .clear_channel
= mailbox_clear_channel
,
193 .poll_done
= mailbox_poll_done
,
196 const struct scmi_desc scmi_mailbox_desc
= {
197 .ops
= &scmi_mailbox_ops
,
198 .max_rx_timeout_ms
= 30, /* We may increase this if required */
199 .max_msg
= 20, /* Limited by MBOX_TX_QUEUE_LEN */