2 * BK Id: SCCS/s.prom.c 1.75 01/07/03 22:00:10 paulus
5 * Procedures for interfacing to the Open Firmware PROM on
6 * Power Macintosh computers.
8 * In particular, we are interested in the device tree
9 * and in using some of its services (exit, write to stdout).
11 * Paul Mackerras August 1996.
12 * Copyright (C) 1996 Paul Mackerras.
14 #include <linux/config.h>
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <linux/init.h>
18 #include <linux/version.h>
19 #include <linux/threads.h>
20 #include <linux/spinlock.h>
21 #include <linux/pci.h>
22 #include <linux/slab.h>
24 #include <asm/sections.h>
27 #include <asm/processor.h>
29 #include <asm/open_pic.h>
30 #include <asm/system.h>
31 #include <asm/btext.h>
32 #include <asm/pci-bridge.h>
40 struct pci_reg_property {
41 struct pci_address addr;
46 struct isa_reg_property {
52 typedef unsigned long interpret_func(struct device_node *, unsigned long,
54 static interpret_func interpret_pci_props;
55 static interpret_func interpret_dbdma_props;
56 static interpret_func interpret_isa_props;
57 static interpret_func interpret_macio_props;
58 static interpret_func interpret_root_props;
62 /* Set for a newworld or CHRP machine */
63 int use_of_interrupt_tree;
64 struct device_node *dflt_interrupt_controller;
65 int num_interrupt_controllers;
69 extern unsigned int rtas_entry; /* physical pointer */
71 extern struct device_node *allnodes;
73 static unsigned long finish_node(struct device_node *, unsigned long,
74 interpret_func *, int, int);
75 static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
77 extern void enter_rtas(void *);
78 void phys_call_rtas(int, int, int, ...);
80 extern char cmd_line[512]; /* XXX */
81 extern boot_infos_t *boot_infos;
82 unsigned long dev_tree_size;
85 phys_call_rtas(int service, int nargs, int nret, ...)
89 unsigned long words[16];
92 void (*rtas)(void *, unsigned long);
99 for (i = 0; i < nargs; ++i)
100 u.words[i+3] = va_arg(list, unsigned long);
103 rtas = (void (*)(void *, unsigned long)) rtas_entry;
108 * finish_device_tree is called once things are running normally
109 * (i.e. with text and data mapped to the address they were linked at).
110 * It traverses the device tree and fills in the name, type,
111 * {n_}addrs and {n_}intrs fields of each node.
114 finish_device_tree(void)
116 unsigned long mem = (unsigned long) klimit;
117 struct device_node *np;
119 /* All newworld pmac machines and CHRPs now use the interrupt tree */
120 for (np = allnodes; np != NULL; np = np->allnext) {
121 if (get_property(np, "interrupt-parent", 0)) {
122 use_of_interrupt_tree = 1;
126 if (_machine == _MACH_Pmac && use_of_interrupt_tree)
129 #ifdef CONFIG_BOOTX_TEXT
130 if (boot_infos && pmac_newworld) {
131 prom_print("WARNING ! BootX/miBoot booting is not supported on this machine\n");
132 prom_print(" You should use an Open Firmware bootloader\n");
134 #endif /* CONFIG_BOOTX_TEXT */
136 if (use_of_interrupt_tree) {
138 * We want to find out here how many interrupt-controller
139 * nodes there are, and if we are booted from BootX,
140 * we need a pointer to the first (and hopefully only)
141 * such node. But we can't use find_devices here since
142 * np->name has not been set yet. -- paulus
148 for (np = allnodes; np != NULL; np = np->allnext) {
149 ic = get_property(np, "interrupt-controller", &iclen);
150 name = get_property(np, "name", NULL);
151 /* checking iclen makes sure we don't get a false
152 match on /chosen.interrupt_controller */
154 && strcmp(name, "interrupt-controller") == 0)
155 || (ic != NULL && iclen == 0 && strcmp(name, "AppleKiwi"))) {
157 dflt_interrupt_controller = np;
161 num_interrupt_controllers = n;
164 mem = finish_node(allnodes, mem, NULL, 1, 1);
165 dev_tree_size = mem - (unsigned long) allnodes;
166 klimit = (char *) mem;
169 static unsigned long __init
170 finish_node(struct device_node *np, unsigned long mem_start,
171 interpret_func *ifunc, int naddrc, int nsizec)
173 struct device_node *child;
176 np->name = get_property(np, "name", 0);
177 np->type = get_property(np, "device_type", 0);
184 /* get the device addresses and interrupts */
186 mem_start = ifunc(np, mem_start, naddrc, nsizec);
188 if (use_of_interrupt_tree)
189 mem_start = finish_node_interrupts(np, mem_start);
191 /* Look for #address-cells and #size-cells properties. */
192 ip = (int *) get_property(np, "#address-cells", 0);
195 ip = (int *) get_property(np, "#size-cells", 0);
199 if (np->parent == NULL)
200 ifunc = interpret_root_props;
201 else if (np->type == 0)
203 else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
204 ifunc = interpret_pci_props;
205 else if (!strcmp(np->type, "dbdma"))
206 ifunc = interpret_dbdma_props;
207 else if (!strcmp(np->type, "mac-io")
208 || ifunc == interpret_macio_props)
209 ifunc = interpret_macio_props;
210 else if (!strcmp(np->type, "isa"))
211 ifunc = interpret_isa_props;
212 else if (!strcmp(np->name, "uni-n"))
213 ifunc = interpret_root_props;
214 else if (!((ifunc == interpret_dbdma_props
215 || ifunc == interpret_macio_props)
216 && (!strcmp(np->type, "escc")
217 || !strcmp(np->type, "media-bay"))))
220 /* if we were booted from BootX, convert the full name */
222 && strncmp(np->full_name, "Devices:device-tree", 19) == 0) {
223 if (np->full_name[19] == 0) {
224 strcpy(np->full_name, "/");
225 } else if (np->full_name[19] == ':') {
226 char *p = np->full_name + 19;
234 for (child = np->child; child != NULL; child = child->sibling)
235 mem_start = finish_node(child, mem_start, ifunc,
242 * Find the interrupt parent of a node.
244 static struct device_node * __init
245 intr_parent(struct device_node *p)
249 parp = (phandle *) get_property(p, "interrupt-parent", NULL);
252 p = find_phandle(*parp);
256 * On a powermac booted with BootX, we don't get to know the
257 * phandles for any nodes, so find_phandle will return NULL.
258 * Fortunately these machines only have one interrupt controller
259 * so there isn't in fact any ambiguity. -- paulus
261 if (num_interrupt_controllers == 1)
262 p = dflt_interrupt_controller;
267 * Find out the size of each entry of the interrupts property
271 prom_n_intr_cells(struct device_node *np)
273 struct device_node *p;
276 for (p = np; (p = intr_parent(p)) != NULL; ) {
277 icp = (unsigned int *)
278 get_property(p, "#interrupt-cells", NULL);
281 if (get_property(p, "interrupt-controller", NULL) != NULL
282 || get_property(p, "interrupt-map", NULL) != NULL) {
283 printk("oops, node %s doesn't have #interrupt-cells\n",
288 printk("prom_n_intr_cells failed for %s\n", np->full_name);
293 * Map an interrupt from a device up to the platform interrupt
297 map_interrupt(unsigned int **irq, struct device_node **ictrler,
298 struct device_node *np, unsigned int *ints, int nintrc)
300 struct device_node *p, *ipar;
301 unsigned int *imap, *imask, *ip;
302 int i, imaplen, match;
303 int newintrc, newaddrc;
307 reg = (unsigned int *) get_property(np, "reg", NULL);
308 naddrc = prom_n_addr_cells(np);
311 if (get_property(p, "interrupt-controller", NULL) != NULL)
312 /* this node is an interrupt controller, stop here */
314 imap = (unsigned int *)
315 get_property(p, "interrupt-map", &imaplen);
320 imask = (unsigned int *)
321 get_property(p, "interrupt-map-mask", NULL);
323 printk("oops, %s has interrupt-map but no mask\n",
327 imaplen /= sizeof(unsigned int);
330 while (imaplen > 0 && !match) {
331 /* check the child-interrupt field */
333 for (i = 0; i < naddrc && match; ++i)
334 match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
335 for (; i < naddrc + nintrc && match; ++i)
336 match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
337 imap += naddrc + nintrc;
338 imaplen -= naddrc + nintrc;
339 /* grab the interrupt parent */
340 ipar = find_phandle((phandle) *imap++);
342 if (ipar == NULL && num_interrupt_controllers == 1)
343 /* cope with BootX not giving us phandles */
344 ipar = dflt_interrupt_controller;
346 printk("oops, no int parent %x in map of %s\n",
347 imap[-1], p->full_name);
350 /* find the parent's # addr and intr cells */
351 ip = (unsigned int *)
352 get_property(ipar, "#interrupt-cells", NULL);
354 printk("oops, no #interrupt-cells on %s\n",
359 ip = (unsigned int *)
360 get_property(ipar, "#address-cells", NULL);
361 newaddrc = (ip == NULL)? 0: *ip;
362 imap += newaddrc + newintrc;
363 imaplen -= newaddrc + newintrc;
366 printk("oops, error decoding int-map on %s, len=%d\n",
367 p->full_name, imaplen);
371 printk("oops, no match in %s int-map for %s\n",
372 p->full_name, np->full_name);
378 ints = imap - nintrc;
382 printk("hmmm, int tree for %s doesn't have ctrler\n",
390 * New version of finish_node_interrupts.
392 static unsigned long __init
393 finish_node_interrupts(struct device_node *np, unsigned long mem_start)
396 int intlen, intrcells;
399 struct device_node *ic;
401 ints = (unsigned int *) get_property(np, "interrupts", &intlen);
404 intrcells = prom_n_intr_cells(np);
405 intlen /= intrcells * sizeof(unsigned int);
406 np->n_intrs = intlen;
407 np->intrs = (struct interrupt_info *) mem_start;
408 mem_start += intlen * sizeof(struct interrupt_info);
410 for (i = 0; i < intlen; ++i) {
411 np->intrs[i].line = 0;
412 np->intrs[i].sense = 1;
413 n = map_interrupt(&irq, &ic, np, ints, intrcells);
418 * On a CHRP we have an 8259 which is subordinate to
419 * the openpic in the interrupt tree, but we want the
420 * openpic's interrupt numbers offsetted, not the 8259's.
421 * So we apply the offset if the controller is at the
422 * root of the interrupt tree, i.e. has no interrupt-parent.
423 * This doesn't cope with the general case of multiple
424 * cascaded interrupt controllers, but then neither will
425 * irq.c at the moment either. -- paulus
427 if (num_interrupt_controllers > 1 && ic != NULL
428 && get_property(ic, "interrupt-parent", NULL) == NULL)
430 np->intrs[i].line = irq[0] + offset;
432 np->intrs[i].sense = irq[1];
434 printk("hmmm, got %d intr cells for %s:", n,
436 for (j = 0; j < n; ++j)
437 printk(" %d", irq[j]);
447 * When BootX makes a copy of the device tree from the MacOS
448 * Name Registry, it is in the format we use but all of the pointers
449 * are offsets from the start of the tree.
450 * This procedure updates the pointers.
456 struct device_node *np;
459 #define ADDBASE(x) (x = (x)? ((typeof (x))((unsigned long)(x) + base)): 0)
461 base = (unsigned long) boot_infos + boot_infos->deviceTreeOffset;
462 allnodes = (struct device_node *)(base + 4);
463 for (np = allnodes; np != 0; np = np->allnext) {
464 ADDBASE(np->full_name);
465 ADDBASE(np->properties);
468 ADDBASE(np->sibling);
469 ADDBASE(np->allnext);
470 for (pp = np->properties; pp != 0; pp = pp->next) {
479 prom_n_addr_cells(struct device_node* np)
485 ip = (int *) get_property(np, "#address-cells", 0);
488 } while (np->parent);
489 /* No #address-cells property for the root node, default to 1 */
494 prom_n_size_cells(struct device_node* np)
500 ip = (int *) get_property(np, "#size-cells", 0);
503 } while (np->parent);
504 /* No #size-cells property for the root node, default to 1 */
508 static unsigned long __init
509 map_addr(struct device_node *np, unsigned long space, unsigned long addr)
512 unsigned int *ranges;
516 type = (space >> 24) & 3;
520 while ((np = np->parent) != NULL) {
521 if (strcmp(np->type, "pci") != 0)
523 /* PCI bridge: map the address through the ranges property */
524 na = prom_n_addr_cells(np);
525 ranges = (unsigned int *) get_property(np, "ranges", &rlen);
526 while ((rlen -= (na + 5) * sizeof(unsigned int)) >= 0) {
527 if (((ranges[0] >> 24) & 3) == type
529 && addr - ranges[2] < ranges[na+4]) {
530 /* ok, this matches, translate it */
531 addr += ranges[na+2] - ranges[2];
540 static unsigned long __init
541 interpret_pci_props(struct device_node *np, unsigned long mem_start,
542 int naddrc, int nsizec)
544 struct address_range *adr;
545 struct pci_reg_property *pci_addrs;
548 pci_addrs = (struct pci_reg_property *)
549 get_property(np, "assigned-addresses", &l);
550 if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
552 adr = (struct address_range *) mem_start;
553 while ((l -= sizeof(struct pci_reg_property)) >= 0) {
554 adr[i].space = pci_addrs[i].addr.a_hi;
555 adr[i].address = map_addr(np, pci_addrs[i].addr.a_hi,
556 pci_addrs[i].addr.a_lo);
557 adr[i].size = pci_addrs[i].size_lo;
562 mem_start += i * sizeof(struct address_range);
565 if (use_of_interrupt_tree)
568 ip = (int *) get_property(np, "AAPL,interrupts", &l);
569 if (ip == 0 && np->parent)
570 ip = (int *) get_property(np->parent, "AAPL,interrupts", &l);
572 ip = (int *) get_property(np, "interrupts", &l);
574 np->intrs = (struct interrupt_info *) mem_start;
575 np->n_intrs = l / sizeof(int);
576 mem_start += np->n_intrs * sizeof(struct interrupt_info);
577 for (i = 0; i < np->n_intrs; ++i) {
578 np->intrs[i].line = *ip++;
579 np->intrs[i].sense = 1;
586 static unsigned long __init
587 interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
588 int naddrc, int nsizec)
590 struct reg_property *rp;
591 struct address_range *adr;
592 unsigned long base_address;
594 struct device_node *db;
597 for (db = np->parent; db != NULL; db = db->parent) {
598 if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
599 base_address = db->addrs[0].address;
604 rp = (struct reg_property *) get_property(np, "reg", &l);
605 if (rp != 0 && l >= sizeof(struct reg_property)) {
607 adr = (struct address_range *) mem_start;
608 while ((l -= sizeof(struct reg_property)) >= 0) {
610 adr[i].address = rp[i].address + base_address;
611 adr[i].size = rp[i].size;
616 mem_start += i * sizeof(struct address_range);
619 if (use_of_interrupt_tree)
622 ip = (int *) get_property(np, "AAPL,interrupts", &l);
624 ip = (int *) get_property(np, "interrupts", &l);
626 np->intrs = (struct interrupt_info *) mem_start;
627 np->n_intrs = l / sizeof(int);
628 mem_start += np->n_intrs * sizeof(struct interrupt_info);
629 for (i = 0; i < np->n_intrs; ++i) {
630 np->intrs[i].line = *ip++;
631 np->intrs[i].sense = 1;
638 static unsigned long __init
639 interpret_macio_props(struct device_node *np, unsigned long mem_start,
640 int naddrc, int nsizec)
642 struct reg_property *rp;
643 struct address_range *adr;
644 unsigned long base_address;
646 struct device_node *db;
649 for (db = np->parent; db != NULL; db = db->parent) {
650 if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
651 base_address = db->addrs[0].address;
656 rp = (struct reg_property *) get_property(np, "reg", &l);
657 if (rp != 0 && l >= sizeof(struct reg_property)) {
659 adr = (struct address_range *) mem_start;
660 while ((l -= sizeof(struct reg_property)) >= 0) {
662 adr[i].address = rp[i].address + base_address;
663 adr[i].size = rp[i].size;
668 mem_start += i * sizeof(struct address_range);
671 if (use_of_interrupt_tree)
674 ip = (int *) get_property(np, "interrupts", &l);
676 ip = (int *) get_property(np, "AAPL,interrupts", &l);
678 np->intrs = (struct interrupt_info *) mem_start;
679 np->n_intrs = l / sizeof(int);
680 for (i = 0; i < np->n_intrs; ++i) {
681 np->intrs[i].line = *ip++;
682 np->intrs[i].sense = 1;
684 mem_start += np->n_intrs * sizeof(struct interrupt_info);
690 static unsigned long __init
691 interpret_isa_props(struct device_node *np, unsigned long mem_start,
692 int naddrc, int nsizec)
694 struct isa_reg_property *rp;
695 struct address_range *adr;
698 rp = (struct isa_reg_property *) get_property(np, "reg", &l);
699 if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
701 adr = (struct address_range *) mem_start;
702 while ((l -= sizeof(struct reg_property)) >= 0) {
703 adr[i].space = rp[i].space;
704 adr[i].address = rp[i].address
705 + (adr[i].space? 0: _ISA_MEM_BASE);
706 adr[i].size = rp[i].size;
711 mem_start += i * sizeof(struct address_range);
714 if (use_of_interrupt_tree)
717 ip = (int *) get_property(np, "interrupts", &l);
719 np->intrs = (struct interrupt_info *) mem_start;
720 np->n_intrs = l / (2 * sizeof(int));
721 mem_start += np->n_intrs * sizeof(struct interrupt_info);
722 for (i = 0; i < np->n_intrs; ++i) {
723 np->intrs[i].line = *ip++;
724 np->intrs[i].sense = *ip++;
731 static unsigned long __init
732 interpret_root_props(struct device_node *np, unsigned long mem_start,
733 int naddrc, int nsizec)
735 struct address_range *adr;
738 int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
740 rp = (unsigned int *) get_property(np, "reg", &l);
741 if (rp != 0 && l >= rpsize) {
743 adr = (struct address_range *) mem_start;
744 while ((l -= rpsize) >= 0) {
745 adr[i].space = (naddrc >= 2? rp[naddrc-2]: 2);
746 adr[i].address = rp[naddrc - 1];
747 adr[i].size = rp[naddrc + nsizec - 1];
749 rp += naddrc + nsizec;
753 mem_start += i * sizeof(struct address_range);
756 if (use_of_interrupt_tree)
759 ip = (int *) get_property(np, "AAPL,interrupts", &l);
761 ip = (int *) get_property(np, "interrupts", &l);
763 np->intrs = (struct interrupt_info *) mem_start;
764 np->n_intrs = l / sizeof(int);
765 mem_start += np->n_intrs * sizeof(struct interrupt_info);
766 for (i = 0; i < np->n_intrs; ++i) {
767 np->intrs[i].line = *ip++;
768 np->intrs[i].sense = 1;
776 * Work out the sense (active-low level / active-high edge)
777 * of each interrupt from the device tree.
780 prom_get_irq_senses(unsigned char *senses, int off, int max)
782 struct device_node *np;
785 /* default to level-triggered */
786 memset(senses, 1, max - off);
787 if (!use_of_interrupt_tree)
790 for (np = allnodes; np != 0; np = np->allnext) {
791 for (j = 0; j < np->n_intrs; j++) {
792 i = np->intrs[j].line;
793 if (i >= off && i < max) {
794 if (np->intrs[j].sense == 1) {
795 senses[i-off] = (IRQ_SENSE_LEVEL |
796 IRQ_POLARITY_NEGATIVE);
798 senses[i-off] = (IRQ_SENSE_EDGE |
799 IRQ_POLARITY_POSITIVE);
807 * Construct and return a list of the device_nodes with a given name.
810 find_devices(const char *name)
812 struct device_node *head, **prevp, *np;
815 for (np = allnodes; np != 0; np = np->allnext) {
816 if (np->name != 0 && strcasecmp(np->name, name) == 0) {
826 * Construct and return a list of the device_nodes with a given type.
829 find_type_devices(const char *type)
831 struct device_node *head, **prevp, *np;
834 for (np = allnodes; np != 0; np = np->allnext) {
835 if (np->type != 0 && strcasecmp(np->type, type) == 0) {
845 * Returns all nodes linked together
847 struct device_node * __openfirmware
850 struct device_node *head, **prevp, *np;
853 for (np = allnodes; np != 0; np = np->allnext) {
861 /* Checks if the given "compat" string matches one of the strings in
862 * the device's "compatible" property
865 device_is_compatible(struct device_node *device, const char *compat)
870 cp = (char *) get_property(device, "compatible", &cplen);
874 if (strncasecmp(cp, compat, strlen(compat)) == 0)
886 * Indicates whether the root node has a given value in its
887 * compatible property.
890 machine_is_compatible(const char *compat)
892 struct device_node *root;
894 root = find_path_device("/");
897 return device_is_compatible(root, compat);
901 * Construct and return a list of the device_nodes with a given type
902 * and compatible property.
905 find_compatible_devices(const char *type, const char *compat)
907 struct device_node *head, **prevp, *np;
910 for (np = allnodes; np != 0; np = np->allnext) {
912 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
914 if (device_is_compatible(np, compat)) {
924 * Find the device_node with a given full_name.
927 find_path_device(const char *path)
929 struct device_node *np;
931 for (np = allnodes; np != 0; np = np->allnext)
932 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
938 * Find the device_node with a given phandle.
940 struct device_node * __init
941 find_phandle(phandle ph)
943 struct device_node *np;
945 for (np = allnodes; np != 0; np = np->allnext)
952 * Find a property with a given name for a given node
953 * and return the value.
956 get_property(struct device_node *np, const char *name, int *lenp)
960 for (pp = np->properties; pp != 0; pp = pp->next)
961 if (pp->name != NULL && strcmp(pp->name, name) == 0) {
970 * Add a property to a node
973 prom_add_property(struct device_node* np, struct property* prop)
975 struct property **next = &np->properties;
979 next = &(*next)->next;
983 /* I quickly hacked that one, check against spec ! */
984 static inline unsigned long __openfirmware
985 bus_space_to_resource_flags(unsigned int bus_space)
987 u8 space = (bus_space >> 24) & 0xf;
991 return IORESOURCE_MEM;
992 else if (space == 0x01)
993 return IORESOURCE_IO;
995 printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n",
1001 static struct resource* __openfirmware
1002 find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range)
1007 /* Check this one */
1008 mask = bus_space_to_resource_flags(range->space);
1009 for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
1010 if ((pdev->resource[i].flags & mask) == mask &&
1011 pdev->resource[i].start <= range->address &&
1012 pdev->resource[i].end > range->address) {
1013 if ((range->address + range->size - 1) > pdev->resource[i].end) {
1014 /* Add better message */
1015 printk(KERN_WARNING "PCI/OF resource overlap !\n");
1021 if (i == DEVICE_COUNT_RESOURCE)
1023 return &pdev->resource[i];
1027 * Request an OF device resource. Currently handles child of PCI devices,
1028 * or other nodes attached to the root node. Ultimately, put some
1029 * link to resources in the OF node.
1030 * WARNING: out_resource->name should be initialized before calling this
1033 struct resource* __openfirmware
1034 request_OF_resource(struct device_node* node, int index, const char* name_postfix)
1036 struct pci_dev* pcidev;
1037 u8 pci_bus, pci_devfn;
1038 unsigned long iomask;
1039 struct device_node* nd;
1040 struct resource* parent;
1041 struct resource *res = NULL;
1044 if (index >= node->n_addrs)
1047 /* Sanity check on bus space */
1048 iomask = bus_space_to_resource_flags(node->addrs[index].space);
1049 if (iomask & IORESOURCE_MEM)
1050 parent = &iomem_resource;
1051 else if (iomask & IORESOURCE_IO)
1052 parent = &ioport_resource;
1056 /* Find a PCI parent if any */
1060 if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
1061 pcidev = pci_find_slot(pci_bus, pci_devfn);
1066 parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
1068 printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
1073 res = __request_region(parent, node->addrs[index].address, node->addrs[index].size, NULL);
1076 nlen = strlen(node->name);
1077 plen = name_postfix ? strlen(name_postfix) : 0;
1078 res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL);
1080 strcpy((char *)res->name, node->name);
1082 strcpy((char *)res->name+nlen, name_postfix);
1090 release_OF_resource(struct device_node* node, int index)
1092 struct pci_dev* pcidev;
1093 u8 pci_bus, pci_devfn;
1094 unsigned long iomask;
1095 struct device_node* nd;
1096 struct resource* parent;
1097 struct resource *res = NULL;
1099 if (index >= node->n_addrs)
1102 /* Sanity check on bus space */
1103 iomask = bus_space_to_resource_flags(node->addrs[index].space);
1104 if (iomask & IORESOURCE_MEM)
1105 parent = &iomem_resource;
1106 else if (iomask & IORESOURCE_IO)
1107 parent = &ioport_resource;
1111 /* Find a PCI parent if any */
1115 if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
1116 pcidev = pci_find_slot(pci_bus, pci_devfn);
1121 parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
1123 printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
1128 /* Find us in the parent */
1129 res = parent->child;
1131 if (res->start == node->addrs[index].address &&
1132 res->end == (res->start + node->addrs[index].size - 1))
1143 release_resource(res);
1151 print_properties(struct device_node *np)
1153 struct property *pp;
1157 for (pp = np->properties; pp != 0; pp = pp->next) {
1158 printk(KERN_INFO "%s", pp->name);
1159 for (i = strlen(pp->name); i < 16; ++i)
1161 cp = (char *) pp->value;
1162 for (i = pp->length; i > 0; --i, ++cp)
1163 if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
1164 || (i == 1 && *cp != 0))
1166 if (i == 0 && pp->length > 1) {
1167 /* looks like a string */
1168 printk(" %s\n", (char *) pp->value);
1170 /* dump it in hex */
1174 if (pp->length % 4 == 0) {
1175 unsigned int *p = (unsigned int *) pp->value;
1178 for (i = 0; i < n; ++i) {
1179 if (i != 0 && (i % 4) == 0)
1181 printk(" %08x", *p++);
1184 unsigned char *bp = pp->value;
1186 for (i = 0; i < n; ++i) {
1187 if (i != 0 && (i % 16) == 0)
1189 printk(" %02x", *bp++);
1193 if (pp->length > 64)
1194 printk(" ... (length = %d)\n",
1201 static spinlock_t rtas_lock = SPIN_LOCK_UNLOCKED;
1203 /* this can be called after setup -- Cort */
1205 call_rtas(const char *service, int nargs, int nret,
1206 unsigned long *outputs, ...)
1211 struct device_node *rtas;
1214 unsigned long words[16];
1218 rtas = find_devices("rtas");
1221 tokp = (int *) get_property(rtas, service, NULL);
1223 printk(KERN_ERR "No RTAS service called %s\n", service);
1229 va_start(list, outputs);
1230 for (i = 0; i < nargs; ++i)
1231 u.words[i+3] = va_arg(list, unsigned long);
1235 * RTAS doesn't use floating point.
1236 * Or at least, according to the CHRP spec we enter RTAS
1237 * with FP disabled, and it doesn't change the FP registers.
1240 spin_lock_irqsave(&rtas_lock, s);
1241 enter_rtas((void *)__pa(&u));
1242 spin_unlock_irqrestore(&rtas_lock, s);
1244 if (nret > 1 && outputs != NULL)
1245 for (i = 0; i < nret-1; ++i)
1246 outputs[i] = u.words[i+nargs+4];
1247 return u.words[nargs+3];