From: Alice Guo <alice....@nxp.com> This patch adds SCMI pin control protocol support to make the pin controller driver based on SCMI, such as drivers/pinctrl/nxp/pinctrl-imx-scmi.c, can be bound to the SCMI agent device whose protocol id is 0x19.
Add U_BOOT_SCMI_PROTO_DRIVER() so that the SCMI agent device can choose which SCMI protocol driver to bind by the bind function of struct driver. This can avoid putting i.MX related code in scmi_agent-uclass.c. Signed-off-by: Alice Guo <alice....@nxp.com> --- drivers/firmware/scmi/scmi_agent-uclass.c | 25 +++++++++++++++++++++++++ drivers/pinctrl/nxp/pinctrl-imx-scmi.c | 7 +++++++ include/scmi_agent-uclass.h | 17 +++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c index 8c907c3b032..2ffdd5c881e 100644 --- a/drivers/firmware/scmi/scmi_agent-uclass.c +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -97,6 +97,9 @@ struct udevice *scmi_get_protocol(struct udevice *dev, case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN: proto = priv->voltagedom_dev; break; + case SCMI_PROTOCOL_ID_PINCTRL: + proto = priv->pinctrl_dev; + break; default: dev_err(dev, "Protocol not supported\n"); proto = NULL; @@ -147,6 +150,9 @@ static int scmi_add_protocol(struct udevice *dev, case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN: priv->voltagedom_dev = proto; break; + case SCMI_PROTOCOL_ID_PINCTRL: + priv->pinctrl_dev = proto; + break; default: dev_err(dev, "Protocol not supported\n"); return -EPROTO; @@ -352,6 +358,22 @@ static int scmi_fill_base_info(struct udevice *agent, struct udevice *dev) return 0; } +static struct driver *scmi_proto_driver_get(unsigned int proto_id) +{ + struct scmi_proto_driver *start, *entry; + int n_ents; + + start = ll_entry_start(struct scmi_proto_driver, scmi_proto_driver); + n_ents = ll_entry_count(struct scmi_proto_driver, scmi_proto_driver); + + for (entry = start; entry != start + n_ents; entry++) { + if (entry->match->proto_id == proto_id) + return entry->driver; + } + + return NULL; +} + /* * SCMI agent devices binds devices of various uclasses depending on * the FDT description. scmi_bind_protocol() is a generic bind sequence @@ -436,6 +458,9 @@ static int scmi_bind_protocols(struct udevice *dev) drv = DM_DRIVER_GET(scmi_voltage_domain); } break; + case SCMI_PROTOCOL_ID_PINCTRL: + drv = scmi_proto_driver_get(SCMI_PROTOCOL_ID_PINCTRL); + break; default: break; } diff --git a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c index 0ed971369a3..dbd6ff437e5 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c +++ b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c @@ -9,6 +9,7 @@ #include <dm/device_compat.h> #include <dm/pinctrl.h> #include <scmi_agent.h> +#include <scmi_agent-uclass.h> #include <scmi_protocols.h> #include "pinctrl-imx.h" @@ -150,3 +151,9 @@ U_BOOT_DRIVER(scmi_pinctrl_imx) = { .ops = &imx_scmi_pinctrl_ops, .flags = DM_FLAG_PRE_RELOC, }; + +static struct scmi_proto_match match = { + .proto_id = SCMI_PROTOCOL_ID_PINCTRL, +}; + +U_BOOT_SCMI_PROTO_DRIVER(scmi_pinctrl_imx, &match); diff --git a/include/scmi_agent-uclass.h b/include/scmi_agent-uclass.h index 33e0e18c30d..d6586eb3ff9 100644 --- a/include/scmi_agent-uclass.h +++ b/include/scmi_agent-uclass.h @@ -27,6 +27,7 @@ struct scmi_channel; * @clock_dev: SCMI clock protocol device * @resetdom_dev: SCMI reset domain protocol device * @voltagedom_dev: SCMI voltage domain protocol device + * @pinctrl_dev: SCMI pin control protocol device */ struct scmi_agent_priv { u32 version; @@ -43,6 +44,7 @@ struct scmi_agent_priv { struct udevice *clock_dev; struct udevice *resetdom_dev; struct udevice *voltagedom_dev; + struct udevice *pinctrl_dev; }; static inline u32 scmi_version(struct udevice *dev) @@ -115,4 +117,19 @@ struct scmi_agent_ops { struct scmi_msg *msg); }; +struct scmi_proto_match { + unsigned int proto_id; +}; + +struct scmi_proto_driver { + struct driver *driver; + const struct scmi_proto_match *match; +}; + +#define U_BOOT_SCMI_PROTO_DRIVER(__name, __match) \ + ll_entry_declare(struct scmi_proto_driver, __name, scmi_proto_driver) = { \ + .driver = llsym(struct driver, __name, driver), \ + .match = __match, \ + } + #endif /* _SCMI_TRANSPORT_UCLASS_H */ -- 2.43.0