Commit d6d33678 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: Make finish_device_tree use lmb_alloc, not klimit

From: Rusty Russell <rusty@rustcorp.com.au>

finish_device_tree simply allocates nodes by incrementing klimit (ie.  using
memory on top of the kernel).  Change it to figure out how much memory it
needs, then use lmb_alloc to allocate that, then fill it in.

This gets rid of the only manipulation of klimit after prom_init.
parent 196431fd
...@@ -47,8 +47,6 @@ int force_printk_to_btext = 0; ...@@ -47,8 +47,6 @@ int force_printk_to_btext = 0;
boot_infos_t disp_bi; boot_infos_t disp_bi;
extern char *klimit;
/* This function will enable the early boot text when doing OF booting. This /* This function will enable the early boot text when doing OF booting. This
* way, xmon output should work too * way, xmon output should work too
*/ */
......
...@@ -123,7 +123,7 @@ struct pci_intr_map { ...@@ -123,7 +123,7 @@ struct pci_intr_map {
typedef unsigned long interpret_func(struct device_node *, unsigned long, typedef unsigned long interpret_func(struct device_node *, unsigned long,
int, int); int, int, int);
#ifndef FB_MAX /* avoid pulling in all of the fb stuff */ #ifndef FB_MAX /* avoid pulling in all of the fb stuff */
#define FB_MAX 8 #define FB_MAX 8
...@@ -2064,7 +2064,8 @@ map_interrupt(unsigned int **irq, struct device_node **ictrler, ...@@ -2064,7 +2064,8 @@ map_interrupt(unsigned int **irq, struct device_node **ictrler,
} }
static unsigned long __init static unsigned long __init
finish_node_interrupts(struct device_node *np, unsigned long mem_start) finish_node_interrupts(struct device_node *np, unsigned long mem_start,
int measure_only)
{ {
unsigned int *ints; unsigned int *ints;
int intlen, intrcells; int intlen, intrcells;
...@@ -2081,6 +2082,9 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start) ...@@ -2081,6 +2082,9 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start)
np->intrs = (struct interrupt_info *) mem_start; np->intrs = (struct interrupt_info *) mem_start;
mem_start += intlen * sizeof(struct interrupt_info); mem_start += intlen * sizeof(struct interrupt_info);
if (measure_only)
return mem_start;
for (i = 0; i < intlen; ++i) { for (i = 0; i < intlen; ++i) {
np->intrs[i].line = 0; np->intrs[i].line = 0;
np->intrs[i].sense = 1; np->intrs[i].sense = 1;
...@@ -2117,7 +2121,7 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start) ...@@ -2117,7 +2121,7 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start)
static unsigned long __init static unsigned long __init
interpret_pci_props(struct device_node *np, unsigned long mem_start, interpret_pci_props(struct device_node *np, unsigned long mem_start,
int naddrc, int nsizec) int naddrc, int nsizec, int measure_only)
{ {
struct address_range *adr; struct address_range *adr;
struct pci_reg_property *pci_addrs; struct pci_reg_property *pci_addrs;
...@@ -2129,9 +2133,11 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start, ...@@ -2129,9 +2133,11 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start,
i = 0; i = 0;
adr = (struct address_range *) mem_start; adr = (struct address_range *) mem_start;
while ((l -= sizeof(struct pci_reg_property)) >= 0) { while ((l -= sizeof(struct pci_reg_property)) >= 0) {
if (!measure_only) {
adr[i].space = pci_addrs[i].addr.a_hi; adr[i].space = pci_addrs[i].addr.a_hi;
adr[i].address = pci_addrs[i].addr.a_lo; adr[i].address = pci_addrs[i].addr.a_lo;
adr[i].size = pci_addrs[i].size_lo; adr[i].size = pci_addrs[i].size_lo;
}
++i; ++i;
} }
np->addrs = adr; np->addrs = adr;
...@@ -2143,7 +2149,7 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start, ...@@ -2143,7 +2149,7 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start,
static unsigned long __init static unsigned long __init
interpret_dbdma_props(struct device_node *np, unsigned long mem_start, interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
int naddrc, int nsizec) int naddrc, int nsizec, int measure_only)
{ {
struct reg_property32 *rp; struct reg_property32 *rp;
struct address_range *adr; struct address_range *adr;
...@@ -2164,9 +2170,11 @@ interpret_dbdma_props(struct device_node *np, unsigned long mem_start, ...@@ -2164,9 +2170,11 @@ interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
i = 0; i = 0;
adr = (struct address_range *) mem_start; adr = (struct address_range *) mem_start;
while ((l -= sizeof(struct reg_property32)) >= 0) { while ((l -= sizeof(struct reg_property32)) >= 0) {
if (!measure_only) {
adr[i].space = 2; adr[i].space = 2;
adr[i].address = rp[i].address + base_address; adr[i].address = rp[i].address + base_address;
adr[i].size = rp[i].size; adr[i].size = rp[i].size;
}
++i; ++i;
} }
np->addrs = adr; np->addrs = adr;
...@@ -2179,7 +2187,7 @@ interpret_dbdma_props(struct device_node *np, unsigned long mem_start, ...@@ -2179,7 +2187,7 @@ interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
static unsigned long __init static unsigned long __init
interpret_macio_props(struct device_node *np, unsigned long mem_start, interpret_macio_props(struct device_node *np, unsigned long mem_start,
int naddrc, int nsizec) int naddrc, int nsizec, int measure_only)
{ {
struct reg_property32 *rp; struct reg_property32 *rp;
struct address_range *adr; struct address_range *adr;
...@@ -2200,9 +2208,11 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start, ...@@ -2200,9 +2208,11 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start,
i = 0; i = 0;
adr = (struct address_range *) mem_start; adr = (struct address_range *) mem_start;
while ((l -= sizeof(struct reg_property32)) >= 0) { while ((l -= sizeof(struct reg_property32)) >= 0) {
if (!measure_only) {
adr[i].space = 2; adr[i].space = 2;
adr[i].address = rp[i].address + base_address; adr[i].address = rp[i].address + base_address;
adr[i].size = rp[i].size; adr[i].size = rp[i].size;
}
++i; ++i;
} }
np->addrs = adr; np->addrs = adr;
...@@ -2215,7 +2225,7 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start, ...@@ -2215,7 +2225,7 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start,
static unsigned long __init static unsigned long __init
interpret_isa_props(struct device_node *np, unsigned long mem_start, interpret_isa_props(struct device_node *np, unsigned long mem_start,
int naddrc, int nsizec) int naddrc, int nsizec, int measure_only)
{ {
struct isa_reg_property *rp; struct isa_reg_property *rp;
struct address_range *adr; struct address_range *adr;
...@@ -2226,9 +2236,11 @@ interpret_isa_props(struct device_node *np, unsigned long mem_start, ...@@ -2226,9 +2236,11 @@ interpret_isa_props(struct device_node *np, unsigned long mem_start,
i = 0; i = 0;
adr = (struct address_range *) mem_start; adr = (struct address_range *) mem_start;
while ((l -= sizeof(struct reg_property)) >= 0) { while ((l -= sizeof(struct reg_property)) >= 0) {
if (!measure_only) {
adr[i].space = rp[i].space; adr[i].space = rp[i].space;
adr[i].address = rp[i].address; adr[i].address = rp[i].address;
adr[i].size = rp[i].size; adr[i].size = rp[i].size;
}
++i; ++i;
} }
np->addrs = adr; np->addrs = adr;
...@@ -2241,7 +2253,7 @@ interpret_isa_props(struct device_node *np, unsigned long mem_start, ...@@ -2241,7 +2253,7 @@ interpret_isa_props(struct device_node *np, unsigned long mem_start,
static unsigned long __init static unsigned long __init
interpret_root_props(struct device_node *np, unsigned long mem_start, interpret_root_props(struct device_node *np, unsigned long mem_start,
int naddrc, int nsizec) int naddrc, int nsizec, int measure_only)
{ {
struct address_range *adr; struct address_range *adr;
int i, l; int i, l;
...@@ -2253,9 +2265,11 @@ interpret_root_props(struct device_node *np, unsigned long mem_start, ...@@ -2253,9 +2265,11 @@ interpret_root_props(struct device_node *np, unsigned long mem_start,
i = 0; i = 0;
adr = (struct address_range *) mem_start; adr = (struct address_range *) mem_start;
while ((l -= rpsize) >= 0) { while ((l -= rpsize) >= 0) {
if (!measure_only) {
adr[i].space = 0; adr[i].space = 0;
adr[i].address = rp[naddrc - 1]; adr[i].address = rp[naddrc - 1];
adr[i].size = rp[naddrc + nsizec - 1]; adr[i].size = rp[naddrc + nsizec - 1];
}
++i; ++i;
rp += naddrc + nsizec; rp += naddrc + nsizec;
} }
...@@ -2269,7 +2283,7 @@ interpret_root_props(struct device_node *np, unsigned long mem_start, ...@@ -2269,7 +2283,7 @@ interpret_root_props(struct device_node *np, unsigned long mem_start,
static unsigned long __init static unsigned long __init
finish_node(struct device_node *np, unsigned long mem_start, finish_node(struct device_node *np, unsigned long mem_start,
interpret_func *ifunc, int naddrc, int nsizec) interpret_func *ifunc, int naddrc, int nsizec, int measure_only)
{ {
struct device_node *child; struct device_node *child;
int *ip; int *ip;
...@@ -2284,9 +2298,9 @@ finish_node(struct device_node *np, unsigned long mem_start, ...@@ -2284,9 +2298,9 @@ finish_node(struct device_node *np, unsigned long mem_start,
/* get the device addresses and interrupts */ /* get the device addresses and interrupts */
if (ifunc != NULL) if (ifunc != NULL)
mem_start = ifunc(np, mem_start, naddrc, nsizec); mem_start = ifunc(np, mem_start, naddrc, nsizec, measure_only);
mem_start = finish_node_interrupts(np, mem_start); mem_start = finish_node_interrupts(np, mem_start, measure_only);
/* Look for #address-cells and #size-cells properties. */ /* Look for #address-cells and #size-cells properties. */
ip = (int *) get_property(np, "#address-cells", 0); ip = (int *) get_property(np, "#address-cells", 0);
...@@ -2324,7 +2338,7 @@ finish_node(struct device_node *np, unsigned long mem_start, ...@@ -2324,7 +2338,7 @@ finish_node(struct device_node *np, unsigned long mem_start,
for (child = np->child; child != NULL; child = child->sibling) for (child = np->child; child != NULL; child = child->sibling)
mem_start = finish_node(child, mem_start, ifunc, mem_start = finish_node(child, mem_start, ifunc,
naddrc, nsizec); naddrc, nsizec, measure_only);
return mem_start; return mem_start;
} }
...@@ -2342,14 +2356,11 @@ finish_device_tree(void) ...@@ -2342,14 +2356,11 @@ finish_device_tree(void)
virt_irq_init(); virt_irq_init();
mem = finish_node(allnodes, mem, NULL, 0, 0); dev_tree_size = finish_node(allnodes, 0, NULL, 0, 0, 1);
dev_tree_size = mem - (unsigned long) allnodes; mem = (long)abs_to_virt(lmb_alloc(dev_tree_size,
__alignof__(struct device_node)));
mem = _ALIGN(mem, PAGE_SIZE); if (finish_node(allnodes, mem, NULL, 0, 0, 0) != mem + dev_tree_size)
lmb_reserve(__pa(klimit), mem-klimit); BUG();
klimit = mem;
rtas.dev = of_find_node_by_name(NULL, "rtas"); rtas.dev = of_find_node_by_name(NULL, "rtas");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment