/* * The shmem address is split into 4K page and offset. * This is to make sure the parameters fit in 32bit arguments of the * smc/hvc call to keep it uniform across smc32/smc64 conventions. * This however limits the shmem address to 44 bit. * * These optional parameters can be used to distinguish among multiple * scmi instances that are using the same smc-id. * The page parameter is passed in r1/x1/w1 register and the offset parameter * is passed in r2/x2/w2 register.
*/
/** * struct scmi_smc - Structure representing a SCMI smc transport * * @irq: An optional IRQ for completion * @cinfo: SCMI channel info * @shmem: Transmit/Receive shared memory area * @io_ops: Transport specific I/O operations * @shmem_lock: Lock to protect access to Tx/Rx shared memory area. * Used when NOT operating in atomic mode. * @inflight: Atomic flag to protect access to Tx/Rx shared memory area. * Used when operating in atomic mode. * @func_id: smc/hvc call function id * @param_page: 4K page number of the shmem channel * @param_offset: Offset within the 4K page of the shmem channel * @cap_id: smc/hvc doorbell's capability id to be used on Qualcomm virtual * platforms
*/
ret = of_property_read_u32(dev->of_node, "arm,smc-id", &func_id); if (ret < 0) return ret;
if (of_device_is_compatible(dev->of_node, "qcom,scmi-smc")) {
resource_size_t size = resource_size(&res); void __iomem *ptr = (void __iomem *)scmi_info->shmem + size - 8; /* The capability-id is kept in last 8 bytes of shmem. * +-------+ <-- 0 * | shmem | * +-------+ <-- size - 8 * | capId | * +-------+ <-- size
*/
memcpy_fromio(&cap_id, ptr, sizeof(cap_id));
}
if (of_device_is_compatible(dev->of_node, "arm,scmi-smc-param")) {
scmi_info->param_page = SHMEM_PAGE(res.start);
scmi_info->param_offset = SHMEM_OFFSET(res.start);
} /* * If there is an interrupt named "a2p", then the service and * completion of a message is signaled by an interrupt rather than by * the return of the SMC call.
*/
scmi_info->irq = of_irq_get_byname(cdev->of_node, "a2p"); if (scmi_info->irq > 0) {
ret = request_irq(scmi_info->irq, smc_msg_done_isr,
IRQF_NO_SUSPEND, dev_name(dev), scmi_info); if (ret) {
dev_err(dev, "failed to setup SCMI smc irq\n"); return ret;
}
} else {
cinfo->no_completion_irq = true;
}
/* * Different protocols might share the same chan info, so a previous * smc_chan_free call might have already freed the structure.
*/ if (!scmi_info) return0;
/* Ignore any possible further reception on the IRQ path */ if (scmi_info->irq > 0)
free_irq(scmi_info->irq, scmi_info);
/* * Channel will be released only once response has been * surely fully retrieved, so after .mark_txdone()
*/
smc_channel_lock_acquire(scmi_info, xfer);
staticstruct scmi_desc scmi_smc_desc = {
.ops = &scmi_smc_ops,
.max_rx_timeout_ms = 30,
.max_msg = 20,
.max_msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE, /* * Setting .sync_cmds_atomic_replies to true for SMC assumes that, * once the SMC instruction has completed successfully, the issued * SCMI command would have been already fully processed by the SCMI * platform firmware and so any possible response value expected * for the issued command will be immmediately ready to be fetched * from the shared memory area.
*/
.sync_cmds_completed_on_ret = true,
.atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE),
};
MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
MODULE_AUTHOR("Nikunj Kela <quic_nkela@quicinc.com>");
MODULE_DESCRIPTION("SCMI SMC Transport driver");
MODULE_LICENSE("GPL");
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-07)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.