From c777990fb45b574b967d982986dd2dea8bb85643 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Mon, 30 Oct 2017 16:39:37 +0100 Subject: drm/fb-helper: Handle function NULL argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make functions tolerate that the drm_fb_helper argument is NULL. This is useful for drivers that continue probing when fbdev emulation fails and not having to do this check themselves. Update docs for functions that already handles this. Signed-off-by: Noralf Trønnes Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171030153951.56269-2-noralf@tronnes.org --- drivers/gpu/drm/drm_fb_helper.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/drm_fb_helper.c') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 116d1f1337c7..954cdd48de92 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -150,6 +150,9 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, { int err; + if (!fb_helper) + return 0; + mutex_lock(&fb_helper->lock); err = __drm_fb_helper_add_one_connector(fb_helper, connector); mutex_unlock(&fb_helper->lock); @@ -161,7 +164,7 @@ EXPORT_SYMBOL(drm_fb_helper_add_one_connector); /** * drm_fb_helper_single_add_all_connectors() - add all connectors to fbdev * emulation helper - * @fb_helper: fbdev initialized with drm_fb_helper_init + * @fb_helper: fbdev initialized with drm_fb_helper_init, can be NULL * * This functions adds all the available connectors for use with the given * fb_helper. This is a separate step to allow drivers to freely assign @@ -179,7 +182,7 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) struct drm_connector_list_iter conn_iter; int i, ret = 0; - if (!drm_fbdev_emulation) + if (!drm_fbdev_emulation || !fb_helper) return 0; mutex_lock(&fb_helper->lock); @@ -245,6 +248,9 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, { int err; + if (!fb_helper) + return 0; + mutex_lock(&fb_helper->lock); err = __drm_fb_helper_remove_one_connector(fb_helper, connector); mutex_unlock(&fb_helper->lock); @@ -484,7 +490,7 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper) /** * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration - * @fb_helper: fbcon to restore + * @fb_helper: driver-allocated fbdev helper, can be NULL * * This should be called from driver's drm &drm_driver.lastclose callback * when implementing an fbcon on top of kms using this helper. This ensures that @@ -498,7 +504,7 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) bool do_delayed; int ret; - if (!drm_fbdev_emulation) + if (!drm_fbdev_emulation || !fb_helper) return -ENODEV; if (READ_ONCE(fb_helper->deferred_setup)) @@ -883,7 +889,7 @@ EXPORT_SYMBOL(drm_fb_helper_alloc_fbi); /** * drm_fb_helper_unregister_fbi - unregister fb_info framebuffer device - * @fb_helper: driver-allocated fbdev helper + * @fb_helper: driver-allocated fbdev helper, can be NULL * * A wrapper around unregister_framebuffer, to release the fb_info * framebuffer device. This must be called before releasing all resources for @@ -898,7 +904,7 @@ EXPORT_SYMBOL(drm_fb_helper_unregister_fbi); /** * drm_fb_helper_fini - finialize a &struct drm_fb_helper - * @fb_helper: driver-allocated fbdev helper + * @fb_helper: driver-allocated fbdev helper, can be NULL * * This cleans up all remaining resources associated with @fb_helper. Must be * called after drm_fb_helper_unlink_fbi() was called. @@ -937,7 +943,7 @@ EXPORT_SYMBOL(drm_fb_helper_fini); /** * drm_fb_helper_unlink_fbi - wrapper around unlink_framebuffer - * @fb_helper: driver-allocated fbdev helper + * @fb_helper: driver-allocated fbdev helper, can be NULL * * A wrapper around unlink_framebuffer implemented by fbdev core */ @@ -1138,7 +1144,7 @@ EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); /** * drm_fb_helper_set_suspend - wrapper around fb_set_suspend - * @fb_helper: driver-allocated fbdev helper + * @fb_helper: driver-allocated fbdev helper, can be NULL * @suspend: whether to suspend or resume * * A wrapper around fb_set_suspend implemented by fbdev core. @@ -1155,7 +1161,7 @@ EXPORT_SYMBOL(drm_fb_helper_set_suspend); /** * drm_fb_helper_set_suspend_unlocked - wrapper around fb_set_suspend that also * takes the console lock - * @fb_helper: driver-allocated fbdev helper + * @fb_helper: driver-allocated fbdev helper, can be NULL * @suspend: whether to suspend or resume * * A wrapper around fb_set_suspend() that takes the console lock. If the lock @@ -2568,7 +2574,7 @@ EXPORT_SYMBOL(drm_fb_helper_initial_config); /** * drm_fb_helper_hotplug_event - respond to a hotplug notification by * probing all the outputs attached to the fb - * @fb_helper: the drm_fb_helper + * @fb_helper: driver-allocated fbdev helper, can be NULL * * Scan the connectors attached to the fb_helper and try to put together a * setup after notification of a change in output configuration. @@ -2590,7 +2596,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) { int err = 0; - if (!drm_fbdev_emulation) + if (!drm_fbdev_emulation || !fb_helper) return 0; mutex_lock(&fb_helper->lock); -- cgit v1.2.3 From 29ad20b22c8f3ab35e91c2f68b4c7956cee30fd0 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Mon, 30 Oct 2017 16:39:38 +0100 Subject: drm: Add drm_device->fb_helper pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_fb_helper is *the* way of doing fbdev emulation so add a pointer to struct drm_device. This makes it possible to add callback helpers for .last_close and .output_poll_changed further reducing fbdev emulation footprint in drivers. The pointer is set by drm_fb_helper_init() and cleared by drm_fb_helper_fini(). Signed-off-by: Noralf Trønnes Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171030153951.56269-3-noralf@tronnes.org --- drivers/gpu/drm/drm_fb_helper.c | 13 +++++++++++-- include/drm/drm_device.h | 9 +++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/drm_fb_helper.c') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 954cdd48de92..19aaca9fea06 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -799,8 +799,10 @@ int drm_fb_helper_init(struct drm_device *dev, struct drm_mode_config *config = &dev->mode_config; int i; - if (!drm_fbdev_emulation) + if (!drm_fbdev_emulation) { + dev->fb_helper = fb_helper; return 0; + } if (!max_conn_count) return -EINVAL; @@ -835,6 +837,8 @@ int drm_fb_helper_init(struct drm_device *dev, i++; } + dev->fb_helper = fb_helper; + return 0; out_free: drm_fb_helper_crtc_free(fb_helper); @@ -913,7 +917,12 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) { struct fb_info *info; - if (!drm_fbdev_emulation || !fb_helper) + if (!fb_helper) + return; + + fb_helper->dev->fb_helper = NULL; + + if (!drm_fbdev_emulation) return; cancel_work_sync(&fb_helper->resume_work); diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index e21af87a2f3c..7c4fa32f3fc6 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -17,6 +17,7 @@ struct drm_vblank_crtc; struct drm_sg_mem; struct drm_local_map; struct drm_vma_offset_manager; +struct drm_fb_helper; struct inode; @@ -185,6 +186,14 @@ struct drm_device { struct drm_vma_offset_manager *vma_offset_manager; /*@} */ int switch_power_state; + + /** + * @fb_helper: + * + * Pointer to the fbdev emulation structure. + * Set by drm_fb_helper_init() and cleared by drm_fb_helper_fini(). + */ + struct drm_fb_helper *fb_helper; }; #endif -- cgit v1.2.3 From 304a4f6accac4add4967fc062069fc8421c46aae Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Mon, 30 Oct 2017 16:39:39 +0100 Subject: drm/fb-helper: Add .last_close and .output_poll_changed helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds helpers for the drm_driver->last_close and the drm_mode_config_funcs->output_poll_changed callbacks. Signed-off-by: Noralf Trønnes Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171030153951.56269-4-noralf@tronnes.org --- drivers/gpu/drm/drm_fb_helper.c | 28 ++++++++++++++++++++++++++++ include/drm/drm_fb_helper.h | 11 +++++++++++ 2 files changed, 39 insertions(+) (limited to 'drivers/gpu/drm/drm_fb_helper.c') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 19aaca9fea06..defd6a76fef3 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2633,6 +2633,34 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_hotplug_event); +/** + * drm_fb_helper_lastclose - DRM driver lastclose helper for fbdev emulation + * @dev: DRM device + * + * This function can be used as the &drm_driver->lastclose callback for drivers + * that only need to call drm_fb_helper_restore_fbdev_mode_unlocked(). + */ +void drm_fb_helper_lastclose(struct drm_device *dev) +{ + drm_fb_helper_restore_fbdev_mode_unlocked(dev->fb_helper); +} +EXPORT_SYMBOL(drm_fb_helper_lastclose); + +/** + * drm_fb_helper_output_poll_changed - DRM mode config \.output_poll_changed + * helper for fbdev emulation + * @dev: DRM device + * + * This function can be used as the + * &drm_mode_config_funcs.output_poll_changed callback for drivers that only + * need to call drm_fb_helper_hotplug_event(). + */ +void drm_fb_helper_output_poll_changed(struct drm_device *dev) +{ + drm_fb_helper_hotplug_event(dev->fb_helper); +} +EXPORT_SYMBOL(drm_fb_helper_output_poll_changed); + /* The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT) * but the module doesn't depend on any fb console symbols. At least * attempt to load fbcon to avoid leaving the system without a usable console. diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 33fe95927742..877e5b395c02 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -310,6 +310,9 @@ drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn); int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector); int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector); + +void drm_fb_helper_lastclose(struct drm_device *dev); +void drm_fb_helper_output_poll_changed(struct drm_device *dev); #else static inline void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, @@ -507,6 +510,14 @@ drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, return 0; } +static inline void drm_fb_helper_lastclose(struct drm_device *dev) +{ +} + +static inline void drm_fb_helper_output_poll_changed(struct drm_device *dev) +{ +} + #endif static inline int -- cgit v1.2.3