diff options
Diffstat (limited to 'drivers/pci/host/pci-host-generic.c')
-rw-r--r-- | drivers/pci/host/pci-host-generic.c | 52 |
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 | */ | ||
41 | struct gen_pci { | 47 | struct 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 | ||
201 | static 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 | |||
208 | static int gen_pci_probe(struct platform_device *pdev) | 208 | static 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 | ||