summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/drmem.h5
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c55
2 files changed, 21 insertions, 39 deletions
diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h
index ce242b9ea8c6..7c1d8e74b25d 100644
--- a/arch/powerpc/include/asm/drmem.h
+++ b/arch/powerpc/include/asm/drmem.h
@@ -99,4 +99,9 @@ void __init walk_drmem_lmbs_early(unsigned long node,
void (*func)(struct drmem_lmb *, const __be32 **));
#endif
+static inline void invalidate_lmb_associativity_index(struct drmem_lmb *lmb)
+{
+ lmb->aa_index = 0xffffffff;
+}
+
#endif /* _ASM_POWERPC_LMB_H */
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index c1578f54c626..9a15d39995e5 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -163,7 +163,7 @@ static u32 find_aa_index(struct device_node *dr_node,
return aa_index;
}
-static u32 lookup_lmb_associativity_index(struct drmem_lmb *lmb)
+static int update_lmb_associativity_index(struct drmem_lmb *lmb)
{
struct device_node *parent, *lmb_node, *dr_node;
struct property *ala_prop;
@@ -203,43 +203,14 @@ static u32 lookup_lmb_associativity_index(struct drmem_lmb *lmb)
aa_index = find_aa_index(dr_node, ala_prop, lmb_assoc);
dlpar_free_cc_nodes(lmb_node);
- return aa_index;
-}
-
-static int dlpar_add_device_tree_lmb(struct drmem_lmb *lmb)
-{
- int rc, aa_index;
-
- lmb->flags |= DRCONF_MEM_ASSIGNED;
- aa_index = lookup_lmb_associativity_index(lmb);
if (aa_index < 0) {
- pr_err("Couldn't find associativity index for drc index %x\n",
- lmb->drc_index);
- return aa_index;
+ pr_err("Could not find LMB associativity\n");
+ return -1;
}
lmb->aa_index = aa_index;
-
- rtas_hp_event = true;
- rc = drmem_update_dt();
- rtas_hp_event = false;
-
- return rc;
-}
-
-static int dlpar_remove_device_tree_lmb(struct drmem_lmb *lmb)
-{
- int rc;
-
- lmb->flags &= ~DRCONF_MEM_ASSIGNED;
- lmb->aa_index = 0xffffffff;
-
- rtas_hp_event = true;
- rc = drmem_update_dt();
- rtas_hp_event = false;
-
- return rc;
+ return 0;
}
static struct memory_block *lmb_to_memblock(struct drmem_lmb *lmb)
@@ -428,7 +399,9 @@ static int dlpar_remove_lmb(struct drmem_lmb *lmb)
/* Update memory regions for memory remove */
memblock_remove(lmb->base_addr, block_sz);
- dlpar_remove_device_tree_lmb(lmb);
+ invalidate_lmb_associativity_index(lmb);
+ lmb->flags &= ~DRCONF_MEM_ASSIGNED;
+
return 0;
}
@@ -688,10 +661,8 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
if (lmb->flags & DRCONF_MEM_ASSIGNED)
return -EINVAL;
- rc = dlpar_add_device_tree_lmb(lmb);
+ rc = update_lmb_associativity_index(lmb);
if (rc) {
- pr_err("Couldn't update device tree for drc index %x\n",
- lmb->drc_index);
dlpar_release_drc(lmb->drc_index);
return rc;
}
@@ -704,14 +675,14 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
/* Add the memory */
rc = add_memory(nid, lmb->base_addr, block_sz);
if (rc) {
- dlpar_remove_device_tree_lmb(lmb);
+ invalidate_lmb_associativity_index(lmb);
return rc;
}
rc = dlpar_online_lmb(lmb);
if (rc) {
remove_memory(nid, lmb->base_addr, block_sz);
- dlpar_remove_device_tree_lmb(lmb);
+ invalidate_lmb_associativity_index(lmb);
} else {
lmb->flags |= DRCONF_MEM_ASSIGNED;
}
@@ -958,6 +929,12 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
break;
}
+ if (!rc) {
+ rtas_hp_event = true;
+ rc = drmem_update_dt();
+ rtas_hp_event = false;
+ }
+
unlock_device_hotplug();
return rc;
}