int qemu_fdt_nop_node(void *fdt, const char *node_path) { int r; r = fdt_nop_node(fdt, findnode_nofail(fdt, node_path)); if (r < 0) { error_report("%s: Couldn't nop node %s: %s", __func__, node_path, fdt_strerror(r)); exit(1); } return r; }
int qemu_devtree_nop_node(void *fdt, const char *node_path) { int r; r = fdt_nop_node(fdt, findnode_nofail(fdt, node_path)); if (r < 0) { fprintf(stderr, "%s: Couldn't nop node %s: %s\n", __func__, node_path, fdt_strerror(r)); exit(1); } return r; }
static void kill_fdt_phy(void *fdt, int offset, void *arg) { int len, phy_offset; const fdt32_t *php; uint32_t phandle; php = fdt_getprop(fdt, offset, "phy-handle", &len); if (php && len == sizeof(*php)) { phandle = fdt32_to_cpu(*php); fdt_nop_property(fdt, offset, "phy-handle"); phy_offset = fdt_node_offset_by_phandle(fdt, phandle); if (phy_offset > 0) fdt_nop_node(fdt, phy_offset); } }
static __init int remove_gic(void *fdt) { const unsigned int cpu_ehci_int = 2; const unsigned int cpu_uart_int = 4; const unsigned int cpu_eth_int = 6; int gic_off, cpu_off, uart_off, eth_off, ehci_off, err; uint32_t cfg, cpu_phandle; /* leave the GIC node intact if a GIC is present */ cfg = __raw_readl((uint32_t *)SEAD_CONFIG); if (cfg & SEAD_CONFIG_GIC_PRESENT) return 0; gic_off = fdt_node_offset_by_compatible(fdt, -1, "mti,gic"); if (gic_off < 0) { pr_err("unable to find DT GIC node: %d\n", gic_off); return gic_off; } err = fdt_nop_node(fdt, gic_off); if (err) { pr_err("unable to nop GIC node\n"); return err; } cpu_off = fdt_node_offset_by_compatible(fdt, -1, "mti,cpu-interrupt-controller"); if (cpu_off < 0) { pr_err("unable to find CPU intc node: %d\n", cpu_off); return cpu_off; } cpu_phandle = fdt_get_phandle(fdt, cpu_off); if (!cpu_phandle) { pr_err("unable to get CPU intc phandle\n"); return -EINVAL; } uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a"); while (uart_off >= 0) { err = fdt_setprop_u32(fdt, uart_off, "interrupt-parent", cpu_phandle); if (err) { pr_warn("unable to set UART interrupt-parent: %d\n", err); return err; } err = fdt_setprop_u32(fdt, uart_off, "interrupts", cpu_uart_int); if (err) { pr_err("unable to set UART interrupts property: %d\n", err); return err; } uart_off = fdt_node_offset_by_compatible(fdt, uart_off, "ns16550a"); } if (uart_off != -FDT_ERR_NOTFOUND) { pr_err("error searching for UART DT node: %d\n", uart_off); return uart_off; } eth_off = fdt_node_offset_by_compatible(fdt, -1, "smsc,lan9115"); if (eth_off < 0) { pr_err("unable to find ethernet DT node: %d\n", eth_off); return eth_off; } err = fdt_setprop_u32(fdt, eth_off, "interrupt-parent", cpu_phandle); if (err) { pr_err("unable to set ethernet interrupt-parent: %d\n", err); return err; } err = fdt_setprop_u32(fdt, eth_off, "interrupts", cpu_eth_int); if (err) { pr_err("unable to set ethernet interrupts property: %d\n", err); return err; } ehci_off = fdt_node_offset_by_compatible(fdt, -1, "generic-ehci"); if (ehci_off < 0) { pr_err("unable to find EHCI DT node: %d\n", ehci_off); return ehci_off; } err = fdt_setprop_u32(fdt, ehci_off, "interrupt-parent", cpu_phandle); if (err) { pr_err("unable to set EHCI interrupt-parent: %d\n", err); return err; } err = fdt_setprop_u32(fdt, ehci_off, "interrupts", cpu_ehci_int); if (err) { pr_err("unable to set EHCI interrupts property: %d\n", err); return err; } return 0; }
int board_fixup_fdt(void) { char fdt_key[16]; int qlm; char env_var[16]; const char *mode; int node; /* First patch the PHY configuration based on board revision */ octeon_fdt_patch_rename((void *)(gd->fdt_blob), gd->arch.board_desc.rev_major == 1 ? "0,rev1" : "0,notrev1", "cavium,board-trim", false, NULL, NULL); /* Next patch CPU revision chages */ for (node = 0; node < CVMX_MAX_NODES; node++) { if (!(gd->arch.node_mask & (1 << node))) continue; if (OCTEON_IS_MODEL(OCTEON_CN78XX_PASS1_0)) sprintf(fdt_key, "%d,rev1.0", node); else sprintf(fdt_key, "%d,notrev1.0", node); octeon_fdt_patch((void *)(gd->fdt_blob), fdt_key, "cavium,cpu-trim"); } for (qlm = 0; qlm < 8; qlm++) { sprintf(env_var, "qlm%d:%d_mode", qlm, 0); mode = getenv(env_var); sprintf(fdt_key, "%d,none", qlm); if (!mode) { sprintf(fdt_key, "%d,none", qlm); } else if (!strncmp(mode, "sgmii", 5)) { sprintf(fdt_key, "%d,sgmii", qlm); } else if (!strncmp(mode, "xaui", 4)) { sprintf(fdt_key, "%d,xaui", qlm); } else if (!strncmp(mode, "dxaui", 5)) { sprintf(fdt_key, "%d,dxaui", qlm); } else if (!strcmp(mode, "ilk")) { if (qlm < 4) printf("Error: ILK not supported on QLM %d\n", qlm); else sprintf(fdt_key, "%d,ilk", qlm); } else if (!strncmp(mode, "rxaui", 5)) { sprintf(fdt_key, "%d,rxaui", qlm); } else if (!strncmp(mode, "xlaui", 5)) { if (qlm < 4) printf("Error: XLAUI not supported on QLM %d\n", qlm); else sprintf(fdt_key, "%d,xlaui", qlm); } else if (!strncmp(mode, "xfi", 3)) { if (qlm < 4) printf("Error: XFI not supported on QLM %d\n", qlm); else sprintf(fdt_key, "%d,xfi", qlm); } else if (!strncmp(mode, "10G_KR", 6)) { if (qlm < 4) printf("Error: 10G_KR not supported on QLM %d\n", qlm); else sprintf(fdt_key, "%d,10G_KR", qlm); } else if (!strncmp(mode, "40G_KR4", 7)) { if (qlm < 4) printf("Error: 40G_KR4 not supported on QLM %d\n", qlm); else sprintf(fdt_key, "%d,40G_KR4", qlm); } debug("Patching qlm %d for %s\n", qlm, fdt_key); octeon_fdt_patch_rename((void *)gd->fdt_blob, fdt_key, NULL, true, strstr(mode, ",no_phy") ? kill_fdt_phy : NULL, NULL); } /* Test for node 1 */ if (!(gd->arch.node_mask & (1 << 1))) { octeon_fdt_patch((void *)(gd->fdt_blob), "1,none", "cavium,node-trim"); goto final_cleanup; } /* This won't do anything if node 1 is missing */ for (qlm = 10; qlm < 18; qlm++) { sprintf(env_var, "qlm%d:%d_mode", qlm - 10, 1); mode = getenv(env_var); sprintf(fdt_key, "%d,none", qlm); if (!mode) { sprintf(fdt_key, "%d,none", qlm); } else if (!strncmp(mode, "sgmii", 5)) { sprintf(fdt_key, "%d,sgmii", qlm); } else if (!strncmp(mode, "xaui", 4)) { sprintf(fdt_key, "%d,xaui", qlm); } else if (!strncmp(mode, "dxaui", 5)) { sprintf(fdt_key, "%d,dxaui", qlm); } else if (!strcmp(mode, "ilk")) { if (qlm < 4) printf("Error: ILK not supported on QLM %d\n", qlm); else sprintf(fdt_key, "%d,ilk", qlm); } else if (!strncmp(mode, "rxaui", 5)) { sprintf(fdt_key, "%d,rxaui", qlm); } else if (!strncmp(mode, "xlaui", 5)) { if (qlm < 4) printf("Error: XLAUI not supported on QLM %d\n", qlm); else sprintf(fdt_key, "%d,xlaui", qlm); } else if (!strncmp(mode, "xfi", 3)) { if (qlm < 4) printf("Error: XFI not supported on QLM %d\n", qlm); else sprintf(fdt_key, "%d,xfi", qlm); } else if (!strncmp(mode, "10G_KR", 6)) { if (qlm < 4) printf("Error: 10G_KR not supported on QLM %d\n", qlm); else sprintf(fdt_key, "%d,10G_KR", qlm); } else if (!strncmp(mode, "40G_KR4", 7)) { if (qlm < 4) printf("Error: 40G_KR4 not supported on QLM %d\n", qlm); else sprintf(fdt_key, "%d,40G_KR4", qlm); } debug("Patching qlm %d for %s\n", qlm, fdt_key); octeon_fdt_patch_rename((void *)gd->fdt_blob, fdt_key, NULL, true, strstr(mode, ",no_phy") ? kill_fdt_phy : NULL, NULL); } final_cleanup: node = fdt_node_offset_by_compatible((void *)gd->fdt_blob, -1, "cavium,octeon-7890-bgx"); while (node != -FDT_ERR_NOTFOUND) { int depth = 0; int child = fdt_next_node((void *)gd->fdt_blob, node, &depth); if (depth != 1) fdt_nop_node((void *)gd->fdt_blob, node); node = fdt_node_offset_by_compatible((void *)gd->fdt_blob, node, "cavium,octeon-7890-bgx"); } return 0; }