]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/vga/vgaarb.c
vgaarb: Drop obsolete #ifndef
[karo-tx-linux.git] / drivers / gpu / vga / vgaarb.c
index af02597083586d9f6dc7df613cb825455f3f0e67..77711623b9739526f8605fef680120424e4f9a59 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/poll.h>
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
+#include <linux/screen_info.h>
 
 #include <linux/uaccess.h>
 
@@ -112,10 +113,8 @@ both:
        return 1;
 }
 
-#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
 /* this is only used a cookie - it should not be dereferenced */
 static struct pci_dev *vga_default;
-#endif
 
 static void vga_arb_device_card_gone(struct pci_dev *pdev);
 
@@ -131,7 +130,6 @@ static struct vga_device *vgadev_find(struct pci_dev *pdev)
 }
 
 /* Returns the default VGA device (vgacon's babe) */
-#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
 struct pci_dev *vga_default_device(void)
 {
        return vga_default;
@@ -147,7 +145,6 @@ void vga_set_default_device(struct pci_dev *pdev)
        pci_dev_put(vga_default);
        vga_default = pci_dev_get(pdev);
 }
-#endif
 
 static inline void vga_irq_set_state(struct vga_device *vgadev, bool state)
 {
@@ -237,12 +234,10 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
                if (conflict->locks & lwants)
                        return conflict;
 
-               /* Ok, now check if he owns the resource we want. We don't need
-                * to check "decodes" since it should be impossible to own
-                * own legacy resources you don't decode unless I have a bug
-                * in this code...
+               /* Ok, now check if it owns the resource we want.  We can
+                * lock resources that are not decoded, therefore a device
+                * can own resources it doesn't decode.
                 */
-               WARN_ON(conflict->owns & ~conflict->decodes);
                match = lwants & conflict->owns;
                if (!match)
                        continue;
@@ -254,13 +249,19 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
                flags = 0;
                pci_bits = 0;
 
+               /* If we can't control legacy resources via the bridge, we
+                * also need to disable normal decoding.
+                */
                if (!conflict->bridge_has_one_vga) {
-                       vga_irq_set_state(conflict, false);
-                       flags |= PCI_VGA_STATE_CHANGE_DECODES;
-                       if (match & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
+                       if ((match & conflict->decodes) & VGA_RSRC_LEGACY_MEM)
                                pci_bits |= PCI_COMMAND_MEMORY;
-                       if (match & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
+                       if ((match & conflict->decodes) & VGA_RSRC_LEGACY_IO)
                                pci_bits |= PCI_COMMAND_IO;
+
+                       if (pci_bits) {
+                               vga_irq_set_state(conflict, false);
+                               flags |= PCI_VGA_STATE_CHANGE_DECODES;
+                       }
                }
 
                if (change_bridge)
@@ -268,18 +269,19 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
 
                pci_set_vga_state(conflict->pdev, false, pci_bits, flags);
                conflict->owns &= ~match;
-               /* If he also owned non-legacy, that is no longer the case */
-               if (match & VGA_RSRC_LEGACY_MEM)
+
+               /* If we disabled normal decoding, reflect it in owns */
+               if (pci_bits & PCI_COMMAND_MEMORY)
                        conflict->owns &= ~VGA_RSRC_NORMAL_MEM;
-               if (match & VGA_RSRC_LEGACY_IO)
+               if (pci_bits & PCI_COMMAND_IO)
                        conflict->owns &= ~VGA_RSRC_NORMAL_IO;
        }
 
 enable_them:
        /* ok dude, we got it, everybody conflicting has been disabled, let's
-        * enable us. Make sure we don't mark a bit in "owns" that we don't
-        * also have in "decodes". We can lock resources we don't decode but
-        * not own them.
+        * enable us.  Mark any bits in "owns" regardless of whether we
+        * decoded them.  We can lock resources we don't decode, therefore
+        * we must track them via "owns".
         */
        flags = 0;
        pci_bits = 0;
@@ -291,7 +293,7 @@ enable_them:
                if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
                        pci_bits |= PCI_COMMAND_IO;
        }
-       if (!!(wants & VGA_RSRC_LEGACY_MASK))
+       if (wants & VGA_RSRC_LEGACY_MASK)
                flags |= PCI_VGA_STATE_CHANGE_BRIDGE;
 
        pci_set_vga_state(vgadev->pdev, true, pci_bits, flags);
@@ -299,7 +301,7 @@ enable_them:
        if (!vgadev->bridge_has_one_vga) {
                vga_irq_set_state(vgadev, true);
        }
-       vgadev->owns |= (wants & vgadev->decodes);
+       vgadev->owns |= wants;
 lock_them:
        vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK);
        if (rsrc & VGA_RSRC_LEGACY_IO)
@@ -578,11 +580,12 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
        /* Deal with VGA default device. Use first enabled one
         * by default if arch doesn't have it's own hook
         */
-#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
        if (vga_default == NULL &&
-           ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK))
+           ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) {
+               pr_info("vgaarb: setting as boot device: PCI:%s\n",
+                       pci_name(pdev));
                vga_set_default_device(pdev);
-#endif
+       }
 
        vga_arbiter_check_bridge_sharing(vgadev);
 
@@ -616,10 +619,8 @@ static bool vga_arbiter_del_pci_device(struct pci_dev *pdev)
                goto bail;
        }
 
-#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
        if (vga_default == pdev)
                vga_set_default_device(NULL);
-#endif
 
        if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM))
                vga_decode_count--;
@@ -649,7 +650,6 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev,
        old_decodes = vgadev->decodes;
        decodes_removed = ~new_decodes & old_decodes;
        decodes_unlocked = vgadev->locks & decodes_removed;
-       vgadev->owns &= ~decodes_removed;
        vgadev->decodes = new_decodes;
 
        pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s:owns=%s\n",
@@ -1316,6 +1316,38 @@ static int __init vga_arb_device_init(void)
        pr_info("vgaarb: loaded\n");
 
        list_for_each_entry(vgadev, &vga_list, list) {
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
+               /* Override I/O based detection done by vga_arbiter_add_pci_device()
+                * as it may take the wrong device (e.g. on Apple system under EFI).
+                *
+                * Select the device owning the boot framebuffer if there is one.
+                */
+               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(vgadev->pdev, i) & IORESOURCE_MEM))
+                               continue;
+
+                       start = pci_resource_start(vgadev->pdev, i);
+                       end  = pci_resource_end(vgadev->pdev, i);
+
+                       if (!start || !end)
+                               continue;
+
+                       if (screen_info.lfb_base < start ||
+                           (screen_info.lfb_base + screen_info.lfb_size) >= end)
+                               continue;
+                       if (!vga_default_device())
+                               pr_info("vgaarb: setting as boot device: PCI:%s\n",
+                                       pci_name(vgadev->pdev));
+                       else if (vgadev->pdev != vga_default_device())
+                               pr_info("vgaarb: overriding boot device: PCI:%s\n",
+                                       pci_name(vgadev->pdev));
+                       vga_set_default_device(vgadev->pdev);
+               }
+#endif
                if (vgadev->bridge_has_one_vga)
                        pr_info("vgaarb: bridge control possible %s\n", pci_name(vgadev->pdev));
                else