static int pseries_remove_memory(struct device_node *np) { const char *type; const unsigned int *regs; unsigned long base; unsigned int lmb_size; int ret = -EINVAL; /* * Check to see if we are actually removing memory */ type = of_get_property(np, "device_type", NULL); if (type == NULL || strcmp(type, "memory") != 0) return 0; /* * Find the bae address and size of the memblock */ regs = of_get_property(np, "reg", NULL); if (!regs) return ret; base = *(unsigned long *)regs; lmb_size = regs[3]; ret = pseries_remove_memblock(base, lmb_size); return ret; }
static int pseries_drconf_memory(unsigned long *base, unsigned int action) { struct device_node *np; const unsigned long *lmb_size; int rc; np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); if (!np) return -EINVAL; lmb_size = of_get_property(np, "ibm,lmb-size", NULL); if (!lmb_size) { of_node_put(np); return -EINVAL; } if (action == PSERIES_DRCONF_MEM_ADD) { rc = memblock_add(*base, *lmb_size); rc = (rc < 0) ? -EINVAL : 0; } else if (action == PSERIES_DRCONF_MEM_REMOVE) { rc = pseries_remove_memblock(*base, *lmb_size); } else { rc = -EINVAL; } of_node_put(np); return rc; }
static int pseries_update_drconf_memory(struct of_reconfig_data *pr) { struct of_drconf_cell *new_drmem, *old_drmem; unsigned long memblock_size; u32 entries; __be32 *p; int i, rc = -EINVAL; if (rtas_hp_event) return 0; memblock_size = pseries_memory_block_size(); if (!memblock_size) return -EINVAL; p = (__be32 *) pr->old_prop->value; if (!p) return -EINVAL; /* The first int of the property is the number of lmb's described * by the property. This is followed by an array of of_drconf_cell * entries. Get the number of entries and skip to the array of * of_drconf_cell's. */ entries = be32_to_cpu(*p++); old_drmem = (struct of_drconf_cell *)p; p = (__be32 *)pr->prop->value; p++; new_drmem = (struct of_drconf_cell *)p; for (i = 0; i < entries; i++) { if ((be32_to_cpu(old_drmem[i].flags) & DRCONF_MEM_ASSIGNED) && (!(be32_to_cpu(new_drmem[i].flags) & DRCONF_MEM_ASSIGNED))) { rc = pseries_remove_memblock( be64_to_cpu(old_drmem[i].base_addr), memblock_size); break; } else if ((!(be32_to_cpu(old_drmem[i].flags) & DRCONF_MEM_ASSIGNED)) && (be32_to_cpu(new_drmem[i].flags) & DRCONF_MEM_ASSIGNED)) { rc = memblock_add(be64_to_cpu(old_drmem[i].base_addr), memblock_size); rc = (rc < 0) ? -EINVAL : 0; break; } } return rc; }
static int pseries_update_drconf_memory(struct of_prop_reconfig *pr) { struct of_drconf_cell *new_drmem, *old_drmem; unsigned long memblock_size; u32 entries; u32 *p; int i, rc = -EINVAL; memblock_size = get_memblock_size(); if (!memblock_size) return -EINVAL; p = (u32 *)of_get_property(pr->dn, "ibm,dynamic-memory", NULL); if (!p) return -EINVAL; /* The first int of the property is the number of lmb's described * by the property. This is followed by an array of of_drconf_cell * entries. Get the niumber of entries and skip to the array of * of_drconf_cell's. */ entries = *p++; old_drmem = (struct of_drconf_cell *)p; p = (u32 *)pr->prop->value; p++; new_drmem = (struct of_drconf_cell *)p; for (i = 0; i < entries; i++) { if ((old_drmem[i].flags & DRCONF_MEM_ASSIGNED) && (!(new_drmem[i].flags & DRCONF_MEM_ASSIGNED))) { rc = pseries_remove_memblock(old_drmem[i].base_addr, memblock_size); break; } else if ((!(old_drmem[i].flags & DRCONF_MEM_ASSIGNED)) && (new_drmem[i].flags & DRCONF_MEM_ASSIGNED)) { rc = memblock_add(old_drmem[i].base_addr, memblock_size); rc = (rc < 0) ? -EINVAL : 0; break; } } return rc; }
static int pseries_drconf_memory(unsigned long *base, unsigned int action) { unsigned long memblock_size; int rc; memblock_size = get_memblock_size(); if (!memblock_size) return -EINVAL; if (action == PSERIES_DRCONF_MEM_ADD) { rc = memblock_add(*base, memblock_size); rc = (rc < 0) ? -EINVAL : 0; } else if (action == PSERIES_DRCONF_MEM_REMOVE) { rc = pseries_remove_memblock(*base, memblock_size); } else { rc = -EINVAL; } return rc; }
static int pseries_remove_memory(struct device_node *np) { const char *type; const unsigned int *regs; unsigned long base; unsigned int lmb_size; int ret = -EINVAL; type = of_get_property(np, "device_type", NULL); if (type == NULL || strcmp(type, "memory") != 0) return 0; regs = of_get_property(np, "reg", NULL); if (!regs) return ret; base = *(unsigned long *)regs; lmb_size = regs[3]; ret = pseries_remove_memblock(base, lmb_size); return ret; }