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
54 * @param_page: 4K page number of the shmem channel
55 * @param_offset: Offset within the 4K page of the shmem channel
63 struct scmi_shared_mem __iomem *shmem; member
65 /* Protect access to shmem area */
81 core->rx_callback(scmi_info->cinfo, in smc_msg_done_isr()
82 core->shmem->read_header(scmi_info->shmem), NULL); in smc_msg_done_isr()
90 of_parse_phandle(of_node, "shmem", 0); in smc_chan_available()
100 atomic_set(&scmi_info->inflight, INFLIGHT_NONE); in smc_channel_lock_init()
102 mutex_init(&scmi_info->shmem_lock); in smc_channel_lock_init()
109 ret = atomic_cmpxchg(inflight, INFLIGHT_NONE, xfer->hdr.seq); in smc_xfer_inflight()
119 spin_until_cond(smc_xfer_inflight(xfer, &scmi_info->inflight)); in smc_channel_lock_acquire()
121 mutex_lock(&scmi_info->shmem_lock); in smc_channel_lock_acquire()
127 atomic_set(&scmi_info->inflight, INFLIGHT_NONE); in smc_channel_lock_release()
129 mutex_unlock(&scmi_info->shmem_lock); in smc_channel_lock_release()
135 struct device *cdev = cinfo->dev; in smc_chan_setup()
143 return -ENODEV; in smc_chan_setup()
147 return -ENOMEM; in smc_chan_setup()
149 scmi_info->shmem = core->shmem->setup_iomap(cinfo, dev, tx, &res, in smc_chan_setup()
150 &scmi_info->io_ops); in smc_chan_setup()
151 if (IS_ERR(scmi_info->shmem)) in smc_chan_setup()
152 return PTR_ERR(scmi_info->shmem); in smc_chan_setup()
154 ret = of_property_read_u32(dev->of_node, "arm,smc-id", &func_id); in smc_chan_setup()
158 if (of_device_is_compatible(dev->of_node, "qcom,scmi-smc")) { in smc_chan_setup()
160 void __iomem *ptr = (void __iomem *)scmi_info->shmem + size - 8; in smc_chan_setup()
161 /* The capability-id is kept in last 8 bytes of shmem. in smc_chan_setup()
162 * +-------+ <-- 0 in smc_chan_setup()
163 * | shmem | in smc_chan_setup()
164 * +-------+ <-- size - 8 in smc_chan_setup()
166 * +-------+ <-- size in smc_chan_setup()
171 if (of_device_is_compatible(dev->of_node, "arm,scmi-smc-param")) { in smc_chan_setup()
172 scmi_info->param_page = SHMEM_PAGE(res.start); in smc_chan_setup()
173 scmi_info->param_offset = SHMEM_OFFSET(res.start); in smc_chan_setup()
180 scmi_info->irq = of_irq_get_byname(cdev->of_node, "a2p"); in smc_chan_setup()
181 if (scmi_info->irq > 0) { in smc_chan_setup()
182 ret = request_irq(scmi_info->irq, smc_msg_done_isr, in smc_chan_setup()
185 dev_err(dev, "failed to setup SCMI smc irq\n"); in smc_chan_setup()
189 cinfo->no_completion_irq = true; in smc_chan_setup()
192 scmi_info->func_id = func_id; in smc_chan_setup()
193 scmi_info->cap_id = cap_id; in smc_chan_setup()
194 scmi_info->cinfo = cinfo; in smc_chan_setup()
196 cinfo->transport_info = scmi_info; in smc_chan_setup()
204 struct scmi_smc *scmi_info = cinfo->transport_info; in smc_chan_free()
214 if (scmi_info->irq > 0) in smc_chan_free()
215 free_irq(scmi_info->irq, scmi_info); in smc_chan_free()
217 cinfo->transport_info = NULL; in smc_chan_free()
218 scmi_info->cinfo = NULL; in smc_chan_free()
226 struct scmi_smc *scmi_info = cinfo->transport_info; in smc_send_message()
235 core->shmem->tx_prepare(scmi_info->shmem, xfer, cinfo, in smc_send_message()
236 scmi_info->io_ops->toio); in smc_send_message()
238 if (scmi_info->cap_id != ULONG_MAX) in smc_send_message()
239 arm_smccc_1_1_invoke(scmi_info->func_id, scmi_info->cap_id, 0, in smc_send_message()
242 arm_smccc_1_1_invoke(scmi_info->func_id, scmi_info->param_page, in smc_send_message()
243 scmi_info->param_offset, 0, 0, 0, 0, 0, in smc_send_message()
249 return -EOPNOTSUPP; in smc_send_message()
258 struct scmi_smc *scmi_info = cinfo->transport_info; in smc_fetch_response()
260 core->shmem->fetch_response(scmi_info->shmem, xfer, in smc_fetch_response()
261 scmi_info->io_ops->fromio); in smc_fetch_response()
267 struct scmi_smc *scmi_info = cinfo->transport_info; in smc_mark_txdone()
289 * SCMI command would have been already fully processed by the SCMI
299 { .compatible = "arm,scmi-smc" },
300 { .compatible = "arm,scmi-smc-param" },
301 { .compatible = "qcom,scmi-smc" },
312 MODULE_DESCRIPTION("SCMI SMC Transport driver");