aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fb_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 6cd687a20cd5..bdee6eb0b24a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -49,10 +49,11 @@ static LIST_HEAD(kernel_fb_helper_list);
49 * helper functions used by many drivers to implement the kernel mode setting 49 * helper functions used by many drivers to implement the kernel mode setting
50 * interfaces. 50 * interfaces.
51 * 51 *
52 * Initialization is done as a three-step process with drm_fb_helper_init(), 52 * Initialization is done as a four-step process with drm_fb_helper_prepare(),
53 * drm_fb_helper_single_add_all_connectors() and drm_fb_helper_initial_config(). 53 * drm_fb_helper_init(), drm_fb_helper_single_add_all_connectors() and
54 * Drivers with fancier requirements than the default behaviour can override the 54 * drm_fb_helper_initial_config(). Drivers with fancier requirements than the
55 * second step with their own code. Teardown is done with drm_fb_helper_fini(). 55 * default behaviour can override the third step with their own code.
56 * Teardown is done with drm_fb_helper_fini().
56 * 57 *
57 * At runtime drivers should restore the fbdev console by calling 58 * At runtime drivers should restore the fbdev console by calling
58 * drm_fb_helper_restore_fbdev_mode() from their ->lastclose callback. They 59 * drm_fb_helper_restore_fbdev_mode() from their ->lastclose callback. They
@@ -63,6 +64,19 @@ static LIST_HEAD(kernel_fb_helper_list);
63 * 64 *
64 * All other functions exported by the fb helper library can be used to 65 * All other functions exported by the fb helper library can be used to
65 * implement the fbdev driver interface by the driver. 66 * implement the fbdev driver interface by the driver.
67 *
68 * It is possible, though perhaps somewhat tricky, to implement race-free
69 * hotplug detection using the fbdev helpers. The drm_fb_helper_prepare()
70 * helper must be called first to initialize the minimum required to make
71 * hotplug detection work. Drivers also need to make sure to properly set up
72 * the dev->mode_config.funcs member. After calling drm_kms_helper_poll_init()
73 * it is safe to enable interrupts and start processing hotplug events. At the
74 * same time, drivers should initialize all modeset objects such as CRTCs,
75 * encoders and connectors. To finish up the fbdev helper initialization, the
76 * drm_fb_helper_init() function is called. To probe for all attached displays
77 * and set up an initial configuration using the detected hardware, drivers
78 * should call drm_fb_helper_single_add_all_connectors() followed by
79 * drm_fb_helper_initial_config().
66 */ 80 */
67 81
68/** 82/**
@@ -528,6 +542,24 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
528} 542}
529 543
530/** 544/**
545 * drm_fb_helper_prepare - setup a drm_fb_helper structure
546 * @dev: DRM device
547 * @helper: driver-allocated fbdev helper structure to set up
548 * @funcs: pointer to structure of functions associate with this helper
549 *
550 * Sets up the bare minimum to make the framebuffer helper usable. This is
551 * useful to implement race-free initialization of the polling helpers.
552 */
553void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
554 const struct drm_fb_helper_funcs *funcs)
555{
556 INIT_LIST_HEAD(&helper->kernel_fb_list);
557 helper->funcs = funcs;
558 helper->dev = dev;
559}
560EXPORT_SYMBOL(drm_fb_helper_prepare);
561
562/**
531 * drm_fb_helper_init - initialize a drm_fb_helper structure 563 * drm_fb_helper_init - initialize a drm_fb_helper structure
532 * @dev: drm device 564 * @dev: drm device
533 * @fb_helper: driver-allocated fbdev helper structure to initialize 565 * @fb_helper: driver-allocated fbdev helper structure to initialize
@@ -539,8 +571,7 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
539 * nor register the fbdev. This is only done in drm_fb_helper_initial_config() 571 * nor register the fbdev. This is only done in drm_fb_helper_initial_config()
540 * to allow driver writes more control over the exact init sequence. 572 * to allow driver writes more control over the exact init sequence.
541 * 573 *
542 * Drivers must set fb_helper->funcs before calling 574 * Drivers must call drm_fb_helper_prepare() before calling this function.
543 * drm_fb_helper_initial_config().
544 * 575 *
545 * RETURNS: 576 * RETURNS:
546 * Zero if everything went ok, nonzero otherwise. 577 * Zero if everything went ok, nonzero otherwise.
@@ -555,10 +586,6 @@ int drm_fb_helper_init(struct drm_device *dev,
555 if (!max_conn_count) 586 if (!max_conn_count)
556 return -EINVAL; 587 return -EINVAL;
557 588
558 fb_helper->dev = dev;
559
560 INIT_LIST_HEAD(&fb_helper->kernel_fb_list);
561
562 fb_helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL); 589 fb_helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
563 if (!fb_helper->crtc_info) 590 if (!fb_helper->crtc_info)
564 return -ENOMEM; 591 return -ENOMEM;