aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/kernel/pci.c')
-rw-r--r--arch/arm64/kernel/pci.c67
1 files changed, 43 insertions, 24 deletions
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index acf38722457b..4f0e3ebfea4b 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -114,6 +114,19 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
114 return 0; 114 return 0;
115} 115}
116 116
117static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
118{
119 struct resource_entry *entry, *tmp;
120 int status;
121
122 status = acpi_pci_probe_root_resources(ci);
123 resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
124 if (!(entry->res->flags & IORESOURCE_WINDOW))
125 resource_list_destroy_entry(entry);
126 }
127 return status;
128}
129
117/* 130/*
118 * Lookup the bus range for the domain in MCFG, and set up config space 131 * Lookup the bus range for the domain in MCFG, and set up config space
119 * mapping. 132 * mapping.
@@ -121,31 +134,33 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
121static struct pci_config_window * 134static struct pci_config_window *
122pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) 135pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root)
123{ 136{
137 struct device *dev = &root->device->dev;
124 struct resource *bus_res = &root->secondary; 138 struct resource *bus_res = &root->secondary;
125 u16 seg = root->segment; 139 u16 seg = root->segment;
126 struct pci_config_window *cfg; 140 struct pci_ecam_ops *ecam_ops;
127 struct resource cfgres; 141 struct resource cfgres;
128 unsigned int bsz; 142 struct acpi_device *adev;
129 143 struct pci_config_window *cfg;
130 /* Use address from _CBA if present, otherwise lookup MCFG */ 144 int ret;
131 if (!root->mcfg_addr)
132 root->mcfg_addr = pci_mcfg_lookup(seg, bus_res);
133 145
134 if (!root->mcfg_addr) { 146 ret = pci_mcfg_lookup(root, &cfgres, &ecam_ops);
135 dev_err(&root->device->dev, "%04x:%pR ECAM region not found\n", 147 if (ret) {
136 seg, bus_res); 148 dev_err(dev, "%04x:%pR ECAM region not found\n", seg, bus_res);
137 return NULL; 149 return NULL;
138 } 150 }
139 151
140 bsz = 1 << pci_generic_ecam_ops.bus_shift; 152 adev = acpi_resource_consumer(&cfgres);
141 cfgres.start = root->mcfg_addr + bus_res->start * bsz; 153 if (adev)
142 cfgres.end = cfgres.start + resource_size(bus_res) * bsz - 1; 154 dev_info(dev, "ECAM area %pR reserved by %s\n", &cfgres,
143 cfgres.flags = IORESOURCE_MEM; 155 dev_name(&adev->dev));
144 cfg = pci_ecam_create(&root->device->dev, &cfgres, bus_res, 156 else
145 &pci_generic_ecam_ops); 157 dev_warn(dev, FW_BUG "ECAM area %pR not reserved in ACPI namespace\n",
158 &cfgres);
159
160 cfg = pci_ecam_create(dev, &cfgres, bus_res, ecam_ops);
146 if (IS_ERR(cfg)) { 161 if (IS_ERR(cfg)) {
147 dev_err(&root->device->dev, "%04x:%pR error %ld mapping ECAM\n", 162 dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res,
148 seg, bus_res, PTR_ERR(cfg)); 163 PTR_ERR(cfg));
149 return NULL; 164 return NULL;
150 } 165 }
151 166
@@ -159,33 +174,37 @@ static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci)
159 174
160 ri = container_of(ci, struct acpi_pci_generic_root_info, common); 175 ri = container_of(ci, struct acpi_pci_generic_root_info, common);
161 pci_ecam_free(ri->cfg); 176 pci_ecam_free(ri->cfg);
177 kfree(ci->ops);
162 kfree(ri); 178 kfree(ri);
163} 179}
164 180
165static struct acpi_pci_root_ops acpi_pci_root_ops = {
166 .release_info = pci_acpi_generic_release_info,
167};
168
169/* Interface called from ACPI code to setup PCI host controller */ 181/* Interface called from ACPI code to setup PCI host controller */
170struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) 182struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
171{ 183{
172 int node = acpi_get_node(root->device->handle); 184 int node = acpi_get_node(root->device->handle);
173 struct acpi_pci_generic_root_info *ri; 185 struct acpi_pci_generic_root_info *ri;
174 struct pci_bus *bus, *child; 186 struct pci_bus *bus, *child;
187 struct acpi_pci_root_ops *root_ops;
175 188
176 ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node); 189 ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node);
177 if (!ri) 190 if (!ri)
178 return NULL; 191 return NULL;
179 192
193 root_ops = kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node);
194 if (!root_ops)
195 return NULL;
196
180 ri->cfg = pci_acpi_setup_ecam_mapping(root); 197 ri->cfg = pci_acpi_setup_ecam_mapping(root);
181 if (!ri->cfg) { 198 if (!ri->cfg) {
182 kfree(ri); 199 kfree(ri);
200 kfree(root_ops);
183 return NULL; 201 return NULL;
184 } 202 }
185 203
186 acpi_pci_root_ops.pci_ops = &ri->cfg->ops->pci_ops; 204 root_ops->release_info = pci_acpi_generic_release_info;
187 bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common, 205 root_ops->prepare_resources = pci_acpi_root_prepare_resources;
188 ri->cfg); 206 root_ops->pci_ops = &ri->cfg->ops->pci_ops;
207 bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg);
189 if (!bus) 208 if (!bus)
190 return NULL; 209 return NULL;
191 210