static int dlpar_update_device_tree_lmb(struct of_drconf_cell *lmb) { struct device_node *dn; struct property *prop; struct of_drconf_cell *lmbs; u32 *p, num_lmbs; int i; dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); if (!dn) return -ENODEV; prop = dlpar_clone_drconf_property(dn); if (!prop) { of_node_put(dn); return -ENODEV; } p = prop->value; num_lmbs = *p++; lmbs = (struct of_drconf_cell *)p; for (i = 0; i < num_lmbs; i++) { if (lmbs[i].drc_index == lmb->drc_index) { lmbs[i].flags = lmb->flags; lmbs[i].aa_index = lmb->aa_index; dlpar_update_drconf_property(dn, prop); break; } } of_node_put(dn); return 0; }
int dlpar_memory(struct pseries_hp_errorlog *hp_elog) { struct device_node *dn; struct property *prop; u32 count, drc_index; int rc; count = hp_elog->_drc_u.drc_count; drc_index = hp_elog->_drc_u.drc_index; lock_device_hotplug(); dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); if (!dn) { rc = -EINVAL; goto dlpar_memory_out; } prop = dlpar_clone_drconf_property(dn); if (!prop) { rc = -EINVAL; goto dlpar_memory_out; } switch (hp_elog->action) { case PSERIES_HP_ELOG_ACTION_ADD: if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT) rc = dlpar_memory_add_by_count(count, prop); else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX) rc = dlpar_memory_add_by_index(drc_index, prop); else rc = -EINVAL; break; case PSERIES_HP_ELOG_ACTION_REMOVE: if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT) rc = dlpar_memory_remove_by_count(count, prop); else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX) rc = dlpar_memory_remove_by_index(drc_index, prop); else rc = -EINVAL; break; default: pr_err("Invalid action (%d) specified\n", hp_elog->action); rc = -EINVAL; break; } dlpar_free_property(prop); dlpar_memory_out: of_node_put(dn); unlock_device_hotplug(); return rc; }