diff options
Diffstat (limited to 'drivers/pci/host/pci-host-common.c')
-rw-r--r-- | drivers/pci/host/pci-host-common.c | 87 |
1 files changed, 6 insertions, 81 deletions
diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 44a47d4f0b8f..5d028f53fdcd 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c | |||
@@ -1,18 +1,7 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Generic PCI host driver common code | 3 | * Generic PCI host driver common code |
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | * | ||
16 | * Copyright (C) 2014 ARM Limited | 5 | * Copyright (C) 2014 ARM Limited |
17 | * | 6 | * |
18 | * Author: Will Deacon <will.deacon@arm.com> | 7 | * Author: Will Deacon <will.deacon@arm.com> |
@@ -24,50 +13,6 @@ | |||
24 | #include <linux/pci-ecam.h> | 13 | #include <linux/pci-ecam.h> |
25 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
26 | 15 | ||
27 | static int gen_pci_parse_request_of_pci_ranges(struct device *dev, | ||
28 | struct list_head *resources, struct resource **bus_range) | ||
29 | { | ||
30 | int err, res_valid = 0; | ||
31 | struct device_node *np = dev->of_node; | ||
32 | resource_size_t iobase; | ||
33 | struct resource_entry *win, *tmp; | ||
34 | |||
35 | err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase); | ||
36 | if (err) | ||
37 | return err; | ||
38 | |||
39 | err = devm_request_pci_bus_resources(dev, resources); | ||
40 | if (err) | ||
41 | return err; | ||
42 | |||
43 | resource_list_for_each_entry_safe(win, tmp, resources) { | ||
44 | struct resource *res = win->res; | ||
45 | |||
46 | switch (resource_type(res)) { | ||
47 | case IORESOURCE_IO: | ||
48 | err = pci_remap_iospace(res, iobase); | ||
49 | if (err) { | ||
50 | dev_warn(dev, "error %d: failed to map resource %pR\n", | ||
51 | err, res); | ||
52 | resource_list_destroy_entry(win); | ||
53 | } | ||
54 | break; | ||
55 | case IORESOURCE_MEM: | ||
56 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | ||
57 | break; | ||
58 | case IORESOURCE_BUS: | ||
59 | *bus_range = res; | ||
60 | break; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | if (res_valid) | ||
65 | return 0; | ||
66 | |||
67 | dev_err(dev, "non-prefetchable memory resource required\n"); | ||
68 | return -EINVAL; | ||
69 | } | ||
70 | |||
71 | static void gen_pci_unmap_cfg(void *ptr) | 16 | static void gen_pci_unmap_cfg(void *ptr) |
72 | { | 17 | { |
73 | pci_ecam_free((struct pci_config_window *)ptr); | 18 | pci_ecam_free((struct pci_config_window *)ptr); |
@@ -82,9 +27,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev, | |||
82 | struct pci_config_window *cfg; | 27 | struct pci_config_window *cfg; |
83 | 28 | ||
84 | /* Parse our PCI ranges and request their resources */ | 29 | /* Parse our PCI ranges and request their resources */ |
85 | err = gen_pci_parse_request_of_pci_ranges(dev, resources, &bus_range); | 30 | err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range); |
86 | if (err) | 31 | if (err) |
87 | goto err_out; | 32 | return ERR_PTR(err); |
88 | 33 | ||
89 | err = of_address_to_resource(dev->of_node, 0, &cfgres); | 34 | err = of_address_to_resource(dev->of_node, 0, &cfgres); |
90 | if (err) { | 35 | if (err) { |
@@ -116,7 +61,6 @@ int pci_host_common_probe(struct platform_device *pdev, | |||
116 | const char *type; | 61 | const char *type; |
117 | struct device *dev = &pdev->dev; | 62 | struct device *dev = &pdev->dev; |
118 | struct device_node *np = dev->of_node; | 63 | struct device_node *np = dev->of_node; |
119 | struct pci_bus *bus, *child; | ||
120 | struct pci_host_bridge *bridge; | 64 | struct pci_host_bridge *bridge; |
121 | struct pci_config_window *cfg; | 65 | struct pci_config_window *cfg; |
122 | struct list_head resources; | 66 | struct list_head resources; |
@@ -135,14 +79,13 @@ int pci_host_common_probe(struct platform_device *pdev, | |||
135 | of_pci_check_probe_only(); | 79 | of_pci_check_probe_only(); |
136 | 80 | ||
137 | /* Parse and map our Configuration Space windows */ | 81 | /* Parse and map our Configuration Space windows */ |
138 | INIT_LIST_HEAD(&resources); | ||
139 | cfg = gen_pci_init(dev, &resources, ops); | 82 | cfg = gen_pci_init(dev, &resources, ops); |
140 | if (IS_ERR(cfg)) | 83 | if (IS_ERR(cfg)) |
141 | return PTR_ERR(cfg); | 84 | return PTR_ERR(cfg); |
142 | 85 | ||
143 | /* Do not reassign resources if probe only */ | 86 | /* Do not reassign resources if probe only */ |
144 | if (!pci_has_flag(PCI_PROBE_ONLY)) | 87 | if (!pci_has_flag(PCI_PROBE_ONLY)) |
145 | pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS); | 88 | pci_add_flags(PCI_REASSIGN_ALL_BUS); |
146 | 89 | ||
147 | list_splice_init(&resources, &bridge->windows); | 90 | list_splice_init(&resources, &bridge->windows); |
148 | bridge->dev.parent = dev; | 91 | bridge->dev.parent = dev; |
@@ -152,29 +95,11 @@ int pci_host_common_probe(struct platform_device *pdev, | |||
152 | bridge->map_irq = of_irq_parse_and_map_pci; | 95 | bridge->map_irq = of_irq_parse_and_map_pci; |
153 | bridge->swizzle_irq = pci_common_swizzle; | 96 | bridge->swizzle_irq = pci_common_swizzle; |
154 | 97 | ||
155 | ret = pci_scan_root_bus_bridge(bridge); | 98 | ret = pci_host_probe(bridge); |
156 | if (ret < 0) { | 99 | if (ret < 0) { |
157 | dev_err(dev, "Scanning root bridge failed"); | 100 | pci_free_resource_list(&resources); |
158 | return ret; | 101 | return ret; |
159 | } | 102 | } |
160 | 103 | ||
161 | bus = bridge->bus; | ||
162 | |||
163 | /* | ||
164 | * We insert PCI resources into the iomem_resource and | ||
165 | * ioport_resource trees in either pci_bus_claim_resources() | ||
166 | * or pci_bus_assign_resources(). | ||
167 | */ | ||
168 | if (pci_has_flag(PCI_PROBE_ONLY)) { | ||
169 | pci_bus_claim_resources(bus); | ||
170 | } else { | ||
171 | pci_bus_size_bridges(bus); | ||
172 | pci_bus_assign_resources(bus); | ||
173 | |||
174 | list_for_each_entry(child, &bus->children, node) | ||
175 | pcie_bus_configure_settings(child); | ||
176 | } | ||
177 | |||
178 | pci_bus_add_devices(bus); | ||
179 | return 0; | 104 | return 0; |
180 | } | 105 | } |