Split the small bit of code that does default VGA handling out from
the arbiter. Add a Kconfig option to allow the kernel to be built
with just the default handling, or the arbiter and default handling.

While doing this, rename the functions from vga_(set_)default_device
to pci_(set_)default_display. This makes it clear that these functions
do not rely on legacy VGA access: they're about the default PCI display.
(The device still needs to be a member of PCI_CLASS_DISPLAY_VGA.)

This should not introduce any functional change.

Signed-off-by: Daniel Axtens <d...@axtens.net>

---

I know this adds another config option and that's a bit sad, but
we can't include it unconditionally as it depends on PCI.
Suggestions welcome.

v3: split from the part where we add functionality
    rename functions
---
 arch/ia64/pci/fixup.c             |  6 +--
 arch/powerpc/kernel/pci-common.c  |  6 +--
 arch/x86/pci/fixup.c              |  6 +--
 arch/x86/video/fbdev.c            |  4 +-
 drivers/gpu/vga/Kconfig           | 12 ++++++
 drivers/gpu/vga/Makefile          |  1 +
 drivers/gpu/vga/default_display.c | 86 +++++++++++++++++++++++++++++++++++++++
 drivers/gpu/vga/vga_switcheroo.c  |  8 ++--
 drivers/gpu/vga/vgaarb.c          | 61 ++++++---------------------
 drivers/pci/pci-sysfs.c           |  4 +-
 include/linux/default_display.h   | 44 ++++++++++++++++++++
 include/linux/vgaarb.h            | 15 -------
 12 files changed, 173 insertions(+), 80 deletions(-)
 create mode 100644 drivers/gpu/vga/default_display.c
 create mode 100644 include/linux/default_display.h

diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
index 41caa99add51..a5f35e767c84 100644
--- a/arch/ia64/pci/fixup.c
+++ b/arch/ia64/pci/fixup.c
@@ -5,7 +5,7 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/vgaarb.h>
+#include <linux/default_display.h>
 #include <linux/screen_info.h>
 
 #include <asm/machvec.h>
@@ -22,7 +22,7 @@
  * card with this copy. On laptops this copy has to be used since
  * the main ROM may be compressed or combined with another image.
  * See pci_map_rom() for use of this flag. Before marking the device
- * with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set
+ * with IORESOURCE_ROM_SHADOW check if a pci_default_display is already set
  * by either arch code or vga-arbitration; if so only apply the fixup to this
  * already-determined primary video card.
  */
@@ -59,7 +59,7 @@ static void pci_fixup_video(struct pci_dev *pdev)
                }
                bus = bus->parent;
        }
-       if (!vga_default_device() || pdev == vga_default_device()) {
+       if (!pci_default_display() || pdev == pci_default_display()) {
                pci_read_config_word(pdev, PCI_COMMAND, &config);
                if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
                        res = &pdev->resource[PCI_ROM_RESOURCE];
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 341a7469cab8..9f82f13ac531 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -31,7 +31,7 @@
 #include <linux/irq.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
-#include <linux/vgaarb.h>
+#include <linux/default_display.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -1747,8 +1747,8 @@ static void fixup_vga(struct pci_dev *pdev)
        u16 cmd;
 
        pci_read_config_word(pdev, PCI_COMMAND, &cmd);
-       if ((cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) || 
!vga_default_device())
-               vga_set_default_device(pdev);
+       if ((cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) || 
!pci_default_display())
+               pci_set_default_display(pdev);
 
 }
 DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index 11e407489db0..7e32a2a80383 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -5,7 +5,7 @@
 #include <linux/delay.h>
 #include <linux/dmi.h>
 #include <linux/pci.h>
-#include <linux/vgaarb.h>
+#include <linux/default_display.h>
 #include <asm/hpet.h>
 #include <asm/pci_x86.h>
 
@@ -302,7 +302,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,        
PCI_DEVICE_ID_INTEL_MCH_PC1,    pcie_r
  * card with this copy. On laptops this copy has to be used since
  * the main ROM may be compressed or combined with another image.
  * See pci_map_rom() for use of this flag. Before marking the device
- * with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set
+ * with IORESOURCE_ROM_SHADOW check if a pci_default_display is already set
  * by either arch code or vga-arbitration; if so only apply the fixup to this
  * already-determined primary video card.
  */
@@ -334,7 +334,7 @@ static void pci_fixup_video(struct pci_dev *pdev)
                }
                bus = bus->parent;
        }
-       if (!vga_default_device() || pdev == vga_default_device()) {
+       if (!pci_default_display() || pdev == pci_default_display()) {
                pci_read_config_word(pdev, PCI_COMMAND, &config);
                if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
                        res = &pdev->resource[PCI_ROM_RESOURCE];
diff --git a/arch/x86/video/fbdev.c b/arch/x86/video/fbdev.c
index 9fd24846d094..114bd9ac95d0 100644
--- a/arch/x86/video/fbdev.c
+++ b/arch/x86/video/fbdev.c
@@ -9,12 +9,12 @@
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/module.h>
-#include <linux/vgaarb.h>
+#include <linux/default_display.h>
 
 int fb_is_primary_device(struct fb_info *info)
 {
        struct device *device = info->device;
-       struct pci_dev *default_device = vga_default_device();
+       struct pci_dev *default_device = pci_default_display();
        struct pci_dev *pci_dev;
        struct resource *res;
 
diff --git a/drivers/gpu/vga/Kconfig b/drivers/gpu/vga/Kconfig
index 29437eabe095..8e6edfb6d160 100644
--- a/drivers/gpu/vga/Kconfig
+++ b/drivers/gpu/vga/Kconfig
@@ -1,3 +1,14 @@
+config DEFAULT_DISPLAY
+       bool "Default Display Device Support" if EXPERT
+       default y
+       depends on PCI
+       help
+         Some programs find it helpful to know what PCI display device is the
+         default. On platforms like x86 this means the device used by the BIOS
+         to show early boot messages. On other platforms this may be an 
arbitrary
+         PCI graphics card. Select this to have a default device recorded 
within
+         the kernel and exposed to userspace through sysfs.
+
 config VGA_ARB
        bool "VGA Arbitration" if EXPERT
        default y
@@ -22,6 +33,7 @@ config VGA_SWITCHEROO
        depends on X86
        depends on ACPI
        select VGA_ARB
+       select DEFAULT_DISPLAY
        help
          Many laptops released in 2008/9/10 have two GPUs with a multiplexer
          to switch between them. This adds support for dynamic switching when
diff --git a/drivers/gpu/vga/Makefile b/drivers/gpu/vga/Makefile
index 14ca30b75d0a..3abf32c26de5 100644
--- a/drivers/gpu/vga/Makefile
+++ b/drivers/gpu/vga/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_VGA_ARB)  += vgaarb.o
+obj-$(CONFIG_DEFAULT_DISPLAY) += default_display.o
 obj-$(CONFIG_VGA_SWITCHEROO) += vga_switcheroo.o
diff --git a/drivers/gpu/vga/default_display.c 
b/drivers/gpu/vga/default_display.c
new file mode 100644
index 000000000000..99e4723360da
--- /dev/null
+++ b/drivers/gpu/vga/default_display.c
@@ -0,0 +1,86 @@
+/*
+ * default_display.c: What is the default/boot PCI VGA device?
+ *
+ * (C) Copyright 2005 Benjamin Herrenschmidt <b...@kernel.crashing.org>
+ * (C) Copyright 2007 Paulo R. Zanoni <przan...@gmail.com>
+ * (C) Copyright 2007, 2009 Tiago Vignatti <vigna...@freedesktop.org>
+ * (C) Copyright 2017 Canonical Ltd. (Author: Daniel Axtens <d...@axtens.net>)
+ *
+ * (License from vgaarb.c)
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * DOC: overview
+ *
+ * What device should a graphics system draw to?
+ *
+ * It is helpful to have a concept of a default or boot device (for
+ * example, for autoconfiguration where there is no device speficied
+ * by the user). That should be:
+ *
+ *  1) If the platform has a concept of a boot device for early boot
+ *     messages (think BIOS displays on x86), that device.
+ *
+ *  2) Anything specified by an arch hook,
+ *     e.g. arch/powerpc/kernel/pci-common.c::fixup_vga()
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <linux/default_display.h>
+
+static struct pci_dev *vga_default;
+
+/**
+ * pci_default_display - return the default display device
+ *
+ * This represents the default or boot device.
+ *
+ * The default implementation is rather dumb and will probably only
+ * work properly on single vga card setups and/or x86 platforms.
+ */
+struct pci_dev *pci_default_display(void)
+{
+       return vga_default;
+}
+EXPORT_SYMBOL_GPL(pci_default_display);
+
+/**
+ * pci_set_default_display - set the default display device
+ * @pdev: pci device to set as default
+ *
+ * Idempotent - safe to call with the same device repeatedly.
+ *
+ * Drops a reference to the old default, if applicable. Takes a
+ * reference to the new device.
+ */
+void pci_set_default_display(struct pci_dev *pdev)
+{
+       if (vga_default == pdev)
+               return;
+
+       pci_dev_put(vga_default);
+       vga_default = pci_dev_get(pdev);
+}
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 3cd153c6d271..beefefc288f9 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -41,7 +41,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
-#include <linux/vgaarb.h>
+#include <linux/default_display.h>
 #include <linux/vga_switcheroo.h>
 
 /**
@@ -320,7 +320,7 @@ int vga_switcheroo_register_client(struct pci_dev *pdev,
                                   bool driver_power_control)
 {
        return register_client(pdev, ops, VGA_SWITCHEROO_UNKNOWN_ID,
-                              pdev == vga_default_device(),
+                              pdev == pci_default_display(),
                               driver_power_control);
 }
 EXPORT_SYMBOL(vga_switcheroo_register_client);
@@ -397,7 +397,7 @@ bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev)
                 * apple-gmux is needed on pre-retina MacBook Pro
                 * to probe the panel if pdev is the inactive GPU.
                 */
-               if (apple_gmux_present() && pdev != vga_default_device() &&
+               if (apple_gmux_present() && pdev != pci_default_display() &&
                    !vgasr_priv.handler_flags)
                        return true;
        }
@@ -659,7 +659,7 @@ static int vga_switchto_stage1(struct vga_switcheroo_client 
*new_client)
        if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
                vga_switchon(new_client);
 
-       vga_set_default_device(new_client->pdev);
+       pci_set_default_display(new_client->pdev);
        return 0;
 }
 
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index 76875f6299b8..7654bb678587 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -51,6 +51,7 @@
 
 #include <linux/uaccess.h>
 
+#include <linux/default_display.h>
 #include <linux/vgaarb.h>
 
 static void vga_arbiter_notify_clients(void);
@@ -119,9 +120,6 @@ static int vga_str_to_iostate(char *buf, int str_size, int 
*io_state)
        return 1;
 }
 
-/* this is only used a cookie - it should not be dereferenced */
-static struct pci_dev *vga_default;
-
 static void vga_arb_device_card_gone(struct pci_dev *pdev);
 
 /* Find somebody in our list */
@@ -135,39 +133,6 @@ static struct vga_device *vgadev_find(struct pci_dev *pdev)
        return NULL;
 }
 
-/**
- * vga_default_device - return the default VGA device, for vgacon
- *
- * This can be defined by the platform. The default implementation
- * is rather dumb and will probably only work properly on single
- * vga card setups and/or x86 platforms.
- *
- * If your VGA default device is not PCI, you'll have to return
- * NULL here. In this case, I assume it will not conflict with
- * any PCI card. If this is not true, I'll have to define two archs
- * hooks for enabling/disabling the VGA default device if that is
- * possible. This may be a problem with real _ISA_ VGA cards, in
- * addition to a PCI one. I don't know at this point how to deal
- * with that card. Can theirs IOs be disabled at all ? If not, then
- * I suppose it's a matter of having the proper arch hook telling
- * us about it, so we basically never allow anybody to succeed a
- * vga_get()...
- */
-struct pci_dev *vga_default_device(void)
-{
-       return vga_default;
-}
-EXPORT_SYMBOL_GPL(vga_default_device);
-
-void vga_set_default_device(struct pci_dev *pdev)
-{
-       if (vga_default == pdev)
-               return;
-
-       pci_dev_put(vga_default);
-       vga_default = pci_dev_get(pdev);
-}
-
 static inline void vga_irq_set_state(struct vga_device *vgadev, bool state)
 {
        if (vgadev->irq_set_state)
@@ -423,7 +388,7 @@ int vga_get(struct pci_dev *pdev, unsigned int rsrc, int 
interruptible)
        vga_check_first_use();
        /* The one who calls us should check for this, but lets be sure... */
        if (pdev == NULL)
-               pdev = vga_default_device();
+               pdev = pci_default_display();
        if (pdev == NULL)
                return 0;
 
@@ -490,7 +455,7 @@ int vga_tryget(struct pci_dev *pdev, unsigned int rsrc)
 
        /* The one who calls us should check for this, but lets be sure... */
        if (pdev == NULL)
-               pdev = vga_default_device();
+               pdev = pci_default_display();
        if (pdev == NULL)
                return 0;
        spin_lock_irqsave(&vga_lock, flags);
@@ -524,7 +489,7 @@ void vga_put(struct pci_dev *pdev, unsigned int rsrc)
 
        /* The one who calls us should check for this, but lets be sure... */
        if (pdev == NULL)
-               pdev = vga_default_device();
+               pdev = pci_default_display();
        if (pdev == NULL)
                return;
        spin_lock_irqsave(&vga_lock, flags);
@@ -667,10 +632,10 @@ 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
         */
-       if (vga_default == NULL &&
+       if (pci_default_display() == NULL &&
            ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) {
                vgaarb_info(&pdev->dev, "setting as boot VGA device\n");
-               vga_set_default_device(pdev);
+               pci_set_default_display(pdev);
        }
 
        vga_arbiter_check_bridge_sharing(vgadev);
@@ -704,8 +669,8 @@ static bool vga_arbiter_del_pci_device(struct pci_dev *pdev)
                goto bail;
        }
 
-       if (vga_default == pdev)
-               vga_set_default_device(NULL);
+       if (pci_default_display() == pdev)
+               pci_set_default_display(NULL);
 
        if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM))
                vga_decode_count--;
@@ -1182,7 +1147,7 @@ static ssize_t vga_arb_write(struct file *file, const 
char __user *buf,
                pr_debug("client 0x%p called 'target'\n", priv);
                /* if target is default */
                if (!strncmp(curr_pos, "default", 7))
-                       pdev = pci_dev_get(vga_default_device());
+                       pdev = pci_dev_get(pci_default_display());
                else {
                        if (!vga_pci_str_to_vars(curr_pos, remaining,
                                                 &domain, &bus, &devfn)) {
@@ -1292,7 +1257,7 @@ static int vga_arb_open(struct inode *inode, struct file 
*file)
        spin_unlock_irqrestore(&vga_user_lock, flags);
 
        /* Set the client' lists of locks */
-       priv->target = vga_default_device(); /* Maybe this is still null! */
+       priv->target = pci_default_display(); /* Maybe this is still null! */
        priv->cards[0].pdev = priv->target;
        priv->cards[0].io_cnt = 0;
        priv->cards[0].mem_cnt = 0;
@@ -1455,11 +1420,11 @@ static int __init vga_arb_device_init(void)
                        if (screen_info.lfb_base < start || limit >= end)
                                continue;
 
-                       if (!vga_default_device())
+                       if (!pci_default_display())
                                vgaarb_info(dev, "setting as boot device\n");
-                       else if (vgadev->pdev != vga_default_device())
+                       else if (vgadev->pdev != pci_default_display())
                                vgaarb_info(dev, "overriding boot device\n");
-                       vga_set_default_device(vgadev->pdev);
+                       pci_set_default_display(vgadev->pdev);
                }
 #endif
                if (vgadev->bridge_has_one_vga)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 1eecfa301f7f..31a37178fa8a 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -27,7 +27,7 @@
 #include <linux/security.h>
 #include <linux/pci-aspm.h>
 #include <linux/slab.h>
-#include <linux/vgaarb.h>
+#include <linux/default_display.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include "pci.h"
@@ -785,7 +785,7 @@ static ssize_t boot_vga_show(struct device *dev, struct 
device_attribute *attr,
                             char *buf)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
-       struct pci_dev *vga_dev = vga_default_device();
+       struct pci_dev *vga_dev = pci_default_display();
 
        if (vga_dev)
                return sprintf(buf, "%u\n", (pdev == vga_dev));
diff --git a/include/linux/default_display.h b/include/linux/default_display.h
new file mode 100644
index 000000000000..5ccebde96b6a
--- /dev/null
+++ b/include/linux/default_display.h
@@ -0,0 +1,44 @@
+/*
+ * default_display.h: What is the default/boot PCI VGA device?
+ *
+ * (C) Copyright 2005 Benjamin Herrenschmidt <b...@kernel.crashing.org>
+ * (C) Copyright 2007 Paulo R. Zanoni <przan...@gmail.com>
+ * (C) Copyright 2007, 2009 Tiago Vignatti <vigna...@freedesktop.org>
+ * (C) Copyright 2017 Canonical Ltd. (Author: Daniel Axtens <d...@axtens.net>)
+ *
+ * (License from vgaarb.h)
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef LINUX_DEFAULT_DISPLAY_H
+#define LINUX_DEFAULT_DISPLAY_H
+
+struct pci_dev;
+
+#ifdef CONFIG_DEFAULT_DISPLAY
+extern struct pci_dev *pci_default_display(void);
+extern void pci_set_default_display(struct pci_dev *pdev);
+#else
+static inline struct pci_dev *pci_default_display(void) { return NULL; };
+static inline void pci_set_default_display(struct pci_dev *pdev) { };
+#endif
+
+#endif
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
index ee162e3e879b..5434ad4af32d 100644
--- a/include/linux/vgaarb.h
+++ b/include/linux/vgaarb.h
@@ -42,12 +42,6 @@
 #define VGA_RSRC_NORMAL_IO     0x04
 #define VGA_RSRC_NORMAL_MEM    0x08
 
-/* Passing that instead of a pci_dev to use the system "default"
- * device, that is the one used by vgacon. Archs will probably
- * have to provide their own vga_default_device();
- */
-#define VGA_DEFAULT_DEVICE     (NULL)
-
 struct pci_dev;
 
 /* For use by clients */
@@ -121,15 +115,6 @@ extern void vga_put(struct pci_dev *pdev, unsigned int 
rsrc);
 #define vga_put(pdev, rsrc)
 #endif
 
-
-#ifdef CONFIG_VGA_ARB
-extern struct pci_dev *vga_default_device(void);
-extern void vga_set_default_device(struct pci_dev *pdev);
-#else
-static inline struct pci_dev *vga_default_device(void) { return NULL; };
-static inline void vga_set_default_device(struct pci_dev *pdev) { };
-#endif
-
 /*
  * Architectures should define this if they have several
  * independent PCI domains that can afford concurrent VGA
-- 
2.11.0

Reply via email to