164dbbd40SGerald Van Baren /* 264dbbd40SGerald Van Baren * (C) Copyright 2007 364dbbd40SGerald Van Baren * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com 464dbbd40SGerald Van Baren * 564dbbd40SGerald Van Baren * See file CREDITS for list of people who contributed to this 664dbbd40SGerald Van Baren * project. 764dbbd40SGerald Van Baren * 864dbbd40SGerald Van Baren * This program is free software; you can redistribute it and/or 964dbbd40SGerald Van Baren * modify it under the terms of the GNU General Public License as 1064dbbd40SGerald Van Baren * published by the Free Software Foundation; either version 2 of 1164dbbd40SGerald Van Baren * the License, or (at your option) any later version. 1264dbbd40SGerald Van Baren * 1364dbbd40SGerald Van Baren * This program is distributed in the hope that it will be useful, 1464dbbd40SGerald Van Baren * but WITHOUT ANY WARRANTY; without even the implied warranty of 1564dbbd40SGerald Van Baren * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1664dbbd40SGerald Van Baren * GNU General Public License for more details. 1764dbbd40SGerald Van Baren * 1864dbbd40SGerald Van Baren * You should have received a copy of the GNU General Public License 1964dbbd40SGerald Van Baren * along with this program; if not, write to the Free Software 2064dbbd40SGerald Van Baren * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 2164dbbd40SGerald Van Baren * MA 02111-1307 USA 2264dbbd40SGerald Van Baren */ 2364dbbd40SGerald Van Baren 2464dbbd40SGerald Van Baren #include <common.h> 2564dbbd40SGerald Van Baren #include <linux/ctype.h> 2664dbbd40SGerald Van Baren #include <linux/types.h> 2764dbbd40SGerald Van Baren 2864dbbd40SGerald Van Baren #ifdef CONFIG_OF_LIBFDT 2964dbbd40SGerald Van Baren 3064dbbd40SGerald Van Baren #include <asm/global_data.h> 3164dbbd40SGerald Van Baren #include <fdt.h> 3264dbbd40SGerald Van Baren #include <libfdt.h> 3364dbbd40SGerald Van Baren #include <fdt_support.h> 3464dbbd40SGerald Van Baren 3564dbbd40SGerald Van Baren /* 3664dbbd40SGerald Van Baren * Global data (for the gd->bd) 3764dbbd40SGerald Van Baren */ 3864dbbd40SGerald Van Baren DECLARE_GLOBAL_DATA_PTR; 3964dbbd40SGerald Van Baren 40bb930e76SGerald Van Baren /* 41bb930e76SGerald Van Baren * fdt points to our working device tree. 42bb930e76SGerald Van Baren */ 43bb930e76SGerald Van Baren struct fdt_header *fdt; 44bb930e76SGerald Van Baren 4564dbbd40SGerald Van Baren /********************************************************************/ 4664dbbd40SGerald Van Baren 47a3c2933eSKumar Gala /** 48a3c2933eSKumar Gala * fdt_find_and_setprop: Find a node and set it's property 49a3c2933eSKumar Gala * 50a3c2933eSKumar Gala * @fdt: ptr to device tree 51a3c2933eSKumar Gala * @node: path of node 52a3c2933eSKumar Gala * @prop: property name 53a3c2933eSKumar Gala * @val: ptr to new value 54a3c2933eSKumar Gala * @len: length of new property value 55a3c2933eSKumar Gala * @create: flag to create the property if it doesn't exist 56a3c2933eSKumar Gala * 57a3c2933eSKumar Gala * Convenience function to directly set a property given the path to the node. 58a3c2933eSKumar Gala */ 59a3c2933eSKumar Gala int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, 60a3c2933eSKumar Gala const void *val, int len, int create) 61a3c2933eSKumar Gala { 628d04f02fSKumar Gala int nodeoff = fdt_path_offset(fdt, node); 63a3c2933eSKumar Gala 64a3c2933eSKumar Gala if (nodeoff < 0) 65a3c2933eSKumar Gala return nodeoff; 66a3c2933eSKumar Gala 67a3c2933eSKumar Gala if ((!create) && (fdt_get_property(fdt, nodeoff, prop, 0) == NULL)) 68a3c2933eSKumar Gala return 0; /* create flag not set; so exit quietly */ 69a3c2933eSKumar Gala 70a3c2933eSKumar Gala return fdt_setprop(fdt, nodeoff, prop, val, len); 71a3c2933eSKumar Gala } 72a3c2933eSKumar Gala 7364dbbd40SGerald Van Baren int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force) 7464dbbd40SGerald Van Baren { 7564dbbd40SGerald Van Baren int nodeoffset; 7664dbbd40SGerald Van Baren int err; 7764dbbd40SGerald Van Baren u32 tmp; /* used to set 32 bit integer properties */ 7864dbbd40SGerald Van Baren char *str; /* used to set string properties */ 7964dbbd40SGerald Van Baren 8064dbbd40SGerald Van Baren err = fdt_check_header(fdt); 8164dbbd40SGerald Van Baren if (err < 0) { 825fe6be62SGerald Van Baren printf("fdt_chosen: %s\n", fdt_strerror(err)); 8364dbbd40SGerald Van Baren return err; 8464dbbd40SGerald Van Baren } 8564dbbd40SGerald Van Baren 8664dbbd40SGerald Van Baren if (initrd_start && initrd_end) { 878d04f02fSKumar Gala uint64_t addr, size; 888d04f02fSKumar Gala int total = fdt_num_mem_rsv(fdt); 89c28abb9cSGerald Van Baren int j; 90c28abb9cSGerald Van Baren 91c28abb9cSGerald Van Baren /* 92c28abb9cSGerald Van Baren * Look for an existing entry and update it. If we don't find 93c28abb9cSGerald Van Baren * the entry, we will j be the next available slot. 94c28abb9cSGerald Van Baren */ 958d04f02fSKumar Gala for (j = 0; j < total; j++) { 968d04f02fSKumar Gala err = fdt_get_mem_rsv(fdt, j, &addr, &size); 978d04f02fSKumar Gala if (addr == initrd_start) { 988d04f02fSKumar Gala fdt_del_mem_rsv(fdt, j); 99c28abb9cSGerald Van Baren break; 100c28abb9cSGerald Van Baren } 101c28abb9cSGerald Van Baren } 1028d04f02fSKumar Gala 1038d04f02fSKumar Gala err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start + 1); 10464dbbd40SGerald Van Baren if (err < 0) { 1055fe6be62SGerald Van Baren printf("fdt_chosen: %s\n", fdt_strerror(err)); 10664dbbd40SGerald Van Baren return err; 10764dbbd40SGerald Van Baren } 10864dbbd40SGerald Van Baren } 10964dbbd40SGerald Van Baren 11064dbbd40SGerald Van Baren /* 11164dbbd40SGerald Van Baren * Find the "chosen" node. 11264dbbd40SGerald Van Baren */ 1138d04f02fSKumar Gala nodeoffset = fdt_path_offset (fdt, "/chosen"); 11464dbbd40SGerald Van Baren 11564dbbd40SGerald Van Baren /* 11664dbbd40SGerald Van Baren * If we have a "chosen" node already the "force the writing" 11764dbbd40SGerald Van Baren * is not set, our job is done. 11864dbbd40SGerald Van Baren */ 11964dbbd40SGerald Van Baren if ((nodeoffset >= 0) && !force) 12064dbbd40SGerald Van Baren return 0; 12164dbbd40SGerald Van Baren 12264dbbd40SGerald Van Baren /* 12364dbbd40SGerald Van Baren * No "chosen" node in the blob: create it. 12464dbbd40SGerald Van Baren */ 12564dbbd40SGerald Van Baren if (nodeoffset < 0) { 12664dbbd40SGerald Van Baren /* 12764dbbd40SGerald Van Baren * Create a new node "/chosen" (offset 0 is root level) 12864dbbd40SGerald Van Baren */ 12964dbbd40SGerald Van Baren nodeoffset = fdt_add_subnode(fdt, 0, "chosen"); 13064dbbd40SGerald Van Baren if (nodeoffset < 0) { 1315fe6be62SGerald Van Baren printf("WARNING: could not create /chosen %s.\n", 13235ec398fSGerald Van Baren fdt_strerror(nodeoffset)); 13364dbbd40SGerald Van Baren return nodeoffset; 13464dbbd40SGerald Van Baren } 13564dbbd40SGerald Van Baren } 13664dbbd40SGerald Van Baren 13764dbbd40SGerald Van Baren /* 13864dbbd40SGerald Van Baren * Update pre-existing properties, create them if non-existant. 13964dbbd40SGerald Van Baren */ 14064dbbd40SGerald Van Baren str = getenv("bootargs"); 14164dbbd40SGerald Van Baren if (str != NULL) { 14235ec398fSGerald Van Baren err = fdt_setprop(fdt, nodeoffset, 14335ec398fSGerald Van Baren "bootargs", str, strlen(str)+1); 14464dbbd40SGerald Van Baren if (err < 0) 1455fe6be62SGerald Van Baren printf("WARNING: could not set bootargs %s.\n", 14635ec398fSGerald Van Baren fdt_strerror(err)); 14764dbbd40SGerald Van Baren } 14864dbbd40SGerald Van Baren if (initrd_start && initrd_end) { 14964dbbd40SGerald Van Baren tmp = __cpu_to_be32(initrd_start); 15035ec398fSGerald Van Baren err = fdt_setprop(fdt, nodeoffset, 15135ec398fSGerald Van Baren "linux,initrd-start", &tmp, sizeof(tmp)); 15264dbbd40SGerald Van Baren if (err < 0) 1535fe6be62SGerald Van Baren printf("WARNING: " 1545fe6be62SGerald Van Baren "could not set linux,initrd-start %s.\n", 15535ec398fSGerald Van Baren fdt_strerror(err)); 15664dbbd40SGerald Van Baren tmp = __cpu_to_be32(initrd_end); 15735ec398fSGerald Van Baren err = fdt_setprop(fdt, nodeoffset, 15835ec398fSGerald Van Baren "linux,initrd-end", &tmp, sizeof(tmp)); 15964dbbd40SGerald Van Baren if (err < 0) 1605fe6be62SGerald Van Baren printf("WARNING: could not set linux,initrd-end %s.\n", 16135ec398fSGerald Van Baren fdt_strerror(err)); 16264dbbd40SGerald Van Baren } 16364dbbd40SGerald Van Baren #ifdef OF_STDOUT_PATH 16435ec398fSGerald Van Baren err = fdt_setprop(fdt, nodeoffset, 16535ec398fSGerald Van Baren "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1); 16664dbbd40SGerald Van Baren if (err < 0) 1675fe6be62SGerald Van Baren printf("WARNING: could not set linux,stdout-path %s.\n", 16835ec398fSGerald Van Baren fdt_strerror(err)); 16964dbbd40SGerald Van Baren #endif 17064dbbd40SGerald Van Baren 17164dbbd40SGerald Van Baren return err; 17264dbbd40SGerald Van Baren } 17364dbbd40SGerald Van Baren 17464dbbd40SGerald Van Baren /********************************************************************/ 17564dbbd40SGerald Van Baren 17664dbbd40SGerald Van Baren #ifdef CONFIG_OF_HAS_UBOOT_ENV 17764dbbd40SGerald Van Baren 17864dbbd40SGerald Van Baren /* Function that returns a character from the environment */ 17964dbbd40SGerald Van Baren extern uchar(*env_get_char) (int); 18064dbbd40SGerald Van Baren 18164dbbd40SGerald Van Baren 18264dbbd40SGerald Van Baren int fdt_env(void *fdt) 18364dbbd40SGerald Van Baren { 18464dbbd40SGerald Van Baren int nodeoffset; 18564dbbd40SGerald Van Baren int err; 18664dbbd40SGerald Van Baren int k, nxt; 18764dbbd40SGerald Van Baren int i; 18864dbbd40SGerald Van Baren static char tmpenv[256]; 18964dbbd40SGerald Van Baren 19064dbbd40SGerald Van Baren err = fdt_check_header(fdt); 19164dbbd40SGerald Van Baren if (err < 0) { 1925fe6be62SGerald Van Baren printf("fdt_env: %s\n", fdt_strerror(err)); 19364dbbd40SGerald Van Baren return err; 19464dbbd40SGerald Van Baren } 19564dbbd40SGerald Van Baren 19664dbbd40SGerald Van Baren /* 19764dbbd40SGerald Van Baren * See if we already have a "u-boot-env" node, delete it if so. 19864dbbd40SGerald Van Baren * Then create a new empty node. 19964dbbd40SGerald Van Baren */ 2008d04f02fSKumar Gala nodeoffset = fdt_path_offset (fdt, "/u-boot-env"); 20164dbbd40SGerald Van Baren if (nodeoffset >= 0) { 20264dbbd40SGerald Van Baren err = fdt_del_node(fdt, nodeoffset); 20364dbbd40SGerald Van Baren if (err < 0) { 2045fe6be62SGerald Van Baren printf("fdt_env: %s\n", fdt_strerror(err)); 20564dbbd40SGerald Van Baren return err; 20664dbbd40SGerald Van Baren } 20764dbbd40SGerald Van Baren } 20864dbbd40SGerald Van Baren /* 20964dbbd40SGerald Van Baren * Create a new node "/u-boot-env" (offset 0 is root level) 21064dbbd40SGerald Van Baren */ 21164dbbd40SGerald Van Baren nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env"); 21264dbbd40SGerald Van Baren if (nodeoffset < 0) { 2135fe6be62SGerald Van Baren printf("WARNING: could not create /u-boot-env %s.\n", 21435ec398fSGerald Van Baren fdt_strerror(nodeoffset)); 21564dbbd40SGerald Van Baren return nodeoffset; 21664dbbd40SGerald Van Baren } 21764dbbd40SGerald Van Baren 21864dbbd40SGerald Van Baren for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { 21964dbbd40SGerald Van Baren char *s, *lval, *rval; 22064dbbd40SGerald Van Baren 22164dbbd40SGerald Van Baren /* 22264dbbd40SGerald Van Baren * Find the end of the name=definition 22364dbbd40SGerald Van Baren */ 22464dbbd40SGerald Van Baren for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) 22564dbbd40SGerald Van Baren ; 22664dbbd40SGerald Van Baren s = tmpenv; 22764dbbd40SGerald Van Baren for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k) 22864dbbd40SGerald Van Baren *s++ = env_get_char(k); 22964dbbd40SGerald Van Baren *s++ = '\0'; 23064dbbd40SGerald Van Baren lval = tmpenv; 23164dbbd40SGerald Van Baren /* 23264dbbd40SGerald Van Baren * Find the first '=': it separates the name from the value 23364dbbd40SGerald Van Baren */ 23464dbbd40SGerald Van Baren s = strchr(tmpenv, '='); 23564dbbd40SGerald Van Baren if (s != NULL) { 23664dbbd40SGerald Van Baren *s++ = '\0'; 23764dbbd40SGerald Van Baren rval = s; 23864dbbd40SGerald Van Baren } else 23964dbbd40SGerald Van Baren continue; 24064dbbd40SGerald Van Baren err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1); 24164dbbd40SGerald Van Baren if (err < 0) { 2425fe6be62SGerald Van Baren printf("WARNING: could not set %s %s.\n", 24335ec398fSGerald Van Baren lval, fdt_strerror(err)); 24464dbbd40SGerald Van Baren return err; 24564dbbd40SGerald Van Baren } 24664dbbd40SGerald Van Baren } 24764dbbd40SGerald Van Baren return 0; 24864dbbd40SGerald Van Baren } 249c28abb9cSGerald Van Baren #endif /* ifdef CONFIG_OF_HAS_UBOOT_ENV */ 25064dbbd40SGerald Van Baren 25164dbbd40SGerald Van Baren /********************************************************************/ 25264dbbd40SGerald Van Baren 25364dbbd40SGerald Van Baren #ifdef CONFIG_OF_HAS_BD_T 25464dbbd40SGerald Van Baren 25564dbbd40SGerald Van Baren #define BDM(x) { .name = #x, .offset = offsetof(bd_t, bi_ ##x ) } 25664dbbd40SGerald Van Baren 25764dbbd40SGerald Van Baren static const struct { 25864dbbd40SGerald Van Baren const char *name; 25964dbbd40SGerald Van Baren int offset; 26064dbbd40SGerald Van Baren } bd_map[] = { 26164dbbd40SGerald Van Baren BDM(memstart), 26264dbbd40SGerald Van Baren BDM(memsize), 26364dbbd40SGerald Van Baren BDM(flashstart), 26464dbbd40SGerald Van Baren BDM(flashsize), 26564dbbd40SGerald Van Baren BDM(flashoffset), 26664dbbd40SGerald Van Baren BDM(sramstart), 26764dbbd40SGerald Van Baren BDM(sramsize), 26864dbbd40SGerald Van Baren #if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ 26964dbbd40SGerald Van Baren || defined(CONFIG_E500) 27064dbbd40SGerald Van Baren BDM(immr_base), 27164dbbd40SGerald Van Baren #endif 27264dbbd40SGerald Van Baren #if defined(CONFIG_MPC5xxx) 27364dbbd40SGerald Van Baren BDM(mbar_base), 27464dbbd40SGerald Van Baren #endif 27564dbbd40SGerald Van Baren #if defined(CONFIG_MPC83XX) 27664dbbd40SGerald Van Baren BDM(immrbar), 27764dbbd40SGerald Van Baren #endif 27864dbbd40SGerald Van Baren #if defined(CONFIG_MPC8220) 27964dbbd40SGerald Van Baren BDM(mbar_base), 28064dbbd40SGerald Van Baren BDM(inpfreq), 28164dbbd40SGerald Van Baren BDM(pcifreq), 28264dbbd40SGerald Van Baren BDM(pevfreq), 28364dbbd40SGerald Van Baren BDM(flbfreq), 28464dbbd40SGerald Van Baren BDM(vcofreq), 28564dbbd40SGerald Van Baren #endif 28664dbbd40SGerald Van Baren BDM(bootflags), 28764dbbd40SGerald Van Baren BDM(ip_addr), 28864dbbd40SGerald Van Baren BDM(intfreq), 28964dbbd40SGerald Van Baren BDM(busfreq), 29064dbbd40SGerald Van Baren #ifdef CONFIG_CPM2 29164dbbd40SGerald Van Baren BDM(cpmfreq), 29264dbbd40SGerald Van Baren BDM(brgfreq), 29364dbbd40SGerald Van Baren BDM(sccfreq), 29464dbbd40SGerald Van Baren BDM(vco), 29564dbbd40SGerald Van Baren #endif 29664dbbd40SGerald Van Baren #if defined(CONFIG_MPC5xxx) 29764dbbd40SGerald Van Baren BDM(ipbfreq), 29864dbbd40SGerald Van Baren BDM(pcifreq), 29964dbbd40SGerald Van Baren #endif 30064dbbd40SGerald Van Baren BDM(baudrate), 30164dbbd40SGerald Van Baren }; 30264dbbd40SGerald Van Baren 30364dbbd40SGerald Van Baren 30464dbbd40SGerald Van Baren int fdt_bd_t(void *fdt) 30564dbbd40SGerald Van Baren { 30664dbbd40SGerald Van Baren bd_t *bd = gd->bd; 30764dbbd40SGerald Van Baren int nodeoffset; 30864dbbd40SGerald Van Baren int err; 30964dbbd40SGerald Van Baren u32 tmp; /* used to set 32 bit integer properties */ 31064dbbd40SGerald Van Baren int i; 31164dbbd40SGerald Van Baren 31264dbbd40SGerald Van Baren err = fdt_check_header(fdt); 31364dbbd40SGerald Van Baren if (err < 0) { 3145fe6be62SGerald Van Baren printf("fdt_bd_t: %s\n", fdt_strerror(err)); 31564dbbd40SGerald Van Baren return err; 31664dbbd40SGerald Van Baren } 31764dbbd40SGerald Van Baren 31864dbbd40SGerald Van Baren /* 31964dbbd40SGerald Van Baren * See if we already have a "bd_t" node, delete it if so. 32064dbbd40SGerald Van Baren * Then create a new empty node. 32164dbbd40SGerald Van Baren */ 3228d04f02fSKumar Gala nodeoffset = fdt_path_offset (fdt, "/bd_t"); 32364dbbd40SGerald Van Baren if (nodeoffset >= 0) { 32464dbbd40SGerald Van Baren err = fdt_del_node(fdt, nodeoffset); 32564dbbd40SGerald Van Baren if (err < 0) { 3265fe6be62SGerald Van Baren printf("fdt_bd_t: %s\n", fdt_strerror(err)); 32764dbbd40SGerald Van Baren return err; 32864dbbd40SGerald Van Baren } 32964dbbd40SGerald Van Baren } 33064dbbd40SGerald Van Baren /* 33164dbbd40SGerald Van Baren * Create a new node "/bd_t" (offset 0 is root level) 33264dbbd40SGerald Van Baren */ 33364dbbd40SGerald Van Baren nodeoffset = fdt_add_subnode(fdt, 0, "bd_t"); 33464dbbd40SGerald Van Baren if (nodeoffset < 0) { 3355fe6be62SGerald Van Baren printf("WARNING: could not create /bd_t %s.\n", 33635ec398fSGerald Van Baren fdt_strerror(nodeoffset)); 3375fe6be62SGerald Van Baren printf("fdt_bd_t: %s\n", fdt_strerror(nodeoffset)); 33864dbbd40SGerald Van Baren return nodeoffset; 33964dbbd40SGerald Van Baren } 34064dbbd40SGerald Van Baren /* 34164dbbd40SGerald Van Baren * Use the string/pointer structure to create the entries... 34264dbbd40SGerald Van Baren */ 34364dbbd40SGerald Van Baren for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) { 34464dbbd40SGerald Van Baren tmp = cpu_to_be32(getenv("bootargs")); 34535ec398fSGerald Van Baren err = fdt_setprop(fdt, nodeoffset, 34635ec398fSGerald Van Baren bd_map[i].name, &tmp, sizeof(tmp)); 34764dbbd40SGerald Van Baren if (err < 0) 3485fe6be62SGerald Van Baren printf("WARNING: could not set %s %s.\n", 34935ec398fSGerald Van Baren bd_map[i].name, fdt_strerror(err)); 35064dbbd40SGerald Van Baren } 35164dbbd40SGerald Van Baren /* 35264dbbd40SGerald Van Baren * Add a couple of oddball entries... 35364dbbd40SGerald Van Baren */ 35464dbbd40SGerald Van Baren err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6); 35564dbbd40SGerald Van Baren if (err < 0) 3565fe6be62SGerald Van Baren printf("WARNING: could not set enetaddr %s.\n", 35735ec398fSGerald Van Baren fdt_strerror(err)); 35864dbbd40SGerald Van Baren err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4); 35964dbbd40SGerald Van Baren if (err < 0) 3605fe6be62SGerald Van Baren printf("WARNING: could not set ethspeed %s.\n", 36135ec398fSGerald Van Baren fdt_strerror(err)); 36264dbbd40SGerald Van Baren return 0; 36364dbbd40SGerald Van Baren } 364c28abb9cSGerald Van Baren #endif /* ifdef CONFIG_OF_HAS_BD_T */ 36564dbbd40SGerald Van Baren 366e93becf8SKumar Gala void do_fixup_by_path(void *fdt, const char *path, const char *prop, 367e93becf8SKumar Gala const void *val, int len, int create) 368e93becf8SKumar Gala { 369e93becf8SKumar Gala #if defined(DEBUG) 370e93becf8SKumar Gala int i; 371e93becf8SKumar Gala debug("Updating property '%s/%s' = ", node, prop); 372e93becf8SKumar Gala for (i = 0; i < len; i++) 373e93becf8SKumar Gala debug(" %.2x", *(u8*)(val+i)); 374e93becf8SKumar Gala debug("\n"); 375e93becf8SKumar Gala #endif 376e93becf8SKumar Gala int rc = fdt_find_and_setprop(fdt, path, prop, val, len, create); 377e93becf8SKumar Gala if (rc) 378e93becf8SKumar Gala printf("Unable to update property %s:%s, err=%s\n", 379e93becf8SKumar Gala path, prop, fdt_strerror(rc)); 380e93becf8SKumar Gala } 381e93becf8SKumar Gala 382e93becf8SKumar Gala void do_fixup_by_path_u32(void *fdt, const char *path, const char *prop, 383e93becf8SKumar Gala u32 val, int create) 384e93becf8SKumar Gala { 385e93becf8SKumar Gala val = cpu_to_fdt32(val); 386e93becf8SKumar Gala do_fixup_by_path(fdt, path, prop, &val, sizeof(val), create); 387e93becf8SKumar Gala } 388e93becf8SKumar Gala 389*ab544633SKumar Gala void fdt_fixup_ethernet(void *fdt, bd_t *bd) 390*ab544633SKumar Gala { 391*ab544633SKumar Gala int node; 392*ab544633SKumar Gala const char *path; 393*ab544633SKumar Gala 394*ab544633SKumar Gala node = fdt_path_offset(fdt, "/aliases"); 395*ab544633SKumar Gala if (node >= 0) { 396*ab544633SKumar Gala #if defined(CONFIG_HAS_ETH0) 397*ab544633SKumar Gala path = fdt_getprop(fdt, node, "ethernet0", NULL); 398*ab544633SKumar Gala if (path) { 399*ab544633SKumar Gala do_fixup_by_path(fdt, path, "mac-address", 400*ab544633SKumar Gala bd->bi_enetaddr, 6, 0); 401*ab544633SKumar Gala do_fixup_by_path(fdt, path, "local-mac-address", 402*ab544633SKumar Gala bd->bi_enetaddr, 6, 1); 403*ab544633SKumar Gala } 404*ab544633SKumar Gala #endif 405*ab544633SKumar Gala #if defined(CONFIG_HAS_ETH1) 406*ab544633SKumar Gala path = fdt_getprop(fdt, node, "ethernet1", NULL); 407*ab544633SKumar Gala if (path) { 408*ab544633SKumar Gala do_fixup_by_path(fdt, path, "mac-address", 409*ab544633SKumar Gala bd->bi_enet1addr, 6, 0); 410*ab544633SKumar Gala do_fixup_by_path(fdt, path, "local-mac-address", 411*ab544633SKumar Gala bd->bi_enet1addr, 6, 1); 412*ab544633SKumar Gala } 413*ab544633SKumar Gala #endif 414*ab544633SKumar Gala #if defined(CONFIG_HAS_ETH2) 415*ab544633SKumar Gala path = fdt_getprop(fdt, node, "ethernet2", NULL); 416*ab544633SKumar Gala if (path) { 417*ab544633SKumar Gala do_fixup_by_path(fdt, path, "mac-address", 418*ab544633SKumar Gala bd->bi_enet2addr, 6, 0); 419*ab544633SKumar Gala do_fixup_by_path(fdt, path, "local-mac-address", 420*ab544633SKumar Gala bd->bi_enet2addr, 6, 1); 421*ab544633SKumar Gala } 422*ab544633SKumar Gala #endif 423*ab544633SKumar Gala #if defined(CONFIG_HAS_ETH3) 424*ab544633SKumar Gala path = fdt_getprop(fdt, node, "ethernet3", NULL); 425*ab544633SKumar Gala if (path) { 426*ab544633SKumar Gala do_fixup_by_path(fdt, path, "mac-address", 427*ab544633SKumar Gala bd->bi_enet3addr, 6, 0); 428*ab544633SKumar Gala do_fixup_by_path(fdt, path, "local-mac-address", 429*ab544633SKumar Gala bd->bi_enet3addr, 6, 1); 430*ab544633SKumar Gala } 431*ab544633SKumar Gala #endif 432*ab544633SKumar Gala } 433*ab544633SKumar Gala } 434*ab544633SKumar Gala 43564dbbd40SGerald Van Baren #endif /* CONFIG_OF_LIBFDT */ 436