static void __init process_multiboot_node(const void *fdt, int node, const char *name, u32 address_cells, u32 size_cells) { static int kind_guess = 0; const struct fdt_property *prop; const __be32 *cell; bootmodule_kind kind; paddr_t start, size; const char *cmdline; int len; if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 || fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 ) kind = BOOTMOD_KERNEL; else if ( fdt_node_check_compatible(fdt, node, "xen,linux-initrd") == 0 || fdt_node_check_compatible(fdt, node, "multiboot,ramdisk") == 0 ) kind = BOOTMOD_RAMDISK; else if ( fdt_node_check_compatible(fdt, node, "xen,xsm-policy") == 0 ) kind = BOOTMOD_XSM; else kind = BOOTMOD_UNKNOWN; /* Guess that first two unknown are kernel and ramdisk respectively. */ if ( kind == BOOTMOD_UNKNOWN ) { switch ( kind_guess++ ) { case 0: kind = BOOTMOD_KERNEL; break; case 1: kind = BOOTMOD_RAMDISK; break; default: break; } } prop = fdt_get_property(fdt, node, "reg", &len); if ( !prop ) panic("node %s missing `reg' property\n", name); if ( len < dt_cells_to_size(address_cells + size_cells) ) panic("fdt: node `%s': `reg` property length is too short\n", name); cell = (const __be32 *)prop->data; device_tree_get_reg(&cell, address_cells, size_cells, &start, &size); prop = fdt_get_property(fdt, node, "bootargs", &len); if ( prop ) { if ( len > BOOTMOD_MAX_CMDLINE ) panic("module %s command line too long\n", name); cmdline = prop->data; } else cmdline = NULL; add_boot_module(kind, start, size, cmdline); }
static bool fit_cfg_compatible(const void *itb, int cfg, const char *compat) { const void *fdt; const char *fdt_name; bool ret; fdt_name = fdt_getprop(itb, cfg, "fdt", NULL); if (!fdt_name) { return false; } fdt = fit_load_image_alloc(itb, fdt_name, NULL, NULL); if (!fdt) { return false; } if (fdt_check_header(fdt)) { ret = false; goto out; } if (fdt_node_check_compatible(fdt, 0, compat)) { ret = false; goto out; } ret = true; out: g_free((void *) fdt); return ret; }
static int sopc_device_probe(FDTMachineInfo *fdti, const char *node_path, int pass, uint32_t offset) { DevInfo **dev = &(devices[0]); while (*dev) { const char **compat = &((*dev)->compat[0]); while (*compat) { if (0 == fdt_node_check_compatible(fdti->fdt, fdt_path_offset(fdti->fdt, node_path), *compat)) { if (pass == (*dev)->pass) { printf("Adding a device for node %s\n", fdt_get_name(fdti->fdt, fdt_path_offset(fdti->fdt, node_path), NULL)); (*dev)->probe(fdti, node_path, offset); return 0; } if (pass < (*dev)->pass) { /* Probe again on the next pass */ return 1; } } compat++; } dev++; } return 0; }
static int prd_info_init(fwts_framework *fw) { if (fw->fdt) { #ifdef HAVE_LIBFDT int node; node = fdt_path_offset(fw->fdt, "/ibm,opal/diagnostics"); if (node >= 0) { if (!fdt_node_check_compatible(fw->fdt, node, "ibm,opal-prd")) { return FWTS_OK; } else { return FWTS_SKIP; } } #endif } else { fwts_log_info(fw, "The OPAL PRD device tree node is not" " able to be detected so skipping the prd_info" " test. There may be tools missing such as" " libfdt-dev or dtc, check that the packages" " are installed and re-build if needed." " If this condition persists try running the" " dt_base test to further diagnose. If dt_base" " test is not available this is probably a" " setup problem."); return FWTS_SKIP; } /* only run test when fdt node is confirmed */ return FWTS_SKIP; }
/** * driver_check_compatible() - Check if a driver is compatible with this node * * @param blob: Device tree pointer * @param offset: Offset of node in device tree * @param of_match: List of compatible strings to match * @param of_idp: Returns the match that was found * @return 0 if there is a match, -ENOENT if no match, -ENODEV if the node * does not have a compatible string, other error <0 if there is a device * tree error */ static int driver_check_compatible(const void *blob, int offset, const struct udevice_id *of_match, const struct udevice_id **of_idp) { int ret; *of_idp = NULL; if (!of_match) return -ENOENT; while (of_match->compatible) { ret = fdt_node_check_compatible(blob, offset, of_match->compatible); if (!ret) { *of_idp = of_match; return 0; } else if (ret == -FDT_ERR_NOTFOUND) { return -ENODEV; } else if (ret < 0) { return -EINVAL; } of_match++; } return -ENOENT; }
int mkbp_tps65090_init(void) { const void *blob = gd->fdt_blob; int node, parent; node = fdtdec_next_compatible(blob, 0, COMPAT_TI_TPS65090); if (node < 0) { debug("%s: Node not found\n", __func__); return -ENOENT; } parent = fdt_parent_offset(blob, node); if (parent < 0) { debug("%s: Cannot find node parent\n", __func__); return -1; } if (fdt_node_check_compatible(blob, parent, fdtdec_get_compatible(COMPAT_GOOGLE_MKBP))) { debug("%s: TPS65090 not behind MKBP\n", __func__); return -ENOENT; } mkbp_dev = board_get_mkbp_dev(); if (!mkbp_dev) { debug("%s: no mkbp device: cannot init tps65090\n", __func__); return -1; } debug("%s: accessing tps65090 through MKBP\n", __func__); return 0; }
void ft_cpu_setup(void *blob, bd_t *bd) { sys_info_t sys_info; int off, ndepth = 0; get_sys_info(&sys_info); do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "timebase-frequency", bd->bi_intfreq, 1); do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "clock-frequency", bd->bi_intfreq, 1); do_fixup_by_path_u32(blob, "/plb", "clock-frequency", sys_info.freqPLB, 1); do_fixup_by_path_u32(blob, "/plb/opb", "clock-frequency", sys_info.freqOPB, 1); if (fdt_path_offset(blob, "/plb/opb/ebc") >= 0) do_fixup_by_path_u32(blob, "/plb/opb/ebc", "clock-frequency", sys_info.freqEBC, 1); else do_fixup_by_path_u32(blob, "/plb/ebc", "clock-frequency", sys_info.freqEBC, 1); fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); /* * Fixup all UART clocks for CPU internal UARTs * (only these UARTs are definitely clocked by gd->arch.uart_clk) * * These UARTs are direct childs of /plb/opb. This code * does not touch any UARTs that are connected to the ebc. */ off = fdt_path_offset(blob, "/plb/opb"); while ((off = fdt_next_node(blob, off, &ndepth)) >= 0) { /* * process all sub nodes and stop when we are back * at the starting depth */ if (ndepth <= 0) break; /* only update direct childs */ if ((ndepth == 1) && (fdt_node_check_compatible(blob, off, "ns16550") == 0)) fdt_setprop(blob, off, "clock-frequency", (void *)&gd->arch.uart_clk, 4); } /* * Fixup all ethernet nodes * Note: aliases in the dts are required for this */ fdt_fixup_ethernet(blob); /* * Fixup all available PCIe nodes by setting the device_type property */ fdt_pcie_setup(blob); }
enum fdt_compat_id fdt_decode_lookup(const void *blob, int node) { enum fdt_compat_id id; /* Search our drivers */ for (id = COMPAT_UNKNOWN; id < COMPAT_COUNT; id++) if (0 == fdt_node_check_compatible(blob, node, compat_names[id])) return id; return COMPAT_UNKNOWN; }
int __octeon_spi_board_initialize(void) { int i; int nodeoffset, next_nodeoffset; const void *nodep; u32 *pgpio_handle; int gpio_offset; int phandle; int max_spi = 2; u32 tag; int level = 0; debug("%s: Entry\n", __func__); if (!octeon_has_feature(OCTEON_FEATURE_SPI)) return -1; nodeoffset = fdt_path_offset(gd->fdt_blob, "/soc/spi"); if (nodeoffset < 0) { debug("SPI interface not found in device tree\n"); return -1; } if (fdt_node_check_compatible(gd->fdt_blob, nodeoffset, "cavium,octeon-3010-spi")) { puts("Incompatible SPI interface type\n"); return -1; } while ((next_nodeoffset = fdt_next_node(gd->fdt_blob, nodeoffset, &level)) > 0) { if (level < 0) break; if (level > 1) continue; if (fdt_node_check_compatible(gd->fdt_blob, next_nodeoffset, "spi-flash")) { } } }
const struct uniphier_board_data *uniphier_get_board_param(void) { int i; for (i = 0; i < ARRAY_SIZE(uniphier_boards); i++) { if (!fdt_node_check_compatible(gd->fdt_blob, 0, uniphier_boards[i].compatible)) return uniphier_boards[i].param; } return NULL; }
static int rpc_spi_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob; ofnode node; int ret, off; /* * Check if there are any SPI NOR child nodes, if so, bind as * this controller will be operated in SPI mode. */ dev_for_each_subnode(node, parent) { off = ofnode_to_offset(node); ret = fdt_node_check_compatible(fdt, off, "spi-flash"); if (!ret) return 0; ret = fdt_node_check_compatible(fdt, off, "jedec,spi-nor"); if (!ret) return 0; }
const struct dt_driver *dt_find_compatible_driver(const void *fdt, int offs) { const struct dt_device_match *dm; const struct dt_driver *drv; for_each_dt_driver(drv) for (dm = drv->match_table; dm; dm++) if (!fdt_node_check_compatible(fdt, offs, dm->compatible)) return drv; return NULL; }
int fdtdec_next_compatible_subnode(const void *blob, int node, enum fdt_compat_id id, int *depthp) { do { node = fdt_next_node(blob, node, depthp); } while (*depthp > 1); /* If this is a direct subnode, and compatible, return it */ if (*depthp == 1 && 0 == fdt_node_check_compatible( blob, node, compat_names[id])) return node; return -FDT_ERR_NOTFOUND; }
int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible) { uint32_t tag; int offset, nextoffset; int err; CHECK_HEADER(fdt); if (startoffset >= 0) { tag = fdt_next_tag(fdt, startoffset, &nextoffset); if (tag != FDT_BEGIN_NODE) return -FDT_ERR_BADOFFSET; } else { nextoffset = 0; } /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_node_check_compatible(), then if * that didn't find what we want, we scan over them again * making our way to the next node. Still it's the easiest to * implement approach; performance can come later. */ do { offset = nextoffset; tag = fdt_next_tag(fdt, offset, &nextoffset); switch (tag) { case FDT_BEGIN_NODE: err = fdt_node_check_compatible(fdt, offset, compatible); if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) return err; else if (err == 0) return offset; break; case FDT_PROP: case FDT_END: case FDT_END_NODE: case FDT_NOP: break; default: return -FDT_ERR_BADSTRUCTURE; } } while (tag != FDT_END); return -FDT_ERR_NOTFOUND; }
void check_compatible(const void *fdt, const char *path, const char *compat) { int offset, err; offset = fdt_path_offset(fdt, path); if (offset < 0) FAIL("fdt_path_offset(%s): %s", path, fdt_strerror(offset)); err = fdt_node_check_compatible(fdt, offset, compat); if (err < 0) FAIL("fdt_node_check_compatible(%s): %s", path, fdt_strerror(err)); if (err != 0) FAIL("%s is not compatible with \"%s\"", path, compat); }
int rk3288_qos_init(void) { int val = 2 << PRIORITY_HIGH_SHIFT | 2 << PRIORITY_LOW_SHIFT; /* set vop qos to higher priority */ writel(val, CPU_AXI_QOS_PRIORITY + VIO0_VOP_QOS); writel(val, CPU_AXI_QOS_PRIORITY + VIO1_VOP_QOS); if (!fdt_node_check_compatible(gd->fdt_blob, 0, "rockchip,rk3288-miniarm")) { /* set isp qos to higher priority */ writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_R_QOS); writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W0_QOS); writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W1_QOS); } return 0; }
int fdt_decode_next_alias(const void *blob, const char *name, enum fdt_compat_id id, int *upto) { #define MAX_STR_LEN 20 char str[MAX_STR_LEN + 20]; int node, err; sprintf(str, "%.*s%d", MAX_STR_LEN, name, *upto); (*upto)++; node = find_alias_node(blob, str); if (node < 0) return node; err = fdt_node_check_compatible(blob, node, compat_names[id]); if (err < 0) return err; return err ? -FDT_ERR_MISSING : node; }
int fdtdec_next_alias(const void *blob, const char *name, enum fdt_compat_id id, int *upto) { #define MAX_STR_LEN 20 char str[MAX_STR_LEN + 20]; int node, err; /* snprintf() is not available */ assert(strlen(name) < MAX_STR_LEN); sprintf(str, "%.*s%d", MAX_STR_LEN, name, *upto); (*upto)++; node = find_alias_node(blob, str); if (node < 0) return node; err = fdt_node_check_compatible(blob, node, compat_names[id]); if (err < 0) return err; return err ? -FDT_ERR_NOTFOUND : node; }
int board_init(void) { #ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM struct udevice *pinctrl; int ret; /* * We need to implement sdcard iomux here for the further * initlization, otherwise, it'll hit sdcard command sending * timeout exception. */ ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); if (ret) { debug("%s: Cannot find pinctrl device\n", __func__); goto err; } ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD); if (ret) { debug("%s: Failed to set up SD card\n", __func__); goto err; } return 0; err: printf("board_init: Error %d\n", ret); /* No way to report error here */ hang(); return -1; #else int ret; /* We do some SoC one time setting here */ if (!fdt_node_check_compatible(gd->fdt_blob, 0, "google,veyron")) { ret = veyron_init(); if (ret) return ret; } return 0; #endif }
int __init early_init_dt_scan_chosen_serial(void) { int offset; const char *p; int l; const struct of_device_id *match = __earlycon_of_table; const void *fdt = initial_boot_params; offset = fdt_path_offset(fdt, "/chosen"); if (offset < 0) offset = fdt_path_offset(fdt, "/chosen@0"); if (offset < 0) return -ENOENT; p = fdt_getprop(fdt, offset, "stdout-path", &l); if (!p) p = fdt_getprop(fdt, offset, "linux,stdout-path", &l); if (!p || !l) return -ENOENT; /* Get the node specified by stdout-path */ offset = fdt_path_offset(fdt, p); if (offset < 0) return -ENODEV; while (match->compatible) { unsigned long addr; if (fdt_node_check_compatible(fdt, offset, match->compatible)) { match++; continue; } addr = fdt_translate_address(fdt, offset); if (!addr) return -ENXIO; of_setup_earlycon(addr, match->data); return 0; } return -ENODEV; }
/* Verify parent MPU6000 exists */ static int mpu6000_accel_probe(const char *name) { const void *blob = fdtparse_get_blob(); int offset, parent_offset, ret; char *parent; struct obj *parent_obj; offset = fdt_path_offset(blob, name); if (offset < 0) { return 0; } if (fdt_node_check_compatible(blob, offset, MPU6000_ACCEL_COMPAT)) { return 0; } parent_offset = fdt_parent_offset(blob, offset); if (parent_offset < 0) { return 0; } parent = fdtparse_get_path(blob, parent_offset); if (!parent) { return 0; } /* Attempt to get parent MPU6000 */ parent_obj = device_get(parent); if (parent_obj) { /* Found it! Good to go! */ device_put(parent_obj); ret = 1; } else { /* No MPU6000, no MPU6000 accelerometer */ ret = 0; } free(parent); return ret; }
static __init const void *sead3_fixup_fdt(const void *fdt, const void *match_data) { static unsigned char fdt_buf[16 << 10] __initdata; int err; if (fdt_check_header(fdt)) panic("Corrupt DT"); /* if this isn't SEAD3, something went wrong */ BUG_ON(fdt_node_check_compatible(fdt, 0, "mti,sead-3")); fw_init_cmdline(); err = apply_mips_fdt_fixups(fdt_buf, sizeof(fdt_buf), fdt, sead3_fdt_fixups); if (err) panic("Unable to fixup FDT: %d", err); return fdt_buf; }
/** * driver_check_compatible() - Check if a driver is compatible with this node * * @param blob: Device tree pointer * @param offset: Offset of node in device tree * @param of_matchL List of compatible strings to match * @return 0 if there is a match, -ENOENT if no match, -ENODEV if the node * does not have a compatible string, other error <0 if there is a device * tree error */ static int driver_check_compatible(const void *blob, int offset, const struct device_id *of_match) { int ret; if (!of_match) return -ENOENT; while (of_match->compatible) { ret = fdt_node_check_compatible(blob, offset, of_match->compatible); if (!ret) return 0; else if (ret == -FDT_ERR_NOTFOUND) return -ENODEV; else if (ret < 0) return -EINVAL; of_match++; } return -ENOENT; }
int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible) { int offset, err; FDT_CHECK_HEADER(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_node_check_compatible(), then if * that didn't find what we want, we scan over them again * making our way to the next node. Still it's the easiest to * implement approach; performance can come later. */ for (offset = fdt_next_node(fdt, startoffset, NULL); offset >= 0; offset = fdt_next_node(fdt, offset, NULL)) { err = fdt_node_check_compatible(fdt, offset, compatible); if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) return err; else if (err == 0) return offset; } return offset; /* error from fdt_next_node() */ }
/** * fit_conf_find_compat * @fit: pointer to the FIT format image header * @fdt: pointer to the device tree to compare against * * fit_conf_find_compat() attempts to find the configuration whose fdt is the * most compatible with the passed in device tree. * * Example: * * / o image-tree * |-o images * | |-o fdt@1 * | |-o fdt@2 * | * |-o configurations * |-o config@1 * | |-fdt = fdt@1 * | * |-o config@2 * |-fdt = fdt@2 * * / o U-Boot fdt * |-compatible = "foo,bar", "bim,bam" * * / o kernel fdt1 * |-compatible = "foo,bar", * * / o kernel fdt2 * |-compatible = "bim,bam", "baz,biz" * * Configuration 1 would be picked because the first string in U-Boot's * compatible list, "foo,bar", matches a compatible string in the root of fdt1. * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1. * * returns: * offset to the configuration to use if one was found * -1 otherwise */ int fit_conf_find_compat(const void *fit, const void *fdt) { int ndepth = 0; int noffset, confs_noffset, images_noffset; const void *fdt_compat; int fdt_compat_len; int best_match_offset = 0; int best_match_pos = 0; confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); if (confs_noffset < 0 || images_noffset < 0) { debug("Can't find configurations or images nodes.\n"); return -1; } fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len); if (!fdt_compat) { debug("Fdt for comparison has no \"compatible\" property.\n"); return -1; } /* * Loop over the configurations in the FIT image. */ for (noffset = fdt_next_node(fit, confs_noffset, &ndepth); (noffset >= 0) && (ndepth > 0); noffset = fdt_next_node(fit, noffset, &ndepth)) { const void *kfdt; const char *kfdt_name; int kfdt_noffset; const char *cur_fdt_compat; int len; size_t size; int i; if (ndepth > 1) continue; kfdt_name = fdt_getprop(fit, noffset, "fdt", &len); if (!kfdt_name) { debug("No fdt property found.\n"); continue; } kfdt_noffset = fdt_subnode_offset(fit, images_noffset, kfdt_name); if (kfdt_noffset < 0) { debug("No image node named \"%s\" found.\n", kfdt_name); continue; } /* * Get a pointer to this configuration's fdt. */ if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) { debug("Failed to get fdt \"%s\".\n", kfdt_name); continue; } len = fdt_compat_len; cur_fdt_compat = fdt_compat; /* * Look for a match for each U-Boot compatibility string in * turn in this configuration's fdt. */ for (i = 0; len > 0 && (!best_match_offset || best_match_pos > i); i++) { int cur_len = strlen(cur_fdt_compat) + 1; if (!fdt_node_check_compatible(kfdt, 0, cur_fdt_compat)) { best_match_offset = noffset; best_match_pos = i; break; } len -= cur_len; cur_fdt_compat += cur_len; } } if (!best_match_offset) { debug("No match found.\n"); return -1; } return best_match_offset; }
static struct obj *mpu6000_accel_ctor(const char *name) { const void *blob = fdtparse_get_blob(); int offset, parent_offset; char *parent; struct obj *accel_obj; struct accel *accel; struct mpu6000_accel *mpu_accel; offset = fdt_path_offset(blob, name); if (offset < 0) { return NULL; } if (fdt_node_check_compatible(blob, offset, MPU6000_ACCEL_COMPAT)) { return NULL; } parent_offset = fdt_parent_offset(blob, offset); if (parent_offset < 0) { return NULL; } parent = fdtparse_get_path(blob, parent_offset); if (!parent) { return NULL; } accel_obj = instantiate(name, &accel_class, &mpu6000_accel_ops, struct accel); if (!accel_obj) { goto err_free_parent; } /* Connect to parent MPU6000 */ accel = to_accel(accel_obj); accel->device.parent = device_get(parent); if (!accel->device.parent) { goto err_free_obj; } /* Set up private data */ accel->priv = kmalloc(sizeof(struct mpu6000_accel)); if (!accel->priv) { goto err_free_obj; } mpu_accel = (struct mpu6000_accel *) accel->priv; mpu_accel->ready = 0; /* Export to the OS */ class_export_member(accel_obj); free(parent); return accel_obj; err_free_obj: class_deinstantiate(accel_obj); err_free_parent: free(parent); return NULL; }
DebugUART * debug_uart_from_fdt(const void *fdt) { const char *name; const char *type; int node; int len; phys_addr_t regs; int32 clock = 0; int32 speed = 0; const void *prop; DebugUART *uart = NULL; if (fdt == NULL) return NULL; name = fdt_get_alias(fdt, "serial"); if (name == NULL) name = fdt_get_alias(fdt, "serial0"); if (name == NULL) name = fdt_get_alias(fdt, "serial1"); // TODO: else use /chosen linux,stdout-path if (name == NULL) return NULL; node = fdt_path_offset(fdt, name); //dprintf("serial: using '%s', node %d\n", name, node); if (node < 0) return NULL; type = (const char *)fdt_getprop(fdt, node, "device_type", &len); //dprintf("serial: type: '%s'\n", type); if (type == NULL || strcmp(type, "serial")) return NULL; // determine the MMIO address // TODO: ppc460 use 64bit addressing, but U-Boot seems to map it below 4G, // and the FDT is not very clear. libfdt is also getting 64bit addr support. // so FIXME someday. prop = fdt_getprop(fdt, node, "virtual-reg", &len); if (prop && len == 4) { regs = fdt32_to_cpu(*(uint32_t *)prop); //dprintf("serial: virtual-reg 0x%08llx\n", (int64)regs); } else { prop = fdt_getprop(fdt, node, "reg", &len); if (prop && len >= 4) { regs = fdt32_to_cpu(*(uint32_t *)prop); //dprintf("serial: reg 0x%08llx\n", (int64)regs); } else return NULL; } // get the UART clock rate prop = fdt_getprop(fdt, node, "clock-frequency", &len); if (prop && len == 4) { clock = fdt32_to_cpu(*(uint32_t *)prop); //dprintf("serial: clock %ld\n", clock); } // get current speed (XXX: not yet passed over) prop = fdt_getprop(fdt, node, "current-speed", &len); if (prop && len == 4) { speed = fdt32_to_cpu(*(uint32_t *)prop); //dprintf("serial: speed %ld\n", speed); } if (fdt_node_check_compatible(fdt, node, "ns16550a") == 1 || fdt_node_check_compatible(fdt, node, "ns16550") == 1) { uart = arch_get_uart_8250(regs, clock); //dprintf("serial: using 8250\n"); // XXX:assume speed is already set (void)speed; } else { // TODO: handle more UART types // for when we can use U-Boot's console panic("Unknown UART type %s", type); } return uart; }
static int dt_sysinfo_check_ref_plat_compatible(fwts_framework *fw) { int node, compat_len, model_len; node = fdt_path_offset(fw->fdt, "/"); if (node < 0) { fwts_failed(fw, LOG_LEVEL_HIGH, "DTRootNodeMissing", "root device tree node is missing"); return FWTS_ERROR; } if (fdt_node_check_compatible(fw->fdt, node, op_powernv)) { fwts_failed(fw, LOG_LEVEL_HIGH, "DTCompatibleMissing", "DeviceTree failed validation, could not find" " the \"compatible\" property of \"%s\" in the " "root of the device tree", "ibm,powernv"); return FWTS_ERROR; } else { const char *model_buf, *compat_buf; char *orig_model_buf, *tmp_model_buf; compat_buf = fdt_getprop(fw->fdt, node, "compatible", &compat_len); model_buf = fdt_getprop(fw->fdt, node, "model", &model_len); if (!model_buf || !compat_buf) { fwts_failed(fw,LOG_LEVEL_HIGH, "DTSysInfoCheck", "Cannot read the properties for OpenPOWER" " Reference Compatible check"); return FWTS_ERROR; } /* need modifiable memory */ /* save original ptr to free */ tmp_model_buf = orig_model_buf = strdup(model_buf); if (!tmp_model_buf) { fwts_failed(fw, LOG_LEVEL_HIGH, "DTSysInfoCheck", "Unable to get memory for model" " compare for OpenPOWER" " Reference Compatible check"); return FWTS_ERROR; } tmp_model_buf = hidewhitespace(tmp_model_buf); if (!(strcmp(model_buf, tmp_model_buf) == 0)) { fwts_warning(fw, "DTSysInfoCheck" " See further advice in the log."); fwts_log_nl(fw); fwts_log_info_verbatim(fw, "DTSysInfoCheck" " Check the root \"model\" property" " from the device tree %s \"%s\".", DT_FS_PATH, model_buf); fwts_advice(fw, "Check the root \"model\" property" " from the device tree %s, " "there are whitespace inconsistentencies" " between the \"model\" property and " " the trimmed value of \"%s\", report" " this as a possible bug." " Run \"hexdump -C model\"" " from the \"%s\" directory to view" " the raw contents of the property.", DT_FS_PATH, tmp_model_buf, DT_FS_PATH); } if (machine_matches_reference_model(fw, compat_buf, compat_len, tmp_model_buf)) { fwts_passed(fw, "OpenPOWER Reference " "Compatible passed"); } else { fwts_failed(fw, LOG_LEVEL_HIGH, "DTOpenPOWERReferenceFailed", "Unable to find an OpenPOWER supported" " match"); /* adding verbatim to show proper string */ fwts_log_info_verbatim(fw, "Unable to find an OpenPOWER reference" " match for \"%s\"", tmp_model_buf); free(orig_model_buf); return FWTS_ERROR; } free(orig_model_buf); } return FWTS_OK; }
static struct obj *mpu6000_gyro_ctor(const char *name) { const void *blob = fdtparse_get_blob(); int offset, parent_offset; char *parent; struct obj *gyro_obj; struct gyro *gyro; struct mpu6000_gyro *mpu_gyro; offset = fdt_path_offset(blob, name); if (offset < 0) { return NULL; } if (fdt_node_check_compatible(blob, offset, MPU6000_GYRO_COMPAT)) { return NULL; } parent_offset = fdt_parent_offset(blob, offset); if (parent_offset < 0) { return NULL; } parent = fdtparse_get_path(blob, parent_offset); if (!parent) { return NULL; } gyro_obj = instantiate(name, &gyro_class, &mpu6000_gyro_ops, struct gyro); if (!gyro_obj) { goto err_free_parent; } /* Connect to parent MPU6000 */ gyro = to_gyro(gyro_obj); gyro->device.parent = device_get(parent); if (!gyro->device.parent) { goto err_free_obj; } /* Set up private data */ gyro->priv = kmalloc(sizeof(struct mpu6000_gyro)); if (!gyro->priv) { goto err_free_obj; } mpu_gyro = (struct mpu6000_gyro *) gyro->priv; mpu_gyro->ready = 0; /* Export to the OS */ class_export_member(gyro_obj); free(parent); return gyro_obj; err_free_obj: class_deinstantiate(gyro_obj); err_free_parent: free(parent); return NULL; }