#include <asm/pci-bridge.h>
#include <asm/phyp_dump.h>
#include <asm/kexec.h>
+#include <mm/mmu_decl.h>
#ifdef DEBUG
#define DBG(fmt...) printk(KERN_ERR fmt)
}
#endif
lmb_add(base, size);
+
+ memstart_addr = min((u64)memstart_addr, base);
}
+
return 0;
}
}
#ifdef CONFIG_PHYP_DUMP
+/**
+ * phyp_dump_calculate_reserve_size() - reserve variable boot area 5% or arg
+ *
+ * Function to find the largest size we need to reserve
+ * during early boot process.
+ *
+ * It either looks for boot param and returns that OR
+ * returns larger of 256 or 5% rounded down to multiples of 256MB.
+ *
+ */
+static inline unsigned long phyp_dump_calculate_reserve_size(void)
+{
+ unsigned long tmp;
+
+ if (phyp_dump_info->reserve_bootvar)
+ return phyp_dump_info->reserve_bootvar;
+
+ /* divide by 20 to get 5% of value */
+ tmp = lmb_end_of_DRAM();
+ do_div(tmp, 20);
+
+ /* round it down in multiples of 256 */
+ tmp = tmp & ~0x0FFFFFFFUL;
+
+ return (tmp > PHYP_DUMP_RMR_END ? tmp : PHYP_DUMP_RMR_END);
+}
+
/**
* phyp_dump_reserve_mem() - reserve all not-yet-dumped mmemory
*
static void __init phyp_dump_reserve_mem(void)
{
unsigned long base, size;
+ unsigned long variable_reserve_size;
+
if (!phyp_dump_info->phyp_dump_configured) {
printk(KERN_ERR "Phyp-dump not supported on this hardware\n");
return;
return;
}
+ variable_reserve_size = phyp_dump_calculate_reserve_size();
+
if (phyp_dump_info->phyp_dump_is_active) {
/* Reserve *everything* above RMR.Area freed by userland tools*/
- base = PHYP_DUMP_RMR_END;
+ base = variable_reserve_size;
size = lmb_end_of_DRAM() - base;
/* XXX crashed_ram_end is wrong, since it may be beyond
} else {
size = phyp_dump_info->cpu_state_size +
phyp_dump_info->hpte_region_size +
- PHYP_DUMP_RMR_END;
+ variable_reserve_size;
base = lmb_end_of_DRAM() - size;
lmb_reserve(base, size);
phyp_dump_info->init_reserve_start = base;
*/
void of_attach_node(struct device_node *np)
{
- write_lock(&devtree_lock);
+ unsigned long flags;
+
+ write_lock_irqsave(&devtree_lock, flags);
np->sibling = np->parent->child;
np->allnext = allnodes;
np->parent->child = np;
allnodes = np;
- write_unlock(&devtree_lock);
+ write_unlock_irqrestore(&devtree_lock, flags);
}
/*
void of_detach_node(struct device_node *np)
{
struct device_node *parent;
+ unsigned long flags;
- write_lock(&devtree_lock);
+ write_lock_irqsave(&devtree_lock, flags);
parent = np->parent;
if (!parent)
of_node_set_flag(np, OF_DETACHED);
out_unlock:
- write_unlock(&devtree_lock);
+ write_unlock_irqrestore(&devtree_lock, flags);
}
#ifdef CONFIG_PPC_PSERIES
int prom_add_property(struct device_node* np, struct property* prop)
{
struct property **next;
+ unsigned long flags;
prop->next = NULL;
- write_lock(&devtree_lock);
+ write_lock_irqsave(&devtree_lock, flags);
next = &np->properties;
while (*next) {
if (strcmp(prop->name, (*next)->name) == 0) {
/* duplicate ! don't insert it */
- write_unlock(&devtree_lock);
+ write_unlock_irqrestore(&devtree_lock, flags);
return -1;
}
next = &(*next)->next;
}
*next = prop;
- write_unlock(&devtree_lock);
+ write_unlock_irqrestore(&devtree_lock, flags);
#ifdef CONFIG_PROC_DEVICETREE
/* try to add to proc as well if it was initialized */
int prom_remove_property(struct device_node *np, struct property *prop)
{
struct property **next;
+ unsigned long flags;
int found = 0;
- write_lock(&devtree_lock);
+ write_lock_irqsave(&devtree_lock, flags);
next = &np->properties;
while (*next) {
if (*next == prop) {
}
next = &(*next)->next;
}
- write_unlock(&devtree_lock);
+ write_unlock_irqrestore(&devtree_lock, flags);
if (!found)
return -ENODEV;
struct property *oldprop)
{
struct property **next;
+ unsigned long flags;
int found = 0;
- write_lock(&devtree_lock);
+ write_lock_irqsave(&devtree_lock, flags);
next = &np->properties;
while (*next) {
if (*next == oldprop) {
}
next = &(*next)->next;
}
- write_unlock(&devtree_lock);
+ write_unlock_irqrestore(&devtree_lock, flags);
if (!found)
return -ENODEV;