aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Prémont <bonbons@linux-vserver.org>2014-08-24 17:09:53 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-09-16 15:06:18 -0400
commit86fd887b7fe350819dae5b55e7fef05b511c8656 (patch)
tree73888d1d65e169f1eb18316faf98df372f5557b3
parent52addcf9d6669fa439387610bc65c92fa0980cef (diff)
vgaarb: Don't default exclusively to first video device with mem+io
Commit 20cde694027e ("x86, ia64: Move EFI_FB vga_default_device() initialization to pci_vga_fixup()") moved boot video device detection from efifb to x86 and ia64 pci/fixup.c. For dual-GPU Apple computers above change represents a regression as code in efifb did forcefully override vga_default_device while the merge did not (vgaarb happens prior to PCI fixup). To improve on initial device selection by vgaarb (it cannot know if PCI device not behind bridges see/decode legacy VGA I/O or not), move the screen_info based check from pci_video_fixup() to vgaarb's init function and use it to refine/override decision taken while adding the individual PCI VGA devices. This way PCI fixup has no reason to adjust vga_default_device anymore but can depend on its value for flagging shadowed VBIOS. This has the nice benefit of removing duplicated code but does introduce a #if defined() block in vgaarb. Not all architectures have screen_info and would cause compile to fail without it. Link: https://bugzilla.kernel.org/show_bug.cgi?id=84461 Reported-and-Tested-By: Andreas Noever <andreas.noever@gmail.com> Signed-off-by: Bruno Prémont <bonbons@linux-vserver.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> CC: Matthew Garrett <matthew.garrett@nebula.com> CC: stable@vger.kernel.org # v3.5+
-rw-r--r--arch/ia64/pci/fixup.c24
-rw-r--r--arch/x86/pci/fixup.c24
-rw-r--r--drivers/gpu/vga/vgaarb.c38
3 files changed, 39 insertions, 47 deletions
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
index ec73b2cf912a..fc505d58f078 100644
--- a/arch/ia64/pci/fixup.c
+++ b/arch/ia64/pci/fixup.c
@@ -38,27 +38,6 @@ static void pci_fixup_video(struct pci_dev *pdev)
38 return; 38 return;
39 /* Maybe, this machine supports legacy memory map. */ 39 /* Maybe, this machine supports legacy memory map. */
40 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
62 /* Is VGA routed to us? */ 41 /* Is VGA routed to us? */
63 bus = pdev->bus; 42 bus = pdev->bus;
64 while (bus) { 43 while (bus) {
@@ -83,8 +62,7 @@ static void pci_fixup_video(struct pci_dev *pdev)
83 pci_read_config_word(pdev, PCI_COMMAND, &config); 62 pci_read_config_word(pdev, PCI_COMMAND, &config);
84 if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { 63 if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
85 pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; 64 pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
86 dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); 65 dev_printk(KERN_DEBUG, &pdev->dev, "Video device with shadowed ROM\n");
87 vga_set_default_device(pdev);
88 } 66 }
89 } 67 }
90} 68}
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index c61ea57d1ba1..9a2b7101ae8a 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -326,27 +326,6 @@ 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
350 /* Is VGA routed to us? */ 329 /* Is VGA routed to us? */
351 bus = pdev->bus; 330 bus = pdev->bus;
352 while (bus) { 331 while (bus) {
@@ -371,8 +350,7 @@ static void pci_fixup_video(struct pci_dev *pdev)
371 pci_read_config_word(pdev, PCI_COMMAND, &config); 350 pci_read_config_word(pdev, PCI_COMMAND, &config);
372 if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { 351 if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
373 pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; 352 pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
374 dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); 353 dev_printk(KERN_DEBUG, &pdev->dev, "Video device with shadowed ROM\n");
375 vga_set_default_device(pdev);
376 } 354 }
377 } 355 }
378} 356}
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index d2077f040f3e..24ac52e6cd41 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -41,6 +41,7 @@
41#include <linux/poll.h> 41#include <linux/poll.h>
42#include <linux/miscdevice.h> 42#include <linux/miscdevice.h>
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/screen_info.h>
44 45
45#include <linux/uaccess.h> 46#include <linux/uaccess.h>
46 47
@@ -585,8 +586,11 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
585 */ 586 */
586#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE 587#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
587 if (vga_default == NULL && 588 if (vga_default == NULL &&
588 ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) 589 ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) {
590 pr_info("vgaarb: setting as boot device: PCI:%s\n",
591 pci_name(pdev));
589 vga_set_default_device(pdev); 592 vga_set_default_device(pdev);
593 }
590#endif 594#endif
591 595
592 vga_arbiter_check_bridge_sharing(vgadev); 596 vga_arbiter_check_bridge_sharing(vgadev);
@@ -1320,6 +1324,38 @@ static int __init vga_arb_device_init(void)
1320 pr_info("vgaarb: loaded\n"); 1324 pr_info("vgaarb: loaded\n");
1321 1325
1322 list_for_each_entry(vgadev, &vga_list, list) { 1326 list_for_each_entry(vgadev, &vga_list, list) {
1327#if defined(CONFIG_X86) || defined(CONFIG_IA64)
1328 /* Override I/O based detection done by vga_arbiter_add_pci_device()
1329 * as it may take the wrong device (e.g. on Apple system under EFI).
1330 *
1331 * Select the device owning the boot framebuffer if there is one.
1332 */
1333 resource_size_t start, end;
1334 int i;
1335
1336 /* Does firmware framebuffer belong to us? */
1337 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
1338 if (!(pci_resource_flags(vgadev->pdev, i) & IORESOURCE_MEM))
1339 continue;
1340
1341 start = pci_resource_start(vgadev->pdev, i);
1342 end = pci_resource_end(vgadev->pdev, i);
1343
1344 if (!start || !end)
1345 continue;
1346
1347 if (screen_info.lfb_base < start ||
1348 (screen_info.lfb_base + screen_info.lfb_size) >= end)
1349 continue;
1350 if (!vga_default_device())
1351 pr_info("vgaarb: setting as boot device: PCI:%s\n",
1352 pci_name(vgadev->pdev));
1353 else if (vgadev->pdev != vga_default_device())
1354 pr_info("vgaarb: overriding boot device: PCI:%s\n",
1355 pci_name(vgadev->pdev));
1356 vga_set_default_device(vgadev->pdev);
1357 }
1358#endif
1323 if (vgadev->bridge_has_one_vga) 1359 if (vgadev->bridge_has_one_vga)
1324 pr_info("vgaarb: bridge control possible %s\n", pci_name(vgadev->pdev)); 1360 pr_info("vgaarb: bridge control possible %s\n", pci_name(vgadev->pdev));
1325 else 1361 else