Exemple #1
0
/* Base test of register maps */
static int dm_test_regmap_base(struct unit_test_state *uts)
{
	struct udevice *dev;
	struct regmap *map;
	ofnode node;
	int i;

	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
	map = syscon_get_regmap(dev);
	ut_assertok_ptr(map);
	ut_asserteq(1, map->range_count);
	ut_asserteq(0x10, map->ranges[0].start);
	ut_asserteq(4, map->ranges[0].size);
	ut_asserteq(0x10, map_to_sysmem(regmap_get_range(map, 0)));

	ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev));
	map = syscon_get_regmap(dev);
	ut_assertok_ptr(map);
	ut_asserteq(4, map->range_count);
	ut_asserteq(0x20, map->ranges[0].start);
	for (i = 0; i < 4; i++) {
		const unsigned long addr = 0x20 + 8 * i;

		ut_asserteq(addr, map->ranges[i].start);
		ut_asserteq(5 + i, map->ranges[i].size);
		ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i)));
	}

	/* Check that we can't pretend a different device is a syscon */
	ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
	map = syscon_get_regmap(dev);
	ut_asserteq_ptr(ERR_PTR(-ENOEXEC), map);

	/* A different device can be a syscon by using Linux-compat API */
	node = ofnode_path("/syscon@2");
	ut_assert(ofnode_valid(node));

	map = syscon_node_to_regmap(node);
	ut_assertok_ptr(map);
	ut_asserteq(4, map->range_count);
	ut_asserteq(0x40, map->ranges[0].start);
	for (i = 0; i < 4; i++) {
		const unsigned long addr = 0x40 + 8 * i;

		ut_asserteq(addr, map->ranges[i].start);
		ut_asserteq(5 + i, map->ranges[i].size);
		ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i)));
	}

	return 0;
}
Exemple #2
0
int syscon_reboot_probe(struct udevice *dev)
{
	struct udevice *syscon;
	struct syscon_reboot_priv *priv = dev_get_priv(dev);
	int err;

	err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
					   "regmap", &syscon);
	if (err) {
		error("unable to find syscon device\n");
		return err;
	}

	priv->regmap = syscon_get_regmap(syscon);
	if (!priv->regmap) {
		error("unable to find regmap\n");
		return -ENODEV;
	}

	priv->offset = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
				       "offset", 0);
	priv->mask = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
				       "mask", 0);

	return 0;
}
Exemple #3
0
struct regmap *syscon_regmap_lookup_by_phandle(struct udevice *dev,
					       const char *name)
{
	struct udevice *syscon;
	struct regmap *r;
	u32 phandle;
	ofnode node;
	int err;

	err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
					   name, &syscon);
	if (err) {
		/* found node with "syscon" compatible, not bounded to SYSCON */
		err = ofnode_read_u32(dev_ofnode(dev), name, &phandle);
		if (err)
			return ERR_PTR(err);

		node = ofnode_get_by_phandle(phandle);
		if (!ofnode_valid(node)) {
			dev_dbg(dev, "unable to find syscon device\n");
			return ERR_PTR(-EINVAL);
		}
		err = syscon_probe_by_ofnode(node, &syscon);
		if (err)
			return ERR_PTR(-ENODEV);
	}

	r = syscon_get_regmap(syscon);
	if (!r) {
		dev_dbg(dev, "unable to find regmap\n");
		return ERR_PTR(-ENODEV);
	}

	return r;
}
Exemple #4
0
static int utmi_clk_ofdata_to_platdata(struct udevice *dev)
{
	struct pmc_platdata *plat = dev_get_platdata(dev);
	struct udevice *syscon;

	uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
				     "regmap-sfr", &syscon);

	if (syscon)
		plat->regmap_sfr = syscon_get_regmap(syscon);

	return 0;
}
Exemple #5
0
/* Base test of register maps */
static int dm_test_regmap_base(struct unit_test_state *uts)
{
	struct udevice *dev;
	struct regmap *map;
	int i;

	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
	map = syscon_get_regmap(dev);
	ut_assertok_ptr(map);
	ut_asserteq(1, map->range_count);
	ut_asserteq(0x10, map->base);
	ut_asserteq(0x10, map->range->start);
	ut_asserteq(4, map->range->size);
	ut_asserteq_ptr(&map->base_range, map->range);
	ut_asserteq(0x10, map_to_sysmem(regmap_get_range(map, 0)));

	ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev));
	map = syscon_get_regmap(dev);
	ut_assertok_ptr(map);
	ut_asserteq(4, map->range_count);
	ut_asserteq(0x20, map->base);
	ut_assert(&map->base_range != map->range);
	for (i = 0; i < 4; i++) {
		const unsigned long addr = 0x20 + 8 * i;

		ut_asserteq(addr, map->range[i].start);
		ut_asserteq(5 + i, map->range[i].size);
		ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i)));
	}

	/* Check that we can't pretend a different device is a syscon */
	ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
	map = syscon_get_regmap(dev);
	ut_asserteq_ptr(ERR_PTR(-ENOEXEC), map);

	return 0;
}
Exemple #6
0
/*
 * Linux-compatible syscon-to-regmap
 * The syscon node can be bound to another driver, but still works
 * as a syscon provider.
 */
struct regmap *syscon_node_to_regmap(ofnode node)
{
	struct udevice *dev;
	struct regmap *r;

	if (uclass_get_device_by_ofnode(UCLASS_SYSCON, node, &dev))
		if (syscon_probe_by_ofnode(node, &dev))
			return ERR_PTR(-ENODEV);

	r = syscon_get_regmap(dev);
	if (!r) {
		dev_dbg(dev, "unable to find regmap\n");
		return ERR_PTR(-ENODEV);
	}

	return r;
}
Exemple #7
0
/* Read/Write/Modify test */
static int dm_test_regmap_rw(struct unit_test_state *uts)
{
	struct udevice *dev;
	struct regmap *map;
	uint reg;

	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
	map = syscon_get_regmap(dev);
	ut_assertok_ptr(map);

	ut_assertok(regmap_write(map, 0, 0xcacafafa));
	ut_assertok(regmap_write(map, 3, 0x55aa2211));

	ut_assertok(regmap_read(map, 0, &reg));
	ut_assertok(regmap_read(map, 3, &reg));

	ut_assertok(regmap_update_bits(map, 0, 0xff00ff00, 0x55aa2211));
	ut_assertok(regmap_update_bits(map, 3, 0x00ff00ff, 0xcacafada));

	return 0;
}
Exemple #8
0
static void *map_syscon_chipselects(struct udevice *bus)
{
#if CONFIG_IS_ENABLED(SYSCON)
	struct udevice *syscon;
	struct regmap *regmap;
	const fdt32_t *cell;
	int len, err;

	err = uclass_get_device_by_phandle(UCLASS_SYSCON, bus,
					   "syscon-chipselects", &syscon);
	if (err) {
		debug("%s: unable to find syscon device (%d)\n", __func__,
		      err);
		return NULL;
	}

	regmap = syscon_get_regmap(syscon);
	if (IS_ERR(regmap)) {
		debug("%s: unable to find regmap (%ld)\n", __func__,
		      PTR_ERR(regmap));
		return NULL;
	}

	cell = fdt_getprop(gd->fdt_blob, dev_of_offset(bus),
			   "syscon-chipselects", &len);
	if (len < 2*sizeof(fdt32_t)) {
		debug("%s: offset not available\n", __func__);
		return NULL;
	}

	return fdtdec_get_number(cell + 1, 1) + regmap_get_range(regmap, 0);
#else
	fdt_addr_t addr;
	addr = devfdt_get_addr_index(bus, 2);
	return (addr == FDT_ADDR_T_NONE) ? NULL :
		map_physmem(addr, 0, MAP_NOCACHE);
#endif
}
static void *get_reg(struct udevice *dev, const char *name)
{
	struct udevice *syscon;
	struct regmap *regmap;
	const fdt32_t *cell;
	int len, err;
	void *base;

	err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
					   name, &syscon);
	if (err) {
		pr_err("unable to find syscon device for %s (%d)\n",
		      name, err);
		return NULL;
	}

	regmap = syscon_get_regmap(syscon);
	if (IS_ERR(regmap)) {
		pr_err("unable to find regmap for %s (%ld)\n",
		      name, PTR_ERR(regmap));
		return NULL;
	}

	cell = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), name,
			   &len);
	if (len < 2*sizeof(fdt32_t)) {
		pr_err("offset not available for %s\n", name);
		return NULL;
	}

	base = regmap_get_range(regmap, 0);
	if (!base)
		return NULL;

	return fdtdec_get_number(cell + 1, 1) + base;
}
Exemple #10
0
int syscon_reboot_probe(struct udevice *dev)
{
	struct udevice *syscon;
	struct syscon_reboot_priv *priv = dev_get_priv(dev);
	int err;

	err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
					   "regmap", &syscon);
	if (err) {
		pr_err("unable to find syscon device\n");
		return err;
	}

	priv->regmap = syscon_get_regmap(syscon);
	if (!priv->regmap) {
		pr_err("unable to find regmap\n");
		return -ENODEV;
	}

	priv->offset = dev_read_u32_default(dev, "offset", 0);
	priv->mask = dev_read_u32_default(dev, "mask", 0);

	return 0;
}
static int sti_sysreset_probe(struct udevice *dev)
{
	struct sti_sysreset_priv *priv = dev_get_priv(dev);
	struct udevice *syscon;
	struct regmap *regmap;
	struct fdtdec_phandle_args syscfg_phandle;
	int ret;

	/* get corresponding syscon phandle */
	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
					     "st,syscfg", NULL, 0, 0,
					     &syscfg_phandle);
	if (ret < 0) {
		pr_err("Can't get syscfg phandle: %d\n", ret);
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_SYSCON,
					     syscfg_phandle.node,
					     &syscon);
	if (ret) {
		pr_err("%s: uclass_get_device_by_of_offset failed: %d\n",
		      __func__, ret);
		return ret;
	}

	regmap = syscon_get_regmap(syscon);
	if (!regmap) {
		pr_err("unable to get regmap for %s\n", syscon->name);
		return -ENODEV;
	}

	priv->base = regmap->base;

	return 0;
}