Skip to content

Commit

Permalink
firmware: arm_scmi: Add dynamic scmi devices creation
Browse files Browse the repository at this point in the history
Having added the support for SCMI protocols as modules in order to let
vendors extend the SCMI core with their own additions it seems odd to
then force SCMI drivers built on top to use a static device table to
declare their devices since this way any new SCMI drivers addition
would need the core SCMI device table to be updated too.

Remove the static core device table and let SCMI drivers to simply declare
which device/protocol pair they need at initialization time: the core will
then take care to generate such devices dynamically during platform
initialization or at module loading time, as long as the requested
underlying protocol is defined in the devicetree.

Link: https://lore.kernel.org/r/20210316124903.35011-39-cristian.marussi@arm.com
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
  • Loading branch information
Cristian Marussi authored and Sudeep Holla committed Mar 30, 2021
1 parent f5800e0 commit d4f9ddd
Show file tree
Hide file tree
Showing 3 changed files with 311 additions and 34 deletions.
30 changes: 30 additions & 0 deletions drivers/firmware/arm_scmi/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,31 @@ static int scmi_dev_match(struct device *dev, struct device_driver *drv)
return 0;
}

static int scmi_match_by_id_table(struct device *dev, void *data)
{
struct scmi_device *sdev = to_scmi_dev(dev);
struct scmi_device_id *id_table = data;

return sdev->protocol_id == id_table->protocol_id &&
!strcmp(sdev->name, id_table->name);
}

struct scmi_device *scmi_child_dev_find(struct device *parent,
int prot_id, const char *name)
{
struct scmi_device_id id_table;
struct device *dev;

id_table.protocol_id = prot_id;
id_table.name = name;

dev = device_find_child(parent, &id_table, scmi_match_by_id_table);
if (!dev)
return NULL;

return to_scmi_dev(dev);
}

const struct scmi_protocol *scmi_protocol_get(int protocol_id)
{
const struct scmi_protocol *proto;
Expand Down Expand Up @@ -114,6 +139,10 @@ int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
{
int retval;

retval = scmi_protocol_device_request(driver->id_table);
if (retval)
return retval;

driver->driver.bus = &scmi_bus_type;
driver->driver.name = driver->name;
driver->driver.owner = owner;
Expand All @@ -130,6 +159,7 @@ EXPORT_SYMBOL_GPL(scmi_driver_register);
void scmi_driver_unregister(struct scmi_driver *driver)
{
driver_unregister(&driver->driver);
scmi_protocol_device_unrequest(driver->id_table);
}
EXPORT_SYMBOL_GPL(scmi_driver_unregister);

Expand Down
5 changes: 5 additions & 0 deletions drivers/firmware/arm_scmi/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ struct scmi_transport_ops {
bool (*poll_done)(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer);
};

int scmi_protocol_device_request(const struct scmi_device_id *id_table);
void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table);
struct scmi_device *scmi_child_dev_find(struct device *parent,
int prot_id, const char *name);

/**
* struct scmi_desc - Description of SoC integration
*
Expand Down
Loading

0 comments on commit d4f9ddd

Please sign in to comment.