Eric Anholt writes: > Many DRM drivers have common code to make a stub connector > implementation that wraps a drm_panel. By wrapping the panel in a DRM > bridge, all of the connector code (including calls during encoder > enable/disable) goes away. > > Signed-off-by: Eric Anholt > +/** > + * drm_panel_bridge_add - Creates a drm_bridge and drm_connector that > + * just call the appropriate functions from drm_panel. > + * > + * @dev: The struct device of the panel device. This is used for > + * registering the drm_bridge. > + * @panel: The drm_panel being wrapped. Must be non-NULL. > + * @connector_type: The DRM_MODE_CONNECTOR_* for the connector to be > + * created. > + * > + * For drivers converting from directly using drm_panel: The expected > + * usage pattern is that during either encoder module probe or DSI > + * host attach, a drm_panel will be looked up through > + * drm_of_find_panel_or_bridge(). drm_panel_bridge_add() is used to > + * wrap that panel in the new bridge, and the result can then be > + * passed to drm_bridge_attach(). The drm_panel_prepare() and related > + * functions can be dropped from the encoder driver (they're now > + * called by the KMS helpers before calling into the encoder), along > + * with connector creation. > + */ > +struct drm_bridge *drm_panel_bridge_add(struct device *dev, > + struct drm_panel *panel, > + u32 connector_type) > +{ > + struct panel_bridge *panel_bridge = > + devm_kzalloc(dev, sizeof(*panel_bridge), GFP_KERNEL); > + int ret; > + > + if (!dev || !panel) > + return ERR_PTR(EINVAL); > + > + panel_bridge->dev = dev; > + panel_bridge->connector_type = connector_type; > + panel_bridge->panel = panel; > + > + panel_bridge->bridge.funcs = &panel_bridge_bridge_funcs; > + panel_bridge->bridge.of_node = dev->of_node; > + > + ret = drm_bridge_add(&panel_bridge->bridge); > + if (ret) > + return ERR_PTR(ret); > + > + return &panel_bridge->bridge; > +} > +EXPORT_SYMBOL(drm_panel_bridge_add); > + > +void drm_panel_bridge_remove(struct device *dev, struct drm_bridge *bridge) > +{ > + drm_bridge_remove(bridge); > + devm_kfree(dev, bridge); > +} > +EXPORT_SYMBOL(drm_panel_bridge_remove); Working with this interface in another driver, I want to drop the "struct device" argument, since we can get the struct device from panel->dev. It keeps the user of the driver from needing to keep track of the panel/device it needs to hand to drm_panel_bridge_remove().