diff options
-rw-r--r-- | arch/powerpc/kernel/pci_of_scan.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/pci.c | 2 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 7 | ||||
-rw-r--r-- | drivers/pci/pcie/aspm.c | 16 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 25 |
5 files changed, 43 insertions, 9 deletions
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 2a67e9baa59f..d2d407d65344 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -165,7 +165,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, pr_debug(" class: 0x%x\n", dev->class); pr_debug(" revision: 0x%x\n", dev->revision); - dev->current_state = 4; /* unknown power state */ + dev->current_state = PCI_UNKNOWN; /* unknown power state */ dev->error_state = pci_channel_io_normal; dev->dma_mask = 0xffffffff; diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index baf4366e2d6a..972892a0aa11 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -327,7 +327,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) pci_set_master(dev); - dev->current_state = 4; /* unknown power state */ + dev->current_state = PCI_UNKNOWN; /* unknown power state */ dev->error_state = pci_channel_io_normal; dev->dma_mask = 0xffffffff; diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 1dd6f6c85874..f6c0998f248a 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -100,13 +100,12 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) { struct resource *res = data; struct acpi_resource_address64 address; + acpi_status status; - if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && - resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 && - resource->type != ACPI_RESOURCE_TYPE_ADDRESS64) + status = acpi_resource_to_address64(resource, &address); + if (ACPI_FAILURE(status)) return AE_OK; - acpi_resource_to_address64(resource, &address); if ((address.address_length > 0) && (address.resource_type == ACPI_BUS_NUMBER_RANGE)) { res->start = address.minimum; diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index d320df6375a2..faa83b632a84 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -724,9 +724,6 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, struct pci_dev *parent = pdev->bus->self; struct pcie_link_state *link; - if (aspm_disabled && !force) - return; - if (!pci_is_pcie(pdev)) return; @@ -736,6 +733,19 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, if (!parent || !parent->link_state) return; + /* + * A driver requested that ASPM be disabled on this device, but + * if we don't have permission to manage ASPM (e.g., on ACPI + * systems we have to observe the FADT ACPI_FADT_NO_ASPM bit and + * the _OSC method), we can't honor that request. Windows has + * a similar mechanism using "PciASPMOptOut", which is also + * ignored in this situation. + */ + if (aspm_disabled && !force) { + dev_warn(&pdev->dev, "can't disable ASPM; OS doesn't have ASPM control\n"); + return; + } + if (sem) down_read(&pci_bus_sem); mutex_lock(&aspm_lock); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 7d68aeebf56b..7f492574dcf4 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2865,6 +2865,31 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); +/* + * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. To + * work around this, query the size it should be configured to by the device and + * modify the resource end to correspond to this new size. + */ +static void quirk_intel_ntb(struct pci_dev *dev) +{ + int rc; + u8 val; + + rc = pci_read_config_byte(dev, 0x00D0, &val); + if (rc) + return; + + dev->resource[2].end = dev->resource[2].start + ((u64) 1 << val) - 1; + + rc = pci_read_config_byte(dev, 0x00D1, &val); + if (rc) + return; + + dev->resource[4].end = dev->resource[4].start + ((u64) 1 << val) - 1; +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb); + static ktime_t fixup_debug_start(struct pci_dev *dev, void (*fn)(struct pci_dev *dev)) { |