Merge branch 'pci/vga'

- Add pci_is_vga() helper, which checks for both PCI_CLASS_DISPLAY_VGA and
  PCI_CLASS_NOT_DEFINED_VGA (which catches ancient devices built before
  Class Codes were defined) (Sui Jingfeng)

- Use the new pci_is_vga() to identify devices for the VGA arbiter, the
  sysfs "boot_vga" attribute, and the virtio and qxl drivers (SUi Jingfeng)

* pci/vga:
  drm/qxl: Use pci_is_vga() to identify VGA devices
  drm/virtio: Use pci_is_vga() to identify VGA devices
  PCI/sysfs: Enable 'boot_vga' attribute via pci_is_vga()
  PCI/VGA: Select VGA devices earlier
  PCI/VGA: Use pci_is_vga() to identify VGA devices
  PCI: Add pci_is_vga() helper
This commit is contained in:
Bjorn Helgaas 2023-10-28 13:31:00 -05:00
commit dbf9527ca1
5 changed files with 39 additions and 19 deletions

View file

@ -68,11 +68,6 @@ module_param_named(num_heads, qxl_num_crtc, int, 0400);
static struct drm_driver qxl_driver;
static struct pci_driver qxl_pci_driver;
static bool is_vga(struct pci_dev *pdev)
{
return pdev->class == PCI_CLASS_DISPLAY_VGA << 8;
}
static int
qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@ -100,7 +95,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
goto disable_pci;
if (is_vga(pdev) && pdev->revision < 5) {
if (pci_is_vga(pdev) && pdev->revision < 5) {
ret = vga_get_interruptible(pdev, VGA_RSRC_LEGACY_IO);
if (ret) {
DRM_ERROR("can't get legacy vga ioports\n");
@ -131,7 +126,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
unload:
qxl_device_fini(qdev);
put_vga:
if (is_vga(pdev) && pdev->revision < 5)
if (pci_is_vga(pdev) && pdev->revision < 5)
vga_put(pdev, VGA_RSRC_LEGACY_IO);
disable_pci:
pci_disable_device(pdev);
@ -159,7 +154,7 @@ qxl_pci_remove(struct pci_dev *pdev)
drm_dev_unregister(dev);
drm_atomic_helper_shutdown(dev);
if (is_vga(pdev) && pdev->revision < 5)
if (pci_is_vga(pdev) && pdev->revision < 5)
vga_put(pdev, VGA_RSRC_LEGACY_IO);
}

View file

@ -51,7 +51,7 @@ static int virtio_gpu_pci_quirk(struct drm_device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev->dev);
const char *pname = dev_name(&pdev->dev);
bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA;
bool vga = pci_is_vga(pdev);
int ret;
DRM_INFO("pci: %s detected at %s\n",

View file

@ -1548,11 +1548,10 @@ static umode_t pci_dev_attrs_are_visible(struct kobject *kobj,
struct device *dev = kobj_to_dev(kobj);
struct pci_dev *pdev = to_pci_dev(dev);
if (a == &dev_attr_boot_vga.attr)
if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
return 0;
if (a == &dev_attr_boot_vga.attr && pci_is_vga(pdev))
return a->mode;
return a->mode;
return 0;
}
static struct attribute *pci_dev_hp_attrs[] = {

View file

@ -764,10 +764,6 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
struct pci_dev *bridge;
u16 cmd;
/* Only deal with VGA class devices */
if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
return false;
/* Allocate structure */
vgadev = kzalloc(sizeof(struct vga_device), GFP_KERNEL);
if (vgadev == NULL) {
@ -1503,6 +1499,10 @@ static int pci_notify(struct notifier_block *nb, unsigned long action,
vgaarb_dbg(dev, "%s\n", __func__);
/* Only deal with VGA class devices */
if (!pci_is_vga(pdev))
return 0;
/*
* For now, we're only interested in devices added and removed.
* I didn't test this thing here, so someone needs to double check
@ -1550,8 +1550,10 @@ static int __init vga_arb_device_init(void)
pdev = NULL;
while ((pdev =
pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_ANY_ID, pdev)) != NULL)
vga_arbiter_add_pci_device(pdev);
PCI_ANY_ID, pdev)) != NULL) {
if (pci_is_vga(pdev))
vga_arbiter_add_pci_device(pdev);
}
pr_info("loaded\n");
return rc;

View file

@ -713,6 +713,30 @@ static inline bool pci_is_bridge(struct pci_dev *dev)
dev->hdr_type == PCI_HEADER_TYPE_CARDBUS;
}
/**
* pci_is_vga - check if the PCI device is a VGA device
*
* The PCI Code and ID Assignment spec, r1.15, secs 1.4 and 1.1, define
* VGA Base Class and Sub-Classes:
*
* 03 00 PCI_CLASS_DISPLAY_VGA VGA-compatible or 8514-compatible
* 00 01 PCI_CLASS_NOT_DEFINED_VGA VGA-compatible (before Class Code)
*
* Return true if the PCI device is a VGA device and uses the legacy VGA
* resources ([mem 0xa0000-0xbffff], [io 0x3b0-0x3bb], [io 0x3c0-0x3df] and
* aliases).
*/
static inline bool pci_is_vga(struct pci_dev *pdev)
{
if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
return true;
if ((pdev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA)
return true;
return false;
}
#define for_each_pci_bridge(dev, bus) \
list_for_each_entry(dev, &bus->devices, bus_list) \
if (!pci_is_bridge(dev)) {} else