diff options
author | Phil Edworthy <phil.edworthy@renesas.com> | 2015-10-02 06:25:05 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2015-10-30 09:23:15 -0400 |
commit | 79953dd22c1dfe38196485b53987466b048b8cc2 (patch) | |
tree | d9622825d6619d72d66c1287f7b52a7019316757 | |
parent | d0c3f4dbd20205529be1c0e0de618ce3fdaac844 (diff) |
PCI: rcar: Remove dependency on ARM-specific struct hw_pci
The R-Car PCIe host controller driver uses pci_common_init_dev(), which is
ARM-specific and requires the ARM struct hw_pci. The part of
pci_common_init_dev() that is needed is limited and can be done here
without using hw_pci.
Note that the ARM pcibios functions expect the PCI sysdata to be a pointer
to a struct pci_sys_data. Add a struct pci_sys_data as the first element
in struct gen_pci so that when we use a gen_pci pointer as sysdata, it is
also a pointer to a struct pci_sys_data.
Create and scan the root bus directly without using the ARM
pci_common_init_dev() interface.
Based on 499733e0cc1a ("PCI: generic: Remove dependency on ARM-specific
struct hw_pci").
Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r-- | drivers/pci/host/pcie-rcar.c | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 27e2c208f235..6057e3193e0f 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -124,7 +124,16 @@ static inline struct rcar_msi *to_rcar_msi(struct msi_controller *chip) | |||
124 | } | 124 | } |
125 | 125 | ||
126 | /* Structure representing the PCIe interface */ | 126 | /* Structure representing the PCIe interface */ |
127 | /* | ||
128 | * ARM pcibios functions expect the ARM struct pci_sys_data as the PCI | ||
129 | * sysdata. Add pci_sys_data as the first element in struct gen_pci so | ||
130 | * that when we use a gen_pci pointer as sysdata, it is also a pointer to | ||
131 | * a struct pci_sys_data. | ||
132 | */ | ||
127 | struct rcar_pcie { | 133 | struct rcar_pcie { |
134 | #ifdef CONFIG_ARM | ||
135 | struct pci_sys_data sys; | ||
136 | #endif | ||
128 | struct device *dev; | 137 | struct device *dev; |
129 | void __iomem *base; | 138 | void __iomem *base; |
130 | struct resource res[RCAR_PCI_MAX_RESOURCES]; | 139 | struct resource res[RCAR_PCI_MAX_RESOURCES]; |
@@ -135,11 +144,6 @@ struct rcar_pcie { | |||
135 | struct rcar_msi msi; | 144 | struct rcar_msi msi; |
136 | }; | 145 | }; |
137 | 146 | ||
138 | static inline struct rcar_pcie *sys_to_pcie(struct pci_sys_data *sys) | ||
139 | { | ||
140 | return sys->private_data; | ||
141 | } | ||
142 | |||
143 | static void rcar_pci_write_reg(struct rcar_pcie *pcie, unsigned long val, | 147 | static void rcar_pci_write_reg(struct rcar_pcie *pcie, unsigned long val, |
144 | unsigned long reg) | 148 | unsigned long reg) |
145 | { | 149 | { |
@@ -258,7 +262,7 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie, | |||
258 | static int rcar_pcie_read_conf(struct pci_bus *bus, unsigned int devfn, | 262 | static int rcar_pcie_read_conf(struct pci_bus *bus, unsigned int devfn, |
259 | int where, int size, u32 *val) | 263 | int where, int size, u32 *val) |
260 | { | 264 | { |
261 | struct rcar_pcie *pcie = sys_to_pcie(bus->sysdata); | 265 | struct rcar_pcie *pcie = bus->sysdata; |
262 | int ret; | 266 | int ret; |
263 | 267 | ||
264 | ret = rcar_pcie_config_access(pcie, RCAR_PCI_ACCESS_READ, | 268 | ret = rcar_pcie_config_access(pcie, RCAR_PCI_ACCESS_READ, |
@@ -283,7 +287,7 @@ static int rcar_pcie_read_conf(struct pci_bus *bus, unsigned int devfn, | |||
283 | static int rcar_pcie_write_conf(struct pci_bus *bus, unsigned int devfn, | 287 | static int rcar_pcie_write_conf(struct pci_bus *bus, unsigned int devfn, |
284 | int where, int size, u32 val) | 288 | int where, int size, u32 val) |
285 | { | 289 | { |
286 | struct rcar_pcie *pcie = sys_to_pcie(bus->sysdata); | 290 | struct rcar_pcie *pcie = bus->sysdata; |
287 | int shift, ret; | 291 | int shift, ret; |
288 | u32 data; | 292 | u32 data; |
289 | 293 | ||
@@ -353,9 +357,8 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie) | |||
353 | rcar_pci_write_reg(pcie, mask, PCIEPTCTLR(win)); | 357 | rcar_pci_write_reg(pcie, mask, PCIEPTCTLR(win)); |
354 | } | 358 | } |
355 | 359 | ||
356 | static int rcar_pcie_setup(int nr, struct pci_sys_data *sys) | 360 | static int rcar_pcie_setup(int nr, struct list_head *resource, struct rcar_pcie *pcie) |
357 | { | 361 | { |
358 | struct rcar_pcie *pcie = sys_to_pcie(sys); | ||
359 | struct resource *res; | 362 | struct resource *res; |
360 | int i; | 363 | int i; |
361 | 364 | ||
@@ -375,30 +378,49 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys) | |||
375 | pci_ioremap_io(nr * SZ_64K, io_start); | 378 | pci_ioremap_io(nr * SZ_64K, io_start); |
376 | } | 379 | } |
377 | 380 | ||
378 | pci_add_resource(&sys->resources, res); | 381 | pci_add_resource(resource, res); |
379 | } | 382 | } |
380 | pci_add_resource(&sys->resources, &pcie->busn); | 383 | pci_add_resource(resource, &pcie->busn); |
381 | 384 | ||
382 | return 1; | 385 | return 1; |
383 | } | 386 | } |
384 | 387 | ||
385 | static struct hw_pci rcar_pci = { | 388 | static int rcar_pcie_enable(struct rcar_pcie *pcie) |
386 | .setup = rcar_pcie_setup, | ||
387 | .map_irq = of_irq_parse_and_map_pci, | ||
388 | .ops = &rcar_pcie_ops, | ||
389 | }; | ||
390 | |||
391 | static void rcar_pcie_enable(struct rcar_pcie *pcie) | ||
392 | { | 389 | { |
393 | struct platform_device *pdev = to_platform_device(pcie->dev); | 390 | struct pci_bus *bus, *child; |
391 | LIST_HEAD(res); | ||
394 | 392 | ||
395 | rcar_pci.nr_controllers = 1; | 393 | rcar_pcie_setup(1, &res, pcie); |
396 | rcar_pci.private_data = (void **)&pcie; | 394 | |
397 | #ifdef CONFIG_PCI_MSI | 395 | /* Do not reassign resources if probe only */ |
398 | rcar_pci.msi_ctrl = &pcie->msi.chip; | 396 | if (!pci_has_flag(PCI_PROBE_ONLY)) |
399 | #endif | 397 | pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS); |
398 | |||
399 | if (IS_ENABLED(CONFIG_PCI_MSI)) | ||
400 | bus = pci_scan_root_bus_msi(pcie->dev, pcie->root_bus_nr, | ||
401 | &rcar_pcie_ops, pcie, &res, &pcie->msi.chip); | ||
402 | else | ||
403 | bus = pci_scan_root_bus(pcie->dev, pcie->root_bus_nr, | ||
404 | &rcar_pcie_ops, pcie, &res); | ||
405 | |||
406 | if (!bus) { | ||
407 | dev_err(pcie->dev, "Scanning rootbus failed"); | ||
408 | return -ENODEV; | ||
409 | } | ||
410 | |||
411 | pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); | ||
412 | |||
413 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | ||
414 | pci_bus_size_bridges(bus); | ||
415 | pci_bus_assign_resources(bus); | ||
400 | 416 | ||
401 | pci_common_init_dev(&pdev->dev, &rcar_pci); | 417 | list_for_each_entry(child, &bus->children, node) |
418 | pcie_bus_configure_settings(child); | ||
419 | } | ||
420 | |||
421 | pci_bus_add_devices(bus); | ||
422 | |||
423 | return 0; | ||
402 | } | 424 | } |
403 | 425 | ||
404 | static int phy_wait_for_ack(struct rcar_pcie *pcie) | 426 | static int phy_wait_for_ack(struct rcar_pcie *pcie) |
@@ -971,9 +993,7 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
971 | data = rcar_pci_read_reg(pcie, MACSR); | 993 | data = rcar_pci_read_reg(pcie, MACSR); |
972 | dev_info(&pdev->dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f); | 994 | dev_info(&pdev->dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f); |
973 | 995 | ||
974 | rcar_pcie_enable(pcie); | 996 | return rcar_pcie_enable(pcie); |
975 | |||
976 | return 0; | ||
977 | } | 997 | } |
978 | 998 | ||
979 | static struct platform_driver rcar_pcie_driver = { | 999 | static struct platform_driver rcar_pcie_driver = { |