diff options
author | Thierry Reding <treding@nvidia.com> | 2014-06-27 11:19:24 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-07-07 21:31:28 -0400 |
commit | 10a231026574f9ec9761b6435394b8830b485e4e (patch) | |
tree | ae55c7173758db2778f02bb98954e7efceee5ec0 /drivers | |
parent | 3a4938799dec32783759b0c66ee3bb8c82dd9937 (diff) |
drm: Introduce drm_fb_helper_prepare()
To implement hotplug detection in a race-free manner, drivers must call
drm_kms_helper_poll_init() before hotplug events can be triggered. Such
events can be triggered right after any of the encoders or connectors
are initialized. At the same time, if the drm_fb_helper_hotplug_event()
helper is used by a driver, then the poll helper requires some parts of
the FB helper to be initialized to prevent a crash.
At the same time, drm_fb_helper_init() requires information that is not
necessarily available at such an early stage (number of CRTCs and
connectors), so it cannot be used yet.
Add a new helper, drm_fb_helper_prepare(), that initializes the bare
minimum needed to allow drm_kms_helper_poll_init() to execute and any
subsequent hotplug events to be processed properly.
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/armada/armada_fbdev.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_fb.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/bochs/bochs_fbdev.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/cirrus/cirrus_fbdev.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fb_cma_helper.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/framebuffer.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_fbdev.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_fb.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_fbdev.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fbcon.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_fbdev.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_fb.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/fb.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_fb.c | 3 |
17 files changed, 70 insertions, 28 deletions
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index a7c947cd9386..7838e731b0de 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c | |||
@@ -149,7 +149,7 @@ int armada_fbdev_init(struct drm_device *dev) | |||
149 | 149 | ||
150 | priv->fbdev = fbh; | 150 | priv->fbdev = fbh; |
151 | 151 | ||
152 | fbh->funcs = &armada_fb_helper_funcs; | 152 | drm_fb_helper_prepare(dev, fbh, &armada_fb_helper_funcs); |
153 | 153 | ||
154 | ret = drm_fb_helper_init(dev, fbh, 1, 1); | 154 | ret = drm_fb_helper_init(dev, fbh, 1, 1); |
155 | if (ret) { | 155 | if (ret) { |
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index 2113894e4ff8..cba45c774552 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c | |||
@@ -328,8 +328,10 @@ int ast_fbdev_init(struct drm_device *dev) | |||
328 | return -ENOMEM; | 328 | return -ENOMEM; |
329 | 329 | ||
330 | ast->fbdev = afbdev; | 330 | ast->fbdev = afbdev; |
331 | afbdev->helper.funcs = &ast_fb_helper_funcs; | ||
332 | spin_lock_init(&afbdev->dirty_lock); | 331 | spin_lock_init(&afbdev->dirty_lock); |
332 | |||
333 | drm_fb_helper_prepare(dev, &afbdev->helper, &ast_fb_helper_funcs); | ||
334 | |||
333 | ret = drm_fb_helper_init(dev, &afbdev->helper, | 335 | ret = drm_fb_helper_init(dev, &afbdev->helper, |
334 | 1, 1); | 336 | 1, 1); |
335 | if (ret) { | 337 | if (ret) { |
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c index 17e5c17f2730..19cf3e9413b6 100644 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ b/drivers/gpu/drm/bochs/bochs_fbdev.c | |||
@@ -189,7 +189,8 @@ int bochs_fbdev_init(struct bochs_device *bochs) | |||
189 | { | 189 | { |
190 | int ret; | 190 | int ret; |
191 | 191 | ||
192 | bochs->fb.helper.funcs = &bochs_fb_helper_funcs; | 192 | drm_fb_helper_prepare(bochs->dev, &bochs->fb.helper, |
193 | &bochs_fb_helper_funcs); | ||
193 | 194 | ||
194 | ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper, | 195 | ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper, |
195 | 1, 1); | 196 | 1, 1); |
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c index 2bd0291168e4..2a135f253e29 100644 --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c | |||
@@ -306,9 +306,11 @@ int cirrus_fbdev_init(struct cirrus_device *cdev) | |||
306 | return -ENOMEM; | 306 | return -ENOMEM; |
307 | 307 | ||
308 | cdev->mode_info.gfbdev = gfbdev; | 308 | cdev->mode_info.gfbdev = gfbdev; |
309 | gfbdev->helper.funcs = &cirrus_fb_helper_funcs; | ||
310 | spin_lock_init(&gfbdev->dirty_lock); | 309 | spin_lock_init(&gfbdev->dirty_lock); |
311 | 310 | ||
311 | drm_fb_helper_prepare(cdev->dev, &gfbdev->helper, | ||
312 | &cirrus_fb_helper_funcs); | ||
313 | |||
312 | ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper, | 314 | ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper, |
313 | cdev->num_crtc, CIRRUSFB_CONN_LIMIT); | 315 | cdev->num_crtc, CIRRUSFB_CONN_LIMIT); |
314 | if (ret) { | 316 | if (ret) { |
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index cb01e1606384..cc0ae047ed3b 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c | |||
@@ -354,9 +354,10 @@ struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, | |||
354 | return ERR_PTR(-ENOMEM); | 354 | return ERR_PTR(-ENOMEM); |
355 | } | 355 | } |
356 | 356 | ||
357 | fbdev_cma->fb_helper.funcs = &drm_fb_cma_helper_funcs; | ||
358 | helper = &fbdev_cma->fb_helper; | 357 | helper = &fbdev_cma->fb_helper; |
359 | 358 | ||
359 | drm_fb_helper_prepare(dev, helper, &drm_fb_cma_helper_funcs); | ||
360 | |||
360 | ret = drm_fb_helper_init(dev, helper, num_crtc, max_conn_count); | 361 | ret = drm_fb_helper_init(dev, helper, num_crtc, max_conn_count); |
361 | if (ret < 0) { | 362 | if (ret < 0) { |
362 | dev_err(dev->dev, "Failed to initialize drm fb helper.\n"); | 363 | dev_err(dev->dev, "Failed to initialize drm fb helper.\n"); |
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; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index fc25fe75aa77..32e63f60e1d1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
@@ -266,7 +266,8 @@ int exynos_drm_fbdev_init(struct drm_device *dev) | |||
266 | return -ENOMEM; | 266 | return -ENOMEM; |
267 | 267 | ||
268 | private->fb_helper = helper = &fbdev->drm_fb_helper; | 268 | private->fb_helper = helper = &fbdev->drm_fb_helper; |
269 | helper->funcs = &exynos_drm_fb_helper_funcs; | 269 | |
270 | drm_fb_helper_prepare(dev, helper, &exynos_drm_fb_helper_funcs); | ||
270 | 271 | ||
271 | num_crtc = dev->mode_config.num_crtc; | 272 | num_crtc = dev->mode_config.num_crtc; |
272 | 273 | ||
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 76e4d777d01d..d0dd3bea8aa5 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c | |||
@@ -600,7 +600,8 @@ int psb_fbdev_init(struct drm_device *dev) | |||
600 | } | 600 | } |
601 | 601 | ||
602 | dev_priv->fbdev = fbdev; | 602 | dev_priv->fbdev = fbdev; |
603 | fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs; | 603 | |
604 | drm_fb_helper_prepare(dev, &fbdev->psb_fb_helper, &psb_fb_helper_funcs); | ||
604 | 605 | ||
605 | drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs, | 606 | drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs, |
606 | INTELFB_CONN_LIMIT); | 607 | INTELFB_CONN_LIMIT); |
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index c942d13cd5cb..347d16220cd0 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c | |||
@@ -623,7 +623,8 @@ int intel_fbdev_init(struct drm_device *dev) | |||
623 | if (ifbdev == NULL) | 623 | if (ifbdev == NULL) |
624 | return -ENOMEM; | 624 | return -ENOMEM; |
625 | 625 | ||
626 | ifbdev->helper.funcs = &intel_fb_helper_funcs; | 626 | drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs); |
627 | |||
627 | if (!intel_fbdev_init_bios(dev, ifbdev)) | 628 | if (!intel_fbdev_init_bios(dev, ifbdev)) |
628 | ifbdev->preferred_bpp = 32; | 629 | ifbdev->preferred_bpp = 32; |
629 | 630 | ||
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c index a4319aba9180..5451dc58eff1 100644 --- a/drivers/gpu/drm/mgag200/mgag200_fb.c +++ b/drivers/gpu/drm/mgag200/mgag200_fb.c | |||
@@ -293,9 +293,10 @@ int mgag200_fbdev_init(struct mga_device *mdev) | |||
293 | return -ENOMEM; | 293 | return -ENOMEM; |
294 | 294 | ||
295 | mdev->mfbdev = mfbdev; | 295 | mdev->mfbdev = mfbdev; |
296 | mfbdev->helper.funcs = &mga_fb_helper_funcs; | ||
297 | spin_lock_init(&mfbdev->dirty_lock); | 296 | spin_lock_init(&mfbdev->dirty_lock); |
298 | 297 | ||
298 | drm_fb_helper_prepare(mdev->dev, &mfbdev->helper, &mga_fb_helper_funcs); | ||
299 | |||
299 | ret = drm_fb_helper_init(mdev->dev, &mfbdev->helper, | 300 | ret = drm_fb_helper_init(mdev->dev, &mfbdev->helper, |
300 | mdev->num_crtc, MGAG200FB_CONN_LIMIT); | 301 | mdev->num_crtc, MGAG200FB_CONN_LIMIT); |
301 | if (ret) | 302 | if (ret) |
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 7e706c4cf033..c437065933e3 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c | |||
@@ -197,7 +197,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev) | |||
197 | 197 | ||
198 | helper = &fbdev->base; | 198 | helper = &fbdev->base; |
199 | 199 | ||
200 | helper->funcs = &msm_fb_helper_funcs; | 200 | drm_fb_helper_prepare(dev, helper, &msm_fb_helper_funcs); |
201 | 201 | ||
202 | ret = drm_fb_helper_init(dev, helper, | 202 | ret = drm_fb_helper_init(dev, helper, |
203 | priv->num_crtcs, priv->num_connectors); | 203 | priv->num_crtcs, priv->num_connectors); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 8e9c07b7fc89..afe706a20f97 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -464,7 +464,8 @@ nouveau_fbcon_init(struct drm_device *dev) | |||
464 | 464 | ||
465 | fbcon->dev = dev; | 465 | fbcon->dev = dev; |
466 | drm->fbcon = fbcon; | 466 | drm->fbcon = fbcon; |
467 | fbcon->helper.funcs = &nouveau_fbcon_helper_funcs; | 467 | |
468 | drm_fb_helper_prepare(dev, &fbcon->helper, &nouveau_fbcon_helper_funcs); | ||
468 | 469 | ||
469 | ret = drm_fb_helper_init(dev, &fbcon->helper, | 470 | ret = drm_fb_helper_init(dev, &fbcon->helper, |
470 | dev->mode_config.num_crtc, 4); | 471 | dev->mode_config.num_crtc, 4); |
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 4cb12083eb12..8436c6857cda 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c | |||
@@ -325,7 +325,7 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev) | |||
325 | 325 | ||
326 | helper = &fbdev->base; | 326 | helper = &fbdev->base; |
327 | 327 | ||
328 | helper->funcs = &omap_fb_helper_funcs; | 328 | drm_fb_helper_prepare(dev, helper, &omap_fb_helper_funcs); |
329 | 329 | ||
330 | ret = drm_fb_helper_init(dev, helper, | 330 | ret = drm_fb_helper_init(dev, helper, |
331 | priv->num_crtcs, priv->num_connectors); | 331 | priv->num_crtcs, priv->num_connectors); |
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index cf89614c72be..df567888bb1e 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c | |||
@@ -676,9 +676,12 @@ int qxl_fbdev_init(struct qxl_device *qdev) | |||
676 | 676 | ||
677 | qfbdev->qdev = qdev; | 677 | qfbdev->qdev = qdev; |
678 | qdev->mode_info.qfbdev = qfbdev; | 678 | qdev->mode_info.qfbdev = qfbdev; |
679 | qfbdev->helper.funcs = &qxl_fb_helper_funcs; | ||
680 | spin_lock_init(&qfbdev->delayed_ops_lock); | 679 | spin_lock_init(&qfbdev->delayed_ops_lock); |
681 | INIT_LIST_HEAD(&qfbdev->delayed_ops); | 680 | INIT_LIST_HEAD(&qfbdev->delayed_ops); |
681 | |||
682 | drm_fb_helper_prepare(qdev->ddev, &qfbdev->helper, | ||
683 | &qxl_fb_helper_funcs); | ||
684 | |||
682 | ret = drm_fb_helper_init(qdev->ddev, &qfbdev->helper, | 685 | ret = drm_fb_helper_init(qdev->ddev, &qfbdev->helper, |
683 | qxl_num_crtc /* num_crtc - QXL supports just 1 */, | 686 | qxl_num_crtc /* num_crtc - QXL supports just 1 */, |
684 | QXLFB_CONN_LIMIT); | 687 | QXLFB_CONN_LIMIT); |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index ad97afdbc4c7..db598d712901 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -353,7 +353,9 @@ int radeon_fbdev_init(struct radeon_device *rdev) | |||
353 | 353 | ||
354 | rfbdev->rdev = rdev; | 354 | rfbdev->rdev = rdev; |
355 | rdev->mode_info.rfbdev = rfbdev; | 355 | rdev->mode_info.rfbdev = rfbdev; |
356 | rfbdev->helper.funcs = &radeon_fb_helper_funcs; | 356 | |
357 | drm_fb_helper_prepare(rdev->ddev, &rfbdev->helper, | ||
358 | &radeon_fb_helper_funcs); | ||
357 | 359 | ||
358 | ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper, | 360 | ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper, |
359 | rdev->num_crtc, | 361 | rdev->num_crtc, |
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index f7cf47bf0afb..d5d53aa79ced 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c | |||
@@ -276,7 +276,6 @@ static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm, | |||
276 | unsigned int num_crtc, | 276 | unsigned int num_crtc, |
277 | unsigned int max_connectors) | 277 | unsigned int max_connectors) |
278 | { | 278 | { |
279 | struct drm_fb_helper *helper; | ||
280 | struct tegra_fbdev *fbdev; | 279 | struct tegra_fbdev *fbdev; |
281 | int err; | 280 | int err; |
282 | 281 | ||
@@ -286,8 +285,7 @@ static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm, | |||
286 | return ERR_PTR(-ENOMEM); | 285 | return ERR_PTR(-ENOMEM); |
287 | } | 286 | } |
288 | 287 | ||
289 | fbdev->base.funcs = &tegra_fb_helper_funcs; | 288 | drm_fb_helper_prepare(drm, &fbdev->base, &tegra_fb_helper_funcs); |
290 | helper = &fbdev->base; | ||
291 | 289 | ||
292 | err = drm_fb_helper_init(drm, &fbdev->base, num_crtc, max_connectors); | 290 | err = drm_fb_helper_init(drm, &fbdev->base, num_crtc, max_connectors); |
293 | if (err < 0) { | 291 | if (err < 0) { |
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 0647c8cc368b..d1da339843ca 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c | |||
@@ -583,7 +583,8 @@ int udl_fbdev_init(struct drm_device *dev) | |||
583 | return -ENOMEM; | 583 | return -ENOMEM; |
584 | 584 | ||
585 | udl->fbdev = ufbdev; | 585 | udl->fbdev = ufbdev; |
586 | ufbdev->helper.funcs = &udl_fb_helper_funcs; | 586 | |
587 | drm_fb_helper_prepare(dev, &ufbdev->helper, &udl_fb_helper_funcs); | ||
587 | 588 | ||
588 | ret = drm_fb_helper_init(dev, &ufbdev->helper, | 589 | ret = drm_fb_helper_init(dev, &ufbdev->helper, |
589 | 1, 1); | 590 | 1, 1); |