Beispiel #1
0
static int led_gpio_bind(struct udevice *parent)
{
	struct udevice *dev;
	ofnode node;
	int ret;

	dev_for_each_subnode(node, parent) {
		struct led_uc_plat *uc_plat;
		const char *label;

		label = ofnode_read_string(node, "label");
		if (!label) {
			debug("%s: node %s has no label\n", __func__,
			      ofnode_get_name(node));
			return -EINVAL;
		}
		ret = device_bind_driver_to_node(parent, "gpio_led",
						 ofnode_get_name(node),
						 node, &dev);
		if (ret)
			return ret;
		uc_plat = dev_get_uclass_platdata(dev);
		uc_plat->label = label;
	}

	return 0;
}
Beispiel #2
0
static int syscon_probe_by_ofnode(ofnode node, struct udevice **devp)
{
	struct udevice *dev, *parent;
	int ret;

	/* found node with "syscon" compatible, not bounded to SYSCON UCLASS */
	if (!ofnode_device_is_compatible(node, "syscon")) {
		dev_dbg(dev, "invalid compatible for syscon device\n");
		return -EINVAL;
	}

	/* bound to driver with same ofnode or to root if not found */
	if (device_find_global_by_ofnode(node, &parent))
		parent = dm_root();

	/* force bound to syscon class */
	ret = device_bind_driver_to_node(parent, "syscon",
					 ofnode_get_name(node),
					 node, &dev);
	if (ret) {
		dev_dbg(dev, "unable to bound syscon device\n");
		return ret;
	}
	ret = device_probe(dev);
	if (ret) {
		dev_dbg(dev, "unable to probe syscon device\n");
		return ret;
	}

	*devp = dev;
	return 0;
}
int pmic_bind_children(struct udevice *pmic, ofnode parent,
		       const struct pmic_child_info *child_info)
{
	const struct pmic_child_info *info;
	struct driver *drv;
	struct udevice *child;
	const char *node_name;
	int bind_count = 0;
	ofnode node;
	int prefix_len;
	int ret;

	debug("%s for '%s' at node offset: %d\n", __func__, pmic->name,
	      dev_of_offset(pmic));

	ofnode_for_each_subnode(node, parent) {
		node_name = ofnode_get_name(node);

		debug("* Found child node: '%s'\n", node_name);

		child = NULL;
		for (info = child_info; info->prefix && info->driver; info++) {
			debug("  - compatible prefix: '%s'\n", info->prefix);

			prefix_len = strlen(info->prefix);
			if (strncmp(info->prefix, node_name, prefix_len))
				continue;

			drv = lists_driver_lookup_name(info->driver);
			if (!drv) {
				debug("  - driver: '%s' not found!\n",
				      info->driver);
				continue;
			}

			debug("  - found child driver: '%s'\n", drv->name);

			ret = device_bind_with_driver_data(pmic, drv, node_name,
							   0, node, &child);
			if (ret) {
				debug("  - child binding error: %d\n", ret);
				continue;
			}

			debug("  - bound child device: '%s'\n", child->name);

			child->driver_data = trailing_strtol(node_name);

			debug("  - set 'child->driver_data': %lu\n",
			      child->driver_data);
			break;
		}

		if (child)
			bind_count++;
		else
			debug("  - compatible prefix not found\n");
	}
Beispiel #4
0
static int gpio_request_tail(int ret, ofnode node,
			     struct ofnode_phandle_args *args,
			     const char *list_name, int index,
			     struct gpio_desc *desc, int flags, bool add_index)
{
	desc->dev = NULL;
	desc->offset = 0;
	desc->flags = 0;
	if (ret)
		goto err;

	ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
					  &desc->dev);
	if (ret) {
		debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
		goto err;
	}
	ret = gpio_find_and_xlate(desc, args);
	if (ret) {
		debug("%s: gpio_find_and_xlate failed\n", __func__);
		goto err;
	}
	ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
			       ofnode_get_name(node),
			       list_name, index);
	if (ret) {
		debug("%s: dm_gpio_requestf failed\n", __func__);
		goto err;
	}
	ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
	if (ret) {
		debug("%s: dm_gpio_set_dir failed\n", __func__);
		goto err;
	}

	return 0;
err:
	debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
	      __func__, ofnode_get_name(node), list_name, index, ret);
	return ret;
}
Beispiel #5
0
static int gpio_dwapb_bind(struct udevice *dev)
{
	struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
	struct udevice *subdev;
	fdt_addr_t base;
	int ret, bank = 0;
	ofnode node;

	/* If this is a child device, there is nothing to do here */
	if (plat)
		return 0;

	base = dev_read_addr(dev);
	if (base == FDT_ADDR_T_NONE) {
		debug("Can't get the GPIO register base address\n");
		return -ENXIO;
	}

	for (node = dev_read_first_subnode(dev); ofnode_valid(node);
	     node = dev_read_next_subnode(node)) {
		if (!ofnode_read_bool(node, "gpio-controller"))
			continue;

		plat = devm_kcalloc(dev, 1, sizeof(*plat), GFP_KERNEL);
		if (!plat)
			return -ENOMEM;

		plat->base = base;
		plat->bank = bank;
		plat->pins = ofnode_read_u32_default(node, "snps,nr-gpios", 0);

		if (ofnode_read_string_index(node, "bank-name", 0,
					     &plat->name)) {
			/*
			 * Fall back to node name. This means accessing pins
			 * via bank name won't work.
			 */
			plat->name = ofnode_get_name(node);
		}

		ret = device_bind(dev, dev->driver, plat->name,
				  plat, -1, &subdev);
		if (ret)
			return ret;

		dev->node = node;
		bank++;
	}

	return 0;
}
Beispiel #6
0
int ofnode_decode_region(ofnode node, const char *prop_name, fdt_addr_t *basep,
			 fdt_size_t *sizep)
{
	const fdt_addr_t *cell;
	int len;

	debug("%s: %s: %s\n", __func__, ofnode_get_name(node), prop_name);
	cell = ofnode_get_property(node, prop_name, &len);
	if (!cell || (len < sizeof(fdt_addr_t) * 2)) {
		debug("cell=%p, len=%d\n", cell, len);
		return -1;
	}

	*basep = fdt_addr_to_cpu(*cell);
	*sizep = fdt_size_to_cpu(cell[1]);
	debug("%s: base=%08lx, size=%lx\n", __func__, (ulong)*basep,
	      (ulong)*sizep);

	return 0;
}
Beispiel #7
0
int cros_ec_decode_ec_flash(struct udevice *dev, struct fdt_cros_ec *config)
{
	ofnode flash_node, node;

	flash_node = dev_read_subnode(dev, "flash");
	if (!ofnode_valid(flash_node)) {
		debug("Failed to find flash node\n");
		return -1;
	}

	if (ofnode_read_fmap_entry(flash_node,  &config->flash)) {
		debug("Failed to decode flash node in chrome-ec\n");
		return -1;
	}

	config->flash_erase_value = ofnode_read_s32_default(flash_node,
							    "erase-value", -1);
	ofnode_for_each_subnode(node, flash_node) {
		const char *name = ofnode_get_name(node);
		enum ec_flash_region region;

		if (0 == strcmp(name, "ro")) {
			region = EC_FLASH_REGION_RO;
		} else if (0 == strcmp(name, "rw")) {
			region = EC_FLASH_REGION_ACTIVE;
		} else if (0 == strcmp(name, "wp-ro")) {
			region = EC_FLASH_REGION_WP_RO;
		} else {
			debug("Unknown EC flash region name '%s'\n", name);
			return -1;
		}

		if (ofnode_read_fmap_entry(node, &config->region[region])) {
			debug("Failed to decode flash region in chrome-ec'\n");
			return -1;
		}
	}

	return 0;
}
Beispiel #8
0
/**
 * pinconfig_post_bind() - post binding for PINCONFIG uclass
 * Recursively bind its children as pinconfig devices.
 *
 * @dev: pinconfig device
 * @return: 0 on success, or negative error code on failure
 */
static int pinconfig_post_bind(struct udevice *dev)
{
	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
	const char *name;
	ofnode node;
	int ret;

	if (!dev_of_valid(dev))
		return 0;

	dev_for_each_subnode(node, dev) {
		if (pre_reloc_only &&
		    !ofnode_pre_reloc(node))
			continue;
		/*
		 * If this node has "compatible" property, this is not
		 * a pin configuration node, but a normal device. skip.
		 */
		ofnode_get_property(node, "compatible", &ret);
		if (ret >= 0)
			continue;
		/* If this node has "gpio-controller" property, skip */
		if (ofnode_read_bool(node, "gpio-controller"))
			continue;

		if (ret != -FDT_ERR_NOTFOUND)
			return ret;

		name = ofnode_get_name(node);
		if (!name)
			return -EINVAL;
		ret = device_bind_driver_to_node(dev, "pinconfig", name,
						 node, NULL);
		if (ret)
			return ret;
	}

	return 0;
}
Beispiel #9
0
int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry)
{
	const char *prop;
	u32 reg[2];

	if (ofnode_read_u32_array(node, "reg", reg, 2)) {
		debug("Node '%s' has bad/missing 'reg' property\n",
		      ofnode_get_name(node));
		return -log_ret(ENOENT);
	}
	entry->offset = reg[0];
	entry->length = reg[1];
	entry->used = ofnode_read_s32_default(node, "used", entry->length);
	prop = ofnode_read_string(node, "compress");
	entry->compress_algo = prop && !strcmp(prop, "lzo") ?
		FMAP_COMPRESS_LZO : FMAP_COMPRESS_NONE;
	prop = ofnode_read_string(node, "hash");
	if (prop)
		entry->hash_size = strlen(prop);
	entry->hash_algo = prop ? FMAP_HASH_SHA256 : FMAP_HASH_NONE;
	entry->hash = (uint8_t *)prop;

	return 0;
}
Beispiel #10
0
static int stm32_fmc_ofdata_to_platdata(struct udevice *dev)
{
	struct stm32_sdram_params *params = dev_get_platdata(dev);
	struct bank_params *bank_params;
	struct ofnode_phandle_args args;
	u32 *syscfg_base;
	u32 mem_remap;
	u32 swp_fmc;
	ofnode bank_node;
	char *bank_name;
	u8 bank = 0;
	int ret;

	ret = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
						 &args);
	if (ret) {
		dev_dbg(dev, "%s: can't find syscon device (%d)\n", __func__, ret);
	} else {
		syscfg_base = (u32 *)ofnode_get_addr(args.node);

		mem_remap = dev_read_u32_default(dev, "st,mem_remap", NOT_FOUND);
		if (mem_remap != NOT_FOUND) {
			/* set memory mapping selection */
			clrsetbits_le32(syscfg_base, MEM_MODE_MASK, mem_remap);
		} else {
			dev_dbg(dev, "%s: cannot find st,mem_remap property\n", __func__);
		}
		
		swp_fmc = dev_read_u32_default(dev, "st,swp_fmc", NOT_FOUND);
		if (swp_fmc != NOT_FOUND) {
			/* set fmc swapping selection */
			clrsetbits_le32(syscfg_base, SWP_FMC_MASK, swp_fmc << SWP_FMC_OFFSET);
		} else {
			dev_dbg(dev, "%s: cannot find st,swp_fmc property\n", __func__);
		}

		dev_dbg(dev, "syscfg %x = %x\n", (u32)syscfg_base, *syscfg_base);
	}

	dev_for_each_subnode(bank_node, dev) {
		/* extract the bank index from DT */
		bank_name = (char *)ofnode_get_name(bank_node);
		strsep(&bank_name, "@");
		if (!bank_name) {
			pr_err("missing sdram bank index");
			return -EINVAL;
		}

		bank_params = &params->bank_params[bank];
		strict_strtoul(bank_name, 10,
			       (long unsigned int *)&bank_params->target_bank);

		if (bank_params->target_bank >= MAX_SDRAM_BANK) {
			pr_err("Found bank %d , but only bank 0 and 1 are supported",
			      bank_params->target_bank);
			return -EINVAL;
		}

		debug("Find bank %s %u\n", bank_name, bank_params->target_bank);

		params->bank_params[bank].sdram_control =
			(struct stm32_sdram_control *)
			 ofnode_read_u8_array_ptr(bank_node,
						  "st,sdram-control",
						  sizeof(struct stm32_sdram_control));

		if (!params->bank_params[bank].sdram_control) {
			pr_err("st,sdram-control not found for %s",
			      ofnode_get_name(bank_node));
			return -EINVAL;
		}


		params->bank_params[bank].sdram_timing =
			(struct stm32_sdram_timing *)
			 ofnode_read_u8_array_ptr(bank_node,
						  "st,sdram-timing",
						  sizeof(struct stm32_sdram_timing));

		if (!params->bank_params[bank].sdram_timing) {
			pr_err("st,sdram-timing not found for %s",
			      ofnode_get_name(bank_node));
			return -EINVAL;
		}


		bank_params->sdram_ref_count = ofnode_read_u32_default(bank_node,
						"st,sdram-refcount", 8196);
		bank++;
	}
Beispiel #11
0
const char *dev_read_name(struct udevice *dev)
{
	return ofnode_get_name(dev_ofnode(dev));
}