aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/prom_parse.c288
1 files changed, 148 insertions, 140 deletions
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 603dff3ad62a..346fb7bf9a05 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -25,6 +25,12 @@
25#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ 25#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
26 (ns) > 0) 26 (ns) > 0)
27 27
28static struct of_bus *of_match_bus(struct device_node *np);
29static int __of_address_to_resource(struct device_node *dev,
30 const u32 *addrp, u64 size, unsigned int flags,
31 struct resource *r);
32
33
28/* Debug utility */ 34/* Debug utility */
29#ifdef DEBUG 35#ifdef DEBUG
30static void of_dump_addr(const char *s, const u32 *addr, int na) 36static void of_dump_addr(const char *s, const u32 *addr, int na)
@@ -101,6 +107,7 @@ static unsigned int of_bus_default_get_flags(const u32 *addr)
101} 107}
102 108
103 109
110#ifdef CONFIG_PCI
104/* 111/*
105 * PCI bus specific translator 112 * PCI bus specific translator
106 */ 113 */
@@ -162,6 +169,145 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr)
162 return flags; 169 return flags;
163} 170}
164 171
172const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
173 unsigned int *flags)
174{
175 const u32 *prop;
176 unsigned int psize;
177 struct device_node *parent;
178 struct of_bus *bus;
179 int onesize, i, na, ns;
180
181 /* Get parent & match bus type */
182 parent = of_get_parent(dev);
183 if (parent == NULL)
184 return NULL;
185 bus = of_match_bus(parent);
186 if (strcmp(bus->name, "pci")) {
187 of_node_put(parent);
188 return NULL;
189 }
190 bus->count_cells(dev, &na, &ns);
191 of_node_put(parent);
192 if (!OF_CHECK_COUNTS(na, ns))
193 return NULL;
194
195 /* Get "reg" or "assigned-addresses" property */
196 prop = get_property(dev, bus->addresses, &psize);
197 if (prop == NULL)
198 return NULL;
199 psize /= 4;
200
201 onesize = na + ns;
202 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
203 if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
204 if (size)
205 *size = of_read_number(prop + na, ns);
206 if (flags)
207 *flags = bus->get_flags(prop);
208 return prop;
209 }
210 return NULL;
211}
212EXPORT_SYMBOL(of_get_pci_address);
213
214int of_pci_address_to_resource(struct device_node *dev, int bar,
215 struct resource *r)
216{
217 const u32 *addrp;
218 u64 size;
219 unsigned int flags;
220
221 addrp = of_get_pci_address(dev, bar, &size, &flags);
222 if (addrp == NULL)
223 return -EINVAL;
224 return __of_address_to_resource(dev, addrp, size, flags, r);
225}
226EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
227
228static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
229{
230 return (((pin - 1) + slot) % 4) + 1;
231}
232
233int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
234{
235 struct device_node *dn, *ppnode;
236 struct pci_dev *ppdev;
237 u32 lspec;
238 u32 laddr[3];
239 u8 pin;
240 int rc;
241
242 /* Check if we have a device node, if yes, fallback to standard OF
243 * parsing
244 */
245 dn = pci_device_to_OF_node(pdev);
246 if (dn)
247 return of_irq_map_one(dn, 0, out_irq);
248
249 /* Ok, we don't, time to have fun. Let's start by building up an
250 * interrupt spec. we assume #interrupt-cells is 1, which is standard
251 * for PCI. If you do different, then don't use that routine.
252 */
253 rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
254 if (rc != 0)
255 return rc;
256 /* No pin, exit */
257 if (pin == 0)
258 return -ENODEV;
259
260 /* Now we walk up the PCI tree */
261 lspec = pin;
262 for (;;) {
263 /* Get the pci_dev of our parent */
264 ppdev = pdev->bus->self;
265
266 /* Ouch, it's a host bridge... */
267 if (ppdev == NULL) {
268#ifdef CONFIG_PPC64
269 ppnode = pci_bus_to_OF_node(pdev->bus);
270#else
271 struct pci_controller *host;
272 host = pci_bus_to_host(pdev->bus);
273 ppnode = host ? host->arch_data : NULL;
274#endif
275 /* No node for host bridge ? give up */
276 if (ppnode == NULL)
277 return -EINVAL;
278 } else
279 /* We found a P2P bridge, check if it has a node */
280 ppnode = pci_device_to_OF_node(ppdev);
281
282 /* Ok, we have found a parent with a device-node, hand over to
283 * the OF parsing code.
284 * We build a unit address from the linux device to be used for
285 * resolution. Note that we use the linux bus number which may
286 * not match your firmware bus numbering.
287 * Fortunately, in most cases, interrupt-map-mask doesn't include
288 * the bus number as part of the matching.
289 * You should still be careful about that though if you intend
290 * to rely on this function (you ship a firmware that doesn't
291 * create device nodes for all PCI devices).
292 */
293 if (ppnode)
294 break;
295
296 /* We can only get here if we hit a P2P bridge with no node,
297 * let's do standard swizzling and try again
298 */
299 lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
300 pdev = ppdev;
301 }
302
303 laddr[0] = (pdev->bus->number << 16)
304 | (pdev->devfn << 8);
305 laddr[1] = laddr[2] = 0;
306 return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
307}
308EXPORT_SYMBOL_GPL(of_irq_map_pci);
309#endif /* CONFIG_PCI */
310
165/* 311/*
166 * ISA bus specific translator 312 * ISA bus specific translator
167 */ 313 */
@@ -223,6 +369,7 @@ static unsigned int of_bus_isa_get_flags(const u32 *addr)
223 */ 369 */
224 370
225static struct of_bus of_busses[] = { 371static struct of_bus of_busses[] = {
372#ifdef CONFIG_PCI
226 /* PCI */ 373 /* PCI */
227 { 374 {
228 .name = "pci", 375 .name = "pci",
@@ -233,6 +380,7 @@ static struct of_bus of_busses[] = {
233 .translate = of_bus_pci_translate, 380 .translate = of_bus_pci_translate,
234 .get_flags = of_bus_pci_get_flags, 381 .get_flags = of_bus_pci_get_flags,
235 }, 382 },
383#endif /* CONFIG_PCI */
236 /* ISA */ 384 /* ISA */
237 { 385 {
238 .name = "isa", 386 .name = "isa",
@@ -445,48 +593,6 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
445} 593}
446EXPORT_SYMBOL(of_get_address); 594EXPORT_SYMBOL(of_get_address);
447 595
448const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
449 unsigned int *flags)
450{
451 const u32 *prop;
452 unsigned int psize;
453 struct device_node *parent;
454 struct of_bus *bus;
455 int onesize, i, na, ns;
456
457 /* Get parent & match bus type */
458 parent = of_get_parent(dev);
459 if (parent == NULL)
460 return NULL;
461 bus = of_match_bus(parent);
462 if (strcmp(bus->name, "pci")) {
463 of_node_put(parent);
464 return NULL;
465 }
466 bus->count_cells(dev, &na, &ns);
467 of_node_put(parent);
468 if (!OF_CHECK_COUNTS(na, ns))
469 return NULL;
470
471 /* Get "reg" or "assigned-addresses" property */
472 prop = get_property(dev, bus->addresses, &psize);
473 if (prop == NULL)
474 return NULL;
475 psize /= 4;
476
477 onesize = na + ns;
478 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
479 if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
480 if (size)
481 *size = of_read_number(prop + na, ns);
482 if (flags)
483 *flags = bus->get_flags(prop);
484 return prop;
485 }
486 return NULL;
487}
488EXPORT_SYMBOL(of_get_pci_address);
489
490static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, 596static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
491 u64 size, unsigned int flags, 597 u64 size, unsigned int flags,
492 struct resource *r) 598 struct resource *r)
@@ -529,20 +635,6 @@ int of_address_to_resource(struct device_node *dev, int index,
529} 635}
530EXPORT_SYMBOL_GPL(of_address_to_resource); 636EXPORT_SYMBOL_GPL(of_address_to_resource);
531 637
532int of_pci_address_to_resource(struct device_node *dev, int bar,
533 struct resource *r)
534{
535 const u32 *addrp;
536 u64 size;
537 unsigned int flags;
538
539 addrp = of_get_pci_address(dev, bar, &size, &flags);
540 if (addrp == NULL)
541 return -EINVAL;
542 return __of_address_to_resource(dev, addrp, size, flags, r);
543}
544EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
545
546void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, 638void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
547 unsigned long *busno, unsigned long *phys, unsigned long *size) 639 unsigned long *busno, unsigned long *phys, unsigned long *size)
548{ 640{
@@ -898,87 +990,3 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
898 return res; 990 return res;
899} 991}
900EXPORT_SYMBOL_GPL(of_irq_map_one); 992EXPORT_SYMBOL_GPL(of_irq_map_one);
901
902#ifdef CONFIG_PCI
903static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
904{
905 return (((pin - 1) + slot) % 4) + 1;
906}
907
908int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
909{
910 struct device_node *dn, *ppnode;
911 struct pci_dev *ppdev;
912 u32 lspec;
913 u32 laddr[3];
914 u8 pin;
915 int rc;
916
917 /* Check if we have a device node, if yes, fallback to standard OF
918 * parsing
919 */
920 dn = pci_device_to_OF_node(pdev);
921 if (dn)
922 return of_irq_map_one(dn, 0, out_irq);
923
924 /* Ok, we don't, time to have fun. Let's start by building up an
925 * interrupt spec. we assume #interrupt-cells is 1, which is standard
926 * for PCI. If you do different, then don't use that routine.
927 */
928 rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
929 if (rc != 0)
930 return rc;
931 /* No pin, exit */
932 if (pin == 0)
933 return -ENODEV;
934
935 /* Now we walk up the PCI tree */
936 lspec = pin;
937 for (;;) {
938 /* Get the pci_dev of our parent */
939 ppdev = pdev->bus->self;
940
941 /* Ouch, it's a host bridge... */
942 if (ppdev == NULL) {
943#ifdef CONFIG_PPC64
944 ppnode = pci_bus_to_OF_node(pdev->bus);
945#else
946 struct pci_controller *host;
947 host = pci_bus_to_host(pdev->bus);
948 ppnode = host ? host->arch_data : NULL;
949#endif
950 /* No node for host bridge ? give up */
951 if (ppnode == NULL)
952 return -EINVAL;
953 } else
954 /* We found a P2P bridge, check if it has a node */
955 ppnode = pci_device_to_OF_node(ppdev);
956
957 /* Ok, we have found a parent with a device-node, hand over to
958 * the OF parsing code.
959 * We build a unit address from the linux device to be used for
960 * resolution. Note that we use the linux bus number which may
961 * not match your firmware bus numbering.
962 * Fortunately, in most cases, interrupt-map-mask doesn't include
963 * the bus number as part of the matching.
964 * You should still be careful about that though if you intend
965 * to rely on this function (you ship a firmware that doesn't
966 * create device nodes for all PCI devices).
967 */
968 if (ppnode)
969 break;
970
971 /* We can only get here if we hit a P2P bridge with no node,
972 * let's do standard swizzling and try again
973 */
974 lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
975 pdev = ppdev;
976 }
977
978 laddr[0] = (pdev->bus->number << 16)
979 | (pdev->devfn << 8);
980 laddr[1] = laddr[2] = 0;
981 return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
982}
983EXPORT_SYMBOL_GPL(of_irq_map_pci);
984#endif /* CONFIG_PCI */