Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86, ia64: Move EFI_FB vga_default_device() initialization to pci_vga_fixup()

Commit b4aa0163056b ("efifb: Implement vga_default_device() (v2)") added
efifb vga_default_device() so EFI systems that do not load shadow VBIOS or
setup VGA get proper value for boot_vga PCI sysfs attribute on the
corresponding PCI device.

Xorg doesn't detect devices when boot_vga=0, e.g., on some EFI systems such
as MacBookAir2,1. Xorg detects the GPU and finds the DRI device but then
bails out with "no devices detected".

Note: When vga_default_device() is set boot_vga PCI sysfs attribute
reflects its state. When unset this attribute is 1 whenever
IORESOURCE_ROM_SHADOW flag is set.

With introduction of sysfb/simplefb/simpledrm efifb is getting obsolete
while having native drivers for the GPU also makes selecting sysfb/efifb
optional.

Remove the efifb implementation of vga_default_device() and initialize
vgaarb's vga_default_device() with the PCI GPU that matches boot
screen_info in pci_fixup_video().

[bhelgaas: remove unused "dev" in efifb_setup()]
Fixes: b4aa0163056b ("efifb: Implement vga_default_device() (v2)")
Tested-by: Anibal Francisco Martinez Cortina <linuxkid.zeuz@gmail.com>
Signed-off-by: Bruno Prémont <bonbons@linux-vserver.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Matthew Garrett <matthew.garrett@nebula.com>
CC: stable@vger.kernel.org # v3.5+

authored by

Bruno Prémont and committed by
Bjorn Helgaas
20cde694 dcfa9be8

+43 -45
+22
arch/ia64/pci/fixup.c
··· 6 6 #include <linux/pci.h> 7 7 #include <linux/init.h> 8 8 #include <linux/vgaarb.h> 9 + #include <linux/screen_info.h> 9 10 10 11 #include <asm/machvec.h> 11 12 ··· 37 36 && (strcmp(ia64_platform_name, "hpzx1") != 0)) 38 37 return; 39 38 /* Maybe, this machine supports legacy memory map. */ 39 + 40 + if (!vga_default_device()) { 41 + resource_size_t start, end; 42 + int i; 43 + 44 + /* Does firmware framebuffer belong to us? */ 45 + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 46 + if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM)) 47 + continue; 48 + 49 + start = pci_resource_start(pdev, i); 50 + end = pci_resource_end(pdev, i); 51 + 52 + if (!start || !end) 53 + continue; 54 + 55 + if (screen_info.lfb_base >= start && 56 + (screen_info.lfb_base + screen_info.lfb_size) < end) 57 + vga_set_default_device(pdev); 58 + } 59 + } 40 60 41 61 /* Is VGA routed to us? */ 42 62 bus = pdev->bus;
-6
arch/x86/include/asm/vga.h
··· 17 17 #define vga_readb(x) (*(x)) 18 18 #define vga_writeb(x, y) (*(y) = (x)) 19 19 20 - #ifdef CONFIG_FB_EFI 21 - #define __ARCH_HAS_VGA_DEFAULT_DEVICE 22 - extern struct pci_dev *vga_default_device(void); 23 - extern void vga_set_default_device(struct pci_dev *pdev); 24 - #endif 25 - 26 20 #endif /* _ASM_X86_VGA_H */
+21
arch/x86/pci/fixup.c
··· 326 326 struct pci_bus *bus; 327 327 u16 config; 328 328 329 + if (!vga_default_device()) { 330 + resource_size_t start, end; 331 + int i; 332 + 333 + /* Does firmware framebuffer belong to us? */ 334 + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 335 + if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM)) 336 + continue; 337 + 338 + start = pci_resource_start(pdev, i); 339 + end = pci_resource_end(pdev, i); 340 + 341 + if (!start || !end) 342 + continue; 343 + 344 + if (screen_info.lfb_base >= start && 345 + (screen_info.lfb_base + screen_info.lfb_size) < end) 346 + vga_set_default_device(pdev); 347 + } 348 + } 349 + 329 350 /* Is VGA routed to us? */ 330 351 bus = pdev->bus; 331 352 while (bus) {
-39
drivers/video/fbdev/efifb.c
··· 19 19 20 20 static bool request_mem_succeeded = false; 21 21 22 - static struct pci_dev *default_vga; 23 - 24 22 static struct fb_var_screeninfo efifb_defined = { 25 23 .activate = FB_ACTIVATE_NOW, 26 24 .height = -1, ··· 82 84 .fb_imageblit = cfb_imageblit, 83 85 }; 84 86 85 - struct pci_dev *vga_default_device(void) 86 - { 87 - return default_vga; 88 - } 89 - 90 - EXPORT_SYMBOL_GPL(vga_default_device); 91 - 92 - void vga_set_default_device(struct pci_dev *pdev) 93 - { 94 - default_vga = pdev; 95 - } 96 - 97 87 static int efifb_setup(char *options) 98 88 { 99 89 char *this_opt; 100 90 int i; 101 - struct pci_dev *dev = NULL; 102 91 103 92 if (options && *options) { 104 93 while ((this_opt = strsep(&options, ",")) != NULL) { ··· 108 123 screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0); 109 124 else if (!strncmp(this_opt, "width:", 6)) 110 125 screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0); 111 - } 112 - } 113 - 114 - for_each_pci_dev(dev) { 115 - int i; 116 - 117 - if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) 118 - continue; 119 - 120 - for (i=0; i < DEVICE_COUNT_RESOURCE; i++) { 121 - resource_size_t start, end; 122 - 123 - if (!(pci_resource_flags(dev, i) & IORESOURCE_MEM)) 124 - continue; 125 - 126 - start = pci_resource_start(dev, i); 127 - end = pci_resource_end(dev, i); 128 - 129 - if (!start || !end) 130 - continue; 131 - 132 - if (screen_info.lfb_base >= start && 133 - (screen_info.lfb_base + screen_info.lfb_size) < end) 134 - default_vga = dev; 135 126 } 136 127 } 137 128