Message ID | 1465993109-19523-3-git-send-email-chris@chris-wilson.co.uk (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Jun 15, 2016 at 01:17:47PM +0100, Chris Wilson wrote: > If a driver wants to more precisely control its initialisation and in > particular, defer registering its interfaces with userspace until after > everything is setup, it also needs to defer registering the connectors. > As some devices need more work during registration, add a callback so > that drivers can do additional work if required for a connector. > > Correspondingly, we also require an unregister callback. > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> > Cc: Dave Airlie <airlied@redhat.com> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch> > Cc: dri-devel@lists.freedesktop.org > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> > --- > drivers/gpu/drm/drm_crtc.c | 18 ++++++++++++++++-- > include/drm/drm_crtc.h | 28 ++++++++++++++++++++++++++++ > 2 files changed, 44 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index 4ec35f9e6de5..23dfec41decb 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -990,13 +990,24 @@ int drm_connector_register(struct drm_connector *connector) > > ret = drm_debugfs_connector_add(connector); > if (ret) { > - drm_sysfs_connector_remove(connector); > - return ret; > + goto err_sysfs; > + } > + > + if (connector->funcs->late_register) { > + ret = connector->funcs->late_register(connector); > + if (ret) > + goto err_debugfs; > } > > drm_mode_object_register(connector->dev, &connector->base); > > return 0; > + > +err_debugfs: > + drm_debugfs_connector_remove(connector); > +err_sysfs: > + drm_sysfs_connector_remove(connector); > + return ret; > } > EXPORT_SYMBOL(drm_connector_register); > > @@ -1008,6 +1019,9 @@ EXPORT_SYMBOL(drm_connector_register); > */ > void drm_connector_unregister(struct drm_connector *connector) > { > + if (connector->funcs->early_unregister) > + connector->funcs->early_unregister(connector); > + > drm_sysfs_connector_remove(connector); > drm_debugfs_connector_remove(connector); > } > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index 914baa8c161d..0c35b4f73e4c 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -957,6 +957,34 @@ struct drm_connector_funcs { > uint64_t val); > > /** > + * @late_register: > + * > + * This optional hook can be used to register additional userspace > + * interfaces attached to the connector, light backlight control, i2c, > + * DP aux or similar interfaces. It is called late in the driver load > + * sequence from drm_connector_register() when registering all the > + * core drm connector interfaces. Everything added from this callback > + * should be unregistered in the early_unregister callback. > + * > + * Returns: > + * > + * 0 on success, or a negative error code on failure. > + * I went ocd and removed this line here before applying. -Daniel > + */ > + int (*late_register)(struct drm_connector *connector); > + > + /** > + * @early_unregister: > + * > + * This optional hook should be used to unregister the additional > + * userspace interfaces attached to the connector from > + * late_unregister(). It is called from drm_connector_unregister(), > + * early in the driver unload sequence to disable userspace access > + * before data structures are torndown. > + */ > + void (*early_unregister)(struct drm_connector *connector); > + > + /** > * @destroy: > * > * Clean up connector resources. This is called at driver unload time > -- > 2.8.1 >
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 4ec35f9e6de5..23dfec41decb 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -990,13 +990,24 @@ int drm_connector_register(struct drm_connector *connector) ret = drm_debugfs_connector_add(connector); if (ret) { - drm_sysfs_connector_remove(connector); - return ret; + goto err_sysfs; + } + + if (connector->funcs->late_register) { + ret = connector->funcs->late_register(connector); + if (ret) + goto err_debugfs; } drm_mode_object_register(connector->dev, &connector->base); return 0; + +err_debugfs: + drm_debugfs_connector_remove(connector); +err_sysfs: + drm_sysfs_connector_remove(connector); + return ret; } EXPORT_SYMBOL(drm_connector_register); @@ -1008,6 +1019,9 @@ EXPORT_SYMBOL(drm_connector_register); */ void drm_connector_unregister(struct drm_connector *connector) { + if (connector->funcs->early_unregister) + connector->funcs->early_unregister(connector); + drm_sysfs_connector_remove(connector); drm_debugfs_connector_remove(connector); } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 914baa8c161d..0c35b4f73e4c 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -957,6 +957,34 @@ struct drm_connector_funcs { uint64_t val); /** + * @late_register: + * + * This optional hook can be used to register additional userspace + * interfaces attached to the connector, light backlight control, i2c, + * DP aux or similar interfaces. It is called late in the driver load + * sequence from drm_connector_register() when registering all the + * core drm connector interfaces. Everything added from this callback + * should be unregistered in the early_unregister callback. + * + * Returns: + * + * 0 on success, or a negative error code on failure. + * + */ + int (*late_register)(struct drm_connector *connector); + + /** + * @early_unregister: + * + * This optional hook should be used to unregister the additional + * userspace interfaces attached to the connector from + * late_unregister(). It is called from drm_connector_unregister(), + * early in the driver unload sequence to disable userspace access + * before data structures are torndown. + */ + void (*early_unregister)(struct drm_connector *connector); + + /** * @destroy: * * Clean up connector resources. This is called at driver unload time