aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/pci_of_scan.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2009-08-25 16:07:11 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-08-28 00:24:15 -0400
commitfbe65447197789a3ccccc27755956f6a4c445089 (patch)
tree58d0f0a97883bb573b5eae2a0e35618cc8b83062 /arch/powerpc/kernel/pci_of_scan.c
parentae14e13a4c8bb091dfd5606fd76c9cd272090ab7 (diff)
powerpc/pci: move pci_64.c device tree scanning code into pci-common.c
The PCI device tree scanning code in pci_64.c is some useful functionality. It allows PCI devices to be described in the device tree instead of being probed for, which in turn allows pci devices to use all of the device tree facilities to describe complex PCI bus architectures like GPIO and IRQ routing (perhaps not a common situation for desktop or server systems, but useful for embedded systems with on-board PCI devices). This patch moves the device tree scanning into pci-common.c so it is available for 32-bit powerpc machines too. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Acked-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/pci_of_scan.c')
-rw-r--r--arch/powerpc/kernel/pci_of_scan.c358
1 files changed, 358 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
new file mode 100644
index 000000000000..72c31bcb7aa4
--- /dev/null
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -0,0 +1,358 @@
1/*
2 * Helper routines to scan the device tree for PCI devices and busses
3 *
4 * Migrated out of PowerPC architecture pci_64.c file by Grant Likely
5 * <grant.likely@secretlab.ca> so that these routines are available for
6 * 32 bit also.
7 *
8 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
9 * Rework, based on alpha PCI code.
10 * Copyright (c) 2009 Secret Lab Technologies Ltd.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 as published by the Free Software Foundation.
15 */
16
17#include <linux/pci.h>
18#include <asm/pci-bridge.h>
19#include <asm/prom.h>
20
21/**
22 * get_int_prop - Decode a u32 from a device tree property
23 */
24static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
25{
26 const u32 *prop;
27 int len;
28
29 prop = of_get_property(np, name, &len);
30 if (prop && len >= 4)
31 return *prop;
32 return def;
33}
34
35/**
36 * pci_parse_of_flags - Parse the flags cell of a device tree PCI address
37 * @addr0: value of 1st cell of a device tree PCI address.
38 * @bridge: Set this flag if the address is from a bridge 'ranges' property
39 */
40unsigned int pci_parse_of_flags(u32 addr0, int bridge)
41{
42 unsigned int flags = 0;
43
44 if (addr0 & 0x02000000) {
45 flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
46 flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
47 flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
48 if (addr0 & 0x40000000)
49 flags |= IORESOURCE_PREFETCH
50 | PCI_BASE_ADDRESS_MEM_PREFETCH;
51 /* Note: We don't know whether the ROM has been left enabled
52 * by the firmware or not. We mark it as disabled (ie, we do
53 * not set the IORESOURCE_ROM_ENABLE flag) for now rather than
54 * do a config space read, it will be force-enabled if needed
55 */
56 if (!bridge && (addr0 & 0xff) == 0x30)
57 flags |= IORESOURCE_READONLY;
58 } else if (addr0 & 0x01000000)
59 flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
60 if (flags)
61 flags |= IORESOURCE_SIZEALIGN;
62 return flags;
63}
64
65/**
66 * of_pci_parse_addrs - Parse PCI addresses assigned in the device tree node
67 * @node: device tree node for the PCI device
68 * @dev: pci_dev structure for the device
69 *
70 * This function parses the 'assigned-addresses' property of a PCI devices'
71 * device tree node and writes them into the associated pci_dev structure.
72 */
73static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
74{
75 u64 base, size;
76 unsigned int flags;
77 struct resource *res;
78 const u32 *addrs;
79 u32 i;
80 int proplen;
81
82 addrs = of_get_property(node, "assigned-addresses", &proplen);
83 if (!addrs)
84 return;
85 pr_debug(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
86 for (; proplen >= 20; proplen -= 20, addrs += 5) {
87 flags = pci_parse_of_flags(addrs[0], 0);
88 if (!flags)
89 continue;
90 base = of_read_number(&addrs[1], 2);
91 size = of_read_number(&addrs[3], 2);
92 if (!size)
93 continue;
94 i = addrs[0] & 0xff;
95 pr_debug(" base: %llx, size: %llx, i: %x\n",
96 (unsigned long long)base,
97 (unsigned long long)size, i);
98
99 if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
100 res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
101 } else if (i == dev->rom_base_reg) {
102 res = &dev->resource[PCI_ROM_RESOURCE];
103 flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
104 } else {
105 printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
106 continue;
107 }
108 res->start = base;
109 res->end = base + size - 1;
110 res->flags = flags;
111 res->name = pci_name(dev);
112 }
113}
114
115/**
116 * of_create_pci_dev - Given a device tree node on a pci bus, create a pci_dev
117 * @node: device tree node pointer
118 * @bus: bus the device is sitting on
119 * @devfn: PCI function number, extracted from device tree by caller.
120 */
121struct pci_dev *of_create_pci_dev(struct device_node *node,
122 struct pci_bus *bus, int devfn)
123{
124 struct pci_dev *dev;
125 const char *type;
126
127 dev = alloc_pci_dev();
128 if (!dev)
129 return NULL;
130 type = of_get_property(node, "device_type", NULL);
131 if (type == NULL)
132 type = "";
133
134 pr_debug(" create device, devfn: %x, type: %s\n", devfn, type);
135
136 dev->bus = bus;
137 dev->sysdata = node;
138 dev->dev.parent = bus->bridge;
139 dev->dev.bus = &pci_bus_type;
140 dev->devfn = devfn;
141 dev->multifunction = 0; /* maybe a lie? */
142
143 dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
144 dev->device = get_int_prop(node, "device-id", 0xffff);
145 dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
146 dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);
147
148 dev->cfg_size = pci_cfg_space_size(dev);
149
150 dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
151 dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
152 dev->class = get_int_prop(node, "class-code", 0);
153 dev->revision = get_int_prop(node, "revision-id", 0);
154
155 pr_debug(" class: 0x%x\n", dev->class);
156 pr_debug(" revision: 0x%x\n", dev->revision);
157
158 dev->current_state = 4; /* unknown power state */
159 dev->error_state = pci_channel_io_normal;
160 dev->dma_mask = 0xffffffff;
161
162 if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
163 /* a PCI-PCI bridge */
164 dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
165 dev->rom_base_reg = PCI_ROM_ADDRESS1;
166 } else if (!strcmp(type, "cardbus")) {
167 dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
168 } else {
169 dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
170 dev->rom_base_reg = PCI_ROM_ADDRESS;
171 /* Maybe do a default OF mapping here */
172 dev->irq = NO_IRQ;
173 }
174
175 of_pci_parse_addrs(node, dev);
176
177 pr_debug(" adding to system ...\n");
178
179 pci_device_add(dev, bus);
180
181 return dev;
182}
183EXPORT_SYMBOL(of_create_pci_dev);
184
185/**
186 * of_scan_pci_bridge - Set up a PCI bridge and scan for child nodes
187 * @node: device tree node of bridge
188 * @dev: pci_dev structure for the bridge
189 *
190 * of_scan_bus() calls this routine for each PCI bridge that it finds, and
191 * this routine in turn call of_scan_bus() recusively to scan for more child
192 * devices.
193 */
194void __devinit of_scan_pci_bridge(struct device_node *node,
195 struct pci_dev *dev)
196{
197 struct pci_bus *bus;
198 const u32 *busrange, *ranges;
199 int len, i, mode;
200 struct resource *res;
201 unsigned int flags;
202 u64 size;
203
204 pr_debug("of_scan_pci_bridge(%s)\n", node->full_name);
205
206 /* parse bus-range property */
207 busrange = of_get_property(node, "bus-range", &len);
208 if (busrange == NULL || len != 8) {
209 printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
210 node->full_name);
211 return;
212 }
213 ranges = of_get_property(node, "ranges", &len);
214 if (ranges == NULL) {
215 printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
216 node->full_name);
217 return;
218 }
219
220 bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
221 if (!bus) {
222 printk(KERN_ERR "Failed to create pci bus for %s\n",
223 node->full_name);
224 return;
225 }
226
227 bus->primary = dev->bus->number;
228 bus->subordinate = busrange[1];
229 bus->bridge_ctl = 0;
230 bus->sysdata = node;
231
232 /* parse ranges property */
233 /* PCI #address-cells == 3 and #size-cells == 2 always */
234 res = &dev->resource[PCI_BRIDGE_RESOURCES];
235 for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) {
236 res->flags = 0;
237 bus->resource[i] = res;
238 ++res;
239 }
240 i = 1;
241 for (; len >= 32; len -= 32, ranges += 8) {
242 flags = pci_parse_of_flags(ranges[0], 1);
243 size = of_read_number(&ranges[6], 2);
244 if (flags == 0 || size == 0)
245 continue;
246 if (flags & IORESOURCE_IO) {
247 res = bus->resource[0];
248 if (res->flags) {
249 printk(KERN_ERR "PCI: ignoring extra I/O range"
250 " for bridge %s\n", node->full_name);
251 continue;
252 }
253 } else {
254 if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
255 printk(KERN_ERR "PCI: too many memory ranges"
256 " for bridge %s\n", node->full_name);
257 continue;
258 }
259 res = bus->resource[i];
260 ++i;
261 }
262 res->start = of_read_number(&ranges[1], 2);
263 res->end = res->start + size - 1;
264 res->flags = flags;
265 }
266 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
267 bus->number);
268 pr_debug(" bus name: %s\n", bus->name);
269
270 mode = PCI_PROBE_NORMAL;
271 if (ppc_md.pci_probe_mode)
272 mode = ppc_md.pci_probe_mode(bus);
273 pr_debug(" probe mode: %d\n", mode);
274
275 if (mode == PCI_PROBE_DEVTREE)
276 of_scan_bus(node, bus);
277 else if (mode == PCI_PROBE_NORMAL)
278 pci_scan_child_bus(bus);
279}
280EXPORT_SYMBOL(of_scan_pci_bridge);
281
282/**
283 * __of_scan_bus - given a PCI bus node, setup bus and scan for child devices
284 * @node: device tree node for the PCI bus
285 * @bus: pci_bus structure for the PCI bus
286 * @rescan_existing: Flag indicating bus has already been set up
287 */
288static void __devinit __of_scan_bus(struct device_node *node,
289 struct pci_bus *bus, int rescan_existing)
290{
291 struct device_node *child;
292 const u32 *reg;
293 int reglen, devfn;
294 struct pci_dev *dev;
295
296 pr_debug("of_scan_bus(%s) bus no %d... \n",
297 node->full_name, bus->number);
298
299 /* Scan direct children */
300 for_each_child_of_node(node, child) {
301 pr_debug(" * %s\n", child->full_name);
302 reg = of_get_property(child, "reg", &reglen);
303 if (reg == NULL || reglen < 20)
304 continue;
305 devfn = (reg[0] >> 8) & 0xff;
306
307 /* create a new pci_dev for this device */
308 dev = of_create_pci_dev(child, bus, devfn);
309 if (!dev)
310 continue;
311 pr_debug(" dev header type: %x\n", dev->hdr_type);
312 }
313
314 /* Apply all fixups necessary. We don't fixup the bus "self"
315 * for an existing bridge that is being rescanned
316 */
317 if (!rescan_existing)
318 pcibios_setup_bus_self(bus);
319 pcibios_setup_bus_devices(bus);
320
321 /* Now scan child busses */
322 list_for_each_entry(dev, &bus->devices, bus_list) {
323 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
324 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
325 struct device_node *child = pci_device_to_OF_node(dev);
326 if (dev)
327 of_scan_pci_bridge(child, dev);
328 }
329 }
330}
331
332/**
333 * of_scan_bus - given a PCI bus node, setup bus and scan for child devices
334 * @node: device tree node for the PCI bus
335 * @bus: pci_bus structure for the PCI bus
336 */
337void __devinit of_scan_bus(struct device_node *node,
338 struct pci_bus *bus)
339{
340 __of_scan_bus(node, bus, 0);
341}
342EXPORT_SYMBOL_GPL(of_scan_bus);
343
344/**
345 * of_rescan_bus - given a PCI bus node, scan for child devices
346 * @node: device tree node for the PCI bus
347 * @bus: pci_bus structure for the PCI bus
348 *
349 * Same as of_scan_bus, but for a pci_bus structure that has already been
350 * setup.
351 */
352void __devinit of_rescan_bus(struct device_node *node,
353 struct pci_bus *bus)
354{
355 __of_scan_bus(node, bus, 1);
356}
357EXPORT_SYMBOL_GPL(of_rescan_bus);
358