mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-29 04:34:45 -04:00
Some multi GPU systems may have a VGA compatible device, but that might not be
used for display. If due to enumeration order this device is found before the
one actually used for display then multiple devices may show the boot_display
attribute, confusing userspace.
When screen info is valid, use it exclusively to find the primary device so
that only the device backing the framebuffer is reported. Only when no
framebuffer has been set up does it make sense to fall back to the default VGA
device. This ensures at most one primary graphics device, preferably the one
with the framebuffer.
Fixes: ad90860bd1 ("fbcon: Use screen info to find primary device")
Closes: https://lore.kernel.org/linux-pci/20260618081803.2790848-1-aaron.ma@canonical.com/#t
Reported-by: Aaron Ma <aaron.ma@canonical.com>
Suggested-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Tested-by: Aaron Ma <aaron.ma@canonical.com>
Cc: <stable@kernel.org>
Link: https://patch.msgid.link/20260623141505.1816786-1-mario.limonciello@amd.com
70 lines
1.5 KiB
C
70 lines
1.5 KiB
C
/*
|
|
* Copyright (C) 2007 Antonino Daplas <adaplas@gmail.com>
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file COPYING in the main directory of this archive
|
|
* for more details.
|
|
*
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/pci.h>
|
|
#include <linux/sysfb.h>
|
|
#include <linux/vgaarb.h>
|
|
|
|
#include <asm/video.h>
|
|
|
|
pgprot_t pgprot_framebuffer(pgprot_t prot,
|
|
unsigned long vm_start, unsigned long vm_end,
|
|
unsigned long offset)
|
|
{
|
|
pgprot_val(prot) &= ~_PAGE_CACHE_MASK;
|
|
if (boot_cpu_data.x86 > 3)
|
|
pgprot_val(prot) |= cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS);
|
|
|
|
return prot;
|
|
}
|
|
EXPORT_SYMBOL(pgprot_framebuffer);
|
|
|
|
bool video_is_primary_device(struct device *dev)
|
|
{
|
|
#ifdef CONFIG_SCREEN_INFO
|
|
struct screen_info *si = &sysfb_primary_display.screen;
|
|
struct resource res[SCREEN_INFO_MAX_RESOURCES];
|
|
ssize_t i, numres;
|
|
#endif
|
|
struct pci_dev *pdev;
|
|
|
|
if (!dev_is_pci(dev))
|
|
return false;
|
|
|
|
pdev = to_pci_dev(dev);
|
|
|
|
if (!pci_is_display(pdev))
|
|
return false;
|
|
|
|
#ifdef CONFIG_SCREEN_INFO
|
|
numres = screen_info_resources(si, res, ARRAY_SIZE(res));
|
|
if (numres > 0) {
|
|
for (i = 0; i < numres; ++i) {
|
|
if (!(res[i].flags & IORESOURCE_MEM))
|
|
continue;
|
|
|
|
if (pci_find_resource(pdev, &res[i]))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* No framebuffer was set up by the firmware/bootloader, so fall back
|
|
* to the default VGA device.
|
|
*/
|
|
return pdev == vga_default_device();
|
|
}
|
|
EXPORT_SYMBOL(video_is_primary_device);
|
|
|
|
MODULE_LICENSE("GPL");
|