hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/firmware/arm_scmi/smc.c
....@@ -9,9 +9,11 @@
99 #include <linux/arm-smccc.h>
1010 #include <linux/device.h>
1111 #include <linux/err.h>
12
+#include <linux/interrupt.h>
1213 #include <linux/mutex.h>
1314 #include <linux/of.h>
1415 #include <linux/of_address.h>
16
+#include <linux/of_irq.h>
1517 #include <linux/slab.h>
1618
1719 #include "common.h"
....@@ -23,6 +25,8 @@
2325 * @shmem: Transmit/Receive shared memory area
2426 * @shmem_lock: Lock to protect access to Tx/Rx shared memory area
2527 * @func_id: smc/hvc call function id
28
+ * @irq: Optional; employed when platforms indicates msg completion by intr.
29
+ * @tx_complete: Optional, employed only when irq is valid.
2630 */
2731
2832 struct scmi_smc {
....@@ -30,7 +34,18 @@
3034 struct scmi_shared_mem __iomem *shmem;
3135 struct mutex shmem_lock;
3236 u32 func_id;
37
+ int irq;
38
+ struct completion tx_complete;
3339 };
40
+
41
+static irqreturn_t smc_msg_done_isr(int irq, void *data)
42
+{
43
+ struct scmi_smc *scmi_info = data;
44
+
45
+ complete(&scmi_info->tx_complete);
46
+
47
+ return IRQ_HANDLED;
48
+}
3449
3550 static bool smc_chan_available(struct device *dev, int idx)
3651 {
....@@ -51,7 +66,7 @@
5166 struct resource res;
5267 struct device_node *np;
5368 u32 func_id;
54
- int ret;
69
+ int ret, irq;
5570
5671 if (!tx)
5772 return -ENODEV;
....@@ -78,6 +93,24 @@
7893 ret = of_property_read_u32(dev->of_node, "arm,smc-id", &func_id);
7994 if (ret < 0)
8095 return ret;
96
+
97
+ /*
98
+ * If there is an interrupt named "a2p", then the service and
99
+ * completion of a message is signaled by an interrupt rather than by
100
+ * the return of the SMC call.
101
+ */
102
+ irq = of_irq_get_byname(cdev->of_node, "a2p");
103
+ if (irq > 0) {
104
+ ret = devm_request_irq(dev, irq, smc_msg_done_isr,
105
+ IRQF_NO_SUSPEND,
106
+ dev_name(dev), scmi_info);
107
+ if (ret) {
108
+ dev_err(dev, "failed to setup SCMI smc irq\n");
109
+ return ret;
110
+ }
111
+ init_completion(&scmi_info->tx_complete);
112
+ scmi_info->irq = irq;
113
+ }
81114
82115 scmi_info->func_id = func_id;
83116 scmi_info->cinfo = cinfo;
....@@ -110,7 +143,14 @@
110143
111144 shmem_tx_prepare(scmi_info->shmem, xfer);
112145
146
+ if (scmi_info->irq)
147
+ reinit_completion(&scmi_info->tx_complete);
148
+
113149 arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
150
+
151
+ if (scmi_info->irq)
152
+ wait_for_completion(&scmi_info->tx_complete);
153
+
114154 scmi_rx_callback(scmi_info->cinfo, shmem_read_header(scmi_info->shmem));
115155
116156 mutex_unlock(&scmi_info->shmem_lock);
....@@ -137,7 +177,7 @@
137177 return shmem_poll_done(scmi_info->shmem, xfer);
138178 }
139179
140
-static struct scmi_transport_ops scmi_smc_ops = {
180
+static const struct scmi_transport_ops scmi_smc_ops = {
141181 .chan_available = smc_chan_available,
142182 .chan_setup = smc_chan_setup,
143183 .chan_free = smc_chan_free,