1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
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;
@@ -4551,6 +4551,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);
+
+/*
* VMD-enabled root ports will change the source ID for all messages
* to the VMD device. Rather than doing device matching with the source
* ID, the AER driver should traverse the child device tree, reading
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_io_size = pci_hotplug_io_size;
additional_mem_size = pci_hotplug_mem_size;
}
+
+ pci_fixup_device(pci_fixup_assign, bus->self);
/* Fall through */
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 6a67ab9..3ba05f0 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -299,6 +299,9 @@
VMLINUX_SYMBOL(__start_pci_fixups_final) = .; \
KEEP(*(.pci_fixup_final)) \
VMLINUX_SYMBOL(__end_pci_fixups_final) = .; \
+ VMLINUX_SYMBOL(__start_pci_fixups_assign) = .; \
+ KEEP(*(.pci_fixup_assign)) \
+ VMLINUX_SYMBOL(__end_pci_fixups_assign) = .; \
VMLINUX_SYMBOL(__start_pci_fixups_enable) = .; \
KEEP(*(.pci_fixup_enable)) \
VMLINUX_SYMBOL(__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"
|