aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyrille Pitchen <cyrille.pitchen@free-electrons.com>2018-01-30 15:56:50 -0500
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2018-01-31 06:09:32 -0500
commit3a8f77e48666a39adb3ac4d5ce8261563e039e31 (patch)
treeb5146ef9b6734451c1c246871d63d30808199658
parent9de0eec29c07a65c21323f934d84ce164b0d9205 (diff)
PCI: OF: Add generic function to parse and allocate PCI resources
The patch moves the gen_pci_parse_request_of_pci_ranges() function from drivers/pci/host/pci-host-common.c into drivers/pci/of.c to easily share common source code between PCI host drivers. Signed-off-by: Cyrille Pitchen <cyrille.pitchen@free-electrons.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
-rw-r--r--drivers/pci/host/pci-host-common.c49
-rw-r--r--drivers/pci/of.c51
-rw-r--r--include/linux/pci.h9
3 files changed, 62 insertions, 47 deletions
diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c
index 44a47d4f0b8f..efd904d93562 100644
--- a/drivers/pci/host/pci-host-common.c
+++ b/drivers/pci/host/pci-host-common.c
@@ -24,50 +24,6 @@
24#include <linux/pci-ecam.h> 24#include <linux/pci-ecam.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26 26
27static 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
71static void gen_pci_unmap_cfg(void *ptr) 27static void gen_pci_unmap_cfg(void *ptr)
72{ 28{
73 pci_ecam_free((struct pci_config_window *)ptr); 29 pci_ecam_free((struct pci_config_window *)ptr);
@@ -82,9 +38,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev,
82 struct pci_config_window *cfg; 38 struct pci_config_window *cfg;
83 39
84 /* Parse our PCI ranges and request their resources */ 40 /* Parse our PCI ranges and request their resources */
85 err = gen_pci_parse_request_of_pci_ranges(dev, resources, &bus_range); 41 err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
86 if (err) 42 if (err)
87 goto err_out; 43 return ERR_PTR(err);
88 44
89 err = of_address_to_resource(dev->of_node, 0, &cfgres); 45 err = of_address_to_resource(dev->of_node, 0, &cfgres);
90 if (err) { 46 if (err) {
@@ -135,7 +91,6 @@ int pci_host_common_probe(struct platform_device *pdev,
135 of_pci_check_probe_only(); 91 of_pci_check_probe_only();
136 92
137 /* Parse and map our Configuration Space windows */ 93 /* Parse and map our Configuration Space windows */
138 INIT_LIST_HEAD(&resources);
139 cfg = gen_pci_init(dev, &resources, ops); 94 cfg = gen_pci_init(dev, &resources, ops);
140 if (IS_ERR(cfg)) 95 if (IS_ERR(cfg))
141 return PTR_ERR(cfg); 96 return PTR_ERR(cfg);
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index e112da11630e..54e210501b73 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -88,3 +88,54 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus)
88 return NULL; 88 return NULL;
89#endif 89#endif
90} 90}
91
92int pci_parse_request_of_pci_ranges(struct device *dev,
93 struct list_head *resources,
94 struct resource **bus_range)
95{
96 int err, res_valid = 0;
97 struct device_node *np = dev->of_node;
98 resource_size_t iobase;
99 struct resource_entry *win, *tmp;
100
101 INIT_LIST_HEAD(resources);
102 err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase);
103 if (err)
104 return err;
105
106 err = devm_request_pci_bus_resources(dev, resources);
107 if (err)
108 goto out_release_res;
109
110 resource_list_for_each_entry_safe(win, tmp, resources) {
111 struct resource *res = win->res;
112
113 switch (resource_type(res)) {
114 case IORESOURCE_IO:
115 err = pci_remap_iospace(res, iobase);
116 if (err) {
117 dev_warn(dev, "error %d: failed to map resource %pR\n",
118 err, res);
119 resource_list_destroy_entry(win);
120 }
121 break;
122 case IORESOURCE_MEM:
123 res_valid |= !(res->flags & IORESOURCE_PREFETCH);
124 break;
125 case IORESOURCE_BUS:
126 if (bus_range)
127 *bus_range = res;
128 break;
129 }
130 }
131
132 if (res_valid)
133 return 0;
134
135 dev_err(dev, "non-prefetchable memory resource required\n");
136 err = -EINVAL;
137
138 out_release_res:
139 pci_free_resource_list(resources);
140 return err;
141}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index c170c9250c8b..c7a701abbf17 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -2182,6 +2182,9 @@ void pci_release_of_node(struct pci_dev *dev);
2182void pci_set_bus_of_node(struct pci_bus *bus); 2182void pci_set_bus_of_node(struct pci_bus *bus);
2183void pci_release_bus_of_node(struct pci_bus *bus); 2183void pci_release_bus_of_node(struct pci_bus *bus);
2184struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus); 2184struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus);
2185int pci_parse_request_of_pci_ranges(struct device *dev,
2186 struct list_head *resources,
2187 struct resource **bus_range);
2185 2188
2186/* Arch may override this (weak) */ 2189/* Arch may override this (weak) */
2187struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus); 2190struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus);
@@ -2206,6 +2209,12 @@ static inline struct device_node *
2206pci_device_to_OF_node(const struct pci_dev *pdev) { return NULL; } 2209pci_device_to_OF_node(const struct pci_dev *pdev) { return NULL; }
2207static inline struct irq_domain * 2210static inline struct irq_domain *
2208pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; } 2211pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
2212static inline int pci_parse_request_of_pci_ranges(struct device *dev,
2213 struct list_head *resources,
2214 struct resource **bus_range)
2215{
2216 return -EINVAL;
2217}
2209#endif /* CONFIG_OF */ 2218#endif /* CONFIG_OF */
2210 2219
2211#ifdef CONFIG_ACPI 2220#ifdef CONFIG_ACPI