fbdev: fbmem: add a helper to determine if an aperture is used by a fw fb

Add a function for drivers to check if the a firmware initialized
fb is corresponds to their aperture. This allows drivers to check if the
device corresponds to what the firmware set up as the display device.

Bug: https://bugzilla.kernel.org/show_bug.cgi?id=215203
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1840
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+48
+47
drivers/video/fbdev/core/fbmem.c
··· 1763 EXPORT_SYMBOL(remove_conflicting_framebuffers); 1764 1765 /** 1766 * remove_conflicting_pci_framebuffers - remove firmware-configured framebuffers for PCI devices 1767 * @pdev: PCI device 1768 * @name: requesting driver name
··· 1763 EXPORT_SYMBOL(remove_conflicting_framebuffers); 1764 1765 /** 1766 + * is_firmware_framebuffer - detect if firmware-configured framebuffer matches 1767 + * @a: memory range, users of which are to be checked 1768 + * 1769 + * This function checks framebuffer devices (initialized by firmware/bootloader) 1770 + * which use memory range described by @a. If @a matchesm the function returns 1771 + * true, otherwise false. 1772 + */ 1773 + bool is_firmware_framebuffer(struct apertures_struct *a) 1774 + { 1775 + bool do_free = false; 1776 + bool found = false; 1777 + int i; 1778 + 1779 + if (!a) { 1780 + a = alloc_apertures(1); 1781 + if (!a) 1782 + return false; 1783 + 1784 + a->ranges[0].base = 0; 1785 + a->ranges[0].size = ~0; 1786 + do_free = true; 1787 + } 1788 + 1789 + mutex_lock(&registration_lock); 1790 + /* check all firmware fbs and kick off if the base addr overlaps */ 1791 + for_each_registered_fb(i) { 1792 + struct apertures_struct *gen_aper; 1793 + 1794 + if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE)) 1795 + continue; 1796 + 1797 + gen_aper = registered_fb[i]->apertures; 1798 + if (fb_do_apertures_overlap(gen_aper, a)) { 1799 + found = true; 1800 + break; 1801 + } 1802 + } 1803 + mutex_unlock(&registration_lock); 1804 + 1805 + if (do_free) 1806 + kfree(a); 1807 + 1808 + return found; 1809 + } 1810 + EXPORT_SYMBOL(is_firmware_framebuffer); 1811 + 1812 + /** 1813 * remove_conflicting_pci_framebuffers - remove firmware-configured framebuffers for PCI devices 1814 * @pdev: PCI device 1815 * @name: requesting driver name
+1
include/linux/fb.h
··· 610 const char *name); 611 extern int remove_conflicting_framebuffers(struct apertures_struct *a, 612 const char *name, bool primary); 613 extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); 614 extern int fb_show_logo(struct fb_info *fb_info, int rotate); 615 extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
··· 610 const char *name); 611 extern int remove_conflicting_framebuffers(struct apertures_struct *a, 612 const char *name, bool primary); 613 + extern bool is_firmware_framebuffer(struct apertures_struct *a); 614 extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); 615 extern int fb_show_logo(struct fb_info *fb_info, int rotate); 616 extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);