With refcounting we need to adjust framebuffer refcounts at each callsite - much easier to do if they all call the same little helper function. Signed-off-by: Daniel Vetter <daniel.vetter@xxxxxxxx> --- drivers/gpu/drm/drm_crtc.c | 19 +++++++++++++++++-- drivers/gpu/drm/drm_fb_helper.c | 6 +++--- drivers/gpu/drm/i2c/ch7006_drv.c | 2 +- drivers/gpu/drm/nouveau/nv04_display.c | 2 +- drivers/gpu/drm/nouveau/nv17_tv.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- include/drm/drm_crtc.h | 1 + 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index a9abf49..7ca2f28 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -381,7 +381,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) memset(&set, 0, sizeof(struct drm_mode_set)); set.crtc = crtc; set.fb = NULL; - ret = crtc->funcs->set_config(&set); + ret = drm_mode_set_config_internal(&set); if (ret) DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc); } @@ -1801,6 +1801,21 @@ out: } /** + * drm_mode_set_config_internal - helper to call ->set_config + * @set: modeset config to set + * + * This is a little helper to wrap internal calls to the ->set_config driver + * interface. The only thing it adds is correct refcounting dance. + */ +int drm_mode_set_config_internal(struct drm_mode_set *set) +{ + struct drm_crtc *crtc = set->crtc; + + return crtc->funcs->set_config(set); +} +EXPORT_SYMBOL(drm_mode_set_config_internal); + +/** * drm_mode_setcrtc - set CRTC configuration * @dev: drm device for the ioctl * @data: data pointer for the ioctl @@ -1963,7 +1978,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, set.connectors = connector_set; set.num_connectors = crtc_req->count_connectors; set.fb = fb; - ret = crtc->funcs->set_config(&set); + ret = drm_mode_set_config_internal(&set); out: kfree(connector_set); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 954d175..82c3a9f 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -245,7 +245,7 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) int i, ret; for (i = 0; i < fb_helper->crtc_count; i++) { struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; - ret = mode_set->crtc->funcs->set_config(mode_set); + ret = drm_mode_set_config_internal(mode_set); if (ret) error = true; } @@ -675,7 +675,7 @@ int drm_fb_helper_set_par(struct fb_info *info) mutex_lock(&dev->mode_config.mutex); for (i = 0; i < fb_helper->crtc_count; i++) { crtc = fb_helper->crtc_info[i].mode_set.crtc; - ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set); + ret = drm_mode_set_config_internal(&fb_helper->crtc_info[i].mode_set); if (ret) { mutex_unlock(&dev->mode_config.mutex); return ret; @@ -711,7 +711,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, modeset->y = var->yoffset; if (modeset->num_connectors) { - ret = crtc->funcs->set_config(modeset); + ret = drm_mode_set_config_internal(modeset); if (!ret) { info->var.xoffset = var->xoffset; info->var.yoffset = var->yoffset; diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index b865d07..51fa323 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c @@ -364,7 +364,7 @@ static int ch7006_encoder_set_property(struct drm_encoder *encoder, .crtc = crtc, }; - crtc->funcs->set_config(&modeset); + drm_mode_set_config_internal(&modeset); } } diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index 2cd6fb8..4c6e9f8 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -140,7 +140,7 @@ nv04_display_destroy(struct drm_device *dev) .crtc = crtc, }; - crtc->funcs->set_config(&modeset); + drm_mode_set_config_internal(&modeset); } /* Restore state */ diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 2ca276a..977e42b 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -768,7 +768,7 @@ static int nv17_tv_set_property(struct drm_encoder *encoder, .crtc = crtc, }; - crtc->funcs->set_config(&modeset); + drm_mode_set_config_internal(&modeset); } } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 161f8b2..07dfd82 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -829,7 +829,7 @@ static void vmw_lastclose(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { set.crtc = crtc; - ret = crtc->funcs->set_config(&set); + ret = drm_mode_set_config_internal(&set); WARN_ON(ret != 0); } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 00d78b5..665289a 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -985,6 +985,7 @@ extern int drm_mode_getcrtc(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_getconnector(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int drm_mode_set_config_internal(struct drm_mode_set *set); extern int drm_mode_setcrtc(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_getplane(struct drm_device *dev, -- 1.7.10.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel