lkml.org 
[lkml]   [2004]   [Apr]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH] Reorder arch/ppc64/kernel/prom.c
From
Date
Name: Clean Up Select prom.c Prototypes
Status: Trivial
Version: ppc64

prom.c pre-declares various static functions. This makes it a PITA to
navigate and alter.

Rearrange them as a C programmer would.

diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .17232-linux-ppc64-2.5/arch/ppc64/kernel/prom.c .17232-linux-ppc64-2.5.updated/arch/ppc64/kernel/prom.c
--- .17232-linux-ppc64-2.5/arch/ppc64/kernel/prom.c 2004-04-13 18:06:15.000000000 +1000
+++ .17232-linux-ppc64-2.5.updated/arch/ppc64/kernel/prom.c 2004-04-15 16:58:25.000000000 +1000
@@ -161,25 +161,6 @@ struct device_node *allnodes = 0;
*/
static rwlock_t devtree_lock = RW_LOCK_UNLOCKED;

-static unsigned long call_prom(const char *service, int nargs, int nret, ...);
-static void prom_panic(const char *reason);
-static unsigned long copy_device_tree(unsigned long);
-static unsigned long inspect_node(phandle, struct device_node *, unsigned long,
- unsigned long, struct device_node ***);
-static unsigned long finish_node(struct device_node *, unsigned long,
- interpret_func *, int, int);
-static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
-static unsigned long check_display(unsigned long);
-static int prom_next_node(phandle *);
-static struct bi_record * prom_bi_rec_verify(struct bi_record *);
-static unsigned long prom_bi_rec_reserve(unsigned long);
-static struct device_node *find_phandle(phandle);
-static void of_node_cleanup(struct device_node *);
-static struct device_node *derive_parent(const char *);
-static void add_node_proc_entries(struct device_node *);
-static void remove_node_proc_entries(struct device_node *);
-static int of_finish_dynamic_node(struct device_node *);
-
#ifdef DEBUG_PROM
void prom_dump_lmb(void);
#endif
@@ -304,6 +285,24 @@ prom_print_nl(void)
prom_print(RELOC("\n"));
}

+static int __init
+prom_next_node(phandle *nodep)
+{
+ phandle node;
+ unsigned long offset = reloc_offset();
+
+ if ((node = *nodep) != 0
+ && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0)
+ return 1;
+ if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
+ return 1;
+ for (;;) {
+ if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0)
+ return 0;
+ if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
+ return 1;
+ }
+}

static unsigned long
prom_initialize_naca(unsigned long mem)
@@ -1441,170 +1440,186 @@ static int __init prom_find_machine_type
return PLATFORM_PSERIES;
}

-/*
- * We enter here early on, when the Open Firmware prom is still
- * handling exceptions and the MMU hash table for us.
- */
-
-unsigned long __init
-prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
- unsigned long r6, unsigned long r7)
+static unsigned long __init
+inspect_node(phandle node, struct device_node *dad,
+ unsigned long mem_start, unsigned long mem_end,
+ struct device_node ***allnextpp)
{
- unsigned long mem;
- ihandle prom_cpu;
- phandle cpu_pkg;
+ int l;
+ phandle child;
+ struct device_node *np;
+ struct property *pp, **prev_propp;
+ char *prev_name, *namep;
+ unsigned char *valp;
unsigned long offset = reloc_offset();
- long l;
- char *p, *d;
- unsigned long phys;
- u32 getprop_rval;
- struct systemcfg *_systemcfg;
- struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
- struct prom_t *_prom = PTRRELOC(&prom);
-
- /* First zero the BSS -- use memset, some arches don't have
- * caches on yet */
- memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);

- /* Setup systemcfg and NACA pointers now */
- RELOC(systemcfg) = _systemcfg = (struct systemcfg *)(SYSTEMCFG_VIRT_ADDR - offset);
- RELOC(naca) = (struct naca_struct *)(NACA_VIRT_ADDR - offset);
-
- /* Init interface to Open Firmware and pickup bi-recs */
- prom_init_client_services(pp);
-
- /* Init prom stdout device */
- prom_init_stdout();
-
- /* check out if we have bi_recs */
- _prom->bi_recs = prom_bi_rec_verify((struct bi_record *)r6);
- if ( _prom->bi_recs != NULL )
- RELOC(klimit) = PTRUNRELOC((unsigned long)_prom->bi_recs +
- _prom->bi_recs->data[1]);
-
- /* Default machine type. */
- _systemcfg->platform = prom_find_machine_type();
-
- /* On pSeries, copy the CPU hold code */
- if (_systemcfg->platform == PLATFORM_PSERIES)
- copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
-
- /* Start storing things at klimit */
- mem = RELOC(klimit) - offset;
+ np = (struct device_node *) mem_start;
+ mem_start += sizeof(struct device_node);
+ memset(np, 0, sizeof(*np));
+ np->node = node;
+ **allnextpp = PTRUNRELOC(np);
+ *allnextpp = &np->allnext;
+ if (dad != 0) {
+ np->parent = PTRUNRELOC(dad);
+ /* we temporarily use the `next' field as `last_child'. */
+ if (dad->next == 0)
+ dad->child = PTRUNRELOC(np);
+ else
+ dad->next->sibling = PTRUNRELOC(np);
+ dad->next = np;
+ }

- /* Get the full OF pathname of the stdout device */
- p = (char *) mem;
- memset(p, 0, 256);
- call_prom(RELOC("instance-to-path"), 3, 1, _prom->stdout, p, 255);
- RELOC(of_stdout_device) = PTRUNRELOC(p);
- mem += strlen(p) + 1;
+ /* get and store all properties */
+ prev_propp = &np->properties;
+ prev_name = RELOC("");
+ for (;;) {
+ pp = (struct property *) mem_start;
+ namep = (char *) (pp + 1);
+ pp->name = PTRUNRELOC(namep);
+ if ((long) call_prom(RELOC("nextprop"), 3, 1, node, prev_name,
+ namep) <= 0)
+ break;
+ mem_start = DOUBLEWORD_ALIGN((unsigned long)namep + strlen(namep) + 1);
+ prev_name = namep;
+ valp = (unsigned char *) mem_start;
+ pp->value = PTRUNRELOC(valp);
+ pp->length = (int)(long)
+ call_prom(RELOC("getprop"), 4, 1, node, namep,
+ valp, mem_end - mem_start);
+ if (pp->length < 0)
+ continue;
+ if (pp->length > MAX_PROPERTY_LENGTH) {
+ char path[128];

- getprop_rval = 1;
- call_prom(RELOC("getprop"), 4, 1,
- _prom->root, RELOC("#size-cells"),
- &getprop_rval, sizeof(getprop_rval));
- _prom->encode_phys_size = (getprop_rval == 1) ? 32 : 64;
+ prom_print(RELOC("WARNING: ignoring large property "));
+ /* It seems OF doesn't null-terminate the path :-( */
+ memset(path, 0, sizeof(path));
+ if (call_prom(RELOC("package-to-path"), 3, 1, node,
+ path, sizeof(path)-1) > 0)
+ prom_print(path);
+ prom_print(namep);
+ prom_print(RELOC(" length 0x"));
+ prom_print_hex(pp->length);
+ prom_print_nl();

- /* Determine which cpu is actually running right _now_ */
- if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
- RELOC("cpu"), &getprop_rval,
- sizeof(getprop_rval)) <= 0)
- prom_panic(RELOC("cannot find boot cpu"));
+ continue;
+ }
+ mem_start = DOUBLEWORD_ALIGN(mem_start + pp->length);
+ *prev_propp = PTRUNRELOC(pp);
+ prev_propp = &pp->next;
+ }

- prom_cpu = (ihandle)(unsigned long)getprop_rval;
- cpu_pkg = call_prom(RELOC("instance-to-package"), 1, 1, prom_cpu);
- call_prom(RELOC("getprop"), 4, 1,
- cpu_pkg, RELOC("reg"),
- &getprop_rval, sizeof(getprop_rval));
- _prom->cpu = (int)(unsigned long)getprop_rval;
- _xPaca[0].xHwProcNum = _prom->cpu;
+ /* Add a "linux_phandle" value */
+ if (np->node) {
+ u32 ibm_phandle = 0;
+ int len;

- RELOC(boot_cpuid) = 0;
+ /* First see if "ibm,phandle" exists and use its value */
+ len = (int)
+ call_prom(RELOC("getprop"), 4, 1, node, RELOC("ibm,phandle"),
+ &ibm_phandle, sizeof(ibm_phandle));
+ if (len < 0) {
+ np->linux_phandle = np->node;
+ } else {
+ np->linux_phandle = ibm_phandle;
+ }
+ }

-#ifdef DEBUG_PROM
- prom_print(RELOC("Booting CPU hw index = 0x"));
- prom_print_hex(_prom->cpu);
- prom_print_nl();
-#endif
+ *prev_propp = 0;

- /* Get the boot device and translate it to a full OF pathname. */
- p = (char *) mem;
- l = (long) call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
- RELOC("bootpath"), p, 1<<20);
- if (l > 0) {
- p[l] = 0; /* should already be null-terminated */
- RELOC(bootpath) = PTRUNRELOC(p);
- mem += l + 1;
- d = (char *) mem;
- *d = 0;
- call_prom(RELOC("canon"), 3, 1, p, d, 1<<20);
- RELOC(bootdevice) = PTRUNRELOC(d);
- mem = DOUBLEWORD_ALIGN(mem + strlen(d) + 1);
+ /* get the node's full name */
+ l = (long) call_prom(RELOC("package-to-path"), 3, 1, node,
+ (char *) mem_start, mem_end - mem_start);
+ if (l >= 0) {
+ np->full_name = PTRUNRELOC((char *) mem_start);
+ *(char *)(mem_start + l) = 0;
+ mem_start = DOUBLEWORD_ALIGN(mem_start + l + 1);
}

- RELOC(cmd_line[0]) = 0;
- if ((long)_prom->chosen > 0) {
- call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
- RELOC("bootargs"), p, sizeof(cmd_line));
- if (p != NULL && p[0] != 0)
- strlcpy(RELOC(cmd_line), p, sizeof(cmd_line));
+ /* do all our children */
+ child = call_prom(RELOC("child"), 1, 1, node);
+ while (child != (phandle)0) {
+ mem_start = inspect_node(child, np, mem_start, mem_end,
+ allnextpp);
+ child = call_prom(RELOC("peer"), 1, 1, child);
}

- early_cmdline_parse();
-
- mem = prom_initialize_lmb(mem);
+ return mem_start;
+}

- mem = prom_bi_rec_reserve(mem);
+/*
+ * Make a copy of the device tree from the PROM.
+ */
+static unsigned long __init
+copy_device_tree(unsigned long mem_start)
+{
+ phandle root;
+ unsigned long new_start;
+ struct device_node **allnextp;
+ unsigned long offset = reloc_offset();
+ unsigned long mem_end = mem_start + (8<<20);

- mem = check_display(mem);
+ root = call_prom(RELOC("peer"), 1, 1, (phandle)0);
+ if (root == (phandle)0) {
+ prom_panic(RELOC("couldn't get device tree root\n"));
+ }
+ allnextp = &RELOC(allnodes);
+ mem_start = DOUBLEWORD_ALIGN(mem_start);
+ new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);
+ *allnextp = 0;
+ return new_start;
+}

- if (_systemcfg->platform != PLATFORM_POWERMAC)
- prom_instantiate_rtas();
-
- /* Initialize some system info into the Naca early... */
- mem = prom_initialize_naca(mem);
+/* Verify bi_recs are good */
+static struct bi_record *
+prom_bi_rec_verify(struct bi_record *bi_recs)
+{
+ struct bi_record *first, *last;

- smt_setup();
-
- /* If we are on an SMP machine, then we *MUST* do the
- * following, regardless of whether we have an SMP
- * kernel or not.
- */
- prom_hold_cpus(mem);
+ if ( bi_recs == NULL || bi_recs->tag != BI_FIRST )
+ return NULL;

-#ifdef DEBUG_PROM
- prom_print(RELOC("copying OF device tree...\n"));
-#endif
- mem = copy_device_tree(mem);
+ last = (struct bi_record *)(long)bi_recs->data[0];
+ if ( last == NULL || last->tag != BI_LAST )
+ return NULL;

- RELOC(klimit) = mem + offset;
+ first = (struct bi_record *)(long)last->data[0];
+ if ( first == NULL || first != bi_recs )
+ return NULL;

- lmb_reserve(0, __pa(RELOC(klimit)));
+ return bi_recs;
+}

- if (_systemcfg->platform == PLATFORM_PSERIES)
- prom_initialize_tce_table();
+static unsigned long
+prom_bi_rec_reserve(unsigned long mem)
+{
+ unsigned long offset = reloc_offset();
+ struct prom_t *_prom = PTRRELOC(&prom);
+ struct bi_record *rec;

-#ifdef CONFIG_PMAC_DART
- if (_systemcfg->platform == PLATFORM_POWERMAC)
- prom_initialize_dart_table();
-#endif
+ if ( _prom->bi_recs != NULL) {

-#ifdef CONFIG_BOOTX_TEXT
- if(_prom->disp_node) {
- prom_print(RELOC("Setting up bi display...\n"));
- setup_disp_fake_bi(_prom->disp_node);
+ for ( rec=_prom->bi_recs;
+ rec->tag != BI_LAST;
+ rec=bi_rec_next(rec) ) {
+ switch (rec->tag) {
+#ifdef CONFIG_BLK_DEV_INITRD
+ case BI_INITRD:
+ lmb_reserve(rec->data[0], rec->data[1]);
+ break;
+#endif /* CONFIG_BLK_DEV_INITRD */
+ }
+ }
+ /* The next use of this field will be after relocation
+ * is enabled, so convert this physical address into a
+ * virtual address.
+ */
+ _prom->bi_recs = PTRUNRELOC(_prom->bi_recs);
}
-#endif /* CONFIG_BOOTX_TEXT */

- prom_print(RELOC("Calling quiesce ...\n"));
- call_prom(RELOC("quiesce"), 0, 0);
- phys = KERNELBASE - offset;
-
- prom_print(RELOC("returning from prom_init\n"));
- return phys;
+ return mem;
}

-
static int
prom_set_color(ihandle ih, int i, int r, int g, int b)
{
@@ -1742,237 +1757,185 @@ check_display(unsigned long mem)
return DOUBLEWORD_ALIGN(mem);
}

+/*
+ * We enter here early on, when the Open Firmware prom is still
+ * handling exceptions and the MMU hash table for us.
+ */

-static int __init
-prom_next_node(phandle *nodep)
+unsigned long __init
+prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
+ unsigned long r6, unsigned long r7)
{
- phandle node;
+ unsigned long mem;
+ ihandle prom_cpu;
+ phandle cpu_pkg;
unsigned long offset = reloc_offset();
+ long l;
+ char *p, *d;
+ unsigned long phys;
+ u32 getprop_rval;
+ struct systemcfg *_systemcfg;
+ struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
+ struct prom_t *_prom = PTRRELOC(&prom);

- if ((node = *nodep) != 0
- && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0)
- return 1;
- if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
- return 1;
- for (;;) {
- if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0)
- return 0;
- if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)
- return 1;
- }
-}
+ /* First zero the BSS -- use memset, some arches don't have
+ * caches on yet */
+ memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);

-/*
- * Make a copy of the device tree from the PROM.
- */
-static unsigned long __init
-copy_device_tree(unsigned long mem_start)
-{
- phandle root;
- unsigned long new_start;
- struct device_node **allnextp;
- unsigned long offset = reloc_offset();
- unsigned long mem_end = mem_start + (8<<20);
+ /* Setup systemcfg and NACA pointers now */
+ RELOC(systemcfg) = _systemcfg = (struct systemcfg *)(SYSTEMCFG_VIRT_ADDR - offset);
+ RELOC(naca) = (struct naca_struct *)(NACA_VIRT_ADDR - offset);

- root = call_prom(RELOC("peer"), 1, 1, (phandle)0);
- if (root == (phandle)0) {
- prom_panic(RELOC("couldn't get device tree root\n"));
- }
- allnextp = &RELOC(allnodes);
- mem_start = DOUBLEWORD_ALIGN(mem_start);
- new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);
- *allnextp = 0;
- return new_start;
-}
+ /* Init interface to Open Firmware and pickup bi-recs */
+ prom_init_client_services(pp);

-static unsigned long __init
-inspect_node(phandle node, struct device_node *dad,
- unsigned long mem_start, unsigned long mem_end,
- struct device_node ***allnextpp)
-{
- int l;
- phandle child;
- struct device_node *np;
- struct property *pp, **prev_propp;
- char *prev_name, *namep;
- unsigned char *valp;
- unsigned long offset = reloc_offset();
+ /* Init prom stdout device */
+ prom_init_stdout();

- np = (struct device_node *) mem_start;
- mem_start += sizeof(struct device_node);
- memset(np, 0, sizeof(*np));
- np->node = node;
- **allnextpp = PTRUNRELOC(np);
- *allnextpp = &np->allnext;
- if (dad != 0) {
- np->parent = PTRUNRELOC(dad);
- /* we temporarily use the `next' field as `last_child'. */
- if (dad->next == 0)
- dad->child = PTRUNRELOC(np);
- else
- dad->next->sibling = PTRUNRELOC(np);
- dad->next = np;
- }
+ /* check out if we have bi_recs */
+ _prom->bi_recs = prom_bi_rec_verify((struct bi_record *)r6);
+ if ( _prom->bi_recs != NULL )
+ RELOC(klimit) = PTRUNRELOC((unsigned long)_prom->bi_recs +
+ _prom->bi_recs->data[1]);

- /* get and store all properties */
- prev_propp = &np->properties;
- prev_name = RELOC("");
- for (;;) {
- pp = (struct property *) mem_start;
- namep = (char *) (pp + 1);
- pp->name = PTRUNRELOC(namep);
- if ((long) call_prom(RELOC("nextprop"), 3, 1, node, prev_name,
- namep) <= 0)
- break;
- mem_start = DOUBLEWORD_ALIGN((unsigned long)namep + strlen(namep) + 1);
- prev_name = namep;
- valp = (unsigned char *) mem_start;
- pp->value = PTRUNRELOC(valp);
- pp->length = (int)(long)
- call_prom(RELOC("getprop"), 4, 1, node, namep,
- valp, mem_end - mem_start);
- if (pp->length < 0)
- continue;
- if (pp->length > MAX_PROPERTY_LENGTH) {
- char path[128];
+ /* Default machine type. */
+ _systemcfg->platform = prom_find_machine_type();

- prom_print(RELOC("WARNING: ignoring large property "));
- /* It seems OF doesn't null-terminate the path :-( */
- memset(path, 0, sizeof(path));
- if (call_prom(RELOC("package-to-path"), 3, 1, node,
- path, sizeof(path)-1) > 0)
- prom_print(path);
- prom_print(namep);
- prom_print(RELOC(" length 0x"));
- prom_print_hex(pp->length);
- prom_print_nl();
+ /* On pSeries, copy the CPU hold code */
+ if (_systemcfg->platform == PLATFORM_PSERIES)
+ copy_and_flush(0, KERNELBASE - offset, 0x100, 0);

- continue;
- }
- mem_start = DOUBLEWORD_ALIGN(mem_start + pp->length);
- *prev_propp = PTRUNRELOC(pp);
- prev_propp = &pp->next;
- }
+ /* Start storing things at klimit */
+ mem = RELOC(klimit) - offset;

- /* Add a "linux_phandle" value */
- if (np->node) {
- u32 ibm_phandle = 0;
- int len;
+ /* Get the full OF pathname of the stdout device */
+ p = (char *) mem;
+ memset(p, 0, 256);
+ call_prom(RELOC("instance-to-path"), 3, 1, _prom->stdout, p, 255);
+ RELOC(of_stdout_device) = PTRUNRELOC(p);
+ mem += strlen(p) + 1;

- /* First see if "ibm,phandle" exists and use its value */
- len = (int)
- call_prom(RELOC("getprop"), 4, 1, node, RELOC("ibm,phandle"),
- &ibm_phandle, sizeof(ibm_phandle));
- if (len < 0) {
- np->linux_phandle = np->node;
- } else {
- np->linux_phandle = ibm_phandle;
- }
- }
+ getprop_rval = 1;
+ call_prom(RELOC("getprop"), 4, 1,
+ _prom->root, RELOC("#size-cells"),
+ &getprop_rval, sizeof(getprop_rval));
+ _prom->encode_phys_size = (getprop_rval == 1) ? 32 : 64;

- *prev_propp = 0;
+ /* Determine which cpu is actually running right _now_ */
+ if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
+ RELOC("cpu"), &getprop_rval,
+ sizeof(getprop_rval)) <= 0)
+ prom_panic(RELOC("cannot find boot cpu"));

- /* get the node's full name */
- l = (long) call_prom(RELOC("package-to-path"), 3, 1, node,
- (char *) mem_start, mem_end - mem_start);
- if (l >= 0) {
- np->full_name = PTRUNRELOC((char *) mem_start);
- *(char *)(mem_start + l) = 0;
- mem_start = DOUBLEWORD_ALIGN(mem_start + l + 1);
+ prom_cpu = (ihandle)(unsigned long)getprop_rval;
+ cpu_pkg = call_prom(RELOC("instance-to-package"), 1, 1, prom_cpu);
+ call_prom(RELOC("getprop"), 4, 1,
+ cpu_pkg, RELOC("reg"),
+ &getprop_rval, sizeof(getprop_rval));
+ _prom->cpu = (int)(unsigned long)getprop_rval;
+ _xPaca[0].xHwProcNum = _prom->cpu;
+
+ RELOC(boot_cpuid) = 0;
+
+#ifdef DEBUG_PROM
+ prom_print(RELOC("Booting CPU hw index = 0x"));
+ prom_print_hex(_prom->cpu);
+ prom_print_nl();
+#endif
+
+ /* Get the boot device and translate it to a full OF pathname. */
+ p = (char *) mem;
+ l = (long) call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
+ RELOC("bootpath"), p, 1<<20);
+ if (l > 0) {
+ p[l] = 0; /* should already be null-terminated */
+ RELOC(bootpath) = PTRUNRELOC(p);
+ mem += l + 1;
+ d = (char *) mem;
+ *d = 0;
+ call_prom(RELOC("canon"), 3, 1, p, d, 1<<20);
+ RELOC(bootdevice) = PTRUNRELOC(d);
+ mem = DOUBLEWORD_ALIGN(mem + strlen(d) + 1);
}

- /* do all our children */
- child = call_prom(RELOC("child"), 1, 1, node);
- while (child != (phandle)0) {
- mem_start = inspect_node(child, np, mem_start, mem_end,
- allnextpp);
- child = call_prom(RELOC("peer"), 1, 1, child);
+ RELOC(cmd_line[0]) = 0;
+ if ((long)_prom->chosen > 0) {
+ call_prom(RELOC("getprop"), 4, 1, _prom->chosen,
+ RELOC("bootargs"), p, sizeof(cmd_line));
+ if (p != NULL && p[0] != 0)
+ strlcpy(RELOC(cmd_line), p, sizeof(cmd_line));
}

- return mem_start;
-}
+ early_cmdline_parse();

-/*
- * finish_device_tree is called once things are running normally
- * (i.e. with text and data mapped to the address they were linked at).
- * It traverses the device tree and fills in the name, type,
- * {n_}addrs and {n_}intrs fields of each node.
- */
-void __init
-finish_device_tree(void)
-{
- unsigned long mem = klimit;
+ mem = prom_initialize_lmb(mem);

- virt_irq_init();
+ mem = prom_bi_rec_reserve(mem);

- mem = finish_node(allnodes, mem, NULL, 0, 0);
- dev_tree_size = mem - (unsigned long) allnodes;
+ mem = check_display(mem);

- mem = _ALIGN(mem, PAGE_SIZE);
- lmb_reserve(__pa(klimit), mem-klimit);
+ if (_systemcfg->platform != PLATFORM_POWERMAC)
+ prom_instantiate_rtas();
+
+ /* Initialize some system info into the Naca early... */
+ mem = prom_initialize_naca(mem);

- klimit = mem;
+ smt_setup();
+
+ /* If we are on an SMP machine, then we *MUST* do the
+ * following, regardless of whether we have an SMP
+ * kernel or not.
+ */
+ prom_hold_cpus(mem);

- rtas.dev = of_find_node_by_name(NULL, "rtas");
-}
+#ifdef DEBUG_PROM
+ prom_print(RELOC("copying OF device tree...\n"));
+#endif
+ mem = copy_device_tree(mem);

-static unsigned long __init
-finish_node(struct device_node *np, unsigned long mem_start,
- interpret_func *ifunc, int naddrc, int nsizec)
-{
- struct device_node *child;
- int *ip;
+ RELOC(klimit) = mem + offset;

- np->name = get_property(np, "name", 0);
- np->type = get_property(np, "device_type", 0);
+ lmb_reserve(0, __pa(RELOC(klimit)));

- /* get the device addresses and interrupts */
- if (ifunc != NULL)
- mem_start = ifunc(np, mem_start, naddrc, nsizec);
+ if (_systemcfg->platform == PLATFORM_PSERIES)
+ prom_initialize_tce_table();

- mem_start = finish_node_interrupts(np, mem_start);
+#ifdef CONFIG_PMAC_DART
+ if (_systemcfg->platform == PLATFORM_POWERMAC)
+ prom_initialize_dart_table();
+#endif

- /* Look for #address-cells and #size-cells properties. */
- ip = (int *) get_property(np, "#address-cells", 0);
- if (ip != NULL)
- naddrc = *ip;
- ip = (int *) get_property(np, "#size-cells", 0);
- if (ip != NULL)
- nsizec = *ip;
+#ifdef CONFIG_BOOTX_TEXT
+ if(_prom->disp_node) {
+ prom_print(RELOC("Setting up bi display...\n"));
+ setup_disp_fake_bi(_prom->disp_node);
+ }
+#endif /* CONFIG_BOOTX_TEXT */

- /* the f50 sets the name to 'display' and 'compatible' to what we
- * expect for the name -- Cort
- */
- if (!strcmp(np->name, "display"))
- np->name = get_property(np, "compatible", 0);
+ prom_print(RELOC("Calling quiesce ...\n"));
+ call_prom(RELOC("quiesce"), 0, 0);
+ phys = KERNELBASE - offset;

- if (!strcmp(np->name, "device-tree") || np->parent == NULL)
- ifunc = interpret_root_props;
- else if (np->type == 0)
- ifunc = NULL;
- else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
- ifunc = interpret_pci_props;
- else if (!strcmp(np->type, "dbdma"))
- ifunc = interpret_dbdma_props;
- else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
- ifunc = interpret_macio_props;
- else if (!strcmp(np->type, "isa"))
- ifunc = interpret_isa_props;
- else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
- ifunc = interpret_root_props;
- else if (!((ifunc == interpret_dbdma_props
- || ifunc == interpret_macio_props)
- && (!strcmp(np->type, "escc")
- || !strcmp(np->type, "media-bay"))))
- ifunc = NULL;
+ prom_print(RELOC("returning from prom_init\n"));
+ return phys;
+}

- for (child = np->child; child != NULL; child = child->sibling)
- mem_start = finish_node(child, mem_start, ifunc,
- naddrc, nsizec);

- return mem_start;
+/*
+ * Find the device_node with a given phandle.
+ */
+static struct device_node * __devinit
+find_phandle(phandle ph)
+{
+ struct device_node *np;
+
+ for (np = allnodes; np != 0; np = np->allnext)
+ if (np->linux_phandle == ph)
+ return np;
+ return NULL;
}

+
/*
* Find the interrupt parent of a node.
*/
@@ -1988,34 +1951,6 @@ intr_parent(struct device_node *p)
}

/*
- * Find out the size of each entry of the interrupts property
- * for a node.
- */
-static int __devinit
-prom_n_intr_cells(struct device_node *np)
-{
- struct device_node *p;
- unsigned int *icp;
-
- for (p = np; (p = intr_parent(p)) != NULL; ) {
- icp = (unsigned int *)
- get_property(p, "#interrupt-cells", NULL);
- if (icp != NULL)
- return *icp;
- if (get_property(p, "interrupt-controller", NULL) != NULL
- || get_property(p, "interrupt-map", NULL) != NULL) {
- printk("oops, node %s doesn't have #interrupt-cells\n",
- p->full_name);
- return 1;
- }
- }
-#ifdef DEBUG_IRQ
- printk("prom_n_intr_cells failed for %s\n", np->full_name);
-#endif
- return 1;
-}
-
-/*
* Map an interrupt from a device up to the platform interrupt
* descriptor.
*/
@@ -2114,8 +2049,33 @@ map_interrupt(unsigned int **irq, struct
}

/*
- * New version of finish_node_interrupts.
+ * Find out the size of each entry of the interrupts property
+ * for a node.
*/
+static int __devinit
+prom_n_intr_cells(struct device_node *np)
+{
+ struct device_node *p;
+ unsigned int *icp;
+
+ for (p = np; (p = intr_parent(p)) != NULL; ) {
+ icp = (unsigned int *)
+ get_property(p, "#interrupt-cells", NULL);
+ if (icp != NULL)
+ return *icp;
+ if (get_property(p, "interrupt-controller", NULL) != NULL
+ || get_property(p, "interrupt-map", NULL) != NULL) {
+ printk("oops, node %s doesn't have #interrupt-cells\n",
+ p->full_name);
+ return 1;
+ }
+ }
+#ifdef DEBUG_IRQ
+ printk("prom_n_intr_cells failed for %s\n", np->full_name);
+#endif
+ return 1;
+}
+
static unsigned long __init
finish_node_interrupts(struct device_node *np, unsigned long mem_start)
{
@@ -2168,6 +2128,87 @@ finish_node_interrupts(struct device_nod
return mem_start;
}

+static unsigned long __init
+finish_node(struct device_node *np, unsigned long mem_start,
+ interpret_func *ifunc, int naddrc, int nsizec)
+{
+ struct device_node *child;
+ int *ip;
+
+ np->name = get_property(np, "name", 0);
+ np->type = get_property(np, "device_type", 0);
+
+ /* get the device addresses and interrupts */
+ if (ifunc != NULL)
+ mem_start = ifunc(np, mem_start, naddrc, nsizec);
+
+ mem_start = finish_node_interrupts(np, mem_start);
+
+ /* Look for #address-cells and #size-cells properties. */
+ ip = (int *) get_property(np, "#address-cells", 0);
+ if (ip != NULL)
+ naddrc = *ip;
+ ip = (int *) get_property(np, "#size-cells", 0);
+ if (ip != NULL)
+ nsizec = *ip;
+
+ /* the f50 sets the name to 'display' and 'compatible' to what we
+ * expect for the name -- Cort
+ */
+ if (!strcmp(np->name, "display"))
+ np->name = get_property(np, "compatible", 0);
+
+ if (!strcmp(np->name, "device-tree") || np->parent == NULL)
+ ifunc = interpret_root_props;
+ else if (np->type == 0)
+ ifunc = NULL;
+ else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
+ ifunc = interpret_pci_props;
+ else if (!strcmp(np->type, "dbdma"))
+ ifunc = interpret_dbdma_props;
+ else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
+ ifunc = interpret_macio_props;
+ else if (!strcmp(np->type, "isa"))
+ ifunc = interpret_isa_props;
+ else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
+ ifunc = interpret_root_props;
+ else if (!((ifunc == interpret_dbdma_props
+ || ifunc == interpret_macio_props)
+ && (!strcmp(np->type, "escc")
+ || !strcmp(np->type, "media-bay"))))
+ ifunc = NULL;
+
+ for (child = np->child; child != NULL; child = child->sibling)
+ mem_start = finish_node(child, mem_start, ifunc,
+ naddrc, nsizec);
+
+ return mem_start;
+}
+
+/*
+ * finish_device_tree is called once things are running normally
+ * (i.e. with text and data mapped to the address they were linked at).
+ * It traverses the device tree and fills in the name, type,
+ * {n_}addrs and {n_}intrs fields of each node.
+ */
+void __init
+finish_device_tree(void)
+{
+ unsigned long mem = klimit;
+
+ virt_irq_init();
+
+ mem = finish_node(allnodes, mem, NULL, 0, 0);
+ dev_tree_size = mem - (unsigned long) allnodes;
+
+ mem = _ALIGN(mem, PAGE_SIZE);
+ lmb_reserve(__pa(klimit), mem-klimit);
+
+ klimit = mem;
+
+ rtas.dev = of_find_node_by_name(NULL, "rtas");
+}
+
int
prom_n_addr_cells(struct device_node* np)
{
@@ -2719,6 +2760,29 @@ struct device_node *of_node_get(struct d
EXPORT_SYMBOL(of_node_get);

/**
+ * of_node_cleanup - release a dynamically allocated node
+ * @arg: Node to be released
+ */
+static void of_node_cleanup(struct device_node *node)
+{
+ struct property *prop = node->properties;
+
+ if (!OF_IS_DYNAMIC(node))
+ return;
+ while (prop) {
+ struct property *next = prop->next;
+ kfree(prop->name);
+ kfree(prop->value);
+ kfree(prop);
+ prop = next;
+ }
+ kfree(node->intrs);
+ kfree(node->addrs);
+ kfree(node->full_name);
+ kfree(node);
+}
+
+/**
* of_node_put - Decrement refcount of a node
* @node: Node to dec refcount, NULL is supported to
* simplify writing of callers
@@ -2743,29 +2807,6 @@ void of_node_put(struct device_node *nod
EXPORT_SYMBOL(of_node_put);

/**
- * of_node_cleanup - release a dynamically allocated node
- * @arg: Node to be released
- */
-static void of_node_cleanup(struct device_node *node)
-{
- struct property *prop = node->properties;
-
- if (!OF_IS_DYNAMIC(node))
- return;
- while (prop) {
- struct property *next = prop->next;
- kfree(prop->name);
- kfree(prop->value);
- kfree(prop);
- prop = next;
- }
- kfree(node->intrs);
- kfree(node->addrs);
- kfree(node->full_name);
- kfree(node);
-}
-
-/**
* derive_parent - basically like dirname(1)
* @path: the full_name of a node to be added to the tree
*
@@ -2798,104 +2839,6 @@ static struct device_node *derive_parent
/*
* Routines for "runtime" addition and removal of device tree nodes.
*/
-
-/*
- * Given a path and a property list, construct an OF device node, add
- * it to the device tree and global list, and place it in
- * /proc/device-tree. This function may sleep.
- */
-int of_add_node(const char *path, struct property *proplist)
-{
- struct device_node *np;
- int err = 0;
-
- np = kmalloc(sizeof(struct device_node), GFP_KERNEL);
- if (!np)
- return -ENOMEM;
-
- memset(np, 0, sizeof(*np));
-
- np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
- if (!np->full_name) {
- kfree(np);
- return -ENOMEM;
- }
- strcpy(np->full_name, path);
-
- np->properties = proplist;
- OF_MARK_DYNAMIC(np);
- of_node_get(np);
- np->parent = derive_parent(path);
- if (!np->parent) {
- kfree(np);
- return -EINVAL; /* could also be ENOMEM, though */
- }
-
- if (0 != (err = of_finish_dynamic_node(np))) {
- kfree(np);
- return err;
- }
-
- write_lock(&devtree_lock);
- np->sibling = np->parent->child;
- np->allnext = allnodes;
- np->parent->child = np;
- allnodes = np;
- write_unlock(&devtree_lock);
-
- add_node_proc_entries(np);
-
- of_node_put(np->parent);
- of_node_put(np);
- return 0;
-}
-
-/*
- * Remove an OF device node from the system.
- * Caller should have already "gotten" np.
- */
-int of_remove_node(struct device_node *np)
-{
- struct device_node *parent, *child;
-
- parent = of_get_parent(np);
- if (!parent)
- return -EINVAL;
-
- if ((child = of_get_next_child(np, NULL))) {
- of_node_put(child);
- return -EBUSY;
- }
-
- write_lock(&devtree_lock);
- OF_MARK_STALE(np);
- remove_node_proc_entries(np);
- if (allnodes == np)
- allnodes = np->allnext;
- else {
- struct device_node *prev;
- for (prev = allnodes;
- prev->allnext != np;
- prev = prev->allnext)
- ;
- prev->allnext = np->allnext;
- }
-
- if (parent->child == np)
- parent->child = np->sibling;
- else {
- struct device_node *prevsib;
- for (prevsib = np->parent->child;
- prevsib->sibling != np;
- prevsib = prevsib->sibling)
- ;
- prevsib->sibling = np->sibling;
- }
- write_unlock(&devtree_lock);
- of_node_put(parent);
- return 0;
-}
-
#ifdef CONFIG_PROC_DEVICETREE
/*
* Add a node to /proc/device-tree.
@@ -2941,6 +2884,7 @@ static void remove_node_proc_entries(str
}
#endif /* CONFIG_PROC_DEVICETREE */

+
/*
* Fix up n_intrs and intrs fields in a new device node
*
@@ -3087,17 +3031,100 @@ out:
}

/*
- * Find the device_node with a given phandle.
+ * Given a path and a property list, construct an OF device node, add
+ * it to the device tree and global list, and place it in
+ * /proc/device-tree. This function may sleep.
*/
-static struct device_node * __devinit
-find_phandle(phandle ph)
+int of_add_node(const char *path, struct property *proplist)
{
struct device_node *np;
+ int err = 0;

- for (np = allnodes; np != 0; np = np->allnext)
- if (np->linux_phandle == ph)
- return np;
- return NULL;
+ np = kmalloc(sizeof(struct device_node), GFP_KERNEL);
+ if (!np)
+ return -ENOMEM;
+
+ memset(np, 0, sizeof(*np));
+
+ np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
+ if (!np->full_name) {
+ kfree(np);
+ return -ENOMEM;
+ }
+ strcpy(np->full_name, path);
+
+ np->properties = proplist;
+ OF_MARK_DYNAMIC(np);
+ of_node_get(np);
+ np->parent = derive_parent(path);
+ if (!np->parent) {
+ kfree(np);
+ return -EINVAL; /* could also be ENOMEM, though */
+ }
+
+ if (0 != (err = of_finish_dynamic_node(np))) {
+ kfree(np);
+ return err;
+ }
+
+ write_lock(&devtree_lock);
+ np->sibling = np->parent->child;
+ np->allnext = allnodes;
+ np->parent->child = np;
+ allnodes = np;
+ write_unlock(&devtree_lock);
+
+ add_node_proc_entries(np);
+
+ of_node_put(np->parent);
+ of_node_put(np);
+ return 0;
+}
+
+/*
+ * Remove an OF device node from the system.
+ * Caller should have already "gotten" np.
+ */
+int of_remove_node(struct device_node *np)
+{
+ struct device_node *parent, *child;
+
+ parent = of_get_parent(np);
+ if (!parent)
+ return -EINVAL;
+
+ if ((child = of_get_next_child(np, NULL))) {
+ of_node_put(child);
+ return -EBUSY;
+ }
+
+ write_lock(&devtree_lock);
+ OF_MARK_STALE(np);
+ remove_node_proc_entries(np);
+ if (allnodes == np)
+ allnodes = np->allnext;
+ else {
+ struct device_node *prev;
+ for (prev = allnodes;
+ prev->allnext != np;
+ prev = prev->allnext)
+ ;
+ prev->allnext = np->allnext;
+ }
+
+ if (parent->child == np)
+ parent->child = np->sibling;
+ else {
+ struct device_node *prevsib;
+ for (prevsib = np->parent->child;
+ prevsib->sibling != np;
+ prevsib = prevsib->sibling)
+ ;
+ prevsib->sibling = np->sibling;
+ }
+ write_unlock(&devtree_lock);
+ of_node_put(parent);
+ return 0;
}

/*
@@ -3183,55 +3210,3 @@ print_properties(struct device_node *np)
}
}
#endif
-
-
-/* Verify bi_recs are good */
-static struct bi_record *
-prom_bi_rec_verify(struct bi_record *bi_recs)
-{
- struct bi_record *first, *last;
-
- if ( bi_recs == NULL || bi_recs->tag != BI_FIRST )
- return NULL;
-
- last = (struct bi_record *)(long)bi_recs->data[0];
- if ( last == NULL || last->tag != BI_LAST )
- return NULL;
-
- first = (struct bi_record *)(long)last->data[0];
- if ( first == NULL || first != bi_recs )
- return NULL;
-
- return bi_recs;
-}
-
-static unsigned long
-prom_bi_rec_reserve(unsigned long mem)
-{
- unsigned long offset = reloc_offset();
- struct prom_t *_prom = PTRRELOC(&prom);
- struct bi_record *rec;
-
- if ( _prom->bi_recs != NULL) {
-
- for ( rec=_prom->bi_recs;
- rec->tag != BI_LAST;
- rec=bi_rec_next(rec) ) {
- switch (rec->tag) {
-#ifdef CONFIG_BLK_DEV_INITRD
- case BI_INITRD:
- lmb_reserve(rec->data[0], rec->data[1]);
- break;
-#endif /* CONFIG_BLK_DEV_INITRD */
- }
- }
- /* The next use of this field will be after relocation
- * is enabled, so convert this physical address into a
- * virtual address.
- */
- _prom->bi_recs = PTRUNRELOC(_prom->bi_recs);
- }
-
- return mem;
-}
-
--
Anyone who quotes me in their signature is an idiot -- Rusty Russell

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:02    [W:0.096 / U:0.336 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site