Messages in this thread Patch in this message | | | From | Cristian Marussi <> | Subject | [PATCH 2/5] firmware: arm_scmi: Support only one single SystemPower device | Date | Thu, 23 Jun 2022 13:47:39 +0100 |
| |
In order to minimize SCMI platform fw-side complexity, only one single SCMI platform should be in charge of SCMI SystemPower protocol communications with the OSPM: enforce the existence of one single unique device associated with SystemPower protocol across any possible number of SCMI platforms, and warn if a system tries to register different SystemPower devices from multiple platforms.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> --- drivers/firmware/arm_scmi/bus.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index a7cbf4d09081..476855d3dccb 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -19,6 +19,11 @@ static DEFINE_IDA(scmi_bus_id); static DEFINE_IDR(scmi_protocols); static DEFINE_SPINLOCK(protocol_lock); +/* Track globally the creation of SCMI SystemPower related devices */ +static bool scmi_syspower_registered; +/* Protect access to scmi_syspower_registered */ +static DEFINE_MUTEX(scmi_syspower_mtx); + static const struct scmi_device_id * scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv) { @@ -207,11 +212,31 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol, scmi_dev->dev.release = scmi_device_release; dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id); + mutex_lock(&scmi_syspower_mtx); + if (protocol == SCMI_PROTOCOL_SYSTEM && scmi_syspower_registered) { + dev_warn(parent, + "SCMI SystemPower protocol device must be unique !\n"); + + mutex_unlock(&scmi_syspower_mtx); + ida_free(&scmi_bus_id, id); + kfree_const(scmi_dev->name); + kfree(scmi_dev); + return NULL; + } + retval = device_register(&scmi_dev->dev); - if (retval) + if (retval) { + mutex_unlock(&scmi_syspower_mtx); goto put_dev; + } + + if (protocol == SCMI_PROTOCOL_SYSTEM) + scmi_syspower_registered = true; + + mutex_unlock(&scmi_syspower_mtx); return scmi_dev; + put_dev: kfree_const(scmi_dev->name); put_device(&scmi_dev->dev); @@ -221,6 +246,10 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol, void scmi_device_destroy(struct scmi_device *scmi_dev) { + mutex_lock(&scmi_syspower_mtx); + if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM) + scmi_syspower_registered = false; + mutex_unlock(&scmi_syspower_mtx); kfree_const(scmi_dev->name); scmi_handle_put(scmi_dev->handle); ida_free(&scmi_bus_id, scmi_dev->id); -- 2.32.0
| |