diff options
author | Bruno Prémont <bonbons@linux-vserver.org> | 2014-06-24 18:55:01 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-07-10 18:48:48 -0400 |
commit | 20cde694027e7477cc532833e38ab9fcaa83fb64 (patch) | |
tree | 5f8923f15a5acb1107908a9ea9d0bb5528fe7f70 | |
parent | dcfa9be83866e28fcb8b7e22b4eeb4ba63bd3174 (diff) |
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+
-rw-r--r-- | arch/ia64/pci/fixup.c | 22 | ||||
-rw-r--r-- | arch/x86/include/asm/vga.h | 6 | ||||
-rw-r--r-- | arch/x86/pci/fixup.c | 21 | ||||
-rw-r--r-- | drivers/video/fbdev/efifb.c | 39 |
4 files changed, 43 insertions, 45 deletions
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c index 1fe9aa5068ea..ec73b2cf912a 100644 --- a/arch/ia64/pci/fixup.c +++ b/arch/ia64/pci/fixup.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/pci.h> | 6 | #include <linux/pci.h> |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/vgaarb.h> | 8 | #include <linux/vgaarb.h> |
9 | #include <linux/screen_info.h> | ||
9 | 10 | ||
10 | #include <asm/machvec.h> | 11 | #include <asm/machvec.h> |
11 | 12 | ||
@@ -37,6 +38,27 @@ static void pci_fixup_video(struct pci_dev *pdev) | |||
37 | return; | 38 | return; |
38 | /* Maybe, this machine supports legacy memory map. */ | 39 | /* Maybe, this machine supports legacy memory map. */ |
39 | 40 | ||
41 | if (!vga_default_device()) { | ||
42 | resource_size_t start, end; | ||
43 | int i; | ||
44 | |||
45 | /* Does firmware framebuffer belong to us? */ | ||
46 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
47 | if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM)) | ||
48 | continue; | ||
49 | |||
50 | start = pci_resource_start(pdev, i); | ||
51 | end = pci_resource_end(pdev, i); | ||
52 | |||
53 | if (!start || !end) | ||
54 | continue; | ||
55 | |||
56 | if (screen_info.lfb_base >= start && | ||
57 | (screen_info.lfb_base + screen_info.lfb_size) < end) | ||
58 | vga_set_default_device(pdev); | ||
59 | } | ||
60 | } | ||
61 | |||
40 | /* Is VGA routed to us? */ | 62 | /* Is VGA routed to us? */ |
41 | bus = pdev->bus; | 63 | bus = pdev->bus; |
42 | while (bus) { | 64 | while (bus) { |
diff --git a/arch/x86/include/asm/vga.h b/arch/x86/include/asm/vga.h index 44282fbf7bf9..c4b9dc2f67c5 100644 --- a/arch/x86/include/asm/vga.h +++ b/arch/x86/include/asm/vga.h | |||
@@ -17,10 +17,4 @@ | |||
17 | #define vga_readb(x) (*(x)) | 17 | #define vga_readb(x) (*(x)) |
18 | #define vga_writeb(x, y) (*(y) = (x)) | 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 | #endif /* _ASM_X86_VGA_H */ | 20 | #endif /* _ASM_X86_VGA_H */ |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index b5e60268d93f..c61ea57d1ba1 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -326,6 +326,27 @@ static void pci_fixup_video(struct pci_dev *pdev) | |||
326 | struct pci_bus *bus; | 326 | struct pci_bus *bus; |
327 | u16 config; | 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 | /* Is VGA routed to us? */ | 350 | /* Is VGA routed to us? */ |
330 | bus = pdev->bus; | 351 | bus = pdev->bus; |
331 | while (bus) { | 352 | while (bus) { |
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index ae9618ff6735..982f6abe6faf 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c | |||
@@ -19,8 +19,6 @@ | |||
19 | 19 | ||
20 | static bool request_mem_succeeded = false; | 20 | static bool request_mem_succeeded = false; |
21 | 21 | ||
22 | static struct pci_dev *default_vga; | ||
23 | |||
24 | static struct fb_var_screeninfo efifb_defined = { | 22 | static struct fb_var_screeninfo efifb_defined = { |
25 | .activate = FB_ACTIVATE_NOW, | 23 | .activate = FB_ACTIVATE_NOW, |
26 | .height = -1, | 24 | .height = -1, |
@@ -84,23 +82,10 @@ static struct fb_ops efifb_ops = { | |||
84 | .fb_imageblit = cfb_imageblit, | 82 | .fb_imageblit = cfb_imageblit, |
85 | }; | 83 | }; |
86 | 84 | ||
87 | struct pci_dev *vga_default_device(void) | ||
88 | { | ||
89 | return default_vga; | ||
90 | } | ||
91 | |||
92 | EXPORT_SYMBOL_GPL(vga_default_device); | ||
93 | |||
94 | void vga_set_default_device(struct pci_dev *pdev) | ||
95 | { | ||
96 | default_vga = pdev; | ||
97 | } | ||
98 | |||
99 | static int efifb_setup(char *options) | 85 | static int efifb_setup(char *options) |
100 | { | 86 | { |
101 | char *this_opt; | 87 | char *this_opt; |
102 | int i; | 88 | int i; |
103 | struct pci_dev *dev = NULL; | ||
104 | 89 | ||
105 | if (options && *options) { | 90 | if (options && *options) { |
106 | while ((this_opt = strsep(&options, ",")) != NULL) { | 91 | while ((this_opt = strsep(&options, ",")) != NULL) { |
@@ -126,30 +111,6 @@ static int efifb_setup(char *options) | |||
126 | } | 111 | } |
127 | } | 112 | } |
128 | 113 | ||
129 | for_each_pci_dev(dev) { | ||
130 | int i; | ||
131 | |||
132 | if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
133 | continue; | ||
134 | |||
135 | for (i=0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
136 | resource_size_t start, end; | ||
137 | |||
138 | if (!(pci_resource_flags(dev, i) & IORESOURCE_MEM)) | ||
139 | continue; | ||
140 | |||
141 | start = pci_resource_start(dev, i); | ||
142 | end = pci_resource_end(dev, i); | ||
143 | |||
144 | if (!start || !end) | ||
145 | continue; | ||
146 | |||
147 | if (screen_info.lfb_base >= start && | ||
148 | (screen_info.lfb_base + screen_info.lfb_size) < end) | ||
149 | default_vga = dev; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | return 0; | 114 | return 0; |
154 | } | 115 | } |
155 | 116 | ||