aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2006-05-01 11:43:46 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-21 14:59:59 -0400
commit75acfecaa031c0e1bc412cee4fe58ba49ff3406c (patch)
tree39f784dcc17a093e80463163867ec0e554942453
parentea28502d5d0fc624777a8a6b4d6865d282055b05 (diff)
[PATCH] PCI: Add pci_assign_resource_fixed -- allow fixed address assignments
PCI: Add pci_assign_resource_fixed -- allow fixed address assignments On some embedded systems the PCI address for hotplug devices are not only known a priori but are required to be at a given PCI address for other master in the system to be able to access. An example of such a system would be an FPGA which is setup from user space after the system has booted. The FPGA may be access by DSPs in the system and those DSPs expect the FPGA at a fixed PCI address. Added pci_assign_resource_fixed() as a way to allow assignment of the PCI devices's BARs at fixed PCI addresses. Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/pci/setup-res.c40
-rw-r--r--include/linux/pci.h1
2 files changed, 41 insertions, 0 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index ea9277b7f899..577f4b55c46d 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -155,6 +155,46 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
155 return ret; 155 return ret;
156} 156}
157 157
158#ifdef CONFIG_EMBEDDED
159int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
160{
161 struct pci_bus *bus = dev->bus;
162 struct resource *res = dev->resource + resno;
163 unsigned int type_mask;
164 int i, ret = -EBUSY;
165
166 type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH;
167
168 for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
169 struct resource *r = bus->resource[i];
170 if (!r)
171 continue;
172
173 /* type_mask must match */
174 if ((res->flags ^ r->flags) & type_mask)
175 continue;
176
177 ret = request_resource(r, res);
178
179 if (ret == 0)
180 break;
181 }
182
183 if (ret) {
184 printk(KERN_ERR "PCI: Failed to allocate %s resource "
185 "#%d:%llx@%llx for %s\n",
186 res->flags & IORESOURCE_IO ? "I/O" : "mem",
187 resno, (unsigned long long)(res->end - res->start + 1),
188 (unsigned long long)res->start, pci_name(dev));
189 } else if (resno < PCI_BRIDGE_RESOURCES) {
190 pci_update_resource(dev, res, resno);
191 }
192
193 return ret;
194}
195EXPORT_SYMBOL_GPL(pci_assign_resource_fixed);
196#endif
197
158/* Sort resources by alignment */ 198/* Sort resources by alignment */
159void __devinit 199void __devinit
160pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) 200pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6c4bc773f7b7..b9eb9b021d6a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -496,6 +496,7 @@ int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
496int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); 496int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
497void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); 497void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
498int pci_assign_resource(struct pci_dev *dev, int i); 498int pci_assign_resource(struct pci_dev *dev, int i);
499int pci_assign_resource_fixed(struct pci_dev *dev, int i);
499void pci_restore_bars(struct pci_dev *dev); 500void pci_restore_bars(struct pci_dev *dev);
500 501
501/* ROM control related routines */ 502/* ROM control related routines */