DRM drivers using drm_fb_helpers still call some fbdev core functions. This makes the driver depend on CONFIG_FB, resulting in complicated Kconfig options, and preventing us from creating a top level drm config option to enable/disable FBDEV emulation.
Create new drm_fb_helper functions that replace these fbdev functions.
In most cases, the new helper funcs simply wrap around the original fbdev functions. For a few (like framebufer_alloc), we actually do some work that is currently redundant across multiple drivers.
With these patches, the drivers don't call any fbdev functions directly. They are now called through functions in drm_fb_helper.c. We will later create a fbdev emulation config option to stub out the fb helpers.
The only exception is vmwgfx driver. This doesn't use drm_fb_helper. It creates a fb device how a driver in drivers/video/fbdev would. Maybe this needs to be converted to use drm_fb_helpers.
For more info, have a look at the threads: http://lists.freedesktop.org/archives/dri-devel/2015-March/078729.html http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html
Archit Taneja (25): drm/fb_helper: Add drm_fb_helper functions to manage fb_info creation drm/fb_helper: Create a wrapper for unlink_framebuffer drm/fb_helper: Create wrappers for fb_sys_read/write funcs drm/fb_helper: Create wrappers for blit, copyarea and fillrect funcs drm/fb_helper: Create a wrapper for fb_set_suspend drm/fb_helper: Create a wrapper for remove_conflicting_framebuffers drm/cirrus: Use new drm_fb_helper functions drm/rockchip: Use new drm_fb_helper functions drm/armada: Use new drm_fb_helper functions drm/ast: Use new drm_fb_helper functions drm/omap: Use new drm_fb_helper functions drm/tegra: Use new drm_fb_helper functions drm/msm: Use new drm_fb_helper functions drm/exynos: Use new drm_fb_helper functions drm/gma500: Use new drm_fb_helper functions drm/mgag200: Use new drm_fb_helper functions drm/radeon: Use new drm_fb_helper functions drm/qxl: Use new drm_fb_helper functions drm/i915: Use new drm_fb_helper functions drm/nouveau: Use new drm_fb_helper functions drm/udl: Use new drm_fb_helper functions drm/boschs: Use new drm_fb_helper functions drm/amdgpu: Use new drm_fb_helper functions drm/virtio: Use new drm_fb_helper functions drm/fb_cma_helper: Use new drm_fb_helper functions
drivers/gpu/drm/Kconfig | 7 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 43 +++----- drivers/gpu/drm/armada/armada_fbdev.c | 33 ++---- drivers/gpu/drm/ast/ast_fb.c | 47 +++------ drivers/gpu/drm/bochs/bochs_drv.c | 6 +- drivers/gpu/drm/bochs/bochs_fbdev.c | 34 ++---- drivers/gpu/drm/cirrus/cirrus_drv.c | 7 +- drivers/gpu/drm/cirrus/cirrus_fbdev.c | 39 ++----- drivers/gpu/drm/drm_fb_cma_helper.c | 45 ++------ drivers/gpu/drm/drm_fb_helper.c | 142 ++++++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 45 +++----- drivers/gpu/drm/gma500/accel_2d.c | 6 +- drivers/gpu/drm/gma500/framebuffer.c | 47 +++------ drivers/gpu/drm/i915/i915_dma.c | 3 +- drivers/gpu/drm/i915/intel_fbdev.c | 40 +++----- drivers/gpu/drm/mgag200/mgag200_drv.c | 3 +- drivers/gpu/drm/mgag200/mgag200_fb.c | 36 ++----- drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 34 ++---- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 38 +++---- drivers/gpu/drm/omapdrm/omap_fbdev.c | 34 ++---- drivers/gpu/drm/qxl/qxl_fb.c | 40 +++----- drivers/gpu/drm/radeon/radeon_drv.c | 4 +- drivers/gpu/drm/radeon/radeon_fb.c | 41 +++----- drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 47 +++------ drivers/gpu/drm/tegra/fb.c | 40 +++----- drivers/gpu/drm/udl/udl_fb.c | 40 +++----- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 3 +- drivers/gpu/drm/virtio/virtgpu_fb.c | 30 ++---- include/drm/drm_fb_helper.h | 30 ++++++ 32 files changed, 426 insertions(+), 547 deletions(-)
Every drm driver calls framebuffer_alloc, fb_alloc_cmap, unregister_framebuffer, fb_dealloc_cmap and framebuffer_release in order to emulate fbdev support.
Create drm_fb_helper functions that perform the above operations.
This is part of an effort to prevent drm drivers from calling fbdev functions directly. It also removes repetitive code from drivers.
There are some drivers that call alloc_apertures after framebuffer_alloc and some that don't. Make the helper always call alloc_apertures. This would make certain drivers allocate memory for apertures but not use them. Since it's a small amount of memory, it shouldn't be an issue.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/drm_fb_helper.c | 53 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_fb_helper.h | 4 ++++ 2 files changed, 57 insertions(+)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index cac4229..78859ad 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -667,6 +667,59 @@ out_free: } EXPORT_SYMBOL(drm_fb_helper_init);
+struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper) +{ + struct device *dev = fb_helper->dev->dev; + struct fb_info *info; + int ret; + + info = framebuffer_alloc(0, dev); + if (!info) + return ERR_PTR(-ENOMEM); + + ret = fb_alloc_cmap(&info->cmap, 256, 0); + if (ret) + goto err_release; + + info->apertures = alloc_apertures(1); + if (!info->apertures) { + ret = -ENOMEM; + goto err_free_cmap; + } + + fb_helper->fbdev = info; + + return info; + +err_free_cmap: + fb_dealloc_cmap(&info->cmap); +err_release: + framebuffer_release(info); + return ERR_PTR(ret); +} +EXPORT_SYMBOL(drm_fb_helper_alloc_fbi); + +void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper) +{ + if (fb_helper->fbdev) + unregister_framebuffer(fb_helper->fbdev); +} +EXPORT_SYMBOL(drm_fb_helper_unregister_fbi); + +void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper) +{ + struct fb_info *info = fb_helper->fbdev; + + if (info) { + if (info->cmap.len) + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); + } + + fb_helper->fbdev = NULL; +} +EXPORT_SYMBOL(drm_fb_helper_release_fbi); + void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) { if (!list_empty(&fb_helper->kernel_fb_list)) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 0dfd94def..2ee4ec5 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -136,6 +136,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
bool drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper); + +struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper); +void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper); +void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper); void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, uint32_t fb_width, uint32_t fb_height); void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
Some drm drivers call unlink_framebuffer. Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/drm_fb_helper.c | 7 +++++++ include/drm/drm_fb_helper.h | 2 ++ 2 files changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 78859ad..742377d 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -737,6 +737,13 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_fini);
+void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) +{ + if (fb_helper->fbdev) + unlink_framebuffer(fb_helper->fbdev); +} +EXPORT_SYMBOL(drm_fb_helper_unlink_fbi); + static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 2ee4ec5..4c90837 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -145,6 +145,8 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, uint32_t depth);
+void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper); + int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
On Mon, Jul 13, 2015 at 12:07:58PM +0530, Archit Taneja wrote:
Some drm drivers call unlink_framebuffer. Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org
drivers/gpu/drm/drm_fb_helper.c | 7 +++++++ include/drm/drm_fb_helper.h | 2 ++ 2 files changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 78859ad..742377d 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -737,6 +737,13 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_fini);
+void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) +{
- if (fb_helper->fbdev)
In anticipation of adding a runtime knob for fbdev emulation, shouldn't we be checking for if (fb_helper && fb_helper->fbdev)
here? Applies to all the other patches too.
Other big missing thing is (simple) kerneldoc for all these new functions. -Daniel
unlink_framebuffer(fb_helper->fbdev);
+} +EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 2ee4ec5..4c90837 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -145,6 +145,8 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, uint32_t depth);
+void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper);
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Some drm drivers populate their fb_ops with fb_sys_read/write fb sysfs ops.
Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/drm_fb_helper.c | 20 ++++++++++++++++++++ include/drm/drm_fb_helper.h | 5 +++++ 3 files changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index a66ac44..b284cdc 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -37,6 +37,7 @@ config DRM_KMS_FB_HELPER select FB select FRAMEBUFFER_CONSOLE if !EXPERT select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE + select FB_SYS_FOPS help FBDEV helpers for KMS drivers.
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 742377d..795547e 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -744,6 +744,26 @@ void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
+ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos) +{ + if (info) + return fb_sys_read(info, buf, count, ppos); + + return -ENODEV; +} +EXPORT_SYMBOL(drm_fb_helper_sys_read); + +ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + if (info) + return fb_sys_write(info, buf, count, ppos); + + return -ENODEV; +} +EXPORT_SYMBOL(drm_fb_helper_sys_write); + static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 4c90837..f74e59e 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -147,6 +147,11 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper);
+ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos); +ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos); + int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
On Mon, Jul 13, 2015 at 12:07:59PM +0530, Archit Taneja wrote:
Some drm drivers populate their fb_ops with fb_sys_read/write fb sysfs ops.
Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org
drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/drm_fb_helper.c | 20 ++++++++++++++++++++ include/drm/drm_fb_helper.h | 5 +++++ 3 files changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index a66ac44..b284cdc 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -37,6 +37,7 @@ config DRM_KMS_FB_HELPER select FB select FRAMEBUFFER_CONSOLE if !EXPERT select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
- select FB_SYS_FOPS help FBDEV helpers for KMS drivers.
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 742377d..795547e 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -744,6 +744,26 @@ void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
+ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos)
+{
- if (info)
I think this check here can never fail (if there's no fbdev you can't call this function), I don't think we need it. Even for drivers which call this themselves (like qxl/udl) they only call it from fbdev code. -Daniel
return fb_sys_read(info, buf, count, ppos);
- return -ENODEV;
+} +EXPORT_SYMBOL(drm_fb_helper_sys_read);
+ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos)
+{
- if (info)
return fb_sys_write(info, buf, count, ppos);
- return -ENODEV;
+} +EXPORT_SYMBOL(drm_fb_helper_sys_write);
static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 4c90837..f74e59e 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -147,6 +147,11 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper);
+ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos);
+ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
On 07/13/2015 01:01 PM, Daniel Vetter wrote:
On Mon, Jul 13, 2015 at 12:07:59PM +0530, Archit Taneja wrote:
Some drm drivers populate their fb_ops with fb_sys_read/write fb sysfs ops.
Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org
drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/drm_fb_helper.c | 20 ++++++++++++++++++++ include/drm/drm_fb_helper.h | 5 +++++ 3 files changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index a66ac44..b284cdc 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -37,6 +37,7 @@ config DRM_KMS_FB_HELPER select FB select FRAMEBUFFER_CONSOLE if !EXPERT select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
- select FB_SYS_FOPS help FBDEV helpers for KMS drivers.
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 742377d..795547e 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -744,6 +744,26 @@ void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
+ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos)
+{
- if (info)
I think this check here can never fail (if there's no fbdev you can't call this function), I don't think we need it. Even for drivers which call this themselves (like qxl/udl) they only call it from fbdev code.
That's a good point. I'll remove the 'if (info)' check.
qxl/udl don't seem to call the fb sysfs funcs. So I think it's okay.
Archit
On Mon, Jul 13, 2015 at 12:07:59PM +0530, Archit Taneja wrote:
Some drm drivers populate their fb_ops with fb_sys_read/write fb sysfs ops.
Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org
drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/drm_fb_helper.c | 20 ++++++++++++++++++++ include/drm/drm_fb_helper.h | 5 +++++ 3 files changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index a66ac44..b284cdc 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -37,6 +37,7 @@ config DRM_KMS_FB_HELPER select FB select FRAMEBUFFER_CONSOLE if !EXPERT select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
- select FB_SYS_FOPS help FBDEV helpers for KMS drivers.
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 742377d..795547e 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -744,6 +744,26 @@ void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
+ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos)
Another one: Checkpatch complains about alignment here. I agree. -Danel
+{
- if (info)
return fb_sys_read(info, buf, count, ppos);
- return -ENODEV;
+} +EXPORT_SYMBOL(drm_fb_helper_sys_read);
+ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos)
+{
- if (info)
return fb_sys_write(info, buf, count, ppos);
- return -ENODEV;
+} +EXPORT_SYMBOL(drm_fb_helper_sys_write);
static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 4c90837..f74e59e 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -147,6 +147,11 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper);
+ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos);
+ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
drm drivers that emulate fbdev populate their fb_fillrect, fb_copyarea and fb_imageblit fb_ops with the help of cfb_* or sys_* fbdev core helper functions.
Create drm_fb_helper functions that wrap around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/Kconfig | 6 ++++++ drivers/gpu/drm/drm_fb_helper.c | 48 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_fb_helper.h | 14 ++++++++++++ 3 files changed, 68 insertions(+)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index b284cdc..e373f8a 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -38,6 +38,12 @@ config DRM_KMS_FB_HELPER select FRAMEBUFFER_CONSOLE if !EXPERT select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE select FB_SYS_FOPS + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT help FBDEV helpers for KMS drivers.
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 795547e..55b5212 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -764,6 +764,54 @@ ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, } EXPORT_SYMBOL(drm_fb_helper_sys_write);
+void drm_fb_helper_sys_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) +{ + if (info) + sys_fillrect(info, rect); +} +EXPORT_SYMBOL(drm_fb_helper_sys_fillrect); + +void drm_fb_helper_sys_copyarea(struct fb_info *info, + const struct fb_copyarea *area) +{ + if (info) + sys_copyarea(info, area); +} +EXPORT_SYMBOL(drm_fb_helper_sys_copyarea); + +void drm_fb_helper_sys_imageblit(struct fb_info *info, + const struct fb_image *image) +{ + if (info) + sys_imageblit(info, image); +} +EXPORT_SYMBOL(drm_fb_helper_sys_imageblit); + +void drm_fb_helper_cfb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) +{ + if (info) + cfb_fillrect(info, rect); +} +EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect); + +void drm_fb_helper_cfb_copyarea(struct fb_info *info, + const struct fb_copyarea *area) +{ + if (info) + cfb_copyarea(info, area); +} +EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea); + +void drm_fb_helper_cfb_imageblit(struct fb_info *info, + const struct fb_image *image) +{ + if (info) + cfb_imageblit(info, image); +} +EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); + static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index f74e59e..aa45837 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -152,6 +152,20 @@ ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos);
+void drm_fb_helper_sys_fillrect(struct fb_info *info, + const struct fb_fillrect *rect); +void drm_fb_helper_sys_copyarea(struct fb_info *info, + const struct fb_copyarea *area); +void drm_fb_helper_sys_imageblit(struct fb_info *info, + const struct fb_image *image); + +void drm_fb_helper_cfb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect); +void drm_fb_helper_cfb_copyarea(struct fb_info *info, + const struct fb_copyarea *area); +void drm_fb_helper_cfb_imageblit(struct fb_info *info, + const struct fb_image *image); + int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
On Mon, Jul 13, 2015 at 12:08:00PM +0530, Archit Taneja wrote:
drm drivers that emulate fbdev populate their fb_fillrect, fb_copyarea and fb_imageblit fb_ops with the help of cfb_* or sys_* fbdev core helper functions.
Create drm_fb_helper functions that wrap around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org
drivers/gpu/drm/Kconfig | 6 ++++++ drivers/gpu/drm/drm_fb_helper.c | 48 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_fb_helper.h | 14 ++++++++++++ 3 files changed, 68 insertions(+)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index b284cdc..e373f8a 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -38,6 +38,12 @@ config DRM_KMS_FB_HELPER select FRAMEBUFFER_CONSOLE if !EXPERT select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE select FB_SYS_FOPS
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT help FBDEV helpers for KMS drivers.
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 795547e..55b5212 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -764,6 +764,54 @@ ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, } EXPORT_SYMBOL(drm_fb_helper_sys_write);
+void drm_fb_helper_sys_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
More alignment noise from checkpatch - continuations should align with the opening (. Since we follow this pretty consistently in drm worth keeping up imo. -Daniel
+{
- if (info)
sys_fillrect(info, rect);
+} +EXPORT_SYMBOL(drm_fb_helper_sys_fillrect);
+void drm_fb_helper_sys_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
+{
- if (info)
sys_copyarea(info, area);
+} +EXPORT_SYMBOL(drm_fb_helper_sys_copyarea);
+void drm_fb_helper_sys_imageblit(struct fb_info *info,
const struct fb_image *image)
+{
- if (info)
sys_imageblit(info, image);
+} +EXPORT_SYMBOL(drm_fb_helper_sys_imageblit);
+void drm_fb_helper_cfb_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
+{
- if (info)
cfb_fillrect(info, rect);
+} +EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect);
+void drm_fb_helper_cfb_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
+{
- if (info)
cfb_copyarea(info, area);
+} +EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea);
+void drm_fb_helper_cfb_imageblit(struct fb_info *info,
const struct fb_image *image)
+{
- if (info)
cfb_imageblit(info, image);
+} +EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit);
static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index f74e59e..aa45837 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -152,6 +152,20 @@ ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos);
+void drm_fb_helper_sys_fillrect(struct fb_info *info,
const struct fb_fillrect *rect);
+void drm_fb_helper_sys_copyarea(struct fb_info *info,
const struct fb_copyarea *area);
+void drm_fb_helper_sys_imageblit(struct fb_info *info,
const struct fb_image *image);
+void drm_fb_helper_cfb_fillrect(struct fb_info *info,
const struct fb_fillrect *rect);
+void drm_fb_helper_cfb_copyarea(struct fb_info *info,
const struct fb_copyarea *area);
+void drm_fb_helper_cfb_imageblit(struct fb_info *info,
const struct fb_image *image);
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Some drm drivers call fb_set_suspend. Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/drm_fb_helper.c | 7 +++++++ include/drm/drm_fb_helper.h | 2 ++ 2 files changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 55b5212..bb35103 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -812,6 +812,13 @@ void drm_fb_helper_cfb_imageblit(struct fb_info *info, } EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit);
+void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state) +{ + if (fb_helper->fbdev) + fb_set_suspend(fb_helper->fbdev, state); +} +EXPORT_SYMBOL(drm_fb_helper_set_suspend); + static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index aa45837..200771e 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -166,6 +166,8 @@ void drm_fb_helper_cfb_copyarea(struct fb_info *info, void drm_fb_helper_cfb_imageblit(struct fb_info *info, const struct fb_image *image);
+void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state); + int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
Some drm drivers call remove_conflicting_framebuffers. Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/drm_fb_helper.c | 7 +++++++ include/drm/drm_fb_helper.h | 3 +++ 2 files changed, 10 insertions(+)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index bb35103..389c2a7 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -819,6 +819,13 @@ void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state) } EXPORT_SYMBOL(drm_fb_helper_set_suspend);
+int drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary) +{ + return remove_conflicting_framebuffers(a, name, primary); +} +EXPORT_SYMBOL(drm_fb_helper_remove_conflicting_framebuffers); + static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 200771e..cc19e88 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -168,6 +168,9 @@ void drm_fb_helper_cfb_imageblit(struct fb_info *info,
void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state);
+int drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary); + int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly.
COMPILE TESTED ONLY.
Cc: Thierry Reding treding@nvidia.com Cc: Zach Reizner zachr@google.com Cc: Russell King rmk+kernel@arm.linux.org.uk Cc: Fabian Frederick fabf@skynet.be
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/cirrus/cirrus_drv.c | 7 ++++--- drivers/gpu/drm/cirrus/cirrus_fbdev.c | 39 +++++++---------------------------- 2 files changed, 12 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index b914003..08bd176 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -56,7 +56,8 @@ static int cirrus_kick_out_firmware_fb(struct pci_dev *pdev) #ifdef CONFIG_X86 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif - remove_conflicting_framebuffers(ap, "cirrusdrmfb", primary); + drm_fb_helper_remove_conflicting_framebuffers(ap, "cirrusdrmfb", + primary); kfree(ap);
return 0; @@ -92,7 +93,7 @@ static int cirrus_pm_suspend(struct device *dev)
if (cdev->mode_info.gfbdev) { console_lock(); - fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1); + drm_fb_helper_set_suspend(&cdev->mode_info.gfbdev->helper, 1); console_unlock(); }
@@ -109,7 +110,7 @@ static int cirrus_pm_resume(struct device *dev)
if (cdev->mode_info.gfbdev) { console_lock(); - fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0); + drm_fb_helper_set_suspend(&cdev->mode_info.gfbdev->helper, 0); console_unlock(); }
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c index 13ddf1c..9b5ea22 100644 --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c @@ -98,7 +98,7 @@ static void cirrus_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct cirrus_fbdev *afbdev = info->par; - sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect); cirrus_dirty_update(afbdev, rect->dx, rect->dy, rect->width, rect->height); } @@ -107,7 +107,7 @@ static void cirrus_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct cirrus_fbdev *afbdev = info->par; - sys_copyarea(info, area); + drm_fb_helper_sys_copyarea(info, area); cirrus_dirty_update(afbdev, area->dx, area->dy, area->width, area->height); } @@ -116,7 +116,7 @@ static void cirrus_imageblit(struct fb_info *info, const struct fb_image *image) { struct cirrus_fbdev *afbdev = info->par; - sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image); cirrus_dirty_update(afbdev, image->dx, image->dy, image->width, image->height); } @@ -165,12 +165,10 @@ static int cirrusfb_create(struct drm_fb_helper *helper, { struct cirrus_fbdev *gfbdev = container_of(helper, struct cirrus_fbdev, helper); - struct drm_device *dev = gfbdev->helper.dev; struct cirrus_device *cdev = gfbdev->helper.dev->dev_private; struct fb_info *info; struct drm_framebuffer *fb; struct drm_mode_fb_cmd2 mode_cmd; - struct device *device = &dev->pdev->dev; void *sysram; struct drm_gem_object *gobj = NULL; struct cirrus_bo *bo = NULL; @@ -195,9 +193,9 @@ static int cirrusfb_create(struct drm_fb_helper *helper, if (!sysram) return -ENOMEM;
- info = framebuffer_alloc(0, device); - if (info == NULL) - return -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) + return PTR_ERR(info);
info->par = gfbdev;
@@ -216,11 +214,9 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
/* setup helper */ gfbdev->helper.fb = fb; - gfbdev->helper.fbdev = info;
strcpy(info->fix.id, "cirrusdrmfb");
- info->flags = FBINFO_DEFAULT; info->fbops = &cirrusfb_ops;
@@ -229,11 +225,6 @@ static int cirrusfb_create(struct drm_fb_helper *helper, sizes->fb_height);
/* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_iounmap; - } info->apertures->ranges[0].base = cdev->dev->mode_config.fb_base; info->apertures->ranges[0].size = cdev->mc.vram_size;
@@ -246,13 +237,6 @@ static int cirrusfb_create(struct drm_fb_helper *helper, info->fix.mmio_start = 0; info->fix.mmio_len = 0;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - DRM_ERROR("%s: can't allocate color map\n", info->fix.id); - ret = -ENOMEM; - goto out_iounmap; - } - DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); DRM_INFO("vram aper at 0x%lX\n", (unsigned long)info->fix.smem_start); DRM_INFO("size %lu\n", (unsigned long)info->fix.smem_len); @@ -267,17 +251,10 @@ out_iounmap: static int cirrus_fbdev_destroy(struct drm_device *dev, struct cirrus_fbdev *gfbdev) { - struct fb_info *info; struct cirrus_framebuffer *gfb = &gfbdev->gfb;
- if (gfbdev->helper.fbdev) { - info = gfbdev->helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&gfbdev->helper); + drm_fb_helper_release_fbi(&gfbdev->helper);
if (gfb->obj) { drm_gem_object_unreference_unlocked(gfb->obj);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
This is an effort to create a top level drm fbdev emulation option.
COMPILE TESTED ONLY.
Cc: Mark Yao mark.yao@rock-chips.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Rob Clark robdclark@gmail.com Cc: Daniel Kurtz djkurtz@chromium.org
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 47 +++++++-------------------- 1 file changed, 12 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c index 5b0dc0f..4de4292 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c @@ -37,9 +37,9 @@ static int rockchip_fbdev_mmap(struct fb_info *info, static struct fb_ops rockchip_drm_fbdev_ops = { .owner = THIS_MODULE, .fb_mmap = rockchip_fbdev_mmap, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, @@ -77,10 +77,10 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
private->fbdev_bo = &rk_obj->base;
- fbi = framebuffer_alloc(0, dev->dev); - if (!fbi) { - dev_err(dev->dev, "Failed to allocate framebuffer info.\n"); - ret = -ENOMEM; + fbi = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(fbi)) + dev_err(dev->dev, "Failed to create framebuffer info.\n"); + ret = PTR_ERR(fbi); goto err_rockchip_gem_free_object; }
@@ -89,21 +89,13 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper, if (IS_ERR(helper->fb)) { dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); ret = PTR_ERR(helper->fb); - goto err_framebuffer_release; + goto err_release_fbi; }
- helper->fbdev = fbi; - fbi->par = helper; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->fbops = &rockchip_drm_fbdev_ops;
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - dev_err(dev->dev, "Failed to allocate color map.\n"); - goto err_drm_framebuffer_unref; - } - fb = helper->fb; drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height); @@ -124,10 +116,8 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
return 0;
-err_drm_framebuffer_unref: - drm_framebuffer_unreference(helper->fb); -err_framebuffer_release: - framebuffer_release(fbi); +err_release_fbi: + drm_fb_helper_release_fbi(helper); err_rockchip_gem_free_object: rockchip_gem_free_object(&rk_obj->base); return ret; @@ -190,21 +180,8 @@ void rockchip_drm_fbdev_fini(struct drm_device *dev)
helper = &private->fbdev_helper;
- if (helper->fbdev) { - struct fb_info *info; - int ret; - - info = helper->fbdev; - ret = unregister_framebuffer(info); - if (ret < 0) - DRM_DEBUG_KMS("failed unregister_framebuffer() - %d\n", - ret); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(helper); + drm_fb_helper_release_fbi(helper);
if (helper->fb) drm_framebuffer_unreference(helper->fb);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Russell King rmk+kernel@arm.linux.org.uk Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/armada/armada_fbdev.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index 7838e73..7d03c51 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -22,9 +22,9 @@ static /*const*/ struct fb_ops armada_fb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -80,18 +80,12 @@ static int armada_fb_create(struct drm_fb_helper *fbh, if (IS_ERR(dfb)) return PTR_ERR(dfb);
- info = framebuffer_alloc(0, dev->dev); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(fbh); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto err_fballoc; }
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto err_fbcmap; - } - strlcpy(info->fix.id, "armada-drmfb", sizeof(info->fix.id)); info->par = fbh; info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; @@ -101,7 +95,7 @@ static int armada_fb_create(struct drm_fb_helper *fbh, info->screen_size = obj->obj.size; info->screen_base = ptr; fbh->fb = &dfb->fb; - fbh->fbdev = info; + drm_fb_helper_fill_fix(info, dfb->fb.pitches[0], dfb->fb.depth); drm_fb_helper_fill_var(info, fbh, sizes->fb_width, sizes->fb_height);
@@ -111,8 +105,6 @@ static int armada_fb_create(struct drm_fb_helper *fbh,
return 0;
- err_fbcmap: - framebuffer_release(info); err_fballoc: dfb->fb.funcs->destroy(&dfb->fb); return ret; @@ -171,6 +163,7 @@ int armada_fbdev_init(struct drm_device *dev)
return 0; err_fb_setup: + drm_fb_helper_release_fbi(fbh); drm_fb_helper_fini(fbh); err_fb_helper: priv->fbdev = NULL; @@ -191,14 +184,8 @@ void armada_fbdev_fini(struct drm_device *dev) struct drm_fb_helper *fbh = priv->fbdev;
if (fbh) { - struct fb_info *info = fbh->fbdev; - - if (info) { - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(fbh); + drm_fb_helper_release_fbi(fbh);
drm_fb_helper_fini(fbh);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
Cleaned up the error handling in astfb_create a bit.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: "Y.C. Chen" yc_chen@aspeedtech.com Cc: Alex Deucher alexander.deucher@amd.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/ast/ast_fb.c | 47 ++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index ff68eef..637a784 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c @@ -125,7 +125,7 @@ static void ast_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct ast_fbdev *afbdev = info->par; - sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect); ast_dirty_update(afbdev, rect->dx, rect->dy, rect->width, rect->height); } @@ -134,7 +134,7 @@ static void ast_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct ast_fbdev *afbdev = info->par; - sys_copyarea(info, area); + drm_fb_helper_sys_copyarea(info, area); ast_dirty_update(afbdev, area->dx, area->dy, area->width, area->height); } @@ -143,7 +143,7 @@ static void ast_imageblit(struct fb_info *info, const struct fb_image *image) { struct ast_fbdev *afbdev = info->par; - sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image); ast_dirty_update(afbdev, image->dx, image->dy, image->width, image->height); } @@ -217,40 +217,28 @@ static int astfb_create(struct drm_fb_helper *helper, if (!sysram) return -ENOMEM;
- info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; - goto out; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); + goto err_free_vram; } info->par = afbdev;
ret = ast_framebuffer_init(dev, &afbdev->afb, &mode_cmd, gobj); if (ret) - goto out; + goto err_release_fbi;
afbdev->sysram = sysram; afbdev->size = size;
fb = &afbdev->afb.base; afbdev->helper.fb = fb; - afbdev->helper.fbdev = info;
strcpy(info->fix.id, "astdrmfb");
info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->fbops = &astfb_ops;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out; - } - - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out; - } info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0); info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0);
@@ -266,7 +254,11 @@ static int astfb_create(struct drm_fb_helper *helper, fb->width, fb->height);
return 0; -out: + +err_release_fbi: + drm_fb_helper_release_fbi(helper); +err_free_vram: + vfree(afbdev->sysram); return ret; }
@@ -297,15 +289,10 @@ static const struct drm_fb_helper_funcs ast_fb_helper_funcs = { static void ast_fbdev_destroy(struct drm_device *dev, struct ast_fbdev *afbdev) { - struct fb_info *info; struct ast_framebuffer *afb = &afbdev->afb; - if (afbdev->helper.fbdev) { - info = afbdev->helper.fbdev; - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + + drm_fb_helper_unregister_fbi(&afbdev->helper); + drm_fb_helper_release_fbi(&afbdev->helper);
if (afb->obj) { drm_gem_object_unreference_unlocked(afb->obj); @@ -377,5 +364,5 @@ void ast_fbdev_set_suspend(struct drm_device *dev, int state) if (!ast->fbdev) return;
- fb_set_suspend(ast->fbdev->helper.fbdev, state); + drm_fb_helper_set_suspend(&ast->fbdev->helper, state); }
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Tomi Valkeinen tomi.valkeinen@ti.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/omapdrm/omap_fbdev.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 23b5a84..a388a85 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -86,11 +86,11 @@ static struct fb_ops omap_fb_ops = { /* Note: to properly handle manual update displays, we wrap the * basic fbdev ops which write to the framebuffer */ - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + .fb_read = drm_fb_helper_sys_read, + .fb_write = drm_fb_helper_sys_write, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit,
.fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, @@ -179,7 +179,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- fbi = framebuffer_alloc(0, dev->dev); + fbi = drm_fb_helper_alloc_fbi(helper); if (!fbi) { dev_err(dev->dev, "failed to allocate fb info\n"); ret = -ENOMEM; @@ -190,7 +190,6 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
fbdev->fb = fb; helper->fb = fb; - helper->fbdev = fbi;
fbi->par = helper; fbi->flags = FBINFO_DEFAULT; @@ -198,12 +197,6 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
strcpy(fbi->fix.id, MODULE_NAME);
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto fail_unlock; - } - drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
@@ -236,8 +229,9 @@ fail_unlock: fail:
if (ret) { - if (fbi) - framebuffer_release(fbi); + + drm_fb_helper_release_fbi(helper); + if (fb) { drm_framebuffer_unregister_private(fb); drm_framebuffer_remove(fb); @@ -312,17 +306,11 @@ void omap_fbdev_free(struct drm_device *dev) struct omap_drm_private *priv = dev->dev_private; struct drm_fb_helper *helper = priv->fbdev; struct omap_fbdev *fbdev; - struct fb_info *fbi;
DBG();
- fbi = helper->fbdev; - - /* only cleanup framebuffer if it is present */ - if (fbi) { - unregister_framebuffer(fbi); - framebuffer_release(fbi); - } + drm_fb_helper_unregister_fbi(helper); + drm_fb_helper_release_fbi(helper);
drm_fb_helper_fini(helper);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Thierry Reding thierry.reding@gmail.com Cc: "Terje Bergström" tbergstrom@nvidia.com Cc: Stephen Warren swarren@wwwdotorg.org
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/tegra/fb.c | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 397fb34..a2d66f9 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -184,9 +184,9 @@ unreference: #ifdef CONFIG_DRM_TEGRA_FBDEV static struct fb_ops tegra_fb_ops = { .owner = THIS_MODULE, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, @@ -224,11 +224,11 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, if (IS_ERR(bo)) return PTR_ERR(bo);
- info = framebuffer_alloc(0, drm->dev); - if (!info) { + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { dev_err(drm->dev, "failed to allocate framebuffer info\n"); - drm_gem_object_unreference_unlocked(&bo->gem); - return -ENOMEM; + err = PTR_ERR(info); + goto gem_unref; }
fbdev->fb = tegra_fb_alloc(drm, &cmd, &bo, 1); @@ -236,7 +236,6 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, err = PTR_ERR(fbdev->fb); dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n", err); - drm_gem_object_unreference_unlocked(&bo->gem); goto release; }
@@ -248,12 +247,6 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, info->flags = FBINFO_FLAG_DEFAULT; info->fbops = &tegra_fb_ops;
- err = fb_alloc_cmap(&info->cmap, 256, 0); - if (err < 0) { - dev_err(drm->dev, "failed to allocate color map: %d\n", err); - goto destroy; - } - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(info, helper, fb->width, fb->height);
@@ -282,7 +275,9 @@ destroy: drm_framebuffer_unregister_private(fb); tegra_fb_destroy(fb); release: - framebuffer_release(info); + drm_fb_helper_release_fbi(helper); +gem_unref: + drm_gem_object_unreference_unlocked(&bo->gem); return err; }
@@ -347,20 +342,9 @@ fini:
static void tegra_fbdev_exit(struct tegra_fbdev *fbdev) { - struct fb_info *info = fbdev->base.fbdev; - - if (info) { - int err;
- err = unregister_framebuffer(info); - if (err < 0) - DRM_DEBUG_KMS("failed to unregister framebuffer\n"); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&fbdev->base); + drm_fb_helper_release_fbi(&fbdev->base);
if (fbdev->fb) { drm_framebuffer_unregister_private(&fbdev->fb->base);
On Mon, Jul 13, 2015 at 12:08:08PM +0530, Archit Taneja wrote: [...]
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
[...]
@@ -224,11 +224,11 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, if (IS_ERR(bo)) return PTR_ERR(bo);
- info = framebuffer_alloc(0, drm->dev);
- if (!info) {
- info = drm_fb_helper_alloc_fbi(helper);
- if (IS_ERR(info)) { dev_err(drm->dev, "failed to allocate framebuffer info\n");
drm_gem_object_unreference_unlocked(&bo->gem);
return -ENOMEM;
err = PTR_ERR(info);
goto gem_unref;
}
fbdev->fb = tegra_fb_alloc(drm, &cmd, &bo, 1);
@@ -236,7 +236,6 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, err = PTR_ERR(fbdev->fb); dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n", err);
goto release; }drm_gem_object_unreference_unlocked(&bo->gem);
@@ -248,12 +247,6 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, info->flags = FBINFO_FLAG_DEFAULT; info->fbops = &tegra_fb_ops;
- err = fb_alloc_cmap(&info->cmap, 256, 0);
- if (err < 0) {
dev_err(drm->dev, "failed to allocate color map: %d\n", err);
goto destroy;
- }
- drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(info, helper, fb->width, fb->height);
@@ -282,7 +275,9 @@ destroy: drm_framebuffer_unregister_private(fb); tegra_fb_destroy(fb); release:
- framebuffer_release(info);
- drm_fb_helper_release_fbi(helper);
+gem_unref:
- drm_gem_object_unreference_unlocked(&bo->gem);
You can't do this. tegra_fb_alloc() takes ownership of the buffer, so unless you compensate for that (by taking an explicit reference to the buffer in tegra_fb_alloc()) you'd be dereferencing twice and likely end up with use-after-free errors later on.
I'd prefer to keep the error clean up as it is.
Thierry
On 07/14/2015 02:20 PM, Thierry Reding wrote:
On Mon, Jul 13, 2015 at 12:08:08PM +0530, Archit Taneja wrote: [...]
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
[...]
@@ -224,11 +224,11 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, if (IS_ERR(bo)) return PTR_ERR(bo);
- info = framebuffer_alloc(0, drm->dev);
- if (!info) {
- info = drm_fb_helper_alloc_fbi(helper);
- if (IS_ERR(info)) { dev_err(drm->dev, "failed to allocate framebuffer info\n");
drm_gem_object_unreference_unlocked(&bo->gem);
return -ENOMEM;
err = PTR_ERR(info);
goto gem_unref;
}
fbdev->fb = tegra_fb_alloc(drm, &cmd, &bo, 1);
@@ -236,7 +236,6 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, err = PTR_ERR(fbdev->fb); dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n", err);
goto release; }drm_gem_object_unreference_unlocked(&bo->gem);
@@ -248,12 +247,6 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, info->flags = FBINFO_FLAG_DEFAULT; info->fbops = &tegra_fb_ops;
- err = fb_alloc_cmap(&info->cmap, 256, 0);
- if (err < 0) {
dev_err(drm->dev, "failed to allocate color map: %d\n", err);
goto destroy;
- }
- drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(info, helper, fb->width, fb->height);
@@ -282,7 +275,9 @@ destroy: drm_framebuffer_unregister_private(fb); tegra_fb_destroy(fb); release:
- framebuffer_release(info);
- drm_fb_helper_release_fbi(helper);
+gem_unref:
- drm_gem_object_unreference_unlocked(&bo->gem);
You can't do this. tegra_fb_alloc() takes ownership of the buffer, so unless you compensate for that (by taking an explicit reference to the buffer in tegra_fb_alloc()) you'd be dereferencing twice and likely end up with use-after-free errors later on.
I'd prefer to keep the error clean up as it is.
Okay. I missed out on the fact that tegra_fb_destroy in the clean up code calls drm_gem_object_unreference_unlocked. I'll keep it as is.
Archit
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
Cc: Rob Clark robdclark@gmail.com Cc: Stephane Viau sviau@codeaurora.org Cc: Hai Li hali@codeaurora.org
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/msm/msm_fbdev.c | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 95f6532..f97a196 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -43,11 +43,11 @@ static struct fb_ops msm_fb_ops = { /* Note: to properly handle manual update displays, we wrap the * basic fbdev ops which write to the framebuffer */ - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + .fb_read = drm_fb_helper_sys_read, + .fb_write = drm_fb_helper_sys_write, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_mmap = msm_fbdev_mmap,
.fb_check_var = drm_fb_helper_check_var, @@ -144,10 +144,10 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, goto fail_unlock; }
- fbi = framebuffer_alloc(0, dev->dev); - if (!fbi) { + fbi = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(fbi)) { dev_err(dev->dev, "failed to allocate fb info\n"); - ret = -ENOMEM; + ret = PTR_ERR(fbi); goto fail_unlock; }
@@ -155,7 +155,6 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
fbdev->fb = fb; helper->fb = fb; - helper->fbdev = fbi;
fbi->par = helper; fbi->flags = FBINFO_DEFAULT; @@ -163,12 +162,6 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
strcpy(fbi->fix.id, "msm");
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto fail_unlock; - } - drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
@@ -191,7 +184,6 @@ fail_unlock: fail:
if (ret) { - framebuffer_release(fbi); if (fb) { drm_framebuffer_unregister_private(fb); drm_framebuffer_remove(fb); @@ -266,17 +258,11 @@ void msm_fbdev_free(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct drm_fb_helper *helper = priv->fbdev; struct msm_fbdev *fbdev; - struct fb_info *fbi;
DBG();
- fbi = helper->fbdev; - - /* only cleanup framebuffer if it is present */ - if (fbi) { - unregister_framebuffer(fbi); - framebuffer_release(fbi); - } + drm_fb_helper_unregister_fbi(helper); + drm_fb_helper_release_fbi(helper);
drm_fb_helper_fini(helper);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Inki Dae inki.dae@samsung.com Cc: Joonyoung Shim jy0922.shim@samsung.com Cc: Seung-Woo Kim sw0312.kim@samsung.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 45 +++++++++---------------------- 1 file changed, 12 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index e0b085b..6975b70 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -65,9 +65,9 @@ static int exynos_drm_fb_mmap(struct fb_info *info, static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, .fb_mmap = exynos_drm_fb_mmap, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, @@ -142,10 +142,10 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- fbi = framebuffer_alloc(0, &pdev->dev); - if (!fbi) { + fbi = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(fbi)) { DRM_ERROR("failed to allocate fb info.\n"); - ret = -ENOMEM; + ret = PTR_ERR(fbi); goto out; }
@@ -165,7 +165,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
if (IS_ERR(exynos_gem_obj)) { ret = PTR_ERR(exynos_gem_obj); - goto err_release_framebuffer; + goto err_release_fbi; }
exynos_fbdev->exynos_gem_obj = exynos_gem_obj; @@ -178,21 +178,13 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, goto err_destroy_gem; }
- helper->fbdev = fbi; - fbi->par = helper; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->fbops = &exynos_drm_fb_ops;
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - DRM_ERROR("failed to allocate cmap.\n"); - goto err_destroy_framebuffer; - } - ret = exynos_drm_fbdev_update(helper, sizes, helper->fb); if (ret < 0) - goto err_dealloc_cmap; + goto err_destroy_framebuffer;
mutex_unlock(&dev->struct_mutex); return ret; @@ -203,8 +195,8 @@ err_destroy_framebuffer: drm_framebuffer_cleanup(helper->fb); err_destroy_gem: exynos_drm_gem_destroy(exynos_gem_obj); -err_release_framebuffer: - framebuffer_release(fbi); +err_release_fbi: + drm_fb_helper_release_fbi(helper);
/* * if failed, all resources allocated above would be released by @@ -312,21 +304,8 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev, } }
- /* release linux framebuffer */ - if (fb_helper->fbdev) { - struct fb_info *info; - int ret; - - info = fb_helper->fbdev; - ret = unregister_framebuffer(info); - if (ret < 0) - DRM_DEBUG_KMS("failed unregister_framebuffer()\n"); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(fb_helper); + drm_fb_helper_release_fbi(fb_helper);
drm_fb_helper_fini(fb_helper); }
On 2015년 07월 13일 15:38, Archit Taneja wrote:
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Inki Dae inki.dae@samsung.com Cc: Joonyoung Shim jy0922.shim@samsung.com Cc: Seung-Woo Kim sw0312.kim@samsung.com
Signed-off-by: Archit Taneja architt@codeaurora.org
drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 45 +++++++++---------------------- 1 file changed, 12 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index e0b085b..6975b70 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -65,9 +65,9 @@ static int exynos_drm_fb_mmap(struct fb_info *info, static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, .fb_mmap = exynos_drm_fb_mmap,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_fillrect = drm_fb_helper_cfb_fillrect,
- .fb_copyarea = drm_fb_helper_cfb_copyarea,
- .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank,
@@ -142,10 +142,10 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- fbi = framebuffer_alloc(0, &pdev->dev);
- if (!fbi) {
- fbi = drm_fb_helper_alloc_fbi(helper);
- if (IS_ERR(fbi)) { DRM_ERROR("failed to allocate fb info.\n");
ret = -ENOMEM;
goto out; }ret = PTR_ERR(fbi);
@@ -165,7 +165,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
if (IS_ERR(exynos_gem_obj)) { ret = PTR_ERR(exynos_gem_obj);
goto err_release_framebuffer;
goto err_release_fbi;
}
exynos_fbdev->exynos_gem_obj = exynos_gem_obj;
@@ -178,21 +178,13 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, goto err_destroy_gem; }
helper->fbdev = fbi;
fbi->par = helper; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->fbops = &exynos_drm_fb_ops;
ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
if (ret) {
DRM_ERROR("failed to allocate cmap.\n");
goto err_destroy_framebuffer;
}
ret = exynos_drm_fbdev_update(helper, sizes, helper->fb); if (ret < 0)
goto err_dealloc_cmap;
goto err_destroy_framebuffer;
With above change, err_dealloc_cmap label isn't used anymore so you need to remove below lines,
err_dealloc_cmap: fb_dealloc_cmap(&fbi->cmap);
Thanks, Inki Dae
mutex_unlock(&dev->struct_mutex); return ret; @@ -203,8 +195,8 @@ err_destroy_framebuffer: drm_framebuffer_cleanup(helper->fb); err_destroy_gem: exynos_drm_gem_destroy(exynos_gem_obj); -err_release_framebuffer:
- framebuffer_release(fbi);
+err_release_fbi:
- drm_fb_helper_release_fbi(helper);
/*
- if failed, all resources allocated above would be released by
@@ -312,21 +304,8 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev, } }
- /* release linux framebuffer */
- if (fb_helper->fbdev) {
struct fb_info *info;
int ret;
info = fb_helper->fbdev;
ret = unregister_framebuffer(info);
if (ret < 0)
DRM_DEBUG_KMS("failed unregister_framebuffer()\n");
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
- }
drm_fb_helper_unregister_fbi(fb_helper);
drm_fb_helper_release_fbi(fb_helper);
drm_fb_helper_fini(fb_helper);
}
On 2015년 08월 11일 18:04, Inki Dae wrote:
On 2015년 07월 13일 15:38, Archit Taneja wrote:
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Inki Dae inki.dae@samsung.com Cc: Joonyoung Shim jy0922.shim@samsung.com Cc: Seung-Woo Kim sw0312.kim@samsung.com
Signed-off-by: Archit Taneja architt@codeaurora.org
drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 45 +++++++++---------------------- 1 file changed, 12 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index e0b085b..6975b70 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -65,9 +65,9 @@ static int exynos_drm_fb_mmap(struct fb_info *info, static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, .fb_mmap = exynos_drm_fb_mmap,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_fillrect = drm_fb_helper_cfb_fillrect,
- .fb_copyarea = drm_fb_helper_cfb_copyarea,
- .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank,
@@ -142,10 +142,10 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- fbi = framebuffer_alloc(0, &pdev->dev);
- if (!fbi) {
- fbi = drm_fb_helper_alloc_fbi(helper);
- if (IS_ERR(fbi)) { DRM_ERROR("failed to allocate fb info.\n");
ret = -ENOMEM;
goto out; }ret = PTR_ERR(fbi);
@@ -165,7 +165,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
if (IS_ERR(exynos_gem_obj)) { ret = PTR_ERR(exynos_gem_obj);
goto err_release_framebuffer;
goto err_release_fbi;
}
exynos_fbdev->exynos_gem_obj = exynos_gem_obj;
@@ -178,21 +178,13 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, goto err_destroy_gem; }
helper->fbdev = fbi;
fbi->par = helper; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->fbops = &exynos_drm_fb_ops;
ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
if (ret) {
DRM_ERROR("failed to allocate cmap.\n");
goto err_destroy_framebuffer;
}
ret = exynos_drm_fbdev_update(helper, sizes, helper->fb); if (ret < 0)
goto err_dealloc_cmap;
goto err_destroy_framebuffer;
With above change, err_dealloc_cmap label isn't used anymore so you need to remove below lines,
err_dealloc_cmap: fb_dealloc_cmap(&fbi->cmap);
Oops, Sorry. You already posted v2 and there is no warning.
Please ignore it.
Thanks, Inki Dae
Thanks, Inki Dae
mutex_unlock(&dev->struct_mutex); return ret; @@ -203,8 +195,8 @@ err_destroy_framebuffer: drm_framebuffer_cleanup(helper->fb); err_destroy_gem: exynos_drm_gem_destroy(exynos_gem_obj); -err_release_framebuffer:
- framebuffer_release(fbi);
+err_release_fbi:
- drm_fb_helper_release_fbi(helper);
/*
- if failed, all resources allocated above would be released by
@@ -312,21 +304,8 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev, } }
- /* release linux framebuffer */
- if (fb_helper->fbdev) {
struct fb_info *info;
int ret;
info = fb_helper->fbdev;
ret = unregister_framebuffer(info);
if (ret < 0)
DRM_DEBUG_KMS("failed unregister_framebuffer()\n");
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
- }
drm_fb_helper_unregister_fbi(fb_helper);
drm_fb_helper_release_fbi(fb_helper);
drm_fb_helper_fini(fb_helper);
}
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/gma500/accel_2d.c | 6 ++--- drivers/gpu/drm/gma500/framebuffer.c | 47 ++++++++++++------------------------ 2 files changed, 19 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/gma500/accel_2d.c b/drivers/gpu/drm/gma500/accel_2d.c index de6f62a..db9f7d0 100644 --- a/drivers/gpu/drm/gma500/accel_2d.c +++ b/drivers/gpu/drm/gma500/accel_2d.c @@ -276,12 +276,12 @@ static void psbfb_copyarea_accel(struct fb_info *info, break; default: /* software fallback */ - cfb_copyarea(info, a); + drm_fb_helper_cfb_copyarea(info, a); return; }
if (!gma_power_begin(dev, false)) { - cfb_copyarea(info, a); + drm_fb_helper_cfb_copyarea(info, a); return; } psb_accel_2d_copy(dev_priv, @@ -308,7 +308,7 @@ void psbfb_copyarea(struct fb_info *info, /* Avoid the 8 pixel erratum */ if (region->width == 8 || region->height == 8 || (info->flags & FBINFO_HWACCEL_DISABLED)) - return cfb_copyarea(info, region); + return drm_fb_helper_cfb_copyarea(info, region);
psbfb_copyarea_accel(info, region); } diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 2d42ce6..4fbe362 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -194,9 +194,9 @@ static struct fb_ops psbfb_ops = { .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = cfb_fillrect, + .fb_fillrect = drm_fb_helper_cfb_fillrect, .fb_copyarea = psbfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_mmap = psbfb_mmap, .fb_sync = psbfb_sync, .fb_ioctl = psbfb_ioctl, @@ -208,9 +208,9 @@ static struct fb_ops psbfb_roll_ops = { .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = psbfb_pan, .fb_mmap = psbfb_mmap, .fb_ioctl = psbfb_ioctl, @@ -222,9 +222,9 @@ static struct fb_ops psbfb_unaccel_ops = { .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_mmap = psbfb_mmap, .fb_ioctl = psbfb_ioctl, }; @@ -409,9 +409,9 @@ static int psbfb_create(struct psb_fbdev *fbdev,
mutex_lock(&dev->struct_mutex);
- info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(&fbdev->psb_fb_helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_err1; } info->par = fbdev; @@ -426,7 +426,6 @@ static int psbfb_create(struct psb_fbdev *fbdev, psbfb->fbdev = info;
fbdev->psb_fb_helper.fb = fb; - fbdev->psb_fb_helper.fbdev = info;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); strcpy(info->fix.id, "psbdrmfb"); @@ -440,12 +439,6 @@ static int psbfb_create(struct psb_fbdev *fbdev, } else /* Software */ info->fbops = &psbfb_unaccel_ops;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; - } - info->fix.smem_start = dev->mode_config.fb_base; info->fix.smem_len = size; info->fix.ywrapstep = gtt_roll; @@ -456,11 +449,6 @@ static int psbfb_create(struct psb_fbdev *fbdev, info->screen_size = size;
if (dev_priv->gtt.stolen_size) { - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } info->apertures->ranges[0].base = dev->mode_config.fb_base; info->apertures->ranges[0].size = dev_priv->gtt.stolen_size; } @@ -483,6 +471,8 @@ out_unref: psb_gtt_free_range(dev, backing); else drm_gem_object_unreference(&backing->gem); + + drm_fb_helper_release_fbi(&fbdev->psb_fb_helper); out_err1: mutex_unlock(&dev->struct_mutex); psb_gtt_free_range(dev, backing); @@ -570,16 +560,11 @@ static const struct drm_fb_helper_funcs psb_fb_helper_funcs = {
static int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev) { - struct fb_info *info; struct psb_framebuffer *psbfb = &fbdev->pfb;
- if (fbdev->psb_fb_helper.fbdev) { - info = fbdev->psb_fb_helper.fbdev; - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&fbdev->psb_fb_helper); + drm_fb_helper_release_fbi(&fbdev->psb_fb_helper); + drm_fb_helper_fini(&fbdev->psb_fb_helper); drm_framebuffer_unregister_private(&psbfb->base); drm_framebuffer_cleanup(&psbfb->base);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: David Airlie airlied@linux.ie Cc: Alex Deucher alexander.deucher@amd.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/mgag200/mgag200_drv.c | 3 ++- drivers/gpu/drm/mgag200/mgag200_fb.c | 36 ++++++++-------------------------- drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- 3 files changed, 11 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 9774599..38363f8 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -55,7 +55,8 @@ static void mgag200_kick_out_firmware_fb(struct pci_dev *pdev) #ifdef CONFIG_X86 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif - remove_conflicting_framebuffers(ap, "mgag200drmfb", primary); + drm_fb_helper_remove_conflicting_framebuffers(ap, "mgag200drmfb", + primary); kfree(ap); }
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c index c36b830..f7553b2 100644 --- a/drivers/gpu/drm/mgag200/mgag200_fb.c +++ b/drivers/gpu/drm/mgag200/mgag200_fb.c @@ -101,7 +101,7 @@ static void mga_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct mga_fbdev *mfbdev = info->par; - sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect); mga_dirty_update(mfbdev, rect->dx, rect->dy, rect->width, rect->height); } @@ -110,7 +110,7 @@ static void mga_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct mga_fbdev *mfbdev = info->par; - sys_copyarea(info, area); + drm_fb_helper_sys_copyarea(info, area); mga_dirty_update(mfbdev, area->dx, area->dy, area->width, area->height); } @@ -119,7 +119,7 @@ static void mga_imageblit(struct fb_info *info, const struct fb_image *image) { struct mga_fbdev *mfbdev = info->par; - sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image); mga_dirty_update(mfbdev, image->dx, image->dy, image->width, image->height); } @@ -191,9 +191,9 @@ static int mgag200fb_create(struct drm_fb_helper *helper, if (!sysram) return -ENOMEM;
- info = framebuffer_alloc(0, device); - if (info == NULL) - return -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) + return PTR_ERR(info);
info->par = mfbdev;
@@ -208,14 +208,6 @@ static int mgag200fb_create(struct drm_fb_helper *helper,
/* setup helper */ mfbdev->helper.fb = fb; - mfbdev->helper.fbdev = info; - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - DRM_ERROR("%s: can't allocate color map\n", info->fix.id); - ret = -ENOMEM; - goto out; - }
strcpy(info->fix.id, "mgadrmfb");
@@ -223,11 +215,6 @@ static int mgag200fb_create(struct drm_fb_helper *helper, info->fbops = &mgag200fb_ops;
/* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out; - } info->apertures->ranges[0].base = mdev->dev->mode_config.fb_base; info->apertures->ranges[0].size = mdev->mc.vram_size;
@@ -249,17 +236,10 @@ out: static int mga_fbdev_destroy(struct drm_device *dev, struct mga_fbdev *mfbdev) { - struct fb_info *info; struct mga_framebuffer *mfb = &mfbdev->mfb;
- if (mfbdev->helper.fbdev) { - info = mfbdev->helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&mfbdev->helper); + drm_fb_helper_release_fbi(&mfbdev->helper);
if (mfb->obj) { drm_gem_object_unreference_unlocked(mfb->obj); diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index f6b283b..b435d3c 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -128,7 +128,7 @@ static int mga_vram_init(struct mga_device *mdev) aper->ranges[0].base = mdev->mc.vram_base; aper->ranges[0].size = mdev->mc.vram_window;
- remove_conflicting_framebuffers(aper, "mgafb", true); + drm_fb_helper_remove_conflicting_framebuffers(aper, "mgafb", true); kfree(aper);
if (!devm_request_mem_region(mdev->dev->dev, mdev->mc.vram_base, mdev->mc.vram_window,
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Alex Deucher alexander.deucher@amd.com Cc: "Christian König" christian.koenig@amd.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/radeon/radeon_drv.c | 4 +++- drivers/gpu/drm/radeon/radeon_fb.c | 41 +++++++++++-------------------------- 2 files changed, 15 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 5751446..98ee541 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -39,6 +39,7 @@ #include <linux/pm_runtime.h> #include <linux/vga_switcheroo.h> #include <drm/drm_gem.h> +#include <drm/drm_fb_helper.h>
#include "drm_crtc_helper.h" #include "radeon_kfd.h" @@ -390,7 +391,8 @@ static int radeon_kick_out_firmware_fb(struct pci_dev *pdev) #ifdef CONFIG_X86 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif - remove_conflicting_framebuffers(ap, "radeondrmfb", primary); + drm_fb_helper_remove_conflicting_framebuffers(ap, "radeondrmfb", + primary); kfree(ap);
return 0; diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 634793e..8d6a834 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -82,9 +82,9 @@ static struct fb_ops radeonfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = radeon_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -250,9 +250,9 @@ static int radeonfb_create(struct drm_fb_helper *helper, rbo = gem_to_radeon_bo(gobj);
/* okay we have an object now allocate the framebuffer */ - info = framebuffer_alloc(0, device); - if (info == NULL) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_unref; }
@@ -261,14 +261,13 @@ static int radeonfb_create(struct drm_fb_helper *helper, ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); if (ret) { DRM_ERROR("failed to initialize framebuffer %d\n", ret); - goto out_unref; + goto out_destroy_fbi; }
fb = &rfbdev->rfb.base;
/* setup helper */ rfbdev->helper.fb = fb; - rfbdev->helper.fbdev = info;
memset_io(rbo->kptr, 0x0, radeon_bo_size(rbo));
@@ -288,11 +287,6 @@ static int radeonfb_create(struct drm_fb_helper *helper, drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
/* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; info->apertures->ranges[0].size = rdev->mc.aper_size;
@@ -300,13 +294,7 @@ static int radeonfb_create(struct drm_fb_helper *helper,
if (info->screen_base == NULL) { ret = -ENOSPC; - goto out_unref; - } - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; + goto out_destroy_fbi; }
DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); @@ -318,6 +306,8 @@ static int radeonfb_create(struct drm_fb_helper *helper, vga_switcheroo_client_fb_set(rdev->ddev->pdev, info); return 0;
+out_destroy_fbi: + drm_fb_helper_release_fbi(helper); out_unref: if (rbo) {
@@ -338,17 +328,10 @@ void radeon_fb_output_poll_changed(struct radeon_device *rdev)
static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev) { - struct fb_info *info; struct radeon_framebuffer *rfb = &rfbdev->rfb;
- if (rfbdev->helper.fbdev) { - info = rfbdev->helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&rfbdev->helper); + drm_fb_helper_release_fbi(&rfbdev->helper);
if (rfb->obj) { radeonfb_destroy_pinned_object(rfb->obj);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: Frediano Ziglio fziglio@redhat.com Cc: Maarten Lankhorst maarten.lankhorst@canonical.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/qxl/qxl_fb.c | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 6b6e57e..41c422f 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c @@ -197,7 +197,7 @@ static void qxl_fb_fillrect(struct fb_info *info, { struct qxl_fbdev *qfbdev = info->par;
- sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect); qxl_dirty_update(qfbdev, rect->dx, rect->dy, rect->width, rect->height); } @@ -207,7 +207,7 @@ static void qxl_fb_copyarea(struct fb_info *info, { struct qxl_fbdev *qfbdev = info->par;
- sys_copyarea(info, area); + drm_fb_helper_sys_copyarea(info, area); qxl_dirty_update(qfbdev, area->dx, area->dy, area->width, area->height); } @@ -217,7 +217,7 @@ static void qxl_fb_imageblit(struct fb_info *info, { struct qxl_fbdev *qfbdev = info->par;
- sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image); qxl_dirty_update(qfbdev, image->dx, image->dy, image->width, image->height); } @@ -345,7 +345,6 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, struct drm_mode_fb_cmd2 mode_cmd; struct drm_gem_object *gobj = NULL; struct qxl_bo *qbo = NULL; - struct device *device = &qdev->pdev->dev; int ret; int size; int bpp = sizes->surface_bpp; @@ -374,9 +373,9 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, shadow); size = mode_cmd.pitches[0] * mode_cmd.height;
- info = framebuffer_alloc(0, device); - if (info == NULL) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(&qfbdev->helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_unref; }
@@ -388,7 +387,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev,
/* setup helper with fb data */ qfbdev->helper.fb = fb; - qfbdev->helper.fbdev = info; + qfbdev->shadow = shadow; strcpy(info->fix.id, "qxldrmfb");
@@ -410,11 +409,6 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, sizes->fb_height);
/* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } info->apertures->ranges[0].base = qdev->ddev->mode_config.fb_base; info->apertures->ranges[0].size = qdev->vram_size;
@@ -423,13 +417,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev,
if (info->screen_base == NULL) { ret = -ENOSPC; - goto out_unref; - } - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; + goto out_destroy_fbi; }
info->fbdefio = &qxl_defio; @@ -441,6 +429,8 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, DRM_INFO("fb: depth %d, pitch %d, width %d, height %d\n", fb->depth, fb->pitches[0], fb->width, fb->height); return 0;
+out_destroy_fbi: + drm_fb_helper_release_fbi(&qfbdev->helper); out_unref: if (qbo) { ret = qxl_bo_reserve(qbo, false); @@ -479,15 +469,11 @@ static int qxl_fb_find_or_create_single(
static int qxl_fbdev_destroy(struct drm_device *dev, struct qxl_fbdev *qfbdev) { - struct fb_info *info; struct qxl_framebuffer *qfb = &qfbdev->qfb;
- if (qfbdev->helper.fbdev) { - info = qfbdev->helper.fbdev; + drm_fb_helper_unregister_fbi(&qfbdev->helper); + drm_fb_helper_release_fbi(&qfbdev->helper);
- unregister_framebuffer(info); - framebuffer_release(info); - } if (qfb->obj) { qxlfb_destroy_pinned_object(qfb->obj); qfb->obj = NULL; @@ -557,7 +543,7 @@ void qxl_fbdev_fini(struct qxl_device *qdev)
void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state) { - fb_set_suspend(qdev->mode_info.qfbdev->helper.fbdev, state); + drm_fb_helper_set_suspend(&qdev->mode_info.qfbdev->helper, state); }
bool qxl_fbdev_qobj_is_fb(struct qxl_device *qdev, struct qxl_bo *qobj)
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Daniel Vetter daniel.vetter@intel.com Cc: Jani Nikula jani.nikula@linux.intel.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/i915/i915_dma.c | 3 ++- drivers/gpu/drm/i915/intel_fbdev.c | 40 ++++++++++++-------------------------- 2 files changed, 14 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d2df321..10f6019 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -498,7 +498,8 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
- ret = remove_conflicting_framebuffers(ap, "inteldrmfb", primary); + ret = drm_fb_helper_remove_conflicting_framebuffers(ap, "inteldrmfb", + primary);
kfree(ap);
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 6372cfc..4aa21f7 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -126,9 +126,9 @@ static struct fb_ops intelfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = intel_fbdev_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = intel_fbdev_pan_display, .fb_blank = intel_fbdev_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -237,9 +237,9 @@ static int intelfb_create(struct drm_fb_helper *helper, obj = intel_fb->obj; size = obj->base.size;
- info = framebuffer_alloc(0, &dev->pdev->dev); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_unpin; }
@@ -248,24 +248,13 @@ static int intelfb_create(struct drm_fb_helper *helper, fb = &ifbdev->fb->base;
ifbdev->helper.fb = fb; - ifbdev->helper.fbdev = info;
strcpy(info->fix.id, "inteldrmfb");
info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->fbops = &intelfb_ops;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unpin; - } /* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unpin; - } info->apertures->ranges[0].base = dev->mode_config.fb_base; info->apertures->ranges[0].size = dev_priv->gtt.mappable_end;
@@ -277,7 +266,7 @@ static int intelfb_create(struct drm_fb_helper *helper, size); if (!info->screen_base) { ret = -ENOSPC; - goto out_unpin; + goto out_destroy_fbi; } info->screen_size = size;
@@ -304,6 +293,8 @@ static int intelfb_create(struct drm_fb_helper *helper, vga_switcheroo_client_fb_set(dev->pdev, info); return 0;
+out_destroy_fbi: + drm_fb_helper_release_fbi(helper); out_unpin: i915_gem_object_ggtt_unpin(obj); drm_gem_object_unreference(&obj->base); @@ -550,16 +541,9 @@ static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { static void intel_fbdev_destroy(struct drm_device *dev, struct intel_fbdev *ifbdev) { - if (ifbdev->helper.fbdev) { - struct fb_info *info = ifbdev->helper.fbdev;
- unregister_framebuffer(info); - iounmap(info->screen_base); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&ifbdev->helper); + drm_fb_helper_release_fbi(&ifbdev->helper);
drm_fb_helper_fini(&ifbdev->helper);
@@ -810,7 +794,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen) memset_io(info->screen_base, 0, info->screen_size);
- fb_set_suspend(info, state); + drm_fb_helper_set_suspend(&ifbdev->helper, state); console_unlock(); }
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: Ben Skeggs bskeggs@redhat.com Cc: Alexandre Courbot acourbot@nvidia.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 ++- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 38 +++++++++++---------------------- 2 files changed, 14 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 649024d..01d3fb2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -317,7 +317,8 @@ static int nouveau_drm_probe(struct pci_dev *pdev, boot = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif if (nouveau_modeset != 2) - remove_conflicting_framebuffers(aper, "nouveaufb", boot); + drm_fb_helper_remove_conflicting_framebuffers(aper, "nouveaufb", + boot); kfree(aper);
ret = nvkm_device_create(pdev, NVKM_BUS_PCI, diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 6751553..443ea87 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -84,7 +84,7 @@ nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
if (ret != -ENODEV) nouveau_fbcon_gpu_lockup(info); - cfb_fillrect(info, rect); + drm_fb_helper_cfb_fillrect(info, rect); }
static void @@ -116,7 +116,7 @@ nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
if (ret != -ENODEV) nouveau_fbcon_gpu_lockup(info); - cfb_copyarea(info, image); + drm_fb_helper_cfb_copyarea(info, image); }
static void @@ -148,7 +148,7 @@ nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
if (ret != -ENODEV) nouveau_fbcon_gpu_lockup(info); - cfb_imageblit(info, image); + drm_fb_helper_cfb_imageblit(info, image); }
static int @@ -197,9 +197,9 @@ static struct fb_ops nouveau_fbcon_sw_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -365,20 +365,13 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- info = framebuffer_alloc(0, &pdev->dev); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_unlock; } info->skip_vt_switch = 1;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - framebuffer_release(info); - goto out_unlock; - } - info->par = fbcon;
nouveau_framebuffer_init(dev, &fbcon->nouveau_fb, &mode_cmd, nvbo); @@ -388,7 +381,6 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
/* setup helper */ fbcon->helper.fb = fb; - fbcon->helper.fbdev = info;
strcpy(info->fix.id, "nouveaufb"); if (!chan) @@ -450,15 +442,9 @@ static int nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) { struct nouveau_framebuffer *nouveau_fb = &fbcon->nouveau_fb; - struct fb_info *info;
- if (fbcon->helper.fbdev) { - info = fbcon->helper.fbdev; - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&fbcon->helper); + drm_fb_helper_release_fbi(&fbcon->helper);
if (nouveau_fb->nvbo) { nouveau_bo_unmap(nouveau_fb->nvbo); @@ -496,7 +482,7 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state) console_lock(); if (state == FBINFO_STATE_RUNNING) nouveau_fbcon_accel_restore(dev); - fb_set_suspend(drm->fbcon->helper.fbdev, state); + drm_fb_helper_set_suspend(&drm->fbcon->helper, state); if (state != FBINFO_STATE_RUNNING) nouveau_fbcon_accel_save_disable(dev); console_unlock();
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: Haixia Shi hshi@chromium.org Cc: "Stéphane Marchesin" marcheu@chromium.org
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/udl/udl_fb.c | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 5fc16ce..9fd6e83 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -288,7 +288,7 @@ static void udl_fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect { struct udl_fbdev *ufbdev = info->par;
- sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect);
udl_handle_damage(&ufbdev->ufb, rect->dx, rect->dy, rect->width, rect->height); @@ -298,7 +298,7 @@ static void udl_fb_copyarea(struct fb_info *info, const struct fb_copyarea *regi { struct udl_fbdev *ufbdev = info->par;
- sys_copyarea(info, region); + drm_fb_helper_sys_copyarea(info, region);
udl_handle_damage(&ufbdev->ufb, region->dx, region->dy, region->width, region->height); @@ -308,7 +308,7 @@ static void udl_fb_imageblit(struct fb_info *info, const struct fb_image *image) { struct udl_fbdev *ufbdev = info->par;
- sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image);
udl_handle_damage(&ufbdev->ufb, image->dx, image->dy, image->width, image->height); @@ -506,21 +506,20 @@ static int udlfb_create(struct drm_fb_helper *helper, goto out_gfree; }
- info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_gfree; } info->par = ufbdev;
ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, obj); if (ret) - goto out_gfree; + goto out_destroy_fbi;
fb = &ufbdev->ufb.base;
ufbdev->helper.fb = fb; - ufbdev->helper.fbdev = info;
strcpy(info->fix.id, "udldrmfb");
@@ -533,18 +532,13 @@ static int udlfb_create(struct drm_fb_helper *helper, drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(info, &ufbdev->helper, sizes->fb_width, sizes->fb_height);
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_gfree; - } - - DRM_DEBUG_KMS("allocated %dx%d vmal %p\n", fb->width, fb->height, ufbdev->ufb.obj->vmapping);
return ret; +out_destroy_fbi: + drm_fb_helper_release_fbi(helper); out_gfree: drm_gem_object_unreference(&ufbdev->ufb.obj->base); out: @@ -558,14 +552,8 @@ static const struct drm_fb_helper_funcs udl_fb_helper_funcs = { static void udl_fbdev_destroy(struct drm_device *dev, struct udl_fbdev *ufbdev) { - struct fb_info *info; - if (ufbdev->helper.fbdev) { - info = ufbdev->helper.fbdev; - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&ufbdev->helper); + drm_fb_helper_release_fbi(&ufbdev->helper); drm_fb_helper_fini(&ufbdev->helper); drm_framebuffer_unregister_private(&ufbdev->ufb.base); drm_framebuffer_cleanup(&ufbdev->ufb.base); @@ -631,11 +619,7 @@ void udl_fbdev_unplug(struct drm_device *dev) return;
ufbdev = udl->fbdev; - if (ufbdev->helper.fbdev) { - struct fb_info *info; - info = ufbdev->helper.fbdev; - unlink_framebuffer(info); - } + drm_fb_helper_unlink_fbi(&ufbdev->helper); }
struct drm_framebuffer *
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/bochs/bochs_drv.c | 6 +++--- drivers/gpu/drm/bochs/bochs_fbdev.c | 34 +++++++++++----------------------- 2 files changed, 14 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index 98837bd..7802fc6 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -109,7 +109,7 @@ static int bochs_pm_suspend(struct device *dev)
if (bochs->fb.initialized) { console_lock(); - fb_set_suspend(bochs->fb.helper.fbdev, 1); + drm_fb_helper_set_suspend(&bochs->fb.helper, 1); console_unlock(); }
@@ -126,7 +126,7 @@ static int bochs_pm_resume(struct device *dev)
if (bochs->fb.initialized) { console_lock(); - fb_set_suspend(bochs->fb.helper.fbdev, 0); + drm_fb_helper_set_suspend(&bochs->fb.helper, 0); console_unlock(); }
@@ -153,7 +153,7 @@ static int bochs_kick_out_firmware_fb(struct pci_dev *pdev)
ap->ranges[0].base = pci_resource_start(pdev, 0); ap->ranges[0].size = pci_resource_len(pdev, 0); - remove_conflicting_framebuffers(ap, "bochsdrmfb", false); + drm_fb_helper_remove_conflicting_framebuffers(ap, "bochsdrmfb", false); kfree(ap);
return 0; diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c index 976d979..8c26d5b 100644 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ b/drivers/gpu/drm/bochs/bochs_fbdev.c @@ -24,9 +24,9 @@ static struct fb_ops bochsfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -106,22 +106,23 @@ static int bochsfb_create(struct drm_fb_helper *helper, ttm_bo_unreserve(&bo->bo);
/* init fb device */ - info = framebuffer_alloc(0, device); - if (info == NULL) - return -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) + return PTR_ERR(info);
info->par = &bochs->fb.helper;
ret = bochs_framebuffer_init(bochs->dev, &bochs->fb.gfb, &mode_cmd, gobj); - if (ret) + if (ret) { + drm_fb_helper_release_fbi(helper); return ret; + }
bochs->fb.size = size;
/* setup helper */ fb = &bochs->fb.gfb.base; bochs->fb.helper.fb = fb; - bochs->fb.helper.fbdev = info;
strcpy(info->fix.id, "bochsdrmfb");
@@ -139,30 +140,17 @@ static int bochsfb_create(struct drm_fb_helper *helper, info->fix.smem_start = 0; info->fix.smem_len = size;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - DRM_ERROR("%s: can't allocate color map\n", info->fix.id); - return -ENOMEM; - } - return 0; }
static int bochs_fbdev_destroy(struct bochs_device *bochs) { struct bochs_framebuffer *gfb = &bochs->fb.gfb; - struct fb_info *info;
DRM_DEBUG_DRIVER("\n");
- if (bochs->fb.helper.fbdev) { - info = bochs->fb.helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&bochs->fb.helper); + drm_fb_helper_release_fbi(&bochs->fb.helper);
if (gfb->obj) { drm_gem_object_unreference_unlocked(gfb->obj);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Alex Deucher alexander.deucher@amd.com Cc: Oded Gabbay oded.gabbay@gmail.com Cc: "Christian König" christian.koenig@amd.com Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 43 +++++++++++---------------------- 2 files changed, 17 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 56da962..52d7cfd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -35,6 +35,7 @@ #include "amdgpu_drv.h"
#include <drm/drm_pciids.h> +#include <drm/drm_fb_helper.h> #include <linux/console.h> #include <linux/module.h> #include <linux/pm_runtime.h> @@ -267,7 +268,8 @@ static int amdgpu_kick_out_firmware_fb(struct pci_dev *pdev) #ifdef CONFIG_X86 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif - remove_conflicting_framebuffers(ap, "amdgpudrmfb", primary); + drm_fb_helper_remove_conflicting_framebuffers(ap, "amdgpudrmfb", + primary); kfree(ap);
return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index c1645d2..f49fdc2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -53,9 +53,9 @@ static struct fb_ops amdgpufb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -201,9 +201,9 @@ static int amdgpufb_create(struct drm_fb_helper *helper, rbo = gem_to_amdgpu_bo(gobj);
/* okay we have an object now allocate the framebuffer */ - info = framebuffer_alloc(0, device); - if (info == NULL) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(ret); goto out_unref; }
@@ -212,14 +212,13 @@ static int amdgpufb_create(struct drm_fb_helper *helper, ret = amdgpu_framebuffer_init(adev->ddev, &rfbdev->rfb, &mode_cmd, gobj); if (ret) { DRM_ERROR("failed to initialize framebuffer %d\n", ret); - goto out_unref; + goto out_destroy_fbi; }
fb = &rfbdev->rfb.base;
/* setup helper */ rfbdev->helper.fb = fb; - rfbdev->helper.fbdev = info;
memset_io(rbo->kptr, 0x0, amdgpu_bo_size(rbo));
@@ -239,11 +238,6 @@ static int amdgpufb_create(struct drm_fb_helper *helper, drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
/* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } info->apertures->ranges[0].base = adev->ddev->mode_config.fb_base; info->apertures->ranges[0].size = adev->mc.aper_size;
@@ -251,13 +245,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
if (info->screen_base == NULL) { ret = -ENOSPC; - goto out_unref; - } - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; + goto out_destroy_fbi; }
DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); @@ -269,6 +257,8 @@ static int amdgpufb_create(struct drm_fb_helper *helper, vga_switcheroo_client_fb_set(adev->ddev->pdev, info); return 0;
+out_destroy_fbi: + drm_fb_helper_release_fbi(helper); out_unref: if (rbo) {
@@ -293,14 +283,8 @@ static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfb struct fb_info *info; struct amdgpu_framebuffer *rfb = &rfbdev->rfb;
- if (rfbdev->helper.fbdev) { - info = rfbdev->helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&rfbdev->helper); + drm_fb_helper_release_fbi(&rfbdev->helper);
if (rfb->obj) { amdgpufb_destroy_pinned_object(rfb->obj); @@ -395,7 +379,8 @@ void amdgpu_fbdev_fini(struct amdgpu_device *adev) void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state) { if (adev->mode_info.rfbdev) - fb_set_suspend(adev->mode_info.rfbdev->helper.fbdev, state); + drm_fb_helper_set_suspend(&adev->mode_info.rfbdev->helper, + state); }
int amdgpu_fbdev_total_size(struct amdgpu_device *adev)
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: Gerd Hoffmann kraxel@redhat.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 3 ++- drivers/gpu/drm/virtio/virtgpu_fb.c | 30 +++++++++--------------------- 2 files changed, 11 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c index 88a3916..aea1bac 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c +++ b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c @@ -52,7 +52,8 @@ static void virtio_pci_kick_out_firmware_fb(struct pci_dev *pci_dev) primary = pci_dev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
- remove_conflicting_framebuffers(ap, "virtiodrmfb", primary); + drm_fb_helper_remove_conflicting_framebuffers(ap, "virtiodrmfb", + primary);
kfree(ap); } diff --git a/drivers/gpu/drm/virtio/virtgpu_fb.c b/drivers/gpu/drm/virtio/virtgpu_fb.c index df198d9..3b5462b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fb.c +++ b/drivers/gpu/drm/virtio/virtgpu_fb.c @@ -173,7 +173,7 @@ static void virtio_gpu_3d_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct virtio_gpu_fbdev *vfbdev = info->par; - sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect); virtio_gpu_dirty_update(&vfbdev->vgfb, true, rect->dx, rect->dy, rect->width, rect->height); schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); @@ -183,7 +183,7 @@ static void virtio_gpu_3d_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct virtio_gpu_fbdev *vfbdev = info->par; - sys_copyarea(info, area); + drm_fb_helper_sys_copyarea(info, area); virtio_gpu_dirty_update(&vfbdev->vgfb, true, area->dx, area->dy, area->width, area->height); schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); @@ -193,7 +193,7 @@ static void virtio_gpu_3d_imageblit(struct fb_info *info, const struct fb_image *image) { struct virtio_gpu_fbdev *vfbdev = info->par; - sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image); virtio_gpu_dirty_update(&vfbdev->vgfb, true, image->dx, image->dy, image->width, image->height); schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); @@ -317,18 +317,12 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper, if (ret) goto err_obj_attach;
- info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto err_fb_alloc; }
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto err_fb_alloc_cmap; - } - info->par = helper;
ret = virtio_gpu_framebuffer_init(dev, &vfbdev->vgfb, @@ -339,7 +333,6 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper, fb = &vfbdev->vgfb.base;
vfbdev->helper.fb = fb; - vfbdev->helper.fbdev = info;
strcpy(info->fix.id, "virtiodrmfb"); info->flags = FBINFO_DEFAULT; @@ -357,9 +350,7 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper, return 0;
err_fb_init: - fb_dealloc_cmap(&info->cmap); -err_fb_alloc_cmap: - framebuffer_release(info); + drm_fb_helper_release_fbi(helper); err_fb_alloc: virtio_gpu_cmd_resource_inval_backing(vgdev, resid); err_obj_attach: @@ -374,12 +365,9 @@ static int virtio_gpu_fbdev_destroy(struct drm_device *dev, struct fb_info *info; struct virtio_gpu_framebuffer *vgfb = &vgfbdev->vgfb;
- if (vgfbdev->helper.fbdev) { - info = vgfbdev->helper.fbdev; + drm_fb_helper_unregister_fbi(&vgfbdev->helper); + drm_fb_helper_release_fbi(&vgfbdev->helper);
- unregister_framebuffer(info); - framebuffer_release(info); - } if (vgfb->obj) vgfb->obj = NULL; drm_fb_helper_fini(&vgfbdev->helper);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Lars-Peter Clausen lars@metafoo.de Cc: Daniel Vetter daniel.vetter@ffwll.ch
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/drm_fb_cma_helper.c | 45 +++++++++---------------------------- 1 file changed, 11 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 5c1aca4..0da6a24 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -234,9 +234,9 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_debugfs_show);
static struct fb_ops drm_fbdev_cma_ops = { .owner = THIS_MODULE, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, @@ -275,10 +275,9 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, if (IS_ERR(obj)) return -ENOMEM;
- fbi = framebuffer_alloc(0, dev->dev); - if (!fbi) { - dev_err(dev->dev, "Failed to allocate framebuffer info.\n"); - ret = -ENOMEM; + fbi = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(fbi)) { + ret = PTR_ERR(fbi); goto err_drm_gem_cma_free_object; }
@@ -286,23 +285,16 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, if (IS_ERR(fbdev_cma->fb)) { dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); ret = PTR_ERR(fbdev_cma->fb); - goto err_framebuffer_release; + goto err_fb_info_destroy; }
fb = &fbdev_cma->fb->fb; helper->fb = fb; - helper->fbdev = fbi;
fbi->par = helper; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->fbops = &drm_fbdev_cma_ops;
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - dev_err(dev->dev, "Failed to allocate color map.\n"); - goto err_drm_fb_cma_destroy; - } - drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
@@ -317,11 +309,8 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
return 0;
-err_drm_fb_cma_destroy: - drm_framebuffer_unregister_private(fb); - drm_fb_cma_destroy(fb); -err_framebuffer_release: - framebuffer_release(fbi); +err_fb_info_destroy: + drm_fb_helper_release_fbi(helper); err_drm_gem_cma_free_object: drm_gem_cma_free_object(&obj->base); return ret; @@ -397,20 +386,8 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_init); */ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma) { - if (fbdev_cma->fb_helper.fbdev) { - struct fb_info *info; - int ret; - - info = fbdev_cma->fb_helper.fbdev; - ret = unregister_framebuffer(info); - if (ret < 0) - DRM_DEBUG_KMS("failed unregister_framebuffer()\n"); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&fbdev_cma->fb_helper); + drm_fb_helper_release_fbi(&fbdev_cma->fb_helper);
if (fbdev_cma->fb) { drm_framebuffer_unregister_private(&fbdev_cma->fb->fb);
On Mon, Jul 13, 2015 at 12:07:56PM +0530, Archit Taneja wrote:
DRM drivers using drm_fb_helpers still call some fbdev core functions. This makes the driver depend on CONFIG_FB, resulting in complicated Kconfig options, and preventing us from creating a top level drm config option to enable/disable FBDEV emulation.
Create new drm_fb_helper functions that replace these fbdev functions.
In most cases, the new helper funcs simply wrap around the original fbdev functions. For a few (like framebufer_alloc), we actually do some work that is currently redundant across multiple drivers.
With these patches, the drivers don't call any fbdev functions directly. They are now called through functions in drm_fb_helper.c. We will later create a fbdev emulation config option to stub out the fb helpers.
The only exception is vmwgfx driver. This doesn't use drm_fb_helper. It creates a fb device how a driver in drivers/video/fbdev would. Maybe this needs to be converted to use drm_fb_helpers.
For more info, have a look at the threads: http://lists.freedesktop.org/archives/dri-devel/2015-March/078729.html http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html
I think overall this looks really nice. I quickly fired this up on an i915 machine and it worked, so I pulled it all into topic/drm-misc (which is in linux-next) to give this the testing it needs. I'll probably do a separate topic branch for the pull request to Dave with the final patches. My plan would be to make one overall pull for step 1 plus the first patch of step 2. Then everything else could go in through driver maintainers like usual I think.
Cheers, Daniel
Archit Taneja (25): drm/fb_helper: Add drm_fb_helper functions to manage fb_info creation drm/fb_helper: Create a wrapper for unlink_framebuffer drm/fb_helper: Create wrappers for fb_sys_read/write funcs drm/fb_helper: Create wrappers for blit, copyarea and fillrect funcs drm/fb_helper: Create a wrapper for fb_set_suspend drm/fb_helper: Create a wrapper for remove_conflicting_framebuffers drm/cirrus: Use new drm_fb_helper functions drm/rockchip: Use new drm_fb_helper functions drm/armada: Use new drm_fb_helper functions drm/ast: Use new drm_fb_helper functions drm/omap: Use new drm_fb_helper functions drm/tegra: Use new drm_fb_helper functions drm/msm: Use new drm_fb_helper functions drm/exynos: Use new drm_fb_helper functions drm/gma500: Use new drm_fb_helper functions drm/mgag200: Use new drm_fb_helper functions drm/radeon: Use new drm_fb_helper functions drm/qxl: Use new drm_fb_helper functions drm/i915: Use new drm_fb_helper functions drm/nouveau: Use new drm_fb_helper functions drm/udl: Use new drm_fb_helper functions drm/boschs: Use new drm_fb_helper functions drm/amdgpu: Use new drm_fb_helper functions drm/virtio: Use new drm_fb_helper functions drm/fb_cma_helper: Use new drm_fb_helper functions
drivers/gpu/drm/Kconfig | 7 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 43 +++----- drivers/gpu/drm/armada/armada_fbdev.c | 33 ++---- drivers/gpu/drm/ast/ast_fb.c | 47 +++------ drivers/gpu/drm/bochs/bochs_drv.c | 6 +- drivers/gpu/drm/bochs/bochs_fbdev.c | 34 ++---- drivers/gpu/drm/cirrus/cirrus_drv.c | 7 +- drivers/gpu/drm/cirrus/cirrus_fbdev.c | 39 ++----- drivers/gpu/drm/drm_fb_cma_helper.c | 45 ++------ drivers/gpu/drm/drm_fb_helper.c | 142 ++++++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 45 +++----- drivers/gpu/drm/gma500/accel_2d.c | 6 +- drivers/gpu/drm/gma500/framebuffer.c | 47 +++------ drivers/gpu/drm/i915/i915_dma.c | 3 +- drivers/gpu/drm/i915/intel_fbdev.c | 40 +++----- drivers/gpu/drm/mgag200/mgag200_drv.c | 3 +- drivers/gpu/drm/mgag200/mgag200_fb.c | 36 ++----- drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 34 ++---- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 38 +++---- drivers/gpu/drm/omapdrm/omap_fbdev.c | 34 ++---- drivers/gpu/drm/qxl/qxl_fb.c | 40 +++----- drivers/gpu/drm/radeon/radeon_drv.c | 4 +- drivers/gpu/drm/radeon/radeon_fb.c | 41 +++----- drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 47 +++------ drivers/gpu/drm/tegra/fb.c | 40 +++----- drivers/gpu/drm/udl/udl_fb.c | 40 +++----- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 3 +- drivers/gpu/drm/virtio/virtgpu_fb.c | 30 ++---- include/drm/drm_fb_helper.h | 30 ++++++ 32 files changed, 426 insertions(+), 547 deletions(-)
-- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
On 07/13/2015 01:37 PM, Daniel Vetter wrote:
On Mon, Jul 13, 2015 at 12:07:56PM +0530, Archit Taneja wrote:
DRM drivers using drm_fb_helpers still call some fbdev core functions. This makes the driver depend on CONFIG_FB, resulting in complicated Kconfig options, and preventing us from creating a top level drm config option to enable/disable FBDEV emulation.
Create new drm_fb_helper functions that replace these fbdev functions.
In most cases, the new helper funcs simply wrap around the original fbdev functions. For a few (like framebufer_alloc), we actually do some work that is currently redundant across multiple drivers.
With these patches, the drivers don't call any fbdev functions directly. They are now called through functions in drm_fb_helper.c. We will later create a fbdev emulation config option to stub out the fb helpers.
The only exception is vmwgfx driver. This doesn't use drm_fb_helper. It creates a fb device how a driver in drivers/video/fbdev would. Maybe this needs to be converted to use drm_fb_helpers.
For more info, have a look at the threads: http://lists.freedesktop.org/archives/dri-devel/2015-March/078729.html http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html
I think overall this looks really nice. I quickly fired this up on an i915 machine and it worked, so I pulled it all into topic/drm-misc (which is in linux-next) to give this the testing it needs. I'll probably do a separate topic branch for the pull request to Dave with the final patches. My plan would be to make one overall pull for step 1 plus the first patch of step 2. Then everything else could go in through driver maintainers like usual I think.
Okay. That sounds good to me too. I'll fix up the comments and the warnings thrown by the kbuild bot.
There was an initial Kconfig clean up patch set 'drm/misc: Kconfig cleanup' that will make the remainder steps easier to pull. Could we try to get that in too?
Archit
Cheers, Daniel
Archit Taneja (25): drm/fb_helper: Add drm_fb_helper functions to manage fb_info creation drm/fb_helper: Create a wrapper for unlink_framebuffer drm/fb_helper: Create wrappers for fb_sys_read/write funcs drm/fb_helper: Create wrappers for blit, copyarea and fillrect funcs drm/fb_helper: Create a wrapper for fb_set_suspend drm/fb_helper: Create a wrapper for remove_conflicting_framebuffers drm/cirrus: Use new drm_fb_helper functions drm/rockchip: Use new drm_fb_helper functions drm/armada: Use new drm_fb_helper functions drm/ast: Use new drm_fb_helper functions drm/omap: Use new drm_fb_helper functions drm/tegra: Use new drm_fb_helper functions drm/msm: Use new drm_fb_helper functions drm/exynos: Use new drm_fb_helper functions drm/gma500: Use new drm_fb_helper functions drm/mgag200: Use new drm_fb_helper functions drm/radeon: Use new drm_fb_helper functions drm/qxl: Use new drm_fb_helper functions drm/i915: Use new drm_fb_helper functions drm/nouveau: Use new drm_fb_helper functions drm/udl: Use new drm_fb_helper functions drm/boschs: Use new drm_fb_helper functions drm/amdgpu: Use new drm_fb_helper functions drm/virtio: Use new drm_fb_helper functions drm/fb_cma_helper: Use new drm_fb_helper functions
drivers/gpu/drm/Kconfig | 7 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 43 +++----- drivers/gpu/drm/armada/armada_fbdev.c | 33 ++---- drivers/gpu/drm/ast/ast_fb.c | 47 +++------ drivers/gpu/drm/bochs/bochs_drv.c | 6 +- drivers/gpu/drm/bochs/bochs_fbdev.c | 34 ++---- drivers/gpu/drm/cirrus/cirrus_drv.c | 7 +- drivers/gpu/drm/cirrus/cirrus_fbdev.c | 39 ++----- drivers/gpu/drm/drm_fb_cma_helper.c | 45 ++------ drivers/gpu/drm/drm_fb_helper.c | 142 ++++++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 45 +++----- drivers/gpu/drm/gma500/accel_2d.c | 6 +- drivers/gpu/drm/gma500/framebuffer.c | 47 +++------ drivers/gpu/drm/i915/i915_dma.c | 3 +- drivers/gpu/drm/i915/intel_fbdev.c | 40 +++----- drivers/gpu/drm/mgag200/mgag200_drv.c | 3 +- drivers/gpu/drm/mgag200/mgag200_fb.c | 36 ++----- drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 34 ++---- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 38 +++---- drivers/gpu/drm/omapdrm/omap_fbdev.c | 34 ++---- drivers/gpu/drm/qxl/qxl_fb.c | 40 +++----- drivers/gpu/drm/radeon/radeon_drv.c | 4 +- drivers/gpu/drm/radeon/radeon_fb.c | 41 +++----- drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 47 +++------ drivers/gpu/drm/tegra/fb.c | 40 +++----- drivers/gpu/drm/udl/udl_fb.c | 40 +++----- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 3 +- drivers/gpu/drm/virtio/virtgpu_fb.c | 30 ++---- include/drm/drm_fb_helper.h | 30 ++++++ 32 files changed, 426 insertions(+), 547 deletions(-)
-- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
On Mon, Jul 13, 2015 at 03:59:25PM +0530, Archit Taneja wrote:
On 07/13/2015 01:37 PM, Daniel Vetter wrote:
On Mon, Jul 13, 2015 at 12:07:56PM +0530, Archit Taneja wrote:
DRM drivers using drm_fb_helpers still call some fbdev core functions. This makes the driver depend on CONFIG_FB, resulting in complicated Kconfig options, and preventing us from creating a top level drm config option to enable/disable FBDEV emulation.
Create new drm_fb_helper functions that replace these fbdev functions.
In most cases, the new helper funcs simply wrap around the original fbdev functions. For a few (like framebufer_alloc), we actually do some work that is currently redundant across multiple drivers.
With these patches, the drivers don't call any fbdev functions directly. They are now called through functions in drm_fb_helper.c. We will later create a fbdev emulation config option to stub out the fb helpers.
The only exception is vmwgfx driver. This doesn't use drm_fb_helper. It creates a fb device how a driver in drivers/video/fbdev would. Maybe this needs to be converted to use drm_fb_helpers.
For more info, have a look at the threads: http://lists.freedesktop.org/archives/dri-devel/2015-March/078729.html http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html
I think overall this looks really nice. I quickly fired this up on an i915 machine and it worked, so I pulled it all into topic/drm-misc (which is in linux-next) to give this the testing it needs. I'll probably do a separate topic branch for the pull request to Dave with the final patches. My plan would be to make one overall pull for step 1 plus the first patch of step 2. Then everything else could go in through driver maintainers like usual I think.
Okay. That sounds good to me too. I'll fix up the comments and the warnings thrown by the kbuild bot.
There was an initial Kconfig clean up patch set 'drm/misc: Kconfig cleanup' that will make the remainder steps easier to pull. Could we try to get that in too?
I think we only need that once we pull in the driver-specific parts for step2&3, right? Personally I don't really care about the Kconfig organization all that much, so I'd like to see some Acks from other maintainers before I pull that in. If that happens I can pull in the patches for old/legacy drivers into topic/drm-misc sure. -Daniel
On Mon, Jul 13, 2015 at 2:37 AM, Archit Taneja architt@codeaurora.org wrote:
DRM drivers using drm_fb_helpers still call some fbdev core functions. This makes the driver depend on CONFIG_FB, resulting in complicated Kconfig options, and preventing us from creating a top level drm config option to enable/disable FBDEV emulation.
Create new drm_fb_helper functions that replace these fbdev functions.
In most cases, the new helper funcs simply wrap around the original fbdev functions. For a few (like framebufer_alloc), we actually do some work that is currently redundant across multiple drivers.
With these patches, the drivers don't call any fbdev functions directly. They are now called through functions in drm_fb_helper.c. We will later create a fbdev emulation config option to stub out the fb helpers.
The only exception is vmwgfx driver. This doesn't use drm_fb_helper. It creates a fb device how a driver in drivers/video/fbdev would. Maybe this needs to be converted to use drm_fb_helpers.
For more info, have a look at the threads: http://lists.freedesktop.org/archives/dri-devel/2015-March/078729.html http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html
Series is: Acked-by: Alex Deucher alexander.deucher@amd.com
Archit Taneja (25): drm/fb_helper: Add drm_fb_helper functions to manage fb_info creation drm/fb_helper: Create a wrapper for unlink_framebuffer drm/fb_helper: Create wrappers for fb_sys_read/write funcs drm/fb_helper: Create wrappers for blit, copyarea and fillrect funcs drm/fb_helper: Create a wrapper for fb_set_suspend drm/fb_helper: Create a wrapper for remove_conflicting_framebuffers drm/cirrus: Use new drm_fb_helper functions drm/rockchip: Use new drm_fb_helper functions drm/armada: Use new drm_fb_helper functions drm/ast: Use new drm_fb_helper functions drm/omap: Use new drm_fb_helper functions drm/tegra: Use new drm_fb_helper functions drm/msm: Use new drm_fb_helper functions drm/exynos: Use new drm_fb_helper functions drm/gma500: Use new drm_fb_helper functions drm/mgag200: Use new drm_fb_helper functions drm/radeon: Use new drm_fb_helper functions drm/qxl: Use new drm_fb_helper functions drm/i915: Use new drm_fb_helper functions drm/nouveau: Use new drm_fb_helper functions drm/udl: Use new drm_fb_helper functions drm/boschs: Use new drm_fb_helper functions drm/amdgpu: Use new drm_fb_helper functions drm/virtio: Use new drm_fb_helper functions drm/fb_cma_helper: Use new drm_fb_helper functions
drivers/gpu/drm/Kconfig | 7 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 43 +++----- drivers/gpu/drm/armada/armada_fbdev.c | 33 ++---- drivers/gpu/drm/ast/ast_fb.c | 47 +++------ drivers/gpu/drm/bochs/bochs_drv.c | 6 +- drivers/gpu/drm/bochs/bochs_fbdev.c | 34 ++---- drivers/gpu/drm/cirrus/cirrus_drv.c | 7 +- drivers/gpu/drm/cirrus/cirrus_fbdev.c | 39 ++----- drivers/gpu/drm/drm_fb_cma_helper.c | 45 ++------ drivers/gpu/drm/drm_fb_helper.c | 142 ++++++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 45 +++----- drivers/gpu/drm/gma500/accel_2d.c | 6 +- drivers/gpu/drm/gma500/framebuffer.c | 47 +++------ drivers/gpu/drm/i915/i915_dma.c | 3 +- drivers/gpu/drm/i915/intel_fbdev.c | 40 +++----- drivers/gpu/drm/mgag200/mgag200_drv.c | 3 +- drivers/gpu/drm/mgag200/mgag200_fb.c | 36 ++----- drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 34 ++---- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 38 +++---- drivers/gpu/drm/omapdrm/omap_fbdev.c | 34 ++---- drivers/gpu/drm/qxl/qxl_fb.c | 40 +++----- drivers/gpu/drm/radeon/radeon_drv.c | 4 +- drivers/gpu/drm/radeon/radeon_fb.c | 41 +++----- drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 47 +++------ drivers/gpu/drm/tegra/fb.c | 40 +++----- drivers/gpu/drm/udl/udl_fb.c | 40 +++----- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 3 +- drivers/gpu/drm/virtio/virtgpu_fb.c | 30 ++---- include/drm/drm_fb_helper.h | 30 ++++++ 32 files changed, 426 insertions(+), 547 deletions(-)
-- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
DRM drivers using drm_fb_helpers still call some fbdev core functions. This makes the driver depend on CONFIG_FB, resulting in complicated Kconfig options, and preventing us from creating a top level drm config option to enable/disable FBDEV emulation.
Create new drm_fb_helper functions that replace these fbdev functions.
In most cases, the new helper funcs simply wrap around the original fbdev functions. For a few (like framebufer_alloc), we actually do some work that is currently redundant across multiple drivers.
With these patches, the drivers don't call any fbdev functions directly. They are now called through functions in drm_fb_helper.c. We will later create a fbdev emulation config option to stub out the fb helpers.
The only exception is vmwgfx driver. This doesn't use drm_fb_helper. It creates a fb device how a driver in drivers/video/fbdev would. Maybe this needs to be converted to use drm_fb_helpers.
For more info, have a look at the threads: http://lists.freedesktop.org/archives/dri-devel/2015-March/078729.html http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html
v2: - Remove if (info) checks in fb_sys functions - Use 'if (fb_helper && fb_helper->fbdev)' checks where appropriate - Add kerneldocs for the new helper funcs - Follow drm way of aligning of arguments in func definitions - Fixed build error in drm/virtio - Fixed error cleanup path in drm/tegra - Fixed build error in drm/rockchip - Fixed return issue in drm/amdgpu - Fixed 'unused variable' warnings in bochs, ast, udl and radeon - Fixed stray goto labels in cirrus, exynos, mgag
Archit Taneja (25): drm/fb_helper: Add drm_fb_helper functions to manage fb_info creation drm/fb_helper: Create a wrapper for unlink_framebuffer drm/fb_helper: Create wrappers for fb_sys_read/write funcs drm/fb_helper: Create wrappers for blit, copyarea and fillrect funcs drm/fb_helper: Create a wrapper for fb_set_suspend drm/fb_helper: Create a wrapper for remove_conflicting_framebuffers drm/cirrus: Use new drm_fb_helper functions drm/rockchip: Use new drm_fb_helper functions drm/armada: Use new drm_fb_helper functions drm/ast: Use new drm_fb_helper functions drm/omap: Use new drm_fb_helper functions drm/tegra: Use new drm_fb_helper functions drm/msm: Use new drm_fb_helper functions drm/exynos: Use new drm_fb_helper functions drm/gma500: Use new drm_fb_helper functions drm/mgag200: Use new drm_fb_helper functions drm/radeon: Use new drm_fb_helper functions drm/qxl: Use new drm_fb_helper functions drm/i915: Use new drm_fb_helper functions drm/nouveau: Use new drm_fb_helper functions drm/udl: Use new drm_fb_helper functions drm/bochs: Use new drm_fb_helper functions drm/amdgpu: Use new drm_fb_helper functions drm/virtio: Use new drm_fb_helper functions drm/fb_cma_helper: Use new drm_fb_helper functions
drivers/gpu/drm/Kconfig | 7 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 45 ++---- drivers/gpu/drm/armada/armada_fbdev.c | 33 ++-- drivers/gpu/drm/ast/ast_fb.c | 48 ++---- drivers/gpu/drm/bochs/bochs_drv.c | 6 +- drivers/gpu/drm/bochs/bochs_fbdev.c | 36 ++--- drivers/gpu/drm/cirrus/cirrus_drv.c | 7 +- drivers/gpu/drm/cirrus/cirrus_fbdev.c | 41 +---- drivers/gpu/drm/drm_fb_cma_helper.c | 45 ++---- drivers/gpu/drm/drm_fb_helper.c | 225 ++++++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 47 ++---- drivers/gpu/drm/gma500/accel_2d.c | 6 +- drivers/gpu/drm/gma500/framebuffer.c | 48 ++---- drivers/gpu/drm/i915/i915_dma.c | 3 +- drivers/gpu/drm/i915/intel_fbdev.c | 40 ++--- drivers/gpu/drm/mgag200/mgag200_drv.c | 3 +- drivers/gpu/drm/mgag200/mgag200_fb.c | 39 +---- drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 34 ++-- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 39 ++--- drivers/gpu/drm/omapdrm/omap_fbdev.c | 34 ++-- drivers/gpu/drm/qxl/qxl_fb.c | 40 ++--- drivers/gpu/drm/radeon/radeon_drv.c | 4 +- drivers/gpu/drm/radeon/radeon_fb.c | 42 ++--- drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 47 ++---- drivers/gpu/drm/tegra/fb.c | 35 ++-- drivers/gpu/drm/udl/udl_fb.c | 41 ++--- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 3 +- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 + drivers/gpu/drm/virtio/virtgpu_fb.c | 32 ++-- include/drm/drm_fb_helper.h | 31 ++++ 33 files changed, 508 insertions(+), 563 deletions(-)
Every drm driver calls framebuffer_alloc, fb_alloc_cmap, unregister_framebuffer, fb_dealloc_cmap and framebuffer_release in order to emulate fbdev support.
Create drm_fb_helper functions that perform the above operations.
This is part of an effort to prevent drm drivers from calling fbdev functions directly. It also removes repetitive code from drivers.
There are some drivers that call alloc_apertures after framebuffer_alloc and some that don't. Make the helper always call alloc_apertures. This would make certain drivers allocate memory for apertures but not use them. Since it's a small amount of memory, it shouldn't be an issue.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/drm_fb_helper.c | 80 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_fb_helper.h | 4 +++ 2 files changed, 84 insertions(+)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index cac4229..a5ae64a 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -667,6 +667,86 @@ out_free: } EXPORT_SYMBOL(drm_fb_helper_init);
+/** + * drm_fb_helper_alloc_fbi - allocate fb_info and some of its members + * @fb_helper: driver-allocated fbdev helper + * + * A helper to alloc fb_info and the members cmap and apertures. Called + * by the driver within the fb_probe fb_helper callback function. + * + * RETURNS: + * fb_info pointer if things went okay, pointer containing error code + * otherwise + */ +struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper) +{ + struct device *dev = fb_helper->dev->dev; + struct fb_info *info; + int ret; + + info = framebuffer_alloc(0, dev); + if (!info) + return ERR_PTR(-ENOMEM); + + ret = fb_alloc_cmap(&info->cmap, 256, 0); + if (ret) + goto err_release; + + info->apertures = alloc_apertures(1); + if (!info->apertures) { + ret = -ENOMEM; + goto err_free_cmap; + } + + fb_helper->fbdev = info; + + return info; + +err_free_cmap: + fb_dealloc_cmap(&info->cmap); +err_release: + framebuffer_release(info); + return ERR_PTR(ret); +} +EXPORT_SYMBOL(drm_fb_helper_alloc_fbi); + +/** + * drm_fb_helper_unregister_fbi - unregister fb_info framebuffer device + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around unregister_framebuffer, to release the fb_info + * framebuffer device + */ +void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper) +{ + if (fb_helper && fb_helper->fbdev) + unregister_framebuffer(fb_helper->fbdev); +} +EXPORT_SYMBOL(drm_fb_helper_unregister_fbi); + +/** + * drm_fb_helper_release_fbi - dealloc fb_info and its members + * @fb_helper: driver-allocated fbdev helper + * + * A helper to free memory taken by fb_info and the members cmap and + * apertures + */ +void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper) +{ + if (fb_helper) { + struct fb_info *info = fb_helper->fbdev; + + if (info) { + if (info->cmap.len) + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); + } + + fb_helper->fbdev = NULL; + } +} +EXPORT_SYMBOL(drm_fb_helper_release_fbi); + void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) { if (!list_empty(&fb_helper->kernel_fb_list)) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 0dfd94def..2ee4ec5 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -136,6 +136,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
bool drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper); + +struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper); +void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper); +void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper); void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, uint32_t fb_width, uint32_t fb_height); void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
Some drm drivers call unlink_framebuffer. Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/drm_fb_helper.c | 13 +++++++++++++ include/drm/drm_fb_helper.h | 2 ++ 2 files changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index a5ae64a..2f8dd8d 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -764,6 +764,19 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_fini);
+/** + * drm_fb_helper_unlink_fbi - wrapper around unlink_framebuffer + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around unlink_framebuffer implemented by fbdev core + */ +void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) +{ + if (fb_helper && fb_helper->fbdev) + unlink_framebuffer(fb_helper->fbdev); +} +EXPORT_SYMBOL(drm_fb_helper_unlink_fbi); + static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 2ee4ec5..4c90837 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -145,6 +145,8 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, uint32_t depth);
+void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper); + int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
Some drm drivers populate their fb_ops with fb_sys_read/write fb sysfs ops.
Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/drm_fb_helper.c | 26 ++++++++++++++++++++++++++ include/drm/drm_fb_helper.h | 5 +++++ 3 files changed, 32 insertions(+)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index c46ca31..6ab503b 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -37,6 +37,7 @@ config DRM_KMS_FB_HELPER select FB select FRAMEBUFFER_CONSOLE if !EXPERT select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE + select FB_SYS_FOPS help FBDEV helpers for KMS drivers.
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 2f8dd8d..abb36f9 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -777,6 +777,32 @@ void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
+/** + * drm_fb_helper_sys_read - wrapper around fb_sys_read + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around fb_sys_read implemented by fbdev core + */ +ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos) +{ + return fb_sys_read(info, buf, count, ppos); +} +EXPORT_SYMBOL(drm_fb_helper_sys_read); + +/** + * drm_fb_helper_sys_write - wrapper around fb_sys_write + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around fb_sys_write implemented by fbdev core + */ +ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + return fb_sys_write(info, buf, count, ppos); +} +EXPORT_SYMBOL(drm_fb_helper_sys_write); + static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 4c90837..fc12368 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -147,6 +147,11 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper);
+ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos); +ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos); + int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
drm drivers that emulate fbdev populate their fb_fillrect, fb_copyarea and fb_imageblit fb_ops with the help of cfb_* or sys_* fbdev core helper functions.
Create drm_fb_helper functions that wrap around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/Kconfig | 6 ++++ drivers/gpu/drm/drm_fb_helper.c | 78 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_fb_helper.h | 14 ++++++++ 3 files changed, 98 insertions(+)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 6ab503b..35a8c0b 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -38,6 +38,12 @@ config DRM_KMS_FB_HELPER select FRAMEBUFFER_CONSOLE if !EXPERT select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE select FB_SYS_FOPS + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT help FBDEV helpers for KMS drivers.
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index abb36f9..1312b6b 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -803,6 +803,84 @@ ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, } EXPORT_SYMBOL(drm_fb_helper_sys_write);
+/** + * drm_fb_helper_sys_fillrect - wrapper around sys_fillrect + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around sys_fillrect implemented by fbdev core + */ +void drm_fb_helper_sys_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) +{ + sys_fillrect(info, rect); +} +EXPORT_SYMBOL(drm_fb_helper_sys_fillrect); + +/** + * drm_fb_helper_sys_copyarea - wrapper around sys_copyarea + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around sys_copyarea implemented by fbdev core + */ +void drm_fb_helper_sys_copyarea(struct fb_info *info, + const struct fb_copyarea *area) +{ + sys_copyarea(info, area); +} +EXPORT_SYMBOL(drm_fb_helper_sys_copyarea); + +/** + * drm_fb_helper_sys_imageblit - wrapper around sys_imageblit + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around sys_imageblit implemented by fbdev core + */ +void drm_fb_helper_sys_imageblit(struct fb_info *info, + const struct fb_image *image) +{ + sys_imageblit(info, image); +} +EXPORT_SYMBOL(drm_fb_helper_sys_imageblit); + +/** + * drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around cfb_imageblit implemented by fbdev core + */ +void drm_fb_helper_cfb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) +{ + cfb_fillrect(info, rect); +} +EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect); + +/** + * drm_fb_helper_cfb_copyarea - wrapper around cfb_copyarea + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around cfb_copyarea implemented by fbdev core + */ +void drm_fb_helper_cfb_copyarea(struct fb_info *info, + const struct fb_copyarea *area) +{ + cfb_copyarea(info, area); +} +EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea); + +/** + * drm_fb_helper_cfb_imageblit - wrapper around cfb_imageblit + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around cfb_imageblit implemented by fbdev core + */ +void drm_fb_helper_cfb_imageblit(struct fb_info *info, + const struct fb_image *image) +{ + cfb_imageblit(info, image); +} +EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); + static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index fc12368..180290e 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -152,6 +152,20 @@ ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos);
+void drm_fb_helper_sys_fillrect(struct fb_info *info, + const struct fb_fillrect *rect); +void drm_fb_helper_sys_copyarea(struct fb_info *info, + const struct fb_copyarea *area); +void drm_fb_helper_sys_imageblit(struct fb_info *info, + const struct fb_image *image); + +void drm_fb_helper_cfb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect); +void drm_fb_helper_cfb_copyarea(struct fb_info *info, + const struct fb_copyarea *area); +void drm_fb_helper_cfb_imageblit(struct fb_info *info, + const struct fb_image *image); + int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
Some drm drivers call fb_set_suspend. Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/drm_fb_helper.c | 13 +++++++++++++ include/drm/drm_fb_helper.h | 2 ++ 2 files changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 1312b6b..9620aa5 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -881,6 +881,19 @@ void drm_fb_helper_cfb_imageblit(struct fb_info *info, } EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit);
+/** + * drm_fb_helper_set_suspend - wrapper around fb_set_suspend + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around fb_set_suspend implemented by fbdev core + */ +void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state) +{ + if (fb_helper && fb_helper->fbdev) + fb_set_suspend(fb_helper->fbdev, state); +} +EXPORT_SYMBOL(drm_fb_helper_set_suspend); + static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 180290e..ef32500 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -166,6 +166,8 @@ void drm_fb_helper_cfb_copyarea(struct fb_info *info, void drm_fb_helper_cfb_imageblit(struct fb_info *info, const struct fb_image *image);
+void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state); + int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
Some drm drivers call remove_conflicting_framebuffers. Create a drm_fb_helper function that wraps around these calls.
This is part of an effort to prevent drm drivers from calling fbdev functions directly, in order to make fbdev emulation a top level drm option.
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/drm_fb_helper.c | 15 +++++++++++++++ include/drm/drm_fb_helper.h | 4 ++++ 2 files changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 9620aa5..d503528 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -894,6 +894,21 @@ void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state) } EXPORT_SYMBOL(drm_fb_helper_set_suspend);
+/** + * drm_fb_helper_remove_conflicting_framebuffers - wrapper around + * remove_conflicting_framebuffers + * @fb_helper: driver-allocated fbdev helper + * + * A wrapper around remove_conflicting_framebuffers implemented by fbdev core + */ +int drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, + bool primary) +{ + return remove_conflicting_framebuffers(a, name, primary); +} +EXPORT_SYMBOL(drm_fb_helper_remove_conflicting_framebuffers); + static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, u16 regno, struct fb_info *info) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index ef32500..cbdc69d 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -168,6 +168,10 @@ void drm_fb_helper_cfb_imageblit(struct fb_info *info,
void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state);
+int drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, + bool primary); + int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly.
COMPILE TESTED ONLY.
Cc: Thierry Reding treding@nvidia.com Cc: Zach Reizner zachr@google.com Cc: Russell King rmk+kernel@arm.linux.org.uk Cc: Fabian Frederick fabf@skynet.be
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/cirrus/cirrus_drv.c | 7 +++--- drivers/gpu/drm/cirrus/cirrus_fbdev.c | 41 +++++++---------------------------- 2 files changed, 12 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index b914003..08bd176 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -56,7 +56,8 @@ static int cirrus_kick_out_firmware_fb(struct pci_dev *pdev) #ifdef CONFIG_X86 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif - remove_conflicting_framebuffers(ap, "cirrusdrmfb", primary); + drm_fb_helper_remove_conflicting_framebuffers(ap, "cirrusdrmfb", + primary); kfree(ap);
return 0; @@ -92,7 +93,7 @@ static int cirrus_pm_suspend(struct device *dev)
if (cdev->mode_info.gfbdev) { console_lock(); - fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1); + drm_fb_helper_set_suspend(&cdev->mode_info.gfbdev->helper, 1); console_unlock(); }
@@ -109,7 +110,7 @@ static int cirrus_pm_resume(struct device *dev)
if (cdev->mode_info.gfbdev) { console_lock(); - fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0); + drm_fb_helper_set_suspend(&cdev->mode_info.gfbdev->helper, 0); console_unlock(); }
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c index 13ddf1c..589103b 100644 --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c @@ -98,7 +98,7 @@ static void cirrus_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct cirrus_fbdev *afbdev = info->par; - sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect); cirrus_dirty_update(afbdev, rect->dx, rect->dy, rect->width, rect->height); } @@ -107,7 +107,7 @@ static void cirrus_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct cirrus_fbdev *afbdev = info->par; - sys_copyarea(info, area); + drm_fb_helper_sys_copyarea(info, area); cirrus_dirty_update(afbdev, area->dx, area->dy, area->width, area->height); } @@ -116,7 +116,7 @@ static void cirrus_imageblit(struct fb_info *info, const struct fb_image *image) { struct cirrus_fbdev *afbdev = info->par; - sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image); cirrus_dirty_update(afbdev, image->dx, image->dy, image->width, image->height); } @@ -165,12 +165,10 @@ static int cirrusfb_create(struct drm_fb_helper *helper, { struct cirrus_fbdev *gfbdev = container_of(helper, struct cirrus_fbdev, helper); - struct drm_device *dev = gfbdev->helper.dev; struct cirrus_device *cdev = gfbdev->helper.dev->dev_private; struct fb_info *info; struct drm_framebuffer *fb; struct drm_mode_fb_cmd2 mode_cmd; - struct device *device = &dev->pdev->dev; void *sysram; struct drm_gem_object *gobj = NULL; struct cirrus_bo *bo = NULL; @@ -195,9 +193,9 @@ static int cirrusfb_create(struct drm_fb_helper *helper, if (!sysram) return -ENOMEM;
- info = framebuffer_alloc(0, device); - if (info == NULL) - return -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) + return PTR_ERR(info);
info->par = gfbdev;
@@ -216,11 +214,9 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
/* setup helper */ gfbdev->helper.fb = fb; - gfbdev->helper.fbdev = info;
strcpy(info->fix.id, "cirrusdrmfb");
- info->flags = FBINFO_DEFAULT; info->fbops = &cirrusfb_ops;
@@ -229,11 +225,6 @@ static int cirrusfb_create(struct drm_fb_helper *helper, sizes->fb_height);
/* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_iounmap; - } info->apertures->ranges[0].base = cdev->dev->mode_config.fb_base; info->apertures->ranges[0].size = cdev->mc.vram_size;
@@ -246,13 +237,6 @@ static int cirrusfb_create(struct drm_fb_helper *helper, info->fix.mmio_start = 0; info->fix.mmio_len = 0;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - DRM_ERROR("%s: can't allocate color map\n", info->fix.id); - ret = -ENOMEM; - goto out_iounmap; - } - DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); DRM_INFO("vram aper at 0x%lX\n", (unsigned long)info->fix.smem_start); DRM_INFO("size %lu\n", (unsigned long)info->fix.smem_len); @@ -260,24 +244,15 @@ static int cirrusfb_create(struct drm_fb_helper *helper, DRM_INFO(" pitch is %d\n", fb->pitches[0]);
return 0; -out_iounmap: - return ret; }
static int cirrus_fbdev_destroy(struct drm_device *dev, struct cirrus_fbdev *gfbdev) { - struct fb_info *info; struct cirrus_framebuffer *gfb = &gfbdev->gfb;
- if (gfbdev->helper.fbdev) { - info = gfbdev->helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&gfbdev->helper); + drm_fb_helper_release_fbi(&gfbdev->helper);
if (gfb->obj) { drm_gem_object_unreference_unlocked(gfb->obj);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
This is an effort to create a top level drm fbdev emulation option.
COMPILE TESTED ONLY.
Cc: Mark Yao mark.yao@rock-chips.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Rob Clark robdclark@gmail.com Cc: Daniel Kurtz djkurtz@chromium.org
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 47 +++++++-------------------- 1 file changed, 12 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c index 5b0dc0f..f261512 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c @@ -37,9 +37,9 @@ static int rockchip_fbdev_mmap(struct fb_info *info, static struct fb_ops rockchip_drm_fbdev_ops = { .owner = THIS_MODULE, .fb_mmap = rockchip_fbdev_mmap, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, @@ -77,10 +77,10 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
private->fbdev_bo = &rk_obj->base;
- fbi = framebuffer_alloc(0, dev->dev); - if (!fbi) { - dev_err(dev->dev, "Failed to allocate framebuffer info.\n"); - ret = -ENOMEM; + fbi = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(fbi)) { + dev_err(dev->dev, "Failed to create framebuffer info.\n"); + ret = PTR_ERR(fbi); goto err_rockchip_gem_free_object; }
@@ -89,21 +89,13 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper, if (IS_ERR(helper->fb)) { dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); ret = PTR_ERR(helper->fb); - goto err_framebuffer_release; + goto err_release_fbi; }
- helper->fbdev = fbi; - fbi->par = helper; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->fbops = &rockchip_drm_fbdev_ops;
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - dev_err(dev->dev, "Failed to allocate color map.\n"); - goto err_drm_framebuffer_unref; - } - fb = helper->fb; drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height); @@ -124,10 +116,8 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
return 0;
-err_drm_framebuffer_unref: - drm_framebuffer_unreference(helper->fb); -err_framebuffer_release: - framebuffer_release(fbi); +err_release_fbi: + drm_fb_helper_release_fbi(helper); err_rockchip_gem_free_object: rockchip_gem_free_object(&rk_obj->base); return ret; @@ -190,21 +180,8 @@ void rockchip_drm_fbdev_fini(struct drm_device *dev)
helper = &private->fbdev_helper;
- if (helper->fbdev) { - struct fb_info *info; - int ret; - - info = helper->fbdev; - ret = unregister_framebuffer(info); - if (ret < 0) - DRM_DEBUG_KMS("failed unregister_framebuffer() - %d\n", - ret); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(helper); + drm_fb_helper_release_fbi(helper);
if (helper->fb) drm_framebuffer_unreference(helper->fb);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Russell King rmk+kernel@arm.linux.org.uk Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/armada/armada_fbdev.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index 7838e73..7d03c51 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -22,9 +22,9 @@ static /*const*/ struct fb_ops armada_fb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -80,18 +80,12 @@ static int armada_fb_create(struct drm_fb_helper *fbh, if (IS_ERR(dfb)) return PTR_ERR(dfb);
- info = framebuffer_alloc(0, dev->dev); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(fbh); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto err_fballoc; }
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto err_fbcmap; - } - strlcpy(info->fix.id, "armada-drmfb", sizeof(info->fix.id)); info->par = fbh; info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; @@ -101,7 +95,7 @@ static int armada_fb_create(struct drm_fb_helper *fbh, info->screen_size = obj->obj.size; info->screen_base = ptr; fbh->fb = &dfb->fb; - fbh->fbdev = info; + drm_fb_helper_fill_fix(info, dfb->fb.pitches[0], dfb->fb.depth); drm_fb_helper_fill_var(info, fbh, sizes->fb_width, sizes->fb_height);
@@ -111,8 +105,6 @@ static int armada_fb_create(struct drm_fb_helper *fbh,
return 0;
- err_fbcmap: - framebuffer_release(info); err_fballoc: dfb->fb.funcs->destroy(&dfb->fb); return ret; @@ -171,6 +163,7 @@ int armada_fbdev_init(struct drm_device *dev)
return 0; err_fb_setup: + drm_fb_helper_release_fbi(fbh); drm_fb_helper_fini(fbh); err_fb_helper: priv->fbdev = NULL; @@ -191,14 +184,8 @@ void armada_fbdev_fini(struct drm_device *dev) struct drm_fb_helper *fbh = priv->fbdev;
if (fbh) { - struct fb_info *info = fbh->fbdev; - - if (info) { - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(fbh); + drm_fb_helper_release_fbi(fbh);
drm_fb_helper_fini(fbh);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
Cleaned up the error handling in astfb_create a bit.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: "Y.C. Chen" yc_chen@aspeedtech.com Cc: Alex Deucher alexander.deucher@amd.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/ast/ast_fb.c | 48 ++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index ff68eef..f31db28 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c @@ -125,7 +125,7 @@ static void ast_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct ast_fbdev *afbdev = info->par; - sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect); ast_dirty_update(afbdev, rect->dx, rect->dy, rect->width, rect->height); } @@ -134,7 +134,7 @@ static void ast_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct ast_fbdev *afbdev = info->par; - sys_copyarea(info, area); + drm_fb_helper_sys_copyarea(info, area); ast_dirty_update(afbdev, area->dx, area->dy, area->width, area->height); } @@ -143,7 +143,7 @@ static void ast_imageblit(struct fb_info *info, const struct fb_image *image) { struct ast_fbdev *afbdev = info->par; - sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image); ast_dirty_update(afbdev, image->dx, image->dy, image->width, image->height); } @@ -193,7 +193,6 @@ static int astfb_create(struct drm_fb_helper *helper, struct drm_framebuffer *fb; struct fb_info *info; int size, ret; - struct device *device = &dev->pdev->dev; void *sysram; struct drm_gem_object *gobj = NULL; struct ast_bo *bo = NULL; @@ -217,40 +216,28 @@ static int astfb_create(struct drm_fb_helper *helper, if (!sysram) return -ENOMEM;
- info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; - goto out; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); + goto err_free_vram; } info->par = afbdev;
ret = ast_framebuffer_init(dev, &afbdev->afb, &mode_cmd, gobj); if (ret) - goto out; + goto err_release_fbi;
afbdev->sysram = sysram; afbdev->size = size;
fb = &afbdev->afb.base; afbdev->helper.fb = fb; - afbdev->helper.fbdev = info;
strcpy(info->fix.id, "astdrmfb");
info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->fbops = &astfb_ops;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out; - } - - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out; - } info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0); info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0);
@@ -266,7 +253,11 @@ static int astfb_create(struct drm_fb_helper *helper, fb->width, fb->height);
return 0; -out: + +err_release_fbi: + drm_fb_helper_release_fbi(helper); +err_free_vram: + vfree(afbdev->sysram); return ret; }
@@ -297,15 +288,10 @@ static const struct drm_fb_helper_funcs ast_fb_helper_funcs = { static void ast_fbdev_destroy(struct drm_device *dev, struct ast_fbdev *afbdev) { - struct fb_info *info; struct ast_framebuffer *afb = &afbdev->afb; - if (afbdev->helper.fbdev) { - info = afbdev->helper.fbdev; - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + + drm_fb_helper_unregister_fbi(&afbdev->helper); + drm_fb_helper_release_fbi(&afbdev->helper);
if (afb->obj) { drm_gem_object_unreference_unlocked(afb->obj); @@ -377,5 +363,5 @@ void ast_fbdev_set_suspend(struct drm_device *dev, int state) if (!ast->fbdev) return;
- fb_set_suspend(ast->fbdev->helper.fbdev, state); + drm_fb_helper_set_suspend(&ast->fbdev->helper, state); }
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Tomi Valkeinen tomi.valkeinen@ti.com Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/omapdrm/omap_fbdev.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 23b5a84..a388a85 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -86,11 +86,11 @@ static struct fb_ops omap_fb_ops = { /* Note: to properly handle manual update displays, we wrap the * basic fbdev ops which write to the framebuffer */ - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + .fb_read = drm_fb_helper_sys_read, + .fb_write = drm_fb_helper_sys_write, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit,
.fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, @@ -179,7 +179,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- fbi = framebuffer_alloc(0, dev->dev); + fbi = drm_fb_helper_alloc_fbi(helper); if (!fbi) { dev_err(dev->dev, "failed to allocate fb info\n"); ret = -ENOMEM; @@ -190,7 +190,6 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
fbdev->fb = fb; helper->fb = fb; - helper->fbdev = fbi;
fbi->par = helper; fbi->flags = FBINFO_DEFAULT; @@ -198,12 +197,6 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
strcpy(fbi->fix.id, MODULE_NAME);
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto fail_unlock; - } - drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
@@ -236,8 +229,9 @@ fail_unlock: fail:
if (ret) { - if (fbi) - framebuffer_release(fbi); + + drm_fb_helper_release_fbi(helper); + if (fb) { drm_framebuffer_unregister_private(fb); drm_framebuffer_remove(fb); @@ -312,17 +306,11 @@ void omap_fbdev_free(struct drm_device *dev) struct omap_drm_private *priv = dev->dev_private; struct drm_fb_helper *helper = priv->fbdev; struct omap_fbdev *fbdev; - struct fb_info *fbi;
DBG();
- fbi = helper->fbdev; - - /* only cleanup framebuffer if it is present */ - if (fbi) { - unregister_framebuffer(fbi); - framebuffer_release(fbi); - } + drm_fb_helper_unregister_fbi(helper); + drm_fb_helper_release_fbi(helper);
drm_fb_helper_fini(helper);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Thierry Reding thierry.reding@gmail.com Cc: "Terje Bergström" tbergstrom@nvidia.com Cc: Stephen Warren swarren@wwwdotorg.org
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/tegra/fb.c | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 397fb34..07c844b 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -184,9 +184,9 @@ unreference: #ifdef CONFIG_DRM_TEGRA_FBDEV static struct fb_ops tegra_fb_ops = { .owner = THIS_MODULE, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, @@ -224,11 +224,11 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, if (IS_ERR(bo)) return PTR_ERR(bo);
- info = framebuffer_alloc(0, drm->dev); - if (!info) { + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { dev_err(drm->dev, "failed to allocate framebuffer info\n"); drm_gem_object_unreference_unlocked(&bo->gem); - return -ENOMEM; + return PTR_ERR(info); }
fbdev->fb = tegra_fb_alloc(drm, &cmd, &bo, 1); @@ -248,12 +248,6 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, info->flags = FBINFO_FLAG_DEFAULT; info->fbops = &tegra_fb_ops;
- err = fb_alloc_cmap(&info->cmap, 256, 0); - if (err < 0) { - dev_err(drm->dev, "failed to allocate color map: %d\n", err); - goto destroy; - } - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(info, helper, fb->width, fb->height);
@@ -282,7 +276,7 @@ destroy: drm_framebuffer_unregister_private(fb); tegra_fb_destroy(fb); release: - framebuffer_release(info); + drm_fb_helper_release_fbi(helper); return err; }
@@ -347,20 +341,9 @@ fini:
static void tegra_fbdev_exit(struct tegra_fbdev *fbdev) { - struct fb_info *info = fbdev->base.fbdev; - - if (info) { - int err;
- err = unregister_framebuffer(info); - if (err < 0) - DRM_DEBUG_KMS("failed to unregister framebuffer\n"); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&fbdev->base); + drm_fb_helper_release_fbi(&fbdev->base);
if (fbdev->fb) { drm_framebuffer_unregister_private(&fbdev->fb->base);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
Cc: Rob Clark robdclark@gmail.com Cc: Stephane Viau sviau@codeaurora.org Cc: Hai Li hali@codeaurora.org
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/msm/msm_fbdev.c | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 95f6532..f97a196 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -43,11 +43,11 @@ static struct fb_ops msm_fb_ops = { /* Note: to properly handle manual update displays, we wrap the * basic fbdev ops which write to the framebuffer */ - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + .fb_read = drm_fb_helper_sys_read, + .fb_write = drm_fb_helper_sys_write, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_mmap = msm_fbdev_mmap,
.fb_check_var = drm_fb_helper_check_var, @@ -144,10 +144,10 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, goto fail_unlock; }
- fbi = framebuffer_alloc(0, dev->dev); - if (!fbi) { + fbi = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(fbi)) { dev_err(dev->dev, "failed to allocate fb info\n"); - ret = -ENOMEM; + ret = PTR_ERR(fbi); goto fail_unlock; }
@@ -155,7 +155,6 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
fbdev->fb = fb; helper->fb = fb; - helper->fbdev = fbi;
fbi->par = helper; fbi->flags = FBINFO_DEFAULT; @@ -163,12 +162,6 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
strcpy(fbi->fix.id, "msm");
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto fail_unlock; - } - drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
@@ -191,7 +184,6 @@ fail_unlock: fail:
if (ret) { - framebuffer_release(fbi); if (fb) { drm_framebuffer_unregister_private(fb); drm_framebuffer_remove(fb); @@ -266,17 +258,11 @@ void msm_fbdev_free(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct drm_fb_helper *helper = priv->fbdev; struct msm_fbdev *fbdev; - struct fb_info *fbi;
DBG();
- fbi = helper->fbdev; - - /* only cleanup framebuffer if it is present */ - if (fbi) { - unregister_framebuffer(fbi); - framebuffer_release(fbi); - } + drm_fb_helper_unregister_fbi(helper); + drm_fb_helper_release_fbi(helper);
drm_fb_helper_fini(helper);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Inki Dae inki.dae@samsung.com Cc: Joonyoung Shim jy0922.shim@samsung.com Cc: Seung-Woo Kim sw0312.kim@samsung.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 47 ++++++++----------------------- 1 file changed, 12 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index e0b085b..dd64bc0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -65,9 +65,9 @@ static int exynos_drm_fb_mmap(struct fb_info *info, static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, .fb_mmap = exynos_drm_fb_mmap, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, @@ -142,10 +142,10 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- fbi = framebuffer_alloc(0, &pdev->dev); - if (!fbi) { + fbi = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(fbi)) { DRM_ERROR("failed to allocate fb info.\n"); - ret = -ENOMEM; + ret = PTR_ERR(fbi); goto out; }
@@ -165,7 +165,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
if (IS_ERR(exynos_gem_obj)) { ret = PTR_ERR(exynos_gem_obj); - goto err_release_framebuffer; + goto err_release_fbi; }
exynos_fbdev->exynos_gem_obj = exynos_gem_obj; @@ -178,33 +178,23 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, goto err_destroy_gem; }
- helper->fbdev = fbi; - fbi->par = helper; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->fbops = &exynos_drm_fb_ops;
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - DRM_ERROR("failed to allocate cmap.\n"); - goto err_destroy_framebuffer; - } - ret = exynos_drm_fbdev_update(helper, sizes, helper->fb); if (ret < 0) - goto err_dealloc_cmap; + goto err_destroy_framebuffer;
mutex_unlock(&dev->struct_mutex); return ret;
-err_dealloc_cmap: - fb_dealloc_cmap(&fbi->cmap); err_destroy_framebuffer: drm_framebuffer_cleanup(helper->fb); err_destroy_gem: exynos_drm_gem_destroy(exynos_gem_obj); -err_release_framebuffer: - framebuffer_release(fbi); +err_release_fbi: + drm_fb_helper_release_fbi(helper);
/* * if failed, all resources allocated above would be released by @@ -312,21 +302,8 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev, } }
- /* release linux framebuffer */ - if (fb_helper->fbdev) { - struct fb_info *info; - int ret; - - info = fb_helper->fbdev; - ret = unregister_framebuffer(info); - if (ret < 0) - DRM_DEBUG_KMS("failed unregister_framebuffer()\n"); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(fb_helper); + drm_fb_helper_release_fbi(fb_helper);
drm_fb_helper_fini(fb_helper); }
On 2015년 07월 22일 15:59, Archit Taneja wrote:
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Acked-by: Inki Dae inki.dae@samsung.com
Thanks, Inki Dae
Cc: Inki Dae inki.dae@samsung.com Cc: Joonyoung Shim jy0922.shim@samsung.com Cc: Seung-Woo Kim sw0312.kim@samsung.com
Signed-off-by: Archit Taneja architt@codeaurora.org
drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 47 ++++++++----------------------- 1 file changed, 12 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index e0b085b..dd64bc0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -65,9 +65,9 @@ static int exynos_drm_fb_mmap(struct fb_info *info, static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, .fb_mmap = exynos_drm_fb_mmap,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_fillrect = drm_fb_helper_cfb_fillrect,
- .fb_copyarea = drm_fb_helper_cfb_copyarea,
- .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank,
@@ -142,10 +142,10 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- fbi = framebuffer_alloc(0, &pdev->dev);
- if (!fbi) {
- fbi = drm_fb_helper_alloc_fbi(helper);
- if (IS_ERR(fbi)) { DRM_ERROR("failed to allocate fb info.\n");
ret = -ENOMEM;
goto out; }ret = PTR_ERR(fbi);
@@ -165,7 +165,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
if (IS_ERR(exynos_gem_obj)) { ret = PTR_ERR(exynos_gem_obj);
goto err_release_framebuffer;
goto err_release_fbi;
}
exynos_fbdev->exynos_gem_obj = exynos_gem_obj;
@@ -178,33 +178,23 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, goto err_destroy_gem; }
helper->fbdev = fbi;
fbi->par = helper; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->fbops = &exynos_drm_fb_ops;
ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
if (ret) {
DRM_ERROR("failed to allocate cmap.\n");
goto err_destroy_framebuffer;
}
ret = exynos_drm_fbdev_update(helper, sizes, helper->fb); if (ret < 0)
goto err_dealloc_cmap;
goto err_destroy_framebuffer;
mutex_unlock(&dev->struct_mutex); return ret;
-err_dealloc_cmap:
- fb_dealloc_cmap(&fbi->cmap);
err_destroy_framebuffer: drm_framebuffer_cleanup(helper->fb); err_destroy_gem: exynos_drm_gem_destroy(exynos_gem_obj); -err_release_framebuffer:
- framebuffer_release(fbi);
+err_release_fbi:
- drm_fb_helper_release_fbi(helper);
/*
- if failed, all resources allocated above would be released by
@@ -312,21 +302,8 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev, } }
- /* release linux framebuffer */
- if (fb_helper->fbdev) {
struct fb_info *info;
int ret;
info = fb_helper->fbdev;
ret = unregister_framebuffer(info);
if (ret < 0)
DRM_DEBUG_KMS("failed unregister_framebuffer()\n");
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
- }
drm_fb_helper_unregister_fbi(fb_helper);
drm_fb_helper_release_fbi(fb_helper);
drm_fb_helper_fini(fb_helper);
}
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Patrik Jakobsson patrik.r.jakobsson@gmail.com Cc: Daniel Vetter daniel.vetter@ffwll.ch
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/gma500/accel_2d.c | 6 ++--- drivers/gpu/drm/gma500/framebuffer.c | 48 ++++++++++++------------------------ 2 files changed, 19 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/gma500/accel_2d.c b/drivers/gpu/drm/gma500/accel_2d.c index de6f62a..db9f7d0 100644 --- a/drivers/gpu/drm/gma500/accel_2d.c +++ b/drivers/gpu/drm/gma500/accel_2d.c @@ -276,12 +276,12 @@ static void psbfb_copyarea_accel(struct fb_info *info, break; default: /* software fallback */ - cfb_copyarea(info, a); + drm_fb_helper_cfb_copyarea(info, a); return; }
if (!gma_power_begin(dev, false)) { - cfb_copyarea(info, a); + drm_fb_helper_cfb_copyarea(info, a); return; } psb_accel_2d_copy(dev_priv, @@ -308,7 +308,7 @@ void psbfb_copyarea(struct fb_info *info, /* Avoid the 8 pixel erratum */ if (region->width == 8 || region->height == 8 || (info->flags & FBINFO_HWACCEL_DISABLED)) - return cfb_copyarea(info, region); + return drm_fb_helper_cfb_copyarea(info, region);
psbfb_copyarea_accel(info, region); } diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 2d42ce6..2eaf1b3 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -194,9 +194,9 @@ static struct fb_ops psbfb_ops = { .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = cfb_fillrect, + .fb_fillrect = drm_fb_helper_cfb_fillrect, .fb_copyarea = psbfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_mmap = psbfb_mmap, .fb_sync = psbfb_sync, .fb_ioctl = psbfb_ioctl, @@ -208,9 +208,9 @@ static struct fb_ops psbfb_roll_ops = { .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = psbfb_pan, .fb_mmap = psbfb_mmap, .fb_ioctl = psbfb_ioctl, @@ -222,9 +222,9 @@ static struct fb_ops psbfb_unaccel_ops = { .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_mmap = psbfb_mmap, .fb_ioctl = psbfb_ioctl, }; @@ -343,7 +343,6 @@ static int psbfb_create(struct psb_fbdev *fbdev, struct drm_framebuffer *fb; struct psb_framebuffer *psbfb = &fbdev->pfb; struct drm_mode_fb_cmd2 mode_cmd; - struct device *device = &dev->pdev->dev; int size; int ret; struct gtt_range *backing; @@ -409,9 +408,9 @@ static int psbfb_create(struct psb_fbdev *fbdev,
mutex_lock(&dev->struct_mutex);
- info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(&fbdev->psb_fb_helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_err1; } info->par = fbdev; @@ -426,7 +425,6 @@ static int psbfb_create(struct psb_fbdev *fbdev, psbfb->fbdev = info;
fbdev->psb_fb_helper.fb = fb; - fbdev->psb_fb_helper.fbdev = info;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); strcpy(info->fix.id, "psbdrmfb"); @@ -440,12 +438,6 @@ static int psbfb_create(struct psb_fbdev *fbdev, } else /* Software */ info->fbops = &psbfb_unaccel_ops;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; - } - info->fix.smem_start = dev->mode_config.fb_base; info->fix.smem_len = size; info->fix.ywrapstep = gtt_roll; @@ -456,11 +448,6 @@ static int psbfb_create(struct psb_fbdev *fbdev, info->screen_size = size;
if (dev_priv->gtt.stolen_size) { - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } info->apertures->ranges[0].base = dev->mode_config.fb_base; info->apertures->ranges[0].size = dev_priv->gtt.stolen_size; } @@ -483,6 +470,8 @@ out_unref: psb_gtt_free_range(dev, backing); else drm_gem_object_unreference(&backing->gem); + + drm_fb_helper_release_fbi(&fbdev->psb_fb_helper); out_err1: mutex_unlock(&dev->struct_mutex); psb_gtt_free_range(dev, backing); @@ -570,16 +559,11 @@ static const struct drm_fb_helper_funcs psb_fb_helper_funcs = {
static int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev) { - struct fb_info *info; struct psb_framebuffer *psbfb = &fbdev->pfb;
- if (fbdev->psb_fb_helper.fbdev) { - info = fbdev->psb_fb_helper.fbdev; - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&fbdev->psb_fb_helper); + drm_fb_helper_release_fbi(&fbdev->psb_fb_helper); + drm_fb_helper_fini(&fbdev->psb_fb_helper); drm_framebuffer_unregister_private(&psbfb->base); drm_framebuffer_cleanup(&psbfb->base);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: David Airlie airlied@linux.ie Cc: Alex Deucher alexander.deucher@amd.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/mgag200/mgag200_drv.c | 3 ++- drivers/gpu/drm/mgag200/mgag200_fb.c | 39 +++++++--------------------------- drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- 3 files changed, 11 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 9774599..38363f8 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -55,7 +55,8 @@ static void mgag200_kick_out_firmware_fb(struct pci_dev *pdev) #ifdef CONFIG_X86 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif - remove_conflicting_framebuffers(ap, "mgag200drmfb", primary); + drm_fb_helper_remove_conflicting_framebuffers(ap, "mgag200drmfb", + primary); kfree(ap); }
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c index c36b830..dc06f8b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_fb.c +++ b/drivers/gpu/drm/mgag200/mgag200_fb.c @@ -101,7 +101,7 @@ static void mga_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct mga_fbdev *mfbdev = info->par; - sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect); mga_dirty_update(mfbdev, rect->dx, rect->dy, rect->width, rect->height); } @@ -110,7 +110,7 @@ static void mga_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct mga_fbdev *mfbdev = info->par; - sys_copyarea(info, area); + drm_fb_helper_sys_copyarea(info, area); mga_dirty_update(mfbdev, area->dx, area->dy, area->width, area->height); } @@ -119,7 +119,7 @@ static void mga_imageblit(struct fb_info *info, const struct fb_image *image) { struct mga_fbdev *mfbdev = info->par; - sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image); mga_dirty_update(mfbdev, image->dx, image->dy, image->width, image->height); } @@ -166,7 +166,6 @@ static int mgag200fb_create(struct drm_fb_helper *helper, struct fb_info *info; struct drm_framebuffer *fb; struct drm_gem_object *gobj = NULL; - struct device *device = &dev->pdev->dev; struct mgag200_bo *bo; int ret; void *sysram; @@ -191,9 +190,9 @@ static int mgag200fb_create(struct drm_fb_helper *helper, if (!sysram) return -ENOMEM;
- info = framebuffer_alloc(0, device); - if (info == NULL) - return -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) + return PTR_ERR(info);
info->par = mfbdev;
@@ -208,14 +207,6 @@ static int mgag200fb_create(struct drm_fb_helper *helper,
/* setup helper */ mfbdev->helper.fb = fb; - mfbdev->helper.fbdev = info; - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - DRM_ERROR("%s: can't allocate color map\n", info->fix.id); - ret = -ENOMEM; - goto out; - }
strcpy(info->fix.id, "mgadrmfb");
@@ -223,11 +214,6 @@ static int mgag200fb_create(struct drm_fb_helper *helper, info->fbops = &mgag200fb_ops;
/* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out; - } info->apertures->ranges[0].base = mdev->dev->mode_config.fb_base; info->apertures->ranges[0].size = mdev->mc.vram_size;
@@ -242,24 +228,15 @@ static int mgag200fb_create(struct drm_fb_helper *helper, DRM_DEBUG_KMS("allocated %dx%d\n", fb->width, fb->height); return 0; -out: - return ret; }
static int mga_fbdev_destroy(struct drm_device *dev, struct mga_fbdev *mfbdev) { - struct fb_info *info; struct mga_framebuffer *mfb = &mfbdev->mfb;
- if (mfbdev->helper.fbdev) { - info = mfbdev->helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&mfbdev->helper); + drm_fb_helper_release_fbi(&mfbdev->helper);
if (mfb->obj) { drm_gem_object_unreference_unlocked(mfb->obj); diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index f6b283b..b435d3c 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -128,7 +128,7 @@ static int mga_vram_init(struct mga_device *mdev) aper->ranges[0].base = mdev->mc.vram_base; aper->ranges[0].size = mdev->mc.vram_window;
- remove_conflicting_framebuffers(aper, "mgafb", true); + drm_fb_helper_remove_conflicting_framebuffers(aper, "mgafb", true); kfree(aper);
if (!devm_request_mem_region(mdev->dev->dev, mdev->mc.vram_base, mdev->mc.vram_window,
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Alex Deucher alexander.deucher@amd.com Cc: "Christian König" christian.koenig@amd.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/radeon/radeon_drv.c | 4 +++- drivers/gpu/drm/radeon/radeon_fb.c | 42 +++++++++++-------------------------- 2 files changed, 15 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 5751446..98ee541 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -39,6 +39,7 @@ #include <linux/pm_runtime.h> #include <linux/vga_switcheroo.h> #include <drm/drm_gem.h> +#include <drm/drm_fb_helper.h>
#include "drm_crtc_helper.h" #include "radeon_kfd.h" @@ -390,7 +391,8 @@ static int radeon_kick_out_firmware_fb(struct pci_dev *pdev) #ifdef CONFIG_X86 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif - remove_conflicting_framebuffers(ap, "radeondrmfb", primary); + drm_fb_helper_remove_conflicting_framebuffers(ap, "radeondrmfb", + primary); kfree(ap);
return 0; diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 634793e..e0fcd3d 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -82,9 +82,9 @@ static struct fb_ops radeonfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = radeon_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -227,7 +227,6 @@ static int radeonfb_create(struct drm_fb_helper *helper, struct drm_mode_fb_cmd2 mode_cmd; struct drm_gem_object *gobj = NULL; struct radeon_bo *rbo = NULL; - struct device *device = &rdev->pdev->dev; int ret; unsigned long tmp;
@@ -250,9 +249,9 @@ static int radeonfb_create(struct drm_fb_helper *helper, rbo = gem_to_radeon_bo(gobj);
/* okay we have an object now allocate the framebuffer */ - info = framebuffer_alloc(0, device); - if (info == NULL) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_unref; }
@@ -261,14 +260,13 @@ static int radeonfb_create(struct drm_fb_helper *helper, ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); if (ret) { DRM_ERROR("failed to initialize framebuffer %d\n", ret); - goto out_unref; + goto out_destroy_fbi; }
fb = &rfbdev->rfb.base;
/* setup helper */ rfbdev->helper.fb = fb; - rfbdev->helper.fbdev = info;
memset_io(rbo->kptr, 0x0, radeon_bo_size(rbo));
@@ -288,11 +286,6 @@ static int radeonfb_create(struct drm_fb_helper *helper, drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
/* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; info->apertures->ranges[0].size = rdev->mc.aper_size;
@@ -300,13 +293,7 @@ static int radeonfb_create(struct drm_fb_helper *helper,
if (info->screen_base == NULL) { ret = -ENOSPC; - goto out_unref; - } - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; + goto out_destroy_fbi; }
DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); @@ -318,6 +305,8 @@ static int radeonfb_create(struct drm_fb_helper *helper, vga_switcheroo_client_fb_set(rdev->ddev->pdev, info); return 0;
+out_destroy_fbi: + drm_fb_helper_release_fbi(helper); out_unref: if (rbo) {
@@ -338,17 +327,10 @@ void radeon_fb_output_poll_changed(struct radeon_device *rdev)
static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev) { - struct fb_info *info; struct radeon_framebuffer *rfb = &rfbdev->rfb;
- if (rfbdev->helper.fbdev) { - info = rfbdev->helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&rfbdev->helper); + drm_fb_helper_release_fbi(&rfbdev->helper);
if (rfb->obj) { radeonfb_destroy_pinned_object(rfb->obj);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: Frediano Ziglio fziglio@redhat.com Cc: Maarten Lankhorst maarten.lankhorst@canonical.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/qxl/qxl_fb.c | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 6b6e57e..41c422f 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c @@ -197,7 +197,7 @@ static void qxl_fb_fillrect(struct fb_info *info, { struct qxl_fbdev *qfbdev = info->par;
- sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect); qxl_dirty_update(qfbdev, rect->dx, rect->dy, rect->width, rect->height); } @@ -207,7 +207,7 @@ static void qxl_fb_copyarea(struct fb_info *info, { struct qxl_fbdev *qfbdev = info->par;
- sys_copyarea(info, area); + drm_fb_helper_sys_copyarea(info, area); qxl_dirty_update(qfbdev, area->dx, area->dy, area->width, area->height); } @@ -217,7 +217,7 @@ static void qxl_fb_imageblit(struct fb_info *info, { struct qxl_fbdev *qfbdev = info->par;
- sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image); qxl_dirty_update(qfbdev, image->dx, image->dy, image->width, image->height); } @@ -345,7 +345,6 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, struct drm_mode_fb_cmd2 mode_cmd; struct drm_gem_object *gobj = NULL; struct qxl_bo *qbo = NULL; - struct device *device = &qdev->pdev->dev; int ret; int size; int bpp = sizes->surface_bpp; @@ -374,9 +373,9 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, shadow); size = mode_cmd.pitches[0] * mode_cmd.height;
- info = framebuffer_alloc(0, device); - if (info == NULL) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(&qfbdev->helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_unref; }
@@ -388,7 +387,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev,
/* setup helper with fb data */ qfbdev->helper.fb = fb; - qfbdev->helper.fbdev = info; + qfbdev->shadow = shadow; strcpy(info->fix.id, "qxldrmfb");
@@ -410,11 +409,6 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, sizes->fb_height);
/* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } info->apertures->ranges[0].base = qdev->ddev->mode_config.fb_base; info->apertures->ranges[0].size = qdev->vram_size;
@@ -423,13 +417,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev,
if (info->screen_base == NULL) { ret = -ENOSPC; - goto out_unref; - } - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; + goto out_destroy_fbi; }
info->fbdefio = &qxl_defio; @@ -441,6 +429,8 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, DRM_INFO("fb: depth %d, pitch %d, width %d, height %d\n", fb->depth, fb->pitches[0], fb->width, fb->height); return 0;
+out_destroy_fbi: + drm_fb_helper_release_fbi(&qfbdev->helper); out_unref: if (qbo) { ret = qxl_bo_reserve(qbo, false); @@ -479,15 +469,11 @@ static int qxl_fb_find_or_create_single(
static int qxl_fbdev_destroy(struct drm_device *dev, struct qxl_fbdev *qfbdev) { - struct fb_info *info; struct qxl_framebuffer *qfb = &qfbdev->qfb;
- if (qfbdev->helper.fbdev) { - info = qfbdev->helper.fbdev; + drm_fb_helper_unregister_fbi(&qfbdev->helper); + drm_fb_helper_release_fbi(&qfbdev->helper);
- unregister_framebuffer(info); - framebuffer_release(info); - } if (qfb->obj) { qxlfb_destroy_pinned_object(qfb->obj); qfb->obj = NULL; @@ -557,7 +543,7 @@ void qxl_fbdev_fini(struct qxl_device *qdev)
void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state) { - fb_set_suspend(qdev->mode_info.qfbdev->helper.fbdev, state); + drm_fb_helper_set_suspend(&qdev->mode_info.qfbdev->helper, state); }
bool qxl_fbdev_qobj_is_fb(struct qxl_device *qdev, struct qxl_bo *qobj)
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Daniel Vetter daniel.vetter@intel.com Cc: Jani Nikula jani.nikula@linux.intel.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/i915/i915_dma.c | 3 ++- drivers/gpu/drm/i915/intel_fbdev.c | 40 ++++++++++++-------------------------- 2 files changed, 14 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d2df321..10f6019 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -498,7 +498,8 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
- ret = remove_conflicting_framebuffers(ap, "inteldrmfb", primary); + ret = drm_fb_helper_remove_conflicting_framebuffers(ap, "inteldrmfb", + primary);
kfree(ap);
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 6372cfc..4aa21f7 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -126,9 +126,9 @@ static struct fb_ops intelfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = intel_fbdev_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = intel_fbdev_pan_display, .fb_blank = intel_fbdev_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -237,9 +237,9 @@ static int intelfb_create(struct drm_fb_helper *helper, obj = intel_fb->obj; size = obj->base.size;
- info = framebuffer_alloc(0, &dev->pdev->dev); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_unpin; }
@@ -248,24 +248,13 @@ static int intelfb_create(struct drm_fb_helper *helper, fb = &ifbdev->fb->base;
ifbdev->helper.fb = fb; - ifbdev->helper.fbdev = info;
strcpy(info->fix.id, "inteldrmfb");
info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->fbops = &intelfb_ops;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unpin; - } /* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unpin; - } info->apertures->ranges[0].base = dev->mode_config.fb_base; info->apertures->ranges[0].size = dev_priv->gtt.mappable_end;
@@ -277,7 +266,7 @@ static int intelfb_create(struct drm_fb_helper *helper, size); if (!info->screen_base) { ret = -ENOSPC; - goto out_unpin; + goto out_destroy_fbi; } info->screen_size = size;
@@ -304,6 +293,8 @@ static int intelfb_create(struct drm_fb_helper *helper, vga_switcheroo_client_fb_set(dev->pdev, info); return 0;
+out_destroy_fbi: + drm_fb_helper_release_fbi(helper); out_unpin: i915_gem_object_ggtt_unpin(obj); drm_gem_object_unreference(&obj->base); @@ -550,16 +541,9 @@ static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { static void intel_fbdev_destroy(struct drm_device *dev, struct intel_fbdev *ifbdev) { - if (ifbdev->helper.fbdev) { - struct fb_info *info = ifbdev->helper.fbdev;
- unregister_framebuffer(info); - iounmap(info->screen_base); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&ifbdev->helper); + drm_fb_helper_release_fbi(&ifbdev->helper);
drm_fb_helper_fini(&ifbdev->helper);
@@ -810,7 +794,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen) memset_io(info->screen_base, 0, info->screen_size);
- fb_set_suspend(info, state); + drm_fb_helper_set_suspend(&ifbdev->helper, state); console_unlock(); }
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: Ben Skeggs bskeggs@redhat.com Cc: Alexandre Courbot acourbot@nvidia.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 ++- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 39 ++++++++++----------------------- 2 files changed, 14 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 649024d..01d3fb2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -317,7 +317,8 @@ static int nouveau_drm_probe(struct pci_dev *pdev, boot = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif if (nouveau_modeset != 2) - remove_conflicting_framebuffers(aper, "nouveaufb", boot); + drm_fb_helper_remove_conflicting_framebuffers(aper, "nouveaufb", + boot); kfree(aper);
ret = nvkm_device_create(pdev, NVKM_BUS_PCI, diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 6751553..2791701 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -84,7 +84,7 @@ nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
if (ret != -ENODEV) nouveau_fbcon_gpu_lockup(info); - cfb_fillrect(info, rect); + drm_fb_helper_cfb_fillrect(info, rect); }
static void @@ -116,7 +116,7 @@ nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
if (ret != -ENODEV) nouveau_fbcon_gpu_lockup(info); - cfb_copyarea(info, image); + drm_fb_helper_cfb_copyarea(info, image); }
static void @@ -148,7 +148,7 @@ nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
if (ret != -ENODEV) nouveau_fbcon_gpu_lockup(info); - cfb_imageblit(info, image); + drm_fb_helper_cfb_imageblit(info, image); }
static int @@ -197,9 +197,9 @@ static struct fb_ops nouveau_fbcon_sw_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -319,7 +319,6 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, struct nouveau_channel *chan; struct nouveau_bo *nvbo; struct drm_mode_fb_cmd2 mode_cmd; - struct pci_dev *pdev = dev->pdev; int size, ret;
mode_cmd.width = sizes->surface_width; @@ -365,20 +364,13 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- info = framebuffer_alloc(0, &pdev->dev); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_unlock; } info->skip_vt_switch = 1;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - framebuffer_release(info); - goto out_unlock; - } - info->par = fbcon;
nouveau_framebuffer_init(dev, &fbcon->nouveau_fb, &mode_cmd, nvbo); @@ -388,7 +380,6 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
/* setup helper */ fbcon->helper.fb = fb; - fbcon->helper.fbdev = info;
strcpy(info->fix.id, "nouveaufb"); if (!chan) @@ -450,15 +441,9 @@ static int nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) { struct nouveau_framebuffer *nouveau_fb = &fbcon->nouveau_fb; - struct fb_info *info;
- if (fbcon->helper.fbdev) { - info = fbcon->helper.fbdev; - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&fbcon->helper); + drm_fb_helper_release_fbi(&fbcon->helper);
if (nouveau_fb->nvbo) { nouveau_bo_unmap(nouveau_fb->nvbo); @@ -496,7 +481,7 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state) console_lock(); if (state == FBINFO_STATE_RUNNING) nouveau_fbcon_accel_restore(dev); - fb_set_suspend(drm->fbcon->helper.fbdev, state); + drm_fb_helper_set_suspend(&drm->fbcon->helper, state); if (state != FBINFO_STATE_RUNNING) nouveau_fbcon_accel_save_disable(dev); console_unlock();
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: Haixia Shi hshi@chromium.org Cc: "Stéphane Marchesin" marcheu@chromium.org
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/udl/udl_fb.c | 41 ++++++++++++----------------------------- 1 file changed, 12 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 5fc16ce..62c7b1d 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -288,7 +288,7 @@ static void udl_fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect { struct udl_fbdev *ufbdev = info->par;
- sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect);
udl_handle_damage(&ufbdev->ufb, rect->dx, rect->dy, rect->width, rect->height); @@ -298,7 +298,7 @@ static void udl_fb_copyarea(struct fb_info *info, const struct fb_copyarea *regi { struct udl_fbdev *ufbdev = info->par;
- sys_copyarea(info, region); + drm_fb_helper_sys_copyarea(info, region);
udl_handle_damage(&ufbdev->ufb, region->dx, region->dy, region->width, region->height); @@ -308,7 +308,7 @@ static void udl_fb_imageblit(struct fb_info *info, const struct fb_image *image) { struct udl_fbdev *ufbdev = info->par;
- sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image);
udl_handle_damage(&ufbdev->ufb, image->dx, image->dy, image->width, image->height); @@ -476,7 +476,6 @@ static int udlfb_create(struct drm_fb_helper *helper, container_of(helper, struct udl_fbdev, helper); struct drm_device *dev = ufbdev->helper.dev; struct fb_info *info; - struct device *device = dev->dev; struct drm_framebuffer *fb; struct drm_mode_fb_cmd2 mode_cmd; struct udl_gem_object *obj; @@ -506,21 +505,20 @@ static int udlfb_create(struct drm_fb_helper *helper, goto out_gfree; }
- info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_gfree; } info->par = ufbdev;
ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, obj); if (ret) - goto out_gfree; + goto out_destroy_fbi;
fb = &ufbdev->ufb.base;
ufbdev->helper.fb = fb; - ufbdev->helper.fbdev = info;
strcpy(info->fix.id, "udldrmfb");
@@ -533,18 +531,13 @@ static int udlfb_create(struct drm_fb_helper *helper, drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(info, &ufbdev->helper, sizes->fb_width, sizes->fb_height);
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_gfree; - } - - DRM_DEBUG_KMS("allocated %dx%d vmal %p\n", fb->width, fb->height, ufbdev->ufb.obj->vmapping);
return ret; +out_destroy_fbi: + drm_fb_helper_release_fbi(helper); out_gfree: drm_gem_object_unreference(&ufbdev->ufb.obj->base); out: @@ -558,14 +551,8 @@ static const struct drm_fb_helper_funcs udl_fb_helper_funcs = { static void udl_fbdev_destroy(struct drm_device *dev, struct udl_fbdev *ufbdev) { - struct fb_info *info; - if (ufbdev->helper.fbdev) { - info = ufbdev->helper.fbdev; - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&ufbdev->helper); + drm_fb_helper_release_fbi(&ufbdev->helper); drm_fb_helper_fini(&ufbdev->helper); drm_framebuffer_unregister_private(&ufbdev->ufb.base); drm_framebuffer_cleanup(&ufbdev->ufb.base); @@ -631,11 +618,7 @@ void udl_fbdev_unplug(struct drm_device *dev) return;
ufbdev = udl->fbdev; - if (ufbdev->helper.fbdev) { - struct fb_info *info; - info = ufbdev->helper.fbdev; - unlink_framebuffer(info); - } + drm_fb_helper_unlink_fbi(&ufbdev->helper); }
struct drm_framebuffer *
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/bochs/bochs_drv.c | 6 +++--- drivers/gpu/drm/bochs/bochs_fbdev.c | 36 +++++++++++------------------------- 2 files changed, 14 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index 98837bd..7802fc6 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -109,7 +109,7 @@ static int bochs_pm_suspend(struct device *dev)
if (bochs->fb.initialized) { console_lock(); - fb_set_suspend(bochs->fb.helper.fbdev, 1); + drm_fb_helper_set_suspend(&bochs->fb.helper, 1); console_unlock(); }
@@ -126,7 +126,7 @@ static int bochs_pm_resume(struct device *dev)
if (bochs->fb.initialized) { console_lock(); - fb_set_suspend(bochs->fb.helper.fbdev, 0); + drm_fb_helper_set_suspend(&bochs->fb.helper, 0); console_unlock(); }
@@ -153,7 +153,7 @@ static int bochs_kick_out_firmware_fb(struct pci_dev *pdev)
ap->ranges[0].base = pci_resource_start(pdev, 0); ap->ranges[0].size = pci_resource_len(pdev, 0); - remove_conflicting_framebuffers(ap, "bochsdrmfb", false); + drm_fb_helper_remove_conflicting_framebuffers(ap, "bochsdrmfb", false); kfree(ap);
return 0; diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c index 976d979..09a0637 100644 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ b/drivers/gpu/drm/bochs/bochs_fbdev.c @@ -24,9 +24,9 @@ static struct fb_ops bochsfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -56,11 +56,9 @@ static int bochsfb_create(struct drm_fb_helper *helper, { struct bochs_device *bochs = container_of(helper, struct bochs_device, fb.helper); - struct drm_device *dev = bochs->dev; struct fb_info *info; struct drm_framebuffer *fb; struct drm_mode_fb_cmd2 mode_cmd; - struct device *device = &dev->pdev->dev; struct drm_gem_object *gobj = NULL; struct bochs_bo *bo = NULL; int size, ret; @@ -106,22 +104,23 @@ static int bochsfb_create(struct drm_fb_helper *helper, ttm_bo_unreserve(&bo->bo);
/* init fb device */ - info = framebuffer_alloc(0, device); - if (info == NULL) - return -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) + return PTR_ERR(info);
info->par = &bochs->fb.helper;
ret = bochs_framebuffer_init(bochs->dev, &bochs->fb.gfb, &mode_cmd, gobj); - if (ret) + if (ret) { + drm_fb_helper_release_fbi(helper); return ret; + }
bochs->fb.size = size;
/* setup helper */ fb = &bochs->fb.gfb.base; bochs->fb.helper.fb = fb; - bochs->fb.helper.fbdev = info;
strcpy(info->fix.id, "bochsdrmfb");
@@ -139,30 +138,17 @@ static int bochsfb_create(struct drm_fb_helper *helper, info->fix.smem_start = 0; info->fix.smem_len = size;
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - DRM_ERROR("%s: can't allocate color map\n", info->fix.id); - return -ENOMEM; - } - return 0; }
static int bochs_fbdev_destroy(struct bochs_device *bochs) { struct bochs_framebuffer *gfb = &bochs->fb.gfb; - struct fb_info *info;
DRM_DEBUG_DRIVER("\n");
- if (bochs->fb.helper.fbdev) { - info = bochs->fb.helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&bochs->fb.helper); + drm_fb_helper_release_fbi(&bochs->fb.helper);
if (gfb->obj) { drm_gem_object_unreference_unlocked(gfb->obj);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
v2: Fixed PTR_ERR issue mentioned by kbuild bot
Cc: Fengguang Wu fengguang.wu@intel.com Cc: Alex Deucher alexander.deucher@amd.com Cc: Oded Gabbay oded.gabbay@gmail.com Cc: "Christian König" christian.koenig@amd.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 45 ++++++++++----------------------- 2 files changed, 17 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 56da962..52d7cfd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -35,6 +35,7 @@ #include "amdgpu_drv.h"
#include <drm/drm_pciids.h> +#include <drm/drm_fb_helper.h> #include <linux/console.h> #include <linux/module.h> #include <linux/pm_runtime.h> @@ -267,7 +268,8 @@ static int amdgpu_kick_out_firmware_fb(struct pci_dev *pdev) #ifdef CONFIG_X86 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif - remove_conflicting_framebuffers(ap, "amdgpudrmfb", primary); + drm_fb_helper_remove_conflicting_framebuffers(ap, "amdgpudrmfb", + primary); kfree(ap);
return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index c1645d2..81b8212 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -53,9 +53,9 @@ static struct fb_ops amdgpufb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -179,7 +179,6 @@ static int amdgpufb_create(struct drm_fb_helper *helper, struct drm_mode_fb_cmd2 mode_cmd; struct drm_gem_object *gobj = NULL; struct amdgpu_bo *rbo = NULL; - struct device *device = &adev->pdev->dev; int ret; unsigned long tmp;
@@ -201,9 +200,9 @@ static int amdgpufb_create(struct drm_fb_helper *helper, rbo = gem_to_amdgpu_bo(gobj);
/* okay we have an object now allocate the framebuffer */ - info = framebuffer_alloc(0, device); - if (info == NULL) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto out_unref; }
@@ -212,14 +211,13 @@ static int amdgpufb_create(struct drm_fb_helper *helper, ret = amdgpu_framebuffer_init(adev->ddev, &rfbdev->rfb, &mode_cmd, gobj); if (ret) { DRM_ERROR("failed to initialize framebuffer %d\n", ret); - goto out_unref; + goto out_destroy_fbi; }
fb = &rfbdev->rfb.base;
/* setup helper */ rfbdev->helper.fb = fb; - rfbdev->helper.fbdev = info;
memset_io(rbo->kptr, 0x0, amdgpu_bo_size(rbo));
@@ -239,11 +237,6 @@ static int amdgpufb_create(struct drm_fb_helper *helper, drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
/* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } info->apertures->ranges[0].base = adev->ddev->mode_config.fb_base; info->apertures->ranges[0].size = adev->mc.aper_size;
@@ -251,13 +244,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
if (info->screen_base == NULL) { ret = -ENOSPC; - goto out_unref; - } - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; + goto out_destroy_fbi; }
DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); @@ -269,6 +256,8 @@ static int amdgpufb_create(struct drm_fb_helper *helper, vga_switcheroo_client_fb_set(adev->ddev->pdev, info); return 0;
+out_destroy_fbi: + drm_fb_helper_release_fbi(helper); out_unref: if (rbo) {
@@ -290,17 +279,10 @@ void amdgpu_fb_output_poll_changed(struct amdgpu_device *adev)
static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfbdev) { - struct fb_info *info; struct amdgpu_framebuffer *rfb = &rfbdev->rfb;
- if (rfbdev->helper.fbdev) { - info = rfbdev->helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&rfbdev->helper); + drm_fb_helper_release_fbi(&rfbdev->helper);
if (rfb->obj) { amdgpufb_destroy_pinned_object(rfb->obj); @@ -395,7 +377,8 @@ void amdgpu_fbdev_fini(struct amdgpu_device *adev) void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state) { if (adev->mode_info.rfbdev) - fb_set_suspend(adev->mode_info.rfbdev->helper.fbdev, state); + drm_fb_helper_set_suspend(&adev->mode_info.rfbdev->helper, + state); }
int amdgpu_fbdev_total_size(struct amdgpu_device *adev)
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: David Airlie airlied@linux.ie Cc: Gerd Hoffmann kraxel@redhat.com
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 3 ++- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 + drivers/gpu/drm/virtio/virtgpu_fb.c | 32 +++++++++----------------------- 3 files changed, 12 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c index 88a3916..aea1bac 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c +++ b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c @@ -52,7 +52,8 @@ static void virtio_pci_kick_out_firmware_fb(struct pci_dev *pci_dev) primary = pci_dev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
- remove_conflicting_framebuffers(ap, "virtiodrmfb", primary); + drm_fb_helper_remove_conflicting_framebuffers(ap, "virtiodrmfb", + primary);
kfree(ap); } diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 6d4db2d..7b747ba 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -34,6 +34,7 @@ #include <drm/drmP.h> #include <drm/drm_gem.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_fb_helper.h> #include <ttm/ttm_bo_api.h> #include <ttm/ttm_bo_driver.h> #include <ttm/ttm_placement.h> diff --git a/drivers/gpu/drm/virtio/virtgpu_fb.c b/drivers/gpu/drm/virtio/virtgpu_fb.c index df198d9..6a81e08 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fb.c +++ b/drivers/gpu/drm/virtio/virtgpu_fb.c @@ -173,7 +173,7 @@ static void virtio_gpu_3d_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct virtio_gpu_fbdev *vfbdev = info->par; - sys_fillrect(info, rect); + drm_fb_helper_sys_fillrect(info, rect); virtio_gpu_dirty_update(&vfbdev->vgfb, true, rect->dx, rect->dy, rect->width, rect->height); schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); @@ -183,7 +183,7 @@ static void virtio_gpu_3d_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct virtio_gpu_fbdev *vfbdev = info->par; - sys_copyarea(info, area); + drm_fb_helper_sys_copyarea(info, area); virtio_gpu_dirty_update(&vfbdev->vgfb, true, area->dx, area->dy, area->width, area->height); schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); @@ -193,7 +193,7 @@ static void virtio_gpu_3d_imageblit(struct fb_info *info, const struct fb_image *image) { struct virtio_gpu_fbdev *vfbdev = info->par; - sys_imageblit(info, image); + drm_fb_helper_sys_imageblit(info, image); virtio_gpu_dirty_update(&vfbdev->vgfb, true, image->dx, image->dy, image->width, image->height); schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); @@ -230,7 +230,6 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper, struct drm_framebuffer *fb; struct drm_mode_fb_cmd2 mode_cmd = {}; struct virtio_gpu_object *obj; - struct device *device = vgdev->dev; uint32_t resid, format, size; int ret;
@@ -317,18 +316,12 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper, if (ret) goto err_obj_attach;
- info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); goto err_fb_alloc; }
- ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto err_fb_alloc_cmap; - } - info->par = helper;
ret = virtio_gpu_framebuffer_init(dev, &vfbdev->vgfb, @@ -339,7 +332,6 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper, fb = &vfbdev->vgfb.base;
vfbdev->helper.fb = fb; - vfbdev->helper.fbdev = info;
strcpy(info->fix.id, "virtiodrmfb"); info->flags = FBINFO_DEFAULT; @@ -357,9 +349,7 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper, return 0;
err_fb_init: - fb_dealloc_cmap(&info->cmap); -err_fb_alloc_cmap: - framebuffer_release(info); + drm_fb_helper_release_fbi(helper); err_fb_alloc: virtio_gpu_cmd_resource_inval_backing(vgdev, resid); err_obj_attach: @@ -371,15 +361,11 @@ err_obj_vmap: static int virtio_gpu_fbdev_destroy(struct drm_device *dev, struct virtio_gpu_fbdev *vgfbdev) { - struct fb_info *info; struct virtio_gpu_framebuffer *vgfb = &vgfbdev->vgfb;
- if (vgfbdev->helper.fbdev) { - info = vgfbdev->helper.fbdev; + drm_fb_helper_unregister_fbi(&vgfbdev->helper); + drm_fb_helper_release_fbi(&vgfbdev->helper);
- unregister_framebuffer(info); - framebuffer_release(info); - } if (vgfb->obj) vgfb->obj = NULL; drm_fb_helper_fini(&vgfbdev->helper);
Use the newly created wrapper drm_fb_helper functions instead of calling core fbdev functions directly. They also simplify the fb_info creation.
COMPILE TESTED ONLY.
Cc: Lars-Peter Clausen lars@metafoo.de Cc: Daniel Vetter daniel.vetter@ffwll.ch
Signed-off-by: Archit Taneja architt@codeaurora.org --- drivers/gpu/drm/drm_fb_cma_helper.c | 45 +++++++++---------------------------- 1 file changed, 11 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 5c1aca4..0da6a24 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -234,9 +234,9 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_debugfs_show);
static struct fb_ops drm_fbdev_cma_ops = { .owner = THIS_MODULE, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, @@ -275,10 +275,9 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, if (IS_ERR(obj)) return -ENOMEM;
- fbi = framebuffer_alloc(0, dev->dev); - if (!fbi) { - dev_err(dev->dev, "Failed to allocate framebuffer info.\n"); - ret = -ENOMEM; + fbi = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(fbi)) { + ret = PTR_ERR(fbi); goto err_drm_gem_cma_free_object; }
@@ -286,23 +285,16 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, if (IS_ERR(fbdev_cma->fb)) { dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); ret = PTR_ERR(fbdev_cma->fb); - goto err_framebuffer_release; + goto err_fb_info_destroy; }
fb = &fbdev_cma->fb->fb; helper->fb = fb; - helper->fbdev = fbi;
fbi->par = helper; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->fbops = &drm_fbdev_cma_ops;
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - dev_err(dev->dev, "Failed to allocate color map.\n"); - goto err_drm_fb_cma_destroy; - } - drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
@@ -317,11 +309,8 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
return 0;
-err_drm_fb_cma_destroy: - drm_framebuffer_unregister_private(fb); - drm_fb_cma_destroy(fb); -err_framebuffer_release: - framebuffer_release(fbi); +err_fb_info_destroy: + drm_fb_helper_release_fbi(helper); err_drm_gem_cma_free_object: drm_gem_cma_free_object(&obj->base); return ret; @@ -397,20 +386,8 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_init); */ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma) { - if (fbdev_cma->fb_helper.fbdev) { - struct fb_info *info; - int ret; - - info = fbdev_cma->fb_helper.fbdev; - ret = unregister_framebuffer(info); - if (ret < 0) - DRM_DEBUG_KMS("failed unregister_framebuffer()\n"); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } + drm_fb_helper_unregister_fbi(&fbdev_cma->fb_helper); + drm_fb_helper_release_fbi(&fbdev_cma->fb_helper);
if (fbdev_cma->fb) { drm_framebuffer_unregister_private(&fbdev_cma->fb->fb);
On Wed, Jul 22, 2015 at 12:29:36PM +0530, Archit Taneja wrote:
DRM drivers using drm_fb_helpers still call some fbdev core functions. This makes the driver depend on CONFIG_FB, resulting in complicated Kconfig options, and preventing us from creating a top level drm config option to enable/disable FBDEV emulation.
Create new drm_fb_helper functions that replace these fbdev functions.
In most cases, the new helper funcs simply wrap around the original fbdev functions. For a few (like framebufer_alloc), we actually do some work that is currently redundant across multiple drivers.
With these patches, the drivers don't call any fbdev functions directly. They are now called through functions in drm_fb_helper.c. We will later create a fbdev emulation config option to stub out the fb helpers.
The only exception is vmwgfx driver. This doesn't use drm_fb_helper. It creates a fb device how a driver in drivers/video/fbdev would. Maybe this needs to be converted to use drm_fb_helpers.
For more info, have a look at the threads: http://lists.freedesktop.org/archives/dri-devel/2015-March/078729.html http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html
v2:
- Remove if (info) checks in fb_sys functions
- Use 'if (fb_helper && fb_helper->fbdev)' checks where appropriate
- Add kerneldocs for the new helper funcs
- Follow drm way of aligning of arguments in func definitions
- Fixed build error in drm/virtio
- Fixed error cleanup path in drm/tegra
- Fixed build error in drm/rockchip
- Fixed return issue in drm/amdgpu
- Fixed 'unused variable' warnings in bochs, ast, udl and radeon
- Fixed stray goto labels in cirrus, exynos, mgag
When resending patches please also have changelogs per-patch, not just in the cover letter. Otherwise you have to constantly jump back&forth.
Also I'd drop the compile tested only from patches, just adds noise. -Daniel
Archit Taneja (25): drm/fb_helper: Add drm_fb_helper functions to manage fb_info creation drm/fb_helper: Create a wrapper for unlink_framebuffer drm/fb_helper: Create wrappers for fb_sys_read/write funcs drm/fb_helper: Create wrappers for blit, copyarea and fillrect funcs drm/fb_helper: Create a wrapper for fb_set_suspend drm/fb_helper: Create a wrapper for remove_conflicting_framebuffers drm/cirrus: Use new drm_fb_helper functions drm/rockchip: Use new drm_fb_helper functions drm/armada: Use new drm_fb_helper functions drm/ast: Use new drm_fb_helper functions drm/omap: Use new drm_fb_helper functions drm/tegra: Use new drm_fb_helper functions drm/msm: Use new drm_fb_helper functions drm/exynos: Use new drm_fb_helper functions drm/gma500: Use new drm_fb_helper functions drm/mgag200: Use new drm_fb_helper functions drm/radeon: Use new drm_fb_helper functions drm/qxl: Use new drm_fb_helper functions drm/i915: Use new drm_fb_helper functions drm/nouveau: Use new drm_fb_helper functions drm/udl: Use new drm_fb_helper functions drm/bochs: Use new drm_fb_helper functions drm/amdgpu: Use new drm_fb_helper functions drm/virtio: Use new drm_fb_helper functions drm/fb_cma_helper: Use new drm_fb_helper functions
drivers/gpu/drm/Kconfig | 7 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 45 ++---- drivers/gpu/drm/armada/armada_fbdev.c | 33 ++-- drivers/gpu/drm/ast/ast_fb.c | 48 ++---- drivers/gpu/drm/bochs/bochs_drv.c | 6 +- drivers/gpu/drm/bochs/bochs_fbdev.c | 36 ++--- drivers/gpu/drm/cirrus/cirrus_drv.c | 7 +- drivers/gpu/drm/cirrus/cirrus_fbdev.c | 41 +---- drivers/gpu/drm/drm_fb_cma_helper.c | 45 ++---- drivers/gpu/drm/drm_fb_helper.c | 225 ++++++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 47 ++---- drivers/gpu/drm/gma500/accel_2d.c | 6 +- drivers/gpu/drm/gma500/framebuffer.c | 48 ++---- drivers/gpu/drm/i915/i915_dma.c | 3 +- drivers/gpu/drm/i915/intel_fbdev.c | 40 ++--- drivers/gpu/drm/mgag200/mgag200_drv.c | 3 +- drivers/gpu/drm/mgag200/mgag200_fb.c | 39 +---- drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 34 ++-- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 39 ++--- drivers/gpu/drm/omapdrm/omap_fbdev.c | 34 ++-- drivers/gpu/drm/qxl/qxl_fb.c | 40 ++--- drivers/gpu/drm/radeon/radeon_drv.c | 4 +- drivers/gpu/drm/radeon/radeon_fb.c | 42 ++--- drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 47 ++---- drivers/gpu/drm/tegra/fb.c | 35 ++-- drivers/gpu/drm/udl/udl_fb.c | 41 ++--- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 3 +- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 + drivers/gpu/drm/virtio/virtgpu_fb.c | 32 ++-- include/drm/drm_fb_helper.h | 31 ++++ 33 files changed, 508 insertions(+), 563 deletions(-)
-- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
On 07/22/2015 01:11 PM, Daniel Vetter wrote:
On Wed, Jul 22, 2015 at 12:29:36PM +0530, Archit Taneja wrote:
DRM drivers using drm_fb_helpers still call some fbdev core functions. This makes the driver depend on CONFIG_FB, resulting in complicated Kconfig options, and preventing us from creating a top level drm config option to enable/disable FBDEV emulation.
Create new drm_fb_helper functions that replace these fbdev functions.
In most cases, the new helper funcs simply wrap around the original fbdev functions. For a few (like framebufer_alloc), we actually do some work that is currently redundant across multiple drivers.
With these patches, the drivers don't call any fbdev functions directly. They are now called through functions in drm_fb_helper.c. We will later create a fbdev emulation config option to stub out the fb helpers.
The only exception is vmwgfx driver. This doesn't use drm_fb_helper. It creates a fb device how a driver in drivers/video/fbdev would. Maybe this needs to be converted to use drm_fb_helpers.
For more info, have a look at the threads: http://lists.freedesktop.org/archives/dri-devel/2015-March/078729.html http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html
v2:
- Remove if (info) checks in fb_sys functions
- Use 'if (fb_helper && fb_helper->fbdev)' checks where appropriate
- Add kerneldocs for the new helper funcs
- Follow drm way of aligning of arguments in func definitions
- Fixed build error in drm/virtio
- Fixed error cleanup path in drm/tegra
- Fixed build error in drm/rockchip
- Fixed return issue in drm/amdgpu
- Fixed 'unused variable' warnings in bochs, ast, udl and radeon
- Fixed stray goto labels in cirrus, exynos, mgag
When resending patches please also have changelogs per-patch, not just in the cover letter. Otherwise you have to constantly jump back&forth.
Also I'd drop the compile tested only from patches, just adds noise.
I'll remove the 'compile tested only' line from the patches.
About the changelogs per-patch, I'll add them for the drm_fb_helper.c changes, and for a few drm drivers where people found flaws in the changes. I'm going to skip for the ones which were build error/warning fixes found by kbots. I didn't intend the first version to be full proof, just wanted people to have a look.
Thanks, Archit
dri-devel@lists.freedesktop.org