예제 #1
0
파일: bootfdt.c 프로젝트: Chong-Li/xen
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);
}
예제 #2
0
파일: loader-fit.c 프로젝트: 8tab/qemu
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;
}
예제 #4
0
파일: prd_info.c 프로젝트: 9elements/fwts
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;
}
예제 #5
0
파일: lists.c 프로젝트: PanizBertsch/u-boot
/**
 * 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;
}
예제 #6
0
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;
}
예제 #7
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);
}
예제 #8
0
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;
}
예제 #9
0
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")) {

		}
	}
}
예제 #10
0
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;
}
예제 #11
0
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;
	}
예제 #12
0
파일: dt.c 프로젝트: jbech-linaro/optee_os
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;
}
예제 #13
0
파일: fdtdec.c 프로젝트: eliasbakken/u-boot
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;
}
예제 #14
0
파일: fdt_ro.c 프로젝트: ForayJones/iods
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);
}
예제 #16
0
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;
}
예제 #17
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;
}
예제 #18
0
파일: fdtdec.c 프로젝트: Apaisal/u-boot
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;
}
예제 #19
0
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
}
예제 #20
0
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;
}
예제 #21
0
파일: accel.c 프로젝트: JamesHyunKim/F4OS
/* 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;
}
예제 #22
0
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;
}
예제 #23
0
파일: lists.c 프로젝트: AnAtom/u-boot-sunxi
/**
 * 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;
}
예제 #24
0
파일: fdt_ro.c 프로젝트: BadrElh/open-amp
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() */
}
예제 #25
0
파일: image-fit.c 프로젝트: bbbLinux/u_boot
/**
 * 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;
}
예제 #26
0
파일: accel.c 프로젝트: JamesHyunKim/F4OS
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;
}
예제 #27
0
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;
}
예제 #28
0
파일: dt_sysinfo.c 프로젝트: 9elements/fwts
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;
}
예제 #29
0
파일: gyro.c 프로젝트: JamesHyunKim/F4OS
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;
}