static int _regmap_multi_reg_write()

in regmap/regmap.c [2458:2535]


static int _regmap_multi_reg_write(struct regmap *map,
				   const struct reg_sequence *regs,
				   size_t num_regs)
{
	int i;
	int ret;

	if (!map->can_multi_write) {
		for (i = 0; i < num_regs; i++) {
			ret = _regmap_write(map, regs[i].reg, regs[i].def);
			if (ret != 0)
				return ret;

			if (regs[i].delay_us) {
				if (map->can_sleep)
					fsleep(regs[i].delay_us);
				else
					udelay(regs[i].delay_us);
			}
		}
		return 0;
	}

	if (!map->format.parse_inplace)
		return -EINVAL;

	if (map->writeable_reg)
		for (i = 0; i < num_regs; i++) {
			int reg = regs[i].reg;
			if (!map->writeable_reg(map->dev, reg))
				return -EINVAL;
			if (!IS_ALIGNED(reg, map->reg_stride))
				return -EINVAL;
		}

	if (!map->cache_bypass) {
		for (i = 0; i < num_regs; i++) {
			unsigned int val = regs[i].def;
			unsigned int reg = regs[i].reg;
			ret = regcache_write(map, reg, val);
			if (ret) {
				dev_err(map->dev,
				"Error in caching of register: %x ret: %d\n",
								reg, ret);
				return ret;
			}
		}
		if (map->cache_only) {
			map->cache_dirty = true;
			return 0;
		}
	}

	WARN_ON(!map->bus);

	for (i = 0; i < num_regs; i++) {
		unsigned int reg = regs[i].reg;
		struct regmap_range_node *range;

		/* Coalesce all the writes between a page break or a delay
		 * in a sequence
		 */
		range = _regmap_range_lookup(map, reg);
		if (range || regs[i].delay_us) {
			size_t len = sizeof(struct reg_sequence)*num_regs;
			struct reg_sequence *base = kmemdup(regs, len,
							   GFP_KERNEL);
			if (!base)
				return -ENOMEM;
			ret = _regmap_range_multi_paged_reg_write(map, base,
								  num_regs);
			kfree(base);

			return ret;
		}
	}
	return _regmap_raw_multi_reg_write(map, regs, num_regs);
}