History

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

ARM SCMI/SCPI updates for v5.8 1. Addition of ARM SMC/HVC as SCMI transport type with required abstraction already in place 2. Initial infrastructure support to add SCMI notifications from platform to agents 3. Miscellaneous fix adding header include guards * tag 'scmi-updates-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: firmware: arm_scmi: fix psci dependency firmware: arm_scmi: Fix return error code in smc_send_message firmware: arm_scmi: Fix handling of unexpected delayed responses firmware: arm_scmi: Clear channel for delayed responses firmware: arm_scmi: Clear channel on reception of unexpected responses firmware: arm_scmi: Rename .clear_notification() transport_ops firmware: arm_scmi: Add support for notifications message processing firmware: arm_scmi: Add notifications support in transport layer firmware: arm_scmi: Update protocol commands and notification list firmware: arm_scmi: Add receive buffer support for notifications firmware: arm_scpi: Add include guard to linux/scpi_protocol.h firmware: arm_scmi: Add include guard to linux/scmi_protocol.h firmware: arm_scmi: Drop checking for shmem property in parent node firmware: arm_scmi: Check shmem property for channel availablity firmware: arm_scmi: Drop empty stub for smc_mark_txdone firmware: arm_scmi: Make mutex channel specific firmware: arm_scmi: Add smc/hvc transport dt-bindings: arm: Add smc/hvc transport for SCMI

Arnd Bergmann committed 6 years ago

Commit a7afae52 parents 0e698df 5a897e313 files · +340 −30Browse files

Unified · Split

13 files
  1. Documentation/devicetree/bindings/arm/arm,scmi.txt +2 −1
  2. drivers/firmware/arm_scmi/Makefile +3 −1
  3. drivers/firmware/arm_scmi/base.c +7 −0
  4. drivers/firmware/arm_scmi/common.h +11 −0
  5. drivers/firmware/arm_scmi/driver.c +105 −28
  6. drivers/firmware/arm_scmi/mailbox.c +17 −0
  7. drivers/firmware/arm_scmi/perf.c +5 −0
  8. drivers/firmware/arm_scmi/power.c +6 −0
  9. drivers/firmware/arm_scmi/sensors.c +4 −0
  10. drivers/firmware/arm_scmi/shmem.c +15 −0
  11. drivers/firmware/arm_scmi/smc.c +153 −0
  12. include/linux/scmi_protocol.h +6 −0
  13. include/linux/scpi_protocol.h +6 −0
Documentation/devicetree/bindings/arm/arm,scmi.txt+2−1
@@ -14,7 +14,7 @@ Required properties: · 13 unmodified lines
1414
1515 The scmi node with the following properties shall be under the /firmware/ node.
1616
17−- compatible : shall be "arm,scmi"
17+- compatible : shall be "arm,scmi" or "arm,scmi-smc" for smc/hvc transports
1818 - mboxes: List of phandle and mailbox channel specifiers. It should contain
1919 exactly one or two mailboxes, one for transmitting messages("tx")
2020 and another optional for receiving the notifications("rx") if
@@ -25,6 +25,7 @@ The scmi node with the following properties shall be under the /firmware/ node. · 4 unmodified lines
2525 protocol identifier for a given sub-node.
2626 - #size-cells : should be '0' as 'reg' property doesn't have any size
2727 associated with it.
28+- arm,smc-id : SMC id required when using smc or hvc transports
2829
2930 Optional properties:
3031
drivers/firmware/arm_scmi/Makefile+3−1
@@ -2,6 +2,8 @@ · 1 unmodified line
22 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
5+scmi-transport-y = shmem.o
6+scmi-transport-$(CONFIG_MAILBOX) += mailbox.o
7+scmi-transport-$(CONFIG_ARM_PSCI_FW) += smc.o
68 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o
79 obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
drivers/firmware/arm_scmi/base.c+7−0
@@ -14,6 +14,13 @@ enum scmi_base_protocol_cmd { · 13 unmodified lines
1414 BASE_DISCOVER_LIST_PROTOCOLS = 0x6,
1515 BASE_DISCOVER_AGENT = 0x7,
1616 BASE_NOTIFY_ERRORS = 0x8,
17+ BASE_SET_DEVICE_PERMISSIONS = 0x9,
18+ BASE_SET_PROTOCOL_PERMISSIONS = 0xa,
19+ BASE_RESET_AGENT_CONFIGURATION = 0xb,
20+};
21+
22+enum scmi_base_protocol_notify {
23+ BASE_ERROR_EVENT = 0x0,
1724 };
1825
1926 struct scmi_msg_resp_base_attributes {
drivers/firmware/arm_scmi/common.h+11−0
@@ -178,6 +178,8 @@ struct scmi_chan_info { · 177 unmodified lines
178178 * @send_message: Callback to send a message
179179 * @mark_txdone: Callback to mark tx as done
180180 * @fetch_response: Callback to fetch response
181+ * @fetch_notification: Callback to fetch notification
182+ * @clear_channel: Callback to clear a channel
181183 * @poll_done: Callback to poll transfer status
182184 */
183185 struct scmi_transport_ops {
@@ -190,6 +192,9 @@ struct scmi_transport_ops { · 6 unmodified lines
190192 void (*mark_txdone)(struct scmi_chan_info *cinfo, int ret);
191193 void (*fetch_response)(struct scmi_chan_info *cinfo,
192194 struct scmi_xfer *xfer);
195+ void (*fetch_notification)(struct scmi_chan_info *cinfo,
196+ size_t max_len, struct scmi_xfer *xfer);
197+ void (*clear_channel)(struct scmi_chan_info *cinfo);
193198 bool (*poll_done)(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer);
194199 };
195200
@@ -210,6 +215,9 @@ struct scmi_desc { · 14 unmodified lines
210215 };
211216
212217 extern const struct scmi_desc scmi_mailbox_desc;
218+#ifdef CONFIG_HAVE_ARM_SMCCC
219+extern const struct scmi_desc scmi_smc_desc;
220+#endif
213221
214222 void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr);
215223 void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
@@ -222,5 +230,8 @@ void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem, · 6 unmodified lines
222230 u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem);
223231 void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
224232 struct scmi_xfer *xfer);
233+void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
234+ size_t max_len, struct scmi_xfer *xfer);
235+void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem);
225236 bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
226237 struct scmi_xfer *xfer);
drivers/firmware/arm_scmi/driver.c+105−28
@@ -76,6 +76,7 @@ struct scmi_xfers_info { · 75 unmodified lines
7676 * implementation version and (sub-)vendor identification.
7777 * @handle: Instance of SCMI handle to send to clients
7878 * @tx_minfo: Universal Transmit Message management info
79+ * @rx_minfo: Universal Receive Message management info
7980 * @tx_idr: IDR object to map protocol id to Tx channel info pointer
8081 * @rx_idr: IDR object to map protocol id to Rx channel info pointer
8182 * @protocols_imp: List of protocols implemented, currently maximum of
@@ -89,6 +90,7 @@ struct scmi_info { · 7 unmodified lines
8990 struct scmi_revision_info version;
9091 struct scmi_handle handle;
9192 struct scmi_xfers_info tx_minfo;
93+ struct scmi_xfers_info rx_minfo;
9294 struct idr tx_idr;
9395 struct idr rx_idr;
9496 u8 *protocols_imp;
@@ -200,37 +202,66 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) · 105 unmodified lines
200202 spin_unlock_irqrestore(&minfo->xfer_lock, flags);
201203 }
202204
203−/**
204− * scmi_rx_callback() - callback for receiving messages
205− *
206− * @cinfo: SCMI channel info
207− * @msg_hdr: Message header
208− *
209− * Processes one received message to appropriate transfer information and
210− * signals completion of the transfer.
211− *
212− * NOTE: This function will be invoked in IRQ context, hence should be
213− * as optimal as possible.
214− */
215−void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
205+static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
216206 {
217− struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
218− struct scmi_xfers_info *minfo = &info->tx_minfo;
219− u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
220− u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
221− struct device *dev = cinfo->dev;
222207 struct scmi_xfer *xfer;
208+ struct device *dev = cinfo->dev;
209+ struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
210+ struct scmi_xfers_info *minfo = &info->rx_minfo;
223211
224− if (msg_type == MSG_TYPE_NOTIFICATION)
225− return; /* Notifications not yet supported */
212+ xfer = scmi_xfer_get(cinfo->handle, minfo);
213+ if (IS_ERR(xfer)) {
214+ dev_err(dev, "failed to get free message slot (%ld)\n",
215+ PTR_ERR(xfer));
216+ info->desc->ops->clear_channel(cinfo);
217+ return;
218+ }
219+
220+ unpack_scmi_header(msg_hdr, &xfer->hdr);
221+ scmi_dump_header_dbg(dev, &xfer->hdr);
222+ info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,
223+ xfer);
224+
225+ trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
226+ xfer->hdr.protocol_id, xfer->hdr.seq,
227+ MSG_TYPE_NOTIFICATION);
228+
229+ __scmi_xfer_put(minfo, xfer);
230+
231+ info->desc->ops->clear_channel(cinfo);
232+}
233+
234+static void scmi_handle_response(struct scmi_chan_info *cinfo,
235+ u16 xfer_id, u8 msg_type)
236+{
237+ struct scmi_xfer *xfer;
238+ struct device *dev = cinfo->dev;
239+ struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
240+ struct scmi_xfers_info *minfo = &info->tx_minfo;
226241
227242 /* Are we even expecting this? */
228243 if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
229244 dev_err(dev, "message for %d is not expected!\n", xfer_id);
245+ info->desc->ops->clear_channel(cinfo);
230246 return;
231247 }
232248
233249 xfer = &minfo->xfer_block[xfer_id];
250+ /*
251+ * Even if a response was indeed expected on this slot at this point,
252+ * a buggy platform could wrongly reply feeding us an unexpected
253+ * delayed response we're not prepared to handle: bail-out safely
254+ * blaming firmware.
255+ */
256+ if (unlikely(msg_type == MSG_TYPE_DELAYED_RESP && !xfer->async_done)) {
257+ dev_err(dev,
258+ "Delayed Response for %d not expected! Buggy F/W ?\n",
259+ xfer_id);
260+ info->desc->ops->clear_channel(cinfo);
261+ /* It was unexpected, so nobody will clear the xfer if not us */
262+ __scmi_xfer_put(minfo, xfer);
263+ return;
264+ }
234265
235266 scmi_dump_header_dbg(dev, &xfer->hdr);
236267
@@ -240,10 +271,43 @@ void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr) · 3 unmodified lines
240271 xfer->hdr.protocol_id, xfer->hdr.seq,
241272 msg_type);
242273
243− if (msg_type == MSG_TYPE_DELAYED_RESP)
274+ if (msg_type == MSG_TYPE_DELAYED_RESP) {
275+ info->desc->ops->clear_channel(cinfo);
244276 complete(xfer->async_done);
245− else
277+ } else {
246278 complete(&xfer->done);
279+ }
280+}
281+
282+/**
283+ * scmi_rx_callback() - callback for receiving messages
284+ *
285+ * @cinfo: SCMI channel info
286+ * @msg_hdr: Message header
287+ *
288+ * Processes one received message to appropriate transfer information and
289+ * signals completion of the transfer.
290+ *
291+ * NOTE: This function will be invoked in IRQ context, hence should be
292+ * as optimal as possible.
293+ */
294+void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
295+{
296+ u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
297+ u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
298+
299+ switch (msg_type) {
300+ case MSG_TYPE_NOTIFICATION:
301+ scmi_handle_notification(cinfo, msg_hdr);
302+ break;
303+ case MSG_TYPE_COMMAND:
304+ case MSG_TYPE_DELAYED_RESP:
305+ scmi_handle_response(cinfo, xfer_id, msg_type);
306+ break;
307+ default:
308+ WARN_ONCE(1, "received unknown msg_type:%d\n", msg_type);
309+ break;
310+ }
247311 }
248312
249313 /**
@@ -525,13 +589,13 @@ int scmi_handle_put(const struct scmi_handle *handle) · 275 unmodified lines
525589 return 0;
526590 }
527591
528−static int scmi_xfer_info_init(struct scmi_info *sinfo)
592+static int __scmi_xfer_info_init(struct scmi_info *sinfo,
593+ struct scmi_xfers_info *info)
529594 {
530595 int i;
531596 struct scmi_xfer *xfer;
532597 struct device *dev = sinfo->dev;
533598 const struct scmi_desc *desc = sinfo->desc;
534− struct scmi_xfers_info *info = &sinfo->tx_minfo;
535599
536600 /* Pre-allocated messages, no more than what hdr.seq can support */
537601 if (WARN_ON(desc->max_msg >= MSG_TOKEN_MAX)) {
@@ -566,6 +630,16 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo) · 28 unmodified lines
566630 return 0;
567631 }
568632
633+static int scmi_xfer_info_init(struct scmi_info *sinfo)
634+{
635+ int ret = __scmi_xfer_info_init(sinfo, &sinfo->tx_minfo);
636+
637+ if (!ret && idr_find(&sinfo->rx_idr, SCMI_PROTOCOL_BASE))
638+ ret = __scmi_xfer_info_init(sinfo, &sinfo->rx_minfo);
639+
640+ return ret;
641+}
642+
569643 static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
570644 int prot_id, bool tx)
571645 {
@@ -699,10 +773,6 @@ static int scmi_probe(struct platform_device *pdev) · 127 unmodified lines
699773 info->desc = desc;
700774 INIT_LIST_HEAD(&info->node);
701775
702− ret = scmi_xfer_info_init(info);
703− if (ret)
704− return ret;
705−
706776 platform_set_drvdata(pdev, info);
707777 idr_init(&info->tx_idr);
708778 idr_init(&info->rx_idr);
@@ -715,6 +785,10 @@ static int scmi_probe(struct platform_device *pdev) · 6 unmodified lines
715785 if (ret)
716786 return ret;
717787
788+ ret = scmi_xfer_info_init(info);
789+ if (ret)
790+ return ret;
791+
718792 ret = scmi_base_protocol_init(handle);
719793 if (ret) {
720794 dev_err(dev, "unable to communicate with SCMI(%d)\n", ret);
@@ -827,6 +901,9 @@ ATTRIBUTE_GROUPS(versions); · 106 unmodified lines
827901 /* Each compatible listed below must have descriptor associated with it */
828902 static const struct of_device_id scmi_of_match[] = {
829903 { .compatible = "arm,scmi", .data = &scmi_mailbox_desc },
904+#ifdef CONFIG_ARM_PSCI_FW
905+ { .compatible = "arm,scmi-smc", .data = &scmi_smc_desc},
906+#endif
830907 { /* Sentinel */ },
831908 };
832909
drivers/firmware/arm_scmi/mailbox.c+17−0
@@ -158,6 +158,21 @@ static void mailbox_fetch_response(struct scmi_chan_info *cinfo, · 157 unmodified lines
158158 shmem_fetch_response(smbox->shmem, xfer);
159159 }
160160
161+static void mailbox_fetch_notification(struct scmi_chan_info *cinfo,
162+ size_t max_len, struct scmi_xfer *xfer)
163+{
164+ struct scmi_mailbox *smbox = cinfo->transport_info;
165+
166+ shmem_fetch_notification(smbox->shmem, max_len, xfer);
167+}
168+
169+static void mailbox_clear_channel(struct scmi_chan_info *cinfo)
170+{
171+ struct scmi_mailbox *smbox = cinfo->transport_info;
172+
173+ shmem_clear_channel(smbox->shmem);
174+}
175+
161176 static bool
162177 mailbox_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
163178 {
@@ -173,6 +188,8 @@ static struct scmi_transport_ops scmi_mailbox_ops = { · 9 unmodified lines
173188 .send_message = mailbox_send_message,
174189 .mark_txdone = mailbox_mark_txdone,
175190 .fetch_response = mailbox_fetch_response,
191+ .fetch_notification = mailbox_fetch_notification,
192+ .clear_channel = mailbox_clear_channel,
176193 .poll_done = mailbox_poll_done,
177194 };
178195
drivers/firmware/arm_scmi/perf.c+5−0
@@ -27,6 +27,11 @@ enum scmi_performance_protocol_cmd { · 26 unmodified lines
2727 PERF_DESCRIBE_FASTCHANNEL = 0xb,
2828 };
2929
30+enum scmi_performance_protocol_notify {
31+ PERFORMANCE_LIMITS_CHANGED = 0x0,
32+ PERFORMANCE_LEVEL_CHANGED = 0x1,
33+};
34+
3035 struct scmi_opp {
3136 u32 perf;
3237 u32 power;
drivers/firmware/arm_scmi/power.c+6−0
@@ -12,6 +12,12 @@ enum scmi_power_protocol_cmd { · 11 unmodified lines
1212 POWER_STATE_SET = 0x4,
1313 POWER_STATE_GET = 0x5,
1414 POWER_STATE_NOTIFY = 0x6,
15+ POWER_STATE_CHANGE_REQUESTED_NOTIFY = 0x7,
16+};
17+
18+enum scmi_power_protocol_notify {
19+ POWER_STATE_CHANGED = 0x0,
20+ POWER_STATE_CHANGE_REQUESTED = 0x1,
1521 };
1622
1723 struct scmi_msg_resp_power_attributes {
drivers/firmware/arm_scmi/sensors.c+4−0
@@ -14,6 +14,10 @@ enum scmi_sensor_protocol_cmd { · 13 unmodified lines
1414 SENSOR_READING_GET = 0x6,
1515 };
1616
17+enum scmi_sensor_protocol_notify {
18+ SENSOR_TRIP_POINT_EVENT = 0x0,
19+};
20+
1721 struct scmi_msg_resp_sensor_attributes {
1822 __le16 num_sensors;
1923 u8 max_requests;
drivers/firmware/arm_scmi/shmem.c+15−0
@@ -67,6 +67,21 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, · 66 unmodified lines
6767 memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
6868 }
6969
70+void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
71+ size_t max_len, struct scmi_xfer *xfer)
72+{
73+ /* Skip only the length of header in shmem area i.e 4 bytes */
74+ xfer->rx.len = min_t(size_t, max_len, ioread32(&shmem->length) - 4);
75+
76+ /* Take a copy to the rx buffer.. */
77+ memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);
78+}
79+
80+void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem)
81+{
82+ iowrite32(SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE, &shmem->channel_status);
83+}
84+
7085 bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
7186 struct scmi_xfer *xfer)
7287 {
drivers/firmware/arm_scmi/smc.c+153−0
@@ -0,0 +1,153 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * System Control and Management Interface (SCMI) Message SMC/HVC
4+ * Transport driver
5+ *
6+ * Copyright 2020 NXP
7+ */
8+
9+#include <linux/arm-smccc.h>
10+#include <linux/device.h>
11+#include <linux/err.h>
12+#include <linux/mutex.h>
13+#include <linux/of.h>
14+#include <linux/of_address.h>
15+#include <linux/slab.h>
16+
17+#include "common.h"
18+
19+/**
20+ * struct scmi_smc - Structure representing a SCMI smc transport
21+ *
22+ * @cinfo: SCMI channel info
23+ * @shmem: Transmit/Receive shared memory area
24+ * @func_id: smc/hvc call function id
25+ */
26+
27+struct scmi_smc {
28+ struct scmi_chan_info *cinfo;
29+ struct scmi_shared_mem __iomem *shmem;
30+ struct mutex shmem_lock;
31+ u32 func_id;
32+};
33+
34+static bool smc_chan_available(struct device *dev, int idx)
35+{
36+ struct device_node *np = of_parse_phandle(dev->of_node, "shmem", 0);
37+ if (!np)
38+ return false;
39+
40+ of_node_put(np);
41+ return true;
42+}
43+
44+static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
45+ bool tx)
46+{
47+ struct device *cdev = cinfo->dev;
48+ struct scmi_smc *scmi_info;
49+ resource_size_t size;
50+ struct resource res;
51+ struct device_node *np;
52+ u32 func_id;
53+ int ret;
54+
55+ if (!tx)
56+ return -ENODEV;
57+
58+ scmi_info = devm_kzalloc(dev, sizeof(*scmi_info), GFP_KERNEL);
59+ if (!scmi_info)
60+ return -ENOMEM;
61+
62+ np = of_parse_phandle(cdev->of_node, "shmem", 0);
63+ ret = of_address_to_resource(np, 0, &res);
64+ of_node_put(np);
65+ if (ret) {
66+ dev_err(cdev, "failed to get SCMI Tx shared memory\n");
67+ return ret;
68+ }
69+
70+ size = resource_size(&res);
71+ scmi_info->shmem = devm_ioremap(dev, res.start, size);
72+ if (!scmi_info->shmem) {
73+ dev_err(dev, "failed to ioremap SCMI Tx shared memory\n");
74+ return -EADDRNOTAVAIL;
75+ }
76+
77+ ret = of_property_read_u32(dev->of_node, "arm,smc-id", &func_id);
78+ if (ret < 0)
79+ return ret;
80+
81+ scmi_info->func_id = func_id;
82+ scmi_info->cinfo = cinfo;
83+ mutex_init(&scmi_info->shmem_lock);
84+ cinfo->transport_info = scmi_info;
85+
86+ return 0;
87+}
88+
89+static int smc_chan_free(int id, void *p, void *data)
90+{
91+ struct scmi_chan_info *cinfo = p;
92+ struct scmi_smc *scmi_info = cinfo->transport_info;
93+
94+ cinfo->transport_info = NULL;
95+ scmi_info->cinfo = NULL;
96+
97+ scmi_free_channel(cinfo, data, id);
98+
99+ return 0;
100+}
101+
102+static int smc_send_message(struct scmi_chan_info *cinfo,
103+ struct scmi_xfer *xfer)
104+{
105+ struct scmi_smc *scmi_info = cinfo->transport_info;
106+ struct arm_smccc_res res;
107+
108+ mutex_lock(&scmi_info->shmem_lock);
109+
110+ shmem_tx_prepare(scmi_info->shmem, xfer);
111+
112+ arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
113+ scmi_rx_callback(scmi_info->cinfo, shmem_read_header(scmi_info->shmem));
114+
115+ mutex_unlock(&scmi_info->shmem_lock);
116+
117+ /* Only SMCCC_RET_NOT_SUPPORTED is valid error code */
118+ if (res.a0)
119+ return -EOPNOTSUPP;
120+ return 0;
121+}
122+
123+static void smc_fetch_response(struct scmi_chan_info *cinfo,
124+ struct scmi_xfer *xfer)
125+{
126+ struct scmi_smc *scmi_info = cinfo->transport_info;
127+
128+ shmem_fetch_response(scmi_info->shmem, xfer);
129+}
130+
131+static bool
132+smc_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
133+{
134+ struct scmi_smc *scmi_info = cinfo->transport_info;
135+
136+ return shmem_poll_done(scmi_info->shmem, xfer);
137+}
138+
139+static struct scmi_transport_ops scmi_smc_ops = {
140+ .chan_available = smc_chan_available,
141+ .chan_setup = smc_chan_setup,
142+ .chan_free = smc_chan_free,
143+ .send_message = smc_send_message,
144+ .fetch_response = smc_fetch_response,
145+ .poll_done = smc_poll_done,
146+};
147+
148+const struct scmi_desc scmi_smc_desc = {
149+ .ops = &scmi_smc_ops,
150+ .max_rx_timeout_ms = 30,
151+ .max_msg = 1,
152+ .max_msg_size = 128,
153+};
include/linux/scmi_protocol.h+6−0
@@ -4,6 +4,10 @@ · 3 unmodified lines
44 *
55 * Copyright (C) 2018 ARM Ltd.
66 */
7+
8+#ifndef _LINUX_SCMI_PROTOCOL_H
9+#define _LINUX_SCMI_PROTOCOL_H
10+
711 #include <linux/device.h>
812 #include <linux/types.h>
913
@@ -319,3 +323,5 @@ static inline void scmi_driver_unregister(struct scmi_driver *driver) {} · 309 unmodified lines
319323 typedef int (*scmi_prot_init_fn_t)(struct scmi_handle *);
320324 int scmi_protocol_register(int protocol_id, scmi_prot_init_fn_t fn);
321325 void scmi_protocol_unregister(int protocol_id);
326+
327+#endif /* _LINUX_SCMI_PROTOCOL_H */
include/linux/scpi_protocol.h+6−0
@@ -4,6 +4,10 @@ · 3 unmodified lines
44 *
55 * Copyright (C) 2014 ARM Ltd.
66 */
7+
8+#ifndef _LINUX_SCPI_PROTOCOL_H
9+#define _LINUX_SCPI_PROTOCOL_H
10+
711 #include <linux/types.h>
812
913 struct scpi_opp {
@@ -71,3 +75,5 @@ struct scpi_ops *get_scpi_ops(void); · 61 unmodified lines
7175 #else
7276 static inline struct scpi_ops *get_scpi_ops(void) { return NULL; }
7377 #endif
78+
79+#endif /* _LINUX_SCPI_PROTOCOL_H */