3 #include <linux/kernel.h>
4 #include <linux/string.h>
5 #include <linux/pci_regs.h>
6 #include <linux/module.h>
7 #include <linux/ioport.h>
8 #include <linux/etherdevice.h>
9 #include <linux/of_address.h>
11 #include <asm/pci-bridge.h>
14 int of_irq_map_pci(struct pci_dev
*pdev
, struct of_irq
*out_irq
)
16 struct device_node
*dn
, *ppnode
;
17 struct pci_dev
*ppdev
;
23 /* Check if we have a device node, if yes, fallback to standard OF
26 dn
= pci_device_to_OF_node(pdev
);
28 rc
= of_irq_map_one(dn
, 0, out_irq
);
33 /* Ok, we don't, time to have fun. Let's start by building up an
34 * interrupt spec. we assume #interrupt-cells is 1, which is standard
35 * for PCI. If you do different, then don't use that routine.
37 rc
= pci_read_config_byte(pdev
, PCI_INTERRUPT_PIN
, &pin
);
44 /* Now we walk up the PCI tree */
47 /* Get the pci_dev of our parent */
48 ppdev
= pdev
->bus
->self
;
50 /* Ouch, it's a host bridge... */
53 ppnode
= pci_bus_to_OF_node(pdev
->bus
);
55 struct pci_controller
*host
;
56 host
= pci_bus_to_host(pdev
->bus
);
57 ppnode
= host
? host
->dn
: NULL
;
59 /* No node for host bridge ? give up */
63 /* We found a P2P bridge, check if it has a node */
64 ppnode
= pci_device_to_OF_node(ppdev
);
66 /* Ok, we have found a parent with a device-node, hand over to
67 * the OF parsing code.
68 * We build a unit address from the linux device to be used for
69 * resolution. Note that we use the linux bus number which may
70 * not match your firmware bus numbering.
71 * Fortunately, in most cases, interrupt-map-mask doesn't include
72 * the bus number as part of the matching.
73 * You should still be careful about that though if you intend
74 * to rely on this function (you ship a firmware that doesn't
75 * create device nodes for all PCI devices).
80 /* We can only get here if we hit a P2P bridge with no node,
81 * let's do standard swizzling and try again
83 lspec
= pci_swizzle_interrupt_pin(pdev
, lspec
);
87 laddr
[0] = (pdev
->bus
->number
<< 16)
89 laddr
[1] = laddr
[2] = 0;
90 return of_irq_map_raw(ppnode
, &lspec
, 1, laddr
, out_irq
);
92 EXPORT_SYMBOL_GPL(of_irq_map_pci
);
93 #endif /* CONFIG_PCI */
95 void of_parse_dma_window(struct device_node
*dn
, const void *dma_window_prop
,
96 unsigned long *busno
, unsigned long *phys
, unsigned long *size
)
98 const u32
*dma_window
;
100 const unsigned char *prop
;
102 dma_window
= dma_window_prop
;
104 /* busno is always one cell */
105 *busno
= *(dma_window
++);
107 prop
= of_get_property(dn
, "ibm,#dma-address-cells", NULL
);
109 prop
= of_get_property(dn
, "#address-cells", NULL
);
111 cells
= prop
? *(u32
*)prop
: of_n_addr_cells(dn
);
112 *phys
= of_read_number(dma_window
, cells
);
116 prop
= of_get_property(dn
, "ibm,#dma-size-cells", NULL
);
117 cells
= prop
? *(u32
*)prop
: of_n_size_cells(dn
);
118 *size
= of_read_number(dma_window
, cells
);
122 * Search the device tree for the best MAC address to use. 'mac-address' is
123 * checked first, because that is supposed to contain to "most recent" MAC
124 * address. If that isn't set, then 'local-mac-address' is checked next,
125 * because that is the default address. If that isn't set, then the obsolete
126 * 'address' is checked, just in case we're using an old device tree.
128 * Note that the 'address' property is supposed to contain a virtual address of
129 * the register set, but some DTS files have redefined that property to be the
132 * All-zero MAC addresses are rejected, because those could be properties that
133 * exist in the device tree, but were not set by U-Boot. For example, the
134 * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
135 * addresses. Some older U-Boots only initialized 'local-mac-address'. In
136 * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
139 const void *of_get_mac_address(struct device_node
*np
)
143 pp
= of_find_property(np
, "mac-address", NULL
);
144 if (pp
&& (pp
->length
== 6) && is_valid_ether_addr(pp
->value
))
147 pp
= of_find_property(np
, "local-mac-address", NULL
);
148 if (pp
&& (pp
->length
== 6) && is_valid_ether_addr(pp
->value
))
151 pp
= of_find_property(np
, "address", NULL
);
152 if (pp
&& (pp
->length
== 6) && is_valid_ether_addr(pp
->value
))
157 EXPORT_SYMBOL(of_get_mac_address
);
This page took 0.0338 seconds and 6 git commands to generate.