History

Merge tag 'scmi-updates-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/drivers

ARM SCMI/SCPI updates for v5.7 1. Abstraction of the scmi transport type from the core protocol driver which enables addition of other transports like SMC/HVC, SPCI and virtio apart from the existing mailbox 2. Miscellaneous fix for minor formatting issues with the kernel-doc style comments 3. Replacement of zero-length array with flexible-array member which is part of tree-wide cleanup * tag 'scmi-updates-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: misc: vexpress: Replace zero-length array with flexible-array member firmware: arm_scpi: Replace zero-length array with flexible-array member firmware: arm_scmi/perf: Replace zero-length array with flexible-array member firmware: arm_scmi: Replace zero-length array with flexible-array member firmware: arm_scmi: Make scmi core independent of the transport type firmware: arm_scmi: Move macros and helpers to common.h firmware: arm_scmi: Update doc style comments

Arnd Bergmann committed 6 years ago

Commit cedb4142 parents 021249e 57c45d48 files · +420 −266Browse files

Unified · Split

8 files
  1. drivers/firmware/arm_scmi/Makefile +2 −1
  2. drivers/firmware/arm_scmi/common.h +113 −2
  3. drivers/firmware/arm_scmi/driver.c +34 −259
  4. drivers/firmware/arm_scmi/mailbox.c +184 −0
  5. drivers/firmware/arm_scmi/perf.c +1 −1
  6. drivers/firmware/arm_scmi/shmem.c +83 −0
  7. drivers/firmware/arm_scpi.c +2 −2
  8. drivers/misc/vexpress-syscfg.c +1 −1
drivers/firmware/arm_scmi/Makefile+2−1
@@ -1,6 +1,7 @@
11 # SPDX-License-Identifier: GPL-2.0-only
2−obj-y = scmi-bus.o scmi-driver.o scmi-protocols.o
2+obj-y = scmi-bus.o scmi-driver.o scmi-protocols.o scmi-transport.o
33 scmi-bus-y = bus.o
44 scmi-driver-y = driver.o
5+scmi-transport-y = mailbox.o shmem.o
56 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o
67 obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
drivers/firmware/arm_scmi/common.h+113−2
@@ -33,8 +33,8 @@ enum scmi_common_cmd { · 32 unmodified lines
3333 /**
3434 * struct scmi_msg_resp_prot_version - Response for a message
3535 *
36− * @major_version: Major version of the ABI that firmware supports
3736 * @minor_version: Minor version of the ABI that firmware supports
37+ * @major_version: Major version of the ABI that firmware supports
3838 *
3939 * In general, ABI version changes follow the rule that minor version increments
4040 * are backward compatible. Major revision changes in ABI may not be
@@ -47,6 +47,19 @@ struct scmi_msg_resp_prot_version { · 6 unmodified lines
4747 __le16 major_version;
4848 };
4949
50+#define MSG_ID_MASK GENMASK(7, 0)
51+#define MSG_XTRACT_ID(hdr) FIELD_GET(MSG_ID_MASK, (hdr))
52+#define MSG_TYPE_MASK GENMASK(9, 8)
53+#define MSG_XTRACT_TYPE(hdr) FIELD_GET(MSG_TYPE_MASK, (hdr))
54+#define MSG_TYPE_COMMAND 0
55+#define MSG_TYPE_DELAYED_RESP 2
56+#define MSG_TYPE_NOTIFICATION 3
57+#define MSG_PROTOCOL_ID_MASK GENMASK(17, 10)
58+#define MSG_XTRACT_PROT_ID(hdr) FIELD_GET(MSG_PROTOCOL_ID_MASK, (hdr))
59+#define MSG_TOKEN_ID_MASK GENMASK(27, 18)
60+#define MSG_XTRACT_TOKEN(hdr) FIELD_GET(MSG_TOKEN_ID_MASK, (hdr))
61+#define MSG_TOKEN_MAX (MSG_XTRACT_TOKEN(MSG_TOKEN_ID_MASK) + 1)
62+
5063 /**
5164 * struct scmi_msg_hdr - Message(Tx/Rx) header
5265 *
@@ -67,6 +80,33 @@ struct scmi_msg_hdr { · 14 unmodified lines
6780 bool poll_completion;
6881 };
6982
83+/**
84+ * pack_scmi_header() - packs and returns 32-bit header
85+ *
86+ * @hdr: pointer to header containing all the information on message id,
87+ * protocol id and sequence id.
88+ *
89+ * Return: 32-bit packed message header to be sent to the platform.
90+ */
91+static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr)
92+{
93+ return FIELD_PREP(MSG_ID_MASK, hdr->id) |
94+ FIELD_PREP(MSG_TOKEN_ID_MASK, hdr->seq) |
95+ FIELD_PREP(MSG_PROTOCOL_ID_MASK, hdr->protocol_id);
96+}
97+
98+/**
99+ * unpack_scmi_header() - unpacks and records message and protocol id
100+ *
101+ * @msg_hdr: 32-bit packed message header sent from the platform
102+ * @hdr: pointer to header to fetch message and protocol id.
103+ */
104+static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr)
105+{
106+ hdr->id = MSG_XTRACT_ID(msg_hdr);
107+ hdr->protocol_id = MSG_XTRACT_PROT_ID(msg_hdr);
108+}
109+
70110 /**
71111 * struct scmi_msg - Message(Tx/Rx) structure
72112 *
@@ -88,7 +128,7 @@ struct scmi_msg { · 15 unmodified lines
88128 * message. If request-ACK protocol is used, we can reuse the same
89129 * buffer for the rx path as we use for the tx path.
90130 * @done: command message transmit completion event
91− * @async: pointer to delayed response message received event completion
131+ * @async_done: pointer to delayed response message received event completion
92132 */
93133 struct scmi_xfer {
94134 int transfer_id;
@@ -113,3 +153,74 @@ void scmi_setup_protocol_implemented(const struct scmi_handle *handle, · 18 unmodified lines
113153 u8 *prot_imp);
114154
115155 int scmi_base_protocol_init(struct scmi_handle *h);
156+
157+/* SCMI Transport */
158+/**
159+ * struct scmi_chan_info - Structure representing a SCMI channel information
160+ *
161+ * @dev: Reference to device in the SCMI hierarchy corresponding to this
162+ * channel
163+ * @handle: Pointer to SCMI entity handle
164+ * @transport_info: Transport layer related information
165+ */
166+struct scmi_chan_info {
167+ struct device *dev;
168+ struct scmi_handle *handle;
169+ void *transport_info;
170+};
171+
172+/**
173+ * struct scmi_transport_ops - Structure representing a SCMI transport ops
174+ *
175+ * @chan_available: Callback to check if channel is available or not
176+ * @chan_setup: Callback to allocate and setup a channel
177+ * @chan_free: Callback to free a channel
178+ * @send_message: Callback to send a message
179+ * @mark_txdone: Callback to mark tx as done
180+ * @fetch_response: Callback to fetch response
181+ * @poll_done: Callback to poll transfer status
182+ */
183+struct scmi_transport_ops {
184+ bool (*chan_available)(struct device *dev, int idx);
185+ int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev,
186+ bool tx);
187+ int (*chan_free)(int id, void *p, void *data);
188+ int (*send_message)(struct scmi_chan_info *cinfo,
189+ struct scmi_xfer *xfer);
190+ void (*mark_txdone)(struct scmi_chan_info *cinfo, int ret);
191+ void (*fetch_response)(struct scmi_chan_info *cinfo,
192+ struct scmi_xfer *xfer);
193+ bool (*poll_done)(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer);
194+};
195+
196+/**
197+ * struct scmi_desc - Description of SoC integration
198+ *
199+ * @ops: Pointer to the transport specific ops structure
200+ * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
201+ * @max_msg: Maximum number of messages that can be pending
202+ * simultaneously in the system
203+ * @max_msg_size: Maximum size of data per message that can be handled.
204+ */
205+struct scmi_desc {
206+ struct scmi_transport_ops *ops;
207+ int max_rx_timeout_ms;
208+ int max_msg;
209+ int max_msg_size;
210+};
211+
212+extern const struct scmi_desc scmi_mailbox_desc;
213+
214+void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr);
215+void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
216+
217+/* shmem related declarations */
218+struct scmi_shared_mem;
219+
220+void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
221+ struct scmi_xfer *xfer);
222+u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem);
223+void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
224+ struct scmi_xfer *xfer);
225+bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
226+ struct scmi_xfer *xfer);
drivers/firmware/arm_scmi/driver.c+34−259
@@ -19,12 +19,10 @@ · 18 unmodified lines
1919 #include <linux/io.h>
2020 #include <linux/kernel.h>
2121 #include <linux/ktime.h>
22−#include <linux/mailbox_client.h>
2322 #include <linux/module.h>
2423 #include <linux/of_address.h>
2524 #include <linux/of_device.h>
2625 #include <linux/processor.h>
27−#include <linux/semaphore.h>
2826 #include <linux/slab.h>
2927
3028 #include "common.h"
@@ -32,19 +30,6 @@ · 1 unmodified line
3230 #define CREATE_TRACE_POINTS
3331 #include <trace/events/scmi.h>
3432
35−#define MSG_ID_MASK GENMASK(7, 0)
36−#define MSG_XTRACT_ID(hdr) FIELD_GET(MSG_ID_MASK, (hdr))
37−#define MSG_TYPE_MASK GENMASK(9, 8)
38−#define MSG_XTRACT_TYPE(hdr) FIELD_GET(MSG_TYPE_MASK, (hdr))
39−#define MSG_TYPE_COMMAND 0
40−#define MSG_TYPE_DELAYED_RESP 2
41−#define MSG_TYPE_NOTIFICATION 3
42−#define MSG_PROTOCOL_ID_MASK GENMASK(17, 10)
43−#define MSG_XTRACT_PROT_ID(hdr) FIELD_GET(MSG_PROTOCOL_ID_MASK, (hdr))
44−#define MSG_TOKEN_ID_MASK GENMASK(27, 18)
45−#define MSG_XTRACT_TOKEN(hdr) FIELD_GET(MSG_TOKEN_ID_MASK, (hdr))
46−#define MSG_TOKEN_MAX (MSG_XTRACT_TOKEN(MSG_TOKEN_ID_MASK) + 1)
47−
4833 enum scmi_error_codes {
4934 SCMI_SUCCESS = 0, /* Success */
5035 SCMI_ERR_SUPPORT = -1, /* Not supported */
@@ -82,46 +67,14 @@ struct scmi_xfers_info { · 31 unmodified lines
8267 spinlock_t xfer_lock;
8368 };
8469
85−/**
86− * struct scmi_desc - Description of SoC integration
87− *
88− * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
89− * @max_msg: Maximum number of messages that can be pending
90− * simultaneously in the system
91− * @max_msg_size: Maximum size of data per message that can be handled.
92− */
93−struct scmi_desc {
94− int max_rx_timeout_ms;
95− int max_msg;
96− int max_msg_size;
97−};
98−
99−/**
100− * struct scmi_chan_info - Structure representing a SCMI channel information
101− *
102− * @cl: Mailbox Client
103− * @chan: Transmit/Receive mailbox channel
104− * @payload: Transmit/Receive mailbox channel payload area
105− * @dev: Reference to device in the SCMI hierarchy corresponding to this
106− * channel
107− * @handle: Pointer to SCMI entity handle
108− */
109−struct scmi_chan_info {
110− struct mbox_client cl;
111− struct mbox_chan *chan;
112− void __iomem *payload;
113− struct device *dev;
114− struct scmi_handle *handle;
115−};
116−
11770 /**
11871 * struct scmi_info - Structure representing a SCMI instance
11972 *
12073 * @dev: Device pointer
12174 * @desc: SoC description for this instance
122− * @handle: Instance of SCMI handle to send to clients
12375 * @version: SCMI revision information containing protocol version,
12476 * implementation version and (sub-)vendor identification.
77+ * @handle: Instance of SCMI handle to send to clients
12578 * @tx_minfo: Universal Transmit Message management info
12679 * @tx_idr: IDR object to map protocol id to Tx channel info pointer
12780 * @rx_idr: IDR object to map protocol id to Rx channel info pointer
@@ -143,27 +96,8 @@ struct scmi_info { · 15 unmodified lines
14396 int users;
14497 };
14598
146−#define client_to_scmi_chan_info(c) container_of(c, struct scmi_chan_info, cl)
14799 #define handle_to_scmi_info(h) container_of(h, struct scmi_info, handle)
148100
149−/*
150− * SCMI specification requires all parameters, message headers, return
151− * arguments or any protocol data to be expressed in little endian
152− * format only.
153− */
154−struct scmi_shared_mem {
155− __le32 reserved;
156− __le32 channel_status;
157−#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR BIT(1)
158−#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE BIT(0)
159− __le32 reserved1[2];
160− __le32 flags;
161−#define SCMI_SHMEM_FLAG_INTR_ENABLED BIT(0)
162− __le32 length;
163− __le32 msg_header;
164− u8 msg_payload[0];
165−};
166−
167101 static const int scmi_linux_errmap[] = {
168102 /* better than switch case as long as return value is continuous */
169103 0, /* SCMI_SUCCESS */
@@ -199,77 +133,6 @@ static inline void scmi_dump_header_dbg(struct device *dev, · 29 unmodified lines
199133 hdr->id, hdr->seq, hdr->protocol_id);
200134 }
201135
202−static void scmi_fetch_response(struct scmi_xfer *xfer,
203− struct scmi_shared_mem __iomem *mem)
204−{
205− xfer->hdr.status = ioread32(mem->msg_payload);
206− /* Skip the length of header and status in payload area i.e 8 bytes */
207− xfer->rx.len = min_t(size_t, xfer->rx.len, ioread32(&mem->length) - 8);
208−
209− /* Take a copy to the rx buffer.. */
210− memcpy_fromio(xfer->rx.buf, mem->msg_payload + 4, xfer->rx.len);
211−}
212−
213−/**
214− * pack_scmi_header() - packs and returns 32-bit header
215− *
216− * @hdr: pointer to header containing all the information on message id,
217− * protocol id and sequence id.
218− *
219− * Return: 32-bit packed message header to be sent to the platform.
220− */
221−static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr)
222−{
223− return FIELD_PREP(MSG_ID_MASK, hdr->id) |
224− FIELD_PREP(MSG_TOKEN_ID_MASK, hdr->seq) |
225− FIELD_PREP(MSG_PROTOCOL_ID_MASK, hdr->protocol_id);
226−}
227−
228−/**
229− * unpack_scmi_header() - unpacks and records message and protocol id
230− *
231− * @msg_hdr: 32-bit packed message header sent from the platform
232− * @hdr: pointer to header to fetch message and protocol id.
233− */
234−static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr)
235−{
236− hdr->id = MSG_XTRACT_ID(msg_hdr);
237− hdr->protocol_id = MSG_XTRACT_PROT_ID(msg_hdr);
238−}
239−
240−/**
241− * scmi_tx_prepare() - mailbox client callback to prepare for the transfer
242− *
243− * @cl: client pointer
244− * @m: mailbox message
245− *
246− * This function prepares the shared memory which contains the header and the
247− * payload.
248− */
249−static void scmi_tx_prepare(struct mbox_client *cl, void *m)
250−{
251− struct scmi_xfer *t = m;
252− struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
253− struct scmi_shared_mem __iomem *mem = cinfo->payload;
254−
255− /*
256− * Ideally channel must be free by now unless OS timeout last
257− * request and platform continued to process the same, wait
258− * until it releases the shared memory, otherwise we may endup
259− * overwriting its response with new message payload or vice-versa
260− */
261− spin_until_cond(ioread32(&mem->channel_status) &
262− SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
263− /* Mark channel busy + clear error */
264− iowrite32(0x0, &mem->channel_status);
265− iowrite32(t->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED,
266− &mem->flags);
267− iowrite32(sizeof(mem->msg_header) + t->tx.len, &mem->length);
268− iowrite32(pack_scmi_header(&t->hdr), &mem->msg_header);
269− if (t->tx.buf)
270− memcpy_toio(mem->msg_payload, t->tx.buf, t->tx.len);
271−}
272−
273136 /**
274137 * scmi_xfer_get() - Allocate one message
275138 *
@@ -338,10 +201,10 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) · 62 unmodified lines
338201 }
339202
340203 /**
341− * scmi_rx_callback() - mailbox client callback for receive messages
204+ * scmi_rx_callback() - callback for receiving messages
342205 *
343− * @cl: client pointer
344− * @m: mailbox message
206+ * @cinfo: SCMI channel info
207+ * @msg_hdr: Message header
345208 *
346209 * Processes one received message to appropriate transfer information and
347210 * signals completion of the transfer.
@@ -349,21 +212,14 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) · 1 unmodified line
349212 * NOTE: This function will be invoked in IRQ context, hence should be
350213 * as optimal as possible.
351214 */
352−static void scmi_rx_callback(struct mbox_client *cl, void *m)
215+void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
353216 {
354− u8 msg_type;
355− u32 msg_hdr;
356− u16 xfer_id;
357− struct scmi_xfer *xfer;
358− struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
359− struct device *dev = cinfo->dev;
360217 struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
361218 struct scmi_xfers_info *minfo = &info->tx_minfo;
362− struct scmi_shared_mem __iomem *mem = cinfo->payload;
363−
364− msg_hdr = ioread32(&mem->msg_header);
365− msg_type = MSG_XTRACT_TYPE(msg_hdr);
366− xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
219+ u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
220+ u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
221+ struct device *dev = cinfo->dev;
222+ struct scmi_xfer *xfer;
367223
368224 if (msg_type == MSG_TYPE_NOTIFICATION)
369225 return; /* Notifications not yet supported */
@@ -378,7 +234,7 @@ static void scmi_rx_callback(struct mbox_client *cl, void *m) · 8 unmodified lines
378234
379235 scmi_dump_header_dbg(dev, &xfer->hdr);
380236
381− scmi_fetch_response(xfer, mem);
237+ info->desc->ops->fetch_response(cinfo, xfer);
382238
383239 trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
384240 xfer->hdr.protocol_id, xfer->hdr.seq,
@@ -403,28 +259,15 @@ void scmi_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer) · 18 unmodified lines
403259 __scmi_xfer_put(&info->tx_minfo, xfer);
404260 }
405261
406−static bool
407−scmi_xfer_poll_done(const struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
408−{
409− struct scmi_shared_mem __iomem *mem = cinfo->payload;
410− u16 xfer_id = MSG_XTRACT_TOKEN(ioread32(&mem->msg_header));
411−
412− if (xfer->hdr.seq != xfer_id)
413− return false;
414−
415− return ioread32(&mem->channel_status) &
416− (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR |
417− SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
418−}
419−
420262 #define SCMI_MAX_POLL_TO_NS (100 * NSEC_PER_USEC)
421263
422−static bool scmi_xfer_done_no_timeout(const struct scmi_chan_info *cinfo,
264+static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
423265 struct scmi_xfer *xfer, ktime_t stop)
424266 {
425− ktime_t __cur = ktime_get();
267+ struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
426268
427− return scmi_xfer_poll_done(cinfo, xfer) || ktime_after(__cur, stop);
269+ return info->desc->ops->poll_done(cinfo, xfer) ||
270+ ktime_after(ktime_get(), stop);
428271 }
429272
430273 /**
@@ -453,29 +296,26 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer) · 22 unmodified lines
453296 xfer->hdr.protocol_id, xfer->hdr.seq,
454297 xfer->hdr.poll_completion);
455298
456− ret = mbox_send_message(cinfo->chan, xfer);
299+ ret = info->desc->ops->send_message(cinfo, xfer);
457300 if (ret < 0) {
458− dev_dbg(dev, "mbox send fail %d\n", ret);
301+ dev_dbg(dev, "Failed to send message %d\n", ret);
459302 return ret;
460303 }
461304
462− /* mbox_send_message returns non-negative value on success, so reset */
463− ret = 0;
464−
465305 if (xfer->hdr.poll_completion) {
466306 ktime_t stop = ktime_add_ns(ktime_get(), SCMI_MAX_POLL_TO_NS);
467307
468308 spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
469309
470310 if (ktime_before(ktime_get(), stop))
471− scmi_fetch_response(xfer, cinfo->payload);
311+ info->desc->ops->fetch_response(cinfo, xfer);
472312 else
473313 ret = -ETIMEDOUT;
474314 } else {
475315 /* And we wait for the response. */
476316 timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
477317 if (!wait_for_completion_timeout(&xfer->done, timeout)) {
478− dev_err(dev, "mbox timed out in resp(caller: %pS)\n",
318+ dev_err(dev, "timed out in resp(caller: %pS)\n",
479319 (void *)_RET_IP_);
480320 ret = -ETIMEDOUT;
481321 }
@@ -484,13 +324,8 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer) · 2 unmodified lines
484324 if (!ret && xfer->hdr.status)
485325 ret = scmi_to_linux_errno(xfer->hdr.status);
486326
487− /*
488− * NOTE: we might prefer not to need the mailbox ticker to manage the
489− * transfer queueing since the protocol layer queues things by itself.
490− * Unfortunately, we have to kick the mailbox framework after we have
491− * received our message.
492− */
493− mbox_client_txdone(cinfo->chan, ret);
327+ if (info->desc->ops->mark_txdone)
328+ info->desc->ops->mark_txdone(cinfo, ret);
494329
495330 trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
496331 xfer->hdr.protocol_id, xfer->hdr.seq,
@@ -731,23 +566,12 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo) · 234 unmodified lines
731566 return 0;
732567 }
733568
734−static int scmi_mailbox_check(struct device_node *np, int idx)
735−{
736− return of_parse_phandle_with_args(np, "mboxes", "#mbox-cells",
737− idx, NULL);
738−}
739−
740−static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev,
741− int prot_id, bool tx)
569+static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
570+ int prot_id, bool tx)
742571 {
743572 int ret, idx;
744− struct resource res;
745− resource_size_t size;
746− struct device_node *shmem, *np = dev->of_node;
747573 struct scmi_chan_info *cinfo;
748− struct mbox_client *cl;
749574 struct idr *idr;
750− const char *desc = tx ? "Tx" : "Rx";
751575
752576 /* Transmit channel is first entry i.e. index 0 */
753577 idx = tx ? 0 : 1;
@@ -758,7 +582,7 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, · 4 unmodified lines
758582 if (cinfo)
759583 return 0;
760584
761− if (scmi_mailbox_check(np, idx)) {
585+ if (!info->desc->ops->chan_available(dev, idx)) {
762586 cinfo = idr_find(idr, SCMI_PROTOCOL_BASE);
763587 if (unlikely(!cinfo)) /* Possible only if platform has no Rx */
764588 return -EINVAL;
@@ -771,36 +595,9 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, · 6 unmodified lines
771595
772596 cinfo->dev = dev;
773597
774− cl = &cinfo->cl;
775− cl->dev = dev;
776− cl->rx_callback = scmi_rx_callback;
777− cl->tx_prepare = tx ? scmi_tx_prepare : NULL;
778− cl->tx_block = false;
779− cl->knows_txdone = tx;
780−
781− shmem = of_parse_phandle(np, "shmem", idx);
782− ret = of_address_to_resource(shmem, 0, &res);
783− of_node_put(shmem);
784− if (ret) {
785− dev_err(dev, "failed to get SCMI %s payload memory\n", desc);
786− return ret;
787− }
788−
789− size = resource_size(&res);
790− cinfo->payload = devm_ioremap(info->dev, res.start, size);
791− if (!cinfo->payload) {
792− dev_err(dev, "failed to ioremap SCMI %s payload\n", desc);
793− return -EADDRNOTAVAIL;
794− }
795−
796− cinfo->chan = mbox_request_channel(cl, idx);
797− if (IS_ERR(cinfo->chan)) {
798− ret = PTR_ERR(cinfo->chan);
799− if (ret != -EPROBE_DEFER)
800− dev_err(dev, "failed to request SCMI %s mailbox\n",
801− desc);
598+ ret = info->desc->ops->chan_setup(cinfo, info->dev, tx);
599+ if (ret)
802600 return ret;
803− }
804601
805602 idr_alloc:
806603 ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
@@ -814,12 +611,12 @@ idr_alloc: · 7 unmodified lines
814611 }
815612
816613 static inline int
817−scmi_mbox_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
614+scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
818615 {
819− int ret = scmi_mbox_chan_setup(info, dev, prot_id, true);
616+ int ret = scmi_chan_setup(info, dev, prot_id, true);
820617
821618 if (!ret) /* Rx is optional, hence no error check */
822− scmi_mbox_chan_setup(info, dev, prot_id, false);
619+ scmi_chan_setup(info, dev, prot_id, false);
823620
824621 return ret;
825622 }
@@ -837,7 +634,7 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info, · 11 unmodified lines
837634 return;
838635 }
839636
840− if (scmi_mbox_txrx_setup(info, &sdev->dev, prot_id)) {
637+ if (scmi_txrx_setup(info, &sdev->dev, prot_id)) {
841638 dev_err(&sdev->dev, "failed to setup transport\n");
842639 scmi_device_destroy(sdev);
843640 return;
@@ -890,12 +687,6 @@ static int scmi_probe(struct platform_device *pdev) · 46 unmodified lines
890687 struct device *dev = &pdev->dev;
891688 struct device_node *child, *np = dev->of_node;
892689
893− /* Only mailbox method supported, check for the presence of one */
894− if (scmi_mailbox_check(np, 0)) {
895− dev_err(dev, "no mailbox found in %pOF\n", np);
896− return -EINVAL;
897− }
898−
899690 desc = of_device_get_match_data(dev);
900691 if (!desc)
901692 return -EINVAL;
@@ -920,7 +711,7 @@ static int scmi_probe(struct platform_device *pdev) · 18 unmodified lines
920711 handle->dev = info->dev;
921712 handle->version = &info->version;
922713
923− ret = scmi_mbox_txrx_setup(info, dev, SCMI_PROTOCOL_BASE);
714+ ret = scmi_txrx_setup(info, dev, SCMI_PROTOCOL_BASE);
924715 if (ret)
925716 return ret;
926717
@@ -955,19 +746,9 @@ static int scmi_probe(struct platform_device *pdev) · 28 unmodified lines
955746 return 0;
956747 }
957748
958−static int scmi_mbox_free_channel(int id, void *p, void *data)
749+void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id)
959750 {
960− struct scmi_chan_info *cinfo = p;
961− struct idr *idr = data;
962−
963− if (!IS_ERR_OR_NULL(cinfo->chan)) {
964− mbox_free_channel(cinfo->chan);
965− cinfo->chan = NULL;
966− }
967−
968751 idr_remove(idr, id);
969−
970− return 0;
971752 }
972753
973754 static int scmi_remove(struct platform_device *pdev)
@@ -987,11 +768,11 @@ static int scmi_remove(struct platform_device *pdev) · 13 unmodified lines
987768 return ret;
988769
989770 /* Safe to free channels since no more users */
990− ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
771+ ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
991772 idr_destroy(&info->tx_idr);
992773
993774 idr = &info->rx_idr;
994− ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
775+ ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
995776 idr_destroy(&info->rx_idr);
996777
997778 return ret;
@@ -1043,15 +824,9 @@ static struct attribute *versions_attrs[] = { · 45 unmodified lines
1043824 };
1044825 ATTRIBUTE_GROUPS(versions);
1045826
1046−static const struct scmi_desc scmi_generic_desc = {
1047− .max_rx_timeout_ms = 30, /* We may increase this if required */
1048− .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */
1049− .max_msg_size = 128,
1050−};
1051−
1052827 /* Each compatible listed below must have descriptor associated with it */
1053828 static const struct of_device_id scmi_of_match[] = {
1054− { .compatible = "arm,scmi", .data = &scmi_generic_desc },
829+ { .compatible = "arm,scmi", .data = &scmi_mailbox_desc },
1055830 { /* Sentinel */ },
1056831 };
1057832
drivers/firmware/arm_scmi/mailbox.c+184−0
@@ -0,0 +1,184 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * System Control and Management Interface (SCMI) Message Mailbox Transport
4+ * driver.
5+ *
6+ * Copyright (C) 2019 ARM Ltd.
7+ */
8+
9+#include <linux/err.h>
10+#include <linux/device.h>
11+#include <linux/mailbox_client.h>
12+#include <linux/of.h>
13+#include <linux/of_address.h>
14+#include <linux/slab.h>
15+
16+#include "common.h"
17+
18+/**
19+ * struct scmi_mailbox - Structure representing a SCMI mailbox transport
20+ *
21+ * @cl: Mailbox Client
22+ * @chan: Transmit/Receive mailbox channel
23+ * @cinfo: SCMI channel info
24+ * @shmem: Transmit/Receive shared memory area
25+ */
26+struct scmi_mailbox {
27+ struct mbox_client cl;
28+ struct mbox_chan *chan;
29+ struct scmi_chan_info *cinfo;
30+ struct scmi_shared_mem __iomem *shmem;
31+};
32+
33+#define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)
34+
35+static void tx_prepare(struct mbox_client *cl, void *m)
36+{
37+ struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);
38+
39+ shmem_tx_prepare(smbox->shmem, m);
40+}
41+
42+static void rx_callback(struct mbox_client *cl, void *m)
43+{
44+ struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);
45+
46+ scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem));
47+}
48+
49+static bool mailbox_chan_available(struct device *dev, int idx)
50+{
51+ return !of_parse_phandle_with_args(dev->of_node, "mboxes",
52+ "#mbox-cells", idx, NULL);
53+}
54+
55+static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
56+ bool tx)
57+{
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;
64+ resource_size_t size;
65+ struct resource res;
66+
67+ smbox = devm_kzalloc(dev, sizeof(*smbox), GFP_KERNEL);
68+ if (!smbox)
69+ return -ENOMEM;
70+
71+ shmem = of_parse_phandle(cdev->of_node, "shmem", idx);
72+ ret = of_address_to_resource(shmem, 0, &res);
73+ of_node_put(shmem);
74+ if (ret) {
75+ dev_err(cdev, "failed to get SCMI %s shared memory\n", desc);
76+ return ret;
77+ }
78+
79+ size = resource_size(&res);
80+ smbox->shmem = devm_ioremap(dev, res.start, size);
81+ if (!smbox->shmem) {
82+ dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc);
83+ return -EADDRNOTAVAIL;
84+ }
85+
86+ cl = &smbox->cl;
87+ cl->dev = cdev;
88+ cl->tx_prepare = tx ? tx_prepare : NULL;
89+ cl->rx_callback = rx_callback;
90+ cl->tx_block = false;
91+ cl->knows_txdone = tx;
92+
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",
98+ tx ? "Tx" : "Rx");
99+ return ret;
100+ }
101+
102+ cinfo->transport_info = smbox;
103+ smbox->cinfo = cinfo;
104+
105+ return 0;
106+}
107+
108+static int mailbox_chan_free(int id, void *p, void *data)
109+{
110+ struct scmi_chan_info *cinfo = p;
111+ struct scmi_mailbox *smbox = cinfo->transport_info;
112+
113+ if (!IS_ERR(smbox->chan)) {
114+ mbox_free_channel(smbox->chan);
115+ cinfo->transport_info = NULL;
116+ smbox->chan = NULL;
117+ smbox->cinfo = NULL;
118+ }
119+
120+ scmi_free_channel(cinfo, data, id);
121+
122+ return 0;
123+}
124+
125+static int mailbox_send_message(struct scmi_chan_info *cinfo,
126+ struct scmi_xfer *xfer)
127+{
128+ struct scmi_mailbox *smbox = cinfo->transport_info;
129+ int ret;
130+
131+ ret = mbox_send_message(smbox->chan, xfer);
132+
133+ /* mbox_send_message returns non-negative value on success, so reset */
134+ if (ret > 0)
135+ ret = 0;
136+
137+ return ret;
138+}
139+
140+static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret)
141+{
142+ struct scmi_mailbox *smbox = cinfo->transport_info;
143+
144+ /*
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.
149+ */
150+ mbox_client_txdone(smbox->chan, ret);
151+}
152+
153+static void mailbox_fetch_response(struct scmi_chan_info *cinfo,
154+ struct scmi_xfer *xfer)
155+{
156+ struct scmi_mailbox *smbox = cinfo->transport_info;
157+
158+ shmem_fetch_response(smbox->shmem, xfer);
159+}
160+
161+static bool
162+mailbox_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
163+{
164+ struct scmi_mailbox *smbox = cinfo->transport_info;
165+
166+ return shmem_poll_done(smbox->shmem, xfer);
167+}
168+
169+static struct scmi_transport_ops scmi_mailbox_ops = {
170+ .chan_available = mailbox_chan_available,
171+ .chan_setup = mailbox_chan_setup,
172+ .chan_free = mailbox_chan_free,
173+ .send_message = mailbox_send_message,
174+ .mark_txdone = mailbox_mark_txdone,
175+ .fetch_response = mailbox_fetch_response,
176+ .poll_done = mailbox_poll_done,
177+};
178+
179+const struct scmi_desc scmi_mailbox_desc = {
180+ .ops = &scmi_mailbox_ops,
181+ .max_rx_timeout_ms = 30, /* We may increase this if required */
182+ .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */
183+ .max_msg_size = 128,
184+};
drivers/firmware/arm_scmi/perf.c+1−1
@@ -89,7 +89,7 @@ struct scmi_msg_resp_perf_describe_levels { · 88 unmodified lines
8989 __le32 power;
9090 __le16 transition_latency_us;
9191 __le16 reserved;
92− } opp[0];
92+ } opp[];
9393 };
9494
9595 struct scmi_perf_get_fc_info {
drivers/firmware/arm_scmi/shmem.c+83−0
@@ -0,0 +1,83 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * For transport using shared mem structure.
4+ *
5+ * Copyright (C) 2019 ARM Ltd.
6+ */
7+
8+#include <linux/io.h>
9+#include <linux/processor.h>
10+#include <linux/types.h>
11+
12+#include "common.h"
13+
14+/*
15+ * SCMI specification requires all parameters, message headers, return
16+ * arguments or any protocol data to be expressed in little endian
17+ * format only.
18+ */
19+struct scmi_shared_mem {
20+ __le32 reserved;
21+ __le32 channel_status;
22+#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR BIT(1)
23+#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE BIT(0)
24+ __le32 reserved1[2];
25+ __le32 flags;
26+#define SCMI_SHMEM_FLAG_INTR_ENABLED BIT(0)
27+ __le32 length;
28+ __le32 msg_header;
29+ u8 msg_payload[];
30+};
31+
32+void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
33+ struct scmi_xfer *xfer)
34+{
35+ /*
36+ * Ideally channel must be free by now unless OS timeout last
37+ * request and platform continued to process the same, wait
38+ * until it releases the shared memory, otherwise we may endup
39+ * overwriting its response with new message payload or vice-versa
40+ */
41+ spin_until_cond(ioread32(&shmem->channel_status) &
42+ SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
43+ /* Mark channel busy + clear error */
44+ iowrite32(0x0, &shmem->channel_status);
45+ iowrite32(xfer->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED,
46+ &shmem->flags);
47+ iowrite32(sizeof(shmem->msg_header) + xfer->tx.len, &shmem->length);
48+ iowrite32(pack_scmi_header(&xfer->hdr), &shmem->msg_header);
49+ if (xfer->tx.buf)
50+ memcpy_toio(shmem->msg_payload, xfer->tx.buf, xfer->tx.len);
51+}
52+
53+u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem)
54+{
55+ return ioread32(&shmem->msg_header);
56+}
57+
58+void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
59+ struct scmi_xfer *xfer)
60+{
61+ xfer->hdr.status = ioread32(shmem->msg_payload);
62+ /* Skip the length of header and status in shmem area i.e 8 bytes */
63+ xfer->rx.len = min_t(size_t, xfer->rx.len,
64+ ioread32(&shmem->length) - 8);
65+
66+ /* Take a copy to the rx buffer.. */
67+ memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
68+}
69+
70+bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
71+ struct scmi_xfer *xfer)
72+{
73+ u16 xfer_id;
74+
75+ xfer_id = MSG_XTRACT_TOKEN(ioread32(&shmem->msg_header));
76+
77+ if (xfer->hdr.seq != xfer_id)
78+ return false;
79+
80+ return ioread32(&shmem->channel_status) &
81+ (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR |
82+ SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
83+}
drivers/firmware/arm_scpi.c+2−2
@@ -262,12 +262,12 @@ struct scpi_drvinfo { · 261 unmodified lines
262262 struct scpi_shared_mem {
263263 __le32 command;
264264 __le32 status;
265− u8 payload[0];
265+ u8 payload[];
266266 } __packed;
267267
268268 struct legacy_scpi_shared_mem {
269269 __le32 status;
270− u8 payload[0];
270+ u8 payload[];
271271 } __packed;
272272
273273 struct scp_capabilities {
drivers/misc/vexpress-syscfg.c+1−1
@@ -42,7 +42,7 @@ struct vexpress_syscfg_func { · 41 unmodified lines
4242 struct vexpress_syscfg *syscfg;
4343 struct regmap *regmap;
4444 int num_templates;
45− u32 template[0]; /* Keep it last! */
45+ u32 template[]; /* Keep it last! */
4646 };
4747
4848