diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ee72ebe..e347047 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3370,6 +3370,8 @@ extern struct pci_fixup __start_pci_fixups_header[]; extern struct pci_fixup __end_pci_fixups_header[]; extern struct pci_fixup __start_pci_fixups_final[]; extern struct pci_fixup __end_pci_fixups_final[]; +extern struct pci_fixup __start_pci_fixups_assign[]; +extern struct pci_fixup __end_pci_fixups_assign[]; extern struct pci_fixup __start_pci_fixups_enable[]; extern struct pci_fixup __end_pci_fixups_enable[]; extern struct pci_fixup __start_pci_fixups_resume[]; @@ -3405,6 +3407,11 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) end = __end_pci_fixups_final; break; + case pci_fixup_assign: + start = __start_pci_fixups_assign; + end = __end_pci_fixups_assign; + break; + case pci_fixup_enable: start = __start_pci_fixups_enable; end = __end_pci_fixups_enable; @@ -2886,6 +2893,27 @@ static void quirk_hotplug_bridge(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0020, quirk_hotplug_bridge); +/* + * Apple: Avoid programming the memory/io aperture of 00:1c.0 + * + * BIOS does not declare any resource for 00:1c.0, but with + * hotplug flag set, thus OS allocate: + * [mem 0x7fa00000 - 0x7fbfffff] + * [mem 0x7fc00000-0x7fdfffff 64bit pref] + * which is conflict with an unreported device, which + * causes unpredictable result such as accessing io port. + * So clear the hotplug flag to work around it. + */ +static void quirk_apple_mbp_poweroff(struct pci_dev *dev) +{ + if (dmi_match(DMI_BOARD_VENDOR, "Apple Inc.") && + dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,4") || + dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,5")) + dev->is_hotplug_bridge = 0; +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_poweroff); + /* * This is a quirk for the Ricoh MMC controller found as a part of some * multifunction chips. @@ -5099,6 +5106,24 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap); +/* + * On Mac Pro 11, the allocation of pci bridge memory resource + * broke ACPI Sleep Type register region. + */ +static void quirk_mac_disable_mmio_bar(struct pci_dev *dev) +{ + struct resource *b_res; + + dev_info(&dev->dev, "[Quirk] Disable mmio on Mac Pro 11\n"); + if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) + return; + + b_res = &dev->resource[PCI_BRIDGE_RESOURCES]; + b_res[1].flags = 0; + b_res[2].flags = 0; +} +DECLARE_PCI_FIXUP_ASSIGN(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_mac_disable_mmio_bar); + /* * FLR may cause the following to devices to hang: * diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 55641a3..730d6fd 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1256,6 +1256,8 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) additional_mmio_size = pci_hotplug_mmio_size; additional_mmio_pref_size = pci_hotplug_mmio_pref_size; } + + pci_fixup_device(pci_fixup_assign, bus->self); fallthrough; default: pbus_size_io(bus, realloc_head ? 0 : additional_io_size, diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index e373e2e10f6a..8ec44c7450e0 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -346,6 +346,9 @@ __start_pci_fixups_final = .; \ KEEP(*(.pci_fixup_final)) \ __end_pci_fixups_final = .; \ + __start_pci_fixups_assign = .; \ + KEEP(*(.pci_fixup_assign)) \ + __end_pci_fixups_assign = .; \ __start_pci_fixups_enable = .; \ KEEP(*(.pci_fixup_enable)) \ __end_pci_fixups_enable = .; \ diff --git a/include/linux/pci.h b/include/linux/pci.h index b67e4df..14a35bb 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1584,6 +1584,7 @@ enum pci_fixup_pass { pci_fixup_early, /* Before probing BARs */ pci_fixup_header, /* After reading configuration header */ pci_fixup_final, /* Final phase of device fixups */ + pci_fixup_assign, /* Before resource assignment */ pci_fixup_enable, /* pci_enable_device() time */ pci_fixup_resume, /* pci_device_resume() */ pci_fixup_suspend, /* pci_device_suspend() */ @@ -1644,6 +1645,9 @@ enum pci_fixup_pass { #define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook) \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ hook, vendor, device, PCI_ANY_ID, 0, hook) +#define DECLARE_PCI_FIXUP_ASSIGN(vendor, device, hook) \ + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_assign, \ + hook, vendor, device, PCI_ANY_ID, 0, hook) #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ hook, vendor, device, PCI_ANY_ID, 0, hook) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 48958d3..248acdb 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -877,6 +877,7 @@ static void check_section(const char *modname, struct elf_info *elf, #define ALL_PCI_INIT_SECTIONS \ ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \ + ".pci_fixup_assign", \ ".pci_fixup_enable", ".pci_fixup_resume", \ ".pci_fixup_resume_early", ".pci_fixup_suspend"