Message ID | 20240627071904.4017160-1-wenst@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] drm/mipi-dsi: Add OF notifier handler | expand |
Hello Chen-Yu, +Rob On Thu, 27 Jun 2024 15:19:03 +0800 Chen-Yu Tsai <wenst@chromium.org> wrote: > Add OF notifier handler needed for creating/destroying MIPI DSI devices > according to dynamic runtime changes in the DT live tree. This code is > enabled when CONFIG_OF_DYNAMIC is selected. > > This is based on existing code for I2C and SPI subsystems. > > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Thanks for copying me on this patch. Could be useful for my hotplug-bridge work, however I'm aiming at writing code that works also for non-DSI so we'll see. The code looks pretty fine however. My concern however is about the usage of an OF reconfig notifier. A few days ago Rob Herring wrote: > a notifier is never a great design so > maybe we can come up with something better (https://lore.kernel.org/all/CAL_Jsq+=mGEJXsjq1UZFMJtHko_z+doiFMXnx9K7exDuznymSA@mail.gmail.com) So maybe this is something you can clarify with him. Luca
On Fri, Jun 28, 2024 at 6:31 PM Luca Ceresoli <luca.ceresoli@bootlin.com> wrote: > > Hello Chen-Yu, > > +Rob > > On Thu, 27 Jun 2024 15:19:03 +0800 > Chen-Yu Tsai <wenst@chromium.org> wrote: > > > Add OF notifier handler needed for creating/destroying MIPI DSI devices > > according to dynamic runtime changes in the DT live tree. This code is > > enabled when CONFIG_OF_DYNAMIC is selected. > > > > This is based on existing code for I2C and SPI subsystems. > > > > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> > > Thanks for copying me on this patch. Could be useful for my > hotplug-bridge work, however I'm aiming at writing code that works also > for non-DSI so we'll see. The code looks pretty fine however. > > My concern however is about the usage of an OF reconfig notifier. A few > days ago Rob Herring wrote: > > > a notifier is never a great design so > > maybe we can come up with something better > > (https://lore.kernel.org/all/CAL_Jsq+=mGEJXsjq1UZFMJtHko_z+doiFMXnx9K7exDuznymSA@mail.gmail.com) > > So maybe this is something you can clarify with him. Well, as mentioned in the commit message, this is based on existing code found in the I2C and SPI cores. In these cases it is dealing with the status flipping from disabled to okay, which then triggers the subsystem to register a new device for the toggled device node. If a better mechanism can be developed, then the existing code along with the code I introduce here can be migrated over. ChenYu > Luca > > -- > Luca Ceresoli, Bootlin > Embedded Linux and Kernel engineering > https://bootlin.com
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index a471c46f5ca6..35d6ed1fb587 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -118,6 +118,7 @@ static void mipi_dsi_dev_release(struct device *dev) { struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); + of_node_clear_flag(dev->of_node, OF_POPULATED); of_node_put(dev->of_node); kfree(dsi); } @@ -158,6 +159,7 @@ static struct mipi_dsi_device * of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) { struct mipi_dsi_device_info info = { }; + struct mipi_dsi_device *device; int ret; u32 reg; @@ -175,10 +177,72 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) info.channel = reg; info.node = of_node_get(node); + of_node_set_flag(node, OF_POPULATED); - return mipi_dsi_device_register_full(host, &info); + device = mipi_dsi_device_register_full(host, &info); + if (IS_ERR(device)) + of_node_clear_flag(node, OF_POPULATED); + + return device; } + +#if IS_ENABLED(CONFIG_OF_DYNAMIC) +static int of_mipi_dsi_notify(struct notifier_block *nb, unsigned long action, void *arg) +{ + struct of_reconfig_data *rd = arg; + struct mipi_dsi_host *host; + struct mipi_dsi_device *device; + + switch (of_reconfig_get_state_change(action, rd)) { + case OF_RECONFIG_CHANGE_ADD: + host = of_find_mipi_dsi_host_by_node(rd->dn->parent); + if (!host) + return NOTIFY_OK; /* not for us */ + + if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) + return NOTIFY_OK; + + /* + * Clear the flag before adding the device so that fw_devlink + * doesn't skip adding consumers to this device. + */ + rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; + device = of_mipi_dsi_device_add(host, rd->dn); + if (IS_ERR(device)) { + dev_err(host->dev, "failed to create device for '%pOF'\n", rd->dn); + of_node_clear_flag(rd->dn, OF_POPULATED); + return notifier_from_errno(PTR_ERR(device)); + } + break; + case OF_RECONFIG_CHANGE_REMOVE: + /* already depopulated? */ + if (!of_node_check_flag(rd->dn, OF_POPULATED)) + return NOTIFY_OK; + + /* find our device by node */ + device = of_find_mipi_dsi_device_by_node(rd->dn); + if (!device) + return NOTIFY_OK; /* no? not meant for us */ + + /* unregister takes one ref away */ + mipi_dsi_device_unregister(device); + + /* and put the reference of the find */ + put_device(&device->dev); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block mipi_dsi_of_notifier = { + .notifier_call = of_mipi_dsi_notify, +}; +#else +static struct notifier_block mipi_dsi_of_notifier __always_unused; +#endif #else +static struct notifier_block mipi_dsi_of_notifier __always_unused; static struct mipi_dsi_device * of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) { @@ -1703,6 +1767,8 @@ EXPORT_SYMBOL(mipi_dsi_driver_unregister); static int __init mipi_dsi_bus_init(void) { + if (IS_ENABLED(CONFIG_OF_DYNAMIC)) + WARN_ON(of_reconfig_notifier_register(&mipi_dsi_of_notifier)); return bus_register(&mipi_dsi_bus_type); } postcore_initcall(mipi_dsi_bus_init);
Add OF notifier handler needed for creating/destroying MIPI DSI devices according to dynamic runtime changes in the DT live tree. This code is enabled when CONFIG_OF_DYNAMIC is selected. This is based on existing code for I2C and SPI subsystems. Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> --- Changes since v1: - Added stub mipi_dsi_of_notifier in CONFIG_OF=n section for compilation drivers/gpu/drm/drm_mipi_dsi.c | 68 +++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-)