Lines Matching +full:scmi +full:- +full:shmem
1 // SPDX-License-Identifier: GPL-2.0
3 * System Control and Management Interface (SCMI) Message SMC/HVC
9 #include <linux/arm-smccc.h>
26 * The shmem address is split into 4K page and offset.
29 * This however limits the shmem address to 44 bit.
32 * scmi instances that are using the same smc-id.
40 #define SHMEM_OFFSET(x) ((x) & (SHMEM_SIZE - 1))
43 * struct scmi_smc - Structure representing a SCMI smc transport
46 * @cinfo: SCMI channel info
47 * @shmem: Transmit/Receive shared memory area
53 * @param_page: 4K page number of the shmem channel
54 * @param_offset: Offset within the 4K page of the shmem channel
62 struct scmi_shared_mem __iomem *shmem; member
63 /* Protect access to shmem area */
79 core->rx_callback(scmi_info->cinfo, in smc_msg_done_isr()
80 core->shmem->read_header(scmi_info->shmem), NULL); in smc_msg_done_isr()
88 of_parse_phandle(of_node, "shmem", 0); in smc_chan_available()
98 atomic_set(&scmi_info->inflight, INFLIGHT_NONE); in smc_channel_lock_init()
100 mutex_init(&scmi_info->shmem_lock); in smc_channel_lock_init()
107 ret = atomic_cmpxchg(inflight, INFLIGHT_NONE, xfer->hdr.seq); in smc_xfer_inflight()
117 spin_until_cond(smc_xfer_inflight(xfer, &scmi_info->inflight)); in smc_channel_lock_acquire()
119 mutex_lock(&scmi_info->shmem_lock); in smc_channel_lock_acquire()
125 atomic_set(&scmi_info->inflight, INFLIGHT_NONE); in smc_channel_lock_release()
127 mutex_unlock(&scmi_info->shmem_lock); in smc_channel_lock_release()
133 struct device *cdev = cinfo->dev; in smc_chan_setup()
141 return -ENODEV; in smc_chan_setup()
145 return -ENOMEM; in smc_chan_setup()
147 scmi_info->shmem = core->shmem->setup_iomap(cinfo, dev, tx, &res); in smc_chan_setup()
148 if (IS_ERR(scmi_info->shmem)) in smc_chan_setup()
149 return PTR_ERR(scmi_info->shmem); in smc_chan_setup()
151 ret = of_property_read_u32(dev->of_node, "arm,smc-id", &func_id); in smc_chan_setup()
155 if (of_device_is_compatible(dev->of_node, "qcom,scmi-smc")) { in smc_chan_setup()
157 void __iomem *ptr = (void __iomem *)scmi_info->shmem + size - 8; in smc_chan_setup()
158 /* The capability-id is kept in last 8 bytes of shmem. in smc_chan_setup()
159 * +-------+ <-- 0 in smc_chan_setup()
160 * | shmem | in smc_chan_setup()
161 * +-------+ <-- size - 8 in smc_chan_setup()
163 * +-------+ <-- size in smc_chan_setup()
168 if (of_device_is_compatible(dev->of_node, "arm,scmi-smc-param")) { in smc_chan_setup()
169 scmi_info->param_page = SHMEM_PAGE(res.start); in smc_chan_setup()
170 scmi_info->param_offset = SHMEM_OFFSET(res.start); in smc_chan_setup()
177 scmi_info->irq = of_irq_get_byname(cdev->of_node, "a2p"); in smc_chan_setup()
178 if (scmi_info->irq > 0) { in smc_chan_setup()
179 ret = request_irq(scmi_info->irq, smc_msg_done_isr, in smc_chan_setup()
182 dev_err(dev, "failed to setup SCMI smc irq\n"); in smc_chan_setup()
186 cinfo->no_completion_irq = true; in smc_chan_setup()
189 scmi_info->func_id = func_id; in smc_chan_setup()
190 scmi_info->cap_id = cap_id; in smc_chan_setup()
191 scmi_info->cinfo = cinfo; in smc_chan_setup()
193 cinfo->transport_info = scmi_info; in smc_chan_setup()
201 struct scmi_smc *scmi_info = cinfo->transport_info; in smc_chan_free()
211 if (scmi_info->irq > 0) in smc_chan_free()
212 free_irq(scmi_info->irq, scmi_info); in smc_chan_free()
214 cinfo->transport_info = NULL; in smc_chan_free()
215 scmi_info->cinfo = NULL; in smc_chan_free()
223 struct scmi_smc *scmi_info = cinfo->transport_info; in smc_send_message()
232 core->shmem->tx_prepare(scmi_info->shmem, xfer, cinfo); in smc_send_message()
234 if (scmi_info->cap_id != ULONG_MAX) in smc_send_message()
235 arm_smccc_1_1_invoke(scmi_info->func_id, scmi_info->cap_id, 0, in smc_send_message()
238 arm_smccc_1_1_invoke(scmi_info->func_id, scmi_info->param_page, in smc_send_message()
239 scmi_info->param_offset, 0, 0, 0, 0, 0, in smc_send_message()
245 return -EOPNOTSUPP; in smc_send_message()
254 struct scmi_smc *scmi_info = cinfo->transport_info; in smc_fetch_response()
256 core->shmem->fetch_response(scmi_info->shmem, xfer); in smc_fetch_response()
262 struct scmi_smc *scmi_info = cinfo->transport_info; in smc_mark_txdone()
284 * SCMI command would have been already fully processed by the SCMI
294 { .compatible = "arm,scmi-smc" },
295 { .compatible = "arm,scmi-smc-param" },
296 { .compatible = "qcom,scmi-smc" },
306 MODULE_DESCRIPTION("SCMI SMC Transport driver");