In a normal Greybus topology, the enumeration of an interface would start with a "Module Inserted" event, issued by the SVC. In a point-to-point configuration, the SVC is absent and the host device must enumerate the module manually.
In order to do so, export a new function that lets the host device driver start the enumeration. Note that this function issues commands to the module in a blocking way and should not be called in a probe function, but should rather be called from a workqueue.
Signed-off-by: Damien Riégel damien.riegel@silabs.com --- drivers/greybus/hd.c | 30 ++++++++++++++++++++++++++++++ include/linux/greybus/hd.h | 2 ++ 2 files changed, 32 insertions(+)
diff --git a/drivers/greybus/hd.c b/drivers/greybus/hd.c index 2fc9fbe987f..165775b6b8b 100644 --- a/drivers/greybus/hd.c +++ b/drivers/greybus/hd.c @@ -132,6 +132,36 @@ const struct device_type greybus_hd_type = { .release = gb_hd_release, };
+int gb_hd_p2p_probe_module(struct gb_host_device *hd) +{ + struct gb_module *module; + int ret; + + if (!gb_hd_is_p2p(hd)) + return -EOPNOTSUPP; + + /* In P2P mode, only one module is supported. */ + if (!list_empty(&hd->modules)) + return -EBUSY; + + module = gb_module_create_p2p(hd); + if (!module) { + dev_err(&hd->dev, "failed to create module\n"); + return -ENOMEM; + } + + ret = gb_module_add(module); + if (ret) { + gb_module_put(module); + return ret; + } + + list_add(&module->hd_node, &hd->modules); + + return 0; +} +EXPORT_SYMBOL_GPL(gb_hd_p2p_probe_module); + struct gb_host_device *gb_hd_create_p2p(struct gb_hd_driver *driver, struct device *parent, size_t buffer_size_max, diff --git a/include/linux/greybus/hd.h b/include/linux/greybus/hd.h index 28ee7fca1d1..096b9642d11 100644 --- a/include/linux/greybus/hd.h +++ b/include/linux/greybus/hd.h @@ -83,6 +83,8 @@ void gb_hd_put(struct gb_host_device *hd); int gb_hd_output(struct gb_host_device *hd, void *req, u16 size, u8 cmd, bool in_irq);
+int gb_hd_p2p_probe_module(struct gb_host_device *hd); + int gb_hd_init(void); void gb_hd_exit(void);