aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom_parse.c
diff options
context:
space:
mode:
authorDave Jones <davej@redhat.com>2006-12-12 17:41:41 -0500
committerDave Jones <davej@redhat.com>2006-12-12 17:41:41 -0500
commitc4366889dda8110247be59ca41fddb82951a8c26 (patch)
tree705c1a996bed8fd48ce94ff33ec9fd00f9b94875 /arch/powerpc/kernel/prom_parse.c
parentdb2fb9db5735cc532fd4fc55e94b9a3c3750378e (diff)
parente1036502e5263851259d147771226161e5ccc85a (diff)
Merge ../linus
Conflicts: drivers/cpufreq/cpufreq.c
Diffstat (limited to 'arch/powerpc/kernel/prom_parse.c')
-rw-r--r--arch/powerpc/kernel/prom_parse.c290
1 files changed, 150 insertions, 140 deletions
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 603dff3ad62a..0dfbe1cd28eb 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 */
@@ -153,15 +160,156 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr)
153 switch((w >> 24) & 0x03) { 160 switch((w >> 24) & 0x03) {
154 case 0x01: 161 case 0x01:
155 flags |= IORESOURCE_IO; 162 flags |= IORESOURCE_IO;
163 break;
156 case 0x02: /* 32 bits */ 164 case 0x02: /* 32 bits */
157 case 0x03: /* 64 bits */ 165 case 0x03: /* 64 bits */
158 flags |= IORESOURCE_MEM; 166 flags |= IORESOURCE_MEM;
167 break;
159 } 168 }
160 if (w & 0x40000000) 169 if (w & 0x40000000)
161 flags |= IORESOURCE_PREFETCH; 170 flags |= IORESOURCE_PREFETCH;
162 return flags; 171 return flags;
163} 172}
164 173
174const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
175 unsigned int *flags)
176{
177 const u32 *prop;
178 unsigned int psize;
179 struct device_node *parent;
180 struct of_bus *bus;
181 int onesize, i, na, ns;
182
183 /* Get parent & match bus type */
184 parent = of_get_parent(dev);
185 if (parent == NULL)
186 return NULL;
187 bus = of_match_bus(parent);
188 if (strcmp(bus->name, "pci")) {
189 of_node_put(parent);
190 return NULL;
191 }
192 bus->count_cells(dev, &na, &ns);
193 of_node_put(parent);
194 if (!OF_CHECK_COUNTS(na, ns))
195 return NULL;
196
197 /* Get "reg" or "assigned-addresses" property */
198 prop = get_property(dev, bus->addresses, &psize);
199 if (prop == NULL)
200 return NULL;
201 psize /= 4;
202
203 onesize = na + ns;
204 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
205 if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
206 if (size)
207 *size = of_read_number(prop + na, ns);
208 if (flags)
209 *flags = bus->get_flags(prop);
210 return prop;
211 }
212 return NULL;
213}
214EXPORT_SYMBOL(of_get_pci_address);
215
216int of_pci_address_to_resource(struct device_node *dev, int bar,
217 struct resource *r)
218{
219 const u32 *addrp;
220 u64 size;
221 unsigned int flags;
222
223 addrp = of_get_pci_address(dev, bar, &size, &flags);
224 if (addrp == NULL)
225 return -EINVAL;
226 return __of_address_to_resource(dev, addrp, size, flags, r);
227}
228EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
229
230static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
231{
232 return (((pin - 1) + slot) % 4) + 1;
233}
234
235int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
236{
237 struct device_node *dn, *ppnode;
238 struct pci_dev *ppdev;
239 u32 lspec;
240 u32 laddr[3];
241 u8 pin;
242 int rc;
243
244 /* Check if we have a device node, if yes, fallback to standard OF
245 * parsing
246 */
247 dn = pci_device_to_OF_node(pdev);
248 if (dn)
249 return of_irq_map_one(dn, 0, out_irq);
250
251 /* Ok, we don't, time to have fun. Let's start by building up an
252 * interrupt spec. we assume #interrupt-cells is 1, which is standard
253 * for PCI. If you do different, then don't use that routine.
254 */
255 rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
256 if (rc != 0)
257 return rc;
258 /* No pin, exit */
259 if (pin == 0)
260 return -ENODEV;
261
262 /* Now we walk up the PCI tree */
263 lspec = pin;
264 for (;;) {
265 /* Get the pci_dev of our parent */
266 ppdev = pdev->bus->self;
267
268 /* Ouch, it's a host bridge... */
269 if (ppdev == NULL) {
270#ifdef CONFIG_PPC64
271 ppnode = pci_bus_to_OF_node(pdev->bus);
272#else
273 struct pci_controller *host;
274 host = pci_bus_to_host(pdev->bus);
275 ppnode = host ? host->arch_data : NULL;
276#endif
277 /* No node for host bridge ? give up */
278 if (ppnode == NULL)
279 return -EINVAL;
280 } else
281 /* We found a P2P bridge, check if it has a node */
282 ppnode = pci_device_to_OF_node(ppdev);
283
284 /* Ok, we have found a parent with a device-node, hand over to
285 * the OF parsing code.
286 * We build a unit address from the linux device to be used for
287 * resolution. Note that we use the linux bus number which may
288 * not match your firmware bus numbering.
289 * Fortunately, in most cases, interrupt-map-mask doesn't include
290 * the bus number as part of the matching.
291 * You should still be careful about that though if you intend
292 * to rely on this function (you ship a firmware that doesn't
293 * create device nodes for all PCI devices).
294 */
295 if (ppnode)
296 break;
297
298 /* We can only get here if we hit a P2P bridge with no node,
299 * let's do standard swizzling and try again
300 */
301 lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
302 pdev = ppdev;
303 }
304
305 laddr[0] = (pdev->bus->number << 16)
306 | (pdev->devfn << 8);
307 laddr[1] = laddr[2] = 0;
308 return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
309}
310EXPORT_SYMBOL_GPL(of_irq_map_pci);
311#endif /* CONFIG_PCI */
312
165/* 313/*
166 * ISA bus specific translator 314 * ISA bus specific translator
167 */ 315 */
@@ -223,6 +371,7 @@ static unsigned int of_bus_isa_get_flags(const u32 *addr)
223 */ 371 */
224 372
225static struct of_bus of_busses[] = { 373static struct of_bus of_busses[] = {
374#ifdef CONFIG_PCI
226 /* PCI */ 375 /* PCI */
227 { 376 {
228 .name = "pci", 377 .name = "pci",
@@ -233,6 +382,7 @@ static struct of_bus of_busses[] = {
233 .translate = of_bus_pci_translate, 382 .translate = of_bus_pci_translate,
234 .get_flags = of_bus_pci_get_flags, 383 .get_flags = of_bus_pci_get_flags,
235 }, 384 },
385#endif /* CONFIG_PCI */
236 /* ISA */ 386 /* ISA */
237 { 387 {
238 .name = "isa", 388 .name = "isa",
@@ -445,48 +595,6 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
445} 595}
446EXPORT_SYMBOL(of_get_address); 596EXPORT_SYMBOL(of_get_address);
447 597
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, 598static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
491 u64 size, unsigned int flags, 599 u64 size, unsigned int flags,
492 struct resource *r) 600 struct resource *r)
@@ -529,20 +637,6 @@ int of_address_to_resource(struct device_node *dev, int index,
529} 637}
530EXPORT_SYMBOL_GPL(of_address_to_resource); 638EXPORT_SYMBOL_GPL(of_address_to_resource);
531 639
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, 640void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
547 unsigned long *busno, unsigned long *phys, unsigned long *size) 641 unsigned long *busno, unsigned long *phys, unsigned long *size)
548{ 642{
@@ -898,87 +992,3 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
898 return res; 992 return res;
899} 993}
900EXPORT_SYMBOL_GPL(of_irq_map_one); 994EXPORT_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 */