예제 #1
0
int fdt_get_named_resource(const void *fdt, int node, const char *property,
			   const char *prop_names, const char *name,
			   struct fdt_resource *res)
{
	int index;

	index = fdt_stringlist_search(fdt, node, prop_names, name);
	if (index < 0)
		return index;

	return fdt_get_resource(fdt, node, property, index, res);
}
예제 #2
0
파일: stringlist.c 프로젝트: ryo/netbsd-src
static void check_expected_failure(const void *fdt, const char *path,
                                   const char *property)
{
    int offset, err;

    offset = fdt_path_offset(fdt, "/");
    if (offset < 0)
        FAIL("Couldn't find path %s", path);

    err = fdt_stringlist_count(fdt, offset, "#address-cells");
    if (err != -FDT_ERR_BADVALUE)
        FAIL("unexpectedly succeeded in parsing #address-cells\n");

    err = fdt_stringlist_search(fdt, offset, "#address-cells", "foo");
    if (err != -FDT_ERR_BADVALUE)
        FAIL("found string in #address-cells: %d\n", err);

    /*
     * Note that the #address-cells property contains a small 32-bit
     * unsigned integer, hence some bytes will be zero, and searching for
     * the empty string will succeed.
     *
     * The reason for this oddity is that the function will exit when the
     * first occurrence of the string is found, but in order to determine
     * that the property does not contain a valid string list it would
     * need to process the whole value.
     */
    err = fdt_stringlist_search(fdt, offset, "#address-cells", "");
    if (err != 0)
        FAIL("empty string not found in #address-cells: %d\n", err);

    /*
     * fdt_get_string() can successfully extract strings from non-string
     * properties. This is because it doesn't necessarily parse the whole
     * property value, which would be necessary for it to determine if a
     * valid string or string list is present.
     */
}
예제 #3
0
int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
{
	int index;

	debug("%s(dev=%p, name=%s, clk=%p)\n", __func__, dev, name, clk);

	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
				      "clock-names", name);
	if (index < 0) {
		debug("fdt_stringlist_search() failed: %d\n", index);
		return index;
	}

	return clk_get_by_index(dev, index, clk);
}
예제 #4
0
파일: stringlist.c 프로젝트: ryo/netbsd-src
static void check_string_index(const void *fdt, const char *path,
                               const char *property, const char *string,
                               int idx)
{
    int offset, err;

    offset = fdt_path_offset(fdt, path);
    if (offset < 0)
        FAIL("Couldn't find path %s", path);

    err = fdt_stringlist_search(fdt, offset, property, string);

    if (err != idx)
        FAIL("Index of %s in property %s of node %s is %d, expected %d\n",
             string, property, path, err, idx);
}
예제 #5
0
int sunxi_simplefb_fdt_match(void *blob, const char *pipeline)
{
	int offset, ret;

	/* Find a prefilled simpefb node, matching out pipeline config */
	offset = fdt_node_offset_by_compatible(blob, -1,
					       "allwinner,simple-framebuffer");
	while (offset >= 0) {
		ret = fdt_stringlist_search(blob, offset, "allwinner,pipeline",
					    pipeline);
		if (ret == 0)
			break;
		offset = fdt_node_offset_by_compatible(blob, offset,
						"allwinner,simple-framebuffer");
	}

	return offset;
}
예제 #6
0
static int create_pirq_routing_table(struct udevice *dev)
{
	struct irq_router *priv = dev_get_priv(dev);
	const void *blob = gd->fdt_blob;
	int node;
	int len, count;
	const u32 *cell;
	struct irq_routing_table *rt;
	struct irq_info *slot, *slot_base;
	int irq_entries = 0;
	int i;
	int ret;

	node = dev->of_offset;

	/* extract the bdf from fdt_pci_addr */
	priv->bdf = dm_pci_get_bdf(dev->parent);

	ret = fdt_stringlist_search(blob, node, "intel,pirq-config", "pci");
	if (!ret) {
		priv->config = PIRQ_VIA_PCI;
	} else {
		ret = fdt_stringlist_search(blob, node, "intel,pirq-config",
					    "ibase");
		if (!ret)
			priv->config = PIRQ_VIA_IBASE;
		else
			return -EINVAL;
	}

	ret = fdtdec_get_int(blob, node, "intel,pirq-link", -1);
	if (ret == -1)
		return ret;
	priv->link_base = ret;

	priv->irq_mask = fdtdec_get_int(blob, node,
					"intel,pirq-mask", PIRQ_BITMAP);

	if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
		/* Reserve IRQ9 for SCI */
		priv->irq_mask &= ~(1 << 9);
	}

	if (priv->config == PIRQ_VIA_IBASE) {
		int ibase_off;

		ibase_off = fdtdec_get_int(blob, node, "intel,ibase-offset", 0);
		if (!ibase_off)
			return -EINVAL;

		/*
		 * Here we assume that the IBASE register has already been
		 * properly configured by U-Boot before.
		 *
		 * By 'valid' we mean:
		 *   1) a valid memory space carved within system memory space
		 *      assigned to IBASE register block.
		 *   2) memory range decoding is enabled.
		 * Hence we don't do any santify test here.
		 */
		dm_pci_read_config32(dev->parent, ibase_off, &priv->ibase);
		priv->ibase &= ~0xf;
	}

	priv->actl_8bit = fdtdec_get_bool(blob, node, "intel,actl-8bit");
	priv->actl_addr = fdtdec_get_int(blob, node, "intel,actl-addr", 0);

	cell = fdt_getprop(blob, node, "intel,pirq-routing", &len);
	if (!cell || len % sizeof(struct pirq_routing))
		return -EINVAL;
	count = len / sizeof(struct pirq_routing);

	rt = calloc(1, sizeof(struct irq_routing_table));
	if (!rt)
		return -ENOMEM;

	/* Populate the PIRQ table fields */
	rt->signature = PIRQ_SIGNATURE;
	rt->version = PIRQ_VERSION;
	rt->rtr_bus = PCI_BUS(priv->bdf);
	rt->rtr_devfn = (PCI_DEV(priv->bdf) << 3) | PCI_FUNC(priv->bdf);
	rt->rtr_vendor = PCI_VENDOR_ID_INTEL;
	rt->rtr_device = PCI_DEVICE_ID_INTEL_ICH7_31;

	slot_base = rt->slots;

	/* Now fill in the irq_info entries in the PIRQ table */
	for (i = 0; i < count;
	     i++, cell += sizeof(struct pirq_routing) / sizeof(u32)) {
		struct pirq_routing pr;

		pr.bdf = fdt_addr_to_cpu(cell[0]);
		pr.pin = fdt_addr_to_cpu(cell[1]);
		pr.pirq = fdt_addr_to_cpu(cell[2]);

		debug("irq_info %d: b.d.f %x.%x.%x INT%c PIRQ%c\n",
		      i, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf),
		      PCI_FUNC(pr.bdf), 'A' + pr.pin - 1,
		      'A' + pr.pirq);

		slot = check_dup_entry(slot_base, irq_entries,
				       PCI_BUS(pr.bdf), PCI_DEV(pr.bdf));
		if (slot) {
			debug("found entry for bus %d device %d, ",
			      PCI_BUS(pr.bdf), PCI_DEV(pr.bdf));

			if (slot->irq[pr.pin - 1].link) {
				debug("skipping\n");

				/*
				 * Sanity test on the routed PIRQ pin
				 *
				 * If they don't match, show a warning to tell
				 * there might be something wrong with the PIRQ
				 * routing information in the device tree.
				 */
				if (slot->irq[pr.pin - 1].link !=
					LINK_N2V(pr.pirq, priv->link_base))
					debug("WARNING: Inconsistent PIRQ routing information\n");
				continue;
			}
		} else {
			slot = slot_base + irq_entries++;
		}
		debug("writing INT%c\n", 'A' + pr.pin - 1);
		fill_irq_info(priv, slot, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf),
			      pr.pin, pr.pirq);
	}

	rt->size = irq_entries * sizeof(struct irq_info) + 32;

	/* Fix up the table checksum */
	rt->checksum = table_compute_checksum(rt, rt->size);

	pirq_routing_table = rt;

	return 0;
}