Newer
Older
Nathan Fontenot
committed
read_drconf_cell(&drmem, &dm);
/* skip this block if it is reserved or not assigned to
* this partition */
if ((drmem.flags & DRCONF_MEM_RESERVED)
|| !(drmem.flags & DRCONF_MEM_ASSIGNED))
continue;
nid = of_drconf_to_nid_single(&drmem, &aa);
if (valid_hot_add_scn(&nid, drmem.base_addr, lmb_size,
scn_addr))
return nid;
}
BUG(); /* section address should be found above */
return 0;
}
/*
* Find the node associated with a hot added memory section. Section
* corresponds to a SPARSEMEM section, not an LMB. It is assumed that
* sections are fully contained within a single LMB.
*/
int hot_add_scn_to_nid(unsigned long scn_addr)
{
struct device_node *memory = NULL;
if (!numa_enabled || (min_common_depth < 0))
Nathan Fontenot
committed
return any_online_node(NODE_MASK_ALL);
memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
if (memory) {
nid = hot_add_drconf_scn_to_nid(memory, scn_addr);
of_node_put(memory);
return nid;
}
while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
unsigned long start, size;
const unsigned int *memcell_buf;
unsigned int len;
memcell_buf = of_get_property(memory, "reg", &len);
if (!memcell_buf || len <= 0)
continue;
/* ranges in cell */
ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells);
ha_new_range:
start = read_n_cells(n_mem_addr_cells, &memcell_buf);
size = read_n_cells(n_mem_size_cells, &memcell_buf);
nid = of_node_to_nid_single(memory);
Nathan Fontenot
committed
if (valid_hot_add_scn(&nid, start, size, scn_addr)) {
of_node_put(memory);
Nathan Fontenot
committed
return nid;
}
if (--ranges) /* process all ranges in cell */
goto ha_new_range;
}
BUG(); /* section address should be found above */
}
#endif /* CONFIG_MEMORY_HOTPLUG */