aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
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
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')
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h5
-rw-r--r--arch/powerpc/include/asm/pci.h5
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/pci-common.c1
-rw-r--r--arch/powerpc/kernel/pci_64.c289
-rw-r--r--arch/powerpc/kernel/pci_of_scan.c358
6 files changed, 364 insertions, 296 deletions
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 4c61fa0b8d75..3faf575f6b06 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -284,11 +284,6 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
284extern int pcibios_unmap_io_space(struct pci_bus *bus); 284extern int pcibios_unmap_io_space(struct pci_bus *bus);
285extern int pcibios_map_io_space(struct pci_bus *bus); 285extern int pcibios_map_io_space(struct pci_bus *bus);
286 286
287/* Return values for ppc_md.pci_probe_mode function */
288#define PCI_PROBE_NONE -1 /* Don't look at this bus at all */
289#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */
290#define PCI_PROBE_DEVTREE 1 /* Instantiate from device tree */
291
292#ifdef CONFIG_NUMA 287#ifdef CONFIG_NUMA
293#define PHB_SET_NODE(PHB, NODE) ((PHB)->node = (NODE)) 288#define PHB_SET_NODE(PHB, NODE) ((PHB)->node = (NODE))
294#else 289#else
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 7ae46d7e270d..b856a837b4a3 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -22,6 +22,11 @@
22 22
23#include <asm-generic/pci-dma-compat.h> 23#include <asm-generic/pci-dma-compat.h>
24 24
25/* Return values for ppc_md.pci_probe_mode function */
26#define PCI_PROBE_NONE -1 /* Don't look at this bus at all */
27#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */
28#define PCI_PROBE_DEVTREE 1 /* Instantiate from device tree */
29
25#define PCIBIOS_MIN_IO 0x1000 30#define PCIBIOS_MIN_IO 0x1000
26#define PCIBIOS_MIN_MEM 0x10000000 31#define PCIBIOS_MIN_MEM 0x10000000
27 32
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 7c83edbc2155..569f79ccd310 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -88,7 +88,7 @@ obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o
88 88
89pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o 89pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o
90obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \ 90obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
91 pci-common.o 91 pci-common.o pci_of_scan.o
92obj-$(CONFIG_PCI_MSI) += msi.o 92obj-$(CONFIG_PCI_MSI) += msi.o
93obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \ 93obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \
94 machine_kexec_$(CONFIG_WORD_SIZE).o 94 machine_kexec_$(CONFIG_WORD_SIZE).o
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 158a78ae6341..725ea9144e38 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1617,4 +1617,3 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
1617 (unsigned long)hose->io_base_virt - _IO_BASE); 1617 (unsigned long)hose->io_base_virt - _IO_BASE);
1618 1618
1619} 1619}
1620
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 9e8902fa14c7..4d5b4ced7e45 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -43,295 +43,6 @@ unsigned long pci_probe_only = 1;
43unsigned long pci_io_base = ISA_IO_BASE; 43unsigned long pci_io_base = ISA_IO_BASE;
44EXPORT_SYMBOL(pci_io_base); 44EXPORT_SYMBOL(pci_io_base);
45 45
46static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
47{
48 const u32 *prop;
49 int len;
50
51 prop = of_get_property(np, name, &len);
52 if (prop && len >= 4)
53 return *prop;
54 return def;
55}
56
57static unsigned int pci_parse_of_flags(u32 addr0, int bridge)
58{
59 unsigned int flags = 0;
60
61 if (addr0 & 0x02000000) {
62 flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
63 flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
64 flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
65 if (addr0 & 0x40000000)
66 flags |= IORESOURCE_PREFETCH
67 | PCI_BASE_ADDRESS_MEM_PREFETCH;
68 /* Note: We don't know whether the ROM has been left enabled
69 * by the firmware or not. We mark it as disabled (ie, we do
70 * not set the IORESOURCE_ROM_ENABLE flag) for now rather than
71 * do a config space read, it will be force-enabled if needed
72 */
73 if (!bridge && (addr0 & 0xff) == 0x30)
74 flags |= IORESOURCE_READONLY;
75 } else if (addr0 & 0x01000000)
76 flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
77 if (flags)
78 flags |= IORESOURCE_SIZEALIGN;
79 return flags;
80}
81
82
83static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
84{
85 u64 base, size;
86 unsigned int flags;
87 struct resource *res;
88 const u32 *addrs;
89 u32 i;
90 int proplen;
91
92 addrs = of_get_property(node, "assigned-addresses", &proplen);
93 if (!addrs)
94 return;
95 pr_debug(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
96 for (; proplen >= 20; proplen -= 20, addrs += 5) {
97 flags = pci_parse_of_flags(addrs[0], 0);
98 if (!flags)
99 continue;
100 base = of_read_number(&addrs[1], 2);
101 size = of_read_number(&addrs[3], 2);
102 if (!size)
103 continue;
104 i = addrs[0] & 0xff;
105 pr_debug(" base: %llx, size: %llx, i: %x\n",
106 (unsigned long long)base,
107 (unsigned long long)size, i);
108
109 if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
110 res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
111 } else if (i == dev->rom_base_reg) {
112 res = &dev->resource[PCI_ROM_RESOURCE];
113 flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
114 } else {
115 printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
116 continue;
117 }
118 res->start = base;
119 res->end = base + size - 1;
120 res->flags = flags;
121 res->name = pci_name(dev);
122 }
123}
124
125struct pci_dev *of_create_pci_dev(struct device_node *node,
126 struct pci_bus *bus, int devfn)
127{
128 struct pci_dev *dev;
129 const char *type;
130
131 dev = alloc_pci_dev();
132 if (!dev)
133 return NULL;
134 type = of_get_property(node, "device_type", NULL);
135 if (type == NULL)
136 type = "";
137
138 pr_debug(" create device, devfn: %x, type: %s\n", devfn, type);
139
140 dev->bus = bus;
141 dev->sysdata = node;
142 dev->dev.parent = bus->bridge;
143 dev->dev.bus = &pci_bus_type;
144 dev->devfn = devfn;
145 dev->multifunction = 0; /* maybe a lie? */
146
147 dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
148 dev->device = get_int_prop(node, "device-id", 0xffff);
149 dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
150 dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);
151
152 dev->cfg_size = pci_cfg_space_size(dev);
153
154 dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
155 dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
156 dev->class = get_int_prop(node, "class-code", 0);
157 dev->revision = get_int_prop(node, "revision-id", 0);
158
159 pr_debug(" class: 0x%x\n", dev->class);
160 pr_debug(" revision: 0x%x\n", dev->revision);
161
162 dev->current_state = 4; /* unknown power state */
163 dev->error_state = pci_channel_io_normal;
164 dev->dma_mask = 0xffffffff;
165
166 if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
167 /* a PCI-PCI bridge */
168 dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
169 dev->rom_base_reg = PCI_ROM_ADDRESS1;
170 } else if (!strcmp(type, "cardbus")) {
171 dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
172 } else {
173 dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
174 dev->rom_base_reg = PCI_ROM_ADDRESS;
175 /* Maybe do a default OF mapping here */
176 dev->irq = NO_IRQ;
177 }
178
179 pci_parse_of_addrs(node, dev);
180
181 pr_debug(" adding to system ...\n");
182
183 pci_device_add(dev, bus);
184
185 return dev;
186}
187EXPORT_SYMBOL(of_create_pci_dev);
188
189static void __devinit __of_scan_bus(struct device_node *node,
190 struct pci_bus *bus, int rescan_existing)
191{
192 struct device_node *child;
193 const u32 *reg;
194 int reglen, devfn;
195 struct pci_dev *dev;
196
197 pr_debug("of_scan_bus(%s) bus no %d... \n",
198 node->full_name, bus->number);
199
200 /* Scan direct children */
201 for_each_child_of_node(node, child) {
202 pr_debug(" * %s\n", child->full_name);
203 reg = of_get_property(child, "reg", &reglen);
204 if (reg == NULL || reglen < 20)
205 continue;
206 devfn = (reg[0] >> 8) & 0xff;
207
208 /* create a new pci_dev for this device */
209 dev = of_create_pci_dev(child, bus, devfn);
210 if (!dev)
211 continue;
212 pr_debug(" dev header type: %x\n", dev->hdr_type);
213 }
214
215 /* Apply all fixups necessary. We don't fixup the bus "self"
216 * for an existing bridge that is being rescanned
217 */
218 if (!rescan_existing)
219 pcibios_setup_bus_self(bus);
220 pcibios_setup_bus_devices(bus);
221
222 /* Now scan child busses */
223 list_for_each_entry(dev, &bus->devices, bus_list) {
224 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
225 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
226 struct device_node *child = pci_device_to_OF_node(dev);
227 if (dev)
228 of_scan_pci_bridge(child, dev);
229 }
230 }
231}
232
233void __devinit of_scan_bus(struct device_node *node,
234 struct pci_bus *bus)
235{
236 __of_scan_bus(node, bus, 0);
237}
238EXPORT_SYMBOL_GPL(of_scan_bus);
239
240void __devinit of_rescan_bus(struct device_node *node,
241 struct pci_bus *bus)
242{
243 __of_scan_bus(node, bus, 1);
244}
245EXPORT_SYMBOL_GPL(of_rescan_bus);
246
247void __devinit of_scan_pci_bridge(struct device_node *node,
248 struct pci_dev *dev)
249{
250 struct pci_bus *bus;
251 const u32 *busrange, *ranges;
252 int len, i, mode;
253 struct resource *res;
254 unsigned int flags;
255 u64 size;
256
257 pr_debug("of_scan_pci_bridge(%s)\n", node->full_name);
258
259 /* parse bus-range property */
260 busrange = of_get_property(node, "bus-range", &len);
261 if (busrange == NULL || len != 8) {
262 printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
263 node->full_name);
264 return;
265 }
266 ranges = of_get_property(node, "ranges", &len);
267 if (ranges == NULL) {
268 printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
269 node->full_name);
270 return;
271 }
272
273 bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
274 if (!bus) {
275 printk(KERN_ERR "Failed to create pci bus for %s\n",
276 node->full_name);
277 return;
278 }
279
280 bus->primary = dev->bus->number;
281 bus->subordinate = busrange[1];
282 bus->bridge_ctl = 0;
283 bus->sysdata = node;
284
285 /* parse ranges property */
286 /* PCI #address-cells == 3 and #size-cells == 2 always */
287 res = &dev->resource[PCI_BRIDGE_RESOURCES];
288 for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) {
289 res->flags = 0;
290 bus->resource[i] = res;
291 ++res;
292 }
293 i = 1;
294 for (; len >= 32; len -= 32, ranges += 8) {
295 flags = pci_parse_of_flags(ranges[0], 1);
296 size = of_read_number(&ranges[6], 2);
297 if (flags == 0 || size == 0)
298 continue;
299 if (flags & IORESOURCE_IO) {
300 res = bus->resource[0];
301 if (res->flags) {
302 printk(KERN_ERR "PCI: ignoring extra I/O range"
303 " for bridge %s\n", node->full_name);
304 continue;
305 }
306 } else {
307 if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
308 printk(KERN_ERR "PCI: too many memory ranges"
309 " for bridge %s\n", node->full_name);
310 continue;
311 }
312 res = bus->resource[i];
313 ++i;
314 }
315 res->start = of_read_number(&ranges[1], 2);
316 res->end = res->start + size - 1;
317 res->flags = flags;
318 }
319 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
320 bus->number);
321 pr_debug(" bus name: %s\n", bus->name);
322
323 mode = PCI_PROBE_NORMAL;
324 if (ppc_md.pci_probe_mode)
325 mode = ppc_md.pci_probe_mode(bus);
326 pr_debug(" probe mode: %d\n", mode);
327
328 if (mode == PCI_PROBE_DEVTREE)
329 of_scan_bus(node, bus);
330 else if (mode == PCI_PROBE_NORMAL)
331 pci_scan_child_bus(bus);
332}
333EXPORT_SYMBOL(of_scan_pci_bridge);
334
335void __devinit scan_phb(struct pci_controller *hose) 46void __devinit scan_phb(struct pci_controller *hose)
336{ 47{
337 struct pci_bus *bus; 48 struct pci_bus *bus;
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