Commit 20cde694 authored by Bruno Prémont's avatar Bruno Prémont Committed by Bjorn Helgaas

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

Commit b4aa0163 ("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: b4aa0163 ("efifb: Implement vga_default_device() (v2)")
Tested-by: default avatarAnibal Francisco Martinez Cortina <linuxkid.zeuz@gmail.com>
Signed-off-by: default avatarBruno Prémont <bonbons@linux-vserver.org>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarMatthew Garrett <matthew.garrett@nebula.com>
CC: stable@vger.kernel.org	# v3.5+
parent dcfa9be8
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/vgaarb.h> #include <linux/vgaarb.h>
#include <linux/screen_info.h>
#include <asm/machvec.h> #include <asm/machvec.h>
...@@ -37,6 +38,27 @@ static void pci_fixup_video(struct pci_dev *pdev) ...@@ -37,6 +38,27 @@ static void pci_fixup_video(struct pci_dev *pdev)
return; return;
/* Maybe, this machine supports legacy memory map. */ /* Maybe, this machine supports legacy memory map. */
if (!vga_default_device()) {
resource_size_t start, end;
int i;
/* Does firmware framebuffer belong to us? */
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
continue;
start = pci_resource_start(pdev, i);
end = pci_resource_end(pdev, i);
if (!start || !end)
continue;
if (screen_info.lfb_base >= start &&
(screen_info.lfb_base + screen_info.lfb_size) < end)
vga_set_default_device(pdev);
}
}
/* Is VGA routed to us? */ /* Is VGA routed to us? */
bus = pdev->bus; bus = pdev->bus;
while (bus) { while (bus) {
......
...@@ -17,10 +17,4 @@ ...@@ -17,10 +17,4 @@
#define vga_readb(x) (*(x)) #define vga_readb(x) (*(x))
#define vga_writeb(x, y) (*(y) = (x)) #define vga_writeb(x, y) (*(y) = (x))
#ifdef CONFIG_FB_EFI
#define __ARCH_HAS_VGA_DEFAULT_DEVICE
extern struct pci_dev *vga_default_device(void);
extern void vga_set_default_device(struct pci_dev *pdev);
#endif
#endif /* _ASM_X86_VGA_H */ #endif /* _ASM_X86_VGA_H */
...@@ -326,6 +326,27 @@ static void pci_fixup_video(struct pci_dev *pdev) ...@@ -326,6 +326,27 @@ static void pci_fixup_video(struct pci_dev *pdev)
struct pci_bus *bus; struct pci_bus *bus;
u16 config; u16 config;
if (!vga_default_device()) {
resource_size_t start, end;
int i;
/* Does firmware framebuffer belong to us? */
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
continue;
start = pci_resource_start(pdev, i);
end = pci_resource_end(pdev, i);
if (!start || !end)
continue;
if (screen_info.lfb_base >= start &&
(screen_info.lfb_base + screen_info.lfb_size) < end)
vga_set_default_device(pdev);
}
}
/* Is VGA routed to us? */ /* Is VGA routed to us? */
bus = pdev->bus; bus = pdev->bus;
while (bus) { while (bus) {
......
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
static bool request_mem_succeeded = false; static bool request_mem_succeeded = false;
static struct pci_dev *default_vga;
static struct fb_var_screeninfo efifb_defined = { static struct fb_var_screeninfo efifb_defined = {
.activate = FB_ACTIVATE_NOW, .activate = FB_ACTIVATE_NOW,
.height = -1, .height = -1,
...@@ -84,23 +82,10 @@ static struct fb_ops efifb_ops = { ...@@ -84,23 +82,10 @@ static struct fb_ops efifb_ops = {
.fb_imageblit = cfb_imageblit, .fb_imageblit = cfb_imageblit,
}; };
struct pci_dev *vga_default_device(void)
{
return default_vga;
}
EXPORT_SYMBOL_GPL(vga_default_device);
void vga_set_default_device(struct pci_dev *pdev)
{
default_vga = pdev;
}
static int efifb_setup(char *options) static int efifb_setup(char *options)
{ {
char *this_opt; char *this_opt;
int i; int i;
struct pci_dev *dev = NULL;
if (options && *options) { if (options && *options) {
while ((this_opt = strsep(&options, ",")) != NULL) { while ((this_opt = strsep(&options, ",")) != NULL) {
...@@ -126,30 +111,6 @@ static int efifb_setup(char *options) ...@@ -126,30 +111,6 @@ static int efifb_setup(char *options)
} }
} }
for_each_pci_dev(dev) {
int i;
if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
continue;
for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
resource_size_t start, end;
if (!(pci_resource_flags(dev, i) & IORESOURCE_MEM))
continue;
start = pci_resource_start(dev, i);
end = pci_resource_end(dev, i);
if (!start || !end)
continue;
if (screen_info.lfb_base >= start &&
(screen_info.lfb_base + screen_info.lfb_size) < end)
default_vga = dev;
}
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment