X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=common%2Ffdt_support.c;h=75d0858e76317e71fb1f8839e5e8f8f0b1499653;hb=0ac8b1f437aa71c205f498d068d9d097cf72ce03;hp=8266bca7d6489a2ca8fb6f1015064184b137d2dd;hpb=272a1acf1ef574356e5da51f7d6b3b07ab4e9b83;p=u-boot diff --git a/common/fdt_support.c b/common/fdt_support.c index 8266bca7d6..75d0858e76 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -16,6 +16,7 @@ #include #include #include +#include /** * fdt_getprop_u32_default_node - Return a node's property or a default @@ -130,18 +131,6 @@ static int fdt_fixup_stdout(void *fdt, int chosenoff) OF_STDOUT_PATH, strlen(OF_STDOUT_PATH) + 1); } #elif defined(CONFIG_OF_STDOUT_VIA_ALIAS) && defined(CONFIG_CONS_INDEX) -static void fdt_fill_multisername(char *sername, size_t maxlen) -{ - const char *outname = stdio_devices[stdout]->name; - - if (strcmp(outname, "serial") > 0) - strncpy(sername, outname, maxlen); - - /* eserial? */ - if (strcmp(outname + 1, "serial") > 0) - strncpy(sername, outname + 1, maxlen); -} - static int fdt_fixup_stdout(void *fdt, int chosenoff) { int err; @@ -151,32 +140,35 @@ static int fdt_fixup_stdout(void *fdt, int chosenoff) int len; char tmp[256]; /* long enough */ - fdt_fill_multisername(sername, sizeof(sername) - 1); - if (!sername[0]) - sprintf(sername, "serial%d", CONFIG_CONS_INDEX - 1); + sprintf(sername, "serial%d", CONFIG_CONS_INDEX - 1); aliasoff = fdt_path_offset(fdt, "/aliases"); if (aliasoff < 0) { err = aliasoff; - goto error; + goto noalias; } path = fdt_getprop(fdt, aliasoff, sername, &len); if (!path) { err = len; - goto error; + goto noalias; } /* fdt_setprop may break "path" so we copy it to tmp buffer */ memcpy(tmp, path, len); err = fdt_setprop(fdt, chosenoff, "linux,stdout-path", tmp, len); -error: if (err < 0) printf("WARNING: could not set linux,stdout-path %s.\n", fdt_strerror(err)); return err; + +noalias: + printf("WARNING: %s: could not read %s alias: %s\n", + __func__, sername, fdt_strerror(err)); + + return 0; } #else static int fdt_fixup_stdout(void *fdt, int chosenoff) @@ -194,6 +186,31 @@ static inline int fdt_setprop_uxx(void *fdt, int nodeoffset, const char *name, return fdt_setprop_u32(fdt, nodeoffset, name, (uint32_t)val); } +int fdt_root(void *fdt) +{ + char *serial; + int err; + + err = fdt_check_header(fdt); + if (err < 0) { + printf("fdt_root: %s\n", fdt_strerror(err)); + return err; + } + + serial = getenv("serial#"); + if (serial) { + err = fdt_setprop(fdt, 0, "serial-number", serial, + strlen(serial) + 1); + + if (err < 0) { + printf("WARNING: could not set serial-number %s.\n", + fdt_strerror(err)); + return err; + } + } + + return 0; +} int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end) { @@ -429,6 +446,9 @@ int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) return err; } + if (!banks) + return 0; + len = fdt_pack_reg(blob, tmp, start, size, banks); err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); @@ -448,47 +468,49 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) void fdt_fixup_ethernet(void *fdt) { int node, i, j; - char enet[16], *tmp, *end; + char *tmp, *end; char mac[16]; const char *path; unsigned char mac_addr[6]; + int offset; node = fdt_path_offset(fdt, "/aliases"); if (node < 0) return; - if (!getenv("ethaddr")) { - if (getenv("usbethaddr")) { - strcpy(mac, "usbethaddr"); - } else { - debug("No ethernet MAC Address defined\n"); - return; - } - } else { - strcpy(mac, "ethaddr"); - } - - i = 0; - while ((tmp = getenv(mac)) != NULL) { - sprintf(enet, "ethernet%d", i); - path = fdt_getprop(fdt, node, enet, NULL); - if (!path) { - debug("No alias for %s\n", enet); - sprintf(mac, "eth%daddr", ++i); - continue; - } + for (offset = fdt_first_property_offset(fdt, node); + offset > 0; + offset = fdt_next_property_offset(fdt, offset)) { + const char *name; + int len = strlen("ethernet"); + + path = fdt_getprop_by_offset(fdt, offset, &name, NULL); + if (!strncmp(name, "ethernet", len)) { + i = trailing_strtol(name); + if (i != -1) { + if (i == 0) + strcpy(mac, "ethaddr"); + else + sprintf(mac, "eth%daddr", i); + } else { + continue; + } + tmp = getenv(mac); + if (!tmp) + continue; + + for (j = 0; j < 6; j++) { + mac_addr[j] = tmp ? + simple_strtoul(tmp, &end, 16) : 0; + if (tmp) + tmp = (*end) ? end + 1 : end; + } - for (j = 0; j < 6; j++) { - mac_addr[j] = tmp ? simple_strtoul(tmp, &end, 16) : 0; - if (tmp) - tmp = (*end) ? end+1 : end; + do_fixup_by_path(fdt, path, "mac-address", + &mac_addr, 6, 0); + do_fixup_by_path(fdt, path, "local-mac-address", + &mac_addr, 6, 1); } - - do_fixup_by_path(fdt, path, "mac-address", &mac_addr, 6, 0); - do_fixup_by_path(fdt, path, "local-mac-address", - &mac_addr, 6, 1); - - sprintf(mac, "eth%daddr", ++i); } } @@ -917,9 +939,8 @@ void fdt_del_node_and_alias(void *blob, const char *alias) /* Max address size we deal with */ #define OF_MAX_ADDR_CELLS 4 -#define OF_BAD_ADDR ((u64)-1) -#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ - (ns) > 0) +#define OF_BAD_ADDR FDT_ADDR_T_NONE +#define OF_CHECK_COUNTS(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS) /* Debug utility */ #ifdef DEBUG @@ -1087,7 +1108,7 @@ static u64 __of_translate_address(void *blob, int node_offset, const fdt32_t *in /* Cound address cells & copy address locally */ bus->count_cells(blob, parent, &na, &ns); - if (!OF_CHECK_COUNTS(na, ns)) { + if (!OF_CHECK_COUNTS(na)) { printf("%s: Bad cell count for %s\n", __FUNCTION__, fdt_get_name(blob, node_offset, NULL)); goto bail; @@ -1114,7 +1135,7 @@ static u64 __of_translate_address(void *blob, int node_offset, const fdt32_t *in /* Get new parent bus and counts */ pbus = &of_busses[0]; pbus->count_cells(blob, parent, &pna, &pns); - if (!OF_CHECK_COUNTS(pna, pns)) { + if (!OF_CHECK_COUNTS(pna)) { printf("%s: Bad cell count for %s\n", __FUNCTION__, fdt_get_name(blob, node_offset, NULL)); break; @@ -1533,7 +1554,7 @@ int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width, if (ret < 0) return ret; - snprintf(name, sizeof(name), "framebuffer@%llx", base_address); + snprintf(name, sizeof(name), "framebuffer@%" PRIx64, base_address); ret = fdt_set_name(fdt, node, name); if (ret < 0) return ret; @@ -1560,3 +1581,32 @@ int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width, return 0; } + +/* + * Update native-mode in display-timings from display environment variable. + * The node to update are specified by path. + */ +int fdt_fixup_display(void *blob, const char *path, const char *display) +{ + int off, toff; + + if (!display || !path) + return -FDT_ERR_NOTFOUND; + + toff = fdt_path_offset(blob, path); + if (toff >= 0) + toff = fdt_subnode_offset(blob, toff, "display-timings"); + if (toff < 0) + return toff; + + for (off = fdt_first_subnode(blob, toff); + off >= 0; + off = fdt_next_subnode(blob, off)) { + uint32_t h = fdt_get_phandle(blob, off); + debug("%s:0x%x\n", fdt_get_name(blob, off, NULL), + fdt32_to_cpu(h)); + if (strcasecmp(fdt_get_name(blob, off, NULL), display) == 0) + return fdt_setprop_u32(blob, toff, "native-mode", h); + } + return toff; +}