From 15fced5b051e6e22c228a521a5894b12c2ba0892 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 18 Jul 2022 09:23:22 +0200 Subject: [PATCH] fbdev: Remove conflict-handling code Remove the call to do_remove_conflicting_framebuffers() from the framebuffer registration. Aperture helpers take care of removing conflicting devices. With all ownership information stored in the aperture datastrcutures, remove remove_conflicting_framebuffers() entirely. This change also rectifies DRM generic-framebuffer registration, which tried to unregister conflicting framebuffers, even though it's entirely build on top of DRM. v2: * remove internal aperture-overlap helpers, which are now unused Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20220718072322.8927-12-tzimmermann@suse.de --- drivers/video/aperture.c | 21 ------ drivers/video/fbdev/core/fbmem.c | 136 --------------------------------------- include/linux/fb.h | 2 - 3 files changed, 159 deletions(-) diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index abc6912..9e6bcc0 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -2,7 +2,6 @@ #include #include -#include /* for old fbdev helpers */ #include #include #include @@ -286,11 +285,6 @@ static void aperture_detach_devices(resource_size_t base, resource_size_t size) int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, bool primary, const char *name) { -#if IS_REACHABLE(CONFIG_FB) - struct apertures_struct *a; - int ret; -#endif - /* * If a driver asked to unregister a platform device registered by * sysfb, then can be assumed that this is a driver for a display @@ -312,21 +306,6 @@ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t si if (primary) aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); -#if IS_REACHABLE(CONFIG_FB) - a = alloc_apertures(1); - if (!a) - return -ENOMEM; - - a->ranges[0].base = base; - a->ranges[0].size = size; - - ret = remove_conflicting_framebuffers(a, name, primary); - kfree(a); - - if (ret) - return ret; -#endif - return 0; } EXPORT_SYMBOL(aperture_remove_conflicting_devices); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index d790d30..6ae1c5f 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1526,102 +1526,6 @@ static int fb_check_foreignness(struct fb_info *fi) return 0; } -static bool apertures_overlap(struct aperture *gen, struct aperture *hw) -{ - /* is the generic aperture base the same as the HW one */ - if (gen->base == hw->base) - return true; - /* is the generic aperture base inside the hw base->hw base+size */ - if (gen->base > hw->base && gen->base < hw->base + hw->size) - return true; - return false; -} - -static bool fb_do_apertures_overlap(struct apertures_struct *gena, - struct apertures_struct *hwa) -{ - int i, j; - if (!hwa || !gena) - return false; - - for (i = 0; i < hwa->count; ++i) { - struct aperture *h = &hwa->ranges[i]; - for (j = 0; j < gena->count; ++j) { - struct aperture *g = &gena->ranges[j]; - printk(KERN_DEBUG "checking generic (%llx %llx) vs hw (%llx %llx)\n", - (unsigned long long)g->base, - (unsigned long long)g->size, - (unsigned long long)h->base, - (unsigned long long)h->size); - if (apertures_overlap(g, h)) - return true; - } - } - - return false; -} - -static void do_unregister_framebuffer(struct fb_info *fb_info); - -static void do_remove_conflicting_framebuffers(struct apertures_struct *a, - const char *name, bool primary) -{ - int i; - -restart_removal: - /* check all firmware fbs and kick off if the base addr overlaps */ - for_each_registered_fb(i) { - struct apertures_struct *gen_aper; - struct device *device; - - if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE)) - continue; - - gen_aper = registered_fb[i]->apertures; - device = registered_fb[i]->device; - if (fb_do_apertures_overlap(gen_aper, a) || - (primary && gen_aper && gen_aper->count && - gen_aper->ranges[0].base == VGA_FB_PHYS_BASE)) { - - printk(KERN_INFO "fb%d: switching to %s from %s\n", - i, name, registered_fb[i]->fix.id); - - /* - * If we kick-out a firmware driver, we also want to remove - * the underlying platform device, such as simple-framebuffer, - * VESA, EFI, etc. A native driver will then be able to - * allocate the memory range. - * - * If it's not a platform device, at least print a warning. A - * fix would add code to remove the device from the system. For - * framebuffers without any Linux device, print a warning as - * well. - */ - if (!device) { - pr_warn("fb%d: no device set\n", i); - do_unregister_framebuffer(registered_fb[i]); - } else if (dev_is_platform(device)) { - /* - * Drop the lock because if the device is unregistered, its - * driver will call to unregister_framebuffer(), that takes - * this lock. - */ - mutex_unlock(®istration_lock); - platform_device_unregister(to_platform_device(device)); - mutex_lock(®istration_lock); - } else { - pr_warn("fb%d: cannot remove device\n", i); - do_unregister_framebuffer(registered_fb[i]); - } - /* - * Restart the removal loop now that the device has been - * unregistered and its associated framebuffer gone. - */ - goto restart_removal; - } - } -} - static int do_register_framebuffer(struct fb_info *fb_info) { int i; @@ -1630,10 +1534,6 @@ static int do_register_framebuffer(struct fb_info *fb_info) if (fb_check_foreignness(fb_info)) return -ENOSYS; - do_remove_conflicting_framebuffers(fb_info->apertures, - fb_info->fix.id, - fb_is_primary_device(fb_info)); - if (num_registered_fb == FB_MAX) return -ENXIO; @@ -1779,42 +1679,6 @@ static int fb_aperture_acquire_for_platform_device(struct fb_info *fb_info) } /** - * remove_conflicting_framebuffers - remove firmware-configured framebuffers - * @a: memory range, users of which are to be removed - * @name: requesting driver name - * @primary: also kick vga16fb if present - * - * This function removes framebuffer devices (initialized by firmware/bootloader) - * which use memory range described by @a. If @a is NULL all such devices are - * removed. - */ -int remove_conflicting_framebuffers(struct apertures_struct *a, - const char *name, bool primary) -{ - bool do_free = false; - - if (!a) { - a = alloc_apertures(1); - if (!a) - return -ENOMEM; - - a->ranges[0].base = 0; - a->ranges[0].size = ~0; - do_free = true; - } - - mutex_lock(®istration_lock); - do_remove_conflicting_framebuffers(a, name, primary); - mutex_unlock(®istration_lock); - - if (do_free) - kfree(a); - - return 0; -} -EXPORT_SYMBOL(remove_conflicting_framebuffers); - -/** * register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure * diff --git a/include/linux/fb.h b/include/linux/fb.h index b91c770..453c3b2 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -615,8 +615,6 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, /* drivers/video/fbmem.c */ extern int register_framebuffer(struct fb_info *fb_info); extern void unregister_framebuffer(struct fb_info *fb_info); -extern int remove_conflicting_framebuffers(struct apertures_struct *a, - const char *name, bool primary); extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); extern int fb_show_logo(struct fb_info *fb_info, int rotate); extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); -- 2.7.4