Skip to content

Commit

Permalink
Merge tag 'pci-v5.15-fixes-1' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/helgaas/pci

Pull PCI fixes from Bjorn Helgaas:

 - Defer VPD sizing until we actually need the contents; fixes a
   boot-time slowdown reported by Dave Jones (Bjorn Helgaas)

 - Stop clobbering OF fwnodes when we look for an ACPI fwnode; fixes a
   virtio-iommu boot regression (Jean-Philippe Brucker)

 - Add AMD GPU multi-function power dependencies; fixes runtime power
   management, including GPU resume and temp and fan sensor issues (Evan
   Quan)

 - Update VMD maintainer to Nirmal Patel (Jon Derrick)

* tag 'pci-v5.15-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
  MAINTAINERS: Add Nirmal Patel as VMD maintainer
  PCI: Add AMD GPU multi-function power dependencies
  PCI/ACPI: Don't reset a fwnode set by OF
  PCI/VPD: Defer VPD sizing until first access
  • Loading branch information
Linus Torvalds committed Sep 17, 2021
2 parents ddf21bd + e042a45 commit 7639afa
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 14 deletions.
3 changes: 2 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -14342,7 +14342,8 @@ F: Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml
F: drivers/pci/controller/pci-ixp4xx.c

PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
M: Jonathan Derrick <jonathan.derrick@intel.com>
M: Nirmal Patel <nirmal.patel@linux.intel.com>
R: Jonathan Derrick <jonathan.derrick@linux.dev>
L: linux-pci@vger.kernel.org
S: Supported
F: drivers/pci/controller/vmd.c
Expand Down
2 changes: 1 addition & 1 deletion drivers/pci/pci-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ static struct acpi_device *acpi_pci_find_companion(struct device *dev);

void pci_set_acpi_fwnode(struct pci_dev *dev)
{
if (!ACPI_COMPANION(&dev->dev) && !pci_dev_is_added(dev))
if (!dev_fwnode(&dev->dev) && !pci_dev_is_added(dev))
ACPI_COMPANION_SET(&dev->dev,
acpi_pci_find_companion(&dev->dev));
}
Expand Down
9 changes: 7 additions & 2 deletions drivers/pci/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -5435,7 +5435,7 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);

/*
* Create device link for NVIDIA GPU with integrated USB xHCI Host
* Create device link for GPUs with integrated USB xHCI Host
* controller to VGA.
*/
static void quirk_gpu_usb(struct pci_dev *usb)
Expand All @@ -5444,9 +5444,11 @@ static void quirk_gpu_usb(struct pci_dev *usb)
}
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_CLASS_SERIAL_USB, 8, quirk_gpu_usb);
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID,
PCI_CLASS_SERIAL_USB, 8, quirk_gpu_usb);

/*
* Create device link for NVIDIA GPU with integrated Type-C UCSI controller
* Create device link for GPUs with integrated Type-C UCSI controller
* to VGA. Currently there is no class code defined for UCSI device over PCI
* so using UNKNOWN class for now and it will be updated when UCSI
* over PCI gets a class code.
Expand All @@ -5459,6 +5461,9 @@ static void quirk_gpu_usb_typec_ucsi(struct pci_dev *ucsi)
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_CLASS_SERIAL_UNKNOWN, 8,
quirk_gpu_usb_typec_ucsi);
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID,
PCI_CLASS_SERIAL_UNKNOWN, 8,
quirk_gpu_usb_typec_ucsi);

/*
* Enable the NVIDIA GPU integrated HDA controller if the BIOS left it
Expand Down
36 changes: 26 additions & 10 deletions drivers/pci/vpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ static size_t pci_vpd_size(struct pci_dev *dev)
return off ?: PCI_VPD_SZ_INVALID;
}

static bool pci_vpd_available(struct pci_dev *dev)
{
struct pci_vpd *vpd = &dev->vpd;

if (!vpd->cap)
return false;

if (vpd->len == 0) {
vpd->len = pci_vpd_size(dev);
if (vpd->len == PCI_VPD_SZ_INVALID) {
vpd->cap = 0;
return false;
}
}

return true;
}

/*
* Wait for last operation to complete.
* This code has to spin since there is no other notification from the PCI
Expand Down Expand Up @@ -145,7 +163,7 @@ static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count,
loff_t end = pos + count;
u8 *buf = arg;

if (!vpd->cap)
if (!pci_vpd_available(dev))
return -ENODEV;

if (pos < 0)
Expand Down Expand Up @@ -206,7 +224,7 @@ static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count,
loff_t end = pos + count;
int ret = 0;

if (!vpd->cap)
if (!pci_vpd_available(dev))
return -ENODEV;

if (pos < 0 || (pos & 3) || (count & 3))
Expand Down Expand Up @@ -242,14 +260,11 @@ static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count,

void pci_vpd_init(struct pci_dev *dev)
{
if (dev->vpd.len == PCI_VPD_SZ_INVALID)
return;

dev->vpd.cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
mutex_init(&dev->vpd.lock);

if (!dev->vpd.len)
dev->vpd.len = pci_vpd_size(dev);

if (dev->vpd.len == PCI_VPD_SZ_INVALID)
dev->vpd.cap = 0;
}

static ssize_t vpd_read(struct file *filp, struct kobject *kobj,
Expand Down Expand Up @@ -294,13 +309,14 @@ const struct attribute_group pci_dev_vpd_attr_group = {

void *pci_vpd_alloc(struct pci_dev *dev, unsigned int *size)
{
unsigned int len = dev->vpd.len;
unsigned int len;
void *buf;
int cnt;

if (!dev->vpd.cap)
if (!pci_vpd_available(dev))
return ERR_PTR(-ENODEV);

len = dev->vpd.len;
buf = kmalloc(len, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
Expand Down

0 comments on commit 7639afa

Please sign in to comment.