From eb6de2863750e696201780283e4c9ada19b4728e Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 28 Feb 2007 14:12:29 +1100 Subject: [POWERPC] Allow duplicate lmb_reserve() calls At present calling lmb_reserve() (and hence lmb_add_region()) twice for exactly the same memory region will cause strange behaviour. This makes life difficult when booting from a flat device tree with memory reserve map. Which regions are automatically reserved by the kernel has changed over time, so it's quite possible a newer kernel could attempt to auto-reserve a region which is also explicitly listed in the device tree's reserve map, leading to trouble. This patch avoids the problem by making lmb_reserve() ignore a call to reserve a previously reserved region. It also removes a now redundant test designed to avoid one specific case of the problem noted above. At present, this patch deals only with duplicate reservations of an identical region. Attempting to reserve two different, but overlapping regions will still cause problems. I might post another patch later dealing with this case, but I'm avoiding it now since it is substantially more complicated to deal with, less likely to occur and more likely to indicate a genuine bug elsewhere if it does occur. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 8d52b23348bd..15ece3abfb37 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -954,9 +954,6 @@ static void __init early_reserve_mem(void) size = *(reserve_map++); if (size == 0) break; - /* skip if the reservation is for the blob */ - if (base == self_base && size == self_size) - continue; DBG("reserving: %llx -> %llx\n", base, size); lmb_reserve(base, size); } -- cgit v1.2.2 From 30437b3e743f33e9b68f813ca24e547aa9fcf7d7 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 28 Feb 2007 14:12:29 +1100 Subject: [POWERPC] Automatically lmb_reserve() initrd At present, when an initrd is passed to the kernel used flat device tree properties, the memory the initrd occupies must also be reserved in the flat tree's reserve map, or the kernel may overwrite it. That makes life more complicated than it could be for the bootwrapper. This patch makes the kernel automatically reserve the initrd's space. That in turn requires parsing the initrd parameters earlier than they are currently, in early_init_dt_scan_chosen() instead of check_for_initrd(). Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 15ece3abfb37..ef6bfb70b24a 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -719,6 +719,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, int depth, void *data) { unsigned long *lprop; + u32 *prop; unsigned long l; char *p; @@ -760,6 +761,22 @@ static int __init early_init_dt_scan_chosen(unsigned long node, crashk_res.end = crashk_res.start + *lprop - 1; #endif +#ifdef CONFIG_BLK_DEV_INITRD + DBG("Looking for initrd properties... "); + prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l); + if (prop) { + initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4)); + prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l); + if (prop) { + initrd_end = (unsigned long)__va(of_read_ulong(prop, l/4)); + initrd_below_start_ok = 1; + } else { + initrd_start = 0; + } + } + DBG("initrd_start=0x%lx initrd_end=0x%lx\n", initrd_start, initrd_end); +#endif /* CONFIG_BLK_DEV_INITRD */ + /* Retreive command line */ p = of_get_flat_dt_prop(node, "bootargs", &l); if (p != NULL && l > 0) @@ -926,6 +943,12 @@ static void __init early_reserve_mem(void) self_size = initial_boot_params->totalsize; lmb_reserve(self_base, self_size); +#ifdef CONFIG_BLK_DEV_INITRD + /* then reserve the initrd, if any */ + if (initrd_start && (initrd_end > initrd_start)) + lmb_reserve(__pa(initrd_start), initrd_end - initrd_start); +#endif /* CONFIG_BLK_DEV_INITRD */ + #ifdef CONFIG_PPC32 /* * Handle the case where we might be booting from an old kexec -- cgit v1.2.2 From 0e56efc7dcd1eb5004363e52bdbe801783245638 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 3 Apr 2007 10:54:01 +1000 Subject: [POWERPC] Rename get_property to of_get_property This is more consistent and gets us closer to the Sparc code. We add a get_property define for compatibility during the change over. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index ef6bfb70b24a..622472818723 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -400,8 +400,8 @@ static unsigned long __init unflatten_dt_node(unsigned long mem, } if (allnextpp) { *prev_pp = NULL; - np->name = get_property(np, "name", NULL); - np->type = get_property(np, "device_type", NULL); + np->name = of_get_property(np, "name", NULL); + np->type = of_get_property(np, "device_type", NULL); if (!np->name) np->name = ""; @@ -1048,7 +1048,7 @@ prom_n_addr_cells(struct device_node* np) do { if (np->parent) np = np->parent; - ip = get_property(np, "#address-cells", NULL); + ip = of_get_property(np, "#address-cells", NULL); if (ip != NULL) return *ip; } while (np->parent); @@ -1064,7 +1064,7 @@ prom_n_size_cells(struct device_node* np) do { if (np->parent) np = np->parent; - ip = get_property(np, "#size-cells", NULL); + ip = of_get_property(np, "#size-cells", NULL); if (ip != NULL) return *ip; } while (np->parent); @@ -1136,7 +1136,7 @@ int device_is_compatible(const struct device_node *device, const char *compat) const char* cp; int cplen, l; - cp = get_property(device, "compatible", &cplen); + cp = of_get_property(device, "compatible", &cplen); if (cp == NULL) return 0; while (cplen > 0) { @@ -1547,8 +1547,8 @@ static int of_finish_dynamic_node(struct device_node *node) int err = 0; const phandle *ibm_phandle; - node->name = get_property(node, "name", NULL); - node->type = get_property(node, "device_type", NULL); + node->name = of_get_property(node, "name", NULL); + node->type = of_get_property(node, "device_type", NULL); if (!parent) { err = -ENODEV; @@ -1562,7 +1562,7 @@ static int of_finish_dynamic_node(struct device_node *node) return -ENODEV; /* fix up new node's linux_phandle field */ - if ((ibm_phandle = get_property(node, "ibm,phandle", NULL))) + if ((ibm_phandle = of_get_property(node, "ibm,phandle", NULL))) node->linux_phandle = *ibm_phandle; out: @@ -1625,13 +1625,13 @@ EXPORT_SYMBOL(of_find_property); * Find a property with a given name for a given node * and return the value. */ -const void *get_property(const struct device_node *np, const char *name, +const void *of_get_property(const struct device_node *np, const char *name, int *lenp) { struct property *pp = of_find_property(np,name,lenp); return pp ? pp->value : NULL; } -EXPORT_SYMBOL(get_property); +EXPORT_SYMBOL(of_get_property); /* * Add a property to a node @@ -1762,10 +1762,10 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist * fallback to "reg" property and assume no threads */ - intserv = get_property(np, "ibm,ppc-interrupt-server#s", + intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &plen); if (intserv == NULL) { - const u32 *reg = get_property(np, "reg", NULL); + const u32 *reg = of_get_property(np, "reg", NULL); if (reg == NULL) continue; if (*reg == hardid) { -- cgit v1.2.2 From 7a92f74f98bde8498c98aad6cac5da5a87dd0bf4 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 3 Apr 2007 10:55:39 +1000 Subject: [POWERPC] Rename device_is_compatible to of_device_is_compatible This is more consistent and gets us closer to the Sparc code. We add a device_is_compatible define for compatibility during the change over. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 622472818723..d2840b66c8c1 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1131,7 +1131,8 @@ EXPORT_SYMBOL(find_all_nodes); /** Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */ -int device_is_compatible(const struct device_node *device, const char *compat) +int of_device_is_compatible(const struct device_node *device, + const char *compat) { const char* cp; int cplen, l; @@ -1149,7 +1150,7 @@ int device_is_compatible(const struct device_node *device, const char *compat) return 0; } -EXPORT_SYMBOL(device_is_compatible); +EXPORT_SYMBOL(of_device_is_compatible); /** @@ -1163,7 +1164,7 @@ int machine_is_compatible(const char *compat) root = of_find_node_by_path("/"); if (root) { - rc = device_is_compatible(root, compat); + rc = of_device_is_compatible(root, compat); of_node_put(root); } return rc; @@ -1184,7 +1185,7 @@ struct device_node *find_compatible_devices(const char *type, if (type != NULL && !(np->type != 0 && strcasecmp(np->type, type) == 0)) continue; - if (device_is_compatible(np, compat)) { + if (of_device_is_compatible(np, compat)) { *prevp = np; prevp = &np->next; } @@ -1300,7 +1301,7 @@ struct device_node *of_find_compatible_node(struct device_node *from, if (type != NULL && !(np->type != 0 && strcasecmp(np->type, type) == 0)) continue; - if (device_is_compatible(np, compatible) && of_node_get(np)) + if (of_device_is_compatible(np, compatible) && of_node_get(np)) break; } of_node_put(from); -- cgit v1.2.2 From a8bda5dd4f99d6469f3c0dc362db3cce8a4d6416 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 3 Apr 2007 10:56:50 +1000 Subject: [POWERPC] Rename prom_n_addr_cells to of_n_addr_cells This is more consistent and gets us closer to the Sparc code. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index d2840b66c8c1..08d619756d33 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1041,8 +1041,7 @@ void __init early_init_devtree(void *params) #undef printk -int -prom_n_addr_cells(struct device_node* np) +int of_n_addr_cells(struct device_node* np) { const int *ip; do { @@ -1055,7 +1054,7 @@ prom_n_addr_cells(struct device_node* np) /* No #address-cells property for the root node, default to 1 */ return 1; } -EXPORT_SYMBOL(prom_n_addr_cells); +EXPORT_SYMBOL(of_n_addr_cells); int prom_n_size_cells(struct device_node* np) -- cgit v1.2.2 From 9213feea6e197f8507ec855337798cc3388f5570 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 3 Apr 2007 10:57:48 +1000 Subject: [POWERPC] Rename prom_n_size_cells to of_n_size_cells This is more consistent and gets us closer to the Sparc code. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 08d619756d33..2890ce3d6641 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1056,8 +1056,7 @@ int of_n_addr_cells(struct device_node* np) } EXPORT_SYMBOL(of_n_addr_cells); -int -prom_n_size_cells(struct device_node* np) +int of_n_size_cells(struct device_node* np) { const int* ip; do { @@ -1070,7 +1069,7 @@ prom_n_size_cells(struct device_node* np) /* No #size-cells property for the root node, default to 1 */ return 1; } -EXPORT_SYMBOL(prom_n_size_cells); +EXPORT_SYMBOL(of_n_size_cells); /** * Construct and return a list of the device_nodes with a given name. -- cgit v1.2.2 From 1a38147ed0737a9c01dbf5f2ca47fd2a0aa5cb55 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 3 Apr 2007 10:58:52 +1000 Subject: [POWERPC] Make struct property's value a void * Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 2890ce3d6641..ec6921c54a07 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -390,12 +390,13 @@ static unsigned long __init unflatten_dt_node(unsigned long mem, if (allnextpp) { pp->name = "name"; pp->length = sz; - pp->value = (unsigned char *)(pp + 1); + pp->value = pp + 1; *prev_pp = pp; prev_pp = &pp->next; memcpy(pp->value, ps, sz - 1); ((char *)pp->value)[sz - 1] = 0; - DBG("fixed up name for %s -> %s\n", pathp, pp->value); + DBG("fixed up name for %s -> %s\n", pathp, + (char *)pp->value); } } if (allnextpp) { -- cgit v1.2.2 From 4bf56e1725a298fb430977cf143ad3a36c91b46a Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 24 Apr 2007 13:48:41 +1000 Subject: [POWERPC] Remove find_compatible_devices This is an old interface and is replaced by of_find_compatible_node. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index ec6921c54a07..2f7e6ec215f8 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1170,30 +1170,6 @@ int machine_is_compatible(const char *compat) } EXPORT_SYMBOL(machine_is_compatible); -/** - * Construct and return a list of the device_nodes with a given type - * and compatible property. - */ -struct device_node *find_compatible_devices(const char *type, - const char *compat) -{ - struct device_node *head, **prevp, *np; - - prevp = &head; - for (np = allnodes; np != 0; np = np->allnext) { - if (type != NULL - && !(np->type != 0 && strcasecmp(np->type, type) == 0)) - continue; - if (of_device_is_compatible(np, compat)) { - *prevp = np; - prevp = &np->next; - } - } - *prevp = NULL; - return head; -} -EXPORT_SYMBOL(find_compatible_devices); - /** * Find the device_node with a given full_name. */ -- cgit v1.2.2 From 112466b4d0036b3244509d01dbbf3c8caec52a23 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 24 Apr 2007 13:49:47 +1000 Subject: [POWERPC] Remove find_all_nodes This old interface has no more users. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 2f7e6ec215f8..911ec77a42d2 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1110,23 +1110,6 @@ struct device_node *find_type_devices(const char *type) } EXPORT_SYMBOL(find_type_devices); -/** - * Returns all nodes linked together - */ -struct device_node *find_all_nodes(void) -{ - struct device_node *head, **prevp, *np; - - prevp = &head; - for (np = allnodes; np != 0; np = np->allnext) { - *prevp = np; - prevp = &np->next; - } - *prevp = NULL; - return head; -} -EXPORT_SYMBOL(find_all_nodes); - /** Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */ -- cgit v1.2.2 From 8c8dc322486d5394dc981bef9276dd0ce6c8d1ce Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 24 Apr 2007 13:50:55 +1000 Subject: [POWERPC] Remove old interface find_path_device Replaced by of_find_node_by_path. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 911ec77a42d2..17c41fefecf2 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1153,20 +1153,6 @@ int machine_is_compatible(const char *compat) } EXPORT_SYMBOL(machine_is_compatible); -/** - * Find the device_node with a given full_name. - */ -struct device_node *find_path_device(const char *path) -{ - struct device_node *np; - - for (np = allnodes; np != 0; np = np->allnext) - if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0) - return np; - return NULL; -} -EXPORT_SYMBOL(find_path_device); - /******* * * New implementation of the OF "find" APIs, return a refcounted -- cgit v1.2.2 From 1658ab66781d918f604c6069c5cf9a94b6f52f84 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 24 Apr 2007 13:51:59 +1000 Subject: [POWERPC] Remove old interface find_type_devices Replaced by of_find_node_by_type. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 17c41fefecf2..860c88b2f6d1 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1091,25 +1091,6 @@ struct device_node *find_devices(const char *name) } EXPORT_SYMBOL(find_devices); -/** - * Construct and return a list of the device_nodes with a given type. - */ -struct device_node *find_type_devices(const char *type) -{ - struct device_node *head, **prevp, *np; - - prevp = &head; - for (np = allnodes; np != 0; np = np->allnext) { - if (np->type != 0 && strcasecmp(np->type, type) == 0) { - *prevp = np; - prevp = &np->next; - } - } - *prevp = NULL; - return head; -} -EXPORT_SYMBOL(find_type_devices); - /** Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */ -- cgit v1.2.2 From 30686ba6d56858657829d3eb524ed73e5dc98d2b Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 24 Apr 2007 13:53:04 +1000 Subject: [POWERPC] Remove old interface find_devices Replace uses with of_find_node_by_name and for_each_node_by_name. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 860c88b2f6d1..caef555f2dc0 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1072,25 +1072,6 @@ int of_n_size_cells(struct device_node* np) } EXPORT_SYMBOL(of_n_size_cells); -/** - * Construct and return a list of the device_nodes with a given name. - */ -struct device_node *find_devices(const char *name) -{ - struct device_node *head, **prevp, *np; - - prevp = &head; - for (np = allnodes; np != 0; np = np->allnext) { - if (np->name != 0 && strcasecmp(np->name, name) == 0) { - *prevp = np; - prevp = &np->next; - } - } - *prevp = NULL; - return head; -} -EXPORT_SYMBOL(find_devices); - /** Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */ -- cgit v1.2.2