diff options
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 47 |
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 | */ | ||
553 | void 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 | } | ||
560 | EXPORT_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; |