11ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass/* 21ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 31ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * 41ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * This program is free software; you can redistribute it and/or 51ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * modify it under the terms of the GNU General Public License as 61ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * published by the Free Software Foundation; either version 2 of 71ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * the License, or (at your option) any later version. 81ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * 91ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * This program is distributed in the hope that it will be useful, 101ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * but WITHOUT ANY WARRANTY; without even the implied warranty of 111ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 121ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * GNU General Public License for more details. 131ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * 141ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * You should have received a copy of the GNU General Public License 151ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * along with this program; if not, write to the Free Software 161ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 171ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * MA 02111-1307 USA 181ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass */ 191ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 201ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass#include <assert.h> 211ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass#include <ctype.h> 221ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass#include <getopt.h> 231ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass#include <stdio.h> 241ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass#include <stdlib.h> 251ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass#include <string.h> 261ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 271ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass#include <libfdt.h> 281ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 291ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass#include "util.h" 301ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 31f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass/* These are the operations we support */ 32f58dff50407c0ee56b372ab201469c18dc042f56Simon Glassenum oper_type { 33f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass OPER_WRITE_PROP, /* Write a property in a node */ 34d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass OPER_CREATE_NODE, /* Create a new node */ 35aa719618a8b7c748be659717a9fd003bfa186017Wang Long OPER_REMOVE_NODE, /* Delete a node */ 36aa719618a8b7c748be659717a9fd003bfa186017Wang Long OPER_DELETE_PROP, /* Delete a property in a node */ 37f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass}; 38f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass 391ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glassstruct display_info { 40f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass enum oper_type oper; /* operation to perform */ 411ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass int type; /* data type (s/i/u/x or 0 for default) */ 421ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass int size; /* data size (1/2/4) */ 431ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass int verbose; /* verbose output */ 44f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass int auto_path; /* automatically create all path components */ 451ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass}; 461ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 473553dfac224435233f2c0d33169194098e979c88Simon Glass 483553dfac224435233f2c0d33169194098e979c88Simon Glass/** 493553dfac224435233f2c0d33169194098e979c88Simon Glass * Report an error with a particular node. 503553dfac224435233f2c0d33169194098e979c88Simon Glass * 513553dfac224435233f2c0d33169194098e979c88Simon Glass * @param name Node name to report error on 523553dfac224435233f2c0d33169194098e979c88Simon Glass * @param namelen Length of node name, or -1 to use entire string 533553dfac224435233f2c0d33169194098e979c88Simon Glass * @param err Error number to report (-FDT_ERR_...) 543553dfac224435233f2c0d33169194098e979c88Simon Glass */ 553553dfac224435233f2c0d33169194098e979c88Simon Glassstatic void report_error(const char *name, int namelen, int err) 561ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass{ 573553dfac224435233f2c0d33169194098e979c88Simon Glass if (namelen == -1) 583553dfac224435233f2c0d33169194098e979c88Simon Glass namelen = strlen(name); 593553dfac224435233f2c0d33169194098e979c88Simon Glass fprintf(stderr, "Error at '%1.*s': %s\n", namelen, name, 603553dfac224435233f2c0d33169194098e979c88Simon Glass fdt_strerror(err)); 611ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass} 621ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 631ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass/** 641ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * Encode a series of arguments in a property value. 651ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * 661ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * @param disp Display information / options 671ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * @param arg List of arguments from command line 681ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * @param arg_count Number of arguments (may be 0) 691ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * @param valuep Returns buffer containing value 70c17a811c62ebdcb3ad6e7b5c9a0e0f64d5d64d8bNicolas Iooss * @param value_len Returns length of value encoded 711ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass */ 721ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glassstatic int encode_value(struct display_info *disp, char **arg, int arg_count, 731ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass char **valuep, int *value_len) 741ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass{ 751ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass char *value = NULL; /* holding area for value */ 761ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass int value_size = 0; /* size of holding area */ 771ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass char *ptr; /* pointer to current value position */ 781ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass int len; /* length of this cell/string/byte */ 791ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass int ival; 801ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass int upto; /* the number of bytes we have written to buf */ 811ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass char fmt[3]; 821ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 831ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass upto = 0; 841ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 851ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (disp->verbose) 861ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass fprintf(stderr, "Decoding value:\n"); 871ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 881ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass fmt[0] = '%'; 891ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass fmt[1] = disp->type ? disp->type : 'd'; 901ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass fmt[2] = '\0'; 911ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass for (; arg_count > 0; arg++, arg_count--, upto += len) { 921ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass /* assume integer unless told otherwise */ 931ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (disp->type == 's') 941ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass len = strlen(*arg) + 1; 951ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass else 961ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass len = disp->size == -1 ? 4 : disp->size; 971ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 981ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass /* enlarge our value buffer by a suitable margin if needed */ 991ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (upto + len > value_size) { 1001ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass value_size = (upto + len) + 500; 1018ce36476ae8d2541e9bf3a6c23c345ec03694ee3Heinrich Schuchardt value = xrealloc(value, value_size); 1021ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass } 1031ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 1041ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass ptr = value + upto; 1051ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (disp->type == 's') { 1061ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass memcpy(ptr, *arg, len); 1071ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (disp->verbose) 1081ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass fprintf(stderr, "\tstring: '%s'\n", ptr); 1091ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass } else { 110bad5b28049e5e0562a8ad91797fb77953a53fa20David Gibson fdt32_t *iptr = (fdt32_t *)ptr; 1111ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass sscanf(*arg, fmt, &ival); 1121ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (len == 4) 1131ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass *iptr = cpu_to_fdt32(ival); 1141ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass else 1151ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass *ptr = (uint8_t)ival; 1161ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (disp->verbose) { 1171ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass fprintf(stderr, "\t%s: %d\n", 1181ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass disp->size == 1 ? "byte" : 1191ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass disp->size == 2 ? "short" : "int", 1201ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass ival); 1211ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass } 1221ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass } 1231ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass } 1241ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass *value_len = upto; 1251ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass *valuep = value; 1261ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (disp->verbose) 1271ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass fprintf(stderr, "Value size %d\n", upto); 1281ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass return 0; 1291ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass} 1301ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 131d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla#define ALIGN(x) (((x) + (FDT_TAGSIZE) - 1) & ~((FDT_TAGSIZE) - 1)) 132d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla 133d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatlastatic char *_realloc_fdt(char *fdt, int delta) 134d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla{ 135d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla int new_sz = fdt_totalsize(fdt) + delta; 136d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla fdt = xrealloc(fdt, new_sz); 137d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla fdt_open_into(fdt, fdt, new_sz); 138d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla return fdt; 139d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla} 140d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla 141d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatlastatic char *realloc_node(char *fdt, const char *name) 142d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla{ 143d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla int delta; 144d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla /* FDT_BEGIN_NODE, node name in off_struct and FDT_END_NODE */ 145d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla delta = sizeof(struct fdt_node_header) + ALIGN(strlen(name) + 1) 146d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla + FDT_TAGSIZE; 147d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla return _realloc_fdt(fdt, delta); 148d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla} 149d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla 150d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatlastatic char *realloc_property(char *fdt, int nodeoffset, 151d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla const char *name, int newlen) 152d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla{ 153d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla int delta = 0; 154d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla int oldlen = 0; 155d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla 156d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla if (!fdt_get_property(fdt, nodeoffset, name, &oldlen)) 157d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla /* strings + property header */ 158d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla delta = sizeof(struct fdt_property) + strlen(name) + 1; 159d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla 160d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla if (newlen > oldlen) 161d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla /* actual value in off_struct */ 162d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla delta += ALIGN(newlen) - ALIGN(oldlen); 163d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla 164d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla return _realloc_fdt(fdt, delta); 165d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla} 166d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla 167d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatlastatic int store_key_value(char **blob, const char *node_name, 1681ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass const char *property, const char *buf, int len) 1691ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass{ 1701ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass int node; 1711ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass int err; 1721ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 173d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla node = fdt_path_offset(*blob, node_name); 1741ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (node < 0) { 1753553dfac224435233f2c0d33169194098e979c88Simon Glass report_error(node_name, -1, node); 1761ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass return -1; 1771ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass } 1781ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 179d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla err = fdt_setprop(*blob, node, property, buf, len); 180d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla if (err == -FDT_ERR_NOSPACE) { 181d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla *blob = realloc_property(*blob, node, property, len); 182d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla err = fdt_setprop(*blob, node, property, buf, len); 183d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla } 1841ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (err) { 1853553dfac224435233f2c0d33169194098e979c88Simon Glass report_error(property, -1, err); 1861ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass return -1; 1871ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass } 1881ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass return 0; 1891ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass} 1901ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 191d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass/** 192f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass * Create paths as needed for all components of a path 193f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass * 194f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass * Any components of the path that do not exist are created. Errors are 195f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass * reported. 196f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass * 197f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass * @param blob FDT blob to write into 198f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass * @param in_path Path to process 199f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass * @return 0 if ok, -1 on error 200f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass */ 201d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatlastatic int create_paths(char **blob, const char *in_path) 202f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass{ 203f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass const char *path = in_path; 204f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass const char *sep; 205f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass int node, offset = 0; 206f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass 207f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass /* skip leading '/' */ 208f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass while (*path == '/') 209f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass path++; 210f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass 211f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass for (sep = path; *sep; path = sep + 1, offset = node) { 212f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass /* equivalent to strchrnul(), but it requires _GNU_SOURCE */ 213f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass sep = strchr(path, '/'); 214f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass if (!sep) 215f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass sep = path + strlen(path); 216f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass 217d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla node = fdt_subnode_offset_namelen(*blob, offset, path, 218f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass sep - path); 219f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass if (node == -FDT_ERR_NOTFOUND) { 220d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla *blob = realloc_node(*blob, path); 221d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla node = fdt_add_subnode_namelen(*blob, offset, path, 222f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass sep - path); 223f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass } 224f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass if (node < 0) { 225f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass report_error(path, sep - path, node); 226f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass return -1; 227f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass } 228f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass } 229f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass 230f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass return 0; 231f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass} 232f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass 233f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass/** 234d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass * Create a new node in the fdt. 235d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass * 236d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass * This will overwrite the node_name string. Any error is reported. 237d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass * 238d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass * TODO: Perhaps create fdt_path_offset_namelen() so we don't need to do this. 239d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass * 240d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass * @param blob FDT blob to write into 241d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass * @param node_name Name of node to create 242d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass * @return new node offset if found, or -1 on failure 243d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass */ 244d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatlastatic int create_node(char **blob, const char *node_name) 245d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass{ 246d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass int node = 0; 247d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass char *p; 248d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass 249d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass p = strrchr(node_name, '/'); 250d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass if (!p) { 2513553dfac224435233f2c0d33169194098e979c88Simon Glass report_error(node_name, -1, -FDT_ERR_BADPATH); 252d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass return -1; 253d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass } 254d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass *p = '\0'; 255d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass 256d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla *blob = realloc_node(*blob, p + 1); 257d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla 258d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass if (p > node_name) { 259d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla node = fdt_path_offset(*blob, node_name); 260d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass if (node < 0) { 2613553dfac224435233f2c0d33169194098e979c88Simon Glass report_error(node_name, -1, node); 262d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass return -1; 263d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass } 264d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass } 265d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass 266d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla node = fdt_add_subnode(*blob, node, p + 1); 267d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass if (node < 0) { 2683553dfac224435233f2c0d33169194098e979c88Simon Glass report_error(p + 1, -1, node); 269d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass return -1; 270d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass } 271d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass 272d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass return 0; 273d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass} 274d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass 275aa719618a8b7c748be659717a9fd003bfa186017Wang Long/** 276aa719618a8b7c748be659717a9fd003bfa186017Wang Long * Delete a property of a node in the fdt. 277aa719618a8b7c748be659717a9fd003bfa186017Wang Long * 278aa719618a8b7c748be659717a9fd003bfa186017Wang Long * @param blob FDT blob to write into 279aa719618a8b7c748be659717a9fd003bfa186017Wang Long * @param node_name Path to node containing the property to delete 280aa719618a8b7c748be659717a9fd003bfa186017Wang Long * @param prop_name Name of property to delete 281aa719618a8b7c748be659717a9fd003bfa186017Wang Long * @return 0 on success, or -1 on failure 282aa719618a8b7c748be659717a9fd003bfa186017Wang Long */ 283aa719618a8b7c748be659717a9fd003bfa186017Wang Longstatic int delete_prop(char *blob, const char *node_name, const char *prop_name) 284aa719618a8b7c748be659717a9fd003bfa186017Wang Long{ 285aa719618a8b7c748be659717a9fd003bfa186017Wang Long int node = 0; 286aa719618a8b7c748be659717a9fd003bfa186017Wang Long 287aa719618a8b7c748be659717a9fd003bfa186017Wang Long node = fdt_path_offset(blob, node_name); 288aa719618a8b7c748be659717a9fd003bfa186017Wang Long if (node < 0) { 289aa719618a8b7c748be659717a9fd003bfa186017Wang Long report_error(node_name, -1, node); 290aa719618a8b7c748be659717a9fd003bfa186017Wang Long return -1; 291aa719618a8b7c748be659717a9fd003bfa186017Wang Long } 292aa719618a8b7c748be659717a9fd003bfa186017Wang Long 293aa719618a8b7c748be659717a9fd003bfa186017Wang Long node = fdt_delprop(blob, node, prop_name); 294aa719618a8b7c748be659717a9fd003bfa186017Wang Long if (node < 0) { 295aa719618a8b7c748be659717a9fd003bfa186017Wang Long report_error(node_name, -1, node); 296aa719618a8b7c748be659717a9fd003bfa186017Wang Long return -1; 297aa719618a8b7c748be659717a9fd003bfa186017Wang Long } 298aa719618a8b7c748be659717a9fd003bfa186017Wang Long 299aa719618a8b7c748be659717a9fd003bfa186017Wang Long return 0; 300aa719618a8b7c748be659717a9fd003bfa186017Wang Long} 301aa719618a8b7c748be659717a9fd003bfa186017Wang Long 302aa719618a8b7c748be659717a9fd003bfa186017Wang Long/** 303aa719618a8b7c748be659717a9fd003bfa186017Wang Long * Delete a node in the fdt. 304aa719618a8b7c748be659717a9fd003bfa186017Wang Long * 305aa719618a8b7c748be659717a9fd003bfa186017Wang Long * @param blob FDT blob to write into 306aa719618a8b7c748be659717a9fd003bfa186017Wang Long * @param node_name Name of node to delete 307aa719618a8b7c748be659717a9fd003bfa186017Wang Long * @return 0 on success, or -1 on failure 308aa719618a8b7c748be659717a9fd003bfa186017Wang Long */ 309aa719618a8b7c748be659717a9fd003bfa186017Wang Longstatic int delete_node(char *blob, const char *node_name) 310aa719618a8b7c748be659717a9fd003bfa186017Wang Long{ 311aa719618a8b7c748be659717a9fd003bfa186017Wang Long int node = 0; 312aa719618a8b7c748be659717a9fd003bfa186017Wang Long 313aa719618a8b7c748be659717a9fd003bfa186017Wang Long node = fdt_path_offset(blob, node_name); 314aa719618a8b7c748be659717a9fd003bfa186017Wang Long if (node < 0) { 315aa719618a8b7c748be659717a9fd003bfa186017Wang Long report_error(node_name, -1, node); 316aa719618a8b7c748be659717a9fd003bfa186017Wang Long return -1; 317aa719618a8b7c748be659717a9fd003bfa186017Wang Long } 318aa719618a8b7c748be659717a9fd003bfa186017Wang Long 319aa719618a8b7c748be659717a9fd003bfa186017Wang Long node = fdt_del_node(blob, node); 320aa719618a8b7c748be659717a9fd003bfa186017Wang Long if (node < 0) { 321aa719618a8b7c748be659717a9fd003bfa186017Wang Long report_error(node_name, -1, node); 322aa719618a8b7c748be659717a9fd003bfa186017Wang Long return -1; 323aa719618a8b7c748be659717a9fd003bfa186017Wang Long } 324aa719618a8b7c748be659717a9fd003bfa186017Wang Long 325aa719618a8b7c748be659717a9fd003bfa186017Wang Long return 0; 326aa719618a8b7c748be659717a9fd003bfa186017Wang Long} 327aa719618a8b7c748be659717a9fd003bfa186017Wang Long 3281ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glassstatic int do_fdtput(struct display_info *disp, const char *filename, 3291ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass char **arg, int arg_count) 3301ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass{ 331c539075ba8ba61fffbf7e005ce2e834868a9e0abJean-Christophe Dubois char *value = NULL; 3321ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass char *blob; 333aa719618a8b7c748be659717a9fd003bfa186017Wang Long char *node; 3341ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass int len, ret = 0; 3351ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 3365543b88d5e3047b781552eb431bc2e3bdd9ade06Jon Loeliger blob = utilfdt_read(filename); 3371ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (!blob) 3381ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass return -1; 3391ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 340f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass switch (disp->oper) { 341f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass case OPER_WRITE_PROP: 342f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass /* 343f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass * Convert the arguments into a single binary value, then 344f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass * store them into the property. 345f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass */ 346f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass assert(arg_count >= 2); 347d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla if (disp->auto_path && create_paths(&blob, *arg)) 348f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass return -1; 349f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass if (encode_value(disp, arg + 2, arg_count - 2, &value, &len) || 350d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla store_key_value(&blob, *arg, arg[1], value, len)) 351f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass ret = -1; 352f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass break; 353d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass case OPER_CREATE_NODE: 354f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass for (; ret >= 0 && arg_count--; arg++) { 355f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass if (disp->auto_path) 356d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla ret = create_paths(&blob, *arg); 357f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass else 358d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla ret = create_node(&blob, *arg); 359f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass } 360d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass break; 361aa719618a8b7c748be659717a9fd003bfa186017Wang Long case OPER_REMOVE_NODE: 362aa719618a8b7c748be659717a9fd003bfa186017Wang Long for (; ret >= 0 && arg_count--; arg++) 363aa719618a8b7c748be659717a9fd003bfa186017Wang Long ret = delete_node(blob, *arg); 364aa719618a8b7c748be659717a9fd003bfa186017Wang Long break; 365aa719618a8b7c748be659717a9fd003bfa186017Wang Long case OPER_DELETE_PROP: 366aa719618a8b7c748be659717a9fd003bfa186017Wang Long node = *arg; 367aa719618a8b7c748be659717a9fd003bfa186017Wang Long for (arg++; ret >= 0 && arg_count-- > 1; arg++) 368aa719618a8b7c748be659717a9fd003bfa186017Wang Long ret = delete_prop(blob, node, *arg); 369aa719618a8b7c748be659717a9fd003bfa186017Wang Long break; 370f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass } 371d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla if (ret >= 0) { 372d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla fdt_pack(blob); 3731ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass ret = utilfdt_write(filename, blob); 374d214655904b49938dafcb83797de3f6a0dc725c8Srinivas Kandagatla } 3751ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 3761ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass free(blob); 377c539075ba8ba61fffbf7e005ce2e834868a9e0abJean-Christophe Dubois 378c539075ba8ba61fffbf7e005ce2e834868a9e0abJean-Christophe Dubois if (value) { 379c539075ba8ba61fffbf7e005ce2e834868a9e0abJean-Christophe Dubois free(value); 380c539075ba8ba61fffbf7e005ce2e834868a9e0abJean-Christophe Dubois } 381c539075ba8ba61fffbf7e005ce2e834868a9e0abJean-Christophe Dubois 3821ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass return ret; 3831ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass} 3841ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 38503449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger/* Usage related data. */ 38603449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysingerstatic const char usage_synopsis[] = 38703449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger "write a property value to a device tree\n" 388bb21f0a766056114e4d9336324b4c294f640d9d1Simon Glass " fdtput <options> <dt file> <node> <property> [<value>...]\n" 389d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass " fdtput -c <options> <dt file> [<node>...]\n" 390aa719618a8b7c748be659717a9fd003bfa186017Wang Long " fdtput -r <options> <dt file> [<node>...]\n" 391aa719618a8b7c748be659717a9fd003bfa186017Wang Long " fdtput -d <options> <dt file> <node> [<property>...]\n" 39203449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger "\n" 39303449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger "The command line arguments are joined together into a single value.\n" 3941ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass USAGE_TYPE_MSG; 395aa719618a8b7c748be659717a9fd003bfa186017Wang Longstatic const char usage_short_opts[] = "crdpt:v" USAGE_COMMON_SHORT_OPTS; 39603449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysingerstatic struct option const usage_long_opts[] = { 39703449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger {"create", no_argument, NULL, 'c'}, 398aa719618a8b7c748be659717a9fd003bfa186017Wang Long {"remove", no_argument, NULL, 'r'}, 399aa719618a8b7c748be659717a9fd003bfa186017Wang Long {"delete", no_argument, NULL, 'd'}, 40003449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger {"auto-path", no_argument, NULL, 'p'}, 40103449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger {"type", a_argument, NULL, 't'}, 40203449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger {"verbose", no_argument, NULL, 'v'}, 40303449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger USAGE_COMMON_LONG_OPTS, 40403449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger}; 40503449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysingerstatic const char * const usage_opts_help[] = { 40603449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger "Create nodes if they don't already exist", 407aa719618a8b7c748be659717a9fd003bfa186017Wang Long "Delete nodes (and any subnodes) if they already exist", 408aa719618a8b7c748be659717a9fd003bfa186017Wang Long "Delete properties if they already exist", 40903449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger "Automatically create nodes as needed for the node path", 41003449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger "Type of data", 41103449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger "Display each value decoded from command line", 41203449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger USAGE_COMMON_OPTS_HELP 41303449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger}; 4141ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 4151ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glassint main(int argc, char *argv[]) 4161ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass{ 41703449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger int opt; 4181ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass struct display_info disp; 4191ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass char *filename = NULL; 4201ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 4211ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass memset(&disp, '\0', sizeof(disp)); 4221ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass disp.size = -1; 423f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass disp.oper = OPER_WRITE_PROP; 42403449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger while ((opt = util_getopt_long()) != EOF) { 4251ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass /* 4261ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * TODO: add options to: 4271ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * - rename node 4281ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * - pack fdt before writing 4291ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass * - set amount of free space when writing 4301ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass */ 43103449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger switch (opt) { 43203449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger case_USAGE_COMMON_FLAGS 43303449b84c8f9aee2bf2f438bec2c2ec4606bea48Mike Frysinger 434d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass case 'c': 435d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass disp.oper = OPER_CREATE_NODE; 436d46c2de5700fd8d43de67ca3709c276beba39b39Simon Glass break; 437aa719618a8b7c748be659717a9fd003bfa186017Wang Long case 'r': 438aa719618a8b7c748be659717a9fd003bfa186017Wang Long disp.oper = OPER_REMOVE_NODE; 439aa719618a8b7c748be659717a9fd003bfa186017Wang Long break; 440aa719618a8b7c748be659717a9fd003bfa186017Wang Long case 'd': 441aa719618a8b7c748be659717a9fd003bfa186017Wang Long disp.oper = OPER_DELETE_PROP; 442aa719618a8b7c748be659717a9fd003bfa186017Wang Long break; 443f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass case 'p': 444f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass disp.auto_path = 1; 445f807af192828222dee7a5c9f94d999673bb4d8a1Simon Glass break; 4461ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass case 't': 4471ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (utilfdt_decode_type(optarg, &disp.type, 4481ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass &disp.size)) 449b9e80656f2de441826ed2ff1cd9c5d43b3ae43d3Mike Frysinger usage("Invalid type string"); 4501ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass break; 4511ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 4521ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass case 'v': 4531ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass disp.verbose = 1; 4541ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass break; 4551ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass } 4561ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass } 4571ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 4581ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (optind < argc) 4591ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass filename = argv[optind++]; 4601ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (!filename) 461b9e80656f2de441826ed2ff1cd9c5d43b3ae43d3Mike Frysinger usage("missing filename"); 4621ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 4631ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass argv += optind; 4641ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass argc -= optind; 4651ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 466f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass if (disp.oper == OPER_WRITE_PROP) { 467f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass if (argc < 1) 468b9e80656f2de441826ed2ff1cd9c5d43b3ae43d3Mike Frysinger usage("missing node"); 469f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass if (argc < 2) 470b9e80656f2de441826ed2ff1cd9c5d43b3ae43d3Mike Frysinger usage("missing property"); 471f58dff50407c0ee56b372ab201469c18dc042f56Simon Glass } 4721ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass 473aa719618a8b7c748be659717a9fd003bfa186017Wang Long if (disp.oper == OPER_DELETE_PROP) 474aa719618a8b7c748be659717a9fd003bfa186017Wang Long if (argc < 1) 475aa719618a8b7c748be659717a9fd003bfa186017Wang Long usage("missing node"); 476aa719618a8b7c748be659717a9fd003bfa186017Wang Long 4771ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass if (do_fdtput(&disp, filename, argv, argc)) 4781ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass return 1; 4791ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass return 0; 4801ede50c3559bbfca79fadcbfd8acb9388f4aac87Simon Glass} 481