aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/host/pci-host-generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/host/pci-host-generic.c')
-rw-r--r--drivers/pci/host/pci-host-generic.c52
1 files changed, 33 insertions, 19 deletions
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index ba46e581db99..265dd25169bf 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -38,7 +38,16 @@ struct gen_pci_cfg_windows {
38 const struct gen_pci_cfg_bus_ops *ops; 38 const struct gen_pci_cfg_bus_ops *ops;
39}; 39};
40 40
41/*
42 * ARM pcibios functions expect the ARM struct pci_sys_data as the PCI
43 * sysdata. Add pci_sys_data as the first element in struct gen_pci so
44 * that when we use a gen_pci pointer as sysdata, it is also a pointer to
45 * a struct pci_sys_data.
46 */
41struct gen_pci { 47struct gen_pci {
48#ifdef CONFIG_ARM
49 struct pci_sys_data sys;
50#endif
42 struct pci_host_bridge host; 51 struct pci_host_bridge host;
43 struct gen_pci_cfg_windows cfg; 52 struct gen_pci_cfg_windows cfg;
44 struct list_head resources; 53 struct list_head resources;
@@ -48,8 +57,7 @@ static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus,
48 unsigned int devfn, 57 unsigned int devfn,
49 int where) 58 int where)
50{ 59{
51 struct pci_sys_data *sys = bus->sysdata; 60 struct gen_pci *pci = bus->sysdata;
52 struct gen_pci *pci = sys->private_data;
53 resource_size_t idx = bus->number - pci->cfg.bus_range->start; 61 resource_size_t idx = bus->number - pci->cfg.bus_range->start;
54 62
55 return pci->cfg.win[idx] + ((devfn << 8) | where); 63 return pci->cfg.win[idx] + ((devfn << 8) | where);
@@ -64,8 +72,7 @@ static void __iomem *gen_pci_map_cfg_bus_ecam(struct pci_bus *bus,
64 unsigned int devfn, 72 unsigned int devfn,
65 int where) 73 int where)
66{ 74{
67 struct pci_sys_data *sys = bus->sysdata; 75 struct gen_pci *pci = bus->sysdata;
68 struct gen_pci *pci = sys->private_data;
69 resource_size_t idx = bus->number - pci->cfg.bus_range->start; 76 resource_size_t idx = bus->number - pci->cfg.bus_range->start;
70 77
71 return pci->cfg.win[idx] + ((devfn << 12) | where); 78 return pci->cfg.win[idx] + ((devfn << 12) | where);
@@ -198,13 +205,6 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
198 return 0; 205 return 0;
199} 206}
200 207
201static int gen_pci_setup(int nr, struct pci_sys_data *sys)
202{
203 struct gen_pci *pci = sys->private_data;
204 list_splice_init(&pci->resources, &sys->resources);
205 return 1;
206}
207
208static int gen_pci_probe(struct platform_device *pdev) 208static int gen_pci_probe(struct platform_device *pdev)
209{ 209{
210 int err; 210 int err;
@@ -214,13 +214,7 @@ static int gen_pci_probe(struct platform_device *pdev)
214 struct device *dev = &pdev->dev; 214 struct device *dev = &pdev->dev;
215 struct device_node *np = dev->of_node; 215 struct device_node *np = dev->of_node;
216 struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); 216 struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
217 struct hw_pci hw = { 217 struct pci_bus *bus, *child;
218 .nr_controllers = 1,
219 .private_data = (void **)&pci,
220 .setup = gen_pci_setup,
221 .map_irq = of_irq_parse_and_map_pci,
222 .ops = &gen_pci_ops,
223 };
224 218
225 if (!pci) 219 if (!pci)
226 return -ENOMEM; 220 return -ENOMEM;
@@ -258,7 +252,27 @@ static int gen_pci_probe(struct platform_device *pdev)
258 return err; 252 return err;
259 } 253 }
260 254
261 pci_common_init_dev(dev, &hw); 255 /* Do not reassign resources if probe only */
256 if (!pci_has_flag(PCI_PROBE_ONLY))
257 pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
258
259 bus = pci_scan_root_bus(dev, 0, &gen_pci_ops, pci, &pci->resources);
260 if (!bus) {
261 dev_err(dev, "Scanning rootbus failed");
262 return -ENODEV;
263 }
264
265 pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
266
267 if (!pci_has_flag(PCI_PROBE_ONLY)) {
268 pci_bus_size_bridges(bus);
269 pci_bus_assign_resources(bus);
270
271 list_for_each_entry(child, &bus->children, node)
272 pcie_bus_configure_settings(child);
273 }
274
275 pci_bus_add_devices(bus);
262 return 0; 276 return 0;
263} 277}
264 278