| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2022-11-26 GuEe-GUI first version
- */
- #include "agent.h"
- #define DBG_TAG "scmi.agent"
- #define DBG_LVL DBG_INFO
- #include <rtdbg.h>
- rt_err_t rt_scmi_process_msg(struct rt_scmi_device *sdev, struct rt_scmi_msg *msg)
- {
- struct scmi_agent *agent;
- if (!sdev || !msg)
- {
- return -RT_EINVAL;
- }
- agent = sdev->agent;
- msg->sdev = sdev;
- return agent->ops->process_msg(agent, msg);
- }
- static const char * const _scmi_error_table[] =
- {
- [-SCMI_SUCCESS] = "SUCCESS",
- [-SCMI_ERR_SUPPORT] = "SUPPORT",
- [-SCMI_ERR_PARAMS] = "PARAMS",
- [-SCMI_ERR_ACCESS] = "ACCESS",
- [-SCMI_ERR_ENTRY] = "ENTRY",
- [-SCMI_ERR_RANGE] = "RANGE",
- [-SCMI_ERR_BUSY] = "BUSY",
- [-SCMI_ERR_COMMS] = "COMMS",
- [-SCMI_ERR_GENERIC] = "GENERIC",
- [-SCMI_ERR_HARDWARE] = "HARDWARE",
- [-SCMI_ERR_PROTOCOL] = "PROTOCOL",
- };
- const char *rt_scmi_strerror(rt_base_t err)
- {
- const char *str;
- err = err < 0 ? -err : err;
- if (err < RT_ARRAY_SIZE(_scmi_error_table))
- {
- str = _scmi_error_table[err];
- }
- else
- {
- str = "UNKNOWN";
- }
- return str;
- }
- static rt_err_t scmi_channels_setup(struct scmi_agent *agent,
- struct rt_platform_device *pdev)
- {
- struct rt_ofw_node *np = pdev->parent.ofw_node, *chn;
- rt_ofw_foreach_available_child_node(np, chn)
- {
- rt_uint32_t prot_id;
- struct rt_scmi_device *sdev;
- if (rt_ofw_prop_read_u32(chn, "reg", &prot_id))
- {
- continue;
- }
- sdev = rt_calloc(1, sizeof(*sdev));
- if (!sdev)
- {
- rt_ofw_node_put(chn);
- return -RT_ENOMEM;
- }
- sdev->parent.ofw_node = chn;
- sdev->protocol_id = prot_id;
- sdev->agent = agent;
- rt_scmi_device_register(sdev);
- }
- return RT_EOK;
- }
- static rt_err_t scmi_probe(struct rt_platform_device *pdev)
- {
- rt_err_t err;
- struct rt_scmi_device *base_sdev;
- struct scmi_agent *agent = rt_malloc(sizeof(*agent) + sizeof(*base_sdev));
- const struct scmi_agent_ops *agent_ops;
- if (!agent)
- {
- return -RT_ENOMEM;
- }
- agent_ops = pdev->id->data;
- agent->ops = agent_ops;
- if ((err = agent_ops->setup(agent, &pdev->parent)))
- {
- LOG_E("Setup interface %s error = %s", agent_ops->name, rt_strerror(err));
- goto _fail;
- }
- if ((err = scmi_channels_setup(agent, pdev)))
- {
- goto _fail;
- }
- base_sdev = (void *)&agent[1];
- rt_memset(base_sdev, 0, sizeof(*base_sdev));
- base_sdev->protocol_id = SCMI_PROTOCOL_ID_BASE;
- base_sdev->agent = agent;
- if ((err = rt_scmi_device_register(base_sdev)))
- {
- LOG_W("Base protocol register error = %s", rt_strerror(err));
- }
- return RT_EOK;
- _fail:
- rt_free(agent);
- return err;
- }
- extern struct rt_scmi_agent_ops scmi_agent_mailbox_ops;
- extern struct rt_scmi_agent_ops scmi_agent_smc_ops;
- extern struct rt_scmi_agent_ops scmi_agent_virtio_ops;
- static const struct rt_ofw_node_id scmi_ofw_ids[] =
- {
- #ifdef RT_FIRMWARE_ARM_SCMI_TRANSPORT_MAILBOX
- { .compatible = "arm,scmi", .data = &scmi_agent_mailbox_ops },
- #endif
- #ifdef RT_FIRMWARE_ARM_SCMI_TRANSPORT_SMC
- { .compatible = "arm,scmi-smc", .data = &scmi_agent_smc_ops },
- { .compatible = "arm,scmi-smc-param", .data = &scmi_agent_smc_ops },
- { .compatible = "qcom,scmi-smc", .data = &scmi_agent_smc_ops},
- #endif
- #ifdef RT_FIRMWARE_ARM_SCMI_TRANSPORT_VIRTIO
- { .compatible = "arm,scmi-virtio", .data = &scmi_agent_virtio_ops },
- #endif
- { /* sentinel */ }
- };
- static struct rt_platform_driver scmi_driver =
- {
- .name = "arm-scmi",
- .ids = scmi_ofw_ids,
- .probe = scmi_probe,
- };
- static int scmi_drv_register(void)
- {
- rt_platform_driver_register(&scmi_driver);
- return 0;
- }
- INIT_SUBSYS_EXPORT(scmi_drv_register);
|