Commit 7639afad authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pci-v5.15-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/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
parents ddf21bd8 e042a453
...@@ -14342,7 +14342,8 @@ F: Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml ...@@ -14342,7 +14342,8 @@ F: Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml
F: drivers/pci/controller/pci-ixp4xx.c F: drivers/pci/controller/pci-ixp4xx.c
PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD) 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 L: linux-pci@vger.kernel.org
S: Supported S: Supported
F: drivers/pci/controller/vmd.c F: drivers/pci/controller/vmd.c
......
...@@ -937,7 +937,7 @@ static struct acpi_device *acpi_pci_find_companion(struct device *dev); ...@@ -937,7 +937,7 @@ static struct acpi_device *acpi_pci_find_companion(struct device *dev);
void pci_set_acpi_fwnode(struct pci_dev *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_COMPANION_SET(&dev->dev,
acpi_pci_find_companion(&dev->dev)); acpi_pci_find_companion(&dev->dev));
} }
......
...@@ -5435,7 +5435,7 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, ...@@ -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); 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. * controller to VGA.
*/ */
static void quirk_gpu_usb(struct pci_dev *usb) static void quirk_gpu_usb(struct pci_dev *usb)
...@@ -5444,9 +5444,11 @@ static void quirk_gpu_usb(struct pci_dev *usb) ...@@ -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, DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_CLASS_SERIAL_USB, 8, quirk_gpu_usb); 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 * 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 * so using UNKNOWN class for now and it will be updated when UCSI
* over PCI gets a class code. * over PCI gets a class code.
...@@ -5459,6 +5461,9 @@ static void quirk_gpu_usb_typec_ucsi(struct pci_dev *ucsi) ...@@ -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, DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_CLASS_SERIAL_UNKNOWN, 8, PCI_CLASS_SERIAL_UNKNOWN, 8,
quirk_gpu_usb_typec_ucsi); 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 * Enable the NVIDIA GPU integrated HDA controller if the BIOS left it
......
...@@ -99,6 +99,24 @@ static size_t pci_vpd_size(struct pci_dev *dev) ...@@ -99,6 +99,24 @@ static size_t pci_vpd_size(struct pci_dev *dev)
return off ?: PCI_VPD_SZ_INVALID; 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. * Wait for last operation to complete.
* This code has to spin since there is no other notification from the PCI * This code has to spin since there is no other notification from the PCI
...@@ -145,7 +163,7 @@ static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count, ...@@ -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; loff_t end = pos + count;
u8 *buf = arg; u8 *buf = arg;
if (!vpd->cap) if (!pci_vpd_available(dev))
return -ENODEV; return -ENODEV;
if (pos < 0) if (pos < 0)
...@@ -206,7 +224,7 @@ static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count, ...@@ -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; loff_t end = pos + count;
int ret = 0; int ret = 0;
if (!vpd->cap) if (!pci_vpd_available(dev))
return -ENODEV; return -ENODEV;
if (pos < 0 || (pos & 3) || (count & 3)) if (pos < 0 || (pos & 3) || (count & 3))
...@@ -242,14 +260,11 @@ static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count, ...@@ -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) 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); dev->vpd.cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
mutex_init(&dev->vpd.lock); 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, static ssize_t vpd_read(struct file *filp, struct kobject *kobj,
...@@ -294,13 +309,14 @@ const struct attribute_group pci_dev_vpd_attr_group = { ...@@ -294,13 +309,14 @@ const struct attribute_group pci_dev_vpd_attr_group = {
void *pci_vpd_alloc(struct pci_dev *dev, unsigned int *size) void *pci_vpd_alloc(struct pci_dev *dev, unsigned int *size)
{ {
unsigned int len = dev->vpd.len; unsigned int len;
void *buf; void *buf;
int cnt; int cnt;
if (!dev->vpd.cap) if (!pci_vpd_available(dev))
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
len = dev->vpd.len;
buf = kmalloc(len, GFP_KERNEL); buf = kmalloc(len, GFP_KERNEL);
if (!buf) if (!buf)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment