aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-04-10 21:37:07 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-06-07 19:08:17 -0400
commit98d9f30c820d509145757e6ecbc36013aa02f7bc (patch)
treedd5da915d991352ced56ed849612029339f64198 /arch/powerpc
parent1fa7b6a29c61358cc2ca6f64cef4aa0e1a7ca74c (diff)
pci/of: Match PCI devices to OF nodes dynamically
powerpc has two different ways of matching PCI devices to their corresponding OF node (if any) for historical reasons. The ppc64 one does a scan looking for matching bus/dev/fn, while the ppc32 one does a scan looking only for matching dev/fn on each level in order to be agnostic to busses being renumbered (which Linux does on some platforms). This removes both and instead moves the matching code to the PCI core itself. It's the most logical place to do it: when a pci_dev is created, we know the parent and thus can do a single level scan for the matching device_node (if any). The benefit is that all archs now get the matching for free. There's one hook the arch might want to provide to match a PHB bus to its device node. A default weak implementation is provided that looks for the parent device device node, but it's not entirely reliable on powerpc for various reasons so powerpc provides its own. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Michal Simek <monstr@monstr.eu> Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h35
-rw-r--r--arch/powerpc/include/asm/pci.h3
-rw-r--r--arch/powerpc/include/asm/prom.h14
-rw-r--r--arch/powerpc/kernel/pci-common.c11
-rw-r--r--arch/powerpc/kernel/pci_32.c150
-rw-r--r--arch/powerpc/kernel/pci_dn.c47
-rw-r--r--arch/powerpc/kernel/pci_of_scan.c9
-rw-r--r--arch/powerpc/platforms/powermac/pci.c3
8 files changed, 37 insertions, 235 deletions
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index b90dbf8e5cd..3e6869476e5 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -169,18 +169,22 @@ static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
169 return bus->sysdata; 169 return bus->sysdata;
170} 170}
171 171
172#ifndef CONFIG_PPC64 172static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
173{
174 return dev->dev.of_node;
175}
173 176
174static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) 177static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
175{ 178{
176 struct pci_controller *host; 179 return bus->dev.of_node;
177
178 if (bus->self)
179 return pci_device_to_OF_node(bus->self);
180 host = pci_bus_to_host(bus);
181 return host ? host->dn : NULL;
182} 180}
183 181
182#ifndef CONFIG_PPC64
183
184extern int pci_device_from_OF_node(struct device_node *node,
185 u8 *bus, u8 *devfn);
186extern void pci_create_OF_bus_map(void);
187
184static inline int isa_vaddr_is_ioport(void __iomem *address) 188static inline int isa_vaddr_is_ioport(void __iomem *address)
185{ 189{
186 /* No specific ISA handling on ppc32 at this stage, it 190 /* No specific ISA handling on ppc32 at this stage, it
@@ -223,17 +227,8 @@ struct pci_dn {
223/* Get the pointer to a device_node's pci_dn */ 227/* Get the pointer to a device_node's pci_dn */
224#define PCI_DN(dn) ((struct pci_dn *) (dn)->data) 228#define PCI_DN(dn) ((struct pci_dn *) (dn)->data)
225 229
226extern struct device_node *fetch_dev_dn(struct pci_dev *dev);
227extern void * update_dn_pci_info(struct device_node *dn, void *data); 230extern void * update_dn_pci_info(struct device_node *dn, void *data);
228 231
229/* Get a device_node from a pci_dev. This code must be fast except
230 * in the case where the sysdata is incorrect and needs to be fixed
231 * up (this will only happen once). */
232static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
233{
234 return dev->dev.of_node ? dev->dev.of_node : fetch_dev_dn(dev);
235}
236
237static inline int pci_device_from_OF_node(struct device_node *np, 232static inline int pci_device_from_OF_node(struct device_node *np,
238 u8 *bus, u8 *devfn) 233 u8 *bus, u8 *devfn)
239{ 234{
@@ -244,14 +239,6 @@ static inline int pci_device_from_OF_node(struct device_node *np,
244 return 0; 239 return 0;
245} 240}
246 241
247static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
248{
249 if (bus->self)
250 return pci_device_to_OF_node(bus->self);
251 else
252 return bus->dev.of_node; /* Must be root bus (PHB) */
253}
254
255/** Find the bus corresponding to the indicated device node */ 242/** Find the bus corresponding to the indicated device node */
256extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn); 243extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn);
257 244
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 7d7790954e0..1f522680ea1 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -179,8 +179,7 @@ extern int remove_phb_dynamic(struct pci_controller *phb);
179extern struct pci_dev *of_create_pci_dev(struct device_node *node, 179extern struct pci_dev *of_create_pci_dev(struct device_node *node,
180 struct pci_bus *bus, int devfn); 180 struct pci_bus *bus, int devfn);
181 181
182extern void of_scan_pci_bridge(struct device_node *node, 182extern void of_scan_pci_bridge(struct pci_dev *dev);
183 struct pci_dev *dev);
184 183
185extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); 184extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
186extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus); 185extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus);
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index c189aa5fe1f..b823536375d 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -22,20 +22,6 @@
22 22
23#define HAVE_ARCH_DEVTREE_FIXUPS 23#define HAVE_ARCH_DEVTREE_FIXUPS
24 24
25#ifdef CONFIG_PPC32
26/*
27 * PCI <-> OF matching functions
28 * (XXX should these be here?)
29 */
30struct pci_bus;
31struct pci_dev;
32extern int pci_device_from_OF_node(struct device_node *node,
33 u8* bus, u8* devfn);
34extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int);
35extern struct device_node* pci_device_to_OF_node(struct pci_dev *);
36extern void pci_create_OF_bus_map(void);
37#endif
38
39/* 25/*
40 * OF address retreival & translation 26 * OF address retreival & translation
41 */ 27 */
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 893af2a9cd0..a3c92770e42 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1097,9 +1097,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
1097 if (dev->is_added) 1097 if (dev->is_added)
1098 continue; 1098 continue;
1099 1099
1100 /* Setup OF node pointer in the device */
1101 dev->dev.of_node = pci_device_to_OF_node(dev);
1102
1103 /* Fixup NUMA node as it may not be setup yet by the generic 1100 /* Fixup NUMA node as it may not be setup yet by the generic
1104 * code and is needed by the DMA init 1101 * code and is needed by the DMA init
1105 */ 1102 */
@@ -1685,6 +1682,13 @@ int early_find_capability(struct pci_controller *hose, int bus, int devfn,
1685 return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap); 1682 return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);
1686} 1683}
1687 1684
1685struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
1686{
1687 struct pci_controller *hose = bus->sysdata;
1688
1689 return of_node_get(hose->dn);
1690}
1691
1688/** 1692/**
1689 * pci_scan_phb - Given a pci_controller, setup and scan the PCI bus 1693 * pci_scan_phb - Given a pci_controller, setup and scan the PCI bus
1690 * @hose: Pointer to the PCI host controller instance structure 1694 * @hose: Pointer to the PCI host controller instance structure
@@ -1705,7 +1709,6 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
1705 hose->global_number); 1709 hose->global_number);
1706 return; 1710 return;
1707 } 1711 }
1708 bus->dev.of_node = of_node_get(node);
1709 bus->secondary = hose->first_busno; 1712 bus->secondary = hose->first_busno;
1710 hose->bus = bus; 1713 hose->bus = bus;
1711 1714
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index bedb370459f..86585508e9c 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -167,150 +167,26 @@ pcibios_make_OF_bus_map(void)
167#endif 167#endif
168} 168}
169 169
170typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);
171
172static struct device_node*
173scan_OF_pci_childs(struct device_node *parent, pci_OF_scan_iterator filter, void* data)
174{
175 struct device_node *node;
176 struct device_node* sub_node;
177
178 for_each_child_of_node(parent, node) {
179 const unsigned int *class_code;
180
181 if (filter(node, data)) {
182 of_node_put(node);
183 return node;
184 }
185
186 /* For PCI<->PCI bridges or CardBus bridges, we go down
187 * Note: some OFs create a parent node "multifunc-device" as
188 * a fake root for all functions of a multi-function device,
189 * we go down them as well.
190 */
191 class_code = of_get_property(node, "class-code", NULL);
192 if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
193 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
194 strcmp(node->name, "multifunc-device"))
195 continue;
196 sub_node = scan_OF_pci_childs(node, filter, data);
197 if (sub_node) {
198 of_node_put(node);
199 return sub_node;
200 }
201 }
202 return NULL;
203}
204
205static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
206 unsigned int devfn)
207{
208 struct device_node *np, *cnp;
209 const u32 *reg;
210 unsigned int psize;
211
212 for_each_child_of_node(parent, np) {
213 reg = of_get_property(np, "reg", &psize);
214 if (reg && psize >= 4 && ((reg[0] >> 8) & 0xff) == devfn)
215 return np;
216
217 /* Note: some OFs create a parent node "multifunc-device" as
218 * a fake root for all functions of a multi-function device,
219 * we go down them as well. */
220 if (!strcmp(np->name, "multifunc-device")) {
221 cnp = scan_OF_for_pci_dev(np, devfn);
222 if (cnp)
223 return cnp;
224 }
225 }
226 return NULL;
227}
228
229
230static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus)
231{
232 struct device_node *parent, *np;
233
234 /* Are we a root bus ? */
235 if (bus->self == NULL || bus->parent == NULL) {
236 struct pci_controller *hose = pci_bus_to_host(bus);
237 if (hose == NULL)
238 return NULL;
239 return of_node_get(hose->dn);
240 }
241
242 /* not a root bus, we need to get our parent */
243 parent = scan_OF_for_pci_bus(bus->parent);
244 if (parent == NULL)
245 return NULL;
246
247 /* now iterate for children for a match */
248 np = scan_OF_for_pci_dev(parent, bus->self->devfn);
249 of_node_put(parent);
250
251 return np;
252}
253
254/*
255 * Scans the OF tree for a device node matching a PCI device
256 */
257struct device_node *
258pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
259{
260 struct device_node *parent, *np;
261
262 pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
263 parent = scan_OF_for_pci_bus(bus);
264 if (parent == NULL)
265 return NULL;
266 pr_debug(" parent is %s\n", parent ? parent->full_name : "<NULL>");
267 np = scan_OF_for_pci_dev(parent, devfn);
268 of_node_put(parent);
269 pr_debug(" result is %s\n", np ? np->full_name : "<NULL>");
270
271 /* XXX most callers don't release the returned node
272 * mostly because ppc64 doesn't increase the refcount,
273 * we need to fix that.
274 */
275 return np;
276}
277EXPORT_SYMBOL(pci_busdev_to_OF_node);
278
279struct device_node*
280pci_device_to_OF_node(struct pci_dev *dev)
281{
282 return pci_busdev_to_OF_node(dev->bus, dev->devfn);
283}
284EXPORT_SYMBOL(pci_device_to_OF_node);
285
286static int
287find_OF_pci_device_filter(struct device_node* node, void* data)
288{
289 return ((void *)node == data);
290}
291 170
292/* 171/*
293 * Returns the PCI device matching a given OF node 172 * Returns the PCI device matching a given OF node
294 */ 173 */
295int 174int pci_device_from_OF_node(struct device_node *node, u8 *bus, u8 *devfn)
296pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
297{ 175{
298 const unsigned int *reg; 176 struct pci_dev *dev = NULL;
299 struct pci_controller* hose; 177 const __be32 *reg;
300 struct pci_dev* dev = NULL; 178 int size;
301 179
302 /* Make sure it's really a PCI device */ 180 /* Check if it might have a chance to be a PCI device */
303 hose = pci_find_hose_for_OF_device(node); 181 if (!pci_find_hose_for_OF_device(node))
304 if (!hose || !hose->dn)
305 return -ENODEV;
306 if (!scan_OF_pci_childs(hose->dn,
307 find_OF_pci_device_filter, (void *)node))
308 return -ENODEV; 182 return -ENODEV;
309 reg = of_get_property(node, "reg", NULL); 183
310 if (!reg) 184 reg = of_get_property(node, "reg", &size);
185 if (!reg || size < 5 * sizeof(u32))
311 return -ENODEV; 186 return -ENODEV;
312 *bus = (reg[0] >> 16) & 0xff; 187
313 *devfn = ((reg[0] >> 8) & 0xff); 188 *bus = (be32_to_cpup(&reg[0]) >> 16) & 0xff;
189 *devfn = (be32_to_cpup(&reg[0]) >> 8) & 0xff;
314 190
315 /* Ok, here we need some tweak. If we have already renumbered 191 /* Ok, here we need some tweak. If we have already renumbered
316 * all busses, we can't rely on the OF bus number any more. 192 * all busses, we can't rely on the OF bus number any more.
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index 6baabc13306..478f8d78716 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -142,53 +142,6 @@ void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
142 traverse_pci_devices(dn, update_dn_pci_info, phb); 142 traverse_pci_devices(dn, update_dn_pci_info, phb);
143} 143}
144 144
145/*
146 * Traversal func that looks for a <busno,devfcn> value.
147 * If found, the pci_dn is returned (thus terminating the traversal).
148 */
149static void *is_devfn_node(struct device_node *dn, void *data)
150{
151 int busno = ((unsigned long)data >> 8) & 0xff;
152 int devfn = ((unsigned long)data) & 0xff;
153 struct pci_dn *pci = dn->data;
154
155 if (pci && (devfn == pci->devfn) && (busno == pci->busno))
156 return dn;
157 return NULL;
158}
159
160/*
161 * This is the "slow" path for looking up a device_node from a
162 * pci_dev. It will hunt for the device under its parent's
163 * phb and then update of_node pointer.
164 *
165 * It may also do fixups on the actual device since this happens
166 * on the first read/write.
167 *
168 * Note that it also must deal with devices that don't exist.
169 * In this case it may probe for real hardware ("just in case")
170 * and add a device_node to the device tree if necessary.
171 *
172 * Is this function necessary anymore now that dev->dev.of_node is
173 * used to store the node pointer?
174 *
175 */
176struct device_node *fetch_dev_dn(struct pci_dev *dev)
177{
178 struct pci_controller *phb = dev->sysdata;
179 struct device_node *dn;
180 unsigned long searchval = (dev->bus->number << 8) | dev->devfn;
181
182 if (WARN_ON(!phb))
183 return NULL;
184
185 dn = traverse_pci_devices(phb->dn, is_devfn_node, (void *)searchval);
186 if (dn)
187 dev->dev.of_node = dn;
188 return dn;
189}
190EXPORT_SYMBOL(fetch_dev_dn);
191
192/** 145/**
193 * pci_devs_phb_init - Initialize phbs and pci devs under them. 146 * pci_devs_phb_init - Initialize phbs and pci devs under them.
194 * 147 *
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 1e89a72fd03..fe0a5ad6f73 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -202,9 +202,9 @@ EXPORT_SYMBOL(of_create_pci_dev);
202 * this routine in turn call of_scan_bus() recusively to scan for more child 202 * this routine in turn call of_scan_bus() recusively to scan for more child
203 * devices. 203 * devices.
204 */ 204 */
205void __devinit of_scan_pci_bridge(struct device_node *node, 205void __devinit of_scan_pci_bridge(struct pci_dev *dev)
206 struct pci_dev *dev)
207{ 206{
207 struct device_node *node = dev->dev.of_node;
208 struct pci_bus *bus; 208 struct pci_bus *bus;
209 const u32 *busrange, *ranges; 209 const u32 *busrange, *ranges;
210 int len, i, mode; 210 int len, i, mode;
@@ -238,7 +238,6 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
238 bus->primary = dev->bus->number; 238 bus->primary = dev->bus->number;
239 bus->subordinate = busrange[1]; 239 bus->subordinate = busrange[1];
240 bus->bridge_ctl = 0; 240 bus->bridge_ctl = 0;
241 bus->dev.of_node = of_node_get(node);
242 241
243 /* parse ranges property */ 242 /* parse ranges property */
244 /* PCI #address-cells == 3 and #size-cells == 2 always */ 243 /* PCI #address-cells == 3 and #size-cells == 2 always */
@@ -335,9 +334,7 @@ static void __devinit __of_scan_bus(struct device_node *node,
335 list_for_each_entry(dev, &bus->devices, bus_list) { 334 list_for_each_entry(dev, &bus->devices, bus_list) {
336 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 335 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
337 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { 336 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
338 struct device_node *child = pci_device_to_OF_node(dev); 337 of_scan_pci_bridge(dev);
339 if (child)
340 of_scan_pci_bridge(child, dev);
341 } 338 }
342 } 339 }
343} 340}
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index f33e08d573c..abe8d7e2ebe 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -17,6 +17,7 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/bootmem.h> 18#include <linux/bootmem.h>
19#include <linux/irq.h> 19#include <linux/irq.h>
20#include <linux/of_pci.h>
20 21
21#include <asm/sections.h> 22#include <asm/sections.h>
22#include <asm/io.h> 23#include <asm/io.h>
@@ -235,7 +236,7 @@ static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
235 236
236 if (offset >= 0x100) 237 if (offset >= 0x100)
237 return PCIBIOS_BAD_REGISTER_NUMBER; 238 return PCIBIOS_BAD_REGISTER_NUMBER;
238 np = pci_busdev_to_OF_node(bus, devfn); 239 np = of_pci_find_child_device(bus->dev.of_node, devfn);
239 if (np == NULL) 240 if (np == NULL)
240 return PCIBIOS_DEVICE_NOT_FOUND; 241 return PCIBIOS_DEVICE_NOT_FOUND;
241 242